From 8e829099236e27e123146d90f4c6ca1e0e859c8c Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Sat, 20 Dec 2025 12:11:57 +0900 Subject: [PATCH] things --- CMakeLists.txt | 6 ++--- client/net.c | 65 ++++++++++++++++++++++++++++++++++++++------- format.sh | 2 +- include/af_common.h | 28 +++++++++++++++++-- include/af_server.h | 4 +++ server/main.c | 7 +++-- server/net.c | 62 ++++++++++++++++++++++++++++++++++++++++++ src/log.c | 14 ++++++++++ src/version.c | 11 ++++++++ 9 files changed, 180 insertions(+), 19 deletions(-) create mode 100644 server/net.c create mode 100644 src/log.c create mode 100644 src/version.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4309358..b5dd58e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,10 +9,10 @@ add_subdirectory(external/libfishsoup) add_subdirectory(external/milsko) add_subdirectory(external/glad) -file(GLOB SERVER_SRC server/*.c) -file(GLOB CLIENT_SRC client/*.c) +file(GLOB SERVER_SRC server/*.c src/*.c) +file(GLOB CLIENT_SRC client/*.c src/*.c) -add_executable(af_server ${SERVER_SRC}) +add_executable(af_server ${SERVER_SRC} external/stb/stb_ds.c) add_executable(af_client ${CLIENT_SRC} external/stb/stb_image.c) add_executable(af_dumpfont tools/af_dumpfont.c external/stb/stb_image_write.c) diff --git a/client/net.c b/client/net.c index 4335e43..3ee6b8d 100644 --- a/client/net.c +++ b/client/net.c @@ -2,16 +2,63 @@ static fishsoup_client_t* client = NULL; +enum OPAQUE_STATES { + OPAQUE_WAITING_HELLO = 0, + OPAQUE_SENT_JOIN +}; + +typedef struct opaque { + char username[256]; + int state; +} opaque_t; + static void net_return(MwWidget handle, void* user, void* client) { scene_change(AF_SCENE_MAIN); } -static void on_packet(fishsoup_client_t* client, fishsoup_packet_t* pkt) { +static void on_packet(fishsoup_client_t* self, fishsoup_packet_t* pkt) { + opaque_t* o = self->user; + + if(pkt->header.type == AF_PACKET_HELLO && pkt->header.length == sizeof(af_packet_hello_t) && o->state == OPAQUE_WAITING_HELLO) { + af_packet_hello_t* p_hello = pkt->data; + unsigned char mj, mi, pt; + + af_common_version(&mj, &mi, &pt); + + af_common_log_info("HELLO packet: Server version %hhu.%hhu.%hhu\n", p_hello->major, p_hello->minor, p_hello->patch); + + if(mj == p_hello->major && mi >= p_hello->minor && (mi == p_hello->minor ? (pt >= p_hello->patch) : (1))) { + fishsoup_packet_t p; + af_packet_join_t p_join; + + af_common_log_info("Server version is compatible with this client\n"); + + p.header.type = AF_PACKET_JOIN; + p.header.length = sizeof(p_join); + p.data = &p_join; + + memcpy(p_join.username, o->username, 256); + + fishsoup_packet_send(self->fd, &p); + + o->state = OPAQUE_SENT_JOIN; + + return; + } + + af_common_log_info("Server version is incompatible with this client\n"); + MwAddUserHandler(ui_message("Server version is incompatible with this client"), MwNactivateHandler, net_return, NULL); + fishsoup_client_destroy(self); + client = NULL; + } +} + +static void on_disconnect(fishsoup_client_t* self) { + free(self->user); } void net_connect(const char* username, const char* hostname, int port) { - fishsoup_packet_t pkt; - af_packet_join_t join; + opaque_t* o; scene_change(AF_SCENE_CONNECTING); client = fishsoup_client(hostname, port == 0 ? AF_DEFAULT_PORT : port); @@ -20,20 +67,20 @@ void net_connect(const char* username, const char* hostname, int port) { return; } - pkt.header.type = AF_PACKET_JOIN; - pkt.header.length = sizeof(join); - pkt.data = &join; + o = client->user = malloc(sizeof(opaque_t)); + o->state = OPAQUE_WAITING_HELLO; + memset(o->username, 0, 256); + memcpy(o->username, username, strlen(username)); fishsoup_client_on_packet(client, on_packet); - - fishsoup_packet_send(client->fd, &pkt); + fishsoup_client_on_disconnect(client, on_disconnect); } void net_poll(void) { int ret; if(client == NULL) return; - while((ret = fishsoup_client_poll(client)) > 0); + while(client != NULL && (ret = fishsoup_client_poll(client)) > 0); if(ret < 0) { MwAddUserHandler(ui_message("Connection destroyed"), MwNactivateHandler, net_return, NULL); fishsoup_client_destroy(client); diff --git a/format.sh b/format.sh index 5484336..e650534 100755 --- a/format.sh +++ b/format.sh @@ -1,2 +1,2 @@ #!/bin/sh -clang-format --verbose -i `find include server client tools -name "*.c" -or -name "*.h"` +clang-format --verbose -i `find include server client tools src -name "*.c" -or -name "*.h"` diff --git a/include/af_common.h b/include/af_common.h index 37cd55f..3c9d5f1 100644 --- a/include/af_common.h +++ b/include/af_common.h @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -22,13 +23,36 @@ #define AF_COPYRIGHT "Copyright (C) 2025 Fishsoup" enum AF_USER_PACKETS { - AF_PACKET_JOIN = FISHSOUP_PACKET_USER + AF_PACKET_HELLO = FISHSOUP_PACKET_USER, + AF_PACKET_OK, + AF_PACKET_ERROR, + AF_PACKET_JOIN }; #pragma pack(1) +typedef struct af_packet_hello { + unsigned char major; + unsigned char minor; + unsigned char patch; +} af_packet_hello_t; + +typedef struct af_packet_ok { + char reason[256]; +} af_packet_ok_t; + +typedef struct af_packet_error { + char reason[256]; +} af_packet_error_t; + typedef struct af_packet_join { - char name[256]; + char username[256]; } af_packet_join_t; #pragma pack() +/* version.c */ +void af_common_version(unsigned char* v_major, unsigned char* v_minor, unsigned char* v_patch); + +/* log.c */ +void af_common_log_info(const char* fmt, ...); + #endif diff --git a/include/af_server.h b/include/af_server.h index 8183dd1..24f90d3 100644 --- a/include/af_server.h +++ b/include/af_server.h @@ -1,4 +1,8 @@ #ifndef __AF_SERVER_H__ #define __AF_SERVER_H__ +/* net.c */ +void net_start(int port); +void net_loop(void); + #endif diff --git a/server/main.c b/server/main.c index 16ea0ae..8da016b 100644 --- a/server/main.c +++ b/server/main.c @@ -1,10 +1,9 @@ #include int main(int argc, char** argv) { - fishsoup_server_t* server; - int port = 0; + int port = 0; - server = fishsoup_server(port == 0 ? AF_DEFAULT_PORT : port); + net_start(port); - fishsoup_server_loop(server); + net_loop(); } diff --git a/server/net.c b/server/net.c new file mode 100644 index 0000000..6c28f30 --- /dev/null +++ b/server/net.c @@ -0,0 +1,62 @@ +#include + +static fishsoup_server_t* server; + +typedef struct opaque { + char username[256 + 1]; +} opaque_t; + +static void on_packet(fishsoup_client_t* self, fishsoup_packet_t* pkt) { + opaque_t* o = self->user; + + if(pkt->header.type == AF_PACKET_JOIN && pkt->header.length == sizeof(af_packet_join_t)) { + af_packet_join_t* p_join = pkt->data; + + o->username[256] = 0; + memcpy(o->username, p_join->username, 256); + + af_common_log_info("Client %d: JOIN packet: Username \"%s\"\n", self->fd, o->username); + } +} + +static void on_disconnect(fishsoup_client_t* self) { + free(self->user); + af_common_log_info("Client %d: Disconnected\n", self->fd); +} + +static void on_client(fishsoup_server_t* self, fishsoup_client_t* client) { + opaque_t* o; + fishsoup_packet_t pkt; + af_packet_hello_t hello; + + af_common_log_info("Client %d: Connected\n", client->fd); + + o = client->user = malloc(sizeof(opaque_t)); + + o->username[0] = 0; + + fishsoup_client_on_disconnect(client, on_disconnect); + fishsoup_client_on_packet(client, on_packet); + + pkt.header.type = AF_PACKET_HELLO; + pkt.header.length = sizeof(hello); + pkt.data = &hello; + + af_common_version(&hello.major, &hello.minor, &hello.patch); + + fishsoup_packet_send(client->fd, &pkt); +} + +void net_start(int port) { + if(port == 0) port = AF_DEFAULT_PORT; + + if((server = fishsoup_server(port)) == NULL) return; + + fishsoup_server_on_client(server, on_client); +} + +void net_loop(void) { + if(server == NULL) return; + + fishsoup_server_loop(server); +} diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..dc8b4db --- /dev/null +++ b/src/log.c @@ -0,0 +1,14 @@ +#include + +static void af_common_log(const char* type, const char* fmt, va_list va) { + printf("[%.4s] ", type); + vprintf(fmt, va); +} + +void af_common_log_info(const char* fmt, ...) { + va_list va; + + va_start(va, fmt); + af_common_log("INFO", fmt, va); + va_end(va); +} diff --git a/src/version.c b/src/version.c new file mode 100644 index 0000000..9a48e41 --- /dev/null +++ b/src/version.c @@ -0,0 +1,11 @@ +#include + +void af_common_version(unsigned char* v_major, unsigned char* v_minor, unsigned char* v_patch) { + char* mj = AF_VERSION; + char* mi = strchr(mj, '.') + 1; + char* pt = strchr(mi, '.') + 1; + + *v_major = atoi(mj); + *v_minor = atoi(mi); + *v_patch = atoi(pt); +}