Initial work to port network profile to use weak_ptr

This commit is contained in:
Benau 2018-03-14 15:48:02 +08:00
parent ea8ba470d6
commit 1b8d4c80dc
18 changed files with 263 additions and 542 deletions

View File

@ -48,7 +48,7 @@ WorldStatus::WorldStatus()
m_play_track_intro_sound = UserConfigParams::m_music;
m_play_ready_set_go_sounds = true;
m_play_racestart_sounds = true;
m_server_is_ready = false;
m_server_is_ready.store(false);
IrrlichtDevice *device = irr_driver->getDevice();
@ -98,7 +98,7 @@ void WorldStatus::reset()
// In case of a networked race the race can only start once
// all protocols are up. This flag is used to wait for
// a confirmation before starting the actual race.
m_server_is_ready = false;
m_server_is_ready.store(false);
} // reset
//-----------------------------------------------------------------------------
@ -259,7 +259,7 @@ void WorldStatus::updateTime(const float dt)
// loaded the world). The server waits for a confirmation from
// each client that they have started (to guarantee that the
// server is running with a local time behind all clients).
if (!m_server_is_ready) return;
if (m_server_is_ready.load() == false) return;
m_phase = READY_PHASE;
auto cl = LobbyProtocol::get<ClientLobby>();
@ -474,7 +474,7 @@ float WorldStatus::adjustDT(float dt)
*/
void WorldStatus::startReadySetGo()
{
m_server_is_ready = true;
m_server_is_ready.store(true);
} // startReadySetGo
//-----------------------------------------------------------------------------

View File

@ -19,6 +19,7 @@
#define HEADER_WORLD_STATUS_HPP
#include "utils/cpp2011.hpp"
#include <atomic>
class SFXBase;
@ -138,7 +139,7 @@ private:
* set go' to make sure all client are actually ready to start the game.
* A server on the other hand will run behind all clients, so it will
* wait for all clients to indicate that they have started the race. */
bool m_server_is_ready;
std::atomic_bool m_server_is_ready;
void startEngines();
@ -205,7 +206,7 @@ public:
/** Get the time since start regardless of which way the clock counts */
float getTimeSinceStart() const { return m_count_up_timer; }
// ------------------------------------------------------------------------
void setReadyToRace() { m_server_is_ready = true; }
void setReadyToRace() { m_server_is_ready.store(true); }
// ------------------------------------------------------------------------
/** Sets a time by which the clock should be adjusted. Used by networking
* if too many rewinds are detected. */

View File

@ -19,6 +19,7 @@
#include "network/game_setup.hpp"
#include "karts/abstract_kart.hpp"
#include "network/race_config.hpp"
#include "modes/world.hpp"
#include "network/network_player_profile.hpp"
#include "online/online_profile.hpp"
@ -39,43 +40,39 @@ GameSetup::GameSetup()
GameSetup::~GameSetup()
{
// remove all players
for (unsigned int i = 0; i < m_players.size(); i++)
{
delete m_players[i];
};
m_players.clear();
delete m_race_config;
} // ~GameSetup
//-----------------------------------------------------------------------------
void GameSetup::addPlayer(NetworkPlayerProfile* profile)
void GameSetup::addPlayer(std::shared_ptr<NetworkPlayerProfile> profile)
{
m_players.push_back(profile);
Log::info("GameSetup", "New player in the game setup. Player id : %d.",
profile->getGlobalPlayerId());
Log::info("GameSetup", "New player in the game setup. Player name : %s.",
StringUtils::wideToUtf8(profile->getName()).c_str());
} // addPlayer
//-----------------------------------------------------------------------------
/** Removed a player give his NetworkPlayerProfile.
* \param profile The NetworkPlayerProfile to remove.
* \return True if the player was found and removed, false otherwise.
/** Update and see if any player disconnects.
* \param remove_disconnected_players remove the disconnected players,
* otherwise replace with AI (when racing), so this function must be called
* in main thread.
*/
bool GameSetup::removePlayer(const NetworkPlayerProfile *profile)
void GameSetup::update(bool remove_disconnected_players)
{
for (unsigned int i = 0; i < m_players.size(); i++)
std::unique_lock<std::mutex> lock(m_players_mutex);
if (remove_disconnected_players)
{
if (m_players[i] == profile)
{
delete m_players[i];
m_players.erase(m_players.begin()+i, m_players.begin()+i+1);
Log::verbose("GameSetup",
"Removed a player from the game setup. Remains %u.",
m_players.size());
return true;
}
m_players.erase(std::remove_if(m_players.begin(), m_players.end(), []
(const std::weak_ptr<NetworkPlayerProfile> npp)->bool
{
return npp.expired();
}), m_players.end());
return;
}
return false;
lock.unlock();
if (!World::getWorld())
return;
} // removePlayer
//-----------------------------------------------------------------------------
@ -97,38 +94,13 @@ bool GameSetup::isLocalMaster(uint8_t player_id)
return m_local_master == player_id;
} // isLocalMaster
//-----------------------------------------------------------------------------
/** Sets the kart the specified player uses.
* \param player_id ID of this player (in this race).
* \param kart_name Name of the kart the player picked.
*/
void GameSetup::setPlayerKart(uint8_t player_id, const std::string &kart_name)
{
bool found = false;
for (unsigned int i = 0; i < m_players.size(); i++)
{
if (m_players[i]->getGlobalPlayerId() == player_id)
{
m_players[i]->setKartName(kart_name);
Log::info("GameSetup::setPlayerKart", "Player %d took kart %s",
player_id, kart_name.c_str());
found = true;
}
}
if (!found)
{
Log::info("GameSetup::setPlayerKart", "The player %d was unknown.",
player_id);
}
} // setPlayerKart
//-----------------------------------------------------------------------------
void GameSetup::bindKartsToProfiles()
{
World::KartList karts = World::getWorld()->getKarts();
for (unsigned int i = 0; i < m_players.size(); i++)
/*for (unsigned int i = 0; i < m_players.size(); i++)
{
Log::info("GameSetup", "Player %d has id %d and kart %s", i,
m_players[i]->getGlobalPlayerId(),
@ -155,73 +127,5 @@ void GameSetup::bindKartsToProfiles()
{
Log::error("GameSetup", "Error while binding world kart ids to players profiles.");
}
}
}*/
} // bindKartsToProfiles
//-----------------------------------------------------------------------------
/** \brief Get a network player profile with the specified player id.
* \param player_id : Player id in this race.
* \return The profile of the player having the specified player id, or
* NULL if no such player exists.
*/
const NetworkPlayerProfile* GameSetup::getProfile(uint8_t player_id)
{
for (unsigned int i = 0; i < m_players.size(); i++)
{
if (m_players[i]->getGlobalPlayerId()== player_id)
{
return m_players[i];
}
}
return NULL;
} // getProfile
//-----------------------------------------------------------------------------
/** \brief Get a network player profile matching a kart name.
* \param kart_name : Name of the kart used by the player.
* \return The profile of the player having the kart kart_name, or NULL
* if no such network profile exists.
*/
const NetworkPlayerProfile* GameSetup::getProfile(const std::string &kart_name)
{
for (unsigned int i = 0; i < m_players.size(); i++)
{
if (m_players[i]->getKartName() == kart_name)
{
return m_players[i];
}
}
return NULL;
} // getProfile(kart_name)
//-----------------------------------------------------------------------------
/** Returns the list of all player profiles from a specified host. Note that
* this function is somewhat expensive (it loops over all network profiles
* to find the ones with the specified host id).
* \param host_id The host id which players should be collected.
* \return List of NetworkPlayerProfile pointers/
*/
std::vector<NetworkPlayerProfile*> GameSetup::getAllPlayersOnHost(uint8_t host_id)
{
std::vector<NetworkPlayerProfile*> result;
for (unsigned int i = 0; i < m_players.size(); i++)
{
if (m_players[i]->getHostId() == host_id)
result.push_back(m_players[i]);
}
return result;
} // getAllPlayersOnHost
//-----------------------------------------------------------------------------
bool GameSetup::isKartAvailable(std::string kart_name)
{
for (unsigned int i = 0; i < m_players.size(); i++)
{
if (m_players[i]->getKartName() == kart_name)
return false;
}
return true;
}

