/**************************************************************************** ** Eradicated Worlds to Eradicated Worlds 2, user database conversion ** utility. ** Author: Marty **************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <string.h> #include <ctype.h> #include <time.h> #include <gdbm.h> /************************************************************************** ** Global types definitions. **************************************************************************/ typedef struct dlongint { long b3; long b2; long b1; } DoubleLongInt; typedef struct longint { long h; long l; } LongInt; /**************************************************************************** ** Data required for old database ****************************************************************************/ typedef DoubleLongInt OLD_PFLAGS; typedef long int OLD_SFLAGS; typedef LongInt OLD_MFLAGS; typedef long int OLD_QFLAGS; #define OLD_TITLE_LEN 55 /* Max. length of a players title */ #define OLD_PROMPT_LEN 20 /* Max. length of the prompt */ #define OLD_PNAME_LEN 12 /* Max. length of a player-name */ #define OLD_PASSWD_LEN 16 /* Max chars of passwd + 1 */ #define OLD_MAX_EMAIL_LEN 128 /* max chars in email address */ typedef struct _OLD_PERSONA { char p_name[OLD_PNAME_LEN+1]; char p_title[OLD_TITLE_LEN+1]; char p_email[OLD_MAX_EMAIL_LEN+1]; char p_passwd[OLD_PASSWD_LEN]; long int p_home; int p_score; int p_strength; int p_damage; int p_armor; OLD_SFLAGS p_sflags; OLD_PFLAGS p_pflags; OLD_PFLAGS p_mask; OLD_QFLAGS p_quests; int p_vlevel; int p_level; time_t p_last_on; int p_wimpy; long int p_id; } OLD_PERSONA; /****************************************************************************** ** Data for new database ******************************************************************************/ typedef DoubleLongInt NEW_PFLAGS; typedef DoubleLongInt NEW_SFLAGS; typedef LongInt NEW_QFLAGS; #define NEW_TITLE_LEN 55 /* Max. length of a players title */ #define NEW_PROMPT_LEN 80 /* Max. length of the prompt */ #define NEW_PNAME_LEN 12 /* Max. length of a player-name */ #define NEW_PASSWD_LEN 16 /* Max chars of passwd + 1 */ #define NEW_MAX_EMAIL_LEN 128 /* max chars in email address */ typedef struct _NEW_PERSONA { char p_idname[NEW_PNAME_LEN+1]; char p_name[NEW_PNAME_LEN+1]; char p_title[NEW_TITLE_LEN+1]; char p_email[NEW_MAX_EMAIL_LEN+1]; char p_passwd[NEW_PASSWD_LEN]; char p_prompt[NEW_PROMPT_LEN+1]; long int p_home; int p_score; int p_strength; int p_damage; int p_armor; NEW_SFLAGS p_sflags; NEW_PFLAGS p_pflags; NEW_PFLAGS p_mask; NEW_QFLAGS p_quests; int p_vlevel; int p_level; time_t p_last_on; int p_wimpy; long int p_id; int p_pager; /* Unused now, for future expantions */ NEW_SFLAGS spareset1; NEW_SFLAGS spareset2; int p_killed; int p_died; int p_questpoints; /* Spell points */ int p_losses; int spareint5; } NEW_PERSONA; /**************************************************************************** ** Data required for flags, since not all flags are on the same place. ****************************************************************************/ static int questtable[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 23, 25, 18, 22, 26, 24, -1, -1, -1, -1, -1, -1, -1 }; static int pflagtable[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, 34, 24, 22, 23, /* 19 */ 25, 38, 65, 48, 40, 53, 43, 45, 66, 68, 33, 51, 55, 57, 36, 16, 17, 49, 32, 30, /* 39 */ 26, 72, 52, 54, 60, 35, 46, 61, 70, 39, 28, 71, 47, 63, 59, 67, 37, 31, 44, 41, /* 59 */ 29, 42, 58, 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 79 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 89 */ -1, -1, -1, -1, -1, -1 /* 95 */ }; static int sflagtable[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, 29, 34, 33, -1, -1, -1, -1, -1, -1, -1, -1 }; static int QuestPoints[] = { 3, 2, 2, 2, 3, 2, 2, 1, 2, 1, 2, 3, 2, 3, 1, 2, 3, 3, 4, 2, 1, 3, 2, 2, 5, 2, 3, 4, 3, 4, }; #define xtstbit(W,V) ((W) & (1<<(V))) /* Standard DoubleLongInt stuff */ void setdbit(NEW_PFLAGS *f, int bit) { if (bit >= 64) f->b3 |= (1 << (bit-64)); else if (bit >= 32) f->b2 |= (1 << (bit-32)); else f->b1 |= (1 << bit); } int tstdbit(DoubleLongInt *f, int b) { if (b >= 64) return xtstbit(f->b3,b); else if (b >= 32) return xtstbit(f->b2,b); else return xtstbit(f->b1,b); } void convert_quests(NEW_QFLAGS *n, OLD_QFLAGS *o,int *qp) { int i; n->h = n->l = 0; for (i = 0; i < 32; i++) { if (questtable[i] != -1 && xtstbit(*o,i)) { n->l |= (1 << questtable[i]); (*qp) += QuestPoints[(questtable[i])]; } } } void convert_pflags(NEW_PFLAGS *n, OLD_PFLAGS *o) { int i; n->b1 = n->b2 = n->b3 = 0; for (i = 0; i < 96; i++) { if (pflagtable[i] != -1 && tstdbit(o,i)) setdbit(n,pflagtable[i]); } } void convert_sflags(NEW_SFLAGS *n, OLD_SFLAGS *o) { int i; n->b3 = n->b2, n->b1 = 0; for (i=0; i < 32; i++) { if (sflagtable[i] != -1 && xtstbit(*o,i)) setdbit(n,i); } } void old_to_new(OLD_PERSONA *o, NEW_PERSONA *n) { /* Take old fields over */ strncpy(n->p_name,o->p_name,NEW_PNAME_LEN+1); strcpy(n->p_idname,n->p_name); strncpy(n->p_title,o->p_title,NEW_TITLE_LEN+1); strncpy(n->p_email,o->p_email,NEW_MAX_EMAIL_LEN+1); strncpy(n->p_passwd,o->p_passwd,NEW_PASSWD_LEN+1); n->p_id = o->p_id; n->p_wimpy = o->p_wimpy; n->p_last_on = o->p_last_on; n->p_level = o->p_level; n->p_vlevel = o->p_vlevel; n->p_score = o->p_score; n->p_strength = o->p_strength; n->p_damage = o->p_damage; n->p_armor = o->p_armor; n->p_home = 0; /* Can't take over the old home loc */ n->p_sflags.b1 = n->p_sflags.b2 = n->p_sflags.b3 = 0; n->p_questpoints = 0; convert_quests(&n->p_quests,&o->p_quests,&n->p_questpoints); convert_pflags(&n->p_pflags,&o->p_pflags); convert_pflags(&n->p_mask,&o->p_mask); convert_sflags(&n->p_sflags, &o->p_sflags); /* FIll in new fields */ strcpy(n->p_prompt,"&+BEW&+W>&* "); n->p_killed = 0; n->p_died = 0; n->p_losses = 0; n->spareint5 = 0; n->p_pager = 24; n->spareset1.b1 = n->spareset1.b2 = n->spareset1.b3 = 0; n->spareset2.b1 = n->spareset2.b2 = n->spareset2.b3 = 0; } int main(void) { GDBM_FILE oldf; GDBM_FILE newf; OLD_PERSONA o; NEW_PERSONA n; datum old_key; datum old_next; datum old_data; datum new_key; datum new_data; int i=0; oldf = gdbm_open("uaf_rand",sizeof(OLD_PERSONA),GDBM_READER,S_IRUSR|S_IWUSR,NULL); if (oldf == NULL) { printf("Error opening old database file (not in this directory?)\n"); exit(1); } newf = gdbm_open("users_data",sizeof(NEW_PERSONA),GDBM_WRCREAT,S_IRUSR|S_IWUSR,NULL); if (newf == NULL) { printf("Error opening new database (FS full?)\n"); exit(2); } old_key = gdbm_firstkey(oldf); while (old_key.dptr != NULL) { old_data = gdbm_fetch(oldf,old_key); bcopy(old_data.dptr,&o,sizeof(OLD_PERSONA)); if (o.p_name != '\0') { old_to_new(&o,&n); new_key.dptr = n.p_idname; new_key.dsize = strlen(n.p_idname) + 1; new_data.dptr = (char *)&n; new_data.dsize = sizeof(NEW_PERSONA) + 1; gdbm_store(newf,new_key, new_data, GDBM_REPLACE); printf("Player %s converted.\n",n.p_idname); i++; } old_next = gdbm_nextkey(oldf,old_key); if (old_key.dptr != NULL) free(old_key.dptr); if (old_data.dptr != NULL) free(old_data.dptr); old_key = old_next; } gdbm_reorganize(newf); gdbm_close(oldf); gdbm_close(newf); printf("Converted %d users\n",i); printf("Wizards may need a pflagreset, since there are new flags that weren't in\n" "the old one.\n"); return 0; }