1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2016-2018, The OpenClonk Team and contributors
6 * Copyright (c) 2017-2020, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18#pragma once
19
20#include "C4NetIO.h"
21#include "StdFile.h"
22
23// *** packet base class
24
25class C4PacketBase
26{
27 friend class C4PacketList;
28
29public:
30 C4PacketBase() {}
31 virtual ~C4PacketBase() {}
32
33 // virtual functions to implement by derived classes
34 virtual void CompileFunc(StdCompiler *pComp) = 0;
35
36 // conversion (using above functions)
37 C4NetIOPacket pack(uint8_t cStatus, const C4NetIO::addr_t &addr = C4NetIO::addr_t()) const;
38 void unpack(const C4NetIOPacket &Pkt, char *pStatus = nullptr);
39};
40
41inline C4NetIOPacket MkC4NetIOPacket(char cStatus, const class C4PacketBase &Pkt, const C4NetIO::addr_t &addr = C4NetIO::addr_t())
42{
43 return Pkt.pack(cStatus, addr);
44}
45
46// Filename Adaptor
47// Converts the network filename separator to the native filename separator
48struct C4NetFilenameAdapt
49{
50 StdStrBuf &FileName;
51 explicit C4NetFilenameAdapt(StdStrBuf &FileName) : FileName(FileName) {}
52 inline void CompileFunc(StdCompiler *pComp) const
53 {
54#ifdef _WIN32
55 pComp->Value(FileName);
56#else
57 StdStrBuf FileName2;
58 if (pComp->isDecompiler() && FileName)
59 {
60 FileName2.Copy(Buf2: FileName);
61 SReplaceChar(str: FileName2.getMData(), DirectorySeparator, tc: '\\');
62 }
63 pComp->Value(rStruct&: FileName2);
64 if (pComp->isCompiler())
65 {
66 FileName.Take(Buf2&: FileName2);
67 SReplaceChar(str: FileName.getMData(), fc: '\\', DirectorySeparator);
68 }
69#endif
70 }
71
72 template <class T> bool operator==(const T &rVal) { return FileName == rVal; }
73 template <class T> C4NetFilenameAdapt &operator=(const T &rVal) { FileName.Ref(rVal); return *this; }
74};
75
76inline C4NetFilenameAdapt mkNetFilenameAdapt(StdStrBuf &FileName) { return C4NetFilenameAdapt(FileName); }
77
78// enumaration of all used packet types
79enum C4PacketType
80{
81 PID_None = 0xFF,
82
83 // *** network
84
85 // * base packets
86 // ping
87 PID_Ping = 0x00,
88 PID_Pong = 0x01,
89
90 // connecting
91 PID_Conn = 0x02,
92 PID_ConnRe = 0x03,
93
94 // msg forwarding
95 PID_FwdReq = 0x04,
96 PID_Fwd = 0x05,
97
98 // post mortem
99 PID_PostMortem = 0x06,
100
101 // (packets before this ID won't be recovered post-mortem)
102 PID_PacketLogStart = 0x04,
103
104 // * game
105 // game status
106 PID_Status = 0x10,
107 PID_StatusAck = 0x11,
108
109 // client address propagation
110 PID_Addr = 0x12,
111
112 // activation request
113 PID_ClientActReq = 0x13,
114
115 // request to perform TCP simultaneous open
116 PID_TCPSimOpen = 0x14,
117
118 // all data a client needs to get started
119 PID_JoinData = 0x15,
120
121 // player info
122 PID_PlayerInfoUpdReq = 0x16,
123
124 // round results league info
125 PID_LeagueRoundResults = 0x17,
126
127 // * lobby
128 PID_LobbyCountdown = 0x20,
129 PID_ReadyCheck = 0x21,
130
131 // * ressources
132 PID_NetResDis = 0x30,
133 PID_NetResStat = 0x31,
134 PID_NetResDerive = 0x32,
135 PID_NetResReq = 0x33,
136 PID_NetResData = 0x34,
137
138 // * control
139 PID_Control = 0x40,
140 PID_ControlReq = 0x41,
141 PID_ControlPkt = 0x42,
142 PID_ExecSyncCtrl = 0x43,
143
144 // *** control
145 CID_First = 0x80,
146
147 CID_ClientJoin = CID_First | 0x00,
148 CID_ClientUpdate = CID_First | 0x01,
149 CID_ClientRemove = CID_First | 0x02,
150
151 CID_Vote = CID_First | 0x03,
152 CID_VoteEnd = CID_First | 0x04,
153
154 CID_SyncCheck = CID_First | 0x05,
155 CID_Synchronize = CID_First | 0x06,
156 CID_Set = CID_First | 0x07,
157 CID_Script = CID_First | 0x08,
158
159 CID_PlrInfo = CID_First | 0x10,
160 CID_JoinPlr = CID_First | 0x11,
161 CID_RemovePlr = CID_First | 0x12,
162
163 CID_PlrSelect = CID_First | 0x20,
164 CID_PlrControl = CID_First | 0x21,
165 CID_PlrCommand = CID_First | 0x22,
166 CID_Message = CID_First | 0x23,
167
168 CID_EMMoveObj = CID_First | 0x30,
169 CID_EMDrawTool = CID_First | 0x31,
170 CID_EMDropDef = CID_First | 0x32,
171
172 CID_DebugRec = CID_First | 0x40,
173
174 // the following replace the old "internal" scripts
175 // to ensure that the behavior stays exactly the same, they still need to execute the same script
176 CID_MessageBoardAnswer = CID_First | 0x50,
177 CID_CustomCommand = CID_First | 0x51,
178 CID_InitScenarioPlayer = CID_First | 0x52,
179 CID_ActivateGameGoalMenu = CID_First | 0x53,
180 CID_ToggleHostility = CID_First | 0x54,
181 CID_SurrenderPlayer = CID_First | 0x55,
182 CID_ActivateGameGoalRule = CID_First | 0x56,
183 CID_SetPlayerTeam = CID_First | 0x57,
184 CID_EliminatePlayer = CID_First | 0x58
185
186 // Note: There are some more packet types in src/C4PuncherPacket.h
187 // They have been picked to be distinct from these for safety, not for necessity.
188};
189
190// packet classes
191enum C4PacketClass
192{
193 PC_Network, // network packet - internal stuff
194 PC_Control, // control packet - game data (saved in records)
195};
196
197// enumeration of packet handlers
198enum C4PacketHandlerID
199{
200 PH_C4Network2IO = 1 << 0, // network i/o class
201 PH_C4Network2 = 1 << 1, // main network class
202 PH_C4GUIMainDlg = 1 << 2, // network lobby class
203 PH_C4Network2ClientList = 1 << 3, // client list class
204 PH_C4Network2Players = 1 << 4, // player list class
205 PH_C4Network2ResList = 1 << 5, // ressource list class
206 PH_C4GameControlNetwork = 1 << 6, // network control class
207};
208
209// packet handling data
210struct C4PktHandlingData
211{
212 C4PacketType ID;
213 C4PacketClass Class;
214 const char *Name;
215
216 bool AcceptedOnly;
217 bool ProcByThread;
218
219 int32_t HandlerID; // (C4PacketHandlerID)
220
221 class C4PacketBase *(*FnUnpack)(StdCompiler *pComp);
222};
223
224extern const C4PktHandlingData PktHandlingData[];
225
226// *** general packet types
227
228// "identified" packet: packet with packet type id
229class C4IDPacket : public C4PacketBase
230{
231 friend class C4PacketList;
232
233public:
234 C4IDPacket();
235 C4IDPacket(C4PacketType eID, C4PacketBase *pPkt, bool fTakePkt = true);
236 C4IDPacket(const C4IDPacket &Packet2);
237 ~C4IDPacket();
238
239protected:
240 C4PacketType eID;
241 C4PacketBase *pPkt;
242 bool fOwnPkt;
243
244 // used by C4PacketList
245 C4IDPacket *pNext;
246
247public:
248 C4PacketType getPktType() const { return eID; }
249 C4PacketBase *getPkt() const { return pPkt; }
250 const char *getPktName() const;
251
252 void Clear();
253 void Default();
254
255 virtual void CompileFunc(StdCompiler *pComp) override;
256};
257
258// list of identified packets
259class C4PacketList : public C4PacketBase
260{
261public:
262 C4PacketList();
263 C4PacketList(const C4PacketList &List2);
264 virtual ~C4PacketList();
265
266protected:
267 C4IDPacket *pFirst, *pLast;
268
269public:
270 C4IDPacket *firstPkt() const { return pFirst; }
271 C4IDPacket *nextPkt(C4IDPacket *pPkt) const { return pPkt->pNext; }
272
273 void Add(C4IDPacket *pPkt);
274 void Add(C4PacketType eType, C4PacketBase *pPkt);
275
276 void Take(C4PacketList &List);
277 void Append(const C4PacketList &List);
278
279 void Clear();
280 void Remove(C4IDPacket *pPkt);
281 void Delete(C4IDPacket *pPkt);
282
283 virtual void CompileFunc(StdCompiler *pComp) override;
284};
285