View File

@ -22,15 +22,16 @@
#ifndef GAME_SETUP_HPP
#define GAME_SETUP_HPP
#include "network/race_config.hpp"
#include "network/remote_kart_info.hpp"
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
class NetworkPlayerProfile;
class RaceConfig;
// ============================================================================
/*! \class GameSetup
@ -40,8 +41,10 @@ class NetworkPlayerProfile;
class GameSetup
{
private:
mutable std::mutex m_players_mutex;
/** Information about all connected players. */
std::vector<NetworkPlayerProfile*> m_players;
std::vector<std::weak_ptr<NetworkPlayerProfile> > m_players;
/** The race configuration. */
RaceConfig* m_race_config;
@ -52,26 +55,22 @@ private:
/** The player id of the local game master, used in
* kart selection screen. */
uint8_t m_local_master;
public:
GameSetup();
virtual ~GameSetup();
void addPlayer(NetworkPlayerProfile* profile); //!< Add a player.
bool removePlayer(const NetworkPlayerProfile *profile);
void setPlayerKart(uint8_t player_id, const std::string &kart_name);
void bindKartsToProfiles(); //!< Sets the right world_kart_id in profiles
// ------------------------------------------------------------------------
GameSetup();
// ------------------------------------------------------------------------
~GameSetup();
// ------------------------------------------------------------------------
void addPlayer(std::shared_ptr<NetworkPlayerProfile> profile);
// ------------------------------------------------------------------------
void update(bool remove_disconnected_players);
// ------------------------------------------------------------------------
void bindKartsToProfiles();
// ------------------------------------------------------------------------
void setLocalMaster(uint8_t player_id);
// ------------------------------------------------------------------------
bool isLocalMaster(uint8_t player_id);
const NetworkPlayerProfile* getProfile(uint8_t id);
const NetworkPlayerProfile* getProfile(const std::string &kart_name);
std::vector<NetworkPlayerProfile*> getAllPlayersOnHost(uint8_t host_id);
/*! \brief Used to know if a kart is available.
* \param kart_name : Name of the kart to check.
* \return True if the kart hasn't been selected yet, false elseway.
*/
bool isKartAvailable(std::string kart_name);
// ------------------------------------------------------------------------
/** Sets the number of local players. */
void setNumLocalPlayers(int n) { m_num_local_players = n; }
@ -79,26 +78,23 @@ public:
/** Returns the nunber of local players. */
int getNumLocalPlayers() const { return m_num_local_players; }
// ------------------------------------------------------------------------
/*! \brief Used to know if a kart is playable.
* \param kart_name : Name of the kart to check.
* \return True if the kart is playable (standard kart).
* Currently this is always true as the kart selection screen shows
* only the standard karts.
*/
bool isKartAllowed(std::string kart_name) { return true; }
// ------------------------------------------------------------------------
/** Returns the configuration for this race. */
RaceConfig* getRaceConfig() { return m_race_config; }
// ------------------------------------------------------------------------
/** \brief Get the players that are in the game
* \return A vector containing pointers on the players profiles. */
const std::vector<NetworkPlayerProfile*>& getPlayers() const
std::vector<std::weak_ptr<NetworkPlayerProfile> > getPlayers() const
{
std::lock_guard<std::mutex> lock(m_players_mutex);
return m_players;
} // getPlayers
// ------------------------------------------------------------------------
/** Returns the number of connected players. */
int getPlayerCount() { return (int)m_players.size(); }
unsigned getPlayerCount()
{
std::lock_guard<std::mutex> lock(m_players_mutex);
return (unsigned)m_players.size();
}
// ------------------------------------------------------------------------
/** Returns the id of the local master. */
int getLocalMasterID() const { return m_local_master; }

View File

@ -70,7 +70,7 @@ private:
uint16_t m_client_port;
/** Maximum number of players on the server. */
int m_max_players;
unsigned m_max_players;
/** True if a client should connect to the first server it finds and
* immediately start a race. */
@ -171,10 +171,10 @@ public:
}
// ------------------------------------------------------------------------
/** Sets the maximum number of players for this server. */
void setMaxPlayers(int n) { m_max_players = n; }
void setMaxPlayers(unsigned n) { m_max_players = n; }
// ------------------------------------------------------------------------
/** Returns the maximum number of players for this server. */
int getMaxPlayers() const { return m_max_players; }
unsigned getMaxPlayers() const { return m_max_players; }
// ------------------------------------------------------------------------
/** Returns if this instance is a server. */
bool isServer() const { return m_is_server; }

View File

