2026-10-25 23:30:00 +01:00

114 lines
2.5 KiB
C++

#include <deerith/core/log.h>
#include <deerith/network/client.h>
#include <deerith/network/router.h>
#include <deerith/network/packets.h>
#include <deerith/server/world.h>
#include <enet/enet.h>
#include <thread>
#include <vector>
#include <memory>
#include <deerith/server/network/network_internals.h>
#include <deerith/server/world/world_internals.h>
namespace deerith
{
ENetHost *server;
std::vector<std::unique_ptr<client_t>> clients;
void create_client(ENetPeer *peer);
void delete_client(client_t *client);
}
void deerith::delete_client(client_t *client)
{
auto it = std::find_if(
clients.begin(),
clients.end(),
[client](const std::unique_ptr<client_t> &ptr)
{ return ptr.get() == client; });
if (it != clients.end())
{
clients.erase(it);
}
}
bool deerith::init_server(int port)
{
ENetAddress address = {0};
address.host = ENET_HOST_ANY;
address.port = port;
server = enet_host_create(&address, 32, 2, 0, 0);
if (server == nullptr)
{
deerith_error("init_server failed");
return false;
}
load_base_protocols();
return true;
}
int deerith::init_network()
{
if (enet_initialize() != 0)
{
deerith_error("An error occurred while initializing ENet.\n");
return 1;
}
return 0;
}
void deerith::shutdown_network()
{
enet_deinitialize();
}
void deerith::flush_network_events()
{
ENetEvent event;
while (enet_host_service(server, &event, 0) > 0)
{
switch (event.type)
{
case ENET_EVENT_TYPE_CONNECT:
create_client(event.peer);
break;
case ENET_EVENT_TYPE_DISCONNECT:
client_disconnects((client_t *)event.peer->data);
delete_client((client_t *)event.peer->data);
event.peer->data = NULL;
break;
case ENET_EVENT_TYPE_RECEIVE:
ENetPacket *packet = event.packet;
router_process_packet(packet->data, packet->dataLength, (client_t *)event.peer->data);
enet_packet_destroy(event.packet);
break;
}
}
}
void deerith::create_client(ENetPeer *peer)
{
char enet_address[32];
enet_address_get_host_ip(&peer->address, enet_address, 31);
deerith_trace("a new client has connected : {}", enet_address);
std::unique_ptr<client_t> client = std::make_unique<client_t>(peer);
peer->data = client.get();
clients.push_back(std::move(client));
client_connects((client_t *)peer->data);
}