void save_text(struct char_data * ch) { FILE *fil = NULL; char fname[MAX_INPUT_LENGTH]; struct alias *al; if (IS_NPC(ch)) { return; } if (!get_filename(GET_NAME(ch), fname, ETEXT_FILE)) { return; } if (!(fil = fopen(fname, "w"))) { return; } al = ch->player_specials->aliases; while (al) { fprintf(fil, "%d\n", al->type); fprintf(fil, "%s\n", al->alias); fprintf(fil, "%s\n", al->replacement); al = al->next; } fprintf(fil, "-1\n"); /* End of alias segment */ if (WHOSPEC(ch)) { fprintf(fil, "%s\n", WHOSPEC(ch)); } else { fprintf(fil, "!UNUSED!\n"); } if (POOFIN(ch)) { fprintf(fil, "%s\n", POOFIN(ch)); } else { fprintf(fil, "!UNUSED!\n"); } if (POOFOUT(ch)) { fprintf(fil, "%s\n", POOFOUT(ch)); } else { fprintf(fil, "!UNUSED!\n"); } if (WHOSTR(ch)) { fprintf(fil, "%s\n", WHOSTR(ch)); } else { fprintf(fil, "!UNUSED!\n"); } if (ch->desc && NAMECOLOR(ch)) { fprintf(fil, "%s\n", NAMECOLOR(ch)); } else { fprintf(fil, "!UNUSED!\n"); } fclose(fil); return; }
// Create a brand new character struct creature * account_create_char(struct account *account, const char *name) { struct creature *ch; int i; if (chars_available(account) <= 0) return NULL; ch = make_creature(true); ch->player.name = strdup(tmp_capitalize(tmp_tolower(name))); ch->char_specials.saved.idnum = top_player_idnum() + 1; account->chars = g_list_append(account->chars, GINT_TO_POINTER(GET_IDNUM(ch))); sql_exec ("insert into players (idnum, name, account) values (%ld, '%s', %d)", GET_IDNUM(ch), tmp_sqlescape(name), account->id); // New characters shouldn't get old mail. if (has_mail(GET_IDNUM(ch))) { if (purge_mail(GET_IDNUM(ch)) > 0) { errlog("Purging pre-existing mailfile for new character.(%s)", GET_NAME(ch)); } } // *** if this is our first player --- he be God *** if (GET_IDNUM(ch) == 1) { GET_EXP(ch) = 160000000; GET_LEVEL(ch) = LVL_GRIMP; ch->points.max_hit = 666; ch->points.max_mana = 555; ch->points.max_move = 444; GET_HOME(ch) = HOME_MODRIAN; ch->player_specials->saved.load_room = -1; ch->player_specials->saved.home_room = 1204; } else { ch->points.max_hit = 100; ch->points.max_mana = 100; ch->points.max_move = 82; GET_HOME(ch) = HOME_NEWBIE_SCHOOL; ch->player_specials->saved.load_room = -1; ch->player_specials->saved.home_room = -1; } ch->player_specials->rentcode = RENT_CREATING; set_title(ch, ""); ch->player.short_descr = NULL; ch->player.long_descr = NULL; ch->player.description = NULL; ch->player.time.birth = time(NULL); ch->player.time.death = 0; ch->player.time.played = 0; ch->player.time.logon = time(NULL); for (i = 0; i < MAX_SKILLS; i++) ch->player_specials->saved.skills[i] = 0; for (i = 0; i < MAX_WEAPON_SPEC; i++) { ch->player_specials->saved.weap_spec[i].vnum = 0; ch->player_specials->saved.weap_spec[i].level = 0; } ch->player_specials->saved.imm_qp = 0; ch->player_specials->saved.quest_id = 0; ch->player_specials->saved.qlog_level = 0; GET_REMORT_CLASS(ch) = -1; ch->player.weight = 100; ch->player.height = 100; ch->points.hit = GET_MAX_HIT(ch); ch->points.mana = GET_MAX_MANA(ch); ch->points.move = GET_MAX_MOVE(ch); ch->points.armor = 100; SET_BIT(PRF_FLAGS(ch), PRF_DISPHP | PRF_DISPMANA | PRF_DISPMOVE | PRF_AUTOEXIT | PRF_NOSPEW | PRF_NOPLUG); SET_BIT(PRF2_FLAGS(ch), PRF2_AUTO_DIAGNOSE | PRF2_AUTOPROMPT | PRF2_DISPALIGN | PRF2_NEWBIE_HELPER); ch->char_specials.saved.affected_by = 0; ch->char_specials.saved.affected2_by = 0; ch->char_specials.saved.affected3_by = 0; for (i = 0; i < 5; i++) GET_SAVE(ch, i) = 0; GET_COND(ch, FULL) = (GET_LEVEL(ch) == LVL_GRIMP ? -1 : 24); GET_COND(ch, THIRST) = (GET_LEVEL(ch) == LVL_GRIMP ? -1 : 24); GET_COND(ch, DRUNK) = (GET_LEVEL(ch) == LVL_GRIMP ? -1 : 0); POOFIN(ch) = NULL; POOFOUT(ch) = NULL; return ch; }
/* * Read in a char. */ int fread_char( struct char_data *ch, FILE *fp ) { int error_count = 0; char *word; char buf [ MAX_STRING_LENGTH ]; struct affected_type *paf; int sn; int i; int j; int status; int status1; char *p; int tmpi; int num_keys; int last_key = 0; char def_sdesc [] = "Your short description was corrupted."; char def_ldesc [] = "Your long description was corrupted."; char def_desc [] = "Your description was corrupted."; char def_title [] = "Your title was corrupted."; struct key_data key_tab [] = { { "ShtDsc", TRUE, (int) &def_sdesc, { &GET_SHORT_DESC(ch), NULL } }, { "LngDsc", TRUE, (int) &def_ldesc, { &GET_LONG_DESC(ch), NULL } }, { "Dscr", TRUE, (int) &def_desc, { &GET_DESCRIPTION(ch), NULL } }, { "Sx", FALSE, SEX_MALE, { &GET_SEX(ch), NULL } }, { "Race", FALSE, MAND, { &GET_RACE(ch), NULL } }, { "Lvl", FALSE, MAND, { &GET_LEVEL(ch), NULL } }, { "Trst", FALSE, 0, { &GET_TRUST(ch), NULL } }, { "HpMnMv", FALSE, MAND, { &GET_HIT(ch), &GET_MAX_HIT(ch), &GET_MANA(ch), &GET_MAX_MANA(ch), &GET_MOVE(ch), &GET_MAX_MOVE(ch), NULL } }, { "Gold", FALSE, 0, { &GET_GOLD(ch), NULL } }, { "Exp", FALSE, MAND, { &GET_EXP(ch), NULL } }, { "Act", FALSE, DEFLT, { &PLR_FLAGS(ch), NULL } }, { "Act2", FALSE, DEFLT, { &PLR2_FLAGS(ch), NULL } }, { "AffdBy", FALSE, 0, { &AFF_FLAGS(ch), NULL } }, { "AffdBy2", FALSE, 0, { &AFF2_FLAGS(ch), NULL } }, { "Pref", FALSE, 0, { &PRF_FLAGS(ch), NULL } }, { "Pref2", FALSE, 0, { &PRF2_FLAGS(ch), NULL } }, { "Pos", FALSE, POS_STANDING, { &GET_POS(ch), NULL } }, { "Prac", FALSE, MAND, { &GET_PRACTICES(ch), NULL } }, { "PAlign", FALSE, 0, { &GET_PERMALIGN(ch), NULL } }, { "CAlign", FALSE, 0, { &GET_ALIGNMENT(ch), NULL } }, { "Ttle", TRUE, (int) &def_title, { &GET_TITLE(ch), NULL } }, #if 0 { "SavThr", FALSE, MAND, { &ch->saving_throw, NULL } }, { "Hit", FALSE, MAND, { &ch->hitroll, NULL } }, { "Dam", FALSE, MAND, { &ch->damroll, NULL } }, { "Armr", FALSE, MAND, { &ch->armor, NULL } }, { "Wimp", FALSE, 10, { &ch->wimpy, NULL } }, { "Deaf", FALSE, 0, { &ch->deaf, NULL } }, { "Immskll",TRUE, DEFLT, { &ch->pcdata->immskll, NULL } }, { "AtrPrm", FALSE, MAND, { &ch->pcdata->perm_str, &ch->pcdata->perm_int, &ch->pcdata->perm_wis, &ch->pcdata->perm_dex, &ch->pcdata->perm_con, NULL } }, { "AtrMd", FALSE, MAND, { &ch->pcdata->mod_str, &ch->pcdata->mod_int, &ch->pcdata->mod_wis, &ch->pcdata->mod_dex, &ch->pcdata->mod_con, NULL } }, { "Cond", FALSE, DEFLT, { &ch->pcdata->condition [0], &ch->pcdata->condition [1], &ch->pcdata->condition [2], NULL } }, { "Pglen", FALSE, 20, { &ch->pcdata->pagelen, NULL } }, { "Playd", FALSE, 0, { &ch->played, NULL } }, #endif { "Paswd", TRUE, MAND, { &GET_PASSWD(ch), NULL } }, { "Poofin", TRUE, DEFLT, { &POOFIN(ch), NULL } }, { "Poofout", TRUE, DEFLT, { &POOFOUT(ch), NULL } }, { "\0", FALSE, 0 } }; for ( num_keys = 0; *key_tab [num_keys].key; ) num_keys++; for ( ; !feof (fp) ; ) { word = fread_word_stat( fp, &status ); if ( !word ) { log( "fread_char: Error reading key. EOF?" ); fread_to_eol( fp ); break; } /* This little diddy searches for the keyword from the last keyword found */ for ( i = last_key; i < last_key + num_keys && str_cmp (key_tab [i % num_keys].key, word); ) i++; i = i % num_keys; if ( !str_cmp (key_tab [i].key, word) ) last_key = i; else i = num_keys; if ( *key_tab [i].key ) /* Key entry found in key_tab */ { if ( key_tab [i].string == SPECIFIED ) log( "Key already specified." ); /* Entry is a string */ else if ( key_tab [i].string ) { if ( ( p = fread_string( fp, (char*)&status ) ) && !status ) { free( *(char **)key_tab [i].ptrs [0] ); *(char **)key_tab [i].ptrs [0] = p; } } /* Entry is an integer */ else for ( j = 0; key_tab [i].ptrs [j]; j++ ) { tmpi = fread_number_stat( fp, &status ); if ( !status ) *(int *)key_tab [i].ptrs [j] = tmpi; } if ( status ) { fread_to_eol( fp ); continue; } else key_tab [i].string = SPECIFIED; } else if ( *word == '*' || !str_cmp( word, "Nm" ) ) fread_to_eol( fp ); else if ( !str_cmp( word, "End" ) ) break; else if ( !str_cmp( word, "Room" ) ) { ch->in_room = fread_number_stat( fp, &status ); if ( !ch->in_room ) ch->in_room = NOWHERE; } else if ( !str_cmp( word, "Race" ) ) { i = race_lookup( fread_string( fp, (char*)&status ) ); if ( status ) log( "Fread_char: Unknown Race." ); else GET_RACE(ch) = i; } else if ( !str_cmp( word, "Skill" ) ) { i = fread_number_stat( fp, &status ); sn = skill_lookup( fread_word_stat( fp, &status1 ) ); if ( status || status1 ) { log( "Fread_char: Error reading skill." ); fread_to_eol( fp ); continue; } if ( sn < 0 ) log( "Fread_char: unknown skill." ); else GET_SKILL(ch, sn) = i; } else if ( !str_cmp ( word, "Afft" ) ) { int status; CREATE(paf, struct affected_type, 1); memset(paf, 0, sizeof( struct affected_type )); paf->type = skill_lookup( fread_string( fp, (char*)&status ) ); paf->duration = fread_number_stat( fp, &status ); paf->modifier = fread_number_stat( fp, &status ); paf->location = fread_number_stat( fp, &status ); paf->bitvector = fread_number_stat( fp, &status ); paf->next = ch->affected; ch->affected = paf; } else {
/* * Load a char and inventory into a new ch structure. */ bool load_char_obj( struct descriptor_data * d, const char * name ) { FILE *fp; struct char_data *ch; char strsave [ MAX_INPUT_LENGTH ]; bool found; char sorry_player [] = "********************************************************\n\r" "** One or more of the critical fields in your player **\n\r" "** file were corrupted since you last played. Please **\n\r" "** contact an administrator or programmer to **\n\r" "** investigate the recovery of your characters. **\n\r" "********************************************************\n\r"; char sorry_object [] = "********************************************************\n\r" "** One or more of the critical fields in your player **\n\r" "** file were corrupted leading to the loss of one or **\n\r" "** more of your possessions. **\n\r" "********************************************************\n\r"; char sorry_alias [] = "********************************************************\n\r" "** One or more of the critical fields in your player **\n\r" "** file were corrupted leading to the loss of one or **\n\r" "** more of your aliases. **\n\r" "********************************************************\n\r"; ch = new_character( TRUE ); d->character = ch; GET_DESC(ch) = d; ch->player.name = str_dup( name ); /* ch->pcdata->prompt = str_dup( daPrompt ); ch->last_note = 0; */ strcpy( GET_PASSWD(ch), "" ); POOFIN(ch) = str_dup( "" ); POOFOUT(ch) = str_dup( "" ); GET_TITLE(ch) = str_dup( "" ); GET_STR(ch) = 10; GET_ADD(ch) = 10; GET_INT(ch) = 10; GET_WIS(ch) = 10; GET_DEX(ch) = 10; GET_CON(ch) = 10; GET_CHA(ch) = 10; GET_WILL(ch) = 10; GET_COND(ch, DRUNK) = 48; GET_COND(ch, FULL) = 48; GET_COND(ch, THIRST) = 48; GET_COND(ch, TIRED) = 48; // ch->pcdata->switched = FALSE; found = FALSE; fclose( fpReserve ); /* parsed player file directories by Yaz of 4th Realm */ /* decompress if .gz file exists - Thx Alander */ sprintf( strsave, "%s/%s/%s%s", PLAYER_DIR, player_dir( GET_NAME(ch) ), capitalize( GET_NAME(ch) ), ".gz" ); if ( ( fp = fopen( strsave, "r" ) ) ) { char buf [ MAX_STRING_LENGTH ]; fclose( fp ); sprintf( buf, "gzip -dfq %s", strsave ); system( buf ); } sprintf( strsave, "%s/%s/%s", PLAYER_DIR, player_dir( GET_NAME(ch) ), capitalize( GET_NAME(ch) ) ); if ( ( fp = fopen( strsave, "r" ) ) ) { char buf[ MAX_STRING_LENGTH ]; int iNest; for ( iNest = 0; iNest < MAX_NEST; iNest++ ) rgObjNest[iNest] = NULL; found = TRUE; for ( ; ; ) { char *word; char letter; int status; letter = fread_letter( fp ); if ( letter == '*' ) { fread_to_eol( fp ); continue; } if ( letter != '#' ) { log( "Load_char_obj: # not found." ); break; } word = fread_word_stat( fp, &status ); if ( !str_cmp( word, "PLAYER" ) ) { if ( fread_char ( ch, fp ) ) { sprintf( buf, "Load_char_obj: %s section PLAYER corrupt.\n\r", name ); log( buf ); SEND_TO_Q( sorry_player, d ); /* * In case you are curious, * it is ok to leave ch alone for close_socket * to free. * We want to now kick the bad character out as * what we are missing are MANDATORY fields. -Kahn */ SET_BIT( PRF_FLAGS(ch), PLR_DELETED ); return TRUE; } } else if ( !str_cmp( word, "OBJECT" ) ) { if ( !fread_obj_char( ch, fp ) ) { sprintf( buf, "Load_char_obj: %s section OBJECT corrupt.\n\r", name ); log( buf ); SEND_TO_Q( sorry_object, d ); return FALSE; } } else if ( !str_cmp( word, "ALIAS" ) ) { if ( !fread_alias( ch, fp ) ) { sprintf( buf, "Load_char_obj: %s section ALIAS corrupt.\n\r", name ); log( buf ); SEND_TO_Q( sorry_alias, d ); return FALSE; } } else if ( !str_cmp( word, "END" ) ) break; else { log( "Load_char_obj: bad section." ); break; } } /* for */ fclose( fp ); } fpReserve = fopen( NULL_FILE, "r" ); if ( found ) rent_adjust( d->character ); return found; }
/* * Write the char to the file. * * @param ch the character to be written * @param fp the file to write to */ void fwrite_char( struct char_data *ch, FILE *fp ) { extern struct race_data * races; struct affected_type *paf; int sn, i; fprintf( fp, "#%s\n", IS_NPC( ch ) ? "MOB" : "PLAYER" ); fprintf( fp, "Name %s~\n", GET_NAME(ch) ); fprintf( fp, "ShtDsc %s~\n", GET_SHORT_DESC(ch) ? GET_SHORT_DESC(ch) : "" ); fprintf( fp, "LngDsc %s~\n", GET_LONG_DESC(ch) ? GET_LONG_DESC(ch) : "" ); fprintf( fp, "Dscr %s~\n", GET_DESCRIPTION(ch) ? GET_DESCRIPTION(ch) : "" ); // fprintf( fp, "Prmpt %s~\n", ch->pcdata->prompt ); fprintf( fp, "Sx %d\n", GET_SEX(ch) ); fprintf( fp, "Race %s~\n", races[ (int)GET_RACE(ch) ].name ); fprintf( fp, "Lvl %d\n", GET_LEVEL(ch) ); fprintf( fp, "Trst %d\n", GET_TRUST(ch) ); /* fprintf( fp, "Playd %ld\n", GET_PLAYED(ch) + (int)( time( 0 ) - GET_LOGON(ch) ) ); */ // fprintf( fp, "Note %ld\n", (unsigned long)ch->last_note ); fprintf( fp, "Room %ld\n", ( ch->in_room == NOWHERE && ch->was_in_room ) ? ch->was_in_room : ch->in_room ); fprintf( fp, "HpMnMv %d %d %d %d %d %d\n", GET_HIT(ch), GET_MAX_HIT(ch), GET_MANA(ch), GET_MAX_MANA(ch), GET_MOVE(ch), GET_MAX_MOVE(ch) ); fprintf( fp, "Gold %ld\n", GET_GOLD(ch) ); fprintf( fp, "Exp %ld\n", GET_EXP(ch) ); fprintf( fp, "Act %lld\n", PLR_FLAGS(ch) ); fprintf( fp, "Act2 %lld\n", PLR2_FLAGS(ch) ); fprintf( fp, "Pref %lld\n", PRF_FLAGS(ch) ); fprintf( fp, "Pref2 %lld\n", PRF2_FLAGS(ch) ); fprintf( fp, "AffdBy %lld\n", AFF_FLAGS(ch) ); fprintf( fp, "AffdBy2 %lld\n", AFF2_FLAGS(ch) ); /* Bug fix from Alander */ fprintf( fp, "Pos %d\n", GET_POS(ch) == POS_FIGHTING ? POS_STANDING : GET_POS(ch) ); fprintf( fp, "Prac %d\n", GET_PRACTICES(ch) ); fprintf( fp, "PAlign %d\n", GET_PERMALIGN(ch) ); fprintf( fp, "CAlign %d\n", GET_ALIGNMENT(ch) ); fprintf( fp, "SavThr " ); for ( i = 0; i < NUM_SAVES; i++ ) fprintf( fp, "%d%s", GET_SAVE(ch, i), (i != NUM_SAVES-1 ? ", " : "\n") ); fprintf( fp, "Hitroll %d\n", GET_HITROLL(ch) ); fprintf( fp, "Damroll %d\n", GET_DAMROLL(ch) ); fprintf( fp, "Armr " ); for ( i = 0; i < ARMOR_LIMIT; i++ ) fprintf( fp, "%d%s", GET_AC(ch, i), (i != ARMOR_LIMIT-1 ? ", " : "\n") ); fprintf( fp, "Wimp %d\n", GET_WIMP_LEV(ch) ); if ( IS_NPC( ch ) ) { fprintf( fp, "Vnum %ld\n", GET_MOB_VNUM(ch) ); } else { fprintf( fp, "Paswd %s~\n", GET_PASSWD(ch) ); fprintf( fp, "Poofin %s~\n", POOFIN(ch) ? POOFIN(ch) : "" ); fprintf( fp, "Poofout %s~\n", POOFOUT(ch) ? POOFOUT(ch) : "" ); fprintf( fp, "Ttle %s~\n", GET_TITLE(ch) ? GET_TITLE(ch) : "" ); fprintf( fp, "AtrPrm %d/%d %d %d %d %d %d %d\n", ch->real_abils.str, ch->real_abils.str_add, ch->real_abils.intel, ch->real_abils.wis, ch->real_abils.dex, ch->real_abils.con, ch->real_abils.cha, ch->real_abils.will ); fprintf( fp, "AtrMd %d/%d %d %d %d %d %d %d\n", ch->aff_abils.str, ch->aff_abils.str_add, ch->aff_abils.intel, ch->aff_abils.wis, ch->aff_abils.dex, ch->aff_abils.con, ch->aff_abils.cha, ch->aff_abils.will ); fprintf( fp, "Conditions " ); for ( i = 0; i < MAX_COND; i++ ) fprintf( fp, "%d%s", GET_COND(ch, i), (i != MAX_COND-1 ? ", " : "\n") ); fprintf( fp, "Addictions " ); for ( i = 0; i < MAX_COND; i++ ) fprintf( fp, "%d%s", GET_ADDICT(ch, i), (i != MAX_COND-1 ? ", " : "\n") ); for ( sn = 0; sn < MAX_SKILLS; sn++ ) { if ( skill_name( sn ) && strcmp( skill_name( sn ), "!UNUSED!" ) && GET_SKILL(ch, sn) > 0 ) { fprintf( fp, "Skill %d '%s'\n", GET_SKILL(ch, sn), skill_name( sn ) ); } } } for ( paf = ch->affected; paf; paf = paf->next ) { fprintf( fp, "Afft %18s~ %3d %3d %3d %lld\n", skill_name( paf->type ), paf->duration, paf->modifier, paf->location, paf->bitvector ); } for ( paf = ch->affected2; paf; paf = paf->next ) { fprintf( fp, "Afft2 %18s~ %3d %3d %3d %lld\n", skill_name( paf->type ), paf->duration, paf->modifier, paf->location, paf->bitvector ); } fprintf( fp, "End\n\n" ); return; }
struct creature * load_player_from_file(const char *path) { struct creature *ch = NULL; char *txt; if (access(path, W_OK)) { errlog("Unable to open xml player file '%s': %s", path, strerror(errno)); return NULL; } xmlDocPtr doc = xmlParseFile(path); if (!doc) { errlog("XML parse error while loading %s", path); return NULL; } xmlNodePtr root = xmlDocGetRootElement(doc); if (!root) { xmlFreeDoc(doc); errlog("XML file %s is empty", path); return NULL; } /* to save memory, only PC's -- not MOB's -- have player_specials */ ch = make_creature(true); ch->player.name = (char *)xmlGetProp(root, (xmlChar *) "name"); ch->char_specials.saved.idnum = xmlGetIntProp(root, "idnum", 0); set_title(ch, ""); ch->player.short_descr = NULL; ch->player.long_descr = NULL; if (ch->points.max_mana < 100) ch->points.max_mana = 100; ch->char_specials.carry_weight = 0; ch->char_specials.carry_items = 0; ch->char_specials.worn_weight = 0; ch->points.armor = 100; ch->points.hitroll = 0; ch->points.damroll = 0; ch->player_specials->saved.speed = 0; // Read in the subnodes for (xmlNodePtr node = root->xmlChildrenNode; node; node = node->next) { if (xmlMatches(node->name, "points")) { ch->points.mana = xmlGetIntProp(node, "mana", 100); ch->points.max_mana = xmlGetIntProp(node, "maxmana", 100); ch->points.hit = xmlGetIntProp(node, "hit", 100); ch->points.max_hit = xmlGetIntProp(node, "maxhit", 100); ch->points.move = xmlGetIntProp(node, "move", 100); ch->points.max_move = xmlGetIntProp(node, "maxmove", 100); } else if (xmlMatches(node->name, "money")) { ch->points.gold = xmlGetIntProp(node, "gold", 0); ch->points.cash = xmlGetIntProp(node, "cash", 0); ch->points.exp = xmlGetIntProp(node, "xp", 0); } else if (xmlMatches(node->name, "stats")) { ch->player.level = xmlGetIntProp(node, "level", 0); ch->player.height = xmlGetIntProp(node, "height", 0); ch->player.weight = xmlGetIntProp(node, "weight", 0); GET_ALIGNMENT(ch) = xmlGetIntProp(node, "align", 0); /*** Temp fix for negative weights ***/ if (ch->player.weight < 0) { calculate_height_weight(ch); } GET_SEX(ch) = 0; char *sex = (char *)xmlGetProp(node, (xmlChar *) "sex"); if (sex != NULL) GET_SEX(ch) = search_block(sex, genders, false); free(sex); GET_RACE(ch) = 0; char *race_name = (char *)xmlGetProp(node, (xmlChar *) "race"); if (race_name != NULL) { struct race *race = race_by_name(race_name, true); if (race != NULL) { GET_RACE(ch) = race->idnum; } } free(race_name); } else if (xmlMatches(node->name, "class")) { GET_OLD_CLASS(ch) = GET_REMORT_CLASS(ch) = GET_CLASS(ch) = -1; char *trade = (char *)xmlGetProp(node, (xmlChar *) "name"); if (trade != NULL) { GET_CLASS(ch) = search_block(trade, class_names, false); free(trade); } trade = (char *)xmlGetProp(node, (xmlChar *) "remort"); if (trade != NULL) { GET_REMORT_CLASS(ch) = search_block(trade, class_names, false); free(trade); } if (IS_CYBORG(ch)) { char *subclass = (char *)xmlGetProp(node, (xmlChar *) "subclass"); if (subclass != NULL) { GET_OLD_CLASS(ch) = search_block(subclass, borg_subchar_class_names, false); free(subclass); } } if (GET_CLASS(ch) == CLASS_MAGE) { ch->player_specials->saved.mana_shield_low = xmlGetLongProp(node, "manash_low", 0); ch->player_specials->saved.mana_shield_pct = xmlGetLongProp(node, "manash_pct", 0); } GET_REMORT_GEN(ch) = xmlGetIntProp(node, "gen", 0); GET_TOT_DAM(ch) = xmlGetIntProp(node, "total_dam", 0); GET_BROKE(ch) = xmlGetIntProp(node, "broken", 0); } else if (xmlMatches(node->name, "time")) { ch->player.time.birth = xmlGetLongProp(node, "birth", 0); ch->player.time.death = xmlGetLongProp(node, "death", 0); ch->player.time.played = xmlGetLongProp(node, "played", 0); ch->player.time.logon = xmlGetLongProp(node, "last", 0); } else if (xmlMatches(node->name, "carnage")) { GET_PKILLS(ch) = xmlGetIntProp(node, "pkills", 0); GET_ARENAKILLS(ch) = xmlGetIntProp(node, "akills", 0); GET_MOBKILLS(ch) = xmlGetIntProp(node, "mkills", 0); GET_PC_DEATHS(ch) = xmlGetIntProp(node, "deaths", 0); RAW_REPUTATION_OF(ch) = xmlGetIntProp(node, "reputation", 0); GET_SEVERITY(ch) = xmlGetIntProp(node, "severity", 0); } else if (xmlMatches(node->name, "attr")) { ch->aff_abils.str = ch->real_abils.str = xmlGetIntProp(node, "str", 0); ch->aff_abils.str = ch->real_abils.str += xmlGetIntProp(node, "stradd", 0) / 10; ch->aff_abils.intel = ch->real_abils.intel = xmlGetIntProp(node, "int", 0); ch->aff_abils.wis = ch->real_abils.wis = xmlGetIntProp(node, "wis", 0); ch->aff_abils.dex = ch->real_abils.dex = xmlGetIntProp(node, "dex", 0); ch->aff_abils.con = ch->real_abils.con = xmlGetIntProp(node, "con", 0); ch->aff_abils.cha = ch->real_abils.cha = xmlGetIntProp(node, "cha", 0); } else if (xmlMatches(node->name, "condition")) { GET_COND(ch, THIRST) = xmlGetIntProp(node, "thirst", 0); GET_COND(ch, FULL) = xmlGetIntProp(node, "hunger", 0); GET_COND(ch, DRUNK) = xmlGetIntProp(node, "drunk", 0); } else if (xmlMatches(node->name, "player")) { GET_WIMP_LEV(ch) = xmlGetIntProp(node, "wimpy", 0); GET_LIFE_POINTS(ch) = xmlGetIntProp(node, "lp", 0); GET_CLAN(ch) = xmlGetIntProp(node, "clan", 0); } else if (xmlMatches(node->name, "home")) { GET_HOME(ch) = xmlGetIntProp(node, "town", 0); GET_HOMEROOM(ch) = xmlGetIntProp(node, "homeroom", 0); GET_LOADROOM(ch) = xmlGetIntProp(node, "loadroom", 0); } else if (xmlMatches(node->name, "quest")) { GET_QUEST(ch) = xmlGetIntProp(node, "current", 0); GET_IMMORT_QP(ch) = xmlGetIntProp(node, "points", 0); GET_QUEST_ALLOWANCE(ch) = xmlGetIntProp(node, "allowance", 0); } else if (xmlMatches(node->name, "bits")) { char *flag = (char *)xmlGetProp(node, (xmlChar *) "flag1"); ch->char_specials.saved.act = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "flag2"); ch->player_specials->saved.plr2_bits = hex2dec(flag); free(flag); } else if (xmlMatches(node->name, "frozen")) { ch->player_specials->thaw_time = xmlGetIntProp(node, "thaw_time", 0); ch->player_specials->freezer_id = xmlGetIntProp(node, "freezer_id", 0); } else if (xmlMatches(node->name, "prefs")) { char *flag = (char *)xmlGetProp(node, (xmlChar *) "flag1"); ch->player_specials->saved.pref = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "flag2"); ch->player_specials->saved.pref2 = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "tongue"); if (flag) GET_TONGUE(ch) = find_tongue_idx_by_name(flag); free(flag); } else if (xmlMatches(node->name, "weaponspec")) { int vnum = xmlGetIntProp(node, "vnum", -1); int level = xmlGetIntProp(node, "level", 0); if (vnum > 0 && level > 0) { for (int i = 0; i < MAX_WEAPON_SPEC; i++) { if (GET_WEAP_SPEC(ch, i).level <= 0) { GET_WEAP_SPEC(ch, i).vnum = vnum; GET_WEAP_SPEC(ch, i).level = level; break; } } } } else if (xmlMatches(node->name, "title")) { char *txt; txt = (char *)xmlNodeGetContent(node); set_title(ch, txt); free(txt); } else if (xmlMatches(node->name, "affect")) { struct affected_type af; init_affect(&af); af.type = xmlGetIntProp(node, "type", 0); af.duration = xmlGetIntProp(node, "duration", 0); af.modifier = xmlGetIntProp(node, "modifier", 0); af.location = xmlGetIntProp(node, "location", 0); af.level = xmlGetIntProp(node, "level", 0); af.aff_index = xmlGetIntProp(node, "index", 0); af.owner = xmlGetIntProp(node, "owner", 0); af.next = NULL; char *instant = (char *)xmlGetProp(node, (xmlChar *) "instant"); if (instant != NULL && strcmp(instant, "yes") == 0) { af.is_instant = 1; } free(instant); char *bits = (char *)xmlGetProp(node, (xmlChar *) "affbits"); af.bitvector = hex2dec(bits); free(bits); affect_to_char(ch, &af); } else if (xmlMatches(node->name, "affects")) { // PCs shouldn't have ANY perm affects if (IS_NPC(ch)) { char *flag = (char *)xmlGetProp(node, (xmlChar *) "flag1"); AFF_FLAGS(ch) = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "flag2"); AFF2_FLAGS(ch) = hex2dec(flag); free(flag); flag = (char *)xmlGetProp(node, (xmlChar *) "flag3"); AFF3_FLAGS(ch) = hex2dec(flag); free(flag); } else { AFF_FLAGS(ch) = 0; AFF2_FLAGS(ch) = 0; AFF3_FLAGS(ch) = 0; } } else if (xmlMatches(node->name, "skill")) { char *spellName = (char *)xmlGetProp(node, (xmlChar *) "name"); int index = str_to_spell(spellName); if (index >= 0) { SET_SKILL(ch, index, xmlGetIntProp(node, "level", 0)); } free(spellName); } else if (xmlMatches(node->name, "tongue")) { char *tongue = (char *)xmlGetProp(node, (xmlChar *) "name"); int index = find_tongue_idx_by_name(tongue); if (index >= 0) SET_TONGUE(ch, index, MIN(100, xmlGetIntProp(node, "level", 0))); free(tongue); } else if (xmlMatches(node->name, "alias")) { struct alias_data *alias; CREATE(alias, struct alias_data, 1); alias->type = xmlGetIntProp(node, "type", 0); alias->alias = (char *)xmlGetProp(node, (xmlChar *) "alias"); alias->replacement = (char *)xmlGetProp(node, (xmlChar *) "replace"); if (alias->alias == NULL || alias->replacement == NULL) { free(alias); } else { add_alias(ch, alias); } } else if (xmlMatches(node->name, "description")) { txt = (char *)xmlNodeGetContent(node); ch->player.description = strdup(tmp_gsub(txt, "\n", "\r\n")); free(txt); } else if (xmlMatches(node->name, "poofin")) { POOFIN(ch) = (char *)xmlNodeGetContent(node); } else if (xmlMatches(node->name, "poofout")) { POOFOUT(ch) = (char *)xmlNodeGetContent(node); } else if (xmlMatches(node->name, "immort")) { txt = (char *)xmlGetProp(node, (xmlChar *) "badge"); strncpy(BADGE(ch), txt, 7); BADGE(ch)[7] = '\0'; free(txt); GET_QLOG_LEVEL(ch) = xmlGetIntProp(node, "qlog", 0); GET_INVIS_LVL(ch) = xmlGetIntProp(node, "invis", 0); } else if (xmlMatches(node->name, "rent")) { char *txt; ch->player_specials->rentcode = xmlGetIntProp(node, "code", 0); ch->player_specials->rent_per_day = xmlGetIntProp(node, "perdiem", 0); ch->player_specials->rent_currency = xmlGetIntProp(node, "currency", 0); txt = (char *)xmlGetProp(node, (xmlChar *) "state"); if (txt) ch->player_specials->desc_mode = (enum cxn_state)search_block(txt, desc_modes, false); free(txt); } else if (xmlMatches(node->name, "recentkill")) { struct kill_record *kill; CREATE(kill, struct kill_record, 1); kill->vnum = xmlGetIntProp(node, "vnum", 0); kill->times = xmlGetIntProp(node, "times", 0); GET_RECENT_KILLS(ch) = g_list_prepend(GET_RECENT_KILLS(ch), kill); } else if (xmlMatches(node->name, "grievance")) {
void save_player_to_file(struct creature *ch, const char *path) { void expire_old_grievances(struct creature *); // Save vital statistics FILE *ouf; char *tmp_path; struct alias_data *cur_alias; int idx; int hit = GET_HIT(ch), mana = GET_MANA(ch), move = GET_MOVE(ch); tmp_path = tmp_sprintf("%s.tmp", path); ouf = fopen(tmp_path, "w"); if (!ouf) { fprintf(stderr, "Unable to open XML player file for save.[%s] (%s)\n", path, strerror(errno)); return; } struct aff_stash *aff_stash = stash_creature_affects(ch); expire_old_grievances(ch); fprintf(ouf, "<creature name=\"%s\" idnum=\"%ld\">\n", GET_NAME(ch), ch->char_specials.saved.idnum); fprintf(ouf, "<points hit=\"%d\" mana=\"%d\" move=\"%d\" maxhit=\"%d\" maxmana=\"%d\" maxmove=\"%d\"/>\n", ch->points.hit, ch->points.mana, ch->points.move, ch->points.max_hit, ch->points.max_mana, ch->points.max_move); fprintf(ouf, "<money gold=\"%" PRId64 "\" cash=\"%" PRId64 "\" xp=\"%d\"/>\n", ch->points.gold, ch->points.cash, ch->points.exp); fprintf(ouf, "<stats level=\"%d\" sex=\"%s\" race=\"%s\" height=\"%d\" weight=\"%f\" align=\"%d\"/>\n", GET_LEVEL(ch), genders[(int)GET_SEX(ch)], race_name_by_idnum(GET_RACE(ch)), GET_HEIGHT(ch), GET_WEIGHT(ch), GET_ALIGNMENT(ch)); fprintf(ouf, "<class name=\"%s\"", class_names[GET_CLASS(ch)]); if (GET_REMORT_CLASS(ch) != CLASS_UNDEFINED) fprintf(ouf, " remort=\"%s\"", class_names[GET_REMORT_CLASS(ch)]); if (GET_REMORT_GEN(ch) > 0) fprintf(ouf, " gen=\"%d\"", GET_REMORT_GEN(ch)); if (IS_CYBORG(ch)) { if (GET_OLD_CLASS(ch) != -1) fprintf(ouf, " subclass=\"%s\"", borg_subchar_class_names[GET_OLD_CLASS(ch)]); if (GET_TOT_DAM(ch)) fprintf(ouf, " total_dam=\"%d\"", GET_TOT_DAM(ch)); if (GET_BROKE(ch)) fprintf(ouf, " broken=\"%d\"", GET_BROKE(ch)); } if (GET_CLASS(ch) == CLASS_MAGE && GET_SKILL(ch, SPELL_MANA_SHIELD) > 0) { fprintf(ouf, " manash_low=\"%ld\" manash_pct=\"%ld\"", ch->player_specials->saved.mana_shield_low, ch->player_specials->saved.mana_shield_pct); } fprintf(ouf, "/>\n"); fprintf(ouf, "<time birth=\"%ld\" death=\"%ld\" played=\"%ld\" last=\"%ld\"/>\n", ch->player.time.birth, ch->player.time.death, ch->player.time.played, ch->player.time.logon); fprintf(ouf, "<carnage pkills=\"%d\" akills=\"%d\" mkills=\"%d\" deaths=\"%d\" reputation=\"%d\"", GET_PKILLS(ch), GET_ARENAKILLS(ch), GET_MOBKILLS(ch), GET_PC_DEATHS(ch), ch->player_specials->saved.reputation); fprintf(ouf, "/>\n"); fprintf(ouf, "<attr str=\"%d\" int=\"%d\" wis=\"%d\" dex=\"%d\" con=\"%d\" cha=\"%d\"/>\n", ch->real_abils.str, ch->real_abils.intel, ch->real_abils.wis, ch->real_abils.dex, ch->real_abils.con, ch->real_abils.cha); fprintf(ouf, "<condition hunger=\"%d\" thirst=\"%d\" drunk=\"%d\"/>\n", GET_COND(ch, FULL), GET_COND(ch, THIRST), GET_COND(ch, DRUNK)); fprintf(ouf, "<player wimpy=\"%d\" lp=\"%d\" clan=\"%d\"/>\n", GET_WIMP_LEV(ch), GET_LIFE_POINTS(ch), GET_CLAN(ch)); if (ch->desc) ch->player_specials->desc_mode = ch->desc->input_mode; if (ch->player_specials->rentcode == RENT_CREATING || ch->player_specials->rentcode == RENT_REMORTING) { fprintf(ouf, "<rent code=\"%d\" perdiem=\"%d\" " "currency=\"%d\" state=\"%s\"/>\n", ch->player_specials->rentcode, ch->player_specials->rent_per_day, ch->player_specials->rent_currency, desc_modes[(int)ch->player_specials->desc_mode]); } else { fprintf(ouf, "<rent code=\"%d\" perdiem=\"%d\" currency=\"%d\"/>\n", ch->player_specials->rentcode, ch->player_specials->rent_per_day, ch->player_specials->rent_currency); } fprintf(ouf, "<home town=\"%d\" homeroom=\"%d\" loadroom=\"%d\"/>\n", GET_HOME(ch), GET_HOMEROOM(ch), GET_LOADROOM(ch)); fprintf(ouf, "<quest"); if (GET_QUEST(ch)) fprintf(ouf, " current=\"%d\"", GET_QUEST(ch)); if (GET_LEVEL(ch) >= LVL_IMMORT) fprintf(ouf, " allowance=\"%d\"", GET_QUEST_ALLOWANCE(ch)); if (GET_IMMORT_QP(ch) != 0) fprintf(ouf, " points=\"%d\"", GET_IMMORT_QP(ch)); fprintf(ouf, "/>\n"); fprintf(ouf, "<bits flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\"/>\n", ch->char_specials.saved.act, ch->player_specials->saved.plr2_bits); if (PLR_FLAGGED(ch, PLR_FROZEN)) { fprintf(ouf, "<frozen thaw_time=\"%d\" freezer_id=\"%d\"/>\n", ch->player_specials->thaw_time, ch->player_specials->freezer_id); } fprintf(ouf, "<prefs flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\" tongue=\"%s\"/>\n", ch->player_specials->saved.pref, ch->player_specials->saved.pref2, tongue_name(GET_TONGUE(ch))); fprintf(ouf, "<affects flag1=\"%" PRIx32 "\" flag2=\"%" PRIx32 "\" flag3=\"%" PRIx32 "\"/>\n", ch->char_specials.saved.affected_by, ch->char_specials.saved.affected2_by, ch->char_specials.saved.affected3_by); for (idx = 0; idx < MAX_WEAPON_SPEC; idx++) { if (GET_WEAP_SPEC(ch, idx).level > 0) fprintf(ouf, "<weaponspec vnum=\"%d\" level=\"%d\"/>\n", GET_WEAP_SPEC(ch, idx).vnum, GET_WEAP_SPEC(ch, idx).level); } if (GET_TITLE(ch) && *GET_TITLE(ch)) { fprintf(ouf, "<title>%s</title>\n", xmlEncodeTmp(GET_TITLE(ch))); } if (GET_LEVEL(ch) >= 50) { fprintf(ouf, "<immort badge=\"%s\" qlog=\"%d\" invis=\"%d\"/>\n", xmlEncodeSpecialTmp(BADGE(ch)), GET_QLOG_LEVEL(ch), GET_INVIS_LVL(ch)); if (POOFIN(ch) && *POOFIN(ch)) fprintf(ouf, "<poofin>%s</poofin>\n", xmlEncodeTmp(POOFIN(ch))); if (POOFOUT(ch) && *POOFOUT(ch)) fprintf(ouf, "<poofout>%s</poofout>\n", xmlEncodeTmp(POOFOUT(ch))); } if (ch->player.description && *ch->player.description) { fprintf(ouf, "<description>%s</description>\n", xmlEncodeTmp(tmp_gsub(tmp_gsub(ch->player.description, "\r\n", "\n"), "\r", ""))); } for (cur_alias = ch->player_specials->aliases; cur_alias; cur_alias = cur_alias->next) fprintf(ouf, "<alias type=\"%d\" alias=\"%s\" replace=\"%s\"/>\n", cur_alias->type, xmlEncodeSpecialTmp(cur_alias->alias), xmlEncodeSpecialTmp(cur_alias->replacement)); for (struct affected_type *cur_aff = aff_stash->saved_affs; cur_aff; cur_aff = cur_aff->next) fprintf(ouf, "<affect type=\"%d\" duration=\"%d\" modifier=\"%d\" location=\"%d\" level=\"%d\" instant=\"%s\" affbits=\"%lx\" index=\"%d\" owner=\"%ld\"/>\n", cur_aff->type, cur_aff->duration, cur_aff->modifier, cur_aff->location, cur_aff->level, (cur_aff->is_instant) ? "yes" : "no", cur_aff->bitvector, cur_aff->aff_index, cur_aff->owner); if (!IS_IMMORT(ch)) { for (idx = 0; idx < MAX_SKILLS; idx++) if (ch->player_specials->saved.skills[idx] > 0) fprintf(ouf, "<skill name=\"%s\" level=\"%d\"/>\n", spell_to_str(idx), GET_SKILL(ch, idx)); write_tongue_xml(ch, ouf); for (GList * it = GET_RECENT_KILLS(ch); it; it = it->next) { struct kill_record *kill = it->data; fprintf(ouf, "<recentkill vnum=\"%d\" times=\"%d\"/>\n", kill->vnum, kill->times); } for (GList * it = GET_GRIEVANCES(ch); it; it = it->next) { struct grievance *grievance = it->data; fprintf(ouf, "<grievance time=\"%lu\" player=\"%d\" reputation=\"%d\" kind=\"%s\"/>\n", (long unsigned)grievance->time, grievance->player_id, grievance->rep, grievance_kind_descs[grievance->grievance]); } } if (IS_PC(ch) && ch->player_specials->tags) { GHashTableIter iter; char *key; g_hash_table_iter_init(&iter, ch->player_specials->tags); while (g_hash_table_iter_next(&iter, (gpointer *)&key, NULL)) { fprintf(ouf, "<tag tag=\"%s\"/>\n", key); } } fprintf(ouf, "</creature>\n"); fclose(ouf); // on success, move temp file on top of the old file rename(tmp_path, path); restore_creature_affects(ch, aff_stash); free(aff_stash); GET_HIT(ch) = MIN(GET_MAX_HIT(ch), hit); GET_MANA(ch) = MIN(GET_MAX_MANA(ch), mana); GET_MOVE(ch) = MIN(GET_MAX_MOVE(ch), move); }
void load_text(struct char_data * ch) { FILE *fil = NULL; char fname[MAX_INPUT_LENGTH]; struct alias *al; int i, cnt; void free_alias(struct alias * a); if (IS_NPC(ch)) return; if (!get_filename(GET_NAME(ch), fname, ETEXT_FILE)) return; if (!(fil = fopen(fname, "r"))) { if (errno != ENOENT) { /* if it fails, NOT because of no file */ sprintf(buf1, "SYSERR: READING TEXT FILE %s (5)", fname); perror(buf1); send_to_char("\r\n***** NOTICE - THERE WAS A PROBLEM READING YOUR ALIAS FILE *****\r\n", ch); return; } return; } while ((al = GET_ALIASES(ch)) != NULL) { /* get rid of alias multiplying problem */ GET_ALIASES(ch) = (GET_ALIASES(ch))->next; free_alias(al); } cnt = 200; /* security counter to make memory alloc bombing impossible :) */ fscanf(fil, "%d\n", &i); /* get first type */ while (i != -1 && cnt != 0) { CREATE(al, struct alias, 1); al->type = i; fgets(buf, MAX_INPUT_LENGTH, fil); buf[strlen(buf) - 1] = '\0'; al->alias = strdup(buf); fgets(buf, MAX_INPUT_LENGTH, fil); buf[strlen(buf) - 1] = '\0'; al->replacement = strdup(buf); al->next = ch->player_specials->aliases; ch->player_specials->aliases = al; fscanf(fil, "%d\n", &i); cnt--; } /* aliases has been loaded */ if (WHOSPEC(ch)) { FREE(WHOSPEC(ch)); } if (POOFIN(ch)) { FREE(POOFIN(ch)); } if (POOFOUT(ch)) { FREE(POOFOUT(ch)); } if (WHOSTR(ch)) { FREE(WHOSTR(ch)); } if (NAMECOLOR(ch)) { FREE(NAMECOLOR(ch)); } fgets(buf, MAX_INPUT_LENGTH, fil); buf[strlen(buf) - 1] = '\0'; if (str_cmp("!UNUSED!", buf)) { WHOSPEC(ch) = strdup(buf); } fgets(buf, SMALL_BUFSIZE, fil); buf[strlen(buf) - 1] = '\0'; if (str_cmp("!UNUSED!", buf)) { POOFIN(ch) = strdup(buf); } fgets(buf, SMALL_BUFSIZE, fil); buf[strlen(buf) - 1] = '\0'; if (str_cmp("!UNUSED!", buf)) { POOFOUT(ch) = strdup(buf); } fgets(buf, MAX_INPUT_LENGTH, fil); buf[strlen(buf) - 1] = '\0'; if (str_cmp("!UNUSED!", buf)) { WHOSTR(ch) = strdup(buf); } if (fgets(buf, SMALL_BUFSIZE, fil) > (char*) NULL) { buf[strlen(buf) - 1] = '\0'; if (str_cmp("!UNUSED!", buf)) { NAMECOLOR(ch) = strdup(buf); } } if (cnt == 0) { send_to_char("Undetermined error when reading your alias file ...\r\n", ch); sprintf(buf, "ERROR when reading %s's alias file.", GET_NAME(ch)); mudlog(buf, 'W', COM_IMMORT, TRUE); plog(buf, ch, 0); } fclose(fil); return; }