1 //       _________ __                 __
2 //      /   _____//  |_____________ _/  |______     ____  __ __  ______
3 //      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
4 //      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
5 //     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
6 //             \/                  \/          \//_____/            \/
7 //  ______________________                           ______________________
8 //                        T H E   W A R   B E G I N S
9 //         Stratagus - A free fantasy real time strategy game engine
10 //
11 /**@name net_message.cpp - The network message code. */
12 //
13 //      (c) Copyright 2013 by Joris Dauphin
14 //
15 //      This program is free software; you can redistribute it and/or modify
16 //      it under the terms of the GNU General Public License as published by
17 //      the Free Software Foundation; only version 2 of the License.
18 //
19 //      This program is distributed in the hope that it will be useful,
20 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
21 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 //      GNU General Public License for more details.
23 //
24 //      You should have received a copy of the GNU General Public License
25 //      along with this program; if not, write to the Free Software
26 //      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 //      02111-1307, USA.
28 //
29 
30 //@{
31 
32 //----------------------------------------------------------------------------
33 // Includes
34 //----------------------------------------------------------------------------
35 
36 #include "stratagus.h"
37 
38 #include "net_message.h"
39 
40 #include "net_lowlevel.h"
41 #include "netconnect.h"
42 #include "network.h"
43 #include "version.h"
44 
serialize32(unsigned char * buf,uint32_t data)45 size_t serialize32(unsigned char *buf, uint32_t data)
46 {
47 	if (buf) {
48 		*reinterpret_cast<uint32_t *>(buf) = htonl(data);
49 	}
50 	return sizeof(data);
51 }
serialize32(unsigned char * buf,int32_t data)52 size_t serialize32(unsigned char *buf, int32_t data)
53 {
54 	if (buf) {
55 		*reinterpret_cast<int32_t *>(buf) = htonl(data);
56 	}
57 	return sizeof(data);
58 }
serialize16(unsigned char * buf,uint16_t data)59 size_t serialize16(unsigned char *buf, uint16_t data)
60 {
61 	if (buf) {
62 		*reinterpret_cast<uint16_t *>(buf) = htons(data);
63 	}
64 	return sizeof(data);
65 }
serialize16(unsigned char * buf,int16_t data)66 size_t serialize16(unsigned char *buf, int16_t data)
67 {
68 	if (buf) {
69 		*reinterpret_cast<int16_t *>(buf) = htons(data);
70 	}
71 	return sizeof(data);
72 }
serialize8(unsigned char * buf,uint8_t data)73 size_t serialize8(unsigned char *buf, uint8_t data)
74 {
75 	if (buf) {
76 		*buf = data;
77 	}
78 	return sizeof(data);
79 }
serialize8(unsigned char * buf,int8_t data)80 size_t serialize8(unsigned char *buf, int8_t data)
81 {
82 	if (buf) {
83 		*buf = data;
84 	}
85 	return sizeof(data);
86 }
87 template <int N>
serialize(unsigned char * buf,const char (& data)[N])88 size_t serialize(unsigned char *buf, const char(&data)[N])
89 {
90 	if (buf) {
91 		memcpy(buf, data, N);
92 	}
93 	return N;
94 }
serialize(unsigned char * buf,const std::string & s)95 size_t serialize(unsigned char *buf, const std::string &s)
96 {
97 	if (buf) {
98 		buf += serialize16(buf, uint16_t(s.size()));
99 		memcpy(buf, s.c_str(), s.size());
100 		buf += s.size();
101 		//Wyrmgus start
102 		//Andrettin: fix to the multiplayer OOS issue - the fix works, but it would be better if someone reviewed the code! I am leaving the Wyrmgus tags on these changes until the code has been properly reviewed
103 		/*
104 		if ((s.size() & 0x03) != 0) {
105 			memset(buf, 0, s.size() & 0x03);
106 		}
107 		*/
108 		//Wyrmgus end
109 	}
110 	//Wyrmgus start
111 //	return 2 + ((s.size() + 3) & ~0x03); // round up to multiple of 4 for alignment.
112 	return 2 + (s.size() + 3);
113 	//Wyrmgus end
114 }
serialize(unsigned char * buf,const std::vector<unsigned char> & data)115 size_t serialize(unsigned char *buf, const std::vector<unsigned char> &data)
116 {
117 	if (buf) {
118 		if (data.empty()) {
119 			return serialize16(buf, uint16_t(data.size()));
120 		}
121 		buf += serialize16(buf, uint16_t(data.size()));
122 		memcpy(buf, &data[0], data.size());
123 		buf += data.size();
124 		//Wyrmgus start
125 //		if ((data.size() & 0x03) != 0) {
126 //			memset(buf, 0, data.size() & 0x03);
127 //		}
128 		//Wyrmgus end
129 	}
130 	//Wyrmgus start
131 //	return 2 + ((data.size() + 3) & ~0x03); // round up to multiple of 4 for alignment.
132 	return 2 + (data.size() + 3);
133 	//Wyrmgus end
134 }
135 
deserialize32(const unsigned char * buf,uint32_t * data)136 size_t deserialize32(const unsigned char *buf, uint32_t *data)
137 {
138 	*data = ntohl(*reinterpret_cast<const uint32_t *>(buf));
139 	return sizeof(*data);
140 }
deserialize32(const unsigned char * buf,int32_t * data)141 size_t deserialize32(const unsigned char *buf, int32_t *data)
142 {
143 	*data = ntohl(*reinterpret_cast<const int32_t *>(buf));
144 	return sizeof(*data);
145 }
deserialize16(const unsigned char * buf,uint16_t * data)146 size_t deserialize16(const unsigned char *buf, uint16_t *data)
147 {
148 	*data = ntohs(*reinterpret_cast<const uint16_t *>(buf));
149 	return sizeof(*data);
150 }
deserialize16(const unsigned char * buf,int16_t * data)151 size_t deserialize16(const unsigned char *buf, int16_t *data)
152 {
153 	*data = ntohs(*reinterpret_cast<const int16_t *>(buf));
154 	return sizeof(*data);
155 }
deserialize8(const unsigned char * buf,uint8_t * data)156 size_t deserialize8(const unsigned char *buf, uint8_t *data)
157 {
158 	*data = *buf;
159 	return sizeof(*data);
160 }
deserialize8(const unsigned char * buf,int8_t * data)161 size_t deserialize8(const unsigned char *buf, int8_t *data)
162 {
163 	*data = *buf;
164 	return sizeof(*data);
165 }
166 template <int N>
deserialize(const unsigned char * buf,char (& data)[N])167 size_t deserialize(const unsigned char *buf, char(&data)[N])
168 {
169 	memcpy(data, buf, N);
170 	return N;
171 }
deserialize(const unsigned char * buf,std::string & s)172 size_t deserialize(const unsigned char *buf, std::string &s)
173 {
174 	uint16_t size;
175 
176 	buf += deserialize16(buf, &size);
177 	s = std::string(reinterpret_cast<const char *>(buf), size);
178 	//Wyrmgus start
179 //	return 2 + ((s.size() + 3) & ~0x03); // round up to multiple of 4 for alignment.
180 	return 2 + (s.size() + 3);
181 	//Wyrmgus end
182 }
deserialize(const unsigned char * buf,std::vector<unsigned char> & data)183 size_t deserialize(const unsigned char *buf, std::vector<unsigned char> &data)
184 {
185 	uint16_t size;
186 
187 	buf += deserialize16(buf, &size);
188 	data.assign(buf, buf + size);
189 	//Wyrmgus start
190 //	return 2 + ((data.size() + 3) & ~0x03); // round up to multiple of 4 for alignment.
191 	return 2 + (data.size() + 3);
192 	//Wyrmgus end
193 }
194 
195 //
196 // CNetworkHost
197 //
198 
Serialize(unsigned char * buf) const199 size_t CNetworkHost::Serialize(unsigned char *buf) const
200 {
201 	unsigned char *p = buf;
202 
203 	p += serialize32(p, this->Host);
204 	p += serialize16(p, this->Port);
205 	p += serialize16(p, this->PlyNr);
206 	p += serialize(p, this->PlyName);
207 
208 	return p - buf;
209 }
210 
Deserialize(const unsigned char * p)211 size_t CNetworkHost::Deserialize(const unsigned char *p)
212 {
213 	const unsigned char *buf = p;
214 
215 	p += deserialize32(p, &Host);
216 	p += deserialize16(p, &Port);
217 	p += deserialize16(p, &PlyNr);
218 	p += deserialize(p, this->PlyName);
219 	return p - buf;
220 }
221 
Clear()222 void CNetworkHost::Clear()
223 {
224 	this->Host = 0;
225 	this->Port = 0;
226 	this->PlyNr = 0;
227 	memset(this->PlyName, 0, sizeof(this->PlyName));
228 }
229 
SetName(const char * name)230 void CNetworkHost::SetName(const char *name)
231 {
232 	strncpy_s(this->PlyName, sizeof(this->PlyName), name, _TRUNCATE);
233 }
234 
235 //
236 // CServerSetup
237 //
238 
Serialize(unsigned char * buf) const239 size_t CServerSetup::Serialize(unsigned char *buf) const
240 {
241 	unsigned char *p = buf;
242 
243 	p += serialize8(p, this->ResourcesOption);
244 	p += serialize8(p, this->UnitsOption);
245 	p += serialize8(p, this->FogOfWar);
246 	p += serialize8(p, this->Inside);
247 	p += serialize8(p, this->RevealMap);
248 	p += serialize8(p, this->TilesetSelection);
249 	p += serialize8(p, this->GameTypeOption);
250 	p += serialize8(p, this->Difficulty);
251 	p += serialize8(p, this->MapRichness);
252 	p += serialize8(p, this->Opponents);
253 	for (int i = 0; i < PlayerMax; ++i) {
254 		p += serialize8(p, this->CompOpt[i]);
255 	}
256 	for (int i = 0; i < PlayerMax; ++i) {
257 		p += serialize8(p, this->Ready[i]);
258 	}
259 	for (int i = 0; i < PlayerMax; ++i) {
260 		p += serialize8(p, this->Race[i]);
261 	}
262 	return p - buf;
263 }
264 
Deserialize(const unsigned char * p)265 size_t CServerSetup::Deserialize(const unsigned char *p)
266 {
267 	const unsigned char *buf = p;
268 	p += deserialize8(p, &this->ResourcesOption);
269 	p += deserialize8(p, &this->UnitsOption);
270 	p += deserialize8(p, &this->FogOfWar);
271 	p += deserialize8(p, &this->Inside);
272 	p += deserialize8(p, &this->RevealMap);
273 	p += deserialize8(p, &this->TilesetSelection);
274 	p += deserialize8(p, &this->GameTypeOption);
275 	p += deserialize8(p, &this->Difficulty);
276 	p += deserialize8(p, &this->MapRichness);
277 	p += deserialize8(p, &this->Opponents);
278 	for (int i = 0; i < PlayerMax; ++i) {
279 		p += deserialize8(p, &this->CompOpt[i]);
280 	}
281 	for (int i = 0; i < PlayerMax; ++i) {
282 		p += deserialize8(p, &this->Ready[i]);
283 	}
284 	for (int i = 0; i < PlayerMax; ++i) {
285 		p += deserialize8(p, &this->Race[i]);
286 	}
287 	return p - buf;
288 }
289 
Clear()290 void CServerSetup::Clear()
291 {
292 	ResourcesOption = 0;
293 	UnitsOption = 0;
294 	FogOfWar = 0;
295 	Inside = 0;
296 	RevealMap = 0;
297 	TilesetSelection = 0;
298 	GameTypeOption = 0;
299 	Difficulty = 0;
300 	MapRichness = 0;
301 	Opponents = 0;
302 	memset(CompOpt, 0, sizeof(CompOpt));
303 	memset(Ready, 0, sizeof(Ready));
304 	memset(Race, 0, sizeof(Race));
305 }
306 
operator ==(const CServerSetup & rhs) const307 bool CServerSetup::operator == (const CServerSetup &rhs) const
308 {
309 	return (ResourcesOption == rhs.ResourcesOption
310 			&& UnitsOption == rhs.UnitsOption
311 			&& FogOfWar == rhs.FogOfWar
312 			&& Inside == rhs.Inside
313 			&& RevealMap == rhs.RevealMap
314 			&& TilesetSelection == rhs.TilesetSelection
315 			&& GameTypeOption == rhs.GameTypeOption
316 			&& Difficulty == rhs.Difficulty
317 			&& MapRichness == rhs.MapRichness
318 			&& Opponents == rhs.Opponents
319 			&& memcmp(CompOpt, rhs.CompOpt, sizeof(CompOpt)) == 0
320 			&& memcmp(Ready, rhs.Ready, sizeof(Ready)) == 0
321 			&& memcmp(Race, rhs.Race, sizeof(Race)) == 0);
322 }
323 
324 //
325 //  CInitMessage_Header
326 //
327 
Serialize(unsigned char * p) const328 size_t CInitMessage_Header::Serialize(unsigned char *p) const
329 {
330 	unsigned char *buf = p;
331 	p += serialize8(p, type);
332 	p += serialize8(p, subtype);
333 	return p - buf;
334 }
335 
Deserialize(const unsigned char * p)336 size_t CInitMessage_Header::Deserialize(const unsigned char *p)
337 {
338 	const unsigned char *buf = p;
339 	p += deserialize8(p, &type);
340 	p += deserialize8(p, &subtype);
341 	return p - buf;
342 }
343 
344 //
345 // CInitMessage_Hello
346 //
347 
CInitMessage_Hello(const char * name)348 CInitMessage_Hello::CInitMessage_Hello(const char *name) :
349 	header(MessageInit_FromClient, ICMHello)
350 {
351 	strncpy_s(this->PlyName, sizeof(this->PlyName), name, _TRUNCATE);
352 	this->Stratagus = StratagusVersion;
353 	this->Version = FileChecksums;
354 }
355 
Serialize() const356 const unsigned char *CInitMessage_Hello::Serialize() const
357 {
358 	unsigned char *buf = new unsigned char[Size()];
359 	unsigned char *p = buf;
360 
361 	p += header.Serialize(p);
362 	p += serialize(p, this->PlyName);
363 	p += serialize32(p, this->Stratagus);
364 	p += serialize32(p, this->Version);
365 	return buf;
366 }
367 
Deserialize(const unsigned char * p)368 void CInitMessage_Hello::Deserialize(const unsigned char *p)
369 {
370 	p += header.Deserialize(p);
371 	p += deserialize(p, this->PlyName);
372 	p += deserialize32(p, &this->Stratagus);
373 	p += deserialize32(p, &this->Version);
374 }
375 
376 //
377 // CInitMessage_Config
378 //
379 
CInitMessage_Config()380 CInitMessage_Config::CInitMessage_Config() :
381 	header(MessageInit_FromServer, ICMConfig)
382 {
383 }
384 
Serialize() const385 const unsigned char *CInitMessage_Config::Serialize() const
386 {
387 	unsigned char *buf = new unsigned char[Size()];
388 	unsigned char *p = buf;
389 
390 	p += header.Serialize(p);
391 	p += serialize8(p, this->clientIndex);
392 	p += serialize8(p, this->hostsCount);
393 	for (int i = 0; i != PlayerMax; ++i) {
394 		p += this->hosts[i].Serialize(p);
395 	}
396 	return buf;
397 }
398 
Deserialize(const unsigned char * p)399 void CInitMessage_Config::Deserialize(const unsigned char *p)
400 {
401 	p += header.Deserialize(p);
402 	p += deserialize8(p, &this->clientIndex);
403 	p += deserialize8(p, &this->hostsCount);
404 	for (int i = 0; i != PlayerMax; ++i) {
405 		p += this->hosts[i].Deserialize(p);
406 	}
407 }
408 
409 //
410 // CInitMessage_EngineMismatch
411 //
412 
CInitMessage_EngineMismatch()413 CInitMessage_EngineMismatch::CInitMessage_EngineMismatch() :
414 	header(MessageInit_FromServer, ICMEngineMismatch)
415 {
416 	this->Stratagus = StratagusVersion;
417 }
418 
Serialize() const419 const unsigned char *CInitMessage_EngineMismatch::Serialize() const
420 {
421 	unsigned char *buf = new unsigned char[Size()];
422 	unsigned char *p = buf;
423 
424 	p += header.Serialize(p);
425 	p += serialize32(p, this->Stratagus);
426 	return buf;
427 }
428 
Deserialize(const unsigned char * p)429 void CInitMessage_EngineMismatch::Deserialize(const unsigned char *p)
430 {
431 	p += header.Deserialize(p);
432 	p += deserialize32(p, &this->Stratagus);
433 }
434 
435 //
436 // CInitMessage_LuaFilesMismatch
437 //
438 
CInitMessage_LuaFilesMismatch()439 CInitMessage_LuaFilesMismatch::CInitMessage_LuaFilesMismatch() :
440 	header(MessageInit_FromServer, ICMLuaFilesMismatch)
441 {
442 	this->Version = FileChecksums;
443 }
444 
Serialize() const445 const unsigned char *CInitMessage_LuaFilesMismatch::Serialize() const
446 {
447 	unsigned char *buf = new unsigned char[Size()];
448 	unsigned char *p = buf;
449 
450 	p += header.Serialize(p);
451 	p += serialize32(p, this->Version);
452 	return buf;
453 }
454 
Deserialize(const unsigned char * p)455 void CInitMessage_LuaFilesMismatch::Deserialize(const unsigned char *p)
456 {
457 	p += header.Deserialize(p);
458 	p += deserialize32(p, &this->Version);
459 }
460 
461 //
462 // CInitMessage_Welcome
463 //
464 
CInitMessage_Welcome()465 CInitMessage_Welcome::CInitMessage_Welcome() :
466 	header(MessageInit_FromServer, ICMWelcome)
467 {
468 	this->Lag = CNetworkParameter::Instance.NetworkLag;
469 	this->gameCyclesPerUpdate = CNetworkParameter::Instance.gameCyclesPerUpdate;
470 }
471 
Serialize() const472 const unsigned char *CInitMessage_Welcome::Serialize() const
473 {
474 	unsigned char *buf = new unsigned char[Size()];
475 	unsigned char *p = buf;
476 
477 	p += header.Serialize(p);
478 	for (int i = 0; i < PlayerMax; ++i) {
479 		p += this->hosts[i].Serialize(p);
480 	}
481 	p += serialize32(p, this->Lag);
482 	p += serialize32(p, this->gameCyclesPerUpdate);
483 	return buf;
484 }
485 
Deserialize(const unsigned char * p)486 void CInitMessage_Welcome::Deserialize(const unsigned char *p)
487 {
488 	p += header.Deserialize(p);
489 	for (int i = 0; i < PlayerMax; ++i) {
490 		p += this->hosts[i].Deserialize(p);
491 	}
492 	p += deserialize32(p, &this->Lag);
493 	p += deserialize32(p, &this->gameCyclesPerUpdate);
494 }
495 
496 //
497 // CInitMessage_Map
498 //
499 
CInitMessage_Map(const char * path,uint32_t mapUID)500 CInitMessage_Map::CInitMessage_Map(const char *path, uint32_t mapUID) :
501 	header(MessageInit_FromServer, ICMMap),
502 	MapUID(mapUID)
503 {
504 	strncpy_s(MapPath, sizeof(MapPath), path, _TRUNCATE);
505 }
506 
Serialize() const507 const unsigned char *CInitMessage_Map::Serialize() const
508 {
509 	unsigned char *buf = new unsigned char[Size()];
510 	unsigned char *p = buf;
511 
512 	p += header.Serialize(p);
513 	p += serialize(p, MapPath);
514 	p += serialize32(p, this->MapUID);
515 	return buf;
516 }
517 
Deserialize(const unsigned char * p)518 void CInitMessage_Map::Deserialize(const unsigned char *p)
519 {
520 	p += header.Deserialize(p);
521 	p += deserialize(p, this->MapPath);
522 	p += deserialize32(p, &this->MapUID);
523 }
524 
525 //
526 // CInitMessage_State
527 //
528 
CInitMessage_State(int type,const CServerSetup & data)529 CInitMessage_State::CInitMessage_State(int type, const CServerSetup &data) :
530 	header(type, ICMState),
531 	State(data)
532 {
533 }
534 
Serialize() const535 const unsigned char *CInitMessage_State::Serialize() const
536 {
537 	unsigned char *buf = new unsigned char[Size()];
538 	unsigned char *p = buf;
539 
540 	p += header.Serialize(p);
541 	p += this->State.Serialize(p);
542 	return buf;
543 }
544 
Deserialize(const unsigned char * p)545 void CInitMessage_State::Deserialize(const unsigned char *p)
546 {
547 	p += header.Deserialize(p);
548 	p += this->State.Deserialize(p);
549 }
550 
551 //
552 // CInitMessage_Resync
553 //
554 
CInitMessage_Resync()555 CInitMessage_Resync::CInitMessage_Resync() :
556 	header(MessageInit_FromServer, ICMResync)
557 {
558 }
559 
Serialize() const560 const unsigned char *CInitMessage_Resync::Serialize() const
561 {
562 	unsigned char *buf = new unsigned char[Size()];
563 	unsigned char *p = buf;
564 
565 	p += header.Serialize(p);
566 	for (int i = 0; i < PlayerMax; ++i) {
567 		p += this->hosts[i].Serialize(p);
568 	}
569 	return buf;
570 }
571 
Deserialize(const unsigned char * p)572 void CInitMessage_Resync::Deserialize(const unsigned char *p)
573 {
574 	p += header.Deserialize(p);
575 	for (int i = 0; i < PlayerMax; ++i) {
576 		p += this->hosts[i].Deserialize(p);
577 	}
578 }
579 
580 //
581 // CNetworkCommand
582 //
583 
Serialize(unsigned char * buf) const584 size_t CNetworkCommand::Serialize(unsigned char *buf) const
585 {
586 	unsigned char *p = buf;
587 	p += serialize16(p, this->Unit);
588 	p += serialize16(p, this->X);
589 	p += serialize16(p, this->Y);
590 	p += serialize16(p, this->Dest);
591 	return p - buf;
592 }
593 
Deserialize(const unsigned char * buf)594 size_t CNetworkCommand::Deserialize(const unsigned char *buf)
595 {
596 	const unsigned char *p = buf;
597 	p += deserialize16(p, &this->Unit);
598 	p += deserialize16(p, &this->X);
599 	p += deserialize16(p, &this->Y);
600 	p += deserialize16(p, &this->Dest);
601 	return p - buf;
602 }
603 
604 //
605 // CNetworkExtendedCommand
606 //
607 
Serialize(unsigned char * buf) const608 size_t CNetworkExtendedCommand::Serialize(unsigned char *buf) const
609 {
610 	unsigned char *p = buf;
611 	p += serialize8(p, this->ExtendedType);
612 	p += serialize8(p, this->Arg1);
613 	p += serialize16(p, this->Arg2);
614 	p += serialize16(p, this->Arg3);
615 	p += serialize16(p, this->Arg4);
616 	return p - buf;
617 }
618 
Deserialize(const unsigned char * buf)619 size_t CNetworkExtendedCommand::Deserialize(const unsigned char *buf)
620 {
621 	const unsigned char *p = buf;
622 	p += deserialize8(p, &this->ExtendedType);
623 	p += deserialize8(p, &this->Arg1);
624 	p += deserialize16(p, &this->Arg2);
625 	p += deserialize16(p, &this->Arg3);
626 	p += deserialize16(p, &this->Arg4);
627 	return p - buf;
628 }
629 
630 //
631 // CNetworkChat
632 //
633 
Serialize(unsigned char * buf) const634 size_t CNetworkChat::Serialize(unsigned char *buf) const
635 {
636 	unsigned char *p = buf;
637 	p += serialize(p, this->Text);
638 	return p - buf;
639 }
640 
Deserialize(const unsigned char * buf)641 size_t CNetworkChat::Deserialize(const unsigned char *buf)
642 {
643 	const unsigned char *p = buf;
644 	p += deserialize(p, this->Text);
645 	return p - buf;
646 }
647 
Size() const648 size_t CNetworkChat::Size() const
649 {
650 	size_t size = 0;
651 	size += serialize(NULL, this->Text);
652 	return size;
653 }
654 
655 //
656 // CNetworkCommandSync
657 //
658 
Serialize(unsigned char * buf) const659 size_t CNetworkCommandSync::Serialize(unsigned char *buf) const
660 {
661 	unsigned char *p = buf;
662 	p += serialize32(p, this->syncSeed);
663 	p += serialize32(p, this->syncHash);
664 	return p - buf;
665 }
666 
Deserialize(const unsigned char * buf)667 size_t CNetworkCommandSync::Deserialize(const unsigned char *buf)
668 {
669 	const unsigned char *p = buf;
670 	p += deserialize32(p, &this->syncSeed);
671 	p += deserialize32(p, &this->syncHash);
672 	return p - buf;
673 }
674 
675 //
676 // CNetworkCommandQuit
677 //
678 
Serialize(unsigned char * buf) const679 size_t CNetworkCommandQuit::Serialize(unsigned char *buf) const
680 {
681 	unsigned char *p = buf;
682 	p += serialize16(p, this->player);
683 	return p - buf;
684 }
685 
Deserialize(const unsigned char * buf)686 size_t CNetworkCommandQuit::Deserialize(const unsigned char *buf)
687 {
688 	const unsigned char *p = buf;
689 	p += deserialize16(p, &this->player);
690 	return p - buf;
691 }
692 
693 //
694 // CNetworkSelection
695 //
696 
Serialize(unsigned char * buf) const697 size_t CNetworkSelection::Serialize(unsigned char *buf) const
698 {
699 	unsigned char *p = buf;
700 
701 	p += serialize16(p, this->player);
702 	p += serialize16(p, uint16_t(this->Units.size()));
703 	for (size_t i = 0; i != this->Units.size(); ++i) {
704 		p += serialize16(p, Units[i]);
705 	}
706 	return p - buf;
707 }
708 
Deserialize(const unsigned char * buf)709 size_t CNetworkSelection::Deserialize(const unsigned char *buf)
710 {
711 	const unsigned char *p = buf;
712 
713 	uint16_t size;
714 	p += deserialize16(p, &this->player);
715 	p += deserialize16(p, &size);
716 	this->Units.resize(size);
717 	for (size_t i = 0; i != this->Units.size(); ++i) {
718 		p += deserialize16(p, &Units[i]);
719 	}
720 	return p - buf;
721 }
722 
Size() const723 size_t CNetworkSelection::Size() const
724 {
725 	return 2 + 2 + 2 * Units.size();
726 }
727 
728 //
729 // CNetworkPacketHeader
730 //
731 
Serialize(unsigned char * p) const732 size_t CNetworkPacketHeader::Serialize(unsigned char *p) const
733 {
734 	if (p != NULL) {
735 		for (int i = 0; i != MaxNetworkCommands; ++i) {
736 			p += serialize8(p, this->Type[i]);
737 		}
738 		p += serialize8(p, this->Cycle);
739 		p += serialize8(p, this->OrigPlayer);
740 	}
741 	return MaxNetworkCommands + 1 + 1;
742 }
743 
Deserialize(const unsigned char * buf)744 size_t CNetworkPacketHeader::Deserialize(const unsigned char *buf)
745 {
746 	const unsigned char *p = buf;
747 
748 	for (int i = 0; i != MaxNetworkCommands; ++i) {
749 		p += deserialize8(p, &this->Type[i]);
750 	}
751 	p += deserialize8(p, &this->Cycle);
752 	p += deserialize8(p, &this->OrigPlayer);
753 	return p - buf;
754 }
755 
756 //
757 // CNetworkPacket
758 //
759 
Serialize(unsigned char * buf,int numcommands) const760 size_t CNetworkPacket::Serialize(unsigned char *buf, int numcommands) const
761 {
762 	unsigned char *p = buf;
763 
764 	p += this->Header.Serialize(p);
765 	for (int i = 0; i != numcommands; ++i) {
766 		p += serialize(p, this->Command[i]);
767 	}
768 	return p - buf;
769 }
770 
Deserialize(const unsigned char * p,unsigned int len,int * commandCount)771 void CNetworkPacket::Deserialize(const unsigned char *p, unsigned int len, int *commandCount)
772 {
773 	this->Header.Deserialize(p);
774 	p += CNetworkPacketHeader::Size();
775 	len -= CNetworkPacketHeader::Size();
776 
777 	for (*commandCount = 0; len != 0; ++*commandCount) {
778 		const size_t r = deserialize(p, this->Command[*commandCount]);
779 		p += r;
780 		len -= r;
781 	}
782 }
783 
Size(int numcommands) const784 size_t CNetworkPacket::Size(int numcommands) const
785 {
786 	size_t size = 0;
787 
788 	size += this->Header.Serialize(NULL);
789 	for (int i = 0; i != numcommands; ++i) {
790 		size += serialize(NULL, this->Command[i]);
791 	}
792 	return size;
793 }
794 
795 //@}
796