diff --git a/source/client/network/ClientCommandHandler.cpp b/source/client/network/ClientCommandHandler.cpp index 8562bd158..bd8d22475 100644 --- a/source/client/network/ClientCommandHandler.cpp +++ b/source/client/network/ClientCommandHandler.cpp @@ -174,9 +174,8 @@ void ClientCommandHandler::setupCallbacks() { std::string message; packet >> message; - gk::ApplicationStateStack::getInstance().pop(); - gk::ApplicationStateStack::getInstance().pop(); - gk::ApplicationStateStack::getInstance().push(message, m_client.serverAddress().toString(), m_client.serverPort(), m_client.texturePack(), &gk::ApplicationStateStack::getInstance().top()); + gk::ApplicationStateStack::getInstance().clear(); + gk::ApplicationStateStack::getInstance().push(message, m_client.serverAddress().toString(), m_client.serverPort(), m_client.texturePack(), nullptr); }); m_client.setCommandCallback(Network::Command::RegistryData, [this](Network::Packet &packet) { diff --git a/source/client/states/ConnectionErrorState.cpp b/source/client/states/ConnectionErrorState.cpp index 105812f26..014b758b4 100644 --- a/source/client/states/ConnectionErrorState.cpp +++ b/source/client/states/ConnectionErrorState.cpp @@ -25,13 +25,18 @@ * ===================================================================================== */ #include +#include #include "Config.hpp" #include "ConnectionErrorState.hpp" #include "GameState.hpp" #include "ServerLoadingState.hpp" +#include "TitleScreenState.hpp" ConnectionErrorState::ConnectionErrorState(const std::string &error, const std::string &host, u16 port, const std::string &texturePack, gk::ApplicationState *parent) : InterfaceState(parent) { + gk::Mouse::setCursorGrabbed(false); + gk::Mouse::setCursorVisible(true); + m_host = host; m_port = port; @@ -55,7 +60,13 @@ ConnectionErrorState::ConnectionErrorState(const std::string &error, const std:: m_cancelButton.setText("Cancel"); m_cancelButton.setScale(Config::guiScale, Config::guiScale); m_cancelButton.setCallback([this](TextButton &) { - m_stateStack->pop(); + if (m_stateStack->size() > 1) { + m_stateStack->pop(); + } + else { + m_stateStack->pop(); + m_stateStack->push(m_port).setTexturePack(m_texturePack); + } }); updateWidgetPosition(); @@ -83,12 +94,11 @@ void ConnectionErrorState::updateWidgetPosition() { } void ConnectionErrorState::draw(gk::RenderTarget &target, gk::RenderStates states) const { - if (m_parent) - target.draw(*m_parent, states); - if (&m_stateStack->top() == this) { prepareDraw(target, states); + target.draw(m_background, states); + target.draw(m_text, states); target.draw(m_reconnectButton, states); diff --git a/source/client/states/ConnectionErrorState.hpp b/source/client/states/ConnectionErrorState.hpp index 4dbaea2f1..3a2e1b495 100644 --- a/source/client/states/ConnectionErrorState.hpp +++ b/source/client/states/ConnectionErrorState.hpp @@ -50,6 +50,8 @@ class ConnectionErrorState : public InterfaceState { TextButton m_reconnectButton; TextButton m_cancelButton; + + gk::Image m_background{"texture-title_screen"}; }; #endif // CONNECTIONERRORSTATE_HPP_ diff --git a/source/server/core/ServerApplication.cpp b/source/server/core/ServerApplication.cpp index 14935a550..17dab2b0b 100644 --- a/source/server/core/ServerApplication.cpp +++ b/source/server/core/ServerApplication.cpp @@ -130,6 +130,8 @@ int ServerApplication::run(bool isProtected) { mainLoop(); } + gkInfo() << "Stopping server..."; + m_serverCommandHandler.sendServerClosed("Server closed."); m_registry.clear(); diff --git a/source/server/network/ChatCommandHandler.cpp b/source/server/network/ChatCommandHandler.cpp index 11555120e..340246fb2 100644 --- a/source/server/network/ChatCommandHandler.cpp +++ b/source/server/network/ChatCommandHandler.cpp @@ -46,6 +46,7 @@ void ChatCommandHandler::parseCommand(const std::string &str, ClientInfo &client {"tp", &ChatCommandHandler::teleportationCommand}, {"save", &ChatCommandHandler::saveCommand}, {"load", &ChatCommandHandler::loadCommand}, + {"stop", &ChatCommandHandler::stopCommand}, }; if (!command.empty()) { @@ -111,3 +112,8 @@ void ChatCommandHandler::loadCommand(const std::vector &command, Cl } } +void ChatCommandHandler::stopCommand(const std::vector &, ClientInfo &client) const { + m_server.sendChatMessage(0, "Stopping server...", &client); + m_server.stopServer(); +} + diff --git a/source/server/network/ChatCommandHandler.hpp b/source/server/network/ChatCommandHandler.hpp index ff41520b6..c5717d313 100644 --- a/source/server/network/ChatCommandHandler.hpp +++ b/source/server/network/ChatCommandHandler.hpp @@ -45,6 +45,7 @@ class ChatCommandHandler { void teleportationCommand(const std::vector &command, ClientInfo &client) const; void saveCommand(const std::vector &command, ClientInfo &client) const; void loadCommand(const std::vector &command, ClientInfo &client) const; + void stopCommand(const std::vector &command, ClientInfo &client) const; ServerCommandHandler &m_server; WorldController &m_worldController; diff --git a/source/server/network/ServerCommandHandler.cpp b/source/server/network/ServerCommandHandler.cpp index 4c85cdcf2..6f31eb236 100644 --- a/source/server/network/ServerCommandHandler.cpp +++ b/source/server/network/ServerCommandHandler.cpp @@ -416,6 +416,10 @@ inline ServerWorld &ServerCommandHandler::getWorldForClient(u16 clientID) { return m_worldController.getWorld(player->dimension()); } +void ServerCommandHandler::stopServer() const { + m_server.setRunning(false); +} + // Please update 'docs/lua-api-cpp.md' if you change this void ServerCommandHandler::initUsertype(sol::state &lua) { lua.new_usertype("ServerCommandHandler", diff --git a/source/server/network/ServerCommandHandler.hpp b/source/server/network/ServerCommandHandler.hpp index 99bbaf94f..e9491fc8b 100644 --- a/source/server/network/ServerCommandHandler.hpp +++ b/source/server/network/ServerCommandHandler.hpp @@ -76,6 +76,8 @@ class ServerCommandHandler { void setPlayerPosition(u16 clientID, s32 x, s32 y, s32 z); + void stopServer() const; + const Server &server() const { return m_server; } static void initUsertype(sol::state &lua); diff --git a/source/server/world/WorldController.cpp b/source/server/world/WorldController.cpp index 900d597b9..59ccb7204 100644 --- a/source/server/world/WorldController.cpp +++ b/source/server/world/WorldController.cpp @@ -48,7 +48,7 @@ void WorldController::update() { } void WorldController::load(const std::string &name) { - gkDebug() << ("Loading '" + name + "'...").c_str(); + gkInfo() << ("Loading '" + name + "'...").c_str(); std::ifstream file("saves/" + name + ".dat", std::ofstream::binary); @@ -69,7 +69,7 @@ void WorldController::load(const std::string &name) { unsigned int chunkCount; save >> chunkCount; - gkDebug() << "Loading dimension" << world.dimension().id() << "| Chunk count:" << chunkCount; + gkInfo() << "Loading dimension" << world.dimension().id() << "| Chunk count:" << chunkCount; for (unsigned int i = 0 ; i < chunkCount ; ++i) { int cx, cy, cz; @@ -96,11 +96,11 @@ void WorldController::load(const std::string &name) { } } - gkDebug() << "Loading done."; + gkInfo() << "Loading done."; } void WorldController::save(const std::string &name) { - gkDebug() << ("Saving '" + name + "'...").c_str(); + gkInfo() << ("Saving '" + name + "'...").c_str(); std::filesystem::create_directory("saves"); @@ -129,7 +129,7 @@ void WorldController::save(const std::string &name) { ++chunkCount; } - gkDebug() << "Saving dimension" << world.dimension().id() << "| Chunk count:" << chunkCount; + gkInfo() << "Saving dimension" << world.dimension().id() << "| Chunk count:" << chunkCount; save << chunkCount; save.append(chunks.getData(), chunks.getDataSize()); @@ -137,5 +137,5 @@ void WorldController::save(const std::string &name) { file.write((const char *)save.getData(), save.getDataSize()); - gkDebug() << "Saving done."; + gkInfo() << "Saving done."; }