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 :
2022-08-08 01:40:28 +02:00
static ConCommand * Create ( const char * szName , const char * szHelpString , int nFlags , FnCommandCallback_t pCallback , FnCommandCompletionCallback pCommandCompletionCallback ) ;
2022-08-04 17:37:30 +02:00
ConCommand ( void ) ;
2022-08-08 01:40:28 +02:00
~ ConCommand ( void ) ;
2022-02-21 17:56:31 +01:00
void Init ( void ) ;
2022-04-14 19:18:59 +02:00
void InitShipped ( void ) ;
void PurgeShipped ( void ) const ;
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-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-04-18 03:35:08 +02:00
inline CMemory g_pConCommandVtable ;
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
void ConCommand_Attach ( ) ;
void ConCommand_Detach ( ) ;
2022-01-09 16:14:17 +01:00
extern ConCommand * g_pConCommand ;
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
{
2022-05-13 14:53:25 +02:00
spdlog : : debug ( " | FUN: Cbuf_AddText : {:#18x} | \n " , p_Cbuf_AddText . GetPtr ( ) ) ;
spdlog : : debug ( " | FUN: Cbuf_Execute : {:#18x} | \n " , p_Cbuf_Execute . GetPtr ( ) ) ;
spdlog : : debug ( " +----------------------------------------------------------------+ \n " ) ;
spdlog : : debug ( " | FUN: ConCommandBase::IsFlagSet : {:#18x} | \n " , p_ConCommandBase_IsFlagSet . GetPtr ( ) ) ;
spdlog : : debug ( " +----------------------------------------------------------------+ \n " ) ;
spdlog : : debug ( " | FUN: CallbackStub : {:#18x} | \n " , p_CallbackStub . GetPtr ( ) ) ;
spdlog : : debug ( " | FUN: NullSub : {:#18x} | \n " , p_NullSub . GetPtr ( ) ) ;
spdlog : : debug ( " +----------------------------------------------------------------+ \n " ) ;
spdlog : : debug ( " | VAR: g_pConCommandVtable : {:#18x} | \n " , g_pConCommandVtable . GetPtr ( ) ) ;
spdlog : : debug ( " +----------------------------------------------------------------+ \n " ) ;
2021-12-25 22:36:38 +01:00
}
2022-04-18 03:35:08 +02:00
virtual void GetFun ( void ) const
{
2022-08-09 03:02:00 +02:00
p_Cbuf_AddText = g_GameDll . FindPatternSIMD ( reinterpret_cast < rsig_t > ( " \x48 \x89 \x5C \x24 \x00 \x48 \x89 \x74 \x24 \x00 \x57 \x48 \x83 \xEC \x20 \x48 \x63 \xD9 \x41 \x8B \xF8 \x48 \x8D \x0D \x00 \x00 \x00 \x00 \x48 \x8B \xF2 \xFF \x15 \x00 \x00 \x00 \x00 \x48 \x8D \x05 \x00 \x00 \x00 \x00 \x41 \xB9 \x00 \x00 \x00 \x00 " ) , " xxxx?xxxx?xxxxxxxxxxxxxx????xxxxx????xxx????xx???? " ) ;
p_Cbuf_Execute = g_GameDll . FindPatternSIMD ( reinterpret_cast < rsig_t > ( " \x48 \x89 \x5C \x24 \x00 \x48 \x89 \x6C \x24 \x00 \x48 \x89 \x74 \x24 \x00 \x57 \x48 \x83 \xEC \x20 \xFF \x15 \x00 \x00 \x00 \x00 " ) , " xxxx?xxxx?xxxx?xxxxxxx???? " ) ;
p_ConCommandBase_IsFlagSet = g_GameDll . FindPatternSIMD ( reinterpret_cast < rsig_t > ( " \x85 \x51 \x38 \x0F \x95 \xC0 \xC3 " ) , " xxxxxxx " ) ;
p_NullSub = g_GameDll . FindPatternSIMD ( reinterpret_cast < rsig_t > ( " \xC2 \x00 \x00 \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \x40 \x53 \x48 \x83 \xEC \x20 \x48 \x8D \x05 \x00 \x00 \x00 \x00 " ) , " xxxxxxxxxxxxxxxxxxxxxxxxx???? " ) ;
p_CallbackStub = g_GameDll . FindPatternSIMD ( reinterpret_cast < rsig_t > ( " \x33 \xC0 \xC3 \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \xCC \x80 \x49 \x68 \x08 " ) , " xxxxxxxxxxxxxxxxxxxx " ) ;
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 ?? ?? ?? ??*/
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
}
virtual void GetVar ( void ) const
{
2022-08-13 21:38:44 +02:00
g_pConCommandVtable = g_GameDll . FindPatternSIMD ( reinterpret_cast < rsig_t > (
" \x48 \x89 \x5C \x24 \x00 \x48 \x89 \x74 \x24 \x00 \x48 \x89 \x7C \x24 \x00 \x55 \x41 \x54 \x41 \x55 \x41 \x56 \x41 \x57 \x48 \x8B \xEC \x48 \x83 \xEC \x50 \x48 \x8B \x15 \x00 \x00 \x00 \x00 " ) ,
" xxxx?xxxx?xxxx?xxxxxxxxxxxxxxxxxxx???? " ) . FindPatternSelf ( " 4C 8D 25 " , CMemory : : Direction : : DOWN , 150 ) . ResolveRelativeAddressSelf ( 0x3 , 0x7 ) ;
2022-04-18 03:35:08 +02:00
}
2022-04-11 01:44:30 +02:00
virtual void GetCon ( void ) const { }
virtual void Attach ( void ) const { }
virtual void Detach ( void ) const { }
2021-12-25 22:36:38 +01:00
} ;
///////////////////////////////////////////////////////////////////////////////
2022-05-13 14:53:25 +02:00
REGISTER ( VConCommand ) ;