#include <sys/file.h> #include <unistd.h> #include <stdio.h> #include <time.h> #include <sys/stat.h> #include <errno.h> #include <malloc.h> #include "pflags.h" #include "kernel.h" #include "sflags.h" #include "mflags.h" #include "eflags.h" #include "clone.h" #include "nflags.h" #include "uaf.h" #include "mobile.h" #include "flags.h" #include "exit.h" #include "sendsys.h" #include "mud.h" #include "bprintf.h" #include "wizlist.h" #include "bootstrap.h" #include "log.h" #include "parse.h" #include "locations.h" #include "quests.h" #include "utils.h" #include "cflags.h" #include "levels.h" #include "stdlib.h" #include "objsys.h" #include "fight.h" extern int errno; time_t time (time_t * v); extern char *levnam(int lev, int class, Boolean sex); #define UAF_VERSION 6 /* increment to add changes */ #define NUM_ENT 55 /* number of variables to save/load */ #define LLEN 256 /* max length of a pfile line */ #define TOKEN_LEN 11 /* Length of space before value */ #define NOVAL (long int *) 0 #define INT 0 #define CHAR 1 #define PTR 2 typedef struct __iorec { short int type; /* Type of value: int char ptr */ char *token; /* Name of text token */ char **sval; /* String value to load */ long int *ival; /* Integer to load */ } IORec; Boolean save_load_plr(PERSONA *d, char *player, Boolean save, Boolean new) { int i; FILE *fptr = NULL; IORec *pptr = NULL; char *token = NULL; char file[256], line[256], *nptr, *value; IORec p_rec[NUM_ENT] = { /* arrays */ {CHAR, "Title", (char **) &(d->player.ptitle), NOVAL}, {CHAR, "Passwd", (char **) &(d->player.passwd), NOVAL}, {CHAR, "Username", (char **) &(d->rplr.usrname), NOVAL}, {CHAR, "LastHost", (char **) &(d->rplr.hostname), NOVAL}, /* pointers to char */ {PTR, "Awaymsg", &(d->player.awaymsg), NOVAL}, {PTR, "Prompt", &(d->player.prompt), NOVAL}, {PTR, "Setin", &(d->player.setin), NOVAL}, {PTR, "Setout", &(d->player.setout), NOVAL}, {PTR, "Setmin", &(d->player.setmin), NOVAL}, {PTR, "Setmout", &(d->player.setmout), NOVAL}, {PTR, "Setvin", &(d->player.setvin), NOVAL}, {PTR, "Setvout", &(d->player.setvout), NOVAL}, {PTR, "Setqin", &(d->player.setqin), NOVAL}, {PTR, "Setqout", &(d->player.setqout), NOVAL}, {PTR, "Setsit", &(d->player.setsit), NOVAL}, {PTR, "Setstand", &(d->player.setstand), NOVAL}, {PTR, "Setsum", &(d->player.setsum), NOVAL}, {PTR, "Setsin", &(d->player.setsumin), NOVAL}, {PTR, "Setsout", &(d->player.setsumout), NOVAL}, /* integers */ {INT, "PLines", NULL, (long *) &d->player.pager.len}, {INT, "CarryCap", NULL, (long *) &d->player.pcarry}, {INT, "Score", NULL, (long *) &d->ublock.pscore}, {INT, "Strength", NULL, (long *) &d->ublock.pstr}, {INT, "Damage", NULL, (long *) &d->ublock.pdam}, {INT, "Armor", NULL, (long *) &d->ublock.parmor}, {INT, "Visibility", NULL, (long *) &d->ublock.pvis}, {INT, "Level", NULL, (long *) &d->ublock.plev}, {INT, "Wimpy", NULL, (long *) &d->ublock.pwimpy}, {INT, "Magic", NULL, (long *) &d->player.pmagic}, {INT, "Channel", NULL, (long *) &d->player.pchannel}, {INT, "Killed", NULL, (long *) &d->player.pkilled}, {INT, "Died", NULL, (long *) &d->player.pdied}, {INT, "Coins", NULL, (long *) &d->player.coins}, {INT, "Class", NULL, (long *) &d->ublock.class}, /* long ints */ {INT, "FirstOn", NULL, &d->player.first_on}, {INT, "TimeOn", NULL, &d->player.time_on}, {INT, "MortalTime", NULL, &d->player.mortal_time}, {INT, "WizTime", NULL, &d->player.wiz_time}, {INT, "SpellsH", NULL, &d->ublock.pspells.h}, {INT, "SpellsL", NULL, &d->ublock.pspells.l}, {INT, "NFlags", NULL, &d->ublock.pnflags}, {INT, "Home", NULL, &d->ublock.phome}, {INT, "LastOn", NULL, &d->player.last_on}, {INT, "ID", NULL, &d->ublock.id}, {INT, "EFlagsH", NULL, &d->ublock.peflags.h}, {INT, "EFlagsL", NULL, &d->ublock.peflags.l}, {INT, "SFlagsH", NULL, &d->ublock.psflags.h}, {INT, "SFlagsL", NULL, &d->ublock.psflags.l}, {INT, "PFlagsU", NULL, &d->ublock.pflags.u}, {INT, "PFlagsH", NULL, &d->ublock.pflags.h}, {INT, "PFlagsL", NULL, &d->ublock.pflags.l}, {INT, "MaskU", NULL, &d->ublock.pmask.u}, {INT, "MaskH", NULL, &d->ublock.pmask.h}, {INT, "MaskL", NULL, &d->ublock.pmask.l}, {INT, "QFlags", NULL, &d->player.pquests}}; if (!valid_fname(player) && (save || new)) { bprintf("Sorry, that name has illegal characters.\n"); return(False); } for (nptr = player; *nptr; nptr++) if (isalpha(*nptr)) *nptr = tolower(*nptr); *player = toupper(*player); sprintf(file, "%s/%c/%s", TEXT_PFILES_BASE, *player, player); if (save) { if (access(file, F_OK) && !new) /* player zapped */ return(False); else if (!(fptr = FOPEN(file, "w"))) { mudlog("UAF: Cannot store %s", file); return(False); } for (pptr = p_rec ; pptr < p_rec + NUM_ENT ; pptr++) { if (pptr->type == INT && *(pptr->ival)) fprintf(fptr, "%-11s%ld\n", pptr->token, *(pptr->ival)); else if (pptr->type == CHAR && *(pptr->sval)) fprintf(fptr, "%-11s%s\n", pptr->token, (char *) pptr->sval); else if (pptr->type == PTR && *(pptr->sval)) fprintf(fptr, "%-11s%s\n", pptr->token, *(pptr->sval)); } store_parts(fptr, d); for (i = 0 ; i < NUM_STORE_SLOTS ; i++) if (d->rplr.storage[i] != -1) fprintf(fptr, "Storage %s\n", oname(d->rplr.storage[i])); } else { /* load */ memset(d, 0, sizeof(PERSONA)); if (!(fptr = FOPEN(file, "r"))) { if (!access(file, F_OK)) mudlog("UAF: Cannot load %s", file); return(False); } strcpy(d->ublock.pname, player); for (i = 0 ; i < NUM_STORE_SLOTS ; i++) d->rplr.storage[i] = -1; while (!feof(fptr)) { fgets(line, LLEN, fptr); if (strlen(line) < TOKEN_LEN + 1) { mudlog("UAF: Error in player record %s", player); continue; } line[strlen(line) - 1] = 0; token = line; value = line + TOKEN_LEN; if (!strncmp(token, "Bodyparts", 9)) load_parts(value, d); else if (!strncmp(token, "Storage", 7)) { for (i = 0 ; i < NUM_STORE_SLOTS ; i++) /* free storage slot */ if (d->rplr.storage[i] == -1) { d->rplr.storage[i] = fobn(value); break; } } else { /* table */ for (pptr = p_rec ; pptr < p_rec + NUM_ENT ; pptr++) if (!strncmp(pptr->token, token, strlen(pptr->token))) { if (pptr->type == INT) *(pptr->ival) = atol(value); else if (pptr->type == CHAR) strcpy((char *) pptr->sval, value); else if (pptr->type == PTR) *(pptr->sval) = COPY(value); break; } if (pptr == p_rec + NUM_ENT) mudlog("UAF: Unknown token in %s: %s", player, token); } } } FCLOSE(fptr); return(True); } void pers2player (PERSONA * d, int plx) { int i; memcpy(&ublock[plx], &(d->ublock), sizeof(UBLOCK_REC)); memcpy(&players[plx], &(d->player), sizeof(PLAYER_REC)); if (plev(plx) < LVL_WIZARD) setpvis(plx, 0); pangry(plx) = -1; for (i = 0 ; i < NUM_STORE_SLOTS ; i++) { rplrs[plx].storage[i] = -1; if (d->rplr.storage[i] != -1) clone_object(d->rplr.storage[i], -1, NULL, plx, CARRIED_BY); } reset_armor(False, plx); set_player_parts(plx); players[plx].resfd = -1; oldscore(plx) = pscore(plx); pfighting(plx) = -1; phelping(plx) = -1; is_conn(plx) = True; } void player2pers (PERSONA *d, time_t *last_on, int plx) { if (plx < max_players) { memcpy(&(d->player), &players[plx], sizeof(PLAYER_REC)); memcpy(&(d->rplr), &rplrs[plx], sizeof(RPLR_REC)); } memcpy(&(d->ublock), &ublock[plx], sizeof(UBLOCK_REC)); if (last_on != NULL) { d->player.last_on = *last_on; if (rplrs[plx].logged_on) { d->player.time_on += *last_on - rplrs[plx].logged_on; if (plev(plx) < LVL_WIZARD) d->player.mortal_time += *last_on - rplrs[plx].logged_on; } } } void get_gender (char *gen) { Boolean ok = False; Boolean female = False; PERSONA d; if (gen == NULL) replace_input_handler (get_gender); else if (*gen == 'M' || *gen == 'm') ok = True; else if (*gen == 'F' || *gen == 'f') ok = female = True; else bprintf ("M or F"); if (ok) { if (OPERATOR (pname (mynum))) { setplev (mynum, LVL_CREATOR); sprintf (ptitle (mynum), "%%s the %s", player_level(mynum)); setpstr (mynum, pmaxstrength (LVL_CREATOR)); setpscore (mynum, levels[wlevel(LVL_CREATOR)]); update_wizlist (pname (mynum), wlevel(LVL_CREATOR)); } else { setplev (mynum, 1); sprintf (ptitle (mynum), "%%s the %s", player_level(mynum)); setpstr (mynum, 40); } setpwimpy (mynum, 25); mob_id (mynum) = id_counter++; setpdam (mynum, 8); if (female) ssetflg (mynum, SFL_FEMALE); set_xpflags (plev (mynum), &(pflags (mynum)), &(pmask (mynum))); setppager (mynum, 24); if (female) xsetbit (d.ublock.psflags.l, SFL_FEMALE); /* defaults */ ssetflg(mynum, SFL_AUTOEXIT); ssetflg(mynum, SFL_HEARBACK); ssetflg(mynum, SFL_NEWSTYLE); psetflg(mynum, PFL_ABERCHAT); nsetflg(mynum, NFL_ENGLISH); set_player_parts(mynum); set_vital(mynum); reset_armor(False, mynum); player2pers (&d, &global_clock, mynum); d.player.first_on = players[mynum].first_on = global_clock; newuaf (&d); save_id_counter (); do_motd (NULL); } else { bprintf ("\n"); strcpy (cur_player->cprompt, "Sex (M/F) : "); } } void saveother (void) { int p; static PERSONA d; if (EMPTY (item1)) p = mynum; else { if ((p = pl1) == -1) { bprintf ("Cannot find player.\n"); return; } if (plev (mynum) < LVL_WIZARD && p != mynum) { bprintf ("You cannot save another player!\n"); return; } } if (aliased(p)) { bprintf ("Not while aliased.\n"); return; } player2pers (&d, &global_clock, p); putuaf (&d); if (p != mynum) sendf (mynum, "&+M[%s Saved]\n", pname (p)); else bprintf ("&+M[Player Saved]\n", pname (mynum)); } void saveme (Boolean silent) { static PERSONA d; if (aliased(real_mynum)) { bprintf ("Not while aliased.\n"); return; } player2pers (&d, &global_clock, mynum); putuaf (&d); if (!silent) bprintf ("&+M[Player Saved]\n"); } void saveallcom (void) { static PERSONA d; int i; if (plev (mynum) < LVL_WIZARD) { erreval (); return; } for (i = 0; i < max_players; ++i) { if (is_in_game (i)) { if (aliased(i)); else { player2pers (&d, &global_clock, i); putuaf (&d); } } } bprintf ("&+M[Saved All Players]\n"); send_msg (DEST_ALL, MODE_QUIET, LVL_WIZARD, LVL_MAX, mynum, NOBODY, "&+B[&+CSaveall &*by &+W\001p%s\003&+B]\n", pname (mynum)); } char *ipname (int plr) { static char name[30]; sprintf (name, "\001p%s\003", pname (plr)); return name; } char *build_setin (int type, char *notused, char *s, char *n, char *d, char *v){ char *p, *q, *r; char temp[SETIN_MAX]; static char buff[SETIN_MAX + PNAME_LEN * 2]; /* allows for 2 victims */ if(s == NULL) { switch(type) { default: mudlog("Unknown type passed to build_setin: %d!", type); return NULL; case SETIN_SETIN: strcpy(temp, DEFAULT_SETIN); break; case SETIN_SETOUT: strcpy(temp, DEFAULT_SETOUT); break; case SETIN_SETMIN: strcpy(temp, DEFAULT_SETMIN); break; case SETIN_SETMOUT: strcpy(temp, DEFAULT_SETMOUT); break; case SETIN_SETVIN: strcpy(temp, DEFAULT_SETVIN); break; case SETIN_SETVOUT: strcpy(temp, DEFAULT_SETVOUT); break; case SETIN_SETQIN: strcpy(temp, DEFAULT_SETQIN); break; case SETIN_SETQOUT: strcpy(temp, DEFAULT_SETQOUT); break; case SETIN_SETSIT: strcpy(temp, DEFAULT_SETSIT); break; case SETIN_SETSTAND: strcpy(temp, DEFAULT_SETSTAND); break; case SETIN_SETSUM: strcpy(temp, DEFAULT_SETSUM); break; case SETIN_SETSUMIN: strcpy(temp, DEFAULT_SETSUMIN); break; case SETIN_SETSUMOUT: strcpy(temp, DEFAULT_SETSUMOUT); break; } s = temp; } for (p = buff, q = s; *q;) { if (*q != '%') *p++ = *q++; else { switch (*++q) { case 'n': if (n) sprintf(p, "\001p%s\003", n); p += strlen(n) + 3; break; case 'v': if (v) sprintf(p, "\001p%s\003", v); p += strlen(v) + 3; break; case 'd': if (d) for (r = d; *r;) *p++ = *r++; break; case 'N': for (r = xname (n); *r != 0;) *p++ = *r++; break; case 'f': for (r = (psex (mynum) ? "her" : "his"); *r != 0;) *p++ = *r++; break; case 'F': for (r = (psex (mynum) ? "her" : "him"); *r != 0;) *p++ = *r++; break; case 0: --q; break; default: *p++ = *q; } ++q; } } if (p[-1] == '\n') --p; *p = 0; return buff; } Boolean getuafinfo (char *name) { PERSONA d; Boolean b; b = getuaf (name, &d); if (b) { pers2player (&d, mynum); setpname (mynum, d.ublock.pname); } return b; } int deluaf(char *name) { char *nptr, file[256]; if (!valid_fname(name)) { bprintf("Player name contains illegal characters.\n"); return(1); } for (nptr = name; *nptr; nptr++) if (isalpha(*nptr)) *nptr = tolower(*nptr); *name = toupper(*name); sprintf(file, "%s/%c/%s", TEXT_PFILES_BASE, *name, name); if (unlink(file) == -1) return(1); return(0); }