Changeset View
Changeset View
Standalone View
Standalone View
source/network/NetClient.cpp
Show All 14 Lines | |||||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
#include "precompiled.h" | #include "precompiled.h" | ||||
#include "NetClient.h" | #include "NetClient.h" | ||||
#include "NetClientTurnManager.h" | #include "NetClientTurnManager.h" | ||||
#include "NetMessage.h" | |||||
#include "NetSession.h" | #include "NetSession.h" | ||||
#include "lib/byte_order.h" | #include "lib/byte_order.h" | ||||
#include "lib/external_libraries/enet.h" | #include "lib/external_libraries/enet.h" | ||||
#include "lib/sysdep/sysdep.h" | #include "lib/sysdep/sysdep.h" | ||||
#include "ps/CConsole.h" | #include "ps/CConsole.h" | ||||
#include "ps/CLogger.h" | #include "ps/CLogger.h" | ||||
#include "ps/Compress.h" | #include "ps/Compress.h" | ||||
#include "ps/CStr.h" | #include "ps/CStr.h" | ||||
#include "ps/Game.h" | #include "ps/Game.h" | ||||
#include "ps/GUID.h" | #include "ps/GUID.h" | ||||
#include "ps/Loader.h" | #include "ps/Loader.h" | ||||
#include "scriptinterface/ScriptInterface.h" | #include "scriptinterface/ScriptInterface.h" | ||||
#include "simulation2/Simulation2.h" | #include "simulation2/Simulation2.h" | ||||
CNetClient *g_NetClient = NULL; | CNetClient* g_NetClient = nullptr; | ||||
/** | /** | ||||
* Async task for receiving the initial game state when rejoining an | * Async task for receiving the initial game state when rejoining an | ||||
* in-progress network game. | * in-progress network game. | ||||
*/ | */ | ||||
class CNetFileReceiveTask_ClientRejoin : public CNetFileReceiveTask | class CNetFileReceiveTask_ClientRejoin : public CNetFileReceiveTask | ||||
{ | { | ||||
NONCOPYABLE(CNetFileReceiveTask_ClientRejoin); | NONCOPYABLE(CNetFileReceiveTask_ClientRejoin); | ||||
public: | public: | ||||
CNetFileReceiveTask_ClientRejoin(CNetClient& client) | CNetFileReceiveTask_ClientRejoin(CNetClient& client) | ||||
: m_Client(client) | : m_Client(client) | ||||
{ | { | ||||
} | } | ||||
virtual void OnComplete() | virtual void OnComplete() | ||||
{ | { | ||||
// We've received the game state from the server | // We've received the game state from the server | ||||
// Save it so we can use it after the map has finished loading | // Save it so we can use it after the map has finished loading | ||||
m_Client.m_JoinSyncBuffer = m_Buffer; | m_Client.m_JoinSyncBuffer = m_Buffer; | ||||
// Pretend the server told us to start the game | // Pretend the server told us to start the game | ||||
CGameStartMessage start; | CGameStartMessage start; | ||||
m_Client.HandleMessage(&start); | m_Client.HandleMessage(start); | ||||
} | } | ||||
private: | private: | ||||
CNetClient& m_Client; | CNetClient& m_Client; | ||||
}; | }; | ||||
CNetClient::CNetClient(CGame* game, bool isLocalClient) : | CNetClient::CNetClient(CGame* game, bool isLocalClient) : | ||||
m_Session(NULL), | CFsm(NCS_UNCONNECTED), | ||||
m_Game(game), | |||||
m_UserName(L"anonymous"), | m_UserName(L"anonymous"), | ||||
m_GUID(ps_generate_guid()), m_HostID((u32)-1), m_ClientTurnManager(NULL), m_Game(game), | m_Session(nullptr), | ||||
m_GameAttributes(game->GetSimulation2()->GetScriptInterface().GetContext()), | m_ClientTurnManager(nullptr), | ||||
m_HostID((u32)-1), | |||||
m_Rejoin(false), | |||||
leper: `nullptr`? | |||||
m_IsLocalClient(isLocalClient), | m_IsLocalClient(isLocalClient), | ||||
m_LastConnectionCheck(0), | m_GameAttributes(game->GetSimulation2()->GetScriptInterface().GetContext()), | ||||
m_Rejoin(false) | m_GUID(ps_generate_guid()), | ||||
m_LastConnectionCheck(0) | |||||
Not Done Inline ActionsI suspect we should rename that member variable to be consistent with all other uses of GetContext. leper: I suspect we should rename that member variable to be consistent with all other uses of… | |||||
Not Done Inline ActionsMight be something for a later patch? echotangoecho: Might be something for a later patch? | |||||
Not Done Inline ActionsFine by me. leper: Fine by me. | |||||
{ | { | ||||
m_Game->SetTurnManager(NULL); // delete the old local turn manager so we don't accidentally use it | m_Game->SetTurnManager(nullptr); // delete the old local turn manager so we don't accidentally use it | ||||
void* context = this; | void* context = this; | ||||
JS_AddExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClient::Trace, this); | JS_AddExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClient::Trace, this); | ||||
// Set up transitions for session | // Set up transitions for session | ||||
AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, (void*)&OnConnect, context); | AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, &OnConnect, context); | ||||
AddTransition(NCS_CONNECT, (uint)NMT_SERVER_HANDSHAKE, NCS_HANDSHAKE, (void*)&OnHandshake, context); | AddTransition(NCS_CONNECT, (uint)NMT_SERVER_HANDSHAKE, NCS_HANDSHAKE, &OnHandshake, context); | ||||
AddTransition(NCS_HANDSHAKE, (uint)NMT_SERVER_HANDSHAKE_RESPONSE, NCS_AUTHENTICATE, (void*)&OnHandshakeResponse, context); | AddTransition(NCS_HANDSHAKE, (uint)NMT_SERVER_HANDSHAKE_RESPONSE, NCS_AUTHENTICATE, &OnHandshakeResponse, context); | ||||
AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE_RESULT, NCS_INITIAL_GAMESETUP, (void*)&OnAuthenticate, context); | AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE_RESULT, NCS_INITIAL_GAMESETUP, &OnAuthenticate, context); | ||||
AddTransition(NCS_INITIAL_GAMESETUP, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context); | AddTransition(NCS_INITIAL_GAMESETUP, (uint)NMT_GAME_SETUP, NCS_PREGAME, &OnGameSetup, context); | ||||
AddTransition(NCS_PREGAME, (uint)NMT_CHAT, NCS_PREGAME, (void*)&OnChat, context); | AddTransition(NCS_PREGAME, (uint)NMT_CHAT, NCS_PREGAME, &OnChat, context); | ||||
AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, (void*)&OnReady, context); | AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, &OnReady, context); | ||||
AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context); | AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, &OnGameSetup, context); | ||||
AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, (void*)&OnPlayerAssignment, context); | AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, &OnPlayerAssignment, context); | ||||
AddTransition(NCS_PREGAME, (uint)NMT_KICKED, NCS_PREGAME, (void*)&OnKicked, context); | AddTransition(NCS_PREGAME, (uint)NMT_KICKED, NCS_PREGAME, &OnKicked, context); | ||||
AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_PREGAME, (void*)&OnClientTimeout, context); | AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_PREGAME, &OnClientTimeout, context); | ||||
AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_PREGAME, (void*)&OnClientPerformance, context); | AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_PREGAME, &OnClientPerformance, context); | ||||
AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, (void*)&OnGameStart, context); | AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, &OnGameStart, context); | ||||
AddTransition(NCS_PREGAME, (uint)NMT_JOIN_SYNC_START, NCS_JOIN_SYNCING, (void*)&OnJoinSyncStart, context); | AddTransition(NCS_PREGAME, (uint)NMT_JOIN_SYNC_START, NCS_JOIN_SYNCING, &OnJoinSyncStart, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CHAT, NCS_JOIN_SYNCING, (void*)&OnChat, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CHAT, NCS_JOIN_SYNCING, &OnChat, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_SETUP, NCS_JOIN_SYNCING, (void*)&OnGameSetup, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_SETUP, NCS_JOIN_SYNCING, &OnGameSetup, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_JOIN_SYNCING, (void*)&OnPlayerAssignment, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_JOIN_SYNCING, &OnPlayerAssignment, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_KICKED, NCS_JOIN_SYNCING, (void*)&OnKicked, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_KICKED, NCS_JOIN_SYNCING, &OnKicked, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_TIMEOUT, NCS_JOIN_SYNCING, (void*)&OnClientTimeout, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_TIMEOUT, NCS_JOIN_SYNCING, &OnClientTimeout, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_PERFORMANCE, NCS_JOIN_SYNCING, (void*)&OnClientPerformance, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_PERFORMANCE, NCS_JOIN_SYNCING, &OnClientPerformance, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_START, NCS_JOIN_SYNCING, (void*)&OnGameStart, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_START, NCS_JOIN_SYNCING, &OnGameStart, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_SIMULATION_COMMAND, NCS_JOIN_SYNCING, (void*)&OnInGame, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_SIMULATION_COMMAND, NCS_JOIN_SYNCING, &OnInGame, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_END_COMMAND_BATCH, NCS_JOIN_SYNCING, (void*)&OnJoinSyncEndCommandBatch, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_END_COMMAND_BATCH, NCS_JOIN_SYNCING, &OnJoinSyncEndCommandBatch, context); | ||||
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NCS_INGAME, (void*)&OnLoadedGame, context); | AddTransition(NCS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NCS_INGAME, &OnLoadedGame, context); | ||||
AddTransition(NCS_LOADING, (uint)NMT_CHAT, NCS_LOADING, (void*)&OnChat, context); | AddTransition(NCS_LOADING, (uint)NMT_CHAT, NCS_LOADING, &OnChat, context); | ||||
AddTransition(NCS_LOADING, (uint)NMT_GAME_SETUP, NCS_LOADING, (void*)&OnGameSetup, context); | AddTransition(NCS_LOADING, (uint)NMT_GAME_SETUP, NCS_LOADING, &OnGameSetup, context); | ||||
AddTransition(NCS_LOADING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_LOADING, (void*)&OnPlayerAssignment, context); | AddTransition(NCS_LOADING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_LOADING, &OnPlayerAssignment, context); | ||||
AddTransition(NCS_LOADING, (uint)NMT_KICKED, NCS_LOADING, (void*)&OnKicked, context); | AddTransition(NCS_LOADING, (uint)NMT_KICKED, NCS_LOADING, &OnKicked, context); | ||||
AddTransition(NCS_LOADING, (uint)NMT_CLIENT_TIMEOUT, NCS_LOADING, (void*)&OnClientTimeout, context); | AddTransition(NCS_LOADING, (uint)NMT_CLIENT_TIMEOUT, NCS_LOADING, &OnClientTimeout, context); | ||||
AddTransition(NCS_LOADING, (uint)NMT_CLIENT_PERFORMANCE, NCS_LOADING, (void*)&OnClientPerformance, context); | AddTransition(NCS_LOADING, (uint)NMT_CLIENT_PERFORMANCE, NCS_LOADING, &OnClientPerformance, context); | ||||
AddTransition(NCS_LOADING, (uint)NMT_CLIENTS_LOADING, NCS_LOADING, (void*)&OnClientsLoading, context); | AddTransition(NCS_LOADING, (uint)NMT_CLIENTS_LOADING, NCS_LOADING, &OnClientsLoading, context); | ||||
AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, (void*)&OnLoadedGame, context); | AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, &OnLoadedGame, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_REJOINED, NCS_INGAME, (void*)&OnRejoined, context); | AddTransition(NCS_INGAME, (uint)NMT_REJOINED, NCS_INGAME, &OnRejoined, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_KICKED, NCS_INGAME, (void*)&OnKicked, context); | AddTransition(NCS_INGAME, (uint)NMT_KICKED, NCS_INGAME, &OnKicked, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_INGAME, (void*)&OnClientTimeout, context); | AddTransition(NCS_INGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_INGAME, &OnClientTimeout, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_INGAME, (void*)&OnClientPerformance, context); | AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_INGAME, &OnClientPerformance, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_CLIENTS_LOADING, NCS_INGAME, (void*)&OnClientsLoading, context); | AddTransition(NCS_INGAME, (uint)NMT_CLIENTS_LOADING, NCS_INGAME, &OnClientsLoading, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PAUSED, NCS_INGAME, (void*)&OnClientPaused, context); | AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PAUSED, NCS_INGAME, &OnClientPaused, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_CHAT, NCS_INGAME, (void*)&OnChat, context); | AddTransition(NCS_INGAME, (uint)NMT_CHAT, NCS_INGAME, &OnChat, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, (void*)&OnGameSetup, context); | AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, &OnGameSetup, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_INGAME, (void*)&OnPlayerAssignment, context); | AddTransition(NCS_INGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_INGAME, &OnPlayerAssignment, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_SIMULATION_COMMAND, NCS_INGAME, (void*)&OnInGame, context); | AddTransition(NCS_INGAME, (uint)NMT_SIMULATION_COMMAND, NCS_INGAME, &OnInGame, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_SYNC_ERROR, NCS_INGAME, (void*)&OnInGame, context); | AddTransition(NCS_INGAME, (uint)NMT_SYNC_ERROR, NCS_INGAME, &OnInGame, context); | ||||
AddTransition(NCS_INGAME, (uint)NMT_END_COMMAND_BATCH, NCS_INGAME, (void*)&OnInGame, context); | AddTransition(NCS_INGAME, (uint)NMT_END_COMMAND_BATCH, NCS_INGAME, &OnInGame, context); | ||||
// Set first state | |||||
SetFirstState(NCS_UNCONNECTED); | |||||
} | } | ||||
CNetClient::~CNetClient() | CNetClient::~CNetClient() | ||||
{ | { | ||||
DestroyConnection(); | DestroyConnection(); | ||||
JS_RemoveExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClient::Trace, this); | JS_RemoveExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClient::Trace, this); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | for (const std::pair<CStr, PlayerAssignment>& p : m_PlayerAssignments) | ||||
GetScriptInterface().SetProperty(assignment, "player", p.second.m_PlayerID, false); | GetScriptInterface().SetProperty(assignment, "player", p.second.m_PlayerID, false); | ||||
GetScriptInterface().SetProperty(assignment, "status", p.second.m_Status, false); | GetScriptInterface().SetProperty(assignment, "status", p.second.m_Status, false); | ||||
GetScriptInterface().SetProperty(newAssignments, p.first.c_str(), assignment, false); | GetScriptInterface().SetProperty(newAssignments, p.first.c_str(), assignment, false); | ||||
} | } | ||||
PushGuiMessage(msg); | PushGuiMessage(msg); | ||||
} | } | ||||
bool CNetClient::SendMessage(const CNetMessage* message) | bool CNetClient::SendMessage(const CNetMessageBuffer& message) | ||||
{ | { | ||||
if (!m_Session) | if (!m_Session) | ||||
return false; | return false; | ||||
return m_Session->SendMessage(message); | return m_Session->SendMessage(message); | ||||
} | } | ||||
void CNetClient::HandleConnect() | void CNetClient::HandleConnect() | ||||
{ | { | ||||
Update((uint)NMT_CONNECT_COMPLETE, NULL); | Update(NMT_CONNECT_COMPLETE, nullptr); | ||||
} | } | ||||
void CNetClient::HandleDisconnect(u32 reason) | void CNetClient::HandleDisconnect(u32 reason) | ||||
{ | { | ||||
JSContext* cx = GetScriptInterface().GetContext(); | JSContext* cx = GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
GetScriptInterface().Eval("({'type':'netstatus','status':'disconnected'})", &msg); | GetScriptInterface().Eval("({'type':'netstatus','status':'disconnected'})", &msg); | ||||
GetScriptInterface().SetProperty(msg, "reason", (int)reason, false); | GetScriptInterface().SetProperty(msg, "reason", (int)reason, false); | ||||
PushGuiMessage(msg); | PushGuiMessage(msg); | ||||
SAFE_DELETE(m_Session); | SAFE_DELETE(m_Session); | ||||
// Update the state immediately to UNCONNECTED (don't bother with FSM transitions since | // Update the state immediately to UNCONNECTED (don't bother with FSM transitions since | ||||
// we'd need one for every single state, and we don't need to use per-state actions) | // we'd need one for every single state, and we don't need to use per-state actions) | ||||
SetCurrState(NCS_UNCONNECTED); | SetCurrState(NCS_UNCONNECTED); | ||||
} | } | ||||
void CNetClient::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface) | void CNetClient::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface) | ||||
{ | { | ||||
CGameSetupMessage gameSetup(scriptInterface); | CGameSetupMessage gameSetup(scriptInterface, (JS::HandleValue)attrs); | ||||
gameSetup.m_Data = attrs; | SendMessage(gameSetup); | ||||
SendMessage(&gameSetup); | |||||
} | } | ||||
void CNetClient::SendAssignPlayerMessage(const int playerID, const CStr& guid) | void CNetClient::SendAssignPlayerMessage(const int playerID, const CStr& guid) | ||||
{ | { | ||||
CAssignPlayerMessage assignPlayer; | CAssignPlayerMessage assignPlayer; | ||||
assignPlayer.m_PlayerID = playerID; | assignPlayer.m_PlayerID = playerID; | ||||
assignPlayer.m_GUID = guid; | assignPlayer.m_GUID = guid; | ||||
SendMessage(&assignPlayer); | SendMessage(assignPlayer); | ||||
} | } | ||||
void CNetClient::SendChatMessage(const std::wstring& text) | void CNetClient::SendChatMessage(const std::wstring& text) | ||||
{ | { | ||||
CChatMessage chat; | CChatMessage chat; | ||||
chat.m_Message = text; | chat.m_Message = text; | ||||
SendMessage(&chat); | SendMessage(chat); | ||||
} | } | ||||
void CNetClient::SendReadyMessage(const int status) | void CNetClient::SendReadyMessage(const int status) | ||||
{ | { | ||||
CReadyMessage readyStatus; | CReadyMessage readyStatus; | ||||
readyStatus.m_Status = status; | readyStatus.m_Status = status; | ||||
SendMessage(&readyStatus); | SendMessage(readyStatus); | ||||
} | } | ||||
void CNetClient::SendClearAllReadyMessage() | void CNetClient::SendClearAllReadyMessage() | ||||
{ | { | ||||
CClearAllReadyMessage clearAllReady; | CClearAllReadyMessage clearAllReady; | ||||
SendMessage(&clearAllReady); | SendMessage(clearAllReady); | ||||
} | } | ||||
void CNetClient::SendStartGameMessage() | void CNetClient::SendStartGameMessage() | ||||
{ | { | ||||
CGameStartMessage gameStart; | CGameStartMessage gameStart; | ||||
SendMessage(&gameStart); | SendMessage(gameStart); | ||||
} | } | ||||
void CNetClient::SendRejoinedMessage() | void CNetClient::SendRejoinedMessage() | ||||
{ | { | ||||
CRejoinedMessage rejoinedMessage; | CRejoinedMessage rejoinedMessage; | ||||
SendMessage(&rejoinedMessage); | SendMessage(rejoinedMessage); | ||||
} | } | ||||
void CNetClient::SendKickPlayerMessage(const CStrW& playerName, bool ban) | void CNetClient::SendKickPlayerMessage(const CStrW& playerName, bool ban) | ||||
{ | { | ||||
CKickedMessage kickPlayer; | CKickedMessage kickPlayer; | ||||
kickPlayer.m_Name = playerName; | kickPlayer.m_Name = playerName; | ||||
kickPlayer.m_Ban = ban; | kickPlayer.m_Ban = ban; | ||||
SendMessage(&kickPlayer); | SendMessage(kickPlayer); | ||||
} | } | ||||
void CNetClient::SendPausedMessage(bool pause) | void CNetClient::SendPausedMessage(bool pause) | ||||
{ | { | ||||
CClientPausedMessage pausedMessage; | CClientPausedMessage pausedMessage; | ||||
pausedMessage.m_Pause = pause; | pausedMessage.m_Pause = pause; | ||||
SendMessage(&pausedMessage); | SendMessage(pausedMessage); | ||||
} | } | ||||
bool CNetClient::HandleMessage(CNetMessage* message) | bool CNetClient::HandleMessage(const CNetMessageBuffer& message) | ||||
{ | { | ||||
// Handle non-FSM messages first | // Handle non-FSM messages first | ||||
Status status = m_Session->GetFileTransferer().HandleMessageReceive(message); | Status status = m_Session->GetFileTransferer().HandleMessageReceive(message); | ||||
if (status == INFO::OK) | if (status == INFO::OK) | ||||
return true; | return true; | ||||
if (status != INFO::SKIPPED) | if (status != INFO::SKIPPED) | ||||
return false; | return false; | ||||
if (message->GetType() == NMT_FILE_TRANSFER_REQUEST) | if (message.GetType() == NMT_FILE_TRANSFER_REQUEST) | ||||
{ | { | ||||
CFileTransferRequestMessage* reqMessage = (CFileTransferRequestMessage*)message; | CFileTransferRequestMessage reqMessage(message); | ||||
Not Done Inline ActionsI suspect that we might want to enable writing that on one line again. leper: I suspect that we might want to enable writing that on one line again. | |||||
// TODO: we should support different transfer request types, instead of assuming | // TODO: we should support different transfer request types, instead of assuming | ||||
// it's always requesting the simulation state | // it's always requesting the simulation state | ||||
std::stringstream stream; | std::stringstream stream; | ||||
LOGMESSAGERENDER("Serializing game at turn %u for rejoining player", m_ClientTurnManager->GetCurrentTurn()); | LOGMESSAGERENDER("Serializing game at turn %u for rejoining player", m_ClientTurnManager->GetCurrentTurn()); | ||||
u32 turn = to_le32(m_ClientTurnManager->GetCurrentTurn()); | u32 turn = to_le32(m_ClientTurnManager->GetCurrentTurn()); | ||||
stream.write((char*)&turn, sizeof(turn)); | stream.write((char*)&turn, sizeof(turn)); | ||||
bool ok = m_Game->GetSimulation2()->SerializeState(stream); | bool ok = m_Game->GetSimulation2()->SerializeState(stream); | ||||
ENSURE(ok); | ENSURE(ok); | ||||
// Compress the content with zlib to save bandwidth | // Compress the content with zlib to save bandwidth | ||||
// (TODO: if this is still too large, compressing with e.g. LZMA works much better) | // (TODO: if this is still too large, compressing with e.g. LZMA works much better) | ||||
std::string compressed; | std::string compressed; | ||||
CompressZLib(stream.str(), compressed, true); | CompressZLib(stream.str(), compressed, true); | ||||
m_Session->GetFileTransferer().StartResponse(reqMessage->m_RequestID, compressed); | m_Session->GetFileTransferer().StartResponse(reqMessage.m_RequestID, compressed); | ||||
return true; | return true; | ||||
} | } | ||||
// Update FSM | // Update FSM | ||||
bool ok = Update(message->GetType(), message); | bool ok = Update(message.GetType(), &message); | ||||
if (!ok) | if (!ok) | ||||
LOGERROR("Net client: Error running FSM update (type=%d state=%d)", (int)message->GetType(), (int)GetCurrState()); | LOGERROR("Net client: Error running FSM update (type=%d state=%d)", (int)message.GetType(), (int)GetCurrState()); | ||||
return ok; | return ok; | ||||
} | } | ||||
void CNetClient::LoadFinished() | void CNetClient::LoadFinished() | ||||
{ | { | ||||
JSContext* cx = GetScriptInterface().GetContext(); | JSContext* cx = GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
Show All 27 Lines | else | ||||
// Connecting at the start of a game, so we'll wait for other players to finish loading | // Connecting at the start of a game, so we'll wait for other players to finish loading | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
GetScriptInterface().Eval("({'type':'netstatus','status':'waiting_for_players'})", &msg); | GetScriptInterface().Eval("({'type':'netstatus','status':'waiting_for_players'})", &msg); | ||||
PushGuiMessage(msg); | PushGuiMessage(msg); | ||||
} | } | ||||
CLoadedGameMessage loaded; | CLoadedGameMessage loaded; | ||||
loaded.m_CurrentTurn = m_ClientTurnManager->GetCurrentTurn(); | loaded.m_CurrentTurn = m_ClientTurnManager->GetCurrentTurn(); | ||||
SendMessage(&loaded); | SendMessage(loaded); | ||||
} | } | ||||
bool CNetClient::OnConnect(void* context, CFsmEvent* event) | bool CNetClient::OnConnect(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_CONNECT_COMPLETE); | ENSURE(event.GetType() == (uint)NMT_CONNECT_COMPLETE); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({'type':'netstatus','status':'connected'})", &msg); | client->GetScriptInterface().Eval("({'type':'netstatus','status':'connected'})", &msg); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnHandshake(void* context, CFsmEvent* event) | bool CNetClient::OnHandshake(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE); | ENSURE(event.GetType() == (uint)NMT_SERVER_HANDSHAKE); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
CCliHandshakeMessage handshake; | CCliHandshakeMessage handshake; | ||||
handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE; | handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE; | ||||
handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION; | handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION; | ||||
handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION; | handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION; | ||||
client->SendMessage(&handshake); | client->SendMessage(handshake); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnHandshakeResponse(void* context, CFsmEvent* event) | bool CNetClient::OnHandshakeResponse(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE_RESPONSE); | ENSURE(event.GetType() == (uint)NMT_SERVER_HANDSHAKE_RESPONSE); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
CAuthenticateMessage authenticate; | CAuthenticateMessage authenticate; | ||||
authenticate.m_GUID = client->m_GUID; | authenticate.m_GUID = client->m_GUID; | ||||
authenticate.m_Name = client->m_UserName; | authenticate.m_Name = client->m_UserName; | ||||
authenticate.m_Password = L""; // TODO | authenticate.m_Password = L""; // TODO | ||||
authenticate.m_IsLocalClient = client->m_IsLocalClient; | authenticate.m_IsLocalClient = client->m_IsLocalClient; | ||||
client->SendMessage(&authenticate); | client->SendMessage(authenticate); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event) | bool CNetClient::OnAuthenticate(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE_RESULT); | ENSURE(event.GetType() == (uint)NMT_AUTHENTICATE_RESULT); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
CAuthenticateResultMessage* message = (CAuthenticateResultMessage*)event->GetParamRef(); | CAuthenticateResultMessage message(event.GetMessageBuffer()); | ||||
LOGMESSAGE("Net: Authentication result: host=%u, %s", message->m_HostID, utf8_from_wstring(message->m_Message)); | LOGMESSAGE("Net: Authentication result: host=%u, %s", message.m_HostID, utf8_from_wstring(message.m_Message)); | ||||
client->m_HostID = message->m_HostID; | client->m_HostID = message.m_HostID; | ||||
client->m_Rejoin = message->m_Code == ARC_OK_REJOINING; | client->m_Rejoin = message.m_Code == ARC_OK_REJOINING; | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({'type':'netstatus','status':'authenticated'})", &msg); | client->GetScriptInterface().Eval("({'type':'netstatus','status':'authenticated'})", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "rejoining", client->m_Rejoin); | client->GetScriptInterface().SetProperty(msg, "rejoining", client->m_Rejoin); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnChat(void* context, CFsmEvent* event) | bool CNetClient::OnChat(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_CHAT); | ENSURE(event.GetType() == (uint)NMT_CHAT); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
CChatMessage* message = (CChatMessage*)event->GetParamRef(); | CChatMessage message(event.GetMessageBuffer()); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({'type':'chat'})", &msg); | client->GetScriptInterface().Eval("({'type':'chat'})", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "guid", std::string(message->m_GUID), false); | client->GetScriptInterface().SetProperty(msg, "guid", std::string(message.m_GUID), false); | ||||
client->GetScriptInterface().SetProperty(msg, "text", std::wstring(message->m_Message), false); | client->GetScriptInterface().SetProperty(msg, "text", std::wstring(message.m_Message), false); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnReady(void* context, CFsmEvent* event) | bool CNetClient::OnReady(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_READY); | ENSURE(event.GetType() == (uint)NMT_READY); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
CReadyMessage* message = (CReadyMessage*)event->GetParamRef(); | CReadyMessage message(event.GetMessageBuffer()); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({'type':'ready'})", &msg); | client->GetScriptInterface().Eval("({'type':'ready'})", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "guid", std::string(message->m_GUID), false); | client->GetScriptInterface().SetProperty(msg, "guid", std::string(message.m_GUID), false); | ||||
client->GetScriptInterface().SetProperty(msg, "status", int (message->m_Status), false); | client->GetScriptInterface().SetProperty(msg, "status", int (message.m_Status), false); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnGameSetup(void* context, CFsmEvent* event) | bool CNetClient::OnGameSetup(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_GAME_SETUP); | ENSURE(event.GetType() == (uint)NMT_GAME_SETUP); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
CGameSetupMessage* message = (CGameSetupMessage*)event->GetParamRef(); | CGameSetupMessage message(client->GetScriptInterface(), event.GetMessageBuffer()); | ||||
client->m_GameAttributes = message.m_JSData.m_Data; | |||||
client->m_GameAttributes = message->m_Data; | |||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({'type':'gamesetup'})", &msg); | client->GetScriptInterface().Eval("({'type':'gamesetup'})", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "data", message->m_Data, false); | client->GetScriptInterface().SetProperty(msg, "data", message.m_JSData.m_Data, false); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnPlayerAssignment(void* context, CFsmEvent* event) | bool CNetClient::OnPlayerAssignment(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_PLAYER_ASSIGNMENT); | ENSURE(event.GetType() == (uint)NMT_PLAYER_ASSIGNMENT); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
CPlayerAssignmentMessage* message = (CPlayerAssignmentMessage*)event->GetParamRef(); | CPlayerAssignmentMessage message(event.GetMessageBuffer()); | ||||
// Unpack the message | // Unpack the message | ||||
PlayerAssignmentMap newPlayerAssignments; | PlayerAssignmentMap newPlayerAssignments; | ||||
for (size_t i = 0; i < message->m_Hosts.size(); ++i) | for (size_t i = 0; i < message.m_Hosts.size(); ++i) | ||||
{ | { | ||||
PlayerAssignment assignment; | PlayerAssignment assignment; | ||||
assignment.m_Enabled = true; | assignment.m_Enabled = true; | ||||
assignment.m_Name = message->m_Hosts[i].m_Name; | assignment.m_Name = message.m_Hosts[i].m_Name; | ||||
assignment.m_PlayerID = message->m_Hosts[i].m_PlayerID; | assignment.m_PlayerID = message.m_Hosts[i].m_PlayerID; | ||||
assignment.m_Status = message->m_Hosts[i].m_Status; | assignment.m_Status = message.m_Hosts[i].m_Status; | ||||
newPlayerAssignments[message->m_Hosts[i].m_GUID] = assignment; | newPlayerAssignments[message.m_Hosts[i].m_GUID] = assignment; | ||||
} | } | ||||
client->m_PlayerAssignments.swap(newPlayerAssignments); | client->m_PlayerAssignments.swap(newPlayerAssignments); | ||||
client->PostPlayerAssignmentsToScript(); | client->PostPlayerAssignmentsToScript(); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnGameStart(void* context, CFsmEvent* event) | bool CNetClient::OnGameStart(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_GAME_START); | ENSURE(event.GetType() == (uint)NMT_GAME_START); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
// Find the player assigned to our GUID | // Find the player assigned to our GUID | ||||
int player = -1; | int player = -1; | ||||
if (client->m_PlayerAssignments.find(client->m_GUID) != client->m_PlayerAssignments.end()) | if (client->m_PlayerAssignments.find(client->m_GUID) != client->m_PlayerAssignments.end()) | ||||
player = client->m_PlayerAssignments[client->m_GUID].m_PlayerID; | player = client->m_PlayerAssignments[client->m_GUID].m_PlayerID; | ||||
client->m_ClientTurnManager = new CNetClientTurnManager( | client->m_ClientTurnManager = new CNetClientTurnManager( | ||||
*client->m_Game->GetSimulation2(), *client, client->m_HostID, client->m_Game->GetReplayLogger()); | *client->m_Game->GetSimulation2(), *client, client->m_HostID, client->m_Game->GetReplayLogger()); | ||||
client->m_Game->SetPlayerID(player); | client->m_Game->SetPlayerID(player); | ||||
client->m_Game->StartGame(&client->m_GameAttributes, ""); | client->m_Game->StartGame(&client->m_GameAttributes, ""); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({'type':'start'})", &msg); | client->GetScriptInterface().Eval("({'type':'start'})", &msg); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnJoinSyncStart(void* context, CFsmEvent* event) | bool CNetClient::OnJoinSyncStart(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_JOIN_SYNC_START); | ENSURE(event.GetType() == (uint)NMT_JOIN_SYNC_START); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
// The server wants us to start downloading the game state from it, so do so | // The server wants us to start downloading the game state from it, so do so | ||||
client->m_Session->GetFileTransferer().StartTask( | client->m_Session->GetFileTransferer().StartTask( | ||||
shared_ptr<CNetFileReceiveTask>(new CNetFileReceiveTask_ClientRejoin(*client)) | shared_ptr<CNetFileReceiveTask>(new CNetFileReceiveTask_ClientRejoin(*client)) | ||||
); | ); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event) | bool CNetClient::OnJoinSyncEndCommandBatch(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_END_COMMAND_BATCH); | ENSURE(event.GetType() == (uint)NMT_END_COMMAND_BATCH); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
CEndCommandBatchMessage* endMessage = (CEndCommandBatchMessage*)event->GetParamRef(); | CEndCommandBatchMessage endMessage(event.GetMessageBuffer()); | ||||
client->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn, endMessage->m_TurnLength); | client->m_ClientTurnManager->FinishedAllCommands(endMessage.m_Turn, endMessage.m_TurnLength); | ||||
// Execute all the received commands for the latest turn | // Execute all the received commands for the latest turn | ||||
client->m_ClientTurnManager->UpdateFastForward(); | client->m_ClientTurnManager->UpdateFastForward(); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnRejoined(void* context, CFsmEvent* event) | bool CNetClient::OnRejoined(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_REJOINED); | ENSURE(event.GetType() == (uint)NMT_REJOINED); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
CRejoinedMessage* message = (CRejoinedMessage*)event->GetParamRef(); | CRejoinedMessage message(event.GetMessageBuffer()); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({'type':'rejoined'})", &msg); | client->GetScriptInterface().Eval("({'type':'rejoined'})", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "guid", std::string(message->m_GUID), false); | client->GetScriptInterface().SetProperty(msg, "guid", std::string(message.m_GUID), false); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnKicked(void *context, CFsmEvent* event) | bool CNetClient::OnKicked(void *context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_KICKED); | ENSURE(event.GetType() == (uint)NMT_KICKED); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
CKickedMessage* message = (CKickedMessage*)event->GetParamRef(); | CKickedMessage message(event.GetMessageBuffer()); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({})", &msg); | client->GetScriptInterface().Eval("({})", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "username", message->m_Name); | client->GetScriptInterface().SetProperty(msg, "username", message.m_Name); | ||||
client->GetScriptInterface().SetProperty(msg, "type", CStr("kicked")); | client->GetScriptInterface().SetProperty(msg, "type", CStr("kicked")); | ||||
client->GetScriptInterface().SetProperty(msg, "banned", message->m_Ban != 0); | client->GetScriptInterface().SetProperty(msg, "banned", message.m_Ban != 0); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnClientTimeout(void *context, CFsmEvent* event) | bool CNetClient::OnClientTimeout(void *context, const CFsmEvent& event) | ||||
{ | { | ||||
// Report the timeout of some other client | // Report the timeout of some other client | ||||
ENSURE(event->GetType() == (uint)NMT_CLIENT_TIMEOUT); | ENSURE(event.GetType() == (uint)NMT_CLIENT_TIMEOUT); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
if (client->GetCurrState() == NCS_LOADING) | if (client->GetCurrState() == NCS_LOADING) | ||||
return true; | return true; | ||||
CClientTimeoutMessage* message = (CClientTimeoutMessage*)event->GetParamRef(); | CClientTimeoutMessage message(event.GetMessageBuffer()); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({ 'type':'netwarn', 'warntype': 'client-timeout' })", &msg); | client->GetScriptInterface().Eval("({ 'type':'netwarn', 'warntype': 'client-timeout' })", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "guid", std::string(message->m_GUID)); | client->GetScriptInterface().SetProperty(msg, "guid", std::string(message.m_GUID)); | ||||
client->GetScriptInterface().SetProperty(msg, "lastReceivedTime", message->m_LastReceivedTime); | client->GetScriptInterface().SetProperty(msg, "lastReceivedTime", message.m_LastReceivedTime); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnClientPerformance(void *context, CFsmEvent* event) | bool CNetClient::OnClientPerformance(void *context, const CFsmEvent& event) | ||||
{ | { | ||||
// Performance statistics for one or multiple clients | // Performance statistics for one or multiple clients | ||||
ENSURE(event->GetType() == (uint)NMT_CLIENT_PERFORMANCE); | ENSURE(event.GetType() == (uint)NMT_CLIENT_PERFORMANCE); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
if (client->GetCurrState() == NCS_LOADING) | if (client->GetCurrState() == NCS_LOADING) | ||||
return true; | return true; | ||||
CClientPerformanceMessage* message = (CClientPerformanceMessage*)event->GetParamRef(); | CClientPerformanceMessage message(event.GetMessageBuffer()); | ||||
// Display warnings for other clients with bad ping | // Display warnings for other clients with bad ping | ||||
for (size_t i = 0; i < message->m_Clients.size(); ++i) | for (size_t i = 0; i < message.m_Clients.size(); ++i) | ||||
{ | { | ||||
if (message->m_Clients[i].m_MeanRTT < DEFAULT_TURN_LENGTH_MP || message->m_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; | continue; | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({ 'type':'netwarn', 'warntype': 'client-latency' })", &msg); | client->GetScriptInterface().Eval("({ 'type':'netwarn', 'warntype': 'client-latency' })", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "guid", message->m_Clients[i].m_GUID); | client->GetScriptInterface().SetProperty(msg, "guid", message.m_Clients[i].m_GUID); | ||||
client->GetScriptInterface().SetProperty(msg, "meanRTT", message->m_Clients[i].m_MeanRTT); | client->GetScriptInterface().SetProperty(msg, "meanRTT", message.m_Clients[i].m_MeanRTT); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnClientsLoading(void *context, CFsmEvent *event) | bool CNetClient::OnClientsLoading(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_CLIENTS_LOADING); | ENSURE(event.GetType() == (uint)NMT_CLIENTS_LOADING); | ||||
CClientsLoadingMessage* message = (CClientsLoadingMessage*)event->GetParamRef(); | CClientsLoadingMessage message(event.GetMessageBuffer()); | ||||
std::vector<CStr> guids; | std::vector<CStr> guids; | ||||
guids.reserve(message->m_Clients.size()); | guids.reserve(message.m_Clients.size()); | ||||
for (const CClientsLoadingMessage::S_m_Clients& client : message->m_Clients) | for (const CClientsLoadingMessage::SClient& client : message.m_Clients) | ||||
guids.push_back(client.m_GUID); | guids.push_back(client.m_GUID); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({ 'type':'clients-loading' })", &msg); | client->GetScriptInterface().Eval("({ 'type':'clients-loading' })", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "guids", guids); | client->GetScriptInterface().SetProperty(msg, "guids", guids); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnClientPaused(void *context, CFsmEvent *event) | bool CNetClient::OnClientPaused(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_CLIENT_PAUSED); | ENSURE(event.GetType() == (uint)NMT_CLIENT_PAUSED); | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
CClientPausedMessage* message = (CClientPausedMessage*)event->GetParamRef(); | CClientPausedMessage message(event.GetMessageBuffer()); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({ 'type':'paused' })", &msg); | client->GetScriptInterface().Eval("({ 'type':'paused' })", &msg); | ||||
client->GetScriptInterface().SetProperty(msg, "pause", message->m_Pause != 0); | client->GetScriptInterface().SetProperty(msg, "pause", message.m_Pause != 0); | ||||
client->GetScriptInterface().SetProperty(msg, "guid", message->m_GUID); | client->GetScriptInterface().SetProperty(msg, "guid", message.m_GUID); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnLoadedGame(void* context, CFsmEvent* event) | bool CNetClient::OnLoadedGame(void* context, const CFsmEvent& event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_LOADED_GAME); | ENSURE(event.GetType() == (uint)NMT_LOADED_GAME); | ||||
leperUnsubmitted Not Done Inline ActionsNo need for the cast. leper: No need for the cast. | |||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
JSContext* cx = client->GetScriptInterface().GetContext(); | JSContext* cx = client->GetScriptInterface().GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
// All players have loaded the game - start running the turn manager | // All players have loaded the game - start running the turn manager | ||||
// so that the game begins | // so that the game begins | ||||
client->m_Game->SetTurnManager(client->m_ClientTurnManager); | client->m_Game->SetTurnManager(client->m_ClientTurnManager); | ||||
JS::RootedValue msg(cx); | JS::RootedValue msg(cx); | ||||
client->GetScriptInterface().Eval("({'type':'netstatus','status':'active'})", &msg); | client->GetScriptInterface().Eval("({'type':'netstatus','status':'active'})", &msg); | ||||
client->PushGuiMessage(msg); | client->PushGuiMessage(msg); | ||||
// If we have rejoined an in progress game, send the rejoined message to the server. | // If we have rejoined an in progress game, send the rejoined message to the server. | ||||
if (client->m_Rejoin) | if (client->m_Rejoin) | ||||
client->SendRejoinedMessage(); | client->SendRejoinedMessage(); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetClient::OnInGame(void *context, CFsmEvent* event) | bool CNetClient::OnInGame(void *context, const CFsmEvent& event) | ||||
{ | { | ||||
// TODO: should split each of these cases into a separate method | // TODO: should split each of these cases into a separate method | ||||
CNetClient* client = (CNetClient*)context; | CNetClient* client = (CNetClient*)context; | ||||
CNetMessage* message = (CNetMessage*)event->GetParamRef(); | const CNetMessageBuffer& message = event.GetMessageBuffer(); | ||||
if (message) | switch (message.GetType()) | ||||
Done Inline Actionsswitch leper: `switch` | |||||
{ | { | ||||
if (message->GetType() == NMT_SIMULATION_COMMAND) | case NMT_SIMULATION_COMMAND: | ||||
{ | { | ||||
CSimulationMessage* simMessage = static_cast<CSimulationMessage*> (message); | CSimulationMessage simMessage(client->GetScriptInterface(), message); | ||||
client->m_ClientTurnManager->OnSimulationMessage(simMessage); | client->m_ClientTurnManager->OnSimulationMessage(&simMessage); | ||||
break; | |||||
} | } | ||||
else if (message->GetType() == NMT_SYNC_ERROR) | case NMT_SYNC_ERROR: | ||||
{ | { | ||||
CSyncErrorMessage* syncMessage = static_cast<CSyncErrorMessage*> (message); | CSyncErrorMessage syncMessage(message); | ||||
client->m_ClientTurnManager->OnSyncError(syncMessage->m_Turn, syncMessage->m_HashExpected, syncMessage->m_PlayerNames); | client->m_ClientTurnManager->OnSyncError(syncMessage.m_Turn, syncMessage.m_HashExpected, syncMessage.m_PlayerNames); | ||||
break; | |||||
} | } | ||||
else if (message->GetType() == NMT_END_COMMAND_BATCH) | case NMT_END_COMMAND_BATCH: | ||||
{ | { | ||||
CEndCommandBatchMessage* endMessage = static_cast<CEndCommandBatchMessage*> (message); | CEndCommandBatchMessage endMessage(message); | ||||
client->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn, endMessage->m_TurnLength); | client->m_ClientTurnManager->FinishedAllCommands(endMessage.m_Turn, endMessage.m_TurnLength); | ||||
break; | |||||
} | } | ||||
} | } | ||||
return true; | return true; | ||||
} | } |
Wildfire Games · Phabricator
nullptr?