// // SuperTuxKart - a fun racing game with go-kart // Copyright (C) 2013-2015 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 3 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "network/protocols/lobby_protocol.hpp" #include "input/input_manager.hpp" #include "input/device_manager.hpp" #include "modes/world.hpp" #include "network/game_setup.hpp" #include "network/network_config.hpp" #include "network/network_player_profile.hpp" #include "network/protocols/game_protocol.hpp" #include "network/protocols/game_events_protocol.hpp" #include "network/race_event_manager.hpp" #include "race/race_manager.hpp" #include "states_screens/state_manager.hpp" #include "utils/time.hpp" std::weak_ptr LobbyProtocol::m_lobby; LobbyProtocol::LobbyProtocol(CallbackObject* callback_object) : Protocol(PROTOCOL_LOBBY_ROOM, callback_object) { m_game_setup = new GameSetup(); m_end_voting_period.store(0); } // LobbyProtocol // ---------------------------------------------------------------------------- LobbyProtocol::~LobbyProtocol() { if (RaceEventManager::getInstance()) RaceEventManager::getInstance()->stop(); delete m_game_setup; joinStartGameThread(); } // ~LobbyProtocol //----------------------------------------------------------------------------- /** Starts the sychronization protocol and the RaceEventManager. It then * sets the player structures up, creates the active player, and loads * the world. * This is called on the client when the server informs them that * the world can be loaded (LE_LOAD_WORLD) and on the server in state * LOAD_WORLD (i.e. just after informing all clients). */ void LobbyProtocol::loadWorld() { Log::info("LobbyProtocol", "Ready !"); // Race startup sequence // --------------------- // This creates the network world. auto gep = std::make_shared(); RaceEventManager::getInstance()->start(gep); // Make sure that if there is only a single local player this player can // use all input devices. StateManager::ActivePlayer *ap = race_manager->getNumLocalPlayers()>1 ? NULL : StateManager::get()->getActivePlayer(0); input_manager->getDeviceManager()->setSinglePlayer(ap); // Load the actual world. m_game_setup->loadWorld(); World::getWorld()->setNetworkWorld(true); GameProtocol::createInstance()->requestStart(); gep->requestStart(); } // loadWorld // ---------------------------------------------------------------------------- void LobbyProtocol::configRemoteKart( const std::vector >& players) const { // The number of karts includes the AI karts, which are not supported atm race_manager->setNumKarts((int)players.size()); // Set number of global and local players. race_manager->setNumPlayers((int)players.size(), (int)NetworkConfig::get()->getNetworkPlayers().size()); // Create the kart information for the race manager: // ------------------------------------------------- for (unsigned int i = 0; i < players.size(); i++) { std::shared_ptr profile = players[i]; bool is_local = profile->isLocalPlayer(); // All non-local players are created here. This means all players // on the server, and all non-local players on a client (the local // karts are created in the ClientLobby). int local_player_id = profile->getLocalPlayerId(); if (!is_local) { // No device or player profile is needed for remote kart. local_player_id = (int)(StateManager::get()->createActivePlayer(NULL, NULL)); } // Adjust the local player id so that local players have the numbers // 0 to num-1; and all other karts start with num. This way the local // players get the first ActivePlayers assigned (which have the // corresponding device associated with it). RemoteKartInfo rki(local_player_id, profile->getKartName(), profile->getName(), profile->getHostId(), !is_local); rki.setGlobalPlayerId(i); rki.setDefaultKartColor(profile->getDefaultKartColor()); rki.setPerPlayerDifficulty(profile->getPerPlayerDifficulty()); rki.setOnlineId(profile->getOnlineId()); if (race_manager->teamEnabled()) rki.setKartTeam(profile->getTeam()); // Inform the race manager about the data for this kart. race_manager->setPlayerKart(i, rki); } // for i in players // Clean all previous AI if exists in offline game race_manager->computeRandomKartList(); Log::info("LobbyProtocol", "Player configuration ready."); } // configRemoteKart //----------------------------------------------------------------------------- /** A previous GameSetup is deleted and a new one is created. * \return Newly create GameSetup object. */ void LobbyProtocol::setup() { m_game_setup->reset(); } // setupNewGame //----------------------------------------------------------------------------- /** Starts the voting period time with the specified maximum time. * \param max_time Maximum voting time in seconds */ void LobbyProtocol::startVotingPeriod(float max_time) { m_max_voting_time = uint64_t(max_time*1000); m_end_voting_period.store(StkTime::getRealTimeMs() + m_max_voting_time); } // startVotingPeriod //----------------------------------------------------------------------------- /** Returns the remaining voting time in seconds. */ int LobbyProtocol::getRemainingVotingTime() { uint64_t t = m_end_voting_period.load()- StkTime::getRealTimeMs(); return int(t/1000); } // getRemainingVotingTime //----------------------------------------------------------------------------- /** Returns if the voting period is over. */ bool LobbyProtocol::isVotingOver() { return m_end_voting_period.load() < StkTime::getRealTimeMs(); } // isVotingOver