both client and server. Voting time now starts from the moment the kart screen is shown (not on first player having finished voting). Improved coding style.
171 lines
6.7 KiB
C++
171 lines
6.7 KiB
C++
//
|
|
// 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> 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<GameEventsProtocol>();
|
|
RaceEventManager::getInstance<RaceEventManager>()->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<std::shared_ptr<NetworkPlayerProfile> >& 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<NetworkPlayerProfile> 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
|
|
|