Skip to content

Commit

Permalink
[Network] 'ServerClosed' packet added. Fixed #106.
Browse files Browse the repository at this point in the history
  • Loading branch information
Unarelith committed May 26, 2020
1 parent 00b5ba8 commit f440525
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 32 deletions.
2 changes: 1 addition & 1 deletion external/gamekit
10 changes: 10 additions & 0 deletions source/client/network/Client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ class Client {

u16 id() const { return m_id; }

sf::IpAddress serverAddress() const { return m_serverAddress; }
u16 serverPort() const { return m_serverPort; }

// FIXME: This should move elsewhere, see command callback
// in ClientCommandHandler for ServerClosed
const std::string &texturePack() const { return m_texturePack; }
void setTexturePack(const std::string &texturePack) { m_texturePack = texturePack; }

private:
bool m_isConnected = false;
bool m_isSingleplayer = false;
Expand All @@ -83,6 +91,8 @@ class Client {
gk::Timer m_keyUpdateTimer;

std::unordered_map<Network::Command, CommandCallback> m_commands;

std::string m_texturePack;
};

#endif // CLIENT_HPP_
10 changes: 10 additions & 0 deletions source/client/network/ClientCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "ClientPlayer.hpp"
#include "ClientWorld.hpp"
#include "ClientCommandHandler.hpp"
#include "ConnectionErrorState.hpp"
#include "DrawableComponent.hpp"
#include "DrawableDef.hpp"
#include "LuaGUIState.hpp"
Expand Down Expand Up @@ -136,6 +137,15 @@ void ClientCommandHandler::setupCallbacks() {
m_playerBoxes.erase(it);
});

m_client.setCommandCallback(Network::Command::ServerClosed, [this](Network::Packet &packet) {
std::string message;
packet >> message;

gk::ApplicationStateStack::getInstance().pop();
gk::ApplicationStateStack::getInstance().pop();
gk::ApplicationStateStack::getInstance().push<ConnectionErrorState>(message, m_client.serverAddress().toString(), m_client.serverPort(), m_client.texturePack(), &gk::ApplicationStateStack::getInstance().top());
});

m_client.setCommandCallback(Network::Command::RegistryData, [this](Network::Packet &packet) {
// FIXME: This is a quick fix for concurrency between client and server in singleplayer
if (!m_isSingleplayer)
Expand Down
5 changes: 5 additions & 0 deletions source/client/states/ServerLoadingState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ void ServerLoadingState::update() {
}
}

void ServerLoadingState::setTexturePack(const std::string &texturePack) {
m_game.client().setTexturePack(texturePack);
m_texturePack = texturePack;
}

void ServerLoadingState::onServerOnlineEvent(const ServerOnlineEvent &event) {
m_isServerOnline = event.isOnline;
m_port = event.port;
Expand Down
2 changes: 1 addition & 1 deletion source/client/states/ServerLoadingState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ServerLoadingState : public InterfaceState {

void update() override;

void setTexturePack(const std::string &texturePack) { m_texturePack = texturePack; }
void setTexturePack(const std::string &texturePack);

private:
void onServerOnlineEvent(const ServerOnlineEvent &event);
Expand Down
2 changes: 2 additions & 0 deletions source/common/network/Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ std::string Network::commandToString(Network::Command command) {
{Network::Command::ClientOk, "ClientOk"},
{Network::Command::ClientRefused, "ClientRefused"},

{Network::Command::ServerClosed, "ServerClosed"},

{Network::Command::ChunkData, "ChunkData"},
{Network::Command::ChunkRequest, "ChunkRequest"},

Expand Down
49 changes: 26 additions & 23 deletions source/common/network/Network.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,40 +39,43 @@ namespace Network {
ClientOk = 0x02, // <TCP> [NetworkCommand][u16 client id][bool isSingleplayer] (from Server only)
ClientRefused = 0x03, // <TCP> [NetworkCommand] (from Server only)

// Server commands
ServerClosed = 0x04, // <TCP> [NetworkCommand][string message] (from Server only)

// Chunk commands
ChunkData = 0x04, // <TCP> [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only)
ChunkRequest = 0x05, // <TCP> [NetworkCommand][s32 cx, cy, cz] (from Client only)
ChunkData = 0x05, // <TCP> [NetworkCommand][s32 cx, cy, cz][u32...] (from Server only)
ChunkRequest = 0x06, // <TCP> [NetworkCommand][s32 cx, cy, cz] (from Client only)

// Player commands
PlayerPlaceBlock = 0x06, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Client only)
PlayerDigBlock = 0x07, // <TCP> [NetworkCommand][s32 x, y, z] (from Client only)
PlayerInvUpdate = 0x08, // <TCP> [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
PlayerPosUpdate = 0x09, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME
PlayerSpawn = 0x0a, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z] (from Server only)
PlayerInventory = 0x0b, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerCreativeWindow = 0x0c, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerChangeDimension = 0x0d, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][u16 dimension] (from Server only)
PlayerPlaceBlock = 0x07, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Client only)
PlayerDigBlock = 0x08, // <TCP> [NetworkCommand][s32 x, y, z] (from Client only)
PlayerInvUpdate = 0x09, // <TCP> [NetworkCommand][u16 client id][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
PlayerPosUpdate = 0x0a, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][bool isTeleportation] (both) // FIXME
PlayerSpawn = 0x0b, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z] (from Server only)
PlayerInventory = 0x0c, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerCreativeWindow = 0x0d, // <TCP> [NetworkCommand][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
PlayerChangeDimension = 0x0e, // <TCP> [NetworkCommand][u16 client id][s32 x, y, z][u16 dimension] (from Server only)

