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_CONNECTIONSLOT_H_ 13 #define _GLEST_GAME_CONNECTIONSLOT_H_ 14 15 #include "socket.h" 16 #include "network_interface.h" 17 #include "base_thread.h" 18 #include <time.h> 19 #include <vector> 20 21 #include "leak_dumper.h" 22 23 using Shared::Platform::ServerSocket; 24 using Shared::Platform::Socket; 25 using std::vector; 26 27 namespace Glest{ namespace Game{ 28 29 class ServerInterface; 30 class ConnectionSlot; 31 32 // ===================================================== 33 // class ConnectionSlotThread 34 // ===================================================== 35 36 enum ConnectionSlotEventType 37 { 38 eNone, 39 eReceiveSocketData, 40 eSendSocketData 41 }; 42 43 class ConnectionSlotEvent { 44 public: 45 ConnectionSlotEvent()46 ConnectionSlotEvent() { 47 eventType = eNone; 48 triggerId = -1; 49 connectionSlot = NULL; 50 networkMessage = NULL; 51 socketTriggered = false; 52 eventCompleted = false; 53 eventId = -1; 54 } 55 56 int64 triggerId; 57 ConnectionSlot* connectionSlot; 58 ConnectionSlotEventType eventType; 59 NetworkMessage *networkMessage; 60 bool socketTriggered; 61 bool eventCompleted; 62 int64 eventId; 63 }; 64 65 // 66 // This interface describes the methods a callback object must implement 67 // 68 class ConnectionSlotCallbackInterface { 69 public: 70 virtual bool isClientConnected(int index) = 0; 71 virtual bool getAllowInGameConnections() const = 0; 72 virtual ConnectionSlot *getSlot(int index, bool lockMutex) = 0; 73 virtual Mutex *getSlotMutex(int index) = 0; 74 75 virtual void slotUpdateTask(ConnectionSlotEvent *event) = 0; ~ConnectionSlotCallbackInterface()76 virtual ~ConnectionSlotCallbackInterface() {} 77 }; 78 79 class ConnectionSlotThread : public BaseThread, public SlaveThreadControllerInterface 80 { 81 protected: 82 83 ConnectionSlotCallbackInterface *slotInterface; 84 Semaphore semTaskSignalled; 85 Mutex *triggerIdMutex; 86 vector<ConnectionSlotEvent> eventList; 87 int slotIndex; 88 MasterSlaveThreadController *masterController; 89 90 Mutex *triggerGameStarted; 91 bool gameStarted; 92 93 virtual void setQuitStatus(bool value); 94 virtual void setTaskCompleted(int eventId); 95 96 void slotUpdateTask(ConnectionSlotEvent *event); 97 98 public: 99 ConnectionSlotThread(int slotIndex); 100 ConnectionSlotThread(ConnectionSlotCallbackInterface *slotInterface,int slotIndex); 101 virtual ~ConnectionSlotThread(); 102 103 bool getGameStarted(); 104 void setGameStarted(bool value); 105 setMasterController(MasterSlaveThreadController * master)106 virtual void setMasterController(MasterSlaveThreadController *master) { masterController = master; } 107 virtual void signalSlave(void *userdata); 108 109 virtual void execute(); 110 void signalUpdate(ConnectionSlotEvent *event); 111 bool isSignalCompleted(ConnectionSlotEvent *event); 112 getSlotIndex()113 int getSlotIndex() const {return slotIndex; } setSlotIndex(int index)114 void setSlotIndex(int index) { this->slotIndex = index; } 115 116 void purgeCompletedEvents(); 117 void purgeAllEvents(); 118 void setAllEventsCompleted(); 119 120 virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false); 121 }; 122 123 // ===================================================== 124 // class ConnectionSlot 125 // ===================================================== 126 127 class ConnectionSlot: public NetworkInterface { 128 private: 129 ServerInterface* serverInterface; 130 131 Mutex *mutexSocket; 132 Socket* socket; 133 int playerIndex; 134 string name; 135 bool ready; 136 vector<std::pair<string,uint32> > vctFileList; 137 bool receivedNetworkGameStatus; 138 time_t connectedTime; 139 bool gotIntro; 140 141 Mutex *mutexCloseConnection; 142 143 Mutex *mutexPendingNetworkCommandList; 144 vector<NetworkCommand> vctPendingNetworkCommandList; 145 ConnectionSlotThread* slotThreadWorker; 146 int currentFrameCount; 147 int currentLagCount; 148 time_t lastReceiveCommandListTime; 149 bool gotLagCountWarning; 150 string versionString; 151 int sessionKey; 152 uint32 connectedRemoteIPAddress; 153 int playerStatus; 154 string playerLanguage; 155 string playerUUID; 156 string platform; 157 158 bool skipLagCheck; 159 bool joinGameInProgress; 160 bool canAcceptConnections; 161 bool startInGameConnectionLaunch; 162 bool pauseForInGameConnection; 163 bool unPauseForInGameConnection; 164 bool sentSavedGameInfo; 165 166 int autoPauseGameCountForLag; 167 168 public: 169 ConnectionSlot(ServerInterface* serverInterface, int playerIndex); 170 ~ConnectionSlot(); 171 172 int getAutoPauseGameCountForLag(); 173 void incrementAutoPauseGameCountForLag(); 174 175 bool getGameStarted(); 176 void setGameStarted(bool value); 177 getStartInGameConnectionLaunch()178 bool getStartInGameConnectionLaunch() const { return startInGameConnectionLaunch; } setStartInGameConnectionLaunch(bool value)179 void setStartInGameConnectionLaunch(bool value) { startInGameConnectionLaunch = value; } 180 getPauseForInGameConnection()181 bool getPauseForInGameConnection() const { return pauseForInGameConnection; } setPauseForInGameConnection(bool value)182 void setPauseForInGameConnection(bool value) { pauseForInGameConnection = value; } 183 getUnPauseForInGameConnection()184 bool getUnPauseForInGameConnection() const { return unPauseForInGameConnection; } setUnPauseForInGameConnection(bool value)185 void setUnPauseForInGameConnection(bool value) { unPauseForInGameConnection = value; } 186 getSkipLagCheck()187 bool getSkipLagCheck() const { return skipLagCheck; } getJoinGameInProgress()188 bool getJoinGameInProgress() const { return joinGameInProgress; } 189 getSentSavedGameInfo()190 bool getSentSavedGameInfo() const { return sentSavedGameInfo; } setSentSavedGameInfo(bool value)191 void setSentSavedGameInfo(bool value) { sentSavedGameInfo = value; } 192 getWorkerThread()193 ConnectionSlotThread *getWorkerThread() { return slotThreadWorker; } 194 195 void update(bool checkForNewClients,int lockedSlotIndex); 196 void setPlayerIndex(int value); getPlayerIndex()197 int getPlayerIndex() const {return playerIndex;} 198 getConnectedRemoteIPAddress()199 uint32 getConnectedRemoteIPAddress() const { return connectedRemoteIPAddress; } 200 201 void setReady(); getName()202 const string &getName() const {return name;} getUUID()203 const string &getUUID() const {return playerUUID;} getPlatform()204 const string &getPlatform() const { return platform; } setName(string value)205 void setName(string value) {name = value;} isReady()206 bool isReady() const {return ready;} 207 208 virtual std::string getIpAddress(bool mutexLock=true); 209 210 virtual Socket* getSocket(bool mutexLock=true); 211 pair<bool,Socket*> getSocketInfo(); 212 213 virtual void close(); 214 //virtual bool getFogOfWar(); 215 getReceivedNetworkGameStatus()216 bool getReceivedNetworkGameStatus() const { return receivedNetworkGameStatus; } setReceivedNetworkGameStatus(bool value)217 void setReceivedNetworkGameStatus(bool value) { receivedNetworkGameStatus = value; } 218 219 bool hasValidSocketId(); getConnectHasHandshaked()220 virtual bool getConnectHasHandshaked() const { return gotIntro; } getThreadErrorList()221 std::vector<std::string> getThreadErrorList() const { return threadErrorList; } clearThreadErrorList()222 void clearThreadErrorList() { threadErrorList.clear(); } 223 224 vector<NetworkCommand> getPendingNetworkCommandList(bool clearList=false); 225 void clearPendingNetworkCommandList(); 226 227 void signalUpdate(ConnectionSlotEvent *event); 228 bool updateCompleted(ConnectionSlotEvent *event); 229 230 virtual void sendMessage(NetworkMessage* networkMessage); getCurrentFrameCount()231 int getCurrentFrameCount() const { return currentFrameCount; } 232 getCurrentLagCount()233 int getCurrentLagCount() const { return currentLagCount; } setCurrentLagCount(int value)234 void setCurrentLagCount(int value) { currentLagCount = value; } 235 getLastReceiveCommandListTime()236 time_t getLastReceiveCommandListTime() const { return lastReceiveCommandListTime; } 237 getLagCountWarning()238 bool getLagCountWarning() const { return gotLagCountWarning; } setLagCountWarning(bool value)239 void setLagCountWarning(bool value) { gotLagCountWarning = value; } 240 getVersionString()241 const string &getVersionString() const {return versionString;} 242 243 void validateConnection(); 244 virtual string getHumanPlayerName(int index=-1); getHumanPlayerIndex()245 virtual int getHumanPlayerIndex() const {return playerIndex;} 246 getNetworkPlayerStatus()247 int getNetworkPlayerStatus() const { return playerStatus;} 248 getNetworkPlayerLanguage()249 string getNetworkPlayerLanguage() const { return playerLanguage; } 250 getConnectedTime()251 time_t getConnectedTime() const { return connectedTime; } getSessionKey()252 int getSessionKey() const { return sessionKey; } 253 254 void updateSlot(ConnectionSlotEvent *event); 255 virtual bool isConnected(); 256 257 PLATFORM_SOCKET getSocketId(); 258 setCanAcceptConnections(bool value)259 void setCanAcceptConnections(bool value) { canAcceptConnections = value; } getCanAcceptConnections()260 bool getCanAcceptConnections() const { return canAcceptConnections; } 261 saveGame(XmlNode * rootNode)262 virtual void saveGame(XmlNode *rootNode) {}; 263 264 void resetJoinGameInProgressFlags(); 265 void setJoinGameInProgressFlags(); 266 267 protected: 268 269 Mutex * getServerSynchAccessor(); 270 std::vector<std::string> threadErrorList; 271 Mutex *socketSynchAccessor; 272 273 void setSocket(Socket *newSocket); 274 void deleteSocket(); update()275 virtual void update() {} 276 277 bool hasDataToRead(); 278 }; 279 280 }}//end namespace 281 282 #endif 283