You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
306 lines
12 KiB
306 lines
12 KiB
//========= 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, |
|
unsigned long *lpThreadID ); |
|
|
|
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
|
|
|