@ -25,10 +25,12 @@
#include "guiengine/message_queue.hpp"
#include "modes/world_with_rank.hpp"
#include "network/event.hpp"
#include "network/game_setup.hpp"
#include "network/network_config.hpp"
#include "network/network_player_profile.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/latency_protocol.hpp"
#include "network/race_config.hpp"
#include "network/race_event_manager.hpp"
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"
@ -85,7 +87,7 @@ void ClientLobby::setAddress(const TransportAddress &address)
void ClientLobby::setup()
{
m_game_setup = STKHost::get()->setupNewGame(); // create a new game setup
LobbyProtocol::setup();
m_state = NONE;
} // setup
@ -446,6 +448,7 @@ void ClientLobby::connectionAccepted(Event* event)
Log::info("ClientLobby", "The server accepted the connection.");
STKHost::get()->setMyHostId(data.getUInt32());
// For now no split screen so only 1 player
m_game_setup->setNumLocalPlayers(1);
// connection token
uint32_t token = data.getToken();
@ -596,18 +599,7 @@ void ClientLobby::kartSelectionRefused(Event* event)
void ClientLobby::kartSelectionUpdate(Event* event)
{
if(!checkDataSize(event, 3)) return;
const NetworkString &data = event->data();
uint8_t player_id = data.getUInt8();
std::string kart_name;
data.decodeString(&kart_name);
if (!m_game_setup->isKartAvailable(kart_name))
{
Log::error("ClientLobby",
"The updated kart is taken already.");
}
m_game_setup->setPlayerKart(player_id, kart_name);
NetworkKartSelectionScreen::getInstance()->playerSelected(player_id,
kart_name);
} // kartSelectionUpdate
//-----------------------------------------------------------------------------
@ -725,7 +717,7 @@ void ClientLobby::exitResultScreen(Event *event)
{
RaceResultGUI::getInstance()->backToLobby();
// Will be reset to linked if connected to server, see update(float dt)
m_game_setup = STKHost::get()->setupNewGame();
LobbyProtocol::setup();
STKHost::get()->getServerPeerForClient()->unsetClientServerToken();
// stop race protocols
auto pm = ProtocolManager::lock();
@ -873,19 +865,8 @@ void ClientLobby::playerLapsVote(Event* event)
*/
void ClientLobby::finishedLoadingWorld()
{
assert(STKHost::get()->getPeerCount() == 1);
std::vector<NetworkPlayerProfile*> players =
STKHost::get()->getMyPlayerProfiles();
NetworkString *ns = getNetworkString(2);
NetworkString* ns = getNetworkString(1);
ns->addUInt8(LE_CLIENT_LOADED_WORLD);
ns->addUInt8( uint8_t(players.size()) ) ;
for (unsigned int i = 0; i < players.size(); i++)
{
ns->addUInt8(players[i]->getGlobalPlayerId());
Log::info("ClientLobby",
"Player %d ready, notifying server.",
players[i]->getGlobalPlayerId());
} // for i < players.size()
sendToServer(ns, /*reliable*/true);
sendToServer(ns, true);
delete ns;
} // finishedLoadingWorld

View File

@ -176,7 +176,7 @@ void GameEventsProtocol::clientHasStarted()
* ready set go. */
void GameEventsProtocol::receivedClientHasStarted(Event *event)
{
assert(NetworkConfig::get()->isServer());
/* assert(NetworkConfig::get()->isServer());
m_count_ready_clients++;
Log::verbose("GameEvent",
"Host %d has started ready-set-go: %d out of %d done",
@ -189,5 +189,5 @@ void GameEventsProtocol::receivedClientHasStarted(Event *event)
// SIgnal the server to start now - since it is now behind the client
// times by the latency of the 'slowest' client.
World::getWorld()->startReadySetGo();
}
}*/
} // receivedClientHasStarted

View File

@ -22,14 +22,15 @@
#include "input/input_manager.hpp"
#include "input/device_manager.hpp"
#include "modes/world.hpp"
#include "network/game_setup.hpp"
#include "network/network_player_profile.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/game_protocol.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "network/protocols/latency_protocol.hpp"
#include "network/race_config.hpp"
#include "network/race_event_manager.hpp"
#include "network/rewind_manager.hpp"
#include "network/stk_host.hpp"
#include "race/race_manager.hpp"
#include "states_screens/state_manager.hpp"
@ -44,6 +45,8 @@ LobbyProtocol::LobbyProtocol(CallbackObject* callback_object)
// ----------------------------------------------------------------------------
LobbyProtocol::~LobbyProtocol()
{
if (m_game_setup)
delete m_game_setup;
} // ~LobbyProtocol
//-----------------------------------------------------------------------------
@ -73,7 +76,7 @@ void LobbyProtocol::loadWorld()
// Create the kart information for the race manager:
// -------------------------------------------------
std::vector<NetworkPlayerProfile*> players = m_game_setup->getPlayers();
/*std::vector<NetworkPlayerProfile*> players = m_game_setup->getPlayers();
int local_player_id = 0;
for (unsigned int i = 0; i < players.size(); i++)
{
@ -95,7 +98,7 @@ void LobbyProtocol::loadWorld()
// corresponding device associated with it).
RemoteKartInfo rki(is_local ? local_player_id
: i - local_player_id
+ STKHost::get()->getGameSetup()->getNumLocalPlayers(),
+ m_game_setup->getNumLocalPlayers(),
profile->getKartName(),
profile->getName(),
profile->getHostId(),
@ -110,7 +113,7 @@ void LobbyProtocol::loadWorld()
// Inform the race manager about the data for this kart.
race_manager->setPlayerKart(i, rki);
} // for i in players
} // for i in players*/
// Make sure that if there is only a single local player this player can
// use all input devices.
@ -137,3 +140,14 @@ void LobbyProtocol::terminateLatencyProtocol()
{
ProtocolManager::lock()->findAndTerminate(PROTOCOL_SYNCHRONIZATION);
} // stopLatencyProtocol
//-----------------------------------------------------------------------------
/** A previous GameSetup is deleted and a new one is created.
* \return Newly create GameSetup object.
*/
void LobbyProtocol::setup()
{
if (m_game_setup)
delete m_game_setup;
m_game_setup = new GameSetup();
} // setupNewGame

View File

@ -20,10 +20,10 @@
#define LOBBY_PROTOCOL_HPP
#include "network/protocol.hpp"
#include "network/game_setup.hpp"
#include "network/network_string.hpp"
class GameSetup;
/*!
* \class LobbyProtocol
* \brief Base class for both client and server lobby. The lobbies are started
@ -78,7 +78,7 @@ public:
protected:
static std::weak_ptr<LobbyProtocol> m_lobby;
/** The game setup. */
/** Stores data about the online game to play. */
GameSetup* m_game_setup;
public:
@ -109,7 +109,7 @@ public:
LobbyProtocol(CallbackObject* callback_object);
virtual ~LobbyProtocol();
virtual void setup() = 0;
virtual void setup();
virtual void update(float dt) = 0;
virtual void finishedLoadingWorld() = 0;
virtual void loadWorld();
@ -120,6 +120,7 @@ public:
{
assert(false); // Only defined in client
};
GameSetup* getGameSetup() const { return m_game_setup; }
}; // class LobbyProtocol

