Add initial live join handling for the one who does it
This commit is contained in:
parent
0431344886
commit
2f8da236e3
@ -193,7 +193,8 @@ bool LocalPlayerController::action(PlayerAction action, int value,
|
||||
// If this is a client, send the action to networking layer
|
||||
if (NetworkConfig::get()->isNetworking() &&
|
||||
NetworkConfig::get()->isClient() &&
|
||||
!RewindManager::get()->isRewinding())
|
||||
!RewindManager::get()->isRewinding() &&
|
||||
World::getWorld() && !World::getWorld()->isLiveJoinWorld())
|
||||
{
|
||||
if (auto gp = GameProtocol::lock())
|
||||
{
|
||||
|
@ -1412,7 +1412,7 @@ void Kart::update(int ticks)
|
||||
|
||||
// Hover the kart above reset position before entering the game
|
||||
if (m_live_join_util != 0 &&
|
||||
(m_live_join_util < World::getWorld()->getTicksSinceStart() ||
|
||||
(m_live_join_util > World::getWorld()->getTicksSinceStart() ||
|
||||
World::getWorld()->isLiveJoinWorld()))
|
||||
{
|
||||
btRigidBody *body = getBody();
|
||||
|
@ -326,6 +326,8 @@ public:
|
||||
unsigned int getCurrentNumPlayers() const { return m_num_players -
|
||||
m_eliminated_players;}
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void addReservedKart(int kart_id) { m_eliminated_karts--; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** The code that draws the timer should call this first to know
|
||||
* whether the game mode wants a timer drawn. */
|
||||
virtual bool shouldDrawTimer() const
|
||||
|
@ -275,7 +275,7 @@ void WorldStatus::updateTime(int ticks)
|
||||
// Add 3 seconds delay before telling server finish loading
|
||||
// world, so previous (if any) disconnected player has left
|
||||
// fully
|
||||
if (m_auxiliary_ticks == 360)
|
||||
if (m_auxiliary_ticks == stk_config->time2Ticks(3.0f))
|
||||
{
|
||||
auto lobby = LobbyProtocol::get<LobbyProtocol>();
|
||||
assert(lobby);
|
||||
@ -545,4 +545,8 @@ void WorldStatus::endLiveJoinWorld(int ticks_now)
|
||||
{
|
||||
m_live_join_world = false;
|
||||
m_auxiliary_ticks = 0;
|
||||
m_phase = RACE_PHASE;
|
||||
startEngines();
|
||||
music_manager->startMusic();
|
||||
setTicksForRewind(ticks_now);
|
||||
} // endLiveJoinWorld
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "input/device_manager.hpp"
|
||||
#include "items/item_manager.hpp"
|
||||
#include "items/powerup_manager.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/controller.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "modes/linear_world.hpp"
|
||||
#include "network/crypto.hpp"
|
||||
@ -109,6 +111,8 @@ ClientLobby::~ClientLobby()
|
||||
void ClientLobby::setup()
|
||||
{
|
||||
m_auto_back_to_lobby_time = std::numeric_limits<uint64_t>::max();
|
||||
m_start_live_game_time = std::numeric_limits<uint64_t>::max();
|
||||
m_live_join_ticks = -1;
|
||||
m_received_server_result = false;
|
||||
TracksScreen::getInstance()->resetVote();
|
||||
LobbyProtocol::setup();
|
||||
@ -155,6 +159,7 @@ bool ClientLobby::notifyEvent(Event* event)
|
||||
case LE_SERVER_OWNERSHIP: becomingServerOwner(); break;
|
||||
case LE_BAD_TEAM: handleBadTeam(); break;
|
||||
case LE_BAD_CONNECTION: handleBadConnection(); break;
|
||||
case LE_LIVE_JOIN_ACK: liveJoinAcknowledged(event); break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
@ -272,6 +277,22 @@ void ClientLobby::addAllPlayers(Event* event)
|
||||
// Disable until render gui during loading is bug free
|
||||
//StateManager::get()->enterGameState();
|
||||
|
||||
// Live join if state is CONNECTED
|
||||
if (m_state.load() == CONNECTED)
|
||||
{
|
||||
World* w = World::getWorld();
|
||||
w->setLiveJoinWorld(true);
|
||||
for (unsigned i = 0; i < w->getNumKarts(); i++)
|
||||
{
|
||||
AbstractKart* k = w->getKart(i);
|
||||
// The final joining ticks will be set by server later
|
||||
if (k->getController()->isLocalPlayerController())
|
||||
k->setLiveJoinKart(-1);
|
||||
else
|
||||
k->getNode()->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Switch to assign mode in case a player hasn't chosen any karts
|
||||
input_manager->getDeviceManager()->setAssignMode(ASSIGN);
|
||||
} // addAllPlayers
|
||||
@ -374,6 +395,11 @@ void ClientLobby::update(int ticks)
|
||||
break;
|
||||
case REQUESTING_CONNECTION:
|
||||
case CONNECTED:
|
||||
if (m_start_live_game_time != std::numeric_limits<uint64_t>::max() &&
|
||||
STKHost::get()->getNetworkTimer() >= m_start_live_game_time)
|
||||
{
|
||||
finishLiveJoin();
|
||||
}
|
||||
if (NetworkConfig::get()->isAutoConnect() && !m_auto_started)
|
||||
{
|
||||
// Send a message to the server to start
|
||||
@ -931,7 +957,51 @@ void ClientLobby::exitResultScreen(Event *event)
|
||||
void ClientLobby::finishedLoadingWorld()
|
||||
{
|
||||
NetworkString* ns = getNetworkString(1);
|
||||
// Live join if state is CONNECTED
|
||||
ns->setSynchronous(m_state.load() == CONNECTED);
|
||||
ns->addUInt8(LE_CLIENT_LOADED_WORLD);
|
||||
sendToServer(ns, true);
|
||||
delete ns;
|
||||
} // finishedLoadingWorld
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ClientLobby::liveJoinAcknowledged(Event* event)
|
||||
{
|
||||
World* w = World::getWorld();
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
const NetworkString& data = event->data();
|
||||
m_start_live_game_time = data.getUInt64();
|
||||
powerup_manager->setRandomSeed(m_start_live_game_time);
|
||||
m_start_live_game_time = data.getUInt64();
|
||||
m_live_join_ticks = data.getUInt32();
|
||||
for (unsigned i = 0; i < w->getNumKarts(); i++)
|
||||
{
|
||||
AbstractKart* k = w->getKart(i);
|
||||
if (k->getController()->isLocalPlayerController())
|
||||
k->setLiveJoinKart(m_live_join_ticks);
|
||||
}
|
||||
} // liveJoinAcknowledged
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ClientLobby::finishLiveJoin()
|
||||
{
|
||||
m_start_live_game_time = std::numeric_limits<uint64_t>::max();
|
||||
World* w = World::getWorld();
|
||||
if (!w)
|
||||
return;
|
||||
Log::info("ClientLobby", "Live join started at %lf",
|
||||
StkTime::getRealTime());
|
||||
|
||||
w->setLiveJoinWorld(false);
|
||||
w->endLiveJoinWorld(m_live_join_ticks);
|
||||
for (unsigned i = 0; i < w->getNumKarts(); i++)
|
||||
{
|
||||
AbstractKart* k = w->getKart(i);
|
||||
if (!k->getController()->isLocalPlayerController() &&
|
||||
!k->isEliminated())
|
||||
k->getNode()->setVisible(true);
|
||||
}
|
||||
m_state.store(RACING);
|
||||
} // finishLiveJoin
|
||||
|
@ -81,6 +81,10 @@ private:
|
||||
|
||||
uint64_t m_auto_back_to_lobby_time;
|
||||
|
||||
uint64_t m_start_live_game_time;
|
||||
|
||||
int m_live_join_ticks;
|
||||
|
||||
/** The state of the finite state machine. */
|
||||
std::atomic<ClientState> m_state;
|
||||
|
||||
@ -95,6 +99,8 @@ private:
|
||||
|
||||
irr::core::stringw m_total_players;
|
||||
|
||||
void liveJoinAcknowledged(Event* event);
|
||||
void finishLiveJoin();
|
||||
public:
|
||||
ClientLobby(const TransportAddress& a, std::shared_ptr<Server> s);
|
||||
virtual ~ClientLobby();
|
||||
|
@ -173,6 +173,9 @@ void GameProtocol::controllerAction(int kart_id, PlayerAction action,
|
||||
*/
|
||||
void GameProtocol::handleControllerAction(Event *event)
|
||||
{
|
||||
STKPeer* peer = event->getPeer();
|
||||
if (NetworkConfig::get()->isServer() && peer->isWaitingForGame())
|
||||
return;
|
||||
NetworkString &data = event->data();
|
||||
uint8_t count = data.getUInt8();
|
||||
bool will_trigger_rewind = false;
|
||||
@ -193,10 +196,10 @@ void GameProtocol::handleControllerAction(Event *event)
|
||||
}
|
||||
uint8_t kart_id = data.getUInt8();
|
||||
if (NetworkConfig::get()->isServer() &&
|
||||
!event->getPeer()->availableKartID(kart_id))
|
||||
!peer->availableKartID(kart_id))
|
||||
{
|
||||
Log::warn("GameProtocol", "Wrong kart id %d from %s.",
|
||||
kart_id, event->getPeer()->getAddress().toString().c_str());
|
||||
kart_id, peer->getAddress().toString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -227,9 +230,9 @@ void GameProtocol::handleControllerAction(Event *event)
|
||||
{
|
||||
// Send update to all clients except the original sender if the event
|
||||
// is after the server time
|
||||
event->getPeer()->updateLastActivity();
|
||||
peer->updateLastActivity();
|
||||
if (!will_trigger_rewind)
|
||||
STKHost::get()->sendPacketExcept(event->getPeer(), &data, false);
|
||||
STKHost::get()->sendPacketExcept(peer, &data, false);
|
||||
|
||||
// FIXME unless there is a network jitter more than 100ms (more than
|
||||
// server delay), time adjust is not necessary
|
||||
|
@ -68,7 +68,8 @@ public:
|
||||
LE_BAD_CONNECTION,
|
||||
LE_CONFIG_SERVER,
|
||||
LE_CHANGE_HANDICAP,
|
||||
LE_LIVE_JOIN
|
||||
LE_LIVE_JOIN,
|
||||
LE_LIVE_JOIN_ACK
|
||||
};
|
||||
|
||||
enum RejectReason : uint8_t
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "config/user_config.hpp"
|
||||
#include "items/item_manager.hpp"
|
||||
#include "items/powerup_manager.hpp"
|
||||
#include "graphics/render_info.hpp"
|
||||
#include "karts/abstract_kart.hpp"
|
||||
#include "karts/controller/player_controller.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
@ -298,6 +299,7 @@ bool ServerLobby::notifyEvent(Event* event)
|
||||
{
|
||||
case LE_RACE_FINISHED_ACK: playerFinishedResult(event); break;
|
||||
case LE_LIVE_JOIN: liveJoinRequest(event); break;
|
||||
case LE_CLIENT_LOADED_WORLD: finishedLoadingLiveJoinClient(event); break;
|
||||
default: Log::error("ServerLobby", "Unknown message type %d - ignored.",
|
||||
message_type);
|
||||
break;
|
||||
@ -647,10 +649,230 @@ NetworkString* ServerLobby::getLoadWorldMessage(
|
||||
} // getLoadWorldMessage
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool ServerLobby::canLiveJoinNow() const
|
||||
{
|
||||
return race_manager->supportsLiveJoining() &&
|
||||
World::getWorld() && RaceEventManager::getInstance()->isRunning() &&
|
||||
!RaceEventManager::getInstance()->isRaceOver() &&
|
||||
(World::getWorld()->getPhase() == WorldStatus::RACE_PHASE ||
|
||||
World::getWorld()->getPhase() == WorldStatus::GOAL_PHASE);
|
||||
} // canLiveJoinNow
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** \ref peer will be reset back to the lobby.
|
||||
*/
|
||||
void ServerLobby::rejectLiveJoin(STKPeer* peer)
|
||||
{
|
||||
NetworkString* reset = getNetworkString(1);
|
||||
reset->setSynchronous(true);
|
||||
reset->addUInt8(LE_EXIT_RESULT);
|
||||
peer->sendPacket(reset, /*reliable*/true);
|
||||
delete reset;
|
||||
updatePlayerList();
|
||||
NetworkString* server_info = getNetworkString();
|
||||
server_info->setSynchronous(true);
|
||||
server_info->addUInt8(LE_SERVER_INFO);
|
||||
m_game_setup->addServerInfo(server_info);
|
||||
peer->sendPacket(server_info, /*reliable*/true);
|
||||
delete server_info;
|
||||
} // rejectLiveJoin
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** This message is like kartSelectionRequested, but it will send the peer
|
||||
* load world message if he can join the current started game.
|
||||
*/
|
||||
void ServerLobby::liveJoinRequest(Event* event)
|
||||
{
|
||||
STKPeer* peer = event->getPeer();
|
||||
const NetworkString& data = event->data();
|
||||
|
||||
if (!canLiveJoinNow())
|
||||
{
|
||||
rejectLiveJoin(peer);
|
||||
return;
|
||||
}
|
||||
setPlayerKarts(data, peer);
|
||||
|
||||
std::vector<int> used_id;
|
||||
for (unsigned i = 0; i < peer->getPlayerProfiles().size(); i++)
|
||||
{
|
||||
int id = getReservedId(peer->getPlayerProfiles()[i], i);
|
||||
if (id == -1)
|
||||
break;
|
||||
used_id.push_back(id);
|
||||
}
|
||||
if (used_id.size() != peer->getPlayerProfiles().size())
|
||||
{
|
||||
for (unsigned i = 0; i < peer->getPlayerProfiles().size(); i++)
|
||||
peer->getPlayerProfiles()[i]->setKartName("");
|
||||
for (unsigned i = 0; i < used_id.size(); i++)
|
||||
{
|
||||
RemoteKartInfo& rki = race_manager->getKartInfo(used_id[i]);
|
||||
rki.makeReserved();
|
||||
}
|
||||
Log::info("ServerLobby", "Too many players (%d) try to live join",
|
||||
(int)peer->getPlayerProfiles().size());
|
||||
rejectLiveJoin(peer);
|
||||
return;
|
||||
}
|
||||
|
||||
peer->clearAvailableKartIDs();
|
||||
for (int id : used_id)
|
||||
{
|
||||
Log::info("ServerLobby", "%s live joining with reserved kart id %d.",
|
||||
peer->getAddress().toString().c_str(), id);
|
||||
peer->addAvailableKartID(id);
|
||||
}
|
||||
std::vector<std::shared_ptr<NetworkPlayerProfile> > players;
|
||||
for (unsigned i = 0; i < race_manager->getNumPlayers(); i++)
|
||||
{
|
||||
const RemoteKartInfo& rki = race_manager->getKartInfo(i);
|
||||
std::shared_ptr<NetworkPlayerProfile> player =
|
||||
rki.getNetworkPlayerProfile().lock();
|
||||
if (!player)
|
||||
{
|
||||
player = NetworkPlayerProfile::getReservedProfile(
|
||||
race_manager->getMinorMode() ==
|
||||
RaceManager::MINOR_MODE_FREE_FOR_ALL ?
|
||||
KART_TEAM_NONE : rki.getKartTeam());
|
||||
}
|
||||
players.push_back(player);
|
||||
}
|
||||
NetworkString* load_world_message = getLoadWorldMessage(players);
|
||||
peer->sendPacket(load_world_message, true/*reliable*/);
|
||||
delete load_world_message;
|
||||
peer->updateLastActivity();
|
||||
} // liveJoinRequest
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Decide where to put the live join player depends on his team and game mode.
|
||||
*/
|
||||
int ServerLobby::getReservedId(std::shared_ptr<NetworkPlayerProfile>& p,
|
||||
unsigned local_id) const
|
||||
{
|
||||
const bool is_ffa =
|
||||
race_manager->getMinorMode() == RaceManager::MINOR_MODE_FREE_FOR_ALL;
|
||||
int red_count = 0;
|
||||
int blue_count = 0;
|
||||
for (unsigned i = 0; i < race_manager->getNumPlayers(); i++)
|
||||
{
|
||||
RemoteKartInfo& rki = race_manager->getKartInfo(i);
|
||||
if (rki.isReserved())
|
||||
continue;
|
||||
bool disconnected = rki.disconnected();
|
||||
if (race_manager->getKartInfo(i).getKartTeam() == KART_TEAM_RED &&
|
||||
!disconnected)
|
||||
red_count++;
|
||||
else if (race_manager->getKartInfo(i).getKartTeam() ==
|
||||
KART_TEAM_BLUE && !disconnected)
|
||||
blue_count++;
|
||||
}
|
||||
KartTeam target_team = red_count > blue_count ? KART_TEAM_BLUE :
|
||||
KART_TEAM_RED;
|
||||
|
||||
for (unsigned i = 0; i < race_manager->getNumPlayers(); i++)
|
||||
{
|
||||
RemoteKartInfo& rki = race_manager->getKartInfo(i);
|
||||
std::shared_ptr<NetworkPlayerProfile> player =
|
||||
rki.getNetworkPlayerProfile().lock();
|
||||
if (!player)
|
||||
{
|
||||
if (is_ffa)
|
||||
{
|
||||
rki.copyFrom(p, local_id);
|
||||
return i;
|
||||
}
|
||||
if (ServerConfig::m_team_choosing)
|
||||
{
|
||||
if ((p->getTeam() == KART_TEAM_RED &&
|
||||
rki.getKartTeam() == KART_TEAM_RED) ||
|
||||
(p->getTeam() == KART_TEAM_BLUE &&
|
||||
rki.getKartTeam() == KART_TEAM_BLUE))
|
||||
{
|
||||
rki.copyFrom(p, local_id);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rki.getKartTeam() == target_team)
|
||||
{
|
||||
p->setTeam(target_team);
|
||||
rki.copyFrom(p, local_id);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
} // getReservedId
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Finally put the kart in the world and inform client the current world
|
||||
* status, (including current confirmed item state, kart scores...)
|
||||
*/
|
||||
void ServerLobby::finishedLoadingLiveJoinClient(Event* event)
|
||||
{
|
||||
STKPeer* peer = event->getPeer();
|
||||
if (!canLiveJoinNow())
|
||||
{
|
||||
rejectLiveJoin(peer);
|
||||
return;
|
||||
}
|
||||
bool live_joined_in_time = true;
|
||||
for (const int id : peer->getAvailableKartIDs())
|
||||
{
|
||||
const RemoteKartInfo& rki = race_manager->getKartInfo(id);
|
||||
if (rki.isReserved())
|
||||
{
|
||||
live_joined_in_time = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!live_joined_in_time)
|
||||
{
|
||||
Log::warn("ServerLobby", "%s can't live-join in time.",
|
||||
peer->getAddress().toString().c_str());
|
||||
rejectLiveJoin(peer);
|
||||
return;
|
||||
}
|
||||
World* w = World::getWorld();
|
||||
assert(w);
|
||||
|
||||
// Give 3 seconds for all peers to get new kart info
|
||||
const int live_join_util_ticks = w->getTicksSinceStart() +
|
||||
stk_config->time2Ticks(3.0f);
|
||||
uint64_t live_join_start_time = STKHost::get()->getNetworkTimer();
|
||||
live_join_start_time -= m_server_delay;
|
||||
live_join_start_time += 3000;
|
||||
|
||||
for (const int id : peer->getAvailableKartIDs())
|
||||
{
|
||||
const RemoteKartInfo& rki = race_manager->getKartInfo(id);
|
||||
AbstractKart* k = w->getKart(id);
|
||||
k->changeKart(rki.getKartName(), rki.getDifficulty(),
|
||||
rki.getKartTeam() == KART_TEAM_RED ?
|
||||
std::make_shared<RenderInfo>(1.0f) :
|
||||
rki.getKartTeam() == KART_TEAM_BLUE ?
|
||||
std::make_shared<RenderInfo>(0.66f) :
|
||||
std::make_shared<RenderInfo>(rki.getDefaultKartColor()));
|
||||
k->setLiveJoinKart(live_join_util_ticks);
|
||||
w->addReservedKart(id);
|
||||
}
|
||||
Log::info("ServerLobby", "%s live-joining succeeded.",
|
||||
peer->getAddress().toString().c_str());
|
||||
|
||||
NetworkString* ns = getNetworkString(10);
|
||||
ns->setSynchronous(true);
|
||||
ns->addUInt8(LE_LIVE_JOIN_ACK).addUInt64(m_client_starting_time)
|
||||
.addUInt64(live_join_start_time).addUInt32(live_join_util_ticks);
|
||||
peer->setWaitingForGame(false);
|
||||
peer->sendPacket(ns, true/*reliable*/);
|
||||
delete ns;
|
||||
updatePlayerList();
|
||||
peer->updateLastActivity();
|
||||
} // finishedLoadingLiveJoinClient
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Simple finite state machine. Once this
|
||||
* is known, register the server and its address with the stk server so that
|
||||
@ -660,8 +882,7 @@ void ServerLobby::update(int ticks)
|
||||
{
|
||||
World* w = World::getWorld();
|
||||
int sec = ServerConfig::m_kick_idle_player_seconds;
|
||||
if (NetworkConfig::get()->isWAN() &&
|
||||
sec > 0 && m_state.load() >= WAIT_FOR_WORLD_LOADED &&
|
||||
if (sec > 0 && m_state.load() >= WAIT_FOR_WORLD_LOADED &&
|
||||
m_state.load() <= RACING && m_server_has_loaded_world.load() == true)
|
||||
{
|
||||
for (unsigned i = 0; i < race_manager->getNumPlayers(); i++)
|
||||
@ -672,15 +893,27 @@ void ServerLobby::update(int ticks)
|
||||
if (!player)
|
||||
continue;
|
||||
auto peer = player->getPeer();
|
||||
if (peer && peer->idleForSeconds() > sec &&
|
||||
!peer->isDisconnected())
|
||||
if (peer && peer->idleForSeconds() > sec)
|
||||
{
|
||||
if (w && w->getKart(i)->hasFinishedRace())
|
||||
if (w && w->getKart(i)->isEliminated())
|
||||
{
|
||||
// Remove loading world too long live join peer
|
||||
Log::info("ServerLobby", "%s hasn't live-joined within"
|
||||
" %d seconds, remove it.",
|
||||
peer->getAddress().toString().c_str(), sec);
|
||||
RemoteKartInfo& rki = race_manager->getKartInfo(i);
|
||||
rki.makeReserved();
|
||||
continue;
|
||||
Log::info("ServerLobby", "%s has been idle for more than"
|
||||
" %d seconds, kick.",
|
||||
peer->getAddress().toString().c_str(), sec);
|
||||
peer->kick();
|
||||
}
|
||||
if (!peer->isDisconnected() && NetworkConfig::get()->isWAN())
|
||||
{
|
||||
if (w && w->getKart(i)->hasFinishedRace())
|
||||
continue;
|
||||
Log::info("ServerLobby", "%s has been idle for more than"
|
||||
" %d seconds, kick.",
|
||||
peer->getAddress().toString().c_str(), sec);
|
||||
peer->kick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2963,10 +3196,12 @@ void ServerLobby::handlePlayerDisconnection() const
|
||||
total++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
rki.makeReserved();
|
||||
|
||||
AbstractKart* k = World::getWorld()->getKart(i);
|
||||
if (!k->isEliminated() && !k->hasFinishedRace())
|
||||
{
|
||||
rki.makeReserved();
|
||||
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>
|
||||
(World::getWorld());
|
||||
if (ctf)
|
||||
|
@ -183,6 +183,7 @@ private:
|
||||
void playerFinishedResult(Event *event);
|
||||
bool registerServer(bool now);
|
||||
void finishedLoadingWorldClient(Event *event);
|
||||
void finishedLoadingLiveJoinClient(Event *event);
|
||||
void kickHost(Event* event);
|
||||
void changeTeam(Event* event);
|
||||
void handleChat(Event* event);
|
||||
@ -276,6 +277,10 @@ private:
|
||||
std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const;
|
||||
void setPlayerKarts(const NetworkString& ns, STKPeer* peer) const;
|
||||
void liveJoinRequest(Event* event);
|
||||
void rejectLiveJoin(STKPeer* peer);
|
||||
bool canLiveJoinNow() const;
|
||||
int getReservedId(std::shared_ptr<NetworkPlayerProfile>& p,
|
||||
unsigned local_id) const;
|
||||
public:
|
||||
ServerLobby();
|
||||
virtual ~ServerLobby();
|
||||
|
@ -207,6 +207,9 @@ public:
|
||||
bool availableKartID(unsigned id)
|
||||
{ return m_available_kart_ids.find(id) != m_available_kart_ids.end(); }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::set<unsigned>& getAvailableKartIDs() const
|
||||
{ return m_available_kart_ids; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setUserVersion(const std::string& uv) { m_user_version = uv; }
|
||||
// ------------------------------------------------------------------------
|
||||
const std::string& getUserVersion() const { return m_user_version; }
|
||||
|
Loading…
Reference in New Issue
Block a user