/*! \brief Called when a player asks to select a kart. * \param event : Event providing the information. * * Format of the data : * Byte 0 1 5 6 N+6 * --------------------------------------------------- * Size | 1 | 4 | 1 | N | * Data | 4 | priv token | N (kart name size) | kart name | * --------------------------------------------------- */ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event) { NetworkString data = event->data(); STKPeer* peer = *(event->peer); if (!checkDataSizeAndToken(event, 6)) return; uint8_t kart_name_size = data.gui8(5); std::string kart_name = data.gs(6, kart_name_size); if (kart_name.size() != kart_name_size) { Log::error("ServerLobbyRoomProtocol", "Kart names sizes differ: told:" "%d, real: %d.", kart_name_size, kart_name.size()); return; } // check if selection is possible if (!m_selection_enabled) { NetworkString answer; answer.ai8(0x82).ai8(1).ai8(2); // selection still not started m_listener->sendMessage(this, peer, answer); return; } // check if somebody picked that kart if (!m_setup->isKartAvailable(kart_name)) { NetworkString answer; answer.ai8(0x82).ai8(1).ai8(0); // kart is already taken m_listener->sendMessage(this, peer, answer); return; } // check if this kart is authorized if (!m_setup->isKartAllowed(kart_name)) { NetworkString answer; answer.ai8(0x82).ai8(1).ai8(1); // kart is not authorized m_listener->sendMessage(this, peer, answer); return; } // send a kart update to everyone NetworkString answer; // kart update (3), 1, race id answer.ai8(0x03).ai8(1).ai8(peer->getPlayerProfile()->race_id); // kart name size, kart name answer.ai8(kart_name.size()).as(kart_name); m_listener->sendMessage(this, answer); m_setup->setPlayerKart(peer->getPlayerProfile()->race_id, kart_name); }
void ServerLobbyRoomProtocol::kartDisconnected(Event* event) { STKPeer* peer = *(event->peer); if (peer->getPlayerProfile() != NULL) // others knew him { NetworkString msg; msg.ai8(0x02).ai8(1).ai8(peer->getPlayerProfile()->race_id); m_listener->sendMessage(this, msg); Log::info("ServerLobbyRoomProtocol", "Player disconnected : id %d", peer->getPlayerProfile()->race_id); m_setup->removePlayer(peer->getPlayerProfile()->race_id); NetworkManager::getInstance()->removePeer(peer); } else Log::info("ServerLobbyRoomProtocol", "The DC peer wasn't registered."); }
void ServerLobbyRoomProtocol::kartDisconnected(Event* event) { STKPeer* peer = event->getPeer(); if (peer->getPlayerProfile() != NULL) // others knew him { NetworkString msg(3); msg.ai8(LE_PLAYER_DISCONNECTED).ai8(1) .ai8(peer->getPlayerProfile()->getGlobalPlayerId()); sendMessage(msg); Log::info("ServerLobbyRoomProtocol", "Player disconnected : id %d", peer->getPlayerProfile()->getGlobalPlayerId()); m_setup->removePlayer(peer->getPlayerProfile()); // Remove the profile from the peer (to avoid double free) peer->setPlayerProfile(NULL); STKHost::get()->removePeer(peer); } else Log::info("ServerLobbyRoomProtocol", "The DC peer wasn't registered."); } // kartDisconnected
/*! \brief Called when a player asks to select a kart. * \param event : Event providing the information. * * Format of the data : * Byte 0 1 5 6 N+6 * --------------------------------------------------- * Size | 1 | 4 | 1 | N | * Data | 4 | priv token | N (kart name size) | kart name | * --------------------------------------------------- */ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event) { if(m_state!=SELECTING_KARTS) { Log::warn("Server", "Received kart selection while in state %d.", m_state); return; } const NetworkString &data = event->data(); STKPeer* peer = event->getPeer(); if (!checkDataSizeAndToken(event, 6)) return; std::string kart_name; data.decodeString(5, &kart_name); // check if selection is possible if (!m_selection_enabled) { NetworkString answer(3); // selection still not started answer.ai8(LE_KART_SELECTION_REFUSED).ai8(1).ai8(2); sendMessage(peer, answer); return; } // check if somebody picked that kart if (!m_setup->isKartAvailable(kart_name)) { NetworkString answer(3); // kart is already taken answer.ai8(LE_KART_SELECTION_REFUSED).ai8(1).ai8(0); sendMessage(peer, answer); return; } // check if this kart is authorized if (!m_setup->isKartAllowed(kart_name)) { NetworkString answer(3); // kart is not authorized answer.ai8(LE_KART_SELECTION_REFUSED).ai8(1).ai8(1); sendMessage(peer, answer); return; } // send a kart update to everyone NetworkString answer(3+1+kart_name.size()); // kart update (3), 1, race id uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId(); answer.ai8(LE_KART_SELECTION_UPDATE).ai8(1).ai8(player_id) .encodeString(kart_name); // This message must be handled synchronously on the client. sendSynchronousMessage(answer); m_setup->setPlayerKart(player_id, kart_name); } // kartSelectionRequested
// ---------------------------------------------------------------------------- bool StartGameProtocol::notifyEventAsynchronous(Event* event) { const NetworkString &data = event->data(); if (data.size() < 5) { Log::error("StartGameProtocol", "Too short message."); return true; } uint32_t token = data.gui32(); uint8_t ready = data.gui8(4); STKPeer* peer = event->getPeer(); if (peer->getClientServerToken() != token) { Log::error("StartGameProtocol", "Bad token received."); return true; } if (NetworkConfig::get()->isServer() && ready) // on server, player is ready { Log::info("StartGameProtocol", "One of the players is ready."); m_player_states[peer->getPlayerProfile()] = READY; m_ready_count++; if (m_ready_count == m_game_setup->getPlayerCount()) { // everybody ready, synchronize Protocol *p = ProtocolManager::getInstance() ->getProtocol(PROTOCOL_SYNCHRONIZATION); SynchronizationProtocol* protocol = static_cast<SynchronizationProtocol*>(p); if (protocol) { protocol->startCountdown(5000); // 5 seconds countdown Log::info("StartGameProtocol", "All players ready, starting countdown."); m_ready = true; return true; } else Log::error("StartGameProtocol", "The Synchronization protocol hasn't been started."); } // if m_ready_count == number of players } else // on the client, we shouldn't even receive messages. { Log::error("StartGameProtocol", "Received a message with bad format."); } return true; } // notifyEventAsynchronous
/*! \brief Called when a player votes for the number of races in a GP. * \param event : Event providing the information. * * Format of the data : * Byte 0 1 5 6 7 * ------------------------------------ * Size | 1 | 4 | 1 | 1 | * Data | 4 | priv token | 1 | races count | * ------------------------------------ */ void ServerLobbyRoomProtocol::playerRaceCountVote(Event* event) { NetworkString &data = event->data(); STKPeer* peer = event->getPeer(); if (!checkDataSizeAndToken(event, 7)) return; if (!isByteCorrect(event, 5, 1)) return; uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId(); m_setup->getRaceConfig()->setPlayerRaceCountVote(player_id, data[6]); // Send the vote to everybody (including the sender) data.removeFront(5); // remove the token NetworkString other(2+data.size()); other.ai8(1).ai8(player_id); // add the player id other += data; // add the data sendMessageToPeersChangingToken(LE_VOTE_RACE_COUNT, other); } // playerRaceCountVote
/*! \brief Called when a player votes for a minor race mode. * \param event : Event providing the information. * * Format of the data : * Byte 0 1 5 6 7 * ---------------------------------------- * Size | 1 | 4 | 1 | 1 | * Data | 4 | priv token | 1 | minor mode vote | * ---------------------------------------- */ void ServerLobbyRoomProtocol::playerMinorVote(Event* event) { NetworkString data = event->data(); STKPeer* peer = *(event->peer); if (!checkDataSizeAndToken(event, 7)) return; if (!isByteCorrect(event, 5, 1)) return; uint8_t player_id = peer->getPlayerProfile()->race_id; m_setup->getRaceConfig()->setPlayerMinorVote(player_id, data[6]); // Send the vote to everybody (including the sender) NetworkString other; other.ai8(1).ai8(player_id); // add the player id data.removeFront(5); // remove the token other += data; // add the data NetworkString prefix; prefix.ai8(0xc2); // prefix the token with the ype sendMessageToPeersChangingToken(prefix, other); }
/*! \brief Called when a player votes for a track. * \param event : Event providing the information. * * Format of the data : * Byte 0 1 5 6 N+6 N+7 N+8 * ----------------------------------------------------------- * Size | 1 | 4 | 1 | N | 1 | 1 | * Data | 4 | priv token | N | track name | 1 | track number (gp) | * ----------------------------------------------------------- */ void ServerLobbyRoomProtocol::playerTrackVote(Event* event) { NetworkString &data = event->data(); STKPeer* peer = event->getPeer(); if (!checkDataSizeAndToken(event, 8)) return; std::string track_name; int N = data.decodeString(5, &track_name); if (!isByteCorrect(event, N+5, 1)) return; uint8_t player_id = peer->getPlayerProfile()->getGlobalPlayerId(); m_setup->getRaceConfig()->setPlayerTrackVote(player_id, track_name, data[N+6]); // Send the vote to everybody (including the sender) data.removeFront(5); // remove the token NetworkString other(2+data.size()); other.ai8(1).ai8(player_id); // add the player id other += data; // add the data sendMessageToPeersChangingToken(LE_VOTE_TRACK, other); if(m_setup->getRaceConfig()->getNumTrackVotes()==m_setup->getPlayerCount()) startGame(); } // playerTrackVote