Browse Source

Server without tests

Kajetan Johannes Hammerle 11 tháng trước cách đây
mục cha
commit
b5954456b8
2 tập tin đã thay đổi với 122 bổ sung116 xóa
  1. 16 22
      include/core/Network.h
  2. 106 94
      src/Network.c

+ 16 - 22
include/core/Network.h

@@ -54,7 +54,7 @@ bool coreClientStart(void);
 void coreClientStop(void);
 bool coreClientConnect(const char* server, CorePort port, int timeoutTicks);
 void coreClientDisconnect(int timeoutTicks);
-void coreClientSend(CoreOutPacket* p, CorePacketSendMode mode);
+void coreClientSend(const CoreOutPacket* p, CorePacketSendMode mode);
 void coreClientTick(void);
 void coreClientSetConnectHandler(CoreClientOnConnect oc);
 void coreClientSetDisconnectHandler(CoreClientOnDisconnect od);
@@ -63,27 +63,21 @@ void coreClientResetHandler(void);
 bool coreClientIsConnecting(void);
 bool coreClientIsConnected(void);
 
-/*namespace Server {
-    typedef uint16 Port;
-    typedef int Client;
-    typedef void (*OnConnect)(Client);
-    typedef void (*OnDisconnect)(Client);
-    typedef void (*OnPacket)(Client, InPacket&);
+typedef int CoreClient;
+typedef void (*CoreServerOnConnect)(CoreClient);
+typedef void (*CoreServerOnDisconnect)(CoreClient);
+typedef void (*CoreServerOnPacket)(CoreClient, CoreInPacket*);
 
-    Error start(Port port, int maxClients);
-    void stop();
-
-    void tick();
-
-    void send(const OutPacket& p, PacketSendMode mode);
-    void send(Client client, const OutPacket& p, PacketSendMode mode);
-
-    void disconnect(Client client);
-
-    void setConnectHandler(OnConnect oc);
-    void setDisconnectHandler(OnDisconnect od);
-    void setPacketHandler(OnPacket op);
-    void resetHandler();
-}*/
+bool coreServerStart(CorePort port, size_t maxClients);
+void coreServerStop(void);
+void coreServerTick(void);
+void coreServerSendAll(const CoreOutPacket* p, CorePacketSendMode mode);
+void coreServerSend(CoreClient client, const CoreOutPacket* p,
+                    CorePacketSendMode mode);
+void coreServerDisconnect(CoreClient client);
+void coreServerSetConnectHandler(CoreServerOnConnect oc);
+void coreServerSetDisconnectHandler(CoreServerOnDisconnect od);
+void coreServerSetPacketHandler(CoreServerOnPacket op);
+void coreServerResetHandler(void);
 
 #endif

+ 106 - 94
src/Network.c

@@ -1,6 +1,7 @@
 #include "core/Network.h"
 
 #define ENET_IMPLEMENTATION
+#include <core/HashMap.h>
 #include <core/Logger.h>
 #include <core/Utility.h>
 #include <enet.h>
@@ -220,7 +221,7 @@ bool coreClientStart(void) {
         CORE_LOG_WARNING("Client already started");
         return true;
     } else if(addENet()) {
-        CORE_LOG_WARNING("Client cannot initialize enet");
+        CORE_LOG_ERROR("Client cannot initialize enet");
         return true;
     }
     client.client = enet_host_create(nullptr, 1, 2, 0, 0);
@@ -241,8 +242,8 @@ void coreClientStop(void) {
     if(client.client != nullptr) {
         enet_host_destroy(client.client);
         client.client = nullptr;
-        removeENet();
     }
+    removeENet();
     client.connectTicks = 0;
     client.disconnectTicks = 0;
 }
@@ -280,7 +281,7 @@ void coreClientDisconnect(int timeoutTicks) {
     client.disconnectTimeoutTicks = timeoutTicks;
 }
 
