maint: dump changes

This commit is contained in:
Jack Back 2024-03-31 19:04:04 +02:00
parent 158c6931d3
commit 1f32ca159a
15 changed files with 169 additions and 112 deletions

View File

@ -13,8 +13,6 @@
#include <utils/hook.hpp>
#include <utils/string.hpp>
#include <version.hpp>
namespace dedicated
{
namespace
@ -105,12 +103,6 @@ namespace dedicated
reinterpret_cast<void(*)()>(0x14046F3B0)(); // SV_CheckLoadGame
}
game::dvar_t* register_maxfps_stub(const char* name, int, int, int, unsigned int flags,
const char* desc)
{
return game::Dvar_RegisterInt(name, 0, 0, 0, game::DvarFlags::DVAR_FLAG_READ, desc);
}
void send_heartbeat()
{
if (sv_lanOnly->current.enabled)
@ -293,7 +285,7 @@ namespace dedicated
//utils::hook::set<uint8_t>(0x1402C89A0, 0xC3); // R_Init caller
utils::hook::jump(0x1402C89A0, init_dedicated_server);
utils::hook::call(0x140413AD8, register_maxfps_stub);
dvars::override::register_int("com_maxfps", 0, 0, 0, game::DVAR_FLAG_READ);
// delay startup commands until the initialization is done
utils::hook::call(0x140412183, execute_startup_command);

View File

@ -18,7 +18,23 @@ namespace dvars
bool value{};
};
struct dvar_int : dvar_base
{
int value{};
int min{};
int max{};
};
struct dvar_float : dvar_base
{
float value{};
float min{};
float max{};
};
utils::hook::detour dvar_register_bool_hook;
utils::hook::detour dvar_register_int_hook;
utils::hook::detour dvar_register_float_hook;
template <typename T>
T* find_dvar(std::unordered_map<std::string, T>& map, const std::string& name)
@ -35,6 +51,8 @@ namespace dvars
namespace override
{
static std::unordered_map<std::string, dvar_bool> register_bool_overrides;
static std::unordered_map<std::string, dvar_int> register_int_overrides;
static std::unordered_map<std::string, dvar_float> register_float_overrides;
void register_bool(const std::string& name, const bool value, const unsigned int flags)
{
@ -43,6 +61,26 @@ namespace dvars
values.flags = flags;
register_bool_overrides[name] = values;
}
void register_int(const std::string& name, const int value, const int min, const int max, const unsigned int flags)
{
dvar_int values;
values.value = value;
values.min = min;
values.max = max;
values.flags = flags;
register_int_overrides[name] = std::move(values);
}
void register_float(const std::string& name, const float value, const float min, const float max, const unsigned int flags)
{
dvar_float values;
values.value = value;
values.min = min;
values.max = max;
values.flags = flags;
register_float_overrides[name] = std::move(values);
}
}
std::string get_string(const std::string& dvar)
@ -68,17 +106,49 @@ namespace dvars
return dvar_register_bool_hook.invoke<const game::dvar_t*>(name, value, flags, description);
}
game::dvar_t* dvar_register_int_stub(const char* name, int value, int min, int max, unsigned int flags, const char* description)
{
auto* var = find_dvar(override::register_int_overrides, name);
if (var)
{
value = var->value;
min = var->min;
max = var->max;
flags = var->flags;
}
return dvar_register_int_hook.invoke<game::dvar_t*>(name, value, min, max, flags, description);
}
game::dvar_t* dvar_register_float_stub(const char* name, float value, float min, float max, unsigned int flags, const char* description)
{
auto* var = find_dvar(override::register_float_overrides, name);
if (var)
{
value = var->value;
min = var->min;
max = var->max;
flags = var->flags;
}
return dvar_register_float_hook.invoke<game::dvar_t*>(name, value, min, max, flags, description);
}
class component final : public component_interface
{
public:
void post_unpack() override
{
dvar_register_bool_hook.create(game::Dvar_RegisterBool, &dvar_register_bool_stub);
dvar_register_int_hook.create(game::Dvar_RegisterInt, &dvar_register_int_stub);
dvar_register_float_hook.create(game::Dvar_RegisterFloat, &dvar_register_float_stub);
}
void pre_destroy() override
{
dvar_register_bool_hook.clear();
dvar_register_int_hook.clear();
dvar_register_float_hook.clear();
}
};
}

