Reset server to accepting client state if no more connected players

This commit is contained in:
Benau 2018-04-19 00:38:08 +08:00
parent 99a25bb837
commit bd13f40584
4 changed files with 60 additions and 15 deletions

View File

@ -29,7 +29,8 @@
#include "network/game_setup.hpp"
#include "network/network_config.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/race_event_manager.hpp"
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"
@ -706,10 +707,16 @@ void ClientLobby::raceFinished(Event* event)
}
// stop race protocols
auto pm = ProtocolManager::lock();
assert(pm);
pm->findAndTerminate(PROTOCOL_CONTROLLER_EVENTS);
pm->findAndTerminate(PROTOCOL_GAME_EVENTS);
RaceEventManager::getInstance()->stop();
RaceEventManager::getInstance()->getProtocol()->requestTerminate();
GameProtocol::lock()->requestTerminate();
while (!RaceEventManager::getInstance()->protocolStopped())
StkTime::sleep(1);
while (!GameProtocol::emptyInstance())
StkTime::sleep(1);
m_received_server_result = true;
} // raceFinished

View File

@ -26,7 +26,8 @@
#include "network/network_config.hpp"
#include "network/network_player_profile.hpp"
#include "network/protocols/connect_to_peer.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/game_protocol.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "network/race_event_manager.hpp"
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"
@ -369,6 +370,22 @@ void ServerLobby::asynchronousUpdate()
*/
void ServerLobby::update(int ticks)
{
// Reset server to initial state if no more connected players
if (m_state.load() > ACCEPTING_CLIENTS &&
STKHost::get()->getPeerCount() == 0 &&
NetworkConfig::get()->getServerIdFile().empty())
{
std::lock_guard<std::mutex> lock(m_connection_mutex);
if (RaceEventManager::getInstance() &&
RaceEventManager::getInstance()->isRunning())
{
stopCurrentRace();
}
m_state = NetworkConfig::get()->isLAN() ?
ACCEPTING_CLIENTS : REGISTER_SELF_ADDRESS;
setup();
}
// Check if server owner has left
updateServerOwner();
if (m_game_setup)
@ -671,14 +688,8 @@ void ServerLobby::checkIncomingConnectionRequests()
static_cast<LinearWorld*>(World::getWorld())->getFastestLapTicks();
total->addUInt32(fastest_lap);
}
RaceResultGUI::getInstance()->backToLobby();
// notify the network world that it is stopped
RaceEventManager::getInstance()->stop();
// stop race protocols
auto pm = ProtocolManager::lock();
assert(pm);
pm->findAndTerminate(PROTOCOL_CONTROLLER_EVENTS);
pm->findAndTerminate(PROTOCOL_GAME_EVENTS);
stopCurrentRace();
// Set the delay before the server forces all clients to exit the race
// result screen and go back to the lobby
m_timeout.store((float)StkTime::getRealTime() + 15.0f);
@ -689,6 +700,27 @@ void ServerLobby::checkIncomingConnectionRequests()
} // checkRaceFinished
//-----------------------------------------------------------------------------
/** Stop any race currently in server, should only be called in main thread.
*/
void ServerLobby::stopCurrentRace()
{
// notify the network world that it is stopped
RaceEventManager::getInstance()->stop();
// stop race protocols before going back to lobby (end race)
RaceEventManager::getInstance()->getProtocol()->requestTerminate();
GameProtocol::lock()->requestTerminate();
while (!RaceEventManager::getInstance()->protocolStopped())
StkTime::sleep(1);
while (!GameProtocol::emptyInstance())
StkTime::sleep(1);
// This will go back to lobby in server (and exit the current race)
RaceResultGUI::getInstance()->backToLobby();
} // stopCurrentRace
//-----------------------------------------------------------------------------
/** Called when a client disconnects.
* \param event The disconnect event.

View File

@ -124,6 +124,7 @@ private:
}
}
std::tuple<std::string, uint8_t, bool> handleVote();
void stopCurrentRace();
public:
ServerLobby();

View File

@ -62,6 +62,11 @@ public:
/** Returns if this instance is in running state or not. */
bool isRunning() { return m_running; }
// ------------------------------------------------------------------------
std::shared_ptr<GameEventsProtocol> getProtocol() const
{ return m_game_events_protocol.lock(); }
// ------------------------------------------------------------------------
bool protocolStopped() const { return m_game_events_protocol.expired(); }
// ------------------------------------------------------------------------
bool isRaceOver();
// ------------------------------------------------------------------------
void collectedItem(Item *item, AbstractKart *kart);