View File

@ -22,11 +22,13 @@
#include "karts/kart_properties_manager.hpp"
#include "modes/world.hpp"
#include "network/event.hpp"
#include "network/game_setup.hpp"
#include "network/network_config.hpp"
#include "network/network_player_profile.hpp"
#include "network/protocols/connect_to_peer.hpp"
#include "network/protocols/latency_protocol.hpp"
#include "network/protocol_manager.hpp"
#include "network/race_config.hpp"
#include "network/race_event_manager.hpp"
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"
@ -42,6 +44,7 @@
#include "utils/time.hpp"
#include <algorithm>
#include <iterator>
#include <fstream>
/** This is the central game setup protocol running in the server. It is
@ -102,9 +105,9 @@ ServerLobby::~ServerLobby()
} // ~ServerLobby
//-----------------------------------------------------------------------------
void ServerLobby::setup()
{
LobbyProtocol::setup();
// We use maximum 16bit unsigned limit
auto all_k = kart_properties_manager->getAllAvailableKarts();
auto all_t = track_manager->getAllTrackIdentifiers();
@ -116,24 +119,14 @@ void ServerLobby::setup()
m_available_kts.second = { all_t.begin(), all_t.end() };
m_server_registered = false;
m_game_setup = STKHost::get()->setupNewGame();
m_game_setup->setNumLocalPlayers(0); // no local players on a server
m_next_player_id.setAtomic(0);
m_selection_enabled = false;
Log::info("ServerLobby", "Starting the protocol.");
// Initialise the data structures to detect if all clients and
// the server are ready:
m_player_states.clear();
m_client_ready_count.setAtomic(0);
m_server_has_loaded_world = false;
const std::vector<NetworkPlayerProfile*> &players =
m_game_setup->getPlayers();
for (unsigned int i = 0; i < players.size(); i++)
{
m_player_states[players[i]->getGlobalPlayerId()] = false;
}
m_server_has_loaded_world.store(false);
m_peers_ready.clear();
m_server_delay = 0.0;
Log::info("ServerLobby", "Reset server to initial state.");
} // setup
//-----------------------------------------------------------------------------
@ -302,12 +295,55 @@ void ServerLobby::asynchronousUpdate()
STKHost::get()->requestShutdown();
break;
}
case WAIT_FOR_WORLD_LOADED:
{
// m_server_has_loaded_world is set by main thread with atomic write
if (m_server_has_loaded_world.load() == false)
return;
if (!checkPeersReady())
return;
m_state = WAIT_FOR_RACE_STARTED;
// Reset for next state usage
for (auto p : m_peers_ready)
{
p.second = false;
}
signalRaceStartToClients();
break;
}
case WAIT_FOR_RACE_STARTED:
// The function startedRaceOnClient() will trigger the
// next state.
break;
case DELAY_SERVER:
if (m_server_delay < StkTime::getRealTime())
{
Log::verbose("ServerLobby", "End delay at %lf",
StkTime::getRealTime());
m_state = RACING;
World::getWorld()->setReadyToRace();
}
default:
break;
}
} // asynchronousUpdate
//-----------------------------------------------------------------------------
bool ServerLobby::checkPeersReady() const
{
bool all_ready = true;
for (auto p : m_peers_ready)
{
if (p.first.expired())
continue;
all_ready = all_ready && p.second;
if (!all_ready)
return false;
}
return true;
} // checkPeersReady
//-----------------------------------------------------------------------------
/** Simple finite state machine. Once this
* is known, register the server and its address with the stk server so that
@ -317,12 +353,20 @@ void ServerLobby::update(float dt)
{
// Check if server owner has left
updateServerOwner();
if (m_game_setup)
{
// Remove disconnected players if in these two states
m_game_setup->update(m_state.load() == ACCEPTING_CLIENTS ||
m_state.load() == SELECTING);
}
switch (m_state.load())
{
case SET_PUBLIC_ADDRESS:
case REGISTER_SELF_ADDRESS:
case ACCEPTING_CLIENTS:
case WAIT_FOR_WORLD_LOADED:
case WAIT_FOR_RACE_STARTED:
case DELAY_SERVER:
{
// Waiting for asynchronousUpdate
break;
@ -337,33 +381,6 @@ void ServerLobby::update(float dt)
loadWorld();
m_state = WAIT_FOR_WORLD_LOADED;
break;
case WAIT_FOR_WORLD_LOADED:
// Note that m_server_has_loaded_world is called by the main thread
// (same as the thread updating this protocol)
m_client_ready_count.lock();
if (m_server_has_loaded_world &&
m_client_ready_count.getData() == m_game_setup->getPlayerCount())
{
signalRaceStartToClients();
m_client_ready_count.getData() = 0;
}
m_client_ready_count.unlock();
// Initialise counter again, to wait for all clients to indicate that
// they have started the race/
break;
case WAIT_FOR_RACE_STARTED:
// The function startedRaceOnClient() will trigger the
// next state.
break;
case DELAY_SERVER:
if (m_server_delay < StkTime::getRealTime())
{
Log::verbose("ServerLobby", "End delay at %lf",
StkTime::getRealTime());
m_state = RACING;
World::getWorld()->setReadyToRace();
}
break;
case RACING:
if (World::getWorld() &&
RaceEventManager::getInstance<RaceEventManager>()->isRunning())
@ -374,16 +391,6 @@ void ServerLobby::update(float dt)
case RESULT_DISPLAY:
if(StkTime::getRealTime() > m_timeout)
{
// Send a notification to all clients to exit
// the race result screen
NetworkString *exit_result_screen = getNetworkString(1);
exit_result_screen->setSynchronous(true);
exit_result_screen->addUInt8(LE_EXIT_RESULT);
sendMessageToPeersChangingToken(exit_result_screen,
/*reliable*/true);
delete exit_result_screen;
m_state = NetworkConfig::get()->isLAN() ?
ACCEPTING_CLIENTS : REGISTER_SELF_ADDRESS;
RaceResultGUI::getInstance()->backToLobby();
// notify the network world that it is stopped
RaceEventManager::getInstance()->stop();
@ -394,6 +401,16 @@ void ServerLobby::update(float dt)
pm->findAndTerminate(PROTOCOL_KART_UPDATE);
pm->findAndTerminate(PROTOCOL_GAME_EVENTS);
setup();
m_state = NetworkConfig::get()->isLAN() ?
ACCEPTING_CLIENTS : REGISTER_SELF_ADDRESS;
// Send a notification to all clients to exit
// the race result screen
NetworkString *exit_result_screen = getNetworkString(1);
exit_result_screen->setSynchronous(true);
exit_result_screen->addUInt8(LE_EXIT_RESULT);
sendMessageToPeersChangingToken(exit_result_screen,
/*reliable*/true);
delete exit_result_screen;
}
break;
case ERROR_LEAVE:
@ -502,7 +519,6 @@ void ServerLobby::signalRaceStartToClients()
ns->addUInt8(LE_START_RACE);
sendMessageToPeersChangingToken(ns, /*reliable*/true);
delete ns;
m_state = WAIT_FOR_RACE_STARTED;
} // startGame
//-----------------------------------------------------------------------------
@ -555,8 +571,6 @@ void ServerLobby::startSelection(const Event *event)
sendMessageToPeersChangingToken(ns, /*reliable*/true);
delete ns;
m_selection_enabled = true;
m_state = SELECTING;
WaitingForOthersScreen::getInstance()->push();
@ -591,7 +605,7 @@ void ServerLobby::checkIncomingConnectionRequests()
const TransportAddress &addr = STKHost::get()->getPublicAddress();
request->addParameter("address", addr.getIP() );
request->addParameter("port", addr.getPort());
request->addParameter("current_players", STKHost::get()->getPeerCount());
request->addParameter("current_players", m_game_setup->getPlayerCount());
request->executeNow();
assert(request->isDone());
@ -684,7 +698,9 @@ void ServerLobby::clientDisconnected(Event* event)
msg->addUInt8((uint8_t)players_on_peer.size());
for (auto p : players_on_peer)
{
msg->encodeString(p->getName());
std::string name = StringUtils::wideToUtf8(p->getName());
msg->encodeString(name);
Log::info("ServerLobby", "%s disconnected", name.c_str());
}
sendMessageToPeersChangingToken(msg, /*reliable*/true);
updatePlayerList();
@ -852,6 +868,9 @@ void ServerLobby::connectionRequested(Event* event)
peer->sendPacket(message_ack);
delete message_ack;
m_peers_ready[peer] = false;
for (std::shared_ptr<NetworkPlayerProfile> npp : peer->getPlayerProfiles())
m_game_setup->addPlayer(npp);
updatePlayerList();
Log::verbose("ServerLobby", "New player.");
@ -922,74 +941,41 @@ void ServerLobby::updateServerOwner()
} // updateServerOwner
//-----------------------------------------------------------------------------
/*! \brief Called when a player asks to select a kart.
/*! \brief Called when a player asks to select karts.
* \param event : Event providing the information.
*
* Format of the data :
* Byte 0 1 2
* ----------------------------------------------
* Size | 1 | 1 | N |
* Data |player id | N (kart name size) | kart name |
* ----------------------------------------------
*/
void ServerLobby::kartSelectionRequested(Event* event)
{
if(m_state!=SELECTING)
std::lock_guard<std::mutex> lock(m_connection_mutex);
if (m_state != SELECTING)
{
Log::warn("Server", "Received kart selection while in state %d.",
Log::warn("ServerLobby", "Received kart selection while in state %d.",
m_state.load());
return;
}
if (!checkDataSize(event, 1)) return;
const NetworkString &data = event->data();
const NetworkString& data = event->data();
STKPeer* peer = event->getPeer();
uint8_t player_id = data.getUInt8();
std::string kart_name;
data.decodeString(&kart_name);
// check if selection is possible
if (!m_selection_enabled)
unsigned player_count = data.getUInt8();
for (unsigned i = 0; i < player_count; i++)
{
NetworkString *answer = getNetworkString(2);
// selection still not started
answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(2);
peer->sendPacket(answer);
delete answer;
return;
std::string kart;
data.decodeString(&kart);
if (m_available_kts.first.find(kart) == m_available_kts.first.end())
{
Log::debug("ServerLobby", "Player %d from peer %d chose unknown "
"kart %s, use a random one", i, peer->getHostId(),
kart.c_str());
RandomGenerator rg;
std::set<std::string>::iterator it = m_available_kts.first.begin();
std::advance(it, rg.get((int)m_available_kts.first.size()));
kart = *it;
}
peer->getPlayerProfiles()[i]->setKartName(kart);
Log::verbose("ServerLobby", "Player %d from peer %d chose %s", i,
peer->getHostId(), kart.c_str());
}
// check if somebody picked that kart
if (!m_game_setup->isKartAvailable(kart_name))
{
NetworkString *answer = getNetworkString(2);
// kart is already taken
answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(0);
peer->sendPacket(answer);
delete answer;
return;
}
// check if this kart is authorized
if (!m_game_setup->isKartAllowed(kart_name))
{
NetworkString *answer = getNetworkString(2);
// kart is not authorized
answer->addUInt8(LE_KART_SELECTION_REFUSED).addUInt8(1);
peer->sendPacket(answer);
delete answer;
return;
}
// send a kart update to everyone
NetworkString *answer = getNetworkString(3+kart_name.size());
// This message must be handled synchronously on the client.
answer->setSynchronous(true);
// kart update (3), 1, race id
answer->addUInt8(LE_KART_SELECTION_UPDATE).addUInt8(player_id)
.encodeString(kart_name);
sendMessageToPeersChangingToken(answer);
delete answer;
m_game_setup->setPlayerKart(player_id, kart_name);
} // kartSelectionRequested
//-----------------------------------------------------------------------------
@ -1179,7 +1165,7 @@ void ServerLobby::playerLapsVote(Event* event)
*/
void ServerLobby::finishedLoadingWorld()
{
m_server_has_loaded_world = true;
m_server_has_loaded_world.store(true);
} // finishedLoadingWorld;
//-----------------------------------------------------------------------------
@ -1188,30 +1174,10 @@ void ServerLobby::finishedLoadingWorld()
*/
void ServerLobby::finishedLoadingWorldClient(Event *event)
{
if (!checkDataSize(event, 1)) return;
const NetworkString &data = event->data();
uint8_t player_count = data.getUInt8();
m_client_ready_count.lock();
for (unsigned int i = 0; i < player_count; i++)
{
uint8_t player_id = data.getUInt8();
if (m_player_states[player_id])
{
Log::error("ServerLobbyProtocol",
"Player %d send more than one ready message.",
player_id);
m_client_ready_count.unlock();
return;
}
m_player_states[player_id] = true;
m_client_ready_count.getData()++;
Log::info("ServerLobbyeProtocol", "Player %d is ready (%d/%d).",
player_id, m_client_ready_count.getData(),
m_game_setup->getPlayerCount());
}
m_client_ready_count.unlock();
std::shared_ptr<STKPeer> peer = event->getPeerSP();
m_peers_ready.at(peer) = true;
Log::info("ServerLobby", "Peer %d has finished loading world",
peer->getHostId());
} // finishedLoadingWorldClient
//-----------------------------------------------------------------------------
@ -1225,20 +1191,19 @@ void ServerLobby::finishedLoadingWorldClient(Event *event)
*/
void ServerLobby::startedRaceOnClient(Event *event)
{
m_client_ready_count.lock();
Log::verbose("ServerLobby", "Host %d has started race at %lf.",
event->getPeer()->getHostId(), StkTime::getRealTime());
m_client_ready_count.getData()++;
if (m_client_ready_count.getData() == m_game_setup->getPlayerCount())
std::shared_ptr<STKPeer> peer = event->getPeerSP();
m_peers_ready.at(peer) = true;
Log::info("ServerLobby", "Peer %d has started race at %lf",
peer->getHostId(), StkTime::getRealTime());
if (checkPeersReady())
{
m_state = DELAY_SERVER;
m_server_delay = StkTime::getRealTime() + 0.1f;
m_server_delay = StkTime::getRealTime() + 0.1;
Log::verbose("ServerLobby", "Started delay at %lf set delay to %lf",
StkTime::getRealTime(),
m_server_delay);
StkTime::getRealTime(), m_server_delay);
terminateLatencyProtocol();
}
m_client_ready_count.unlock();
} // startedRaceOnClient
//-----------------------------------------------------------------------------

