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 for a connection. * \param event : Event providing the information. * * Format of the data : * Byte 0 1 5 * ------------------------ * Size | 1 | 4 | * Data | 4 | global player id | * ------------------------ */ void ServerLobbyRoomProtocol::connectionRequested(Event* event) { STKPeer* peer = *(event->peer); NetworkString data = event->data(); if (data.size() != 5 || data[0] != 4) { Log::warn("ServerLobbyRoomProtocol", "Receiving badly formated message. Size is %d and first byte %d", data.size(), data[0]); return; } uint32_t player_id = 0; player_id = data.getUInt32(1); // can we add the player ? if (m_setup->getPlayerCount() < ServerNetworkManager::getInstance()->getMaxPlayers()) //accept { // add the player to the game setup m_next_id = m_setup->getPlayerCount(); // notify everybody that there is a new player NetworkString message; // new player (1) -- size of id -- id -- size of local id -- local id; message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id); m_listener->sendMessageExcept(this, peer, message); /// now answer to the peer that just connected RandomGenerator token_generator; // use 4 random numbers because rand_max is probably 2^15-1. uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) + ((token_generator.get(RAND_MAX)<<16) & 0xff) + ((token_generator.get(RAND_MAX)<<8) & 0xff) + ((token_generator.get(RAND_MAX) & 0xff))); // send a message to the one that asked to connect NetworkString message_ack; // connection success (129) -- size of token -- token message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id); // add all players so that this user knows std::vector<NetworkPlayerProfile*> players = m_setup->getPlayers(); for (unsigned int i = 0; i < players.size(); i++) { // do not duplicate the player into the message if (players[i]->race_id != m_next_id && players[i]->user_profile->getID() != player_id) message_ack.ai8(1).ai8(players[i]->race_id).ai8(4).ai32(players[i]->user_profile->getID()); } m_listener->sendMessage(this, peer, message_ack); peer->setClientServerToken(token); NetworkPlayerProfile* profile = new NetworkPlayerProfile(); profile->race_id = m_next_id; profile->kart_name = ""; profile->user_profile = new Online::OnlineProfile(player_id, ""); m_setup->addPlayer(profile); peer->setPlayerProfile(profile); Log::verbose("ServerLobbyRoomProtocol", "New player."); } // accept player else // refuse the connection with code 0 (too much players) { NetworkString message; message.ai8(0x80); // 128 means connection refused message.ai8(1); // 1 bytes for the error code message.ai8(0); // 0 = too much players // send only to the peer that made the request m_listener->sendMessage(this, peer, message); Log::verbose("ServerLobbyRoomProtocol", "Player refused"); } }
/*! \brief Called when a player asks for a connection. * \param event : Event providing the information. * * Format of the data : * Byte 0 1 * --------------------- * Size | 1 |1| | * Data | 4 |n| player name | * --------------------- */ void ServerLobbyRoomProtocol::connectionRequested(Event* event) { STKPeer* peer = event->getPeer(); const NetworkString &data = event->data(); // can we add the player ? if (m_setup->getPlayerCount() >= NetworkConfig::get()->getMaxPlayers() || m_state!=ACCEPTING_CLIENTS ) { NetworkString message(3); // Len, error code: 2 = busy, 0 = too many players message.ai8(LE_CONNECTION_REFUSED).ai8(1) .ai8(m_state!=ACCEPTING_CLIENTS ? 2 : 0); // send only to the peer that made the request sendMessage(peer, message); Log::verbose("ServerLobbyRoomProtocol", "Player refused"); return; } // Connection accepted. // ==================== std::string name_u8; int len = data.decodeString(0, &name_u8); core::stringw name = StringUtils::utf8ToWide(name_u8); std::string password; data.decodeString(len, &password); bool is_authorised = (password==NetworkConfig::get()->getPassword()); // Get the unique global ID for this player. m_next_player_id.lock(); m_next_player_id.getData()++; int new_player_id = m_next_player_id.getData(); m_next_player_id.unlock(); if(m_setup->getLocalMasterID()==0) m_setup->setLocalMaster(new_player_id); // The host id has already been incremented when the peer // was added, so it is the right id now. int new_host_id = STKHost::get()->getNextHostId(); // Notify everybody that there is a new player // ------------------------------------------- NetworkString message(8); // size of id -- id -- size of local id -- local id; message.ai8(LE_NEW_PLAYER_CONNECTED).ai8(1).ai8(new_player_id) .encodeString(name_u8).addUInt8(new_host_id); ProtocolManager::getInstance()->sendMessageExcept(this, peer, message); // Now answer to the peer that just connected // ------------------------------------------ RandomGenerator token_generator; // use 4 random numbers because rand_max is probably 2^15-1. uint32_t token = (uint32_t)((token_generator.get(RAND_MAX) & 0xff) << 24 | (token_generator.get(RAND_MAX) & 0xff) << 16 | (token_generator.get(RAND_MAX) & 0xff) << 8 | (token_generator.get(RAND_MAX) & 0xff)); const std::vector<NetworkPlayerProfile*> &players = m_setup->getPlayers(); // send a message to the one that asked to connect // Size is overestimated, probably one player's data will not be sent NetworkString message_ack(14 + players.size() * 7); // connection success -- size of token -- token message_ack.ai8(LE_CONNECTION_ACCEPTED).ai8(1).ai8(new_player_id).ai8(4) .ai32(token).addUInt8(new_host_id).addUInt8(is_authorised); // Add all players so that this user knows (this new player is only added // to the list of players later, so the new player's info is not included) for (unsigned int i = 0; i < players.size(); i++) { message_ack.ai8(1).ai8(players[i]->getGlobalPlayerId()) .encodeString(players[i]->getName()) .addUInt8(players[i]->getHostId()); } sendMessage(peer, message_ack); NetworkPlayerProfile* profile = new NetworkPlayerProfile(new_player_id, name); profile->setHostId(new_host_id); m_setup->addPlayer(profile); peer->setPlayerProfile(profile); peer->setClientServerToken(token); peer->setAuthorised(is_authorised); peer->setHostId(new_host_id); Log::verbose("ServerLobbyRoomProtocol", "New player."); } // connectionRequested