void free_char (CHAR_DATA *ch)
{
OBJ_DATA *obj;
OBJ_DATA *obj_next;
AFFECT_DATA *paf;
AFFECT_DATA *paf_next;
EXTRA_DESCR_DATA *ed, *ed_next;
Escape(ch);
if (IS_NPC(ch))
mobile_count–;
for (obj = ch->carrying; obj != NULL; obj = obj_next)
{
obj_next = obj->next_content;
extract_obj(obj);
}
for (paf = ch->affected; paf != NULL; paf = paf_next)
{
paf_next = paf->next;
affect_remove(ch,paf);
}
if(ch->script != NULL)
free_script(ch->script);
PURGE_DATA(ch->aifile);
PURGE_DATA(ch->alt_description);
PURGE_DATA(ch->alt_long_descr);
PURGE_DATA(ch->alt_name);
PURGE_DATA(ch->colours[0]);
PURGE_DATA(ch->colours[1]);
PURGE_DATA(ch->demeanor);
PURGE_DATA(ch->description);
PURGE_DATA(ch->email_addr);
PURGE_DATA(ch->ghouled_by);
PURGE_DATA(ch->ignore);
PURGE_DATA(ch->laston);
PURGE_DATA(ch->long_descr);
PURGE_DATA(ch->married);
PURGE_DATA(ch->material);
PURGE_DATA(ch->name);
PURGE_DATA(ch->nature);
PURGE_DATA(ch->next_in_room);
PURGE_DATA(ch->oldname);
PURGE_DATA(ch->pack);
PURGE_DATA(ch->prefix);
PURGE_DATA(ch->profession);
PURGE_DATA(ch->prompt);
PURGE_DATA(ch->reply);
PURGE_DATA(ch->short_descr);
PURGE_DATA(ch->sire);
PURGE_DATA(ch->surname);
PURGE_DATA(ch->switch_desc);
PURGE_DATA(ch->to_learn);
PURGE_DATA(ch->pnote);
PURGE_DATA(ch->pcdata);
for (ed = ch->extra_descr; ed != NULL; ed = ed_next )
{
ed_next = ed->next;
free_extra_descr(ed);
}
ch->extra_descr = NULL;
PURGE_DATA(ch);
return;
}
CHAR_DATA *new_char (void)
{
CHAR_DATA *ch;
int i;
ALLOC_DATA(ch, CHAR_DATA, 1);
ch->hunted = FALSE;
ch->aifile = NULL;
ch->alt_description = NULL;
ch->alt_long_descr = NULL;
ch->alt_name = NULL;
ch->demeanor = NULL;
ch->description = NULL;
ch->email_addr = NULL;
ch->ghouled_by = NULL;
ch->ignore = NULL;
ch->laston = NULL;
ch->long_descr = NULL;
ch->married = NULL;
ch->material = NULL;
ch->name = NULL;
ch->nature = NULL;
ch->next_in_room = NULL;
ch->oldname = NULL;
ch->pack = NULL;
ch->prefix = NULL;
ch->profession = NULL;
ch->prompt = NULL;
ch->reply = NULL;
ch->short_descr = NULL;
ch->sire = NULL;
ch->surname = NULL;
ch->switch_desc = NULL;
ch->to_learn = NULL;
ch->BUILDER_MODE = 0;
ch->act = 0;
ch->act2 = 0;
ch->act_points = 0;
ch->affected_by = 0;
ch->affected_by2 = 0;
ch->agghealth = 7;
ch->attitude = 0;
ch->balance = 0;
ch->bank_account = 0;
ch->bg_count = 0;
ch->cents = 0;
ch->char_age = 0;
ch->clan = 0;
ch->combo_success = 0;
ch->comm = 0;
ch->concede = 0;
ch->current_tip = 0;
ch->dollars = 0;
ch->email_lock = 0;
ch->employer = 0;
ch->exp = 0;
ch->falldam = 0;
ch->form = 0;
ch->gen = 0;
ch->health = 7;
ch->herd_timer = 0;
ch->home = 0;
ch->hunter_vis = 0;
ch->id = 0;
ch->imm_flags = 0;
ch->jump_timer = 0;
ch->lines = PAGELEN;
ch->logon = current_time;
ch->markup = 0;
ch->max_traits[0] = 5;
ch->max_traits[1] = 5;
ch->off_flags = 0;
ch->on_phone = 0;
ch->ooc_xp_count = 0;
ch->ooc_xp_time = 0;
ch->oocxp = 0;
ch->parts = 0;
ch->played = 0;
ch->plr_flags = 0;
ch->position = P_STAND;
ch->pospts = 0;
ch->res_flags = 0;
ch->ritepoint = 0;
ch->stock_ticker = 0;
ch->version = 0;
ch->vuln_flags = 0;
ch->wait = 0;
ch->warrants = 0;
ch->wiznet = 0;
ch->xp_job_acts = 0;
ch->xpgift = 0;
ch->GHB = 0;
ch->RBPG = 0;
ch->auspice = 0;
ch->bg_timer = 0;
ch->blood_timer = 0;
ch->breed = 0;
ch->carry_number = 0;
ch->carry_weight = 0;
ch->combat_flag = 0;
ch->dam_type = 0;
ch->daze = 0;
ch->default_pos = P_STAND;
ch->dice_mod = 0;
ch->diff_mod = 0;
ch->group = 0;
ch->incog_level = 0;
ch->infl_timer = 0;
ch->invis_level = 0;
ch->jump_dir = 0;
ch->max_GHB = 0;
ch->max_RBPG = 0;
ch->max_willpower = 0;
ch->mprog_delay = 0;
ch->power_timer = 0;
ch->race = 0;
ch->saving_throw = 0;
ch->sex = 0;
ch->shape = 0;
ch->size = 0;
ch->start_pos = P_STAND;
ch->timer = 0;
ch->torpor_timer = 0;
ch->train_success = 0;
ch->willpower = 0;
ch->trust = 0;
for (i = 0; i < 3; i++)
ch->armor[i] = 100;
for (i = 0; i < 3; i++)
ch->clan_powers[i] = -1;
for (i = 0; i < 3; i++)
ch->colours[i] = NULL;
for (i = 0; i < MAX_STATS; i ++)
{
ch->perm_stat[i] = 1;
ch->mod_stat[i] = 0;
}
clear_rite(ch);
return ch;
}
#define PURGE_DATA(data) \
do { \
if(data) \
{ \
free((void *)data); \
} \
else { \
if(logFail) { \
log_string((char *)Format("clear_free_lists: unable to purge_data as it was NULL from: %s %s %d", __FILE__, __FUNCTION__, __LINE__)); \
} \
} \
data = NULL; \
} while(0)
void aggr_update( void )
{
CHAR_DATA *wch, *wch_next;
CHAR_DATA *ch, *ch_next;
CHAR_DATA *vch, *vch_next;
CHAR_DATA *victim, *prev;
// say WHA? (Zeroed! by Omega)
wch = wch_next = ch = ch_next = vch = vch_next = victim = prev = NULL;
for ( wch = char_list; wch != NULL; wch = wch_next )
{
wch_next = wch->next; //<—-LINE 1479
if ( IS_NPC(wch)
|| wch->trust >= LEVEL_IMMORTAL
|| wch->in_room == NULL
|| wch->in_room->area->empty
|| IS_SET(wch->act, ACT_REINCARNATE)) {
prev = wch;
continue;
}
for ( ch = wch->in_room->people; ch != NULL; ch = ch_next )
{
int count;
ch_next = ch->next_in_room;
if ( (!IS_NPC(ch)
&& !IS_SET(ch->act2, ACT2_FRENZY))
|| !IS_SET(ch->act, ACT_AGGRESSIVE)
|| ch->fighting != NULL
|| IS_AFFECTED(ch, AFF_CHARM)
|| !IS_AWAKE(ch)
|| ( IS_SET(ch->act, ACT_WIMPY) && IS_AWAKE(wch) )
|| !can_see( ch, wch )
|| number_bits(1) == 0)
prev = wch;
continue;
/*
* Ok we have a 'wch' player character and a 'ch' npc aggressor.
* Now make the aggressor fight a RANDOM pc victim in the room,
* giving each 'vch' an equal chance of selection.
*/
count = 0;
victim = NULL;
for ( vch = wch->in_room->people; vch != NULL; vch = vch_next )
{
vch_next = vch->next_in_room;
if ( (!IS_NPC(vch)
|| !IS_NPC(ch))
&& vch->trust < LEVEL_IMMORTAL
&& ( !IS_SET(ch->act, ACT_WIMPY) || !IS_AWAKE(vch) )
&& can_see( ch, vch ) )
{
if ( number_range( 0, count ) == 0 )
victim = vch;
count++;
}
}
if ( victim == NULL || IS_SET(victim->act2, ACT2_RP_ING)) {
prev = wch;
continue;
}
if(IS_NPC(ch) || ch->condition[COND_FEAR] < ch->condition[COND_ANGER])
multi_hit( ch, victim, TYPE_UNDEFINED );
else
do_function(ch, &do_flee, "" );
}
prev = wch;
}
return;
}
PURGE_DATA(ch->next_in_room);
ch->next_in_room = NULL;
PURGE_DATA(ch->reply);
bool IS_NATURAL( CHAR_DATA *ch )
{
if(ch->race == race_lookup("werewolf") || ch->race == race_lookup("vampire"))
return FALSE;
return TRUE;
}
void update_pos( CHAR_DATA *victim, int agg )
{
if ( (victim->health + victim->agghealth - 7) > 0
&& (victim->position < P_SLEEP || victim->position > P_STAND) )
{
victim->position = P_STAND;
return;
}
if(IS_SET(victim->plr_flags, PLR_ARREST)
&& (victim->health + victim->agghealth - 7) <= 0)
{
victim->health = 6;
victim->agghealth = 7;
victim->position = P_STAND;
if(victim->fighting)
{
act("$N loads $n into a police cruiser to be taken to gaol.",
victim, NULL, victim->fighting, TO_NOTVICT, 0);
act("$N loads you into a police car and you are hauled away.",
victim, NULL, victim->fighting, TO_CHAR, 0);
act("You pack $n into a police car to be taken off to gaol.",
victim, NULL, victim->fighting, TO_VICT, 0);
}
else
{
act("The police load $n into a cruiser to be taken to gaol.",
victim, NULL, NULL, TO_NOTVICT, 0);
act("A group of police officers haul you away.",
victim, NULL, NULL, TO_CHAR, 1);
}
char_from_room(victim);
char_to_room(victim, get_room_index(ROOM_VNUM_GAOL));
return;
}
if (((IS_NATURAL(victim)) && ((victim->health + victim->agghealth - 7) < 0
|| (victim->health + victim->agghealth - 7) < 0))
|| ( (victim->health + victim->agghealth - 7) < 0 && victim->RBPG <= 1 ))
{
victim->position = P_DEAD;
return;
}
if ( (victim->health + victim->agghealth - 7) == 0 )
victim->position = P_INCAP;
if ( (victim->health + victim->agghealth - 7) < 0 )
{
if ( victim->race == race_lookup("human"))
victim->position = P_MORT;
else
if( victim->agghealth > 0 && !agg )
victim->position = P_TORPOR;
else
victim->position = P_MORT;
}
return;
}
I'm busy taking out some old color code in favor of using KaVir's protocol color. So, this is what I did. I replaced the send_to_char that we had and replaced it with a stock rom send_to_char. It worked OK, but I noticed a few problems, but nothing I don't think I can figure out. For one, when I did things like do_score, it didn't return a prompt to me.
However, the real problem is that when I went to shutdown my mud, it finally started to shutdown properly (something it hadn't done for a LONG time), but I got this (warning: It's long). I'm including the color code for send_to_char I'd been using and the stock one I am currently using. Unfortunately, I have no clue what it means.
Cleaning news list
Cleaning out index hashes.
Cleaning out area list
cleaning out remaining shop data
cleaning out social table.
cleaning out plots
Cleaning out events / scripts / actors
*** glibc detected *** /home/m243bra/ptdev/src/project: double free or corruption (top): 0x08353b80 ***
======= Backtrace: =========
/lib/libc.so.6[0xb064a5]
/lib/libc.so.6(cfree+0x59)[0xb068e9]
/home/m243bra/ptdev/src/project[0x80f1721]
/home/m243bra/ptdev/src/project[0x80a6145]
/home/m243bra/ptdev/src/project[0x809229f]
/home/m243bra/ptdev/src/project[0x80924e3]
/lib/libc.so.6(__libc_start_main+0xdc)[0xab2e9c]
/home/m243bra/ptdev/src/project[0x8049151]
======= Memory map: ========
002b1000-002bb000 r-xp 00000000 fd:01 56263788 /lib/libnss_files-2.5.so
002bb000-002bc000 r–p 00009000 fd:01 56263788 /lib/libnss_files-2.5.so
002bc000-002bd000 rw-p 0000a000 fd:01 56263788 /lib/libnss_files-2.5.so
00a7e000-00a99000 r-xp 00000000 fd:01 56262898 /lib/ld-2.5.so
00a99000-00a9a000 r–p 0001a000 fd:01 56262898 /lib/ld-2.5.so
00a9a000-00a9b000 rw-p 0001b000 fd:01 56262898 /lib/ld-2.5.so
00a9d000-00bf1000 r-xp 00000000 fd:01 56263398 /lib/libc-2.5.so
00bf1000-00bf2000 —p 00154000 fd:01 56263398 /lib/libc-2.5.so
00bf2000-00bf4000 r–p 00154000 fd:01 56263398 /lib/libc-2.5.so
00bf4000-00bf5000 rw-p 00156000 fd:01 56263398 /lib/libc-2.5.so
00bf5000-00bf8000 rw-p 00bf5000 00:00 0
00bfa000-00c21000 r-xp 00000000 fd:01 56263557 /lib/libm-2.5.so
00c21000-00c22000 r–p 00026000 fd:01 56263557 /lib/libm-2.5.so
00c22000-00c23000 rw-p 00027000 fd:01 56263557 /lib/libm-2.5.so
00cfe000-00d09000 r-xp 00000000 fd:01 56263576 /lib/libgcc_s-4.1.2-20080825.so.1
00d09000-00d0a000 rw-p 0000a000 fd:01 56263576 /lib/libgcc_s-4.1.2-20080825.so.1
00d3d000-00d4e000 r-xp 00000000 fd:01 56263596 /lib/libresolv-2.5.so
00d4e000-00d4f000 r–p 00010000 fd:01 56263596 /lib/libresolv-2.5.so
00d4f000-00d50000 rw-p 00011000 fd:01 56263596 /lib/libresolv-2.5.so
00d50000-00d52000 rw-p 00d50000 00:00 0
00fb0000-00fb1000 r-xp 00fb0000 00:00 0 [vdso]
00fcc000-00fd0000 r-xp 00000000 fd:01 56263593 /lib/libnss_dns-2.5.so
00fd0000-00fd1000 r–p 00003000 fd:01 56263593 /lib/libnss_dns-2.5.so
00fd1000-00fd2000 rw-p 00004000 fd:01 56263593 /lib/libnss_dns-2.5.so
08048000-08156000 r-xp 00000000 fd:01 69140600 /home/m243bra/ptdev/src/project
08156000-08157000 rw-p 0010d000 fd:01 69140600 /home/m243bra/ptdev/src/project
08157000-08374000 rw-p 08157000 00:00 0 [heap]
b7ff5000-b7ff7000 rw-p b7ff5000 00:00 0
b7ffc000-b7ffd000 rw-p b7ffc000 00:00 0
bffe9000-bfffe000 rw-p bffe8000 00:00 0 [stack]
Program received signal SIGABRT, Aborted.
0x00a7e7f2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb) bt
#0 0x00a7e7f2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
#1 0x00ac5df0 in raise () from /lib/libc.so.6
#2 0x00ac7701 in abort () from /lib/libc.so.6
#3 0x00afe18b in __libc_message () from /lib/libc.so.6
#4 0x00b064a5 in _int_free () from /lib/libc.so.6
#5 0x00b068e9 in free () from /lib/libc.so.6
#6 0x080f1721 in free_char (ch=0x8353b80) at recycle.c:969
#7 0x080a6145 in purgeExtractedWorldData () at handler.c:4716
#8 0x0809229f in cleanup_mud (control=8) at comm.c:584
#9 0x080924e3 in main (argc=Cannot access memory at address 0x55c8
) at comm.c:660
(gdb) frame 0
#0 0x00a7e7f2 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb) list
589 int main( int argc, char **argv )
590 {
591 struct timeval now_time;
592
593 bool fCopyOver = FALSE;
594
595 /*
596 * Init time.
597 */
598 gettimeofday( &now_time, NULL );
(gdb) info locals
No symbol table info available.
(gdb) frame 1
#1 0x00ac5df0 in raise () from /lib/libc.so.6
(gdb) list
599 current_time = (time_t) now_time.tv_sec;
600 strncpy( str_boot_time, ctime( ¤t_time ), sizeof(str_boot_time));
601
602 /*
603 * Reserve one channel for our use.
604 */
605 if ( ( fpReserve = fopen( NULL_FILE, "r" ) ) == NULL )
606 {
607 perror( NULL_FILE );
608 exit( 1 );
(gdb) info locals
No symbol table info available.
(gdb) frame 3
#3 0x00afe18b in __libc_message () from /lib/libc.so.6
(gdb) list
609 }
610
611 /*
612 * Get the port number and initial log file number.
613 */
614 port = MUD_PORT;
615 if ( argc > 1 )
616 {
617 if ( !is_number( argv[1] ) )
618 {
(gdb) info local
No symbol table info available.
(gdb) frame 2
#2 0x00ac7701 in abort () from /lib/libc.so.6
(gdb) list
619 fprintf( stderr, "Usage: %s [port #] [first log #]\n", argv[0] );
620 exit( 1 );
621 }
622 else if ( ( port = atoi( argv[1] ) ) <= 1024 )
623 {
624 fprintf( stderr, "Port number must be above 1024.\n" );
625 exit( 1 );
626 }
627
628 /* Are we recovering from a copyover? */
(gdb) info local
No symbol table info available.
(gdb) frame 4
#4 0x00b064a5 in _int_free () from /lib/libc.so.6
(gdb) list
629 if (argv[3] && argv[3][0])
630 {
631 fCopyOver = TRUE;
632 control = atoi(argv[3]);
633 }
634 else
635 fCopyOver = FALSE;
636 }
637
638 if( argv[2] == NULL || !is_number( argv[2] ) )
(gdb) info local
No symbol table info available.
(gdb) frame 5
#5 0x00b068e9 in free () from /lib/libc.so.6
(gdb) list
639 snprintf(logfile, sizeof(logfile), "%d", 1000);
640 else
641 snprintf(logfile, sizeof(logfile), "%s", argv[2] );
642
643 /*
644 * Run the game.
645 */
646 // if (!fCopyOver)
647 control = init_socket( port );
648
(gdb) info local
No symbol table info available.
(gdb) frame 6
#6 0x080f1721 in free_char (ch=0x8353b80) at recycle.c:969
969 PURGE_DATA(ch);
(gdb) list
964 {
965 ed_next = ed->next;
966 free_extra_descr(ed);
967 }
968 ch->extra_descr = NULL;
969 PURGE_DATA(ch);
970 return;
971 }
972
973
(gdb) info local
obj = <value optimized out>
obj_next = 0x8353b80
paf = <value optimized out>
paf_next = 0x8353b80
ed = 0x0
ed_next = 0x8353b80
__FUNCTION__ = "free_char"
(gdb) frame 7
#7 0x080a6145 in purgeExtractedWorldData () at handler.c:4716
4716 free_char(ch);
(gdb) list
4711
4712 for(ch = worldExtractedCharacters; ch; ch = ch_next)
4713 {
4714 ch_next = ch->next;
4715 UNLINK_SINGLE(ch, next, CHAR_DATA, worldExtractedCharacters);
4716 free_char(ch);
4717 }
4718 for(obj = worldExtractedObjects; obj; obj = obj_next)
4719 {
4720 obj_next = obj->next;
(gdb) info local
ch = 0x8353b80
ch_next = 0x0
obj = <value optimized out>
obj_next = <value optimized out>
(gdb) frame 8
#8 0x0809229f in cleanup_mud (control=8) at comm.c:584
584 purgeExtractedWorldData();
(gdb) list
579 pEvent_next = pEvent->next;
580
581 free_event(pEvent);
582 }
583
584 purgeExtractedWorldData();
585 log_string("Project Twilight has completed its cleanup procedure and may now shutdown.");
586 return;
587 }
588
(gdb) info local
mob_index = <value optimized out>
room_index = 0x0
obj_index = <value optimized out>
pShop = <value optimized out>
pShop_next = 0x0
pArea = <value optimized out>
pArea_next = 0x0
ch = <value optimized out>
ch_next = <value optimized out>
obj = <value optimized out>
obj_next = <value optimized out>
pack = <value optimized out>
pack_next = <value optimized out>
org = <value optimized out>
org_next = <value optimized out>
stock = <value optimized out>
stock_next = <value optimized out>
paper = <value optimized out>
paper_next = <value optimized out>
d = <value optimized out>
d_next = <value optimized out>
pbg = <value optimized out>
pbg_next = <value optimized out>
pnote = <value optimized out>
pnote_next = <value optimized out>
help = <value optimized out>
help_next = <value optimized out>
pPlot = <value optimized out>
pPlot_next = 0x0
pEvent = 0x0
pEvent_next = 0x0
iHash = 1024
(gdb) frame 9
#9 0x080924e3 in main (argc=Cannot access memory at address 0x55c8
) at comm.c:660
660 cleanup_mud(control);
(gdb) list
655 copyover_recover();
656 */
657 game_loop_unix( control );
658 /* shutdown_web(); */
659
660 cleanup_mud(control);
661
662
663 /*
664 * That's all, folks.
(gdb) info local
now_time = {tv_sec = 1348241263, tv_usec = 346214}