diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/data.c | 131 | ||||
-rw-r--r-- | src/data.h | 15 | ||||
-rw-r--r-- | src/game.c | 36 | ||||
-rw-r--r-- | src/game.h | 36 | ||||
-rw-r--r-- | src/login.c | 20 | ||||
-rw-r--r-- | src/main.c | 5 | ||||
-rw-r--r-- | src/server.c | 18 |
7 files changed, 249 insertions, 12 deletions
@@ -1,5 +1,6 @@ -#include <asm-generic/errno-base.h> #define _GNU_SOURCE +#include <errno.h> +#include <stdlib.h> #include "data.h" #include "login.h" #include <errno.h> @@ -8,6 +9,8 @@ #include <sys/stat.h> #include <unistd.h> +int deserialize_player(FILE* fp, player_t *plr); +int serialize_player(player_t* plr, FILE* fp); int try_make_data_dirs() { int err = 0; err = mkdir("data", S_IRWXU); @@ -43,9 +46,15 @@ int try_load_plr(char *player_name, playerc_t *plr) { printf("Got fp\n"); - fread(&plr->plr, sizeof(player_t), 1, fp); + if (deserialize_player(fp, &plr->plr)) { + printf("Couldn't deserialize player\n"); + return -1; + } } else { - return 4; // File doesn't exist + + printf("Couldn't open file: %d\n", errno); + printf("%s", strerror(errno)); + return -1; } printf("Read file into plr\n"); @@ -75,8 +84,122 @@ int try_write_plr(player_t *plr) { FILE *fp = fopen(fname, "wb"); - fwrite(&plr, sizeof(player_t), 1, fp); + char* buf = malloc(sizeof(player_t) + 1); + serialize_player(plr, fp); + + printf("serialized as: %s\n"); + + fprintf(fp, "%s", buf); fclose(fp); return err; } + +/* + * Ugh + * + * serialize_player takes in a `player_t` struct and a buffer and does some + * magic to write out the player in a format that can be easily parsed back + * including strings + * + * because we can't have nice things + * + * this function is sensitive to player struct updates so if things break but + * don't fail to compile this is probably the reason + */ +int serialize_player(player_t *plr, FILE* fp) { + int err = 0; + + err = fprintf(fp, "%d,%d,%d,%d,%d,%s,%s", plr->xp, plr->hp, plr->max_hp, plr->level, plr->location_id, plr->pw_hash, plr->name); + + return err; +} + +/* + * deserialize_player reverses the results of serialize_player. + * + * because even when we're gay we can't have nice things + * + * this function is *also* sensitive to player struct updates (no shit) so if + * things break but still compile it's probably this thing + */ +int deserialize_player(FILE* fp, player_t* plr) { + int err = 0; + + if (fp == NULL) { + perror("can't open player file"); + return -1; + } + + int c; + + enum ParsePlayerState state = ReadingData; + enum ParsePlayerType type = Xp; + + char* buf = malloc(1 << 10); + printf("Allocated buf\n"); + + while ((c = getc(fp) != EOF)) { + if (c == ',') { + state = Comma; + printf("Found comma"); + } + switch (state) { + case ReadingData: + strncat(buf, c, 1); + break; + case Comma: + switch (type) { + case Xp: ; + int xp = atoi(buf); + plr->xp = xp; + state = ReadingData; + type = Hp; + memset(buf, 0, strlen(buf)); + break; + case Hp: ; + int hp = atoi(buf); + plr->hp = hp; + state = ReadingData; + type = MaxHp; + memset(buf, 0, strlen(buf)); + break; + case MaxHp: ; + int max_hp = atoi(buf); + plr->max_hp = max_hp; + state = ReadingData; + type = Level; + memset(buf, 0, strlen(buf)); + break; + case Level: ; + int level = atoi(buf); + plr->level = level; + state = ReadingData; + type = LocationId; + memset(buf, 0, strlen(buf)); + break; + case LocationId: ; + int location_id = atoi(buf); + plr->location_id = location_id; + state = ReadingData; + type = PwHash; + memset(buf, 0, strlen(buf)); + break; + case PwHash: ; + plr->pw_hash = malloc(1 << 5); + strcpy(plr->pw_hash, buf); + state = ReadingData; + type = Name; + memset(buf, 0, strlen(buf)); + break; + case Name: ; + plr->name = malloc(1 << 5); + strcpy(plr->name, buf); + // we're done here + free(buf); + return 0; + } + } + } + return err; +} @@ -6,4 +6,19 @@ int try_load_plr(char *player_name, playerc_t *conn); int try_write_plr(player_t *plr); +enum ParsePlayerState { + ReadingData, + Comma +}; + +enum ParsePlayerType { + Hp, + MaxHp, + Level, + Xp, + LocationId, + PwHash, + Name +}; + #endif diff --git a/src/game.c b/src/game.c new file mode 100644 index 0000000..a5d6ca1 --- /dev/null +++ b/src/game.c @@ -0,0 +1,36 @@ +/* + * ===================================================================================== + * + * Filename: game.c + * + * Description: Implementations for the global action request tracker + * + * Version: 1.0 + * Created: 01/31/2022 11:59:12 AM + * Revision: none + * Compiler: gcc + * + * Author: Cara Salter <cara@devcara.com>, + * Organization: + * + * ===================================================================================== + */ +#include <stdlib.h> +#include <stdio.h> +#include <threads.h> +#include "game.h" + +static mtx_t queue; + +int game_loop() { + int err = 0; + + // Initialize mutex + err = mtx_init(&queue, mtx_plain); + if (err == thrd_error) { + perror("initializing mutex"); + return -1; + } + + return err; +} diff --git a/src/game.h b/src/game.h new file mode 100644 index 0000000..2fe6d3d --- /dev/null +++ b/src/game.h @@ -0,0 +1,36 @@ +/* + * ===================================================================================== + * + * Filename: game.h + * + * Description: Types and prototypes for the global action request tracker + * + * Version: 1.0 + * Created: 01/31/2022 11:55:50 AM + * Revision: none + * Compiler: gcc + * + * Author: Cara Salter <cara@devcara.com>, + * Organization: + * + * ===================================================================================== + */ + + +#ifndef _GAME_H +#define _GAME_H + +enum RequestType { + Msg, + MoveTo, + Attack +}; + +typedef struct { + enum RequestType type; + char* args[]; +} Request; + +int submit_request(Request req); + +#endif diff --git a/src/login.c b/src/login.c index 9eba897..b38fdd1 100644 --- a/src/login.c +++ b/src/login.c @@ -38,7 +38,7 @@ int step_login(playerc_t *player, int conn_fd) { for (;;) { switch (player->state) { - case LoggedOut: /* the player has yet to log in, this is a fresh connection! + case LoggedOut: ; /* the player has yet to log in, this is a fresh connection! */ printf("The player is logged out\n"); send_to_fd(player->conn, @@ -58,16 +58,22 @@ int step_login(playerc_t *player, int conn_fd) { recv(player->conn, buf, sizeof(buf), 0); if (buf[0] == 'y') { player->state = WantMakeAccount; + break; } else if (buf[0] == 'n') { send_to_fd(player->conn, "Awww :(. Oh well, hope to see you again soon!\n"); return 4; } - continue; + break; } else { - player->state = LoggedOut; - continue; + player->state = EnterPassword; + break; } + case EnterPassword: ; + asprintf(&buf, "Welcome back %s! Please enter your password, so we can confirm it.\n", player->plr.name); + send_to_fd(player->conn, buf); + recv(player->conn, buf, sizeof(buf), 0); + break; case WantMakeAccount: asprintf(&buf, "Welcome aboard %s! Why don't you start us off by giving me a password.\n", player->plr.name); send_to_fd(player->conn, buf); @@ -83,7 +89,7 @@ int step_login(playerc_t *player, int conn_fd) { send_to_fd(player->conn, "Uhhh, something happened. Try again."); printf("%d\n", err); player->state = LoggedOut; - continue; + break; } else { send_to_fd(player->conn, "Sounds good! let's drop you into a world!"); player->state = Complete; @@ -91,10 +97,14 @@ int step_login(playerc_t *player, int conn_fd) { player->plr.level = 1; player->plr.xp = 0; player->plr.location_id = 0; + printf("Trying to write player\n"); try_write_plr(&player->plr); + printf("Done\n"); player->state = Complete; } } + case Complete: ; + return 0; } } @@ -1,7 +1,8 @@ /** - * Creates a socket for the server + * Initializes main game loop and hands off to listeners * */ #include "server.h" +#include <stdlib.h> #include <stdio.h> /** @@ -12,9 +13,7 @@ int main() { int err = 0; server_t server = {0}; - err = server_listen(&server); - if (err) { printf("Failed to listen on address"); return err; diff --git a/src/server.c b/src/server.c index 68fec90..632cb28 100644 --- a/src/server.c +++ b/src/server.c @@ -5,8 +5,15 @@ #include <string.h> #include <sys/socket.h> #include <sys/types.h> +#include <signal.h> #include <unistd.h> +static int socket_fd; + +void closeServer(int dummy) { + shutdown(socket_fd, 2); +} + int server_listen(server_t *server) { /* ** @@ -27,10 +34,19 @@ int server_listen(server_t *server) { struct sockaddr_in server_addr = {0}; + if (signal(SIGINT, closeServer) == SIG_ERR) { + printf("Could not set signal handler\n"); + return -1; + } + server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(8000); + if (setsockopt(server->listen_fd, SOL_SOCKET, SO_REUSEADDR,1,sizeof(1))) { + printf("Could not set SO_REUSEADDR on server socket, continuing\n"); + } + err = bind(server->listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (err == -1) { @@ -39,6 +55,8 @@ int server_listen(server_t *server) { return err; } + socket_fd = server->listen_fd; + err = listen(server->listen_fd, 100); if (err == -1) { perror("listen"); |