1.04 -> 1.15

This commit is contained in:
Skull Merlin 2022-05-17 17:56:26 +03:00
parent 83eb4851b9
commit 1d06f9108c
61 changed files with 516 additions and 293 deletions

View File

@ -303,7 +303,7 @@ targetname "h1-mod"
pchheader "std_include.hpp"
pchsource "src/client/std_include.cpp"
linkoptions {"/IGNORE:4254", "/DYNAMICBASE:NO", "/SAFESEH:NO", "/LARGEADDRESSAWARE", "/LAST:.main", "/PDBCompress"}
linkoptions {"/IGNORE:4254", "/SAFESEH:NO", "/LARGEADDRESSAWARE", "/PDBCompress"}
files {"./src/client/**.rc", "./src/client/**.hpp", "./src/client/**.cpp", "./src/client/resources/**.*"}

View File

@ -0,0 +1,163 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "scheduler.hpp"
#include "game/game.hpp"
#include <utils/hook.hpp>
namespace arxan
{
namespace
{
DWORD get_steam_pid()
{
static DWORD pid = 0; //234567;//GetCurrentProcessId();
if (pid) return pid;
HKEY hRegKey;
if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_QUERY_VALUE,
&hRegKey) != ERROR_SUCCESS)
return pid;
DWORD dwLength = sizeof(pid);
RegQueryValueExA(hRegKey, "pid", nullptr, nullptr, reinterpret_cast<BYTE*>(&pid), &dwLength);
RegCloseKey(hRegKey);
return pid;
}
utils::hook::detour nt_close_hook;
utils::hook::detour nt_query_information_process_hook;
NTSTATUS WINAPI nt_query_information_process_stub(const HANDLE handle, const PROCESSINFOCLASS info_class,
const PVOID info,
const ULONG info_length, const PULONG ret_length)
{
auto* orig = static_cast<decltype(NtQueryInformationProcess)*>(nt_query_information_process_hook.
get_original());
const auto status = orig(handle, info_class, info, info_length, ret_length);
if (NT_SUCCESS(status))
{
if (info_class == ProcessBasicInformation)
{
static DWORD explorer_pid = 0;
if (!explorer_pid)
{
auto* const shell_window = GetShellWindow();
GetWindowThreadProcessId(shell_window, &explorer_pid);
}
static_cast<PPROCESS_BASIC_INFORMATION>(info)->Reserved3 = PVOID(DWORD64(get_steam_pid()));
}
else if (info_class == 30) // ProcessDebugObjectHandle
{
*static_cast<HANDLE*>(info) = nullptr;
return 0xC0000353;
}
else if (info_class == 7) // ProcessDebugPort
{
*static_cast<HANDLE*>(info) = nullptr;
}
else if (info_class == 31)
{
*static_cast<ULONG*>(info) = 1;
}
//https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess
}
return status;
}
NTSTATUS NTAPI nt_close_stub(const HANDLE handle)
{
char info[16];
if (NtQueryObject(handle, OBJECT_INFORMATION_CLASS(4), &info, 2, nullptr) >= 0 && size_t(handle) != 0x12345)
{
auto* orig = static_cast<decltype(NtClose)*>(nt_close_hook.get_original());
return orig(handle);
}
return STATUS_INVALID_HANDLE;
}
LONG WINAPI exception_filter(const LPEXCEPTION_POINTERS info)
{
if (info->ExceptionRecord->ExceptionCode == STATUS_INVALID_HANDLE)
{
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
void hide_being_debugged()
{
auto* const peb = PPEB(__readgsqword(0x60));
peb->BeingDebugged = false;
*reinterpret_cast<PDWORD>(LPSTR(peb) + 0xBC) &= ~0x70;
}
void remove_hardware_breakpoints()
{
CONTEXT context;
ZeroMemory(&context, sizeof(context));
context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
auto* const thread = GetCurrentThread();
GetThreadContext(thread, &context);
context.Dr0 = 0;
context.Dr1 = 0;
context.Dr2 = 0;
context.Dr3 = 0;
context.Dr6 = 0;
context.Dr7 = 0;
SetThreadContext(thread, &context);
}
BOOL WINAPI set_thread_context_stub(const HANDLE thread, CONTEXT* context)
{
return SetThreadContext(thread, context);
}
}
class component final : public component_interface
{
public:
void* load_import(const std::string& library, const std::string& function) override
{
if (function == "SetThreadContext")
{
//return set_thread_context_stub;
}
return nullptr;
}
void post_load() override
{
hide_being_debugged();
scheduler::loop(hide_being_debugged, scheduler::pipeline::async);
const utils::nt::library ntdll("ntdll.dll");
nt_close_hook.create(ntdll.get_proc<void*>("NtClose"), nt_close_stub);
nt_query_information_process_hook.create(ntdll.get_proc<void*>("NtQueryInformationProcess"),
nt_query_information_process_stub);
// https://www.geoffchappell.com/studies/windows/win32/ntdll/api/index.htm
AddVectoredExceptionHandler(1, exception_filter);
}
void post_unpack() override
{
// cba to implement sp, not sure if it's even needed
if (game::environment::is_sp()) return;
}
};
}
REGISTER_COMPONENT(arxan::component)

View File

@ -218,19 +218,19 @@ namespace auth
}
else
{
utils::hook::jump(0x140571E07, 0x140571E5A); // H1(1.4)
utils::hook::jump(0x14004B223, 0x14004B4F2); // H1(1.4)
utils::hook::jump(0x14004B4AD, 0x14004B4F2); // H1(1.4)
utils::hook::jump(0x140572F6F, 0x140572FB0); // H1(1.4)
utils::hook::jump(0x140573470, 0x1405734B6); // H1(1.4)
utils::hook::jump(0x1D6193_b, 0x1D61FA_b); // 1.15
utils::hook::jump(0x60153_b, 0x60426_b); // 1.15
utils::hook::jump(0x603E1_b, 0x60426_b); // 1.15
utils::hook::jump(0x1D7542_b, 0x1D7587_b); // 1.15, MAYBE `1D7553` ON FIRST
utils::hook::jump(0x1D7A82_b, 0x1D7AC8_b); // 1.15
utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4)
utils::hook::call(0x140250ED2, send_connect_data_stub); // H1(1.4)
//utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) couldn't find
utils::hook::call(0x12D437_b, send_connect_data_stub); // 1.15
// Skip checks for sending connect packet
utils::hook::jump(0x1402508FC, 0x140250946);
utils::hook::jump(0x12CDFC_b, 0x12CE5C_b); // 1.15
// Don't instantly timeout the connecting client ? not sure about this
utils::hook::set(0x14025136B, 0xC3);
//utils::hook::set(0x14025136B, 0xC3); // gonna lookup for this soon
}
command::add("guid", []()
@ -241,4 +241,4 @@ namespace auth
};
}
REGISTER_COMPONENT(auth::component)
//REGISTER_COMPONENT(auth::component)

View File

@ -135,4 +135,4 @@ namespace binding
};
}
REGISTER_COMPONENT(binding::component)
//REGISTER_COMPONENT(binding::component)

View File

@ -106,4 +106,4 @@ namespace bots
};
}
REGISTER_COMPONENT(bots::component)
//REGISTER_COMPONENT(bots::component)

View File

@ -34,7 +34,6 @@ namespace branding
public:
void post_unpack() override
{
if (game::environment::is_dedi())
{
return;
@ -42,24 +41,26 @@ namespace branding
if (game::environment::is_mp())
{
localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n");
localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER");
//localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n");
//localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER");
}
dvars::override::set_string("version", utils::string::va("H1-Mod %s", VERSION));
//dvars::override::set_string("version", utils::string::va("H1-Mod %s", VERSION));
ui_get_formatted_build_number_hook.create(
SELECT_VALUE(0x1403B1C40, 0x1404E74C0), ui_get_formatted_build_number_stub);
SELECT_VALUE(0x0, 0x1DF300_b), ui_get_formatted_build_number_stub);
scheduler::loop([]()
{
const auto font = game::R_RegisterFont("fonts/fira_mono_bold.ttf", 20);
game::R_AddCmdDrawText("H1-Mod: " VERSION, 0x7FFFFFFF, font, 10.f,
5.f + static_cast<float>(font->pixelHeight), 1.f, 1.f, 0.0f, color, 0);
if (font)
{
game::R_AddCmdDrawText("H1-Mod: " VERSION, 0x7FFFFFFF, font, 10.f,
5.f + static_cast<float>(font->pixelHeight), 1.f, 1.f, 0.0f, color, 0);
}
}, scheduler::pipeline::renderer);
}
};
}
REGISTER_COMPONENT(branding::component)
//REGISTER_COMPONENT(branding::component)

