// ============================================================== // This file is part of Glest (www.glest.org) // // Copyright (C) 2001-2008 MartiƱo Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version // ============================================================== #ifndef _GLEST_GAME_NETWORKINTERFACE_H_ #define _GLEST_GAME_NETWORKINTERFACE_H_ #ifdef WIN32 #include #include #endif #include #include #include "checksum.h" #include "network_message.h" #include "network_types.h" #include "game_settings.h" #include "thread.h" #include "data_types.h" #include #include "leak_dumper.h" using std::string; using std::vector; using Shared::Util::Checksum; using namespace Shared::Util; using namespace Shared::Platform; namespace Glest{ namespace Game{ // ===================================================== // class NetworkInterface // ===================================================== // // This interface describes the methods to notify when a client is lagging // class ClientLagCallbackInterface { public: virtual bool clientLagHandler(int slotIndex, bool networkPauseGameForLaggedClients) = 0; virtual ~ClientLagCallbackInterface() {} }; class ChatMsgInfo { protected: void copyAll(const ChatMsgInfo &obj) { this->chatText = obj.chatText.c_str(); this->chatTeamIndex = obj.chatTeamIndex; this->chatPlayerIndex = obj.chatPlayerIndex; this->targetLanguage = obj.targetLanguage; } public: ChatMsgInfo() { this->chatText = ""; this->chatTeamIndex = -1; this->chatPlayerIndex = -1; this->targetLanguage = ""; } ChatMsgInfo(string chatText, int chatTeamIndex, int chatPlayerIndex, string targetLanguage) { this->chatText = chatText; this->chatTeamIndex = chatTeamIndex; this->chatPlayerIndex = chatPlayerIndex; this->targetLanguage = targetLanguage; } ChatMsgInfo(const ChatMsgInfo& obj) { copyAll(obj); } ChatMsgInfo & operator=(const ChatMsgInfo & obj) { copyAll(obj); return *this; } string chatText; int chatTeamIndex; int chatPlayerIndex; string targetLanguage; }; class MarkedCell { protected: Vec2i targetPos; const Faction *faction; int factionIndex; int playerIndex; string note; int aliveCount; public: static Vec3f static_system_marker_color; MarkedCell() { faction = NULL; factionIndex = -1; playerIndex = -1; note = ""; aliveCount=200; } MarkedCell(Vec2i targetPos,const Faction *faction,string note, int playerIndex) { this->targetPos = targetPos; this->faction = faction; this->factionIndex = -1; this->playerIndex = playerIndex; this->note = note; aliveCount=200; } MarkedCell(Vec2i targetPos,int factionIndex,string note, int playerIndex) { this->targetPos = targetPos; this->faction = NULL; this->factionIndex = factionIndex; this->playerIndex = playerIndex; this->note = note; aliveCount=200; } Vec2i getTargetPos() const { return targetPos; } const Faction * getFaction() const { return faction; } void setFaction(const Faction *faction) { this->faction = faction; } int getFactionIndex() const { return factionIndex; } string getNote() const { return note; } void decrementAliveCount() { this->aliveCount--; } int getAliveCount() const { return aliveCount; } void setAliveCount(int value) { this->aliveCount = value; } int getPlayerIndex() const { return playerIndex; } void setNote(string value) { note = value; } void setPlayerIndex(int value) { playerIndex = value; } }; class UnMarkedCell { protected: Vec2i targetPos; const Faction *faction; int factionIndex; public: UnMarkedCell() { faction = NULL; factionIndex = -1; } UnMarkedCell(Vec2i targetPos,const Faction *faction) { this->targetPos = targetPos; this->faction = faction; this->factionIndex = -1; } UnMarkedCell(Vec2i targetPos,int factionIndex) { this->targetPos = targetPos; this->faction = NULL; this->factionIndex = factionIndex; } Vec2i getTargetPos() const { return targetPos; } const Faction * getFaction() const { return faction; } void setFaction(const Faction *faction) { this->faction = faction; } int getFactionIndex() const { return factionIndex; } }; typedef int (*DisplayMessageFunction)(const char *msg, bool exit); class NetworkInterface { protected: static bool allowGameDataSynchCheck; static bool allowDownloadDataSynch; bool networkGameDataSynchCheckOkMap; bool networkGameDataSynchCheckOkTile; bool networkGameDataSynchCheckOkTech; string networkGameDataSynchCheckTechMismatchReport; bool receivedDataSynchCheck; NetworkMessagePing lastPingInfo; std::vector chatTextList; std::vector markedCellList; std::vector unmarkedCellList; static DisplayMessageFunction pCB_DisplayMessage; void DisplayErrorMessage(string sErr, bool closeSocket=true); virtual Mutex * getServerSynchAccessor() = 0; std::vector highlightedCellList; Mutex *networkAccessMutex; void init(); Mutex *networkPlayerFactionCRCMutex; uint32 networkPlayerFactionCRC[GameConstants::maxPlayers]; public: static const int readyWaitTimeout; GameSettings gameSettings; public: NetworkInterface(); virtual ~NetworkInterface(); NetworkInterface(const NetworkInterface& obj) { init(); throw megaglest_runtime_error("class NetworkInterface is NOT safe to copy!"); } NetworkInterface & operator=(const NetworkInterface& obj) { init(); throw megaglest_runtime_error("class NetworkInterface is NOT safe to assign!"); } uint32 getNetworkPlayerFactionCRC(int index); void setNetworkPlayerFactionCRC(int index, uint32 crc); virtual Socket* getSocket(bool mutexLock=true)= 0; virtual void close()= 0; virtual string getHumanPlayerName(int index=-1) = 0; virtual int getHumanPlayerIndex() const = 0; static void setDisplayMessageFunction(DisplayMessageFunction pDisplayMessage) { pCB_DisplayMessage = pDisplayMessage; } static DisplayMessageFunction getDisplayMessageFunction() { return pCB_DisplayMessage; } virtual std::string getIpAddress(bool mutexLock=true) = 0; string getIp() const {return Socket::getIp();} string getHostName() const {return Socket::getHostName();} virtual void sendMessage(NetworkMessage* networkMessage); NetworkMessageType getNextMessageType(int waitMilliseconds=0); bool receiveMessage(NetworkMessage* networkMessage); virtual bool isConnected(); const virtual GameSettings * getGameSettings() { return &gameSettings; } GameSettings * getGameSettingsPtr() { return &gameSettings; } static void setAllowDownloadDataSynch(bool value) { allowDownloadDataSynch = value; } static bool getAllowDownloadDataSynch() { return allowDownloadDataSynch; } static void setAllowGameDataSynchCheck(bool value) { allowGameDataSynchCheck = value; } static bool getAllowGameDataSynchCheck() { return allowGameDataSynchCheck; } virtual bool getNetworkGameDataSynchCheckOk() { return (networkGameDataSynchCheckOkMap && networkGameDataSynchCheckOkTile && networkGameDataSynchCheckOkTech); } virtual void setNetworkGameDataSynchCheckOkMap(bool value) { networkGameDataSynchCheckOkMap = value; } virtual void setNetworkGameDataSynchCheckOkTile(bool value) { networkGameDataSynchCheckOkTile = value; } virtual void setNetworkGameDataSynchCheckOkTech(bool value) { networkGameDataSynchCheckOkTech = value; } virtual bool getNetworkGameDataSynchCheckOkMap() { return networkGameDataSynchCheckOkMap; } virtual bool getNetworkGameDataSynchCheckOkTile() { return networkGameDataSynchCheckOkTile; } virtual bool getNetworkGameDataSynchCheckOkTech() { return networkGameDataSynchCheckOkTech; } std::vector getChatTextList(bool clearList); void clearChatInfo(); void addChatInfo(const ChatMsgInfo &msg); std::vector getMarkedCellList(bool clearList); void clearMarkedCellList(); void addMarkedCell(const MarkedCell &msg); std::vector getUnMarkedCellList(bool clearList); void clearUnMarkedCellList(); void addUnMarkedCell(const UnMarkedCell &msg); std::vector getHighlightedCellList(bool clearList); void clearHighlightedCellList(); void setHighlightedCell(const MarkedCell &msg); virtual bool getConnectHasHandshaked() const= 0; void setLastPingInfo(const NetworkMessagePing &ping); void setLastPingInfoToNow(); NetworkMessagePing getLastPingInfo(); double getLastPingLag(); float getThreadedPingMS(std::string host); string getNetworkGameDataSynchCheckTechMismatchReport() const {return networkGameDataSynchCheckTechMismatchReport;} void setNetworkGameDataSynchCheckTechMismatchReport(string value) {networkGameDataSynchCheckTechMismatchReport = value;} bool getReceivedDataSynchCheck() const {return receivedDataSynchCheck;} void setReceivedDataSynchCheck(bool value) { receivedDataSynchCheck = value; } virtual void saveGame(XmlNode *rootNode) = 0; //static void loadGame(string name); }; // ===================================================== // class GameNetworkInterface // // Adds functions common to servers and clients // but not connection slots // ===================================================== class GameNetworkInterface: public NetworkInterface { protected: typedef vector Commands; Commands requestedCommands; //commands requested by the user Commands pendingCommands; //commands ready to be given bool quit; public: GameNetworkInterface(); virtual ~GameNetworkInterface(){} //message processimg virtual void update()= 0; virtual void updateLobby()= 0; virtual void updateKeyframe(int frameCount)= 0; virtual void setKeyframe(int frameCount)= 0; virtual void waitUntilReady(Checksum* checksum)= 0; //message sending virtual void sendTextMessage(const string &text, int teamIndex,bool echoLocal, string targetLanguage)= 0; virtual void quitGame(bool userManuallyQuit)=0; virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note,int playerIndex) = 0; virtual void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex) = 0; virtual void sendHighlightCellMessage(Vec2i targetPos, int factionIndex) = 0; //misc virtual string getNetworkStatus() = 0; //access functions void requestCommand(const NetworkCommand *networkCommand, bool insertAtStart=false); int getPendingCommandCount() const {return (int)pendingCommands.size();} NetworkCommand* getPendingCommand(int i) {return &pendingCommands[i];} void clearPendingCommands() {pendingCommands.clear();} bool getQuit() const {return quit;} }; // ===================================================== // class FileTransferSocketThread // ===================================================== enum FileTransferHostType { eClient, eServer }; enum FileTransferOperationType { eSend, eReceive }; class FileTransferInfo { private: void CopyAll(const FileTransferInfo &obj) { hostType = obj.hostType; serverIP = obj.serverIP; serverPort = obj.serverPort; opType = obj.opType; fileName = obj.fileName; } public: FileTransferInfo() { hostType = eClient; serverIP = ""; serverPort = 0; opType = eSend; fileName = ""; } FileTransferInfo(const FileTransferInfo &obj) { CopyAll(obj); } FileTransferInfo &operator=(const FileTransferInfo &obj) { CopyAll(obj); return *this; } FileTransferHostType hostType; string serverIP; int32 serverPort; FileTransferOperationType opType; string fileName; }; class FileInfo { public: string fileName; int64 filesize; uint32 filecrc; }; class FileTransferSocketThread : public Thread { private: FileTransferInfo info; public: FileTransferSocketThread(FileTransferInfo fileInfo); virtual void execute(); }; }}//end namespace #endif