Don't trigger a NetServerTurnManager debug breakpoint if a modified or unmodified client sends a non-sequential turnnumber.

Disconnect that client.

Refs #3643
Differential Revision: https://code.wildfiregames.com/D1256
Reviewed By: echotangoecho
This was SVN commit r21023.
This commit is contained in:
elexis 2018-01-26 23:02:13 +00:00
parent c53adeaaa6
commit 95179c5e46
3 changed files with 40 additions and 11 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2017 Wildfire Games.
/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -1096,13 +1096,13 @@ bool CNetServerWorker::OnInGame(void* context, CFsmEvent* event)
else if (message->GetType() == (uint)NMT_SYNC_CHECK)
{
CSyncCheckMessage* syncMessage = static_cast<CSyncCheckMessage*> (message);
server.m_ServerTurnManager->NotifyFinishedClientUpdate(session->GetHostID(), session->GetUserName(), syncMessage->m_Turn, syncMessage->m_Hash);
server.m_ServerTurnManager->NotifyFinishedClientUpdate(*session, syncMessage->m_Turn, syncMessage->m_Hash);
}
else if (message->GetType() == (uint)NMT_END_COMMAND_BATCH)
{
// The turn-length field is ignored
CEndCommandBatchMessage* endMessage = static_cast<CEndCommandBatchMessage*> (message);
server.m_ServerTurnManager->NotifyFinishedClientCommands(session->GetHostID(), endMessage->m_Turn);
server.m_ServerTurnManager->NotifyFinishedClientCommands(*session, endMessage->m_Turn);
}
return true;

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2017 Wildfire Games.
/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -20,7 +20,9 @@
#include "NetMessage.h"
#include "NetServerTurnManager.h"
#include "NetServer.h"
#include "NetSession.h"
#include "ps/CLogger.h"
#include "simulation2/system/TurnManager.h"
#if 0
@ -38,15 +40,27 @@ CNetServerTurnManager::CNetServerTurnManager(CNetServerWorker& server)
m_SavedTurnLengths.push_back(0);
}
void CNetServerTurnManager::NotifyFinishedClientCommands(int client, u32 turn)
void CNetServerTurnManager::NotifyFinishedClientCommands(CNetServerSession& session, u32 turn)
{
int client = session.GetHostID();
NETSERVERTURN_LOG("NotifyFinishedClientCommands(client=%d, turn=%d)\n", client, turn);
// Must be a client we've already heard of
ENSURE(m_ClientsReady.find(client) != m_ClientsReady.end());
// Clients must advance one turn at a time
ENSURE(turn == m_ClientsReady[client] + 1);
if (turn != m_ClientsReady[client] + 1)
{
LOGERROR("NotifyFinishedClientCommands: Client %d (%s) is ready for turn %d, but expected %d",
client,
utf8_from_wstring(session.GetUserName()).c_str(),
turn,
m_ClientsReady[client] + 1);
session.Disconnect(NDR_UNKNOWN);
}
m_ClientsReady[client] = turn;
// Check whether this was the final client to become ready
@ -77,10 +91,24 @@ void CNetServerTurnManager::CheckClientsReady()
m_SavedTurnLengths.push_back(m_TurnLength);
}
void CNetServerTurnManager::NotifyFinishedClientUpdate(int client, const CStrW& playername, u32 turn, const CStr& hash)
void CNetServerTurnManager::NotifyFinishedClientUpdate(CNetServerSession& session, u32 turn, const CStr& hash)
{
int client = session.GetHostID();
const CStrW& playername = session.GetUserName();
// Clients must advance one turn at a time
ENSURE(turn == m_ClientsSimulated[client] + 1);
if (turn != m_ClientsSimulated[client] + 1)
{
LOGERROR("NotifyFinishedClientUpdate: Client %d (%s) is ready for turn %d, but expected %d",
client,
utf8_from_wstring(playername).c_str(),
turn,
m_ClientsReady[client] + 1);
session.Disconnect(NDR_UNKNOWN);
}
m_ClientsSimulated[client] = turn;
// Check for OOS only if in sync

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2017 Wildfire Games.
/* Copyright (C) 2018 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -22,6 +22,7 @@
#include "ps/CStr.h"
class CNetServerWorker;
class CNetServerSession;
/**
* The server-side counterpart to CNetClientTurnManager.
@ -37,9 +38,9 @@ class CNetServerTurnManager
public:
CNetServerTurnManager(CNetServerWorker& server);
void NotifyFinishedClientCommands(int client, u32 turn);
void NotifyFinishedClientCommands(CNetServerSession& session, u32 turn);
void NotifyFinishedClientUpdate(int client, const CStrW& playername, u32 turn, const CStr& hash);
void NotifyFinishedClientUpdate(CNetServerSession& session, u32 turn, const CStr& hash);
/**
* Inform the turn manager of a new client who will be sending commands.