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