Ticket #3700: 3700.3.patch
File 3700.3.patch, 26.4 KB (added by , 7 years ago) |
---|
-
source/gui/scripting/ScriptFunctions.cpp
349 349 } 350 350 351 351 g_Game = new CGame(); 352 g_NetClient = new CNetClient (g_Game, true);352 g_NetClient = new CNetClientWorker(g_Game, true); 353 353 g_NetClient->SetUserName(playerName); 354 354 355 355 if (!g_NetClient->SetupConnection("127.0.0.1", serverPort)) … … 367 367 ENSURE(!g_Game); 368 368 369 369 g_Game = new CGame(); 370 g_NetClient = new CNetClient (g_Game, false);370 g_NetClient = new CNetClientWorker(g_Game, false); 371 371 g_NetClient->SetUserName(playerName); 372 372 if (!g_NetClient->SetupConnection(serverAddress, serverPort)) 373 373 { -
source/network/NetClient.cpp
45 45 { 46 46 NONCOPYABLE(CNetFileReceiveTask_ClientRejoin); 47 47 public: 48 CNetFileReceiveTask_ClientRejoin(CNetClient & client)48 CNetFileReceiveTask_ClientRejoin(CNetClientWorker& client) 49 49 : m_Client(client) 50 50 { 51 51 } … … 63 63 } 64 64 65 65 private: 66 CNetClient & m_Client;66 CNetClientWorker& m_Client; 67 67 }; 68 68 69 CNetClient ::CNetClient(CGame* game, bool isLocalClient) :69 CNetClientWorker::CNetClientWorker(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), … … 79 79 80 80 void* context = this; 81 81 82 JS_AddExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClient ::Trace, this);82 JS_AddExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClientWorker::Trace, this); 83 83 84 84 // Set up transitions for session 85 85 AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, (void*)&OnConnect, context); … … 139 139 SetFirstState(NCS_UNCONNECTED); 140 140 } 141 141 142 CNetClient ::~CNetClient()142 CNetClientWorker::~CNetClientWorker() 143 143 { 144 144 DestroyConnection(); 145 JS_RemoveExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClient::Trace, this); 145 JS_RemoveExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClientWorker::Trace, this); 146 147 /* if (m_State != SERVER_STATE_UNCONNECTED) 148 { 149 // Tell the thread to shut down 150 { 151 CScopeLock lock(m_WorkerMutex); 152 m_Shutdown = true; 153 } 154 155 // Wait for it to shut down cleanly 156 pthread_join(m_WorkerThread, NULL); 157 } 158 159 // Clean up resources 160 161 delete m_Stats; 162 163 for (CNetServerSession* session : m_Sessions) 164 { 165 session->DisconnectNow(NDR_SERVER_SHUTDOWN); 166 delete session; 167 } 168 169 if (m_Host) 170 enet_host_destroy(m_Host); 171 172 delete m_ServerTurnManager; */ 146 173 } 147 174 148 void CNetClient ::TraceMember(JSTracer *trc)175 void CNetClientWorker::TraceMember(JSTracer *trc) 149 176 { 150 177 for (JS::Heap<JS::Value>& guiMessage : m_GuiMessageQueue) 151 178 JS_CallValueTracer(trc, &guiMessage, "m_GuiMessageQueue"); 152 179 } 153 180 154 void CNetClient ::SetUserName(const CStrW& username)181 void CNetClientWorker::SetUserName(const CStrW& username) 155 182 { 156 183 ENSURE(!m_Session); // must be called before we start the connection 157 184 … … 158 185 m_UserName = username; 159 186 } 160 187 161 bool CNetClient ::SetupConnection(const CStr& server, const u16 port)188 bool CNetClientWorker::SetupConnection(const CStr& server, const u16 port) 162 189 { 163 190 CNetClientSession* session = new CNetClientSession(*this); 164 191 bool ok = session->Connect(server, port, m_IsLocalClient); 165 192 SetAndOwnSession(session); 193 194 //m_State = SERVER_STATE_PREGAME; 195 196 // Launch the worker thread 197 int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this); 198 ENSURE(ret == 0); 199 166 200 return ok; 167 201 } 168 202 169 void CNetClient ::SetAndOwnSession(CNetClientSession* session)203 void CNetClientWorker::SetAndOwnSession(CNetClientSession* session) 170 204 { 171 205 delete m_Session; 172 206 m_Session = session; 173 207 } 174 208 175 void CNetClient ::DestroyConnection()209 void CNetClientWorker::DestroyConnection() 176 210 { 177 211 // Send network messages from the current frame before connection is destroyed. 178 212 if (m_ClientTurnManager) … … 183 217 SAFE_DELETE(m_Session); 184 218 } 185 219 186 void CNetClient ::Poll()220 void CNetClientWorker::Poll() 187 221 { 188 222 if (!m_Session) 189 223 return; … … 192 226 m_Session->Poll(); 193 227 } 194 228 195 void CNetClient::CheckServerConnection()229 void* CNetClientWorker::RunThread(void* data) 196 230 { 231 debug_SetThreadName("NetClient"); 232 233 static_cast<CNetClientWorker*>(data)->Run(); 234 235 return NULL; 236 } 237 238 void CNetClientWorker::Run() 239 { 240 // The script runtime uses the profiler and therefore the thread must be registered before the runtime is created 241 g_Profiler2.RegisterCurrentThread("Net client"); 242 243 // To avoid the need for JS_SetContextThread, we create and use and destroy 244 // the script interface entirely within this network thread 245 m_ScriptInterface = new ScriptInterface("Engine", "Net client", ScriptInterface::CreateRuntime(g_ScriptRuntime)); 246 m_GameAttributes.init(m_ScriptInterface->GetJSRuntime(), JS::UndefinedValue()); 247 248 while (true) 249 { 250 if (!RunStep()) 251 break; 252 253 // Implement autostart mode 254 //if (m_State == CLIENT_STATE_PREGAME && (int)m_PlayerAssignments.size() == m_AutostartPlayers) 255 // StartGame(); 256 257 // Update profiler stats 258 //m_Stats->LatchHostState(m_Host); 259 } 260 } 261 262 bool CNetClientWorker::RunStep() 263 { 264 // Check for messages from the game thread. 265 // (Do as little work as possible while the mutex is held open, 266 // to avoid performance problems and deadlocks.) 267 268 CheckServerConnection(); 269 270 return true; 271 } 272 273 void CNetClientWorker::CheckServerConnection() 274 { 197 275 // Trigger local warnings if the connection to the server is bad. 198 276 // At most once per second. 199 277 std::time_t now = std::time(nullptr); … … 227 305 } 228 306 } 229 307 230 void CNetClient ::Flush()308 void CNetClientWorker::Flush() 231 309 { 232 310 if (m_Session) 233 311 m_Session->Flush(); 234 312 } 235 313 236 void CNetClient ::GuiPoll(JS::MutableHandleValue ret)314 void CNetClientWorker::GuiPoll(JS::MutableHandleValue ret) 237 315 { 238 316 if (m_GuiMessageQueue.empty()) 239 317 { … … 245 323 m_GuiMessageQueue.pop_front(); 246 324 } 247 325 248 void CNetClient ::PushGuiMessage(const JS::HandleValue message)326 void CNetClientWorker::PushGuiMessage(const JS::HandleValue message) 249 327 { 250 328 ENSURE(!message.isUndefined()); 251 329 … … 252 330 m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message)); 253 331 } 254 332 255 std::string CNetClient ::TestReadGuiMessages()333 std::string CNetClientWorker::TestReadGuiMessages() 256 334 { 257 335 JSContext* cx = GetScriptInterface().GetContext(); 258 336 JSAutoRequest rq(cx); … … 269 347 return r; 270 348 } 271 349 272 ScriptInterface& CNetClient ::GetScriptInterface()350 ScriptInterface& CNetClientWorker::GetScriptInterface() 273 351 { 274 352 return m_Game->GetSimulation2()->GetScriptInterface(); 275 353 } 276 354 277 void CNetClient ::PostPlayerAssignmentsToScript()355 void CNetClientWorker::PostPlayerAssignmentsToScript() 278 356 { 279 357 JSContext* cx = GetScriptInterface().GetContext(); 280 358 JSAutoRequest rq(cx); … … 298 376 PushGuiMessage(msg); 299 377 } 300 378 301 bool CNetClient ::SendMessage(const CNetMessage* message)379 bool CNetClientWorker::SendMessage(const CNetMessage* message) 302 380 { 303 381 if (!m_Session) 304 382 return false; … … 306 384 return m_Session->SendMessage(message); 307 385 } 308 386 309 void CNetClient ::HandleConnect()387 void CNetClientWorker::HandleConnect() 310 388 { 311 389 Update((uint)NMT_CONNECT_COMPLETE, NULL); 312 390 } 313 391 314 void CNetClient ::HandleDisconnect(u32 reason)392 void CNetClientWorker::HandleDisconnect(u32 reason) 315 393 { 316 394 JSContext* cx = GetScriptInterface().GetContext(); 317 395 JSAutoRequest rq(cx); … … 328 406 SetCurrState(NCS_UNCONNECTED); 329 407 } 330 408 331 void CNetClient ::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface)409 void CNetClientWorker::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface) 332 410 { 333 411 CGameSetupMessage gameSetup(scriptInterface); 334 412 gameSetup.m_Data = attrs; … … 335 413 SendMessage(&gameSetup); 336 414 } 337 415 338 void CNetClient ::SendAssignPlayerMessage(const int playerID, const CStr& guid)416 void CNetClientWorker::SendAssignPlayerMessage(const int playerID, const CStr& guid) 339 417 { 340 418 CAssignPlayerMessage assignPlayer; 341 419 assignPlayer.m_PlayerID = playerID; … … 343 421 SendMessage(&assignPlayer); 344 422 } 345 423 346 void CNetClient ::SendChatMessage(const std::wstring& text)424 void CNetClientWorker::SendChatMessage(const std::wstring& text) 347 425 { 348 426 CChatMessage chat; 349 427 chat.m_Message = text; … … 350 428 SendMessage(&chat); 351 429 } 352 430 353 void CNetClient ::SendReadyMessage(const int status)431 void CNetClientWorker::SendReadyMessage(const int status) 354 432 { 355 433 CReadyMessage readyStatus; 356 434 readyStatus.m_Status = status; … … 357 435 SendMessage(&readyStatus); 358 436 } 359 437 360 void CNetClient ::SendClearAllReadyMessage()438 void CNetClientWorker::SendClearAllReadyMessage() 361 439 { 362 440 CClearAllReadyMessage clearAllReady; 363 441 SendMessage(&clearAllReady); 364 442 } 365 443 366 void CNetClient ::SendStartGameMessage()444 void CNetClientWorker::SendStartGameMessage() 367 445 { 368 446 CGameStartMessage gameStart; 369 447 SendMessage(&gameStart); 370 448 } 371 449 372 void CNetClient ::SendRejoinedMessage()450 void CNetClientWorker::SendRejoinedMessage() 373 451 { 374 452 CRejoinedMessage rejoinedMessage; 375 453 SendMessage(&rejoinedMessage); 376 454 } 377 455 378 void CNetClient ::SendKickPlayerMessage(const CStrW& playerName, bool ban)456 void CNetClientWorker::SendKickPlayerMessage(const CStrW& playerName, bool ban) 379 457 { 380 458 CKickedMessage kickPlayer; 381 459 kickPlayer.m_Name = playerName; … … 383 461 SendMessage(&kickPlayer); 384 462 } 385 463 386 void CNetClient ::SendPausedMessage(bool pause)464 void CNetClientWorker::SendPausedMessage(bool pause) 387 465 { 388 466 CClientPausedMessage pausedMessage; 389 467 pausedMessage.m_Pause = pause; … … 390 468 SendMessage(&pausedMessage); 391 469 } 392 470 393 bool CNetClient ::HandleMessage(CNetMessage* message)471 bool CNetClientWorker::HandleMessage(CNetMessage* message) 394 472 { 395 473 // Handle non-FSM messages first 396 474 … … 433 511 return ok; 434 512 } 435 513 436 void CNetClient ::LoadFinished()514 void CNetClientWorker::LoadFinished() 437 515 { 438 516 JSContext* cx = GetScriptInterface().GetContext(); 439 517 JSAutoRequest rq(cx); … … 476 554 SendMessage(&loaded); 477 555 } 478 556 479 bool CNetClient ::OnConnect(void* context, CFsmEvent* event)557 bool CNetClientWorker::OnConnect(void* context, CFsmEvent* event) 480 558 { 481 559 ENSURE(event->GetType() == (uint)NMT_CONNECT_COMPLETE); 482 560 483 CNetClient * client = (CNetClient*)context;561 CNetClientWorker* client = (CNetClientWorker*)context; 484 562 485 563 JSContext* cx = client->GetScriptInterface().GetContext(); 486 564 JSAutoRequest rq(cx); … … 492 570 return true; 493 571 } 494 572 495 bool CNetClient ::OnHandshake(void* context, CFsmEvent* event)573 bool CNetClientWorker::OnHandshake(void* context, CFsmEvent* event) 496 574 { 497 575 ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE); 498 576 499 CNetClient * client = (CNetClient*)context;577 CNetClientWorker* client = (CNetClientWorker*)context; 500 578 501 579 CCliHandshakeMessage handshake; 502 580 handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE; … … 507 585 return true; 508 586 } 509 587 510 bool CNetClient ::OnHandshakeResponse(void* context, CFsmEvent* event)588 bool CNetClientWorker::OnHandshakeResponse(void* context, CFsmEvent* event) 511 589 { 512 590 ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE_RESPONSE); 513 591 514 CNetClient * client = (CNetClient*)context;592 CNetClientWorker* client = (CNetClientWorker*)context; 515 593 516 594 CAuthenticateMessage authenticate; 517 595 authenticate.m_GUID = client->m_GUID; … … 523 601 return true; 524 602 } 525 603 526 bool CNetClient ::OnAuthenticate(void* context, CFsmEvent* event)604 bool CNetClientWorker::OnAuthenticate(void* context, CFsmEvent* event) 527 605 { 528 606 ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE_RESULT); 529 607 530 CNetClient * client = (CNetClient*)context;608 CNetClientWorker* client = (CNetClientWorker*)context; 531 609 532 610 JSContext* cx = client->GetScriptInterface().GetContext(); 533 611 JSAutoRequest rq(cx); … … 547 625 return true; 548 626 } 549 627 550 bool CNetClient ::OnChat(void* context, CFsmEvent* event)628 bool CNetClientWorker::OnChat(void* context, CFsmEvent* event) 551 629 { 552 630 ENSURE(event->GetType() == (uint)NMT_CHAT); 553 631 554 CNetClient * client = (CNetClient*)context;632 CNetClientWorker* client = (CNetClientWorker*)context; 555 633 JSContext* cx = client->GetScriptInterface().GetContext(); 556 634 JSAutoRequest rq(cx); 557 635 … … 566 644 return true; 567 645 } 568 646 569 bool CNetClient ::OnReady(void* context, CFsmEvent* event)647 bool CNetClientWorker::OnReady(void* context, CFsmEvent* event) 570 648 { 571 649 ENSURE(event->GetType() == (uint)NMT_READY); 572 650 573 CNetClient * client = (CNetClient*)context;651 CNetClientWorker* client = (CNetClientWorker*)context; 574 652 JSContext* cx = client->GetScriptInterface().GetContext(); 575 653 JSAutoRequest rq(cx); 576 654 … … 585 663 return true; 586 664 } 587 665 588 bool CNetClient ::OnGameSetup(void* context, CFsmEvent* event)666 bool CNetClientWorker::OnGameSetup(void* context, CFsmEvent* event) 589 667 { 590 668 ENSURE(event->GetType() == (uint)NMT_GAME_SETUP); 591 669 592 CNetClient * client = (CNetClient*)context;670 CNetClientWorker* client = (CNetClientWorker*)context; 593 671 JSContext* cx = client->GetScriptInterface().GetContext(); 594 672 JSAutoRequest rq(cx); 595 673 … … 605 683 return true; 606 684 } 607 685 608 bool CNetClient ::OnPlayerAssignment(void* context, CFsmEvent* event)686 bool CNetClientWorker::OnPlayerAssignment(void* context, CFsmEvent* event) 609 687 { 610 688 ENSURE(event->GetType() == (uint)NMT_PLAYER_ASSIGNMENT); 611 689 612 CNetClient * client = (CNetClient*)context;690 CNetClientWorker* client = (CNetClientWorker*)context; 613 691 614 692 CPlayerAssignmentMessage* message = (CPlayerAssignmentMessage*)event->GetParamRef(); 615 693 … … 632 710 return true; 633 711 } 634 712 635 bool CNetClient ::OnGameStart(void* context, CFsmEvent* event)713 bool CNetClientWorker::OnGameStart(void* context, CFsmEvent* event) 636 714 { 637 715 ENSURE(event->GetType() == (uint)NMT_GAME_START); 638 716 639 CNetClient * client = (CNetClient*)context;717 CNetClientWorker* client = (CNetClientWorker*)context; 640 718 JSContext* cx = client->GetScriptInterface().GetContext(); 641 719 JSAutoRequest rq(cx); 642 720 … … 658 736 return true; 659 737 } 660 738 661 bool CNetClient ::OnJoinSyncStart(void* context, CFsmEvent* event)739 bool CNetClientWorker::OnJoinSyncStart(void* context, CFsmEvent* event) 662 740 { 663 741 ENSURE(event->GetType() == (uint)NMT_JOIN_SYNC_START); 664 742 665 CNetClient * client = (CNetClient*)context;743 CNetClientWorker* client = (CNetClientWorker*)context; 666 744 667 745 // The server wants us to start downloading the game state from it, so do so 668 746 client->m_Session->GetFileTransferer().StartTask( … … 672 750 return true; 673 751 } 674 752 675 bool CNetClient ::OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event)753 bool CNetClientWorker::OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event) 676 754 { 677 755 ENSURE(event->GetType() == (uint)NMT_END_COMMAND_BATCH); 678 756 679 CNetClient * client = (CNetClient*)context;757 CNetClientWorker* client = (CNetClientWorker*)context; 680 758 681 759 CEndCommandBatchMessage* endMessage = (CEndCommandBatchMessage*)event->GetParamRef(); 682 760 … … 688 766 return true; 689 767 } 690 768 691 bool CNetClient ::OnRejoined(void* context, CFsmEvent* event)769 bool CNetClientWorker::OnRejoined(void* context, CFsmEvent* event) 692 770 { 693 771 ENSURE(event->GetType() == (uint)NMT_REJOINED); 694 772 695 CNetClient * client = (CNetClient*)context;773 CNetClientWorker* client = (CNetClientWorker*)context; 696 774 JSContext* cx = client->GetScriptInterface().GetContext(); 697 775 JSAutoRequest rq(cx); 698 776 … … 705 783 return true; 706 784 } 707 785 708 bool CNetClient ::OnKicked(void *context, CFsmEvent* event)786 bool CNetClientWorker::OnKicked(void *context, CFsmEvent* event) 709 787 { 710 788 ENSURE(event->GetType() == (uint)NMT_KICKED); 711 789 712 CNetClient * client = (CNetClient*)context;790 CNetClientWorker* client = (CNetClientWorker*)context; 713 791 JSContext* cx = client->GetScriptInterface().GetContext(); 714 792 JSAutoRequest rq(cx); 715 793 … … 725 803 return true; 726 804 } 727 805 728 bool CNetClient ::OnClientTimeout(void *context, CFsmEvent* event)806 bool CNetClientWorker::OnClientTimeout(void *context, CFsmEvent* event) 729 807 { 730 808 // Report the timeout of some other client 731 809 732 810 ENSURE(event->GetType() == (uint)NMT_CLIENT_TIMEOUT); 733 811 734 CNetClient * client = (CNetClient*)context;812 CNetClientWorker* client = (CNetClientWorker*)context; 735 813 JSContext* cx = client->GetScriptInterface().GetContext(); 736 814 JSAutoRequest rq(cx); 737 815 … … 749 827 return true; 750 828 } 751 829 752 bool CNetClient ::OnClientPerformance(void *context, CFsmEvent* event)830 bool CNetClientWorker::OnClientPerformance(void *context, CFsmEvent* event) 753 831 { 754 832 // Performance statistics for one or multiple clients 755 833 756 834 ENSURE(event->GetType() == (uint)NMT_CLIENT_PERFORMANCE); 757 835 758 CNetClient * client = (CNetClient*)context;836 CNetClientWorker* client = (CNetClientWorker*)context; 759 837 JSContext* cx = client->GetScriptInterface().GetContext(); 760 838 JSAutoRequest rq(cx); 761 839 … … 780 858 return true; 781 859 } 782 860 783 bool CNetClient ::OnClientsLoading(void *context, CFsmEvent *event)861 bool CNetClientWorker::OnClientsLoading(void *context, CFsmEvent *event) 784 862 { 785 863 ENSURE(event->GetType() == (uint)NMT_CLIENTS_LOADING); 786 864 … … 791 869 for (const CClientsLoadingMessage::S_m_Clients& client : message->m_Clients) 792 870 guids.push_back(client.m_GUID); 793 871 794 CNetClient * client = (CNetClient*)context;872 CNetClientWorker* client = (CNetClientWorker*)context; 795 873 JSContext* cx = client->GetScriptInterface().GetContext(); 796 874 JSAutoRequest rq(cx); 797 875 … … 802 880 return true; 803 881 } 804 882 805 bool CNetClient ::OnClientPaused(void *context, CFsmEvent *event)883 bool CNetClientWorker::OnClientPaused(void *context, CFsmEvent *event) 806 884 { 807 885 ENSURE(event->GetType() == (uint)NMT_CLIENT_PAUSED); 808 886 809 CNetClient * client = (CNetClient*)context;887 CNetClientWorker* client = (CNetClientWorker*)context; 810 888 JSContext* cx = client->GetScriptInterface().GetContext(); 811 889 JSAutoRequest rq(cx); 812 890 … … 821 899 return true; 822 900 } 823 901 824 bool CNetClient ::OnLoadedGame(void* context, CFsmEvent* event)902 bool CNetClientWorker::OnLoadedGame(void* context, CFsmEvent* event) 825 903 { 826 904 ENSURE(event->GetType() == (uint)NMT_LOADED_GAME); 827 905 828 CNetClient * client = (CNetClient*)context;906 CNetClientWorker* client = (CNetClientWorker*)context; 829 907 JSContext* cx = client->GetScriptInterface().GetContext(); 830 908 JSAutoRequest rq(cx); 831 909 … … 844 922 return true; 845 923 } 846 924 847 bool CNetClient ::OnInGame(void *context, CFsmEvent* event)925 bool CNetClientWorker::OnInGame(void *context, CFsmEvent* event) 848 926 { 849 927 // TODO: should split each of these cases into a separate method 850 928 851 CNetClient * client = (CNetClient*)context;929 CNetClientWorker* client = (CNetClientWorker*)context; 852 930 853 931 CNetMessage* message = (CNetMessage*)event->GetParamRef(); 854 932 if (message) … … 872 950 873 951 return true; 874 952 } 953 954 CNetClient::CNetClient(CGame* game, bool isLocalClient) : 955 m_Worker(new CNetClient(autostartPlayers)) 956 { 957 } 958 959 CNetClient::~CNetClient() 960 { 961 delete m_Worker; 962 } 963 964 void CNetClient::DestroyConnection() 965 { 966 } 967 968 void CNetClient::TraceMember(JSTracer *trc) 969 { 970 } 971 972 void CNetClient::SetUserName(const CStrW& username) 973 { 974 m_Worker->username = username; 975 } 976 977 bool CNetClient::SetupConnection(const u16 port) 978 { 979 return m_Worker->SetupConnection(port); 980 } 981 982 983 984 -
source/network/NetClient.h
23 23 #include "network/NetHost.h" 24 24 #include "scriptinterface/ScriptVal.h" 25 25 26 #include "ps/ThreadUtil.h" 26 27 #include "ps/CStr.h" 27 28 28 29 #include <deque> … … 33 34 class CNetServer; 34 35 class ScriptInterface; 35 36 37 class CNetClientWorker; 38 36 39 // NetClient session FSM states 37 40 enum 38 41 { … … 107 110 */ 108 111 void DestroyConnection(); 109 112 113 private: 114 CStr m_GUID; 115 CNetClientWorker* m_Worker; 116 }; 117 118 /** 119 * Network client worker thread. 120 * 121 * Thread-safety: 122 * 123 * 124 */ 125 class CNetClientWorker : public CFsm 126 { 127 NONCOPYABLE(CNetClientWorker); 128 129 public: 110 130 /** 131 * Returns the GUID of the local client. 132 * Used for distinguishing observers. 133 */ 134 CStr GetGUID() const { return m_GUID; } 135 136 /** 137 * Send a message to the server. 138 * @param message message to send 139 * @return true on success 140 */ 141 bool SendMessage(const CNetMessage* message); 142 143 /** 144 * Call when the network connection has been successfully initiated. 145 */ 146 void HandleConnect(); 147 148 /** 149 * Call when the network connection has been lost. 150 */ 151 void HandleDisconnect(u32 reason); 152 153 /** 154 * Call when a message has been received from the network. 155 */ 156 bool HandleMessage(CNetMessage* message); 157 158 /** 159 * Get the script interface associated with this network client, 160 * which is equivalent to the one used by the CGame in the constructor. 161 */ 162 ScriptInterface& GetScriptInterface(); 163 164 private: 165 friend class CNetClient; 166 friend class CNetFileReceiveTask_ClientRejoin; 167 168 CNetClientWorker(CGame* game, bool isLocalClient); 169 ~CNetClientWorker(); 170 171 /** 172 * We assume that adding a tracing function that's only called 173 * during GC is better for performance than using a 174 * PersistentRooted<T> where each value needs to be added to 175 * the root set. 176 */ 177 static void Trace(JSTracer *trc, void *data) 178 { 179 reinterpret_cast<CNetClientWorker*>(data)->TraceMember(trc); 180 } 181 182 void TraceMember(JSTracer *trc); 183 184 void SetUserName(const CStrW& username); 185 186 bool SetupConnection(const CStr& server, const u16 port); 187 188 /** 189 * Destroy the connection to the server. 190 * This client probably cannot be used again. 191 */ 192 void DestroyConnection(); 193 194 /** 111 195 * Poll the connection for messages from the server and process them, and send 112 196 * any queued messages. 113 197 * This must be called frequently (i.e. once per frame). … … 154 238 std::string TestReadGuiMessages(); 155 239 156 240 /** 157 * Get the script interface associated with this network client,158 * which is equivalent to the one used by the CGame in the constructor.159 */160 ScriptInterface& GetScriptInterface();161 162 /**163 * Send a message to the server.164 * @param message message to send165 * @return true on success166 */167 bool SendMessage(const CNetMessage* message);168 169 /**170 * Call when the network connection has been successfully initiated.171 */172 void HandleConnect();173 174 /**175 * Call when the network connection has been lost.176 */177 void HandleDisconnect(u32 reason);178 179 /**180 * Call when a message has been received from the network.181 */182 bool HandleMessage(CNetMessage* message);183 184 /**185 241 * Call when the game has started and all data files have been loaded, 186 242 * to signal to the server that we are ready to begin the game. 187 243 */ … … 215 271 */ 216 272 void SendPausedMessage(bool pause); 217 273 218 private:219 274 // Net message / FSM transition handlers 220 275 static bool OnConnect(void* context, CFsmEvent* event); 221 276 static bool OnHandshake(void* context, CFsmEvent* event); … … 282 337 283 338 /// Time when the server was last checked for timeouts and bad latency 284 339 std::time_t m_LastConnectionCheck; 340 341 // Thread-related stuff: 342 343 static void* RunThread(void* data); 344 void Run(); 345 bool RunStep(); 346 347 pthread_t m_WorkerThread; 348 CMutex m_WorkerMutex; 349 350 bool m_Shutdown; // protected by m_WorkerMutex 351 352 // Queues for messages sent by the game thread: 353 std::vector<bool> m_StartGameQueue; // protected by m_WorkerMutex 354 std::vector<std::string> m_GameAttributesQueue; // protected by m_WorkerMutex 355 std::vector<u32> m_TurnLengthQueue; // protected by m_WorkerMutex 285 356 }; 286 357 287 358 /// Global network client for the standard game -
source/network/NetClientTurnManager.cpp
33 33 #define NETCLIENTTURN_LOG(...) 34 34 #endif 35 35 36 CNetClientTurnManager::CNetClientTurnManager(CSimulation2& simulation, CNetClient & client, int clientId, IReplayLogger& replay)36 CNetClientTurnManager::CNetClientTurnManager(CSimulation2& simulation, CNetClientWorker& client, int clientId, IReplayLogger& replay) 37 37 : CTurnManager(simulation, DEFAULT_TURN_LENGTH_MP, clientId, replay), m_NetClient(client) 38 38 { 39 39 } -
source/network/NetClientTurnManager.h
21 21 #include "simulation2/system/TurnManager.h" 22 22 #include "NetMessage.h" 23 23 24 class CNetClient ;24 class CNetClientWorker; 25 25 26 26 /** 27 27 * Implementation of CTurnManager for network clients. … … 30 30 { 31 31 NONCOPYABLE(CNetClientTurnManager); 32 32 public: 33 CNetClientTurnManager(CSimulation2& simulation, CNetClient & client, int clientId, IReplayLogger& replay);33 CNetClientTurnManager(CSimulation2& simulation, CNetClientWorker& client, int clientId, IReplayLogger& replay); 34 34 35 35 void OnSimulationMessage(CSimulationMessage* msg) override; 36 36 … … 48 48 49 49 void NotifyFinishedUpdate(u32 turn) override; 50 50 51 CNetClient & m_NetClient;51 CNetClientWorker& m_NetClient; 52 52 }; 53 53 54 54 #endif // INCLUDED_NETCLIENTTURNMANAGER -
source/network/NetSession.cpp
32 32 33 33 static const int CHANNEL_COUNT = 1; 34 34 35 CNetClientSession::CNetClientSession(CNetClient & client) :35 CNetClientSession::CNetClientSession(CNetClientWorker& client) : 36 36 m_Client(client), m_FileTransferer(this), m_Host(NULL), m_Server(NULL), m_Stats(NULL) 37 37 { 38 38 } -
source/network/NetSession.h
34 34 */ 35 35 extern const u32 MAXIMUM_HOST_TIMEOUT; 36 36 37 class CNetClient ;37 class CNetClientWorker; 38 38 class CNetServerWorker; 39 39 40 40 class CNetStatsTable; … … 67 67 NONCOPYABLE(CNetClientSession); 68 68 69 69 public: 70 CNetClientSession(CNetClient & client);70 CNetClientSession(CNetClientWorker& client); 71 71 ~CNetClientSession(); 72 72 73 73 bool Connect(const CStr& server, const u16 port, const bool isLocalClient); … … 106 106 CNetFileTransferer& GetFileTransferer() { return m_FileTransferer; } 107 107 108 108 private: 109 CNetClient & m_Client;109 CNetClientWorker& m_Client; 110 110 111 111 CNetFileTransferer m_FileTransferer; 112 112 -
source/ps/GameSetup/GameSetup.cpp
1498 1498 bool ok = g_NetServer->SetupConnection(PS_DEFAULT_PORT); 1499 1499 ENSURE(ok); 1500 1500 1501 g_NetClient = new CNetClient (g_Game, true);1501 g_NetClient = new CNetClientWorker(g_Game, true); 1502 1502 g_NetClient->SetUserName(userName); 1503 1503 g_NetClient->SetupConnection("127.0.0.1", PS_DEFAULT_PORT); 1504 1504 } … … 1506 1506 { 1507 1507 InitPs(true, L"page_loading.xml", &scriptInterface, mpInitData); 1508 1508 1509 g_NetClient = new CNetClient (g_Game, false);1509 g_NetClient = new CNetClientWorker(g_Game, false); 1510 1510 g_NetClient->SetUserName(userName); 1511 1511 1512 1512 CStr ip = args.Get("autostart-client");