#define _GNU_SOURCE #include #include #include "data.h" #include "login.h" #include "log.h" #include #include #include #include #include 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); err = mkdir("data/players", S_IRWXU); return err; } int try_load_plr(char *player_name, playerc_t *plr) { int err = 0; debug("Trying to make data directories...\n"); try_make_data_dirs(); debug("Done, opening file.\n"); char *fname; asprintf(&fname, "data/players/%s.plr", player_name); FILE *fp; if ((fp = fopen(fname, "r"))) { debug("Got fp\n"); if (deserialize_player(fp, &plr->plr) == EOF) { error("Couldn't deserialize player\n"); return -1; } } else { error("Couldn't open file: %d\n", errno); printf("%s", strerror(errno)); return -1; } debug("Read file into plr\n"); fclose(fp); return err; } int try_write_plr(player_t *plr) { int err = 0; err = try_make_data_dirs(); if (err) { switch (err) { // Now the errors that continue will be from I/O, which we can use to // figure out if the file exists in login case EACCES: /* No permissions***************************************/ error("No permissions to create directories\n"); return -1; default: /* Do nothing because this is fine****************************/ break; } } char *fname; asprintf(&fname, "data/players/%s.plr", plr->name); FILE *fp = fopen(fname, "w"); char* buf = malloc(sizeof(player_t) + 1); serialize_player(plr, fp); 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"); error("Can't open player file"); return -1; } plr->pw_hash = (char*) malloc(512); plr->name = (char*) malloc(32); err = fscanf(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; }