From 61c78d6b79004ef87fedcfb297178690068be196 Mon Sep 17 00:00:00 2001 From: aurailus <100Toby1@gmail.com> Date: Mon, 4 Feb 2019 23:22:31 -0800 Subject: [PATCH] NetHandler class to abstract ENet C ugliness. * Remove some old Boost:Asio based network code. --- CMakeLists.txt | 1 - src/CMakeLists.txt | 4 - src/client/Client.cpp | 2 - src/client/gameworld/World.cpp | 10 +- src/client/network/ServerConnection.cpp | 43 +-------- src/client/network/ServerConnection.h | 7 +- src/generic/network/NetHandler.cpp | 120 ++++++++++++++++++++++++ src/generic/network/NetHandler.h | 46 +++++++++ src/generic/network/Packet.h | 1 - src/server/Server.cpp | 19 +--- src/server/Server.h | 7 +- src/server/ServerPlayer.cpp | 10 +- src/server/ServerPlayer.h | 12 +-- src/server/network/ConnMan.cpp | 111 ---------------------- src/server/network/ConnMan.h | 45 --------- src/server/network/ServerClient.h | 28 ------ 16 files changed, 191 insertions(+), 275 deletions(-) create mode 100644 src/generic/network/NetHandler.cpp create mode 100644 src/generic/network/NetHandler.h delete mode 100644 src/server/network/ConnMan.cpp delete mode 100644 src/server/network/ConnMan.h delete mode 100644 src/server/network/ServerClient.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f6aeff7..d2118562 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,6 @@ include_directories ( lib/stb_image lib/cute lib/sol - lib/asio-1.12.2/include lib/gzip-hpp-master/include lib/catch ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 47d4dc39..2b6eb449 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,8 +70,6 @@ set(ZEUS_SRC_FILES client/scene/MenuScene.h server/Server.cpp server/Server.h - server/network/ServerClient.cpp - server/network/ServerClient.h generic/network/Packet.cpp generic/network/Packet.h server/ServerPlayer.cpp @@ -80,8 +78,6 @@ set(ZEUS_SRC_FILES client/network/ServerConnection.h client/gameworld/WorldThreadDefs.cpp client/gameworld/WorldThreadDefs.h - server/network/ConnMan.cpp - server/network/ConnMan.h generic/gen/MapGen.cpp generic/gen/MapGen.h generic/network/NetHandler.cpp diff --git a/src/client/Client.cpp b/src/client/Client.cpp index c943cc33..e04ea179 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -8,8 +8,6 @@ #include "Client.h" -using asio::ip::udp; - Client::Client() = default; Client::Client(int width, int height) { diff --git a/src/client/gameworld/World.cpp b/src/client/gameworld/World.cpp index 8b2ca05e..4f2e6ece 100644 --- a/src/client/gameworld/World.cpp +++ b/src/client/gameworld/World.cpp @@ -37,8 +37,6 @@ void World::loadChunkPacket(Packet *p) { // b->deserialize(data); // // commitChunk(pos, b); - -std::cout << "me m e"<chunk = threadDef->mapGen->generate(data->pos); - //TODO: WARN: THIS IS DISABLING CLIENT-SIDE MAP GENERATION - auto b = new BlockChunk(new std::vector(4096)); - data->chunk = b; + data->chunk = threadDef->mapGen->generate(data->pos); +// TODO: WARN: THIS IS DISABLING CLIENT-SIDE MAP GENERATION +// auto b = new BlockChunk(new std::vector(4096)); +// data->chunk = b; data->done = true; diff --git a/src/client/network/ServerConnection.cpp b/src/client/network/ServerConnection.cpp index a87999cc..c7e5b841 100644 --- a/src/client/network/ServerConnection.cpp +++ b/src/client/network/ServerConnection.cpp @@ -7,52 +7,19 @@ ServerConnection::ServerConnection(std::string address, unsigned short port) { this->port = port; this->address = std::move(address); - - if (enet_initialize() != 0) { - fprintf(stderr, "[FATAL] Failed to Initialize ENet.\n"); - exit(EXIT_FAILURE); - } } void ServerConnection::init() { - client = enet_host_create(nullptr, 1, 2, 0, 0); + handler = NetHandler(address, port, 3, 3000); - if (client == nullptr) { - fprintf(stderr, "[FATAL] Failed to create ENet client.\n"); - return; - } - - ENetAddress server_address; - - enet_address_set_host(&server_address, address.c_str()); - server_address.port = port; - - server = enet_host_connect(client, &server_address, 2, 0); - - if (server == nullptr) { - fprintf(stderr, "No available peers to initiate a connection to.\n"); - return; - } - - ENetEvent event; - if (enet_host_service(client, &event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT) { - //Connected to the server successfully - printf("I connected to %x:%u.\n", - event.peer->address.host, - event.peer->address.port); - connected = true; - } - else { - //Connection failed - enet_peer_reset(server); - printf("Connection failed.\n"); - connected = false; + if (handler.getState() != NetHandler::CLIENT) { + exit(EXIT_FAILURE); } } void ServerConnection::update() { ENetEvent event; - while (enet_host_service(client, &event, 0) > 0) { + while (handler.update(&event)) { switch (event.type) { case ENET_EVENT_TYPE_CONNECT: @@ -98,8 +65,6 @@ void ServerConnection::update() { void ServerConnection::cleanup() { connected = false; - if (client != nullptr) enet_host_destroy(client); - enet_deinitialize(); } ServerConnection::~ServerConnection() { diff --git a/src/client/network/ServerConnection.h b/src/client/network/ServerConnection.h index 9156f33c..f8b9c4e1 100644 --- a/src/client/network/ServerConnection.h +++ b/src/client/network/ServerConnection.h @@ -8,10 +8,10 @@ #include #include #include -#include -#include "../../generic/network/Packet.h" #include "../engine/Timer.h" +#include "../../generic/network/Packet.h" +#include "../../generic/network/NetHandler.h" class ServerConnection { public: @@ -26,8 +26,7 @@ public: private: bool connected = false; - ENetHost* client; - ENetPeer* server; + NetHandler handler; int sendInterval = 0; int sendCount = 0; diff --git a/src/generic/network/NetHandler.cpp b/src/generic/network/NetHandler.cpp new file mode 100644 index 00000000..d96f20bc --- /dev/null +++ b/src/generic/network/NetHandler.cpp @@ -0,0 +1,120 @@ +// +// Created by aurailus on 03/02/19. +// + +#include "NetHandler.h" + +NetHandler::NetHandler() { + address = ENetAddress(); + host = nullptr; + peer = nullptr; +} + + +NetHandler::NetHandler(std::string host_address, unsigned short host_port) { + initClient(std::move(host_address), host_port, 3, 3); +} + +NetHandler::NetHandler(std::string host_address, unsigned short host_port, int attempts, int timeout) { + initClient(std::move(host_address), host_port, attempts, timeout); +} + +NetHandler::NetHandler(unsigned short port, short max_clients) { + initServer(port, max_clients); +} + +void NetHandler::initServer(unsigned short port, short max_clients) { + state = HOST; + + if (enet_initialize() != 0) { + fprintf(stderr, "[FATAL] Failed to Initialize ENet.\n"); + state = ERROR; + return; + } + + address.host = ENET_HOST_ANY; + address.port = port; + + host = enet_host_create(&address, (size_t)max_clients, CHANNELS, 0, 0); + peer = nullptr; + + if (host == nullptr) { + fprintf(stderr, "[FATAL] Failed to create ENet host.\n"); + state = ERROR; + return; + } + + printf("[INFO] Started server.\n"); +} + +void NetHandler::initClient(std::string host_address, unsigned short host_port, int attempts, int timeout) { + state = FAILED_CONNECT; + + if (enet_initialize() != 0) { + fprintf(stderr, "[FATAL] Failed to Initialize ENet.\n"); + state = ERROR; + return; + } + + host = enet_host_create(nullptr, 1, CHANNELS, 0, 0); + + if (host == nullptr) { + fprintf(stderr, "[FATAL] Failed to create ENet client.\n"); + state = ERROR; + return; + } + + enet_address_set_host(&address, host_address.c_str()); + address.port = host_port; + + int attempt = 0; + while (attempt++ < attempts) { + + peer = enet_host_connect(host, &address, CHANNELS, 0); + + if (peer == nullptr) { + fprintf(stderr, "[FATAL] Failed to find ENet peer.\n"); + state = ERROR; + return; + } + + ENetEvent event; + if (enet_host_service(host, &event, (enet_uint32)timeout) > 0 && event.type == ENET_EVENT_TYPE_CONNECT) { + printf("Connected to %x:%u.\n", event.peer->address.host, event.peer->address.port); + state = CLIENT; + break; + } else { + enet_peer_reset(peer); + if (attempt < attempts) { + printf("[INFO] Failed to connect to peer, retrying.\n"); + } + } + } + + if (state == FAILED_CONNECT) { + fprintf(stderr, "[FATAL] Failed to connect to peer.\n"); + return; + } +} + +bool NetHandler::update(ENetEvent *event) { + return enet_host_service(host, event, 0) > 0; +} + +int NetHandler::getState() { + return state; +} + +ENetPeer *NetHandler::getPeer() { + return peer; +} + +NetHandler::~NetHandler() { + //TODO: This causes a weird bug The destructor is called on initialization for some reason +// if (host != nullptr) { +// enet_host_destroy(host); +// } +// if (getState() != UNINITIALIZED) { +// enet_deinitialize(); +// } +} diff --git a/src/generic/network/NetHandler.h b/src/generic/network/NetHandler.h new file mode 100644 index 00000000..d3c5d3bd --- /dev/null +++ b/src/generic/network/NetHandler.h @@ -0,0 +1,46 @@ +// +// Created by aurailus on 03/02/19. +// + +#ifndef ZEUS_NETHANDLER_H +#define ZEUS_NETHANDLER_H + +#include +#include +#include + +class NetHandler { +public: + NetHandler(); + NetHandler(unsigned short port, short max_clients); + NetHandler(std::string host_address, unsigned short host_port); + NetHandler(std::string host_address, unsigned short host_port, int connection_attempts, int connection_timeout); + + int getState(); + ENetPeer* getPeer(); + bool update(ENetEvent* event); + + ~NetHandler(); +private: + void initServer(unsigned short port, short max_clients); + void initClient(std::string host_address, unsigned short host_port, int connection_attempts, int connection_timeout); + + int state = UNINITIALIZED; + + ENetPeer* peer; + ENetHost* host; + + ENetAddress address; + +public: + /*Definitions*/ + const static int UNINITIALIZED = 0; + const static int FAILED_CONNECT = 1; + const static int ERROR = 2; + const static int CLIENT = 3; + const static int HOST = 4; + + const static int CHANNELS = 2; +}; + +#endif //ZEUS_NETHANDLER_H diff --git a/src/generic/network/Packet.h b/src/generic/network/Packet.h index 044816e4..7eca2301 100644 --- a/src/generic/network/Packet.h +++ b/src/generic/network/Packet.h @@ -7,7 +7,6 @@ #include #include -#include #include class Packet { diff --git a/src/server/Server.cpp b/src/server/Server.cpp index e33171a6..f9d73df2 100644 --- a/src/server/Server.cpp +++ b/src/server/Server.cpp @@ -9,23 +9,10 @@ Server::Server() = default; Server::Server(unsigned short port) { this->port = port; - - address.host = ENET_HOST_ANY; - address.port = port; - - if (enet_initialize() != 0) { - fprintf(stderr, "[FATAL] Failed to Initialize ENet.\n"); - exit(EXIT_FAILURE); - } } void Server::init() { - server = enet_host_create(&address, 32, 2, 0, 0); - - if (server == nullptr) { - fprintf(stderr, "[FATAL] Failed to create ENet host.\n"); - exit(EXIT_FAILURE); - } + handler = NetHandler(port, 32); while (alive) update(); } @@ -34,7 +21,7 @@ void Server::update() { Timer loop(""); ENetEvent event; - while (enet_host_service(server, &event, 0) > 0 && loop.elapsedNs() < 15L*1000000L) { + while (handler.update(&event) && loop.elapsedNs() < 15L*1000000L) { switch (event.type) { case ENET_EVENT_TYPE_CONNECT: printf("A new client connected from %x:%u.\n", @@ -70,8 +57,6 @@ void Server::update() { void Server::cleanup() { alive = false; - if (server != nullptr) enet_host_destroy(server); - enet_deinitialize(); } Server::~Server() { diff --git a/src/server/Server.h b/src/server/Server.h index ee1fc6b4..31d04639 100644 --- a/src/server/Server.h +++ b/src/server/Server.h @@ -8,13 +8,11 @@ #include #include #include -#include #include "ServerPlayer.h" -#include "network/ConnMan.h" -#include "network/ServerClient.h" #include "../generic/network/Packet.h" #include "../client/engine/Timer.h" +#include "../generic/network/NetHandler.h" class Server { public: @@ -29,8 +27,7 @@ public: private: bool alive = true; - ENetAddress address; - ENetHost* server; + NetHandler handler; unsigned short port; }; diff --git a/src/server/ServerPlayer.cpp b/src/server/ServerPlayer.cpp index ec7741c3..0afba9c6 100644 --- a/src/server/ServerPlayer.cpp +++ b/src/server/ServerPlayer.cpp @@ -5,10 +5,10 @@ #include "ServerPlayer.h" ServerPlayer::ServerPlayer() { - this->connection = nullptr; +// this->connection = nullptr; } -ServerPlayer::ServerPlayer(ServerClient *connection, glm::vec3 pos) { - this->pos = pos; - this->connection = connection; -} +//ServerPlayer::ServerPlayer(ServerClient *connection, glm::vec3 pos) { +// this->pos = pos; +// this->connection = connection; +//} diff --git a/src/server/ServerPlayer.h b/src/server/ServerPlayer.h index f394a852..43b615d9 100644 --- a/src/server/ServerPlayer.h +++ b/src/server/ServerPlayer.h @@ -7,20 +7,18 @@ #include -#include "network/ServerClient.h" +//#include "network/ServerClient.h" class ServerPlayer { public: ServerPlayer(); - ServerPlayer(ServerClient* connection, glm::vec3 pos); +// ServerPlayer(ServerClient* connection, glm::vec3 pos); - ServerClient* connection; +// ServerClient* connection; glm::vec3 pos = glm::vec3(0, 0, 0); - glm::vec3 lastSentPos = glm::vec3(0, 0, 0); - bool forceSendChunks = false; - - std::vector requestedChunks; +// glm::vec3 lastSentPos = glm::vec3(0, 0, 0); +// bool forceSendChunks = false; }; diff --git a/src/server/network/ConnMan.cpp b/src/server/network/ConnMan.cpp deleted file mode 100644 index 49f1f630..00000000 --- a/src/server/network/ConnMan.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// Created by aurailus on 22/01/19. -// - -#include "ConnMan.h" -#include "../../generic/blocks/BlockChunk.h" - -ConnMan::ConnMan() = default; - -void ConnMan::init(unsigned short port) { - server_socket = new asio::ip::udp::socket(io_context, udp::endpoint(udp::v4(), port)); -} - -void ConnMan::poll() { - while (server_socket->available() > 0) { - size_t pendingSize = server_socket->available(); - std::vector recv_buf((unsigned long)pendingSize); - - auto remote_endpoint = new udp::endpoint(); - server_socket->receive_from(asio::buffer(recv_buf, pendingSize), *remote_endpoint); - - if (recv_buf.size() > 4) { - auto packet = Packet::deserialize(recv_buf); - handlePacket(packet, remote_endpoint); - } - } -} - -void ConnMan::handlePacket(Packet* packet, udp::endpoint* endpoint) { - std::string uuid = createIdentifier(endpoint); - - if (!clients.count(uuid)) { - if (packet->type == Packet::HANDSHAKE) { - - auto client = addClient(uuid, endpoint); - - Packet p(Packet::HANDSHAKE); - send(&p, client); - } - } - else if (!clients[uuid]->authenticated) { - if (packet->type == Packet::AUTHENTICATE) { - int strLen = Packet::decodeInt(&packet->data[0]); - int offset = 4; - - std::string token(packet->data.begin() + offset, packet->data.begin() + offset + strLen); - - //At some point there needs to be validation here with a centralized server, but for now - //we just assume that the information is some sort of token and move on. - - offset = offset + strLen; - strLen = Packet::decodeInt(&packet->data[offset]); - offset += 4; - - std::string username(packet->data.begin() + offset, packet->data.begin() + offset + strLen); - clients[uuid]->authenticated = true; - addPlayer(clients[uuid], username); - } - } - else { - //TODO: Push to the packet vector - } -} - -ServerClient* ConnMan::addClient(std::string uuid, udp::endpoint* endpoint) { - printf("[INFO] Handshake recieved from %s.\n", uuid.c_str()); - - auto client = new ServerClient(endpoint, uuid); - clients.insert(std::pair(uuid, client)); - return client; -} - -void ConnMan::addPlayer(ServerClient* client, std::string username) { - printf("[INFO] User %s has connected with IP %s.\n", username.c_str(), client->uuid.c_str()); - - auto player = new ServerPlayer(client, glm::vec3(0, 64, 0)); - client->player = player; - player->forceSendChunks = true; - players.insert(std::pair(username, player)); - - Packet p(Packet::PLAYERINFO); - - p.addFloat(player->pos.x); - p.addFloat(player->pos.y); - p.addFloat(player->pos.z); - - send(&p, client); -} - -//Create a IP + Port combo that can be used as a UUID for an endpoint. -std::string ConnMan::createIdentifier(udp::endpoint *endpoint) { - return endpoint->address().to_string() + ":" + std::to_string(endpoint->port()); -} - -void ConnMan::send(Packet *p, ServerClient* client) { - send(p, client->endpoint); -} - -void ConnMan::send(Packet *p, udp::endpoint* endpoint) { - auto data = p->serialize(); - server_socket->send_to(asio::buffer(data, data.size()), *endpoint); - std::cout << "sent" << std::endl; -} - -std::map* ConnMan::getPlayersMap() { - return &players; -} - -ConnMan::~ConnMan() { - delete server_socket; -} diff --git a/src/server/network/ConnMan.h b/src/server/network/ConnMan.h deleted file mode 100644 index 51e9f902..00000000 --- a/src/server/network/ConnMan.h +++ /dev/null @@ -1,45 +0,0 @@ -// -// Created by aurailus on 22/01/19. -// - -#ifndef ZEUS_CONNMAN_H -#define ZEUS_CONNMAN_H - -#include -#include "ServerClient.h" -#include "../ServerPlayer.h" -#include "../../generic/network/Packet.h" - -using asio::ip::udp; - -class ConnMan { -public: - ConnMan(); - - void init(unsigned short port); - void poll(); - void send(Packet* p, ServerClient* connection); - void send(Packet* p, udp::endpoint* endpoint); - - std::map* getPlayersMap(); - - ~ConnMan(); -private: - void handlePacket(Packet* packet, udp::endpoint* endpoint); - std::string createIdentifier(udp::endpoint *endpoint); - - ServerClient* addClient(std::string uuid, udp::endpoint* endpoint); - void addPlayer(ServerClient* client, std::string username); - - std::map clients; - std::map players; - - -// std::vector> packets; - - asio::io_context io_context; - udp::socket* server_socket; -}; - - -#endif //ZEUS_CONNMAN_H diff --git a/src/server/network/ServerClient.h b/src/server/network/ServerClient.h deleted file mode 100644 index a7927b92..00000000 --- a/src/server/network/ServerClient.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// Created by aurailus on 10/01/19. -// - -#ifndef ZEUS_CLIENTCONNECTION_H -#define ZEUS_CLIENTCONNECTION_H - -#include - -class ServerPlayer; - -class ServerClient { -public: - ServerClient(); - ServerClient(asio::ip::udp::endpoint* endpoint, std::string uuid); - - ServerPlayer* player; - - std::string uuid; - bool authenticated; - - asio::ip::udp::endpoint* endpoint; - - ~ServerClient(); -}; - - -#endif //ZEUS_CLIENTCONNECTION_H