Eliminate disconnected kart

This commit is contained in:
Benau 2018-04-16 15:18:10 +08:00
parent 6f30fd0cb0
commit d4fb888ffa
5 changed files with 50 additions and 13 deletions

View File

@ -1202,6 +1202,7 @@ AbstractKart *World::getLocalPlayerKart(unsigned int n) const
/** Remove (eliminate) a kart from the race */ /** Remove (eliminate) a kart from the race */
void World::eliminateKart(int kart_id, bool notify_of_elimination) void World::eliminateKart(int kart_id, bool notify_of_elimination)
{ {
assert(kart_id < (int)m_karts.size());
AbstractKart *kart = m_karts[kart_id]; AbstractKart *kart = m_karts[kart_id];
if (kart->isGhostKart()) return; if (kart->isGhostKart()) return;

View File

@ -113,7 +113,6 @@ protected:
void updateHighscores (int* best_highscore_rank); void updateHighscores (int* best_highscore_rank);
void resetAllKarts (); void resetAllKarts ();
void eliminateKart (int kart_number, bool notifyOfElimination=true);
Controller* Controller*
loadAIController (AbstractKart *kart); loadAIController (AbstractKart *kart);
@ -321,6 +320,8 @@ public:
virtual void escapePressed(); virtual void escapePressed();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void loadCustomModels() {} virtual void loadCustomModels() {}
// ------------------------------------------------------------------------
void eliminateKart(int kart_number, bool notify_of_elimination = true);
/** Set the network mode (true if networked) */ /** Set the network mode (true if networked) */
void setNetworkWorld(bool is_networked) { m_is_network_world = is_networked; } void setNetworkWorld(bool is_networked) { m_is_network_world = is_networked; }

View File

@ -23,14 +23,15 @@
#include "modes/world.hpp" #include "modes/world.hpp"
#include "network/network_config.hpp" #include "network/network_config.hpp"
#include "network/network_player_profile.hpp" #include "network/network_player_profile.hpp"
#include "online/online_profile.hpp" #include "network/protocols/game_events_protocol.hpp"
#include "network/stk_host.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Update and see if any player disconnects. /** Update and see if any player disconnects.
* \param remove_disconnected_players remove the disconnected players, * \param remove_disconnected_players remove the disconnected players,
* otherwise replace with AI (when racing), so this function must be called * otherwise eliminate the kart in world, so this function must be called
* in main thread. * in main thread.
*/ */
void GameSetup::update(bool remove_disconnected_players) void GameSetup::update(bool remove_disconnected_players)
@ -46,8 +47,27 @@ void GameSetup::update(bool remove_disconnected_players)
return; return;
} }
lock.unlock(); lock.unlock();
if (!World::getWorld()) if (!World::getWorld() ||
World::getWorld()->getPhase() < WorldStatus::MUSIC_PHASE)
return; return;
for (uint8_t i = 0; i < (uint8_t)m_players.size(); i++)
{
if (!m_players[i].expired())
continue;
AbstractKart* k = World::getWorld()->getKart(i);
if (!k->isEliminated())
{
World::getWorld()->eliminateKart(i,
false/*notify_of_elimination*/);
k->setPosition(
World::getWorld()->getCurrentNumKarts() + 1);
k->finishedRace(World::getWorld()->getTime());
NetworkString p(PROTOCOL_GAME_EVENTS);
p.setSynchronous(true);
p.addUInt8(GameEventsProtocol::GE_PLAYER_DISCONNECT).addUInt8(i);
STKHost::get()->sendPacketToAllPeers(&p, true);
}
}
} // removePlayer } // removePlayer
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -46,11 +46,6 @@ bool GameEventsProtocol::notifyEvent(Event* event)
Log::warn("GameEventsProtocol", "Too short message."); Log::warn("GameEventsProtocol", "Too short message.");
return true; return true;
} }
if ( event->getPeer()->getClientServerToken() != data.getToken())
{
Log::warn("GameEventsProtocol", "Bad token.");
return true;
}
uint8_t type = data.getUInt8(); uint8_t type = data.getUInt8();
switch (type) switch (type)
{ {
@ -58,7 +53,8 @@ bool GameEventsProtocol::notifyEvent(Event* event)
collectedItem(data); break; collectedItem(data); break;
case GE_KART_FINISHED_RACE: case GE_KART_FINISHED_RACE:
kartFinishedRace(data); break; kartFinishedRace(data); break;
case GE_PLAYER_DISCONNECT:
eliminatePlayer(data); break;
default: default:
Log::warn("GameEventsProtocol", "Unkown message type."); Log::warn("GameEventsProtocol", "Unkown message type.");
break; break;
@ -90,6 +86,22 @@ void GameEventsProtocol::collectedItem(Item* item, AbstractKart* kart)
delete ns; delete ns;
} // collectedItem } // collectedItem
// ----------------------------------------------------------------------------
void GameEventsProtocol::eliminatePlayer(const NetworkString &data)
{
assert(NetworkConfig::get()->isClient());
if (data.size() < 1)
{
Log::warn("GameEventsProtocol", "eliminatePlayer: Too short message.");
}
int kartid = data.getUInt8();
World::getWorld()->eliminateKart(kartid, false/*notify_of_elimination*/);
World::getWorld()->getKart(kartid)->setPosition(
World::getWorld()->getCurrentNumKarts() + 1);
World::getWorld()->getKart(kartid)->finishedRace(
World::getWorld()->getTime());
} // eliminatePlayer
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Called on the client when an itemCollected message is received. /** Called on the client when an itemCollected message is received.
*/ */

View File

@ -9,12 +9,15 @@ class Item;
class GameEventsProtocol : public Protocol class GameEventsProtocol : public Protocol
{ {
private: public:
enum GameEventType : uint8_t enum GameEventType : uint8_t
{ {
GE_ITEM_COLLECTED = 1, GE_ITEM_COLLECTED = 1,
GE_KART_FINISHED_RACE = 2 GE_KART_FINISHED_RACE = 2,
GE_PLAYER_DISCONNECT = 3
}; // GameEventType }; // GameEventType
private:
void eliminatePlayer(const NetworkString &ns);
public: public:
GameEventsProtocol(); GameEventsProtocol();
@ -31,7 +34,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE virtual bool notifyEventAsynchronous(Event* event) OVERRIDE
{ {
return false; return false;
} // notifyEventAsynchronous } // notifyEventAsynchronous