Auto-record demos with svdemo_autorecord cvar
Set svdemo_autorecord 1 to automatically record a demo on every map load. Demo files are named <mapname>_YYYYMMDD_HHMMSS.svdm in the svdemos/ directory. Refactored SVD_Record_f to use SVD_StartRecording helper so both manual and auto recording share the same code path. Also fixed prevPlayers delta state not being cleared on recording start. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6fc96e7070
commit
e58414f564
3 changed files with 63 additions and 14 deletions
|
|
@ -348,6 +348,7 @@ void SVD_Record_f( void );
|
|||
void SVD_StopRecord_f( void );
|
||||
void SVD_RecordFrame( void );
|
||||
void SVD_ResetDeltaState( void );
|
||||
void SVD_AutoRecord( void );
|
||||
void SVD_Play_f( void );
|
||||
void SVD_StopPlay_f( void );
|
||||
void SVD_Stop_f( void );
|
||||
|
|
|
|||
|
|
@ -552,6 +552,9 @@ void SV_SpawnServer( char *server, qboolean killBots ) {
|
|||
Hunk_SetMark();
|
||||
|
||||
Com_Printf ("-----------------------------------\n");
|
||||
|
||||
// auto-record demo if enabled
|
||||
SVD_AutoRecord();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -618,6 +621,9 @@ void SV_Init (void) {
|
|||
sv_lanForceRate = Cvar_Get ("sv_lanForceRate", "1", CVAR_ARCHIVE );
|
||||
sv_strictAuth = Cvar_Get ("sv_strictAuth", "1", CVAR_ARCHIVE );
|
||||
|
||||
// server-side demo auto-recording
|
||||
Cvar_Get ("svdemo_autorecord", "0", CVAR_ARCHIVE);
|
||||
|
||||
// initialize bot cvars so they are listed and can be set before loading the botlib
|
||||
SV_BotInitCvars();
|
||||
|
||||
|
|
|
|||
|
|
@ -321,41 +321,83 @@ static void SVD_WriteFrame( fileHandle_t f ) {
|
|||
// Recording commands
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
void SVD_Record_f( void ) {
|
||||
char name[MAX_OSPATH];
|
||||
char *s;
|
||||
/*
|
||||
Start recording a demo with the given name.
|
||||
Returns qtrue on success.
|
||||
*/
|
||||
static qboolean SVD_StartRecording( const char *demoname ) {
|
||||
char path[MAX_OSPATH];
|
||||
|
||||
if ( demo.recording ) {
|
||||
Com_Printf( "Already recording a server demo.\n" );
|
||||
return;
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( sv.state != SS_GAME ) {
|
||||
Com_Printf( "Not running a server.\n" );
|
||||
return;
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
Com_sprintf( path, sizeof(path), "svdemos/%s.svdm", demoname );
|
||||
|
||||
demo.recordFile = FS_FOpenFileWrite( path );
|
||||
if ( !demo.recordFile ) {
|
||||
Com_Printf( "ERROR: couldn't open %s for writing.\n", path );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
Com_Printf( "Recording server demo to %s\n", path );
|
||||
demo.recording = qtrue;
|
||||
|
||||
// clear delta state for fresh recording
|
||||
Com_Memset( demo.prevEntities, 0, sizeof(demo.prevEntities) );
|
||||
Com_Memset( demo.prevPlayers, 0, sizeof(demo.prevPlayers) );
|
||||
|
||||
SVD_WriteHeader( demo.recordFile );
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
void SVD_Record_f( void ) {
|
||||
char *s;
|
||||
|
||||
s = Cmd_Argv(1);
|
||||
if ( !s[0] ) {
|
||||
Com_Printf( "Usage: svdemo_record <demoname>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Com_sprintf( name, sizeof(name), "svdemos/%s.svdm", s );
|
||||
SVD_StartRecording( s );
|
||||
}
|
||||
|
||||
demo.recordFile = FS_FOpenFileWrite( name );
|
||||
if ( !demo.recordFile ) {
|
||||
Com_Printf( "ERROR: couldn't open %s for writing.\n", name );
|
||||
/*
|
||||
Auto-record: called from SV_SpawnServer after the map is fully loaded.
|
||||
Generates a name from map name + timestamp.
|
||||
*/
|
||||
void SVD_AutoRecord( void ) {
|
||||
char demoname[MAX_OSPATH];
|
||||
const char *mapname;
|
||||
qtime_t now;
|
||||
|
||||
if ( demo.recording || demo.playing ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Printf( "Recording server demo to %s\n", name );
|
||||
demo.recording = qtrue;
|
||||
if ( !Cvar_VariableIntegerValue( "svdemo_autorecord" ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// clear delta state for fresh recording
|
||||
Com_Memset( demo.prevEntities, 0, sizeof(demo.prevEntities) );
|
||||
if ( sv.state != SS_GAME ) {
|
||||
return;
|
||||
}
|
||||
|
||||
SVD_WriteHeader( demo.recordFile );
|
||||
mapname = Cvar_VariableString( "mapname" );
|
||||
Com_RealTime( &now );
|
||||
Com_sprintf( demoname, sizeof(demoname), "%s_%04d%02d%02d_%02d%02d%02d",
|
||||
mapname,
|
||||
1900 + now.tm_year, 1 + now.tm_mon, now.tm_mday,
|
||||
now.tm_hour, now.tm_min, now.tm_sec );
|
||||
|
||||
SVD_StartRecording( demoname );
|
||||
}
|
||||
|
||||
void SVD_StopRecord_f( void ) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue