#include #include "loader/component_loader.hpp" #include #include #include "command.hpp" #include "filesystem.hpp" namespace patches { namespace { void sys_init_stub() { game::Cmd_SetAutoComplete("exec", "", "cfg"); utils::hook::invoke(0x4EEB20); } void cl_play_unskippable_cinematic_f() { // CL_PlayCinematic_f utils::hook::invoke(0x4CC950); *game::cin_skippable = true; } void cl_start_multiplayer_f() { utils::nt::update_dll_search_path(filesystem::get_binary_directory()); utils::nt::launch_process("iw4mp.exe", "-multiplayer"); command::execute("quit", false); } const char* live_get_local_client_name_stub() { return game::Dvar_FindVar("name")->current.string; } bool g_exit_after_tool_complete_stub() { return false; } void ui_replace_directive_stub(const int local_client_num, const char* src_string, char* dst_string, const int dst_buffer_size) { if (!src_string) { return; } if (!dst_string) { return; } if (dst_buffer_size <= 0) { return; } constexpr std::size_t MAX_HUDELEM_TEXT_LEN = 0x100; if (std::strlen(src_string) > MAX_HUDELEM_TEXT_LEN) { return; } game::UI_ReplaceDirective(local_client_num, src_string, dst_string, dst_buffer_size); } } // namespace class component final : public component_interface { public: void post_load() override { utils::hook(0x6042A2, sys_init_stub, HOOK_CALL).install()->quick(); utils::hook(0x6216CC, g_exit_after_tool_complete_stub, HOOK_CALL) .install() // hook* ->quick(); // UI_LoadMenuLists utils::hook(0x4E638C, g_exit_after_tool_complete_stub, HOOK_CALL) .install() // hook* ->quick(); // Vehicle_Create utils::hook(0x65F54A, g_exit_after_tool_complete_stub, HOOK_CALL) .install() // hook* ->quick(); // ?? utils::hook(0x425F6F, g_exit_after_tool_complete_stub, HOOK_CALL) .install() // hook* ->quick(); // ?? utils::hook(0x663845, g_exit_after_tool_complete_stub, HOOK_CALL) .install() // hook* ->quick(); // ?? utils::hook(0x492EF0, live_get_local_client_name_stub, HOOK_JUMP) .install() // hook* ->quick(); utils::hook(0x563C0C, ui_replace_directive_stub, HOOK_CALL) .install() // hook* ->quick(); utils::hook(0x56454F, ui_replace_directive_stub, HOOK_CALL) .install() // hook* ->quick(); utils::hook(0x568A7E, ui_replace_directive_stub, HOOK_CALL) .install() // hook* ->quick(); utils::hook(0x6283AE, ui_replace_directive_stub, HOOK_CALL) .install() // hook* ->quick(); patch_sp(); } private: static void patch_sp() { // Force external console utils::hook::nop(0x604071, 21); // Remove limit on IWD file loading utils::hook::set(0x630FF3, 0xEB); // Ignore XUID match utils::hook::set(0x65D1AF, 0xEB); // Remove this particular string from the log file utils::hook::nop(0x6030A6, 5); // Config related utils::hook::set(0x4D3FD3, 0xEB); // Improper quit popup utils::hook::nop(0x4F5B3A, 2); // Remove fs_game check utils::hook::nop(0x612932, 2); // Build os path stuff utils::hook::set(0x6300BF, 0xEB); // raw -> main utils::hook::set(0x50A0B2, 0x723390); // Disable 'replay' output utils::hook::nop(0x65F14A, 5); // Disable heartbeat output utils::hook::nop(0x57EF87, 5); // Allow intro to be skipped utils::hook::set(0x47529F, cl_play_unskippable_cinematic_f); // Start IW4 MP utils::hook::set(0x475327, cl_start_multiplayer_f); // Enable commandline arguments utils::hook::set(0x453B24, 0xEB); // Rename config utils::hook::set(0x6040F2, CLIENT_CONFIG); utils::hook::set(0x602D38, CLIENT_CONFIG); utils::hook::set(0x6037C9, CLIENT_CONFIG); utils::hook::set(0x4D3FDB, CLIENT_CONFIG); utils::hook::set(0x469DB6, CLIENT_CONFIG); } }; } // namespace patches REGISTER_COMPONENT(patches::component)