Skip to content

Commit

Permalink
session handling improvements and added mod functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Chomenor committed Apr 3, 2022
1 parent 81d8e39 commit 5f71bc4
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 5 deletions.
4 changes: 4 additions & 0 deletions code/game/g_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ typedef struct {
void ( *callback )( trackedCvar_t *tc );
} cvarCallback_t;

typedef struct {
char s[BIG_INFO_STRING];
} info_string_t;

// tpType
typedef enum
{
Expand Down
93 changes: 88 additions & 5 deletions code/game/g_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,51 @@ and tournament restarts.
=======================================================================
*/

// Random identifier to prevent loading data from incompatible mods, in case
// server uses mod switching.
#define SESSION_VERSION "hszK3I2I"

extern int borgQueenClientNum;
extern int noJoinLimit;
extern int numKilled;

/*
================
(ModFN) InitClientSession
================
*/
LOGFUNCTION_VOID( ModFNDefault_InitClientSession, ( int clientNum, qboolean initialConnect, const info_string_t *info ),
( clientNum, initialConnect, info ), "G_MODFN_INITCLIENTSESSION" ) {
}

/*
================
(ModFN) GenerateClientSessionInfo
================
*/
LOGFUNCTION_VOID( ModFNDefault_GenerateClientSessionInfo, ( int clientNum, info_string_t *info ),
( clientNum, info ), "G_MODFN_GENERATECLIENTSESSIONINFO" ) {
}

/*
================
G_VerifySessionVersion
Returns qtrue if session data was written by compatible mod.
================
*/
static qboolean G_VerifySessionVersion( void ) {
char buffer[256];
char *version;
trap_Cvar_VariableStringBuffer( "session", buffer, sizeof( buffer ) );
version = strchr( buffer, '*' );
if ( version && !strcmp( &version[1], SESSION_VERSION ) ) {
return qtrue;
}

return qfalse;
}

/*
================
G_WriteClientSessionData
Expand All @@ -25,8 +66,10 @@ Called on game shutdown
================
*/
void G_WriteClientSessionData( gclient_t *client ) {
int clientNum = client - level.clients;
const char *s;
const char *var;
info_string_t info;

s = va("%i %i %i %i %i %i %i %i",
client->sess.sessionTeam,
Expand All @@ -39,9 +82,35 @@ void G_WriteClientSessionData( gclient_t *client ) {
client->sess.altSwapFlags
);

var = va( "session%i", client - level.clients );
var = va( "session%i", clientNum );

trap_Cvar_Set( var, s );

// Write session info
info.s[0] = '\0';
modfn.GenerateClientSessionInfo( clientNum, &info );
var = va( "session_info%i", clientNum );
trap_Cvar_Set( var, info.s );
}

/*
==================
G_RetrieveSessionInfo
Retrieves client session info segment in session_info* cvars.
This should only be called for clients that are reconnecting with firstTime=false,
otherwise invalid info may be returned.
==================
*/
void G_RetrieveSessionInfo( int clientNum, info_string_t *output ) {
output->s[0] = '\0';

if ( G_VerifySessionVersion() ) {
char buffer[256];
Com_sprintf( buffer, sizeof( buffer ), "session_info%i", clientNum );
trap_Cvar_VariableStringBuffer( buffer, output->s, sizeof( output->s ) );
}
}

/*
Expand All @@ -52,10 +121,11 @@ Called on a reconnect
================
*/
void G_ReadSessionData( gclient_t *client ) {
int clientNum = client - level.clients;
char s[MAX_STRING_CHARS];
const char *var;

var = va( "session%i", client - level.clients );
var = va( "session%i", clientNum );
trap_Cvar_VariableStringBuffer( var, s, sizeof(s) );

sscanf( s, "%i %i %i %i %i %i %i %i",
Expand All @@ -68,6 +138,13 @@ void G_ReadSessionData( gclient_t *client ) {
&client->sess.losses,
&client->sess.altSwapFlags
);

// Call mod initialization
{
info_string_t info;
G_RetrieveSessionInfo( clientNum, &info );
modfn.InitClientSession( clientNum, qfalse, &info );
}
}


Expand All @@ -79,6 +156,7 @@ Called on a first-time connect
================
*/
void G_InitSessionData( gclient_t *client, char *userinfo ) {
int clientNum = client - level.clients;
clientSession_t *sess;
const char *value;

Expand Down Expand Up @@ -147,7 +225,12 @@ void G_InitSessionData( gclient_t *client, char *userinfo ) {
sess->spectatorState = SPECTATOR_FREE;
sess->spectatorTime = level.time;

G_WriteClientSessionData( client );
// Call mod initialization
{
info_string_t info;
*info.s = '\0';
modfn.InitClientSession( clientNum, qtrue, &info );
}
}


Expand Down Expand Up @@ -181,10 +264,10 @@ G_WriteSessionData
void G_WriteSessionData( void ) {
int i;

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

for ( i = 0 ; i < level.maxclients ; i++ ) {
if ( level.clients[i].pers.connected == CON_CONNECTED ) {
if ( level.clients[i].pers.connected >= CON_CONNECTING ) {
G_WriteClientSessionData( &level.clients[i] );
}
}
Expand Down
11 changes: 11 additions & 0 deletions code/game/mods/g_mod_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ MOD_FUNCTION_DEF( GeneralInit, void, ( void ) )
// Called after G_RunFrame completes.
MOD_FUNCTION_DEF( PostRunFrame, void, ( void ) )

//////////////////////////
// session related
//////////////////////////

// Called to initialize client state when client is initially connecting, or to load saved client data
// when client is being reconnected from a map change/restart. Info string will be empty when initialConnect is true.
MOD_FUNCTION_DEF( InitClientSession, void, ( int clientNum, qboolean initialConnect, const info_string_t *info ) )

// Generates client info string data to be written to cvar on match exit.
MOD_FUNCTION_DEF( GenerateClientSessionInfo, void, ( int clientNum, info_string_t *info ) )

//////////////////////////
// player movement
//////////////////////////
Expand Down

0 comments on commit 5f71bc4

Please sign in to comment.