diff options
author | Cara Salter <cara@devcara.com> | 2022-08-15 23:43:52 -0400 |
---|---|---|
committer | Cara Salter <cara@devcara.com> | 2022-08-15 23:43:52 -0400 |
commit | e6ae01729aeaffc560c59e7887c5743521677e4d (patch) | |
tree | 34ea1333a9c0ce85ac72852cd7fd1b85651dda9d /src/data.c | |
parent | f15f93f6e55d6c09b5f556f8fc8e21c29f549a96 (diff) | |
download | cmud-e6ae01729aeaffc560c59e7887c5743521677e4d.tar.gz cmud-e6ae01729aeaffc560c59e7887c5743521677e4d.zip |
data work
Diffstat (limited to 'src/data.c')
-rw-r--r-- | src/data.c | 131 |
1 files changed, 127 insertions, 4 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; +} |