diff --git a/source/client/network/Client.cpp b/source/client/network/Client.cpp index 6c8fc4aee..ea6488eb1 100644 --- a/source/client/network/Client.cpp +++ b/source/client/network/Client.cpp @@ -37,10 +37,10 @@ void Client::connect(sf::IpAddress serverAddress, u16 serverPort) { m_tcpSocket.reset(new sf::TcpSocket); if (serverAddress.toInteger() == 0 || m_tcpSocket->connect(serverAddress, serverPort, sf::seconds(5)) != sf::Socket::Done) - throw EXCEPTION("Network error: Unable to connect to server", serverAddress.toString() + ":" + std::to_string(serverPort)); + throw ClientConnectException("Network error: Unable to connect to server " + serverAddress.toString() + ":" + std::to_string(serverPort)); if (m_socket.bind(0) != sf::Socket::Done) - throw EXCEPTION("Network error: Bind failed"); + throw ClientConnectException("Network error: Bind failed"); sf::Packet packet; packet << Network::Command::ClientConnect << sf::IpAddress::getLocalAddress().toString() << m_socket.getLocalPort(); @@ -52,15 +52,15 @@ void Client::connect(sf::IpAddress serverAddress, u16 serverPort) { Network::Command command; answer >> command; if (command == Network::Command::ClientRefused) - throw EXCEPTION("Server error: Connection refused. Server probably reached max player amount."); + throw ClientConnectException("Server error: Connection refused. Server probably reached max player amount."); bool isSingleplayer; if (command != Network::Command::ClientOk) - throw EXCEPTION("Network error: Expected 'ClientOk' packet."); + throw ClientConnectException("Network error: Expected 'ClientOk' packet."); answer >> m_id >> isSingleplayer; if (m_isSingleplayer != isSingleplayer) - throw EXCEPTION("Client error: The server is not valid"); + throw ClientConnectException("Client error: The server is not valid"); m_tcpSocket->setBlocking(false); m_socket.setBlocking(false); diff --git a/source/client/network/Client.hpp b/source/client/network/Client.hpp index 5ccb5825a..9200b8a70 100644 --- a/source/client/network/Client.hpp +++ b/source/client/network/Client.hpp @@ -39,6 +39,19 @@ #include "Network.hpp" +class ClientConnectException { + public: + ClientConnectException(const std::string &str) + : m_str(str) {} + + virtual const char *what() const noexcept { + return m_str.c_str(); + } + + private: + std::string m_str; +}; + class Client { using CommandCallback = std::function; diff --git a/source/client/states/GameState.cpp b/source/client/states/GameState.cpp index a9146c703..2478b1abe 100644 --- a/source/client/states/GameState.cpp +++ b/source/client/states/GameState.cpp @@ -49,9 +49,6 @@ GameState::GameState() : m_textureAtlas(gk::ResourceHandler::getInstance().get("atlas-blocks")) { - gk::Mouse::setCursorVisible(false); - gk::Mouse::setCursorGrabbed(true); - initShaders(); m_clientCommandHandler.setupCallbacks(); @@ -69,6 +66,9 @@ void GameState::init() { void GameState::connect(const std::string &host, int port) { m_client.connect(host, port); m_player.setClientID(m_client.id()); + + gk::Mouse::setCursorVisible(false); + gk::Mouse::setCursorGrabbed(true); } void GameState::onEvent(const SDL_Event &event) { diff --git a/source/client/states/ServerConnectState.cpp b/source/client/states/ServerConnectState.cpp index 6b9628ba0..6869f678d 100644 --- a/source/client/states/ServerConnectState.cpp +++ b/source/client/states/ServerConnectState.cpp @@ -57,10 +57,25 @@ ServerConnectState::ServerConnectState(gk::ApplicationState *parent) : Interface } auto &game = m_stateStack->push(); - game.connect(host, port); - auto &serverLoadingState = m_stateStack->push(game, true, this); - serverLoadingState.setTexturePack(m_texturePack); + try { + game.connect(host, port); + + auto &serverLoadingState = m_stateStack->push(game, true, 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"); @@ -69,6 +84,9 @@ ServerConnectState::ServerConnectState(gk::ApplicationState *parent) : Interface m_cancelButton.setCallback([this](TextButton &) { m_stateStack->pop(); }); + + m_errorText.setColor(gk::Color::Red); + m_errorText.setScale(Config::guiScale, Config::guiScale); } void ServerConnectState::onEvent(const SDL_Event &event) { @@ -80,6 +98,11 @@ void ServerConnectState::onEvent(const SDL_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 + ); } if (!m_stateStack->empty() && &m_stateStack->top() == this) { @@ -104,6 +127,9 @@ 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); } } diff --git a/source/client/states/ServerConnectState.hpp b/source/client/states/ServerConnectState.hpp index 6edfc41b1..88f93a6ad 100644 --- a/source/client/states/ServerConnectState.hpp +++ b/source/client/states/ServerConnectState.hpp @@ -49,6 +49,8 @@ class ServerConnectState : public InterfaceState { TextButton m_connectButton; TextButton m_cancelButton; + Text m_errorText; + std::string m_texturePack; }; diff --git a/source/client/states/TitleScreenState.cpp b/source/client/states/TitleScreenState.cpp index beb364b06..f725a4b96 100644 --- a/source/client/states/TitleScreenState.cpp +++ b/source/client/states/TitleScreenState.cpp @@ -118,7 +118,12 @@ void TitleScreenState::startSingleplayer(bool showLoadingState) { void TitleScreenState::startMultiplayer(const std::string &host) { auto &game = m_stateStack->push(); - game.connect(host, m_port); + try { + game.connect(host, m_port); + } + catch (ClientConnectException &e) { + throw EXCEPTION(e.what()); + } auto &serverLoadingState = m_stateStack->push(game, false, this); serverLoadingState.setTexturePack(m_texturePack);