From ed6d4c0b08e3c7353dda28a45b312ce5083d9494 Mon Sep 17 00:00:00 2001 From: iWas-Coder Date: Mon, 1 Apr 2024 05:20:24 +0200 Subject: [PATCH] Abstracted away server operations Keep thinking about the game state topology and design... still WIP. --- include/sk_server.h | 10 +++++-- include/sk_state.h | 20 +++++++------- src/sk_client.c | 64 ++++++++++++++++++++------------------------- src/sk_server.c | 58 +++++++++++++++++++++++++--------------- src/sk_state.c | 33 ++++++++++++----------- 5 files changed, 102 insertions(+), 83 deletions(-) diff --git a/include/sk_server.h b/include/sk_server.h index 7bc26d1..4d497ef 100644 --- a/include/sk_server.h +++ b/include/sk_server.h @@ -27,7 +27,13 @@ #define SK_SERVER_PORT 27015 #define SK_SERVER_TICK_RATE 128 #define SK_SERVER_MSG_MAX_SIZE 1024 -#define SK_SERVER_MSG_CONN_REQ SK_SERVER_NAME "::ping" -#define SK_SERVER_MSG_CONN_RES SK_SERVER_NAME "::pong::%u/%u" +#define SK_SERVER_MSG_HELLO SK_SERVER_NAME "::hello" +#define SK_SERVER_MSG_HOWDY SK_SERVER_NAME "::howdy::%u/%u" + +int sk_server_socket_create(void); + +void sk_server_socket_destroy(int sock_fd); + +int sk_server_socket_bind(int sock_fd); u8 sk_server_run(void); diff --git a/include/sk_state.h b/include/sk_state.h index 7989357..dfdaa94 100644 --- a/include/sk_state.h +++ b/include/sk_state.h @@ -26,20 +26,22 @@ #define SK_STATE_MAX_LOBBIES 256 +typedef struct { + u8 lobbies_count; + sk_lobby lobbies[SK_STATE_MAX_LOBBIES]; +} sk_state_global; + typedef struct { u8 is_online; sk_scene curr_scene; union { - struct { - u8 lobbies_count; - sk_lobby lobbies[SK_STATE_MAX_LOBBIES]; - }; - struct { - sk_player player; - }; + sk_lobby lobby; + sk_player player; }; } sk_state; -sk_state sk_state_create(u8 is_online); +sk_state_global sk_state_global_create(void); + +sk_state sk_state_create_offline(void); -void sk_state_destroy(sk_state *s); +sk_state sk_state_create_online(u8 lobby_id); diff --git a/src/sk_client.c b/src/sk_client.c index d3b889f..fa6fff1 100644 --- a/src/sk_client.c +++ b/src/sk_client.c @@ -33,24 +33,32 @@ u8 sk_client_run(const char *ip) { SK_LOG_INFO("Initializing %s", SK_CLIENT_NAME); - u8 is_online = 0; - int sock_fd; - if (!ip) SK_LOG_WARN("Running in offline mode"); + if (!ChangeDirectory(GetApplicationDirectory())) { + SK_LOG_WARN("Could not change CWD to the game's root directory"); + } + if (!ip) { + SK_LOG_WARN("Running in offline mode"); + sk_state state = sk_state_create_offline(); + sk_renderer_create(); + sk_renderer_loop { + sk_renderer_update(&state); + sk_renderer_draw(&state); + } + sk_player_destroy(&state.player); + sk_renderer_destroy(); + } else { - SK_LOG_INFO("Connecting to `%s` ...", ip); const struct sockaddr_in server_addr = { .sin_family = AF_INET, .sin_port = htons(SK_SERVER_PORT), .sin_addr.s_addr = inet_addr(ip) }; - sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock_fd == -1) { - SK_LOG_ERROR("socket(2) :: %s", strerror(errno)); - return 1; - } + int sock_fd = sk_server_socket_create(); + if (sock_fd == -1) return 1; + SK_LOG_INFO("Connecting to `%s` ...", ip); if (sendto(sock_fd, - SK_SERVER_MSG_CONN_REQ, - strlen(SK_SERVER_MSG_CONN_REQ), + SK_SERVER_MSG_HELLO, + strlen(SK_SERVER_MSG_HELLO), 0, (const struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) { @@ -58,41 +66,25 @@ u8 sk_client_run(const char *ip) { close(sock_fd); return 1; } - char pong_msg[SK_SERVER_MSG_MAX_SIZE]; - int pong_msg_n = recv(sock_fd, pong_msg, sizeof(pong_msg), MSG_WAITALL); - if (pong_msg_n == -1) { + char howdy_msg[SK_SERVER_MSG_MAX_SIZE]; + int howdy_msg_n = recv(sock_fd, howdy_msg, sizeof(howdy_msg), MSG_WAITALL); + if (howdy_msg_n == -1) { SK_LOG_ERROR("recv(2) :: %s", strerror(errno)); close(sock_fd); return 1; } - pong_msg[pong_msg_n] = 0; - if (!strcmp(pong_msg, SK_SERVER_MSG_CONN_RES)) { - is_online = 1; - } - if (!is_online) { + howdy_msg[howdy_msg_n] = 0; + SK_LOG_DEBUG(howdy_msg); + // TODO: hardcoded now to 0/0 ... change this to save the received IDs + if (strcmp(howdy_msg, TextFormat(SK_SERVER_MSG_HOWDY, 0, 0))) { SK_LOG_ERROR("Unable to communicate with `%s`. Exiting...", ip); close(sock_fd); return 1; } SK_LOG_INFO("Connected successfully to `%s`", ip); + SK_LOG_WARN("Exit due to not being implemented yet"); + sk_server_socket_destroy(sock_fd); } - if (!ChangeDirectory(GetApplicationDirectory())) { - SK_LOG_WARN("Could not change CWD to the game's root directory"); - } - sk_state state = sk_state_create(is_online); - if (!is_online) { - sk_renderer_create(); - sk_renderer_loop { - sk_renderer_update(&state); - sk_renderer_draw(&state); - } - sk_player_destroy(&state.player); - sk_renderer_destroy(); - } - else { - SK_LOG_WARN("Not implemented yet"); - } - if (is_online) close(sock_fd); SK_LOG_INFO("%s closed successfully", SK_CLIENT_NAME); return 0; } diff --git a/src/sk_server.c b/src/sk_server.c index f0e3284..fc3af17 100644 --- a/src/sk_server.c +++ b/src/sk_server.c @@ -57,24 +57,41 @@ static void wait_next_tick(double t) { #endif } -u8 sk_server_run(void) { - SK_LOG_INFO("Initializing %s", SK_SERVER_NAME); - const struct sockaddr_in server_addr = { +int sk_server_socket_create(void) { + int sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock_fd == -1) SK_LOG_ERROR("sk_server_socket_create :: %s", strerror(errno)); + else SK_LOG_INFO("UDP socket created"); + return sock_fd; +} + +void sk_server_socket_destroy(int sock_fd) { + if (sock_fd == -1) { + SK_LOG_WARN("sk_server_socket_destroy :: `sock_fd` not valid"); + return; + } + close(sock_fd); +} + +int sk_server_socket_bind(int sock_fd) { + const struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(SK_SERVER_PORT), .sin_addr.s_addr = inet_addr("127.0.0.1") }; - int sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock_fd == -1) { - SK_LOG_ERROR("socket(2) :: %s", strerror(errno)); - return 1; + int result = bind(sock_fd, (const struct sockaddr *) &addr, sizeof(addr)); + if (result == -1) { + SK_LOG_ERROR("sk_server_socket_bind :: %s", strerror(errno)); + sk_server_socket_destroy(sock_fd); } - if (bind(sock_fd, (const struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) { - SK_LOG_ERROR("bind(2) :: %s", strerror(errno)); - close(sock_fd); - return 1; - } - SK_LOG_INFO("UDP socket binded to 127.0.0.1:%d", SK_SERVER_PORT); + else SK_LOG_INFO("UDP socket binded to 127.0.0.1:%d", SK_SERVER_PORT); + return result; +} + +u8 sk_server_run(void) { + SK_LOG_INFO("Initializing %s", SK_SERVER_NAME); + int sock_fd = sk_server_socket_create(); + if (sock_fd == -1) return 1; + if (sk_server_socket_bind(sock_fd) == -1) return 1; double dt = 1 / SK_SERVER_TICK_RATE; signal(SIGINT, handle_interrupt); struct sockaddr_in client_addr; @@ -97,17 +114,16 @@ u8 sk_server_run(void) { continue; } msg[msg_n] = 0; - if (!strcmp(msg, SK_SERVER_MSG_CONN_REQ)) { + if (!strcmp(msg, SK_SERVER_MSG_HELLO)) { SK_LOG_INFO("Connection from client (%s:%d) requested", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); + u8 assigned_lobby_id = 0; + u8 assigned_lobby_slot_id = 0; // TODO: check if there is a free slot in a lobby - u8 lobby_id = 0; - u8 lobby_slot_id = 0; // TODO: assign him a lobby and a player slot inside it - memset(msg, 0, sizeof(msg)); - sprintf(msg, SK_SERVER_MSG_CONN_RES, lobby_id, lobby_slot_id); + const char * const response = TextFormat(SK_SERVER_MSG_HOWDY, assigned_lobby_id, assigned_lobby_slot_id); if (sendto(sock_fd, - msg, - strlen(SK_SERVER_MSG_CONN_RES), + response, + strlen(response), 0, (struct sockaddr *) &client_addr, client_addr_len) == -1) { @@ -118,7 +134,7 @@ u8 sk_server_run(void) { } wait_next_tick(dt); } - close(sock_fd); + sk_server_socket_destroy(sock_fd); SK_LOG_INFO("%s closed successfully", SK_SERVER_NAME); return 0; } diff --git a/src/sk_state.c b/src/sk_state.c index e42188a..67b64d6 100644 --- a/src/sk_state.c +++ b/src/sk_state.c @@ -21,23 +21,26 @@ #include -sk_state sk_state_create(u8 is_online) { - sk_state s = { - .is_online = is_online, - .curr_scene = (sk_scene) { .kind = SK_SCENE_KIND_MAIN_MENU } - }; - if (is_online) { - s.lobbies_count = 0; - for (u16 i = 0; i < SK_STATE_MAX_LOBBIES; ++i) { - s.lobbies[i] = sk_lobby_create(i); - } - } - else { - s.player = sk_player_create(SK_PLAYER_KIND_JETT); +sk_state_global sk_state_global_create(void) { + sk_state_global s = { .lobbies_count = 0 }; + for (u16 i = 0; i < SK_STATE_MAX_LOBBIES; ++i) { + s.lobbies[i] = sk_lobby_create(i); } return s; } -void sk_state_destroy(sk_state *s) { - (void) s; +sk_state sk_state_create_online(u8 lobby_id) { + return (sk_state) { + .is_online = 1, + .curr_scene = (sk_scene) { .kind = SK_SCENE_KIND_MAIN_MENU }, + .lobby = sk_lobby_create(lobby_id) + }; +} + +sk_state sk_state_create_offline(void) { + return (sk_state) { + .is_online = 0, + .curr_scene = (sk_scene) { .kind = SK_SCENE_KIND_MAIN_MENU }, + .player = sk_player_create(SK_PLAYER_KIND_JETT) + }; }