From 6dba63b62270127cf8e3be2e3afa0fe2202b6e4f Mon Sep 17 00:00:00 2001
From: elexis <elexis1@users.noreply.github.com>
Date: Sat, 26 Nov 2016 02:09:32 +0100
Subject: [PATCH 1/2] Network server cleanup.
Require specifying the state of the target clients in Broadcast calls.
Removes the peculiarity of skipping rejoining clients in that function,
making it more versatile and less prone to errors.
---
source/network/NetServer.cpp | 29 +++++++++++++++--------------
source/network/NetServer.h | 5 ++---
source/network/NetTurnManager.cpp | 4 ++--
3 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/source/network/NetServer.cpp b/source/network/NetServer.cpp
index 38680d8..e3fc12c 100644
a
|
b
|
bool CNetServerWorker::SendMessage(ENetPeer* peer, const CNetMessage* message)
|
338 | 338 | return CNetHost::SendMessage(message, peer, DebugName(session).c_str()); |
339 | 339 | } |
340 | 340 | |
341 | | bool CNetServerWorker::Broadcast(const CNetMessage* message) |
| 341 | bool CNetServerWorker::Broadcast(const CNetMessage* message, std::vector<NetServerSessionState> targetStates) |
342 | 342 | { |
343 | 343 | ENSURE(m_Host); |
344 | 344 | |
345 | 345 | bool ok = true; |
346 | 346 | |
347 | | // Send to all sessions that are active and has finished authentication |
348 | 347 | // TODO: this does lots of repeated message serialisation if we have lots |
349 | 348 | // of remote peers; could do it more efficiently if that's a real problem |
| 349 | |
350 | 350 | for (CNetServerSession* session : m_Sessions) |
351 | | if (session->GetCurrState() == NSS_PREGAME || session->GetCurrState() == NSS_INGAME) |
| 351 | if (std::find(targetStates.begin(), targetStates.end(), session->GetCurrState()) != targetStates.end()) |
352 | 352 | if (!session->SendMessage(message)) |
353 | 353 | ok = false; |
354 | 354 | |
… |
… |
void CNetServerWorker::SendPlayerAssignments()
|
849 | 849 | { |
850 | 850 | CPlayerAssignmentMessage message; |
851 | 851 | ConstructPlayerAssignmentMessage(message); |
852 | | Broadcast(&message); |
| 852 | Broadcast(&message, { NSS_PREGAME, NSS_INGAME }); |
853 | 853 | } |
854 | 854 | |
855 | 855 | ScriptInterface& CNetServerWorker::GetScriptInterface() |
… |
… |
bool CNetServerWorker::OnInGame(void* context, CFsmEvent* event)
|
1050 | 1050 | if (!cheatsEnabled && (it == server.m_PlayerAssignments.end() || it->second.m_PlayerID != simMessage->m_Player)) |
1051 | 1051 | return true; |
1052 | 1052 | |
1053 | | // Send it back to all clients immediately |
1054 | | server.Broadcast(simMessage); |
| 1053 | // Send it back to all clients that have finished |
| 1054 | // the loading screen (and the synchronization when rejoining) |
| 1055 | server.Broadcast(simMessage, { NSS_INGAME }); |
1055 | 1056 | |
1056 | 1057 | // Save all the received commands |
1057 | 1058 | if (server.m_SavedCommands.size() < simMessage->m_Turn + 1) |
… |
… |
bool CNetServerWorker::OnChat(void* context, CFsmEvent* event)
|
1086 | 1087 | |
1087 | 1088 | message->m_GUID = session->GetGUID(); |
1088 | 1089 | |
1089 | | server.Broadcast(message); |
| 1090 | server.Broadcast(message, { NSS_PREGAME, NSS_INGAME} ); |
1090 | 1091 | |
1091 | 1092 | return true; |
1092 | 1093 | } |
… |
… |
bool CNetServerWorker::OnReady(void* context, CFsmEvent* event)
|
1102 | 1103 | |
1103 | 1104 | message->m_GUID = session->GetGUID(); |
1104 | 1105 | |
1105 | | server.Broadcast(message); |
| 1106 | server.Broadcast(message, { NSS_PREGAME } ); |
1106 | 1107 | server.SetPlayerReady(message->m_GUID, message->m_Status); |
1107 | 1108 | |
1108 | 1109 | return true; |
… |
… |
bool CNetServerWorker::OnRejoined(void* context, CFsmEvent* event)
|
1236 | 1237 | CNetServerSession* session = (CNetServerSession*)context; |
1237 | 1238 | CNetServerWorker& server = session->GetServer(); |
1238 | 1239 | |
| 1240 | // Inform everyone of the client having rejoined |
1239 | 1241 | CRejoinedMessage* message = (CRejoinedMessage*)event->GetParamRef(); |
1240 | | |
1241 | 1242 | message->m_GUID = session->GetGUID(); |
1242 | | |
1243 | | server.Broadcast(message); |
| 1243 | server.Broadcast(message, { NSS_INGAME }); |
1244 | 1244 | |
1245 | 1245 | // Send all pausing players to the rejoined client. |
1246 | 1246 | for (const CStr& guid : server.m_PausingPlayers) |
… |
… |
void CNetServerWorker::CheckGameLoadStatus(CNetServerSession* changedSession)
|
1326 | 1326 | if (session != changedSession && session->GetCurrState() != NSS_INGAME) |
1327 | 1327 | return; |
1328 | 1328 | |
| 1329 | // Inform clients that everyone has loaded the map and that the game can start |
1329 | 1330 | CLoadedGameMessage loaded; |
1330 | 1331 | loaded.m_CurrentTurn = 0; |
1331 | | Broadcast(&loaded); |
| 1332 | Broadcast(&loaded, { NSS_PREGAME }); |
1332 | 1333 | |
1333 | 1334 | m_State = SERVER_STATE_INGAME; |
1334 | 1335 | } |
… |
… |
void CNetServerWorker::StartGame()
|
1355 | 1356 | SendPlayerAssignments(); |
1356 | 1357 | |
1357 | 1358 | CGameStartMessage gameStart; |
1358 | | Broadcast(&gameStart); |
| 1359 | Broadcast(&gameStart, { NSS_PREGAME }); |
1359 | 1360 | } |
1360 | 1361 | |
1361 | 1362 | void CNetServerWorker::UpdateGameAttributes(JS::MutableHandleValue attrs) |
… |
… |
void CNetServerWorker::UpdateGameAttributes(JS::MutableHandleValue attrs)
|
1367 | 1368 | |
1368 | 1369 | CGameSetupMessage gameSetupMessage(GetScriptInterface()); |
1369 | 1370 | gameSetupMessage.m_Data = m_GameAttributes; |
1370 | | Broadcast(&gameSetupMessage); |
| 1371 | Broadcast(&gameSetupMessage, { NSS_PREGAME }); |
1371 | 1372 | } |
1372 | 1373 | |
1373 | 1374 | CStrW CNetServerWorker::SanitisePlayerName(const CStrW& original) |
diff --git a/source/network/NetServer.h b/source/network/NetServer.h
index 043b763..34f29a1 100644
a
|
b
|
public:
|
168 | 168 | void KickPlayer(const CStrW& playerName, const bool ban); |
169 | 169 | |
170 | 170 | /** |
171 | | * Send a message to all clients who have completed the full connection process |
172 | | * (i.e. are in the pre-game or in-game states). |
| 171 | * Send a message to all clients who match one of the given states. |
173 | 172 | */ |
174 | | bool Broadcast(const CNetMessage* message); |
| 173 | bool Broadcast(const CNetMessage* message, std::vector<NetServerSessionState> targetStates); |
175 | 174 | |
176 | 175 | private: |
177 | 176 | friend class CNetServer; |
diff --git a/source/network/NetTurnManager.cpp b/source/network/NetTurnManager.cpp
index 19bfb98..2dabb0f 100644
a
|
b
|
void CNetServerTurnManager::CheckClientsReady()
|
617 | 617 | CEndCommandBatchMessage msg; |
618 | 618 | msg.m_TurnLength = m_TurnLength; |
619 | 619 | msg.m_Turn = m_ReadyTurn; |
620 | | m_NetServer.Broadcast(&msg); |
| 620 | m_NetServer.Broadcast(&msg, { NSS_INGAME }); |
621 | 621 | |
622 | 622 | ENSURE(m_SavedTurnLengths.size() == m_ReadyTurn); |
623 | 623 | m_SavedTurnLengths.push_back(m_TurnLength); |
… |
… |
void CNetServerTurnManager::NotifyFinishedClientUpdate(int client, const CStrW&
|
676 | 676 | h.m_Name = playername; |
677 | 677 | msg.m_PlayerNames.push_back(h); |
678 | 678 | } |
679 | | m_NetServer.Broadcast(&msg); |
| 679 | m_NetServer.Broadcast(&msg, { NSS_INGAME }); |
680 | 680 | break; |
681 | 681 | } |
682 | 682 | } |