From 44ebe1e1da989a12df1d74cf0438fd5288464311 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Tue, 22 Apr 2025 22:52:45 -0500 Subject: [PATCH] Packet system basically working --- src/client/networked/networkedclient.c | 19 ++++++++++++-- src/packet/packet.c | 35 +++++++++++++++++--------- src/packet/packet.h | 9 +++++++ src/packet/packetbase.h | 13 ++++++++++ src/packet/packetdisconnect.c | 9 +++++-- src/packet/packetdisconnect.h | 11 ++++---- src/packet/packetping.c | 13 ++++++++++ src/packet/packetping.h | 5 +--- src/packet/packetwelcome.h | 4 +-- 9 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 src/packet/packetbase.h diff --git a/src/client/networked/networkedclient.c b/src/client/networked/networkedclient.c index 985e274..5b024d8 100644 --- a/src/client/networked/networkedclient.c +++ b/src/client/networked/networkedclient.c @@ -93,9 +93,9 @@ errorret_t networkedClientConnect( if(err) return err; switch(packet.type) { case PACKET_TYPE_DISCONNECT: - err = packetDisconnectClient(&packet); + err = packetDisconnectClientProcess(&packet, client); if(err) return err; - break; + return error("Server disconnected"); case PACKET_TYPE_WELCOME: err = packetWelcomeClient(&packet); @@ -335,6 +335,21 @@ void * networkedClientReadThread(void *arg) { if(err) { consolePrint("Failed to read packet %s", errorString()); errorFlush(); + pthread_mutex_unlock(&client->networked.readLock); + break; + } + + // Handle disconnect packets here + if(packet.type == PACKET_TYPE_DISCONNECT) { + err = packetDisconnectClientProcess(&packet, client); + if(err) { + consolePrint(errorString()); + errorFlush(); + } else { + consolePrint("Server disconnected"); + } + client->state = CLIENT_STATE_DISCONNECTING; + pthread_mutex_unlock(&client->networked.readLock); break; } diff --git a/src/packet/packet.c b/src/packet/packet.c index 2029d97..981c56b 100644 --- a/src/packet/packet.c +++ b/src/packet/packet.c @@ -11,6 +11,13 @@ #include "client/client.h" #include "server/server.h" +packethandler_t PACKET_HANDLERS[] = { + { NULL, NULL }, + { NULL, NULL }, + { packetDisconnectClientProcess, NULL }, + { packetPingClientProcess, packetPingServerProcess }, +}; + void packetInit( packet_t *packet, const packettype_t type, @@ -42,13 +49,15 @@ errorret_t packetClientProcess( ); assertIsMainThread("Client process must be on main thread"); - switch(packet->type) { - case PACKET_TYPE_PING: - return packetPingClientProcess(packet, client); - - default: - return error("Unknown packet type %d", packet->type); + if(packet->type >= PACKET_TYPE_COUNT) { + return error("Unknown packet type %d", packet->type); } + + if(PACKET_HANDLERS[packet->type].client == NULL) { + return error("Packet type %d has no client handler", packet->type); + } + + return PACKET_HANDLERS[packet->type].client(packet, client); } errorret_t packetServerProcess( @@ -63,11 +72,13 @@ errorret_t packetServerProcess( ); assertIsMainThread("Server client process must be on main thread"); - switch(packet->type) { - case PACKET_TYPE_PING: - return packetPingServerProcess(packet, client); - - default: - return error("Unknown packet type %d", packet->type); + if(packet->type >= PACKET_TYPE_COUNT) { + return error("Unknown packet type %d", packet->type); } + + if(PACKET_HANDLERS[packet->type].server == NULL) { + return error("Packet type %d has no server handler", packet->type); + } + + return PACKET_HANDLERS[packet->type].server(packet, client); } \ No newline at end of file diff --git a/src/packet/packet.h b/src/packet/packet.h index 51aeed0..d1d34c0 100644 --- a/src/packet/packet.h +++ b/src/packet/packet.h @@ -18,6 +18,8 @@ typedef enum { PACKET_TYPE_PING = 3, } packettype_t; +#define PACKET_TYPE_COUNT 4 + typedef union { packetwelcome_t welcome; packetdisconnect_t disconnect; @@ -30,6 +32,13 @@ typedef struct packet_s { packetdata_t data; } packet_t; +typedef struct { + errorret_t (*client)(const packet_t *packet, client_t *client); + errorret_t (*server)(const packet_t *packet, serverclient_t *client); +} packethandler_t; + +extern packethandler_t PACKET_HANDLERS[]; + /** * Initializes a packet with the given type. This is only to be used by sub * initializers, such as packetWelcomeCreate for example. diff --git a/src/packet/packetbase.h b/src/packet/packetbase.h new file mode 100644 index 0000000..1622f67 --- /dev/null +++ b/src/packet/packetbase.h @@ -0,0 +1,13 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "error/error.h" + +typedef struct client_s client_t; +typedef struct serverclient_s serverclient_t; +typedef struct packet_s packet_t; \ No newline at end of file diff --git a/src/packet/packetdisconnect.c b/src/packet/packetdisconnect.c index 2986f01..50be7cb 100644 --- a/src/packet/packetdisconnect.c +++ b/src/packet/packetdisconnect.c @@ -8,6 +8,7 @@ #include "packet.h" #include "util/memory.h" #include "assert/assert.h" +#include "client/client.h" void packetDisconnectCreate( packet_t *packet, @@ -17,8 +18,10 @@ void packetDisconnectCreate( packet->data.disconnect.reason = reason; } -errorret_t packetDisconnectClient(packet_t *packet) { - assertNotNull(packet, "Packet is NULL"); +errorret_t packetDisconnectClientProcess( + const packet_t *packet, + client_t *client +) { assertTrue( packet->type == PACKET_TYPE_DISCONNECT, "Packet type is not DISCONNECT" @@ -43,4 +46,6 @@ errorret_t packetDisconnectClient(packet_t *packet) { default: return error("Server disconnected: Unknown reason"); } + + return ERROR_OK; } \ No newline at end of file diff --git a/src/packet/packetdisconnect.h b/src/packet/packetdisconnect.h index fa16693..998fce0 100644 --- a/src/packet/packetdisconnect.h +++ b/src/packet/packetdisconnect.h @@ -6,9 +6,7 @@ */ #pragma once -#include "error/error.h" - -typedef struct packet_s packet_t; +#include "packetbase.h" typedef enum { PACKET_DISCONNECT_REASON_UNKNOWN = 0, @@ -34,9 +32,12 @@ void packetDisconnectCreate( ); /** - * Handles a disconnect packet received FROM a server INTO a client. + * Handles disconnect packet client side. * * @param packet Pointer to the packet structure to handle. + * @param client Pointer to the client structure. * @return ERROR_OK on success, or an error code on failure. */ -errorret_t packetDisconnectClient(packet_t *packet); \ No newline at end of file +errorret_t packetDisconnectClientProcess( + const packet_t *packet, client_t *client +); \ No newline at end of file diff --git a/src/packet/packetping.c b/src/packet/packetping.c index 961bf3f..09b17be 100644 --- a/src/packet/packetping.c +++ b/src/packet/packetping.c @@ -19,7 +19,13 @@ errorret_t packetPingClientProcess( const packet_t *packet, client_t *client ) { + assertTrue( + packet->type == PACKET_TYPE_PING, + "Packet type is not PING" + ); + printf("Client got Pong!\n"); + return ERROR_OK; } @@ -27,14 +33,21 @@ errorret_t packetPingServerProcess( const packet_t *packet, serverclient_t *client ) { + assertTrue( + packet->type == PACKET_TYPE_PING, + "Packet type is not PING" + ); + if(packet->length != sizeof(packetping_t)) { return error("Ping packet length is not %d", sizeof(packetping_t)); } printf("Server got Ping!\n"); + // Send ping back to the client. packet_t pong; packetPingCreate(&pong); packetQueuePushOut(&client->packetQueue, &pong); + return ERROR_OK; } \ No newline at end of file diff --git a/src/packet/packetping.h b/src/packet/packetping.h index 8735c19..aec495d 100644 --- a/src/packet/packetping.h +++ b/src/packet/packetping.h @@ -6,10 +6,7 @@ */ #pragma once -#include "error/error.h" - -typedef struct client_s client_t; -typedef struct serverclient_s serverclient_t; +#include "packetbase.h" typedef struct { int32_t number; diff --git a/src/packet/packetwelcome.h b/src/packet/packetwelcome.h index dedc047..e3b1da9 100644 --- a/src/packet/packetwelcome.h +++ b/src/packet/packetwelcome.h @@ -6,9 +6,7 @@ */ #pragma once -#include "error/error.h" - -typedef struct packet_s packet_t; +#include "packetbase.h" #define PACKET_WELCOME_STRING "DUSK" #define PACKET_WELCOME_SIZE 4