-void coreClientSend(OutPacket* p, CorePacketSendMode mode) {
+void coreClientSend(const OutPacket* p, CorePacketSendMode mode) {
     if(client.client != nullptr || client.connection != nullptr ||
        client.connectTicks >= 0) {
         return;
@@ -361,162 +362,173 @@ bool coreClientIsConnected(void) {
     return client.connectTicks < 0;
 }
 
-/*static_assert(sizeof(enet_uint16) == sizeof(Server::Port),
-              "client port has wrong type");
+static void voidClientDummy(CoreClient) {
+}
 
-static ENetHost* server;
-static HashMap<Server::Client, ENetPeer*> clients;
-static Server::Client idCounter = 1;
-static Server::OnConnect onConnect = [](Server::Client) {};
-static Server::OnDisconnect onDisconnect = [](Server::Client) {};
-static Server::OnPacket onPacket = [](Server::Client, InPacket&) {};
+static void voidClientInPacketDummy(CoreClient, CoreInPacket*) {
+}
 
-Error Server::start(Port port, int maxClients) {
+typedef struct {
+    ENetHost* server;
+    CoreHashMap clients; // CoreClient -> ENetPeer*
+    CoreClient idCounter;
+    CoreServerOnConnect onConnect;
+    CoreServerOnDisconnect onDisconnect;
+    CoreServerOnPacket onPacket;
+} Server;
+
+static Server server = {
+    nullptr, {0}, 1, voidClientDummy, voidClientDummy, voidClientInPacketDummy};
+
+bool coreServerStart(CorePort port, size_t maxClients) {
     if(maxClients <= 0) {
-        return {"invalid max client amount"};
-    } else if(server != nullptr) {
-        return {"already started"};
-    } else if(ENet::add()) {
-        return {"cannot initialize enet"};
+        CORE_LOG_ERROR("Invalid max client amount");
+        return true;
+    } else if(server.server != nullptr) {
+        CORE_LOG_WARNING("Server already started");
+        return true;
+    } else if(addENet()) {
+        CORE_LOG_ERROR("Server cannot initialize enet");
+        return true;
     }
 
-    ENetAddress address;
-    memset(&address, 0, sizeof(ENetAddress));
-    address.host = ENET_HOST_ANY;
-    address.port = port;
-
-    server = enet_host_create(&address, static_cast<unsigned
-int>(maxClients), 3, 0, 0); if(server == nullptr) { ENet::remove(); return
-{"cannot create enet server host"};
+    ENetAddress address = {.host = ENET_HOST_ANY, .port = port};
+    server.server = enet_host_create(&address, maxClients, 3, 0, 0);
+    if(server.server == nullptr) {
+        coreServerStop();
+        CORE_LOG_ERROR("Cannot create enet server host");
+        return true;
     }
-    return {};
+    coreInitHashMap(&server.clients, sizeof(CoreClient), sizeof(ENetPeer*));
+    return false;
 }
 
-void Server::stop() {
-    if(server == nullptr) {
-        return;
-    }
-    for(ENetPeer* peer : clients.values()) {
-        enet_peer_reset(peer);
+void coreServerStop(void) {
+    if(server.server != nullptr) {
+        CoreHashMapIterator i;
+        coreInitHashMapIterator(&i, &server.clients);
+        while(coreHashMapHasNext(&i)) {
+            CoreHashMapNode* n = coreHashMapNext(&i);
+            enet_peer_reset(coreHashMapValue(n, ENetPeer*));
+        }
+        enet_host_destroy(server.server);
+        server.server = nullptr;
+        coreDestroyHashMap(&server.clients);
     }
-    enet_host_destroy(server);
-    server = nullptr;
-    ENet::remove();
+    removeENet();
 }
 
-static void writeId(ENetPeer* peer, Server::Client id) {
+static void writeId(ENetPeer* peer, CoreClient id) {
     static_assert(sizeof(peer->data) >= sizeof(id),
                   "private data not big enough for id");
     memcpy(&(peer->data), &id, sizeof(id));
 }
 
-static Server::Client getId(ENetPeer* peer) {
-    Server::Client id = -1;
+static CoreClient getId(ENetPeer* peer) {
+    CoreClient id = -1;
     memcpy(&id, &(peer->data), sizeof(id));
     return id;
 }
 
-static void handleConnect(ENetEvent& e) {
-    Server::Client id = idCounter++;
-    if(clients.tryEmplace(id, e.peer)) {
-        LOG_WARNING("id is connected twice");
+static void handleConnect(ENetEvent* e) {
+    CoreClient id = server.idCounter++;
+    if(coreHashMapContains(&server.clients, CoreClient, id)) {
+        CORE_LOG_WARNING("Id is connected twice");
         return;
     }
-    writeId(e.peer, id);
-    onConnect(id);
+    coreHashMapPut(&server.clients, CoreClient, id, ENetPeer*, e->peer);
+    writeId(e->peer, id);
+    server.onConnect(id);
 }
 
-static void handlePacket(ENetEvent& e) {
-    if(e.peer->data == nullptr) {
-        LOG_WARNING("client without data sent package");
+static void handlePacket(ENetEvent* e) {
+    if(e->peer->data == nullptr) {
+        CORE_LOG_WARNING("Client without data sent package");
         return;
     }
-    Server::Client id = getId(e.peer);
-    InPacket in(e.packet->data, static_cast<int>(e.packet->dataLength));
-    onPacket(id, in);
+    CoreClient id = getId(e->peer);
+    CoreInPacket in;
+    coreInitInPacket(&in, e->packet->data, e->packet->dataLength);
+    server.onPacket(id, &in);
 }
 
-static void handleDisconnect(ENetEvent& e) {
-    if(e.peer->data == nullptr) {
-        LOG_WARNING("client without data disconnected");
+static void handleDisconnect(ENetEvent* e) {
+    if(e->peer->data == nullptr) {
+        CORE_LOG_WARNING("Client without data disconnected");
         return;
     }
-    Server::Client id = getId(e.peer);
-    onDisconnect(id);
-    if(clients.remove(id)) {
-        LOG_WARNING("removed non existing client");
+    CoreClient id = getId(e->peer);
+    server.onDisconnect(id);
+    if(!coreHashMapRemove(&server.clients, CoreClient, id)) {
+        CORE_LOG_WARNING("Removed non existing client");
     }
 }
 
-void Server::tick() {
-    if(server == nullptr) {
+void coreServerTick(void) {
+    if(server.server == nullptr) {
         return;
     }
     ENetEvent e;
-    while(enet_host_service(server, &e, 0) > 0) {
+    while(enet_host_service(server.server, &e, 0) > 0) {
         switch(e.type) {
-            case ENET_EVENT_TYPE_CONNECT: handleConnect(e); break;
+            case ENET_EVENT_TYPE_CONNECT: handleConnect(&e); break;
             case ENET_EVENT_TYPE_RECEIVE:
-                handlePacket(e);
+                handlePacket(&e);
                 enet_packet_destroy(e.packet);
                 break;
             case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
-            case ENET_EVENT_TYPE_DISCONNECT: handleDisconnect(e); break;
+            case ENET_EVENT_TYPE_DISCONNECT: handleDisconnect(&e); break;
             case ENET_EVENT_TYPE_NONE: return;
         }
     }
 }
 
-static ENetPacket* fromBuffer(const Buffer& buffer, int index) {
-    constexpr enet_uint32 flags[] = {ENET_PACKET_FLAG_RELIABLE, 0,
-                                     ENET_PACKET_FLAG_UNSEQUENCED};
-    return enet_packet_create(
-        buffer, static_cast<unsigned int>(buffer.getLength()),
-flags[index]);
+static ENetPacket* fromBuffer(const CoreBuffer* buffer, enet_uint8 index) {
+    static const enet_uint32 flags[] = {ENET_PACKET_FLAG_RELIABLE, 0,
+                                        ENET_PACKET_FLAG_UNSEQUENCED};
+    return enet_packet_create(buffer->buffer, buffer->size, flags[index]);
 }
 
-void Server::send(const OutPacket& p, PacketSendMode mode) {
-    if(server != nullptr) {
-        int index = static_cast<int>(mode);
-        enet_host_broadcast(server, static_cast<enet_uint8>(index),
-                            fromBuffer(p.buffer, index));
+void coreServerSendAll(const CoreOutPacket* p, CorePacketSendMode mode) {
+    if(server.server != nullptr) {
+        enet_uint8 index = (enet_uint8)mode;
+        enet_host_broadcast(server.server, index, fromBuffer(&p->data, index));
     }
 }
 
-void Server::send(Server::Client client, const OutPacket& p,
-                  PacketSendMode mode) {
-    if(server == nullptr) {
+void coreServerSend(CoreClient clientId, const CoreOutPacket* p,
+                    CorePacketSendMode mode) {
+    if(server.server == nullptr) {
         return;
     }
-    ENetPeer** peer = clients.search(client);
+    ENetPeer** peer = coreHashMapSearchPointer(&server.clients, &clientId);
     if(peer != nullptr) {
-        int index = static_cast<int>(mode);
-        enet_peer_send(*peer, static_cast<enet_uint8>(index),
-                       fromBuffer(p.buffer, index));
+        enet_uint8 index = (enet_uint8)mode;
+        enet_peer_send(*peer, index, fromBuffer(&p->data, index));
     }
 }
 
-void Server::disconnect(Client client) {
-    ENetPeer** peer = clients.search(client);
+void coreServerDisconnect(CoreClient clientId) {
+    ENetPeer** peer = coreHashMapSearchPointer(&server.clients, &clientId);
     if(peer != nullptr) {
         enet_peer_disconnect(*peer, 0);
     }
 }
 
-void Server::setConnectHandler(OnConnect oc) {
-    onConnect = oc;
+void coreServerSetConnectHandler(CoreServerOnConnect oc) {
+    server.onConnect = oc == nullptr ? voidClientDummy : oc;
 }
 
-void Server::setDisconnectHandler(OnDisconnect od) {
-    onDisconnect = od;
+void coreServerSetDisconnectHandler(CoreServerOnDisconnect od) {
+    server.onDisconnect = od == nullptr ? voidClientDummy : od;
 }
 
-void Server::setPacketHandler(OnPacket op) {
-    onPacket = op;
+void coreServerSetPacketHandler(CoreServerOnPacket op) {
+    server.onPacket = op == nullptr ? voidClientInPacketDummy : op;
 }
 
-void Server::resetHandler() {
-    onConnect = [](Server::Client) {};
-    onDisconnect = [](Server::Client) {};
-    onPacket = [](Server::Client, InPacket&) {};
-}*/
+void coreServerResetHandler(void) {
+    server.onConnect = voidClientDummy;
+    server.onDisconnect = voidClientDummy;
+    server.onPacket = voidClientInPacketDummy;
+}