// Block commands
BlockUpdate = 0x0e, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Server only)
BlockActivated = 0x0f, // <TCP> [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
BlockGUIData = 0x10, // <TCP> [NetworkCommand][LuaGUIData data] (from Server only)
BlockInvUpdate = 0x11, // <TCP> [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
BlockDataUpdate = 0x12, // <TCP> [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME]
BlockUpdate = 0x0f, // <TCP> [NetworkCommand][s32 x, y, z][u32 block] (from Server only)
BlockActivated = 0x10, // <TCP> [NetworkCommand][s32 x, y, z][u16 screenWidth, screenHeight][u8 guiScale] (from Client only)
BlockGUIData = 0x11, // <TCP> [NetworkCommand][LuaGUIData data] (from Server only)
BlockInvUpdate = 0x12, // <TCP> [NetworkCommand][s32 x, y, z][[std::string item][u16 amount][u8 x, y]...] (both) [FIXME]
BlockDataUpdate = 0x13, // <TCP> [NetworkCommand][s32 x, y, z][u64 data] (both) [FIXME]

// Registry commands
RegistryData = 0x13, // <TCP> [NetworkCommand][Block block] (from Server only)
RegistryData = 0x14, // <TCP> [NetworkCommand][Block block] (from Server only)

// Chat commands
ChatMessage = 0x14, // <TCP> [NetworkCommand][u16 client id][std::string message] (both)
ChatMessage = 0x15, // <TCP> [NetworkCommand][u16 client id][std::string message] (both)

// Entity commands
EntitySpawn = 0x15, // <TCP> [NetworkCommand][u32 entity id] (from Server only)
EntityDespawn = 0x16, // <TCP> [NetworkCommand][u32 entity id] (from Server only)
EntityPosition = 0x17, // <TCP> [NetworkCommand][u32 entity id][double x, double y, double z] (from Server only)
EntityRotation = 0x18, // <TCP> [NetworkCommand][u32 entity id][float w, float x, float y, float z] (from Server only)
EntityAnimation = 0x19, // <TCP> [NetworkCommand][u32 entity id][AnimationComponent anim] (from Server only)
EntityDrawableDef = 0x1a, // <TCP> [NetworkCommand][u32 entity id][DrawableDef def] (from Server only)
EntitySpawn = 0x16, // <TCP> [NetworkCommand][u32 entity id] (from Server only)
EntityDespawn = 0x17, // <TCP> [NetworkCommand][u32 entity id] (from Server only)
EntityPosition = 0x18, // <TCP> [NetworkCommand][u32 entity id][double x, double y, double z] (from Server only)
EntityRotation = 0x19, // <TCP> [NetworkCommand][u32 entity id][float w, float x, float y, float z] (from Server only)
EntityAnimation = 0x1a, // <TCP> [NetworkCommand][u32 entity id][AnimationComponent anim] (from Server only)
EntityDrawableDef = 0x1b, // <TCP> [NetworkCommand][u32 entity id][DrawableDef def] (from Server only)
};

