Ticket #3556: t3556_dedicated_server_WIP_v0.2.patch
File t3556_dedicated_server_WIP_v0.2.patch, 23.1 KB (added by , 8 years ago) |
---|
-
binaries/system/readme.txt
Basic gameplay: 4 4 -autostart=... load a map instead of showing main menu (see below) 5 5 -editor launch the Atlas scenario editor 6 6 -mod=NAME start the game using NAME mod 7 7 -quickstart load faster (disables audio and some system info logging) 8 8 9 Dedicated Server: 10 -dedicated-host starts a dedicated multiplayer server (without graphics) 11 please specify the mods, for example -mod="public" 12 -dedicated-lobby advertize the game of the dedicated host in the lobby 13 9 14 Autostart: 10 15 -autostart="TYPEDIR/MAPNAME" enables autostart and sets MAPNAME; TYPEDIR is skirmishes, scenarios, or random 11 16 -autostart-ai=PLAYER:AI sets the AI for PLAYER (e.g. 2:petra) 12 17 -autostart-aidiff=PLAYER:DIFF sets the DIFFiculty of PLAYER's AI (0: sandbox, 5: very hard) 13 18 -autostart-civ=PLAYER:CIV sets PLAYER's civilisation to CIV (skirmish and random maps only) -
source/main.cpp
static void RunGameOrAtlas(int argc, con 527 527 { 528 528 flags &= ~INIT_MODS; 529 529 Shutdown(SHUTDOWN_FROM_CONFIG); 530 530 continue; 531 531 } 532 533 if (args.Has("dedicated-host")) 534 { 535 (new CDedicatedServer())->StartHosting(); 536 while (true) 537 SDL_Delay(100); // TODO: optimize this value 538 continue; 539 } 540 532 541 InitGraphics(args, 0); 542 533 543 MainControllerInit(); 534 544 while (!quit) 535 545 Frame(); 536 546 Shutdown(0); 537 547 MainControllerShutdown(); -
source/network/DedicatedServer.cpp
1 /* Copyright (C) 2015 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. 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 * 0 A.D. 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 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 // TODO: use lobby 19 // TODO: manage SERVER_STATE 20 // TODO: we should let the clients chose their civs and team numbers (but nothing else) via the regular GUI elements 21 // TODO: use ReplayLogger 22 // TODO: end the game when somebody won or everybody left 23 // TODO: start a new game after one finished 24 25 // TODO: #include "precompiled.h" ?? 26 //#include "DedicatedServer.h" 27 #include "NetServer.h" 28 29 #include "ps/CLogger.h" 30 31 CDedicatedServer::CDedicatedServer() 32 { 33 } 34 35 CDedicatedServer::~CDedicatedServer() 36 { 37 } 38 39 void CDedicatedServer::StartHosting() 40 { 41 LOGERROR("[HOST] Starting dedicated host"); 42 43 g_NetServer = new CNetServer(true); 44 45 if (!g_NetServer->m_Worker->SetupConnection()) 46 { 47 LOGERROR("ERROR: Could not start the server!"); 48 delete g_NetServer; 49 } 50 } 51 52 void CDedicatedServer::Initialize() 53 { 54 LOGERROR("[HOST] Initializing dedicated servers"); 55 56 m_Worker = g_NetServer->m_Worker; 57 m_ScriptInterface = g_NetServer->m_Worker->m_ScriptInterface; 58 59 CStrW serverName(L"Autohost"); 60 //if (g_args.Has("dedicated-host-name")) 61 // serverName = wstring_from_utf8(g_args.Get("dedicated-host-name")); 62 JSContext* cx = m_ScriptInterface->GetContext(); 63 JSAutoRequest rq(cx); 64 65 // Needs to be kept in sync with gamesetup.js 66 // TODO: load from a JSON file 67 JS::RootedValue attribs(cx); 68 JS::RootedValue settings(cx); 69 JS::RootedValue playerAssignments(cx); 70 JS::RootedValue PlayerData(cx); 71 JS::RootedValue VictoryScripts(cx); 72 73 m_ScriptInterface->Eval("({})", &attribs); 74 m_ScriptInterface->Eval("({})", &settings); 75 m_ScriptInterface->Eval("({})", &playerAssignments); 76 m_ScriptInterface->Eval("([])", &PlayerData); 77 m_ScriptInterface->Eval("([\"scripts/TriggerHelper.js\",\"scripts/ConquestCommon.js\",\"scripts/Conquest.js\"])", &VictoryScripts); 78 79 m_ScriptInterface->SetProperty(settings, "AISeed", rand()); 80 m_ScriptInterface->SetProperty(settings, "Seed", rand()); 81 m_ScriptInterface->SetProperty(settings, "Ceasefire", 0); 82 m_ScriptInterface->SetProperty(settings, "CheatsEnabled", false); 83 m_ScriptInterface->SetProperty(settings, "GameType", std::wstring(L"conquest")); 84 m_ScriptInterface->SetProperty(settings, "PlayerData", PlayerData); 85 m_ScriptInterface->SetProperty(settings, "PopulationCap", 300); 86 m_ScriptInterface->SetProperty(settings, "Size", 320); // map size 4 87 m_ScriptInterface->SetProperty(settings, "StartingResources", 500); // medium res for nomad 88 m_ScriptInterface->SetProperty(settings, "VictoryScripts", VictoryScripts); 89 // disable treasure, no revealed map, no explored map 90 // "timestamp": "1446043600", 91 // "engine_version": "0.0.19", 92 // "mods": ["mod","public"] 93 //"Preview": "acropolis_bay.png", 94 //CircularMap 95 //Description 96 m_ScriptInterface->SetProperty(attribs, "gameSpeed", 1); 97 m_ScriptInterface->SetProperty(attribs, "isNetworked", true); 98 m_ScriptInterface->SetProperty(attribs, "map", std::wstring(L"random")); 99 m_ScriptInterface->SetProperty(attribs, "mapFilter", std::wstring(L"default")); 100 m_ScriptInterface->SetProperty(attribs, "mapPath", std::wstring(L"maps/random/")); 101 m_ScriptInterface->SetProperty(attribs, "mapType", std::wstring(L"random")); 102 m_ScriptInterface->SetProperty(attribs, "matchID", ps_generate_guid().FromUTF8()); 103 m_ScriptInterface->SetProperty(attribs, "playerAssignments", playerAssignments); 104 m_ScriptInterface->SetProperty(attribs, "serverName", serverName); 105 m_ScriptInterface->SetProperty(attribs, "settings", settings); 106 107 m_Worker->UpdateGameAttributes(&attribs); 108 } 109 110 void CDedicatedServer::UpdatePlayerAssignments() 111 { 112 JSContext* cx = m_ScriptInterface->GetContext(); 113 JSAutoRequest rq(cx); 114 115 JS::RootedValue attribs(cx); 116 JS::RootedValue settings(cx); 117 JS::RootedValue PlayerData(cx); 118 119 attribs.set(m_Worker->m_GameAttributes.get()); 120 m_ScriptInterface->GetProperty(attribs, "settings", &settings); 121 m_ScriptInterface->Eval("([])", &PlayerData); 122 123 // Find all player IDs in active use 124 /* std::set<i32> usedIDs; 125 for (PlayerAssignmentMap::iterator it = m_Worker->.m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it) 126 if (it->second.m_Enabled && it->second.m_PlayerID != -1) 127 usedIDs.insert(it->second.m_PlayerID); 128 */ 129 // Update player data 130 for (u8 i=0; i<m_Worker->m_PlayerAssignments.size(); i++) 131 { 132 JS::RootedValue player(cx); 133 m_ScriptInterface->Eval("({})", &player); 134 //m_ScriptInterface->SetProperty(player, "Name", "Some player"); 135 m_ScriptInterface->SetProperty(player, "Team", -1); 136 m_ScriptInterface->SetProperty(player, "Civ", std::wstring(L"random")); 137 m_ScriptInterface->SetProperty(player, "AI", std::wstring(L"")); 138 m_ScriptInterface->SetProperty(player, "AiDiff", 3); 139 m_ScriptInterface->SetPropertyInt(PlayerData, i, player); 140 } 141 m_ScriptInterface->SetProperty(settings, "PlayerData", PlayerData); 142 143 // Limit pop cap according to playercount 144 std::map<int,int> popCaps = { 145 {1, 300}, // 600 pop total, 700 with wonder 146 {2, 300}, // 600 pop total, 750 with wonder 147 {3, 200}, // 600 pop total, 750 with wonder 148 {4, 200}, // 800 pop total, 1000 with wonder 149 {5, 150}, // 750 pop total, 1000 with wonder 150 {6, 150}, // 900 pop total, 1200 with wonder 151 {7, 100}, // 700 pop total, 1050 with wonder 152 {8, 100} // 800 pop total, 1200 with wonder 153 }; 154 m_ScriptInterface->SetProperty(settings, "PopulationCap", popCaps[m_Worker->m_PlayerAssignments.size()]); 155 156 // TODO: send chat that pop cap has been adopted 157 158 m_ScriptInterface->SetProperty(attribs, "settings", settings); 159 160 m_Worker->UpdateGameAttributes(&attribs); 161 162 // Sends the player assignments 163 m_Worker->ClearAllPlayerReady(); 164 } 165 166 void CDedicatedServer::OnChat(CNetServerSession* session, CChatMessage* message) 167 { 168 LOGERROR("[HOST] %s: %s", utf8_from_wstring(session->GetUserName().c_str()), utf8_from_wstring(message->m_Message)); 169 } 170 171 void CDedicatedServer::OnReady(CNetServerSession* session, CReadyMessage* message) 172 { 173 LOGERROR("[HOST] %s is %s", utf8_from_wstring(session->GetUserName().c_str()), message->m_Status ? "ready " : "not ready"); 174 // TODO if all ready: m_Worker->StartGame(); 175 } 176 177 void CDedicatedServer::OnUserJoin(CNetServerSession* session) 178 { 179 // TODO: if game has started, show "is starting to rejoin" 180 LOGERROR("[HOST] %s has joined (%s)", utf8_from_wstring(session->GetUserName()).c_str(), session->GetIPAddress().c_str()); 181 ++m_PlayerCount; 182 UpdatePlayerAssignments(); 183 } 184 185 void CDedicatedServer::OnUserLeave(CNetServerSession* session) 186 { 187 LOGERROR("[HOST] %s has left", utf8_from_wstring(session->GetUserName())); 188 --m_PlayerCount; 189 UpdatePlayerAssignments(); 190 } 191 192 void CDedicatedServer::OnUserRejoined(CNetServerSession* session) 193 { 194 LOGERROR("[HOST] %s has finished rejoining.", utf8_from_wstring(m_Worker->m_PlayerAssignments[session->GetGUID()].m_Name.c_str())); 195 } 196 197 void CDedicatedServer::OnStartGame() 198 { 199 LOGERROR("[HOST] The game has started."); 200 } -
source/network/DedicatedServer.h
1 /* Copyright (C) 2015 Wildfire Games. 2 * This file is part of 0 A.D. 3 * 4 * 0 A.D. 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 * 0 A.D. 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 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 // TODO: some ifndef define NETSERVER_H ? 19 20 #include "NetServer.h" 21 #include "NetSession.h" 22 #include "NetMessage.h" 23 24 #include "ps/GUID.h" 25 #include "scriptinterface/ScriptInterface.h" 26 27 /** 28 * Contains functions used by the dedicated server. 29 */ 30 class CDedicatedServer 31 { 32 NONCOPYABLE(CDedicatedServer); 33 34 private: 35 friend class NetServer; 36 friend class NetServerWorker; 37 38 /** 39 * Used to control the server. 40 */ 41 CNetServerWorker* m_Worker = nullptr; 42 43 /** 44 * Used to control the server. 45 */ 46 ScriptInterface* m_ScriptInterface = nullptr; 47 48 bool m_IsHosting = false; 49 50 /** 51 * Used to setup the game. 52 */ 53 u8 m_PlayerCount = 0; 54 55 public: 56 57 CDedicatedServer(); 58 ~CDedicatedServer(); 59 60 /** 61 * Create the host. Starts listening on UDP port 20595 for player connects. 62 */ 63 void StartHosting(); 64 65 /* 66 * Contains the default gamesetup atributes. Called after CNetServerWorker::Run() initializes the ScriptInterface. 67 */ 68 void Initialize(); 69 70 /** 71 * Sets the number of players to the number of connected clients, 72 * assigns unassigned players to unassigned slots, 73 * reduces the population count accordingly, 74 * resets ready states, 75 * sends the player assignments. 76 */ 77 void UpdatePlayerAssignments(); 78 79 /** 80 * Updates the player assignments. 81 */ 82 void OnUserJoin(CNetServerSession* session); 83 84 /** 85 * Updates the player assignments. 86 */ 87 void OnUserLeave(CNetServerSession* session); 88 89 /** 90 * Lets the users chose their own civs and team numbers. 91 */ 92 void OnChat(CNetServerSession* session, CChatMessage* message); 93 94 /** 95 * Starts the game if all players are ready. 96 */ 97 void OnReady(CNetServerSession* session, CReadyMessage* message); 98 99 /** 100 * Used for logging only. 101 */ 102 void OnStartGame(); 103 104 /** 105 * Used for logging only. 106 */ 107 void OnUserRejoined(CNetServerSession* session); 108 }; -
source/network/NetServer.cpp
public: 106 106 CJoinSyncStartMessage message; 107 107 session->SendMessage(&message); 108 108 } 109 109 110 110 private: 111 111 112 CNetServerWorker& m_Server; 112 113 u32 m_RejoinerHostID; 113 114 }; 114 115 115 116 /* 116 117 * XXX: We use some non-threadsafe functions from the worker thread. 117 118 * See http://trac.wildfiregames.com/ticket/654 118 119 */ 119 120 120 CNetServerWorker::CNetServerWorker(int autostartPlayers) : 121 CNetServerWorker::CNetServerWorker(bool isDedicated, int autostartPlayers) : 122 m_DedicatedServer(isDedicated ? new CDedicatedServer() : NULL), 121 123 m_AutostartPlayers(autostartPlayers), 122 124 m_Shutdown(false), 123 125 m_ScriptInterface(NULL), 124 126 m_NextHostID(1), m_Host(NULL), m_Stats(NULL) 125 127 { … … CNetServerWorker::~CNetServerWorker() 159 161 { 160 162 enet_host_destroy(m_Host); 161 163 } 162 164 163 165 delete m_ServerTurnManager; 166 delete m_DedicatedServer; 164 167 } 165 168 166 169 bool CNetServerWorker::SetupConnection() 167 170 { 168 171 ENSURE(m_State == SERVER_STATE_UNCONNECTED); … … void* CNetServerWorker::RunThread(void* 364 367 365 368 void CNetServerWorker::Run() 366 369 { 367 370 // The script runtime uses the profiler and therefore the thread must be registered before the runtime is created 368 371 g_Profiler2.RegisterCurrentThread("Net server"); 369 372 370 373 // To avoid the need for JS_SetContextThread, we create and use and destroy 371 374 // the script interface entirely within this network thread 372 375 m_ScriptInterface = new ScriptInterface("Engine", "Net server", ScriptInterface::CreateRuntime(g_ScriptRuntime)); 373 376 m_GameAttributes.set(m_ScriptInterface->GetJSRuntime(), JS::UndefinedValue()); 374 377 378 if (m_DedicatedServer) 379 m_DedicatedServer->Initialize(); 380 375 381 while (true) 376 382 { 377 383 if (!RunStep()) 378 384 break; 379 385 … … bool CNetServerWorker::HandleConnect(CNe 617 623 return session->SendMessage(&handshake); 618 624 } 619 625 620 626 void CNetServerWorker::OnUserJoin(CNetServerSession* session) 621 627 { 622 AddPlayer(session->GetGUID(), session->GetUserName()); 628 if (m_DedicatedServer) 629 m_DedicatedServer->OnUserJoin(session); 630 else 631 AddPlayer(session->GetGUID(), session->GetUserName()); 623 632 624 633 CGameSetupMessage gameSetupMessage(GetScriptInterface()); 625 634 gameSetupMessage.m_Data = m_GameAttributes.get(); 626 635 session->SendMessage(&gameSetupMessage); 627 636 … … void CNetServerWorker::OnUserJoin(CNetSe 630 639 session->SendMessage(&assignMessage); 631 640 } 632 641 633 642 void CNetServerWorker::OnUserLeave(CNetServerSession* session) 634 643 { 635 RemovePlayer(session->GetGUID()); 644 if (m_DedicatedServer) 645 m_DedicatedServer->OnUserLeave(session); 646 else 647 RemovePlayer(session->GetGUID()); 636 648 637 649 if (m_ServerTurnManager && session->GetCurrState() != NSS_JOIN_SYNCING) 638 650 m_ServerTurnManager->UninitialiseClient(session->GetHostID()); // TODO: only for non-observers 639 651 640 652 // TODO: ought to switch the player controlled by that client … … bool CNetServerWorker::OnAuthenticate(vo 858 870 // Request a copy of the current game state from an existing player, 859 871 // so we can send it on to the new player 860 872 861 873 // Assume session 0 is most likely the local player, so they're 862 874 // the most efficient client to request a copy from 875 876 // TODO: When using a dedicated server we should use the client that didn't reconnect for the longest time 863 877 CNetServerSession* sourceSession = server.m_Sessions.at(0); 864 878 sourceSession->GetFileTransferer().StartTask( 865 879 shared_ptr<CNetFileReceiveTask>(new CNetFileReceiveTask_ServerRejoin(server, newHostID)) 866 880 ); 867 881 … … bool CNetServerWorker::OnChat(void* cont 918 932 919 933 CChatMessage* message = (CChatMessage*)event->GetParamRef(); 920 934 921 935 message->m_GUID = session->GetGUID(); 922 936 937 if (server.m_DedicatedServer) 938 server.m_DedicatedServer->OnChat(session, message); 939 923 940 server.Broadcast(message); 924 941 925 942 return true; 926 943 } 927 944 … … bool CNetServerWorker::OnReady(void* con 936 953 937 954 message->m_GUID = session->GetGUID(); 938 955 939 956 server.Broadcast(message); 940 957 958 if (server.m_DedicatedServer) 959 server.m_DedicatedServer->OnReady(session, message); 960 941 961 return true; 942 962 } 943 963 944 964 bool CNetServerWorker::OnLoadedGame(void* context, CFsmEvent* event) 945 965 { … … bool CNetServerWorker::OnRejoined(void* 1017 1037 1018 1038 CRejoinedMessage* message = (CRejoinedMessage*)event->GetParamRef(); 1019 1039 1020 1040 message->m_GUID = session->GetGUID(); 1021 1041 1042 if (server.m_DedicatedServer) 1043 server.m_DedicatedServer->OnUserRejoined(session); 1044 1022 1045 server.Broadcast(message); 1023 1046 1024 1047 return true; 1025 1048 } 1026 1049 … … void CNetServerWorker::CheckGameLoadStat 1051 1074 m_State = SERVER_STATE_INGAME; 1052 1075 } 1053 1076 1054 1077 void CNetServerWorker::StartGame() 1055 1078 { 1079 if (m_DedicatedServer) 1080 m_DedicatedServer->OnStartGame(); 1081 1056 1082 m_ServerTurnManager = new CNetServerTurnManager(*this); 1057 1083 1058 1084 for (size_t i = 0; i < m_Sessions.size(); ++i) 1059 1085 m_ServerTurnManager->InitialiseClient(m_Sessions[i]->GetHostID(), 0); // TODO: only for non-observers 1060 1086 … … void CNetServerWorker::UpdateGameAttribu 1081 1107 m_GameAttributes.set(m_ScriptInterface->GetJSRuntime(), attrs); 1082 1108 1083 1109 if (!m_Host) 1084 1110 return; 1085 1111 1112 if (m_DedicatedServer) 1113 LOGMESSAGE("[HOST] The game settings have been updated."); 1114 1086 1115 CGameSetupMessage gameSetupMessage(GetScriptInterface()); 1087 1116 gameSetupMessage.m_Data.set(m_GameAttributes.get()); 1088 1117 Broadcast(&gameSetupMessage); 1089 1118 } 1090 1119 … … CStrW CNetServerWorker::DeduplicatePlaye 1136 1165 } 1137 1166 1138 1167 1139 1168 1140 1169 1141 CNetServer::CNetServer( int autostartPlayers) :1142 m_Worker(new CNetServerWorker( autostartPlayers))1170 CNetServer::CNetServer(bool isDedicated, int autostartPlayers) : 1171 m_Worker(new CNetServerWorker(isDedicated, autostartPlayers)) 1143 1172 { 1144 1173 } 1145 1174 1146 1175 CNetServer::~CNetServer() 1147 1176 { -
source/network/NetServer.h
16 16 */ 17 17 18 18 #ifndef NETSERVER_H 19 19 #define NETSERVER_H 20 20 21 #include "DedicatedServer.h" 21 22 #include "NetFileTransfer.h" 22 23 #include "NetHost.h" 23 24 24 25 #include "lib/config2.h" 25 26 #include "ps/ThreadUtil.h" … … enum NetServerSessionState 89 90 NSS_INGAME 90 91 }; 91 92 92 93 /** 93 94 * Network server interface. Handles all the coordination between players. 94 * One person runs this object, and every player (including the host) connects their CNetClient to it. 95 * The host runs this object and every player connects their CNetClient to it. 96 * If it is a dedicated server, the host will not be a player (nor observer). 95 97 * 96 * The actual work is performed by CNetServerWorker in a separate thread.98 * The actual work is performed by CNetServerWorker and CDedicatedServer in a separate thread. 97 99 */ 98 100 class CNetServer 99 101 { 100 102 NONCOPYABLE(CNetServer); 101 103 public: 102 104 /** 103 105 * Construct a new network server. 106 * 107 * @param dedicated Whether or not to use dedicated mode (i.e. no graphics and no local simulation). 108 * 104 109 * @param autostartPlayers if positive then StartGame will be called automatically 105 110 * once this many players are connected (intended for the command-line testing mode). 106 111 */ 107 CNetServer( int autostartPlayers = -1);112 CNetServer(bool dedicated = false, int autostartPlayers = -1); 108 113 109 114 ~CNetServer(); 110 115 111 116 /** 112 117 * Begin listening for network connections. … … public: 153 158 * TODO: we should replace this with some adapative lag-dependent computation. 154 159 */ 155 160 void SetTurnLength(u32 msecs); 156 161 157 162 private: 163 164 friend class CDedicatedServer; 165 158 166 CNetServerWorker* m_Worker; 159 167 }; 160 168 161 169 /** 162 170 * Network server worker thread. … … public: 187 195 * (i.e. are in the pre-game or in-game states). 188 196 */ 189 197 bool Broadcast(const CNetMessage* message); 190 198 191 199 private: 200 friend class CDedicatedServer; 192 201 friend class CNetServer; 193 202 friend class CNetFileReceiveTask_ServerRejoin; 194 203 195 CNetServerWorker( int autostartPlayers);204 CNetServerWorker(bool dedicated, int autostartPlayers); 196 205 ~CNetServerWorker(); 197 206 198 207 /** 199 208 * Begin listening for network connections. 200 209 * @return true on success, false on error (e.g. port already in use) … … private: 299 308 CStrW m_ServerName; 300 309 CStrW m_WelcomeMessage; 301 310 302 311 u32 m_NextHostID; 303 312 313 CDedicatedServer* m_DedicatedServer; 314 304 315 CNetServerTurnManager* m_ServerTurnManager; 305 316 306 317 /** 307 318 * A copy of all simulation commands received so far, indexed by 308 319 * turn number, to simplify support for rejoining etc. -
source/network/NetSession.cpp
bool CNetClientSession::Connect(u16 port 76 76 g_ProfileViewer.AddRootTable(m_Stats); 77 77 78 78 return true; 79 79 } 80 80 81 CStr CNetServerSession::GetIPAddress() 82 { 83 char ipAddress[256] = "(error)"; 84 enet_address_get_host_ip(&(m_Peer->address), ipAddress, ARRAY_SIZE(ipAddress)); 85 return CStr(ipAddress); 86 } 87 81 88 void CNetClientSession::Disconnect(u32 reason) 82 89 { 83 90 ENSURE(m_Host && m_Server); 84 91 85 92 // TODO: ought to do reliable async disconnects, probably -
source/network/NetSession.h
public: 120 120 void SetUserName(const CStrW& name) { m_UserName = name; } 121 121 122 122 u32 GetHostID() const { return m_HostID; } 123 123 void SetHostID(u32 id) { m_HostID = id; } 124 124 125 /** 126 * Returns the IP address of the client. 127 */ 128 CStr GetIPAddress(); 129 125 130 /** 126 131 * Sends a disconnection notification to the client, 127 132 * and sends a NMT_CONNECTION_LOST message to the session FSM. 128 133 * The server will receive a disconnection notification after a while. 129 134 * The server will not receive any further messages sent via this session. -
source/network/NetTurnManager.cpp
void CNetServerTurnManager::NotifyFinish 630 630 { 631 631 if (it->first > newest) 632 632 break; 633 633 634 634 // Assume the host is correct (maybe we should choose the most common instead to help debugging) 635 // TODO: for dedicated hosts, we have to chose the hash of a client that didn't rejoin for the longest period 635 636 std::string expected = it->second.begin()->second; 636 637 637 638 // Find all players that are OOS on that turn 638 639 std::vector<CStrW> OOSPlayerNames; 639 640 for (std::map<int, std::string>::iterator cit = it->second.begin(); cit != it->second.end(); ++cit) -
source/ps/GameSetup/GameSetup.cpp
bool Init(const CmdLineArgs& args, int f 933 933 } 934 934 935 935 CNetHost::Initialize(); 936 936 937 937 #if CONFIG2_AUDIO 938 ISoundManager::CreateSoundManager(); 938 if (!args.Has("dedicated-host")) 939 ISoundManager::CreateSoundManager(); 939 940 #endif 940 941 941 942 // Check if there are mods specified on the command line, 942 943 // or if we already set the mods (~INIT_MODS), 943 944 // else check if there are mods that should be loaded specified