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 #ifndef INC_C4PacketBase
17 #define INC_C4PacketBase
18 
19 #include "network/C4NetIO.h"
20 
21 // *** packet base class
22 
23 class C4PacketBase
24 {
25 	friend class C4PacketList;
26 public:
27 	C4PacketBase();
28 	virtual ~C4PacketBase();
29 
30 	// virtual functions to implement by derived classes
31 	virtual void CompileFunc(StdCompiler *pComp) = 0;
32 
33 	// conversion (using above functions)
34 	C4NetIOPacket pack(const C4NetIO::addr_t &addr = C4NetIO::addr_t()) const;
35 	C4NetIOPacket pack(uint8_t cStatus, const C4NetIO::addr_t &addr = C4NetIO::addr_t()) const;
36 	void unpack(const C4NetIOPacket &Pkt, char *pStatus = nullptr);
37 
38 };
39 
40 inline C4NetIOPacket MkC4NetIOPacket(char cStatus, const class C4PacketBase &Pkt, const C4NetIO::addr_t &addr = C4NetIO::addr_t())
41 {
42 	return Pkt.pack(cStatus, addr);
43 }
44 
45 // Filename Adaptor
46 // Converts the network filename separator to the native filename separator
47 struct C4NetFilenameAdapt
48 {
49 	StdStrBuf &FileName;
C4NetFilenameAdaptC4NetFilenameAdapt50 	explicit C4NetFilenameAdapt(StdStrBuf &FileName) : FileName(FileName) { }
CompileFuncC4NetFilenameAdapt51 	inline void CompileFunc(StdCompiler *pComp) const
52 	{
53 #ifdef _WIN32
54 		pComp->Value(FileName);
55 #else
56 		StdCopyStrBuf FileName2;
57 		if (pComp->isSerializer() && FileName)
58 		{
59 			FileName2.Copy(FileName);
60 			SReplaceChar(FileName2.getMData(),DirectorySeparator,'\\');
61 		}
62 		pComp->Value(FileName2);
63 		if (pComp->isDeserializer())
64 		{
65 			FileName.Take(FileName2);
66 			SReplaceChar(FileName.getMData(),'\\',DirectorySeparator);
67 		}
68 #endif
69 	}
70 	template <class T> bool operator == (const T &rVal) { return FileName == rVal; }
71 	template <class T> C4NetFilenameAdapt &operator = (const T &rVal) { FileName = rVal; return *this; }
72 };
mkNetFilenameAdapt(StdStrBuf & FileName)73 inline C4NetFilenameAdapt mkNetFilenameAdapt(StdStrBuf &FileName) { return C4NetFilenameAdapt(FileName); }
74 
75 // enumaration of all used packet types
76 enum C4PacketType
77 {
78 	PID_None          = 0xFF,
79 
80 	// *** network
81 
82 	// * base packets
83 	// ping
84 	PID_Ping          = 0x00,
85 	PID_Pong          = 0x01,
86 
87 	// connecting
88 	PID_Conn          = 0x02,
89 	PID_ConnRe        = 0x03,
90 
91 	// msg forwarding
92 	PID_FwdReq        = 0x04,
93 	PID_Fwd           = 0x05,
94 
95 	// post mortem
96 	PID_PostMortem    = 0x06,
97 
98 	// (packets before this ID won't be recovered post-mortem)
99 	PID_PacketLogStart = 0x04,
100 
101 	// * game
102 	// game status
103 	PID_Status        = 0x10,
104 	PID_StatusAck     = 0x11,
105 
106 	// client address propagation
107 	PID_Addr          = 0x12,
108 
109 	// activation request
110 	PID_ClientActReq  = 0x13,
111 
112 	// all data a client needs to get started
113 	PID_JoinData      = 0x15,
114 
115 	// player info
116 	PID_PlayerInfoUpdReq = 0x16,
117 
118 	// round results league info
119 	PID_LeagueRoundResults = 0x17,
120 
121 	// * lobby
122 	PID_LobbyCountdown = 0x20,
123 	PID_SetScenarioParameter = 0x21, // scenario parameter update
124 
125 	// * resources
126 	PID_NetResDis     = 0x30,
127 	PID_NetResStat    = 0x31,
128 	PID_NetResDerive  = 0x32,
129 	PID_NetResReq     = 0x33,
130 	PID_NetResData    = 0x34,
131 
132 	// * control
133 	PID_Control       = 0x40,
134 	PID_ControlReq    = 0x41,
135 	PID_ControlPkt    = 0x42,
136 	PID_ExecSyncCtrl  = 0x43,
137 
138 	// *** control
139 	CID_First         = 0x80,
140 
141 	CID_ClientJoin    = CID_First | 0x00,
142 	CID_ClientUpdate  = CID_First | 0x01,
143 	CID_ClientRemove  = CID_First | 0x02,
144 
145 	CID_Vote          = CID_First | 0x03,
146 	CID_VoteEnd       = CID_First | 0x04,
147 
148 	CID_SyncCheck     = CID_First | 0x05,
149 	CID_Synchronize   = CID_First | 0x06,
150 	CID_Set           = CID_First | 0x07,
151 	CID_Script        = CID_First | 0x08,
152 	CID_MsgBoardReply = CID_First | 0x09,
153 	CID_MsgBoardCmd   = CID_First | 0x0A,
154 
155 	CID_PlrInfo       = CID_First | 0x10,
156 	CID_JoinPlr       = CID_First | 0x11,
157 	CID_RemovePlr     = CID_First | 0x12,
158 
159 	CID_PlrSelect     = CID_First | 0x20,
160 	CID_PlrControl    = CID_First | 0x21,
161 
162 	CID_Message       = CID_First | 0x23,
163 	CID_PlrAction     = CID_First | 0x24,
164 	CID_PlrMouseMove  = CID_First | 0x25,
165 
166 	CID_EMMoveObj     = CID_First | 0x30,
167 	CID_EMDrawTool    = CID_First | 0x31,
168 	CID_ReInitScenario= CID_First | 0x32,
169 	CID_EditGraph     = CID_First | 0x33,
170 
171 	CID_DebugRec      = CID_First | 0x40,
172 	CID_MenuCommand   = CID_First | 0x41,
173 
174 	// Note: There are some more packet types in src/netpuncher/C4PuncherPacket.h
175 	// They have been picked to be distinct from these for safety, not for necessary.
176 };
177 
178 // packet classes
179 enum C4PacketClass
180 {
181 	PC_Network,                           // network packet - internal stuff
182 	PC_Control                            // control packet - game data (saved in records)
183 };
184 
185 // enumeration of packet handlers
186 enum C4PacketHandlerID
187 {
188 	PH_C4Network2IO           = 1 << 0,   // network i/o class
189 	PH_C4Network2             = 1 << 1,   // main network class
190 	PH_C4GUIMainDlg           = 1 << 2,   // network lobby class
191 	PH_C4Network2ClientList   = 1 << 3,   // client list class
192 	PH_C4Network2Players      = 1 << 4,   // player list class
193 	PH_C4Network2ResList      = 1 << 5,   // resource list class
194 	PH_C4GameControlNetwork   = 1 << 6,   // network control class
195 };
196 
197 
198 // packet handling data
199 struct C4PktHandlingData
200 {
201 	C4PacketType ID;
202 	C4PacketClass Class;
203 	const char  *Name;
204 
205 	bool AcceptedOnly;
206 	bool ProcByThread;
207 
208 	int32_t HandlerID; // (C4PacketHandlerID)
209 
210 	class C4PacketBase *(*FnUnpack)(StdCompiler *pComp);
211 };
212 extern const C4PktHandlingData PktHandlingData[];
213 
214 const char *PacketNameByID(C4PacketType eID);
215 
216 
217 // *** general packet types
218 
219 // raw packet: contains std buffer
220 class C4PktBuf : public C4PacketBase
221 {
222 protected:
223 	StdCopyBuf Data;
224 public:
225 	C4PktBuf();
226 	C4PktBuf(const C4PktBuf &rCopy);
227 	C4PktBuf(const StdBuf &rCpyData);
228 
getSize()229 	size_t getSize() const { return Data.getSize(); }
getData()230 	const void *getData() const { return Data.getData(); }
231 
232 	void CompileFunc(StdCompiler *pComp) override;
233 };
234 
235 // "identified" packet: packet with packet type id
236 class C4IDPacket : public C4PacketBase
237 {
238 	friend class C4PacketList;
239 public:
240 	C4IDPacket();
241 	C4IDPacket(C4PacketType eID, C4PacketBase *pPkt, bool fTakePkt = true);
242 	C4IDPacket(const C4IDPacket &Packet2);
243 	~C4IDPacket() override;
244 
245 protected:
246 	C4PacketType eID{PID_None};
247 	C4PacketBase *pPkt{nullptr};
248 	bool fOwnPkt{true};
249 
250 	// used by C4PacketList
251 	C4IDPacket *pNext{nullptr};
252 
253 public:
getPktType()254 	C4PacketType  getPktType() const { return eID; }
getPkt()255 	C4PacketBase *getPkt()     const { return pPkt; }
256 	const char   *getPktName() const;
257 
258 	void Clear();
259 	void Default();
260 	void Set(C4PacketType eType, C4PacketBase *pPkt);
261 
262 	void CompileFunc(StdCompiler *pComp) override;
263 };
264 
265 // list of identified packets
266 class C4PacketList : public C4PacketBase
267 {
268 public:
269 	C4PacketList();
270 	C4PacketList(const C4PacketList &List2);
271 	~C4PacketList() override;
272 
273 protected:
274 	C4IDPacket *pFirst{nullptr}, *pLast{nullptr};
275 
276 public:
firstPkt()277 	C4IDPacket *firstPkt() const { return pFirst; }
nextPkt(C4IDPacket * pPkt)278 	C4IDPacket *nextPkt(C4IDPacket *pPkt) const { return pPkt->pNext; }
279 
280 	int32_t getPktCnt() const;
281 
282 	void Add(C4IDPacket *pPkt);
283 	void AddHead(C4IDPacket *pPkt);
284 	void Add(C4PacketType eType, C4PacketBase *pPkt);
285 	void AddHead(C4PacketType eType, C4PacketBase *pPkt);
286 
287 	void Take(C4PacketList &List);
288 	void Append(const C4PacketList &List);
289 
290 	void Clear();
291 	void Remove(C4IDPacket *pPkt);
292 	void Delete(C4IDPacket *pPkt);
293 
294 	void CompileFunc(StdCompiler *pComp) override;
295 };
296 #endif // INC_C4PacketBase
297