Merge branch 'master' of https://github.com/project-bo4/shield-development
This commit is contained in:
commit
b66a191aff
@ -218,7 +218,7 @@ namespace blackbox
|
||||
|
||||
std::string generate_crash_info(const LPEXCEPTION_POINTERS exceptioninfo)
|
||||
{
|
||||
const auto& build_info = game::version_string;
|
||||
std::string build_info = game::Com_GetVersionString();
|
||||
const auto main_module = utilities::nt::library{};
|
||||
const auto rip_address = exceptioninfo->ExceptionRecord->ExceptionAddress;
|
||||
|
||||
|
212
source/proxy-dll/component/command.cpp
Normal file
212
source/proxy-dll/component/command.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
#include <std_include.hpp>
|
||||
#include "command.hpp"
|
||||
#include "definitions/game.hpp"
|
||||
|
||||
#include <utilities/hook.hpp>
|
||||
#include <utilities/string.hpp>
|
||||
#include <utilities/memory.hpp>
|
||||
|
||||
namespace command
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::unordered_map<std::string, command_param_function>& get_command_map()
|
||||
{
|
||||
static std::unordered_map<std::string, command_param_function> command_map{};
|
||||
return command_map;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, sv_command_param_function>& get_sv_command_map()
|
||||
{
|
||||
static std::unordered_map<std::string, sv_command_param_function> command_map{};
|
||||
return command_map;
|
||||
}
|
||||
|
||||
void execute_custom_command()
|
||||
{
|
||||
const params params{};
|
||||
const auto command = utilities::string::to_lower(params[0]);
|
||||
|
||||
auto& map = get_command_map();
|
||||
const auto entry = map.find(command);
|
||||
if (entry != map.end())
|
||||
{
|
||||
entry->second(params);
|
||||
}
|
||||
}
|
||||
|
||||
void execute_custom_sv_command()
|
||||
{
|
||||
const params_sv params{};
|
||||
const auto command = utilities::string::to_lower(params[0]);
|
||||
|
||||
auto& map = get_sv_command_map();
|
||||
const auto entry = map.find(command);
|
||||
if (entry != map.end())
|
||||
{
|
||||
entry->second(params);
|
||||
}
|
||||
}
|
||||
|
||||
game::CmdArgs* get_cmd_args()
|
||||
{
|
||||
return game::Sys_GetTLS()->cmdArgs;
|
||||
}
|
||||
}
|
||||
|
||||
params::params()
|
||||
: nesting_(get_cmd_args()->nesting)
|
||||
{
|
||||
assert(this->nesting_ < game::CMD_MAX_NESTING);
|
||||
}
|
||||
|
||||
params::params(const std::string& text)
|
||||
: needs_end_(true)
|
||||
{
|
||||
auto* cmd_args = get_cmd_args();
|
||||
game::Cmd_TokenizeStringKernel(0, 0, text.data(),
|
||||
512 - cmd_args->totalUsedArgvPool, false, cmd_args);
|
||||
|
||||
this->nesting_ = cmd_args->nesting;
|
||||
}
|
||||
|
||||
params::~params()
|
||||
{
|
||||
if (this->needs_end_)
|
||||
{
|
||||
game::Cmd_EndTokenizedString();
|
||||
}
|
||||
}
|
||||
|
||||
int params::size() const
|
||||
{
|
||||
return get_cmd_args()->argc[this->nesting_];
|
||||
}
|
||||
|
||||
params_sv::params_sv()
|
||||
: nesting_(game::sv_cmd_args->nesting)
|
||||
{
|
||||
assert(this->nesting_ < game::CMD_MAX_NESTING);
|
||||
}
|
||||
|
||||
params_sv::params_sv(const std::string& text)
|
||||
: needs_end_(true)
|
||||
{
|
||||
game::SV_Cmd_TokenizeString(text.data());
|
||||
this->nesting_ = game::sv_cmd_args->nesting;
|
||||
}
|
||||
|
||||
params_sv::~params_sv()
|
||||
{
|
||||
if (this->needs_end_)
|
||||
{
|
||||
game::SV_Cmd_EndTokenizedString();
|
||||
}
|
||||
}
|
||||
|
||||
int params_sv::size() const
|
||||
{
|
||||
return game::sv_cmd_args->argc[this->nesting_];
|
||||
}
|
||||
|
||||
const char* params_sv::get(const int index) const
|
||||
{
|
||||
if (index >= this->size())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return game::sv_cmd_args->argv[this->nesting_][index];
|
||||
}
|
||||
|
||||
std::string params_sv::join(const int index) const
|
||||
{
|
||||
std::string result;
|
||||
|
||||
for (auto i = index; i < this->size(); ++i)
|
||||
{
|
||||
if (i > index) result.append(" ");
|
||||
result.append(this->get(i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* params::get(const int index) const
|
||||
{
|
||||
if (index >= this->size())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return get_cmd_args()->argv[this->nesting_][index];
|
||||
}
|
||||
|
||||
std::string params::join(const int index) const
|
||||
{
|
||||
std::string result = {};
|
||||
|
||||
for (auto i = index; i < this->size(); i++)
|
||||
{
|
||||
if (i > index) result.append(" ");
|
||||
result.append(this->get(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void add(const std::string& command, command_function function, const char* desc)
|
||||
{
|
||||
add(command, [f = std::move(function)](const params&)
|
||||
{
|
||||
f();
|
||||
});
|
||||
}
|
||||
|
||||
void add(const std::string& command, command_param_function function, const char* desc)
|
||||
{
|
||||
auto lower_command = utilities::string::to_lower(command);
|
||||
|
||||
auto& map = get_command_map();
|
||||
const auto is_registered = map.contains(lower_command);
|
||||
|
||||
map[std::move(lower_command)] = std::move(function);
|
||||
|
||||
if (is_registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& allocator = *utilities::memory::get_allocator();
|
||||
auto* cmd_function = allocator.allocate<game::cmd_function_t>();
|
||||
auto cmdRef = game::AssetRef(command.data());
|
||||
|
||||
variables::commands_table.push_back({ command, desc, fnv1a::generate_hash(command.data()) });
|
||||
|
||||
game::Cmd_AddCommandInternal(&cmdRef, execute_custom_command, cmd_function);
|
||||
}
|
||||
|
||||
void add_sv(const std::string& command, sv_command_param_function function, const char* desc)
|
||||
{
|
||||
auto lower_command = utilities::string::to_lower(command);
|
||||
|
||||
auto& map = get_sv_command_map();
|
||||
const auto is_registered = map.contains(lower_command);
|
||||
|
||||
map[std::move(lower_command)] = std::move(function);
|
||||
|
||||
if (is_registered)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& allocator = *utilities::memory::get_allocator();
|
||||
auto cmdRef = game::AssetRef(command.data());
|
||||
|
||||
variables::commands_table.push_back({ command, desc, fnv1a::generate_hash(command.data()) });
|
||||
|
||||
game::Cmd_AddCommandInternal(&cmdRef, game::Cbuf_AddServerText_f,
|
||||
allocator.allocate<game::cmd_function_t>());
|
||||
game::Cmd_AddServerCommandInternal(&cmdRef, execute_custom_sv_command,
|
||||
allocator.allocate<game::cmd_function_t>());
|
||||
}
|
||||
}
|
67
source/proxy-dll/component/command.hpp
Normal file
67
source/proxy-dll/component/command.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
namespace command
|
||||
{
|
||||
class params
|
||||
{
|
||||
public:
|
||||
params();
|
||||
params(const std::string& text);
|
||||
~params();
|
||||
|
||||
params(params&&) = delete;
|
||||
params(const params&) = delete;
|
||||
|
||||
params& operator=(params&&) = delete;
|
||||
params& operator=(const params&) = delete;
|
||||
|
||||
[[nodiscard]] int size() const;
|
||||
[[nodiscard]] const char* get(int index) const;
|
||||
[[nodiscard]] std::string join(int index) const;
|
||||
|
||||
[[nodiscard]] const char* operator[](const int index) const
|
||||
{
|
||||
return this->get(index); //
|
||||
}
|
||||
|
||||
private:
|
||||
bool needs_end_{false};
|
||||
int nesting_;
|
||||
};
|
||||
|
||||
class params_sv
|
||||
{
|
||||
public:
|
||||
params_sv();
|
||||
params_sv(const std::string& text);
|
||||
~params_sv();
|
||||
|
||||
params_sv(params_sv&&) = delete;
|
||||
params_sv(const params_sv&) = delete;
|
||||
|
||||
params_sv& operator=(params_sv&&) = delete;
|
||||
params_sv& operator=(const params_sv&) = delete;
|
||||
|
||||
[[nodiscard]] int size() const;
|
||||
[[nodiscard]] const char* get(int index) const;
|
||||
[[nodiscard]] std::string join(int index) const;
|
||||
|
||||
[[nodiscard]] const char* operator[](const int index) const
|
||||
{
|
||||
return this->get(index); //
|
||||
}
|
||||
|
||||
private:
|
||||
bool needs_end_{false};
|
||||
int nesting_;
|
||||
};
|
||||
|
||||
using command_function = std::function<void()>;
|
||||
using command_param_function = std::function<void(const params&)>;
|
||||
using sv_command_param_function = std::function<void(const params_sv&)>;
|
||||
|
||||
void add(const std::string& command, command_function function, const char* desc = "");
|
||||
void add(const std::string& command, command_param_function function, const char* desc = "");
|
||||
|
||||
void add_sv(const std::string& command, sv_command_param_function function, const char* desc = "");
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
#include <std_include.hpp>
|
||||
#include "definitions/game.hpp"
|
||||
#include "definitions/game_runtime_errors.hpp"
|
||||
#include "component/scheduler.hpp"
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
@ -74,7 +73,7 @@ namespace debugging
|
||||
|
||||
void sys_error_stub(uint32_t code, const char* message)
|
||||
{
|
||||
const char* error_message = game::runtime_errors::get_error_message(code);
|
||||
const char* error_message = runtime_errors::get_error_message(code);
|
||||
|
||||
if (error_message)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ namespace dvars
|
||||
{
|
||||
void fetch_dvar_pointers()
|
||||
{
|
||||
for (auto& dvar : variables::dvars_record)
|
||||
for (auto& dvar : variables::dvars_table)
|
||||
{
|
||||
dvar.pointer = spoofcall::invoke<uintptr_t>(game::Dvar_FindVar, dvar.name.data());
|
||||
}
|
||||
@ -248,9 +248,9 @@ namespace dvars
|
||||
{
|
||||
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; });
|
||||
auto it = std::find_if(variables::dvars_table.begin(), variables::dvars_table.end(), [&hashRef](variables::varEntry& i) { return i.fnv1a == hashRef; });
|
||||
|
||||
if (it != variables::dvars_record.end() && it->pointer)
|
||||
if (it != variables::dvars_table.end() && it->pointer)
|
||||
{
|
||||
return reinterpret_cast<game::dvar_t*>(it->pointer);
|
||||
}
|
||||
@ -265,9 +265,9 @@ namespace dvars
|
||||
|
||||
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 utilities::string::compare(i.name, nameRef); });
|
||||
auto it = std::find_if(variables::dvars_table.begin(), variables::dvars_table.end(), [&nameRef](variables::varEntry& i) { return utilities::string::compare(i.name, nameRef); });
|
||||
|
||||
if (it != variables::dvars_record.end() && it->pointer)
|
||||
if (it != variables::dvars_table.end() && it->pointer)
|
||||
{
|
||||
return reinterpret_cast<game::dvar_t*>(it->pointer);
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ namespace game_console
|
||||
{
|
||||
double required_ratio = exact ? 1.00 : 0.01;
|
||||
|
||||
for (const auto& dvar : variables::dvars_record)
|
||||
for (const auto& dvar : variables::dvars_table)
|
||||
{
|
||||
if (dvars::find_dvar(dvar.fnv1a) && utilities::string::match(input, dvar.name) >= required_ratio)
|
||||
{
|
||||
@ -202,7 +202,7 @@ namespace game_console
|
||||
suggestions.push_back({ input, "", fnv1a::generate_hash(input.data()), reinterpret_cast<uintptr_t>(dvars::find_dvar(input)) });
|
||||
}
|
||||
|
||||
for (const auto& cmd : variables::commands_record)
|
||||
for (const auto& cmd : variables::commands_table)
|
||||
{
|
||||
if (utilities::string::match(input, cmd.name) >= required_ratio)
|
||||
{
|
||||
@ -374,7 +374,13 @@ namespace game_console
|
||||
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);
|
||||
char sysinfo_version[256];
|
||||
bool result1 = utilities::hook::invoke<bool>(game::Live_SystemInfo, 0, 0, sysinfo_version, 256);
|
||||
char sysinfo_livebits[256];
|
||||
bool result2 = utilities::hook::invoke<bool>(game::Live_SystemInfo, 0, 1, sysinfo_livebits, 256);
|
||||
const char* info = utilities::string::va("Project-BO4 1.0.0, Engine Version: %s, LiveBits: %s", sysinfo_version, sysinfo_livebits);
|
||||
|
||||
game::R_AddCmdDrawText(info, 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);
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "gsc_custom.hpp"
|
||||
#include "hashes.hpp"
|
||||
#include "definitions/game.hpp"
|
||||
#include "definitions/game_runtime_errors.hpp"
|
||||
#include "definitions/xassets.hpp"
|
||||
#include "loader/component_loader.hpp"
|
||||
#include "component/scheduler.hpp"
|
||||
@ -53,7 +52,7 @@ namespace gsc_funcs
|
||||
vsprintf_s(buffer[inst], message, va);
|
||||
va_end(va);
|
||||
|
||||
game::ScrVm_Error(game::runtime_errors::custom_error_id, inst, buffer[inst], terminal);
|
||||
game::ScrVm_Error(runtime_errors::custom_error_id, inst, buffer[inst], terminal);
|
||||
}
|
||||
|
||||
const char* lookup_hash(game::scriptInstance_t inst, const char* type, uint64_t hash)
|
||||
@ -1329,13 +1328,13 @@ namespace gsc_funcs
|
||||
break;
|
||||
default:
|
||||
// put custom message for our id
|
||||
if (code == game::runtime_errors::custom_error_id)
|
||||
if (code == runtime_errors::custom_error_id)
|
||||
{
|
||||
game::scrVarPub[inst].error_message = unused;
|
||||
}
|
||||
else
|
||||
{
|
||||
game::scrVarPub[inst].error_message = game::runtime_errors::get_error_message(code);
|
||||
game::scrVarPub[inst].error_message = runtime_errors::get_error_message(code);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -72,11 +72,6 @@ namespace logger
|
||||
write(LOG_TYPE_INFO, " T8-Mod Initializing ... %s[0x%llX]", utilities::nt::library{}.get_name().c_str(), utilities::nt::library{}.get_ptr());
|
||||
write(LOG_TYPE_INFO, "=======================================================================================================");
|
||||
}
|
||||
|
||||
void post_unpack() override
|
||||
{
|
||||
/* PLACE_HOLDER */
|
||||
}
|
||||
};
|
||||
}
|
||||
REGISTER_COMPONENT(logger::component)
|
@ -1,15 +1,15 @@
|
||||
#include <std_include.hpp>
|
||||
#include "definitions/xassets.hpp"
|
||||
#include "definitions/game.hpp"
|
||||
|
||||
#include "game_console.hpp"
|
||||
|
||||
#include "gsc_funcs.hpp"
|
||||
#include "gsc_custom.hpp"
|
||||
#include "dvars.hpp"
|
||||
#include "hashes.hpp"
|
||||
|
||||
#include "command.hpp"
|
||||
#include "game_console.hpp"
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "definitions/xassets.hpp"
|
||||
#include "definitions/game.hpp"
|
||||
|
||||
#include <utilities/io.hpp>
|
||||
#include <utilities/hook.hpp>
|
||||
|
||||
@ -1094,7 +1094,7 @@ namespace mods {
|
||||
mod_storage storage{};
|
||||
|
||||
|
||||
void load_mods_cmd()
|
||||
void mods_reload_f()
|
||||
{
|
||||
if (!game::Com_IsRunningUILevel())
|
||||
{
|
||||
@ -1267,8 +1267,7 @@ namespace mods {
|
||||
hksl_loadfile_hook.create(0x14375D6A0_g, hksl_loadfile_stub);
|
||||
bg_cache_sync_hook.create(0x1405CE0B0_g, bg_cache_sync_stub);
|
||||
|
||||
// register load mods command
|
||||
Cmd_AddCommand("reload_mods", load_mods_cmd);
|
||||
command::add("reload_mods", mods_reload_f, "Reload the shield mods");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,168 +0,0 @@
|
||||
#include <std_include.hpp>
|
||||
#include "discovery.hpp"
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include <utilities/hook.hpp>
|
||||
#include <utilities/signature.hpp>
|
||||
|
||||
std::unordered_map<std::string, size_t> symbols_list;
|
||||
|
||||
size_t operator"" _d(const char* str, const size_t len)
|
||||
{
|
||||
auto itr = symbols_list.find(std::string(str, len));
|
||||
if (itr != symbols_list.end()) return itr->second; // found you!
|
||||
|
||||
//return find_missing_symbol(name);
|
||||
}
|
||||
|
||||
namespace discovery
|
||||
{
|
||||
void export_address_list_to_json()
|
||||
{
|
||||
/* PLACE_HOLDER */
|
||||
}
|
||||
|
||||
void import_address_list_from_json()
|
||||
{
|
||||
/* PLACE_HOLDER */
|
||||
}
|
||||
|
||||
void start_address_list_discovery()
|
||||
{
|
||||
auto follow_jmp = [](size_t addr) -> size_t {
|
||||
return *(int32_t*)(addr + 1) + addr + 5;
|
||||
};
|
||||
|
||||
auto follow_lea = [](size_t addr) -> size_t {
|
||||
return *(int32_t*)(addr + 3) + addr + 7;
|
||||
};
|
||||
|
||||
std::vector<sig_instance> signature_list; // SYMBOL NAME , SIGNATURE, DISTANCE, SIGNATURE RELATION
|
||||
|
||||
// Main Symbols
|
||||
signature_list.push_back({ "com_error", "4C 89 4C 24 ? 55 53 56 57 48", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "live_get_connectivity_info", "48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 48 8B DA C7 02", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "draw_text_cmd", "48 89 6C 24 ? 41 54 41 56 41 57 48 83 EC 30 80", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "ui_get_font_handle", "48 89 5C 24 ? 57 48 83 EC 30 8B DA 48 8B F9 83", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "scr_place_get_view", "E8 ? ? ? ? 48 85 C0 74 11 4C 8D", 0, SIG_RELEVANCE_JMP_FROM });
|
||||
signature_list.push_back({ "r_text_height", "E8 ? ? ? ? 66 0F 6E C0 0F 5B C0 F3 0F 59 C6 F3 0F", 0, SIG_RELEVANCE_JMP_FROM });
|
||||
|
||||
// Platform Symbols
|
||||
signature_list.push_back({ "bnet_is_disabled", "40 55 48 8D 6C 24 ? 48 81 EC ? ? ? ? 45 85", 0x17, SIG_RELEVANCE_JMP_FROM });
|
||||
signature_list.push_back({ "bnet_is_connected", "48 83 EC 28 48 8B 0D ? ? ? ? E8 ? ? ? ? 84 C0 74 5A", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "bnet_patch_unk1", "48 83 EC 28 48 8B 0D ? ? ? ? E8 ? ? ? ? 84 C0 75 11", 0, SIG_RELEVANCE_DIRECT_HIT }); // Annoying function related to bnet; crashes game
|
||||
signature_list.push_back({ "bnet_patch_unk2", "E8 ? ? ? ? 8B CF E8 ? ? ? ? 45 33 C0 48", 0, SIG_RELEVANCE_JMP_FROM }); // Annoying function related to bnet; crashes game
|
||||
signature_list.push_back({ "bnet_patch_unk3", "E8 ? ? ? ? 88 85 ? ? ? ? 48 8B", 0, SIG_RELEVANCE_JMP_FROM }); // BattleNet_IsModeAvailable?
|
||||
signature_list.push_back({ "bnet_patch_auth3", "E8 ? ? ? ? 84 C0 0F 85 ? ? ? ? 8B CB E8 ? ? ? ? 4C", 0, SIG_RELEVANCE_DIRECT_HIT }); // LiveConnect_BeginCrossAuthPlatform
|
||||
|
||||
// Frame Hooks
|
||||
signature_list.push_back({ "r_end_frame", "E8 ? ? ? ? 41 F6 DD 1B", 0, SIG_RELEVANCE_JMP_FROM });
|
||||
signature_list.push_back({ "com_frame", "48 83 EC 48 48 C7 44 24 ? ? ? ? ? 48 8D 0D", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "g_run_frame", "48 8B C4 48 89 58 10 48 89 70 18 48 89 78 20 55 41 54 41 55 41 56 41 57 48 8D A8 C8 F7 FF FF", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
|
||||
// Demonware
|
||||
signature_list.push_back({ "curl_setup_ssl_verify_peer", "40 53 48 83 EC 20 BA ? ? ? ? 48 8B D9 48 8B", 0x29, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "curl_setup_ssl_verify_host", "40 53 48 83 EC 20 BA ? ? ? ? 48 8B D9 48 8B", 0x15, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "dw_https", "68 74 74 70 73 00", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "dw_prod_umbrella_url", "68 74 74 70 73 3A 2F 2F 70 72 6F 64 2E 75 6D 62 72 65 6C 6C 61 2E 64 65 6D 6F 6E 77 61 72 65 2E 6E 65 74 00", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "dw_prod_uno_url", "68 74 74 70 73 3A 2F 2F 70 72 6F 64 2E 75 6E 6F 2E 64 65 6D 6F 6E 77 61 72 65 2E 6E 65 74 2F 76 31 2E 30 00", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "dw_auth3_url_frmt", "68 74 74 70 73 3A 2F 2F 25 73 3A 25 64 2F 61 75 74 68 2F 00", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
|
||||
// BuildNumber
|
||||
signature_list.push_back({ "com_get_build_version", "40 53 48 83 EC 40 44 8B 0D", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
|
||||
// UI Symbols
|
||||
signature_list.push_back({ "ui_get_model_for_controller", "48 63 C1 48 8D 0D ? ? ? ? 0F B7 04", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "ui_create_model_from_path", "45 33 C9 41 B0 01 E9", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
signature_list.push_back({ "ui_model_set_string", "48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 8B DA 49 8B F1", 0x4E, SIG_RELEVANCE_JMP_FROM });
|
||||
signature_list.push_back({ "ui_model_set_int", "48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 8B DA 49 8B F1", 0x20, SIG_RELEVANCE_JMP_FROM });
|
||||
signature_list.push_back({ "ui_model_set_bool", "48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 8B DA 49 8B F1", 0x31, SIG_RELEVANCE_JMP_FROM });
|
||||
signature_list.push_back({ "ui_model_set_real", "48 83 EC 28 66 85 C9 74 3A", 0, SIG_RELEVANCE_DIRECT_HIT });
|
||||
|
||||
|
||||
//// Impossible to make signature; should be updated manually
|
||||
//signature_list.push_back({ "bnet_process_auth3_data", "", 0x000000000_g, SIG_RELEVANCE_IMPOSSIBLE });
|
||||
//signature_list.push_back({ "bnet_patch_text_chat", "", 0x000000000_g, SIG_RELEVANCE_IMPOSSIBLE });
|
||||
|
||||
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "[ DISCOVERY ]: Starting signature scan; total defined symbols: %u", signature_list.size());
|
||||
|
||||
symbols_list.clear();
|
||||
int error_count = 0;
|
||||
|
||||
for (sig_instance i : signature_list)
|
||||
{
|
||||
if (i.relv == SIG_RELEVANCE_IMPOSSIBLE)
|
||||
{
|
||||
symbols_list.insert({ i.name, i.dist });
|
||||
continue;
|
||||
}
|
||||
|
||||
utilities::hook::signature::signature_result scan = utilities::hook::signature(std::string(i.sig, strlen(i.sig))).process();
|
||||
|
||||
if (scan.size() == 0 || scan.size() > 1)
|
||||
{
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "[ DISCOVERY ]: %s while searching for %s", scan.size() ? "Multiple Matches" : "No Hits", i.name);
|
||||
error_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i.relv == SIG_RELEVANCE_DIRECT_HIT)
|
||||
{
|
||||
symbols_list.insert({ i.name, reinterpret_cast<size_t>(scan[0]) + i.dist });
|
||||
}
|
||||
else if (i.relv == SIG_RELEVANCE_JMP_FROM)
|
||||
{
|
||||
symbols_list.insert({ i.name, follow_jmp(reinterpret_cast<size_t>(scan[0]) + i.dist) });
|
||||
}
|
||||
else
|
||||
{
|
||||
symbols_list.insert({ i.name, follow_lea(reinterpret_cast<size_t>(scan[0]) + i.dist) });
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
|
||||
if (symbols_list.find("com_get_build_version") != symbols_list.end())
|
||||
{
|
||||
const char* build_version = utilities::hook::invoke<const char*>(symbols_list["com_get_build_version"]);
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "Address-List Discovery Results for BlackOps4 %s", build_version);
|
||||
}
|
||||
|
||||
for (auto symbol : symbols_list)
|
||||
{
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "- %-28s: 0x%llX_g", symbol.first.c_str(), reverse_g(symbol.second));
|
||||
}
|
||||
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
#endif // DEBUG
|
||||
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "[ DISCOVERY ]: Signature scanning complete. %u/%u successful", signature_list.size() - error_count, signature_list.size());
|
||||
}
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
#ifdef DEBUG
|
||||
start_address_list_discovery();
|
||||
#endif // DEBUG
|
||||
|
||||
/*************************************************************************************************************
|
||||
** NOTE : Updating game code by developers depending on compiler and where and what changes made, most likely
|
||||
** will shift addresses. using signature patterns to find addresses at runtime is a good counter to this
|
||||
** problem when game gets updated frequently but there should be decent fail-safe mechanism implemented
|
||||
** to detect sig-scanning errors when there is signature-breaking changes in binary to prevent misleadings
|
||||
**
|
||||
*************************************************************************************************************/
|
||||
}
|
||||
|
||||
int priority() override
|
||||
{
|
||||
return 9998;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//REGISTER_COMPONENT(discovery::component)
|
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
size_t operator"" _d(const char* str, size_t len);
|
||||
|
||||
namespace discovery
|
||||
{
|
||||
enum sig_relation
|
||||
{
|
||||
SIG_RELEVANCE_IMPOSSIBLE = -1,
|
||||
SIG_RELEVANCE_DIRECT_HIT = 0,
|
||||
SIG_RELEVANCE_LEA_FROM = 1,
|
||||
SIG_RELEVANCE_JMP_FROM = 2
|
||||
};
|
||||
|
||||
struct sig_instance
|
||||
{
|
||||
const char* name;
|
||||
const char* sig;
|
||||
size_t dist;
|
||||
sig_relation relv;
|
||||
};
|
||||
}
|
@ -1,14 +1,30 @@
|
||||
#include <std_include.hpp>
|
||||
#include "game.hpp"
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
std::string version_string = "VERSION STRING UN-INITIALIZED";
|
||||
const char* Com_GetVersionString()
|
||||
{
|
||||
static std::string version_string{};
|
||||
|
||||
typedef const char* (__fastcall* Com_GetBuildVersion_t)();
|
||||
Com_GetBuildVersion_t Com_GetBuildVersion = (Com_GetBuildVersion_t)0x142892F40_g;
|
||||
if (version_string.empty()) {
|
||||
version_string = std::format("BlackOps4 {}", Com_GetBuildVersion());
|
||||
}
|
||||
|
||||
return version_string.data();
|
||||
}
|
||||
|
||||
void verify_game_version()
|
||||
{
|
||||
if (*(int*)0x1449CA7E8_g != 13869365) // BlackOps4 CL(13869365) BEYQBBUILD106 DEV [Wed Feb 22 16:31:32 2023]
|
||||
{
|
||||
throw std::runtime_error("Unsupported BlackOps4.exe Version. This DLL Expects Latest BNET Build");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "[ SYSTEM ]: Verified Game Version '%s'", Com_GetVersionString());
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
scoped_critical_section::scoped_critical_section(int32_t s, scoped_critical_section_type type) : _s(0), _hasOwnership(false), _isScopedRelease(false), _next(nullptr)
|
||||
{
|
||||
@ -19,42 +35,4 @@ namespace game
|
||||
{
|
||||
game::ScopedCriticalSectionDestructor(this);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void verify_game_version()
|
||||
{
|
||||
if (*(int*)0x1449CA7E8_g != 13869365) // BlackOps4 CL(13869365) BEYQBBUILD106 DEV [Wed Feb 22 16:31:32 2023]
|
||||
{
|
||||
throw std::runtime_error("Unsupported BlackOps4.exe Version. Update Your game using Battle.net Launcher");
|
||||
}
|
||||
|
||||
version_string = std::format("BlackOps4 {}", Com_GetBuildVersion());
|
||||
|
||||
#ifdef DEBUG
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "[ SYSTEM ]: game version string: %s", version_string.c_str());
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void pre_start() override
|
||||
{
|
||||
/* PLACE_HOLDER */
|
||||
}
|
||||
|
||||
void post_unpack() override
|
||||
{
|
||||
verify_game_version();
|
||||
}
|
||||
|
||||
int priority() override
|
||||
{
|
||||
return 9997;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(game::component)
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "definitions/discovery.hpp"
|
||||
#include "keys.hpp"
|
||||
#include "network.hpp"
|
||||
#include "scripting.hpp"
|
||||
#include "definitions/variables.hpp"
|
||||
|
||||
#define WEAK __declspec(selectany)
|
||||
@ -8,22 +9,25 @@
|
||||
namespace game
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// VARIABLES //
|
||||
// SHIELD //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern std::string version_string;
|
||||
void verify_game_version();
|
||||
|
||||
const char* Com_GetVersionString();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// TYPES //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4];
|
||||
|
||||
typedef uint32_t ScrVarIndex_t;
|
||||
typedef uint64_t ScrVarNameIndex_t;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// STRUCTS //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct BO4_AssetRef_t
|
||||
{
|
||||
@ -40,509 +44,15 @@ namespace game
|
||||
return m128i;
|
||||
}
|
||||
|
||||
typedef void (*xcommand_t)(void);
|
||||
|
||||
struct cmd_function_t
|
||||
inline BO4_AssetRef_t
|
||||
AssetRef(const char* nameRef)
|
||||
{
|
||||
cmd_function_t* next;
|
||||
uint64_t name;
|
||||
uint64_t pad0;
|
||||
uint64_t pad1;
|
||||
uint64_t pad2;
|
||||
xcommand_t function;
|
||||
};
|
||||
BO4_AssetRef_t m128i;
|
||||
m128i.hash = fnv1a::generate_hash(nameRef);
|
||||
|
||||
struct GSC_IMPORT_ITEM
|
||||
{
|
||||
uint32_t name;
|
||||
uint32_t name_space;
|
||||
uint16_t num_address;
|
||||
uint8_t param_count;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
struct GSC_EXPORT_ITEM
|
||||
{
|
||||
uint32_t checksum;
|
||||
uint32_t address;
|
||||
uint32_t name;
|
||||
uint32_t name_space;
|
||||
uint32_t callback_event;
|
||||
uint8_t param_count;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
struct GSC_OBJ
|
||||
{
|
||||
byte magic[8];
|
||||
int32_t crc;
|
||||
int32_t pad;
|
||||
uint64_t name;
|
||||
int32_t include_offset;
|
||||
uint16_t string_count;
|
||||
uint16_t exports_count;
|
||||
int32_t start_data;
|
||||
int32_t string_offset;
|
||||
int16_t imports_count;
|
||||
uint16_t fixup_count;
|
||||
int32_t ukn2c;
|
||||
int32_t exports_offset;
|
||||
int32_t ukn34;
|
||||
int32_t imports_offset;
|
||||
uint16_t globalvar_count;
|
||||
int32_t fixup_offset;
|
||||
int32_t globalvar_offset;
|
||||
int32_t script_size;
|
||||
int32_t requires_implements_offset;
|
||||
int32_t ukn50;
|
||||
int32_t data_length;
|
||||
uint16_t include_count;
|
||||
byte ukn5a;
|
||||
byte requires_implements_count;
|
||||
|
||||
inline GSC_EXPORT_ITEM* get_exports()
|
||||
{
|
||||
return reinterpret_cast<GSC_EXPORT_ITEM*>(magic + exports_offset);
|
||||
return m128i;
|
||||
}
|
||||
|
||||
inline GSC_IMPORT_ITEM* get_imports()
|
||||
{
|
||||
return reinterpret_cast<GSC_IMPORT_ITEM*>(magic + imports_offset);
|
||||
}
|
||||
|
||||
inline uint64_t* get_includes()
|
||||
{
|
||||
return reinterpret_cast<uint64_t*>(magic + include_offset);
|
||||
}
|
||||
|
||||
inline GSC_EXPORT_ITEM* get_exports_end()
|
||||
{
|
||||
return get_exports() + exports_count;
|
||||
}
|
||||
|
||||
inline uint64_t* get_includes_end()
|
||||
{
|
||||
return get_includes() + include_count;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
enum scriptInstance_t : int32_t
|
||||
{
|
||||
SCRIPTINSTANCE_SERVER = 0x0,
|
||||
SCRIPTINSTANCE_CLIENT = 0x1,
|
||||
SCRIPTINSTANCE_MAX = 0x2,
|
||||
};
|
||||
|
||||
typedef void (*BuiltinFunction)(scriptInstance_t);
|
||||
|
||||
|
||||
struct BO4_BuiltinFunctionDef
|
||||
{
|
||||
uint32_t canonId;
|
||||
uint32_t min_args;
|
||||
uint32_t max_args;
|
||||
BuiltinFunction actionFunc;
|
||||
uint32_t type;
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) BO4_scrVarGlobalVars_t
|
||||
{
|
||||
uint32_t name;
|
||||
ScrVarIndex_t id;
|
||||
bool persist;
|
||||
};
|
||||
|
||||
|
||||
enum ScrVarType_t : uint32_t {
|
||||
TYPE_UNDEFINED = 0x0,
|
||||
TYPE_POINTER = 0x1,
|
||||
TYPE_STRING = 0x2,
|
||||
TYPE_VECTOR = 0x3,
|
||||
TYPE_HASH = 0x4,
|
||||
TYPE_FLOAT = 0x5,
|
||||
TYPE_INTEGER = 0x6,
|
||||
TYPE_UINTPTR = 0x7,
|
||||
TYPE_ENTITY_OFFSET = 0x8,
|
||||
TYPE_CODEPOS = 0x9,
|
||||
TYPE_PRECODEPOS = 0xA,
|
||||
TYPE_API_FUNCTION = 0xB,
|
||||
TYPE_SCRIPT_FUNCTION = 0xC,
|
||||
TYPE_STACK = 0xD,
|
||||
TYPE_THREAD = 0xE,
|
||||
TYPE_NOTIFY_THREAD = 0xF,
|
||||
TYPE_TIME_THREAD = 0x10,
|
||||
TYPE_FRAME_THREAD = 0x11,
|
||||
TYPE_CHILD_THREAD = 0x12,
|
||||
TYPE_CLASS = 0x13,
|
||||
TYPE_SHARED_STRUCT = 0x14,
|
||||
TYPE_STRUCT = 0x15,
|
||||
TYPE_REMOVED_ENTITY = 0x16,
|
||||
TYPE_ENTITY = 0x17,
|
||||
TYPE_ARRAY = 0x18,
|
||||
TYPE_REMOVED_THREAD = 0x19,
|
||||
TYPE_FREE = 0x1a,
|
||||
TYPE_THREAD_LIST = 0x1b,
|
||||
TYPE_ENT_LIST = 0x1c,
|
||||
TYPE_COUNT
|
||||
};
|
||||
|
||||
|
||||
struct BO4_scrVarPub {
|
||||
const char* fieldBuffer;
|
||||
const char* error_message;
|
||||
byte* programBuffer;
|
||||
byte* endScriptBuffer;
|
||||
byte* programHunkUser; // HunkUser
|
||||
BO4_scrVarGlobalVars_t globalVars[16];
|
||||
ScrVarNameIndex_t entFieldNameIndex;
|
||||
ScrVarIndex_t freeEntList;
|
||||
ScrVarIndex_t tempVariable;
|
||||
uint32_t checksum;
|
||||
uint32_t entId;
|
||||
uint32_t varHighWatermark;
|
||||
uint32_t numScriptThreads;
|
||||
uint32_t numVarAllocations;
|
||||
int32_t varHighWatermarkId;
|
||||
};
|
||||
|
||||
union ScrVarValueUnion_t
|
||||
{
|
||||
int64_t intValue;
|
||||
uintptr_t uintptrValue;
|
||||
float floatValue;
|
||||
int32_t stringValue;
|
||||
const float* vectorValue;
|
||||
byte* codePosValue;
|
||||
ScrVarIndex_t pointerValue;
|
||||
};
|
||||
|
||||
struct ScrVarValue_t
|
||||
{
|
||||
ScrVarValueUnion_t u;
|
||||
ScrVarType_t type;
|
||||
};
|
||||
|
||||
struct ScrVar_t_Info
|
||||
{
|
||||
uint32_t nameType : 3;
|
||||
uint32_t flags : 5;
|
||||
uint32_t refCount : 24;
|
||||
};
|
||||
|
||||
struct ScrVar_t
|
||||
{
|
||||
ScrVarNameIndex_t nameIndex;
|
||||
ScrVar_t_Info _anon_0;
|
||||
ScrVarIndex_t nextSibling;
|
||||
ScrVarIndex_t prevSibling;
|
||||
ScrVarIndex_t parentId;
|
||||
ScrVarIndex_t nameSearchHashList;
|
||||
uint32_t pad0;
|
||||
};
|
||||
|
||||
union ScrVarObjectInfo1_t
|
||||
{
|
||||
uint64_t object_o;
|
||||
unsigned int size;
|
||||
ScrVarIndex_t nextEntId;
|
||||
ScrVarIndex_t self;
|
||||
ScrVarIndex_t free;
|
||||
};
|
||||
|
||||
union ScrVarObjectInfo2_t
|
||||
{
|
||||
uint32_t object_w;
|
||||
ScrVarIndex_t stackId;
|
||||
};
|
||||
|
||||
struct function_stack_t
|
||||
{
|
||||
byte* pos;
|
||||
ScrVarValue_t* top;
|
||||
ScrVarValue_t* startTop;
|
||||
ScrVarIndex_t threadId;
|
||||
uint16_t localVarCount;
|
||||
uint16_t profileInfoCount;
|
||||
};
|
||||
|
||||
struct function_frame_t
|
||||
{
|
||||
function_stack_t fs;
|
||||
};
|
||||
|
||||
struct ScrVmContext_t
|
||||
{
|
||||
ScrVarIndex_t fieldValueId;
|
||||
ScrVarIndex_t objectId;
|
||||
byte* lastGoodPos;
|
||||
ScrVarValue_t* lastGoodTop;
|
||||
};
|
||||
|
||||
typedef void (*VM_OP_FUNC)(scriptInstance_t, function_stack_t*, ScrVmContext_t*, bool*);
|
||||
|
||||
|
||||
struct BO4_scrVarGlob
|
||||
{
|
||||
ScrVarIndex_t* scriptNameSearchHashList;
|
||||
ScrVar_t* scriptVariables;
|
||||
ScrVarObjectInfo1_t* scriptVariablesObjectInfo1;
|
||||
ScrVarObjectInfo2_t* scriptVariablesObjectInfo2;
|
||||
ScrVarValue_t* scriptValues;
|
||||
};
|
||||
|
||||
struct BO4_scrVmPub
|
||||
{
|
||||
void* unk0;
|
||||
void* unk8;
|
||||
void* executionQueueHeap; // HunkUser
|
||||
void* timeByValueQueue; // VmExecutionQueueData_t
|
||||
void* timeByThreadQueue[1024]; // VmExecutionQueue_t
|
||||
void* frameByValueQueue; // VmExecutionQueueData_t
|
||||
void* frameByThreadQueue[1024]; // VmExecutionQueue_t
|
||||
void* timeoutByValueList; // VmExecutionQueueData_t
|
||||
void* timeoutByThreadList[1024]; // VmExecutionQueue_t
|
||||
void* notifyByObjectQueue[1024]; // VmExecutionNotifyQueue_t
|
||||
void* notifyByThreadQueue[1024]; // VmExecutionNotifyQueue_t
|
||||
void* endonByObjectList[1024]; // VmExecutionNotifyQueue_t
|
||||
void* endonByThreadList[1024]; // VmExecutionNotifyQueue_t
|
||||
ScrVarIndex_t* localVars;
|
||||
ScrVarValue_t* maxstack;
|
||||
function_frame_t* function_frame;
|
||||
ScrVarValue_t* top;
|
||||
function_frame_t function_frame_start[64];
|
||||
ScrVarValue_t stack[2048];
|
||||
uint32_t time;
|
||||
uint32_t frame;
|
||||
int function_count;
|
||||
int callNesting;
|
||||
unsigned int inparamcount;
|
||||
bool showError;
|
||||
bool systemInitialized;
|
||||
bool vmInitialized;
|
||||
bool isShutdown;
|
||||
};
|
||||
|
||||
struct objFileInfo_t
|
||||
{
|
||||
GSC_OBJ* activeVersion;
|
||||
int slot;
|
||||
int refCount;
|
||||
uint32_t groupId;
|
||||
};
|
||||
|
||||
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;
|
||||
@ -596,18 +106,6 @@ namespace game
|
||||
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,
|
||||
@ -725,6 +223,75 @@ namespace game
|
||||
char padding_unk2[8];
|
||||
};
|
||||
|
||||
typedef void (*xcommand_t)(void);
|
||||
|
||||
struct cmd_function_t
|
||||
{
|
||||
cmd_function_t* next;
|
||||
BO4_AssetRef_t name;
|
||||
const char* autoCompleteDir;
|
||||
const char* autoCompleteExt;
|
||||
xcommand_t function;
|
||||
int autoComplete;
|
||||
};
|
||||
|
||||
struct CmdArgs
|
||||
{
|
||||
int nesting;
|
||||
int localClientNum[8];
|
||||
int controllerIndex[8];
|
||||
int argshift[8];
|
||||
int argc[8];
|
||||
const char** argv[8];
|
||||
char textPool[8192];
|
||||
const char* argvPool[512];
|
||||
int usedTextPool[8];
|
||||
int totalUsedArgvPool;
|
||||
int totalUsedTextPool;
|
||||
};
|
||||
|
||||
struct va_info_t
|
||||
{
|
||||
char va_string[4][1024];
|
||||
int index;
|
||||
};
|
||||
|
||||
struct TLSData
|
||||
{
|
||||
va_info_t* vaInfo;
|
||||
jmp_buf* errorJmpBuf;
|
||||
void* traceInfo;
|
||||
CmdArgs* cmdArgs;
|
||||
void* errorData;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ENUMS //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 eGameModes
|
||||
{
|
||||
MODE_GAME_MATCHMAKING_PLAYLIST = 0x0,
|
||||
MODE_GAME_MATCHMAKING_MANUAL = 0x1,
|
||||
MODE_GAME_DEFAULT = 0x2,
|
||||
MODE_GAME_LEAGUE = 0x3,
|
||||
MODE_GAME_THEATER = 0x4,
|
||||
MODE_GAME_COUNT = 0x5,
|
||||
MODE_GAME_INVALID = 0x5,
|
||||
};
|
||||
|
||||
enum eModes : int32_t
|
||||
{
|
||||
MODE_ZOMBIES = 0x0,
|
||||
@ -803,6 +370,10 @@ namespace game
|
||||
CON_LABEL_COUNT = 0x3F
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// CLASSES //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum scoped_critical_section_type : int32_t
|
||||
{
|
||||
SCOPED_CRITSECT_NORMAL = 0x0,
|
||||
@ -822,6 +393,10 @@ namespace game
|
||||
~scoped_critical_section();
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// HAVOK //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct hks_global {};
|
||||
struct hks_callstack
|
||||
{
|
||||
@ -866,9 +441,9 @@ namespace game
|
||||
// ...
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// SYMBOLS //
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
class symbol
|
||||
@ -898,25 +473,49 @@ namespace game
|
||||
T* address_;
|
||||
};
|
||||
|
||||
// Main Functions
|
||||
// Main
|
||||
WEAK symbol<void(const char* file, int line, int code, const char* fmt, ...)> Com_Error_{ 0x14288B410_g };
|
||||
|
||||
// mutex
|
||||
// Sys
|
||||
WEAK symbol<int()> Sys_Milliseconds{ 0x143D89E80_g };
|
||||
WEAK symbol<TLSData* ()> Sys_GetTLS{ 0x143C56140_g };
|
||||
|
||||
// Mutex
|
||||
WEAK symbol<void(scoped_critical_section* sec, int32_t s, scoped_critical_section_type type)> ScopedCriticalSectionConstructor{ 0x14289E3C0_g };
|
||||
WEAK symbol<void(scoped_critical_section* sec)> ScopedCriticalSectionDestructor{ 0x14289E440_g };
|
||||
|
||||
// CMD
|
||||
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{ 0x143CDE880_g };
|
||||
|
||||
// Dvar
|
||||
WEAK symbol<void* (const char* dvarName)> Dvar_FindVar{ 0x143CEBE40_g };
|
||||
WEAK symbol<void* (void* dvarHash)> Dvar_FindVar_Hash{ 0x143CEBED0_g };
|
||||
|
||||
// Live Functions
|
||||
// Cmd
|
||||
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{ 0x143CDE880_g };
|
||||
WEAK symbol<void(int localClientNum, int controllerIndex, const char* buffer)> Cbuf_ExecuteBuffer{ 0x143CDEBE0_g };
|
||||
|
||||
WEAK symbol<void(BO4_AssetRef_t* cmdName, xcommand_t function, cmd_function_t* allocedCmd)> Cmd_AddCommandInternal{ 0x143CDEE80_g };
|
||||
WEAK symbol<void()> Cbuf_AddServerText_f{ 0x143CDE870_g };
|
||||
WEAK symbol<void(BO4_AssetRef_t* cmdName, xcommand_t function, cmd_function_t* allocedCmd)> Cmd_AddServerCommandInternal{ 0x143CDEEF0_g };
|
||||
WEAK symbol<void(int localClientNum, int controllerIndex, const char* text, bool fromRemoteConsole)> Cmd_ExecuteSingleCommand{ 0x143CDF490_g };
|
||||
|
||||
WEAK symbol<void(int localClientNum, int localControllerIndex, const char* text_in,
|
||||
int max_tokens, bool evalExpressions, CmdArgs* args)> Cmd_TokenizeStringKernel{ 0x143CE0750_g };
|
||||
|
||||
WEAK symbol<void()> Cmd_EndTokenizedString{ 0x143CDF070_g };
|
||||
WEAK symbol<void(const char* text_in)> SV_Cmd_TokenizeString{ 0x143CE0A10_g };
|
||||
WEAK symbol<void()> SV_Cmd_EndTokenizedString{ 0x143CE09C0_g };
|
||||
|
||||
// NET
|
||||
WEAK symbol<bool(netsrc_t sock, netadr_t* adr, const void* data, int len)> NET_OutOfBandData{ 0x142E06390_g };
|
||||
WEAK symbol<bool(netsrc_t sock, int length, const void* data, const netadr_t* to)> Sys_SendPacket{ 0x143D89900_g };
|
||||
WEAK symbol<bool(netadr_t* adr, const char* s)> NetAdr_InitFromString{ 0x142E05230_g };
|
||||
WEAK symbol<bool(const netadr_t addr1, const netadr_t addr2)> NetAdr_IsTheSameAddr{ 0x142E053A0_g };
|
||||
|
||||
// Live
|
||||
WEAK symbol<bool(uint64_t, int*)> Live_GetConnectivityInformation{ 0x1437FA460_g };
|
||||
|
||||
// Rendering Functions
|
||||
WEAK symbol<void(const char* text, int maxChars, void* font, float x, float y, float xScale, float yScale, float rotation, float* color, int style, int cursorPos, char cursor, float padding)> T8_AddBaseDrawTextCmd{ 0x143616B60_g };
|
||||
// Renderer
|
||||
WEAK symbol<void(const char* text, int maxChars, void* font, float x, float y, float xScale, float yScale, float rotation,
|
||||
float* color, int style, int cursorPos, char cursor, float padding)> T8_AddBaseDrawTextCmd{ 0x143616B60_g };
|
||||
WEAK symbol<void(float x, float y, float w, float h, float, float, float, float, float* color, void* material)> R_AddCmdDrawStretchPic{ 0x143616790_g };
|
||||
|
||||
WEAK symbol<int(void* font)> R_TextHeight{ 0x1435B2350_g };
|
||||
@ -927,19 +526,18 @@ namespace game
|
||||
|
||||
WEAK symbol<ScreenPlacement* (int localClientNum)> ScrPlace_GetView{ 0x142876E70_g };
|
||||
|
||||
// BuildInfo
|
||||
WEAK symbol<const char* ()> Com_GetBuildVersion{ 0x142892F40_g };
|
||||
WEAK symbol<bool(int controllerIndex, int info, char* outputString, const int outputLen)> Live_SystemInfo{ 0x143804B00_g };
|
||||
|
||||
// ETC
|
||||
WEAK symbol<bool()> Com_IsInGame{ 0x14288FDB0_g };
|
||||
WEAK symbol<bool()> Com_IsRunningUILevel{ 0x14288FDF0_g };
|
||||
WEAK symbol<eModes()> Com_SessionMode_GetMode{ 0x14289EFF0_g };
|
||||
WEAK symbol<eModes(const char* str)> Com_SessionMode_GetModeForAbbreviation{ 0x14289F000_g };
|
||||
WEAK symbol<const char*(eModes mode)> Com_SessionMode_GetAbbreviationForMode{0x14289EC70_g};
|
||||
|
||||
WEAK symbol<int> keyCatchers{ 0x148A53F84_g };
|
||||
WEAK symbol<PlayerKeyState> playerKeys{ 0x148A3EF80_g };
|
||||
|
||||
WEAK symbol<sharedUiInfo_t> sharedUiInfo{ 0x14F956850_g };
|
||||
|
||||
// Scr Functions
|
||||
|
||||
// SCR
|
||||
WEAK symbol<void(scriptInstance_t inst, int value)> ScrVm_AddBool{ 0x14276E760_g };
|
||||
WEAK symbol<void(scriptInstance_t inst, float value)> ScrVm_AddFloat{ 0x14276E9B0_g };
|
||||
WEAK symbol<void(scriptInstance_t inst, BO4_AssetRef_t* value)> ScrVm_AddHash{ 0x14276EAB0_g };
|
||||
@ -981,23 +579,12 @@ namespace game
|
||||
WEAK symbol<uint32_t> gObjFileInfoCount{ 0x1482F76B0_g };
|
||||
WEAK symbol<objFileInfo_t[SCRIPTINSTANCE_MAX][650]> gObjFileInfo{ 0x1482EFCD0_g };
|
||||
|
||||
// lua functions
|
||||
// LUA
|
||||
WEAK symbol<bool(lua_state* luaVM, const char* file)> Lua_CoD_LoadLuaFile{ 0x143962DF0_g };
|
||||
WEAK symbol<void(int code, const char* error, lua_state* s)> Lua_CoD_LuaStateManager_Error{ 0x14398A860_g };
|
||||
WEAK symbol<const char*(lua_state* luaVM, hks_object* obj, size_t* len)> hks_obj_tolstring{ 0x143755730_g };
|
||||
WEAK symbol<float(lua_state* luaVM, const hks_object* obj)> hks_obj_tonumber{ 0x143755A90_g };
|
||||
|
||||
// console labels
|
||||
WEAK symbol<const char*> builtinLabels{ 0x144F11530_g };
|
||||
// gsc types
|
||||
WEAK symbol<const char*> var_typename{ 0x144EED240_g };
|
||||
|
||||
WEAK symbol<void(BO4_AssetRef_t* cmdName, xcommand_t function, cmd_function_t* allocedCmd)> Cmd_AddCommandInternal{0x143CDEE80_g};
|
||||
|
||||
#define Cmd_AddCommand(name, function) \
|
||||
static game::cmd_function_t __cmd_func_##function; \
|
||||
game::BO4_AssetRef_t __cmd_func_name_##function { (int64_t)fnv1a::generate_hash(name), 0 }; \
|
||||
game::Cmd_AddCommandInternal(&__cmd_func_name_##function, function, &__cmd_func_##function)
|
||||
|
||||
#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)
|
||||
@ -1008,11 +595,26 @@ namespace game
|
||||
#define Com_Error(code, fmt, ...) \
|
||||
Com_Error_(__FILE__, __LINE__, code, fmt, ##__VA_ARGS__)
|
||||
|
||||
class scoped_critical_section_guard_lock
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// NAME TABLES //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WEAK symbol<const char*> var_typename{ 0x144EED240_g }; // GSC Types
|
||||
|
||||
WEAK symbol<const char*> builtinLabels{ 0x144F11530_g }; // Console Labels
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// VARIABLES //
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
WEAK symbol<sharedUiInfo_t> sharedUiInfo{ 0x14F956850_g };
|
||||
|
||||
WEAK symbol<cmd_function_t> cmd_functions{ 0x14F99B188_g };
|
||||
WEAK symbol<CmdArgs> sv_cmd_args{ 0x14F998070_g };
|
||||
|
||||
};
|
||||
WEAK symbol<int> keyCatchers{ 0x148A53F84_g };
|
||||
WEAK symbol<PlayerKeyState> playerKeys{ 0x148A3EF80_g };
|
||||
|
||||
// Global game definitions
|
||||
constexpr auto CMD_MAX_NESTING = 8;
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
#include <std_include.hpp>
|
||||
#include "definitions/game.hpp"
|
||||
#include "definitions/xassets.hpp"
|
||||
#include "game_runtime_errors.hpp"
|
||||
|
||||
|
||||
namespace game::runtime_errors
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::unordered_map<uint64_t, const char*> errors =
|
||||
{
|
||||
{ 1045192683, "Scr_RandomFloatRange's second parameter must be greater than the first." },
|
||||
{ 1047729873, "exitlevel already called" },
|
||||
{ 104978404, "cannot cast type to canon" },
|
||||
{ 1072585573, "Raw file is not a file of the right type" },
|
||||
{ 1088278929, "Raw file is not a file of the right type" },
|
||||
{ 1099145600, "Can't find asset" },
|
||||
{ 1132507782, "bad opcode" },
|
||||
{ 1137123674, "GScr_LUINotifyEvent: Expected Istrings, hash or integers only" },
|
||||
{ 1252503459, "caller is not an entity" },
|
||||
{ 1273214009, "CScr_PlayFX: invalid effect" },
|
||||
{ 1333649786, "IsMature can only be called on a player." },
|
||||
{ 1364331101, "Object must be an array" },
|
||||
{ 1377489376, "Gesture key can't have the higher bit set" },
|
||||
{ 1385570291, "assert fail (with message)" },
|
||||
{ 1402557361, "bad opcode" },
|
||||
{ 1403832952, "Attempt to register ClientField failed. Client Field set either already contains a field, or a hash collision has occurred." },
|
||||
{ 1412130119, "parameter can't be cast to a hash" },
|
||||
{ 1427704235, "expected struct type to add value pair" },
|
||||
{ 1480037573, "Invalid canonical name hash" },
|
||||
{ 1480821566, "Error registering client field. Attempted field size is not acceptable bit number range 1->32" },
|
||||
{ 1517473035, "Value out of range. Allowed values: 0 to 2" },
|
||||
{ 1609894461, "bad entity" },
|
||||
{ 1670707254, "linking error" },
|
||||
{ 1850691545, "Debug Break" },
|
||||
{ 1895566756, "dvar is not a 3d vector, but GetDvarVector3D has been called on it" },
|
||||
{ 1909233687, "Optional argument must be a vector type" },
|
||||
{ 1915758537, "RegisterClientField can only accept bit ranges between 1 and 32." },
|
||||
{ 1957162421, "Can't find bgCache entry" },
|
||||
{ 1999906612, "type is not a integer or float" },
|
||||
{ 2078816051, "not a valid name for a clientfield set." },
|
||||
{ 209668787, "RandomInt parm must be positive integer." },
|
||||
{ 2116335949, "function called with too many parameters" },
|
||||
{ 219569925, "hasperk() can only be called on local players" },
|
||||
{ 219686544, "object is not an array index" },
|
||||
{ 2253722136, "CamAnimScripted can only be called on a player." },
|
||||
{ 2269096660, "vector scale expecting vector" },
|
||||
{ 2279633554, "SV_SetConfigstring: bad index" },
|
||||
{ 2331090760, "stack does not have the pool" },
|
||||
{ 2344222932, "assert fail" },
|
||||
{ 2355618801, "Gesture table key can't have the higher bit set" },
|
||||
{ 2408700928, "not a valid name for a clientfield set." },
|
||||
{ 2448966512, "string too long" },
|
||||
{ 245612264, "foreach should be used with an array" },
|
||||
{ 247375020, "Attempting to register client field in client field set using bits, but system is out of space." },
|
||||
{ 2479879368, "RegisterClientField can only accept bit ranges between 1 and 32." },
|
||||
{ 249068885, "Failed to allocate from state pool" },
|
||||
{ 2517242050, "parameter does not exist" },
|
||||
{ 2532286589, "error message" },
|
||||
{ 2538360978, "not a function pointer" },
|
||||
{ 2572009355, "vector scale expecting vector" },
|
||||
{ 2606724305, "parameter does not exist" },
|
||||
{ 2626909173, "exceeded maximum number of script strings" },
|
||||
{ 2681972741, "bad clientfield for name" },
|
||||
{ 2687742442, "Forced script exception." },
|
||||
{ 269518924, "Ammo count must not be negative" },
|
||||
{ 2706458388, "Trying to get a local client index for a client that is not a local client." },
|
||||
{ 2734491973, "Error need at least one argument for LUINotifyEvent." },
|
||||
{ 2737681163, "assert fail (with message)" },
|
||||
{ 2751867714, "self isn't a field object" },
|
||||
{ 2792722947, "RegisterClientField can only accept 5 parameters" },
|
||||
{ 280703902, "parameter does not exist" },
|
||||
{ 2838301872, "Gesture table key can't have the higher bit set" },
|
||||
{ 2855209542, "Cannot call IncrementClientField on a non-'counter' type clientfield." },
|
||||
{ 2940210599, "Invalid Version Handling. Grab Bat !!!" },
|
||||
{ 3015158315, "getperks() can only be called on local players" },
|
||||
{ 3016026156, "Can't find asset" },
|
||||
{ 3030895505, "Whitelist failure for title" },
|
||||
{ 3059411687, "Argument and parameter count mismatch for LUINotifyEvent" },
|
||||
{ 3086288875, "playFx called with (0 0 0) forward direction" },
|
||||
{ 3122940489, "caller is not an entity" },
|
||||
{ 312545010, "not a vector" },
|
||||
{ 3143575744, "parameter does not exist" },
|
||||
{ 317100267, "unmatching types" },
|
||||
{ 3189465155, "Invalid bgCache type" },
|
||||
{ 3221522156, "Failed to alloc client field" },
|
||||
{ 3222417139, "size cannot be applied to type" },
|
||||
{ 3251676101, "Could not load raw file" },
|
||||
{ 3255107847, "LUINotifyEvent: entity must be a player entity" },
|
||||
{ 3288551912, "expected array type to add value pair" },
|
||||
{ 3385008561, "cannot set field on type" },
|
||||
{ 3459949409, "Failed to alloc client field - MAX_CLIENTFIELD_FIELDS_IN_SET=512 exceeded." },
|
||||
{ 3523382186, "ScrEvent map is full, unable to register new event" },
|
||||
{ 3524483616, "Ammo count must not be negative" },
|
||||
{ 3592841213, "cannot directly set the origin on AI. Use the teleport command instead." },
|
||||
{ 359760836, "G_Spawn: no free entities" },
|
||||
{ 3654063291, "ScrEvent map is full, unable to register new event" },
|
||||
{ 3679846953, "LUINotifyEvent: entity must be a player entity" },
|
||||
{ 3699844858, "parameter does not exist" },
|
||||
{ 3761634992, "not a pointer" },
|
||||
{ 3894031202, "Can't find gamedata/playeranim/playeranimtypes.txt" },
|
||||
{ 3967909977, "Trying to get version of a demo when the demo system is idle." },
|
||||
{ 3990130335, "player getperks(<localClientNum>): localClientNum out of range" },
|
||||
{ 4039057166, "LUINotifyEvent: entity must be a player entity" },
|
||||
{ 4047738848, "Invalid opcode (Recovery)" },
|
||||
{ 409067247, "No clientfield named found in set." },
|
||||
{ 4100218247, "Error sending LUI notify event: LUI event name is not precached." },
|
||||
{ 4103906837, "Entity is not an item." },
|
||||
{ 4104994143, "can't allocate more script variables" },
|
||||
{ 4106063796, "key value provided for array is not valid" },
|
||||
{ 4163774148, "Optional argument must be a float or integer type" },
|
||||
{ 4178589916, "Model was not cached by the linker." },
|
||||
{ 4196473479, "parameter does not exist" },
|
||||
{ 4213634562, "precacheLeaderboards must be called before any wait statements in the gametype or level script" },
|
||||
{ 4220857104, "Cannot call IncrementClientField on a 'counter' type clientfield on the frame it is spawned, since newEnts on the clientside will not process 'counter' type clientfields." },
|
||||
{ 467754466, "Error registering client field. bCallbacksFor0WhenNew (CF_CALLBACK_ZERO_ON_NEW_ENT) is disallowed for CF_SCRIPTMOVERFIELDS." },
|
||||
{ 512306404, "not a function pointer" },
|
||||
{ 57350207, "Unknown perk" },
|
||||
{ 580674660, "Unknown ent type in GScr_GetFieldSetForEntityType." },
|
||||
{ 619241173, "Failed to allocate from element pool" },
|
||||
{ 647662103, "parameter can't be cast to a string" },
|
||||
{ 657813230, "Error registering client field. bCallbacksFor0WhenNew (CF_CALLBACK_ZERO_ON_NEW_ENT) is disallowed for counter type clientfields. Due to it's treatment of the old and new val as a ring buffer, the counter type is not valid on a new snapshot, new ent, or demojump" },
|
||||
{ 665902298, "Parameter must be an array" },
|
||||
{ 71894325, "CamAnimScripted or ExtraCamAnimScripted can only be called on a player." },
|
||||
{ 732489269, "Non-player entity passed to UploadStats()" },
|
||||
{ 744499668, "too many vehicles" },
|
||||
{ 750896894, "Invalid bgCache type" },
|
||||
{ 753495682, "RandomIntRange's second parameter must be greater than the first." },
|
||||
{ 754846421, "invalid vehicle spawn origin" },
|
||||
{ 829015102, "var isn't a field object" },
|
||||
{ 876169112, "key value provided for struct is not valid" },
|
||||
{ 887228744, "origin being set to NAN." },
|
||||
{ 904544970, "Attempt to register Client Field post finalization of Client Field registration period failed." },
|
||||
{ 941828720, "exitlevel already called" },
|
||||
{ 946363963, "Invalid opcode" },
|
||||
{ 949934674, "Invalid Version Handling. Grab Bat !!!" },
|
||||
{ 952690413, "parameter can't be cast to a boolean" },
|
||||
{ 962032109, "Entity does not exist." },
|
||||
{ 968521323, "player hasperk(<localClientNum>, <perk>): localClientNum out of range" },
|
||||
{ 4088624643, "Can't find asset" },
|
||||
{ game::runtime_errors::custom_error_id, "Shield Error" }
|
||||
};
|
||||
}
|
||||
|
||||
const char* get_error_message(uint64_t code)
|
||||
{
|
||||
auto it = errors.find(code);
|
||||
// known error
|
||||
if (it != errors.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// read from the csv
|
||||
static game::BO4_AssetRef_t custom_errors_file = game::AssetRef(fnv1a::generate_hash("gamedata/shield/custom_errors.csv"));
|
||||
|
||||
xassets::stringtable_header* table = xassets::DB_FindXAssetHeader(xassets::ASSET_TYPE_STRINGTABLE, &custom_errors_file, false, -1).stringtable;
|
||||
|
||||
if (!table || !table->columns_count || table->columns_count < 2)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < table->rows_count; i++)
|
||||
{
|
||||
auto* rows = &table->values[i * table->columns_count];
|
||||
|
||||
if (rows[0].type != xassets::STC_TYPE_INT || rows[1].type != xassets::STC_TYPE_STRING)
|
||||
{
|
||||
continue; // bad types
|
||||
}
|
||||
|
||||
if (rows[0].value.hash_value == code)
|
||||
{
|
||||
return rows[1].value.string_value;
|
||||
}
|
||||
}
|
||||
|
||||
// unknown
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace game::runtime_errors
|
||||
{
|
||||
constexpr uint64_t custom_error_id = 0x42693201;
|
||||
const char* get_error_message(uint64_t code);
|
||||
}
|
7
source/proxy-dll/definitions/keys.cpp
Normal file
7
source/proxy-dll/definitions/keys.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include <std_include.hpp>
|
||||
#include "keys.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
/* NAMESPACE_PLACE_HOLDER */
|
||||
}
|
216
source/proxy-dll/definitions/keys.hpp
Normal file
216
source/proxy-dll/definitions/keys.hpp
Normal file
@ -0,0 +1,216 @@
|
||||
#pragma once
|
||||
|
||||
namespace game
|
||||
{
|
||||
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];
|
||||
};
|
||||
}
|
7
source/proxy-dll/definitions/network.cpp
Normal file
7
source/proxy-dll/definitions/network.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include <std_include.hpp>
|
||||
#include "network.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
/* NAMESPACE_PLACE_HOLDER */
|
||||
}
|
59
source/proxy-dll/definitions/network.hpp
Normal file
59
source/proxy-dll/definitions/network.hpp
Normal file
@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
namespace game
|
||||
{
|
||||
struct netipv4_t
|
||||
{
|
||||
byte a;
|
||||
byte b;
|
||||
byte c;
|
||||
byte d;
|
||||
};
|
||||
|
||||
enum netadrtype_t
|
||||
{
|
||||
NA_BOT = 0x0,
|
||||
NA_BAD = 0x1,
|
||||
NA_LOOPBACK = 0x2,
|
||||
NA_RAWIP = 0x3,
|
||||
NA_IP = 0x4,
|
||||
};
|
||||
|
||||
enum netsrc_t
|
||||
{
|
||||
NS_NULL = -1,
|
||||
NS_CLIENT1 = 0x0,
|
||||
NS_CLIENT2 = 0x1,
|
||||
NS_CLIENT3 = 0x2,
|
||||
NS_CLIENT4 = 0x3,
|
||||
NS_SERVER = 0x4,
|
||||
NS_MAXCLIENTS = 0x4,
|
||||
NS_PACKET = 0x5,
|
||||
};
|
||||
|
||||
struct netadr_t
|
||||
{
|
||||
union
|
||||
{
|
||||
netipv4_t ipv4;
|
||||
uint32_t addr;
|
||||
};
|
||||
|
||||
uint16_t port;
|
||||
netadrtype_t type;
|
||||
netsrc_t localNetID;
|
||||
};
|
||||
|
||||
struct msg_t
|
||||
{
|
||||
byte* data; //0x0000
|
||||
int maxsize; //0x0008
|
||||
int cursize; //0x000C
|
||||
int readcount; //0x0010
|
||||
char pad_unknown[32]; //0x0014
|
||||
bool unknown; //0x0034
|
||||
bool overflowed; //0x0035
|
||||
bool readOnly; //0x0036
|
||||
};
|
||||
|
||||
}
|
7
source/proxy-dll/definitions/scripting.cpp
Normal file
7
source/proxy-dll/definitions/scripting.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include <std_include.hpp>
|
||||
#include "scripting.hpp"
|
||||
|
||||
namespace game
|
||||
{
|
||||
/* NAMESPACE_PLACE_HOLDER */
|
||||
}
|
286
source/proxy-dll/definitions/scripting.hpp
Normal file
286
source/proxy-dll/definitions/scripting.hpp
Normal file
@ -0,0 +1,286 @@
|
||||
#pragma once
|
||||
|
||||
namespace game
|
||||
{
|
||||
typedef uint32_t ScrVarIndex_t;
|
||||
typedef uint64_t ScrVarNameIndex_t;
|
||||
|
||||
struct GSC_IMPORT_ITEM
|
||||
{
|
||||
uint32_t name;
|
||||
uint32_t name_space;
|
||||
uint16_t num_address;
|
||||
uint8_t param_count;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
struct GSC_EXPORT_ITEM
|
||||
{
|
||||
uint32_t checksum;
|
||||
uint32_t address;
|
||||
uint32_t name;
|
||||
uint32_t name_space;
|
||||
uint32_t callback_event;
|
||||
uint8_t param_count;
|
||||
uint8_t flags;
|
||||
};
|
||||
|
||||
struct GSC_OBJ
|
||||
{
|
||||
byte magic[8];
|
||||
int32_t crc;
|
||||
int32_t pad;
|
||||
uint64_t name;
|
||||
int32_t include_offset;
|
||||
uint16_t string_count;
|
||||
uint16_t exports_count;
|
||||
int32_t start_data;
|
||||
int32_t string_offset;
|
||||
int16_t imports_count;
|
||||
uint16_t fixup_count;
|
||||
int32_t ukn2c;
|
||||
int32_t exports_offset;
|
||||
int32_t ukn34;
|
||||
int32_t imports_offset;
|
||||
uint16_t globalvar_count;
|
||||
int32_t fixup_offset;
|
||||
int32_t globalvar_offset;
|
||||
int32_t script_size;
|
||||
int32_t requires_implements_offset;
|
||||
int32_t ukn50;
|
||||
int32_t data_length;
|
||||
uint16_t include_count;
|
||||
byte ukn5a;
|
||||
byte requires_implements_count;
|
||||
|
||||
inline GSC_EXPORT_ITEM* get_exports()
|
||||
{
|
||||
return reinterpret_cast<GSC_EXPORT_ITEM*>(magic + exports_offset);
|
||||
}
|
||||
|
||||
inline GSC_IMPORT_ITEM* get_imports()
|
||||
{
|
||||
return reinterpret_cast<GSC_IMPORT_ITEM*>(magic + imports_offset);
|
||||
}
|
||||
|
||||
inline uint64_t* get_includes()
|
||||
{
|
||||
return reinterpret_cast<uint64_t*>(magic + include_offset);
|
||||
}
|
||||
|
||||
inline GSC_EXPORT_ITEM* get_exports_end()
|
||||
{
|
||||
return get_exports() + exports_count;
|
||||
}
|
||||
|
||||
inline uint64_t* get_includes_end()
|
||||
{
|
||||
return get_includes() + include_count;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
enum scriptInstance_t : int32_t
|
||||
{
|
||||
SCRIPTINSTANCE_SERVER = 0x0,
|
||||
SCRIPTINSTANCE_CLIENT = 0x1,
|
||||
SCRIPTINSTANCE_MAX = 0x2,
|
||||
};
|
||||
|
||||
typedef void (*BuiltinFunction)(scriptInstance_t);
|
||||
|
||||
|
||||
struct BO4_BuiltinFunctionDef
|
||||
{
|
||||
uint32_t canonId;
|
||||
uint32_t min_args;
|
||||
uint32_t max_args;
|
||||
BuiltinFunction actionFunc;
|
||||
uint32_t type;
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) BO4_scrVarGlobalVars_t
|
||||
{
|
||||
uint32_t name;
|
||||
ScrVarIndex_t id;
|
||||
bool persist;
|
||||
};
|
||||
|
||||
|
||||
enum ScrVarType_t : uint32_t {
|
||||
TYPE_UNDEFINED = 0x0,
|
||||
TYPE_POINTER = 0x1,
|
||||
TYPE_STRING = 0x2,
|
||||
TYPE_VECTOR = 0x3,
|
||||
TYPE_HASH = 0x4,
|
||||
TYPE_FLOAT = 0x5,
|
||||
TYPE_INTEGER = 0x6,
|
||||
TYPE_UINTPTR = 0x7,
|
||||
TYPE_ENTITY_OFFSET = 0x8,
|
||||
TYPE_CODEPOS = 0x9,
|
||||
TYPE_PRECODEPOS = 0xA,
|
||||
TYPE_API_FUNCTION = 0xB,
|
||||
TYPE_SCRIPT_FUNCTION = 0xC,
|
||||
TYPE_STACK = 0xD,
|
||||
TYPE_THREAD = 0xE,
|
||||
TYPE_NOTIFY_THREAD = 0xF,
|
||||
TYPE_TIME_THREAD = 0x10,
|
||||
TYPE_FRAME_THREAD = 0x11,
|
||||
TYPE_CHILD_THREAD = 0x12,
|
||||
TYPE_CLASS = 0x13,
|
||||
TYPE_SHARED_STRUCT = 0x14,
|
||||
TYPE_STRUCT = 0x15,
|
||||
TYPE_REMOVED_ENTITY = 0x16,
|
||||
TYPE_ENTITY = 0x17,
|
||||
TYPE_ARRAY = 0x18,
|
||||
TYPE_REMOVED_THREAD = 0x19,
|
||||
TYPE_FREE = 0x1a,
|
||||
TYPE_THREAD_LIST = 0x1b,
|
||||
TYPE_ENT_LIST = 0x1c,
|
||||
TYPE_COUNT
|
||||
};
|
||||
|
||||
|
||||
struct BO4_scrVarPub {
|
||||
const char* fieldBuffer;
|
||||
const char* error_message;
|
||||
byte* programBuffer;
|
||||
byte* endScriptBuffer;
|
||||
byte* programHunkUser; // HunkUser
|
||||
BO4_scrVarGlobalVars_t globalVars[16];
|
||||
ScrVarNameIndex_t entFieldNameIndex;
|
||||
ScrVarIndex_t freeEntList;
|
||||
ScrVarIndex_t tempVariable;
|
||||
uint32_t checksum;
|
||||
uint32_t entId;
|
||||
uint32_t varHighWatermark;
|
||||
uint32_t numScriptThreads;
|
||||
uint32_t numVarAllocations;
|
||||
int32_t varHighWatermarkId;
|
||||
};
|
||||
|
||||
union ScrVarValueUnion_t
|
||||
{
|
||||
int64_t intValue;
|
||||
uintptr_t uintptrValue;
|
||||
float floatValue;
|
||||
int32_t stringValue;
|
||||
const float* vectorValue;
|
||||
byte* codePosValue;
|
||||
ScrVarIndex_t pointerValue;
|
||||
};
|
||||
|
||||
struct ScrVarValue_t
|
||||
{
|
||||
ScrVarValueUnion_t u;
|
||||
ScrVarType_t type;
|
||||
};
|
||||
|
||||
struct ScrVar_t_Info
|
||||
{
|
||||
uint32_t nameType : 3;
|
||||
uint32_t flags : 5;
|
||||
uint32_t refCount : 24;
|
||||
};
|
||||
|
||||
struct ScrVar_t
|
||||
{
|
||||
ScrVarNameIndex_t nameIndex;
|
||||
ScrVar_t_Info _anon_0;
|
||||
ScrVarIndex_t nextSibling;
|
||||
ScrVarIndex_t prevSibling;
|
||||
ScrVarIndex_t parentId;
|
||||
ScrVarIndex_t nameSearchHashList;
|
||||
uint32_t pad0;
|
||||
};
|
||||
|
||||
union ScrVarObjectInfo1_t
|
||||
{
|
||||
uint64_t object_o;
|
||||
unsigned int size;
|
||||
ScrVarIndex_t nextEntId;
|
||||
ScrVarIndex_t self;
|
||||
ScrVarIndex_t free;
|
||||
};
|
||||
|
||||
union ScrVarObjectInfo2_t
|
||||
{
|
||||
uint32_t object_w;
|
||||
ScrVarIndex_t stackId;
|
||||
};
|
||||
|
||||
struct function_stack_t
|
||||
{
|
||||
byte* pos;
|
||||
ScrVarValue_t* top;
|
||||
ScrVarValue_t* startTop;
|
||||
ScrVarIndex_t threadId;
|
||||
uint16_t localVarCount;
|
||||
uint16_t profileInfoCount;
|
||||
};
|
||||
|
||||
struct function_frame_t
|
||||
{
|
||||
function_stack_t fs;
|
||||
};
|
||||
|
||||
struct ScrVmContext_t
|
||||
{
|
||||
ScrVarIndex_t fieldValueId;
|
||||
ScrVarIndex_t objectId;
|
||||
byte* lastGoodPos;
|
||||
ScrVarValue_t* lastGoodTop;
|
||||
};
|
||||
|
||||
typedef void (*VM_OP_FUNC)(scriptInstance_t, function_stack_t*, ScrVmContext_t*, bool*);
|
||||
|
||||
|
||||
struct BO4_scrVarGlob
|
||||
{
|
||||
ScrVarIndex_t* scriptNameSearchHashList;
|
||||
ScrVar_t* scriptVariables;
|
||||
ScrVarObjectInfo1_t* scriptVariablesObjectInfo1;
|
||||
ScrVarObjectInfo2_t* scriptVariablesObjectInfo2;
|
||||
ScrVarValue_t* scriptValues;
|
||||
};
|
||||
|
||||
struct BO4_scrVmPub
|
||||
{
|
||||
void* unk0;
|
||||
void* unk8;
|
||||
void* executionQueueHeap; // HunkUser
|
||||
void* timeByValueQueue; // VmExecutionQueueData_t
|
||||
void* timeByThreadQueue[1024]; // VmExecutionQueue_t
|
||||
void* frameByValueQueue; // VmExecutionQueueData_t
|
||||
void* frameByThreadQueue[1024]; // VmExecutionQueue_t
|
||||
void* timeoutByValueList; // VmExecutionQueueData_t
|
||||
void* timeoutByThreadList[1024]; // VmExecutionQueue_t
|
||||
void* notifyByObjectQueue[1024]; // VmExecutionNotifyQueue_t
|
||||
void* notifyByThreadQueue[1024]; // VmExecutionNotifyQueue_t
|
||||
void* endonByObjectList[1024]; // VmExecutionNotifyQueue_t
|
||||
void* endonByThreadList[1024]; // VmExecutionNotifyQueue_t
|
||||
ScrVarIndex_t* localVars;
|
||||
ScrVarValue_t* maxstack;
|
||||
function_frame_t* function_frame;
|
||||
ScrVarValue_t* top;
|
||||
function_frame_t function_frame_start[64];
|
||||
ScrVarValue_t stack[2048];
|
||||
uint32_t time;
|
||||
uint32_t frame;
|
||||
int function_count;
|
||||
int callNesting;
|
||||
unsigned int inparamcount;
|
||||
bool showError;
|
||||
bool systemInitialized;
|
||||
bool vmInitialized;
|
||||
bool isShutdown;
|
||||
};
|
||||
|
||||
struct objFileInfo_t
|
||||
{
|
||||
GSC_OBJ* activeVersion;
|
||||
int slot;
|
||||
int refCount;
|
||||
uint32_t groupId;
|
||||
};
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#include <std_include.hpp>
|
||||
#include "variables.hpp"
|
||||
#include "game.hpp"
|
||||
#include "xassets.hpp"
|
||||
#include "component/hashes.hpp"
|
||||
|
||||
namespace fnv1a
|
||||
@ -67,7 +69,7 @@ namespace fnv1a
|
||||
|
||||
namespace variables
|
||||
{
|
||||
std::vector<varEntry> dvars_record =
|
||||
std::vector<varEntry> dvars_table =
|
||||
{
|
||||
{
|
||||
"aim_slowdown_enabled",
|
||||
@ -6521,17 +6523,12 @@ namespace variables
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<varEntry> commands_record =
|
||||
std::vector<varEntry> commands_table =
|
||||
{
|
||||
{
|
||||
"quit",
|
||||
"Shutdown the Game [Com_Quit_f]",
|
||||
0x1DEE6107B26F8BB6
|
||||
},
|
||||
{
|
||||
"reload_mods",
|
||||
"Reload the shield mods",
|
||||
0x6cb53357b4ef835c
|
||||
}
|
||||
};
|
||||
|
||||
@ -6540,7 +6537,7 @@ namespace variables
|
||||
static std::vector<const char*> dvars;
|
||||
if (!dvars.empty()) return dvars;
|
||||
|
||||
for (const auto& dvar : dvars_record)
|
||||
for (const auto& dvar : dvars_table)
|
||||
{
|
||||
dvars.push_back(dvar.name.data());
|
||||
}
|
||||
@ -6553,7 +6550,7 @@ namespace variables
|
||||
static std::vector<const char*> commands;
|
||||
if (!commands.empty()) return commands;
|
||||
|
||||
for (const auto& cmd : commands_record)
|
||||
for (const auto& cmd : commands_table)
|
||||
{
|
||||
commands.push_back(cmd.name.data());
|
||||
}
|
||||
@ -6561,3 +6558,178 @@ namespace variables
|
||||
return commands;
|
||||
}
|
||||
}
|
||||
|
||||
namespace runtime_errors
|
||||
{
|
||||
std::unordered_map<uint64_t, const char*> errors =
|
||||
{
|
||||
{ 1045192683, "Scr_RandomFloatRange's second parameter must be greater than the first." },
|
||||
{ 1047729873, "exitlevel already called" },
|
||||
{ 104978404, "cannot cast type to canon" },
|
||||
{ 1072585573, "Raw file is not a file of the right type" },
|
||||
{ 1088278929, "Raw file is not a file of the right type" },
|
||||
{ 1099145600, "Can't find asset" },
|
||||
{ 1132507782, "bad opcode" },
|
||||
{ 1137123674, "GScr_LUINotifyEvent: Expected Istrings, hash or integers only" },
|
||||
{ 1252503459, "caller is not an entity" },
|
||||
{ 1273214009, "CScr_PlayFX: invalid effect" },
|
||||
{ 1333649786, "IsMature can only be called on a player." },
|
||||
{ 1364331101, "Object must be an array" },
|
||||
{ 1377489376, "Gesture key can't have the higher bit set" },
|
||||
{ 1385570291, "assert fail (with message)" },
|
||||
{ 1402557361, "bad opcode" },
|
||||
{ 1403832952, "Attempt to register ClientField failed. Client Field set either already contains a field, or a hash collision has occurred." },
|
||||
{ 1412130119, "parameter can't be cast to a hash" },
|
||||
{ 1427704235, "expected struct type to add value pair" },
|
||||
{ 1480037573, "Invalid canonical name hash" },
|
||||
{ 1480821566, "Error registering client field. Attempted field size is not acceptable bit number range 1->32" },
|
||||
{ 1517473035, "Value out of range. Allowed values: 0 to 2" },
|
||||
{ 1609894461, "bad entity" },
|
||||
{ 1670707254, "linking error" },
|
||||
{ 1850691545, "Debug Break" },
|
||||
{ 1895566756, "dvar is not a 3d vector, but GetDvarVector3D has been called on it" },
|
||||
{ 1909233687, "Optional argument must be a vector type" },
|
||||
{ 1915758537, "RegisterClientField can only accept bit ranges between 1 and 32." },
|
||||
{ 1957162421, "Can't find bgCache entry" },
|
||||
{ 1999906612, "type is not a integer or float" },
|
||||
{ 2078816051, "not a valid name for a clientfield set." },
|
||||
{ 209668787, "RandomInt parm must be positive integer." },
|
||||
{ 2116335949, "function called with too many parameters" },
|
||||
{ 219569925, "hasperk() can only be called on local players" },
|
||||
{ 219686544, "object is not an array index" },
|
||||
{ 2253722136, "CamAnimScripted can only be called on a player." },
|
||||
{ 2269096660, "vector scale expecting vector" },
|
||||
{ 2279633554, "SV_SetConfigstring: bad index" },
|
||||
{ 2331090760, "stack does not have the pool" },
|
||||
{ 2344222932, "assert fail" },
|
||||
{ 2355618801, "Gesture table key can't have the higher bit set" },
|
||||
{ 2408700928, "not a valid name for a clientfield set." },
|
||||
{ 2448966512, "string too long" },
|
||||
{ 245612264, "foreach should be used with an array" },
|
||||
{ 247375020, "Attempting to register client field in client field set using bits, but system is out of space." },
|
||||
{ 2479879368, "RegisterClientField can only accept bit ranges between 1 and 32." },
|
||||
{ 249068885, "Failed to allocate from state pool" },
|
||||
{ 2517242050, "parameter does not exist" },
|
||||
{ 2532286589, "error message" },
|
||||
{ 2538360978, "not a function pointer" },
|
||||
{ 2572009355, "vector scale expecting vector" },
|
||||
{ 2606724305, "parameter does not exist" },
|
||||
{ 2626909173, "exceeded maximum number of script strings" },
|
||||
{ 2681972741, "bad clientfield for name" },
|
||||
{ 2687742442, "Forced script exception." },
|
||||
{ 269518924, "Ammo count must not be negative" },
|
||||
{ 2706458388, "Trying to get a local client index for a client that is not a local client." },
|
||||
{ 2734491973, "Error need at least one argument for LUINotifyEvent." },
|
||||
{ 2737681163, "assert fail (with message)" },
|
||||
{ 2751867714, "self isn't a field object" },
|
||||
{ 2792722947, "RegisterClientField can only accept 5 parameters" },
|
||||
{ 280703902, "parameter does not exist" },
|
||||
{ 2838301872, "Gesture table key can't have the higher bit set" },
|
||||
{ 2855209542, "Cannot call IncrementClientField on a non-'counter' type clientfield." },
|
||||
{ 2940210599, "Invalid Version Handling. Grab Bat !!!" },
|
||||
{ 3015158315, "getperks() can only be called on local players" },
|
||||
{ 3016026156, "Can't find asset" },
|
||||
{ 3030895505, "Whitelist failure for title" },
|
||||
{ 3059411687, "Argument and parameter count mismatch for LUINotifyEvent" },
|
||||
{ 3086288875, "playFx called with (0 0 0) forward direction" },
|
||||
{ 3122940489, "caller is not an entity" },
|
||||
{ 312545010, "not a vector" },
|
||||
{ 3143575744, "parameter does not exist" },
|
||||
{ 317100267, "unmatching types" },
|
||||
{ 3189465155, "Invalid bgCache type" },
|
||||
{ 3221522156, "Failed to alloc client field" },
|
||||
{ 3222417139, "size cannot be applied to type" },
|
||||
{ 3251676101, "Could not load raw file" },
|
||||
{ 3255107847, "LUINotifyEvent: entity must be a player entity" },
|
||||
{ 3288551912, "expected array type to add value pair" },
|
||||
{ 3385008561, "cannot set field on type" },
|
||||
{ 3459949409, "Failed to alloc client field - MAX_CLIENTFIELD_FIELDS_IN_SET=512 exceeded." },
|
||||
{ 3523382186, "ScrEvent map is full, unable to register new event" },
|
||||
{ 3524483616, "Ammo count must not be negative" },
|
||||
{ 3592841213, "cannot directly set the origin on AI. Use the teleport command instead." },
|
||||
{ 359760836, "G_Spawn: no free entities" },
|
||||
{ 3654063291, "ScrEvent map is full, unable to register new event" },
|
||||
{ 3679846953, "LUINotifyEvent: entity must be a player entity" },
|
||||
{ 3699844858, "parameter does not exist" },
|
||||
{ 3761634992, "not a pointer" },
|
||||
{ 3894031202, "Can't find gamedata/playeranim/playeranimtypes.txt" },
|
||||
{ 3967909977, "Trying to get version of a demo when the demo system is idle." },
|
||||
{ 3990130335, "player getperks(<localClientNum>): localClientNum out of range" },
|
||||
{ 4039057166, "LUINotifyEvent: entity must be a player entity" },
|
||||
{ 4047738848, "Invalid opcode (Recovery)" },
|
||||
{ 409067247, "No clientfield named found in set." },
|
||||
{ 4100218247, "Error sending LUI notify event: LUI event name is not precached." },
|
||||
{ 4103906837, "Entity is not an item." },
|
||||
{ 4104994143, "can't allocate more script variables" },
|
||||
{ 4106063796, "key value provided for array is not valid" },
|
||||
{ 4163774148, "Optional argument must be a float or integer type" },
|
||||
{ 4178589916, "Model was not cached by the linker." },
|
||||
{ 4196473479, "parameter does not exist" },
|
||||
{ 4213634562, "precacheLeaderboards must be called before any wait statements in the gametype or level script" },
|
||||
{ 4220857104, "Cannot call IncrementClientField on a 'counter' type clientfield on the frame it is spawned, since newEnts on the clientside will not process 'counter' type clientfields." },
|
||||
{ 467754466, "Error registering client field. bCallbacksFor0WhenNew (CF_CALLBACK_ZERO_ON_NEW_ENT) is disallowed for CF_SCRIPTMOVERFIELDS." },
|
||||
{ 512306404, "not a function pointer" },
|
||||
{ 57350207, "Unknown perk" },
|
||||
{ 580674660, "Unknown ent type in GScr_GetFieldSetForEntityType." },
|
||||
{ 619241173, "Failed to allocate from element pool" },
|
||||
{ 647662103, "parameter can't be cast to a string" },
|
||||
{ 657813230, "Error registering client field. bCallbacksFor0WhenNew (CF_CALLBACK_ZERO_ON_NEW_ENT) is disallowed for counter type clientfields. Due to it's treatment of the old and new val as a ring buffer, the counter type is not valid on a new snapshot, new ent, or demojump" },
|
||||
{ 665902298, "Parameter must be an array" },
|
||||
{ 71894325, "CamAnimScripted or ExtraCamAnimScripted can only be called on a player." },
|
||||
{ 732489269, "Non-player entity passed to UploadStats()" },
|
||||
{ 744499668, "too many vehicles" },
|
||||
{ 750896894, "Invalid bgCache type" },
|
||||
{ 753495682, "RandomIntRange's second parameter must be greater than the first." },
|
||||
{ 754846421, "invalid vehicle spawn origin" },
|
||||
{ 829015102, "var isn't a field object" },
|
||||
{ 876169112, "key value provided for struct is not valid" },
|
||||
{ 887228744, "origin being set to NAN." },
|
||||
{ 904544970, "Attempt to register Client Field post finalization of Client Field registration period failed." },
|
||||
{ 941828720, "exitlevel already called" },
|
||||
{ 946363963, "Invalid opcode" },
|
||||
{ 949934674, "Invalid Version Handling. Grab Bat !!!" },
|
||||
{ 952690413, "parameter can't be cast to a boolean" },
|
||||
{ 962032109, "Entity does not exist." },
|
||||
{ 968521323, "player hasperk(<localClientNum>, <perk>): localClientNum out of range" },
|
||||
{ 4088624643, "Can't find asset" },
|
||||
{ custom_error_id, "Shield Error" }
|
||||
};
|
||||
|
||||
const char* get_error_message(uint64_t code)
|
||||
{
|
||||
auto it = errors.find(code);
|
||||
// known error
|
||||
if (it != errors.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// read from the csv
|
||||
static game::BO4_AssetRef_t custom_errors_file = game::AssetRef(fnv1a::generate_hash("gamedata/shield/custom_errors.csv"));
|
||||
|
||||
xassets::stringtable_header* table = xassets::DB_FindXAssetHeader(xassets::ASSET_TYPE_STRINGTABLE, &custom_errors_file, false, -1).stringtable;
|
||||
|
||||
if (!table || !table->columns_count || table->columns_count < 2)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < table->rows_count; i++)
|
||||
{
|
||||
auto* rows = &table->values[i * table->columns_count];
|
||||
|
||||
if (rows[0].type != xassets::STC_TYPE_INT || rows[1].type != xassets::STC_TYPE_STRING)
|
||||
{
|
||||
continue; // bad types
|
||||
}
|
||||
|
||||
if (rows[0].value.hash_value == code)
|
||||
{
|
||||
return rows[1].value.string_value;
|
||||
}
|
||||
}
|
||||
|
||||
// unknown
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -21,9 +21,15 @@ namespace variables
|
||||
uintptr_t pointer = 0;
|
||||
};
|
||||
|
||||
extern std::vector<varEntry> dvars_record;
|
||||
extern std::vector<varEntry> commands_record;
|
||||
extern std::vector<varEntry> dvars_table;
|
||||
extern std::vector<varEntry> commands_table;
|
||||
|
||||
std::vector<const char*> get_dvars_list();
|
||||
std::vector<const char*> get_commands_list();
|
||||
}
|
||||
|
||||
namespace runtime_errors
|
||||
{
|
||||
constexpr uint64_t custom_error_id = 0x42693201;
|
||||
const char* get_error_message(uint64_t code);
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
#include <std_include.hpp>
|
||||
|
||||
#include "definitions/game.hpp"
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include <utilities/io.hpp>
|
||||
#include <utilities/nt.hpp>
|
||||
#include <utilities/hook.hpp>
|
||||
@ -36,12 +37,16 @@ namespace
|
||||
|
||||
INT WINAPI get_system_metrics(int nIndex)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
logger::write(logger::LOG_TYPE_DEBUG, "get_system_metrics(%i)", nIndex);
|
||||
#endif // DEBUG
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
game::verify_game_version();
|
||||
|
||||
component_loader::post_unpack();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return GetSystemMetrics(nIndex);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user