std::string commandToString(Command command);
Expand Down
23 changes: 20 additions & 3 deletions source/server/core/ServerApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,24 @@

namespace fs = ghc::filesystem;

static bool hasBeenInterrupted = false;

#ifdef SFML_SYSTEM_LINUX

#include <stdio.h>
#include <signal.h>

static void sigintHandler(int) {
signal(SIGINT, sigintHandler);
hasBeenInterrupted = true;
}

#endif // SFML_SYSTEM_LINUX

ServerApplication::ServerApplication(int argc, char **argv) : m_argumentParser(argc, argv) {
#ifdef SFML_SYSTEM_LINUX
signal(SIGINT, sigintHandler);
#endif
}

ServerApplication::ServerApplication(gk::EventHandler &eventHandler) {
Expand Down Expand Up @@ -97,7 +114,7 @@ int ServerApplication::run(bool isProtected) {

std::cerr << "Fatal error " << e.what() << std::endl;

// TODO: Send server offline event here
m_serverCommandHandler.sendServerClosed(std::string("Server error ") + e.what());

m_registry.clear();
m_worldController.clearEntities();
Expand All @@ -110,7 +127,7 @@ int ServerApplication::run(bool isProtected) {
mainLoop();
}

// TODO: Send server offline event here
m_serverCommandHandler.sendServerClosed("Server closed.");

m_registry.clear();
m_worldController.clearEntities();
Expand All @@ -129,7 +146,7 @@ void ServerApplication::update() {
}

void ServerApplication::mainLoop() {
while (m_server.isRunning()) {
while (!hasBeenInterrupted && m_server.isRunning()) {
m_server.handleGameEvents();

m_clock.updateGame([this] {
Expand Down
4 changes: 0 additions & 4 deletions source/server/core/ServerApplication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,6 @@ struct ServerOnlineEvent {
int port;
};

// TODO: Add server offline event to tell the clients that the server is closed
// The best way would be to create a dedicated state displaying the error message
// allowing to reconnect or to go back to title screen

class ServerApplication {
public:
ServerApplication(int argc = 0, char **argv = nullptr);
Expand Down
10 changes: 10 additions & 0 deletions source/server/network/ServerCommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@
#include "ServerCommandHandler.hpp"
#include "WorldController.hpp"

void ServerCommandHandler::sendServerClosed(const std::string &message, const ClientInfo *client) const {
Network::Packet packet;
packet << Network::Command::ServerClosed << message;

if (!client)
m_server.sendToAllClients(packet);
else
client->tcpSocket->send(packet);
}

void ServerCommandHandler::sendBlockDataUpdate(s32 x, s32 y, s32 z, const BlockData *blockData, const ClientInfo *client) const {
Network::Packet packet;
packet << Network::Command::BlockDataUpdate << x << y << z
Expand Down
1 change: 1 addition & 0 deletions source/server/network/ServerCommandHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class ServerCommandHandler {
ServerCommandHandler(ScriptEngine &scriptEngine, Server &server, WorldController &worldController, PlayerList &players, Registry &registry)
: m_scriptEngine(scriptEngine), m_server(server), m_worldController(worldController), m_players(players), m_registry(registry) {}

void sendServerClosed(const std::string &message, const ClientInfo *client = nullptr) const;
void sendBlockDataUpdate(s32 x, s32 y, s32 z, const BlockData *blockData, const ClientInfo *client = nullptr) const;
void sendBlockInvUpdate(s32 x, s32 y, s32 z, const Inventory &inventory, const ClientInfo *client = nullptr) const;
void sendPlayerPosUpdate(u16 clientID, bool isTeleportation = false, const ClientInfo *client = nullptr) const;
Expand Down

0 comments on commit f440525

Please sign in to comment.