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