Ticket #3700: 3700.5.patch
File 3700.5.patch, 26.5 KB (added by , 7 years ago) |
---|
-
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); 83 84 // Set up transitions for session 82 // Set up transitions for session 85 83 AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, (void*)&OnConnect, context); 86 84 87 85 AddTransition(NCS_CONNECT, (uint)NMT_SERVER_HANDSHAKE, NCS_HANDSHAKE, (void*)&OnHandshake, context); … … 139 137 SetFirstState(NCS_UNCONNECTED); 140 138 } 141 139 142 CNetClient ::~CNetClient()140 CNetClientWorker::~CNetClientWorker() 143 141 { 144 142 DestroyConnection(); 145 JS_RemoveExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClient::Trace, this);146 }147 143 148 void CNetClient::TraceMember(JSTracer *trc) 149 { 150 for (JS::Heap<JS::Value>& guiMessage : m_GuiMessageQueue) 151 JS_CallValueTracer(trc, &guiMessage, "m_GuiMessageQueue"); 144 /* if (m_State != SERVER_STATE_UNCONNECTED) 145 { 146 // Tell the thread to shut down 147 { 148 CScopeLock lock(m_WorkerMutex); 149 m_Shutdown = true; 150 } 151 152 // Wait for it to shut down cleanly 153 pthread_join(m_WorkerThread, NULL); 154 } 155 156 // Clean up resources 157 158 delete m_Stats; 159 160 for (CNetServerSession* session : m_Sessions) 161 { 162 session->DisconnectNow(NDR_SERVER_SHUTDOWN); 163 delete session; 164 } 165 166 if (m_Host) 167 enet_host_destroy(m_Host); 168 169 delete m_ServerTurnManager; */ 152 170 } 153 171 154 void CNetClient ::SetUserName(const CStrW& username)172 void CNetClientWorker::SetUserName(const CStrW& username) 155 173 { 156 174 ENSURE(!m_Session); // must be called before we start the connection 157 175 … … 158 176 m_UserName = username; 159 177 } 160 178 161 bool CNetClient ::SetupConnection(const CStr& server, const u16 port)179 bool CNetClientWorker::SetupConnection(const CStr& server, const u16 port) 162 180 { 163 181 CNetClientSession* session = new CNetClientSession(*this); 164 182 bool ok = session->Connect(server, port, m_IsLocalClient); 165 183 SetAndOwnSession(session); 184 185 //m_State = SERVER_STATE_PREGAME; 186 187 // Launch the worker thread 188 int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this); 189 ENSURE(ret == 0); 190 166 191 return ok; 167 192 } 168 193 169 void CNetClient ::SetAndOwnSession(CNetClientSession* session)194 void CNetClientWorker::SetAndOwnSession(CNetClientSession* session) 170 195 { 171 196 delete m_Session; 172 197 m_Session = session; 173 198 } 174 199 175 void CNetClient ::DestroyConnection()200 void CNetClientWorker::DestroyConnection() 176 201 { 177 202 // Send network messages from the current frame before connection is destroyed. 178 203 if (m_ClientTurnManager) … … 183 208 SAFE_DELETE(m_Session); 184 209 } 185 210 186 void CNetClient ::Poll()211 void CNetClientWorker::Poll() 187 212 { 188 213 if (!m_Session) 189 214 return; … … 192 217 m_Session->Poll(); 193 218 } 194 219 195 void CNetClient::CheckServerConnection()220 void* CNetClientWorker::RunThread(void* data) 196 221 { 222 debug_SetThreadName("NetClient"); 223 224 static_cast<CNetClientWorker*>(data)->Run(); 225 226 return NULL; 227 } 228 229 void CNetClientWorker::Run() 230 { 231 // The script runtime uses the profiler and therefore the thread must be registered before the runtime is created 232 g_Profiler2.RegisterCurrentThread("Net client"); 233 234 while (true) 235 { 236 if (!RunStep()) 237 break; 238 239 // Implement autostart mode 240 //if (m_State == CLIENT_STATE_PREGAME && (int)m_PlayerAssignments.size() == m_AutostartPlayers) 241 // StartGame(); 242 243 // Update profiler stats 244 //m_Stats->LatchHostState(m_Host); 245 } 246 } 247 248 bool CNetClientWorker::RunStep() 249 { 250 // Check for messages from the game thread. 251 // (Do as little work as possible while the mutex is held open, 252 // to avoid performance problems and deadlocks.) 253 254 CheckServerConnection(); 255 256 return true; 257 } 258 259 void CNetClientWorker::CheckServerConnection() 260 { 197 261 // Trigger local warnings if the connection to the server is bad. 198 262 // At most once per second. 199 263 std::time_t now = std::time(nullptr); … … 227 291 } 228 292 } 229 293 230 void CNetClient ::Flush()294 void CNetClientWorker::Flush() 231 295 { 232 296 if (m_Session) 233 297 m_Session->Flush(); 234 298 } 235 299 236 void CNetClient ::GuiPoll(JS::MutableHandleValue ret)300 void CNetClientWorker::GuiPoll(JS::MutableHandleValue ret) 237 301 { 238 302 if (m_GuiMessageQueue.empty()) 239 303 { … … 245 309 m_GuiMessageQueue.pop_front(); 246 310 } 247 311 248 void CNetClient ::PushGuiMessage(const JS::HandleValue message)312 void CNetClientWorker::PushGuiMessage(const JS::HandleValue message) 249 313 { 250 314 ENSURE(!message.isUndefined()); 251 315 … … 252 316 m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message)); 253 317 } 254 318 255 std::string CNetClient ::TestReadGuiMessages()319 std::string CNetClientWorker::TestReadGuiMessages() 256 320 { 257 321 JSContext* cx = GetScriptInterface().GetContext(); 258 322 JSAutoRequest rq(cx); … … 269 333 return r; 270 334 } 271 335 272 ScriptInterface& CNetClient ::GetScriptInterface()336 ScriptInterface& CNetClientWorker::GetScriptInterface() 273 337 { 274 338 return m_Game->GetSimulation2()->GetScriptInterface(); 275 339 } 276 340 277 void CNetClient ::PostPlayerAssignmentsToScript()341 void CNetClientWorker::PostPlayerAssignmentsToScript() 278 342 { 279 343 JSContext* cx = GetScriptInterface().GetContext(); 280 344 JSAutoRequest rq(cx); … … 298 362 PushGuiMessage(msg); 299 363 } 300 364 301 bool CNetClient ::SendMessage(const CNetMessage* message)365 bool CNetClientWorker::SendMessage(const CNetMessage* message) 302 366 { 303 367 if (!m_Session) 304 368 return false; … … 306 370 return m_Session->SendMessage(message); 307 371 } 308 372 309 void CNetClient ::HandleConnect()373 void CNetClientWorker::HandleConnect() 310 374 { 311 375 Update((uint)NMT_CONNECT_COMPLETE, NULL); 312 376 } 313 377 314 void CNetClient ::HandleDisconnect(u32 reason)378 void CNetClientWorker::HandleDisconnect(u32 reason) 315 379 { 316 380 JSContext* cx = GetScriptInterface().GetContext(); 317 381 JSAutoRequest rq(cx); … … 328 392 SetCurrState(NCS_UNCONNECTED); 329 393 } 330 394 331 void CNetClient ::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface)395 void CNetClientWorker::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface) 332 396 { 333 397 CGameSetupMessage gameSetup(scriptInterface); 334 398 gameSetup.m_Data = attrs; … … 335 399 SendMessage(&gameSetup); 336 400 } 337 401 338 void CNetClient ::SendAssignPlayerMessage(const int playerID, const CStr& guid)402 void CNetClientWorker::SendAssignPlayerMessage(const int playerID, const CStr& guid) 339 403 { 340 404 CAssignPlayerMessage assignPlayer; 341 405 assignPlayer.m_PlayerID = playerID; … … 343 407 SendMessage(&assignPlayer); 344 408 } 345 409 346 void CNetClient ::SendChatMessage(const std::wstring& text)410 void CNetClientWorker::SendChatMessage(const std::wstring& text) 347 411 { 348 412 CChatMessage chat; 349 413 chat.m_Message = text; … … 350 414 SendMessage(&chat); 351 415 } 352 416 353 void CNetClient ::SendReadyMessage(const int status)417 void CNetClientWorker::SendReadyMessage(const int status) 354 418 { 355 419 CReadyMessage readyStatus; 356 420 readyStatus.m_Status = status; … … 357 421 SendMessage(&readyStatus); 358 422 } 359 423 360 void CNetClient ::SendClearAllReadyMessage()424 void CNetClientWorker::SendClearAllReadyMessage() 361 425 { 362 426 CClearAllReadyMessage clearAllReady; 363 427 SendMessage(&clearAllReady); 364 428 } 365 429 366 void CNetClient ::SendStartGameMessage()430 void CNetClientWorker::SendStartGameMessage() 367 431 { 368 432 CGameStartMessage gameStart; 369 433 SendMessage(&gameStart); 370 434 } 371 435 372 void CNetClient ::SendRejoinedMessage()436 void CNetClientWorker::SendRejoinedMessage() 373 437 { 374 438 CRejoinedMessage rejoinedMessage; 375 439 SendMessage(&rejoinedMessage); 376 440 } 377 441 378 void CNetClient ::SendKickPlayerMessage(const CStrW& playerName, bool ban)442 void CNetClientWorker::SendKickPlayerMessage(const CStrW& playerName, bool ban) 379 443 { 380 444 CKickedMessage kickPlayer; 381 445 kickPlayer.m_Name = playerName; … … 383 447 SendMessage(&kickPlayer); 384 448 } 385 449 386 void CNetClient ::SendPausedMessage(bool pause)450 void CNetClientWorker::SendPausedMessage(bool pause) 387 451 { 388 452 CClientPausedMessage pausedMessage; 389 453 pausedMessage.m_Pause = pause; … … 390 454 SendMessage(&pausedMessage); 391 455 } 392 456 393 bool CNetClient ::HandleMessage(CNetMessage* message)457 bool CNetClientWorker::HandleMessage(CNetMessage* message) 394 458 { 395 459 // Handle non-FSM messages first 396 460 … … 433 497 return ok; 434 498 } 435 499 436 void CNetClient ::LoadFinished()500 void CNetClientWorker::LoadFinished() 437 501 { 438 502 JSContext* cx = GetScriptInterface().GetContext(); 439 503 JSAutoRequest rq(cx); … … 476 540 SendMessage(&loaded); 477 541 } 478 542 479 bool CNetClient ::OnConnect(void* context, CFsmEvent* event)543 bool CNetClientWorker::OnConnect(void* context, CFsmEvent* event) 480 544 { 481 545 ENSURE(event->GetType() == (uint)NMT_CONNECT_COMPLETE); 482 546 483 CNetClient * client = (CNetClient*)context;547 CNetClientWorker* client = (CNetClientWorker*)context; 484 548 485 549 JSContext* cx = client->GetScriptInterface().GetContext(); 486 550 JSAutoRequest rq(cx); … … 492 556 return true; 493 557 } 494 558 495 bool CNetClient ::OnHandshake(void* context, CFsmEvent* event)559 bool CNetClientWorker::OnHandshake(void* context, CFsmEvent* event) 496 560 { 497 561 ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE); 498 562 499 CNetClient * client = (CNetClient*)context;563 CNetClientWorker* client = (CNetClientWorker*)context; 500 564 501 565 CCliHandshakeMessage handshake; 502 566 handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE; … … 507 571 return true; 508 572 } 509 573 510 bool CNetClient ::OnHandshakeResponse(void* context, CFsmEvent* event)574 bool CNetClientWorker::OnHandshakeResponse(void* context, CFsmEvent* event) 511 575 { 512 576 ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE_RESPONSE); 513 577 514 CNetClient * client = (CNetClient*)context;578 CNetClientWorker* client = (CNetClientWorker*)context; 515 579 516 580 CAuthenticateMessage authenticate; 517 581 authenticate.m_GUID = client->m_GUID; … … 523 587 return true; 524 588 } 525 589 526 bool CNetClient ::OnAuthenticate(void* context, CFsmEvent* event)590 bool CNetClientWorker::OnAuthenticate(void* context, CFsmEvent* event) 527 591 { 528 592 ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE_RESULT); 529 593 530 CNetClient * client = (CNetClient*)context;594 CNetClientWorker* client = (CNetClientWorker*)context; 531 595 532 596 JSContext* cx = client->GetScriptInterface().GetContext(); 533 597 JSAutoRequest rq(cx); … … 547 611 return true; 548 612 } 549 613 550 bool CNetClient ::OnChat(void* context, CFsmEvent* event)614 bool CNetClientWorker::OnChat(void* context, CFsmEvent* event) 551 615 { 552 616 ENSURE(event->GetType() == (uint)NMT_CHAT); 553 617 554 CNetClient * client = (CNetClient*)context;618 CNetClientWorker* client = (CNetClientWorker*)context; 555 619 JSContext* cx = client->GetScriptInterface().GetContext(); 556 620 JSAutoRequest rq(cx); 557 621 … … 566 630 return true; 567 631 } 568 632 569 bool CNetClient ::OnReady(void* context, CFsmEvent* event)633 bool CNetClientWorker::OnReady(void* context, CFsmEvent* event) 570 634 { 571 635 ENSURE(event->GetType() == (uint)NMT_READY); 572 636 573 CNetClient * client = (CNetClient*)context;637 CNetClientWorker* client = (CNetClientWorker*)context; 574 638 JSContext* cx = client->GetScriptInterface().GetContext(); 575 639 JSAutoRequest rq(cx); 576 640 … … 585 649 return true; 586 650 } 587 651 588 bool CNetClient ::OnGameSetup(void* context, CFsmEvent* event)652 bool CNetClientWorker::OnGameSetup(void* context, CFsmEvent* event) 589 653 { 590 654 ENSURE(event->GetType() == (uint)NMT_GAME_SETUP); 591 655 592 CNetClient * client = (CNetClient*)context;656 CNetClientWorker* client = (CNetClientWorker*)context; 593 657 JSContext* cx = client->GetScriptInterface().GetContext(); 594 658 JSAutoRequest rq(cx); 595 659 … … 605 669 return true; 606 670 } 607 671 608 bool CNetClient ::OnPlayerAssignment(void* context, CFsmEvent* event)672 bool CNetClientWorker::OnPlayerAssignment(void* context, CFsmEvent* event) 609 673 { 610 674 ENSURE(event->GetType() == (uint)NMT_PLAYER_ASSIGNMENT); 611 675 612 CNetClient * client = (CNetClient*)context;676 CNetClientWorker* client = (CNetClientWorker*)context; 613 677 614 678 CPlayerAssignmentMessage* message = (CPlayerAssignmentMessage*)event->GetParamRef(); 615 679 … … 632 696 return true; 633 697 } 634 698 635 bool CNetClient ::OnGameStart(void* context, CFsmEvent* event)699 bool CNetClientWorker::OnGameStart(void* context, CFsmEvent* event) 636 700 { 637 701 ENSURE(event->GetType() == (uint)NMT_GAME_START); 638 702 639 CNetClient * client = (CNetClient*)context;703 CNetClientWorker* client = (CNetClientWorker*)context; 640 704 JSContext* cx = client->GetScriptInterface().GetContext(); 641 705 JSAutoRequest rq(cx); 642 706 … … 658 722 return true; 659 723 } 660 724 661 bool CNetClient ::OnJoinSyncStart(void* context, CFsmEvent* event)725 bool CNetClientWorker::OnJoinSyncStart(void* context, CFsmEvent* event) 662 726 { 663 727 ENSURE(event->GetType() == (uint)NMT_JOIN_SYNC_START); 664 728 665 CNetClient * client = (CNetClient*)context;729 CNetClientWorker* client = (CNetClientWorker*)context; 666 730 667 731 // The server wants us to start downloading the game state from it, so do so 668 732 client->m_Session->GetFileTransferer().StartTask( … … 672 736 return true; 673 737 } 674 738 675 bool CNetClient ::OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event)739 bool CNetClientWorker::OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event) 676 740 { 677 741 ENSURE(event->GetType() == (uint)NMT_END_COMMAND_BATCH); 678 742 679 CNetClient * client = (CNetClient*)context;743 CNetClientWorker* client = (CNetClientWorker*)context; 680 744 681 745 CEndCommandBatchMessage* endMessage = (CEndCommandBatchMessage*)event->GetParamRef(); 682 746 … … 688 752 return true; 689 753 } 690 754 691 bool CNetClient ::OnRejoined(void* context, CFsmEvent* event)755 bool CNetClientWorker::OnRejoined(void* context, CFsmEvent* event) 692 756 { 693 757 ENSURE(event->GetType() == (uint)NMT_REJOINED); 694 758 695 CNetClient * client = (CNetClient*)context;759 CNetClientWorker* client = (CNetClientWorker*)context; 696 760 JSContext* cx = client->GetScriptInterface().GetContext(); 697 761 JSAutoRequest rq(cx); 698 762 … … 705 769 return true; 706 770 } 707 771 708 bool CNetClient ::OnKicked(void *context, CFsmEvent* event)772 bool CNetClientWorker::OnKicked(void *context, CFsmEvent* event) 709 773 { 710 774 ENSURE(event->GetType() == (uint)NMT_KICKED); 711 775 712 CNetClient * client = (CNetClient*)context;776 CNetClientWorker* client = (CNetClientWorker*)context; 713 777 JSContext* cx = client->GetScriptInterface().GetContext(); 714 778 JSAutoRequest rq(cx); 715 779 … … 725 789 return true; 726 790 } 727 791 728 bool CNetClient ::OnClientTimeout(void *context, CFsmEvent* event)792 bool CNetClientWorker::OnClientTimeout(void *context, CFsmEvent* event) 729 793 { 730 794 // Report the timeout of some other client 731 795 732 796 ENSURE(event->GetType() == (uint)NMT_CLIENT_TIMEOUT); 733 797 734 CNetClient * client = (CNetClient*)context;798 CNetClientWorker* client = (CNetClientWorker*)context; 735 799 JSContext* cx = client->GetScriptInterface().GetContext(); 736 800 JSAutoRequest rq(cx); 737 801 … … 749 813 return true; 750 814 } 751 815 752 bool CNetClient ::OnClientPerformance(void *context, CFsmEvent* event)816 bool CNetClientWorker::OnClientPerformance(void *context, CFsmEvent* event) 753 817 { 754 818 // Performance statistics for one or multiple clients 755 819 756 820 ENSURE(event->GetType() == (uint)NMT_CLIENT_PERFORMANCE); 757 821 758 CNetClient * client = (CNetClient*)context;822 CNetClientWorker* client = (CNetClientWorker*)context; 759 823 JSContext* cx = client->GetScriptInterface().GetContext(); 760 824 JSAutoRequest rq(cx); 761 825 … … 780 844 return true; 781 845 } 782 846 783 bool CNetClient ::OnClientsLoading(void *context, CFsmEvent *event)847 bool CNetClientWorker::OnClientsLoading(void *context, CFsmEvent *event) 784 848 { 785 849 ENSURE(event->GetType() == (uint)NMT_CLIENTS_LOADING); 786 850 … … 791 855 for (const CClientsLoadingMessage::S_m_Clients& client : message->m_Clients) 792 856 guids.push_back(client.m_GUID); 793 857 794 CNetClient * client = (CNetClient*)context;858 CNetClientWorker* client = (CNetClientWorker*)context; 795 859 JSContext* cx = client->GetScriptInterface().GetContext(); 796 860 JSAutoRequest rq(cx); 797 861 … … 802 866 return true; 803 867 } 804 868 805 bool CNetClient ::OnClientPaused(void *context, CFsmEvent *event)869 bool CNetClientWorker::OnClientPaused(void *context, CFsmEvent *event) 806 870 { 807 871 ENSURE(event->GetType() == (uint)NMT_CLIENT_PAUSED); 808 872 809 CNetClient * client = (CNetClient*)context;873 CNetClientWorker* client = (CNetClientWorker*)context; 810 874 JSContext* cx = client->GetScriptInterface().GetContext(); 811 875 JSAutoRequest rq(cx); 812 876 … … 821 885 return true; 822 886 } 823 887 824 bool CNetClient ::OnLoadedGame(void* context, CFsmEvent* event)888 bool CNetClientWorker::OnLoadedGame(void* context, CFsmEvent* event) 825 889 { 826 890 ENSURE(event->GetType() == (uint)NMT_LOADED_GAME); 827 891 828 CNetClient * client = (CNetClient*)context;892 CNetClientWorker* client = (CNetClientWorker*)context; 829 893 JSContext* cx = client->GetScriptInterface().GetContext(); 830 894 JSAutoRequest rq(cx); 831 895 … … 844 908 return true; 845 909 } 846 910 847 bool CNetClient ::OnInGame(void *context, CFsmEvent* event)911 bool CNetClientWorker::OnInGame(void *context, CFsmEvent* event) 848 912 { 849 913 // TODO: should split each of these cases into a separate method 850 914 851 CNetClient * client = (CNetClient*)context;915 CNetClientWorker* client = (CNetClientWorker*)context; 852 916 853 917 CNetMessage* message = (CNetMessage*)event->GetParamRef(); 854 918 if (message) … … 872 936 873 937 return true; 874 938 } 939 940 CNetClient::CNetClient(CGame* game, bool isLocalClient) : 941 m_Worker(new CNetClientWorker(game, isLocalClient)) 942 { 943 } 944 945 CNetClient::~CNetClient() 946 { 947 delete m_Worker; 948 } 949 950 void CNetClient::SetUserName(const CStrW& username) 951 { 952 m_Worker->m_UserName = username; 953 } 954 955 bool CNetClient::SetupConnection(const CStr& server, const u16 port) 956 { 957 return m_Worker->SetupConnection(server, port); 958 } 959 960 void CNetClient::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface) 961 { 962 m_Worker->SendGameSetupMessage(attrs, scriptInterface); 963 } 964 965 void CNetClient::SendStartGameMessage() 966 { 967 m_Worker->SendStartGameMessage(); 968 } 969 970 /** 971 * Call to kick/ban a client 972 */ 973 void CNetClient::SendKickPlayerMessage(const CStrW& playerName, bool ban) 974 { 975 m_Worker->SendKickPlayerMessage(playerName, ban); 976 } 977 978 void CNetClient::LoadFinished() 979 { 980 m_Worker->LoadFinished(); 981 } 982 983 void CNetClient::GuiPoll(JS::MutableHandleValue ret) 984 { 985 m_Worker->GuiPoll(ret); 986 } 987 988 ScriptInterface& CNetClient::GetScriptInterface() 989 { 990 return m_Worker->GetScriptInterface(); 991 } 992 993 void CNetClient::SendAssignPlayerMessage(const int playerID, const CStr& guid) 994 { 995 m_Worker->SendAssignPlayerMessage(playerID, guid); 996 } 997 998 void CNetClient::SendChatMessage(const std::wstring& text) 999 { 1000 m_Worker->SendChatMessage(text); 1001 } 1002 1003 void CNetClient::SendReadyMessage(const int status) 1004 { 1005 m_Worker->SendReadyMessage(status); 1006 } 1007 1008 void CNetClient::SendClearAllReadyMessage() 1009 { 1010 SendClearAllReadyMessage(); 1011 } 1012 1013 void CNetClient::SendPausedMessage(bool pause) 1014 { 1015 m_Worker->SendPausedMessage(pause); 1016 } -
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 { … … 70 73 virtual ~CNetClient(); 71 74 72 75 /** 73 * We assume that adding a tracing function that's only called74 * during GC is better for performance than using a75 * PersistentRooted<T> where each value needs to be added to76 * the root set.77 */78 static void Trace(JSTracer *trc, void *data)79 {80 reinterpret_cast<CNetClient*>(data)->TraceMember(trc);81 }82 83 void TraceMember(JSTracer *trc);84 85 /**86 76 * Set the user's name that will be displayed to all players. 87 77 * This must not be called after the connection setup. 88 78 */ … … 101 91 */ 102 92 bool SetupConnection(const CStr& server, const u16 port); 103 93 94 void SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface); 95 96 void SendStartGameMessage(); 97 104 98 /** 99 * Call to kick/ban a client 100 */ 101 void SendKickPlayerMessage(const CStrW& playerName, bool ban); 102 103 void LoadFinished(); 104 105 void GuiPoll(JS::MutableHandleValue ret); 106 107 void SendAssignPlayerMessage(const int playerID, const CStr& guid); 108 109 void SendChatMessage(const std::wstring& text); 110 111 void SendReadyMessage(const int status); 112 113 void SendClearAllReadyMessage(); 114 115 void SendPausedMessage(bool pause); 116 117 /** 118 * Get the script interface associated with this network client, 119 * which is equivalent to the one used by the CGame in the constructor. 120 */ 121 ScriptInterface& GetScriptInterface(); 122 123 private: 124 CStr m_GUID; 125 CNetClientWorker* m_Worker; 126 }; 127 128 /** 129 * Network client worker thread. 130 * 131 * Thread-safety: 132 * 133 * 134 */ 135 class CNetClientWorker : public CFsm 136 { 137 NONCOPYABLE(CNetClientWorker); 138 139 public: 140 /** 141 * Returns the GUID of the local client. 142 * Used for distinguishing observers. 143 */ 144 CStr GetGUID() const { return m_GUID; } 145 146 /** 147 * Send a message to the server. 148 * @param message message to send 149 * @return true on success 150 */ 151 bool SendMessage(const CNetMessage* message); 152 153 /** 154 * Call when the network connection has been successfully initiated. 155 */ 156 void HandleConnect(); 157 158 /** 159 * Call when the network connection has been lost. 160 */ 161 void HandleDisconnect(u32 reason); 162 163 /** 164 * Call when a message has been received from the network. 165 */ 166 bool HandleMessage(CNetMessage* message); 167 168 /** 169 * Get the script interface associated with this network client, 170 * which is equivalent to the one used by the CGame in the constructor. 171 */ 172 ScriptInterface& GetScriptInterface(); 173 174 private: 175 friend class CNetClient; 176 friend class CNetFileReceiveTask_ClientRejoin; 177 178 CNetClientWorker(CGame* game, bool isLocalClient); 179 ~CNetClientWorker(); 180 181 void SetUserName(const CStrW& username); 182 183 bool SetupConnection(const CStr& server, const u16 port); 184 185 /** 105 186 * Destroy the connection to the server. 106 187 * This client probably cannot be used again. 107 188 */ … … 139 220 * 140 221 * @return next message, or the value 'undefined' if the queue is empty 141 222 */ 142 void GuiPoll(JS::MutableHandleValue );223 void GuiPoll(JS::MutableHandleValue ret); 143 224 144 225 /** 145 226 * Add a message to the queue, to be read by GuiPoll. … … 154 235 std::string TestReadGuiMessages(); 155 236 156 237 /** 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 238 * Call when the game has started and all data files have been loaded, 186 239 * to signal to the server that we are ready to begin the game. 187 240 */ … … 215 268 */ 216 269 void SendPausedMessage(bool pause); 217 270 218 private:219 271 // Net message / FSM transition handlers 220 272 static bool OnConnect(void* context, CFsmEvent* event); 221 273 static bool OnHandshake(void* context, CFsmEvent* event); … … 282 334 283 335 /// Time when the server was last checked for timeouts and bad latency 284 336 std::time_t m_LastConnectionCheck; 337 338 // Thread-related stuff: 339 340 static void* RunThread(void* data); 341 void Run(); 342 bool RunStep(); 343 344 pthread_t m_WorkerThread; 345 CMutex m_WorkerMutex; 346 347 bool m_Shutdown; // protected by m_WorkerMutex 348 349 // Queues for messages sent by the game thread: 350 std::vector<bool> m_StartGameQueue; // protected by m_WorkerMutex 351 std::vector<std::string> m_GameAttributesQueue; // protected by m_WorkerMutex 352 std::vector<u32> m_TurnLengthQueue; // protected by m_WorkerMutex 285 353 }; 286 354 287 355 /// 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