1 /* 2 * This file is part of Dune Legacy. 3 * 4 * Dune Legacy is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * Dune Legacy is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with Dune Legacy. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef NETWORKMANAGER_H 19 #define NETWORKMANAGER_H 20 21 #include <Network/ENetPacketIStream.h> 22 #include <Network/ENetPacketOStream.h> 23 #include <Network/ChangeEventList.h> 24 #include <Network/CommandList.h> 25 26 #include <Network/LANGameFinderAndAnnouncer.h> 27 #include <Network/MetaServerClient.h> 28 29 #include <misc/string_util.h> 30 31 #include <enet/enet.h> 32 #include <SDL.h> 33 #include <string> 34 #include <list> 35 #include <functional> 36 #include <stdarg.h> 37 38 #define NETWORKDISCONNECT_QUIT 1 39 #define NETWORKDISCONNECT_TIMEOUT 2 40 #define NETWORKDISCONNECT_PLAYER_EXISTS 3 41 #define NETWORKDISCONNECT_GAME_FULL 4 42 43 #define NETWORKPACKET_UNKNOWN 0 44 #define NETWORKPACKET_CONNECT 1 45 #define NETWORKPACKET_DISCONNECT 2 46 #define NETWORKPACKET_PEER_CONNECTED 3 47 #define NETWORKPACKET_SENDGAMEINFO 4 48 #define NETWORKPACKET_SENDNAME 5 49 #define NETWORKPACKET_CHATMESSAGE 6 50 #define NETWORKPACKET_CHANGEEVENTLIST 7 51 #define NETWORKPACKET_STARTGAME 8 52 #define NETWORKPACKET_COMMANDLIST 9 53 #define NETWORKPACKET_SELECTIONLIST 10 54 55 #define AWAITING_CONNECTION_TIMEOUT 5000 56 57 class GameInitSettings; 58 59 class NetworkManager { 60 public: 61 NetworkManager(int port, const std::string& metaserver); 62 NetworkManager(const NetworkManager& o) = delete; 63 ~NetworkManager(); 64 isServer()65 bool isServer() const { return bIsServer; }; 66 67 void startServer(bool bLANServer, const std::string& serverName, const std::string& playerName, GameInitSettings* pGameInitSettings, int numPlayers, int maxPlayers); 68 void updateServer(int numPlayers); 69 void stopServer(); 70 71 void connect(const std::string& hostname, int port, const std::string& playerName); 72 void connect(ENetAddress address, const std::string& playerName); 73 74 void disconnect(); 75 76 void update(); 77 78 void sendChatMessage(const std::string& message); 79 80 void sendChangeEventList(const ChangeEventList& changeEventList); 81 82 void sendStartGame(unsigned int timeLeft); 83 84 void sendCommandList(const CommandList& commandList); 85 86 void sendSelectedList(const std::set<Uint32>& selectedList, int groupListIndex = -1); 87 getConnectedPeers()88 std::list<std::string> getConnectedPeers() const { 89 std::list<std::string> peerNameList; 90 91 for(const ENetPeer* pPeer : peerList) { 92 PeerData* peerData = static_cast<PeerData*>(pPeer->data); 93 if(peerData != nullptr) { 94 peerNameList.push_back(peerData->name); 95 } 96 } 97 98 return peerNameList; 99 } 100 101 int getMaxPeerRoundTripTime(); 102 getLANGameFinderAndAnnouncer()103 LANGameFinderAndAnnouncer* getLANGameFinderAndAnnouncer() { 104 return pLANGameFinderAndAnnouncer; 105 }; 106 getMetaServerClient()107 MetaServerClient* getMetaServerClient() { 108 return pMetaServerClient; 109 }; 110 111 /** 112 Sets the function that should be called when a chat message is received 113 \param pOnReceiveChatMessage function to call on new chat message 114 */ setOnReceiveChatMessage(std::function<void (const std::string &,const std::string &)> pOnReceiveChatMessage)115 inline void setOnReceiveChatMessage(std::function<void (const std::string&, const std::string&)> pOnReceiveChatMessage) { 116 this->pOnReceiveChatMessage = pOnReceiveChatMessage; 117 } 118 119 /** 120 Sets the function that should be called when game infos are received after connecting to the server. 121 \param pOnReceiveGameInfo function to call on receive 122 */ setOnReceiveGameInfo(std::function<void (const GameInitSettings &,const ChangeEventList &)> pOnReceiveGameInfo)123 inline void setOnReceiveGameInfo(std::function<void (const GameInitSettings&, const ChangeEventList&)> pOnReceiveGameInfo) { 124 this->pOnReceiveGameInfo = pOnReceiveGameInfo; 125 } 126 127 128 /** 129 Sets the function that should be called when a change event is received. 130 \param pOnReceiveChangeEventList function to call on receive 131 */ setOnReceiveChangeEventList(std::function<void (const ChangeEventList &)> pOnReceiveChangeEventList)132 inline void setOnReceiveChangeEventList(std::function<void (const ChangeEventList&)> pOnReceiveChangeEventList) { 133 this->pOnReceiveChangeEventList = pOnReceiveChangeEventList; 134 } 135 136 137 /** 138 Sets the function that should be called when a peer disconnects. 139 \param pOnPeerDisconnected function to call on disconnect 140 */ setOnPeerDisconnected(std::function<void (const std::string &,bool,int)> pOnPeerDisconnected)141 inline void setOnPeerDisconnected(std::function<void (const std::string&, bool, int)> pOnPeerDisconnected) { 142 this->pOnPeerDisconnected = pOnPeerDisconnected; 143 } 144 145 /** 146 Sets the function that can be used to retreive all house/player changes to get the current state 147 \param pGetGameInitSettingsCallback function to call 148 */ setGetChangeEventListForNewPlayerCallback(std::function<ChangeEventList (const std::string &)> pGetChangeEventListForNewPlayerCallback)149 inline void setGetChangeEventListForNewPlayerCallback(std::function<ChangeEventList (const std::string&)> pGetChangeEventListForNewPlayerCallback) { 150 this->pGetChangeEventListForNewPlayerCallback = pGetChangeEventListForNewPlayerCallback; 151 } 152 153 /** 154 Sets the function that should be called when the game is about to start and the time (in ms) left is received 155 \param pOnStartGame function to call on receive 156 */ setOnStartGame(std::function<void (unsigned int)> pOnStartGame)157 inline void setOnStartGame(std::function<void (unsigned int)> pOnStartGame) { 158 this->pOnStartGame = pOnStartGame; 159 } 160 161 /** 162 Sets the function that should be called when a command list is received. 163 \param pOnReceiveCommandList function to call on receive 164 */ setOnReceiveCommandList(std::function<void (const std::string &,const CommandList &)> pOnReceiveCommandList)165 inline void setOnReceiveCommandList(std::function<void (const std::string&, const CommandList&)> pOnReceiveCommandList) { 166 this->pOnReceiveCommandList = pOnReceiveCommandList; 167 } 168 169 /** 170 Sets the function that should be called when a selection list is received. 171 \param pOnReceiveSelectionList function to call on receive 172 */ setOnReceiveSelectionList(std::function<void (const std::string &,const std::set<Uint32> &,int)> pOnReceiveSelectionList)173 inline void setOnReceiveSelectionList(std::function<void (const std::string&, const std::set<Uint32>&, int)> pOnReceiveSelectionList) { 174 this->pOnReceiveSelectionList = pOnReceiveSelectionList; 175 } 176 177 private: 178 static void debugNetwork(PRINTF_FORMAT_STRING const char* fmt, ...) PRINTF_VARARG_FUNC(1); 179 180 void sendPacketToHost(ENetPacketOStream& packetStream, int channel = 0); 181 182 void sendPacketToPeer(ENetPeer* peer, ENetPacketOStream& packetStream, int channel = 0); 183 184 void sendPacketToAllConnectedPeers(ENetPacketOStream& packetStream, int channel = 0); 185 186 void handlePacket(ENetPeer* peer, ENetPacketIStream& packetStream); 187 188 class PeerData { 189 public: 190 enum class PeerState { 191 WaitingForConnect, 192 WaitingForName, 193 ReadyForOtherPeersToConnect, 194 WaitingForOtherPeersToConnect, 195 Connected 196 }; 197 198 PeerData(ENetPeer * pPeer,PeerState peerState)199 PeerData(ENetPeer* pPeer, PeerState peerState) 200 : pPeer(pPeer), peerState(peerState), timeout(0) { 201 } 202 203 204 ENetPeer* pPeer; 205 206 PeerState peerState; 207 Uint32 timeout; 208 209 std::string name; 210 std::list<ENetPeer*> notYetConnectedPeers; 211 }; 212 213 ENetHost* host = nullptr; 214 bool bIsServer = false; 215 bool bLANServer = false; 216 GameInitSettings* pGameInitSettings = nullptr; 217 int numPlayers = 0; 218 int maxPlayers = 0; 219 220 std::string playerName; 221 222 ENetPeer* connectPeer = nullptr; 223 224 std::list<ENetPeer*> peerList; 225 226 std::list<ENetPeer*> awaitingConnectionList; 227 228 std::function<void (const std::string&, const std::string&)> pOnReceiveChatMessage; 229 std::function<void (const GameInitSettings&, const ChangeEventList&)> pOnReceiveGameInfo; 230 std::function<void (const ChangeEventList&)> pOnReceiveChangeEventList; 231 std::function<void (const std::string&, bool, int)> pOnPeerDisconnected; 232 std::function<ChangeEventList (const std::string&)> pGetChangeEventListForNewPlayerCallback; 233 std::function<void (unsigned int)> pOnStartGame; 234 std::function<void (const std::string&, const CommandList&)> pOnReceiveCommandList; 235 std::function<void (const std::string&, const std::set<Uint32>&, int)> pOnReceiveSelectionList; 236 237 LANGameFinderAndAnnouncer* pLANGameFinderAndAnnouncer = nullptr; 238 MetaServerClient* pMetaServerClient = nullptr; 239 }; 240 241 #endif // NETWORKMANAGER_H 242