Reset graphical client server if its owner quited the game

This commit is contained in:
Benau 2020-02-28 19:52:07 +08:00
parent 97ad138763
commit 4322f47413
5 changed files with 65 additions and 2 deletions

View File

@ -47,6 +47,7 @@
#include "network/protocols/connect_to_server.hpp"
#include "network/protocols/game_protocol.hpp"
#include "network/protocols/game_events_protocol.hpp"
#include "network/protocols/server_lobby.hpp"
#include "network/protocol_manager.hpp"
#include "network/race_event_manager.hpp"
#include "network/server.hpp"
@ -622,7 +623,11 @@ void ClientLobby::connectionAccepted(Event* event)
MessageQueue::add(MessageQueue::MT_GENERIC, msg);
}
STKHost::get()->setMyHostId(data.getUInt32());
uint32_t host_id = data.getUInt32();
STKHost::get()->setMyHostId(host_id);
if (auto sl = LobbyProtocol::getByType<ServerLobby>(PT_CHILD))
sl->setClientServerHostId(host_id);
assert(!NetworkConfig::get()->isAddingNetworkPlayers());
uint32_t server_version = data.getUInt32();
NetworkConfig::get()->setJoinedServerVersion(server_version);
@ -1182,6 +1187,12 @@ void ClientLobby::backToLobby(Event *event)
// I18N: Error message shown if only 1 player remains in network
msg = _("Only 1 player remaining, returning to lobby.");
break;
case BLR_SERVER_ONWER_QUITED_THE_GAME:
// I18N: Error message shown when all players will go back to lobby
// when server owner quited the game
if (!STKHost::get()->isClientServer())
msg = _("Server owner quited the game.");
break;
default:
break;
}

View File

@ -185,6 +185,7 @@ public:
{ return m_ranking_changes; }
void handleClientCommand(const std::string& cmd);
void updateAssetsToServer();
ClientState getCurrentState() const { return m_state.load(); }
};
#endif // CLIENT_LOBBY_HPP

View File

@ -98,7 +98,8 @@ public:
BLR_NONE = 0,
BLR_NO_GAME_FOR_LIVE_JOIN = 1,
BLR_NO_PLACE_FOR_LIVE_JOIN = 2,
BLR_ONE_PLAYER_IN_RANKED_MATCH = 3
BLR_ONE_PLAYER_IN_RANKED_MATCH = 3,
BLR_SERVER_ONWER_QUITED_THE_GAME = 4
};
protected:

View File

@ -170,6 +170,7 @@ sqlite3_extension_init(sqlite3* db, char** pzErrMsg,
*/
ServerLobby::ServerLobby() : LobbyProtocol()
{
m_client_server_host_id.store(0);
m_lobby_players.store(0);
std::vector<int> all_k =
kart_properties_manager->getKartsInGroup("standard");
@ -5063,6 +5064,37 @@ void ServerLobby::clientInGameWantsToBackLobby(Event* event)
return;
}
if (m_process_type == PT_CHILD &&
event->getPeer()->getHostId() == m_client_server_host_id.load())
{
// For child server the remaining client cannot go on player when the
// server owner quited the game (because the world will be deleted), so
// we reset all players
auto pm = ProtocolManager::lock();
if (RaceEventManager::get())
{
RaceEventManager::get()->stop();
pm->findAndTerminate(PROTOCOL_GAME_EVENTS);
}
auto gp = GameProtocol::lock();
if (gp)
{
auto lock = gp->acquireWorldDeletingMutex();
pm->findAndTerminate(PROTOCOL_CONTROLLER_EVENTS);
exitGameState();
}
else
exitGameState();
NetworkString* back_to_lobby = getNetworkString(2);
back_to_lobby->setSynchronous(true);
back_to_lobby->addUInt8(LE_BACK_LOBBY)
.addUInt8(BLR_SERVER_ONWER_QUITED_THE_GAME);
sendMessageToPeersInServer(back_to_lobby, /*reliable*/true);
delete back_to_lobby;
m_rs_state.store(RS_ASYNC_RESET);
return;
}
for (const int id : peer->getAvailableKartIDs())
{
RemoteKartInfo& rki = RaceManager::get()->getKartInfo(id);
@ -5116,6 +5148,21 @@ void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event)
return;
}
if (m_process_type == PT_CHILD &&
event->getPeer()->getHostId() == m_client_server_host_id.load())
{
NetworkString* back_to_lobby = getNetworkString(2);
back_to_lobby->setSynchronous(true);
back_to_lobby->addUInt8(LE_BACK_LOBBY)
.addUInt8(BLR_SERVER_ONWER_QUITED_THE_GAME);
sendMessageToPeersInServer(back_to_lobby, /*reliable*/true);
delete back_to_lobby;
resetVotingTime();
resetServer();
m_rs_state.store(RS_NONE);
return;
}
m_peers_ready.erase(peer);
peer->setWaitingForGame(true);
peer->setSpectator(false);

View File

@ -212,6 +212,8 @@ private:
std::atomic<uint32_t> m_server_id_online;
std::atomic<uint32_t> m_client_server_host_id;
std::atomic<int> m_difficulty;
std::atomic<int> m_game_mode;
@ -389,6 +391,7 @@ public:
bool isAIProfile(const std::shared_ptr<NetworkPlayerProfile>& npp) const
{ return m_ai_profiles.find(npp) != m_ai_profiles.end(); }
uint32_t getServerIdOnline() const { return m_server_id_online; }
void setClientServerHostId(uint32_t id) { m_client_server_host_id = id; }
}; // class ServerLobby
#endif // SERVER_LOBBY_HPP