View File

@ -49,4 +49,4 @@ namespace chat
};
}
REGISTER_COMPONENT(chat::component)
//REGISTER_COMPONENT(chat::component)

View File

@ -179,4 +179,4 @@ namespace colors
};
}
REGISTER_COMPONENT(colors::component)
//REGISTER_COMPONENT(colors::component)

View File

@ -818,4 +818,4 @@ namespace command
};
}
REGISTER_COMPONENT(command::component)
//REGISTER_COMPONENT(command::component)

View File

@ -296,4 +296,4 @@ namespace console
}
}
REGISTER_COMPONENT(console::component)
//REGISTER_COMPONENT(console::component)

View File

@ -330,4 +330,4 @@ namespace dedicated
};
}
REGISTER_COMPONENT(dedicated::component)
//REGISTER_COMPONENT(dedicated::component)

View File

@ -62,4 +62,4 @@ namespace dedicated_info
};
}
REGISTER_COMPONENT(dedicated_info::component)
//REGISTER_COMPONENT(dedicated_info::component)

View File

@ -596,4 +596,4 @@ namespace demonware
};
}
REGISTER_COMPONENT(demonware::component)
//REGISTER_COMPONENT(demonware::component)

View File

@ -285,4 +285,4 @@ namespace discord
};
}
REGISTER_COMPONENT(discord::component)
//REGISTER_COMPONENT(discord::component)

View File

@ -198,4 +198,4 @@ namespace dvar_cheats
};
}
REGISTER_COMPONENT(dvar_cheats::component)
//REGISTER_COMPONENT(dvar_cheats::component)

View File

@ -440,4 +440,4 @@ namespace dvars
};
}
REGISTER_COMPONENT(dvars::component)
//REGISTER_COMPONENT(dvars::component)

View File

@ -258,4 +258,4 @@ namespace exception
};
}
REGISTER_COMPONENT(exception::component)
//REGISTER_COMPONENT(exception::component)

View File

@ -56,4 +56,4 @@ namespace fastfiles
};
}
REGISTER_COMPONENT(fastfiles::component)
//REGISTER_COMPONENT(fastfiles::component)

View File

@ -130,4 +130,4 @@ namespace filesystem
};
}
REGISTER_COMPONENT(filesystem::component)
//REGISTER_COMPONENT(filesystem::component)

View File

@ -133,4 +133,4 @@ namespace fonts
};
}
REGISTER_COMPONENT(fonts::component)
//REGISTER_COMPONENT(fonts::component)

View File

@ -179,4 +179,4 @@ namespace fps
};
}
REGISTER_COMPONENT(fps::component)
//REGISTER_COMPONENT(fps::component)

View File

@ -797,4 +797,4 @@ namespace game_console
};
}
REGISTER_COMPONENT(game_console::component)
//REGISTER_COMPONENT(game_console::component)

View File

@ -3,6 +3,7 @@
#include "game_module.hpp"
#include <utils/hook.hpp>
#include <game/game.hpp>
namespace game_module
{
@ -90,7 +91,7 @@ namespace game_module
utils::nt::library get_game_module()
{
static utils::nt::library game{HMODULE(0x140000000)};
static utils::nt::library game{HMODULE(game::base_address)};
return game;
}
@ -110,7 +111,11 @@ namespace game_module
void post_load() override
{
#ifdef INJECT_HOST_AS_LIB
hook_module_resolving();
#else
assert(get_host_module() == get_game_module());
#endif
}
};
}

View File

@ -227,4 +227,4 @@ namespace gameplay
};
}
REGISTER_COMPONENT(gameplay::component)
//REGISTER_COMPONENT(gameplay::component)

View File

@ -72,4 +72,4 @@ namespace input
};
}
REGISTER_COMPONENT(input::component)
//REGISTER_COMPONENT(input::component)

View File

@ -44,9 +44,9 @@ namespace localized_strings
void post_unpack() override
{
// Change some localized strings
seh_string_ed_get_string_hook.create(SELECT_VALUE(0x1403924A0, 0x1404BB2A0), &seh_string_ed_get_string);
seh_string_ed_get_string_hook.create(SELECT_VALUE(0x0, 0x585DA0_b), &seh_string_ed_get_string); // 1.15
}
};
}
REGISTER_COMPONENT(localized_strings::component)
//REGISTER_COMPONENT(localized_strings::component)

View File

@ -314,4 +314,4 @@ namespace logfile
};
}
REGISTER_COMPONENT(logfile::component)
//REGISTER_COMPONENT(logfile::component)

View File

@ -177,4 +177,4 @@ namespace logger
};
}
REGISTER_COMPONENT(logger::component)
//REGISTER_COMPONENT(logger::component)

View File

@ -55,4 +55,4 @@ namespace lui
};
}
REGISTER_COMPONENT(lui::component)
//REGISTER_COMPONENT(lui::component)

View File

@ -177,4 +177,4 @@ namespace map_rotation
};
}
REGISTER_COMPONENT(map_rotation::component)
//REGISTER_COMPONENT(map_rotation::component)

View File

@ -209,4 +209,4 @@ namespace materials
};
}
REGISTER_COMPONENT(materials::component)
//REGISTER_COMPONENT(materials::component)

View File

@ -116,4 +116,4 @@ namespace mods
};
}
REGISTER_COMPONENT(mods::component)
//REGISTER_COMPONENT(mods::component)

View File

@ -323,4 +323,4 @@ namespace network
};
}
REGISTER_COMPONENT(network::component)
//REGISTER_COMPONENT(network::component)

View File

@ -642,4 +642,4 @@ namespace party
};
}
REGISTER_COMPONENT(party::component)
//REGISTER_COMPONENT(party::component)

View File

@ -283,4 +283,4 @@ namespace patches
};
}
REGISTER_COMPONENT(patches::component)
//REGISTER_COMPONENT(patches::component)

View File

@ -44,4 +44,4 @@ namespace ranked
};
}
REGISTER_COMPONENT(ranked::component)
//REGISTER_COMPONENT(ranked::component)

View File

@ -80,4 +80,4 @@ namespace redirect
};
}
REGISTER_COMPONENT(redirect::component)
//REGISTER_COMPONENT(redirect::component)

View File

@ -82,4 +82,4 @@ namespace renderer
};
}
REGISTER_COMPONENT(renderer::component)
//REGISTER_COMPONENT(renderer::component)

View File

@ -75,7 +75,8 @@ namespace scheduler
{
new_callbacks_.access([&](task_list& new_tasks)
{
tasks.insert(tasks.end(), std::move_iterator<task_list::iterator>(new_tasks.begin()), std::move_iterator<task_list::iterator>(new_tasks.end()));
tasks.insert(tasks.end(), std::move_iterator<task_list::iterator>(new_tasks.begin()),
std::move_iterator<task_list::iterator>(new_tasks.end()));
new_tasks = {};
});
});
@ -88,7 +89,7 @@ namespace scheduler
utils::hook::detour r_end_frame_hook;
utils::hook::detour g_run_frame_hook;
utils::hook::detour main_frame_hook;
utils::hook::detour hks_frame_hook;
//utils::hook::detour hks_frame_hook; //no scripting for now
void execute(const pipeline type)
{
@ -99,7 +100,7 @@ namespace scheduler
void r_end_frame_stub()
{
execute(pipeline::renderer);
r_end_frame_hook.invoke<void>();
//r_end_frame_hook.invoke<void>();
}
void server_frame_stub()
@ -125,7 +126,7 @@ namespace scheduler
}
void schedule(const std::function<bool()>& callback, const pipeline type,
const std::chrono::milliseconds delay)
const std::chrono::milliseconds delay)
{
assert(type >= 0 && type < pipeline::count);
@ -138,7 +139,7 @@ namespace scheduler
}
void loop(const std::function<void()>& callback, const pipeline type,
const std::chrono::milliseconds delay)
const std::chrono::milliseconds delay)
{
schedule([callback]()
{
@ -148,7 +149,7 @@ namespace scheduler
}
void once(const std::function<void()>& callback, const pipeline type,
const std::chrono::milliseconds delay)
const std::chrono::milliseconds delay)
{
schedule([callback]()
{
@ -158,7 +159,7 @@ namespace scheduler
}
void on_game_initialized(const std::function<void()>& callback, const pipeline type,
const std::chrono::milliseconds delay)
const std::chrono::milliseconds delay)
{
schedule([=]()
{
@ -190,10 +191,23 @@ namespace scheduler
void post_unpack() override
{
r_end_frame_hook.create(SELECT_VALUE(0x1404F7310, 0x1405FE470), scheduler::r_end_frame_stub);
g_run_frame_hook.create(SELECT_VALUE(0x1402772D0, 0x14033A640), scheduler::server_frame_stub);
main_frame_hook.create(SELECT_VALUE(0x1401CE8D0, 0x1400D8310), scheduler::main_frame_stub);
hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), scheduler::hks_frame_stub);
utils::hook::jump(SELECT_VALUE(0, 0x6A6300_b), utils::hook::assemble([](utils::hook::assembler& a)
{
a.pushad64();
a.call_aligned(r_end_frame_stub);
a.popad64();
a.sub(rsp, 0x28);
a.call(0x6A5C20_b);
a.mov(rax, 0xEAB4308_b);
a.mov(rax, qword_ptr(rax));
a.jmp(0x6A6310_b);
}), true);
//r_end_frame_hook.create(SELECT_VALUE(0x0, 0x6A6300_b), scheduler::r_end_frame_stub);
//g_run_frame_hook.create(SELECT_VALUE(0x0, 0x417940_b), scheduler::server_frame_stub);
//main_frame_hook.create(SELECT_VALUE(0x0, 0x0), scheduler::main_frame_stub);
//hks_frame_hook.create(SELECT_VALUE(0x0, 0x0), scheduler::hks_frame_stub); // no scripting for now
}
void pre_destroy() override
@ -207,4 +221,4 @@ namespace scheduler
};
}
REGISTER_COMPONENT(scheduler::component)
//REGISTER_COMPONENT(scheduler::component)

View File

@ -216,4 +216,4 @@ namespace scripting
};
}
REGISTER_COMPONENT(scripting::component)
//REGISTER_COMPONENT(scripting::component)

