forked from Mirrors/openclonk
595 lines
19 KiB
C++
595 lines
19 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
|
|
* Copyright (c) 2009-2016, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
#include "C4Include.h"
|
|
|
|
#include "C4Version.h"
|
|
#include "control/C4RoundResults.h"
|
|
#include "gui/C4GameLobby.h"
|
|
#include "network/C4GameControlNetwork.h"
|
|
#include "network/C4Network2.h"
|
|
#include "network/C4Network2Res.h"
|
|
|
|
// *** constants
|
|
|
|
// workaround
|
|
template <class T> struct unpack_class
|
|
{
|
|
static C4PacketBase *unpack(StdCompiler *pComp)
|
|
{
|
|
assert(pComp->isDeserializer());
|
|
T *pPkt = new T();
|
|
try
|
|
{
|
|
pComp->Value(*pPkt);
|
|
}
|
|
catch (...)
|
|
{
|
|
delete pPkt;
|
|
throw;
|
|
}
|
|
return pPkt;
|
|
}
|
|
};
|
|
|
|
#define PKT_UNPACK(T) unpack_class<T>::unpack
|
|
|
|
|
|
const C4PktHandlingData PktHandlingData[] =
|
|
{
|
|
|
|
// C4Network2IO (network thread)
|
|
{ PID_Conn, PC_Network, "Connection Request", true, true, PH_C4Network2IO, PKT_UNPACK(C4PacketConn) },
|
|
{ PID_ConnRe, PC_Network, "Connection Request Reply", true, true, PH_C4Network2IO, PKT_UNPACK(C4PacketConnRe) },
|
|
|
|
{ PID_Ping, PC_Network, "Ping", true, true, PH_C4Network2IO, PKT_UNPACK(C4PacketPing) },
|
|
{ PID_Pong, PC_Network, "Pong", true, true, PH_C4Network2IO, PKT_UNPACK(C4PacketPing) },
|
|
|
|
{ PID_FwdReq, PC_Network, "Forward Request", false, true, PH_C4Network2IO, PKT_UNPACK(C4PacketFwd) },
|
|
{ PID_Fwd, PC_Network, "Forward", false, true, PH_C4Network2IO, PKT_UNPACK(C4PacketFwd) },
|
|
|
|
{ PID_PostMortem, PC_Network, "Post Mortem", false, true, PH_C4Network2IO, PKT_UNPACK(C4PacketPostMortem) },
|
|
|
|
// C4Network2 (main thread)
|
|
{ PID_Conn, PC_Network, "Connection Request", true, false, PH_C4Network2, PKT_UNPACK(C4PacketConn) },
|
|
{ PID_ConnRe, PC_Network, "Connection Request Reply", true, false, PH_C4Network2, PKT_UNPACK(C4PacketConnRe) },
|
|
|
|
{ PID_Status, PC_Network, "Game Status", true, false, PH_C4Network2, PKT_UNPACK(C4Network2Status) },
|
|
{ PID_StatusAck, PC_Network, "Game Status Acknowledgement",true, false, PH_C4Network2, PKT_UNPACK(C4Network2Status) },
|
|
|
|
{ PID_ClientActReq, PC_Network, "Client Activation Request", false, false, PH_C4Network2, PKT_UNPACK(C4PacketActivateReq) },
|
|
|
|
{ PID_JoinData, PC_Network, "Join Data", false, false, PH_C4Network2, PKT_UNPACK(C4PacketJoinData) },
|
|
|
|
// C4Network2PlayerList (main thread)
|
|
{ PID_PlayerInfoUpdReq,PC_Network, "Player info update request",true, false, PH_C4Network2Players, PKT_UNPACK(C4PacketPlayerInfoUpdRequest) },
|
|
|
|
{ PID_LeagueRoundResults,PC_Network, "League round results", true, false, PH_C4Network2Players, PKT_UNPACK(C4PacketLeagueRoundResults) },
|
|
|
|
// C4GameLobby (main thread)
|
|
{ PID_LobbyCountdown,PC_Network,"Lobby countdown", false, false, PH_C4GUIMainDlg, PKT_UNPACK(C4GameLobby::C4PacketCountdown) },
|
|
{ PID_SetScenarioParameter,PC_Network,"Scenario parameter", false, false, PH_C4GUIMainDlg, PKT_UNPACK(C4GameLobby::C4PacketSetScenarioParameter) },
|
|
|
|
// C4Network2ClientList (main thread)
|
|
{ PID_Addr, PC_Network, "Client Address", false, false, PH_C4Network2ClientList, PKT_UNPACK(C4PacketAddr) },
|
|
{ PID_TCPSimOpen, PC_Network, "TCP simultaneous open req", false, false, PH_C4Network2ClientList, PKT_UNPACK(C4PacketTCPSimOpen) },
|
|
|
|
|
|
// C4Network2ResList (network thread)
|
|
{ PID_NetResDis, PC_Network, "Resource Discover", true, true, PH_C4Network2ResList, PKT_UNPACK(C4PacketResDiscover) },
|
|
{ PID_NetResStat, PC_Network, "Resource Status", false, true, PH_C4Network2ResList, PKT_UNPACK(C4PacketResStatus) },
|
|
{ PID_NetResDerive, PC_Network, "Resource Derive", false, true, PH_C4Network2ResList, PKT_UNPACK(C4Network2ResCore) },
|
|
{ PID_NetResReq, PC_Network, "Resource Request", false, true, PH_C4Network2ResList, PKT_UNPACK(C4PacketResRequest) },
|
|
{ PID_NetResData, PC_Network, "Resource Data", false, true, PH_C4Network2ResList, PKT_UNPACK(C4Network2ResChunk) },
|
|
|
|
// C4GameControlNetwork (network thread)
|
|
{ PID_Control, PC_Network, "Control", false, true, PH_C4GameControlNetwork, PKT_UNPACK(C4GameControlPacket) },
|
|
{ PID_ControlReq, PC_Network, "Control Request", false, true, PH_C4GameControlNetwork, PKT_UNPACK(C4PacketControlReq) },
|
|
// main thread
|
|
{ PID_ControlPkt, PC_Network, "Control Paket", false, false, PH_C4GameControlNetwork, PKT_UNPACK(C4PacketControlPkt) },
|
|
{ PID_ExecSyncCtrl, PC_Network, "Execute Sync Control", false, false, PH_C4GameControlNetwork, PKT_UNPACK(C4PacketExecSyncCtrl)},
|
|
|
|
// Control (Isn't send over network, handled only as part of a control list)
|
|
{ CID_ClientJoin, PC_Control, "Client Join", false, true, 0, PKT_UNPACK(C4ControlClientJoin) },
|
|
{ CID_ClientUpdate, PC_Control, "Client Update", false, true, 0, PKT_UNPACK(C4ControlClientUpdate)},
|
|
{ CID_ClientRemove, PC_Control, "Client Remove", false, true, 0, PKT_UNPACK(C4ControlClientRemove)},
|
|
{ CID_Vote, PC_Control, "Voting", false, true, 0, PKT_UNPACK(C4ControlVote) },
|
|
{ CID_VoteEnd, PC_Control, "Voting End", false, true, 0, PKT_UNPACK(C4ControlVoteEnd) },
|
|
{ CID_SyncCheck, PC_Control, "Sync Check", false, true, 0, PKT_UNPACK(C4ControlSyncCheck) },
|
|
{ CID_Synchronize, PC_Control, "Synchronize", false, true, 0, PKT_UNPACK(C4ControlSynchronize)},
|
|
{ CID_Set, PC_Control, "Set", false, true, 0, PKT_UNPACK(C4ControlSet) },
|
|
{ CID_Script, PC_Control, "Script", false, true, 0, PKT_UNPACK(C4ControlScript) },
|
|
{ CID_MsgBoardReply,PC_Control, "Message Board Reply", false, true, 0, PKT_UNPACK(C4ControlMsgBoardReply)},
|
|
{ CID_MsgBoardCmd ,PC_Control, "Message Board Command", false, true, 0, PKT_UNPACK(C4ControlMsgBoardCmd)},
|
|
{ CID_PlrInfo, PC_Control, "Player Info", false, true, 0, PKT_UNPACK(C4ControlPlayerInfo) },
|
|
{ CID_JoinPlr, PC_Control, "Join Player", false, true, 0, PKT_UNPACK(C4ControlJoinPlayer) },
|
|
{ CID_RemovePlr, PC_Control, "Remove Player", false, true, 0, PKT_UNPACK(C4ControlRemovePlr) },
|
|
{ CID_PlrSelect, PC_Control, "Player Select", false, true, 0, PKT_UNPACK(C4ControlPlayerSelect)},
|
|
{ CID_PlrControl, PC_Control, "Player Control", false, true, 0, PKT_UNPACK(C4ControlPlayerControl)},
|
|
{ CID_PlrAction, PC_Control, "Player Self-Mgmt Action", false, true, 0, PKT_UNPACK(C4ControlPlayerAction)},
|
|
{ CID_PlrMouseMove, PC_Control, "Player Mouse Movement", false, true, 0, PKT_UNPACK(C4ControlPlayerMouse)},
|
|
{ CID_Message, PC_Control, "Message", false, true, 0, PKT_UNPACK(C4ControlMessage) },
|
|
{ CID_MenuCommand, PC_Control, "Menu Command", false, true, 0, PKT_UNPACK(C4ControlMenuCommand)},
|
|
{ CID_EMMoveObj, PC_Control, "EM Move Obj", false, true, 0, PKT_UNPACK(C4ControlEMMoveObject)},
|
|
{ CID_EMDrawTool, PC_Control, "EM Draw Tool", false, true, 0, PKT_UNPACK(C4ControlEMDrawTool) },
|
|
{ CID_ReInitScenario,PC_Control, "Reinit Scenario", false, true, 0, PKT_UNPACK(C4ControlReInitScenario) },
|
|
{ CID_EditGraph, PC_Control, "Edit Graph", false, true, 0, PKT_UNPACK(C4ControlEditGraph) },
|
|
|
|
{ CID_DebugRec, PC_Control, "Debug Rec", false, true, 0, PKT_UNPACK(C4ControlDebugRec) },
|
|
|
|
// EOL
|
|
{ PID_None, PC_Network, nullptr, false, true, 0, nullptr }
|
|
};
|
|
|
|
const char *PacketNameByID(C4PacketType eID)
|
|
{
|
|
for (const C4PktHandlingData *pPData = PktHandlingData; pPData->ID != PID_None; pPData++)
|
|
if (pPData->ID == eID)
|
|
return pPData->Name;
|
|
return "?!?";
|
|
}
|
|
|
|
// *** C4PacketBase
|
|
|
|
C4PacketBase::C4PacketBase() = default;
|
|
|
|
C4PacketBase::~C4PacketBase() = default;
|
|
|
|
C4NetIOPacket C4PacketBase::pack(const C4NetIO::addr_t &addr) const
|
|
{
|
|
return C4NetIOPacket(DecompileToBuf<StdCompilerBinWrite>(*this), addr);
|
|
}
|
|
|
|
C4NetIOPacket C4PacketBase::pack(uint8_t cStatus, const C4NetIO::addr_t &addr) const
|
|
{
|
|
return C4NetIOPacket(DecompileToBuf<StdCompilerBinWrite>(mkInsertAdapt(mkDecompileAdapt(*this), cStatus)), addr);
|
|
}
|
|
|
|
void C4PacketBase::unpack(const C4NetIOPacket &Pkt, char *pStatus)
|
|
{
|
|
if (pStatus) *pStatus = Pkt.getStatus();
|
|
CompileFromBuf<StdCompilerBinRead>(*this, pStatus ? Pkt.getPBuf() : Pkt.getRef());
|
|
}
|
|
|
|
|
|
// *** C4PktBuf
|
|
|
|
C4PktBuf::C4PktBuf() = default;
|
|
|
|
C4PktBuf::C4PktBuf(const C4PktBuf &rCopy) : C4PacketBase(rCopy)
|
|
{
|
|
Data.Copy(rCopy.Data);
|
|
}
|
|
|
|
C4PktBuf::C4PktBuf(const StdBuf &rCpyData)
|
|
{
|
|
Data.Copy(rCpyData);
|
|
}
|
|
|
|
void C4PktBuf::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(Data, "Data"));
|
|
}
|
|
|
|
// *** C4IDPacket
|
|
|
|
C4IDPacket::C4IDPacket() = default;
|
|
|
|
C4IDPacket::C4IDPacket(C4PacketType eID, C4PacketBase *pPkt, bool fTakePkt)
|
|
: eID(eID), pPkt(pPkt), fOwnPkt(fTakePkt), pNext(nullptr)
|
|
{
|
|
|
|
}
|
|
|
|
C4IDPacket::C4IDPacket(const C4IDPacket &Packet2)
|
|
: C4PacketBase(Packet2)
|
|
{
|
|
// kinda hacky (note this might throw an uncaught exception)
|
|
C4PacketBase::unpack(Packet2.C4PacketBase::pack());
|
|
}
|
|
|
|
C4IDPacket::~C4IDPacket()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
const char *C4IDPacket::getPktName() const
|
|
{
|
|
// Use map
|
|
for (const C4PktHandlingData *pPData = PktHandlingData; pPData->ID != PID_None; pPData++)
|
|
if (pPData->ID == eID && pPData->Name)
|
|
return pPData->Name;
|
|
return "Unknown Packet Type";
|
|
}
|
|
|
|
void C4IDPacket::Default()
|
|
{
|
|
eID = PID_None; pPkt = nullptr;
|
|
}
|
|
|
|
void C4IDPacket::Clear()
|
|
{
|
|
if (fOwnPkt) delete pPkt;
|
|
pPkt = nullptr;
|
|
eID = PID_None;
|
|
}
|
|
|
|
void C4IDPacket::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
// Packet ID
|
|
pComp->Value(mkNamingAdapt(mkIntAdaptT<uint8_t>(eID), "ID", PID_None));
|
|
// Compiling or Decompiling?
|
|
if (pComp->isDeserializer())
|
|
{
|
|
if (!pComp->Name(getPktName()))
|
|
{ pComp->excCorrupt("C4IDPacket: Data value needed! Packet data missing!"); return; }
|
|
// Delete old packet
|
|
if (fOwnPkt) delete pPkt;
|
|
pPkt = nullptr;
|
|
if (eID == PID_None) return;
|
|
// Search unpacking function
|
|
for (const C4PktHandlingData *pPData = PktHandlingData; pPData->ID != PID_None; pPData++)
|
|
if (pPData->ID == eID && pPData->FnUnpack)
|
|
{
|
|
pPkt = pPData->FnUnpack(pComp);
|
|
break;
|
|
}
|
|
if (!pPkt)
|
|
pComp->excCorrupt("C4IDPacket: could not unpack packet id %02x!", eID);
|
|
pComp->NameEnd();
|
|
}
|
|
else if (eID != PID_None)
|
|
// Just write
|
|
pComp->Value(mkNamingAdapt(*pPkt, getPktName()));
|
|
}
|
|
|
|
// *** C4PacketList
|
|
|
|
C4PacketList::C4PacketList() = default;
|
|
|
|
C4PacketList::C4PacketList(const C4PacketList &List2)
|
|
: C4PacketBase(List2),
|
|
pFirst(nullptr), pLast(nullptr)
|
|
{
|
|
Append(List2);
|
|
}
|
|
|
|
C4PacketList::~C4PacketList()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
int32_t C4PacketList::getPktCnt() const
|
|
{
|
|
int32_t iCnt = 0;
|
|
for (C4IDPacket *pPkt = pFirst; pPkt; pPkt = pPkt->pNext)
|
|
iCnt++;
|
|
return iCnt;
|
|
}
|
|
|
|
void C4PacketList::Add(C4IDPacket *pPkt)
|
|
{
|
|
assert(!pPkt->pNext);
|
|
(pLast ? pLast->pNext : pFirst) = pPkt;
|
|
pLast = pPkt;
|
|
}
|
|
|
|
void C4PacketList::AddHead(C4IDPacket *pPkt)
|
|
{
|
|
assert(!pPkt->pNext);
|
|
pPkt->pNext = pFirst;
|
|
pFirst = pPkt;
|
|
if (!pLast) pLast = pPkt;
|
|
}
|
|
|
|
void C4PacketList::Add(C4PacketType eType, C4PacketBase *pPkt)
|
|
{
|
|
Add(new C4IDPacket(eType, pPkt));
|
|
}
|
|
|
|
void C4PacketList::AddHead(C4PacketType eType, C4PacketBase *pPkt)
|
|
{
|
|
AddHead(new C4IDPacket(eType, pPkt));
|
|
}
|
|
|
|
void C4PacketList::Take(C4PacketList &List)
|
|
{
|
|
pFirst = List.pFirst;
|
|
pLast = List.pLast;
|
|
List.pFirst = List.pLast = nullptr;
|
|
}
|
|
|
|
void C4PacketList::Append(const C4PacketList &List)
|
|
{
|
|
for (C4IDPacket *pPkt = List.firstPkt(); pPkt; pPkt = List.nextPkt(pPkt))
|
|
Add(new C4IDPacket(*pPkt));
|
|
}
|
|
|
|
void C4PacketList::Clear()
|
|
{
|
|
while (pFirst)
|
|
Delete(pFirst);
|
|
}
|
|
|
|
void C4PacketList::Remove(C4IDPacket *pPkt)
|
|
{
|
|
if (pPkt == pFirst)
|
|
{
|
|
pFirst = pPkt->pNext;
|
|
if (pPkt == pLast)
|
|
pLast = nullptr;
|
|
}
|
|
else
|
|
{
|
|
C4IDPacket *pPrev;
|
|
for (pPrev = pFirst; pPrev && pPrev->pNext != pPkt; pPrev = pPrev->pNext) {}
|
|
if (pPrev)
|
|
{
|
|
pPrev->pNext = pPkt->pNext;
|
|
if (pPkt == pLast)
|
|
pLast = pPrev;
|
|
}
|
|
}
|
|
}
|
|
|
|
void C4PacketList::Delete(C4IDPacket *pPkt)
|
|
{
|
|
Remove(pPkt);
|
|
delete pPkt;
|
|
}
|
|
|
|
void C4PacketList::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
// unpack packets
|
|
if (pComp->isDeserializer())
|
|
{
|
|
// Read until no further sections available
|
|
while (pComp->Name("IDPacket"))
|
|
{
|
|
// Read the packet
|
|
C4IDPacket *pPkt = new C4IDPacket();
|
|
try
|
|
{
|
|
pComp->Value(*pPkt);
|
|
pComp->NameEnd();
|
|
}
|
|
catch (...)
|
|
{
|
|
delete pPkt;
|
|
throw;
|
|
}
|
|
// Terminator?
|
|
if (!pPkt->getPkt()) { delete pPkt; break; }
|
|
// Add to list
|
|
Add(pPkt);
|
|
}
|
|
pComp->NameEnd();
|
|
}
|
|
else
|
|
{
|
|
// Write all packets
|
|
for (C4IDPacket *pPkt = pFirst; pPkt; pPkt = pPkt->pNext)
|
|
pComp->Value(mkNamingAdapt(*pPkt, "IDPacket"));
|
|
// Terminate, if no naming is available
|
|
if (!pComp->hasNaming())
|
|
{
|
|
C4IDPacket Pkt;
|
|
pComp->Value(mkNamingAdapt(Pkt, "IDPacket"));
|
|
}
|
|
}
|
|
}
|
|
|
|
// *** C4PacketConn
|
|
|
|
C4PacketConn::C4PacketConn()
|
|
: iVer(C4XVER1*100 + C4XVER2)
|
|
{
|
|
}
|
|
|
|
C4PacketConn::C4PacketConn(const C4ClientCore &nCCore, uint32_t inConnID, const char *szPassword)
|
|
: iVer(C4XVER1*100 + C4XVER2),
|
|
iConnID(inConnID),
|
|
CCore(nCCore),
|
|
Password(szPassword)
|
|
{
|
|
}
|
|
|
|
void C4PacketConn::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(CCore, "CCore"));
|
|
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iVer), "Version", -1));
|
|
pComp->Value(mkNamingAdapt(Password, "Password", ""));
|
|
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iConnID), "ConnID", ~0u));
|
|
}
|
|
|
|
// *** C4PacketConnRe
|
|
|
|
C4PacketConnRe::C4PacketConnRe() = default;
|
|
|
|
C4PacketConnRe::C4PacketConnRe(bool fnOK, bool fWrongPassword, const char *sznMsg)
|
|
: fOK(fnOK),
|
|
fWrongPassword(fWrongPassword),
|
|
szMsg(sznMsg, true)
|
|
{
|
|
}
|
|
|
|
void C4PacketConnRe::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(fOK, "OK", true));
|
|
pComp->Value(mkNamingAdapt(szMsg, "Message", ""));
|
|
pComp->Value(mkNamingAdapt(fWrongPassword, "WrongPassword", false));
|
|
}
|
|
|
|
// *** C4PacketFwd
|
|
|
|
C4PacketFwd::C4PacketFwd() = default;
|
|
|
|
C4PacketFwd::C4PacketFwd(const StdBuf &Pkt)
|
|
: Data(Pkt)
|
|
{
|
|
}
|
|
|
|
bool C4PacketFwd::DoFwdTo(int32_t iClient) const
|
|
{
|
|
for (int32_t i = 0; i < iClientCnt; i++)
|
|
if (iClients[i] == iClient)
|
|
return !fNegativeList;
|
|
return fNegativeList;
|
|
}
|
|
|
|
void C4PacketFwd::SetData(const StdBuf &Pkt)
|
|
{
|
|
Data = Pkt;
|
|
}
|
|
|
|
void C4PacketFwd::SetListType(bool fnNegativeList)
|
|
{
|
|
fNegativeList = fnNegativeList;
|
|
}
|
|
|
|
void C4PacketFwd::AddClient(int32_t iClient)
|
|
{
|
|
if (iClientCnt + 1 > C4NetMaxClients) return;
|
|
// add
|
|
iClients[iClientCnt++] = iClient;
|
|
}
|
|
|
|
void C4PacketFwd::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(fNegativeList, "Negative", false));
|
|
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iClientCnt), "ClientCnt", 0));
|
|
pComp->Value(mkNamingAdapt(mkArrayAdaptMap(iClients, iClientCnt, mkIntPackAdapt<int32_t>), "Clients", -1));
|
|
pComp->Value(mkNamingAdapt(Data, "Data"));
|
|
}
|
|
|
|
// *** C4PacketJoinData
|
|
|
|
void C4PacketJoinData::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iClientID), "ClientID", C4ClientIDUnknown));
|
|
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iStartCtrlTick), "CtrlTick", -1));
|
|
pComp->Value(mkNamingAdapt(mkParAdapt(GameStatus, true), "GameStatus"));
|
|
pComp->Value(mkNamingAdapt(Dynamic, "Dynamic"));
|
|
pComp->Value(mkNamingAdapt(ScenarioParameterDefs, "ParameterDefs"));
|
|
pComp->Value(Parameters);
|
|
}
|
|
|
|
// *** C4PacketPing
|
|
|
|
C4PacketPing::C4PacketPing(uint32_t iPacketCounter, uint32_t iRemotePacketCounter)
|
|
: tTime(C4TimeMilliseconds::Now()),
|
|
iPacketCounter(iPacketCounter)
|
|
{
|
|
}
|
|
|
|
uint32_t C4PacketPing::getTravelTime() const
|
|
{
|
|
return C4TimeMilliseconds::Now() - tTime;
|
|
}
|
|
|
|
void C4PacketPing::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
uint32_t time = tTime.AsInt();
|
|
pComp->Value(mkNamingAdapt(time, "Time", 0U));
|
|
tTime = C4TimeMilliseconds(time);
|
|
|
|
pComp->Value(mkNamingAdapt(iPacketCounter, "PacketCounter", 0U));
|
|
}
|
|
|
|
// *** C4PacketResStatus
|
|
|
|
C4PacketResStatus::C4PacketResStatus() = default;
|
|
|
|
C4PacketResStatus::C4PacketResStatus(int32_t iResID, const C4Network2ResChunkData &nChunks)
|
|
: iResID(iResID), Chunks(nChunks)
|
|
{
|
|
|
|
}
|
|
|
|
void C4PacketResStatus::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(iResID, "ResID"));
|
|
pComp->Value(mkNamingAdapt(Chunks, "Chunks"));
|
|
}
|
|
|
|
// *** C4PacketResDiscover
|
|
|
|
C4PacketResDiscover::C4PacketResDiscover() = default;
|
|
|
|
bool C4PacketResDiscover::isIDPresent(int32_t iID) const
|
|
{
|
|
for (int32_t i = 0; i < iDisIDCnt; i++)
|
|
if (iDisIDs[i] == iID)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool C4PacketResDiscover::AddDisID(int32_t iID)
|
|
{
|
|
if (iDisIDCnt + 1 >= int32_t(sizeof(iDisIDs) / sizeof(*iDisIDs))) return false;
|
|
// add
|
|
iDisIDs[iDisIDCnt++] = iID;
|
|
return true;
|
|
}
|
|
|
|
void C4PacketResDiscover::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iDisIDCnt), "DiscoverCnt", 0));
|
|
pComp->Value(mkNamingAdapt(mkArrayAdapt(iDisIDs, iDisIDCnt), "Discovers", -1));
|
|
}
|
|
|
|
// *** C4PacketResRequest
|
|
|
|
C4PacketResRequest::C4PacketResRequest(int32_t inID, int32_t inChunk)
|
|
: iReqID(inID), iReqChunk(inChunk)
|
|
{
|
|
|
|
}
|
|
|
|
void C4PacketResRequest::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(iReqID, "ResID", -1));
|
|
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iReqChunk), "Chunk", -1));
|
|
}
|
|
|
|
// *** C4PacketControlReq
|
|
|
|
C4PacketControlReq::C4PacketControlReq(int32_t inCtrlTick)
|
|
: iCtrlTick(inCtrlTick)
|
|
{
|
|
|
|
}
|
|
|
|
void C4PacketControlReq::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iCtrlTick), "CtrlTick", -1));
|
|
}
|
|
|
|
// *** C4PacketActivateReq
|
|
|
|
void C4PacketActivateReq::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(mkIntPackAdapt(iTick), "Tick", -1));
|
|
}
|
|
|
|
|
|
// *** C4PacketControlPkt
|
|
|
|
void C4PacketControlPkt::CompileFunc(StdCompiler *pComp)
|
|
{
|
|
pComp->Value(mkNamingAdapt(mkIntAdaptT<uint8_t>(eDelivery), "Delivery", CDT_Queue));
|
|
pComp->Value(Ctrl);
|
|
}
|