Changeset View
Changeset View
Standalone View
Standalone View
source/network/NetServerTurnManager.cpp
Show All 18 Lines | |||||
#include "NetMessage.h" | #include "NetMessage.h" | ||||
#include "NetServerTurnManager.h" | #include "NetServerTurnManager.h" | ||||
#include "NetServer.h" | #include "NetServer.h" | ||||
#include "NetSession.h" | #include "NetSession.h" | ||||
#include "lib/utf8.h" | #include "lib/utf8.h" | ||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||
#include "ps/ConfigDB.h" | |||||
#include "simulation2/system/TurnManager.h" | #include "simulation2/system/TurnManager.h" | ||||
#if 0 | #if 0 | ||||
#include "ps/Util.h" | #include "ps/Util.h" | ||||
#define NETSERVERTURN_LOG(...) debug_printf(__VA_ARGS__) | #define NETSERVERTURN_LOG(...) debug_printf(__VA_ARGS__) | ||||
#else | #else | ||||
#define NETSERVERTURN_LOG(...) | #define NETSERVERTURN_LOG(...) | ||||
#endif | #endif | ||||
Show All 33 Lines | void CNetServerTurnManager::NotifyFinishedClientCommands(CNetServerSession& session, u32 turn) | ||||
m_ClientsReady[client] = turn; | m_ClientsReady[client] = turn; | ||||
// Check whether this was the final client to become ready | // Check whether this was the final client to become ready | ||||
CheckClientsReady(); | CheckClientsReady(); | ||||
} | } | ||||
void CNetServerTurnManager::CheckClientsReady() | void CNetServerTurnManager::CheckClientsReady() | ||||
{ | { | ||||
int max_observer_lag = -1; | |||||
CFG_GET_VAL("network.observermaxlag", max_observer_lag); | |||||
// Clamp to 0-10000 seconds, below/above that is no limit. | |||||
Freagarach: Turns? | |||||
max_observer_lag = max_observer_lag < 0 ? -1 : max_observer_lag > 10000 ? -1 : max_observer_lag; | |||||
// See if all clients (including self) are ready for a new turn | // See if all clients (including self) are ready for a new turn | ||||
for (const std::pair<const int, u32>& clientReady : m_ClientsReady) | for (const std::pair<const int, u32>& clientReady : m_ClientsReady) | ||||
{ | { | ||||
// Observers are allowed to lag more than regular clients. | |||||
if (m_ClientsObserver[clientReady.first] && (max_observer_lag == -1 || clientReady.second > m_ReadyTurn - max_observer_lag)) | |||||
continue; | |||||
NETSERVERTURN_LOG(" %d: %d <=? %d\n", clientReady.first, clientReady.second, m_ReadyTurn); | NETSERVERTURN_LOG(" %d: %d <=? %d\n", clientReady.first, clientReady.second, m_ReadyTurn); | ||||
if (clientReady.second <= m_ReadyTurn) | if (clientReady.second <= m_ReadyTurn) | ||||
return; // wasn't ready for m_ReadyTurn+1 | return; // wasn't ready for m_ReadyTurn+1 | ||||
} | } | ||||
++m_ReadyTurn; | ++m_ReadyTurn; | ||||
NETSERVERTURN_LOG("CheckClientsReady: ready for turn %d\n", m_ReadyTurn); | NETSERVERTURN_LOG("CheckClientsReady: ready for turn %d\n", m_ReadyTurn); | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | for (const std::pair<const u32, std::map<int, std::string>>& clientStateHash : m_ClientStateHashes) | ||||
// Find all players that are OOS on that turn | // Find all players that are OOS on that turn | ||||
std::vector<CStrW> OOSPlayerNames; | std::vector<CStrW> OOSPlayerNames; | ||||
for (const std::pair<const int, std::string>& hashPair : clientStateHash.second) | for (const std::pair<const int, std::string>& hashPair : clientStateHash.second) | ||||
{ | { | ||||
NETSERVERTURN_LOG("sync check %d: %d = %hs\n", clientStateHash.first, hashPair.first, Hexify(hashPair.second).c_str()); | NETSERVERTURN_LOG("sync check %d: %d = %hs\n", clientStateHash.first, hashPair.first, Hexify(hashPair.second).c_str()); | ||||
if (hashPair.second != expected) | if (hashPair.second != expected) | ||||
{ | { | ||||
// Oh no, out of sync | // Oh no, out of sync | ||||
m_HasSyncError = true; | m_HasSyncError = true; | ||||
Done Inline ActionsIsn't it going to be reverted? vladislavbelov: Isn't it going to be reverted? | |||||
Not Done Inline ActionsLooks strange, clientStateHash.first is u32. vladislavbelov: Looks strange, `clientStateHash.first` is `u32`. | |||||
Not Done Inline ActionsStill. vladislavbelov: Still. | |||||
OOSPlayerNames.push_back(m_ClientPlayernames[hashPair.first]); | OOSPlayerNames.push_back(m_ClientPlayernames[hashPair.first]); | ||||
} | } | ||||
} | } | ||||
// Tell everyone about it | // Tell everyone about it | ||||
if (m_HasSyncError) | if (m_HasSyncError) | ||||
{ | { | ||||
CSyncErrorMessage msg; | CSyncErrorMessage msg; | ||||
Show All 9 Lines | if (m_HasSyncError) | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
// Delete the saved hashes for all turns that we've already verified | // Delete the saved hashes for all turns that we've already verified | ||||
m_ClientStateHashes.erase(m_ClientStateHashes.begin(), m_ClientStateHashes.lower_bound(newest+1)); | m_ClientStateHashes.erase(m_ClientStateHashes.begin(), m_ClientStateHashes.lower_bound(newest+1)); | ||||
} | } | ||||
void CNetServerTurnManager::InitialiseClient(int client, u32 turn) | void CNetServerTurnManager::InitialiseClient(int client, u32 turn, bool observer) | ||||
{ | { | ||||
NETSERVERTURN_LOG("InitialiseClient(client=%d, turn=%d)\n", client, turn); | NETSERVERTURN_LOG("InitialiseClient(client=%d, turn=%d)\n", client, turn); | ||||
ENSURE(m_ClientsReady.find(client) == m_ClientsReady.end()); | ENSURE(m_ClientsReady.find(client) == m_ClientsReady.end()); | ||||
m_ClientsReady[client] = turn + COMMAND_DELAY_MP - 1; | m_ClientsReady[client] = turn + COMMAND_DELAY_MP - 1; | ||||
m_ClientsSimulated[client] = turn; | m_ClientsSimulated[client] = turn; | ||||
m_ClientsObserver[client] = observer; | |||||
} | } | ||||
void CNetServerTurnManager::UninitialiseClient(int client) | void CNetServerTurnManager::UninitialiseClient(int client) | ||||
{ | { | ||||
NETSERVERTURN_LOG("UninitialiseClient(client=%d)\n", client); | NETSERVERTURN_LOG("UninitialiseClient(client=%d)\n", client); | ||||
ENSURE(m_ClientsReady.find(client) != m_ClientsReady.end()); | ENSURE(m_ClientsReady.find(client) != m_ClientsReady.end()); | ||||
m_ClientsReady.erase(client); | m_ClientsReady.erase(client); | ||||
m_ClientsSimulated.erase(client); | m_ClientsSimulated.erase(client); | ||||
m_ClientsObserver.erase(client); | |||||
// Check whether we're ready for the next turn now that we're not | // Check whether we're ready for the next turn now that we're not | ||||
// waiting for this client any more | // waiting for this client any more | ||||
CheckClientsReady(); | CheckClientsReady(); | ||||
} | } | ||||
void CNetServerTurnManager::SetTurnLength(u32 msecs) | void CNetServerTurnManager::SetTurnLength(u32 msecs) | ||||
{ | { | ||||
m_TurnLength = msecs; | m_TurnLength = msecs; | ||||
} | } | ||||
u32 CNetServerTurnManager::GetSavedTurnLength(u32 turn) | u32 CNetServerTurnManager::GetSavedTurnLength(u32 turn) | ||||
{ | { | ||||
ENSURE(turn <= m_ReadyTurn); | ENSURE(turn <= m_ReadyTurn); | ||||
return m_SavedTurnLengths.at(turn); | return m_SavedTurnLengths.at(turn); | ||||
} | } |
Wildfire Games · Phabricator
Turns?