Ticket #3953: disable_timeouts_differently_v2.patch
File disable_timeouts_differently_v2.patch, 16.9 KB (added by , 8 years ago) |
---|
-
source/gui/scripting/ScriptFunctions.cpp
void StartNetworkHost(ScriptInterface::C 357 357 SAFE_DELETE(g_NetServer); 358 358 return; 359 359 } 360 360 361 361 g_Game = new CGame(); 362 g_NetClient = new CNetClient(g_Game );362 g_NetClient = new CNetClient(g_Game, true); 363 363 g_NetClient->SetUserName(playerName); 364 364 365 365 if (!g_NetClient->SetupConnection("127.0.0.1")) 366 366 { 367 367 pCxPrivate->pScriptInterface->ReportError("Failed to connect to server"); … … void StartNetworkJoin(ScriptInterface::C 375 375 ENSURE(!g_NetClient); 376 376 ENSURE(!g_NetServer); 377 377 ENSURE(!g_Game); 378 378 379 379 g_Game = new CGame(); 380 g_NetClient = new CNetClient(g_Game );380 g_NetClient = new CNetClient(g_Game, false); 381 381 g_NetClient->SetUserName(playerName); 382 382 if (!g_NetClient->SetupConnection(serverAddress)) 383 383 { 384 384 pCxPrivate->pScriptInterface->ReportError("Failed to connect to server"); 385 385 SAFE_DELETE(g_NetClient); -
source/network/NetClient.cpp
public: 64 64 65 65 private: 66 66 CNetClient& m_Client; 67 67 }; 68 68 69 CNetClient::CNetClient(CGame* game ) :69 CNetClient::CNetClient(CGame* game, bool isLocalClient) : 70 70 m_Session(NULL), 71 71 m_UserName(L"anonymous"), 72 72 m_GUID(ps_generate_guid()), m_HostID((u32)-1), m_ClientTurnManager(NULL), m_Game(game), 73 73 m_GameAttributes(game->GetSimulation2()->GetScriptInterface().GetContext()), 74 m_IsLocalClient(isLocalClient), 74 75 m_LastConnectionCheck(0) 75 76 { 76 77 m_Game->SetTurnManager(NULL); // delete the old local turn manager so we don't accidentally use it 77 78 78 79 void* context = this; … … void CNetClient::SetUserName(const CStrW 152 153 } 153 154 154 155 bool CNetClient::SetupConnection(const CStr& server) 155 156 { 156 157 CNetClientSession* session = new CNetClientSession(*this); 157 bool ok = session->Connect(PS_DEFAULT_PORT, server );158 bool ok = session->Connect(PS_DEFAULT_PORT, server, m_IsLocalClient); 158 159 SetAndOwnSession(session); 159 160 return ok; 160 161 } 161 162 162 163 void CNetClient::SetAndOwnSession(CNetClientSession* session) … … bool CNetClient::OnHandshakeResponse(voi 465 466 466 467 CAuthenticateMessage authenticate; 467 468 authenticate.m_GUID = client->m_GUID; 468 469 authenticate.m_Name = client->m_UserName; 469 470 authenticate.m_Password = L""; // TODO 471 authenticate.m_IsLocalClient = client->m_IsLocalClient; 470 472 client->SendMessage(&authenticate); 471 473 472 474 return true; 473 475 } 474 476 -
source/network/NetClient.h
class CNetClient : public CFsm 63 63 public: 64 64 /** 65 65 * Construct a client associated with the given game object. 66 66 * The game must exist for the lifetime of this object. 67 67 */ 68 CNetClient(CGame* game );68 CNetClient(CGame* game, bool isLocalClient); 69 69 70 70 virtual ~CNetClient(); 71 71 72 72 /** 73 73 * We assume that adding a tracing function that's only called … … private: 237 237 CNetClientTurnManager* m_ClientTurnManager; 238 238 239 239 /// Unique-per-game identifier of this client, used to identify the sender of simulation commands 240 240 u32 m_HostID; 241 241 242 /// Whether to prevent the client of the host from timing out 243 bool m_IsLocalClient; 244 242 245 /// Latest copy of game setup attributes heard from the server 243 246 JS::PersistentRootedValue m_GameAttributes; 244 247 245 248 /// Latest copy of player assignments heard from the server 246 249 PlayerAssignmentMap m_PlayerAssignments; -
source/network/NetMessages.h
26 26 #include "ps/CStr.h" 27 27 #include "scriptinterface/ScriptVal.h" 28 28 29 29 #define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?' 30 30 #define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!' 31 #define PS_PROTOCOL_VERSION 0x0101001 1// Arbitrary protocol31 #define PS_PROTOCOL_VERSION 0x01010012 // Arbitrary protocol 32 32 #define PS_DEFAULT_PORT 0x5073 // 'P', 's' 33 33 34 34 // Defines the list of message types. The order of the list must not change. 35 35 // The message types having a negative value are used internally and not sent 36 36 // over the network. The message types used for network communication have … … END_NMT_CLASS() 110 110 111 111 START_NMT_CLASS_(Authenticate, NMT_AUTHENTICATE) 112 112 NMT_FIELD(CStr8, m_GUID) 113 113 NMT_FIELD(CStrW, m_Name) 114 114 NMT_FIELD(CStrW, m_Password) 115 NMT_FIELD_INT(m_IsLocalClient, u8, 1) 115 116 END_NMT_CLASS() 116 117 117 118 START_NMT_CLASS_(AuthenticateResult, NMT_AUTHENTICATE_RESULT) 118 119 NMT_FIELD_INT(m_Code, u32, 4) 119 120 NMT_FIELD_INT(m_HostID, u32, 2) -
source/network/NetServer.cpp
23 23 #include "NetMessage.h" 24 24 #include "NetSession.h" 25 25 #include "NetStats.h" 26 26 #include "NetTurnManager.h" 27 27 28 #include "lib/external_libraries/enet.h"29 28 #include "ps/CLogger.h" 30 29 #include "ps/ConfigDB.h" 31 30 #include "scriptinterface/ScriptInterface.h" 32 31 #include "scriptinterface/ScriptRuntime.h" 33 32 #include "simulation2/Simulation2.h" … … private: 126 125 127 126 CNetServerWorker::CNetServerWorker(int autostartPlayers) : 128 127 m_AutostartPlayers(autostartPlayers), 129 128 m_Shutdown(false), 130 129 m_ScriptInterface(NULL), 131 m_NextHostID(1), m_Host(NULL), m_ HostGUID(), m_Stats(NULL),130 m_NextHostID(1), m_Host(NULL), m_Stats(NULL), 132 131 m_LastConnectionCheck(0) 133 132 { 134 133 m_State = SERVER_STATE_UNCONNECTED; 135 134 136 135 m_ServerTurnManager = NULL; … … bool CNetServerWorker::RunStep() 484 483 485 484 // Set up a session object for this peer 486 485 487 486 CNetServerSession* session = new CNetServerSession(*this, event.peer); 488 487 489 // Prevent the local client of the host from timing out too quickly490 #if (ENET_VERSION >= ENET_VERSION_CREATE(1, 3, 4))491 if (session->GetIPAddress() == "127.0.0.1")492 enet_peer_timeout(event.peer, 0, MAXIMUM_HOST_TIMEOUT, MAXIMUM_HOST_TIMEOUT);493 #endif494 495 488 m_Sessions.push_back(session); 496 489 497 490 SetupSession(session); 498 491 499 492 ENSURE(event.peer->data == NULL); … … bool CNetServerWorker::HandleConnect(CNe 688 681 689 682 void CNetServerWorker::OnUserJoin(CNetServerSession* session) 690 683 { 691 684 AddPlayer(session->GetGUID(), session->GetUserName()); 692 685 693 if (m_HostGUID.empty() && session->GetIPAddress() == "127.0.0.1")694 m_HostGUID = session->GetGUID();695 696 686 CGameSetupMessage gameSetupMessage(GetScriptInterface()); 697 687 gameSetupMessage.m_Data = m_GameAttributes.get(); 698 688 session->SendMessage(&gameSetupMessage); 699 689 700 690 CPlayerAssignmentMessage assignMessage; … … bool CNetServerWorker::KickPlayer(const 790 780 // Find the user with that name 791 781 std::vector<CNetServerSession*>::iterator it = std::find_if(m_Sessions.begin(), m_Sessions.end(), 792 782 [&](CNetServerSession* session) { return session->GetUserName() == playerName; }); 793 783 794 784 // and return if no one or the host has that name 795 if (it == m_Sessions.end() || (*it)-> GetGUID() == m_HostGUID)785 if (it == m_Sessions.end() || (*it)->IsLocalClient()) 796 786 return false; 797 787 798 788 if (ban) 799 789 { 800 790 // Remember name 801 791 if (std::find(m_BannedPlayers.begin(), m_BannedPlayers.end(), playerName) == m_BannedPlayers.end()) 802 792 m_BannedPlayers.push_back(playerName); 803 793 804 794 // Remember IP address 805 CStripAddress = (*it)->GetIPAddress();806 if ( !ipAddress.empty() &&std::find(m_BannedIPs.begin(), m_BannedIPs.end(), ipAddress) == m_BannedIPs.end())795 enet_uint32 ipAddress = (*it)->GetIPAddress(); 796 if (std::find(m_BannedIPs.begin(), m_BannedIPs.end(), ipAddress) == m_BannedIPs.end()) 807 797 m_BannedIPs.push_back(ipAddress); 808 798 } 809 799 810 800 // Disconnect that user 811 801 (*it)->Disconnect(ban ? NDR_BANNED : NDR_KICKED); … … bool CNetServerWorker::OnAuthenticate(vo 997 987 u32 newHostID = server.m_NextHostID++; 998 988 999 989 session->SetUserName(username); 1000 990 session->SetGUID(message->m_GUID); 1001 991 session->SetHostID(newHostID); 992 session->SetLocalClient(message->m_IsLocalClient); 1002 993 1003 994 CAuthenticateResultMessage authenticateResult; 1004 995 authenticateResult.m_Code = isRejoining ? ARC_OK_REJOINING : ARC_OK; 1005 996 authenticateResult.m_HostID = newHostID; 1006 997 authenticateResult.m_Message = L"Logged in"; -
source/network/NetServer.h
20 20 21 21 #include "NetFileTransfer.h" 22 22 #include "NetHost.h" 23 23 24 24 #include "lib/config2.h" 25 #include "lib/external_libraries/enet.h" 25 26 #include "ps/ThreadUtil.h" 26 27 #include "scriptinterface/ScriptVal.h" 27 28 28 29 #include <vector> 29 30 … … private: 311 312 NetServerState m_State; 312 313 313 314 CStrW m_ServerName; 314 315 CStrW m_WelcomeMessage; 315 316 316 std::vector< CStr> m_BannedIPs;317 std::vector<enet_uint32> m_BannedIPs; 317 318 std::vector<CStrW> m_BannedPlayers; 318 319 319 320 u32 m_NextHostID; 320 321 321 322 CNetServerTurnManager* m_ServerTurnManager; 322 323 323 CStr m_HostGUID;324 325 324 /** 326 325 * A copy of all simulation commands received so far, indexed by 327 326 * turn number, to simplify support for rejoining etc. 328 327 * TODO: verify this doesn't use too much RAM. 329 328 */ -
source/network/NetSession.cpp
19 19 #include "NetSession.h" 20 20 #include "NetClient.h" 21 21 #include "NetServer.h" 22 22 #include "NetMessage.h" 23 23 #include "NetStats.h" 24 #include "lib/external_libraries/enet.h"25 24 #include "ps/CLogger.h" 26 25 #include "scriptinterface/ScriptInterface.h" 27 26 28 27 const u32 NETWORK_WARNING_TIMEOUT = 4000; 29 28 … … CNetClientSession::~CNetClientSession() 49 48 m_Host = NULL; 50 49 m_Server = NULL; 51 50 } 52 51 } 53 52 54 bool CNetClientSession::Connect(u16 port, const CStr& server )53 bool CNetClientSession::Connect(u16 port, const CStr& server, bool isLocalClient) 55 54 { 56 55 ENSURE(!m_Host); 57 56 ENSURE(!m_Server); 58 57 59 58 // Create ENet host … … bool CNetClientSession::Connect(u16 port 75 74 m_Host = host; 76 75 m_Server = peer; 77 76 78 77 // Prevent the local client of the host from timing out too quickly. 79 78 #if (ENET_VERSION >= ENET_VERSION_CREATE(1, 3, 4)) 80 if ( GetIPAddress() == "127.0.0.1")79 if (isLocalClient) 81 80 enet_peer_timeout(peer, 1, MAXIMUM_HOST_TIMEOUT, MAXIMUM_HOST_TIMEOUT); 82 81 #endif 83 82 84 83 m_Stats = new CNetStatsTable(m_Server); 85 84 if (CProfileViewer::IsInitialised()) … … bool CNetClientSession::SendMessage(cons 176 175 ENSURE(m_Host && m_Server); 177 176 178 177 return CNetHost::SendMessage(message, m_Server, "server"); 179 178 } 180 179 181 CStr CNetClientSession::GetIPAddress() const182 {183 char ipAddress[256] = "";184 if (enet_address_get_host_ip(&m_Server->address, ipAddress, ARRAY_SIZE(ipAddress)) < 0)185 LOGMESSAGE("Could not get IP address of the server!");186 187 return ipAddress;188 }189 190 180 u32 CNetClientSession::GetLastReceivedTime() const 191 181 { 192 182 if (!m_Server) 193 183 return 0; 194 184 … … u32 CNetClientSession::GetMeanRTT() cons 208 198 CNetServerSession::CNetServerSession(CNetServerWorker& server, ENetPeer* peer) : 209 199 m_Server(server), m_FileTransferer(this), m_Peer(peer) 210 200 { 211 201 } 212 202 213 CStrCNetServerSession::GetIPAddress() const203 enet_uint32 CNetServerSession::GetIPAddress() const 214 204 { 215 char ipAddress[256] = ""; 216 if (enet_address_get_host_ip(&m_Peer->address, ipAddress, ARRAY_SIZE(ipAddress)) < 0) 217 LOGMESSAGE("Could not get IP address of a client!"); 218 219 return ipAddress; 205 return m_Peer->address.host; 220 206 } 221 207 222 208 u32 CNetServerSession::GetLastReceivedTime() const 223 209 { 224 210 if (!m_Peer) … … void CNetServerSession::DisconnectNow(u3 249 235 250 236 bool CNetServerSession::SendMessage(const CNetMessage* message) 251 237 { 252 238 return m_Server.SendMessage(m_Peer, message); 253 239 } 240 241 bool CNetServerSession::IsLocalClient() 242 { 243 return m_IsLocalClient; 244 } 245 246 void CNetServerSession::SetLocalClient(bool isLocalClient) 247 { 248 m_IsLocalClient = isLocalClient; 249 250 if (!isLocalClient) 251 return; 252 253 // Prevent the local client of the host from timing out too quickly 254 #if (ENET_VERSION >= ENET_VERSION_CREATE(1, 3, 4)) 255 enet_peer_timeout(m_Peer, 0, MAXIMUM_HOST_TIMEOUT, MAXIMUM_HOST_TIMEOUT); 256 #endif 257 } -
source/network/NetSession.h
19 19 #define NETSESSION_H 20 20 21 21 #include "network/fsm.h" 22 22 #include "network/NetFileTransfer.h" 23 23 #include "network/NetHost.h" 24 #include "lib/external_libraries/enet.h" 24 25 #include "ps/CStr.h" 25 26 #include "scriptinterface/ScriptVal.h" 26 27 27 28 /** 28 29 * Report the peer if we didn't receive a packet after this time (milliseconds). … … class CNetClientSession : public INetSes 68 69 69 70 public: 70 71 CNetClientSession(CNetClient& client); 71 72 ~CNetClientSession(); 72 73 73 bool Connect(u16 port, const CStr& server );74 bool Connect(u16 port, const CStr& server, bool isLocalClient); 74 75 75 76 /** 76 77 * Process queued incoming messages. 77 78 */ 78 79 void Poll(); … … public: 91 92 /** 92 93 * Send a message to the server. 93 94 */ 94 95 virtual bool SendMessage(const CNetMessage* message); 95 96 96 CStr GetIPAddress() const;97 98 97 /** 99 98 * Number of milliseconds since the most recent packet of the server was received. 100 99 */ 101 100 u32 GetLastReceivedTime() const; 102 101 … … public: 142 141 void SetUserName(const CStrW& name) { m_UserName = name; } 143 142 144 143 u32 GetHostID() const { return m_HostID; } 145 144 void SetHostID(u32 id) { m_HostID = id; } 146 145 147 CStrGetIPAddress() const;146 enet_uint32 GetIPAddress() const; 148 147 149 148 /** 150 149 * Number of milliseconds since the latest packet of that client was received. 151 150 */ 152 151 u32 GetLastReceivedTime() const; … … public: 170 169 * The server will not receive any further messages sent via this session. 171 170 */ 172 171 void DisconnectNow(u32 reason); 173 172 174 173 /** 174 * Whether this client is running in the same process as the server. 175 */ 176 bool IsLocalClient(); 177 178 /** 179 * Prevent timeouts for the client running in the same process as the server. 180 */ 181 void SetLocalClient(bool isLocalClient); 182 183 /** 175 184 * Send a message to the client. 176 185 */ 177 186 virtual bool SendMessage(const CNetMessage* message); 178 187 179 188 CNetFileTransferer& GetFileTransferer() { return m_FileTransferer; } … … private: 186 195 ENetPeer* m_Peer; 187 196 188 197 CStr m_GUID; 189 198 CStrW m_UserName; 190 199 u32 m_HostID; 200 201 bool m_IsLocalClient; 191 202 }; 192 203 193 204 #endif // NETSESSION_H -
source/network/tests/test_Net.h
public: 150 150 151 151 JS::RootedValue attrs(cx); 152 152 scriptInterface.Eval("({mapType:'scenario',map:'maps/scenarios/Saharan Oases',mapPath:'maps/scenarios/',thing:'example'})", &attrs); 153 153 server.UpdateGameAttributes(&attrs, scriptInterface); 154 154 155 CNetClient client1(&client1Game );156 CNetClient client2(&client2Game );157 CNetClient client3(&client3Game );155 CNetClient client1(&client1Game, false); 156 CNetClient client2(&client2Game, false); 157 CNetClient client3(&client3Game, false); 158 158 159 159 clients.push_back(&client1); 160 160 clients.push_back(&client2); 161 161 clients.push_back(&client3); 162 162 … … public: 215 215 216 216 JS::RootedValue attrs(cx); 217 217 scriptInterface.Eval("({mapType:'scenario',map:'maps/scenarios/Saharan Oases',mapPath:'maps/scenarios/',thing:'example'})", &attrs); 218 218 server.UpdateGameAttributes(&attrs, scriptInterface); 219 219 220 CNetClient client1(&client1Game );221 CNetClient client2(&client2Game );222 CNetClient client3(&client3Game );220 CNetClient client1(&client1Game, false); 221 CNetClient client2(&client2Game, false); 222 CNetClient client3(&client3Game, false); 223 223 224 224 client1.SetUserName(L"alice"); 225 225 client2.SetUserName(L"bob"); 226 226 client3.SetUserName(L"charlie"); 227 227 … … public: 267 267 clients.erase(clients.begin()+1); 268 268 269 269 debug_printf("==== Connecting client 2B\n"); 270 270 271 271 CGame client2BGame(true); 272 CNetClient client2B(&client2BGame );272 CNetClient client2B(&client2BGame, false); 273 273 client2B.SetUserName(L"bob"); 274 274 clients.push_back(&client2B); 275 275 276 276 TS_ASSERT(client2B.SetupConnection("127.0.0.1")); 277 277 -
source/ps/GameSetup/GameSetup.cpp
bool Autostart(const CmdLineArgs& args) 1445 1445 g_NetServer->UpdateGameAttributes(&attrs, scriptInterface); 1446 1446 1447 1447 bool ok = g_NetServer->SetupConnection(); 1448 1448 ENSURE(ok); 1449 1449 1450 g_NetClient = new CNetClient(g_Game );1450 g_NetClient = new CNetClient(g_Game, true); 1451 1451 g_NetClient->SetUserName(userName); 1452 1452 g_NetClient->SetupConnection("127.0.0.1"); 1453 1453 } 1454 1454 else if (args.Has("autostart-client")) 1455 1455 { 1456 1456 InitPs(true, L"page_loading.xml", &scriptInterface, mpInitData); 1457 1457 1458 g_NetClient = new CNetClient(g_Game );1458 g_NetClient = new CNetClient(g_Game, false); 1459 1459 g_NetClient->SetUserName(userName); 1460 1460 1461 1461 CStr ip = args.Get("autostart-client"); 1462 1462 if (ip.empty()) 1463 1463 ip = "127.0.0.1";