View File

@ -3,9 +3,9 @@
#include "network/protocols/lobby_protocol.hpp"
#include "utils/cpp2011.hpp"
#include "utils/synchronised.hpp"
#include <atomic>
#include <map>
#include <memory>
#include <mutex>
#include <set>
@ -42,19 +42,12 @@ private:
* with data in server first. */
std::pair<std::set<std::string>, std::set<std::string> > m_available_kts;
/** Next id to assign to a peer. */
Synchronised<int> m_next_player_id;
/** Keeps track of the server state. */
bool m_server_has_loaded_world;
std::atomic_bool m_server_has_loaded_world;
/** Counts how many clients have finished loading the world. */
Synchronised<int> m_client_ready_count;
/** For debugging: keep track of the state (ready or not) of each player,
* to make sure no client/player reports more than once. Needs to be a
* map since the client IDs can be non-consecutive. */
std::map<uint8_t, bool> m_player_states;
/** Counts how many peers have finished loading the world. */
std::map<std::weak_ptr<STKPeer>, bool,
std::owner_less<std::weak_ptr<STKPeer> > > m_peers_ready;
/** Keeps track of an artificial server delay (which makes sure that the
* data from all clients has arrived when the server computes a certain
@ -62,8 +55,6 @@ private:
* seconds), which is the real time at which the server should start. */
double m_server_delay;
bool m_selection_enabled;
bool m_has_created_server_id_file;
/** It indicates if this server is registered with the stk server. */
@ -101,6 +92,7 @@ private:
void createServerIdFile();
void updatePlayerList();
void updateServerOwner();
bool checkPeersReady() const;
public:
ServerLobby();

