2019-12-03 23:28:14 +00:00
# pragma once
# include <Windows.h>
2020-01-03 02:22:09 +00:00
# include <DbgHelp.h>
# define ASMJIT_EMBED
# define ASMTK_EMBED
2019-12-03 23:28:14 +00:00
# include <regex>
# include <sstream>
2020-01-03 02:22:09 +00:00
# include <string>
2019-12-03 23:28:14 +00:00
2020-01-03 02:22:09 +00:00
# include <asmtk/asmtk.h>
2019-12-03 23:28:14 +00:00
# include "Scrapland.hpp"
# include "Util.hpp"
void DllUnload ( ) ;
void unhook_d3d8 ( ) ;
void hook_d3d8 ( ) ;
2020-01-03 02:22:09 +00:00
struct Command ;
typedef void ( _cdecl * t_cmd_func ) ( Command * , vector < string > ) ;
size_t assemble ( vector < string > assembly , uint64_t base ) {
using namespace asmjit ;
using namespace asmtk ;
char err_msg [ 1024 ] ;
Error err ;
CodeInfo ci ( ArchInfo : : kIdX86 ) ;
ci . setBaseAddress ( base ) ;
CodeHolder code ;
code . init ( ci ) ;
x86 : : Assembler a ( & code ) ;
AsmParser p ( & a ) ;
for ( string line : assembly ) {
if ( err = p . parse ( ( line + " \n " ) . c_str ( ) ) ) {
snprintf ( err_msg , 1024 , " PARSE ERROR: [%s] %08x (%s) \n " , line . c_str ( ) , err , DebugUtils : : errorAsString ( err ) ) ;
scrap_log ( ERR_COLOR , err_msg ) ;
return 0 ;
}
}
if ( err = code . flatten ( ) ) {
snprintf ( err_msg , 1024 , " FLATTEN ERROR: %08x (%s) \n " , err , DebugUtils : : errorAsString ( err ) ) ;
scrap_log ( ERR_COLOR , err_msg ) ;
return 0 ;
}
if ( err = code . resolveUnresolvedLinks ( ) ) {
snprintf ( err_msg , 1024 , " RESOLVE ERROR: %08x (%s) \n " , err , DebugUtils : : errorAsString ( err ) ) ;
scrap_log ( ERR_COLOR , err_msg ) ;
return 0 ;
}
CodeBuffer & buffer = code . sectionById ( 0 ) - > buffer ( ) ;
if ( base = = 0 ) {
return buffer . size ( ) ;
}
MEMORY_BASIC_INFORMATION mbi ;
if ( VirtualQuery ( ( void * ) base , & mbi , sizeof ( mbi ) ) = = 0 ) {
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , GetLastErrorAsString ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
return 0 ;
} ;
if ( ! VirtualProtect ( mbi . BaseAddress , mbi . RegionSize , PAGE_EXECUTE_READWRITE , & mbi . Protect ) )
{
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , GetLastErrorAsString ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
return 0 ;
} ;
memcpy ( ( void * ) base , buffer . data ( ) , buffer . size ( ) ) ;
scrap_log ( INFO_COLOR , " Code: " + hexdump_s ( ( void * ) base , buffer . size ( ) ) ) ;
VirtualProtect ( mbi . BaseAddress , mbi . RegionSize , mbi . Protect , NULL ) ;
return buffer . size ( ) ;
}
size_t asm_size ( vector < string > assembly ) {
return assemble ( assembly , 0 ) ;
}
2019-12-03 23:28:14 +00:00
2020-01-03 02:22:09 +00:00
struct Command {
2019-12-03 23:28:14 +00:00
t_cmd_func func ;
2020-01-03 02:22:09 +00:00
string usage ;
string doc ;
map < string , Command * > subcommands ;
Command ( t_cmd_func func = nullptr , string usage = " " , string doc = " " , map < string , Command * > subcommands = { } ) {
this - > func = func ;
this - > usage = usage ;
this - > doc = doc ;
this - > subcommands = subcommands ;
}
Command ( string usage = " " , string doc = " " , map < string , Command * > subcommands = { } ) :
Command ( nullptr , usage , doc , subcommands ) { } ;
void add_subcommand ( string name , Command * cmd ) {
this - > subcommands [ name ] = cmd ;
}
void set_subcommands ( const map < string , Command * > & subcommands ) {
for ( auto subcmd : subcommands ) {
this - > add_subcommand ( subcmd . first , subcmd . second ) ;
}
}
bool has_subcommand ( string cmd ) {
return this - > subcommands . count ( cmd ) > 0 ;
}
void exec ( vector < string > args ) {
if ( args . size ( ) > 1 ) {
string cmd = args [ 0 ] ;
if ( this - > has_subcommand ( cmd ) ) {
// matching subcommand found, strip first part and forward args
args . erase ( args . begin ( ) ) ;
return this - > subcommands [ cmd ] - > exec ( args ) ;
} ;
}
// args vector empty or no subcommand found, check if we have a func ptr and call it
if ( this - > func ! = nullptr ) {
this - > func ( this , args ) ;
return ;
}
scrap_log ( ERR_COLOR , " Unknown command! \n " ) ;
return ;
}
2019-12-03 23:28:14 +00:00
} ;
2020-01-03 02:22:09 +00:00
struct REPL {
map < string , Command * > commands ;
REPL ( map < string , Command * > commands ) {
this - > commands = commands ;
}
bool has_command ( string cmd ) {
return this - > commands . count ( cmd ) > 0 ;
}
bool exec ( vector < string > args ) {
vector < tuple < string , Command * > > cmd_stack ;
map < string , Command * > cmds = this - > commands ;
if ( args . size ( ) = = 0 ) {
return false ;
}
while ( cmds . count ( args [ 0 ] ) ) {
cmd_stack . push_back ( make_tuple ( args [ 0 ] , cmds [ args [ 0 ] ] ) ) ;
cmds = cmds [ args [ 0 ] ] - > subcommands ;
args . erase ( args . begin ( ) ) ;
if ( args . empty ( ) ) break ;
}
while ( cmd_stack . size ( ) ) {
auto elem = cmd_stack . back ( ) ;
string cmd = get < 0 > ( elem ) ;
Command * cmd_ptr = get < 1 > ( elem ) ;
cmd_stack . pop_back ( ) ;
if ( cmd_ptr - > func ! = nullptr ) {
cmd_ptr - > func ( cmd_ptr , args ) ;
return true ;
}
args . insert ( args . begin ( ) , cmd ) ;
}
return false ;
}
string help ( vector < string > args ) {
map < string , Command * > cmds = this - > commands ;
string ret ;
if ( args . empty ( ) ) {
return this - > show_commands ( cmds ) ;
}
pair < string , Command * > cmd = make_pair ( " " , nullptr ) ;
for ( string part : args ) {
if ( cmds . count ( part ) = = 0 ) {
return " No help for (sub)command ' " + part + " ' " ;
}
cmd = make_pair ( part , cmds [ part ] ) ;
cmds = cmd . second - > subcommands ;
}
ret = cmd . first + " : " + cmd . second - > usage + " \n " ;
if ( cmds . size ( ) ) {
ret + = " Subcommands: \n " + this - > show_commands ( cmds , 1 ) + " \n " ;
} ;
return ret ;
}
string show_commands ( map < string , Command * > cmds , size_t depth = 0 ) {
string s ;
for ( auto cmd : cmds ) {
for ( size_t n = 0 ; n < depth ; + + n ) {
s + = " " ;
}
s + = cmd . first + " : " + cmd . second - > doc + " ( " + cmd . second - > usage + " ) \n " + this - > show_commands ( cmd . second - > subcommands , depth + 1 ) ;
}
return s ;
}
} ;
2019-12-03 23:28:14 +00:00
DWORD
get_protection ( void * addr ) {
MEMORY_BASIC_INFORMATION mbi ;
VirtualQuery ( addr , & mbi , sizeof ( mbi ) ) ;
return mbi . Protect ;
}
2020-01-03 02:22:09 +00:00
void cmd_exec ( Command * cmd , vector < string > args ) {
void * addr ;
2019-12-03 23:28:14 +00:00
MEMORY_BASIC_INFORMATION mbi ;
2020-01-03 02:22:09 +00:00
if ( args . size ( ) < 1 ) {
scrap_log ( ERR_COLOR , cmd - > usage ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
}
try {
addr = ( void * ) stoull ( args [ 0 ] , 0 , 16 ) ;
} catch ( exception e ) {
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , e . what ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
2019-12-03 23:28:14 +00:00
return ;
}
2020-01-03 02:22:09 +00:00
if ( VirtualQuery ( addr , & mbi , sizeof ( mbi ) ) = = 0 ) {
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , GetLastErrorAsString ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
return ;
} ;
if ( ! VirtualProtect ( mbi . BaseAddress , mbi . RegionSize , PAGE_EXECUTE_READWRITE , & mbi . Protect ) )
{
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , GetLastErrorAsString ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
} ;
CreateThread ( NULL , 0 , ( LPTHREAD_START_ROUTINE ) addr , 0 , NULL , NULL ) ;
}
void cmd_write ( Command * cmd , vector < string > args ) {
MEMORY_BASIC_INFORMATION mbi ;
if ( args . size ( ) = = 0 ) {
scrap_log ( ERR_COLOR , cmd - > usage ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
return ;
}
uint8_t * buffer = nullptr ;
2019-12-03 23:28:14 +00:00
vector < uint8_t > data ;
try {
2020-01-03 02:22:09 +00:00
if ( args . size ( ) > 1 ) {
buffer = ( uint8_t * ) stoull ( args [ 0 ] , 0 , 16 ) ;
data = fromhex ( args [ 1 ] ) ;
} else {
data = fromhex ( args [ 0 ] ) ;
buffer = new uint8_t [ data . size ( ) ] ;
if ( buffer = = nullptr ) {
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , " new[] failed " ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
return ;
}
char ptr [ 255 ] ;
snprintf ( ptr , 255 , " Buffer @ %p \n " , buffer ) ;
scrap_log ( INFO_COLOR , ptr ) ;
}
2019-12-03 23:28:14 +00:00
} catch ( exception e ) {
2020-01-03 02:22:09 +00:00
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , e . what ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
2019-12-03 23:28:14 +00:00
return ;
}
2020-01-03 02:22:09 +00:00
if ( VirtualQuery ( buffer , & mbi , sizeof ( mbi ) ) = = 0 ) {
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , GetLastErrorAsString ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
return ;
} ;
if ( ! VirtualProtect ( mbi . BaseAddress , mbi . RegionSize , PAGE_EXECUTE_READWRITE , & mbi . Protect ) )
{
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , GetLastErrorAsString ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
} ;
2019-12-03 23:28:14 +00:00
size_t idx = 0 ;
for ( uint8_t v : data ) {
buffer [ idx + + ] = v ;
}
2020-01-03 02:22:09 +00:00
2019-12-03 23:28:14 +00:00
VirtualProtect ( mbi . BaseAddress , mbi . RegionSize , mbi . Protect , NULL ) ;
return ;
}
2020-01-03 02:22:09 +00:00
void cmd_read ( Command * cmd , vector < string > args ) {
2019-12-03 23:28:14 +00:00
MEMORY_BASIC_INFORMATION mbi ;
2020-01-03 02:22:09 +00:00
if ( args . size ( ) < 1 ) {
scrap_log ( ERR_COLOR , cmd - > usage ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
2019-12-03 23:28:14 +00:00
return ;
}
uintptr_t addr = UINTPTR_MAX ;
2020-01-03 02:22:09 +00:00
size_t size = 0xff ;
2019-12-03 23:28:14 +00:00
unsigned char * buffer ;
try {
addr = stoull ( args [ 0 ] , 0 , 16 ) ;
2020-01-03 02:22:09 +00:00
if ( args . size ( ) > 1 ) {
size = stoull ( args [ 1 ] ) ;
}
2019-12-03 23:28:14 +00:00
buffer = new unsigned char [ size ] ;
} catch ( exception e ) {
2020-01-03 02:22:09 +00:00
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , e . what ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
2019-12-03 23:28:14 +00:00
return ;
}
void * mptr = reinterpret_cast < void * > ( addr ) ;
if ( VirtualQuery ( mptr , & mbi , sizeof ( mbi ) ) = = 0 ) {
2020-01-03 02:22:09 +00:00
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , GetLastErrorAsString ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
return ;
} ;
if ( ! VirtualProtect ( mbi . BaseAddress , mbi . RegionSize , PAGE_EXECUTE_READWRITE ,
& mbi . Protect ) ) {
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , GetLastErrorAsString ( ) ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
2019-12-03 23:28:14 +00:00
return ;
} ;
string hxd = hexdump_s ( mptr , size ) ;
scrap_log ( INFO_COLOR , hxd . c_str ( ) ) ;
VirtualProtect ( mbi . BaseAddress , mbi . RegionSize , mbi . Protect , NULL ) ;
if ( buffer ) {
free ( buffer ) ;
}
return ;
}
2020-01-03 02:22:09 +00:00
void cmd_hook_dx8 ( Command * cmd , vector < string > args ) {
hook_d3d8 ( ) ;
scrap_log ( INFO_COLOR , " DX8 hooked! \n " ) ;
return ;
}
void cmd_unhook_dx8 ( Command * cmd , vector < string > args ) {
unhook_d3d8 ( ) ;
scrap_log ( INFO_COLOR , " DX8 unhooked! \n " ) ;
return ;
}
void cmd_dx8 ( Command * cmd , vector < string > args ) {
2019-12-03 23:28:14 +00:00
if ( args . size ( ) ! = 1 ) {
2020-01-03 02:22:09 +00:00
scrap_log ( ERR_COLOR , cmd - > usage ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
2019-12-03 23:28:14 +00:00
return ;
}
2020-01-03 02:22:09 +00:00
if ( args [ 0 ] = = " zenable:true " ) {
use_z = true ;
scrap_log ( INFO_COLOR , " DX8 mode switched! \n " ) ;
2019-12-03 23:28:14 +00:00
return ;
2020-01-03 02:22:09 +00:00
} ;
if ( args [ 0 ] = = " zenable:false " ) {
use_z = false ;
scrap_log ( INFO_COLOR , " DX8 mode switched! \n " ) ;
return ;
} ;
if ( args [ 0 ] = = " fill:wire " ) {
fillmode = D3DFILLMODE : : D3DFILL_WIREFRAME ;
scrap_log ( INFO_COLOR , " DX8 mode switched! \n " ) ;
return ;
} ;
if ( args [ 0 ] = = " fill:solid " ) {
fillmode = D3DFILLMODE : : D3DFILL_SOLID ;
scrap_log ( INFO_COLOR , " DX8 mode switched! \n " ) ;
return ;
} ;
if ( args [ 0 ] = = " fill:point " ) {
fillmode = D3DFILLMODE : : D3DFILL_POINT ;
scrap_log ( INFO_COLOR , " DX8 mode switched! \n " ) ;
2019-12-03 23:28:14 +00:00
return ;
} ;
scrap_log ( ERR_COLOR , " Invalid argument! \n " ) ;
return ;
}
2020-01-03 02:22:09 +00:00
void cmd_dump_stack ( Command * cmd , vector < string > args ) {
void * * stack = ( void * * ) _AddressOfReturnAddress ( ) ;
cout < < " ESP: " < < stack < < endl ;
for ( size_t n = 0 ; n < 0x100 ; + + n ) {
if ( ! addr_exists ( stack [ n ] ) ) {
continue ;
}
char R = can_read ( stack [ n ] ) ? ' R ' : ' ' ;
char W = can_write ( stack [ n ] ) ? ' W ' : ' ' ;
char X = can_execute ( stack [ n ] ) ? ' X ' : ' ' ;
cout < < " ESP[ " < < std : : hex < < setfill ( ' 0 ' ) < < setw ( 2 ) < < n < < " ]: " < < stack [ n ] < < " " < < R < < W < < X ;
if ( can_read ( stack [ n ] ) ) {
cout < < " [ " < < hexdump_s ( stack [ n ] , 0xf , true ) < < " ] " < < endl ;
} else {
cout < < endl ;
}
}
return ;
}
void cmd_dump_py ( Command * cmd , vector < string > args ) {
2019-12-03 23:28:14 +00:00
stringstream out ;
for ( auto mod : Py ) {
for ( auto meth : mod . second . methods ) {
out < < mod . first < < " . " < < meth . first < < " @ "
< < meth . second - > ml_meth < < endl ;
}
}
scrap_log ( INFO_COLOR , out . str ( ) . c_str ( ) ) ;
}
2020-01-03 02:22:09 +00:00
void cmd_dump_vars ( Command * cmd , vector < string > args ) {
stringstream out ;
GameVar * var = ptr < GameVar > ( P_VARS , 0 ) ;
out < < " GameVars: " < < endl ;
while ( var ! = nullptr ) {
out < < var - > name < < " [ " < < std : : hex < < ( uint16_t ) var - > type < < " , " < < ( uint16_t ) var - > subtype < < std : : dec < < " ]: " < < var - > desc < < " ( " < < var - > value < < " , " < < var - > default < < " ) " < < endl ;
var = var - > next ;
}
scrap_log ( INFO_COLOR , out . str ( ) . c_str ( ) ) ;
}
void cmd_dump_ents ( Command * cmd , vector < string > args ) {
2019-12-03 23:28:14 +00:00
stringstream out ;
out < < " Entities: " < < endl ;
dump_ht ( ptr < HashTable < Entity > > ( P_WORLD , O_ENTS ) , & out ) ;
out < < " Entity Lists: " < < endl ;
dump_ht ( ptr < HashTable < EntityList > > ( P_WORLD , O_ENTLISTS ) , & out ) ;
scrap_log ( INFO_COLOR , out . str ( ) . c_str ( ) ) ;
return ;
}
2020-01-03 02:22:09 +00:00
void cmd_toggle_overlay ( Command * cmd , vector < string > args ) {
if ( ! hooked ) {
scrap_log ( INFO_COLOR , " DX8 not hooked, run '$dx8 hook' first! \n " ) ;
return ;
}
2019-12-03 23:28:14 +00:00
overlay = ! overlay ;
if ( overlay ) {
scrap_log ( INFO_COLOR , " Overlay enabled! \n " ) ;
} else {
scrap_log ( INFO_COLOR , " Overlay disabled! \n " ) ;
}
}
2020-01-03 02:22:09 +00:00
void cmd_enable_overlay ( Command * cmd , vector < string > args ) {
if ( ! overlay ) {
cmd_toggle_overlay ( cmd , args ) ;
}
}
void cmd_disable_overlay ( Command * cmd , vector < string > args ) {
if ( overlay ) {
cmd_toggle_overlay ( cmd , args ) ;
}
}
void cmd_print_alarm ( Command * cmd , vector < string > args ) {
2019-12-03 23:28:14 +00:00
stringstream out ;
float * alarm = ptr < float > ( P_WORLD , O_ALARM ) ;
float * alarm_grow = ptr < float > ( P_WORLD , O_ALARM_GROW ) ;
out < < " Alarm: " < < alarm [ 0 ] < < " + " < < alarm_grow [ 0 ] < < endl ;
scrap_log ( INFO_COLOR , out . str ( ) . c_str ( ) ) ;
return ;
}
2020-01-03 02:22:09 +00:00
void cmd_unload ( Command * cmd , vector < string > args ) {
2019-12-03 23:28:14 +00:00
scrap_log ( INFO_COLOR , " Unloading ScrapHacks... bye! \n " ) ;
DllUnload ( ) ;
}
2020-01-03 02:22:09 +00:00
void cmd_asm ( Command * cmd , vector < string > args ) {
string code ;
uintptr_t buffer_addr ;
bool has_addr = false ;
if ( args . size ( ) < 1 ) {
scrap_log ( ERR_COLOR , cmd - > usage ) ;
2019-12-03 23:28:14 +00:00
return ;
}
2020-01-03 02:22:09 +00:00
try {
buffer_addr = stoull ( args [ 0 ] , 0 , 16 ) ;
has_addr = true ;
} catch ( exception e ) {
// NOP
has_addr = false ;
2019-12-03 23:28:14 +00:00
}
2020-01-03 02:22:09 +00:00
if ( has_addr ) {
// remove address from args
args . erase ( args . begin ( ) ) ;
}
for ( string arg : args ) {
code + = arg + " " ;
} ;
size_t data_size = asm_size ( split ( code , ' ; ' ) ) ;
if ( ! has_addr ) {
buffer_addr = ( uintptr_t ) malloc ( data_size ) ;
if ( buffer_addr = = 0 ) {
scrap_log ( ERR_COLOR , " ERROR: " ) ;
scrap_log ( ERR_COLOR , " malloc() failed " ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
return ;
}
char ptr [ 255 ] ;
snprintf ( ptr , 255 , " Buffer @ %p \n " , ( void * ) buffer_addr ) ;
scrap_log ( INFO_COLOR , ptr ) ;
}
assemble ( split ( code , ' ; ' ) , buffer_addr ) ;
2019-12-03 23:28:14 +00:00
}
2020-01-03 02:22:09 +00:00
void cmd_help ( Command * cmd , vector < string > args ) ;
static REPL * repl = new REPL (
{
{ " mem " , new Command ( " Usage: $mem (read|write) " , " Manipulate memory " , {
{ " read " , new Command ( cmd_read , " Usage: $mem read <addr> [size] " , " Read memory " ) } ,
{ " write " , new Command ( cmd_write , " Usage: $mem write [addr] <data(hex)> " , " Write memory, if no address is specifiew we VirtualAlloc() a region " ) } ,
{ " exec " , new Command ( cmd_exec , " Usage: $exec <addr> " , " Start a new thread at the specified address " ) } ,
{ " asm " , new Command ( cmd_asm , " Usage: $asm [addr] <inst1>;<inst2>;... " , " Assemble instructions at address, if no address is given allocate memory and assemble code into that " ) } ,
{ " stack " , new Command ( cmd_dump_stack , " Usage: $mem stack " , " Dump stack contents " ) } ,
} ) } ,
{ " unload " , new Command ( cmd_unload , " Usage: $unload " , " Unload ScrapHacks " ) } ,
{ " dx8 " , new Command ( cmd_dx8 , " Usage: $dx8 <subcommand> " , " Manipulate DirectX 8 functions and state " , {
{ " overlay " , new Command ( " Usage: $dx8 overlay <subcommand> " , " Control DX8 overlay " , {
{ " toggle " , new Command ( cmd_toggle_overlay , " Usage: $dx8 overlay toggle " , " Toggle overlay " ) } ,
{ " enable " , new Command ( cmd_enable_overlay , " Usage: $dx8 overlay enable " , " Enable overlay " ) } ,
{ " disable " , new Command ( cmd_disable_overlay , " Usage: $dx8 overlay disable " , " Disable overlay " ) } ,
} ) } ,
{ " hook " , new Command ( cmd_hook_dx8 , " Usage: $dx8 hook " , " Enable DirectX 8 hook " ) } ,
{ " unhook " , new Command ( cmd_unhook_dx8 , " Usage: $dx8 hook " , " Disable DirectX 8 hook " ) }
} ) } ,
{ " dump " , new Command ( " Usage: $dump <subcommand> " , " Dump various data to the console " , {
{ " py " , new Command ( cmd_dump_py , " Usage: $dump py " , " Dump python module information " ) } ,
{ " ents " , new Command ( cmd_dump_ents , " Usage: $dump ents " , " Dump entity information " ) } ,
{ " alarm " , new Command ( cmd_print_alarm , " Usage: $dump alarm " , " Print alarm status " ) } ,
{ " vars " , new Command ( cmd_dump_vars , " Usage: $dump vars " , " Print engine variables " ) } ,
} ) } ,
{ " help " , new Command ( cmd_help , " Usage: $help [command] " , " Print help for ScrapHacks command " ) }
} ) ;
void cmd_help ( Command * cmd , vector < string > args ) {
scrap_log ( INFO_COLOR , repl - > help ( args ) + " \n " ) ;
} ;
2019-12-03 23:28:14 +00:00
void handle_command ( const char * _cmd ) {
scrap_log ( ERR_COLOR , " $ " ) ;
scrap_log ( ERR_COLOR , _cmd ) ;
scrap_log ( ERR_COLOR , " \n " ) ;
cout < < " CMD: ' " < < _cmd < < " ' " < < endl ;
2020-01-03 02:22:09 +00:00
repl - > exec ( split ( string ( _cmd ) , ' ' ) ) ;
2019-12-03 23:28:14 +00:00
return ;
}