1 // ==============================================================
2 //	This file is part of Glest (www.glest.org)
3 //
4 //	Copyright (C) 2001-2008 Martiño Figueroa
5 //
6 //	You can redistribute this code and/or modify it under
7 //	the terms of the GNU General Public License as published
8 //	by the Free Software Foundation; either version 2 of the
9 //	License, or (at your option) any later version
10 // ==============================================================
11 
12 #ifndef _GLEST_GAME_NETWORKMESSAGE_H_
13 #define _GLEST_GAME_NETWORKMESSAGE_H_
14 
15 #include "socket.h"
16 #include "game_constants.h"
17 #include "network_types.h"
18 #include "byte_order.h"
19 #include <map>
20 #include "common_scoped_ptr.h"
21 #include "leak_dumper.h"
22 
23 using Shared::Platform::Socket;
24 using Shared::Platform::int8;
25 using Shared::Platform::uint8;
26 using Shared::Platform::int16;
27 
28 namespace Glest{ namespace Game{
29 
30 class GameSettings;
31 
32 enum NetworkMessageType {
33 	nmtInvalid,
34 	nmtIntro,
35 	nmtPing,
36 	nmtReady,
37 	nmtLaunch,
38 	nmtCommandList,
39 	nmtText,
40 	nmtQuit,
41 	nmtSynchNetworkGameData,
42 	nmtSynchNetworkGameDataStatus,
43 	nmtSynchNetworkGameDataFileCRCCheck,
44 	nmtSynchNetworkGameDataFileGet,
45 	nmtBroadCastSetup,
46 	nmtSwitchSetupRequest,
47 	nmtPlayerIndexMessage,
48 	nmtLoadingStatusMessage,
49 	nmtMarkCell,
50 	nmtUnMarkCell,
51 	nmtHighlightCell,
52 //	nmtCompressedPacket,
53 
54 	nmtCount
55 };
56 
57 enum NetworkGameStateType {
58 	nmgstInvalid,
59 	nmgstOk,
60 	nmgstNoSlots,
61 
62 	nmgstCount
63 };
64 
65 static const int maxLanguageStringSize= 60;
66 static const int maxNetworkMessageSize= 20000;
67 
68 // =====================================================
69 //	class NetworkMessage
70 // =====================================================
71 
72 enum NetworkMessageStatisticType {
73 	netmsgstPacketsPerMillisecondSend,
74 	netmsgstPacketsPerMillisecondSend_current_count,
75 	netmsgstPacketsPerMillisecondSend_last,
76 
77 	netmsgstPacketsPerSecondSend,
78 	netmsgstPacketsPerSecondSend_current_count,
79 	netmsgstPacketsPerSecondSend_last,
80 
81 	netmsgstAverageSendSize,
82 
83 	// ---------------------------------------------
84 	netmsgstPacketsPerMillisecondRecv,
85 	netmsgstPacketsPerMillisecondRecv_current_count,
86 	netmsgstPacketsPerMillisecondRecv_last,
87 
88 	netmsgstPacketsPerSecondRecv,
89 	netmsgstPacketsPerSecondRecv_current_count,
90 	netmsgstPacketsPerSecondRecv_last,
91 
92 	netmsgstAverageRecvSize,
93 
94 	netmsgstLastEvent
95 
96 };
97 
98 class NetworkMessage {
99 private:
100 
101 	static auto_ptr<Mutex> mutexMessageStats;
102 	static Chrono statsTimer;
103 	static Chrono lastSend;
104 	static Chrono lastRecv;
105 	static std::map<NetworkMessageStatisticType,int64> mapMessageStats;
106 
107 public:
108 	static void resetNetworkPacketStats();
109 	static string getNetworkPacketStats();
110 
111 	static bool useOldProtocol;
~NetworkMessage()112 	virtual ~NetworkMessage(){}
113 	virtual bool receive(Socket* socket)= 0;
receive(Socket * socket,NetworkMessageType type)114 	virtual bool receive(Socket* socket, NetworkMessageType type) { return receive(socket); };
115 
116 	virtual void send(Socket* socket) = 0;
117 	virtual size_t getDataSize() const = 0;
getData()118 	virtual unsigned char * getData() { return NULL; }
119 
120 	virtual NetworkMessageType getNetworkMessageType() const = 0;
121 
122 	void dump_packet(string label, const void* data, int dataSize, bool isSend);
123 
124 protected:
125 	//bool peek(Socket* socket, void* data, int dataSize);
126 	bool receive(Socket* socket, void* data, int dataSize,bool tryReceiveUntilDataSizeMet);
127 	void send(Socket* socket, const void* data, int dataSize);
128 	void send(Socket* socket, const void* data, int dataSize, int8 messageType);
129 	void send(Socket* socket, const void* data, int dataSize, int8 messageType, uint32 compressedLength);
130 
131 	virtual const char * getPackedMessageFormat() const = 0;
132 	virtual unsigned int getPackedSize() = 0;
133 	virtual void unpackMessage(unsigned char *buf) = 0;
134 	virtual unsigned char * packMessage() = 0;
135 };
136 
137 // =====================================================
138 //	class NetworkMessageIntro
139 //
140 //	Message sent from the server to the client
141 //	when the client connects and vice versa
142 // =====================================================
143 
144 #pragma pack(push, 1)
145 class NetworkMessageIntro: public NetworkMessage{
146 private:
147 	static const int maxVersionStringSize= 128;
148 	static const int maxNameSize= 32;
149 	static const int maxSmallStringSize= 60;
150 
151 private:
152 	int8 messageType;
153 	struct Data {
154 		int32 sessionId;
155 		NetworkString<maxVersionStringSize> versionString;
156 		NetworkString<maxNameSize> name;
157 		int16 playerIndex;
158 		int8 gameState;
159 		uint32 externalIp;
160 		uint32 ftpPort;
161 		NetworkString<maxLanguageStringSize> language;
162 		int8 gameInProgress;
163 		NetworkString<maxSmallStringSize> playerUUID;
164 		NetworkString<maxSmallStringSize> platform;
165 	};
166 
167 	void toEndian();
168 	void fromEndian();
169 
170 private:
171 	Data data;
172 
173 protected:
174 
175 public:
176 	NetworkMessageIntro();
177 	NetworkMessageIntro(int32 sessionId, const string &versionString,
178 			const string &name, int playerIndex, NetworkGameStateType gameState,
179 			uint32 externalIp, uint32 ftpPort, const string &playerLanguage,
180 			int gameInProgress, const string &playerUUID, const string &platform);
181 
182 
183 	virtual const char * getPackedMessageFormat() const;
184 	virtual unsigned int getPackedSize();
185 	virtual void unpackMessage(unsigned char *buf);
186 	virtual unsigned char * packMessage();
187 
getDataSize()188 	virtual size_t getDataSize() const { return sizeof(Data); }
189 
getNetworkMessageType()190 	virtual NetworkMessageType getNetworkMessageType() const {
191 		return nmtIntro;
192 	}
193 
getSessionId()194 	int32 getSessionId() const 					{ return data.sessionId;}
getVersionString()195 	string getVersionString() const				{ return data.versionString.getString(); }
getName()196 	string getName() const						{ return data.name.getString(); }
getPlayerIndex()197 	int getPlayerIndex() const					{ return data.playerIndex; }
getGameState()198 	NetworkGameStateType getGameState() const 	{ return static_cast<NetworkGameStateType>(data.gameState); }
getExternalIp()199 	uint32 getExternalIp() const                { return data.externalIp;}
getFtpPort()200 	uint32 getFtpPort() const					{ return data.ftpPort; }
getPlayerLanguage()201 	string getPlayerLanguage() const			{ return data.language.getString(); }
getGameInProgress()202 	uint8 getGameInProgress() const				{ return data.gameInProgress; }
203 
getPlayerUUID()204 	string getPlayerUUID() const				{ return data.playerUUID.getString();}
getPlayerPlatform()205 	string getPlayerPlatform() const			{ return data.platform.getString();}
206 
207 	virtual bool receive(Socket* socket);
208 	virtual void send(Socket* socket);
209 
210 	string toString() const;
211 };
212 #pragma pack(pop)
213 
214 // =====================================================
215 //	class NetworkMessagePing
216 //
217 //	Message sent at any time
218 // =====================================================
219 
220 #pragma pack(push, 1)
221 class NetworkMessagePing: public NetworkMessage{
222 private:
223 	int8 messageType;
224 	struct Data{
225 		int32 pingFrequency;
226 		int64 pingTime;
227 	};
228 	void toEndian();
229 	void fromEndian();
230 
231 private:
232 	Data data;
233 	int64 pingReceivedLocalTime;
234 
235 protected:
236 	virtual const char * getPackedMessageFormat() const;
237 	virtual unsigned int getPackedSize();
238 	virtual void unpackMessage(unsigned char *buf);
239 	virtual unsigned char * packMessage();
240 
241 public:
242 	NetworkMessagePing();
243 	NetworkMessagePing(int32 pingFrequency, int64 pingTime);
244 
getDataSize()245 	virtual size_t getDataSize() const { return sizeof(Data); }
246 
getNetworkMessageType()247 	virtual NetworkMessageType getNetworkMessageType() const {
248 		return nmtPing;
249 	}
250 
getPingFrequency()251 	int32 getPingFrequency() const	{return data.pingFrequency;}
getPingTime()252 	int64 getPingTime() const	{return data.pingTime;}
getPingReceivedLocalTime()253 	int64 getPingReceivedLocalTime() const { return pingReceivedLocalTime; }
setPingReceivedLocalTime(int64 pingTime)254 	void setPingReceivedLocalTime(int64 pingTime)  { pingReceivedLocalTime = pingTime; }
255 
256 	virtual bool receive(Socket* socket);
257 	virtual void send(Socket* socket);
258 };
259 #pragma pack(pop)
260 
261 // =====================================================
262 //	class NetworkMessageReady
263 //
264 //	Message sent at the beginning of the game
265 // =====================================================
266 
267 #pragma pack(push, 1)
268 class NetworkMessageReady: public NetworkMessage{
269 private:
270 	int8 messageType;
271 	struct Data{
272 		uint32 checksum;
273 	};
274 	void toEndian();
275 	void fromEndian();
276 
277 private:
278 	Data data;
279 
280 protected:
281 	virtual const char * getPackedMessageFormat() const;
282 	virtual unsigned int getPackedSize();
283 	virtual void unpackMessage(unsigned char *buf);
284 	virtual unsigned char * packMessage();
285 
286 public:
287 	NetworkMessageReady();
288 	NetworkMessageReady(uint32 checksum);
289 
getDataSize()290 	virtual size_t getDataSize() const { return sizeof(Data); }
291 
getNetworkMessageType()292 	virtual NetworkMessageType getNetworkMessageType() const {
293 		return nmtReady;
294 	}
295 
getChecksum()296 	uint32 getChecksum() const	{return data.checksum;}
297 
298 	virtual bool receive(Socket* socket);
299 	virtual void send(Socket* socket);
300 };
301 #pragma pack(pop)
302 
303 // =====================================================
304 //	class NetworkMessageLaunch
305 //
306 //	Message sent from the server to the client
307 //	to launch the game
308 // =====================================================
309 
310 #pragma pack(push, 1)
311 class NetworkMessageLaunch: public NetworkMessage {
312 private:
313 	static const int maxStringSize= 256;
314 	static const int maxSmallStringSize= 60;
315 	static const int maxFactionCRCCount= 20;
316 
317 private:
318 
319 	int8 messageType;
320 	uint32 compressedLength;
321 	struct Data {
322 		NetworkString<maxStringSize> description;
323 		NetworkString<maxSmallStringSize> map;
324 		NetworkString<maxSmallStringSize> tileset;
325 		NetworkString<maxSmallStringSize> tech;
326 		NetworkString<maxSmallStringSize> factionTypeNames[GameConstants::maxPlayers]; //faction names
327 		NetworkString<maxSmallStringSize> networkPlayerNames[GameConstants::maxPlayers]; //networkPlayerNames
328 		NetworkString<maxSmallStringSize> networkPlayerPlatform[GameConstants::maxPlayers];
329 		int32 networkPlayerStatuses[GameConstants::maxPlayers]; //networkPlayerStatuses
330 		NetworkString<maxSmallStringSize> networkPlayerLanguages[GameConstants::maxPlayers];
331 
332 		uint32 mapCRC;
333 		int8 mapFilter;
334 		uint32 tilesetCRC;
335 		uint32 techCRC;
336 		NetworkString<maxSmallStringSize> factionNameList[maxFactionCRCCount];
337 		uint32 factionCRCList[maxFactionCRCCount];
338 
339 		int8 factionControls[GameConstants::maxPlayers];
340 		int8 resourceMultiplierIndex[GameConstants::maxPlayers];
341 
342 		int8 thisFactionIndex;
343 		int8 factionCount;
344 		int8 teams[GameConstants::maxPlayers];
345 		int8 startLocationIndex[GameConstants::maxPlayers];
346 
347 		int8 defaultResources;
348         int8 defaultUnits;
349         int8 defaultVictoryConditions;
350 		int8 fogOfWar;
351 		int8 allowObservers;
352 		int8 enableObserverModeAtEndGame;
353 		int8 enableServerControlledAI;
354 		uint8 networkFramePeriod; // allowed values 0 - 255
355 		int8 networkPauseGameForLaggedClients;
356 		int8 pathFinderType;
357 		uint32 flagTypes1;
358 
359 		int8 aiAcceptSwitchTeamPercentChance;
360 		int8 cpuReplacementMultiplier;
361 		int32 masterserver_admin;
362 		int32 masterserver_admin_factionIndex;
363 
364 		NetworkString<maxStringSize> scenario;
365 
366 		NetworkString<maxSmallStringSize> networkPlayerUUID[GameConstants::maxPlayers];
367 
368 		int8 networkAllowNativeLanguageTechtree;
369 		NetworkString<maxSmallStringSize> gameUUID;
370 	};
371 	void toEndian();
372 	void fromEndian();
373 	std::pair<unsigned char *,unsigned long> getCompressedMessage();
374 private:
375 	Data data;
376 
377 protected:
378 	virtual const char * getPackedMessageFormat() const;
379 	virtual unsigned int getPackedSize();
380 	virtual void unpackMessage(unsigned char *buf);
381 	virtual unsigned char * packMessage();
382 
383 public:
384 	NetworkMessageLaunch();
385 	NetworkMessageLaunch(const GameSettings *gameSettings,int8 messageType);
386 
getDataSize()387 	virtual size_t getDataSize() const { return sizeof(Data); }
388 	virtual unsigned char * getData();
389 
getNetworkMessageType()390 	virtual NetworkMessageType getNetworkMessageType() const {
391 		return nmtLaunch;
392 	}
393 
394 	void buildGameSettings(GameSettings *gameSettings) const;
getMessageType()395 	int getMessageType() const { return messageType; }
396 
getMapCRC()397 	int getMapCRC() const { return data.mapCRC; }
getTilesetCRC()398 	int getTilesetCRC() const { return data.tilesetCRC; }
getTechCRC()399 	int getTechCRC() const { return data.techCRC; }
400 	vector<pair<string,uint32> > getFactionCRCList() const;
401 
402 	virtual bool receive(Socket* socket);
403 	virtual bool receive(Socket* socket, NetworkMessageType type);
404 
405 	virtual void send(Socket* socket);
406 };
407 #pragma pack(pop)
408 
409 // =====================================================
410 //	class CommandList
411 //
412 //	Message to order a commands to several units
413 // =====================================================
414 
415 #pragma pack(push, 1)
416 class NetworkMessageCommandList: public NetworkMessage {
417 
418 private:
419 
420 	struct DataHeader {
421 
422 		uint16 commandCount;
423 		int32 frameCount;
424 		uint32 networkPlayerFactionCRC[GameConstants::maxPlayers];
425 	};
426 
427 	static const int32 commandListHeaderSize = sizeof(DataHeader);
428 
429 	struct Data {
430 		int8 messageType;
431 		DataHeader header;
432 		std::vector<NetworkCommand> commands;
433 	};
init(Data & data_ref)434 	void init(Data &data_ref) {
435 		data_ref.messageType = 0;
436 		data_ref.header.commandCount = 0;
437 		data_ref.header.frameCount = 0;
438 		for(int index = 0; index < GameConstants::maxPlayers; ++index) {
439 			data_ref.header.networkPlayerFactionCRC[index] = 0;
440 		}
441 	}
442 	void toEndianHeader();
443 	void fromEndianHeader();
444 	void toEndianDetail(uint16 totalCommand);
445 	void fromEndianDetail();
446 
447 private:
448 	Data data;
449 
450 protected:
getPackedMessageFormat()451 	virtual const char * getPackedMessageFormat() const { return NULL; }
getPackedSize()452 	virtual unsigned int getPackedSize() { return 0; }
unpackMessage(unsigned char * buf)453 	virtual void unpackMessage(unsigned char *buf) { };
packMessage()454 	virtual unsigned char * packMessage() { return NULL; }
455 
456 	const char * getPackedMessageFormatHeader() const;
457 	unsigned int getPackedSizeHeader();
458 	void unpackMessageHeader(unsigned char *buf);
459 	unsigned char * packMessageHeader();
460 
461 	const char * getPackedMessageFormatDetail() const;
462 	unsigned int getPackedSizeDetail(int count);
463 	void unpackMessageDetail(unsigned char *buf,int count);
464 	unsigned char * packMessageDetail(uint16 totalCommand);
465 
466 public:
467 	NetworkMessageCommandList(int32 frameCount= -1);
468 
getDataSize()469 	virtual size_t getDataSize() const { return sizeof(Data); }
470 	virtual unsigned char * getData();
471 
getNetworkMessageType()472 	virtual NetworkMessageType getNetworkMessageType() const {
473 		return nmtCommandList;
474 	}
475 
476 	bool addCommand(const NetworkCommand* networkCommand);
477 
clear()478 	void clear()										{data.header.commandCount= 0;}
getCommandCount()479 	int getCommandCount() const							{return data.header.commandCount;}
getFrameCount()480 	int getFrameCount() const							{return data.header.frameCount;}
getNetworkPlayerFactionCRC(int index)481 	uint32 getNetworkPlayerFactionCRC(int index) const  {return data.header.networkPlayerFactionCRC[index];}
setNetworkPlayerFactionCRC(int index,uint32 crc)482 	void setNetworkPlayerFactionCRC(int index, uint32 crc) { data.header.networkPlayerFactionCRC[index]=crc;}
483 
getCommand(int i)484 	const NetworkCommand* getCommand(int i) const	{return &data.commands[i];}
485 
486 	virtual bool receive(Socket* socket);
487 	virtual void send(Socket* socket);
488 };
489 #pragma pack(pop)
490 
491 // =====================================================
492 //	class NetworkMessageText
493 //
494 //	Chat text message
495 // =====================================================
496 
497 #pragma pack(push, 1)
498 class NetworkMessageText: public NetworkMessage {
499 private:
500 	static const int maxTextStringSize= 500;
501 
502 private:
503 	int8 messageType;
504 	struct Data{
505 
506 		NetworkString<maxTextStringSize> text;
507 		int8 teamIndex;
508 		int8 playerIndex;
509 		NetworkString<maxLanguageStringSize> targetLanguage;
510 	};
511 	void toEndian();
512 	void fromEndian();
513 
514 private:
515 	Data data;
516 
517 protected:
518 	virtual const char * getPackedMessageFormat() const;
519 	virtual unsigned int getPackedSize();
520 	virtual void unpackMessage(unsigned char *buf);
521 	virtual unsigned char * packMessage();
522 
523 public:
524 	NetworkMessageText();
525 	NetworkMessageText(const string &text, int teamIndex, int playerIndex,
526 			const string targetLanguage);
527 
getDataSize()528 	virtual size_t getDataSize() const { return sizeof(Data); }
529 
getNetworkMessageType()530 	virtual NetworkMessageType getNetworkMessageType() const {
531 		return nmtText;
532 	}
533 
getText()534 	string getText() const		{return data.text.getString();}
getTeamIndex()535 	int getTeamIndex() const	{return data.teamIndex;}
getPlayerIndex()536 	int getPlayerIndex() const  {return data.playerIndex;}
getTargetLanguage()537 	string getTargetLanguage() const  {return data.targetLanguage.getString();}
538 
539 	virtual bool receive(Socket* socket);
540 	virtual void send(Socket* socket);
541 	NetworkMessageText * getCopy() const;
542 };
543 #pragma pack(pop)
544 
545 // =====================================================
546 //	class NetworkMessageQuit
547 //
548 //	Message sent at the beginning of the game
549 // =====================================================
550 
551 #pragma pack(push, 1)
552 class NetworkMessageQuit: public NetworkMessage{
553 private:
554 
555 	int8 messageType;
556 	//struct Data{
557 	//	int8 messageType;
558 	//};
559 	void toEndian();
560 	void fromEndian();
561 
562 private:
563 	//Data data;
564 
565 protected:
566 	virtual const char * getPackedMessageFormat() const;
567 	virtual unsigned int getPackedSize();
568 	virtual void unpackMessage(unsigned char *buf);
569 	virtual unsigned char * packMessage();
570 
571 public:
572 	NetworkMessageQuit();
573 
574 	//virtual size_t getDataSize() const { return sizeof(Data); }
getDataSize()575 	virtual size_t getDataSize() const { return 0; }
576 
getNetworkMessageType()577 	virtual NetworkMessageType getNetworkMessageType() const {
578 		return nmtQuit;
579 	}
580 
581 	virtual bool receive(Socket* socket);
582 	virtual void send(Socket* socket);
583 };
584 #pragma pack(pop)
585 
586 // =====================================================
587 //	class NetworkMessageSynchNetworkGameData
588 //
589 //	Message sent at the beginning of a network game
590 // =====================================================
591 
592 #pragma pack(push, 1)
593 class NetworkMessageSynchNetworkGameData: public NetworkMessage{
594 
595 private:
596 
597 static const int maxStringSize= 255;
598 static const int maxFileCRCCount= 1500;
599 static const int maxFileCRCPacketCount= 25;
600 
601 private:
602 
603 	struct DataHeader {
604 		NetworkString<maxStringSize> map;
605 		NetworkString<maxStringSize> tileset;
606 		NetworkString<maxStringSize> tech;
607 
608 		uint32 mapCRC;
609 		uint32 tilesetCRC;
610 		uint32 techCRC;
611 
612 		uint32 techCRCFileCount;
613 	};
614 
615 	static const int32 HeaderSize = sizeof(DataHeader);
616 
617 	struct DataDetail {
618 		NetworkString<maxStringSize> techCRCFileList[maxFileCRCCount];
619 		uint32 techCRCFileCRCList[maxFileCRCCount];
620 	};
621 
622 	static const int32 DetailSize1 = sizeof(NetworkString<maxStringSize>);
623 	static const int32 DetailSize2 = sizeof(uint32);
624 
625 	struct Data {
626 		int8 messageType;
627 		DataHeader header;
628 		DataDetail detail;
629 	};
630 	void toEndianHeader();
631 	void fromEndianHeader();
632 	void toEndianDetail(uint32 totalFileCount);
633 	void fromEndianDetail();
634 
635 private:
636 	Data data;
637 
638 protected:
getPackedMessageFormat()639 	virtual const char * getPackedMessageFormat() const { return NULL; }
getPackedSize()640 	virtual unsigned int getPackedSize() { return 0; }
unpackMessage(unsigned char * buf)641 	virtual void unpackMessage(unsigned char *buf) { };
packMessage()642 	virtual unsigned char * packMessage() { return NULL; }
643 
644 	const char * getPackedMessageFormatHeader() const;
645 	unsigned int getPackedSizeHeader();
646 	void unpackMessageHeader(unsigned char *buf);
647 	unsigned char * packMessageHeader();
648 
649 	unsigned int getPackedSizeDetail();
650 	void unpackMessageDetail(unsigned char *buf);
651 	unsigned char * packMessageDetail();
652 
653 public:
NetworkMessageSynchNetworkGameData()654     NetworkMessageSynchNetworkGameData() {};
655 	NetworkMessageSynchNetworkGameData(const GameSettings *gameSettings);
656 
getDataSize()657 	virtual size_t getDataSize() const { return sizeof(Data); }
658 
getNetworkMessageType()659 	virtual NetworkMessageType getNetworkMessageType() const {
660 		return nmtSynchNetworkGameData;
661 	}
662 
663 	virtual bool receive(Socket* socket);
664 	virtual void send(Socket* socket);
665 
getMap()666 	string getMap() const		{return data.header.map.getString();}
getTileset()667 	string getTileset() const   {return data.header.tileset.getString();}
getTech()668 	string getTech() const		{return data.header.tech.getString();}
669 
getMapCRC()670 	uint32 getMapCRC() const		{return data.header.mapCRC;}
getTilesetCRC()671 	uint32 getTilesetCRC() const	{return data.header.tilesetCRC;}
getTechCRC()672 	uint32 getTechCRC() const	{return data.header.techCRC;}
673 
getTechCRCFileCount()674 	uint32 getTechCRCFileCount() const {return data.header.techCRCFileCount;}
getTechCRCFileList()675 	const NetworkString<maxStringSize> * getTechCRCFileList() const {return &data.detail.techCRCFileList[0];}
getTechCRCFileCRCList()676 	const uint32 * getTechCRCFileCRCList() const {return data.detail.techCRCFileCRCList;}
677 
678 	string getTechCRCFileMismatchReport(vector<std::pair<string,uint32> > &vctFileList);
679 };
680 #pragma pack(pop)
681 
682 // =====================================================
683 //	class NetworkMessageSynchNetworkGameDataStatus
684 //
685 //	Message sent at the beggining of a network game
686 // =====================================================
687 
688 #pragma pack(push, 1)
689 class NetworkMessageSynchNetworkGameDataStatus: public NetworkMessage{
690 
691 private:
692 
693 static const int maxStringSize= 255;
694 static const int maxFileCRCCount= 1500;
695 static const uint32 maxFileCRCPacketCount= 25;
696 
697 private:
698 
699 	struct DataHeader {
700 		uint32 mapCRC;
701 		uint32 tilesetCRC;
702 		uint32 techCRC;
703 
704 		uint32 techCRCFileCount;
705 	};
706 	static const int32 HeaderSize = sizeof(DataHeader);
707 
708 	struct DataDetail {
709 		NetworkString<maxStringSize> techCRCFileList[maxFileCRCCount];
710 		uint32 techCRCFileCRCList[maxFileCRCCount];
711 	};
712 
713 	static const int32 DetailSize1 = sizeof(NetworkString<maxStringSize>);
714 	static const int32 DetailSize2 = sizeof(uint32);
715 
716 	struct Data {
717 		int8 messageType;
718 		DataHeader header;
719 		DataDetail detail;
720 	};
721 	void toEndianHeader();
722 	void fromEndianHeader();
723 	void toEndianDetail(uint32 totalFileCount);
724 	void fromEndianDetail();
725 
726 private:
727 	Data data;
728 
729 protected:
getPackedMessageFormat()730 	virtual const char * getPackedMessageFormat() const { return NULL; }
getPackedSize()731 	virtual unsigned int getPackedSize() { return 0; }
unpackMessage(unsigned char * buf)732 	virtual void unpackMessage(unsigned char *buf) { };
packMessage()733 	virtual unsigned char * packMessage() { return NULL; }
734 
735 public:
NetworkMessageSynchNetworkGameDataStatus()736     NetworkMessageSynchNetworkGameDataStatus() {};
737 	NetworkMessageSynchNetworkGameDataStatus(uint32 mapCRC, uint32 tilesetCRC, uint32 techCRC, vector<std::pair<string,uint32> > &vctFileList);
738 
getDataSize()739 	virtual size_t getDataSize() const { return sizeof(Data); }
740 
getNetworkMessageType()741 	virtual NetworkMessageType getNetworkMessageType() const {
742 		return nmtSynchNetworkGameDataStatus;
743 	}
744 
745 	virtual bool receive(Socket* socket);
746 	virtual void send(Socket* socket);
747 
getMapCRC()748 	uint32 getMapCRC() const		{return data.header.mapCRC;}
getTilesetCRC()749 	uint32 getTilesetCRC() const	{return data.header.tilesetCRC;}
getTechCRC()750 	uint32 getTechCRC() const	{return data.header.techCRC;}
751 
getTechCRCFileCount()752 	uint32 getTechCRCFileCount() const {return data.header.techCRCFileCount;}
getTechCRCFileList()753 	const NetworkString<maxStringSize> * getTechCRCFileList() const {return &data.detail.techCRCFileList[0];}
getTechCRCFileCRCList()754 	const uint32 * getTechCRCFileCRCList() const {return data.detail.techCRCFileCRCList;}
755 
756 	string getTechCRCFileMismatchReport(string techtree, vector<std::pair<string,uint32> > &vctFileList);
757 
758 };
759 #pragma pack(pop)
760 
761 // =====================================================
762 //	class NetworkMessageSynchNetworkGameDataFileCRCCheck
763 //
764 //	Message sent at the beginning of a network game
765 // =====================================================
766 
767 #pragma pack(push, 1)
768 class NetworkMessageSynchNetworkGameDataFileCRCCheck: public NetworkMessage{
769 
770 private:
771 
772 static const int maxStringSize= 256;
773 
774 private:
775 	int8 messageType;
776 	struct Data{
777 
778 
779 		uint32 totalFileCount;
780 		uint32 fileIndex;
781 		uint32 fileCRC;
782 		NetworkString<maxStringSize> fileName;
783 	};
784 	void toEndian();
785 	void fromEndian();
786 
787 private:
788 	Data data;
789 
790 protected:
791 	virtual const char * getPackedMessageFormat() const;
792 	virtual unsigned int getPackedSize();
793 	virtual void unpackMessage(unsigned char *buf);
794 	virtual unsigned char * packMessage();
795 
796 public:
797     NetworkMessageSynchNetworkGameDataFileCRCCheck();
798 	NetworkMessageSynchNetworkGameDataFileCRCCheck(uint32 totalFileCount, uint32 fileIndex, uint32 fileCRC, const string fileName);
799 
getDataSize()800 	virtual size_t getDataSize() const { return sizeof(Data); }
801 
getNetworkMessageType()802 	virtual NetworkMessageType getNetworkMessageType() const {
803 		return nmtSynchNetworkGameDataFileCRCCheck;
804 	}
805 
806 	virtual bool receive(Socket* socket);
807 	virtual void send(Socket* socket);
808 
getTotalFileCount()809 	uint32 getTotalFileCount() const	{return data.totalFileCount;}
getFileIndex()810 	uint32 getFileIndex() const	    {return data.fileIndex;}
getFileCRC()811 	uint32 getFileCRC() const	    {return data.fileCRC;}
getFileName()812 	string getFileName() const		{return data.fileName.getString();}
813 };
814 #pragma pack(pop)
815 
816 // =====================================================
817 //	class NetworkMessageSynchNetworkGameDataFileGet
818 //
819 //	Message sent at the beginning of a network game
820 // =====================================================
821 
822 #pragma pack(push, 1)
823 class NetworkMessageSynchNetworkGameDataFileGet: public NetworkMessage{
824 
825 private:
826 
827 static const int maxStringSize= 256;
828 
829 private:
830 
831 	int8 messageType;
832 	struct Data{
833 
834 		NetworkString<maxStringSize> fileName;
835 	};
836 	void toEndian();
837 	void fromEndian();
838 
839 private:
840 	Data data;
841 
842 protected:
843 	virtual const char * getPackedMessageFormat() const;
844 	virtual unsigned int getPackedSize();
845 	virtual void unpackMessage(unsigned char *buf);
846 	virtual unsigned char * packMessage();
847 
848 public:
849     NetworkMessageSynchNetworkGameDataFileGet();
850 	NetworkMessageSynchNetworkGameDataFileGet(const string fileName);
851 
getDataSize()852 	virtual size_t getDataSize() const { return sizeof(Data); }
853 
getNetworkMessageType()854 	virtual NetworkMessageType getNetworkMessageType() const {
855 		return nmtSynchNetworkGameDataFileGet;
856 	}
857 
858 	virtual bool receive(Socket* socket);
859 	virtual void send(Socket* socket);
860 
getFileName()861 	string getFileName() const		{return data.fileName.getString();}
862 };
863 #pragma pack(pop)
864 
865 // =====================================================
866 //	class SwitchSetupRequest
867 //
868 //	Message sent from the client to the server
869 //	to switch its settings
870 // =====================================================
871 
872 // Each bit represents which item in the packet has a changed value
873 enum SwitchSetupRequestFlagType {
874 	ssrft_None					= 0x00,
875 	ssrft_SelectedFactionName	= 0x01,
876 	ssrft_CurrentFactionIndex	= 0x02,
877 	ssrft_ToFactionIndex		= 0x04,
878 	ssrft_ToTeam				= 0x08,
879 	ssrft_NetworkPlayerName		= 0x10,
880 	ssrft_PlayerStatus			= 0x20
881 };
882 
883 #pragma pack(push, 1)
884 class SwitchSetupRequest: public NetworkMessage{
885 private:
886 	static const int maxStringSize= 256;
887 	static const int maxPlayernameStringSize= 80;
888 
889 private:
890 
891 	int8 messageType;
892 	struct Data {
893 
894 		NetworkString<maxStringSize> selectedFactionName; //wanted faction name
895 		int8 currentSlotIndex;
896 		int8 toSlotIndex;
897 		int8 toTeam;
898 		NetworkString<maxPlayernameStringSize> networkPlayerName;
899 		int8 networkPlayerStatus;
900 		int8 switchFlags;
901 		NetworkString<maxLanguageStringSize> language;
902 	};
903 	void toEndian();
904 	void fromEndian();
905 
906 private:
907 	Data data;
908 
909 public:
910 	virtual const char * getPackedMessageFormat() const;
911 	virtual unsigned int getPackedSize();
912 	virtual void unpackMessage(unsigned char *buf);
913 	virtual unsigned char * packMessage();
914 
915 public:
916 	SwitchSetupRequest();
917 	SwitchSetupRequest( string selectedFactionName, int8 currentFactionIndex,
918 						int8 toFactionIndex,int8 toTeam,string networkPlayerName,
919 						int8 networkPlayerStatus, int8 flags,
920 						string language);
921 
getDataSize()922 	virtual size_t getDataSize() const { return sizeof(Data); }
923 
getNetworkMessageType()924 	virtual NetworkMessageType getNetworkMessageType() const {
925 		return nmtSwitchSetupRequest;
926 	}
927 
getSelectedFactionName()928 	string getSelectedFactionName() const	{return data.selectedFactionName.getString();}
getCurrentSlotIndex()929 	int getCurrentSlotIndex() const		{return data.currentSlotIndex;}
getToSlotIndex()930 	int getToSlotIndex() const			{return data.toSlotIndex;}
getToTeam()931 	int getToTeam() const					{return data.toTeam;}
getNetworkPlayerName()932 	string getNetworkPlayerName() const		{return data.networkPlayerName.getString(); }
getSwitchFlags()933 	int getSwitchFlags() const				{return data.switchFlags;}
addSwitchFlag(SwitchSetupRequestFlagType flag)934 	void addSwitchFlag(SwitchSetupRequestFlagType flag) { data.switchFlags |= flag;}
clearSwitchFlag(SwitchSetupRequestFlagType flag)935 	void clearSwitchFlag(SwitchSetupRequestFlagType flag) { data.switchFlags &= ~flag;}
936 
getNetworkPlayerStatus()937 	int getNetworkPlayerStatus() const		{ return data.networkPlayerStatus; }
getNetworkPlayerLanguage()938 	string getNetworkPlayerLanguage() const	{ return data.language.getString(); }
939 
940 	virtual bool receive(Socket* socket);
941 	virtual void send(Socket* socket);
942 };
943 #pragma pack(pop)
944 
945 // =====================================================
946 //	class PlayerIndexMessage
947 //
948 //	Message sent from the server to the clients
949 //	to tell them about a slot change ( caused by another client )
950 // =====================================================
951 
952 #pragma pack(push, 1)
953 class PlayerIndexMessage: public NetworkMessage{
954 
955 private:
956 
957 	int8 messageType;
958 	struct Data {
959 
960 		int16 playerIndex;
961 	};
962 	void toEndian();
963 	void fromEndian();
964 
965 private:
966 	Data data;
967 
968 protected:
969 	virtual const char * getPackedMessageFormat() const;
970 	virtual unsigned int getPackedSize();
971 	virtual void unpackMessage(unsigned char *buf);
972 	virtual unsigned char * packMessage();
973 
974 public:
975 	PlayerIndexMessage( int16 playerIndex);
976 
getDataSize()977 	virtual size_t getDataSize() const { return sizeof(Data); }
978 
getNetworkMessageType()979 	virtual NetworkMessageType getNetworkMessageType() const {
980 		return nmtPlayerIndexMessage;
981 	}
982 
getPlayerIndex()983 	int16 getPlayerIndex() const	{return data.playerIndex;}
984 
985 	virtual bool receive(Socket* socket);
986 	virtual void send(Socket* socket);
987 };
988 #pragma pack(pop)
989 
990 // =====================================================
991 //	class NetworkMessageLoadingStatus
992 //
993 //	Message sent during game loading
994 // =====================================================
995 
996 enum NetworkMessageLoadingStatusType {
997 	nmls_NONE = 0x00,
998 
999 	nmls_PLAYER1_CONNECTED = 0x01,
1000 	nmls_PLAYER2_CONNECTED = 0x02,
1001 	nmls_PLAYER3_CONNECTED = 0x04,
1002 	nmls_PLAYER4_CONNECTED = 0x08,
1003 	nmls_PLAYER5_CONNECTED = 0x10,
1004 	nmls_PLAYER6_CONNECTED = 0x20,
1005 	nmls_PLAYER7_CONNECTED = 0x40,
1006 	nmls_PLAYER8_CONNECTED = 0x80,
1007 
1008 	nmls_PLAYER1_READY = 0x100,
1009 	nmls_PLAYER2_READY = 0x200,
1010 	nmls_PLAYER3_READY = 0x400,
1011 	nmls_PLAYER4_READY = 0x1000,
1012 	nmls_PLAYER5_READY = 0x2000,
1013 	nmls_PLAYER6_READY = 0x4000,
1014 	nmls_PLAYER7_READY = 0x8000,
1015 	nmls_PLAYER8_READY = 0x10000
1016 };
1017 
1018 #pragma pack(push, 1)
1019 class NetworkMessageLoadingStatus : public NetworkMessage {
1020 private:
1021 
1022 	int8 messageType;
1023 	struct Data {
1024 
1025 		uint32 status;
1026 	};
1027 	void toEndian();
1028 	void fromEndian();
1029 
1030 private:
1031 	Data data;
1032 
1033 protected:
1034 	virtual const char * getPackedMessageFormat() const;
1035 	virtual unsigned int getPackedSize();
1036 	virtual void unpackMessage(unsigned char *buf);
1037 	virtual unsigned char * packMessage();
1038 
1039 public:
1040 	NetworkMessageLoadingStatus();
1041 	NetworkMessageLoadingStatus(uint32 status);
1042 
getDataSize()1043 	virtual size_t getDataSize() const { return sizeof(Data); }
1044 
getNetworkMessageType()1045 	virtual NetworkMessageType getNetworkMessageType() const {
1046 		return nmtLoadingStatusMessage;
1047 	}
1048 
getStatus()1049 	uint32 getStatus() const	{return data.status;}
1050 
1051 	virtual bool receive(Socket* socket);
1052 	virtual void send(Socket* socket);
1053 };
1054 #pragma pack(pop)
1055 
1056 
1057 // =====================================================
1058 //	class NetworkMessageMarkCell
1059 //
1060 //	Mark a Cell message nmtMarkCell
1061 // =====================================================
1062 
1063 #pragma pack(push, 1)
1064 class NetworkMessageMarkCell: public NetworkMessage {
1065 private:
1066 	static const int maxTextStringSize= 500;
1067 
1068 private:
1069 
1070 	int8 messageType;
1071 	struct Data{
1072 
1073 
1074 		int16 targetX;
1075 		int16 targetY;
1076 		int8 factionIndex;
1077 		int8 playerIndex;
1078 		NetworkString<maxTextStringSize> text;
1079 	};
1080 	void toEndian();
1081 	void fromEndian();
1082 
1083 private:
1084 	Data data;
1085 
1086 protected:
1087 	virtual const char * getPackedMessageFormat() const;
1088 	virtual unsigned int getPackedSize();
1089 	virtual void unpackMessage(unsigned char *buf);
1090 	virtual unsigned char * packMessage();
1091 
1092 public:
1093 	NetworkMessageMarkCell();
1094 	NetworkMessageMarkCell(Vec2i target, int factionIndex, const string &text, int playerIndex);
1095 
getDataSize()1096 	virtual size_t getDataSize() const { return sizeof(Data); }
1097 
getNetworkMessageType()1098 	virtual NetworkMessageType getNetworkMessageType() const {
1099 		return nmtMarkCell;
1100 	}
1101 
getText()1102 	string getText() const			{ return data.text.getString(); }
getTarget()1103 	Vec2i getTarget() const		{ return Vec2i(data.targetX,data.targetY); }
getFactionIndex()1104 	int getFactionIndex() const  { return data.factionIndex; }
getPlayerIndex()1105 	int getPlayerIndex() const { return data.playerIndex; }
1106 
1107 	virtual bool receive(Socket* socket);
1108 	virtual void send(Socket* socket);
1109 	NetworkMessageMarkCell * getCopy() const;
1110 };
1111 #pragma pack(pop)
1112 
1113 // =====================================================
1114 //	class NetworkUnMessageMarkCell
1115 //
1116 //	Mark a Cell message nmtUnMarkCell
1117 // =====================================================
1118 
1119 #pragma pack(push, 1)
1120 class NetworkMessageUnMarkCell: public NetworkMessage {
1121 
1122 private:
1123 
1124 	int8 messageType;
1125 	struct Data {
1126 
1127 
1128 		int16 targetX;
1129 		int16 targetY;
1130 		int8 factionIndex;
1131 	};
1132 	void toEndian();
1133 	void fromEndian();
1134 
1135 private:
1136 	Data data;
1137 
1138 protected:
1139 	virtual const char * getPackedMessageFormat() const;
1140 	virtual unsigned int getPackedSize();
1141 	virtual void unpackMessage(unsigned char *buf);
1142 	virtual unsigned char * packMessage();
1143 
1144 public:
1145 	NetworkMessageUnMarkCell();
1146 	NetworkMessageUnMarkCell(Vec2i target, int factionIndex);
1147 
getDataSize()1148 	virtual size_t getDataSize() const { return sizeof(Data); }
1149 
getNetworkMessageType()1150 	virtual NetworkMessageType getNetworkMessageType() const {
1151 		return nmtUnMarkCell;
1152 	}
1153 
getTarget()1154 	Vec2i getTarget() const		{ return Vec2i(data.targetX,data.targetY); }
getFactionIndex()1155 	int getFactionIndex() const  { return data.factionIndex; }
1156 
1157 	virtual bool receive(Socket* socket);
1158 	virtual void send(Socket* socket);
1159 	NetworkMessageUnMarkCell * getCopy() const;
1160 };
1161 #pragma pack(pop)
1162 
1163 // =====================================================
1164 //	class NetworkHighlightCellMessage
1165 //
1166 //	Highlight a Cell message
1167 // =====================================================
1168 
1169 
1170 #pragma pack(push, 1)
1171 class NetworkMessageHighlightCell: public NetworkMessage {
1172 private:
1173 	static const int maxTextStringSize= 500;
1174 
1175 private:
1176 
1177 	int8 messageType;
1178 	struct Data{
1179 
1180 		int16 targetX;
1181 		int16 targetY;
1182 		int8 factionIndex;
1183 	};
1184 	void toEndian();
1185 	void fromEndian();
1186 
1187 private:
1188 	Data data;
1189 
1190 protected:
1191 	virtual const char * getPackedMessageFormat() const;
1192 	virtual unsigned int getPackedSize();
1193 	virtual void unpackMessage(unsigned char *buf);
1194 	virtual unsigned char * packMessage();
1195 
1196 public:
1197 	NetworkMessageHighlightCell();
1198 	NetworkMessageHighlightCell(Vec2i target, int factionIndex);
1199 
getDataSize()1200 	virtual size_t getDataSize() const { return sizeof(Data); }
1201 
getNetworkMessageType()1202 	virtual NetworkMessageType getNetworkMessageType() const {
1203 		return nmtHighlightCell;
1204 	}
1205 
getTarget()1206 	Vec2i getTarget() const		{ return Vec2i(data.targetX,data.targetY); }
getFactionIndex()1207 	int getFactionIndex() const  { return data.factionIndex; }
1208 
1209 	virtual bool receive(Socket* socket);
1210 	virtual void send(Socket* socket);
1211 };
1212 #pragma pack(pop)
1213 
1214 }}//end namespace
1215 
1216 #endif
1217