View File

@ -21,6 +21,7 @@
#include "config/user_config.hpp"
#include "io/file_manager.hpp"
#include "network/event.hpp"
#include "network/game_setup.hpp"
#include "network/network_config.hpp"
#include "network/network_console.hpp"
#include "network/network_string.hpp"
@ -72,8 +73,9 @@ void STKHost::create(std::shared_ptr<Server> server, SeparateProcess* p)
assert(m_stk_host == NULL);
if (NetworkConfig::get()->isServer())
{
std::shared_ptr<ServerLobby> sl = LobbyProtocol::create<ServerLobby>();
m_stk_host = new STKHost(NetworkConfig::get()->getServerName());
LobbyProtocol::create<ServerLobby>()->requestStart();
sl->requestStart();
}
else
{
@ -319,7 +321,6 @@ void STKHost::init()
m_shutdown = false;
m_authorised = false;
m_network = NULL;
m_game_setup = NULL;
m_exit_timeout.store(std::numeric_limits<double>::max());
// Start with initialising ENet
@ -351,10 +352,6 @@ STKHost::~STKHost()
requestShutdown();
if (m_network_console.joinable())
m_network_console.join();
// delete the game setup
if (m_game_setup)
delete m_game_setup;
m_game_setup = NULL;
disconnectAllPeers(true/*timeout_waiting*/);
Network::closeLog();
@ -607,18 +604,6 @@ void STKHost::setPrivatePort()
m_private_port = ntohs(sin.sin_port);
} // setPrivatePort
//-----------------------------------------------------------------------------
/** A previous GameSetup is deletea and a new one is created.
* \return Newly create GameSetup object.
*/
GameSetup* STKHost::setupNewGame()
{
if (m_game_setup)
delete m_game_setup;
m_game_setup = new GameSetup();
return m_game_setup;
} // setupNewGame
//-----------------------------------------------------------------------------
/** Disconnect all connected peers.
*/
@ -730,7 +715,7 @@ void STKHost::mainLoop()
auto sl = LobbyProtocol::get<ServerLobby>();
if (direct_socket && sl && sl->waitingForPlayers())
{
handleDirectSocketRequest(direct_socket);
handleDirectSocketRequest(direct_socket, sl);
} // if discovery host
std::list<std::tuple<ENetPeer*, ENetPacket*, uint32_t,
@ -847,7 +832,8 @@ void STKHost::mainLoop()
* message is received, will answer with a message containing server details
* (and sender IP address and port).
*/
void STKHost::handleDirectSocketRequest(Network* direct_socket)
void STKHost::handleDirectSocketRequest(Network* direct_socket,
std::shared_ptr<ServerLobby> sl)
{
const int LEN=2048;
char buffer[LEN];
@ -877,7 +863,7 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket)
s.addUInt8(NetworkConfig::m_server_version);
s.encodeString(name);
s.addUInt8(NetworkConfig::get()->getMaxPlayers());
s.addUInt8(0); // FIXME: current number of connected players
s.addUInt8((uint8_t)sl->getGameSetup()->getPlayerCount());
s.addUInt16(m_private_port);
s.addUInt8((uint8_t)race_manager->getDifficulty());
s.addUInt8((uint8_t)
@ -938,12 +924,6 @@ bool STKHost::peerExists(const TransportAddress& peer)
return false;
} // peerExists
// ----------------------------------------------------------------------------
std::vector<NetworkPlayerProfile*> STKHost::getMyPlayerProfiles()
{
return m_game_setup->getAllPlayersOnHost(m_host_id);
} // getMyPlayerProfiles
// ----------------------------------------------------------------------------
/** \brief Return the only server peer for client.
* \return STKPeer the STKPeer of server.

View File

@ -45,6 +45,7 @@
class GameSetup;
class NetworkPlayerProfile;
class Server;
class ServerLobby;
class SeparateProcess;
enum ENetCommandType : unsigned int
@ -104,9 +105,6 @@ private:
/** Host id of this host. */
uint32_t m_host_id = 0;
/** Stores data about the online game to play. */
GameSetup* m_game_setup;
/** Id of thread listening to enet events. */
std::thread m_listening_thread;
@ -133,17 +131,22 @@ private:
/** The private port enet socket is bound. */
uint16_t m_private_port;
STKHost(std::shared_ptr<Server> server);
STKHost(const irr::core::stringw &server_name);
virtual ~STKHost();
// ------------------------------------------------------------------------
STKHost(std::shared_ptr<Server> server);
// ------------------------------------------------------------------------
STKHost(const irr::core::stringw &server_name);
// ------------------------------------------------------------------------
~STKHost();
// ------------------------------------------------------------------------
void init();
void handleDirectSocketRequest(Network* direct_socket);
// ------------------------------------------------------------------------
void handleDirectSocketRequest(Network* direct_socket,
std::shared_ptr<ServerLobby> sl);
// ------------------------------------------------------------------------
void mainLoop();
public:
/** If a network console should be started. Note that the console can cause
* a crash in release mode on windows (see #1529). */
/** If a network console should be started. */
static bool m_enable_console;
/** Creates the STKHost. It takes all confifguration parameters from
@ -181,8 +184,6 @@ public:
// ------------------------------------------------------------------------
void setPublicAddress();
// ------------------------------------------------------------------------
GameSetup* setupNewGame();
// ------------------------------------------------------------------------
void disconnectAllPeers(bool timeout_waiting = false);
// ------------------------------------------------------------------------
bool connect(const TransportAddress& peer);
@ -217,19 +218,25 @@ public:
// ------------------------------------------------------------------------
std::shared_ptr<STKPeer> findPeerByHostId(uint32_t id) const;
// ------------------------------------------------------------------------
void sendPacketExcept(STKPeer* peer,
NetworkString *data,
void sendPacketExcept(STKPeer* peer, NetworkString *data,
bool reliable = true);
void setupClient(int peer_count, int channel_limit,
uint32_t max_incoming_bandwidth,
uint32_t max_outgoing_bandwidth);
void startListening();
void stopListening();
bool peerExists(const TransportAddress& peer_address);
bool isConnectedTo(const TransportAddress& peer_address);
// ------------------------------------------------------------------------
void setupClient(int peer_count, int channel_limit,
uint32_t max_incoming_bandwidth,
uint32_t max_outgoing_bandwidth);
// ------------------------------------------------------------------------
void startListening();
// ------------------------------------------------------------------------
void stopListening();
// ------------------------------------------------------------------------
bool peerExists(const TransportAddress& peer_address);
// ------------------------------------------------------------------------
bool isConnectedTo(const TransportAddress& peer_address);
// ------------------------------------------------------------------------
std::shared_ptr<STKPeer> getServerPeerForClient() const;
std::vector<NetworkPlayerProfile*> getMyPlayerProfiles();
void setErrorMessage(const irr::core::stringw &message);
// ------------------------------------------------------------------------
void setErrorMessage(const irr::core::stringw &message);
// ------------------------------------------------------------------------
void addEnetCommand(ENetPeer* peer, ENetPacket* packet, uint32_t i,
ENetCommandType ect)
{
@ -245,9 +252,6 @@ public:
* requested. */
bool requestedShutdown() const { return m_shutdown.load(); }
// ------------------------------------------------------------------------
/** Returns the current game setup. */
GameSetup* getGameSetup() { return m_game_setup; }
// ------------------------------------------------------------------------
int receiveRawPacket(char *buffer, int buffer_len,
TransportAddress* sender, int max_tries = -1)
{

View File

@ -86,8 +86,8 @@ public:
bool isSamePeer(const STKPeer* peer) const;
bool isSamePeer(const ENetPeer* peer) const;
// ------------------------------------------------------------------------
std::vector<std::shared_ptr<NetworkPlayerProfile> >
getPlayerProfiles() const { return m_players; }
std::vector<std::shared_ptr<NetworkPlayerProfile> >& getPlayerProfiles()
{ return m_players; }
// ------------------------------------------------------------------------
bool hasPlayerProfiles() const { return !m_players.empty(); }
// ------------------------------------------------------------------------

View File

@ -27,6 +27,7 @@
#include "items/item_manager.hpp"
#include "karts/kart_properties.hpp"
#include "karts/kart_properties_manager.hpp"
#include "network/game_setup.hpp"
#include "network/network_config.hpp"
#include "network/network_player_profile.hpp"
#include "network/protocol_manager.hpp"
@ -71,16 +72,13 @@ void NetworkKartSelectionScreen::init()
back_button->setImage("gui/main_quit.png");
// add a widget for each player except self (already exists):
GameSetup* setup = STKHost::get()->getGameSetup();
if (!setup)
GameSetup* game_setup = LobbyProtocol::get<LobbyProtocol>()->getGameSetup();
if (!game_setup)
{
Log::error("NetworkKartSelectionScreen",
"No network game setup registered.");
return;
}
std::vector<NetworkPlayerProfile*> players = setup->getPlayers();
Log::info("NKSS", "There are %d players", players.size());
// ---- Get available area for karts
// make a copy of the area, ands move it to be outside the screen
Widget* kartsAreaWidget = getWidget("playerskarts");
@ -90,7 +88,6 @@ void NetworkKartSelectionScreen::init()
kartsAreaWidget->m_y,
kartsAreaWidget->m_x + shift + kartsAreaWidget->m_w,
kartsAreaWidget->m_y + kartsAreaWidget->m_h);
GameSetup *game_setup = STKHost::get()->getGameSetup();
// FIXME: atm only adds the local master, split screen supports
// needs to be added
@ -115,7 +112,6 @@ void NetworkKartSelectionScreen::init()
assert(w != NULL);
w->setSelection(UserConfigParams::m_default_kart, /*player id*/0, /*focus*/true);
playerConfirm(0);
RaceSetupScreen::getInstance()->push();
}
} // init
@ -142,81 +138,21 @@ void NetworkKartSelectionScreen::playerConfirm(const int playerID)
SFXManager::get()->quickSound( "anvil" );
return;
}
if(playerID == PLAYER_ID_GAME_MASTER) // self
if (playerID == PLAYER_ID_GAME_MASTER) // self
{
auto clrp = LobbyProtocol::get<ClientLobby>();
assert(clrp);
// FIXME SPLITSCREEN: we need to supply the global player id of the
// player selecting the kart here. For now ... just vote the same kart
// for each local player.
std::vector<NetworkPlayerProfile*> players =
STKHost::get()->getMyPlayerProfiles();
for(unsigned int i=0; i<players.size(); i++)
{
clrp->requestKartSelection(players[i]->getGlobalPlayerId(),
selection );
}
uint8_t player_count = 1;
NetworkString kart(PROTOCOL_LOBBY_ROOM);
kart.addUInt8(LobbyProtocol::LE_KART_SELECTION).addUInt8(player_count)
.encodeString(selection);
STKHost::get()->sendToServer(&kart, true);
input_manager->getDeviceManager()->setAssignMode(ASSIGN);
TracksScreen::getInstance()->push();
}
} // playerConfirm
// ----------------------------------------------------------------------------
void NetworkKartSelectionScreen::playerSelected(uint8_t player_id,
const std::string &kart_name)
{
int widget_id = -1;
for (unsigned int i = 0; i < m_id_mapping.size(); i++)
{
Log::info("NKSS", "Checking race id %d : mapped of %d is %d",
player_id, i, m_id_mapping[i]);
if (m_id_mapping[i] == player_id)
widget_id = i;
}
// This selection was for a remote kart, which is not shown
// Just ignore it.
if(widget_id==-1)
return;
// In case of auto-connect the screen is already replaced, so
// m_kart_widget is empty.
if (! STKHost::get()->isAuthorisedToControl())
{
KartSelectionScreen::updateKartWidgetModel(widget_id, kart_name,
irr::core::stringw(kart_name.c_str()),
/*Todo get color*/0.0f);
KartSelectionScreen::updateKartStats(widget_id, kart_name);
m_kart_widgets[widget_id].setKartInternalName(kart_name);
m_kart_widgets[widget_id].markAsReady(); // mark player ready
}
// If this is the authorised client, send the currently set race config
// to the server.
if(STKHost::get()->isAuthorisedToControl())
{
auto clrp = LobbyProtocol::get<ClientLobby>();
assert(clrp);
// FIXME: for now we submit a vote from the authorised user
// for the various modes based on the settings in the race manager.
// This needs more/better gui elements (and some should be set when
// defining the server).
std::vector<NetworkPlayerProfile*> players =
STKHost::get()->getMyPlayerProfiles();
for(unsigned int i=0; i<players.size(); i++)
{
uint8_t id = players[i]->getGlobalPlayerId();
clrp->voteMajor(id, race_manager->getMajorMode());
clrp->voteMinor(id, race_manager->getMinorMode());
clrp->voteReversed(id, race_manager->getReverseTrack());
clrp->voteRaceCount(id, 1);
clrp->voteLaps(id, 1);
}
//WaitingForOthersScreen::getInstance()->push();
//return;
}
TracksScreen::getInstance()->push();
} // playerSelected
// ----------------------------------------------------------------------------
bool NetworkKartSelectionScreen::onEscapePressed()
{

View File

@ -50,8 +50,6 @@ public:
}
virtual void init() OVERRIDE;
virtual bool onEscapePressed() OVERRIDE;
virtual void playerSelected(uint8_t player_id,
const std::string &kart_name);
};
#endif // NETWORK_KART_SELECTION_HPP

