From 4e2b843f713ec3ceb2cb062b8507e98910a6c08a Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 16 Jan 2019 13:43:26 +0800 Subject: [PATCH] Allow going back to lobby in selecting karts or tracks phase It allows player to be spectator later --- src/network/protocols/server_lobby.cpp | 40 +++++++++++++++++-- src/network/protocols/server_lobby.hpp | 3 +- .../online/network_kart_selection.cpp | 31 ++++++++++---- .../online/network_kart_selection.hpp | 1 + 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index 54b6d2b68..2be860f93 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -303,7 +303,7 @@ bool ServerLobby::notifyEvent(Event* event) case LE_LIVE_JOIN: liveJoinRequest(event); break; case LE_CLIENT_LOADED_WORLD: finishedLoadingLiveJoinClient(event); break; case LE_KART_INFO: handleKartInfo(event); break; - case LE_CLIENT_BACK_LOBBY: clientWantsToBackLobby(event); break; + case LE_CLIENT_BACK_LOBBY: clientInGameWantsToBackLobby(event); break; default: Log::error("ServerLobby", "Unknown message type %d - ignored.", message_type); break; @@ -409,6 +409,8 @@ bool ServerLobby::notifyEventAsynchronous(Event* event) case LE_CHAT: handleChat(event); break; case LE_CONFIG_SERVER: handleServerConfiguration(event); break; case LE_CHANGE_HANDICAP: changeHandicap(event); break; + case LE_CLIENT_BACK_LOBBY: + clientSelectingAssetsWantsToBackLobby(event); break; default: break; } // switch } // if (event->getType() == EVENT_TYPE_MESSAGE) @@ -3466,7 +3468,7 @@ void ServerLobby::handleKartInfo(Event* event) /** Client if currently in-game (including spectator) wants to go back to * lobby. */ -void ServerLobby::clientWantsToBackLobby(Event* event) +void ServerLobby::clientInGameWantsToBackLobby(Event* event) { World* w = World::getWorld(); std::shared_ptr peer = event->getPeerSP(); @@ -3513,4 +3515,36 @@ void ServerLobby::clientWantsToBackLobby(Event* event) m_game_setup->addServerInfo(server_info); peer->sendPacket(server_info, /*reliable*/true); delete server_info; -} // clientWantsToBackLobby +} // clientInGameWantsToBackLobby + +//----------------------------------------------------------------------------- +/** Client if currently select assets wants to go back to lobby. + */ +void ServerLobby::clientSelectingAssetsWantsToBackLobby(Event* event) +{ + std::shared_ptr peer = event->getPeerSP(); + + if (m_state.load() != SELECTING || peer->isWaitingForGame()) + { + Log::warn("ServerLobby", + "%s try to leave selecting assets at wrong time.", + peer->getAddress().toString().c_str()); + return; + } + + m_peers_ready.erase(peer); + peer->setWaitingForGame(true); + + NetworkString* reset = getNetworkString(2); + reset->setSynchronous(true); + reset->addUInt8(LE_BACK_LOBBY).addUInt8(BLR_NONE); + 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; +} // clientSelectingAssetsWantsToBackLobby diff --git a/src/network/protocols/server_lobby.hpp b/src/network/protocols/server_lobby.hpp index 23cc2b555..ae8c10db2 100644 --- a/src/network/protocols/server_lobby.hpp +++ b/src/network/protocols/server_lobby.hpp @@ -286,7 +286,8 @@ private: int getReservedId(std::shared_ptr& p, unsigned local_id) const; void handleKartInfo(Event* event); - void clientWantsToBackLobby(Event* event); + void clientInGameWantsToBackLobby(Event* event); + void clientSelectingAssetsWantsToBackLobby(Event* event); public: ServerLobby(); virtual ~ServerLobby(); diff --git a/src/states_screens/online/network_kart_selection.cpp b/src/states_screens/online/network_kart_selection.cpp index 749a4678c..1654ae0de 100644 --- a/src/states_screens/online/network_kart_selection.cpp +++ b/src/states_screens/online/network_kart_selection.cpp @@ -45,10 +45,6 @@ void NetworkKartSelectionScreen::init() updateProgressBarText(); } - // change the back button image (because it makes the game quit) - IconButtonWidget* back_button = getWidget("back"); - back_button->setImage("gui/icons/main_quit.png"); - DynamicRibbonWidget* w = getWidget("karts"); assert(w != NULL); for (auto& p : NetworkConfig::get()->getNetworkPlayers()) @@ -66,6 +62,7 @@ void NetworkKartSelectionScreen::init() w->setSelection(0, 0, true); } } + m_exit_timeout = std::numeric_limits::max(); } // init // ---------------------------------------------------------------------------- @@ -74,6 +71,16 @@ void NetworkKartSelectionScreen::init() */ void NetworkKartSelectionScreen::onUpdate(float dt) { + if (StkTime::getRealTimeMs() > m_exit_timeout) + { + // Reset the screen to networking menu if failed to back to lobby + STKHost::get()->shutdown(); + StateManager::get()->resetAndSetStack( + NetworkConfig::get()->getResetScreens().data()); + NetworkConfig::get()->unsetNetworking(); + return; + } + KartSelectionScreen::onUpdate(dt); updateProgressBarText(); } // onUpdate @@ -131,9 +138,19 @@ void NetworkKartSelectionScreen::allPlayersDone() // ---------------------------------------------------------------------------- bool NetworkKartSelectionScreen::onEscapePressed() { - // then remove the lobby screen (you left the server) - StateManager::get()->popMenu(); - STKHost::get()->shutdown(); + if (!m_live_join) + { + if (m_exit_timeout == std::numeric_limits::max()) + { + // Send go back lobby event to server with an exit timeout, so if + // server doesn't react in time we exit the server + m_exit_timeout = StkTime::getRealTimeMs() + 5000; + NetworkString back(PROTOCOL_LOBBY_ROOM); + back.addUInt8(LobbyProtocol::LE_CLIENT_BACK_LOBBY); + STKHost::get()->sendToServer(&back, true); + } + return false; + } return true; // remove the screen } // onEscapePressed diff --git a/src/states_screens/online/network_kart_selection.hpp b/src/states_screens/online/network_kart_selection.hpp index c728accd3..c667e8782 100644 --- a/src/states_screens/online/network_kart_selection.hpp +++ b/src/states_screens/online/network_kart_selection.hpp @@ -40,6 +40,7 @@ private: bool m_live_join; + uint64_t m_exit_timeout; protected: // ------------------------------------------------------------------------ NetworkKartSelectionScreen()