Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/network/NetServer.cpp
/* Copyright (C) 2018 Wildfire Games. | /* Copyright (C) 2019 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 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 | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
▲ Show 20 Lines • Show All 655 Lines • ▼ Show 20 Lines | void CNetServerWorker::SetupSession(CNetServerSession* session) | ||||
session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context); | session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context); | ||||
session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NSS_INGAME, (void*)&OnJoinSyncingLoadedGame, context); | session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NSS_INGAME, (void*)&OnJoinSyncingLoadedGame, context); | ||||
session->AddTransition(NSS_INGAME, (uint)NMT_REJOINED, NSS_INGAME, (void*)&OnRejoined, context); | session->AddTransition(NSS_INGAME, (uint)NMT_REJOINED, NSS_INGAME, (void*)&OnRejoined, context); | ||||
session->AddTransition(NSS_INGAME, (uint)NMT_KICKED, NSS_INGAME, (void*)&OnKickPlayer, context); | session->AddTransition(NSS_INGAME, (uint)NMT_KICKED, NSS_INGAME, (void*)&OnKickPlayer, context); | ||||
session->AddTransition(NSS_INGAME, (uint)NMT_CLIENT_PAUSED, NSS_INGAME, (void*)&OnClientPaused, context); | session->AddTransition(NSS_INGAME, (uint)NMT_CLIENT_PAUSED, NSS_INGAME, (void*)&OnClientPaused, context); | ||||
session->AddTransition(NSS_INGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context); | session->AddTransition(NSS_INGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context); | ||||
session->AddTransition(NSS_INGAME, (uint)NMT_CHAT, NSS_INGAME, (void*)&OnChat, context); | session->AddTransition(NSS_INGAME, (uint)NMT_CHAT, NSS_INGAME, (void*)&OnChat, context); | ||||
session->AddTransition(NSS_INGAME, (uint)NMT_SIMULATION_COMMAND, NSS_INGAME, (void*)&OnInGame, context); | session->AddTransition(NSS_INGAME, (uint)NMT_SIMULATION_COMMAND, NSS_INGAME, (void*)&OnSimulationCommand, context); | ||||
session->AddTransition(NSS_INGAME, (uint)NMT_SYNC_CHECK, NSS_INGAME, (void*)&OnInGame, context); | session->AddTransition(NSS_INGAME, (uint)NMT_SYNC_CHECK, NSS_INGAME, (void*)&OnSyncCheck, context); | ||||
session->AddTransition(NSS_INGAME, (uint)NMT_END_COMMAND_BATCH, NSS_INGAME, (void*)&OnInGame, context); | session->AddTransition(NSS_INGAME, (uint)NMT_END_COMMAND_BATCH, NSS_INGAME, (void*)&OnEndCommandBatch, context); | ||||
// Set first state | // Set first state | ||||
session->SetFirstState(NSS_HANDSHAKE); | session->SetFirstState(NSS_HANDSHAKE); | ||||
} | } | ||||
bool CNetServerWorker::HandleConnect(CNetServerSession* session) | bool CNetServerWorker::HandleConnect(CNetServerSession* session) | ||||
{ | { | ||||
if (std::find(m_BannedIPs.begin(), m_BannedIPs.end(), session->GetIPAddress()) != m_BannedIPs.end()) | if (std::find(m_BannedIPs.begin(), m_BannedIPs.end(), session->GetIPAddress()) != m_BannedIPs.end()) | ||||
▲ Show 20 Lines • Show All 422 Lines • ▼ Show 20 Lines | sourceSession->GetFileTransferer().StartTask( | ||||
shared_ptr<CNetFileReceiveTask>(new CNetFileReceiveTask_ServerRejoin(server, newHostID)) | shared_ptr<CNetFileReceiveTask>(new CNetFileReceiveTask_ServerRejoin(server, newHostID)) | ||||
); | ); | ||||
session->SetNextState(NSS_JOIN_SYNCING); | session->SetNextState(NSS_JOIN_SYNCING); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetServerWorker::OnSimulationCommand(void* context, CFsmEvent* event) | |||||
bool CNetServerWorker::OnInGame(void* context, CFsmEvent* event) | |||||
{ | { | ||||
// TODO: should split each of these cases into a separate method | ENSURE(event->GetType() == (uint)NMT_SIMULATION_COMMAND); | ||||
CNetServerSession* session = (CNetServerSession*)context; | CNetServerSession* session = (CNetServerSession*)context; | ||||
CNetServerWorker& server = session->GetServer(); | CNetServerWorker& server = session->GetServer(); | ||||
CNetMessage* message = (CNetMessage*)event->GetParamRef(); | CSimulationMessage* message = (CSimulationMessage*)event->GetParamRef(); | ||||
if (message->GetType() == (uint)NMT_SIMULATION_COMMAND) | |||||
{ | |||||
CSimulationMessage* simMessage = static_cast<CSimulationMessage*> (message); | |||||
// Ignore messages sent by one player on behalf of another player | // Ignore messages sent by one player on behalf of another player | ||||
// unless cheating is enabled | // unless cheating is enabled | ||||
bool cheatsEnabled = false; | bool cheatsEnabled = false; | ||||
const ScriptInterface& scriptInterface = server.GetScriptInterface(); | const ScriptInterface& scriptInterface = server.GetScriptInterface(); | ||||
JSContext* cx = scriptInterface.GetContext(); | JSContext* cx = scriptInterface.GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
JS::RootedValue settings(cx); | JS::RootedValue settings(cx); | ||||
scriptInterface.GetProperty(server.m_GameAttributes, "settings", &settings); | scriptInterface.GetProperty(server.m_GameAttributes, "settings", &settings); | ||||
if (scriptInterface.HasProperty(settings, "CheatsEnabled")) | if (scriptInterface.HasProperty(settings, "CheatsEnabled")) | ||||
scriptInterface.GetProperty(settings, "CheatsEnabled", cheatsEnabled); | scriptInterface.GetProperty(settings, "CheatsEnabled", cheatsEnabled); | ||||
PlayerAssignmentMap::iterator it = server.m_PlayerAssignments.find(session->GetGUID()); | PlayerAssignmentMap::iterator it = server.m_PlayerAssignments.find(session->GetGUID()); | ||||
// When cheating is disabled, fail if the player the message claims to | // When cheating is disabled, fail if the player the message claims to | ||||
// represent does not exist or does not match the sender's player name | // represent does not exist or does not match the sender's player name | ||||
if (!cheatsEnabled && (it == server.m_PlayerAssignments.end() || it->second.m_PlayerID != simMessage->m_Player)) | if (!cheatsEnabled && (it == server.m_PlayerAssignments.end() || it->second.m_PlayerID != message->m_Player)) | ||||
return true; | return true; | ||||
// Send it back to all clients that have finished | // Send it back to all clients that have finished | ||||
// the loading screen (and the synchronization when rejoining) | // the loading screen (and the synchronization when rejoining) | ||||
server.Broadcast(simMessage, { NSS_INGAME }); | server.Broadcast(message, { NSS_INGAME }); | ||||
// Save all the received commands | // Save all the received commands | ||||
if (server.m_SavedCommands.size() < simMessage->m_Turn + 1) | if (server.m_SavedCommands.size() < message->m_Turn + 1) | ||||
server.m_SavedCommands.resize(simMessage->m_Turn + 1); | server.m_SavedCommands.resize(message->m_Turn + 1); | ||||
server.m_SavedCommands[simMessage->m_Turn].push_back(*simMessage); | server.m_SavedCommands[message->m_Turn].push_back(*message); | ||||
// TODO: we shouldn't send the message back to the client that first sent it | // TODO: we shouldn't send the message back to the client that first sent it | ||||
return true; | |||||
} | } | ||||
else if (message->GetType() == (uint)NMT_SYNC_CHECK) | |||||
bool CNetServerWorker::OnSyncCheck(void* context, CFsmEvent* event) | |||||
{ | { | ||||
CSyncCheckMessage* syncMessage = static_cast<CSyncCheckMessage*> (message); | ENSURE(event->GetType() == (uint)NMT_SYNC_CHECK); | ||||
server.m_ServerTurnManager->NotifyFinishedClientUpdate(*session, syncMessage->m_Turn, syncMessage->m_Hash); | |||||
CNetServerSession* session = (CNetServerSession*)context; | |||||
CNetServerWorker& server = session->GetServer(); | |||||
CSyncCheckMessage* message = (CSyncCheckMessage*)event->GetParamRef(); | |||||
server.m_ServerTurnManager->NotifyFinishedClientUpdate(*session, message->m_Turn, message->m_Hash); | |||||
return true; | |||||
} | } | ||||
else if (message->GetType() == (uint)NMT_END_COMMAND_BATCH) | |||||
bool CNetServerWorker::OnEndCommandBatch(void* context, CFsmEvent* event) | |||||
{ | { | ||||
// The turn-length field is ignored | ENSURE(event->GetType() == (uint)NMT_END_COMMAND_BATCH); | ||||
CEndCommandBatchMessage* endMessage = static_cast<CEndCommandBatchMessage*> (message); | |||||
server.m_ServerTurnManager->NotifyFinishedClientCommands(*session, endMessage->m_Turn); | |||||
} | |||||
CNetServerSession* session = (CNetServerSession*)context; | |||||
CNetServerWorker& server = session->GetServer(); | |||||
CEndCommandBatchMessage* message = (CEndCommandBatchMessage*)event->GetParamRef(); | |||||
// The turn-length field is ignored | |||||
server.m_ServerTurnManager->NotifyFinishedClientCommands(*session, message->m_Turn); | |||||
return true; | return true; | ||||
} | } | ||||
bool CNetServerWorker::OnChat(void* context, CFsmEvent* event) | bool CNetServerWorker::OnChat(void* context, CFsmEvent* event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_CHAT); | ENSURE(event->GetType() == (uint)NMT_CHAT); | ||||
CNetServerSession* session = (CNetServerSession*)context; | CNetServerSession* session = (CNetServerSession*)context; | ||||
▲ Show 20 Lines • Show All 440 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator