source-engine/public/tier0/vcrmode.h

307 lines
12 KiB
C
Raw Permalink Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: VCR mode records a client's game and allows you to
// play it back and reproduce it exactly. When playing it back, nothing
// is simulated on the server, but all server packets are recorded.
//
// Most of the VCR mode functionality is accomplished through hooks
// called at various points in the engine.
//
// $NoKeywords: $
//===========================================================================//
#ifndef VCRMODE_H
#define VCRMODE_H
#ifdef _WIN32
#include <process.h>
#endif
#ifdef _WIN32
#pragma once
#endif
#include "tier0/platform.h"
#include "tier0/vcr_shared.h"
#include "tier0/dbg.h"
#ifdef POSIX
DBG_INTERFACE const char *BuildCmdLine( int argc, char **argv, bool fAddSteam = true );
tchar *GetCommandLine();
#endif
#ifdef _X360
#define NO_VCR 1
#endif
// Enclose lines of code in this if you don't want anything in them written to or read from the VCR file.
#ifndef NO_VCR
#define NOVCR(x) \
{\
VCRSetEnabled(0);\
x;\
VCRSetEnabled(1);\
}
#else
#define NOVCR(x) \
{\
x;\
}
#endif
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
struct InputEvent_t;
//-----------------------------------------------------------------------------
// Definitions.
//-----------------------------------------------------------------------------
enum VCRMode_t
{
VCR_Invalid=-1,
VCR_Disabled=0,
VCR_Record,
VCR_Playback
};
//-----------------------------------------------------------------------------
// Functions.
//-----------------------------------------------------------------------------
abstract_class IVCRHelpers
{
public:
virtual void ErrorMessage( const tchar *pMsg ) = 0;
virtual void* GetMainWindow() = 0;
};
// Used by the vcrtrace program.
abstract_class IVCRTrace
{
public:
virtual VCREvent ReadEvent() = 0;
virtual void Read( void *pDest, int size ) = 0;
};
typedef struct VCR_s
{
// Start VCR record or play.
int (*Start)( tchar const *pFilename, bool bRecord, IVCRHelpers *pHelpers );
void (*End)();
// Used by the VCR trace app.
IVCRTrace* (*GetVCRTraceInterface)();
// Get the current mode the VCR is in.
VCRMode_t (*GetMode)();
// This can be used to block out areas of code that are unpredictable (like things triggered by WM_TIMER messages).
// Note: this enables/disables VCR mode usage on a PER-THREAD basis. The assumption is that you're marking out
// specific sections of code that you don't want to use VCR mode inside of, but you're not intending to
// stop all the other threads from using VCR mode.
void (*SetEnabled)(int bEnabled);
// This can be called any time to put in a debug check to make sure things are synchronized.
void (*SyncToken)(tchar const *pToken);
// Hook for Sys_FloatTime().
double (*Hook_Sys_FloatTime)(double time);
// Note: this makes no guarantees about msg.hwnd being the same on playback. If it needs to be, then we need to add
// an ID system for Windows and store the ID like in Goldsrc.
int (*Hook_PeekMessage)(
struct tagMSG *msg,
void *hWnd,
unsigned int wMsgFilterMin,
unsigned int wMsgFilterMax,
unsigned int wRemoveMsg
);
// Call this to record game messages.
void (*Hook_RecordGameMsg)( const InputEvent_t &event );
void (*Hook_RecordEndGameMsg)();
// Call this to playback game messages until it returns false.
bool (*Hook_PlaybackGameMsg)( InputEvent_t *pEvent );
// Hook for recvfrom() calls. This replaces the recvfrom() call.
int (*Hook_recvfrom)(int s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen);
void (*Hook_GetCursorPos)(struct tagPOINT *pt);
void (*Hook_ScreenToClient)(void *hWnd, struct tagPOINT *pt);
void (*Hook_Cmd_Exec)(tchar **f);
tchar* (*Hook_GetCommandLine)();
// Registry hooks.
long (*Hook_RegOpenKeyEx)( void *hKey, const tchar *lpSubKey, unsigned long ulOptions, unsigned long samDesired, void *pHKey );
long (*Hook_RegSetValueEx)(void *hKey, tchar const *lpValueName, unsigned long Reserved, unsigned long dwType, uint8 const *lpData, unsigned long cbData);
long (*Hook_RegQueryValueEx)(void *hKey, tchar const *lpValueName, unsigned long *lpReserved, unsigned long *lpType, uint8 *lpData, unsigned long *lpcbData);
long (*Hook_RegCreateKeyEx)(void *hKey, tchar const *lpSubKey, unsigned long Reserved, tchar *lpClass, unsigned long dwOptions, unsigned long samDesired, void *lpSecurityAttributes, void *phkResult, unsigned long *lpdwDisposition);
void (*Hook_RegCloseKey)(void *hKey);
// hInput is a HANDLE.
int (*Hook_GetNumberOfConsoleInputEvents)( void *hInput, unsigned long *pNumEvents );
// hInput is a HANDLE.
// pRecs is an INPUT_RECORD pointer.
int (*Hook_ReadConsoleInput)( void *hInput, void *pRecs, int nMaxRecs, unsigned long *pNumRead );
// This calls time() then gives you localtime()'s result.
void (*Hook_LocalTime)( struct tm *today );
short (*Hook_GetKeyState)( int nVirtKey );
// TCP calls.
int (*Hook_recv)( int s, char *buf, int len, int flags );
int (*Hook_send)( int s, const char *buf, int len, int flags );
// These can be used to add events without having to modify VCR mode.
// pEventName is used for verification to make sure it's playing back correctly.
// If pEventName is null, then verification is not performed.
void (*GenericRecord)( const tchar *pEventName, const void *pData, int len );
// Returns the number of bytes written in the generic event.
// If bForceLenSame is true, then it will error out unless the value in the VCR file is the same as maxLen.
int (*GenericPlayback)( const tchar *pEventName, void *pOutData, int maxLen, bool bForceLenSame );
// If you just want to record and playback a value and not worry about whether or not you're
// recording or playing back, use this. It also will do nothing if you're not recording or playing back.
//
// NOTE: also see GenericValueVerify, which allows you to have it VERIFY that pData's contents are the same upon playback
// (rather than just copying whatever is in the VCR file into pData).
void (*GenericValue)( const tchar *pEventName, void *pData, int maxLen );
// Get the current percent (0.0 - 1.0) that it's played back through the file (only valid in playback).
double (*GetPercentCompleted)();
// If you use this, then any VCR stuff the thread does will work with VCR mode.
// This mirrors the Windows API CreateThread function and returns a HANDLE the same way.
void* (*Hook_CreateThread)(
void *lpThreadAttributes,
unsigned long dwStackSize,
void *lpStartAddress,
void *lpParameter,
unsigned long dwCreationFlags,
2022-02-23 11:50:30 +00:00
uintp *lpThreadID );
2020-04-22 16:56:21 +00:00
unsigned long (*Hook_WaitForSingleObject)(
void *handle,
unsigned long dwMilliseconds );
void (*Hook_EnterCriticalSection)( void *pCS );
void (*Hook_Time)( long *pTime );
// String value. Playback just verifies that the incoming string is the same as it was when recording.
void (*GenericString)( const char *pEventName, const char *pString );
// Works like GenericValue, except upon playback it will verify that pData's contents are the same as it was during recording.
void (*GenericValueVerify)( const tchar *pEventName, const void *pData, int maxLen );
unsigned long (*Hook_WaitForMultipleObjects)( uint32 nHandles, const void **pHandles, int bWaitAll, uint32 timeout );
} VCR_t;
#ifndef NO_VCR
// In the launcher, this is created by vcrmode.c.
// In the engine, this is set when the launcher initializes its DLL.
PLATFORM_INTERFACE VCR_t *g_pVCR;
#endif
#ifndef NO_VCR
#define VCRStart g_pVCR->Start
#define VCREnd g_pVCR->End
#define VCRGetVCRTraceInterface g_pVCR->GetVCRTraceInterface
#define VCRGetMode g_pVCR->GetMode
#define VCRSetEnabled g_pVCR->SetEnabled
#define VCRSyncToken g_pVCR->SyncToken
#define VCRGenericString g_pVCR->GenericString
#define VCRGenericValueVerify g_pVCR->GenericValueVerify
#define VCRHook_Sys_FloatTime g_pVCR->Hook_Sys_FloatTime
#define VCRHook_PeekMessage g_pVCR->Hook_PeekMessage
#define VCRHook_RecordGameMsg g_pVCR->Hook_RecordGameMsg
#define VCRHook_RecordEndGameMsg g_pVCR->Hook_RecordEndGameMsg
#define VCRHook_PlaybackGameMsg g_pVCR->Hook_PlaybackGameMsg
#define VCRHook_recvfrom g_pVCR->Hook_recvfrom
#define VCRHook_GetCursorPos g_pVCR->Hook_GetCursorPos
#define VCRHook_ScreenToClient g_pVCR->Hook_ScreenToClient
#define VCRHook_Cmd_Exec g_pVCR->Hook_Cmd_Exec
#define VCRHook_GetCommandLine g_pVCR->Hook_GetCommandLine
#define VCRHook_RegOpenKeyEx g_pVCR->Hook_RegOpenKeyEx
#define VCRHook_RegSetValueEx g_pVCR->Hook_RegSetValueEx
#define VCRHook_RegQueryValueEx g_pVCR->Hook_RegQueryValueEx
#define VCRHook_RegCreateKeyEx g_pVCR->Hook_RegCreateKeyEx
#define VCRHook_RegCloseKey g_pVCR->Hook_RegCloseKey
#define VCRHook_GetNumberOfConsoleInputEvents g_pVCR->Hook_GetNumberOfConsoleInputEvents
#define VCRHook_ReadConsoleInput g_pVCR->Hook_ReadConsoleInput
#define VCRHook_LocalTime g_pVCR->Hook_LocalTime
#define VCRHook_GetKeyState g_pVCR->Hook_GetKeyState
#define VCRHook_recv g_pVCR->Hook_recv
#define VCRHook_send g_pVCR->Hook_send
#define VCRGenericRecord g_pVCR->GenericRecord
#define VCRGenericPlayback g_pVCR->GenericPlayback
#define VCRGenericValue g_pVCR->GenericValue
#define VCRGetPercentCompleted g_pVCR->GetPercentCompleted
#define VCRHook_CreateThread g_pVCR->Hook_CreateThread
#define VCRHook_WaitForSingleObject g_pVCR->Hook_WaitForSingleObject
#define VCRHook_EnterCriticalSection g_pVCR->Hook_EnterCriticalSection
#define VCRHook_Time g_pVCR->Hook_Time
#define VCRHook_WaitForMultipleObjects( a, b, c, d) g_pVCR->Hook_WaitForMultipleObjects( a, (const void **)b, c, d)
#else
#define VCRStart( a, b, c ) (1)
#define VCREnd ((void)(0))
#define VCRGetVCRTraceInterface (NULL)
#define VCRGetMode() (VCR_Disabled)
#define VCRSetEnabled( a ) ((void)(0))
#define VCRSyncToken( a ) ((void)(0))
#define VCRGenericRecord MUST_IFDEF_OUT_GenericRecord
#define VCRGenericPlayback MUST_IFDEF_OUT_GenericPlayback
#define VCRGenericValue MUST_IFDEF_OUT_GenericValue
#define VCRGenericString MUST_IFDEF_OUT_GenericString
#define VCRGenericValueVerify MUST_IFDEF_OUT_GenericValueVerify
#define VCRGetPercentCompleted() (0.0f)
#define VCRHook_Sys_FloatTime Sys_FloatTime
#define VCRHook_PeekMessage PeekMessage
#define VCRHook_RecordGameMsg RecordGameMsg
#define VCRHook_RecordEndGameMsg RecordEndGameMsg
#define VCRHook_PlaybackGameMsg PlaybackGameMsg
#define VCRHook_recvfrom recvfrom
#define VCRHook_GetCursorPos GetCursorPos
#define VCRHook_ScreenToClient ScreenToClient
#define VCRHook_Cmd_Exec( a ) ((void)(0))
#define VCRHook_GetCommandLine GetCommandLine
#define VCRHook_RegOpenKeyEx RegOpenKeyEx
#define VCRHook_RegSetValueEx RegSetValueEx
#define VCRHook_RegQueryValueEx RegQueryValueEx
#define VCRHook_RegCreateKeyEx RegCreateKeyEx
#define VCRHook_RegCloseKey RegCloseKey
#define VCRHook_GetNumberOfConsoleInputEvents GetNumberOfConsoleInputEvents
#define VCRHook_ReadConsoleInput ReadConsoleInput
#define VCRHook_LocalTime( a ) memset(a, 0, sizeof(*a));
#define VCRHook_GetKeyState GetKeyState
#define VCRHook_recv recv
#define VCRHook_send send
#if defined( _X360 )
#define VCRHook_CreateThread CreateThread
#else
#define VCRHook_CreateThread (void*)_beginthreadex
#endif
#define VCRHook_WaitForSingleObject WaitForSingleObject
#define VCRHook_EnterCriticalSection EnterCriticalSection
#define VCRHook_WaitForMultipleObjects( a, b, c, d) WaitForMultipleObjects( a, (const HANDLE *)b, c, d)
#define VCRHook_Time Time
#endif
#endif // VCRMODE_H