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