aboutsummaryrefslogblamecommitdiff
path: root/src/data.c
blob: 8c7ed539316188421e042576f3407e37f8c17917 (plain) (tree)
1
2
3
4
5
6
7
8
9
                   

                   





                     
                   
 

                                                









                                                     
                                                 


                             

                                                                           
                                                                          



                                                                            


     

                                  


                                                       
           
 
                                


                             



                                                   
          



                                                      
   
 
                                 
             
 


             
                                  



                             








                                                                            


              
                                                     


                                





                                           
             


             












































































































                                                                                                                                     
#define _GNU_SOURCE
#include <errno.h>
#include <stdlib.h>
#include "data.h"
#include "login.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
#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);
  err = mkdir("data/players", S_IRWXU);

  return err;
}

int try_load_plr(char *player_name, playerc_t *plr) {
  int err = 0;
  printf("Trying to make data directories...\n");
  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***************************************/
      printf("No permissions to create directories\n");
      return -1;
    default: /* Do nothing because this is fine****************************/
      break;
    }
  }

  printf("Done, opening file.\n");

  char *fname;
  asprintf(&fname, "data/players/%s.plr", player_name);

  FILE *fp;

  if (fp = fopen(fname, "rb")) {

	  printf("Got fp\n");

        if (deserialize_player(fp, &plr->plr)) {
           printf("Couldn't deserialize player\n");
           return -1;
        }
  } else {

            printf("Couldn't open file: %d\n", errno);
            printf("%s", strerror(errno));
            return -1;
  }

  printf("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***************************************/
      printf("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, "wb");

  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;
}