Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ SMAUG ➜ SMAUG coding ➜ "Disapearing ch's"

"Disapearing ch's"

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Cynshard   (3 posts)  Bio
Date Wed 08 Sep 2004 03:27 AM (UTC)

Amended on Wed 08 Sep 2004 03:34 AM (UTC) by Cynshard

Message
Hey everyone.

I've been experiencing a strange bug lately with my copy of AFKMUD. I'll get right to it. Often, players will not be able to see one another, but they will be able to talk to each other/social one another.

I have a feeling my loadup function may be causing the errors but I'm not certain here is the function:

CHAR_DATA* get_char2( CHAR_DATA *ch, char *argument )
{
	CHAR_DATA *temp;
	char fname[256];
	struct stat fst;
	DESCRIPTOR_DATA *d;
	int old_room_vnum;

	if( !argument || argument[0] == '\0' )
		return ch;

	if( ch && ( temp = get_char_world( ch, capitalize( argument ) ) ) != NULL && !IS_NPC( temp ) )
	{
		log_printf_plus( LOG_INFO, 115, "Get_char2: found %s with get_char_world", temp->name );
		temp->pcdata->loaded = FALSE;
		return temp;
	}
	
	argument[0] = UPPER(argument[0]);
	snprintf( fname, 256, "%s%c/%s", PLAYER_DIR, tolower(argument[0]), capitalize( argument ) );

	/* Bug fix here provided by Senir to stop /dev/null crash */
	if ( stat( fname, &fst ) == -1 || !check_parse_name( capitalize( argument ), FALSE ) )
		return NULL;

	if( stat( fname, &fst ) != -1 )
	{
		CREATE( d, DESCRIPTOR_DATA, 1 );
		d->next = NULL;
		d->prev = NULL;
		d->connected = CON_PLOADED;
		d->outsize = 2000;
		CREATE( d->outbuf, char, d->outsize );

		// Prevent Build Log from Spamming
		getchar_flag = TRUE;

		load_char_obj( d, argument, FALSE, FALSE );

		LINK( d->character, first_char, last_char, next, prev );
		old_room_vnum = d->character->in_room->vnum;

		temp = d->character; // Hope this works...
		temp->pcdata->loaded = TRUE;

		d->character->desc	= NULL;
		d->character		= NULL;
		DISPOSE( d->outbuf );
		DISPOSE( d );
		log_printf_plus( LOG_INFO, 115, "Get_char2: found %s by loading", temp->name );
		return temp;
	}
	/* else no player file */
	return NULL;
}


The game will crash when a ch moves into a room with players/mobs that cannot "see" it. Here is some gdb output and valgrind output to illustrate what I mean:

#0  0x080e477a in char_to_room (ch=0x8855a18, pRoomIndex=0x8742358) at handler.c:1305
1305            LINK( ch, pRoomIndex->first_person, pRoomIndex->last_person, next_in_room, prev_in_room );
(gdb) bt
#0  0x080e477a in char_to_room (ch=0x8855a18, pRoomIndex=0x8742358) at handler.c:1305
#1  0x08075e59 in move_char (ch=0x8855a18, pexit=0x8745e68, fall=0, direction=1, running=false) at act_move.c:1084
#2  0x08162254 in mobile_update () at update.c:1021
#3  0x08164ecd in update_handler () at update.c:2939
#4  0x080c227c in game_loop () at comm.c:4057
#5  0x080c2f37 in main (argc=6, argv=0xbffffa94) at comm.c:4534


I'll spare you the prints of *ch and *pRoomIndex->last_person, but I will tell you that pRoomIndex = 0x0 which seems wrong when you look at the LINK macro.

Here is the associated Valgrind message:

Tue Sep 7, 2004 9:50:37 PM CDT :: Log Cynshard: force moron n
==22211==
==22211== Invalid write of size 4
==22211==    at 0x80E71EA: char_to_room(char_data*, room_index_data*) (handler.c:1305)
==22211==    by 0x8078510: move_char(char_data*, exit_data*, int, int, bool) (act_move.c:1084)
==22211==    by 0x8078B11: do_north (act_move.c:1335)
==22211==    by 0x80FB526: interpret(char_data*, char*) (interp.c:891)
==22211==    by 0x8088324: do_force (act_wiz.c:4876)
==22211==    by 0x80FB526: interpret(char_data*, char*) (interp.c:891)
==22211==    by 0x80C4C95: game_loop() (comm.c:4030)
==22211==    by 0x80C59A4: main (comm.c:4534)
==22211==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
==22211==
==22211== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ----


