2022-02-21 14:39:44 -05:00
# include <std_include.hpp>
# include "loader/component_loader.hpp"
2022-02-28 14:36:32 -05:00
# include "dvars.hpp"
2022-06-24 20:59:11 -04:00
# include "fastfiles.hpp"
2022-03-01 15:38:16 -05:00
# include "version.h"
# include "command.hpp"
# include "console.hpp"
# include "network.hpp"
# include "scheduler.hpp"
2022-03-03 07:56:46 -05:00
# include "filesystem.hpp"
2022-02-28 14:36:32 -05:00
2022-02-21 14:39:44 -05:00
# include "game/game.hpp"
# include "game/dvars.hpp"
# include <utils/hook.hpp>
# include <utils/string.hpp>
2022-03-01 15:38:16 -05:00
# include <utils/flags.hpp>
2022-02-26 10:10:35 -05:00
2022-02-21 14:39:44 -05:00
namespace patches
{
namespace
{
2022-02-26 10:10:35 -05:00
const char * live_get_local_client_name ( )
{
return game : : Dvar_FindVar ( " name " ) - > current . string ;
}
utils : : hook : : detour sv_kick_client_num_hook ;
void sv_kick_client_num ( const int client_num , const char * reason )
{
// Don't kick bot to equalize team balance.
if ( reason = = " EXE_PLAYERKICKED_BOT_BALANCE " s )
{
return ;
}
2022-02-28 20:39:51 -05:00
return sv_kick_client_num_hook . invoke < void > ( client_num , reason ) ;
2022-02-21 14:39:44 -05:00
}
2022-02-26 10:10:35 -05:00
std : : string get_login_username ( )
{
char username [ UNLEN + 1 ] ;
DWORD username_len = UNLEN + 1 ;
if ( ! GetUserNameA ( username , & username_len ) )
{
return " Unknown Soldier " ;
}
2022-05-19 15:04:57 -04:00
return std : : string { username , username_len - 1 } ;
}
utils : : hook : : detour com_register_dvars_hook ;
void com_register_dvars_stub ( )
{
if ( game : : environment : : is_mp ( ) )
{
// Make name save
dvars : : register_string ( " name " , get_login_username ( ) . data ( ) , game : : DVAR_FLAG_SAVED , " Player name. " ) ;
}
return com_register_dvars_hook . invoke < void > ( ) ;
2022-02-26 10:10:35 -05:00
}
2022-05-19 13:09:17 -04:00
utils : : hook : : detour set_client_dvar_from_server_hook ;
2022-05-28 13:51:26 -04:00
void set_client_dvar_from_server_stub ( void * clientNum , void * cgameGlob , const char * dvar , const char * value )
2022-02-27 14:35:21 -05:00
{
2022-03-06 08:03:44 -05:00
if ( dvar = = " cg_fov " s | | dvar = = " cg_fovMin " s )
2022-02-27 14:35:21 -05:00
{
return ;
}
2022-05-28 13:51:26 -04:00
set_client_dvar_from_server_hook . invoke < void > ( 0x11AA90 _b , clientNum , cgameGlob , dvar , value ) ;
2022-02-27 14:35:21 -05:00
}
2022-03-03 07:56:46 -05:00
const char * db_read_raw_file_stub ( const char * filename , char * buf , const int size )
2022-02-26 10:10:35 -05:00
{
2022-03-03 07:56:46 -05:00
std : : string file_name = filename ;
if ( file_name . find ( " .cfg " ) = = std : : string : : npos )
{
file_name . append ( " .cfg " ) ;
}
2022-02-26 10:10:35 -05:00
2022-03-03 07:56:46 -05:00
const auto file = filesystem : : file ( file_name ) ;
if ( file . exists ( ) )
{
snprintf ( buf , size , " %s \n " , file . get_buffer ( ) . data ( ) ) ;
return buf ;
}
// DB_ReadRawFile
2022-05-24 20:08:28 -04:00
return utils : : hook : : invoke < const char * > ( SELECT_VALUE ( 0x1F4D00 _b , 0x3994B0 _b ) , filename , buf , size ) ;
2022-03-03 07:56:46 -05:00
}
2022-02-26 10:10:35 -05:00
void bsp_sys_error_stub ( const char * error , const char * arg1 )
{
if ( game : : environment : : is_dedi ( ) )
{
game : : Sys_Error ( error , arg1 ) ;
}
else
{
scheduler : : once ( [ ] ( )
2022-02-27 01:36:54 -05:00
{
command : : execute ( " reconnect " ) ;
} , scheduler : : pipeline : : main , 1 s ) ;
2022-02-26 10:10:35 -05:00
game : : Com_Error ( game : : ERR_DROP , error , arg1 ) ;
}
}
utils : : hook : : detour cmd_lui_notify_server_hook ;
void cmd_lui_notify_server_stub ( game : : mp : : gentity_s * ent )
{
2022-05-21 06:26:30 -04:00
const auto svs_clients = * game : : mp : : svs_clients ;
if ( svs_clients = = nullptr )
{
return ;
}
2022-02-26 10:10:35 -05:00
command : : params_sv params { } ;
const auto menu_id = atoi ( params . get ( 1 ) ) ;
2022-05-21 18:38:15 -04:00
const auto client = & svs_clients [ ent - > s . entityNum ] ;
2022-02-26 10:10:35 -05:00
// 22 => "end_game"
2022-05-21 18:38:15 -04:00
if ( menu_id = = 22 & & client - > header . remoteAddress . type ! = game : : NA_LOOPBACK )
2022-02-26 10:10:35 -05:00
{
return ;
}
cmd_lui_notify_server_hook . invoke < void > ( ent ) ;
}
void sv_execute_client_message_stub ( game : : mp : : client_t * client , game : : msg_t * msg )
{
if ( client - > reliableAcknowledge < 0 )
{
client - > reliableAcknowledge = client - > reliableSequence ;
console : : info ( " Negative reliableAcknowledge from %s - cl->reliableSequence is %i, reliableAcknowledge is %i \n " ,
client - > name , client - > reliableSequence , client - > reliableAcknowledge ) ;
network : : send ( client - > header . remoteAddress , " error " , " EXE_LOSTRELIABLECOMMANDS " , ' \n ' ) ;
return ;
}
2022-05-24 20:08:28 -04:00
utils : : hook : : invoke < void > ( 0x54EC50 _b , client , msg ) ;
2022-02-26 10:10:35 -05:00
}
2022-02-28 15:49:10 -05:00
2022-05-28 13:51:26 -04:00
void aim_assist_add_to_target_list ( void * aaGlob , void * screenTarget )
2022-02-28 15:49:10 -05:00
{
if ( ! dvars : : aimassist_enabled - > current . enabled )
2022-05-28 09:51:38 -04:00
{
2022-02-28 15:49:10 -05:00
return ;
2022-05-28 09:51:38 -04:00
}
2022-02-28 15:49:10 -05:00
2022-05-28 13:51:26 -04:00
game : : AimAssist_AddToTargetList ( aaGlob , screenTarget ) ;
2022-02-28 15:49:10 -05:00
}
2022-05-31 15:02:07 -04:00
2022-06-24 20:59:11 -04:00
void missing_content_error_stub ( int , const char * )
{
game : : Com_Error ( game : : ERR_DROP , utils : : string : : va ( " MISSING FILE \n %s.ff " ,
fastfiles : : get_current_fastfile ( ) . data ( ) ) ) ;
}
2022-05-31 15:02:07 -04:00
utils : : hook : : detour init_network_dvars_hook ;
void init_network_dvars_stub ( game : : dvar_t * dvar )
{
static const auto hash = game : : generateHashValue ( " r_tonemapHighlightRange " ) ;
if ( dvar - > hash = = hash )
{
init_network_dvars_hook . invoke < void > ( dvar ) ;
}
}
2022-05-31 17:23:07 -04:00
int ui_draw_crosshair ( )
{
return 1 ;
}
2022-06-24 21:05:42 -04:00
utils : : hook : : detour cl_gamepad_scrolling_buttons_hook ;
void cl_gamepad_scrolling_buttons_stub ( int local_client_num , int a2 )
{
if ( local_client_num < = 3 )
{
cl_gamepad_scrolling_buttons_hook . invoke < void > ( local_client_num , a2 ) ;
}
}
2022-06-24 21:45:02 -04:00
int out_of_memory_text_stub ( char * dest , int size , const char * fmt , . . . )
{
fmt = " %s (%d) \n \n Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers. \n \n If this still occurs, try using the '-memoryfix' parameter to generate the 'players2' folder. " ;
char buffer [ 2048 ] ;
va_list ap ;
va_start ( ap , fmt ) ;
vsnprintf_s ( buffer , sizeof ( buffer ) , _TRUNCATE , fmt , ap ) ;
va_end ( ap ) ;
return utils : : hook : : invoke < int > ( SELECT_VALUE ( 0x429200 _b , 0x5AF0F0 _b ) , dest , size , " %s " , buffer ) ;
}
2022-02-21 14:39:44 -05:00
}
class component final : public component_interface
{
public :
void post_unpack ( ) override
{
2022-05-19 15:04:57 -04:00
// Register dvars
2022-05-24 20:08:28 -04:00
com_register_dvars_hook . create ( SELECT_VALUE ( 0x385BE0 _b , 0x15BB60 _b ) , & com_register_dvars_stub ) ;
2022-05-19 15:04:57 -04:00
2022-02-21 14:39:44 -05:00
// Unlock fps in main menu
2022-05-24 20:08:28 -04:00
utils : : hook : : set < BYTE > ( SELECT_VALUE ( 0x1B1EAB _b , 0x34396B _b ) , 0xEB ) ;
2022-02-21 14:39:44 -05:00
2022-02-28 20:39:51 -05:00
if ( ! game : : environment : : is_dedi ( ) )
2022-02-26 14:12:05 -05:00
{
2022-02-28 20:39:51 -05:00
// Fix mouse lag
2022-05-24 20:08:28 -04:00
utils : : hook : : nop ( SELECT_VALUE ( 0x4631F9 _b , 0x5BFF89 _b ) , 6 ) ;
2022-02-28 20:39:51 -05:00
scheduler : : loop ( [ ] ( )
{
SetThreadExecutionState ( ES_DISPLAY_REQUIRED ) ;
} , scheduler : : pipeline : : main ) ;
}
2022-02-21 14:39:44 -05:00
// Make cg_fov and cg_fovscale saved dvars
2022-02-28 14:36:32 -05:00
dvars : : override : : register_float ( " cg_fov " , 65.f , 40.f , 200.f , game : : DvarFlags : : DVAR_FLAG_SAVED ) ;
dvars : : override : : register_float ( " cg_fovScale " , 1.f , 0.1f , 2.f , game : : DvarFlags : : DVAR_FLAG_SAVED ) ;
2022-03-06 08:03:44 -05:00
dvars : : override : : register_float ( " cg_fovMin " , 1.f , 1.0f , 90.f , game : : DvarFlags : : DVAR_FLAG_SAVED ) ;
2022-02-28 19:16:28 -05:00
// Allow kbam input when gamepad is enabled
2022-05-24 20:08:28 -04:00
utils : : hook : : nop ( SELECT_VALUE ( 0x1AC0CE _b , 0x135EFB _b ) , 2 ) ;
utils : : hook : : nop ( SELECT_VALUE ( 0x1A9DDC _b , 0x13388F _b ) , 6 ) ;
2022-02-26 10:10:35 -05:00
2022-06-24 20:59:11 -04:00
// Show missing fastfiles
utils : : hook : : call ( SELECT_VALUE ( 0x0 _b , 0x39A78E _b ) , missing_content_error_stub ) ;
2022-03-03 07:56:46 -05:00
// Allow executing custom cfg files with the "exec" command
2022-05-28 09:51:38 -04:00
utils : : hook : : call ( SELECT_VALUE ( 0x376EB5 _b , 0x156D41 _b ) , db_read_raw_file_stub ) ;
2022-03-03 07:56:46 -05:00
2022-06-24 21:45:02 -04:00
// Remove useless information from errors + add additional help to common errors
utils : : hook : : set < const char * > ( SELECT_VALUE ( 0x7E3DF0 _b , 0x937B80 _b ) ,
" Create2DTexture( %s, %i, %i, %i, %i ) failed \n \n "
" Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers. " ) ;
utils : : hook : : set < const char * > ( SELECT_VALUE ( 0x800EA8 _b , 0x954FF0 _b ) ,
" IDXGISwapChain::Present failed: %s \n \n "
" Disable shader caching, lower graphic settings, free up RAM, or update your GPU drivers. " ) ;
utils : : hook : : call ( SELECT_VALUE ( 0x457BC9 _b , 0x1D8E09 _b ) , out_of_memory_text_stub ) ; // "Out of memory. You are probably low on disk space."
2022-03-01 09:40:37 -05:00
if ( ! game : : environment : : is_sp ( ) )
2022-02-26 10:10:35 -05:00
{
patch_mp ( ) ;
}
}
static void patch_mp ( )
{
2022-05-28 09:51:38 -04:00
utils : : hook : : jump ( 0x5BB9C0 _b , & live_get_local_client_name ) ;
2022-05-19 14:15:27 -04:00
// Disable data validation error popup
dvars : : override : : register_int ( " data_validation_allow_drop " , 0 , 0 , 0 , game : : DVAR_FLAG_NONE ) ;
2022-02-26 10:10:35 -05:00
// Patch SV_KickClientNum
2022-05-21 06:26:30 -04:00
sv_kick_client_num_hook . create ( game : : SV_KickClientNum , & sv_kick_client_num ) ;
2022-02-26 10:10:35 -05:00
// block changing name in-game
2022-05-24 20:08:28 -04:00
utils : : hook : : set < uint8_t > ( 0x54CFF0 _b , 0xC3 ) ;
2022-02-26 10:10:35 -05:00
2022-05-25 13:50:41 -04:00
// client side aim assist dvar
2022-05-28 09:51:38 -04:00
dvars : : aimassist_enabled = dvars : : register_bool ( " aimassist_enabled " , true ,
2022-05-25 13:50:41 -04:00
game : : DvarFlags : : DVAR_FLAG_SAVED ,
" Enables aim assist for controllers " ) ;
2022-05-28 09:51:38 -04:00
utils : : hook : : call ( 0xE857F _b , aim_assist_add_to_target_list ) ;
2022-05-25 13:50:41 -04:00
2022-02-26 10:10:35 -05:00
// patch "Couldn't find the bsp for this map." error to not be fatal in mp
2022-05-28 09:51:38 -04:00
utils : : hook : : call ( 0x39465B _b , bsp_sys_error_stub ) ;
2022-02-26 10:10:35 -05:00
// isProfanity
2022-05-28 09:51:38 -04:00
utils : : hook : : set ( 0x361AA0 _b , 0xC3C033 ) ;
2022-05-25 13:50:41 -04:00
2022-02-26 10:10:35 -05:00
// disable elite_clan
dvars : : override : : register_int ( " elite_clan_active " , 0 , 0 , 0 , game : : DVAR_FLAG_NONE ) ;
2022-05-24 20:08:28 -04:00
utils : : hook : : set < uint8_t > ( 0x62D2F0 _b , 0xC3 ) ; // don't register commands
2022-02-26 10:10:35 -05:00
2022-02-27 01:36:54 -05:00
// disable codPointStore
2022-02-28 14:36:32 -05:00
dvars : : override : : register_int ( " codPointStore_enabled " , 0 , 0 , 0 , game : : DVAR_FLAG_NONE ) ;
2022-02-26 10:10:35 -05:00
2022-05-31 15:02:07 -04:00
// don't register every replicated dvar as a network dvar (only r_tonemapHighlightRange, fixes red dots)
init_network_dvars_hook . create ( 0x4740C0 _b , init_network_dvars_stub ) ;
2022-02-26 10:10:35 -05:00
// patch "Server is different version" to show the server client version
2022-05-28 09:51:38 -04:00
utils : : hook : : inject ( 0x54DCE5 _b , VERSION ) ;
2022-02-26 10:10:35 -05:00
2022-03-01 09:40:37 -05:00
// prevent servers overriding our fov
2022-05-19 13:09:17 -04:00
set_client_dvar_from_server_hook . create ( 0x11AA90 _b , set_client_dvar_from_server_stub ) ;
utils : : hook : : nop ( 0x17DA96 _b , 0x16 ) ;
utils : : hook : : nop ( 0xE00BE _b , 0x17 ) ;
2022-05-18 10:23:01 -04:00
utils : : hook : : set < uint8_t > ( 0x307F39 _b , 0xEB ) ;
2022-02-26 10:10:35 -05:00
2022-05-18 20:14:19 -04:00
// some [data validation] anti tamper thing that kills performance
2022-03-12 18:56:15 -05:00
dvars : : override : : register_int ( " dvl " , 0 , 0 , 0 , game : : DVAR_FLAG_READ ) ;
2022-02-26 10:10:35 -05:00
// unlock safeArea_*
2022-05-28 10:36:07 -04:00
utils : : hook : : jump ( 0x347BC5 _b , 0x347BD3 _b ) ;
utils : : hook : : jump ( 0x347BEC _b , 0x347C17 _b ) ;
2022-03-18 18:47:07 -04:00
dvars : : override : : register_float ( " safeArea_adjusted_horizontal " , 1 , 0 , 1 , game : : DVAR_FLAG_SAVED ) ;
dvars : : override : : register_float ( " safeArea_adjusted_vertical " , 1 , 0 , 1 , game : : DVAR_FLAG_SAVED ) ;
dvars : : override : : register_float ( " safeArea_horizontal " , 1 , 0 , 1 , game : : DVAR_FLAG_SAVED ) ;
dvars : : override : : register_float ( " safeArea_vertical " , 1 , 0 , 1 , game : : DVAR_FLAG_SAVED ) ;
2022-02-26 10:10:35 -05:00
// allow servers to check for new packages more often
2022-02-28 14:36:32 -05:00
dvars : : override : : register_int ( " sv_network_fps " , 1000 , 20 , 1000 , game : : DVAR_FLAG_SAVED ) ;
2022-02-26 10:10:35 -05:00
// Massively increate timeouts
2022-02-28 14:36:32 -05:00
dvars : : override : : register_int ( " cl_timeout " , 90 , 90 , 1800 , game : : DVAR_FLAG_NONE ) ; // Seems unused
dvars : : override : : register_int ( " sv_timeout " , 90 , 90 , 1800 , game : : DVAR_FLAG_NONE ) ; // 30 - 0 - 1800
dvars : : override : : register_int ( " cl_connectTimeout " , 120 , 120 , 1800 , game : : DVAR_FLAG_NONE ) ; // Seems unused
dvars : : override : : register_int ( " sv_connectTimeout " , 120 , 120 , 1800 , game : : DVAR_FLAG_NONE ) ; // 60 - 0 - 1800
2022-03-12 18:56:15 -05:00
dvars : : register_int ( " scr_game_spectatetype " , 1 , 0 , 99 , game : : DVAR_FLAG_REPLICATED , " " ) ;
2022-02-26 10:10:35 -05:00
2022-03-18 18:47:07 -04:00
dvars : : override : : register_bool ( " ui_drawCrosshair " , true , game : : DVAR_FLAG_WRITE ) ;
2022-05-31 17:23:07 -04:00
utils : : hook : : jump ( 0x1E6010 _b , ui_draw_crosshair ) ;
2022-03-06 17:13:37 -05:00
2022-03-05 10:38:34 -05:00
dvars : : override : : register_int ( " com_maxfps " , 0 , 0 , 1000 , game : : DVAR_FLAG_SAVED ) ;
2022-02-26 10:10:35 -05:00
// Prevent clients from ending the game as non host by sending 'end_game' lui notification
2022-05-24 20:08:28 -04:00
cmd_lui_notify_server_hook . create ( 0x412D50 _b , cmd_lui_notify_server_stub ) ;
2022-02-26 10:10:35 -05:00
// Prevent clients from sending invalid reliableAcknowledge
2022-05-28 09:51:38 -04:00
utils : : hook : : call ( 0x1CBD06 _b , sv_execute_client_message_stub ) ;
2022-03-01 15:38:16 -05:00
// "fix" for rare 'Out of memory error' error
if ( utils : : flags : : has_flag ( " memoryfix " ) )
{
2022-05-24 20:08:28 -04:00
utils : : hook : : jump ( 0x6200C0 _b , malloc ) ;
utils : : hook : : jump ( 0x61FFE0 _b , _aligned_malloc ) ;
utils : : hook : : jump ( 0x620120 _b , free ) ;
utils : : hook : : jump ( 0x620210 _b , realloc ) ;
utils : : hook : : jump ( 0x620040 _b , _aligned_realloc ) ;
}
2022-03-01 19:00:27 -05:00
// Change default hostname and make it replicated
dvars : : override : : register_string ( " sv_hostname " , " ^2H1-Mod^7 Default Server " , game : : DVAR_FLAG_REPLICATED ) ;
2022-05-21 18:38:15 -04:00
// Dont free server/client memory on asset loading (fixes crashing on map rotation)
utils : : hook : : nop ( 0x132474 _b , 5 ) ;
2022-06-24 21:05:42 -04:00
// Fix gamepad related crash
cl_gamepad_scrolling_buttons_hook . create ( 0x133210 _b , cl_gamepad_scrolling_buttons_stub ) ;
2022-02-21 14:39:44 -05:00
}
} ;
}
2022-05-19 13:09:17 -04:00
REGISTER_COMPONENT ( patches : : component )