View File

@ -423,4 +423,4 @@ namespace server_list
};
}
REGISTER_COMPONENT(server_list::component)
//REGISTER_COMPONENT(server_list::component)

View File

@ -48,4 +48,4 @@ namespace shaders
};
}
REGISTER_COMPONENT(shaders::component)
//REGISTER_COMPONENT(shaders::component)

View File

@ -50,4 +50,4 @@ namespace slowmotion
};
}
REGISTER_COMPONENT(slowmotion::component)
//REGISTER_COMPONENT(slowmotion::component)

View File

@ -138,4 +138,4 @@ namespace splash
};
}
REGISTER_COMPONENT(splash::component)
//REGISTER_COMPONENT(splash::component)

View File

@ -88,4 +88,4 @@ namespace stats
};
}
REGISTER_COMPONENT(stats::component)
//REGISTER_COMPONENT(stats::component)

View File

@ -185,4 +185,4 @@ namespace steam_proxy
}
}
REGISTER_COMPONENT(steam_proxy::component)
//REGISTER_COMPONENT(steam_proxy::component)

View File

@ -51,13 +51,13 @@ namespace system_check
{
static std::unordered_map<std::string, std::string> mp_zone_hashes =
{
{"patch_common_mp.ff", "3F44B0CFB0B8E0FBD9687C2942204AB7F11E66E6E15C73B8B4A5EB5920115A31"},
{"patch_common_mp.ff", "E45EF5F29D12A5A47F405F89FBBEE479C0A90D02141ABF852D481689514134A1"},
};
static std::unordered_map<std::string, std::string> sp_zone_hashes =
{
// Steam doesn't necessarily deliver this file :(
{"patch_common.ff", "BB0617DD94AF2F511571E7184BBEDE76E64D97E5D0DAFDB457F00717F035EBF0"},
{"patch_common.ff", "1D32A9770F90ED022AA76F4859B4AB178E194A703383E61AC2CE83B1E828B18F"},
};
@ -85,7 +85,7 @@ namespace system_check
public:
void post_load() override
{
verify_binary_version();
//verify_binary_version();
if (!is_valid())
{
@ -97,4 +97,4 @@ namespace system_check
};
}
REGISTER_COMPONENT(system_check::component)
//REGISTER_COMPONENT(system_check::component)

View File

@ -57,4 +57,4 @@ namespace thread_names
};
}
REGISTER_COMPONENT(thread_names::component)
//REGISTER_COMPONENT(thread_names::component)

View File

@ -206,4 +206,4 @@ namespace ui_scripting
};
}
REGISTER_COMPONENT(ui_scripting::component)
//REGISTER_COMPONENT(ui_scripting::component)

View File

@ -468,4 +468,4 @@ namespace updater
};
}
REGISTER_COMPONENT(updater::component)
//REGISTER_COMPONENT(updater::component)

View File

@ -52,4 +52,4 @@ namespace videos
};
}
REGISTER_COMPONENT(videos::component)
//REGISTER_COMPONENT(videos::component)

View File

@ -61,4 +61,4 @@ namespace virtuallobby
};
}
REGISTER_COMPONENT(virtuallobby::component)
//REGISTER_COMPONENT(virtuallobby::component)

View File

@ -3,6 +3,14 @@
namespace game
{
uint64_t base_address;
void load_base_address()
{
const auto module = GetModuleHandle(NULL);
base_address = uint64_t(module);
}
int Cmd_Argc()
{
return cmd_args->argc[cmd_args->nesting];
@ -102,3 +110,8 @@ namespace game
}
}
}
uintptr_t operator"" _b(const uintptr_t ptr)
{
return game::base_address + ptr;
}

View File

