Record and replay broadcast server commands (chat, prints)
Capture broadcast server commands (chat, print, cp, etc.) from SV_SendServerCommand when cl==NULL. Buffer up to 64 commands per frame. Written after configstrings in the demo file, replayed to the spectator client during playback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
60b50ce224
commit
4f0d46024b
3 changed files with 53 additions and 0 deletions
|
|
@ -349,6 +349,7 @@ void SVD_StopRecord_f( void );
|
|||
void SVD_RecordFrame( void );
|
||||
void SVD_ResetDeltaState( void );
|
||||
void SVD_AutoRecord( void );
|
||||
void SVD_CaptureServerCommand( const char *cmd );
|
||||
void SVD_Play_f( void );
|
||||
void SVD_StopPlay_f( void );
|
||||
void SVD_Stop_f( void );
|
||||
|
|
|
|||
|
|
@ -177,6 +177,9 @@ void QDECL SV_SendServerCommand(client_t *cl, const char *fmt, ...) {
|
|||
return;
|
||||
}
|
||||
|
||||
// capture broadcast commands for demo recording
|
||||
SVD_CaptureServerCommand( (char *)message );
|
||||
|
||||
// hack to echo broadcast prints to console
|
||||
if ( com_dedicated->integer && !strncmp( (char *)message, "print", 5) ) {
|
||||
Com_Printf ("broadcast: %s\n", SV_ExpandNewlines((char *)message) );
|
||||
|
|
|
|||
|
|
@ -78,6 +78,9 @@ typedef struct {
|
|||
qboolean active;
|
||||
} svdPlayerState_t;
|
||||
|
||||
#define SVD_MAX_SERVERCMDS 64
|
||||
#define SVD_MAX_SERVERCMD_LEN 1024
|
||||
|
||||
typedef struct {
|
||||
// recording
|
||||
fileHandle_t recordFile;
|
||||
|
|
@ -87,6 +90,10 @@ typedef struct {
|
|||
svdEntityState_t prevEntities[MAX_GENTITIES]; // previous frame for delta
|
||||
svdPlayerState_t prevPlayers[MAX_CLIENTS]; // previous frame player states
|
||||
|
||||
// buffered server commands for current frame
|
||||
char serverCmds[SVD_MAX_SERVERCMDS][SVD_MAX_SERVERCMD_LEN];
|
||||
int numServerCmds;
|
||||
|
||||
// playback
|
||||
fileHandle_t playFile;
|
||||
qboolean playing;
|
||||
|
|
@ -368,6 +375,15 @@ static void SVD_WriteFrame( fileHandle_t f ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write buffered server commands (chat, prints, etc.)
|
||||
SVD_WriteShort( f, (short)demo.numServerCmds );
|
||||
for ( i = 0; i < demo.numServerCmds; i++ ) {
|
||||
short len = (short)( strlen( demo.serverCmds[i] ) + 1 );
|
||||
SVD_WriteShort( f, len );
|
||||
FS_Write( demo.serverCmds[i], len, f );
|
||||
}
|
||||
demo.numServerCmds = 0;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
|
@ -488,6 +504,21 @@ Called from SV_Frame() after the game has run its frame.
|
|||
Reset delta compression state. Call on map_restart so the next
|
||||
recorded frame writes full entity/player states from baseline.
|
||||
*/
|
||||
/*
|
||||
Capture a broadcast server command for the current frame.
|
||||
Called from SV_SendServerCommand when cl == NULL (broadcast).
|
||||
*/
|
||||
void SVD_CaptureServerCommand( const char *cmd ) {
|
||||
if ( !demo.recording ) {
|
||||
return;
|
||||
}
|
||||
if ( demo.numServerCmds >= SVD_MAX_SERVERCMDS ) {
|
||||
return; // overflow, drop command
|
||||
}
|
||||
Q_strncpyz( demo.serverCmds[demo.numServerCmds], cmd, SVD_MAX_SERVERCMD_LEN );
|
||||
demo.numServerCmds++;
|
||||
}
|
||||
|
||||
void SVD_ResetDeltaState( void ) {
|
||||
if ( !demo.recording ) {
|
||||
return;
|
||||
|
|
@ -770,6 +801,24 @@ static qboolean SVD_ReadFrame( fileHandle_t f ) {
|
|||
}
|
||||
}
|
||||
|
||||
// read server commands (chat, prints, etc.) and replay to spectator
|
||||
{
|
||||
short numCmds = SVD_ReadShort( f );
|
||||
for ( i = 0; i < numCmds; i++ ) {
|
||||
short len = SVD_ReadShort( f );
|
||||
char buf[SVD_MAX_SERVERCMD_LEN];
|
||||
if ( len > 0 && len < (short)sizeof(buf) ) {
|
||||
FS_Read( buf, len, f );
|
||||
buf[len - 1] = '\0';
|
||||
// send to the spectator client
|
||||
if ( demo.spectatorClientNum < sv_maxclients->integer
|
||||
&& svs.clients[demo.spectatorClientNum].state >= CS_PRIMED ) {
|
||||
SV_SendServerCommand( &svs.clients[demo.spectatorClientNum], "%s", buf );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue