1#ifndef BOMBERMAN_NET_NETCLIENTINTERNAL_H
2#define BOMBERMAN_NET_NETCLIENTINTERNAL_H
18namespace bomberman::net::net_client_internal
20 constexpr int kConnectTimeoutMs = 5000;
21 constexpr int kDisconnectTimeoutMs = 5000;
22 constexpr int kDisconnectPollTimeoutMs = 100;
25 constexpr std::size_t kMaxPendingGameplayEvents = 128;
27 using SteadyClock = std::chrono::steady_clock;
28 using TimePoint = SteadyClock::time_point;
30 inline int elapsedMs(
const TimePoint& since)
32 return static_cast<int>(
33 std::chrono::duration_cast<std::chrono::milliseconds>(SteadyClock::now() - since).count());
36 inline uint32_t elapsedSinceOrZero(
const TimePoint& latest,
const TimePoint& fallback)
38 const TimePoint since = latest != TimePoint{} ? latest : fallback;
39 if (since == TimePoint{})
44 return static_cast<uint32_t
>(elapsedMs(since));
47 inline std::string currentLocalTimeTagForFilename()
49 const auto now = std::chrono::system_clock::now();
50 const auto nowTimeT = std::chrono::system_clock::to_time_t(now);
54 localtime_s(&localTm, &nowTimeT);
56 localtime_r(&nowTimeT, &localTm);
59 std::ostringstream out;
60 out << std::put_time(&localTm,
"%H%M%S");
64 inline std::string makeUniqueJsonReportPath(
const std::string_view basePathWithoutExtension)
66 std::string candidate = std::string(basePathWithoutExtension) +
".json";
67 if (!std::filesystem::exists(candidate))
72 for (uint32_t suffix = 2; suffix < 1000; ++suffix)
74 candidate = std::string(basePathWithoutExtension) +
"_" + std::to_string(suffix) +
".json";
75 if (!std::filesystem::exists(candidate))
81 return std::string(basePathWithoutExtension) +
"_overflow.json";
84 constexpr bool isHandshakeControlMessage(
EMsgType type)
113 using net_client_internal::SteadyClock;
114 using net_client_internal::TimePoint;
118 ENetHost* host =
nullptr;
119 ENetPeer* peer =
nullptr;
127 std::string pendingPlayerName;
128 TimePoint connectStartTime;
129 TimePoint handshakeStartTime;
130 TimePoint disconnectStartTime;
131 TimePoint connectedStartTime;
132 TimePoint lastLobbyStateReceiveTime;
133 TimePoint lastGameplayReceiveTime;
134 TimePoint lastSnapshotReceiveTime;
135 TimePoint lastCorrectionReceiveTime;
136 TimePoint lastTransportSampleTime;
137 TimePoint lastInputSendTime;
141 bool diagnosticsEnabled =
false;
142 bool diagnosticsSessionActive =
false;
143 bool diagnosticsPredictionEnabled =
true;
144 bool diagnosticsRemoteSmoothingEnabled =
true;
146 std::optional<MsgLobbyState> cachedLobbyState{};
151 bool hasLevelInfo =
false;
152 bool levelInfoPending =
false;
153 bool brokenGameplayEventStream =
false;
154 std::optional<MsgMatchStart> matchStart{};
155 std::optional<uint32_t> cancelledMatchId{};
156 std::optional<MsgMatchResult> matchResult{};
157 std::optional<MsgSnapshot> snapshot{};
158 std::optional<MsgCorrection> correction{};
159 std::deque<GameplayEvent> pendingGameplayEvents{};
161 void resetRuntimeState()
166 cancelledMatchId.reset();
168 brokenGameplayEventStream =
false;
169 pendingGameplayEvents.clear();
175 levelInfo = newLevelInfo;
177 levelInfoPending =
true;
181 bool isActiveMatch(
const uint32_t matchId)
const
183 return hasLevelInfo && levelInfo.
matchId == matchId;
187 uint32_t currentMatchId()
const
189 return hasLevelInfo ? levelInfo.
matchId : 0u;
196 hasLevelInfo =
false;
197 levelInfoPending =
false;
204 const uint8_t* payload,
205 std::size_t payloadSize)
207 client.handleWelcome(payload, payloadSize);
212 const uint8_t* payload,
213 std::size_t payloadSize)
215 client.handleReject(payload, payloadSize);
218 static void onLevelInfo(
NetClient& client,
219 const PacketHeader& ,
220 const uint8_t* payload,
221 std::size_t payloadSize)
223 client.handleLevelInfo(payload, payloadSize);
226 static void onLobbyState(
NetClient& client,
227 const PacketHeader& ,
228 const uint8_t* payload,
229 std::size_t payloadSize)
231 client.handleLobbyState(payload, payloadSize);
234 static void onMatchStart(
NetClient& client,
235 const PacketHeader& ,
236 const uint8_t* payload,
237 std::size_t payloadSize)
239 client.handleMatchStart(payload, payloadSize);
242 static void onMatchCancelled(
NetClient& client,
243 const PacketHeader& ,
244 const uint8_t* payload,
245 std::size_t payloadSize)
247 client.handleMatchCancelled(payload, payloadSize);
250 static void onMatchResult(
NetClient& client,
251 const PacketHeader& ,
252 const uint8_t* payload,
253 std::size_t payloadSize)
255 client.handleMatchResult(payload, payloadSize);
258 static void onSnapshot(
NetClient& client,
259 const PacketHeader& ,
260 const uint8_t* payload,
261 std::size_t payloadSize)
263 client.handleSnapshot(payload, payloadSize);
266 static void onCorrection(
NetClient& client,
267 const PacketHeader& ,
268 const uint8_t* payload,
269 std::size_t payloadSize)
271 client.handleCorrection(payload, payloadSize);
274 static void onBombPlaced(
NetClient& client,
275 const PacketHeader& ,
276 const uint8_t* payload,
277 std::size_t payloadSize)
279 client.handleBombPlaced(payload, payloadSize);
282 static void onExplosionResolved(
NetClient& client,
283 const PacketHeader& ,
284 const uint8_t* payload,
285 std::size_t payloadSize)
287 client.handleExplosionResolved(payload, payloadSize);
Client-side multiplayer diagnostics data model and recorder.
Client-side multiplayer connection lifecycle and packet endpoint.
Shared packet parsing and type-safe dispatch helpers.
Client-side multiplayer diagnostics recorder owned by NetClient.
Definition ClientDiagnostics.h:104
ENet client connection and protocol endpoint.
Definition NetClient.h:75
NetClient()
Constructs an idle client with no active transport.
Definition NetClient.cpp:11
spdlog::logger * client()
Client bootstrap and top-level runtime.
Definition Log.cpp:363
Shared multiplayer protocol types and transport-facing wire helpers.
Definition ClientPrediction.cpp:13
constexpr uint8_t kMaxInputBatchSize
Maximum number of inputs in a single batched MsgInput packet.
Definition NetCommon.h:67
EMsgType
Message type identifiers used in packet headers.
Definition NetCommon.h:316
@ Input
Client message containing a batch of input bitmasks and their base sequence number.
@ MatchStart
Server message indicating the authoritative server tick for round start and the unlock tick for early...
@ LevelInfo
Server message containing map seed and match id for an upcoming round.
@ LobbyState
Server message containing current lobby state.
@ BombPlaced
Server message indicating that a bomb has been placed by a player.
@ MatchResult
Server message containing the result of a completed match.
@ MatchCancelled
Server message indicating that the current match has been cancelled due to a player disconnect.
@ Welcome
Server handshake acceptance message.
@ Hello
Client-initiated handshake message.
@ Correction
Server message containing an authoritative correction to the local player's state.
@ ExplosionResolved
Server message containing the authoritative result of a bomb explosion.
@ MatchLoaded
Server message indicating that all players have loaded the level and the match is ready to start.
@ Snapshot
Server message containing the authoritative game state for a single tick.
@ Reject
Server handshake rejection message.
constexpr uint32_t kFirstInputSeq
First valid input sequence number. Seq 0 means "no input received yet".
Definition NetCommon.h:64
Round-start payload sent reliably by the server when a match begins.
Definition NetCommon.h:546
uint32_t matchId
Monotonic authoritative match identifier for this round start.
Definition NetCommon.h:547
Live multiplayer/network HUD state updated during gameplay.
Definition NetClient.h:79
Definition NetClientInternal.h:149
Definition NetClientInternal.h:117
Fixed-size message type to handler lookup table.
Definition PacketDispatch.h:65