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_SERVERINTERFACE_H_ 13 #define _GLEST_GAME_SERVERINTERFACE_H_ 14 15 #ifdef WIN32 16 #include <winsock2.h> 17 #include <winsock.h> 18 #endif 19 20 #include <vector> 21 #include "game_constants.h" 22 #include "network_interface.h" 23 #include "connection_slot.h" 24 #include "socket.h" 25 #include "leak_dumper.h" 26 27 using std::vector; 28 using Shared::Platform::ServerSocket; 29 30 namespace Shared { namespace PlatformCommon { class FTPServerThread; }} 31 32 namespace Glest{ namespace Game{ 33 34 class Stats; 35 // ===================================================== 36 // class ServerInterface 37 // ===================================================== 38 39 class ServerInterface: public GameNetworkInterface, 40 public ConnectionSlotCallbackInterface, 41 // This is for publishing game status to the masterserver 42 public SimpleTaskCallbackInterface, 43 public FTPClientValidationInterface { 44 45 class TextMessageQueue { 46 public: 47 string text; 48 int teamIndex; 49 bool echoLocal; 50 string targetLanguage; 51 }; 52 53 private: 54 ConnectionSlot* slots[GameConstants::maxPlayers]; 55 Mutex *slotAccessorMutexes[GameConstants::maxPlayers]; 56 57 ServerSocket serverSocket; 58 59 Mutex *switchSetupRequestsSynchAccessor; 60 SwitchSetupRequest* switchSetupRequests[GameConstants::maxPlayers]; 61 62 Mutex *serverSynchAccessor; 63 int currentFrameCount; 64 65 time_t gameStartTime; 66 67 time_t lastGlobalLagCheckTime; 68 69 SimpleTaskThread *publishToMasterserverThread; 70 Mutex *masterServerThreadAccessor; 71 time_t lastMasterserverHeartbeatTime; 72 bool needToRepublishToMasterserver; 73 74 ::Shared::PlatformCommon::FTPServerThread *ftpServer; 75 bool exitServer; 76 int64 nextEventId; 77 78 Mutex *textMessageQueueThreadAccessor; 79 vector<TextMessageQueue> textMessageQueue; 80 81 Mutex *broadcastMessageQueueThreadAccessor; 82 vector<pair<NetworkMessage *,int> > broadcastMessageQueue; 83 84 Mutex *inBroadcastMessageThreadAccessor; 85 bool inBroadcastMessage; 86 87 bool masterserverAdminRequestLaunch; 88 89 vector<string> mapFiles; 90 vector<string> playerSortedMaps[GameConstants::maxPlayers+1]; 91 vector<string> techTreeFiles; 92 vector<string> tilesetFiles; 93 94 map<string,pair<uint64,time_t> > badClientConnectIPList; 95 96 ServerSocket *serverSocketAdmin; 97 MasterSlaveThreadController masterController; 98 99 bool gameHasBeenInitiated; 100 int gameSettingsUpdateCount; 101 102 bool allowInGameConnections; 103 bool gameLaunched; 104 time_t lastListenerSlotCheckTime; 105 106 time_t resumeGameStartTime; 107 108 Mutex *gameStatsThreadAccessor; 109 Stats *gameStats; 110 111 bool clientsAutoPausedDueToLag; 112 Chrono clientsAutoPausedDueToLagTimer; 113 Chrono lastBroadcastCommandsTimer; 114 ClientLagCallbackInterface *clientLagCallbackInterface; 115 116 public: 117 ServerInterface(bool publishEnabled, ClientLagCallbackInterface *clientLagCallbackInterface); 118 virtual ~ServerInterface(); 119 120 bool getClientsAutoPausedDueToLag(); 121 void setClientLagCallbackInterface(ClientLagCallbackInterface *intf); 122 void setGameStats(Stats *gameStats); 123 124 virtual Socket* getSocket(bool mutexLock=true) {return &serverSocket;} 125 virtual std::string getIpAddress(bool mutexLock=true); 126 getGameStartTime()127 time_t getGameStartTime() const { return gameStartTime; } 128 getAllowInGameConnections()129 virtual bool getAllowInGameConnections() const { return allowInGameConnections; } setAllowInGameConnections(bool value)130 void setAllowInGameConnections(bool value) { allowInGameConnections = value; } 131 132 bool getStartInGameConnectionLaunch(); 133 bool getPauseForInGameConnection(); 134 bool getUnPauseForInGameConnection(); 135 136 void shutdownFTPServer(); 137 138 virtual void close(); 139 virtual void update(); updateLobby()140 virtual void updateLobby() { }; 141 virtual void updateKeyframe(int frameCount); setKeyframe(int frameCount)142 virtual void setKeyframe(int frameCount) { currentFrameCount = frameCount; } 143 144 virtual void waitUntilReady(Checksum *checksum); 145 virtual void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage); 146 void sendTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage, int lockedSlotIndex); 147 148 void queueTextMessage(const string & text, int teamIndex, bool echoLocal, string targetLanguage); 149 150 virtual void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note,int playerIndex); 151 void sendMarkCellMessage(Vec2i targetPos, int factionIndex, string note, int playerIndex, int lockedSlotIndex); 152 153 virtual void sendHighlightCellMessage(Vec2i targetPos, int factionIndex); 154 void sendHighlightCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex); 155 156 virtual void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex); 157 void sendUnMarkCellMessage(Vec2i targetPos, int factionIndex, int lockedSlotIndex); 158 159 virtual void quitGame(bool userManuallyQuit); 160 virtual string getNetworkStatus(); getServerSocket()161 ServerSocket *getServerSocket() { 162 return &serverSocket; 163 } 164 165 SwitchSetupRequest **getSwitchSetupRequests(); 166 SwitchSetupRequest *getSwitchSetupRequests(int index); 167 void setSwitchSetupRequests(int index,SwitchSetupRequest *ptr); getSwitchSetupRequestsMutex()168 Mutex * getSwitchSetupRequestsMutex() { return switchSetupRequestsSynchAccessor; } 169 170 void addSlot(int playerIndex); 171 bool switchSlot(int fromPlayerIndex, int toPlayerIndex); 172 void removeSlot(int playerIndex, int lockedSlotIndex = -1); 173 virtual ConnectionSlot *getSlot(int playerIndex, bool lockMutex); 174 virtual Mutex *getSlotMutex(int playerIndex); 175 int getSlotCount(); 176 int getConnectedSlotCount(bool authenticated); 177 178 int getOpenSlotCount(); 179 bool launchGame(const GameSettings *gameSettings); 180 void validateGameSettings(GameSettings *serverGameSettings); 181 void setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck); 182 void broadcastGameSetup(GameSettings *gameSettingsBuffer, bool setGameSettingsBuffer=false); 183 184 int getGameSettingsUpdateCount(); 185 getMasterserverAdminRequestLaunch()186 bool getMasterserverAdminRequestLaunch() const { return masterserverAdminRequestLaunch; } setMasterserverAdminRequestLaunch(bool value)187 void setMasterserverAdminRequestLaunch(bool value) { masterserverAdminRequestLaunch = value; } 188 189 void updateListen(); getConnectHasHandshaked()190 virtual bool getConnectHasHandshaked() const { 191 return false; 192 } 193 slotUpdateTask(ConnectionSlotEvent * event)194 virtual void slotUpdateTask(ConnectionSlotEvent *event) { }; 195 bool hasClientConnection(); 196 virtual bool isClientConnected(int index); 197 getCurrentFrameCount()198 int getCurrentFrameCount() const { 199 return currentFrameCount; 200 } 201 202 std::pair<bool,bool> clientLagCheck(ConnectionSlot *connectionSlot, bool skipNetworkBroadCast = false); 203 bool signalClientReceiveCommands(ConnectionSlot *connectionSlot, int slotIndex, bool socketTriggered, ConnectionSlotEvent & event); 204 void updateSocketTriggeredList(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList); isPortBound()205 bool isPortBound() const { 206 return serverSocket.isPortBound(); 207 } 208 getBindPort()209 int getBindPort() const { 210 return serverSocket.getBindPort(); 211 } 212 213 void broadcastPing(NetworkMessagePing *networkMessage, int excludeSlot = -1) { 214 this->broadcastMessage(networkMessage, excludeSlot); 215 } 216 217 void queueBroadcastMessage(NetworkMessage *networkMessage, int excludeSlot = -1); 218 virtual string getHumanPlayerName(int index = -1); 219 virtual int getHumanPlayerIndex() const; getNeedToRepublishToMasterserver()220 bool getNeedToRepublishToMasterserver() const { 221 return needToRepublishToMasterserver; 222 } 223 setNeedToRepublishToMasterserver(bool value)224 void setNeedToRepublishToMasterserver(bool value) { 225 needToRepublishToMasterserver = value; 226 } 227 228 void setPublishEnabled(bool value); 229 getGameHasBeenInitiated()230 bool getGameHasBeenInitiated() const { 231 return gameHasBeenInitiated; 232 } 233 234 public: getServerSynchAccessor()235 Mutex *getServerSynchAccessor() { 236 return serverSynchAccessor; 237 } 238 239 virtual void simpleTask(BaseThread *callingThread,void *userdata); 240 void addClientToServerIPAddress(uint32 clientIp, uint32 ServerIp); 241 virtual int isValidClientType(uint32 clientIp); 242 virtual int isClientAllowedToGetFile(uint32 clientIp, const char *username, const char *filename); 243 244 void notifyBadClientConnectAttempt(string ipAddress); 245 std::string DumpStatsToLog(bool dumpToStringOnly) const; 246 247 virtual void saveGame(XmlNode *rootNode); 248 249 void broadcastMessage(NetworkMessage *networkMessage, int excludeSlot = -1, int lockedSlotIndex = -1); 250 251 ConnectionSlot * findSlotForUUID(string uuid, bool unConnectedOnly=true); 252 253 private: 254 255 void broadcastMessageToConnectedClients(NetworkMessage *networkMessage, int excludeSlot = -1); 256 bool shouldDiscardNetworkMessage(NetworkMessageType networkMessageType, ConnectionSlot *connectionSlot); 257 void updateSlot(ConnectionSlotEvent *event); 258 void validateConnectedClients(); 259 260 std::map<string,string> publishToMasterserver(); 261 std::map<string,string> publishToMasterserverStats(); 262 263 int64 getNextEventId(); 264 void processTextMessageQueue(); 265 void processBroadCastMessageQueue(); 266 void checkListenerSlots(); 267 void checkForCompletedClientsUsingThreadManager( 268 std::map<int, bool>& mapSlotSignalledList, 269 std::vector<string>& errorMsgList); 270 void checkForCompletedClientsUsingLoop( 271 std::map<int, bool>& mapSlotSignalledList, 272 std::vector<string>& errorMsgList, 273 std::map<int, ConnectionSlotEvent>& eventList); 274 void checkForAutoPauseForLaggingClient(int index, 275 ConnectionSlot* connectionSlot); 276 void checkForAutoResumeForLaggingClients(); 277 278 protected: 279 void signalClientsToRecieveData(std::map<PLATFORM_SOCKET,bool> & socketTriggeredList, std::map<int,ConnectionSlotEvent> & eventList, std::map<int,bool> & mapSlotSignalledList); 280 void checkForCompletedClients(std::map<int,bool> & mapSlotSignalledList,std::vector <string> &errorMsgList,std::map<int,ConnectionSlotEvent> &eventList); 281 void checkForLaggingClients(std::map<int,bool> &mapSlotSignalledList, std::map<int,ConnectionSlotEvent> &eventList, std::map<PLATFORM_SOCKET,bool> &socketTriggeredList,std::vector <string> &errorMsgList); 282 void executeNetworkCommandsFromClients(); 283 void dispatchPendingChatMessages(std::vector <string> &errorMsgList); 284 void dispatchPendingMarkCellMessages(std::vector <string> &errorMsgList); 285 void dispatchPendingUnMarkCellMessages(std::vector <string> &errorMsgList); 286 void dispatchPendingHighlightCellMessages(std::vector <string> &errorMsgList); 287 288 void shutdownMasterserverPublishThread(); 289 290 291 }; 292 293 }}//end namespace 294 295 #endif 296