@ -5,10 +5,13 @@
#define SELECT_VALUE(sp, mp) (game::environment::is_sp() ? (sp) : (mp))
#define SERVER_CD_KEY "S1X-CD-Key"
#define SERVER_CD_KEY "H1MOD-CD-Key"
namespace game
{
extern uint64_t base_address;
void load_base_address();
namespace environment
{
launcher::mode get_mode();
@ -67,4 +70,6 @@ namespace game
bool VirtualLobby_Loaded();
}
uintptr_t operator"" _b(const uintptr_t ptr);
#include "symbols.hpp"

View File

@ -8,119 +8,119 @@ namespace game
* Functions
**************************************************************/
WEAK symbol<void(int type, VariableUnion u)> AddRefToValue{0x14036E600, 0x14043C580};
WEAK symbol<void(int type, VariableUnion u)> RemoveRefToValue{0x1403700F0, 0x14043E090};
WEAK symbol<void(unsigned int id)> AddRefToObject{0x14036E5F0, 0x14043C570};
WEAK symbol<void(unsigned int id)> RemoveRefToObject{0x14036FFE0, 0x14043DF80};
WEAK symbol<unsigned int(unsigned int id)> AllocThread{0x14036E960, 0x14043C8E0};
WEAK symbol<ObjectVariableValue*(unsigned int* id)> AllocVariable{0x14036E9C0, 0x14043C940};
WEAK symbol<void(int type, VariableUnion u)> AddRefToValue{0x0, 0x0};
WEAK symbol<void(int type, VariableUnion u)> RemoveRefToValue{0x0, 0x0};
WEAK symbol<void(unsigned int id)> AddRefToObject{0x0, 0x0};
WEAK symbol<void(unsigned int id)> RemoveRefToObject{0x0, 0x0};
WEAK symbol<unsigned int(unsigned int id)> AllocThread{0x0, 0x0};
WEAK symbol<ObjectVariableValue*(unsigned int* id)> AllocVariable{0x0, 0x0};
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{0x140342EB0, 0x1404033B0};
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{0x0, 0x1CF480}; // 1.15
WEAK symbol<void(int localClientNum, int controllerIndex, const char* buffer,
void (int, int, const char*))> Cbuf_ExecuteBufferInternal{0x140342FC0, 0x1404034C0};
WEAK symbol<void(const char* message)> Conbuf_AppendText{0x1403E3300, 0x140513FF0};
WEAK symbol<char*(int start)> ConcatArgs{0x1402697F0, 0x140335D70};
WEAK symbol<void(int localClientNum, int controllerIndex, const char* text)> Cmd_ExecuteSingleCommand{0x140343980, 0x140403F60};
WEAK symbol<void(const char* cmdName, void(), cmd_function_s* allocedCmd)> Cmd_AddCommandInternal{0x1403433E0, 0x140403950};
WEAK symbol<void(const char*)> Cmd_RemoveCommand{0x140343FF0, 0x1404045D0};
WEAK symbol<void(const char* text_in)> Cmd_TokenizeString{0x140344110, 0x1404046F0};
WEAK symbol<void()> Cmd_EndTokenizeString{0x140343630, 0x140403C20};
void (int, int, const char*))> Cbuf_ExecuteBufferInternal{0x0, 0x0};
WEAK symbol<void(const char* message)> Conbuf_AppendText{0x0, 0x0};
WEAK symbol<char*(int start)> ConcatArgs{0x0, 0x0};
WEAK symbol<void(int localClientNum, int controllerIndex, const char* text)> Cmd_ExecuteSingleCommand{0x0, 0x0};
WEAK symbol<void(const char* cmdName, void(), cmd_function_s* allocedCmd)> Cmd_AddCommandInternal{0x0, 0x0};
WEAK symbol<void(const char*)> Cmd_RemoveCommand{0x0, 0x0};
WEAK symbol<void(const char* text_in)> Cmd_TokenizeString{0x0, 0x0};
WEAK symbol<void()> Cmd_EndTokenizeString{0x0, 0x0};
WEAK symbol<void(void*, void*)> AimAssist_AddToTargetList{0, 0x14009D0F0};
WEAK symbol<void(void*, void*)> AimAssist_AddToTargetList{0x0, 0x0};
WEAK symbol<void(unsigned int weapon, bool isAlternate,
char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x140430550, 0x1401F9670};
char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x0, 0x0};
WEAK symbol<void()> Com_Frame_Try_Block_Function{0x1401CE8D0, 0x1400D8310};
WEAK symbol<CodPlayMode()> Com_GetCurrentCoDPlayMode{0, 0x1405039A0};
WEAK symbol<bool()> Com_InFrontend{0x1400E4B30, 0x140176A30};
WEAK symbol<void(float, float, int)> Com_SetSlowMotion{0, 0x1400DB790};
WEAK symbol<void(errorParm code, const char* message, ...)> Com_Error{0x1403509C0, 0x1400D78A0};
WEAK symbol<void()> Com_Quit_f{0x140352BE0, 0x1400DA830};
WEAK symbol<void(char const* finalMessage)> Com_Shutdown{0x140353B70, 0x1400DB8A0};
WEAK symbol<void()> Com_Frame_Try_Block_Function{0x0, 0x0};
WEAK symbol<CodPlayMode()> Com_GetCurrentCoDPlayMode{0x0, 0x0};
WEAK symbol<bool()> Com_InFrontend{0x0, 0x0};
WEAK symbol<void(float, float, int)> Com_SetSlowMotion{0x0, 0x0};
WEAK symbol<void(errorParm code, const char* message, ...)> Com_Error{0x0, 0x0};
WEAK symbol<void()> Com_Quit_f{0x0, 0x0};
WEAK symbol<void(char const* finalMessage)> Com_Shutdown{0x0, 0x0};
WEAK symbol<void()> Quit{0x140352D90, 0x1400DA830};
WEAK symbol<void()> Quit{0x0, 0x0};
WEAK symbol<void(int localClientNum, const char* message)> CG_GameMessage{0x1401389A0, 0x140220CC0};
WEAK symbol<void(int localClientNum, const char* message)> CG_GameMessageBold{0x140138750, 0x140220620};
WEAK symbol<void(int localClientNum, const char* message)> CG_GameMessage{0x0, 0x0};
WEAK symbol<void(int localClientNum, const char* message)> CG_GameMessageBold{0x0, 0x0};
WEAK symbol<void(int localClientNum, /*mp::cg_s**/void* cg,
const char* dvar, const char* value)> CG_SetClientDvarFromServer{0, 0x140236120};
const char* dvar, const char* value)> CG_SetClientDvarFromServer{0x0, 0x0};
WEAK symbol<char*(const unsigned int weapon,
bool isAlternate, char* outputBuffer, int bufferLen)> CG_GetWeaponDisplayName{0x14016EC30, 0x1400B5840};
bool isAlternate, char* outputBuffer, int bufferLen)> CG_GetWeaponDisplayName{0x0, 0x0};
WEAK symbol<bool()> CL_IsCgameInitialized{0x14017EE30, 0x140245650};
WEAK symbol<void(int a1)> CL_VirtualLobbyShutdown{0, 0x140256D40};
WEAK symbol<bool()> CL_IsCgameInitialized{0x0, 0x0};
WEAK symbol<void(int a1)> CL_VirtualLobbyShutdown{0x0, 0x0};
WEAK symbol<void(int hash, const char* name, const char* buffer)> Dvar_SetCommand{0x1403C72B0, 0x1404FD0A0};
WEAK symbol<dvar_t*(const char* name)> Dvar_FindVar{0x1403C5D50, 0x1404FBB00};
WEAK symbol<void(const dvar_t* dvar)> Dvar_ClearModified{0x1403C5C20, 0x1404FB930};
WEAK symbol<void(char* buffer, int index)> Dvar_GetCombinedString{0x140354DF0, 0x14041D830};
WEAK symbol<const char*(dvar_t* dvar, dvar_value value)> Dvar_ValueToString{0x1403C8560, 0x1404FE660};
WEAK symbol<void(dvar_t* dvar, DvarSetSource source)> Dvar_Reset{0, 0x1404FCC40};
WEAK symbol<void(int hash, const char* name, const char* buffer)> Dvar_SetCommand{0x0, 0x0};
WEAK symbol<dvar_t*(const char* name)> Dvar_FindVar{0x0, 0x0};
WEAK symbol<void(const dvar_t* dvar)> Dvar_ClearModified{0x0, 0x0};
WEAK symbol<void(char* buffer, int index)> Dvar_GetCombinedString{0x0, 0x0};
WEAK symbol<const char*(dvar_t* dvar, dvar_value value)> Dvar_ValueToString{0x0, 0x0};
WEAK symbol<void(dvar_t* dvar, DvarSetSource source)> Dvar_Reset{0x0, 0x0};
WEAK symbol<void(const char*, const char*,
DvarSetSource)> Dvar_SetFromStringByNameFromSource{0, 0x1404FD490};
DvarSetSource)> Dvar_SetFromStringByNameFromSource{0x0, 0x0};
WEAK symbol<dvar_t*(int hash, const char* name, bool value,
unsigned int flags)> Dvar_RegisterBool{0x1403C47E0, 0x1404FA540};
unsigned int flags)> Dvar_RegisterBool{0x0, 0x0};
WEAK symbol<dvar_t*(int hash, const char* name, int value, int min, int max,
unsigned int flags)> Dvar_RegisterInt{0x1403C4CC0, 0x1404FAA20};
unsigned int flags)> Dvar_RegisterInt{0x0, 0x0};
WEAK symbol<dvar_t*(int hash, const char* dvarName, float value, float min,
float max, unsigned int flags)> Dvar_RegisterFloat{0x1403C4BB0, 0x1404FA910};
float max, unsigned int flags)> Dvar_RegisterFloat{0x0, 0x0};
WEAK symbol<dvar_t*(int hash, const char* dvarName, const char* value,
unsigned int flags)> Dvar_RegisterString{0x1403C4DA0, 0x1404FAB00};
unsigned int flags)> Dvar_RegisterString{0x0, 0x0};
WEAK symbol<dvar_t*(int dvarName, const char* a2, float x, float y, float z,
float w, float min, float max, unsigned int flags)> Dvar_RegisterVec4{0x1403C5220, 0x1404FAF40};
float w, float min, float max, unsigned int flags)> Dvar_RegisterVec4{0x0, 0x0};
WEAK symbol<long long(const char* qpath, char** buffer)> FS_ReadFile{0x1403B9020, 0x1404EE720};
WEAK symbol<void(void* buffer)> FS_FreeFile{0x1403B9010, 0x1404EE710};
WEAK symbol<void(const char* gameName)> FS_Startup{0x1403B85D0, 0x1404EDD30};
WEAK symbol<void(const char* path, const char* dir)> FS_AddLocalizedGameDirectory{0x1403B6030, 0x1404EBE20};
WEAK symbol<long long(const char* qpath, char** buffer)> FS_ReadFile{0x0, 0x0};
WEAK symbol<void(void* buffer)> FS_FreeFile{0x0, 0x0};
WEAK symbol<void(const char* gameName)> FS_Startup{0x0, 0x0};
WEAK symbol<void(const char* path, const char* dir)> FS_AddLocalizedGameDirectory{0x0, 0x0};
WEAK symbol<unsigned int(unsigned int, unsigned int)> GetVariable{0x14036FDD0, 0x14043DD70};
WEAK symbol<unsigned int(unsigned int parentId, unsigned int unsignedValue)> GetNewVariable{0x14036FA00, 0x14043D990};
WEAK symbol<unsigned int(unsigned int parentId, unsigned int unsignedValue)> GetNewArrayVariable{0x14036F880, 0x14043D810};
WEAK symbol<void()> GScr_LoadConsts{0x1402D13E0, 0x140393810};
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindVariable{0x14036F4B0, 0x14043D430};
WEAK symbol<unsigned int(int entnum, unsigned int classnum)> FindEntityId{0x14036F3B0, 0x14043D330};
WEAK symbol<void(unsigned int parentId, unsigned int index)> RemoveVariableValue{0x140370190, 0x14043E130};
WEAK symbol<unsigned int(unsigned int, unsigned int)> GetVariable{0x0, 0x0};
WEAK symbol<unsigned int(unsigned int parentId, unsigned int unsignedValue)> GetNewVariable{0x0, 0x0};
WEAK symbol<unsigned int(unsigned int parentId, unsigned int unsignedValue)> GetNewArrayVariable{0x0, 0x0};
WEAK symbol<void()> GScr_LoadConsts{0x0, 0x0};
WEAK symbol<unsigned int(unsigned int parentId, unsigned int name)> FindVariable{0x0, 0x0};
WEAK symbol<unsigned int(int entnum, unsigned int classnum)> FindEntityId{0x0, 0x0};
WEAK symbol<void(unsigned int parentId, unsigned int index)> RemoveVariableValue{0x0, 0x0};
WEAK symbol<void(VariableValue* result, unsigned int classnum,
int entnum, int offset)> GetEntityFieldValue{0x140373780, 0x140441780};
int entnum, int offset)> GetEntityFieldValue{0x0, 0x0};
WEAK symbol<int(const char* fname)> generateHashValue{0x1400FE8A0, 0x1401B1010};
WEAK symbol<int(const char* fname)> generateHashValue{0x0, 0x0};
WEAK symbol<void()> G_Glass_Update{0x14026C570, 0x14033A640};
WEAK symbol<int(int clientNum)> G_GetClientScore{0, 0x140342F90};
WEAK symbol<unsigned int(const char* name)> G_GetWeaponForName{0x1402C2A90, 0x14038C300};
WEAK symbol<void()> G_Glass_Update{0x0, 0x0};
WEAK symbol<int(int clientNum)> G_GetClientScore{0x0, 0x0};
WEAK symbol<unsigned int(const char* name)> G_GetWeaponForName{0x0, 0x0};
WEAK symbol<int(playerState_s* ps, unsigned int weapon, int dualWield,
int startInAltMode, int, int, int, char, ...)> G_GivePlayerWeapon{0x1402C2DF0, 0x14038C750};
WEAK symbol<void(playerState_s* ps, unsigned int weapon, int hadWeapon)> G_InitializeAmmo{0x140270980, 0x14033EDD0};
WEAK symbol<void(int clientNum, unsigned int weapon)> G_SelectWeapon{0x1402C3750, 0x14038D1B0};
WEAK symbol<int(playerState_s* ps, unsigned int weapon)> G_TakePlayerWeapon{0x1402C3900, 0x14038D370};
int startInAltMode, int, int, int, char, ...)> G_GivePlayerWeapon{0x0, 0x0};
WEAK symbol<void(playerState_s* ps, unsigned int weapon, int hadWeapon)> G_InitializeAmmo{0x0, 0x0};
WEAK symbol<void(int clientNum, unsigned int weapon)> G_SelectWeapon{0x0, 0x0};
WEAK symbol<int(playerState_s* ps, unsigned int weapon)> G_TakePlayerWeapon{0x0, 0x0};
WEAK symbol<char*(char* string)> I_CleanStr{0x1403CD230, 0x140503D00};
WEAK symbol<char*(char* string)> I_CleanStr{0x0, 0x0};
WEAK symbol<const char* (int, int, int)> Key_KeynumToString{0x140187CC0, 0x14024FE10};
WEAK symbol<const char* (int, int, int)> Key_KeynumToString{0x0, 0x0};
WEAK symbol<unsigned int(int)> Live_SyncOnlineDataFlags{0, 0x14059A700};
WEAK symbol<unsigned int(int)> Live_SyncOnlineDataFlags{0x0, 0x0};
WEAK symbol<Material* (const char* material)> Material_RegisterHandle{0x1404E48B0, 0x1405EAB30};
WEAK symbol<Material* (const char* material)> Material_RegisterHandle{0x0, 0x0};
WEAK symbol<void(netadr_s*, sockaddr*)> NetadrToSockadr{0x1403C11C0, 0x1404F62F0};
WEAK symbol<void(netsrc_t, netadr_s*, const char*)> NET_OutOfBandPrint{0x140357560, 0x1404255D0};
WEAK symbol<void(netsrc_t sock, int length, const void* data, const netadr_s* to)> NET_SendLoopPacket{0, 0x140425790};
WEAK symbol<bool(const char* s, netadr_s* a)> NET_StringToAdr{0, 0x140425870};
WEAK symbol<void(netadr_s*, sockaddr*)> NetadrToSockadr{0x0, 0x0};
WEAK symbol<void(netsrc_t, netadr_s*, const char*)> NET_OutOfBandPrint{0x0, 0x0};
WEAK symbol<void(netsrc_t sock, int length, const void* data, const netadr_s* to)> NET_SendLoopPacket{0x0, 0x0};
WEAK symbol<bool(const char* s, netadr_s* a)> NET_StringToAdr{0x0, 0x0};
WEAK symbol<void(float x, float y, float width, float height, float s0, float t0, float s1, float t1,
float* color, Material* material)> R_AddCmdDrawStretchPic{0x14017E5C0, 0x1402443A0};
WEAK symbol<Font_s* (const char* font, int size)> R_RegisterFont{0x1404D4100, 0x1405D91E0};
WEAK symbol<int(const char* text, int maxChars, Font_s* font)> R_TextWidth{0x1404D43B0, 0x1405D94A0};
WEAK symbol<int(void* font)> R_GetFontHeight{0x1405EA360, 0x1405D92C0};
WEAK symbol<void* (int a1)> R_DrawSomething{0x1404D37B0, 0x1405D8890};
WEAK symbol<void()> R_SyncRenderThread{0x1404F8240, 0x1405FF3A0};
float* color, Material* material)> R_AddCmdDrawStretchPic{0x0, 0x0};
WEAK symbol<Font_s* (const char* font, int size)> R_RegisterFont{0x0, 0x67F630}; // 1.15
WEAK symbol<int(const char* text, int maxChars, Font_s* font)> R_TextWidth{0x0, 0x0};
WEAK symbol<int(void* font)> R_GetFontHeight{0x0, 0x67F710}; // 1.15
WEAK symbol<void* (int a1)> R_DrawSomething{0x0, 0x67ECE0}; // 1.15
WEAK symbol<void()> R_SyncRenderThread{0x0, 0x0};
WEAK symbol<void* (const char* text, int maxChars, void* font, int fontHeight, float x,
float y, float xScale, float yScale, float rotation, float* color,
int style, int cursor_pos, char cursor_char,
void* style_unk)> H1_AddBaseDrawTextCmd{0x1404F3DC0, 0x1405FB1F0};
void* style_unk)> H1_AddBaseDrawTextCmd{0x0, 0x6A3080}; // 1.15
#define R_AddCmdDrawText(TXT, MC, F, X, Y, XS, YS, R, C, S) \
H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S,-1, 0, game::R_DrawSomething(S))
@ -128,157 +128,155 @@ namespace game
H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S, CP, CC, game::R_DrawSomething(S))
WEAK symbol<char* (GfxImage* image, uint32_t width, uint32_t height, uint32_t depth, uint32_t mipCount,
uint32_t imageFlags, DXGI_FORMAT imageFormat, const char* name, const D3D11_SUBRESOURCE_DATA* initData)> Image_Setup{0x1404D7D50, 0x1405DCF90};
uint32_t imageFlags, DXGI_FORMAT imageFormat, const char* name, const D3D11_SUBRESOURCE_DATA* initData)> Image_Setup{0x0, 0x0};
WEAK symbol<unsigned int(unsigned int localId, const char* pos,
unsigned int paramcount)> VM_Execute{0x140376360, 0x140444350};
unsigned int paramcount)> VM_Execute{0x0, 0x0};
WEAK symbol<void(unsigned int id, scr_string_t stringValue,
unsigned int paramcount)> Scr_NotifyId{0x140375800, 0x1404437E0};
WEAK symbol<const float*(const float* v)> Scr_AllocVector{0x140370930, 0x14043E7D0};
WEAK symbol<float(int index)> Scr_GetFloat{0x140374D20, 0x140442D10};
WEAK symbol<const char*(int index)> Scr_GetString{0x140375210, 0x140443150};
WEAK symbol<int()> Scr_GetNumParam{0x140374F30, 0x140442E70};
WEAK symbol<void()> Scr_ClearOutParams{0x140374460, 0x140442510};
WEAK symbol<scr_entref_t(unsigned int entId)> Scr_GetEntityIdRef{0x140372D50, 0x140440D80};
WEAK symbol<unsigned int(int classnum, unsigned int entnum)> Scr_GetEntityId{0x140372CA0, 0x140440CD0};
WEAK symbol<int(unsigned int classnum, int entnum, int offset)> Scr_SetObjectField{0x1402B9F60, 0x140385330};
unsigned int paramcount)> Scr_NotifyId{0x0, 0x0};
WEAK symbol<const float*(const float* v)> Scr_AllocVector{0x0, 0x0};
WEAK symbol<float(int index)> Scr_GetFloat{0x0, 0x0};
WEAK symbol<const char*(int index)> Scr_GetString{0x0, 0x0};
WEAK symbol<int()> Scr_GetNumParam{0x0, 0x0};
WEAK symbol<void()> Scr_ClearOutParams{0x0, 0x0};
WEAK symbol<scr_entref_t(unsigned int entId)> Scr_GetEntityIdRef{0x0, 0x0};
WEAK symbol<unsigned int(int classnum, unsigned int entnum)> Scr_GetEntityId{0x0, 0x0};
WEAK symbol<int(unsigned int classnum, int entnum, int offset)> Scr_SetObjectField{0x0, 0x0};
WEAK symbol<ScreenPlacement* ()> ScrPlace_GetViewPlacement{0x1401981F0, 0x140288550};
WEAK symbol<ScreenPlacement* ()> ScrPlace_GetViewPlacement{0x0, 0x0};
WEAK symbol<void(XAssetType type, void(__cdecl* func)(XAssetHeader, void*), const void* inData, bool includeOverride)>
DB_EnumXAssets_Internal{0x1401C9C10, 0x1402BA830};
WEAK symbol<const char*(const XAsset* asset)> DB_GetXAssetName{0x14019A390, 0x14028BE50};
WEAK symbol<int(XAssetType type)> DB_GetXAssetTypeSize{0x14019A3B0, 0x14028BE70};
DB_EnumXAssets_Internal{0x0, 0x0};
WEAK symbol<const char*(const XAsset* asset)> DB_GetXAssetName{0x0, 0x0};
WEAK symbol<int(XAssetType type)> DB_GetXAssetTypeSize{0x0, 0x0};
WEAK symbol<XAssetHeader(XAssetType type, const char* name,
int createDefault)> DB_FindXAssetHeader{0x1401CA150, 0x1402BAC70};
int createDefault)> DB_FindXAssetHeader{0x0, 0x0};
WEAK symbol<void(int clientNum, const char* menu,
int a3, int a4, unsigned int a5)> LUI_OpenMenu{0x14039D5F0, 0x1404CD210};
WEAK symbol<bool(int clientNum, const char* name, hks::lua_State* s)> LUI_BeginEvent{0x1400D27F0, 0x140161A00};
WEAK symbol<void(hks::lua_State* s)> LUI_EndEvent{0x1400D3A80, 0x140162CD0};
WEAK symbol<void()> LUI_EnterCriticalSection{0x1400D3B70, 0x140162DC0};
WEAK symbol<void()> LUI_LeaveCriticalSection{0x1400D8DB0, 0x140168150};
int a3, int a4, unsigned int a5)> LUI_OpenMenu{0x0, 0x0};
WEAK symbol<bool(int clientNum, const char* name, hks::lua_State* s)> LUI_BeginEvent{0x0, 0x0};
WEAK symbol<void(hks::lua_State* s)> LUI_EndEvent{0x0, 0x0};
WEAK symbol<void()> LUI_EnterCriticalSection{0x0, 0x0};
WEAK symbol<void()> LUI_LeaveCriticalSection{0x0, 0x0};
WEAK symbol<bool(int clientNum, const char* menu)> Menu_IsMenuOpenAndVisible{0x1404709C0, 0x1404C7320};
WEAK symbol<bool(int clientNum, const char* menu)> Menu_IsMenuOpenAndVisible{0x0, 0x0};
WEAK symbol<scr_string_t(const char* str)> SL_FindString{0x14036D700, 0x14043B470};
WEAK symbol<scr_string_t(const char* str, unsigned int user)> SL_GetString{0x14036D9A0, 0x14043B840};
WEAK symbol<const char*(scr_string_t stringValue)> SL_ConvertToString{0x14036D420, 0x14043B170};
WEAK symbol<unsigned int(const char* str)> SL_GetCanonicalString{0x14036A310, 0x140437EA0};
WEAK symbol<scr_string_t(const char* str)> SL_FindString{0x0, 0x0};
WEAK symbol<scr_string_t(const char* str, unsigned int user)> SL_GetString{0x0, 0x0};
WEAK symbol<const char*(scr_string_t stringValue)> SL_ConvertToString{0x0, 0x0};
WEAK symbol<unsigned int(const char* str)> SL_GetCanonicalString{0x0, 0x0};
WEAK symbol<void(netadr_s* from)> SV_DirectConnect{0, 0x140480860};
WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{0x1403446C0, 0x140404CA0};
WEAK symbol<void(const char* text_in)> SV_Cmd_TokenizeString{0x140344740, 0x140404D20};
WEAK symbol<void()> SV_Cmd_EndTokenizedString{0x140344700, 0x140404CE0};
WEAK symbol<void(netadr_s* from)> SV_DirectConnect{0x0, 0x0};
WEAK symbol<void(int arg, char* buffer, int bufferLength)> SV_Cmd_ArgvBuffer{0x0, 0x0};
WEAK symbol<void(const char* text_in)> SV_Cmd_TokenizeString{0x0, 0x0};
WEAK symbol<void()> SV_Cmd_EndTokenizedString{0x0, 0x0};
WEAK symbol<mp::gentity_s*(const char* name)> SV_AddBot{0, 0x140480190};
WEAK symbol<bool(int clientNum)> SV_BotIsBot{0, 0x14046E6C0};
WEAK symbol<const char* ()> SV_BotGetRandomName{0, 0x14046DBA0};
WEAK symbol<int(mp::gentity_s* ent)> SV_SpawnTestClient{0, 0x1404832A0};
WEAK symbol<mp::gentity_s*(const char* name)> SV_AddBot{0x0, 0x0};
WEAK symbol<bool(int clientNum)> SV_BotIsBot{0x0, 0x0};
WEAK symbol<const char* ()> SV_BotGetRandomName{0x0, 0x0};
WEAK symbol<int(mp::gentity_s* ent)> SV_SpawnTestClient{0x0, 0x0};
WEAK symbol<const char* (int clientNum)> SV_GetGuid{0, 0x140484B90};
WEAK symbol<int(int clientNum)> SV_GetClientPing{0, 0x140484B70};
WEAK symbol<playerState_s* (int num)> SV_GetPlayerstateForClientNum{0x1404426D0, 0x140484C10};
WEAK symbol<void(int index, const char* string)> SV_SetConfigstring{0, 0x140486720};
WEAK symbol<bool()> SV_Loaded{0x140442F60, 0x1404864A0};
WEAK symbol<void(int clientNum, const char* reason)> SV_KickClientNum{0, 0x14047ED00};
WEAK symbol<bool(const char* map)> SV_MapExists{0, 0x14047ED60};
WEAK symbol<void(mp::client_t*, const char*, int)> SV_ExecuteClientCommand{0, 0x140481870};
WEAK symbol<void(int localClientNum)> SV_FastRestart{0, 0x14047E990};
WEAK symbol<void(int clientNum, svscmd_type type, const char* text)> SV_GameSendServerCommand{
0x1403F3A70, 0x140484AD0
};
WEAK symbol<const char* (int clientNum)> SV_GetGuid{0x0, 0x0};
WEAK symbol<int(int clientNum)> SV_GetClientPing{0x0, 0x0};
WEAK symbol<playerState_s* (int num)> SV_GetPlayerstateForClientNum{0x0, 0x0};
WEAK symbol<void(int index, const char* string)> SV_SetConfigstring{0x0, 0x0};
WEAK symbol<bool()> SV_Loaded{0x0, 0x0};
WEAK symbol<void(int clientNum, const char* reason)> SV_KickClientNum{0x0, 0x0};
WEAK symbol<bool(const char* map)> SV_MapExists{0x0, 0x0};
WEAK symbol<void(mp::client_t*, const char*, int)> SV_ExecuteClientCommand{0x0, 0x0};
WEAK symbol<void(int localClientNum)> SV_FastRestart{0x0, 0x0};
WEAK symbol<void(int clientNum, svscmd_type type, const char* text)> SV_GameSendServerCommand{0x0, 0x0};
WEAK symbol<void()> Sys_ShowConsole{0x1403E3B90, 0x140514910};
WEAK symbol<void(const char* error, ...)> Sys_Error{0x1403E0C40, 0x140511520};
WEAK symbol<void()> Sys_ShowConsole{0x0, 0x0};
WEAK symbol<void(const char* error, ...)> Sys_Error{0x0, 0x0};
WEAK symbol<void(char* path, int pathSize, Sys_Folder folder, const char* filename, const char* ext)>
Sys_BuildAbsPath{0x1403CFF90, 0x140507010};
WEAK symbol<int()> Sys_Milliseconds{0x1403E2B10, 0x140513710};
WEAK symbol<bool()> Sys_IsDatabaseReady2{0x1403580B0, 0x14042B090};
WEAK symbol<bool(int, void const*, const netadr_s*)> Sys_SendPacket{0x1403E2820, 0x1405133B0};
WEAK symbol<bool(const char* path)> Sys_FileExists{0x1403E0CE0, 0x1405115E0};
Sys_BuildAbsPath{0x0, 0x0};
WEAK symbol<int()> Sys_Milliseconds{0x0, 0x0};
WEAK symbol<bool()> Sys_IsDatabaseReady2{0x0, 0x0};
WEAK symbol<bool(int, void const*, const netadr_s*)> Sys_SendPacket{0x0, 0x0};
WEAK symbol<bool(const char* path)> Sys_FileExists{0x0, 0x0};
WEAK symbol<const char* (const char*)> UI_GetMapDisplayName{0, 0x140408CC0};
WEAK symbol<const char* (const char*)> UI_GetGameTypeDisplayName{0, 0x1404086A0};
WEAK symbol<void(unsigned int localClientNum, const char** args)> UI_RunMenuScript{0x14039EFF0, 0x1404CFE60};
WEAK symbol<int(const char* text, int maxChars, Font_s* font, float scale)> UI_TextWidth{0x1403A0F20, 0x1404D21A0};
WEAK symbol<const char* (const char*)> UI_GetMapDisplayName{0x0, 0x0};
WEAK symbol<const char* (const char*)> UI_GetGameTypeDisplayName{0x0, 0x0};
WEAK symbol<void(unsigned int localClientNum, const char** args)> UI_RunMenuScript{0x0, 0x0};
WEAK symbol<int(const char* text, int maxChars, Font_s* font, float scale)> UI_TextWidth{0x0, 0x0};
WEAK symbol<const char*(const char* string)> UI_SafeTranslateString{0x140350430, 0x14041C580};
WEAK symbol<const char*(const char* string)> UI_SafeTranslateString{0x0, 0x0};
WEAK symbol<void* (jmp_buf* Buf, int Value)> longjmp{0x140648FD4, 0x140779F64};
WEAK symbol<int(jmp_buf* Buf)> _setjmp{0x1406BFD30, 0x1407F5F90};
WEAK symbol<void* (jmp_buf* Buf, int Value)> longjmp{0x0, 0x0};
WEAK symbol<int(jmp_buf* Buf)> _setjmp{0x0, 0x0};
/***************************************************************
* Variables
**************************************************************/
WEAK symbol<CmdArgs> sv_cmd_args{0x14AD99A10, 0x14946BA20};
WEAK symbol<CmdArgs> sv_cmd_args{0x0, 0x0};
WEAK symbol<int> g_script_error_level{0x14BCFA4A4, 0x14A33C824};
WEAK symbol<jmp_buf> g_script_error{0x14BCFA5C0, 0x14A33C940};
WEAK symbol<int> g_script_error_level{0x0, 0x0};
WEAK symbol<jmp_buf> g_script_error{0x0, 0x0};
WEAK symbol<unsigned int> levelEntityId{0x14B65E3B0, 0x149CA0730};
WEAK symbol<unsigned int> gameEntityId{0x14B65E3B4, 0x149CA0734};
WEAK symbol<unsigned int> levelEntityId{0x0, 0x0};
WEAK symbol<unsigned int> gameEntityId{0x0, 0x0};
WEAK symbol<const char*> command_whitelist{0x141079A60, 0x14120C360};
WEAK symbol<cmd_function_s*> cmd_functions{0x14AD99AB8, 0x14946BAC8};
WEAK symbol<CmdArgs> cmd_args{0x14AD99960, 0x14946B970};
WEAK symbol<const char*> command_whitelist{0x0, 0x0};
WEAK symbol<cmd_function_s*> cmd_functions{0x0, 0x344DF18}; // 1.15
WEAK symbol<CmdArgs> cmd_args{0x0, 0x0};
WEAK symbol<int> g_poolSize{0x140DE84A0, 0x140FEADF0};
WEAK symbol<scr_classStruct_t> g_classMap{0x14107AAF0, 0x1412106B0};
WEAK symbol<int> g_poolSize{0x0, 0x0};
WEAK symbol<scr_classStruct_t> g_classMap{0x0, 0x0};
WEAK symbol<scrVarGlob_t> scr_VarGlob{0x14B686480, 0x149CC8800};
WEAK symbol<scrVmPub_t> scr_VmPub{0x14BCFC6C0, 0x14A33EA40};
WEAK symbol<function_stack_t> scr_function_stack{0x14BD06C40, 0x14A348FC0};
WEAK symbol<scrVarGlob_t> scr_VarGlob{0x0, 0x0};
WEAK symbol<scrVmPub_t> scr_VmPub{0x0, 0x0};
WEAK symbol<function_stack_t> scr_function_stack{0x0, 0x0};
WEAK symbol<GfxDrawMethod_s> gfxDrawMethod{0x14F05CE50, 0x14FD21180};
WEAK symbol<GfxDrawMethod_s> gfxDrawMethod{0x0, 0x0};
WEAK symbol<int> dvarCount{0x14C217D10, 0x14D064CF4};
WEAK symbol<dvar_t> dvarPool{0x14C217D20, 0x14D064D00};
WEAK symbol<int> dvarCount{0x0, 0x0};
WEAK symbol<dvar_t> dvarPool{0x0, 0x0};
WEAK symbol<void*> DB_XAssetPool{0x140DE8C80, 0x140FEB5D0};
WEAK symbol<const char*> g_assetNames{0x1408B0870, 0x140FEA240};
WEAK symbol<void*> DB_XAssetPool{0x0, 0x0};
WEAK symbol<const char*> g_assetNames{0x0, 0x0};
WEAK symbol<int> keyCatchers{0x14243DAF0, 0x142D0BA9C};
WEAK symbol<PlayerKeyState> playerKeys{0x1422A873C, 0x142C19AFC};
WEAK symbol<int> keyCatchers{0x0, 0x0};
WEAK symbol<PlayerKeyState> playerKeys{0x0, 0x0};
WEAK symbol<SOCKET> query_socket{0, 0x14DDFBF98};
WEAK symbol<SOCKET> query_socket{0x0, 0x0};
WEAK symbol<DWORD> threadIds{0x14B19B880, 0x149810E00};
WEAK symbol<DWORD> threadIds{0x0, 0x0};
namespace mp
{
WEAK symbol<gentity_s> g_entities{0, 0x14621E530};
WEAK symbol<client_t> svs_clients{0, 0x14B204A10};
WEAK symbol<int> svs_numclients{0, 0x14B204A0C};
WEAK symbol<int> gameTime{0, 0x14621BDBC};
WEAK symbol<gentity_s> g_entities{0x0, 0x71F19E0}; // 1.15
WEAK symbol<client_t> svs_clients{0x0, 0x0};
WEAK symbol<int> svs_numclients{0x0, 0x0};
WEAK symbol<int> gameTime{0x0, 0x0};
WEAK symbol<int> ping{0, 0x142D106F0};
WEAK symbol<int> ping{0x0, 0x0};
WEAK symbol<int> sv_serverId_value{0, 0x14A3E99B8};
WEAK symbol<int> sv_serverId_value{0x0, 0x0};
WEAK symbol<bool> virtualLobby_loaded{0, 0x142D077FD};
WEAK symbol<bool> virtualLobby_loaded{0x0, 0x0};
}
namespace sp
{
WEAK symbol<gentity_s> g_entities{0x14550DD90, 0};
WEAK symbol<gentity_s> g_entities{0x0, 0x0};
}
namespace hks
{
WEAK symbol<lua_State*> lua_state{0x141E2C2F8, 0x1426D3D08};
WEAK symbol<void(lua_State* s, const char* str, unsigned int l)> hksi_lua_pushlstring{0x14004DA90, 0x1400624F0};
WEAK symbol<HksObject*(HksObject* result, lua_State* s, const HksObject* table, const HksObject* key)> hks_obj_getfield{0x14009C0A0, 0x14012C600};
WEAK symbol<void(lua_State* s, const HksObject* tbl, const HksObject* key, const HksObject* val)> hks_obj_settable{0x14009D240, 0x14012D820};
WEAK symbol<HksObject* (HksObject* result, lua_State* s, const HksObject* table, const HksObject* key)> hks_obj_gettable{0x14009C580, 0x14012CAE0};
WEAK symbol<void(lua_State* s, int nargs, int nresults, const unsigned int* pc)> vm_call_internal{0x1400C87A0, 0x140159EB0};
WEAK symbol<HashTable*(lua_State* s, unsigned int arraySize, unsigned int hashSize)> Hashtable_Create{0x14008B3B0, 0x14011B320};
WEAK symbol<lua_State*> lua_state{0x0, 0x0};
WEAK symbol<void(lua_State* s, const char* str, unsigned int l)> hksi_lua_pushlstring{0x0, 0x0};
WEAK symbol<HksObject*(HksObject* result, lua_State* s, const HksObject* table, const HksObject* key)> hks_obj_getfield{0x0, 0x0};
WEAK symbol<void(lua_State* s, const HksObject* tbl, const HksObject* key, const HksObject* val)> hks_obj_settable{0x0, 0x0};
WEAK symbol<HksObject* (HksObject* result, lua_State* s, const HksObject* table, const HksObject* key)> hks_obj_gettable{0x0, 0x0};
WEAK symbol<void(lua_State* s, int nargs, int nresults, const unsigned int* pc)> vm_call_internal{0x0, 0x0};
WEAK symbol<HashTable*(lua_State* s, unsigned int arraySize, unsigned int hashSize)> Hashtable_Create{0x0, 0x0};
WEAK symbol<cclosure*(lua_State* s, lua_function function, int num_upvalues,
int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x14008B5D0, 0x14011B540};
WEAK symbol<int(lua_State* s, int t)> hksi_luaL_ref{0x1400A64D0, 0x140136D30};
WEAK symbol<void(lua_State* s, int t, int ref)> hksi_luaL_unref{0x14009EF10, 0x14012F610};
WEAK symbol<void(lua_State* s, HksObject* lfp)> closePendingUpvalues{0x14008EA00, 0x14011E970};
int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x0, 0x0};
WEAK symbol<int(lua_State* s, int t)> hksi_luaL_ref{0x0, 0x0};
WEAK symbol<void(lua_State* s, int t, int ref)> hksi_luaL_unref{0x0, 0x0};
WEAK symbol<void(lua_State* s, HksObject* lfp)> closePendingUpvalues{0x0, 0x0};
}
}