Sorry for all the spam. I'm really quite frustrated :) If anyone has had this problem or has any idea what could be causing this I'd greatly appreciate the input.
Thanks,
Cynshard
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #1 on Wed 08 Sep 2004 04:00 AM (UTC)
Message
Well, if the handling of putting the character into the room is supposed to be in that function, its not. Show the function that calls get_char2. Also, what is the significance of the old_room_vnum variable? I see you do old_room_vnum = d->character->in_room->vnum; and never reference to it again within this function.

~Nick Cash
http://www.nick-cash.com
Top

Posted by Cynshard   (3 posts)  Bio
Date Reply #2 on Wed 08 Sep 2004 12:46 PM (UTC)
Message
Ah the old_vnum_room is something that is used in do_loadup, I adapted this function from that, but it's not for the same thing. Here is a function that uses get_char2:


void decay_skills( const char *pname, int timestamp )
{
	CHAR_DATA *ch;
	char * name = str_dup( pname );
	int sn;

	float dec;

	if( ( ch = get_char2( NULL, name ) ) == NULL )
	{
		log_printf( "Decay_skills: get_char2 failed %s", name );
		DISPOSE( name );
		return;
	}
	DISPOSE( name );
	if( ch->level > 100 )
	{
		save_char_obj( ch );
		if( !IS_CH_ONLINE( ch ) )
			todo_quit( ch ); 
		return;
	}
	/* 
	 *  Read through the players skills and decrement the
	 *  the percentages based upon the timestamp.
	 */
	log_printf_plus( LOG_SKILL, 115, "Processing %s%s Skill Decay", ch->name, ch->name[strlen(ch->name)-1] == 's' ? "\'" : "\'s" );
	for ( sn = 1; sn < top_sn; sn++ )
	{
		if ( skill_table[sn]->name && ch->pcdata->learned[sn] > 0 )
		{
			dec = ( ( ( timestamp - ch->pcdata->last_decay ) / 86400 ) * skill_table[sn]->decay );
			ch->pcdata->learned[sn] -= (sh_int)( dec <= skill_table[sn]->min ? skill_table[sn]->min : dec );
		}
	}

	save_char_obj( ch );
	if( !IS_CH_ONLINE( ch ) )
		todo_quit( ch );
	return;
}


Also here is the todo_quit function that is used to quit chars that have been loaded with get_char2:

void todo_quit( CHAR_DATA *ch )
{
	if( ch->pcdata->loaded == FALSE || IS_CH_ONLINE( ch ) )
		return;

	int x, y;
	ROOM_INDEX_DATA *original;
	original = ch->in_room;

	char_from_room( ch );
	if( !char_to_room( ch, original ) )
		log_printf( "char_to_room: %s:%s, line %d.", __FILE__, __FUNCTION__, __LINE__ );

	quitting_char = ch;

	nullify_temp_todo( ch );

	if( sysdata.save_pets )
	{
		CHAR_DATA *pet;

		while( ( pet = ch->last_pet ) != NULL )
			extract_char( pet, TRUE );
	}
	saving_char = NULL;

	/*
	* After extract_char the ch is no longer valid!
	*/
	extract_char( ch, TRUE );
	for ( x = 0; x < MAX_WEAR; x++ )
		for ( y = 0; y < MAX_LAYERS; y++ )
			save_equipment[x][y] = NULL;

	return;
}


Thanks for the rapid response.
Cynshard
Top

Posted by Cynshard   (3 posts)  Bio
Date Reply #3 on Wed 08 Sep 2004 01:29 PM (UTC)
Message
It just occured to me that todo_quit was calling char_from_room when get_char2 wasn't putting the ch in a room. I went ahead and made get_char2 put the ch into the limbo room and things seem to have cleared up.

Thanks WK

Cynshard
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


12,904 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.