2021-12-25 22:36:38 +01:00
# pragma once
2022-07-29 17:30:05 +02:00
# include "tier1/characterset.h"
2022-08-09 17:18:07 +02:00
# include "public/iconvar.h"
# include "public/iconcommand.h"
2021-12-25 22:36:38 +01:00
2022-02-21 17:56:31 +01:00
//-----------------------------------------------------------------------------
// Forward declarations
//-----------------------------------------------------------------------------
class ConCommandBase ;
//-----------------------------------------------------------------------------
// Any executable that wants to use ConVars need to implement one of
// these to hook up access to console variables.
//-----------------------------------------------------------------------------
class IConCommandBaseAccessor
{
public :
// Flags is a combination of FCVAR flags in cvar.h.
// hOut is filled in with a handle to the variable.
virtual bool RegisterConCommandBase ( ConCommandBase * pVar ) = 0 ;
} ;
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
// Purpose: Command buffer context
//-----------------------------------------------------------------------------
2022-03-28 12:03:07 +02:00
enum class ECommandTarget_t : int
2022-02-19 02:31:16 +01:00
{
CBUF_FIRST_PLAYER = 0 ,
CBUF_LAST_PLAYER = MAX_SPLITSCREEN_CLIENTS - 1 ,
CBUF_SERVER = CBUF_LAST_PLAYER + 1 ,
CBUF_COUNT ,
2022-03-28 12:03:07 +02:00
} ;
2022-02-19 02:31:16 +01:00
//-----------------------------------------------------------------------------
// Sources of console commands
//-----------------------------------------------------------------------------
enum class cmd_source_t : int
{
kCommandSrcCode ,
kCommandSrcClientCmd ,
kCommandSrcUserInput ,
kCommandSrcNetClient ,
kCommandSrcNetServer ,
kCommandSrcDemoFile ,
kCommandSrcInvalid = - 1
} ;
2022-02-14 23:16:24 +01:00
//-----------------------------------------------------------------------------
// Purpose: Command tokenizer
//-----------------------------------------------------------------------------
2021-12-25 22:36:38 +01:00
class CCommand
{
private :
enum
{
COMMAND_MAX_ARGC = 64 ,
COMMAND_MAX_LENGTH = 512 ,
} ;
public :
2022-07-30 00:43:40 +02:00
CCommand ( ) ;
2022-07-29 17:30:05 +02:00
CCommand ( int nArgC , const char * * ppArgV , cmd_source_t source ) ;
bool Tokenize ( const char * pCommand , cmd_source_t source , characterset_t * pBreakSet ) ;
2021-12-25 22:36:38 +01:00
2022-04-14 19:18:59 +02:00
int64_t ArgC ( void ) const ;
2022-02-14 23:16:24 +01:00
const char * * ArgV ( void ) const ;
const char * ArgS ( void ) const ;
const char * GetCommandString ( void ) const ;
const char * Arg ( int nIndex ) const ;
const char * operator [ ] ( int nIndex ) const ;
2021-12-25 22:36:38 +01:00
2022-07-29 17:30:05 +02:00
void Reset ( ) ;
int MaxCommandLength ( void ) const ;
2022-03-28 18:47:11 +02:00
bool HasOnlyDigits ( int nIndex ) const ;
2021-12-25 22:36:38 +01:00
private :
2022-07-29 17:30:05 +02:00
cmd_source_t m_nQueuedVal ;
2022-03-02 02:03:46 +01:00
int m_nArgc ;
2022-04-14 19:18:59 +02:00
int64_t m_nArgv0Size ;
2021-12-25 22:36:38 +01:00
char m_pArgSBuffer [ COMMAND_MAX_LENGTH ] ;
char m_pArgvBuffer [ COMMAND_MAX_LENGTH ] ;
const char * m_ppArgv [ COMMAND_MAX_ARGC ] ;
} ;
2022-02-14 23:16:24 +01:00
//-----------------------------------------------------------------------------
// Purpose: The base console invoked command/cvar interface
//-----------------------------------------------------------------------------
2021-12-25 22:36:38 +01:00
class ConCommandBase
{
public :
2022-08-13 12:39:57 +02:00
bool HasFlags ( int nFlags ) const ;
2022-01-09 16:14:17 +01:00
void AddFlags ( int nFlags ) ;
void RemoveFlags ( int nFlags ) ;
2022-02-23 00:18:46 +01:00
bool IsCommand ( void ) const ;
bool IsRegistered ( void ) const ;
2022-08-13 12:39:57 +02:00
2022-08-13 20:21:32 +02:00
bool IsFlagSet ( int nFlags ) const { return IsFlagSetInternal ( this , nFlags ) ; } ;
static bool IsFlagSetInternal ( const ConCommandBase * pCommandBase , int nFlags ) ;
2021-12-28 01:14:56 +01:00
2022-02-23 00:18:46 +01:00
int GetFlags ( void ) const ;
ConCommandBase * GetNext ( void ) const ;
2022-04-14 19:18:59 +02:00
const char * GetName ( void ) const ;
2022-02-23 00:18:46 +01:00
const char * GetHelpText ( void ) const ;
2022-02-23 15:56:03 +01:00
const char * GetUsageText ( void ) const ;
2022-02-23 00:18:46 +01:00
char * CopyString ( const char * szFrom ) const ;
2022-07-25 20:06:06 +02:00
IConCommandBase * m_pConCommandBaseVFTable ; //0x0000
2022-02-21 17:56:31 +01:00
ConCommandBase * m_pNext ; //0x0008
bool m_bRegistered ; //0x0010
char pad_0011 [ 7 ] ; //0x0011
const char * m_pszName ; //0x0018
const char * m_pszHelpString ; //0x0020
const char * m_pszUsageString ; //0x0028
IConCommandBaseAccessor * s_pAccessor ; //0x0030 <-- unused since executable is monolithic.
int m_nFlags ; //0x0038
char pad_003C [ 4 ] ; //0x003C
} ; //Size: 0x0040
//-----------------------------------------------------------------------------
// Purpose: The console invoked command
//-----------------------------------------------------------------------------
2022-02-23 00:18:46 +01:00
class ConCommand : public ConCommandBase
2022-02-21 17:56:31 +01:00
{
2022-08-13 19:41:45 +02:00
friend class CCvar ;
2021-12-25 22:36:38 +01:00
public :
2023-02-23 23:47:27 +01:00
static ConCommand * Create ( const char * szName , const char * szHelpString , const char * pszUsageString ,
int nFlags , FnCommandCallback_t pCallback , FnCommandCompletionCallback pCommandCompletionCallback ) ;
2022-08-08 01:40:28 +02:00
2022-08-04 17:37:30 +02:00
ConCommand ( void ) ;
2022-08-08 01:40:28 +02:00
~ ConCommand ( void ) ;
2022-11-18 22:10:20 +01:00
static void Init ( void ) ;
static void InitShipped ( void ) ;
static void PurgeShipped ( void ) ;
2022-02-23 00:18:46 +01:00
bool IsCommand ( void ) const ;
2022-02-21 17:56:31 +01:00
2022-08-04 17:37:30 +02:00
void * m_nNullCallBack ; //0x0040
void * m_pSubCallback ; //0x0048
// Call this function when executing the command
union
{
FnCommandCallbackV1_t m_fnCommandCallbackV1 ;
FnCommandCallback_t m_fnCommandCallback ;
ICommandCallback * m_pCommandCallback ;
} ;
union
{
FnCommandCompletionCallback m_fnCompletionCallback ;
ICommandCompletionCallback * m_pCommandCompletionCallback ;
} ;
bool m_bHasCompletionCallback : 1 ;
bool m_bUsingNewCommandCallback : 1 ;
bool m_bUsingCommandCallbackInterface : 1 ;
2022-02-21 17:56:31 +01:00
} ;
2021-12-25 22:36:38 +01:00
2022-04-09 02:18:57 +02:00
/* ==== COMMAND_BUFFER ================================================================================================================================================== */
2022-04-18 03:35:08 +02:00
inline CMemory p_Cbuf_AddText ;
inline auto Cbuf_AddText = p_Cbuf_AddText . RCast < void ( * ) ( ECommandTarget_t eTarget , const char * pText , cmd_source_t cmdSource ) > ( ) ;
2022-02-19 02:31:16 +01:00
2022-04-18 03:35:08 +02:00
inline CMemory p_Cbuf_Execute ;
inline auto Cbuf_Execute = p_Cbuf_Execute . RCast < void ( * ) ( void ) > ( ) ;
2022-02-19 02:31:16 +01:00
2022-09-22 21:37:58 +02:00
inline CMemory p_Cmd_ForwardToServer ;
inline auto v_Cmd_ForwardToServer = p_Cmd_ForwardToServer . RCast < bool ( * ) ( const CCommand * args ) > ( ) ;
2022-04-09 02:18:57 +02:00
/* ==== CONCOMMAND ====================================================================================================================================================== */
2022-04-18 03:35:08 +02:00
inline CMemory p_ConCommandBase_IsFlagSet ;
inline auto ConCommandBase_IsFlagSet = p_ConCommandBase_IsFlagSet . RCast < bool ( * ) ( ConCommandBase * pCommand , int nFlag ) > ( ) ;
2021-12-25 22:36:38 +01:00
2022-04-18 03:35:08 +02:00
inline CMemory p_NullSub ;
inline auto NullSub = p_NullSub . RCast < void ( * ) ( void ) > ( ) ;
2021-12-25 22:36:38 +01:00
2022-04-18 03:35:08 +02:00
inline CMemory p_CallbackStub ;
2022-08-04 17:37:30 +02:00
inline FnCommandCompletionCallback CallbackStub = p_CallbackStub . RCast < FnCommandCompletionCallback > ( ) ;
2021-12-25 22:36:38 +01:00
2022-08-15 22:29:16 +02:00
inline CMemory g_pConCommandVFTable ;
2021-12-25 22:36:38 +01:00
///////////////////////////////////////////////////////////////////////////////
2022-03-25 13:17:57 +01:00
ECommandTarget_t Cbuf_GetCurrentPlayer ( void ) ;
2021-12-25 22:36:38 +01:00
///////////////////////////////////////////////////////////////////////////////
2022-05-13 14:53:25 +02:00
class VConCommand : public IDetour
2021-12-25 22:36:38 +01:00
{
2022-04-11 01:44:30 +02:00
virtual void GetAdr ( void ) const
2021-12-25 22:36:38 +01:00
{
2023-01-25 11:19:53 +01:00
LogConAdr ( " ConCommand::`vftable' " , g_pConCommandVFTable . GetPtr ( ) ) ;
2023-01-25 02:26:52 +01:00
LogFunAdr ( " ConCommandBase::IsFlagSet " , p_ConCommandBase_IsFlagSet . GetPtr ( ) ) ;
LogFunAdr ( " Cbuf_AddText " , p_Cbuf_AddText . GetPtr ( ) ) ;
LogFunAdr ( " Cbuf_Execute " , p_Cbuf_Execute . GetPtr ( ) ) ;
LogFunAdr ( " Cmd_ForwardToServer " , p_Cmd_ForwardToServer . GetPtr ( ) ) ;
LogFunAdr ( " CallbackStub " , p_CallbackStub . GetPtr ( ) ) ;
LogFunAdr ( " NullSub " , p_NullSub . GetPtr ( ) ) ;
2021-12-25 22:36:38 +01:00
}
2022-04-18 03:35:08 +02:00
virtual void GetFun ( void ) const
{
2023-01-25 02:26:52 +01:00
p_ConCommandBase_IsFlagSet = g_GameDll . FindPatternSIMD ( " 85 51 38 0F 95 C0 C3 " ) ;
2022-12-01 22:44:55 +01:00
p_Cbuf_AddText = g_GameDll . FindPatternSIMD ( " 48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 63 D9 41 8B F8 48 8D 0D ?? ?? ?? ?? 48 8B F2 FF 15 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 41 B9 ?? ?? ?? ?? " ) ;
p_Cbuf_Execute = g_GameDll . FindPatternSIMD ( " 48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 FF 15 ?? ?? ?? ?? " ) ;
p_Cmd_ForwardToServer = g_GameDll . FindPatternSIMD ( " 48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 44 8B 59 04 " ) ;
p_NullSub = g_GameDll . FindPatternSIMD ( " C2 ?? ?? CC CC CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ?? " ) ;
p_CallbackStub = g_GameDll . FindPatternSIMD ( " 33 C0 C3 CC CC CC CC CC CC CC CC CC CC CC CC CC 80 49 68 08 " ) ;
2022-04-18 03:35:08 +02:00
2022-08-04 17:37:30 +02:00
Cbuf_AddText = p_Cbuf_AddText . RCast < void ( * ) ( ECommandTarget_t , const char * , cmd_source_t ) > ( ) ; /*48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 63 D9 41 8B F8 48 8D 0D ?? ?? ?? ?? 48 8B F2 FF 15 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 41 B9 ?? ?? ?? ??*/
Cbuf_Execute = p_Cbuf_Execute . RCast < void ( * ) ( void ) > ( ) ; /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 FF 15 ?? ?? ?? ??*/
2022-09-22 21:37:58 +02:00
v_Cmd_ForwardToServer = p_Cmd_ForwardToServer . RCast < bool ( * ) ( const CCommand * ) > ( ) ; /*48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 81 EC ?? ?? ?? ?? 44 8B 59 04*/
2022-08-04 17:37:30 +02:00
ConCommandBase_IsFlagSet = p_ConCommandBase_IsFlagSet . RCast < bool ( * ) ( ConCommandBase * , int ) > ( ) ; /*85 51 38 0F 95 C0 C3*/
NullSub = p_NullSub . RCast < void ( * ) ( void ) > ( ) ; /*C2 00 00 CC CC CC CC CC CC CC CC CC CC CC CC CC 40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ??*/
CallbackStub = p_CallbackStub . RCast < FnCommandCompletionCallback > ( ) ; /*33 C0 C3 CC CC CC CC CC CC CC CC CC CC CC CC CC 80 49 68 08*/ /*UserMathErrorFunction*/
2022-04-18 03:35:08 +02:00
}
2022-11-10 00:53:12 +01:00
virtual void GetVar ( void ) const { }
virtual void GetCon ( void ) const
2022-04-18 03:35:08 +02:00
{
2022-08-15 22:29:16 +02:00
g_pConCommandVFTable = g_GameDll . GetVirtualMethodTable ( " .?AVConCommand@@ " ) ;
2022-04-18 03:35:08 +02:00
}
2023-01-25 02:26:52 +01:00
virtual void Attach ( void ) const ;
virtual void Detach ( void ) const ;
2021-12-25 22:36:38 +01:00
} ;
///////////////////////////////////////////////////////////////////////////////