View File

@ -31,7 +31,7 @@ FARPROC loader::load(const utils::nt::library& library, const std::string& buffe
return FARPROC(library.get_ptr() + source.get_relative_entry_point());
}
FARPROC loader::load_library(const std::string& filename) const
FARPROC loader::load_library(const std::string& filename, uint64_t* base_address) const
{
const auto target = utils::nt::library::load(filename);
if (!target)
@ -40,10 +40,7 @@ FARPROC loader::load_library(const std::string& filename) const
}
const auto base = size_t(target.get_ptr());
if(base != 0x140000000)
{
throw std::runtime_error{utils::string::va("Binary was mapped at 0x%llX (instead of 0x%llX). Something is severely broken :(", base, 0x140000000)};
}
*base_address = base;
this->load_imports(target, target);
this->load_tls(target, target);

View File

@ -5,7 +5,7 @@ class loader final
{
public:
FARPROC load(const utils::nt::library& library, const std::string& buffer) const;
FARPROC load_library(const std::string& filename) const;
FARPROC load_library(const std::string& filename, uint64_t* base_address) const;
void set_import_resolver(const std::function<void*(const std::string&, const std::string&)>& resolver);

View File

@ -20,16 +20,6 @@ BOOL WINAPI system_parameters_info_a(const UINT uiAction, const UINT uiParam, co
return SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni);
}
FARPROC WINAPI get_proc_address(const HMODULE hModule, const LPCSTR lpProcName)
{
if (lpProcName == "GlobalMemoryStatusEx"s)
{
component_loader::post_unpack();
}
return GetProcAddress(hModule, lpProcName);
}
launcher::mode detect_mode_from_arguments()
{
if (utils::flags::has_flag("dedicated"))
@ -50,14 +40,15 @@ launcher::mode detect_mode_from_arguments()
return launcher::mode::none;
}
FARPROC load_binary(const launcher::mode mode)
FARPROC load_binary(const launcher::mode mode, uint64_t* base_address)
{
loader loader;
utils::nt::library self;
loader.set_import_resolver([self](const std::string& library, const std::string& function) -> void*
{
if (library == "steam_api64.dll")
if (library == "steam_api64.dll"
&& function != "SteamAPI_GetSteamInstallPath") // Arxan requires one valid steam api import - maybe SteamAPI_Shutdown is better?
{
return self.get_proc<FARPROC>(function);
}
@ -69,10 +60,6 @@ FARPROC load_binary(const launcher::mode mode)
{
return system_parameters_info_a;
}
else if (function == "GetProcAddress")
{
return get_proc_address;
}
return component_loader::load_import(library, function);
});
@ -99,8 +86,13 @@ FARPROC load_binary(const launcher::mode mode)
"Failed to read game binary (%s)!\nPlease copy the h1-mod.exe into your Call of Duty: Modern Warfare Remastered installation folder and run it from there.",
binary.data()));
}
return loader.load_library(binary);
#ifdef INJECT_HOST_AS_LIB
return loader.load_library(binary, base_address);
#else
*base_address = 0x140000000;
return loader.load(self, data);
#endif
}
void remove_crash_file()
@ -158,6 +150,8 @@ void apply_proper_directory()
int main()
{
ShowWindow(GetConsoleWindow(), SW_HIDE);
FARPROC entry_point;
enable_dpi_awareness();
@ -166,6 +160,7 @@ int main()
limit_parallel_dll_loading();
srand(uint32_t(time(nullptr)));
remove_crash_file();
{
auto premature_shutdown = true;
@ -179,8 +174,8 @@ int main()
try
{
apply_proper_directory();
remove_crash_file();
//apply_proper_directory();
//remove_crash_file();
if (!component_loader::post_start()) return 0;
@ -194,12 +189,15 @@ int main()
game::environment::set_mode(mode);
entry_point = load_binary(mode);
uint64_t base_address{};
entry_point = load_binary(mode, &base_address);
if (!entry_point)
{
throw std::runtime_error("Unable to load binary into memory");
}
game::base_address = base_address;
if (!component_loader::post_load()) return 0;
premature_shutdown = false;

View File

@ -1,6 +1,23 @@
#include <std_include.hpp>
#pragma comment(linker, "/base:0x160000000")
#pragma comment(linker, "/stack:0x1000000")
#ifdef INJECT_HOST_AS_LIB
//#pragma comment(linker, "/base:0x160000000")
#else
#pragma comment(linker, "/base:0x140000000")
#pragma comment(linker, "/merge:.data=.cld")
#pragma comment(linker, "/merge:.rdata=.clr")
#pragma comment(linker, "/merge:.cl=.main")
#pragma comment(linker, "/merge:.text=.main")
#endif
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language=''\"")
#ifndef INJECT_HOST_AS_LIB
#pragma bss_seg(".payload")
char payload_data[BINARY_PAYLOAD_SIZE];
#endif
extern "C"
{

View File

@ -1,6 +1,9 @@
#pragma once
#define BINARY_PAYLOAD_SIZE 0x12000000
#define BINARY_PAYLOAD_SIZE 0x14000000
// Decide whether to load the game as lib or to inject it
#define INJECT_HOST_AS_LIB
#pragma warning(push)
#pragma warning(disable: 4100)

View File

@ -1,6 +1,8 @@
#include <std_include.hpp>
#include "steam.hpp"
#include <utils/nt.hpp>
namespace steam
{
uint64_t callbacks::call_id_ = 0;
@ -108,6 +110,13 @@ namespace steam
bool SteamAPI_Init()
{
const std::filesystem::path steam_path = steam::SteamAPI_GetSteamInstallPath();
if (steam_path.empty()) return true;
::utils::nt::library::load(steam_path / "tier0_s64.dll");
::utils::nt::library::load(steam_path / "vstdlib_s64.dll");
::utils::nt::library::load(steam_path / "gameoverlayrenderer64.dll");
::utils::nt::library::load(steam_path / "steamclient64.dll");
return true;
}
@ -235,4 +244,4 @@ namespace steam
}
}
}
}