Cleanup of the network code (range-based for, remove spaces between angle brackets, and other little things).
Based on a patch by elexis, fixes #3907 This was SVN commit r18091.
This commit is contained in:
parent
c856bc296d
commit
d70062c348
@ -172,14 +172,10 @@ function getNetworkWarnings()
|
||||
{
|
||||
// Remove outdated messages
|
||||
for (let guid in g_NetworkWarnings)
|
||||
{
|
||||
if (Date.now() > g_NetworkWarnings[guid].added + g_NetworkWarningTimeout)
|
||||
if (Date.now() > g_NetworkWarnings[guid].added + g_NetworkWarningTimeout ||
|
||||
guid != "server" && !g_PlayerAssignments[guid])
|
||||
delete g_NetworkWarnings[guid];
|
||||
|
||||
if (guid != "server" && !g_PlayerAssignments[guid])
|
||||
delete g_NetworkWarnings[guid];
|
||||
}
|
||||
|
||||
// Show local messages first
|
||||
let guids = Object.keys(g_NetworkWarnings).sort(guid => guid != "server");
|
||||
|
||||
|
@ -140,9 +140,8 @@ CNetClient::~CNetClient()
|
||||
|
||||
void CNetClient::TraceMember(JSTracer *trc)
|
||||
{
|
||||
std::deque<JS::Heap<JS::Value> >::iterator itr;
|
||||
for (itr=m_GuiMessageQueue.begin(); itr != m_GuiMessageQueue.end(); ++itr)
|
||||
JS_CallHeapValueTracer(trc, &*itr, "m_GuiMessageQueue");
|
||||
for (JS::Heap<JS::Value>& guiMessage : m_GuiMessageQueue)
|
||||
JS_CallHeapValueTracer(trc, &guiMessage, "m_GuiMessageQueue");
|
||||
}
|
||||
|
||||
void CNetClient::SetUserName(const CStrW& username)
|
||||
@ -278,14 +277,14 @@ void CNetClient::PostPlayerAssignmentsToScript()
|
||||
JS::RootedValue hosts(cx);
|
||||
GetScriptInterface().GetProperty(msg, "hosts", &hosts);
|
||||
|
||||
for (PlayerAssignmentMap::iterator it = m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it)
|
||||
for (const std::pair<CStr, PlayerAssignment>& p : m_PlayerAssignments)
|
||||
{
|
||||
JS::RootedValue host(cx);
|
||||
GetScriptInterface().Eval("({})", &host);
|
||||
GetScriptInterface().SetProperty(host, "name", std::wstring(it->second.m_Name), false);
|
||||
GetScriptInterface().SetProperty(host, "player", it->second.m_PlayerID, false);
|
||||
GetScriptInterface().SetProperty(host, "status", it->second.m_Status, false);
|
||||
GetScriptInterface().SetProperty(hosts, it->first.c_str(), host, false);
|
||||
GetScriptInterface().SetProperty(host, "name", std::wstring(p.second.m_Name), false);
|
||||
GetScriptInterface().SetProperty(host, "player", p.second.m_PlayerID, false);
|
||||
GetScriptInterface().SetProperty(host, "status", p.second.m_Status, false);
|
||||
GetScriptInterface().SetProperty(hosts, p.first.c_str(), host, false);
|
||||
}
|
||||
|
||||
PushGuiMessage(msg);
|
||||
@ -709,18 +708,17 @@ bool CNetClient::OnClientPerformance(void *context, CFsmEvent* event)
|
||||
return true;
|
||||
|
||||
CClientPerformanceMessage* message = (CClientPerformanceMessage*)event->GetParamRef();
|
||||
std::vector<CClientPerformanceMessage::S_m_Clients> &clients = message->m_Clients;
|
||||
|
||||
// Display warnings for other clients with bad ping
|
||||
for (size_t i = 0; i < clients.size(); ++i)
|
||||
for (size_t i = 0; i < message->m_Clients.size(); ++i)
|
||||
{
|
||||
if (clients[i].m_MeanRTT < DEFAULT_TURN_LENGTH_MP || clients[i].m_GUID == client->m_GUID)
|
||||
if (message->m_Clients[i].m_MeanRTT < DEFAULT_TURN_LENGTH_MP || message->m_Clients[i].m_GUID == client->m_GUID)
|
||||
continue;
|
||||
|
||||
JS::RootedValue msg(cx);
|
||||
client->GetScriptInterface().Eval("({ 'type':'netwarn', 'warntype': 'client-latency' })", &msg);
|
||||
client->GetScriptInterface().SetProperty(msg, "guid", clients[i].m_GUID);
|
||||
client->GetScriptInterface().SetProperty(msg, "meanRTT", clients[i].m_MeanRTT);
|
||||
client->GetScriptInterface().SetProperty(msg, "guid", message->m_Clients[i].m_GUID);
|
||||
client->GetScriptInterface().SetProperty(msg, "meanRTT", message->m_Clients[i].m_MeanRTT);
|
||||
client->PushGuiMessage(msg);
|
||||
}
|
||||
|
||||
|
@ -249,7 +249,7 @@ private:
|
||||
CStr m_GUID;
|
||||
|
||||
/// Queue of messages for GuiPoll
|
||||
std::deque<JS::Heap<JS::Value> > m_GuiMessageQueue;
|
||||
std::deque<JS::Heap<JS::Value>> m_GuiMessageQueue;
|
||||
|
||||
/// Serialized game state received when joining an in-progress game
|
||||
std::string m_JoinSyncBuffer;
|
||||
|
@ -1,3 +1,20 @@
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 0 A.D. is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "NetFileTransfer.h"
|
||||
@ -141,16 +158,18 @@ void CNetFileTransferer::Poll()
|
||||
{
|
||||
// Find tasks which have fewer packets in flight than their window size,
|
||||
// and send more packets
|
||||
for (FileSendTasksMap::iterator it = m_FileSendTasks.begin(); it != m_FileSendTasks.end(); ++it)
|
||||
for (std::pair<const u32, CNetFileSendTask>& p : m_FileSendTasks)
|
||||
{
|
||||
while (it->second.packetsInFlight < it->second.maxWindowSize && it->second.offset < it->second.buffer.size())
|
||||
CNetFileSendTask& task = p.second;
|
||||
|
||||
while (task.packetsInFlight < task.maxWindowSize && task.offset < task.buffer.size())
|
||||
{
|
||||
CFileTransferDataMessage dataMessage;
|
||||
dataMessage.m_RequestID = it->second.requestID;
|
||||
ssize_t packetSize = std::min(DEFAULT_FILE_TRANSFER_PACKET_SIZE, it->second.buffer.size() - it->second.offset);
|
||||
dataMessage.m_Data = it->second.buffer.substr(it->second.offset, packetSize);
|
||||
it->second.offset += packetSize;
|
||||
it->second.packetsInFlight++;
|
||||
dataMessage.m_RequestID = task.requestID;
|
||||
ssize_t packetSize = std::min(DEFAULT_FILE_TRANSFER_PACKET_SIZE, task.buffer.size() - task.offset);
|
||||
dataMessage.m_Data = task.buffer.substr(task.offset, packetSize);
|
||||
task.offset += packetSize;
|
||||
++task.packetsInFlight;
|
||||
m_Session->SendMessage(&dataMessage);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2011 Wildfire Games.
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -121,7 +121,7 @@ private:
|
||||
|
||||
u32 m_NextRequestID;
|
||||
|
||||
typedef std::map<u32, shared_ptr<CNetFileReceiveTask> > FileReceiveTasksMap;
|
||||
typedef std::map<u32, shared_ptr<CNetFileReceiveTask>> FileReceiveTasksMap;
|
||||
FileReceiveTasksMap m_FileReceiveTasks;
|
||||
|
||||
typedef std::map<u32, CNetFileSendTask> FileSendTasksMap;
|
||||
|
@ -90,11 +90,11 @@ public:
|
||||
|
||||
// Find the session corresponding to the rejoining host (if any)
|
||||
CNetServerSession* session = NULL;
|
||||
for (size_t i = 0; i < m_Server.m_Sessions.size(); ++i)
|
||||
for (CNetServerSession* serverSession : m_Server.m_Sessions)
|
||||
{
|
||||
if (m_Server.m_Sessions[i]->GetHostID() == m_RejoinerHostID)
|
||||
if (serverSession->GetHostID() == m_RejoinerHostID)
|
||||
{
|
||||
session = m_Server.m_Sessions[i];
|
||||
session = serverSession;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -157,16 +157,14 @@ CNetServerWorker::~CNetServerWorker()
|
||||
|
||||
delete m_Stats;
|
||||
|
||||
for (size_t i = 0; i < m_Sessions.size(); ++i)
|
||||
for (CNetServerSession* session : m_Sessions)
|
||||
{
|
||||
m_Sessions[i]->DisconnectNow(NDR_SERVER_SHUTDOWN);
|
||||
delete m_Sessions[i];
|
||||
session->DisconnectNow(NDR_SERVER_SHUTDOWN);
|
||||
delete session;
|
||||
}
|
||||
|
||||
if (m_Host)
|
||||
{
|
||||
enet_host_destroy(m_Host);
|
||||
}
|
||||
|
||||
delete m_ServerTurnManager;
|
||||
}
|
||||
@ -346,18 +344,13 @@ bool CNetServerWorker::Broadcast(const CNetMessage* message)
|
||||
bool ok = true;
|
||||
|
||||
// Send to all sessions that are active and has finished authentication
|
||||
for (size_t i = 0; i < m_Sessions.size(); ++i)
|
||||
{
|
||||
if (m_Sessions[i]->GetCurrState() == NSS_PREGAME || m_Sessions[i]->GetCurrState() == NSS_INGAME)
|
||||
{
|
||||
if (!m_Sessions[i]->SendMessage(message))
|
||||
// TODO: this does lots of repeated message serialisation if we have lots
|
||||
// of remote peers; could do it more efficiently if that's a real problem
|
||||
for (CNetServerSession* session : m_Sessions)
|
||||
if (session->GetCurrState() == NSS_PREGAME || session->GetCurrState() == NSS_INGAME)
|
||||
if (!session->SendMessage(message))
|
||||
ok = false;
|
||||
|
||||
// TODO: this does lots of repeated message serialisation if we have lots
|
||||
// of remote peers; could do it more efficiently if that's a real problem
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -411,9 +404,9 @@ bool CNetServerWorker::RunStep()
|
||||
JSContext* cx = m_ScriptInterface->GetContext();
|
||||
JSAutoRequest rq(cx);
|
||||
|
||||
std::vector<std::pair<int, CStr> > newAssignPlayer;
|
||||
std::vector<std::pair<int, CStr>> newAssignPlayer;
|
||||
std::vector<bool> newStartGame;
|
||||
std::vector<std::pair<CStr, int> > newPlayerReady;
|
||||
std::vector<std::pair<CStr, int>> newPlayerReady;
|
||||
std::vector<bool> newPlayerResetReady;
|
||||
std::vector<std::string> newGameAttributes;
|
||||
std::vector<u32> newTurnLength;
|
||||
@ -432,11 +425,11 @@ bool CNetServerWorker::RunStep()
|
||||
newTurnLength.swap(m_TurnLengthQueue);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < newAssignPlayer.size(); ++i)
|
||||
AssignPlayer(newAssignPlayer[i].first, newAssignPlayer[i].second);
|
||||
for (const std::pair<int, CStr8>& p : newAssignPlayer)
|
||||
AssignPlayer(p.first, p.second);
|
||||
|
||||
for (size_t i = 0; i < newPlayerReady.size(); ++i)
|
||||
SetPlayerReady(newPlayerReady[i].first, newPlayerReady[i].second);
|
||||
for (const std::pair<CStr8, int>& p : newPlayerReady)
|
||||
SetPlayerReady(p.first, p.second);
|
||||
|
||||
if (!newPlayerResetReady.empty())
|
||||
ClearAllPlayerReady();
|
||||
@ -456,8 +449,8 @@ bool CNetServerWorker::RunStep()
|
||||
StartGame();
|
||||
|
||||
// Perform file transfers
|
||||
for (size_t i = 0; i < m_Sessions.size(); ++i)
|
||||
m_Sessions[i]->GetFileTransferer().Poll();
|
||||
for (CNetServerSession* session : m_Sessions)
|
||||
session->GetFileTransferer().Poll();
|
||||
|
||||
CheckClientConnections();
|
||||
|
||||
@ -635,8 +628,7 @@ void CNetServerWorker::HandleMessageReceive(const CNetMessage* message, CNetServ
|
||||
}
|
||||
|
||||
// Update FSM
|
||||
bool ok = session->Update(message->GetType(), (void*)message);
|
||||
if (!ok)
|
||||
if (!session->Update(message->GetType(), (void*)message))
|
||||
LOGERROR("Net server: Error running FSM update (type=%d state=%d)", (int)message->GetType(), (int)session->GetCurrState());
|
||||
}
|
||||
|
||||
@ -719,9 +711,9 @@ void CNetServerWorker::AddPlayer(const CStr& guid, const CStrW& name)
|
||||
{
|
||||
// Find all player IDs in active use; we mustn't give them to a second player (excluding the unassigned ID: -1)
|
||||
std::set<i32> usedIDs;
|
||||
for (PlayerAssignmentMap::iterator it = m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it)
|
||||
if (it->second.m_Enabled && it->second.m_PlayerID != -1)
|
||||
usedIDs.insert(it->second.m_PlayerID);
|
||||
for (const std::pair<CStr, PlayerAssignment>& p : m_PlayerAssignments)
|
||||
if (p.second.m_Enabled && p.second.m_PlayerID != -1)
|
||||
usedIDs.insert(p.second.m_PlayerID);
|
||||
|
||||
// If the player is rejoining after disconnecting, try to give them
|
||||
// back their old player ID
|
||||
@ -824,10 +816,10 @@ bool CNetServerWorker::KickPlayer(const CStrW& playerName, const bool ban)
|
||||
void CNetServerWorker::AssignPlayer(int playerID, const CStr& guid)
|
||||
{
|
||||
// Remove anyone who's already assigned to this player
|
||||
for (PlayerAssignmentMap::iterator it = m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it)
|
||||
for (std::pair<const CStr, PlayerAssignment>& p : m_PlayerAssignments)
|
||||
{
|
||||
if (it->second.m_PlayerID == playerID)
|
||||
it->second.m_PlayerID = -1;
|
||||
if (p.second.m_PlayerID == playerID)
|
||||
p.second.m_PlayerID = -1;
|
||||
}
|
||||
|
||||
// Update this host's assignment if it exists
|
||||
@ -839,16 +831,16 @@ void CNetServerWorker::AssignPlayer(int playerID, const CStr& guid)
|
||||
|
||||
void CNetServerWorker::ConstructPlayerAssignmentMessage(CPlayerAssignmentMessage& message)
|
||||
{
|
||||
for (PlayerAssignmentMap::iterator it = m_PlayerAssignments.begin(); it != m_PlayerAssignments.end(); ++it)
|
||||
for (const std::pair<CStr, PlayerAssignment>& p : m_PlayerAssignments)
|
||||
{
|
||||
if (!it->second.m_Enabled)
|
||||
if (!p.second.m_Enabled)
|
||||
continue;
|
||||
|
||||
CPlayerAssignmentMessage::S_m_Hosts h;
|
||||
h.m_GUID = it->first;
|
||||
h.m_Name = it->second.m_Name;
|
||||
h.m_PlayerID = it->second.m_PlayerID;
|
||||
h.m_Status = it->second.m_Status;
|
||||
h.m_GUID = p.first;
|
||||
h.m_Name = p.second.m_Name;
|
||||
h.m_PlayerID = p.second.m_PlayerID;
|
||||
h.m_Status = p.second.m_Status;
|
||||
message.m_Hosts.push_back(h);
|
||||
}
|
||||
}
|
||||
@ -955,18 +947,20 @@ bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event)
|
||||
int disconnectedPlayers = 0;
|
||||
int connectedPlayers = 0;
|
||||
// (TODO: if GUIDs were stable, we should use them instead)
|
||||
for (PlayerAssignmentMap::iterator it = server.m_PlayerAssignments.begin(); it != server.m_PlayerAssignments.end(); ++it)
|
||||
for (const std::pair<CStr, PlayerAssignment>& p : server.m_PlayerAssignments)
|
||||
{
|
||||
if (!it->second.m_Enabled && it->second.m_Name == username)
|
||||
const PlayerAssignment& assignment = p.second;
|
||||
|
||||
if (!assignment.m_Enabled && assignment.m_Name == username)
|
||||
{
|
||||
isObserver = it->second.m_PlayerID == -1;
|
||||
isObserver = assignment.m_PlayerID == -1;
|
||||
isRejoining = true;
|
||||
}
|
||||
|
||||
if (it->second.m_PlayerID == -1)
|
||||
if (assignment.m_PlayerID == -1)
|
||||
continue;
|
||||
|
||||
if (it->second.m_Enabled)
|
||||
if (assignment.m_Enabled)
|
||||
++connectedPlayers;
|
||||
else
|
||||
++disconnectedPlayers;
|
||||
@ -1208,9 +1202,9 @@ bool CNetServerWorker::OnDisconnect(void* context, CFsmEvent* event)
|
||||
|
||||
void CNetServerWorker::CheckGameLoadStatus(CNetServerSession* changedSession)
|
||||
{
|
||||
for (size_t i = 0; i < m_Sessions.size(); ++i)
|
||||
for (const CNetServerSession* session : m_Sessions)
|
||||
{
|
||||
if (m_Sessions[i] != changedSession && m_Sessions[i]->GetCurrState() != NSS_INGAME)
|
||||
if (session != changedSession && session->GetCurrState() != NSS_INGAME)
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1225,8 +1219,8 @@ void CNetServerWorker::StartGame()
|
||||
{
|
||||
m_ServerTurnManager = new CNetServerTurnManager(*this);
|
||||
|
||||
for (size_t i = 0; i < m_Sessions.size(); ++i)
|
||||
m_ServerTurnManager->InitialiseClient(m_Sessions[i]->GetHostID(), 0); // TODO: only for non-observers
|
||||
for (const CNetServerSession* session : m_Sessions)
|
||||
m_ServerTurnManager->InitialiseClient(session->GetHostID(), 0); // TODO: only for non-observers
|
||||
|
||||
m_State = SERVER_STATE_LOADING;
|
||||
|
||||
@ -1289,9 +1283,9 @@ CStrW CNetServerWorker::DeduplicatePlayerName(const CStrW& original)
|
||||
while (true)
|
||||
{
|
||||
bool unique = true;
|
||||
for (size_t i = 0; i < m_Sessions.size(); ++i)
|
||||
for (const CNetServerSession* session : m_Sessions)
|
||||
{
|
||||
if (m_Sessions[i]->GetUserName() == name)
|
||||
if (session->GetUserName() == name)
|
||||
{
|
||||
unique = false;
|
||||
break;
|
||||
|
@ -327,7 +327,7 @@ private:
|
||||
* turn number, to simplify support for rejoining etc.
|
||||
* TODO: verify this doesn't use too much RAM.
|
||||
*/
|
||||
std::vector<std::vector<CSimulationMessage> > m_SavedCommands;
|
||||
std::vector<std::vector<CSimulationMessage>> m_SavedCommands;
|
||||
|
||||
/**
|
||||
* The latest copy of the simulation state, received from an existing
|
||||
@ -361,9 +361,9 @@ private:
|
||||
bool m_Shutdown; // protected by m_WorkerMutex
|
||||
|
||||
// Queues for messages sent by the game thread:
|
||||
std::vector<std::pair<int, CStr> > m_AssignPlayerQueue; // protected by m_WorkerMutex
|
||||
std::vector<std::pair<int, CStr>> m_AssignPlayerQueue; // protected by m_WorkerMutex
|
||||
std::vector<bool> m_StartGameQueue; // protected by m_WorkerMutex
|
||||
std::vector<std::pair<CStr, int> > m_PlayerReadyQueue; // protected by m_WorkerMutex
|
||||
std::vector<std::pair<CStr, int>> m_PlayerReadyQueue; // protected by m_WorkerMutex
|
||||
std::vector<bool> m_PlayerResetReadyQueue; // protected by m_WorkerMutex
|
||||
std::vector<std::string> m_GameAttributesQueue; // protected by m_WorkerMutex
|
||||
std::vector<u32> m_TurnLengthQueue; // protected by m_WorkerMutex
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -69,10 +69,9 @@ const std::vector<ProfileColumn>& CNetStatsTable::GetColumns()
|
||||
{
|
||||
m_ColumnDescriptions.clear();
|
||||
m_ColumnDescriptions.push_back(ProfileColumn("Name", 200));
|
||||
|
||||
if (m_Peer)
|
||||
{
|
||||
m_ColumnDescriptions.push_back(ProfileColumn("Value", 80));
|
||||
}
|
||||
else
|
||||
{
|
||||
CScopeLock lock(m_Mutex);
|
||||
@ -80,6 +79,7 @@ const std::vector<ProfileColumn>& CNetStatsTable::GetColumns()
|
||||
for (size_t i = 0; i < m_LatchedData.size(); ++i)
|
||||
m_ColumnDescriptions.push_back(ProfileColumn("Peer "+CStr::FromUInt(i), 80));
|
||||
}
|
||||
|
||||
return m_ColumnDescriptions;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2010 Wildfire Games.
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -54,7 +54,7 @@ private:
|
||||
std::vector<ProfileColumn> m_ColumnDescriptions;
|
||||
|
||||
CMutex m_Mutex;
|
||||
std::vector<std::vector<CStr> > m_LatchedData; // protected by m_Mutex
|
||||
std::vector<std::vector<CStr>> m_LatchedData; // protected by m_Mutex
|
||||
};
|
||||
|
||||
#endif // INCLUDED_NETSTATS
|
||||
|
@ -170,10 +170,9 @@ bool CNetTurnManager::Update(float simFrameLength, size_t maxTurns)
|
||||
|
||||
// Put all the client commands into a single list, in a globally consistent order
|
||||
std::vector<SimulationCommand> commands;
|
||||
for (std::map<u32, std::vector<SimulationCommand> >::iterator it = m_QueuedCommands[0].begin(); it != m_QueuedCommands[0].end(); ++it)
|
||||
{
|
||||
commands.insert(commands.end(), std::make_move_iterator(it->second.begin()), std::make_move_iterator(it->second.end()));
|
||||
}
|
||||
for (std::pair<const u32, std::vector<SimulationCommand>>& p : m_QueuedCommands[0])
|
||||
commands.insert(commands.end(), std::make_move_iterator(p.second.begin()), std::make_move_iterator(p.second.end()));
|
||||
|
||||
m_QueuedCommands.pop_front();
|
||||
m_QueuedCommands.resize(m_QueuedCommands.size() + 1);
|
||||
|
||||
@ -214,10 +213,9 @@ bool CNetTurnManager::UpdateFastForward()
|
||||
|
||||
// Put all the client commands into a single list, in a globally consistent order
|
||||
std::vector<SimulationCommand> commands;
|
||||
for (std::map<u32, std::vector<SimulationCommand> >::iterator it = m_QueuedCommands[0].begin(); it != m_QueuedCommands[0].end(); ++it)
|
||||
{
|
||||
commands.insert(commands.end(), std::make_move_iterator(it->second.begin()), std::make_move_iterator(it->second.end()));
|
||||
}
|
||||
for (std::pair<const u32, std::vector<SimulationCommand>>& p : m_QueuedCommands[0])
|
||||
commands.insert(commands.end(), std::make_move_iterator(p.second.begin()), std::make_move_iterator(p.second.end()));
|
||||
|
||||
m_QueuedCommands.pop_front();
|
||||
m_QueuedCommands.resize(m_QueuedCommands.size() + 1);
|
||||
|
||||
@ -564,11 +562,11 @@ void CNetReplayTurnManager::DoTurn(u32 turn)
|
||||
m_TurnLength = m_ReplayTurnLengths[turn];
|
||||
|
||||
// Simulate commands for that turn
|
||||
for (const std::pair<player_id_t, std::string>& pair : m_ReplayCommands[turn])
|
||||
for (const std::pair<player_id_t, std::string>& p : m_ReplayCommands[turn])
|
||||
{
|
||||
JS::RootedValue command(m_Simulation2.GetScriptInterface().GetContext());
|
||||
m_Simulation2.GetScriptInterface().ParseJSON(pair.second, &command);
|
||||
AddCommand(m_ClientId, pair.first, command, m_CurrentTurn + 1);
|
||||
m_Simulation2.GetScriptInterface().ParseJSON(p.second, &command);
|
||||
AddCommand(m_ClientId, p.first, command, m_CurrentTurn + 1);
|
||||
}
|
||||
|
||||
if (turn == m_FinalTurn)
|
||||
@ -602,10 +600,10 @@ void CNetServerTurnManager::NotifyFinishedClientCommands(int client, u32 turn)
|
||||
void CNetServerTurnManager::CheckClientsReady()
|
||||
{
|
||||
// See if all clients (including self) are ready for a new turn
|
||||
for (std::map<int, u32>::iterator it = m_ClientsReady.begin(); it != m_ClientsReady.end(); ++it)
|
||||
for (const std::pair<int, u32>& clientReady : m_ClientsReady)
|
||||
{
|
||||
NETTURN_LOG((L" %d: %d <=? %d\n", it->first, it->second, m_ReadyTurn));
|
||||
if (it->second <= m_ReadyTurn)
|
||||
NETTURN_LOG((L" %d: %d <=? %d\n", clientReady.first, clientReady.second, m_ReadyTurn));
|
||||
if (clientReady.second <= m_ReadyTurn)
|
||||
return; // wasn't ready for m_ReadyTurn+1
|
||||
}
|
||||
|
||||
@ -640,31 +638,29 @@ void CNetServerTurnManager::NotifyFinishedClientUpdate(int client, const CStrW&
|
||||
|
||||
// Find the newest turn which we know all clients have simulated
|
||||
u32 newest = std::numeric_limits<u32>::max();
|
||||
for (std::map<int, u32>::iterator it = m_ClientsSimulated.begin(); it != m_ClientsSimulated.end(); ++it)
|
||||
{
|
||||
if (it->second < newest)
|
||||
newest = it->second;
|
||||
}
|
||||
for (const std::pair<int, u32>& clientSimulated : m_ClientsSimulated)
|
||||
if (clientSimulated.second < newest)
|
||||
newest = clientSimulated.second;
|
||||
|
||||
// For every set of state hashes that all clients have simulated, check for OOS
|
||||
for (std::map<u32, std::map<int, std::string> >::iterator it = m_ClientStateHashes.begin(); it != m_ClientStateHashes.end(); ++it)
|
||||
for (const std::pair<u32, std::map<int, std::string>>& clientStateHash : m_ClientStateHashes)
|
||||
{
|
||||
if (it->first > newest)
|
||||
if (clientStateHash.first > newest)
|
||||
break;
|
||||
|
||||
// Assume the host is correct (maybe we should choose the most common instead to help debugging)
|
||||
std::string expected = it->second.begin()->second;
|
||||
std::string expected = clientStateHash.second.begin()->second;
|
||||
|
||||
// Find all players that are OOS on that turn
|
||||
std::vector<CStrW> OOSPlayerNames;
|
||||
for (std::map<int, std::string>::iterator cit = it->second.begin(); cit != it->second.end(); ++cit)
|
||||
for (const std::pair<int, std::string>& hashPair : clientStateHash.second)
|
||||
{
|
||||
NETTURN_LOG((L"sync check %d: %d = %hs\n", it->first, cit->first, Hexify(cit->second).c_str()));
|
||||
if (cit->second != expected)
|
||||
if (hashPair.second != expected)
|
||||
{
|
||||
// Oh no, out of sync
|
||||
m_HasSyncError = true;
|
||||
OOSPlayerNames.push_back(m_ClientPlayernames[cit->first]);
|
||||
OOSPlayerNames.push_back(m_ClientPlayernames[hashPair.first]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -672,7 +668,7 @@ void CNetServerTurnManager::NotifyFinishedClientUpdate(int client, const CStrW&
|
||||
if (m_HasSyncError)
|
||||
{
|
||||
CSyncErrorMessage msg;
|
||||
msg.m_Turn = it->first;
|
||||
msg.m_Turn = clientStateHash.first;
|
||||
msg.m_HashExpected = expected;
|
||||
for (const CStrW& playername : OOSPlayerNames)
|
||||
{
|
||||
|
@ -180,7 +180,7 @@ protected:
|
||||
u32 m_TurnLength;
|
||||
|
||||
/// Commands queued at each turn (index 0 is for m_CurrentTurn+1)
|
||||
std::deque<std::map<u32, std::vector<SimulationCommand> > > m_QueuedCommands;
|
||||
std::deque<std::map<u32, std::vector<SimulationCommand>>> m_QueuedCommands;
|
||||
|
||||
int m_PlayerId;
|
||||
uint m_ClientId;
|
||||
@ -272,13 +272,13 @@ protected:
|
||||
void DoTurn(u32 turn);
|
||||
|
||||
// Contains the commands of every player on each turn
|
||||
std::map<u32, std::vector<std::pair<player_id_t, std::string> > > m_ReplayCommands;
|
||||
std::map<u32, std::vector<std::pair<player_id_t, std::string>>> m_ReplayCommands;
|
||||
|
||||
// Contains the length of every turn
|
||||
std::map<u32, u32> m_ReplayTurnLengths;
|
||||
|
||||
// Contains all replay hash values and weather or not the quick hash method was used
|
||||
std::map<u32, std::pair<std::string, bool> > m_ReplayHash;
|
||||
std::map<u32, std::pair<std::string, bool>> m_ReplayHash;
|
||||
};
|
||||
/**
|
||||
* The server-side counterpart to CNetClientTurnManager.
|
||||
@ -337,7 +337,7 @@ protected:
|
||||
std::map<int, u32> m_ClientsSimulated;
|
||||
|
||||
// Map of turn -> {Client ID -> state hash}; old indexes <= min(m_ClientsSimulated) are deleted
|
||||
std::map<u32, std::map<int, std::string> > m_ClientStateHashes;
|
||||
std::map<u32, std::map<int, std::string>> m_ClientStateHashes;
|
||||
|
||||
// Map of client ID -> playername
|
||||
std::map<u32, CStrW> m_ClientPlayernames;
|
||||
|
Loading…
Reference in New Issue
Block a user