Changeset View
Changeset View
Standalone View
Standalone View
source/network/NetServer.cpp
Show First 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | private: | ||||
u32 m_RejoinerHostID; | u32 m_RejoinerHostID; | ||||
}; | }; | ||||
/* | /* | ||||
* XXX: We use some non-threadsafe functions from the worker thread. | * XXX: We use some non-threadsafe functions from the worker thread. | ||||
* See http://trac.wildfiregames.com/ticket/654 | * See http://trac.wildfiregames.com/ticket/654 | ||||
*/ | */ | ||||
CNetServerWorker::CNetServerWorker(bool useLobbyAuth, int autostartPlayers) : | CNetServerWorker::CNetServerWorker(const std::string& secret, bool useLobbyAuth, int autostartPlayers) : | ||||
m_AutostartPlayers(autostartPlayers), | m_AutostartPlayers(autostartPlayers), | ||||
m_LobbyAuth(useLobbyAuth), | m_LobbyAuth(useLobbyAuth), | ||||
m_Shutdown(false), | m_Shutdown(false), | ||||
m_ScriptInterface(NULL), | m_ScriptInterface(NULL), | ||||
m_NextHostID(1), m_Host(NULL), m_HostGUID(), m_Stats(NULL), | m_NextHostID(1), m_Host(NULL), m_ControllerGUID(), m_ControllerSecret(secret), m_Stats(NULL), | ||||
m_LastConnectionCheck(0) | m_LastConnectionCheck(0) | ||||
{ | { | ||||
m_State = SERVER_STATE_UNCONNECTED; | m_State = SERVER_STATE_UNCONNECTED; | ||||
m_ServerTurnManager = NULL; | m_ServerTurnManager = NULL; | ||||
m_ServerName = DEFAULT_SERVER_NAME; | m_ServerName = DEFAULT_SERVER_NAME; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 555 Lines • ▼ Show 20 Lines | bool CNetServerWorker::HandleConnect(CNetServerSession* session) | ||||
handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION; | handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION; | ||||
return session->SendMessage(&handshake); | return session->SendMessage(&handshake); | ||||
} | } | ||||
void CNetServerWorker::OnUserJoin(CNetServerSession* session) | void CNetServerWorker::OnUserJoin(CNetServerSession* session) | ||||
{ | { | ||||
AddPlayer(session->GetGUID(), session->GetUserName()); | AddPlayer(session->GetGUID(), session->GetUserName()); | ||||
if (m_HostGUID.empty() && session->IsLocalClient()) | |||||
m_HostGUID = session->GetGUID(); | |||||
CGameSetupMessage gameSetupMessage(GetScriptInterface()); | CGameSetupMessage gameSetupMessage(GetScriptInterface()); | ||||
gameSetupMessage.m_Data = m_GameAttributes; | gameSetupMessage.m_Data = m_GameAttributes; | ||||
session->SendMessage(&gameSetupMessage); | session->SendMessage(&gameSetupMessage); | ||||
CPlayerAssignmentMessage assignMessage; | CPlayerAssignmentMessage assignMessage; | ||||
ConstructPlayerAssignmentMessage(assignMessage); | ConstructPlayerAssignmentMessage(assignMessage); | ||||
session->SendMessage(&assignMessage); | session->SendMessage(&assignMessage); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
void CNetServerWorker::KickPlayer(const CStrW& playerName, const bool ban) | void CNetServerWorker::KickPlayer(const CStrW& playerName, const bool ban) | ||||
{ | { | ||||
// Find the user with that name | // Find the user with that name | ||||
std::vector<CNetServerSession*>::iterator it = std::find_if(m_Sessions.begin(), m_Sessions.end(), | std::vector<CNetServerSession*>::iterator it = std::find_if(m_Sessions.begin(), m_Sessions.end(), | ||||
[&](CNetServerSession* session) { return session->GetUserName() == playerName; }); | [&](CNetServerSession* session) { return session->GetUserName() == playerName; }); | ||||
// and return if no one or the host has that name | // and return if no one or the host has that name | ||||
if (it == m_Sessions.end() || (*it)->GetGUID() == m_HostGUID) | if (it == m_Sessions.end() || (*it)->GetGUID() == m_ControllerGUID) | ||||
return; | return; | ||||
if (ban) | if (ban) | ||||
{ | { | ||||
// Remember name | // Remember name | ||||
if (std::find(m_BannedPlayers.begin(), m_BannedPlayers.end(), playerName) == m_BannedPlayers.end()) | if (std::find(m_BannedPlayers.begin(), m_BannedPlayers.end(), playerName) == m_BannedPlayers.end()) | ||||
m_BannedPlayers.push_back(m_LobbyAuth ? CStrW(playerName.substr(0, playerName.find(L" ("))) : playerName); | m_BannedPlayers.push_back(m_LobbyAuth ? CStrW(playerName.substr(0, playerName.find(L" ("))) : playerName); | ||||
▲ Show 20 Lines • Show All 269 Lines • ▼ Show 20 Lines | bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event) | ||||
} | } | ||||
// TODO: check server password etc? | // TODO: check server password etc? | ||||
u32 newHostID = server.m_NextHostID++; | u32 newHostID = server.m_NextHostID++; | ||||
session->SetUserName(username); | session->SetUserName(username); | ||||
session->SetHostID(newHostID); | session->SetHostID(newHostID); | ||||
session->SetLocalClient(message->m_IsLocalClient); | |||||
CAuthenticateResultMessage authenticateResult; | CAuthenticateResultMessage authenticateResult; | ||||
authenticateResult.m_Code = isRejoining ? ARC_OK_REJOINING : ARC_OK; | authenticateResult.m_Code = isRejoining ? ARC_OK_REJOINING : ARC_OK; | ||||
authenticateResult.m_HostID = newHostID; | authenticateResult.m_HostID = newHostID; | ||||
authenticateResult.m_Message = L"Logged in"; | authenticateResult.m_Message = L"Logged in"; | ||||
authenticateResult.m_IsController = 0; | |||||
if (message->m_ControllerSecret == server.m_ControllerSecret) | |||||
{ | |||||
if (server.m_ControllerGUID.empty()) | |||||
{ | |||||
server.m_ControllerGUID = session->GetGUID(); | |||||
authenticateResult.m_IsController = 1; | |||||
} | |||||
// TODO: we could probably handle having several controllers, or swapping? | |||||
} | |||||
session->SendMessage(&authenticateResult); | session->SendMessage(&authenticateResult); | ||||
server.OnUserJoin(session); | server.OnUserJoin(session); | ||||
if (isRejoining) | if (isRejoining) | ||||
{ | { | ||||
// Request a copy of the current game state from an existing player, | // Request a copy of the current game state from an existing player, | ||||
// so we can send it on to the new player | // so we can send it on to the new player | ||||
▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | |||||
bool CNetServerWorker::OnClearAllReady(void* context, CFsmEvent* event) | bool CNetServerWorker::OnClearAllReady(void* context, CFsmEvent* event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_CLEAR_ALL_READY); | ENSURE(event->GetType() == (uint)NMT_CLEAR_ALL_READY); | ||||
CNetServerSession* session = (CNetServerSession*)context; | CNetServerSession* session = (CNetServerSession*)context; | ||||
CNetServerWorker& server = session->GetServer(); | CNetServerWorker& server = session->GetServer(); | ||||
if (session->GetGUID() == server.m_HostGUID) | if (session->GetGUID() == server.m_ControllerGUID) | ||||
server.ClearAllPlayerReady(); | server.ClearAllPlayerReady(); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetServerWorker::OnGameSetup(void* context, CFsmEvent* event) | bool CNetServerWorker::OnGameSetup(void* context, CFsmEvent* event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_GAME_SETUP); | ENSURE(event->GetType() == (uint)NMT_GAME_SETUP); | ||||
CNetServerSession* session = (CNetServerSession*)context; | CNetServerSession* session = (CNetServerSession*)context; | ||||
CNetServerWorker& server = session->GetServer(); | CNetServerWorker& server = session->GetServer(); | ||||
// Changing the settings after gamestart is not implemented and would cause an Out-of-sync error. | // Changing the settings after gamestart is not implemented and would cause an Out-of-sync error. | ||||
// This happened when doubleclicking on the startgame button. | // This happened when doubleclicking on the startgame button. | ||||
if (server.m_State != SERVER_STATE_PREGAME) | if (server.m_State != SERVER_STATE_PREGAME) | ||||
return true; | return true; | ||||
if (session->GetGUID() == server.m_HostGUID) | if (session->GetGUID() == server.m_ControllerGUID) | ||||
{ | { | ||||
CGameSetupMessage* message = (CGameSetupMessage*)event->GetParamRef(); | CGameSetupMessage* message = (CGameSetupMessage*)event->GetParamRef(); | ||||
server.UpdateGameAttributes(&(message->m_Data)); | server.UpdateGameAttributes(&(message->m_Data)); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetServerWorker::OnAssignPlayer(void* context, CFsmEvent* event) | bool CNetServerWorker::OnAssignPlayer(void* context, CFsmEvent* event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_ASSIGN_PLAYER); | ENSURE(event->GetType() == (uint)NMT_ASSIGN_PLAYER); | ||||
CNetServerSession* session = (CNetServerSession*)context; | CNetServerSession* session = (CNetServerSession*)context; | ||||
CNetServerWorker& server = session->GetServer(); | CNetServerWorker& server = session->GetServer(); | ||||
if (session->GetGUID() == server.m_HostGUID) | if (session->GetGUID() == server.m_ControllerGUID) | ||||
{ | { | ||||
CAssignPlayerMessage* message = (CAssignPlayerMessage*)event->GetParamRef(); | CAssignPlayerMessage* message = (CAssignPlayerMessage*)event->GetParamRef(); | ||||
server.AssignPlayer(message->m_PlayerID, message->m_GUID); | server.AssignPlayer(message->m_PlayerID, message->m_GUID); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetServerWorker::OnStartGame(void* context, CFsmEvent* event) | bool CNetServerWorker::OnStartGame(void* context, CFsmEvent* event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_GAME_START); | ENSURE(event->GetType() == (uint)NMT_GAME_START); | ||||
CNetServerSession* session = (CNetServerSession*)context; | CNetServerSession* session = (CNetServerSession*)context; | ||||
CNetServerWorker& server = session->GetServer(); | CNetServerWorker& server = session->GetServer(); | ||||
if (session->GetGUID() == server.m_HostGUID) | if (session->GetGUID() == server.m_ControllerGUID) | ||||
server.StartGame(); | server.StartGame(); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetServerWorker::OnLoadedGame(void* context, CFsmEvent* event) | bool CNetServerWorker::OnLoadedGame(void* context, CFsmEvent* event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_LOADED_GAME); | ENSURE(event->GetType() == (uint)NMT_LOADED_GAME); | ||||
▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | |||||
bool CNetServerWorker::OnKickPlayer(void* context, CFsmEvent* event) | bool CNetServerWorker::OnKickPlayer(void* context, CFsmEvent* event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_KICKED); | ENSURE(event->GetType() == (uint)NMT_KICKED); | ||||
CNetServerSession* session = (CNetServerSession*)context; | CNetServerSession* session = (CNetServerSession*)context; | ||||
CNetServerWorker& server = session->GetServer(); | CNetServerWorker& server = session->GetServer(); | ||||
if (session->GetGUID() == server.m_HostGUID) | if (session->GetGUID() == server.m_ControllerGUID) | ||||
{ | { | ||||
CKickedMessage* message = (CKickedMessage*)event->GetParamRef(); | CKickedMessage* message = (CKickedMessage*)event->GetParamRef(); | ||||
server.KickPlayer(message->m_Name, message->m_Ban); | server.KickPlayer(message->m_Name, message->m_Ban); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetServerWorker::OnDisconnect(void* context, CFsmEvent* event) | bool CNetServerWorker::OnDisconnect(void* context, CFsmEvent* event) | ||||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
if (m_Host) | if (m_Host) | ||||
StunClient::SendHolePunchingMessages(*m_Host, ipStr, port); | StunClient::SendHolePunchingMessages(*m_Host, ipStr, port); | ||||
} | } | ||||
CNetServer::CNetServer(bool useLobbyAuth, int autostartPlayers) : | CNetServer::CNetServer(const std::string& secret, bool useLobbyAuth, int autostartPlayers) : | ||||
m_Worker(new CNetServerWorker(useLobbyAuth, autostartPlayers)), | m_Worker(new CNetServerWorker(secret, useLobbyAuth, autostartPlayers)), | ||||
m_LobbyAuth(useLobbyAuth) | m_LobbyAuth(useLobbyAuth) | ||||
{ | { | ||||
} | } | ||||
CNetServer::~CNetServer() | CNetServer::~CNetServer() | ||||
{ | { | ||||
delete m_Worker; | delete m_Worker; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 43 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator