|
@@ -1,6 +1,8 @@
|
|
|
#include "core/Network.h"
|
|
|
|
|
|
#define ENET_IMPLEMENTATION
|
|
|
+#include <core/Logger.h>
|
|
|
+#include <core/Utility.h>
|
|
|
#include <enet.h>
|
|
|
#include <string.h>
|
|
|
|
|
@@ -173,8 +175,9 @@ OutPacket* coreOutPacketWrite(OutPacket* out, const void* buffer, size_t n) {
|
|
|
return out;
|
|
|
}
|
|
|
|
|
|
-/*static int enetCounter = 0;
|
|
|
-bool ENet::add() {
|
|
|
+static int enetCounter = 0;
|
|
|
+
|
|
|
+static bool addENet(void) {
|
|
|
if(enetCounter == 0 && enet_initialize() != 0) {
|
|
|
return true;
|
|
|
}
|
|
@@ -182,164 +185,183 @@ bool ENet::add() {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-void ENet::remove() {
|
|
|
+static void removeENet(void) {
|
|
|
if(enetCounter > 0 && --enetCounter == 0) {
|
|
|
enet_deinitialize();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static_assert(sizeof(enet_uint16) == sizeof(Client::Port),
|
|
|
- "client port has wrong type");
|
|
|
+static_assert(sizeof(enet_uint16) == sizeof(CorePort), "port has wrong type");
|
|
|
|
|
|
-static ENetHost* client = nullptr;
|
|
|
-static ENetPeer* connection = nullptr;
|
|
|
-static int connectTicks = 0;
|
|
|
-static int connectTimeoutTicks = 0;
|
|
|
-static int disconnectTicks = 0;
|
|
|
-static int disconnectTimeoutTicks = 0;
|
|
|
-static Client::OnConnect onConnect = []() {};
|
|
|
-static Client::OnDisconnect onDisconnect = []() {};
|
|
|
-static Client::OnPacket onPacket = [](InPacket&) {};
|
|
|
-
|
|
|
-Error Client::start() {
|
|
|
- if(client != nullptr) {
|
|
|
- return {"already started"};
|
|
|
- } else if(ENet::add()) {
|
|
|
- return {"cannot initialize enet"};
|
|
|
+static void voidVoidDummy(void) {
|
|
|
+}
|
|
|
+
|
|
|
+static void voidInPacketDummy(CoreInPacket*) {
|
|
|
+}
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ ENetHost* client;
|
|
|
+ ENetPeer* connection;
|
|
|
+ CoreClientOnConnect onConnect;
|
|
|
+ CoreClientOnDisconnect onDisconnect;
|
|
|
+ CoreClientOnPacket onPacket;
|
|
|
+ int connectTicks;
|
|
|
+ int connectTimeoutTicks;
|
|
|
+ int disconnectTicks;
|
|
|
+ int disconnectTimeoutTicks;
|
|
|
+} Client;
|
|
|
+
|
|
|
+static Client client = {
|
|
|
+ nullptr, nullptr, voidVoidDummy, voidVoidDummy, voidInPacketDummy, 0, 0,
|
|
|
+ 0, 0};
|
|
|
+
|
|
|
+bool coreClientStart(void) {
|
|
|
+ if(client.client != nullptr) {
|
|
|
+ CORE_LOG_WARNING("Client already started");
|
|
|
+ return true;
|
|
|
+ } else if(addENet()) {
|
|
|
+ CORE_LOG_WARNING("Client cannot initialize enet");
|
|
|
+ return true;
|
|
|
}
|
|
|
- client = enet_host_create(nullptr, 1, 2, 0, 0);
|
|
|
- if(client == nullptr) {
|
|
|
- ENet::remove();
|
|
|
- return {"cannot create enet client host"};
|
|
|
+ client.client = enet_host_create(nullptr, 1, 2, 0, 0);
|
|
|
+ if(client.client == nullptr) {
|
|
|
+ coreClientStop();
|
|
|
+ CORE_LOG_ERROR("Cannot create enet client host");
|
|
|
+ return true;
|
|
|
}
|
|
|
- return {};
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
-void Client::stop() {
|
|
|
- if(connection != nullptr) {
|
|
|
- onDisconnect();
|
|
|
- enet_peer_disconnect_now(connection, 0);
|
|
|
- connection = nullptr;
|
|
|
+void coreClientStop(void) {
|
|
|
+ if(client.connection != nullptr) {
|
|
|
+ client.onDisconnect();
|
|
|
+ enet_peer_disconnect_now(client.connection, 0);
|
|
|
+ client.connection = nullptr;
|
|
|
}
|
|
|
- if(client != nullptr) {
|
|
|
- enet_host_destroy(client);
|
|
|
- ENet::remove();
|
|
|
- client = nullptr;
|
|
|
+ if(client.client != nullptr) {
|
|
|
+ enet_host_destroy(client.client);
|
|
|
+ client.client = nullptr;
|
|
|
+ removeENet();
|
|
|
}
|
|
|
- connectTicks = 0;
|
|
|
- disconnectTicks = 0;
|
|
|
+ client.connectTicks = 0;
|
|
|
+ client.disconnectTicks = 0;
|
|
|
}
|
|
|
|
|
|
-Error Client::connect(const char* server, Port port, int timeoutTicks) {
|
|
|
- if(client == nullptr) {
|
|
|
- return {"client not started"};
|
|
|
- } else if(connection != nullptr) {
|
|
|
- return {"connection already exists"};
|
|
|
+bool coreClientConnect(const char* server, CorePort port, int timeoutTicks) {
|
|
|
+ if(client.client == nullptr) {
|
|
|
+ CORE_LOG_WARNING("client not started");
|
|
|
+ return true;
|
|
|
+ } else if(client.connection != nullptr) {
|
|
|
+ CORE_LOG_WARNING("connection already exists");
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
- ENetAddress address;
|
|
|
- memset(&address, 0, sizeof(ENetAddress));
|
|
|
+ ENetAddress address = {0};
|
|
|
enet_address_set_host(&address, server);
|
|
|
address.port = port;
|
|
|
|
|
|
- connection = enet_host_connect(client, &address, 3, 0);
|
|
|
- if(connection == nullptr) {
|
|
|
- return {"cannot create connection"};
|
|
|
+ client.connection = enet_host_connect(client.client, &address, 3, 0);
|
|
|
+ if(client.connection == nullptr) {
|
|
|
+ CORE_LOG_ERROR("cannot create connection");
|
|
|
+ return true;
|
|
|
}
|
|
|
- connectTicks = 1;
|
|
|
- connectTimeoutTicks = timeoutTicks;
|
|
|
- return {};
|
|
|
+ client.connectTicks = 1;
|
|
|
+ client.connectTimeoutTicks = timeoutTicks;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
-void Client::disconnect(int timeoutTicks) {
|
|
|
- if(connection == nullptr) {
|
|
|
+void coreClientDisconnect(int timeoutTicks) {
|
|
|
+ if(client.connection == nullptr) {
|
|
|
return;
|
|
|
}
|
|
|
- connectTicks = 0;
|
|
|
- enet_peer_disconnect(connection, 0);
|
|
|
- disconnectTicks = 1;
|
|
|
- disconnectTimeoutTicks = timeoutTicks;
|
|
|
+ client.connectTicks = 0;
|
|
|
+ enet_peer_disconnect(client.connection, 0);
|
|
|
+ client.disconnectTicks = 1;
|
|
|
+ client.disconnectTimeoutTicks = timeoutTicks;
|
|
|
}
|
|
|
|
|
|
-void Client::send(OutPacket& p, PacketSendMode mode) {
|
|
|
- if(client != nullptr && connection != nullptr && connectTicks < 0) {
|
|
|
- constexpr enet_uint32 flags[] = {ENET_PACKET_FLAG_RELIABLE, 0,
|
|
|
- ENET_PACKET_FLAG_UNSEQUENCED};
|
|
|
- enet_uint8 index = static_cast<enet_uint8>(mode);
|
|
|
- enet_peer_send(connection, index,
|
|
|
- enet_packet_create(
|
|
|
- p.buffer,
|
|
|
-static_cast<size_t>(p.buffer.getLength()), flags[index]));
|
|
|
+void coreClientSend(OutPacket* p, CorePacketSendMode mode) {
|
|
|
+ if(client.client != nullptr || client.connection != nullptr ||
|
|
|
+ client.connectTicks >= 0) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ static const enet_uint32 flags[] = {ENET_PACKET_FLAG_RELIABLE, 0,
|
|
|
+ ENET_PACKET_FLAG_UNSEQUENCED};
|
|
|
+ enet_uint8 i = (enet_uint8)mode;
|
|
|
+ enet_peer_send(client.connection, i,
|
|
|
+ enet_packet_create(p->data.buffer, p->data.size, flags[i]));
|
|
|
}
|
|
|
|
|
|
-void Client::tick() {
|
|
|
- if(client == nullptr) {
|
|
|
+void coreClientTick(void) {
|
|
|
+ if(client.client == nullptr) {
|
|
|
return;
|
|
|
}
|
|
|
ENetEvent e;
|
|
|
- while(enet_host_service(client, &e, 0) > 0) {
|
|
|
+ while(enet_host_service(client.client, &e, 0) > 0) {
|
|
|
switch(e.type) {
|
|
|
case ENET_EVENT_TYPE_CONNECT:
|
|
|
- connectTicks = -1;
|
|
|
- onConnect();
|
|
|
+ client.connectTicks = -1;
|
|
|
+ client.onConnect();
|
|
|
break;
|
|
|
case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
|
|
|
case ENET_EVENT_TYPE_DISCONNECT:
|
|
|
- disconnectTicks = 0;
|
|
|
- onDisconnect();
|
|
|
- connection = nullptr;
|
|
|
+ client.disconnectTicks = 0;
|
|
|
+ client.onDisconnect();
|
|
|
+ client.connection = nullptr;
|
|
|
break;
|
|
|
case ENET_EVENT_TYPE_NONE: return;
|
|
|
- case ENET_EVENT_TYPE_RECEIVE:
|
|
|
- InPacket in(e.packet->data,
|
|
|
- static_cast<int>(e.packet->dataLength));
|
|
|
- onPacket(in);
|
|
|
+ case ENET_EVENT_TYPE_RECEIVE: {
|
|
|
+ CoreInPacket in;
|
|
|
+ coreInitInPacket(&in, e.packet->data, e.packet->dataLength);
|
|
|
+ client.onPacket(&in);
|
|
|
enet_packet_destroy(e.packet);
|
|
|
break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- if(connectTicks >= 1 && ++connectTicks > connectTimeoutTicks) {
|
|
|
- connectTicks = 0;
|
|
|
- disconnect(connectTimeoutTicks);
|
|
|
- }
|
|
|
- if(disconnectTicks >= 1 && ++disconnectTicks > disconnectTimeoutTicks) {
|
|
|
- disconnectTicks = 0;
|
|
|
- onDisconnect();
|
|
|
- if(connection != nullptr) {
|
|
|
- enet_peer_reset(connection);
|
|
|
- connection = nullptr;
|
|
|
+ if(client.connectTicks >= 1 &&
|
|
|
+ ++client.connectTicks > client.connectTimeoutTicks) {
|
|
|
+ client.connectTicks = 0;
|
|
|
+ coreClientDisconnect(client.connectTimeoutTicks);
|
|
|
+ }
|
|
|
+ if(client.disconnectTicks >= 1 &&
|
|
|
+ ++client.disconnectTicks > client.disconnectTimeoutTicks) {
|
|
|
+ client.disconnectTicks = 0;
|
|
|
+ client.onDisconnect();
|
|
|
+ if(client.connection != nullptr) {
|
|
|
+ enet_peer_reset(client.connection);
|
|
|
+ client.connection = nullptr;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Client::setConnectHandler(OnConnect oc) {
|
|
|
- onConnect = oc;
|
|
|
+void coreClientSetConnectHandler(CoreClientOnConnect oc) {
|
|
|
+ client.onConnect = oc == nullptr ? voidVoidDummy : oc;
|
|
|
}
|
|
|
|
|
|
-void Client::setDisconnectHandler(OnDisconnect od) {
|
|
|
- onDisconnect = od;
|
|
|
+void coreClientSetDisconnectHandler(CoreClientOnDisconnect od) {
|
|
|
+ client.onDisconnect = od == nullptr ? voidVoidDummy : od;
|
|
|
}
|
|
|
|
|
|
-void Client::setPacketHandler(OnPacket op) {
|
|
|
- onPacket = op;
|
|
|
+void coreClientSetPacketHandler(CoreClientOnPacket op) {
|
|
|
+ client.onPacket = op == nullptr ? voidInPacketDummy : op;
|
|
|
}
|
|
|
|
|
|
-void Client::resetHandler() {
|
|
|
- onConnect = []() {};
|
|
|
- onDisconnect = []() {};
|
|
|
- onPacket = [](InPacket&) {};
|
|
|
+void coreClientResetHandler(void) {
|
|
|
+ client.onConnect = voidVoidDummy;
|
|
|
+ client.onDisconnect = voidVoidDummy;
|
|
|
+ client.onPacket = voidInPacketDummy;
|
|
|
}
|
|
|
|
|
|
-bool Client::isConnecting() {
|
|
|
- return connectTicks >= 1;
|
|
|
+bool coreClientIsConnecting(void) {
|
|
|
+ return client.connectTicks >= 1;
|
|
|
}
|
|
|
|
|
|
-bool Client::isConnected() {
|
|
|
- return connectTicks < 0;
|
|
|
+bool coreClientIsConnected(void) {
|
|
|
+ return client.connectTicks < 0;
|
|
|
}
|
|
|
|
|
|
-static_assert(sizeof(enet_uint16) == sizeof(Server::Port),
|
|
|
+/*static_assert(sizeof(enet_uint16) == sizeof(Server::Port),
|
|
|
"client port has wrong type");
|
|
|
|
|
|
static ENetHost* server;
|