From 2358dcf30b377b20cc96f9f12ad68293c180101d Mon Sep 17 00:00:00 2001 From: project-bo4 Date: Wed, 6 Sep 2023 05:08:38 -0700 Subject: [PATCH] developer console + added in-game developer console + added dvar definitions and helping class + list of known game dvars can be found inside variables.cpp + adjusted logger component + re-enabled com_frame hook + some minor code formatting --- .../component/{integrity.cpp => arxan.cpp} | 263 +- source/proxy-dll/component/blackbox.cpp | 2 +- source/proxy-dll/component/debugging.cpp | 169 +- source/proxy-dll/component/debugging.hpp | 5 - source/proxy-dll/component/dvars.cpp | 289 + source/proxy-dll/component/dvars.hpp | 13 + source/proxy-dll/component/experimental.cpp | 3 +- source/proxy-dll/component/game_console.cpp | 734 ++ source/proxy-dll/component/game_console.hpp | 7 + source/proxy-dll/component/logger.cpp | 36 +- source/proxy-dll/component/platform.cpp | 5 +- source/proxy-dll/component/scheduler.cpp | 5 +- source/proxy-dll/component/splash.cpp | 2 +- source/proxy-dll/definitions/discovery.cpp | 3 +- .../definitions/{t8_engine.cpp => game.cpp} | 2 +- source/proxy-dll/definitions/game.hpp | 507 ++ source/proxy-dll/definitions/t8_engine.hpp | 115 - source/proxy-dll/definitions/variables.cpp | 6510 +++++++++++++++++ source/proxy-dll/definitions/variables.hpp | 27 + source/proxy-dll/demonware/objects.cpp | 12 +- .../demonware/services/bdObjectStore.cpp | 6 +- .../demonware/services/bdProfiles.cpp | 1 + source/proxy-dll/spoofer/spoofcall.cpp | 92 + source/proxy-dll/spoofer/spoofcall.hpp | 18 + 24 files changed, 8501 insertions(+), 325 deletions(-) rename source/proxy-dll/component/{integrity.cpp => arxan.cpp} (57%) create mode 100644 source/proxy-dll/component/dvars.cpp create mode 100644 source/proxy-dll/component/dvars.hpp create mode 100644 source/proxy-dll/component/game_console.cpp create mode 100644 source/proxy-dll/component/game_console.hpp rename source/proxy-dll/definitions/{t8_engine.cpp => game.cpp} (97%) create mode 100644 source/proxy-dll/definitions/game.hpp delete mode 100644 source/proxy-dll/definitions/t8_engine.hpp create mode 100644 source/proxy-dll/definitions/variables.cpp create mode 100644 source/proxy-dll/definitions/variables.hpp create mode 100644 source/proxy-dll/spoofer/spoofcall.cpp create mode 100644 source/proxy-dll/spoofer/spoofcall.hpp diff --git a/source/proxy-dll/component/integrity.cpp b/source/proxy-dll/component/arxan.cpp similarity index 57% rename from source/proxy-dll/component/integrity.cpp rename to source/proxy-dll/component/arxan.cpp index 3b6b795..efa9aac 100644 --- a/source/proxy-dll/component/integrity.cpp +++ b/source/proxy-dll/component/arxan.cpp @@ -5,10 +5,10 @@ #include -namespace integrity +namespace arxan { namespace - { + { const std::vector>& get_text_sections() { static const std::vector> text = [] @@ -88,7 +88,7 @@ namespace integrity } uint32_t adjust_integrity_checksum(const uint64_t return_address, uint8_t* stack_frame, - const uint32_t current_checksum) + const uint32_t current_checksum) { const auto handler_address = reverse_b(return_address - 5); const auto* context = search_handler_context(stack_frame, current_checksum); @@ -96,7 +96,7 @@ namespace integrity if (!context) { MessageBoxA(nullptr, utils::string::va("No frame offset for: %llX", handler_address), "Error", - MB_ICONERROR); + MB_ICONERROR); TerminateProcess(GetCurrentProcess(), 0xBAD); return current_checksum; } @@ -107,8 +107,8 @@ namespace integrity if (current_checksum != correct_checksum) { #ifndef NDEBUG - /*printf("Adjusting checksum (%llX): %X -> %X\n", handler_address, - current_checksum, correct_checksum);*/ + /*logger::write(logger::LOG_TYPE_DEBUG, "Adjusting checksum (%llX): %X -> %X\n", handler_address, + current_checksum, correct_checksum);*/ #endif } @@ -130,38 +130,38 @@ namespace integrity const auto other_frame_offset = static_cast(next_inst >> 16); static const auto stub = utils::hook::assemble([](utils::hook::assembler& a) - { - a.push(rax); + { + a.push(rax); - a.mov(rax, qword_ptr(rsp, 8)); - a.sub(rax, 2); // Skip the push we inserted + a.mov(rax, qword_ptr(rsp, 8)); + a.sub(rax, 2); // Skip the push we inserted - a.push(rax); - a.pushad64(); + a.push(rax); + a.pushad64(); - a.mov(r8, qword_ptr(rsp, 0x88)); - a.mov(rcx, rax); - a.mov(rdx, rbp); - a.call_aligned(adjust_integrity_checksum); + a.mov(r8, qword_ptr(rsp, 0x88)); + a.mov(rcx, rax); + a.mov(rdx, rbp); + a.call_aligned(adjust_integrity_checksum); - a.mov(qword_ptr(rsp, 0x80), rax); + a.mov(qword_ptr(rsp, 0x80), rax); - a.popad64(); - a.pop(rax); + a.popad64(); + a.pop(rax); - a.add(rsp, 8); + a.add(rsp, 8); - a.mov(dword_ptr(rdx, rcx, 4), eax); + a.mov(dword_ptr(rdx, rcx, 4), eax); - a.pop(rax); // return addr - a.xchg(rax, qword_ptr(rsp)); // switch with push + a.pop(rax); // return addr + a.xchg(rax, qword_ptr(rsp)); // switch with push - a.add(dword_ptr(rbp, rax), 0xFFFFFFFF); + a.add(dword_ptr(rbp, rax), 0xFFFFFFFF); - a.mov(rax, dword_ptr(rdx, rcx, 4)); // restore rax + a.mov(rax, dword_ptr(rdx, rcx, 4)); // restore rax - a.ret(); - }); + a.ret(); + }); // push other_frame_offset utils::hook::set(game_address, static_cast(0x6A | (other_frame_offset << 8))); @@ -182,32 +182,32 @@ namespace integrity const auto jump_target = utils::hook::extract(reinterpret_cast(next_inst_addr + 1)); const auto stub = utils::hook::assemble([jump_target](utils::hook::assembler& a) - { - a.push(rax); + { + a.push(rax); - a.mov(rax, qword_ptr(rsp, 8)); - a.push(rax); + a.mov(rax, qword_ptr(rsp, 8)); + a.push(rax); - a.pushad64(); + a.pushad64(); - a.mov(r8, qword_ptr(rsp, 0x88)); - a.mov(rcx, rax); - a.mov(rdx, rbp); - a.call_aligned(adjust_integrity_checksum); + a.mov(r8, qword_ptr(rsp, 0x88)); + a.mov(rcx, rax); + a.mov(rdx, rbp); + a.call_aligned(adjust_integrity_checksum); - a.mov(qword_ptr(rsp, 0x80), rax); + a.mov(qword_ptr(rsp, 0x80), rax); - a.popad64(); - a.pop(rax); + a.popad64(); + a.pop(rax); - a.add(rsp, 8); + a.add(rsp, 8); - a.mov(dword_ptr(rdx, rcx, 4), eax); + a.mov(dword_ptr(rdx, rcx, 4), eax); - a.add(rsp, 8); + a.add(rsp, 8); - a.jmp(jump_target); - }); + a.jmp(jump_target); + }); utils::hook::call(game_address, stub); } @@ -303,8 +303,160 @@ namespace integrity return get_thread_context_hook.invoke(thread_handle, context); } + + utils::hook::detour create_mutex_ex_a_hook; + HANDLE create_mutex_ex_a_stub(const LPSECURITY_ATTRIBUTES attributes, const LPCSTR name, const DWORD flags, + const DWORD access) + { + if (name == "$ IDA trusted_idbs"s || name == "$ IDA registry mutex $"s) + { + return nullptr; + } + + return create_mutex_ex_a_hook.invoke(attributes, name, flags, access); + } + + bool remove_evil_keywords_from_string(const UNICODE_STRING& string) + { + static const std::wstring evil_keywords[] = + { + L"IDA", + L"ida", + L"HxD", + L"cheatengine", + L"Cheat Engine", + L"x96dbg", + L"x32dbg", + L"x64dbg", + L"Wireshark", + }; + + if (!string.Buffer || !string.Length) + { + return false; + } + + const std::wstring_view path(string.Buffer, string.Length / sizeof(string.Buffer[0])); + + bool modified = false; + for (const auto& keyword : evil_keywords) + { + while (true) + { + const auto pos = path.find(keyword); + if (pos == std::wstring::npos) + { + break; + } + + modified = true; + + for (size_t i = 0; i < keyword.size(); ++i) + { + string.Buffer[pos + i] = L'a'; + } + } + } + + return modified; + } + + bool remove_evil_keywords_from_string(wchar_t* str, const size_t length) + { + UNICODE_STRING unicode_string{}; + unicode_string.Buffer = str; + unicode_string.Length = static_cast(length); + unicode_string.MaximumLength = unicode_string.Length; + + return remove_evil_keywords_from_string(unicode_string); + } + + bool remove_evil_keywords_from_string(char* str, const size_t length) + { + std::string_view str_view(str, length); + std::wstring wstr(str_view.begin(), str_view.end()); + + if (!remove_evil_keywords_from_string(wstr.data(), wstr.size())) + { + return false; + } + + const std::string regular_str(wstr.begin(), wstr.end()); + memcpy(str, regular_str.data(), length); + + return true; + } + + int WINAPI get_window_text_a_stub(const HWND wnd, const LPSTR str, const int max_count) + { + std::wstring wstr{}; + wstr.resize(max_count); + + const auto res = GetWindowTextW(wnd, wstr.data(), max_count); + if (res) + { + remove_evil_keywords_from_string(wstr.data(), res); + + const std::string regular_str(wstr.begin(), wstr.end()); + memset(str, 0, max_count); + memcpy(str, regular_str.data(), res); + } + + return res; + } + + utils::hook::detour nt_query_system_information_hook; + NTSTATUS NTAPI nt_query_system_information_stub(const SYSTEM_INFORMATION_CLASS system_information_class, + const PVOID system_information, + const ULONG system_information_length, + const PULONG return_length) + { + const auto status = nt_query_system_information_hook.invoke( + system_information_class, system_information, system_information_length, return_length); + + if (NT_SUCCESS(status)) + { + if (system_information_class == SystemProcessInformation && !utils::nt::is_shutdown_in_progress()) + { + auto addr = static_cast(system_information); + while (true) + { + const auto info = reinterpret_cast(addr); + remove_evil_keywords_from_string(info->ImageName); + + if (!info->NextEntryOffset) + { + break; + } + + addr = addr + info->NextEntryOffset; + } + } + } + + return status; + } + + 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) + { + NTSTATUS status = nt_query_information_process_hook.invoke(handle, info_class, info, info_length, + ret_length); + + if (NT_SUCCESS(status)) + { + if (info_class == ProcessImageFileName || static_cast(info_class) == 43 /*ProcessImageFileNameWin32*/) + { + remove_evil_keywords_from_string(*static_cast(info)); + } + } + + return status; + } } - + class component final : public component_interface { public: @@ -316,6 +468,22 @@ namespace integrity auto* get_thread_context_func = utils::nt::library("kernelbase.dll").get_proc("GetThreadContext"); get_thread_context_hook.create(get_thread_context_func, get_thread_context_stub); + create_mutex_ex_a_hook.create(CreateMutexExA, create_mutex_ex_a_stub); + + utils::hook::copy(this->window_text_buffer_, GetWindowTextA, sizeof(this->window_text_buffer_)); + utils::hook::jump(GetWindowTextA, get_window_text_a_stub, true, true); + utils::hook::move_hook(GetWindowTextA); + + const utils::nt::library ntdll("ntdll.dll"); + + const auto nt_query_information_process = ntdll.get_proc("NtQueryInformationProcess"); + nt_query_information_process_hook.create(nt_query_information_process, + nt_query_information_process_stub); + + const auto nt_query_system_information = ntdll.get_proc("NtQuerySystemInformation"); + nt_query_system_information_hook.create(nt_query_system_information, nt_query_system_information_stub); + nt_query_system_information_hook.move(); + /************************************************************************************************************* ** TODO : There is some kind of dormant defence mechanism. works so random makes it harder to investigate @@ -335,7 +503,10 @@ namespace integrity { return 9999; } + + private: + uint8_t window_text_buffer_[15]{}; }; } -REGISTER_COMPONENT(integrity::component) \ No newline at end of file +REGISTER_COMPONENT(arxan::component) \ No newline at end of file diff --git a/source/proxy-dll/component/blackbox.cpp b/source/proxy-dll/component/blackbox.cpp index b2c2912..1308f31 100644 --- a/source/proxy-dll/component/blackbox.cpp +++ b/source/proxy-dll/component/blackbox.cpp @@ -1,6 +1,6 @@ #include +#include "definitions/game.hpp" #include "loader/component_loader.hpp" -#include "definitions/t8_engine.hpp" #include #include diff --git a/source/proxy-dll/component/debugging.cpp b/source/proxy-dll/component/debugging.cpp index 757f374..22ec50f 100644 --- a/source/proxy-dll/component/debugging.cpp +++ b/source/proxy-dll/component/debugging.cpp @@ -1,137 +1,59 @@ #include +#include "definitions/game.hpp" +#include "component/scheduler.hpp" #include "loader/component_loader.hpp" -#include "definitions/t8_engine.hpp" -#include "scheduler.hpp" +#include namespace debugging { - typedef short(__fastcall* UI_Model_GetModelForController_t)(int controllerIndex); - UI_Model_GetModelForController_t UI_Model_GetModelForController = (UI_Model_GetModelForController_t)0x143AD0200_g; - - typedef short(__fastcall* UI_Model_CreateModelFromPath_t)(short parentNodeIndex, const char* path); - UI_Model_CreateModelFromPath_t UI_Model_CreateModelFromPath = (UI_Model_CreateModelFromPath_t)0x143ACFC10_g; - - typedef bool(__fastcall* UI_Model_SetString_t)(short nodeIndex, const char* newValue); - UI_Model_SetString_t UI_Model_SetString = (UI_Model_SetString_t)0x143AD18C0_g; - - typedef bool(__fastcall* UI_Model_SetInt_t)(short nodeIndex, int newValue); - UI_Model_SetInt_t UI_Model_SetInt = (UI_Model_SetInt_t)0x143AD1820_g; - - typedef bool(__fastcall* UI_Model_SetBool_t)(short nodeIndex, bool newValue); - UI_Model_SetBool_t UI_Model_SetBool = (UI_Model_SetBool_t)0x143AD1780_g; - - typedef bool(__fastcall* UI_Model_SetReal_t)(short nodeIndex, float newValue); - UI_Model_SetReal_t UI_Model_SetReal = (UI_Model_SetReal_t)0x143AD1870_g; - - void LUI_ShowToast(const char* title, const char* desc, const char* icon) - { - short main_model = UI_Model_GetModelForController(0); - short toast_model = UI_Model_CreateModelFromPath(main_model, "FrontendToast"); - - short sub_model = UI_Model_CreateModelFromPath(toast_model, "state"); - UI_Model_SetString(sub_model, "DefaultState"); - - sub_model = UI_Model_CreateModelFromPath(toast_model, "kicker"); - UI_Model_SetString(sub_model, title); - - sub_model = UI_Model_CreateModelFromPath(toast_model, "description"); - UI_Model_SetString(sub_model, desc); - - sub_model = UI_Model_CreateModelFromPath(toast_model, "contentIcon"); - UI_Model_SetString(sub_model, icon); - - sub_model = UI_Model_CreateModelFromPath(toast_model, "functionIcon"); - UI_Model_SetString(sub_model, "blacktransparent"); - - sub_model = UI_Model_CreateModelFromPath(toast_model, "backgroundId"); - UI_Model_SetInt(sub_model, 0); - - sub_model = UI_Model_CreateModelFromPath(toast_model, "emblemDecal"); - UI_Model_SetReal(sub_model, 0.000000); - - sub_model = UI_Model_CreateModelFromPath(toast_model, "notify"); - UI_Model_SetBool(sub_model, true); - } - namespace { - const char* s_connectivityNames[] = + const char* get_connectivity_info_string(int infoBitmask) { - "user is non-guest", // 0x1 - "connected to live", // 0x2 - "user has multiplayer privs", // 0x4 - "networking initialized", // 0x8 - "connected to demonware", // 0x10 - "lpc ready", // 0x20 - "retrieved ffotd", // 0x40 - "retrieved playlists", // 0x80 - "publisher variables inited", // 0x100 - "ffotd is valid", // 0x200 - "user has stats and loadouts", // 0x400 - "time is synced", // 0x800 - "retrieved geo location", // 0x1000 - "dedicated pings done", // 0x2000 - "dedicated ping responses ok", // 0x4000 - "literally unlisted", // 0x8000 - "unknown - lpc related", // 0x10000 - "inventory fetched", // 0x20000 - "marketing messages received", // 0x40000 - "bnet initialized", // 0x80000 - "achievements fetched" // 0x100000 - }; + char connectionInfoString[64]; - std::string GetConnectivityInfo() + for (int bitNumber = 0; bitNumber < 21; bitNumber++) + { + if ((1 << bitNumber) & infoBitmask) + { + connectionInfoString[bitNumber * 2] = bitNumber + 0x41; + } + else + { + connectionInfoString[bitNumber * 2] = 0x2D; + } + + connectionInfoString[(bitNumber * 2) + 1] = 0x2E; + } + + connectionInfoString[42] = NULL; + + return utils::string::va("%s", connectionInfoString); + } + + void draw_debug_info() { int infoBitmask = 0; int requiredMask = 0x1337FA; game::Live_GetConnectivityInformation(0, &infoBitmask); bool connected = (requiredMask & infoBitmask) == requiredMask; - std::string result{}; - //result.append(std::format("Can play online (controller: {}): {}\n", 0, connected ? "true" : "false")); + void* font = reinterpret_cast(game::sharedUiInfo->assets.bigFont); if (!font) return; - for (int i = 1; i < 21; ++i) + if (!connected) { - if (i == 15) continue; // unlisted bit + float color[4] = { 0.8f, 1.0f, 0.3, 0.8f }; - const char* v13; - const char* v14; - const char* v15; + sz = get_connectivity_info_string(infoBitmask); - if (((1 << i) & infoBitmask) != 0 || (requiredMask & (1 << i)) == 0) - v13 = "^7"; - else - v13 = "^1"; - if ((requiredMask & (1 << i)) != 0) - v14 = "required"; - else - v14 = "optional"; - if (((1 << i) & infoBitmask) != 0) - v15 = "true"; - else - v15 = "false"; + game::ScreenPlacement* scrPlace = game::ScrPlace_GetView(0); - result.append(std::format("{}{}({}) - {}\n", v13, s_connectivityNames[i], v14, v15)); + float offset_x = scrPlace->realViewportSize[0] - 8.0f + - game::UI_TextWidth(0, sz, 0x7FFFFFFF, font, 0.45f); + float offset_y = scrPlace->realViewportSize[1] - 8.0f; + + game::R_AddCmdDrawText(sz, 0x7FFFFFFF, font, offset_x, offset_y, 0.45f, 0.45f, 0.0f, color, game::ITEM_TEXTSTYLE_BORDERED); } - - return result; - } - - void draw_debug_info() - { - static bool should_draw_debugging_info = false; - if (GetAsyncKeyState(VK_INSERT) & 0x01) should_draw_debugging_info ^= 1; - - if (!should_draw_debugging_info) return; - - - float color[4] = { 0.666f, 0.666f, 0.666f, 1.0f }; - game::ScreenPlacement* scrPlace = game::ScrPlace_GetView(0); - void* font = game::UI_GetFontHandle(scrPlace, 0, 1.0f); if (!font) return; - - std::string sz = GetConnectivityInfo(); - game::R_AddCmdDrawText(sz.data(), 0x7FFFFFFF, font, 18.0f, 1.0f * (game::R_TextHeight(font) * 0.45f) + 4.0f, 0.45f, 0.45f, 0.0f, color, game::ITEM_TEXTSTYLE_BORDERED); - } void test_key_catcher() @@ -140,20 +62,21 @@ namespace debugging if ((GetAsyncKeyState(VK_HOME) & 0x01)/* && (static_cast(time(nullptr)) - last_press_time) > 1*/) { last_press_time = static_cast(time(nullptr)); - LUI_ShowToast("Title", "Description", "uie_bookmark"); + + /* ACTION_PLACE_HOLDER */ } } } -class component final : public component_interface -{ -public: - void post_unpack() override - { - scheduler::loop(draw_debug_info, scheduler::renderer); - scheduler::loop(test_key_catcher, scheduler::main); - } -}; + class component final : public component_interface + { + public: + void post_unpack() override + { + scheduler::loop(draw_debug_info, scheduler::renderer); + scheduler::loop(test_key_catcher, scheduler::main); + } + }; } REGISTER_COMPONENT(debugging::component) \ No newline at end of file diff --git a/source/proxy-dll/component/debugging.hpp b/source/proxy-dll/component/debugging.hpp index 35cfb3d..6f70f09 100644 --- a/source/proxy-dll/component/debugging.hpp +++ b/source/proxy-dll/component/debugging.hpp @@ -1,6 +1 @@ #pragma once - -namespace debugging -{ - void LUI_ShowToast(const char* title, const char* desc, const char* icon = "blacktransparent"); -} diff --git a/source/proxy-dll/component/dvars.cpp b/source/proxy-dll/component/dvars.cpp new file mode 100644 index 0000000..ecc9e44 --- /dev/null +++ b/source/proxy-dll/component/dvars.cpp @@ -0,0 +1,289 @@ +#include +#include "dvars.hpp" +#include "scheduler.hpp" +#include "spoofer/spoofcall.hpp" +#include "definitions/variables.hpp" +#include "loader/component_loader.hpp" + +#include + +namespace dvars +{ + namespace + { + void fetch_dvar_pointers() + { + for (auto& dvar : variables::dvars_record) + { + dvar.pointer = spoofcall::invoke(game::Dvar_FindVar, dvar.name.data()); + } + } + + std::string get_vector_string(const int components, const game::DvarLimits& domain) + { + if (domain.vector.min == -FLT_MAX) + { + if (domain.vector.max == FLT_MAX) + { + return utils::string::va("Domain is any %iD vector", components); + } + else + { + return utils::string::va("Domain is any %iD vector with components %g or smaller", components, + domain.vector.max); + } + } + else if (domain.vector.max == FLT_MAX) + { + return utils::string::va("Domain is any %iD vector with components %g or bigger", components, + domain.vector.min); + } + else + { + return utils::string::va("Domain is any %iD vector with components from %g to %g", components, + domain.vector.min, domain.vector.max); + } + } + } + + std::string get_domain_string(const game::dvarType_t type, const game::DvarLimits& domain) + { + std::string str; + + switch (type) + { + case game::DVAR_TYPE_BOOL: + return "Domain is 0 or 1"s; + + case game::DVAR_TYPE_FLOAT: + if (domain.value.min == -FLT_MAX) + { + if (domain.value.max == FLT_MAX) + { + return "Domain is any number"s; + } + else + { + return utils::string::va("Domain is any number %g or smaller", domain.value.max); + } + } + else if (domain.value.max == FLT_MAX) + { + return utils::string::va("Domain is any number %g or bigger", domain.value.min); + } + else + { + return utils::string::va("Domain is any number from %g to %g", domain.value.min, domain.value.max); + } + + case game::DVAR_TYPE_FLOAT_2: + return get_vector_string(2, domain); + + case game::DVAR_TYPE_FLOAT_3: + case game::DVAR_TYPE_LINEAR_COLOR_RGB: + case game::DVAR_TYPE_COLOR_XYZ: + case game::DVAR_TYPE_COLOR_LAB: + return get_vector_string(3, domain); + + case game::DVAR_TYPE_FLOAT_4: + return get_vector_string(4, domain); + + case game::DVAR_TYPE_INT: + if (domain.integer.min == INT_MIN) + { + if (domain.integer.max == INT_MAX) + { + return "Domain is any integer"s; + } + else + { + return utils::string::va("Domain is any integer %i or smaller", domain.integer.max); + } + } + else if (domain.integer.max == INT_MAX) + { + return utils::string::va("Domain is any integer %i or bigger", domain.integer.min); + } + else + { + return utils::string::va("Domain is any integer from %i to %i", domain.integer.min, domain.integer.max); + } + + case game::DVAR_TYPE_ENUM: + str = "Domain is one of the following:"s; + + for (auto string_index = 0; string_index < domain.enumeration.stringCount; ++string_index) + { + str += utils::string::va("\n %2i: %s", string_index, domain.enumeration.strings[string_index]); + } + + return str; + + case game::DVAR_TYPE_STRING: + return "Domain is any text"s; + + case game::DVAR_TYPE_COLOR: + return "Domain is any 4-component color, in RGBA format"s; + + case game::DVAR_TYPE_INT64: + if (domain.integer64.min == _I64_MIN) + { + if (domain.integer64.max == _I64_MAX) + { + return "Domain is any integer"s; + } + else + { + return utils::string::va("Domain is any integer %lli or smaller", domain.integer64.max); + } + } + else if (domain.integer64.max == _I64_MAX) + { + return utils::string::va("Domain is any integer %lli or bigger", domain.integer64.min); + } + else + { + return utils::string::va("Domain is any integer from %lli to %lli", domain.integer64.min, domain.integer64.max); + } + + case game::DVAR_TYPE_UINT64: + if (domain.unsignedInt64.min) + { + if (domain.unsignedInt64.max == _UI64_MAX) + { + return utils::string::va("Domain is any unsigned integer %zu or bigger", domain.unsignedInt64.min); + + } + else + { + return utils::string::va("Domain is any unsigned integer from %zu to %zu", domain.unsignedInt64.min, domain.unsignedInt64.max); + } + } + else if (domain.unsignedInt64.max == _UI64_MAX) + { + return "Domain is any integer"s; + } + else + { + return utils::string::va("Domain is any integer %zu or smaller", domain.unsignedInt64.max); + } + + default: + return utils::string::va("unhandled dvar type '%i'", type); + } + } + + std::string get_value_string(const game::dvar_t * dvar, game::DvarValue * value) + { + std::string result = "N/A"; + + switch (dvar->type) + { + case game::DVAR_TYPE_BOOL: + if (value->naked.enabled) + { + result = "1"s; + } + else + { + result = "0"s; + } + break; + + case game::DVAR_TYPE_FLOAT: + result = std::format("{:.2f}", value->naked.value); + break; + + case game::DVAR_TYPE_FLOAT_2: + result = std::format("{:.2f} {:.2f}", value->naked.vector[0], value->naked.vector[1]); + break; + + case game::DVAR_TYPE_FLOAT_3: + case game::DVAR_TYPE_LINEAR_COLOR_RGB: + case game::DVAR_TYPE_COLOR_XYZ: + case game::DVAR_TYPE_COLOR_LAB: + result = std::format("{:.2f} {:.2f} {:.2f}", value->naked.vector[0], value->naked.vector[1], value->naked.vector[2]); + break; + + case game::DVAR_TYPE_FLOAT_4: + result = std::format("{:.2f} {:.2f} {:.2f} {:.2f}", value->naked.vector[0], value->naked.vector[1], value->naked.vector[2], value->naked.vector[3]); + break; + + case game::DVAR_TYPE_INT: + result = std::format("{}", value->naked.integer); + break; + + case game::DVAR_TYPE_ENUM: + if (dvar->domain.enumeration.stringCount) + { + result = std::string(dvar->domain.enumeration.strings[value->naked.integer]); + } + break; + + case game::DVAR_TYPE_STRING: + result = std::string(value->naked.string); + break; + + case game::DVAR_TYPE_COLOR: + result = std::format("{:.2f} {:.2f} {:.2f} {:.2f}", (float)value->naked.color[0] * 0.0039215689, (float)value->naked.color[1] * 0.0039215689, (float)value->naked.color[2] * 0.0039215689, (float)value->naked.color[3] * 0.0039215689); + break; + + case game::DVAR_TYPE_INT64: + result = std::format("{}", value->naked.integer64); + break; + + case game::DVAR_TYPE_UINT64: + result = std::format("{}", value->naked.unsignedInt64); + break; + + default: + result = "ERROR:DVAR_TYPE_UNKNOWN"s; + break; + } + + return result; + } + + game::dvar_t* find_dvar(uint64_t hashRef) + { + if (hashRef == 0) return NULL; + + auto it = std::find_if(variables::dvars_record.begin(), variables::dvars_record.end(), [&hashRef](variables::varEntry& i) { return i.fnv1a == hashRef; }); + + if (it != variables::dvars_record.end() && it->pointer) + { + return reinterpret_cast(it->pointer); + } + + return spoofcall::invoke(game::Dvar_FindVar_Hash, game::AssetRef(hashRef)); + } + + game::dvar_t* find_dvar(const char* nameRef) + { + return spoofcall::invoke(game::Dvar_FindVar, nameRef); + } + + game::dvar_t* find_dvar(const std::string& nameRef) + { + auto it = std::find_if(variables::dvars_record.begin(), variables::dvars_record.end(), [&nameRef](variables::varEntry& i) { return utils::string::compare(i.name, nameRef); }); + + if (it != variables::dvars_record.end() && it->pointer) + { + return reinterpret_cast(it->pointer); + } + + return spoofcall::invoke(game::Dvar_FindVar, nameRef.data()); + } + + + class component final : public component_interface + { + public: + void post_unpack() override + { + scheduler::once(fetch_dvar_pointers, scheduler::pipeline::main); + } + }; +} + +REGISTER_COMPONENT(dvars::component) diff --git a/source/proxy-dll/component/dvars.hpp b/source/proxy-dll/component/dvars.hpp new file mode 100644 index 0000000..b5d1d46 --- /dev/null +++ b/source/proxy-dll/component/dvars.hpp @@ -0,0 +1,13 @@ +#pragma once +#include "definitions\game.hpp" + +namespace dvars +{ + std::string get_value_string(const game::dvar_t* dvar, game::DvarValue* value); + std::string get_domain_string(const game::dvarType_t type, const game::DvarLimits& domain); + + game::dvar_t* find_dvar(uint64_t hashRef); + game::dvar_t* find_dvar(const char* nameRef); + game::dvar_t* find_dvar(const std::string& nameRef); + +} diff --git a/source/proxy-dll/component/experimental.cpp b/source/proxy-dll/component/experimental.cpp index 8a7f3f7..f09f478 100644 --- a/source/proxy-dll/component/experimental.cpp +++ b/source/proxy-dll/component/experimental.cpp @@ -1,7 +1,8 @@ #include -#include #include "loader/component_loader.hpp" +#include + namespace experimental { namespace diff --git a/source/proxy-dll/component/game_console.cpp b/source/proxy-dll/component/game_console.cpp new file mode 100644 index 0000000..453b71d --- /dev/null +++ b/source/proxy-dll/component/game_console.cpp @@ -0,0 +1,734 @@ +#include +#include "game_console.hpp" +#include "definitions/game.hpp" +#include "definitions/variables.hpp" +#include "loader/component_loader.hpp" + +#include "component/dvars.hpp" +#include "component/scheduler.hpp" + +#include +#include +#include + +#define R_DrawTextFont reinterpret_cast(game::sharedUiInfo->assets.bigFont) +#define R_WhiteMaterial reinterpret_cast(game::sharedUiInfo->assets.whiteMaterial) + +namespace game_console +{ + namespace + { + game::vec4_t con_inputBoxColor = { 0.1f, 0.1f, 0.1f, 0.9f }; + game::vec4_t con_inputHintBoxColor = { 0.1f, 0.1f, 0.1f, 1.0f }; + game::vec4_t con_outputBarColor = { 0.8f, 0.8f, 0.8f, 0.6f }; + game::vec4_t con_outputSliderColor = { 0.8f, 0.8f, 0.8f, 1.0f }; + game::vec4_t con_outputWindowColor = { 0.15f, 0.15f, 0.15f, 0.85f }; + game::vec4_t con_inputWriteDownColor = { 1.0f, 1.0f, 1.0f, 1.0f }; + game::vec4_t con_inputDvarMatchColor = { 0.1f, 0.8f, 0.8f, 1.0f }; + game::vec4_t con_inputDvarInactiveValueColor = { 0.4f, 0.8f, 0.7f, 1.0f }; + game::vec4_t con_inputCmdMatchColor = { 0.9f, 0.6f, 0.2f, 1.0f }; + game::vec4_t con_inputDescriptionColor = { 1.0f, 1.0f, 1.0f, 1.0f }; + game::vec4_t con_inputAltDescriptionColor = { 0.9f, 0.6f, 0.2f, 1.0f }; + game::vec4_t con_inputExtraInfoColor = { 1.0f, 0.5f, 0.5f, 1.0f }; + game::vec4_t con_outputVersionStringColor = { 0.92f, 1.0f, 0.65f, 1.0f }; + + using suggestion_t = variables::varEntry; + using output_queue = std::deque; + + struct ingame_console + { + char buffer[256]{}; + int cursor{}; + float font_scale{}; + float font_height{}; + int max_suggestions{}; + int visible_line_count{}; + float screen_min[2]{}; + float screen_max[2]{}; + struct { + float x{}, y{}; + } screen_pointer; + bool may_auto_complete{}; + char auto_complete_choice[64]{}; + bool output_visible{}; + int display_line_offset{}; + int total_line_count{}; + utils::concurrency::container output{}; + }; + + ingame_console con{}; + + std::int32_t history_index = -1; + std::deque history{}; + + std::string fixed_input{}; + std::vector matches{}; + + void clear_input() + { + strncpy_s(con.buffer, "", sizeof(con.buffer)); + con.cursor = 0; + + fixed_input = ""; + matches.clear(); + } + + void clear_output() + { + con.total_line_count = 0; + con.display_line_offset = 0; + con.output.access([](output_queue& output) + { + output.clear(); + }); + history_index = -1; + history.clear(); + } + + void print_internal(const std::string& data) + { + con.output.access([&](output_queue& output) + { + if (con.visible_line_count > 0 + && con.display_line_offset == (output.size() - con.visible_line_count)) + { + con.display_line_offset++; + } + output.push_back(data); + if (output.size() > 512) + { + output.pop_front(); + } + }); + } + + void toggle_console() + { + clear_input(); + + con.output_visible = false; + *game::keyCatchers ^= 1; + } + + void toggle_console_output() + { + con.output_visible = con.output_visible == 0; + } + + bool is_renderer_ready() + { + return (R_DrawTextFont && R_WhiteMaterial); + } + + void calculate_window_size() + { + con.screen_min[0] = 6.0f; + con.screen_min[1] = 6.0f; + con.screen_max[0] = game::ScrPlace_GetView(0)->realViewportSize[0] - 6.0f; + con.screen_max[1] = game::ScrPlace_GetView(0)->realViewportSize[1] - 6.0f; + + con.font_height = static_cast(game::UI_TextHeight(R_DrawTextFont, con.font_scale)); + con.visible_line_count = static_cast((con.screen_max[1] - con.screen_min[1] - (con.font_height * 2)) - 24.0f) / con.font_height; + } + + void draw_box(const float x, const float y, const float w, const float h, float* color) + { + game::vec4_t outline_color; + + outline_color[0] = color[0] * 0.5f; + outline_color[1] = color[1] * 0.5f; + outline_color[2] = color[2] * 0.5f; + outline_color[3] = color[3]; + + game::R_AddCmdDrawStretchPic(x, y, w, h, 0.0f, 0.0f, 0.0f, 0.0f, color, R_WhiteMaterial); + game::R_AddCmdDrawStretchPic(x, y, 2.0f, h, 0.0f, 0.0f, 0.0f, 0.0f, outline_color, R_WhiteMaterial); + game::R_AddCmdDrawStretchPic((x + w) - 2.0f, y, 2.0f, h, 0.0f, 0.0f, 0.0f, 0.0f, outline_color, R_WhiteMaterial); + game::R_AddCmdDrawStretchPic(x, y, w, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, outline_color, R_WhiteMaterial); + game::R_AddCmdDrawStretchPic(x, (y + h) - 2.0f, w, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, outline_color, R_WhiteMaterial); + } + + void draw_input_box(const int lines, float* color) + { + draw_box( con.screen_pointer.x - 6.0f, con.screen_pointer.y - 6.0f, + (con.screen_max[0] - con.screen_min[0]) - ((con.screen_pointer.x - 6.0f) - con.screen_min[0]), + (lines * con.font_height) + 12.0f, color); + } + + void draw_input_text_and_over(const char* str, float* color) + { + game::R_AddCmdDrawText(str, 0x7FFFFFFF, R_DrawTextFont, con.screen_pointer.x, + con.screen_pointer.y + con.font_height, con.font_scale, con.font_scale, 0.0f, color, 0); + + con.screen_pointer.x = game::UI_TextWidth(0, str, 0x7FFFFFFF, R_DrawTextFont, con.font_scale) + con.screen_pointer.x + 6.0f; + } + + float draw_hint_box(const int lines, float* color, [[maybe_unused]] float offset_x = 0.0f, + [[maybe_unused]] float offset_y = 0.0f) + { + const auto _h = lines * con.font_height + 12.0f; + const auto _y = con.screen_pointer.y - 3.0f + con.font_height + 12.0f + offset_y; + const auto _w = (con.screen_max[0] - con.screen_min[0]) - ((con.screen_pointer.x - 6.0f) - con.screen_min[0]); + + draw_box(con.screen_pointer.x - 6.0f, _y, _w, _h, color); + return _h; + } + + void draw_hint_text(const int line, const char* text, float* color, const float offset_x = 0.0f, const float offset_y = 0.0f) + { + const auto _y = con.font_height + con.screen_pointer.y + (con.font_height * (line + 1)) + 15.0f + offset_y; + + game::R_AddCmdDrawText(text, 0x7FFFFFFF, R_DrawTextFont, con.screen_pointer.x + offset_x, _y, con.font_scale, con.font_scale, 0.0f, color, 0); + } + + void find_matches(const std::string& input, std::vector& suggestions, bool exact) + { + double required_ratio = exact ? 1.00 : 0.01; + + for (const auto& dvar : variables::dvars_record) + { + if (dvars::find_dvar(dvar.fnv1a) && utils::string::match(input, dvar.name) >= required_ratio) + { + suggestions.push_back(dvar); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + if (suggestions.size() == 0 && dvars::find_dvar(input)) + { + suggestions.push_back({ input, "", fnv1a::generate_hash(input.data()), reinterpret_cast(dvars::find_dvar(input)) }); + } + + for (const auto& cmd : variables::commands_record) + { + if (utils::string::match(input, cmd.name) >= required_ratio) + { + suggestions.push_back(cmd); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + } + + void draw_input() + { + con.screen_pointer.x = con.screen_min[0] + 6.0f; + con.screen_pointer.y = con.screen_min[1] + 6.0f; + + draw_input_box(1, con_inputBoxColor); + draw_input_text_and_over("PROJECT-BO4 >", con_inputWriteDownColor); + + con.auto_complete_choice[0] = 0; + + game::R_AddCmdDrawTextWithCursor(con.buffer, 0x7FFFFFFF, R_DrawTextFont, con.screen_pointer.x, con.screen_pointer.y + con.font_height, con.font_scale, con.font_scale, 0, con_inputWriteDownColor, 0, con.cursor, '|'); + + // check if using a prefixed '/' or not + const auto input = con.buffer[1] && (con.buffer[0] == '/' || con.buffer[0] == '\\') + ? std::string(con.buffer).substr(1) : std::string(con.buffer); + + if (!input.length()) + { + return; + } + + if (input != fixed_input) + { + matches.clear(); + + if (input.find(" ") != std::string::npos) + { + find_matches(input.substr(0, input.find(" ")), matches, true); + } + else + { + find_matches(input, matches, false); + + if (matches.size() <= con.max_suggestions) + { + std::sort(matches.begin(), matches.end(), [&input](suggestion_t& lhs, suggestion_t& rhs) { + return utils::string::match(input, lhs.name) > utils::string::match(input, rhs.name); + }); + } + + } + + fixed_input = input; + } + + con.may_auto_complete = false; + + if (matches.size() > con.max_suggestions) + { + draw_hint_box(1, con_inputHintBoxColor); + draw_hint_text(0, utils::string::va("%i matches (too many to show here)", matches.size()), con_inputDvarMatchColor); + } + else if (matches.size() == 1) + { + auto* dvar = dvars::find_dvar(matches[0].fnv1a); + auto line_count = dvar ? 3 : 1; + + auto height = draw_hint_box(line_count, con_inputHintBoxColor); + draw_hint_text(0, matches[0].name.data(), dvar ? con_inputDvarMatchColor : con_inputCmdMatchColor); + + if (dvar) + { + auto offset_x = (con.screen_max[0] - con.screen_pointer.x) / 4.f; + + draw_hint_text(0, dvars::get_value_string(dvar, &dvar->value->current).data(), con_inputDvarMatchColor, offset_x); + draw_hint_text(1, " default", con_inputDvarInactiveValueColor); + draw_hint_text(1, dvars::get_value_string(dvar, &dvar->value->reset).data(), con_inputDvarInactiveValueColor, offset_x); + draw_hint_text(2, matches[0].desc, con_inputDescriptionColor, 0); + + auto offset_y = height + 3.f; + auto domain_lines = 1; + if (dvar->type == game::DVAR_TYPE_ENUM) + domain_lines = dvar->domain.enumeration.stringCount + 1; + + draw_hint_box(domain_lines, con_inputHintBoxColor, 0, offset_y); + draw_hint_text(0, dvars::get_domain_string(dvar->type, dvar->domain).data(), con_inputAltDescriptionColor, 0, offset_y); + } + else + { + auto offset_x = (con.screen_max[0] - con.screen_pointer.x) / 4.f; + + draw_hint_text(0, matches[0].desc, con_inputCmdMatchColor, offset_x); + } + + strncpy_s(con.auto_complete_choice, matches[0].name.data(), 64); + con.may_auto_complete = true; + } + else if (matches.size() > 1) + { + draw_hint_box(static_cast(matches.size()), con_inputHintBoxColor); + + auto offset_x = (con.screen_max[0] - con.screen_pointer.x) / 4.f; + + for (size_t i = 0; i < matches.size(); i++) + { + auto* const dvar = dvars::find_dvar(matches[i].fnv1a); + + draw_hint_text(static_cast(i), matches[i].name.data(), dvar ? con_inputDvarMatchColor : con_inputCmdMatchColor); + draw_hint_text(static_cast(i), matches[i].desc, dvar ? con_inputDvarMatchColor : con_inputCmdMatchColor, offset_x * 1.5f); + + if (dvar) + { + draw_hint_text(static_cast(i), dvars::get_value_string(dvar, &dvar->value->current).data(), con_inputDvarMatchColor, offset_x); + } + } + + strncpy_s(con.auto_complete_choice, matches[0].name.data(), 64); + con.may_auto_complete = true; + } + } + + void draw_output_scrollbar(const float x, float y, const float width, const float height, output_queue& output) + { + auto _x = (x + width) - 10.0f; + draw_box(_x, y, 10.0f, height, con_outputBarColor); + + auto _height = height; + if (output.size() > con.visible_line_count) + { + auto percentage = static_cast(con.visible_line_count) / output.size(); + _height *= percentage; + + auto remainingSpace = height - _height; + auto percentageAbove = static_cast(con.display_line_offset) / (output.size() - con.visible_line_count); + + y = y + (remainingSpace * percentageAbove); + } + + draw_box(_x, y, 10.0f, _height, con_outputSliderColor); + } + + void draw_output_text(const float x, float y, output_queue& output) + { + auto offset = output.size() >= con.visible_line_count ? 0.0f : (con.font_height * (con.visible_line_count - output.size())); + + for (auto i = 0; i < con.visible_line_count; i++) + { + auto index = i + con.display_line_offset; + if (index >= output.size()) + { + break; + } + + game::R_AddCmdDrawText(output.at(index).data(), 0x400, R_DrawTextFont, x, y + offset + ((i + 1) * con.font_height), con.font_scale, con.font_scale, 0.0f, con_inputWriteDownColor, 0); + } + } + + void draw_output_window() + { + con.output.access([](output_queue& output) + { + draw_box(con.screen_min[0], con.screen_min[1] + 32.0f, con.screen_max[0] - con.screen_min[0], (con.screen_max[1] - con.screen_min[1]) - 32.0f, con_outputWindowColor); + + auto x = con.screen_min[0] + 6.0f; + auto y = (con.screen_min[1] + 32.0f) + 6.0f; + auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f; + auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f; + + game::R_AddCmdDrawText(game::version_string.data(), 0x7FFFFFFF, R_DrawTextFont, x, ((height - 16.0f) + y) + con.font_height, con.font_scale, con.font_scale, 0.0f, con_outputVersionStringColor, 0); + + draw_output_scrollbar(x, y, width, height, output); + draw_output_text(x, y, output); + }); + } + + void draw_console() + { + if (!is_renderer_ready()) return; + + calculate_window_size(); + + if (*game::keyCatchers & 1) + { + if (!(*game::keyCatchers & 1)) + { + con.output_visible = false; + } + + if (con.output_visible) + { + draw_output_window(); + } + + draw_input(); + } + } + } + + void print(const char* fmt, ...) + { + char va_buffer[0x200] = { 0 }; + + va_list ap; + va_start(ap, fmt); + vsprintf_s(va_buffer, fmt, ap); + va_end(ap); + + const auto formatted = std::string(va_buffer); + const auto lines = utils::string::split(formatted, '\n'); + + for (const auto& line : lines) + { + print_internal(line); + } + } + + void print(const std::string& data) + { + const auto lines = utils::string::split(data, '\n'); + for (const auto& line : lines) + { + print_internal(line); + } + } + + + bool console_char_event(const int local_client_num, const int key) + { + if (key == game::keyNum_t::K_GRAVE || + key == game::keyNum_t::K_TILDE || + key == '|' || + key == '\\') + { + return false; + } + + if (key > 127) + { + return true; + } + + if (*game::keyCatchers & 1) + { + if (key == game::keyNum_t::K_TAB) // tab (auto complete) + { + if (con.may_auto_complete) + { + const auto first_char = con.buffer[0]; + + clear_input(); + + if (first_char == '\\' || first_char == '/') + { + con.buffer[0] = first_char; + con.buffer[1] = '\0'; + } + + strncat_s(con.buffer, con.auto_complete_choice, 64); + con.cursor = static_cast(std::string(con.buffer).length()); + + if (con.cursor != 254) + { + con.buffer[con.cursor++] = ' '; + con.buffer[con.cursor] = '\0'; + } + } + } + + if (key == 'v' - 'a' + 1) // paste + { + const auto clipboard = utils::string::get_clipboard_data(); + if (clipboard.empty()) + { + return false; + } + + for (size_t i = 0; i < clipboard.length(); i++) + { + console_char_event(local_client_num, clipboard[i]); + } + + return false; + } + + if (key == 'c' - 'a' + 1) // clear + { + clear_input(); + con.total_line_count = 0; + con.display_line_offset = 0; + con.output.access([](output_queue& output) + { + output.clear(); + }); + history_index = -1; + history.clear(); + + return false; + } + + if (key == 'h' - 'a' + 1) // backspace + { + if (con.cursor > 0) + { + memmove(con.buffer + con.cursor - 1, con.buffer + con.cursor, + strlen(con.buffer) + 1 - con.cursor); + con.cursor--; + } + + return false; + } + + if (key < 32) + { + return false; + } + + if (con.cursor == 256 - 1) + { + return false; + } + + memmove(con.buffer + con.cursor + 1, con.buffer + con.cursor, strlen(con.buffer) + 1 - con.cursor); + con.buffer[con.cursor] = static_cast(key); + con.cursor++; + + if (con.cursor == strlen(con.buffer) + 1) + { + con.buffer[con.cursor] = 0; + } + } + + return true; + } + + bool console_key_event(const int local_client_num, const int key, const int down) + { + if (key == game::keyNum_t::K_GRAVE || key == game::keyNum_t::K_TILDE) + { + if (!down) + { + return false; + } + + const auto shift_down = game::playerKeys[local_client_num].keys[game::keyNum_t::K_LSHIFT].down; + if (shift_down) + { + if (!(*game::keyCatchers & 1)) + { + toggle_console(); + } + + toggle_console_output(); + return false; + } + + toggle_console(); + + return false; + } + + if (*game::keyCatchers & 1) + { + if (down) + { + if (key == game::keyNum_t::K_UPARROW) + { + if (++history_index >= history.size()) + { + history_index = static_cast(history.size()) - 1; + } + + clear_input(); + + if (history_index != -1) + { + strncpy_s(con.buffer, history.at(history_index).c_str(), 0x100); + con.cursor = static_cast(strlen(con.buffer)); + } + } + else if (key == game::keyNum_t::K_DOWNARROW) + { + if (--history_index < -1) + { + history_index = -1; + } + + clear_input(); + + if (history_index != -1) + { + strncpy_s(con.buffer, history.at(history_index).c_str(), 0x100); + con.cursor = static_cast(strlen(con.buffer)); + } + } + + if (key == game::keyNum_t::K_RIGHTARROW) + { + if (con.cursor < strlen(con.buffer)) + { + con.cursor++; + } + + return false; + } + + if (key == game::keyNum_t::K_LEFTARROW) + { + if (con.cursor > 0) + { + con.cursor--; + } + + return false; + } + + //scroll through output + if (key == game::keyNum_t::K_MWHEELUP || key == game::keyNum_t::K_PGUP) + { + con.output.access([](output_queue& output) + { + if (output.size() > con.visible_line_count && con.display_line_offset > 0) + { + con.display_line_offset--; + } + }); + } + else if (key == game::keyNum_t::K_MWHEELDOWN || key == game::keyNum_t::K_PGDN) + { + con.output.access([](output_queue& output) + { + if (output.size() > con.visible_line_count + && con.display_line_offset < (output.size() - con.visible_line_count)) + { + con.display_line_offset++; + } + }); + } + + if (key == game::keyNum_t::K_ENTER) + { + //game::Cbuf_AddText(0, utils::string::va("%s \n", fixed_input.data())); + + if (history_index != -1) + { + const auto itr = history.begin() + history_index; + + if (*itr == con.buffer) + { + history.erase(history.begin() + history_index); + } + } + + history.push_front(con.buffer); + + print("]%s\n", con.buffer); + game::Cbuf_AddText(0, utils::string::va("%s \n", fixed_input.data())); + + if (history.size() > 10) + { + history.erase(history.begin() + 10); + } + + history_index = -1; + + clear_input(); + } + } + } + + return true; + } + + utils::hook::detour cl_key_event_hook; + void cl_key_event_stub(int localClientNum, int key, bool down, unsigned int time) + { + if (!game_console::console_key_event(localClientNum, key, down)) + { + return; + } + + cl_key_event_hook.invoke(localClientNum, key, down, time); + } + + utils::hook::detour cl_char_event_hook; + void cl_char_event_stub(const int localClientNum, const int key, bool isRepeated) + { + if (!game_console::console_char_event(localClientNum, key)) + { + return; + } + + cl_char_event_hook.invoke(localClientNum, key, isRepeated); + } + + + class component final : public component_interface + { + public: + void post_unpack() override + { + scheduler::loop(draw_console, scheduler::renderer); + + cl_key_event_hook.create(0x142839250_g, cl_key_event_stub); + cl_char_event_hook.create(0x142836F80_g, cl_char_event_stub); + + + // initialize our structs + con.cursor = 0; + con.visible_line_count = 0; + con.output_visible = false; + con.display_line_offset = 0; + con.total_line_count = 0; + strncpy_s(con.buffer, "", 256); + + con.screen_pointer.x = 0.0f; + con.screen_pointer.y = 0.0f; + con.may_auto_complete = false; + strncpy_s(con.auto_complete_choice, "", 64); + + con.font_scale = 0.38f; + con.max_suggestions = 24; + } + }; +} + +REGISTER_COMPONENT(game_console::component) \ No newline at end of file diff --git a/source/proxy-dll/component/game_console.hpp b/source/proxy-dll/component/game_console.hpp new file mode 100644 index 0000000..4a2214b --- /dev/null +++ b/source/proxy-dll/component/game_console.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace game_console +{ + void print(const char* fmt, ...); + void print(const std::string& data); +} \ No newline at end of file diff --git a/source/proxy-dll/component/logger.cpp b/source/proxy-dll/component/logger.cpp index 93b0aa1..57ff36d 100644 --- a/source/proxy-dll/component/logger.cpp +++ b/source/proxy-dll/component/logger.cpp @@ -1,10 +1,12 @@ #include #include "logger.hpp" +#include "game_console.hpp" #include "loader/component_loader.hpp" + #include #define OUTPUT_DEBUG_API -#define PREPEND_TIMESTAMP +#define OUTPUT_GAME_CONSOLE namespace logger { @@ -22,20 +24,25 @@ namespace logger if (type == LOG_TYPE_DEBUG) return; #endif // _DEBUG + std::stringstream ss; + ss << "[ " << LogTypeNames[type] << " ] " << str << std::endl; + + std::string text = ss.str(); + +#ifdef OUTPUT_GAME_CONSOLE + game_console::print(text); +#endif // OUTPUT_GAME_CONSOLE + #ifdef OUTPUT_DEBUG_API - OutputDebugStringA(str.c_str()); + OutputDebugStringA(text.c_str()); #endif // OUTPUT_DEBUG_API - std::ofstream stream; - stream.open("project-bo4.log", std::ios_base::app); + std::ofstream fs; + fs.open("project-bo4.log", std::ios_base::app); -#ifdef PREPEND_TIMESTAMP time_t now = time(0); std::tm* t = std::localtime(&now); - stream << "" << std::put_time(t, "%Y-%m-%d %H:%M:%S") << "\t"; -#endif // PREPEND_TIMESTAMP - - stream << "[ " << LogTypeNames[type] << " ] " << str << std::endl; + fs << "" << std::put_time(t, "%Y-%m-%d %H:%M:%S") << "\t" << text; } void write(const int type, const char* fmt, ...) @@ -51,11 +58,6 @@ namespace logger write(type, formatted); } - namespace - { - /* PLACE_HOLDER */ - } - class component final : public component_interface { public: @@ -65,9 +67,9 @@ namespace logger utils::io::remove_file("project-bo4.log"); #endif // REMOVE_PREVIOUS_LOG - write(LOG_TYPE_INFO, "======================================================================================================="); - write(LOG_TYPE_INFO, " Project-BO4 Initializing ... %s[0x%llX]", utils::nt::library{}.get_name().c_str(), utils::nt::library{}.get_ptr()); - write(LOG_TYPE_INFO, "======================================================================================================="); + write(LOG_TYPE_INFO, "======================================================================================================="); + write(LOG_TYPE_INFO, " Project-BO4 Initializing ... %s[0x%llX]", utils::nt::library{}.get_name().c_str(), utils::nt::library{}.get_ptr()); + write(LOG_TYPE_INFO, "======================================================================================================="); } void post_unpack() override diff --git a/source/proxy-dll/component/platform.cpp b/source/proxy-dll/component/platform.cpp index 81bae6d..cf0f08d 100644 --- a/source/proxy-dll/component/platform.cpp +++ b/source/proxy-dll/component/platform.cpp @@ -1,13 +1,14 @@ #include #include "platform.hpp" +#include "definitions/game.hpp" #include "loader/component_loader.hpp" + #include #include #include #include #include -#include "WinReg.hpp" -#include "definitions/t8_engine.hpp" +#include namespace platform { diff --git a/source/proxy-dll/component/scheduler.cpp b/source/proxy-dll/component/scheduler.cpp index f1435e7..407506e 100644 --- a/source/proxy-dll/component/scheduler.cpp +++ b/source/proxy-dll/component/scheduler.cpp @@ -1,7 +1,6 @@ #include -#include "loader/component_loader.hpp" - #include "scheduler.hpp" +#include "loader/component_loader.hpp" #include #include @@ -166,7 +165,7 @@ namespace scheduler void post_unpack() override { r_end_frame_hook.create(0x14361E260_g, r_end_frame_stub); // R_EndFrame - //main_frame_hook.create(0x14288BAE0_g, main_frame_stub); // Com_Frame + main_frame_hook.create(0x14288BAE0_g, main_frame_stub); // Com_Frame //g_run_frame_hook.create(0x142D08FC0_g, server_frame_stub); // G_RunFrame } diff --git a/source/proxy-dll/component/splash.cpp b/source/proxy-dll/component/splash.cpp index 1be0213..3cd99ec 100644 --- a/source/proxy-dll/component/splash.cpp +++ b/source/proxy-dll/component/splash.cpp @@ -1,7 +1,7 @@ #include +#include "splash.hpp" #include "loader/component_loader.hpp" -#include "splash.hpp" #include "resource.hpp" #include diff --git a/source/proxy-dll/definitions/discovery.cpp b/source/proxy-dll/definitions/discovery.cpp index edf480b..893205c 100644 --- a/source/proxy-dll/definitions/discovery.cpp +++ b/source/proxy-dll/definitions/discovery.cpp @@ -1,6 +1,7 @@ #include -#include "definitions\discovery.hpp" +#include "discovery.hpp" #include "loader/component_loader.hpp" + #include #include diff --git a/source/proxy-dll/definitions/t8_engine.cpp b/source/proxy-dll/definitions/game.cpp similarity index 97% rename from source/proxy-dll/definitions/t8_engine.cpp rename to source/proxy-dll/definitions/game.cpp index d295e16..d0970b7 100644 --- a/source/proxy-dll/definitions/t8_engine.cpp +++ b/source/proxy-dll/definitions/game.cpp @@ -1,5 +1,5 @@ #include -#include "definitions\t8_engine.hpp" +#include "game.hpp" #include "loader/component_loader.hpp" namespace game diff --git a/source/proxy-dll/definitions/game.hpp b/source/proxy-dll/definitions/game.hpp new file mode 100644 index 0000000..3bf967f --- /dev/null +++ b/source/proxy-dll/definitions/game.hpp @@ -0,0 +1,507 @@ +#pragma once + +#include "definitions\discovery.hpp" + +#define WEAK __declspec(selectany) + +namespace game +{ + ////////////////////////////////////////////////////////////////////////// + // VARIABLES // + ////////////////////////////////////////////////////////////////////////// + + extern std::string version_string; + + typedef float vec_t; + typedef vec_t vec2_t[2]; + typedef vec_t vec3_t[3]; + typedef vec_t vec4_t[4]; + + + ////////////////////////////////////////////////////////////////////////// + // STRUCTS // + ////////////////////////////////////////////////////////////////////////// + + struct BO4_AssetRef_t + { + __int64 hash; + __int64 null; + }; + + inline BO4_AssetRef_t + AssetRef(uint64_t hashRef) + { + BO4_AssetRef_t m128i; + m128i.hash = hashRef; + + return m128i; + } + + enum keyNum_t + { + K_NONE = 0x00, + K_BUTTON_A = 0x01, + K_BUTTON_B = 0x02, + K_BUTTON_X = 0x03, + K_BUTTON_Y = 0x04, + K_BUTTON_LSHLDR = 0x05, + K_BUTTON_RSHLDR = 0x06, + K_UNK7 = 0x07, + K_UNK8 = 0x08, + K_TAB = 0x09, + K_UNK10 = 0x0A, + K_UNK11 = 0x0B, + K_UNK12 = 0x0C, + K_ENTER = 0x0D, + K_BUTTON_START = 0x0E, + K_BUTTON_BACK = 0x0F, + K_BUTTON_LSTICK = 0x10, + K_BUTTON_RSTICK = 0x11, + K_BUTTON_LTRIG = 0x12, + K_BUTTON_RTRIG = 0x13, + K_UNK20 = 0x14, + K_UNK21 = 0x15, + K_DPAD_UP = 0x16, + K_DPAD_DOWN = 0x17, + K_DPAD_LEFT = 0x18, + K_DPAD_RIGHT = 0x19, + K_UNK26 = 0x1A, + K_ESCAPE = 0x1B, + K_APAD_UP = 0x1C, + K_APAD_DOWN = 0x1D, + K_APAD_LEFT = 0x1E, + K_APAD_RIGHT = 0x1F, + K_SPACE = 0x20, + K_UNK33 = 0x21, + K_UNK34 = 0x22, + K_UNK35 = 0x23, + K_UNK36 = 0x24, + K_UNK37 = 0x25, + K_UNK38 = 0x26, + K_UNK39 = 0x27, + K_UNK40 = 0x28, + K_UNK41 = 0x29, + K_UNK42 = 0x2A, + K_UNK43 = 0x2B, + K_UNK44 = 0x2C, + K_UNK45 = 0x2D, + K_UNK46 = 0x2E, + K_UNK47 = 0x2F, + K_UNK48 = 0x30, + K_UNK49 = 0x31, + K_UNK50 = 0x32, + K_UNK51 = 0x33, + K_UNK52 = 0x34, + K_UNK53 = 0x35, + K_UNK54 = 0x36, + K_UNK55 = 0x37, + K_UNK56 = 0x38, + K_UNK57 = 0x39, + K_UNK58 = 0x3A, + K_SEMICOLON = 0x3B, + K_UNK60 = 0x3C, + K_UNK61 = 0x3D, + K_UNK62 = 0x3E, + K_UNK63 = 0x3F, + K_UNK64 = 0x40, + K_UNK65 = 0x41, + K_UNK66 = 0x42, + K_UNK67 = 0x43, + K_UNK68 = 0x44, + K_UNK69 = 0x45, + K_UNK70 = 0x46, + K_UNK71 = 0x47, + K_UNK72 = 0x48, + K_UNK73 = 0x49, + K_UNK74 = 0x4A, + K_UNK75 = 0x4B, + K_UNK76 = 0x4C, + K_UNK77 = 0x4D, + K_UNK78 = 0x4E, + K_UNK79 = 0x4F, + K_UNK80 = 0x50, + K_UNK81 = 0x51, + K_UNK82 = 0x52, + K_UNK83 = 0x53, + K_UNK84 = 0x54, + K_UNK85 = 0x55, + K_UNK86 = 0x56, + K_UNK87 = 0x57, + K_UNK88 = 0x58, + K_UNK89 = 0x59, + K_UNK90 = 0x5A, + K_UNK91 = 0x5B, + K_UNK92 = 0x5C, + K_UNK93 = 0x5D, + K_UNK94 = 0x5E, + K_UNK95 = 0x5F, + K_GRAVE = 0x60, + K_UNK97 = 0x61, + K_UNK98 = 0x62, + K_UNK99 = 0x63, + K_UNK100 = 0x64, + K_UNK101 = 0x65, + K_UNK102 = 0x66, + K_UNK103 = 0x67, + K_UNK104 = 0x68, + K_UNK105 = 0x69, + K_UNK106 = 0x6A, + K_UNK107 = 0x6B, + K_UNK108 = 0x6C, + K_UNK109 = 0x6D, + K_UNK110 = 0x6E, + K_UNK111 = 0x6F, + K_UNK112 = 0x70, + K_UNK113 = 0x71, + K_UNK114 = 0x72, + K_UNK115 = 0x73, + K_UNK116 = 0x74, + K_UNK117 = 0x75, + K_UNK118 = 0x76, + K_UNK119 = 0x77, + K_UNK120 = 0x78, + K_UNK121 = 0x79, + K_UNK122 = 0x7A, + K_UNK123 = 0x7B, + K_UNK124 = 0x7C, + K_UNK125 = 0x7D, + K_TILDE = 0x7E, + K_BACKSPACE = 0x7F, + K_CAPSLOCK = 0x80, + K_PAUSE = 0x81, + K_PRINTSCREEN = 0x82, + K_SCROLLLOCK = 0x83, + K_UPARROW = 0x84, + K_DOWNARROW = 0x85, + K_LEFTARROW = 0x86, + K_RIGHTARROW = 0x87, + K_LALT = 0x88, + K_RALT = 0x89, + K_LCTRL = 0x8A, + K_RCTRL = 0x8B, + K_LSHIFT = 0x8C, + K_RSHIFT = 0x8D, + K_HIRAGANA = 0x8E, + K_HENKAN = 0x8F, + K_MUHENKAN = 0x90, + K_LWIN = 0x91, + K_RWIN = 0x92, + K_MENU = 0x93, + K_INS = 0x94, + K_DEL = 0x95, + K_PGDN = 0x96, + K_PGUP = 0x97, + K_HOME = 0x98, + K_END = 0x99, + K_F1 = 0x9A, + K_F2 = 0x9B, + K_F3 = 0x9C, + K_F4 = 0x9D, + K_F5 = 0x9E, + K_F6 = 0x9F, + K_F7 = 0xA0, + K_F8 = 0xA1, + K_F9 = 0xA2, + K_F10 = 0xA3, + K_F11 = 0xA4, + K_F12 = 0xA5, + K_UNK166 = 0xA6, + K_UNK167 = 0xA7, + K_UNK168 = 0xA8, + K_KP_HOME = 0xA9, + K_KP_UPARROW = 0xAA, + K_KP_PGUP = 0xAB, + K_KP_LEFTARROW = 0xAC, + K_KP_5 = 0xAD, + K_KP_RIGHTARROW = 0xAE, + K_KP_END = 0xAF, + K_KP_DOWNARROW = 0xB0, + K_KP_PGDN = 0xB1, + K_KP_ENTER = 0xB2, + K_KP_INS = 0xB3, + K_KP_DEL = 0xB4, + K_KP_SLASH = 0xB5, + K_KP_MINUS = 0xB6, + K_KP_PLUS = 0xB7, + K_KP_NUMLOCK = 0xB8, + K_KP_STAR = 0xB9, + K_MOUSE1 = 0xBA, + K_MOUSE2 = 0xBB, + K_MOUSE3 = 0xBC, + K_MOUSE4 = 0xBD, + K_MOUSE5 = 0xBE, + K_MWHEELDOWN = 0xBF, + K_MWHEELUP = 0xC0 + }; + + struct KeyState + { + int down; + int repeats; + int binding; + char pad[20]; + }; // size = 32 + + struct PlayerKeyState + { + bool overstrikeMode; + int anyKeyDown; + KeyState keys[256]; + }; + + struct AssetCache + { + uintptr_t whiteMaterial; + uintptr_t cursor; + uintptr_t blur; + uintptr_t devFont; // TTF + uintptr_t defaultFont; // TTF + uintptr_t bigFont; + uintptr_t smallFont; + uintptr_t consoleFont; + uintptr_t boldFont; + uintptr_t textFont; + uintptr_t extraBigFont; + uintptr_t extraSmallFont; + uintptr_t fxFont; + }; + + struct sharedUiInfo_t + { + AssetCache assets; + }; + + struct ScreenPlacement + { + vec2_t scaleVirtualToReal; + vec2_t scaleVirtualToFull; + vec2_t scaleRealToVirtual; + vec2_t virtualViewableMin; + vec2_t virtualViewableMax; + vec2_t virtualTweakableMin; + vec2_t virtualTweakableMax; + vec2_t realViewportBase; + vec2_t realViewportSize; + vec2_t realViewportMid; + vec2_t realViewableMin; + vec2_t realViewableMax; + vec2_t realTweakableMin; + vec2_t realTweakableMax; + vec2_t subScreen; + float hudSplitscreenScale; + }; + + enum itemTextStyle + { + ITEM_TEXTSTYLE_NORMAL = 0, + ITEM_TEXTSTYLE_SHADOWED = 3, + ITEM_TEXTSTYLE_SHADOWEDMORE = 6, + ITEM_TEXTSTYLE_BORDERED = 7, + ITEM_TEXTSTYLE_BORDEREDMORE = 8, + ITEM_TEXTSTYLE_MONOSPACE = 128, + ITEM_TEXTSTYLE_MONOSPACESHADOWED = 132, + }; + + enum errorParm + { + ERR_FATAL = 0, + ERR_DROP = 1, + ERR_SERVERDISCONNECT = 2, + ERR_DISCONNECT = 3, + ERR_SCRIPT = 4, + ERR_SCRIPT_DROP = 5, + ERR_LOCALIZATION = 6, + ERR_MAPLOADERRORSUMMARY = 7, + }; + + enum dvarType_t + { + DVAR_TYPE_INVALID = 0x0, + DVAR_TYPE_BOOL = 0x1, + DVAR_TYPE_FLOAT = 0x2, + DVAR_TYPE_FLOAT_2 = 0x3, + DVAR_TYPE_FLOAT_3 = 0x4, + DVAR_TYPE_FLOAT_4 = 0x5, + DVAR_TYPE_INT = 0x6, + DVAR_TYPE_ENUM = 0x7, + DVAR_TYPE_STRING = 0x8, + DVAR_TYPE_COLOR = 0x9, + DVAR_TYPE_INT64 = 0xA, + DVAR_TYPE_UINT64 = 0xB, + DVAR_TYPE_LINEAR_COLOR_RGB = 0xC, + DVAR_TYPE_COLOR_XYZ = 0xD, + DVAR_TYPE_COLOR_LAB = 0xE, + DVAR_TYPE_SESSIONMODE_BASE_DVAR = 0xF, + DVAR_TYPE_COUNT = 0x10, + }; + + enum dvarFlags_e + { + DVAR_NONE = 0, + DVAR_ARCHIVE = 1 << 0, + DVAR_USERINFO = 1 << 1, + DVAR_SERVERINFO = 1 << 2, + DVAR_SYSTEMINFO = 1 << 3, + DVAR_LATCH = 1 << 4, + DVAR_ROM = 1 << 5, + DVAR_SAVED = 1 << 6, + DVAR_INIT = 1 << 7, + DVAR_CHEAT = 1 << 8, + //DVAR_UNKNOWN = 1 << 9, + DVAR_EXTERNAL = 1 << 10, + //DVAR_UNKNOWN3x = 1 << 11-13, + DVAR_SESSIONMODE = 1 << 15 + }; + + union DvarLimits + { + struct + { + int stringCount; + const char** strings; + } enumeration; + + struct + { + int min; + int max; + } integer; + + struct + { + int64_t min; + int64_t max; + } integer64; + + struct + { + uint64_t min; + uint64_t max; + } unsignedInt64; + + struct + { + float min; + float max; + } value; + + struct + { + vec_t min; + vec_t max; + } vector; + }; + + struct dvar_t; + + struct DvarValue + { + union + { + bool enabled; + int integer; + uint32_t unsignedInt; + int64_t integer64; + uint64_t unsignedInt64; + float value; + vec4_t vector; + const char* string; + byte color[4]; + const dvar_t* indirect[3]; + } naked; + + uint64_t encrypted; + }; + + struct DvarData + { + DvarValue current; + DvarValue latched; + DvarValue reset; + }; + + struct dvar_t + { + BO4_AssetRef_t name; + char padding_unk1[8]; + DvarData* value; + dvarType_t type; + unsigned int flags; + DvarLimits domain; + char padding_unk2[8]; + }; + + ////////////////////////////////////////////////////////////////////////// + // SYMBOLS // + ////////////////////////////////////////////////////////////////////////// + + template + class symbol + { + public: + symbol(const size_t address) + : address_(reinterpret_cast(address)) + { + } + + T* get() const + { + return address_; + } + + operator T* () const + { + return this->get(); + } + + T* operator->() const + { + return this->get(); + } + + private: + T* address_; + }; + + // Main Functions + WEAK symbol Com_Error_{ 0x14288B410_g }; + + // CMD + WEAK symbol Cbuf_AddText{ 0x143CDE880_g }; + + // Dvar + WEAK symbol Dvar_FindVar{ 0x143CEBE40_g }; + WEAK symbol Dvar_FindVar_Hash{ 0x143CEBED0_g }; + + // Live Functions + WEAK symbol Live_GetConnectivityInformation{ 0x1437FA460_g }; + + // Rendering Functions + WEAK symbol T8_AddBaseDrawTextCmd{ 0x143616B60_g }; + WEAK symbol R_AddCmdDrawStretchPic{ 0x143616790_g }; + + WEAK symbol R_TextHeight{ 0x1435B2350_g }; + WEAK symbol UI_TextHeight{ 0x143CD6560_g }; + + WEAK symbol R_TextWidth{ 0x1435B2530_g }; + WEAK symbol UI_TextWidth{ 0x143CD65B0_g }; + + WEAK symbol ScrPlace_GetView{ 0x142876E70_g }; + + WEAK symbol Com_IsInGame{ 0x14288FDB0_g }; + + WEAK symbol keyCatchers{ 0x148A53F84_g }; + WEAK symbol playerKeys{ 0x148A3EF80_g }; + + WEAK symbol sharedUiInfo{ 0x14F956850_g }; + + +#define R_AddCmdDrawText(TXT, MC, F, X, Y, XS, YS, R, C, S) \ + T8_AddBaseDrawTextCmd(TXT, MC, F, X, Y, XS, YS, R, C, S, -1, 0, 0) + +#define R_AddCmdDrawTextWithCursor(TXT, MC, F, X, Y, XS, YS, R, C, S, CP, CC) \ + T8_AddBaseDrawTextCmd(TXT, MC, F, X, Y, XS, YS, R, C, S, CP, CC, 0) + +#define Com_Error(code, fmt, ...) \ + Com_Error_(__FILE__, __LINE__, code, fmt, ##__VA_ARGS__) +} \ No newline at end of file diff --git a/source/proxy-dll/definitions/t8_engine.hpp b/source/proxy-dll/definitions/t8_engine.hpp deleted file mode 100644 index ae66394..0000000 --- a/source/proxy-dll/definitions/t8_engine.hpp +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include "definitions\discovery.hpp" - -#define WEAK __declspec(selectany) - -namespace game -{ - extern std::string version_string; - - typedef float vec_t; - typedef vec_t vec2_t[2]; - typedef vec_t vec3_t[3]; - typedef vec_t vec4_t[4]; - - struct T8_Hash_t - { - int64_t value; - int64_t wtf; - }; - - struct ScreenPlacement - { - vec2_t scaleVirtualToReal; - vec2_t scaleVirtualToFull; - vec2_t scaleRealToVirtual; - vec2_t virtualViewableMin; - vec2_t virtualViewableMax; - vec2_t virtualTweakableMin; - vec2_t virtualTweakableMax; - vec2_t realViewportBase; - vec2_t realViewportSize; - vec2_t realViewportMid; - vec2_t realViewableMin; - vec2_t realViewableMax; - vec2_t realTweakableMin; - vec2_t realTweakableMax; - vec2_t subScreen; - float hudSplitscreenScale; - }; - - enum itemTextStyle - { - ITEM_TEXTSTYLE_NORMAL = 0, - ITEM_TEXTSTYLE_SHADOWED = 3, - ITEM_TEXTSTYLE_SHADOWEDMORE = 6, - ITEM_TEXTSTYLE_BORDERED = 7, - ITEM_TEXTSTYLE_BORDEREDMORE = 8, - ITEM_TEXTSTYLE_MONOSPACE = 128, - ITEM_TEXTSTYLE_MONOSPACESHADOWED = 132, - }; - - enum errorParm - { - ERR_FATAL = 0, - ERR_DROP = 1, - ERR_SERVERDISCONNECT = 2, - ERR_DISCONNECT = 3, - ERR_SCRIPT = 4, - ERR_SCRIPT_DROP = 5, - ERR_LOCALIZATION = 6, - ERR_MAPLOADERRORSUMMARY = 7, - }; - - template - class symbol - { - public: - symbol(const size_t address) - : address_(reinterpret_cast(address)) - { - } - - T* get() const - { - return address_; - } - - operator T* () const - { - return this->get(); - } - - T* operator->() const - { - return this->get(); - } - - private: - T* address_; - }; - - // Main Functions - WEAK symbol Com_Error_{ 0x14288B410_g }; - - // Live Functions - WEAK symbol Live_GetConnectivityInformation{ 0x1437FA460_g }; - - // Rendering Functions - WEAK symbol T8_AddBaseDrawTextCmd{ 0x143616B60_g }; - WEAK symbol UI_GetFontHandle{ 0x143CD0A30_g }; - WEAK symbol R_TextHeight{ 0x1435B2350_g }; // [BO4-BNET-2023] - - WEAK symbol ScrPlace_GetView{ 0x142876E70_g }; - - -#define R_AddCmdDrawText(TXT, MC, F, X, Y, XS, YS, R, C, S) \ - T8_AddBaseDrawTextCmd(TXT, MC, F, X, Y, XS, YS, R, C, S, -1, 0, 0) - -#define R_AddCmdDrawTextWithCursor(TXT, MC, F, X, Y, XS, YS, R, C, S, CP, CC) \ - T8_AddBaseDrawTextCmd(TXT, MC, F, X, Y, XS, YS, R, C, S, CP, CC, 0) - -#define Com_Error(code, fmt, ...) \ - Com_Error_(__FILE__, __LINE__, code, fmt, ##__VA_ARGS__) -} \ No newline at end of file diff --git a/source/proxy-dll/definitions/variables.cpp b/source/proxy-dll/definitions/variables.cpp new file mode 100644 index 0000000..7dbb1b5 --- /dev/null +++ b/source/proxy-dll/definitions/variables.cpp @@ -0,0 +1,6510 @@ +#include +#include "variables.hpp" + +namespace fnv1a +{ + uint64_t generate_hash(const char* string) + { + uint64_t Result = 0xCBF29CE484222325; + + for (uint64_t i = 0; i < strlen(string); i++) + { + Result ^= string[i]; + Result *= 0x100000001B3; + } + + return (Result & 0x7FFFFFFFFFFFFFFF); + } +} + +namespace variables +{ + std::vector dvars_record = + { + { + "aim_slowdown_enabled", + "Slowdown the turn rate when the cross hair passes over a target", + 0x3D607772590C64FC + }, + { + "aim_lockon_enabled", + "Aim lock on helps the player to stay on target", + 0xD3FCDCA2CD83783 + }, + { + "arena_defaultPlaylist", + "Default Arena Playlist", + 0x7D60181470E5E8E8 + }, + { + "arena_seasonOverride", + "Arena Season Override", + 0x4810417D791DD7F8 + }, + { + "arena_enableListenHosting", + "Enable listen servers for arena matchmaking", + 0x181DF5AA7D92095 + }, + { + "arena_qosSkillStart", + "Base arena point skill range, regardless of search duration", + 0x35A4B7E98B04250D + }, + { + "arena_qosBrodenSkillStep", + "Arena points per interval to increase the distance between the skill and the qos skill", + 0x44A22EC68E0798C5 + }, + { + "arena_qosBrodenSkillFrequency", + "Frequency of which the the skill step is increased linearly", + 0x75215E81615C6A0F + }, + { + "arena_minHostSkillRange", + "Skill range from client's arena skill that must be qos'd before hosting lobby or unparking dedi", + 0x2A5FFA081C299437 + }, + { + "arena_giveBonusStar", + "When enabled, one bonus star will be awarded every n consecutive wins.", + 0x3F960938DC77B97F + }, + { + "arena_bonusStarStreak", + "Win streak required before awarding bonus star (if enabled)", + 0x16B8856172F03E5E + }, + { + "arena_minPlayTime", + "Time in seconds a player must play an arena match for a loss to count.", + 0x256BA16072C5A454 + }, + { + "arena_maintenance", + "When accessing Arena mode, display a maintenance message.", + 0x48972F7E0A188F50 + }, + { + "arena_lobbyReloadSearchDelayMin", + "Minimum time in seconds to delay the search for a new arena lobby after a match.", + 0x6ED9351EBCEE08C7 + }, + { + "arena_lobbyReloadSearchDelayMax", + "Maximum time in seconds to delay the search for a new arena lobby after a match.", + 0x6EF5231EBD0664E9 + }, + { + "arena_enableArenaChallenges", + "Enable arena challenges including Season Vet and Best Rank.", + 0x2E3EEB19A9EE340B + }, + { + "arena_seasonVetChallengeWins", + "Number of arena wins in a season to complete a season vet challenge.", + 0x2F56FC304D6E61EB + }, + { + "arena_unfairTeamGap", + "This is the gap where if a team is down this many players compaired with the other team then the pentalty is waved.", + 0x170F0BEC873AC2D3 + }, + { + "bg_movingPlatformPitchScale", + "The scale to apply to pitch from the moving platform that should be applied to the player's pitch", + 0x29FD42871E7EAED2 + }, + { + "player_view_pitch_up", + "Maximum angle that the player can look up", + 0x7ED57F474B124FEF + }, + { + "player_view_pitch_down", + "Maximum angle that the player can look down", + 0xDE7DB9DD6AC744A + }, + { + "player_view_swim_pitch_up", + "Maximum angle that the player can look up while swimming", + 0x60B713C5A6FCC60C + }, + { + "player_view_swim_pitch_down", + "Maximum angle that the player can look up while swimming", + 0x3997DA36B5C98979 + }, + { + "player_lean_shift", + "Amount to shift the player 3rd person model when leaning(x:left, y:right)", + 0xB8EF752D3C087DE + }, + { + "player_lean_shift_crouch", + "Amount to shift the player 3rd person model when crouch leaning(x:left, y:right)", + 0x671B0241FC57FA9 + }, + { + "player_lean_rotate", + "Amount to rotate the player 3rd person model when leaning(x:left, y:right)", + 0x4E6970FC488D8BBD + }, + { + "player_lean_rotate_crouch", + "Amount to rotate the player 3rd person model when crouch leaning(x:left, y:right)", + 0x293B5F04CFDD9DAC + }, + { + "bg_prone_yawcap", + "The maximum angle that a player can look around quickly while prone", + 0x1E0BF5B71128804D + }, + { + "bg_aimSpreadMoveSpeedThreshold", + "When player is moving faster than this speed, the aim spread will increase", + 0x25A81EC42CBDFDB4 + }, + { + "bg_maxGrenadeIndicatorSpeed", + "Maximum speed of grenade that will show up in indicator and can be thrown back.", + 0x51A6D8B45C526193 + }, + { + "player_scopeExitOnDamage", + "Exit the scope if the player takes damage", + 0x2B90906C1300936B + }, + { + "player_sustainAmmo", + "Firing weapon will not decrease clip ammo.", + 0x47C5EB83E44DCFC4 + }, + { + "player_clipSizeMultiplier", + "Changes the clip size of weapons with more than one bullet in their clip.", + 0x68CB46E1460CAB15 + }, + { + "player_lastStandSuicideDelay", + "The amount of time that must pass before the player is allowed to suicide", + 0x1038D42009D25460 + }, + { + "player_sprintTime", + "The base length of time a player can sprint", + 0x2C0C64DDCFC802FC + }, + { + "bg_gravity", + "Gravity in inches per second per second", + 0x30B9B1B37A543E43 + }, + { + "bg_lowGravity", + "Low gravity for slow or floaty objects, in inches per second per second", + 0x2652ABDA75F57CA3 + }, + { + "bg_moonGravity", + "Gravity on the moon, in inches per second per second", + 0x7587080AF570DF78 + }, + { + "bg_waterGravity", + "Gravity for missiles while in water that use tr_watergravity", + 0x5C5088A687D0F420 + }, + { + "player_viewLockEnt", + "Set an entity that the player view will be locked too.", + 0x3F017ABABB9075D4 + }, + { + "cg_isGameplayActive", + "", + 0x437875777AEF3616 + }, + { + "vehLockTurretToPlayerView", + "Locks the turret angles to the player angles and sets the players rotation speed to the turrets rotRate", + 0x443BAC9ED2A2F4 + }, + { + "mp_blackjack_consumable_wait", + "For Blackjack, the time to wait between updating consumable time.", + 0x7A9105508D8C784D + }, + { + "tu11_enableClassicMode", + "", + 0x11732EEF735B5749 + }, + { + "tu11_enableVehicleMode", + "", + 0x736B3744DE946B29 + }, + { + "bg_shieldHitEncodeWidthWorld", + "The encoding range, in width, of a client's world shield. A hit in this range is encoded into one of 16 collumns.", + 0x57A8E17675CBFE41LL + }, + { + "bg_shieldHitEncodeHeightWorld", + "The encoding range, in height, of a client's world shield. A hit in this range is encoded into one of 8 rows.", + 0x5D1E511BDF96E56ALL + }, + { + "bg_shieldHitEncodeWidthVM", + "The decoding range, in width, of a client's viewmodel shield.", + 0xC5F06C878CFD2FE + }, + { + "bg_shieldHitEncodeHeightVM", + "The decoding range, in height, of a client's viewmodel shield.", + 0x5CFD635A296ED3C7 + }, + { + "bg_disableWeaponPlantingInWater", + "Disables being able to plant mines in the water.", + 0x7D4734AAB01CCAC0 + }, + { + "disable_rope", + "Disables the rope system", + 0x589543C5CA4AA0B0 + }, + { + "waterbrush_entity", + "CM_GetWaterHeight function will test against this enitty. Can be used on brushmodels to move the water level", + 0x6D05F3E31E627502 + }, + { + "playerPushAmount", + "If this value is set the player will get pushed away from AIs by the amount specified.", + 0x536C6409B3369248 + }, + { + "bg_serverDelayDamageKickForPing", + "Turn on delayed damage kick on server to allow for client ping", + 0x3CB742BC7C5039B3 + }, + { + "bg_useClientDamageKick", + "Turn on to make the server use the damage kick angles from the client usercmd", + 0x66718A7BBE48B522 + }, + { + "slam_enabled", + "Enable slam activation", + 0x3DF86A5C80DE5AFA + }, + { + "playerWeaponRaisePostIGC", + "Temp dvar to give script control over which wepaon anim plays after an IGC", + 0x48B28EA7A73F4D7F + }, + { + "bg_allowPlayerRoleTemplateButtonOverrides", + "When true the PlayerRoleTemplates are allowed to define button overrides per the enum PlayerRoleButtonOverrideTypes.", + 0x39DAA8BF95AE47A0 + }, + { + "bg_aqs", + "", + 0x28A5EA43BB11E71A + }, + { + "bg_aqsStyle", + "", + 0x629275EC97C1ED2F + }, + { + "bg_ads", + "", + 0x285DEA43BAD43177 + }, + { + "bg_bobcycleResetThreshold", + "The difference between the new and old bob cycle before we treat as if the server reset its bob cycle.", + 0x78821CC8458682CE + }, + { + "adsZeroSpread", + "Immediately zero spreadAmount when fully ADS", + 0x630AAA3ED87A2CD0 + }, + { + "bg_deferScriptMissileDetonation", + "Defer G_ExplodeMissile() till after origin is updated in G_RunMissile()", + 0x9AC21A6A320098B + }, + { + "bg_isolateDamageFlash", + "Drive damage flash overlay from isolated variable instead of view kick pitch", + 0x5C7202461031C541 + }, + { + "bg_limitGrenadeImpacts", + "Use missileTargetEnt to limit impact damage to the first impact", + 0x1B4BC4AC24D6A8B7 + }, + { + "bg_zombiePlayerUsesUtilityClip", + "Use utility clip for zombie player movement", + 0x4C3B22F554427952 + }, + { + "bg_warmode_version", + "Temp dvar to control the war mode gametype", + 0x62CE61CC049BBAF + }, + { + "gadgetPowerOverrideFactor", + "Override power factor", + 0x6358FE7CC1E358D9 + }, + { + "gadgetPowerOverchargePerkTimeFactor", + "Overcharge perk charge over time multiplier", + 0x72F867BAEAFFED96 + }, + { + "gadgetPowerOverchargePerkScoreFactor", + "Overcharge perk score multiplier", + 0x342CA843EBD8A6D9 + }, + { + "gadgetThiefShutdownFullCharge", + "If this is set to true then the users will recieve a full gadget charge if they shutdown an enemy. ", + 0x7C3412AD9BC26114 + }, + { + "gadget_force_slots", + "Force the gadget slots to be in a defined order: primary, secondary, ability, heavy", + 0x1E1071C9F9971C53 + }, + { + "mm_keyframeUsageAnimIndex", + "anim to watch usage graph of", + 0x58BA8669CAF26406 + }, + { + "cg_minimapPadding", + "The amount of padding to apply to the circular minimap", + 0x61C6A72FF051961C + }, + { + "shoutcastHighlightedClient", + "Shoutcaster's currently highlighted clientNum.", + 0x69E29B87C17AED9 + }, + { + "cg_hudMapFriendlyWidth", + "The size of the friendly icon on the full map", + 0x7F519E0BEE1AB1CA + }, + { + "cg_hudMapFriendlyHeight", + "The size of the friendly icon on the full map", + 0x4619BD1BC36D8445 + }, + { + "cg_hudMapPlayerWidth", + "The size of the player's icon on the full map", + 0x6178FDF4AAD2F55C + }, + { + "cg_hudMapPlayerHeight", + "The size of the player's icon on the full map", + 0x24B133C70747FCEB + }, + { + "waypointIconWidth", + "Width of the offscreen pointer.", + 0x7D914A08D198D4D9 + }, + { + "waypointIconHeight", + "Height of the offscreen pointer.", + 0x7E8A5C6D93107AC8 + }, + { + "waypointOffscreenPointerDistance", + "Distance from the center of the offscreen objective icon to the center its arrow.", + 0x678EB86FAC35A1BB + }, + { + "cg_threatDetectorRadius", + "The radius of the threat detector scan.", + 0x6D04072BA075F624 + }, + { + "cg_usingClientScripts", + "True, if client scripts are enabled.", + 0x2651402F8E72FD35 + }, + { + "cg_drawGun", + "Draw the view model", + 0x21ECB143EDAE83C0 + }, + { + "cg_weaponHintsCoD1Style", + "Draw weapon hints in CoD1 style: with the weapon name, and with the icon below", + 0x386051E08C3DBFCC + }, + { + "cg_focalLength", + "Lens focal length for 3-perf 16x9 super 35mm (24.89mm x 14mm)", + 0x76CB476AD96F6429 + }, + { + "cg_fov", + "The field of view angle in degrees", + 0x68E6BD38B3C5F133 + }, + { + "cg_fovExtraCam", + "The field of view angle in degrees for the extra cam", + 0x619179B3BFB57936 + }, + { + "cg_useWeaponBasedVariableZoom", + "Use weapon based variable zoom instead of player based.", + 0x5F0E3C836B0F7251 + }, + { + "cg_viewVehicleInfluenceGunner", + "The influence on the view from being a vehicle gunner", + 0x6CAE8CF76050DCCD + }, + { + "cg_viewVehicleInfluenceGunnerFiring", + "The influence on the view from being a vehicle gunner while firing", + 0x2A04D21251DFF822LL + }, + { + "cg_viewVehicleInfluenceGunner_mode", + "Controls when the viewVehicleInfluenceGunnerFiring is effective. 0 - only on ADS and firing; 1 - on ADS, firing, or moving camera; 2 - always on", + 0x292947732E98C3DD + }, + { + "cg_draw2D", + "Draw 2D screen elements", + 0x578107FC9F13DAEC + }, + { + "cg_drawLagometer", + "Draw lagometer", + 0x548B3E93CD81FC04 + }, + { + "cg_drawFPS", + "Draw frames per second", + 0x1A9A9543E9EA5C55 + }, + { + "cg_drawMaterialImageNum", + "Use up/down on the dpad to select an image when cg_drawMaterial is enabled. Press right for more info on that image.", + 0x62201416DD316B1C + }, + { + "cg_drawMaterialImageName", + "Do not use (set by cg_drawMaterialImageNum code)", + 0x1B45AFDA3D2F6497 + }, + { + "cg_drawCrosshair", + "Turn on weapon crosshair", + 0x28A680A206CE7AA + }, + { + "cg_drawCrosshairCooker", + "Turn on cook indicator for cooked grenades. Use 1 for cookOffHoldTime grenades and 2 cookOffHoldTime and cookOffHold ones.", + 0x28B74F0EA64BBD81 + }, + { + "cg_drawCrosshairNames", + "Draw the name of an enemy under the crosshair", + 0x3DFF0D6F30875126 + }, + { + "cg_hudGrenadeIconMaxRangeFrag", + "The minimum distance that a grenade has to be from a player in order to be shown on the grenade indicator", + 0x7E10D8205D5FB7A3 + }, + { + "cg_lagometer_pos", + "lagometer position", + 0x2369C26464214397 + }, + { + "cg_thirdPersonRange", + "The range of the camera from the player in third person view", + 0x7721647E3B677041 + }, + { + "cg_thirdPersonAngle", + "The angle of the camera from the player in third person view", + 0x3B52B3027049DD27 + }, + { + "cg_thirdPersonRoll", + "The roll of the camera from the player in third person view", + 0x69BF0372ED5290BF + }, + { + "cg_thirdPersonSideOffset", + "The side offset for the camera from the player in third person view", + 0x137F72894198596C + }, + { + "cg_thirdPersonUpOffset", + "The up offset for the camera from the player in third person view", + 0x1E667A2FDB87697E + }, + { + "cg_thirdPersonFocusDist", + "The distance infront of the player to aim the 3rd person camera at", + 0x4709868684DEF034 + }, + { + "cg_thirdPersonFocusOffsetUp", + "An offset to add to the position the camera is looking at", + 0x4AE8BBC003F5814A + }, + { + "cg_thirdPersonCamOffsetUp", + "An offset to add to the camera position", + 0x69C3ABA3C8961E95 + }, + { + "cg_thirdPersonCamLerpScale", + "Lerp amount for the camera in 3rd person mode", + 0x38173B979832E468 + }, + { + "cg_thirdPerson", + "Use third person view", + 0x39575543F27BBB7C + }, + { + "cg_thirdPersonMode", + "How the camera behaves in third person", + 0x17D6FA8AFA02D41F + }, + { + "cg_subtitleWidthWidescreen", + "The width of the subtitle on a wide-screen", + 0x592E4EB48B2992B3 + }, + { + "cg_headIconMinScreenRadius", + "The minumum radius of a head icon on the screen", + 0x577DAAC9CC20E5DB + }, + { + "cg_overheadNamesSize", + "The maximum size to show overhead names", + 0x18CD0DE6C7E17CD + }, + { + "cg_overheadIconSize", + "The maximum size to show overhead icons like 'rank'", + 0x6A685E4DC639DB4C + }, + { + "cg_overheadRankSize", + "The size to show rank text", + 0x13A81F9AA23A7593 + }, + { + "cg_healthPerBar", + "How much health is represented per health bar", + 0x442D42EFC73D739A + }, + { + "cg_drawFriendlyNames", + "Whether to show friendly names in game", + 0x58DD8654FFC55717 + }, + { + "cg_playerHighlightTargetSize", + "Size of player target highlights.", + 0x20568A24245D86D3 + }, + { + "cg_ScoresColor_Gamertag_0", + "player gamertag color on scoreboard", + 0x66BEE54AB204EDA4 + }, + { + "cg_ScoresColor_Gamertag_1", + "player gamertag color on scoreboard", + 0x66BEE64AB204EF57 + }, + { + "cg_ScoresColor_Gamertag_2", + "player gamertag color on scoreboard", + 0x66BEE74AB204F10A + }, + { + "cg_ScoresColor_Gamertag_3", + "player gamertag color on scoreboard", + 0x66BEE84AB204F2BD + }, + { + "hud_healthOverlay_pulseStart", + "The percentage of full health at which the low-health warning overlay begins flashing", + 0x62097F9D5D1CCCD7 + }, + { + "cg_drawTalk", + "Controls which icons CG_TALKER ownerdraw draws", + 0x1CAE64EFA0B7AC5C + }, + { + "cg_drawJobsPerf", + "draw jobs performance information", + 0x666AE70D31B8A985 + }, + { + "flareDisableEffects", + "", + 0xA05647541297479 + }, + { + "showVisionSetDebugInfo", + "Enables visionset debug info", + 0x3109253A0366F337 + }, + { + "cl_smoothSnapInterval", + "Length of the buffer smoothing the snap interval when adjusting the time delta. Value must be a power of 2.", + 0x61D822229C373508 + }, + { + "con_typewriterColorBase", + "Base color of typewritten objective text.", + 0x43271A84C67417BF + }, + { + "cl_deathMessageWidth", + "Pixel width of the obituary area", + 0x1A60BB02342FD5F6 + }, + { + "m_pitch", + "Default pitch", + 0x68045F57217A8E71 + }, + { + "m_filter", + "Allow mouse movement smoothing", + 0x68CB4EF34E0CEDB7 + }, + { + "m_mouseFilter", + "Mouse filter", + 0x626B0DAB7BF45F06 + }, + { + "m_mouseAcceleration", + "Mouse acceleration", + 0x24898FD2F3E6C0D8 + }, + { + "m_mouseSensitivity", + "Mouse sensitivity", + 0x7659B9A54E5830C7 + }, + { + "cl_freelook", + "Enable looking with mouse", + 0x1B49BFBB87BE110E + }, + { + "cl_motdString", + "Message of the day", + 0x370CC5B56A1F2E1E + }, + { + "cl_ingame", + "True if the game is active", + 0x64F0BE81B0EA8E0E + }, + { + "player_name", + "Player name", + 0x13A62F542CF8E86E + }, + { + "maxVoicePacketsPerFrame", + "The max number of voice packets that a local client will process per frame", + 0x415248C9D932B45E + }, + { + "splitscreen_playerCount", + "The number of players in a splitscreen game", + 0x6CDDC2FC45915C64 + }, + { + "splitscreen_horizontal", + "Draw splitscreen views horizontally", + 0x11734D8E2969A720 + }, + { + "cl_migrationPingTime", + "how many seconds between client pings. used to determine hosting suitability.", + 0x605F4A6B9253BE84 + }, + { + "con_label_filter_mask", + "mask to filter tty by label, if flag set then visible (1<cryptokey conversion", + 0x32D8C55014C9A25A + }, + { + "tu11_lootCryptoAutoRetry", + "Enabled or disables auto lootxp->cryptokey conversion", + 0x7889330B0D3267E5 + }, + { + "loot_burnBatchSize", + "Batch size for burning duplicate items", + 0x21D791CABDDF87A + }, + { + "loot_burnCooloff", + "Cooloff period before burning the next batch of items", + 0x7CF2540405181DE1 + }, + { + "loot_burnRefetchOnSuccess", + "Refetch inventory when a burn is successful", + 0x10FA7626F75D5DC4 + }, + { + "loot_burnCommonRefund", + "Cryptokeys refunded when a Common item is burned", + 0x1F47DF8371DDB95E + }, + { + "loot_burnRareRefund", + "Cryptokeys refunded when a Rare item is burned", + 0x3529C093CB10C247 + }, + { + "loot_burnLegendaryRefund", + "Cryptokeys refunded when a Legendary item is burned", + 0x610F1F0B8B9F240 + }, + { + "loot_burnEpicRefund", + "Cryptokeys refunded when an Epic item is burned", + 0x18866B4E6E036D8A + }, + { + "loot_burnMinMegaRequired", + "Minimum number of mega gobblegum required to burn", + 0x7C2541F3FD37CB64 + }, + { + "loot_burnMinRareRequired", + "Minimum number of rare gobblegum required to burn", + 0x679FDEC337F446A2 + }, + { + "loot_burnMinUltraRequired", + "Minimum number of ultra gobblegum required to burn", + 0xBA9673DB515C92A + }, + { + "live_store_enable", + "Enable/Disable Store button in UI.", + 0x514F69F96CEB06F9 + }, + { + "live_store_enable_inventory", + "Enable/Disable inventory fetch.", + 0x1861A7458471BFC6 + }, + { + "store_item_viewed_timer", + "Minimum time (in ms) player should look at a store item to register a comscore event", + 0x6B1BF1B329DA7BA7 + }, + { + "live_store_show_details", + "Enable/Disable product browse.", + 0x4DF1F8667B658AF6 + }, + { + "live_store_disable_lang", + "Disable store for the available language based on value of dvar loc_availableLanguages.", + 0xED2201F94165577 + }, + { + "live_store_disable_region", + "Disable store for the given SKU region.", + 0x3A06182194A98F5F + }, + { + "live_enablePolls", + "If true, polls will fire off demonware tasks", + 0x7D6F7033B3CBEFFF + }, + { + "xblive_matchEndingSoon", + "True if the match is ending soon", + 0x1930826547682687 + }, + { + "live_pubSemaphoreCheckIntervalSeconds", + "Interval in seconds between checking the backend to see if the pubsemaphore timestamp has changed", + 0x46298D1906A8D521 + }, + { + "live_pubSemaphoreJitterSeconds", + "Jitter in seconds to apply to live_pubSemaphoreCheckIntervalSeconds", + 0x79FB304CA592D50A + }, + { + "live_pubSemaphoreForceChange", + "If true pubsemaphore will always signal as changed", + 0xD886CFC3E211B9E + }, + { + "live_pubSemaphoreUserTriggerTime", + "time when the user confirmed a game settings changed popup", + 0x61A5DB82D8C14329 + }, + { + "stat_version", + "Stats version number", + 0x2D3ACDB765E3A044 + }, + { + "stats_version_check", + "Reset stats if version numbers do not match", + 0x265573B1313AE7CC + }, + { + "maxStatsBackupInterval", + "Maximum number of days before performing stats backup to Demonware User Storage", + 0x1DF65DE154336663 + }, + { + "zero_stats_check", + "Check for zeroed out stats from Demonware", + 0x511151061E142E78 + }, + { + "dwFileFetchTryIntervalBase", + "Delay in seconds after file fetch fails to the next retry. Exponential growth each retry.", + 0x3CCF9927A600C7BB + }, + { + "dwFileFetchTryIntervalMax", + "Max delay in seconds between file fetch tries.", + 0x395223811BA33748 + }, + { + "dwFileFetchTryMaxAttempts", + "Max retry attempts before stopping altogether.", + 0x6589D56B17D70C3D + }, + { + "waitOnStatsTimeout", + "Time in seconds to wait for stats to be fetched while dev mapping.", + 0x112A3EC30994F0FB + }, + { + "minDelayForOtherPlayerStatsFetch", + "Delay in milliseconds to refetch the stats of a player.", + 0xEB0B5C7E1D13D45 + }, + { + "statsLocationFatal", + "If true, a zombie stats error will cause the game to end, if false a warning is printed to the console and the game continues", + 0x3D6403AE9B540CAF + }, + { + "statsCheckXuidBeforeStatsUpload", + "Checks the XUID of the stats before uploading. Used as bitmask for each eMode(1 << mode)", + 0x2F96F30B7A7EEBC9 + }, + { + "statsErrorNormal", + "Error if an invalid stats access is requested on NORMAL stats.", + 0x3AA8AD957724ADA9 + }, + { + "statsErrorStable", + "Error if an invalid stats access is requested on STABLE stats.", + 0x63C563C0735A0D + }, + { + "statsErrorOtherPlayer", + "Error if an invalid stats access is requested on OTHERPLAYER stats.", + 0x5BC9EEC9F12DCE9D + }, + { + "livestorage_fakeNoob", + "Force this player to be treated like a noob", + 0x12ABEB1A03756136 + }, + { + "purchasedClassSetCount", + "Number of class sets available when purchased", + 0x2142A22063B24F79 + }, + { + "defaultClassSetCount", + "Number of class sets available when not purchased", + 0xFF412D378A4FF95 + }, + { + "live_timewarp", + "Offset calculated live time by this amount of days", + 0x59E760D0F14AE13B + }, + { + "tu9_backupBadDecompress", + "Create an online backup when decompression fails", + 0x6A8952240D0AC6F0 + }, + { + "tu9_backupBadSpace", + "Create an online backup when there is insufficient space for decompression", + 0x57C84253DD30221B + }, + { + "tu10_validationFatal", + "Disconnect completely when a stats validation error is detected", + 0x7EF64CF71033AD43 + }, + { + "tu12_delayFFOTD", + "ffotd waits on the playlist to first be downloaded, the execs everything in the proper sequence.", + 0x1BB581108319DD0E + }, + { + "tu10_enableCyclicalDailyChallenges", + "Enable cyclical daily challenges", + 0x4BAA56D6CA76F50 + }, + { + "skill_teamBeta", + "Beta value for team based skill calculation", + 0x55DAE8F1DBE070F0 + }, + { + "skill_onboardingEnter", + "Initial skill for players entering the onboarding pool", + 0x5D596089B4139224 + }, + { + "skill_onboardingExit", + "Initial skill for players leaving the onboarding pool", + 0x3813AEE9B163746A + }, + { + "skill_onboardingThreshold", + "Skill value that will force players out of the onboarding pool", + 0x573F2FA1606C09FD + }, + { + "skill_onboardingGames", + "Number of games to player before moving the player out of the onboarding pool", + 0x1735443A940137E9 + }, + { + "skill_onboardingAdjustOnExit", + "Whether of not skill values should be adjusted when exiting onboarding pool", + 0x359776C98A2ECB4C + }, + { + "skill_onboardingEnabled", + "Whether or not onboarding is enabled for new players.", + 0x35FD28B79E60A31F + }, + { + "allowHost_matchesHostedRatio", + "Required match completion/hosted ratio. 0 is off.", + 0x14D959F9CE846C4C + }, + { + "allowHost_matchesPlayedRatio", + "Required match completion/played ratio. 0 is off.", + 0x60A221B0500B366C + }, + { + "disableHost_matchesHostedRatio", + "Required match hosted completion/failure ratio. 0 is off.", + 0x2ED3F5BDC6787D0B + }, + { + "disableHost_matchesPlayedRatio", + "Required match played completion/failure ratio. 0 is off.", + 0x19B1C23FBE338457 + }, + { + "behaviorTrackerVersionNumber", + "Version number for the behavior tracker", + 0x696D9FC45BE57EA + }, + { + "probation_version", + "", + 0x15791DA116824B0C + }, + { + "probation_public_enabled", + "Probation enabled", + 0x1161F73C69A2E4E7 + }, + { + "probation_public_quitScalar", + "How much each quit is factored into the probation", + 0x4D3075E7488FB0C1 + }, + { + "probation_public_timeoutScalar", + "How much each timeout is factored into the probation", + 0xC2C15F1DCB07EA5 + }, + { + "probation_public_kickScalar", + "How much each kick is factored into the probation", + 0x7F9B6B07BA2C9F38 + }, + { + "probation_public_matchHistoryWindow", + "How many games are evaluated to determin probation.", + 0x193941C02761329D + }, + { + "probation_public_probationThreshold", + "How many violations puts the player over the limit.", + 0x64D06AFB221D250D + }, + { + "probation_public_warningThreshold", + "How many violations causes the player to get warned.", + 0x178D54890E821071 + }, + { + "probation_public_probationTime", + "Time the player gets punished in minutes.", + 0x7B0E75C7433D0183 + }, + { + "probation_public_forgiveCount", + "How many violations to forgive when probation is given", + 0x27B7BAD494922037 + }, + { + "probation_league_enabled", + "Probation enabled", + 0x2CA03D36EA11AB0B + }, + { + "probation_league_quitScalar", + "How much each quit is factored into the probation", + 0x23369C53BFC4A83D + }, + { + "probation_league_timeoutScalar", + "How much each timeout is factored into the probation", + 0x512A4ADD52B273C9 + }, + { + "probation_league_kickScalar", + "How much each kick is factored into the probation", + 0x2B1667544F18824 + }, + { + "probation_league_dashboardScalar", + "How much each dashboard is factored into the probation", + 0x19E3BFFA3914C0F6 + }, + { + "probation_league_matchHistoryWindow", + "How many games are evaluated to determin probation.", + 0x296988DCFD7F3FA9 + }, + { + "probation_league_probationThreshold", + "How many violations puts the player over the limit.", + 0x58849275CA1E3AE9 + }, + { + "probation_league_warningThreshold", + "How many violations causes the player to get warned.", + 0x2122E9BA9041C1ED + }, + { + "probation_league_probationTime", + "Time the player gets punished in minutes.", + 0x4F631B62128031D7 + }, + { + "probation_league_forgiveCount", + "How many violations to forgive when probation is given", + 0x7097B82B46A66AC3 + }, + { + "fixNegativeLosses", + "Fix negative losses in combat record", + 0x536CD41D57579E2C + }, + { + "livestats_skipFirstTime", + "Disables first time flow for all session modes.", + 0x62BE8FB76AD6AEA3 + }, + { + "loot_taskWindow", + "time alloted to the reward task, after which a retry will occur", + 0x1A52CF5F59246D05 + }, + { + "loot_taskMaxAttempts", + "max retries before the reward task is considered a failure", + 0x17598E3F123CF14B + }, + { + "tu4_enableCodPoints", + "Enable display and spending of COD Points", + 0x524F4493E0257D85 + }, + { + "local_media_tier", + "current local media tier for all users on this console.", + 0x4FA6A41CE0F84F78 + }, + { + "statsVersionMP", + "design version for MP stats", + 0x7AEFEDDC58F9E985 + }, + { + "statsVersionCP", + "design version for CP stats", + 0x7ACDF1DC58DD09EB + }, + { + "statsVersionZM", + "design version for ZM stats", + 0x7B1BE0DC591F0E59 + }, + { + "statsVersionFR", + "design version for FR stats", + 0x7AD7E1DC58E54340 + }, + { + "loadoutVersionMP", + "design version for MP loadouts", + 0x62C3C580035FD180 + }, + { + "loadoutVersionZM", + "design version for ZM loadouts", + 0x62A5C2800346CED8 + }, + { + "lobby_hostBots", + "Enables lobby bots", + 0x547BB8673052413C + }, + { + "lobbyvm_forceGC", + "Force garbage collection after lobby pump to keep memory usage in check", + 0x550FF919028CC160 + }, + { + "ui_lobbyDebugVis", + "master switch for turning on or off lobby debug ui", + 0x868D54ACE3910EB + }, + { + "ui_lobbyDebugClients", + "Enables and sets the Lobby Type for Client Debugging", + 0x7D92D9DB09C4181D + }, + { + "ui_lobbyDebugOverlay", + "Turn Lobby Debug Overlay ON/OFF", + 0x6EF2722E9DA903F9 + }, + { + "ui_lobbyDebugBaseX", + "debug ui base x", + 0x706255C3ACBF781A + }, + { + "ui_lobbyDebugBaseY", + "debug ui base x", + 0x706256C3ACBF79CD + }, + { + "ui_lobbyDebugExtraInfoLoc", + "game mode loc", + 0x6DF332536E7673DF + }, + { + "ui_lobbyDebugSessionSQJ", + "Enables/Disables session search debugging", + 0x5102D263505BECD9 + }, + { + "ui_lobbyDebugVoice", + "Enables/Disables lobby voice debugging", + 0x47514411BBEAF + }, + { + "ui_abortKeyboardOnUIChange", + "Abort any onscreen keyboard operations when the lobby system changes the UI screen", + 0x5FA1AEC845987540 + }, + { + "tu11_matchmakingPriorityMP", + "MP matchmaking priority setting", + 0x3B7E7D205283F9AA + }, + { + "tu11_matchmakingPriorityMPIgnoreTime", + "MP amount of time that a session will be ignored for", + 0x393504697ED9246D + }, + { + "party_minplayers", + "Minimum number of players in a party", + 0x2500E4DB2F10F5EE + }, + { + "party_maxplayers", + "Maximum number of players in a party", + 0x596545C72F0E4FE4 + }, + { + "party_autoteams", + "Enables/Disables auto team functionality", + 0x2482606B77C310A7 + }, + { + "lobby_maxLocalPlayers", + "Enables/Disables auto team functionality", + 0x66BAC8B42067D2C5 + }, + { + "lobby_forceLAN", + "Force LAN lobby if > 0, 1-LAN offline, 2-LAN and connected to dw", + 0x44DE8F206FD45EEA + }, + { + "lobby_showSVDebug", + "shows sv debug info in the frontend", + 0x28B546FBE4B2AF13 + }, + { + "lobbymigrate_MaxBWPackets", + "number of bw test packets to send when we have the token", + 0x1CB0320F843FECB + }, + { + "lobbymigrate_MaxPacketWaitTime", + "ms to wait for test packet responses after last packet is sent", + 0x5E0E655C82BD8DD9 + }, + { + "lobbymigrate_NomineeWaitMS", + "ms to wait for each nominee to send us a partystate", + 0x3461F602C3EC7F19 + }, + { + "lobbymigrate_HostWaitMS", + "ms to send hostannounce packets before sending partystates", + 0x3D04D8184D5237F6 + }, + { + "lobbymigrate_NomineeRecalcInterval", + "ms to wait between recalculating migration nominees", + 0x63766A793BE4AC8D + }, + { + "lobbymigrate_TestInterval", + "base ms to wait between test rounds, see lobbymigrate_TestIntervalJitter", + 0x2D7E4E3258446878 + }, + { + "lobbymigrate_TestIntervalJitter", + "ms jitter between test rounds", + 0x29CD2D8303C0B9EE + }, + { + "lobbymigrate_MinScoreDiff", + "minimum score nominee must differ by before rank will change", + 0x20EFC56A1BCFC618 + }, + { + "lobbymigrate_WirelessLatencyIncrease", + "percentage increase for wireless client latency during host selection", + 0x48EF2DF9DA3140B5 + }, + { + "lobbymigrate_useStdDev", + "If true we'll use the standard devation of the clients latency as a tie-breaker instead of the clientnum", + 0x7D62DC2DCC9C357C + }, + { + "lobbyMigrate_Enabled", + "Set to false to disable lobby migration", + 0x1B20187487D3509E + }, + { + "lobbyMigrate_EnabledLAN", + "Set to false to disable lobby migration in LAN mode", + 0x6210238C373449C1 + }, + { + "lobbyMigrate_migrateToBestGameHostEnabled", + "Set to false to disable migrate to best game host migration", + 0x77255714A6A48B0A + }, + { + "lobbyMigrate_dedicatedOnly", + "only allow dedicated servers to host", + 0x47EBF1500DC54DA4 + }, + { + "lobbyMigrate_considerStreamingForHostMigration", + "When true, will consider the factor of whether the host is streaming or not, when nominating for host migration", + 0x1403A1EDE03BB4A5 + }, + { + "lobby_clientTimeout", + "Seconds with no received packets from host until a timeout occurs", + 0x6B76B42B0169563E + }, + { + "lobby_clientWarnTimeout", + "Seconds with no received packets from host until a host missing warning is displayed", + 0x3400A1AC84221B6E + }, + { + "lobby_clientContentTimeout", + "Milli-Seconds to finish sending the active client data until a timeout occurs", + 0x7DB3090EE0D467AF + }, + { + "lobby_clientEndCooloffTime", + "Miliseconds before dropping net chan channels to host", + 0x44D076BCC8EA1A3F + }, + { + "lobby_clientEndFakeSendLoss", + "When a match end and are returning to the front end, check if we have full loaded the UI level", + 0x7B6F8090CE75BC9C + }, + { + "lobby_clientLoadingIntoUICheck", + "When a match end and are returning to the front end, check if we have full loaded the UI level", + 0x21A55E1609045893 + }, + { + "lobbyLaunch_fadeToBlackDelay", + "Once the launch game timer has started, when the fade to black will happen", + 0x1F6674CAE730AA08 + }, + { + "lobbyLaunch_gameLaunchDelay", + "Once the launch game timer has started, when the launch will happen", + 0x3AC3D72F21D83F1B + }, + { + "lobbyLaunch_fadeToBlackDelayOnConnect", + "Once the launch game timer has started, when the fade to black will happen", + 0xCD73B6D54F107A5 + }, + { + "lobbyLaunch_gameLaunchDelayOnConnect", + "Once the launch game timer has started, when the launch will happen", + 0x68663791C854DEC4 + }, + { + "lobbyLaunch_waitForClientAckDelay", + "Time to wait for acknowledgments from the clients before launching", + 0x2E0639684531C4C8 + }, + { + "lobby_hostTimeout", + "seconds without any message from client before they are disconnected", + 0x3C2A63995EDF4741 + }, + { + "lobby_hostIntervalState", + "lobby state message intervals", + 0x21ACD63ED36D63B4 + }, + { + "lobby_hostIntervalHeartbeat", + "lobby heartbeat message intervals", + 0x25E441ECA4C55181 + }, + { + "lobby_hostContentTimeout", + "Seconds to finish sending the host content until a timeout occurs", + 0x39777C9A27DF8E2A + }, + { + "lobby_enablePSDataStreamingInGame", + "Turn on the in-game streaming of paintshop data to all clients marked dirty", + 0x2836622FCD9AC11F + }, + { + "lobby_enableLoadoutDataStreamingInGame", + "Turn on the in-game streaming of loadout data to all clients marked dirty", + 0x7867B95DC8C4230A + }, + { + "lobby_hostPSFragmentRetryInterval", + "Paintshop data fragment retry interval", + 0x2600410670BD4182 + }, + { + "lobby_enablePSDataStreamingInLobby", + "Turn on the paintshop data to be shared in the frontend lobbies", + 0x7639D7847E1D3B + }, + { + "lobby_ingamePSDataStreamingBW", + "Control In-Game Paintshop data streaming Bandwidth(total bumber of paintshop bytes to be sent per snapshop)", + 0x49D12FB1ED3F005B + }, + { + "lobby_moveLobby", + "seconds before a lobby move is considered a failure", + 0x7050EF8E2D8622E7 + }, + { + "lobby_hostJoinRequestReject", + "Have the host reject incomming connections with random reasons", + 0x2C16E97C130C620C + }, + { + "join_agreementWindow", + "all clients must agree to join the new host in this window", + 0x57043A928B14422A + }, + { + "join_handshakeWindow", + "server must respond to reservation request within this window", + 0x790D64342518F3FB + }, + { + "join_completionWindow", + "once a join is complete, the old host remains active for this amount of time before deactivating itself", + 0x2638FCB20DC52814 + }, + { + "join_infoProbeWindow", + "time to wait for an info probe IM response", + 0x7943C77D227FF348 + }, + { + "join_retryDelay", + "if the host is busy, we'll try re-joining after this cooloff", + 0x69A67CC8E74D05CF + }, + { + "join_retryCount", + "if the host is still busy after these many retries, move on", + 0x5D50F5CB3997496F + }, + { + "join_reservationWindow", + "host join reservation window in ms", + 0x2C13C8872AEA0758 + }, + { + "lobbymsg_prints", + "Turns on and off the message debug prints", + 0xFEFA8EC975C9D0D + }, + { + "lobbyDebugLogJoins", + "Logs join results to the kvs", + 0x15325B3EB423F269 + }, + { + "lobbyDebugLogJoinSuccess", + "Includes join success results while logging", + 0xBAD693F0A579CA3 + }, + { + "lobby_ptptimeout", + "Time out for connection test", + 0x10FFB6C091A1744B + }, + { + "partyPrivacyEnabled", + "Lobby party privacy on/off", + 0x1E52CB4B7B32961A + }, + { + "partyPrivacyPumpEnabled", + "Lobby party privacy pump on/off", + 0x2FF3E7BFBD5CE85C + }, + { + "partyPrivacyCheckInterval", + "Party privacy check interval", + 0x1C018601EF2EA99A + }, + { + "leaveWithPartyEnabled", + "Lobby leave with party on/off", + 0x61CD7A5D0E152F8D + }, + { + "lobbyMergeEnabled", + "Lobby merge on/off", + 0x406AB21D919144AA + }, + { + "lobbyMergeInterval", + "Lobby merge interval", + 0x747EDB66E0FE444C + }, + { + "lobbyMergeDedicatedEnabled", + "Lobby dedicated merge on/off", + 0x36D033E0551BFF83 + }, + { + "lobbyAdvertiseSkip", + "Lobby Advertise: Skip advertisment", + 0x462E6E8627E5372B + }, + { + "lobbyAdvertiseDirty", + "Lobby Advertise: Session is dirty/needs updating", + 0x60506FA050DCE73C + }, + { + "lobbyAdvertiseMaxPlayers", + "Lobby Advertise Param: Max Players", + 0x452B5D4465EE5AD8 + }, + { + "lobbyAdvertiseNumPlayers", + "Lobby Advertise Param: Num Players", + 0x58D7611F93A7FCFE + }, + { + "lobbyAdvertiseServerType", + "Lobby Advertise Param: server type", + 0x64EC2C20CC5CBE0F + }, + { + "lobbyAdvertiseShowInMatchmaking", + "Lobby Advertise Param: Show in matchmaking", + 0x50E5350E8F7BD556 + }, + { + "lobbyAdvertiseNetcodeVersion", + "Lobby Advertise Param: Netcode version", + 0x21B1541ECD98A72 + }, + { + "lobbyAdvertiseMapPacks", + "Lobby Advertise Param: Map packs", + 0x7A96CE8EF5319D80 + }, + { + "lobbyAdvertisePlaylistVersion", + "Lobby Advertise Param: Playlist Version", + 0x460990550E224156 + }, + { + "lobbyAdvertisePlaylistNumber", + "Lobby Advertise Param: Playlist Number", + 0x705B789559A59177 + }, + { + "lobbyAdvertiseIsEmpty", + "Lobby Advertise Param: Is Empty", + 0x688AAC69E4F7C18D + }, + { + "lobbyAdvertiseTeamSizeMax", + "Lobby Advertise Param: Team Size Max", + 0x2A90AF2FA81CF8EA + }, + { + "lobbyAdvertiseSkill", + "Lobby Advertise Param: Skill level", + 0x264614F5CA9FF2B9 + }, + { + "lobbyAdvertiseGeo1", + "Lobby Advertise Param: Geographical loc 1", + 0x3C83EFEB4F222B40 + }, + { + "lobbyAdvertiseGeo2", + "Lobby Advertise Param: Geographical loc 2", + 0x3C83F2EB4F223059 + }, + { + "lobbyAdvertiseGeo3", + "Lobby Advertise Param: Geographical loc 3", + 0x3C83F1EB4F222EA6 + }, + { + "lobbyAdvertiseGeo4", + "Lobby Advertise Param: Geographical loc 4", + 0x3C83F4EB4F2233BF + }, + { + "lobbyAdvertiseServerLocation", + "Server location to advertise", + 0x27D325BF9B693A80 + }, + { + "lobbyAdvertiseLatencyBand", + "Server latency band to advertise", + 0x2686027EBE0C93F5 + }, + { + "lobbyAdvertiseMap", + "Lobby Advertise Param: Map", + 0x61F1674454C3251A + }, + { + "lobbySearchSkip", + "Lobby Search: Skip searches", + 0x1654E95D79AE2D20 + }, + { + "lobbyDedicatedSearchSkip", + "Lobby Search: Skip dedicated server searches", + 0x7E7A52A88079870B + }, + { + "lobbySearchDelay", + "Lobby Search: Time delay between searches", + 0x58CAF432075AC8A + }, + { + "lobbySearchGeoMin", + "Lobby Search: Minimum number of geo tiers that must match", + 0x7E01BF4D20878528 + }, + { + "lobbySearchQueryId", + "Lobby Search Param: Query ID", + 0xD6F0384367E76DC + }, + { + "lobbySearchGameSecurityId", + "Lobby Search Param: Game security id, used in communication encryption", + 0x180772AC2D5D37FA + }, + { + "lobbySearchShowInMatchmaking", + "Lobby Search Param: Show in matchmaking, flag for shown or hidden games", + 0x778CB42E7042F8CB + }, + { + "lobbySearchNetcodeVersion", + "Lobby Search Param: Netcode Version, of the code base", + 0x1B6D149B6BCE7B6D + }, + { + "lobbySearchMapPacks", + "Lobby Search Param: Search for emabled map packs", + 0x5FD32115F3E81D0F + }, + { + "lobbySearchPlaylistVersion", + "Lobby Search Param: Playlist version of session", + 0x71DCDE4E59ACB1DF + }, + { + "lobbySearchPlaylistNumber", + "Lobby Search Param: Playlist number of session", + 0x257D6B84159AE9C8 + }, + { + "lobbySearchServerType", + "Lobby Search Param: Server type of session", + 0x2107859BFDA22E40 + }, + { + "lobbySearchIsEmpty", + "Lobby Search Param: If the session is empty", + 0x420D3B772483054C + }, + { + "lobbySearchTeamSize", + "Lobby Search Param: Team size", + 0x7F60C6CF17A46E6B + }, + { + "lobbySearchSkill", + "Lobby Search Param: Session skill level", + 0x20D4F5D5C347C308 + }, + { + "lobbySearchSkillWeight", + "Lobby Search Param: Session skill level weight", + 0x4BD1AD7AFB19CD88 + }, + { + "lobbySearchGeo1", + "Lobby Search Param: Geographical loc 1", + 0x7F78BBF8409E5E7F + }, + { + "lobbySearchGeo2", + "Lobby Search Param: Geographical loc 2", + 0x7F78BCF8409E6032 + }, + { + "lobbySearchGeo3", + "Lobby Search Param: Geographical loc 3", + 0x7F78BDF8409E61E5 + }, + { + "lobbySearchGeo4", + "Lobby Search Param: Geographical loc 4", + 0x7F78B6F8409E5600 + }, + { + "lobbySearchPingBand", + "Lobby search param: Ping band", + 0x3BD37C49236A4C70 + }, + { + "lobbySearchDediUnparkPingLimit", + "Limit on RTT in milliseconds to a given serverloc we'll consider for unparking", + 0x339E15BDB813DCCB + }, + { + "lobbySearchServerLocation1", + "Lobby search param: Server location 1", + 0x2599C296FF29D0A + }, + { + "lobbySearchServerLocation2", + "Lobby search param: Server location 2", + 0x2599B296FF29B57 + }, + { + "lobbySearchServerLocation3", + "Lobby search param: Server location 3", + 0x2599A296FF299A4 + }, + { + "lobbySearchServerLocation4", + "Lobby search param: Server location 4", + 0x25999296FF297F1 + }, + { + "lobbySearchServerLocation5", + "Lobby search param: Server location 5", + 0x25998296FF2963E + }, + { + "lobbySearchPingBandWeight1", + "Lobby Search Param: Ping band weight1 for dedicated matchmaking query", + 0x786E5B4B359DD833 + }, + { + "lobbySearchPingBandWeight2", + "Lobby Search Param: Ping band weight2 for dedicated matchmaking query", + 0x786E5C4B359DD9E6 + }, + { + "lobbySearchPingBandWeight3", + "Lobby Search Param: Ping band weight3 for dedicated matchmaking query", + 0x786E5D4B359DDB99 + }, + { + "lobbySearchPingBandWeight4", + "Lobby Search Param: Ping band weight4 for dedicated matchmaking query", + 0x786E5E4B359DDD4C + }, + { + "lobbySearchPingBandWeight5", + "Lobby Search Param: Ping band weight5 for dedicated matchmaking query", + 0x786E5F4B359DDEFF + }, + { + "lobbySearchForceLocation", + "If true we'll ignore qos results and only search for sessions in this location", + 0x60A007B37323C55D + }, + { + "lobbySearchDatacenterType", + "Do we look for Gameservers or Thunderhead datacenters?", + 0x1811D3265B27B866 + }, + { + "lobbySearchDatacenterTypeGeo", + "Gameservers/Thunderhead geo-filter", + 0x7AF990C759653E57 + }, + { + "lobbySearchDatacenterTypeOverride", + "Do we look for Gameservers or Thunderhead datacenters - override if != ANY?", + 0x40BF9CEA4DBF2906 + }, + { + "lobbySearchGeo1Weight", + "Lobby Search Param: Geographical loc latitude weight for weighted distance matchmaking queries", + 0x66A0C9D1B5E5E5BB + }, + { + "lobbySearchGeo2Weight", + "Lobby Search Param: Geographical loc latitude weight for weighted distance matchmaking queries", + 0x4C6A5C1204B980DA + }, + { + "lobbySearchGeo3Weight", + "Lobby Search Param: Geographical loc latitude weight for weighted distance matchmaking queries", + 0xB39CA390B7FC7D9 + }, + { + "lobbySearchGeo4Weight", + "Lobby Search Param: Geographical loc latitude weight for weighted distance matchmaking queries", + 0x7C17DF3E855A4940 + }, + { + "lobbySearchMaxLatencyBandDiff", + "Max diff in latency before we reject this host as a possible host", + 0x5C37AB5C77EECFBB + }, + { + "lobbySearchMinDediSearchTime", + "The minimum amount of time required to search/unpark dedi before any listen search", + 0x71372F42FAD45694 + }, + { + "lobbySearchMinDediSearchClientAdd", + "The amount of time added to minimum dedi search/unpark for each party member", + 0x3A5FA123002E0DAD + }, + { + "lobbySearchBaseSkillRange", + "Base skill range for public matchmaking", + 0x1AED798FF3820324 + }, + { + "lobbySearchSkillRangeMultiplier", + "Rate at which skill range increases for each stage retry", + 0x73D85BE005E3364E + }, + { + "lobbySearchForceUnparkLobbySize", + "Party size that will force a dedicated server unpark", + 0x7A3A27C2D1E550D6 + }, + { + "lobbySearchSkipUnparkProbability", + "Probability that we skip unparking", + 0x608CF9277DBC2F6A + }, + { + "lobbySearchSkipDLCProbability", + "Probability we'll search for original maps instead of DLC1", + 0x728AC8324738DCB0 + }, + { + "lobbySearchPingBandEnabled", + "If true set the lobbySearchPingBand value before the search", + 0x398C582C5C1D64D1 + }, + { + "lobbySearchExperimentDatacenter", + "Datacenter to use for pingband experiment", + 0x5449839A25C9ABE9 + }, + { + "lobbySearchForceXuid", + "If set, all search results will be discarded except for specified xuid", + 0x4C7745FD758DB978 + }, + { + "qosPreferredPing", + "QoS preferred ping", + 0x7B331A08D4780C2B + }, + { + "qosMaxAllowedPing", + "QoS max allowed ping", + 0x2D12B3AE4A4BEBB8 + }, + { + "qosLocklessQueue", + "If true we'll queue up qos results locklessly and push them to the VM on the main thread later", + 0x722E69B3B9F428D3 + }, + { + "excellentPing", + "Anything less than this is consider excellent", + 0x19A8F14A21E7424D + }, + { + "goodPing", + "Anything less thant this is considered decent", + 0x38E0DBD8C71F9D10 + }, + { + "terriblePing", + "Just awful, limit of playability", + 0xB2C59B4EE116AEA + }, + { + "lobbyTimerStartInterval", + "Lobby timer interval for start match", + 0x21A227834B17E155 + }, + { + "lobbyCPTimerStartInterval", + "Lobby CP timer interval for start match", + 0x44832F85F8B2FA6A + }, + { + "lobbyCPZMTimerStartInterval", + "Lobby CPZM or Nightmares timer interval for start match", + 0x405CFC2E0315533 + }, + { + "lobbyTimerStatusVotingInterval", + "Lobby timer interval for voting", + 0x4A0A01C39967B404 + }, + { + "lobbyTimerStatusBeginInterval", + "Lobby timer interval for match begin", + 0x18A58F5C4D4B8CBE + }, + { + "lobbyTimerStatusStartInterval", + "Lobby timer interval for match start", + 0x1AEDDAFEB3887F37 + }, + { + "lobbyTimerStatusPostGameInterval", + "Lobby timer interval for post match", + 0x5F28A3041BBCDF83 + }, + { + "lobbyTimerStatusVotingInterval_Arena", + "Lobby timer interval for arena pro voting", + 0x4140BB40F5D43CAC + }, + { + "lobbyTimerZMStartInterval", + "Lobby timer interval for zm start match", + 0x7676A47FE42DA15A + }, + { + "lobbyMapVotePrevMapPlayCount", + "Number of times a previous map cazn be voted for", + 0x2FDE55C3193279A9 + }, + { + "lobby_beginPlay", + "use to signal UI_CoD_KeyEvent to force beginPlay on the Main thread", + 0x66CCDF6439ECB1EF + }, + { + "lobby_readyUpPercentRequired", + "The fraction of the waiting players who need to be ready for a party to start", + 0x8A2424003E8E98A + }, + { + "lobbyProbedXuidOverride", + "How long to check new connecting clients against the probed xuids of already connected clients", + 0x3935876169435D5F + }, + { + "lobby_MatchmakingLoggingLevel", + "0 = off, 1 = all on, etc.", + 0x4E2F4F37C098A2A1 + }, + { + "lobby_MatchmakingLoggingChance", + "Probability of uploading a telemetry event record. Throttle control.", + 0x42170DC52C04ACA5 + }, + { + "ui_lobbyDebugJoinLoc", + "lobby Join debug loc", + 0x4D0BB6AA5A213F17 + }, + { + "ui_lobbyDebugMsgLoc", + "lobby Msg debug loc", + 0x1AA41CEB2A0F867A + }, + { + "ui_lobbyDebugReservationLoc", + "lobby Reservation debug loc", + 0xE4596014B16CF17 + }, + { + "ui_lobbyDebugResCountLoc", + "lobby ResCount debug loc", + 0x33481A4A36A771AC + }, + { + "ui_lobbyDebugAgreementLoc", + "lobby Agreement debug loc", + 0x47EDF2B82532CC4D + }, + { + "ui_lobbyDebugAgreeCountLoc", + "lobby AgreeCount debug loc", + 0x7F0B910B664147FA + }, + { + "ui_lobbyDebugPrivateHostSessionLoc", + "lobby PrivateHostSession debug loc", + 0x194F549185C1A50A + }, + { + "ui_lobbyDebugPrivateClientSessionLoc", + "lobby PrivateClientSession debug loc", + 0x413FCDA52C5CD2BB + }, + { + "ui_lobbyDebugGameHostSessionLoc", + "lobby GameHostSession debug loc", + 0x5B7EA066041EA125 + }, + { + "ui_lobbyDebugGameClientSessionLoc", + "lobby GameClientSession debug loc", + 0x32FF1036F4665D70 + }, + { + "ui_lobbyDebugDWSessionLoc", + "lobby DWSession debug loc", + 0xF527311279E40B4 + }, + { + "ui_lobbyDebugLobbyTasksLoc", + "lobby LobbyTasks debug loc", + 0x67FC6A044DF7E4C9 + }, + { + "ui_lobbyDebugVoiceHostLoc", + "lobby VoiceHost debug loc", + 0x7F992163F8807079 + }, + { + "ui_lobbyDebugVoiceClientLoc", + "lobby VoiceClient debug loc", + 0x4FD12895DE1C7E36 + }, + { + "ui_lobbyDebugPlatformSessionLoc", + "lobby PlatformSession debug loc", + 0x37C37EA31BFE7056 + }, + { + "lpc_forceDownloadFiles", + "Force downloading of files even when they pass the FSCK", + 0x161764104EC9A361 + }, + { + "marketing_enabled", + "Used to turn off/on the marketing mtx comms system", + 0xE0901B68E1F4FF1 + }, + { + "marketing_refreshTime", + "The refresh time for the marketing messsages.", + 0x168B66C54B816252 + }, + { + "marketing_autorefresh", + "Automatically download new messages after reporting any message read", + 0x21FC65B413AD213A + }, + { + "marketing_waitTimeOnLogin", + "Used to enable the wait on fetching marketing messages on login. Time value in ms.", + 0x75DD9083C75B9B66 + }, + { + "constBaseline_allow", + "If true, enable use of const baselines", + 0x4AA780B9C974A68D + }, + { + "net_ip", + "Network IP address", + 0x14BBB153CC56743C + }, + { + "net_port", + "Network port", + 0x3208549148778326 + }, + { + "playlist_debug", + "Enable the debug display for additional playlist information", + 0x5F2487E6FB3C1ECB + }, + { + "playlist_linearMapCycle", + "We will cycle through the maps linearly if this is true.", + 0x8FB704DB4195CBD + }, + { + "playlist_linearMapCycleRandom", + "We will cycle through the maps linearly if this is true but picks a random start map.", + 0x63F3D820E8C560EA + }, + { + "playlist_excludeMap", + "", + 0x6E821F385A3BDAD0 + }, + { + "playlist_excludeGametype", + "", + 0x5D2D4B0CC74E8DD4 + }, + { + "playlist_allowdevmaps", + "Allow maps that aren't in the map/presence table to be selected", + 0x2D295AE4CBA401DB + }, + { + "playlist_forceEvent", + "Force a particular playlist event to be active", + 0x5C6628C09B69B14D + }, + { + "playlist_autoEvent", + "Playlist event currently active as set by the autoevent schedule", + 0x477094C6DDA9299 + }, + { + "playlist_autoEventsEnabled", + "Allow autoevent scheduler to run playlist events", + 0x3A5446A46890E11B + }, + { + "com_profileLoadingForceSend", + "Force Blackbox send after loading done", + 0x4D32C3E41139CD1D + }, + { + "com_smoothFrames", + "Enable frame times smoothing.", + 0x4E0D20851CFAA043 + }, + { + "com_maxclients", + "Maximum amount of clients on the server", + 0x65A2E5EE8014325D + }, + { + "sv_maxclients", + "The maximum number of clients that can connect to a server", + 0x5EC68A2C5682907F + }, + { + "ui_level_sv", + "Load the UI level and start a listen server", + 0x77E97FB748A90E2E + }, + { + "ui_execdemo", + "Show or hide certain options in the UI for demo purposes.", + 0x1E017690F8837DD6 + }, + { + "ui_execdemo_cp", + "Show or hide certain options in the UI for demo purposes, for campaign demos only.", + 0x139AC704E09BFB98 + }, + { + "ui_execdemo_beta", + "Show or hide certain options in the UI for demo purposes, for public beta only.", + 0x242A6A3568FF9F81 + }, + { + "ui_execdemo_gamescom", + "Show or hide certain options in the UI for demo purposes, for gamescom only.", + 0x5F52444CC548D39F + }, + { + "ui_execdemo_gamescom_host", + "Show or hide certain options in the UI for demo purposes, for gamescom host machine only.", + 0x14AEFFF49B0FCC12 + }, + { + "ui_disablePSControlWidgets", + "Disable all the control widgets in PS. This dvar is added for recording video for DPS Demo.", + 0x2619094D06AF4CBF + }, + { + "com_maxfps", + "Cap frames per second", + 0x4A1149C362763AF2 + }, + { + "ui_error_callstack_ship", + "Enable LUI error callstack reporting to show in the UI", + 0x6BBE933116225B20 + }, + { + "ui_timescale", + "Scale time of each frame of LUI animation", + 0x6CFC8AA220A5D8F9 + }, + { + "ui_disable_blur", + "Disable LUI blur", + 0x381EC2D6BD9DBE18 + }, + { + "zombie_devgui", + "", + 0x1C968190FE36E472 + }, + { + "zm_private_rankedmatch", + "Zombies private online match will be ranked and no join in progress is allowed", + 0x48CA6583B1EFAB4B + }, + { + "com_fixedtime_float", + "Use a fixed time rate for each frame", + 0x30831B5184168C87 + }, + { + "long_blocking_call", + "Enable SCR_DrawPleaseWait dialog", + 0x146BF4F090F03BB4 + }, + { + "sv_paused", + "Pause the server", + 0x3F07F66E96FC06C7 + }, + { + "cl_paused", + "Pause the client", + 0x4BF32EA04B74B241 + }, + { + "cl_gamepadCheatsEnabled", + "Enable God and Demigod controller cheats", + 0x68729BCBA76FFC13 + }, + { + "com_sv_running", + "Server is running", + 0x74A8CF2E4D0E6736 + }, + { + "com_forceSVLockStep", + "Only allow the server frame to run when it gets told to by the client thread", + 0x39FFAE4F4746F20E + }, + { + "com_wideScreen", + "True if the game video is running in 16x9 aspect, false if 4x3.", + 0x3E634AF40BAA3108 + }, + { + "log_filename", + "Open log file with a given filename", + 0x39767A2C213B3A67 + }, + { + "showMapErrors", + "Show pointless error message after quitting level", + 0x3B90D40A821362F5 + }, + { + "ui_mapname", + "Current map name", + 0x873561D7387A6D9 + }, + { + "ui_enableAllHeroes", + "Enables all Heroes.", + 0x9E317343EDF4396 + }, + { + "ui_tu11_splitscreen_scoreboard_snap_check", + "Enables a force update of the scoreboard for splitscreen clients on the first snapshot.", + 0x77E1104928E25049 + }, + { + "tu11_maxQuadCacheAlloc", + "Splits up large quadCache allocations into smaller ones, to fix a UI out of memory error with long strings.", + 0x1B1FCFB3B23177D5 + }, + { + "ui_errorUndefLocals", + "Turns on whether LUI will error or warning for undefined local variables.", + 0x296B7991ACA20308 + }, + { + "ui_deadquote", + "", + 0x41ECE7435D602BE + }, + { + "ui_errorMessage", + "Most recent error message", + 0x35C7129C26B55101 + }, + { + "ui_autoContinue", + "Automatically 'click to continue' after loading a level", + 0x51B3A199470FFC52 + }, + { + "ui_playLogoMovie", + "Play the initial loading movie with the company logos", + 0x404C70893D7EA01B + }, + { + "ui_allowDisplayContinue", + "if true, allow the skip button to be displayed during loading cinematic", + 0x725305F6F4755B1C + }, + { + "scr_hostmigrationtest", + "", + 0x17A381319703271E + }, + { + "debug_show_viewpos", + "", + 0x289F07B47495E02E + }, + { + "scr_killcam", + "", + 0x4E9123863104C903 + }, + { + "nextarena", + "", + 0x7472515618429E7 + }, + { + "ClickToContinue", + "", + 0x33060DEBB7B116F3 + }, + { + "saved_gameskill", + "", + 0x1715F21BBCA499A8 + }, + { + "upload_bps_dedicated", + "dedicated server bandwidth req'd", + 0x1EBD3BA96FF47B5A + }, + { + "testMissingContentPacks", + "When the DLC flag changes for a player, sent the result to Demonware.", + 0x443D55B29B2317B6 + }, + { + "addMapPackFlagsUserInfo", + "Send availableMappackFlags out with the User info.", + 0x4259A4A90D12FC5D + }, + { + "missingCommandWillError", + "When true a missing command or config file will cause an ERR_DROP.", + 0x6CEDC002A76A2D4E + }, + { + "doAutoExecDevConfig", + "Exec autoexec developer config files.", + 0x2152755F67286EDF + }, + { + "doAutoExecUserConfig", + "Exec autoexec user config files.", + 0x38DE9F32E6BA54DB + }, + { + "tu6_doublePistolSpreadAmmo", + "Show double ammo in the HUD for pistol spread weapons", + 0x2560E60DB190DF0A + }, + { + "tu9_skipPerlocalClientAllocation", + "", + 0x2A389B201BD3752A + }, + { + "tu10_ClearWeapNextHeldInputOnSwitchWeaponCmd", + "clear cl->weapNextHeld in the SVSCMD_SWITCH_WEAPON response. We should not allow controller input to weapon cycling on the same frame that the server tells us to switch weapons.", + 0x255705FD12C32E19LL + }, + { + "scr_xpscaleCP", + "Controls the xp scaling for CP", + 0x61E39CDFEB605A5D + }, + { + "scr_xpscaleMP", + "Controls the xp scaling for MP", + 0x61F880DFEB7286D3 + }, + { + "scr_xpscaleZM", + "Controls the xp scaling for ZM", + 0x62319BDFEBA279FB + }, + { + "scr_xpscaleZMPromo", + "Controls the xp scaling for the ZM DoubleXP Promo", + 0x5EFDC8092AE5DA76 + }, + { + "scr_vialsAwardedScale", + "Controls how many vials are awarded to the player", + 0x7536E9929D361703 + }, + { + "scr_gunxpscaleCP", + "Controls the gun xp scaling for CP", + 0xC9129B7B2A939CF + }, + { + "scr_gunxpscaleMP", + "Controls the gun xp scaling for MP", + 0xC9735B7B2ADB9E1 + }, + { + "scr_gunxpscaleZM", + "Controls the gun xp scaling for ZM", + 0xCDF40B7B2EB8235 + }, + { + "scr_scorestreaks", + "", + 0x779A6F3044AFFE65 + }, + { + "scr_scorestreaks_maxstacking", + "", + 0x57E72F51FA6FF960 + }, + { + "scr_rampagebonusscale", + "", + 0x60D40843E7CC6090 + }, + { + "scr_disableChallenges", + "", + 0x1E8C2F621BF6361E + }, + { + "scr_disableStatTracking", + "", + 0x62BF0AA3DA13811F + }, + { + "scr_disableSetDStat", + "", + 0x237B114DC8A1EEDE + }, + { + "com_logfile", + "Write to log file - 0 = disabled, 1 = async file write, 2 = Sync every write", + 0x56204B9D7E74AB6D + }, + { + "tu9_highestAvailableDLC", + "Highest DLC to show purchase prompts for. Should be ovewritten in playlists.info when DLC is released", + 0x2C1AA405FFD7FE8E + }, + { + "tu10_enableHighestAvailableDLCEntitlementCheck", + "Enable/Disable the highest available DLC entitlement check.", + 0xA9045D6278B9AB0 + }, + { + "net_broadcast_ip", + "IP address to use for broadcast packets", + 0x1BE72842E3F0F668 + }, + { + "netstats_dummy_tracker_data", + "Turn on dummy random data generation for the netstats tracker", + 0x5032E7C7436812EC + }, + { + "netchan_debugSpew", + "Print very verbose debug info about netchan traffic", + 0x6080BA478FB700F7 + }, + { + "netchan_debugSpewChan", + "If turned on, debug spew for this channel will be displayed", + 0x3554CFC5A2660F2B + }, + { + "netchan_fakeLoad", + "Additional ms lard to add to netchan frame to simulate heavy load / context switch", + 0x755D3806119FB980 + }, + { + "net_emu_latency", + "Emulated network latency in ms", + 0x578086F2DA99CAB3 + }, + { + "net_emu_jitter", + "Emulated network latency jitter in ms", + 0x6A69D4ECF9FE4829 + }, + { + "net_emu_packet_loss", + "Emulated network %% packet loss", + 0x584C87C7E223C767 + }, + { + "net_emu_server", + "Server network emulation info string", + 0x7DB6414CC9DA9F38 + }, + { + "net_emu_client", + "Client network emulation info string", + 0x6526FB7A61BAB7C + }, + { + "streamMBPerSecond", + "Throttle the streamer to the specified megabytes per second", + 0x3FD16FBB21B5CF85 + }, + { + "sv_connectionLogProbability", + "Probability of uploading connection log data.", + 0x2479F0A6D085F098 + }, + { + "sv_connectionLogSamplesPerSecond", + "Number of samples per second per client.", + 0x656231BE534BDD67 + }, + { + "sv_mapname", + "Current map name", + 0x3B7B241B78207C96 + }, + { + "sv_mapcrc", + "crc of the map file", + 0x3C727A79C9E602C9 + }, + { + "cp_queued_level", + "Queued level", + 0x78D438D99BE5C86F + }, + { + "sv_skipto", + "Current skipto", + 0x70FA26C2326002DB + }, + { + "sv_saveGameSkipto", + "Skipto that gets saved to the save game", + 0x1D8621150BCF0C0C + }, + { + "sv_privateClients", + "Maximum number of private clients allowed on the server", + 0x6D4930096BA3E4D4 + }, + { + "sv_privateClientsForClients", + "The # of private clients (we send this to clients)", + 0x12A1B7450A49430D + }, + { + "sv_hostname", + "Host name of the server", + 0x37C96E4191305118 + }, + { + "sv_noname", + "Player name assigned to players that fail name validation", + 0x181B1023195812AD + }, + { + "sv_penetrationCount", + "Maximum number of private clients allowed on the server", + 0xF93473F7D04DCE5 + }, + { + "sv_connectTimeout", + "seconds without any message when a client is loading", + 0x36A999BA53305150 + }, + { + "sv_writeConfigStrings", + "Write out the config string file", + 0x1A5A3BDD393BD184 + }, + { + "scr_writeConfigStrings", + "Special script mode for writing config string files", + 0x46704500104207ED + }, + { + "sv_generateConstBaselines", + "Whether or not to generate the const baseline files.", + 0x3572DBDFC80618CB + }, + { + "sv_cheats", + "Enable cheats on the server", + 0x2F2097BC767C1B1 + }, + { + "sv_sendCmdAngles", + "Send cmdAngles to clients for increased viewangles fidelity during killcam", + 0x6022021F1A5EE5CD + }, + { + "sv_mapRotation", + "List of maps for the server to play", + 0x40285E3E4165AE4F + }, + { + "sv_mapRotationCurrent", + "Current map in the map rotation", + 0x248FA32EBFBBEE40 + }, + { + "sv_rateBoosting", + "Determines whether we should allow rate boosting: 0 - disabled, 1 - enabled based on huristic, 2 - force enabled", + 0x6470CCD761596532 + }, + { + "sv_maxRate", + "Maximum server->client rate", + 0x4E15EFBF1B205C0F + }, + { + "sv_zlib_threshold", + "Message size threshold which triggers more aggressive compression", + 0x3A39BC141F6CD4E0 + }, + { + "sv_timeout", + "seconds without any message", + 0x4056F2DCDC894774 + }, + { + "sv_mapSwitch", + "in-game map switching: 0,disabled|1,enabled|(default)2,enabled but devmap will turn it off", + 0x786D1EF57C183CA1 + }, + { + "sv_potm_debug", + "Debug info for the Play of the Match system", + 0x17ABBB7F8E9C8C87 + }, + { + "migration_blocksperframe", + "Number of blocks to send out each server frame. A value of 0 means base it off our tested bandwidth.", + 0x6A6B27E043217AE2 + }, + { + "migration_msgtimeout", + "timeout time in ms of migration messages", + 0x62859B8FF4AB9C18 + }, + { + "migration_timeBetween", + "milliseconds between migration_limit dvar's value of migrations.", + 0x7AB6A203C9196427 + }, + { + "migration_forceHost", + "force a particular client index to be host.", + 0x48B07629370FF5D9 + }, + { + "migration_soak", + "Soak test the migration. Migrate every migrationTimeBetween milliseconds", + 0x55D2448BFF1A461A + }, + { + "storage_offline", + "Live features are stored locally instead of on Demownare.", + 0x7EF5B59EA5F493E2 + }, + { + "storage_maxfailures", + "Number of failures before maxing out backoff increases.", + 0x53854EF6368F3310 + }, + { + "storage_backoff", + "Base for backing off exponentially", + 0xEE22CA89B1CE239 + }, + { + "loc_availableLanguages", + "", + 0x746B5D9C4A7CE4C0 + }, + { + "loc_language", + "Language", + 0x3A97AE527D90FB24 + }, + { + "loc_systemLanguage", + "System language", + 0x22A8E1B081BE1169 + }, + { + "loc_forceEnglish", + "Force english localized strings", + 0x762BB067CC1A6FF3 + }, + { + "loc_warnings", + "Enable localization warnings", + 0x361B832B45F743AB + }, + { + "loc_warningsAsErrors", + "Throw an error for any unlocalized string", + 0x27B8B7C2DAED657C + }, + { + "loc_languageSaved", + "Has a language value been chosen and saved", + 0x4A833C8D8F59EE5F + }, + { + "st_LODDistScale", + "Distance scale for terrain LOD - when this increases, detail at a given distance is reduced", + 0x3834D608A126064C + }, + { + "ui_emblemDisableGroups", + "Disable the emblem group feature.", + 0x3211555FF0E63362 + }, + { + "ui_creditSkipTo", + "Line number to skip to in the credits?", + 0x47104A72C3388B7B + }, + { + "ui_smallFont", + "Small font scale", + 0x75C89B766727AA1A + }, + { + "ui_bigFont", + "Big font scale", + 0xE3775D5A36206AB + }, + { + "ui_demoname", + "Current selected demo name", + 0x4CB3FA6C5D46BBA8 + }, + { + "ui_liveEventViewerOpen", + "If the liveEventViewer menu is currently open", + 0x5CE320CFE22FBC0 + }, + { + "ui_keyboardtitle", + "", + 0x709BA994593CFF9D + }, + { + "ui_keyboard_dvar_edit", + "", + 0x61FF91986A2313BC + }, + { + "scr_hardcore", + "", + 0x67646047091E1652 + }, + { + "ui_hud_showobjicons", + "", + 0x46ABEE835CBEF546 + }, + { + "ui_hud_obituaries", + "", + 0x31F420F8D8A1D739 + }, + { + "ui_currMenuNameList", + "Current menu name list set in lua, for debug display.", + 0x7FEB365B406388 + }, + { + "ui_currFocusList", + "Current focus stack in lua, for debug display and ship crash dumps.", + 0x3B8B4D0064475D4 + }, + { + "ui_currFocusStates", + "Current focus stack, with states, set in lua, for debug display.", + 0x2196FDA5E89973C6 + }, + { + "ui_usingFreeCursor", + "Turns the free cursor on/off in console builds.", + 0x48E0F129D51A415C + }, + { + "ui_scrollSpeed", + "", + 0x129E807CE7642720 + }, + { + "ui_hud_hardcore", + "Whether the HUD should be suppressed for hardcore mode", + 0x70BBA44D358FF7CC + }, + { + "ui_allow_classchange", + "Whether the UI should allow changing class", + 0x32A7215CE28F3782 + }, + { + "ui_hud_visible", + "Whether the 2D HUD should be displayed or not.", + 0x737582CB19486988 + }, + { + "ls_gametype", + "", + 0x6D55675CD612876F + }, + { + "ls_mapname", + "", + 0x7E247074D08441DA + }, + { + "ui_busyBlockIngameMenu", + "1 if ingame menu should be blocked for pending action", + 0x54488B7C651BD0EC + }, + { + "ui_heatMapColor", + "Heat Map Blob Color", + 0x460242CEAD08594F + }, + { + "ui_heatMapColorForPlayer", + "Heat Map Blob Color for player deaths only", + 0x5BA69E7B82A5FC53 + }, + { + "ui_useloadingmovie", + "Play and render a loading movie instead of static screen (mapname_load)", + 0x7BD8C108B14CF06B + }, + { + "ui_badWordSeverity", + "1 to block partial and full profanity matches, 2 to only block full matches", + 0x6339CAD319524344 + }, + { + "ui_badWordMaxTaskWaits", + "The number of cycles *10 ms for a remoteTask before we decide to cancel the isBadWord task", + 0x2052CA8D71E32144 + }, + { + "ui_friendsListOpen", + "True when viewing Friends List.", + 0x1F305A5C795ADA5D + }, + { + "mp_prototype", + "Enabled T8 prototype features (int because this was used as a command line int-only property)", + 0x5D15C63764CE79B9 + }, + { + "ui_autoControlledPlayer", + "Enables the player to select a ui option to transfer the player's control to Bot", + 0x1A94323F2C9E094C + }, + { + "blackboxMode", + "", + 0x44F8B711C6A78FFA + }, + { + "cg_drawFramePerformanceWarnings", + "Draw onscreen timers for client, server, and gps if they exceed their frame budgets.", + 0x5F9C1EEA7170D2E + }, + { + "devmaponline", + "devmap into online mode", + 0x5A76FEC4DAB557D1 + }, + { + "phys_player_step_on_actors", + "phys_player_step_on_actors", + 0x4C1224C82006E50D + }, + { + "snd_losOcclusion", + "occlusion based off of LOS", + 0x78C926CA413487C2 + }, + { + "ui_drawCrosshair", + "Whether to draw crosshairs.", + 0x3147A8F5BF451AA6 + }, + { + "voice_enabled", + "Voice communication enabled", + 0x52A69EB47F9E465F + }, + { + "cg_fov_default", + "User default field of view angle in degrees", + 0x57ED85B05E9BCDB9 + }, + { + "compassFriendlyHeight", + "The size of the friendly icon on the compass", + 0x1F5D7DB9E25EC97F + }, + { + "compassFriendlyWidth", + "The size of the friendly icon on the compass", + 0x44D392B641449348 + }, + { + "cg_weaponCycleDelay", + "The delay after cycling to a new weapon to prevent holding down the cycle weapon button from cycling too fast", + 0x4EB1835CF0F023D + }, + { + "cl_packetdup", + "Enable packet duplication", + 0x7F3427FA1A7374C8 + }, + { + "debug_audio", + "Enables debug rendering for audio.", + 0x3A868AD5FB0774F9 + }, + { + "debug_mover", + "Turns on mover debug mode", + 0x1DE09BE0EE1A8012 + }, + { + "demo_drawdebuginformation", + "Used to draw debug information.", + 0x5D02584AB86AA8C2 + }, + { + "g_reviveTime", + "The time it takes to revive a player in last stand (do not change as it is tied to the third person animations)", + 0x6F1B1794F8F39B93 + }, + { + "slide_subsequentSlideScale", + "Percent the slide speed should be scaled down by per subsequent slide", + 0x1B823EBA6DD7C7CB + }, + { + "player_swimSprintSpeedScale", + "Scale the swim speed by this amount when sprinting", + 0x7DB976AB518CA222 + }, + { + "melee_attachmentMultiplier", + "If the melee attachment is equipped, the melee base damage is multiplied by this amount", + 0x2A89C38ADF39A3EA + }, + { + "tm_taskTrackerOn", + "If true, tasks will be tracked by the tracking system", + 0x2AB491F3E86C44DF + }, + { + "tm_taskManagerDebug", + "Shows more information as the number is increased", + 0x716C5A7404912A18 + }, + { + "tm_startedThreshold", + "If this many tasks of a single definition are started, a warning message will pop-up.", + 0x1FB1BC2C2EFCEE0F + }, + { + "tm_failsThreshold", + "If this many tasks of a single definition fail, a warning message will pop-up.", + 0x3CA374003C95549B + }, + { + "tm_succeedsThreshold", + "If this many tasks of a single definition succeed, a warning message will pop-up.", + 0x4EA659694387C23D + }, + { + "tm_pendingeThreshold", + "If this many tasks of a single definition are concurrently pending, a warning message will pop-up.", + 0xD5441818C92A64 + }, + { + "tm_typeToDisplay", + "Chooses which type of task to display in the log", + 0x27835F42462F0E68 + }, + { + "tm_logTimeLimit", + "In seconds, how long should pass before an event is shown in the log", + 0x2247CB6C6F557F3D + }, + { + "tm_currentErrorPage", + "In seconds, how long should pass before an event is shown in the log", + 0x632902C39A5AA12D + }, + { + "sv_cheats", + "External Dvar", + 0x2F2097BC767C1B1 + }, + { + "allClientDvarsEnabled", + "Allow host to set all client dvars", + 0x60C8FCA8AB2A735C + }, + { + "profileDwUpdateInterval", + "Interval (in seconds) between updating recorded performance information in DW (negative value disable recording)", + 0xE8DC9F4D91759DF + }, + { + "reliableResendTime", + "Amount of time (in ms) to wait before resending an unack'd reliable message", + 0x22B6677D5D184B9 + }, + { + "reliableTimeoutTime", + "Amount of time (in ms) to wait before timing out a client for not ack'ing a message", + 0x3FDFE198FF2CC267 + }, + { + "phys_gravity", + "Physics gravity in units/sec^2.", + 0x569DC74596BBB254 + }, + { + "phys_gravity_dir", + "Sets the gravity direction.", + 0x4B6BB42074C7A840 + }, + { + "phys_buoyancy", + "Used to turn on/off buoyancy", + 0x75CEE65DE741344 + }, + { + "phys_ragdoll_buoyancy", + "Used to turn on/off the buoyancy for he ragdolls", + 0x2DAC8B2B9D305718 + }, + { + "phys_disableEntsAndDynEntsCollision", + "Disable rigid body collision with dyn ents and regular entities as an optimization. Vehicles do not apply.", + 0x24FE8BEB1C5AD1D6 + }, + { + "enable_moving_paths", + "enable moving paths", + 0x214D5952AABA3E6A + }, + { + "enable_new_prone_check", + "enable new prone check", + 0x3C40F1AD7C84AAB9 + }, + { + "phys_wind_enabled", + "Used to turn off/on physics wind sim", + 0x60A2BCF45461E9CA + }, + { + "phys_wind_vehicle_scale", + "Scale the vehicle wind reactions by this value", + 0x3EDB64F8EFE5F48E + }, + { + "snd_speakerConfiguration", + "Speaker configuration", + 0x53BB4B101A1369B8 + }, + { + "glassDamageMultiplier", + "Multiplier the damage applied to the glass (server).", + 0x4B8A7BB010C32F6D + }, + { + "maxAIGlassHits", + "Maximum number of hits it takes an AI to break the glass.", + 0x23AEA643B2775AD7 + }, + { + "demo_enabled", + "Used to turn the system on/off.", + 0x561CEAA988616530 + }, + { + "demo_recordPrivateMatch", + "Used to turn the private match recording on/off.", + 0x67284532BECB20B2 + }, + { + "demo_recordSystemlinkMatch", + "Used to turn the systemlink match recording on/off.", + 0x27E3565C7550EDF0 + }, + { + "demo_recordOfflineMatch", + "Used to turn the offline match recording on/off.", + 0x5BFDFC14138D3B06 + }, + { + "demo_debug", + "Debug info for the Server Snapshot Demo system", + 0x1E197923F31FE4A2 + }, + { + "demo_client", + "Current viewing player", + 0x72DE091D1D0C2B8C + }, + { + "demo_recordingrate", + "Used to tweak the rate(in msec) at which we write a super snapshot", + 0x2772FD9F0557FBF4 + }, + { + "demo_fileblockWriteRate", + "Used to tweak the rate(in sec) at which we write the file blocks during demo recording", + 0x3266962B55BCDEF + }, + { + "demo_keyframerate", + "Used to specify the rate(in sec) at which we generate a keyframe during playback.", + 0x104BE62213ED4629 + }, + { + "demo_pause", + "Used to pause a demo playback.", + 0x2FF56845FD43D403 + }, + { + "demo_pauseOnNextSnapshot", + "Used to jump to the next snapshot during network analysis.", + 0x5B081E0BCDCD8993 + }, + { + "demo_maxTimeScale", + "The maximum timescale rate we will support.", + 0x665BE4626D4D30D0 + }, + { + "demo_downloadEntireFile", + "Used toggle the ability to download the entire file instead of parts.", + 0x2A048F122F8470A0 + }, + { + "demo_livestreaming", + "Used to turn the live streaming system on/off", + 0x4B22DC55CD99A0CF + }, + { + "demo_downloadLiveStreamThrottleTime", + "The maximum amount of time (in msec) we can starve the download of live stream callback.", + 0x562235A0A6CFE3DC + }, + { + "demo_summaryReadEnabled", + "Used to turn meta summary read on/off", + 0xE1DEC861F6BF51E + }, + { + "demo_writePaintShopInformation", + "Used to turn on/off the paintshop data write into the demo file", + 0x4BD70EF582CFA310 + }, + { + "demo_bookmarkEventThresholdTime", + "The time duration for which we want to show the bookmark event image in the demo timeline.", + 0x39E372A043D4A591 + }, + { + "demo_freeCameraLockOnOrbitRadius", + "Radius of the lockon orbit.", + 0x11D58469A34F979E + }, + { + "demo_highlightReelPlayerFilter", + "Demo Highlight Reel player filter control", + 0x5FF295469C16F65A + }, + { + "demo_highlightReelTransitionFilter", + "Demo Highlight Reel transition filter control", + 0x102761C252F95DF4 + }, + { + "demo_highlightReelStylesFilter", + "Demo Highlight Reel styles filter control", + 0x592196442EA9D201 + }, + { + "demo_highlightReelNumberOfSegments", + "Demo Highlight Reel number of segments", + 0x795C6EE8CF31F403 + }, + { + "demo_highlightReelMinimumStarsFilter", + "Minimum stars used for the filtering of events in the highlight.", + 0x5FA6C62A685B3352 + }, + { + "demo_highlightReelGameResultFilter", + "Demo highlight reel round outcome filter.", + 0x27F56CCA950310C0 + }, + { + "demo_packetsPerSecondMin", + "Min amount of packets to send per second before throttling.", + 0x6771EE54572E19ED + }, + { + "demo_bytesPerSecondMin", + "Min amount of bytes to send per second before throttling.", + 0x43ECC22C3CD4C007 + }, + { + "demo_packetsPerSecondMax", + "Max amount of packets to send per second before throttling.", + 0x6756D85457172CD3 + }, + { + "demo_bytesPerSecondMax", + "Max amount of bytes to send per second before throttling.", + 0x4407B02C3CEB6929 + }, + { + "demo_inLobbyThrottleBandwidthPercent", + "Bandwidth percent to be released when we are not going to throttle in the lobby.", + 0x531AE3C9B8F3E1EA + }, + { + "demo_inGameThrottleBandwidthPercent", + "Bandwidth percent to be released when we are not going to throttle inside the game.", + 0x647D504203ADF4A4 + }, + { + "demo_streamingAdjustmentFactor", + "The adjustment factor for howScrewedAreWe in the streaming.", + 0x55FF38576DFA03C9 + }, + { + "demo_enableSvBandwidthLimitThrottle", + "Used to enable the server bandwidth based throttling system.", + 0x324732789DCF2EDD + }, + { + "demo_svBandwidthLimitThrottleMaxBytesPercent", + "The percentage of the max. bandwidth per frame within which we want to apply the throttle.", + 0x6E6DD67487DD3964LL + }, + { + "demo_svBandwidthLimitThrottleTimeout", + "The maximum amount of time (in msec) we can starve the write to stream callback, due to the server hitting the maximum bandwidth limit per frame.", + 0x61B1FD239D69A10DLL + }, + { + "demo_streamingSendSocketBuffSizeForRecording", + "The send socket buffer size which will be used for recording", + 0x15A37D18D6A1B438 + }, + { + "demo_streamingSendSocketBuffSizeForOtherUploads", + "The send socket buffer size which will be used for other uploads", + 0x56E207A2D8B2E2B1 + }, + { + "demo_downloadStreamThrottleTime", + "The maximum amount of time (in msec) we can starve the download stream callback.", + 0x3CF9A5CF8FF93606 + }, + { + "demo_downloadStreamRetryWaitTime", + "The maximum amount of time (in msec) we will have to wait before we retry the download.", + 0x20B2FAE4FB152DDF + }, + { + "demo_downloadStreamMaxRetryAttemps", + "The maximum number of retry attempts before we mark the downloadstream as failed..", + 0x18CECC6FF1929FF1 + }, + { + "perk_weapReloadMultiplier", + "Percentage of weapon reload time to use", + 0x4458F4E852DB0E55 + }, + { + "perk_killstreakReduction", + "Reduced number of kills required to obtain a killstreak.", + 0x30DB5C3D6375C831 + }, + { + "perk_killstreakMomentumMultiplier", + "Multiplies the amount of momentum received by the player", + 0x52BCDEC14ED72605 + }, + { + "perk_killstreakAnteUpResetValue", + "Scorestreak reset value when the ante up perk is in use.", + 0x2D6BDF06C07C91FD + }, + { + "perk_delayExplosiveTime", + "Time in seconds to delay a proximity explosive", + 0x62D6967E8CA82E61 + }, + { + "perk_disarmExplosiveTime", + "Time in seconds to disarm a proximity explosive", + 0x63DA9311C0D217AA + }, + { + "perk_deathStreakCountRequired", + "Number of deaths required to obtain a deathstreak.", + 0x7C155EA09F9D8070 + }, + { + "perk_healthRegenMultiplier", + "Multiplier to the time which the player starts to regenerate health after damage", + 0x7B66853FFF18AF66 + }, + { + "perk_flakJacket", + "Percent of explosive damage done that will apply to player.", + 0x3EAF6A2850D1FCCE + }, + { + "perk_flakJacket_hardcore", + "Percent of explosive damage done that will apply to player in hardcore.", + 0x70CF0DA8B63FB1D9 + }, + { + "perk_fireproof", + "Percent to reduce flame damage done to the player.", + 0x23FF287409E487B4 + }, + { + "perk_gpsjammer_min_speed", + "Minimum speed a player must be moving for gpsjammer to protect them from UAV sweeps. Based on player speed used in g_speed (I believe this is units/sec). If 0, player will always be protected from UAV sweeps with this specialty.", + 0x57DB5142A091AE9DLL + }, + { + "perk_gpsjammer_min_distance", + "Minimum distance a player must have moved in a time period for gpsjammer to protect them from UAV sweeps. If 0, player will always be protected from UAV sweeps with this specialty.", + 0x162F55DAA69B421LL + }, + { + "perk_gpsjammer_time_period", + "Time period inbetween checks, in MSec. Please use multiples of 50 msec as that is the period of server script ", + 0x66B53538163C5622 + }, + { + "perk_gpsjammer_graceperiods", + "Number of time period a player can be below the required velocity before removing protection.", + 0x5D3C723F26B11B75 + }, + { + "perk_sgjammer_min_speed", + "Minimum speed a player must be moving for gpsjammer to protect them from Sensor Grenade sweeps. Based on player speed used in g_speed (I believe this is units/sec). If 0, player will always be protected from Sensor Grenade sweeps with this specialty.", + 0x4A76E168621E07D7LL + }, + { + "perk_sgjammer_min_distance", + "Minimum distance a player must have moved in a time period for gpsjammer to protect them from Sensor Grenade sweeps. If 0, player will always be protected from UAV sweeps with this specialty.", + 0x6FF59096FF8B6487LL + }, + { + "perk_sgjammer_time_period", + "Time period inbetween checks, in MSec. Please use multiples of 50 msec as that is the period of server script ", + 0x75B67E026EB962B4 + }, + { + "perk_sgjammer_graceperiods", + "Number of time period a player can be below the required velocity before removing protection.", + 0x5E68178D11E9D667 + }, + { + "perk_nottargetedbyai_min_speed", + "Minimum speed a player must be moving for nottargetedbyai to protect them from AI controlled killstreaks. If 0, player will always be protected from AI controlled killstreaks with this specialty.", + 0x47982F834510FFFBLL + }, + { + "perk_nottargetedbyai_graceperiod", + "Time after which the player drops below min_gpsjammer_speed that they are still protected from ai support targetting. 0-10000 int (in milliseconds), 0 default.", + 0x42A7884708587E8ALL + }, + { + "perk_tracker_fx_foot_height", + "Height of footsteps for tracker perk.", + 0x56DE6E0B6C136484 + }, + { + "perk_tracker_fx_fly_height", + "Height of flying markers for tracker perk.", + 0x4A3DF32AEBF30903 + }, + { + "enable_global_wind", + "enable wind effect", + 0x76C3F9094AEEF287 + }, + { + "enable_grass_wind", + "enable grass wind effect", + 0x350A9A0FDAFE92BE + }, + { + "wind_global_vector", + "global wind force in units/sec. This is also the hi-level wind", + 0x52F7C1DFF8F57DCF + }, + { + "wind_global_low_altitude", + "altitude of global low-level wind", + 0x67FA4884FE9A2BE9 + }, + { + "wind_global_hi_altitude", + "altitude of global hi-level wind", + 0x2048DC9AD2E7D6EA + }, + { + "wind_global_low_strength_percent", + "strength of global low-level wind, expressed as a percentage of wind_global_vector", + 0x262DB7094325F8BC + }, + { + "wind_leaf_scale", + "global wind grass tension (stiffness)", + 0x5945330E01E3D861 + }, + { + "wind_grass_gustinterval", + "global wind force gust interval", + 0x6F2BE374CBBF4099 + }, + { + "wind_grass_scale", + "global wind force scaler", + 0x34A90FB9F8A09F27 + }, + { + "wind_grass_tension", + "global wind grass tension (stiffness)", + 0x290FCF75EFEB5373 + }, + { + "wind_grass_gust_speed", + "speed multiplier for gusts", + 0x664AC6A4D7D61778 + }, + { + "wind_grass_gust_radius", + "size of global wind gust effector", + 0x5648FE2DCB2B8F8B + }, + { + "wind_grass_gust_distance", + "max distance at which to place gusts", + 0x2C6E04600BBE184A + }, + { + "aim_target_closest_first", + "Target the closest AI based on 3d distance", + 0x419BA7D17BB018C7 + }, + { + "aim_autoaim_enabled", + "Turn on auto aim", + 0x2DE12E2AFE23ADCF + }, + { + "bg_viewKickScale", + "The scale to apply to the damage done to caluclate damage view kick", + 0x4BF878D35CAD6F8A + }, + { + "bg_viewKickMax", + "The maximum view kick", + 0x393CD911FFBB3B46 + }, + { + "bg_viewKickMin", + "The minimum view kick", + 0x3921CB11FFA45BC4 + }, + { + "bg_viewKickDeflectTime", + "The random direction scale view kick", + 0x268E1E3AA428B72A + }, + { + "bg_viewKickRecoverTime", + "The random direction scale view kick", + 0xAE16241B8D06F6D + }, + { + "bg_viewKickScaleAds", + "The scale to apply to the damage done to caluclate damage view kick", + 0x298FEF62A5A1CCB4 + }, + { + "bg_viewKickMaxAds", + "The maximum view kick", + 0x7BF23BA0928AC620 + }, + { + "bg_viewKickMinAds", + "The minimum view kick", + 0x55C59F681B31E1F6 + }, + { + "bg_viewKickDeflectTimeAds", + "The random direction scale view kick", + 0x5BC2B1A69CB282D4 + }, + { + "bg_viewKickRecoverTimeAds", + "The random direction scale view kick", + 0x672E3C15A41C1C69 + }, + { + "bg_scriptCanDisableStances", + "Whether script is allowed to disable stances", + 0x138E0DBBCCF56F1B + }, + { + "bg_useThrowButtonForDetonatorGrenades", + "Whether the throw button should be returned as the fire button for grenades and mines that have a detonator", + 0x87286E123370AC4 + }, + { + "bg_heavyWeaponsAlwaysPlayFirstRaise", + "Always play the first raise animation when switching to heavy weapons", + 0xF8628384A6BF6F2 + }, + { + "player_useWaterFriction", + "Change the players walk friction when in water, using water friction scales", + 0x8932E7EFEE3D6CD + }, + { + "player_useWaterWadeScale", + "Scale the players command based on their depth in the water", + 0x327565589F891CD6 + }, + { + "bg_friendlyFire", + "Friendly fire status", + 0x225326DCF1D8C634 + }, + { + "bg_friendlyFireMode", + "Enables friendly fire mode, cannot shoot down friendlies at close range", + 0x4D80B80B9ED81737 + }, + { + "bg_grenadeMinimumThrowbackTime", + "Time added to grenade countdown to stop it from blowing up during throwback.", + 0x3E6D6D1E70394899 + }, + { + "bg_weaponCompatibleIfSharedAmmo", + "Allow leeching ammo from weapons touched on the ground if the player has a weapon with matching shared ammo", + 0x2E6A89AD001FE5A9 + }, + { + "disableLookAtEntityLogic", + "Disables the Player_UpdateLookAtEntity logic (expensive)", + 0x5CF9AE63F3BFE638 + }, + { + "player_lastStandBleedoutTime", + "The time taken by the player to completely bleedout when in last stand (pro version).", + 0x414B968F85361F6 + }, + { + "player_lastStandDistScale", + "Tweaks some of the movement in last stand.", + 0x6EEEC609104F37FF + }, + { + "player_ProneMinPitchDiff", + "Minimum pitch difference allowed to move in prone.", + 0x6D16F2F249198008 + }, + { + "player_ProneLaststandFreeMove", + "Allow freer movement in last stand than normal prone movement", + 0x29E2C87F14934BC + }, + { + "player_lastStandCrawlTransition", + "Transition to the last stand crawl set, and not regular last stand animation", + 0x429EB921B546A6F1 + }, + { + "bg_useT7Melee", + "use the T7 melee system.", + 0x2A78F8D99222AC09 + }, + { + "player_meleeChargeMaxSpeed", + "Max speed to clamp when doing a charge melee", + 0x4F0998E4E4BA6BB6 + }, + { + "player_meleeChargeMinSpeed", + "Min speed to clamp when doing a charge melee", + 0x7A62D62E37F7A5F0 + }, + { + "player_meleeLungeAcceleration", + "Dvar to control the acceleration for the lunge attack", + 0x94D4FAB8CE278AE + }, + { + "player_meleeLungeUnderwaterSpeedScale", + "Scaler for the underwater lunge speed", + 0x3FF643A885AAEB28 + }, + { + "player_meleeLungeSpeedCutoff", + "Cutoff the lunge attacks if the velocity falls bellow this value", + 0x34414D4498355154 + }, + { + "player_meleeLungeTimeCutoff", + "Max duration of the lunge attack", + 0x1946DDA26B1162B2 + }, + { + "vehicle_riding", + "Turning this on enables players to walk around on top of vehicles", + 0x559448DC6708AFDD + }, + { + "vehicle_selfCollision", + "Enabled the vehicle to shoot itself with it's own turret.", + 0x43496C21C39056FA + }, + { + "tu11_IgnoreItemsWithPLevel100InIsItemLockedForChallenge", + "Treats items with PLevel 100 or more as never unlocked in IsItemLockedForChallenge().", + 0x6C09B0BFF51AC81C + }, + { + "bg_disableWeaponPlantingGroundTrace", + "Disables the ground trace check for weapon planting.", + 0x4392DE0CF30D6CCE + }, + { + "slide_forceBaseSlide", + "Force the player to use the base slide, do not allow boost reduced or boost", + 0x4C6022373CF3066C + }, + { + "actors_walkable", + "Players can walk on AI without sliding off", + 0x125B4A64B58DC66D + }, + { + "trm_enabled", + "Enable or disable the player's mantle", + 0x54E4287F98A644F4 + }, + { + "juke_enabled", + "Enable player evasive move", + 0x30BC3CBFB08B248A + }, + { + "sprint_capSpeedEnabled", + "Enable physics cap on speed during sprinting", + 0x234789E28481E1D2 + }, + { + "weaponrest_enabled", + "Enable weapon rest, player turns gun so that it does not appear to intersect geo", + 0xA92A344E2E38925 + }, + { + "traverse_mode", + "1 = new traversal 2 = pre-BO3 mantle system", + 0x6C71BF6810FA346F + }, + { + "sprint_allowRestore", + "Restore the players sprint state after certain actions, wallrun, traverse etc. ", + 0x62FA420611F210F3 + }, + { + "bg_weaponSwitchHero", + "The HeroWeaponType to switch to on a press of button WEAPON_SWITCH_HERO.", + 0x2F5602FEACAEB597 + }, + { + "bg_specialOffhandInventorySwitch", + "The HeroWeaponType to switch to on a press of button OFFHAND_SPECIAL.", + 0x641EB1218246D20A + }, + { + "bg_specialOffhandInventoryAllowBallSwitch", + "When true the special offhand input switch to inventory weapon allows ball switch.", + 0x1BA8872A25A6A67A + }, + { + "friendlyContentOutlines", + "Use this to enable the outlines on friendlies and disable the icons", + 0x7F6CF93A7A55D6A8 + }, + { + "player_dpad_gadget_scheme", + "Dpad gadget control scheme, 0 - mp system, 1 - career mode (dapd controls 3 gadgets)", + 0x57ABDD7E4A691B01 + }, + { + "compassObjectiveIconWidth", + "The size of the objective on the full map", + 0x2127B85AA4AD5C49 + }, + { + "compassObjectiveIconHeight", + "The size of the objective on the full map", + 0x623281D39B08B738 + }, + { + "compassDrawLastStandIcon", + "Draw the last stand icon on the minimap", + 0x58369F73B6EF74AE + }, + { + "waypointOffscreenPadLeft", + "Offset from the edge.", + 0x16611D1C3A11368D + }, + { + "waypointOffscreenPadRight", + "Offset from the edge.", + 0x5E8218284D9BB186 + }, + { + "waypointOffscreenPadTop", + "Offset from the edge.", + 0x50694F1B92EB913F + }, + { + "waypointOffscreenPadBottom", + "Offset from the edge.", + 0xBC868C8D709B137 + }, + { + "cg_aggressiveCullRadius", + "The radius to use for entity CG_ProcessEntity frustrus culling. 0 means disabled.", + 0x72E5D4F083B92862 + }, + { + "slam_blur_enabled", + "Is screen blur enabled for slam", + 0x58950029C9E7384A + }, + { + "cg_drawBreathHint", + "Draw a 'hold breath to steady' hint", + 0x4825068A6A96C54D + }, + { + "cg_hudDamageIconTime", + "The amount of time for the damage icon to stay on screen after damage is taken", + 0x4B30A71B20B23194 + }, + { + "cg_crosshairVehicleSentientCheck", + "Whether to show colored crosshairs when targetting vehicles iff sentient exists", + 0x44548156F075E666 + }, + { + "cg_updateScoreboardAfterGameEnded", + "Controls whether to update or freeze the scoreboard when the game ends.", + 0x44C35D5960CC531B + }, + { + "cg_DrawRemoteVehiclePlayerNames", + "Player's gamertag displayed above remote controlled vehicles", + 0x7C1B72369DF3CBC7 + }, + { + "cg_DrawPlayerNamesWhileInVehicle", + "Player's gamertags are displayed to player who is in vehicle", + 0x650C3842D88563E7 + }, + { + "cg_DrawOnlyFriendlyPlayerNamesWhileInVehicle", + "Only Friendly Player's gamertags are displayed to player who is in vehicle", + 0x241E40FA8E872528 + }, + { + "cg_DrawOnScreenFriendlyAI", + "Draws all friendly AI names who are currently on screen.", + 0x63FDE83AC1820602 + }, + { + "cg_thirdPersonLastStand", + "Uses the third person view when the player is in laststand.", + 0x3EB163CDE8DA7ACC + }, + { + "cg_WeaponButtVictimCameraShakeScale", + "Scale of the camera Shake applied to a weapon butt Victim.", + 0x5AC135B499C4483A + }, + { + "cg_WeaponButtVictimCameraShakeDuration", + "Duration in milliseconds of the camera Shake applied to a weapon butt Victim.", + 0x465C02A95F508068 + }, + { + "cl_dpadLeftHeavyWeapon", + "When true player switches to the inventory weapon when pressing dpad left.", + 0x3D5BCFA1163E653E + }, + { + "cl_bspmismatchFatal", + "If true client will ERR_DROP if its BSP doesn't match the server's", + 0x39FEE69EFD4711F2 + }, + { + "cl_bitfieldmismatchFatal", + "If true client will ERR_DROP if its bitfield doesn't match the server's", + 0xC266A8932CF9CEC + }, + { + "dynEnt_disable_rb_collision", + "Disable rigid body collision for dyn ents with point or hinge constraints.", + 0x1AAD2B07AF7736D4 + }, + { + "dynEnt_small_cylinder_dimension", + "Treats dyn ents with small cylinders less than this number in the X or Y as small for the purposes of angular velocity. Applies to dyn ents with point or hinge constraints. Set to 0 to disable.", + 0x61292D4020F08F5BLL + }, + { + "dynEnt_delete_expensive", + "Delete expensive dyn ents.", + 0x4D979C5083D355F + }, + { + "g_pickupPromptsForDroppedWeapons", + "Whether dropped weapons allow a pickup prompt", + 0x17F313F6BB56ABAE + }, + { + "ai_avoidNavBoundaries", + "enables/disables the nearby boundary avoidance", + 0x1F2AEA7F8944E6A4 + }, + { + "ai_codeGameskill", + "Use code based gameskill buildup accuracy instead of script's implementation.", + 0x646A06A52703219C + }, + { + "ai_secondaryThreats", + "Allow secondary targets", + 0x272F8D946AE3E82F + }, + { + "player_throwbackOuterRadius", + "The radius player is allow to throwback a grenade once the player has been in the inner radius", + 0x5EAF4E0C0373CE31 + }, + { + "player_useRadius", + "The radius within which a player can use things", + 0x1194DB96AF781D52 + }, + { + "player_useTouchScore", + "The touch score for player use checks", + 0x3AE4FFCB7525206F + }, + { + "g_avoidEnabled", + "Disable the vehicle avoidance", + 0x6420FE8F4634BCC1 + }, + { + "g_throttleTempEnts", + "Whether to throttle the number of temp ents created", + 0x3D8266A7CC590A3B + }, + { + "g_allowLastStandForActiveClients", + "Whether last stand is possible by default for active clients", + 0x53E6EECA9F56D0BF + }, + { + "dynEnt_shouldCullEntitiesForSplitscreen", + "Cull alternating entities in splitscreen", + 0x3ABAC99330C30387 + }, + { + "spawnsystem_sight_check_sentient_ai", + "Consider AI sentients while evaluating spawnpoint visibility", + 0x68475AF4558AFA16 + }, + { + "r_splitscreenBlurEdges", + "Turns on blurring the side edges in splitscreen", + 0x189B2FBABA6985FF + }, + { + "r_maxSpotShadowUpdates", + "Set the number of spot &omni shadow updates per frame (each omni light account for 6 updates)", + 0x3D8DDE2C8465F2A + }, + { + "ai_generateNavmeshRegions", + "Generate navmesh regions.", + 0x4E13CC2C0E16356A + }, + { + "useClassSets", + "Enable class sets", + 0x23E5A4387FF1BAE5 + }, + { + "com_pauseSupported", + "Whether is pause is ever supported by the game mode", + 0x72369C90B4ADFCC7 + }, + { + "gts_validation_enabled", + "Enables gametype settings validation in online modes", + 0x2882717B2065EA05 + }, + { + "path_checkDangerousNodes", + "Whether to mark and check dangerous nodes", + 0x15A1D9FE7E66AE48 + }, + { + "path_alwaysFindNearestNode", + "Use to force finding some nearest node in, generally to try to ensure getting close enough to melee", + 0x772A87292B07D429 + }, + { + "path_boundsFudge", + "Fudge the size of the ai's bounds when finding the nearest node", + 0x1883E5500901F485 + }, + { + "path_minzBias", + "Bias to prevent missing valid cells below the origin", + 0x430BA728A48A5E4 + }, + { + "path_double_wide_checks", + "Whether to do double wide checks when finding a start node for a pathfinding check", + 0x379B878A381D53E0 + }, + { + "ui_keepLoadingScreenUntilAllPlayersConnected", + "Whether to keep the loading screen up until all players have initially connected", + 0x40811D6D0A69715D + }, + { + "upload_bps_demosystem", + "demo system bandwidth req'd", + 0x5D47051C209221EF + }, + { + "upload_bps_perplayer", + "per player bandwidth req'd", + 0x315659FEDA74DD21 + }, + { + "sv_antilagAnim", + "Rewind animations during antilag rewind", + 0x1294D23BCA5F2FE6 + }, + { + "g_gametype", + "Current game type", + 0x1FF54369D6573B91 + }, + { + "migration_minclientcount", + "Minimum real client count, below which the host will not migrate.", + 0x58BFAAB543C1D66 + }, + { + "migration_limit", + "maximum number of migrations within migration_timeBetween dvar's value in milliseconds.", + 0x434E1DE25E9449DF + }, + { + "phys_usePhysicsForLocalClientIfPossible", + "Use the client physics simulation for the local vehicle if possible instead of the server snapshots", + 0x444A7FAD68CB733B + }, + { + "tu10_cleanupRagdollsOnExit", + "Cleanup ragdolls on shutdown.", + 0x11A578FDEE103601 + }, + { + "tu11_cleanupRagdollsOnDemoJump", + "Cleanup ragdolls on demo jump.", + 0x461D77AAA527E2FD + }, + { + "demo_dollycamLeaveAtPreviousMarker", + "Whether to place the camera at the previous dolly cam marker when leaving the mode.", + 0x2A8C932E8F7EEE21 + }, + { + "demo_freeCameraUseHeliHeightLockAsCeiling", + "Whether to treat the heli_height_lock as a ceiling.", + 0x4EA01EB65008EC48 + }, + { + "demo_freeCameraLockOnMissileAllowed", + "Whether missile entities are eligible for lockon", + 0x2DDDF1803E519648 + }, + { + "demo_streamUploadKeepAliveFrequency", + "Specifies the frequency that we send the keep alive on the upload connection if we are otherwise starved for data to send (0 means not in use), used mainly to account for pause.", + 0x357723BC86B953BALL + }, + { + "demo_oldposInsteadOfMapCenter", + "Use the oldpos instead of CL_GetMapCenter() when in freecam", + 0x29023B1D815E0BD8 + }, + { + "demo_filmStartInformationScreenStayTime", + "How long the film start information screen will stay on screen in ms.", + 0x1727557D9DA1919F + }, + { + "demo_viewTraceMask", + "The contents mask to use for view traces.", + 0x412217DB434E3CB7 + }, + { + "demo_useMapNameAsDefaultName", + "Use the map name instead of the gametype as the default recording name.", + 0x4A18A9BCE200B967 + }, + { + "perk_requireScavengerPerk", + "Should the player interact with the scavenger pickup without the perk", + 0xAD6B56033F77267 + }, + { + "allCollectiblesUnlocked", + "Allows all Collectibles to be available in the Safehouse", + 0x41D589BB75561DCA + }, + { + "equipmentAsGadgets", + "Enable equipment as gadgets in CAC", + 0x9F6426BBE2E6248 + } + }; + + std::vector commands_record = + { + { + "quit", + "Shutdown the Game [Com_Quit_f]", + 0x1DEE6107B26F8BB6 + } + }; + + std::vector get_dvars_list() + { + static std::vector dvars; + if (!dvars.empty()) return dvars; + + for (const auto& dvar : dvars_record) + { + dvars.push_back(dvar.name.data()); + } + + return dvars; + } + + std::vector get_commands_list() + { + static std::vector commands; + if (!commands.empty()) return commands; + + for (const auto& cmd : commands_record) + { + commands.push_back(cmd.name.data()); + } + + return commands; + } +} \ No newline at end of file diff --git a/source/proxy-dll/definitions/variables.hpp b/source/proxy-dll/definitions/variables.hpp new file mode 100644 index 0000000..e6a9d04 --- /dev/null +++ b/source/proxy-dll/definitions/variables.hpp @@ -0,0 +1,27 @@ +#pragma once + +namespace fnv1a +{ + uint64_t generate_hash(const char* string); +} + +namespace variables +{ + struct varInfo + { + std::string name; + const char* desc; + uint64_t fnv1a; + }; + + struct varEntry : varInfo + { + uintptr_t pointer = 0; + }; + + extern std::vector dvars_record; + extern std::vector commands_record; + + std::vector get_dvars_list(); + std::vector get_commands_list(); +} \ No newline at end of file diff --git a/source/proxy-dll/demonware/objects.cpp b/source/proxy-dll/demonware/objects.cpp index 838cdea..81f5e39 100644 --- a/source/proxy-dll/demonware/objects.cpp +++ b/source/proxy-dll/demonware/objects.cpp @@ -1,14 +1,14 @@ #include +#include "objects.hpp" + +#include "protobuf_helper.hpp" + +#include "resource.hpp" +#include #include #include #include #include -#include "protobuf_helper.hpp" - -#include "objects.hpp" - -#include "resource.hpp" -#include #define PUBLISHER_OBJECTS_ENUMERATE_LPC_DIR diff --git a/source/proxy-dll/demonware/services/bdObjectStore.cpp b/source/proxy-dll/demonware/services/bdObjectStore.cpp index fca41ce..8638134 100644 --- a/source/proxy-dll/demonware/services/bdObjectStore.cpp +++ b/source/proxy-dll/demonware/services/bdObjectStore.cpp @@ -1,9 +1,9 @@ #include #include "../services.hpp" -#include - -#include #include "../objects.hpp" + +#include +#include #include #include diff --git a/source/proxy-dll/demonware/services/bdProfiles.cpp b/source/proxy-dll/demonware/services/bdProfiles.cpp index 8b1b725..bb535bb 100644 --- a/source/proxy-dll/demonware/services/bdProfiles.cpp +++ b/source/proxy-dll/demonware/services/bdProfiles.cpp @@ -1,5 +1,6 @@ #include #include "../services.hpp" + #include #include diff --git a/source/proxy-dll/spoofer/spoofcall.cpp b/source/proxy-dll/spoofer/spoofcall.cpp new file mode 100644 index 0000000..78ea55a --- /dev/null +++ b/source/proxy-dll/spoofer/spoofcall.cpp @@ -0,0 +1,92 @@ +#include + +#include +#include + +namespace spoofcall +{ + void* callstack_proxy_addr{ nullptr }; + static thread_local const void* address_to_call{}; + + namespace + { + thread_local std::stack address_stack{}; + + const void* get_address_to_call() + { + return address_to_call; + } + + void store_address(const uint64_t address) + { + address_stack.push(address); + } + + uint64_t get_stored_address() + { + const auto res = address_stack.top(); + address_stack.pop(); + + return res; + } + + void callstack_return_stub(utils::hook::assembler& a) + { + a.push(rax); + a.pushad64(); + + a.call_aligned(get_stored_address); + a.mov(qword_ptr(rsp, 0x80), rax); + + a.popad64(); + + a.add(rsp, 8); + + a.jmp(qword_ptr(rsp, -8)); + } + + uint64_t get_callstack_return_stub() + { + const auto placeholder = 0x1403CF1C6_g; + + utils::hook::set(placeholder - 2, 0xFF); // fakes a call + utils::hook::nop(placeholder, 1); + utils::hook::jump(placeholder + 1, utils::hook::assemble(callstack_return_stub)); + + return placeholder; + } + + void callstack_stub(utils::hook::assembler& a) + { + a.push(rax); + + a.pushad64(); + a.call_aligned(get_address_to_call); + a.mov(qword_ptr(rsp, 0x80), rax); + + a.mov(rcx, qword_ptr(rsp, 0x88)); + a.call_aligned(store_address); + + a.mov(rax, get_callstack_return_stub()); + a.mov(qword_ptr(rsp, 0x88), rax); + + a.popad64(); + + a.add(rsp, 8); + + a.jmp(qword_ptr(rsp, -8)); + } + } + + void* get_spoofcall_proxy(const void* funcAddr) + { + static bool spoofer_initialized = false; + if (!spoofer_initialized) + { + callstack_proxy_addr = utils::hook::assemble(callstack_stub); + } + + address_to_call = funcAddr; + return callstack_proxy_addr; + } +} \ No newline at end of file diff --git a/source/proxy-dll/spoofer/spoofcall.hpp b/source/proxy-dll/spoofer/spoofcall.hpp new file mode 100644 index 0000000..4022f7d --- /dev/null +++ b/source/proxy-dll/spoofer/spoofcall.hpp @@ -0,0 +1,18 @@ +#pragma once + +namespace spoofcall +{ + void* get_spoofcall_proxy(const void* funcAddr); + + template + static T invoke(size_t funcAddr, Args ... args) + { + return static_cast(get_spoofcall_proxy(reinterpret_cast(funcAddr)))(args...); + } + + template + static T invoke(void* funcAddr, Args ... args) + { + return static_cast(get_spoofcall_proxy(funcAddr))(args...); + } +} \ No newline at end of file