bool CNetClient::OnInGame(void *context, CFsmEvent* event) { // TODO: should split each of these cases into a separate method CNetClient* client = (CNetClient*)context; CNetMessage* message = (CNetMessage*)event->GetParamRef(); if (message) { if (message->GetType() == NMT_SIMULATION_COMMAND) { CSimulationMessage* simMessage = static_cast<CSimulationMessage*> (message); client->m_ClientTurnManager->OnSimulationMessage(simMessage); } else if (message->GetType() == NMT_SYNC_ERROR) { CSyncErrorMessage* syncMessage = static_cast<CSyncErrorMessage*> (message); client->m_ClientTurnManager->OnSyncError(syncMessage->m_Turn, syncMessage->m_HashExpected, syncMessage->m_PlayerNames); } else if (message->GetType() == NMT_END_COMMAND_BATCH) { CEndCommandBatchMessage* endMessage = static_cast<CEndCommandBatchMessage*> (message); client->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn, endMessage->m_TurnLength); } } return true; }
bool CNetServerWorker::OnInGame(void* context, CFsmEvent* event) { // TODO: should split each of these cases into a separate method CNetServerSession* session = (CNetServerSession*)context; CNetServerWorker& server = session->GetServer(); CNetMessage* message = (CNetMessage*)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 // unless cheating is enabled bool cheatsEnabled = false; ScriptInterface& scriptInterface = server.GetScriptInterface(); JSContext* cx = scriptInterface.GetContext(); JSAutoRequest rq(cx); JS::RootedValue settings(cx); scriptInterface.GetProperty(server.m_GameAttributes.get(), "settings", &settings); if (scriptInterface.HasProperty(settings, "CheatsEnabled")) scriptInterface.GetProperty(settings, "CheatsEnabled", cheatsEnabled); PlayerAssignmentMap::iterator it = server.m_PlayerAssignments.find(session->GetGUID()); // 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 if (!cheatsEnabled && (it == server.m_PlayerAssignments.end() || it->second.m_PlayerID != simMessage->m_Player)) return true; // Send it back to all clients immediately server.Broadcast(simMessage); // Save all the received commands if (server.m_SavedCommands.size() < simMessage->m_Turn + 1) server.m_SavedCommands.resize(simMessage->m_Turn + 1); server.m_SavedCommands[simMessage->m_Turn].push_back(*simMessage); // TODO: we shouldn't send the message back to the client that first sent it } 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); } else if (message->GetType() == (uint)NMT_END_COMMAND_BATCH) { CEndCommandBatchMessage* endMessage = static_cast<CEndCommandBatchMessage*> (message); server.m_ServerTurnManager->NotifyFinishedClientCommands(session->GetHostID(), endMessage->m_Turn); } return true; }
bool CNetServerWorker::OnInGame(void* context, CFsmEvent* event) { // TODO: should split each of these cases into a separate method CNetServerSession* session = (CNetServerSession*)context; CNetServerWorker& server = session->GetServer(); CNetMessage* message = (CNetMessage*)event->GetParamRef(); if (message->GetType() == (uint)NMT_SIMULATION_COMMAND) { CSimulationMessage* simMessage = static_cast<CSimulationMessage*> (message); // Send it back to all clients immediately server.Broadcast(simMessage); // Save all the received commands if (server.m_SavedCommands.size() < simMessage->m_Turn + 1) server.m_SavedCommands.resize(simMessage->m_Turn + 1); server.m_SavedCommands[simMessage->m_Turn].push_back(*simMessage); // TODO: we should do some validation of ownership (clients can't send commands on behalf of opposing players) // TODO: we shouldn't send the message back to the client that first sent it } else if (message->GetType() == (uint)NMT_SYNC_CHECK) { CSyncCheckMessage* syncMessage = static_cast<CSyncCheckMessage*> (message); server.m_ServerTurnManager->NotifyFinishedClientUpdate(session->GetHostID(), syncMessage->m_Turn, syncMessage->m_Hash); } else if (message->GetType() == (uint)NMT_END_COMMAND_BATCH) { CEndCommandBatchMessage* endMessage = static_cast<CEndCommandBatchMessage*> (message); server.m_ServerTurnManager->NotifyFinishedClientCommands(session->GetHostID(), endMessage->m_Turn); } return true; }
CNetMessage* CNetMessageFactory::CreateMessage(const void* pData, size_t dataSize, ScriptInterface& scriptInterface) { CNetMessage* pNewMessage = NULL; CNetMessage header; // Figure out message type header.Deserialize((const u8*)pData, (const u8*)pData + dataSize); switch (header.GetType()) { case NMT_GAME_SETUP: pNewMessage = new CGameSetupMessage(scriptInterface); break; case NMT_PLAYER_ASSIGNMENT: pNewMessage = new CPlayerAssignmentMessage; break; case NMT_FILE_TRANSFER_REQUEST: pNewMessage = new CFileTransferRequestMessage; break; case NMT_FILE_TRANSFER_RESPONSE: pNewMessage = new CFileTransferResponseMessage; break; case NMT_FILE_TRANSFER_DATA: pNewMessage = new CFileTransferDataMessage; break; case NMT_FILE_TRANSFER_ACK: pNewMessage = new CFileTransferAckMessage; break; case NMT_JOIN_SYNC_START: pNewMessage = new CJoinSyncStartMessage; break; case NMT_REJOINED: pNewMessage = new CRejoinedMessage; break; case NMT_KICKED: pNewMessage = new CKickedMessage; break; case NMT_LOADED_GAME: pNewMessage = new CLoadedGameMessage; break; case NMT_SERVER_HANDSHAKE: pNewMessage = new CSrvHandshakeMessage; break; case NMT_SERVER_HANDSHAKE_RESPONSE: pNewMessage = new CSrvHandshakeResponseMessage; break; case NMT_CLIENT_HANDSHAKE: pNewMessage = new CCliHandshakeMessage; break; case NMT_AUTHENTICATE: pNewMessage = new CAuthenticateMessage; break; case NMT_AUTHENTICATE_RESULT: pNewMessage = new CAuthenticateResultMessage; break; case NMT_GAME_START: pNewMessage = new CGameStartMessage; break; case NMT_END_COMMAND_BATCH: pNewMessage = new CEndCommandBatchMessage; break; case NMT_SYNC_CHECK: pNewMessage = new CSyncCheckMessage; break; case NMT_SYNC_ERROR: pNewMessage = new CSyncErrorMessage; break; case NMT_CHAT: pNewMessage = new CChatMessage; break; case NMT_READY: pNewMessage = new CReadyMessage; break; case NMT_SIMULATION_COMMAND: pNewMessage = new CSimulationMessage(scriptInterface); break; default: LOGERROR("CNetMessageFactory::CreateMessage(): Unknown message type '%d' received", header.GetType()); break; } if (pNewMessage) pNewMessage->Deserialize((const u8*)pData, (const u8*)pData + dataSize); return pNewMessage; }