Use the new method to connect / start game

This commit is contained in:
Benau 2018-03-16 17:11:23 +08:00
parent a5c1dbb446
commit 82be7572a1
11 changed files with 152 additions and 108 deletions

View File

@ -341,6 +341,13 @@ AbstractKart *World::createKart(const std::string &kart_ident, int index,
gk = ReplayPlay::get()->getNumGhostKart(); gk = ReplayPlay::get()->getNumGhostKart();
std::shared_ptr<RenderInfo> ri = std::make_shared<RenderInfo>(); std::shared_ptr<RenderInfo> ri = std::make_shared<RenderInfo>();
if (global_player_id > -1 && race_manager->getKartInfo(global_player_id)
.getDefaultKartColor() > 0.0f)
{
ri->setHue(race_manager->getKartInfo(global_player_id)
.getDefaultKartColor());
}
int position = index+1; int position = index+1;
btTransform init_pos = getStartTransform(index - gk); btTransform init_pos = getStartTransform(index - gk);
AbstractKart *new_kart; AbstractKart *new_kart;
@ -357,10 +364,7 @@ AbstractKart *World::createKart(const std::string &kart_ident, int index,
{ {
case RaceManager::KT_PLAYER: case RaceManager::KT_PLAYER:
{ {
controller = new LocalPlayerController(new_kart, controller = new LocalPlayerController(new_kart, local_player_id);
local_player_id);
const float hue = StateManager::get()->getActivePlayer(local_player_id) const float hue = StateManager::get()->getActivePlayer(local_player_id)
->getConstProfile()->getDefaultKartColor(); ->getConstProfile()->getDefaultKartColor();
if (hue > 0.0f) if (hue > 0.0f)

View File

@ -66,25 +66,6 @@ void GameSetup::update(bool remove_disconnected_players)
return; return;
} // removePlayer } // removePlayer
//-----------------------------------------------------------------------------
/** Sets the player id of the local master.
* \param player_id The id of the player who is the local master.
*/
void GameSetup::setLocalMaster(uint8_t player_id)
{
m_local_master = player_id;
} // setLocalMaster
//-----------------------------------------------------------------------------
/** Returns true if the player id is the local game master (used in the
* network game selection.
* \param Local player id to test.
*/
bool GameSetup::isLocalMaster(uint8_t player_id)
{
return m_local_master == player_id;
} // isLocalMaster
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void GameSetup::loadWorld() void GameSetup::loadWorld()
{ {
@ -94,38 +75,3 @@ void GameSetup::loadWorld()
race_manager->setReverseTrack(m_reverse); race_manager->setReverseTrack(m_reverse);
race_manager->startSingleRace(m_track, m_laps, false/*from_overworld*/); race_manager->startSingleRace(m_track, m_laps, false/*from_overworld*/);
} // loadWorld } // loadWorld
//-----------------------------------------------------------------------------
void GameSetup::bindKartsToProfiles()
{
World::KartList karts = World::getWorld()->getKarts();
/*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(),
m_players[i]->getKartName().c_str());
}
for (unsigned int i = 0; i < karts.size(); i++)
{
Log::info("GameSetup", "Kart %d has id %d and kart %s", i,
karts[i]->getWorldKartId(), karts[i]->getIdent().c_str());
}
for (unsigned int j = 0; j < m_players.size(); j++)
{
bool found = false;
for (unsigned int i = 0 ; i < karts.size(); i++)
{
if (karts[i]->getIdent() == m_players[j]->getKartName())
{
m_players[j]->setWorldKartID(karts[i]->getWorldKartId());
found = true;
break;
}
}
if (!found)
{
Log::error("GameSetup", "Error while binding world kart ids to players profiles.");
}
}*/
} // bindKartsToProfiles

View File

@ -24,6 +24,7 @@
#include "network/remote_kart_info.hpp" #include "network/remote_kart_info.hpp"
#include <algorithm>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
@ -68,26 +69,34 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void update(bool remove_disconnected_players); void update(bool remove_disconnected_players);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void bindKartsToProfiles();
// ------------------------------------------------------------------------
void setLocalMaster(uint8_t player_id);
// ------------------------------------------------------------------------
bool isLocalMaster(uint8_t player_id);
// ------------------------------------------------------------------------
/** Sets the number of local players. */ /** Sets the number of local players. */
void setNumLocalPlayers(int n) { m_num_local_players = n; } void setNumLocalPlayers(int n) { m_num_local_players = n; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the nunber of local players. */ /** Returns the nunber of local players. */
int getNumLocalPlayers() const { return m_num_local_players; } int getNumLocalPlayers() const { return m_num_local_players; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** \brief Get the players that are in the game /** \brief Get the players that are / were in the game
* \return A vector containing pointers on the players profiles. */ * \return A vector containing pointers on the players profiles. */
std::vector<std::weak_ptr<NetworkPlayerProfile> > getPlayers() const const std::vector<std::weak_ptr<NetworkPlayerProfile> >& getPlayers() const
{ {
std::lock_guard<std::mutex> lock(m_players_mutex); std::lock_guard<std::mutex> lock(m_players_mutex);
return m_players; return m_players;
} // getPlayers } // getPlayers
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** \brief Get the players that are in the game
* \return A vector containing pointers on the players profiles. */
std::vector<std::shared_ptr<NetworkPlayerProfile> >
getConnectedPlayers() const
{
std::lock_guard<std::mutex> lock(m_players_mutex);
std::vector<std::shared_ptr<NetworkPlayerProfile> > players;
std::transform(m_players.begin(), m_players.end(),
std::back_inserter(players),
std::bind(&std::weak_ptr<NetworkPlayerProfile>::lock,
std::placeholders::_1));
return players;
} // getConnectedPlayers
// ------------------------------------------------------------------------
/** Returns the number of connected players. */ /** Returns the number of connected players. */
unsigned getPlayerCount() unsigned getPlayerCount()
{ {

View File

@ -91,7 +91,7 @@ public:
int getGlobalPlayerId() const { return m_global_player_id; } int getGlobalPlayerId() const { return m_global_player_id; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the host id of this player. */ /** Returns the host id of this player. */
uint8_t getHostId() const { return m_host_id; } uint32_t getHostId() const { return m_host_id; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Sets the kart name for this player. */ /** Sets the kart name for this player. */
void setKartName(const std::string &kart_name) { m_kart_name = kart_name; } void setKartName(const std::string &kart_name) { m_kart_name = kart_name; }
@ -116,7 +116,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
float getDefaultKartColor() const { return m_default_kart_color; } float getDefaultKartColor() const { return m_default_kart_color; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
uint32_t getOnlineID() const { return m_online_id; } uint32_t getOnlineId() const { return m_online_id; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isOfflineAccount() const { return m_online_id == 0; } bool isOfflineAccount() const { return m_online_id == 0; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -105,7 +105,6 @@ void ClientLobby::doneWithResults()
} // doneWithResults } // doneWithResults
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool ClientLobby::notifyEvent(Event* event) bool ClientLobby::notifyEvent(Event* event)
{ {
assert(m_game_setup); // assert that the setup exists assert(m_game_setup); // assert that the setup exists
@ -118,7 +117,7 @@ bool ClientLobby::notifyEvent(Event* event)
switch(message_type) switch(message_type)
{ {
case LE_START_SELECTION: startSelection(event); break; case LE_START_SELECTION: startSelection(event); break;
case LE_LOAD_WORLD: loadWorld(); break; case LE_LOAD_WORLD: addAllPlayers(event); break;
case LE_RACE_FINISHED: raceFinished(event); break; case LE_RACE_FINISHED: raceFinished(event); break;
case LE_EXIT_RESULT: exitResultScreen(event); break; case LE_EXIT_RESULT: exitResultScreen(event); break;
case LE_UPDATE_PLAYER_LIST: updatePlayerList(event); break; case LE_UPDATE_PLAYER_LIST: updatePlayerList(event); break;
@ -131,7 +130,6 @@ bool ClientLobby::notifyEvent(Event* event)
} // notifyEvent } // notifyEvent
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool ClientLobby::notifyEventAsynchronous(Event* event) bool ClientLobby::notifyEventAsynchronous(Event* event)
{ {
assert(m_game_setup); // assert that the setup exists assert(m_game_setup); // assert that the setup exists
@ -186,6 +184,51 @@ bool ClientLobby::notifyEventAsynchronous(Event* event)
return false; return false;
} // notifyEventAsynchronous } // notifyEventAsynchronous
//-----------------------------------------------------------------------------
void ClientLobby::addAllPlayers(Event* event)
{
if (!checkDataSize(event, 1))
{
// If recieved invalid message for players leave now
STKHost::get()->disconnectAllPeers(false/*timeout_waiting*/);
STKHost::get()->requestShutdown();
return;
}
NetworkString& data = event->data();
std::string track_name;
data.decodeString(&track_name);
uint8_t lap = data.getUInt8();
bool reverse = (bool)data.getUInt8();
m_game_setup->setRace(track_name, lap, reverse);
std::shared_ptr<STKPeer> peer = event->getPeerSP();
peer->cleanPlayerProfiles();
std::vector<std::shared_ptr<NetworkPlayerProfile> > players;
unsigned player_count = data.getUInt8();
assert(m_game_setup->getPlayerCount() == 0);
for (unsigned i = 0; i < player_count; i++)
{
core::stringw player_name;
data.decodeStringW(&player_name);
uint32_t host_id = data.getUInt32();
float kart_color = data.getFloat();
uint32_t online_id = data.getUInt32();
PerPlayerDifficulty ppd = (PerPlayerDifficulty)data.getUInt8();
auto player = std::make_shared<NetworkPlayerProfile>(peer, player_name,
host_id, kart_color, online_id, ppd);
std::string kart_name;
data.decodeString(&kart_name);
player->setKartName(kart_name);
peer->addPlayer(player);
m_game_setup->addPlayer(player);
players.push_back(player);
}
configRemoteKart(players);
loadWorld();
} // addAllPlayers
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ClientLobby::update(float dt) void ClientLobby::update(float dt)
{ {

View File

@ -44,6 +44,8 @@ private:
std::set<std::string> m_available_karts; std::set<std::string> m_available_karts;
std::set<std::string> m_available_tracks; std::set<std::string> m_available_tracks;
void addAllPlayers(Event* event);
public: public:
ClientLobby(); ClientLobby();
virtual ~ClientLobby(); virtual ~ClientLobby();

View File

@ -66,13 +66,6 @@ void LobbyProtocol::loadWorld()
// This creates the network world. // This creates the network world.
RaceEventManager::getInstance<RaceEventManager>()->start(); RaceEventManager::getInstance<RaceEventManager>()->start();
// The number of karts includes the AI karts, which are not supported atm
race_manager->setNumKarts(m_game_setup->getPlayerCount());
// Set number of global and local players.
race_manager->setNumPlayers(m_game_setup->getPlayerCount(),
m_game_setup->getNumLocalPlayers());
// Make sure that if there is only a single local player this player can // Make sure that if there is only a single local player this player can
// use all input devices. // use all input devices.
StateManager::ActivePlayer *ap = race_manager->getNumLocalPlayers()>1 StateManager::ActivePlayer *ap = race_manager->getNumLocalPlayers()>1
@ -81,8 +74,6 @@ void LobbyProtocol::loadWorld()
input_manager->getDeviceManager()->setSinglePlayer(ap); input_manager->getDeviceManager()->setSinglePlayer(ap);
Log::info("LobbyProtocol", "Player configuration ready.");
// Load the actual world. // Load the actual world.
m_game_setup->loadWorld(); m_game_setup->loadWorld();
World::getWorld()->setNetworkWorld(true); World::getWorld()->setNetworkWorld(true);
@ -92,15 +83,22 @@ void LobbyProtocol::loadWorld()
} // loadWorld } // loadWorld
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void LobbyProtocol::configRemoteKart() 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(players.size());
// Set number of global and local players.
race_manager->setNumPlayers(players.size(),
m_game_setup->getNumLocalPlayers());
// Create the kart information for the race manager: // Create the kart information for the race manager:
// ------------------------------------------------- // -------------------------------------------------
/*std::vector<NetworkPlayerProfile*> players = m_game_setup->getPlayers();
int local_player_id = 0; int local_player_id = 0;
for (unsigned int i = 0; i < players.size(); i++) for (unsigned int i = 0; i < players.size(); i++)
{ {
NetworkPlayerProfile* profile = players[i]; std::shared_ptr<NetworkPlayerProfile> profile = players[i];
bool is_local = profile->isLocalPlayer(); bool is_local = profile->isLocalPlayer();
// All non-local players are created here. This means all players // All non-local players are created here. This means all players
@ -123,7 +121,8 @@ void LobbyProtocol::configRemoteKart()
profile->getName(), profile->getName(),
profile->getHostId(), profile->getHostId(),
!is_local); !is_local);
rki.setGlobalPlayerId(profile->getGlobalPlayerId()); rki.setGlobalPlayerId(i);
rki.setDefaultKartColor(profile->getDefaultKartColor());
rki.setPerPlayerDifficulty(profile->getPerPlayerDifficulty()); rki.setPerPlayerDifficulty(profile->getPerPlayerDifficulty());
if (is_local) if (is_local)
{ {
@ -133,7 +132,8 @@ void LobbyProtocol::configRemoteKart()
// Inform the race manager about the data for this kart. // Inform the race manager about the data for this kart.
race_manager->setPlayerKart(i, rki); race_manager->setPlayerKart(i, rki);
} // for i in players*/ } // for i in players
Log::info("LobbyProtocol", "Player configuration ready.");
} // configRemoteKart } // configRemoteKart
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -25,6 +25,9 @@
class GameSetup; class GameSetup;
class NetworkPlayerProfile; class NetworkPlayerProfile;
#include <memory>
#include <vector>
/*! /*!
* \class LobbyProtocol * \class LobbyProtocol
* \brief Base class for both client and server lobby. The lobbies are started * \brief Base class for both client and server lobby. The lobbies are started
@ -75,7 +78,8 @@ protected:
/** Stores data about the online game to play. */ /** Stores data about the online game to play. */
GameSetup* m_game_setup; GameSetup* m_game_setup;
void configRemoteKart(); void configRemoteKart(
const std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const;
public: public:

View File

@ -317,6 +317,48 @@ void ServerLobby::asynchronousUpdate()
m_state = RACING; m_state = RACING;
World::getWorld()->setReadyToRace(); World::getWorld()->setReadyToRace();
} }
break;
case SELECTING:
if (m_timeout < (float)StkTime::getRealTime())
{
auto result = handleVote();
// Remove disconnected player (if any) one last time
m_game_setup->update(true);
auto players = m_game_setup->getConnectedPlayers();
// TODO: sort players for grand prix here
configRemoteKart(players);
// Reset for next state usage
for (auto p : m_peers_ready)
{
p.second = false;
}
m_state = LOAD_WORLD;
NetworkString* load_world = getNetworkString();
load_world->setSynchronous(true);
load_world->addUInt8(LE_LOAD_WORLD).encodeString(std::get<0>(result))
.addUInt8(std::get<1>(result)).addUInt8(std::get<2>(result))
.addUInt8((uint8_t)players.size());
for (auto player : players)
{
load_world->encodeString(player->getName())
.addUInt32(player->getHostId())
.addFloat(player->getDefaultKartColor())
.addUInt32(player->getOnlineId())
.addUInt8(player->getPerPlayerDifficulty());
if (player->getKartName().empty())
{
RandomGenerator rg;
std::set<std::string>::iterator it =
m_available_kts.first.begin();
std::advance(it, rg.get((int)m_available_kts.first.size()));
player->setKartName(*it);
}
load_world->encodeString(player->getKartName());
}
sendMessageToPeersChangingToken(load_world);
delete load_world;
}
break;
default: default:
break; break;
} }
@ -883,7 +925,7 @@ void ServerLobby::updatePlayerList()
pl->addUInt8(LE_UPDATE_PLAYER_LIST).addUInt8((uint8_t)all_profiles.size()); pl->addUInt8(LE_UPDATE_PLAYER_LIST).addUInt8((uint8_t)all_profiles.size());
for (auto profile : all_profiles) for (auto profile : all_profiles)
{ {
pl->addUInt32(profile->getHostId()).addUInt32(profile->getOnlineID()) pl->addUInt32(profile->getHostId()).addUInt32(profile->getOnlineId())
.encodeString(profile->getName()); .encodeString(profile->getName());
uint8_t server_owner = 0; uint8_t server_owner = 0;
if (m_server_owner.lock() == profile->getPeer()) if (m_server_owner.lock() == profile->getPeer())
@ -963,15 +1005,16 @@ void ServerLobby::kartSelectionRequested(Event* event)
data.decodeString(&kart); data.decodeString(&kart);
if (m_available_kts.first.find(kart) == m_available_kts.first.end()) if (m_available_kts.first.find(kart) == m_available_kts.first.end())
{ {
// Will be reset to a random one later
Log::debug("ServerLobby", "Player %d from peer %d chose unknown " Log::debug("ServerLobby", "Player %d from peer %d chose unknown "
"kart %s, use a random one", i, peer->getHostId(), "kart %s, use a random one", i, peer->getHostId(),
kart.c_str()); kart.c_str());
RandomGenerator rg; continue;
std::set<std::string>::iterator it = m_available_kts.first.begin(); }
std::advance(it, rg.get((int)m_available_kts.first.size())); else
kart = *it; {
peer->getPlayerProfiles()[i]->setKartName(kart);
} }
peer->getPlayerProfiles()[i]->setKartName(kart);
Log::verbose("ServerLobby", "Player %d from peer %d chose %s", i, Log::verbose("ServerLobby", "Player %d from peer %d chose %s", i,
peer->getHostId(), kart.c_str()); peer->getHostId(), kart.c_str());
} }
@ -1001,17 +1044,7 @@ void ServerLobby::playerVote(Event* event)
float remaining_time = m_timeout - (float)StkTime::getRealTime(); float remaining_time = m_timeout - (float)StkTime::getRealTime();
if (remaining_time < 0.0f) if (remaining_time < 0.0f)
{ {
// Start world remaining_time = 0.0f;
handleVote();
configRemoteKart();
// Reset for next state usage
for (auto p : m_peers_ready)
{
p.second = false;
}
m_state = LOAD_WORLD;
return;
} }
NetworkString& data = event->data(); NetworkString& data = event->data();
@ -1022,15 +1055,17 @@ void ServerLobby::playerVote(Event* event)
std::string track_name; std::string track_name;
data.decodeString(&track_name); data.decodeString(&track_name);
m_peers_votes.emplace(event->getPeerSP(), std::forward_as_tuple(track_name, uint8_t lap = data.getUInt8();
data.getUInt8(), (bool)data.getUInt8())); bool reverse = (bool)data.getUInt8();
m_peers_votes[event->getPeerSP()] =
std::make_tuple(track_name,lap, reverse);
other.addUInt8((uint8_t)remaining_time); other.addUInt8((uint8_t)remaining_time);
sendMessageToPeersChangingToken(&other); sendMessageToPeersChangingToken(&other);
} // playerVote } // playerVote
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ServerLobby::handleVote() std::tuple<std::string, uint8_t, bool> ServerLobby::handleVote()
{ {
// Default settings if no votes at all // Default settings if no votes at all
RandomGenerator rg; RandomGenerator rg;
@ -1104,6 +1139,7 @@ void ServerLobby::handleVote()
final_reverse = reverse_vote->first; final_reverse = reverse_vote->first;
m_game_setup->setRace(final_track, final_laps, final_reverse); m_game_setup->setRace(final_track, final_laps, final_reverse);
return std::make_tuple(final_track, final_laps, final_reverse);
} // handleVote } // handleVote
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -93,7 +93,7 @@ private:
void updatePlayerList(); void updatePlayerList();
void updateServerOwner(); void updateServerOwner();
bool checkPeersReady() const; bool checkPeersReady() const;
void handleVote(); std::tuple<std::string, uint8_t, bool> handleVote();
public: public:
ServerLobby(); ServerLobby();

View File

@ -142,7 +142,7 @@ bool STKPeer::isBanned() const
return true; return true;
for (auto p : m_players) for (auto p : m_players)
{ {
if (ret->second == p->getOnlineID()) if (ret->second == p->getOnlineId())
return true; return true;
} }
} }