openclonk/src/network/C4PacketBase.h

300 lines
7.5 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.
*/
#ifndef INC_C4PacketBase
#define INC_C4PacketBase
#include "network/C4NetIO.h"
// *** packet base class
class C4PacketBase
{
friend class C4PacketList;
public:
C4PacketBase();
virtual ~C4PacketBase();
// virtual functions to implement by derived classes
virtual void CompileFunc(StdCompiler *pComp) = 0;
// conversion (using above functions)
C4NetIOPacket pack(const C4NetIO::addr_t &addr = C4NetIO::addr_t()) const;
C4NetIOPacket pack(uint8_t cStatus, const C4NetIO::addr_t &addr = C4NetIO::addr_t()) const;
void unpack(const C4NetIOPacket &Pkt, char *pStatus = nullptr);
};
inline C4NetIOPacket MkC4NetIOPacket(char cStatus, const class C4PacketBase &Pkt, const C4NetIO::addr_t &addr = C4NetIO::addr_t())
{
return Pkt.pack(cStatus, addr);
}
// Filename Adaptor
// Converts the network filename separator to the native filename separator
struct C4NetFilenameAdapt
{
StdStrBuf &FileName;
explicit C4NetFilenameAdapt(StdStrBuf &FileName) : FileName(FileName) { }
inline void CompileFunc(StdCompiler *pComp) const
{
#ifdef _WIN32
pComp->Value(FileName);
#else
StdCopyStrBuf FileName2;
if (pComp->isSerializer() && FileName)
{
FileName2.Copy(FileName);
SReplaceChar(FileName2.getMData(),DirectorySeparator,'\\');
}
pComp->Value(FileName2);
if (pComp->isDeserializer())
{
FileName.Take(FileName2);
SReplaceChar(FileName.getMData(),'\\',DirectorySeparator);
}
#endif
}
template <class T> bool operator == (const T &rVal) { return FileName == rVal; }
template <class T> C4NetFilenameAdapt &operator = (const T &rVal) { FileName = rVal; return *this; }
};
inline C4NetFilenameAdapt mkNetFilenameAdapt(StdStrBuf &FileName) { return C4NetFilenameAdapt(FileName); }
// enumaration of all used packet types
enum C4PacketType
{
PID_None = 0xFF,
// *** network
// * base packets
// ping
PID_Ping = 0x00,
PID_Pong = 0x01,
// connecting
PID_Conn = 0x02,
PID_ConnRe = 0x03,
// msg forwarding
PID_FwdReq = 0x04,
PID_Fwd = 0x05,
// post mortem
PID_PostMortem = 0x06,
// (packets before this ID won't be recovered post-mortem)
PID_PacketLogStart = 0x04,
// * game
// game status
PID_Status = 0x10,
PID_StatusAck = 0x11,
// client address propagation
PID_Addr = 0x12,
// activation request
PID_ClientActReq = 0x13,
// request to perform TCP simultaneous open
PID_TCPSimOpen = 0x14,
// all data a client needs to get started
PID_JoinData = 0x15,
// player info
PID_PlayerInfoUpdReq = 0x16,
// round results league info
PID_LeagueRoundResults = 0x17,
// * lobby
PID_LobbyCountdown = 0x20,
PID_SetScenarioParameter = 0x21, // scenario parameter update
// * resources
PID_NetResDis = 0x30,
PID_NetResStat = 0x31,
PID_NetResDerive = 0x32,
PID_NetResReq = 0x33,
PID_NetResData = 0x34,
// * control
PID_Control = 0x40,
PID_ControlReq = 0x41,
PID_ControlPkt = 0x42,
PID_ExecSyncCtrl = 0x43,
// *** control
CID_First = 0x80,
CID_ClientJoin = CID_First | 0x00,
CID_ClientUpdate = CID_First | 0x01,
CID_ClientRemove = CID_First | 0x02,
CID_Vote = CID_First | 0x03,
CID_VoteEnd = CID_First | 0x04,
CID_SyncCheck = CID_First | 0x05,
CID_Synchronize = CID_First | 0x06,
CID_Set = CID_First | 0x07,
CID_Script = CID_First | 0x08,
CID_MsgBoardReply = CID_First | 0x09,
CID_MsgBoardCmd = CID_First | 0x0A,
CID_PlrInfo = CID_First | 0x10,
CID_JoinPlr = CID_First | 0x11,
CID_RemovePlr = CID_First | 0x12,
CID_PlrSelect = CID_First | 0x20,
CID_PlrControl = CID_First | 0x21,
CID_Message = CID_First | 0x23,
CID_PlrAction = CID_First | 0x24,
CID_PlrMouseMove = CID_First | 0x25,
CID_EMMoveObj = CID_First | 0x30,
CID_EMDrawTool = CID_First | 0x31,
CID_ReInitScenario= CID_First | 0x32,
CID_EditGraph = CID_First | 0x33,
CID_DebugRec = CID_First | 0x40,
CID_MenuCommand = CID_First | 0x41,
// Note: There are some more packet types in src/netpuncher/C4PuncherPacket.h
// They have been picked to be distinct from these for safety, not for necessary.
};
// packet classes
enum C4PacketClass
{
PC_Network, // network packet - internal stuff
PC_Control // control packet - game data (saved in records)
};
// enumeration of packet handlers
enum C4PacketHandlerID
{
PH_C4Network2IO = 1 << 0, // network i/o class
PH_C4Network2 = 1 << 1, // main network class
PH_C4GUIMainDlg = 1 << 2, // network lobby class
PH_C4Network2ClientList = 1 << 3, // client list class
PH_C4Network2Players = 1 << 4, // player list class
PH_C4Network2ResList = 1 << 5, // resource list class
PH_C4GameControlNetwork = 1 << 6, // network control class
};
// packet handling data
struct C4PktHandlingData
{
C4PacketType ID;
C4PacketClass Class;
const char *Name;
bool AcceptedOnly;
bool ProcByThread;
int32_t HandlerID; // (C4PacketHandlerID)
class C4PacketBase *(*FnUnpack)(StdCompiler *pComp);
};
extern const C4PktHandlingData PktHandlingData[];
const char *PacketNameByID(C4PacketType eID);
// *** general packet types
// raw packet: contains std buffer
class C4PktBuf : public C4PacketBase
{
protected:
StdCopyBuf Data;
public:
C4PktBuf();
C4PktBuf(const C4PktBuf &rCopy);
C4PktBuf(const StdBuf &rCpyData);
size_t getSize() const { return Data.getSize(); }
const void *getData() const { return Data.getData(); }
void CompileFunc(StdCompiler *pComp) override;
};
// "identified" packet: packet with packet type id
class C4IDPacket : public C4PacketBase
{
friend class C4PacketList;
public:
C4IDPacket();
C4IDPacket(C4PacketType eID, C4PacketBase *pPkt, bool fTakePkt = true);
C4IDPacket(const C4IDPacket &Packet2);
~C4IDPacket() override;
protected:
C4PacketType eID{PID_None};
C4PacketBase *pPkt{nullptr};
bool fOwnPkt{true};
// used by C4PacketList
C4IDPacket *pNext{nullptr};
public:
C4PacketType getPktType() const { return eID; }
C4PacketBase *getPkt() const { return pPkt; }
const char *getPktName() const;
void Clear();
void Default();
void Set(C4PacketType eType, C4PacketBase *pPkt);
void CompileFunc(StdCompiler *pComp) override;
};
// list of identified packets
class C4PacketList : public C4PacketBase
{
public:
C4PacketList();
C4PacketList(const C4PacketList &List2);
~C4PacketList() override;
protected:
C4IDPacket *pFirst{nullptr}, *pLast{nullptr};
public:
C4IDPacket *firstPkt() const { return pFirst; }
C4IDPacket *nextPkt(C4IDPacket *pPkt) const { return pPkt->pNext; }
int32_t getPktCnt() const;
void Add(C4IDPacket *pPkt);
void AddHead(C4IDPacket *pPkt);
void Add(C4PacketType eType, C4PacketBase *pPkt);
void AddHead(C4PacketType eType, C4PacketBase *pPkt);
void Take(C4PacketList &List);
void Append(const C4PacketList &List);
void Clear();
void Remove(C4IDPacket *pPkt);
void Delete(C4IDPacket *pPkt);
void CompileFunc(StdCompiler *pComp) override;
};
#endif // INC_C4PacketBase