1 /*
2 * OpenClonk, http://www.openclonk.org
3 *
4 * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5 * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6 *
7 * Distributed under the terms of the ISC license; see accompanying file
8 * "COPYING" for details.
9 *
10 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11 * See accompanying file "TRADEMARK" for details.
12 *
13 * To redistribute this file separately, substitute the full license texts
14 * for the above references.
15 */
16 #include "C4Include.h"
17
18 #include "C4Version.h"
19 #include "control/C4RoundResults.h"
20 #include "gui/C4GameLobby.h"
21 #include "network/C4GameControlNetwork.h"
22 #include "network/C4Network2.h"
23 #include "network/C4Network2Res.h"
24
25 // *** constants
26
27 // workaround
28 template <class T> struct unpack_class
29 {
unpackunpack_class30 static C4PacketBase *unpack(StdCompiler *pComp)
31 {
32 assert(pComp->isDeserializer());
33 T *pPkt = new T();
34 try
35 {
36 pComp->Value(*pPkt);
37 }
38 catch (...)
39 {
40 delete pPkt;
41 throw;
42 }
43 return pPkt;
44 }
45 };
46
47 #define PKT_UNPACK(T) unpack_class<T>::unpack
48
49
50 const C4PktHandlingData PktHandlingData[] =
51 {
52
53 // C4Network2IO (network thread)
54 { PID_Conn, PC_Network, "Connection Request", true, true, PH_C4Network2IO, PKT_UNPACK(C4PacketConn) },
55 { PID_ConnRe, PC_Network, "Connection Request Reply", true, true, PH_C4Network2IO, PKT_UNPACK(C4PacketConnRe) },
56
57 { PID_Ping, PC_Network, "Ping", true, true, PH_C4Network2IO, PKT_UNPACK(C4PacketPing) },
58 { PID_Pong, PC_Network, "Pong", true, true, PH_C4Network2IO, PKT_UNPACK(C4PacketPing) },
59
60 { PID_FwdReq, PC_Network, "Forward Request", false, true, PH_C4Network2IO, PKT_UNPACK(C4PacketFwd) },
61 { PID_Fwd, PC_Network, "Forward", false, true, PH_C4Network2IO, PKT_UNPACK(C4PacketFwd) },
62
63 { PID_PostMortem, PC_Network, "Post Mortem", false, true, PH_C4Network2IO, PKT_UNPACK(C4PacketPostMortem) },
64
65 // C4Network2 (main thread)
66 { PID_Conn, PC_Network, "Connection Request", true, false, PH_C4Network2, PKT_UNPACK(C4PacketConn) },
67 { PID_ConnRe, PC_Network, "Connection Request Reply", true, false, PH_C4Network2, PKT_UNPACK(C4PacketConnRe) },
68
69 { PID_Status, PC_Network, "Game Status", true, false, PH_C4Network2, PKT_UNPACK(C4Network2Status) },
70 { PID_StatusAck, PC_Network, "Game Status Acknowledgement",true, false, PH_C4Network2, PKT_UNPACK(C4Network2Status) },
71
72 { PID_ClientActReq, PC_Network, "Client Activation Request", false, false, PH_C4Network2, PKT_UNPACK(C4PacketActivateReq) },
73
74 { PID_JoinData, PC_Network, "Join Data", false, false, PH_C4Network2, PKT_UNPACK(C4PacketJoinData) },
75
76 // C4Network2PlayerList (main thread)
77 { PID_PlayerInfoUpdReq,PC_Network, "Player info update request",true, false, PH_C4Network2Players, PKT_UNPACK(C4PacketPlayerInfoUpdRequest) },
78
79 { PID_LeagueRoundResults,PC_Network, "League round results", true, false, PH_C4Network2Players, PKT_UNPACK(C4PacketLeagueRoundResults) },
80
81 // C4GameLobby (main thread)
82 { PID_LobbyCountdown,PC_Network,"Lobby countdown", false, false, PH_C4GUIMainDlg, PKT_UNPACK(C4GameLobby::C4PacketCountdown) },
83 { PID_SetScenarioParameter,PC_Network,"Scenario parameter", false, false, PH_C4GUIMainDlg, PKT_UNPACK(C4GameLobby::C4PacketSetScenarioParameter) },
84
85 // C4Network2ClientList (main thread)
86 { PID_Addr, PC_Network, "Client Address", false, false, PH_C4Network2ClientList, PKT_UNPACK(C4PacketAddr) },
87
88
89 // C4Network2ResList (network thread)
90 { PID_NetResDis, PC_Network, "Resource Discover", true, true, PH_C4Network2ResList, PKT_UNPACK(C4PacketResDiscover) },
91 { PID_NetResStat, PC_Network, "Resource Status", false, true, PH_C4Network2ResList, PKT_UNPACK(C4PacketResStatus) },
92 { PID_NetResDerive, PC_Network, "Resource Derive", false, true, PH_C4Network2ResList, PKT_UNPACK(C4Network2ResCore) },
93 { PID_NetResReq, PC_Network, "Resource Request", false, true, PH_C4Network2ResList, PKT_UNPACK(C4PacketResRequest) },
94 { PID_NetResData, PC_Network, "Resource Data", false, true, PH_C4Network2ResList, PKT_UNPACK(C4Network2ResChunk) },
95
96 // C4GameControlNetwork (network thread)
97 { PID_Control, PC_Network, "Control", false, true, PH_C4GameControlNetwork, PKT_UNPACK(C4GameControlPacket) },
98 { PID_ControlReq, PC_Network, "Control Request", false, true, PH_C4GameControlNetwork, PKT_UNPACK(C4PacketControlReq) },
99 // main thread
100 { PID_ControlPkt, PC_Network, "Control Paket", false, false, PH_C4GameControlNetwork, PKT_UNPACK(C4PacketControlPkt) },
101 { PID_ExecSyncCtrl, PC_Network, "Execute Sync Control", false, false, PH_C4GameControlNetwork, PKT_UNPACK(C4PacketExecSyncCtrl)},
102
103 // Control (Isn't send over network, handled only as part of a control list)
104 { CID_ClientJoin, PC_Control, "Client Join", false, true, 0, PKT_UNPACK(C4ControlClientJoin) },
105 { CID_ClientUpdate, PC_Control, "Client Update", false, true, 0, PKT_UNPACK(C4ControlClientUpdate)},
106 { CID_ClientRemove, PC_Control, "Client Remove", false, true, 0, PKT_UNPACK(C4ControlClientRemove)},
107 { CID_Vote, PC_Control, "Voting", false, true, 0, PKT_UNPACK(C4ControlVote) },
108 { CID_VoteEnd, PC_Control, "Voting End", false, true, 0, PKT_UNPACK(C4ControlVoteEnd) },
109 { CID_SyncCheck, PC_Control, "Sync Check", false, true, 0, PKT_UNPACK(C4ControlSyncCheck) },
110 { CID_Synchronize, PC_Control, "Synchronize", false, true, 0, PKT_UNPACK(C4ControlSynchronize)},
111 { CID_Set, PC_Control, "Set", false, true, 0, PKT_UNPACK(C4ControlSet) },
112 { CID_Script, PC_Control, "Script", false, true, 0, PKT_UNPACK(C4ControlScript) },
113 { CID_MsgBoardReply,PC_Control, "Message Board Reply", false, true, 0, PKT_UNPACK(C4ControlMsgBoardReply)},
114 { CID_MsgBoardCmd ,PC_Control, "Message Board Command", false, true, 0, PKT_UNPACK(C4ControlMsgBoardCmd)},
115 { CID_PlrInfo, PC_Control, "Player Info", false, true, 0, PKT_UNPACK(C4ControlPlayerInfo) },
116 { CID_JoinPlr, PC_Control, "Join Player", false, true, 0, PKT_UNPACK(C4ControlJoinPlayer) },
117 { CID_RemovePlr, PC_Control, "Remove Player", false, true, 0, PKT_UNPACK(C4ControlRemovePlr) },
118 { CID_PlrSelect, PC_Control, "Player Select", false, true, 0, PKT_UNPACK(C4ControlPlayerSelect)},
119 { CID_PlrControl, PC_Control, "Player Control", false, true, 0, PKT_UNPACK(C4ControlPlayerControl)},
120 { CID_PlrAction, PC_Control, "Player Self-Mgmt Action", false, true, 0, PKT_UNPACK(C4ControlPlayerAction)},
121 { CID_PlrMouseMove, PC_Control, "Player Mouse Movement", false, true, 0, PKT_UNPACK(C4ControlPlayerMouse)},
122 { CID_Message, PC_Control, "Message", false, true, 0, PKT_UNPACK(C4ControlMessage) },
123 { CID_MenuCommand, PC_Control, "Menu Command", false, true, 0, PKT_UNPACK(C4ControlMenuCommand)},
124 { CID_EMMoveObj, PC_Control, "EM Move Obj", false, true, 0, PKT_UNPACK(C4ControlEMMoveObject)},
125 { CID_EMDrawTool, PC_Control, "EM Draw Tool", false, true, 0, PKT_UNPACK(C4ControlEMDrawTool) },
126 { CID_ReInitScenario,PC_Control, "Reinit Scenario", false, true, 0, PKT_UNPACK(C4ControlReInitScenario) },
127 { CID_EditGraph, PC_Control, "Edit Graph", false, true, 0, PKT_UNPACK(C4ControlEditGraph) },
128
129 { CID_DebugRec, PC_Control, "Debug Rec", false, true, 0, PKT_UNPACK(C4ControlDebugRec) },
130
131 // EOL
132 { PID_None, PC_Network, nullptr, false, true, 0, nullptr }
133 };
134
PacketNameByID(C4PacketType eID)135 const char *PacketNameByID(C4PacketType eID)
136 {
137 for (const C4PktHandlingData *pPData = PktHandlingData; pPData->ID != PID_None; pPData++)
138 if (pPData->ID == eID)
139 return pPData->Name;
140 return "?!?";
141 }
142
143 // *** C4PacketBase
144
145 C4PacketBase::C4PacketBase() = default;
146
147 C4PacketBase::~C4PacketBase() = default;
148
pack(const C4NetIO::addr_t & addr) const149 C4NetIOPacket C4PacketBase::pack(const C4NetIO::addr_t &addr) const
150 {
151 return C4NetIOPacket(DecompileToBuf<StdCompilerBinWrite>(*this), addr);
152 }
153
pack(uint8_t cStatus,const C4NetIO::addr_t & addr) const154 C4NetIOPacket C4PacketBase::pack(uint8_t cStatus, const C4NetIO::addr_t &addr) const
155 {
156 return C4NetIOPacket(DecompileToBuf<StdCompilerBinWrite>(mkInsertAdapt(mkDecompileAdapt(*this), cStatus)), addr);
157 }
158
unpack(const C4NetIOPacket & Pkt,char * pStatus)159 void C4PacketBase::unpack(const C4NetIOPacket &Pkt, char *pStatus)
160 {
161 if (pStatus) *pStatus = Pkt.getStatus();
162 CompileFromBuf<StdCompilerBinRead>(*this, pStatus ? Pkt.getPBuf() : Pkt.getRef());
163 }
164
165
166 // *** C4PktBuf
167
168 C4PktBuf::C4PktBuf() = default;
169
C4PktBuf(const C4PktBuf & rCopy)170 C4PktBuf::C4PktBuf(const C4PktBuf &rCopy) : C4PacketBase(rCopy)
171 {
172 Data.Copy(rCopy.Data);
173 }
174
C4PktBuf(const StdBuf & rCpyData)175 C4PktBuf::C4PktBuf(const StdBuf &rCpyData)
176 {
177 Data.Copy(rCpyData);
178 }
179
CompileFunc(StdCompiler * pComp)180 void C4PktBuf::CompileFunc(StdCompiler *pComp)
181 {
182 pComp->Value(mkNamingAdapt(Data, "Data"));
183 }
184
185 // *** C4IDPacket
186
187 C4IDPacket::C4IDPacket() = default;
188
C4IDPacket(C4PacketType eID,C4PacketBase * pPkt,bool fTakePkt)189 C4IDPacket::C4IDPacket(C4PacketType eID, C4PacketBase *pPkt, bool fTakePkt)
190 : eID(eID), pPkt(pPkt), fOwnPkt(fTakePkt), pNext(nullptr)
191 {
192
193 }
194
C4IDPacket(const C4IDPacket & Packet2)195 C4IDPacket::C4IDPacket(const C4IDPacket &Packet2)
196 : C4PacketBase(Packet2)
197 {
198 // kinda hacky (note this might throw an uncaught exception)
199 C4PacketBase::unpack(Packet2.C4PacketBase::pack());
200 }
201
~C4IDPacket()202 C4IDPacket::~C4IDPacket()
203 {
204 Clear();
205 }
206
getPktName() const207 const char *C4IDPacket::getPktName() const
208 {
209 // Use map
210 for (const C4PktHandlingData *pPData = PktHandlingData; pPData->ID != PID_None; pPData++)
211 if (pPData->ID == eID && pPData->Name)
212 return pPData->Name;
213 return "Unknown Packet Type";
214 }
215
Default()216 void C4IDPacket::Default()
217 {
218 eID = PID_None; pPkt = nullptr;
219 }
220
Clear()221 void C4IDPacket::Clear()
222 {
223 if (fOwnPkt) delete pPkt; pPkt = nullptr;
224 eID = PID_None;
225 }
226
CompileFunc(StdCompiler * pComp)227 void C4IDPacket::CompileFunc(StdCompiler *pComp)
228 {
229 // Packet ID
230 pComp->Value(mkNamingAdapt(mkIntAdaptT<uint8_t>(eID), "ID", PID_None));
231 // Compiling or Decompiling?
232 if (pComp->isDeserializer())
233 {
234 if (!pComp->Name(getPktName()))
235 { pComp->excCorrupt("C4IDPacket: Data value needed! Packet data missing!"); return; }
236 // Delete old packet
237 if (fOwnPkt) delete pPkt; pPkt = nullptr;
238 if (eID == PID_None) return;
239 // Search unpacking function
240 for (const C4PktHandlingData *pPData = PktHandlingData; pPData->ID != PID_None; pPData++)
241 if (pPData->ID == eID && pPData->FnUnpack)
242 {
243 pPkt = pPData->FnUnpack(pComp);
244 break;
245 }
246 if (!pPkt)
247 pComp->excCorrupt("C4IDPacket: could not unpack packet id %02x!", eID);
248 pComp->NameEnd();
249 }
250 else if (eID != PID_None)
251 // Just write
252 pComp->Value(mkNamingAdapt(*pPkt, getPktName()));
253 }
254
255 // *** C4PacketList
256
257 C4PacketList::C4PacketList() = default;
258
C4PacketList(const C4PacketList & List2)259 C4PacketList::C4PacketList(const C4PacketList &List2)
260 : C4PacketBase(List2),
261 pFirst(nullptr), pLast(nullptr)
262 {
263 Append(List2);
264 }
265
~C4PacketList()266 C4PacketList::~C4PacketList()
267 {
268 Clear();
269 }
270
getPktCnt() const271 int32_t C4PacketList::getPktCnt() const
272 {
273 int32_t iCnt = 0;
274 for (C4IDPacket *pPkt = pFirst; pPkt; pPkt = pPkt->pNext)
275 iCnt++;
276 return iCnt;
277 }
278
Add(C4IDPacket * pPkt)279 void C4PacketList::Add(C4IDPacket *pPkt)
280 {
281 assert(!pPkt->pNext);
282 (pLast ? pLast->pNext : pFirst) = pPkt;
283 pLast = pPkt;
284 }
285
AddHead(C4IDPacket * pPkt)286 void C4PacketList::AddHead(C4IDPacket *pPkt)
287 {
288 assert(!pPkt->pNext);
289 pPkt->pNext = pFirst;
290 pFirst = pPkt;
291 if (!pLast) pLast = pPkt;
292 }
293
Add(C4PacketType eType,C4PacketBase * pPkt)294 void C4PacketList::Add(C4PacketType eType, C4PacketBase *pPkt)
295 {
296 Add(new C4IDPacket(eType, pPkt));
297 }
298
AddHead(C4PacketType eType,C4PacketBase * pPkt)299 void C4PacketList::AddHead(C4PacketType eType, C4PacketBase *pPkt)
300 {
301 AddHead(new C4IDPacket(eType, pPkt));
302 }
303
Take(C4PacketList & List)304 void C4PacketList::Take(C4PacketList &List)
305 {
306 pFirst = List.pFirst;
307 pLast = List.pLast;
308 List.pFirst = List.pLast = nullptr;
309 }
310
Append(const C4PacketList & List)311 void C4PacketList::Append(const C4PacketList &List)
312 {
313 for (C4IDPacket *pPkt = List.firstPkt(); pPkt; pPkt = List.nextPkt(pPkt))
314 Add(new C4IDPacket(*pPkt));
315 }
316
Clear()317 void C4PacketList::Clear()
318 {
319 while (pFirst)
320 Delete(pFirst);
321 }
322
Remove(C4IDPacket * pPkt)323 void C4PacketList::Remove(C4IDPacket *pPkt)
324 {
325 if (pPkt == pFirst)
326 {
327 pFirst = pPkt->pNext;
328 if (pPkt == pLast)
329 pLast = nullptr;
330 }
331 else
332 {
333 C4IDPacket *pPrev;
334 for (pPrev = pFirst; pPrev && pPrev->pNext != pPkt; pPrev = pPrev->pNext) {}
335 if (pPrev)
336 {
337 pPrev->pNext = pPkt->pNext;
338 if (pPkt == pLast)
339 pLast = pPrev;
340 }
341 }
342 }
343
Delete(C4IDPacket * pPkt)344 void C4PacketList::Delete(C4IDPacket *pPkt)
345 {
346 Remove(pPkt);
347 delete pPkt;
348 }
349
CompileFunc(StdCompiler * pComp)350 void C4PacketList::CompileFunc(StdCompiler *pComp)
351 {
352 // unpack packets
353 if (pComp->isDeserializer())
354 {
355 // Read until no further sections available
356 while (pComp->Name("IDPacket"))
357 {
358 // Read the packet
359 C4IDPacket *pPkt = new C4IDPacket();
360 try
361 {
362 pComp->Value(*pPkt);
363 pComp->NameEnd();
364 }
365 catch (...)
366 {
367 delete pPkt;
368 throw;
369 }
370 // Terminator?
371 if (!pPkt->getPkt()) { delete pPkt; break; }
372 // Add to list
373 Add(pPkt);
374 }
375 pComp->NameEnd();
376 }
377 else
378 {
379 // Write all packets
380 for (C4IDPacket *pPkt = pFirst; pPkt; pPkt = pPkt->pNext)
381 pComp->Value(mkNamingAdapt(*pPkt, "IDPacket"));
382 // Terminate, if no naming is available
383 if (!pComp->hasNaming())
384 {
385 C4IDPacket Pkt;
386 pComp->Value(mkNamingAdapt(Pkt, "IDPacket"));
387 }
388 }
389 }
390
391 // *** C4PacketConn
392
C4PacketConn()393 C4PacketConn::C4PacketConn()
394 : iVer(C4XVER1*100 + C4XVER2)
395 {
396 }
397
C4PacketConn(const C4ClientCore & nCCore,uint32_t inConnID,const char * szPassword)398 C4PacketConn::C4PacketConn(const C4ClientCore &nCCore, uint32_t inConnID, const char *szPassword)
399 : iVer(C4XVER1*100 + C4XVER2),
400 iConnID(inConnID),
401 CCore(nCCore),
402 Password(szPassword)
403 {
404 }
405
CompileFunc(StdCompiler * pComp)406 void C4PacketConn::CompileFunc(StdCompiler *pComp)
407 {
408 pComp->Value(mkNamingAdapt(CCore, "CCore"));
409 pComp->Value(mkNamingAdapt(mkIntPackAdapt(iVer), "Version", -1));
410 pComp->Value(mkNamingAdapt(Password, "Password", ""));
411 pComp->Value(mkNamingAdapt(mkIntPackAdapt(iConnID), "ConnID", ~0u));
412 }
413
414 // *** C4PacketConnRe
415
416 C4PacketConnRe::C4PacketConnRe() = default;
417
C4PacketConnRe(bool fnOK,bool fWrongPassword,const char * sznMsg)418 C4PacketConnRe::C4PacketConnRe(bool fnOK, bool fWrongPassword, const char *sznMsg)
419 : fOK(fnOK),
420 fWrongPassword(fWrongPassword),
421 szMsg(sznMsg, true)
422 {
423 }
424
CompileFunc(StdCompiler * pComp)425 void C4PacketConnRe::CompileFunc(StdCompiler *pComp)
426 {
427 pComp->Value(mkNamingAdapt(fOK, "OK", true));
428 pComp->Value(mkNamingAdapt(szMsg, "Message", ""));
429 pComp->Value(mkNamingAdapt(fWrongPassword, "WrongPassword", false));
430 }
431
432 // *** C4PacketFwd
433
434 C4PacketFwd::C4PacketFwd() = default;
435
C4PacketFwd(const StdBuf & Pkt)436 C4PacketFwd::C4PacketFwd(const StdBuf &Pkt)
437 : Data(Pkt)
438 {
439 }
440
DoFwdTo(int32_t iClient) const441 bool C4PacketFwd::DoFwdTo(int32_t iClient) const
442 {
443 for (int32_t i = 0; i < iClientCnt; i++)
444 if (iClients[i] == iClient)
445 return !fNegativeList;
446 return fNegativeList;
447 }
448
SetData(const StdBuf & Pkt)449 void C4PacketFwd::SetData(const StdBuf &Pkt)
450 {
451 Data = Pkt;
452 }
453
SetListType(bool fnNegativeList)454 void C4PacketFwd::SetListType(bool fnNegativeList)
455 {
456 fNegativeList = fnNegativeList;
457 }
458
AddClient(int32_t iClient)459 void C4PacketFwd::AddClient(int32_t iClient)
460 {
461 if (iClientCnt + 1 > C4NetMaxClients) return;
462 // add
463 iClients[iClientCnt++] = iClient;
464 }
465
CompileFunc(StdCompiler * pComp)466 void C4PacketFwd::CompileFunc(StdCompiler *pComp)
467 {
468 pComp->Value(mkNamingAdapt(fNegativeList, "Negative", false));
469 pComp->Value(mkNamingAdapt(mkIntPackAdapt(iClientCnt), "ClientCnt", 0));
470 pComp->Value(mkNamingAdapt(mkArrayAdaptMap(iClients, iClientCnt, mkIntPackAdapt<int32_t>), "Clients", -1));
471 pComp->Value(mkNamingAdapt(Data, "Data"));
472 }
473
474 // *** C4PacketJoinData
475
CompileFunc(StdCompiler * pComp)476 void C4PacketJoinData::CompileFunc(StdCompiler *pComp)
477 {
478 pComp->Value(mkNamingAdapt(mkIntPackAdapt(iClientID), "ClientID", C4ClientIDUnknown));
479 pComp->Value(mkNamingAdapt(mkIntPackAdapt(iStartCtrlTick), "CtrlTick", -1));
480 pComp->Value(mkNamingAdapt(mkParAdapt(GameStatus, true), "GameStatus"));
481 pComp->Value(mkNamingAdapt(Dynamic, "Dynamic"));
482 pComp->Value(mkNamingAdapt(ScenarioParameterDefs, "ParameterDefs"));
483 pComp->Value(Parameters);
484 }
485
486 // *** C4PacketPing
487
C4PacketPing(uint32_t iPacketCounter,uint32_t iRemotePacketCounter)488 C4PacketPing::C4PacketPing(uint32_t iPacketCounter, uint32_t iRemotePacketCounter)
489 : tTime(C4TimeMilliseconds::Now()),
490 iPacketCounter(iPacketCounter)
491 {
492 }
493
getTravelTime() const494 uint32_t C4PacketPing::getTravelTime() const
495 {
496 return C4TimeMilliseconds::Now() - tTime;
497 }
498
CompileFunc(StdCompiler * pComp)499 void C4PacketPing::CompileFunc(StdCompiler *pComp)
500 {
501 uint32_t time = tTime.AsInt();
502 pComp->Value(mkNamingAdapt(time, "Time", 0U));
503 tTime = C4TimeMilliseconds(time);
504
505 pComp->Value(mkNamingAdapt(iPacketCounter, "PacketCounter", 0U));
506 }
507
508 // *** C4PacketResStatus
509
510 C4PacketResStatus::C4PacketResStatus() = default;
511
C4PacketResStatus(int32_t iResID,const C4Network2ResChunkData & nChunks)512 C4PacketResStatus::C4PacketResStatus(int32_t iResID, const C4Network2ResChunkData &nChunks)
513 : iResID(iResID), Chunks(nChunks)
514 {
515
516 }
517
CompileFunc(StdCompiler * pComp)518 void C4PacketResStatus::CompileFunc(StdCompiler *pComp)
519 {
520 pComp->Value(mkNamingAdapt(iResID, "ResID"));
521 pComp->Value(mkNamingAdapt(Chunks, "Chunks"));
522 }
523
524 // *** C4PacketResDiscover
525
526 C4PacketResDiscover::C4PacketResDiscover() = default;
527
isIDPresent(int32_t iID) const528 bool C4PacketResDiscover::isIDPresent(int32_t iID) const
529 {
530 for (int32_t i = 0; i < iDisIDCnt; i++)
531 if (iDisIDs[i] == iID)
532 return true;
533 return false;
534 }
535
AddDisID(int32_t iID)536 bool C4PacketResDiscover::AddDisID(int32_t iID)
537 {
538 if (iDisIDCnt + 1 >= int32_t(sizeof(iDisIDs) / sizeof(*iDisIDs))) return false;
539 // add
540 iDisIDs[iDisIDCnt++] = iID;
541 return true;
542 }
543
CompileFunc(StdCompiler * pComp)544 void C4PacketResDiscover::CompileFunc(StdCompiler *pComp)
545 {
546 pComp->Value(mkNamingAdapt(mkIntPackAdapt(iDisIDCnt), "DiscoverCnt", 0));
547 pComp->Value(mkNamingAdapt(mkArrayAdapt(iDisIDs, iDisIDCnt), "Discovers", -1));
548 }
549
550 // *** C4PacketResRequest
551
C4PacketResRequest(int32_t inID,int32_t inChunk)552 C4PacketResRequest::C4PacketResRequest(int32_t inID, int32_t inChunk)
553 : iReqID(inID), iReqChunk(inChunk)
554 {
555
556 }
557
CompileFunc(StdCompiler * pComp)558 void C4PacketResRequest::CompileFunc(StdCompiler *pComp)
559 {
560 pComp->Value(mkNamingAdapt(iReqID, "ResID", -1));
561 pComp->Value(mkNamingAdapt(mkIntPackAdapt(iReqChunk), "Chunk", -1));
562 }
563
564 // *** C4PacketControlReq
565
C4PacketControlReq(int32_t inCtrlTick)566 C4PacketControlReq::C4PacketControlReq(int32_t inCtrlTick)
567 : iCtrlTick(inCtrlTick)
568 {
569
570 }
571
CompileFunc(StdCompiler * pComp)572 void C4PacketControlReq::CompileFunc(StdCompiler *pComp)
573 {
574 pComp->Value(mkNamingAdapt(mkIntPackAdapt(iCtrlTick), "CtrlTick", -1));
575 }
576
577 // *** C4PacketActivateReq
578
CompileFunc(StdCompiler * pComp)579 void C4PacketActivateReq::CompileFunc(StdCompiler *pComp)
580 {
581 pComp->Value(mkNamingAdapt(mkIntPackAdapt(iTick), "Tick", -1));
582 }
583
584
585 // *** C4PacketControlPkt
586
CompileFunc(StdCompiler * pComp)587 void C4PacketControlPkt::CompileFunc(StdCompiler *pComp)
588 {
589 pComp->Value(mkNamingAdapt(mkIntAdaptT<uint8_t>(eDelivery), "Delivery", CDT_Queue));
590 pComp->Value(Ctrl);
591 }
592