Page 1 of 1

MAX_GAMESTATE_CHARS EXCEEDED?

Posted: Thu May 21, 2009 2:30 pm
by $oldier Of Ra
This errors seems to kick my clients on my server on one specific map in a specific mode.

Does anyone know what causes this?

Posted: Thu May 21, 2009 3:23 pm
by Aprop

Code: Select all

#define	MAX_GAMESTATE_CHARS	16000

Code: Select all

/*
=====================
CL_ConfigstringModified
=====================
*/
void CL_ConfigstringModified( void ) {
	char		*old, *s;
	int			i, index;
	char		*dup;
	gameState_t	oldGs;
	int			len;

	index = atoi( Cmd_Argv(1) );
	if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
		Com_Error( ERR_DROP, "configstring > MAX_CONFIGSTRINGS" );
	}
	// get everything after "cs <num>"
	s = Cmd_ArgsFrom(2);

	old = cl.gameState.stringData + cl.gameState.stringOffsets[ index ];
	if ( !strcmp( old, s ) ) {
		return;		// unchanged
	}

	// build the new gameState_t
	oldGs = cl.gameState;

	Com_Memset( &cl.gameState, 0, sizeof( cl.gameState ) );

	// leave the first 0 for uninitialized strings
	cl.gameState.dataCount = 1;

	for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) {
		if ( i == index ) {
			dup = s;
		} else {
			dup = oldGs.stringData + oldGs.stringOffsets[ i ];
		}
		if ( !dup[0] ) {
			continue;		// leave with the default empty string
		}

		len = strlen( dup );

		if ( len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS ) {
			Com_Error( ERR_DROP, "MAX_GAMESTATE_CHARS exceeded" );
		}

		// append it to the gameState string buffer
		cl.gameState.stringOffsets[ i ] = cl.gameState.dataCount;
		Com_Memcpy( cl.gameState.stringData + cl.gameState.dataCount, dup, len + 1 );
		cl.gameState.dataCount += len + 1;
	}

	if ( index == CS_SYSTEMINFO ) {
		// parse serverId and other cvars
		CL_SystemInfoChanged();
	}

}
ahh you probably getin it here

Code: Select all

/*
==================
CL_ParseGamestate
==================
*/
void CL_ParseGamestate( msg_t *msg ) {
	int				i;
	entityState_t	*es;
	int				newnum;
	entityState_t	nullstate;
	int				cmd;
	char			*s;

	Con_Close();

	clc.connectPacketCount = 0;

	// wipe local client state
	CL_ClearState();

	// a gamestate always marks a server command sequence
	clc.serverCommandSequence = MSG_ReadLong( msg );

	// parse all the configstrings and baselines
	cl.gameState.dataCount = 1;	// leave a 0 at the beginning for uninitialized configstrings
	while ( 1 ) {
		cmd = MSG_ReadByte( msg );

		if ( cmd == svc_EOF ) {
			break;
		}
		
		if ( cmd == svc_configstring ) {
			int		len;

			i = MSG_ReadShort( msg );
			if ( i < 0 || i >= MAX_CONFIGSTRINGS ) {
				Com_Error( ERR_DROP, "configstring > MAX_CONFIGSTRINGS" );
			}
			s = MSG_ReadBigString( msg );
			len = strlen( s );

			if ( len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS ) {
				Com_Error( ERR_DROP, "MAX_GAMESTATE_CHARS exceeded" );
			}

			// append it to the gameState string buffer
			cl.gameState.stringOffsets[ i ] = cl.gameState.dataCount;
			Com_Memcpy( cl.gameState.stringData + cl.gameState.dataCount, s, len + 1 );
			cl.gameState.dataCount += len + 1;
		} else if ( cmd == svc_baseline ) {
			newnum = MSG_ReadBits( msg, GENTITYNUM_BITS );
			if ( newnum < 0 || newnum >= MAX_GENTITIES ) {
				Com_Error( ERR_DROP, "Baseline number out of range: %i", newnum );
			}
			Com_Memset (&nullstate, 0, sizeof(nullstate));
			es = &cl.entityBaselines[ newnum ];
			MSG_ReadDeltaEntity( msg, &nullstate, es, newnum );
		} else {
			Com_Error( ERR_DROP, "CL_ParseGamestate: bad command byte" );
		}
	}

	clc.clientNum = MSG_ReadLong(msg);
	// read the checksum feed
	clc.checksumFeed = MSG_ReadLong( msg );

	// parse useful values out of CS_SERVERINFO
	CL_ParseServerInfo();

	// parse serverId and other cvars
	CL_SystemInfoChanged();

	// stop recording now so the demo won't have an unnecessary level load at the end.
	if(cl_autoRecordDemo->integer && clc.demorecording)
		CL_StopRecord_f();
	
	// reinitialize the filesystem if the game directory has changed
	FS_ConditionalRestart( clc.checksumFeed );

	// This used to call CL_StartHunkUsers, but now we enter the download state before loading the
	// cgame
	CL_InitDownloads();

	// make sure the game starts
	Cvar_Set( "cl_paused", "0" );
}

Posted: Thu May 21, 2009 3:38 pm
by $oldier Of Ra
So too much info is sent to the players...in the form of strings or other things?

Posted: Thu May 21, 2009 5:26 pm
by Rookie One.pl
Too much stuff in config strings. I guess you're either using too many serverinfo variables (the ones you set with "sets") or cacheing too many sounds or models.

Posted: Thu May 21, 2009 5:40 pm
by SilentAngel

Code: Select all

#define   MAX_GAMESTATE_CHARS   16000
and

Code: Select all

cl.gameState.dataCount = 1;
s = MSG_ReadBigString( msg ); 
len = strlen( s );
if ( len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS )
so, if math is not an opinion:
cl.gameState.dataCount + 1 = 2
so 16000 - 2 = 15998!!!!!!
oh my good, how can you have a 15998 chars string!! :lol:
however, I don't get what msg exactly is. to me it appear much more as a string with all the configuration info of your server and then clients can't drop them all and their connection is timed out..but, honestly, I HAVE NO IDEA!! lol
Aprop where did you found these info? I would like to have a look at them! even if I won't probably understeand them all! haha :oops:

Posted: Thu May 21, 2009 6:05 pm
by $oldier Of Ra
It doesn't count for 1 string, it counts for ALL strings/configs etc combined. However the sounds and cvars could be the cause here...

Aprop got it from Q3's Source.

Posted: Thu May 21, 2009 6:31 pm
by SilentAngel
well of course it's a "ALL IN ONE", but still I can't believe you reached this number!
this remind me another post, where i read about this kind of limitation, but about variables..
try to remove some cvar, considering that there are already a lot of them into the game, if you made a huge mod with a lot of them, or some really long cvar probably you overreach 15998 chars in this string.. :shock:
Well post your results after changed some cvar, this post is really intresting, I never though at this engine as something so limited.. :?

Posted: Thu May 21, 2009 9:54 pm
by $oldier Of Ra
Technically, it is not one big string or a bunch of strings. It's the entire information package that's exchanged between server and clients that's over 16 000 chars. Reminding you that each letter and each space is 1 character. And it goes amazingly fast. With this post alone I just reached 361 chars.

If you cannot believe it, google it, I'm not the only one.