From c5510ee595709001835c835fffbdb31c7ca4b5ba Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Thu, 12 Mar 2020 00:06:45 +0100 Subject: [PATCH] Fixed crash related to singleplayer games. (see #75) --- client/source/network/Client.cpp | 6 +++++- client/source/network/Client.hpp | 2 ++ client/source/states/GameState.cpp | 22 +++++++++------------ client/source/states/GameState.hpp | 9 +++++++-- client/source/states/ServerConnectState.cpp | 4 +++- client/source/states/TitleScreenState.cpp | 7 +++++-- common/source/network/Network.hpp | 2 +- server/source/network/Server.cpp | 2 +- 8 files changed, 33 insertions(+), 21 deletions(-) diff --git a/client/source/network/Client.cpp b/client/source/network/Client.cpp index 9bbfbb6cf..7b1b40384 100644 --- a/client/source/network/Client.cpp +++ b/client/source/network/Client.cpp @@ -54,9 +54,13 @@ void Client::connect(sf::IpAddress serverAddress, u16 serverPort) { if (command == Network::Command::ClientRefused) throw EXCEPTION("Server error: Connection refused. Server probably reached max player amount."); + bool isSingleplayer; if (command != Network::Command::ClientOk) throw EXCEPTION("Network error: Expected 'ClientOk' packet."); - answer >> m_id; + + answer >> m_id >> isSingleplayer; + if (m_isSingleplayer != isSingleplayer) + throw EXCEPTION("Client error: The server is not valid"); m_tcpSocket->setBlocking(false); m_socket.setBlocking(false); diff --git a/client/source/network/Client.hpp b/client/source/network/Client.hpp index 1c085a2b6..31e2a07e3 100644 --- a/client/source/network/Client.hpp +++ b/client/source/network/Client.hpp @@ -51,6 +51,7 @@ class Client { void update(); void setCommandCallback(Network::Command command, const CommandCallback &callback) { m_commands[command] = callback; } + void setSingleplayer(bool isSingleplayer) { m_isSingleplayer = isSingleplayer; } bool isConnected() const { return m_isConnected; } @@ -58,6 +59,7 @@ class Client { private: bool m_isConnected = false; + bool m_isSingleplayer = false; u16 m_id; diff --git a/client/source/states/GameState.cpp b/client/source/states/GameState.cpp index 8c22c893c..4c3b2da56 100644 --- a/client/source/states/GameState.cpp +++ b/client/source/states/GameState.cpp @@ -45,31 +45,27 @@ #include "Registry.hpp" #include "TextureAtlas.hpp" -GameState::GameState(const std::string &host, int port) +GameState::GameState() : m_textureAtlas(gk::ResourceHandler::getInstance().get("atlas-blocks")) { - // Set clear color to skyblue - glClearColor(0.196078, 0.6, 0.8, 1.0); - - m_camera.setAspectRatio((float)Config::screenWidth / Config::screenHeight); - - initShaders(); - gk::Mouse::setCursorVisible(false); gk::Mouse::setCursorGrabbed(true); - // m_playerBoxes.emplace(0, PlayerBox{}); - // m_playerBoxes.at(0).setPosition(0, 22, 35); - - m_client.connect(host, port); + initShaders(); m_clientCommandHandler.setupCallbacks(); + m_camera.setAspectRatio((float)Config::screenWidth / Config::screenHeight); + m_world.setClient(m_clientCommandHandler); - m_player.setClientID(m_client.id()); m_world.setCamera(m_player.camera()); } +void GameState::connect(const std::string &host, int port) { + m_client.connect(host, port); + m_player.setClientID(m_client.id()); +} + void GameState::onEvent(const SDL_Event &event) { if (event.type == SDL_QUIT) { m_client.disconnect(); diff --git a/client/source/states/GameState.hpp b/client/source/states/GameState.hpp index 5f89980b5..2edeecd8e 100644 --- a/client/source/states/GameState.hpp +++ b/client/source/states/GameState.hpp @@ -45,7 +45,9 @@ class TextureAtlas; class GameState : public gk::ApplicationState { public: - GameState(const std::string &host, int port); + GameState(); + + void connect(const std::string &host, int port); void onEvent(const SDL_Event &event) override; @@ -56,7 +58,10 @@ class GameState : public gk::ApplicationState { ClientCommandHandler &clientCommandHandler() { return m_clientCommandHandler; } TextureAtlas &textureAtlas() { return m_textureAtlas; } - void setSingleplayer(bool isSingleplayer) { m_clientCommandHandler.setSingleplayer(isSingleplayer); } + void setSingleplayer(bool isSingleplayer) { + m_clientCommandHandler.setSingleplayer(isSingleplayer); + m_client.setSingleplayer(isSingleplayer); + } private: void initShaders(); diff --git a/client/source/states/ServerConnectState.cpp b/client/source/states/ServerConnectState.cpp index a06edf473..2283b5592 100644 --- a/client/source/states/ServerConnectState.cpp +++ b/client/source/states/ServerConnectState.cpp @@ -56,7 +56,9 @@ ServerConnectState::ServerConnectState(gk::ApplicationState *parent) : Interface std::cerr << "Error: Invalid server address." << std::endl; } - auto &game = m_stateStack->push(host, port); + auto &game = m_stateStack->push(); + game.connect(host, port); + m_stateStack->push(game, true, this); }); diff --git a/client/source/states/TitleScreenState.cpp b/client/source/states/TitleScreenState.cpp index 749882b2e..951ee8ee7 100644 --- a/client/source/states/TitleScreenState.cpp +++ b/client/source/states/TitleScreenState.cpp @@ -93,14 +93,17 @@ void TitleScreenState::startSingleplayer(bool showLoadingState) { std::this_thread::sleep_for(std::chrono::milliseconds(200)); - auto &game = m_stateStack->push("localhost", m_port); + auto &game = m_stateStack->push(); game.setSingleplayer(true); + game.connect("localhost", m_port); m_stateStack->push(game, showLoadingState, this); } void TitleScreenState::startMultiplayer(const std::string &host) { - auto &game = m_stateStack->push(host, m_port); + auto &game = m_stateStack->push(); + game.connect(host, m_port); + m_stateStack->push(game, false, this); } diff --git a/common/source/network/Network.hpp b/common/source/network/Network.hpp index f57ec25ee..d64fba087 100644 --- a/common/source/network/Network.hpp +++ b/common/source/network/Network.hpp @@ -34,7 +34,7 @@ namespace Network { // Client commands ClientConnect = 0, // [NetworkCommand][u16 udp port] (from Client only) ClientDisconnect = 1, // [NetworkCommand] (from Client only) - ClientOk = 2, // [NetworkCommand][u16 client id] (from Server only) + ClientOk = 2, // [NetworkCommand][u16 client id][bool isSingleplayer] (from Server only) ClientRefused = 3, // [NetworkCommand] (from Server only) // Input commands diff --git a/server/source/network/Server.cpp b/server/source/network/Server.cpp index 4021a4050..12543596d 100644 --- a/server/source/network/Server.cpp +++ b/server/source/network/Server.cpp @@ -103,7 +103,7 @@ void Server::handleNewConnections() { m_selector.add(*client.tcpSocket); sf::Packet outPacket; - outPacket << Network::Command::ClientOk << client.id; + outPacket << Network::Command::ClientOk << client.id << m_isSingleplayer; client.tcpSocket->send(outPacket); // client.tcpSocket->setBlocking(false);