View File

@ -5,6 +5,8 @@ namespace dvars
namespace override
{
void register_bool(const std::string& name, bool value, unsigned int flags);
void register_int(const std::string& name, int value, int min, int max, unsigned int flags);
void register_float(const std::string& name, float value, float min, float max, unsigned int flags);
}
std::string get_string(const std::string& dvar);

View File

@ -25,6 +25,12 @@ namespace filesystem
return search_paths;
}
const char* sys_default_install_path_stub()
{
static auto current_path = std::filesystem::current_path().string();
return current_path.data();
}
std::string get_binary_directory()
{
const auto dir = game_module::get_host_module().get_folder();
@ -264,6 +270,10 @@ namespace filesystem
// Set fs_basegame
utils::hook::inject(SELECT_VALUE(0x14041C053, 0x1404DDA13), "iw6");
#ifndef INJECT_HOST_AS_LIB
utils::hook::jump(SELECT_VALUE(0x1404351B0, 0x1404F96C0), sys_default_install_path_stub);
#endif
if (game::environment::is_sp())
{
utils::hook::call(0x14041B744, fs_startup_stub);

View File

@ -71,10 +71,9 @@ namespace gsc
return scripting::get_token(id);
}
void get_unknown_function_error(const char* code_pos)
void get_unknown_function_error(char* code_pos)
{
const auto function = find_function(code_pos);
if (function.has_value())
if (const auto function = find_function(code_pos); function.has_value())
{
const auto& pos = function.value();
unknown_function_error = std::format(
@ -97,7 +96,7 @@ namespace gsc
);
}
void compile_error_stub(const char* code_pos, [[maybe_unused]] const char* msg)
void compile_error_stub(char* code_pos, [[maybe_unused]] const char* msg)
{
get_unknown_function_error(code_pos);
game::Com_Error(game::ERR_DROP, "script link error\n%s", unknown_function_error.data());

View File

@ -1,6 +1,7 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "game/dvars.hpp"
#include "game/scripting/functions.hpp"
@ -8,7 +9,6 @@
#include <utils/string.hpp>
#include "component/console.hpp"
#include "component/scripting.hpp"
#include "component/notifies.hpp"
#include "component/command.hpp"
@ -23,8 +23,6 @@ namespace gsc
void* func_table[0x1000];
const game::dvar_t* developer_script = nullptr;
namespace
{
#define RVA(ptr) static_cast<std::uint32_t>(reinterpret_cast<std::size_t>(ptr) - 0x140000000)
@ -135,7 +133,7 @@ namespace gsc
void vm_error_stub(int mark_pos)
{
if (!developer_script->current.enabled && !force_error_print)
if (!dvars::com_developer_script->current.enabled && !force_error_print)
{
utils::hook::invoke<void>(0x1404E4D00, mark_pos);
return;
@ -284,8 +282,6 @@ namespace gsc
return;
}
developer_script = game::Dvar_RegisterBool("developer_script", false, game::DVAR_FLAG_NONE, "Enable developer script comments");
utils::hook::nop(0x14043BBBE + 5, 2);
utils::hook::call(0x14043BBBE, vm_call_builtin_function);

View File

@ -4,8 +4,6 @@ namespace gsc
{
extern void* func_table[0x1000];
extern const game::dvar_t* developer_script;
void add_function(const std::string& name, game::BuiltinFunction function);
void scr_error(const char* error);

View File

@ -1,6 +1,7 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "game/dvars.hpp"
#include <utils/io.hpp>
#include <utils/hook.hpp>
@ -10,7 +11,6 @@
#include "component/filesystem.hpp"
#include "component/console.hpp"
#include "component/scripting.hpp"
#include "component/fastfiles.hpp"
#include "script_loading.hpp"
@ -26,8 +26,6 @@ namespace gsc
std::unordered_map<std::string, game::ScriptFile*> loaded_scripts;
utils::memory::allocator script_allocator;
const game::dvar_t* developer_script;
void clear()
{
main_handles.clear();
@ -266,11 +264,19 @@ namespace gsc
void scr_begin_load_scripts_stub()
{
const auto comp_mode = developer_script->current.enabled ?
xsk::gsc::build::dev :
xsk::gsc::build::prod;
auto build = xsk::gsc::build::prod;
gsc_ctx->init(comp_mode, []([[maybe_unused]] auto const* ctx, const auto& included_path) -> std::pair<xsk::gsc::buffer, std::vector<std::uint8_t>>
if ((*dvars::com_developer) && (*dvars::com_developer)->current.integer > 0)
{
build = static_cast<xsk::gsc::build>(static_cast<unsigned int>(build) | static_cast<unsigned int>(xsk::gsc::build::dev_maps));
}
if (dvars::com_developer_script && dvars::com_developer_script->current.enabled)
{
build = static_cast<xsk::gsc::build>(static_cast<unsigned int>(build) | static_cast<unsigned int>(xsk::gsc::build::dev_blocks));
}
gsc_ctx->init(build, []([[maybe_unused]] auto const* ctx, const auto& included_path) -> std::pair<xsk::gsc::buffer, std::vector<std::uint8_t>>
{
const auto script_name = std::filesystem::path(included_path).replace_extension().string();
@ -331,13 +337,15 @@ namespace gsc
void post_unpack() override
{
dvars::com_developer = reinterpret_cast<game::dvar_t**>(SELECT_VALUE(0x141603850, 0x1419A9700));
// Load our scripts with an uncompressed stack
utils::hook::call(SELECT_VALUE(0x1403DC8F0, 0x140437940), db_get_raw_buffer_stub);
utils::hook::call(SELECT_VALUE(0x14032D1E0, 0x1403CCED9), scr_begin_load_scripts_stub); // GScr_LoadScripts
utils::hook::call(SELECT_VALUE(0x14032D345, 0x1403CD08D), scr_end_load_scripts_stub); // GScr_LoadScripts
developer_script = game::Dvar_RegisterBool("developer_script", false, game::DVAR_FLAG_NONE, "Enable developer script comments");
dvars::com_developer_script = game::Dvar_RegisterBool("developer_script", false, game::DVAR_FLAG_NONE, "Enable developer script comments");
if (game::environment::is_sp())
{

View File

@ -4,7 +4,6 @@
#include "command.hpp"
#include "network.hpp"
#include "console.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp>
@ -277,12 +276,8 @@ namespace network
// allow server owner to modify net_port before the socket bind
utils::hook::call(0x140500FD0, register_netport_stub);
// ignore built in "print" oob command and add in our own
// ignore built in "print" oob command for security reasons
utils::hook::set<std::uint8_t>(0x1402C6AA4, 0xEB);
on("print", [](const game::netadr_s&, const std::string& data)
{
console::info("%s", data.data());
});
}
}
};

View File

@ -60,54 +60,6 @@ namespace patches
return com_register_dvars_hook.invoke<void>();
}
utils::hook::detour dvar_register_int_hook;
game::dvar_t* dvar_register_int(const char* name, int value, const int min, const int max,
const unsigned int flags,
const char* description)
{
// enable map selection in extinction
if (!strcmp(name, "extinction_map_selection_enabled"))
{
value = true;
}
// enable extra loadouts
else if (!strcmp(name, "extendedLoadoutsEnable"))
{
value = true;
}
// show all in-game store items
else if (strstr(name, "igs_"))
{
value = true;
}
return dvar_register_int_hook.invoke<game::dvar_t*>(name, value, min, max, flags, description);
}
game::dvar_t* register_fovscale_stub(const char* name, float /*value*/, float /*min*/, float /*max*/,
unsigned int /*flags*/,
const char* desc)
{
// changed max value from 2.0f -> 5.0f and min value from 0.5f -> 0.1f
return game::Dvar_RegisterFloat(name, 1.0f, 0.1f, 5.0f, game::DvarFlags::DVAR_FLAG_SAVED, desc);
}
game::dvar_t* register_cg_gun_dvars(const char* name, float /*value*/, float /*min*/, float /*max*/,
unsigned int /*flags*/, const char* desc)
{
if (name == "cg_gun_x"s)
{
return game::Dvar_RegisterFloat(name, 0.0f, -1.0f, 2.0f, game::DvarFlags::DVAR_FLAG_SAVED, desc);
}
else
{
return game::Dvar_RegisterFloat(name, 0.0f, 0.0f, 0.0f, game::DvarFlags::DVAR_FLAG_NONE, desc);
}
}
game::dvar_t* register_network_fps_stub(const char* name, int, int, int, unsigned int flags,
const char* desc)
{
@ -280,7 +232,7 @@ namespace patches
LoadLibraryA("PhysXUpdateLoader64.dll");
// Unlock fps in main menu
utils::hook::set<BYTE>(SELECT_VALUE(0x140242DDB, 0x1402CF58B), 0xEB);
utils::hook::set<std::uint8_t>(SELECT_VALUE(0x140242DDB, 0x1402CF58B), 0xEB);
// Unlock cg_fov
utils::hook::call(SELECT_VALUE(0x1401F3E96, 0x14027273C), register_cg_fov_stub);
@ -289,14 +241,10 @@ namespace patches
utils::hook::call(0x1401F3EC7, register_cg_fov_stub);
}
// set it to 3 to display both voice dlc announcers did only show 1
game::Dvar_RegisterInt("igs_announcer", 3, 3, 3, game::DvarFlags::DVAR_FLAG_NONE,
"Show Announcer Packs. (Bitfield representing which announcer paks to show)");
// changed max value from 85 -> 1000
if (!game::environment::is_dedi())
{
game::Dvar_RegisterInt("com_maxfps", 85, 0, 1000, game::DvarFlags::DVAR_FLAG_SAVED, "Cap frames per second");
dvars::override::register_int("com_maxfps", 85, 0, 1000, game::DVAR_FLAG_SAVED);
}
if (!game::environment::is_sp())
@ -307,12 +255,12 @@ namespace patches
// register cg_gun_ dvars with new values and flags
// maybe _x can stay usable within a reasonable range? it can make scoped weapons DRASTICALLY better on high FOVs
utils::hook::call(SELECT_VALUE(0x140228DDE, 0x1402AB04C), register_cg_gun_dvars);
utils::hook::call(SELECT_VALUE(0x140228E0E, 0x1402AB07C), register_cg_gun_dvars);
utils::hook::call(SELECT_VALUE(0x140228E3E, 0x1402AB0AC), register_cg_gun_dvars);
dvars::override::register_float("cg_gun_x", 0.0f, -1.0f, 2.0f, game::DVAR_FLAG_SAVED);
dvars::override::register_float("cg_gun_y", 0.0f, 0.0f, 0.0f, game::DVAR_FLAG_NONE);
dvars::override::register_float("cg_gun_z", 0.0f, 0.0f, 0.0f, game::DVAR_FLAG_NONE);
// Register cg_fovscale with new params
utils::hook::call(SELECT_VALUE(0x140317079, 0x140272777), register_fovscale_stub);
dvars::override::register_float("cg_fovScale", 1.0f, 0.1f, 5.0f, game::DVAR_FLAG_SAVED);
// Patch Dvar_Command to print out values how CoD4 does it
utils::hook::jump(SELECT_VALUE(0x1403BFCB0, 0x140416A60), dvar_command_patch);
@ -320,8 +268,7 @@ namespace patches
// Allow executing custom cfg files with the "exec" command
utils::hook::jump(SELECT_VALUE(0x1403B39BB, 0x1403F752B), SELECT_VALUE(0x1403B3A12, 0x1403F7582));
//Use a relative jump to empty memory first
utils::hook::jump(SELECT_VALUE(0x1403B3A12, 0x1403F7582), SELECT_VALUE(cmd_exec_stub_sp, cmd_exec_stub_mp),
true);
utils::hook::jump(SELECT_VALUE(0x1403B3A12, 0x1403F7582), SELECT_VALUE(cmd_exec_stub_sp, cmd_exec_stub_mp), true);
// Use empty memory to go to our stub first (can't do close jump, so need space for 12 bytes)
// Fix mouse lag
@ -331,10 +278,6 @@ namespace patches
SetThreadExecutionState(ES_DISPLAY_REQUIRED);
}, scheduler::pipeline::main);
// Allow kbam input when gamepad is enabled
utils::hook::nop(SELECT_VALUE(0x14023D490, 0x1402C3099), 2);
utils::hook::nop(SELECT_VALUE(0x14023B3AC, 0x1402C0CE0), 6);
if (game::environment::is_sp())
{
patch_sp();
@ -365,7 +308,23 @@ namespace patches
utils::hook::set(0x140599890, 0xC301B0); // Entitlements_IsIDUnlocked
// Enable DLC items, extra loadouts and map selection in extinction
dvar_register_int_hook.create(0x1404EE270, &dvar_register_int);
dvars::override::register_int("extinction_map_selection_enabled", 1, 0, 1, 0);
dvars::override::register_int("extendedLoadoutsEnable", 1, 0, 1, 0);
dvars::override::register_int("igs_announcer", 3, 3, 3, 0);
dvars::override::register_int("igs_swp", 1, 0, 1, 0);
dvars::override::register_int("igs_shp", 1, 0, 1, 0);
dvars::override::register_int("igs_svp", 1, 0, 1, 0);
dvars::override::register_int("igs_sve", 1, 0, 1, 0);
dvars::override::register_int("igs_svs", 1, 0, 1, 0);
dvars::override::register_int("igs_svr", 1, 0, 1, 0);
dvars::override::register_int("igs_swap", 1, 0, 1, 0);
dvars::override::register_int("igs_fo", 1, 0, 1, 0);
dvars::override::register_int("igs_td", 1, 0, 1, 0);
dvars::override::register_int("igs_sripper", 1, 0, 1, 0);
dvars::override::register_int("igs_smappacks", 1, 0, 1, 0);
dvars::override::register_int("igs_sosp", 1, 0, 1, 0);
dvars::override::register_int("igs_s1", 1, 0, 1, 0);
dvars::override::register_int("igs_crossgame", 1, 0, 1, 0);
// Patch game chat on resolutions higher than 1080p to use the right font
utils::hook::call(0x14025C825, get_chat_font_handle);
@ -373,7 +332,7 @@ namespace patches
utils::hook::call(0x1402C3699, get_chat_font_handle);
dvars::aimassist_enabled = game::Dvar_RegisterBool("aimassist_enabled", true,
game::DvarFlags::DVAR_FLAG_SAVED,
game::DVAR_FLAG_SAVED,
"Enables aim assist for controllers");
// Client side aim assist dvar
utils::hook::call(0x14013B9AC, aim_assist_add_to_target_list);

View File

@ -17,10 +17,20 @@ namespace ranked
utils::hook::detour bg_bot_fast_file_enabled_hook;
utils::hook::detour bg_bots_using_team_difficulty_hook;
int bg_bot_system_enabled_stub()
bool should_activate_bot_system()
{
const auto* game_type = game::Dvar_FindVar("g_gametype")->current.string;
if (!std::strcmp(game_type, "aliens") || !std::strcmp(game_type, "horde"))
{
return false;
}
return true;
}
int bg_bot_system_enabled_stub()
{
if (!should_activate_bot_system())
{
return bg_bot_system_enabled_hook.invoke<int>();
}
@ -30,8 +40,7 @@ namespace ranked
int bg_ai_system_enabled_stub()
{
const auto* game_type = game::Dvar_FindVar("g_gametype")->current.string;
if (!std::strcmp(game_type, "aliens") || !std::strcmp(game_type, "horde"))
if (!should_activate_bot_system())
{
return bg_ai_system_enabled_hook.invoke<int>();
}
@ -41,8 +50,7 @@ namespace ranked
int bg_bot_fast_file_enabled_stub()
{
const auto* game_type = game::Dvar_FindVar("g_gametype")->current.string;
if (!std::strcmp(game_type, "aliens") || !std::strcmp(game_type, "horde"))
if (!should_activate_bot_system())
{
return bg_bot_fast_file_enabled_hook.invoke<int>();
}
@ -52,8 +60,7 @@ namespace ranked
int bg_bots_using_team_difficulty_stub()
{
const auto* game_type = game::Dvar_FindVar("g_gametype")->current.string;
if (!std::strcmp(game_type, "aliens") || !std::strcmp(game_type, "horde"))
if (!should_activate_bot_system())
{
return bg_bots_using_team_difficulty_hook.invoke<int>();
}
@ -86,7 +93,7 @@ namespace ranked
game::Dvar_RegisterBool("force_ranking", true, game::DVAR_FLAG_WRITE, "Force ranking");
// Fix sessionteam always returning none (SV_HasAssignedTeam_Internal)
utils::hook::set(0x140479CF0, 0xC300B0);
utils::hook::set<std::uint32_t>(0x140479CF0, 0xC300B0);
}
// Always run bots, even if xblive_privatematch is 0

View File

@ -48,7 +48,7 @@ namespace rcon
const auto client = &game::mp::svs_clients[i];
auto self = &game::mp::g_entities[i];
char clean_name[32] = {0};
char clean_name[32]{};
strncpy_s(clean_name, self->client->sess.cs.name, sizeof(clean_name));
game::I_CleanStr(clean_name);
@ -175,7 +175,7 @@ namespace rcon
const auto password = data.substr(0, pos);
const auto command = data.substr(pos + 1);
const auto rcon_password = game::Dvar_FindVar("rcon_password");
const auto* rcon_password = game::Dvar_FindVar("rcon_password");
if (command.empty() || !rcon_password || !*rcon_password->current.string)
{
return;

View File

@ -45,6 +45,9 @@ namespace dvars
game::dvar_t* cg_legacyCrashHandling = nullptr;
game::dvar_t* com_developer_script = nullptr;
game::dvar_t** com_developer;
std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain)
{
if (domain.vector.min == -FLT_MAX)

View File

@ -44,6 +44,9 @@ namespace dvars
extern game::dvar_t* cg_legacyCrashHandling;
extern game::dvar_t* com_developer_script;
extern game::dvar_t** com_developer;
std::string dvar_get_vector_domain(int components, const game::dvar_limits& domain);
std::string dvar_get_domain(game::dvar_type type, const game::dvar_limits& domain);
}

View File

@ -12,6 +12,21 @@
#include <version.hpp>
const char* get_current_date()
{
auto now = std::chrono::system_clock::now();
auto current_time = std::chrono::system_clock::to_time_t(now);
std::tm local_time{};
(void)localtime_s(&local_time, &current_time);
std::stringstream ss;
ss << std::put_time(&local_time, "%Y%m%d_%H%M%S");
const auto result = ss.str();
return utils::string::va("%s", result.data());
}
LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception_info)
{
if (exception_info->ExceptionRecord->ExceptionCode == 0x406D1388)
@ -38,7 +53,7 @@ LONG WINAPI exception_handler(PEXCEPTION_POINTERS exception_info)
| MiniDumpWithThreadInfo;
CreateDirectoryA("minidumps", nullptr);
const auto* file_name = utils::string::va("minidumps\\iw6-mod_%s_%u.dmp", SHORTVERSION, static_cast<std::uint32_t>(std::time(nullptr)));
const auto* file_name = utils::string::va("minidumps\\iw6-mod_%s_%s.dmp", SHORTVERSION, get_current_date());
constexpr auto file_share = FILE_SHARE_READ | FILE_SHARE_WRITE;
const auto file_handle = CreateFileA(file_name, GENERIC_WRITE | GENERIC_READ, file_share, nullptr,