View File

@ -96,13 +96,13 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name,
// FIXME SPLITSCREEN: we need to supply the global player id of the
// player selecting the track here. For now ... just vote the same
// track for each local player.
std::vector<NetworkPlayerProfile*> players =
/*std::vector<NetworkPlayerProfile*> players =
STKHost::get()->getMyPlayerProfiles();
for(unsigned int i=0; i<players.size(); i++)
{
clrp->voteTrack(players[i]->getGlobalPlayerId(),selection);
}
WaitingForOthersScreen::getInstance()->push();
WaitingForOthersScreen::getInstance()->push();*/
}
else
{

View File

@ -16,89 +16,38 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "states_screens/waiting_for_others.hpp"
#include "config/user_config.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "input/device_manager.hpp"
#include "input/input_manager.hpp"
#include "input/keyboard_device.hpp"
#include "karts/kart_properties_manager.hpp"
#include "network/game_setup.hpp"
#include "network/network_player_profile.hpp"
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"
#include "race/race_manager.hpp"
#include "states_screens/state_manager.hpp"
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( WaitingForOthersScreen );
// -----------------------------------------------------------------------------
WaitingForOthersScreen::WaitingForOthersScreen() : Screen("online/waiting_for_others.stkgui")
WaitingForOthersScreen::WaitingForOthersScreen()
: Screen("online/waiting_for_others.stkgui")
{
} // WaitingForOthersScreen
// -----------------------------------------------------------------------------
void WaitingForOthersScreen::loadedFromFile()
{
} // loadedFromFile
// -----------------------------------------------------------------------------
void WaitingForOthersScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
void WaitingForOthersScreen::eventCallback(Widget* widget,
const std::string& name,
const int player_id)
{
} // eventCallback
// -----------------------------------------------------------------------------
void WaitingForOthersScreen::init()
{
Screen::init();
} //init
// -----------------------------------------------------------------------------
void WaitingForOthersScreen::onUpdate(float dt)
{
const GameSetup *setup = STKHost::get()->getGameSetup();
const std::vector<NetworkPlayerProfile*> &all_profiles = setup->getPlayers();
RaceConfig* config = STKHost::get()->getGameSetup()->getRaceConfig();
core::stringw w;
for (unsigned int i = 0; i < all_profiles.size(); i++)
{
const NetworkPlayerProfile* profile = all_profiles[i];
if (profile == NULL)
continue;
core::stringw name = profile->getName();
int playerId = profile->getGlobalPlayerId();
const std::string &kart = profile->getKartName();
if (!kart.empty())
name += StringUtils::insertValues(L" (%s)", core::stringw(kart.c_str()));
w += name + L" : ";
const RaceVote& vote = config->getRaceVote(playerId);
if (vote.hasVotedTrack())
{
w += vote.getTrackVote().c_str();
}
else
{
w += L"...";
}
w += "\n";
}
GUIEngine::LabelWidget* lbl = getWidget<GUIEngine::LabelWidget>("lblDetails");
lbl->setText(w.c_str(), true);
}
// -----------------------------------------------------------------------------