From 732c2dd493ffe137e85d505e2aa79f4044349e8b Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Wed, 20 May 2020 20:45:05 +0200 Subject: [PATCH] [ConnectionErrorState] Added. --- source/client/states/ConnectionErrorState.cpp | 98 +++++++++++++++++++ source/client/states/ConnectionErrorState.hpp | 55 +++++++++++ source/client/states/ServerConnectState.cpp | 59 +++++------ source/client/states/ServerConnectState.hpp | 2 +- source/client/states/ServerLoadingState.cpp | 11 +-- 5 files changed, 186 insertions(+), 39 deletions(-) create mode 100644 source/client/states/ConnectionErrorState.cpp create mode 100644 source/client/states/ConnectionErrorState.hpp diff --git a/source/client/states/ConnectionErrorState.cpp b/source/client/states/ConnectionErrorState.cpp new file mode 100644 index 000000000..105812f26 --- /dev/null +++ b/source/client/states/ConnectionErrorState.cpp @@ -0,0 +1,98 @@ +/* + * ===================================================================================== + * + * OpenMiner + * + * Copyright (C) 2018-2020 Unarelith, Quentin Bazin + * Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md) + * + * This file is part of OpenMiner. + * + * OpenMiner is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * OpenMiner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with OpenMiner; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * ===================================================================================== + */ +#include + +#include "Config.hpp" +#include "ConnectionErrorState.hpp" +#include "GameState.hpp" +#include "ServerLoadingState.hpp" + +ConnectionErrorState::ConnectionErrorState(const std::string &error, const std::string &host, u16 port, const std::string &texturePack, gk::ApplicationState *parent) : InterfaceState(parent) { + m_host = host; + m_port = port; + + m_texturePack = texturePack; + + m_text.setText(error); + m_text.setColor(gk::Color::Red); + m_text.updateVertexBuffer(); + m_text.setScale(Config::guiScale * 1.5, Config::guiScale * 1.5); + + m_reconnectButton.setText("Reconnect"); + m_reconnectButton.setScale(Config::guiScale, Config::guiScale); + m_reconnectButton.setCallback([this](TextButton &) { + m_stateStack->pop(); + + auto &game = m_stateStack->push(); + auto &serverLoadingState = m_stateStack->push(game, true, m_host, m_port, m_parent); + serverLoadingState.setTexturePack(m_texturePack); + }); + + m_cancelButton.setText("Cancel"); + m_cancelButton.setScale(Config::guiScale, Config::guiScale); + m_cancelButton.setCallback([this](TextButton &) { + m_stateStack->pop(); + }); + + updateWidgetPosition(); +} + +void ConnectionErrorState::onEvent(const sf::Event &event) { + InterfaceState::onEvent(event); + + if (event.type == sf::Event::Resized) { + updateWidgetPosition(); + } + + if (!m_stateStack->empty() && &m_stateStack->top() == this) { + m_reconnectButton.onEvent(event); + m_cancelButton.onEvent(event); + } +} + +void ConnectionErrorState::updateWidgetPosition() { + m_text.setPosition(Config::screenWidth / 2 - m_text.getSize().x * Config::guiScale * 1.5 / 2, + Config::screenHeight / 2 - m_text.getSize().y * Config::guiScale * 1.5 / 2); + + m_reconnectButton.setPosition(Config::screenWidth / 2.0f - m_reconnectButton.getGlobalBounds().sizeX / 2.0f, Config::screenHeight - 340); + m_cancelButton.setPosition(Config::screenWidth / 2.0f - m_cancelButton.getGlobalBounds().sizeX / 2.0f, Config::screenHeight - 261); +} + +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_text, states); + + target.draw(m_reconnectButton, states); + target.draw(m_cancelButton, states); + } +} + diff --git a/source/client/states/ConnectionErrorState.hpp b/source/client/states/ConnectionErrorState.hpp new file mode 100644 index 000000000..4dbaea2f1 --- /dev/null +++ b/source/client/states/ConnectionErrorState.hpp @@ -0,0 +1,55 @@ +/* + * ===================================================================================== + * + * OpenMiner + * + * Copyright (C) 2018-2020 Unarelith, Quentin Bazin + * Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md) + * + * This file is part of OpenMiner. + * + * OpenMiner is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * OpenMiner is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with OpenMiner; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * ===================================================================================== + */ +#ifndef CONNECTIONERRORSTATE_HPP_ +#define CONNECTIONERRORSTATE_HPP_ + +#include "InterfaceState.hpp" +#include "TextButton.hpp" + +class ConnectionErrorState : public InterfaceState { + public: + ConnectionErrorState(const std::string &error, const std::string &host, u16 port, const std::string &texturePack, gk::ApplicationState *parent = nullptr); + + void onEvent(const sf::Event &event) override; + + private: + void updateWidgetPosition(); + + void draw(gk::RenderTarget &target, gk::RenderStates states) const override; + + std::string m_host; + u16 m_port; + + std::string m_texturePack; + + Text m_text; + + TextButton m_reconnectButton; + TextButton m_cancelButton; +}; + +#endif // CONNECTIONERRORSTATE_HPP_ diff --git a/source/client/states/ServerConnectState.cpp b/source/client/states/ServerConnectState.cpp index 8c976a238..2c76b1eba 100644 --- a/source/client/states/ServerConnectState.cpp +++ b/source/client/states/ServerConnectState.cpp @@ -47,35 +47,30 @@ ServerConnectState::ServerConnectState(gk::ApplicationState *parent) : Interface size_t sep = m_textInput.text().find_first_of(':'); std::string host = m_textInput.text().substr(0, sep); + bool isPortInvalid = false; int port = 0; - try { - port = std::stoi(m_textInput.text().substr(sep + 1)); + if (sep != std::string::npos) { + try { + port = std::stoi(m_textInput.text().substr(sep + 1)); + } + catch (const std::invalid_argument &e) { + isPortInvalid = true; + } } - catch (const std::invalid_argument &e) { - // TODO: Use m_errorText - gkError() << "Error: Invalid server address."; - } - - auto &game = m_stateStack->push(); - - // try { - // game.connect(host, port); + if (port == 0 || isPortInvalid) { + m_errorText.setText("Error: Invalid server address"); + m_errorText.updateVertexBuffer(); + m_errorText.setPosition( + Config::screenWidth / 2.0f - m_errorText.getSize().x * Config::guiScale / 2.0f, + Config::screenHeight / 2.0f - 30 * Config::guiScale + ); + } + else { + auto &game = m_stateStack->push(); auto &serverLoadingState = m_stateStack->push(game, true, host, port, this); serverLoadingState.setTexturePack(m_texturePack); - // } - // catch (ClientConnectException &e) { - // gkError() << e.what(); - // - // m_stateStack->pop(); - // - // m_errorText.setText(e.what()); - // m_errorText.updateVertexBuffer(); - // m_errorText.setPosition( - // Config::screenWidth / 2.0f - m_errorText.getSize().x * Config::guiScale / 2.0f, - // Config::screenHeight / 2.0f - 30 * Config::guiScale - // ); - // } + } }); m_cancelButton.setText("Cancel"); @@ -85,8 +80,8 @@ ServerConnectState::ServerConnectState(gk::ApplicationState *parent) : Interface m_stateStack->pop(); }); - // m_errorText.setColor(gk::Color::Red); - // m_errorText.setScale(Config::guiScale, Config::guiScale); + m_errorText.setColor(gk::Color::Red); + m_errorText.setScale(Config::guiScale, Config::guiScale); } void ServerConnectState::onEvent(const sf::Event &event) { @@ -99,10 +94,10 @@ void ServerConnectState::onEvent(const sf::Event &event) { m_connectButton.setPosition(Config::screenWidth / 2.0f - m_connectButton.getGlobalBounds().sizeX / 2, Config::screenHeight - 340); m_cancelButton.setPosition(Config::screenWidth / 2.0f - m_cancelButton.getGlobalBounds().sizeX / 2, Config::screenHeight - 261); - // m_errorText.setPosition( - // Config::screenWidth / 2.0f - m_errorText.getSize().x * Config::guiScale / 2.0f, - // Config::screenHeight / 2.0f - 30 * Config::guiScale - // ); + m_errorText.setPosition( + Config::screenWidth / 2.0f - m_errorText.getSize().x * Config::guiScale / 2.0f, + Config::screenHeight / 2.0f - 30 * Config::guiScale + ); } if (!m_stateStack->empty() && &m_stateStack->top() == this) { @@ -128,8 +123,8 @@ void ServerConnectState::draw(gk::RenderTarget &target, gk::RenderStates states) target.draw(m_connectButton, states); target.draw(m_cancelButton, states); - // if (!m_errorText.text().empty()) - // target.draw(m_errorText, states); + if (!m_errorText.text().empty()) + target.draw(m_errorText, states); } } diff --git a/source/client/states/ServerConnectState.hpp b/source/client/states/ServerConnectState.hpp index 579ddd706..94ade3686 100644 --- a/source/client/states/ServerConnectState.hpp +++ b/source/client/states/ServerConnectState.hpp @@ -49,7 +49,7 @@ class ServerConnectState : public InterfaceState { TextButton m_connectButton; TextButton m_cancelButton; - // Text m_errorText; + Text m_errorText; std::string m_texturePack; }; diff --git a/source/client/states/ServerLoadingState.cpp b/source/client/states/ServerLoadingState.cpp index fdeb3ea9a..2e89602fa 100644 --- a/source/client/states/ServerLoadingState.cpp +++ b/source/client/states/ServerLoadingState.cpp @@ -31,6 +31,7 @@ #include #include "Config.hpp" +#include "ConnectionErrorState.hpp" #include "GameState.hpp" #include "ServerLoadingState.hpp" #include "TextureAtlas.hpp" @@ -45,11 +46,11 @@ ServerLoadingState::ServerLoadingState(GameState &game, bool showLoadingState, c m_text.updateVertexBuffer(); m_text.setScale(Config::guiScale * 2, Config::guiScale * 2); + centerText(); + m_host = host; m_port = port; - centerText(); - // FIXME: SFML_RAW_MOUSE // gk::Mouse::setCursorVisible(true); // gk::Mouse::setCursorGrabbed(false); @@ -79,12 +80,10 @@ void ServerLoadingState::update() { m_isConnected = true; } catch (ClientConnectException &e) { - // TODO: Add a state to display this message instead of printing to the console - - gkError() << "Failed to connect to" << m_host + std::to_string(m_port) + ":" << e.what(); - m_stateStack->pop(); // GameState m_stateStack->pop(); // ServerLoadingState + + m_stateStack->push(e.what(), m_host, m_port, m_texturePack, m_parent); } }