Jump to content

Home

Making player IP accessable from "game"


ensiform

Recommended Posts

Posted

Anybody have any other ideas at how to make ip accessable across maps without clearing, ive tried in session but it truncates itself, and now i have it stored in client and it works on death, but not on like restart or map change it clears itself. here's my code, i was wondering if someone could help cause i think this is best way it just needs to stay somehow.

 

g_local.h : gclient_s/t

 

	char		IPstring[16];		// yeah, I know, could be 16, but, just in case...

 

g_client.c : ClientConnect

 

	G_ReadSessionData( client );
// new
if ( firstTime || level.restarted || level.newSession ) {
	ent->client->IPstring[0] = 0;
	Q_strncpyz(ent->client->IPstring, tmpIP, sizeof(ent->client->IPstring));
}
// end new

 

g_client.c : ClientSpawn

 

char				IPstring[16];

 

	accuracy_shots = client->accuracy_shots;
// new
Q_strncpyz(IPstring,client->IPstring,sizeof(client->IPstring));
// end new
for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {

 

down further in clientspawn still...

 

	client->ps.fd = savedForce;
// new
Q_strncpyz(client->IPstring, IPstring, sizeof(IPstring));
// end new
client->ps.duelIndex = ENTITYNUM_NONE;

  • 4 weeks later...
Posted

okay this is how it was done:

 

/*
================
G_WriteClientSessionData

Called on game shutdown
================
*/
void G_WriteClientSessionData( gclient_t *client ) {
g_sess[client - level.clients] = client->sess;
}

/*
================
G_ReadSessionData

Called on a reconnect
================
*/
void G_ReadSessionData( gclient_t *client ) {

client->sess = g_sess[client - level.clients];

client->ps.fd.saberAnimLevel = client->sess.saberLevel;
client->ps.fd.saberDrawAnimLevel = client->sess.saberLevel;
client->ps.fd.forcePowerSelected = client->sess.selectedFP;
}

you can use the old initsessiondata for clients but for making ipstring you need to add at the bottom sess->IPstring[0] = 0;


/*
==================
G_InitWorldSession

==================
*/
void G_InitWorldSession( void ) {
char		gsessptr[MAX_STRING_CHARS];
char		s[MAX_STRING_CHARS];
int			gt;

trap_Cvar_VariableStringBuffer( "session", s, sizeof(s) );
gt = atoi( s );

// if the gametype changed since the last session, don't use any
// client sessions
if ( g_gametype.integer != gt ) {
	level.newSession = qtrue;
	G_Printf( "Gametype changed, clearing session data.\n" );
}


// bani - allocate client persistent session data
trap_TrueMalloc( (void **)&g_sess, g_maxclients.integer * sizeof( clientSession_t ) );
trap_Cvar_VariableStringBuffer( "gsess", gsessptr, sizeof( gsessptr ) );
if( !Q_stricmp( gsessptr, "" ) ) {
	G_LogPrintf("gsess mallocd\n");
	trap_Cvar_Set( "gsess", "1" );
	memset( g_sess, 0, g_maxclients.integer * sizeof( clientSession_t ) );
} else {
	fileHandle_t tmpfile;
	trap_FS_FOpenFile( "sess.dat", &tmpfile, FS_READ );
	trap_FS_Read( g_sess, g_maxclients.integer * sizeof( clientSession_t ), tmpfile );
	trap_FS_FCloseFile( tmpfile );
}
}

/*
==================
G_WriteSessionData

==================
*/
void G_WriteSessionData( void ) {
int		i;
fileHandle_t tmpfile;

trap_Cvar_Set( "session", va("%i", g_gametype.integer) );

for ( i = 0 ; i < level.maxclients ; i++ ) {
	if ( level.clients[i].pers.connected == CON_CONNECTED ) {
		G_WriteClientSessionData( &level.clients[i] );
	}
}
//save2file
trap_FS_FOpenFile( "sess.dat", &tmpfile, FS_WRITE );
trap_FS_Write( g_sess, level.maxclients * sizeof( clientSession_t ), tmpfile );
trap_FS_FCloseFile( tmpfile );
}

 

stick this in the bottom of clientSession_t in g_local.h:

 

char		IPstring[16];

 

stick this at the bottom of g_local.h before the namespace end line:

 

clientSession_t		*g_sess;

 

okay so now we go to ClientConnect in g_client.c

 

because i dont like using value over and over again and its a good idea to do it this way:

 

declare these:

char tmpIP[16];
char fkntmpstr[30];

 

	Q_strncpyz(tmpIP, Info_ValueForKey (userinfo, "ip"),sizeof(tmpIP) );

 

change this then too instead of checking value

 

if ( G_FilterPacket( tmpIP ) ) {

 

okay now down to session loading:

 

	// read or initialize the session data
if ( firstTime || level.newSession ) {
	G_InitSessionData( client, userinfo, isBot );
}
G_ReadSessionData( client );

 

get rid of that or comment it then we need to add:

 

	// read or initialize the session data
if ( firstTime ) {
  		G_InitSessionData( client, userinfo, isBot );
   } else if( level.newSession ) {
       Q_strncpyz(fkntmpstr, g_sess[client-level.clients].IPstring, sizeof(g_sess[client-level.clients].IPstring));
	G_InitSessionData( client, userinfo, isBot );
	Q_strncpyz(client->sess.IPstring, fkntmpstr, sizeof(fkntmpstr));
	G_WriteClientSessionData( client );
}
G_ReadSessionData( client );

if ( Q_stricmp(tmpIP, "" ) || tmpIP[0] != 0 ) {
	i=0;
	while(++i<strlen(tmpIP))if(tmpIP[i]==':')tmpIP[i]=0;
	Q_strncpyz(client->sess.IPstring, tmpIP, sizeof(client->sess.IPstring));
}

 

open up g_main.c and look for this in g_shutdowngame:

 

// write all the client session data so we can get it back
G_WriteSessionData();

 

add this below that:

 

trap_TrueFree( (void **)&g_sess );

 

gsess cvar stuff:

 

vmCvar_t	gsess;    // g_main.c

{ &gsess, "gsess", "", CVAR_INTERNAL | CVAR_ROM | CVAR_NORESTART, 0, qfalse}, // g_main.c

extern vmCvar_t	gsess; // g_local.h

 

that should be all, if you are having any other troubles let me know.

Posted

Danger Will Roberson, Danger! You don't free your dynamic memory after allocating it.

 

I think it would be wiser if you just create a static chunk of memory using the MAX_CLIENTS variable. That would be much more stable in terms of memory.

Posted

sorry but freeing the mem crashes :) and jka refuses to use malloc or free as in the real ones. dont think i didnt forget to free that mem, its just it doesnt like when its free'd. jka already has memleaks as it is cause of raven.

Posted

okay weird stick this in G_WriteSessionData below the closefile line:

 

trap_TrueFree( &g_sess );

 

it seems to just work now. and i think who i had working on it was only doing trap_TrueFree( g_sess ); and missing the & :p

Posted

JKA might have mem leaks but they aren't normally a problem in the long term. IE most servers can survive until their daily resets. The only real problem I've heard of is the lack of cloaking in Siege after the server has been running for a while.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...