From 78dd80c7fb007adc9c7af50165d495c66b37d1ab Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Tue, 1 Mar 2022 21:56:21 +0200 Subject: [PATCH 001/346] open server list easier --- src/client/component/server_list.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index 76c68058..bbf55a86 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -12,6 +12,7 @@ #include #include "console.hpp" +#include "command.hpp" namespace server_list { @@ -372,7 +373,15 @@ namespace server_list if (!game::environment::is_mp()) return; localized_strings::override("PLATFORM_SYSTEM_LINK_TITLE", "SERVER LIST"); + localized_strings::override("MENU_NUMPLAYERS", "Players"); + // small command until ui scripting + command::add("openServerList", []() + { + refresh_server_list(); + command::execute("lui_open menu_systemlink_join\n"); + }); + // hook LUI_OpenMenu to refresh server list for system link menu lui_open_menu_hook.create(game::LUI_OpenMenu, lui_open_menu_stub); From 10d8a9696ad25012aedf3b62c31400a5b139f3fb Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Tue, 1 Mar 2022 22:14:41 +0200 Subject: [PATCH 002/346] scripting components --- src/client/component/scripting.cpp | 119 ++ src/client/component/scripting.hpp | 11 + src/client/game/scripting/entity.cpp | 120 ++ src/client/game/scripting/entity.hpp | 50 + src/client/game/scripting/event.hpp | 13 + src/client/game/scripting/execution.cpp | 250 +++ src/client/game/scripting/execution.hpp | 36 + src/client/game/scripting/function_tables.cpp | 1535 +++++++++++++++++ src/client/game/scripting/functions.cpp | 106 ++ src/client/game/scripting/functions.hpp | 16 + src/client/game/scripting/lua/context.cpp | 489 ++++++ src/client/game/scripting/lua/context.hpp | 45 + src/client/game/scripting/lua/engine.cpp | 75 + src/client/game/scripting/lua/engine.hpp | 11 + src/client/game/scripting/lua/error.cpp | 37 + src/client/game/scripting/lua/error.hpp | 8 + .../game/scripting/lua/event_handler.cpp | 174 ++ .../game/scripting/lua/event_handler.hpp | 58 + src/client/game/scripting/lua/scheduler.cpp | 171 ++ src/client/game/scripting/lua/scheduler.hpp | 54 + .../game/scripting/lua/value_conversion.cpp | 319 ++++ .../game/scripting/lua/value_conversion.hpp | 11 + src/client/game/scripting/safe_execution.cpp | 72 + src/client/game/scripting/safe_execution.hpp | 10 + src/client/game/scripting/script_value.cpp | 278 +++ src/client/game/scripting/script_value.hpp | 52 + src/client/game/scripting/stack_isolation.cpp | 27 + src/client/game/scripting/stack_isolation.hpp | 25 + src/client/game/scripting/variable_value.cpp | 68 + src/client/game/scripting/variable_value.hpp | 27 + src/client/game/scripting/vector.cpp | 85 + src/client/game/scripting/vector.hpp | 31 + 32 files changed, 4383 insertions(+) create mode 100644 src/client/component/scripting.cpp create mode 100644 src/client/component/scripting.hpp create mode 100644 src/client/game/scripting/entity.cpp create mode 100644 src/client/game/scripting/entity.hpp create mode 100644 src/client/game/scripting/event.hpp create mode 100644 src/client/game/scripting/execution.cpp create mode 100644 src/client/game/scripting/execution.hpp create mode 100644 src/client/game/scripting/function_tables.cpp create mode 100644 src/client/game/scripting/functions.cpp create mode 100644 src/client/game/scripting/functions.hpp create mode 100644 src/client/game/scripting/lua/context.cpp create mode 100644 src/client/game/scripting/lua/context.hpp create mode 100644 src/client/game/scripting/lua/engine.cpp create mode 100644 src/client/game/scripting/lua/engine.hpp create mode 100644 src/client/game/scripting/lua/error.cpp create mode 100644 src/client/game/scripting/lua/error.hpp create mode 100644 src/client/game/scripting/lua/event_handler.cpp create mode 100644 src/client/game/scripting/lua/event_handler.hpp create mode 100644 src/client/game/scripting/lua/scheduler.cpp create mode 100644 src/client/game/scripting/lua/scheduler.hpp create mode 100644 src/client/game/scripting/lua/value_conversion.cpp create mode 100644 src/client/game/scripting/lua/value_conversion.hpp create mode 100644 src/client/game/scripting/safe_execution.cpp create mode 100644 src/client/game/scripting/safe_execution.hpp create mode 100644 src/client/game/scripting/script_value.cpp create mode 100644 src/client/game/scripting/script_value.hpp create mode 100644 src/client/game/scripting/stack_isolation.cpp create mode 100644 src/client/game/scripting/stack_isolation.hpp create mode 100644 src/client/game/scripting/variable_value.cpp create mode 100644 src/client/game/scripting/variable_value.hpp create mode 100644 src/client/game/scripting/vector.cpp create mode 100644 src/client/game/scripting/vector.hpp diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp new file mode 100644 index 00000000..99988189 --- /dev/null +++ b/src/client/component/scripting.cpp @@ -0,0 +1,119 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include + +#include "game/scripting/entity.hpp" +#include "game/scripting/functions.hpp" +#include "game/scripting/event.hpp" +#include "game/scripting/lua/engine.hpp" +#include "game/scripting/execution.hpp" + +#include "scheduler.hpp" +#include "scripting.hpp" + +namespace scripting +{ + std::unordered_map> script_function_table; + + namespace + { + utils::hook::detour vm_notify_hook; + utils::hook::detour scr_load_level_hook; + utils::hook::detour g_shutdown_game_hook; + + utils::hook::detour scr_set_thread_position_hook; + utils::hook::detour process_script_hook; + + std::string current_file; + + void vm_notify_stub(const unsigned int notify_list_owner_id, const game::scr_string_t string_value, + game::VariableValue* top) + { + if (!game::VirtualLobby_Loaded()) + { + const auto* string = game::SL_ConvertToString(string_value); + if (string) + { + event e; + e.name = string; + e.entity = notify_list_owner_id; + + for (auto* value = top; value->type != game::SCRIPT_END; --value) + { + e.arguments.emplace_back(*value); + } + + if (e.name == "connected") + { + scripting::clear_entity_fields(e.entity); + } + + lua::engine::notify(e); + } + } + + vm_notify_hook.invoke(notify_list_owner_id, string_value, top); + } + + void scr_load_level_stub() + { + scr_load_level_hook.invoke(); + if (!game::VirtualLobby_Loaded()) + { + lua::engine::start(); + } + } + + void g_shutdown_game_stub(const int free_scripts) + { + lua::engine::stop(); + return g_shutdown_game_hook.invoke(free_scripts); + } + + void process_script_stub(const char* filename) + { + const auto file_id = atoi(filename); + if (file_id) + { + current_file = scripting::find_token(file_id); + } + else + { + current_file = filename; + } + + process_script_hook.invoke(filename); + } + + void scr_set_thread_position_stub(unsigned int threadName, const char* codePos) + { + const auto function_name = scripting::find_token(threadName); + script_function_table[current_file][function_name] = codePos; + scr_set_thread_position_hook.invoke(threadName, codePos); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + vm_notify_hook.create(SELECT_VALUE(0x140320E50, 0x1404479F0 ), vm_notify_stub); // H1MP + // SP address is wrong, but should be ok + scr_load_level_hook.create(SELECT_VALUE(0x140005260, 0x1403727C0), scr_load_level_stub); // H1MP + g_shutdown_game_hook.create(SELECT_VALUE(0x140228BA0, 0x140345A60), g_shutdown_game_stub); // H1MP + + scr_set_thread_position_hook.create(SELECT_VALUE(0x1403115E0, 0x140437D10), scr_set_thread_position_stub); // H1MP + process_script_hook.create(SELECT_VALUE(0x14031AB30, 0x1404417E0), process_script_stub); // H1MP + + scheduler::loop([]() + { + lua::engine::run_frame(); + }, scheduler::pipeline::server); + } + }; +} + +REGISTER_COMPONENT(scripting::component) \ No newline at end of file diff --git a/src/client/component/scripting.hpp b/src/client/component/scripting.hpp new file mode 100644 index 00000000..5794bff2 --- /dev/null +++ b/src/client/component/scripting.hpp @@ -0,0 +1,11 @@ +#pragma once +#include + +namespace scripting +{ + using shared_table_t = std::unordered_map; + + extern std::unordered_map> fields_table; + extern std::unordered_map> script_function_table; + extern utils::concurrency::container shared_table; +} \ No newline at end of file diff --git a/src/client/game/scripting/entity.cpp b/src/client/game/scripting/entity.cpp new file mode 100644 index 00000000..b81dea1b --- /dev/null +++ b/src/client/game/scripting/entity.cpp @@ -0,0 +1,120 @@ +#include +#include "entity.hpp" +#include "script_value.hpp" +#include "execution.hpp" + +namespace scripting +{ + entity::entity() + : entity(0) + { + } + + entity::entity(const entity& other) : entity(other.entity_id_) + { + } + + entity::entity(entity&& other) noexcept + { + this->entity_id_ = other.entity_id_; + other.entity_id_ = 0; + } + + entity::entity(const unsigned int entity_id) + : entity_id_(entity_id) + { + this->add(); + } + + entity::entity(game::scr_entref_t entref) + : entity(game::FindEntityId(entref.entnum, entref.classnum)) + { + } + + entity::~entity() + { + this->release(); + } + + entity& entity::operator=(const entity& other) + { + if (&other != this) + { + this->release(); + this->entity_id_ = other.entity_id_; + this->add(); + } + + return *this; + } + + entity& entity::operator=(entity&& other) noexcept + { + if (&other != this) + { + this->release(); + this->entity_id_ = other.entity_id_; + other.entity_id_ = 0; + } + + return *this; + } + + unsigned int entity::get_entity_id() const + { + return this->entity_id_; + } + + game::scr_entref_t entity::get_entity_reference() const + { + if (!this->entity_id_) + { + const auto not_null = static_cast(~0ui16); + return game::scr_entref_t{not_null, not_null}; + } + + return game::Scr_GetEntityIdRef(this->get_entity_id()); + } + + bool entity::operator==(const entity& other) const noexcept + { + return this->get_entity_id() == other.get_entity_id(); + } + + bool entity::operator!=(const entity& other) const noexcept + { + return !this->operator==(other); + } + + void entity::add() const + { + if (this->entity_id_) + { + game::AddRefToValue(game::SCRIPT_OBJECT, {static_cast(this->entity_id_)}); + } + } + + void entity::release() const + { + if (this->entity_id_) + { + game::RemoveRefToValue(game::SCRIPT_OBJECT, {static_cast(this->entity_id_)}); + } + } + + void entity::set(const std::string& field, const script_value& value) const + { + set_entity_field(*this, field, value); + } + + template <> + script_value entity::get(const std::string& field) const + { + return get_entity_field(*this, field); + } + + script_value entity::call(const std::string& name, const std::vector& arguments) const + { + return call_function(name, *this, arguments); + } +} diff --git a/src/client/game/scripting/entity.hpp b/src/client/game/scripting/entity.hpp new file mode 100644 index 00000000..b1702379 --- /dev/null +++ b/src/client/game/scripting/entity.hpp @@ -0,0 +1,50 @@ +#pragma once +#include "game/game.hpp" +#include "script_value.hpp" + +namespace scripting +{ + class entity final + { + public: + entity(); + entity(unsigned int entity_id); + entity(game::scr_entref_t entref); + + entity(const entity& other); + entity(entity&& other) noexcept; + + ~entity(); + + entity& operator=(const entity& other); + entity& operator=(entity&& other) noexcept; + + void set(const std::string& field, const script_value& value) const; + + template + T get(const std::string& field) const; + + script_value call(const std::string& name, const std::vector& arguments = {}) const; + + unsigned int get_entity_id() const; + game::scr_entref_t get_entity_reference() const; + + bool operator ==(const entity& other) const noexcept; + bool operator !=(const entity& other) const noexcept; + + private: + unsigned int entity_id_; + + void add() const; + void release() const; + }; + + template <> + script_value entity::get(const std::string& field) const; + + template + T entity::get(const std::string& field) const + { + return this->get(field).as(); + } +} diff --git a/src/client/game/scripting/event.hpp b/src/client/game/scripting/event.hpp new file mode 100644 index 00000000..bc1d53e0 --- /dev/null +++ b/src/client/game/scripting/event.hpp @@ -0,0 +1,13 @@ +#pragma once +#include "script_value.hpp" +#include "entity.hpp" + +namespace scripting +{ + struct event + { + std::string name; + entity entity{}; + std::vector arguments; + }; +} diff --git a/src/client/game/scripting/execution.cpp b/src/client/game/scripting/execution.cpp new file mode 100644 index 00000000..ba4e4abd --- /dev/null +++ b/src/client/game/scripting/execution.cpp @@ -0,0 +1,250 @@ +#include +#include "execution.hpp" +#include "safe_execution.hpp" +#include "stack_isolation.hpp" + +#include "component/scripting.hpp" + +namespace scripting +{ + namespace + { + game::VariableValue* allocate_argument() + { + game::VariableValue* value_ptr = ++game::scr_VmPub->top; + ++game::scr_VmPub->inparamcount; + return value_ptr; + } + + void push_value(const script_value& value) + { + auto* value_ptr = allocate_argument(); + *value_ptr = value.get_raw(); + + game::AddRefToValue(value_ptr->type, value_ptr->u); + } + + int get_field_id(const int classnum, const std::string& field) + { + const auto class_id = game::g_classMap[classnum].id; + const auto field_str = game::SL_GetString(field.data(), 0); + const auto _ = gsl::finally([field_str]() + { + game::RemoveRefToValue(game::SCRIPT_STRING, {static_cast(field_str)}); + }); + + const auto offset = game::FindVariable(class_id, field_str); + if (offset) + { + const auto index = 3 * (offset + 0xFA00 * (class_id & 3)); + const auto id = reinterpret_cast(SELECT_VALUE(0x149BB5680, 0x14821DF80))[index]; + return static_cast(id); + } + + return -1; + } + + script_value get_return_value() + { + if (game::scr_VmPub->inparamcount == 0) + { + return {}; + } + + game::Scr_ClearOutParams(); + game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount; + game::scr_VmPub->inparamcount = 0; + + return script_value(game::scr_VmPub->top[1 - game::scr_VmPub->outparamcount]); + } + } + + void notify(const entity& entity, const std::string& event, const std::vector& arguments) + { + stack_isolation _; + for (auto i = arguments.rbegin(); i != arguments.rend(); ++i) + { + push_value(*i); + } + + const auto event_id = game::SL_GetString(event.data(), 0); + game::Scr_NotifyId(entity.get_entity_id(), event_id, game::scr_VmPub->inparamcount); + } + + script_value call_function(const std::string& name, const entity& entity, + const std::vector& arguments) + { + const auto entref = entity.get_entity_reference(); + + const auto is_method_call = *reinterpret_cast(&entref) != -1; + const auto function = find_function(name, !is_method_call); + if (function == nullptr) + { + throw std::runtime_error("Unknown "s + (is_method_call ? "method" : "function") + " '" + name + "'"); + } + + stack_isolation _; + + for (auto i = arguments.rbegin(); i != arguments.rend(); ++i) + { + push_value(*i); + } + + game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount; + game::scr_VmPub->inparamcount = 0; + + if (!safe_execution::call(function, entref)) + { + throw std::runtime_error( + "Error executing "s + (is_method_call ? "method" : "function") + " '" + name + "'"); + } + + return get_return_value(); + } + + script_value call_function(const std::string& name, const std::vector& arguments) + { + return call_function(name, entity(), arguments); + } + + template <> + script_value call(const std::string& name, const std::vector& arguments) + { + return call_function(name, arguments); + } + + script_value exec_ent_thread(const entity& entity, const char* pos, const std::vector& arguments) + { + const auto id = entity.get_entity_id(); + + stack_isolation _; + for (auto i = arguments.rbegin(); i != arguments.rend(); ++i) + { + scripting::push_value(*i); + } + + game::AddRefToObject(id); + + const auto local_id = game::AllocThread(id); + const auto result = game::VM_Execute(local_id, pos, (unsigned int)arguments.size()); + game::RemoveRefToObject(result); + + return get_return_value(); + } + + const char* get_function_pos(const std::string& filename, const std::string& function) + { + if (scripting::script_function_table.find(filename) == scripting::script_function_table.end()) + { + throw std::runtime_error("File '" + filename + "' not found"); + }; + + const auto functions = scripting::script_function_table[filename]; + if (functions.find(function) == functions.end()) + { + throw std::runtime_error("Function '" + function + "' in file '" + filename + "' not found"); + } + + return functions.at(function); + } + + script_value call_script_function(const entity& entity, const std::string& filename, + const std::string& function, const std::vector& arguments) + { + const auto pos = get_function_pos(filename, function); + return exec_ent_thread(entity, pos, arguments); + } + + static std::unordered_map> custom_fields; + + script_value get_custom_field(const entity& entity, const std::string& field) + { + auto& fields = custom_fields[entity.get_entity_id()]; + const auto _field = fields.find(field); + if (_field != fields.end()) + { + return _field->second; + } + return {}; + } + + void set_custom_field(const entity& entity, const std::string& field, const script_value& value) + { + const auto id = entity.get_entity_id(); + + if (custom_fields[id].find(field) != custom_fields[id].end()) + { + custom_fields[id][field] = value; + return; + } + + custom_fields[id].insert(std::make_pair(field, value)); + } + + void clear_entity_fields(const entity& entity) + { + const auto id = entity.get_entity_id(); + + if (custom_fields.find(id) != custom_fields.end()) + { + custom_fields[id].clear(); + } + } + + void clear_custom_fields() + { + custom_fields.clear(); + } + + void set_entity_field(const entity& entity, const std::string& field, const script_value& value) + { + const auto entref = entity.get_entity_reference(); + const int id = get_field_id(entref.classnum, field); + + if (id != -1) + { + stack_isolation _; + push_value(value); + + game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount; + game::scr_VmPub->inparamcount = 0; + + if (!safe_execution::set_entity_field(entref, id)) + { + throw std::runtime_error("Failed to set value for field '" + field + "'"); + } + } + else + { + // Read custom fields + set_custom_field(entity, field, value); + } + } + + script_value get_entity_field(const entity& entity, const std::string& field) + { + const auto entref = entity.get_entity_reference(); + const auto id = get_field_id(entref.classnum, field); + + if (id != -1) + { + stack_isolation _; + + game::VariableValue value{}; + if (!safe_execution::get_entity_field(entref, id, &value)) + { + throw std::runtime_error("Failed to get value for field '" + field + "'"); + } + + const auto __ = gsl::finally([value]() + { + game::RemoveRefToValue(value.type, value.u); + }); + + return value; + } + + // Add custom fields + return get_custom_field(entity, field); + } +} diff --git a/src/client/game/scripting/execution.hpp b/src/client/game/scripting/execution.hpp new file mode 100644 index 00000000..7fff1840 --- /dev/null +++ b/src/client/game/scripting/execution.hpp @@ -0,0 +1,36 @@ +#pragma once +#include "game/game.hpp" +#include "entity.hpp" +#include "script_value.hpp" + +namespace scripting +{ + script_value call_function(const std::string& name, const std::vector& arguments); + script_value call_function(const std::string& name, const entity& entity, + const std::vector& arguments); + + template + T call(const std::string& name, const std::vector& arguments = {}); + + template <> + script_value call(const std::string& name, const std::vector& arguments); + + template + T call(const std::string& name, const std::vector& arguments) + { + return call(name, arguments).as(); + } + + script_value exec_ent_thread(const entity& entity, const char* pos, const std::vector& arguments); + const char* get_function_pos(const std::string& filename, const std::string& function); + script_value call_script_function(const entity& entity, const std::string& filename, + const std::string& function, const std::vector& arguments); + + void clear_entity_fields(const entity& entity); + void clear_custom_fields(); + + void set_entity_field(const entity& entity, const std::string& field, const script_value& value); + script_value get_entity_field(const entity& entity, const std::string& field); + + void notify(const entity& entity, const std::string& event, const std::vector& arguments); +} diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp new file mode 100644 index 00000000..6eac3d97 --- /dev/null +++ b/src/client/game/scripting/function_tables.cpp @@ -0,0 +1,1535 @@ +#include + +// This file has been generated. +// Do not touch! + +namespace scripting +{ + std::unordered_map function_map = + { + {"precacheturret", 0}, + {"getweaponarray", 1}, + {"getnumparam", 15}, + {"getnumparam", 16}, + {"spawnturret", 23}, + {"canspawnturret", 24}, + {"assertexcmd", 25}, + {"badplace_delete", 30}, + {"badplace_cylinder", 31}, + {"badplace_arc", 32}, + {"badplace_brush", 33}, + {"assertexcmd0", 44}, + {"isdefined", 46}, + {"isvalidmissile", 47}, + {"isstring", 48}, + {"setomnvar", 49}, + {"getomnvar", 50}, + {"setdvar", 51}, + {"setdynamicdvar", 52}, + {"setdvarifuninitialized", 53}, + {"setdevdvar", 54}, + {"setdevdvarifuninitialized", 55}, + {"getdvar", 56}, + {"getdvarint", 57}, + {"getdvarfloat", 58}, + {"getdvarvector", 59}, + {"gettime", 60}, + {"getutc", 61}, + {"getradiometricunit", 62}, + {"getentbynum", 63}, + {"getweaponmodel", 64}, + {"setsunlight", 68}, + {"resetsunlight", 69}, + {"getweapondisplayname", 92}, + {"getweaponbasename", 93}, + {"getweaponattachments", 94}, + {"getweaponattachmentdisplaynames", 95}, + {"getweaponcamoname", 96}, + {"getweaponreticlename", 97}, + {"getanimlength", 98}, + {"animhasnotetrack", 99}, + {"getnotetracktimes", 100}, + {"spawn", 101}, + {"spawnloopingsound", 103}, + {"bullettrace", 104}, + {"getstartorigin", 108}, + {"getstartangles", 109}, + {"magicgrenademanual", 112}, + {"sub_140311ad0", 117}, + {"sub_140311d80", 118}, + {"sub_140311d90", 119}, + {"sub_140311df0", 120}, + {"sub_140311ef0", 121}, + {"sub_140311f50", 122}, + {"sub_14031fb60", 127}, + {"bullettracepassed", 138}, + {"sighttracepassed", 139}, + {"physicstrace", 140}, + {"playerphysicstrace", 141}, + {"getgroundposition", 142}, + {"getmovedelta", 143}, + {"getangledelta", 144}, + {"getnorthyaw", 145}, + {"setnorthyaw", 172}, + {"setslowmotion", 173}, + {"randomint", 174}, + {"randomfloat", 175}, + {"randomintrange", 176}, + {"randomfloatrange", 177}, + {"sin", 178}, + {"cos", 179}, + {"tan", 180}, + {"asin", 181}, + {"acos", 182}, + {"atan", 183}, + {"castint", 184}, + {"castfloat", 185}, + {"abs", 186}, + {"min", 187}, + {"getnode", 191}, + {"getnodearray", 192}, + {"getallnodes", 193}, + {"getnodesinradius", 194}, + {"getnodesinradiussorted", 195}, + {"getclosestnodeinsight", 196}, + {"isarray", 202}, + {"isai", 203}, + {"getindexforluincstring", 204}, + {"issentient", 205}, + {"max", 221}, + {"floor", 222}, + {"ceil", 223}, + {"exp", 224}, + {"log", 225}, + {"sqrt", 226}, + {"squared", 227}, + {"clamp", 228}, + {"angleclamp360", 229}, + {"angleclamp180", 230}, + {"vectorfromlinetopoint", 231}, + {"pointonsegmentnearesttopoint", 232}, + {"distance", 233}, + {"distance2d", 234}, + {"distancesquared", 235}, + {"length", 236}, + {"length2d", 237}, + {"lengthsquared", 238}, + {"length2dsquared", 239}, + {"closer", 240}, + {"vectordot", 241}, + {"vectorcross", 242}, + {"axistoangles", 243}, + {"visionsetthermal", 244}, + {"visionsetpain", 245}, + {"startservermigration", 246}, + {"setac130ambience", 247}, + {"getmapcustomfield", 248}, + {"spawnsighttrace", 249}, + {"incrementcounter", 250}, + {"getcountertotal", 251}, + {"createthreatbiasgroup", 258}, + {"threatbiasgroupexists", 259}, + {"getthreatbias", 260}, + {"setthreatbias", 261}, + {"setthreatbiasagainstall", 262}, + {"setignoremegroup", 263}, + {"isenemyteam", 264}, + {"vectornormalize", 271}, + {"vectortoangles", 272}, + {"vectortoyaw", 273}, + {"vectorlerp", 274}, + {"anglestoup", 275}, + {"anglestoright", 276}, + {"anglestoforward", 277}, + {"anglesdelta", 278}, + {"combineangles", 279}, + {"transformmove", 280}, + {"rotatevector", 281}, + {"rotatepointaroundvector", 282}, + {"issubstr", 283}, + {"isendstr", 284}, + {"getsubstr", 285}, + {"tolower", 286}, + {"strtok", 287}, + {"stricmp", 288}, + {"ambientplay", 289}, + {"getuavstrengthmax", 290}, + {"getuavstrengthlevelneutral", 291}, + {"getuavstrengthlevelshowenemyfastsweep", 292}, + {"getuavstrengthlevelshowenemydirectional", 293}, + {"blockteamradar", 294}, + {"unblockteamradar", 295}, + {"isteamradarblocked", 296}, + {"sub_140328710", 297}, + {"setmatchdata", 298}, + {"getmatchdata", 299}, + {"sendmatchdata", 300}, + {"clearmatchdata", 301}, + {"setmatchdatadef", 302}, + {"setmatchclientip", 303}, + {"setmatchdataid", 304}, + {"setclientmatchdata", 305}, + {"getclientmatchdata", 306}, + {"setclientmatchdatadef", 307}, + {"sendclientmatchdata", 308}, + {"getbuildversion", 309}, + {"getbuildnumber", 310}, + {"getsystemtime", 311}, + {"getmatchrulesdata", 312}, + {"isusingmatchrulesdata", 313}, + {"kickplayer", 314}, + {"issplitscreen", 315}, + {"setmapcenter", 316}, + {"setgameendtime", 317}, + {"visionsetnaked", 318}, + {"visionsetnight", 319}, + {"visionsetmissilecam", 320}, + {"ambientstop", 321}, + {"precachemodel", 322}, + {"precacheshellshock", 323}, + {"precacheitem", 324}, + {"precachematerial", 325}, + {"precachestring", 326}, + {"precachemenu", 327}, + {"precacherumble", 328}, + {"precachelocationselector", 329}, + {"precacheleaderboards", 330}, + {"loadfx", 331}, + {"playfx", 332}, + {"playfxontag", 333}, + {"stopfxontag", 334}, + {"killfxontag", 335}, + {"playloopedfx", 336}, + {"spawnfx", 337}, + {"triggerfx", 338}, + {"playfxontagforclients", 339}, + {"sub_1403326a0", 340}, + {"sub_14031be80", 341}, + {"setwinningteam", 342}, + {"announcement", 343}, + {"clientannouncement", 344}, + {"setteammode", 345}, + {"getteamscore", 346}, + {"setteamscore", 347}, + {"setclientnamemode", 348}, + {"updateclientnames", 349}, + {"getteamplayersalive", 350}, + {"worldentnumber", 352}, + {"obituary", 353}, + {"positionwouldtelefrag", 354}, + {"canspawn", 355}, + {"getstarttime", 356}, + {"precacheheadicon", 357}, + {"precacheminimapicon", 358}, + {"precachempanim", 359}, + {"maprestart", 360}, + {"exitlevel", 361}, + {"addtestclient", 362}, + {"addagent", 363}, + {"allclientsprint", 365}, + {"clientprint", 366}, + {"mapexists", 367}, + {"isvalidgametype", 368}, + {"setplayerteamrank", 370}, + {"setteamradar", 372}, + {"getteamradar", 373}, + {"setteamradarstrength", 374}, + {"getteamradarstrength", 375}, + {"getuavstrengthmin", 376}, + {"physicsexplosionsphere", 377}, + {"physicsexplosioncylinder", 378}, + {"physicsradiusjolt", 379}, + {"physicsradiusjitter", 380}, + {"setexpfog", 381}, + {"setexpfogext", 382}, + {"setexpfogdvarsonly", 383}, + {"setexpfogextdvarsonly", 384}, + {"setatmosfog", 385}, + {"setatmosfogdvarsonly", 386}, + {"isexplosivedamagemod", 387}, + {"radiusdamage", 388}, + {"setplayerignoreradiusdamage", 389}, + {"glassradiusdamage", 390}, + {"earthquake", 391}, + {"getnumparts", 392}, + {"objective_onentity", 393}, + {"objective_onentitywithrotation", 394}, + {"objective_team", 395}, + {"objective_player", 396}, + {"objective_playerteam", 397}, + {"objective_playerenemyteam", 398}, + {"objective_playermask_hidefromall", 399}, + {"objective_playermask_hidefrom", 400}, + {"objective_playermask_showtoall", 401}, + {"objective_playermask_showto", 402}, + {"iprintln", 403}, + {"iprintlnbold", 404}, + {"getent", 406}, + {"getentarray", 407}, + {"getspawnarray", 408}, + {"spawnplane", 409}, + {"addstruct", 410}, + {"spawnhelicopter", 411}, + {"isalive", 412}, + {"isspawner", 413}, + {"missilecreateattractorent", 414}, + {"missilecreateattractororigin", 415}, + {"missilecreaterepulsorent", 416}, + {"missilecreaterepulsororigin", 417}, + {"missiledeleteattractor", 418}, + {"playsoundatpos", 419}, + {"newhudelem", 420}, + {"newclienthudelem", 421}, + {"newteamhudelem", 422}, + {"resettimeout", 423}, + {"isplayer", 424}, + {"isplayernumber", 425}, + {"getpartname", 426}, + {"weaponfiretime", 427}, + {"weaponclipsize", 428}, + {"weaponisauto", 429}, + {"weaponissemiauto", 430}, + {"weaponisboltaction", 431}, + {"weaponinheritsperks", 432}, + {"weaponburstcount", 433}, + {"weapontype", 434}, + {"weaponclass", 435}, + {"getnextarraykey", 436}, + {"sortbydistance", 437}, + {"tablelookup", 438}, + {"tablelookupbyrow", 439}, + {"tablelookupistring", 440}, + {"tablelookupistringbyrow", 441}, + {"tablelookuprownum", 442}, + {"tableexists", 443}, + {"getmissileowner", 444}, + {"magicbullet", 445}, + {"getweaponflashtagname", 446}, + {"averagepoint", 447}, + {"averagenormal", 448}, + {"getspawnerarray", 449}, + {"playrumbleonposition", 450}, + {"playrumblelooponposition", 451}, + {"stopallrumbles", 452}, + {"soundexists", 453}, + {"setminimap", 460}, + {"setthermalbodymaterial", 461}, + {"getarraykeys", 462}, + {"getfirstarraykey", 463}, + {"getglass", 464}, + {"getglassarray", 465}, + {"getglassorigin", 466}, + {"isglassdestroyed", 467}, + {"destroyglass", 468}, + {"deleteglass", 469}, + {"getentchannelscount", 470}, + {"getentchannelname", 471}, + {"objective_add", 472}, + {"objective_delete", 473}, + {"objective_state", 474}, + {"objective_icon", 475}, + {"objective_position", 476}, + {"objective_current", 477}, + {"weaponinventorytype", 478}, + {"weaponstartammo", 479}, + {"weaponmaxammo", 480}, + {"weaponaltweaponname", 481}, + {"isweaponcliponly", 482}, + {"sub_14030dfc0", 483}, + {"sub_14030e400", 484}, + {"weaponhasthermalscope", 485}, + {"getvehiclenode", 486}, + {"getvehiclenodearray", 487}, + {"getallvehiclenodes", 488}, + {"getactivecount", 489}, + {"precache", 490}, + {"spawnvehicle", 491}, + {"getarray", 492}, + {"pow", 493}, + {"atan2", 494}, + {"botgetmemoryevents", 495}, + {"botautoconnectenabled", 496}, + {"botzonegetcount", 497}, + {"botzonesetteam", 498}, + {"botzonenearestcount", 499}, + {"botmemoryflags", 500}, + {"botflagmemoryevents", 501}, + {"botzonegetindoorpercent", 502}, + {"botsentientswap", 503}, + {"isbot", 504}, + {"isagent", 505}, + {"getmaxagents", 506}, + {"botgetclosestnavigablepoint", 508}, + {"getnodesintrigger", 509}, + {"nodesvisible", 510}, + {"getnodesonpath", 511}, + {"getzonecount", 512}, + {"getzonenearest", 513}, + {"getzonenodes", 514}, + {"getzonepath", 515}, + {"getzoneorigin", 516}, + {"getnodezone", 517}, + {"getzonenodesbydist", 518}, + {"getzonenodeforindex", 519}, + {"getweaponexplosionradius", 520}, + {"nodeexposedtosky", 523}, + {"findentrances", 524}, + {"badplace_global", 525}, + {"getpathdist", 526}, + {"getlinkednodes", 527}, + {"disconnectnodepair", 528}, + {"connectnodepair", 529}, + {"precachesound", 533}, + {"distance2dsquared", 543}, + {"getangledelta3d", 544}, + {"activateclientexploder", 545}, + {"trajectorycalculateinitialvelocity", 546}, + {"trajectorycalculateminimumvelocity", 547}, + {"trajectorycalculateexitangle", 548}, + {"trajectoryestimatedesiredinairtime", 549}, + {"trajectorycomputedeltaheightattime", 550}, + {"trajectorycanattemptaccuratejump", 551}, + {"ispointinvolume", 553}, + {"getscriptablearray", 560}, + {"clearfog", 561}, + {"setleveldopplerpreset", 562}, + {"isusinghdr", 564}, + {"sub_140321c40", 565}, + {"sub_140311a40", 567}, + {"sub_14030ec50", 568}, + {"sub_14030f050", 569}, + {"sub_14030f340", 570}, + {"sub_14030f550", 571}, + {"sub_14030f710", 572}, + {"sub_1403295e0", 573}, + {"sub_140322690", 574}, + {"sub_140329600", 575}, + {"sub_14031a690", 580}, + {"sub_1403163c0", 581}, + {"anglestoaxis", 582}, + {"invertangles", 587}, + {"rotatevectorinverted", 588}, + {"calculatestartorientation", 589}, + {"droptoground", 590}, + {"precachelaser", 592}, + {"getcsplinecount", 593}, + {"getcsplinepointcount", 594}, + {"getcsplinelength", 595}, + {"getcsplinepointid", 596}, + {"getcsplinepointlabel", 597}, + {"getcsplinepointtension", 598}, + {"getcsplinepointposition", 599}, + {"getcsplinepointcorridordims", 600}, + {"getcsplinepointtangent", 601}, + {"getcsplinepointdisttonextpoint", 602}, + {"calccsplineposition", 603}, + {"calccsplinetangent", 604}, + {"calccsplinecorridor", 605}, + {"setnojipscore", 606}, + {"setnojiptime", 607}, + {"getpredictedentityposition", 608}, + {"queuedialog", 615}, + {"triggerportableradarping", 622}, + {"botgetteamlimit", 624}, + {"spawnfxforclient", 625}, + {"botgetteamdifficulty", 626}, + {"loadluifile", 632}, + {"isdedicatedserver", 633}, + {"getplaylistversion", 634}, + {"getplaylistid", 635}, + {"getactiveclientcount", 636}, + {"issquadsmode", 637}, + {"visionsetpostapply", 639}, + {"addbot", 640}, + {"sub_140310ec0", 641}, + {"sub_14031bae0", 642}, + {"sub_14031c2b0", 643}, + {"isalliedsentient", 644}, + {"istestclient", 645}, + {"sub_1402d2850", 646}, + {"sub_140311ff0", 648}, + {"sub_140312040", 649}, + {"sub_140311100", 651}, + {"sub_140314c70", 652}, + {"sub_14030d340", 653}, + {"sub_14030da60", 654}, + {"sub_14030e5c0", 655}, + {"sub_14031fda0", 657}, + {"sub_140317140", 658}, + {"isremovedentity", 659}, + {"tablegetrowcount", 660}, + {"tablegetcolumncount", 661}, + {"batteryusepershot", 662}, + {"batteryreqtouse", 663}, + {"sub_14030e700", 664}, + {"getentityweaponname", 666}, + {"sub_14031fc20", 667}, + {"deployriotshield", 668}, + {"validatecostume", 669}, + {"randomcostume", 670}, + {"shootblank", 671}, + {"debugstringtostring", 673}, + {"sub_140319680", 675}, + {"playcinematicforall", 679}, + {"preloadcinematicforall", 680}, + {"stopcinematicforall", 681}, + {"capsuletracepassed", 682}, + {"sub_14031ca40", 683}, + {"sub_14031e1f0", 684}, + {"sub_140321880", 685}, + {"lootservicestarttrackingplaytime", 687}, + {"sub_1403297b0", 688}, + {"lootservicevalidateplaytime", 689}, + {"recordbreadcrumbdataforplayer", 690}, + {"sub_140317df0", 691}, + {"sysprint", 693}, + {"sub_140337920", 694}, + {"sub_140321ae0", 697}, + {"isonlinegame", 698}, + {"issystemlink", 699}, + {"getstanceandmotionstateforplayer", 701}, + {"sub_1402d3540", 702}, + {"sub_1402d35b0", 703}, + {"sub_140332a70", 704}, + {"sub_140332ae0", 705}, + {"getplaylistname", 706}, + {"getlocaltime", 707}, + {"sub_14032c820", 708}, + {"getchallengeid", 710}, + {"nodegetremotemissilename", 711}, + {"nodehasremotemissileset", 712}, + {"remotemissileenttracetooriginpassed", 713}, + {"bombingruntracepassed", 714}, + {"handlepickupdeployedriotshield", 716}, + {"sub_14032c6b0", 717}, + {"getcostumefromtable", 718}, + {"sub_1402d3460", 720}, + {"getchallenerewarditem", 722}, + {"setentplayerxuidforemblem", 723}, + {"resetentplayerxuidforemblems", 724}, + {"nodesetremotemissilename", 725}, + {"sub_14031aa80", 726}, + {"sub_14031ead0", 727}, + {"iszombie", 728}, + {"sub_14031b670", 729}, + {"sub_14031d3f0", 730}, + {"sub_14031e670", 731}, + {"getactiveplayerlist", 732}, + {"sub_140319200", 733}, + {"sub_140331e00", 734}, + }; + + std::unordered_map method_map = + { + {"thermaldrawdisable", 32768}, + {"heli_setdamagestage", 32770}, + {"playsoundtoteam", 32771}, + {"playsoundtoplayer", 32772}, + {"playerhide", 32773}, + {"playershow", 32774}, + {"showtoplayer", 32775}, + {"threatdetectedtoplayer", 32776}, + {"clearthreatdetected", 32777}, + {"enableplayeruse", 32778}, + {"disableplayeruse", 32779}, + {"enableammogeneration", 32780}, + {"disableammogeneration", 32781}, + {"makescrambler", 32782}, + {"makeportableradar", 32783}, + {"clearscrambler", 32784}, + {"clearportableradar", 32785}, + {"placespawnpoint", 32786}, + {"setteamfortrigger", 32787}, + {"clientclaimtrigger", 32788}, + {"clientreleasetrigger", 32789}, + {"releaseclaimedtrigger", 32790}, + {"isusingonlinedataoffline", 32791}, + {"getrestedtime", 32792}, + {"sendleaderboards", 32793}, + {"isonladder", 32794}, + {"getcorpseanim", 32795}, + {"playerforcedeathanim", 32796}, + {"attach", 32797}, + {"startragdoll", 32803}, + {"thermaldrawenable", 32809}, + {"detach", 32810}, + {"detachall", 32811}, + {"getattachsize", 32812}, + {"getattachmodelname", 32813}, + {"getattachtagname", 32814}, + {"gethighestnodestance", 32820}, + {"doesnodeallowstance", 32821}, + {"getlightcolor", 32835}, + {"setlightcolor", 32836}, + {"getattachignorecollision", 32839}, + {"hidepart", 32840}, + {"hidepartallinstances", 32841}, + {"hideallparts", 32842}, + {"showpart", 32843}, + {"showallparts", 32844}, + {"linkto", 32845}, + {"linktoblendtotag", 32846}, + {"unlink", 32847}, + {"setnormalhealth", 32848}, + {"dodamage", 32849}, + {"show", 32851}, + {"hide", 32852}, + {"disconnectpaths", 32855}, + {"connectpaths", 32856}, + {"disconnectnode", 32857}, + {"connectnode", 32858}, + {"digitaldistortsetparams", 32868}, + {"setmode", 32869}, + {"getmode", 32870}, + {"islinked", 32872}, + {"enablelinkto", 32873}, + {"setpitch", 32876}, + {"scalepitch", 32877}, + {"setvolume", 32878}, + {"scalevolume", 32879}, + {"playsound", 32884}, + {"playloopsound", 32885}, + {"getnormalhealth", 32891}, + {"playerlinkto", 32892}, + {"playerlinktodelta", 32893}, + {"playerlinkweaponviewtodelta", 32894}, + {"playerlinktoabsolute", 32895}, + {"playerlinktoblend", 32896}, + {"playerlinkedoffsetenable", 32897}, + {"setwaypointedgestyle_secondaryarrow", 32898}, + {"setwaypointiconoffscreenonly", 32899}, + {"fadeovertime", 32900}, + {"scaleovertime", 32901}, + {"moveovertime", 32902}, + {"reset", 32903}, + {"destroy", 32904}, + {"setpulsefx", 32905}, + {"setplayernamestring", 32906}, + {"changefontscaleovertime", 32907}, + {"playersetgroundreferenceent", 32913}, + {"dontinterpolate", 32914}, + {"getorigin", 32917}, + {"useby", 32921}, + {"playsoundasmaster", 32922}, + {"playerlinkedoffsetdisable", 32927}, + {"playerlinkedsetviewznear", 32928}, + {"playerlinkedsetusebaseangleforviewclamp", 32929}, + {"lerpviewangleclamp", 32930}, + {"geteye", 32936}, + {"istouching", 32937}, + {"getistouchingentities", 32938}, + {"stoploopsound", 32939}, + {"stopsounds", 32940}, + {"playrumbleonentity", 32941}, + {"playrumblelooponentity", 32942}, + {"stoprumble", 32943}, + {"delete", 32944}, + {"setmodel", 32945}, + {"laseron", 32946}, + {"laseroff", 32947}, + {"thermalvisionon", 32950}, + {"thermalvisionoff", 32951}, + {"thermalvisionfofoverlayon", 32952}, + {"thermalvisionfofoverlayoff", 32953}, + {"autospotoverlayon", 32954}, + {"autospotoverlayoff", 32955}, + {"seteyesonuplinkenabled", 32956}, + {"setcontents", 32958}, + {"makeusable", 32959}, + {"makeunusable", 32960}, + {"makeglobalusable", 32961}, + {"makeglobalunusable", 32962}, + {"settext", 32970}, + {"setmaterial", 32972}, + {"settargetent", 32973}, + {"cleartargetent", 32974}, + {"settimer", 32975}, + {"settimerup", 32976}, + {"settimerstatic", 32977}, + {"settenthstimer", 32978}, + {"settenthstimerup", 32979}, + {"settenthstimerstatic", 32980}, + {"setclock", 32981}, + {"setclockup", 32982}, + {"setvalue", 32983}, + {"setwaypoint", 32984}, + {"setwaypointedgestyle_rotatingicon", 32985}, + {"setcursorhint", 32986}, + {"sethintstring", 32987}, + {"setsecondaryhintstring", 32988}, + {"forceusehinton", 32989}, + {"forceusehintoff", 32990}, + {"makesoft", 32991}, + {"makehard", 32992}, + {"entitywillneverchange", 32993}, + {"startfiring", 32994}, + {"stopfiring", 32995}, + {"isfiringturret", 32996}, + {"startbarrelspin", 32997}, + {"stopbarrelspin", 32998}, + {"getbarrelspinrate", 32999}, + {"remotecontrolturret", 33000}, + {"remotecontrolturretoff", 33001}, + {"shootturret", 33002}, + {"getturretowner", 33003}, + {"giveachievement", 33017}, + {"sub_1402ddb00", 33022}, + {"sub_1402ddcc0", 33023}, + {"setsentryowner", 33027}, + {"setsentrycarrier", 33028}, + {"setturretminimapvisible", 33029}, + {"settargetentity", 33030}, + {"snaptotargetentity", 33031}, + {"cleartargetentity", 33032}, + {"getturrettarget", 33033}, + {"setplayerspread", 33034}, + {"setaispread", 33035}, + {"setsuppressiontime", 33036}, + {"allowstand", 33048}, + {"allowcrouch", 33049}, + {"allowprone", 33050}, + {"sub_1402dd9e0", 33051}, + {"isthrowinggrenade", 33068}, + {"isfiring", 33069}, + {"ismeleeing", 33070}, + {"allowmelee", 33072}, + {"allowfire", 33073}, + {"setconvergencetime", 33075}, + {"setconvergenceheightpercent", 33076}, + {"setturretteam", 33077}, + {"maketurretsolid", 33078}, + {"maketurretoperable", 33079}, + {"maketurretinoperable", 33080}, + {"makeentitysentient", 33081}, + {"freeentitysentient", 33082}, + {"setrightarc", 33109}, + {"setleftarc", 33110}, + {"settoparc", 33111}, + {"setbottomarc", 33112}, + {"setautorotationdelay", 33113}, + {"setdefaultdroppitch", 33114}, + {"restoredefaultdroppitch", 33115}, + {"turretfiredisable", 33116}, + {"getenemyinfo", 33125}, + {"getenemysqdist", 33141}, + {"getclosestenemysqdist", 33142}, + {"setthreatbiasgroup", 33143}, + {"getthreatbiasgroup", 33144}, + {"turretfireenable", 33145}, + {"setturretmodechangewait", 33146}, + {"usetriggerrequirelookat", 33147}, + {"getstance", 33148}, + {"setstance", 33149}, + {"itemweaponsetammo", 33150}, + {"getammocount", 33151}, + {"gettagorigin", 33152}, + {"gettagangles", 33153}, + {"shellshock", 33154}, + {"stunplayer", 33155}, + {"stopshellshock", 33156}, + {"fadeoutshellshock", 33157}, + {"setdepthoffield", 33158}, + {"setviewmodeldepthoffield", 33159}, + {"setmotionblurmovescale", 33160}, + {"getnegotiationstartnode", 33181}, + {"getnegotiationendnode", 33182}, + {"getnegotiationnextnode", 33183}, + {"setmotionblurturnscale", 33197}, + {"setmotionblurzoomscale", 33198}, + {"viewkick", 33199}, + {"localtoworldcoords", 33200}, + {"getentitynumber", 33201}, + {"getentityvelocity", 33202}, + {"enablegrenadetouchdamage", 33203}, + {"disablegrenadetouchdamage", 33204}, + {"enableaimassist", 33205}, + {"lastknowntime", 33216}, + {"lastknownpos", 33217}, + {"disableaimassist", 33236}, + {"entityradiusdamage", 33237}, + {"detonate", 33238}, + {"damageconetrace", 33239}, + {"sightconetrace", 33240}, + {"missilesettargetent", 33241}, + {"missilesettargetpos", 33242}, + {"missilecleartarget", 33243}, + {"missilesetflightmodedirect", 33244}, + {"missilesetflightmodetop", 33245}, + {"getlightintensity", 33246}, + {"setlightintensity", 33247}, + {"isragdoll", 33248}, + {"setmovespeedscale", 33249}, + {"cameralinkto", 33250}, + {"cameraunlink", 33251}, + {"controlslinkto", 33280}, + {"controlsunlink", 33281}, + {"makevehiclesolidcapsule", 33282}, + {"makevehiclesolidsphere", 33284}, + {"remotecontrolvehicle", 33286}, + {"remotecontrolvehicleoff", 33287}, + {"isfiringvehicleturret", 33288}, + {"remotecontrolvehicletarget", 33289}, + {"remotecontrolvehicletargetoff", 33290}, + {"drivevehicleandcontrolturret", 33291}, + {"drivevehicleandcontrolturretoff", 33292}, + {"getplayersetting", 33293}, + {"getlocalplayerprofiledata", 33294}, + {"setlocalplayerprofiledata", 33295}, + {"remotecamerasoundscapeon", 33296}, + {"remotecamerasoundscapeoff", 33297}, + {"setmotiontrackervisible", 33298}, + {"getmotiontrackervisible", 33299}, + {"worldpointinreticle_circle", 33300}, + {"worldpointinreticle_rect", 33301}, + {"getpointinbounds", 33302}, + {"transfermarkstonewscriptmodel", 33303}, + {"setwatersheeting", 33304}, + {"setweaponhudiconoverride", 33307}, + {"getweaponhudiconoverride", 33308}, + {"setempjammed", 33309}, + {"playersetexpfogext", 33310}, + {"playersetexpfog", 33311}, + {"playersetatmosfog", 33312}, + {"isitemunlocked", 33313}, + {"getplayerdata", 33314}, + {"getrankedplayerdata", 33315}, + {"getprivateplayerdata", 33316}, + {"getcoopplayerdata", 33317}, + {"getcommonplayerdata", 33318}, + {"vehicleturretcontroloff", 33319}, + {"isturretready", 33320}, + {"vehicledriveto", 33321}, + {"dospawn", 33322}, + {"isphysveh", 33323}, + {"crash", 33324}, + {"launch", 33325}, + {"disablecrashing", 33326}, + {"enablecrashing", 33327}, + {"setphysvehspeed", 33328}, + {"setconveyorbelt", 33329}, + {"freevehicle", 33330}, + {"setplayerdata", 33347}, + {"setrankedplayerdata", 33348}, + {"setprivateplayerdata", 33349}, + {"setcoopplayerdata", 33350}, + {"setcommonplayerdata", 33351}, + {"getcacplayerdata", 33352}, + {"setcacplayerdata", 33353}, + {"trackerupdate", 33354}, + {"pingplayer", 33355}, + {"buttonpressed", 33356}, + {"sayall", 33357}, + {"sayteam", 33358}, + {"setspawnweapon", 33359}, + {"dropitem", 33360}, + {"dropscavengerbag", 33361}, + {"setjitterparams", 33362}, + {"sethoverparams", 33363}, + {"joltbody", 33364}, + {"getwheelsurface", 33366}, + {"getvehicleowner", 33367}, + {"setvehiclelookattext", 33368}, + {"setvehicleteam", 33369}, + {"neargoalnotifydist", 33370}, + {"setvehgoalpos", 33371}, + {"setgoalyaw", 33372}, + {"cleargoalyaw", 33373}, + {"settargetyaw", 33374}, + {"cleartargetyaw", 33375}, + {"helisetgoal", 33376}, + {"setturrettargetvec", 33377}, + {"setturrettargetent", 33378}, + {"clearturrettargetent", 33379}, + {"canturrettargetpoint", 33380}, + {"setlookatent", 33381}, + {"clearlookatent", 33382}, + {"setweapon", 33383}, + {"fireweapon", 33384}, + {"vehicleturretcontrolon", 33385}, + {"finishplayerdamage", 33386}, + {"suicide", 33387}, + {"closeingamemenu", 33388}, + {"iclientprintln", 33389}, + {"iclientprintlnbold", 33390}, + {"spawn", 33391}, + {"setentertime", 33392}, + {"cloneplayer", 33393}, + {"istalking", 33394}, + {"allowspectateteam", 33395}, + {"forcespectatepov", 33396}, + {"getguid", 33397}, + {"physicslaunchserver", 33398}, + {"physicslaunchserveritem", 33399}, + {"clonebrushmodeltoscriptmodel", 33400}, + {"scriptmodelplayanim", 33401}, + {"scriptmodelclearanim", 33402}, + {"scriptmodelplayanimdeltamotion", 33403}, + {"teleport", 33404}, + {"attachpath", 33405}, + {"getattachpos", 33406}, + {"startpath", 33407}, + {"setswitchnode", 33408}, + {"setwaitspeed", 33409}, + {"finishdamage", 33410}, + {"setspeed", 33411}, + {"setspeedimmediate", 33412}, + {"rotatevehyaw", 33413}, + {"getspeed", 33414}, + {"getvehvelocity", 33415}, + {"getbodyvelocity", 33416}, + {"getsteering", 33417}, + {"getthrottle", 33418}, + {"turnengineoff", 33419}, + {"turnengineon", 33420}, + {"getgoalspeedmph", 33422}, + {"setacceleration", 33423}, + {"setdeceleration", 33424}, + {"resumespeed", 33425}, + {"setyawspeed", 33426}, + {"setyawspeedbyname", 33427}, + {"setmaxpitchroll", 33428}, + {"setairresitance", 33429}, + {"setturningability", 33430}, + {"getxuid", 33431}, + {"getucdidhigh", 33432}, + {"getucdidlow", 33433}, + {"getclanidhigh", 33434}, + {"getclanidlow", 33435}, + {"ishost", 33436}, + {"getspectatingplayer", 33437}, + {"predictstreampos", 33438}, + {"setrank", 33441}, + {"weaponlocknoclearance", 33443}, + {"visionsyncwithplayer", 33444}, + {"showhudsplash", 33445}, + {"setperk", 33446}, + {"hasperk", 33447}, + {"clearperks", 33448}, + {"unsetperk", 33449}, + {"registerparty", 33450}, + {"getfireteammembers", 33451}, + {"moveto", 33454}, + {"movex", 33455}, + {"movey", 33456}, + {"movez", 33457}, + {"gravitymove", 33458}, + {"moveslide", 33459}, + {"stopmoveslide", 33460}, + {"rotateto", 33461}, + {"rotatepitch", 33462}, + {"rotateyaw", 33463}, + {"rotateroll", 33464}, + {"addpitch", 33465}, + {"addyaw", 33466}, + {"addroll", 33467}, + {"vibrate", 33468}, + {"rotatevelocity", 33469}, + {"solid", 33470}, + {"notsolid", 33471}, + {"setcandamage", 33472}, + {"setcanradiusdamage", 33473}, + {"physicslaunchclient", 33474}, + {"setcarddisplayslot", 33477}, + {"kc_regweaponforfxremoval", 33478}, + {"laststandrevive", 33479}, + {"laststand", 33480}, + {"setspectatedefaults", 33481}, + {"getthirdpersoncrosshairoffset", 33482}, + {"disableweaponpickup", 33483}, + {"enableweaponpickup", 33484}, + {"issplitscreenplayer", 33485}, + {"getweaponslistoffhands", 33486}, + {"getweaponslistitems", 33487}, + {"getweaponslistexclusives", 33488}, + {"getweaponslist", 33489}, + {"canplayerplacesentry", 33490}, + {"canplayerplacetank", 33491}, + {"visionsetnakedforplayer", 33492}, + {"visionsetnightforplayer", 33493}, + {"visionsetmissilecamforplayer", 33494}, + {"visionsetthermalforplayer", 33495}, + {"visionsetpainforplayer", 33496}, + {"setblurforplayer", 33497}, + {"getplayerweaponmodel", 33498}, + {"getplayerknifemodel", 33499}, + {"notifyonplayercommand", 33501}, + {"canmantle", 33502}, + {"forcemantle", 33503}, + {"ismantling", 33504}, + {"playfx", 33505}, + {"playerrecoilscaleon", 33506}, + {"playerrecoilscaleoff", 33507}, + {"weaponlockstart", 33508}, + {"weaponlockfinalize", 33509}, + {"weaponlockfree", 33510}, + {"weaponlocktargettooclose", 33511}, + {"issplitscreenplayerprimary", 33512}, + {"markforeyeson", 33513}, + {"issighted", 33514}, + {"getsightedplayers", 33515}, + {"getplayerssightingme", 33516}, + {"getviewmodel", 33517}, + {"fragbuttonpressed", 33518}, + {"secondaryoffhandbuttonpressed", 33519}, + {"getcurrentweaponclipammo", 33520}, + {"setvelocity", 33521}, + {"getviewheight", 33522}, + {"getnormalizedmovement", 33523}, + {"playlocalsound", 33524}, + {"stoplocalsound", 33525}, + {"setweaponammoclip", 33526}, + {"setweaponammostock", 33527}, + {"getweaponammoclip", 33528}, + {"getweaponammostock", 33529}, + {"anyammoforweaponmodes", 33530}, + {"setclientomnvar", 33531}, + {"setclientdvar", 33532}, + {"setclientdvars", 33533}, + {"setclientspawnsighttraces", 33534}, + {"clientspawnsighttracepassed", 33535}, + {"allowads", 33536}, + {"allowjump", 33537}, + {"allowladder", 33538}, + {"allowmantle", 33539}, + {"allowsprint", 33540}, + {"setspreadoverride", 33541}, + {"resetspreadoverride", 33542}, + {"setaimspreadmovementscale", 33543}, + {"setactionslot", 33544}, + {"setviewkickscale", 33545}, + {"getviewkickscale", 33546}, + {"getweaponslistall", 33547}, + {"getweaponslistprimaries", 33548}, + {"getnormalizedcameramovement", 33549}, + {"giveweapon", 33550}, + {"takeweapon", 33551}, + {"takeallweapons", 33552}, + {"getcurrentweapon", 33553}, + {"getcurrentprimaryweapon", 33554}, + {"getcurrentoffhand", 33555}, + {"hasweapon", 33556}, + {"switchtoweapon", 33557}, + {"switchtoweaponimmediate", 33558}, + {"sub_1402e1d60", 33559}, + {"switchtooffhand", 33560}, + {"setoffhandsecondaryclass", 33561}, + {"getoffhandsecondaryclass", 33562}, + {"beginlocationselection", 33563}, + {"endlocationselection", 33564}, + {"disableweapons", 33565}, + {"enableweapons", 33566}, + {"disableoffhandweapons", 33567}, + {"enableoffhandweapons", 33568}, + {"disableweaponswitch", 33569}, + {"enableweaponswitch", 33570}, + {"openpopupmenu", 33571}, + {"openpopupmenunomouse", 33572}, + {"closepopupmenu", 33573}, + {"openmenu", 33574}, + {"closemenu", 33575}, + {"freezecontrols", 33577}, + {"disableusability", 33578}, + {"enableusability", 33579}, + {"setwhizbyspreads", 33580}, + {"setwhizbyradii", 33581}, + {"setchannelvolume", 33584}, + {"givestartammo", 33585}, + {"givemaxammo", 33586}, + {"getfractionstartammo", 33587}, + {"getfractionmaxammo", 33588}, + {"isdualwielding", 33589}, + {"isreloading", 33590}, + {"isswitchingweapon", 33591}, + {"setorigin", 33592}, + {"getvelocity", 33593}, + {"setangles", 33594}, + {"getangles", 33595}, + {"usebuttonpressed", 33596}, + {"attackbuttonpressed", 33597}, + {"adsbuttonpressed", 33598}, + {"meleebuttonpressed", 33599}, + {"playerads", 33600}, + {"isonground", 33601}, + {"isusingturret", 33602}, + {"setviewmodel", 33603}, + {"setoffhandprimaryclass", 33604}, + {"getoffhandprimaryclass", 33605}, + {"sub_14032dff0", 33610}, + {"sub_14032e040", 33611}, + {"enablemousesteer", 33612}, + {"setscriptmoverkillcam", 33613}, + {"usinggamepad", 33614}, + {"forcethirdpersonwhenfollowing", 33615}, + {"disableforcethirdpersonwhenfollowing", 33616}, + {"botsetflag", 33617}, + {"botsetstance", 33618}, + {"botsetscriptmove", 33619}, + {"botsetscriptgoal", 33620}, + {"botsetscriptgoalnode", 33621}, + {"botclearscriptgoal", 33622}, + {"botsetscriptenemy", 33623}, + {"botclearscriptenemy", 33624}, + {"botsetattacker", 33625}, + {"botgetscriptgoal", 33626}, + {"botgetscriptgoalradius", 33627}, + {"botgetscriptgoalyaw", 33628}, + {"botgetscriptgoaltype", 33629}, + {"botgetworldsize", 33631}, + {"botnodeavailable", 33632}, + {"botfindnoderandom", 33633}, + {"botmemoryevent", 33634}, + {"botnodepick", 33636}, + {"bothasscriptgoal", 33637}, + {"botgetpersonality", 33638}, + {"botthrowgrenade", 33639}, + {"botsetpersonality", 33641}, + {"botsetdifficulty", 33642}, + {"botgetdifficulty", 33643}, + {"botgetworldclosestedge", 33644}, + {"botlookatpoint", 33645}, + {"botpredictseepoint", 33646}, + {"botcanseeentity", 33647}, + {"botgetnodesonpath", 33648}, + {"botnodepickmultiple", 33649}, + {"botgetfovdot", 33651}, + {"botsetawareness", 33652}, + {"botpursuingscriptgoal", 33653}, + {"botgetscriptgoalnode", 33654}, + {"botgetimperfectenemyinfo", 33655}, + {"botsetpathingstyle", 33657}, + {"botsetdifficultysetting", 33658}, + {"botgetdifficultysetting", 33659}, + {"botgetpathdist", 33660}, + {"botisrandomized", 33661}, + {"botpressbutton", 33662}, + {"botclearbutton", 33663}, + {"botnodescoremultiple", 33664}, + {"getnodenumber", 33665}, + {"setclientowner", 33666}, + {"setotherent", 33667}, + {"setaisightlinevisible", 33668}, + {"setentityowner", 33669}, + {"nodeisdisconnected", 33670}, + {"getnearestnode", 33671}, + {"makeentitynomeleetarget", 33672}, + {"spawnagent", 33674}, + {"finishagentdamage", 33675}, + {"setagentattacker", 33676}, + {"cloneagent", 33677}, + {"agentcanseesentient", 33678}, + {"setagentwaypoint", 33679}, + {"setgoalpos", 33680}, + {"getgoalpos", 33681}, + {"setgoalnode", 33682}, + {"setgoalentity", 33683}, + {"setgoalradius", 33684}, + {"setanimscale", 33685}, + {"setorientmode", 33686}, + {"setanimmode", 33687}, + {"setphysicsmode", 33688}, + {"setclipmode", 33689}, + {"setmaxturnspeed", 33690}, + {"getmaxturnspeed", 33691}, + {"beginmelee", 33692}, + {"setscripted", 33693}, + {"dotrajectory", 33694}, + {"doanimlerp", 33695}, + {"setviewheight", 33696}, + {"claimnode", 33697}, + {"relinquishclaimednode", 33698}, + {"setradarping", 33699}, + {"visitfxent", 33700}, + {"sub_1402ef480", 33701}, + {"sub_1402ef4e0", 33702}, + {"sub_1402dd560", 33704}, + {"sub_1402dd590", 33705}, + {"allowhighjump", 33714}, + {"isjumping", 33715}, + {"ishighjumping", 33716}, + {"sub_140529a10", 33717}, + {"sub_140529a20", 33718}, + {"getbraggingright", 33719}, + {"getmodelfromentity", 33720}, + {"getweaponheatlevel", 33721}, + {"isweaponoverheated", 33722}, + {"isshiftbuttonpresseddown", 33723}, + {"sub_14052be00", 33724}, + {"sub_14052beb0", 33725}, + {"sub_14052bf30", 33726}, + {"lightsetforplayer", 33728}, + {"lightsetoverrideenableforplayer", 33729}, + {"lightsetoverridedisableforplayer", 33730}, + {"sub_140333c10", 33731}, + {"sub_140043710", 33732}, + {"sub_14052b420", 33733}, + {"sub_1402ddd70", 33734}, + {"setanimclass", 33744}, + {"enableanimstate", 33745}, + {"setanimstate", 33746}, + {"getanimentry", 33747}, + {"getanimentryname", 33748}, + {"getanimentryalias", 33749}, + {"getanimentrycount", 33750}, + {"issprinting", 33752}, + {"jumpbuttonpressed", 33758}, + {"rotateby", 33759}, + {"getlookaheaddir", 33760}, + {"getpathgoalpos", 33761}, + {"sub_140316940", 33762}, + {"setcorpsefalling", 33763}, + {"setsurfacetype", 33764}, + {"aiphysicstrace", 33765}, + {"aiphysicstracepassed", 33766}, + {"visionsetstage", 33770}, + {"linkwaypointtotargetwithoffset", 33771}, + {"getlinkedparent", 33772}, + {"getmovingplatformparent", 33773}, + {"setnameplatematerial", 33774}, + {"sub_140313d20", 33777}, + {"sub_1403131d0", 33778}, + {"makevehiclenotcollidewithplayers", 33779}, + {"setscriptablepartstate", 33782}, + {"stopsliding", 33783}, + {"sub_140316a60", 33784}, + {"setdronegoalpos", 33785}, + {"hudoutlineenable", 33786}, + {"hudoutlinedisable", 33787}, + {"worldpointtoscreenpos", 33792}, + {"botfirstavailablegrenade", 33795}, + {"emissiveblend", 33801}, + {"sub_1402e66d0", 33804}, + {"sub_1402e66e0", 33805}, + {"sub_1402e66f0", 33806}, + {"physicssetmaxlinvel", 33810}, + {"physicssetmaxangvel", 33811}, + {"physicsgetlinvel", 33812}, + {"physicsgetlinspeed", 33813}, + {"physicsgetangvel", 33814}, + {"physicsgetangspeed", 33815}, + {"disablemissileboosting", 33816}, + {"enablemissileboosting", 33817}, + {"canspawntestclient", 33818}, + {"spawntestclient", 33819}, + {"loadcustomizationplayerview", 33820}, + {"setgrenadethrowscale", 33821}, + {"setgrenadecookscale", 33822}, + {"setplanesplineid", 33823}, + {"hudoutlineenableforclient", 33824}, + {"hudoutlinedisableforclient", 33825}, + {"hudoutlineenableforclients", 33826}, + {"hudoutlinedisableforclients", 33827}, + {"turretsetbarrelspinenabled", 33828}, + {"hasloadedcustomizationplayerview", 33829}, + {"sub_140313420", 33830}, + {"sub_1403136f0", 33831}, + {"doanimrelative", 33832}, + {"getcorpseentity", 33836}, + {"logmatchdatalife", 33838}, + {"logmatchdatadeath", 33839}, + {"queuedialogforplayer", 33840}, + {"setmlgcameradefaults", 33841}, + {"ismlgspectator", 33842}, + {"disableautoreload", 33843}, + {"enableautoreload", 33844}, + {"getlinkedchildren", 33846}, + {"botpredictenemycampspots", 33847}, + {"playsoundonmovingent", 33848}, + {"cancelmantle", 33849}, + {"hasfemalecustomizationmodel", 33850}, + {"sub_1402e6bb0", 33851}, + {"setscriptabledamageowner", 33852}, + {"setfxkilldefondelete", 33853}, + {"sub_1402e1b80", 33856}, + {"sub_140310fb0", 33858}, + {"challengenotification", 33859}, + {"sub_140528300", 33860}, + {"sub_14052bff0", 33861}, + {"linktosynchronizedparent", 33862}, + {"getclientomnvar", 33863}, + {"getcacplayerdataforgroup", 33866}, + {"cloakingenable", 33867}, + {"cloakingdisable", 33868}, + {"getunnormalizedcameramovement", 33869}, + {"sub_14031edf0", 33870}, + {"isturretoverheated", 33871}, + {"sub_14052c170", 33872}, + {"sub_14052c190", 33873}, + {"sub_14052c1b0", 33874}, + {"sub_14052c1d0", 33875}, + {"sub_14052c0b0", 33878}, + {"sub_1402de140", 33879}, + {"getvieworigin", 33884}, + {"setweaponmodelvariant", 33885}, + {"ridevehicle", 33886}, + {"stopridingvehicle", 33887}, + {"autoboltmissileeffects", 33889}, + {"disablemissilestick", 33890}, + {"enablemissilestick", 33891}, + {"setmissileminimapvisible", 33892}, + {"isoffhandweaponreadytothrow", 33893}, + {"makecollidewithitemclip", 33895}, + {"visionsetpostapplyforplayer", 33897}, + {"setlookattarget", 33898}, + {"clearlookattarget", 33899}, + {"sub_14052c250", 33907}, + {"sub_14052c290", 33908}, + {"sub_14052c2f0", 33909}, + {"sub_14052c340", 33910}, + {"sub_14052c360", 33911}, + {"sub_14031c170", 33912}, + {"sub_14031c590", 33913}, + {"setclienttriggervisionset", 33914}, + {"sub_1402e41c0", 33917}, + {"sub_1402e43b0", 33918}, + {"sub_14052b4d0", 33919}, + {"sub_14052b550", 33920}, + {"showviewmodel", 33921}, + {"hideviewmodel", 33922}, + {"setpickupweapon", 33923}, + {"allowpowerslide", 33925}, + {"allowhighjumpdrop", 33926}, + {"sub_1404045e0", 33927}, + {"sub_1405297e0", 33928}, + {"sub_14052c200", 33929}, + {"clearentity", 33930}, + {"sub_140334a40", 33931}, + {"allowdodge", 33933}, + {"sub_140529860", 33934}, + {"setminimapvisible", 33935}, + {"sub_1402e0a90", 33936}, + {"sub_1402e0bc0", 33937}, + {"sub_1402e0cf0", 33938}, + {"setplayermech", 33940}, + {"setdamagecallbackon", 33941}, + {"finishentitydamage", 33942}, + {"designatefoftarget", 33946}, + {"sethintstringvisibleonlytoowner", 33947}, + {"notifyonplayercommandremove", 33948}, + {"sub_1402e3bf0", 33949}, + {"allowboostjump", 33950}, + {"batterydischargebegin", 33951}, + {"batterydischargeend", 33952}, + {"batterydischargeonce", 33953}, + {"batterygetcharge", 33954}, + {"batterysetcharge", 33955}, + {"batteryfullrecharge", 33956}, + {"batterygetsize", 33957}, + {"batterysetdischargescale", 33958}, + {"batterygetdischargerate", 33959}, + {"batteryisinuse", 33960}, + {"enablephysicaldepthoffieldscripting", 33961}, + {"disablephysicaldepthoffieldscripting", 33962}, + {"setphysicaldepthoffield", 33963}, + {"sub_140313860", 33964}, + {"sub_14052a560", 33965}, + {"sub_140321790", 33966}, + {"sub_140321a50", 33967}, + {"sub_1402dda50", 33968}, + {"sub_14052ac50", 33969}, + {"sub_14052ad50", 33970}, + {"setdemigod", 33971}, + {"sub_140310840", 33972}, + {"setcostumemodels", 33978}, + {"sub_140529e00", 33979}, + {"sub_140313510", 33980}, + {"scriptmodelpauseanim", 33981}, + {"digitaldistortsetmaterial", 33982}, + {"disableoffhandsecondaryweapons", 33983}, + {"enableoffhandsecondaryweapons", 33984}, + {"canplaceriotshield", 33985}, + {"setriotshieldfailhint", 33986}, + {"enabledetonate", 33987}, + {"getdetonateenabled", 33988}, + {"playergetuseent", 33989}, + {"refreshshieldmodels", 33990}, + {"sub_14052c3a0", 33991}, + {"locret_140406a70", 33993}, + {"getgravity", 33994}, + {"sub_140529560", 33997}, + {"sub_140529650", 33998}, + {"setcommonplayerdatareservedint", 33999}, + {"getrankedplayerdatareservedint", 34000}, + {"setrankedplayerdatareservedint", 34001}, + {"getcommonplayerdatareservedint", 34002}, + {"sub_1402e8a20", 34003}, + {"sub_14052c3c0", 34004}, + {"addsoundmutedevice", 34005}, + {"removesoundmutedevice", 34006}, + {"clientaddsoundsubmix", 34007}, + {"clientclearsoundsubmix", 34008}, + {"sub_140312520", 34009}, + {"sub_140312ba0", 34010}, + {"sub_140312bf0", 34011}, + {"sub_140312cb0", 34012}, + {"sub_140312df0", 34013}, + {"sub_140312ff0", 34014}, + {"isusingoffhand", 34016}, + {"physicsstop", 34017}, + {"sub_14031b9e0", 34018}, + {"sub_14031e3c0", 34023}, + {"sub_1402ef8a0", 34024}, + {"sub_14052c400", 34025}, + {"initwaterclienttrigger", 34026}, + {"getcurrentweaponmodelname", 34027}, + {"sub_14031f000", 34028}, + {"setignorefoliagesightingme", 34030}, + {"loadcostumemodels", 34031}, + {"sub_14030cd90", 34036}, + {"sub_14030b1c0", 34038}, + {"sub_140322450", 34039}, + {"iscloaked", 34040}, + {"sub_140528bc0", 34041}, + {"sub_140528cf0", 34042}, + {"sub_14031fb80", 34043}, + {"sub_140320180", 34044}, + {"selfieaccessselfievalidflaginplayerdef", 34045}, + {"selfieaccessselfiecustomassetsarestreamed", 34046}, + {"sub_14031ede0", 34048}, + {"selfiescreenshottaken", 34049}, + {"sub_14031f190", 34050}, + {"sub_140319de0", 34052}, + {"setmissilecoasting", 34053}, + {"setmlgspectator", 34054}, + {"gettotalmpxp", 34055}, + {"turretsetgroundaimentity", 34056}, + {"sub_140318610", 34057}, + {"sub_140317760", 34058}, + {"sub_14032e9a0", 34059}, + {"sub_140320830", 34060}, + {"sub_140329bc0", 34061}, + {"sub_14032e370", 34062}, + {"consumereinforcement", 34063}, + {"ghost", 34064}, + {"loadweapons", 34065}, + {"sub_1402e0e80", 34067}, + {"setwaypointiconfadeatcenter", 34068}, + {"setreinforcementhintstrings", 34069}, + {"playgoliathentryanim", 34070}, + {"playgoliathtoidleanim", 34071}, + {"sub_140312210", 34072}, + {"sub_140312280", 34073}, + {"sub_140321660", 34074}, + {"playlocalannouncersound", 34075}, + {"setmissilespecialclipmask", 34076}, + {"sub_140527c40", 34077}, + {"sub_140527c60", 34078}, + {"isdodging", 34079}, + {"ispowersliding", 34080}, + {"sub_140320ab0", 34081}, + {"getcurrentping", 34082}, + {"sub_1402eeb60", 34083}, + {"sub_140329390", 34084}, + {"gethordeplayerdata", 34085}, + {"sethordeplayerdata", 34086}, + {"sub_1402dcbc0", 34087}, + {"sub_14031a0b0", 34088}, + {"sub_1403198a0", 34089}, + {"sub_1403345e0", 34090}, + {"sub_1402e7d80", 34092}, + {"sub_140404f00", 34093}, + {"issplitscreenplayer2", 34095}, + {"setowneroriginal", 34096}, + {"getlinkedtagname", 34097}, + {"sub_14032de80", 34098}, + {"sub_14032dfb0", 34099}, + {"setwaypointaerialtargeting", 34100}, + {"worldweaponsloaded", 34101}, + {"sub_140320aa0", 34102}, + {"usetriggertouchcheckstance", 34103}, + {"onlystreamactiveweapon", 34104}, + {"precachekillcamiconforweapon", 34105}, + {"selfierequestupdate", 34106}, + {"getclanwarsbonus", 34107}, + {"sub_140406810", 34108}, + {"sub_1404051d0", 34109}, + {"sub_140406340", 34110}, + {"sub_1402e72a0", 34111}, + {"sub_140404c70", 34112}, + {"sub_1404065c0", 34113}, + {"sub_140405c60", 34114}, + {"sub_140406400", 34115}, + {"sub_140406230", 34116}, + {"sub_140406650", 34117}, + {"sub_1402e7de0", 34118}, + {"sub_140333550", 34119}, + {"sub_140403fe0", 34120}, + {"sub_140320360", 34121}, + {"canhighjump", 34122}, + {"setprestigemastery", 34123}, + {"sub_140403f50", 34124}, + {"sub_14030c7b0", 34125}, + {"sub_1403206b0", 34126}, + {"sub_140329960", 34127}, + {"sub_140328100", 34128}, + {"sub_140405990", 34129}, + {"sub_1402e70c0", 34130}, + {"sub_1403335f0", 34131}, + {"getcoopplayerdatareservedint", 34132}, + {"setcoopplayerdatareservedint", 34133}, + {"sub_140406b50", 34134}, + {"sub_1402de070", 34135}, + {"sub_1402e7e40", 34136}, + {"sub_140329ba0", 34137}, + {"sub_140405af0", 34138}, + {"sub_1402e7240", 34139}, + {"sub_14031a370", 34140}, + {"sub_140406970", 34141}, + {"sub_140405b60", 34142}, + {"sub_140334e10", 34143}, + {"sub_140320a90", 34144}, + {"sub_140406c00", 34145}, + {"sub_140328bf0", 34146}, + {"sub_1404053e0", 34147}, + {"sub_140406d20", 34148}, + {"sub_14032c900", 34149}, + {"sub_14032c9e0", 34150}, + {"sub_140044360", 34151}, + {"sub_140333680", 34152}, + {"sub_1402e7130", 34153}, + {"sub_1403294b0", 34154}, + {"sub_140320b40", 34155}, + {"sub_140333710", 34156}, + }; + + std::unordered_map token_map = + { + {"CodeCallback_BulletHitEntity", 180}, + {"CodeCallback_CodeEndGame", 181}, + {"CodeCallback_EntityDamage", 182}, + {"CodeCallback_EntityOutOfWorld", 183}, + {"CodeCallback_HostMigration", 185}, + {"CodeCallback_PartyMembers", 187}, + {"CodeCallback_PlayerConnect", 188}, + {"CodeCallback_PlayerDamage", 189}, + {"CodeCallback_PlayerDisconnect", 190}, + {"CodeCallback_PlayerGrenadeSuicide", 191}, + {"CodeCallback_PlayerKilled", 192}, + {"CodeCallback_PlayerLastStand", 193}, + {"CodeCallback_PlayerMigrated", 194}, + {"CodeCallback_StartGameType", 195}, + {"CodeCallback_VehicleDamage", 196}, + {"CreateStruct", 221}, + {"InitStructs", 522}, + {"main", 619}, + {"AbortLevel", 1727}, + {"callbackVoid", 6662}, + {"CodeCallback_GiveKillstreak", 8192}, + {"SetDefaultCallbacks", 32577}, + {"SetupCallbacks", 33531}, + {"SetupDamageFlags", 33542}, + {"struct", 36698}, + {"codescripts/delete", 0x053D}, + {"codescripts/struct", 0x053E}, + {"maps/mp/gametypes/_callbacksetup", 0x0540}, + {"codescripts/character", 0xA4E5}, + {"common_scripts/_artcommon", 42214}, + {"common_scripts/_bcs_location_trigs", 42215}, + {"common_scripts/_createfx", 42216}, + {"common_scripts/_createfxmenu", 42217}, + {"common_scripts/_destructible", 42218}, + {"common_scripts/_dynamic_world", 42219}, + {"maps/createart/mp_vlobby_room_art", 42735}, + {"maps/createart/mp_vlobby_room_fog", 42736}, + {"maps/createart/mp_vlobby_room_fog_hdr", 42737} + }; +} diff --git a/src/client/game/scripting/functions.cpp b/src/client/game/scripting/functions.cpp new file mode 100644 index 00000000..3452c767 --- /dev/null +++ b/src/client/game/scripting/functions.cpp @@ -0,0 +1,106 @@ +#include +#include "functions.hpp" + +#include + +namespace scripting +{ + namespace + { + std::unordered_map lowercase_map( + const std::unordered_map& old_map) + { + std::unordered_map new_map{}; + for (auto& entry : old_map) + { + new_map[utils::string::to_lower(entry.first)] = entry.second; + } + + return new_map; + } + + const std::unordered_map& get_methods() + { + static auto methods = lowercase_map(method_map); + return methods; + } + + const std::unordered_map& get_functions() + { + static auto function = lowercase_map(function_map); + return function; + } + + int find_function_index(const std::string& name, const bool prefer_global) + { + const auto target = utils::string::to_lower(name); + + const auto& primary_map = prefer_global + ? get_functions() + : get_methods(); + const auto& secondary_map = !prefer_global + ? get_functions() + : get_methods(); + + auto function_entry = primary_map.find(target); + if (function_entry != primary_map.end()) + { + return function_entry->second; + } + + function_entry = secondary_map.find(target); + if (function_entry != secondary_map.end()) + { + return function_entry->second; + } + + return -1; + } + + script_function get_function_by_index(const unsigned index) + { + static const auto function_table = SELECT_VALUE(0x149668F50, 0x147DD1850); + static const auto method_table = SELECT_VALUE(0x14966A670, 0x147DD2F50); + + if (index < 0x2DF) + { + return reinterpret_cast(function_table)[index]; + } + + return reinterpret_cast(method_table)[index - 0x8000]; + } + } + + std::string find_token(unsigned int id) + { + for (const auto& token : token_map) + { + if (token.second == id) + { + return token.first; + } + } + + return utils::string::va("_ID%i", id); + } + + unsigned int find_token_id(const std::string& name) + { + const auto result = token_map.find(name); + + if (result != token_map.end()) + { + return result->second; + } + + return 0; + } + + script_function find_function(const std::string& name, const bool prefer_global) + { + const auto index = find_function_index(name, prefer_global); + if (index < 0) return nullptr; + + return get_function_by_index(index); + } +} diff --git a/src/client/game/scripting/functions.hpp b/src/client/game/scripting/functions.hpp new file mode 100644 index 00000000..0422bcf7 --- /dev/null +++ b/src/client/game/scripting/functions.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "game/game.hpp" + +namespace scripting +{ + extern std::unordered_map method_map; + extern std::unordered_map function_map; + extern std::unordered_map token_map; + + using script_function = void(*)(game::scr_entref_t); + + std::string find_token(unsigned int id); + unsigned int find_token_id(const std::string& name); + + script_function find_function(const std::string& name, const bool prefer_global); +} diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp new file mode 100644 index 00000000..462a6628 --- /dev/null +++ b/src/client/game/scripting/lua/context.cpp @@ -0,0 +1,489 @@ +#include +#include "context.hpp" +#include "error.hpp" +#include "value_conversion.hpp" + +#include "../execution.hpp" +#include "../functions.hpp" + +#include "../../../component/command.hpp" +#include "../../../component/logfile.hpp" +#include "../../../component/scripting.hpp" + +#include + +namespace scripting::lua +{ + namespace + { + std::vector load_game_constants() + { + std::vector result{}; + + const auto constants = game::GScr_LoadConsts.get(); + + ud_t ud; + ud_init(&ud); + ud_set_mode(&ud, 64); + ud_set_pc(&ud, uint64_t(constants)); + ud_set_input_buffer(&ud, reinterpret_cast(constants), INT32_MAX); + + while (true) + { + ud_disassemble(&ud); + + if (ud_insn_mnemonic(&ud) == UD_Iret) + { + break; + } + + if (ud_insn_mnemonic(&ud) == UD_Imov) + { + const auto* operand = ud_insn_opr(&ud, 0); + if (operand && operand->type == UD_OP_REG && operand->base == UD_R_ECX) + { + operand = ud_insn_opr(&ud, 1); + if (operand && operand->type == UD_OP_IMM && (operand->base == UD_R_RAX || operand->base == UD_R_EAX)) + { + result.emplace_back(reinterpret_cast(0x1409C1CE0)[operand->lval.udword]); + } + } + } + + if (ud_insn_mnemonic(&ud) == UD_Ilea) + { + const auto* operand = ud_insn_opr(&ud, 0); + if (!operand || operand->type != UD_OP_REG || operand->base != UD_R_RCX) + { + continue; + } + + operand = ud_insn_opr(&ud, 1); + if (operand && operand->type == UD_OP_MEM && operand->base == UD_R_RIP) + { + auto* operand_ptr = reinterpret_cast(ud_insn_len(&ud) + ud_insn_off(&ud) + operand->lval. + sdword); + if (!utils::memory::is_bad_read_ptr(operand_ptr) && utils::memory::is_rdata_ptr(operand_ptr) && + strlen(operand_ptr) > 0) + { + result.emplace_back(operand_ptr); + } + } + } + + if (*reinterpret_cast(ud.pc) == 0xCC) break; // int 3 + } + + return result; + } + + const std::vector& get_game_constants() + { + static auto constants = load_game_constants(); + return constants; + } + + void setup_entity_type(sol::state& state, event_handler& handler, scheduler& scheduler) + { + state["level"] = entity{*game::levelEntityId}; + + auto vector_type = state.new_usertype("vector", sol::constructors()); + vector_type["x"] = sol::property(&vector::get_x, &vector::set_x); + vector_type["y"] = sol::property(&vector::get_y, &vector::set_y); + vector_type["z"] = sol::property(&vector::get_z, &vector::set_z); + + vector_type["r"] = sol::property(&vector::get_x, &vector::set_x); + vector_type["g"] = sol::property(&vector::get_y, &vector::set_y); + vector_type["b"] = sol::property(&vector::get_z, &vector::set_z); + + auto entity_type = state.new_usertype("entity"); + + for (const auto& func : method_map) + { + const auto name = utils::string::to_lower(func.first); + entity_type[name.data()] = [name](const entity& entity, const sol::this_state s, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + return convert(s, entity.call(name, arguments)); + }; + } + + for (const auto& constant : get_game_constants()) + { + entity_type[constant] = sol::property( + [constant](const entity& entity, const sol::this_state s) + { + return convert(s, entity.get(constant)); + }, + [constant](const entity& entity, const sol::this_state s, const sol::lua_value& value) + { + entity.set(constant, convert({s, value})); + }); + } + + entity_type["set"] = [](const entity& entity, const std::string& field, + const sol::lua_value& value) + { + entity.set(field, convert(value)); + }; + + entity_type["get"] = [](const entity& entity, const sol::this_state s, const std::string& field) + { + return convert(s, entity.get(field)); + }; + + entity_type["notify"] = [](const entity& entity, const sol::this_state s, const std::string& event, + sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + notify(entity, event, arguments); + }; + + entity_type["onnotify"] = [&handler](const entity& entity, const std::string& event, + const event_callback& callback) + { + event_listener listener{}; + listener.callback = callback; + listener.entity = entity; + listener.event = event; + listener.is_volatile = false; + + return handler.add_event_listener(std::move(listener)); + }; + + entity_type["onnotifyonce"] = [&handler](const entity& entity, const std::string& event, + const event_callback& callback) + { + event_listener listener{}; + listener.callback = callback; + listener.entity = entity; + listener.event = event; + listener.is_volatile = true; + + return handler.add_event_listener(std::move(listener)); + }; + + entity_type["call"] = [](const entity& entity, const sol::this_state s, const std::string& function, + sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + return convert(s, entity.call(function, arguments)); + }; + + entity_type[sol::meta_function::new_index] = [](const entity& entity, const std::string& field, + const sol::lua_value& value) + { + entity.set(field, convert(value)); + }; + + entity_type[sol::meta_function::index] = [](const entity& entity, const sol::this_state s, const std::string& field) + { + return convert(s, entity.get(field)); + }; + + entity_type["getstruct"] = [](const entity& entity, const sol::this_state s) + { + const auto id = entity.get_entity_id(); + return scripting::lua::entity_to_struct(s, id); + }; + + entity_type["struct"] = sol::property([](const entity& entity, const sol::this_state s) + { + const auto id = entity.get_entity_id(); + return scripting::lua::entity_to_struct(s, id); + }); + + entity_type["scriptcall"] = [](const entity& entity, const sol::this_state s, const std::string& filename, + const std::string function, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + return convert(s, call_script_function(entity, filename, function, arguments)); + }; + + struct game + { + }; + auto game_type = state.new_usertype("game_"); + state["game"] = game(); + + for (const auto& func : function_map) + { + const auto name = utils::string::to_lower(func.first); + game_type[name] = [name](const game&, const sol::this_state s, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + return convert(s, call(name, arguments)); + }; + } + + game_type["call"] = [](const game&, const sol::this_state s, const std::string& function, + sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + return convert(s, call(function, arguments)); + }; + + game_type["ontimeout"] = [&scheduler](const game&, const sol::protected_function& callback, + const long long milliseconds) + { + return scheduler.add(callback, milliseconds, true); + }; + + game_type["oninterval"] = [&scheduler](const game&, const sol::protected_function& callback, + const long long milliseconds) + { + return scheduler.add(callback, milliseconds, false); + }; + + game_type["executecommand"] = [](const game&, const std::string& command) + { + command::execute(command, false); + }; + + game_type["onplayerdamage"] = [](const game&, const sol::protected_function& callback) + { + logfile::add_player_damage_callback(callback); + }; + + game_type["onplayerkilled"] = [](const game&, const sol::protected_function& callback) + { + logfile::add_player_killed_callback(callback); + }; + + game_type["getgamevar"] = [](const sol::this_state s) + { + const auto id = *reinterpret_cast(0x14815DEB4); + const auto value = ::game::scr_VarGlob->childVariableValue[id]; + + ::game::VariableValue variable{}; + variable.type = value.type; + variable.u.uintValue = value.u.u.uintValue; + + return convert(s, variable); + }; + + game_type["getfunctions"] = [entity_type](const game&, const sol::this_state s, const std::string& filename) + { + if (scripting::script_function_table.find(filename) == scripting::script_function_table.end()) + { + throw std::runtime_error("File '" + filename + "' not found"); + } + + auto functions = sol::table::create(s.lua_state()); + + for (const auto& function : scripting::script_function_table[filename]) + { + functions[function.first] = sol::overload( + [filename, function](const entity& entity, const sol::this_state s, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + gsl::finally(&logfile::enable_vm_execute_hook); + logfile::disable_vm_execute_hook(); + + return convert(s, call_script_function(entity, filename, function.first, arguments)); + }, + [filename, function](const sol::this_state s, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + gsl::finally(&logfile::enable_vm_execute_hook); + logfile::disable_vm_execute_hook(); + + return convert(s, call_script_function(*::game::levelEntityId, filename, function.first, arguments)); + } + ); + } + + return functions; + }; + + game_type["scriptcall"] = [](const game&, const sol::this_state s, const std::string& filename, + const std::string function, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + gsl::finally(&logfile::enable_vm_execute_hook); + logfile::disable_vm_execute_hook(); + + return convert(s, call_script_function(*::game::levelEntityId, filename, function, arguments)); + }; + + game_type["detour"] = [](const game&, const sol::this_state s, const std::string& filename, + const std::string function_name, const sol::protected_function& function) + { + const auto pos = get_function_pos(filename, function_name); + logfile::vm_execute_hooks[pos] = function; + + auto detour = sol::table::create(function.lua_state()); + + detour["disable"] = [pos]() + { + logfile::vm_execute_hooks.erase(pos); + }; + + detour["enable"] = [pos, function]() + { + logfile::vm_execute_hooks[pos] = function; + }; + + detour["invoke"] = sol::overload( + [filename, function_name](const entity& entity, const sol::this_state s, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + gsl::finally(&logfile::enable_vm_execute_hook); + logfile::disable_vm_execute_hook(); + + return convert(s, call_script_function(entity, filename, function_name, arguments)); + }, + [filename, function_name](const sol::this_state s, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + gsl::finally(&logfile::enable_vm_execute_hook); + logfile::disable_vm_execute_hook(); + + return convert(s, call_script_function(*::game::levelEntityId, filename, function_name, arguments)); + } + ); + + return detour; + }; + } + } + + context::context(std::string folder) + : folder_(std::move(folder)) + , scheduler_(state_) + , event_handler_(state_) + + { + this->state_.open_libraries(sol::lib::base, + sol::lib::package, + sol::lib::io, + sol::lib::string, + sol::lib::os, + sol::lib::math, + sol::lib::table); + + this->state_["include"] = [this](const std::string& file) + { + this->load_script(file); + }; + + sol::function old_require = this->state_["require"]; + auto base_path = utils::string::replace(this->folder_, "/", ".") + "."; + this->state_["require"] = [base_path, old_require](const std::string& path) + { + return old_require(base_path + path); + }; + + this->state_["scriptdir"] = [this]() + { + return this->folder_; + }; + + setup_entity_type(this->state_, this->event_handler_, this->scheduler_); + + printf("Loading script '%s'\n", this->folder_.data()); + this->load_script("__init__"); + } + + context::~context() + { + this->collect_garbage(); + this->scheduler_.clear(); + this->event_handler_.clear(); + this->state_ = {}; + } + + void context::run_frame() + { + this->scheduler_.run_frame(); + this->collect_garbage(); + } + + void context::notify(const event& e) + { + this->scheduler_.dispatch(e); + this->event_handler_.dispatch(e); + } + + void context::collect_garbage() + { + this->state_.collect_garbage(); + } + + void context::load_script(const std::string& script) + { + if (!this->loaded_scripts_.emplace(script).second) + { + return; + } + + const auto file = (std::filesystem::path{this->folder_} / (script + ".lua")).generic_string(); + handle_error(this->state_.safe_script_file(file, &sol::script_pass_on_error)); + } +} diff --git a/src/client/game/scripting/lua/context.hpp b/src/client/game/scripting/lua/context.hpp new file mode 100644 index 00000000..79a5e905 --- /dev/null +++ b/src/client/game/scripting/lua/context.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include "../event.hpp" + +#pragma warning(push) +#pragma warning(disable: 4702) + +#define SOL_ALL_SAFETIES_ON 1 +#define SOL_PRINT_ERRORS 0 +#include + +#pragma warning(pop) + +#include "scheduler.hpp" +#include "event_handler.hpp" + +namespace scripting::lua +{ + class context + { + public: + context(std::string folder); + ~context(); + + context(context&&) noexcept = delete; + context& operator=(context&&) noexcept = delete; + + context(const context&) = delete; + context& operator=(const context&) = delete; + + void run_frame(); + void notify(const event& e); + void collect_garbage(); + + private: + sol::state state_{}; + std::string folder_; + std::unordered_set loaded_scripts_; + + scheduler scheduler_; + event_handler event_handler_; + + void load_script(const std::string& script); + }; +} diff --git a/src/client/game/scripting/lua/engine.cpp b/src/client/game/scripting/lua/engine.cpp new file mode 100644 index 00000000..351ad04b --- /dev/null +++ b/src/client/game/scripting/lua/engine.cpp @@ -0,0 +1,75 @@ +#include +#include "engine.hpp" +#include "context.hpp" + +#include "../execution.hpp" +#include "../../../component/logfile.hpp" +#include "../../../component/game_module.hpp" + +#include + +namespace scripting::lua::engine +{ + namespace + { + auto& get_scripts() + { + static std::vector> scripts{}; + return scripts; + } + + void load_scripts(const std::string& script_dir) + { + if (!utils::io::directory_exists(script_dir)) + { + return; + } + + const auto scripts = utils::io::list_files(script_dir); + + for (const auto& script : scripts) + { + if (std::filesystem::is_directory(script) && utils::io::file_exists(script + "/__init__.lua")) + { + get_scripts().push_back(std::make_unique(script)); + } + } + } + } + + void stop() + { + logfile::clear_callbacks(); + get_scripts().clear(); + } + + void start() + { + // No SP until there is a concept + if (game::environment::is_sp()) + { + return; + } + + stop(); + load_scripts(game_module::get_host_module().get_folder() + "/data/scripts/"); + load_scripts("h1-mod/scripts/"); + load_scripts("data/scripts/"); + } + + void notify(const event& e) + { + for (auto& script : get_scripts()) + { + script->notify(e); + } + } + + void run_frame() + { + for (auto& script : get_scripts()) + { + script->run_frame(); + } + } +} diff --git a/src/client/game/scripting/lua/engine.hpp b/src/client/game/scripting/lua/engine.hpp new file mode 100644 index 00000000..471316cd --- /dev/null +++ b/src/client/game/scripting/lua/engine.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "../event.hpp" + +namespace scripting::lua::engine +{ + void start(); + void stop(); + void notify(const event& e); + void run_frame(); +} diff --git a/src/client/game/scripting/lua/error.cpp b/src/client/game/scripting/lua/error.cpp new file mode 100644 index 00000000..935db0f0 --- /dev/null +++ b/src/client/game/scripting/lua/error.cpp @@ -0,0 +1,37 @@ +#include +#include "error.hpp" +#include "../execution.hpp" + +#include "component/console.hpp" + +namespace scripting::lua +{ + namespace + { + void notify_error() + { + try + { + call("iprintln", {"^1Script execution error!"}); + } + catch (...) + { + } + } + } + + void handle_error(const sol::protected_function_result& result) + { + if (!result.valid()) + { + console::error("************** Script execution error **************\n"); + + const sol::error err = result; + console::error("%s\n", err.what()); + + console::error("****************************************************\n"); + + notify_error(); + } + } +} diff --git a/src/client/game/scripting/lua/error.hpp b/src/client/game/scripting/lua/error.hpp new file mode 100644 index 00000000..dab56bee --- /dev/null +++ b/src/client/game/scripting/lua/error.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "context.hpp" + +namespace scripting::lua +{ + void handle_error(const sol::protected_function_result& result); +} diff --git a/src/client/game/scripting/lua/event_handler.cpp b/src/client/game/scripting/lua/event_handler.cpp new file mode 100644 index 00000000..7121ea63 --- /dev/null +++ b/src/client/game/scripting/lua/event_handler.cpp @@ -0,0 +1,174 @@ +#include "std_include.hpp" +#include "context.hpp" +#include "error.hpp" +#include "value_conversion.hpp" + +namespace scripting::lua +{ + event_handler::event_handler(sol::state& state) + : state_(state) + { + auto event_listener_handle_type = state.new_usertype("event_listener_handle"); + + event_listener_handle_type["clear"] = [this](const event_listener_handle& handle) + { + this->remove(handle); + }; + + event_listener_handle_type["endon"] = [this](const event_listener_handle& handle, const entity& entity, const std::string& event) + { + this->add_endon_condition(handle, entity, event); + }; + } + + void event_handler::dispatch(const event& event) + { + bool has_built_arguments = false; + event_arguments arguments{}; + + callbacks_.access([&](task_list& tasks) + { + this->merge_callbacks(); + this->handle_endon_conditions(event); + + for (auto i = tasks.begin(); i != tasks.end();) + { + if (i->event != event.name || i->entity != event.entity) + { + ++i; + continue; + } + + if (!i->is_deleted) + { + if(!has_built_arguments) + { + has_built_arguments = true; + arguments = this->build_arguments(event); + } + + handle_error(i->callback(sol::as_args(arguments))); + } + + if (i->is_volatile || i->is_deleted) + { + i = tasks.erase(i); + } + else + { + ++i; + } + } + }); + } + + event_listener_handle event_handler::add_event_listener(event_listener&& listener) + { + const uint64_t id = ++this->current_listener_id_; + listener.id = id; + listener.is_deleted = false; + + new_callbacks_.access([&listener](task_list& tasks) + { + tasks.emplace_back(std::move(listener)); + }); + + return {id}; + } + + void event_handler::add_endon_condition(const event_listener_handle& handle, const entity& entity, + const std::string& event) + { + auto merger = [&](task_list& tasks) + { + for(auto& task : tasks) + { + if(task.id == handle.id) + { + task.endon_conditions.emplace_back(entity, event); + } + } + }; + + callbacks_.access([&](task_list& tasks) + { + merger(tasks); + new_callbacks_.access(merger); + }); + } + + void event_handler::clear() + { + callbacks_.access([&](task_list& tasks) + { + new_callbacks_.access([&](task_list& new_tasks) + { + new_tasks.clear(); + tasks.clear(); + }); + }); + } + + void event_handler::remove(const event_listener_handle& handle) + { + auto mask_as_deleted = [&](task_list& tasks) + { + for (auto& task : tasks) + { + if (task.id == handle.id) + { + task.is_deleted = true; + break; + } + } + }; + + callbacks_.access(mask_as_deleted); + new_callbacks_.access(mask_as_deleted); + } + + void event_handler::merge_callbacks() + { + callbacks_.access([&](task_list& tasks) + { + new_callbacks_.access([&](task_list& new_tasks) + { + tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), + std::move_iterator(new_tasks.end())); + new_tasks = {}; + }); + }); + } + + void event_handler::handle_endon_conditions(const event& event) + { + auto deleter = [&](task_list& tasks) + { + for(auto& task : tasks) + { + for(auto& condition : task.endon_conditions) + { + if(condition.first == event.entity && condition.second == event.name) + { + task.is_deleted = true; + break; + } + } + } + }; + + callbacks_.access(deleter); + } + + event_arguments event_handler::build_arguments(const event& event) const + { + event_arguments arguments; + + for (const auto& argument : event.arguments) + { + arguments.emplace_back(convert(this->state_, argument)); + } + + return arguments; + } +} diff --git a/src/client/game/scripting/lua/event_handler.hpp b/src/client/game/scripting/lua/event_handler.hpp new file mode 100644 index 00000000..fc95b704 --- /dev/null +++ b/src/client/game/scripting/lua/event_handler.hpp @@ -0,0 +1,58 @@ +#pragma once + +namespace scripting::lua +{ + using event_arguments = std::vector; + using event_callback = sol::protected_function; + + class event_listener_handle + { + public: + uint64_t id = 0; + }; + + class event_listener final : public event_listener_handle + { + public: + std::string event = {}; + entity entity{}; + event_callback callback = {}; + bool is_volatile = false; + bool is_deleted = false; + std::vector> endon_conditions{}; + }; + + class event_handler final + { + public: + event_handler(sol::state& state); + + event_handler(event_handler&&) noexcept = delete; + event_handler& operator=(event_handler&&) noexcept = delete; + + event_handler(const scheduler&) = delete; + event_handler& operator=(const event_handler&) = delete; + + void dispatch(const event& event); + + event_listener_handle add_event_listener(event_listener&& listener); + + void clear(); + + private: + sol::state& state_; + std::atomic_int64_t current_listener_id_ = 0; + + using task_list = std::vector; + utils::concurrency::container new_callbacks_; + utils::concurrency::container callbacks_; + + void remove(const event_listener_handle& handle); + void merge_callbacks(); + void handle_endon_conditions(const event& event); + + void add_endon_condition(const event_listener_handle& handle, const entity& entity, const std::string& event); + + event_arguments build_arguments(const event& event) const; + }; +} diff --git a/src/client/game/scripting/lua/scheduler.cpp b/src/client/game/scripting/lua/scheduler.cpp new file mode 100644 index 00000000..1afb7df2 --- /dev/null +++ b/src/client/game/scripting/lua/scheduler.cpp @@ -0,0 +1,171 @@ +#include "std_include.hpp" +#include "context.hpp" +#include "error.hpp" + +namespace scripting::lua +{ + scheduler::scheduler(sol::state& state) + { + auto task_handle_type = state.new_usertype("task_handle"); + + task_handle_type["clear"] = [this](const task_handle& handle) + { + this->remove(handle); + }; + + task_handle_type["endon"] = [this](const task_handle& handle, const entity& entity, const std::string& event) + { + this->add_endon_condition(handle, entity, event); + }; + } + + void scheduler::dispatch(const event& event) + { + auto deleter = [&](task_list& tasks) + { + for(auto& task : tasks) + { + for(auto& condition : task.endon_conditions) + { + if(condition.first == event.entity && condition.second == event.name) + { + task.is_deleted = true; + break; + } + } + } + }; + + callbacks_.access([&](task_list& tasks) + { + deleter(tasks); + new_callbacks_.access(deleter); + }); + } + + void scheduler::run_frame() + { + callbacks_.access([&](task_list& tasks) + { + this->merge_callbacks(); + + for (auto i = tasks.begin(); i != tasks.end();) + { + const auto now = std::chrono::high_resolution_clock::now(); + const auto diff = now - i->last_call; + + if (diff < i->delay) + { + ++i; + continue; + } + + i->last_call = now; + + if (!i->is_deleted) + { + handle_error(i->callback()); + } + + if (i->is_volatile || i->is_deleted) + { + i = tasks.erase(i); + } + else + { + ++i; + } + } + }); + } + + void scheduler::clear() + { + callbacks_.access([&](task_list& tasks) + { + new_callbacks_.access([&](task_list& new_tasks) + { + new_tasks.clear(); + tasks.clear(); + }); + }); + } + + task_handle scheduler::add(const sol::protected_function& callback, const long long milliseconds, + const bool is_volatile) + { + return this->add(callback, std::chrono::milliseconds(milliseconds), is_volatile); + } + + task_handle scheduler::add(const sol::protected_function& callback, const std::chrono::milliseconds delay, + const bool is_volatile) + { + const uint64_t id = ++this->current_task_id_; + + task task; + task.is_volatile = is_volatile; + task.callback = callback; + task.delay = delay; + task.last_call = std::chrono::steady_clock::now(); + task.id = id; + task.is_deleted = false; + + new_callbacks_.access([&task](task_list& tasks) + { + tasks.emplace_back(std::move(task)); + }); + + return {id}; + } + + void scheduler::add_endon_condition(const task_handle& handle, const entity& entity, const std::string& event) + { + auto merger = [&](task_list& tasks) + { + for(auto& task : tasks) + { + if(task.id == handle.id) + { + task.endon_conditions.emplace_back(entity, event); + } + } + }; + + callbacks_.access([&](task_list& tasks) + { + merger(tasks); + new_callbacks_.access(merger); + }); + } + + void scheduler::remove(const task_handle& handle) + { + auto mask_as_deleted = [&](task_list& tasks) + { + for (auto& task : tasks) + { + if (task.id == handle.id) + { + task.is_deleted = true; + break; + } + } + }; + + callbacks_.access(mask_as_deleted); + new_callbacks_.access(mask_as_deleted); + } + + void scheduler::merge_callbacks() + { + callbacks_.access([&](task_list& tasks) + { + new_callbacks_.access([&](task_list& new_tasks) + { + tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), + std::move_iterator(new_tasks.end())); + new_tasks = {}; + }); + }); + } +} diff --git a/src/client/game/scripting/lua/scheduler.hpp b/src/client/game/scripting/lua/scheduler.hpp new file mode 100644 index 00000000..17c90797 --- /dev/null +++ b/src/client/game/scripting/lua/scheduler.hpp @@ -0,0 +1,54 @@ +#pragma once +#include + +namespace scripting::lua +{ + class context; + + class task_handle + { + public: + uint64_t id = 0; + }; + + class task final : public task_handle + { + public: + std::chrono::steady_clock::time_point last_call{}; + sol::protected_function callback{}; + std::chrono::milliseconds delay{}; + bool is_volatile = false; + bool is_deleted = false; + std::vector> endon_conditions{}; + }; + + class scheduler final + { + public: + scheduler(sol::state& state); + + scheduler(scheduler&&) noexcept = delete; + scheduler& operator=(scheduler&&) noexcept = delete; + + scheduler(const scheduler&) = delete; + scheduler& operator=(const scheduler&) = delete; + + void dispatch(const event& event); + void run_frame(); + void clear(); + + task_handle add(const sol::protected_function& callback, long long milliseconds, bool is_volatile); + task_handle add(const sol::protected_function& callback, std::chrono::milliseconds delay, bool is_volatile); + + private: + using task_list = std::vector; + utils::concurrency::container new_callbacks_; + utils::concurrency::container callbacks_; + std::atomic_int64_t current_task_id_ = 0; + + void add_endon_condition(const task_handle& handle, const entity& entity, const std::string& event); + + void remove(const task_handle& handle); + void merge_callbacks(); + }; +} diff --git a/src/client/game/scripting/lua/value_conversion.cpp b/src/client/game/scripting/lua/value_conversion.cpp new file mode 100644 index 00000000..defbe14d --- /dev/null +++ b/src/client/game/scripting/lua/value_conversion.cpp @@ -0,0 +1,319 @@ +#include +#include "value_conversion.hpp" +#include "../functions.hpp" +#include "../execution.hpp" +#include ".../../component/logfile.hpp" + +namespace scripting::lua +{ + namespace + { + struct array_value + { + int index; + script_value value; + }; + + sol::lua_value entity_to_array(lua_State* state, unsigned int id) + { + auto table = sol::table::create(state); + auto metatable = sol::table::create(state); + + std::unordered_map values; + + const auto offset = 64000 * (id & 3); + + auto current = game::scr_VarGlob->objectVariableChildren[id].firstChild; + auto idx = 1; + + for (auto i = offset + current; current; i = offset + current) + { + const auto var = game::scr_VarGlob->childVariableValue[i]; + + if (var.type == game::SCRIPT_NONE) + { + current = var.nextSibling; + continue; + } + + const auto string_value = (game::scr_string_t)((unsigned __int8)var.name_lo + (var.k.keys.name_hi << 8)); + const auto* str = game::SL_ConvertToString(string_value); + + std::string key = string_value < 0x40000 && str + ? str + : std::to_string(idx++); + + game::VariableValue variable{}; + variable.type = var.type; + variable.u = var.u.u; + + array_value value; + value.index = i; + value.value = variable; + + values[key] = value; + + current = var.nextSibling; + } + + table["getkeys"] = [values]() + { + std::vector _keys; + + for (const auto& entry : values) + { + _keys.push_back(entry.first); + } + + return _keys; + }; + + metatable[sol::meta_function::new_index] = [values](const sol::table t, const sol::this_state s, + const sol::lua_value& key_value, const sol::lua_value& value) + { + const auto key = key_value.is() + ? std::to_string(key_value.as()) + : key_value.as(); + + if (values.find(key) == values.end()) + { + return; + } + + const auto i = values.at(key).index; + const auto variable = &game::scr_VarGlob->childVariableValue[i]; + + const auto new_variable = convert({s, value}).get_raw(); + + game::AddRefToValue(new_variable.type, new_variable.u); + game::RemoveRefToValue(variable->type, variable->u.u); + + variable->type = (char)new_variable.type; + variable->u.u = new_variable.u; + }; + + metatable[sol::meta_function::index] = [values](const sol::table t, const sol::this_state s, + const sol::lua_value& key_value) + { + const auto key = key_value.is() + ? std::to_string(key_value.as()) + : key_value.as(); + + if (values.find(key) == values.end()) + { + return sol::lua_value{s, sol::lua_nil}; + } + + return convert(s, values.at(key).value); + }; + + metatable[sol::meta_function::length] = [values]() + { + return values.size(); + }; + + table[sol::metatable_key] = metatable; + + return {state, table}; + } + + game::VariableValue convert_function(sol::lua_value value) + { + const auto function = value.as(); + const auto index = reinterpret_cast(logfile::vm_execute_hooks.size()); + + logfile::vm_execute_hooks[index] = function; + + game::VariableValue func; + func.type = game::SCRIPT_FUNCTION; + func.u.codePosValue = index; + + return func; + } + + sol::lua_value convert_function(lua_State* state, const char* pos) + { + return sol::overload( + [pos](const entity& entity, const sol::this_state s, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + return convert(s, exec_ent_thread(entity, pos, arguments)); + }, + [pos](const sol::this_state s, sol::variadic_args va) + { + std::vector arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + return convert(s, exec_ent_thread(*game::levelEntityId, pos, arguments)); + } + ); + } + } + + sol::lua_value entity_to_struct(lua_State* state, unsigned int parent_id) + { + auto table = sol::table::create(state); + auto metatable = sol::table::create(state); + + const auto offset = 64000 * (parent_id & 3); + + metatable[sol::meta_function::new_index] = [offset, parent_id](const sol::table t, const sol::this_state s, + const sol::lua_value& field, const sol::lua_value& value) + { + const auto id = field.is() + ? scripting::find_token_id(field.as()) + : field.as(); + + if (!id) + { + return; + } + + const auto variable_id = game::GetVariable(parent_id, id); + const auto variable = &game::scr_VarGlob->childVariableValue[variable_id + offset]; + const auto new_variable = convert({s, value}).get_raw(); + + game::AddRefToValue(new_variable.type, new_variable.u); + game::RemoveRefToValue(variable->type, variable->u.u); + + variable->type = (char)new_variable.type; + variable->u.u = new_variable.u; + }; + + metatable[sol::meta_function::index] = [offset, parent_id](const sol::table t, const sol::this_state s, + const sol::lua_value& field) + { + const auto id = field.is() + ? scripting::find_token_id(field.as()) + : field.as(); + + if (!id) + { + return sol::lua_value{s, sol::lua_nil}; + } + + const auto variable_id = game::FindVariable(parent_id, id); + if (!variable_id) + { + return sol::lua_value{s, sol::lua_nil}; + } + + const auto variable = game::scr_VarGlob->childVariableValue[variable_id + offset]; + + game::VariableValue result{}; + result.u = variable.u.u; + result.type = (game::scriptType_e)variable.type; + + return convert(s, result); + }; + + table[sol::metatable_key] = metatable; + + return {state, table}; + } + + script_value convert(const sol::lua_value& value) + { + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return convert_function(value); + } + + return {}; + } + + sol::lua_value convert(lua_State* state, const script_value& value) + { + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is>()) + { + return entity_to_struct(state, value.get_raw().u.uintValue); + } + + if (value.is>()) + { + return entity_to_array(state, value.get_raw().u.uintValue); + } + + if (value.is>()) + { + return convert_function(state, value.get_raw().u.codePosValue); + } + + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is()) + { + return {state, value.as()}; + } + + return {state, sol::lua_nil}; + } +} diff --git a/src/client/game/scripting/lua/value_conversion.hpp b/src/client/game/scripting/lua/value_conversion.hpp new file mode 100644 index 00000000..93256f80 --- /dev/null +++ b/src/client/game/scripting/lua/value_conversion.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include "context.hpp" + +namespace scripting::lua +{ + sol::lua_value entity_to_struct(lua_State* state, unsigned int parent_id); + + script_value convert(const sol::lua_value& value); + sol::lua_value convert(lua_State* state, const script_value& value); +} diff --git a/src/client/game/scripting/safe_execution.cpp b/src/client/game/scripting/safe_execution.cpp new file mode 100644 index 00000000..92daa3b7 --- /dev/null +++ b/src/client/game/scripting/safe_execution.cpp @@ -0,0 +1,72 @@ +#include +#include "safe_execution.hpp" + +#pragma warning(push) +#pragma warning(disable: 4611) + +namespace scripting::safe_execution +{ + namespace + { + bool execute_with_seh(const script_function function, const game::scr_entref_t& entref) + { + __try + { + function(entref); + return true; + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + return false; + } + } + } + + bool call(const script_function function, const game::scr_entref_t& entref) + { + *game::g_script_error_level += 1; + if (game::_setjmp(&game::g_script_error[*game::g_script_error_level])) + { + *game::g_script_error_level -= 1; + return false; + } + + const auto result = execute_with_seh(function, entref); + *game::g_script_error_level -= 1; + return result; + } + + bool set_entity_field(const game::scr_entref_t& entref, const int offset) + { + *game::g_script_error_level += 1; + if (game::_setjmp(&game::g_script_error[*game::g_script_error_level])) + { + *game::g_script_error_level -= 1; + return false; + } + + game::Scr_SetObjectField(entref.classnum, entref.entnum, offset); + + *game::g_script_error_level -= 1; + return true; + } + + bool get_entity_field(const game::scr_entref_t& entref, const int offset, game::VariableValue* value) + { + *game::g_script_error_level += 1; + if (game::_setjmp(&game::g_script_error[*game::g_script_error_level])) + { + value->type = game::SCRIPT_NONE; + value->u.intValue = 0; + *game::g_script_error_level -= 1; + return false; + } + + game::GetEntityFieldValue(value, entref.classnum, entref.entnum, offset); + + *game::g_script_error_level -= 1; + return true; + } +} + +#pragma warning(pop) diff --git a/src/client/game/scripting/safe_execution.hpp b/src/client/game/scripting/safe_execution.hpp new file mode 100644 index 00000000..6eea59d2 --- /dev/null +++ b/src/client/game/scripting/safe_execution.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "functions.hpp" + +namespace scripting::safe_execution +{ + bool call(script_function function, const game::scr_entref_t& entref); + + bool set_entity_field(const game::scr_entref_t& entref, int offset); + bool get_entity_field(const game::scr_entref_t& entref, int offset, game::VariableValue* value); +} diff --git a/src/client/game/scripting/script_value.cpp b/src/client/game/scripting/script_value.cpp new file mode 100644 index 00000000..7d334f17 --- /dev/null +++ b/src/client/game/scripting/script_value.cpp @@ -0,0 +1,278 @@ +#include +#include "script_value.hpp" +#include "entity.hpp" + + +namespace scripting +{ + /*************************************************************** + * Constructors + **************************************************************/ + + script_value::script_value(const game::VariableValue& value) + : value_(value) + { + } + + script_value::script_value(const int value) + { + game::VariableValue variable{}; + variable.type = game::SCRIPT_INTEGER; + variable.u.intValue = value; + + this->value_ = variable; + } + + script_value::script_value(const unsigned int value) + { + game::VariableValue variable{}; + variable.type = game::SCRIPT_INTEGER; + variable.u.uintValue = value; + + this->value_ = variable; + } + + script_value::script_value(const bool value) + : script_value(static_cast(value)) + { + } + + script_value::script_value(const float value) + { + game::VariableValue variable{}; + variable.type = game::SCRIPT_FLOAT; + variable.u.floatValue = value; + + this->value_ = variable; + } + + script_value::script_value(const double value) + : script_value(static_cast(value)) + { + } + + script_value::script_value(const char* value) + { + game::VariableValue variable{}; + variable.type = game::SCRIPT_STRING; + variable.u.stringValue = game::SL_GetString(value, 0); + + const auto _ = gsl::finally([&variable]() + { + game::RemoveRefToValue(variable.type, variable.u); + }); + + this->value_ = variable; + } + + script_value::script_value(const std::string& value) + : script_value(value.data()) + { + } + + script_value::script_value(const entity& value) + { + game::VariableValue variable{}; + variable.type = game::SCRIPT_OBJECT; + variable.u.pointerValue = value.get_entity_id(); + + this->value_ = variable; + } + + script_value::script_value(const vector& value) + { + game::VariableValue variable{}; + variable.type = game::SCRIPT_VECTOR; + variable.u.vectorValue = game::Scr_AllocVector(value); + + const auto _ = gsl::finally([&variable]() + { + game::RemoveRefToValue(variable.type, variable.u); + }); + + this->value_ = variable; + } + + /*************************************************************** + * Integer + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().type == game::SCRIPT_INTEGER; + } + + template <> + bool script_value::is() const + { + return this->is(); + } + + template <> + bool script_value::is() const + { + return this->is(); + } + + template <> + int script_value::get() const + { + return this->get_raw().u.intValue; + } + + template <> + unsigned int script_value::get() const + { + return this->get_raw().u.uintValue; + } + + template <> + bool script_value::get() const + { + return this->get_raw().u.uintValue != 0; + } + + /*************************************************************** + * Float + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().type == game::SCRIPT_FLOAT; + } + + template <> + bool script_value::is() const + { + return this->is(); + } + + template <> + float script_value::get() const + { + return this->get_raw().u.floatValue; + } + + template <> + double script_value::get() const + { + return static_cast(this->get_raw().u.floatValue); + } + + /*************************************************************** + * String + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().type == game::SCRIPT_STRING; + } + + template <> + bool script_value::is() const + { + return this->is(); + } + + template <> + const char* script_value::get() const + { + return game::SL_ConvertToString(static_cast(this->get_raw().u.stringValue)); + } + + template <> + std::string script_value::get() const + { + return this->get(); + } + + /*************************************************************** + * Array + **************************************************************/ + + template <> + bool script_value::is>() const + { + if (this->get_raw().type != game::SCRIPT_OBJECT) + { + return false; + } + + const auto id = this->get_raw().u.uintValue; + const auto type = game::scr_VarGlob->objectVariableValue[id].w.type; + + return type == game::SCRIPT_ARRAY; + } + + /*************************************************************** + * Struct + **************************************************************/ + + template <> + bool script_value::is>() const + { + if (this->get_raw().type != game::SCRIPT_OBJECT) + { + return false; + } + + const auto id = this->get_raw().u.uintValue; + const auto type = game::scr_VarGlob->objectVariableValue[id].w.type; + + return type == game::SCRIPT_STRUCT; + } + + /*************************************************************** + * Function + **************************************************************/ + + template <> + bool script_value::is>() const + { + return this->get_raw().type == game::SCRIPT_FUNCTION; + } + + /*************************************************************** + * Entity + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().type == game::SCRIPT_OBJECT; + } + + template <> + entity script_value::get() const + { + return entity(this->get_raw().u.pointerValue); + } + + /*************************************************************** + * Vector + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().type == game::SCRIPT_VECTOR; + } + + template <> + vector script_value::get() const + { + return this->get_raw().u.vectorValue; + } + + /*************************************************************** + * + **************************************************************/ + + const game::VariableValue& script_value::get_raw() const + { + return this->value_.get(); + } +} diff --git a/src/client/game/scripting/script_value.hpp b/src/client/game/scripting/script_value.hpp new file mode 100644 index 00000000..df8a95b6 --- /dev/null +++ b/src/client/game/scripting/script_value.hpp @@ -0,0 +1,52 @@ +#pragma once +#include "game/game.hpp" +#include "variable_value.hpp" +#include "vector.hpp" + +namespace scripting +{ + class entity; + + class script_value + { + public: + script_value() = default; + script_value(const game::VariableValue& value); + + script_value(int value); + script_value(unsigned int value); + script_value(bool value); + + script_value(float value); + script_value(double value); + + script_value(const char* value); + script_value(const std::string& value); + + script_value(const entity& value); + + script_value(const vector& value); + + template + bool is() const; + + template + T as() const + { + if (!this->is()) + { + throw std::runtime_error("Invalid type"); + } + + return get(); + } + + const game::VariableValue& get_raw() const; + + private: + template + T get() const; + + variable_value value_{}; + }; +} diff --git a/src/client/game/scripting/stack_isolation.cpp b/src/client/game/scripting/stack_isolation.cpp new file mode 100644 index 00000000..646e2584 --- /dev/null +++ b/src/client/game/scripting/stack_isolation.cpp @@ -0,0 +1,27 @@ +#include +#include "stack_isolation.hpp" + +namespace scripting +{ + stack_isolation::stack_isolation() + { + this->in_param_count_ = game::scr_VmPub->inparamcount; + this->out_param_count_ = game::scr_VmPub->outparamcount; + this->top_ = game::scr_VmPub->top; + this->max_stack_ = game::scr_VmPub->maxstack; + + game::scr_VmPub->top = this->stack_; + game::scr_VmPub->maxstack = &this->stack_[ARRAYSIZE(this->stack_) - 1]; + game::scr_VmPub->inparamcount = 0; + game::scr_VmPub->outparamcount = 0; + } + + stack_isolation::~stack_isolation() + { + game::Scr_ClearOutParams(); + game::scr_VmPub->inparamcount = this->in_param_count_; + game::scr_VmPub->outparamcount = this->out_param_count_; + game::scr_VmPub->top = this->top_; + game::scr_VmPub->maxstack = this->max_stack_; + } +} diff --git a/src/client/game/scripting/stack_isolation.hpp b/src/client/game/scripting/stack_isolation.hpp new file mode 100644 index 00000000..8dffd4bc --- /dev/null +++ b/src/client/game/scripting/stack_isolation.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "game/game.hpp" + +namespace scripting +{ + class stack_isolation final + { + public: + stack_isolation(); + ~stack_isolation(); + + stack_isolation(stack_isolation&&) = delete; + stack_isolation(const stack_isolation&) = delete; + stack_isolation& operator=(stack_isolation&&) = delete; + stack_isolation& operator=(const stack_isolation&) = delete; + + private: + game::VariableValue stack_[512]{}; + + game::VariableValue* max_stack_; + game::VariableValue* top_; + unsigned int in_param_count_; + unsigned int out_param_count_; + }; +} diff --git a/src/client/game/scripting/variable_value.cpp b/src/client/game/scripting/variable_value.cpp new file mode 100644 index 00000000..69a20023 --- /dev/null +++ b/src/client/game/scripting/variable_value.cpp @@ -0,0 +1,68 @@ +#include +#include "variable_value.hpp" + +namespace scripting +{ + variable_value::variable_value(const game::VariableValue& value) + { + this->assign(value); + } + + variable_value::variable_value(const variable_value& other) noexcept + { + this->operator=(other); + } + + variable_value::variable_value(variable_value&& other) noexcept + { + this->operator=(std::move(other)); + } + + variable_value& variable_value::operator=(const variable_value& other) noexcept + { + if (this != &other) + { + this->release(); + this->assign(other.value_); + } + + return *this; + } + + variable_value& variable_value::operator=(variable_value&& other) noexcept + { + if (this != &other) + { + this->release(); + this->value_ = other.value_; + other.value_.type = game::SCRIPT_NONE; + } + + return *this; + } + + variable_value::~variable_value() + { + this->release(); + } + + const game::VariableValue& variable_value::get() const + { + return this->value_; + } + + void variable_value::assign(const game::VariableValue& value) + { + this->value_ = value; + game::AddRefToValue(this->value_.type, this->value_.u); + } + + void variable_value::release() + { + if (this->value_.type != game::SCRIPT_NONE) + { + game::RemoveRefToValue(this->value_.type, this->value_.u); + this->value_.type = game::SCRIPT_NONE; + } + } +} diff --git a/src/client/game/scripting/variable_value.hpp b/src/client/game/scripting/variable_value.hpp new file mode 100644 index 00000000..7a962612 --- /dev/null +++ b/src/client/game/scripting/variable_value.hpp @@ -0,0 +1,27 @@ +#pragma once +#include "game/game.hpp" + +namespace scripting +{ + class variable_value + { + public: + variable_value() = default; + variable_value(const game::VariableValue& value); + variable_value(const variable_value& other) noexcept; + variable_value(variable_value&& other) noexcept; + + variable_value& operator=(const variable_value& other) noexcept; + variable_value& operator=(variable_value&& other) noexcept; + + ~variable_value(); + + const game::VariableValue& get() const; + + private: + void assign(const game::VariableValue& value); + void release(); + + game::VariableValue value_{{0}, game::SCRIPT_NONE}; + }; +} diff --git a/src/client/game/scripting/vector.cpp b/src/client/game/scripting/vector.cpp new file mode 100644 index 00000000..e3b66dcd --- /dev/null +++ b/src/client/game/scripting/vector.cpp @@ -0,0 +1,85 @@ +#include +#include "vector.hpp" + +namespace scripting +{ + vector::vector(const float* value) + { + for (auto i = 0; i < 3; ++i) + { + this->value_[i] = value[i]; + } + } + + vector::vector(const game::vec3_t& value) + : vector(&value[0]) + { + } + + vector::vector(const float x, const float y, const float z) + { + this->value_[0] = x; + this->value_[1] = y; + this->value_[2] = z; + } + + vector::operator game::vec3_t&() + { + return this->value_; + } + + vector::operator const game::vec3_t&() const + { + return this->value_; + } + + game::vec_t& vector::operator[](const size_t i) + { + if (i >= 3) + { + throw std::runtime_error("Out of bounds."); + } + + return this->value_[i]; + } + + const game::vec_t& vector::operator[](const size_t i) const + { + if (i >= 3) + { + throw std::runtime_error("Out of bounds."); + } + + return this->value_[i]; + } + + float vector::get_x() const + { + return this->operator[](0); + } + + float vector::get_y() const + { + return this->operator[](1); + } + + float vector::get_z() const + { + return this->operator[](2); + } + + void vector::set_x(const float value) + { + this->operator[](0) = value; + } + + void vector::set_y(const float value) + { + this->operator[](1) = value; + } + + void vector::set_z(const float value) + { + this->operator[](2) = value; + } +} diff --git a/src/client/game/scripting/vector.hpp b/src/client/game/scripting/vector.hpp new file mode 100644 index 00000000..70b146d6 --- /dev/null +++ b/src/client/game/scripting/vector.hpp @@ -0,0 +1,31 @@ +#pragma once +#include "game/game.hpp" + +namespace scripting +{ + class vector final + { + public: + vector() = default; + vector(const float* value); + vector(const game::vec3_t& value); + vector(float x, float y, float z); + + operator game::vec3_t&(); + operator const game::vec3_t&() const; + + game::vec_t& operator[](size_t i); + const game::vec_t& operator[](size_t i) const; + + float get_x() const; + float get_y() const; + float get_z() const; + + void set_x(float value); + void set_y(float value); + void set_z(float value); + + private: + game::vec3_t value_{0}; + }; +} From 13b5ac1f7dc0ca908c4d204469c35af44d7ccf05 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Tue, 1 Mar 2022 22:24:55 +0200 Subject: [PATCH 003/346] symbols --- src/client/game/symbols.hpp | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index d82ee023..85ca5543 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -8,10 +8,17 @@ namespace game * Functions **************************************************************/ + WEAK symbol AddRefToValue{0x140315830, 0x14043C580}; // H1MP + WEAK symbol RemoveRefToValue{0x140317340, 0x14043E090}; // H1MP + WEAK symbol AddRefToObject{0, 0x14043C570 }; // H1MP + WEAK symbol RemoveRefToObject{0, 0x14043DF80 }; // H1MP + WEAK symbol AllocThread{0, 0x14043C8E0 }; // H1MP + WEAK symbol Cbuf_AddText{0x140342EB0, 0x1404033B0}; WEAK symbol Cbuf_ExecuteBufferInternal{0, 0x1404034C0}; WEAK symbol Conbuf_AppendText{0x1403E3300, 0x140513FF0}; + WEAK symbol ConcatArgs{0x14021A7E0, 0x140335D70}; // h1mp WEAK symbol Cmd_ExecuteSingleCommand{0x140343980, 0x140403F60}; WEAK symbol Cmd_AddCommandInternal{0x1403433E0, 0x140403950}; WEAK symbol Cmd_RemoveCommand{0x140343FF0, 0x1404045D0}; @@ -20,6 +27,8 @@ namespace game WEAK symbol AimAssist_AddToTargetList{0, 0x14009D0F0}; + WEAK symbol BG_GetWeaponNameComplete{ 0x0, 0x140165580 }; + WEAK symbol Com_Frame_Try_Block_Function{0, 0x1400D8310}; WEAK symbol Com_GetCurrentCoDPlayMode{0, 0x1405039A0}; WEAK symbol Com_SetSlowMotion{0, 0x1400DB790}; @@ -53,6 +62,13 @@ namespace game WEAK symbol FS_Startup{0x1403B85D0, 0x1404EDD30}; WEAK symbol FS_AddLocalizedGameDirectory{0x1403B6030, 0x1404EBE20}; + WEAK symbol GetVariable{ 0x0, 0x1403F3730 }; + + WEAK symbol GScr_LoadConsts{0x1402D13E0, 0x140393810}; + WEAK symbol FindVariable{0x1403165D0, 0x14043D430}; // H1MP + WEAK symbol FindEntityId{0x1403166D0, 0x14043D330}; // H1MP + WEAK symbol RemoveVariableValue{0, 0x14043E130}; // H1MP + WEAK symbol GetEntityFieldValue{0x14031AAD0, 0x140441780}; // H1MP WEAK symbol generateHashValue{0x1400FE8A0, 0x1401B1010}; WEAK symbol G_Glass_Update{0, 0x14033A640}; @@ -88,9 +104,17 @@ namespace game #define R_AddCmdDrawTextWithCursor(TXT, MC, F, UNK, X, Y, XS, YS, R, C, S, CP, CC) \ H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S, CP, CC, game::R_DrawSomething(S)) + WEAK symbol VM_Execute{0x0, 0x140444350}; + + WEAK symbol Scr_NotifyId{ + 0x14031CB80, 0x1404437E0 + }; + WEAK symbol Scr_AllocVector{0x140317D10, 0x14043E7D0}; // H1MP WEAK symbol Scr_GetFloat{0x140374D20, 0x140442D10}; WEAK symbol Scr_GetString{0, 0x14032F0A0}; WEAK symbol Scr_GetNumParam{0x140374F30, 0x140442E70}; + WEAK symbol Scr_ClearOutParams{0x14031B7C0, 0x140442510}; // H1MP + WEAK symbol Scr_GetEntityIdRef{ 0x14031A0D0, 0x1403F68A0 }; WEAK symbol ScrPlace_GetViewPlacement{0x1401981F0, 0x140288550}; @@ -101,8 +125,12 @@ namespace game WEAK symbol Menu_IsMenuOpenAndVisible{0, 0x1404C7320}; WEAK symbol SL_FindString{0x140314AF0, 0x14043B470}; + WEAK symbol SL_GetString{0x140314D90, 0x14043B840}; // H1MP + WEAK symbol SL_ConvertToString{0x14036D420, 0x14043B170}; + WEAK symbol Scr_SetObjectField{ 0x14026B620, 0x140385330 }; // H1MP WEAK symbol SV_DirectConnect{0, 0x140480860}; + WEAK symbol SV_Cmd_ArgvBuffer{ 0x1402EEFD0, 0x1403B05C0 }; WEAK symbol SV_Cmd_TokenizeString{0x1402EF050, 0x140404D20}; WEAK symbol SV_Cmd_EndTokenizedString{0x140344700, 0x140404CE0}; @@ -140,17 +168,30 @@ namespace game WEAK symbol UI_SafeTranslateString{0x140350430, 0x14041C580}; + WEAK symbol longjmp{ 0x140648FD4, 0x140779F64 }; + WEAK symbol _setjmp{ 0x1406BFD30, 0x1407F5F90 }; + /*************************************************************** * Variables **************************************************************/ WEAK symbol sv_cmd_args{0, 0x14946BA20}; + WEAK symbol g_script_error_level{0x14A1917A8, 0x14A33C824}; // H1MP + WEAK symbol g_script_error{0x14A1917B0, 0x14A33C940}; // H1MP + + WEAK symbol levelEntityId{0x149AF55B0, 0x149CA0730}; // H1MP + WEAK symbol command_whitelist{0x141079A60, 0x14120C360}; WEAK symbol cmd_functions{0x14AD99AB8, 0x14946BAC8}; WEAK symbol cmd_args{0x14AD99960, 0x14946B970}; WEAK symbol g_poolSize{0, 0x140FEADF0}; + WEAK symbol g_classMap{ 0x14080A840, 0x1412106B0 }; + + WEAK symbol scr_VarGlob{0x149B1D680, 0x149CC8800}; // H1MP + WEAK symbol scr_VmPub{0x14A1938C0, 0x14A33EA40}; // H1MP + WEAK symbol scr_function_stack{0x14A19DE40, 0x14A348FC0}; // H1MP WEAK symbol gfxDrawMethod{0, 0x14FD21180}; From f8980041f1ca6e119a99ffa92b72f1514318f502 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Tue, 1 Mar 2022 22:27:23 +0200 Subject: [PATCH 004/346] spacing 1 --- src/client/game/symbols.hpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 85ca5543..9690f48b 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -27,7 +27,7 @@ namespace game WEAK symbol AimAssist_AddToTargetList{0, 0x14009D0F0}; - WEAK symbol BG_GetWeaponNameComplete{ 0x0, 0x140165580 }; + WEAK symbol BG_GetWeaponNameComplete{0x0, 0x140165580}; // H1MP WEAK symbol Com_Frame_Try_Block_Function{0, 0x1400D8310}; WEAK symbol Com_GetCurrentCoDPlayMode{0, 0x1405039A0}; @@ -62,7 +62,7 @@ namespace game WEAK symbol FS_Startup{0x1403B85D0, 0x1404EDD30}; WEAK symbol FS_AddLocalizedGameDirectory{0x1403B6030, 0x1404EBE20}; - WEAK symbol GetVariable{ 0x0, 0x1403F3730 }; + WEAK symbol GetVariable{0x0, 0x1403F3730}; // H1MP WEAK symbol GScr_LoadConsts{0x1402D13E0, 0x140393810}; WEAK symbol FindVariable{0x1403165D0, 0x14043D430}; // H1MP @@ -106,15 +106,13 @@ namespace game WEAK symbol VM_Execute{0x0, 0x140444350}; - WEAK symbol Scr_NotifyId{ - 0x14031CB80, 0x1404437E0 - }; + WEAK symbol Scr_NotifyId{0x14031CB80, 0x1404437E0}; WEAK symbol Scr_AllocVector{0x140317D10, 0x14043E7D0}; // H1MP WEAK symbol Scr_GetFloat{0x140374D20, 0x140442D10}; WEAK symbol Scr_GetString{0, 0x14032F0A0}; WEAK symbol Scr_GetNumParam{0x140374F30, 0x140442E70}; WEAK symbol Scr_ClearOutParams{0x14031B7C0, 0x140442510}; // H1MP - WEAK symbol Scr_GetEntityIdRef{ 0x14031A0D0, 0x1403F68A0 }; + WEAK symbol Scr_GetEntityIdRef{0x14031A0D0, 0x1403F68A0}; // H1MP WEAK symbol ScrPlace_GetViewPlacement{0x1401981F0, 0x140288550}; @@ -130,7 +128,7 @@ namespace game WEAK symbol Scr_SetObjectField{ 0x14026B620, 0x140385330 }; // H1MP WEAK symbol SV_DirectConnect{0, 0x140480860}; - WEAK symbol SV_Cmd_ArgvBuffer{ 0x1402EEFD0, 0x1403B05C0 }; + WEAK symbol SV_Cmd_ArgvBuffer{0x1402EEFD0, 0x1403B05C0}; // H1MP WEAK symbol SV_Cmd_TokenizeString{0x1402EF050, 0x140404D20}; WEAK symbol SV_Cmd_EndTokenizedString{0x140344700, 0x140404CE0}; @@ -168,8 +166,8 @@ namespace game WEAK symbol UI_SafeTranslateString{0x140350430, 0x14041C580}; - WEAK symbol longjmp{ 0x140648FD4, 0x140779F64 }; - WEAK symbol _setjmp{ 0x1406BFD30, 0x1407F5F90 }; + WEAK symbol longjmp{0x140648FD4, 0x140779F64}; + WEAK symbol _setjmp{0x1406BFD30, 0x1407F5F90}; /*************************************************************** * Variables @@ -187,7 +185,7 @@ namespace game WEAK symbol cmd_args{0x14AD99960, 0x14946B970}; WEAK symbol g_poolSize{0, 0x140FEADF0}; - WEAK symbol g_classMap{ 0x14080A840, 0x1412106B0 }; + WEAK symbol g_classMap{0x14080A840, 0x1412106B0}; // H1MP WEAK symbol scr_VarGlob{0x149B1D680, 0x149CC8800}; // H1MP WEAK symbol scr_VmPub{0x14A1938C0, 0x14A33EA40}; // H1MP From 05ff6c3f09ff91ceabbb187876eabc689bb2236c Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Wed, 2 Mar 2022 00:08:43 +0200 Subject: [PATCH 005/346] scroptong workong? --- src/client/component/logfile.cpp | 315 +++++++++++++++++++++++++++++++ src/client/component/logfile.hpp | 13 ++ 2 files changed, 328 insertions(+) create mode 100644 src/client/component/logfile.cpp create mode 100644 src/client/component/logfile.hpp diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp new file mode 100644 index 00000000..7a3a0870 --- /dev/null +++ b/src/client/component/logfile.cpp @@ -0,0 +1,315 @@ +#include +#include "loader/component_loader.hpp" +#include "scheduler.hpp" + +#include "game/scripting/entity.hpp" +#include "game/scripting/execution.hpp" +#include "game/scripting/lua/value_conversion.hpp" +#include "game/scripting/lua/error.hpp" + +#include + +#include "logfile.hpp" + +namespace logfile +{ + std::unordered_map vm_execute_hooks; + + namespace + { + utils::hook::detour scr_player_killed_hook; + utils::hook::detour scr_player_damage_hook; + + std::vector player_killed_callbacks; + std::vector player_damage_callbacks; + + utils::hook::detour vm_execute_hook; + char empty_function[2] = { 0x32, 0x34 }; // CHECK_CLEAR_PARAMS, END + bool hook_enabled = true; + + sol::lua_value convert_entity(lua_State* state, const game::mp::gentity_s* ent) + { + if (!ent) + { + return {}; + } + + const auto player = scripting::call("getEntByNum", { ent->s.entityNum }); + + return scripting::lua::convert(state, player); + } + + std::string get_weapon_name(unsigned int weapon, bool isAlternate) + { + char output[1024] = { 0 }; + game::BG_GetWeaponNameComplete(weapon, isAlternate, output, 1024); + + return output; + } + + sol::lua_value convert_vector(lua_State* state, const float* vec) + { + if (!vec) + { + return {}; + } + + const auto _vec = scripting::vector(vec); + + return scripting::lua::convert(state, _vec); + } + + std::string convert_mod(const int meansOfDeath) + { + const auto value = reinterpret_cast(0x140FEC3F0)[meansOfDeath]; + const auto string = game::SL_ConvertToString(*value); + + return string; + } + + void scr_player_killed_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, game::mp::gentity_s* attacker, int damage, + const int meansOfDeath, const unsigned int weapon, const bool isAlternate, const float* vDir, const unsigned int hitLoc, int psTimeOffset, int deathAnimDuration) + { + { + const std::string _hitLoc = reinterpret_cast(0x140FEC4D0)[hitLoc]; // or 12162B0 + const auto _mod = convert_mod(meansOfDeath); + + const auto _weapon = get_weapon_name(weapon, isAlternate); + + for (const auto& callback : player_killed_callbacks) + { + const auto state = callback.lua_state(); + + const auto _self = convert_entity(state, self); + const auto _inflictor = convert_entity(state, inflictor); + const auto _attacker = convert_entity(state, attacker); + + const auto _vDir = convert_vector(state, vDir); + + const auto result = callback(_self, _inflictor, _attacker, damage, _mod, _weapon, _vDir, _hitLoc, psTimeOffset, deathAnimDuration); + + scripting::lua::handle_error(result); + + if (result.valid() && result.get_type() == sol::type::number) + { + damage = result.get(); + } + } + + if (damage == 0) + { + return; + } + } + + scr_player_killed_hook.invoke(self, inflictor, attacker, damage, meansOfDeath, weapon, isAlternate, vDir, hitLoc, psTimeOffset, deathAnimDuration); + } + + void scr_player_damage_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, game::mp::gentity_s* attacker, int damage, int dflags, + const int meansOfDeath, const unsigned int weapon, const bool isAlternate, const float* vPoint, const float* vDir, const unsigned int hitLoc, const int timeOffset) + { + { + const std::string _hitLoc = reinterpret_cast(0x140FEC4D0)[hitLoc]; // or 12162B0 + const auto _mod = convert_mod(meansOfDeath); + + const auto _weapon = get_weapon_name(weapon, isAlternate); + + for (const auto& callback : player_damage_callbacks) + { + const auto state = callback.lua_state(); + + const auto _self = convert_entity(state, self); + const auto _inflictor = convert_entity(state, inflictor); + const auto _attacker = convert_entity(state, attacker); + + const auto _vPoint = convert_vector(state, vPoint); + const auto _vDir = convert_vector(state, vDir); + + const auto result = callback(_self, _inflictor, _attacker, damage, dflags, _mod, _weapon, _vPoint, _vDir, _hitLoc); + + scripting::lua::handle_error(result); + + if (result.valid() && result.get_type() == sol::type::number) + { + damage = result.get(); + } + } + + if (damage == 0) + { + return; + } + } + + scr_player_damage_hook.invoke(self, inflictor, attacker, damage, dflags, meansOfDeath, weapon, isAlternate, vPoint, vDir, hitLoc, timeOffset); + } + + void client_command_stub(const int clientNum) + { + auto self = &game::mp::g_entities[clientNum]; + char cmd[1024]{}; + + game::SV_Cmd_ArgvBuffer(0, cmd, 1024); + + if (cmd == "say"s || cmd == "say_team"s) + { + auto hidden = false; + std::string message(game::ConcatArgs(1)); + + hidden = message[1] == '/'; + message.erase(0, hidden ? 2 : 1); + + scheduler::once([cmd, message, self]() + { + const scripting::entity level{ *game::levelEntityId }; + const auto player = scripting::call("getEntByNum", { self->s.entityNum }).as(); + + scripting::notify(level, cmd, { player, message }); + scripting::notify(player, cmd, { message }); + }, scheduler::pipeline::server); + + if (hidden) + { + return; + } + } + + // ClientCommand + return reinterpret_cast(0x140336000)(clientNum); + } + + void g_shutdown_game_stub(const int freeScripts) + { + { + const scripting::entity level{ *game::levelEntityId }; + scripting::notify(level, "shutdownGame_called", { 1 }); + } + + // G_ShutdownGame + return reinterpret_cast(0x140345A60)(freeScripts); + } + + unsigned int local_id_to_entity(unsigned int local_id) + { + const auto variable = game::scr_VarGlob->objectVariableValue[local_id]; + return variable.u.f.next; + } + + bool execute_vm_hook(const char* pos) + { + if (vm_execute_hooks.find(pos) == vm_execute_hooks.end()) + { + hook_enabled = true; + return false; + } + + if (!hook_enabled && pos > reinterpret_cast(vm_execute_hooks.size())) + { + hook_enabled = true; + return false; + } + + const auto hook = vm_execute_hooks[pos]; + const auto state = hook.lua_state(); + + const scripting::entity self = local_id_to_entity(game::scr_VmPub->function_frame->fs.localId); + + std::vector args; + + const auto top = game::scr_function_stack->top; + + for (auto* value = top; value->type != game::SCRIPT_END; --value) + { + args.push_back(scripting::lua::convert(state, *value)); + } + + const auto result = hook(self, sol::as_args(args)); + scripting::lua::handle_error(result); + + return true; + } + + void vm_execute_stub(utils::hook::assembler& a) + { + const auto replace = a.newLabel(); + const auto end = a.newLabel(); + + a.pushad64(); + + a.mov(rcx, r14); + a.call_aligned(execute_vm_hook); + + a.cmp(al, 0); + a.jne(replace); + + a.popad64(); + a.jmp(end); + + a.bind(end); + + a.movzx(r15d, byte_ptr(r14)); + a.inc(r14); + a.lea(eax, dword_ptr(r15, -0x17)); + a.mov(dword_ptr(rbp, 0x68), r15d); + + a.jmp(0x140444653); + + a.bind(replace); + + a.popad64(); + a.mov(r14, reinterpret_cast(empty_function)); + a.jmp(end); + } + } + + void add_player_damage_callback(const sol::protected_function& callback) + { + player_damage_callbacks.push_back(callback); + } + + void add_player_killed_callback(const sol::protected_function& callback) + { + player_killed_callbacks.push_back(callback); + } + + void clear_callbacks() + { + player_damage_callbacks.clear(); + player_killed_callbacks.clear(); + vm_execute_hooks.clear(); + } + + void enable_vm_execute_hook() + { + hook_enabled = true; + } + + void disable_vm_execute_hook() + { + hook_enabled = false; + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) + { + return; + } + + utils::hook::call(0x14048191D, client_command_stub); + + scr_player_damage_hook.create(0x14037DC50, scr_player_damage_stub); + scr_player_killed_hook.create(0x14037DF30, scr_player_killed_stub); + + utils::hook::call(0x140484EC0, g_shutdown_game_stub); + utils::hook::call(0x1404853C1, g_shutdown_game_stub); + + utils::hook::jump(0x140444645, utils::hook::assemble(vm_execute_stub), true); + } + }; +} + +REGISTER_COMPONENT(logfile::component) \ No newline at end of file diff --git a/src/client/component/logfile.hpp b/src/client/component/logfile.hpp new file mode 100644 index 00000000..77f699c8 --- /dev/null +++ b/src/client/component/logfile.hpp @@ -0,0 +1,13 @@ +#pragma once + +namespace logfile +{ + extern std::unordered_map vm_execute_hooks; + + void add_player_damage_callback(const sol::protected_function& callback); + void add_player_killed_callback(const sol::protected_function& callback); + void clear_callbacks(); + + void enable_vm_execute_hook(); + void disable_vm_execute_hook(); +} \ No newline at end of file From 5793866b7f9b523b49c685658fa86d1f99195bbc Mon Sep 17 00:00:00 2001 From: m Date: Wed, 2 Mar 2022 05:26:55 -0600 Subject: [PATCH 006/346] add ui scripting --- src/client/component/ui_scripting.cpp | 176 +++++++++++ src/client/component/ui_scripting.hpp | 12 + src/client/game/symbols.hpp | 15 + src/client/game/ui_scripting/execution.cpp | 161 ++++++++++ src/client/game/ui_scripting/execution.hpp | 18 ++ src/client/game/ui_scripting/lua/context.cpp | 205 +++++++++++++ src/client/game/ui_scripting/lua/context.hpp | 36 +++ src/client/game/ui_scripting/lua/engine.cpp | 61 ++++ src/client/game/ui_scripting/lua/engine.hpp | 8 + src/client/game/ui_scripting/lua/error.cpp | 18 ++ src/client/game/ui_scripting/lua/error.hpp | 8 + .../game/ui_scripting/lua/scheduler.cpp | 122 ++++++++ .../game/ui_scripting/lua/scheduler.hpp | 50 ++++ .../ui_scripting/lua/value_conversion.cpp | 144 +++++++++ .../ui_scripting/lua/value_conversion.hpp | 9 + src/client/game/ui_scripting/script_value.cpp | 274 +++++++++++++++++ src/client/game/ui_scripting/script_value.hpp | 56 ++++ src/client/game/ui_scripting/types.cpp | 276 ++++++++++++++++++ src/client/game/ui_scripting/types.hpp | 89 ++++++ 19 files changed, 1738 insertions(+) create mode 100644 src/client/component/ui_scripting.cpp create mode 100644 src/client/component/ui_scripting.hpp create mode 100644 src/client/game/ui_scripting/execution.cpp create mode 100644 src/client/game/ui_scripting/execution.hpp create mode 100644 src/client/game/ui_scripting/lua/context.cpp create mode 100644 src/client/game/ui_scripting/lua/context.hpp create mode 100644 src/client/game/ui_scripting/lua/engine.cpp create mode 100644 src/client/game/ui_scripting/lua/engine.hpp create mode 100644 src/client/game/ui_scripting/lua/error.cpp create mode 100644 src/client/game/ui_scripting/lua/error.hpp create mode 100644 src/client/game/ui_scripting/lua/scheduler.cpp create mode 100644 src/client/game/ui_scripting/lua/scheduler.hpp create mode 100644 src/client/game/ui_scripting/lua/value_conversion.cpp create mode 100644 src/client/game/ui_scripting/lua/value_conversion.hpp create mode 100644 src/client/game/ui_scripting/script_value.cpp create mode 100644 src/client/game/ui_scripting/script_value.hpp create mode 100644 src/client/game/ui_scripting/types.cpp create mode 100644 src/client/game/ui_scripting/types.hpp diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp new file mode 100644 index 00000000..feb13ffb --- /dev/null +++ b/src/client/component/ui_scripting.cpp @@ -0,0 +1,176 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "scheduler.hpp" +#include "command.hpp" + +#include "ui_scripting.hpp" + +#include "game/ui_scripting/lua/engine.hpp" +#include "game/ui_scripting/execution.hpp" +#include "game/ui_scripting/lua/error.hpp" + +#include +#include + +namespace ui_scripting +{ + namespace + { + std::unordered_map converted_functions; + + utils::hook::detour hksi_lual_error_hook; + utils::hook::detour hksi_lual_error_hook2; + utils::hook::detour hks_start_hook; + utils::hook::detour hks_shutdown_hook; + utils::hook::detour hks_allocator_hook; + utils::hook::detour hks_frame_hook; + + bool error_hook_enabled = false; + + void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...) + { + char va_buffer[2048] = {0}; + + va_list ap; + va_start(ap, fmt); + vsprintf_s(va_buffer, fmt, ap); + va_end(ap); + + const auto formatted = std::string(va_buffer); + + if (!error_hook_enabled) + { + return hksi_lual_error_hook.invoke(s, formatted.data()); + } + else + { + throw std::runtime_error(formatted); + } + } + + void* hks_start_stub(char a1) + { + const auto _1 = gsl::finally([]() + { + ui_scripting::lua::engine::start(); + }); + + return hks_start_hook.invoke(a1); + } + + void hks_shutdown_stub() + { + ui_scripting::lua::engine::stop(); + hks_shutdown_hook.invoke(); + } + + void* hks_allocator_stub(void* userData, void* oldMemory, unsigned __int64 oldSize, unsigned __int64 newSize) + { + const auto closure = reinterpret_cast(oldMemory); + if (converted_functions.find(closure) != converted_functions.end()) + { + converted_functions.erase(closure); + } + + return hks_allocator_hook.invoke(userData, oldMemory, oldSize, newSize); + } + + void hks_frame_stub() + { + const auto state = *game::hks::lua_state; + if (state) + { + ui_scripting::lua::engine::run_frame(); + } + } + } + + int main_function_handler(game::hks::lua_State* state) + { + const auto value = state->m_apistack.base[-1]; + if (value.t != game::hks::TCFUNCTION) + { + return 0; + } + + const auto closure = reinterpret_cast(value.v.cClosure); + if (converted_functions.find(closure) == converted_functions.end()) + { + return 0; + } + + const auto function = converted_functions[closure]; + const auto count = static_cast(state->m_apistack.top - state->m_apistack.base); + const auto arguments = get_return_values(count); + const auto s = function.lua_state(); + + std::vector converted_args; + + for (const auto& argument : arguments) + { + converted_args.push_back(lua::convert(s, argument)); + } + + const auto results = function(sol::as_args(converted_args)); + lua::handle_error(results); + + for (const auto& result : results) + { + push_value(lua::convert({s, result})); + } + + return results.return_count(); + } + + void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function) + { + converted_functions[closure] = function; + } + + void clear_converted_functions() + { + converted_functions.clear(); + } + + void enable_error_hook() + { + error_hook_enabled = true; + } + + void disable_error_hook() + { + error_hook_enabled = false; + } + + class component final : public component_interface + { + public: + + void post_unpack() override + { + if (!game::environment::is_mp()) + { + return; + } + + hks_start_hook.create(0x140176A40, hks_start_stub); + hks_shutdown_hook.create(0x14016CA80, hks_shutdown_stub); + hksi_lual_error_hook.create(0x14011D4CC, hksi_lual_error_stub); + hksi_lual_error_hook2.create(0x1401366B0, hksi_lual_error_stub); + hks_allocator_hook.create(0x14012BB90, hks_allocator_stub); + hks_frame_hook.create(0x1401755B0, hks_frame_stub); + + command::add("lui_restart", []() + { + utils::hook::invoke(0x14016CA95); + utils::hook::invoke(0x1401780D0); + }); + } + }; +} + +REGISTER_COMPONENT(ui_scripting::component) \ No newline at end of file diff --git a/src/client/component/ui_scripting.hpp b/src/client/component/ui_scripting.hpp new file mode 100644 index 00000000..2a48f6ec --- /dev/null +++ b/src/client/component/ui_scripting.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "game/ui_scripting/lua/value_conversion.hpp" + +namespace ui_scripting +{ + int main_function_handler(game::hks::lua_State* state); + void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function); + void clear_converted_functions(); + + void enable_error_hook(); + void disable_error_hook(); +} \ No newline at end of file diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 62995ea4..5b832bb1 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -183,4 +183,19 @@ namespace game { WEAK symbol g_entities{0x14550DD90, 0}; } + + namespace hks + { + WEAK symbol lua_state{0, 0x1426D3D08}; + WEAK symbol hksi_lua_pushlstring{0, 0x1400624F0}; + WEAK symbol hks_obj_getfield{0, 0x14012C600}; + WEAK symbol hks_obj_settable{0, 0x14012D820}; + WEAK symbol hks_obj_gettable{0, 0x14012CAE0}; + WEAK symbol vm_call_internal{0, 0x140159EB0}; + WEAK symbol Hashtable_Create{0, 0x14011B320}; + WEAK symbol cclosure_Create{0, 0x14011B540}; + WEAK symbol hksi_luaL_ref{0, 0x140136D30}; + WEAK symbol hksi_luaL_unref{0, 0x14012F610}; + } } diff --git a/src/client/game/ui_scripting/execution.cpp b/src/client/game/ui_scripting/execution.cpp new file mode 100644 index 00000000..fff6b88e --- /dev/null +++ b/src/client/game/ui_scripting/execution.cpp @@ -0,0 +1,161 @@ +#include +#include "execution.hpp" +#include "component/ui_scripting.hpp" + +#include + +namespace ui_scripting +{ + void push_value(const script_value& value) + { + const auto state = *game::hks::lua_state; + const auto value_ = value.get_raw(); + *state->m_apistack.top = value_; + state->m_apistack.top++; + } + + script_value get_return_value(int offset) + { + const auto state = *game::hks::lua_state; + return state->m_apistack.top[-1 - offset]; + } + + arguments get_return_values(int count) + { + arguments values; + + for (auto i = count - 1; i >= 0; i--) + { + values.push_back(get_return_value(i)); + } + + if (values.size() == 0) + { + values.push_back({}); + } + + return values; + } + + arguments call_script_function(const function& function, const arguments& arguments) + { + const auto state = *game::hks::lua_state; + state->m_apistack.top = state->m_apistack.base; + + push_value(function); + for (auto i = arguments.begin(); i != arguments.end(); ++i) + { + push_value(*i); + } + + const auto _1 = gsl::finally(&disable_error_hook); + enable_error_hook(); + + try + { + game::hks::vm_call_internal(state, static_cast(arguments.size()), -1, 0); + const auto count = static_cast(state->m_apistack.top - state->m_apistack.base); + return get_return_values(count); + } + catch (const std::exception& e) + { + throw std::runtime_error(std::string("Error executing script function: ") + e.what()); + } + } + + script_value get_field(const userdata& self, const script_value& key) + { + const auto state = *game::hks::lua_state; + state->m_apistack.top = state->m_apistack.base; + + push_value(key); + + const auto _1 = gsl::finally(&disable_error_hook); + enable_error_hook(); + + game::hks::HksObject value{}; + game::hks::HksObject userdata{}; + userdata.t = game::hks::TUSERDATA; + userdata.v.ptr = self.ptr; + + try + { + game::hks::hks_obj_gettable(&value, state, &userdata, &state->m_apistack.top[-1]); + return value; + } + catch (const std::exception& e) + { + throw std::runtime_error(std::string("Error getting userdata field: ") + e.what()); + } + } + + script_value get_field(const table& self, const script_value& key) + { + const auto state = *game::hks::lua_state; + state->m_apistack.top = state->m_apistack.base; + + push_value(key); + + const auto _1 = gsl::finally(&disable_error_hook); + enable_error_hook(); + + game::hks::HksObject value{}; + game::hks::HksObject userdata{}; + userdata.t = game::hks::TTABLE; + userdata.v.ptr = self.ptr; + + try + { + game::hks::hks_obj_gettable(&value, state, &userdata, &state->m_apistack.top[-1]); + return value; + } + catch (const std::exception& e) + { + throw std::runtime_error(std::string("Error getting table field: ") + e.what()); + } + } + + void set_field(const userdata& self, const script_value& key, const script_value& value) + { + const auto state = *game::hks::lua_state; + state->m_apistack.top = state->m_apistack.base; + + const auto _1 = gsl::finally(&disable_error_hook); + enable_error_hook(); + + game::hks::HksObject userdata{}; + userdata.t = game::hks::TUSERDATA; + userdata.v.ptr = self.ptr; + + try + { + game::hks::hks_obj_settable(state, &userdata, &key.get_raw(), &value.get_raw()); + } + catch (const std::exception& e) + { + throw std::runtime_error(std::string("Error setting userdata field: ") + e.what()); + } + } + + void set_field(const table& self, const script_value& key, const script_value& value) + { + const auto state = *game::hks::lua_state; + state->m_apistack.top = state->m_apistack.base; + + const auto _1 = gsl::finally(&disable_error_hook); + enable_error_hook(); + + game::hks::HksObject userdata{}; + userdata.t = game::hks::TTABLE; + userdata.v.ptr = self.ptr; + + try + { + game::hks::hks_obj_settable(state, &userdata, &key.get_raw(), &value.get_raw()); + } + catch (const std::exception& e) + { + throw std::runtime_error(std::string("Error setting table field: ") + e.what()); + } + } +} diff --git a/src/client/game/ui_scripting/execution.hpp b/src/client/game/ui_scripting/execution.hpp new file mode 100644 index 00000000..24f4dd72 --- /dev/null +++ b/src/client/game/ui_scripting/execution.hpp @@ -0,0 +1,18 @@ +#pragma once +#include "game/game.hpp" +#include "types.hpp" +#include "script_value.hpp" + +namespace ui_scripting +{ + void push_value(const script_value& value); + script_value get_return_value(int offset); + arguments get_return_values(int count); + + arguments call_script_function(const function& function, const arguments& arguments); + + script_value get_field(const userdata& self, const script_value& key); + script_value get_field(const table& self, const script_value& key); + void set_field(const userdata& self, const script_value& key, const script_value& value); + void set_field(const table& self, const script_value& key, const script_value& value); +} diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp new file mode 100644 index 00000000..d6d05f1d --- /dev/null +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -0,0 +1,205 @@ +#include +#include "context.hpp" +#include "error.hpp" +#include "value_conversion.hpp" +#include "../script_value.hpp" +#include "../execution.hpp" + +#include "../../../component/ui_scripting.hpp" +#include "../../../component/command.hpp" + +#include "component/game_console.hpp" +#include "component/scheduler.hpp" + +#include +#include +#include + +namespace ui_scripting::lua +{ + namespace + { + void setup_types(sol::state& state, scheduler& scheduler) + { + struct game + { + }; + auto game_type = state.new_usertype("game_"); + state["game"] = game(); + + game_type["ontimeout"] = [&scheduler](const game&, const sol::protected_function& callback, + const long long milliseconds) + { + return scheduler.add(callback, milliseconds, true); + }; + + game_type["oninterval"] = [&scheduler](const game&, const sol::protected_function& callback, + const long long milliseconds) + { + return scheduler.add(callback, milliseconds, false); + }; + + auto userdata_type = state.new_usertype("userdata_"); + + userdata_type["new"] = sol::property( + [](const userdata& userdata, const sol::this_state s) + { + return convert(s, userdata.get("new")); + }, + [](const userdata& userdata, const sol::this_state s, const sol::lua_value& value) + { + userdata.set("new", convert({s, value})); + } + ); + + + userdata_type["get"] = [](const userdata& userdata, const sol::this_state s, + const sol::lua_value& key) + { + return convert(s, userdata.get(convert({s, key}))); + }; + + userdata_type["set"] = [](const userdata& userdata, const sol::this_state s, + const sol::lua_value& key, const sol::lua_value& value) + { + userdata.set(convert({s, key}), convert({s, value})); + }; + + userdata_type[sol::meta_function::index] = [](const userdata& userdata, const sol::this_state s, + const sol::lua_value& key) + { + return convert(s, userdata.get(convert({s, key}))); + }; + + userdata_type[sol::meta_function::new_index] = [](const userdata& userdata, const sol::this_state s, + const sol::lua_value& key, const sol::lua_value& value) + { + userdata.set(convert({s, key }), convert({s, value})); + }; + + auto table_type = state.new_usertype("table_"); + + table_type["new"] = sol::property( + [](const table& table, const sol::this_state s) + { + return convert(s, table.get("new")); + }, + [](const table& table, const sol::this_state s, const sol::lua_value& value) + { + table.set("new", convert({s, value})); + } + ); + + table_type["get"] = [](const table& table, const sol::this_state s, + const sol::lua_value& key) + { + return convert(s, table.get(convert({s, key}))); + }; + + table_type["set"] = [](const table& table, const sol::this_state s, + const sol::lua_value& key, const sol::lua_value& value) + { + table.set(convert({s, key}), convert({s, value})); + }; + + table_type[sol::meta_function::index] = [](const table& table, const sol::this_state s, + const sol::lua_value& key) + { + return convert(s, table.get(convert({s, key}))); + }; + + table_type[sol::meta_function::new_index] = [](const table& table, const sol::this_state s, + const sol::lua_value& key, const sol::lua_value& value) + { + table.set(convert({s, key}), convert({s, value})); + }; + + auto function_type = state.new_usertype("function_"); + + function_type[sol::meta_function::call] = [](const function& function, const sol::this_state s, sol::variadic_args va) + { + arguments arguments{}; + + for (auto arg : va) + { + arguments.push_back(convert({s, arg})); + } + + const auto values = function.call(arguments); + std::vector returns; + + for (const auto& value : values) + { + returns.push_back(convert(s, value)); + } + + return sol::as_returns(returns); + }; + + state["luiglobals"] = table((*::game::hks::lua_state)->globals.v.table); + state["CoD"] = state["luiglobals"]["CoD"]; + state["LUI"] = state["luiglobals"]["LUI"]; + state["Engine"] = state["luiglobals"]["Engine"]; + state["Game"] = state["luiglobals"]["Game"]; + } + } + + context::context(std::string folder) + : folder_(std::move(folder)) + , scheduler_(state_) + { + this->state_.open_libraries(sol::lib::base, + sol::lib::package, + sol::lib::io, + sol::lib::string, + sol::lib::os, + sol::lib::math, + sol::lib::table); + + this->state_["include"] = [this](const std::string& file) + { + this->load_script(file); + }; + + sol::function old_require = this->state_["require"]; + auto base_path = utils::string::replace(this->folder_, "/", ".") + "."; + this->state_["require"] = [base_path, old_require](const std::string& path) + { + return old_require(base_path + path); + }; + + this->state_["scriptdir"] = [this]() + { + return this->folder_; + }; + + setup_types(this->state_, this->scheduler_); + + printf("Loading ui script '%s'\n", this->folder_.data()); + this->load_script("__init__"); + } + + context::~context() + { + this->state_.collect_garbage(); + this->scheduler_.clear(); + this->state_ = {}; + } + + void context::run_frame() + { + this->scheduler_.run_frame(); + this->state_.collect_garbage(); + } + + void context::load_script(const std::string& script) + { + if (!this->loaded_scripts_.emplace(script).second) + { + return; + } + + const auto file = (std::filesystem::path{this->folder_} / (script + ".lua")).generic_string(); + handle_error(this->state_.safe_script_file(file, &sol::script_pass_on_error)); + } +} diff --git a/src/client/game/ui_scripting/lua/context.hpp b/src/client/game/ui_scripting/lua/context.hpp new file mode 100644 index 00000000..0876d3df --- /dev/null +++ b/src/client/game/ui_scripting/lua/context.hpp @@ -0,0 +1,36 @@ +#pragma once +#pragma warning(push) +#pragma warning(disable: 4702) + +#define SOL_ALL_SAFETIES_ON 1 +#define SOL_PRINT_ERRORS 0 +#include + +#include "scheduler.hpp" + +namespace ui_scripting::lua +{ + class context + { + public: + context(std::string folder); + ~context(); + + context(context&&) noexcept = delete; + context& operator=(context&&) noexcept = delete; + + context(const context&) = delete; + context& operator=(const context&) = delete; + + void run_frame(); + + private: + sol::state state_{}; + std::string folder_; + std::unordered_set loaded_scripts_; + + scheduler scheduler_; + + void load_script(const std::string& script); + }; +} diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp new file mode 100644 index 00000000..7e6d7f6c --- /dev/null +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -0,0 +1,61 @@ +#include +#include "engine.hpp" +#include "context.hpp" + +#include "../../../component/ui_scripting.hpp" +#include "../../../component/game_module.hpp" + +#include + +namespace ui_scripting::lua::engine +{ + namespace + { + auto& get_scripts() + { + static std::vector> scripts{}; + return scripts; + } + + void load_scripts(const std::string& script_dir) + { + if (!utils::io::directory_exists(script_dir)) + { + return; + } + + const auto scripts = utils::io::list_files(script_dir); + + for (const auto& script : scripts) + { + if (std::filesystem::is_directory(script) && utils::io::file_exists(script + "/__init__.lua")) + { + get_scripts().push_back(std::make_unique(script)); + } + } + } + } + + void start() + { + clear_converted_functions(); + get_scripts().clear(); + load_scripts(game_module::get_host_module().get_folder() + "/data/ui_scripts/"); + load_scripts("h1-mod/ui_scripts/"); + load_scripts("data/ui_scripts/"); + } + + void stop() + { + clear_converted_functions(); + get_scripts().clear(); + } + + void run_frame() + { + for (auto& script : get_scripts()) + { + script->run_frame(); + } + } +} diff --git a/src/client/game/ui_scripting/lua/engine.hpp b/src/client/game/ui_scripting/lua/engine.hpp new file mode 100644 index 00000000..bbcf427c --- /dev/null +++ b/src/client/game/ui_scripting/lua/engine.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace ui_scripting::lua::engine +{ + void start(); + void stop(); + void run_frame(); +} diff --git a/src/client/game/ui_scripting/lua/error.cpp b/src/client/game/ui_scripting/lua/error.cpp new file mode 100644 index 00000000..d13b4896 --- /dev/null +++ b/src/client/game/ui_scripting/lua/error.cpp @@ -0,0 +1,18 @@ +#include +#include "error.hpp" + +namespace ui_scripting::lua +{ + void handle_error(const sol::protected_function_result& result) + { + if (!result.valid()) + { + printf("************** UI Script execution error **************\n"); + + const sol::error err = result; + printf("%s\n", err.what()); + + printf("****************************************************\n"); + } + } +} diff --git a/src/client/game/ui_scripting/lua/error.hpp b/src/client/game/ui_scripting/lua/error.hpp new file mode 100644 index 00000000..28a5c453 --- /dev/null +++ b/src/client/game/ui_scripting/lua/error.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "context.hpp" + +namespace ui_scripting::lua +{ + void handle_error(const sol::protected_function_result& result); +} diff --git a/src/client/game/ui_scripting/lua/scheduler.cpp b/src/client/game/ui_scripting/lua/scheduler.cpp new file mode 100644 index 00000000..18e779b6 --- /dev/null +++ b/src/client/game/ui_scripting/lua/scheduler.cpp @@ -0,0 +1,122 @@ +#include "std_include.hpp" +#include "context.hpp" +#include "error.hpp" + +namespace ui_scripting::lua +{ + scheduler::scheduler(sol::state& state) + { + auto task_handle_type = state.new_usertype("task_handle"); + + task_handle_type["clear"] = [this](const task_handle& handle) + { + this->remove(handle); + }; + } + + void scheduler::run_frame() + { + callbacks_.access([&](task_list& tasks) + { + this->merge_callbacks(); + + for (auto i = tasks.begin(); i != tasks.end();) + { + const auto now = std::chrono::high_resolution_clock::now(); + const auto diff = now - i->last_call; + + if (diff < i->delay) + { + ++i; + continue; + } + + i->last_call = now; + + if (!i->is_deleted) + { + handle_error(i->callback()); + } + + if (i->is_volatile || i->is_deleted) + { + i = tasks.erase(i); + } + else + { + ++i; + } + } + }); + } + + void scheduler::clear() + { + callbacks_.access([&](task_list& tasks) + { + new_callbacks_.access([&](task_list& new_tasks) + { + new_tasks.clear(); + tasks.clear(); + }); + }); + } + + task_handle scheduler::add(const sol::protected_function& callback, const long long milliseconds, + const bool is_volatile) + { + return this->add(callback, std::chrono::milliseconds(milliseconds), is_volatile); + } + + task_handle scheduler::add(const sol::protected_function& callback, const std::chrono::milliseconds delay, + const bool is_volatile) + { + const uint64_t id = ++this->current_task_id_; + + task task; + task.is_volatile = is_volatile; + task.callback = callback; + task.delay = delay; + task.last_call = std::chrono::steady_clock::now(); + task.id = id; + task.is_deleted = false; + + new_callbacks_.access([&task](task_list& tasks) + { + tasks.emplace_back(std::move(task)); + }); + + return {id}; + } + + void scheduler::remove(const task_handle& handle) + { + auto mask_as_deleted = [&](task_list& tasks) + { + for (auto& task : tasks) + { + if (task.id == handle.id) + { + task.is_deleted = true; + break; + } + } + }; + + callbacks_.access(mask_as_deleted); + new_callbacks_.access(mask_as_deleted); + } + + void scheduler::merge_callbacks() + { + callbacks_.access([&](task_list& tasks) + { + new_callbacks_.access([&](task_list& new_tasks) + { + tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), + std::move_iterator(new_tasks.end())); + new_tasks = {}; + }); + }); + } +} diff --git a/src/client/game/ui_scripting/lua/scheduler.hpp b/src/client/game/ui_scripting/lua/scheduler.hpp new file mode 100644 index 00000000..1935e25e --- /dev/null +++ b/src/client/game/ui_scripting/lua/scheduler.hpp @@ -0,0 +1,50 @@ +#pragma once +#include + +namespace ui_scripting::lua +{ + class context; + + class task_handle + { + public: + uint64_t id = 0; + }; + + class task final : public task_handle + { + public: + std::chrono::steady_clock::time_point last_call{}; + sol::protected_function callback{}; + std::chrono::milliseconds delay{}; + bool is_volatile = false; + bool is_deleted = false; + }; + + class scheduler final + { + public: + scheduler(sol::state& state); + + scheduler(scheduler&&) noexcept = delete; + scheduler& operator=(scheduler&&) noexcept = delete; + + scheduler(const scheduler&) = delete; + scheduler& operator=(const scheduler&) = delete; + + void run_frame(); + void clear(); + + task_handle add(const sol::protected_function& callback, long long milliseconds, bool is_volatile); + task_handle add(const sol::protected_function& callback, std::chrono::milliseconds delay, bool is_volatile); + + private: + using task_list = std::vector; + utils::concurrency::container new_callbacks_; + utils::concurrency::container callbacks_; + std::atomic_int64_t current_task_id_ = 0; + + void remove(const task_handle& handle); + void merge_callbacks(); + }; +} diff --git a/src/client/game/ui_scripting/lua/value_conversion.cpp b/src/client/game/ui_scripting/lua/value_conversion.cpp new file mode 100644 index 00000000..38376cdf --- /dev/null +++ b/src/client/game/ui_scripting/lua/value_conversion.cpp @@ -0,0 +1,144 @@ +#include +#include "value_conversion.hpp" +#include "../execution.hpp" +#include "../../../component/ui_scripting.hpp" + +namespace ui_scripting::lua +{ + namespace + { + table convert_table(const sol::table& t) + { + table res{}; + + t.for_each([res](const sol::object& key, const sol::object& value) + { + res.set(convert(key), convert(value)); + }); + + return res; + } + + script_value convert_function(const sol::protected_function& function) + { + const auto closure = game::hks::cclosure_Create(*game::hks::lua_state, main_function_handler, 0, 0, 0); + add_converted_function(closure, function); + + game::hks::HksObject value{}; + value.t = game::hks::TCFUNCTION; + value.v.cClosure = closure; + + return value; + } + } + + script_value convert(const sol::lua_value& value) + { + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is
()) + { + return {value.as
()}; + } + + if (value.is()) + { + return {value.as()}; + } + + if (value.is()) + { + return {convert_table(value.as())}; + } + + if (value.is()) + { + return {convert_function(value.as())}; + } + + return {}; + } + + sol::lua_value convert(lua_State* state, const script_value& value) + { + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is()) + { + return {state, value.as()}; + } + + if (value.is
()) + { + return {state, value.as
()}; + } + + if (value.is()) + { + return {state, value.as()}; + } + + return {state, sol::lua_nil}; + } +} diff --git a/src/client/game/ui_scripting/lua/value_conversion.hpp b/src/client/game/ui_scripting/lua/value_conversion.hpp new file mode 100644 index 00000000..21a67e33 --- /dev/null +++ b/src/client/game/ui_scripting/lua/value_conversion.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "context.hpp" +#include "../script_value.hpp" + +namespace ui_scripting::lua +{ + script_value convert(const sol::lua_value& value); + sol::lua_value convert(lua_State* state, const script_value& value); +} diff --git a/src/client/game/ui_scripting/script_value.cpp b/src/client/game/ui_scripting/script_value.cpp new file mode 100644 index 00000000..34d17020 --- /dev/null +++ b/src/client/game/ui_scripting/script_value.cpp @@ -0,0 +1,274 @@ +#include +#include "execution.hpp" +#include "types.hpp" +#include "script_value.hpp" + +namespace ui_scripting +{ + /*************************************************************** + * Constructors + **************************************************************/ + + script_value::script_value(const game::hks::HksObject& value) + : value_(value) + { + } + + script_value::script_value(const int value) + { + game::hks::HksObject obj{}; + obj.t = game::hks::TNUMBER; + obj.v.number = static_cast(value); + + this->value_ = obj; + } + + script_value::script_value(const unsigned int value) + { + game::hks::HksObject obj{}; + obj.t = game::hks::TNUMBER; + obj.v.number = static_cast(value); + + this->value_ = obj; + } + + script_value::script_value(const bool value) + { + game::hks::HksObject obj{}; + obj.t = game::hks::TBOOLEAN; + obj.v.boolean = value; + + this->value_ = obj; + } + + script_value::script_value(const float value) + { + game::hks::HksObject obj{}; + obj.t = game::hks::TNUMBER; + obj.v.number = static_cast(value); + + this->value_ = obj; + } + + script_value::script_value(const double value) + : script_value(static_cast(value)) + { + } + + script_value::script_value(const char* value) + { + game::hks::HksObject obj{}; + + const auto state = *game::hks::lua_state; + state->m_apistack.top = state->m_apistack.base; + + game::hks::hksi_lua_pushlstring(state, value, (unsigned int)strlen(value)); + obj = state->m_apistack.top[-1]; + + this->value_ = obj; + } + + script_value::script_value(const std::string& value) + : script_value(value.data()) + { + } + + script_value::script_value(const lightuserdata& value) + { + this->value_.t = game::hks::TLIGHTUSERDATA; + this->value_.v.ptr = value.ptr; + } + + script_value::script_value(const userdata& value) + { + this->value_.t = game::hks::TUSERDATA; + this->value_.v.ptr = value.ptr; + } + + script_value::script_value(const table& value) + { + this->value_.t = game::hks::TTABLE; + this->value_.v.ptr = value.ptr; + } + + script_value::script_value(const function& value) + { + this->value_.t = value.type; + this->value_.v.ptr = value.ptr; + } + + /*************************************************************** + * Integer + **************************************************************/ + + template <> + bool script_value::is() const + { + const auto number = this->get_raw().v.number; + return this->get_raw().t == game::hks::TNUMBER && static_cast(number) == number; + } + + template <> + bool script_value::is() const + { + return this->is(); + } + + template <> + int script_value::get() const + { + return static_cast(this->get_raw().v.number); + } + + template <> + unsigned int script_value::get() const + { + return static_cast(this->get_raw().v.number); + } + + /*************************************************************** + * Boolean + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().t == game::hks::TBOOLEAN; + } + + template <> + bool script_value::get() const + { + return this->get_raw().v.boolean; + } + + /*************************************************************** + * Float + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().t == game::hks::TNUMBER; + } + + template <> + bool script_value::is() const + { + return this->is(); + } + + template <> + float script_value::get() const + { + return this->get_raw().v.number; + } + + template <> + double script_value::get() const + { + return static_cast(this->get_raw().v.number); + } + + /*************************************************************** + * String + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().t == game::hks::TSTRING; + } + + template <> + bool script_value::is() const + { + return this->is(); + } + + template <> + const char* script_value::get() const + { + return this->get_raw().v.str->m_data; + } + + template <> + std::string script_value::get() const + { + return this->get(); + } + + /*************************************************************** + * Lightuserdata + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().t == game::hks::TLIGHTUSERDATA; + } + + template <> + lightuserdata script_value::get() const + { + return this->get_raw().v.ptr; + } + + /*************************************************************** + * Userdata + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().t == game::hks::TUSERDATA; + } + + template <> + userdata script_value::get() const + { + return this->get_raw().v.ptr; + } + + /*************************************************************** + * Table + **************************************************************/ + + template <> + bool script_value::is
() const + { + return this->get_raw().t == game::hks::TTABLE; + } + + template <> + table script_value::get() const + { + return this->get_raw().v.table; + } + + /*************************************************************** + * Function + **************************************************************/ + + template <> + bool script_value::is() const + { + return this->get_raw().t == game::hks::TIFUNCTION + || this->get_raw().t == game::hks::TCFUNCTION; + } + + template <> + function script_value::get() const + { + return { this->get_raw().v.cClosure, this->get_raw().t }; + } + + /*************************************************************** + * + **************************************************************/ + + const game::hks::HksObject& script_value::get_raw() const + { + return this->value_; + } +} diff --git a/src/client/game/ui_scripting/script_value.hpp b/src/client/game/ui_scripting/script_value.hpp new file mode 100644 index 00000000..3de52ddf --- /dev/null +++ b/src/client/game/ui_scripting/script_value.hpp @@ -0,0 +1,56 @@ +#pragma once +#include "game/game.hpp" + +namespace ui_scripting +{ + class lightuserdata; + class userdata; + class table; + class function; + + class script_value + { + public: + script_value() = default; + script_value(const game::hks::HksObject& value); + + script_value(int value); + script_value(unsigned int value); + script_value(bool value); + + script_value(float value); + script_value(double value); + + script_value(const char* value); + script_value(const std::string& value); + + script_value(const lightuserdata& value); + script_value(const userdata& value); + script_value(const table& value); + script_value(const function& value); + + template + bool is() const; + + template + T as() const + { + if (!this->is()) + { + throw std::runtime_error("Invalid type"); + } + + return get(); + } + + const game::hks::HksObject& get_raw() const; + + private: + template + T get() const; + + game::hks::HksObject value_{}; + }; + + using arguments = std::vector; +} diff --git a/src/client/game/ui_scripting/types.cpp b/src/client/game/ui_scripting/types.cpp new file mode 100644 index 00000000..37032b1b --- /dev/null +++ b/src/client/game/ui_scripting/types.cpp @@ -0,0 +1,276 @@ +#include +#include "types.hpp" +#include "execution.hpp" + +namespace ui_scripting +{ + /*************************************************************** + * Lightuserdata + **************************************************************/ + + lightuserdata::lightuserdata(void* ptr_) + : ptr(ptr_) + { + } + + /*************************************************************** + * Userdata + **************************************************************/ + + userdata::userdata(void* ptr_) + : ptr(ptr_) + { + this->add(); + } + + userdata::userdata(const userdata& other) + { + this->operator=(other); + } + + userdata::userdata(userdata&& other) noexcept + { + this->ptr = other.ptr; + this->ref = other.ref; + other.ref = 0; + } + + userdata::~userdata() + { + this->release(); + } + + userdata& userdata::operator=(const userdata& other) + { + if (&other != this) + { + this->release(); + this->ptr = other.ptr; + this->ref = other.ref; + this->add(); + } + + return *this; + } + + userdata& userdata::operator=(userdata&& other) noexcept + { + if (&other != this) + { + this->release(); + this->ptr = other.ptr; + this->ref = other.ref; + other.ref = 0; + } + + return *this; + } + + void userdata::add() + { + game::hks::HksObject value{}; + value.v.ptr = this->ptr; + value.t = game::hks::TUSERDATA; + + const auto state = *game::hks::lua_state; + state->m_apistack.top = state->m_apistack.base; + + push_value(value); + + this->ref = game::hks::hksi_luaL_ref(*game::hks::lua_state, -10000); + } + + void userdata::release() + { + if (this->ref) + { + game::hks::hksi_luaL_unref(*game::hks::lua_state, -10000, this->ref); + } + } + + void userdata::set(const script_value& key, const script_value& value) const + { + set_field(*this, key, value); + } + + script_value userdata::get(const script_value& key) const + { + return get_field(*this, key); + } + + /*************************************************************** + * Table + **************************************************************/ + + table::table() + { + const auto state = *game::hks::lua_state; + this->ptr = game::hks::Hashtable_Create(state, 0, 0); + this->add(); + } + + table::table(game::hks::HashTable* ptr_) + : ptr(ptr_) + { + this->add(); + } + + table::table(const table& other) + { + this->operator=(other); + } + + table::table(table&& other) noexcept + { + this->ptr = other.ptr; + this->ref = other.ref; + other.ref = 0; + } + + table::~table() + { + this->release(); + } + + table& table::operator=(const table& other) + { + if (&other != this) + { + this->release(); + this->ptr = other.ptr; + this->ref = other.ref; + this->add(); + } + + return *this; + } + + table& table::operator=(table&& other) noexcept + { + if (&other != this) + { + this->release(); + this->ptr = other.ptr; + this->ref = other.ref; + other.ref = 0; + } + + return *this; + } + + void table::add() + { + game::hks::HksObject value{}; + value.v.table = this->ptr; + value.t = game::hks::TTABLE; + + const auto state = *game::hks::lua_state; + state->m_apistack.top = state->m_apistack.base; + + push_value(value); + + this->ref = game::hks::hksi_luaL_ref(*game::hks::lua_state, -10000); + } + + void table::release() + { + if (this->ref) + { + game::hks::hksi_luaL_unref(*game::hks::lua_state, -10000, this->ref); + } + } + + void table::set(const script_value& key, const script_value& value) const + { + set_field(*this, key, value); + } + + script_value table::get(const script_value& key) const + { + return get_field(*this, key); + } + + /*************************************************************** + * Function + **************************************************************/ + + function::function(game::hks::cclosure* ptr_, game::hks::HksObjectType type_) + : ptr(ptr_) + , type(type_) + { + this->add(); + } + + function::function(const function& other) + { + this->operator=(other); + } + + function::function(function&& other) noexcept + { + this->ptr = other.ptr; + this->type = other.type; + this->ref = other.ref; + other.ref = 0; + } + + function::~function() + { + this->release(); + } + + function& function::operator=(const function& other) + { + if (&other != this) + { + this->release(); + this->ptr = other.ptr; + this->type = other.type; + this->ref = other.ref; + this->add(); + } + + return *this; + } + + function& function::operator=(function&& other) noexcept + { + if (&other != this) + { + this->release(); + this->ptr = other.ptr; + this->type = other.type; + this->ref = other.ref; + other.ref = 0; + } + + return *this; + } + + void function::add() + { + game::hks::HksObject value{}; + value.v.cClosure = this->ptr; + value.t = this->type; + + const auto state = *game::hks::lua_state; + state->m_apistack.top = state->m_apistack.base; + + push_value(value); + + this->ref = game::hks::hksi_luaL_ref(*game::hks::lua_state, -10000); + } + + void function::release() + { + if (this->ref) + { + game::hks::hksi_luaL_unref(*game::hks::lua_state, -10000, this->ref); + } + } + + arguments function::call(const arguments& arguments) const + { + return call_script_function(*this, arguments); + } +} diff --git a/src/client/game/ui_scripting/types.hpp b/src/client/game/ui_scripting/types.hpp new file mode 100644 index 00000000..1924407f --- /dev/null +++ b/src/client/game/ui_scripting/types.hpp @@ -0,0 +1,89 @@ +#pragma once +#include "game/game.hpp" +#include "script_value.hpp" + +namespace ui_scripting +{ + class lightuserdata + { + public: + lightuserdata(void*); + void* ptr; + }; + + class userdata + { + public: + userdata(void*); + + userdata(const userdata& other); + userdata(userdata&& other) noexcept; + + ~userdata(); + + userdata& operator=(const userdata& other); + userdata& operator=(userdata&& other) noexcept; + + script_value get(const script_value& key) const; + void set(const script_value& key, const script_value& value) const; + + void* ptr; + + private: + void add(); + void release(); + + int ref{}; + }; + + class table + { + public: + table(); + table(game::hks::HashTable* ptr_); + + table(const table& other); + table(table&& other) noexcept; + + ~table(); + + table& operator=(const table& other); + table& operator=(table&& other) noexcept; + + script_value get(const script_value& key) const; + void set(const script_value& key, const script_value& value) const; + + game::hks::HashTable* ptr; + + private: + void add(); + void release(); + + int ref{}; + }; + + class function + { + public: + function(game::hks::cclosure*, game::hks::HksObjectType); + + function(const function& other); + function(function&& other) noexcept; + + ~function(); + + function& operator=(const function& other); + function& operator=(function&& other) noexcept; + + arguments call(const arguments& arguments) const; + + game::hks::cclosure* ptr; + game::hks::HksObjectType type; + + private: + void add(); + void release(); + + int ref{}; + }; +} From d7b16e78ac419773ed5ff3d4f7ebd3fc98507561 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 2 Mar 2022 07:01:01 -0600 Subject: [PATCH 007/346] sp addresses + fix mp addresses stupid ida decompiler --- src/client/component/ui_scripting.cpp | 18 +++++++++--------- src/client/game/symbols.hpp | 20 ++++++++++---------- src/client/game/ui_scripting/lua/context.cpp | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index feb13ffb..421abf06 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -152,22 +152,22 @@ namespace ui_scripting void post_unpack() override { - if (!game::environment::is_mp()) + if (game::environment::is_dedi()) { return; } - hks_start_hook.create(0x140176A40, hks_start_stub); - hks_shutdown_hook.create(0x14016CA80, hks_shutdown_stub); - hksi_lual_error_hook.create(0x14011D4CC, hksi_lual_error_stub); - hksi_lual_error_hook2.create(0x1401366B0, hksi_lual_error_stub); - hks_allocator_hook.create(0x14012BB90, hks_allocator_stub); - hks_frame_hook.create(0x1401755B0, hks_frame_stub); + hks_start_hook.create(SELECT_VALUE(0x1400E4B40, 0x140176A40), hks_start_stub); + hks_shutdown_hook.create(SELECT_VALUE(0x1400DD3D0, 0x14016CA80), hks_shutdown_stub); + hksi_lual_error_hook.create(SELECT_VALUE(0x1400A5EA0, 0x14012F300), hksi_lual_error_stub); + hksi_lual_error_hook2.create(SELECT_VALUE(0x1400A5EA0, 0x1401366B0), hksi_lual_error_stub); + hks_allocator_hook.create(SELECT_VALUE(0x14009B570, 0x14012BAC0), hks_allocator_stub); + hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), hks_frame_stub); command::add("lui_restart", []() { - utils::hook::invoke(0x14016CA95); - utils::hook::invoke(0x1401780D0); + utils::hook::invoke(SELECT_VALUE(0x1400DD3D0, 0x14016CA80)); + utils::hook::invoke(SELECT_VALUE(0x1400E6170, 0x1401780D0)); }); } }; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 5b832bb1..5d57dd0b 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -186,16 +186,16 @@ namespace game namespace hks { - WEAK symbol lua_state{0, 0x1426D3D08}; - WEAK symbol hksi_lua_pushlstring{0, 0x1400624F0}; - WEAK symbol hks_obj_getfield{0, 0x14012C600}; - WEAK symbol hks_obj_settable{0, 0x14012D820}; - WEAK symbol hks_obj_gettable{0, 0x14012CAE0}; - WEAK symbol vm_call_internal{0, 0x140159EB0}; - WEAK symbol Hashtable_Create{0, 0x14011B320}; + WEAK symbol lua_state{0x141E2C2F8, 0x1426D3D08}; + WEAK symbol hksi_lua_pushlstring{0x14004DA90, 0x1400624F0}; + WEAK symbol hks_obj_getfield{0x14009C0A0, 0x14012C600}; + WEAK symbol hks_obj_settable{0x14009D240, 0x14012D820}; + WEAK symbol hks_obj_gettable{0x14009C580, 0x14012CAE0}; + WEAK symbol vm_call_internal{0x14009D2D0, 0x140159EB0}; + WEAK symbol Hashtable_Create{0x14008B3B0, 0x14011B320}; WEAK symbol cclosure_Create{0, 0x14011B540}; - WEAK symbol hksi_luaL_ref{0, 0x140136D30}; - WEAK symbol hksi_luaL_unref{0, 0x14012F610}; + int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x14008B5D0, 0x14011B540}; + WEAK symbol hksi_luaL_ref{0x1400A64D0, 0x140136D30}; + WEAK symbol hksi_luaL_unref{0x14009EF10, 0x14012F610}; } } diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index d6d05f1d..def427e0 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -74,7 +74,7 @@ namespace ui_scripting::lua userdata_type[sol::meta_function::new_index] = [](const userdata& userdata, const sol::this_state s, const sol::lua_value& key, const sol::lua_value& value) { - userdata.set(convert({s, key }), convert({s, value})); + userdata.set(convert({s, key}), convert({s, value})); }; auto table_type = state.new_usertype
("table_"); From 884efc7ce75c2d0bde8c919939a169b9e4f69719 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 2 Mar 2022 15:01:01 +0100 Subject: [PATCH 008/346] Some fixes --- src/client/component/dvars.cpp | 2 +- src/client/component/lui.cpp | 5 ----- src/client/component/ui_scripting.cpp | 6 +++++- src/client/game/symbols.hpp | 10 +++++----- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp index 4a086a27..d9c77fdf 100644 --- a/src/client/component/dvars.cpp +++ b/src/client/component/dvars.cpp @@ -435,7 +435,7 @@ namespace dvars dvar_set_float_hook.create(SELECT_VALUE(0x1403C7420, 0x1404FD360), &dvar_set_float); dvar_set_int_hook.create(SELECT_VALUE(0x1403C76C0, 0x1404FD5E0), &dvar_set_int); dvar_set_string_hook.create(SELECT_VALUE(0x1403C7900, 0x1404FD8D0), &dvar_set_string); - dvar_set_from_string_hook.create(SELECT_VALUE(0, 0x1404FD520), &dvar_set_from_string); + dvar_set_from_string_hook.create(SELECT_VALUE(0x1403C7620, 0x1404FD520), &dvar_set_from_string); } }; } diff --git a/src/client/component/lui.cpp b/src/client/component/lui.cpp index 1407d471..d3a7edca 100644 --- a/src/client/component/lui.cpp +++ b/src/client/component/lui.cpp @@ -15,11 +15,6 @@ namespace lui public: void post_unpack() override { - if (!game::environment::is_mp()) - { - return; - } - // Don't show create cod account popup //utils::hook::set(0x14017C957, 0); // H1(1.4) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index 421abf06..941dda10 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -160,10 +160,14 @@ namespace ui_scripting hks_start_hook.create(SELECT_VALUE(0x1400E4B40, 0x140176A40), hks_start_stub); hks_shutdown_hook.create(SELECT_VALUE(0x1400DD3D0, 0x14016CA80), hks_shutdown_stub); hksi_lual_error_hook.create(SELECT_VALUE(0x1400A5EA0, 0x14012F300), hksi_lual_error_stub); - hksi_lual_error_hook2.create(SELECT_VALUE(0x1400A5EA0, 0x1401366B0), hksi_lual_error_stub); hks_allocator_hook.create(SELECT_VALUE(0x14009B570, 0x14012BAC0), hks_allocator_stub); hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), hks_frame_stub); + if (game::environment::is_mp()) + { + hksi_lual_error_hook2.create(0x1401366B0, hksi_lual_error_stub); + } + command::add("lui_restart", []() { utils::hook::invoke(SELECT_VALUE(0x1400DD3D0, 0x14016CA80)); diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 5d57dd0b..ff0b8b64 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -97,9 +97,9 @@ namespace game WEAK symbol DB_GetXAssetTypeSize{0x14019A3B0, 0x14028BE70}; - WEAK symbol LUI_OpenMenu{0, 0x1404CD210}; + WEAK symbol LUI_OpenMenu{0x14039D5F0, 0x1404CD210}; - WEAK symbol Menu_IsMenuOpenAndVisible{0, 0x1404C7320}; + WEAK symbol Menu_IsMenuOpenAndVisible{0x1404709C0, 0x1404C7320}; WEAK symbol SL_FindString{0x140314AF0, 0x14043B470}; @@ -136,8 +136,8 @@ namespace game WEAK symbol UI_GetMapDisplayName{0, 0x140408CC0}; WEAK symbol UI_GetGameTypeDisplayName{0, 0x1404086A0}; - WEAK symbol UI_RunMenuScript{0, 0x1404CFE60}; - WEAK symbol UI_TextWidth{0, 0x1404D21A0}; + WEAK symbol UI_RunMenuScript{0x14039EFF0, 0x1404CFE60}; + WEAK symbol UI_TextWidth{0x1403A0F20, 0x1404D21A0}; WEAK symbol UI_SafeTranslateString{0x140350430, 0x14041C580}; @@ -191,7 +191,7 @@ namespace game WEAK symbol hks_obj_getfield{0x14009C0A0, 0x14012C600}; WEAK symbol hks_obj_settable{0x14009D240, 0x14012D820}; WEAK symbol hks_obj_gettable{0x14009C580, 0x14012CAE0}; - WEAK symbol vm_call_internal{0x14009D2D0, 0x140159EB0}; + WEAK symbol vm_call_internal{0x1400C87A0, 0x140159EB0}; WEAK symbol Hashtable_Create{0x14008B3B0, 0x14011B320}; WEAK symbol cclosure_Create{0x14008B5D0, 0x14011B540}; From 2f69033ec189f9a13af8dee277c6cd770ad83e2e Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 2 Mar 2022 21:05:05 +0100 Subject: [PATCH 009/346] Setup data folder --- data/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 data/.gitkeep diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 00000000..e69de29b From 0b3f8bf8fac63a18c64ececc358e673fa0db89be Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 2 Mar 2022 21:06:15 +0100 Subject: [PATCH 010/346] Finish fixing classes not saving --- src/client/game/demonware/data_types.hpp | 29 +++++ .../game/demonware/services/bdStorage.cpp | 115 ++++++++---------- 2 files changed, 77 insertions(+), 67 deletions(-) diff --git a/src/client/game/demonware/data_types.hpp b/src/client/game/demonware/data_types.hpp index c7ba4929..fb108190 100644 --- a/src/client/game/demonware/data_types.hpp +++ b/src/client/game/demonware/data_types.hpp @@ -141,4 +141,33 @@ namespace demonware buffer->read_string(&this->timezone); } }; + + // made up name + class bdFile final : public bdTaskResult + { + public: + uint64_t owner_id; + std::string platform; + std::string filename; + uint32_t unk; + std::string data; + + void serialize(byte_buffer* buffer) override + { + buffer->write_uint64(this->owner_id); + buffer->write_string(this->platform); + buffer->write_string(this->filename); + buffer->write_uint32(this->unk); + buffer->write_blob(this->data); + } + + void deserialize(byte_buffer* buffer) override + { + buffer->read_uint64(&this->owner_id); + buffer->read_string(&this->platform); + buffer->read_string(&this->filename); + buffer->read_uint32(&this->unk); + buffer->read_blob(&this->data); + } + }; } diff --git a/src/client/game/demonware/services/bdStorage.cpp b/src/client/game/demonware/services/bdStorage.cpp index 1e1426db..2e7f026c 100644 --- a/src/client/game/demonware/services/bdStorage.cpp +++ b/src/client/game/demonware/services/bdStorage.cpp @@ -147,62 +147,31 @@ namespace demonware utils::io::write_file("demonware/bdStorage/set_user_file", buffer->get_buffer()); #endif - auto reply = server->create_reply(this->task_id()); uint64_t owner; + uint32_t numfiles; + std::string game, platform; + buffer->read_string(&game); + buffer->read_uint64(&owner); + buffer->read_string(&platform); + buffer->read_uint32(&numfiles); + + auto reply = server->create_reply(this->task_id()); + + for (uint32_t i = 0; i < numfiles; i++) { - bool priv; - uint32_t unk32_0; - uint32_t unk32_1; - std::string game, platform, filename, data; - - buffer->read_string(&game); - buffer->read_uint64(&owner); - buffer->read_string(&platform); - buffer->read_uint32(&unk32_0); - - buffer->read_string(&filename); - buffer->read_blob(&data); - buffer->read_uint32(&unk32_1); - buffer->read_bool(&priv); - - const auto path = get_user_file_path(filename); - utils::io::write_file(path, data); - -#ifdef DEBUG - printf("[DW]: [bdStorage]: set user file: %s\n", filename.data()); -#endif - - auto* info = new bdFileInfo; - - info->file_id = *reinterpret_cast(utils::cryptography::sha1::compute(filename).data()); - info->filename = filename; - info->create_time = uint32_t(time(nullptr)); - info->modified_time = info->create_time; - info->file_size = uint32_t(data.size()); - info->owner_id = uint64_t(owner); - info->priv = priv; - - reply->add(info); - } - - { - bool priv; - uint32_t unk32_0; std::string filename, data; + uint32_t unk; + bool priv; buffer->read_string(&filename); buffer->read_blob(&data); - buffer->read_uint32(&unk32_0); + buffer->read_uint32(&unk); buffer->read_bool(&priv); const auto path = get_user_file_path(filename); utils::io::write_file(path, data); -#ifdef DEBUG - printf("[DW]: [bdStorage]: set user file: %s\n", filename.data()); -#endif - auto* info = new bdFileInfo; info->file_id = *reinterpret_cast(utils::cryptography::sha1::compute(filename).data()); @@ -213,6 +182,10 @@ namespace demonware info->owner_id = uint64_t(owner); info->priv = priv; +#ifdef DEBUG + printf("[DW]: [bdStorage]: set user file: %s\n", filename.data()); +#endif + reply->add(info); } @@ -226,10 +199,9 @@ namespace demonware #endif uint32_t unk32_0; - uint32_t unk32_1; + uint32_t numfiles, count = 0; uint64_t owner; - std::string game, filename, filename2, - platform, data, data2; + std::string game, platform; buffer->read_string(&game); buffer->read_uint32(&unk32_0); @@ -237,30 +209,39 @@ namespace demonware buffer->read_string(&platform); buffer->read_uint64(&owner); buffer->read_string(&platform); - buffer->read_uint32(&unk32_1); - buffer->read_string(&filename); - buffer->read_string(&filename2); + buffer->read_uint32(&numfiles); -#ifdef DEBUG - printf("[DW]: [bdStorage]: get user file: %s, %s, %s\n", game.data(), filename.data(), platform.data()); -#endif + auto reply = server->create_reply(this->task_id()); -#ifdef DEBUG - printf("[DW]: [bdStorage]: get user file: %s, %s, %s\n", game.data(), filename2.data(), platform.data()); -#endif - - const auto path = get_user_file_path(filename); - const auto path2 = get_user_file_path(filename2); - - if (utils::io::read_file(path, &data) && utils::io::read_file(path2, &data2)) + for (uint32_t i = 0; i < numfiles; i++) { - // TODO: find out what the response should be for 2 files - // auto reply = server->create_reply(this->task_id()); - // reply->add(new bdFileData(data)); - // reply->add(new bdFileData(data2)); - // reply->send(); + std::string filename, data; + buffer->read_string(&filename); - server->create_reply(this->task_id(), game::BD_NO_FILE)->send(); + const auto path = get_user_file_path(filename); + if (!utils::io::read_file(path, &data)) + { + continue; + } + + auto response = new bdFile; + response->owner_id = owner; + response->unk = 0; + response->platform = platform; + response->filename = filename; + response->data = data; + + reply->add(response); + ++count; + +#ifdef DEBUG + printf("[DW]: [bdStorage]: get user file: %s, %s, %s\n", game.data(), filename.data(), platform.data()); +#endif + } + + if (count == numfiles) + { + reply->send(); } else { From 586abfe0f6ccd11d5c9ecf7dd3e1e7a5aed03a78 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 2 Mar 2022 21:10:37 +0100 Subject: [PATCH 011/346] Improve server list --- data/ui_scripts/server_list/__init__.lua | 143 +++++++++++++++++++++++ src/client/component/server_list.cpp | 5 + 2 files changed, 148 insertions(+) create mode 100644 data/ui_scripts/server_list/__init__.lua diff --git a/data/ui_scripts/server_list/__init__.lua b/data/ui_scripts/server_list/__init__.lua new file mode 100644 index 00000000..a5532b0a --- /dev/null +++ b/data/ui_scripts/server_list/__init__.lua @@ -0,0 +1,143 @@ +local Lobby = luiglobals.Lobby +local SystemLinkJoinMenu = LUI.mp_menus.SystemLinkJoinMenu + +if (not SystemLinkJoinMenu) then + return +end + +local offsets = { + 10, + 500, + 950, + 700, + 1100, +} + +local columns = { + "@MENU_HOST_NAME", + "@MENU_MAP", + "Players", + "@MENU_TYPE1", + "Ping", +} + +SystemLinkJoinMenu.AddHeaderButton = function(menu, f12_arg1, width) + local state = CoD.CreateState(0, f12_arg1, nil, nil, CoD.AnchorTypes.TopLeft) + state.width = width + local element = LUI.UIElement.new(state) + local button = SystemLinkJoinMenu.CreateButton("header", 24) + + button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.TopLeftRight), 40, LUI.Divider.Grey)) + button:makeNotFocusable() + button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.BottomLeftRight), 40, LUI.Divider.Grey)) + + local gettext = function(i) + return Engine.Localize(columns[i]) + end + + for i = 1, #offsets do + SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), nil) + end + + element:addElement(button) + menu:addElement(element) +end + +SystemLinkJoinMenu.AddServerButton = function(menu, controller, index) + local button = SystemLinkJoinMenu.CreateButton(index or "header", 24) + button:makeFocusable() + button.index = index + button:addEventHandler("button_action", SystemLinkJoinMenu.OnJoinGame) + + local gettext = function(i) + return Lobby.GetServerData(controller, index, i - 1) + end + + for i = 1, #offsets do + SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), luiglobals.Colors.h1.medium_grey) + end + + menu.list:addElement(button) + return button +end + +SystemLinkJoinMenu.MakeText = function(menu, f5_arg1, text, color) + local state = CoD.CreateState(f5_arg1, nil, f5_arg1 + 200, nil, CoD.AnchorTypes.Left) + state.font = CoD.TextSettings.TitleFontSmall.Font + state.top = -6 + state.height = 14 + state.alignment = LUI.Alignment.Left + state.glow = LUI.GlowState.None + state.color = color + + local el = LUI.UIText.new(state) + el:registerAnimationState("focused", { + color = luiglobals.Colors.white + }) + + el:registerEventHandler("focused", function(element, event) + element:animateToState("focused", 0) + end) + + el:registerEventHandler("unfocused", function(element, event) + element:animateToState("default", 0) + end) + + el:setText(text) + menu:addElement(el) +end + +function menu_systemlink_join(f19_arg0, f19_arg1) + local width = 1145 + + local menu = LUI.MenuTemplate.new(f19_arg0, { + menu_title = "@PLATFORM_SYSTEM_LINK_TITLE", + menu_width = width, + menu_top_indent = 20, + disableDeco = true, + spacing = 1 + }) + + SystemLinkJoinMenu.AddHeaderButton(menu, 80, width) + SystemLinkJoinMenu.AddLowerCounter(menu, width) + SystemLinkJoinMenu.UpdateCounterText(menu, nil) + Lobby.BuildServerList(Engine.GetFirstActiveController()) + + menu.list:registerEventHandler(LUI.UIScrollIndicator.UpdateEvent, function(element, event) + SystemLinkJoinMenu.UpdateCounterText(menu, event) + end) + + SystemLinkJoinMenu.UpdateGameList(menu) + menu:registerEventHandler("updateGameList", SystemLinkJoinMenu.UpdateGameList) + menu:addElement(LUI.UITimer.new(250, "updateGameList")) + + LUI.ButtonHelperText.ClearHelperTextObjects(menu.help, { + side = "all" + }) + + menu:AddHelp({ + name = "add_button_helper_text", + button_ref = "button_alt1", + helper_text = Engine.Localize("@MENU_SB_TOOLTIP_BTN_REFRESH"), + side = "right", + clickable = true, + priority = -1000 + }, function(f21_arg0, f21_arg1) + SystemLinkJoinMenu.RefreshServers(f21_arg0, f21_arg1, menu) + end) + + menu:AddHelp({ + name = "add_button_helper_text", + button_ref = "button_action", + helper_text = Engine.Localize("@MENU_JOIN_GAME1"), + side = "left", + clickable = false, + priority = -1000 + }, nil, nil, true) + + menu:AddBackButton() + + return menu +end + +LUI.MenuBuilder.m_types_build["menu_systemlink_join"] = menu_systemlink_join diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index 76c68058..5f01c8c5 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -150,6 +150,11 @@ namespace server_list return servers[i].game_type.empty() ? "" : utils::string::va("%s", servers[i].game_type.data()); } + if (column == 4) + { + return servers[i].game_type.empty() ? "" : utils::string::va("%i", servers[i].ping); + } + return ""; } From a26b7fe153e132e568013986ca700997b38417b4 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 2 Mar 2022 16:50:40 -0600 Subject: [PATCH 012/346] Don't show ping in lobby --- src/client/component/fps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index 82d8f715..db471119 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -111,7 +111,7 @@ namespace fps void cg_draw_ping() { - if (cg_drawping->current.integer > 0 && game::CL_IsCgameInitialized()) + if (cg_drawping->current.integer > 0 && game::CL_IsCgameInitialized() && !game::VirtualLobby_Loaded()) { const auto ping = *reinterpret_cast(0x142D106F0); From 84cb994da57e8c346a630e507ab14f17e0013f31 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 2 Mar 2022 17:21:09 -0600 Subject: [PATCH 013/346] add Server List button --- data/ui_scripts/server_list/__init__.lua | 145 +-------------------- data/ui_scripts/server_list/lobby.lua | 66 ++++++++++ data/ui_scripts/server_list/serverlist.lua | 145 +++++++++++++++++++++ 3 files changed, 213 insertions(+), 143 deletions(-) create mode 100644 data/ui_scripts/server_list/lobby.lua create mode 100644 data/ui_scripts/server_list/serverlist.lua diff --git a/data/ui_scripts/server_list/__init__.lua b/data/ui_scripts/server_list/__init__.lua index a5532b0a..40ef8d17 100644 --- a/data/ui_scripts/server_list/__init__.lua +++ b/data/ui_scripts/server_list/__init__.lua @@ -1,143 +1,2 @@ -local Lobby = luiglobals.Lobby -local SystemLinkJoinMenu = LUI.mp_menus.SystemLinkJoinMenu - -if (not SystemLinkJoinMenu) then - return -end - -local offsets = { - 10, - 500, - 950, - 700, - 1100, -} - -local columns = { - "@MENU_HOST_NAME", - "@MENU_MAP", - "Players", - "@MENU_TYPE1", - "Ping", -} - -SystemLinkJoinMenu.AddHeaderButton = function(menu, f12_arg1, width) - local state = CoD.CreateState(0, f12_arg1, nil, nil, CoD.AnchorTypes.TopLeft) - state.width = width - local element = LUI.UIElement.new(state) - local button = SystemLinkJoinMenu.CreateButton("header", 24) - - button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.TopLeftRight), 40, LUI.Divider.Grey)) - button:makeNotFocusable() - button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.BottomLeftRight), 40, LUI.Divider.Grey)) - - local gettext = function(i) - return Engine.Localize(columns[i]) - end - - for i = 1, #offsets do - SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), nil) - end - - element:addElement(button) - menu:addElement(element) -end - -SystemLinkJoinMenu.AddServerButton = function(menu, controller, index) - local button = SystemLinkJoinMenu.CreateButton(index or "header", 24) - button:makeFocusable() - button.index = index - button:addEventHandler("button_action", SystemLinkJoinMenu.OnJoinGame) - - local gettext = function(i) - return Lobby.GetServerData(controller, index, i - 1) - end - - for i = 1, #offsets do - SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), luiglobals.Colors.h1.medium_grey) - end - - menu.list:addElement(button) - return button -end - -SystemLinkJoinMenu.MakeText = function(menu, f5_arg1, text, color) - local state = CoD.CreateState(f5_arg1, nil, f5_arg1 + 200, nil, CoD.AnchorTypes.Left) - state.font = CoD.TextSettings.TitleFontSmall.Font - state.top = -6 - state.height = 14 - state.alignment = LUI.Alignment.Left - state.glow = LUI.GlowState.None - state.color = color - - local el = LUI.UIText.new(state) - el:registerAnimationState("focused", { - color = luiglobals.Colors.white - }) - - el:registerEventHandler("focused", function(element, event) - element:animateToState("focused", 0) - end) - - el:registerEventHandler("unfocused", function(element, event) - element:animateToState("default", 0) - end) - - el:setText(text) - menu:addElement(el) -end - -function menu_systemlink_join(f19_arg0, f19_arg1) - local width = 1145 - - local menu = LUI.MenuTemplate.new(f19_arg0, { - menu_title = "@PLATFORM_SYSTEM_LINK_TITLE", - menu_width = width, - menu_top_indent = 20, - disableDeco = true, - spacing = 1 - }) - - SystemLinkJoinMenu.AddHeaderButton(menu, 80, width) - SystemLinkJoinMenu.AddLowerCounter(menu, width) - SystemLinkJoinMenu.UpdateCounterText(menu, nil) - Lobby.BuildServerList(Engine.GetFirstActiveController()) - - menu.list:registerEventHandler(LUI.UIScrollIndicator.UpdateEvent, function(element, event) - SystemLinkJoinMenu.UpdateCounterText(menu, event) - end) - - SystemLinkJoinMenu.UpdateGameList(menu) - menu:registerEventHandler("updateGameList", SystemLinkJoinMenu.UpdateGameList) - menu:addElement(LUI.UITimer.new(250, "updateGameList")) - - LUI.ButtonHelperText.ClearHelperTextObjects(menu.help, { - side = "all" - }) - - menu:AddHelp({ - name = "add_button_helper_text", - button_ref = "button_alt1", - helper_text = Engine.Localize("@MENU_SB_TOOLTIP_BTN_REFRESH"), - side = "right", - clickable = true, - priority = -1000 - }, function(f21_arg0, f21_arg1) - SystemLinkJoinMenu.RefreshServers(f21_arg0, f21_arg1, menu) - end) - - menu:AddHelp({ - name = "add_button_helper_text", - button_ref = "button_action", - helper_text = Engine.Localize("@MENU_JOIN_GAME1"), - side = "left", - clickable = false, - priority = -1000 - }, nil, nil, true) - - menu:AddBackButton() - - return menu -end - -LUI.MenuBuilder.m_types_build["menu_systemlink_join"] = menu_systemlink_join +require("lobby") +require("serverlist") diff --git a/data/ui_scripts/server_list/lobby.lua b/data/ui_scripts/server_list/lobby.lua new file mode 100644 index 00000000..348e95af --- /dev/null +++ b/data/ui_scripts/server_list/lobby.lua @@ -0,0 +1,66 @@ +local Lobby = luiglobals.Lobby +local MPLobbyOnline = LUI.mp_menus.MPLobbyOnline + +function LeaveLobby(f5_arg0) + LeaveXboxLive() + if Lobby.IsInPrivateParty() == false or Lobby.IsPrivatePartyHost() then + LUI.FlowManager.RequestLeaveMenuByName("menu_xboxlive") + Engine.ExecNow("clearcontrollermap") + end +end + +function menu_xboxlive(f16_arg0, f16_arg1) + local menu = LUI.MPLobbyBase.new(f16_arg0, { + menu_title = "@PLATFORM_UI_HEADER_PLAY_MP_CAPS", + memberListState = Lobby.MemberListStates.Prelobby + }) + + menu:setClass(LUI.MPLobbyOnline) + + local serverListButton = menu:AddButton("SERVER LIST", function (a1, a2) + LUI.FlowManager.RequestAddMenu(a1, "menu_systemlink_join", true, nil) + end) + serverListButton:setDisabledRefreshRate(500) + if Engine.IsCoreMode() then + menu:AddCACButton() + menu:AddBarracksButton() + menu:AddPersonalizationButton() + -- menu:AddDepotButton() + end + + serverListButton = menu:AddButton("@MENU_PRIVATE_MATCH", MPLobbyOnline.OnPrivateMatch, MPLobbyOnline.disablePrivateMatchButton) + serverListButton:rename("menu_xboxlive_private_match") + serverListButton:setDisabledRefreshRate(500) + if not Engine.IsCoreMode() then + local leaderboardButton = menu:AddButton("@LUA_MENU_LEADERBOARD", "OpLeaderboardMain") + leaderboardButton:rename("OperatorMenu_leaderboard") + end + + menu:AddOptionsButton() + local natType = Lobby.GetNATType() + if natType then + local natTypeText = Engine.Localize("NETWORK_YOURNATTYPE", natType) + local properties = CoD.CreateState(nil, nil, 2, -62, CoD.AnchorTypes.BottomRight) + properties.width = 250 + properties.height = CoD.TextSettings.BodyFontVeryTiny.Height + properties.font = CoD.TextSettings.BodyFontVeryTiny.Font + properties.color = luiglobals.Colors.white + properties.alpha = 0.25 + local self = LUI.UIText.new(properties) + self:setText(natTypeText) + menu:addElement(self) + end + + menu.isSignInMenu = true + menu:registerEventHandler("gain_focus", LUI.MPLobbyOnline.OnGainFocus) + menu:registerEventHandler("player_joined", luiglobals.Cac.PlayerJoinedEvent) + menu:registerEventHandler("exit_live_lobby", LeaveLobby) + + if Engine.IsCoreMode() then + Engine.ExecNow("eliteclan_refresh", Engine.GetFirstActiveController()) + end + + return menu +end + +LUI.MenuBuilder.m_types_build["menu_xboxlive"] = menu_xboxlive diff --git a/data/ui_scripts/server_list/serverlist.lua b/data/ui_scripts/server_list/serverlist.lua new file mode 100644 index 00000000..ca597cee --- /dev/null +++ b/data/ui_scripts/server_list/serverlist.lua @@ -0,0 +1,145 @@ +local Lobby = luiglobals.Lobby +local SystemLinkJoinMenu = LUI.mp_menus.SystemLinkJoinMenu + +if (not SystemLinkJoinMenu) then + return +end + +local offsets = { + 10, + 500, + 950, + 700, + 1100, +} + +local columns = { + "@MENU_HOST_NAME", + "@MENU_MAP", + "Players", + "@MENU_TYPE1", + "Ping", +} + +SystemLinkJoinMenu.AddHeaderButton = function(menu, f12_arg1, width) + local state = CoD.CreateState(0, f12_arg1, nil, nil, CoD.AnchorTypes.TopLeft) + state.width = width + local element = LUI.UIElement.new(state) + local button = SystemLinkJoinMenu.CreateButton("header", 24) + + button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.TopLeftRight), 40, LUI.Divider.Grey)) + button:makeNotFocusable() + button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.BottomLeftRight), 40, LUI.Divider.Grey)) + + local gettext = function(i) + return Engine.Localize(columns[i]) + end + + for i = 1, #offsets do + SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), nil) + end + + element:addElement(button) + menu:addElement(element) +end + +SystemLinkJoinMenu.AddServerButton = function(menu, controller, index) + local button = SystemLinkJoinMenu.CreateButton(index or "header", 24) + button:makeFocusable() + button.index = index + button:addEventHandler("button_action", SystemLinkJoinMenu.OnJoinGame) + + local gettext = function(i) + return Lobby.GetServerData(controller, index, i - 1) + end + + for i = 1, #offsets do + SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), luiglobals.Colors.h1.medium_grey) + end + + menu.list:addElement(button) + return button +end + +SystemLinkJoinMenu.MakeText = function(menu, f5_arg1, text, color) + local state = CoD.CreateState(f5_arg1, nil, f5_arg1 + 200, nil, CoD.AnchorTypes.Left) + state.font = CoD.TextSettings.TitleFontSmall.Font + state.top = -6 + state.height = 14 + state.alignment = LUI.Alignment.Left + state.glow = LUI.GlowState.None + state.color = color + + local el = LUI.UIText.new(state) + el:registerAnimationState("focused", { + color = luiglobals.Colors.white + }) + + el:registerEventHandler("focused", function(element, event) + element:animateToState("focused", 0) + end) + + el:registerEventHandler("unfocused", function(element, event) + element:animateToState("default", 0) + end) + + el:setText(text) + menu:addElement(el) +end + +function menu_systemlink_join(f19_arg0, f19_arg1) + local width = 1145 + + local menu = LUI.MenuTemplate.new(f19_arg0, { + menu_title = "@PLATFORM_SYSTEM_LINK_TITLE", + menu_width = width, + menu_top_indent = 20, + disableDeco = true, + spacing = 1 + }) + + SystemLinkJoinMenu.AddHeaderButton(menu, 80, width) + SystemLinkJoinMenu.AddLowerCounter(menu, width) + SystemLinkJoinMenu.UpdateCounterText(menu, nil) + Lobby.BuildServerList(Engine.GetFirstActiveController()) + + menu.list:registerEventHandler(LUI.UIScrollIndicator.UpdateEvent, function(element, event) + SystemLinkJoinMenu.UpdateCounterText(menu, event) + end) + + SystemLinkJoinMenu.UpdateGameList(menu) + menu:registerEventHandler("updateGameList", SystemLinkJoinMenu.UpdateGameList) + menu:addElement(LUI.UITimer.new(250, "updateGameList")) + + LUI.ButtonHelperText.ClearHelperTextObjects(menu.help, { + side = "all" + }) + + menu:AddHelp({ + name = "add_button_helper_text", + button_ref = "button_alt1", + helper_text = Engine.Localize("@MENU_SB_TOOLTIP_BTN_REFRESH"), + side = "right", + clickable = true, + priority = -1000 + }, function(f21_arg0, f21_arg1) + SystemLinkJoinMenu.RefreshServers(f21_arg0, f21_arg1, menu) + end) + + menu:AddHelp({ + name = "add_button_helper_text", + button_ref = "button_action", + helper_text = Engine.Localize("@MENU_JOIN_GAME1"), + side = "left", + clickable = false, + priority = -1000 + }, nil, nil, true) + + menu:AddBackButton() + + Lobby.RefreshServerList(Engine.GetFirstActiveController()) + + return menu +end + +LUI.MenuBuilder.m_types_build["menu_systemlink_join"] = menu_systemlink_join From a7f03c1c62a01cbef6c161bb3bbab55ae3251d27 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 2 Mar 2022 18:13:34 -0600 Subject: [PATCH 014/346] Update README.md --- README.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b459ea06..0e5d0cf4 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,11 @@ -# H1-Mod 1.4 - -- *Note: Multiplayer support is in progress!* +# H1-Mod

-Proof of concept for an Modern Warfare Remastered client.
-[This project is based on S1x](https://github.com/XLabsProject/s1x-client) +Currently a proof-of-concept client for Modern Warfare Remaster (1.04). Latest MWR (1.15) version planned in future.
+[This project is based on S1x.](https://github.com/XLabsProject/s1x-client) ## Compile from source @@ -24,11 +22,11 @@ Proof of concept for an Modern Warfare Remastered client.
## Credits: -- [XLabsProject - S1x](https://github.com/XLabsProject/s1x-client), Project base. -- [quaK](https://github.com/Joelrau), Helping in alot of stuff. -- [fed - h2-mod](https://github.com/fedddddd/h2-mod), [Dvars](https://github.com/skkuull/h1-mod/blob/main/src/client/game/dvars.cpp) and [patches](https://github.com/skkuull/h1-mod/blob/main/src/client/component/patches.cpp). - +- [S1x](https://github.com/XLabsProject/s1x-client) - code and base. +- [quaK](https://github.com/Joelrau) - lots of insight and help +- [fed](https://github.com/fedddddd) - fixed DW/networking, work from [fed](https://github.com/fedddddd/h2-mod) +- [mjkzy](https://github.com/mjkzy) - porting code from s1x ## Disclaimer -This software has been made for learning purposes. +This software has been created purely for the purposes of academic research. It is not intended to be used to attack other systems. Project maintainers are not responsible or liable for misuse of the software. Use responsibly. From 16f2f7e9f7b172c530efe869db2e5e91294eb102 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 2 Mar 2022 18:20:15 -0600 Subject: [PATCH 015/346] Create LICENSE --- LICENSE | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..f288702d --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From 9d7f74c93944e4103b6c0fadc941873e9e4d6c0b Mon Sep 17 00:00:00 2001 From: m Date: Wed, 2 Mar 2022 18:35:23 -0600 Subject: [PATCH 016/346] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e5d0cf4..1debc4bc 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Currently a proof-of-concept client for Modern Warfare Remaster (1.04). Latest M - [S1x](https://github.com/XLabsProject/s1x-client) - code and base. - [quaK](https://github.com/Joelrau) - lots of insight and help -- [fed](https://github.com/fedddddd) - fixed DW/networking, work from [fed](https://github.com/fedddddd/h2-mod) +- [fed](https://github.com/fedddddd) - fixed DW/networking, work from [h2-mod](https://github.com/fedddddd/h2-mod) - [mjkzy](https://github.com/mjkzy) - porting code from s1x ## Disclaimer From e5149fe721fa026adebf6ed823c832ad4a0e9a69 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 3 Mar 2022 02:09:13 +0100 Subject: [PATCH 017/346] Scripting progress --- src/client/component/logfile.cpp | 114 +- src/client/component/scripting.cpp | 42 +- src/client/component/scripting.hpp | 3 - src/client/game/scripting/execution.cpp | 14 +- src/client/game/scripting/function_tables.cpp | 4977 ++++++++++++----- src/client/game/scripting/lua/context.cpp | 209 +- .../game/scripting/lua/value_conversion.cpp | 2 +- src/client/game/structs.hpp | 12 +- src/client/game/symbols.hpp | 83 +- 9 files changed, 3737 insertions(+), 1719 deletions(-) diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp index 7a3a0870..db291587 100644 --- a/src/client/component/logfile.cpp +++ b/src/client/component/logfile.cpp @@ -24,7 +24,7 @@ namespace logfile std::vector player_damage_callbacks; utils::hook::detour vm_execute_hook; - char empty_function[2] = { 0x32, 0x34 }; // CHECK_CLEAR_PARAMS, END + char empty_function[2] = {0x32, 0x34}; // CHECK_CLEAR_PARAMS, END bool hook_enabled = true; sol::lua_value convert_entity(lua_State* state, const game::mp::gentity_s* ent) @@ -34,16 +34,14 @@ namespace logfile return {}; } - const auto player = scripting::call("getEntByNum", { ent->s.entityNum }); - + const scripting::entity player{game::Scr_GetEntityId(ent->s.entityNum, 0)}; return scripting::lua::convert(state, player); } std::string get_weapon_name(unsigned int weapon, bool isAlternate) { - char output[1024] = { 0 }; + char output[1024] = {0}; game::BG_GetWeaponNameComplete(weapon, isAlternate, output, 1024); - return output; } @@ -54,39 +52,39 @@ namespace logfile return {}; } - const auto _vec = scripting::vector(vec); - - return scripting::lua::convert(state, _vec); + const auto vec_ = scripting::vector(vec); + return scripting::lua::convert(state, vec_); } std::string convert_mod(const int meansOfDeath) { const auto value = reinterpret_cast(0x140FEC3F0)[meansOfDeath]; const auto string = game::SL_ConvertToString(*value); - return string; } - void scr_player_killed_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, game::mp::gentity_s* attacker, int damage, - const int meansOfDeath, const unsigned int weapon, const bool isAlternate, const float* vDir, const unsigned int hitLoc, int psTimeOffset, int deathAnimDuration) + void scr_player_killed_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, + game::mp::gentity_s* attacker, int damage, const int meansOfDeath, const unsigned int weapon, + const bool isAlternate, const float* vDir, const unsigned int hitLoc, int psTimeOffset, int deathAnimDuration) { { - const std::string _hitLoc = reinterpret_cast(0x140FEC4D0)[hitLoc]; // or 12162B0 - const auto _mod = convert_mod(meansOfDeath); + const std::string hitloc = reinterpret_cast(0x140FEC4D0)[hitLoc]; + const auto mod_ = convert_mod(meansOfDeath); - const auto _weapon = get_weapon_name(weapon, isAlternate); + const auto weapon_ = get_weapon_name(weapon, isAlternate); for (const auto& callback : player_killed_callbacks) { const auto state = callback.lua_state(); - const auto _self = convert_entity(state, self); - const auto _inflictor = convert_entity(state, inflictor); - const auto _attacker = convert_entity(state, attacker); + const auto self_ = convert_entity(state, self); + const auto inflictor_ = convert_entity(state, inflictor); + const auto attacker_ = convert_entity(state, attacker); - const auto _vDir = convert_vector(state, vDir); + const auto dir = convert_vector(state, vDir); - const auto result = callback(_self, _inflictor, _attacker, damage, _mod, _weapon, _vDir, _hitLoc, psTimeOffset, deathAnimDuration); + const auto result = callback(self_, inflictor_, attacker_, damage, + mod_, weapon_, dir, hitloc, psTimeOffset, deathAnimDuration); scripting::lua::handle_error(result); @@ -102,30 +100,34 @@ namespace logfile } } - scr_player_killed_hook.invoke(self, inflictor, attacker, damage, meansOfDeath, weapon, isAlternate, vDir, hitLoc, psTimeOffset, deathAnimDuration); + scr_player_killed_hook.invoke(self, inflictor, attacker, damage, meansOfDeath, + weapon, isAlternate, vDir, hitLoc, psTimeOffset, deathAnimDuration); } - void scr_player_damage_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, game::mp::gentity_s* attacker, int damage, int dflags, - const int meansOfDeath, const unsigned int weapon, const bool isAlternate, const float* vPoint, const float* vDir, const unsigned int hitLoc, const int timeOffset) + void scr_player_damage_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, + game::mp::gentity_s* attacker, int damage, int dflags, const int meansOfDeath, + const unsigned int weapon, const bool isAlternate, const float* vPoint, + const float* vDir, const unsigned int hitLoc, const int timeOffset) { { - const std::string _hitLoc = reinterpret_cast(0x140FEC4D0)[hitLoc]; // or 12162B0 - const auto _mod = convert_mod(meansOfDeath); + const std::string hitloc = reinterpret_cast(0x140FEC4D0)[hitLoc]; + const auto mod_ = convert_mod(meansOfDeath); - const auto _weapon = get_weapon_name(weapon, isAlternate); + const auto weapon_ = get_weapon_name(weapon, isAlternate); for (const auto& callback : player_damage_callbacks) { const auto state = callback.lua_state(); - const auto _self = convert_entity(state, self); - const auto _inflictor = convert_entity(state, inflictor); - const auto _attacker = convert_entity(state, attacker); + const auto self_ = convert_entity(state, self); + const auto inflictor_ = convert_entity(state, inflictor); + const auto attacker_ = convert_entity(state, attacker); - const auto _vPoint = convert_vector(state, vPoint); - const auto _vDir = convert_vector(state, vDir); + const auto point = convert_vector(state, vPoint); + const auto dir = convert_vector(state, vDir); - const auto result = callback(_self, _inflictor, _attacker, damage, dflags, _mod, _weapon, _vPoint, _vDir, _hitLoc); + const auto result = callback(self_, inflictor_, attacker_, + damage, dflags, mod_, weapon_, point, dir, hitloc); scripting::lua::handle_error(result); @@ -141,13 +143,14 @@ namespace logfile } } - scr_player_damage_hook.invoke(self, inflictor, attacker, damage, dflags, meansOfDeath, weapon, isAlternate, vPoint, vDir, hitLoc, timeOffset); + scr_player_damage_hook.invoke(self, inflictor, attacker, damage, dflags, + meansOfDeath, weapon, isAlternate, vPoint, vDir, hitLoc, timeOffset); } void client_command_stub(const int clientNum) { auto self = &game::mp::g_entities[clientNum]; - char cmd[1024]{}; + char cmd[1024] = {0}; game::SV_Cmd_ArgvBuffer(0, cmd, 1024); @@ -160,13 +163,13 @@ namespace logfile message.erase(0, hidden ? 2 : 1); scheduler::once([cmd, message, self]() - { - const scripting::entity level{ *game::levelEntityId }; - const auto player = scripting::call("getEntByNum", { self->s.entityNum }).as(); + { + const scripting::entity level{*game::levelEntityId}; + const scripting::entity player{game::Scr_GetEntityId(self->s.entityNum, 0)}; - scripting::notify(level, cmd, { player, message }); - scripting::notify(player, cmd, { message }); - }, scheduler::pipeline::server); + scripting::notify(level, cmd, {player, message}); + scripting::notify(player, cmd, {message}); + }, scheduler::pipeline::server); if (hidden) { @@ -175,18 +178,18 @@ namespace logfile } // ClientCommand - return reinterpret_cast(0x140336000)(clientNum); + return utils::hook::invoke(0x140336000, clientNum); } void g_shutdown_game_stub(const int freeScripts) { { - const scripting::entity level{ *game::levelEntityId }; - scripting::notify(level, "shutdownGame_called", { 1 }); + const scripting::entity level{*game::levelEntityId}; + scripting::notify(level, "shutdownGame_called", {1}); } // G_ShutdownGame - return reinterpret_cast(0x140345A60)(freeScripts); + return utils::hook::invoke(0x140345A60, freeScripts); } unsigned int local_id_to_entity(unsigned int local_id) @@ -249,10 +252,9 @@ namespace logfile a.movzx(r15d, byte_ptr(r14)); a.inc(r14); - a.lea(eax, dword_ptr(r15, -0x17)); - a.mov(dword_ptr(rbp, 0x68), r15d); + a.mov(dword_ptr(rbp, 0xA4), r15d); - a.jmp(0x140444653); + a.jmp(SELECT_VALUE(0x140376663, 0x140444653)); a.bind(replace); @@ -294,20 +296,18 @@ namespace logfile public: void post_unpack() override { - if (game::environment::is_sp()) + if (!game::environment::is_sp()) { - return; + utils::hook::call(0x14048191D, client_command_stub); + + scr_player_damage_hook.create(0x14037DC50, scr_player_damage_stub); + scr_player_killed_hook.create(0x14037DF30, scr_player_killed_stub); + + utils::hook::call(0x140484EC0, g_shutdown_game_stub); + utils::hook::call(0x1404853C1, g_shutdown_game_stub); } - utils::hook::call(0x14048191D, client_command_stub); - - scr_player_damage_hook.create(0x14037DC50, scr_player_damage_stub); - scr_player_killed_hook.create(0x14037DF30, scr_player_killed_stub); - - utils::hook::call(0x140484EC0, g_shutdown_game_stub); - utils::hook::call(0x1404853C1, g_shutdown_game_stub); - - utils::hook::jump(0x140444645, utils::hook::assemble(vm_execute_stub), true); + utils::hook::jump(SELECT_VALUE(0x140376655, 0x140444645), utils::hook::assemble(vm_execute_stub), true); } }; } diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index 99988189..6cdb54e0 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -15,6 +15,7 @@ namespace scripting { + std::unordered_map> fields_table; std::unordered_map> script_function_table; namespace @@ -23,6 +24,8 @@ namespace scripting utils::hook::detour scr_load_level_hook; utils::hook::detour g_shutdown_game_hook; + utils::hook::detour scr_add_class_field_hook; + utils::hook::detour scr_set_thread_position_hook; utils::hook::detour process_script_hook; @@ -45,7 +48,7 @@ namespace scripting e.arguments.emplace_back(*value); } - if (e.name == "connected") + if (e.name == "entitydeleted") { scripting::clear_entity_fields(e.entity); } @@ -72,6 +75,18 @@ namespace scripting return g_shutdown_game_hook.invoke(free_scripts); } + void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t _name, unsigned int canonicalString, unsigned int offset) + { + const auto name = game::SL_ConvertToString(_name); + + if (fields_table[classnum].find(name) == fields_table[classnum].end()) + { + fields_table[classnum][name] = offset; + } + + scr_add_class_field_hook.invoke(classnum, _name, canonicalString, offset); + } + void process_script_stub(const char* filename) { const auto file_id = atoi(filename); @@ -100,18 +115,25 @@ namespace scripting public: void post_unpack() override { - vm_notify_hook.create(SELECT_VALUE(0x140320E50, 0x1404479F0 ), vm_notify_stub); // H1MP - // SP address is wrong, but should be ok - scr_load_level_hook.create(SELECT_VALUE(0x140005260, 0x1403727C0), scr_load_level_stub); // H1MP - g_shutdown_game_hook.create(SELECT_VALUE(0x140228BA0, 0x140345A60), g_shutdown_game_stub); // H1MP + if (game::environment::is_sp()) + { + return; + } - scr_set_thread_position_hook.create(SELECT_VALUE(0x1403115E0, 0x140437D10), scr_set_thread_position_stub); // H1MP - process_script_hook.create(SELECT_VALUE(0x14031AB30, 0x1404417E0), process_script_stub); // H1MP + vm_notify_hook.create(SELECT_VALUE(0x140379A00, 0x1404479F0), vm_notify_stub); + + scr_add_class_field_hook.create(SELECT_VALUE(0x140370370, 0x14043E2C0), scr_add_class_field_stub); + + scr_set_thread_position_hook.create(SELECT_VALUE(0x14036A180, 0x140437D10), scr_set_thread_position_stub); + process_script_hook.create(SELECT_VALUE(0x1403737E0, 0x1404417E0), process_script_stub); + + scr_load_level_hook.create(0x1403727C0, scr_load_level_stub); + g_shutdown_game_hook.create(0x140345A60, g_shutdown_game_stub); scheduler::loop([]() - { - lua::engine::run_frame(); - }, scheduler::pipeline::server); + { + lua::engine::run_frame(); + }, scheduler::pipeline::server); } }; } diff --git a/src/client/component/scripting.hpp b/src/client/component/scripting.hpp index 5794bff2..865ae858 100644 --- a/src/client/component/scripting.hpp +++ b/src/client/component/scripting.hpp @@ -3,9 +3,6 @@ namespace scripting { - using shared_table_t = std::unordered_map; - extern std::unordered_map> fields_table; extern std::unordered_map> script_function_table; - extern utils::concurrency::container shared_table; } \ No newline at end of file diff --git a/src/client/game/scripting/execution.cpp b/src/client/game/scripting/execution.cpp index ba4e4abd..29faaad4 100644 --- a/src/client/game/scripting/execution.cpp +++ b/src/client/game/scripting/execution.cpp @@ -26,19 +26,9 @@ namespace scripting int get_field_id(const int classnum, const std::string& field) { - const auto class_id = game::g_classMap[classnum].id; - const auto field_str = game::SL_GetString(field.data(), 0); - const auto _ = gsl::finally([field_str]() + if (scripting::fields_table[classnum].find(field) != scripting::fields_table[classnum].end()) { - game::RemoveRefToValue(game::SCRIPT_STRING, {static_cast(field_str)}); - }); - - const auto offset = game::FindVariable(class_id, field_str); - if (offset) - { - const auto index = 3 * (offset + 0xFA00 * (class_id & 3)); - const auto id = reinterpret_cast(SELECT_VALUE(0x149BB5680, 0x14821DF80))[index]; - return static_cast(id); + return scripting::fields_table[classnum][field]; } return -1; diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 6eac3d97..db1cead0 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -3,1533 +3,3478 @@ // This file has been generated. // Do not touch! +// https://github.com/xensik/gsc-tool/blob/dev/src/h1/xsk/resolver.cpp :) + namespace scripting { std::unordered_map function_map = { - {"precacheturret", 0}, - {"getweaponarray", 1}, - {"getnumparam", 15}, - {"getnumparam", 16}, - {"spawnturret", 23}, - {"canspawnturret", 24}, - {"assertexcmd", 25}, - {"badplace_delete", 30}, - {"badplace_cylinder", 31}, - {"badplace_arc", 32}, - {"badplace_brush", 33}, - {"assertexcmd0", 44}, - {"isdefined", 46}, - {"isvalidmissile", 47}, - {"isstring", 48}, - {"setomnvar", 49}, - {"getomnvar", 50}, - {"setdvar", 51}, - {"setdynamicdvar", 52}, - {"setdvarifuninitialized", 53}, - {"setdevdvar", 54}, - {"setdevdvarifuninitialized", 55}, - {"getdvar", 56}, - {"getdvarint", 57}, - {"getdvarfloat", 58}, - {"getdvarvector", 59}, - {"gettime", 60}, - {"getutc", 61}, - {"getradiometricunit", 62}, - {"getentbynum", 63}, - {"getweaponmodel", 64}, - {"setsunlight", 68}, - {"resetsunlight", 69}, - {"getweapondisplayname", 92}, - {"getweaponbasename", 93}, - {"getweaponattachments", 94}, - {"getweaponattachmentdisplaynames", 95}, - {"getweaponcamoname", 96}, - {"getweaponreticlename", 97}, - {"getanimlength", 98}, - {"animhasnotetrack", 99}, - {"getnotetracktimes", 100}, - {"spawn", 101}, - {"spawnloopingsound", 103}, - {"bullettrace", 104}, - {"getstartorigin", 108}, - {"getstartangles", 109}, - {"magicgrenademanual", 112}, - {"sub_140311ad0", 117}, - {"sub_140311d80", 118}, - {"sub_140311d90", 119}, - {"sub_140311df0", 120}, - {"sub_140311ef0", 121}, - {"sub_140311f50", 122}, - {"sub_14031fb60", 127}, - {"bullettracepassed", 138}, - {"sighttracepassed", 139}, - {"physicstrace", 140}, - {"playerphysicstrace", 141}, - {"getgroundposition", 142}, - {"getmovedelta", 143}, - {"getangledelta", 144}, - {"getnorthyaw", 145}, - {"setnorthyaw", 172}, - {"setslowmotion", 173}, - {"randomint", 174}, - {"randomfloat", 175}, - {"randomintrange", 176}, - {"randomfloatrange", 177}, - {"sin", 178}, - {"cos", 179}, - {"tan", 180}, - {"asin", 181}, - {"acos", 182}, - {"atan", 183}, - {"castint", 184}, - {"castfloat", 185}, - {"abs", 186}, - {"min", 187}, - {"getnode", 191}, - {"getnodearray", 192}, - {"getallnodes", 193}, - {"getnodesinradius", 194}, - {"getnodesinradiussorted", 195}, - {"getclosestnodeinsight", 196}, - {"isarray", 202}, - {"isai", 203}, - {"getindexforluincstring", 204}, - {"issentient", 205}, - {"max", 221}, - {"floor", 222}, - {"ceil", 223}, - {"exp", 224}, - {"log", 225}, - {"sqrt", 226}, - {"squared", 227}, - {"clamp", 228}, - {"angleclamp360", 229}, - {"angleclamp180", 230}, - {"vectorfromlinetopoint", 231}, - {"pointonsegmentnearesttopoint", 232}, - {"distance", 233}, - {"distance2d", 234}, - {"distancesquared", 235}, - {"length", 236}, - {"length2d", 237}, - {"lengthsquared", 238}, - {"length2dsquared", 239}, - {"closer", 240}, - {"vectordot", 241}, - {"vectorcross", 242}, - {"axistoangles", 243}, - {"visionsetthermal", 244}, - {"visionsetpain", 245}, - {"startservermigration", 246}, - {"setac130ambience", 247}, - {"getmapcustomfield", 248}, - {"spawnsighttrace", 249}, - {"incrementcounter", 250}, - {"getcountertotal", 251}, - {"createthreatbiasgroup", 258}, - {"threatbiasgroupexists", 259}, - {"getthreatbias", 260}, - {"setthreatbias", 261}, - {"setthreatbiasagainstall", 262}, - {"setignoremegroup", 263}, - {"isenemyteam", 264}, - {"vectornormalize", 271}, - {"vectortoangles", 272}, - {"vectortoyaw", 273}, - {"vectorlerp", 274}, - {"anglestoup", 275}, - {"anglestoright", 276}, - {"anglestoforward", 277}, - {"anglesdelta", 278}, - {"combineangles", 279}, - {"transformmove", 280}, - {"rotatevector", 281}, - {"rotatepointaroundvector", 282}, - {"issubstr", 283}, - {"isendstr", 284}, - {"getsubstr", 285}, - {"tolower", 286}, - {"strtok", 287}, - {"stricmp", 288}, - {"ambientplay", 289}, - {"getuavstrengthmax", 290}, - {"getuavstrengthlevelneutral", 291}, - {"getuavstrengthlevelshowenemyfastsweep", 292}, - {"getuavstrengthlevelshowenemydirectional", 293}, - {"blockteamradar", 294}, - {"unblockteamradar", 295}, - {"isteamradarblocked", 296}, - {"sub_140328710", 297}, - {"setmatchdata", 298}, - {"getmatchdata", 299}, - {"sendmatchdata", 300}, - {"clearmatchdata", 301}, - {"setmatchdatadef", 302}, - {"setmatchclientip", 303}, - {"setmatchdataid", 304}, - {"setclientmatchdata", 305}, - {"getclientmatchdata", 306}, - {"setclientmatchdatadef", 307}, - {"sendclientmatchdata", 308}, - {"getbuildversion", 309}, - {"getbuildnumber", 310}, - {"getsystemtime", 311}, - {"getmatchrulesdata", 312}, - {"isusingmatchrulesdata", 313}, - {"kickplayer", 314}, - {"issplitscreen", 315}, - {"setmapcenter", 316}, - {"setgameendtime", 317}, - {"visionsetnaked", 318}, - {"visionsetnight", 319}, - {"visionsetmissilecam", 320}, - {"ambientstop", 321}, - {"precachemodel", 322}, - {"precacheshellshock", 323}, - {"precacheitem", 324}, - {"precachematerial", 325}, - {"precachestring", 326}, - {"precachemenu", 327}, - {"precacherumble", 328}, - {"precachelocationselector", 329}, - {"precacheleaderboards", 330}, - {"loadfx", 331}, - {"playfx", 332}, - {"playfxontag", 333}, - {"stopfxontag", 334}, - {"killfxontag", 335}, - {"playloopedfx", 336}, - {"spawnfx", 337}, - {"triggerfx", 338}, - {"playfxontagforclients", 339}, - {"sub_1403326a0", 340}, - {"sub_14031be80", 341}, - {"setwinningteam", 342}, - {"announcement", 343}, - {"clientannouncement", 344}, - {"setteammode", 345}, - {"getteamscore", 346}, - {"setteamscore", 347}, - {"setclientnamemode", 348}, - {"updateclientnames", 349}, - {"getteamplayersalive", 350}, - {"worldentnumber", 352}, - {"obituary", 353}, - {"positionwouldtelefrag", 354}, - {"canspawn", 355}, - {"getstarttime", 356}, - {"precacheheadicon", 357}, - {"precacheminimapicon", 358}, - {"precachempanim", 359}, - {"maprestart", 360}, - {"exitlevel", 361}, - {"addtestclient", 362}, - {"addagent", 363}, - {"allclientsprint", 365}, - {"clientprint", 366}, - {"mapexists", 367}, - {"isvalidgametype", 368}, - {"setplayerteamrank", 370}, - {"setteamradar", 372}, - {"getteamradar", 373}, - {"setteamradarstrength", 374}, - {"getteamradarstrength", 375}, - {"getuavstrengthmin", 376}, - {"physicsexplosionsphere", 377}, - {"physicsexplosioncylinder", 378}, - {"physicsradiusjolt", 379}, - {"physicsradiusjitter", 380}, - {"setexpfog", 381}, - {"setexpfogext", 382}, - {"setexpfogdvarsonly", 383}, - {"setexpfogextdvarsonly", 384}, - {"setatmosfog", 385}, - {"setatmosfogdvarsonly", 386}, - {"isexplosivedamagemod", 387}, - {"radiusdamage", 388}, - {"setplayerignoreradiusdamage", 389}, - {"glassradiusdamage", 390}, - {"earthquake", 391}, - {"getnumparts", 392}, - {"objective_onentity", 393}, - {"objective_onentitywithrotation", 394}, - {"objective_team", 395}, - {"objective_player", 396}, - {"objective_playerteam", 397}, - {"objective_playerenemyteam", 398}, - {"objective_playermask_hidefromall", 399}, - {"objective_playermask_hidefrom", 400}, - {"objective_playermask_showtoall", 401}, - {"objective_playermask_showto", 402}, - {"iprintln", 403}, - {"iprintlnbold", 404}, - {"getent", 406}, - {"getentarray", 407}, - {"getspawnarray", 408}, - {"spawnplane", 409}, - {"addstruct", 410}, - {"spawnhelicopter", 411}, - {"isalive", 412}, - {"isspawner", 413}, - {"missilecreateattractorent", 414}, - {"missilecreateattractororigin", 415}, - {"missilecreaterepulsorent", 416}, - {"missilecreaterepulsororigin", 417}, - {"missiledeleteattractor", 418}, - {"playsoundatpos", 419}, - {"newhudelem", 420}, - {"newclienthudelem", 421}, - {"newteamhudelem", 422}, - {"resettimeout", 423}, - {"isplayer", 424}, - {"isplayernumber", 425}, - {"getpartname", 426}, - {"weaponfiretime", 427}, - {"weaponclipsize", 428}, - {"weaponisauto", 429}, - {"weaponissemiauto", 430}, - {"weaponisboltaction", 431}, - {"weaponinheritsperks", 432}, - {"weaponburstcount", 433}, - {"weapontype", 434}, - {"weaponclass", 435}, - {"getnextarraykey", 436}, - {"sortbydistance", 437}, - {"tablelookup", 438}, - {"tablelookupbyrow", 439}, - {"tablelookupistring", 440}, - {"tablelookupistringbyrow", 441}, - {"tablelookuprownum", 442}, - {"tableexists", 443}, - {"getmissileowner", 444}, - {"magicbullet", 445}, - {"getweaponflashtagname", 446}, - {"averagepoint", 447}, - {"averagenormal", 448}, - {"getspawnerarray", 449}, - {"playrumbleonposition", 450}, - {"playrumblelooponposition", 451}, - {"stopallrumbles", 452}, - {"soundexists", 453}, - {"setminimap", 460}, - {"setthermalbodymaterial", 461}, - {"getarraykeys", 462}, - {"getfirstarraykey", 463}, - {"getglass", 464}, - {"getglassarray", 465}, - {"getglassorigin", 466}, - {"isglassdestroyed", 467}, - {"destroyglass", 468}, - {"deleteglass", 469}, - {"getentchannelscount", 470}, - {"getentchannelname", 471}, - {"objective_add", 472}, - {"objective_delete", 473}, - {"objective_state", 474}, - {"objective_icon", 475}, - {"objective_position", 476}, - {"objective_current", 477}, - {"weaponinventorytype", 478}, - {"weaponstartammo", 479}, - {"weaponmaxammo", 480}, - {"weaponaltweaponname", 481}, - {"isweaponcliponly", 482}, - {"sub_14030dfc0", 483}, - {"sub_14030e400", 484}, - {"weaponhasthermalscope", 485}, - {"getvehiclenode", 486}, - {"getvehiclenodearray", 487}, - {"getallvehiclenodes", 488}, - {"getactivecount", 489}, - {"precache", 490}, - {"spawnvehicle", 491}, - {"getarray", 492}, - {"pow", 493}, - {"atan2", 494}, - {"botgetmemoryevents", 495}, - {"botautoconnectenabled", 496}, - {"botzonegetcount", 497}, - {"botzonesetteam", 498}, - {"botzonenearestcount", 499}, - {"botmemoryflags", 500}, - {"botflagmemoryevents", 501}, - {"botzonegetindoorpercent", 502}, - {"botsentientswap", 503}, - {"isbot", 504}, - {"isagent", 505}, - {"getmaxagents", 506}, - {"botgetclosestnavigablepoint", 508}, - {"getnodesintrigger", 509}, - {"nodesvisible", 510}, - {"getnodesonpath", 511}, - {"getzonecount", 512}, - {"getzonenearest", 513}, - {"getzonenodes", 514}, - {"getzonepath", 515}, - {"getzoneorigin", 516}, - {"getnodezone", 517}, - {"getzonenodesbydist", 518}, - {"getzonenodeforindex", 519}, - {"getweaponexplosionradius", 520}, - {"nodeexposedtosky", 523}, - {"findentrances", 524}, - {"badplace_global", 525}, - {"getpathdist", 526}, - {"getlinkednodes", 527}, - {"disconnectnodepair", 528}, - {"connectnodepair", 529}, - {"precachesound", 533}, - {"distance2dsquared", 543}, - {"getangledelta3d", 544}, - {"activateclientexploder", 545}, - {"trajectorycalculateinitialvelocity", 546}, - {"trajectorycalculateminimumvelocity", 547}, - {"trajectorycalculateexitangle", 548}, - {"trajectoryestimatedesiredinairtime", 549}, - {"trajectorycomputedeltaheightattime", 550}, - {"trajectorycanattemptaccuratejump", 551}, - {"ispointinvolume", 553}, - {"getscriptablearray", 560}, - {"clearfog", 561}, - {"setleveldopplerpreset", 562}, - {"isusinghdr", 564}, - {"sub_140321c40", 565}, - {"sub_140311a40", 567}, - {"sub_14030ec50", 568}, - {"sub_14030f050", 569}, - {"sub_14030f340", 570}, - {"sub_14030f550", 571}, - {"sub_14030f710", 572}, - {"sub_1403295e0", 573}, - {"sub_140322690", 574}, - {"sub_140329600", 575}, - {"sub_14031a690", 580}, - {"sub_1403163c0", 581}, - {"anglestoaxis", 582}, - {"invertangles", 587}, - {"rotatevectorinverted", 588}, - {"calculatestartorientation", 589}, - {"droptoground", 590}, - {"precachelaser", 592}, - {"getcsplinecount", 593}, - {"getcsplinepointcount", 594}, - {"getcsplinelength", 595}, - {"getcsplinepointid", 596}, - {"getcsplinepointlabel", 597}, - {"getcsplinepointtension", 598}, - {"getcsplinepointposition", 599}, - {"getcsplinepointcorridordims", 600}, - {"getcsplinepointtangent", 601}, - {"getcsplinepointdisttonextpoint", 602}, - {"calccsplineposition", 603}, - {"calccsplinetangent", 604}, - {"calccsplinecorridor", 605}, - {"setnojipscore", 606}, - {"setnojiptime", 607}, - {"getpredictedentityposition", 608}, - {"queuedialog", 615}, - {"triggerportableradarping", 622}, - {"botgetteamlimit", 624}, - {"spawnfxforclient", 625}, - {"botgetteamdifficulty", 626}, - {"loadluifile", 632}, - {"isdedicatedserver", 633}, - {"getplaylistversion", 634}, - {"getplaylistid", 635}, - {"getactiveclientcount", 636}, - {"issquadsmode", 637}, - {"visionsetpostapply", 639}, - {"addbot", 640}, - {"sub_140310ec0", 641}, - {"sub_14031bae0", 642}, - {"sub_14031c2b0", 643}, - {"isalliedsentient", 644}, - {"istestclient", 645}, - {"sub_1402d2850", 646}, - {"sub_140311ff0", 648}, - {"sub_140312040", 649}, - {"sub_140311100", 651}, - {"sub_140314c70", 652}, - {"sub_14030d340", 653}, - {"sub_14030da60", 654}, - {"sub_14030e5c0", 655}, - {"sub_14031fda0", 657}, - {"sub_140317140", 658}, - {"isremovedentity", 659}, - {"tablegetrowcount", 660}, - {"tablegetcolumncount", 661}, - {"batteryusepershot", 662}, - {"batteryreqtouse", 663}, - {"sub_14030e700", 664}, - {"getentityweaponname", 666}, - {"sub_14031fc20", 667}, - {"deployriotshield", 668}, - {"validatecostume", 669}, - {"randomcostume", 670}, - {"shootblank", 671}, - {"debugstringtostring", 673}, - {"sub_140319680", 675}, - {"playcinematicforall", 679}, - {"preloadcinematicforall", 680}, - {"stopcinematicforall", 681}, - {"capsuletracepassed", 682}, - {"sub_14031ca40", 683}, - {"sub_14031e1f0", 684}, - {"sub_140321880", 685}, - {"lootservicestarttrackingplaytime", 687}, - {"sub_1403297b0", 688}, - {"lootservicevalidateplaytime", 689}, - {"recordbreadcrumbdataforplayer", 690}, - {"sub_140317df0", 691}, - {"sysprint", 693}, - {"sub_140337920", 694}, - {"sub_140321ae0", 697}, - {"isonlinegame", 698}, - {"issystemlink", 699}, - {"getstanceandmotionstateforplayer", 701}, - {"sub_1402d3540", 702}, - {"sub_1402d35b0", 703}, - {"sub_140332a70", 704}, - {"sub_140332ae0", 705}, - {"getplaylistname", 706}, - {"getlocaltime", 707}, - {"sub_14032c820", 708}, - {"getchallengeid", 710}, - {"nodegetremotemissilename", 711}, - {"nodehasremotemissileset", 712}, - {"remotemissileenttracetooriginpassed", 713}, - {"bombingruntracepassed", 714}, - {"handlepickupdeployedriotshield", 716}, - {"sub_14032c6b0", 717}, - {"getcostumefromtable", 718}, - {"sub_1402d3460", 720}, - {"getchallenerewarditem", 722}, - {"setentplayerxuidforemblem", 723}, - {"resetentplayerxuidforemblems", 724}, - {"nodesetremotemissilename", 725}, - {"sub_14031aa80", 726}, - {"sub_14031ead0", 727}, - {"iszombie", 728}, - {"sub_14031b670", 729}, - {"sub_14031d3f0", 730}, - {"sub_14031e670", 731}, - {"getactiveplayerlist", 732}, - {"sub_140319200", 733}, - {"sub_140331e00", 734}, + {"_func_001", 0x001}, // SP 0x14029D940 MP 0x140368EA0 + {"_func_002", 0x002}, // SP 0x14028F750 MP 0x140357B80 + {"_func_003", 0x003}, // SP 0x1405D92F0 MP 0x1403668A0 + {"_func_004", 0x004}, // SP 0x1402ACD70 MP 0x000000000 + {"_func_005", 0x005}, // SP 0x1402ADB70 MP 0x000000000 + {"_func_006", 0x006}, // SP 0x1402A8E20 MP 0x000000000 + {"_func_007", 0x007}, // SP 0x1402A8B20 MP 0x000000000 + {"_func_008", 0x008}, // SP 0x1402A8B40 MP 0x000000000 + {"_func_009", 0x009}, // SP 0x1402A8BC0 MP 0x000000000 + {"_func_00A", 0x00A}, // SP 0x1402A8B60 MP 0x000000000 + {"_func_00B", 0x00B}, // SP 0x1402A8960 MP 0x000000000 + {"_func_00C", 0x00C}, // SP 0x1402ADBE0 MP 0x000000000 + {"_func_00D", 0x00D}, // SP 0x1402ADC60 MP 0x000000000 + {"_func_00E", 0x00E}, // SP 0x1402ADC90 MP 0x000000000 + {"_func_00F", 0x00F}, // SP 0x1405D92F0 MP 0x1403669E0 + {"_func_010", 0x010}, // SP 0x14029AF60 MP 0x1403669F0 + {"_func_011", 0x011}, // SP 0x14029AF60 MP 0x140366D40 + {"_func_012", 0x012}, // SP 0x1405D92F0 MP 0x140367400 + {"_func_013", 0x013}, // SP 0x1405D92F0 MP 0x140367520 + {"_func_014", 0x014}, // SP 0x1405D92F0 MP 0x140367530 + {"_func_015", 0x015}, // SP 0x1405D92F0 MP 0x1403675E0 + {"_func_016", 0x016}, // SP 0x1405D92F0 MP 0x140367660 + {"_func_017", 0x017}, // SP 0x1405D92F0 MP 0x140367890 + {"_func_018", 0x018}, // SP 0x14029D650 MP 0x140368B10 + {"_func_019", 0x019}, // SP 0x14029D870 MP 0x140368E80 + {"_func_01A", 0x01A}, // SP 0x14029C9B0 MP 0x1403678A0 + {"_func_01B", 0x01B}, // SP 0x1402AB640 MP 0x000000000 + {"_func_01C", 0x01C}, // SP 0x1402AB670 MP 0x000000000 + {"_func_01D", 0x01D}, // SP 0x1402AB7A0 MP 0x000000000 + {"_func_01E", 0x01E}, // SP 0x1402AB960 MP 0x000000000 + {"_func_01F", 0x01F}, // SP 0x14028F340 MP 0x140358600 + {"_func_020", 0x020}, // SP 0x14028F4B0 MP 0x140358C50 + {"_func_021", 0x021}, // SP 0x14028F830 MP 0x140359110 + {"_func_022", 0x022}, // SP 0x14028FF10 MP 0x140359CB0 + {"_func_023", 0x023}, // SP 0x1402AC9D0 MP 0x000000000 + {"_func_024", 0x024}, // SP 0x1402CC640 MP 0x000000000 + {"_func_025", 0x025}, // SP 0x1402CC6E0 MP 0x000000000 + {"_func_026", 0x026}, // SP 0x1402CC570 MP 0x000000000 + {"_func_027", 0x027}, // SP 0x1402CC430 MP 0x000000000 + {"_func_02A", 0x02A}, // SP 0x1405D92F0 MP 0x000000000 + {"_func_02B", 0x02B}, // SP 0x1405D92F0 MP 0x000000000 + {"_func_02C", 0x02C}, // SP 0x1402ACD10 MP 0x000000000 + {"_func_02D", 0x02D}, // SP 0x14029C9B0 MP 0x140367950 + {"_func_02E", 0x02E}, // SP 0x14029CAC0 MP 0x140367980 + {"_func_02F", 0x02F}, // SP 0x14029D000 MP 0x140368520 + {"_func_030", 0x030}, // SP 0x14029D3E0 MP 0x140368A70 + {"_func_031", 0x031}, // SP 0x14029D630 MP 0x140368D30 + {"_func_032", 0x032}, // SP 0x14029E0A0 MP 0x14036A580 + {"_func_033", 0x033}, // SP 0x14029E220 MP 0x14036A7C0 + {"_func_034", 0x034}, // SP 0x14029EB20 MP 0x14036AE70 + {"_func_035", 0x035}, // SP 0x000000000 MP 0x14036B600 + {"_func_036", 0x036}, // SP 0x14029F8F0 MP 0x14036BB60 + {"_func_037", 0x037}, // SP 0x14029F1C0 MP 0x14036B7F0 + {"_func_038", 0x038}, // SP 0x14029F8F0 MP 0x14036C070 + {"_func_039", 0x039}, // SP 0x14029FE30 MP 0x14036C350 + {"_func_03A", 0x03A}, // SP 0x1402A0270 MP 0x14036C7B0 + {"_func_03B", 0x03B}, // SP 0x1402A0810 MP 0x14036CDD0 + {"_func_03C", 0x03C}, // SP 0x1402A10E0 MP 0x14036D190 + {"_func_03D", 0x03D}, // SP 0x1402A1A50 MP 0x14036DB40 + {"_func_03E", 0x03E}, // SP 0x1402A1A60 MP 0x14036DD80 + {"_func_03F", 0x03F}, // SP 0x1402A1AC0 MP 0x14036DDA0 + {"_func_040", 0x040}, // SP 0x1402A1C50 MP 0x14036DF50 + {"_func_041", 0x041}, // SP 0x1402A1D10 MP 0x000000000 + {"_func_042", 0x042}, // SP 0x1402A1D20 MP 0x000000000 + {"_func_043", 0x043}, // SP 0x1402A1D30 MP 0x14036E110 + {"_func_044", 0x044}, // SP 0x1402ABBE0 MP 0x000000000 + {"_func_045", 0x045}, // SP 0x1402ABCF0 MP 0x000000000 + {"_func_046", 0x046}, // SP 0x1402ABD30 MP 0x000000000 + {"_func_047", 0x047}, // SP 0x1402ABD90 MP 0x1403775E0 + {"_func_048", 0x048}, // SP 0x1402ABE60 MP 0x140377840 + {"_func_049", 0x049}, // SP 0x1402ABF90 MP 0x000000000 + {"_func_04A", 0x04A}, // SP 0x1402ABFC0 MP 0x000000000 + {"_func_04B", 0x04B}, // SP 0x1402AC0E0 MP 0x000000000 + {"_func_04C", 0x04C}, // SP 0x1402AC210 MP 0x000000000 + {"_func_04D", 0x04D}, // SP 0x1402AC520 MP 0x000000000 + {"_func_04E", 0x04E}, // SP 0x1402AC6F0 MP 0x000000000 + {"_func_04F", 0x04F}, // SP 0x1402AC720 MP 0x000000000 + {"_func_050", 0x050}, // SP 0x1402AC740 MP 0x000000000 + {"_func_051", 0x051}, // SP 0x1402AC760 MP 0x000000000 + {"_func_052", 0x052}, // SP 0x1402AC780 MP 0x000000000 + {"_func_053", 0x053}, // SP 0x1402AC830 MP 0x000000000 + {"_func_054", 0x054}, // SP 0x1402AD6E0 MP 0x000000000 + {"_func_055", 0x055}, // SP 0x1402AAEC0 MP 0x000000000 + {"_func_056", 0x056}, // SP 0x1402AAF60 MP 0x000000000 + {"_func_057", 0x057}, // SP 0x1402AB040 MP 0x000000000 + {"_func_058", 0x058}, // SP 0x1402AB060 MP 0x000000000 + {"_func_059", 0x059}, // SP 0x1402AB140 MP 0x000000000 + {"_func_05A", 0x05A}, // SP 0x1402AB1E0 MP 0x000000000 + {"_func_05B", 0x05B}, // SP 0x1402AB2A0 MP 0x000000000 + {"_func_05C", 0x05C}, // SP 0x1402AB420 MP 0x000000000 + {"_func_05D", 0x05D}, // SP 0x1402AB4A0 MP 0x000000000 + {"_func_05E", 0x05E}, // SP 0x1402AB620 MP 0x000000000 + {"_func_05F", 0x05F}, // SP 0x1402A2410 MP 0x14036E740 + {"_func_060", 0x060}, // SP 0x1402A2910 MP 0x14036ED60 + {"_func_061", 0x061}, // SP 0x1402A3170 MP 0x14036F3E0 + {"_func_062", 0x062}, // SP 0x1402A34D0 MP 0x140357CA0 + {"_func_063", 0x063}, // SP 0x14028DEA0 MP 0x140358890 + {"_func_064", 0x064}, // SP 0x14028E0B0 MP 0x140358B80 + {"_func_065", 0x065}, // SP 0x14028FB80 MP 0x14035AB80 + {"_func_066", 0x066}, // SP 0x14028FD60 MP 0x14035B110 + {"_func_067", 0x067}, // SP 0x14028FDC0 MP 0x14035B220 + {"_func_068", 0x068}, // SP 0x14029D0C0 MP 0x140368410 + {"_func_069", 0x069}, // SP 0x14029D0C0 MP 0x140368410 + {"_func_06A", 0x06A}, // SP 0x140444BB0 MP 0x14036AF90 + {"_func_06B", 0x06B}, // SP 0x14029E950 MP 0x140366EF0 + {"_func_06C", 0x06C}, // SP 0x1402BBCA0 MP 0x000000000 + {"_func_06D", 0x06D}, // SP 0x1402BB830 MP 0x000000000 + {"_func_06E", 0x06E}, // SP 0x1402BB990 MP 0x000000000 + {"_func_06F", 0x06F}, // SP 0x14025D860 MP 0x140375D40 + {"_func_070", 0x070}, // SP 0x14025D770 MP 0x140375F10 + {"_func_071", 0x071}, // SP 0x14025D630 MP 0x000000000 + {"_func_072", 0x072}, // SP 0x1402AB510 MP 0x000000000 + {"_func_073", 0x073}, // SP 0x1402981B0 MP 0x140364BC0 + {"_func_074", 0x074}, // SP 0x1402AFD80 MP 0x000000000 + {"_func_075", 0x075}, // SP 0x1402AFEA0 MP 0x000000000 + {"_func_076", 0x076}, // SP 0x1402A78A0 MP 0x000000000 + {"_func_077", 0x077}, // SP 0x1402A79D0 MP 0x000000000 + {"_func_078", 0x078}, // SP 0x14029E170 MP 0x140367970 + {"_func_079", 0x079}, // SP 0x14029E210 MP 0x140367990 + {"_func_07A", 0x07A}, // SP 0x14029E2D0 MP 0x140367D70 + {"_func_07B", 0x07B}, // SP 0x14029E320 MP 0x140367F30 + {"_func_07C", 0x07C}, // SP 0x14029E330 MP 0x140367F40 + {"_func_07D", 0x07D}, // SP 0x14029E730 MP 0x140367FA0 + {"_func_07E", 0x07E}, // SP 0x1402A7BF0 MP 0x000000000 + {"_func_07F", 0x07F}, // SP 0x1402A8BB0 MP 0x000000000 + {"_func_080", 0x080}, // SP 0x1402A7A80 MP 0x000000000 + {"_func_081", 0x081}, // SP 0x1402AAE30 MP 0x000000000 + {"_func_083", 0x083}, // SP 0x1402AAE50 MP 0x000000000 + {"_func_084", 0x084}, // SP 0x1402AAEA0 MP 0x000000000 + {"_func_085", 0x085}, // SP 0x1402A8CB0 MP 0x000000000 + {"_func_086", 0x086}, // SP 0x1402A9990 MP 0x000000000 + {"_func_087", 0x087}, // SP 0x1402A99B0 MP 0x000000000 + {"_func_088", 0x088}, // SP 0x1402A9100 MP 0x000000000 + {"_func_089", 0x089}, // SP 0x1402A99D0 MP 0x000000000 + {"_func_08A", 0x08A}, // SP 0x1402A9A70 MP 0x000000000 + {"_func_08B", 0x08B}, // SP 0x1402AB690 MP 0x000000000 + {"_func_08C", 0x08C}, // SP 0x1402ABB90 MP 0x000000000 + {"_func_08D", 0x08D}, // SP 0x14029F480 MP 0x140367410 + {"_func_08E", 0x08E}, // SP 0x14029F7A0 MP 0x140367670 + {"_func_08F", 0x08F}, // SP 0x14029FF90 MP 0x140367E20 + {"_func_090", 0x090}, // SP 0x1402A0360 MP 0x140368180 + {"_func_091", 0x091}, // SP 0x1402A2670 MP 0x14036A300 + {"_func_092", 0x092}, // SP 0x14028F3D0 MP 0x14036E210 + {"_func_093", 0x093}, // SP 0x14028FA60 MP 0x14036E910 + {"_func_094", 0x094}, // SP 0x1402903E0 MP 0x140357C50 + {"_func_095", 0x095}, // SP 0x1402A7970 MP 0x000000000 + {"_func_096", 0x096}, // SP 0x1402A7A50 MP 0x000000000 + {"_func_097", 0x097}, // SP 0x1402A9B20 MP 0x000000000 + {"_func_098", 0x098}, // SP 0x1402A9B70 MP 0x000000000 + {"_func_099", 0x099}, // SP 0x1402A9AE0 MP 0x000000000 + {"_func_09A", 0x09A}, // SP 0x1402AE4D0 MP 0x000000000 + {"_func_09B", 0x09B}, // SP 0x1402BB040 MP 0x000000000 + {"_func_09C", 0x09C}, // SP 0x1402BB410 MP 0x000000000 + {"_func_09D", 0x09D}, // SP 0x1402BB6F0 MP 0x000000000 + {"_func_09E", 0x09E}, // SP 0x1402BB6B0 MP 0x000000000 + {"_func_09F", 0x09F}, // SP 0x1402BC260 MP 0x000000000 + {"_func_0A0", 0x0A0}, // SP 0x1402BBF00 MP 0x000000000 + {"_func_0A1", 0x0A1}, // SP 0x1402BB590 MP 0x000000000 + {"_func_0A2", 0x0A2}, // SP 0x1402BB520 MP 0x000000000 + {"_func_0A3", 0x0A3}, // SP 0x1402BC390 MP 0x000000000 + {"_func_0A4", 0x0A4}, // SP 0x1402BB060 MP 0x000000000 + {"_func_0A5", 0x0A5}, // SP 0x1402BB4A0 MP 0x000000000 + {"_func_0A6", 0x0A6}, // SP 0x1402BB630 MP 0x000000000 + {"_func_0A7", 0x0A7}, // SP 0x1402BB710 MP 0x000000000 + {"_func_0A8", 0x0A8}, // SP 0x1402BBB80 MP 0x000000000 + {"_func_0A9", 0x0A9}, // SP 0x1402BB510 MP 0x000000000 + {"_func_0AA", 0x0AA}, // SP 0x1402BC380 MP 0x000000000 + {"_func_0AB", 0x0AB}, // SP 0x1402BC140 MP 0x000000000 + {"_func_0AC", 0x0AC}, // SP 0x1402BB090 MP 0x000000000 + {"_func_0AD", 0x0AD}, // SP 0x1402BB2C0 MP 0x000000000 + {"_func_0AE", 0x0AE}, // SP 0x1402BB1C0 MP 0x000000000 + {"_func_0AF", 0x0AF}, // SP 0x1402BBDB0 MP 0x000000000 + {"_func_0B0", 0x0B0}, // SP 0x140290420 MP 0x140357E90 + {"_func_0B1", 0x0B1}, // SP 0x14029BC60 MP 0x140365480 + {"_func_0B2", 0x0B2}, // SP 0x1402A2ED0 MP 0x14036A770 + {"_func_0B3", 0x0B3}, // SP 0x1402A3140 MP 0x14036A9E0 + {"_func_0B4", 0x0B4}, // SP 0x1402A3240 MP 0x14036ACD0 + {"_func_0B5", 0x0B5}, // SP 0x1402A3310 MP 0x14036AE10 + {"_func_0B6", 0x0B6}, // SP 0x1402A3440 MP 0x14036B240 + {"_func_0B7", 0x0B7}, // SP 0x1402A34A0 MP 0x14036B550 + {"_func_0B8", 0x0B8}, // SP 0x1402A3610 MP 0x14036B5A0 + {"_func_0B9", 0x0B9}, // SP 0x1402A37D0 MP 0x14036B720 + {"_func_0BA", 0x0BA}, // SP 0x1402A3A60 MP 0x14036B7A0 + {"_func_0BB", 0x0BB}, // SP 0x14028D680 MP 0x14036BAE0 + {"_func_0BC", 0x0BC}, // SP 0x14028DAE0 MP 0x14036BBF0 + {"_func_0BD", 0x0BD}, // SP 0x14028DE30 MP 0x14036C000 + {"_func_0BE", 0x0BE}, // SP 0x14028DFC0 MP 0x14036C320 + {"_func_0BF", 0x0BF}, // SP 0x14028DFF0 MP 0x14036C580 + {"_func_0C0", 0x0C0}, // SP 0x1402B7A30 MP 0x000000000 + {"_func_0C1", 0x0C1}, // SP 0x1402B7B50 MP 0x000000000 + {"_func_0C2", 0x0C2}, // SP 0x1402B7BF0 MP 0x000000000 + {"_func_0C3", 0x0C3}, // SP 0x1402CBED0 MP 0x14031FA00 + {"_func_0C4", 0x0C4}, // SP 0x1402CBFE0 MP 0x14031FB10 + {"_func_0C5", 0x0C5}, // SP 0x1402CBCD0 MP 0x14031F7E0 + {"_func_0C6", 0x0C6}, // SP 0x1402CC0F0 MP 0x14031FCC0 + {"_func_0C7", 0x0C7}, // SP 0x1402CC100 MP 0x14031FCD0 + {"_func_0C8", 0x0C8}, // SP 0x1402CBD20 MP 0x14031F830 + {"_func_0C9", 0x0C9}, // SP 0x1405D92F0 MP 0x000000000 + {"_func_0CA", 0x0CA}, // SP 0x1405D92F0 MP 0x000000000 + {"_func_0CB", 0x0CB}, // SP 0x140468CF0 MP 0x000000000 + {"_func_0CC", 0x0CC}, // SP 0x140468DD0 MP 0x000000000 + {"_func_0CD", 0x0CD}, // SP 0x140468CA0 MP 0x000000000 + {"_func_0CE", 0x0CE}, // SP 0x140291BF0 MP 0x14035E620 + {"_func_0CF", 0x0CF}, // SP 0x1402ADC10 MP 0x140377460 + {"_func_0D0", 0x0D0}, // SP 0x14029DB50 MP 0x140369C50 + {"_func_0D1", 0x0D1}, // SP 0x14029D7D0 MP 0x140368DA0 + {"_func_0D2", 0x0D2}, // SP 0x1402ADD90 MP 0x000000000 + {"_func_0D3", 0x0D3}, // SP 0x1402ADED0 MP 0x000000000 + {"_func_0D4", 0x0D4}, // SP 0x1402ADF60 MP 0x000000000 + {"_func_0D5", 0x0D5}, // SP 0x1402ADFD0 MP 0x000000000 + {"_func_0D6", 0x0D6}, // SP 0x1402AE020 MP 0x000000000 + {"_func_0D7", 0x0D7}, // SP 0x1402AE4E0 MP 0x000000000 + {"_func_0D8", 0x0D8}, // SP 0x1402AE4F0 MP 0x000000000 + {"_func_0D9", 0x0D9}, // SP 0x1402AE7A0 MP 0x000000000 + {"_func_0DA", 0x0DA}, // SP 0x1402AF980 MP 0x000000000 + {"_func_0DB", 0x0DB}, // SP 0x1402AFBD0 MP 0x000000000 + {"_func_0DC", 0x0DC}, // SP 0x1402AFB20 MP 0x000000000 + {"_func_0DD", 0x0DD}, // SP 0x1402AFCE0 MP 0x000000000 + {"_func_0DE", 0x0DE}, // SP 0x1402AFE20 MP 0x000000000 + {"_func_0DF", 0x0DF}, // SP 0x14029CAC0 MP 0x000000000 + {"_func_0E0", 0x0E0}, // SP 0x1402A7830 MP 0x000000000 + {"_func_0E1", 0x0E1}, // SP 0x14028E170 MP 0x14036C720 + {"_func_0E2", 0x0E2}, // SP 0x14028E1C0 MP 0x14036C750 + {"_func_0E3", 0x0E3}, // SP 0x14028E260 MP 0x14036C770 + {"_func_0E4", 0x0E4}, // SP 0x14028E280 MP 0x14036C790 + {"_func_0E5", 0x0E5}, // SP 0x14028E370 MP 0x14036C820 + {"_func_0E6", 0x0E6}, // SP 0x14028E410 MP 0x14036C840 + {"_func_0E7", 0x0E7}, // SP 0x14028E470 MP 0x14036CB80 + {"_func_0E8", 0x0E8}, // SP 0x14028E4B0 MP 0x14036CBA0 + {"_func_0E9", 0x0E9}, // SP 0x14028E770 MP 0x14036CE40 + {"_func_0EA", 0x0EA}, // SP 0x14028E8C0 MP 0x14036CF30 + {"_func_0EB", 0x0EB}, // SP 0x14028E920 MP 0x14036CFB0 + {"_func_0EC", 0x0EC}, // SP 0x140290740 MP 0x14036E5A0 + {"_func_0ED", 0x0ED}, // SP 0x140290B60 MP 0x14036EB30 + {"_func_0EE", 0x0EE}, // SP 0x140291260 MP 0x14036F6E0 + {"_func_0EF", 0x0EF}, // SP 0x1402913A0 MP 0x14036F790 + {"_func_0F0", 0x0F0}, // SP 0x140291600 MP 0x140357E10 + {"_func_0F1", 0x0F1}, // SP 0x1402918C0 MP 0x140357FB0 + {"_func_0F2", 0x0F2}, // SP 0x140291930 MP 0x140358030 + {"_func_0F3", 0x0F3}, // SP 0x140291AF0 MP 0x140358130 + {"_func_0F4", 0x0F4}, // SP 0x140291B30 MP 0x140358190 + {"_func_0F5", 0x0F5}, // SP 0x140291C20 MP 0x1403581E0 + {"_func_0F6", 0x0F6}, // SP 0x140291EB0 MP 0x140358570 + {"_func_0F7", 0x0F7}, // SP 0x140291F80 MP 0x140358640 + {"_func_0F8", 0x0F8}, // SP 0x140292690 MP 0x140359050 + {"_func_0F9", 0x0F9}, // SP 0x1402ABB50 MP 0x1403771E0 + {"_func_0FA", 0x0FA}, // SP 0x1402ABB60 MP 0x140377260 + {"_func_0FB", 0x0FB}, // SP 0x000000000 MP 0x14037B950 + {"_func_0FC", 0x0FC}, // SP 0x000000000 MP 0x140374E10 + {"_func_0FD", 0x0FD}, // SP 0x000000000 MP 0x140378260 + {"_func_0FE", 0x0FE}, // SP 0x000000000 MP 0x1403765A0 + {"_func_0FF", 0x0FF}, // SP 0x1402AE370 MP 0x140374FE0 + {"_func_100", 0x100}, // SP 0x1402AE3C0 MP 0x140375100 + {"_func_101", 0x101}, // SP 0x1402A1AE0 MP 0x000000000 + {"_func_102", 0x102}, // SP 0x14028E970 MP 0x000000000 + {"_func_103", 0x103}, // SP 0x14028ED80 MP 0x000000000 + {"_func_104", 0x104}, // SP 0x1405D92F0 MP 0x14042C2C0 + {"_func_105", 0x105}, // SP 0x1405D92F0 MP 0x14042C2D0 + {"_func_106", 0x106}, // SP 0x14028D7F0 MP 0x000000000 + {"_func_107", 0x107}, // SP 0x1402D79E0 MP 0x1400774E0 + {"_func_108", 0x108}, // SP 0x1402D7A10 MP 0x140077510 + {"_func_109", 0x109}, // SP 0x1402D7A50 MP 0x140077550 + {"_func_10A", 0x10A}, // SP 0x1402D7AB0 MP 0x1400775B0 + {"_func_10B", 0x10B}, // SP 0x1402D7B30 MP 0x140077630 + {"_func_10C", 0x10C}, // SP 0x1402D7B80 MP 0x140077680 + {"_func_10D", 0x10D}, // SP 0x1402D7CC0 MP 0x140077820 + {"_func_10E", 0x10E}, // SP 0x1402B7530 MP 0x000000000 + {"_func_10F", 0x10F}, // SP 0x1402B77F0 MP 0x000000000 + {"_func_110", 0x110}, // SP 0x1402B7800 MP 0x000000000 + {"_func_111", 0x111}, // SP 0x1402B7810 MP 0x000000000 + {"_func_112", 0x112}, // SP 0x1402B79C0 MP 0x000000000 + {"_func_113", 0x113}, // SP 0x1402B7A20 MP 0x000000000 + {"_func_114", 0x114}, // SP 0x140292150 MP 0x1403587A0 + {"_func_115", 0x115}, // SP 0x140292290 MP 0x140358A90 + {"_func_116", 0x116}, // SP 0x1402924D0 MP 0x140358B10 + {"_func_117", 0x117}, // SP 0x140292510 MP 0x140358E60 + {"_func_118", 0x118}, // SP 0x140292C80 MP 0x1403596E0 + {"_func_119", 0x119}, // SP 0x140292D50 MP 0x140359890 + {"_func_11A", 0x11A}, // SP 0x140292F80 MP 0x140359930 + {"_func_11B", 0x11B}, // SP 0x1402930E0 MP 0x140359BC0 + {"_func_11C", 0x11C}, // SP 0x1402934C0 MP 0x14035A0F0 + {"_func_11D", 0x11D}, // SP 0x140293670 MP 0x14035A280 + {"_func_11E", 0x11E}, // SP 0x1402956B0 MP 0x14035B550 + {"_func_11F", 0x11F}, // SP 0x140295850 MP 0x14035B7F0 + {"_func_120", 0x120}, // SP 0x140296960 MP 0x14035CB70 + {"_func_121", 0x121}, // SP 0x1402969A0 MP 0x14035CD40 + {"_func_122", 0x122}, // SP 0x140296BB0 MP 0x14035CF80 + {"_func_123", 0x123}, // SP 0x140296DC0 MP 0x14035D360 + {"_func_124", 0x124}, // SP 0x140297230 MP 0x14035DA90 + {"_func_125", 0x125}, // SP 0x140297970 MP 0x14035E690 + {"_func_126", 0x126}, // SP 0x14029FA50 MP 0x1403679A0 + {"_func_127", 0x127}, // SP 0x000000000 MP 0x14037B790 + {"_func_128", 0x128}, // SP 0x000000000 MP 0x14037B7A0 + {"_func_129", 0x129}, // SP 0x000000000 MP 0x14037B7B0 + {"_func_12A", 0x12A}, // SP 0x000000000 MP 0x14037B7C0 + {"_func_12B", 0x12B}, // SP 0x000000000 MP 0x14037B7D0 + {"_func_12C", 0x12C}, // SP 0x000000000 MP 0x14037B830 + {"_func_12D", 0x12D}, // SP 0x000000000 MP 0x14037B8B0 + {"_func_12E", 0x12E}, // SP 0x000000000 MP 0x140378110 + {"_func_12F", 0x12F}, // SP 0x000000000 MP 0x14037A7B0 + {"_func_130", 0x130}, // SP 0x000000000 MP 0x140378420 + {"_func_131", 0x131}, // SP 0x000000000 MP 0x140378490 + {"_func_132", 0x132}, // SP 0x000000000 MP 0x140378F40 + {"_func_133", 0x133}, // SP 0x000000000 MP 0x14037A820 + {"_func_134", 0x134}, // SP 0x000000000 MP 0x140378FE0 + {"_func_135", 0x135}, // SP 0x000000000 MP 0x140378DD0 + {"_func_136", 0x136}, // SP 0x000000000 MP 0x140378F70 + {"_func_137", 0x137}, // SP 0x000000000 MP 0x140378290 + {"_func_138", 0x138}, // SP 0x000000000 MP 0x14037A8D0 + {"_func_139", 0x139}, // SP 0x000000000 MP 0x14037ADE0 + {"_func_13A", 0x13A}, // SP 0x000000000 MP 0x14037AEB0 + {"_func_13B", 0x13B}, // SP 0x000000000 MP 0x14037B0E0 + {"_func_13C", 0x13C}, // SP 0x000000000 MP 0x14037B100 + {"_func_13D", 0x13D}, // SP 0x000000000 MP 0x14037AA30 + {"_func_13E", 0x13E}, // SP 0x000000000 MP 0x14037AB20 + {"_func_13F", 0x13F}, // SP 0x000000000 MP 0x1403769E0 + {"_func_140", 0x140}, // SP 0x1402ACD00 MP 0x140378030 + {"_func_141", 0x141}, // SP 0x000000000 MP 0x14037B550 + {"_func_142", 0x142}, // SP 0x000000000 MP 0x14037B5A0 + {"_func_143", 0x143}, // SP 0x1402ABA00 MP 0x140376D40 + {"_func_144", 0x144}, // SP 0x1402ABA10 MP 0x1403770E0 + {"_func_145", 0x145}, // SP 0x1402ABA20 MP 0x140377160 + {"_func_146", 0x146}, // SP 0x1402A12A0 MP 0x1403699C0 + {"_func_147", 0x147}, // SP 0x140298040 MP 0x14035F250 + {"_func_148", 0x148}, // SP 0x140298370 MP 0x14035F7A0 + {"_func_149", 0x149}, // SP 0x14029E7B0 MP 0x140366DA0 + {"_func_14A", 0x14A}, // SP 0x14029ECC0 MP 0x140366E30 + {"_func_14B", 0x14B}, // SP 0x14029F2B0 MP 0x1403673D0 + {"_func_14C", 0x14C}, // SP 0x14029F3E0 MP 0x140367540 + {"_func_14D", 0x14D}, // SP 0x14029F5B0 MP 0x1403675F0 + {"_func_14E", 0x14E}, // SP 0x1402982C0 MP 0x14035F470 + {"_func_14F", 0x14F}, // SP 0x14029EDB0 MP 0x1403670E0 + {"_func_150", 0x150}, // SP 0x140290A80 MP 0x1403583B0 + {"_func_151", 0x151}, // SP 0x140291730 MP 0x140359620 + {"_func_152", 0x152}, // SP 0x140292A40 MP 0x14035AF90 + {"_func_153", 0x153}, // SP 0x140294440 MP 0x14035C4B0 + {"_func_154", 0x154}, // SP 0x140294DD0 MP 0x14035D560 + {"_func_155", 0x155}, // SP 0x140474350 MP 0x14037DA70 + {"_func_156", 0x156}, // SP 0x1404746B0 MP 0x14037E2D0 + {"_func_157", 0x157}, // SP 0x140474940 MP 0x14037E8B0 + {"_func_158", 0x158}, // SP 0x140292ED0 MP 0x14035B2B0 + {"_func_159", 0x159}, // SP 0x140474640 MP 0x14037E1D0 + {"_func_15A", 0x15A}, // SP 0x140293D50 MP 0x14035BFE0 + {"_func_15B", 0x15B}, // SP 0x000000000 MP 0x1403778C0 + {"_func_15C", 0x15C}, // SP 0x000000000 MP 0x140377920 + {"_func_15D", 0x15D}, // SP 0x000000000 MP 0x1403779A0 + {"_func_15E", 0x15E}, // SP 0x000000000 MP 0x140377A40 + {"_func_15F", 0x15F}, // SP 0x000000000 MP 0x140377BE0 + {"_func_160", 0x160}, // SP 0x000000000 MP 0x140377C50 + {"_func_161", 0x161}, // SP 0x000000000 MP 0x140377D70 + {"_func_162", 0x162}, // SP 0x000000000 MP 0x140377DC0 + {"_func_163", 0x163}, // SP 0x000000000 MP 0x140377EB0 + {"_func_164", 0x164}, // SP 0x000000000 MP 0x140375460 + {"_func_165", 0x165}, // SP 0x000000000 MP 0x140375480 + {"_func_166", 0x166}, // SP 0x000000000 MP 0x1403754A0 + {"_func_167", 0x167}, // SP 0x000000000 MP 0x1403756D0 + {"_func_168", 0x168}, // SP 0x000000000 MP 0x1403759C0 + {"_func_169", 0x169}, // SP 0x000000000 MP 0x1403760D0 + {"_func_16A", 0x16A}, // SP 0x14029F100 MP 0x1403673A0 + {"_func_16B", 0x16B}, // SP 0x000000000 MP 0x140376BE0 + {"_func_16C", 0x16C}, // SP 0x000000000 MP 0x140376C60 + {"_func_16D", 0x16D}, // SP 0x000000000 MP 0x140376550 + {"_func_16E", 0x16E}, // SP 0x000000000 MP 0x140376630 + {"_func_16F", 0x16F}, // SP 0x000000000 MP 0x140376680 + {"_func_170", 0x170}, // SP 0x000000000 MP 0x140376860 + {"_func_171", 0x171}, // SP 0x000000000 MP 0x140378020 + {"_func_172", 0x172}, // SP 0x000000000 MP 0x140376880 + {"_func_173", 0x173}, // SP 0x000000000 MP 0x140376B60 + {"_func_174", 0x174}, // SP 0x000000000 MP 0x140376910 + {"_func_175", 0x175}, // SP 0x000000000 MP 0x140376950 + {"_func_176", 0x176}, // SP 0x000000000 MP 0x140378040 + {"_func_177", 0x177}, // SP 0x000000000 MP 0x140378050 + {"_func_178", 0x178}, // SP 0x000000000 MP 0x140378100 + {"_func_179", 0x179}, // SP 0x000000000 MP 0x14037B5D0 + {"_func_17A", 0x17A}, // SP 0x000000000 MP 0x14037B640 + {"_func_17B", 0x17B}, // SP 0x000000000 MP 0x14037B6A0 + {"_func_17C", 0x17C}, // SP 0x000000000 MP 0x14037B720 + {"_func_17D", 0x17D}, // SP 0x000000000 MP 0x14037B780 + {"_func_17E", 0x17E}, // SP 0x140295500 MP 0x14035E730 + {"_func_17F", 0x17F}, // SP 0x140296890 MP 0x14035FE90 + {"_func_180", 0x180}, // SP 0x140295F60 MP 0x14035F2D0 + {"_func_181", 0x181}, // SP 0x1402963A0 MP 0x14035F900 + {"_func_182", 0x182}, // SP 0x140299880 MP 0x140362E20 + {"_func_183", 0x183}, // SP 0x140299900 MP 0x140363010 + {"_func_184", 0x184}, // SP 0x140299F70 MP 0x140363800 + {"_func_185", 0x185}, // SP 0x14029A180 MP 0x140363920 + {"_func_186", 0x186}, // SP 0x14029A220 MP 0x140363B00 + {"_func_187", 0x187}, // SP 0x14029A4B0 MP 0x140363E60 + {"_func_188", 0x188}, // SP 0x1402A2800 MP 0x14036ADB0 + {"_func_189", 0x189}, // SP 0x1402A3690 MP 0x14036C110 + {"_func_18A", 0x18A}, // SP 0x14028DFA0 MP 0x14036CF90 + {"_func_18B", 0x18B}, // SP 0x1402A3950 MP 0x14036C1E0 + {"_func_18C", 0x18C}, // SP 0x14029B460 MP 0x140366A00 + {"_func_18D", 0x18D}, // SP 0x14029A830 MP 0x140363F40 + {"_func_18E", 0x18E}, // SP 0x1402B76D0 MP 0x140383170 + {"_func_18F", 0x18F}, // SP 0x000000000 MP 0x1403831D0 + {"_func_190", 0x190}, // SP 0x000000000 MP 0x140383310 + {"_func_191", 0x191}, // SP 0x000000000 MP 0x1403833B0 + {"_func_192", 0x192}, // SP 0x000000000 MP 0x140383410 + {"_func_193", 0x193}, // SP 0x000000000 MP 0x1403834B0 + {"_func_194", 0x194}, // SP 0x000000000 MP 0x1403835B0 + {"_func_195", 0x195}, // SP 0x000000000 MP 0x1403835F0 + {"_func_196", 0x196}, // SP 0x000000000 MP 0x140382DA0 + {"_func_197", 0x197}, // SP 0x000000000 MP 0x140382DE0 + {"_func_198", 0x198}, // SP 0x1402AD860 MP 0x140377360 + {"_func_199", 0x199}, // SP 0x1402AD8C0 MP 0x1403773E0 + {"_func_19A", 0x19A}, // SP 0x1405D92F0 MP 0x140377C30 + {"_func_19B", 0x19B}, // SP 0x1402B9570 MP 0x1403845D0 + {"_func_19C", 0x19C}, // SP 0x1402B95E0 MP 0x1403846A0 + {"_func_19D", 0x19D}, // SP 0x000000000 MP 0x140384C00 + {"_func_19E", 0x19E}, // SP 0x000000000 MP 0x140377670 + {"_func_19F", 0x19F}, // SP 0x140374110 MP 0x140442170 + {"_func_1A0", 0x1A0}, // SP 0x000000000 MP 0x140377A90 + {"_func_1A1", 0x1A1}, // SP 0x1402AD940 MP 0x140377410 + {"_func_1A2", 0x1A2}, // SP 0x1402ADB20 MP 0x1403774F0 + {"_func_1A3", 0x1A3}, // SP 0x140282D00 MP 0x14034F8E0 + {"_func_1A4", 0x1A4}, // SP 0x140282D10 MP 0x14034F8F0 + {"_func_1A5", 0x1A5}, // SP 0x140282FD0 MP 0x14034FBA0 + {"_func_1A6", 0x1A6}, // SP 0x140282FE0 MP 0x14034FBB0 + {"_func_1A7", 0x1A7}, // SP 0x140282FF0 MP 0x14034FBC0 + {"_func_1A8", 0x1A8}, // SP 0x000000000 MP 0x140378150 + {"_func_1A9", 0x1A9}, // SP 0x14026F000 MP 0x14033CF50 + {"_func_1AA", 0x1AA}, // SP 0x14026EFB0 MP 0x14033CEF0 + {"_func_1AB", 0x1AB}, // SP 0x000000000 MP 0x14033CF80 + {"_func_1AC", 0x1AC}, // SP 0x140375910 MP 0x1404438F0 + {"_func_1AD", 0x1AD}, // SP 0x1402ADB90 MP 0x140377390 + {"_func_1AE", 0x1AE}, // SP 0x000000000 MP 0x1403774C0 + {"_func_1AF", 0x1AF}, // SP 0x14029A9A0 MP 0x140364120 + {"_func_1B0", 0x1B0}, // SP 0x14029CDC0 MP 0x140363D50 + {"_func_1B1", 0x1B1}, // SP 0x1402999A0 MP 0x140360B10 + {"_func_1B2", 0x1B2}, // SP 0x14029AA30 MP 0x140361AC0 + {"_func_1B3", 0x1B3}, // SP 0x14029ADB0 MP 0x140361CE0 + {"_func_1B4", 0x1B4}, // SP 0x14029B360 MP 0x1403622D0 + {"_func_1B5", 0x1B5}, // SP 0x14029B580 MP 0x140362520 + {"_func_1B6", 0x1B6}, // SP 0x14029B020 MP 0x140361EC0 + {"_func_1B7", 0x1B7}, // SP 0x14029B7A0 MP 0x140362920 + {"_func_1B8", 0x1B8}, // SP 0x14029B8E0 MP 0x140362A60 + {"_func_1B9", 0x1B9}, // SP 0x1402A35D0 MP 0x14036D000 + {"_func_1BA", 0x1BA}, // SP 0x14028D850 MP 0x14036D690 + {"_func_1BB", 0x1BB}, // SP 0x14029CCC0 MP 0x1403664F0 + {"_func_1BC", 0x1BC}, // SP 0x14029D970 MP 0x1403671B0 + {"_func_1BD", 0x1BD}, // SP 0x14029CF50 MP 0x1403667F0 + {"_func_1BE", 0x1BE}, // SP 0x14029DC10 MP 0x140367320 + {"_func_1BF", 0x1BF}, // SP 0x14029D280 MP 0x140366C90 + {"_func_1C0", 0x1C0}, // SP 0x14029D820 MP 0x140366DE0 + {"_func_1C1", 0x1C1}, // SP 0x14029AD10 MP 0x140366490 + {"_func_1C2", 0x1C2}, // SP 0x140294EF0 MP 0x14035E270 + {"_func_1C3", 0x1C3}, // SP 0x140295DC0 MP 0x14035F290 + {"_func_1C4", 0x1C4}, // SP 0x14029A870 MP 0x140363F90 + {"_func_1C5", 0x1C5}, // SP 0x14029AB60 MP 0x140364300 + {"_func_1C6", 0x1C6}, // SP 0x140466C40 MP 0x140564030 + {"_func_1C7", 0x1C7}, // SP 0x140299410 MP 0x140360540 + {"_func_1C8", 0x1C8}, // SP 0x140299470 MP 0x1403605E0 + {"_func_1C9", 0x1C9}, // SP 0x1402996F0 MP 0x140360670 + {"_func_1CA", 0x1CA}, // SP 0x140290B30 MP 0x14035C2D0 + {"_func_1CB", 0x1CB}, // SP 0x1405D92F0 MP 0x14036B580 + {"_func_1CC", 0x1CC}, // SP 0x1405D92F0 MP 0x14036B590 + {"_func_1CD", 0x1CD}, // SP 0x1405D92F0 MP 0x14036B710 + {"_func_1CE", 0x1CE}, // SP 0x1405D92F0 MP 0x14036B770 + {"_func_1CF", 0x1CF}, // SP 0x1405D92F0 MP 0x14036B780 + {"_func_1D0", 0x1D0}, // SP 0x1405D92F0 MP 0x14036B790 + {"_func_1D1", 0x1D1}, // SP 0x1402A2200 MP 0x14036C3C0 + {"_func_1D2", 0x1D2}, // SP 0x1402A28F0 MP 0x14036CA90 + {"_func_1D3", 0x1D3}, // SP 0x1402A3410 MP 0x14036CDA0 + {"_func_1D4", 0x1D4}, // SP 0x1402A3470 MP 0x14036CF00 + {"_func_1D5", 0x1D5}, // SP 0x14029AD60 MP 0x1403644F0 + {"_func_1D6", 0x1D6}, // SP 0x14029B110 MP 0x1403647D0 + {"_func_1D7", 0x1D7}, // SP 0x14029B410 MP 0x1403649E0 + {"_func_1D8", 0x1D8}, // SP 0x14029B630 MP 0x140364CF0 + {"_func_1D9", 0x1D9}, // SP 0x14029B850 MP 0x140365010 + {"_func_1DA", 0x1DA}, // SP 0x14029B9F0 MP 0x1403651E0 + {"_func_1DB", 0x1DB}, // SP 0x14029C0E0 MP 0x140365F50 + {"_func_1DC", 0x1DC}, // SP 0x14029C160 MP 0x140366130 + {"_func_1DD", 0x1DD}, // SP 0x1402B7080 MP 0x140382E50 + {"_func_1DE", 0x1DE}, // SP 0x1402B74F0 MP 0x140382F80 + {"_func_1DF", 0x1DF}, // SP 0x1402B77E0 MP 0x140382FF0 + {"_func_1E0", 0x1E0}, // SP 0x1402B7820 MP 0x140383090 + {"_func_1E1", 0x1E1}, // SP 0x1402B7900 MP 0x000000000 + {"_func_1E2", 0x1E2}, // SP 0x1402B7980 MP 0x1403830D0 + {"_func_1E3", 0x1E3}, // SP 0x1402B7A10 MP 0x140383230 + {"_func_1E4", 0x1E4}, // SP 0x14029BA70 MP 0x140362C20 + {"_func_1E5", 0x1E5}, // SP 0x14029BE70 MP 0x140362F00 + {"_func_1E6", 0x1E6}, // SP 0x14029BF80 MP 0x140363300 + {"_func_1E7", 0x1E7}, // SP 0x14029C9D0 MP 0x140363950 + {"_func_1E8", 0x1E8}, // SP 0x14029D050 MP 0x140364220 + {"_func_1E9", 0x1E9}, // SP 0x14029D330 MP 0x140364590 + {"_func_1EA", 0x1EA}, // SP 0x14029D720 MP 0x140364870 + {"_func_1EB", 0x1EB}, // SP 0x14029D9F0 MP 0x140364E70 + {"_func_1EC", 0x1EC}, // SP 0x14045D5C0 MP 0x14055A900 + {"_func_1ED", 0x1ED}, // SP 0x14045D6B0 MP 0x14055A9F0 + {"_func_1EE", 0x1EE}, // SP 0x14045D550 MP 0x14055A890 + {"_func_1EF", 0x1EF}, // SP 0x1404669B0 MP 0x140563DA0 + {"_func_1F0", 0x1F0}, // SP 0x140466CC0 MP 0x140564110 + {"_func_1F1", 0x1F1}, // SP 0x140466D20 MP 0x140564170 + {"_func_1F2", 0x1F2}, // SP 0x1404669F0 MP 0x140563DE0 + {"_func_1F3", 0x1F3}, // SP 0x14028E710 MP 0x14036CBC0 + {"_func_1F4", 0x1F4}, // SP 0x14028D7B0 MP 0x14036BB10 + {"_func_1F5", 0x1F5}, // SP 0x000000000 MP 0x14047A600 + {"_func_1F6", 0x1F6}, // SP 0x000000000 MP 0x14047ABF0 + {"_func_1F7", 0x1F7}, // SP 0x000000000 MP 0x14047AC20 + {"_func_1F8", 0x1F8}, // SP 0x000000000 MP 0x14047AF10 + {"_func_1F9", 0x1F9}, // SP 0x000000000 MP 0x14047AD50 + {"_func_1FA", 0x1FA}, // SP 0x000000000 MP 0x14047A940 + {"_func_1FB", 0x1FB}, // SP 0x000000000 MP 0x14047A320 + {"_func_1FC", 0x1FC}, // SP 0x000000000 MP 0x14047ACF0 + {"_func_1FD", 0x1FD}, // SP 0x000000000 MP 0x14047A990 + {"_func_1FE", 0x1FE}, // SP 0x000000000 MP 0x14047AF70 + {"_func_1FF", 0x1FF}, // SP 0x000000000 MP 0x14037B2B0 + {"_func_200", 0x200}, // SP 0x000000000 MP 0x140450E50 + {"_func_201", 0x201}, // SP 0x000000000 MP 0x14047A310 + {"_func_202", 0x202}, // SP 0x000000000 MP 0x14047A550 + {"_func_203", 0x203}, // SP 0x000000000 MP 0x14031FCE0 + {"_func_204", 0x204}, // SP 0x1402CC4A0 MP 0x140320EA0 + {"_func_205", 0x205}, // SP 0x1402CC110 MP 0x14031FDD0 + {"_func_206", 0x206}, // SP 0x000000000 MP 0x1403201B0 + {"_func_207", 0x207}, // SP 0x000000000 MP 0x1403201C0 + {"_func_208", 0x208}, // SP 0x000000000 MP 0x140320320 + {"_func_209", 0x209}, // SP 0x000000000 MP 0x140320A10 + {"_func_20A", 0x20A}, // SP 0x000000000 MP 0x140320960 + {"_func_20B", 0x20B}, // SP 0x000000000 MP 0x14031FC20 + {"_func_20C", 0x20C}, // SP 0x000000000 MP 0x140320600 + {"_func_20D", 0x20D}, // SP 0x000000000 MP 0x1403202E0 + {"_func_20E", 0x20E}, // SP 0x1402AFFC0 MP 0x14037AE40 + {"_func_211", 0x211}, // SP 0x000000000 MP 0x140320C70 + {"_func_212", 0x212}, // SP 0x000000000 MP 0x14031F6F0 + {"_func_213", 0x213}, // SP 0x000000000 MP 0x14035A190 + {"_func_214", 0x214}, // SP 0x000000000 MP 0x140375150 + {"_func_215", 0x215}, // SP 0x1402CBE10 MP 0x14031F940 + {"_func_216", 0x216}, // SP 0x14028E840 MP 0x14036F800 + {"_func_217", 0x217}, // SP 0x14028EAC0 MP 0x140357F30 + {"_func_218", 0x218}, // SP 0x1402AE000 MP 0x000000000 + {"_func_21B", 0x21B}, // SP 0x1405D92F0 MP 0x1403780E0 + {"_func_21C", 0x21C}, // SP 0x000000000 MP 0x140374FD0 + {"_func_21D", 0x21D}, // SP 0x14037AA30 MP 0x000000000 + {"_func_21E", 0x21E}, // SP 0x14037AC70 MP 0x000000000 + {"_func_21F", 0x21F}, // SP 0x14037ABB0 MP 0x000000000 + {"_func_220", 0x220}, // SP 0x14037AB50 MP 0x000000000 + {"_func_221", 0x221}, // SP 0x14037A730 MP 0x000000000 + {"_func_222", 0x222}, // SP 0x14037A7B0 MP 0x000000000 + {"_func_223", 0x223}, // SP 0x14037A760 MP 0x000000000 + {"_func_224", 0x224}, // SP 0x14037A7F0 MP 0x000000000 + {"_func_225", 0x225}, // SP 0x1402914F0 MP 0x140357BF0 + {"_func_226", 0x226}, // SP 0x14028FE10 MP 0x14036F1C0 + {"_func_227", 0x227}, // SP 0x140290710 MP 0x14035B7B0 + {"_func_228", 0x228}, // SP 0x1402909E0 MP 0x14035CED0 + {"_func_229", 0x229}, // SP 0x140290DF0 MP 0x14035D200 + {"_func_22A", 0x22A}, // SP 0x140290FA0 MP 0x14035D4C0 + {"_func_22B", 0x22B}, // SP 0x1402911D0 MP 0x14035D830 + {"_func_22C", 0x22C}, // SP 0x140291530 MP 0x14035DFB0 + {"_func_22D", 0x22D}, // SP 0x140291910 MP 0x14035E0B0 + {"_func_22E", 0x22E}, // SP 0x1405D92F0 MP 0x140367D60 + {"_func_22F", 0x22F}, // SP 0x140291190 MP 0x14036F5A0 + {"_func_230", 0x230}, // SP 0x1402AB600 MP 0x000000000 + {"_func_231", 0x231}, // SP 0x1402AB4F0 MP 0x000000000 + {"_func_232", 0x232}, // SP 0x1402AB4D0 MP 0x000000000 + {"_func_234", 0x234}, // SP 0x1405D92F0 MP 0x1403605D0 + {"_func_236", 0x236}, // SP 0x140294380 MP 0x140360720 + {"_func_237", 0x237}, // SP 0x140297840 MP 0x140360C40 + {"_func_238", 0x238}, // SP 0x1402A87C0 MP 0x14037B1D0 + {"_func_239", 0x239}, // SP 0x1402AA280 MP 0x000000000 + {"_func_23A", 0x23A}, // SP 0x140292220 MP 0x14035E710 + {"_func_23B", 0x23B}, // SP 0x140292220 MP 0x14035E860 + {"_func_23D", 0x23D}, // SP 0x1402A06D0 MP 0x1403686B0 + {"_func_23E", 0x23E}, // SP 0x1402A0900 MP 0x140368C00 + {"_func_23F", 0x23F}, // SP 0x14029DDC0 MP 0x140365220 + {"_func_240", 0x240}, // SP 0x14029DDC0 MP 0x140365440 + {"_func_241", 0x241}, // SP 0x1402ACD00 MP 0x140365460 + {"_func_242", 0x242}, // SP 0x1402ACD00 MP 0x140365470 + {"_func_243", 0x243}, // SP 0x1402ACD00 MP 0x140365630 + {"_func_244", 0x244}, // SP 0x000000000 MP 0x1403784C0 + {"_func_245", 0x245}, // SP 0x140292D40 MP 0x14035FAF0 + {"_func_246", 0x246}, // SP 0x000000000 MP 0x1403784E0 + {"_func_247", 0x247}, // SP 0x000000000 MP 0x140378DA0 + {"_func_248", 0x248}, // SP 0x000000000 MP 0x140378DB0 + {"_func_249", 0x249}, // SP 0x000000000 MP 0x140378DC0 + {"_func_24A", 0x24A}, // SP 0x1402A8F70 MP 0x000000000 + {"_func_24B", 0x24B}, // SP 0x1402A8FF0 MP 0x000000000 + {"_func_24C", 0x24C}, // SP 0x1402946A0 MP 0x14035ABF0 + {"_func_24D", 0x24D}, // SP 0x140290110 MP 0x14036DF90 + {"_func_24E", 0x24E}, // SP 0x140292B00 MP 0x140359490 + {"_func_24F", 0x24F}, // SP 0x1402ABB80 MP 0x000000000 + {"_func_250", 0x250}, // SP 0x1405D92F0 MP 0x140360370 + {"_func_251", 0x251}, // SP 0x1405D92F0 MP 0x1403604B0 + {"_func_252", 0x252}, // SP 0x1405D92F0 MP 0x140360530 + {"_func_253", 0x253}, // SP 0x140293F90 MP 0x14035A6C0 + {"_func_254", 0x254}, // SP 0x140293FF0 MP 0x14035A7C0 + {"_func_255", 0x255}, // SP 0x140294500 MP 0x14035A9F0 + {"_func_256", 0x256}, // SP 0x000000000 MP 0x1403844C0 + {"_func_257", 0x257}, // SP 0x1402ADE20 MP 0x000000000 + {"_func_258", 0x258}, // SP 0x14029F640 MP 0x1403677A0 + {"_func_259", 0x259}, // SP 0x14029F710 MP 0x1403678C0 + {"_func_25A", 0x25A}, // SP 0x1402954E0 MP 0x1403611E0 + {"_func_25B", 0x25B}, // SP 0x1402955F0 MP 0x140361200 + {"_func_25C", 0x25C}, // SP 0x140295790 MP 0x1403613C0 + {"_func_25D", 0x25D}, // SP 0x140295AD0 MP 0x1403615F0 + {"_func_25E", 0x25E}, // SP 0x140295E00 MP 0x140361A30 + {"_func_25F", 0x25F}, // SP 0x140296150 MP 0x140361DD0 + {"_func_260", 0x260}, // SP 0x1402965B0 MP 0x140362020 + {"_func_261", 0x261}, // SP 0x140296740 MP 0x140362470 + {"_func_262", 0x262}, // SP 0x140296B10 MP 0x140362680 + {"_func_263", 0x263}, // SP 0x140296CE0 MP 0x140362AE0 + {"_func_264", 0x264}, // SP 0x140296EE0 MP 0x140362D50 + {"_func_265", 0x265}, // SP 0x1402970D0 MP 0x140363430 + {"_func_266", 0x266}, // SP 0x140297580 MP 0x1403636C0 + {"_func_267", 0x267}, // SP 0x140297820 MP 0x140363AB0 + {"_func_268", 0x268}, // SP 0x140297820 MP 0x140363C90 + {"_func_269", 0x269}, // SP 0x000000000 MP 0x14037AEC0 + {"_func_26A", 0x26A}, // SP 0x1405D92F0 MP 0x140363F80 + {"_func_26B", 0x26B}, // SP 0x1405D92F0 MP 0x140364110 + {"_func_26C", 0x26C}, // SP 0x1405D92F0 MP 0x1403642F0 + {"_func_26D", 0x26D}, // SP 0x1405D92F0 MP 0x1403644E0 + {"_func_26E", 0x26E}, // SP 0x1405D92F0 MP 0x140364540 + {"_func_26F", 0x26F}, // SP 0x1405D92F0 MP 0x140364700 + {"_func_270", 0x270}, // SP 0x000000000 MP 0x140378930 + {"_func_271", 0x271}, // SP 0x1405D92F0 MP 0x000000000 + {"_func_272", 0x272}, // SP 0x1405D92F0 MP 0x000000000 + {"_func_273", 0x273}, // SP 0x1405D92F0 MP 0x140364710 + {"_func_274", 0x274}, // SP 0x1405D92F0 MP 0x140364860 + {"_func_275", 0x275}, // SP 0x1405D92F0 MP 0x140364970 + {"_func_276", 0x276}, // SP 0x1405D92F0 MP 0x1403649D0 + {"_func_277", 0x277}, // SP 0x000000000 MP 0x14037B980 + {"_func_279", 0x279}, // SP 0x000000000 MP 0x14047A900 + {"_func_27A", 0x27A}, // SP 0x000000000 MP 0x14037E430 + {"_func_27B", 0x27B}, // SP 0x000000000 MP 0x14047A8C0 + {"_func_27C", 0x27C}, // SP 0x1405D92F0 MP 0x1403675D0 + {"_func_27D", 0x27D}, // SP 0x14029CAC0 MP 0x14033CF40 + {"_func_27E", 0x27E}, // SP 0x1405D92F0 MP 0x140363CE0 + {"_func_27F", 0x27F}, // SP 0x1405D92F0 MP 0x140363E50 + {"_func_280", 0x280}, // SP 0x1405D92F0 MP 0x140360610 + {"_func_281", 0x281}, // SP 0x14029DC90 MP 0x140369F80 + {"_func_282", 0x282}, // SP 0x000000000 MP 0x14037BBD0 + {"_func_283", 0x283}, // SP 0x000000000 MP 0x14037BBE0 + {"_func_284", 0x284}, // SP 0x000000000 MP 0x14037BC00 + {"_func_285", 0x285}, // SP 0x000000000 MP 0x1403748B0 + {"_func_286", 0x286}, // SP 0x000000000 MP 0x140374B00 + {"_func_287", 0x287}, // SP 0x1405D92F0 MP 0x140360660 + {"_func_288", 0x288}, // SP 0x000000000 MP 0x1403772E0 + {"_func_289", 0x289}, // SP 0x000000000 MP 0x140376690 + {"_func_28A", 0x28A}, // SP 0x1402ACD00 MP 0x140365450 + {"_func_28B", 0x28B}, // SP 0x140295B60 MP 0x14035BD90 + {"_func_28C", 0x28C}, // SP 0x140296230 MP 0x14035C6E0 + {"_func_28D", 0x28D}, // SP 0x000000000 MP 0x1400777C0 + {"_func_28E", 0x28E}, // SP 0x000000000 MP 0x1403767D0 + {"_func_28F", 0x28F}, // SP 0x000000000 MP 0x140320120 + {"_func_290", 0x290}, // SP 0x000000000 MP 0x1403775D0 + {"_func_291", 0x291}, // SP 0x14029E770 MP 0x140368040 + {"_func_292", 0x292}, // SP 0x14029E7F0 MP 0x140368150 + {"_func_293", 0x293}, // SP 0x1402ADDE0 MP 0x000000000 + {"_func_294", 0x294}, // SP 0x1402988E0 MP 0x140365640 + {"_func_295", 0x295}, // SP 0x14029C2F0 MP 0x140368F40 + {"_func_296", 0x296}, // SP 0x14029B680 MP 0x140364D50 + {"_func_297", 0x297}, // SP 0x14029BD80 MP 0x140365540 + {"_func_298", 0x298}, // SP 0x14029C1B0 MP 0x140366230 + {"_func_299", 0x299}, // SP 0x1402ABA30 MP 0x000000000 + {"_func_29A", 0x29A}, // SP 0x1405D92F0 MP 0x14035B9A0 + {"_func_29B", 0x29B}, // SP 0x140291040 MP 0x14036F330 + {"_func_29C", 0x29C}, // SP 0x14029D240 MP 0x140368760 + {"_func_29D", 0x29D}, // SP 0x14029DE30 MP 0x1403674E0 + {"_func_29E", 0x29E}, // SP 0x14029DEC0 MP 0x140367620 + {"_func_29F", 0x29F}, // SP 0x000000000 MP 0x140375690 + {"_func_2A0", 0x2A0}, // SP 0x000000000 MP 0x1403756A0 + {"_func_2A1", 0x2A1}, // SP 0x14029D890 MP 0x140364AB0 + {"_func_2A2", 0x2A2}, // SP 0x1402ABC20 MP 0x000000000 + {"_func_2A3", 0x2A3}, // SP 0x1402A2F20 MP 0x14036F010 + {"_func_2A4", 0x2A4}, // SP 0x140290710 MP 0x14035B890 + {"_func_2A5", 0x2A5}, // SP 0x14029DF00 MP 0x14036D0F0 + {"_func_2A6", 0x2A6}, // SP 0x1405D92F0 MP 0x14036DAE0 + {"_func_2A7", 0x2A7}, // SP 0x1405D92F0 MP 0x14036DA60 + {"_func_2A8", 0x2A8}, // SP 0x000000000 MP 0x140376390 + {"_func_2A9", 0x2A9}, // SP 0x1402AE820 MP 0x000000000 + {"_func_2AA", 0x2AA}, // SP 0x14029AE80 MP 0x140364550 + {"_func_2AB", 0x2AB}, // SP 0x1405D92F0 MP 0x14036E590 + {"_func_2AC", 0x2AC}, // SP 0x1402ACD00 MP 0x14036E310 + {"_func_2AD", 0x2AD}, // SP 0x1405D92F0 MP 0x14036E3E0 + {"_func_2AE", 0x2AE}, // SP 0x1405D92F0 MP 0x14036E470 + {"_func_2AF", 0x2AF}, // SP 0x1405D92F0 MP 0x14036E730 + {"_func_2B0", 0x2B0}, // SP 0x000000000 MP 0x140375320 + {"_func_2B1", 0x2B1}, // SP 0x000000000 MP 0x1403753F0 + {"_func_2B2", 0x2B2}, // SP 0x000000000 MP 0x140375430 + {"_func_2B3", 0x2B3}, // SP 0x000000000 MP 0x140375A40 + {"_func_2B4", 0x2B4}, // SP 0x1405D92F0 MP 0x14035C9D0 + {"_func_2B5", 0x2B5}, // SP 0x1405D92F0 MP 0x14035D920 + {"_func_2B6", 0x2B6}, // SP 0x140291AD0 MP 0x14035E150 + {"_func_2B7", 0x2B7}, // SP 0x1402A85B0 MP 0x000000000 + {"_func_2B8", 0x2B8}, // SP 0x000000000 MP 0x140378570 + {"_func_2B9", 0x2B9}, // SP 0x000000000 MP 0x1403787D0 + {"_func_2BA", 0x2BA}, // SP 0x000000000 MP 0x140378850 + {"_func_2BB", 0x2BB}, // SP 0x000000000 MP 0x140379930 + {"_func_2BC", 0x2BC}, // SP 0x14028EBB0 MP 0x140359E00 + {"_func_2BD", 0x2BD}, // SP 0x1402A8640 MP 0x000000000 + {"_func_2BE", 0x2BE}, // SP 0x14029B310 MP 0x140366D50 + {"_func_2BF", 0x2BF}, // SP 0x000000000 MP 0x140383570 + {"_func_2C0", 0x2C0}, // SP 0x1405D92F0 MP 0x14036E8A0 + {"_func_2C1", 0x2C1}, // SP 0x1405D92F0 MP 0x14036E900 + {"_func_2C2", 0x2C2}, // SP 0x140291E10 MP 0x14035E670 + {"_func_2C3", 0x2C3}, // SP 0x1402A1A30 MP 0x14036DA40 + {"_func_2C4", 0x2C4}, // SP 0x1402A1A30 MP 0x14036DAC0 + {"_func_2C5", 0x2C5}, // SP 0x1402A8810 MP 0x000000000 + {"_func_2C6", 0x2C6}, // SP 0x000000000 MP 0x140379A80 + {"_func_2C7", 0x2C7}, // SP 0x000000000 MP 0x140320DC0 + {"_func_2C8", 0x2C8}, // SP 0x000000000 MP 0x140320E20 + {"_func_2C9", 0x2C9}, // SP 0x000000000 MP 0x14037E5E0 + {"_func_2CA", 0x2CA}, // SP 0x000000000 MP 0x14037E650 + {"_func_2CB", 0x2CB}, // SP 0x000000000 MP 0x14037BC40 + {"_func_2CC", 0x2CC}, // SP 0x000000000 MP 0x14037BD00 + {"_func_2CD", 0x2CD}, // SP 0x000000000 MP 0x140374820 + {"_func_2CE", 0x2CE}, // SP 0x1402A79A0 MP 0x000000000 + {"_func_2CF", 0x2CF}, // SP 0x000000000 MP 0x14037AB40 + {"_func_2D4", 0x2D4}, // SP 0x1402A7CB0 MP 0x000000000 + {"_func_2D5", 0x2D5}, // SP 0x14029E120 MP 0x14036D640 + {"_func_2D6", 0x2D6}, // SP 0x000000000 MP 0x14037BE30 + {"_func_2D7", 0x2D7}, // SP 0x1405D92F0 MP 0x14036DB50 + {"_func_2D8", 0x2D8}, // SP 0x1402ABB70 MP 0x000000000 + {"_func_2D9", 0x2D9}, // SP 0x000000000 MP 0x140320D50 + {"_func_2DA", 0x2DA}, // SP 0x1405D92F0 MP 0x000000000 + {"_func_2DB", 0x2DB}, // SP 0x000000000 MP 0x14037ABB0 + {"_func_2DC", 0x2DC}, // SP 0x000000000 MP 0x14037E1C0 + {"_func_2DD", 0x2DD}, // SP 0x000000000 MP 0x14037E1B0 + {"_func_2DF", 0x2DF}, // SP 0x140292220 MP 0x14036F7F0 + {"_func_2E0", 0x2E0}, // SP 0x140297C80 MP 0x14035EDE0 + {"_func_2E1", 0x2E1}, // SP 0x000000000 MP 0x1403788D0 + {"_func_2E2", 0x2E2}, // SP 0x1405D92F0 MP 0x14035B3B0 + {"_func_2E3", 0x2E3}, // SP 0x1405D92F0 MP 0x14035D0B0 + {"_func_2E4", 0x2E4}, // SP 0x1405D92F0 MP 0x14035E170 + {"_func_2E5", 0x2E5}, // SP 0x1402A8730 MP 0x000000000 + {"_func_2E6", 0x2E6}, // SP 0x140295A10 MP 0x14035EFF0 + {"_func_2E7", 0x2E7}, // SP 0x140295CF0 MP 0x14035F120 + {"_func_2E8", 0x2E8}, // SP 0x1402AC850 MP 0x000000000 + {"_func_2E9", 0x2E9}, // SP 0x14029E760 MP 0x140366680 + {"_func_2EA", 0x2EA}, // SP 0x000000000 MP 0x140376DC0 + {"_func_2EB", 0x2EB}, // SP 0x000000000 MP 0x140377540 + {"_func_2EC", 0x2EC}, // SP 0x000000000 MP 0x140377880 + {"_func_2ED", 0x2ED}, // SP 0x1402ACD00 MP 0x14036BA50 + {"_func_2EE", 0x2EE}, // SP 0x1402A1E10 MP 0x14036BA60 + {"_func_2EF", 0x2EF}, // SP 0x1402A1FB0 MP 0x14036BA70 + {"_func_2F0", 0x2F0}, // SP 0x1402A21F0 MP 0x14036BB50 + {"_func_2F1", 0x2F1}, // SP 0x1402ACD00 MP 0x14036BC60 + {"_func_2F2", 0x2F2}, // SP 0x1402A1E10 MP 0x14036BC70 + {"_func_2F3", 0x2F3}, // SP 0x1402A1FB0 MP 0x14036BF90 + {"_func_2F4", 0x2F4}, // SP 0x1402A21F0 MP 0x14036C100 + {"_func_2F5", 0x2F5}, // SP 0x1402A1E10 MP 0x14036C120 + {"_func_2F6", 0x2F6}, // SP 0x1402A1FB0 MP 0x14036C170 + {"_func_2F7", 0x2F7}, // SP 0x1402A21F0 MP 0x14036C310 + {"_func_2F8", 0x2F8}, // SP 0x14028D700 MP 0x1403582B0 + {"_func_2F9", 0x2F9}, // SP 0x14029CAC0 MP 0x14036D300 + {"_func_2FA", 0x2FA}, // SP 0x14029CAC0 MP 0x14036DDC0 + {"_func_2FB", 0x2FB}, // SP 0x14029DB60 MP 0x140365110 + {"_func_2FC", 0x2FC}, // SP 0x14029CB20 MP 0x140367DD0 + {"_func_2FD", 0x2FD}, // SP 0x14029CEA0 MP 0x140368000 + {"_func_2FE", 0x2FE}, // SP 0x14029CEE0 MP 0x140368290 + {"_func_2FF", 0x2FF}, // SP 0x000000000 MP 0x140367110 + {"_func_300", 0x300}, // SP 0x000000000 MP 0x140377870 + {"_func_301", 0x301}, // SP 0x1405D92F0 MP 0x140363E90 }; std::unordered_map method_map = { - {"thermaldrawdisable", 32768}, - {"heli_setdamagestage", 32770}, - {"playsoundtoteam", 32771}, - {"playsoundtoplayer", 32772}, - {"playerhide", 32773}, - {"playershow", 32774}, - {"showtoplayer", 32775}, - {"threatdetectedtoplayer", 32776}, - {"clearthreatdetected", 32777}, - {"enableplayeruse", 32778}, - {"disableplayeruse", 32779}, - {"enableammogeneration", 32780}, - {"disableammogeneration", 32781}, - {"makescrambler", 32782}, - {"makeportableradar", 32783}, - {"clearscrambler", 32784}, - {"clearportableradar", 32785}, - {"placespawnpoint", 32786}, - {"setteamfortrigger", 32787}, - {"clientclaimtrigger", 32788}, - {"clientreleasetrigger", 32789}, - {"releaseclaimedtrigger", 32790}, - {"isusingonlinedataoffline", 32791}, - {"getrestedtime", 32792}, - {"sendleaderboards", 32793}, - {"isonladder", 32794}, - {"getcorpseanim", 32795}, - {"playerforcedeathanim", 32796}, - {"attach", 32797}, - {"startragdoll", 32803}, - {"thermaldrawenable", 32809}, - {"detach", 32810}, - {"detachall", 32811}, - {"getattachsize", 32812}, - {"getattachmodelname", 32813}, - {"getattachtagname", 32814}, - {"gethighestnodestance", 32820}, - {"doesnodeallowstance", 32821}, - {"getlightcolor", 32835}, - {"setlightcolor", 32836}, - {"getattachignorecollision", 32839}, - {"hidepart", 32840}, - {"hidepartallinstances", 32841}, - {"hideallparts", 32842}, - {"showpart", 32843}, - {"showallparts", 32844}, - {"linkto", 32845}, - {"linktoblendtotag", 32846}, - {"unlink", 32847}, - {"setnormalhealth", 32848}, - {"dodamage", 32849}, - {"show", 32851}, - {"hide", 32852}, - {"disconnectpaths", 32855}, - {"connectpaths", 32856}, - {"disconnectnode", 32857}, - {"connectnode", 32858}, - {"digitaldistortsetparams", 32868}, - {"setmode", 32869}, - {"getmode", 32870}, - {"islinked", 32872}, - {"enablelinkto", 32873}, - {"setpitch", 32876}, - {"scalepitch", 32877}, - {"setvolume", 32878}, - {"scalevolume", 32879}, - {"playsound", 32884}, - {"playloopsound", 32885}, - {"getnormalhealth", 32891}, - {"playerlinkto", 32892}, - {"playerlinktodelta", 32893}, - {"playerlinkweaponviewtodelta", 32894}, - {"playerlinktoabsolute", 32895}, - {"playerlinktoblend", 32896}, - {"playerlinkedoffsetenable", 32897}, - {"setwaypointedgestyle_secondaryarrow", 32898}, - {"setwaypointiconoffscreenonly", 32899}, - {"fadeovertime", 32900}, - {"scaleovertime", 32901}, - {"moveovertime", 32902}, - {"reset", 32903}, - {"destroy", 32904}, - {"setpulsefx", 32905}, - {"setplayernamestring", 32906}, - {"changefontscaleovertime", 32907}, - {"playersetgroundreferenceent", 32913}, - {"dontinterpolate", 32914}, - {"getorigin", 32917}, - {"useby", 32921}, - {"playsoundasmaster", 32922}, - {"playerlinkedoffsetdisable", 32927}, - {"playerlinkedsetviewznear", 32928}, - {"playerlinkedsetusebaseangleforviewclamp", 32929}, - {"lerpviewangleclamp", 32930}, - {"geteye", 32936}, - {"istouching", 32937}, - {"getistouchingentities", 32938}, - {"stoploopsound", 32939}, - {"stopsounds", 32940}, - {"playrumbleonentity", 32941}, - {"playrumblelooponentity", 32942}, - {"stoprumble", 32943}, - {"delete", 32944}, - {"setmodel", 32945}, - {"laseron", 32946}, - {"laseroff", 32947}, - {"thermalvisionon", 32950}, - {"thermalvisionoff", 32951}, - {"thermalvisionfofoverlayon", 32952}, - {"thermalvisionfofoverlayoff", 32953}, - {"autospotoverlayon", 32954}, - {"autospotoverlayoff", 32955}, - {"seteyesonuplinkenabled", 32956}, - {"setcontents", 32958}, - {"makeusable", 32959}, - {"makeunusable", 32960}, - {"makeglobalusable", 32961}, - {"makeglobalunusable", 32962}, - {"settext", 32970}, - {"setmaterial", 32972}, - {"settargetent", 32973}, - {"cleartargetent", 32974}, - {"settimer", 32975}, - {"settimerup", 32976}, - {"settimerstatic", 32977}, - {"settenthstimer", 32978}, - {"settenthstimerup", 32979}, - {"settenthstimerstatic", 32980}, - {"setclock", 32981}, - {"setclockup", 32982}, - {"setvalue", 32983}, - {"setwaypoint", 32984}, - {"setwaypointedgestyle_rotatingicon", 32985}, - {"setcursorhint", 32986}, - {"sethintstring", 32987}, - {"setsecondaryhintstring", 32988}, - {"forceusehinton", 32989}, - {"forceusehintoff", 32990}, - {"makesoft", 32991}, - {"makehard", 32992}, - {"entitywillneverchange", 32993}, - {"startfiring", 32994}, - {"stopfiring", 32995}, - {"isfiringturret", 32996}, - {"startbarrelspin", 32997}, - {"stopbarrelspin", 32998}, - {"getbarrelspinrate", 32999}, - {"remotecontrolturret", 33000}, - {"remotecontrolturretoff", 33001}, - {"shootturret", 33002}, - {"getturretowner", 33003}, - {"giveachievement", 33017}, - {"sub_1402ddb00", 33022}, - {"sub_1402ddcc0", 33023}, - {"setsentryowner", 33027}, - {"setsentrycarrier", 33028}, - {"setturretminimapvisible", 33029}, - {"settargetentity", 33030}, - {"snaptotargetentity", 33031}, - {"cleartargetentity", 33032}, - {"getturrettarget", 33033}, - {"setplayerspread", 33034}, - {"setaispread", 33035}, - {"setsuppressiontime", 33036}, - {"allowstand", 33048}, - {"allowcrouch", 33049}, - {"allowprone", 33050}, - {"sub_1402dd9e0", 33051}, - {"isthrowinggrenade", 33068}, - {"isfiring", 33069}, - {"ismeleeing", 33070}, - {"allowmelee", 33072}, - {"allowfire", 33073}, - {"setconvergencetime", 33075}, - {"setconvergenceheightpercent", 33076}, - {"setturretteam", 33077}, - {"maketurretsolid", 33078}, - {"maketurretoperable", 33079}, - {"maketurretinoperable", 33080}, - {"makeentitysentient", 33081}, - {"freeentitysentient", 33082}, - {"setrightarc", 33109}, - {"setleftarc", 33110}, - {"settoparc", 33111}, - {"setbottomarc", 33112}, - {"setautorotationdelay", 33113}, - {"setdefaultdroppitch", 33114}, - {"restoredefaultdroppitch", 33115}, - {"turretfiredisable", 33116}, - {"getenemyinfo", 33125}, - {"getenemysqdist", 33141}, - {"getclosestenemysqdist", 33142}, - {"setthreatbiasgroup", 33143}, - {"getthreatbiasgroup", 33144}, - {"turretfireenable", 33145}, - {"setturretmodechangewait", 33146}, - {"usetriggerrequirelookat", 33147}, - {"getstance", 33148}, - {"setstance", 33149}, - {"itemweaponsetammo", 33150}, - {"getammocount", 33151}, - {"gettagorigin", 33152}, - {"gettagangles", 33153}, - {"shellshock", 33154}, - {"stunplayer", 33155}, - {"stopshellshock", 33156}, - {"fadeoutshellshock", 33157}, - {"setdepthoffield", 33158}, - {"setviewmodeldepthoffield", 33159}, - {"setmotionblurmovescale", 33160}, - {"getnegotiationstartnode", 33181}, - {"getnegotiationendnode", 33182}, - {"getnegotiationnextnode", 33183}, - {"setmotionblurturnscale", 33197}, - {"setmotionblurzoomscale", 33198}, - {"viewkick", 33199}, - {"localtoworldcoords", 33200}, - {"getentitynumber", 33201}, - {"getentityvelocity", 33202}, - {"enablegrenadetouchdamage", 33203}, - {"disablegrenadetouchdamage", 33204}, - {"enableaimassist", 33205}, - {"lastknowntime", 33216}, - {"lastknownpos", 33217}, - {"disableaimassist", 33236}, - {"entityradiusdamage", 33237}, - {"detonate", 33238}, - {"damageconetrace", 33239}, - {"sightconetrace", 33240}, - {"missilesettargetent", 33241}, - {"missilesettargetpos", 33242}, - {"missilecleartarget", 33243}, - {"missilesetflightmodedirect", 33244}, - {"missilesetflightmodetop", 33245}, - {"getlightintensity", 33246}, - {"setlightintensity", 33247}, - {"isragdoll", 33248}, - {"setmovespeedscale", 33249}, - {"cameralinkto", 33250}, - {"cameraunlink", 33251}, - {"controlslinkto", 33280}, - {"controlsunlink", 33281}, - {"makevehiclesolidcapsule", 33282}, - {"makevehiclesolidsphere", 33284}, - {"remotecontrolvehicle", 33286}, - {"remotecontrolvehicleoff", 33287}, - {"isfiringvehicleturret", 33288}, - {"remotecontrolvehicletarget", 33289}, - {"remotecontrolvehicletargetoff", 33290}, - {"drivevehicleandcontrolturret", 33291}, - {"drivevehicleandcontrolturretoff", 33292}, - {"getplayersetting", 33293}, - {"getlocalplayerprofiledata", 33294}, - {"setlocalplayerprofiledata", 33295}, - {"remotecamerasoundscapeon", 33296}, - {"remotecamerasoundscapeoff", 33297}, - {"setmotiontrackervisible", 33298}, - {"getmotiontrackervisible", 33299}, - {"worldpointinreticle_circle", 33300}, - {"worldpointinreticle_rect", 33301}, - {"getpointinbounds", 33302}, - {"transfermarkstonewscriptmodel", 33303}, - {"setwatersheeting", 33304}, - {"setweaponhudiconoverride", 33307}, - {"getweaponhudiconoverride", 33308}, - {"setempjammed", 33309}, - {"playersetexpfogext", 33310}, - {"playersetexpfog", 33311}, - {"playersetatmosfog", 33312}, - {"isitemunlocked", 33313}, - {"getplayerdata", 33314}, - {"getrankedplayerdata", 33315}, - {"getprivateplayerdata", 33316}, - {"getcoopplayerdata", 33317}, - {"getcommonplayerdata", 33318}, - {"vehicleturretcontroloff", 33319}, - {"isturretready", 33320}, - {"vehicledriveto", 33321}, - {"dospawn", 33322}, - {"isphysveh", 33323}, - {"crash", 33324}, - {"launch", 33325}, - {"disablecrashing", 33326}, - {"enablecrashing", 33327}, - {"setphysvehspeed", 33328}, - {"setconveyorbelt", 33329}, - {"freevehicle", 33330}, - {"setplayerdata", 33347}, - {"setrankedplayerdata", 33348}, - {"setprivateplayerdata", 33349}, - {"setcoopplayerdata", 33350}, - {"setcommonplayerdata", 33351}, - {"getcacplayerdata", 33352}, - {"setcacplayerdata", 33353}, - {"trackerupdate", 33354}, - {"pingplayer", 33355}, - {"buttonpressed", 33356}, - {"sayall", 33357}, - {"sayteam", 33358}, - {"setspawnweapon", 33359}, - {"dropitem", 33360}, - {"dropscavengerbag", 33361}, - {"setjitterparams", 33362}, - {"sethoverparams", 33363}, - {"joltbody", 33364}, - {"getwheelsurface", 33366}, - {"getvehicleowner", 33367}, - {"setvehiclelookattext", 33368}, - {"setvehicleteam", 33369}, - {"neargoalnotifydist", 33370}, - {"setvehgoalpos", 33371}, - {"setgoalyaw", 33372}, - {"cleargoalyaw", 33373}, - {"settargetyaw", 33374}, - {"cleartargetyaw", 33375}, - {"helisetgoal", 33376}, - {"setturrettargetvec", 33377}, - {"setturrettargetent", 33378}, - {"clearturrettargetent", 33379}, - {"canturrettargetpoint", 33380}, - {"setlookatent", 33381}, - {"clearlookatent", 33382}, - {"setweapon", 33383}, - {"fireweapon", 33384}, - {"vehicleturretcontrolon", 33385}, - {"finishplayerdamage", 33386}, - {"suicide", 33387}, - {"closeingamemenu", 33388}, - {"iclientprintln", 33389}, - {"iclientprintlnbold", 33390}, - {"spawn", 33391}, - {"setentertime", 33392}, - {"cloneplayer", 33393}, - {"istalking", 33394}, - {"allowspectateteam", 33395}, - {"forcespectatepov", 33396}, - {"getguid", 33397}, - {"physicslaunchserver", 33398}, - {"physicslaunchserveritem", 33399}, - {"clonebrushmodeltoscriptmodel", 33400}, - {"scriptmodelplayanim", 33401}, - {"scriptmodelclearanim", 33402}, - {"scriptmodelplayanimdeltamotion", 33403}, - {"teleport", 33404}, - {"attachpath", 33405}, - {"getattachpos", 33406}, - {"startpath", 33407}, - {"setswitchnode", 33408}, - {"setwaitspeed", 33409}, - {"finishdamage", 33410}, - {"setspeed", 33411}, - {"setspeedimmediate", 33412}, - {"rotatevehyaw", 33413}, - {"getspeed", 33414}, - {"getvehvelocity", 33415}, - {"getbodyvelocity", 33416}, - {"getsteering", 33417}, - {"getthrottle", 33418}, - {"turnengineoff", 33419}, - {"turnengineon", 33420}, - {"getgoalspeedmph", 33422}, - {"setacceleration", 33423}, - {"setdeceleration", 33424}, - {"resumespeed", 33425}, - {"setyawspeed", 33426}, - {"setyawspeedbyname", 33427}, - {"setmaxpitchroll", 33428}, - {"setairresitance", 33429}, - {"setturningability", 33430}, - {"getxuid", 33431}, - {"getucdidhigh", 33432}, - {"getucdidlow", 33433}, - {"getclanidhigh", 33434}, - {"getclanidlow", 33435}, - {"ishost", 33436}, - {"getspectatingplayer", 33437}, - {"predictstreampos", 33438}, - {"setrank", 33441}, - {"weaponlocknoclearance", 33443}, - {"visionsyncwithplayer", 33444}, - {"showhudsplash", 33445}, - {"setperk", 33446}, - {"hasperk", 33447}, - {"clearperks", 33448}, - {"unsetperk", 33449}, - {"registerparty", 33450}, - {"getfireteammembers", 33451}, - {"moveto", 33454}, - {"movex", 33455}, - {"movey", 33456}, - {"movez", 33457}, - {"gravitymove", 33458}, - {"moveslide", 33459}, - {"stopmoveslide", 33460}, - {"rotateto", 33461}, - {"rotatepitch", 33462}, - {"rotateyaw", 33463}, - {"rotateroll", 33464}, - {"addpitch", 33465}, - {"addyaw", 33466}, - {"addroll", 33467}, - {"vibrate", 33468}, - {"rotatevelocity", 33469}, - {"solid", 33470}, - {"notsolid", 33471}, - {"setcandamage", 33472}, - {"setcanradiusdamage", 33473}, - {"physicslaunchclient", 33474}, - {"setcarddisplayslot", 33477}, - {"kc_regweaponforfxremoval", 33478}, - {"laststandrevive", 33479}, - {"laststand", 33480}, - {"setspectatedefaults", 33481}, - {"getthirdpersoncrosshairoffset", 33482}, - {"disableweaponpickup", 33483}, - {"enableweaponpickup", 33484}, - {"issplitscreenplayer", 33485}, - {"getweaponslistoffhands", 33486}, - {"getweaponslistitems", 33487}, - {"getweaponslistexclusives", 33488}, - {"getweaponslist", 33489}, - {"canplayerplacesentry", 33490}, - {"canplayerplacetank", 33491}, - {"visionsetnakedforplayer", 33492}, - {"visionsetnightforplayer", 33493}, - {"visionsetmissilecamforplayer", 33494}, - {"visionsetthermalforplayer", 33495}, - {"visionsetpainforplayer", 33496}, - {"setblurforplayer", 33497}, - {"getplayerweaponmodel", 33498}, - {"getplayerknifemodel", 33499}, - {"notifyonplayercommand", 33501}, - {"canmantle", 33502}, - {"forcemantle", 33503}, - {"ismantling", 33504}, - {"playfx", 33505}, - {"playerrecoilscaleon", 33506}, - {"playerrecoilscaleoff", 33507}, - {"weaponlockstart", 33508}, - {"weaponlockfinalize", 33509}, - {"weaponlockfree", 33510}, - {"weaponlocktargettooclose", 33511}, - {"issplitscreenplayerprimary", 33512}, - {"markforeyeson", 33513}, - {"issighted", 33514}, - {"getsightedplayers", 33515}, - {"getplayerssightingme", 33516}, - {"getviewmodel", 33517}, - {"fragbuttonpressed", 33518}, - {"secondaryoffhandbuttonpressed", 33519}, - {"getcurrentweaponclipammo", 33520}, - {"setvelocity", 33521}, - {"getviewheight", 33522}, - {"getnormalizedmovement", 33523}, - {"playlocalsound", 33524}, - {"stoplocalsound", 33525}, - {"setweaponammoclip", 33526}, - {"setweaponammostock", 33527}, - {"getweaponammoclip", 33528}, - {"getweaponammostock", 33529}, - {"anyammoforweaponmodes", 33530}, - {"setclientomnvar", 33531}, - {"setclientdvar", 33532}, - {"setclientdvars", 33533}, - {"setclientspawnsighttraces", 33534}, - {"clientspawnsighttracepassed", 33535}, - {"allowads", 33536}, - {"allowjump", 33537}, - {"allowladder", 33538}, - {"allowmantle", 33539}, - {"allowsprint", 33540}, - {"setspreadoverride", 33541}, - {"resetspreadoverride", 33542}, - {"setaimspreadmovementscale", 33543}, - {"setactionslot", 33544}, - {"setviewkickscale", 33545}, - {"getviewkickscale", 33546}, - {"getweaponslistall", 33547}, - {"getweaponslistprimaries", 33548}, - {"getnormalizedcameramovement", 33549}, - {"giveweapon", 33550}, - {"takeweapon", 33551}, - {"takeallweapons", 33552}, - {"getcurrentweapon", 33553}, - {"getcurrentprimaryweapon", 33554}, - {"getcurrentoffhand", 33555}, - {"hasweapon", 33556}, - {"switchtoweapon", 33557}, - {"switchtoweaponimmediate", 33558}, - {"sub_1402e1d60", 33559}, - {"switchtooffhand", 33560}, - {"setoffhandsecondaryclass", 33561}, - {"getoffhandsecondaryclass", 33562}, - {"beginlocationselection", 33563}, - {"endlocationselection", 33564}, - {"disableweapons", 33565}, - {"enableweapons", 33566}, - {"disableoffhandweapons", 33567}, - {"enableoffhandweapons", 33568}, - {"disableweaponswitch", 33569}, - {"enableweaponswitch", 33570}, - {"openpopupmenu", 33571}, - {"openpopupmenunomouse", 33572}, - {"closepopupmenu", 33573}, - {"openmenu", 33574}, - {"closemenu", 33575}, - {"freezecontrols", 33577}, - {"disableusability", 33578}, - {"enableusability", 33579}, - {"setwhizbyspreads", 33580}, - {"setwhizbyradii", 33581}, - {"setchannelvolume", 33584}, - {"givestartammo", 33585}, - {"givemaxammo", 33586}, - {"getfractionstartammo", 33587}, - {"getfractionmaxammo", 33588}, - {"isdualwielding", 33589}, - {"isreloading", 33590}, - {"isswitchingweapon", 33591}, - {"setorigin", 33592}, - {"getvelocity", 33593}, - {"setangles", 33594}, - {"getangles", 33595}, - {"usebuttonpressed", 33596}, - {"attackbuttonpressed", 33597}, - {"adsbuttonpressed", 33598}, - {"meleebuttonpressed", 33599}, - {"playerads", 33600}, - {"isonground", 33601}, - {"isusingturret", 33602}, - {"setviewmodel", 33603}, - {"setoffhandprimaryclass", 33604}, - {"getoffhandprimaryclass", 33605}, - {"sub_14032dff0", 33610}, - {"sub_14032e040", 33611}, - {"enablemousesteer", 33612}, - {"setscriptmoverkillcam", 33613}, - {"usinggamepad", 33614}, - {"forcethirdpersonwhenfollowing", 33615}, - {"disableforcethirdpersonwhenfollowing", 33616}, - {"botsetflag", 33617}, - {"botsetstance", 33618}, - {"botsetscriptmove", 33619}, - {"botsetscriptgoal", 33620}, - {"botsetscriptgoalnode", 33621}, - {"botclearscriptgoal", 33622}, - {"botsetscriptenemy", 33623}, - {"botclearscriptenemy", 33624}, - {"botsetattacker", 33625}, - {"botgetscriptgoal", 33626}, - {"botgetscriptgoalradius", 33627}, - {"botgetscriptgoalyaw", 33628}, - {"botgetscriptgoaltype", 33629}, - {"botgetworldsize", 33631}, - {"botnodeavailable", 33632}, - {"botfindnoderandom", 33633}, - {"botmemoryevent", 33634}, - {"botnodepick", 33636}, - {"bothasscriptgoal", 33637}, - {"botgetpersonality", 33638}, - {"botthrowgrenade", 33639}, - {"botsetpersonality", 33641}, - {"botsetdifficulty", 33642}, - {"botgetdifficulty", 33643}, - {"botgetworldclosestedge", 33644}, - {"botlookatpoint", 33645}, - {"botpredictseepoint", 33646}, - {"botcanseeentity", 33647}, - {"botgetnodesonpath", 33648}, - {"botnodepickmultiple", 33649}, - {"botgetfovdot", 33651}, - {"botsetawareness", 33652}, - {"botpursuingscriptgoal", 33653}, - {"botgetscriptgoalnode", 33654}, - {"botgetimperfectenemyinfo", 33655}, - {"botsetpathingstyle", 33657}, - {"botsetdifficultysetting", 33658}, - {"botgetdifficultysetting", 33659}, - {"botgetpathdist", 33660}, - {"botisrandomized", 33661}, - {"botpressbutton", 33662}, - {"botclearbutton", 33663}, - {"botnodescoremultiple", 33664}, - {"getnodenumber", 33665}, - {"setclientowner", 33666}, - {"setotherent", 33667}, - {"setaisightlinevisible", 33668}, - {"setentityowner", 33669}, - {"nodeisdisconnected", 33670}, - {"getnearestnode", 33671}, - {"makeentitynomeleetarget", 33672}, - {"spawnagent", 33674}, - {"finishagentdamage", 33675}, - {"setagentattacker", 33676}, - {"cloneagent", 33677}, - {"agentcanseesentient", 33678}, - {"setagentwaypoint", 33679}, - {"setgoalpos", 33680}, - {"getgoalpos", 33681}, - {"setgoalnode", 33682}, - {"setgoalentity", 33683}, - {"setgoalradius", 33684}, - {"setanimscale", 33685}, - {"setorientmode", 33686}, - {"setanimmode", 33687}, - {"setphysicsmode", 33688}, - {"setclipmode", 33689}, - {"setmaxturnspeed", 33690}, - {"getmaxturnspeed", 33691}, - {"beginmelee", 33692}, - {"setscripted", 33693}, - {"dotrajectory", 33694}, - {"doanimlerp", 33695}, - {"setviewheight", 33696}, - {"claimnode", 33697}, - {"relinquishclaimednode", 33698}, - {"setradarping", 33699}, - {"visitfxent", 33700}, - {"sub_1402ef480", 33701}, - {"sub_1402ef4e0", 33702}, - {"sub_1402dd560", 33704}, - {"sub_1402dd590", 33705}, - {"allowhighjump", 33714}, - {"isjumping", 33715}, - {"ishighjumping", 33716}, - {"sub_140529a10", 33717}, - {"sub_140529a20", 33718}, - {"getbraggingright", 33719}, - {"getmodelfromentity", 33720}, - {"getweaponheatlevel", 33721}, - {"isweaponoverheated", 33722}, - {"isshiftbuttonpresseddown", 33723}, - {"sub_14052be00", 33724}, - {"sub_14052beb0", 33725}, - {"sub_14052bf30", 33726}, - {"lightsetforplayer", 33728}, - {"lightsetoverrideenableforplayer", 33729}, - {"lightsetoverridedisableforplayer", 33730}, - {"sub_140333c10", 33731}, - {"sub_140043710", 33732}, - {"sub_14052b420", 33733}, - {"sub_1402ddd70", 33734}, - {"setanimclass", 33744}, - {"enableanimstate", 33745}, - {"setanimstate", 33746}, - {"getanimentry", 33747}, - {"getanimentryname", 33748}, - {"getanimentryalias", 33749}, - {"getanimentrycount", 33750}, - {"issprinting", 33752}, - {"jumpbuttonpressed", 33758}, - {"rotateby", 33759}, - {"getlookaheaddir", 33760}, - {"getpathgoalpos", 33761}, - {"sub_140316940", 33762}, - {"setcorpsefalling", 33763}, - {"setsurfacetype", 33764}, - {"aiphysicstrace", 33765}, - {"aiphysicstracepassed", 33766}, - {"visionsetstage", 33770}, - {"linkwaypointtotargetwithoffset", 33771}, - {"getlinkedparent", 33772}, - {"getmovingplatformparent", 33773}, - {"setnameplatematerial", 33774}, - {"sub_140313d20", 33777}, - {"sub_1403131d0", 33778}, - {"makevehiclenotcollidewithplayers", 33779}, - {"setscriptablepartstate", 33782}, - {"stopsliding", 33783}, - {"sub_140316a60", 33784}, - {"setdronegoalpos", 33785}, - {"hudoutlineenable", 33786}, - {"hudoutlinedisable", 33787}, - {"worldpointtoscreenpos", 33792}, - {"botfirstavailablegrenade", 33795}, - {"emissiveblend", 33801}, - {"sub_1402e66d0", 33804}, - {"sub_1402e66e0", 33805}, - {"sub_1402e66f0", 33806}, - {"physicssetmaxlinvel", 33810}, - {"physicssetmaxangvel", 33811}, - {"physicsgetlinvel", 33812}, - {"physicsgetlinspeed", 33813}, - {"physicsgetangvel", 33814}, - {"physicsgetangspeed", 33815}, - {"disablemissileboosting", 33816}, - {"enablemissileboosting", 33817}, - {"canspawntestclient", 33818}, - {"spawntestclient", 33819}, - {"loadcustomizationplayerview", 33820}, - {"setgrenadethrowscale", 33821}, - {"setgrenadecookscale", 33822}, - {"setplanesplineid", 33823}, - {"hudoutlineenableforclient", 33824}, - {"hudoutlinedisableforclient", 33825}, - {"hudoutlineenableforclients", 33826}, - {"hudoutlinedisableforclients", 33827}, - {"turretsetbarrelspinenabled", 33828}, - {"hasloadedcustomizationplayerview", 33829}, - {"sub_140313420", 33830}, - {"sub_1403136f0", 33831}, - {"doanimrelative", 33832}, - {"getcorpseentity", 33836}, - {"logmatchdatalife", 33838}, - {"logmatchdatadeath", 33839}, - {"queuedialogforplayer", 33840}, - {"setmlgcameradefaults", 33841}, - {"ismlgspectator", 33842}, - {"disableautoreload", 33843}, - {"enableautoreload", 33844}, - {"getlinkedchildren", 33846}, - {"botpredictenemycampspots", 33847}, - {"playsoundonmovingent", 33848}, - {"cancelmantle", 33849}, - {"hasfemalecustomizationmodel", 33850}, - {"sub_1402e6bb0", 33851}, - {"setscriptabledamageowner", 33852}, - {"setfxkilldefondelete", 33853}, - {"sub_1402e1b80", 33856}, - {"sub_140310fb0", 33858}, - {"challengenotification", 33859}, - {"sub_140528300", 33860}, - {"sub_14052bff0", 33861}, - {"linktosynchronizedparent", 33862}, - {"getclientomnvar", 33863}, - {"getcacplayerdataforgroup", 33866}, - {"cloakingenable", 33867}, - {"cloakingdisable", 33868}, - {"getunnormalizedcameramovement", 33869}, - {"sub_14031edf0", 33870}, - {"isturretoverheated", 33871}, - {"sub_14052c170", 33872}, - {"sub_14052c190", 33873}, - {"sub_14052c1b0", 33874}, - {"sub_14052c1d0", 33875}, - {"sub_14052c0b0", 33878}, - {"sub_1402de140", 33879}, - {"getvieworigin", 33884}, - {"setweaponmodelvariant", 33885}, - {"ridevehicle", 33886}, - {"stopridingvehicle", 33887}, - {"autoboltmissileeffects", 33889}, - {"disablemissilestick", 33890}, - {"enablemissilestick", 33891}, - {"setmissileminimapvisible", 33892}, - {"isoffhandweaponreadytothrow", 33893}, - {"makecollidewithitemclip", 33895}, - {"visionsetpostapplyforplayer", 33897}, - {"setlookattarget", 33898}, - {"clearlookattarget", 33899}, - {"sub_14052c250", 33907}, - {"sub_14052c290", 33908}, - {"sub_14052c2f0", 33909}, - {"sub_14052c340", 33910}, - {"sub_14052c360", 33911}, - {"sub_14031c170", 33912}, - {"sub_14031c590", 33913}, - {"setclienttriggervisionset", 33914}, - {"sub_1402e41c0", 33917}, - {"sub_1402e43b0", 33918}, - {"sub_14052b4d0", 33919}, - {"sub_14052b550", 33920}, - {"showviewmodel", 33921}, - {"hideviewmodel", 33922}, - {"setpickupweapon", 33923}, - {"allowpowerslide", 33925}, - {"allowhighjumpdrop", 33926}, - {"sub_1404045e0", 33927}, - {"sub_1405297e0", 33928}, - {"sub_14052c200", 33929}, - {"clearentity", 33930}, - {"sub_140334a40", 33931}, - {"allowdodge", 33933}, - {"sub_140529860", 33934}, - {"setminimapvisible", 33935}, - {"sub_1402e0a90", 33936}, - {"sub_1402e0bc0", 33937}, - {"sub_1402e0cf0", 33938}, - {"setplayermech", 33940}, - {"setdamagecallbackon", 33941}, - {"finishentitydamage", 33942}, - {"designatefoftarget", 33946}, - {"sethintstringvisibleonlytoowner", 33947}, - {"notifyonplayercommandremove", 33948}, - {"sub_1402e3bf0", 33949}, - {"allowboostjump", 33950}, - {"batterydischargebegin", 33951}, - {"batterydischargeend", 33952}, - {"batterydischargeonce", 33953}, - {"batterygetcharge", 33954}, - {"batterysetcharge", 33955}, - {"batteryfullrecharge", 33956}, - {"batterygetsize", 33957}, - {"batterysetdischargescale", 33958}, - {"batterygetdischargerate", 33959}, - {"batteryisinuse", 33960}, - {"enablephysicaldepthoffieldscripting", 33961}, - {"disablephysicaldepthoffieldscripting", 33962}, - {"setphysicaldepthoffield", 33963}, - {"sub_140313860", 33964}, - {"sub_14052a560", 33965}, - {"sub_140321790", 33966}, - {"sub_140321a50", 33967}, - {"sub_1402dda50", 33968}, - {"sub_14052ac50", 33969}, - {"sub_14052ad50", 33970}, - {"setdemigod", 33971}, - {"sub_140310840", 33972}, - {"setcostumemodels", 33978}, - {"sub_140529e00", 33979}, - {"sub_140313510", 33980}, - {"scriptmodelpauseanim", 33981}, - {"digitaldistortsetmaterial", 33982}, - {"disableoffhandsecondaryweapons", 33983}, - {"enableoffhandsecondaryweapons", 33984}, - {"canplaceriotshield", 33985}, - {"setriotshieldfailhint", 33986}, - {"enabledetonate", 33987}, - {"getdetonateenabled", 33988}, - {"playergetuseent", 33989}, - {"refreshshieldmodels", 33990}, - {"sub_14052c3a0", 33991}, - {"locret_140406a70", 33993}, - {"getgravity", 33994}, - {"sub_140529560", 33997}, - {"sub_140529650", 33998}, - {"setcommonplayerdatareservedint", 33999}, - {"getrankedplayerdatareservedint", 34000}, - {"setrankedplayerdatareservedint", 34001}, - {"getcommonplayerdatareservedint", 34002}, - {"sub_1402e8a20", 34003}, - {"sub_14052c3c0", 34004}, - {"addsoundmutedevice", 34005}, - {"removesoundmutedevice", 34006}, - {"clientaddsoundsubmix", 34007}, - {"clientclearsoundsubmix", 34008}, - {"sub_140312520", 34009}, - {"sub_140312ba0", 34010}, - {"sub_140312bf0", 34011}, - {"sub_140312cb0", 34012}, - {"sub_140312df0", 34013}, - {"sub_140312ff0", 34014}, - {"isusingoffhand", 34016}, - {"physicsstop", 34017}, - {"sub_14031b9e0", 34018}, - {"sub_14031e3c0", 34023}, - {"sub_1402ef8a0", 34024}, - {"sub_14052c400", 34025}, - {"initwaterclienttrigger", 34026}, - {"getcurrentweaponmodelname", 34027}, - {"sub_14031f000", 34028}, - {"setignorefoliagesightingme", 34030}, - {"loadcostumemodels", 34031}, - {"sub_14030cd90", 34036}, - {"sub_14030b1c0", 34038}, - {"sub_140322450", 34039}, - {"iscloaked", 34040}, - {"sub_140528bc0", 34041}, - {"sub_140528cf0", 34042}, - {"sub_14031fb80", 34043}, - {"sub_140320180", 34044}, - {"selfieaccessselfievalidflaginplayerdef", 34045}, - {"selfieaccessselfiecustomassetsarestreamed", 34046}, - {"sub_14031ede0", 34048}, - {"selfiescreenshottaken", 34049}, - {"sub_14031f190", 34050}, - {"sub_140319de0", 34052}, - {"setmissilecoasting", 34053}, - {"setmlgspectator", 34054}, - {"gettotalmpxp", 34055}, - {"turretsetgroundaimentity", 34056}, - {"sub_140318610", 34057}, - {"sub_140317760", 34058}, - {"sub_14032e9a0", 34059}, - {"sub_140320830", 34060}, - {"sub_140329bc0", 34061}, - {"sub_14032e370", 34062}, - {"consumereinforcement", 34063}, - {"ghost", 34064}, - {"loadweapons", 34065}, - {"sub_1402e0e80", 34067}, - {"setwaypointiconfadeatcenter", 34068}, - {"setreinforcementhintstrings", 34069}, - {"playgoliathentryanim", 34070}, - {"playgoliathtoidleanim", 34071}, - {"sub_140312210", 34072}, - {"sub_140312280", 34073}, - {"sub_140321660", 34074}, - {"playlocalannouncersound", 34075}, - {"setmissilespecialclipmask", 34076}, - {"sub_140527c40", 34077}, - {"sub_140527c60", 34078}, - {"isdodging", 34079}, - {"ispowersliding", 34080}, - {"sub_140320ab0", 34081}, - {"getcurrentping", 34082}, - {"sub_1402eeb60", 34083}, - {"sub_140329390", 34084}, - {"gethordeplayerdata", 34085}, - {"sethordeplayerdata", 34086}, - {"sub_1402dcbc0", 34087}, - {"sub_14031a0b0", 34088}, - {"sub_1403198a0", 34089}, - {"sub_1403345e0", 34090}, - {"sub_1402e7d80", 34092}, - {"sub_140404f00", 34093}, - {"issplitscreenplayer2", 34095}, - {"setowneroriginal", 34096}, - {"getlinkedtagname", 34097}, - {"sub_14032de80", 34098}, - {"sub_14032dfb0", 34099}, - {"setwaypointaerialtargeting", 34100}, - {"worldweaponsloaded", 34101}, - {"sub_140320aa0", 34102}, - {"usetriggertouchcheckstance", 34103}, - {"onlystreamactiveweapon", 34104}, - {"precachekillcamiconforweapon", 34105}, - {"selfierequestupdate", 34106}, - {"getclanwarsbonus", 34107}, - {"sub_140406810", 34108}, - {"sub_1404051d0", 34109}, - {"sub_140406340", 34110}, - {"sub_1402e72a0", 34111}, - {"sub_140404c70", 34112}, - {"sub_1404065c0", 34113}, - {"sub_140405c60", 34114}, - {"sub_140406400", 34115}, - {"sub_140406230", 34116}, - {"sub_140406650", 34117}, - {"sub_1402e7de0", 34118}, - {"sub_140333550", 34119}, - {"sub_140403fe0", 34120}, - {"sub_140320360", 34121}, - {"canhighjump", 34122}, - {"setprestigemastery", 34123}, - {"sub_140403f50", 34124}, - {"sub_14030c7b0", 34125}, - {"sub_1403206b0", 34126}, - {"sub_140329960", 34127}, - {"sub_140328100", 34128}, - {"sub_140405990", 34129}, - {"sub_1402e70c0", 34130}, - {"sub_1403335f0", 34131}, - {"getcoopplayerdatareservedint", 34132}, - {"setcoopplayerdatareservedint", 34133}, - {"sub_140406b50", 34134}, - {"sub_1402de070", 34135}, - {"sub_1402e7e40", 34136}, - {"sub_140329ba0", 34137}, - {"sub_140405af0", 34138}, - {"sub_1402e7240", 34139}, - {"sub_14031a370", 34140}, - {"sub_140406970", 34141}, - {"sub_140405b60", 34142}, - {"sub_140334e10", 34143}, - {"sub_140320a90", 34144}, - {"sub_140406c00", 34145}, - {"sub_140328bf0", 34146}, - {"sub_1404053e0", 34147}, - {"sub_140406d20", 34148}, - {"sub_14032c900", 34149}, - {"sub_14032c9e0", 34150}, - {"sub_140044360", 34151}, - {"sub_140333680", 34152}, - {"sub_1402e7130", 34153}, - {"sub_1403294b0", 34154}, - {"sub_140320b40", 34155}, - {"sub_140333710", 34156}, + {"_meth_8000", 0x8000}, // SP 0x14029B0D0 MP 0x140362FD0 + {"_meth_8001", 0x8001}, // SP 0x1402A8AC0 MP 0x000000000 + {"_meth_8002", 0x8002}, // SP 0x000000000 MP 0x14055A000 + {"_meth_8003", 0x8003}, // SP 0x000000000 MP 0x140378300 + {"_meth_8004", 0x8004}, // SP 0x000000000 MP 0x1403784F0 + {"_meth_8005", 0x8005}, // SP 0x000000000 MP 0x14037AB70 + {"_meth_8006", 0x8006}, // SP 0x000000000 MP 0x14037ABD0 + {"_meth_8007", 0x8007}, // SP 0x000000000 MP 0x14037AC50 + {"_meth_8008", 0x8008}, // SP 0x000000000 MP 0x14037ACB0 + {"_meth_8009", 0x8009}, // SP 0x000000000 MP 0x14037ACC0 + {"_meth_800A", 0x800A}, // SP 0x000000000 MP 0x140374B10 + {"_meth_800B", 0x800B}, // SP 0x000000000 MP 0x140374BB0 + {"_meth_800C", 0x800C}, // SP 0x000000000 MP 0x140374D70 + {"_meth_800D", 0x800D}, // SP 0x000000000 MP 0x140374C90 + {"_meth_800E", 0x800E}, // SP 0x000000000 MP 0x14037B890 + {"_meth_800F", 0x800F}, // SP 0x000000000 MP 0x14037B930 + {"_meth_8010", 0x8010}, // SP 0x000000000 MP 0x14037B910 + {"_meth_8011", 0x8011}, // SP 0x000000000 MP 0x14037B960 + {"_meth_8012", 0x8012}, // SP 0x000000000 MP 0x1403760E0 + {"_meth_8013", 0x8013}, // SP 0x000000000 MP 0x14037B130 + {"_meth_8014", 0x8014}, // SP 0x000000000 MP 0x14037B220 + {"_meth_8015", 0x8015}, // SP 0x000000000 MP 0x14037B300 + {"_meth_8016", 0x8016}, // SP 0x000000000 MP 0x14037B510 + {"_meth_8017", 0x8017}, // SP 0x000000000 MP 0x14037AC10 + {"_meth_8018", 0x8018}, // SP 0x000000000 MP 0x14037ACD0 + {"_meth_8019", 0x8019}, // SP 0x000000000 MP 0x140378210 + {"_meth_801A", 0x801A}, // SP 0x14028F380 MP 0x14036F540 + {"_meth_801B", 0x801B}, // SP 0x000000000 MP 0x14037BD60 + {"_meth_801C", 0x801C}, // SP 0x000000000 MP 0x140374A30 + {"_meth_801D", 0x801D}, // SP 0x14029DCF0 MP 0x140369D40 + {"_meth_801E", 0x801E}, // SP 0x1402AD230 MP 0x000000000 + {"_meth_801F", 0x801F}, // SP 0x1402AD490 MP 0x000000000 + {"_meth_8020", 0x8020}, // SP 0x1402AD4C0 MP 0x000000000 + {"_meth_8021", 0x8021}, // SP 0x1402AD640 MP 0x000000000 + {"_meth_8022", 0x8022}, // SP 0x1402AD660 MP 0x000000000 + {"_meth_8023", 0x8023}, // SP 0x1402AD920 MP 0x14037BA50 + {"_meth_8024", 0x8024}, // SP 0x1402ADA90 MP 0x000000000 + {"_meth_8025", 0x8025}, // SP 0x1405D92F0 MP 0x14035CB60 + {"_meth_8026", 0x8026}, // SP 0x1405D92F0 MP 0x140377C40 + {"_meth_8028", 0x8028}, // SP 0x1402ADE80 MP 0x000000000 + {"_meth_8029", 0x8029}, // SP 0x14029AEC0 MP 0x140362D10 + {"_meth_802A", 0x802A}, // SP 0x14029E0E0 MP 0x14036A480 + {"_meth_802B", 0x802B}, // SP 0x14029E180 MP 0x14036A4C0 + {"_meth_802C", 0x802C}, // SP 0x1402A0610 MP 0x14036C860 + {"_meth_802D", 0x802D}, // SP 0x1402A0890 MP 0x14036CE90 + {"_meth_802E", 0x802E}, // SP 0x1402A0A90 MP 0x14036D040 + {"_meth_802F", 0x802F}, // SP 0x1402AE150 MP 0x000000000 + {"_meth_8030", 0x8030}, // SP 0x1402AE270 MP 0x000000000 + {"_meth_8031", 0x8031}, // SP 0x1402AE410 MP 0x000000000 + {"_meth_8032", 0x8032}, // SP 0x1402AE620 MP 0x000000000 + {"_meth_8033", 0x8033}, // SP 0x1402AE6E0 MP 0x000000000 + {"_meth_8034", 0x8034}, // SP 0x1402CBC10 MP 0x000000000 + {"_meth_8035", 0x8035}, // SP 0x1402CBBA0 MP 0x14031F650 + {"_meth_8036", 0x8036}, // SP 0x1402CBA70 MP 0x14031F520 + {"_meth_8037", 0x8037}, // SP 0x1402CBB20 MP 0x14031F5D0 + {"_meth_8038", 0x8038}, // SP 0x1402AB240 MP 0x000000000 + {"_meth_8039", 0x8039}, // SP 0x1402AB320 MP 0x000000000 + {"_meth_803A", 0x803A}, // SP 0x1402AB6D0 MP 0x000000000 + {"_meth_803B", 0x803B}, // SP 0x1402ACA20 MP 0x000000000 + {"_meth_803C", 0x803C}, // SP 0x1402ACA40 MP 0x000000000 + {"_meth_803D", 0x803D}, // SP 0x1402ACBA0 MP 0x000000000 + {"_meth_803E", 0x803E}, // SP 0x1402AFA80 MP 0x000000000 + {"_meth_803F", 0x803F}, // SP 0x1402AFAC0 MP 0x000000000 + {"_meth_8040", 0x8040}, // SP 0x1402AFB90 MP 0x000000000 + {"_meth_8041", 0x8041}, // SP 0x1402AFC50 MP 0x000000000 + {"_meth_8042", 0x8042}, // SP 0x1402AFCA0 MP 0x000000000 + {"_meth_8043", 0x8043}, // SP 0x1402A8990 MP 0x000000000 + {"_meth_8044", 0x8044}, // SP 0x1402A89F0 MP 0x000000000 + {"_meth_8045", 0x8045}, // SP 0x14028F020 MP 0x14036EDF0 + {"_meth_8046", 0x8046}, // SP 0x14028F1F0 MP 0x14036EEE0 + {"_meth_8047", 0x8047}, // SP 0x1402ACE10 MP 0x000000000 + {"_meth_8048", 0x8048}, // SP 0x1402ACE50 MP 0x000000000 + {"_meth_8049", 0x8049}, // SP 0x1402A1060 MP 0x14036D280 + {"_meth_804A", 0x804A}, // SP 0x1402A1500 MP 0x14036D940 + {"_meth_804B", 0x804B}, // SP 0x1402A1930 MP 0x14036DC50 + {"_meth_804C", 0x804C}, // SP 0x1402A1C90 MP 0x14036E320 + {"_meth_804D", 0x804D}, // SP 0x1402A2000 MP 0x14036E480 + {"_meth_804E", 0x804E}, // SP 0x1402A2370 MP 0x14036ECC0 + {"_meth_804F", 0x804F}, // SP 0x1402A3670 MP 0x140358AF0 + {"_meth_8050", 0x8050}, // SP 0x1402A3AB0 MP 0x140359830 + {"_meth_8051", 0x8051}, // SP 0x1402A3AD0 MP 0x140359850 + {"_meth_8052", 0x8052}, // SP 0x1402AD0F0 MP 0x140379AD0 + {"_meth_8053", 0x8053}, // SP 0x1402A2B80 MP 0x14036B270 + {"_meth_8054", 0x8054}, // SP 0x1402AD260 MP 0x000000000 + {"_meth_8055", 0x8055}, // SP 0x1402AD6A0 MP 0x14037A9E0 + {"_meth_8056", 0x8056}, // SP 0x1402AD6C0 MP 0x14037AAA0 + {"_meth_8057", 0x8057}, // SP 0x1402AD7A0 MP 0x000000000 + {"_meth_8058", 0x8058}, // SP 0x1402AD7D0 MP 0x000000000 + {"_meth_8059", 0x8059}, // SP 0x14028E1E0 MP 0x14036F090 + {"_meth_805A", 0x805A}, // SP 0x14028E390 MP 0x14036F4C0 + {"_meth_805B", 0x805B}, // SP 0x14028E490 MP 0x14036F5F0 + {"_meth_805C", 0x805C}, // SP 0x14028E750 MP 0x14036F770 + {"_meth_805D", 0x805D}, // SP 0x1402A8420 MP 0x000000000 + {"_meth_805E", 0x805E}, // SP 0x1402A8440 MP 0x000000000 + {"_meth_805F", 0x805F}, // SP 0x1402A8460 MP 0x000000000 + {"_meth_8060", 0x8060}, // SP 0x1402A8480 MP 0x000000000 + {"_meth_8061", 0x8061}, // SP 0x1402A9250 MP 0x000000000 + {"_meth_8062", 0x8062}, // SP 0x1402A92D0 MP 0x000000000 + {"_meth_8063", 0x8063}, // SP 0x1402A9BC0 MP 0x000000000 + {"_meth_8064", 0x8064}, // SP 0x1402AABA0 MP 0x000000000 + {"_meth_8065", 0x8065}, // SP 0x1402AAC10 MP 0x000000000 + {"_meth_8067", 0x8067}, // SP 0x1402AD9A0 MP 0x140375030 + {"_meth_8068", 0x8068}, // SP 0x1402ADCD0 MP 0x140375210 + {"_meth_8069", 0x8069}, // SP 0x1402ADF10 MP 0x000000000 + {"_meth_806A", 0x806A}, // SP 0x14028D6B0 MP 0x1403598E0 + {"_meth_806B", 0x806B}, // SP 0x14028EA50 MP 0x14035A950 + {"_meth_806C", 0x806C}, // SP 0x1402ACB60 MP 0x000000000 + {"_meth_806E", 0x806E}, // SP 0x1402A27D0 MP 0x14035AB10 + {"_meth_806F", 0x806F}, // SP 0x1402A23E0 MP 0x14035A9C0 + {"_meth_8070", 0x8070}, // SP 0x1402A2980 MP 0x14035B0D0 + {"_meth_8071", 0x8071}, // SP 0x1402A28C0 MP 0x14035AB50 + {"_meth_8072", 0x8072}, // SP 0x140291F10 MP 0x000000000 + {"_meth_8073", 0x8073}, // SP 0x1405D92F0 MP 0x000000000 + {"_meth_8074", 0x8074}, // SP 0x1405D92F0 MP 0x000000000 + {"_meth_8075", 0x8075}, // SP 0x1405D92F0 MP 0x000000000 + {"_meth_8076", 0x8076}, // SP 0x1402ACC40 MP 0x1403798B0 + {"_meth_8077", 0x8077}, // SP 0x1402ACC60 MP 0x1403798F0 + {"_meth_8078", 0x8078}, // SP 0x1402ACCD0 MP 0x000000000 + {"_meth_8079", 0x8079}, // SP 0x1402ACD40 MP 0x000000000 + {"_meth_807A", 0x807A}, // SP 0x1402ACDD0 MP 0x000000000 + {"_meth_807B", 0x807B}, // SP 0x1402ACE30 MP 0x000000000 + {"_meth_807C", 0x807C}, // SP 0x1402ACEE0 MP 0x000000000 + {"_meth_807D", 0x807D}, // SP 0x1402ACFF0 MP 0x1403799E0 + {"_meth_807E", 0x807E}, // SP 0x14028FA50 MP 0x14035B880 + {"_meth_807F", 0x807F}, // SP 0x14028FB40 MP 0x14035B8D0 + {"_meth_8080", 0x8080}, // SP 0x14028FB60 MP 0x14035BD70 + {"_meth_8081", 0x8081}, // SP 0x14028FBE0 MP 0x14035C100 + {"_meth_8082", 0x8082}, // SP 0x140292720 MP 0x14035DCB0 + {"_meth_8083", 0x8083}, // SP 0x140290050 MP 0x14035C5A0 + {"_meth_8084", 0x8084}, // SP 0x14026DC10 MP 0x14033BBF0 + {"_meth_8085", 0x8085}, // SP 0x14026DC60 MP 0x14033BC00 + {"_meth_8086", 0x8086}, // SP 0x14026E020 MP 0x14033BF50 + {"_meth_8087", 0x8087}, // SP 0x14026E160 MP 0x14033C090 + {"_meth_8088", 0x8088}, // SP 0x14026E240 MP 0x14033C170 + {"_meth_8089", 0x8089}, // SP 0x14026E380 MP 0x14033C230 + {"_meth_808A", 0x808A}, // SP 0x14026E3C0 MP 0x14033C310 + {"_meth_808B", 0x808B}, // SP 0x14026E500 MP 0x14033C3F0 + {"_meth_808C", 0x808C}, // SP 0x14026E440 MP 0x14033C360 + {"_meth_808D", 0x808D}, // SP 0x14026E0C0 MP 0x14033BFF0 + {"_meth_808E", 0x808E}, // SP 0x1402A83E0 MP 0x000000000 + {"_meth_808F", 0x808F}, // SP 0x1402A8400 MP 0x000000000 + {"_meth_8090", 0x8090}, // SP 0x1402A8970 MP 0x000000000 + {"_meth_8091", 0x8091}, // SP 0x1402A89D0 MP 0x000000000 + {"_meth_8092", 0x8092}, // SP 0x1402AD800 MP 0x000000000 + {"_meth_8093", 0x8093}, // SP 0x1402A9070 MP 0x1403752A0 + {"_meth_8094", 0x8094}, // SP 0x1402A0070 MP 0x140358360 + {"_meth_8095", 0x8095}, // SP 0x1402AAC80 MP 0x000000000 + {"_meth_8096", 0x8096}, // SP 0x1402AAD20 MP 0x000000000 + {"_meth_8097", 0x8097}, // SP 0x1402AADC0 MP 0x140377CA0 + {"_meth_8098", 0x8098}, // SP 0x1402AAE70 MP 0x000000000 + {"_meth_8099", 0x8099}, // SP 0x1402AAF90 MP 0x000000000 + {"_meth_809A", 0x809A}, // SP 0x1402AC1D0 MP 0x000000000 + {"_meth_809B", 0x809B}, // SP 0x1402AC470 MP 0x140377D00 + {"_meth_809C", 0x809C}, // SP 0x1402AC9B0 MP 0x140377F40 + {"_meth_80A1", 0x80A1}, // SP 0x140290320 MP 0x14035CAF0 + {"_meth_80A2", 0x80A2}, // SP 0x140290680 MP 0x14035CE40 + {"_meth_80A3", 0x80A3}, // SP 0x140290960 MP 0x14035D290 + {"_meth_80A4", 0x80A4}, // SP 0x140294B30 MP 0x14035F4A0 + {"_meth_80A5", 0x80A5}, // SP 0x140295300 MP 0x14035FD70 + {"_meth_80A6", 0x80A6}, // SP 0x1402958C0 MP 0x000000000 + {"_meth_80A7", 0x80A7}, // SP 0x1402960D0 MP 0x000000000 + {"_meth_80A8", 0x80A8}, // SP 0x140297190 MP 0x000000000 + {"_meth_80A9", 0x80A9}, // SP 0x140297C20 MP 0x000000000 + {"_meth_80AA", 0x80AA}, // SP 0x14029DDD0 MP 0x1403663C0 + {"_meth_80AB", 0x80AB}, // SP 0x140290390 MP 0x14035B440 + {"_meth_80AC", 0x80AC}, // SP 0x1402904A0 MP 0x14035B650 + {"_meth_80AD", 0x80AD}, // SP 0x1402987B0 MP 0x14035FAA0 + {"_meth_80AE", 0x80AE}, // SP 0x140290F40 MP 0x14035C610 + {"_meth_80AF", 0x80AF}, // SP 0x140299090 MP 0x140360200 + {"_meth_80B0", 0x80B0}, // SP 0x140299200 MP 0x1403602A0 + {"_meth_80B1", 0x80B1}, // SP 0x1402997D0 MP 0x1403608E0 + {"_meth_80B2", 0x80B2}, // SP 0x14029DAA0 MP 0x140366320 + {"_meth_80B3", 0x80B3}, // SP 0x14029C8F0 MP 0x1403677D0 + {"_meth_80B4", 0x80B4}, // SP 0x14029A0F0 MP 0x140361C30 + {"_meth_80B5", 0x80B5}, // SP 0x14029A250 MP 0x140361F90 + {"_meth_80B8", 0x80B8}, // SP 0x14029A450 MP 0x1403623A0 + {"_meth_80B9", 0x80B9}, // SP 0x14029AAF0 MP 0x140362B70 + {"_meth_80BA", 0x80BA}, // SP 0x14029BF20 MP 0x140364290 + {"_meth_80BB", 0x80BB}, // SP 0x14029C080 MP 0x140364630 + {"_meth_80BC", 0x80BC}, // SP 0x000000000 MP 0x140364910 + {"_meth_80BD", 0x80BD}, // SP 0x000000000 MP 0x140364A50 + {"_meth_80BE", 0x80BE}, // SP 0x000000000 MP 0x140364D40 + {"_meth_80C0", 0x80C0}, // SP 0x140297CC0 MP 0x14035FDD0 + {"_meth_80C1", 0x80C1}, // SP 0x140297E90 MP 0x1403600D0 + {"_meth_80C2", 0x80C2}, // SP 0x140297FF0 MP 0x140360320 + {"_meth_80C3", 0x80C3}, // SP 0x1402A1730 MP 0x140359740 + {"_meth_80C4", 0x80C4}, // SP 0x1402A1A80 MP 0x140359DC0 + {"_meth_80C5", 0x80C5}, // SP 0x140266A20 MP 0x000000000 + {"_meth_80C6", 0x80C6}, // SP 0x1402634D0 MP 0x000000000 + {"_meth_80C7", 0x80C7}, // SP 0x1404657D0 MP 0x000000000 + {"_meth_80C8", 0x80C8}, // SP 0x140463A30 MP 0x000000000 + {"_meth_80C9", 0x80C9}, // SP 0x140465630 MP 0x000000000 + {"_meth_80CA", 0x80CA}, // SP 0x1404656C0 MP 0x000000000 + {"_meth_80CB", 0x80CB}, // SP 0x140464F50 MP 0x000000000 + {"_meth_80CC", 0x80CC}, // SP 0x14026CE20 MP 0x14033AF40 + {"_meth_80CD", 0x80CD}, // SP 0x1405D92F0 MP 0x14033B030 + {"_meth_80CE", 0x80CE}, // SP 0x14026CEE0 MP 0x14033B040 + {"_meth_80CF", 0x80CF}, // SP 0x14026D230 MP 0x14033B3A0 + {"_meth_80D0", 0x80D0}, // SP 0x14026D3B0 MP 0x14033B530 + {"_meth_80D1", 0x80D1}, // SP 0x14026D490 MP 0x14033B600 + {"_meth_80D2", 0x80D2}, // SP 0x14026D560 MP 0x14033B6C0 + {"_meth_80D3", 0x80D3}, // SP 0x14026D630 MP 0x14033B760 + {"_meth_80D4", 0x80D4}, // SP 0x14026D700 MP 0x14033B810 + {"_meth_80D5", 0x80D5}, // SP 0x14026D7D0 MP 0x14033B8D0 + {"_meth_80D6", 0x80D6}, // SP 0x14026D8A0 MP 0x14033B970 + {"_meth_80D7", 0x80D7}, // SP 0x14026D970 MP 0x14033BA20 + {"_meth_80D8", 0x80D8}, // SP 0x14026D990 MP 0x14033BA40 + {"_meth_80D9", 0x80D9}, // SP 0x14026D9B0 MP 0x14033BA60 + {"_meth_80DA", 0x80DA}, // SP 0x14026DA50 MP 0x14033BAE0 + {"_meth_80DB", 0x80DB}, // SP 0x14026DBC0 MP 0x14033BBE0 + {"_meth_80DC", 0x80DC}, // SP 0x1402983E0 MP 0x1403607E0 + {"_meth_80DD", 0x80DD}, // SP 0x140299300 MP 0x140361060 + {"_meth_80DE", 0x80DE}, // SP 0x000000000 MP 0x140375C60 + {"_meth_80DF", 0x80DF}, // SP 0x140299730 MP 0x140361260 + {"_meth_80E0", 0x80E0}, // SP 0x140299930 MP 0x140361530 + {"_meth_80E1", 0x80E1}, // SP 0x140298080 MP 0x140360440 + {"_meth_80E2", 0x80E2}, // SP 0x140298160 MP 0x140360570 + {"_meth_80E3", 0x80E3}, // SP 0x1405D92F0 MP 0x140360620 + {"_meth_80E4", 0x80E4}, // SP 0x140291140 MP 0x14035D1B0 + {"_meth_80E5", 0x80E5}, // SP 0x1402912D0 MP 0x14035D310 + {"_meth_80E6", 0x80E6}, // SP 0x140291490 MP 0x14035D460 + {"_meth_80E7", 0x80E7}, // SP 0x1402915B0 MP 0x14035D650 + {"_meth_80E8", 0x80E8}, // SP 0x1402916E0 MP 0x14035D8D0 + {"_meth_80E9", 0x80E9}, // SP 0x140291A10 MP 0x14035DA40 + {"_meth_80EA", 0x80EA}, // SP 0x000000000 MP 0x14035C870 + {"_meth_80EB", 0x80EB}, // SP 0x000000000 MP 0x14035CDD0 + {"_meth_80EC", 0x80EC}, // SP 0x140293380 MP 0x14035E870 + {"_meth_80ED", 0x80ED}, // SP 0x140293430 MP 0x14035EE50 + {"_meth_80EE", 0x80EE}, // SP 0x140268590 MP 0x000000000 + {"_meth_80EF", 0x80EF}, // SP 0x1402685F0 MP 0x000000000 + {"_meth_80F0", 0x80F0}, // SP 0x140268640 MP 0x000000000 + {"_meth_80F1", 0x80F1}, // SP 0x140268690 MP 0x000000000 + {"_meth_80F2", 0x80F2}, // SP 0x1402686F0 MP 0x000000000 + {"_meth_80F3", 0x80F3}, // SP 0x140268750 MP 0x000000000 + {"_meth_80F4", 0x80F4}, // SP 0x1402687A0 MP 0x000000000 + {"_meth_80F5", 0x80F5}, // SP 0x140268AF0 MP 0x000000000 + {"_meth_80F6", 0x80F6}, // SP 0x140268CC0 MP 0x000000000 + {"_meth_80F7", 0x80F7}, // SP 0x140268D20 MP 0x000000000 + {"_meth_80F8", 0x80F8}, // SP 0x140268D80 MP 0x000000000 + {"_meth_80F9", 0x80F9}, // SP 0x140268E10 MP 0x000000000 + {"_meth_80FA", 0x80FA}, // SP 0x140268EC0 MP 0x000000000 + {"_meth_80FB", 0x80FB}, // SP 0x140262E80 MP 0x14032F050 + {"_meth_80FC", 0x80FC}, // SP 0x140268890 MP 0x000000000 + {"_meth_80FD", 0x80FD}, // SP 0x1402688E0 MP 0x000000000 + {"_meth_80FE", 0x80FE}, // SP 0x1402689B0 MP 0x000000000 + {"_meth_80FF", 0x80FF}, // SP 0x140268A40 MP 0x000000000 + {"_meth_8100", 0x8100}, // SP 0x1402611F0 MP 0x14032CF70 + {"_meth_8101", 0x8101}, // SP 0x140261420 MP 0x14032D270 + {"_meth_8102", 0x8102}, // SP 0x140268930 MP 0x000000000 + {"_meth_8103", 0x8103}, // SP 0x1402616E0 MP 0x000000000 + {"_meth_8104", 0x8104}, // SP 0x1402667A0 MP 0x000000000 + {"_meth_8105", 0x8105}, // SP 0x1402935E0 MP 0x14035EF40 + {"_meth_8106", 0x8106}, // SP 0x140293F00 MP 0x14035F1B0 + {"_meth_8107", 0x8107}, // SP 0x1402942F0 MP 0x14035F6D0 + {"_meth_8108", 0x8108}, // SP 0x140294600 MP 0x14035F860 + {"_meth_8109", 0x8109}, // SP 0x140294A20 MP 0x14035FB70 + {"_meth_810A", 0x810A}, // SP 0x140294E90 MP 0x14035FE30 + {"_meth_810B", 0x810B}, // SP 0x140295270 MP 0x140360040 + {"_meth_810C", 0x810C}, // SP 0x1402957F0 MP 0x1403606C0 + {"_meth_810D", 0x810D}, // SP 0x140295A70 MP 0x140360990 + {"_meth_810E", 0x810E}, // SP 0x140295D50 MP 0x1403609A0 + {"_meth_810F", 0x810F}, // SP 0x14028A710 MP 0x000000000 + {"_meth_8110", 0x8110}, // SP 0x14028A730 MP 0x000000000 + {"_meth_8111", 0x8111}, // SP 0x14028A750 MP 0x000000000 + {"_meth_8112", 0x8112}, // SP 0x14028A770 MP 0x000000000 + {"_meth_8113", 0x8113}, // SP 0x14028A790 MP 0x000000000 + {"_meth_8114", 0x8114}, // SP 0x14028A7B0 MP 0x000000000 + {"_meth_8115", 0x8115}, // SP 0x14028A7C0 MP 0x000000000 + {"_meth_8116", 0x8116}, // SP 0x14028A7E0 MP 0x000000000 + {"_meth_8117", 0x8117}, // SP 0x14028A800 MP 0x000000000 + {"_meth_8118", 0x8118}, // SP 0x14028A8E0 MP 0x000000000 + {"_meth_8119", 0x8119}, // SP 0x14028A960 MP 0x000000000 + {"_meth_811A", 0x811A}, // SP 0x140261760 MP 0x14032D140 + {"_meth_811B", 0x811B}, // SP 0x140261870 MP 0x14032D2D0 + {"_meth_811C", 0x811C}, // SP 0x140261950 MP 0x14032D630 + {"_meth_811D", 0x811D}, // SP 0x140261A30 MP 0x14032D780 + {"_meth_811E", 0x811E}, // SP 0x140269090 MP 0x000000000 + {"_meth_811F", 0x811F}, // SP 0x140269510 MP 0x000000000 + {"_meth_8121", 0x8121}, // SP 0x1402692D0 MP 0x000000000 + {"_meth_8122", 0x8122}, // SP 0x140269350 MP 0x000000000 + {"_meth_8123", 0x8123}, // SP 0x140269650 MP 0x000000000 + {"_meth_8128", 0x8128}, // SP 0x140269650 MP 0x000000000 + {"_meth_8129", 0x8129}, // SP 0x140269370 MP 0x000000000 + {"_meth_812A", 0x812A}, // SP 0x1402680B0 MP 0x000000000 + {"_meth_812B", 0x812B}, // SP 0x1402681E0 MP 0x000000000 + {"_meth_812C", 0x812C}, // SP 0x1402691F0 MP 0x000000000 + {"_meth_812D", 0x812D}, // SP 0x140268290 MP 0x000000000 + {"_meth_812E", 0x812E}, // SP 0x140267290 MP 0x14032B170 + {"_meth_812F", 0x812F}, // SP 0x140267650 MP 0x14032B720 + {"_meth_8130", 0x8130}, // SP 0x140262E20 MP 0x14032F570 + {"_meth_8131", 0x8131}, // SP 0x1402684C0 MP 0x000000000 + {"_meth_8132", 0x8132}, // SP 0x140261580 MP 0x14032CD50 + {"_meth_8133", 0x8133}, // SP 0x140261670 MP 0x14032CF00 + {"_meth_8134", 0x8134}, // SP 0x140268530 MP 0x000000000 + {"_meth_8135", 0x8135}, // SP 0x140295E90 MP 0x140360A40 + {"_meth_8136", 0x8136}, // SP 0x140296650 MP 0x140360E90 + {"_meth_8137", 0x8137}, // SP 0x1402967E0 MP 0x140361150 + {"_meth_8138", 0x8138}, // SP 0x140296C90 MP 0x140361320 + {"_meth_8139", 0x8139}, // SP 0x140296D70 MP 0x140361370 + {"_meth_813A", 0x813A}, // SP 0x140296E90 MP 0x1403615A0 + {"_meth_813B", 0x813B}, // SP 0x1402D7DD0 MP 0x140077920 + {"_meth_813C", 0x813C}, // SP 0x1402D7EE0 MP 0x140077A40 + {"_meth_813D", 0x813D}, // SP 0x1402D7FE0 MP 0x000000000 + {"_meth_813E", 0x813E}, // SP 0x1402D8040 MP 0x000000000 + {"_meth_813F", 0x813F}, // SP 0x1402D80E0 MP 0x000000000 + {"_meth_8140", 0x8140}, // SP 0x14028A390 MP 0x000000000 + {"_meth_8142", 0x8142}, // SP 0x14028A3D0 MP 0x000000000 + {"_meth_8143", 0x8143}, // SP 0x14028A370 MP 0x000000000 + {"_meth_8144", 0x8144}, // SP 0x14028A410 MP 0x000000000 + {"_meth_8145", 0x8145}, // SP 0x14028A490 MP 0x000000000 + {"_meth_8146", 0x8146}, // SP 0x14028A4B0 MP 0x000000000 + {"_meth_8147", 0x8147}, // SP 0x14028A4C0 MP 0x000000000 + {"_meth_8148", 0x8148}, // SP 0x14028A4E0 MP 0x000000000 + {"_meth_8149", 0x8149}, // SP 0x14028A500 MP 0x000000000 + {"_meth_814A", 0x814A}, // SP 0x14028A520 MP 0x000000000 + {"_meth_814B", 0x814B}, // SP 0x14028A530 MP 0x000000000 + {"_meth_814C", 0x814C}, // SP 0x14028A550 MP 0x000000000 + {"_meth_814D", 0x814D}, // SP 0x14028A570 MP 0x000000000 + {"_meth_814E", 0x814E}, // SP 0x14028A590 MP 0x000000000 + {"_meth_814F", 0x814F}, // SP 0x14028A5A0 MP 0x000000000 + {"_meth_8150", 0x8150}, // SP 0x14028A5C0 MP 0x000000000 + {"_meth_8151", 0x8151}, // SP 0x14028A5E0 MP 0x000000000 + {"_meth_8152", 0x8152}, // SP 0x14028A650 MP 0x000000000 + {"_meth_8153", 0x8153}, // SP 0x14028A690 MP 0x000000000 + {"_meth_8154", 0x8154}, // SP 0x14028A6E0 MP 0x000000000 + {"_meth_8155", 0x8155}, // SP 0x14028A700 MP 0x000000000 + {"_meth_8156", 0x8156}, // SP 0x1405D92F0 MP 0x140361680 + {"_meth_8157", 0x8157}, // SP 0x140297730 MP 0x140362260 + {"_meth_8158", 0x8158}, // SP 0x140297890 MP 0x140362410 + {"_meth_8159", 0x8159}, // SP 0x140297D20 MP 0x1403629F0 + {"_meth_815A", 0x815A}, // SP 0x140297F90 MP 0x140362CB0 + {"_meth_815B", 0x815B}, // SP 0x1402980D0 MP 0x140363040 + {"_meth_815C", 0x815C}, // SP 0x140298800 MP 0x1403638A0 + {"_meth_815D", 0x815D}, // SP 0x140298880 MP 0x140363B30 + {"_meth_815E", 0x815E}, // SP 0x140299040 MP 0x140363CF0 + {"_meth_815F", 0x815F}, // SP 0x1402495F0 MP 0x000000000 + {"_meth_8160", 0x8160}, // SP 0x1402496C0 MP 0x000000000 + {"_meth_8161", 0x8161}, // SP 0x140249790 MP 0x000000000 + {"_meth_8162", 0x8162}, // SP 0x140249810 MP 0x000000000 + {"_meth_8163", 0x8163}, // SP 0x140249950 MP 0x000000000 + {"_meth_8164", 0x8164}, // SP 0x140249A30 MP 0x000000000 + {"_meth_8165", 0x8165}, // SP 0x140249AC0 MP 0x000000000 + {"_meth_8166", 0x8166}, // SP 0x140249B00 MP 0x000000000 + {"_meth_8167", 0x8167}, // SP 0x140249BE0 MP 0x000000000 + {"_meth_8168", 0x8168}, // SP 0x140249C70 MP 0x000000000 + {"_meth_8169", 0x8169}, // SP 0x140262B90 MP 0x14032E0A0 + {"_meth_816A", 0x816A}, // SP 0x140249D10 MP 0x000000000 + {"_meth_816B", 0x816B}, // SP 0x140249EE0 MP 0x000000000 + {"_meth_816C", 0x816C}, // SP 0x14024A0E0 MP 0x000000000 + {"_meth_816D", 0x816D}, // SP 0x14024A200 MP 0x000000000 + {"_meth_816E", 0x816E}, // SP 0x14024A2D0 MP 0x000000000 + {"_meth_816F", 0x816F}, // SP 0x14024A3F0 MP 0x000000000 + {"_meth_8170", 0x8170}, // SP 0x14024A480 MP 0x000000000 + {"_meth_8171", 0x8171}, // SP 0x14024A5C0 MP 0x000000000 + {"_meth_8172", 0x8172}, // SP 0x14024A630 MP 0x000000000 + {"_meth_8173", 0x8173}, // SP 0x14024A710 MP 0x000000000 + {"_meth_8174", 0x8174}, // SP 0x14024A880 MP 0x000000000 + {"_meth_8175", 0x8175}, // SP 0x14024AAD0 MP 0x000000000 + {"_meth_8176", 0x8176}, // SP 0x14024AB30 MP 0x000000000 + {"_meth_8177", 0x8177}, // SP 0x14024AB90 MP 0x000000000 + {"_meth_8178", 0x8178}, // SP 0x14024AC50 MP 0x000000000 + {"_meth_8179", 0x8179}, // SP 0x1402D77E0 MP 0x1400772C0 + {"_meth_817A", 0x817A}, // SP 0x1402D7820 MP 0x140077300 + {"_meth_817B", 0x817B}, // SP 0x1402D7BE0 MP 0x1400776E0 + {"_meth_817C", 0x817C}, // SP 0x1402D7C50 MP 0x140077750 + {"_meth_817D", 0x817D}, // SP 0x140299220 MP 0x140363EE0 + {"_meth_817E", 0x817E}, // SP 0x1402994D0 MP 0x140364690 + {"_meth_817F", 0x817F}, // SP 0x140297DE0 MP 0x14035EEE0 + {"_meth_8180", 0x8180}, // SP 0x14029D1C0 MP 0x140364F90 + {"_meth_8181", 0x8181}, // SP 0x14029D430 MP 0x140365230 + {"_meth_8182", 0x8182}, // SP 0x140299FA0 MP 0x140360F20 + {"_meth_8183", 0x8183}, // SP 0x14029A5A0 MP 0x140361420 + {"_meth_8184", 0x8184}, // SP 0x14029E360 MP 0x140368090 + {"_meth_8185", 0x8185}, // SP 0x14029E810 MP 0x140368320 + {"_meth_8186", 0x8186}, // SP 0x14028E580 MP 0x14036D490 + {"_meth_8187", 0x8187}, // SP 0x14028F160 MP 0x14036DEC0 + {"_meth_8188", 0x8188}, // SP 0x14029B970 MP 0x140366E70 + {"_meth_8189", 0x8189}, // SP 0x14029BB30 MP 0x140367230 + {"_meth_818A", 0x818A}, // SP 0x14029EF20 MP 0x140368890 + {"_meth_818B", 0x818B}, // SP 0x14029F990 MP 0x140369900 + {"_meth_818C", 0x818C}, // SP 0x1402A15D0 MP 0x14036AD20 + {"_meth_818D", 0x818D}, // SP 0x140247D90 MP 0x000000000 + {"_meth_818E", 0x818E}, // SP 0x140247DE0 MP 0x000000000 + {"_meth_818F", 0x818F}, // SP 0x140247E50 MP 0x000000000 + {"_meth_8190", 0x8190}, // SP 0x140247E90 MP 0x000000000 + {"_meth_8191", 0x8191}, // SP 0x140247F00 MP 0x000000000 + {"_meth_8192", 0x8192}, // SP 0x140247F90 MP 0x000000000 + {"_meth_8193", 0x8193}, // SP 0x140248160 MP 0x000000000 + {"_meth_8194", 0x8194}, // SP 0x1402484A0 MP 0x000000000 + {"_meth_8195", 0x8195}, // SP 0x1402485A0 MP 0x000000000 + {"_meth_8196", 0x8196}, // SP 0x1402485F0 MP 0x000000000 + {"_meth_8197", 0x8197}, // SP 0x140248640 MP 0x000000000 + {"_meth_8198", 0x8198}, // SP 0x1402486A0 MP 0x000000000 + {"_meth_8199", 0x8199}, // SP 0x1402486F0 MP 0x000000000 + {"_meth_819E", 0x819E}, // SP 0x1402487C0 MP 0x000000000 + {"_meth_819F", 0x819F}, // SP 0x140248870 MP 0x000000000 + {"_meth_81A0", 0x81A0}, // SP 0x1402488C0 MP 0x000000000 + {"_meth_81A1", 0x81A1}, // SP 0x140248970 MP 0x14044F980 + {"_meth_81A2", 0x81A2}, // SP 0x1402489E0 MP 0x14044F830 + {"_meth_81A3", 0x81A3}, // SP 0x140248A50 MP 0x14044F8D0 + {"_meth_81A4", 0x81A4}, // SP 0x140248B30 MP 0x000000000 + {"_meth_81A5", 0x81A5}, // SP 0x140248BD0 MP 0x000000000 + {"_meth_81A6", 0x81A6}, // SP 0x140248CC0 MP 0x000000000 + {"_meth_81A7", 0x81A7}, // SP 0x140248DD0 MP 0x000000000 + {"_meth_81A8", 0x81A8}, // SP 0x140247750 MP 0x000000000 + {"_meth_81A9", 0x81A9}, // SP 0x140248E30 MP 0x000000000 + {"_meth_81AA", 0x81AA}, // SP 0x140248FB0 MP 0x000000000 + {"_meth_81AB", 0x81AB}, // SP 0x1402490D0 MP 0x000000000 + {"_meth_81AC", 0x81AC}, // SP 0x140249170 MP 0x000000000 + {"_meth_81AD", 0x81AD}, // SP 0x140249290 MP 0x000000000 + {"_meth_81AE", 0x81AE}, // SP 0x140249460 MP 0x000000000 + {"_meth_81AF", 0x81AF}, // SP 0x1402494B0 MP 0x000000000 + {"_meth_81B0", 0x81B0}, // SP 0x140249500 MP 0x000000000 + {"_meth_81B1", 0x81B1}, // SP 0x1402A15D0 MP 0x14036ADA0 + {"_meth_81B2", 0x81B2}, // SP 0x1402A15D0 MP 0x14036AE60 + {"_meth_81B3", 0x81B3}, // SP 0x1402A1640 MP 0x14036AFA0 + {"_meth_81B4", 0x81B4}, // SP 0x14029B1E0 MP 0x1403668B0 + {"_meth_81B5", 0x81B5}, // SP 0x1402998B0 MP 0x140364980 + {"_meth_81B6", 0x81B6}, // SP 0x140299AA0 MP 0x140364B50 + {"_meth_81B7", 0x81B7}, // SP 0x140299CA0 MP 0x140364F40 + {"_meth_81B8", 0x81B8}, // SP 0x140299F20 MP 0x1403650C0 + {"_meth_81B9", 0x81B9}, // SP 0x14029AF00 MP 0x1403665A0 + {"_meth_81BA", 0x81BA}, // SP 0x14024AF80 MP 0x000000000 + {"_meth_81BB", 0x81BB}, // SP 0x14024B160 MP 0x000000000 + {"_meth_81BC", 0x81BC}, // SP 0x14024B3B0 MP 0x000000000 + {"_meth_81BD", 0x81BD}, // SP 0x14024B4F0 MP 0x000000000 + {"_meth_81BE", 0x81BE}, // SP 0x14024B570 MP 0x000000000 + {"_meth_81BF", 0x81BF}, // SP 0x14024B910 MP 0x000000000 + {"_meth_81C0", 0x81C0}, // SP 0x14024BA40 MP 0x000000000 + {"_meth_81C1", 0x81C1}, // SP 0x14024BB20 MP 0x000000000 + {"_meth_81C2", 0x81C2}, // SP 0x14024BB90 MP 0x000000000 + {"_meth_81C3", 0x81C3}, // SP 0x14024BC40 MP 0x000000000 + {"_meth_81C4", 0x81C4}, // SP 0x1402D7F30 MP 0x140077AA0 + {"_meth_81C5", 0x81C5}, // SP 0x1402D7F90 MP 0x140077B00 + {"_meth_81C6", 0x81C6}, // SP 0x14024BD90 MP 0x000000000 + {"_meth_81C7", 0x81C7}, // SP 0x14024C010 MP 0x000000000 + {"_meth_81C8", 0x81C8}, // SP 0x14024C150 MP 0x000000000 + {"_meth_81C9", 0x81C9}, // SP 0x14024C240 MP 0x000000000 + {"_meth_81CA", 0x81CA}, // SP 0x14024C250 MP 0x000000000 + {"_meth_81CB", 0x81CB}, // SP 0x14024C270 MP 0x000000000 + {"_meth_81CC", 0x81CC}, // SP 0x14024C290 MP 0x000000000 + {"_meth_81CD", 0x81CD}, // SP 0x14024C2F0 MP 0x000000000 + {"_meth_81CE", 0x81CE}, // SP 0x14024C360 MP 0x000000000 + {"_meth_81CF", 0x81CF}, // SP 0x14024C430 MP 0x000000000 + {"_meth_81D0", 0x81D0}, // SP 0x14024C520 MP 0x000000000 + {"_meth_81D1", 0x81D1}, // SP 0x14024C560 MP 0x000000000 + {"_meth_81D2", 0x81D2}, // SP 0x14024C5A0 MP 0x000000000 + {"_meth_81D3", 0x81D3}, // SP 0x14024C5E0 MP 0x000000000 + {"_meth_81D4", 0x81D4}, // SP 0x140247BF0 MP 0x000000000 + {"_meth_81D5", 0x81D5}, // SP 0x140247CE0 MP 0x000000000 + {"_meth_81D6", 0x81D6}, // SP 0x140247930 MP 0x000000000 + {"_meth_81D7", 0x81D7}, // SP 0x14029B180 MP 0x140366790 + {"_meth_81D8", 0x81D8}, // SP 0x1402A3840 MP 0x14036C130 + {"_meth_81D9", 0x81D9}, // SP 0x14028DCF0 MP 0x14036CAB0 + {"_meth_81DA", 0x81DA}, // SP 0x14028E350 MP 0x14036D0C0 + {"_meth_81DB", 0x81DB}, // SP 0x14028E430 MP 0x14036D150 + {"_meth_81DC", 0x81DC}, // SP 0x14029A340 MP 0x140365D80 + {"_meth_81DD", 0x81DD}, // SP 0x14029A4E0 MP 0x140365E90 + {"_meth_81DE", 0x81DE}, // SP 0x14029A700 MP 0x140366180 + {"_meth_81DF", 0x81DF}, // SP 0x14029AA10 MP 0x1403663A0 + {"_meth_81E0", 0x81E0}, // SP 0x14029AB50 MP 0x140366480 + {"_meth_81E1", 0x81E1}, // SP 0x14028EA00 MP 0x14036E8B0 + {"_meth_81E2", 0x81E2}, // SP 0x14028EB40 MP 0x14036EAB0 + {"_meth_81E3", 0x81E3}, // SP 0x14028F2F0 MP 0x14036F2E0 + {"_meth_81E4", 0x81E4}, // SP 0x1402A2860 MP 0x14036EF80 + {"_meth_81E5", 0x81E5}, // SP 0x14028FFC0 MP 0x1403584E0 + {"_meth_81E6", 0x81E6}, // SP 0x1402900C0 MP 0x140358750 + {"_meth_81E7", 0x81E7}, // SP 0x140248F30 MP 0x000000000 + {"_meth_81E8", 0x81E8}, // SP 0x1402491F0 MP 0x000000000 + {"_meth_81E9", 0x81E9}, // SP 0x140249230 MP 0x000000000 + {"_meth_81EA", 0x81EA}, // SP 0x140249370 MP 0x000000000 + {"_meth_81EB", 0x81EB}, // SP 0x140249650 MP 0x000000000 + {"_meth_81EC", 0x81EC}, // SP 0x140249710 MP 0x000000000 + {"_meth_81ED", 0x81ED}, // SP 0x1402499B0 MP 0x000000000 + {"_meth_81EE", 0x81EE}, // SP 0x140249A70 MP 0x000000000 + {"_meth_81EF", 0x81EF}, // SP 0x140249B80 MP 0x000000000 + {"_meth_81F0", 0x81F0}, // SP 0x140249C30 MP 0x000000000 + {"_meth_81F1", 0x81F1}, // SP 0x140249CC0 MP 0x000000000 + {"_meth_81F2", 0x81F2}, // SP 0x140249E00 MP 0x000000000 + {"_meth_81F3", 0x81F3}, // SP 0x140249E50 MP 0x000000000 + {"_meth_81F4", 0x81F4}, // SP 0x14024A010 MP 0x000000000 + {"_meth_81F5", 0x81F5}, // SP 0x14024A080 MP 0x000000000 + {"_meth_81F6", 0x81F6}, // SP 0x14024A190 MP 0x000000000 + {"_meth_81F7", 0x81F7}, // SP 0x14024A330 MP 0x000000000 + {"_meth_81F8", 0x81F8}, // SP 0x14024A390 MP 0x000000000 + {"_meth_81F9", 0x81F9}, // SP 0x14024A260 MP 0x000000000 + {"_meth_81FA", 0x81FA}, // SP 0x14024A440 MP 0x000000000 + {"_meth_81FB", 0x81FB}, // SP 0x14024A4F0 MP 0x000000000 + {"_meth_81FC", 0x81FC}, // SP 0x14024A6B0 MP 0x000000000 + {"_meth_81FD", 0x81FD}, // SP 0x14024A780 MP 0x000000000 + {"_meth_81FE", 0x81FE}, // SP 0x14024A950 MP 0x000000000 + {"_meth_81FF", 0x81FF}, // SP 0x14024AC00 MP 0x000000000 + {"_meth_8200", 0x8200}, // SP 0x14024AD60 MP 0x000000000 + {"_meth_8201", 0x8201}, // SP 0x14024AE60 MP 0x000000000 + {"_meth_8202", 0x8202}, // SP 0x14024B1D0 MP 0x000000000 + {"_meth_8203", 0x8203}, // SP 0x14024B2C0 MP 0x000000000 + {"_meth_8204", 0x8204}, // SP 0x1402905D0 MP 0x140358F20 + {"_meth_8205", 0x8205}, // SP 0x1402908B0 MP 0x1403593C0 + {"_meth_8206", 0x8206}, // SP 0x000000000 MP 0x14035AB40 + {"_meth_8207", 0x8207}, // SP 0x1402AA5F0 MP 0x000000000 + {"_meth_8208", 0x8208}, // SP 0x000000000 MP 0x14035ABE0 + {"_meth_820A", 0x820A}, // SP 0x000000000 MP 0x14035B100 + {"_meth_820B", 0x820B}, // SP 0x000000000 MP 0x14035B170 + {"_meth_820C", 0x820C}, // SP 0x000000000 MP 0x14035B380 + {"_meth_820D", 0x820D}, // SP 0x000000000 MP 0x14035B210 + {"_meth_820E", 0x820E}, // SP 0x000000000 MP 0x14035B270 + {"_meth_820F", 0x820F}, // SP 0x140291CD0 MP 0x14035C250 + {"_meth_8210", 0x8210}, // SP 0x140292090 MP 0x14035C420 + {"_meth_8211", 0x8211}, // SP 0x1402923D0 MP 0x14035C930 + {"_meth_8212", 0x8212}, // SP 0x1402931B0 MP 0x14035CBB0 + {"_meth_8213", 0x8213}, // SP 0x1402940E0 MP 0x14035D6A0 + {"_meth_8214", 0x8214}, // SP 0x140296080 MP 0x14035F750 + {"_meth_8215", 0x8215}, // SP 0x1402961E0 MP 0x14035F810 + {"_meth_8216", 0x8216}, // SP 0x140296540 MP 0x14035FB00 + {"_meth_8217", 0x8217}, // SP 0x1402966E0 MP 0x14035FC80 + {"_meth_8218", 0x8218}, // SP 0x1402990B0 MP 0x1403620D0 + {"_meth_8219", 0x8219}, // SP 0x140299540 MP 0x140362730 + {"_meth_821A", 0x821A}, // SP 0x140299B00 MP 0x140362E50 + {"_meth_821B", 0x821B}, // SP 0x14029A1B0 MP 0x140363790 + {"_meth_821C", 0x821C}, // SP 0x140290290 MP 0x140358930 + {"_meth_821D", 0x821D}, // SP 0x1402A29B0 MP 0x000000000 + {"_meth_821E", 0x821E}, // SP 0x1402A32F0 MP 0x000000000 + {"_meth_821F", 0x821F}, // SP 0x140296A30 MP 0x14035FC90 + {"_meth_8220", 0x8220}, // SP 0x140297010 MP 0x140360380 + {"_meth_8221", 0x8221}, // SP 0x1402976A0 MP 0x1403609B0 + {"_meth_8222", 0x8222}, // SP 0x140299CF0 MP 0x1403635A0 + {"_meth_8223", 0x8223}, // SP 0x140299B90 MP 0x1403630E0 + {"_meth_8224", 0x8224}, // SP 0x14029A2C0 MP 0x140363C10 + {"_meth_8225", 0x8225}, // SP 0x14029DF50 MP 0x140365F70 + {"_meth_8226", 0x8226}, // SP 0x1402A17F0 MP 0x14036B0B0 + {"_meth_8227", 0x8227}, // SP 0x140464260 MP 0x140562970 + {"_meth_8228", 0x8228}, // SP 0x140464340 MP 0x1405629E0 + {"_meth_8229", 0x8229}, // SP 0x140464570 MP 0x140562C70 + {"_meth_822A", 0x822A}, // SP 0x1404646D0 MP 0x140562D90 + {"_meth_822B", 0x822B}, // SP 0x1404647A0 MP 0x140562E80 + {"_meth_822C", 0x822C}, // SP 0x140464840 MP 0x140562F80 + {"_meth_822D", 0x822D}, // SP 0x140464980 MP 0x1405630A0 + {"_meth_822E", 0x822E}, // SP 0x140464B20 MP 0x140563240 + {"_meth_822F", 0x822F}, // SP 0x140464C10 MP 0x140563310 + {"_meth_8230", 0x8230}, // SP 0x140464C90 MP 0x1405633E0 + {"_meth_8231", 0x8231}, // SP 0x140464E50 MP 0x140563610 + {"_meth_8232", 0x8232}, // SP 0x000000000 MP 0x1405609B0 + {"_meth_8233", 0x8233}, // SP 0x140290E70 MP 0x000000000 + {"_meth_8234", 0x8234}, // SP 0x1402910E0 MP 0x000000000 + {"_meth_8235", 0x8235}, // SP 0x140291670 MP 0x000000000 + {"_meth_8236", 0x8236}, // SP 0x140291A60 MP 0x000000000 + {"_meth_8237", 0x8237}, // SP 0x140292010 MP 0x000000000 + {"_meth_8238", 0x8238}, // SP 0x140292230 MP 0x000000000 + {"_meth_8239", 0x8239}, // SP 0x14029C2A0 MP 0x000000000 + {"_meth_823A", 0x823A}, // SP 0x14029CAD0 MP 0x000000000 + {"_meth_823B", 0x823B}, // SP 0x14029CD70 MP 0x000000000 + {"_meth_823C", 0x823C}, // SP 0x14029CF00 MP 0x000000000 + {"_meth_823D", 0x823D}, // SP 0x140292BA0 MP 0x000000000 + {"_meth_823E", 0x823E}, // SP 0x140292DF0 MP 0x000000000 + {"_meth_8240", 0x8240}, // SP 0x1402A3880 MP 0x000000000 + {"_meth_8241", 0x8241}, // SP 0x140248AD0 MP 0x000000000 + {"_meth_8242", 0x8242}, // SP 0x140248EA0 MP 0x000000000 + {"_meth_8243", 0x8243}, // SP 0x1402A1AF0 MP 0x14036B910 + {"_meth_8244", 0x8244}, // SP 0x1402A1E20 MP 0x14036BE30 + {"_meth_8245", 0x8245}, // SP 0x1402A24D0 MP 0x14036C5B0 + {"_meth_8246", 0x8246}, // SP 0x14028DC50 MP 0x14036E800 + {"_meth_8247", 0x8247}, // SP 0x000000000 MP 0x140332B50 + {"_meth_8248", 0x8248}, // SP 0x140268FE0 MP 0x140332B40 + {"_meth_8249", 0x8249}, // SP 0x000000000 MP 0x1403345F0 + {"_meth_824A", 0x824A}, // SP 0x000000000 MP 0x1403346A0 + {"_meth_824B", 0x824B}, // SP 0x000000000 MP 0x140332C90 + {"_meth_824C", 0x824C}, // SP 0x140265080 MP 0x140330FE0 + {"_meth_824D", 0x824D}, // SP 0x000000000 MP 0x140332FB0 + {"_meth_824E", 0x824E}, // SP 0x140461E80 MP 0x140560640 + {"_meth_824F", 0x824F}, // SP 0x140461F50 MP 0x140560710 + {"_meth_8250", 0x8250}, // SP 0x140462070 MP 0x1405607B0 + {"_meth_8251", 0x8251}, // SP 0x140462250 MP 0x1405609B0 + {"_meth_8252", 0x8252}, // SP 0x140462300 MP 0x140560A20 + {"_meth_8253", 0x8253}, // SP 0x140462550 MP 0x140560C70 + {"_meth_8254", 0x8254}, // SP 0x1404625D0 MP 0x140560CF0 + {"_meth_8255", 0x8255}, // SP 0x140462660 MP 0x140560D80 + {"_meth_8256", 0x8256}, // SP 0x1404626E0 MP 0x140560F10 + {"_meth_8257", 0x8257}, // SP 0x140462750 MP 0x140560F80 + {"_meth_8258", 0x8258}, // SP 0x140462840 MP 0x1405610A0 + {"_meth_8259", 0x8259}, // SP 0x1404628D0 MP 0x140561130 + {"_meth_825A", 0x825A}, // SP 0x140462950 MP 0x1405611B0 + {"_meth_825B", 0x825B}, // SP 0x1404629E0 MP 0x140561240 + {"_meth_825C", 0x825C}, // SP 0x140462A60 MP 0x1405612C0 + {"_meth_825D", 0x825D}, // SP 0x140463320 MP 0x140561B60 + {"_meth_825E", 0x825E}, // SP 0x140463410 MP 0x140561C60 + {"_meth_825F", 0x825F}, // SP 0x140463510 MP 0x140561D60 + {"_meth_8260", 0x8260}, // SP 0x1404635A0 MP 0x140561DF0 + {"_meth_8261", 0x8261}, // SP 0x1404638A0 MP 0x1405620F0 + {"_meth_8262", 0x8262}, // SP 0x140463950 MP 0x1405621A0 + {"_meth_8263", 0x8263}, // SP 0x140463AB0 MP 0x140562280 + {"_meth_8264", 0x8264}, // SP 0x140463B20 MP 0x1405622F0 + {"_meth_8265", 0x8265}, // SP 0x1404641D0 MP 0x1405628F0 + {"_meth_8266", 0x8266}, // SP 0x000000000 MP 0x1403337A0 + {"_meth_8267", 0x8267}, // SP 0x000000000 MP 0x140333E20 + {"_meth_8268", 0x8268}, // SP 0x000000000 MP 0x140334010 + {"_meth_8269", 0x8269}, // SP 0x000000000 MP 0x1403340A0 + {"_meth_826A", 0x826A}, // SP 0x000000000 MP 0x140334120 + {"_meth_826B", 0x826B}, // SP 0x000000000 MP 0x1403341A0 + {"_meth_826C", 0x826C}, // SP 0x000000000 MP 0x140334230 + {"_meth_826D", 0x826D}, // SP 0x000000000 MP 0x140334290 + {"_meth_826E", 0x826E}, // SP 0x000000000 MP 0x140334570 + {"_meth_826F", 0x826F}, // SP 0x000000000 MP 0x140334750 + {"_meth_8270", 0x8270}, // SP 0x000000000 MP 0x140334980 + {"_meth_8271", 0x8271}, // SP 0x000000000 MP 0x140334B20 + {"_meth_8272", 0x8272}, // SP 0x1402B3CA0 MP 0x14037FA00 + {"_meth_8273", 0x8273}, // SP 0x1402B3EC0 MP 0x14037FC50 + {"_meth_8274", 0x8274}, // SP 0x1402B4500 MP 0x140380380 + {"_meth_8275", 0x8275}, // SP 0x000000000 MP 0x140380450 + {"_meth_8276", 0x8276}, // SP 0x000000000 MP 0x140380700 + {"_meth_8277", 0x8277}, // SP 0x000000000 MP 0x140380570 + {"_meth_8278", 0x8278}, // SP 0x140465060 MP 0x1405637F0 + {"_meth_8279", 0x8279}, // SP 0x1404651E0 MP 0x14055F040 + {"_meth_827A", 0x827A}, // SP 0x1404652F0 MP 0x14055F170 + {"_meth_827B", 0x827B}, // SP 0x1404654A0 MP 0x14055F340 + {"_meth_827C", 0x827C}, // SP 0x140465740 MP 0x14055F4D0 + {"_meth_827D", 0x827D}, // SP 0x140465840 MP 0x14055F560 + {"_meth_827E", 0x827E}, // SP 0x000000000 MP 0x14055F5E0 + {"_meth_827F", 0x827F}, // SP 0x1404658C0 MP 0x14055F840 + {"_meth_8280", 0x8280}, // SP 0x140465930 MP 0x14055F8B0 + {"_meth_8281", 0x8281}, // SP 0x140465AC0 MP 0x14055FA60 + {"_meth_8282", 0x8282}, // SP 0x140465BE0 MP 0x14055FB80 + {"_meth_8283", 0x8283}, // SP 0x140465CD0 MP 0x14055FC70 + {"_meth_8284", 0x8284}, // SP 0x140465D40 MP 0x14055FCE0 + {"_meth_8285", 0x8285}, // SP 0x140465DB0 MP 0x14055FD50 + {"_meth_8286", 0x8286}, // SP 0x140465E30 MP 0x14055FDE0 + {"_meth_8287", 0x8287}, // SP 0x140465EA0 MP 0x14055FE50 + {"_meth_8288", 0x8288}, // SP 0x140465F00 MP 0x14055FEC0 + {"_meth_8289", 0x8289}, // SP 0x140465F60 MP 0x000000000 + {"_meth_828A", 0x828A}, // SP 0x140466020 MP 0x14055FF30 + {"_meth_828B", 0x828B}, // SP 0x140466090 MP 0x14055FFA0 + {"_meth_828C", 0x828C}, // SP 0x140466100 MP 0x140560010 + {"_meth_828D", 0x828D}, // SP 0x140466170 MP 0x140560080 + {"_meth_828E", 0x828E}, // SP 0x140466200 MP 0x140560110 + {"_meth_828F", 0x828F}, // SP 0x140466360 MP 0x140560270 + {"_meth_8290", 0x8290}, // SP 0x140461CC0 MP 0x140560480 + {"_meth_8291", 0x8291}, // SP 0x140461D80 MP 0x140560540 + {"_meth_8292", 0x8292}, // SP 0x140461E10 MP 0x1405605D0 + {"_meth_8293", 0x8293}, // SP 0x140260F20 MP 0x140334B90 + {"_meth_8294", 0x8294}, // SP 0x000000000 MP 0x140334D50 + {"_meth_8295", 0x8295}, // SP 0x000000000 MP 0x140334DB0 + {"_meth_8296", 0x8296}, // SP 0x000000000 MP 0x140334E10 + {"_meth_8297", 0x8297}, // SP 0x000000000 MP 0x140334E70 + {"_meth_8298", 0x8298}, // SP 0x000000000 MP 0x140334ED0 + {"_meth_8299", 0x8299}, // SP 0x000000000 MP 0x140334F60 + {"_meth_829A", 0x829A}, // SP 0x000000000 MP 0x140334FE0 + {"_meth_829B", 0x829B}, // SP 0x000000000 MP 0x1403350D0 + {"_meth_829C", 0x829C}, // SP 0x000000000 MP 0x1403350E0 + {"_meth_829D", 0x829D}, // SP 0x000000000 MP 0x1403350F0 + {"_meth_829E", 0x829E}, // SP 0x000000000 MP 0x140335190 + {"_meth_829F", 0x829F}, // SP 0x140260730 MP 0x14032CA40 + {"_meth_82A0", 0x82A0}, // SP 0x000000000 MP 0x14032ED90 + {"_meth_82A1", 0x82A1}, // SP 0x140263850 MP 0x14032FB10 + {"_meth_82A2", 0x82A2}, // SP 0x140265490 MP 0x1403297E0 + {"_meth_82A3", 0x82A3}, // SP 0x1402659A0 MP 0x140329D00 + {"_meth_82A4", 0x82A4}, // SP 0x1402661B0 MP 0x14032A460 + {"_meth_82A5", 0x82A5}, // SP 0x140265D40 MP 0x14032A0A0 + {"_meth_82A6", 0x82A6}, // SP 0x000000000 MP 0x1403323C0 + {"_meth_82A7", 0x82A7}, // SP 0x000000000 MP 0x1403324F0 + {"_meth_82A8", 0x82A8}, // SP 0x1405D92F0 MP 0x14032A8F0 + {"_meth_82A9", 0x82A9}, // SP 0x1405D92F0 MP 0x14032A900 + {"_meth_82AA", 0x82AA}, // SP 0x1402B2A10 MP 0x14037E950 + {"_meth_82AB", 0x82AB}, // SP 0x1402B2F60 MP 0x14037EEB0 + {"_meth_82AC", 0x82AC}, // SP 0x1402B2F70 MP 0x14037EEC0 + {"_meth_82AD", 0x82AD}, // SP 0x1402B2F90 MP 0x14037EEE0 + {"_meth_82AE", 0x82AE}, // SP 0x1402B2C10 MP 0x14037EB00 + {"_meth_82AF", 0x82AF}, // SP 0x1402B2D70 MP 0x14037EC90 + {"_meth_82B0", 0x82B0}, // SP 0x1402B2EE0 MP 0x14037EE20 + {"_meth_82B1", 0x82B1}, // SP 0x1402B3030 MP 0x14037EF10 + {"_meth_82B2", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 + {"_meth_82B3", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 + {"_meth_82B4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 + {"_meth_82B5", 0x82B5}, // SP 0x1402B3410 MP 0x14037F010 + {"_meth_82B6", 0x82B6}, // SP 0x1402B3430 MP 0x14037F030 + {"_meth_82B7", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 + {"_meth_82B8", 0x82B8}, // SP 0x1402B34B0 MP 0x14037F0B0 + {"_meth_82B9", 0x82B9}, // SP 0x1402B3700 MP 0x14037F3C0 + {"_meth_82BA", 0x82BA}, // SP 0x1402B45E0 MP 0x1403808A0 + {"_meth_82BB", 0x82BB}, // SP 0x1402B4690 MP 0x140380950 + {"_meth_82BC", 0x82BC}, // SP 0x1402B3880 MP 0x14037F590 + {"_meth_82BD", 0x82BD}, // SP 0x1402B38E0 MP 0x14037F5F0 + {"_meth_82BE", 0x82BE}, // SP 0x1402B3960 MP 0x14037F670 + {"_meth_82BF", 0x82BF}, // SP 0x000000000 MP 0x1403351A0 + {"_meth_82C0", 0x82C0}, // SP 0x000000000 MP 0x1403351B0 + {"_meth_82C1", 0x82C1}, // SP 0x000000000 MP 0x1403351C0 + {"_meth_82C2", 0x82C2}, // SP 0x000000000 MP 0x1403352B0 + {"_meth_82C3", 0x82C3}, // SP 0x000000000 MP 0x140331E00 + {"_meth_82C4", 0x82C4}, // SP 0x000000000 MP 0x140331E70 + {"_meth_82C5", 0x82C5}, // SP 0x000000000 MP 0x140331EE0 + {"_meth_82C6", 0x82C6}, // SP 0x000000000 MP 0x140332250 + {"_meth_82C7", 0x82C7}, // SP 0x140262950 MP 0x14032EF00 + {"_meth_82C8", 0x82C8}, // SP 0x140262A60 MP 0x14032EFF0 + {"_meth_82C9", 0x82C9}, // SP 0x140262AB0 MP 0x14032F0D0 + {"_meth_82CA", 0x82CA}, // SP 0x000000000 MP 0x1403322C0 + {"_meth_82CB", 0x82CB}, // SP 0x1402623D0 MP 0x14032E3A0 + {"_meth_82CC", 0x82CC}, // SP 0x1402624C0 MP 0x14032E4B0 + {"_meth_82CD", 0x82CD}, // SP 0x1402625B0 MP 0x14032E650 + {"_meth_82CE", 0x82CE}, // SP 0x140262720 MP 0x14032E790 + {"_meth_82CF", 0x82CF}, // SP 0x140264D00 MP 0x140331530 + {"_meth_82D0", 0x82D0}, // SP 0x1402651B0 MP 0x1403292E0 + {"_meth_82D1", 0x82D1}, // SP 0x140263410 MP 0x14032FC00 + {"_meth_82D2", 0x82D2}, // SP 0x1402636D0 MP 0x14032FC10 + {"_meth_82D3", 0x82D3}, // SP 0x1402636F0 MP 0x14032FC30 + {"_meth_82D4", 0x82D4}, // SP 0x140263710 MP 0x14032FD20 + {"_meth_82D5", 0x82D5}, // SP 0x140263730 MP 0x14032FD40 + {"_meth_82D6", 0x82D6}, // SP 0x140264890 MP 0x140330B80 + {"_meth_82D7", 0x82D7}, // SP 0x140264C80 MP 0x140331310 + {"_meth_82D8", 0x82D8}, // SP 0x140264C80 MP 0x140331330 + {"_meth_82D9", 0x82D9}, // SP 0x1402ABE90 MP 0x000000000 + {"_meth_82DA", 0x82DA}, // SP 0x1402663A0 MP 0x14032A910 + {"_meth_82DB", 0x82DB}, // SP 0x140266AF0 MP 0x14032AE90 + {"_meth_82DC", 0x82DC}, // SP 0x140266CD0 MP 0x14032B120 + {"_meth_82DD", 0x82DD}, // SP 0x140266FE0 MP 0x14032B500 + {"_meth_82DE", 0x82DE}, // SP 0x140267330 MP 0x14032B9F0 + {"_meth_82DF", 0x82DF}, // SP 0x140267530 MP 0x14032BD00 + {"_meth_82E0", 0x82E0}, // SP 0x140267600 MP 0x14032BDD0 + {"_meth_82E1", 0x82E1}, // SP 0x1402676E0 MP 0x14032C000 + {"_meth_82E2", 0x82E2}, // SP 0x140260240 MP 0x14032C240 + {"_meth_82E3", 0x82E3}, // SP 0x140260540 MP 0x14032C6C0 + {"_meth_82E4", 0x82E4}, // SP 0x1402605E0 MP 0x14032C7F0 + {"_meth_82E5", 0x82E5}, // SP 0x000000000 MP 0x140332300 + {"_meth_82E6", 0x82E6}, // SP 0x000000000 MP 0x140332380 + {"_meth_82E7", 0x82E7}, // SP 0x000000000 MP 0x140332390 + {"_meth_82E8", 0x82E8}, // SP 0x000000000 MP 0x1403323B0 + {"_meth_82E9", 0x82E9}, // SP 0x000000000 MP 0x1403323A0 + {"_meth_82EA", 0x82EA}, // SP 0x1402628A0 MP 0x14032E5C0 + {"_meth_82EB", 0x82EB}, // SP 0x1402619B0 MP 0x14032D5A0 + {"_meth_82EC", 0x82EC}, // SP 0x140261AA0 MP 0x14032D6D0 + {"_meth_82ED", 0x82ED}, // SP 0x140263D40 MP 0x14032FA10 + {"_meth_82EE", 0x82EE}, // SP 0x1402601C0 MP 0x14032BBE0 + {"_meth_82EF", 0x82EF}, // SP 0x140260AD0 MP 0x14032C3C0 + {"_meth_82F0", 0x82F0}, // SP 0x140260E80 MP 0x14032C5E0 + {"_meth_82F1", 0x82F1}, // SP 0x1402677A0 MP 0x14032BE30 + {"_meth_82F2", 0x82F2}, // SP 0x140260130 MP 0x14032BF20 + {"_meth_82F3", 0x82F3}, // SP 0x140264AD0 MP 0x140330E20 + {"_meth_82F4", 0x82F4}, // SP 0x140264EB0 MP 0x140331350 + {"_meth_82F5", 0x82F5}, // SP 0x140265380 MP 0x1403293A0 + {"_meth_82F6", 0x82F6}, // SP 0x1402655D0 MP 0x140329580 + {"_meth_82F7", 0x82F7}, // SP 0x140265820 MP 0x140329990 + {"_meth_82F8", 0x82F8}, // SP 0x140265F20 MP 0x14032A3B0 + {"_meth_82F9", 0x82F9}, // SP 0x140266410 MP 0x14032A990 + {"_meth_82FA", 0x82FA}, // SP 0x1402666C0 MP 0x14032B260 + {"_meth_82FB", 0x82FB}, // SP 0x000000000 MP 0x14032AC30 + {"_meth_82FC", 0x82FC}, // SP 0x000000000 MP 0x14032AD80 + {"_meth_82FD", 0x82FD}, // SP 0x140261130 MP 0x14032C940 + {"_meth_82FE", 0x82FE}, // SP 0x140261440 MP 0x14032CAB0 + {"_meth_82FF", 0x82FF}, // SP 0x140261B20 MP 0x14032D890 + {"_meth_8300", 0x8300}, // SP 0x140261C00 MP 0x14032DA40 + {"_meth_8301", 0x8301}, // SP 0x140261CE0 MP 0x14032DBB0 + {"_meth_8302", 0x8302}, // SP 0x140262B00 MP 0x14032ED00 + {"_meth_8303", 0x8303}, // SP 0x140262CC0 MP 0x14032EE80 + {"_meth_8304", 0x8304}, // SP 0x140262D90 MP 0x14032EF60 + {"_meth_8305", 0x8305}, // SP 0x140261F10 MP 0x14032DD50 + {"_meth_8306", 0x8306}, // SP 0x1402608B0 MP 0x14032CB90 + {"_meth_8307", 0x8307}, // SP 0x140260A80 MP 0x14032CCC0 + {"_meth_8308", 0x8308}, // SP 0x1402621A0 MP 0x14032E120 + {"_meth_8309", 0x8309}, // SP 0x1402622E0 MP 0x14032E230 + {"_meth_830A", 0x830A}, // SP 0x140261090 MP 0x14032C720 + {"_meth_830B", 0x830B}, // SP 0x140262F00 MP 0x14032EA90 + {"_meth_830C", 0x830C}, // SP 0x140263380 MP 0x14032F210 + {"_meth_830D", 0x830D}, // SP 0x1402635B0 MP 0x14032F310 + {"_meth_830E", 0x830E}, // SP 0x140263750 MP 0x14032F5E0 + {"_meth_830F", 0x830F}, // SP 0x140263A30 MP 0x14032F860 + {"_meth_8310", 0x8310}, // SP 0x140263EF0 MP 0x14032FC50 + {"_meth_8311", 0x8311}, // SP 0x1402647A0 MP 0x140330740 + {"_meth_8312", 0x8312}, // SP 0x140264CA0 MP 0x140330D20 + {"_meth_8313", 0x8313}, // SP 0x140264E50 MP 0x140330D90 + {"_meth_8314", 0x8314}, // SP 0x140265950 MP 0x140329520 + {"_meth_8315", 0x8315}, // SP 0x140265B80 MP 0x1403296D0 + {"_meth_8316", 0x8316}, // SP 0x140264440 MP 0x140330340 + {"_meth_8317", 0x8317}, // SP 0x140264600 MP 0x140330520 + {"_meth_8318", 0x8318}, // SP 0x140260C90 MP 0x14032C470 + {"_meth_8319", 0x8319}, // SP 0x140261020 MP 0x14032C780 + {"_meth_831A", 0x831A}, // SP 0x140263E90 MP 0x1403302E0 + {"_meth_831B", 0x831B}, // SP 0x140264020 MP 0x140330410 + {"_meth_831C", 0x831C}, // SP 0x140264150 MP 0x1403305B0 + {"_meth_831D", 0x831D}, // SP 0x140264270 MP 0x1403306E0 + {"_meth_831E", 0x831E}, // SP 0x140264660 MP 0x140330B20 + {"_meth_831F", 0x831F}, // SP 0x140264750 MP 0x140330CC0 + {"_meth_8320", 0x8320}, // SP 0x1402631F0 MP 0x14032F130 + {"_meth_8321", 0x8321}, // SP 0x140263290 MP 0x14032F3A0 + {"_meth_8322", 0x8322}, // SP 0x140263330 MP 0x14032F4E0 + {"_meth_8323", 0x8323}, // SP 0x140263430 MP 0x14032F6C0 + {"_meth_8324", 0x8324}, // SP 0x140263630 MP 0x14032F930 + {"_meth_8326", 0x8326}, // SP 0x140263B10 MP 0x14032FD60 + {"_meth_8327", 0x8327}, // SP 0x140263C10 MP 0x14032FFE0 + {"_meth_8328", 0x8328}, // SP 0x140263E40 MP 0x1403300F0 + {"_meth_8329", 0x8329}, // SP 0x140266C00 MP 0x14032B640 + {"_meth_832A", 0x832A}, // SP 0x140266D10 MP 0x14032B800 + {"_meth_832B", 0x832B}, // SP 0x140266EA0 MP 0x14032B9C0 + {"_meth_832C", 0x832C}, // SP 0x140267180 MP 0x14032B9E0 + {"_meth_832D", 0x832D}, // SP 0x140267410 MP 0x14032BB00 + {"_meth_832E", 0x832E}, // SP 0x140265FA0 MP 0x140329C00 + {"_meth_832F", 0x832F}, // SP 0x140266200 MP 0x140329F00 + {"_meth_8330", 0x8330}, // SP 0x140266560 MP 0x14032A240 + {"_meth_8331", 0x8331}, // SP 0x140266820 MP 0x14032A6F0 + {"_meth_8332", 0x8332}, // SP 0x140266E10 MP 0x14032ABC0 + {"_meth_8333", 0x8333}, // SP 0x140267030 MP 0x14032AD00 + {"_meth_8334", 0x8334}, // SP 0x140267100 MP 0x14032AEE0 + {"_meth_8335", 0x8335}, // SP 0x1402677C0 MP 0x14032B8D0 + {"_meth_8336", 0x8336}, // SP 0x1402604D0 MP 0x14032BC80 + {"_meth_8337", 0x8337}, // SP 0x140260930 MP 0x14032BE70 + {"_meth_8338", 0x8338}, // SP 0x140260990 MP 0x14032C0D0 + {"_meth_8339", 0x8339}, // SP 0x140261500 MP 0x14032CE10 + {"_meth_833A", 0x833A}, // SP 0x1402615F0 MP 0x14032D0B0 + {"_meth_833B", 0x833B}, // SP 0x1402617D0 MP 0x14032D1B0 + {"_meth_833C", 0x833C}, // SP 0x1402618D0 MP 0x14032D450 + {"_meth_833D", 0x833D}, // SP 0x140262070 MP 0x14032DC20 + {"_meth_833E", 0x833E}, // SP 0x1402620C0 MP 0x14032DCE0 + {"_meth_833F", 0x833F}, // SP 0x140262280 MP 0x14032DF80 + {"_meth_8340", 0x8340}, // SP 0x1402626A0 MP 0x14032DFF0 + {"_meth_8341", 0x8341}, // SP 0x140264090 MP 0x14032FF10 + {"_meth_8342", 0x8342}, // SP 0x1402642C0 MP 0x140330170 + {"_meth_8343", 0x8343}, // SP 0x140260360 MP 0x000000000 + {"_meth_8344", 0x8344}, // SP 0x140260640 MP 0x000000000 + {"_meth_8345", 0x8345}, // SP 0x1402607E0 MP 0x000000000 + {"_meth_8346", 0x8346}, // SP 0x1402609E0 MP 0x000000000 + {"_meth_8347", 0x8347}, // SP 0x14026D000 MP 0x14033B150 + {"_meth_8348", 0x8348}, // SP 0x000000000 MP 0x140374D30 + {"_meth_8349", 0x8349}, // SP 0x000000000 MP 0x140374DD0 + {"_meth_834A", 0x834A}, // SP 0x140260C10 MP 0x14032C5D0 + {"_meth_834B", 0x834B}, // SP 0x000000000 MP 0x14037B380 + {"_meth_834C", 0x834C}, // SP 0x140261D40 MP 0x14032D9C0 + {"_meth_834D", 0x834D}, // SP 0x000000000 MP 0x140374B70 + {"_meth_834E", 0x834E}, // SP 0x000000000 MP 0x140374C10 + {"_meth_834F", 0x834F}, // SP 0x000000000 MP 0x1404798E0 + {"_meth_8350", 0x8350}, // SP 0x000000000 MP 0x14047A0F0 + {"_meth_8351", 0x8351}, // SP 0x000000000 MP 0x140479F70 + {"_meth_8352", 0x8352}, // SP 0x000000000 MP 0x140479BC0 + {"_meth_8353", 0x8353}, // SP 0x000000000 MP 0x140479DB0 + {"_meth_8354", 0x8354}, // SP 0x000000000 MP 0x140477C80 + {"_meth_8355", 0x8355}, // SP 0x000000000 MP 0x140479B00 + {"_meth_8356", 0x8356}, // SP 0x000000000 MP 0x140477C00 + {"_meth_8357", 0x8357}, // SP 0x000000000 MP 0x1404796A0 + {"_meth_8358", 0x8358}, // SP 0x000000000 MP 0x1404784A0 + {"_meth_8359", 0x8359}, // SP 0x000000000 MP 0x1404785F0 + {"_meth_835A", 0x835A}, // SP 0x000000000 MP 0x1404786F0 + {"_meth_835B", 0x835B}, // SP 0x000000000 MP 0x140478670 + {"_meth_835D", 0x835D}, // SP 0x000000000 MP 0x140478850 + {"_meth_835E", 0x835E}, // SP 0x000000000 MP 0x140478E10 + {"_meth_835F", 0x835F}, // SP 0x000000000 MP 0x140477D00 + {"_meth_8360", 0x8360}, // SP 0x000000000 MP 0x140478B70 + {"_meth_8362", 0x8362}, // SP 0x000000000 MP 0x140478EB0 + {"_meth_8363", 0x8363}, // SP 0x000000000 MP 0x140478890 + {"_meth_8364", 0x8364}, // SP 0x000000000 MP 0x140478420 + {"_meth_8365", 0x8365}, // SP 0x000000000 MP 0x14047A1C0 + {"_meth_8367", 0x8367}, // SP 0x000000000 MP 0x140479A70 + {"_meth_8368", 0x8368}, // SP 0x000000000 MP 0x1404797B0 + {"_meth_8369", 0x8369}, // SP 0x000000000 MP 0x140477E90 + {"_meth_836A", 0x836A}, // SP 0x000000000 MP 0x140478770 + {"_meth_836B", 0x836B}, // SP 0x000000000 MP 0x140478990 + {"_meth_836C", 0x836C}, // SP 0x000000000 MP 0x140479420 + {"_meth_836D", 0x836D}, // SP 0x000000000 MP 0x140477A90 + {"_meth_836E", 0x836E}, // SP 0x000000000 MP 0x140478230 + {"_meth_836F", 0x836F}, // SP 0x000000000 MP 0x140479020 + {"_meth_8371", 0x8371}, // SP 0x000000000 MP 0x140477FD0 + {"_meth_8372", 0x8372}, // SP 0x000000000 MP 0x140479720 + {"_meth_8373", 0x8373}, // SP 0x000000000 MP 0x140479610 + {"_meth_8374", 0x8374}, // SP 0x000000000 MP 0x140478560 + {"_meth_8375", 0x8375}, // SP 0x000000000 MP 0x1404780D0 + {"_meth_8377", 0x8377}, // SP 0x000000000 MP 0x1404799A0 + {"_meth_8378", 0x8378}, // SP 0x000000000 MP 0x140479840 + {"_meth_8379", 0x8379}, // SP 0x000000000 MP 0x140477F20 + {"_meth_837A", 0x837A}, // SP 0x000000000 MP 0x1404782F0 + {"_meth_837B", 0x837B}, // SP 0x000000000 MP 0x140478910 + {"_meth_837C", 0x837C}, // SP 0x000000000 MP 0x140479510 + {"_meth_837D", 0x837D}, // SP 0x000000000 MP 0x140477B70 + {"_meth_837E", 0x837E}, // SP 0x000000000 MP 0x1404791D0 + {"_meth_837F", 0x837F}, // SP 0x000000000 MP 0x14032E760 + {"_meth_8380", 0x8380}, // SP 0x000000000 MP 0x14037AD60 + {"_meth_8381", 0x8381}, // SP 0x000000000 MP 0x14037A3B0 + {"_meth_8382", 0x8382}, // SP 0x1402A15D0 MP 0x140358460 + {"_meth_8383", 0x8383}, // SP 0x000000000 MP 0x14037A980 + {"_meth_8384", 0x8384}, // SP 0x000000000 MP 0x14032E920 + {"_meth_8385", 0x8385}, // SP 0x140262C60 MP 0x14032E340 + {"_meth_8386", 0x8386}, // SP 0x000000000 MP 0x14037B1B0 + {"_meth_8388", 0x8388}, // SP 0x000000000 MP 0x14044EF90 + {"_meth_8389", 0x8389}, // SP 0x000000000 MP 0x14044E610 + {"_meth_838A", 0x838A}, // SP 0x000000000 MP 0x14044EE40 + {"_meth_838B", 0x838B}, // SP 0x000000000 MP 0x14044E0E0 + {"_meth_838C", 0x838C}, // SP 0x000000000 MP 0x14044DF00 + {"_meth_838D", 0x838D}, // SP 0x000000000 MP 0x140450B20 + {"_meth_838E", 0x838E}, // SP 0x000000000 MP 0x140450120 + {"_meth_838F", 0x838F}, // SP 0x000000000 MP 0x14044F670 + {"_meth_8390", 0x8390}, // SP 0x000000000 MP 0x140450090 + {"_meth_8391", 0x8391}, // SP 0x000000000 MP 0x140450000 + {"_meth_8392", 0x8392}, // SP 0x000000000 MP 0x140450260 + {"_meth_8393", 0x8393}, // SP 0x000000000 MP 0x14044FEC0 + {"_meth_8394", 0x8394}, // SP 0x000000000 MP 0x140450540 + {"_meth_8395", 0x8395}, // SP 0x000000000 MP 0x14044FDA0 + {"_meth_8396", 0x8396}, // SP 0x000000000 MP 0x140450780 + {"_meth_8397", 0x8397}, // SP 0x000000000 MP 0x14044FF60 + {"_meth_8398", 0x8398}, // SP 0x000000000 MP 0x140450370 + {"_meth_8399", 0x8399}, // SP 0x000000000 MP 0x14044F7A0 + {"_meth_839A", 0x839A}, // SP 0x000000000 MP 0x14044F2A0 + {"_meth_839B", 0x839B}, // SP 0x000000000 MP 0x140450840 + {"_meth_839C", 0x839C}, // SP 0x000000000 MP 0x14044F5D0 + {"_meth_839D", 0x839D}, // SP 0x000000000 MP 0x14044F480 + {"_meth_839E", 0x839E}, // SP 0x000000000 MP 0x140450AA0 + {"_meth_839F", 0x839F}, // SP 0x000000000 MP 0x14044F370 + {"_meth_83A0", 0x83A0}, // SP 0x000000000 MP 0x14044FC90 + {"_meth_83A1", 0x83A1}, // SP 0x14026DD90 MP 0x14033BCE0 + {"_meth_83A2", 0x83A2}, // SP 0x14026DE40 MP 0x14033BD90 + {"_meth_83A3", 0x83A3}, // SP 0x14026DEB0 MP 0x14033BDF0 + {"_meth_83A4", 0x83A4}, // SP 0x14026DF20 MP 0x14033BE50 + {"_meth_83A5", 0x83A5}, // SP 0x1402A84A0 MP 0x000000000 + {"_meth_83A6", 0x83A6}, // SP 0x140260B80 MP 0x14032CDC0 + {"_meth_83A7", 0x83A7}, // SP 0x140260DE0 MP 0x14032CEA0 + {"_meth_83A8", 0x83A8}, // SP 0x140268480 MP 0x000000000 + {"_meth_83A9", 0x83A9}, // SP 0x1402A8750 MP 0x000000000 + {"_meth_83AA", 0x83AA}, // SP 0x1402A8860 MP 0x000000000 + {"_meth_83AB", 0x83AB}, // SP 0x140268330 MP 0x000000000 + {"_meth_83AC", 0x83AC}, // SP 0x140268410 MP 0x000000000 + {"_meth_83AD", 0x83AD}, // SP 0x1402683A0 MP 0x000000000 + {"_meth_83B0", 0x83B0}, // SP 0x1405D92F0 MP 0x14032CC20 + {"_meth_83B1", 0x83B1}, // SP 0x1402670A0 MP 0x14032B5D0 + {"_meth_83B2", 0x83B2}, // SP 0x140267250 MP 0x14032B7B0 + {"_meth_83B3", 0x83B3}, // SP 0x1404651B0 MP 0x14055F010 + {"_meth_83B4", 0x83B4}, // SP 0x1404651C0 MP 0x14055F020 + {"_meth_83B5", 0x83B5}, // SP 0x000000000 MP 0x14037BCD0 + {"_meth_83B6", 0x83B6}, // SP 0x14029C100 MP 0x140367570 + {"_meth_83B7", 0x83B7}, // SP 0x140299860 MP 0x140364840 + {"_meth_83B8", 0x83B8}, // SP 0x14028E830 MP 0x140364960 + {"_meth_83B9", 0x83B9}, // SP 0x140261C60 MP 0x14032D930 + {"_meth_83BA", 0x83BA}, // SP 0x140462CB0 MP 0x1405614F0 + {"_meth_83BB", 0x83BB}, // SP 0x140462D60 MP 0x1405615A0 + {"_meth_83BC", 0x83BC}, // SP 0x140462DE0 MP 0x140561620 + {"_meth_83BD", 0x83BD}, // SP 0x14028AB00 MP 0x000000000 + {"_meth_83BE", 0x83BE}, // SP 0x140263B80 MP 0x140330060 + {"_meth_83BF", 0x83BF}, // SP 0x140263C60 MP 0x140330200 + {"_meth_83C0", 0x83C0}, // SP 0x140263F70 MP 0x140330470 + {"_meth_83C1", 0x83C1}, // SP 0x1402B3B00 MP 0x14037F840 + {"_meth_83C2", 0x83C2}, // SP 0x1402D7D50 MP 0x1400778A0 + {"_meth_83C3", 0x83C3}, // SP 0x1404623A0 MP 0x140560AC0 + {"_meth_83C4", 0x83C4}, // SP 0x1405D92F0 MP 0x14032D370 + {"_meth_83C5", 0x83C5}, // SP 0x14028AA90 MP 0x000000000 + {"_meth_83C6", 0x83C6}, // SP 0x14024AEF0 MP 0x000000000 + {"_meth_83C7", 0x83C7}, // SP 0x14024B000 MP 0x000000000 + {"_meth_83C8", 0x83C8}, // SP 0x14024B340 MP 0x000000000 + {"_meth_83C9", 0x83C9}, // SP 0x14024B420 MP 0x000000000 + {"_meth_83CA", 0x83CA}, // SP 0x14024B6D0 MP 0x000000000 + {"_meth_83CB", 0x83CB}, // SP 0x14024B660 MP 0x000000000 + {"_meth_83CC", 0x83CC}, // SP 0x14024B740 MP 0x000000000 + {"_meth_83CD", 0x83CD}, // SP 0x14024B7A0 MP 0x000000000 + {"_meth_83CE", 0x83CE}, // SP 0x000000000 MP 0x1400781E0 + {"_meth_83CF", 0x83CF}, // SP 0x000000000 MP 0x140077CB0 + {"_meth_83D0", 0x83D0}, // SP 0x000000000 MP 0x140078250 + {"_meth_83D1", 0x83D1}, // SP 0x000000000 MP 0x140077DF0 + {"_meth_83D2", 0x83D2}, // SP 0x000000000 MP 0x140077FA0 + {"_meth_83D3", 0x83D3}, // SP 0x000000000 MP 0x140077E80 + {"_meth_83D4", 0x83D4}, // SP 0x000000000 MP 0x140077EE0 + {"_meth_83D5", 0x83D5}, // SP 0x1402AE190 MP 0x000000000 + {"_meth_83D6", 0x83D6}, // SP 0x1402613C0 MP 0x14032CB20 + {"_meth_83D7", 0x83D7}, // SP 0x140291320 MP 0x000000000 + {"_meth_83D8", 0x83D8}, // SP 0x1402495B0 MP 0x000000000 + {"_meth_83D9", 0x83D9}, // SP 0x1405D92F0 MP 0x140358020 + {"_meth_83DA", 0x83DA}, // SP 0x140264C80 MP 0x000000000 + {"_meth_83DB", 0x83DB}, // SP 0x140264C80 MP 0x000000000 + {"_meth_83DC", 0x83DC}, // SP 0x140261B80 MP 0x14032D800 + {"_meth_83DD", 0x83DD}, // SP 0x1402B3200 MP 0x14037EF90 + {"_meth_83DE", 0x83DE}, // SP 0x000000000 MP 0x14044F710 + {"_meth_83DF", 0x83DF}, // SP 0x000000000 MP 0x14044FAD0 + {"_meth_83E0", 0x83E0}, // SP 0x1402A15D0 MP 0x14036E1F0 + {"_meth_83E1", 0x83E1}, // SP 0x000000000 MP 0x140374840 + {"_meth_83E2", 0x83E2}, // SP 0x14029FD00 MP 0x140358090 + {"_meth_83E3", 0x83E3}, // SP 0x1402A0C60 MP 0x140369520 + {"_meth_83E4", 0x83E4}, // SP 0x1402A20D0 MP 0x140369FE0 + {"_meth_83E5", 0x83E5}, // SP 0x1405D92F0 MP 0x14033B020 + {"_meth_83E6", 0x83E6}, // SP 0x1402A7B00 MP 0x000000000 + {"_meth_83E7", 0x83E7}, // SP 0x1402A7C90 MP 0x000000000 + {"_meth_83E8", 0x83E8}, // SP 0x140263140 MP 0x14032F7A0 + {"_meth_83E9", 0x83E9}, // SP 0x14026D2E0 MP 0x14033B450 + {"_meth_83EA", 0x83EA}, // SP 0x14028DB50 MP 0x140359B60 + {"_meth_83EB", 0x83EB}, // SP 0x14028E2A0 MP 0x14035A4D0 + {"_meth_83EC", 0x83EC}, // SP 0x000000000 MP 0x14032CEF0 + {"_meth_83ED", 0x83ED}, // SP 0x1402ADF90 MP 0x000000000 + {"_meth_83EF", 0x83EF}, // SP 0x1402A0B60 MP 0x14036A5C0 + {"_meth_83F0", 0x83F0}, // SP 0x14029F670 MP 0x140369790 + {"_meth_83F1", 0x83F1}, // SP 0x1402913E0 MP 0x14035B490 + {"_meth_83F2", 0x83F2}, // SP 0x140269130 MP 0x000000000 + {"_meth_83F3", 0x83F3}, // SP 0x140269190 MP 0x000000000 + {"_meth_83F4", 0x83F4}, // SP 0x1402A0760 MP 0x1403589E0 + {"_meth_83F5", 0x83F5}, // SP 0x1405D92F0 MP 0x140359100 + {"_meth_83F6", 0x83F6}, // SP 0x1402A15D0 MP 0x14036E200 + {"_meth_83F7", 0x83F7}, // SP 0x140465020 MP 0x140560DF0 + {"_meth_83F8", 0x83F8}, // SP 0x1405D92F0 MP 0x1403636B0 + {"_meth_83F9", 0x83F9}, // SP 0x1405D92F0 MP 0x140363830 + {"_meth_83FA", 0x83FA}, // SP 0x14029BA30 MP 0x140363EA0 + {"_meth_83FB", 0x83FB}, // SP 0x14029BC20 MP 0x1403640D0 + {"_meth_83FC", 0x83FC}, // SP 0x1402AA870 MP 0x000000000 + {"_meth_83FD", 0x83FD}, // SP 0x14024AD20 MP 0x000000000 + {"_meth_83FE", 0x83FE}, // SP 0x140297A40 MP 0x140360C90 + {"_meth_83FF", 0x83FF}, // SP 0x1402974B0 MP 0x000000000 + {"_meth_8400", 0x8400}, // SP 0x1402498E0 MP 0x000000000 + {"_meth_8401", 0x8401}, // SP 0x000000000 MP 0x140477D90 + {"_meth_8402", 0x8402}, // SP 0x140263950 MP 0x000000000 + {"_meth_8403", 0x8403}, // SP 0x140268F10 MP 0x000000000 + {"_meth_8404", 0x8404}, // SP 0x1402977A0 MP 0x000000000 + {"_meth_8405", 0x8405}, // SP 0x1402978F0 MP 0x000000000 + {"_meth_8406", 0x8406}, // SP 0x14029A680 MP 0x000000000 + {"_meth_8407", 0x8407}, // SP 0x000000000 MP 0x140375810 + {"_meth_8408", 0x8408}, // SP 0x1402687F0 MP 0x000000000 + {"_meth_8409", 0x8409}, // SP 0x140268840 MP 0x000000000 + {"_meth_840A", 0x840A}, // SP 0x1402AF930 MP 0x000000000 + {"_meth_840B", 0x840B}, // SP 0x1402AE490 MP 0x000000000 + {"_meth_840C", 0x840C}, // SP 0x1402AE5D0 MP 0x000000000 + {"_meth_840D", 0x840D}, // SP 0x1402B4000 MP 0x14037FDE0 + {"_meth_840E", 0x840E}, // SP 0x1402B40B0 MP 0x14037FE90 + {"_meth_840F", 0x840F}, // SP 0x1402B4160 MP 0x14037FF40 + {"_meth_8410", 0x8410}, // SP 0x1402B41F0 MP 0x140380000 + {"_meth_8411", 0x8411}, // SP 0x1402B42B0 MP 0x1403800E0 + {"_meth_8412", 0x8412}, // SP 0x1402B4340 MP 0x1403801A0 + {"_meth_8413", 0x8413}, // SP 0x000000000 MP 0x14035A430 + {"_meth_8414", 0x8414}, // SP 0x000000000 MP 0x14035A480 + {"_meth_8415", 0x8415}, // SP 0x000000000 MP 0x140376790 + {"_meth_8416", 0x8416}, // SP 0x000000000 MP 0x1403767B0 + {"_meth_8417", 0x8417}, // SP 0x000000000 MP 0x14036F610 + {"_meth_8418", 0x8418}, // SP 0x000000000 MP 0x140357DB0 + {"_meth_8419", 0x8419}, // SP 0x000000000 MP 0x1403767E0 + {"_meth_841A", 0x841A}, // SP 0x1405D92F0 MP 0x1403630D0 + {"_meth_841B", 0x841B}, // SP 0x1405D92F0 MP 0x140363500 + {"_meth_841C", 0x841C}, // SP 0x1405D92F0 MP 0x140363590 + {"_meth_841D", 0x841D}, // SP 0x1405D92F0 MP 0x140363620 + {"_meth_841E", 0x841E}, // SP 0x140299270 MP 0x140364190 + {"_meth_841F", 0x841F}, // SP 0x000000000 MP 0x1403326E0 + {"_meth_8420", 0x8420}, // SP 0x000000000 MP 0x1403328E0 + {"_meth_8421", 0x8421}, // SP 0x14029FEB0 MP 0x140369B60 + {"_meth_8422", 0x8422}, // SP 0x1402A00C0 MP 0x140369E10 + {"_meth_8423", 0x8423}, // SP 0x000000000 MP 0x14044F520 + {"_meth_8424", 0x8424}, // SP 0x1402B30B0 MP 0x000000000 + {"_meth_8425", 0x8425}, // SP 0x1402B3280 MP 0x000000000 + {"_meth_8426", 0x8426}, // SP 0x1402B3320 MP 0x000000000 + {"_meth_8427", 0x8427}, // SP 0x000000000 MP 0x1403748F0 + {"_meth_8428", 0x8428}, // SP 0x1402ABE20 MP 0x000000000 + {"_meth_8429", 0x8429}, // SP 0x000000000 MP 0x140379520 + {"_meth_842A", 0x842A}, // SP 0x000000000 MP 0x140379B70 + {"_meth_842B", 0x842B}, // SP 0x000000000 MP 0x1403785F0 + {"_meth_842C", 0x842C}, // SP 0x000000000 MP 0x1403321B0 + {"_meth_842D", 0x842D}, // SP 0x000000000 MP 0x140334A60 + {"_meth_842E", 0x842E}, // SP 0x140262C10 MP 0x14032F2B0 + {"_meth_842F", 0x842F}, // SP 0x140262D40 MP 0x14032F480 + {"_meth_8430", 0x8430}, // SP 0x1405D92F0 MP 0x000000000 + {"_meth_8431", 0x8431}, // SP 0x14028E020 MP 0x14035A3A0 + {"_meth_8432", 0x8432}, // SP 0x000000000 MP 0x140479320 + {"_meth_8433", 0x8433}, // SP 0x000000000 MP 0x140377F80 + {"_meth_8434", 0x8434}, // SP 0x140266DD0 MP 0x14032B210 + {"_meth_8435", 0x8435}, // SP 0x000000000 MP 0x140332F50 + {"_meth_8437", 0x8437}, // SP 0x1402A0440 MP 0x1403586F0 + {"_meth_8438", 0x8438}, // SP 0x1402A0B00 MP 0x140358FF0 + {"_meth_8439", 0x8439}, // SP 0x000000000 MP 0x140379890 + {"_meth_843A", 0x843A}, // SP 0x14024B810 MP 0x000000000 + {"_meth_843B", 0x843B}, // SP 0x14024B8B0 MP 0x000000000 + {"_meth_843C", 0x843C}, // SP 0x140265900 MP 0x1403294C0 + {"_meth_843D", 0x843D}, // SP 0x14024BCE0 MP 0x000000000 + {"_meth_843E", 0x843E}, // SP 0x14029EC40 MP 0x140368630 + {"_meth_843F", 0x843F}, // SP 0x1405D92F0 MP 0x14032D4E0 + {"_meth_8440", 0x8440}, // SP 0x1404639C0 MP 0x140562210 + {"_meth_8441", 0x8441}, // SP 0x140462EA0 MP 0x1405616E0 + {"_meth_8442", 0x8442}, // SP 0x1402A36A0 MP 0x140358B60 + {"_meth_8443", 0x8443}, // SP 0x140266090 MP 0x14032A550 + {"_meth_8444", 0x8444}, // SP 0x1402A8A40 MP 0x000000000 + {"_meth_8445", 0x8445}, // SP 0x1402A8A80 MP 0x000000000 + {"_meth_8446", 0x8446}, // SP 0x1402A2F70 MP 0x14036CC00 + {"_meth_8447", 0x8447}, // SP 0x1405D92F0 MP 0x140363840 + {"_meth_8448", 0x8448}, // SP 0x1405D92F0 MP 0x140363A50 + {"_meth_8449", 0x8449}, // SP 0x1402611B0 MP 0x14032C860 + {"_meth_844A", 0x844A}, // SP 0x140295480 MP 0x1403602C0 + {"_meth_844B", 0x844B}, // SP 0x140295650 MP 0x1403604C0 + {"_meth_844C", 0x844C}, // SP 0x140463020 MP 0x140561860 + {"_meth_844D", 0x844D}, // SP 0x140463040 MP 0x140561880 + {"_meth_844E", 0x844E}, // SP 0x140463060 MP 0x1405618A0 + {"_meth_844F", 0x844F}, // SP 0x140463080 MP 0x1405618C0 + {"_meth_8450", 0x8450}, // SP 0x1402AC9E0 MP 0x000000000 + {"_meth_8451", 0x8451}, // SP 0x1402ACB20 MP 0x000000000 + {"_meth_8452", 0x8452}, // SP 0x140462F60 MP 0x1405617A0 + {"_meth_8453", 0x8453}, // SP 0x140261E30 MP 0x14032DC80 + {"_meth_8454", 0x8454}, // SP 0x1402612F0 MP 0x000000000 + {"_meth_8455", 0x8455}, // SP 0x1402AD1E0 MP 0x000000000 + {"_meth_8458", 0x8458}, // SP 0x14029DE70 MP 0x140366600 + {"_meth_8459", 0x8459}, // SP 0x140265E70 MP 0x140329A80 + {"_meth_845A", 0x845A}, // SP 0x000000000 MP 0x140359980 + {"_meth_845B", 0x845B}, // SP 0x000000000 MP 0x14035A040 + {"_meth_845C", 0x845C}, // SP 0x140264C80 MP 0x000000000 + {"_meth_845D", 0x845D}, // SP 0x14028E7C0 MP 0x14035A8D0 + {"_meth_845E", 0x845E}, // SP 0x000000000 MP 0x1403762F0 + {"_meth_845F", 0x845F}, // SP 0x000000000 MP 0x140376340 + {"_meth_8460", 0x8460}, // SP 0x000000000 MP 0x140347ED0 + {"_meth_8461", 0x8461}, // SP 0x1402675A0 MP 0x14032B560 + {"_meth_8462", 0x8462}, // SP 0x1402614A0 MP 0x14032CC30 + {"_meth_8463", 0x8463}, // SP 0x140291970 MP 0x14035B8F0 + {"_meth_8464", 0x8464}, // SP 0x140261DC0 MP 0x000000000 + {"_meth_8465", 0x8465}, // SP 0x000000000 MP 0x14032FE10 + {"_meth_8466", 0x8466}, // SP 0x1402B47A0 MP 0x140380A60 + {"_meth_8467", 0x8467}, // SP 0x1402B4950 MP 0x140380C30 + {"_meth_8468", 0x8468}, // SP 0x1402A2E30 MP 0x000000000 + {"_meth_8469", 0x8469}, // SP 0x1402A3290 MP 0x000000000 + {"_meth_846A", 0x846A}, // SP 0x1402A3360 MP 0x000000000 + {"_meth_846B", 0x846B}, // SP 0x1402A36C0 MP 0x000000000 + {"_meth_846C", 0x846C}, // SP 0x14028DBB0 MP 0x000000000 + {"_meth_846D", 0x846D}, // SP 0x140260B20 MP 0x000000000 + {"_meth_846E", 0x846E}, // SP 0x1402A8530 MP 0x000000000 + {"_meth_846F", 0x846F}, // SP 0x140463100 MP 0x140561940 + {"_meth_8470", 0x8470}, // SP 0x140463140 MP 0x140561980 + {"_meth_8471", 0x8471}, // SP 0x1404631A0 MP 0x1405619E0 + {"_meth_8472", 0x8472}, // SP 0x1404631F0 MP 0x140561A30 + {"_meth_8473", 0x8473}, // SP 0x140463210 MP 0x140561A50 + {"_meth_8474", 0x8474}, // SP 0x140291B70 MP 0x14035E030 + {"_meth_8475", 0x8475}, // SP 0x140291E30 MP 0x14035E0D0 + {"_meth_8476", 0x8476}, // SP 0x140263970 MP 0x14032FE30 + {"_meth_8477", 0x8477}, // SP 0x1402A85E0 MP 0x000000000 + {"_meth_8478", 0x8478}, // SP 0x1402A86E0 MP 0x000000000 + {"_meth_8479", 0x8479}, // SP 0x1405D92F0 MP 0x14032C130 + {"_meth_847A", 0x847A}, // SP 0x1405D92F0 MP 0x14032C420 + {"_meth_847B", 0x847B}, // SP 0x140462450 MP 0x140560B70 + {"_meth_847C", 0x847C}, // SP 0x1404624D0 MP 0x140560BF0 + {"_meth_847D", 0x847D}, // SP 0x140262900 MP 0x14032E940 + {"_meth_847E", 0x847E}, // SP 0x1402629A0 MP 0x14032E9D0 + {"_meth_847F", 0x847F}, // SP 0x14029CB70 MP 0x140367C30 + {"_meth_8480", 0x8480}, // SP 0x140291DA0 MP 0x000000000 + {"_meth_8481", 0x8481}, // SP 0x1405D92F0 MP 0x14032CD40 + {"_meth_8482", 0x8482}, // SP 0x1405D92F0 MP 0x14032CD30 + {"_meth_8483", 0x8483}, // SP 0x000000000 MP 0x14044E5B0 + {"_meth_8484", 0x8484}, // SP 0x140464FB0 MP 0x140563710 + {"_meth_8485", 0x8485}, // SP 0x1404630B0 MP 0x1405618F0 + {"_meth_8486", 0x8486}, // SP 0x000000000 MP 0x14044DF90 + {"_meth_8487", 0x8487}, // SP 0x000000000 MP 0x140380630 + {"_meth_8488", 0x8488}, // SP 0x1402B3150 MP 0x000000000 + {"_meth_8489", 0x8489}, // SP 0x1405D92F0 MP 0x14032CD20 + {"_meth_848A", 0x848A}, // SP 0x140465030 MP 0x140563790 + {"_meth_848B", 0x848B}, // SP 0x140465020 MP 0x140563720 + {"_meth_848C", 0x848C}, // SP 0x1402641A0 MP 0x140330610 + {"_meth_848D", 0x848D}, // SP 0x140264320 MP 0x140330840 + {"_meth_848E", 0x848E}, // SP 0x140264550 MP 0x140330970 + {"_meth_848F", 0x848F}, // SP 0x1402694A0 MP 0x000000000 + {"_meth_8490", 0x8490}, // SP 0x1405D92F0 MP 0x14035E610 + {"_meth_8491", 0x8491}, // SP 0x000000000 MP 0x14037A4A0 + {"_meth_8492", 0x8492}, // SP 0x000000000 MP 0x14037A510 + {"_meth_8493", 0x8493}, // SP 0x1402ACF90 MP 0x000000000 + {"_meth_8494", 0x8494}, // SP 0x1402AD070 MP 0x000000000 + {"_meth_8495", 0x8495}, // SP 0x140268C60 MP 0x000000000 + {"_meth_8496", 0x8496}, // SP 0x000000000 MP 0x140375380 + {"_meth_8497", 0x8497}, // SP 0x000000000 MP 0x140376030 + {"_meth_8498", 0x8498}, // SP 0x140266500 MP 0x14032AB70 + {"_meth_8499", 0x8499}, // SP 0x140266B20 MP 0x14032AF60 + {"_meth_849A", 0x849A}, // SP 0x1405D92F0 MP 0x14032CCB0 + {"_meth_849B", 0x849B}, // SP 0x000000000 MP 0x140375470 + {"_meth_849C", 0x849C}, // SP 0x000000000 MP 0x140375490 + {"_meth_849D", 0x849D}, // SP 0x000000000 MP 0x140375640 + {"_meth_849E", 0x849E}, // SP 0x000000000 MP 0x140375650 + {"_meth_849F", 0x849F}, // SP 0x000000000 MP 0x140375660 + {"_meth_84A0", 0x84A0}, // SP 0x000000000 MP 0x140375680 + {"_meth_84A1", 0x84A1}, // SP 0x000000000 MP 0x140375670 + {"_meth_84A2", 0x84A2}, // SP 0x000000000 MP 0x1403756C0 + {"_meth_84A3", 0x84A3}, // SP 0x000000000 MP 0x1403757F0 + {"_meth_84A4", 0x84A4}, // SP 0x000000000 MP 0x1403756B0 + {"_meth_84A5", 0x84A5}, // SP 0x14029FDA0 MP 0x140369CB0 + {"_meth_84A6", 0x84A6}, // SP 0x1402A02F0 MP 0x14036A120 + {"_meth_84A7", 0x84A7}, // SP 0x1402A04A0 MP 0x14036A190 + {"_meth_84A8", 0x84A8}, // SP 0x1402A0FE0 MP 0x14036A960 + {"_meth_84A9", 0x84A9}, // SP 0x140465C50 MP 0x14055FBF0 + {"_meth_84AA", 0x84AA}, // SP 0x1402979E0 MP 0x1403625A0 + {"_meth_84AB", 0x84AB}, // SP 0x140297E40 MP 0x140362BD0 + {"_meth_84AC", 0x84AC}, // SP 0x140261E70 MP 0x14032DAE0 + {"_meth_84AD", 0x84AD}, // SP 0x1404663D0 MP 0x1405602E0 + {"_meth_84AE", 0x84AE}, // SP 0x1404664D0 MP 0x1405603E0 + {"_meth_84AF", 0x84AF}, // SP 0x000000000 MP 0x140333050 + {"_meth_84B0", 0x84B0}, // SP 0x1405D92F0 MP 0x140369850 + {"_meth_84B1", 0x84B1}, // SP 0x1402922D0 MP 0x14035E650 + {"_meth_84B2", 0x84B2}, // SP 0x1402925B0 MP 0x14035E660 + {"_meth_84B3", 0x84B3}, // SP 0x140292CD0 MP 0x14035E700 + {"_meth_84B4", 0x84B4}, // SP 0x140292FC0 MP 0x14035E720 + {"_meth_84B5", 0x84B5}, // SP 0x1405D92F0 MP 0x140364AA0 + {"_meth_84B6", 0x84B6}, // SP 0x1405D92F0 MP 0x14036BC80 + {"_meth_84B7", 0x84B7}, // SP 0x1404655C0 MP 0x14055F460 + {"_meth_84B8", 0x84B8}, // SP 0x1402A09C0 MP 0x14036A6A0 + {"_meth_84B9", 0x84B9}, // SP 0x000000000 MP 0x1403807B0 + {"_meth_84BB", 0x84BB}, // SP 0x1402643F0 MP 0x140330910 + {"_meth_84BC", 0x84BC}, // SP 0x140264500 MP 0x140330A20 + {"_meth_84BD", 0x84BD}, // SP 0x000000000 MP 0x1403330D0 + {"_meth_84BE", 0x84BE}, // SP 0x000000000 MP 0x1403335E0 + {"_meth_84BF", 0x84BF}, // SP 0x140265260 MP 0x1403311D0 + {"_meth_84C0", 0x84C0}, // SP 0x140265710 MP 0x1403291C0 + {"_meth_84C1", 0x84C1}, // SP 0x000000000 MP 0x1403766D0 + {"_meth_84C2", 0x84C2}, // SP 0x14029E430 MP 0x14036AA10 + {"_meth_84C3", 0x84C3}, // SP 0x140463250 MP 0x140561A90 + {"_meth_84C4", 0x84C4}, // SP 0x000000000 MP 0x140450E40 + {"_meth_84C5", 0x84C5}, // SP 0x000000000 MP 0x140450B10 + {"_meth_84C6", 0x84C6}, // SP 0x140260790 MP 0x14032BD80 + {"_meth_84C7", 0x84C7}, // SP 0x140260590 MP 0x000000000 + {"_meth_84C8", 0x84C8}, // SP 0x1402606E0 MP 0x000000000 + {"_meth_84C9", 0x84C9}, // SP 0x140464D30 MP 0x1405634E0 + {"_meth_84CA", 0x84CA}, // SP 0x140464DC0 MP 0x140563580 + {"_meth_84CB", 0x84CB}, // SP 0x000000000 MP 0x140334CC0 + {"_meth_84CC", 0x84CC}, // SP 0x140463270 MP 0x140561AB0 + {"_meth_84CD", 0x84CD}, // SP 0x1402A1470 MP 0x14036A8C0 + {"_meth_84CE", 0x84CE}, // SP 0x1402A15E0 MP 0x14036AD30 + {"_meth_84CF", 0x84CF}, // SP 0x14029ED60 MP 0x1403685E0 + {"_meth_84D0", 0x84D0}, // SP 0x14029EED0 MP 0x1403687A0 + {"_meth_84D1", 0x84D1}, // SP 0x14029F130 MP 0x1403687F0 + {"_meth_84D2", 0x84D2}, // SP 0x14029F300 MP 0x140368AC0 + {"_meth_84D3", 0x84D3}, // SP 0x14029F350 MP 0x140368CE0 + {"_meth_84D4", 0x84D4}, // SP 0x14029F410 MP 0x140368D50 + {"_meth_84D5", 0x84D5}, // SP 0x14029F530 MP 0x140368DF0 + {"_meth_84D6", 0x84D6}, // SP 0x14029F5E0 MP 0x140368ED0 + {"_meth_84D8", 0x84D8}, // SP 0x1402674E0 MP 0x14032B4A0 + {"_meth_84D9", 0x84D9}, // SP 0x1402B4400 MP 0x140380280 + {"_meth_84DA", 0x84DA}, // SP 0x000000000 MP 0x14035B2A0 + {"_meth_84DB", 0x84DB}, // SP 0x140248770 MP 0x000000000 + {"_meth_84DC", 0x84DC}, // SP 0x140461FF0 MP 0x000000000 + {"_meth_84DF", 0x84DF}, // SP 0x14028DF20 MP 0x14035B180 + {"_meth_84E0", 0x84E0}, // SP 0x14026E2F0 MP 0x14033C220 + {"_meth_84E1", 0x84E1}, // SP 0x1404632B0 MP 0x140561AF0 + {"_meth_84E2", 0x84E2}, // SP 0x000000000 MP 0x14036F110 + {"_meth_84E3", 0x84E3}, // SP 0x140264A30 MP 0x140331120 + {"_meth_84E4", 0x84E4}, // SP 0x1405D92F0 MP 0x1403604A0 + {"_meth_84E5", 0x84E5}, // SP 0x1402A88B0 MP 0x000000000 + {"_meth_84E6", 0x84E6}, // SP 0x1405D92F0 MP 0x14036C920 + {"_meth_84E8", 0x84E8}, // SP 0x140264970 MP 0x140330E00 + {"_meth_84E9", 0x84E9}, // SP 0x1402649D0 MP 0x140330E10 + {"_meth_84EA", 0x84EA}, // SP 0x14028ABB0 MP 0x000000000 + {"_meth_84EB", 0x84EB}, // SP 0x14029AF70 MP 0x140364720 + {"_meth_84EC", 0x84EC}, // SP 0x1402A11C0 MP 0x140359610 + {"_meth_84ED", 0x84ED}, // SP 0x140293540 MP 0x140360150 + {"_meth_84EE", 0x84EE}, // SP 0x140298540 MP 0x140361720 + {"_meth_84EF", 0x84EF}, // SP 0x14029B960 MP 0x140363B90 + {"_meth_84F0", 0x84F0}, // SP 0x1404643D0 MP 0x140562AB0 + {"_meth_84F1", 0x84F1}, // SP 0x1404644E0 MP 0x140562BE0 + {"_meth_84F2", 0x84F2}, // SP 0x1405D92F0 MP 0x14035B8C0 + {"_meth_84F3", 0x84F3}, // SP 0x1405D92F0 MP 0x14035B990 + {"_meth_84F4", 0x84F4}, // SP 0x14028E1A0 MP 0x14035B280 + {"_meth_84F5", 0x84F5}, // SP 0x14028E1A0 MP 0x14035B360 + {"_meth_84F6", 0x84F6}, // SP 0x1405D92F0 MP 0x14035B390 + {"_meth_84F7", 0x84F7}, // SP 0x14028E830 MP 0x14035B3A0 + {"_meth_84F8", 0x84F8}, // SP 0x14028E830 MP 0x14035B430 + {"_meth_84F9", 0x84F9}, // SP 0x14028E830 MP 0x14035B540 + {"_meth_84FA", 0x84FA}, // SP 0x1405D92F0 MP 0x14035B7A0 + {"_meth_84FB", 0x84FB}, // SP 0x14029EDE0 MP 0x14036EA10 + {"_meth_84FC", 0x84FC}, // SP 0x140290D70 MP 0x14035A740 + {"_meth_84FD", 0x84FD}, // SP 0x000000000 MP 0x140334AC0 + {"_meth_84FE", 0x84FE}, // SP 0x000000000 MP 0x140376800 + {"_meth_84FF", 0x84FF}, // SP 0x000000000 MP 0x1403768C0 + {"_meth_8500", 0x8500}, // SP 0x14028F5A0 MP 0x14035A550 + {"_meth_8501", 0x8501}, // SP 0x14028E4D0 MP 0x140359550 + {"_meth_8502", 0x8502}, // SP 0x000000000 MP 0x1403767F0 + {"_meth_8503", 0x8503}, // SP 0x14028F6E0 MP 0x14035C670 + {"_meth_8504", 0x8504}, // SP 0x000000000 MP 0x14037A470 + {"_meth_8505", 0x8505}, // SP 0x000000000 MP 0x140374F20 + {"_meth_8506", 0x8506}, // SP 0x000000000 MP 0x14037ADD0 + {"_meth_8507", 0x8507}, // SP 0x000000000 MP 0x14037AAF0 + {"_meth_8508", 0x8508}, // SP 0x000000000 MP 0x140332BC0 + {"_meth_8509", 0x8509}, // SP 0x1402AC990 MP 0x000000000 + {"_meth_850A", 0x850A}, // SP 0x1402646B0 MP 0x140330A80 + {"_meth_850B", 0x850B}, // SP 0x14026DCB0 MP 0x14033BC10 + {"_meth_850C", 0x850C}, // SP 0x000000000 MP 0x140376020 + {"_meth_850D", 0x850D}, // SP 0x14029E8F0 MP 0x1403682B0 + {"_meth_850E", 0x850E}, // SP 0x14029ED00 MP 0x140368570 + {"_meth_850F", 0x850F}, // SP 0x14029A7B0 MP 0x140362600 + {"_meth_8510", 0x8510}, // SP 0x140267840 MP 0x14032BE50 + {"_meth_8511", 0x8511}, // SP 0x140290ED0 MP 0x14035A8E0 + {"_meth_8512", 0x8512}, // SP 0x1404632E0 MP 0x140561B20 + {"_meth_8513", 0x8513}, // SP 0x140463300 MP 0x140561B40 + {"_meth_8514", 0x8514}, // SP 0x14028E830 MP 0x14032B9B0 + {"_meth_8515", 0x8515}, // SP 0x14028E830 MP 0x14032B9D0 + {"_meth_8516", 0x8516}, // SP 0x140299C10 MP 0x140361690 + {"_meth_8517", 0x8517}, // SP 0x000000000 MP 0x1403747A0 + {"_meth_8518", 0x8518}, // SP 0x14026D400 MP 0x14033B580 + {"_meth_8519", 0x8519}, // SP 0x000000000 MP 0x140376990 + {"_meth_851A", 0x851A}, // SP 0x140261370 MP 0x14032C9D0 + {"_meth_851B", 0x851B}, // SP 0x14029F3C0 MP 0x14036EEC0 + {"_meth_851C", 0x851C}, // SP 0x14028E830 MP 0x14036E3D0 + {"_meth_851D", 0x851D}, // SP 0x1402B4480 MP 0x140380300 + {"_meth_851E", 0x851E}, // SP 0x14028A8B0 MP 0x000000000 + {"_meth_851F", 0x851F}, // SP 0x000000000 MP 0x140333EE0 + {"_meth_8520", 0x8520}, // SP 0x000000000 MP 0x14044EEC0 + {"_meth_8521", 0x8521}, // SP 0x140263930 MP 0x000000000 + {"_meth_8522", 0x8522}, // SP 0x000000000 MP 0x140332340 + {"_meth_8523", 0x8523}, // SP 0x1405D92F0 MP 0x140358DC0 + {"_meth_8524", 0x8524}, // SP 0x14028DDD0 MP 0x140359FE0 + {"_meth_8525", 0x8525}, // SP 0x000000000 MP 0x140374C50 + {"_meth_8526", 0x8526}, // SP 0x000000000 MP 0x140374CF0 + {"_meth_8527", 0x8527}, // SP 0x14026DD20 MP 0x14033BC70 + {"_meth_8528", 0x8528}, // SP 0x000000000 MP 0x140332E80 + {"_meth_8529", 0x8529}, // SP 0x14028F7C0 MP 0x14035C9C0 + {"_meth_852A", 0x852A}, // SP 0x140297EF0 MP 0x14035F080 + {"_meth_852B", 0x852B}, // SP 0x000000000 MP 0x140332AD0 + {"_meth_852C", 0x852C}, // SP 0x000000000 MP 0x140331F50 + {"_meth_852D", 0x852D}, // SP 0x14028E830 MP 0x14035B7E0 + {"_meth_852E", 0x852E}, // SP 0x000000000 MP 0x140376A60 + {"_meth_852F", 0x852F}, // SP 0x000000000 MP 0x1404508B0 + {"_meth_8530", 0x8530}, // SP 0x000000000 MP 0x14044F1E0 + {"_meth_8531", 0x8531}, // SP 0x000000000 MP 0x1404503F0 + {"_meth_8532", 0x8532}, // SP 0x000000000 MP 0x140333250 + {"_meth_8533", 0x8533}, // SP 0x000000000 MP 0x14044EC20 + {"_meth_8534", 0x8534}, // SP 0x000000000 MP 0x140450670 + {"_meth_8535", 0x8535}, // SP 0x000000000 MP 0x14044FD10 + {"_meth_8536", 0x8536}, // SP 0x000000000 MP 0x1404504B0 + {"_meth_8537", 0x8537}, // SP 0x000000000 MP 0x1404502E0 + {"_meth_8538", 0x8538}, // SP 0x000000000 MP 0x1404506F0 + {"_meth_8539", 0x8539}, // SP 0x000000000 MP 0x140333F40 + {"_meth_853A", 0x853A}, // SP 0x000000000 MP 0x14037F320 + {"_meth_853B", 0x853B}, // SP 0x000000000 MP 0x14044E080 + {"_meth_853C", 0x853C}, // SP 0x14028F0D0 MP 0x14035BF40 + {"_meth_853D", 0x853D}, // SP 0x14028E830 MP 0x14032CCA0 + {"_meth_853E", 0x853E}, // SP 0x000000000 MP 0x140376AC0 + {"_meth_853F", 0x853F}, // SP 0x000000000 MP 0x14044DFF0 + {"_meth_8540", 0x8540}, // SP 0x140299D70 MP 0x140363160 + {"_meth_8541", 0x8541}, // SP 0x14028F260 MP 0x14035C380 + {"_meth_8542", 0x8542}, // SP 0x000000000 MP 0x140376C00 + {"_meth_8543", 0x8543}, // SP 0x000000000 MP 0x140375800 + {"_meth_8544", 0x8544}, // SP 0x000000000 MP 0x14044FA10 + {"_meth_8545", 0x8545}, // SP 0x000000000 MP 0x140333640 + {"_meth_8547", 0x8547}, // SP 0x000000000 MP 0x140450C20 + {"_meth_8548", 0x8548}, // SP 0x140262130 MP 0x14032DF00 + {"_meth_8549", 0x8549}, // SP 0x000000000 MP 0x140333FA0 + {"_meth_854A", 0x854A}, // SP 0x000000000 MP 0x140376C90 + {"_meth_854B", 0x854B}, // SP 0x000000000 MP 0x14044FBA0 + {"_meth_854C", 0x854C}, // SP 0x000000000 MP 0x1403331F0 + {"_meth_854D", 0x854D}, // SP 0x140290CE0 MP 0x14035C300 + {"_meth_854E", 0x854E}, // SP 0x000000000 MP 0x140450A10 + {"_meth_854F", 0x854F}, // SP 0x000000000 MP 0x14044FC10 + {"_meth_8550", 0x8550}, // SP 0x1402B4720 MP 0x1403809E0 + {"_meth_8551", 0x8551}, // SP 0x1402A15D0 MP 0x14035FB60 + {"_meth_8552", 0x8552}, // SP 0x000000000 MP 0x140450C30 + {"_meth_8553", 0x8553}, // SP 0x000000000 MP 0x140375E30 + {"_meth_8554", 0x8554}, // SP 0x000000000 MP 0x14044F3F0 + {"_meth_8555", 0x8555}, // SP 0x000000000 MP 0x140450D30 + {"_meth_8556", 0x8556}, // SP 0x000000000 MP 0x140374980 + {"_meth_8557", 0x8557}, // SP 0x000000000 MP 0x1403749D0 + {"_meth_8558", 0x8558}, // SP 0x000000000 MP 0x140078140 + {"_meth_8559", 0x8559}, // SP 0x1405D92F0 MP 0x14032D760 + {"_meth_855A", 0x855A}, // SP 0x1405D92F0 MP 0x14032D770 + {"_meth_855B", 0x855B}, // SP 0x1405D92F0 MP 0x14032D7F0 + {"_meth_855C", 0x855C}, // SP 0x000000000 MP 0x140376CB0 + {"_meth_855D", 0x855D}, // SP 0x1402A0220 MP 0x1403585F0 + {"_meth_855E", 0x855E}, // SP 0x140293780 MP 0x14035E8C0 + {"_meth_855F", 0x855F}, // SP 0x000000000 MP 0x140374EC0 + {"_meth_8560", 0x8560}, // SP 0x000000000 MP 0x140374F70 + {"_meth_8561", 0x8561}, // SP 0x140292D90 MP 0x14035FB10 + {"_meth_8562", 0x8562}, // SP 0x140293080 MP 0x14035FD80 + {"_meth_8563", 0x8563}, // SP 0x1402B2FB0 MP 0x14037EF00 + {"_meth_8564", 0x8564}, // SP 0x1402CBB60 MP 0x14031F610 + {"_meth_8565", 0x8565}, // SP 0x1402478E0 MP 0x000000000 + {"_meth_8566", 0x8566}, // SP 0x1402A8F10 MP 0x000000000 + {"_meth_8567", 0x8567}, // SP 0x140248F70 MP 0x000000000 + {"_meth_8568", 0x8568}, // SP 0x1402A3820 MP 0x14036E3F0 + {"_meth_8569", 0x8569}, // SP 0x1402982F0 MP 0x140363510 + {"_meth_856A", 0x856A}, // SP 0x1402984C0 MP 0x140363630 + {"_meth_856B", 0x856B}, // SP 0x140296FA0 MP 0x1403619C0 + {"_meth_856C", 0x856C}, // SP 0x140297420 MP 0x140361BA0 + {"_meth_856D", 0x856D}, // SP 0x140297640 MP 0x140361E60 + {"_meth_856E", 0x856E}, // SP 0x14028ABF0 MP 0x000000000 + {"_meth_856F", 0x856F}, // SP 0x14028AC10 MP 0x000000000 + {"_meth_8570", 0x8570}, // SP 0x14028AC60 MP 0x000000000 + {"_meth_8571", 0x8571}, // SP 0x140249010 MP 0x000000000 + {"_meth_8572", 0x8572}, // SP 0x14024AE00 MP 0x000000000 + {"_meth_8573", 0x8573}, // SP 0x140260B70 MP 0x14032C5C0 + {"_meth_8574", 0x8574}, // SP 0x140265AD0 MP 0x140329B40 + {"_meth_8575", 0x8575}, // SP 0x140265C90 MP 0x140329E40 + {"_meth_8576", 0x8576}, // SP 0x000000000 MP 0x140478050 + {"_meth_8577", 0x8577}, // SP 0x000000000 MP 0x140333650 + {"_meth_8578", 0x8578}, // SP 0x140297D90 MP 0x14035FFF0 + {"_meth_8579", 0x8579}, // SP 0x1402933D0 MP 0x14035FF90 + {"_meth_857A", 0x857A}, // SP 0x000000000 MP 0x1403336F0 + {"_meth_857B", 0x857B}, // SP 0x000000000 MP 0x14032B050 + {"_meth_857C", 0x857C}, // SP 0x1405D92F0 MP 0x14036D0E0 + {"_meth_857D", 0x857D}, // SP 0x000000000 MP 0x140334820 + {"_meth_857E", 0x857E}, // SP 0x000000000 MP 0x1403348E0 + {"_meth_857F", 0x857F}, // SP 0x000000000 MP 0x1403329F0 }; std::unordered_map token_map = { - {"CodeCallback_BulletHitEntity", 180}, - {"CodeCallback_CodeEndGame", 181}, - {"CodeCallback_EntityDamage", 182}, - {"CodeCallback_EntityOutOfWorld", 183}, - {"CodeCallback_HostMigration", 185}, - {"CodeCallback_PartyMembers", 187}, - {"CodeCallback_PlayerConnect", 188}, - {"CodeCallback_PlayerDamage", 189}, - {"CodeCallback_PlayerDisconnect", 190}, - {"CodeCallback_PlayerGrenadeSuicide", 191}, - {"CodeCallback_PlayerKilled", 192}, - {"CodeCallback_PlayerLastStand", 193}, - {"CodeCallback_PlayerMigrated", 194}, - {"CodeCallback_StartGameType", 195}, - {"CodeCallback_VehicleDamage", 196}, - {"CreateStruct", 221}, - {"InitStructs", 522}, - {"main", 619}, - {"AbortLevel", 1727}, - {"callbackVoid", 6662}, - {"CodeCallback_GiveKillstreak", 8192}, - {"SetDefaultCallbacks", 32577}, - {"SetupCallbacks", 33531}, - {"SetupDamageFlags", 33542}, - {"struct", 36698}, - {"codescripts/delete", 0x053D}, - {"codescripts/struct", 0x053E}, - {"maps/mp/gametypes/_callbacksetup", 0x0540}, - {"codescripts/character", 0xA4E5}, - {"common_scripts/_artcommon", 42214}, - {"common_scripts/_bcs_location_trigs", 42215}, - {"common_scripts/_createfx", 42216}, - {"common_scripts/_createfxmenu", 42217}, - {"common_scripts/_destructible", 42218}, - {"common_scripts/_dynamic_world", 42219}, - {"maps/createart/mp_vlobby_room_art", 42735}, - {"maps/createart/mp_vlobby_room_fog", 42736}, - {"maps/createart/mp_vlobby_room_fog_hdr", 42737} + {"pl#", 0x001}, + {"-", 0x002}, + {"radius`", 0x003}, + {"note:", 0x004}, + {"_", 0x005}, + {"_custom", 0x006}, + {"a", 0x007}, + {"ability", 0x008}, + {"accumulate", 0x009}, + {"accuracy", 0x00A}, + {"actionslot1", 0x00B}, + {"actionslot2", 0x00C}, + {"actionslot3", 0x00D}, + {"actionslot4", 0x00E}, + {"actionslot5", 0x00F}, + {"actionslot6", 0x010}, + {"actionslot7", 0x011}, + {"actionslot8", 0x012}, + {"activator", 0x013}, + {"active", 0x014}, + {"activecostume", 0x015}, + {"activeemblemslot", 0x016}, + {"activesquadmember", 0x017}, + {"activevisionset", 0x018}, + {"activevisionsetduration", 0x019}, + {"agent", 0x01A}, + {"agenthealth", 0x01B}, + {"agentname", 0x01C}, + {"agentteam", 0x01D}, + {"ai_event", 0x01E}, + {"ai_sight_line_cycle_group", 0x01F}, + {"ai_sight_line_group", 0x020}, + {"aim_highest_bone", 0x021}, + {"aim_vis_bone", 0x022}, + {"aiSpread", 0x023}, + {"aisquadmembers", 0x024}, + {"alert", 0x025}, + {"alertlevel", 0x026}, + {"alertlevelint", 0x027}, + {"alien", 0x028}, + {"alienplayerloadout", 0x029}, + {"alienplayerstats", 0x02A}, + {"aliensession", 0x02B}, + {"alignx", 0x02C}, + {"aligny", 0x02D}, + {"all", 0x02E}, + {"allies", 0x02F}, + {"allowcrouch", 0x030}, + {"allowdeath", 0x031}, + {"allowjump", 0x032}, + {"allowladders", 0x033}, + {"allowpain", 0x034}, + {"allowprone", 0x035}, + {"allstreaksrestricted", 0x036}, + {"alpha", 0x037}, + {"altmode", 0x038}, + {"always", 0x039}, + {"ambient", 0x03A}, + {"ambienttrack", 0x03B}, + {"ambienttrack_ac130", 0x03C}, + {"ambush", 0x03D}, + {"ambush_nodes_only", 0x03E}, + {"angle_deltas", 0x03F}, + {"anglelerprate", 0x040}, + {"angles", 0x041}, + {"anim_angle_delta", 0x042}, + {"anim_deltas", 0x043}, + {"anim_pose", 0x044}, + {"anim_will_finish", 0x045}, + {"animation", 0x046}, + {"animscript", 0x047}, + {"archived", 0x048}, + {"archivetime", 0x049}, + {"armor", 0x04A}, + {"asleep", 0x04B}, + {"aspectratio", 0x04C}, + {"assaultstreaks", 0x04D}, + {"assignedbucket", 0x04E}, + {"assists", 0x04F}, + {"attachment", 0x050}, + {"attachmentclassrestricted", 0x051}, + {"attachmentrestricted", 0x052}, + {"attachments", 0x053}, + {"attachtag", 0x054}, + {"attacker", 0x055}, + {"attackeraccuracy", 0x056}, + {"attackercount", 0x057}, + {"attackerisjuggernaut", 0x058}, + {"attackerpos", 0x059}, + {"author", 0x05A}, + {"auto_ai", 0x05B}, + {"auto_change", 0x05C}, + {"auto_nonai", 0x05D}, + {"avoidanceboundshalfsize", 0x05E}, + {"awards", 0x05F}, + {"axis", 0x060}, + {"b", 0x061}, + {"back", 0x062}, + {"back_left", 0x063}, + {"back_low", 0x064}, + {"back_mid", 0x065}, + {"back_right", 0x066}, + {"back_up", 0x067}, + {"background", 0x068}, + {"bad_guys", 0x069}, + {"bad_path", 0x06A}, + {"badplaceawareness", 0x06B}, + {"ball_off", 0x06C}, + {"ball_on", 0x06D}, + {"ball_pass", 0x06E}, + {"bandwidthdown", 0x06F}, + {"bandwidthtestcount", 0x070}, + {"bandwidthup", 0x071}, + {"baselineoverflow_max", 0x072}, + {"baselineoverflow_worst", 0x073}, + {"battery_discharge_begin", 0x074}, + {"battery_discharge_end", 0x075}, + {"begin", 0x076}, + {"begin_custom_anim", 0x077}, + {"begin_firing", 0x078}, + {"begin_firing_left", 0x079}, + {"bestweapon", 0x07A}, + {"bestweaponindex", 0x07B}, + {"bipods", 0x07C}, + {"birthtime", 0x07D}, + {"bl_rotor1", 0x07E}, + {"bl_rotor2", 0x07F}, + {"bl_rotor3", 0x080}, + {"blackops2prestige", 0x081}, + {"blackops2rank", 0x082}, + {"blade_hide", 0x083}, + {"blade_show", 0x084}, + {"blockfriendlies", 0x085}, + {"blurradius", 0x086}, + {"body", 0x087}, + {"body_animate_jnt", 0x088}, + {"bottomarc", 0x089}, + {"br_rotor1", 0x08A}, + {"br_rotor2", 0x08B}, + {"br_rotor3", 0x08C}, + {"breadcrumbheader", 0x08D}, + {"buff", 0x08E}, + {"bullet_hitshield", 0x08F}, + {"bullethit", 0x090}, + {"bulletwhizby", 0x091}, + {"c", 0x092}, + {"callingcardindex", 0x093}, + {"camo", 0x094}, + {"cancel_location", 0x095}, + {"canclimbladders", 0x096}, + {"canjumppath", 0x097}, + {"cardicon", 0x098}, + {"cardnameplate", 0x099}, + {"cardtitle", 0x09A}, + {"cgmchecksum", 0x09B}, + {"ch_prestige", 0x09C}, + {"ch_prestige_max", 0x09D}, + {"chainfallback", 0x09E}, + {"chainnode", 0x09F}, + {"challengeprogress", 0x0A0}, + {"challengestate", 0x0A1}, + {"chest", 0x0A2}, + {"churnscores", 0x0A3}, + {"chyron_message1", 0x0A4}, + {"chyron_message2", 0x0A5}, + {"chyron_message3", 0x0A6}, + {"civilian", 0x0A7}, + {"clanidhigh", 0x0A8}, + {"clanidlow", 0x0A9}, + {"classname", 0x0AA}, + {"clipdistance", 0x0AB}, + {"code_classname", 0x0AC}, + {"code_damageradius", 0x0AD}, + {"code_move", 0x0AE}, + {"code_move_slide", 0x0AF}, + {"codecallback_agentadded", 0x0B0}, + {"codecallback_agentdamaged", 0x0B1}, + {"codecallback_agentkilled", 0x0B2}, + {"codecallback_bullethitentity", 0x0B3}, + {"codecallback_codeendgame", 0x0B4}, + {"codecallback_entitydamage", 0x0B5}, + {"codecallback_entityoutofworld", 0x0B6}, + {"codecallback_handleinstantmessage", 0x0B7}, + {"codecallback_hostmigration", 0x0B8}, + {"codecallback_leaderdialog", 0x0B9}, + {"codecallback_partymembers", 0x0BA}, + {"codecallback_playerconnect", 0x0BB}, + {"codecallback_playerdamage", 0x0BC}, + {"codecallback_playerdisconnect", 0x0BD}, + {"codecallback_playergrenadesuicide", 0x0BE}, + {"codecallback_playerkilled", 0x0BF}, + {"codecallback_playerlaststand", 0x0C0}, + {"codecallback_playermigrated", 0x0C1}, + {"codecallback_startgametype", 0x0C2}, + {"codecallback_vehicledamage", 0x0C3}, + {"color", 0x0C4}, + {"color_blind_toggled", 0x0C5}, + {"combat", 0x0C6}, + {"combatmode", 0x0C7}, + {"combatrecord", 0x0C8}, + {"commonoption", 0x0C9}, + {"confirm_location", 0x0CA}, + {"connection_id", 0x0CB}, + {"connectionidchunkhigh", 0x0CC}, + {"connectionidchunklow", 0x0CD}, + {"consolegame", 0x0CE}, + {"consoleidchunkhigh", 0x0CF}, + {"consoleidchunklow", 0x0D0}, + {"constrained", 0x0D1}, + {"contact", 0x0D2}, + {"contextleanenabled", 0x0D3}, + {"convergencetime", 0x0D4}, + {"coopactivesquadmember", 0x0D5}, + {"coopsquadmembers", 0x0D6}, + {"costumes", 0x0D7}, + {"count", 0x0D8}, + {"cover", 0x0D9}, + {"cover_approach", 0x0DA}, + {"coversearchinterval", 0x0DB}, + {"createstruct", 0x0DC}, + {"createtime", 0x0DD}, + {"criticalbulletdamagedist", 0x0DE}, + {"crouch", 0x0DF}, + {"currency", 0x0E0}, + {"current", 0x0E1}, + {"currentanimtime", 0x0E2}, + {"currentgen", 0x0E3}, + {"currentwinstreak", 0x0E4}, + {"cursorhint", 0x0E5}, + {"custom_attach_00", 0x0E6}, + {"custom_attach_01", 0x0E7}, + {"custom_attach_02", 0x0E8}, + {"custom_attach_03", 0x0E9}, + {"custom_attach_04", 0x0EA}, + {"custom_attach_05", 0x0EB}, + {"custom_attach_06", 0x0EC}, + {"custom_attach_07", 0x0ED}, + {"custom_attach_08", 0x0EE}, + {"custom_attach_09", 0x0EF}, + {"custom_attach_10", 0x0F0}, + {"custom_attach_11", 0x0F1}, + {"custom_attach_12", 0x0F2}, + {"custom_attach_13", 0x0F3}, + {"custom_attach_14", 0x0F4}, + {"custom_attach_15", 0x0F5}, + {"customclasses", 0x0F6}, + {"customization_loaded", 0x0F7}, + {"d", 0x0F8}, + {"dailychallengeid", 0x0F9}, + {"damage", 0x0FA}, + {"damage_notdone", 0x0FB}, + {"damagedir", 0x0FC}, + {"damagelocation", 0x0FD}, + {"damagemod", 0x0FE}, + {"damagemultiplier", 0x0FF}, + {"damageshield", 0x100}, + {"damagetaken", 0x101}, + {"damageweapon", 0x102}, + {"damageyaw", 0x103}, + {"dangerreactduration", 0x104}, + {"datalength", 0x105}, + {"dcid", 0x106}, + {"dead", 0x107}, + {"death", 0x108}, + {"deathangles", 0x109}, + {"deathinvulnerabletime", 0x10A}, + {"deathplant", 0x10B}, + {"deathpos", 0x10C}, + {"deaths", 0x10D}, + {"deathshield", 0x10E}, + {"defaultclasses", 0x10F}, + {"defense", 0x110}, + {"defense_level", 0x111}, + {"delayeddeath", 0x112}, + {"deploy_riotshield", 0x113}, + {"desc", 0x114}, + {"descmodified", 0x115}, + {"desiredangle", 0x116}, + {"destructible_type", 0x117}, + {"detectable", 0x118}, + {"detected", 0x119}, + {"detonate", 0x11A}, + {"device_id_high", 0x11B}, + {"device_id_low", 0x11C}, + {"deviceconnectionhistory", 0x11D}, + {"deviceusefrequency", 0x11E}, + {"diequietly", 0x11F}, + {"diffusefraction", 0x120}, + {"direct", 0x121}, + {"disable", 0x122}, + {"disableplayeradsloscheck", 0x123}, + {"dlight", 0x124}, + {"dmg", 0x125}, + {"dodamagetoall", 0x126}, + {"dodangerreact", 0x127}, + {"doffar", 0x128}, + {"dofnear", 0x129}, + {"dofphysicalfocusdistance", 0x12A}, + {"dofphysicalfstop", 0x12B}, + {"dog", 0x12C}, + {"doghandler", 0x12D}, + {"doingambush", 0x12E}, + {"done", 0x12F}, + {"dontavoidplayer", 0x130}, + {"dotofdeath", 0x131}, + {"down", 0x132}, + {"downaimlimit", 0x133}, + {"drawoncompass", 0x134}, + {"dropweapon", 0x135}, + {"duration", 0x136}, + {"eftarc", 0x137}, + {"empty", 0x138}, + {"empty_offhand", 0x139}, + {"enable", 0x13A}, + {"enablehudlighting", 0x13B}, + {"enableshadows", 0x13C}, + {"end_firing", 0x13D}, + {"end_firing_left", 0x13E}, + {"end_script", 0x13F}, + {"enddeaths", 0x140}, + {"endkills", 0x141}, + {"enemy", 0x142}, + {"enemy_sighted", 0x143}, + {"enemy_sighted_lost", 0x144}, + {"enemy_visible", 0x145}, + {"enemyname", 0x146}, + {"enemyplatform", 0x147}, + {"enemyradarmode", 0x148}, + {"enemyxuidhigh", 0x149}, + {"enemyxuidlow", 0x14A}, + {"energy_fire", 0x14B}, + {"engagemaxdist", 0x14C}, + {"engagemaxfalloffdist", 0x14D}, + {"engagemindist", 0x14E}, + {"engageminfalloffdist", 0x14F}, + {"enhanceable", 0x150}, + {"entity", 0x151}, + {"entitydeleted", 0x152}, + {"entityoverflow_max", 0x153}, + {"entityoverflow_worst", 0x154}, + {"equipment", 0x155}, + {"equipmentsetups", 0x156}, + {"escaped", 0x157}, + {"exclusive", 0x158}, + {"exo_ability_activate", 0x159}, + {"exo_adrenaline_fire", 0x15A}, + {"exo_boost", 0x15B}, + {"exo_dodge", 0x15C}, + {"exo_power", 0x15D}, + {"exo_slide", 0x15E}, + {"exo_slide_hit_player", 0x15F}, + {"exoattachment1", 0x160}, + {"exoattachment2", 0x161}, + {"experience", 0x162}, + {"explode", 0x163}, + {"exposedduration", 0x164}, + {"extracustomclassesentitlement", 0x165}, + {"extracustomclassesprestige", 0x166}, + {"extrascore0", 0x167}, + {"extrascore1", 0x168}, + {"face_angle", 0x169}, + {"face_angle_3d", 0x16A}, + {"face_angle_abs", 0x16B}, + {"face_angle_rel", 0x16C}, + {"face_current", 0x16D}, + {"face_default", 0x16E}, + {"face_direction", 0x16F}, + {"face_enemy", 0x170}, + {"face_enemy_or_motion", 0x171}, + {"face_goal", 0x172}, + {"face_motion", 0x173}, + {"face_point", 0x174}, + {"facemotion", 0x175}, + {"failed", 0x176}, + {"falling", 0x177}, + {"fast_radar", 0x178}, + {"favoriteenemy", 0x179}, + {"finalaccuracy", 0x17A}, + {"first_person", 0x17B}, + {"firstplayedsptime", 0x17C}, + {"fixednode", 0x17D}, + {"fixednodesaferadius", 0x17E}, + {"fl_rotor1", 0x17F}, + {"fl_rotor2", 0x180}, + {"fl_rotor3", 0x181}, + {"flash", 0x182}, + {"flashbang", 0x183}, + {"foley", 0x184}, + {"follow", 0x185}, + {"followmax", 0x186}, + {"followmin", 0x187}, + {"font", 0x188}, + {"fontscale", 0x189}, + {"foot_ik_active", 0x18A}, + {"foot_ik_blend_in", 0x18B}, + {"foot_ik_blend_out", 0x18C}, + {"foot_ik_inactive", 0x18D}, + {"footstepdetectdist", 0x18E}, + {"footstepdetectdistsprint", 0x18F}, + {"footstepdetectdistwalk", 0x190}, + {"force_off", 0x191}, + {"force_on", 0x192}, + {"force_fully_on", 0x193}, + {"forcepartyskillignore", 0x194}, + {"forceragdollimmediate", 0x195}, + {"forcespectatorclient", 0x196}, + {"foregrip_off", 0x197}, + {"foreground", 0x198}, + {"forward", 0x199}, + {"fov", 0x19A}, + {"fovcosine", 0x19B}, + {"fovcosinebusy", 0x19C}, + {"fovcosinez", 0x19D}, + {"fr_rotor1", 0x19E}, + {"fr_rotor2", 0x19F}, + {"fr_rotor3", 0x1A0}, + {"fraction", 0x1A1}, + {"frag", 0x1A2}, + {"free", 0x1A3}, + {"freecamera", 0x1A4}, + {"freelook", 0x1A5}, + {"frequency", 0x1A6}, + {"friendlyfire", 0x1A7}, + {"front_left", 0x1A8}, + {"front_right", 0x1A9}, + {"frontshieldanglecos", 0x1AA}, + {"fs_concrete", 0x1AB}, + {"fs_dirt", 0x1AC}, + {"fs_metal", 0x1AD}, + {"fs_wood", 0x1AE}, + {"game_extrainfo", 0x1AF}, + {"gamecount", 0x1B0}, + {"gamertag", 0x1B1}, + {"gamesplayed", 0x1B2}, + {"gametype", 0x1B3}, + {"gender", 0x1B4}, + {"ghostsprestige", 0x1B5}, + {"ghostsrank", 0x1B6}, + {"glass", 0x1B7}, + {"glass_damaged", 0x1B8}, + {"glass_destroyed", 0x1B9}, + {"globalcostume", 0x1BA}, + {"gloves", 0x1BB}, + {"glowalpha", 0x1BC}, + {"glowcolor", 0x1BD}, + {"goal", 0x1BE}, + {"goal_changed", 0x1BF}, + {"goal_reached", 0x1C0}, + {"goal_yaw", 0x1C1}, + {"goalheight", 0x1C2}, + {"goalpos", 0x1C3}, + {"goalradius", 0x1C4}, + {"goaltime", 0x1C5}, + {"goalweight", 0x1C6}, + {"goingtoruntopos", 0x1C7}, + {"gravity", 0x1C8}, + {"gravity_noclip", 0x1C9}, + {"grenade", 0x1CA}, + {"grenade_fire", 0x1CB}, + {"grenade_off", 0x1CC}, + {"grenade_on", 0x1CD}, + {"grenade_pullback", 0x1CE}, + {"grenade_return_hand_tag", 0x1CF}, + {"grenadeammo", 0x1D0}, + {"grenadeawareness", 0x1D1}, + {"grenadedanger", 0x1D2}, + {"grenadeweapon", 0x1D3}, + {"ground_slam", 0x1D4}, + {"ground_slam_hit_player", 0x1D5}, + {"groundentchanged", 0x1D6}, + {"groundtype", 0x1D7}, + {"gunblockedbywall", 0x1D8}, + {"gunshot", 0x1D9}, + {"gunshot_teammate", 0x1DA}, + {"hardcoremodeon", 0x1DB}, + {"hasdoublexpitem", 0x1DC}, + {"hasradar", 0x1DD}, + {"hasvalidcostumeselfieimage", 0x1DE}, + {"head", 0x1DF}, + {"headicon", 0x1E0}, + {"headiconteam", 0x1E1}, + {"headshots", 0x1E2}, + {"health", 0x1E3}, + {"healthregen", 0x1E4}, + {"height", 0x1E5}, + {"helmet", 0x1E6}, + {"hidein3rdperson", 0x1E7}, + {"hidewhendead", 0x1E8}, + {"hidewhenindemo", 0x1E9}, + {"hidewheninmenu", 0x1EA}, + {"high_priority", 0x1EB}, + {"highlyawareradius", 0x1EC}, + {"hindlegstraceoffset", 0x1ED}, + {"hintstring", 0x1EE}, + {"hit_by_missile", 0x1EF}, + {"horzalign", 0x1F0}, + {"host_sucks_end_game", 0x1F1}, + {"hostfailures", 0x1F2}, + {"hostquits", 0x1F3}, + {"hostsuccesses", 0x1F4}, + {"human", 0x1F5}, + {"iconnew", 0x1F6}, + {"iconunlocked", 0x1F7}, + {"ignoreall", 0x1F8}, + {"ignoreclosefoliage", 0x1F9}, + {"ignoreexplosionevents", 0x1FA}, + {"ignoreforfixednodesafecheck", 0x1FB}, + {"ignoreme", 0x1FC}, + {"ignorerandombulletdamage", 0x1FD}, + {"ignoresuppression", 0x1FE}, + {"ignoretriggers", 0x1FF}, + {"ikweight", 0x200}, + {"index", 0x201}, + {"infinite_energy", 0x202}, + {"info_notnull", 0x203}, + {"info_player_start", 0x204}, + {"init", 0x205}, + {"initstructs", 0x206}, + {"insolid", 0x207}, + {"intermission", 0x208}, + {"interval", 0x209}, + {"inuse", 0x20A}, + {"invalid_parent", 0x20B}, + {"invisible", 0x20C}, + {"isradarblocked", 0x20D}, + {"item", 0x20E}, + {"j_exo_rcket_arm02", 0x20F}, + {"j_exoclav04_l", 0x210}, + {"j_exoclav04_r", 0x211}, + {"j_exohip04_l", 0x212}, + {"j_exohip04_r", 0x213}, + {"j_eyeball_le", 0x214}, + {"j_eyeball_ri", 0x215}, + {"j_gun", 0x216}, + {"j_head", 0x217}, + {"j_hip_l", 0x218}, + {"j_hip_r", 0x219}, + {"j_knee_le", 0x21A}, + {"j_knee_ri", 0x21B}, + {"j_left_elbow", 0x21C}, + {"j_left_hand", 0x21D}, + {"j_left_shoulder", 0x21E}, + {"j_mainroot", 0x21F}, + {"j_neck", 0x220}, + {"j_right_elbow", 0x221}, + {"j_right_hand", 0x222}, + {"j_right_hand_placement", 0x223}, + {"j_right_shoulder", 0x224}, + {"j_rocket", 0x225}, + {"j_spine4", 0x226}, + {"j_spinelower", 0x227}, + {"j_spineupper", 0x228}, + {"jumpcost", 0x229}, + {"jumping", 0x22A}, + {"justclass", 0x22B}, + {"kdratio", 0x22C}, + {"keepclaimednode", 0x22D}, + {"keepclaimednodeifvalid", 0x22E}, + {"keepnodeduringscriptedanim", 0x22F}, + {"key1", 0x230}, + {"key2", 0x231}, + {"kill_timestamp", 0x232}, + {"killanimscript", 0x233}, + {"killcamentity", 0x234}, + {"killcamentitylookat", 0x235}, + {"kills", 0x236}, + {"killstreak", 0x237}, + {"killstreakcount", 0x238}, + {"killstreakrestricted", 0x239}, + {"killstreakunlocked", 0x23A}, + {"knife_off", 0x23B}, + {"knife_on", 0x23C}, + {"known_event", 0x23D}, + {"label", 0x23E}, + {"ladder_down", 0x23F}, + {"ladder_up", 0x240}, + {"land", 0x241}, + {"last_stand_count", 0x242}, + {"lastattacker", 0x243}, + {"lastenemysightpos", 0x244}, + {"lastplayedtime", 0x245}, + {"laststand", 0x246}, + {"leanamount", 0x247}, + {"ledge", 0x248}, + {"left", 0x249}, + {"leftaimlimit", 0x24A}, + {"leftarc", 0x24B}, + {"lethal", 0x24C}, + {"lifecount", 0x24D}, + {"light", 0x24E}, + {"lives", 0x24F}, + {"loadouts", 0x250}, + {"lockorientation", 0x251}, + {"lod", 0x252}, + {"look", 0x253}, + {"lookahead", 0x254}, + {"lookaheaddir", 0x255}, + {"lookaheaddist", 0x256}, + {"lookaheadhitsstairs", 0x257}, + {"lookforward", 0x258}, + {"lookright", 0x259}, + {"looktarget", 0x25A}, + {"lookup", 0x25B}, + {"loot", 0x25C}, + {"lootnew", 0x25D}, + {"loses", 0x25E}, + {"low_priority", 0x25F}, + {"lowresbackground", 0x260}, + {"luinotifyserver", 0x261}, + {"mag_eject", 0x262}, + {"mag_eject_left", 0x263}, + {"main", 0x264}, + {"manual", 0x265}, + {"manual_ai", 0x266}, + {"manual_change", 0x267}, + {"map", 0x268}, + {"matchid", 0x269}, + {"matchmakingsettingsversion", 0x26A}, + {"matchmakingtesttype", 0x26B}, + {"max_time", 0x26C}, + {"maxfaceenemydist", 0x26D}, + {"maxhealth", 0x26E}, + {"maxrange", 0x26F}, + {"maxsightdistsqrd", 0x270}, + {"maxturnspeed", 0x271}, + {"maxvisibledist", 0x272}, + {"melee_fired", 0x273}, + {"melee_hit_react", 0x274}, + {"meleeattackdist", 0x275}, + {"menuresponse", 0x276}, + {"micro_dlc_bits_last_gen", 0x277}, + {"micro_dlc_bits_next_gen", 0x278}, + {"middle_left", 0x279}, + {"middle_right", 0x27A}, + {"migrateablequits", 0x27B}, + {"min_energy", 0x27C}, + {"min_time", 0x27D}, + {"minpaindamage", 0x27E}, + {"minusedistsq", 0x27F}, + {"missile_fire", 0x280}, + {"missile_passed_target", 0x281}, + {"missile_stuck", 0x282}, + {"mlgversion", 0x283}, + {"mod", 0x284}, + {"mod_crush", 0x285}, + {"mod_energy", 0x286}, + {"mod_explosive", 0x287}, + {"mod_explosive_bullet", 0x288}, + {"mod_falling", 0x289}, + {"mod_grenade", 0x28A}, + {"mod_grenade_splash", 0x28B}, + {"mod_head_shot", 0x28C}, + {"mod_impact", 0x28D}, + {"mod_melee", 0x28E}, + {"mod_melee_alien", 0x28F}, + {"mod_melee_alt", 0x290}, + {"mod_melee_dog", 0x291}, + {"mod_pistol_bullet", 0x292}, + {"mod_projectile", 0x293}, + {"mod_projectile_splash", 0x294}, + {"mod_rifle_bullet", 0x295}, + {"mod_suicide", 0x296}, + {"mod_trigger_hurt", 0x297}, + {"mod_unknown", 0x298}, + {"model", 0x299}, + {"modeprefix", 0x29A}, + {"modifiers", 0x29B}, + {"motiontrackerenabled", 0x29C}, + {"mounted_dlc_bits", 0x29D}, + {"movedone", 0x29E}, + {"movemode", 0x29F}, + {"munition", 0x2A0}, + {"munition_level", 0x2A1}, + {"mw3prestige", 0x2A2}, + {"mw3rank", 0x2A3}, + {"name", 0x2A4}, + {"namemodified", 0x2A5}, + {"near_goal", 0x2A6}, + {"nearz", 0x2A7}, + {"neutral", 0x2A8}, + {"never", 0x2A9}, + {"newenemyreactiondistsq", 0x2AA}, + {"newentitlement", 0x2AB}, + {"nextgen", 0x2AC}, + {"nextreadblackops2", 0x2AD}, + {"nextreadghosts0", 0x2AE}, + {"nextreadghosts1", 0x2AF}, + {"nextreadmw3", 0x2B0}, + {"night_vision_off", 0x2B1}, + {"night_vision_on", 0x2B2}, + {"no_bot_random_path", 0x2B3}, + {"no_cover", 0x2B4}, + {"no_gravity", 0x2B5}, + {"noattackeraccuracymod", 0x2B6}, + {"noclip", 0x2B7}, + {"node", 0x2B8}, + {"node_not_safe", 0x2B9}, + {"node_out_of_range", 0x2BA}, + {"node_relinquished", 0x2BB}, + {"node_taken", 0x2BC}, + {"nodeoffsetpos", 0x2BD}, + {"nododgemove", 0x2BE}, + {"nogravity", 0x2BF}, + {"nogrenadereturnthrow", 0x2C0}, + {"noncombat", 0x2C1}, + {"none", 0x2C2}, + {"nonmigrateablequits", 0x2C3}, + {"nophysics", 0x2C4}, + {"normal", 0x2C5}, + {"normal_radar", 0x2C6}, + {"northyaw", 0x2C7}, + {"notifyname", 0x2C8}, + {"notinsolid", 0x2C9}, + {"num0", 0x2CA}, + {"num1", 0x2CB}, + {"num2", 0x2CC}, + {"num3", 0x2CD}, + {"num4", 0x2CE}, + {"objective", 0x2CF}, + {"obstacle", 0x2D0}, + {"offense", 0x2D1}, + {"offense_level", 0x2D2}, + {"offhand", 0x2D3}, + {"offhand_end", 0x2D4}, + {"offhandweapon", 0x2D5}, + {"oldtime", 0x2D6}, + {"ondeactivate", 0x2D7}, + {"onenterstate", 0x2D8}, + {"only_sky", 0x2D9}, + {"onlygoodnearestnodes", 0x2DA}, + {"onwifi", 0x2DB}, + {"operationsdeadline", 0x2DC}, + {"oriented", 0x2DD}, + {"orientto_complete", 0x2DE}, + {"origin", 0x2DF}, + {"other", 0x2E0}, + {"over", 0x2E1}, + {"owner", 0x2E2}, + {"pacifist", 0x2E3}, + {"pacifistwait", 0x2E4}, + {"pain", 0x2E5}, + {"pantssize", 0x2E6}, + {"parentindex", 0x2E7}, + {"parentname", 0x2E8}, + {"partyid", 0x2E9}, + {"pasttitledata", 0x2EA}, + {"patch", 0x2EB}, + {"patchbacking", 0x2EC}, + {"path_blocked", 0x2ED}, + {"path_changed", 0x2EE}, + {"path_dir_change", 0x2EF}, + {"path_enemy", 0x2F0}, + {"path_need_dodge", 0x2F1}, + {"path_set", 0x2F2}, + {"pathenemyfightdist", 0x2F3}, + {"pathenemylookahead", 0x2F4}, + {"pathgoalpos", 0x2F5}, + {"pathlookaheaddist", 0x2F6}, + {"pathrandompercent", 0x2F7}, + {"pc", 0x2F8}, + {"pccg", 0x2F9}, + {"pelvis", 0x2FA}, + {"perk1", 0x2FB}, + {"perk2", 0x2FC}, + {"perk3", 0x2FD}, + {"perk4", 0x2FE}, + {"perk5", 0x2FF}, + {"perk6", 0x300}, + {"perkclassrestricted", 0x301}, + {"perkrestricted", 0x302}, + {"perks", 0x303}, + {"perkslots", 0x304}, + {"pers", 0x305}, + {"persistentperksunlocked", 0x306}, + {"persistentweaponsunlocked", 0x307}, + {"phone_off", 0x308}, + {"phone_on", 0x309}, + {"physics_finished", 0x30A}, + {"physics_impact", 0x30B}, + {"pickup", 0x30C}, + {"pickup_riotshield", 0x30D}, + {"pistol", 0x30E}, + {"pitchamount", 0x30F}, + {"pitchconvergencetime", 0x310}, + {"plane_waypoint", 0x311}, + {"playedblackops2", 0x312}, + {"playedghosts", 0x313}, + {"playedmw3", 0x314}, + {"player", 0x315}, + {"player_controller", 0x316}, + {"player_pushed", 0x317}, + {"playercardbackground", 0x318}, + {"playercardpatch", 0x319}, + {"playercardpatchbacking", 0x31A}, + {"playerconnectionhistory", 0x31B}, + {"playerid", 0x31C}, + {"playerip", 0x31D}, + {"playername", 0x31E}, + {"playerpositions", 0x31F}, + {"players", 0x320}, + {"playerSpread", 0x321}, + {"playerxuidhigh", 0x322}, + {"playerxuidlow", 0x323}, + {"playing", 0x324}, + {"points", 0x325}, + {"position", 0x326}, + {"positioninworld", 0x327}, + {"postsharpturnlookaheaddist", 0x328}, + {"precache", 0x329}, + {"predicted_projectile_impact", 0x32A}, + {"prestige", 0x32B}, + {"prestigedoublexp", 0x32C}, + {"prestigedoublexpmaxtimeplayed", 0x32D}, + {"prestigeshoptokens", 0x32E}, + {"prestigeshoptokensentitlement", 0x32F}, + {"prevanimdelta", 0x330}, + {"prevnode", 0x331}, + {"prevscript", 0x332}, + {"primary", 0x333}, + {"primaryattachment1", 0x334}, + {"primaryattachment2", 0x335}, + {"primaryattachment3", 0x336}, + {"primaryattachments", 0x337}, + {"primaryattachkit", 0x338}, + {"primarycamo", 0x339}, + {"primaryfurniturekit", 0x33A}, + {"primaryoffhand", 0x33B}, + {"primaryreticle", 0x33C}, + {"primaryweapon", 0x33D}, + {"privatematchactivesquadmember", 0x33E}, + {"privatematchcustomclasses", 0x33F}, + {"privatematchsquadmembers", 0x340}, + {"projectile_impact", 0x341}, + {"projectile_impact_player", 0x342}, + {"prone", 0x343}, + {"proneok", 0x344}, + {"providecoveringfire", 0x345}, + {"ps3", 0x346}, + {"ps4", 0x347}, + {"psoffsettime", 0x348}, + {"pushable", 0x349}, + {"radaralwayson", 0x34A}, + {"radarmode", 0x34B}, + {"radarshowenemydirection", 0x34C}, + {"radarstrength", 0x34D}, + {"radius", 0x34E}, + {"ragdoll_early_result", 0x34F}, + {"raise_riotshield", 0x350}, + {"rank", 0x351}, + {"rate", 0x352}, + {"reached_end_node", 0x353}, + {"reached_wait_node", 0x354}, + {"reached_wait_speed", 0x355}, + {"reactiontargetpos", 0x356}, + {"realtimedelta", 0x357}, + {"receiver", 0x358}, + {"recipename", 0x359}, + {"reciprocality", 0x35A}, + {"reflection_clear_color", 0x35B}, + {"reinforcement", 0x35C}, + {"relativedir", 0x35D}, + {"relativeoffset", 0x35E}, + {"reload", 0x35F}, + {"reload_start", 0x360}, + {"remotemissilespawn", 0x361}, + {"rendertotexture", 0x362}, + {"reportindex", 0x363}, + {"reports", 0x364}, + {"reputation", 0x365}, + {"requestarrivalnotify", 0x366}, + {"requirement_beat100waves", 0x367}, + {"requirement_beat200waves", 0x368}, + {"requirement_beat50waves", 0x369}, + {"requirement_beatenzombies", 0x36A}, + {"requirement_maxarmorproficiency", 0x36B}, + {"requirement_maxweaponproficiency", 0x36C}, + {"requirement_playedallmaps", 0x36D}, + {"requirement_unlockedprison", 0x36E}, + {"requirement_unlockedtier2", 0x36F}, + {"requirement_unlockedtier3", 0x370}, + {"reserved", 0x371}, + {"respawndelay", 0x372}, + {"result", 0x373}, + {"reticle", 0x374}, + {"return_pitch", 0x375}, + {"reverse", 0x376}, + {"revives", 0x377}, + {"right", 0x378}, + {"rightaimlimit", 0x379}, + {"rightarc", 0x37A}, + {"riotshield_damaged", 0x37B}, + {"riotshield_hit", 0x37C}, + {"rocket", 0x37D}, + {"rocket_off", 0x37E}, + {"rocket_on", 0x37F}, + {"rotatedone", 0x380}, + {"rotation", 0x381}, + {"run", 0x382}, + {"runcost", 0x383}, + {"runto_arrived", 0x384}, + {"safetochangescript", 0x385}, + {"scavenger", 0x386}, + {"scope_cap", 0x387}, + {"scope_center", 0x388}, + {"scope_top", 0x389}, + {"score", 0x38A}, + {"script", 0x38B}, + {"script_brushmodel", 0x38C}, + {"script_clut", 0x38D}, + {"script_context", 0x38E}, + {"script_delay", 0x38F}, + {"script_goal_changed", 0x390}, + {"script_label", 0x391}, + {"script_lightset", 0x392}, + {"script_linkname", 0x393}, + {"script_model", 0x394}, + {"script_noteworthy", 0x395}, + {"script_origin", 0x396}, + {"script_parent", 0x397}, + {"script_parentname", 0x398}, + {"script_pushable", 0x399}, + {"script_vehicle", 0x39A}, + {"script_vehicle_collision", 0x39B}, + {"script_vehicle_collmap", 0x39C}, + {"script_vehicle_corpse", 0x39D}, + {"script_visionset", 0x39E}, + {"script_water", 0x39F}, + {"script_reverb", 0x3A0}, + {"script_zone", 0x3A1}, + {"scriptable", 0x3A2}, + {"scriptableactor", 0x3A3}, + {"scripted_viewmodel_anim", 0x3A4}, + {"scriptedarrivalent", 0x3A5}, + {"search_end", 0x3A6}, + {"secondary", 0x3A7}, + {"secondaryattachment1", 0x3A8}, + {"secondaryattachment2", 0x3A9}, + {"secondaryattachments", 0x3AA}, + {"secondaryattachkit", 0x3AB}, + {"secondarycamo", 0x3AC}, + {"secondaryfurniturekit", 0x3AD}, + {"secondaryoffhand", 0x3AE}, + {"secondaryreticle", 0x3AF}, + {"secondaryweapon", 0x3B0}, + {"sentry", 0x3B1}, + {"sentry_manual", 0x3B2}, + {"sentry_offline", 0x3B3}, + {"servertimecount", 0x3B4}, + {"servertimeexceedcount", 0x3B5}, + {"servertimemax", 0x3B6}, + {"servertimetotal", 0x3B7}, + {"servertimetotalexceed", 0x3B8}, + {"sessionstate", 0x3B9}, + {"sessionteam", 0x3BA}, + {"sharpturn", 0x3BB}, + {"sharpturnlookaheaddist", 0x3BC}, + {"sharpturnnotifydist", 0x3BD}, + {"sharpturntooclosetodestdist", 0x3BE}, + {"shirt", 0x3BF}, + {"showinkillcam", 0x3C0}, + {"showkillcam", 0x3C1}, + {"sightlatency", 0x3C2}, + {"silenced_shot", 0x3C3}, + {"skill_points", 0x3C4}, + {"skillbucket", 0x3C5}, + {"skillrating", 0x3C6}, + {"skillratingtype", 0x3C7}, + {"slidevelocity", 0x3C8}, + {"slowmo_active", 0x3C9}, + {"slowmo_passive", 0x3CA}, + {"smoke", 0x3CB}, + {"snd_channelvolprio_holdbreath", 0x3CC}, + {"snd_channelvolprio_pain", 0x3CD}, + {"snd_channelvolprio_shellshock", 0x3CE}, + {"snd_enveffectsprio_level", 0x3CF}, + {"snd_enveffectsprio_shellshock", 0x3D0}, + {"sort", 0x3D1}, + {"sound_blend", 0x3D2}, + {"soundeventdone", 0x3D3}, + {"space", 0x3D4}, + {"spawned", 0x3D5}, + {"spawner", 0x3D6}, + {"spawnflags", 0x3D7}, + {"spawnpos", 0x3D8}, + {"spawntime", 0x3D9}, + {"specialgrenade", 0x3DA}, + {"spectatekillcam", 0x3DB}, + {"spectating_cycle", 0x3DC}, + {"spectator", 0x3DD}, + {"speechcommand", 0x3DE}, + {"speed", 0x3DF}, + {"splatter", 0x3E0}, + {"splineplanereachednode", 0x3E1}, + {"sprint_begin", 0x3E2}, + {"sprint_end", 0x3E3}, + {"sprint_slide_begin", 0x3E4}, + {"sprint_slide_end", 0x3E5}, + {"squad_base", 0x3E6}, + {"squad_mode", 0x3E7}, + {"squad_name", 0x3E8}, + {"squadhq", 0x3E9}, + {"squadmembers", 0x3EA}, + {"squadmemxp", 0x3EB}, + {"squadname", 0x3EC}, + {"stairs", 0x3ED}, + {"stairsstate", 0x3EE}, + {"stand", 0x3EF}, + {"start_blend", 0x3F0}, + {"start_move", 0x3F1}, + {"start_ragdoll", 0x3F2}, + {"startdeaths", 0x3F3}, + {"startdeploy_riotshield", 0x3F4}, + {"startingoffsetforlife", 0x3F5}, + {"startkills", 0x3F6}, + {"state_changed", 0x3F7}, + {"statelocked", 0x3F8}, + {"stencil_disable", 0x3F9}, + {"stencil_onesided", 0x3FA}, + {"stencil_twosided", 0x3FB}, + {"stencilfunc_always", 0x3FC}, + {"stencilfunc_equal", 0x3FD}, + {"stencilfunc_greater", 0x3FE}, + {"stencilfunc_greaterequal", 0x3FF}, + {"stencilfunc_less", 0x400}, + {"stencilfunc_lessequal", 0x401}, + {"stencilfunc_never", 0x402}, + {"stencilfunc_notequal", 0x403}, + {"stencilop_decr", 0x404}, + {"stencilop_decrsat", 0x405}, + {"stencilop_incr", 0x406}, + {"stencilop_incrsat", 0x407}, + {"stencilop_invert", 0x408}, + {"stencilop_keep", 0x409}, + {"stencilop_replace", 0x40A}, + {"stencilop_zero", 0x40B}, + {"stop", 0x40C}, + {"stop_soon", 0x40D}, + {"stopanimdistsq", 0x40E}, + {"stopsoonnotifydist", 0x40F}, + {"streak", 0x410}, + {"streaktype", 0x411}, + {"suckedashost", 0x412}, + {"suncolor", 0x413}, + {"sundirection", 0x414}, + {"sunlight", 0x415}, + {"support", 0x416}, + {"support_level", 0x417}, + {"suppression", 0x418}, + {"suppression_end", 0x419}, + {"suppressionduration", 0x41A}, + {"suppressionmeter", 0x41B}, + {"suppressionstarttime", 0x41C}, + {"suppressionTime", 0x41D}, + {"suppressionwait", 0x41E}, + {"surfacetype", 0x41F}, + {"surprisedbymedistsq", 0x420}, + {"swimmer", 0x421}, + {"switched_var_grenade", 0x422}, + {"syncedmeleetarget", 0x423}, + {"tactical", 0x424}, + {"tag", 0x425}, + {"tag_ai_aim_target", 0x426}, + {"tag_aim", 0x427}, + {"tag_aim_animated", 0x428}, + {"tag_aim_pivot", 0x429}, + {"tag_barrel", 0x42A}, + {"tag_blade_off", 0x42B}, + {"tag_body", 0x42C}, + {"tag_brass", 0x42D}, + {"tag_brass_2", 0x42E}, + {"tag_butt", 0x42F}, + {"tag_camera", 0x430}, + {"tag_clip", 0x431}, + {"tag_clip_dual", 0x432}, + {"tag_clip_dual2", 0x433}, + {"tag_detach", 0x434}, + {"tag_engine_left", 0x435}, + {"tag_engine_right", 0x436}, + {"tag_eotech_reticle", 0x437}, + {"tag_eye", 0x438}, + {"tag_flash", 0x439}, + {"tag_flash_11", 0x43A}, + {"tag_flash_2", 0x43B}, + {"tag_flash_22", 0x43C}, + {"tag_flash_3", 0x43D}, + {"tag_flash_launcher", 0x43E}, + {"tag_flash_silenced", 0x43F}, + {"tag_fx", 0x440}, + {"tag_gasmask", 0x441}, + {"tag_gasmask2", 0x442}, + {"tag_ik_ankle_fl", 0x443}, + {"tag_ik_ankle_fr", 0x444}, + {"tag_ik_ankle_kl", 0x445}, + {"tag_ik_ankle_kr", 0x446}, + {"tag_ik_ankle_ml", 0x447}, + {"tag_ik_ankle_mr", 0x448}, + {"tag_ik_footflat_fl", 0x449}, + {"tag_ik_footflat_fr", 0x44A}, + {"tag_ik_footflat_kl", 0x44B}, + {"tag_ik_footflat_kr", 0x44C}, + {"tag_ik_footflat_ml", 0x44D}, + {"tag_ik_footflat_mr", 0x44E}, + {"tag_ik_hip_fl", 0x44F}, + {"tag_ik_hip_fr", 0x450}, + {"tag_ik_hip_kl", 0x451}, + {"tag_ik_hip_kr", 0x452}, + {"tag_ik_hip_ml", 0x453}, + {"tag_ik_hip_mr", 0x454}, + {"tag_ik_knee_fl", 0x455}, + {"tag_ik_knee_fr", 0x456}, + {"tag_ik_knee_kl", 0x457}, + {"tag_ik_knee_kr", 0x458}, + {"tag_ik_knee_ml", 0x459}, + {"tag_ik_knee_mr", 0x45A}, + {"tag_ik_loc_le", 0x45B}, + {"tag_ik_loc_le_foregrip", 0x45C}, + {"tag_ik_loc_le_launcher", 0x45D}, + {"tag_ik_loc_le_shotgun", 0x45E}, + {"tag_ik_target", 0x45F}, + {"tag_inhand", 0x460}, + {"tag_jetblast_fx", 0x461}, + {"tag_jetpack", 0x462}, + {"tag_knife_attach", 0x463}, + {"tag_knife_fx", 0x464}, + {"tag_laser", 0x465}, + {"tag_launcher", 0x466}, + {"tag_magnifier_eotech_reticle", 0x467}, + {"tag_mobile_cover_upright", 0x468}, + {"tag_motion_tracker_bl", 0x469}, + {"tag_motion_tracker_br", 0x46A}, + {"tag_motion_tracker_fx", 0x46B}, + {"tag_motion_tracker_tl", 0x46C}, + {"tag_origin", 0x46D}, + {"tag_player", 0x46E}, + {"tag_popout", 0x46F}, + {"tag_rail_master_off", 0x470}, + {"tag_rail_master_on", 0x471}, + {"tag_rail_side_off", 0x472}, + {"tag_rail_side_on", 0x473}, + {"tag_reticle_acog", 0x474}, + {"tag_reticle_default", 0x475}, + {"tag_reticle_default2", 0x476}, + {"tag_reticle_hamr", 0x477}, + {"tag_reticle_on", 0x478}, + {"tag_reticle_red_dot", 0x479}, + {"tag_reticle_reflex", 0x47A}, + {"tag_reticle_tavor_scope", 0x47B}, + {"tag_reticle_thermal_scope", 0x47C}, + {"tag_rider", 0x47D}, + {"tag_riot_shield", 0x47E}, + {"tag_rocket", 0x47F}, + {"tag_scope_ads_off", 0x480}, + {"tag_scope_ads_on", 0x481}, + {"tag_shield_back", 0x482}, + {"tag_shotgun", 0x483}, + {"tag_show_alt", 0x484}, + {"tag_sight_off", 0x485}, + {"tag_sight_on", 0x486}, + {"tag_stow_back_mid_attach", 0x487}, + {"tag_stowed_back", 0x488}, + {"tag_stowed_hip_rear", 0x489}, + {"tag_sync", 0x48A}, + {"tag_tip", 0x48B}, + {"tag_turret", 0x48C}, + {"tag_turret_base", 0x48D}, + {"tag_turret_pitch", 0x48E}, + {"tag_turret_yaw", 0x48F}, + {"tag_weapon", 0x490}, + {"tag_weapon_chest", 0x491}, + {"tag_weapon_left", 0x492}, + {"tag_weapon_right", 0x493}, + {"tag_wheel_back_left", 0x494}, + {"tag_wheel_back_right", 0x495}, + {"tag_wheel_front_left", 0x496}, + {"tag_wheel_front_right", 0x497}, + {"tag_wheel_middle_left", 0x498}, + {"tag_wheel_middle_right", 0x499}, + {"tag_wheel_spin_left01", 0x49A}, + {"tag_wheel_spin_left02", 0x49B}, + {"tag_wheel_spin_left03", 0x49C}, + {"tag_wheel_spin_right01", 0x49D}, + {"tag_wheel_spin_right02", 0x49E}, + {"tag_wheel_spin_right03", 0x49F}, + {"takedamage", 0x4A0}, + {"target", 0x4A1}, + {"target_script_trigger", 0x4A2}, + {"targetname", 0x4A3}, + {"team", 0x4A4}, + {"team3", 0x4A5}, + {"teambalanced", 0x4A6}, + {"teammode_axisallies", 0x4A7}, + {"teammode_ffa", 0x4A8}, + {"teammovewaittime", 0x4A9}, + {"their_score", 0x4AA}, + {"thermal", 0x4AB}, + {"thermalbodymaterial", 0x4AC}, + {"third_person", 0x4AD}, + {"threatbias", 0x4AE}, + {"threatbiasgroup", 0x4AF}, + {"threatsightdelayenabled", 0x4B0}, + {"threatsightdelayfalloff", 0x4B1}, + {"threshold", 0x4B2}, + {"throwingknife", 0x4B3}, + {"time", 0x4B4}, + {"timeplayedtotal", 0x4B5}, + {"titlenew", 0x4B6}, + {"titleunlocked", 0x4B7}, + {"top", 0x4B8}, + {"toparc", 0x4B9}, + {"totalxp", 0x4BA}, + {"touch", 0x4BB}, + {"touching_platform", 0x4BC}, + {"traverse_complete", 0x4BD}, + {"traverse_soon", 0x4BE}, + {"traversecost", 0x4BF}, + {"traversesoonnotifydist", 0x4C0}, + {"trend", 0x4C1}, + {"trigger", 0x4C2}, + {"trigger_damage", 0x4C3}, + {"trigger_use", 0x4C4}, + {"trigger_use_touch", 0x4C5}, + {"truck_cam", 0x4C6}, + {"turnrate", 0x4C7}, + {"turret_deactivate", 0x4C8}, + {"turret_fire", 0x4C9}, + {"turret_no_vis", 0x4CA}, + {"turret_not_on_target", 0x4CB}, + {"turret_on_target", 0x4CC}, + {"turret_on_vistarget", 0x4CD}, + {"turret_pitch_clamped", 0x4CE}, + {"turret_rotate_stopped", 0x4CF}, + {"turret_yaw_clamped", 0x4D0}, + {"turretinvulnerability", 0x4D1}, + {"turretownerchange", 0x4D2}, + {"turretstatechange", 0x4D3}, + {"type", 0x4D4}, + {"ucdidhigh", 0x4D5}, + {"ucdidlow", 0x4D6}, + {"unlockedcamo", 0x4D7}, + {"unlockedreticles", 0x4D8}, + {"unlockpoints", 0x4D9}, + {"unresolved_collision", 0x4DA}, + {"up", 0x4DB}, + {"upaimlimit", 0x4DC}, + {"upgradechallengeprogress", 0x4DD}, + {"upgradechallengestage", 0x4DE}, + {"upgradepoints", 0x4DF}, + {"upgradepurchased", 0x4E0}, + {"useable", 0x4E1}, + {"usechokepoints", 0x4E2}, + {"usecombatscriptatcover", 0x4E3}, + {"usedemblemslots", 0x4E4}, + {"useorcaavoidance", 0x4E5}, + {"usepathsmoothingvalues", 0x4E6}, + {"veh_boatbounce", 0x4E7}, + {"veh_boost_activated", 0x4E8}, + {"veh_boost_deactivated", 0x4E9}, + {"veh_brake", 0x4EA}, + {"veh_collision", 0x4EB}, + {"veh_contact", 0x4EC}, + {"veh_jolt", 0x4ED}, + {"veh_landed", 0x4EE}, + {"veh_leftground", 0x4EF}, + {"veh_pathdir", 0x4F0}, + {"veh_pathspeed", 0x4F1}, + {"veh_pathtype", 0x4F2}, + {"veh_predictedcollision", 0x4F3}, + {"veh_speed", 0x4F4}, + {"veh_throttle", 0x4F5}, + {"veh_topspeed", 0x4F6}, + {"veh_transmission", 0x4F7}, + {"vehicle_dismount", 0x4F8}, + {"vehicle_mount", 0x4F9}, + {"vehicletype", 0x4FA}, + {"velocity", 0x4FB}, + {"vertalign", 0x4FC}, + {"visionsetmissilecam", 0x4FD}, + {"visionsetmissilecamduration", 0x4FE}, + {"visionsetnaked", 0x4FF}, + {"visionsetnakedduration", 0x500}, + {"visionsetnight", 0x501}, + {"visionsetnightduration", 0x502}, + {"visionsetpain", 0x503}, + {"visionsetpainduration", 0x504}, + {"visionsetthermal", 0x505}, + {"visionsetthermalduration", 0x506}, + {"vote", 0x507}, + {"wait", 0x508}, + {"walk", 0x509}, + {"walkdist", 0x50A}, + {"walkdistfacingmotion", 0x50B}, + {"wastacticalinsertion", 0x50C}, + {"waypoint_reached", 0x50D}, + {"weapon", 0x50E}, + {"weapon_change", 0x50F}, + {"weapon_dropped", 0x510}, + {"weapon_fired", 0x511}, + {"weapon_model_change", 0x512}, + {"weapon_switch_invalid", 0x513}, + {"weapon_switch_started", 0x514}, + {"weapon_taken", 0x515}, + {"weaponchange", 0x516}, + {"weaponclassrestricted", 0x517}, + {"weaponinfo", 0x518}, + {"weaponrank", 0x519}, + {"weaponrestricted", 0x51A}, + {"weaponsetups", 0x51B}, + {"weaponstats", 0x51C}, + {"weeklychallengeid", 0x51D}, + {"weight", 0x51E}, + {"width", 0x51F}, + {"wildcard1", 0x520}, + {"wildcard2", 0x521}, + {"wildcard3", 0x522}, + {"wildcardslots", 0x523}, + {"win_streak", 0x524}, + {"winlossratio", 0x525}, + {"wins", 0x526}, + {"won_match", 0x527}, + {"world", 0x528}, + {"worldmodel", 0x529}, + {"worldspawn", 0x52A}, + {"x", 0x52B}, + {"xb3", 0x52C}, + {"xenon", 0x52D}, + {"xp", 0x52E}, + {"xp_multiplier", 0x52F}, + {"xpmaxmultipliertimeplayed", 0x530}, + {"xpmultiplier", 0x531}, + {"xuid", 0x532}, + {"y", 0x533}, + {"yawconvergencetime", 0x534}, + {"your_score", 0x535}, + {"z", 0x536}, + {"zonly_physics", 0x537}, + {"codescripts/delete", 0x53D}, + {"codescripts/struct", 0x53E}, + {"codescripts/message", 0x53F}, + {"maps/mp/gametypes/_callbacksetup", 0x540}, }; } diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index 462a6628..7aaa9f89 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -11,82 +11,44 @@ #include "../../../component/scripting.hpp" #include +#include namespace scripting::lua { namespace { - std::vector load_game_constants() + + vector normalize_vector(const vector& vec) { - std::vector result{}; + const auto length = sqrt( + (vec.get_x() * vec.get_x()) + + (vec.get_y() * vec.get_y()) + + (vec.get_z() * vec.get_z()) + ); - const auto constants = game::GScr_LoadConsts.get(); - - ud_t ud; - ud_init(&ud); - ud_set_mode(&ud, 64); - ud_set_pc(&ud, uint64_t(constants)); - ud_set_input_buffer(&ud, reinterpret_cast(constants), INT32_MAX); - - while (true) - { - ud_disassemble(&ud); - - if (ud_insn_mnemonic(&ud) == UD_Iret) - { - break; - } - - if (ud_insn_mnemonic(&ud) == UD_Imov) - { - const auto* operand = ud_insn_opr(&ud, 0); - if (operand && operand->type == UD_OP_REG && operand->base == UD_R_ECX) - { - operand = ud_insn_opr(&ud, 1); - if (operand && operand->type == UD_OP_IMM && (operand->base == UD_R_RAX || operand->base == UD_R_EAX)) - { - result.emplace_back(reinterpret_cast(0x1409C1CE0)[operand->lval.udword]); - } - } - } - - if (ud_insn_mnemonic(&ud) == UD_Ilea) - { - const auto* operand = ud_insn_opr(&ud, 0); - if (!operand || operand->type != UD_OP_REG || operand->base != UD_R_RCX) - { - continue; - } - - operand = ud_insn_opr(&ud, 1); - if (operand && operand->type == UD_OP_MEM && operand->base == UD_R_RIP) - { - auto* operand_ptr = reinterpret_cast(ud_insn_len(&ud) + ud_insn_off(&ud) + operand->lval. - sdword); - if (!utils::memory::is_bad_read_ptr(operand_ptr) && utils::memory::is_rdata_ptr(operand_ptr) && - strlen(operand_ptr) > 0) - { - result.emplace_back(operand_ptr); - } - } - } - - if (*reinterpret_cast(ud.pc) == 0xCC) break; // int 3 - } - - return result; + return vector( + vec.get_x() / length, + vec.get_y() / length, + vec.get_z() / length + ); } - const std::vector& get_game_constants() + void setup_io(sol::state& state) { - static auto constants = load_game_constants(); - return constants; + state["io"]["fileexists"] = utils::io::file_exists; + state["io"]["writefile"] = utils::io::write_file; + state["io"]["remove_file"] = utils::io::remove_file; + state["io"]["filesize"] = utils::io::file_size; + state["io"]["createdirectory"] = utils::io::create_directory; + state["io"]["directoryexists"] = utils::io::directory_exists; + state["io"]["directoryisempty"] = utils::io::directory_is_empty; + state["io"]["listfiles"] = utils::io::list_files; + state["io"]["copyfolder"] = utils::io::copy_folder; + state["io"]["readfile"] = static_cast(utils::io::read_file); } - void setup_entity_type(sol::state& state, event_handler& handler, scheduler& scheduler) + void setup_vector_type(sol::state& state) { - state["level"] = entity{*game::levelEntityId}; - auto vector_type = state.new_usertype("vector", sol::constructors()); vector_type["x"] = sol::property(&vector::get_x, &vector::set_x); vector_type["y"] = sol::property(&vector::get_y, &vector::set_y); @@ -96,6 +58,109 @@ namespace scripting::lua vector_type["g"] = sol::property(&vector::get_y, &vector::set_y); vector_type["b"] = sol::property(&vector::get_z, &vector::set_z); + vector_type[sol::meta_function::addition] = sol::overload( + [](const vector& a, const vector& b) + { + return vector( + a.get_x() + b.get_x(), + a.get_y() + b.get_y(), + a.get_z() + b.get_z() + ); + }, + [](const vector& a, const int value) + { + return vector( + a.get_x() + value, + a.get_y() + value, + a.get_z() + value + ); + } + ); + + vector_type[sol::meta_function::subtraction] = sol::overload( + [](const vector& a, const vector& b) + { + return vector( + a.get_x() - b.get_x(), + a.get_y() - b.get_y(), + a.get_z() - b.get_z() + ); + }, + [](const vector& a, const int value) + { + return vector( + a.get_x() - value, + a.get_y() - value, + a.get_z() - value + ); + } + ); + + vector_type[sol::meta_function::multiplication] = sol::overload( + [](const vector& a, const vector& b) + { + return vector( + a.get_x() * b.get_x(), + a.get_y() * b.get_y(), + a.get_z() * b.get_z() + ); + }, + [](const vector& a, const int value) + { + return vector( + a.get_x() * value, + a.get_y() * value, + a.get_z() * value + ); + } + ); + + vector_type[sol::meta_function::division] = sol::overload( + [](const vector& a, const vector& b) + { + return vector( + a.get_x() / b.get_x(), + a.get_y() / b.get_y(), + a.get_z() / b.get_z() + ); + }, + [](const vector& a, const int value) + { + return vector( + a.get_x() / value, + a.get_y() / value, + a.get_z() / value + ); + } + ); + + vector_type[sol::meta_function::equal_to] = [](const vector& a, const vector& b) + { + return a.get_x() == b.get_x() && + a.get_y() == b.get_y() && + a.get_z() == b.get_z(); + }; + + vector_type[sol::meta_function::length] = [](const vector& a) + { + return sqrt((a.get_x() * a.get_x()) + (a.get_y() * a.get_y()) + (a.get_z() * a.get_z())); + }; + + vector_type[sol::meta_function::to_string] = [](const vector& a) + { + return utils::string::va("{x: %f, y: %f, z: %f}", a.get_x(), a.get_y(), a.get_z()); + }; + + vector_type["normalize"] = [](const vector& a) + { + return normalize_vector(a); + }; + } + + void setup_entity_type(sol::state& state, event_handler& handler, scheduler& scheduler) + { + state["level"] = entity{*game::levelEntityId}; + auto entity_type = state.new_usertype("entity"); for (const auto& func : method_map) @@ -114,19 +179,6 @@ namespace scripting::lua }; } - for (const auto& constant : get_game_constants()) - { - entity_type[constant] = sol::property( - [constant](const entity& entity, const sol::this_state s) - { - return convert(s, entity.get(constant)); - }, - [constant](const entity& entity, const sol::this_state s, const sol::lua_value& value) - { - entity.set(constant, convert({s, value})); - }); - } - entity_type["set"] = [](const entity& entity, const std::string& field, const sol::lua_value& value) { @@ -288,8 +340,7 @@ namespace scripting::lua game_type["getgamevar"] = [](const sol::this_state s) { - const auto id = *reinterpret_cast(0x14815DEB4); - const auto value = ::game::scr_VarGlob->childVariableValue[id]; + const auto value = ::game::scr_VarGlob->childVariableValue[*::game::gameEntityId]; ::game::VariableValue variable{}; variable.type = value.type; @@ -445,6 +496,8 @@ namespace scripting::lua return this->folder_; }; + setup_io(this->state_); + setup_vector_type(this->state_); setup_entity_type(this->state_, this->event_handler_, this->scheduler_); printf("Loading script '%s'\n", this->folder_.data()); diff --git a/src/client/game/scripting/lua/value_conversion.cpp b/src/client/game/scripting/lua/value_conversion.cpp index defbe14d..3cc37e20 100644 --- a/src/client/game/scripting/lua/value_conversion.cpp +++ b/src/client/game/scripting/lua/value_conversion.cpp @@ -21,7 +21,7 @@ namespace scripting::lua std::unordered_map values; - const auto offset = 64000 * (id & 3); + const auto offset = 0xA000 * (id & 3); auto current = game::scr_VarGlob->objectVariableChildren[id].firstChild; auto idx = 1; diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 842aebbc..e57d54c7 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -186,8 +186,8 @@ namespace game struct scrVarGlob_t { - ObjectVariableValue objectVariableValue[40960]; - ObjectVariableChildren objectVariableChildren[40960]; + ObjectVariableValue objectVariableValue[56320]; + ObjectVariableChildren objectVariableChildren[56320]; unsigned __int16 childVariableBucket[65536]; ChildVariableValue childVariableValue[384000]; }; @@ -1358,18 +1358,22 @@ namespace game struct EntityState { - char entityNum; + uint16_t entityNum; }; // size = ? +#pragma pack(push, 1) struct gentity_s { EntityState s; - char __pad0[343]; + char __pad0[342]; gclient_s* client; char __pad1[80]; int flags; char __pad2[300]; }; // size = 736 +#pragma pack(pop) + + static_assert(sizeof(gentity_s) == 736); struct playerState_s { diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 5ca58188..1df51cb6 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -8,17 +8,17 @@ namespace game * Functions **************************************************************/ - WEAK symbol AddRefToValue{0x140315830, 0x14043C580}; // H1MP - WEAK symbol RemoveRefToValue{0x140317340, 0x14043E090}; // H1MP - WEAK symbol AddRefToObject{0, 0x14043C570 }; // H1MP - WEAK symbol RemoveRefToObject{0, 0x14043DF80 }; // H1MP - WEAK symbol AllocThread{0, 0x14043C8E0 }; // H1MP + WEAK symbol AddRefToValue{0x14036E600, 0x14043C580}; + WEAK symbol RemoveRefToValue{0x1403700F0, 0x14043E090}; + WEAK symbol AddRefToObject{0x14036E5F0, 0x14043C570}; + WEAK symbol RemoveRefToObject{0x14036FFE0, 0x14043DF80}; + WEAK symbol AllocThread{0x14036E960, 0x14043C8E0}; WEAK symbol Cbuf_AddText{0x140342EB0, 0x1404033B0}; WEAK symbol Cbuf_ExecuteBufferInternal{0, 0x1404034C0}; + void (int, int, const char*))> Cbuf_ExecuteBufferInternal{0x140342FC0, 0x1404034C0}; WEAK symbol Conbuf_AppendText{0x1403E3300, 0x140513FF0}; - WEAK symbol ConcatArgs{0x14021A7E0, 0x140335D70}; // h1mp + WEAK symbol ConcatArgs{0x1402697F0, 0x140335D70}; WEAK symbol Cmd_ExecuteSingleCommand{0x140343980, 0x140403F60}; WEAK symbol Cmd_AddCommandInternal{0x1403433E0, 0x140403950}; WEAK symbol Cmd_RemoveCommand{0x140343FF0, 0x1404045D0}; @@ -27,7 +27,8 @@ namespace game WEAK symbol AimAssist_AddToTargetList{0, 0x14009D0F0}; - WEAK symbol BG_GetWeaponNameComplete{0x0, 0x140165580}; // H1MP + WEAK symbol BG_GetWeaponNameComplete{0x140430550, 0x1401F9670}; WEAK symbol Com_Frame_Try_Block_Function{0x1401CE8D0, 0x1400D8310}; WEAK symbol Com_GetCurrentCoDPlayMode{0, 0x1405039A0}; @@ -44,7 +45,6 @@ namespace game WEAK symbol Dvar_SetCommand{0x1403C72B0, 0x1404FD0A0}; WEAK symbol Dvar_FindVar{0x1403C5D50, 0x1404FBB00}; - WEAK symbol Dvar_ClearModified{0x0, 0x1404FB930}; WEAK symbol Dvar_GetCombinedString{0x140354DF0, 0x14041D830}; WEAK symbol Dvar_ValueToString{0x1403C8560, 0x1404FE660}; WEAK symbol FS_Startup{0x1403B85D0, 0x1404EDD30}; WEAK symbol FS_AddLocalizedGameDirectory{0x1403B6030, 0x1404EBE20}; - WEAK symbol GetVariable{0x0, 0x1403F3730}; // H1MP + WEAK symbol GetVariable{0x14036FDD0, 0x1403F3730}; WEAK symbol GScr_LoadConsts{0x1402D13E0, 0x140393810}; - WEAK symbol FindVariable{0x1403165D0, 0x14043D430}; // H1MP - WEAK symbol FindEntityId{0x1403166D0, 0x14043D330}; // H1MP - WEAK symbol RemoveVariableValue{0, 0x14043E130}; // H1MP - WEAK symbol GetEntityFieldValue{0x14031AAD0, 0x140441780}; // H1MP + WEAK symbol FindVariable{0x14036F4B0, 0x14043D430}; + WEAK symbol FindEntityId{0x14036F3B0, 0x14043D330}; + WEAK symbol RemoveVariableValue{0x140370190, 0x14043E130}; + WEAK symbol GetEntityFieldValue{0x140373780, 0x140441780}; + WEAK symbol generateHashValue{0x1400FE8A0, 0x1401B1010}; - WEAK symbol G_Glass_Update{0, 0x14033A640}; + WEAK symbol G_Glass_Update{0x14026C570, 0x14033A640}; WEAK symbol G_GetClientScore{0, 0x140342F90}; WEAK symbol I_CleanStr{0x1403CD230, 0x140503D00}; @@ -94,7 +96,7 @@ namespace game WEAK symbol R_TextWidth{0x1404D43B0, 0x1405D94A0}; WEAK symbol R_GetFontHeight{0x1405EA360, 0x1405D92C0}; WEAK symbol R_DrawSomething{0x1404D37B0, 0x1405D8890}; - WEAK symbol R_SyncRenderThread{0, 0x1405FF3A0}; + WEAK symbol R_SyncRenderThread{0x1404F8240, 0x1405FF3A0}; WEAK symbol VM_Execute{0x0, 0x140444350}; + WEAK symbol VM_Execute{0x140376360, 0x140444350}; - WEAK symbol Scr_NotifyId{0x14031CB80, 0x1404437E0}; - WEAK symbol Scr_AllocVector{0x140317D10, 0x14043E7D0}; // H1MP + WEAK symbol Scr_NotifyId{0x140375800, 0x1404437E0}; + WEAK symbol Scr_AllocVector{0x140370930, 0x14043E7D0}; WEAK symbol Scr_GetFloat{0x140374D20, 0x140442D10}; - WEAK symbol Scr_GetString{0, 0x14032F0A0}; + WEAK symbol Scr_GetString{0x140375210, 0x140443150}; WEAK symbol Scr_GetNumParam{0x140374F30, 0x140442E70}; - WEAK symbol Scr_ClearOutParams{0x14031B7C0, 0x140442510}; // H1MP - WEAK symbol Scr_GetEntityIdRef{0x14031A0D0, 0x1403F68A0}; // H1MP + WEAK symbol Scr_ClearOutParams{0x140374460, 0x140442510}; + WEAK symbol Scr_GetEntityIdRef{0x140372D50, 0x140440D80}; + WEAK symbol Scr_GetEntityId{0x140372CA0, 0x140440CD0}; WEAK symbol ScrPlace_GetViewPlacement{0x1401981F0, 0x140288550}; WEAK symbol DB_GetXAssetTypeSize{0x14019A3B0, 0x14028BE70}; - WEAK symbol LUI_OpenMenu{0x14039D5F0, 0x1404CD210}; + WEAK symbol LUI_OpenMenu{0x14039D5F0, 0x1404CD210}; WEAK symbol Menu_IsMenuOpenAndVisible{0x1404709C0, 0x1404C7320}; - WEAK symbol SL_FindString{0x140314AF0, 0x14043B470}; - WEAK symbol SL_GetString{0x140314D90, 0x14043B840}; // H1MP + WEAK symbol SL_FindString{0x14036D700, 0x14043B470}; + WEAK symbol SL_GetString{0x14036D9A0, 0x14043B840}; WEAK symbol SL_ConvertToString{0x14036D420, 0x14043B170}; - WEAK symbol Scr_SetObjectField{ 0x14026B620, 0x140385330 }; // H1MP + WEAK symbol Scr_SetObjectField{0x1402B9F60, 0x140385330}; WEAK symbol SV_DirectConnect{0, 0x140480860}; - WEAK symbol SV_Cmd_ArgvBuffer{0x1402EEFD0, 0x1403B05C0}; // H1MP - WEAK symbol SV_Cmd_TokenizeString{0x1402EF050, 0x140404D20}; + WEAK symbol SV_Cmd_ArgvBuffer{0x1403446C0, 0x140404CA0}; + WEAK symbol SV_Cmd_TokenizeString{0x140344740, 0x140404D20}; WEAK symbol SV_Cmd_EndTokenizedString{0x140344700, 0x140404CE0}; WEAK symbol SV_AddBot{0, 0x140480190}; @@ -176,26 +182,27 @@ namespace game WEAK symbol sv_cmd_args{0, 0x14946BA20}; - WEAK symbol g_script_error_level{0x14A1917A8, 0x14A33C824}; // H1MP - WEAK symbol g_script_error{0x14A1917B0, 0x14A33C940}; // H1MP + WEAK symbol g_script_error_level{0x14A1917A8, 0x14A33C824}; + WEAK symbol g_script_error{0x14A1917B0, 0x14A33C940}; - WEAK symbol levelEntityId{0x149AF55B0, 0x149CA0730}; // H1MP + WEAK symbol levelEntityId{0x149AF55B0, 0x149CA0730}; + WEAK symbol gameEntityId{0x149CA0734, 0x14B65E3B4}; WEAK symbol command_whitelist{0x141079A60, 0x14120C360}; WEAK symbol cmd_functions{0x14AD99AB8, 0x14946BAC8}; WEAK symbol cmd_args{0x14AD99960, 0x14946B970}; WEAK symbol g_poolSize{0, 0x140FEADF0}; - WEAK symbol g_classMap{0x14080A840, 0x1412106B0}; // H1MP + WEAK symbol g_classMap{0x14080A840, 0x1412106B0}; - WEAK symbol scr_VarGlob{0x149B1D680, 0x149CC8800}; // H1MP - WEAK symbol scr_VmPub{0x14A1938C0, 0x14A33EA40}; // H1MP - WEAK symbol scr_function_stack{0x14A19DE40, 0x14A348FC0}; // H1MP + WEAK symbol scr_VarGlob{0x14B686480, 0x149CC8800}; + WEAK symbol scr_VmPub{0x14A1938C0, 0x14A33EA40}; + WEAK symbol scr_function_stack{0x14BD06C40, 0x14A348FC0}; - WEAK symbol gfxDrawMethod{0, 0x14FD21180}; + WEAK symbol gfxDrawMethod{0x14F05CE50, 0x14FD21180}; - WEAK symbol dvarCount{0, 0x14D064CF4}; - WEAK symbol sortedDvars{0, 0x14D064D00}; + WEAK symbol dvarCount{0x14C217D10, 0x14D064CF4}; + WEAK symbol dvarPool{0x14C217D20, 0x14D064D00}; WEAK symbol DB_XAssetPool{0x140DE8C80, 0x140FEB5D0}; From 7624d400cb8ba679382d75e5fe930a4f0d5c2caa Mon Sep 17 00:00:00 2001 From: fed <58637860+fedddddd@users.noreply.github.com> Date: Thu, 3 Mar 2022 12:37:46 +0100 Subject: [PATCH 018/346] Fix in-game UI --- src/client/component/auth.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 5ea40d9c..f0950e96 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -227,8 +227,8 @@ namespace auth utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) utils::hook::call(0x140250ED2, send_connect_data_stub); // H1(1.4) - // Check for sending connect packet - utils::hook::set(0x14059A6E0, 0xC301B0); + // Skip checks for sending connect packet + utils::hook::jump(0x1402508FC, 0x140250946); // Don't instantly timeout the connecting client ? not sure about this utils::hook::set(0x14025136B, 0xC3); } From 37fe43d4260e5359609be55e982ebcb5ac64fa86 Mon Sep 17 00:00:00 2001 From: fed <58637860+fedddddd@users.noreply.github.com> Date: Thu, 3 Mar 2022 12:51:02 +0100 Subject: [PATCH 019/346] Game console fixes --- src/client/component/game_console.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 289a07a8..cf7c3056 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -59,7 +59,7 @@ namespace game_console std::vector matches{}; float color_white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - float color_title[4] = {0.9f, 0.9f, 0.5f, 1.0f}; + float color_title[4] = {0.25f, 0.62f, 0.3f, 1.0f}; void clear() { @@ -453,11 +453,19 @@ namespace game_console 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) + 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) From 597549df52987ed265cb305cf3dabe1fcfc24f20 Mon Sep 17 00:00:00 2001 From: m Date: Thu, 3 Mar 2022 06:56:46 -0600 Subject: [PATCH 020/346] add filesystem + executing custom cfg files --- src/client/component/filesystem.cpp | 94 +++++++++++++++++++++++++++++ src/client/component/filesystem.hpp | 19 ++++++ src/client/component/patches.cpp | 29 ++++++--- 3 files changed, 135 insertions(+), 7 deletions(-) create mode 100644 src/client/component/filesystem.cpp create mode 100644 src/client/component/filesystem.hpp diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp new file mode 100644 index 00000000..da11d2e4 --- /dev/null +++ b/src/client/component/filesystem.cpp @@ -0,0 +1,94 @@ +#include +#include "loader/component_loader.hpp" +#include "filesystem.hpp" +#include "game_module.hpp" + +#include "game/game.hpp" +#include "dvars.hpp" + +#include +#include + +namespace filesystem +{ + namespace + { + bool custom_path_registered = false; + + std::string get_binary_directory() + { + const auto dir = game_module::get_host_module().get_folder(); + return utils::string::replace(dir, "/", "\\"); + } + + void register_custom_path_stub(const char* path, const char* dir) + { + if (!custom_path_registered) + { + custom_path_registered = true; + + const auto launcher_dir = get_binary_directory(); + game::FS_AddLocalizedGameDirectory(launcher_dir.data(), "data"); + } + + game::FS_AddLocalizedGameDirectory(path, dir); + } + + void fs_startup_stub(const char* gamename) + { + custom_path_registered = false; + game::FS_Startup(gamename); + } + } + + file::file(std::string name) + : name_(std::move(name)) + { + char* buffer{}; + const auto size = game::FS_ReadFile(this->name_.data(), &buffer); + + if (size >= 0 && buffer) + { + this->valid_ = true; + this->buffer_.append(buffer, size); + game::FS_FreeFile(buffer); + } + } + + bool file::exists() const + { + return this->valid_; + } + + const std::string& file::get_buffer() const + { + return this->buffer_; + } + + const std::string& file::get_name() const + { + return this->name_; + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + // Set fs_basegame + dvars::override::register_string("fs_basegame", "h1-mod", game::DVAR_FLAG_WRITE); + + utils::hook::call(SELECT_VALUE(0x1403B76E2, 0x1404ED3E2), fs_startup_stub); + if (game::environment::is_mp()) + { + utils::hook::call(0x1404ED823, fs_startup_stub); + } + + utils::hook::call(SELECT_VALUE(0x1403B8D31, 0x1404EE3D0), register_custom_path_stub); + utils::hook::call(SELECT_VALUE(0x1403B8D51, 0x1404EE3F0), register_custom_path_stub); + utils::hook::call(SELECT_VALUE(0x1403B8D90, 0x1404EE42F), register_custom_path_stub); + } + }; +} + +REGISTER_COMPONENT(filesystem::component) \ No newline at end of file diff --git a/src/client/component/filesystem.hpp b/src/client/component/filesystem.hpp new file mode 100644 index 00000000..6cec8c87 --- /dev/null +++ b/src/client/component/filesystem.hpp @@ -0,0 +1,19 @@ +#pragma once + +namespace filesystem +{ + class file + { + public: + file(std::string name); + + bool exists() const; + const std::string& get_buffer() const; + const std::string& get_name() const; + + private: + bool valid_ = false; + std::string name_; + std::string buffer_; + }; +} \ No newline at end of file diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index a8ee11fc..e9aaf21a 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -7,6 +7,7 @@ #include "console.hpp" #include "network.hpp" #include "scheduler.hpp" +#include "filesystem.hpp" #include "game/game.hpp" #include "game/dvars.hpp" @@ -77,16 +78,27 @@ namespace patches } // CG_SetClientDvarFromServer - reinterpret_cast(0x140236120)(a1, a2, dvar, value); + utils::hook::invoke(0x140236120, a1, a2, dvar, value); } - /*void aim_assist_add_to_target_list(void* a1, void* a2) + const char* db_read_raw_file_stub(const char* filename, char* buf, const int size) { - if (!dvars::aimassist_enabled->current.enabled) - return; + std::string file_name = filename; + if (file_name.find(".cfg") == std::string::npos) + { + file_name.append(".cfg"); + } - game::AimAssist_AddToTargetList(a1, a2); - }*/ + const auto file = filesystem::file(file_name); + if (file.exists()) + { + snprintf(buf, size, "%s\n", file.get_buffer().data()); + return buf; + } + + // DB_ReadRawFile + return utils::hook::invoke(SELECT_VALUE(0x1401CD4F0, 0x1402BEF10), filename, buf, size); + } void bsp_sys_error_stub(const char* error, const char* arg1) { @@ -131,7 +143,7 @@ namespace patches return; } - reinterpret_cast(0x140481A00)(client, msg); + utils::hook::invoke(0x140481A00, client, msg); } void aim_assist_add_to_target_list(void* a1, void* a2) @@ -172,6 +184,9 @@ namespace patches utils::hook::nop(SELECT_VALUE(0x14018797E, 0x14024EF60), 2); utils::hook::nop(SELECT_VALUE(0x1401856DC, 0x14024C6B0), 6); + // Allow executing custom cfg files with the "exec" command + utils::hook::call(SELECT_VALUE(0x140343855, 0x140403E28), db_read_raw_file_stub); + if (!game::environment::is_sp()) { patch_mp(); From 8f9c663321acf28732a673d4dfd7450cfd7d49e0 Mon Sep 17 00:00:00 2001 From: m Date: Thu, 3 Mar 2022 07:07:37 -0600 Subject: [PATCH 021/346] use hooking utils invoke --- src/client/component/colors.cpp | 3 +-- src/client/component/command.cpp | 2 +- src/client/component/dedicated.cpp | 2 +- src/client/component/party.cpp | 11 ++++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp index 66abb6b1..75eff23a 100644 --- a/src/client/component/colors.cpp +++ b/src/client/component/colors.cpp @@ -96,8 +96,7 @@ namespace colors const size_t unk, const size_t unk2) { // CL_GetClientName (CL_GetClientNameAndClantag?) - const auto result = reinterpret_cast(0x14025BAA0)( // H1 (1.4) - local_client_num, index, buf, size, unk, unk2); + const auto result = utils::hook::invoke(0x14025BAA0, local_client_num, index, buf, size, unk, unk2); utils::string::strip(buf, buf, size); diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 01f7b241..b5c1ad40 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -91,7 +91,7 @@ namespace command void parse_commandline_stub() { parse_command_line(); - reinterpret_cast(0x1400D8210)(); // mwr: test + utils::hook::invoke(0x1400D8210); } game::dvar_t* dvar_command_stub() diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index dd9f920f..8de5e9ac 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -26,7 +26,7 @@ namespace dedicated initialized = true; // R_LoadGraphicsAssets - reinterpret_cast(0x1405DF4B0)(); + utils::hook::invoke(0x1405DF4B0); } void send_heartbeat() diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 81159b58..0605afad 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -119,7 +119,7 @@ namespace party } // This function either does Dvar_SetString or Dvar_RegisterString for the given dvar - reinterpret_cast(0x1404FB210)(dvar_name, string); + utils::hook::invoke(0x1404FB210, dvar_name, string); } void disconnect_stub() @@ -129,12 +129,12 @@ namespace party if (game::CL_IsCgameInitialized()) { // CL_ForwardCommandToServer - reinterpret_cast(0x140253480)(0, "disconnect"); + utils::hook::invoke(0x140253480, 0, "disconnect"); // CL_WritePacket - reinterpret_cast(0x14024DB10)(0); + utils::hook::invoke(0x14024DB10, 0); } // CL_Disconnect - reinterpret_cast(0x140252060)(0); + utils::hook::invoke(0x140252060, 0); } } @@ -337,7 +337,8 @@ namespace party *reinterpret_cast(0x14A3A91D0) = 1; // sv_map_restart *reinterpret_cast(0x14A3A91D4) = 1; // sv_loadScripts *reinterpret_cast(0x14A3A91D8) = 0; // sv_migrate - reinterpret_cast(0x14047E7F0)(); // SV_CheckLoadGame + + utils::hook::invoke(0x14047E7F0); // SV_CheckLoadGame }); command::add("fast_restart", []() From 06cabab4ed8e7e284f6d3bef8ce5f0815fd06200 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 3 Mar 2022 16:49:58 +0200 Subject: [PATCH 022/346] missing address for sp --- src/client/game/symbols.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index ff0b8b64..6e9bd9e8 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -145,7 +145,7 @@ namespace game * Variables **************************************************************/ - WEAK symbol sv_cmd_args{0, 0x14946BA20}; + WEAK symbol sv_cmd_args{0x14AD99A10, 0x14946BA20}; WEAK symbol command_whitelist{0x141079A60, 0x14120C360}; WEAK symbol cmd_functions{0x14AD99AB8, 0x14946BAC8}; From 5867849afb294c618f83c62393491fac48fb7368 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 3 Mar 2022 21:01:10 +0100 Subject: [PATCH 023/346] Create build.yml --- .github/workflows/build.yml | 115 ++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..ed060261 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,115 @@ +name: Build + +on: + push: + branches: + - "*" + pull_request: + branches: + - "*" + types: [opened, synchronize, reopened] +jobs: + build: + name: Build binaries + runs-on: windows-2022 + strategy: + matrix: + configuration: + - Debug + - Release + steps: + - name: Wait for previous workflows + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') + uses: softprops/turnstyle@v1 + with: + poll-interval-seconds: 10 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Check out files + uses: actions/checkout@v2 + with: + submodules: true + fetch-depth: 0 + # NOTE - If LFS ever starts getting used during builds, switch this to true! + lfs: false + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + + - name: Generate project files + #run: tools/premake5 vs2022 --ci-build + run: tools/premake5 vs2022 + + - name: Set up problem matching + uses: ammaraskar/msvc-problem-matcher@master + + - name: Build ${{matrix.configuration}} binaries + run: msbuild /m /v:minimal /p:Configuration=${{matrix.configuration}} /p:Platform=x64 build/h2-mod.sln + + - name: Upload ${{matrix.configuration}} binaries + uses: actions/upload-artifact@v2 + with: + name: ${{matrix.configuration}} binaries + path: | + build/bin/x64/${{matrix.configuration}}/h2-mod.exe + build/bin/x64/${{matrix.configuration}}/h2-mod.pdb + + - name: Upload ${{matrix.configuration}} data artifacts + uses: actions/upload-artifact@v2 + with: + name: ${{matrix.configuration}} data artifacts + path: | + data/* + deploy: + name: Deploy artifacts + needs: build + runs-on: ubuntu-latest + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') + steps: + - name: Setup main environment + if: github.ref == 'refs/heads/main' + run: echo "H1_MOD_MASTER_PATH=${{ secrets.H1_MOD_MASTER_SSH_PATH }}" >> $GITHUB_ENV + + - name: Setup develop environment + if: github.ref == 'refs/heads/develop' + run: echo "H1_MOD_MASTER_PATH=${{ secrets.H1_MOD_MASTER_SSH_PATH_DEV }}" >> $GITHUB_ENV + + - name: Download Release binaries + uses: actions/download-artifact@v2 + with: + name: Release binaries + + - name: Download Release data artifacts + uses: actions/download-artifact@v2 + with: + name: Release data artifacts + path: data + + - name: Install SSH key + uses: shimataro/ssh-key-action@v2 + with: + key: ${{ secrets.H1_MOD_MASTER_SSH_PRIVATE_KEY }} + known_hosts: 'just-a-placeholder-so-we-dont-get-errors' + + - name: Add known hosts + run: ssh-keyscan -H ${{ secrets.H1_MOD_MASTER_SSH_ADDRESS }} >> ~/.ssh/known_hosts + + - name: Wait for previous workflows + uses: softprops/turnstyle@v1 + with: + poll-interval-seconds: 10 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Remove old data files + run: ssh ${{ secrets.H1_MOD_MASTER_SSH_USER }}@${{ secrets.H1_MOD_MASTER_SSH_ADDRESS }} rm -rf ${{ env.H1_MOD_MASTER_PATH }}/h1-mod/data/* + + - name: Upload h2-mod binary + run: rsync -avz h2-mod.exe ${{ secrets.H1_MOD_MASTER_SSH_USER }}@${{ secrets.H1_MOD_MASTER_SSH_ADDRESS }}:${{ env.H1_MOD_MASTER_PATH }}/h1-mod/ + + - name: Upload data files + run: rsync -avz ./data/ ${{ secrets.H1_MOD_MASTER_SSH_USER }}@${{ secrets.H1_MOD_MASTER_SSH_ADDRESS }}:${{ env.H1_MOD_MASTER_PATH }}/h1-mod/data/ + + - name: Publish changes + run: ssh ${{ secrets.H1_MOD_MASTER_SSH_USER }}@${{ secrets.H1_MOD_MASTER_SSH_ADDRESS }} ${{ secrets.H1_MOD_MASTER_SSH_CHANGE_PUBLISH_COMMAND }} From ec83ccb612c2cbc5d2e90be437c7809490f24e4f Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 3 Mar 2022 21:09:14 +0100 Subject: [PATCH 024/346] Update build.yml --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ed060261..9db13960 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,15 +45,15 @@ jobs: uses: ammaraskar/msvc-problem-matcher@master - name: Build ${{matrix.configuration}} binaries - run: msbuild /m /v:minimal /p:Configuration=${{matrix.configuration}} /p:Platform=x64 build/h2-mod.sln + run: msbuild /m /v:minimal /p:Configuration=${{matrix.configuration}} /p:Platform=x64 build/h1-mod.sln - name: Upload ${{matrix.configuration}} binaries uses: actions/upload-artifact@v2 with: name: ${{matrix.configuration}} binaries path: | - build/bin/x64/${{matrix.configuration}}/h2-mod.exe - build/bin/x64/${{matrix.configuration}}/h2-mod.pdb + build/bin/x64/${{matrix.configuration}}/h1-mod.exe + build/bin/x64/${{matrix.configuration}}/h1-mod.pdb - name: Upload ${{matrix.configuration}} data artifacts uses: actions/upload-artifact@v2 @@ -105,8 +105,8 @@ jobs: - name: Remove old data files run: ssh ${{ secrets.H1_MOD_MASTER_SSH_USER }}@${{ secrets.H1_MOD_MASTER_SSH_ADDRESS }} rm -rf ${{ env.H1_MOD_MASTER_PATH }}/h1-mod/data/* - - name: Upload h2-mod binary - run: rsync -avz h2-mod.exe ${{ secrets.H1_MOD_MASTER_SSH_USER }}@${{ secrets.H1_MOD_MASTER_SSH_ADDRESS }}:${{ env.H1_MOD_MASTER_PATH }}/h1-mod/ + - name: Upload h1-mod binary + run: rsync -avz h1-mod.exe ${{ secrets.H1_MOD_MASTER_SSH_USER }}@${{ secrets.H1_MOD_MASTER_SSH_ADDRESS }}:${{ env.H1_MOD_MASTER_PATH }}/h1-mod/ - name: Upload data files run: rsync -avz ./data/ ${{ secrets.H1_MOD_MASTER_SSH_USER }}@${{ secrets.H1_MOD_MASTER_SSH_ADDRESS }}:${{ env.H1_MOD_MASTER_PATH }}/h1-mod/data/ From 09d0f99d5adb988487e9d5f4047715d736845de9 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 4 Mar 2022 01:39:19 +0100 Subject: [PATCH 025/346] Add updater --- src/client/component/updater.cpp | 469 +++++++++++++++++++ src/client/component/updater.hpp | 26 + src/client/game/ui_scripting/lua/context.cpp | 78 ++- src/client/game/ui_scripting/lua/context.hpp | 8 +- src/client/game/ui_scripting/lua/engine.cpp | 14 +- src/client/resource.hpp | 3 + src/client/resource.rc | 3 + src/client/resources/ui_scripts/common.lua | 164 +++++++ src/client/resources/ui_scripts/updater.lua | 156 ++++++ 9 files changed, 897 insertions(+), 24 deletions(-) create mode 100644 src/client/component/updater.cpp create mode 100644 src/client/component/updater.hpp create mode 100644 src/client/resources/ui_scripts/common.lua create mode 100644 src/client/resources/ui_scripts/updater.lua diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp new file mode 100644 index 00000000..512b619b --- /dev/null +++ b/src/client/component/updater.cpp @@ -0,0 +1,469 @@ +#include +#include "loader/component_loader.hpp" + +#include "scheduler.hpp" +#include "dvars.hpp" +#include "updater.hpp" + +#include "version.h" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include +#include +#include +#include + +#define MASTER "https://master.fed0001.xyz/h1-mod/" + +#define FILES_PATH "files.json" +#define FILES_PATH_DEV "files-dev.json" + +#define DATA_PATH "data/" +#define DATA_PATH_DEV "data-dev/" + +#define ERR_UPDATE_CHECK_FAIL "Failed to check for updates" +#define ERR_DOWNLOAD_FAIL "Failed to download file " +#define ERR_WRITE_FAIL "Failed to write file " + +#define BINARY_NAME "h1-mod.exe" + +namespace updater +{ + namespace + { + game::dvar_t* cl_auto_update; + bool has_tried_update = false; + + struct status + { + bool done; + bool success; + }; + + struct file_data + { + std::string name; + std::string data; + }; + + struct update_data_t + { + bool restart_required{}; + bool cancelled{}; + status check{}; + status download{}; + std::string error{}; + std::string current_file{}; + std::vector required_files{}; + }; + + utils::concurrency::container update_data; + + std::string get_branch() + { + return GIT_BRANCH; + } + + std::string select(const std::string& main, const std::string& develop) + { + if (get_branch() == "develop") + { + return develop; + } + + return main; + } + + std::string get_data_path() + { + if (get_branch() == "develop") + { + return DATA_PATH_DEV; + } + + return DATA_PATH; + } + + void set_update_check_status(bool done, bool success, const std::string& error = {}) + { + update_data.access([done, success, error](update_data_t& data_) + { + data_.check.done = done; + data_.check.success = success; + data_.error = error; + }); + } + + void set_update_download_status(bool done, bool success, const std::string& error = {}) + { + update_data.access([done, success, error](update_data_t& data_) + { + data_.download.done = done; + data_.download.success = success; + data_.error = error; + }); + } + + bool check_file(const std::string& name, const std::string& sha) + { + std::string data; + if (!utils::io::read_file(name, &data)) + { + return false; + } + + if (utils::cryptography::sha1::compute(data, true) != sha) + { + return false; + } + + return true; + } + + std::string load_binary_name() + { + // utils::nt::library self; + // return self.get_name(); + // returns the game's name and not the client's + + return BINARY_NAME; + } + + std::string get_binary_name() + { + static const auto name = load_binary_name(); + return name; + } + + std::optional download_file(const std::string& name) + { + return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name); + } + + bool is_update_cancelled() + { + return update_data.access([](update_data_t& data_) + { + return data_.cancelled; + }); + } + + bool write_file(const std::string& name, const std::string& data) + { + if (get_binary_name() == name && + utils::io::file_exists(name) && + !utils::io::move_file(name, name + ".old")) + { + return false; + } + +#ifdef DEBUG + return utils::io::write_file("update_test/" + name, data); +#else + return utils::io::write_file(name, data); +#endif + } + + void delete_old_file() + { + utils::io::remove_file(get_binary_name() + ".old"); + } + + void reset_data() + { + update_data.access([](update_data_t& data_) + { + data_ = {}; + }); + } + + std::string get_mode_flag() + { + if (game::environment::is_mp()) + { + return "-multiplayer"; + } + + if (game::environment::is_sp()) + { + return "-singleplayer"; + } + + return {}; + } + } + + // workaround + void relaunch() + { + if (!utils::io::file_exists(BINARY_NAME)) + { + utils::nt::terminate(0); + return; + } + + STARTUPINFOA startup_info; + PROCESS_INFORMATION process_info; + + ZeroMemory(&startup_info, sizeof(startup_info)); + ZeroMemory(&process_info, sizeof(process_info)); + startup_info.cb = sizeof(startup_info); + + char current_dir[MAX_PATH]; + GetCurrentDirectoryA(sizeof(current_dir), current_dir); + + char buf[1024] = {0}; + const auto command_line = utils::string::va("%s %s", GetCommandLineA(), get_mode_flag().data()); + strcpy_s(buf, 1024, command_line); + + CreateProcess(BINARY_NAME, buf, nullptr, nullptr, false, NULL, nullptr, current_dir, + &startup_info, &process_info); + + if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread); + if (process_info.hProcess && process_info.hProcess != INVALID_HANDLE_VALUE) CloseHandle(process_info.hProcess); + + utils::nt::terminate(0); + } + + void set_has_tried_update(bool tried) + { + has_tried_update = tried; + } + + bool get_has_tried_update() + { + return has_tried_update; + } + + bool auto_updates_enabled() + { + return cl_auto_update->current.enabled; + } + + bool is_update_check_done() + { + return update_data.access([](update_data_t& data_) + { + return data_.check.done; + }); + } + + bool is_update_download_done() + { + return update_data.access([](update_data_t& data_) + { + return data_.download.done; + }); + } + + bool get_update_check_status() + { + return update_data.access([](update_data_t& data_) + { + return data_.check.success; + }); + } + + bool get_update_download_status() + { + return update_data.access([](update_data_t& data_) + { + return data_.download.success; + }); + } + + bool is_update_available() + { + return update_data.access([](update_data_t& data_) + { + return data_.required_files.size() > 0; + }); + } + + bool is_restart_required() + { + return update_data.access([](update_data_t& data_) + { + return data_.restart_required; + }); + } + + std::string get_last_error() + { + return update_data.access([](update_data_t& data_) + { + return data_.error; + }); + } + + std::string get_current_file() + { + return update_data.access([](update_data_t& data_) + { + return data_.current_file; + }); + } + + void cancel_update() + { +#ifdef DEBUG + printf("[Updater] Cancelling update\n"); +#endif + + return update_data.access([](update_data_t& data_) + { + data_.cancelled = true; + }); + } + + void start_update_check() + { + cancel_update(); + reset_data(); + +#ifdef DEBUG + printf("[Updater] starting update check\n"); +#endif + + scheduler::once([]() + { + const auto files_data = utils::http::get_data(MASTER + select(FILES_PATH, FILES_PATH_DEV)); + + if (is_update_cancelled()) + { + reset_data(); + return; + } + + if (!files_data.has_value()) + { + set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); + return; + } + + rapidjson::Document j; + j.Parse(files_data.value().data()); + + if (!j.IsArray()) + { + set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); + return; + } + + std::vector required_files; + + const auto files = j.GetArray(); + for (const auto& file : files) + { + if (!file.IsArray() || file.Size() != 3 || !file[0].IsString() || !file[2].IsString()) + { + continue; + } + + const auto name = file[0].GetString(); + const auto sha = file[2].GetString(); + + if (!check_file(name, sha)) + { + if (get_binary_name() == name) + { + update_data.access([](update_data_t& data_) + { + data_.restart_required = true; + }); + } + +#ifdef DEBUG + printf("[Updater] need file %s\n", name); +#endif + + required_files.push_back(name); + } + } + + update_data.access([&required_files](update_data_t& data_) + { + data_.check.done = true; + data_.check.success = true; + data_.required_files = required_files; + }); + }, scheduler::pipeline::async); + } + + void start_update_download() + { +#ifdef DEBUG + printf("[Updater] starting update download\n"); +#endif + + if (!is_update_check_done() || !get_update_check_status() || is_update_cancelled()) + { + return; + } + + scheduler::once([]() + { + const auto required_files = update_data.access>([](update_data_t& data_) + { + return data_.required_files; + }); + + std::vector downloads; + + for (const auto& file : required_files) + { + update_data.access([file](update_data_t& data_) + { + data_.current_file = file; + }); + +#ifdef DEBUG + printf("[Updater] downloading file %s\n", file.data()); +#endif + + const auto data = download_file(file); + + if (is_update_cancelled()) + { + reset_data(); + return; + } + + if (!data.has_value()) + { + set_update_download_status(true, false, ERR_DOWNLOAD_FAIL + file); + return; + } + + downloads.push_back({file, data.value()}); + } + + for (const auto& download : downloads) + { + if (!write_file(download.name, download.data)) + { + set_update_download_status(true, false, ERR_WRITE_FAIL + download.name); + return; + } + } + + set_update_download_status(true, true); + }, scheduler::pipeline::async); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + delete_old_file(); + cl_auto_update = dvars::register_bool("cg_auto_update", true, game::DVAR_FLAG_SAVED, true); + } + }; +} + +REGISTER_COMPONENT(updater::component) diff --git a/src/client/component/updater.hpp b/src/client/component/updater.hpp new file mode 100644 index 00000000..9a3dd45e --- /dev/null +++ b/src/client/component/updater.hpp @@ -0,0 +1,26 @@ +#pragma once + +namespace updater +{ + void relaunch(); + + void set_has_tried_update(bool tried); + bool get_has_tried_update(); + bool auto_updates_enabled(); + + bool is_update_available(); + bool is_update_check_done(); + bool get_update_check_status(); + + bool is_update_download_done(); + bool get_update_download_status(); + + bool is_restart_required(); + + std::string get_last_error(); + std::string get_current_file(); + + void start_update_check(); + void start_update_download(); + void cancel_update(); +} \ No newline at end of file diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index def427e0..afa00d5d 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -7,6 +7,7 @@ #include "../../../component/ui_scripting.hpp" #include "../../../component/command.hpp" +#include "../../../component/updater.hpp" #include "component/game_console.hpp" #include "component/scheduler.hpp" @@ -141,12 +142,35 @@ namespace ui_scripting::lua state["LUI"] = state["luiglobals"]["LUI"]; state["Engine"] = state["luiglobals"]["Engine"]; state["Game"] = state["luiglobals"]["Game"]; + + auto updater_table = sol::table::create(state.lua_state()); + + updater_table["relaunch"] = updater::relaunch; + + updater_table["sethastriedupdate"] = updater::set_has_tried_update; + updater_table["gethastriedupdate"] = updater::get_has_tried_update; + updater_table["autoupdatesenabled"] = updater::auto_updates_enabled; + + updater_table["startupdatecheck"] = updater::start_update_check; + updater_table["isupdatecheckdone"] = updater::is_update_check_done; + updater_table["getupdatecheckstatus"] = updater::get_update_check_status; + updater_table["isupdateavailable"] = updater::is_update_available; + + updater_table["startupdatedownload"] = updater::start_update_download; + updater_table["isupdatedownloaddone"] = updater::is_update_download_done; + updater_table["getupdatedownloadstatus"] = updater::get_update_download_status; + updater_table["cancelupdate"] = updater::cancel_update; + updater_table["isrestartrequired"] = updater::is_restart_required; + + updater_table["getlasterror"] = updater::get_last_error; + updater_table["getcurrentfile"] = updater::get_current_file; + + state["updater"] = updater_table; } } - context::context(std::string folder) - : folder_(std::move(folder)) - , scheduler_(state_) + context::context(std::string data, script_type type) + : scheduler_(state_) { this->state_.open_libraries(sol::lib::base, sol::lib::package, @@ -156,27 +180,37 @@ namespace ui_scripting::lua sol::lib::math, sol::lib::table); - this->state_["include"] = [this](const std::string& file) - { - this->load_script(file); - }; - - sol::function old_require = this->state_["require"]; - auto base_path = utils::string::replace(this->folder_, "/", ".") + "."; - this->state_["require"] = [base_path, old_require](const std::string& path) - { - return old_require(base_path + path); - }; - - this->state_["scriptdir"] = [this]() - { - return this->folder_; - }; - setup_types(this->state_, this->scheduler_); - printf("Loading ui script '%s'\n", this->folder_.data()); - this->load_script("__init__"); + if (type == script_type::file) + { + this->folder_ = data; + + this->state_["include"] = [this](const std::string& file) + { + this->load_script(file); + }; + + sol::function old_require = this->state_["require"]; + auto base_path = utils::string::replace(this->folder_, "/", ".") + "."; + this->state_["require"] = [base_path, old_require](const std::string& path) + { + return old_require(base_path + path); + }; + + this->state_["scriptdir"] = [this]() + { + return this->folder_; + }; + + printf("Loading ui script '%s'\n", this->folder_.data()); + this->load_script("__init__"); + } + + if (type == script_type::code) + { + handle_error(this->state_.safe_script(data, &sol::script_pass_on_error)); + } } context::~context() diff --git a/src/client/game/ui_scripting/lua/context.hpp b/src/client/game/ui_scripting/lua/context.hpp index 0876d3df..866c601e 100644 --- a/src/client/game/ui_scripting/lua/context.hpp +++ b/src/client/game/ui_scripting/lua/context.hpp @@ -10,10 +10,16 @@ namespace ui_scripting::lua { + enum script_type + { + file, + code + }; + class context { public: - context(std::string folder); + context(std::string folder, script_type type); ~context(); context(context&&) noexcept = delete; diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index 7e6d7f6c..93713530 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -11,6 +11,9 @@ namespace ui_scripting::lua::engine { namespace { + const auto lui_common = utils::nt::load_resource(LUI_COMMON); + const auto lui_updater = utils::nt::load_resource(LUI_UPDATER); + auto& get_scripts() { static std::vector> scripts{}; @@ -30,16 +33,25 @@ namespace ui_scripting::lua::engine { if (std::filesystem::is_directory(script) && utils::io::file_exists(script + "/__init__.lua")) { - get_scripts().push_back(std::make_unique(script)); + get_scripts().push_back(std::make_unique(script, script_type::file)); } } } + + void load_code(const std::string& code) + { + get_scripts().push_back(std::make_unique(code, script_type::code)); + } } void start() { clear_converted_functions(); get_scripts().clear(); + + load_code(lui_common); + load_code(lui_updater); + load_scripts(game_module::get_host_module().get_folder() + "/data/ui_scripts/"); load_scripts("h1-mod/ui_scripts/"); load_scripts("data/ui_scripts/"); diff --git a/src/client/resource.hpp b/src/client/resource.hpp index f80f9b48..adc92d9c 100644 --- a/src/client/resource.hpp +++ b/src/client/resource.hpp @@ -15,3 +15,6 @@ #define RUNNER 307 #define ICON_IMAGE 308 + +#define LUI_COMMON 309 +#define LUI_UPDATER 310 diff --git a/src/client/resource.rc b/src/client/resource.rc index 6866f241..c53c106a 100644 --- a/src/client/resource.rc +++ b/src/client/resource.rc @@ -118,6 +118,9 @@ RUNNER RCDATA "../../build/bin/x64/Release/runner.exe" ICON_IMAGE RCDATA "resources/icon.png" +LUI_COMMON RCDATA "resources/ui_scripts/common.lua" +LUI_UPDATER RCDATA "resources/ui_scripts/updater.lua" + #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/client/resources/ui_scripts/common.lua b/src/client/resources/ui_scripts/common.lua new file mode 100644 index 00000000..8f68e96d --- /dev/null +++ b/src/client/resources/ui_scripts/common.lua @@ -0,0 +1,164 @@ +menucallbacks = {} +originalmenus = {} +stack = {} + +LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event) + local oncancel = stack.oncancel + local popup = LUI.MenuBuilder.BuildRegisteredType("waiting_popup", { + message_text = stack.text, + isLiveWithCancel = true, + cancel_func = function(...) + local args = {...} + oncancel() + LUI.FlowManager.RequestLeaveMenu(args[1]) + end + }) + + local listchildren = popup:getChildById("LUIHorizontalList"):getchildren() + local children = listchildren[2]:getchildren() + popup.text = children[2] + + stack = { + ret = popup + } + + return popup +end + +LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function() + local callback = stack.callback + local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", { + popup_title = stack.title, + message_text = stack.text, + yes_action = function() + callback(true) + end, + no_action = function() + callback(false) + end + }) + + stack = { + ret = popup + } + + return popup +end + +LUI.MenuBuilder.m_types_build["generic_confirmation_popup_"] = function() + local popup = LUI.MenuBuilder.BuildRegisteredType( "generic_confirmation_popup", { + cancel_will_close = false, + popup_title = stack.title, + message_text = stack.text, + button_text = stack.buttontext, + confirmation_action = stack.callback + }) + + stack = { + ret = popup + } + + return stack.ret +end + +LUI.onmenuopen = function(name, callback) + if (not LUI.MenuBuilder.m_types_build[name]) then + return + end + + if (not menucallbacks[name]) then + menucallbacks[name] = {} + end + + table.insert(menucallbacks[name], callback) + + if (not originalmenus[name]) then + originalmenus[name] = LUI.MenuBuilder.m_types_build[name] + LUI.MenuBuilder.m_types_build[name] = function(...) + local args = {...} + local menu = originalmenus[name](table.unpack(args)) + + for k, v in luiglobals.next, menucallbacks[name] do + v(menu, table.unpack(args)) + end + + return menu + end + end +end + +local addoptionstextinfo = LUI.Options.AddOptionTextInfo +LUI.Options.AddOptionTextInfo = function(menu) + local result = addoptionstextinfo(menu) + menu.optionTextInfo = result + return result +end + +LUI.addmenubutton = function(name, data) + LUI.onmenuopen(name, function(menu) + if (not menu.list) then + return + end + + local button = menu:AddButton(data.text, data.callback, nil, true, nil, { + desc_text = data.description + }) + + local buttonlist = menu:getChildById(menu.type .. "_list") + + if (data.id) then + button.id = data.id + end + + if (data.index) then + buttonlist:removeElement(button) + buttonlist:insertElement(button, data.index) + end + + local hintbox = menu.optionTextInfo + menu:removeElement(hintbox) + + LUI.Options.InitScrollingList(menu.list, nil) + menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) + end) +end + +LUI.openmenu = function(menu, args) + stack = args + LUI.FlowManager.RequestAddMenu(nil, menu) + return stack.ret +end + +LUI.openpopupmenu = function(menu, args) + stack = args + LUI.FlowManager.RequestPopupMenu(nil, menu) + return stack.ret +end + +LUI.yesnopopup = function(data) + for k, v in luiglobals.next, data do + stack[k] = v + end + LUI.FlowManager.RequestPopupMenu(nil, "generic_yes_no_popup_") + return stack.ret +end + +LUI.confirmationpopup = function(data) + for k, v in luiglobals.next, data do + stack[k] = v + end + LUI.FlowManager.RequestPopupMenu(nil, "generic_confirmation_popup_") + return stack.ret +end + +function userdata_:getchildren() + local children = {} + local first = self:getFirstChild() + + while (first) do + table.insert(children, first) + first = first:getNextSibling() + end + + return children +end diff --git a/src/client/resources/ui_scripts/updater.lua b/src/client/resources/ui_scripts/updater.lua new file mode 100644 index 00000000..21d289d4 --- /dev/null +++ b/src/client/resources/ui_scripts/updater.lua @@ -0,0 +1,156 @@ +updatecancelled = false +taskinterval = 100 + +function startupdatecheck(popup, autoclose) + updatecancelled = false + + local callback = function() + if (not updater.getupdatecheckstatus()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end + + popup.text:setText("Error: " .. updater.getlasterror()) + return + end + + if (not updater.isupdateavailable()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end + + popup.text:setText("No updates available") + return + end + + LUI.yesnopopup({ + title = "NOTICE", + text = "An update is available, proceed with installation?", + callback = function(result) + if (result) then + startupdatedownload(popup, autoclose) + else + LUI.FlowManager.RequestLeaveMenu(popup) + end + end + }) + end + + updater.startupdatecheck() + createtask({ + done = updater.isupdatecheckdone, + cancelled = isupdatecancelled, + callback = callback, + interval = taskinterval + }) +end + +function startupdatedownload(popup, autoclose) + updater.startupdatedownload() + + local textupdate = nil + local previousfile = nil + textupdate = game:oninterval(function() + local file = updater.getcurrentfile() + if (file == previousfile) then + return + end + + file = previousfile + popup.text:setText("Downloading file " .. updater.getcurrentfile() .. "...") + end, 10) + + local callback = function() + textupdate:clear() + + if (not updater.getupdatedownloadstatus()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end + + popup.text:setText("Error: " .. updater.getlasterror()) + return + end + + popup.text:setText("Update successful") + + if (updater.isrestartrequired()) then + LUI.confirmationpopup({ + title = "RESTART REQUIRED", + text = "Update requires restart", + buttontext = "RESTART", + callback = function() + updater.relaunch() + end + })-- + end + + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + end + end + + createtask({ + done = updater.isupdatedownloaddone, + cancelled = isupdatecancelled, + callback = callback, + interval = taskinterval + }) +end + +function updaterpopup(oncancel) + return LUI.openpopupmenu("generic_waiting_popup_", { + oncancel = oncancel, + withcancel = true, + text = "Checking for updates..." + }) +end + +function createtask(data) + local interval = nil + interval = game:oninterval(function() + if (data.cancelled()) then + interval:clear() + return + end + + if (data.done()) then + interval:clear() + data.callback() + end + end, data.interval) + return interval +end + +function isupdatecancelled() + return updatecancelled +end + +function tryupdate(autoclose) + updatecancelled = false + local popup = updaterpopup(function() + updater.cancelupdate() + updatecancelled = true + end) + + startupdatecheck(popup, autoclose) +end + +function tryautoupdate() + if (not updater.autoupdatesenabled()) then + return + end + + if (not updater.gethastriedupdate()) then + game:ontimeout(function() + updater.sethastriedupdate(true) + tryupdate(true) + end, 100) + end +end + +LUI.onmenuopen("mp_main_menu", tryautoupdate) +LUI.onmenuopen("main_lockout", tryautoupdate) \ No newline at end of file From b08b5311deb0b7470a1d243d7dba5641ab852041 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 4 Mar 2022 01:47:06 +0100 Subject: [PATCH 026/346] Small fix --- data/ui_scripts/server_list/__init__.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/ui_scripts/server_list/__init__.lua b/data/ui_scripts/server_list/__init__.lua index 40ef8d17..94df0df8 100644 --- a/data/ui_scripts/server_list/__init__.lua +++ b/data/ui_scripts/server_list/__init__.lua @@ -1,2 +1,6 @@ +if (not LUI.mp_menus) then + return +end + require("lobby") require("serverlist") From b0a572186ce55195a38b286be3513ffa1c43d452 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 4 Mar 2022 01:59:08 +0100 Subject: [PATCH 027/346] Fix updater cache --- src/client/component/updater.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp index 512b619b..939dbd1c 100644 --- a/src/client/component/updater.cpp +++ b/src/client/component/updater.cpp @@ -139,9 +139,14 @@ namespace updater return name; } + std::string get_time_str() + { + return utils::string::va("%i", uint32_t(time(nullptr))); + } + std::optional download_file(const std::string& name) { - return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name); + return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name + "?" + get_time_str()); } bool is_update_cancelled() @@ -331,7 +336,7 @@ namespace updater scheduler::once([]() { - const auto files_data = utils::http::get_data(MASTER + select(FILES_PATH, FILES_PATH_DEV)); + const auto files_data = utils::http::get_data(MASTER + select(FILES_PATH, FILES_PATH_DEV) + "?" + get_time_str()); if (is_update_cancelled()) { From 82896a0a3d4dc80f84e6fd6a1050c19d0698444d Mon Sep 17 00:00:00 2001 From: fed <58637860+fedddddd@users.noreply.github.com> Date: Fri, 4 Mar 2022 09:26:58 +0100 Subject: [PATCH 028/346] Small fix --- src/client/resources/ui_scripts/updater.lua | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/client/resources/ui_scripts/updater.lua b/src/client/resources/ui_scripts/updater.lua index 21d289d4..b8ee7808 100644 --- a/src/client/resources/ui_scripts/updater.lua +++ b/src/client/resources/ui_scripts/updater.lua @@ -1,6 +1,8 @@ updatecancelled = false taskinterval = 100 +updater.cancelupdate() + function startupdatecheck(popup, autoclose) updatecancelled = false @@ -85,12 +87,18 @@ function startupdatedownload(popup, autoclose) callback = function() updater.relaunch() end - })-- + }) end - + if (autoclose) then LUI.FlowManager.RequestLeaveMenu(popup) end + + if (LUI.mp_menus) then + Engine.Exec("lui_restart; lui_open mp_main_menu") + else + Engine.Exec("lui_restart") + end end createtask({ From 5ae5e711f2e67e84133b55f20cafde504b7e6d0d Mon Sep 17 00:00:00 2001 From: fed <58637860+fedddddd@users.noreply.github.com> Date: Fri, 4 Mar 2022 10:38:06 +0100 Subject: [PATCH 029/346] Small fix --- src/client/resources/ui_scripts/updater.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client/resources/ui_scripts/updater.lua b/src/client/resources/ui_scripts/updater.lua index b8ee7808..01d77360 100644 --- a/src/client/resources/ui_scripts/updater.lua +++ b/src/client/resources/ui_scripts/updater.lua @@ -88,17 +88,17 @@ function startupdatedownload(popup, autoclose) updater.relaunch() end }) + else + if (LUI.mp_menus) then + Engine.Exec("lui_restart; lui_open mp_main_menu") + else + Engine.Exec("lui_restart") + end end if (autoclose) then LUI.FlowManager.RequestLeaveMenu(popup) end - - if (LUI.mp_menus) then - Engine.Exec("lui_restart; lui_open mp_main_menu") - else - Engine.Exec("lui_restart") - end end createtask({ From 2261c68b5b3239dc92043c3ed1f80f34c12a799f Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 4 Mar 2022 20:46:09 +0100 Subject: [PATCH 030/346] Update function tables + bots --- src/client/component/bots.cpp | 21 +- src/client/component/renderer.cpp | 2 +- src/client/game/scripting/function_tables.cpp | 1256 ++++++++--------- 3 files changed, 638 insertions(+), 641 deletions(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index e9a25628..81f74628 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -7,6 +7,7 @@ #include "party.hpp" #include "game/game.hpp" +#include "game/scripting/execution.hpp" #include #include @@ -28,20 +29,16 @@ namespace bots // TODO: when scripting comes, fix this to use better notifies void bot_team_join(const int entity_num) { - scheduler::once([entity_num]() + const game::scr_entref_t entref{static_cast(entity_num), 0}; + scheduler::once([entref]() { - game::SV_ExecuteClientCommand(&game::mp::svs_clients[entity_num], - utils::string::va("lui 68 2 %i", *game::mp::sv_serverId_value), - false); - - // scheduler the select class call - scheduler::once([entity_num]() + scripting::notify(entref, "luinotifyserver", {"team_select", 2}); + scheduler::once([entref]() { - game::SV_ExecuteClientCommand(&game::mp::svs_clients[entity_num], - utils::string::va("lui 5 %i %i", (rand() % 5) + 10, - *game::mp::sv_serverId_value), false); - }, scheduler::pipeline::server, 1s); - }, scheduler::pipeline::server, 1s); + auto* _class = utils::string::va("class%d", utils::cryptography::random::get_integer() % 5); + scripting::notify(entref, "luinotifyserver", {"class_select", _class}); + }, scheduler::pipeline::server, 2s); + }, scheduler::pipeline::server, 2s); } void spawn_bot(const int entity_num) diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp index f782b3b7..b315be76 100644 --- a/src/client/component/renderer.cpp +++ b/src/client/component/renderer.cpp @@ -35,7 +35,7 @@ namespace renderer { if (dvars::r_fullbright->modified) { - game::Dvar_ClearModified(dvars::r_fullbright); + //game::Dvar_ClearModified(dvars::r_fullbright); game::R_SyncRenderThread(); gfxdrawmethod(); diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index db1cead0..9a70a9dd 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -10,7 +10,7 @@ namespace scripting std::unordered_map function_map = { {"_func_001", 0x001}, // SP 0x14029D940 MP 0x140368EA0 - {"_func_002", 0x002}, // SP 0x14028F750 MP 0x140357B80 + {"getweaponarray", 0x002}, // SP 0x14028F750 MP 0x140357B80 {"_func_003", 0x003}, // SP 0x1405D92F0 MP 0x1403668A0 {"_func_004", 0x004}, // SP 0x1402ACD70 MP 0x000000000 {"_func_005", 0x005}, // SP 0x1402ADB70 MP 0x000000000 @@ -32,17 +32,17 @@ namespace scripting {"_func_015", 0x015}, // SP 0x1405D92F0 MP 0x1403675E0 {"_func_016", 0x016}, // SP 0x1405D92F0 MP 0x140367660 {"_func_017", 0x017}, // SP 0x1405D92F0 MP 0x140367890 - {"_func_018", 0x018}, // SP 0x14029D650 MP 0x140368B10 - {"_func_019", 0x019}, // SP 0x14029D870 MP 0x140368E80 + {"spawnturret", 0x018}, // SP 0x14029D650 MP 0x140368B10 + {"canspawnturret", 0x019}, // SP 0x14029D870 MP 0x140368E80 {"_func_01A", 0x01A}, // SP 0x14029C9B0 MP 0x1403678A0 {"_func_01B", 0x01B}, // SP 0x1402AB640 MP 0x000000000 {"_func_01C", 0x01C}, // SP 0x1402AB670 MP 0x000000000 {"_func_01D", 0x01D}, // SP 0x1402AB7A0 MP 0x000000000 {"_func_01E", 0x01E}, // SP 0x1402AB960 MP 0x000000000 - {"_func_01F", 0x01F}, // SP 0x14028F340 MP 0x140358600 - {"_func_020", 0x020}, // SP 0x14028F4B0 MP 0x140358C50 - {"_func_021", 0x021}, // SP 0x14028F830 MP 0x140359110 - {"_func_022", 0x022}, // SP 0x14028FF10 MP 0x140359CB0 + {"badplace_delete", 0x01F}, // SP 0x14028F340 MP 0x140358600 + {"badplace_cylinder", 0x020}, // SP 0x14028F4B0 MP 0x140358C50 + {"badplace_arc", 0x021}, // SP 0x14028F830 MP 0x140359110 + {"badplace_brush", 0x022}, // SP 0x14028FF10 MP 0x140359CB0 {"_func_023", 0x023}, // SP 0x1402AC9D0 MP 0x000000000 {"_func_024", 0x024}, // SP 0x1402CC640 MP 0x000000000 {"_func_025", 0x025}, // SP 0x1402CC6E0 MP 0x000000000 @@ -53,24 +53,24 @@ namespace scripting {"_func_02C", 0x02C}, // SP 0x1402ACD10 MP 0x000000000 {"_func_02D", 0x02D}, // SP 0x14029C9B0 MP 0x140367950 {"_func_02E", 0x02E}, // SP 0x14029CAC0 MP 0x140367980 - {"_func_02F", 0x02F}, // SP 0x14029D000 MP 0x140368520 - {"_func_030", 0x030}, // SP 0x14029D3E0 MP 0x140368A70 + {"isdefined", 0x02F}, // SP 0x14029D000 MP 0x140368520 + {"isvalidmissile", 0x030}, // SP 0x14029D3E0 MP 0x140368A70 {"_func_031", 0x031}, // SP 0x14029D630 MP 0x140368D30 {"_func_032", 0x032}, // SP 0x14029E0A0 MP 0x14036A580 {"_func_033", 0x033}, // SP 0x14029E220 MP 0x14036A7C0 - {"_func_034", 0x034}, // SP 0x14029EB20 MP 0x14036AE70 + {"setdynamicdvar", 0x034}, // SP 0x14029EB20 MP 0x14036AE70 {"_func_035", 0x035}, // SP 0x000000000 MP 0x14036B600 {"_func_036", 0x036}, // SP 0x14029F8F0 MP 0x14036BB60 - {"_func_037", 0x037}, // SP 0x14029F1C0 MP 0x14036B7F0 + {"setdvar", 0x037}, // SP 0x14029F1C0 MP 0x14036B7F0 {"_func_038", 0x038}, // SP 0x14029F8F0 MP 0x14036C070 - {"_func_039", 0x039}, // SP 0x14029FE30 MP 0x14036C350 - {"_func_03A", 0x03A}, // SP 0x1402A0270 MP 0x14036C7B0 - {"_func_03B", 0x03B}, // SP 0x1402A0810 MP 0x14036CDD0 - {"_func_03C", 0x03C}, // SP 0x1402A10E0 MP 0x14036D190 + {"getdvar", 0x039}, // SP 0x14029FE30 MP 0x14036C350 + {"getdvarint", 0x03A}, // SP 0x1402A0270 MP 0x14036C7B0 + {"getdvarfloat", 0x03B}, // SP 0x1402A0810 MP 0x14036CDD0 + {"getdvarvector", 0x03C}, // SP 0x1402A10E0 MP 0x14036D190 {"_func_03D", 0x03D}, // SP 0x1402A1A50 MP 0x14036DB40 {"_func_03E", 0x03E}, // SP 0x1402A1A60 MP 0x14036DD80 {"_func_03F", 0x03F}, // SP 0x1402A1AC0 MP 0x14036DDA0 - {"_func_040", 0x040}, // SP 0x1402A1C50 MP 0x14036DF50 + {"getentbynum", 0x040}, // SP 0x1402A1C50 MP 0x14036DF50 {"_func_041", 0x041}, // SP 0x1402A1D10 MP 0x000000000 {"_func_042", 0x042}, // SP 0x1402A1D20 MP 0x000000000 {"_func_043", 0x043}, // SP 0x1402A1D30 MP 0x14036E110 @@ -105,13 +105,13 @@ namespace scripting {"_func_060", 0x060}, // SP 0x1402A2910 MP 0x14036ED60 {"_func_061", 0x061}, // SP 0x1402A3170 MP 0x14036F3E0 {"_func_062", 0x062}, // SP 0x1402A34D0 MP 0x140357CA0 - {"_func_063", 0x063}, // SP 0x14028DEA0 MP 0x140358890 + {"getweaponreticlename", 0x063}, // SP 0x14028DEA0 MP 0x140358890 {"_func_064", 0x064}, // SP 0x14028E0B0 MP 0x140358B80 - {"_func_065", 0x065}, // SP 0x14028FB80 MP 0x14035AB80 - {"_func_066", 0x066}, // SP 0x14028FD60 MP 0x14035B110 - {"_func_067", 0x067}, // SP 0x14028FDC0 MP 0x14035B220 - {"_func_068", 0x068}, // SP 0x14029D0C0 MP 0x140368410 - {"_func_069", 0x069}, // SP 0x14029D0C0 MP 0x140368410 + {"getanimlength", 0x065}, // SP 0x14028FB80 MP 0x14035AB80 + {"animhasnotetrack", 0x066}, // SP 0x14028FD60 MP 0x14035B110 + {"getnotetracktimes", 0x067}, // SP 0x14028FDC0 MP 0x14035B220 + {"spawn", 0x068}, // SP 0x14029D0C0 MP 0x140368410 + {"spawnloopsound", 0x069}, // SP 0x14029D0C0 MP 0x140368410 {"_func_06A", 0x06A}, // SP 0x140444BB0 MP 0x14036AF90 {"_func_06B", 0x06B}, // SP 0x14029E950 MP 0x140366EF0 {"_func_06C", 0x06C}, // SP 0x1402BBCA0 MP 0x000000000 @@ -146,14 +146,14 @@ namespace scripting {"_func_08A", 0x08A}, // SP 0x1402A9A70 MP 0x000000000 {"_func_08B", 0x08B}, // SP 0x1402AB690 MP 0x000000000 {"_func_08C", 0x08C}, // SP 0x1402ABB90 MP 0x000000000 - {"_func_08D", 0x08D}, // SP 0x14029F480 MP 0x140367410 + {"bullettracepassed", 0x08D}, // SP 0x14029F480 MP 0x140367410 {"_func_08E", 0x08E}, // SP 0x14029F7A0 MP 0x140367670 {"_func_08F", 0x08F}, // SP 0x14029FF90 MP 0x140367E20 {"_func_090", 0x090}, // SP 0x1402A0360 MP 0x140368180 {"_func_091", 0x091}, // SP 0x1402A2670 MP 0x14036A300 - {"_func_092", 0x092}, // SP 0x14028F3D0 MP 0x14036E210 - {"_func_093", 0x093}, // SP 0x14028FA60 MP 0x14036E910 - {"_func_094", 0x094}, // SP 0x1402903E0 MP 0x140357C50 + {"getangledelta", 0x092}, // SP 0x14028F3D0 MP 0x14036E210 + {"getangledelta3d", 0x093}, // SP 0x14028FA60 MP 0x14036E910 + {"getnorthyaw", 0x094}, // SP 0x1402903E0 MP 0x140357C50 {"_func_095", 0x095}, // SP 0x1402A7970 MP 0x000000000 {"_func_096", 0x096}, // SP 0x1402A7A50 MP 0x000000000 {"_func_097", 0x097}, // SP 0x1402A9B20 MP 0x000000000 @@ -182,27 +182,27 @@ namespace scripting {"_func_0AE", 0x0AE}, // SP 0x1402BB1C0 MP 0x000000000 {"_func_0AF", 0x0AF}, // SP 0x1402BBDB0 MP 0x000000000 {"_func_0B0", 0x0B0}, // SP 0x140290420 MP 0x140357E90 - {"_func_0B1", 0x0B1}, // SP 0x14029BC60 MP 0x140365480 - {"_func_0B2", 0x0B2}, // SP 0x1402A2ED0 MP 0x14036A770 - {"_func_0B3", 0x0B3}, // SP 0x1402A3140 MP 0x14036A9E0 - {"_func_0B4", 0x0B4}, // SP 0x1402A3240 MP 0x14036ACD0 - {"_func_0B5", 0x0B5}, // SP 0x1402A3310 MP 0x14036AE10 - {"_func_0B6", 0x0B6}, // SP 0x1402A3440 MP 0x14036B240 - {"_func_0B7", 0x0B7}, // SP 0x1402A34A0 MP 0x14036B550 - {"_func_0B8", 0x0B8}, // SP 0x1402A3610 MP 0x14036B5A0 - {"_func_0B9", 0x0B9}, // SP 0x1402A37D0 MP 0x14036B720 - {"_func_0BA", 0x0BA}, // SP 0x1402A3A60 MP 0x14036B7A0 - {"_func_0BB", 0x0BB}, // SP 0x14028D680 MP 0x14036BAE0 - {"_func_0BC", 0x0BC}, // SP 0x14028DAE0 MP 0x14036BBF0 - {"_func_0BD", 0x0BD}, // SP 0x14028DE30 MP 0x14036C000 - {"_func_0BE", 0x0BE}, // SP 0x14028DFC0 MP 0x14036C320 + {"setslowmotion", 0x0B1}, // SP 0x14029BC60 MP 0x140365480 + {"randomint", 0x0B2}, // SP 0x1402A2ED0 MP 0x14036A770 + {"randomfloat", 0x0B3}, // SP 0x1402A3140 MP 0x14036A9E0 + {"randomintrange", 0x0B4}, // SP 0x1402A3240 MP 0x14036ACD0 + {"randomfloatrange", 0x0B5}, // SP 0x1402A3310 MP 0x14036AE10 + {"sin", 0x0B6}, // SP 0x1402A3440 MP 0x14036B240 + {"cos", 0x0B7}, // SP 0x1402A34A0 MP 0x14036B550 + {"tan", 0x0B8}, // SP 0x1402A3610 MP 0x14036B5A0 + {"asin", 0x0B9}, // SP 0x1402A37D0 MP 0x14036B720 + {"acos", 0x0BA}, // SP 0x1402A3A60 MP 0x14036B7A0 + {"atan", 0x0BB}, // SP 0x14028D680 MP 0x14036BAE0 + {"int", 0x0BC}, // SP 0x14028DAE0 MP 0x14036BBF0 + {"float", 0x0BD}, // SP 0x14028DE30 MP 0x14036C000 + {"abs", 0x0BE}, // SP 0x14028DFC0 MP 0x14036C320 {"_func_0BF", 0x0BF}, // SP 0x14028DFF0 MP 0x14036C580 {"_func_0C0", 0x0C0}, // SP 0x1402B7A30 MP 0x000000000 {"_func_0C1", 0x0C1}, // SP 0x1402B7B50 MP 0x000000000 {"_func_0C2", 0x0C2}, // SP 0x1402B7BF0 MP 0x000000000 - {"_func_0C3", 0x0C3}, // SP 0x1402CBED0 MP 0x14031FA00 - {"_func_0C4", 0x0C4}, // SP 0x1402CBFE0 MP 0x14031FB10 - {"_func_0C5", 0x0C5}, // SP 0x1402CBCD0 MP 0x14031F7E0 + {"getnode", 0x0C3}, // SP 0x1402CBED0 MP 0x14031FA00 + {"getnodearray", 0x0C4}, // SP 0x1402CBFE0 MP 0x14031FB10 + {"getallnodes", 0x0C5}, // SP 0x1402CBCD0 MP 0x14031F7E0 {"_func_0C6", 0x0C6}, // SP 0x1402CC0F0 MP 0x14031FCC0 {"_func_0C7", 0x0C7}, // SP 0x1402CC100 MP 0x14031FCD0 {"_func_0C8", 0x0C8}, // SP 0x1402CBD20 MP 0x14031F830 @@ -211,10 +211,10 @@ namespace scripting {"_func_0CB", 0x0CB}, // SP 0x140468CF0 MP 0x000000000 {"_func_0CC", 0x0CC}, // SP 0x140468DD0 MP 0x000000000 {"_func_0CD", 0x0CD}, // SP 0x140468CA0 MP 0x000000000 - {"_func_0CE", 0x0CE}, // SP 0x140291BF0 MP 0x14035E620 - {"_func_0CF", 0x0CF}, // SP 0x1402ADC10 MP 0x140377460 - {"_func_0D0", 0x0D0}, // SP 0x14029DB50 MP 0x140369C50 - {"_func_0D1", 0x0D1}, // SP 0x14029D7D0 MP 0x140368DA0 + {"isarray", 0x0CE}, // SP 0x140291BF0 MP 0x14035E620 + {"isai", 0x0CF}, // SP 0x1402ADC10 MP 0x140377460 + {"getindexforluincstring", 0x0D0}, // SP 0x14029DB50 MP 0x140369C50 + {"issentient", 0x0D1}, // SP 0x14029D7D0 MP 0x140368DA0 {"_func_0D2", 0x0D2}, // SP 0x1402ADD90 MP 0x000000000 {"_func_0D3", 0x0D3}, // SP 0x1402ADED0 MP 0x000000000 {"_func_0D4", 0x0D4}, // SP 0x1402ADF60 MP 0x000000000 @@ -231,18 +231,18 @@ namespace scripting {"_func_0DF", 0x0DF}, // SP 0x14029CAC0 MP 0x000000000 {"_func_0E0", 0x0E0}, // SP 0x1402A7830 MP 0x000000000 {"_func_0E1", 0x0E1}, // SP 0x14028E170 MP 0x14036C720 - {"_func_0E2", 0x0E2}, // SP 0x14028E1C0 MP 0x14036C750 - {"_func_0E3", 0x0E3}, // SP 0x14028E260 MP 0x14036C770 - {"_func_0E4", 0x0E4}, // SP 0x14028E280 MP 0x14036C790 - {"_func_0E5", 0x0E5}, // SP 0x14028E370 MP 0x14036C820 - {"_func_0E6", 0x0E6}, // SP 0x14028E410 MP 0x14036C840 - {"_func_0E7", 0x0E7}, // SP 0x14028E470 MP 0x14036CB80 - {"_func_0E8", 0x0E8}, // SP 0x14028E4B0 MP 0x14036CBA0 + {"floor", 0x0E2}, // SP 0x14028E1C0 MP 0x14036C750 + {"ceil", 0x0E3}, // SP 0x14028E260 MP 0x14036C770 + {"exp", 0x0E4}, // SP 0x14028E280 MP 0x14036C790 + {"exp", 0x0E5}, // SP 0x14028E370 MP 0x14036C820 + {"log", 0x0E6}, // SP 0x14028E410 MP 0x14036C840 + {"sqrt", 0x0E7}, // SP 0x14028E470 MP 0x14036CB80 + {"squared", 0x0E8}, // SP 0x14028E4B0 MP 0x14036CBA0 {"_func_0E9", 0x0E9}, // SP 0x14028E770 MP 0x14036CE40 {"_func_0EA", 0x0EA}, // SP 0x14028E8C0 MP 0x14036CF30 - {"_func_0EB", 0x0EB}, // SP 0x14028E920 MP 0x14036CFB0 - {"_func_0EC", 0x0EC}, // SP 0x140290740 MP 0x14036E5A0 - {"_func_0ED", 0x0ED}, // SP 0x140290B60 MP 0x14036EB30 + {"angleclamp180", 0x0EB}, // SP 0x14028E920 MP 0x14036CFB0 + {"vectorfromlinetopoint", 0x0EC}, // SP 0x140290740 MP 0x14036E5A0 + {"pointonsegmentnearesttopoint", 0x0ED}, // SP 0x140290B60 MP 0x14036EB30 {"_func_0EE", 0x0EE}, // SP 0x140291260 MP 0x14036F6E0 {"_func_0EF", 0x0EF}, // SP 0x1402913A0 MP 0x14036F790 {"_func_0F0", 0x0F0}, // SP 0x140291600 MP 0x140357E10 @@ -253,84 +253,84 @@ namespace scripting {"_func_0F5", 0x0F5}, // SP 0x140291C20 MP 0x1403581E0 {"_func_0F6", 0x0F6}, // SP 0x140291EB0 MP 0x140358570 {"_func_0F7", 0x0F7}, // SP 0x140291F80 MP 0x140358640 - {"_func_0F8", 0x0F8}, // SP 0x140292690 MP 0x140359050 + {"axistoangles", 0x0F8}, // SP 0x140292690 MP 0x140359050 {"_func_0F9", 0x0F9}, // SP 0x1402ABB50 MP 0x1403771E0 {"_func_0FA", 0x0FA}, // SP 0x1402ABB60 MP 0x140377260 {"_func_0FB", 0x0FB}, // SP 0x000000000 MP 0x14037B950 {"_func_0FC", 0x0FC}, // SP 0x000000000 MP 0x140374E10 - {"_func_0FD", 0x0FD}, // SP 0x000000000 MP 0x140378260 + {"getmapcustom", 0x0FD}, // SP 0x000000000 MP 0x140378260 {"_func_0FE", 0x0FE}, // SP 0x000000000 MP 0x1403765A0 - {"_func_0FF", 0x0FF}, // SP 0x1402AE370 MP 0x140374FE0 - {"_func_100", 0x100}, // SP 0x1402AE3C0 MP 0x140375100 + {"incrementcounter", 0x0FF}, // SP 0x1402AE370 MP 0x140374FE0 + {"getcountertotal", 0x100}, // SP 0x1402AE3C0 MP 0x140375100 {"_func_101", 0x101}, // SP 0x1402A1AE0 MP 0x000000000 {"_func_102", 0x102}, // SP 0x14028E970 MP 0x000000000 {"_func_103", 0x103}, // SP 0x14028ED80 MP 0x000000000 {"_func_104", 0x104}, // SP 0x1405D92F0 MP 0x14042C2C0 {"_func_105", 0x105}, // SP 0x1405D92F0 MP 0x14042C2D0 {"_func_106", 0x106}, // SP 0x14028D7F0 MP 0x000000000 - {"_func_107", 0x107}, // SP 0x1402D79E0 MP 0x1400774E0 - {"_func_108", 0x108}, // SP 0x1402D7A10 MP 0x140077510 - {"_func_109", 0x109}, // SP 0x1402D7A50 MP 0x140077550 - {"_func_10A", 0x10A}, // SP 0x1402D7AB0 MP 0x1400775B0 - {"_func_10B", 0x10B}, // SP 0x1402D7B30 MP 0x140077630 - {"_func_10C", 0x10C}, // SP 0x1402D7B80 MP 0x140077680 - {"_func_10D", 0x10D}, // SP 0x1402D7CC0 MP 0x140077820 + {"createthreatbiasgroup", 0x107}, // SP 0x1402D79E0 MP 0x1400774E0 + {"threatbiasgroupexists", 0x108}, // SP 0x1402D7A10 MP 0x140077510 + {"getthreatbias", 0x109}, // SP 0x1402D7A50 MP 0x140077550 + {"setthreatbias", 0x10A}, // SP 0x1402D7AB0 MP 0x1400775B0 + {"setthreatbiasagainstall", 0x10B}, // SP 0x1402D7B30 MP 0x140077630 + {"setignoremegroup", 0x10C}, // SP 0x1402D7B80 MP 0x140077680 + {"isenemyteam", 0x10D}, // SP 0x1402D7CC0 MP 0x140077820 {"_func_10E", 0x10E}, // SP 0x1402B7530 MP 0x000000000 {"_func_10F", 0x10F}, // SP 0x1402B77F0 MP 0x000000000 {"_func_110", 0x110}, // SP 0x1402B7800 MP 0x000000000 {"_func_111", 0x111}, // SP 0x1402B7810 MP 0x000000000 {"_func_112", 0x112}, // SP 0x1402B79C0 MP 0x000000000 {"_func_113", 0x113}, // SP 0x1402B7A20 MP 0x000000000 - {"_func_114", 0x114}, // SP 0x140292150 MP 0x1403587A0 - {"_func_115", 0x115}, // SP 0x140292290 MP 0x140358A90 - {"_func_116", 0x116}, // SP 0x1402924D0 MP 0x140358B10 - {"_func_117", 0x117}, // SP 0x140292510 MP 0x140358E60 - {"_func_118", 0x118}, // SP 0x140292C80 MP 0x1403596E0 + {"vectornormalize", 0x114}, // SP 0x140292150 MP 0x1403587A0 + {"vectortoangles", 0x115}, // SP 0x140292290 MP 0x140358A90 + {"vectortoyaw", 0x116}, // SP 0x1402924D0 MP 0x140358B10 + {"vectorlerp", 0x117}, // SP 0x140292510 MP 0x140358E60 + {"anglestoup", 0x118}, // SP 0x140292C80 MP 0x1403596E0 {"_func_119", 0x119}, // SP 0x140292D50 MP 0x140359890 {"_func_11A", 0x11A}, // SP 0x140292F80 MP 0x140359930 - {"_func_11B", 0x11B}, // SP 0x1402930E0 MP 0x140359BC0 + {"anglesdelta", 0x11B}, // SP 0x1402930E0 MP 0x140359BC0 {"_func_11C", 0x11C}, // SP 0x1402934C0 MP 0x14035A0F0 {"_func_11D", 0x11D}, // SP 0x140293670 MP 0x14035A280 {"_func_11E", 0x11E}, // SP 0x1402956B0 MP 0x14035B550 {"_func_11F", 0x11F}, // SP 0x140295850 MP 0x14035B7F0 - {"_func_120", 0x120}, // SP 0x140296960 MP 0x14035CB70 - {"_func_121", 0x121}, // SP 0x1402969A0 MP 0x14035CD40 - {"_func_122", 0x122}, // SP 0x140296BB0 MP 0x14035CF80 - {"_func_123", 0x123}, // SP 0x140296DC0 MP 0x14035D360 + {"issubstr", 0x120}, // SP 0x140296960 MP 0x14035CB70 + {"isendstr", 0x121}, // SP 0x1402969A0 MP 0x14035CD40 + {"getsubstr", 0x122}, // SP 0x140296BB0 MP 0x14035CF80 + {"tolower", 0x123}, // SP 0x140296DC0 MP 0x14035D360 {"_func_124", 0x124}, // SP 0x140297230 MP 0x14035DA90 {"_func_125", 0x125}, // SP 0x140297970 MP 0x14035E690 {"_func_126", 0x126}, // SP 0x14029FA50 MP 0x1403679A0 - {"_func_127", 0x127}, // SP 0x000000000 MP 0x14037B790 - {"_func_128", 0x128}, // SP 0x000000000 MP 0x14037B7A0 - {"_func_129", 0x129}, // SP 0x000000000 MP 0x14037B7B0 - {"_func_12A", 0x12A}, // SP 0x000000000 MP 0x14037B7C0 - {"_func_12B", 0x12B}, // SP 0x000000000 MP 0x14037B7D0 - {"_func_12C", 0x12C}, // SP 0x000000000 MP 0x14037B830 - {"_func_12D", 0x12D}, // SP 0x000000000 MP 0x14037B8B0 + {"getuavstrengthmax", 0x127}, // SP 0x000000000 MP 0x14037B790 + {"getuavstrengthlevelshowenemyfastsweep", 0x128}, // SP 0x000000000 MP 0x14037B7A0 + {"isdedicatedserver", 0x129}, // SP 0x000000000 MP 0x14037B7B0 + {"worldentnumber", 0x12A}, // SP 0x000000000 MP 0x14037B7C0 + {"blockteamradar", 0x12B}, // SP 0x000000000 MP 0x14037B7D0 + {"unblockteamradar", 0x12C}, // SP 0x000000000 MP 0x14037B830 + {"isteamradarblocked", 0x12D}, // SP 0x000000000 MP 0x14037B8B0 {"_func_12E", 0x12E}, // SP 0x000000000 MP 0x140378110 {"_func_12F", 0x12F}, // SP 0x000000000 MP 0x14037A7B0 {"_func_130", 0x130}, // SP 0x000000000 MP 0x140378420 - {"_func_131", 0x131}, // SP 0x000000000 MP 0x140378490 + {"sendmatchdata", 0x131}, // SP 0x000000000 MP 0x140378490 {"_func_132", 0x132}, // SP 0x000000000 MP 0x140378F40 {"_func_133", 0x133}, // SP 0x000000000 MP 0x14037A820 {"_func_134", 0x134}, // SP 0x000000000 MP 0x140378FE0 - {"_func_135", 0x135}, // SP 0x000000000 MP 0x140378DD0 + {"setmatchdataid", 0x135}, // SP 0x000000000 MP 0x140378DD0 {"_func_136", 0x136}, // SP 0x000000000 MP 0x140378F70 - {"_func_137", 0x137}, // SP 0x000000000 MP 0x140378290 + {"getmatchdata", 0x137}, // SP 0x000000000 MP 0x140378290 {"_func_138", 0x138}, // SP 0x000000000 MP 0x14037A8D0 - {"_func_139", 0x139}, // SP 0x000000000 MP 0x14037ADE0 - {"_func_13A", 0x13A}, // SP 0x000000000 MP 0x14037AEB0 - {"_func_13B", 0x13B}, // SP 0x000000000 MP 0x14037B0E0 - {"_func_13C", 0x13C}, // SP 0x000000000 MP 0x14037B100 - {"_func_13D", 0x13D}, // SP 0x000000000 MP 0x14037AA30 - {"_func_13E", 0x13E}, // SP 0x000000000 MP 0x14037AB20 + {"sendclientmatchdata", 0x139}, // SP 0x000000000 MP 0x14037ADE0 + {"getbuildversion", 0x13A}, // SP 0x000000000 MP 0x14037AEB0 + {"getsquadassaultelo", 0x13B}, // SP 0x000000000 MP 0x14037B0E0 + {"getsystemtime", 0x13C}, // SP 0x000000000 MP 0x14037B100 + {"getmatchrulesdata", 0x13D}, // SP 0x000000000 MP 0x14037AA30 + {"isusingmatchrulesdata", 0x13E}, // SP 0x000000000 MP 0x14037AB20 {"_func_13F", 0x13F}, // SP 0x000000000 MP 0x1403769E0 - {"_func_140", 0x140}, // SP 0x1402ACD00 MP 0x140378030 - {"_func_141", 0x141}, // SP 0x000000000 MP 0x14037B550 - {"_func_142", 0x142}, // SP 0x000000000 MP 0x14037B5A0 - {"_func_143", 0x143}, // SP 0x1402ABA00 MP 0x140376D40 - {"_func_144", 0x144}, // SP 0x1402ABA10 MP 0x1403770E0 - {"_func_145", 0x145}, // SP 0x1402ABA20 MP 0x140377160 + {"ishairrunning", 0x140}, // SP 0x1402ACD00 MP 0x140378030 + {"setmapcenter", 0x141}, // SP 0x000000000 MP 0x14037B550 + {"setgameendtime", 0x142}, // SP 0x000000000 MP 0x14037B5A0 + {"visionsetthermal", 0x143}, // SP 0x1402ABA00 MP 0x140376D40 + {"visionsetpain", 0x144}, // SP 0x1402ABA10 MP 0x1403770E0 + {"visionsetpostapply", 0x145}, // SP 0x1402ABA20 MP 0x140377160 {"_func_146", 0x146}, // SP 0x1402A12A0 MP 0x1403699C0 {"_func_147", 0x147}, // SP 0x140298040 MP 0x14035F250 {"_func_148", 0x148}, // SP 0x140298370 MP 0x14035F7A0 @@ -341,26 +341,26 @@ namespace scripting {"_func_14D", 0x14D}, // SP 0x14029F5B0 MP 0x1403675F0 {"_func_14E", 0x14E}, // SP 0x1402982C0 MP 0x14035F470 {"_func_14F", 0x14F}, // SP 0x14029EDB0 MP 0x1403670E0 - {"_func_150", 0x150}, // SP 0x140290A80 MP 0x1403583B0 + {"loadfx", 0x150}, // SP 0x140290A80 MP 0x1403583B0 {"_func_151", 0x151}, // SP 0x140291730 MP 0x140359620 - {"_func_152", 0x152}, // SP 0x140292A40 MP 0x14035AF90 - {"_func_153", 0x153}, // SP 0x140294440 MP 0x14035C4B0 + {"playfxontag", 0x152}, // SP 0x140292A40 MP 0x14035AF90 + {"stopfxontag", 0x153}, // SP 0x140294440 MP 0x14035C4B0 {"_func_154", 0x154}, // SP 0x140294DD0 MP 0x14035D560 - {"_func_155", 0x155}, // SP 0x140474350 MP 0x14037DA70 - {"_func_156", 0x156}, // SP 0x1404746B0 MP 0x14037E2D0 - {"_func_157", 0x157}, // SP 0x140474940 MP 0x14037E8B0 + {"playloopedfx", 0x155}, // SP 0x140474350 MP 0x14037DA70 + {"spawnfx", 0x156}, // SP 0x1404746B0 MP 0x14037E2D0 + {"triggerfx", 0x157}, // SP 0x140474940 MP 0x14037E8B0 {"_func_158", 0x158}, // SP 0x140292ED0 MP 0x14035B2B0 {"_func_159", 0x159}, // SP 0x140474640 MP 0x14037E1D0 {"_func_15A", 0x15A}, // SP 0x140293D50 MP 0x14035BFE0 {"_func_15B", 0x15B}, // SP 0x000000000 MP 0x1403778C0 {"_func_15C", 0x15C}, // SP 0x000000000 MP 0x140377920 - {"_func_15D", 0x15D}, // SP 0x000000000 MP 0x1403779A0 - {"_func_15E", 0x15E}, // SP 0x000000000 MP 0x140377A40 - {"_func_15F", 0x15F}, // SP 0x000000000 MP 0x140377BE0 - {"_func_160", 0x160}, // SP 0x000000000 MP 0x140377C50 - {"_func_161", 0x161}, // SP 0x000000000 MP 0x140377D70 - {"_func_162", 0x162}, // SP 0x000000000 MP 0x140377DC0 - {"_func_163", 0x163}, // SP 0x000000000 MP 0x140377EB0 + {"clientannouncement", 0x15D}, // SP 0x000000000 MP 0x1403779A0 + {"setteammode", 0x15E}, // SP 0x000000000 MP 0x140377A40 + {"getteamscore", 0x15F}, // SP 0x000000000 MP 0x140377BE0 + {"setteamscore", 0x160}, // SP 0x000000000 MP 0x140377C50 + {"setclientnamemode", 0x161}, // SP 0x000000000 MP 0x140377D70 + {"updateclientnames", 0x162}, // SP 0x000000000 MP 0x140377DC0 + {"getteamplayersalive", 0x163}, // SP 0x000000000 MP 0x140377EB0 {"_func_164", 0x164}, // SP 0x000000000 MP 0x140375460 {"_func_165", 0x165}, // SP 0x000000000 MP 0x140375480 {"_func_166", 0x166}, // SP 0x000000000 MP 0x1403754A0 @@ -370,73 +370,73 @@ namespace scripting {"_func_16A", 0x16A}, // SP 0x14029F100 MP 0x1403673A0 {"_func_16B", 0x16B}, // SP 0x000000000 MP 0x140376BE0 {"_func_16C", 0x16C}, // SP 0x000000000 MP 0x140376C60 - {"_func_16D", 0x16D}, // SP 0x000000000 MP 0x140376550 - {"_func_16E", 0x16E}, // SP 0x000000000 MP 0x140376630 + {"map_restart", 0x16D}, // SP 0x000000000 MP 0x140376550 + {"exitlevel", 0x16E}, // SP 0x000000000 MP 0x140376630 {"_func_16F", 0x16F}, // SP 0x000000000 MP 0x140376680 - {"_func_170", 0x170}, // SP 0x000000000 MP 0x140376860 + {"addagent", 0x170}, // SP 0x000000000 MP 0x140376860 {"_func_171", 0x171}, // SP 0x000000000 MP 0x140378020 {"_func_172", 0x172}, // SP 0x000000000 MP 0x140376880 {"_func_173", 0x173}, // SP 0x000000000 MP 0x140376B60 - {"_func_174", 0x174}, // SP 0x000000000 MP 0x140376910 - {"_func_175", 0x175}, // SP 0x000000000 MP 0x140376950 + {"mapexists", 0x174}, // SP 0x000000000 MP 0x140376910 + {"isvalidgametype", 0x175}, // SP 0x000000000 MP 0x140376950 {"_func_176", 0x176}, // SP 0x000000000 MP 0x140378040 - {"_func_177", 0x177}, // SP 0x000000000 MP 0x140378050 + {"setplayerteamrank", 0x177}, // SP 0x000000000 MP 0x140378050 {"_func_178", 0x178}, // SP 0x000000000 MP 0x140378100 - {"_func_179", 0x179}, // SP 0x000000000 MP 0x14037B5D0 - {"_func_17A", 0x17A}, // SP 0x000000000 MP 0x14037B640 - {"_func_17B", 0x17B}, // SP 0x000000000 MP 0x14037B6A0 - {"_func_17C", 0x17C}, // SP 0x000000000 MP 0x14037B720 - {"_func_17D", 0x17D}, // SP 0x000000000 MP 0x14037B780 + {"setteamradar", 0x179}, // SP 0x000000000 MP 0x14037B5D0 + {"getteamradar", 0x17A}, // SP 0x000000000 MP 0x14037B640 + {"setteamradarstrength", 0x17B}, // SP 0x000000000 MP 0x14037B6A0 + {"getteamradarstrength", 0x17C}, // SP 0x000000000 MP 0x14037B720 + {"getuavstrengthmin", 0x17D}, // SP 0x000000000 MP 0x14037B780 {"_func_17E", 0x17E}, // SP 0x140295500 MP 0x14035E730 - {"_func_17F", 0x17F}, // SP 0x140296890 MP 0x14035FE90 - {"_func_180", 0x180}, // SP 0x140295F60 MP 0x14035F2D0 - {"_func_181", 0x181}, // SP 0x1402963A0 MP 0x14035F900 + {"physicsexplosionsphere", 0x17F}, // SP 0x140296890 MP 0x14035FE90 + {"physicsradiusjolt", 0x180}, // SP 0x140295F60 MP 0x14035F2D0 + {"physicsradiusjitter", 0x181}, // SP 0x1402963A0 MP 0x14035F900 {"_func_182", 0x182}, // SP 0x140299880 MP 0x140362E20 {"_func_183", 0x183}, // SP 0x140299900 MP 0x140363010 {"_func_184", 0x184}, // SP 0x140299F70 MP 0x140363800 {"_func_185", 0x185}, // SP 0x14029A180 MP 0x140363920 {"_func_186", 0x186}, // SP 0x14029A220 MP 0x140363B00 {"_func_187", 0x187}, // SP 0x14029A4B0 MP 0x140363E60 - {"_func_188", 0x188}, // SP 0x1402A2800 MP 0x14036ADB0 - {"_func_189", 0x189}, // SP 0x1402A3690 MP 0x14036C110 - {"_func_18A", 0x18A}, // SP 0x14028DFA0 MP 0x14036CF90 + {"isexplosivedamagemod", 0x188}, // SP 0x1402A2800 MP 0x14036ADB0 + {"radiusdamage", 0x189}, // SP 0x1402A3690 MP 0x14036C110 + {"setplayerignoreradiusdamage", 0x18A}, // SP 0x14028DFA0 MP 0x14036CF90 {"_func_18B", 0x18B}, // SP 0x1402A3950 MP 0x14036C1E0 {"_func_18C", 0x18C}, // SP 0x14029B460 MP 0x140366A00 - {"_func_18D", 0x18D}, // SP 0x14029A830 MP 0x140363F40 + {"getnumparts", 0x18D}, // SP 0x14029A830 MP 0x140363F40 {"_func_18E", 0x18E}, // SP 0x1402B76D0 MP 0x140383170 {"_func_18F", 0x18F}, // SP 0x000000000 MP 0x1403831D0 - {"_func_190", 0x190}, // SP 0x000000000 MP 0x140383310 - {"_func_191", 0x191}, // SP 0x000000000 MP 0x1403833B0 + {"objective_team", 0x190}, // SP 0x000000000 MP 0x140383310 + {"objective_player", 0x191}, // SP 0x000000000 MP 0x1403833B0 {"_func_192", 0x192}, // SP 0x000000000 MP 0x140383410 {"_func_193", 0x193}, // SP 0x000000000 MP 0x1403834B0 {"_func_194", 0x194}, // SP 0x000000000 MP 0x1403835B0 {"_func_195", 0x195}, // SP 0x000000000 MP 0x1403835F0 - {"_func_196", 0x196}, // SP 0x000000000 MP 0x140382DA0 + {"objective_playermask_showtoall", 0x196}, // SP 0x000000000 MP 0x140382DA0 {"_func_197", 0x197}, // SP 0x000000000 MP 0x140382DE0 {"_func_198", 0x198}, // SP 0x1402AD860 MP 0x140377360 {"_func_199", 0x199}, // SP 0x1402AD8C0 MP 0x1403773E0 {"_func_19A", 0x19A}, // SP 0x1405D92F0 MP 0x140377C30 - {"_func_19B", 0x19B}, // SP 0x1402B9570 MP 0x1403845D0 - {"_func_19C", 0x19C}, // SP 0x1402B95E0 MP 0x1403846A0 + {"getent", 0x19B}, // SP 0x1402B9570 MP 0x1403845D0 + {"getentarray", 0x19C}, // SP 0x1402B95E0 MP 0x1403846A0 {"_func_19D", 0x19D}, // SP 0x000000000 MP 0x140384C00 - {"_func_19E", 0x19E}, // SP 0x000000000 MP 0x140377670 - {"_func_19F", 0x19F}, // SP 0x140374110 MP 0x140442170 + {"spawnplane", 0x19E}, // SP 0x000000000 MP 0x140377670 + {"spawnstruct", 0x19F}, // SP 0x140374110 MP 0x140442170 {"_func_1A0", 0x1A0}, // SP 0x000000000 MP 0x140377A90 - {"_func_1A1", 0x1A1}, // SP 0x1402AD940 MP 0x140377410 - {"_func_1A2", 0x1A2}, // SP 0x1402ADB20 MP 0x1403774F0 + {"isalive", 0x1A1}, // SP 0x1402AD940 MP 0x140377410 + {"isspawner", 0x1A2}, // SP 0x1402ADB20 MP 0x1403774F0 {"_func_1A3", 0x1A3}, // SP 0x140282D00 MP 0x14034F8E0 - {"_func_1A4", 0x1A4}, // SP 0x140282D10 MP 0x14034F8F0 - {"_func_1A5", 0x1A5}, // SP 0x140282FD0 MP 0x14034FBA0 + {"missile_createattractorent", 0x1A4}, // SP 0x140282D10 MP 0x14034F8F0 + {"missile_createattractororigin", 0x1A5}, // SP 0x140282FD0 MP 0x14034FBA0 {"_func_1A6", 0x1A6}, // SP 0x140282FE0 MP 0x14034FBB0 {"_func_1A7", 0x1A7}, // SP 0x140282FF0 MP 0x14034FBC0 - {"_func_1A8", 0x1A8}, // SP 0x000000000 MP 0x140378150 - {"_func_1A9", 0x1A9}, // SP 0x14026F000 MP 0x14033CF50 - {"_func_1AA", 0x1AA}, // SP 0x14026EFB0 MP 0x14033CEF0 - {"_func_1AB", 0x1AB}, // SP 0x000000000 MP 0x14033CF80 - {"_func_1AC", 0x1AC}, // SP 0x140375910 MP 0x1404438F0 - {"_func_1AD", 0x1AD}, // SP 0x1402ADB90 MP 0x140377390 - {"_func_1AE", 0x1AE}, // SP 0x000000000 MP 0x1403774C0 - {"_func_1AF", 0x1AF}, // SP 0x14029A9A0 MP 0x140364120 + {"playsoundatpos", 0x1A8}, // SP 0x000000000 MP 0x140378150 + {"newhudelem", 0x1A9}, // SP 0x14026F000 MP 0x14033CF50 + {"newclienthudelem", 0x1AA}, // SP 0x14026EFB0 MP 0x14033CEF0 + {"newteamhudelem", 0x1AB}, // SP 0x000000000 MP 0x14033CF80 + {"resettimeout", 0x1AC}, // SP 0x140375910 MP 0x1404438F0 + {"isplayer", 0x1AD}, // SP 0x1402ADB90 MP 0x140377390 + {"isplayernumber", 0x1AE}, // SP 0x000000000 MP 0x1403774C0 + {"getpartname", 0x1AF}, // SP 0x14029A9A0 MP 0x140364120 {"_func_1B0", 0x1B0}, // SP 0x14029CDC0 MP 0x140363D50 {"_func_1B1", 0x1B1}, // SP 0x1402999A0 MP 0x140360B10 {"_func_1B2", 0x1B2}, // SP 0x14029AA30 MP 0x140361AC0 @@ -445,100 +445,100 @@ namespace scripting {"_func_1B5", 0x1B5}, // SP 0x14029B580 MP 0x140362520 {"_func_1B6", 0x1B6}, // SP 0x14029B020 MP 0x140361EC0 {"_func_1B7", 0x1B7}, // SP 0x14029B7A0 MP 0x140362920 - {"_func_1B8", 0x1B8}, // SP 0x14029B8E0 MP 0x140362A60 - {"_func_1B9", 0x1B9}, // SP 0x1402A35D0 MP 0x14036D000 + {"weaponclass", 0x1B8}, // SP 0x14029B8E0 MP 0x140362A60 + {"getnextarraykey", 0x1B9}, // SP 0x1402A35D0 MP 0x14036D000 {"_func_1BA", 0x1BA}, // SP 0x14028D850 MP 0x14036D690 {"_func_1BB", 0x1BB}, // SP 0x14029CCC0 MP 0x1403664F0 - {"_func_1BC", 0x1BC}, // SP 0x14029D970 MP 0x1403671B0 + {"tablelookupistringbyrow", 0x1BC}, // SP 0x14029D970 MP 0x1403671B0 {"_func_1BD", 0x1BD}, // SP 0x14029CF50 MP 0x1403667F0 - {"_func_1BE", 0x1BE}, // SP 0x14029DC10 MP 0x140367320 + {"tablelookuprownum", 0x1BE}, // SP 0x14029DC10 MP 0x140367320 {"_func_1BF", 0x1BF}, // SP 0x14029D280 MP 0x140366C90 - {"_func_1C0", 0x1C0}, // SP 0x14029D820 MP 0x140366DE0 - {"_func_1C1", 0x1C1}, // SP 0x14029AD10 MP 0x140366490 + {"tableexists", 0x1C0}, // SP 0x14029D820 MP 0x140366DE0 + {"getmissileowner", 0x1C1}, // SP 0x14029AD10 MP 0x140366490 {"_func_1C2", 0x1C2}, // SP 0x140294EF0 MP 0x14035E270 - {"_func_1C3", 0x1C3}, // SP 0x140295DC0 MP 0x14035F290 - {"_func_1C4", 0x1C4}, // SP 0x14029A870 MP 0x140363F90 + {"getweaponflashtagname", 0x1C3}, // SP 0x140295DC0 MP 0x14035F290 + {"averagepoint", 0x1C4}, // SP 0x14029A870 MP 0x140363F90 {"_func_1C5", 0x1C5}, // SP 0x14029AB60 MP 0x140364300 - {"_func_1C6", 0x1C6}, // SP 0x140466C40 MP 0x140564030 - {"_func_1C7", 0x1C7}, // SP 0x140299410 MP 0x140360540 - {"_func_1C8", 0x1C8}, // SP 0x140299470 MP 0x1403605E0 + {"getspawnerarray", 0x1C6}, // SP 0x140466C40 MP 0x140564030 + {"playrumbleonposition", 0x1C7}, // SP 0x140299410 MP 0x140360540 + {"playrumblelooponposition", 0x1C8}, // SP 0x140299470 MP 0x1403605E0 {"_func_1C9", 0x1C9}, // SP 0x1402996F0 MP 0x140360670 - {"_func_1CA", 0x1CA}, // SP 0x140290B30 MP 0x14035C2D0 + {"soundexists", 0x1CA}, // SP 0x140290B30 MP 0x14035C2D0 {"_func_1CB", 0x1CB}, // SP 0x1405D92F0 MP 0x14036B580 {"_func_1CC", 0x1CC}, // SP 0x1405D92F0 MP 0x14036B590 {"_func_1CD", 0x1CD}, // SP 0x1405D92F0 MP 0x14036B710 {"_func_1CE", 0x1CE}, // SP 0x1405D92F0 MP 0x14036B770 {"_func_1CF", 0x1CF}, // SP 0x1405D92F0 MP 0x14036B780 {"_func_1D0", 0x1D0}, // SP 0x1405D92F0 MP 0x14036B790 - {"_func_1D1", 0x1D1}, // SP 0x1402A2200 MP 0x14036C3C0 + {"setminimap", 0x1D1}, // SP 0x1402A2200 MP 0x14036C3C0 {"_func_1D2", 0x1D2}, // SP 0x1402A28F0 MP 0x14036CA90 {"_func_1D3", 0x1D3}, // SP 0x1402A3410 MP 0x14036CDA0 - {"_func_1D4", 0x1D4}, // SP 0x1402A3470 MP 0x14036CF00 - {"_func_1D5", 0x1D5}, // SP 0x14029AD60 MP 0x1403644F0 - {"_func_1D6", 0x1D6}, // SP 0x14029B110 MP 0x1403647D0 - {"_func_1D7", 0x1D7}, // SP 0x14029B410 MP 0x1403649E0 - {"_func_1D8", 0x1D8}, // SP 0x14029B630 MP 0x140364CF0 - {"_func_1D9", 0x1D9}, // SP 0x14029B850 MP 0x140365010 + {"getfirstarraykey", 0x1D4}, // SP 0x1402A3470 MP 0x14036CF00 + {"getglass", 0x1D5}, // SP 0x14029AD60 MP 0x1403644F0 + {"getglassarray", 0x1D6}, // SP 0x14029B110 MP 0x1403647D0 + {"getglassorigin", 0x1D7}, // SP 0x14029B410 MP 0x1403649E0 + {"isglassdestroyed", 0x1D8}, // SP 0x14029B630 MP 0x140364CF0 + {"destroyglass", 0x1D9}, // SP 0x14029B850 MP 0x140365010 {"_func_1DA", 0x1DA}, // SP 0x14029B9F0 MP 0x1403651E0 {"_func_1DB", 0x1DB}, // SP 0x14029C0E0 MP 0x140365F50 {"_func_1DC", 0x1DC}, // SP 0x14029C160 MP 0x140366130 - {"_func_1DD", 0x1DD}, // SP 0x1402B7080 MP 0x140382E50 + {"objective_add", 0x1DD}, // SP 0x1402B7080 MP 0x140382E50 {"_func_1DE", 0x1DE}, // SP 0x1402B74F0 MP 0x140382F80 - {"_func_1DF", 0x1DF}, // SP 0x1402B77E0 MP 0x140382FF0 - {"_func_1E0", 0x1E0}, // SP 0x1402B7820 MP 0x140383090 + {"objective_state", 0x1DF}, // SP 0x1402B77E0 MP 0x140382FF0 + {"objective_icon", 0x1E0}, // SP 0x1402B7820 MP 0x140383090 {"_func_1E1", 0x1E1}, // SP 0x1402B7900 MP 0x000000000 - {"_func_1E2", 0x1E2}, // SP 0x1402B7980 MP 0x1403830D0 - {"_func_1E3", 0x1E3}, // SP 0x1402B7A10 MP 0x140383230 + {"objective_position", 0x1E2}, // SP 0x1402B7980 MP 0x1403830D0 + {"objective_current", 0x1E3}, // SP 0x1402B7A10 MP 0x140383230 {"_func_1E4", 0x1E4}, // SP 0x14029BA70 MP 0x140362C20 {"_func_1E5", 0x1E5}, // SP 0x14029BE70 MP 0x140362F00 {"_func_1E6", 0x1E6}, // SP 0x14029BF80 MP 0x140363300 {"_func_1E7", 0x1E7}, // SP 0x14029C9D0 MP 0x140363950 - {"_func_1E8", 0x1E8}, // SP 0x14029D050 MP 0x140364220 + {"isweaponcliponly", 0x1E8}, // SP 0x14029D050 MP 0x140364220 {"_func_1E9", 0x1E9}, // SP 0x14029D330 MP 0x140364590 {"_func_1EA", 0x1EA}, // SP 0x14029D720 MP 0x140364870 {"_func_1EB", 0x1EB}, // SP 0x14029D9F0 MP 0x140364E70 {"_func_1EC", 0x1EC}, // SP 0x14045D5C0 MP 0x14055A900 - {"_func_1ED", 0x1ED}, // SP 0x14045D6B0 MP 0x14055A9F0 + {"getvehiclenodearray", 0x1ED}, // SP 0x14045D6B0 MP 0x14055A9F0 {"_func_1EE", 0x1EE}, // SP 0x14045D550 MP 0x14055A890 {"_func_1EF", 0x1EF}, // SP 0x1404669B0 MP 0x140563DA0 {"_func_1F0", 0x1F0}, // SP 0x140466CC0 MP 0x140564110 - {"_func_1F1", 0x1F1}, // SP 0x140466D20 MP 0x140564170 - {"_func_1F2", 0x1F2}, // SP 0x1404669F0 MP 0x140563DE0 - {"_func_1F3", 0x1F3}, // SP 0x14028E710 MP 0x14036CBC0 + {"spawnvehicle", 0x1F1}, // SP 0x140466D20 MP 0x140564170 + {"vehicle_getarray", 0x1F2}, // SP 0x1404669F0 MP 0x140563DE0 + {"pow", 0x1F3}, // SP 0x14028E710 MP 0x14036CBC0 {"_func_1F4", 0x1F4}, // SP 0x14028D7B0 MP 0x14036BB10 - {"_func_1F5", 0x1F5}, // SP 0x000000000 MP 0x14047A600 - {"_func_1F6", 0x1F6}, // SP 0x000000000 MP 0x14047ABF0 - {"_func_1F7", 0x1F7}, // SP 0x000000000 MP 0x14047AC20 - {"_func_1F8", 0x1F8}, // SP 0x000000000 MP 0x14047AF10 + {"botgetmemoryevents", 0x1F5}, // SP 0x000000000 MP 0x14047A600 + {"botautoconnectenabled", 0x1F6}, // SP 0x000000000 MP 0x14047ABF0 + {"botzonegetcount", 0x1F7}, // SP 0x000000000 MP 0x14047AC20 + {"botzonesetteam", 0x1F8}, // SP 0x000000000 MP 0x14047AF10 {"_func_1F9", 0x1F9}, // SP 0x000000000 MP 0x14047AD50 - {"_func_1FA", 0x1FA}, // SP 0x000000000 MP 0x14047A940 - {"_func_1FB", 0x1FB}, // SP 0x000000000 MP 0x14047A320 - {"_func_1FC", 0x1FC}, // SP 0x000000000 MP 0x14047ACF0 - {"_func_1FD", 0x1FD}, // SP 0x000000000 MP 0x14047A990 - {"_func_1FE", 0x1FE}, // SP 0x000000000 MP 0x14047AF70 - {"_func_1FF", 0x1FF}, // SP 0x000000000 MP 0x14037B2B0 - {"_func_200", 0x200}, // SP 0x000000000 MP 0x140450E50 + {"botmemoryflags", 0x1FA}, // SP 0x000000000 MP 0x14047A940 + {"botflagmemoryevents", 0x1FB}, // SP 0x000000000 MP 0x14047A320 + {"botzonegetindoorpercent", 0x1FC}, // SP 0x000000000 MP 0x14047ACF0 + {"botsentientswap", 0x1FD}, // SP 0x000000000 MP 0x14047A990 + {"isbot", 0x1FE}, // SP 0x000000000 MP 0x14047AF70 + {"isagent", 0x1FF}, // SP 0x000000000 MP 0x14037B2B0 + {"getmaxagents", 0x200}, // SP 0x000000000 MP 0x140450E50 {"_func_201", 0x201}, // SP 0x000000000 MP 0x14047A310 - {"_func_202", 0x202}, // SP 0x000000000 MP 0x14047A550 - {"_func_203", 0x203}, // SP 0x000000000 MP 0x14031FCE0 - {"_func_204", 0x204}, // SP 0x1402CC4A0 MP 0x140320EA0 + {"botgetclosestnavigablepoint", 0x202}, // SP 0x000000000 MP 0x14047A550 + {"getnodesintrigger", 0x203}, // SP 0x000000000 MP 0x14031FCE0 + {"nodesvisible", 0x204}, // SP 0x1402CC4A0 MP 0x140320EA0 {"_func_205", 0x205}, // SP 0x1402CC110 MP 0x14031FDD0 {"_func_206", 0x206}, // SP 0x000000000 MP 0x1403201B0 - {"_func_207", 0x207}, // SP 0x000000000 MP 0x1403201C0 + {"getzonenearest", 0x207}, // SP 0x000000000 MP 0x1403201C0 {"_func_208", 0x208}, // SP 0x000000000 MP 0x140320320 {"_func_209", 0x209}, // SP 0x000000000 MP 0x140320A10 {"_func_20A", 0x20A}, // SP 0x000000000 MP 0x140320960 - {"_func_20B", 0x20B}, // SP 0x000000000 MP 0x14031FC20 + {"getnodezone", 0x20B}, // SP 0x000000000 MP 0x14031FC20 {"_func_20C", 0x20C}, // SP 0x000000000 MP 0x140320600 - {"_func_20D", 0x20D}, // SP 0x000000000 MP 0x1403202E0 + {"getzonenodeforindex", 0x20D}, // SP 0x000000000 MP 0x1403202E0 {"_func_20E", 0x20E}, // SP 0x1402AFFC0 MP 0x14037AE40 {"_func_211", 0x211}, // SP 0x000000000 MP 0x140320C70 - {"_func_212", 0x212}, // SP 0x000000000 MP 0x14031F6F0 - {"_func_213", 0x213}, // SP 0x000000000 MP 0x14035A190 + {"findentrances", 0x212}, // SP 0x000000000 MP 0x14031F6F0 + {"badplace_global", 0x213}, // SP 0x000000000 MP 0x14035A190 {"_func_214", 0x214}, // SP 0x000000000 MP 0x140375150 {"_func_215", 0x215}, // SP 0x1402CBE10 MP 0x14031F940 - {"_func_216", 0x216}, // SP 0x14028E840 MP 0x14036F800 - {"_func_217", 0x217}, // SP 0x14028EAC0 MP 0x140357F30 + {"disconnectnodepair", 0x216}, // SP 0x14028E840 MP 0x14036F800 + {"connectnodepair", 0x217}, // SP 0x14028EAC0 MP 0x140357F30 {"_func_218", 0x218}, // SP 0x1402AE000 MP 0x000000000 {"_func_21B", 0x21B}, // SP 0x1405D92F0 MP 0x1403780E0 {"_func_21C", 0x21C}, // SP 0x000000000 MP 0x140374FD0 @@ -550,22 +550,22 @@ namespace scripting {"_func_222", 0x222}, // SP 0x14037A7B0 MP 0x000000000 {"_func_223", 0x223}, // SP 0x14037A760 MP 0x000000000 {"_func_224", 0x224}, // SP 0x14037A7F0 MP 0x000000000 - {"_func_225", 0x225}, // SP 0x1402914F0 MP 0x140357BF0 - {"_func_226", 0x226}, // SP 0x14028FE10 MP 0x14036F1C0 - {"_func_227", 0x227}, // SP 0x140290710 MP 0x14035B7B0 + {"distance2dsquared", 0x225}, // SP 0x1402914F0 MP 0x140357BF0 + {"getangledelta3d", 0x226}, // SP 0x14028FE10 MP 0x14036F1C0 + {"activateclientexploder", 0x227}, // SP 0x140290710 MP 0x14035B7B0 {"_func_228", 0x228}, // SP 0x1402909E0 MP 0x14035CED0 {"_func_229", 0x229}, // SP 0x140290DF0 MP 0x14035D200 - {"_func_22A", 0x22A}, // SP 0x140290FA0 MP 0x14035D4C0 + {"trajectorycalculateexitangle", 0x22A}, // SP 0x140290FA0 MP 0x14035D4C0 {"_func_22B", 0x22B}, // SP 0x1402911D0 MP 0x14035D830 - {"_func_22C", 0x22C}, // SP 0x140291530 MP 0x14035DFB0 - {"_func_22D", 0x22D}, // SP 0x140291910 MP 0x14035E0B0 + {"trajectorycomputedeltaheightattime", 0x22C}, // SP 0x140291530 MP 0x14035DFB0 + {"trajectoryestimatedesiredinairtime", 0x22D}, // SP 0x140291910 MP 0x14035E0B0 {"_func_22E", 0x22E}, // SP 0x1405D92F0 MP 0x140367D60 - {"_func_22F", 0x22F}, // SP 0x140291190 MP 0x14036F5A0 + {"ispointinvolume", 0x22F}, // SP 0x140291190 MP 0x14036F5A0 {"_func_230", 0x230}, // SP 0x1402AB600 MP 0x000000000 {"_func_231", 0x231}, // SP 0x1402AB4F0 MP 0x000000000 {"_func_232", 0x232}, // SP 0x1402AB4D0 MP 0x000000000 {"_func_234", 0x234}, // SP 0x1405D92F0 MP 0x1403605D0 - {"_func_236", 0x236}, // SP 0x140294380 MP 0x140360720 + {"getscriptablearray", 0x236}, // SP 0x140294380 MP 0x140360720 {"_func_237", 0x237}, // SP 0x140297840 MP 0x140360C40 {"_func_238", 0x238}, // SP 0x1402A87C0 MP 0x14037B1D0 {"_func_239", 0x239}, // SP 0x1402AA280 MP 0x000000000 @@ -600,47 +600,47 @@ namespace scripting {"_func_257", 0x257}, // SP 0x1402ADE20 MP 0x000000000 {"_func_258", 0x258}, // SP 0x14029F640 MP 0x1403677A0 {"_func_259", 0x259}, // SP 0x14029F710 MP 0x1403678C0 - {"_func_25A", 0x25A}, // SP 0x1402954E0 MP 0x1403611E0 - {"_func_25B", 0x25B}, // SP 0x1402955F0 MP 0x140361200 - {"_func_25C", 0x25C}, // SP 0x140295790 MP 0x1403613C0 - {"_func_25D", 0x25D}, // SP 0x140295AD0 MP 0x1403615F0 - {"_func_25E", 0x25E}, // SP 0x140295E00 MP 0x140361A30 - {"_func_25F", 0x25F}, // SP 0x140296150 MP 0x140361DD0 + {"getcsplinecount", 0x25A}, // SP 0x1402954E0 MP 0x1403611E0 + {"getcsplinepointcount", 0x25B}, // SP 0x1402955F0 MP 0x140361200 + {"getcsplinelength", 0x25C}, // SP 0x140295790 MP 0x1403613C0 + {"getcsplinepointid", 0x25D}, // SP 0x140295AD0 MP 0x1403615F0 + {"getcsplinepointlabel", 0x25E}, // SP 0x140295E00 MP 0x140361A30 + {"getcsplinepointtension", 0x25F}, // SP 0x140296150 MP 0x140361DD0 {"_func_260", 0x260}, // SP 0x1402965B0 MP 0x140362020 {"_func_261", 0x261}, // SP 0x140296740 MP 0x140362470 {"_func_262", 0x262}, // SP 0x140296B10 MP 0x140362680 - {"_func_263", 0x263}, // SP 0x140296CE0 MP 0x140362AE0 + {"getcsplinepointdisttonextpoint", 0x263}, // SP 0x140296CE0 MP 0x140362AE0 {"_func_264", 0x264}, // SP 0x140296EE0 MP 0x140362D50 {"_func_265", 0x265}, // SP 0x1402970D0 MP 0x140363430 {"_func_266", 0x266}, // SP 0x140297580 MP 0x1403636C0 - {"_func_267", 0x267}, // SP 0x140297820 MP 0x140363AB0 - {"_func_268", 0x268}, // SP 0x140297820 MP 0x140363C90 - {"_func_269", 0x269}, // SP 0x000000000 MP 0x14037AEC0 + {"setnojipscore", 0x267}, // SP 0x140297820 MP 0x140363AB0 + {"setnojiptime", 0x268}, // SP 0x140297820 MP 0x140363C90 + {"getpredictedentityposition", 0x269}, // SP 0x000000000 MP 0x14037AEC0 {"_func_26A", 0x26A}, // SP 0x1405D92F0 MP 0x140363F80 {"_func_26B", 0x26B}, // SP 0x1405D92F0 MP 0x140364110 {"_func_26C", 0x26C}, // SP 0x1405D92F0 MP 0x1403642F0 {"_func_26D", 0x26D}, // SP 0x1405D92F0 MP 0x1403644E0 {"_func_26E", 0x26E}, // SP 0x1405D92F0 MP 0x140364540 {"_func_26F", 0x26F}, // SP 0x1405D92F0 MP 0x140364700 - {"_func_270", 0x270}, // SP 0x000000000 MP 0x140378930 + {"queuedialog", 0x270}, // SP 0x000000000 MP 0x140378930 {"_func_271", 0x271}, // SP 0x1405D92F0 MP 0x000000000 {"_func_272", 0x272}, // SP 0x1405D92F0 MP 0x000000000 {"_func_273", 0x273}, // SP 0x1405D92F0 MP 0x140364710 {"_func_274", 0x274}, // SP 0x1405D92F0 MP 0x140364860 {"_func_275", 0x275}, // SP 0x1405D92F0 MP 0x140364970 {"_func_276", 0x276}, // SP 0x1405D92F0 MP 0x1403649D0 - {"_func_277", 0x277}, // SP 0x000000000 MP 0x14037B980 - {"_func_279", 0x279}, // SP 0x000000000 MP 0x14047A900 - {"_func_27A", 0x27A}, // SP 0x000000000 MP 0x14037E430 - {"_func_27B", 0x27B}, // SP 0x000000000 MP 0x14047A8C0 + {"triggerportableradarping", 0x277}, // SP 0x000000000 MP 0x14037B980 + {"botgetteamlimit", 0x279}, // SP 0x000000000 MP 0x14047A900 + {"spawnfxforclient", 0x27A}, // SP 0x000000000 MP 0x14037E430 + {"botgetteamdifficulty", 0x27B}, // SP 0x000000000 MP 0x14047A8C0 {"_func_27C", 0x27C}, // SP 0x1405D92F0 MP 0x1403675D0 {"_func_27D", 0x27D}, // SP 0x14029CAC0 MP 0x14033CF40 {"_func_27E", 0x27E}, // SP 0x1405D92F0 MP 0x140363CE0 {"_func_27F", 0x27F}, // SP 0x1405D92F0 MP 0x140363E50 {"_func_280", 0x280}, // SP 0x1405D92F0 MP 0x140360610 {"_func_281", 0x281}, // SP 0x14029DC90 MP 0x140369F80 - {"_func_282", 0x282}, // SP 0x000000000 MP 0x14037BBD0 - {"_func_283", 0x283}, // SP 0x000000000 MP 0x14037BBE0 + {"getstarttime", 0x282}, // SP 0x000000000 MP 0x14037BBD0 + {"getbuildnumber", 0x283}, // SP 0x000000000 MP 0x14037BBE0 {"_func_284", 0x284}, // SP 0x000000000 MP 0x14037BC00 {"_func_285", 0x285}, // SP 0x000000000 MP 0x1403748B0 {"_func_286", 0x286}, // SP 0x000000000 MP 0x140374B00 @@ -708,7 +708,7 @@ namespace scripting {"_func_2C4", 0x2C4}, // SP 0x1402A1A30 MP 0x14036DAC0 {"_func_2C5", 0x2C5}, // SP 0x1402A8810 MP 0x000000000 {"_func_2C6", 0x2C6}, // SP 0x000000000 MP 0x140379A80 - {"_func_2C7", 0x2C7}, // SP 0x000000000 MP 0x140320DC0 + {"_func_2C6", 0x2C7}, // SP 0x000000000 MP 0x140320DC0 {"_func_2C8", 0x2C8}, // SP 0x000000000 MP 0x140320E20 {"_func_2C9", 0x2C9}, // SP 0x000000000 MP 0x14037E5E0 {"_func_2CA", 0x2CA}, // SP 0x000000000 MP 0x14037E650 @@ -766,35 +766,35 @@ namespace scripting std::unordered_map method_map = { - {"_meth_8000", 0x8000}, // SP 0x14029B0D0 MP 0x140362FD0 + {"motionblurhqenable", 0x8000}, // SP 0x14029B0D0 MP 0x140362FD0 {"_meth_8001", 0x8001}, // SP 0x1402A8AC0 MP 0x000000000 - {"_meth_8002", 0x8002}, // SP 0x000000000 MP 0x14055A000 + {"setdamagestage", 0x8002}, // SP 0x000000000 MP 0x14055A000 {"_meth_8003", 0x8003}, // SP 0x000000000 MP 0x140378300 - {"_meth_8004", 0x8004}, // SP 0x000000000 MP 0x1403784F0 - {"_meth_8005", 0x8005}, // SP 0x000000000 MP 0x14037AB70 + {"playsoundtoplayer", 0x8004}, // SP 0x000000000 MP 0x1403784F0 + {"playerhide", 0x8005}, // SP 0x000000000 MP 0x14037AB70 {"_meth_8006", 0x8006}, // SP 0x000000000 MP 0x14037ABD0 - {"_meth_8007", 0x8007}, // SP 0x000000000 MP 0x14037AC50 + {"showtoplayer", 0x8007}, // SP 0x000000000 MP 0x14037AC50 {"_meth_8008", 0x8008}, // SP 0x000000000 MP 0x14037ACB0 {"_meth_8009", 0x8009}, // SP 0x000000000 MP 0x14037ACC0 - {"_meth_800A", 0x800A}, // SP 0x000000000 MP 0x140374B10 - {"_meth_800B", 0x800B}, // SP 0x000000000 MP 0x140374BB0 + {"enableplayeruse", 0x800A}, // SP 0x000000000 MP 0x140374B10 + {"disableplayeruse", 0x800B}, // SP 0x000000000 MP 0x140374BB0 {"_meth_800C", 0x800C}, // SP 0x000000000 MP 0x140374D70 {"_meth_800D", 0x800D}, // SP 0x000000000 MP 0x140374C90 - {"_meth_800E", 0x800E}, // SP 0x000000000 MP 0x14037B890 - {"_meth_800F", 0x800F}, // SP 0x000000000 MP 0x14037B930 - {"_meth_8010", 0x8010}, // SP 0x000000000 MP 0x14037B910 - {"_meth_8011", 0x8011}, // SP 0x000000000 MP 0x14037B960 - {"_meth_8012", 0x8012}, // SP 0x000000000 MP 0x1403760E0 - {"_meth_8013", 0x8013}, // SP 0x000000000 MP 0x14037B130 - {"_meth_8014", 0x8014}, // SP 0x000000000 MP 0x14037B220 - {"_meth_8015", 0x8015}, // SP 0x000000000 MP 0x14037B300 - {"_meth_8016", 0x8016}, // SP 0x000000000 MP 0x14037B510 + {"makescrambler", 0x800E}, // SP 0x000000000 MP 0x14037B890 + {"makeportableradar", 0x800F}, // SP 0x000000000 MP 0x14037B930 + {"clearscrambler", 0x8010}, // SP 0x000000000 MP 0x14037B910 + {"clearportableradar", 0x8011}, // SP 0x000000000 MP 0x14037B960 + {"addplayermantleblockage", 0x8012}, // SP 0x000000000 MP 0x1403760E0 + {"setteamfortrigger", 0x8013}, // SP 0x000000000 MP 0x14037B130 + {"clientclaimtrigger", 0x8014}, // SP 0x000000000 MP 0x14037B220 + {"clientreleasetrigger", 0x8015}, // SP 0x000000000 MP 0x14037B300 + {"releaseclaimedtrigger", 0x8016}, // SP 0x000000000 MP 0x14037B510 {"_meth_8017", 0x8017}, // SP 0x000000000 MP 0x14037AC10 {"_meth_8018", 0x8018}, // SP 0x000000000 MP 0x14037ACD0 {"_meth_8019", 0x8019}, // SP 0x000000000 MP 0x140378210 {"_meth_801A", 0x801A}, // SP 0x14028F380 MP 0x14036F540 - {"_meth_801B", 0x801B}, // SP 0x000000000 MP 0x14037BD60 - {"_meth_801C", 0x801C}, // SP 0x000000000 MP 0x140374A30 + {"getcorpseanim", 0x801B}, // SP 0x000000000 MP 0x14037BD60 + {"playerforcedeathanim", 0x801C}, // SP 0x000000000 MP 0x140374A30 {"_meth_801D", 0x801D}, // SP 0x14029DCF0 MP 0x140369D40 {"_meth_801E", 0x801E}, // SP 0x1402AD230 MP 0x000000000 {"_meth_801F", 0x801F}, // SP 0x1402AD490 MP 0x000000000 @@ -808,9 +808,9 @@ namespace scripting {"_meth_8028", 0x8028}, // SP 0x1402ADE80 MP 0x000000000 {"_meth_8029", 0x8029}, // SP 0x14029AEC0 MP 0x140362D10 {"_meth_802A", 0x802A}, // SP 0x14029E0E0 MP 0x14036A480 - {"_meth_802B", 0x802B}, // SP 0x14029E180 MP 0x14036A4C0 - {"_meth_802C", 0x802C}, // SP 0x1402A0610 MP 0x14036C860 - {"_meth_802D", 0x802D}, // SP 0x1402A0890 MP 0x14036CE90 + {"detachall", 0x802B}, // SP 0x14029E180 MP 0x14036A4C0 + {"getattachsize", 0x802C}, // SP 0x1402A0610 MP 0x14036C860 + {"getattachmodelname", 0x802D}, // SP 0x1402A0890 MP 0x14036CE90 {"_meth_802E", 0x802E}, // SP 0x1402A0A90 MP 0x14036D040 {"_meth_802F", 0x802F}, // SP 0x1402AE150 MP 0x000000000 {"_meth_8030", 0x8030}, // SP 0x1402AE270 MP 0x000000000 @@ -818,9 +818,9 @@ namespace scripting {"_meth_8032", 0x8032}, // SP 0x1402AE620 MP 0x000000000 {"_meth_8033", 0x8033}, // SP 0x1402AE6E0 MP 0x000000000 {"_meth_8034", 0x8034}, // SP 0x1402CBC10 MP 0x000000000 - {"_meth_8035", 0x8035}, // SP 0x1402CBBA0 MP 0x14031F650 - {"_meth_8036", 0x8036}, // SP 0x1402CBA70 MP 0x14031F520 - {"_meth_8037", 0x8037}, // SP 0x1402CBB20 MP 0x14031F5D0 + {"gethighestnodestance", 0x8035}, // SP 0x1402CBBA0 MP 0x14031F650 + {"doesnodeallowstance", 0x8036}, // SP 0x1402CBA70 MP 0x14031F520 + {"setforcespectatorclient", 0x8037}, // SP 0x1402CBB20 MP 0x14031F5D0 {"_meth_8038", 0x8038}, // SP 0x1402AB240 MP 0x000000000 {"_meth_8039", 0x8039}, // SP 0x1402AB320 MP 0x000000000 {"_meth_803A", 0x803A}, // SP 0x1402AB6D0 MP 0x000000000 @@ -838,11 +838,11 @@ namespace scripting {"_meth_8046", 0x8046}, // SP 0x14028F1F0 MP 0x14036EEE0 {"_meth_8047", 0x8047}, // SP 0x1402ACE10 MP 0x000000000 {"_meth_8048", 0x8048}, // SP 0x1402ACE50 MP 0x000000000 - {"_meth_8049", 0x8049}, // SP 0x1402A1060 MP 0x14036D280 - {"_meth_804A", 0x804A}, // SP 0x1402A1500 MP 0x14036D940 - {"_meth_804B", 0x804B}, // SP 0x1402A1930 MP 0x14036DC50 + {"getattachignorecollision", 0x8049}, // SP 0x1402A1060 MP 0x14036D280 + {"hidepart", 0x804A}, // SP 0x1402A1500 MP 0x14036D940 + {"hidepartallinstances", 0x804B}, // SP 0x1402A1930 MP 0x14036DC50 {"_meth_804C", 0x804C}, // SP 0x1402A1C90 MP 0x14036E320 - {"_meth_804D", 0x804D}, // SP 0x1402A2000 MP 0x14036E480 + {"showpart", 0x804D}, // SP 0x1402A2000 MP 0x14036E480 {"_meth_804E", 0x804E}, // SP 0x1402A2370 MP 0x14036ECC0 {"_meth_804F", 0x804F}, // SP 0x1402A3670 MP 0x140358AF0 {"_meth_8050", 0x8050}, // SP 0x1402A3AB0 MP 0x140359830 @@ -850,12 +850,12 @@ namespace scripting {"_meth_8052", 0x8052}, // SP 0x1402AD0F0 MP 0x140379AD0 {"_meth_8053", 0x8053}, // SP 0x1402A2B80 MP 0x14036B270 {"_meth_8054", 0x8054}, // SP 0x1402AD260 MP 0x000000000 - {"_meth_8055", 0x8055}, // SP 0x1402AD6A0 MP 0x14037A9E0 - {"_meth_8056", 0x8056}, // SP 0x1402AD6C0 MP 0x14037AAA0 + {"show", 0x8055}, // SP 0x1402AD6A0 MP 0x14037A9E0 + {"hide", 0x8056}, // SP 0x1402AD6C0 MP 0x14037AAA0 {"_meth_8057", 0x8057}, // SP 0x1402AD7A0 MP 0x000000000 {"_meth_8058", 0x8058}, // SP 0x1402AD7D0 MP 0x000000000 - {"_meth_8059", 0x8059}, // SP 0x14028E1E0 MP 0x14036F090 - {"_meth_805A", 0x805A}, // SP 0x14028E390 MP 0x14036F4C0 + {"disconnectpaths", 0x8059}, // SP 0x14028E1E0 MP 0x14036F090 + {"connectpaths", 0x805A}, // SP 0x14028E390 MP 0x14036F4C0 {"_meth_805B", 0x805B}, // SP 0x14028E490 MP 0x14036F5F0 {"_meth_805C", 0x805C}, // SP 0x14028E750 MP 0x14036F770 {"_meth_805D", 0x805D}, // SP 0x1402A8420 MP 0x000000000 @@ -867,11 +867,11 @@ namespace scripting {"_meth_8063", 0x8063}, // SP 0x1402A9BC0 MP 0x000000000 {"_meth_8064", 0x8064}, // SP 0x1402AABA0 MP 0x000000000 {"_meth_8065", 0x8065}, // SP 0x1402AAC10 MP 0x000000000 - {"_meth_8067", 0x8067}, // SP 0x1402AD9A0 MP 0x140375030 + {"setmode", 0x8067}, // SP 0x1402AD9A0 MP 0x140375030 {"_meth_8068", 0x8068}, // SP 0x1402ADCD0 MP 0x140375210 {"_meth_8069", 0x8069}, // SP 0x1402ADF10 MP 0x000000000 - {"_meth_806A", 0x806A}, // SP 0x14028D6B0 MP 0x1403598E0 - {"_meth_806B", 0x806B}, // SP 0x14028EA50 MP 0x14035A950 + {"islinked", 0x806A}, // SP 0x14028D6B0 MP 0x1403598E0 + {"enablelinkto", 0x806B}, // SP 0x14028EA50 MP 0x14035A950 {"_meth_806C", 0x806C}, // SP 0x1402ACB60 MP 0x000000000 {"_meth_806E", 0x806E}, // SP 0x1402A27D0 MP 0x14035AB10 {"_meth_806F", 0x806F}, // SP 0x1402A23E0 MP 0x14035A9C0 @@ -882,47 +882,47 @@ namespace scripting {"_meth_8074", 0x8074}, // SP 0x1405D92F0 MP 0x000000000 {"_meth_8075", 0x8075}, // SP 0x1405D92F0 MP 0x000000000 {"_meth_8076", 0x8076}, // SP 0x1402ACC40 MP 0x1403798B0 - {"_meth_8077", 0x8077}, // SP 0x1402ACC60 MP 0x1403798F0 + {"playloopsound", 0x8077}, // SP 0x1402ACC60 MP 0x1403798F0 {"_meth_8078", 0x8078}, // SP 0x1402ACCD0 MP 0x000000000 {"_meth_8079", 0x8079}, // SP 0x1402ACD40 MP 0x000000000 {"_meth_807A", 0x807A}, // SP 0x1402ACDD0 MP 0x000000000 {"_meth_807B", 0x807B}, // SP 0x1402ACE30 MP 0x000000000 {"_meth_807C", 0x807C}, // SP 0x1402ACEE0 MP 0x000000000 - {"_meth_807D", 0x807D}, // SP 0x1402ACFF0 MP 0x1403799E0 + {"getnormalhealth", 0x807D}, // SP 0x1402ACFF0 MP 0x1403799E0 {"_meth_807E", 0x807E}, // SP 0x14028FA50 MP 0x14035B880 {"_meth_807F", 0x807F}, // SP 0x14028FB40 MP 0x14035B8D0 {"_meth_8080", 0x8080}, // SP 0x14028FB60 MP 0x14035BD70 - {"_meth_8081", 0x8081}, // SP 0x14028FBE0 MP 0x14035C100 - {"_meth_8082", 0x8082}, // SP 0x140292720 MP 0x14035DCB0 - {"_meth_8083", 0x8083}, // SP 0x140290050 MP 0x14035C5A0 + {"playerlinktoabsolute", 0x8081}, // SP 0x14028FBE0 MP 0x14035C100 + {"playerlinktoblend", 0x8082}, // SP 0x140292720 MP 0x14035DCB0 + {"playerlinkedoffsetenable", 0x8083}, // SP 0x140290050 MP 0x14035C5A0 {"_meth_8084", 0x8084}, // SP 0x14026DC10 MP 0x14033BBF0 {"_meth_8085", 0x8085}, // SP 0x14026DC60 MP 0x14033BC00 - {"_meth_8086", 0x8086}, // SP 0x14026E020 MP 0x14033BF50 - {"_meth_8087", 0x8087}, // SP 0x14026E160 MP 0x14033C090 + {"changefontscaleovertime", 0x8086}, // SP 0x14026E020 MP 0x14033BF50 + {"scaleovertime", 0x8087}, // SP 0x14026E160 MP 0x14033C090 {"_meth_8088", 0x8088}, // SP 0x14026E240 MP 0x14033C170 {"_meth_8089", 0x8089}, // SP 0x14026E380 MP 0x14033C230 - {"_meth_808A", 0x808A}, // SP 0x14026E3C0 MP 0x14033C310 + {"destroy", 0x808A}, // SP 0x14026E3C0 MP 0x14033C310 {"_meth_808B", 0x808B}, // SP 0x14026E500 MP 0x14033C3F0 {"_meth_808C", 0x808C}, // SP 0x14026E440 MP 0x14033C360 - {"_meth_808D", 0x808D}, // SP 0x14026E0C0 MP 0x14033BFF0 + {"fadeovertime", 0x808D}, // SP 0x14026E0C0 MP 0x14033BFF0 {"_meth_808E", 0x808E}, // SP 0x1402A83E0 MP 0x000000000 {"_meth_808F", 0x808F}, // SP 0x1402A8400 MP 0x000000000 {"_meth_8090", 0x8090}, // SP 0x1402A8970 MP 0x000000000 {"_meth_8091", 0x8091}, // SP 0x1402A89D0 MP 0x000000000 {"_meth_8092", 0x8092}, // SP 0x1402AD800 MP 0x000000000 - {"_meth_8093", 0x8093}, // SP 0x1402A9070 MP 0x1403752A0 - {"_meth_8094", 0x8094}, // SP 0x1402A0070 MP 0x140358360 + {"playersetgroundreferenceent", 0x8093}, // SP 0x1402A9070 MP 0x1403752A0 + {"dontinterpolate", 0x8094}, // SP 0x1402A0070 MP 0x140358360 {"_meth_8095", 0x8095}, // SP 0x1402AAC80 MP 0x000000000 {"_meth_8096", 0x8096}, // SP 0x1402AAD20 MP 0x000000000 {"_meth_8097", 0x8097}, // SP 0x1402AADC0 MP 0x140377CA0 {"_meth_8098", 0x8098}, // SP 0x1402AAE70 MP 0x000000000 {"_meth_8099", 0x8099}, // SP 0x1402AAF90 MP 0x000000000 {"_meth_809A", 0x809A}, // SP 0x1402AC1D0 MP 0x000000000 - {"_meth_809B", 0x809B}, // SP 0x1402AC470 MP 0x140377D00 - {"_meth_809C", 0x809C}, // SP 0x1402AC9B0 MP 0x140377F40 - {"_meth_80A1", 0x80A1}, // SP 0x140290320 MP 0x14035CAF0 - {"_meth_80A2", 0x80A2}, // SP 0x140290680 MP 0x14035CE40 - {"_meth_80A3", 0x80A3}, // SP 0x140290960 MP 0x14035D290 + {"useby", 0x809B}, // SP 0x1402AC470 MP 0x140377D00 + {"playsound", 0x809C}, // SP 0x1402AC9B0 MP 0x140377F40 + {"playerlinkedoffsetdisable", 0x80A1}, // SP 0x140290320 MP 0x14035CAF0 + {"playerlinkedsetviewznear", 0x80A2}, // SP 0x140290680 MP 0x14035CE40 + {"playerlinkedsetusebaseangleforviewclamp", 0x80A3}, // SP 0x140290960 MP 0x14035D290 {"_meth_80A4", 0x80A4}, // SP 0x140294B30 MP 0x14035F4A0 {"_meth_80A5", 0x80A5}, // SP 0x140295300 MP 0x14035FD70 {"_meth_80A6", 0x80A6}, // SP 0x1402958C0 MP 0x000000000 @@ -930,27 +930,27 @@ namespace scripting {"_meth_80A8", 0x80A8}, // SP 0x140297190 MP 0x000000000 {"_meth_80A9", 0x80A9}, // SP 0x140297C20 MP 0x000000000 {"_meth_80AA", 0x80AA}, // SP 0x14029DDD0 MP 0x1403663C0 - {"_meth_80AB", 0x80AB}, // SP 0x140290390 MP 0x14035B440 - {"_meth_80AC", 0x80AC}, // SP 0x1402904A0 MP 0x14035B650 + {"istouching", 0x80AB}, // SP 0x140290390 MP 0x14035B440 + {"getistouchingentities", 0x80AC}, // SP 0x1402904A0 MP 0x14035B650 {"_meth_80AD", 0x80AD}, // SP 0x1402987B0 MP 0x14035FAA0 - {"_meth_80AE", 0x80AE}, // SP 0x140290F40 MP 0x14035C610 - {"_meth_80AF", 0x80AF}, // SP 0x140299090 MP 0x140360200 - {"_meth_80B0", 0x80B0}, // SP 0x140299200 MP 0x1403602A0 - {"_meth_80B1", 0x80B1}, // SP 0x1402997D0 MP 0x1403608E0 - {"_meth_80B2", 0x80B2}, // SP 0x14029DAA0 MP 0x140366320 - {"_meth_80B3", 0x80B3}, // SP 0x14029C8F0 MP 0x1403677D0 + {"stopsounds", 0x80AE}, // SP 0x140290F40 MP 0x14035C610 + {"playrumbleonentity", 0x80AF}, // SP 0x140299090 MP 0x140360200 + {"playrumblelooponentity", 0x80B0}, // SP 0x140299200 MP 0x1403602A0 + {"stoprumble", 0x80B1}, // SP 0x1402997D0 MP 0x1403608E0 + {"delete", 0x80B2}, // SP 0x14029DAA0 MP 0x140366320 + {"setmodel", 0x80B3}, // SP 0x14029C8F0 MP 0x1403677D0 {"_meth_80B4", 0x80B4}, // SP 0x14029A0F0 MP 0x140361C30 {"_meth_80B5", 0x80B5}, // SP 0x14029A250 MP 0x140361F90 - {"_meth_80B8", 0x80B8}, // SP 0x14029A450 MP 0x1403623A0 - {"_meth_80B9", 0x80B9}, // SP 0x14029AAF0 MP 0x140362B70 + {"thermalvisionon", 0x80B8}, // SP 0x14029A450 MP 0x1403623A0 + {"thermalvisionoff", 0x80B9}, // SP 0x14029AAF0 MP 0x140362B70 {"_meth_80BA", 0x80BA}, // SP 0x14029BF20 MP 0x140364290 {"_meth_80BB", 0x80BB}, // SP 0x14029C080 MP 0x140364630 {"_meth_80BC", 0x80BC}, // SP 0x000000000 MP 0x140364910 - {"_meth_80BD", 0x80BD}, // SP 0x000000000 MP 0x140364A50 + {"autospotoverlayon", 0x80BD}, // SP 0x000000000 MP 0x140364A50 {"_meth_80BE", 0x80BE}, // SP 0x000000000 MP 0x140364D40 - {"_meth_80C0", 0x80C0}, // SP 0x140297CC0 MP 0x14035FDD0 - {"_meth_80C1", 0x80C1}, // SP 0x140297E90 MP 0x1403600D0 - {"_meth_80C2", 0x80C2}, // SP 0x140297FF0 MP 0x140360320 + {"setcontents", 0x80C0}, // SP 0x140297CC0 MP 0x14035FDD0 + {"makeusable", 0x80C1}, // SP 0x140297E90 MP 0x1403600D0 + {"makeunusable", 0x80C2}, // SP 0x140297FF0 MP 0x140360320 {"_meth_80C3", 0x80C3}, // SP 0x1402A1730 MP 0x140359740 {"_meth_80C4", 0x80C4}, // SP 0x1402A1A80 MP 0x140359DC0 {"_meth_80C5", 0x80C5}, // SP 0x140266A20 MP 0x000000000 @@ -960,9 +960,9 @@ namespace scripting {"_meth_80C9", 0x80C9}, // SP 0x140465630 MP 0x000000000 {"_meth_80CA", 0x80CA}, // SP 0x1404656C0 MP 0x000000000 {"_meth_80CB", 0x80CB}, // SP 0x140464F50 MP 0x000000000 - {"_meth_80CC", 0x80CC}, // SP 0x14026CE20 MP 0x14033AF40 + {"settext", 0x80CC}, // SP 0x14026CE20 MP 0x14033AF40 {"_meth_80CD", 0x80CD}, // SP 0x1405D92F0 MP 0x14033B030 - {"_meth_80CE", 0x80CE}, // SP 0x14026CEE0 MP 0x14033B040 + {"setshader", 0x80CE}, // SP 0x14026CEE0 MP 0x14033B040 {"_meth_80CF", 0x80CF}, // SP 0x14026D230 MP 0x14033B3A0 {"_meth_80D0", 0x80D0}, // SP 0x14026D3B0 MP 0x14033B530 {"_meth_80D1", 0x80D1}, // SP 0x14026D490 MP 0x14033B600 @@ -971,29 +971,29 @@ namespace scripting {"_meth_80D4", 0x80D4}, // SP 0x14026D700 MP 0x14033B810 {"_meth_80D5", 0x80D5}, // SP 0x14026D7D0 MP 0x14033B8D0 {"_meth_80D6", 0x80D6}, // SP 0x14026D8A0 MP 0x14033B970 - {"_meth_80D7", 0x80D7}, // SP 0x14026D970 MP 0x14033BA20 - {"_meth_80D8", 0x80D8}, // SP 0x14026D990 MP 0x14033BA40 - {"_meth_80D9", 0x80D9}, // SP 0x14026D9B0 MP 0x14033BA60 - {"_meth_80DA", 0x80DA}, // SP 0x14026DA50 MP 0x14033BAE0 + {"setclock", 0x80D7}, // SP 0x14026D970 MP 0x14033BA20 + {"setclockup", 0x80D8}, // SP 0x14026D990 MP 0x14033BA40 + {"setvalue", 0x80D9}, // SP 0x14026D9B0 MP 0x14033BA60 + {"setwaypoint", 0x80DA}, // SP 0x14026DA50 MP 0x14033BAE0 {"_meth_80DB", 0x80DB}, // SP 0x14026DBC0 MP 0x14033BBE0 - {"_meth_80DC", 0x80DC}, // SP 0x1402983E0 MP 0x1403607E0 - {"_meth_80DD", 0x80DD}, // SP 0x140299300 MP 0x140361060 + {"setcursorhint", 0x80DC}, // SP 0x1402983E0 MP 0x1403607E0 + {"sethintstring", 0x80DD}, // SP 0x140299300 MP 0x140361060 {"_meth_80DE", 0x80DE}, // SP 0x000000000 MP 0x140375C60 - {"_meth_80DF", 0x80DF}, // SP 0x140299730 MP 0x140361260 + {"forceusehinton", 0x80DF}, // SP 0x140299730 MP 0x140361260 {"_meth_80E0", 0x80E0}, // SP 0x140299930 MP 0x140361530 {"_meth_80E1", 0x80E1}, // SP 0x140298080 MP 0x140360440 {"_meth_80E2", 0x80E2}, // SP 0x140298160 MP 0x140360570 - {"_meth_80E3", 0x80E3}, // SP 0x1405D92F0 MP 0x140360620 + {"entitywillneverchange", 0x80E3}, // SP 0x1405D92F0 MP 0x140360620 {"_meth_80E4", 0x80E4}, // SP 0x140291140 MP 0x14035D1B0 {"_meth_80E5", 0x80E5}, // SP 0x1402912D0 MP 0x14035D310 - {"_meth_80E6", 0x80E6}, // SP 0x140291490 MP 0x14035D460 - {"_meth_80E7", 0x80E7}, // SP 0x1402915B0 MP 0x14035D650 - {"_meth_80E8", 0x80E8}, // SP 0x1402916E0 MP 0x14035D8D0 - {"_meth_80E9", 0x80E9}, // SP 0x140291A10 MP 0x14035DA40 + {"isfiringturret", 0x80E6}, // SP 0x140291490 MP 0x14035D460 + {"startbarrelspin", 0x80E7}, // SP 0x1402915B0 MP 0x14035D650 + {"stopbarrelspin", 0x80E8}, // SP 0x1402916E0 MP 0x14035D8D0 + {"getbarrelspinrate", 0x80E9}, // SP 0x140291A10 MP 0x14035DA40 {"_meth_80EA", 0x80EA}, // SP 0x000000000 MP 0x14035C870 - {"_meth_80EB", 0x80EB}, // SP 0x000000000 MP 0x14035CDD0 + {"remotecontrolturretoff", 0x80EB}, // SP 0x000000000 MP 0x14035CDD0 {"_meth_80EC", 0x80EC}, // SP 0x140293380 MP 0x14035E870 - {"_meth_80ED", 0x80ED}, // SP 0x140293430 MP 0x14035EE50 + {"getturretowner", 0x80ED}, // SP 0x140293430 MP 0x14035EE50 {"_meth_80EE", 0x80EE}, // SP 0x140268590 MP 0x000000000 {"_meth_80EF", 0x80EF}, // SP 0x1402685F0 MP 0x000000000 {"_meth_80F0", 0x80F0}, // SP 0x140268640 MP 0x000000000 @@ -1017,14 +1017,14 @@ namespace scripting {"_meth_8102", 0x8102}, // SP 0x140268930 MP 0x000000000 {"_meth_8103", 0x8103}, // SP 0x1402616E0 MP 0x000000000 {"_meth_8104", 0x8104}, // SP 0x1402667A0 MP 0x000000000 - {"_meth_8105", 0x8105}, // SP 0x1402935E0 MP 0x14035EF40 - {"_meth_8106", 0x8106}, // SP 0x140293F00 MP 0x14035F1B0 - {"_meth_8107", 0x8107}, // SP 0x1402942F0 MP 0x14035F6D0 - {"_meth_8108", 0x8108}, // SP 0x140294600 MP 0x14035F860 - {"_meth_8109", 0x8109}, // SP 0x140294A20 MP 0x14035FB70 - {"_meth_810A", 0x810A}, // SP 0x140294E90 MP 0x14035FE30 - {"_meth_810B", 0x810B}, // SP 0x140295270 MP 0x140360040 - {"_meth_810C", 0x810C}, // SP 0x1402957F0 MP 0x1403606C0 + {"setsentryowner", 0x8105}, // SP 0x1402935E0 MP 0x14035EF40 + {"setsentrycarrier", 0x8106}, // SP 0x140293F00 MP 0x14035F1B0 + {"setturretminimapvisible", 0x8107}, // SP 0x1402942F0 MP 0x14035F6D0 + {"settargetentity", 0x8108}, // SP 0x140294600 MP 0x14035F860 + {"snaptotargetentity", 0x8109}, // SP 0x140294A20 MP 0x14035FB70 + {"cleartargetentity", 0x810A}, // SP 0x140294E90 MP 0x14035FE30 + {"getturrettarget", 0x810B}, // SP 0x140295270 MP 0x140360040 + {"setplayerspread", 0x810C}, // SP 0x1402957F0 MP 0x1403606C0 {"_meth_810D", 0x810D}, // SP 0x140295A70 MP 0x140360990 {"_meth_810E", 0x810E}, // SP 0x140295D50 MP 0x1403609A0 {"_meth_810F", 0x810F}, // SP 0x14028A710 MP 0x000000000 @@ -1060,14 +1060,14 @@ namespace scripting {"_meth_8132", 0x8132}, // SP 0x140261580 MP 0x14032CD50 {"_meth_8133", 0x8133}, // SP 0x140261670 MP 0x14032CF00 {"_meth_8134", 0x8134}, // SP 0x140268530 MP 0x000000000 - {"_meth_8135", 0x8135}, // SP 0x140295E90 MP 0x140360A40 - {"_meth_8136", 0x8136}, // SP 0x140296650 MP 0x140360E90 - {"_meth_8137", 0x8137}, // SP 0x1402967E0 MP 0x140361150 + {"setconvergencetime", 0x8135}, // SP 0x140295E90 MP 0x140360A40 + {"setconvergenceheightpercent", 0x8136}, // SP 0x140296650 MP 0x140360E90 + {"setturretteam", 0x8137}, // SP 0x1402967E0 MP 0x140361150 {"_meth_8138", 0x8138}, // SP 0x140296C90 MP 0x140361320 - {"_meth_8139", 0x8139}, // SP 0x140296D70 MP 0x140361370 - {"_meth_813A", 0x813A}, // SP 0x140296E90 MP 0x1403615A0 + {"startfiring", 0x8139}, // SP 0x140296D70 MP 0x140361370 + {"stopfiring", 0x813A}, // SP 0x140296E90 MP 0x1403615A0 {"_meth_813B", 0x813B}, // SP 0x1402D7DD0 MP 0x140077920 - {"_meth_813C", 0x813C}, // SP 0x1402D7EE0 MP 0x140077A40 + {"freeentitysentient", 0x813C}, // SP 0x1402D7EE0 MP 0x140077A40 {"_meth_813D", 0x813D}, // SP 0x1402D7FE0 MP 0x000000000 {"_meth_813E", 0x813E}, // SP 0x1402D8040 MP 0x000000000 {"_meth_813F", 0x813F}, // SP 0x1402D80E0 MP 0x000000000 @@ -1097,10 +1097,10 @@ namespace scripting {"_meth_8158", 0x8158}, // SP 0x140297890 MP 0x140362410 {"_meth_8159", 0x8159}, // SP 0x140297D20 MP 0x1403629F0 {"_meth_815A", 0x815A}, // SP 0x140297F90 MP 0x140362CB0 - {"_meth_815B", 0x815B}, // SP 0x1402980D0 MP 0x140363040 + {"setautorotationdelay", 0x815B}, // SP 0x1402980D0 MP 0x140363040 {"_meth_815C", 0x815C}, // SP 0x140298800 MP 0x1403638A0 - {"_meth_815D", 0x815D}, // SP 0x140298880 MP 0x140363B30 - {"_meth_815E", 0x815E}, // SP 0x140299040 MP 0x140363CF0 + {"restoredefaultdroppitch", 0x815D}, // SP 0x140298880 MP 0x140363B30 + {"turretfiredisable", 0x815E}, // SP 0x140299040 MP 0x140363CF0 {"_meth_815F", 0x815F}, // SP 0x1402495F0 MP 0x000000000 {"_meth_8160", 0x8160}, // SP 0x1402496C0 MP 0x000000000 {"_meth_8161", 0x8161}, // SP 0x140249790 MP 0x000000000 @@ -1127,25 +1127,25 @@ namespace scripting {"_meth_8176", 0x8176}, // SP 0x14024AB30 MP 0x000000000 {"_meth_8177", 0x8177}, // SP 0x14024AB90 MP 0x000000000 {"_meth_8178", 0x8178}, // SP 0x14024AC50 MP 0x000000000 - {"_meth_8179", 0x8179}, // SP 0x1402D77E0 MP 0x1400772C0 + {"getenemysqdist", 0x8179}, // SP 0x1402D77E0 MP 0x1400772C0 {"_meth_817A", 0x817A}, // SP 0x1402D7820 MP 0x140077300 - {"_meth_817B", 0x817B}, // SP 0x1402D7BE0 MP 0x1400776E0 - {"_meth_817C", 0x817C}, // SP 0x1402D7C50 MP 0x140077750 - {"_meth_817D", 0x817D}, // SP 0x140299220 MP 0x140363EE0 - {"_meth_817E", 0x817E}, // SP 0x1402994D0 MP 0x140364690 - {"_meth_817F", 0x817F}, // SP 0x140297DE0 MP 0x14035EEE0 - {"_meth_8180", 0x8180}, // SP 0x14029D1C0 MP 0x140364F90 + {"setthreatbiasgroup", 0x817B}, // SP 0x1402D7BE0 MP 0x1400776E0 + {"getthreatbiasgroup", 0x817C}, // SP 0x1402D7C50 MP 0x140077750 + {"turretfireenable", 0x817D}, // SP 0x140299220 MP 0x140363EE0 + {"setturretmodechangewait", 0x817E}, // SP 0x1402994D0 MP 0x140364690 + {"usetriggerrequirelookat", 0x817F}, // SP 0x140297DE0 MP 0x14035EEE0 + {"getstance", 0x8180}, // SP 0x14029D1C0 MP 0x140364F90 {"_meth_8181", 0x8181}, // SP 0x14029D430 MP 0x140365230 - {"_meth_8182", 0x8182}, // SP 0x140299FA0 MP 0x140360F20 + {"itemweaponsetammo", 0x8182}, // SP 0x140299FA0 MP 0x140360F20 {"_meth_8183", 0x8183}, // SP 0x14029A5A0 MP 0x140361420 - {"_meth_8184", 0x8184}, // SP 0x14029E360 MP 0x140368090 - {"_meth_8185", 0x8185}, // SP 0x14029E810 MP 0x140368320 + {"gettagorigin", 0x8184}, // SP 0x14029E360 MP 0x140368090 + {"gettagangles", 0x8185}, // SP 0x14029E810 MP 0x140368320 {"_meth_8186", 0x8186}, // SP 0x14028E580 MP 0x14036D490 - {"_meth_8187", 0x8187}, // SP 0x14028F160 MP 0x14036DEC0 + {"stunplayer", 0x8187}, // SP 0x14028F160 MP 0x14036DEC0 {"_meth_8188", 0x8188}, // SP 0x14029B970 MP 0x140366E70 {"_meth_8189", 0x8189}, // SP 0x14029BB30 MP 0x140367230 - {"_meth_818A", 0x818A}, // SP 0x14029EF20 MP 0x140368890 - {"_meth_818B", 0x818B}, // SP 0x14029F990 MP 0x140369900 + {"setdepthoffield", 0x818A}, // SP 0x14029EF20 MP 0x140368890 + {"setviewmodeldepthoffield", 0x818B}, // SP 0x14029F990 MP 0x140369900 {"_meth_818C", 0x818C}, // SP 0x1402A15D0 MP 0x14036AD20 {"_meth_818D", 0x818D}, // SP 0x140247D90 MP 0x000000000 {"_meth_818E", 0x818E}, // SP 0x140247DE0 MP 0x000000000 @@ -1163,9 +1163,9 @@ namespace scripting {"_meth_819E", 0x819E}, // SP 0x1402487C0 MP 0x000000000 {"_meth_819F", 0x819F}, // SP 0x140248870 MP 0x000000000 {"_meth_81A0", 0x81A0}, // SP 0x1402488C0 MP 0x000000000 - {"_meth_81A1", 0x81A1}, // SP 0x140248970 MP 0x14044F980 - {"_meth_81A2", 0x81A2}, // SP 0x1402489E0 MP 0x14044F830 - {"_meth_81A3", 0x81A3}, // SP 0x140248A50 MP 0x14044F8D0 + {"getnegotiationstartnode", 0x81A1}, // SP 0x140248970 MP 0x14044F980 + {"getnegotiationendnode", 0x81A2}, // SP 0x1402489E0 MP 0x14044F830 + {"getnegotiationnextnode", 0x81A3}, // SP 0x140248A50 MP 0x14044F8D0 {"_meth_81A4", 0x81A4}, // SP 0x140248B30 MP 0x000000000 {"_meth_81A5", 0x81A5}, // SP 0x140248BD0 MP 0x000000000 {"_meth_81A6", 0x81A6}, // SP 0x140248CC0 MP 0x000000000 @@ -1181,12 +1181,12 @@ namespace scripting {"_meth_81B0", 0x81B0}, // SP 0x140249500 MP 0x000000000 {"_meth_81B1", 0x81B1}, // SP 0x1402A15D0 MP 0x14036ADA0 {"_meth_81B2", 0x81B2}, // SP 0x1402A15D0 MP 0x14036AE60 - {"_meth_81B3", 0x81B3}, // SP 0x1402A1640 MP 0x14036AFA0 + {"viewkick", 0x81B3}, // SP 0x1402A1640 MP 0x14036AFA0 {"_meth_81B4", 0x81B4}, // SP 0x14029B1E0 MP 0x1403668B0 {"_meth_81B5", 0x81B5}, // SP 0x1402998B0 MP 0x140364980 - {"_meth_81B6", 0x81B6}, // SP 0x140299AA0 MP 0x140364B50 - {"_meth_81B7", 0x81B7}, // SP 0x140299CA0 MP 0x140364F40 - {"_meth_81B8", 0x81B8}, // SP 0x140299F20 MP 0x1403650C0 + {"autoboltmissileeffects", 0x81B6}, // SP 0x140299AA0 MP 0x140364B50 + {"enablegrenadetouchdamage", 0x81B7}, // SP 0x140299CA0 MP 0x140364F40 + {"disablegrenadetouchdamage", 0x81B8}, // SP 0x140299F20 MP 0x1403650C0 {"_meth_81B9", 0x81B9}, // SP 0x14029AF00 MP 0x1403665A0 {"_meth_81BA", 0x81BA}, // SP 0x14024AF80 MP 0x000000000 {"_meth_81BB", 0x81BB}, // SP 0x14024B160 MP 0x000000000 @@ -1218,21 +1218,21 @@ namespace scripting {"_meth_81D5", 0x81D5}, // SP 0x140247CE0 MP 0x000000000 {"_meth_81D6", 0x81D6}, // SP 0x140247930 MP 0x000000000 {"_meth_81D7", 0x81D7}, // SP 0x14029B180 MP 0x140366790 - {"_meth_81D8", 0x81D8}, // SP 0x1402A3840 MP 0x14036C130 + {"entityradiusdamage", 0x81D8}, // SP 0x1402A3840 MP 0x14036C130 {"_meth_81D9", 0x81D9}, // SP 0x14028DCF0 MP 0x14036CAB0 - {"_meth_81DA", 0x81DA}, // SP 0x14028E350 MP 0x14036D0C0 + {"bddatachunk::deserialize", 0x81DA}, // SP 0x14028E350 MP 0x14036D0C0 {"_meth_81DB", 0x81DB}, // SP 0x14028E430 MP 0x14036D150 {"_meth_81DC", 0x81DC}, // SP 0x14029A340 MP 0x140365D80 {"_meth_81DD", 0x81DD}, // SP 0x14029A4E0 MP 0x140365E90 {"_meth_81DE", 0x81DE}, // SP 0x14029A700 MP 0x140366180 - {"_meth_81DF", 0x81DF}, // SP 0x14029AA10 MP 0x1403663A0 - {"_meth_81E0", 0x81E0}, // SP 0x14029AB50 MP 0x140366480 - {"_meth_81E1", 0x81E1}, // SP 0x14028EA00 MP 0x14036E8B0 + {"missilesetflightmodedirect", 0x81DF}, // SP 0x14029AA10 MP 0x1403663A0 + {"missilesetflightmodetop", 0x81E0}, // SP 0x14029AB50 MP 0x140366480 + {"getlightintensity", 0x81E1}, // SP 0x14028EA00 MP 0x14036E8B0 {"_meth_81E2", 0x81E2}, // SP 0x14028EB40 MP 0x14036EAB0 - {"_meth_81E3", 0x81E3}, // SP 0x14028F2F0 MP 0x14036F2E0 - {"_meth_81E4", 0x81E4}, // SP 0x1402A2860 MP 0x14036EF80 - {"_meth_81E5", 0x81E5}, // SP 0x14028FFC0 MP 0x1403584E0 - {"_meth_81E6", 0x81E6}, // SP 0x1402900C0 MP 0x140358750 + {"isragdoll", 0x81E3}, // SP 0x14028F2F0 MP 0x14036F2E0 + {"setmovespeedscale", 0x81E4}, // SP 0x1402A2860 MP 0x14036EF80 + {"cameralinkto", 0x81E5}, // SP 0x14028FFC0 MP 0x1403584E0 + {"cameraunlink", 0x81E6}, // SP 0x1402900C0 MP 0x140358750 {"_meth_81E7", 0x81E7}, // SP 0x140248F30 MP 0x000000000 {"_meth_81E8", 0x81E8}, // SP 0x1402491F0 MP 0x000000000 {"_meth_81E9", 0x81E9}, // SP 0x140249230 MP 0x000000000 @@ -1262,8 +1262,8 @@ namespace scripting {"_meth_8201", 0x8201}, // SP 0x14024AE60 MP 0x000000000 {"_meth_8202", 0x8202}, // SP 0x14024B1D0 MP 0x000000000 {"_meth_8203", 0x8203}, // SP 0x14024B2C0 MP 0x000000000 - {"_meth_8204", 0x8204}, // SP 0x1402905D0 MP 0x140358F20 - {"_meth_8205", 0x8205}, // SP 0x1402908B0 MP 0x1403593C0 + {"controlslinkto", 0x8204}, // SP 0x1402905D0 MP 0x140358F20 + {"controlsunlink", 0x8205}, // SP 0x1402908B0 MP 0x1403593C0 {"_meth_8206", 0x8206}, // SP 0x000000000 MP 0x14035AB40 {"_meth_8207", 0x8207}, // SP 0x1402AA5F0 MP 0x000000000 {"_meth_8208", 0x8208}, // SP 0x000000000 MP 0x14035ABE0 @@ -1272,8 +1272,8 @@ namespace scripting {"_meth_820C", 0x820C}, // SP 0x000000000 MP 0x14035B380 {"_meth_820D", 0x820D}, // SP 0x000000000 MP 0x14035B210 {"_meth_820E", 0x820E}, // SP 0x000000000 MP 0x14035B270 - {"_meth_820F", 0x820F}, // SP 0x140291CD0 MP 0x14035C250 - {"_meth_8210", 0x8210}, // SP 0x140292090 MP 0x14035C420 + {"drivevehicleandcontrolturret", 0x820F}, // SP 0x140291CD0 MP 0x14035C250 + {"drivevehicleandcontrolturretoff", 0x8210}, // SP 0x140292090 MP 0x14035C420 {"_meth_8211", 0x8211}, // SP 0x1402923D0 MP 0x14035C930 {"_meth_8212", 0x8212}, // SP 0x1402931B0 MP 0x14035CBB0 {"_meth_8213", 0x8213}, // SP 0x1402940E0 MP 0x14035D6A0 @@ -1281,33 +1281,33 @@ namespace scripting {"_meth_8215", 0x8215}, // SP 0x1402961E0 MP 0x14035F810 {"_meth_8216", 0x8216}, // SP 0x140296540 MP 0x14035FB00 {"_meth_8217", 0x8217}, // SP 0x1402966E0 MP 0x14035FC80 - {"_meth_8218", 0x8218}, // SP 0x1402990B0 MP 0x1403620D0 - {"_meth_8219", 0x8219}, // SP 0x140299540 MP 0x140362730 + {"circle", 0x8218}, // SP 0x1402990B0 MP 0x1403620D0 + {"rect", 0x8219}, // SP 0x140299540 MP 0x140362730 {"_meth_821A", 0x821A}, // SP 0x140299B00 MP 0x140362E50 - {"_meth_821B", 0x821B}, // SP 0x14029A1B0 MP 0x140363790 - {"_meth_821C", 0x821C}, // SP 0x140290290 MP 0x140358930 + {"transfermarkstonewscriptmodel", 0x821B}, // SP 0x14029A1B0 MP 0x140363790 + {"setwatersheeting", 0x821C}, // SP 0x140290290 MP 0x140358930 {"_meth_821D", 0x821D}, // SP 0x1402A29B0 MP 0x000000000 {"_meth_821E", 0x821E}, // SP 0x1402A32F0 MP 0x000000000 - {"_meth_821F", 0x821F}, // SP 0x140296A30 MP 0x14035FC90 - {"_meth_8220", 0x8220}, // SP 0x140297010 MP 0x140360380 + {"setweaponhudiconoverride", 0x821F}, // SP 0x140296A30 MP 0x14035FC90 + {"getweaponhudiconoverride", 0x8220}, // SP 0x140297010 MP 0x140360380 {"_meth_8221", 0x8221}, // SP 0x1402976A0 MP 0x1403609B0 {"_meth_8222", 0x8222}, // SP 0x140299CF0 MP 0x1403635A0 {"_meth_8223", 0x8223}, // SP 0x140299B90 MP 0x1403630E0 {"_meth_8224", 0x8224}, // SP 0x14029A2C0 MP 0x140363C10 {"_meth_8225", 0x8225}, // SP 0x14029DF50 MP 0x140365F70 {"_meth_8226", 0x8226}, // SP 0x1402A17F0 MP 0x14036B0B0 - {"_meth_8227", 0x8227}, // SP 0x140464260 MP 0x140562970 - {"_meth_8228", 0x8228}, // SP 0x140464340 MP 0x1405629E0 + {"vehicleturretcontroloff", 0x8227}, // SP 0x140464260 MP 0x140562970 + {"isturretready", 0x8228}, // SP 0x140464340 MP 0x1405629E0 {"_meth_8229", 0x8229}, // SP 0x140464570 MP 0x140562C70 - {"_meth_822A", 0x822A}, // SP 0x1404646D0 MP 0x140562D90 - {"_meth_822B", 0x822B}, // SP 0x1404647A0 MP 0x140562E80 - {"_meth_822C", 0x822C}, // SP 0x140464840 MP 0x140562F80 - {"_meth_822D", 0x822D}, // SP 0x140464980 MP 0x1405630A0 - {"_meth_822E", 0x822E}, // SP 0x140464B20 MP 0x140563240 - {"_meth_822F", 0x822F}, // SP 0x140464C10 MP 0x140563310 - {"_meth_8230", 0x8230}, // SP 0x140464C90 MP 0x1405633E0 - {"_meth_8231", 0x8231}, // SP 0x140464E50 MP 0x140563610 - {"_meth_8232", 0x8232}, // SP 0x000000000 MP 0x1405609B0 + {"dospawn", 0x822A}, // SP 0x1404646D0 MP 0x140562D90 + {"isphysveh", 0x822B}, // SP 0x1404647A0 MP 0x140562E80 + {"crash", 0x822C}, // SP 0x140464840 MP 0x140562F80 + {"launch", 0x822D}, // SP 0x140464980 MP 0x1405630A0 + {"disablecrashing", 0x822E}, // SP 0x140464B20 MP 0x140563240 + {"enablecrashing", 0x822F}, // SP 0x140464C10 MP 0x140563310 + {"setspeed", 0x8230}, // SP 0x140464C90 MP 0x1405633E0 + {"setconveyorbelt", 0x8231}, // SP 0x140464E50 MP 0x140563610 + {"freevehicle", 0x8232}, // SP 0x000000000 MP 0x1405609B0 {"_meth_8233", 0x8233}, // SP 0x140290E70 MP 0x000000000 {"_meth_8234", 0x8234}, // SP 0x1402910E0 MP 0x000000000 {"_meth_8235", 0x8235}, // SP 0x140291670 MP 0x000000000 @@ -1326,114 +1326,114 @@ namespace scripting {"_meth_8243", 0x8243}, // SP 0x1402A1AF0 MP 0x14036B910 {"_meth_8244", 0x8244}, // SP 0x1402A1E20 MP 0x14036BE30 {"_meth_8245", 0x8245}, // SP 0x1402A24D0 MP 0x14036C5B0 - {"_meth_8246", 0x8246}, // SP 0x14028DC50 MP 0x14036E800 - {"_meth_8247", 0x8247}, // SP 0x000000000 MP 0x140332B50 + {"trackerupdate", 0x8246}, // SP 0x14028DC50 MP 0x14036E800 + {"pingplayer", 0x8247}, // SP 0x000000000 MP 0x140332B50 {"_meth_8248", 0x8248}, // SP 0x140268FE0 MP 0x140332B40 - {"_meth_8249", 0x8249}, // SP 0x000000000 MP 0x1403345F0 - {"_meth_824A", 0x824A}, // SP 0x000000000 MP 0x1403346A0 + {"sayteam", 0x8249}, // SP 0x000000000 MP 0x1403345F0 + {"sayall", 0x824A}, // SP 0x000000000 MP 0x1403346A0 {"_meth_824B", 0x824B}, // SP 0x000000000 MP 0x140332C90 {"_meth_824C", 0x824C}, // SP 0x140265080 MP 0x140330FE0 - {"_meth_824D", 0x824D}, // SP 0x000000000 MP 0x140332FB0 - {"_meth_824E", 0x824E}, // SP 0x140461E80 MP 0x140560640 - {"_meth_824F", 0x824F}, // SP 0x140461F50 MP 0x140560710 - {"_meth_8250", 0x8250}, // SP 0x140462070 MP 0x1405607B0 - {"_meth_8251", 0x8251}, // SP 0x140462250 MP 0x1405609B0 + {"dropscavengerbag", 0x824D}, // SP 0x000000000 MP 0x140332FB0 + {"setjitterparams", 0x824E}, // SP 0x140461E80 MP 0x140560640 + {"sethoverparams", 0x824F}, // SP 0x140461F50 MP 0x140560710 + {"joltbody", 0x8250}, // SP 0x140462070 MP 0x1405607B0 + {"freevehicle", 0x8251}, // SP 0x140462250 MP 0x1405609B0 {"_meth_8252", 0x8252}, // SP 0x140462300 MP 0x140560A20 - {"_meth_8253", 0x8253}, // SP 0x140462550 MP 0x140560C70 - {"_meth_8254", 0x8254}, // SP 0x1404625D0 MP 0x140560CF0 - {"_meth_8255", 0x8255}, // SP 0x140462660 MP 0x140560D80 - {"_meth_8256", 0x8256}, // SP 0x1404626E0 MP 0x140560F10 - {"_meth_8257", 0x8257}, // SP 0x140462750 MP 0x140560F80 - {"_meth_8258", 0x8258}, // SP 0x140462840 MP 0x1405610A0 - {"_meth_8259", 0x8259}, // SP 0x1404628D0 MP 0x140561130 - {"_meth_825A", 0x825A}, // SP 0x140462950 MP 0x1405611B0 - {"_meth_825B", 0x825B}, // SP 0x1404629E0 MP 0x140561240 - {"_meth_825C", 0x825C}, // SP 0x140462A60 MP 0x1405612C0 + {"getvehicleowner", 0x8253}, // SP 0x140462550 MP 0x140560C70 + {"setvehiclelookattext", 0x8254}, // SP 0x1404625D0 MP 0x140560CF0 + {"setvehicleteam", 0x8255}, // SP 0x140462660 MP 0x140560D80 + {"neargoalnotifydist", 0x8256}, // SP 0x1404626E0 MP 0x140560F10 + {"setgoalpos", 0x8257}, // SP 0x140462750 MP 0x140560F80 + {"setgoalyaw", 0x8258}, // SP 0x140462840 MP 0x1405610A0 + {"cleargoalyaw", 0x8259}, // SP 0x1404628D0 MP 0x140561130 + {"settargetyaw", 0x825A}, // SP 0x140462950 MP 0x1405611B0 + {"cleartargetyaw", 0x825B}, // SP 0x1404629E0 MP 0x140561240 + {"helisetgoal", 0x825C}, // SP 0x140462A60 MP 0x1405612C0 {"_meth_825D", 0x825D}, // SP 0x140463320 MP 0x140561B60 - {"_meth_825E", 0x825E}, // SP 0x140463410 MP 0x140561C60 - {"_meth_825F", 0x825F}, // SP 0x140463510 MP 0x140561D60 - {"_meth_8260", 0x8260}, // SP 0x1404635A0 MP 0x140561DF0 - {"_meth_8261", 0x8261}, // SP 0x1404638A0 MP 0x1405620F0 - {"_meth_8262", 0x8262}, // SP 0x140463950 MP 0x1405621A0 - {"_meth_8263", 0x8263}, // SP 0x140463AB0 MP 0x140562280 + {"setturrettargetent", 0x825E}, // SP 0x140463410 MP 0x140561C60 + {"clearturrettargetent", 0x825F}, // SP 0x140463510 MP 0x140561D60 + {"canturrettargetpoint", 0x8260}, // SP 0x1404635A0 MP 0x140561DF0 + {"setlookatent", 0x8261}, // SP 0x1404638A0 MP 0x1405620F0 + {"clearlookatent", 0x8262}, // SP 0x140463950 MP 0x1405621A0 + {"setweapon", 0x8263}, // SP 0x140463AB0 MP 0x140562280 {"_meth_8264", 0x8264}, // SP 0x140463B20 MP 0x1405622F0 - {"_meth_8265", 0x8265}, // SP 0x1404641D0 MP 0x1405628F0 - {"_meth_8266", 0x8266}, // SP 0x000000000 MP 0x1403337A0 - {"_meth_8267", 0x8267}, // SP 0x000000000 MP 0x140333E20 + {"vehicleturretcontrolon", 0x8265}, // SP 0x1404641D0 MP 0x1405628F0 + {"finishplayerdamage", 0x8266}, // SP 0x000000000 MP 0x1403337A0 + {"suicide", 0x8267}, // SP 0x000000000 MP 0x140333E20 {"_meth_8268", 0x8268}, // SP 0x000000000 MP 0x140334010 {"_meth_8269", 0x8269}, // SP 0x000000000 MP 0x1403340A0 {"_meth_826A", 0x826A}, // SP 0x000000000 MP 0x140334120 - {"_meth_826B", 0x826B}, // SP 0x000000000 MP 0x1403341A0 + {"spawn", 0x826B}, // SP 0x000000000 MP 0x1403341A0 {"_meth_826C", 0x826C}, // SP 0x000000000 MP 0x140334230 {"_meth_826D", 0x826D}, // SP 0x000000000 MP 0x140334290 - {"_meth_826E", 0x826E}, // SP 0x000000000 MP 0x140334570 - {"_meth_826F", 0x826F}, // SP 0x000000000 MP 0x140334750 + {"istalking", 0x826E}, // SP 0x000000000 MP 0x140334570 + {"allowspectateteam", 0x826F}, // SP 0x000000000 MP 0x140334750 {"_meth_8270", 0x8270}, // SP 0x000000000 MP 0x140334980 - {"_meth_8271", 0x8271}, // SP 0x000000000 MP 0x140334B20 + {"getguid", 0x8271}, // SP 0x000000000 MP 0x140334B20 {"_meth_8272", 0x8272}, // SP 0x1402B3CA0 MP 0x14037FA00 {"_meth_8273", 0x8273}, // SP 0x1402B3EC0 MP 0x14037FC50 - {"_meth_8274", 0x8274}, // SP 0x1402B4500 MP 0x140380380 + {"clonebrushmodeltoscriptmodel", 0x8274}, // SP 0x1402B4500 MP 0x140380380 {"_meth_8275", 0x8275}, // SP 0x000000000 MP 0x140380450 - {"_meth_8276", 0x8276}, // SP 0x000000000 MP 0x140380700 + {"scriptmodelclearanim", 0x8276}, // SP 0x000000000 MP 0x140380700 {"_meth_8277", 0x8277}, // SP 0x000000000 MP 0x140380570 {"_meth_8278", 0x8278}, // SP 0x140465060 MP 0x1405637F0 - {"_meth_8279", 0x8279}, // SP 0x1404651E0 MP 0x14055F040 - {"_meth_827A", 0x827A}, // SP 0x1404652F0 MP 0x14055F170 - {"_meth_827B", 0x827B}, // SP 0x1404654A0 MP 0x14055F340 - {"_meth_827C", 0x827C}, // SP 0x140465740 MP 0x14055F4D0 - {"_meth_827D", 0x827D}, // SP 0x140465840 MP 0x14055F560 - {"_meth_827E", 0x827E}, // SP 0x000000000 MP 0x14055F5E0 - {"_meth_827F", 0x827F}, // SP 0x1404658C0 MP 0x14055F840 - {"_meth_8280", 0x8280}, // SP 0x140465930 MP 0x14055F8B0 + {"attachpath", 0x8279}, // SP 0x1404651E0 MP 0x14055F040 + {"getattachpos", 0x827A}, // SP 0x1404652F0 MP 0x14055F170 + {"startpath", 0x827B}, // SP 0x1404654A0 MP 0x14055F340 + {"setswitchnode", 0x827C}, // SP 0x140465740 MP 0x14055F4D0 + {"setwaitspeed", 0x827D}, // SP 0x140465840 MP 0x14055F560 + {"finishdamage", 0x827E}, // SP 0x000000000 MP 0x14055F5E0 + {"setspeed", 0x827F}, // SP 0x1404658C0 MP 0x14055F840 + {"setspeedimmediate", 0x8280}, // SP 0x140465930 MP 0x14055F8B0 {"_meth_8281", 0x8281}, // SP 0x140465AC0 MP 0x14055FA60 - {"_meth_8282", 0x8282}, // SP 0x140465BE0 MP 0x14055FB80 - {"_meth_8283", 0x8283}, // SP 0x140465CD0 MP 0x14055FC70 - {"_meth_8284", 0x8284}, // SP 0x140465D40 MP 0x14055FCE0 - {"_meth_8285", 0x8285}, // SP 0x140465DB0 MP 0x14055FD50 - {"_meth_8286", 0x8286}, // SP 0x140465E30 MP 0x14055FDE0 - {"_meth_8287", 0x8287}, // SP 0x140465EA0 MP 0x14055FE50 - {"_meth_8288", 0x8288}, // SP 0x140465F00 MP 0x14055FEC0 + {"getspeed", 0x8282}, // SP 0x140465BE0 MP 0x14055FB80 + {"getvelocity", 0x8283}, // SP 0x140465CD0 MP 0x14055FC70 + {"getbodyvelocity", 0x8284}, // SP 0x140465D40 MP 0x14055FCE0 + {"getsteering", 0x8285}, // SP 0x140465DB0 MP 0x14055FD50 + {"getthrottle", 0x8286}, // SP 0x140465E30 MP 0x14055FDE0 + {"turnengineoff", 0x8287}, // SP 0x140465EA0 MP 0x14055FE50 + {"turnengineon", 0x8288}, // SP 0x140465F00 MP 0x14055FEC0 {"_meth_8289", 0x8289}, // SP 0x140465F60 MP 0x000000000 - {"_meth_828A", 0x828A}, // SP 0x140466020 MP 0x14055FF30 + {"getgoalspeedmph", 0x828A}, // SP 0x140466020 MP 0x14055FF30 {"_meth_828B", 0x828B}, // SP 0x140466090 MP 0x14055FFA0 - {"_meth_828C", 0x828C}, // SP 0x140466100 MP 0x140560010 - {"_meth_828D", 0x828D}, // SP 0x140466170 MP 0x140560080 - {"_meth_828E", 0x828E}, // SP 0x140466200 MP 0x140560110 - {"_meth_828F", 0x828F}, // SP 0x140466360 MP 0x140560270 - {"_meth_8290", 0x8290}, // SP 0x140461CC0 MP 0x140560480 - {"_meth_8291", 0x8291}, // SP 0x140461D80 MP 0x140560540 - {"_meth_8292", 0x8292}, // SP 0x140461E10 MP 0x1405605D0 + {"setacceleration", 0x828C}, // SP 0x140466100 MP 0x140560010 + {"resumespeed", 0x828D}, // SP 0x140466170 MP 0x140560080 + {"setyawspeed", 0x828E}, // SP 0x140466200 MP 0x140560110 + {"setyawspeedbyname", 0x828F}, // SP 0x140466360 MP 0x140560270 + {"setmaxpitchroll", 0x8290}, // SP 0x140461CC0 MP 0x140560480 + {"setairresitance", 0x8291}, // SP 0x140461D80 MP 0x140560540 + {"setturningability", 0x8292}, // SP 0x140461E10 MP 0x1405605D0 {"_meth_8293", 0x8293}, // SP 0x140260F20 MP 0x140334B90 {"_meth_8294", 0x8294}, // SP 0x000000000 MP 0x140334D50 - {"_meth_8295", 0x8295}, // SP 0x000000000 MP 0x140334DB0 - {"_meth_8296", 0x8296}, // SP 0x000000000 MP 0x140334E10 - {"_meth_8297", 0x8297}, // SP 0x000000000 MP 0x140334E70 + {"ismlgspectator", 0x8295}, // SP 0x000000000 MP 0x140334DB0 + {"getclanidhigh", 0x8296}, // SP 0x000000000 MP 0x140334E10 + {"getclanidlow", 0x8297}, // SP 0x000000000 MP 0x140334E70 {"_meth_8298", 0x8298}, // SP 0x000000000 MP 0x140334ED0 - {"_meth_8299", 0x8299}, // SP 0x000000000 MP 0x140334F60 - {"_meth_829A", 0x829A}, // SP 0x000000000 MP 0x140334FE0 + {"getspectatingplayer", 0x8299}, // SP 0x000000000 MP 0x140334F60 + {"predictstreampos", 0x829A}, // SP 0x000000000 MP 0x140334FE0 {"_meth_829B", 0x829B}, // SP 0x000000000 MP 0x1403350D0 {"_meth_829C", 0x829C}, // SP 0x000000000 MP 0x1403350E0 - {"_meth_829D", 0x829D}, // SP 0x000000000 MP 0x1403350F0 + {"setrank", 0x829D}, // SP 0x000000000 MP 0x1403350F0 {"_meth_829E", 0x829E}, // SP 0x000000000 MP 0x140335190 - {"_meth_829F", 0x829F}, // SP 0x140260730 MP 0x14032CA40 - {"_meth_82A0", 0x82A0}, // SP 0x000000000 MP 0x14032ED90 - {"_meth_82A1", 0x82A1}, // SP 0x140263850 MP 0x14032FB10 - {"_meth_82A2", 0x82A2}, // SP 0x140265490 MP 0x1403297E0 + {"setmlgspectator", 0x829F}, // SP 0x140260730 MP 0x14032CA40 + {"visionsyncwithplayer", 0x82A0}, // SP 0x000000000 MP 0x14032ED90 + {"showhudsplash", 0x82A1}, // SP 0x140263850 MP 0x14032FB10 + {"setperk", 0x82A2}, // SP 0x140265490 MP 0x1403297E0 {"_meth_82A3", 0x82A3}, // SP 0x1402659A0 MP 0x140329D00 {"_meth_82A4", 0x82A4}, // SP 0x1402661B0 MP 0x14032A460 {"_meth_82A5", 0x82A5}, // SP 0x140265D40 MP 0x14032A0A0 - {"_meth_82A6", 0x82A6}, // SP 0x000000000 MP 0x1403323C0 + {"registerparty", 0x82A6}, // SP 0x000000000 MP 0x1403323C0 {"_meth_82A7", 0x82A7}, // SP 0x000000000 MP 0x1403324F0 {"_meth_82A8", 0x82A8}, // SP 0x1405D92F0 MP 0x14032A8F0 {"_meth_82A9", 0x82A9}, // SP 0x1405D92F0 MP 0x14032A900 - {"_meth_82AA", 0x82AA}, // SP 0x1402B2A10 MP 0x14037E950 - {"_meth_82AB", 0x82AB}, // SP 0x1402B2F60 MP 0x14037EEB0 - {"_meth_82AC", 0x82AC}, // SP 0x1402B2F70 MP 0x14037EEC0 - {"_meth_82AD", 0x82AD}, // SP 0x1402B2F90 MP 0x14037EEE0 + {"moveto", 0x82AA}, // SP 0x1402B2A10 MP 0x14037E950 + {"rotatepitch", 0x82AB}, // SP 0x1402B2F60 MP 0x14037EEB0 + {"rotateyaw", 0x82AC}, // SP 0x1402B2F70 MP 0x14037EEC0 + {"rotateroll", 0x82AD}, // SP 0x1402B2F90 MP 0x14037EEE0 {"_meth_82AE", 0x82AE}, // SP 0x1402B2C10 MP 0x14037EB00 {"_meth_82AF", 0x82AF}, // SP 0x1402B2D70 MP 0x14037EC90 {"_meth_82B0", 0x82B0}, // SP 0x1402B2EE0 MP 0x14037EE20 - {"_meth_82B1", 0x82B1}, // SP 0x1402B3030 MP 0x14037EF10 + {"rotateby", 0x82B1}, // SP 0x1402B3030 MP 0x14037EF10 {"_meth_82B2", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 {"_meth_82B3", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 {"_meth_82B4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 @@ -1442,50 +1442,50 @@ namespace scripting {"_meth_82B7", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 {"_meth_82B8", 0x82B8}, // SP 0x1402B34B0 MP 0x14037F0B0 {"_meth_82B9", 0x82B9}, // SP 0x1402B3700 MP 0x14037F3C0 - {"_meth_82BA", 0x82BA}, // SP 0x1402B45E0 MP 0x1403808A0 - {"_meth_82BB", 0x82BB}, // SP 0x1402B4690 MP 0x140380950 - {"_meth_82BC", 0x82BC}, // SP 0x1402B3880 MP 0x14037F590 - {"_meth_82BD", 0x82BD}, // SP 0x1402B38E0 MP 0x14037F5F0 - {"_meth_82BE", 0x82BE}, // SP 0x1402B3960 MP 0x14037F670 + {"solid", 0x82BA}, // SP 0x1402B45E0 MP 0x1403808A0 + {"notsolid", 0x82BB}, // SP 0x1402B4690 MP 0x140380950 + {"setcandamage", 0x82BC}, // SP 0x1402B3880 MP 0x14037F590 + {"setcanradiusdamage", 0x82BD}, // SP 0x1402B38E0 MP 0x14037F5F0 + {"physicslaunchclient", 0x82BE}, // SP 0x1402B3960 MP 0x14037F670 {"_meth_82BF", 0x82BF}, // SP 0x000000000 MP 0x1403351A0 {"_meth_82C0", 0x82C0}, // SP 0x000000000 MP 0x1403351B0 - {"_meth_82C1", 0x82C1}, // SP 0x000000000 MP 0x1403351C0 - {"_meth_82C2", 0x82C2}, // SP 0x000000000 MP 0x1403352B0 - {"_meth_82C3", 0x82C3}, // SP 0x000000000 MP 0x140331E00 + {"setcarddisplayslot", 0x82C1}, // SP 0x000000000 MP 0x1403351C0 + {"regweaponforfxremoval", 0x82C2}, // SP 0x000000000 MP 0x1403352B0 + {"laststandrevive", 0x82C3}, // SP 0x000000000 MP 0x140331E00 {"_meth_82C4", 0x82C4}, // SP 0x000000000 MP 0x140331E70 - {"_meth_82C5", 0x82C5}, // SP 0x000000000 MP 0x140331EE0 - {"_meth_82C6", 0x82C6}, // SP 0x000000000 MP 0x140332250 + {"setspectatedefaults", 0x82C5}, // SP 0x000000000 MP 0x140331EE0 + {"getthirdpersoncrosshairoffset", 0x82C6}, // SP 0x000000000 MP 0x140332250 {"_meth_82C7", 0x82C7}, // SP 0x140262950 MP 0x14032EF00 {"_meth_82C8", 0x82C8}, // SP 0x140262A60 MP 0x14032EFF0 {"_meth_82C9", 0x82C9}, // SP 0x140262AB0 MP 0x14032F0D0 {"_meth_82CA", 0x82CA}, // SP 0x000000000 MP 0x1403322C0 - {"_meth_82CB", 0x82CB}, // SP 0x1402623D0 MP 0x14032E3A0 + {"getweaponslistexclusives", 0x82CB}, // SP 0x1402623D0 MP 0x14032E3A0 {"_meth_82CC", 0x82CC}, // SP 0x1402624C0 MP 0x14032E4B0 {"_meth_82CD", 0x82CD}, // SP 0x1402625B0 MP 0x14032E650 - {"_meth_82CE", 0x82CE}, // SP 0x140262720 MP 0x14032E790 - {"_meth_82CF", 0x82CF}, // SP 0x140264D00 MP 0x140331530 - {"_meth_82D0", 0x82D0}, // SP 0x1402651B0 MP 0x1403292E0 - {"_meth_82D1", 0x82D1}, // SP 0x140263410 MP 0x14032FC00 - {"_meth_82D2", 0x82D2}, // SP 0x1402636D0 MP 0x14032FC10 - {"_meth_82D3", 0x82D3}, // SP 0x1402636F0 MP 0x14032FC30 - {"_meth_82D4", 0x82D4}, // SP 0x140263710 MP 0x14032FD20 - {"_meth_82D5", 0x82D5}, // SP 0x140263730 MP 0x14032FD40 - {"_meth_82D6", 0x82D6}, // SP 0x140264890 MP 0x140330B80 + {"getweaponslist", 0x82CE}, // SP 0x140262720 MP 0x14032E790 + {"canplayerplacesentry", 0x82CF}, // SP 0x140264D00 MP 0x140331530 + {"canplayerplacetank", 0x82D0}, // SP 0x1402651B0 MP 0x1403292E0 + {"visionsetnakedforplayer", 0x82D1}, // SP 0x140263410 MP 0x14032FC00 + {"visionsetnightforplayer", 0x82D2}, // SP 0x1402636D0 MP 0x14032FC10 + {"visionsetmissilecamforplayer", 0x82D3}, // SP 0x1402636F0 MP 0x14032FC30 + {"visionsetthermalforplayer", 0x82D4}, // SP 0x140263710 MP 0x14032FD20 + {"visionsetpainforplayer", 0x82D5}, // SP 0x140263730 MP 0x14032FD40 + {"setblurforplayer", 0x82D6}, // SP 0x140264890 MP 0x140330B80 {"_meth_82D7", 0x82D7}, // SP 0x140264C80 MP 0x140331310 {"_meth_82D8", 0x82D8}, // SP 0x140264C80 MP 0x140331330 {"_meth_82D9", 0x82D9}, // SP 0x1402ABE90 MP 0x000000000 - {"_meth_82DA", 0x82DA}, // SP 0x1402663A0 MP 0x14032A910 + {"getbuildnumber", 0x82DA}, // SP 0x1402663A0 MP 0x14032A910 {"_meth_82DB", 0x82DB}, // SP 0x140266AF0 MP 0x14032AE90 {"_meth_82DC", 0x82DC}, // SP 0x140266CD0 MP 0x14032B120 {"_meth_82DD", 0x82DD}, // SP 0x140266FE0 MP 0x14032B500 - {"_meth_82DE", 0x82DE}, // SP 0x140267330 MP 0x14032B9F0 - {"_meth_82DF", 0x82DF}, // SP 0x140267530 MP 0x14032BD00 + {"playfx", 0x82DE}, // SP 0x140267330 MP 0x14032B9F0 + {"playerrecoilscaleon", 0x82DF}, // SP 0x140267530 MP 0x14032BD00 {"_meth_82E0", 0x82E0}, // SP 0x140267600 MP 0x14032BDD0 - {"_meth_82E1", 0x82E1}, // SP 0x1402676E0 MP 0x14032C000 - {"_meth_82E2", 0x82E2}, // SP 0x140260240 MP 0x14032C240 - {"_meth_82E3", 0x82E3}, // SP 0x140260540 MP 0x14032C6C0 - {"_meth_82E4", 0x82E4}, // SP 0x1402605E0 MP 0x14032C7F0 - {"_meth_82E5", 0x82E5}, // SP 0x000000000 MP 0x140332300 + {"weaponlockstart", 0x82E1}, // SP 0x1402676E0 MP 0x14032C000 + {"weaponlockfinalize", 0x82E2}, // SP 0x140260240 MP 0x14032C240 + {"disableautoreload", 0x82E3}, // SP 0x140260540 MP 0x14032C6C0 + {"setentertime", 0x82E4}, // SP 0x1402605E0 MP 0x14032C7F0 + {"usinggamepad", 0x82E5}, // SP 0x000000000 MP 0x140332300 {"_meth_82E6", 0x82E6}, // SP 0x000000000 MP 0x140332380 {"_meth_82E7", 0x82E7}, // SP 0x000000000 MP 0x140332390 {"_meth_82E8", 0x82E8}, // SP 0x000000000 MP 0x1403323B0 @@ -1493,50 +1493,50 @@ namespace scripting {"_meth_82EA", 0x82EA}, // SP 0x1402628A0 MP 0x14032E5C0 {"_meth_82EB", 0x82EB}, // SP 0x1402619B0 MP 0x14032D5A0 {"_meth_82EC", 0x82EC}, // SP 0x140261AA0 MP 0x14032D6D0 - {"_meth_82ED", 0x82ED}, // SP 0x140263D40 MP 0x14032FA10 - {"_meth_82EE", 0x82EE}, // SP 0x1402601C0 MP 0x14032BBE0 + {"issighted", 0x82ED}, // SP 0x140263D40 MP 0x14032FA10 + {"setvelocity", 0x82EE}, // SP 0x1402601C0 MP 0x14032BBE0 {"_meth_82EF", 0x82EF}, // SP 0x140260AD0 MP 0x14032C3C0 {"_meth_82F0", 0x82F0}, // SP 0x140260E80 MP 0x14032C5E0 {"_meth_82F1", 0x82F1}, // SP 0x1402677A0 MP 0x14032BE30 {"_meth_82F2", 0x82F2}, // SP 0x140260130 MP 0x14032BF20 {"_meth_82F3", 0x82F3}, // SP 0x140264AD0 MP 0x140330E20 - {"_meth_82F4", 0x82F4}, // SP 0x140264EB0 MP 0x140331350 + {"setweaponammostock", 0x82F4}, // SP 0x140264EB0 MP 0x140331350 {"_meth_82F5", 0x82F5}, // SP 0x140265380 MP 0x1403293A0 - {"_meth_82F6", 0x82F6}, // SP 0x1402655D0 MP 0x140329580 + {"getweaponammostock", 0x82F6}, // SP 0x1402655D0 MP 0x140329580 {"_meth_82F7", 0x82F7}, // SP 0x140265820 MP 0x140329990 - {"_meth_82F8", 0x82F8}, // SP 0x140265F20 MP 0x14032A3B0 - {"_meth_82F9", 0x82F9}, // SP 0x140266410 MP 0x14032A990 + {"stoplocalsound", 0x82F8}, // SP 0x140265F20 MP 0x14032A3B0 + {"setclientdvar", 0x82F9}, // SP 0x140266410 MP 0x14032A990 {"_meth_82FA", 0x82FA}, // SP 0x1402666C0 MP 0x14032B260 {"_meth_82FB", 0x82FB}, // SP 0x000000000 MP 0x14032AC30 {"_meth_82FC", 0x82FC}, // SP 0x000000000 MP 0x14032AD80 - {"_meth_82FD", 0x82FD}, // SP 0x140261130 MP 0x14032C940 + {"allowads", 0x82FD}, // SP 0x140261130 MP 0x14032C940 {"_meth_82FE", 0x82FE}, // SP 0x140261440 MP 0x14032CAB0 {"_meth_82FF", 0x82FF}, // SP 0x140261B20 MP 0x14032D890 {"_meth_8300", 0x8300}, // SP 0x140261C00 MP 0x14032DA40 - {"_meth_8301", 0x8301}, // SP 0x140261CE0 MP 0x14032DBB0 - {"_meth_8302", 0x8302}, // SP 0x140262B00 MP 0x14032ED00 - {"_meth_8303", 0x8303}, // SP 0x140262CC0 MP 0x14032EE80 + {"weaponlocktargettooclose", 0x8301}, // SP 0x140261CE0 MP 0x14032DBB0 + {"setspreadoverride", 0x8302}, // SP 0x140262B00 MP 0x14032ED00 + {"resetspreadoverride", 0x8303}, // SP 0x140262CC0 MP 0x14032EE80 {"_meth_8304", 0x8304}, // SP 0x140262D90 MP 0x14032EF60 - {"_meth_8305", 0x8305}, // SP 0x140261F10 MP 0x14032DD50 - {"_meth_8306", 0x8306}, // SP 0x1402608B0 MP 0x14032CB90 - {"_meth_8307", 0x8307}, // SP 0x140260A80 MP 0x14032CCC0 - {"_meth_8308", 0x8308}, // SP 0x1402621A0 MP 0x14032E120 - {"_meth_8309", 0x8309}, // SP 0x1402622E0 MP 0x14032E230 + {"setactionslot", 0x8305}, // SP 0x140261F10 MP 0x14032DD50 + {"setviewkickscale", 0x8306}, // SP 0x1402608B0 MP 0x14032CB90 + {"getviewkickscale", 0x8307}, // SP 0x140260A80 MP 0x14032CCC0 + {"getweaponslistoffhands", 0x8308}, // SP 0x1402621A0 MP 0x14032E120 + {"getweaponslistitems", 0x8309}, // SP 0x1402622E0 MP 0x14032E230 {"_meth_830A", 0x830A}, // SP 0x140261090 MP 0x14032C720 {"_meth_830B", 0x830B}, // SP 0x140262F00 MP 0x14032EA90 {"_meth_830C", 0x830C}, // SP 0x140263380 MP 0x14032F210 - {"_meth_830D", 0x830D}, // SP 0x1402635B0 MP 0x14032F310 - {"_meth_830E", 0x830E}, // SP 0x140263750 MP 0x14032F5E0 - {"_meth_830F", 0x830F}, // SP 0x140263A30 MP 0x14032F860 - {"_meth_8310", 0x8310}, // SP 0x140263EF0 MP 0x14032FC50 - {"_meth_8311", 0x8311}, // SP 0x1402647A0 MP 0x140330740 - {"_meth_8312", 0x8312}, // SP 0x140264CA0 MP 0x140330D20 - {"_meth_8313", 0x8313}, // SP 0x140264E50 MP 0x140330D90 + {"takeallweapons", 0x830D}, // SP 0x1402635B0 MP 0x14032F310 + {"getcurrentweapon", 0x830E}, // SP 0x140263750 MP 0x14032F5E0 + {"getcurrentprimaryweapon", 0x830F}, // SP 0x140263A30 MP 0x14032F860 + {"getcurrentoffhand", 0x8310}, // SP 0x140263EF0 MP 0x14032FC50 + {"givestartammo", 0x8311}, // SP 0x1402647A0 MP 0x140330740 + {"switchtoweapon", 0x8312}, // SP 0x140264CA0 MP 0x140330D20 + {"switchtoweaponimmediate", 0x8313}, // SP 0x140264E50 MP 0x140330D90 {"_meth_8314", 0x8314}, // SP 0x140265950 MP 0x140329520 - {"_meth_8315", 0x8315}, // SP 0x140265B80 MP 0x1403296D0 + {"switchtooffhand", 0x8315}, // SP 0x140265B80 MP 0x1403296D0 {"_meth_8316", 0x8316}, // SP 0x140264440 MP 0x140330340 - {"_meth_8317", 0x8317}, // SP 0x140264600 MP 0x140330520 - {"_meth_8318", 0x8318}, // SP 0x140260C90 MP 0x14032C470 + {"getcustomizationbody", 0x8317}, // SP 0x140264600 MP 0x140330520 + {"beginlocationselection", 0x8318}, // SP 0x140260C90 MP 0x14032C470 {"_meth_8319", 0x8319}, // SP 0x140261020 MP 0x14032C780 {"_meth_831A", 0x831A}, // SP 0x140263E90 MP 0x1403302E0 {"_meth_831B", 0x831B}, // SP 0x140264020 MP 0x140330410 @@ -1544,38 +1544,38 @@ namespace scripting {"_meth_831D", 0x831D}, // SP 0x140264270 MP 0x1403306E0 {"_meth_831E", 0x831E}, // SP 0x140264660 MP 0x140330B20 {"_meth_831F", 0x831F}, // SP 0x140264750 MP 0x140330CC0 - {"_meth_8320", 0x8320}, // SP 0x1402631F0 MP 0x14032F130 - {"_meth_8321", 0x8321}, // SP 0x140263290 MP 0x14032F3A0 + {"setaimspreadmovementscale", 0x8320}, // SP 0x1402631F0 MP 0x14032F130 + {"closemenu", 0x8321}, // SP 0x140263290 MP 0x14032F3A0 {"_meth_8322", 0x8322}, // SP 0x140263330 MP 0x14032F4E0 - {"_meth_8323", 0x8323}, // SP 0x140263430 MP 0x14032F6C0 - {"_meth_8324", 0x8324}, // SP 0x140263630 MP 0x14032F930 - {"_meth_8326", 0x8326}, // SP 0x140263B10 MP 0x14032FD60 - {"_meth_8327", 0x8327}, // SP 0x140263C10 MP 0x14032FFE0 - {"_meth_8328", 0x8328}, // SP 0x140263E40 MP 0x1403300F0 + {"openpopupmenu", 0x8323}, // SP 0x140263430 MP 0x14032F6C0 + {"openpopupmenunomouse", 0x8324}, // SP 0x140263630 MP 0x14032F930 + {"freezecontrols", 0x8326}, // SP 0x140263B10 MP 0x14032FD60 + {"disableusability", 0x8327}, // SP 0x140263C10 MP 0x14032FFE0 + {"enableusability", 0x8328}, // SP 0x140263E40 MP 0x1403300F0 {"_meth_8329", 0x8329}, // SP 0x140266C00 MP 0x14032B640 {"_meth_832A", 0x832A}, // SP 0x140266D10 MP 0x14032B800 {"_meth_832B", 0x832B}, // SP 0x140266EA0 MP 0x14032B9C0 {"_meth_832C", 0x832C}, // SP 0x140267180 MP 0x14032B9E0 - {"_meth_832D", 0x832D}, // SP 0x140267410 MP 0x14032BB00 + {"deactivatechannelvolumes", 0x832D}, // SP 0x140267410 MP 0x14032BB00 {"_meth_832E", 0x832E}, // SP 0x140265FA0 MP 0x140329C00 {"_meth_832F", 0x832F}, // SP 0x140266200 MP 0x140329F00 {"_meth_8330", 0x8330}, // SP 0x140266560 MP 0x14032A240 {"_meth_8331", 0x8331}, // SP 0x140266820 MP 0x14032A6F0 - {"_meth_8332", 0x8332}, // SP 0x140266E10 MP 0x14032ABC0 + {"isdualwielding", 0x8332}, // SP 0x140266E10 MP 0x14032ABC0 {"_meth_8333", 0x8333}, // SP 0x140267030 MP 0x14032AD00 - {"_meth_8334", 0x8334}, // SP 0x140267100 MP 0x14032AEE0 - {"_meth_8335", 0x8335}, // SP 0x1402677C0 MP 0x14032B8D0 - {"_meth_8336", 0x8336}, // SP 0x1402604D0 MP 0x14032BC80 + {"isreloading", 0x8334}, // SP 0x140267100 MP 0x14032AEE0 + {"setorigin", 0x8335}, // SP 0x1402677C0 MP 0x14032B8D0 + {"getvelocity", 0x8336}, // SP 0x1402604D0 MP 0x14032BC80 {"_meth_8337", 0x8337}, // SP 0x140260930 MP 0x14032BE70 - {"_meth_8338", 0x8338}, // SP 0x140260990 MP 0x14032C0D0 - {"_meth_8339", 0x8339}, // SP 0x140261500 MP 0x14032CE10 + {"forcemantle", 0x8338}, // SP 0x140260990 MP 0x14032C0D0 + {"attackbuttonpressed", 0x8339}, // SP 0x140261500 MP 0x14032CE10 {"_meth_833A", 0x833A}, // SP 0x1402615F0 MP 0x14032D0B0 - {"_meth_833B", 0x833B}, // SP 0x1402617D0 MP 0x14032D1B0 - {"_meth_833C", 0x833C}, // SP 0x1402618D0 MP 0x14032D450 - {"_meth_833D", 0x833D}, // SP 0x140262070 MP 0x14032DC20 + {"meleebuttonpressed", 0x833B}, // SP 0x1402617D0 MP 0x14032D1B0 + {"jumpbuttonpressed", 0x833C}, // SP 0x1402618D0 MP 0x14032D450 + {"getviewheight", 0x833D}, // SP 0x140262070 MP 0x14032DC20 {"_meth_833E", 0x833E}, // SP 0x1402620C0 MP 0x14032DCE0 - {"_meth_833F", 0x833F}, // SP 0x140262280 MP 0x14032DF80 - {"_meth_8340", 0x8340}, // SP 0x1402626A0 MP 0x14032DFF0 + {"isonladder", 0x833F}, // SP 0x140262280 MP 0x14032DF80 + {"setviewmodel", 0x8340}, // SP 0x1402626A0 MP 0x14032DFF0 {"_meth_8341", 0x8341}, // SP 0x140264090 MP 0x14032FF10 {"_meth_8342", 0x8342}, // SP 0x1402642C0 MP 0x140330170 {"_meth_8343", 0x8343}, // SP 0x140260360 MP 0x000000000 @@ -1583,89 +1583,89 @@ namespace scripting {"_meth_8345", 0x8345}, // SP 0x1402607E0 MP 0x000000000 {"_meth_8346", 0x8346}, // SP 0x1402609E0 MP 0x000000000 {"_meth_8347", 0x8347}, // SP 0x14026D000 MP 0x14033B150 - {"_meth_8348", 0x8348}, // SP 0x000000000 MP 0x140374D30 - {"_meth_8349", 0x8349}, // SP 0x000000000 MP 0x140374DD0 + {"forcethirdpersonwhenfollowing", 0x8348}, // SP 0x000000000 MP 0x140374D30 + {"disableforcethirdpersonwhenfollowing", 0x8349}, // SP 0x000000000 MP 0x140374DD0 {"_meth_834A", 0x834A}, // SP 0x140260C10 MP 0x14032C5D0 {"_meth_834B", 0x834B}, // SP 0x000000000 MP 0x14037B380 - {"_meth_834C", 0x834C}, // SP 0x140261D40 MP 0x14032D9C0 + {"secondaryoffhandbuttonpressed", 0x834C}, // SP 0x140261D40 MP 0x14032D9C0 {"_meth_834D", 0x834D}, // SP 0x000000000 MP 0x140374B70 {"_meth_834E", 0x834E}, // SP 0x000000000 MP 0x140374C10 - {"_meth_834F", 0x834F}, // SP 0x000000000 MP 0x1404798E0 - {"_meth_8350", 0x8350}, // SP 0x000000000 MP 0x14047A0F0 - {"_meth_8351", 0x8351}, // SP 0x000000000 MP 0x140479F70 + {"botsetflag", 0x834F}, // SP 0x000000000 MP 0x1404798E0 + {"botsetstance", 0x8350}, // SP 0x000000000 MP 0x14047A0F0 + {"botsetscriptmove", 0x8351}, // SP 0x000000000 MP 0x140479F70 {"_meth_8352", 0x8352}, // SP 0x000000000 MP 0x140479BC0 {"_meth_8353", 0x8353}, // SP 0x000000000 MP 0x140479DB0 - {"_meth_8354", 0x8354}, // SP 0x000000000 MP 0x140477C80 - {"_meth_8355", 0x8355}, // SP 0x000000000 MP 0x140479B00 - {"_meth_8356", 0x8356}, // SP 0x000000000 MP 0x140477C00 - {"_meth_8357", 0x8357}, // SP 0x000000000 MP 0x1404796A0 - {"_meth_8358", 0x8358}, // SP 0x000000000 MP 0x1404784A0 - {"_meth_8359", 0x8359}, // SP 0x000000000 MP 0x1404785F0 - {"_meth_835A", 0x835A}, // SP 0x000000000 MP 0x1404786F0 - {"_meth_835B", 0x835B}, // SP 0x000000000 MP 0x140478670 + {"botclearscriptgoal", 0x8354}, // SP 0x000000000 MP 0x140477C80 + {"getnearestnode", 0x8355}, // SP 0x000000000 MP 0x140479B00 + {"botclearscriptenemy", 0x8356}, // SP 0x000000000 MP 0x140477C00 + {"botsetattacker", 0x8357}, // SP 0x000000000 MP 0x1404796A0 + {"botgetscriptgoal", 0x8358}, // SP 0x000000000 MP 0x1404784A0 + {"botgetscriptgoalradius", 0x8359}, // SP 0x000000000 MP 0x1404785F0 + {"botgetscriptgoalyaw", 0x835A}, // SP 0x000000000 MP 0x1404786F0 + {"botgetscriptgoaltype", 0x835B}, // SP 0x000000000 MP 0x140478670 {"_meth_835D", 0x835D}, // SP 0x000000000 MP 0x140478850 {"_meth_835E", 0x835E}, // SP 0x000000000 MP 0x140478E10 - {"_meth_835F", 0x835F}, // SP 0x000000000 MP 0x140477D00 - {"_meth_8360", 0x8360}, // SP 0x000000000 MP 0x140478B70 + {"botfindnoderandom", 0x835F}, // SP 0x000000000 MP 0x140477D00 + {"botmemoryevent", 0x8360}, // SP 0x000000000 MP 0x140478B70 {"_meth_8362", 0x8362}, // SP 0x000000000 MP 0x140478EB0 - {"_meth_8363", 0x8363}, // SP 0x000000000 MP 0x140478890 - {"_meth_8364", 0x8364}, // SP 0x000000000 MP 0x140478420 + {"bothasscriptgoal", 0x8363}, // SP 0x000000000 MP 0x140478890 + {"botgetpersonality", 0x8364}, // SP 0x000000000 MP 0x140478420 {"_meth_8365", 0x8365}, // SP 0x000000000 MP 0x14047A1C0 - {"_meth_8367", 0x8367}, // SP 0x000000000 MP 0x140479A70 - {"_meth_8368", 0x8368}, // SP 0x000000000 MP 0x1404797B0 - {"_meth_8369", 0x8369}, // SP 0x000000000 MP 0x140477E90 - {"_meth_836A", 0x836A}, // SP 0x000000000 MP 0x140478770 + {"botsetpersonality", 0x8367}, // SP 0x000000000 MP 0x140479A70 + {"botsetdifficulty", 0x8368}, // SP 0x000000000 MP 0x1404797B0 + {"botgetdifficulty", 0x8369}, // SP 0x000000000 MP 0x140477E90 + {"botgetworldclosestedge", 0x836A}, // SP 0x000000000 MP 0x140478770 {"_meth_836B", 0x836B}, // SP 0x000000000 MP 0x140478990 - {"_meth_836C", 0x836C}, // SP 0x000000000 MP 0x140479420 - {"_meth_836D", 0x836D}, // SP 0x000000000 MP 0x140477A90 - {"_meth_836E", 0x836E}, // SP 0x000000000 MP 0x140478230 + {"botpredictseepoint", 0x836C}, // SP 0x000000000 MP 0x140479420 + {"botcanseeentity", 0x836D}, // SP 0x000000000 MP 0x140477A90 + {"botgetnodesonpath", 0x836E}, // SP 0x000000000 MP 0x140478230 {"_meth_836F", 0x836F}, // SP 0x000000000 MP 0x140479020 {"_meth_8371", 0x8371}, // SP 0x000000000 MP 0x140477FD0 - {"_meth_8372", 0x8372}, // SP 0x000000000 MP 0x140479720 + {"botsetawareness", 0x8372}, // SP 0x000000000 MP 0x140479720 {"_meth_8373", 0x8373}, // SP 0x000000000 MP 0x140479610 - {"_meth_8374", 0x8374}, // SP 0x000000000 MP 0x140478560 - {"_meth_8375", 0x8375}, // SP 0x000000000 MP 0x1404780D0 - {"_meth_8377", 0x8377}, // SP 0x000000000 MP 0x1404799A0 - {"_meth_8378", 0x8378}, // SP 0x000000000 MP 0x140479840 - {"_meth_8379", 0x8379}, // SP 0x000000000 MP 0x140477F20 - {"_meth_837A", 0x837A}, // SP 0x000000000 MP 0x1404782F0 + {"botgetscriptgoalnode", 0x8374}, // SP 0x000000000 MP 0x140478560 + {"botgetimperfectenemyinfo", 0x8375}, // SP 0x000000000 MP 0x1404780D0 + {"botsetpathingstyle", 0x8377}, // SP 0x000000000 MP 0x1404799A0 + {"botsetdifficultysetting", 0x8378}, // SP 0x000000000 MP 0x140479840 + {"botgetdifficultysetting", 0x8379}, // SP 0x000000000 MP 0x140477F20 + {"botgetpathdist", 0x837A}, // SP 0x000000000 MP 0x1404782F0 {"_meth_837B", 0x837B}, // SP 0x000000000 MP 0x140478910 {"_meth_837C", 0x837C}, // SP 0x000000000 MP 0x140479510 - {"_meth_837D", 0x837D}, // SP 0x000000000 MP 0x140477B70 + {"botclearbutton", 0x837D}, // SP 0x000000000 MP 0x140477B70 {"_meth_837E", 0x837E}, // SP 0x000000000 MP 0x1404791D0 - {"_meth_837F", 0x837F}, // SP 0x000000000 MP 0x14032E760 - {"_meth_8380", 0x8380}, // SP 0x000000000 MP 0x14037AD60 + {"getnodenumber", 0x837F}, // SP 0x000000000 MP 0x14032E760 + {"setclientowner", 0x8380}, // SP 0x000000000 MP 0x14037AD60 {"_meth_8381", 0x8381}, // SP 0x000000000 MP 0x14037A3B0 - {"_meth_8382", 0x8382}, // SP 0x1402A15D0 MP 0x140358460 - {"_meth_8383", 0x8383}, // SP 0x000000000 MP 0x14037A980 - {"_meth_8384", 0x8384}, // SP 0x000000000 MP 0x14032E920 + {"setaisightlinevisible", 0x8382}, // SP 0x1402A15D0 MP 0x140358460 + {"setentityowner", 0x8383}, // SP 0x000000000 MP 0x14037A980 + {"nodeisdisconnected", 0x8384}, // SP 0x000000000 MP 0x14032E920 {"_meth_8385", 0x8385}, // SP 0x140262C60 MP 0x14032E340 {"_meth_8386", 0x8386}, // SP 0x000000000 MP 0x14037B1B0 {"_meth_8388", 0x8388}, // SP 0x000000000 MP 0x14044EF90 {"_meth_8389", 0x8389}, // SP 0x000000000 MP 0x14044E610 - {"_meth_838A", 0x838A}, // SP 0x000000000 MP 0x14044EE40 + {"setagentattacker", 0x838A}, // SP 0x000000000 MP 0x14044EE40 {"_meth_838B", 0x838B}, // SP 0x000000000 MP 0x14044E0E0 - {"_meth_838C", 0x838C}, // SP 0x000000000 MP 0x14044DF00 - {"_meth_838D", 0x838D}, // SP 0x000000000 MP 0x140450B20 - {"_meth_838E", 0x838E}, // SP 0x000000000 MP 0x140450120 - {"_meth_838F", 0x838F}, // SP 0x000000000 MP 0x14044F670 - {"_meth_8390", 0x8390}, // SP 0x000000000 MP 0x140450090 - {"_meth_8391", 0x8391}, // SP 0x000000000 MP 0x140450000 - {"_meth_8392", 0x8392}, // SP 0x000000000 MP 0x140450260 + {"agentcanseesentient", 0x838C}, // SP 0x000000000 MP 0x14044DF00 + {"setwaypoint", 0x838D}, // SP 0x000000000 MP 0x140450B20 + {"setgoalpos", 0x838E}, // SP 0x000000000 MP 0x140450120 + {"getgoalpos", 0x838F}, // SP 0x000000000 MP 0x14044F670 + {"setgoalnode", 0x8390}, // SP 0x000000000 MP 0x140450090 + {"setgoalentity", 0x8391}, // SP 0x000000000 MP 0x140450000 + {"setgoalradius", 0x8392}, // SP 0x000000000 MP 0x140450260 {"_meth_8393", 0x8393}, // SP 0x000000000 MP 0x14044FEC0 - {"_meth_8394", 0x8394}, // SP 0x000000000 MP 0x140450540 - {"_meth_8395", 0x8395}, // SP 0x000000000 MP 0x14044FDA0 - {"_meth_8396", 0x8396}, // SP 0x000000000 MP 0x140450780 - {"_meth_8397", 0x8397}, // SP 0x000000000 MP 0x14044FF60 - {"_meth_8398", 0x8398}, // SP 0x000000000 MP 0x140450370 - {"_meth_8399", 0x8399}, // SP 0x000000000 MP 0x14044F7A0 - {"_meth_839A", 0x839A}, // SP 0x000000000 MP 0x14044F2A0 - {"_meth_839B", 0x839B}, // SP 0x000000000 MP 0x140450840 - {"_meth_839C", 0x839C}, // SP 0x000000000 MP 0x14044F5D0 - {"_meth_839D", 0x839D}, // SP 0x000000000 MP 0x14044F480 - {"_meth_839E", 0x839E}, // SP 0x000000000 MP 0x140450AA0 - {"_meth_839F", 0x839F}, // SP 0x000000000 MP 0x14044F370 - {"_meth_83A0", 0x83A0}, // SP 0x000000000 MP 0x14044FC90 + {"setorientmode", 0x8394}, // SP 0x000000000 MP 0x140450540 + {"setanimmode", 0x8395}, // SP 0x000000000 MP 0x14044FDA0 + {"setphysicsmode", 0x8396}, // SP 0x000000000 MP 0x140450780 + {"setclipmode", 0x8397}, // SP 0x000000000 MP 0x14044FF60 + {"setmaxturnspeed", 0x8398}, // SP 0x000000000 MP 0x140450370 + {"getmaxturnspeed", 0x8399}, // SP 0x000000000 MP 0x14044F7A0 + {"beginmelee", 0x839A}, // SP 0x000000000 MP 0x14044F2A0 + {"getmlgspectatorteam", 0x839B}, // SP 0x000000000 MP 0x140450840 + {"dotrajectory", 0x839C}, // SP 0x000000000 MP 0x14044F5D0 + {"doanimlerp", 0x839D}, // SP 0x000000000 MP 0x14044F480 + {"setviewheight", 0x839E}, // SP 0x000000000 MP 0x140450AA0 + {"claimnode", 0x839F}, // SP 0x000000000 MP 0x14044F370 + {"relinquishclaimednode", 0x83A0}, // SP 0x000000000 MP 0x14044FC90 {"_meth_83A1", 0x83A1}, // SP 0x14026DD90 MP 0x14033BCE0 {"_meth_83A2", 0x83A2}, // SP 0x14026DE40 MP 0x14033BD90 {"_meth_83A3", 0x83A3}, // SP 0x14026DEB0 MP 0x14033BDF0 @@ -1709,54 +1709,54 @@ namespace scripting {"_meth_83CB", 0x83CB}, // SP 0x14024B660 MP 0x000000000 {"_meth_83CC", 0x83CC}, // SP 0x14024B740 MP 0x000000000 {"_meth_83CD", 0x83CD}, // SP 0x14024B7A0 MP 0x000000000 - {"_meth_83CE", 0x83CE}, // SP 0x000000000 MP 0x1400781E0 - {"_meth_83CF", 0x83CF}, // SP 0x000000000 MP 0x140077CB0 + {"setanimclass", 0x83CE}, // SP 0x000000000 MP 0x1400781E0 + {"enableanimstate", 0x83CF}, // SP 0x000000000 MP 0x140077CB0 {"_meth_83D0", 0x83D0}, // SP 0x000000000 MP 0x140078250 - {"_meth_83D1", 0x83D1}, // SP 0x000000000 MP 0x140077DF0 - {"_meth_83D2", 0x83D2}, // SP 0x000000000 MP 0x140077FA0 - {"_meth_83D3", 0x83D3}, // SP 0x000000000 MP 0x140077E80 - {"_meth_83D4", 0x83D4}, // SP 0x000000000 MP 0x140077EE0 + {"getanimentry", 0x83D1}, // SP 0x000000000 MP 0x140077DF0 + {"getanimentryname", 0x83D2}, // SP 0x000000000 MP 0x140077FA0 + {"getanimentryalias", 0x83D3}, // SP 0x000000000 MP 0x140077E80 + {"getanimentrycount", 0x83D4}, // SP 0x000000000 MP 0x140077EE0 {"_meth_83D5", 0x83D5}, // SP 0x1402AE190 MP 0x000000000 - {"_meth_83D6", 0x83D6}, // SP 0x1402613C0 MP 0x14032CB20 + {"issprinting", 0x83D6}, // SP 0x1402613C0 MP 0x14032CB20 {"_meth_83D7", 0x83D7}, // SP 0x140291320 MP 0x000000000 {"_meth_83D8", 0x83D8}, // SP 0x1402495B0 MP 0x000000000 {"_meth_83D9", 0x83D9}, // SP 0x1405D92F0 MP 0x140358020 {"_meth_83DA", 0x83DA}, // SP 0x140264C80 MP 0x000000000 {"_meth_83DB", 0x83DB}, // SP 0x140264C80 MP 0x000000000 {"_meth_83DC", 0x83DC}, // SP 0x140261B80 MP 0x14032D800 - {"_meth_83DD", 0x83DD}, // SP 0x1402B3200 MP 0x14037EF90 - {"_meth_83DE", 0x83DE}, // SP 0x000000000 MP 0x14044F710 - {"_meth_83DF", 0x83DF}, // SP 0x000000000 MP 0x14044FAD0 + {"rotateto", 0x83DD}, // SP 0x1402B3200 MP 0x14037EF90 + {"getlookaheaddir", 0x83DE}, // SP 0x000000000 MP 0x14044F710 + {"getpathgoalpos", 0x83DF}, // SP 0x000000000 MP 0x14044FAD0 {"_meth_83E0", 0x83E0}, // SP 0x1402A15D0 MP 0x14036E1F0 - {"_meth_83E1", 0x83E1}, // SP 0x000000000 MP 0x140374840 - {"_meth_83E2", 0x83E2}, // SP 0x14029FD00 MP 0x140358090 + {"setcorpsefalling", 0x83E1}, // SP 0x000000000 MP 0x140374840 + {"setsurfacetype", 0x83E2}, // SP 0x14029FD00 MP 0x140358090 {"_meth_83E3", 0x83E3}, // SP 0x1402A0C60 MP 0x140369520 {"_meth_83E4", 0x83E4}, // SP 0x1402A20D0 MP 0x140369FE0 {"_meth_83E5", 0x83E5}, // SP 0x1405D92F0 MP 0x14033B020 {"_meth_83E6", 0x83E6}, // SP 0x1402A7B00 MP 0x000000000 {"_meth_83E7", 0x83E7}, // SP 0x1402A7C90 MP 0x000000000 - {"_meth_83E8", 0x83E8}, // SP 0x140263140 MP 0x14032F7A0 - {"_meth_83E9", 0x83E9}, // SP 0x14026D2E0 MP 0x14033B450 - {"_meth_83EA", 0x83EA}, // SP 0x14028DB50 MP 0x140359B60 - {"_meth_83EB", 0x83EB}, // SP 0x14028E2A0 MP 0x14035A4D0 + {"visionsetstage", 0x83E8}, // SP 0x140263140 MP 0x14032F7A0 + {"hudoutlineenableforclients", 0x83E9}, // SP 0x14026D2E0 MP 0x14033B450 + {"getlinkedparent", 0x83EA}, // SP 0x14028DB50 MP 0x140359B60 + {"getmovingplatformparent", 0x83EB}, // SP 0x14028E2A0 MP 0x14035A4D0 {"_meth_83EC", 0x83EC}, // SP 0x000000000 MP 0x14032CEF0 {"_meth_83ED", 0x83ED}, // SP 0x1402ADF90 MP 0x000000000 {"_meth_83EF", 0x83EF}, // SP 0x1402A0B60 MP 0x14036A5C0 {"_meth_83F0", 0x83F0}, // SP 0x14029F670 MP 0x140369790 - {"_meth_83F1", 0x83F1}, // SP 0x1402913E0 MP 0x14035B490 + {"makevehiclenotcollidewithplayers", 0x83F1}, // SP 0x1402913E0 MP 0x14035B490 {"_meth_83F2", 0x83F2}, // SP 0x140269130 MP 0x000000000 {"_meth_83F3", 0x83F3}, // SP 0x140269190 MP 0x000000000 - {"_meth_83F4", 0x83F4}, // SP 0x1402A0760 MP 0x1403589E0 + {"setscriptablepartstate", 0x83F4}, // SP 0x1402A0760 MP 0x1403589E0 {"_meth_83F5", 0x83F5}, // SP 0x1405D92F0 MP 0x140359100 {"_meth_83F6", 0x83F6}, // SP 0x1402A15D0 MP 0x14036E200 {"_meth_83F7", 0x83F7}, // SP 0x140465020 MP 0x140560DF0 {"_meth_83F8", 0x83F8}, // SP 0x1405D92F0 MP 0x1403636B0 {"_meth_83F9", 0x83F9}, // SP 0x1405D92F0 MP 0x140363830 - {"_meth_83FA", 0x83FA}, // SP 0x14029BA30 MP 0x140363EA0 + {"motionblurhqdisable", 0x83FA}, // SP 0x14029BA30 MP 0x140363EA0 {"_meth_83FB", 0x83FB}, // SP 0x14029BC20 MP 0x1403640D0 {"_meth_83FC", 0x83FC}, // SP 0x1402AA870 MP 0x000000000 {"_meth_83FD", 0x83FD}, // SP 0x14024AD20 MP 0x000000000 - {"_meth_83FE", 0x83FE}, // SP 0x140297A40 MP 0x140360C90 + {"worldpointtoscreenpos", 0x83FE}, // SP 0x140297A40 MP 0x140360C90 {"_meth_83FF", 0x83FF}, // SP 0x1402974B0 MP 0x000000000 {"_meth_8400", 0x8400}, // SP 0x1402498E0 MP 0x000000000 {"_meth_8401", 0x8401}, // SP 0x000000000 MP 0x140477D90 @@ -1765,7 +1765,7 @@ namespace scripting {"_meth_8404", 0x8404}, // SP 0x1402977A0 MP 0x000000000 {"_meth_8405", 0x8405}, // SP 0x1402978F0 MP 0x000000000 {"_meth_8406", 0x8406}, // SP 0x14029A680 MP 0x000000000 - {"_meth_8407", 0x8407}, // SP 0x000000000 MP 0x140375810 + {"emissiveblend", 0x8407}, // SP 0x000000000 MP 0x140375810 {"_meth_8408", 0x8408}, // SP 0x1402687F0 MP 0x000000000 {"_meth_8409", 0x8409}, // SP 0x140268840 MP 0x000000000 {"_meth_840A", 0x840A}, // SP 0x1402AF930 MP 0x000000000 @@ -1773,46 +1773,46 @@ namespace scripting {"_meth_840C", 0x840C}, // SP 0x1402AE5D0 MP 0x000000000 {"_meth_840D", 0x840D}, // SP 0x1402B4000 MP 0x14037FDE0 {"_meth_840E", 0x840E}, // SP 0x1402B40B0 MP 0x14037FE90 - {"_meth_840F", 0x840F}, // SP 0x1402B4160 MP 0x14037FF40 + {"physicsgetlinspeed", 0x840F}, // SP 0x1402B4160 MP 0x14037FF40 {"_meth_8410", 0x8410}, // SP 0x1402B41F0 MP 0x140380000 - {"_meth_8411", 0x8411}, // SP 0x1402B42B0 MP 0x1403800E0 - {"_meth_8412", 0x8412}, // SP 0x1402B4340 MP 0x1403801A0 - {"_meth_8413", 0x8413}, // SP 0x000000000 MP 0x14035A430 - {"_meth_8414", 0x8414}, // SP 0x000000000 MP 0x14035A480 - {"_meth_8415", 0x8415}, // SP 0x000000000 MP 0x140376790 - {"_meth_8416", 0x8416}, // SP 0x000000000 MP 0x1403767B0 - {"_meth_8417", 0x8417}, // SP 0x000000000 MP 0x14036F610 - {"_meth_8418", 0x8418}, // SP 0x000000000 MP 0x140357DB0 + {"physicsgetangvel", 0x8411}, // SP 0x1402B42B0 MP 0x1403800E0 + {"physicsgetangspeed", 0x8412}, // SP 0x1402B4340 MP 0x1403801A0 + {"disablemissileboosting", 0x8413}, // SP 0x000000000 MP 0x14035A430 + {"enablemissileboosting", 0x8414}, // SP 0x000000000 MP 0x14035A480 + {"canspawntestclient", 0x8415}, // SP 0x000000000 MP 0x140376790 + {"spawntestclient", 0x8416}, // SP 0x000000000 MP 0x1403767B0 + {"setgrenadethrowscale", 0x8417}, // SP 0x000000000 MP 0x14036F610 + {"ismantling", 0x8418}, // SP 0x000000000 MP 0x140357DB0 {"_meth_8419", 0x8419}, // SP 0x000000000 MP 0x1403767E0 {"_meth_841A", 0x841A}, // SP 0x1405D92F0 MP 0x1403630D0 {"_meth_841B", 0x841B}, // SP 0x1405D92F0 MP 0x140363500 {"_meth_841C", 0x841C}, // SP 0x1405D92F0 MP 0x140363590 {"_meth_841D", 0x841D}, // SP 0x1405D92F0 MP 0x140363620 - {"_meth_841E", 0x841E}, // SP 0x140299270 MP 0x140364190 + {"turretsetbarrelspinenabled", 0x841E}, // SP 0x140299270 MP 0x140364190 {"_meth_841F", 0x841F}, // SP 0x000000000 MP 0x1403326E0 - {"_meth_8420", 0x8420}, // SP 0x000000000 MP 0x1403328E0 + {"autospotoverlayoff", 0x8420}, // SP 0x000000000 MP 0x1403328E0 {"_meth_8421", 0x8421}, // SP 0x14029FEB0 MP 0x140369B60 {"_meth_8422", 0x8422}, // SP 0x1402A00C0 MP 0x140369E10 - {"_meth_8423", 0x8423}, // SP 0x000000000 MP 0x14044F520 + {"doanimrelative", 0x8423}, // SP 0x000000000 MP 0x14044F520 {"_meth_8424", 0x8424}, // SP 0x1402B30B0 MP 0x000000000 {"_meth_8425", 0x8425}, // SP 0x1402B3280 MP 0x000000000 {"_meth_8426", 0x8426}, // SP 0x1402B3320 MP 0x000000000 - {"_meth_8427", 0x8427}, // SP 0x000000000 MP 0x1403748F0 + {"getcorpseentity", 0x8427}, // SP 0x000000000 MP 0x1403748F0 {"_meth_8428", 0x8428}, // SP 0x1402ABE20 MP 0x000000000 {"_meth_8429", 0x8429}, // SP 0x000000000 MP 0x140379520 {"_meth_842A", 0x842A}, // SP 0x000000000 MP 0x140379B70 - {"_meth_842B", 0x842B}, // SP 0x000000000 MP 0x1403785F0 - {"_meth_842C", 0x842C}, // SP 0x000000000 MP 0x1403321B0 + {"queuedialogforplayer", 0x842B}, // SP 0x000000000 MP 0x1403785F0 + {"setmlgcameradefaults", 0x842C}, // SP 0x000000000 MP 0x1403321B0 {"_meth_842D", 0x842D}, // SP 0x000000000 MP 0x140334A60 {"_meth_842E", 0x842E}, // SP 0x140262C10 MP 0x14032F2B0 {"_meth_842F", 0x842F}, // SP 0x140262D40 MP 0x14032F480 {"_meth_8430", 0x8430}, // SP 0x1405D92F0 MP 0x000000000 - {"_meth_8431", 0x8431}, // SP 0x14028E020 MP 0x14035A3A0 + {"getlinkedchildren", 0x8431}, // SP 0x14028E020 MP 0x14035A3A0 {"_meth_8432", 0x8432}, // SP 0x000000000 MP 0x140479320 - {"_meth_8433", 0x8433}, // SP 0x000000000 MP 0x140377F80 - {"_meth_8434", 0x8434}, // SP 0x140266DD0 MP 0x14032B210 - {"_meth_8435", 0x8435}, // SP 0x000000000 MP 0x140332F50 - {"_meth_8437", 0x8437}, // SP 0x1402A0440 MP 0x1403586F0 + {"playsoundonmovingent", 0x8433}, // SP 0x000000000 MP 0x140377F80 + {"cancelmantle", 0x8434}, // SP 0x140266DD0 MP 0x14032B210 + {"hasfemalecustomizationmodel", 0x8435}, // SP 0x000000000 MP 0x140332F50 + {"setscriptabledamageowner", 0x8437}, // SP 0x1402A0440 MP 0x1403586F0 {"_meth_8438", 0x8438}, // SP 0x1402A0B00 MP 0x140358FF0 {"_meth_8439", 0x8439}, // SP 0x000000000 MP 0x140379890 {"_meth_843A", 0x843A}, // SP 0x14024B810 MP 0x000000000 @@ -1843,20 +1843,20 @@ namespace scripting {"_meth_8453", 0x8453}, // SP 0x140261E30 MP 0x14032DC80 {"_meth_8454", 0x8454}, // SP 0x1402612F0 MP 0x000000000 {"_meth_8455", 0x8455}, // SP 0x1402AD1E0 MP 0x000000000 - {"_meth_8458", 0x8458}, // SP 0x14029DE70 MP 0x140366600 + {"getvieworigin", 0x8458}, // SP 0x14029DE70 MP 0x140366600 {"_meth_8459", 0x8459}, // SP 0x140265E70 MP 0x140329A80 {"_meth_845A", 0x845A}, // SP 0x000000000 MP 0x140359980 - {"_meth_845B", 0x845B}, // SP 0x000000000 MP 0x14035A040 + {"stopridingvehicle", 0x845B}, // SP 0x000000000 MP 0x14035A040 {"_meth_845C", 0x845C}, // SP 0x140264C80 MP 0x000000000 {"_meth_845D", 0x845D}, // SP 0x14028E7C0 MP 0x14035A8D0 - {"_meth_845E", 0x845E}, // SP 0x000000000 MP 0x1403762F0 - {"_meth_845F", 0x845F}, // SP 0x000000000 MP 0x140376340 - {"_meth_8460", 0x8460}, // SP 0x000000000 MP 0x140347ED0 - {"_meth_8461", 0x8461}, // SP 0x1402675A0 MP 0x14032B560 - {"_meth_8462", 0x8462}, // SP 0x1402614A0 MP 0x14032CC30 - {"_meth_8463", 0x8463}, // SP 0x140291970 MP 0x14035B8F0 + {"disablemissilestick", 0x845E}, // SP 0x000000000 MP 0x1403762F0 + {"enablemissilestick", 0x845F}, // SP 0x000000000 MP 0x140376340 + {"setmissileminimapvisible", 0x8460}, // SP 0x000000000 MP 0x140347ED0 + {"isoffhandweaponreadytothrow", 0x8461}, // SP 0x1402675A0 MP 0x14032B560 + {"isleaning", 0x8462}, // SP 0x1402614A0 MP 0x14032CC30 + {"makecollidewithitemclip", 0x8463}, // SP 0x140291970 MP 0x14035B8F0 {"_meth_8464", 0x8464}, // SP 0x140261DC0 MP 0x000000000 - {"_meth_8465", 0x8465}, // SP 0x000000000 MP 0x14032FE10 + {"visionsetpostapplyforplayer", 0x8465}, // SP 0x000000000 MP 0x14032FE10 {"_meth_8466", 0x8466}, // SP 0x1402B47A0 MP 0x140380A60 {"_meth_8467", 0x8467}, // SP 0x1402B4950 MP 0x140380C30 {"_meth_8468", 0x8468}, // SP 0x1402A2E30 MP 0x000000000 From 6150134f77e1824e03247ebc2b87d036d52c7898 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 4 Mar 2022 20:55:45 +0100 Subject: [PATCH 031/346] No SP for now --- src/client/component/logfile.cpp | 18 ++++++++++-------- src/client/component/scripting.cpp | 4 ++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp index db291587..fc949d92 100644 --- a/src/client/component/logfile.cpp +++ b/src/client/component/logfile.cpp @@ -296,17 +296,19 @@ namespace logfile public: void post_unpack() override { - if (!game::environment::is_sp()) + if (game::environment::is_sp()) { - utils::hook::call(0x14048191D, client_command_stub); - - scr_player_damage_hook.create(0x14037DC50, scr_player_damage_stub); - scr_player_killed_hook.create(0x14037DF30, scr_player_killed_stub); - - utils::hook::call(0x140484EC0, g_shutdown_game_stub); - utils::hook::call(0x1404853C1, g_shutdown_game_stub); + return; } + utils::hook::call(0x14048191D, client_command_stub); + + scr_player_damage_hook.create(0x14037DC50, scr_player_damage_stub); + scr_player_killed_hook.create(0x14037DF30, scr_player_killed_stub); + + utils::hook::call(0x140484EC0, g_shutdown_game_stub); + utils::hook::call(0x1404853C1, g_shutdown_game_stub); + utils::hook::jump(SELECT_VALUE(0x140376655, 0x140444645), utils::hook::assemble(vm_execute_stub), true); } }; diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index 6cdb54e0..e3116122 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -127,8 +127,8 @@ namespace scripting scr_set_thread_position_hook.create(SELECT_VALUE(0x14036A180, 0x140437D10), scr_set_thread_position_stub); process_script_hook.create(SELECT_VALUE(0x1403737E0, 0x1404417E0), process_script_stub); - scr_load_level_hook.create(0x1403727C0, scr_load_level_stub); - g_shutdown_game_hook.create(0x140345A60, g_shutdown_game_stub); + scr_load_level_hook.create(SELECT_VALUE(0x1402A5BE0, 0x1403727C0), scr_load_level_stub); + g_shutdown_game_hook.create(SELECT_VALUE(0x140277D40, 0x140345A60), g_shutdown_game_stub); scheduler::loop([]() { From 8e65524f8503cdfaad5246b7311202b1a59ce752 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Sat, 5 Mar 2022 02:53:22 +0300 Subject: [PATCH 032/346] cleanup --- src/client/component/server_list.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index dace554a..1b7e759e 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -378,14 +378,6 @@ namespace server_list if (!game::environment::is_mp()) return; localized_strings::override("PLATFORM_SYSTEM_LINK_TITLE", "SERVER LIST"); - localized_strings::override("MENU_NUMPLAYERS", "Players"); - - // small command until ui scripting - command::add("openServerList", []() - { - refresh_server_list(); - command::execute("lui_open menu_systemlink_join\n"); - }); // hook LUI_OpenMenu to refresh server list for system link menu lui_open_menu_hook.create(game::LUI_OpenMenu, lui_open_menu_stub); @@ -448,4 +440,4 @@ namespace server_list }; } -REGISTER_COMPONENT(server_list::component) \ No newline at end of file +REGISTER_COMPONENT(server_list::component) From 2bad728489c33d98cfecb4fb13e278e9458f5830 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Sat, 5 Mar 2022 02:57:07 +0300 Subject: [PATCH 033/346] program about --- src/client/resources/main.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/resources/main.html b/src/client/resources/main.html index 941a2acc..1a17c6fe 100644 --- a/src/client/resources/main.html +++ b/src/client/resources/main.html @@ -464,7 +464,7 @@

Made by Skull.

-

Special thanks to quaK.

+

Special thanks to all Contributors.

This Project based on XLabs-S1x.

From 8e186c590a99f070fbdbc52ef54abc6721ef25c6 Mon Sep 17 00:00:00 2001 From: m Date: Fri, 4 Mar 2022 18:07:21 -0600 Subject: [PATCH 034/346] proper program about [skip ci] --- src/client/resources/main.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/client/resources/main.html b/src/client/resources/main.html index 1a17c6fe..887b6863 100644 --- a/src/client/resources/main.html +++ b/src/client/resources/main.html @@ -463,10 +463,9 @@
-

Made by Skull.

-

Special thanks to all Contributors.

+

Special thanks to all contributors.

- This Project based on XLabs-S1x. + This project is based on S1x and H2-mod.

From 05696f1ec509684d4cb496581e1eddf437c4278a Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Sat, 5 Mar 2022 02:34:13 +0200 Subject: [PATCH 035/346] baseaddr --- src/client/game/game.cpp | 13 +++++++++++++ src/client/game/game.hpp | 9 +++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 9045761b..95fb0793 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -3,6 +3,14 @@ namespace game { + uint64_t base_address; + + void load_base_address() + { + const auto module = GetModuleHandle(NULL); + base_address = uint64_t(module); + } + int Cmd_Argc() { return cmd_args->argc[cmd_args->nesting]; @@ -102,3 +110,8 @@ namespace game } } } + +uintptr_t operator"" _b(const uintptr_t ptr) +{ + return game::base_address + ptr; +} \ No newline at end of file diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 47041ca9..0442fece 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -9,6 +9,9 @@ namespace game { + extern uint64_t base_address; + void load_base_address(); + namespace environment { launcher::mode get_mode(); @@ -37,10 +40,10 @@ namespace game { if (environment::is_sp()) { - return sp_object_; + return reinterpret_cast((uint64_t)sp_object_ + base_address); } - return mp_object_; + return reinterpret_cast((uint64_t)mp_object_ + base_address); } operator T* () const @@ -67,4 +70,6 @@ namespace game bool VirtualLobby_Loaded(); } +uintptr_t operator"" _b(const uintptr_t ptr); + #include "symbols.hpp" From fc59b7e7a6d37e9c0786789efe9598b690ddffb5 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Sat, 5 Mar 2022 02:35:20 +0200 Subject: [PATCH 036/346] Revert "baseaddr" This reverts commit 05696f1ec509684d4cb496581e1eddf437c4278a. --- src/client/game/game.cpp | 13 ------------- src/client/game/game.hpp | 9 ++------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 95fb0793..9045761b 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -3,14 +3,6 @@ namespace game { - uint64_t base_address; - - void load_base_address() - { - const auto module = GetModuleHandle(NULL); - base_address = uint64_t(module); - } - int Cmd_Argc() { return cmd_args->argc[cmd_args->nesting]; @@ -110,8 +102,3 @@ namespace game } } } - -uintptr_t operator"" _b(const uintptr_t ptr) -{ - return game::base_address + ptr; -} \ No newline at end of file diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 0442fece..47041ca9 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -9,9 +9,6 @@ namespace game { - extern uint64_t base_address; - void load_base_address(); - namespace environment { launcher::mode get_mode(); @@ -40,10 +37,10 @@ namespace game { if (environment::is_sp()) { - return reinterpret_cast((uint64_t)sp_object_ + base_address); + return sp_object_; } - return reinterpret_cast((uint64_t)mp_object_ + base_address); + return mp_object_; } operator T* () const @@ -70,6 +67,4 @@ namespace game bool VirtualLobby_Loaded(); } -uintptr_t operator"" _b(const uintptr_t ptr); - #include "symbols.hpp" From fca59647403d4f68461a2da50b6d498b9a082be6 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Sat, 5 Mar 2022 02:44:16 +0200 Subject: [PATCH 037/346] baseaddr [skip ci] --- src/client/game/game.cpp | 13 +++++++++++++ src/client/game/game.hpp | 9 +++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 9045761b..95fb0793 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -3,6 +3,14 @@ namespace game { + uint64_t base_address; + + void load_base_address() + { + const auto module = GetModuleHandle(NULL); + base_address = uint64_t(module); + } + int Cmd_Argc() { return cmd_args->argc[cmd_args->nesting]; @@ -102,3 +110,8 @@ namespace game } } } + +uintptr_t operator"" _b(const uintptr_t ptr) +{ + return game::base_address + ptr; +} \ No newline at end of file diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 47041ca9..0442fece 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -9,6 +9,9 @@ namespace game { + extern uint64_t base_address; + void load_base_address(); + namespace environment { launcher::mode get_mode(); @@ -37,10 +40,10 @@ namespace game { if (environment::is_sp()) { - return sp_object_; + return reinterpret_cast((uint64_t)sp_object_ + base_address); } - return mp_object_; + return reinterpret_cast((uint64_t)mp_object_ + base_address); } operator T* () const @@ -67,4 +70,6 @@ namespace game bool VirtualLobby_Loaded(); } +uintptr_t operator"" _b(const uintptr_t ptr); + #include "symbols.hpp" From 2614f7251f4b9e438eae3672fbda83eaba433661 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Sat, 5 Mar 2022 03:36:18 +0200 Subject: [PATCH 038/346] should be full [skip ci] --- src/client/component/auth.cpp | 41 +-- src/client/component/input.cpp | 4 +- src/client/component/localized_strings.cpp | 2 +- src/client/component/network.cpp | 84 +++--- src/client/component/scheduler.cpp | 6 +- src/client/component/splash.cpp | 6 +- src/client/game/symbols.hpp | 303 ++++++++++----------- 7 files changed, 222 insertions(+), 224 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index f0950e96..346c8d80 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -177,21 +177,22 @@ namespace auth game::SV_DirectConnect(from); } - void* get_direct_connect_stub() - { - return utils::hook::assemble([](utils::hook::assembler& a) - { - a.lea(rcx, qword_ptr(rsp, 0x20)); - a.movaps(xmmword_ptr(rsp, 0x20), xmm0); + // CAN'T FIND + //void* get_direct_connect_stub() + //{ + // return utils::hook::assemble([](utils::hook::assembler& a) + // { + // a.lea(rcx, qword_ptr(rsp, 0x20)); + // a.movaps(xmmword_ptr(rsp, 0x20), xmm0); - a.pushad64(); - a.mov(rdx, rsi); - a.call_aligned(direct_connect); - a.popad64(); + // a.pushad64(); + // a.mov(rdx, rsi); + // a.call_aligned(direct_connect); + // a.popad64(); - a.jmp(0x140488CE2); // H1MP64(1.4) - }); - } + // a.jmp(0x140488CE2); // H1MP64(1.4) + // }); + //} } uint64_t get_guid() @@ -218,14 +219,14 @@ namespace auth } else { - utils::hook::jump(0x140571E07, 0x140571E5A); // H1(1.4) - utils::hook::jump(0x14004B223, 0x14004B4F2); // H1(1.4) - utils::hook::jump(0x14004B4AD, 0x14004B4F2); // H1(1.4) - utils::hook::jump(0x140572F6F, 0x140572FB0); // H1(1.4) - utils::hook::jump(0x140573470, 0x1405734B6); // H1(1.4) + utils::hook::jump(0x1D6193_b, 0x1D61FA_b); // STEAM + utils::hook::jump(0x60153_b, 0x60426_b); // STEAM + utils::hook::jump(0x603E1_b, 0x60426_b); // STEAM + utils::hook::jump(0x1D7542_b, 0x1D7587_b); // STEAM MAYBE `1401D7553` ON FIRST + utils::hook::jump(0x1D7A82_b, 0x1D7AC8_b); // STEAM - utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) - utils::hook::call(0x140250ED2, send_connect_data_stub); // H1(1.4) + //utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) can't find + utils::hook::call(0x12D437_b, send_connect_data_stub); // H1(1.4) // Skip checks for sending connect packet utils::hook::jump(0x1402508FC, 0x140250946); diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 4fc59741..6d28f601 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -45,8 +45,8 @@ namespace input return; } - cl_char_event_hook.create(SELECT_VALUE(0x1401871A0, 0x14024E810), cl_char_event_stub); // H1(1.4) - cl_key_event_hook.create(SELECT_VALUE(0x1401874D0, 0x14024EA60), cl_key_event_stub); // H1(1.4) + cl_char_event_hook.create(SELECT_VALUE(0, 0x12C8F0_b), cl_char_event_stub); // H1-STEAM(1.15) + cl_key_event_hook.create(SELECT_VALUE(0, 0x135A70_b), cl_key_event_stub); // H1-STEAM(1.15) } }; } diff --git a/src/client/component/localized_strings.cpp b/src/client/component/localized_strings.cpp index 975c76f3..55b41d65 100644 --- a/src/client/component/localized_strings.cpp +++ b/src/client/component/localized_strings.cpp @@ -44,7 +44,7 @@ namespace localized_strings void post_unpack() override { // Change some localized strings - seh_string_ed_get_string_hook.create(SELECT_VALUE(0x1403924A0, 0x1404BB2A0), &seh_string_ed_get_string); + seh_string_ed_get_string_hook.create(SELECT_VALUE(0, 0x585DA0_b), &seh_string_ed_get_string); // H1-STEAM(1.15) } }; } diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 47ca2b20..fb2a6f55 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -67,11 +67,11 @@ namespace network // Command handled a.popad64(); a.mov(al, 1); - a.jmp(0x140252AF8); // H1MP64(1.4) + a.jmp(0x252AF8_b); // STEAM a.bind(return_unhandled); a.popad64(); - a.jmp(0x14025234C); // H1MP64(1.4) + a.jmp(0x25234C_b); // STEAM } int net_compare_base_address(const game::netadr_s* a1, const game::netadr_s* a2) @@ -117,7 +117,7 @@ namespace network if (net_interface && net_interface != "localhost"s) { // Sys_StringToSockaddr - utils::hook::invoke(0x1404F6580, net_interface, &address); + utils::hook::invoke(0x59E810_b, net_interface, &address); } address.sin_family = AF_INET; @@ -237,52 +237,52 @@ namespace network // redirect dw_sendto to raw socket //utils::hook::jump(0x1404D850A, reinterpret_cast(0x1404D849A)); - utils::hook::call(0x140513467, dw_send_to_stub); // H1MP64(1.4) - utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub); // H1MP64(1.4) + utils::hook::call(0x5BDB47_b, dw_send_to_stub); // STEAM + utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub); // STEAM // intercept command handling - utils::hook::jump(0x140252327, utils::hook::assemble(handle_command_stub), true); // H1MP64(1.4) + utils::hook::jump(0x12F387_b, utils::hook::assemble(handle_command_stub), true); // STEAM // handle xuid without secure connection - utils::hook::nop(0x140486AAF, 6); // H1MP64(1.4) + utils::hook::nop(0x554222_b, 6); // STEAM - utils::hook::jump(0x140424F20, net_compare_address); // H1MP64(1.4) - utils::hook::jump(0x140424F70, net_compare_base_address); // H1MP64(1.4) + utils::hook::jump(0x4F1800_b, net_compare_address); // STEAM + utils::hook::jump(0x4F1850_b, net_compare_base_address); // STEAM // don't establish secure conenction - utils::hook::set(0x14027EA4D, 0xEB); // H1MP64(1.4) - utils::hook::set(0x14027EB1E, 0xEB); // H1MP64(1.4) - utils::hook::set(0x14027EF8D, 0xEB); // H1MP64(1.4) - utils::hook::set(0x14025081F, 0xEB); // H1MP64(1.4) + utils::hook::set(0x358C8D_b, 0xEB); // STEAM + utils::hook::set(0x358D5E_b, 0xEB); // STEAM + utils::hook::set(0x3591CD_b, 0xEB); // STEAM + utils::hook::set(0x12CD0F_b, 0xEB); // STEAM // ignore unregistered connection - utils::hook::jump(0x140480F46, 0x140480EE5); // H1MP64(1.4) - utils::hook::set(0x140480F3B, 0xEB); // H1MP64(1.4) + utils::hook::jump(0x54E2D1_b, 0x54E270_b); // STEAM + utils::hook::set(0x54E2C6_b, 0xEB); // STEAM // disable xuid verification - utils::hook::set(0x14005B62D, 0xEB); // H1MP64(1.4) - utils::hook::set(0x14005B649, 0xEB); // H1MP64(1.4) + utils::hook::set(0x728BF_b, 0xEB); // STEAM NOT SURE AT ALL + utils::hook::set(0x72903_b, 0xEB); // STEAM NOT SURE AT FKING ALL // disable xuid verification - utils::hook::nop(0x14048382C, 2); - utils::hook::set(0x140483889, 0xEB); // H1MP64(1.4) + utils::hook::nop(0x5509D9_b, 2); // STEAM SHOULD + utils::hook::set(0x550A36_b, 0xEB); // STEAM SHOULD // ignore configstring mismatch - utils::hook::set(0x1402591C9, 0xEB); // H1MP64(1.4) + utils::hook::set(0x341261_b, 0xEB); // STEAM // ignore dw handle in SV_PacketEvent - utils::hook::set(0x1404898E2, 0xEB); - utils::hook::call(0x1404898D6, &net_compare_address); // H1MP64(1.4) + utils::hook::set(0x1CBC22_b, 0xEB); // STEAM + utils::hook::call(0x1CBC16_b, &net_compare_address); // STEAM // ignore dw handle in SV_FindClientByAddress - utils::hook::set(0x140488EFD, 0xEB); - utils::hook::call(0x140488EF1, &net_compare_address); // H1MP64(1.4) + utils::hook::set(0x1CB24D_b, 0xEB); // STEAM + utils::hook::call(0x1CB241_b, &net_compare_address); // STEAM // ignore dw handle in SV_DirectConnect - utils::hook::set(0x140480C58, 0xEB); - utils::hook::set(0x140480E6F, 0xEB); - utils::hook::call(0x140480C4B, &net_compare_address); - utils::hook::call(0x140480E62, &net_compare_address); + utils::hook::set(0x54DFE8_b, 0xEB); // STEAM + utils::hook::set(0x54E1FD_b, 0xEB); // STEAM NOT_SURE + utils::hook::call(0x54DFDB_b, &net_compare_address); // STEAM + utils::hook::call(0x54E1F0_b, &net_compare_address); // STEAM // increase cl_maxpackets dvars::override::register_int("cl_maxpackets", 1000, 1, 1000, game::DVAR_FLAG_SAVED); @@ -291,32 +291,32 @@ namespace network dvars::override::register_int("sv_remote_client_snapshot_msec", 33, 33, 100, game::DVAR_FLAG_NONE); // ignore impure client - utils::hook::jump(0x140481B58, reinterpret_cast(0x140481BEE)); // H1MP64(1.4) + utils::hook::jump(0x481B58_b, reinterpret_cast(0x54EE69_b)); // STEAM // don't send checksum - utils::hook::set(0x140513433, 0); // H1MP64(1.4) mov: r8d, edi ; LEN - utils::hook::set(0x14051345A, 0); // H1MP64(1.4) + utils::hook::set(0x513433_b, 0); // STEAM mov: r8d, edi ; LEN + utils::hook::set(0x51345A_b, 0); // STEAM // don't read checksum - utils::hook::set(0x1404F6620, 0xC301B0); // H1MP64(1.4) + utils::hook::set(0x513389_b, 0xC301B0); // STEAM // don't try to reconnect client - utils::hook::call(0x140480DFF, reconnect_migratated_client); // H1MP64(1.4) - utils::hook::nop(0x140480DDB, 4); // H1MP64(1.4) this crashes when reconnecting for some reason + utils::hook::call(0x480DFF_b, reconnect_migratated_client); // STEAM + utils::hook::nop(0x480DDB_b, 4); // STEAM this crashes when reconnecting for some reason // allow server owner to modify net_port before the socket bind - utils::hook::call(0x140512BE5, register_netport_stub); // H1MP64(1.4) - utils::hook::call(0x140512D20, register_netport_stub); // H1MP64(1.4) + utils::hook::call(0x512BE5_b, register_netport_stub); // STEAM + utils::hook::call(0x512D20_b, register_netport_stub); // STEAM // increase allowed packet size const auto max_packet_size = 0x20000; - utils::hook::set(0x1404255F1, max_packet_size); // H1MP64(1.4) - utils::hook::set(0x140425630, max_packet_size); // H1MP64(1.4) - utils::hook::set(0x140425522, max_packet_size); // H1MP64(1.4) - utils::hook::set(0x140425545, max_packet_size); // H1MP64(1.4) + utils::hook::set(0x4255F0_b, max_packet_size); // STEAM + utils::hook::set(0x42562E_b, max_packet_size); // STEAM + utils::hook::set(0x425521_b, max_packet_size); // STEAM + utils::hook::set(0x425549_b, max_packet_size); // STEAM // ignore built in "print" oob command and add in our own - utils::hook::set(0x14025280E, 0xEB); // H1MP64(1.4) + utils::hook::set(0x25280E_b, 0xEB); // STEAM on("print", [](const game::netadr_s&, const std::string_view& data) { const std::string message{data}; @@ -325,7 +325,7 @@ namespace network // Use our own socket since the game's socket doesn't work with non localhost addresses // why? no idea - utils::hook::jump(0x140512B40, create_socket); + utils::hook::jump(0x5BD210_b, create_socket); } } }; diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index de9b4983..ac837128 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -180,9 +180,9 @@ namespace scheduler void post_unpack() override { - r_end_frame_hook.create(SELECT_VALUE(0x1404F7310, 0x1405FE470), scheduler::r_end_frame_stub); - g_run_frame_hook.create(SELECT_VALUE(0x1402772D0, 0x14033A640), scheduler::server_frame_stub); - main_frame_hook.create(SELECT_VALUE(0x1401CE8D0, 0x1400D8310), scheduler::main_frame_stub); + r_end_frame_hook.create(SELECT_VALUE(0, 0x6A6300_b), scheduler::r_end_frame_stub); // H1-STEAM(1.15) + g_run_frame_hook.create(SELECT_VALUE(0, 0x417940_b), scheduler::server_frame_stub); // H1(1.15) + //main_frame_hook.create(SELECT_VALUE(0x1401CE8D0, 0x1400D8310), scheduler::main_frame_stub); can't find } void pre_destroy() override diff --git a/src/client/component/splash.cpp b/src/client/component/splash.cpp index 79d23bd1..3dfd6541 100644 --- a/src/client/component/splash.cpp +++ b/src/client/component/splash.cpp @@ -30,9 +30,9 @@ namespace splash void post_unpack() override { // Disable native splash screen - utils::hook::nop(SELECT_VALUE(0x1403E192E, 0x1405123E2), 5); // H1(1.4) - utils::hook::jump(SELECT_VALUE(0x1403E2E70, 0x140513AF0), destroy_stub); // H1(1.4) - utils::hook::jump(SELECT_VALUE(0x1403E2EB0, 0x140513B30), destroy_stub); // H1(1.4) + //utils::hook::nop(SELECT_VALUE(0x1403E192E, 0x1405123E2), 5); // winmain doesn't even exist in 1.15? lmao + utils::hook::jump(SELECT_VALUE(0, 0x5BE1D0_b), destroy_stub); // H1-STEAM(1.15) + utils::hook::jump(SELECT_VALUE(0, 0x5BE210_b), destroy_stub); // H1-STEAM(1.15) } void pre_destroy() override diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 72a3d2bd..01c5cadd 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -8,99 +8,96 @@ namespace game * Functions **************************************************************/ - WEAK symbol AddRefToValue{0x14036E600, 0x14043C580}; - WEAK symbol RemoveRefToValue{0x1403700F0, 0x14043E090}; - WEAK symbol AddRefToObject{0x14036E5F0, 0x14043C570}; - WEAK symbol RemoveRefToObject{0x14036FFE0, 0x14043DF80}; - WEAK symbol AllocThread{0x14036E960, 0x14043C8E0}; + WEAK symbol AddRefToValue{0x36E600, 0x43C580}; + WEAK symbol RemoveRefToValue{0x3700F0, 0x43E090}; + WEAK symbol AddRefToObject{0x36E5F0, 0x43C570}; + WEAK symbol RemoveRefToObject{0x36FFE0, 0x43DF80}; + WEAK symbol AllocThread{0x36E960, 0x43C8E0}; - WEAK symbol Cbuf_AddText{0x140342EB0, 0x1404033B0}; + WEAK symbol Cbuf_AddText{ 0x342EB0, 0x1CF480 }; // H1MP(1.15) WEAK symbol Cbuf_ExecuteBufferInternal{0x140342FC0, 0x1404034C0}; - WEAK symbol Conbuf_AppendText{0x1403E3300, 0x140513FF0}; - WEAK symbol ConcatArgs{0x1402697F0, 0x140335D70}; - WEAK symbol Cmd_ExecuteSingleCommand{0x140343980, 0x140403F60}; - WEAK symbol Cmd_AddCommandInternal{0x1403433E0, 0x140403950}; - WEAK symbol Cmd_RemoveCommand{0x140343FF0, 0x1404045D0}; - WEAK symbol Cmd_TokenizeString{0x140344110, 0x1404046F0}; - WEAK symbol Cmd_EndTokenizeString{0x140343630, 0x140403C20}; + void (int, int, const char*))> Cbuf_ExecuteBufferInternal{0x342FC0, 0x4034C0}; + WEAK symbol Conbuf_AppendText{0x3E3300, 0x513FF0}; + WEAK symbol ConcatArgs{0x2697F0, 0x335D70}; + WEAK symbol Cmd_ExecuteSingleCommand{0x343980, 0x403F60}; + WEAK symbol Cmd_AddCommandInternal{0x3433E0, 0x403950}; + WEAK symbol Cmd_RemoveCommand{0x343FF0, 0x4045D0}; + WEAK symbol Cmd_TokenizeString{0x344110, 0x4046F0}; + WEAK symbol Cmd_EndTokenizeString{0x343630, 0x403C20}; - WEAK symbol AimAssist_AddToTargetList{0, 0x14009D0F0}; + WEAK symbol AimAssist_AddToTargetList{0, 0x9D0F0}; WEAK symbol BG_GetWeaponNameComplete{0x140430550, 0x1401F9670}; + char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x430550, 0x1F9670}; - WEAK symbol Com_Frame_Try_Block_Function{0x1401CE8D0, 0x1400D8310}; - WEAK symbol Com_GetCurrentCoDPlayMode{0, 0x1405039A0}; - WEAK symbol Com_InFrontEnd{0x1400E4B30, 0x140176A30}; - WEAK symbol Com_SetSlowMotion{0, 0x1400DB790}; - WEAK symbol Com_Error{0x1403509C0, 0x1400D78A0}; - WEAK symbol Com_Quit_f{0x140352BE0, 0x1400DA830}; - WEAK symbol Quit{0x140352D90, 0x1400DA830}; + WEAK symbol Com_Frame_Try_Block_Function{0x1CE8D0, 0xD8310}; + WEAK symbol Com_GetCurrentCoDPlayMode{0, 0x5039A0}; + WEAK symbol Com_InFrontEnd{0xE4B30, 0x176A30}; + WEAK symbol Com_SetSlowMotion{0, 0xDB790}; + WEAK symbol Com_Error{0x3509C0, 0xD78A0}; + WEAK symbol Com_Quit_f{0x352BE0, 0xDA830}; + WEAK symbol Quit{0x352D90, 0xDA830}; - WEAK symbol CG_GameMessage{0x1401389A0, 0x140220CC0}; - WEAK symbol CG_GameMessageBold{0x140138750, 0x140220620}; + WEAK symbol CG_GameMessage{0x1389A0, 0x220CC0}; + WEAK symbol CG_GameMessageBold{0x138750, 0x220620}; - WEAK symbol CL_IsCgameInitialized{0x14017EE30, 0x140245650}; + WEAK symbol CL_IsCgameInitialized{0x17EE30, 0x245650}; - WEAK symbol Dvar_SetCommand{0x1403C72B0, 0x1404FD0A0}; - WEAK symbol Dvar_FindVar{0x1403C5D50, 0x1404FBB00}; - WEAK symbol Dvar_GetCombinedString{0x140354DF0, 0x14041D830}; - WEAK symbol Dvar_ValueToString{0x1403C8560, 0x1404FE660}; + WEAK symbol Dvar_SetCommand{0x3C72B0, 0x4FD0A0}; + WEAK symbol Dvar_FindVar{0x3C5D50, 0x4FBB00}; + WEAK symbol Dvar_GetCombinedString{0x354DF0, 0x41D830}; + WEAK symbol Dvar_ValueToString{0x3C8560, 0x4FE660}; WEAK symbol Dvar_RegisterBool{0x1403C47E0, 0x1404FA540}; + unsigned int flags)> Dvar_RegisterBool{0x3C47E0, 0x4FA540}; WEAK symbol Dvar_RegisterInt{0x1403C4CC0, 0x1404FAA20}; + unsigned int flags)> Dvar_RegisterInt{0x3C4CC0, 0x4FAA20}; WEAK symbol Dvar_RegisterFloat{0x1403C4BB0, 0x1404FA910}; + float max, unsigned int flags)> Dvar_RegisterFloat{0x3C4BB0, 0x4FA910}; WEAK symbol Dvar_RegisterString{0x1403C4DA0, 0x1404FAB00}; + unsigned int flags)> Dvar_RegisterString{0x3C4DA0, 0x4FAB00}; WEAK symbol Dvar_RegisterVec4{0x1403C5220, 0x1404FAF40}; + float w, float min, float max, unsigned int flags)> Dvar_RegisterVec4{0x3C5220, 0x4FAF40}; - WEAK symbol FS_ReadFile{0x1403B9020, 0x1404EE720}; - WEAK symbol FS_FreeFile{0x1403B9010, 0x1404EE710}; - WEAK symbol FS_Startup{0x1403B85D0, 0x1404EDD30}; - WEAK symbol FS_AddLocalizedGameDirectory{0x1403B6030, 0x1404EBE20}; + WEAK symbol FS_ReadFile{0x3B9020, 0x4EE720}; + WEAK symbol FS_FreeFile{0x3B9010, 0x4EE710}; + WEAK symbol FS_Startup{0x3B85D0, 0x4EDD30}; + WEAK symbol FS_AddLocalizedGameDirectory{0x3B6030, 0x4EBE20}; - WEAK symbol GetVariable{0x14036FDD0, 0x1403F3730}; + WEAK symbol GetVariable{0x36FDD0, 0x3F3730}; - WEAK symbol GScr_LoadConsts{0x1402D13E0, 0x140393810}; - WEAK symbol FindVariable{0x14036F4B0, 0x14043D430}; - WEAK symbol FindEntityId{0x14036F3B0, 0x14043D330}; - WEAK symbol RemoveVariableValue{0x140370190, 0x14043E130}; + WEAK symbol GScr_LoadConsts{0x2D13E0, 0x393810}; + WEAK symbol FindVariable{0x36F4B0, 0x43D430}; + WEAK symbol FindEntityId{0x36F3B0, 0x43D330}; + WEAK symbol RemoveVariableValue{0x370190, 0x43E130}; WEAK symbol GetEntityFieldValue{0x140373780, 0x140441780}; + int entnum, int offset)> GetEntityFieldValue{0x373780, 0x441780}; - WEAK symbol generateHashValue{0x1400FE8A0, 0x1401B1010}; + WEAK symbol generateHashValue{ 0xFE8A0, 0x183F80 }; // STEEEEEEEEEEEEAM - WEAK symbol G_Glass_Update{0x14026C570, 0x14033A640}; - WEAK symbol G_GetClientScore{0, 0x140342F90}; + WEAK symbol G_Glass_Update{0x26C570, 0x33A640}; + WEAK symbol G_GetClientScore{0, 0x342F90}; - WEAK symbol I_CleanStr{0x1403CD230, 0x140503D00}; + WEAK symbol I_CleanStr{0x3CD230, 0x503D00}; - WEAK symbol Key_KeynumToString{0x140187CC0, 0x14024FE10}; + WEAK symbol Key_KeynumToString{0x187CC0, 0x24FE10}; - WEAK symbol Live_SyncOnlineDataFlags{0, 0x14059A700}; + WEAK symbol Live_SyncOnlineDataFlags{0, 0x59A700}; - WEAK symbol Material_RegisterHandle{0x1404E48B0, 0x1405EAB30}; + WEAK symbol Material_RegisterHandle{0x4E48B0, 0x5EAB30}; - WEAK symbol NetadrToSockadr{0x1403C11C0, 0x1404F62F0}; - WEAK symbol NET_OutOfBandPrint{0x140357560, 0x1404255D0}; - WEAK symbol NET_SendLoopPacket{0, 0x140425790}; - WEAK symbol NET_StringToAdr{0, 0x140425870}; + WEAK symbol NetadrToSockadr{0x3C11C0, 0x4F62F0}; + WEAK symbol NET_OutOfBandPrint{ 0x357560, 0x4F1DE0 }; // STEEAM + WEAK symbol NET_SendLoopPacket{0, 0x425790}; + WEAK symbol NET_StringToAdr{0, 0x425870}; WEAK symbol R_AddCmdDrawStretchPic{0x14017E5C0, 0x1402443A0}; - WEAK symbol R_RegisterFont{0x1404D4100, 0x1405D91E0}; - WEAK symbol R_TextWidth{0x1404D43B0, 0x1405D94A0}; - WEAK symbol R_GetFontHeight{0x1405EA360, 0x1405D92C0}; - WEAK symbol R_DrawSomething{0x1404D37B0, 0x1405D8890}; - WEAK symbol R_SyncRenderThread{0x1404F8240, 0x1405FF3A0}; - WEAK symbol H1_AddBaseDrawTextCmd{0x1404F3DC0, 0x1405FB1F0}; + float* color, Material* material)> R_AddCmdDrawStretchPic{0x17E5C0, 0x2443A0}; + WEAK symbol R_RegisterFont{ 0x4D4100, 0x67F630 }; // H1MP(1.15) + WEAK symbol R_TextWidth{0x4D43B0, 0x5D94A0}; + WEAK symbol R_GetFontHeight{0x5EA360, 0x5D92C0}; + WEAK symbol R_DrawSomething{0x4D37B0, 0x5D8890}; + WEAK symbol R_SyncRenderThread{0x4F8240, 0x5FF3A0}; + WEAK symbol H1_AddBaseDrawTextCmd{ 0x4F3DC0,0x6A3080 }; // H1MP(1.15) #define R_AddCmdDrawText(TXT, MC, F, X, Y, XS, YS, R, C, S) \ H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S,-1, 0, game::R_DrawSomething(S)) @@ -108,140 +105,140 @@ namespace game H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S, CP, CC, game::R_DrawSomething(S)) WEAK symbol VM_Execute{0x140376360, 0x140444350}; + unsigned int paramcount)> VM_Execute{0x376360, 0x444350}; WEAK symbol Scr_NotifyId{0x140375800, 0x1404437E0}; - WEAK symbol Scr_AllocVector{0x140370930, 0x14043E7D0}; - WEAK symbol Scr_GetFloat{0x140374D20, 0x140442D10}; - WEAK symbol Scr_GetString{0x140375210, 0x140443150}; - WEAK symbol Scr_GetNumParam{0x140374F30, 0x140442E70}; - WEAK symbol Scr_ClearOutParams{0x140374460, 0x140442510}; - WEAK symbol Scr_GetEntityIdRef{0x140372D50, 0x140440D80}; - WEAK symbol Scr_GetEntityId{0x140372CA0, 0x140440CD0}; + unsigned int paramcount)> Scr_NotifyId{0x375800, 0x4437E0}; + WEAK symbol Scr_AllocVector{0x370930, 0x43E7D0}; + WEAK symbol Scr_GetFloat{0x374D20, 0x442D10}; + WEAK symbol Scr_GetString{0x375210, 0x443150}; + WEAK symbol Scr_GetNumParam{0x374F30, 0x442E70}; + WEAK symbol Scr_ClearOutParams{0x374460, 0x442510}; + WEAK symbol Scr_GetEntityIdRef{0x372D50, 0x440D80}; + WEAK symbol Scr_GetEntityId{0x372CA0, 0x440CD0}; - WEAK symbol ScrPlace_GetViewPlacement{0x1401981F0, 0x140288550}; + WEAK symbol ScrPlace_GetViewPlacement{0x1981F0, 0x288550}; - WEAK symbol DB_GetXAssetTypeSize{0x14019A3B0, 0x14028BE70}; + WEAK symbol DB_GetXAssetTypeSize{0x19A3B0, 0x28BE70}; WEAK symbol LUI_OpenMenu{0x14039D5F0, 0x1404CD210}; + int a3, int a4, unsigned int a5)> LUI_OpenMenu{0x39D5F0, 0x4CD210}; - WEAK symbol Menu_IsMenuOpenAndVisible{0x1404709C0, 0x1404C7320}; + WEAK symbol Menu_IsMenuOpenAndVisible{0x4709C0, 0x4C7320}; - WEAK symbol SL_FindString{0x14036D700, 0x14043B470}; - WEAK symbol SL_GetString{0x14036D9A0, 0x14043B840}; - WEAK symbol SL_ConvertToString{0x14036D420, 0x14043B170}; - WEAK symbol Scr_SetObjectField{0x1402B9F60, 0x140385330}; + WEAK symbol SL_FindString{0x36D700, 0x43B470}; + WEAK symbol SL_GetString{0x36D9A0, 0x43B840}; + WEAK symbol SL_ConvertToString{0x36D420, 0x43B170}; + WEAK symbol Scr_SetObjectField{0x2B9F60, 0x385330}; - WEAK symbol SV_DirectConnect{0, 0x140480860}; - WEAK symbol SV_Cmd_ArgvBuffer{0x1403446C0, 0x140404CA0}; - WEAK symbol SV_Cmd_TokenizeString{0x140344740, 0x140404D20}; - WEAK symbol SV_Cmd_EndTokenizedString{0x140344700, 0x140404CE0}; + WEAK symbol SV_DirectConnect{0, 0x480860}; + WEAK symbol SV_Cmd_ArgvBuffer{0x3446C0, 0x404CA0}; + WEAK symbol SV_Cmd_TokenizeString{0x344740, 0x404D20}; + WEAK symbol SV_Cmd_EndTokenizedString{0x344700, 0x404CE0}; - WEAK symbol SV_AddBot{0, 0x140480190}; - WEAK symbol SV_BotIsBot{0, 0x14046E6C0}; - WEAK symbol SV_BotGetRandomName{0, 0x14046DBA0}; - WEAK symbol SV_SpawnTestClient{0, 0x1404832A0}; + WEAK symbol SV_AddBot{0, 0x480190}; + WEAK symbol SV_BotIsBot{0, 0x46E6C0}; + WEAK symbol SV_BotGetRandomName{0, 0x46DBA0}; + WEAK symbol SV_SpawnTestClient{0, 0x4832A0}; - WEAK symbol SV_GetGuid{0, 0x140484B90}; - WEAK symbol SV_GetClientPing{0, 0x140484B70}; - WEAK symbol SV_GetPlayerstateForClientNum{0x1404426D0, 0x140484C10}; - WEAK symbol SV_SetConfigstring{0, 0x140486720}; - WEAK symbol SV_Loaded{0x140442F60, 0x1404864A0}; - WEAK symbol SV_KickClientNum{0, 0x14047ED00}; - WEAK symbol SV_MapExists{0, 0x14047ED60}; - WEAK symbol SV_ExecuteClientCommand{0, 0x140481870}; - WEAK symbol SV_FastRestart{0, 0x14047E990}; + WEAK symbol SV_GetGuid{0, 0x484B90}; + WEAK symbol SV_GetClientPing{0, 0x484B70}; + WEAK symbol SV_GetPlayerstateForClientNum{0x4426D0, 0x484C10}; + WEAK symbol SV_SetConfigstring{0, 0x486720}; + WEAK symbol SV_Loaded{0x442F60, 0x4864A0}; + WEAK symbol SV_KickClientNum{0, 0x47ED00}; + WEAK symbol SV_MapExists{0, 0x47ED60}; + WEAK symbol SV_ExecuteClientCommand{0, 0x481870}; + WEAK symbol SV_FastRestart{0, 0x47E990}; WEAK symbol SV_GameSendServerCommand{ - 0x1403F3A70, 0x140484AD0 + 0x3F3A70, 0x484AD0 }; - WEAK symbol Sys_ShowConsole{0x1403E3B90, 0x140514910}; - WEAK symbol Sys_Error{0x1403E0C40, 0x140511520}; + WEAK symbol Sys_ShowConsole{0x3E3B90, 0x514910}; + WEAK symbol Sys_Error{0x3E0C40, 0x511520}; WEAK symbol - Sys_BuildAbsPath{0x1403CFF90, 0x140507010}; - WEAK symbol Sys_Milliseconds{0x1403E2B10, 0x140513710}; - WEAK symbol Sys_IsDatabaseReady2{0x1403580B0, 0x14042B090}; - WEAK symbol Sys_SendPacket{0x1403E2820, 0x1405133B0}; - WEAK symbol Sys_FileExists{0x1403E0CE0, 0x1405115E0}; + Sys_BuildAbsPath{0x3CFF90, 0x507010}; + WEAK symbol Sys_Milliseconds{0x3E2B10, 0x513710}; + WEAK symbol Sys_IsDatabaseReady2{0x3580B0, 0x42B090}; + WEAK symbol Sys_SendPacket{0x3E2820, 0x5133B0}; + WEAK symbol Sys_FileExists{0x3E0CE0, 0x5115E0}; - WEAK symbol UI_GetMapDisplayName{0, 0x140408CC0}; - WEAK symbol UI_GetGameTypeDisplayName{0, 0x1404086A0}; - WEAK symbol UI_RunMenuScript{0x14039EFF0, 0x1404CFE60}; - WEAK symbol UI_TextWidth{0x1403A0F20, 0x1404D21A0}; + WEAK symbol UI_GetMapDisplayName{0, 0x408CC0}; + WEAK symbol UI_GetGameTypeDisplayName{0, 0x4086A0}; + WEAK symbol UI_RunMenuScript{0x39EFF0, 0x4CFE60}; + WEAK symbol UI_TextWidth{0x3A0F20, 0x4D21A0}; - WEAK symbol UI_SafeTranslateString{0x140350430, 0x14041C580}; + WEAK symbol UI_SafeTranslateString{0x350430, 0x41C580}; - WEAK symbol longjmp{0x140648FD4, 0x140779F64}; - WEAK symbol _setjmp{0x1406BFD30, 0x1407F5F90}; + WEAK symbol longjmp{0x648FD4, 0x779F64}; + WEAK symbol _setjmp{0x6BFD30, 0x7F5F90}; /*************************************************************** * Variables **************************************************************/ - WEAK symbol sv_cmd_args{0x14AD99A10, 0x14946BA20}; + WEAK symbol sv_cmd_args{0xAD99A10, 0x946BA20}; - WEAK symbol g_script_error_level{0x14A1917A8, 0x14A33C824}; - WEAK symbol g_script_error{0x14A1917B0, 0x14A33C940}; + WEAK symbol g_script_error_level{0xA1917A8, 0xA33C824}; + WEAK symbol g_script_error{0xA1917B0, 0xA33C940}; - WEAK symbol levelEntityId{0x149AF55B0, 0x149CA0730}; - WEAK symbol gameEntityId{0x149CA0734, 0x14B65E3B4}; + WEAK symbol levelEntityId{0x9AF55B0, 0x9CA0730}; + WEAK symbol gameEntityId{0x9CA0734, 0xB65E3B4}; - WEAK symbol command_whitelist{0x141079A60, 0x14120C360}; - WEAK symbol cmd_functions{0x14AD99AB8, 0x14946BAC8}; - WEAK symbol cmd_args{0x14AD99960, 0x14946B970}; + WEAK symbol command_whitelist{0x1079A60, 0x120C360}; + WEAK symbol cmd_functions{ 0xAD99AB8,0x344DF18 }; // H1MP(1.15) + WEAK symbol cmd_args{0xAD99960, 0x946B970}; - WEAK symbol g_poolSize{0, 0x140FEADF0}; - WEAK symbol g_classMap{0x14080A840, 0x1412106B0}; + WEAK symbol g_poolSize{0, 0xFEADF0}; + WEAK symbol g_classMap{0x80A840, 0x12106B0}; - WEAK symbol scr_VarGlob{0x14B686480, 0x149CC8800}; - WEAK symbol scr_VmPub{0x14A1938C0, 0x14A33EA40}; - WEAK symbol scr_function_stack{0x14BD06C40, 0x14A348FC0}; + WEAK symbol scr_VarGlob{0xB686480, 0x9CC8800}; + WEAK symbol scr_VmPub{0xA1938C0, 0xA33EA40}; + WEAK symbol scr_function_stack{0xBD06C40, 0xA348FC0}; - WEAK symbol gfxDrawMethod{0x14F05CE50, 0x14FD21180}; + WEAK symbol gfxDrawMethod{0xF05CE50, 0xFD21180}; - WEAK symbol dvarCount{0x14C217D10, 0x14D064CF4}; - WEAK symbol dvarPool{0x14C217D20, 0x14D064D00}; + WEAK symbol dvarCount{0xC217D10, 0xD064CF4}; + WEAK symbol dvarPool{0xC217D20, 0xD064D00}; - WEAK symbol DB_XAssetPool{0x140DE8C80, 0x140FEB5D0}; + WEAK symbol DB_XAssetPool{0xDE8C80, 0xFEB5D0}; - WEAK symbol keyCatchers{0x14243DAF0, 0x142D0BA9C}; - WEAK symbol playerKeys{0x1422A873C, 0x142C19AFC}; + WEAK symbol keyCatchers{0x243DAF0, 0x2D0BA9C}; + WEAK symbol playerKeys{0x22A873C, 0x2C19AFC}; - WEAK symbol query_socket{0, 0x14DDFBF98}; + WEAK symbol query_socket{0, 0xDDFBF98}; - WEAK symbol threadIds{0x14B19B880, 0x149810E00}; + WEAK symbol threadIds{0xB19B880, 0x9810E00}; namespace mp { - WEAK symbol g_entities{0, 0x14621E530}; - WEAK symbol svs_clients{0, 0x14B204A10}; - WEAK symbol svs_numclients{0, 0x14B204A0C}; - WEAK symbol gameTime{0, 0x14621BDBC}; + WEAK symbol g_entities{ 0, 0x71F19E0 }; // H1MP(1.15) + WEAK symbol svs_clients{0, 0xB204A10}; + WEAK symbol svs_numclients{0, 0xB204A0C}; + WEAK symbol gameTime{0, 0x621BDBC}; - WEAK symbol sv_serverId_value{0, 0x14A3E99B8}; + WEAK symbol sv_serverId_value{0, 0xA3E99B8}; - WEAK symbol virtualLobby_loaded{0, 0x142D077FD}; + WEAK symbol virtualLobby_loaded{0, 0x2D077FD}; } namespace sp { - WEAK symbol g_entities{0x14550DD90, 0}; + WEAK symbol g_entities{0x550DD90, 0}; } namespace hks { - WEAK symbol lua_state{0x141E2C2F8, 0x1426D3D08}; - WEAK symbol hksi_lua_pushlstring{0x14004DA90, 0x1400624F0}; - WEAK symbol hks_obj_getfield{0x14009C0A0, 0x14012C600}; - WEAK symbol hks_obj_settable{0x14009D240, 0x14012D820}; - WEAK symbol hks_obj_gettable{0x14009C580, 0x14012CAE0}; - WEAK symbol vm_call_internal{0x1400C87A0, 0x140159EB0}; - WEAK symbol Hashtable_Create{0x14008B3B0, 0x14011B320}; + WEAK symbol lua_state{0x1E2C2F8, 0x26D3D08}; + WEAK symbol hksi_lua_pushlstring{0x4DA90, 0x624F0}; + WEAK symbol hks_obj_getfield{0x9C0A0, 0x12C600}; + WEAK symbol hks_obj_settable{0x9D240, 0x12D820}; + WEAK symbol hks_obj_gettable{0x9C580, 0x12CAE0}; + WEAK symbol vm_call_internal{0xC87A0, 0x159EB0}; + WEAK symbol Hashtable_Create{0x8B3B0, 0x11B320}; WEAK symbol cclosure_Create{0x14008B5D0, 0x14011B540}; - WEAK symbol hksi_luaL_ref{0x1400A64D0, 0x140136D30}; - WEAK symbol hksi_luaL_unref{0x14009EF10, 0x14012F610}; + int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x8B5D0, 0x11B540}; + WEAK symbol hksi_luaL_ref{0xA64D0, 0x136D30}; + WEAK symbol hksi_luaL_unref{0x9EF10, 0x12F610}; } } From d48696e2addc019969202297cc0715375747dfe7 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Sat, 5 Mar 2022 15:19:17 +0300 Subject: [PATCH 039/346] update master server --- src/client/component/server_list.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index 1b7e759e..407acfe7 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -309,8 +309,7 @@ namespace server_list bool get_master_server(game::netadr_s& address) { - return game::NET_StringToAdr("135.148.53.121:20810", &address); - // return game::NET_StringToAdr("master.xlabs.dev:20810", &address); + return game::NET_StringToAdr("master.ff.h1p.co:20810", &address); } void handle_info_response(const game::netadr_s& address, const utils::info_string& info) From 6306283272493bf621f613c4ee6c9293187a982e Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sat, 5 Mar 2022 16:38:34 +0100 Subject: [PATCH 040/346] Add better hud ping & fps counter --- data/ui_scripts/hud_info/__init__.lua | 6 + data/ui_scripts/hud_info/hud.lua | 152 ++++++++++++++++ data/ui_scripts/hud_info/settings.lua | 173 +++++++++++++++++++ src/client/component/fps.cpp | 20 ++- src/client/component/fps.hpp | 6 + src/client/component/patches.cpp | 2 +- src/client/game/symbols.hpp | 2 + src/client/game/ui_scripting/lua/context.cpp | 21 +++ 8 files changed, 375 insertions(+), 7 deletions(-) create mode 100644 data/ui_scripts/hud_info/__init__.lua create mode 100644 data/ui_scripts/hud_info/hud.lua create mode 100644 data/ui_scripts/hud_info/settings.lua create mode 100644 src/client/component/fps.hpp diff --git a/data/ui_scripts/hud_info/__init__.lua b/data/ui_scripts/hud_info/__init__.lua new file mode 100644 index 00000000..f1c9049c --- /dev/null +++ b/data/ui_scripts/hud_info/__init__.lua @@ -0,0 +1,6 @@ +if (game:issingleplyer()) then + return +end + +require("settings") +require("hud") \ No newline at end of file diff --git a/data/ui_scripts/hud_info/hud.lua b/data/ui_scripts/hud_info/hud.lua new file mode 100644 index 00000000..fc44dab6 --- /dev/null +++ b/data/ui_scripts/hud_info/hud.lua @@ -0,0 +1,152 @@ +local mphud = luiglobals.require("LUI.mp_hud.MPHud") + +function createinfobar() + local infobar = LUI.UIElement.new({ + left = luiglobals.GameX.IsHardcoreMode() and 160 or 228, + top = luiglobals.GameX.IsHardcoreMode() and 5 or 9, + height = 15, + width = 70, + leftAnchor = true, + topAnchor = true + }) + + infobar:registerAnimationState("hud_on", { + alpha = 1 + }) + + infobar:registerAnimationState("hud_off", { + alpha = 0 + }) + + return infobar +end + +function populateinfobar(infobar) + elementoffset = 0 + + if (Engine.GetDvarBool("cg_infobar_fps")) then + infobar:addElement(infoelement({ + label = "FPS: ", + getvalue = function() + return game:getfps() + end, + width = 70, + interval = 100 + })) + end + + if (Engine.GetDvarBool("cg_infobar_ping")) then + infobar:addElement(infoelement({ + label = "Latency: ", + getvalue = function() + return game:getping() .. " ms" + end, + width = 115, + interval = 100 + })) + end +end + +function infoelement(data) + local container = LUI.UIElement.new({ + bottomAnchor = true, + leftAnchor = true, + topAnchor = true, + width = data.width, + left = elementoffset + }) + + elementoffset = elementoffset + data.width + 10 + + local background = LUI.UIImage.new({ + bottomAnchor = true, + leftAnchor = true, + topAnchor = true, + rightAnchor = true, + material = luiglobals.RegisterMaterial("white"), + color = luiglobals.Colors.black, + alpha = 0.5 + }) + + local labelfont = CoD.TextSettings.FontBold110 + local textheight = 13 + + local label = LUI.UIText.new({ + left = 5, + top = 1, + font = labelfont.Font, + height = textheight, + leftAnchor = true, + topAnchor = true, + color = { + r = 0.8, + g = 0.8, + b = 0.8, + } + }) + + label:setText(data.label) + + local _, _, left = luiglobals.GetTextDimensions(data.label, labelfont.Font, textheight) + local value = LUI.UIText.new({ + left = left + 5, + top = 1, + height = textheight, + leftAnchor = true, + topAnchor = true, + color = { + r = 0.6, + g = 0.6, + b = 0.6, + } + }) + + value:addElement(LUI.UITimer.new(data.interval, "update")) + value:setText(data.getvalue()) + value:addEventHandler("update", function() + value:setText(data.getvalue()) + end) + + container:addElement(background) + container:addElement(label) + container:addElement(value) + + return container +end + +local updatehudvisibility = mphud.updateHudVisibility +mphud.updateHudVisibility = function(a1, a2) + updatehudvisibility(a1, a2) + + local root = Engine.GetLuiRoot() + local menus = root:AnyActiveMenusInStack() + local infobar = root.infobar + + if (menus) then + infobar:animateToState("hud_off") + else + infobar:animateToState("hud_on") + end +end + +LUI.onmenuopen("mp_hud", function(hud) + if (Engine.InFrontend()) then + return + end + + local infobar = createinfobar() + local root = Engine.GetLuiRoot() + root.infobar = infobar + populateinfobar(infobar) + + root:registerEventHandler("update_hud_infobar_settings", function() + infobar:removeAllChildren() + populateinfobar(infobar) + end) + + root:processEvent({ + name = "update_hud_infobar_settings" + }) + + hud.static:addElement(infobar) +end) \ No newline at end of file diff --git a/data/ui_scripts/hud_info/settings.lua b/data/ui_scripts/hud_info/settings.lua new file mode 100644 index 00000000..9646ce5d --- /dev/null +++ b/data/ui_scripts/hud_info/settings.lua @@ -0,0 +1,173 @@ +local pcdisplay = luiglobals.require("LUI.PCDisplay") + +function createdivider(menu, text) + local element = LUI.UIElement.new( { + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + topAnchor = true, + bottomAnchor = false, + top = 0, + bottom = 33.33 + }) + + element.scrollingToNext = true + element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { + title_bar_text = text + })) + + menu.list:addElement(element) +end + +pcdisplay.CreateOptions = function( menu ) + LUI.Options.AddButtonOptionVariant( + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_COLORBLIND_FILTER", + "@LUA_MENU_COLOR_BLIND_DESC", + LUI.Options.GetRenderColorBlindText, + LUI.Options.RenderColorBlindToggle, + LUI.Options.RenderColorBlindToggle + ) + + if Engine.IsMultiplayer() and Engine.GetDvarType( "cg_paintballFx" ) == luiglobals.DvarTypeTable.DvarBool then + LUI.Options.AddButtonOptionVariant( + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_PAINTBALL", "@LUA_MENU_PAINTBALL_DESC", + LUI.Options.GetDvarEnableTextFunc("cg_paintballFx", false), + LUI.Options.ToggleDvarFunc("cg_paintballFx"), + LUI.Options.ToggleDvarFunc("cg_paintballFx") + ) + end + + LUI.Options.AddButtonOptionVariant( + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_BLOOD", + "@LUA_MENU_BLOOD_DESC", + LUI.Options.GetDvarEnableTextFunc("cg_blood", false), + LUI.Options.ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0)), + LUI.Options.ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0)) + ) + + if not Engine.IsMultiplayer() then + LUI.Options.AddButtonOptionVariant( + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_CROSSHAIR", + "@LUA_MENU_CROSSHAIR_DESC", + LUI.Options.GetDvarEnableTextFunc("cg_drawCrosshairOption", false), + LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption"), + LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption") + ) + + LUI.Options.CreateOptionButton( + menu, + "cg_drawDamageFeedbackOption", + "@LUA_MENU_HIT_MARKER", + "@LUA_MENU_HIT_MARKER_DESC", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + } + ) + end + + if Engine.IsMultiplayer() then + LUI.Options.AddButtonOptionVariant( + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@MENU_DISPLAY_KILLSTREAK_COUNTER", + "@MENU_DISPLAY_KILLSTREAK_COUNTER_DESC", + pcdisplay.GetDisplayKillstreakCounterText, + pcdisplay.DisplayKillstreakCounterToggle, + pcdisplay.DisplayKillstreakCounterToggle + ) + + LUI.Options.AddButtonOptionVariant( + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@MENU_DISPLAY_MEDAL_SPLASHES", + "@MENU_DISPLAY_MEDAL_SPLASHES_DESC", + pcdisplay.GetDisplayMedalSplashesText, + pcdisplay.DisplayMedalSplashesToggle, + pcdisplay.DisplayMedalSplashesToggle + ) + + LUI.Options.AddButtonOptionVariant( + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@MENU_DISPLAY_WEAPON_EMBLEMS", + "@MENU_DISPLAY_WEAPON_EMBLEMS_DESC", + pcdisplay.GetDisplayWeaponEmblemsText, + pcdisplay.DisplayWeaponEmblemsToggle, + pcdisplay.DisplayWeaponEmblemsToggle + ) + end + + LUI.Options.AddButtonOptionVariant( + menu, + luiglobals.GenericButtonSettings.Variants.Common, + "@MENU_BRIGHTNESS", + "@MENU_BRIGHTNESS_DESC1", + nil, nil, nil, + pcdisplay.OpenBrightnessMenu, + nil, nil, nil + ) + + createdivider(menu, "TELEMETRY") + + LUI.Options.CreateOptionButton( + menu, + "cg_infobar_ping", + "Server Latency", + "Show server latency", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + }, nil, nil, function(value) + Engine.SetDvarBool("cg_infobar_ping", value) + Engine.GetLuiRoot():processEvent({ + name = "update_hud_infobar_settings" + }) + end + ) + + LUI.Options.CreateOptionButton( + menu, + "cg_infobar_fps", + "FPS counter", + "Show FPS counter", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + }, nil, nil, function(value) + Engine.SetDvarBool("cg_infobar_fps", value) + Engine.GetLuiRoot():processEvent({ + name = "update_hud_infobar_settings" + }) + end + ) + + LUI.Options.InitScrollingList(menu.list, nil) +end diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index db471119..a0ea9299 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -1,6 +1,8 @@ #include #include "loader/component_loader.hpp" +#include "fps.hpp" + #include "game/game.hpp" #include "game/dvars.hpp" @@ -93,9 +95,7 @@ namespace fps { if (cg_drawfps->current.integer > 0) { - const auto fps = static_cast(static_cast(1000.0f / static_cast(cg_perf. - average)) - + 9.313225746154785e-10); + const auto fps = fps::get_fps(); const auto font = game::R_RegisterFont("fonts/fira_mono_regular.ttf", 25); const auto fps_string = utils::string::va("%i", fps); @@ -113,10 +113,8 @@ namespace fps { if (cg_drawping->current.integer > 0 && game::CL_IsCgameInitialized() && !game::VirtualLobby_Loaded()) { - const auto ping = *reinterpret_cast(0x142D106F0); - const auto font = game::R_RegisterFont("fonts/consolefont", 20); - const auto ping_string = utils::string::va("Ping: %i", ping); + const auto ping_string = utils::string::va("Ping: %i", *game::mp::ping); const auto x = (game::ScrPlace_GetViewPlacement()->realViewportSize[0] - 375.0f) - game::R_TextWidth( ping_string, 0x7FFFFFFF, font); @@ -134,6 +132,13 @@ namespace fps } } + int get_fps() + { + return static_cast(static_cast(1000.0f / static_cast(cg_perf. + average)) + + 9.313225746154785e-10); + } + class component final : public component_interface { public: @@ -167,6 +172,9 @@ namespace fps scheduler::loop(cg_draw_ping, scheduler::pipeline::renderer); } + + dvars::register_bool("cg_infobar_fps", false, game::DVAR_FLAG_SAVED, true); + dvars::register_bool("cg_infobar_ping", false, game::DVAR_FLAG_SAVED, true); } }; } diff --git a/src/client/component/fps.hpp b/src/client/component/fps.hpp new file mode 100644 index 00000000..a4326a1f --- /dev/null +++ b/src/client/component/fps.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace fps +{ + int get_fps(); +} diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index e9aaf21a..f90f0375 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -266,7 +266,7 @@ namespace patches dvars::register_int("scr_game_spectatetype", 1, 0, 99, game::DVAR_FLAG_REPLICATED); - dvars::override::register_int("com_maxfps", 0, 10, 1000, game::DVAR_FLAG_SAVED); + dvars::override::register_int("com_maxfps", 0, 0, 1000, game::DVAR_FLAG_SAVED); // Prevent clients from ending the game as non host by sending 'end_game' lui notification // cmd_lui_notify_server_hook.create(0x140335A70, cmd_lui_notify_server_stub); // H1(1.4) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 72a3d2bd..0e0c02e4 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -220,6 +220,8 @@ namespace game WEAK symbol svs_numclients{0, 0x14B204A0C}; WEAK symbol gameTime{0, 0x14621BDBC}; + WEAK symbol ping{0, 0x142D106F0}; + WEAK symbol sv_serverId_value{0, 0x14A3E99B8}; WEAK symbol virtualLobby_loaded{0, 0x142D077FD}; diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index afa00d5d..42ca7977 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -8,6 +8,7 @@ #include "../../../component/ui_scripting.hpp" #include "../../../component/command.hpp" #include "../../../component/updater.hpp" +#include "../../../component/fps.hpp" #include "component/game_console.hpp" #include "component/scheduler.hpp" @@ -40,6 +41,26 @@ namespace ui_scripting::lua return scheduler.add(callback, milliseconds, false); }; + game_type["getfps"] = [](const game&) + { + return fps::get_fps(); + }; + + game_type["getping"] = [](const game&) + { + return *::game::mp::ping; + }; + + game_type["issingleplayer"] = [](const game&) + { + return ::game::environment::is_sp(); + }; + + game_type["ismultiplayer"] = [](const game&) + { + return ::game::environment::is_mp(); + }; + auto userdata_type = state.new_usertype("userdata_"); userdata_type["new"] = sol::property( From 456d83f1c0a4fbce62f70afbc68284225d19228e Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sat, 5 Mar 2022 18:36:56 +0100 Subject: [PATCH 041/346] Some fixes --- data/ui_scripts/hud_info/__init__.lua | 2 +- data/ui_scripts/hud_info/hud.lua | 4 ++++ data/ui_scripts/hud_info/settings.lua | 14 ++++++++++---- src/client/game/ui_scripting/lua/context.cpp | 8 +++++++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/data/ui_scripts/hud_info/__init__.lua b/data/ui_scripts/hud_info/__init__.lua index f1c9049c..b6f5c8a2 100644 --- a/data/ui_scripts/hud_info/__init__.lua +++ b/data/ui_scripts/hud_info/__init__.lua @@ -1,4 +1,4 @@ -if (game:issingleplyer()) then +if (game:issingleplayer()) then return end diff --git a/data/ui_scripts/hud_info/hud.lua b/data/ui_scripts/hud_info/hud.lua index fc44dab6..e2889454 100644 --- a/data/ui_scripts/hud_info/hud.lua +++ b/data/ui_scripts/hud_info/hud.lua @@ -122,6 +122,10 @@ mphud.updateHudVisibility = function(a1, a2) local menus = root:AnyActiveMenusInStack() local infobar = root.infobar + if (not infobar) then + return + end + if (menus) then infobar:animateToState("hud_off") else diff --git a/data/ui_scripts/hud_info/settings.lua b/data/ui_scripts/hud_info/settings.lua index 9646ce5d..4ce32564 100644 --- a/data/ui_scripts/hud_info/settings.lua +++ b/data/ui_scripts/hud_info/settings.lua @@ -1,5 +1,11 @@ local pcdisplay = luiglobals.require("LUI.PCDisplay") +game:addlocalizedstring("LUA_MENU_FPS", "FPS Counter") +game:addlocalizedstring("LUA_MENU_FPS_DESC", "Show FPS Counter") + +game:addlocalizedstring("LUA_MENU_LATENCY", "Server Latency") +game:addlocalizedstring("LUA_MENU_LATENCY_DESC", "Show server latency") + function createdivider(menu, text) local element = LUI.UIElement.new( { leftAnchor = true, @@ -128,8 +134,8 @@ pcdisplay.CreateOptions = function( menu ) LUI.Options.CreateOptionButton( menu, "cg_infobar_ping", - "Server Latency", - "Show server latency", + "@LUA_MENU_LATENCY", + "@LUA_MENU_LATENCY_DESC", { { text = "@LUA_MENU_ENABLED", @@ -150,8 +156,8 @@ pcdisplay.CreateOptions = function( menu ) LUI.Options.CreateOptionButton( menu, "cg_infobar_fps", - "FPS counter", - "Show FPS counter", + "@LUA_MENU_FPS", + "@LUA_MENU_FPS_DESC", { { text = "@LUA_MENU_ENABLED", diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 42ca7977..96286cdd 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -9,6 +9,7 @@ #include "../../../component/command.hpp" #include "../../../component/updater.hpp" #include "../../../component/fps.hpp" +#include "../../../component/localized_strings.hpp" #include "component/game_console.hpp" #include "component/scheduler.hpp" @@ -61,6 +62,12 @@ namespace ui_scripting::lua return ::game::environment::is_mp(); }; + game_type["addlocalizedstring"] = [](const game&, const std::string& string, + const std::string& value) + { + localized_strings::override(string, value); + }; + auto userdata_type = state.new_usertype("userdata_"); userdata_type["new"] = sol::property( @@ -73,7 +80,6 @@ namespace ui_scripting::lua userdata.set("new", convert({s, value})); } ); - userdata_type["get"] = [](const userdata& userdata, const sol::this_state s, const sol::lua_value& key) From efe6291eaf7308796f6fdd70285510adcfd2d631 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sat, 5 Mar 2022 18:47:49 +0100 Subject: [PATCH 042/346] Formatting --- data/ui_scripts/hud_info/__init__.lua | 2 +- data/ui_scripts/hud_info/hud.lua | 246 ++++++++++++------------- data/ui_scripts/hud_info/settings.lua | 250 +++++++++++++------------- 3 files changed, 250 insertions(+), 248 deletions(-) diff --git a/data/ui_scripts/hud_info/__init__.lua b/data/ui_scripts/hud_info/__init__.lua index b6f5c8a2..07dfbdd4 100644 --- a/data/ui_scripts/hud_info/__init__.lua +++ b/data/ui_scripts/hud_info/__init__.lua @@ -1,5 +1,5 @@ if (game:issingleplayer()) then - return + return end require("settings") diff --git a/data/ui_scripts/hud_info/hud.lua b/data/ui_scripts/hud_info/hud.lua index e2889454..94acfc63 100644 --- a/data/ui_scripts/hud_info/hud.lua +++ b/data/ui_scripts/hud_info/hud.lua @@ -1,156 +1,158 @@ local mphud = luiglobals.require("LUI.mp_hud.MPHud") +local barheight = 16 +local textheight = 13 +local textoffsety = barheight / 2 - textheight / 2 function createinfobar() - local infobar = LUI.UIElement.new({ - left = luiglobals.GameX.IsHardcoreMode() and 160 or 228, - top = luiglobals.GameX.IsHardcoreMode() and 5 or 9, - height = 15, - width = 70, - leftAnchor = true, - topAnchor = true - }) + local infobar = LUI.UIElement.new({ + left = luiglobals.GameX.IsHardcoreMode() and 160 or 228, + top = luiglobals.GameX.IsHardcoreMode() and 5 or 9, + height = barheight, + width = 70, + leftAnchor = true, + topAnchor = true + }) - infobar:registerAnimationState("hud_on", { - alpha = 1 - }) + infobar:registerAnimationState("hud_on", { + alpha = 1 + }) - infobar:registerAnimationState("hud_off", { - alpha = 0 - }) + infobar:registerAnimationState("hud_off", { + alpha = 0 + }) - return infobar + return infobar end function populateinfobar(infobar) - elementoffset = 0 + elementoffset = 0 - if (Engine.GetDvarBool("cg_infobar_fps")) then - infobar:addElement(infoelement({ - label = "FPS: ", - getvalue = function() - return game:getfps() - end, - width = 70, - interval = 100 - })) - end + if (Engine.GetDvarBool("cg_infobar_fps")) then + infobar:addElement(infoelement({ + label = "FPS: ", + getvalue = function() + return game:getfps() + end, + width = 70, + interval = 100 + })) + end - if (Engine.GetDvarBool("cg_infobar_ping")) then - infobar:addElement(infoelement({ - label = "Latency: ", - getvalue = function() - return game:getping() .. " ms" - end, - width = 115, - interval = 100 - })) - end + if (Engine.GetDvarBool("cg_infobar_ping")) then + infobar:addElement(infoelement({ + label = "Latency: ", + getvalue = function() + return game:getping() .. " ms" + end, + width = 115, + interval = 100 + })) + end end function infoelement(data) - local container = LUI.UIElement.new({ - bottomAnchor = true, - leftAnchor = true, - topAnchor = true, - width = data.width, - left = elementoffset - }) + local container = LUI.UIElement.new({ + bottomAnchor = true, + leftAnchor = true, + topAnchor = true, + width = data.width, + left = elementoffset + }) - elementoffset = elementoffset + data.width + 10 + elementoffset = elementoffset + data.width + 10 - local background = LUI.UIImage.new({ - bottomAnchor = true, - leftAnchor = true, - topAnchor = true, - rightAnchor = true, - material = luiglobals.RegisterMaterial("white"), - color = luiglobals.Colors.black, - alpha = 0.5 - }) + local background = LUI.UIImage.new({ + bottomAnchor = true, + leftAnchor = true, + topAnchor = true, + rightAnchor = true, + material = luiglobals.RegisterMaterial("white"), + color = luiglobals.Colors.black, + alpha = 0.5 + }) - local labelfont = CoD.TextSettings.FontBold110 - local textheight = 13 + local labelfont = CoD.TextSettings.FontBold110 - local label = LUI.UIText.new({ - left = 5, - top = 1, - font = labelfont.Font, - height = textheight, - leftAnchor = true, - topAnchor = true, - color = { - r = 0.8, - g = 0.8, - b = 0.8, - } - }) + local label = LUI.UIText.new({ + left = 5, + top = textoffsety, + font = labelfont.Font, + height = textheight, + leftAnchor = true, + topAnchor = true, + color = { + r = 0.8, + g = 0.8, + b = 0.8, + } + }) - label:setText(data.label) + label:setText(data.label) - local _, _, left = luiglobals.GetTextDimensions(data.label, labelfont.Font, textheight) - local value = LUI.UIText.new({ - left = left + 5, - top = 1, - height = textheight, - leftAnchor = true, - topAnchor = true, - color = { - r = 0.6, - g = 0.6, - b = 0.6, - } - }) - - value:addElement(LUI.UITimer.new(data.interval, "update")) - value:setText(data.getvalue()) - value:addEventHandler("update", function() - value:setText(data.getvalue()) - end) - - container:addElement(background) - container:addElement(label) - container:addElement(value) - - return container + local _, _, left = luiglobals.GetTextDimensions(data.label, labelfont.Font, textheight) + local value = LUI.UIText.new({ + left = left + 5, + top = textoffsety, + height = textheight, + leftAnchor = true, + topAnchor = true, + color = { + r = 0.6, + g = 0.6, + b = 0.6, + } + }) + + value:addElement(LUI.UITimer.new(data.interval, "update")) + value:setText(data.getvalue()) + value:addEventHandler("update", function() + value:setText(data.getvalue()) + end) + + container:addElement(background) + container:addElement(label) + container:addElement(value) + + return container end local updatehudvisibility = mphud.updateHudVisibility mphud.updateHudVisibility = function(a1, a2) - updatehudvisibility(a1, a2) + updatehudvisibility(a1, a2) - local root = Engine.GetLuiRoot() - local menus = root:AnyActiveMenusInStack() - local infobar = root.infobar + local root = Engine.GetLuiRoot() + local menus = root:AnyActiveMenusInStack() + local infobar = root.infobar - if (not infobar) then - return - end + if (not infobar) then + return + end - if (menus) then - infobar:animateToState("hud_off") - else - infobar:animateToState("hud_on") - end + if (menus) then + infobar:animateToState("hud_off") + else + infobar:animateToState("hud_on") + end end LUI.onmenuopen("mp_hud", function(hud) - if (Engine.InFrontend()) then - return - end + if (Engine.InFrontend()) then + return + end - local infobar = createinfobar() - local root = Engine.GetLuiRoot() - root.infobar = infobar - populateinfobar(infobar) + local infobar = createinfobar() + local root = Engine.GetLuiRoot() + root.infobar = infobar + populateinfobar(infobar) - root:registerEventHandler("update_hud_infobar_settings", function() - infobar:removeAllChildren() - populateinfobar(infobar) - end) + root:registerEventHandler("update_hud_infobar_settings", function() + infobar:removeAllChildren() + populateinfobar(infobar) + end) - root:processEvent({ - name = "update_hud_infobar_settings" - }) - - hud.static:addElement(infobar) + root:processEvent({ + name = "update_hud_infobar_settings" + }) + + hud.static:addElement(infobar) end) \ No newline at end of file diff --git a/data/ui_scripts/hud_info/settings.lua b/data/ui_scripts/hud_info/settings.lua index 4ce32564..18014d33 100644 --- a/data/ui_scripts/hud_info/settings.lua +++ b/data/ui_scripts/hud_info/settings.lua @@ -28,152 +28,152 @@ end pcdisplay.CreateOptions = function( menu ) LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@LUA_MENU_COLORBLIND_FILTER", - "@LUA_MENU_COLOR_BLIND_DESC", - LUI.Options.GetRenderColorBlindText, - LUI.Options.RenderColorBlindToggle, - LUI.Options.RenderColorBlindToggle - ) + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_COLORBLIND_FILTER", + "@LUA_MENU_COLOR_BLIND_DESC", + LUI.Options.GetRenderColorBlindText, + LUI.Options.RenderColorBlindToggle, + LUI.Options.RenderColorBlindToggle + ) - if Engine.IsMultiplayer() and Engine.GetDvarType( "cg_paintballFx" ) == luiglobals.DvarTypeTable.DvarBool then + if Engine.IsMultiplayer() and Engine.GetDvarType( "cg_paintballFx" ) == luiglobals.DvarTypeTable.DvarBool then LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@LUA_MENU_PAINTBALL", "@LUA_MENU_PAINTBALL_DESC", - LUI.Options.GetDvarEnableTextFunc("cg_paintballFx", false), - LUI.Options.ToggleDvarFunc("cg_paintballFx"), - LUI.Options.ToggleDvarFunc("cg_paintballFx") - ) + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_PAINTBALL", "@LUA_MENU_PAINTBALL_DESC", + LUI.Options.GetDvarEnableTextFunc("cg_paintballFx", false), + LUI.Options.ToggleDvarFunc("cg_paintballFx"), + LUI.Options.ToggleDvarFunc("cg_paintballFx") + ) end LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@LUA_MENU_BLOOD", - "@LUA_MENU_BLOOD_DESC", - LUI.Options.GetDvarEnableTextFunc("cg_blood", false), - LUI.Options.ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0)), - LUI.Options.ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0)) - ) + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_BLOOD", + "@LUA_MENU_BLOOD_DESC", + LUI.Options.GetDvarEnableTextFunc("cg_blood", false), + LUI.Options.ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0)), + LUI.Options.ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0)) + ) - if not Engine.IsMultiplayer() then + if not Engine.IsMultiplayer() then LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@LUA_MENU_CROSSHAIR", - "@LUA_MENU_CROSSHAIR_DESC", - LUI.Options.GetDvarEnableTextFunc("cg_drawCrosshairOption", false), - LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption"), - LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption") - ) + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_CROSSHAIR", + "@LUA_MENU_CROSSHAIR_DESC", + LUI.Options.GetDvarEnableTextFunc("cg_drawCrosshairOption", false), + LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption"), + LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption") + ) - LUI.Options.CreateOptionButton( - menu, - "cg_drawDamageFeedbackOption", - "@LUA_MENU_HIT_MARKER", - "@LUA_MENU_HIT_MARKER_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - } - ) + LUI.Options.CreateOptionButton( + menu, + "cg_drawDamageFeedbackOption", + "@LUA_MENU_HIT_MARKER", + "@LUA_MENU_HIT_MARKER_DESC", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + } + ) end if Engine.IsMultiplayer() then LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@MENU_DISPLAY_KILLSTREAK_COUNTER", - "@MENU_DISPLAY_KILLSTREAK_COUNTER_DESC", - pcdisplay.GetDisplayKillstreakCounterText, - pcdisplay.DisplayKillstreakCounterToggle, - pcdisplay.DisplayKillstreakCounterToggle - ) + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@MENU_DISPLAY_KILLSTREAK_COUNTER", + "@MENU_DISPLAY_KILLSTREAK_COUNTER_DESC", + pcdisplay.GetDisplayKillstreakCounterText, + pcdisplay.DisplayKillstreakCounterToggle, + pcdisplay.DisplayKillstreakCounterToggle + ) LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@MENU_DISPLAY_MEDAL_SPLASHES", - "@MENU_DISPLAY_MEDAL_SPLASHES_DESC", - pcdisplay.GetDisplayMedalSplashesText, - pcdisplay.DisplayMedalSplashesToggle, - pcdisplay.DisplayMedalSplashesToggle - ) + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@MENU_DISPLAY_MEDAL_SPLASHES", + "@MENU_DISPLAY_MEDAL_SPLASHES_DESC", + pcdisplay.GetDisplayMedalSplashesText, + pcdisplay.DisplayMedalSplashesToggle, + pcdisplay.DisplayMedalSplashesToggle + ) LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@MENU_DISPLAY_WEAPON_EMBLEMS", - "@MENU_DISPLAY_WEAPON_EMBLEMS_DESC", - pcdisplay.GetDisplayWeaponEmblemsText, - pcdisplay.DisplayWeaponEmblemsToggle, - pcdisplay.DisplayWeaponEmblemsToggle - ) + menu, + luiglobals.GenericButtonSettings.Variants.Select, + "@MENU_DISPLAY_WEAPON_EMBLEMS", + "@MENU_DISPLAY_WEAPON_EMBLEMS_DESC", + pcdisplay.GetDisplayWeaponEmblemsText, + pcdisplay.DisplayWeaponEmblemsToggle, + pcdisplay.DisplayWeaponEmblemsToggle + ) end - LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Common, - "@MENU_BRIGHTNESS", - "@MENU_BRIGHTNESS_DESC1", - nil, nil, nil, - pcdisplay.OpenBrightnessMenu, - nil, nil, nil - ) + LUI.Options.AddButtonOptionVariant( + menu, + luiglobals.GenericButtonSettings.Variants.Common, + "@MENU_BRIGHTNESS", + "@MENU_BRIGHTNESS_DESC1", + nil, nil, nil, + pcdisplay.OpenBrightnessMenu, + nil, nil, nil + ) - createdivider(menu, "TELEMETRY") + createdivider(menu, "TELEMETRY") - LUI.Options.CreateOptionButton( - menu, - "cg_infobar_ping", - "@LUA_MENU_LATENCY", - "@LUA_MENU_LATENCY_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - }, nil, nil, function(value) - Engine.SetDvarBool("cg_infobar_ping", value) - Engine.GetLuiRoot():processEvent({ - name = "update_hud_infobar_settings" - }) - end - ) + LUI.Options.CreateOptionButton( + menu, + "cg_infobar_ping", + "@LUA_MENU_LATENCY", + "@LUA_MENU_LATENCY_DESC", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + }, nil, nil, function(value) + Engine.SetDvarBool("cg_infobar_ping", value) + Engine.GetLuiRoot():processEvent({ + name = "update_hud_infobar_settings" + }) + end + ) - LUI.Options.CreateOptionButton( - menu, - "cg_infobar_fps", - "@LUA_MENU_FPS", - "@LUA_MENU_FPS_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - }, nil, nil, function(value) - Engine.SetDvarBool("cg_infobar_fps", value) - Engine.GetLuiRoot():processEvent({ - name = "update_hud_infobar_settings" - }) - end - ) + LUI.Options.CreateOptionButton( + menu, + "cg_infobar_fps", + "@LUA_MENU_FPS", + "@LUA_MENU_FPS_DESC", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + }, nil, nil, function(value) + Engine.SetDvarBool("cg_infobar_fps", value) + Engine.GetLuiRoot():processEvent({ + name = "update_hud_infobar_settings" + }) + end + ) LUI.Options.InitScrollingList(menu.list, nil) end From 9bb4380f4adcb806e7404f7d62e42c05e488c8ce Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sat, 5 Mar 2022 21:01:55 +0100 Subject: [PATCH 043/346] Small fix --- data/ui_scripts/server_list/lobby.lua | 4 +++- data/ui_scripts/server_list/serverlist.lua | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/data/ui_scripts/server_list/lobby.lua b/data/ui_scripts/server_list/lobby.lua index 348e95af..5f7029df 100644 --- a/data/ui_scripts/server_list/lobby.lua +++ b/data/ui_scripts/server_list/lobby.lua @@ -1,6 +1,8 @@ local Lobby = luiglobals.Lobby local MPLobbyOnline = LUI.mp_menus.MPLobbyOnline +game:addlocalizedstring("LUA_MENU_SERVERLIST", "SERVER LIST") + function LeaveLobby(f5_arg0) LeaveXboxLive() if Lobby.IsInPrivateParty() == false or Lobby.IsPrivatePartyHost() then @@ -17,7 +19,7 @@ function menu_xboxlive(f16_arg0, f16_arg1) menu:setClass(LUI.MPLobbyOnline) - local serverListButton = menu:AddButton("SERVER LIST", function (a1, a2) + local serverListButton = menu:AddButton("@LUA_MENU_SERVERLIST", function (a1, a2) LUI.FlowManager.RequestAddMenu(a1, "menu_systemlink_join", true, nil) end) serverListButton:setDisabledRefreshRate(500) diff --git a/data/ui_scripts/server_list/serverlist.lua b/data/ui_scripts/server_list/serverlist.lua index ca597cee..4eac68e2 100644 --- a/data/ui_scripts/server_list/serverlist.lua +++ b/data/ui_scripts/server_list/serverlist.lua @@ -5,6 +5,9 @@ if (not SystemLinkJoinMenu) then return end +game:addlocalizedstring("MENU_NUMPLAYERS", "Players") +game:addlocalizedstring("MENU_PING", "Ping") + local offsets = { 10, 500, @@ -16,9 +19,9 @@ local offsets = { local columns = { "@MENU_HOST_NAME", "@MENU_MAP", - "Players", + "@MENU_NUMPLAYERS", "@MENU_TYPE1", - "Ping", + "@MENU_PING", } SystemLinkJoinMenu.AddHeaderButton = function(menu, f12_arg1, width) From de1a3d4a38f207b208dcf5076d472148888aa9d7 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sat, 5 Mar 2022 23:23:28 +0100 Subject: [PATCH 044/346] Update function_tables.cpp --- src/client/game/scripting/function_tables.cpp | 466 +++++++++--------- 1 file changed, 233 insertions(+), 233 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 9a70a9dd..ef116e79 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -9,179 +9,179 @@ namespace scripting { std::unordered_map function_map = { - {"_func_001", 0x001}, // SP 0x14029D940 MP 0x140368EA0 + {"precacheturret", 0x001}, // SP 0x14029D940 MP 0x140368EA0 {"getweaponarray", 0x002}, // SP 0x14028F750 MP 0x140357B80 - {"_func_003", 0x003}, // SP 0x1405D92F0 MP 0x1403668A0 - {"_func_004", 0x004}, // SP 0x1402ACD70 MP 0x000000000 - {"_func_005", 0x005}, // SP 0x1402ADB70 MP 0x000000000 - {"_func_006", 0x006}, // SP 0x1402A8E20 MP 0x000000000 - {"_func_007", 0x007}, // SP 0x1402A8B20 MP 0x000000000 - {"_func_008", 0x008}, // SP 0x1402A8B40 MP 0x000000000 - {"_func_009", 0x009}, // SP 0x1402A8BC0 MP 0x000000000 - {"_func_00A", 0x00A}, // SP 0x1402A8B60 MP 0x000000000 - {"_func_00B", 0x00B}, // SP 0x1402A8960 MP 0x000000000 - {"_func_00C", 0x00C}, // SP 0x1402ADBE0 MP 0x000000000 - {"_func_00D", 0x00D}, // SP 0x1402ADC60 MP 0x000000000 - {"_func_00E", 0x00E}, // SP 0x1402ADC90 MP 0x000000000 - {"_func_00F", 0x00F}, // SP 0x1405D92F0 MP 0x1403669E0 - {"_func_010", 0x010}, // SP 0x14029AF60 MP 0x1403669F0 - {"_func_011", 0x011}, // SP 0x14029AF60 MP 0x140366D40 - {"_func_012", 0x012}, // SP 0x1405D92F0 MP 0x140367400 - {"_func_013", 0x013}, // SP 0x1405D92F0 MP 0x140367520 - {"_func_014", 0x014}, // SP 0x1405D92F0 MP 0x140367530 - {"_func_015", 0x015}, // SP 0x1405D92F0 MP 0x1403675E0 - {"_func_016", 0x016}, // SP 0x1405D92F0 MP 0x140367660 - {"_func_017", 0x017}, // SP 0x1405D92F0 MP 0x140367890 + {"createprintchannel", 0x003}, // SP 0x1405D92F0 MP 0x1403668A0 nullsub + {"updategamerprofileall", 0x004}, // SP 0x1402ACD70 MP 0x000000000 + {"clearlocalizedstrings", 0x005}, // SP 0x1402ADB70 MP 0x000000000 + {"setphysicsgravitydir", 0x006}, // SP 0x1402A8E20 MP 0x000000000 + {"gettimescale", 0x007}, // SP 0x1402A8B20 MP 0x000000000 + {"settimescale", 0x008}, // SP 0x1402A8B40 MP 0x000000000 + {"setslowmotionview", 0x009}, // SP 0x1402A8BC0 MP 0x000000000 + {"teleportscene", 0x00A}, // SP 0x1402A8B60 MP 0x000000000 + {"forcesharedammo", 0x00B}, // SP 0x1402A8960 MP 0x000000000 + {"refreshhudcompass", 0x00C}, // SP 0x1402ADBE0 MP 0x000000000 + {"refreshhudammocounter", 0x00D}, // SP 0x1402ADC60 MP 0x000000000 + {"notifyoncommand", 0x00E}, // SP 0x1402ADC90 MP 0x000000000 + {"setprintchannel", 0x00F}, // SP 0x1405D92F0 MP 0x1403669E0 nullsub + {"print", 0x010}, // SP 0x14029AF60 MP 0x1403669F0 ^ + {"println", 0x011}, // SP 0x14029AF60 MP 0x140366D40 ^ + {"print3d", 0x012}, // SP 0x1405D92F0 MP 0x140367400 ^ + {"line", 0x013}, // SP 0x1405D92F0 MP 0x140367520 ^ + {"box", 0x014}, // SP 0x1405D92F0 MP 0x140367530 ^ + {"orientedbox", 0x015}, // SP 0x1405D92F0 MP 0x1403675E0 ^ + {"sphere", 0x016}, // SP 0x1405D92F0 MP 0x140367660 ^ + {"cylinder", 0x017}, // SP 0x1405D92F0 MP 0x140367890 ^ {"spawnturret", 0x018}, // SP 0x14029D650 MP 0x140368B10 {"canspawnturret", 0x019}, // SP 0x14029D870 MP 0x140368E80 - {"_func_01A", 0x01A}, // SP 0x14029C9B0 MP 0x1403678A0 - {"_func_01B", 0x01B}, // SP 0x1402AB640 MP 0x000000000 - {"_func_01C", 0x01C}, // SP 0x1402AB670 MP 0x000000000 - {"_func_01D", 0x01D}, // SP 0x1402AB7A0 MP 0x000000000 - {"_func_01E", 0x01E}, // SP 0x1402AB960 MP 0x000000000 + {"assert", 0x01A}, // SP 0x14029C9B0 MP 0x1403678A0 + {"pausecinematicingame", 0x01B}, // SP 0x1402AB640 MP 0x000000000 + {"drawcompassfriendlies", 0x01C}, // SP 0x1402AB670 MP 0x000000000 + {"bulletspread", 0x01D}, // SP 0x1402AB7A0 MP 0x000000000 + {"bullettracer", 0x01E}, // SP 0x1402AB960 MP 0x000000000 {"badplace_delete", 0x01F}, // SP 0x14028F340 MP 0x140358600 {"badplace_cylinder", 0x020}, // SP 0x14028F4B0 MP 0x140358C50 {"badplace_arc", 0x021}, // SP 0x14028F830 MP 0x140359110 {"badplace_brush", 0x022}, // SP 0x14028FF10 MP 0x140359CB0 - {"_func_023", 0x023}, // SP 0x1402AC9D0 MP 0x000000000 - {"_func_024", 0x024}, // SP 0x1402CC640 MP 0x000000000 - {"_func_025", 0x025}, // SP 0x1402CC6E0 MP 0x000000000 - {"_func_026", 0x026}, // SP 0x1402CC570 MP 0x000000000 - {"_func_027", 0x027}, // SP 0x1402CC430 MP 0x000000000 - {"_func_02A", 0x02A}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_02B", 0x02B}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_02C", 0x02C}, // SP 0x1402ACD10 MP 0x000000000 - {"_func_02D", 0x02D}, // SP 0x14029C9B0 MP 0x140367950 - {"_func_02E", 0x02E}, // SP 0x14029CAC0 MP 0x140367980 + {"clearallcorpses", 0x023}, // SP 0x1402AC9D0 MP 0x000000000 + {"setturretnode", 0x024}, // SP 0x1402CC640 MP 0x000000000 + {"unsetturretnode", 0x025}, // SP 0x1402CC6E0 MP 0x000000000 + {"setnodepriority", 0x026}, // SP 0x1402CC570 MP 0x000000000 + {"isnodeoccupied", 0x027}, // SP 0x1402CC430 MP 0x000000000 + {"setdebugorigin", 0x02A}, // SP 0x1405D92F0 MP 0x000000000 + {"setdebugangles", 0x02B}, // SP 0x1405D92F0 MP 0x000000000 + {"updategamerprofile", 0x02C}, // SP 0x1402ACD10 MP 0x000000000 + {"assertex", 0x02D}, // SP 0x14029C9B0 MP 0x140367950 + {"assertmsg", 0x02E}, // SP 0x14029CAC0 MP 0x140367980 {"isdefined", 0x02F}, // SP 0x14029D000 MP 0x140368520 {"isvalidmissile", 0x030}, // SP 0x14029D3E0 MP 0x140368A70 - {"_func_031", 0x031}, // SP 0x14029D630 MP 0x140368D30 - {"_func_032", 0x032}, // SP 0x14029E0A0 MP 0x14036A580 - {"_func_033", 0x033}, // SP 0x14029E220 MP 0x14036A7C0 - {"setdynamicdvar", 0x034}, // SP 0x14029EB20 MP 0x14036AE70 - {"_func_035", 0x035}, // SP 0x000000000 MP 0x14036B600 - {"_func_036", 0x036}, // SP 0x14029F8F0 MP 0x14036BB60 - {"setdvar", 0x037}, // SP 0x14029F1C0 MP 0x14036B7F0 - {"_func_038", 0x038}, // SP 0x14029F8F0 MP 0x14036C070 + {"isstring", 0x031}, // SP 0x14029D630 MP 0x140368D30 + {"setomnvar", 0x032}, // SP 0x14029E0A0 MP 0x14036A580 + {"getomnvar", 0x033}, // SP 0x14029E220 MP 0x14036A7C0 + {"setdvar", 0x034}, // SP 0x14029EB20 MP 0x14036AE70 + {"setdynamicdvar", 0x035}, // SP 0x000000000 MP 0x14036B600 + {"setdvarifuninitialized", 0x036}, // SP 0x14029F8F0 MP 0x14036BB60 + {"setdevdvar", 0x037}, // SP 0x14029F1C0 MP 0x14036B7F0 + {"setdevdvarifuninitialized", 0x038}, // SP 0x14029F8F0 MP 0x14036C070 {"getdvar", 0x039}, // SP 0x14029FE30 MP 0x14036C350 {"getdvarint", 0x03A}, // SP 0x1402A0270 MP 0x14036C7B0 {"getdvarfloat", 0x03B}, // SP 0x1402A0810 MP 0x14036CDD0 {"getdvarvector", 0x03C}, // SP 0x1402A10E0 MP 0x14036D190 - {"_func_03D", 0x03D}, // SP 0x1402A1A50 MP 0x14036DB40 - {"_func_03E", 0x03E}, // SP 0x1402A1A60 MP 0x14036DD80 - {"_func_03F", 0x03F}, // SP 0x1402A1AC0 MP 0x14036DDA0 + {"gettime", 0x03D}, // SP 0x1402A1A50 MP 0x14036DB40 + {"gettimeutc", 0x03E}, // SP 0x1402A1A60 MP 0x14036DD80 + {"getradiometricunit", 0x03F}, // SP 0x1402A1AC0 MP 0x14036DDA0 {"getentbynum", 0x040}, // SP 0x1402A1C50 MP 0x14036DF50 - {"_func_041", 0x041}, // SP 0x1402A1D10 MP 0x000000000 - {"_func_042", 0x042}, // SP 0x1402A1D20 MP 0x000000000 - {"_func_043", 0x043}, // SP 0x1402A1D30 MP 0x14036E110 + {"getscreenwidth", 0x041}, // SP 0x1402A1D10 MP 0x000000000 + {"getscreenheight", 0x042}, // SP 0x1402A1D20 MP 0x000000000 + {"getweaponmodel", 0x043}, // SP 0x1402A1D30 MP 0x14036E110 {"_func_044", 0x044}, // SP 0x1402ABBE0 MP 0x000000000 {"_func_045", 0x045}, // SP 0x1402ABCF0 MP 0x000000000 {"_func_046", 0x046}, // SP 0x1402ABD30 MP 0x000000000 - {"_func_047", 0x047}, // SP 0x1402ABD90 MP 0x1403775E0 - {"_func_048", 0x048}, // SP 0x1402ABE60 MP 0x140377840 - {"_func_049", 0x049}, // SP 0x1402ABF90 MP 0x000000000 - {"_func_04A", 0x04A}, // SP 0x1402ABFC0 MP 0x000000000 - {"_func_04B", 0x04B}, // SP 0x1402AC0E0 MP 0x000000000 - {"_func_04C", 0x04C}, // SP 0x1402AC210 MP 0x000000000 - {"_func_04D", 0x04D}, // SP 0x1402AC520 MP 0x000000000 - {"_func_04E", 0x04E}, // SP 0x1402AC6F0 MP 0x000000000 - {"_func_04F", 0x04F}, // SP 0x1402AC720 MP 0x000000000 - {"_func_050", 0x050}, // SP 0x1402AC740 MP 0x000000000 - {"_func_051", 0x051}, // SP 0x1402AC760 MP 0x000000000 - {"_func_052", 0x052}, // SP 0x1402AC780 MP 0x000000000 - {"_func_053", 0x053}, // SP 0x1402AC830 MP 0x000000000 - {"_func_054", 0x054}, // SP 0x1402AD6E0 MP 0x000000000 - {"_func_055", 0x055}, // SP 0x1402AAEC0 MP 0x000000000 - {"_func_056", 0x056}, // SP 0x1402AAF60 MP 0x000000000 - {"_func_057", 0x057}, // SP 0x1402AB040 MP 0x000000000 - {"_func_058", 0x058}, // SP 0x1402AB060 MP 0x000000000 - {"_func_059", 0x059}, // SP 0x1402AB140 MP 0x000000000 - {"_func_05A", 0x05A}, // SP 0x1402AB1E0 MP 0x000000000 - {"_func_05B", 0x05B}, // SP 0x1402AB2A0 MP 0x000000000 - {"_func_05C", 0x05C}, // SP 0x1402AB420 MP 0x000000000 - {"_func_05D", 0x05D}, // SP 0x1402AB4A0 MP 0x000000000 - {"_func_05E", 0x05E}, // SP 0x1402AB620 MP 0x000000000 - {"_func_05F", 0x05F}, // SP 0x1402A2410 MP 0x14036E740 - {"_func_060", 0x060}, // SP 0x1402A2910 MP 0x14036ED60 - {"_func_061", 0x061}, // SP 0x1402A3170 MP 0x14036F3E0 - {"_func_062", 0x062}, // SP 0x1402A34D0 MP 0x140357CA0 - {"getweaponreticlename", 0x063}, // SP 0x14028DEA0 MP 0x140358890 - {"_func_064", 0x064}, // SP 0x14028E0B0 MP 0x140358B80 + {"setsunlight", 0x047}, // SP 0x1402ABD90 MP 0x1403775E0 + {"resetsunlight", 0x048}, // SP 0x1402ABE60 MP 0x140377840 + {"getmapsundirection", 0x049}, // SP 0x1402ABF90 MP 0x000000000 + {"getmapsunangles", 0x04A}, // SP 0x1402ABFC0 MP 0x000000000 + {"setsundirection", 0x04B}, // SP 0x1402AC0E0 MP 0x000000000 + {"lerpsundirection", 0x04C}, // SP 0x1402AC210 MP 0x000000000 + {"lerpsunangles", 0x04D}, // SP 0x1402AC520 MP 0x000000000 + {"resetsundirection", 0x04E}, // SP 0x1402AC6F0 MP 0x000000000 + {"enableforcedsunshadows", 0x04F}, // SP 0x1402AC720 MP 0x000000000 + {"enableforcednosunshadows", 0x050}, // SP 0x1402AC740 MP 0x000000000 + {"disableforcedsunshadows", 0x051}, // SP 0x1402AC760 MP 0x000000000 + {"enableouterspacemodellighting", 0x052}, // SP 0x1402AC780 MP 0x000000000 + {"disableouterspacemodellighting", 0x053}, // SP 0x1402AC830 MP 0x000000000 + {"remapstage", 0x054}, // SP 0x1402AD6E0 MP 0x000000000 + {"changelevel", 0x055}, // SP 0x1402AAEC0 MP 0x000000000 + {"missionsuccess", 0x056}, // SP 0x1402AAF60 MP 0x000000000 + {"missionfailed", 0x057}, // SP 0x1402AB040 MP 0x000000000 + {"cinematic", 0x058}, // SP 0x1402AB060 MP 0x000000000 + {"cinematicingame", 0x059}, // SP 0x1402AB140 MP 0x000000000 + {"cinematicingamesync", 0x05A}, // SP 0x1402AB1E0 MP 0x000000000 + {"cinematicingameloop", 0x05B}, // SP 0x1402AB2A0 MP 0x000000000 + {"cinematicingameloopresident", 0x05C}, // SP 0x1402AB420 MP 0x000000000 + {"iscinematicplaying", 0x05D}, // SP 0x1402AB4A0 MP 0x000000000 + {"stopcinematicingame", 0x05E}, // SP 0x1402AB620 MP 0x000000000 + {"getweapondisplayname", 0x05F}, // SP 0x1402A2410 MP 0x14036E740 + {"getweaponbasename", 0x060}, // SP 0x1402A2910 MP 0x14036ED60 + {"getweaponattachments", 0x061}, // SP 0x1402A3170 MP 0x14036F3E0 + {"getweaponattachmentdisplaynames", 0x062}, // SP 0x1402A34D0 MP 0x140357CA0 + {"getweaponcamoname", 0x063}, // SP 0x14028DEA0 MP 0x140358890 + {"getweaponreticlename", 0x064}, // SP 0x14028E0B0 MP 0x140358B80 {"getanimlength", 0x065}, // SP 0x14028FB80 MP 0x14035AB80 {"animhasnotetrack", 0x066}, // SP 0x14028FD60 MP 0x14035B110 {"getnotetracktimes", 0x067}, // SP 0x14028FDC0 MP 0x14035B220 {"spawn", 0x068}, // SP 0x14029D0C0 MP 0x140368410 {"spawnloopsound", 0x069}, // SP 0x14029D0C0 MP 0x140368410 - {"_func_06A", 0x06A}, // SP 0x140444BB0 MP 0x14036AF90 - {"_func_06B", 0x06B}, // SP 0x14029E950 MP 0x140366EF0 - {"_func_06C", 0x06C}, // SP 0x1402BBCA0 MP 0x000000000 - {"_func_06D", 0x06D}, // SP 0x1402BB830 MP 0x000000000 - {"_func_06E", 0x06E}, // SP 0x1402BB990 MP 0x000000000 - {"_func_06F", 0x06F}, // SP 0x14025D860 MP 0x140375D40 - {"_func_070", 0x070}, // SP 0x14025D770 MP 0x140375F10 - {"_func_071", 0x071}, // SP 0x14025D630 MP 0x000000000 - {"_func_072", 0x072}, // SP 0x1402AB510 MP 0x000000000 - {"_func_073", 0x073}, // SP 0x1402981B0 MP 0x140364BC0 - {"_func_074", 0x074}, // SP 0x1402AFD80 MP 0x000000000 - {"_func_075", 0x075}, // SP 0x1402AFEA0 MP 0x000000000 - {"_func_076", 0x076}, // SP 0x1402A78A0 MP 0x000000000 - {"_func_077", 0x077}, // SP 0x1402A79D0 MP 0x000000000 - {"_func_078", 0x078}, // SP 0x14029E170 MP 0x140367970 - {"_func_079", 0x079}, // SP 0x14029E210 MP 0x140367990 - {"_func_07A", 0x07A}, // SP 0x14029E2D0 MP 0x140367D70 - {"_func_07B", 0x07B}, // SP 0x14029E320 MP 0x140367F30 - {"_func_07C", 0x07C}, // SP 0x14029E330 MP 0x140367F40 - {"_func_07D", 0x07D}, // SP 0x14029E730 MP 0x140367FA0 - {"_func_07E", 0x07E}, // SP 0x1402A7BF0 MP 0x000000000 - {"_func_07F", 0x07F}, // SP 0x1402A8BB0 MP 0x000000000 - {"_func_080", 0x080}, // SP 0x1402A7A80 MP 0x000000000 - {"_func_081", 0x081}, // SP 0x1402AAE30 MP 0x000000000 - {"_func_083", 0x083}, // SP 0x1402AAE50 MP 0x000000000 - {"_func_084", 0x084}, // SP 0x1402AAEA0 MP 0x000000000 - {"_func_085", 0x085}, // SP 0x1402A8CB0 MP 0x000000000 - {"_func_086", 0x086}, // SP 0x1402A9990 MP 0x000000000 - {"_func_087", 0x087}, // SP 0x1402A99B0 MP 0x000000000 - {"_func_088", 0x088}, // SP 0x1402A9100 MP 0x000000000 - {"_func_089", 0x089}, // SP 0x1402A99D0 MP 0x000000000 - {"_func_08A", 0x08A}, // SP 0x1402A9A70 MP 0x000000000 - {"_func_08B", 0x08B}, // SP 0x1402AB690 MP 0x000000000 - {"_func_08C", 0x08C}, // SP 0x1402ABB90 MP 0x000000000 + {"spawnloopingsound", 0x06A}, // SP 0x140444BB0 MP 0x14036AF90 + {"bullettrace", 0x06B}, // SP 0x14029E950 MP 0x140366EF0 + {"target_setmaxsize", 0x06C}, // SP 0x1402BBCA0 MP 0x000000000 + {"target_setcolor", 0x06D}, // SP 0x1402BB830 MP 0x000000000 + {"target_setdelay", 0x06E}, // SP 0x1402BB990 MP 0x000000000 + {"getstartorigin", 0x06F}, // SP 0x14025D860 MP 0x140375D40 + {"getstartangles", 0x070}, // SP 0x14025D770 MP 0x140375F10 + {"getcycleoriginoffset", 0x071}, // SP 0x14025D630 MP 0x000000000 + {"magicgrenade", 0x072}, // SP 0x1402AB510 MP 0x000000000 + {"magicgrenademanual", 0x073}, // SP 0x1402981B0 MP 0x140364BC0 + {"setblur", 0x074}, // SP 0x1402AFD80 MP 0x000000000 + {"musicplay", 0x075}, // SP 0x1402AFEA0 MP 0x000000000 + {"musicstop", 0x076}, // SP 0x1402A78A0 MP 0x000000000 + {"soundfade", 0x077}, // SP 0x1402A79D0 MP 0x000000000 + {"addsoundsubmix", 0x078}, // SP 0x14029E170 MP 0x140367970 + {"clearsoundsubmix", 0x079}, // SP 0x14029E210 MP 0x140367990 + {"clearallsubmixes", 0x07A}, // SP 0x14029E2D0 MP 0x140367D70 + {"blendsoundsubmix", 0x07B}, // SP 0x14029E320 MP 0x140367F30 + {"makesoundsubmixsticky", 0x07C}, // SP 0x14029E330 MP 0x140367F40 + {"makesoundsubmixunsticky", 0x07D}, // SP 0x14029E730 MP 0x140367FA0 + {"soundsettimescalefactor", 0x07E}, // SP 0x1402A7BF0 MP 0x000000000 + {"soundresettimescale", 0x07F}, // SP 0x1402A8BB0 MP 0x000000000 + {"levelsoundfade", 0x080}, // SP 0x1402A7A80 MP 0x000000000 + {"precachenightvisioncodeassets", 0x081}, // SP 0x1402AAE30 MP 0x000000000 + {"precachedigitaldistortcodeassets", 0x083}, // SP 0x1402AAE50 MP 0x000000000 + {"precacheminimapsentrycodeassets", 0x084}, // SP 0x1402AAEA0 MP 0x000000000 + {"savegame", 0x085}, // SP 0x1402A8CB0 MP 0x000000000 + {"issavesuccessful", 0x086}, // SP 0x1402A9990 MP 0x000000000 + {"issaverecentlyloaded", 0x087}, // SP 0x1402A99B0 MP 0x000000000 + {"savegamenocommit", 0x088}, // SP 0x1402A9100 MP 0x000000000 + {"commitsave", 0x089}, // SP 0x1402A99D0 MP 0x000000000 + {"commitwouldbevalid", 0x08A}, // SP 0x1402A9A70 MP 0x000000000 + {"getfxvisibility", 0x08B}, // SP 0x1402AB690 MP 0x000000000 + {"setculldist", 0x08C}, // SP 0x1402ABB90 MP 0x000000000 {"bullettracepassed", 0x08D}, // SP 0x14029F480 MP 0x140367410 - {"_func_08E", 0x08E}, // SP 0x14029F7A0 MP 0x140367670 - {"_func_08F", 0x08F}, // SP 0x14029FF90 MP 0x140367E20 - {"_func_090", 0x090}, // SP 0x1402A0360 MP 0x140368180 - {"_func_091", 0x091}, // SP 0x1402A2670 MP 0x14036A300 - {"getangledelta", 0x092}, // SP 0x14028F3D0 MP 0x14036E210 - {"getangledelta3d", 0x093}, // SP 0x14028FA60 MP 0x14036E910 + {"sighttracepassed", 0x08E}, // SP 0x14029F7A0 MP 0x140367670 + {"physicstrace", 0x08F}, // SP 0x14029FF90 MP 0x140367E20 + {"playerphysicstrace", 0x090}, // SP 0x1402A0360 MP 0x140368180 + {"getgroundposition", 0x091}, // SP 0x1402A2670 MP 0x14036A300 + {"getmovedelta", 0x092}, // SP 0x14028F3D0 MP 0x14036E210 + {"getangledelta", 0x093}, // SP 0x14028FA60 MP 0x14036E910 {"getnorthyaw", 0x094}, // SP 0x1402903E0 MP 0x140357C50 - {"_func_095", 0x095}, // SP 0x1402A7970 MP 0x000000000 - {"_func_096", 0x096}, // SP 0x1402A7A50 MP 0x000000000 - {"_func_097", 0x097}, // SP 0x1402A9B20 MP 0x000000000 - {"_func_098", 0x098}, // SP 0x1402A9B70 MP 0x000000000 - {"_func_099", 0x099}, // SP 0x1402A9AE0 MP 0x000000000 - {"_func_09A", 0x09A}, // SP 0x1402AE4D0 MP 0x000000000 - {"_func_09B", 0x09B}, // SP 0x1402BB040 MP 0x000000000 - {"_func_09C", 0x09C}, // SP 0x1402BB410 MP 0x000000000 - {"_func_09D", 0x09D}, // SP 0x1402BB6F0 MP 0x000000000 - {"_func_09E", 0x09E}, // SP 0x1402BB6B0 MP 0x000000000 - {"_func_09F", 0x09F}, // SP 0x1402BC260 MP 0x000000000 - {"_func_0A0", 0x0A0}, // SP 0x1402BBF00 MP 0x000000000 - {"_func_0A1", 0x0A1}, // SP 0x1402BB590 MP 0x000000000 - {"_func_0A2", 0x0A2}, // SP 0x1402BB520 MP 0x000000000 - {"_func_0A3", 0x0A3}, // SP 0x1402BC390 MP 0x000000000 - {"_func_0A4", 0x0A4}, // SP 0x1402BB060 MP 0x000000000 - {"_func_0A5", 0x0A5}, // SP 0x1402BB4A0 MP 0x000000000 - {"_func_0A6", 0x0A6}, // SP 0x1402BB630 MP 0x000000000 - {"_func_0A7", 0x0A7}, // SP 0x1402BB710 MP 0x000000000 - {"_func_0A8", 0x0A8}, // SP 0x1402BBB80 MP 0x000000000 - {"_func_0A9", 0x0A9}, // SP 0x1402BB510 MP 0x000000000 - {"_func_0AA", 0x0AA}, // SP 0x1402BC380 MP 0x000000000 - {"_func_0AB", 0x0AB}, // SP 0x1402BC140 MP 0x000000000 - {"_func_0AC", 0x0AC}, // SP 0x1402BB090 MP 0x000000000 - {"_func_0AD", 0x0AD}, // SP 0x1402BB2C0 MP 0x000000000 - {"_func_0AE", 0x0AE}, // SP 0x1402BB1C0 MP 0x000000000 - {"_func_0AF", 0x0AF}, // SP 0x1402BBDB0 MP 0x000000000 - {"_func_0B0", 0x0B0}, // SP 0x140290420 MP 0x140357E90 + {"getcommandfromkey", 0x095}, // SP 0x1402A7970 MP 0x000000000 + {"getsticksconfig", 0x096}, // SP 0x1402A7A50 MP 0x000000000 + {"weaponfightdist", 0x097}, // SP 0x1402A9B20 MP 0x000000000 + {"weaponmaxdist", 0x098}, // SP 0x1402A9B70 MP 0x000000000 + {"isturretactive", 0x099}, // SP 0x1402A9AE0 MP 0x000000000 + {"getstarttime", 0x09A}, // SP 0x1402AE4D0 MP 0x000000000 + {"target_alloc", 0x09B}, // SP 0x1402BB040 MP 0x000000000 + {"target_flush", 0x09C}, // SP 0x1402BB410 MP 0x000000000 + {"target_set", 0x09D}, // SP 0x1402BB6F0 MP 0x000000000 + {"target_remove", 0x09E}, // SP 0x1402BB6B0 MP 0x000000000 + {"target_setshader", 0x09F}, // SP 0x1402BC260 MP 0x000000000 + {"target_setoffscreenshader", 0x0A0}, // SP 0x1402BBF00 MP 0x000000000 + {"target_isinrect", 0x0A1}, // SP 0x1402BB590 MP 0x000000000 + {"target_isincircle", 0x0A2}, // SP 0x1402BB520 MP 0x000000000 + {"target_startreticlelockon", 0x0A3}, // SP 0x1402BC390 MP 0x000000000 + {"target_clearreticlelockon", 0x0A4}, // SP 0x1402BB060 MP 0x000000000 + {"target_getarray", 0x0A5}, // SP 0x1402BB4A0 MP 0x000000000 + {"target_istarget", 0x0A6}, // SP 0x1402BB630 MP 0x000000000 + {"target_setattackmode", 0x0A7}, // SP 0x1402BB710 MP 0x000000000 + {"target_setjavelinonly", 0x0A8}, // SP 0x1402BBB80 MP 0x000000000 + {"target_hidefromplayer", 0x0A9}, // SP 0x1402BB510 MP 0x000000000 + {"target_showtoplayer", 0x0AA}, // SP 0x1402BC380 MP 0x000000000 + {"target_setscaledrendermode", 0x0AB}, // SP 0x1402BC140 MP 0x000000000 + {"target_drawcornersonly", 0x0AC}, // SP 0x1402BB090 MP 0x000000000 + {"target_drawsquare", 0x0AD}, // SP 0x1402BB2C0 MP 0x000000000 + {"target_drawsingle", 0x0AE}, // SP 0x1402BB1C0 MP 0x000000000 + {"target_setminsize", 0x0AF}, // SP 0x1402BBDB0 MP 0x000000000 + {"setnorthyaw", 0x0B0}, // SP 0x140290420 MP 0x140357E90 {"setslowmotion", 0x0B1}, // SP 0x14029BC60 MP 0x140365480 {"randomint", 0x0B2}, // SP 0x1402A2ED0 MP 0x14036A770 {"randomfloat", 0x0B3}, // SP 0x1402A3140 MP 0x14036A9E0 @@ -196,41 +196,41 @@ namespace scripting {"int", 0x0BC}, // SP 0x14028DAE0 MP 0x14036BBF0 {"float", 0x0BD}, // SP 0x14028DE30 MP 0x14036C000 {"abs", 0x0BE}, // SP 0x14028DFC0 MP 0x14036C320 - {"_func_0BF", 0x0BF}, // SP 0x14028DFF0 MP 0x14036C580 - {"_func_0C0", 0x0C0}, // SP 0x1402B7A30 MP 0x000000000 - {"_func_0C1", 0x0C1}, // SP 0x1402B7B50 MP 0x000000000 - {"_func_0C2", 0x0C2}, // SP 0x1402B7BF0 MP 0x000000000 + {"min", 0x0BF}, // SP 0x14028DFF0 MP 0x14036C580 + {"objective_additionalcurrent", 0x0C0}, // SP 0x1402B7A30 MP 0x000000000 + {"objective_ring", 0x0C1}, // SP 0x1402B7B50 MP 0x000000000 + {"objective_setpointertextoverride", 0x0C2}, // SP 0x1402B7BF0 MP 0x000000000 {"getnode", 0x0C3}, // SP 0x1402CBED0 MP 0x14031FA00 {"getnodearray", 0x0C4}, // SP 0x1402CBFE0 MP 0x14031FB10 {"getallnodes", 0x0C5}, // SP 0x1402CBCD0 MP 0x14031F7E0 - {"_func_0C6", 0x0C6}, // SP 0x1402CC0F0 MP 0x14031FCC0 - {"_func_0C7", 0x0C7}, // SP 0x1402CC100 MP 0x14031FCD0 - {"_func_0C8", 0x0C8}, // SP 0x1402CBD20 MP 0x14031F830 - {"_func_0C9", 0x0C9}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_0CA", 0x0CA}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_0CB", 0x0CB}, // SP 0x140468CF0 MP 0x000000000 - {"_func_0CC", 0x0CC}, // SP 0x140468DD0 MP 0x000000000 - {"_func_0CD", 0x0CD}, // SP 0x140468CA0 MP 0x000000000 + {"getnodesinradius", 0x0C6}, // SP 0x1402CC0F0 MP 0x14031FCC0 + {"getnodesinradiussorted", 0x0C7}, // SP 0x1402CC100 MP 0x14031FCD0 + {"getclosestnodeinsight", 0x0C8}, // SP 0x1402CBD20 MP 0x14031F830 + {"getreflectionlocs", 0x0C9}, // SP 0x1405D92F0 MP 0x000000000 + {"getreflectionreferencelocs", 0x0CA}, // SP 0x1405D92F0 MP 0x000000000 + {"getvehicletracksegment", 0x0CB}, // SP 0x140468CF0 MP 0x000000000 + {"getvehicletracksegmentarray", 0x0CC}, // SP 0x140468DD0 MP 0x000000000 + {"getallvehicletracksegments", 0x0CD}, // SP 0x140468CA0 MP 0x000000000 {"isarray", 0x0CE}, // SP 0x140291BF0 MP 0x14035E620 {"isai", 0x0CF}, // SP 0x1402ADC10 MP 0x140377460 {"getindexforluincstring", 0x0D0}, // SP 0x14029DB50 MP 0x140369C50 {"issentient", 0x0D1}, // SP 0x14029D7D0 MP 0x140368DA0 - {"_func_0D2", 0x0D2}, // SP 0x1402ADD90 MP 0x000000000 - {"_func_0D3", 0x0D3}, // SP 0x1402ADED0 MP 0x000000000 - {"_func_0D4", 0x0D4}, // SP 0x1402ADF60 MP 0x000000000 - {"_func_0D5", 0x0D5}, // SP 0x1402ADFD0 MP 0x000000000 - {"_func_0D6", 0x0D6}, // SP 0x1402AE020 MP 0x000000000 - {"_func_0D7", 0x0D7}, // SP 0x1402AE4E0 MP 0x000000000 - {"_func_0D8", 0x0D8}, // SP 0x1402AE4F0 MP 0x000000000 - {"_func_0D9", 0x0D9}, // SP 0x1402AE7A0 MP 0x000000000 - {"_func_0DA", 0x0DA}, // SP 0x1402AF980 MP 0x000000000 - {"_func_0DB", 0x0DB}, // SP 0x1402AFBD0 MP 0x000000000 - {"_func_0DC", 0x0DC}, // SP 0x1402AFB20 MP 0x000000000 - {"_func_0DD", 0x0DD}, // SP 0x1402AFCE0 MP 0x000000000 - {"_func_0DE", 0x0DE}, // SP 0x1402AFE20 MP 0x000000000 - {"_func_0DF", 0x0DF}, // SP 0x14029CAC0 MP 0x000000000 - {"_func_0E0", 0x0E0}, // SP 0x1402A7830 MP 0x000000000 - {"_func_0E1", 0x0E1}, // SP 0x14028E170 MP 0x14036C720 + {"isgodmode", 0x0D2}, // SP 0x1402ADD90 MP 0x000000000 + {"getdebugdvar", 0x0D3}, // SP 0x1402ADED0 MP 0x000000000 + {"getdebugdvarint", 0x0D4}, // SP 0x1402ADF60 MP 0x000000000 + {"getdebugdvarfloat", 0x0D5}, // SP 0x1402ADFD0 MP 0x000000000 + {"setsaveddvar", 0x0D6}, // SP 0x1402AE020 MP 0x000000000 + {"getfreeaicount", 0x0D7}, // SP 0x1402AE4E0 MP 0x000000000 + {"getaicount", 0x0D8}, // SP 0x1402AE4F0 MP 0x000000000 + {"getaiarray", 0x0D9}, // SP 0x1402AE7A0 MP 0x000000000 + {"getaispeciesarray", 0x0DA}, // SP 0x1402AF980 MP 0x000000000 + {"getspawnerarray", 0x0DB}, // SP 0x1402AFBD0 MP 0x000000000 + {"getcorpsearray", 0x0DC}, // SP 0x1402AFB20 MP 0x000000000 + {"getspawnerteamarray", 0x0DD}, // SP 0x1402AFCE0 MP 0x000000000 + {"getweaponclipmodel", 0x0DE}, // SP 0x1402AFE20 MP 0x000000000 + {"getbrushmodelcenter", 0x0DF}, // SP 0x14029CAC0 MP 0x000000000 + {"getkeybinding", 0x0E0}, // SP 0x1402A7830 MP 0x000000000 + {"max", 0x0E1}, // SP 0x14028E170 MP 0x14036C720 {"floor", 0x0E2}, // SP 0x14028E1C0 MP 0x14036C750 {"ceil", 0x0E3}, // SP 0x14028E260 MP 0x14036C770 {"exp", 0x0E4}, // SP 0x14028E280 MP 0x14036C790 @@ -238,36 +238,36 @@ namespace scripting {"log", 0x0E6}, // SP 0x14028E410 MP 0x14036C840 {"sqrt", 0x0E7}, // SP 0x14028E470 MP 0x14036CB80 {"squared", 0x0E8}, // SP 0x14028E4B0 MP 0x14036CBA0 - {"_func_0E9", 0x0E9}, // SP 0x14028E770 MP 0x14036CE40 - {"_func_0EA", 0x0EA}, // SP 0x14028E8C0 MP 0x14036CF30 + {"clamp", 0x0E9}, // SP 0x14028E770 MP 0x14036CE40 + {"angleclamp", 0x0EA}, // SP 0x14028E8C0 MP 0x14036CF30 {"angleclamp180", 0x0EB}, // SP 0x14028E920 MP 0x14036CFB0 {"vectorfromlinetopoint", 0x0EC}, // SP 0x140290740 MP 0x14036E5A0 {"pointonsegmentnearesttopoint", 0x0ED}, // SP 0x140290B60 MP 0x14036EB30 - {"_func_0EE", 0x0EE}, // SP 0x140291260 MP 0x14036F6E0 - {"_func_0EF", 0x0EF}, // SP 0x1402913A0 MP 0x14036F790 - {"_func_0F0", 0x0F0}, // SP 0x140291600 MP 0x140357E10 - {"_func_0F1", 0x0F1}, // SP 0x1402918C0 MP 0x140357FB0 - {"_func_0F2", 0x0F2}, // SP 0x140291930 MP 0x140358030 - {"_func_0F3", 0x0F3}, // SP 0x140291AF0 MP 0x140358130 - {"_func_0F4", 0x0F4}, // SP 0x140291B30 MP 0x140358190 - {"_func_0F5", 0x0F5}, // SP 0x140291C20 MP 0x1403581E0 - {"_func_0F6", 0x0F6}, // SP 0x140291EB0 MP 0x140358570 - {"_func_0F7", 0x0F7}, // SP 0x140291F80 MP 0x140358640 + {"distance", 0x0EE}, // SP 0x140291260 MP 0x14036F6E0 + {"distance2d", 0x0EF}, // SP 0x1402913A0 MP 0x14036F790 + {"distancesquared", 0x0F0}, // SP 0x140291600 MP 0x140357E10 + {"length", 0x0F1}, // SP 0x1402918C0 MP 0x140357FB0 + {"length2d", 0x0F2}, // SP 0x140291930 MP 0x140358030 + {"lengthsquared", 0x0F3}, // SP 0x140291AF0 MP 0x140358130 + {"length2dsquared", 0x0F4}, // SP 0x140291B30 MP 0x140358190 + {"closer", 0x0F5}, // SP 0x140291C20 MP 0x1403581E0 + {"vectordot", 0x0F6}, // SP 0x140291EB0 MP 0x140358570 + {"vectorcross", 0x0F7}, // SP 0x140291F80 MP 0x140358640 {"axistoangles", 0x0F8}, // SP 0x140292690 MP 0x140359050 - {"_func_0F9", 0x0F9}, // SP 0x1402ABB50 MP 0x1403771E0 - {"_func_0FA", 0x0FA}, // SP 0x1402ABB60 MP 0x140377260 - {"_func_0FB", 0x0FB}, // SP 0x000000000 MP 0x14037B950 - {"_func_0FC", 0x0FC}, // SP 0x000000000 MP 0x140374E10 + {"visionsetthermal", 0x0F9}, // SP 0x1402ABB50 MP 0x1403771E0 + {"visionsetpain", 0x0FA}, // SP 0x1402ABB60 MP 0x140377260 + {"endlobby", 0x0FB}, // SP 0x000000000 MP 0x14037B950 + {"setac130ambience", 0x0FC}, // SP 0x000000000 MP 0x140374E10 {"getmapcustom", 0x0FD}, // SP 0x000000000 MP 0x140378260 - {"_func_0FE", 0x0FE}, // SP 0x000000000 MP 0x1403765A0 + {"spawnsighttrace", 0x0FE}, // SP 0x000000000 MP 0x1403765A0 {"incrementcounter", 0x0FF}, // SP 0x1402AE370 MP 0x140374FE0 {"getcountertotal", 0x100}, // SP 0x1402AE3C0 MP 0x140375100 - {"_func_101", 0x101}, // SP 0x1402A1AE0 MP 0x000000000 - {"_func_102", 0x102}, // SP 0x14028E970 MP 0x000000000 - {"_func_103", 0x103}, // SP 0x14028ED80 MP 0x000000000 - {"_func_104", 0x104}, // SP 0x1405D92F0 MP 0x14042C2C0 - {"_func_105", 0x105}, // SP 0x1405D92F0 MP 0x14042C2D0 - {"_func_106", 0x106}, // SP 0x14028D7F0 MP 0x000000000 + {"getlevelticks", 0x101}, // SP 0x1402A1AE0 MP 0x000000000 + {"perlinnoise2d", 0x102}, // SP 0x14028E970 MP 0x000000000 + {"calcrockingangles", 0x103}, // SP 0x14028ED80 MP 0x000000000 + {"reconevent", 0x104}, // SP 0x1405D92F0 MP 0x14042C2C0 + {"reconspatialevent", 0x105}, // SP 0x1405D92F0 MP 0x14042C2D0 + {"setsunflareposition", 0x106}, // SP 0x14028D7F0 MP 0x000000000 {"createthreatbiasgroup", 0x107}, // SP 0x1402D79E0 MP 0x1400774E0 {"threatbiasgroupexists", 0x108}, // SP 0x1402D7A10 MP 0x140077510 {"getthreatbias", 0x109}, // SP 0x1402D7A50 MP 0x140077550 @@ -275,63 +275,63 @@ namespace scripting {"setthreatbiasagainstall", 0x10B}, // SP 0x1402D7B30 MP 0x140077630 {"setignoremegroup", 0x10C}, // SP 0x1402D7B80 MP 0x140077680 {"isenemyteam", 0x10D}, // SP 0x1402D7CC0 MP 0x140077820 - {"_func_10E", 0x10E}, // SP 0x1402B7530 MP 0x000000000 - {"_func_10F", 0x10F}, // SP 0x1402B77F0 MP 0x000000000 - {"_func_110", 0x110}, // SP 0x1402B7800 MP 0x000000000 - {"_func_111", 0x111}, // SP 0x1402B7810 MP 0x000000000 - {"_func_112", 0x112}, // SP 0x1402B79C0 MP 0x000000000 - {"_func_113", 0x113}, // SP 0x1402B7A20 MP 0x000000000 + {"objective_additionalentity", 0x10E}, // SP 0x1402B7530 MP 0x000000000 + {"objective_state_nomessage", 0x10F}, // SP 0x1402B77F0 MP 0x000000000 + {"objective_string", 0x110}, // SP 0x1402B7800 MP 0x000000000 + {"objective_string_nomessage", 0x111}, // SP 0x1402B7810 MP 0x000000000 + {"objective_additionalposition", 0x112}, // SP 0x1402B79C0 MP 0x000000000 + {"objective_current_nomessage", 0x113}, // SP 0x1402B7A20 MP 0x000000000 {"vectornormalize", 0x114}, // SP 0x140292150 MP 0x1403587A0 {"vectortoangles", 0x115}, // SP 0x140292290 MP 0x140358A90 {"vectortoyaw", 0x116}, // SP 0x1402924D0 MP 0x140358B10 {"vectorlerp", 0x117}, // SP 0x140292510 MP 0x140358E60 {"anglestoup", 0x118}, // SP 0x140292C80 MP 0x1403596E0 - {"_func_119", 0x119}, // SP 0x140292D50 MP 0x140359890 - {"_func_11A", 0x11A}, // SP 0x140292F80 MP 0x140359930 + {"anglestoright", 0x119}, // SP 0x140292D50 MP 0x140359890 + {"anglestoforward", 0x11A}, // SP 0x140292F80 MP 0x140359930 {"anglesdelta", 0x11B}, // SP 0x1402930E0 MP 0x140359BC0 - {"_func_11C", 0x11C}, // SP 0x1402934C0 MP 0x14035A0F0 - {"_func_11D", 0x11D}, // SP 0x140293670 MP 0x14035A280 - {"_func_11E", 0x11E}, // SP 0x1402956B0 MP 0x14035B550 - {"_func_11F", 0x11F}, // SP 0x140295850 MP 0x14035B7F0 + {"combineangles", 0x11C}, // SP 0x1402934C0 MP 0x14035A0F0 + {"transformmove", 0x11D}, // SP 0x140293670 MP 0x14035A280 + {"rotatevector", 0x11E}, // SP 0x1402956B0 MP 0x14035B550 + {"rotatepointaroundvector", 0x11F}, // SP 0x140295850 MP 0x14035B7F0 {"issubstr", 0x120}, // SP 0x140296960 MP 0x14035CB70 {"isendstr", 0x121}, // SP 0x1402969A0 MP 0x14035CD40 {"getsubstr", 0x122}, // SP 0x140296BB0 MP 0x14035CF80 {"tolower", 0x123}, // SP 0x140296DC0 MP 0x14035D360 - {"_func_124", 0x124}, // SP 0x140297230 MP 0x14035DA90 - {"_func_125", 0x125}, // SP 0x140297970 MP 0x14035E690 - {"_func_126", 0x126}, // SP 0x14029FA50 MP 0x1403679A0 + {"strtok", 0x124}, // SP 0x140297230 MP 0x14035DA90 + {"stricmp", 0x125}, // SP 0x140297970 MP 0x14035E690 + {"ambientplay", 0x126}, // SP 0x14029FA50 MP 0x1403679A0 {"getuavstrengthmax", 0x127}, // SP 0x000000000 MP 0x14037B790 - {"getuavstrengthlevelshowenemyfastsweep", 0x128}, // SP 0x000000000 MP 0x14037B7A0 - {"isdedicatedserver", 0x129}, // SP 0x000000000 MP 0x14037B7B0 - {"worldentnumber", 0x12A}, // SP 0x000000000 MP 0x14037B7C0 + {"getuavstrengthlevelneutral", 0x128}, // SP 0x000000000 MP 0x14037B7A0 + {"getuavstrengthlevelshowenemyfastsweep", 0x129}, // SP 0x000000000 MP 0x14037B7B0 + {"getuavstrengthlevelshowenemydirectional", 0x12A}, // SP 0x000000000 MP 0x14037B7C0 {"blockteamradar", 0x12B}, // SP 0x000000000 MP 0x14037B7D0 {"unblockteamradar", 0x12C}, // SP 0x000000000 MP 0x14037B830 {"isteamradarblocked", 0x12D}, // SP 0x000000000 MP 0x14037B8B0 - {"_func_12E", 0x12E}, // SP 0x000000000 MP 0x140378110 - {"_func_12F", 0x12F}, // SP 0x000000000 MP 0x14037A7B0 - {"_func_130", 0x130}, // SP 0x000000000 MP 0x140378420 + {"getassignedteam", 0x12E}, // SP 0x000000000 MP 0x140378110 + {"setmatchdata", 0x12F}, // SP 0x000000000 MP 0x14037A7B0 + {"getmatchdata", 0x130}, // SP 0x000000000 MP 0x140378420 {"sendmatchdata", 0x131}, // SP 0x000000000 MP 0x140378490 - {"_func_132", 0x132}, // SP 0x000000000 MP 0x140378F40 - {"_func_133", 0x133}, // SP 0x000000000 MP 0x14037A820 - {"_func_134", 0x134}, // SP 0x000000000 MP 0x140378FE0 + {"clearmatchdata", 0x132}, // SP 0x000000000 MP 0x140378F40 + {"setmatchdatadef", 0x133}, // SP 0x000000000 MP 0x14037A820 + {"setmatchclientip", 0x134}, // SP 0x000000000 MP 0x140378FE0 {"setmatchdataid", 0x135}, // SP 0x000000000 MP 0x140378DD0 - {"_func_136", 0x136}, // SP 0x000000000 MP 0x140378F70 - {"getmatchdata", 0x137}, // SP 0x000000000 MP 0x140378290 - {"_func_138", 0x138}, // SP 0x000000000 MP 0x14037A8D0 + {"setclientmatchdata", 0x136}, // SP 0x000000000 MP 0x140378F70 + {"getclientmatchdata", 0x137}, // SP 0x000000000 MP 0x140378290 + {"setclientmatchdatadef", 0x138}, // SP 0x000000000 MP 0x14037A8D0 {"sendclientmatchdata", 0x139}, // SP 0x000000000 MP 0x14037ADE0 {"getbuildversion", 0x13A}, // SP 0x000000000 MP 0x14037AEB0 - {"getsquadassaultelo", 0x13B}, // SP 0x000000000 MP 0x14037B0E0 + {"getbuildnumber", 0x13B}, // SP 0x000000000 MP 0x14037B0E0 {"getsystemtime", 0x13C}, // SP 0x000000000 MP 0x14037B100 {"getmatchrulesdata", 0x13D}, // SP 0x000000000 MP 0x14037AA30 {"isusingmatchrulesdata", 0x13E}, // SP 0x000000000 MP 0x14037AB20 - {"_func_13F", 0x13F}, // SP 0x000000000 MP 0x1403769E0 - {"ishairrunning", 0x140}, // SP 0x1402ACD00 MP 0x140378030 + {"kick", 0x13F}, // SP 0x000000000 MP 0x1403769E0 + {"issplitscreen", 0x140}, // SP 0x1402ACD00 MP 0x140378030 {"setmapcenter", 0x141}, // SP 0x000000000 MP 0x14037B550 {"setgameendtime", 0x142}, // SP 0x000000000 MP 0x14037B5A0 {"visionsetthermal", 0x143}, // SP 0x1402ABA00 MP 0x140376D40 {"visionsetpain", 0x144}, // SP 0x1402ABA10 MP 0x1403770E0 - {"visionsetpostapply", 0x145}, // SP 0x1402ABA20 MP 0x140377160 - {"_func_146", 0x146}, // SP 0x1402A12A0 MP 0x1403699C0 + {"visionsetnight", 0x145}, // SP 0x1402ABA20 MP 0x140377160 + {"visionsetmissilecam", 0x146}, // SP 0x1402A12A0 MP 0x1403699C0 {"_func_147", 0x147}, // SP 0x140298040 MP 0x14035F250 {"_func_148", 0x148}, // SP 0x140298370 MP 0x14035F7A0 {"_func_149", 0x149}, // SP 0x14029E7B0 MP 0x140366DA0 @@ -342,7 +342,7 @@ namespace scripting {"_func_14E", 0x14E}, // SP 0x1402982C0 MP 0x14035F470 {"_func_14F", 0x14F}, // SP 0x14029EDB0 MP 0x1403670E0 {"loadfx", 0x150}, // SP 0x140290A80 MP 0x1403583B0 - {"_func_151", 0x151}, // SP 0x140291730 MP 0x140359620 + {"playfx", 0x151}, // SP 0x140291730 MP 0x140359620 {"playfxontag", 0x152}, // SP 0x140292A40 MP 0x14035AF90 {"stopfxontag", 0x153}, // SP 0x140294440 MP 0x14035C4B0 {"_func_154", 0x154}, // SP 0x140294DD0 MP 0x14035D560 From 42ccedefef061747ea4e1afeab32e9bf5c0e40ee Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 6 Mar 2022 01:39:03 +0100 Subject: [PATCH 045/346] Improve text chat --- src/client/component/chat.cpp | 54 ++++++++++++++++++++++++++++++++ src/client/component/patches.cpp | 3 -- 2 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 src/client/component/chat.cpp diff --git a/src/client/component/chat.cpp b/src/client/component/chat.cpp new file mode 100644 index 00000000..b3af7710 --- /dev/null +++ b/src/client/component/chat.cpp @@ -0,0 +1,54 @@ +#include +#include "loader/component_loader.hpp" + +#include "localized_strings.hpp" +#include "dvars.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include + +namespace chat +{ + namespace + { + game::Font_s* ui_get_font_handle_stub() + { + return game::R_RegisterFont("fonts/defaultBold.otf", 24); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (!game::environment::is_mp()) + { + return; + } + + // use better font + utils::hook::call(0x1400AA831, ui_get_font_handle_stub); + utils::hook::call(0x14024800C, ui_get_font_handle_stub); + utils::hook::call(0x14024F573, ui_get_font_handle_stub); + + // set text style to 0 (non-blurry) + utils::hook::set(0x14024F5DD, 0); + utils::hook::set(0x1400AAA1C, 0); + utils::hook::set(0x14024802E, 0); + + localized_strings::override("EXE_SAY", "^3Match^7"); + localized_strings::override("EXE_SAYTEAM", "^5Team^7"); + + // move chat position on the screen above menu splashes + dvars::override::register_vec2("cg_hudChatPosition", 5, 200, 0, 640, game::DVAR_FLAG_SAVED); + dvars::override::register_int("cg_chatHeight", 5, 0, 8, game::DVAR_FLAG_SAVED); + } + }; +} + +REGISTER_COMPONENT(chat::component) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index f90f0375..d5392095 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -252,9 +252,6 @@ namespace patches dvars::override::register_int("safeArea_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); dvars::override::register_int("safeArea_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); - // move chat position on the screen above menu splashes - dvars::override::register_vec2("cg_hudChatPosition", 5, 170, 0, 640, game::DVAR_FLAG_SAVED); - // allow servers to check for new packages more often dvars::override::register_int("sv_network_fps", 1000, 20, 1000, game::DVAR_FLAG_SAVED); From 1816ca1b6154c478a9334dedd620816c41f8dae6 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 6 Mar 2022 02:15:05 +0100 Subject: [PATCH 046/346] Add some jump dvars --- src/client/component/chat.cpp | 2 -- src/client/component/gameplay.cpp | 56 +++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 src/client/component/gameplay.cpp diff --git a/src/client/component/chat.cpp b/src/client/component/chat.cpp index b3af7710..912624f5 100644 --- a/src/client/component/chat.cpp +++ b/src/client/component/chat.cpp @@ -7,9 +7,7 @@ #include "game/game.hpp" #include "game/dvars.hpp" -#include #include -#include namespace chat { diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp new file mode 100644 index 00000000..115522e7 --- /dev/null +++ b/src/client/component/gameplay.cpp @@ -0,0 +1,56 @@ +#include +#include "loader/component_loader.hpp" + +#include "dvars.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include + +namespace gameplay +{ + namespace + { + game::dvar_t* jump_slowDownEnable; + game::dvar_t* jump_enableFallDamage; + + void jump_apply_slowdown_stub(game::mp::playerState_s* ps) + { + if (jump_slowDownEnable->current.enabled) + { + utils::hook::invoke(0x1401D5360, ps); + } + } + + void pm_crashland_stub(game::mp::playerState_s* ps, void* pml) + { + if (jump_enableFallDamage->current.enabled) + { + utils::hook::invoke(0x1401E2D00, ps, pml); + } + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) + { + return; + } + + utils::hook::call(0x1401E8830, jump_apply_slowdown_stub); + jump_slowDownEnable = dvars::register_bool("jump_slowDownEnable", true, game::DVAR_FLAG_REPLICATED, true); + + utils::hook::call(0x1401E490F, pm_crashland_stub); + jump_enableFallDamage = dvars::register_bool("jump_enableFallDamage", true, game::DVAR_FLAG_REPLICATED, true); + } + }; +} + +REGISTER_COMPONENT(gameplay::component) From f9ad7b3ed71c1a735bd0c8bb3796d5d6c81b770a Mon Sep 17 00:00:00 2001 From: m Date: Sat, 5 Mar 2022 19:37:08 -0600 Subject: [PATCH 047/346] Replace obscure ternary operator by https://github.com/diamante0018 from https://github.com/XLabsProject/s1x-client --- src/client/component/bots.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 81f74628..03323512 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -91,7 +91,9 @@ namespace bots num_bots = atoi(params.get(1)); } - for (auto i = 0; i < (num_bots > *game::mp::svs_numclients ? *game::mp::svs_numclients : num_bots); i++) + num_bots = std::min(num_bots, *game::mp::svs_numclients);; + + for (auto i = 0; i < num_bots; i++) { scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i); } From 88cee0fe525266d1a5dbbad249931dde0020713d Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 6 Mar 2022 03:16:57 +0100 Subject: [PATCH 048/346] Scripting fixes --- src/client/game/scripting/function_tables.cpp | 2 +- src/client/game/scripting/functions.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index ef116e79..9a4d9663 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -1183,7 +1183,7 @@ namespace scripting {"_meth_81B2", 0x81B2}, // SP 0x1402A15D0 MP 0x14036AE60 {"viewkick", 0x81B3}, // SP 0x1402A1640 MP 0x14036AFA0 {"_meth_81B4", 0x81B4}, // SP 0x14029B1E0 MP 0x1403668B0 - {"_meth_81B5", 0x81B5}, // SP 0x1402998B0 MP 0x140364980 + {"getentitynumber", 0x81B5}, // SP 0x1402998B0 MP 0x140364980 {"autoboltmissileeffects", 0x81B6}, // SP 0x140299AA0 MP 0x140364B50 {"enablegrenadetouchdamage", 0x81B7}, // SP 0x140299CA0 MP 0x140364F40 {"disablegrenadetouchdamage", 0x81B8}, // SP 0x140299F20 MP 0x1403650C0 diff --git a/src/client/game/scripting/functions.cpp b/src/client/game/scripting/functions.cpp index 3452c767..0f233547 100644 --- a/src/client/game/scripting/functions.cpp +++ b/src/client/game/scripting/functions.cpp @@ -59,12 +59,12 @@ namespace scripting script_function get_function_by_index(const unsigned index) { - static const auto function_table = SELECT_VALUE(0x149668F50, 0x147DD1850); - static const auto method_table = SELECT_VALUE(0x14966A670, 0x147DD2F50); + static const auto function_table = SELECT_VALUE(0x14B1D1B90, 0x149813EF0); + static const auto method_table = SELECT_VALUE(0x14B1D33A0, 0x149815700); - if (index < 0x2DF) + if (index < 0x301) { - return reinterpret_cast(function_table)[index]; + return reinterpret_cast(function_table)[index - 1]; } return reinterpret_cast(method_table)[index - 0x8000]; From 3dd28c156598c2aaa3dc0549e34f1bde4577fca2 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Sun, 6 Mar 2022 15:03:44 +0200 Subject: [PATCH 049/346] fovmin reset fix --- src/client/component/patches.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index d5392095..f1277e94 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -72,7 +72,7 @@ namespace patches void set_client_dvar_from_server_stub(void* a1, void* a2, const char* dvar, const char* value) { - if (dvar == "cg_fov"s) + if (dvar == "cg_fov"s || dvar == "cg_fovMin"s) { return; } @@ -179,7 +179,8 @@ namespace patches // Make cg_fov and cg_fovscale saved dvars dvars::override::register_float("cg_fov", 65.f, 40.f, 200.f, game::DvarFlags::DVAR_FLAG_SAVED); dvars::override::register_float("cg_fovScale", 1.f, 0.1f, 2.f, game::DvarFlags::DVAR_FLAG_SAVED); - + dvars::override::register_float("cg_fovMin", 1.f, 1.0f, 90.f, game::DvarFlags::DVAR_FLAG_SAVED); + // Allow kbam input when gamepad is enabled utils::hook::nop(SELECT_VALUE(0x14018797E, 0x14024EF60), 2); utils::hook::nop(SELECT_VALUE(0x1401856DC, 0x14024C6B0), 6); From 9faaa5a309381e2ee2dc6f9b115764f021935c19 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 6 Mar 2022 21:17:42 +0100 Subject: [PATCH 050/346] Ranked dedis --- src/client/component/ranked.cpp | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/client/component/ranked.cpp diff --git a/src/client/component/ranked.cpp b/src/client/component/ranked.cpp new file mode 100644 index 00000000..027e3d8f --- /dev/null +++ b/src/client/component/ranked.cpp @@ -0,0 +1,47 @@ +#include +#include "loader/component_loader.hpp" + +#include "scheduler.hpp" +#include "dvars.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include + +namespace ranked +{ + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) + { + return; + } + + if (game::environment::is_mp()) + { + dvars::override::register_bool("xblive_privatematch", false, game::DVAR_FLAG_REPLICATED); + } + + if (game::environment::is_dedi() && !utils::flags::has_flag("unranked")) + { + dvars::override::register_bool("xblive_privatematch", false, game::DVAR_FLAG_REPLICATED | game::DVAR_FLAG_WRITE); + + // Skip some check in _menus.gsc + dvars::register_bool("force_ranking", true, game::DVAR_FLAG_WRITE); + } + + // Always run bots, even if xblive_privatematch is 0 + utils::hook::set(0x1401D9300, 0xC301B0); // BG_BotSystemEnabled + utils::hook::set(0x1401D90D0, 0xC301B0); // BG_AISystemEnabled + utils::hook::set(0x1401D92A0, 0xC301B0); // BG_BotFastFileEnabled + utils::hook::set(0x1401D9400, 0xC301B0); // BG_BotsUsingTeamDifficulty + } + }; +} + +REGISTER_COMPONENT(ranked::component) From b1dcc4230d97c1c31e87223cdea210fe726d7783 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Mon, 7 Mar 2022 00:13:37 +0200 Subject: [PATCH 051/346] hide crosshair fix --- src/client/component/patches.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index f1277e94..75406f95 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -264,6 +264,8 @@ namespace patches dvars::register_int("scr_game_spectatetype", 1, 0, 99, game::DVAR_FLAG_REPLICATED); + dvars::override::register_bool("ui_drawcrosshair", true, game::DVAR_FLAG_WRITE); + dvars::override::register_int("com_maxfps", 0, 0, 1000, game::DVAR_FLAG_SAVED); // Prevent clients from ending the game as non host by sending 'end_game' lui notification From 9f909770e6515d6567d56ef9829b8806eb546e39 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 8 Mar 2022 06:23:31 -0600 Subject: [PATCH 052/346] don't load data from host module closes #21, nice copy and paste skull --- src/client/game/scripting/lua/engine.cpp | 2 -- src/client/game/ui_scripting/lua/engine.cpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/client/game/scripting/lua/engine.cpp b/src/client/game/scripting/lua/engine.cpp index 351ad04b..d481dc76 100644 --- a/src/client/game/scripting/lua/engine.cpp +++ b/src/client/game/scripting/lua/engine.cpp @@ -4,7 +4,6 @@ #include "../execution.hpp" #include "../../../component/logfile.hpp" -#include "../../../component/game_module.hpp" #include @@ -52,7 +51,6 @@ namespace scripting::lua::engine } stop(); - load_scripts(game_module::get_host_module().get_folder() + "/data/scripts/"); load_scripts("h1-mod/scripts/"); load_scripts("data/scripts/"); } diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index 93713530..00ea46f6 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -3,7 +3,6 @@ #include "context.hpp" #include "../../../component/ui_scripting.hpp" -#include "../../../component/game_module.hpp" #include @@ -52,7 +51,6 @@ namespace ui_scripting::lua::engine load_code(lui_common); load_code(lui_updater); - load_scripts(game_module::get_host_module().get_folder() + "/data/ui_scripts/"); load_scripts("h1-mod/ui_scripts/"); load_scripts("data/ui_scripts/"); } From 1643d37744d43ebbb34e1e9bbb3b58c911dcdd58 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 8 Mar 2022 06:36:43 -0600 Subject: [PATCH 053/346] update readme [skip ci] --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1debc4bc..998c2c64 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@

-Currently a proof-of-concept client for Modern Warfare Remaster (1.04). Latest MWR (1.15) version planned in future.
-[This project is based on S1x.](https://github.com/XLabsProject/s1x-client) +A experimental client for Modern Warfare Remaster (1.04). Latest MWR (1.15) version planned in future.
+[This project is using the S1x codebase.](https://github.com/XLabsProject/s1x-client) ## Compile from source @@ -22,10 +22,11 @@ Currently a proof-of-concept client for Modern Warfare Remaster (1.04). Latest M ## Credits: -- [S1x](https://github.com/XLabsProject/s1x-client) - code and base. +- [XLabsProject](https://github.com/XLabsProject) - codebase and iw6x/s1x research - [quaK](https://github.com/Joelrau) - lots of insight and help - [fed](https://github.com/fedddddd) - fixed DW/networking, work from [h2-mod](https://github.com/fedddddd/h2-mod) - [mjkzy](https://github.com/mjkzy) - porting code from s1x +- [skkuull](https://github.com/skkuull) - initial porting of s1x ## Disclaimer From 2734d18d71a94e9774f502f898d91c8573433e39 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Tue, 8 Mar 2022 15:38:18 +0300 Subject: [PATCH 054/346] say my name properly [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 998c2c64..4e095ada 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ A experimental client for Modern Warfare Remaster (1.04). Latest MWR (1.15) vers - [quaK](https://github.com/Joelrau) - lots of insight and help - [fed](https://github.com/fedddddd) - fixed DW/networking, work from [h2-mod](https://github.com/fedddddd/h2-mod) - [mjkzy](https://github.com/mjkzy) - porting code from s1x -- [skkuull](https://github.com/skkuull) - initial porting of s1x +- [Skull](https://github.com/skkuull) - initial porting of s1x ## Disclaimer From 83fd05f0f882f8083996c7946127e203abf5edc1 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 8 Mar 2022 06:41:04 -0600 Subject: [PATCH 055/346] fix compile ?? --- src/client/game/ui_scripting/lua/engine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index 00ea46f6..8faf198c 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -5,6 +5,7 @@ #include "../../../component/ui_scripting.hpp" #include +#include namespace ui_scripting::lua::engine { From 001e5a746ac9702c31dd504a012a4b9f8387f255 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Mar 2022 17:52:17 +0000 Subject: [PATCH 056/346] Bump deps/rapidjson from `e4bde97` to `0d78b1c` Bumps [deps/rapidjson](https://github.com/Tencent/rapidjson) from `e4bde97` to `0d78b1c`. - [Release notes](https://github.com/Tencent/rapidjson/releases) - [Commits](https://github.com/Tencent/rapidjson/compare/e4bde977440d4a00f820b6586899e48a972d2493...0d78b1ce9316a9c84d58592fd717eccf41969d4a) --- updated-dependencies: - dependency-name: deps/rapidjson dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/rapidjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rapidjson b/deps/rapidjson index e4bde977..0d78b1ce 160000 --- a/deps/rapidjson +++ b/deps/rapidjson @@ -1 +1 @@ -Subproject commit e4bde977440d4a00f820b6586899e48a972d2493 +Subproject commit 0d78b1ce9316a9c84d58592fd717eccf41969d4a From 1d8eab6490a653f00a5ff90bd1efbf75cf005b53 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Wed, 9 Mar 2022 19:33:00 +0200 Subject: [PATCH 057/346] small cleanup --- src/client/component/demonware.cpp | 27 +++++------- src/client/component/fps.cpp | 2 +- src/client/component/input.cpp | 4 +- src/client/component/lui.cpp | 2 +- src/client/component/network.cpp | 66 ++++++++++++++--------------- src/client/component/patches.cpp | 34 +++++++-------- src/client/component/slowmotion.cpp | 2 +- src/client/component/splash.cpp | 6 +-- src/client/component/videos.cpp | 2 +- 9 files changed, 70 insertions(+), 75 deletions(-) diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp index 4cb3362c..d74889a5 100644 --- a/src/client/component/demonware.cpp +++ b/src/client/component/demonware.cpp @@ -537,34 +537,29 @@ namespace demonware void post_unpack() override { - /* - mwr has upgraded some networking methods and the gethostbyname import from winsock library is no longer used - gethostbyname has been replaced with getaddrinfo - btw, still you can't get online.. - */ - utils::hook::jump(SELECT_VALUE(0x140610320, 0x1407400B0), bd_logger_stub); // H1MP64(1.4) + utils::hook::jump(SELECT_VALUE(0x140610320, 0x1407400B0), bd_logger_stub); if (game::environment::is_sp()) { - utils::hook::set(0x1405FCA00, 0xC3); // bdAuthSteam H1(1.4) - utils::hook::set(0x140333A00, 0xC3); // dwNet H1(1.4) + utils::hook::set(0x1405FCA00, 0xC3); // bdAuthSteam + utils::hook::set(0x140333A00, 0xC3); // dwNet return; } - utils::hook::set(0x140715039, 0x0); // CURLOPT_SSL_VERIFYPEER H1MP64(1.4) - utils::hook::set(0x140715025, 0xAF); // CURLOPT_SSL_VERIFYHOST H1MP64(1.4) - utils::hook::set(0x14095433C, 0x0); // HTTPS -> HTTP [MWR OK][S1X: 0x14088D0E8] + utils::hook::set(0x140715039, 0x0); // CURLOPT_SSL_VERIFYPEER + utils::hook::set(0x140715025, 0xAF); // CURLOPT_SSL_VERIFYHOST + utils::hook::set(0x14095433C, 0x0); // HTTPS -> HTTP //HTTPS -> HTTP - utils::hook::inject(0x14006DDA9, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x14003852E] - utils::hook::inject(0x14006E11C, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x14003884F] - utils::hook::inject(0x14006E2FB, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x140038A07] + utils::hook::inject(0x14006DDA9, "http://prod.umbrella.demonware.net/v1.0/"); + utils::hook::inject(0x14006E11C, "http://prod.umbrella.demonware.net/v1.0/"); + utils::hook::inject(0x14006E2FB, "http://prod.umbrella.demonware.net/v1.0/"); utils::hook::inject(0x14006E9A9, "http://prod.uno.demonware.net/v1.0/"); utils::hook::inject(0x14006ED49, "http://prod.uno.demonware.net/v1.0/"); utils::hook::inject(0x140728170, "http://%s:%d/auth/"); - utils::hook::set(0x14047F290, 0xC3); // SV_SendMatchData H1MP64(1.4) - utils::hook::set(0x140598990, 0xC3); // Live_CheckForFullDisconnect H1MP64(1.4) + utils::hook::set(0x14047F290, 0xC3); // SV_SendMatchData + utils::hook::set(0x140598990, 0xC3); // Live_CheckForFullDisconnect #ifdef DEBUG // yes diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index a0ea9299..f0a62b69 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -88,7 +88,7 @@ namespace fps perf_calc_fps(&cg_perf, cg_perf.frame_ms); - utils::hook::invoke(SELECT_VALUE(0x1405487A0, 0x1406575A0)); // H1(1.4) + utils::hook::invoke(SELECT_VALUE(0x1405487A0, 0x1406575A0)); } void cg_draw_fps() diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 4fc59741..a10ac12a 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -45,8 +45,8 @@ namespace input return; } - cl_char_event_hook.create(SELECT_VALUE(0x1401871A0, 0x14024E810), cl_char_event_stub); // H1(1.4) - cl_key_event_hook.create(SELECT_VALUE(0x1401874D0, 0x14024EA60), cl_key_event_stub); // H1(1.4) + cl_char_event_hook.create(SELECT_VALUE(0x1401871A0, 0x14024E810), cl_char_event_stub); + cl_key_event_hook.create(SELECT_VALUE(0x1401874D0, 0x14024EA60), cl_key_event_stub); } }; } diff --git a/src/client/component/lui.cpp b/src/client/component/lui.cpp index d3a7edca..9bc87113 100644 --- a/src/client/component/lui.cpp +++ b/src/client/component/lui.cpp @@ -16,7 +16,7 @@ namespace lui void post_unpack() override { // Don't show create cod account popup - //utils::hook::set(0x14017C957, 0); // H1(1.4) + //utils::hook::set(0x14017C957, 0); //#ifdef _DEBUG // Enable development menus (causes issues in sp) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 47ca2b20..353f8ee1 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -67,11 +67,11 @@ namespace network // Command handled a.popad64(); a.mov(al, 1); - a.jmp(0x140252AF8); // H1MP64(1.4) + a.jmp(0x140252AF8); a.bind(return_unhandled); a.popad64(); - a.jmp(0x14025234C); // H1MP64(1.4) + a.jmp(0x14025234C); } int net_compare_base_address(const game::netadr_s* a1, const game::netadr_s* a2) @@ -237,46 +237,46 @@ namespace network // redirect dw_sendto to raw socket //utils::hook::jump(0x1404D850A, reinterpret_cast(0x1404D849A)); - utils::hook::call(0x140513467, dw_send_to_stub); // H1MP64(1.4) - utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub); // H1MP64(1.4) + utils::hook::call(0x140513467, dw_send_to_stub); + utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub); // intercept command handling - utils::hook::jump(0x140252327, utils::hook::assemble(handle_command_stub), true); // H1MP64(1.4) + utils::hook::jump(0x140252327, utils::hook::assemble(handle_command_stub), true); // handle xuid without secure connection - utils::hook::nop(0x140486AAF, 6); // H1MP64(1.4) + utils::hook::nop(0x140486AAF, 6); - utils::hook::jump(0x140424F20, net_compare_address); // H1MP64(1.4) - utils::hook::jump(0x140424F70, net_compare_base_address); // H1MP64(1.4) + utils::hook::jump(0x140424F20, net_compare_address); + utils::hook::jump(0x140424F70, net_compare_base_address); // don't establish secure conenction - utils::hook::set(0x14027EA4D, 0xEB); // H1MP64(1.4) - utils::hook::set(0x14027EB1E, 0xEB); // H1MP64(1.4) - utils::hook::set(0x14027EF8D, 0xEB); // H1MP64(1.4) - utils::hook::set(0x14025081F, 0xEB); // H1MP64(1.4) + utils::hook::set(0x14027EA4D, 0xEB); + utils::hook::set(0x14027EB1E, 0xEB); + utils::hook::set(0x14027EF8D, 0xEB); + utils::hook::set(0x14025081F, 0xEB); // ignore unregistered connection - utils::hook::jump(0x140480F46, 0x140480EE5); // H1MP64(1.4) - utils::hook::set(0x140480F3B, 0xEB); // H1MP64(1.4) + utils::hook::jump(0x140480F46, 0x140480EE5); + utils::hook::set(0x140480F3B, 0xEB); // disable xuid verification - utils::hook::set(0x14005B62D, 0xEB); // H1MP64(1.4) - utils::hook::set(0x14005B649, 0xEB); // H1MP64(1.4) + utils::hook::set(0x14005B62D, 0xEB); + utils::hook::set(0x14005B649, 0xEB); // disable xuid verification utils::hook::nop(0x14048382C, 2); - utils::hook::set(0x140483889, 0xEB); // H1MP64(1.4) + utils::hook::set(0x140483889, 0xEB); // ignore configstring mismatch - utils::hook::set(0x1402591C9, 0xEB); // H1MP64(1.4) + utils::hook::set(0x1402591C9, 0xEB); // ignore dw handle in SV_PacketEvent utils::hook::set(0x1404898E2, 0xEB); - utils::hook::call(0x1404898D6, &net_compare_address); // H1MP64(1.4) + utils::hook::call(0x1404898D6, &net_compare_address); // ignore dw handle in SV_FindClientByAddress utils::hook::set(0x140488EFD, 0xEB); - utils::hook::call(0x140488EF1, &net_compare_address); // H1MP64(1.4) + utils::hook::call(0x140488EF1, &net_compare_address); // ignore dw handle in SV_DirectConnect utils::hook::set(0x140480C58, 0xEB); @@ -291,32 +291,32 @@ namespace network dvars::override::register_int("sv_remote_client_snapshot_msec", 33, 33, 100, game::DVAR_FLAG_NONE); // ignore impure client - utils::hook::jump(0x140481B58, reinterpret_cast(0x140481BEE)); // H1MP64(1.4) + utils::hook::jump(0x140481B58, reinterpret_cast(0x140481BEE)); // don't send checksum - utils::hook::set(0x140513433, 0); // H1MP64(1.4) mov: r8d, edi ; LEN - utils::hook::set(0x14051345A, 0); // H1MP64(1.4) + utils::hook::set(0x140513433, 0); + utils::hook::set(0x14051345A, 0); // don't read checksum - utils::hook::set(0x1404F6620, 0xC301B0); // H1MP64(1.4) + utils::hook::set(0x1404F6620, 0xC301B0); // don't try to reconnect client - utils::hook::call(0x140480DFF, reconnect_migratated_client); // H1MP64(1.4) - utils::hook::nop(0x140480DDB, 4); // H1MP64(1.4) this crashes when reconnecting for some reason + utils::hook::call(0x140480DFF, reconnect_migratated_client); + utils::hook::nop(0x140480DDB, 4); // this crashes when reconnecting for some reason // allow server owner to modify net_port before the socket bind - utils::hook::call(0x140512BE5, register_netport_stub); // H1MP64(1.4) - utils::hook::call(0x140512D20, register_netport_stub); // H1MP64(1.4) + utils::hook::call(0x140512BE5, register_netport_stub); + utils::hook::call(0x140512D20, register_netport_stub); // increase allowed packet size const auto max_packet_size = 0x20000; - utils::hook::set(0x1404255F1, max_packet_size); // H1MP64(1.4) - utils::hook::set(0x140425630, max_packet_size); // H1MP64(1.4) - utils::hook::set(0x140425522, max_packet_size); // H1MP64(1.4) - utils::hook::set(0x140425545, max_packet_size); // H1MP64(1.4) + utils::hook::set(0x1404255F1, max_packet_size); + utils::hook::set(0x140425630, max_packet_size); + utils::hook::set(0x140425522, max_packet_size); + utils::hook::set(0x140425545, max_packet_size); // ignore built in "print" oob command and add in our own - utils::hook::set(0x14025280E, 0xEB); // H1MP64(1.4) + utils::hook::set(0x14025280E, 0xEB); on("print", [](const game::netadr_s&, const std::string_view& data) { const std::string message{data}; diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 75406f95..3d86b406 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -161,10 +161,10 @@ namespace patches void post_unpack() override { // Register dvars - com_register_dvars_hook.create(SELECT_VALUE(0x140351B80, 0x1400D9320), &com_register_dvars_stub); // H1(1.4) + com_register_dvars_hook.create(SELECT_VALUE(0x140351B80, 0x1400D9320), &com_register_dvars_stub); // Unlock fps in main menu - utils::hook::set(SELECT_VALUE(0x14018D47B, 0x14025B86B), 0xEB); // H1(1.4) + utils::hook::set(SELECT_VALUE(0x14018D47B, 0x14025B86B), 0xEB); if (!game::environment::is_dedi()) { @@ -197,16 +197,16 @@ namespace patches static void patch_mp() { // Use name dvar - utils::hook::jump(0x14050FF90, &live_get_local_client_name); // H1(1.4) + utils::hook::jump(0x14050FF90, &live_get_local_client_name); // Patch SV_KickClientNum - sv_kick_client_num_hook.create(0x14047ED00, &sv_kick_client_num); // H1(1.4) + sv_kick_client_num_hook.create(0x14047ED00, &sv_kick_client_num); // block changing name in-game - utils::hook::set(0x14047FC90, 0xC3); // H1(1.4) + utils::hook::set(0x14047FC90, 0xC3); // patch "Couldn't find the bsp for this map." error to not be fatal in mp - utils::hook::call(0x1402BA26B, bsp_sys_error_stub); // H1(1.4) + utils::hook::call(0x1402BA26B, bsp_sys_error_stub); // client side aim assist dvar dvars::aimassist_enabled = dvars::register_bool("aimassist_enabled", true, @@ -215,12 +215,12 @@ namespace patches utils::hook::call(0x14009EE9E, aim_assist_add_to_target_list); // unlock all items - utils::hook::jump(0x140413E60, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable_LocalClient H1(1.4) - utils::hook::jump(0x140413860, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable H1(1.4) - utils::hook::jump(0x140412B70, is_item_unlocked); // idk ( unlocks loot etc ) H1(1.4) + utils::hook::jump(0x140413E60, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable_LocalClient + utils::hook::jump(0x140413860, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable + utils::hook::jump(0x140412B70, is_item_unlocked); // idk ( unlocks loot etc ) // isProfanity - utils::hook::set(0x1402877D0, 0xC3C033); // MAY BE WRONG H1(1.4) + utils::hook::set(0x1402877D0, 0xC3C033); // disable emblems dvars::override::register_int("emblems_active", 0, 0, 0, game::DVAR_FLAG_NONE); @@ -228,16 +228,16 @@ namespace patches // disable elite_clan dvars::override::register_int("elite_clan_active", 0, 0, 0, game::DVAR_FLAG_NONE); - utils::hook::set(0x140585680, 0xC3); // don't register commands H1(1.4) + utils::hook::set(0x140585680, 0xC3); // don't register commands // disable codPointStore dvars::override::register_int("codPointStore_enabled", 0, 0, 0, game::DVAR_FLAG_NONE); // don't register every replicated dvar as a network dvar - utils::hook::nop(0x14039E58E, 5); // dvar_foreach H1(1.4) + utils::hook::nop(0x14039E58E, 5); // dvar_foreach // patch "Server is different version" to show the server client version - utils::hook::inject(0x140480952, VERSION); // H1(1.4) + utils::hook::inject(0x140480952, VERSION); // prevent servers overriding our fov utils::hook::call(0x14023279E, set_client_dvar_from_server_stub); @@ -246,8 +246,8 @@ namespace patches utils::hook::set(0x14021D22A, 0xEB); // unlock safeArea_* - utils::hook::jump(0x1402624F5, 0x140262503); // H1(1.4) - utils::hook::jump(0x14026251C, 0x140262547); // H1(1.4) + utils::hook::jump(0x1402624F5, 0x140262503); + utils::hook::jump(0x14026251C, 0x140262547); dvars::override::register_int("safeArea_adjusted_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); dvars::override::register_int("safeArea_adjusted_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); dvars::override::register_int("safeArea_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); @@ -269,10 +269,10 @@ namespace patches dvars::override::register_int("com_maxfps", 0, 0, 1000, game::DVAR_FLAG_SAVED); // Prevent clients from ending the game as non host by sending 'end_game' lui notification - // cmd_lui_notify_server_hook.create(0x140335A70, cmd_lui_notify_server_stub); // H1(1.4) + // cmd_lui_notify_server_hook.create(0x140335A70, cmd_lui_notify_server_stub); // Prevent clients from sending invalid reliableAcknowledge - // utils::hook::call(0x1404899C6, sv_execute_client_message_stub); // H1(1.4) + // utils::hook::call(0x1404899C6, sv_execute_client_message_stub); // "fix" for rare 'Out of memory error' error if (utils::flags::has_flag("memoryfix")) diff --git a/src/client/component/slowmotion.cpp b/src/client/component/slowmotion.cpp index 71f66dbf..f75f8a7e 100644 --- a/src/client/component/slowmotion.cpp +++ b/src/client/component/slowmotion.cpp @@ -45,7 +45,7 @@ namespace slowmotion return; } - utils::hook::jump(0x140365480, scr_cmd_set_slow_motion); // H1(1.4) + utils::hook::jump(0x140365480, scr_cmd_set_slow_motion); } }; } diff --git a/src/client/component/splash.cpp b/src/client/component/splash.cpp index 79d23bd1..c9ec30be 100644 --- a/src/client/component/splash.cpp +++ b/src/client/component/splash.cpp @@ -30,9 +30,9 @@ namespace splash void post_unpack() override { // Disable native splash screen - utils::hook::nop(SELECT_VALUE(0x1403E192E, 0x1405123E2), 5); // H1(1.4) - utils::hook::jump(SELECT_VALUE(0x1403E2E70, 0x140513AF0), destroy_stub); // H1(1.4) - utils::hook::jump(SELECT_VALUE(0x1403E2EB0, 0x140513B30), destroy_stub); // H1(1.4) + utils::hook::nop(SELECT_VALUE(0x1403E192E, 0x1405123E2), 5); + utils::hook::jump(SELECT_VALUE(0x1403E2E70, 0x140513AF0), destroy_stub); + utils::hook::jump(SELECT_VALUE(0x1403E2EB0, 0x140513B30), destroy_stub); } void pre_destroy() override diff --git a/src/client/component/videos.cpp b/src/client/component/videos.cpp index a602cc8a..c17dd899 100644 --- a/src/client/component/videos.cpp +++ b/src/client/component/videos.cpp @@ -35,7 +35,7 @@ namespace videos public: void post_unpack() override { - playvid_hook.create(SELECT_VALUE(0x1404A9D00, 0x1405B0AF0), &playvid); // H1(1.4) + playvid_hook.create(SELECT_VALUE(0x1404A9D00, 0x1405B0AF0), &playvid); if (game::environment::is_mp()) { From c38ea7798398c39d9716b99cc59426234da2f680 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 9 Mar 2022 17:43:07 +0000 Subject: [PATCH 058/346] Bump deps/rapidjson from `0d78b1c` to `8261c1d` Bumps [deps/rapidjson](https://github.com/Tencent/rapidjson) from `0d78b1c` to `8261c1d`. - [Release notes](https://github.com/Tencent/rapidjson/releases) - [Commits](https://github.com/Tencent/rapidjson/compare/0d78b1ce9316a9c84d58592fd717eccf41969d4a...8261c1ddf43f10de00fd8c9a67811d1486b2c784) --- updated-dependencies: - dependency-name: deps/rapidjson dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/rapidjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rapidjson b/deps/rapidjson index 0d78b1ce..8261c1dd 160000 --- a/deps/rapidjson +++ b/deps/rapidjson @@ -1 +1 @@ -Subproject commit 0d78b1ce9316a9c84d58592fd717eccf41969d4a +Subproject commit 8261c1ddf43f10de00fd8c9a67811d1486b2c784 From 9e3cd77c6cccdbe13cfb3cdc1ab8f9547afaa21c Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 9 Mar 2022 22:27:12 +0100 Subject: [PATCH 059/346] Allow longer hostnames --- data/ui_scripts/server_list/serverlist.lua | 16 +- src/client/component/server_list.cpp | 16 -- src/client/resources/ui_scripts/common.lua | 208 ++++++++++----------- 3 files changed, 119 insertions(+), 121 deletions(-) diff --git a/data/ui_scripts/server_list/serverlist.lua b/data/ui_scripts/server_list/serverlist.lua index 4eac68e2..afc8137f 100644 --- a/data/ui_scripts/server_list/serverlist.lua +++ b/data/ui_scripts/server_list/serverlist.lua @@ -24,6 +24,19 @@ local columns = { "@MENU_PING", } +function textlength(text, font, height) + local _, _, width = luiglobals.GetTextDimensions(text, font, height) + return width +end + +function trimtext(text, font, height, maxwidth) + while (textlength(text, font, height) > maxwidth) do + text = text:sub(1, #text - 1) + end + + return text +end + SystemLinkJoinMenu.AddHeaderButton = function(menu, f12_arg1, width) local state = CoD.CreateState(0, f12_arg1, nil, nil, CoD.AnchorTypes.TopLeft) state.width = width @@ -53,7 +66,8 @@ SystemLinkJoinMenu.AddServerButton = function(menu, controller, index) button:addEventHandler("button_action", SystemLinkJoinMenu.OnJoinGame) local gettext = function(i) - return Lobby.GetServerData(controller, index, i - 1) + local text = Lobby.GetServerData(controller, index, i - 1) + return trimtext(text, CoD.TextSettings.TitleFontSmall.Font, 14, 400) end for i = 1, #offsets do diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index 407acfe7..bbe3cb0d 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -258,20 +258,6 @@ namespace server_list return true; } - void resize_host_name(std::string& name) - { - name = utils::string::split(name, '\n').front(); - - game::Font_s* font = game::R_RegisterFont("fonts/default.otf", 18); - auto text_size = game::UI_TextWidth(name.data(), 32, font, 1.0f); - - while (text_size > 450) - { - text_size = game::UI_TextWidth(name.data(), 32, font, 1.0f); - name.pop_back(); - } - } - utils::hook::detour lui_open_menu_hook; void lui_open_menu_stub(int controllerIndex, const char* menu, int a3, int a4, unsigned int a5) @@ -364,8 +350,6 @@ namespace server_list server.in_game = 1; - resize_host_name(server.host_name); - insert_server(std::move(server)); } diff --git a/src/client/resources/ui_scripts/common.lua b/src/client/resources/ui_scripts/common.lua index 8f68e96d..e073be2e 100644 --- a/src/client/resources/ui_scripts/common.lua +++ b/src/client/resources/ui_scripts/common.lua @@ -3,162 +3,162 @@ originalmenus = {} stack = {} LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event) - local oncancel = stack.oncancel + local oncancel = stack.oncancel local popup = LUI.MenuBuilder.BuildRegisteredType("waiting_popup", { - message_text = stack.text, - isLiveWithCancel = true, - cancel_func = function(...) - local args = {...} - oncancel() - LUI.FlowManager.RequestLeaveMenu(args[1]) - end + message_text = stack.text, + isLiveWithCancel = true, + cancel_func = function(...) + local args = {...} + oncancel() + LUI.FlowManager.RequestLeaveMenu(args[1]) + end }) - local listchildren = popup:getChildById("LUIHorizontalList"):getchildren() - local children = listchildren[2]:getchildren() - popup.text = children[2] + local listchildren = popup:getChildById("LUIHorizontalList"):getchildren() + local children = listchildren[2]:getchildren() + popup.text = children[2] - stack = { - ret = popup - } + stack = { + ret = popup + } - return popup + return popup end LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function() - local callback = stack.callback - local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", { - popup_title = stack.title, - message_text = stack.text, - yes_action = function() - callback(true) - end, - no_action = function() - callback(false) - end + local callback = stack.callback + local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", { + popup_title = stack.title, + message_text = stack.text, + yes_action = function() + callback(true) + end, + no_action = function() + callback(false) + end }) - stack = { - ret = popup - } + stack = { + ret = popup + } - return popup + return popup end LUI.MenuBuilder.m_types_build["generic_confirmation_popup_"] = function() - local popup = LUI.MenuBuilder.BuildRegisteredType( "generic_confirmation_popup", { - cancel_will_close = false, - popup_title = stack.title, - message_text = stack.text, - button_text = stack.buttontext, - confirmation_action = stack.callback - }) + local popup = LUI.MenuBuilder.BuildRegisteredType( "generic_confirmation_popup", { + cancel_will_close = false, + popup_title = stack.title, + message_text = stack.text, + button_text = stack.buttontext, + confirmation_action = stack.callback + }) - stack = { - ret = popup - } + stack = { + ret = popup + } - return stack.ret + return stack.ret end LUI.onmenuopen = function(name, callback) - if (not LUI.MenuBuilder.m_types_build[name]) then - return - end + if (not LUI.MenuBuilder.m_types_build[name]) then + return + end - if (not menucallbacks[name]) then - menucallbacks[name] = {} - end + if (not menucallbacks[name]) then + menucallbacks[name] = {} + end - table.insert(menucallbacks[name], callback) + table.insert(menucallbacks[name], callback) - if (not originalmenus[name]) then - originalmenus[name] = LUI.MenuBuilder.m_types_build[name] - LUI.MenuBuilder.m_types_build[name] = function(...) - local args = {...} - local menu = originalmenus[name](table.unpack(args)) + if (not originalmenus[name]) then + originalmenus[name] = LUI.MenuBuilder.m_types_build[name] + LUI.MenuBuilder.m_types_build[name] = function(...) + local args = {...} + local menu = originalmenus[name](table.unpack(args)) - for k, v in luiglobals.next, menucallbacks[name] do - v(menu, table.unpack(args)) - end + for k, v in luiglobals.next, menucallbacks[name] do + v(menu, table.unpack(args)) + end - return menu - end - end + return menu + end + end end local addoptionstextinfo = LUI.Options.AddOptionTextInfo LUI.Options.AddOptionTextInfo = function(menu) - local result = addoptionstextinfo(menu) - menu.optionTextInfo = result - return result + local result = addoptionstextinfo(menu) + menu.optionTextInfo = result + return result end LUI.addmenubutton = function(name, data) - LUI.onmenuopen(name, function(menu) - if (not menu.list) then - return - end + LUI.onmenuopen(name, function(menu) + if (not menu.list) then + return + end - local button = menu:AddButton(data.text, data.callback, nil, true, nil, { - desc_text = data.description - }) + local button = menu:AddButton(data.text, data.callback, nil, true, nil, { + desc_text = data.description + }) - local buttonlist = menu:getChildById(menu.type .. "_list") + local buttonlist = menu:getChildById(menu.type .. "_list") - if (data.id) then - button.id = data.id - end + if (data.id) then + button.id = data.id + end - if (data.index) then - buttonlist:removeElement(button) - buttonlist:insertElement(button, data.index) - end + if (data.index) then + buttonlist:removeElement(button) + buttonlist:insertElement(button, data.index) + end - local hintbox = menu.optionTextInfo - menu:removeElement(hintbox) + local hintbox = menu.optionTextInfo + menu:removeElement(hintbox) - LUI.Options.InitScrollingList(menu.list, nil) - menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) - end) + LUI.Options.InitScrollingList(menu.list, nil) + menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) + end) end LUI.openmenu = function(menu, args) - stack = args - LUI.FlowManager.RequestAddMenu(nil, menu) - return stack.ret + stack = args + LUI.FlowManager.RequestAddMenu(nil, menu) + return stack.ret end LUI.openpopupmenu = function(menu, args) - stack = args - LUI.FlowManager.RequestPopupMenu(nil, menu) - return stack.ret + stack = args + LUI.FlowManager.RequestPopupMenu(nil, menu) + return stack.ret end LUI.yesnopopup = function(data) - for k, v in luiglobals.next, data do - stack[k] = v - end - LUI.FlowManager.RequestPopupMenu(nil, "generic_yes_no_popup_") - return stack.ret + for k, v in luiglobals.next, data do + stack[k] = v + end + LUI.FlowManager.RequestPopupMenu(nil, "generic_yes_no_popup_") + return stack.ret end LUI.confirmationpopup = function(data) - for k, v in luiglobals.next, data do - stack[k] = v - end - LUI.FlowManager.RequestPopupMenu(nil, "generic_confirmation_popup_") - return stack.ret + for k, v in luiglobals.next, data do + stack[k] = v + end + LUI.FlowManager.RequestPopupMenu(nil, "generic_confirmation_popup_") + return stack.ret end function userdata_:getchildren() - local children = {} - local first = self:getFirstChild() + local children = {} + local first = self:getFirstChild() - while (first) do - table.insert(children, first) - first = first:getNextSibling() - end + while (first) do + table.insert(children, first) + first = first:getNextSibling() + end - return children + return children end From 373c0fa2bc3f36eef71c0622c4b18beb65418ba5 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 10 Mar 2022 01:30:03 +0100 Subject: [PATCH 060/346] Add stats menu --- data/ui_scripts/stats/__init__.lua | 226 ++++++++++++++++++++++++++ src/client/component/patches.cpp | 10 -- src/client/component/stats.cpp | 75 +++++++++ src/client/component/ui_scripting.cpp | 37 +++++ 4 files changed, 338 insertions(+), 10 deletions(-) create mode 100644 data/ui_scripts/stats/__init__.lua create mode 100644 src/client/component/stats.cpp diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua new file mode 100644 index 00000000..0aedc62a --- /dev/null +++ b/data/ui_scripts/stats/__init__.lua @@ -0,0 +1,226 @@ +if (game:issingleplayer()) then + return +end + +game:addlocalizedstring("LUA_MENU_STATS", "Stats") +game:addlocalizedstring("LUA_MENU_STATS_DESC", "Edit player stats settings.") + +game:addlocalizedstring("LUA_MENU_UNLOCKALL_ITEMS", "Unlock all items") +game:addlocalizedstring("LUA_MENU_UNLOCKALL_ITEMS_DESC", "Whether items should be locked based on the player's stats or always unlocked.") + +game:addlocalizedstring("LUA_MENU_UNLOCKALL_CLASSES", "Unlock all classes") +game:addlocalizedstring("LUA_MENU_UNLOCKALL_CLASSES_DESC", "Whether classes should be locked based on the player's stats or always unlocked.") + +game:addlocalizedstring("LUA_MENU_PRESTIGE", "Prestige") +game:addlocalizedstring("LUA_MENU_PRESTIGE_DESC", "Edit prestige level.") +game:addlocalizedstring("LUA_MENU_RANK", "Rank") +game:addlocalizedstring("LUA_MENU_RANK_DESC", "Edit rank.") + +game:addlocalizedstring("LUA_MENU_UNSAVED_CHANGES", "You have unsaved changes, are you sure you want to exit?") +game:addlocalizedstring("LUA_MENU_SAVE", "Save changes") +game:addlocalizedstring("LUA_MENU_SAVE_DESC", "Save changes.") +game:addlocalizedstring("LUA_MENU_SETTINGS", "Settings") +game:addlocalizedstring("LUA_MENU_EDIT_STATS", "Edit Stats") + +function createdivider(menu, text) + local element = LUI.UIElement.new( { + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + topAnchor = true, + bottomAnchor = false, + top = 0, + bottom = 33.33 + }) + + element.scrollingToNext = true + element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { + title_bar_text = Engine.ToUpperCase(Engine.Localize(text)) + })) + + menu.list:addElement(element) +end + +local personalizationbutton = LUI.MPLobbyBase.AddPersonalizationButton +LUI.MPLobbyBase.AddPersonalizationButton = function(menu) + personalizationbutton(menu) + menu:AddButton("@LUA_MENU_STATS", function() + LUI.FlowManager.RequestAddMenu(nil, "stats_menu") + end) +end + +LUI.MenuBuilder.registerType("stats_menu", function(a1) + local menu = LUI.MenuTemplate.new(a1, { + menu_title = Engine.ToUpperCase(Engine.Localize("@LUA_MENU_STATS")), + menu_list_divider_top_offset = -(LUI.H1MenuTab.tabChangeHoldingElementHeight + luiglobals.H1MenuDims.spacing), + menu_width = luiglobals.GenericMenuDims.OptionMenuWidth, + skipAnim = 0 ~= LUI.PCGraphicOptions.FindTypeIndex(LUI.PreviousMenuName) + }) + + createdivider(menu, "@LUA_MENU_SETTINGS") + + LUI.Options.CreateOptionButton( + menu, + "cg_unlockall_items", + "@LUA_MENU_UNLOCKALL_ITEMS", + "@LUA_MENU_UNLOCKALL_ITEMS_DESC", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + }, + nil, + nil + ) + + LUI.Options.CreateOptionButton( + menu, + "cg_unlockall_classes", + "@LUA_MENU_UNLOCKALL_CLASSES", + "@LUA_MENU_UNLOCKALL_CLASSES_DESC", + { + { + text = "@LUA_MENU_ENABLED", + value = true + }, + { + text = "@LUA_MENU_DISABLED", + value = false + } + }, + nil, + nil + ) + + createdivider(menu, "@LUA_MENU_EDIT_STATS") + + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 + local rank = luiglobals.Lobby.GetRankForXP(experience, prestige) + + local saved = true + local prestigevalue = prestige + local rankvalue = rank + local rankbutton = nil + + prestigeeditbutton(menu, function(value) + prestigevalue = value + saved = false + end) + + rankbutton = rankeditbutton(menu, function(value) + rankvalue = value + saved = false + end) + + local savebutton = menu:AddButton("@LUA_MENU_SAVE", function() + Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "prestige", tonumber(prestigevalue)) + + local rank = tonumber(rankvalue) + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local experience = rank == 0 and 0 or luiglobals.Rank.GetRankMaxXP(tonumber(rankvalue) - 1, prestige) + + Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "experience", experience) + + saved = true + end, nil, nil, nil, { + desc_text = Engine.Localize("LUA_MENU_SAVE_DESC") + }) + + LUI.Options.InitScrollingList(menu.list, nil) + LUI.Options.AddOptionTextInfo(menu) + + menu:AddBackButton(function() + if (saved) then + LUI.FlowManager.RequestLeaveMenu(menu) + return + end + + LUI.yesnopopup({ + title = Engine.Localize("@MENU_NOTICE"), + text = Engine.Localize("@LUA_MENU_UNSAVED_CHANGES"), + callback = function(result) + if (result) then + LUI.FlowManager.RequestLeaveMenu(menu) + end + end + }) + end) + + return menu +end) + +function prestigeeditbutton(menu, callback) + local options = {} + local max = luiglobals.Lobby.GetMaxPrestigeLevel() + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + + for i = 0, max do + game:addlocalizedstring("LUA_MENU_" .. i, i .. "") + + table.insert(options, { + text = "@" .. i, + value = i .. "" + }) + end + + Engine.SetDvarFromString("ui_prestige_level", prestige .. "") + + LUI.Options.CreateOptionButton( + menu, + "ui_prestige_level", + "@LUA_MENU_PRESTIGE", + "@LUA_MENU_PRESTIGE_DESC", + options, + nil, + nil, + callback + ) +end + +function rankeditbutton(menu, callback) + local options = {} + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 + + local rank = luiglobals.Lobby.GetRankForXP(experience, prestige) + local max = luiglobals.Rank.GetMaxRank(prestige) + local maxprestige = luiglobals.Lobby.GetMaxPrestigeLevel() + + for i = 0, max do + game:addlocalizedstring("LUA_MENU_" .. i, i .. "") + + table.insert(options, { + text = "@" .. (i + 1), + value = i .. "" + }) + end + + Engine.SetDvarFromString("ui_rank_level_", rank .. "") + + return LUI.Options.CreateOptionButton( + menu, + "ui_rank_level_", + "@LUA_MENU_RANK", + "@LUA_MENU_RANK_DESC", + options, + nil, + nil, + callback + ) +end + +local isclasslocked = luiglobals.Cac.IsCustomClassLocked +luiglobals.Cac.IsCustomClassLocked = function(...) + if (Engine.GetDvarBool("cg_unlockall_classes")) then + return false + end + + return isclasslocked(table.unpack({...})) +end diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 3d86b406..4498e272 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -65,11 +65,6 @@ namespace patches return com_register_dvars_hook.invoke(); } - int is_item_unlocked() - { - return 0; // 0 == yes - } - void set_client_dvar_from_server_stub(void* a1, void* a2, const char* dvar, const char* value) { if (dvar == "cg_fov"s || dvar == "cg_fovMin"s) @@ -214,11 +209,6 @@ namespace patches true); utils::hook::call(0x14009EE9E, aim_assist_add_to_target_list); - // unlock all items - utils::hook::jump(0x140413E60, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable_LocalClient - utils::hook::jump(0x140413860, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable - utils::hook::jump(0x140412B70, is_item_unlocked); // idk ( unlocks loot etc ) - // isProfanity utils::hook::set(0x1402877D0, 0xC3C033); diff --git a/src/client/component/stats.cpp b/src/client/component/stats.cpp new file mode 100644 index 00000000..8e238178 --- /dev/null +++ b/src/client/component/stats.cpp @@ -0,0 +1,75 @@ +#include +#include "loader/component_loader.hpp" + +#include "scheduler.hpp" +#include "dvars.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include + +namespace stats +{ + namespace + { + game::dvar_t* cg_unlock_all_items; + + utils::hook::detour is_item_unlocked_hook; + utils::hook::detour is_item_unlocked_hook2; + utils::hook::detour is_item_unlocked_hook3; + + int is_item_unlocked_stub(void* a1, void* a2, void* a3) + { + if (cg_unlock_all_items->current.enabled) + { + return 0; + } + + return is_item_unlocked_hook.invoke(a1, a2, a3); + } + + int is_item_unlocked_stub2(void* a1, void* a2, void* a3, void* a4, void* a5, void* a6) + { + if (cg_unlock_all_items->current.enabled) + { + return 0; + } + + return is_item_unlocked_hook2.invoke(a1, a2, a3, a4, a5, a6); + } + + int is_item_unlocked_stub3(void* a1) + { + if (cg_unlock_all_items->current.enabled) + { + return 0; + } + + return is_item_unlocked_hook3.invoke(a1); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (!game::environment::is_mp()) + { + return; + } + + cg_unlock_all_items = dvars::register_bool("cg_unlockall_items", false, game::DVAR_FLAG_SAVED, true); + dvars::register_bool("cg_unlockall_classes", false, game::DVAR_FLAG_SAVED, true); + + is_item_unlocked_hook.create(0x140413E60, is_item_unlocked_stub); + is_item_unlocked_hook2.create(0x140413860, is_item_unlocked_stub2); + is_item_unlocked_hook3.create(0x140412B70, is_item_unlocked_stub3); + } + }; +} + +REGISTER_COMPONENT(stats::component) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index 941dda10..d58079cc 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -28,6 +28,8 @@ namespace ui_scripting utils::hook::detour hks_shutdown_hook; utils::hook::detour hks_allocator_hook; utils::hook::detour hks_frame_hook; + utils::hook::detour lui_error_hook; + utils::hook::detour hksi_hks_error_hook; bool error_hook_enabled = false; @@ -52,6 +54,39 @@ namespace ui_scripting } } + int hksi_hks_error_stub(game::hks::lua_State* s, int a2) + { + if (!error_hook_enabled) + { + return hksi_hks_error_hook.invoke(s, a2); + } + else + { + throw std::runtime_error("unknown error"); + } + } + + int lui_error_stub(game::hks::lua_State* s) + { + if (!error_hook_enabled) + { + return lui_error_hook.invoke(s); + } + else + { + const auto count = static_cast(s->m_apistack.top - s->m_apistack.base); + const auto arguments = get_return_values(count); + + std::string error_str = "LUI Error"; + if (count && arguments[0].is()) + { + error_str = arguments[0].as(); + } + + throw std::runtime_error(error_str); + } + } + void* hks_start_stub(char a1) { const auto _1 = gsl::finally([]() @@ -162,6 +197,8 @@ namespace ui_scripting hksi_lual_error_hook.create(SELECT_VALUE(0x1400A5EA0, 0x14012F300), hksi_lual_error_stub); hks_allocator_hook.create(SELECT_VALUE(0x14009B570, 0x14012BAC0), hks_allocator_stub); hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), hks_frame_stub); + lui_error_hook.create(SELECT_VALUE(0x14007D7D0, 0x14010C9E0), lui_error_stub); + hksi_hks_error_hook.create(SELECT_VALUE(0x14009DD80, 0x14012E390), hksi_hks_error_stub); if (game::environment::is_mp()) { From 251bd9901ce81c5233a14c1053d770e52e3a2520 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 10 Mar 2022 01:38:34 +0100 Subject: [PATCH 061/346] Small fix --- data/ui_scripts/stats/__init__.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua index 0aedc62a..9ec572b7 100644 --- a/data/ui_scripts/stats/__init__.lua +++ b/data/ui_scripts/stats/__init__.lua @@ -53,9 +53,7 @@ end LUI.MenuBuilder.registerType("stats_menu", function(a1) local menu = LUI.MenuTemplate.new(a1, { menu_title = Engine.ToUpperCase(Engine.Localize("@LUA_MENU_STATS")), - menu_list_divider_top_offset = -(LUI.H1MenuTab.tabChangeHoldingElementHeight + luiglobals.H1MenuDims.spacing), menu_width = luiglobals.GenericMenuDims.OptionMenuWidth, - skipAnim = 0 ~= LUI.PCGraphicOptions.FindTypeIndex(LUI.PreviousMenuName) }) createdivider(menu, "@LUA_MENU_SETTINGS") From 000233454319fd0f739d0cf738cb3a8e2dd57d81 Mon Sep 17 00:00:00 2001 From: fed <58637860+fedddddd@users.noreply.github.com> Date: Thu, 10 Mar 2022 01:52:55 +0100 Subject: [PATCH 062/346] Fix broken english [skip ci] --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4e095ada..f835f69e 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,9 @@

-A experimental client for Modern Warfare Remaster (1.04). Latest MWR (1.15) version planned in future.
-[This project is using the S1x codebase.](https://github.com/XLabsProject/s1x-client) +An experimental client for Call of Duty Modern Warfare Remastered (version 1.04). +Support for the latest version (1.15) is planned for the future. +[This project is based on S1x.](https://github.com/XLabsProject/s1x-client) ## Compile from source From 89dd2a164b77872d8a272b35d0c2aedc1e9971b6 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 10 Mar 2022 20:51:59 +0100 Subject: [PATCH 063/346] Update function_tables.cpp --- src/client/game/scripting/function_tables.cpp | 633 +++++++++--------- 1 file changed, 324 insertions(+), 309 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 9a4d9663..48727e8b 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -47,7 +47,9 @@ namespace scripting {"setturretnode", 0x024}, // SP 0x1402CC640 MP 0x000000000 {"unsetturretnode", 0x025}, // SP 0x1402CC6E0 MP 0x000000000 {"setnodepriority", 0x026}, // SP 0x1402CC570 MP 0x000000000 - {"isnodeoccupied", 0x027}, // SP 0x1402CC430 MP 0x000000000 + {"_func_027", 0x027}, + {"_func_028", 0x028}, + {"isnodeoccupied", 0x029}, // SP 0x1402CC430 MP 0x000000000 {"setdebugorigin", 0x02A}, // SP 0x1405D92F0 MP 0x000000000 {"setdebugangles", 0x02B}, // SP 0x1405D92F0 MP 0x000000000 {"updategamerprofile", 0x02C}, // SP 0x1402ACD10 MP 0x000000000 @@ -74,9 +76,9 @@ namespace scripting {"getscreenwidth", 0x041}, // SP 0x1402A1D10 MP 0x000000000 {"getscreenheight", 0x042}, // SP 0x1402A1D20 MP 0x000000000 {"getweaponmodel", 0x043}, // SP 0x1402A1D30 MP 0x14036E110 - {"_func_044", 0x044}, // SP 0x1402ABBE0 MP 0x000000000 - {"_func_045", 0x045}, // SP 0x1402ABCF0 MP 0x000000000 - {"_func_046", 0x046}, // SP 0x1402ABD30 MP 0x000000000 + {"getculldist", 0x044}, // SP 0x1402ABBE0 MP 0x000000000 + {"sethalfresparticles", 0x045}, // SP 0x1402ABCF0 MP 0x000000000 + {"getmapsunlight", 0x046}, // SP 0x1402ABD30 MP 0x000000000 {"setsunlight", 0x047}, // SP 0x1402ABD90 MP 0x1403775E0 {"resetsunlight", 0x048}, // SP 0x1402ABE60 MP 0x140377840 {"getmapsundirection", 0x049}, // SP 0x1402ABF90 MP 0x000000000 @@ -136,6 +138,7 @@ namespace scripting {"soundresettimescale", 0x07F}, // SP 0x1402A8BB0 MP 0x000000000 {"levelsoundfade", 0x080}, // SP 0x1402A7A80 MP 0x000000000 {"precachenightvisioncodeassets", 0x081}, // SP 0x1402AAE30 MP 0x000000000 + {"_func_082", 0x082}, {"precachedigitaldistortcodeassets", 0x083}, // SP 0x1402AAE50 MP 0x000000000 {"precacheminimapsentrycodeassets", 0x084}, // SP 0x1402AAEA0 MP 0x000000000 {"savegame", 0x085}, // SP 0x1402A8CB0 MP 0x000000000 @@ -331,29 +334,29 @@ namespace scripting {"visionsetthermal", 0x143}, // SP 0x1402ABA00 MP 0x140376D40 {"visionsetpain", 0x144}, // SP 0x1402ABA10 MP 0x1403770E0 {"visionsetnight", 0x145}, // SP 0x1402ABA20 MP 0x140377160 - {"visionsetmissilecam", 0x146}, // SP 0x1402A12A0 MP 0x1403699C0 - {"_func_147", 0x147}, // SP 0x140298040 MP 0x14035F250 - {"_func_148", 0x148}, // SP 0x140298370 MP 0x14035F7A0 - {"_func_149", 0x149}, // SP 0x14029E7B0 MP 0x140366DA0 - {"_func_14A", 0x14A}, // SP 0x14029ECC0 MP 0x140366E30 - {"_func_14B", 0x14B}, // SP 0x14029F2B0 MP 0x1403673D0 - {"_func_14C", 0x14C}, // SP 0x14029F3E0 MP 0x140367540 - {"_func_14D", 0x14D}, // SP 0x14029F5B0 MP 0x1403675F0 - {"_func_14E", 0x14E}, // SP 0x1402982C0 MP 0x14035F470 - {"_func_14F", 0x14F}, // SP 0x14029EDB0 MP 0x1403670E0 + {"ambientstop", 0x146}, // SP 0x1402A12A0 MP 0x1403699C0 + {"precachemodel", 0x147}, // SP 0x140298040 MP 0x14035F250 + {"precacheshellshock", 0x148}, // SP 0x140298370 MP 0x14035F7A0 + {"precacheitem", 0x149}, // SP 0x14029E7B0 MP 0x140366DA0 + {"precacheshader", 0x14A}, // SP 0x14029ECC0 MP 0x140366E30 + {"precachestring", 0x14B}, // SP 0x14029F2B0 MP 0x1403673D0 + {"precachemenu", 0x14C}, // SP 0x14029F3E0 MP 0x140367540 + {"precacherumble", 0x14D}, // SP 0x14029F5B0 MP 0x1403675F0 + {"precachelocationselector", 0x14E}, // SP 0x1402982C0 MP 0x14035F470 + {"precacheleaderboards", 0x14F}, // SP 0x14029EDB0 MP 0x1403670E0 {"loadfx", 0x150}, // SP 0x140290A80 MP 0x1403583B0 {"playfx", 0x151}, // SP 0x140291730 MP 0x140359620 {"playfxontag", 0x152}, // SP 0x140292A40 MP 0x14035AF90 {"stopfxontag", 0x153}, // SP 0x140294440 MP 0x14035C4B0 - {"_func_154", 0x154}, // SP 0x140294DD0 MP 0x14035D560 + {"killfxontag", 0x154}, // SP 0x140294DD0 MP 0x14035D560 {"playloopedfx", 0x155}, // SP 0x140474350 MP 0x14037DA70 {"spawnfx", 0x156}, // SP 0x1404746B0 MP 0x14037E2D0 {"triggerfx", 0x157}, // SP 0x140474940 MP 0x14037E8B0 - {"_func_158", 0x158}, // SP 0x140292ED0 MP 0x14035B2B0 - {"_func_159", 0x159}, // SP 0x140474640 MP 0x14037E1D0 - {"_func_15A", 0x15A}, // SP 0x140293D50 MP 0x14035BFE0 - {"_func_15B", 0x15B}, // SP 0x000000000 MP 0x1403778C0 - {"_func_15C", 0x15C}, // SP 0x000000000 MP 0x140377920 + {"playfxontagforclients", 0x158}, // SP 0x140292ED0 MP 0x14035B2B0 + {"setfxkillondelete", 0x159}, // SP 0x140474640 MP 0x14037E1D0 + {"playimpactheadfatalfx", 0x15A}, // SP 0x140293D50 MP 0x14035BFE0 + {"setwinningteam", 0x15B}, // SP 0x000000000 MP 0x1403778C0 + {"announcement", 0x15C}, // SP 0x000000000 MP 0x140377920 {"clientannouncement", 0x15D}, // SP 0x000000000 MP 0x1403779A0 {"setteammode", 0x15E}, // SP 0x000000000 MP 0x140377A40 {"getteamscore", 0x15F}, // SP 0x000000000 MP 0x140377BE0 @@ -361,74 +364,74 @@ namespace scripting {"setclientnamemode", 0x161}, // SP 0x000000000 MP 0x140377D70 {"updateclientnames", 0x162}, // SP 0x000000000 MP 0x140377DC0 {"getteamplayersalive", 0x163}, // SP 0x000000000 MP 0x140377EB0 - {"_func_164", 0x164}, // SP 0x000000000 MP 0x140375460 - {"_func_165", 0x165}, // SP 0x000000000 MP 0x140375480 - {"_func_166", 0x166}, // SP 0x000000000 MP 0x1403754A0 - {"_func_167", 0x167}, // SP 0x000000000 MP 0x1403756D0 - {"_func_168", 0x168}, // SP 0x000000000 MP 0x1403759C0 - {"_func_169", 0x169}, // SP 0x000000000 MP 0x1403760D0 - {"_func_16A", 0x16A}, // SP 0x14029F100 MP 0x1403673A0 - {"_func_16B", 0x16B}, // SP 0x000000000 MP 0x140376BE0 - {"_func_16C", 0x16C}, // SP 0x000000000 MP 0x140376C60 + {"logprint", 0x164}, // SP 0x000000000 MP 0x140375460 + {"worldentnumber", 0x165}, // SP 0x000000000 MP 0x140375480 + {"obituary", 0x166}, // SP 0x000000000 MP 0x1403754A0 + {"positionwouldtelefrag", 0x167}, // SP 0x000000000 MP 0x1403756D0 + {"canspawn", 0x168}, // SP 0x000000000 MP 0x1403759C0 + {"getstarttime", 0x169}, // SP 0x000000000 MP 0x1403760D0 + {"precacheheadicon", 0x16A}, // SP 0x14029F100 MP 0x1403673A0 + {"precacheminimapicon", 0x16B}, // SP 0x000000000 MP 0x140376BE0 + {"precachempanim", 0x16C}, // SP 0x000000000 MP 0x140376C60 {"map_restart", 0x16D}, // SP 0x000000000 MP 0x140376550 {"exitlevel", 0x16E}, // SP 0x000000000 MP 0x140376630 - {"_func_16F", 0x16F}, // SP 0x000000000 MP 0x140376680 + {"addtestclient", 0x16F}, // SP 0x000000000 MP 0x140376680 {"addagent", 0x170}, // SP 0x000000000 MP 0x140376860 - {"_func_171", 0x171}, // SP 0x000000000 MP 0x140378020 - {"_func_172", 0x172}, // SP 0x000000000 MP 0x140376880 - {"_func_173", 0x173}, // SP 0x000000000 MP 0x140376B60 + {"setarchive", 0x171}, // SP 0x000000000 MP 0x140378020 + {"allclientsprint", 0x172}, // SP 0x000000000 MP 0x140376880 + {"clientprint", 0x173}, // SP 0x000000000 MP 0x140376B60 {"mapexists", 0x174}, // SP 0x000000000 MP 0x140376910 {"isvalidgametype", 0x175}, // SP 0x000000000 MP 0x140376950 - {"_func_176", 0x176}, // SP 0x000000000 MP 0x140378040 + {"matchend", 0x176}, // SP 0x000000000 MP 0x140378040 {"setplayerteamrank", 0x177}, // SP 0x000000000 MP 0x140378050 - {"_func_178", 0x178}, // SP 0x000000000 MP 0x140378100 + {"endparty", 0x178}, // SP 0x000000000 MP 0x140378100 {"setteamradar", 0x179}, // SP 0x000000000 MP 0x14037B5D0 {"getteamradar", 0x17A}, // SP 0x000000000 MP 0x14037B640 {"setteamradarstrength", 0x17B}, // SP 0x000000000 MP 0x14037B6A0 {"getteamradarstrength", 0x17C}, // SP 0x000000000 MP 0x14037B720 {"getuavstrengthmin", 0x17D}, // SP 0x000000000 MP 0x14037B780 - {"_func_17E", 0x17E}, // SP 0x140295500 MP 0x14035E730 - {"physicsexplosionsphere", 0x17F}, // SP 0x140296890 MP 0x14035FE90 - {"physicsradiusjolt", 0x180}, // SP 0x140295F60 MP 0x14035F2D0 - {"physicsradiusjitter", 0x181}, // SP 0x1402963A0 MP 0x14035F900 - {"_func_182", 0x182}, // SP 0x140299880 MP 0x140362E20 - {"_func_183", 0x183}, // SP 0x140299900 MP 0x140363010 - {"_func_184", 0x184}, // SP 0x140299F70 MP 0x140363800 - {"_func_185", 0x185}, // SP 0x14029A180 MP 0x140363920 - {"_func_186", 0x186}, // SP 0x14029A220 MP 0x140363B00 - {"_func_187", 0x187}, // SP 0x14029A4B0 MP 0x140363E60 + {"physicsexplosionsphere", 0x17E}, // SP 0x140295500 MP 0x14035E730 + {"physicsexplosioncylinder", 0x17F}, // SP 0x140296890 MP 0x14035FE90 + {"physicsjolt", 0x180}, // SP 0x140295F60 MP 0x14035F2D0 + {"physicsjitter", 0x181}, // SP 0x1402963A0 MP 0x14035F900 + {"setexpfog", 0x182}, // SP 0x140299880 MP 0x140362E20 + {"setexpfogext", 0x183}, // SP 0x140299900 MP 0x140363010 + {"setexpfogdvarsonly", 0x184}, // SP 0x140299F70 MP 0x140363800 + {"setexpfogextdvarsonly", 0x185}, // SP 0x14029A180 MP 0x140363920 + {"setatmosfog", 0x186}, // SP 0x14029A220 MP 0x140363B00 + {"setatmosfogdvarsonly", 0x187}, // SP 0x14029A4B0 MP 0x140363E60 {"isexplosivedamagemod", 0x188}, // SP 0x1402A2800 MP 0x14036ADB0 {"radiusdamage", 0x189}, // SP 0x1402A3690 MP 0x14036C110 {"setplayerignoreradiusdamage", 0x18A}, // SP 0x14028DFA0 MP 0x14036CF90 - {"_func_18B", 0x18B}, // SP 0x1402A3950 MP 0x14036C1E0 - {"_func_18C", 0x18C}, // SP 0x14029B460 MP 0x140366A00 + {"glassradiusdamage", 0x18B}, // SP 0x1402A3950 MP 0x14036C1E0 + {"earthquake", 0x18C}, // SP 0x14029B460 MP 0x140366A00 {"getnumparts", 0x18D}, // SP 0x14029A830 MP 0x140363F40 - {"_func_18E", 0x18E}, // SP 0x1402B76D0 MP 0x140383170 - {"_func_18F", 0x18F}, // SP 0x000000000 MP 0x1403831D0 + {"objective_onentity", 0x18E}, // SP 0x1402B76D0 MP 0x140383170 + {"objective_onentitywithrotation", 0x18F}, // SP 0x000000000 MP 0x1403831D0 {"objective_team", 0x190}, // SP 0x000000000 MP 0x140383310 {"objective_player", 0x191}, // SP 0x000000000 MP 0x1403833B0 - {"_func_192", 0x192}, // SP 0x000000000 MP 0x140383410 - {"_func_193", 0x193}, // SP 0x000000000 MP 0x1403834B0 - {"_func_194", 0x194}, // SP 0x000000000 MP 0x1403835B0 - {"_func_195", 0x195}, // SP 0x000000000 MP 0x1403835F0 + {"objective_playerteam", 0x192}, // SP 0x000000000 MP 0x140383410 + {"objective_playerenemyteam", 0x193}, // SP 0x000000000 MP 0x1403834B0 + {"objective_playermask_hidefromall", 0x194}, // SP 0x000000000 MP 0x1403835B0 + {"objective_playermask_hidefrom", 0x195}, // SP 0x000000000 MP 0x1403835F0 {"objective_playermask_showtoall", 0x196}, // SP 0x000000000 MP 0x140382DA0 - {"_func_197", 0x197}, // SP 0x000000000 MP 0x140382DE0 - {"_func_198", 0x198}, // SP 0x1402AD860 MP 0x140377360 - {"_func_199", 0x199}, // SP 0x1402AD8C0 MP 0x1403773E0 - {"_func_19A", 0x19A}, // SP 0x1405D92F0 MP 0x140377C30 + {"objective_playermask_showto", 0x197}, // SP 0x000000000 MP 0x140382DE0 + {"iprintln", 0x198}, // SP 0x1402AD860 MP 0x140377360 + {"iprintlnbold", 0x199}, // SP 0x1402AD8C0 MP 0x1403773E0 + {"logstring", 0x19A}, // SP 0x1405D92F0 MP 0x140377C30 {"getent", 0x19B}, // SP 0x1402B9570 MP 0x1403845D0 {"getentarray", 0x19C}, // SP 0x1402B95E0 MP 0x1403846A0 - {"_func_19D", 0x19D}, // SP 0x000000000 MP 0x140384C00 + {"getspawnarray", 0x19D}, // SP 0x000000000 MP 0x140384C00 {"spawnplane", 0x19E}, // SP 0x000000000 MP 0x140377670 {"spawnstruct", 0x19F}, // SP 0x140374110 MP 0x140442170 - {"_func_1A0", 0x1A0}, // SP 0x000000000 MP 0x140377A90 + {"spawnhelicopter", 0x1A0}, // SP 0x000000000 MP 0x140377A90 {"isalive", 0x1A1}, // SP 0x1402AD940 MP 0x140377410 {"isspawner", 0x1A2}, // SP 0x1402ADB20 MP 0x1403774F0 - {"_func_1A3", 0x1A3}, // SP 0x140282D00 MP 0x14034F8E0 - {"missile_createattractorent", 0x1A4}, // SP 0x140282D10 MP 0x14034F8F0 - {"missile_createattractororigin", 0x1A5}, // SP 0x140282FD0 MP 0x14034FBA0 - {"_func_1A6", 0x1A6}, // SP 0x140282FE0 MP 0x14034FBB0 - {"_func_1A7", 0x1A7}, // SP 0x140282FF0 MP 0x14034FBC0 + {"missile_createattractorent", 0x1A3}, // SP 0x140282D00 MP 0x14034F8E0 + {"missile_createattractororigin", 0x1A4}, // SP 0x140282D10 MP 0x14034F8F0 + {"missile_createrepulsorent", 0x1A5}, // SP 0x140282FD0 MP 0x14034FBA0 + {"missile_createrepulsororigin", 0x1A6}, // SP 0x140282FE0 MP 0x14034FBB0 + {"missile_deleteattractor", 0x1A7}, // SP 0x140282FF0 MP 0x14034FBC0 {"playsoundatpos", 0x1A8}, // SP 0x000000000 MP 0x140378150 {"newhudelem", 0x1A9}, // SP 0x14026F000 MP 0x14033CF50 {"newclienthudelem", 0x1AA}, // SP 0x14026EFB0 MP 0x14033CEF0 @@ -437,80 +440,80 @@ namespace scripting {"isplayer", 0x1AD}, // SP 0x1402ADB90 MP 0x140377390 {"isplayernumber", 0x1AE}, // SP 0x000000000 MP 0x1403774C0 {"getpartname", 0x1AF}, // SP 0x14029A9A0 MP 0x140364120 - {"_func_1B0", 0x1B0}, // SP 0x14029CDC0 MP 0x140363D50 - {"_func_1B1", 0x1B1}, // SP 0x1402999A0 MP 0x140360B10 - {"_func_1B2", 0x1B2}, // SP 0x14029AA30 MP 0x140361AC0 - {"_func_1B3", 0x1B3}, // SP 0x14029ADB0 MP 0x140361CE0 - {"_func_1B4", 0x1B4}, // SP 0x14029B360 MP 0x1403622D0 - {"_func_1B5", 0x1B5}, // SP 0x14029B580 MP 0x140362520 - {"_func_1B6", 0x1B6}, // SP 0x14029B020 MP 0x140361EC0 - {"_func_1B7", 0x1B7}, // SP 0x14029B7A0 MP 0x140362920 + {"weaponfiretime", 0x1B0}, // SP 0x14029CDC0 MP 0x140363D50 + {"weaponclipsize", 0x1B1}, // SP 0x1402999A0 MP 0x140360B10 + {"weaponisauto", 0x1B2}, // SP 0x14029AA30 MP 0x140361AC0 + {"weaponissemiauto", 0x1B3}, // SP 0x14029ADB0 MP 0x140361CE0 + {"weaponisboltaction", 0x1B4}, // SP 0x14029B360 MP 0x1403622D0 + {"weaponinheritsperks", 0x1B5}, // SP 0x14029B580 MP 0x140362520 + {"weaponburstcount", 0x1B6}, // SP 0x14029B020 MP 0x140361EC0 + {"weapontype", 0x1B7}, // SP 0x14029B7A0 MP 0x140362920 {"weaponclass", 0x1B8}, // SP 0x14029B8E0 MP 0x140362A60 {"getnextarraykey", 0x1B9}, // SP 0x1402A35D0 MP 0x14036D000 - {"_func_1BA", 0x1BA}, // SP 0x14028D850 MP 0x14036D690 - {"_func_1BB", 0x1BB}, // SP 0x14029CCC0 MP 0x1403664F0 - {"tablelookupistringbyrow", 0x1BC}, // SP 0x14029D970 MP 0x1403671B0 - {"_func_1BD", 0x1BD}, // SP 0x14029CF50 MP 0x1403667F0 - {"tablelookuprownum", 0x1BE}, // SP 0x14029DC10 MP 0x140367320 - {"_func_1BF", 0x1BF}, // SP 0x14029D280 MP 0x140366C90 + {"sortbydistance", 0x1BA}, // SP 0x14028D850 MP 0x14036D690 + {"tablelookup", 0x1BB}, // SP 0x14029CCC0 MP 0x1403664F0 + {"tablelookupbyrow", 0x1BC}, // SP 0x14029D970 MP 0x1403671B0 + {"tablelookupistring", 0x1BD}, // SP 0x14029CF50 MP 0x1403667F0 + {"tablelookupistringbyrow", 0x1BE}, // SP 0x14029DC10 MP 0x140367320 + {"tablelookuprownum", 0x1BF}, // SP 0x14029D280 MP 0x140366C90 {"tableexists", 0x1C0}, // SP 0x14029D820 MP 0x140366DE0 {"getmissileowner", 0x1C1}, // SP 0x14029AD10 MP 0x140366490 - {"_func_1C2", 0x1C2}, // SP 0x140294EF0 MP 0x14035E270 + {"magicbullet", 0x1C2}, // SP 0x140294EF0 MP 0x14035E270 {"getweaponflashtagname", 0x1C3}, // SP 0x140295DC0 MP 0x14035F290 {"averagepoint", 0x1C4}, // SP 0x14029A870 MP 0x140363F90 - {"_func_1C5", 0x1C5}, // SP 0x14029AB60 MP 0x140364300 - {"getspawnerarray", 0x1C6}, // SP 0x140466C40 MP 0x140564030 + {"averagenormal", 0x1C5}, // SP 0x14029AB60 MP 0x140364300 + {"vehicle_getspawnerarray", 0x1C6}, // SP 0x140466C40 MP 0x140564030 {"playrumbleonposition", 0x1C7}, // SP 0x140299410 MP 0x140360540 {"playrumblelooponposition", 0x1C8}, // SP 0x140299470 MP 0x1403605E0 - {"_func_1C9", 0x1C9}, // SP 0x1402996F0 MP 0x140360670 + {"stopallrumbles", 0x1C9}, // SP 0x1402996F0 MP 0x140360670 {"soundexists", 0x1CA}, // SP 0x140290B30 MP 0x14035C2D0 - {"_func_1CB", 0x1CB}, // SP 0x1405D92F0 MP 0x14036B580 - {"_func_1CC", 0x1CC}, // SP 0x1405D92F0 MP 0x14036B590 - {"_func_1CD", 0x1CD}, // SP 0x1405D92F0 MP 0x14036B710 - {"_func_1CE", 0x1CE}, // SP 0x1405D92F0 MP 0x14036B770 - {"_func_1CF", 0x1CF}, // SP 0x1405D92F0 MP 0x14036B780 - {"_func_1D0", 0x1D0}, // SP 0x1405D92F0 MP 0x14036B790 + {"openfile", 0x1CB}, // SP 0x1405D92F0 MP 0x14036B580 + {"closefile", 0x1CC}, // SP 0x1405D92F0 MP 0x14036B590 + {"fprintln", 0x1CD}, // SP 0x1405D92F0 MP 0x14036B710 + {"fprintfields", 0x1CE}, // SP 0x1405D92F0 MP 0x14036B770 + {"freadln", 0x1CF}, // SP 0x1405D92F0 MP 0x14036B780 + {"fgetarg", 0x1D0}, // SP 0x1405D92F0 MP 0x14036B790 {"setminimap", 0x1D1}, // SP 0x1402A2200 MP 0x14036C3C0 - {"_func_1D2", 0x1D2}, // SP 0x1402A28F0 MP 0x14036CA90 - {"_func_1D3", 0x1D3}, // SP 0x1402A3410 MP 0x14036CDA0 + {"setthermalbodymaterial", 0x1D2}, // SP 0x1402A28F0 MP 0x14036CA90 + {"getarraykeys", 0x1D3}, // SP 0x1402A3410 MP 0x14036CDA0 {"getfirstarraykey", 0x1D4}, // SP 0x1402A3470 MP 0x14036CF00 {"getglass", 0x1D5}, // SP 0x14029AD60 MP 0x1403644F0 {"getglassarray", 0x1D6}, // SP 0x14029B110 MP 0x1403647D0 {"getglassorigin", 0x1D7}, // SP 0x14029B410 MP 0x1403649E0 {"isglassdestroyed", 0x1D8}, // SP 0x14029B630 MP 0x140364CF0 {"destroyglass", 0x1D9}, // SP 0x14029B850 MP 0x140365010 - {"_func_1DA", 0x1DA}, // SP 0x14029B9F0 MP 0x1403651E0 - {"_func_1DB", 0x1DB}, // SP 0x14029C0E0 MP 0x140365F50 - {"_func_1DC", 0x1DC}, // SP 0x14029C160 MP 0x140366130 + {"deleteglass", 0x1DA}, // SP 0x14029B9F0 MP 0x1403651E0 + {"getentchannelscount", 0x1DB}, // SP 0x14029C0E0 MP 0x140365F50 + {"getentchannelname", 0x1DC}, // SP 0x14029C160 MP 0x140366130 {"objective_add", 0x1DD}, // SP 0x1402B7080 MP 0x140382E50 - {"_func_1DE", 0x1DE}, // SP 0x1402B74F0 MP 0x140382F80 + {"objective_delete", 0x1DE}, // SP 0x1402B74F0 MP 0x140382F80 {"objective_state", 0x1DF}, // SP 0x1402B77E0 MP 0x140382FF0 {"objective_icon", 0x1E0}, // SP 0x1402B7820 MP 0x140383090 - {"_func_1E1", 0x1E1}, // SP 0x1402B7900 MP 0x000000000 + {"objective_indentlevel", 0x1E1}, // SP 0x1402B7900 MP 0x000000000 {"objective_position", 0x1E2}, // SP 0x1402B7980 MP 0x1403830D0 {"objective_current", 0x1E3}, // SP 0x1402B7A10 MP 0x140383230 - {"_func_1E4", 0x1E4}, // SP 0x14029BA70 MP 0x140362C20 - {"_func_1E5", 0x1E5}, // SP 0x14029BE70 MP 0x140362F00 - {"_func_1E6", 0x1E6}, // SP 0x14029BF80 MP 0x140363300 - {"_func_1E7", 0x1E7}, // SP 0x14029C9D0 MP 0x140363950 + {"weaponinventorytype", 0x1E4}, // SP 0x14029BA70 MP 0x140362C20 + {"weaponstartammo", 0x1E5}, // SP 0x14029BE70 MP 0x140362F00 + {"weaponmaxammo", 0x1E6}, // SP 0x14029BF80 MP 0x140363300 + {"weaponaltweaponname", 0x1E7}, // SP 0x14029C9D0 MP 0x140363950 {"isweaponcliponly", 0x1E8}, // SP 0x14029D050 MP 0x140364220 - {"_func_1E9", 0x1E9}, // SP 0x14029D330 MP 0x140364590 - {"_func_1EA", 0x1EA}, // SP 0x14029D720 MP 0x140364870 - {"_func_1EB", 0x1EB}, // SP 0x14029D9F0 MP 0x140364E70 - {"_func_1EC", 0x1EC}, // SP 0x14045D5C0 MP 0x14055A900 + {"isweapondetonationtimed", 0x1E9}, // SP 0x14029D330 MP 0x140364590 + {"isweaponmanuallydetonatedbyemptythrow", 0x1EA}, // SP 0x14029D720 MP 0x140364870 + {"weaponhasthermalscope", 0x1EB}, // SP 0x14029D9F0 MP 0x140364E70 + {"getvehiclenode", 0x1EC}, // SP 0x14045D5C0 MP 0x14055A900 {"getvehiclenodearray", 0x1ED}, // SP 0x14045D6B0 MP 0x14055A9F0 - {"_func_1EE", 0x1EE}, // SP 0x14045D550 MP 0x14055A890 - {"_func_1EF", 0x1EF}, // SP 0x1404669B0 MP 0x140563DA0 - {"_func_1F0", 0x1F0}, // SP 0x140466CC0 MP 0x140564110 + {"getallvehiclenodes", 0x1EE}, // SP 0x14045D550 MP 0x14055A890 + {"getnumvehicles", 0x1EF}, // SP 0x1404669B0 MP 0x140563DA0 + {"precachevehicle", 0x1F0}, // SP 0x140466CC0 MP 0x140564110 {"spawnvehicle", 0x1F1}, // SP 0x140466D20 MP 0x140564170 {"vehicle_getarray", 0x1F2}, // SP 0x1404669F0 MP 0x140563DE0 {"pow", 0x1F3}, // SP 0x14028E710 MP 0x14036CBC0 - {"_func_1F4", 0x1F4}, // SP 0x14028D7B0 MP 0x14036BB10 + {"atan2", 0x1F4}, // SP 0x14028D7B0 MP 0x14036BB10 {"botgetmemoryevents", 0x1F5}, // SP 0x000000000 MP 0x14047A600 {"botautoconnectenabled", 0x1F6}, // SP 0x000000000 MP 0x14047ABF0 {"botzonegetcount", 0x1F7}, // SP 0x000000000 MP 0x14047AC20 {"botzonesetteam", 0x1F8}, // SP 0x000000000 MP 0x14047AF10 - {"_func_1F9", 0x1F9}, // SP 0x000000000 MP 0x14047AD50 + {"botzonenearestcount", 0x1F9}, // SP 0x000000000 MP 0x14047AD50 {"botmemoryflags", 0x1FA}, // SP 0x000000000 MP 0x14047A940 {"botflagmemoryevents", 0x1FB}, // SP 0x000000000 MP 0x14047A320 {"botzonegetindoorpercent", 0x1FC}, // SP 0x000000000 MP 0x14047ACF0 @@ -518,240 +521,252 @@ namespace scripting {"isbot", 0x1FE}, // SP 0x000000000 MP 0x14047AF70 {"isagent", 0x1FF}, // SP 0x000000000 MP 0x14037B2B0 {"getmaxagents", 0x200}, // SP 0x000000000 MP 0x140450E50 - {"_func_201", 0x201}, // SP 0x000000000 MP 0x14047A310 + {"botdebugdrawtrigger", 0x201}, // SP 0x000000000 MP 0x14047A310 {"botgetclosestnavigablepoint", 0x202}, // SP 0x000000000 MP 0x14047A550 {"getnodesintrigger", 0x203}, // SP 0x000000000 MP 0x14031FCE0 {"nodesvisible", 0x204}, // SP 0x1402CC4A0 MP 0x140320EA0 - {"_func_205", 0x205}, // SP 0x1402CC110 MP 0x14031FDD0 - {"_func_206", 0x206}, // SP 0x000000000 MP 0x1403201B0 + {"getnodesonpath", 0x205}, // SP 0x1402CC110 MP 0x14031FDD0 + {"getzonecount", 0x206}, // SP 0x000000000 MP 0x1403201B0 {"getzonenearest", 0x207}, // SP 0x000000000 MP 0x1403201C0 - {"_func_208", 0x208}, // SP 0x000000000 MP 0x140320320 - {"_func_209", 0x209}, // SP 0x000000000 MP 0x140320A10 - {"_func_20A", 0x20A}, // SP 0x000000000 MP 0x140320960 + {"getzonenodes", 0x208}, // SP 0x000000000 MP 0x140320320 + {"getzonepath", 0x209}, // SP 0x000000000 MP 0x140320A10 + {"getzoneorigin", 0x20A}, // SP 0x000000000 MP 0x140320960 {"getnodezone", 0x20B}, // SP 0x000000000 MP 0x14031FC20 - {"_func_20C", 0x20C}, // SP 0x000000000 MP 0x140320600 + {"getzonenodesbydist", 0x20C}, // SP 0x000000000 MP 0x140320600 {"getzonenodeforindex", 0x20D}, // SP 0x000000000 MP 0x1403202E0 - {"_func_20E", 0x20E}, // SP 0x1402AFFC0 MP 0x14037AE40 - {"_func_211", 0x211}, // SP 0x000000000 MP 0x140320C70 + {"getweaponexplosionradius", 0x20E}, // SP 0x1402AFFC0 MP 0x14037AE40 + {"markdangerousnodes", 0x20F}, + {"markdangerousnodesintrigger", 0x210}, + {"nodeexposedtosky", 0x211}, // SP 0x000000000 MP 0x140320C70 {"findentrances", 0x212}, // SP 0x000000000 MP 0x14031F6F0 {"badplace_global", 0x213}, // SP 0x000000000 MP 0x14035A190 - {"_func_214", 0x214}, // SP 0x000000000 MP 0x140375150 - {"_func_215", 0x215}, // SP 0x1402CBE10 MP 0x14031F940 + {"getpathdist", 0x214}, // SP 0x000000000 MP 0x140375150 + {"getlinkednodes", 0x215}, // SP 0x1402CBE10 MP 0x14031F940 {"disconnectnodepair", 0x216}, // SP 0x14028E840 MP 0x14036F800 {"connectnodepair", 0x217}, // SP 0x14028EAC0 MP 0x140357F30 - {"_func_218", 0x218}, // SP 0x1402AE000 MP 0x000000000 - {"_func_21B", 0x21B}, // SP 0x1405D92F0 MP 0x1403780E0 - {"_func_21C", 0x21C}, // SP 0x000000000 MP 0x140374FD0 - {"_func_21D", 0x21D}, // SP 0x14037AA30 MP 0x000000000 - {"_func_21E", 0x21E}, // SP 0x14037AC70 MP 0x000000000 - {"_func_21F", 0x21F}, // SP 0x14037ABB0 MP 0x000000000 - {"_func_220", 0x220}, // SP 0x14037AB50 MP 0x000000000 - {"_func_221", 0x221}, // SP 0x14037A730 MP 0x000000000 - {"_func_222", 0x222}, // SP 0x14037A7B0 MP 0x000000000 - {"_func_223", 0x223}, // SP 0x14037A760 MP 0x000000000 - {"_func_224", 0x224}, // SP 0x14037A7F0 MP 0x000000000 + {"gettimesincelastpaused", 0x218}, // SP 0x1402AE000 MP 0x000000000 + {"precachefxontag", 0x219}, + {"precachetag", 0x21A}, + {"precachesound", 0x21B}, // SP 0x1405D92F0 MP 0x1403780E0 + {"devsetminimapdvarsettings", 0x21C}, // SP 0x000000000 MP 0x140374FD0 + {"loadtransient", 0x21D}, // SP 0x14037AA30 MP 0x000000000 + {"unloadtransient", 0x21E}, // SP 0x14037AC70 MP 0x000000000 + {"unloadalltransients", 0x21F}, // SP 0x14037ABB0 MP 0x000000000 + {"synctransients", 0x220}, // SP 0x14037AB50 MP 0x000000000 + {"aretransientsbusy", 0x221}, // SP 0x14037A730 MP 0x000000000 + {"istransientqueued", 0x222}, // SP 0x14037A7B0 MP 0x000000000 + {"istransientloaded", 0x223}, // SP 0x14037A760 MP 0x000000000 + {"loadstartpointtransient", 0x224}, // SP 0x14037A7F0 MP 0x000000000 {"distance2dsquared", 0x225}, // SP 0x1402914F0 MP 0x140357BF0 {"getangledelta3d", 0x226}, // SP 0x14028FE10 MP 0x14036F1C0 {"activateclientexploder", 0x227}, // SP 0x140290710 MP 0x14035B7B0 - {"_func_228", 0x228}, // SP 0x1402909E0 MP 0x14035CED0 - {"_func_229", 0x229}, // SP 0x140290DF0 MP 0x14035D200 + {"trajectorycalculateinitialvelocity", 0x228}, // SP 0x1402909E0 MP 0x14035CED0 + {"trajectorycalculateminimumvelocity", 0x229}, // SP 0x140290DF0 MP 0x14035D200 {"trajectorycalculateexitangle", 0x22A}, // SP 0x140290FA0 MP 0x14035D4C0 - {"_func_22B", 0x22B}, // SP 0x1402911D0 MP 0x14035D830 + {"trajectoryestimatedesiredinairtime", 0x22B}, // SP 0x1402911D0 MP 0x14035D830 {"trajectorycomputedeltaheightattime", 0x22C}, // SP 0x140291530 MP 0x14035DFB0 - {"trajectoryestimatedesiredinairtime", 0x22D}, // SP 0x140291910 MP 0x14035E0B0 - {"_func_22E", 0x22E}, // SP 0x1405D92F0 MP 0x140367D60 + {"trajectorycanattemptaccuratejump", 0x22D}, // SP 0x140291910 MP 0x14035E0B0 + {"adddebugcommand", 0x22E}, // SP 0x1405D92F0 MP 0x140367D60 {"ispointinvolume", 0x22F}, // SP 0x140291190 MP 0x14036F5A0 - {"_func_230", 0x230}, // SP 0x1402AB600 MP 0x000000000 - {"_func_231", 0x231}, // SP 0x1402AB4F0 MP 0x000000000 - {"_func_232", 0x232}, // SP 0x1402AB4D0 MP 0x000000000 - {"_func_234", 0x234}, // SP 0x1405D92F0 MP 0x1403605D0 + {"cinematicgettimeinmsec", 0x230}, // SP 0x1402AB600 MP 0x000000000 + {"cinematicgetframe", 0x231}, // SP 0x1402AB4F0 MP 0x000000000 + {"iscinematicloaded", 0x232}, // SP 0x1402AB4D0 MP 0x000000000 + {"bbprint", 0x233}, + {"getenemysquaddata", 0x234}, // SP 0x1405D92F0 MP 0x1403605D0 + {"lookupsoundlength", 0x235}, {"getscriptablearray", 0x236}, // SP 0x140294380 MP 0x140360720 - {"_func_237", 0x237}, // SP 0x140297840 MP 0x140360C40 - {"_func_238", 0x238}, // SP 0x1402A87C0 MP 0x14037B1D0 - {"_func_239", 0x239}, // SP 0x1402AA280 MP 0x000000000 - {"_func_23A", 0x23A}, // SP 0x140292220 MP 0x14035E710 - {"_func_23B", 0x23B}, // SP 0x140292220 MP 0x14035E860 - {"_func_23D", 0x23D}, // SP 0x1402A06D0 MP 0x1403686B0 - {"_func_23E", 0x23E}, // SP 0x1402A0900 MP 0x140368C00 - {"_func_23F", 0x23F}, // SP 0x14029DDC0 MP 0x140365220 - {"_func_240", 0x240}, // SP 0x14029DDC0 MP 0x140365440 - {"_func_241", 0x241}, // SP 0x1402ACD00 MP 0x140365460 - {"_func_242", 0x242}, // SP 0x1402ACD00 MP 0x140365470 - {"_func_243", 0x243}, // SP 0x1402ACD00 MP 0x140365630 - {"_func_244", 0x244}, // SP 0x000000000 MP 0x1403784C0 - {"_func_245", 0x245}, // SP 0x140292D40 MP 0x14035FAF0 - {"_func_246", 0x246}, // SP 0x000000000 MP 0x1403784E0 - {"_func_247", 0x247}, // SP 0x000000000 MP 0x140378DA0 - {"_func_248", 0x248}, // SP 0x000000000 MP 0x140378DB0 - {"_func_249", 0x249}, // SP 0x000000000 MP 0x140378DC0 - {"_func_24A", 0x24A}, // SP 0x1402A8F70 MP 0x000000000 - {"_func_24B", 0x24B}, // SP 0x1402A8FF0 MP 0x000000000 - {"_func_24C", 0x24C}, // SP 0x1402946A0 MP 0x14035ABF0 - {"_func_24D", 0x24D}, // SP 0x140290110 MP 0x14036DF90 - {"_func_24E", 0x24E}, // SP 0x140292B00 MP 0x140359490 - {"_func_24F", 0x24F}, // SP 0x1402ABB80 MP 0x000000000 - {"_func_250", 0x250}, // SP 0x1405D92F0 MP 0x140360370 - {"_func_251", 0x251}, // SP 0x1405D92F0 MP 0x1403604B0 - {"_func_252", 0x252}, // SP 0x1405D92F0 MP 0x140360530 - {"_func_253", 0x253}, // SP 0x140293F90 MP 0x14035A6C0 - {"_func_254", 0x254}, // SP 0x140293FF0 MP 0x14035A7C0 - {"_func_255", 0x255}, // SP 0x140294500 MP 0x14035A9F0 - {"_func_256", 0x256}, // SP 0x000000000 MP 0x1403844C0 - {"_func_257", 0x257}, // SP 0x1402ADE20 MP 0x000000000 - {"_func_258", 0x258}, // SP 0x14029F640 MP 0x1403677A0 - {"_func_259", 0x259}, // SP 0x14029F710 MP 0x1403678C0 + {"clearfog", 0x237}, // SP 0x140297840 MP 0x140360C40 + {"setleveldopplerpreset", 0x238}, // SP 0x1402A87C0 MP 0x14037B1D0 + {"screenshake", 0x239}, // SP 0x1402AA280 MP 0x000000000 + {"isusinghdr", 0x23A}, // SP 0x140292220 MP 0x14035E710 + {"isusingssao", 0x23B}, // SP 0x140292220 MP 0x14035E860 + {"_func_23C", 0x23C}, // SP unk MP 0x1403686B0 capsule + {"playerphysicstraceinfo", 0x23D}, // SP 0x1402A06D0 MP 0x1403686B0 + {"_func_23E", 0x23E}, // SP 0x1402A0900 MP 0x140368C00 capsule + {"getminchargetime", 0x23F}, // SP 0x14029DDC0 MP 0x140365220 + {"getchargetimepershot", 0x240}, // SP 0x14029DDC0 MP 0x140365440 + {"getmaxchargeshots", 0x241}, // SP 0x1402ACD00 MP 0x140365460 + {"weaponischargeable", 0x242}, // SP 0x1402ACD00 MP 0x140365470 + {"weaponusesheat", 0x243}, // SP 0x1402ACD00 MP 0x140365630 + {"lootserviceonendgame", 0x244}, // SP 0x000000000 MP 0x1403784C0 + {"luinotifyevent", 0x245}, // SP 0x140292D40 MP 0x14035FAF0 + {"lootserviceonstartgame", 0x246}, // SP 0x000000000 MP 0x1403784E0 + {"tournamentreportplayerspm", 0x247}, // SP 0x000000000 MP 0x140378DA0 + {"tournamentreportwinningteam", 0x248}, // SP 0x000000000 MP 0x140378DB0 + {"tournamentreportendofgame", 0x249}, // SP 0x000000000 MP 0x140378DC0 + {"wakeupphysicssphere", 0x24A}, // SP 0x1402A8F70 MP 0x000000000 + {"wakeupragdollsphere", 0x24B}, // SP 0x1402A8FF0 MP 0x000000000 + {"dopplerpitch", 0x24C}, // SP 0x1402946A0 MP 0x14035ABF0 + {"piecewiselinearlookup", 0x24D}, // SP 0x140290110 MP 0x14036DF90 + {"anglestoaxis", 0x24E}, // SP 0x140292B00 MP 0x140359490 + {"visionsetwater", 0x24F}, // SP 0x1402ABB80 MP 0x000000000 + {"sendscriptusageanalysisdata", 0x250}, // SP 0x1405D92F0 MP 0x140360370 + {"resetscriptusageanalysisdata", 0x251}, // SP 0x1405D92F0 MP 0x1403604B0 + {"instantlylogusageanalysisdata", 0x252}, // SP 0x1405D92F0 MP 0x140360530 + {"invertangles", 0x253}, // SP 0x140293F90 MP 0x14035A6C0 + {"rotatevectorinverted", 0x254}, // SP 0x140293FF0 MP 0x14035A7C0 + {"calculatestartorientation", 0x255}, // SP 0x140294500 MP 0x14035A9F0 + {"droptoground", 0x256}, // SP 0x000000000 MP 0x1403844C0 + {"setdemigodmode", 0x257}, // SP 0x1402ADE20 MP 0x000000000 + {"precachelaser", 0x258}, // SP 0x14029F640 MP 0x1403677A0 + {"_func_259", 0x259}, // SP 0x14029F710 MP 0x1403678C0 font {"getcsplinecount", 0x25A}, // SP 0x1402954E0 MP 0x1403611E0 {"getcsplinepointcount", 0x25B}, // SP 0x1402955F0 MP 0x140361200 {"getcsplinelength", 0x25C}, // SP 0x140295790 MP 0x1403613C0 {"getcsplinepointid", 0x25D}, // SP 0x140295AD0 MP 0x1403615F0 {"getcsplinepointlabel", 0x25E}, // SP 0x140295E00 MP 0x140361A30 {"getcsplinepointtension", 0x25F}, // SP 0x140296150 MP 0x140361DD0 - {"_func_260", 0x260}, // SP 0x1402965B0 MP 0x140362020 - {"_func_261", 0x261}, // SP 0x140296740 MP 0x140362470 - {"_func_262", 0x262}, // SP 0x140296B10 MP 0x140362680 + {"getcsplinepointposition", 0x260}, // SP 0x1402965B0 MP 0x140362020 + {"getcsplinepointcorridordims", 0x261}, // SP 0x140296740 MP 0x140362470 + {"getcsplinepointtangent", 0x262}, // SP 0x140296B10 MP 0x140362680 {"getcsplinepointdisttonextpoint", 0x263}, // SP 0x140296CE0 MP 0x140362AE0 - {"_func_264", 0x264}, // SP 0x140296EE0 MP 0x140362D50 - {"_func_265", 0x265}, // SP 0x1402970D0 MP 0x140363430 - {"_func_266", 0x266}, // SP 0x140297580 MP 0x1403636C0 + {"calccsplineposition", 0x264}, // SP 0x140296EE0 MP 0x140362D50 + {"calccsplinetangent", 0x265}, // SP 0x1402970D0 MP 0x140363430 + {"calccsplinecorridor", 0x266}, // SP 0x140297580 MP 0x1403636C0 {"setnojipscore", 0x267}, // SP 0x140297820 MP 0x140363AB0 {"setnojiptime", 0x268}, // SP 0x140297820 MP 0x140363C90 {"getpredictedentityposition", 0x269}, // SP 0x000000000 MP 0x14037AEC0 - {"_func_26A", 0x26A}, // SP 0x1405D92F0 MP 0x140363F80 - {"_func_26B", 0x26B}, // SP 0x1405D92F0 MP 0x140364110 - {"_func_26C", 0x26C}, // SP 0x1405D92F0 MP 0x1403642F0 - {"_func_26D", 0x26D}, // SP 0x1405D92F0 MP 0x1403644E0 - {"_func_26E", 0x26E}, // SP 0x1405D92F0 MP 0x140364540 - {"_func_26F", 0x26F}, // SP 0x1405D92F0 MP 0x140364700 + {"gamedvrprohibitrecording", 0x26A}, // SP 0x1405D92F0 MP 0x140363F80 + {"gamedvrstartrecording", 0x26B}, // SP 0x1405D92F0 MP 0x140364110 + {"gamedvrstoprecording", 0x26C}, // SP 0x1405D92F0 MP 0x1403642F0 + {"gamedvrsetvideometadata", 0x26D}, // SP 0x1405D92F0 MP 0x1403644E0 + {"gamedvrprohibitscreenshots", 0x26E}, // SP 0x1405D92F0 MP 0x140364540 + {"gamedvrsetscreenshotmetadata", 0x26F}, // SP 0x1405D92F0 MP 0x140364700 {"queuedialog", 0x270}, // SP 0x000000000 MP 0x140378930 - {"_func_271", 0x271}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_272", 0x272}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_273", 0x273}, // SP 0x1405D92F0 MP 0x140364710 - {"_func_274", 0x274}, // SP 0x1405D92F0 MP 0x140364860 - {"_func_275", 0x275}, // SP 0x1405D92F0 MP 0x140364970 - {"_func_276", 0x276}, // SP 0x1405D92F0 MP 0x1403649D0 + {"speechenablegrammar", 0x271}, // SP 0x1405D92F0 MP 0x000000000 + {"speechenable", 0x272}, // SP 0x1405D92F0 MP 0x000000000 + {"livestreamingenable", 0x273}, // SP 0x1405D92F0 MP 0x140364710 + {"livestreamingsetbitrate", 0x274}, // SP 0x1405D92F0 MP 0x140364860 + {"livestreamingsetmetadata", 0x275}, // SP 0x1405D92F0 MP 0x140364970 + {"livestreamingenablearchiving", 0x276}, // SP 0x1405D92F0 MP 0x1403649D0 {"triggerportableradarping", 0x277}, // SP 0x000000000 MP 0x14037B980 + {"setglaregrimematerial", 0x278}, // SP 0x000000000 MP 0x14037B980 {"botgetteamlimit", 0x279}, // SP 0x000000000 MP 0x14047A900 {"spawnfxforclient", 0x27A}, // SP 0x000000000 MP 0x14037E430 {"botgetteamdifficulty", 0x27B}, // SP 0x000000000 MP 0x14047A8C0 - {"_func_27C", 0x27C}, // SP 0x1405D92F0 MP 0x1403675D0 - {"_func_27D", 0x27D}, // SP 0x14029CAC0 MP 0x14033CF40 - {"_func_27E", 0x27E}, // SP 0x1405D92F0 MP 0x140363CE0 - {"_func_27F", 0x27F}, // SP 0x1405D92F0 MP 0x140363E50 - {"_func_280", 0x280}, // SP 0x1405D92F0 MP 0x140360610 - {"_func_281", 0x281}, // SP 0x14029DC90 MP 0x140369F80 - {"getstarttime", 0x282}, // SP 0x000000000 MP 0x14037BBD0 - {"getbuildnumber", 0x283}, // SP 0x000000000 MP 0x14037BBE0 - {"_func_284", 0x284}, // SP 0x000000000 MP 0x14037BC00 - {"_func_285", 0x285}, // SP 0x000000000 MP 0x1403748B0 - {"_func_286", 0x286}, // SP 0x000000000 MP 0x140374B00 - {"_func_287", 0x287}, // SP 0x1405D92F0 MP 0x140360660 - {"_func_288", 0x288}, // SP 0x000000000 MP 0x1403772E0 - {"_func_289", 0x289}, // SP 0x000000000 MP 0x140376690 - {"_func_28A", 0x28A}, // SP 0x1402ACD00 MP 0x140365450 - {"_func_28B", 0x28B}, // SP 0x140295B60 MP 0x14035BD90 - {"_func_28C", 0x28C}, // SP 0x140296230 MP 0x14035C6E0 - {"_func_28D", 0x28D}, // SP 0x000000000 MP 0x1400777C0 - {"_func_28E", 0x28E}, // SP 0x000000000 MP 0x1403767D0 - {"_func_28F", 0x28F}, // SP 0x000000000 MP 0x140320120 - {"_func_290", 0x290}, // SP 0x000000000 MP 0x1403775D0 - {"_func_291", 0x291}, // SP 0x14029E770 MP 0x140368040 - {"_func_292", 0x292}, // SP 0x14029E7F0 MP 0x140368150 - {"_func_293", 0x293}, // SP 0x1402ADDE0 MP 0x000000000 - {"_func_294", 0x294}, // SP 0x1402988E0 MP 0x140365640 - {"_func_295", 0x295}, // SP 0x14029C2F0 MP 0x140368F40 - {"_func_296", 0x296}, // SP 0x14029B680 MP 0x140364D50 - {"_func_297", 0x297}, // SP 0x14029BD80 MP 0x140365540 - {"_func_298", 0x298}, // SP 0x14029C1B0 MP 0x140366230 - {"_func_299", 0x299}, // SP 0x1402ABA30 MP 0x000000000 - {"_func_29A", 0x29A}, // SP 0x1405D92F0 MP 0x14035B9A0 - {"_func_29B", 0x29B}, // SP 0x140291040 MP 0x14036F330 - {"_func_29C", 0x29C}, // SP 0x14029D240 MP 0x140368760 - {"_func_29D", 0x29D}, // SP 0x14029DE30 MP 0x1403674E0 - {"_func_29E", 0x29E}, // SP 0x14029DEC0 MP 0x140367620 - {"_func_29F", 0x29F}, // SP 0x000000000 MP 0x140375690 - {"_func_2A0", 0x2A0}, // SP 0x000000000 MP 0x1403756A0 - {"_func_2A1", 0x2A1}, // SP 0x14029D890 MP 0x140364AB0 - {"_func_2A2", 0x2A2}, // SP 0x1402ABC20 MP 0x000000000 - {"_func_2A3", 0x2A3}, // SP 0x1402A2F20 MP 0x14036F010 - {"_func_2A4", 0x2A4}, // SP 0x140290710 MP 0x14035B890 - {"_func_2A5", 0x2A5}, // SP 0x14029DF00 MP 0x14036D0F0 - {"_func_2A6", 0x2A6}, // SP 0x1405D92F0 MP 0x14036DAE0 - {"_func_2A7", 0x2A7}, // SP 0x1405D92F0 MP 0x14036DA60 - {"_func_2A8", 0x2A8}, // SP 0x000000000 MP 0x140376390 - {"_func_2A9", 0x2A9}, // SP 0x1402AE820 MP 0x000000000 - {"_func_2AA", 0x2AA}, // SP 0x14029AE80 MP 0x140364550 - {"_func_2AB", 0x2AB}, // SP 0x1405D92F0 MP 0x14036E590 - {"_func_2AC", 0x2AC}, // SP 0x1402ACD00 MP 0x14036E310 - {"_func_2AD", 0x2AD}, // SP 0x1405D92F0 MP 0x14036E3E0 - {"_func_2AE", 0x2AE}, // SP 0x1405D92F0 MP 0x14036E470 - {"_func_2AF", 0x2AF}, // SP 0x1405D92F0 MP 0x14036E730 - {"_func_2B0", 0x2B0}, // SP 0x000000000 MP 0x140375320 - {"_func_2B1", 0x2B1}, // SP 0x000000000 MP 0x1403753F0 - {"_func_2B2", 0x2B2}, // SP 0x000000000 MP 0x140375430 - {"_func_2B3", 0x2B3}, // SP 0x000000000 MP 0x140375A40 - {"_func_2B4", 0x2B4}, // SP 0x1405D92F0 MP 0x14035C9D0 - {"_func_2B5", 0x2B5}, // SP 0x1405D92F0 MP 0x14035D920 - {"_func_2B6", 0x2B6}, // SP 0x140291AD0 MP 0x14035E150 - {"_func_2B7", 0x2B7}, // SP 0x1402A85B0 MP 0x000000000 - {"_func_2B8", 0x2B8}, // SP 0x000000000 MP 0x140378570 - {"_func_2B9", 0x2B9}, // SP 0x000000000 MP 0x1403787D0 - {"_func_2BA", 0x2BA}, // SP 0x000000000 MP 0x140378850 - {"_func_2BB", 0x2BB}, // SP 0x000000000 MP 0x140379930 - {"_func_2BC", 0x2BC}, // SP 0x14028EBB0 MP 0x140359E00 - {"_func_2BD", 0x2BD}, // SP 0x1402A8640 MP 0x000000000 - {"_func_2BE", 0x2BE}, // SP 0x14029B310 MP 0x140366D50 - {"_func_2BF", 0x2BF}, // SP 0x000000000 MP 0x140383570 - {"_func_2C0", 0x2C0}, // SP 0x1405D92F0 MP 0x14036E8A0 - {"_func_2C1", 0x2C1}, // SP 0x1405D92F0 MP 0x14036E900 - {"_func_2C2", 0x2C2}, // SP 0x140291E10 MP 0x14035E670 - {"_func_2C3", 0x2C3}, // SP 0x1402A1A30 MP 0x14036DA40 - {"_func_2C4", 0x2C4}, // SP 0x1402A1A30 MP 0x14036DAC0 - {"_func_2C5", 0x2C5}, // SP 0x1402A8810 MP 0x000000000 - {"_func_2C6", 0x2C6}, // SP 0x000000000 MP 0x140379A80 - {"_func_2C6", 0x2C7}, // SP 0x000000000 MP 0x140320DC0 - {"_func_2C8", 0x2C8}, // SP 0x000000000 MP 0x140320E20 - {"_func_2C9", 0x2C9}, // SP 0x000000000 MP 0x14037E5E0 - {"_func_2CA", 0x2CA}, // SP 0x000000000 MP 0x14037E650 - {"_func_2CB", 0x2CB}, // SP 0x000000000 MP 0x14037BC40 - {"_func_2CC", 0x2CC}, // SP 0x000000000 MP 0x14037BD00 - {"_func_2CD", 0x2CD}, // SP 0x000000000 MP 0x140374820 - {"_func_2CE", 0x2CE}, // SP 0x1402A79A0 MP 0x000000000 - {"_func_2CF", 0x2CF}, // SP 0x000000000 MP 0x14037AB40 - {"_func_2D4", 0x2D4}, // SP 0x1402A7CB0 MP 0x000000000 - {"_func_2D5", 0x2D5}, // SP 0x14029E120 MP 0x14036D640 - {"_func_2D6", 0x2D6}, // SP 0x000000000 MP 0x14037BE30 - {"_func_2D7", 0x2D7}, // SP 0x1405D92F0 MP 0x14036DB50 - {"_func_2D8", 0x2D8}, // SP 0x1402ABB70 MP 0x000000000 - {"_func_2D9", 0x2D9}, // SP 0x000000000 MP 0x140320D50 - {"_func_2DA", 0x2DA}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_2DB", 0x2DB}, // SP 0x000000000 MP 0x14037ABB0 - {"_func_2DC", 0x2DC}, // SP 0x000000000 MP 0x14037E1C0 - {"_func_2DD", 0x2DD}, // SP 0x000000000 MP 0x14037E1B0 - {"_func_2DF", 0x2DF}, // SP 0x140292220 MP 0x14036F7F0 - {"_func_2E0", 0x2E0}, // SP 0x140297C80 MP 0x14035EDE0 - {"_func_2E1", 0x2E1}, // SP 0x000000000 MP 0x1403788D0 - {"_func_2E2", 0x2E2}, // SP 0x1405D92F0 MP 0x14035B3B0 - {"_func_2E3", 0x2E3}, // SP 0x1405D92F0 MP 0x14035D0B0 - {"_func_2E4", 0x2E4}, // SP 0x1405D92F0 MP 0x14035E170 - {"_func_2E5", 0x2E5}, // SP 0x1402A8730 MP 0x000000000 - {"_func_2E6", 0x2E6}, // SP 0x140295A10 MP 0x14035EFF0 - {"_func_2E7", 0x2E7}, // SP 0x140295CF0 MP 0x14035F120 - {"_func_2E8", 0x2E8}, // SP 0x1402AC850 MP 0x000000000 - {"_func_2E9", 0x2E9}, // SP 0x14029E760 MP 0x140366680 - {"_func_2EA", 0x2EA}, // SP 0x000000000 MP 0x140376DC0 - {"_func_2EB", 0x2EB}, // SP 0x000000000 MP 0x140377540 + {"debugstar", 0x27C}, // SP 0x1405D92F0 MP 0x1403675D0 + {"newdebughudelem", 0x27D}, // SP 0x14029CAC0 MP 0x14033CF40 + {"printlightsetsettings", 0x27E}, // SP 0x1405D92F0 MP 0x140363CE0 + {"lightsetdumpstate", 0x27F}, // SP 0x1405D92F0 MP 0x140363E50 + {"getsquadassaultelo", 0x280}, // SP 0x1405D92F0 MP 0x140360610 + {"loadluifile", 0x281}, // SP 0x14029DC90 MP 0x140369F80 + {"isdedicatedserver", 0x282}, // SP 0x000000000 MP 0x14037BBD0 + {"getplaylistversion", 0x283}, // SP 0x000000000 MP 0x14037BBE0 + {"getplaylistid", 0x284}, // SP 0x000000000 MP 0x14037BC00 + {"getactiveclientcount", 0x285}, // SP 0x000000000 MP 0x1403748B0 + {"issquadsmode", 0x286}, // SP 0x000000000 MP 0x140374B00 + {"getsquadassaultsquadindex", 0x287}, // SP 0x1405D92F0 MP 0x140360660 + {"visionsetpostapply", 0x288}, // SP 0x000000000 MP 0x1403772E0 + {"addbot", 0x289}, // SP 0x000000000 MP 0x140376690 + {"ishairrunning", 0x28A}, // SP 0x1402ACD00 MP 0x140365450 + {"getnearbyarrayelements", 0x28B}, // SP 0x140295B60 MP 0x14035BD90 + {"vectorclamp", 0x28C}, // SP 0x140296230 MP 0x14035C6E0 + {"isalliedsentient", 0x28D}, // SP 0x000000000 MP 0x1400777C0 + {"istestclient", 0x28E}, // SP 0x000000000 MP 0x1403767D0 + {"getrandomnodedestination", 0x28F}, // SP 0x000000000 MP 0x140320120 + {"debuglocalizestring", 0x290}, // SP 0x000000000 MP 0x1403775D0 + {"enablesoundcontextoverride", 0x291}, // SP 0x14029E770 MP 0x140368040 + {"disablesoundcontextoverride", 0x292}, // SP 0x14029E7F0 MP 0x140368150 + {"notifyoncommandremove", 0x293}, // SP 0x1402ADDE0 MP 0x000000000 + {"getsndaliasvalue", 0x294}, // SP 0x1402988E0 MP 0x140365640 + {"setsndaliasvalue", 0x295}, // SP 0x14029C2F0 MP 0x140368F40 + {"packedtablelookup", 0x296}, // SP 0x14029B680 MP 0x140364D50 + {"packedtablesectionlookup", 0x297}, // SP 0x14029BD80 MP 0x140365540 + {"packedtablelookupwithrange", 0x298}, // SP 0x14029C1B0 MP 0x140366230 + {"grappletrace", 0x299}, // SP 0x1402ABA30 MP 0x000000000 + {"stopclientexploder", 0x29A}, // SP 0x1405D92F0 MP 0x14035B9A0 + {"closestpointstwosegs", 0x29B}, // SP 0x140291040 MP 0x14036F330 + {"isremovedentity", 0x29C}, // SP 0x14029D240 MP 0x140368760 + {"tablegetrowcount", 0x29D}, // SP 0x14029DE30 MP 0x1403674E0 + {"tablegetcolumncount", 0x29E}, // SP 0x14029DEC0 MP 0x140367620 + {"batteryusepershot", 0x29F}, // SP 0x000000000 MP 0x140375690 + {"batteryreqtouse", 0x2A0}, // SP 0x000000000 MP 0x1403756A0 + {"isweaponmanuallydetonatedbydoubletap", 0x2A1}, // SP 0x14029D890 MP 0x140364AB0 + {"grapplegetmagnets", 0x2A2}, // SP 0x1402ABC20 MP 0x000000000 + {"getweaponname", 0x2A3}, // SP 0x1402A2F20 MP 0x14036F010 + {"activatepersistentclientexploder", 0x2A4}, // SP 0x140290710 MP 0x14035B890 + {"deployriotshield", 0x2A5}, // SP 0x14029DF00 MP 0x14036D0F0 + {"validatecostume", 0x2A6}, // SP 0x1405D92F0 MP 0x14036DAE0 + {"randomcostume", 0x2A7}, // SP 0x1405D92F0 MP 0x14036DA60 + {"shootblank", 0x2A8}, // SP 0x000000000 MP 0x140376390 + {"boidflockupdate", 0x2A9}, // SP 0x1402AE820 MP 0x000000000 + {"debuggetanimname", 0x2AA}, // SP 0x14029AE80 MP 0x140364550 + {"setspmatchdata", 0x2AB}, // SP 0x1405D92F0 MP 0x14036E590 + {"getspmatchdata", 0x2AC}, // SP 0x1402ACD00 MP 0x14036E310 + {"sendspmatchdata", 0x2AD}, // SP 0x1405D92F0 MP 0x14036E3E0 + {"clearspmatchdata", 0x2AE}, // SP 0x1405D92F0 MP 0x14036E470 + {"setspmatchdatadef", 0x2AF}, // SP 0x1405D92F0 MP 0x14036E730 + {"playcinematicforall", 0x2B0}, // SP 0x000000000 MP 0x140375320 + {"preloadcinematicforall", 0x2B1}, // SP 0x000000000 MP 0x1403753F0 + {"stopcinematicforall", 0x2B2}, // SP 0x000000000 MP 0x140375430 + {"capsuletracepassed", 0x2B3}, // SP 0x000000000 MP 0x140375A40 + {"stopfxontagforclient", 0x2B4}, // SP 0x1405D92F0 MP 0x14035C9D0 + {"killfxontagforclient", 0x2B5}, // SP 0x1405D92F0 MP 0x14035D920 + {"isvector", 0x2B6}, // SP 0x140291AD0 MP 0x14035E150 + {"notifychallengecomplete", 0x2B7}, // SP 0x1402A85B0 MP 0x000000000 + {"lootservicestarttrackingplaytime", 0x2B8}, // SP 0x000000000 MP 0x140378570 + {"lootservicestoptrackingplaytime", 0x2B9}, // SP 0x000000000 MP 0x1403787D0 + {"lootservicevalidateplaytime", 0x2BA}, // SP 0x000000000 MP 0x140378850 + {"recordbreadcrumbdataforplayer", 0x2BB}, // SP 0x000000000 MP 0x140379930 + {"getweaponandattachmentmodels", 0x2BC}, // SP 0x14028EBB0 MP 0x140359E00 + {"changewhizbyautosimparams", 0x2BD}, // SP 0x1402A8640 MP 0x000000000 + {"sysprint", 0x2BE}, // SP 0x14029B310 MP 0x140366D50 + {"objective_mlgspectator", 0x2BF}, // SP 0x000000000 MP 0x140383570 + {"setspcheckpointdata", 0x2C0}, // SP 0x1405D92F0 MP 0x14036E8A0 + {"getspcheckpointdata", 0x2C1}, // SP 0x1405D92F0 MP 0x14036E900 + {"isnumber", 0x2C2}, // SP 0x140291E10 MP 0x14035E670 + {"isonlinegame", 0x2C3}, // SP 0x1402A1A30 MP 0x14036DA40 + {"issystemlink", 0x2C4}, // SP 0x1402A1A30 MP 0x14036DAC0 + {"setsoundmasteringfadetime", 0x2C5}, // SP 0x1402A8810 MP 0x000000000 + {"getstanceandmotionstateforplayer", 0x2C6}, // SP 0x000000000 MP 0x140379A80 + {"nodeisnotusable", 0x2C7}, // SP 0x000000000 MP 0x140320DC0 + {"nodesetnotusable", 0x2C8}, // SP 0x000000000 MP 0x140320E20 + {"spawnlinkedfx", 0x2C9}, // SP 0x000000000 MP 0x14037E5E0 + {"spawnlinkedfxforclient", 0x2CA}, // SP 0x000000000 MP 0x14037E650 + {"getplaylistname", 0x2CB}, // SP 0x000000000 MP 0x14037BC40 + {"getlocaltimestring", 0x2CC}, // SP 0x000000000 MP 0x14037BD00 + {"isonwifi", 0x2CD}, // SP 0x000000000 MP 0x140374820 + {"getbuttonsconfig", 0x2CE}, // SP 0x1402A79A0 MP 0x000000000 + {"getchallengeid", 0x2CF}, // SP 0x000000000 MP 0x14037AB40 + {"nodehasremotemissileset", 0x2D0}, + {"nodegetremotemissilename", 0x2D1}, + {"remotemissileenttracetooriginpassed", 0x2D2}, + {"bombingruntracepassed", 0x2D3}, + {"soundsettraceflags", 0x2D4}, // SP 0x1402A7CB0 MP 0x000000000 + {"handlepickupdeployedriotshield", 0x2D5}, // SP 0x14029E120 MP 0x14036D640 + {"getcodanywherecurrentplatform", 0x2D6}, // SP 0x000000000 MP 0x14037BE30 + {"getcostumefromtable", 0x2D7}, // SP 0x1405D92F0 MP 0x14036DB50 + {"visionsetoverdrive", 0x2D8}, // SP 0x1402ABB70 MP 0x000000000 + {"nodegetsplitgroup", 0x2D9}, // SP 0x000000000 MP 0x140320D50 + {"recordbreadcrumbdataforplayersp", 0x2DA}, // SP 0x1405D92F0 MP 0x000000000 + {"getchallengerewarditem", 0x2DB}, // SP 0x000000000 MP 0x14037ABB0 + {"setentplayerxuidforemblem", 0x2DC}, // SP 0x000000000 MP 0x14037E1C0 + {"resetentplayerxuidforemblems", 0x2DD}, // SP 0x000000000 MP 0x14037E1B0 + {"isshipbuild", 0x2DF}, // SP 0x140292220 MP 0x14036F7F0 + {"strinsertnumericdelimiters", 0x2E0}, // SP 0x140297C80 MP 0x14035EDE0 + {"isscriptedagent", 0x2E1}, // SP 0x000000000 MP 0x1403788D0 + {"playfxonweapon", 0x2E2}, // SP 0x1405D92F0 MP 0x14035B3B0 + {"stopfxonweapon", 0x2E3}, // SP 0x1405D92F0 MP 0x14035D0B0 + {"killfxonweapon", 0x2E4}, // SP 0x1405D92F0 MP 0x14035E170 + {"getdefaultmaxfaceenemydistance", 0x2E5}, // SP 0x1402A8730 MP 0x000000000 + {"applyaccelerationonentity", 0x2E6}, // SP 0x140295A10 MP 0x14035EFF0 + {"applyimpulseonentity", 0x2E7}, // SP 0x140295CF0 MP 0x14035F120 + {"applyimpulseonentity", 0x2E8}, // SP 0x1402AC850 MP 0x000000000 + {"getinventoryitemtype", 0x2E9}, // SP 0x14029E760 MP 0x140366680 + {"getweaponmodelbounds", 0x2EA}, // SP 0x000000000 MP 0x140376DC0 + {"weaponitemplayidleanim", 0x2EB}, // SP 0x000000000 MP 0x140377540 {"_func_2EC", 0x2EC}, // SP 0x000000000 MP 0x140377880 - {"_func_2ED", 0x2ED}, // SP 0x1402ACD00 MP 0x14036BA50 - {"_func_2EE", 0x2EE}, // SP 0x1402A1E10 MP 0x14036BA60 - {"_func_2EF", 0x2EF}, // SP 0x1402A1FB0 MP 0x14036BA70 - {"_func_2F0", 0x2F0}, // SP 0x1402A21F0 MP 0x14036BB50 - {"_func_2F1", 0x2F1}, // SP 0x1402ACD00 MP 0x14036BC60 - {"_func_2F2", 0x2F2}, // SP 0x1402A1E10 MP 0x14036BC70 - {"_func_2F3", 0x2F3}, // SP 0x1402A1FB0 MP 0x14036BF90 - {"_func_2F4", 0x2F4}, // SP 0x1402A21F0 MP 0x14036C100 - {"_func_2F5", 0x2F5}, // SP 0x1402A1E10 MP 0x14036C120 - {"_func_2F6", 0x2F6}, // SP 0x1402A1FB0 MP 0x14036C170 - {"_func_2F7", 0x2F7}, // SP 0x1402A21F0 MP 0x14036C310 + {"getstaticmodelcount", 0x2ED}, // SP 0x1402ACD00 MP 0x14036BA50 + {"getstaticmodelname", 0x2EE}, // SP 0x1402A1E10 MP 0x14036BA60 + {"getstaticmodelbounds", 0x2EF}, // SP 0x1402A1FB0 MP 0x14036BA70 + {"findstaticmodelindex", 0x2F0}, // SP 0x1402A21F0 MP 0x14036BB50 + {"getdynentcount", 0x2F1}, // SP 0x1402ACD00 MP 0x14036BC60 + {"getdynentmodelname", 0x2F2}, // SP 0x1402A1E10 MP 0x14036BC70 + {"getdynentmodelbounds", 0x2F3}, // SP 0x1402A1FB0 MP 0x14036BF90 + {"finddynentwithmodelindex", 0x2F4}, // SP 0x1402A21F0 MP 0x14036C100 + {"getentitymodelname", 0x2F5}, // SP 0x1402A1E10 MP 0x14036C120 + {"getentitymodelbounds", 0x2F6}, // SP 0x1402A1FB0 MP 0x14036C170 + {"findentitywithmodelindex", 0x2F7}, // SP 0x1402A21F0 MP 0x14036C310 {"_func_2F8", 0x2F8}, // SP 0x14028D700 MP 0x1403582B0 {"_func_2F9", 0x2F9}, // SP 0x14029CAC0 MP 0x14036D300 {"_func_2FA", 0x2FA}, // SP 0x14029CAC0 MP 0x14036DDC0 From 6a5f9a5be339ea80e219003fe286c61a912c8560 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 10 Mar 2022 21:55:15 +0100 Subject: [PATCH 064/346] Remove update_test folder for debug --- src/client/component/updater.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp index 939dbd1c..9a525427 100644 --- a/src/client/component/updater.cpp +++ b/src/client/component/updater.cpp @@ -166,11 +166,7 @@ namespace updater return false; } -#ifdef DEBUG - return utils::io::write_file("update_test/" + name, data); -#else return utils::io::write_file(name, data); -#endif } void delete_old_file() From b28b776c69e1ecbb477da71a1b271bc70a64989c Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 10 Mar 2022 23:21:31 +0100 Subject: [PATCH 065/346] Lowercase function names --- src/client/component/network.cpp | 9 +- src/client/game/scripting/function_tables.cpp | 1186 ++++++++--------- 2 files changed, 594 insertions(+), 601 deletions(-) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 353f8ee1..226c3d05 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -27,15 +27,8 @@ namespace network const auto cmd_string = utils::string::to_lower(command); auto& callbacks = get_callbacks(); const auto handler = callbacks.find(cmd_string); - - if (handler == callbacks.end()) - { - return false; - } - const auto offset = cmd_string.size() + 5; - - if (message->cursize <= offset) + if (message->cursize < offset || handler == callbacks.end()) { return false; } diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 48727e8b..cf233a30 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -580,9 +580,9 @@ namespace scripting {"screenshake", 0x239}, // SP 0x1402AA280 MP 0x000000000 {"isusinghdr", 0x23A}, // SP 0x140292220 MP 0x14035E710 {"isusingssao", 0x23B}, // SP 0x140292220 MP 0x14035E860 - {"_func_23C", 0x23C}, // SP unk MP 0x1403686B0 capsule + {"_func_23c", 0x23C}, // SP unk MP 0x1403686B0 capsule {"playerphysicstraceinfo", 0x23D}, // SP 0x1402A06D0 MP 0x1403686B0 - {"_func_23E", 0x23E}, // SP 0x1402A0900 MP 0x140368C00 capsule + {"_func_23e", 0x23E}, // SP 0x1402A0900 MP 0x140368C00 capsule {"getminchargetime", 0x23F}, // SP 0x14029DDC0 MP 0x140365220 {"getchargetimepershot", 0x240}, // SP 0x14029DDC0 MP 0x140365440 {"getmaxchargeshots", 0x241}, // SP 0x1402ACD00 MP 0x140365460 @@ -755,7 +755,7 @@ namespace scripting {"getinventoryitemtype", 0x2E9}, // SP 0x14029E760 MP 0x140366680 {"getweaponmodelbounds", 0x2EA}, // SP 0x000000000 MP 0x140376DC0 {"weaponitemplayidleanim", 0x2EB}, // SP 0x000000000 MP 0x140377540 - {"_func_2EC", 0x2EC}, // SP 0x000000000 MP 0x140377880 + {"_func_2ec", 0x2EC}, // SP 0x000000000 MP 0x140377880 {"getstaticmodelcount", 0x2ED}, // SP 0x1402ACD00 MP 0x14036BA50 {"getstaticmodelname", 0x2EE}, // SP 0x1402A1E10 MP 0x14036BA60 {"getstaticmodelbounds", 0x2EF}, // SP 0x1402A1FB0 MP 0x14036BA70 @@ -767,14 +767,14 @@ namespace scripting {"getentitymodelname", 0x2F5}, // SP 0x1402A1E10 MP 0x14036C120 {"getentitymodelbounds", 0x2F6}, // SP 0x1402A1FB0 MP 0x14036C170 {"findentitywithmodelindex", 0x2F7}, // SP 0x1402A21F0 MP 0x14036C310 - {"_func_2F8", 0x2F8}, // SP 0x14028D700 MP 0x1403582B0 - {"_func_2F9", 0x2F9}, // SP 0x14029CAC0 MP 0x14036D300 - {"_func_2FA", 0x2FA}, // SP 0x14029CAC0 MP 0x14036DDC0 - {"_func_2FB", 0x2FB}, // SP 0x14029DB60 MP 0x140365110 - {"_func_2FC", 0x2FC}, // SP 0x14029CB20 MP 0x140367DD0 - {"_func_2FD", 0x2FD}, // SP 0x14029CEA0 MP 0x140368000 - {"_func_2FE", 0x2FE}, // SP 0x14029CEE0 MP 0x140368290 - {"_func_2FF", 0x2FF}, // SP 0x000000000 MP 0x140367110 + {"_func_2f8", 0x2F8}, // SP 0x14028D700 MP 0x1403582B0 + {"_func_2f9", 0x2F9}, // SP 0x14029CAC0 MP 0x14036D300 + {"_func_2fa", 0x2FA}, // SP 0x14029CAC0 MP 0x14036DDC0 + {"_func_2fb", 0x2FB}, // SP 0x14029DB60 MP 0x140365110 + {"_func_2fc", 0x2FC}, // SP 0x14029CB20 MP 0x140367DD0 + {"_func_2fd", 0x2FD}, // SP 0x14029CEA0 MP 0x140368000 + {"_func_2fe", 0x2FE}, // SP 0x14029CEE0 MP 0x140368290 + {"_func_2ff", 0x2FF}, // SP 0x000000000 MP 0x140367110 {"_func_300", 0x300}, // SP 0x000000000 MP 0x140377870 {"_func_301", 0x301}, // SP 0x1405D92F0 MP 0x140363E90 }; @@ -793,8 +793,8 @@ namespace scripting {"_meth_8009", 0x8009}, // SP 0x000000000 MP 0x14037ACC0 {"enableplayeruse", 0x800A}, // SP 0x000000000 MP 0x140374B10 {"disableplayeruse", 0x800B}, // SP 0x000000000 MP 0x140374BB0 - {"_meth_800C", 0x800C}, // SP 0x000000000 MP 0x140374D70 - {"_meth_800D", 0x800D}, // SP 0x000000000 MP 0x140374C90 + {"_meth_800c", 0x800C}, // SP 0x000000000 MP 0x140374D70 + {"_meth_800d", 0x800D}, // SP 0x000000000 MP 0x140374C90 {"makescrambler", 0x800E}, // SP 0x000000000 MP 0x14037B890 {"makeportableradar", 0x800F}, // SP 0x000000000 MP 0x14037B930 {"clearscrambler", 0x8010}, // SP 0x000000000 MP 0x14037B910 @@ -807,12 +807,12 @@ namespace scripting {"_meth_8017", 0x8017}, // SP 0x000000000 MP 0x14037AC10 {"_meth_8018", 0x8018}, // SP 0x000000000 MP 0x14037ACD0 {"_meth_8019", 0x8019}, // SP 0x000000000 MP 0x140378210 - {"_meth_801A", 0x801A}, // SP 0x14028F380 MP 0x14036F540 + {"_meth_801a", 0x801A}, // SP 0x14028F380 MP 0x14036F540 {"getcorpseanim", 0x801B}, // SP 0x000000000 MP 0x14037BD60 {"playerforcedeathanim", 0x801C}, // SP 0x000000000 MP 0x140374A30 - {"_meth_801D", 0x801D}, // SP 0x14029DCF0 MP 0x140369D40 - {"_meth_801E", 0x801E}, // SP 0x1402AD230 MP 0x000000000 - {"_meth_801F", 0x801F}, // SP 0x1402AD490 MP 0x000000000 + {"_meth_801d", 0x801D}, // SP 0x14029DCF0 MP 0x140369D40 + {"_meth_801e", 0x801E}, // SP 0x1402AD230 MP 0x000000000 + {"_meth_801f", 0x801F}, // SP 0x1402AD490 MP 0x000000000 {"_meth_8020", 0x8020}, // SP 0x1402AD4C0 MP 0x000000000 {"_meth_8021", 0x8021}, // SP 0x1402AD640 MP 0x000000000 {"_meth_8022", 0x8022}, // SP 0x1402AD660 MP 0x000000000 @@ -822,12 +822,12 @@ namespace scripting {"_meth_8026", 0x8026}, // SP 0x1405D92F0 MP 0x140377C40 {"_meth_8028", 0x8028}, // SP 0x1402ADE80 MP 0x000000000 {"_meth_8029", 0x8029}, // SP 0x14029AEC0 MP 0x140362D10 - {"_meth_802A", 0x802A}, // SP 0x14029E0E0 MP 0x14036A480 + {"_meth_802a", 0x802A}, // SP 0x14029E0E0 MP 0x14036A480 {"detachall", 0x802B}, // SP 0x14029E180 MP 0x14036A4C0 {"getattachsize", 0x802C}, // SP 0x1402A0610 MP 0x14036C860 {"getattachmodelname", 0x802D}, // SP 0x1402A0890 MP 0x14036CE90 - {"_meth_802E", 0x802E}, // SP 0x1402A0A90 MP 0x14036D040 - {"_meth_802F", 0x802F}, // SP 0x1402AE150 MP 0x000000000 + {"_meth_802e", 0x802E}, // SP 0x1402A0A90 MP 0x14036D040 + {"_meth_802f", 0x802F}, // SP 0x1402AE150 MP 0x000000000 {"_meth_8030", 0x8030}, // SP 0x1402AE270 MP 0x000000000 {"_meth_8031", 0x8031}, // SP 0x1402AE410 MP 0x000000000 {"_meth_8032", 0x8032}, // SP 0x1402AE620 MP 0x000000000 @@ -838,12 +838,12 @@ namespace scripting {"setforcespectatorclient", 0x8037}, // SP 0x1402CBB20 MP 0x14031F5D0 {"_meth_8038", 0x8038}, // SP 0x1402AB240 MP 0x000000000 {"_meth_8039", 0x8039}, // SP 0x1402AB320 MP 0x000000000 - {"_meth_803A", 0x803A}, // SP 0x1402AB6D0 MP 0x000000000 - {"_meth_803B", 0x803B}, // SP 0x1402ACA20 MP 0x000000000 - {"_meth_803C", 0x803C}, // SP 0x1402ACA40 MP 0x000000000 - {"_meth_803D", 0x803D}, // SP 0x1402ACBA0 MP 0x000000000 - {"_meth_803E", 0x803E}, // SP 0x1402AFA80 MP 0x000000000 - {"_meth_803F", 0x803F}, // SP 0x1402AFAC0 MP 0x000000000 + {"_meth_803a", 0x803A}, // SP 0x1402AB6D0 MP 0x000000000 + {"_meth_803b", 0x803B}, // SP 0x1402ACA20 MP 0x000000000 + {"_meth_803c", 0x803C}, // SP 0x1402ACA40 MP 0x000000000 + {"_meth_803d", 0x803D}, // SP 0x1402ACBA0 MP 0x000000000 + {"_meth_803e", 0x803E}, // SP 0x1402AFA80 MP 0x000000000 + {"_meth_803f", 0x803F}, // SP 0x1402AFAC0 MP 0x000000000 {"_meth_8040", 0x8040}, // SP 0x1402AFB90 MP 0x000000000 {"_meth_8041", 0x8041}, // SP 0x1402AFC50 MP 0x000000000 {"_meth_8042", 0x8042}, // SP 0x1402AFCA0 MP 0x000000000 @@ -856,10 +856,10 @@ namespace scripting {"getattachignorecollision", 0x8049}, // SP 0x1402A1060 MP 0x14036D280 {"hidepart", 0x804A}, // SP 0x1402A1500 MP 0x14036D940 {"hidepartallinstances", 0x804B}, // SP 0x1402A1930 MP 0x14036DC50 - {"_meth_804C", 0x804C}, // SP 0x1402A1C90 MP 0x14036E320 + {"_meth_804c", 0x804C}, // SP 0x1402A1C90 MP 0x14036E320 {"showpart", 0x804D}, // SP 0x1402A2000 MP 0x14036E480 - {"_meth_804E", 0x804E}, // SP 0x1402A2370 MP 0x14036ECC0 - {"_meth_804F", 0x804F}, // SP 0x1402A3670 MP 0x140358AF0 + {"_meth_804e", 0x804E}, // SP 0x1402A2370 MP 0x14036ECC0 + {"_meth_804f", 0x804F}, // SP 0x1402A3670 MP 0x140358AF0 {"_meth_8050", 0x8050}, // SP 0x1402A3AB0 MP 0x140359830 {"_meth_8051", 0x8051}, // SP 0x1402A3AD0 MP 0x140359850 {"_meth_8052", 0x8052}, // SP 0x1402AD0F0 MP 0x140379AD0 @@ -871,11 +871,11 @@ namespace scripting {"_meth_8058", 0x8058}, // SP 0x1402AD7D0 MP 0x000000000 {"disconnectpaths", 0x8059}, // SP 0x14028E1E0 MP 0x14036F090 {"connectpaths", 0x805A}, // SP 0x14028E390 MP 0x14036F4C0 - {"_meth_805B", 0x805B}, // SP 0x14028E490 MP 0x14036F5F0 - {"_meth_805C", 0x805C}, // SP 0x14028E750 MP 0x14036F770 - {"_meth_805D", 0x805D}, // SP 0x1402A8420 MP 0x000000000 - {"_meth_805E", 0x805E}, // SP 0x1402A8440 MP 0x000000000 - {"_meth_805F", 0x805F}, // SP 0x1402A8460 MP 0x000000000 + {"_meth_805b", 0x805B}, // SP 0x14028E490 MP 0x14036F5F0 + {"_meth_805c", 0x805C}, // SP 0x14028E750 MP 0x14036F770 + {"_meth_805d", 0x805D}, // SP 0x1402A8420 MP 0x000000000 + {"_meth_805e", 0x805E}, // SP 0x1402A8440 MP 0x000000000 + {"_meth_805f", 0x805F}, // SP 0x1402A8460 MP 0x000000000 {"_meth_8060", 0x8060}, // SP 0x1402A8480 MP 0x000000000 {"_meth_8061", 0x8061}, // SP 0x1402A9250 MP 0x000000000 {"_meth_8062", 0x8062}, // SP 0x1402A92D0 MP 0x000000000 @@ -887,9 +887,9 @@ namespace scripting {"_meth_8069", 0x8069}, // SP 0x1402ADF10 MP 0x000000000 {"islinked", 0x806A}, // SP 0x14028D6B0 MP 0x1403598E0 {"enablelinkto", 0x806B}, // SP 0x14028EA50 MP 0x14035A950 - {"_meth_806C", 0x806C}, // SP 0x1402ACB60 MP 0x000000000 - {"_meth_806E", 0x806E}, // SP 0x1402A27D0 MP 0x14035AB10 - {"_meth_806F", 0x806F}, // SP 0x1402A23E0 MP 0x14035A9C0 + {"_meth_806c", 0x806C}, // SP 0x1402ACB60 MP 0x000000000 + {"_meth_806e", 0x806E}, // SP 0x1402A27D0 MP 0x14035AB10 + {"_meth_806f", 0x806F}, // SP 0x1402A23E0 MP 0x14035A9C0 {"_meth_8070", 0x8070}, // SP 0x1402A2980 MP 0x14035B0D0 {"_meth_8071", 0x8071}, // SP 0x1402A28C0 MP 0x14035AB50 {"_meth_8072", 0x8072}, // SP 0x140291F10 MP 0x000000000 @@ -900,12 +900,12 @@ namespace scripting {"playloopsound", 0x8077}, // SP 0x1402ACC60 MP 0x1403798F0 {"_meth_8078", 0x8078}, // SP 0x1402ACCD0 MP 0x000000000 {"_meth_8079", 0x8079}, // SP 0x1402ACD40 MP 0x000000000 - {"_meth_807A", 0x807A}, // SP 0x1402ACDD0 MP 0x000000000 - {"_meth_807B", 0x807B}, // SP 0x1402ACE30 MP 0x000000000 - {"_meth_807C", 0x807C}, // SP 0x1402ACEE0 MP 0x000000000 + {"_meth_807a", 0x807A}, // SP 0x1402ACDD0 MP 0x000000000 + {"_meth_807b", 0x807B}, // SP 0x1402ACE30 MP 0x000000000 + {"_meth_807c", 0x807C}, // SP 0x1402ACEE0 MP 0x000000000 {"getnormalhealth", 0x807D}, // SP 0x1402ACFF0 MP 0x1403799E0 - {"_meth_807E", 0x807E}, // SP 0x14028FA50 MP 0x14035B880 - {"_meth_807F", 0x807F}, // SP 0x14028FB40 MP 0x14035B8D0 + {"_meth_807e", 0x807E}, // SP 0x14028FA50 MP 0x14035B880 + {"_meth_807f", 0x807F}, // SP 0x14028FB40 MP 0x14035B8D0 {"_meth_8080", 0x8080}, // SP 0x14028FB60 MP 0x14035BD70 {"playerlinktoabsolute", 0x8081}, // SP 0x14028FBE0 MP 0x14035C100 {"playerlinktoblend", 0x8082}, // SP 0x140292720 MP 0x14035DCB0 @@ -917,11 +917,11 @@ namespace scripting {"_meth_8088", 0x8088}, // SP 0x14026E240 MP 0x14033C170 {"_meth_8089", 0x8089}, // SP 0x14026E380 MP 0x14033C230 {"destroy", 0x808A}, // SP 0x14026E3C0 MP 0x14033C310 - {"_meth_808B", 0x808B}, // SP 0x14026E500 MP 0x14033C3F0 - {"_meth_808C", 0x808C}, // SP 0x14026E440 MP 0x14033C360 + {"_meth_808b", 0x808B}, // SP 0x14026E500 MP 0x14033C3F0 + {"_meth_808c", 0x808C}, // SP 0x14026E440 MP 0x14033C360 {"fadeovertime", 0x808D}, // SP 0x14026E0C0 MP 0x14033BFF0 - {"_meth_808E", 0x808E}, // SP 0x1402A83E0 MP 0x000000000 - {"_meth_808F", 0x808F}, // SP 0x1402A8400 MP 0x000000000 + {"_meth_808e", 0x808E}, // SP 0x1402A83E0 MP 0x000000000 + {"_meth_808f", 0x808F}, // SP 0x1402A8400 MP 0x000000000 {"_meth_8090", 0x8090}, // SP 0x1402A8970 MP 0x000000000 {"_meth_8091", 0x8091}, // SP 0x1402A89D0 MP 0x000000000 {"_meth_8092", 0x8092}, // SP 0x1402AD800 MP 0x000000000 @@ -932,101 +932,101 @@ namespace scripting {"_meth_8097", 0x8097}, // SP 0x1402AADC0 MP 0x140377CA0 {"_meth_8098", 0x8098}, // SP 0x1402AAE70 MP 0x000000000 {"_meth_8099", 0x8099}, // SP 0x1402AAF90 MP 0x000000000 - {"_meth_809A", 0x809A}, // SP 0x1402AC1D0 MP 0x000000000 + {"_meth_809a", 0x809A}, // SP 0x1402AC1D0 MP 0x000000000 {"useby", 0x809B}, // SP 0x1402AC470 MP 0x140377D00 {"playsound", 0x809C}, // SP 0x1402AC9B0 MP 0x140377F40 {"playerlinkedoffsetdisable", 0x80A1}, // SP 0x140290320 MP 0x14035CAF0 {"playerlinkedsetviewznear", 0x80A2}, // SP 0x140290680 MP 0x14035CE40 {"playerlinkedsetusebaseangleforviewclamp", 0x80A3}, // SP 0x140290960 MP 0x14035D290 - {"_meth_80A4", 0x80A4}, // SP 0x140294B30 MP 0x14035F4A0 - {"_meth_80A5", 0x80A5}, // SP 0x140295300 MP 0x14035FD70 - {"_meth_80A6", 0x80A6}, // SP 0x1402958C0 MP 0x000000000 - {"_meth_80A7", 0x80A7}, // SP 0x1402960D0 MP 0x000000000 - {"_meth_80A8", 0x80A8}, // SP 0x140297190 MP 0x000000000 - {"_meth_80A9", 0x80A9}, // SP 0x140297C20 MP 0x000000000 - {"_meth_80AA", 0x80AA}, // SP 0x14029DDD0 MP 0x1403663C0 + {"_meth_80a4", 0x80A4}, // SP 0x140294B30 MP 0x14035F4A0 + {"_meth_80a5", 0x80A5}, // SP 0x140295300 MP 0x14035FD70 + {"_meth_80a6", 0x80A6}, // SP 0x1402958C0 MP 0x000000000 + {"_meth_80a7", 0x80A7}, // SP 0x1402960D0 MP 0x000000000 + {"_meth_80a8", 0x80A8}, // SP 0x140297190 MP 0x000000000 + {"_meth_80a9", 0x80A9}, // SP 0x140297C20 MP 0x000000000 + {"_meth_80aa", 0x80AA}, // SP 0x14029DDD0 MP 0x1403663C0 {"istouching", 0x80AB}, // SP 0x140290390 MP 0x14035B440 {"getistouchingentities", 0x80AC}, // SP 0x1402904A0 MP 0x14035B650 - {"_meth_80AD", 0x80AD}, // SP 0x1402987B0 MP 0x14035FAA0 + {"_meth_80ad", 0x80AD}, // SP 0x1402987B0 MP 0x14035FAA0 {"stopsounds", 0x80AE}, // SP 0x140290F40 MP 0x14035C610 {"playrumbleonentity", 0x80AF}, // SP 0x140299090 MP 0x140360200 {"playrumblelooponentity", 0x80B0}, // SP 0x140299200 MP 0x1403602A0 {"stoprumble", 0x80B1}, // SP 0x1402997D0 MP 0x1403608E0 {"delete", 0x80B2}, // SP 0x14029DAA0 MP 0x140366320 {"setmodel", 0x80B3}, // SP 0x14029C8F0 MP 0x1403677D0 - {"_meth_80B4", 0x80B4}, // SP 0x14029A0F0 MP 0x140361C30 - {"_meth_80B5", 0x80B5}, // SP 0x14029A250 MP 0x140361F90 + {"_meth_80b4", 0x80B4}, // SP 0x14029A0F0 MP 0x140361C30 + {"_meth_80b5", 0x80B5}, // SP 0x14029A250 MP 0x140361F90 {"thermalvisionon", 0x80B8}, // SP 0x14029A450 MP 0x1403623A0 {"thermalvisionoff", 0x80B9}, // SP 0x14029AAF0 MP 0x140362B70 - {"_meth_80BA", 0x80BA}, // SP 0x14029BF20 MP 0x140364290 - {"_meth_80BB", 0x80BB}, // SP 0x14029C080 MP 0x140364630 - {"_meth_80BC", 0x80BC}, // SP 0x000000000 MP 0x140364910 + {"_meth_80ba", 0x80BA}, // SP 0x14029BF20 MP 0x140364290 + {"_meth_80bb", 0x80BB}, // SP 0x14029C080 MP 0x140364630 + {"_meth_80bc", 0x80BC}, // SP 0x000000000 MP 0x140364910 {"autospotoverlayon", 0x80BD}, // SP 0x000000000 MP 0x140364A50 - {"_meth_80BE", 0x80BE}, // SP 0x000000000 MP 0x140364D40 + {"_meth_80be", 0x80BE}, // SP 0x000000000 MP 0x140364D40 {"setcontents", 0x80C0}, // SP 0x140297CC0 MP 0x14035FDD0 {"makeusable", 0x80C1}, // SP 0x140297E90 MP 0x1403600D0 {"makeunusable", 0x80C2}, // SP 0x140297FF0 MP 0x140360320 - {"_meth_80C3", 0x80C3}, // SP 0x1402A1730 MP 0x140359740 - {"_meth_80C4", 0x80C4}, // SP 0x1402A1A80 MP 0x140359DC0 - {"_meth_80C5", 0x80C5}, // SP 0x140266A20 MP 0x000000000 - {"_meth_80C6", 0x80C6}, // SP 0x1402634D0 MP 0x000000000 - {"_meth_80C7", 0x80C7}, // SP 0x1404657D0 MP 0x000000000 - {"_meth_80C8", 0x80C8}, // SP 0x140463A30 MP 0x000000000 - {"_meth_80C9", 0x80C9}, // SP 0x140465630 MP 0x000000000 - {"_meth_80CA", 0x80CA}, // SP 0x1404656C0 MP 0x000000000 - {"_meth_80CB", 0x80CB}, // SP 0x140464F50 MP 0x000000000 + {"_meth_80c3", 0x80C3}, // SP 0x1402A1730 MP 0x140359740 + {"_meth_80c4", 0x80C4}, // SP 0x1402A1A80 MP 0x140359DC0 + {"_meth_80c5", 0x80C5}, // SP 0x140266A20 MP 0x000000000 + {"_meth_80c6", 0x80C6}, // SP 0x1402634D0 MP 0x000000000 + {"_meth_80c7", 0x80C7}, // SP 0x1404657D0 MP 0x000000000 + {"_meth_80c8", 0x80C8}, // SP 0x140463A30 MP 0x000000000 + {"_meth_80c9", 0x80C9}, // SP 0x140465630 MP 0x000000000 + {"_meth_80ca", 0x80CA}, // SP 0x1404656C0 MP 0x000000000 + {"_meth_80cb", 0x80CB}, // SP 0x140464F50 MP 0x000000000 {"settext", 0x80CC}, // SP 0x14026CE20 MP 0x14033AF40 - {"_meth_80CD", 0x80CD}, // SP 0x1405D92F0 MP 0x14033B030 + {"_meth_80cd", 0x80CD}, // SP 0x1405D92F0 MP 0x14033B030 {"setshader", 0x80CE}, // SP 0x14026CEE0 MP 0x14033B040 - {"_meth_80CF", 0x80CF}, // SP 0x14026D230 MP 0x14033B3A0 - {"_meth_80D0", 0x80D0}, // SP 0x14026D3B0 MP 0x14033B530 - {"_meth_80D1", 0x80D1}, // SP 0x14026D490 MP 0x14033B600 - {"_meth_80D2", 0x80D2}, // SP 0x14026D560 MP 0x14033B6C0 - {"_meth_80D3", 0x80D3}, // SP 0x14026D630 MP 0x14033B760 - {"_meth_80D4", 0x80D4}, // SP 0x14026D700 MP 0x14033B810 - {"_meth_80D5", 0x80D5}, // SP 0x14026D7D0 MP 0x14033B8D0 - {"_meth_80D6", 0x80D6}, // SP 0x14026D8A0 MP 0x14033B970 + {"_meth_80cf", 0x80CF}, // SP 0x14026D230 MP 0x14033B3A0 + {"_meth_80d0", 0x80D0}, // SP 0x14026D3B0 MP 0x14033B530 + {"_meth_80d1", 0x80D1}, // SP 0x14026D490 MP 0x14033B600 + {"_meth_80d2", 0x80D2}, // SP 0x14026D560 MP 0x14033B6C0 + {"_meth_80d3", 0x80D3}, // SP 0x14026D630 MP 0x14033B760 + {"_meth_80d4", 0x80D4}, // SP 0x14026D700 MP 0x14033B810 + {"_meth_80d5", 0x80D5}, // SP 0x14026D7D0 MP 0x14033B8D0 + {"_meth_80d6", 0x80D6}, // SP 0x14026D8A0 MP 0x14033B970 {"setclock", 0x80D7}, // SP 0x14026D970 MP 0x14033BA20 {"setclockup", 0x80D8}, // SP 0x14026D990 MP 0x14033BA40 {"setvalue", 0x80D9}, // SP 0x14026D9B0 MP 0x14033BA60 {"setwaypoint", 0x80DA}, // SP 0x14026DA50 MP 0x14033BAE0 - {"_meth_80DB", 0x80DB}, // SP 0x14026DBC0 MP 0x14033BBE0 + {"_meth_80db", 0x80DB}, // SP 0x14026DBC0 MP 0x14033BBE0 {"setcursorhint", 0x80DC}, // SP 0x1402983E0 MP 0x1403607E0 {"sethintstring", 0x80DD}, // SP 0x140299300 MP 0x140361060 - {"_meth_80DE", 0x80DE}, // SP 0x000000000 MP 0x140375C60 + {"_meth_80de", 0x80DE}, // SP 0x000000000 MP 0x140375C60 {"forceusehinton", 0x80DF}, // SP 0x140299730 MP 0x140361260 - {"_meth_80E0", 0x80E0}, // SP 0x140299930 MP 0x140361530 - {"_meth_80E1", 0x80E1}, // SP 0x140298080 MP 0x140360440 - {"_meth_80E2", 0x80E2}, // SP 0x140298160 MP 0x140360570 + {"_meth_80e0", 0x80E0}, // SP 0x140299930 MP 0x140361530 + {"_meth_80e1", 0x80E1}, // SP 0x140298080 MP 0x140360440 + {"_meth_80e2", 0x80E2}, // SP 0x140298160 MP 0x140360570 {"entitywillneverchange", 0x80E3}, // SP 0x1405D92F0 MP 0x140360620 - {"_meth_80E4", 0x80E4}, // SP 0x140291140 MP 0x14035D1B0 - {"_meth_80E5", 0x80E5}, // SP 0x1402912D0 MP 0x14035D310 + {"_meth_80e4", 0x80E4}, // SP 0x140291140 MP 0x14035D1B0 + {"_meth_80e5", 0x80E5}, // SP 0x1402912D0 MP 0x14035D310 {"isfiringturret", 0x80E6}, // SP 0x140291490 MP 0x14035D460 {"startbarrelspin", 0x80E7}, // SP 0x1402915B0 MP 0x14035D650 {"stopbarrelspin", 0x80E8}, // SP 0x1402916E0 MP 0x14035D8D0 {"getbarrelspinrate", 0x80E9}, // SP 0x140291A10 MP 0x14035DA40 - {"_meth_80EA", 0x80EA}, // SP 0x000000000 MP 0x14035C870 + {"_meth_80ea", 0x80EA}, // SP 0x000000000 MP 0x14035C870 {"remotecontrolturretoff", 0x80EB}, // SP 0x000000000 MP 0x14035CDD0 - {"_meth_80EC", 0x80EC}, // SP 0x140293380 MP 0x14035E870 + {"_meth_80ec", 0x80EC}, // SP 0x140293380 MP 0x14035E870 {"getturretowner", 0x80ED}, // SP 0x140293430 MP 0x14035EE50 - {"_meth_80EE", 0x80EE}, // SP 0x140268590 MP 0x000000000 - {"_meth_80EF", 0x80EF}, // SP 0x1402685F0 MP 0x000000000 - {"_meth_80F0", 0x80F0}, // SP 0x140268640 MP 0x000000000 - {"_meth_80F1", 0x80F1}, // SP 0x140268690 MP 0x000000000 - {"_meth_80F2", 0x80F2}, // SP 0x1402686F0 MP 0x000000000 - {"_meth_80F3", 0x80F3}, // SP 0x140268750 MP 0x000000000 - {"_meth_80F4", 0x80F4}, // SP 0x1402687A0 MP 0x000000000 - {"_meth_80F5", 0x80F5}, // SP 0x140268AF0 MP 0x000000000 - {"_meth_80F6", 0x80F6}, // SP 0x140268CC0 MP 0x000000000 - {"_meth_80F7", 0x80F7}, // SP 0x140268D20 MP 0x000000000 - {"_meth_80F8", 0x80F8}, // SP 0x140268D80 MP 0x000000000 - {"_meth_80F9", 0x80F9}, // SP 0x140268E10 MP 0x000000000 - {"_meth_80FA", 0x80FA}, // SP 0x140268EC0 MP 0x000000000 - {"_meth_80FB", 0x80FB}, // SP 0x140262E80 MP 0x14032F050 - {"_meth_80FC", 0x80FC}, // SP 0x140268890 MP 0x000000000 - {"_meth_80FD", 0x80FD}, // SP 0x1402688E0 MP 0x000000000 - {"_meth_80FE", 0x80FE}, // SP 0x1402689B0 MP 0x000000000 - {"_meth_80FF", 0x80FF}, // SP 0x140268A40 MP 0x000000000 + {"_meth_80ee", 0x80EE}, // SP 0x140268590 MP 0x000000000 + {"_meth_80ef", 0x80EF}, // SP 0x1402685F0 MP 0x000000000 + {"_meth_80f0", 0x80F0}, // SP 0x140268640 MP 0x000000000 + {"_meth_80f1", 0x80F1}, // SP 0x140268690 MP 0x000000000 + {"_meth_80f2", 0x80F2}, // SP 0x1402686F0 MP 0x000000000 + {"_meth_80f3", 0x80F3}, // SP 0x140268750 MP 0x000000000 + {"_meth_80f4", 0x80F4}, // SP 0x1402687A0 MP 0x000000000 + {"_meth_80f5", 0x80F5}, // SP 0x140268AF0 MP 0x000000000 + {"_meth_80f6", 0x80F6}, // SP 0x140268CC0 MP 0x000000000 + {"_meth_80f7", 0x80F7}, // SP 0x140268D20 MP 0x000000000 + {"_meth_80f8", 0x80F8}, // SP 0x140268D80 MP 0x000000000 + {"_meth_80f9", 0x80F9}, // SP 0x140268E10 MP 0x000000000 + {"_meth_80fa", 0x80FA}, // SP 0x140268EC0 MP 0x000000000 + {"_meth_80fb", 0x80FB}, // SP 0x140262E80 MP 0x14032F050 + {"_meth_80fc", 0x80FC}, // SP 0x140268890 MP 0x000000000 + {"_meth_80fd", 0x80FD}, // SP 0x1402688E0 MP 0x000000000 + {"_meth_80fe", 0x80FE}, // SP 0x1402689B0 MP 0x000000000 + {"_meth_80ff", 0x80FF}, // SP 0x140268A40 MP 0x000000000 {"_meth_8100", 0x8100}, // SP 0x1402611F0 MP 0x14032CF70 {"_meth_8101", 0x8101}, // SP 0x140261420 MP 0x14032D270 {"_meth_8102", 0x8102}, // SP 0x140268930 MP 0x000000000 @@ -1040,9 +1040,9 @@ namespace scripting {"cleartargetentity", 0x810A}, // SP 0x140294E90 MP 0x14035FE30 {"getturrettarget", 0x810B}, // SP 0x140295270 MP 0x140360040 {"setplayerspread", 0x810C}, // SP 0x1402957F0 MP 0x1403606C0 - {"_meth_810D", 0x810D}, // SP 0x140295A70 MP 0x140360990 - {"_meth_810E", 0x810E}, // SP 0x140295D50 MP 0x1403609A0 - {"_meth_810F", 0x810F}, // SP 0x14028A710 MP 0x000000000 + {"_meth_810d", 0x810D}, // SP 0x140295A70 MP 0x140360990 + {"_meth_810e", 0x810E}, // SP 0x140295D50 MP 0x1403609A0 + {"_meth_810f", 0x810F}, // SP 0x14028A710 MP 0x000000000 {"_meth_8110", 0x8110}, // SP 0x14028A730 MP 0x000000000 {"_meth_8111", 0x8111}, // SP 0x14028A750 MP 0x000000000 {"_meth_8112", 0x8112}, // SP 0x14028A770 MP 0x000000000 @@ -1053,23 +1053,23 @@ namespace scripting {"_meth_8117", 0x8117}, // SP 0x14028A800 MP 0x000000000 {"_meth_8118", 0x8118}, // SP 0x14028A8E0 MP 0x000000000 {"_meth_8119", 0x8119}, // SP 0x14028A960 MP 0x000000000 - {"_meth_811A", 0x811A}, // SP 0x140261760 MP 0x14032D140 - {"_meth_811B", 0x811B}, // SP 0x140261870 MP 0x14032D2D0 - {"_meth_811C", 0x811C}, // SP 0x140261950 MP 0x14032D630 - {"_meth_811D", 0x811D}, // SP 0x140261A30 MP 0x14032D780 - {"_meth_811E", 0x811E}, // SP 0x140269090 MP 0x000000000 - {"_meth_811F", 0x811F}, // SP 0x140269510 MP 0x000000000 + {"_meth_811a", 0x811A}, // SP 0x140261760 MP 0x14032D140 + {"_meth_811b", 0x811B}, // SP 0x140261870 MP 0x14032D2D0 + {"_meth_811c", 0x811C}, // SP 0x140261950 MP 0x14032D630 + {"_meth_811d", 0x811D}, // SP 0x140261A30 MP 0x14032D780 + {"_meth_811e", 0x811E}, // SP 0x140269090 MP 0x000000000 + {"_meth_811f", 0x811F}, // SP 0x140269510 MP 0x000000000 {"_meth_8121", 0x8121}, // SP 0x1402692D0 MP 0x000000000 {"_meth_8122", 0x8122}, // SP 0x140269350 MP 0x000000000 {"_meth_8123", 0x8123}, // SP 0x140269650 MP 0x000000000 {"_meth_8128", 0x8128}, // SP 0x140269650 MP 0x000000000 {"_meth_8129", 0x8129}, // SP 0x140269370 MP 0x000000000 - {"_meth_812A", 0x812A}, // SP 0x1402680B0 MP 0x000000000 - {"_meth_812B", 0x812B}, // SP 0x1402681E0 MP 0x000000000 - {"_meth_812C", 0x812C}, // SP 0x1402691F0 MP 0x000000000 - {"_meth_812D", 0x812D}, // SP 0x140268290 MP 0x000000000 - {"_meth_812E", 0x812E}, // SP 0x140267290 MP 0x14032B170 - {"_meth_812F", 0x812F}, // SP 0x140267650 MP 0x14032B720 + {"_meth_812a", 0x812A}, // SP 0x1402680B0 MP 0x000000000 + {"_meth_812b", 0x812B}, // SP 0x1402681E0 MP 0x000000000 + {"_meth_812c", 0x812C}, // SP 0x1402691F0 MP 0x000000000 + {"_meth_812d", 0x812D}, // SP 0x140268290 MP 0x000000000 + {"_meth_812e", 0x812E}, // SP 0x140267290 MP 0x14032B170 + {"_meth_812f", 0x812F}, // SP 0x140267650 MP 0x14032B720 {"_meth_8130", 0x8130}, // SP 0x140262E20 MP 0x14032F570 {"_meth_8131", 0x8131}, // SP 0x1402684C0 MP 0x000000000 {"_meth_8132", 0x8132}, // SP 0x140261580 MP 0x14032CD50 @@ -1081,11 +1081,11 @@ namespace scripting {"_meth_8138", 0x8138}, // SP 0x140296C90 MP 0x140361320 {"startfiring", 0x8139}, // SP 0x140296D70 MP 0x140361370 {"stopfiring", 0x813A}, // SP 0x140296E90 MP 0x1403615A0 - {"_meth_813B", 0x813B}, // SP 0x1402D7DD0 MP 0x140077920 + {"_meth_813b", 0x813B}, // SP 0x1402D7DD0 MP 0x140077920 {"freeentitysentient", 0x813C}, // SP 0x1402D7EE0 MP 0x140077A40 - {"_meth_813D", 0x813D}, // SP 0x1402D7FE0 MP 0x000000000 - {"_meth_813E", 0x813E}, // SP 0x1402D8040 MP 0x000000000 - {"_meth_813F", 0x813F}, // SP 0x1402D80E0 MP 0x000000000 + {"_meth_813d", 0x813D}, // SP 0x1402D7FE0 MP 0x000000000 + {"_meth_813e", 0x813E}, // SP 0x1402D8040 MP 0x000000000 + {"_meth_813f", 0x813F}, // SP 0x1402D80E0 MP 0x000000000 {"_meth_8140", 0x8140}, // SP 0x14028A390 MP 0x000000000 {"_meth_8142", 0x8142}, // SP 0x14028A3D0 MP 0x000000000 {"_meth_8143", 0x8143}, // SP 0x14028A370 MP 0x000000000 @@ -1095,12 +1095,12 @@ namespace scripting {"_meth_8147", 0x8147}, // SP 0x14028A4C0 MP 0x000000000 {"_meth_8148", 0x8148}, // SP 0x14028A4E0 MP 0x000000000 {"_meth_8149", 0x8149}, // SP 0x14028A500 MP 0x000000000 - {"_meth_814A", 0x814A}, // SP 0x14028A520 MP 0x000000000 - {"_meth_814B", 0x814B}, // SP 0x14028A530 MP 0x000000000 - {"_meth_814C", 0x814C}, // SP 0x14028A550 MP 0x000000000 - {"_meth_814D", 0x814D}, // SP 0x14028A570 MP 0x000000000 - {"_meth_814E", 0x814E}, // SP 0x14028A590 MP 0x000000000 - {"_meth_814F", 0x814F}, // SP 0x14028A5A0 MP 0x000000000 + {"_meth_814a", 0x814A}, // SP 0x14028A520 MP 0x000000000 + {"_meth_814b", 0x814B}, // SP 0x14028A530 MP 0x000000000 + {"_meth_814c", 0x814C}, // SP 0x14028A550 MP 0x000000000 + {"_meth_814d", 0x814D}, // SP 0x14028A570 MP 0x000000000 + {"_meth_814e", 0x814E}, // SP 0x14028A590 MP 0x000000000 + {"_meth_814f", 0x814F}, // SP 0x14028A5A0 MP 0x000000000 {"_meth_8150", 0x8150}, // SP 0x14028A5C0 MP 0x000000000 {"_meth_8151", 0x8151}, // SP 0x14028A5E0 MP 0x000000000 {"_meth_8152", 0x8152}, // SP 0x14028A650 MP 0x000000000 @@ -1111,12 +1111,12 @@ namespace scripting {"_meth_8157", 0x8157}, // SP 0x140297730 MP 0x140362260 {"_meth_8158", 0x8158}, // SP 0x140297890 MP 0x140362410 {"_meth_8159", 0x8159}, // SP 0x140297D20 MP 0x1403629F0 - {"_meth_815A", 0x815A}, // SP 0x140297F90 MP 0x140362CB0 + {"_meth_815a", 0x815A}, // SP 0x140297F90 MP 0x140362CB0 {"setautorotationdelay", 0x815B}, // SP 0x1402980D0 MP 0x140363040 - {"_meth_815C", 0x815C}, // SP 0x140298800 MP 0x1403638A0 + {"_meth_815c", 0x815C}, // SP 0x140298800 MP 0x1403638A0 {"restoredefaultdroppitch", 0x815D}, // SP 0x140298880 MP 0x140363B30 {"turretfiredisable", 0x815E}, // SP 0x140299040 MP 0x140363CF0 - {"_meth_815F", 0x815F}, // SP 0x1402495F0 MP 0x000000000 + {"_meth_815f", 0x815F}, // SP 0x1402495F0 MP 0x000000000 {"_meth_8160", 0x8160}, // SP 0x1402496C0 MP 0x000000000 {"_meth_8161", 0x8161}, // SP 0x140249790 MP 0x000000000 {"_meth_8162", 0x8162}, // SP 0x140249810 MP 0x000000000 @@ -1127,12 +1127,12 @@ namespace scripting {"_meth_8167", 0x8167}, // SP 0x140249BE0 MP 0x000000000 {"_meth_8168", 0x8168}, // SP 0x140249C70 MP 0x000000000 {"_meth_8169", 0x8169}, // SP 0x140262B90 MP 0x14032E0A0 - {"_meth_816A", 0x816A}, // SP 0x140249D10 MP 0x000000000 - {"_meth_816B", 0x816B}, // SP 0x140249EE0 MP 0x000000000 - {"_meth_816C", 0x816C}, // SP 0x14024A0E0 MP 0x000000000 - {"_meth_816D", 0x816D}, // SP 0x14024A200 MP 0x000000000 - {"_meth_816E", 0x816E}, // SP 0x14024A2D0 MP 0x000000000 - {"_meth_816F", 0x816F}, // SP 0x14024A3F0 MP 0x000000000 + {"_meth_816a", 0x816A}, // SP 0x140249D10 MP 0x000000000 + {"_meth_816b", 0x816B}, // SP 0x140249EE0 MP 0x000000000 + {"_meth_816c", 0x816C}, // SP 0x14024A0E0 MP 0x000000000 + {"_meth_816d", 0x816D}, // SP 0x14024A200 MP 0x000000000 + {"_meth_816e", 0x816E}, // SP 0x14024A2D0 MP 0x000000000 + {"_meth_816f", 0x816F}, // SP 0x14024A3F0 MP 0x000000000 {"_meth_8170", 0x8170}, // SP 0x14024A480 MP 0x000000000 {"_meth_8171", 0x8171}, // SP 0x14024A5C0 MP 0x000000000 {"_meth_8172", 0x8172}, // SP 0x14024A630 MP 0x000000000 @@ -1143,7 +1143,7 @@ namespace scripting {"_meth_8177", 0x8177}, // SP 0x14024AB90 MP 0x000000000 {"_meth_8178", 0x8178}, // SP 0x14024AC50 MP 0x000000000 {"getenemysqdist", 0x8179}, // SP 0x1402D77E0 MP 0x1400772C0 - {"_meth_817A", 0x817A}, // SP 0x1402D7820 MP 0x140077300 + {"_meth_817a", 0x817A}, // SP 0x1402D7820 MP 0x140077300 {"setthreatbiasgroup", 0x817B}, // SP 0x1402D7BE0 MP 0x1400776E0 {"getthreatbiasgroup", 0x817C}, // SP 0x1402D7C50 MP 0x140077750 {"turretfireenable", 0x817D}, // SP 0x140299220 MP 0x140363EE0 @@ -1161,10 +1161,10 @@ namespace scripting {"_meth_8189", 0x8189}, // SP 0x14029BB30 MP 0x140367230 {"setdepthoffield", 0x818A}, // SP 0x14029EF20 MP 0x140368890 {"setviewmodeldepthoffield", 0x818B}, // SP 0x14029F990 MP 0x140369900 - {"_meth_818C", 0x818C}, // SP 0x1402A15D0 MP 0x14036AD20 - {"_meth_818D", 0x818D}, // SP 0x140247D90 MP 0x000000000 - {"_meth_818E", 0x818E}, // SP 0x140247DE0 MP 0x000000000 - {"_meth_818F", 0x818F}, // SP 0x140247E50 MP 0x000000000 + {"_meth_818c", 0x818C}, // SP 0x1402A15D0 MP 0x14036AD20 + {"_meth_818d", 0x818D}, // SP 0x140247D90 MP 0x000000000 + {"_meth_818e", 0x818E}, // SP 0x140247DE0 MP 0x000000000 + {"_meth_818f", 0x818F}, // SP 0x140247E50 MP 0x000000000 {"_meth_8190", 0x8190}, // SP 0x140247E90 MP 0x000000000 {"_meth_8191", 0x8191}, // SP 0x140247F00 MP 0x000000000 {"_meth_8192", 0x8192}, // SP 0x140247F90 MP 0x000000000 @@ -1175,104 +1175,104 @@ namespace scripting {"_meth_8197", 0x8197}, // SP 0x140248640 MP 0x000000000 {"_meth_8198", 0x8198}, // SP 0x1402486A0 MP 0x000000000 {"_meth_8199", 0x8199}, // SP 0x1402486F0 MP 0x000000000 - {"_meth_819E", 0x819E}, // SP 0x1402487C0 MP 0x000000000 - {"_meth_819F", 0x819F}, // SP 0x140248870 MP 0x000000000 - {"_meth_81A0", 0x81A0}, // SP 0x1402488C0 MP 0x000000000 + {"_meth_819e", 0x819E}, // SP 0x1402487C0 MP 0x000000000 + {"_meth_819f", 0x819F}, // SP 0x140248870 MP 0x000000000 + {"_meth_81a0", 0x81A0}, // SP 0x1402488C0 MP 0x000000000 {"getnegotiationstartnode", 0x81A1}, // SP 0x140248970 MP 0x14044F980 {"getnegotiationendnode", 0x81A2}, // SP 0x1402489E0 MP 0x14044F830 {"getnegotiationnextnode", 0x81A3}, // SP 0x140248A50 MP 0x14044F8D0 - {"_meth_81A4", 0x81A4}, // SP 0x140248B30 MP 0x000000000 - {"_meth_81A5", 0x81A5}, // SP 0x140248BD0 MP 0x000000000 - {"_meth_81A6", 0x81A6}, // SP 0x140248CC0 MP 0x000000000 - {"_meth_81A7", 0x81A7}, // SP 0x140248DD0 MP 0x000000000 - {"_meth_81A8", 0x81A8}, // SP 0x140247750 MP 0x000000000 - {"_meth_81A9", 0x81A9}, // SP 0x140248E30 MP 0x000000000 - {"_meth_81AA", 0x81AA}, // SP 0x140248FB0 MP 0x000000000 - {"_meth_81AB", 0x81AB}, // SP 0x1402490D0 MP 0x000000000 - {"_meth_81AC", 0x81AC}, // SP 0x140249170 MP 0x000000000 - {"_meth_81AD", 0x81AD}, // SP 0x140249290 MP 0x000000000 - {"_meth_81AE", 0x81AE}, // SP 0x140249460 MP 0x000000000 - {"_meth_81AF", 0x81AF}, // SP 0x1402494B0 MP 0x000000000 - {"_meth_81B0", 0x81B0}, // SP 0x140249500 MP 0x000000000 - {"_meth_81B1", 0x81B1}, // SP 0x1402A15D0 MP 0x14036ADA0 - {"_meth_81B2", 0x81B2}, // SP 0x1402A15D0 MP 0x14036AE60 + {"_meth_81a4", 0x81A4}, // SP 0x140248B30 MP 0x000000000 + {"_meth_81a5", 0x81A5}, // SP 0x140248BD0 MP 0x000000000 + {"_meth_81a6", 0x81A6}, // SP 0x140248CC0 MP 0x000000000 + {"_meth_81a7", 0x81A7}, // SP 0x140248DD0 MP 0x000000000 + {"_meth_81a8", 0x81A8}, // SP 0x140247750 MP 0x000000000 + {"_meth_81a9", 0x81A9}, // SP 0x140248E30 MP 0x000000000 + {"_meth_81aa", 0x81AA}, // SP 0x140248FB0 MP 0x000000000 + {"_meth_81ab", 0x81AB}, // SP 0x1402490D0 MP 0x000000000 + {"_meth_81ac", 0x81AC}, // SP 0x140249170 MP 0x000000000 + {"_meth_81ad", 0x81AD}, // SP 0x140249290 MP 0x000000000 + {"_meth_81ae", 0x81AE}, // SP 0x140249460 MP 0x000000000 + {"_meth_81af", 0x81AF}, // SP 0x1402494B0 MP 0x000000000 + {"_meth_81b0", 0x81B0}, // SP 0x140249500 MP 0x000000000 + {"_meth_81b1", 0x81B1}, // SP 0x1402A15D0 MP 0x14036ADA0 + {"_meth_81b2", 0x81B2}, // SP 0x1402A15D0 MP 0x14036AE60 {"viewkick", 0x81B3}, // SP 0x1402A1640 MP 0x14036AFA0 - {"_meth_81B4", 0x81B4}, // SP 0x14029B1E0 MP 0x1403668B0 + {"_meth_81b4", 0x81B4}, // SP 0x14029B1E0 MP 0x1403668B0 {"getentitynumber", 0x81B5}, // SP 0x1402998B0 MP 0x140364980 {"autoboltmissileeffects", 0x81B6}, // SP 0x140299AA0 MP 0x140364B50 {"enablegrenadetouchdamage", 0x81B7}, // SP 0x140299CA0 MP 0x140364F40 {"disablegrenadetouchdamage", 0x81B8}, // SP 0x140299F20 MP 0x1403650C0 - {"_meth_81B9", 0x81B9}, // SP 0x14029AF00 MP 0x1403665A0 - {"_meth_81BA", 0x81BA}, // SP 0x14024AF80 MP 0x000000000 - {"_meth_81BB", 0x81BB}, // SP 0x14024B160 MP 0x000000000 - {"_meth_81BC", 0x81BC}, // SP 0x14024B3B0 MP 0x000000000 - {"_meth_81BD", 0x81BD}, // SP 0x14024B4F0 MP 0x000000000 - {"_meth_81BE", 0x81BE}, // SP 0x14024B570 MP 0x000000000 - {"_meth_81BF", 0x81BF}, // SP 0x14024B910 MP 0x000000000 - {"_meth_81C0", 0x81C0}, // SP 0x14024BA40 MP 0x000000000 - {"_meth_81C1", 0x81C1}, // SP 0x14024BB20 MP 0x000000000 - {"_meth_81C2", 0x81C2}, // SP 0x14024BB90 MP 0x000000000 - {"_meth_81C3", 0x81C3}, // SP 0x14024BC40 MP 0x000000000 - {"_meth_81C4", 0x81C4}, // SP 0x1402D7F30 MP 0x140077AA0 - {"_meth_81C5", 0x81C5}, // SP 0x1402D7F90 MP 0x140077B00 - {"_meth_81C6", 0x81C6}, // SP 0x14024BD90 MP 0x000000000 - {"_meth_81C7", 0x81C7}, // SP 0x14024C010 MP 0x000000000 - {"_meth_81C8", 0x81C8}, // SP 0x14024C150 MP 0x000000000 - {"_meth_81C9", 0x81C9}, // SP 0x14024C240 MP 0x000000000 - {"_meth_81CA", 0x81CA}, // SP 0x14024C250 MP 0x000000000 - {"_meth_81CB", 0x81CB}, // SP 0x14024C270 MP 0x000000000 - {"_meth_81CC", 0x81CC}, // SP 0x14024C290 MP 0x000000000 - {"_meth_81CD", 0x81CD}, // SP 0x14024C2F0 MP 0x000000000 - {"_meth_81CE", 0x81CE}, // SP 0x14024C360 MP 0x000000000 - {"_meth_81CF", 0x81CF}, // SP 0x14024C430 MP 0x000000000 - {"_meth_81D0", 0x81D0}, // SP 0x14024C520 MP 0x000000000 - {"_meth_81D1", 0x81D1}, // SP 0x14024C560 MP 0x000000000 - {"_meth_81D2", 0x81D2}, // SP 0x14024C5A0 MP 0x000000000 - {"_meth_81D3", 0x81D3}, // SP 0x14024C5E0 MP 0x000000000 - {"_meth_81D4", 0x81D4}, // SP 0x140247BF0 MP 0x000000000 - {"_meth_81D5", 0x81D5}, // SP 0x140247CE0 MP 0x000000000 - {"_meth_81D6", 0x81D6}, // SP 0x140247930 MP 0x000000000 - {"_meth_81D7", 0x81D7}, // SP 0x14029B180 MP 0x140366790 + {"_meth_81b9", 0x81B9}, // SP 0x14029AF00 MP 0x1403665A0 + {"_meth_81ba", 0x81BA}, // SP 0x14024AF80 MP 0x000000000 + {"_meth_81bb", 0x81BB}, // SP 0x14024B160 MP 0x000000000 + {"_meth_81bc", 0x81BC}, // SP 0x14024B3B0 MP 0x000000000 + {"_meth_81bd", 0x81BD}, // SP 0x14024B4F0 MP 0x000000000 + {"_meth_81be", 0x81BE}, // SP 0x14024B570 MP 0x000000000 + {"_meth_81bf", 0x81BF}, // SP 0x14024B910 MP 0x000000000 + {"_meth_81c0", 0x81C0}, // SP 0x14024BA40 MP 0x000000000 + {"_meth_81c1", 0x81C1}, // SP 0x14024BB20 MP 0x000000000 + {"_meth_81c2", 0x81C2}, // SP 0x14024BB90 MP 0x000000000 + {"_meth_81c3", 0x81C3}, // SP 0x14024BC40 MP 0x000000000 + {"_meth_81c4", 0x81C4}, // SP 0x1402D7F30 MP 0x140077AA0 + {"_meth_81c5", 0x81C5}, // SP 0x1402D7F90 MP 0x140077B00 + {"_meth_81c6", 0x81C6}, // SP 0x14024BD90 MP 0x000000000 + {"_meth_81c7", 0x81C7}, // SP 0x14024C010 MP 0x000000000 + {"_meth_81c8", 0x81C8}, // SP 0x14024C150 MP 0x000000000 + {"_meth_81c9", 0x81C9}, // SP 0x14024C240 MP 0x000000000 + {"_meth_81ca", 0x81CA}, // SP 0x14024C250 MP 0x000000000 + {"_meth_81cb", 0x81CB}, // SP 0x14024C270 MP 0x000000000 + {"_meth_81cc", 0x81CC}, // SP 0x14024C290 MP 0x000000000 + {"_meth_81cd", 0x81CD}, // SP 0x14024C2F0 MP 0x000000000 + {"_meth_81ce", 0x81CE}, // SP 0x14024C360 MP 0x000000000 + {"_meth_81cf", 0x81CF}, // SP 0x14024C430 MP 0x000000000 + {"_meth_81d0", 0x81D0}, // SP 0x14024C520 MP 0x000000000 + {"_meth_81d1", 0x81D1}, // SP 0x14024C560 MP 0x000000000 + {"_meth_81d2", 0x81D2}, // SP 0x14024C5A0 MP 0x000000000 + {"_meth_81d3", 0x81D3}, // SP 0x14024C5E0 MP 0x000000000 + {"_meth_81d4", 0x81D4}, // SP 0x140247BF0 MP 0x000000000 + {"_meth_81d5", 0x81D5}, // SP 0x140247CE0 MP 0x000000000 + {"_meth_81d6", 0x81D6}, // SP 0x140247930 MP 0x000000000 + {"_meth_81d7", 0x81D7}, // SP 0x14029B180 MP 0x140366790 {"entityradiusdamage", 0x81D8}, // SP 0x1402A3840 MP 0x14036C130 - {"_meth_81D9", 0x81D9}, // SP 0x14028DCF0 MP 0x14036CAB0 + {"_meth_81d9", 0x81D9}, // SP 0x14028DCF0 MP 0x14036CAB0 {"bddatachunk::deserialize", 0x81DA}, // SP 0x14028E350 MP 0x14036D0C0 - {"_meth_81DB", 0x81DB}, // SP 0x14028E430 MP 0x14036D150 - {"_meth_81DC", 0x81DC}, // SP 0x14029A340 MP 0x140365D80 - {"_meth_81DD", 0x81DD}, // SP 0x14029A4E0 MP 0x140365E90 - {"_meth_81DE", 0x81DE}, // SP 0x14029A700 MP 0x140366180 + {"_meth_81db", 0x81DB}, // SP 0x14028E430 MP 0x14036D150 + {"_meth_81dc", 0x81DC}, // SP 0x14029A340 MP 0x140365D80 + {"_meth_81dd", 0x81DD}, // SP 0x14029A4E0 MP 0x140365E90 + {"_meth_81de", 0x81DE}, // SP 0x14029A700 MP 0x140366180 {"missilesetflightmodedirect", 0x81DF}, // SP 0x14029AA10 MP 0x1403663A0 {"missilesetflightmodetop", 0x81E0}, // SP 0x14029AB50 MP 0x140366480 {"getlightintensity", 0x81E1}, // SP 0x14028EA00 MP 0x14036E8B0 - {"_meth_81E2", 0x81E2}, // SP 0x14028EB40 MP 0x14036EAB0 + {"_meth_81e2", 0x81E2}, // SP 0x14028EB40 MP 0x14036EAB0 {"isragdoll", 0x81E3}, // SP 0x14028F2F0 MP 0x14036F2E0 {"setmovespeedscale", 0x81E4}, // SP 0x1402A2860 MP 0x14036EF80 {"cameralinkto", 0x81E5}, // SP 0x14028FFC0 MP 0x1403584E0 {"cameraunlink", 0x81E6}, // SP 0x1402900C0 MP 0x140358750 - {"_meth_81E7", 0x81E7}, // SP 0x140248F30 MP 0x000000000 - {"_meth_81E8", 0x81E8}, // SP 0x1402491F0 MP 0x000000000 - {"_meth_81E9", 0x81E9}, // SP 0x140249230 MP 0x000000000 - {"_meth_81EA", 0x81EA}, // SP 0x140249370 MP 0x000000000 - {"_meth_81EB", 0x81EB}, // SP 0x140249650 MP 0x000000000 - {"_meth_81EC", 0x81EC}, // SP 0x140249710 MP 0x000000000 - {"_meth_81ED", 0x81ED}, // SP 0x1402499B0 MP 0x000000000 - {"_meth_81EE", 0x81EE}, // SP 0x140249A70 MP 0x000000000 - {"_meth_81EF", 0x81EF}, // SP 0x140249B80 MP 0x000000000 - {"_meth_81F0", 0x81F0}, // SP 0x140249C30 MP 0x000000000 - {"_meth_81F1", 0x81F1}, // SP 0x140249CC0 MP 0x000000000 - {"_meth_81F2", 0x81F2}, // SP 0x140249E00 MP 0x000000000 - {"_meth_81F3", 0x81F3}, // SP 0x140249E50 MP 0x000000000 - {"_meth_81F4", 0x81F4}, // SP 0x14024A010 MP 0x000000000 - {"_meth_81F5", 0x81F5}, // SP 0x14024A080 MP 0x000000000 - {"_meth_81F6", 0x81F6}, // SP 0x14024A190 MP 0x000000000 - {"_meth_81F7", 0x81F7}, // SP 0x14024A330 MP 0x000000000 - {"_meth_81F8", 0x81F8}, // SP 0x14024A390 MP 0x000000000 - {"_meth_81F9", 0x81F9}, // SP 0x14024A260 MP 0x000000000 - {"_meth_81FA", 0x81FA}, // SP 0x14024A440 MP 0x000000000 - {"_meth_81FB", 0x81FB}, // SP 0x14024A4F0 MP 0x000000000 - {"_meth_81FC", 0x81FC}, // SP 0x14024A6B0 MP 0x000000000 - {"_meth_81FD", 0x81FD}, // SP 0x14024A780 MP 0x000000000 - {"_meth_81FE", 0x81FE}, // SP 0x14024A950 MP 0x000000000 - {"_meth_81FF", 0x81FF}, // SP 0x14024AC00 MP 0x000000000 + {"_meth_81e7", 0x81E7}, // SP 0x140248F30 MP 0x000000000 + {"_meth_81e8", 0x81E8}, // SP 0x1402491F0 MP 0x000000000 + {"_meth_81e9", 0x81E9}, // SP 0x140249230 MP 0x000000000 + {"_meth_81ea", 0x81EA}, // SP 0x140249370 MP 0x000000000 + {"_meth_81eb", 0x81EB}, // SP 0x140249650 MP 0x000000000 + {"_meth_81ec", 0x81EC}, // SP 0x140249710 MP 0x000000000 + {"_meth_81ed", 0x81ED}, // SP 0x1402499B0 MP 0x000000000 + {"_meth_81ee", 0x81EE}, // SP 0x140249A70 MP 0x000000000 + {"_meth_81ef", 0x81EF}, // SP 0x140249B80 MP 0x000000000 + {"_meth_81f0", 0x81F0}, // SP 0x140249C30 MP 0x000000000 + {"_meth_81f1", 0x81F1}, // SP 0x140249CC0 MP 0x000000000 + {"_meth_81f2", 0x81F2}, // SP 0x140249E00 MP 0x000000000 + {"_meth_81f3", 0x81F3}, // SP 0x140249E50 MP 0x000000000 + {"_meth_81f4", 0x81F4}, // SP 0x14024A010 MP 0x000000000 + {"_meth_81f5", 0x81F5}, // SP 0x14024A080 MP 0x000000000 + {"_meth_81f6", 0x81F6}, // SP 0x14024A190 MP 0x000000000 + {"_meth_81f7", 0x81F7}, // SP 0x14024A330 MP 0x000000000 + {"_meth_81f8", 0x81F8}, // SP 0x14024A390 MP 0x000000000 + {"_meth_81f9", 0x81F9}, // SP 0x14024A260 MP 0x000000000 + {"_meth_81fa", 0x81FA}, // SP 0x14024A440 MP 0x000000000 + {"_meth_81fb", 0x81FB}, // SP 0x14024A4F0 MP 0x000000000 + {"_meth_81fc", 0x81FC}, // SP 0x14024A6B0 MP 0x000000000 + {"_meth_81fd", 0x81FD}, // SP 0x14024A780 MP 0x000000000 + {"_meth_81fe", 0x81FE}, // SP 0x14024A950 MP 0x000000000 + {"_meth_81ff", 0x81FF}, // SP 0x14024AC00 MP 0x000000000 {"_meth_8200", 0x8200}, // SP 0x14024AD60 MP 0x000000000 {"_meth_8201", 0x8201}, // SP 0x14024AE60 MP 0x000000000 {"_meth_8202", 0x8202}, // SP 0x14024B1D0 MP 0x000000000 @@ -1282,11 +1282,11 @@ namespace scripting {"_meth_8206", 0x8206}, // SP 0x000000000 MP 0x14035AB40 {"_meth_8207", 0x8207}, // SP 0x1402AA5F0 MP 0x000000000 {"_meth_8208", 0x8208}, // SP 0x000000000 MP 0x14035ABE0 - {"_meth_820A", 0x820A}, // SP 0x000000000 MP 0x14035B100 - {"_meth_820B", 0x820B}, // SP 0x000000000 MP 0x14035B170 - {"_meth_820C", 0x820C}, // SP 0x000000000 MP 0x14035B380 - {"_meth_820D", 0x820D}, // SP 0x000000000 MP 0x14035B210 - {"_meth_820E", 0x820E}, // SP 0x000000000 MP 0x14035B270 + {"_meth_820a", 0x820A}, // SP 0x000000000 MP 0x14035B100 + {"_meth_820b", 0x820B}, // SP 0x000000000 MP 0x14035B170 + {"_meth_820c", 0x820C}, // SP 0x000000000 MP 0x14035B380 + {"_meth_820d", 0x820D}, // SP 0x000000000 MP 0x14035B210 + {"_meth_820e", 0x820E}, // SP 0x000000000 MP 0x14035B270 {"drivevehicleandcontrolturret", 0x820F}, // SP 0x140291CD0 MP 0x14035C250 {"drivevehicleandcontrolturretoff", 0x8210}, // SP 0x140292090 MP 0x14035C420 {"_meth_8211", 0x8211}, // SP 0x1402923D0 MP 0x14035C930 @@ -1298,11 +1298,11 @@ namespace scripting {"_meth_8217", 0x8217}, // SP 0x1402966E0 MP 0x14035FC80 {"circle", 0x8218}, // SP 0x1402990B0 MP 0x1403620D0 {"rect", 0x8219}, // SP 0x140299540 MP 0x140362730 - {"_meth_821A", 0x821A}, // SP 0x140299B00 MP 0x140362E50 + {"_meth_821a", 0x821A}, // SP 0x140299B00 MP 0x140362E50 {"transfermarkstonewscriptmodel", 0x821B}, // SP 0x14029A1B0 MP 0x140363790 {"setwatersheeting", 0x821C}, // SP 0x140290290 MP 0x140358930 - {"_meth_821D", 0x821D}, // SP 0x1402A29B0 MP 0x000000000 - {"_meth_821E", 0x821E}, // SP 0x1402A32F0 MP 0x000000000 + {"_meth_821d", 0x821D}, // SP 0x1402A29B0 MP 0x000000000 + {"_meth_821e", 0x821E}, // SP 0x1402A32F0 MP 0x000000000 {"setweaponhudiconoverride", 0x821F}, // SP 0x140296A30 MP 0x14035FC90 {"getweaponhudiconoverride", 0x8220}, // SP 0x140297010 MP 0x140360380 {"_meth_8221", 0x8221}, // SP 0x1402976A0 MP 0x1403609B0 @@ -1330,11 +1330,11 @@ namespace scripting {"_meth_8237", 0x8237}, // SP 0x140292010 MP 0x000000000 {"_meth_8238", 0x8238}, // SP 0x140292230 MP 0x000000000 {"_meth_8239", 0x8239}, // SP 0x14029C2A0 MP 0x000000000 - {"_meth_823A", 0x823A}, // SP 0x14029CAD0 MP 0x000000000 - {"_meth_823B", 0x823B}, // SP 0x14029CD70 MP 0x000000000 - {"_meth_823C", 0x823C}, // SP 0x14029CF00 MP 0x000000000 - {"_meth_823D", 0x823D}, // SP 0x140292BA0 MP 0x000000000 - {"_meth_823E", 0x823E}, // SP 0x140292DF0 MP 0x000000000 + {"_meth_823a", 0x823A}, // SP 0x14029CAD0 MP 0x000000000 + {"_meth_823b", 0x823B}, // SP 0x14029CD70 MP 0x000000000 + {"_meth_823c", 0x823C}, // SP 0x14029CF00 MP 0x000000000 + {"_meth_823d", 0x823D}, // SP 0x140292BA0 MP 0x000000000 + {"_meth_823e", 0x823E}, // SP 0x140292DF0 MP 0x000000000 {"_meth_8240", 0x8240}, // SP 0x1402A3880 MP 0x000000000 {"_meth_8241", 0x8241}, // SP 0x140248AD0 MP 0x000000000 {"_meth_8242", 0x8242}, // SP 0x140248EA0 MP 0x000000000 @@ -1346,8 +1346,8 @@ namespace scripting {"_meth_8248", 0x8248}, // SP 0x140268FE0 MP 0x140332B40 {"sayteam", 0x8249}, // SP 0x000000000 MP 0x1403345F0 {"sayall", 0x824A}, // SP 0x000000000 MP 0x1403346A0 - {"_meth_824B", 0x824B}, // SP 0x000000000 MP 0x140332C90 - {"_meth_824C", 0x824C}, // SP 0x140265080 MP 0x140330FE0 + {"_meth_824b", 0x824B}, // SP 0x000000000 MP 0x140332C90 + {"_meth_824c", 0x824C}, // SP 0x140265080 MP 0x140330FE0 {"dropscavengerbag", 0x824D}, // SP 0x000000000 MP 0x140332FB0 {"setjitterparams", 0x824E}, // SP 0x140461E80 MP 0x140560640 {"sethoverparams", 0x824F}, // SP 0x140461F50 MP 0x140560710 @@ -1364,7 +1364,7 @@ namespace scripting {"settargetyaw", 0x825A}, // SP 0x140462950 MP 0x1405611B0 {"cleartargetyaw", 0x825B}, // SP 0x1404629E0 MP 0x140561240 {"helisetgoal", 0x825C}, // SP 0x140462A60 MP 0x1405612C0 - {"_meth_825D", 0x825D}, // SP 0x140463320 MP 0x140561B60 + {"_meth_825d", 0x825D}, // SP 0x140463320 MP 0x140561B60 {"setturrettargetent", 0x825E}, // SP 0x140463410 MP 0x140561C60 {"clearturrettargetent", 0x825F}, // SP 0x140463510 MP 0x140561D60 {"canturrettargetpoint", 0x8260}, // SP 0x1404635A0 MP 0x140561DF0 @@ -1377,10 +1377,10 @@ namespace scripting {"suicide", 0x8267}, // SP 0x000000000 MP 0x140333E20 {"_meth_8268", 0x8268}, // SP 0x000000000 MP 0x140334010 {"_meth_8269", 0x8269}, // SP 0x000000000 MP 0x1403340A0 - {"_meth_826A", 0x826A}, // SP 0x000000000 MP 0x140334120 + {"_meth_826a", 0x826A}, // SP 0x000000000 MP 0x140334120 {"spawn", 0x826B}, // SP 0x000000000 MP 0x1403341A0 - {"_meth_826C", 0x826C}, // SP 0x000000000 MP 0x140334230 - {"_meth_826D", 0x826D}, // SP 0x000000000 MP 0x140334290 + {"_meth_826c", 0x826C}, // SP 0x000000000 MP 0x140334230 + {"_meth_826d", 0x826D}, // SP 0x000000000 MP 0x140334290 {"istalking", 0x826E}, // SP 0x000000000 MP 0x140334570 {"allowspectateteam", 0x826F}, // SP 0x000000000 MP 0x140334750 {"_meth_8270", 0x8270}, // SP 0x000000000 MP 0x140334980 @@ -1410,7 +1410,7 @@ namespace scripting {"turnengineon", 0x8288}, // SP 0x140465F00 MP 0x14055FEC0 {"_meth_8289", 0x8289}, // SP 0x140465F60 MP 0x000000000 {"getgoalspeedmph", 0x828A}, // SP 0x140466020 MP 0x14055FF30 - {"_meth_828B", 0x828B}, // SP 0x140466090 MP 0x14055FFA0 + {"_meth_828b", 0x828B}, // SP 0x140466090 MP 0x14055FFA0 {"setacceleration", 0x828C}, // SP 0x140466100 MP 0x140560010 {"resumespeed", 0x828D}, // SP 0x140466170 MP 0x140560080 {"setyawspeed", 0x828E}, // SP 0x140466200 MP 0x140560110 @@ -1426,57 +1426,57 @@ namespace scripting {"_meth_8298", 0x8298}, // SP 0x000000000 MP 0x140334ED0 {"getspectatingplayer", 0x8299}, // SP 0x000000000 MP 0x140334F60 {"predictstreampos", 0x829A}, // SP 0x000000000 MP 0x140334FE0 - {"_meth_829B", 0x829B}, // SP 0x000000000 MP 0x1403350D0 - {"_meth_829C", 0x829C}, // SP 0x000000000 MP 0x1403350E0 + {"_meth_829b", 0x829B}, // SP 0x000000000 MP 0x1403350D0 + {"_meth_829c", 0x829C}, // SP 0x000000000 MP 0x1403350E0 {"setrank", 0x829D}, // SP 0x000000000 MP 0x1403350F0 - {"_meth_829E", 0x829E}, // SP 0x000000000 MP 0x140335190 + {"_meth_829e", 0x829E}, // SP 0x000000000 MP 0x140335190 {"setmlgspectator", 0x829F}, // SP 0x140260730 MP 0x14032CA40 {"visionsyncwithplayer", 0x82A0}, // SP 0x000000000 MP 0x14032ED90 {"showhudsplash", 0x82A1}, // SP 0x140263850 MP 0x14032FB10 {"setperk", 0x82A2}, // SP 0x140265490 MP 0x1403297E0 - {"_meth_82A3", 0x82A3}, // SP 0x1402659A0 MP 0x140329D00 - {"_meth_82A4", 0x82A4}, // SP 0x1402661B0 MP 0x14032A460 - {"_meth_82A5", 0x82A5}, // SP 0x140265D40 MP 0x14032A0A0 + {"_meth_82a3", 0x82A3}, // SP 0x1402659A0 MP 0x140329D00 + {"_meth_82a4", 0x82A4}, // SP 0x1402661B0 MP 0x14032A460 + {"_meth_82a5", 0x82A5}, // SP 0x140265D40 MP 0x14032A0A0 {"registerparty", 0x82A6}, // SP 0x000000000 MP 0x1403323C0 - {"_meth_82A7", 0x82A7}, // SP 0x000000000 MP 0x1403324F0 - {"_meth_82A8", 0x82A8}, // SP 0x1405D92F0 MP 0x14032A8F0 - {"_meth_82A9", 0x82A9}, // SP 0x1405D92F0 MP 0x14032A900 + {"_meth_82a7", 0x82A7}, // SP 0x000000000 MP 0x1403324F0 + {"_meth_82a8", 0x82A8}, // SP 0x1405D92F0 MP 0x14032A8F0 + {"_meth_82a9", 0x82A9}, // SP 0x1405D92F0 MP 0x14032A900 {"moveto", 0x82AA}, // SP 0x1402B2A10 MP 0x14037E950 {"rotatepitch", 0x82AB}, // SP 0x1402B2F60 MP 0x14037EEB0 {"rotateyaw", 0x82AC}, // SP 0x1402B2F70 MP 0x14037EEC0 {"rotateroll", 0x82AD}, // SP 0x1402B2F90 MP 0x14037EEE0 - {"_meth_82AE", 0x82AE}, // SP 0x1402B2C10 MP 0x14037EB00 - {"_meth_82AF", 0x82AF}, // SP 0x1402B2D70 MP 0x14037EC90 - {"_meth_82B0", 0x82B0}, // SP 0x1402B2EE0 MP 0x14037EE20 + {"_meth_82ae", 0x82AE}, // SP 0x1402B2C10 MP 0x14037EB00 + {"_meth_82af", 0x82AF}, // SP 0x1402B2D70 MP 0x14037EC90 + {"_meth_82b0", 0x82B0}, // SP 0x1402B2EE0 MP 0x14037EE20 {"rotateby", 0x82B1}, // SP 0x1402B3030 MP 0x14037EF10 - {"_meth_82B2", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 - {"_meth_82B3", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 - {"_meth_82B4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 - {"_meth_82B5", 0x82B5}, // SP 0x1402B3410 MP 0x14037F010 - {"_meth_82B6", 0x82B6}, // SP 0x1402B3430 MP 0x14037F030 - {"_meth_82B7", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 - {"_meth_82B8", 0x82B8}, // SP 0x1402B34B0 MP 0x14037F0B0 - {"_meth_82B9", 0x82B9}, // SP 0x1402B3700 MP 0x14037F3C0 + {"_meth_82b2", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 + {"_meth_82b3", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 + {"_meth_82b4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 + {"_meth_82b5", 0x82B5}, // SP 0x1402B3410 MP 0x14037F010 + {"_meth_82b6", 0x82B6}, // SP 0x1402B3430 MP 0x14037F030 + {"_meth_82b7", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 + {"_meth_82b8", 0x82B8}, // SP 0x1402B34B0 MP 0x14037F0B0 + {"_meth_82b9", 0x82B9}, // SP 0x1402B3700 MP 0x14037F3C0 {"solid", 0x82BA}, // SP 0x1402B45E0 MP 0x1403808A0 {"notsolid", 0x82BB}, // SP 0x1402B4690 MP 0x140380950 {"setcandamage", 0x82BC}, // SP 0x1402B3880 MP 0x14037F590 {"setcanradiusdamage", 0x82BD}, // SP 0x1402B38E0 MP 0x14037F5F0 {"physicslaunchclient", 0x82BE}, // SP 0x1402B3960 MP 0x14037F670 - {"_meth_82BF", 0x82BF}, // SP 0x000000000 MP 0x1403351A0 - {"_meth_82C0", 0x82C0}, // SP 0x000000000 MP 0x1403351B0 + {"_meth_82bf", 0x82BF}, // SP 0x000000000 MP 0x1403351A0 + {"_meth_82c0", 0x82C0}, // SP 0x000000000 MP 0x1403351B0 {"setcarddisplayslot", 0x82C1}, // SP 0x000000000 MP 0x1403351C0 {"regweaponforfxremoval", 0x82C2}, // SP 0x000000000 MP 0x1403352B0 {"laststandrevive", 0x82C3}, // SP 0x000000000 MP 0x140331E00 - {"_meth_82C4", 0x82C4}, // SP 0x000000000 MP 0x140331E70 + {"_meth_82c4", 0x82C4}, // SP 0x000000000 MP 0x140331E70 {"setspectatedefaults", 0x82C5}, // SP 0x000000000 MP 0x140331EE0 {"getthirdpersoncrosshairoffset", 0x82C6}, // SP 0x000000000 MP 0x140332250 - {"_meth_82C7", 0x82C7}, // SP 0x140262950 MP 0x14032EF00 - {"_meth_82C8", 0x82C8}, // SP 0x140262A60 MP 0x14032EFF0 - {"_meth_82C9", 0x82C9}, // SP 0x140262AB0 MP 0x14032F0D0 - {"_meth_82CA", 0x82CA}, // SP 0x000000000 MP 0x1403322C0 + {"_meth_82c7", 0x82C7}, // SP 0x140262950 MP 0x14032EF00 + {"_meth_82c8", 0x82C8}, // SP 0x140262A60 MP 0x14032EFF0 + {"_meth_82c9", 0x82C9}, // SP 0x140262AB0 MP 0x14032F0D0 + {"_meth_82ca", 0x82CA}, // SP 0x000000000 MP 0x1403322C0 {"getweaponslistexclusives", 0x82CB}, // SP 0x1402623D0 MP 0x14032E3A0 - {"_meth_82CC", 0x82CC}, // SP 0x1402624C0 MP 0x14032E4B0 - {"_meth_82CD", 0x82CD}, // SP 0x1402625B0 MP 0x14032E650 + {"_meth_82cc", 0x82CC}, // SP 0x1402624C0 MP 0x14032E4B0 + {"_meth_82cd", 0x82CD}, // SP 0x1402625B0 MP 0x14032E650 {"getweaponslist", 0x82CE}, // SP 0x140262720 MP 0x14032E790 {"canplayerplacesentry", 0x82CF}, // SP 0x140264D00 MP 0x140331530 {"canplayerplacetank", 0x82D0}, // SP 0x1402651B0 MP 0x1403292E0 @@ -1486,47 +1486,47 @@ namespace scripting {"visionsetthermalforplayer", 0x82D4}, // SP 0x140263710 MP 0x14032FD20 {"visionsetpainforplayer", 0x82D5}, // SP 0x140263730 MP 0x14032FD40 {"setblurforplayer", 0x82D6}, // SP 0x140264890 MP 0x140330B80 - {"_meth_82D7", 0x82D7}, // SP 0x140264C80 MP 0x140331310 - {"_meth_82D8", 0x82D8}, // SP 0x140264C80 MP 0x140331330 - {"_meth_82D9", 0x82D9}, // SP 0x1402ABE90 MP 0x000000000 + {"_meth_82d7", 0x82D7}, // SP 0x140264C80 MP 0x140331310 + {"_meth_82d8", 0x82D8}, // SP 0x140264C80 MP 0x140331330 + {"_meth_82d9", 0x82D9}, // SP 0x1402ABE90 MP 0x000000000 {"getbuildnumber", 0x82DA}, // SP 0x1402663A0 MP 0x14032A910 - {"_meth_82DB", 0x82DB}, // SP 0x140266AF0 MP 0x14032AE90 - {"_meth_82DC", 0x82DC}, // SP 0x140266CD0 MP 0x14032B120 - {"_meth_82DD", 0x82DD}, // SP 0x140266FE0 MP 0x14032B500 + {"_meth_82db", 0x82DB}, // SP 0x140266AF0 MP 0x14032AE90 + {"_meth_82dc", 0x82DC}, // SP 0x140266CD0 MP 0x14032B120 + {"_meth_82dd", 0x82DD}, // SP 0x140266FE0 MP 0x14032B500 {"playfx", 0x82DE}, // SP 0x140267330 MP 0x14032B9F0 {"playerrecoilscaleon", 0x82DF}, // SP 0x140267530 MP 0x14032BD00 - {"_meth_82E0", 0x82E0}, // SP 0x140267600 MP 0x14032BDD0 + {"_meth_82e0", 0x82E0}, // SP 0x140267600 MP 0x14032BDD0 {"weaponlockstart", 0x82E1}, // SP 0x1402676E0 MP 0x14032C000 {"weaponlockfinalize", 0x82E2}, // SP 0x140260240 MP 0x14032C240 {"disableautoreload", 0x82E3}, // SP 0x140260540 MP 0x14032C6C0 {"setentertime", 0x82E4}, // SP 0x1402605E0 MP 0x14032C7F0 {"usinggamepad", 0x82E5}, // SP 0x000000000 MP 0x140332300 - {"_meth_82E6", 0x82E6}, // SP 0x000000000 MP 0x140332380 - {"_meth_82E7", 0x82E7}, // SP 0x000000000 MP 0x140332390 - {"_meth_82E8", 0x82E8}, // SP 0x000000000 MP 0x1403323B0 - {"_meth_82E9", 0x82E9}, // SP 0x000000000 MP 0x1403323A0 - {"_meth_82EA", 0x82EA}, // SP 0x1402628A0 MP 0x14032E5C0 - {"_meth_82EB", 0x82EB}, // SP 0x1402619B0 MP 0x14032D5A0 - {"_meth_82EC", 0x82EC}, // SP 0x140261AA0 MP 0x14032D6D0 + {"_meth_82e6", 0x82E6}, // SP 0x000000000 MP 0x140332380 + {"_meth_82e7", 0x82E7}, // SP 0x000000000 MP 0x140332390 + {"_meth_82e8", 0x82E8}, // SP 0x000000000 MP 0x1403323B0 + {"_meth_82e9", 0x82E9}, // SP 0x000000000 MP 0x1403323A0 + {"_meth_82ea", 0x82EA}, // SP 0x1402628A0 MP 0x14032E5C0 + {"_meth_82eb", 0x82EB}, // SP 0x1402619B0 MP 0x14032D5A0 + {"_meth_82ec", 0x82EC}, // SP 0x140261AA0 MP 0x14032D6D0 {"issighted", 0x82ED}, // SP 0x140263D40 MP 0x14032FA10 {"setvelocity", 0x82EE}, // SP 0x1402601C0 MP 0x14032BBE0 - {"_meth_82EF", 0x82EF}, // SP 0x140260AD0 MP 0x14032C3C0 - {"_meth_82F0", 0x82F0}, // SP 0x140260E80 MP 0x14032C5E0 - {"_meth_82F1", 0x82F1}, // SP 0x1402677A0 MP 0x14032BE30 - {"_meth_82F2", 0x82F2}, // SP 0x140260130 MP 0x14032BF20 - {"_meth_82F3", 0x82F3}, // SP 0x140264AD0 MP 0x140330E20 + {"_meth_82ef", 0x82EF}, // SP 0x140260AD0 MP 0x14032C3C0 + {"_meth_82f0", 0x82F0}, // SP 0x140260E80 MP 0x14032C5E0 + {"_meth_82f1", 0x82F1}, // SP 0x1402677A0 MP 0x14032BE30 + {"_meth_82f2", 0x82F2}, // SP 0x140260130 MP 0x14032BF20 + {"_meth_82f3", 0x82F3}, // SP 0x140264AD0 MP 0x140330E20 {"setweaponammostock", 0x82F4}, // SP 0x140264EB0 MP 0x140331350 - {"_meth_82F5", 0x82F5}, // SP 0x140265380 MP 0x1403293A0 + {"_meth_82f5", 0x82F5}, // SP 0x140265380 MP 0x1403293A0 {"getweaponammostock", 0x82F6}, // SP 0x1402655D0 MP 0x140329580 - {"_meth_82F7", 0x82F7}, // SP 0x140265820 MP 0x140329990 + {"_meth_82f7", 0x82F7}, // SP 0x140265820 MP 0x140329990 {"stoplocalsound", 0x82F8}, // SP 0x140265F20 MP 0x14032A3B0 {"setclientdvar", 0x82F9}, // SP 0x140266410 MP 0x14032A990 - {"_meth_82FA", 0x82FA}, // SP 0x1402666C0 MP 0x14032B260 - {"_meth_82FB", 0x82FB}, // SP 0x000000000 MP 0x14032AC30 - {"_meth_82FC", 0x82FC}, // SP 0x000000000 MP 0x14032AD80 + {"_meth_82fa", 0x82FA}, // SP 0x1402666C0 MP 0x14032B260 + {"_meth_82fb", 0x82FB}, // SP 0x000000000 MP 0x14032AC30 + {"_meth_82fc", 0x82FC}, // SP 0x000000000 MP 0x14032AD80 {"allowads", 0x82FD}, // SP 0x140261130 MP 0x14032C940 - {"_meth_82FE", 0x82FE}, // SP 0x140261440 MP 0x14032CAB0 - {"_meth_82FF", 0x82FF}, // SP 0x140261B20 MP 0x14032D890 + {"_meth_82fe", 0x82FE}, // SP 0x140261440 MP 0x14032CAB0 + {"_meth_82ff", 0x82FF}, // SP 0x140261B20 MP 0x14032D890 {"_meth_8300", 0x8300}, // SP 0x140261C00 MP 0x14032DA40 {"weaponlocktargettooclose", 0x8301}, // SP 0x140261CE0 MP 0x14032DBB0 {"setspreadoverride", 0x8302}, // SP 0x140262B00 MP 0x14032ED00 @@ -1537,9 +1537,9 @@ namespace scripting {"getviewkickscale", 0x8307}, // SP 0x140260A80 MP 0x14032CCC0 {"getweaponslistoffhands", 0x8308}, // SP 0x1402621A0 MP 0x14032E120 {"getweaponslistitems", 0x8309}, // SP 0x1402622E0 MP 0x14032E230 - {"_meth_830A", 0x830A}, // SP 0x140261090 MP 0x14032C720 - {"_meth_830B", 0x830B}, // SP 0x140262F00 MP 0x14032EA90 - {"_meth_830C", 0x830C}, // SP 0x140263380 MP 0x14032F210 + {"_meth_830a", 0x830A}, // SP 0x140261090 MP 0x14032C720 + {"_meth_830b", 0x830B}, // SP 0x140262F00 MP 0x14032EA90 + {"_meth_830c", 0x830C}, // SP 0x140263380 MP 0x14032F210 {"takeallweapons", 0x830D}, // SP 0x1402635B0 MP 0x14032F310 {"getcurrentweapon", 0x830E}, // SP 0x140263750 MP 0x14032F5E0 {"getcurrentprimaryweapon", 0x830F}, // SP 0x140263A30 MP 0x14032F860 @@ -1553,12 +1553,12 @@ namespace scripting {"getcustomizationbody", 0x8317}, // SP 0x140264600 MP 0x140330520 {"beginlocationselection", 0x8318}, // SP 0x140260C90 MP 0x14032C470 {"_meth_8319", 0x8319}, // SP 0x140261020 MP 0x14032C780 - {"_meth_831A", 0x831A}, // SP 0x140263E90 MP 0x1403302E0 - {"_meth_831B", 0x831B}, // SP 0x140264020 MP 0x140330410 - {"_meth_831C", 0x831C}, // SP 0x140264150 MP 0x1403305B0 - {"_meth_831D", 0x831D}, // SP 0x140264270 MP 0x1403306E0 - {"_meth_831E", 0x831E}, // SP 0x140264660 MP 0x140330B20 - {"_meth_831F", 0x831F}, // SP 0x140264750 MP 0x140330CC0 + {"_meth_831a", 0x831A}, // SP 0x140263E90 MP 0x1403302E0 + {"_meth_831b", 0x831B}, // SP 0x140264020 MP 0x140330410 + {"_meth_831c", 0x831C}, // SP 0x140264150 MP 0x1403305B0 + {"_meth_831d", 0x831D}, // SP 0x140264270 MP 0x1403306E0 + {"_meth_831e", 0x831E}, // SP 0x140264660 MP 0x140330B20 + {"_meth_831f", 0x831F}, // SP 0x140264750 MP 0x140330CC0 {"setaimspreadmovementscale", 0x8320}, // SP 0x1402631F0 MP 0x14032F130 {"closemenu", 0x8321}, // SP 0x140263290 MP 0x14032F3A0 {"_meth_8322", 0x8322}, // SP 0x140263330 MP 0x14032F4E0 @@ -1568,12 +1568,12 @@ namespace scripting {"disableusability", 0x8327}, // SP 0x140263C10 MP 0x14032FFE0 {"enableusability", 0x8328}, // SP 0x140263E40 MP 0x1403300F0 {"_meth_8329", 0x8329}, // SP 0x140266C00 MP 0x14032B640 - {"_meth_832A", 0x832A}, // SP 0x140266D10 MP 0x14032B800 - {"_meth_832B", 0x832B}, // SP 0x140266EA0 MP 0x14032B9C0 - {"_meth_832C", 0x832C}, // SP 0x140267180 MP 0x14032B9E0 + {"_meth_832a", 0x832A}, // SP 0x140266D10 MP 0x14032B800 + {"_meth_832b", 0x832B}, // SP 0x140266EA0 MP 0x14032B9C0 + {"_meth_832c", 0x832C}, // SP 0x140267180 MP 0x14032B9E0 {"deactivatechannelvolumes", 0x832D}, // SP 0x140267410 MP 0x14032BB00 - {"_meth_832E", 0x832E}, // SP 0x140265FA0 MP 0x140329C00 - {"_meth_832F", 0x832F}, // SP 0x140266200 MP 0x140329F00 + {"_meth_832e", 0x832E}, // SP 0x140265FA0 MP 0x140329C00 + {"_meth_832f", 0x832F}, // SP 0x140266200 MP 0x140329F00 {"_meth_8330", 0x8330}, // SP 0x140266560 MP 0x14032A240 {"_meth_8331", 0x8331}, // SP 0x140266820 MP 0x14032A6F0 {"isdualwielding", 0x8332}, // SP 0x140266E10 MP 0x14032ABC0 @@ -1584,11 +1584,11 @@ namespace scripting {"_meth_8337", 0x8337}, // SP 0x140260930 MP 0x14032BE70 {"forcemantle", 0x8338}, // SP 0x140260990 MP 0x14032C0D0 {"attackbuttonpressed", 0x8339}, // SP 0x140261500 MP 0x14032CE10 - {"_meth_833A", 0x833A}, // SP 0x1402615F0 MP 0x14032D0B0 + {"_meth_833a", 0x833A}, // SP 0x1402615F0 MP 0x14032D0B0 {"meleebuttonpressed", 0x833B}, // SP 0x1402617D0 MP 0x14032D1B0 {"jumpbuttonpressed", 0x833C}, // SP 0x1402618D0 MP 0x14032D450 {"getviewheight", 0x833D}, // SP 0x140262070 MP 0x14032DC20 - {"_meth_833E", 0x833E}, // SP 0x1402620C0 MP 0x14032DCE0 + {"_meth_833e", 0x833E}, // SP 0x1402620C0 MP 0x14032DCE0 {"isonladder", 0x833F}, // SP 0x140262280 MP 0x14032DF80 {"setviewmodel", 0x8340}, // SP 0x1402626A0 MP 0x14032DFF0 {"_meth_8341", 0x8341}, // SP 0x140264090 MP 0x14032FF10 @@ -1600,11 +1600,11 @@ namespace scripting {"_meth_8347", 0x8347}, // SP 0x14026D000 MP 0x14033B150 {"forcethirdpersonwhenfollowing", 0x8348}, // SP 0x000000000 MP 0x140374D30 {"disableforcethirdpersonwhenfollowing", 0x8349}, // SP 0x000000000 MP 0x140374DD0 - {"_meth_834A", 0x834A}, // SP 0x140260C10 MP 0x14032C5D0 - {"_meth_834B", 0x834B}, // SP 0x000000000 MP 0x14037B380 + {"_meth_834a", 0x834A}, // SP 0x140260C10 MP 0x14032C5D0 + {"_meth_834b", 0x834B}, // SP 0x000000000 MP 0x14037B380 {"secondaryoffhandbuttonpressed", 0x834C}, // SP 0x140261D40 MP 0x14032D9C0 - {"_meth_834D", 0x834D}, // SP 0x000000000 MP 0x140374B70 - {"_meth_834E", 0x834E}, // SP 0x000000000 MP 0x140374C10 + {"_meth_834d", 0x834D}, // SP 0x000000000 MP 0x140374B70 + {"_meth_834e", 0x834E}, // SP 0x000000000 MP 0x140374C10 {"botsetflag", 0x834F}, // SP 0x000000000 MP 0x1404798E0 {"botsetstance", 0x8350}, // SP 0x000000000 MP 0x14047A0F0 {"botsetscriptmove", 0x8351}, // SP 0x000000000 MP 0x140479F70 @@ -1618,8 +1618,8 @@ namespace scripting {"botgetscriptgoalradius", 0x8359}, // SP 0x000000000 MP 0x1404785F0 {"botgetscriptgoalyaw", 0x835A}, // SP 0x000000000 MP 0x1404786F0 {"botgetscriptgoaltype", 0x835B}, // SP 0x000000000 MP 0x140478670 - {"_meth_835D", 0x835D}, // SP 0x000000000 MP 0x140478850 - {"_meth_835E", 0x835E}, // SP 0x000000000 MP 0x140478E10 + {"_meth_835d", 0x835D}, // SP 0x000000000 MP 0x140478850 + {"_meth_835e", 0x835E}, // SP 0x000000000 MP 0x140478E10 {"botfindnoderandom", 0x835F}, // SP 0x000000000 MP 0x140477D00 {"botmemoryevent", 0x8360}, // SP 0x000000000 MP 0x140478B70 {"_meth_8362", 0x8362}, // SP 0x000000000 MP 0x140478EB0 @@ -1630,11 +1630,11 @@ namespace scripting {"botsetdifficulty", 0x8368}, // SP 0x000000000 MP 0x1404797B0 {"botgetdifficulty", 0x8369}, // SP 0x000000000 MP 0x140477E90 {"botgetworldclosestedge", 0x836A}, // SP 0x000000000 MP 0x140478770 - {"_meth_836B", 0x836B}, // SP 0x000000000 MP 0x140478990 + {"_meth_836b", 0x836B}, // SP 0x000000000 MP 0x140478990 {"botpredictseepoint", 0x836C}, // SP 0x000000000 MP 0x140479420 {"botcanseeentity", 0x836D}, // SP 0x000000000 MP 0x140477A90 {"botgetnodesonpath", 0x836E}, // SP 0x000000000 MP 0x140478230 - {"_meth_836F", 0x836F}, // SP 0x000000000 MP 0x140479020 + {"_meth_836f", 0x836F}, // SP 0x000000000 MP 0x140479020 {"_meth_8371", 0x8371}, // SP 0x000000000 MP 0x140477FD0 {"botsetawareness", 0x8372}, // SP 0x000000000 MP 0x140479720 {"_meth_8373", 0x8373}, // SP 0x000000000 MP 0x140479610 @@ -1644,10 +1644,10 @@ namespace scripting {"botsetdifficultysetting", 0x8378}, // SP 0x000000000 MP 0x140479840 {"botgetdifficultysetting", 0x8379}, // SP 0x000000000 MP 0x140477F20 {"botgetpathdist", 0x837A}, // SP 0x000000000 MP 0x1404782F0 - {"_meth_837B", 0x837B}, // SP 0x000000000 MP 0x140478910 - {"_meth_837C", 0x837C}, // SP 0x000000000 MP 0x140479510 + {"_meth_837b", 0x837B}, // SP 0x000000000 MP 0x140478910 + {"_meth_837c", 0x837C}, // SP 0x000000000 MP 0x140479510 {"botclearbutton", 0x837D}, // SP 0x000000000 MP 0x140477B70 - {"_meth_837E", 0x837E}, // SP 0x000000000 MP 0x1404791D0 + {"_meth_837e", 0x837E}, // SP 0x000000000 MP 0x1404791D0 {"getnodenumber", 0x837F}, // SP 0x000000000 MP 0x14032E760 {"setclientowner", 0x8380}, // SP 0x000000000 MP 0x14037AD60 {"_meth_8381", 0x8381}, // SP 0x000000000 MP 0x14037A3B0 @@ -1659,7 +1659,7 @@ namespace scripting {"_meth_8388", 0x8388}, // SP 0x000000000 MP 0x14044EF90 {"_meth_8389", 0x8389}, // SP 0x000000000 MP 0x14044E610 {"setagentattacker", 0x838A}, // SP 0x000000000 MP 0x14044EE40 - {"_meth_838B", 0x838B}, // SP 0x000000000 MP 0x14044E0E0 + {"_meth_838b", 0x838B}, // SP 0x000000000 MP 0x14044E0E0 {"agentcanseesentient", 0x838C}, // SP 0x000000000 MP 0x14044DF00 {"setwaypoint", 0x838D}, // SP 0x000000000 MP 0x140450B20 {"setgoalpos", 0x838E}, // SP 0x000000000 MP 0x140450120 @@ -1681,98 +1681,98 @@ namespace scripting {"setviewheight", 0x839E}, // SP 0x000000000 MP 0x140450AA0 {"claimnode", 0x839F}, // SP 0x000000000 MP 0x14044F370 {"relinquishclaimednode", 0x83A0}, // SP 0x000000000 MP 0x14044FC90 - {"_meth_83A1", 0x83A1}, // SP 0x14026DD90 MP 0x14033BCE0 - {"_meth_83A2", 0x83A2}, // SP 0x14026DE40 MP 0x14033BD90 - {"_meth_83A3", 0x83A3}, // SP 0x14026DEB0 MP 0x14033BDF0 - {"_meth_83A4", 0x83A4}, // SP 0x14026DF20 MP 0x14033BE50 - {"_meth_83A5", 0x83A5}, // SP 0x1402A84A0 MP 0x000000000 - {"_meth_83A6", 0x83A6}, // SP 0x140260B80 MP 0x14032CDC0 - {"_meth_83A7", 0x83A7}, // SP 0x140260DE0 MP 0x14032CEA0 - {"_meth_83A8", 0x83A8}, // SP 0x140268480 MP 0x000000000 - {"_meth_83A9", 0x83A9}, // SP 0x1402A8750 MP 0x000000000 - {"_meth_83AA", 0x83AA}, // SP 0x1402A8860 MP 0x000000000 - {"_meth_83AB", 0x83AB}, // SP 0x140268330 MP 0x000000000 - {"_meth_83AC", 0x83AC}, // SP 0x140268410 MP 0x000000000 - {"_meth_83AD", 0x83AD}, // SP 0x1402683A0 MP 0x000000000 - {"_meth_83B0", 0x83B0}, // SP 0x1405D92F0 MP 0x14032CC20 - {"_meth_83B1", 0x83B1}, // SP 0x1402670A0 MP 0x14032B5D0 - {"_meth_83B2", 0x83B2}, // SP 0x140267250 MP 0x14032B7B0 - {"_meth_83B3", 0x83B3}, // SP 0x1404651B0 MP 0x14055F010 - {"_meth_83B4", 0x83B4}, // SP 0x1404651C0 MP 0x14055F020 - {"_meth_83B5", 0x83B5}, // SP 0x000000000 MP 0x14037BCD0 - {"_meth_83B6", 0x83B6}, // SP 0x14029C100 MP 0x140367570 - {"_meth_83B7", 0x83B7}, // SP 0x140299860 MP 0x140364840 - {"_meth_83B8", 0x83B8}, // SP 0x14028E830 MP 0x140364960 - {"_meth_83B9", 0x83B9}, // SP 0x140261C60 MP 0x14032D930 - {"_meth_83BA", 0x83BA}, // SP 0x140462CB0 MP 0x1405614F0 - {"_meth_83BB", 0x83BB}, // SP 0x140462D60 MP 0x1405615A0 - {"_meth_83BC", 0x83BC}, // SP 0x140462DE0 MP 0x140561620 - {"_meth_83BD", 0x83BD}, // SP 0x14028AB00 MP 0x000000000 - {"_meth_83BE", 0x83BE}, // SP 0x140263B80 MP 0x140330060 - {"_meth_83BF", 0x83BF}, // SP 0x140263C60 MP 0x140330200 - {"_meth_83C0", 0x83C0}, // SP 0x140263F70 MP 0x140330470 - {"_meth_83C1", 0x83C1}, // SP 0x1402B3B00 MP 0x14037F840 - {"_meth_83C2", 0x83C2}, // SP 0x1402D7D50 MP 0x1400778A0 - {"_meth_83C3", 0x83C3}, // SP 0x1404623A0 MP 0x140560AC0 - {"_meth_83C4", 0x83C4}, // SP 0x1405D92F0 MP 0x14032D370 - {"_meth_83C5", 0x83C5}, // SP 0x14028AA90 MP 0x000000000 - {"_meth_83C6", 0x83C6}, // SP 0x14024AEF0 MP 0x000000000 - {"_meth_83C7", 0x83C7}, // SP 0x14024B000 MP 0x000000000 - {"_meth_83C8", 0x83C8}, // SP 0x14024B340 MP 0x000000000 - {"_meth_83C9", 0x83C9}, // SP 0x14024B420 MP 0x000000000 - {"_meth_83CA", 0x83CA}, // SP 0x14024B6D0 MP 0x000000000 - {"_meth_83CB", 0x83CB}, // SP 0x14024B660 MP 0x000000000 - {"_meth_83CC", 0x83CC}, // SP 0x14024B740 MP 0x000000000 - {"_meth_83CD", 0x83CD}, // SP 0x14024B7A0 MP 0x000000000 + {"_meth_83a1", 0x83A1}, // SP 0x14026DD90 MP 0x14033BCE0 + {"_meth_83a2", 0x83A2}, // SP 0x14026DE40 MP 0x14033BD90 + {"_meth_83a3", 0x83A3}, // SP 0x14026DEB0 MP 0x14033BDF0 + {"_meth_83a4", 0x83A4}, // SP 0x14026DF20 MP 0x14033BE50 + {"_meth_83a5", 0x83A5}, // SP 0x1402A84A0 MP 0x000000000 + {"_meth_83a6", 0x83A6}, // SP 0x140260B80 MP 0x14032CDC0 + {"_meth_83a7", 0x83A7}, // SP 0x140260DE0 MP 0x14032CEA0 + {"_meth_83a8", 0x83A8}, // SP 0x140268480 MP 0x000000000 + {"_meth_83a9", 0x83A9}, // SP 0x1402A8750 MP 0x000000000 + {"_meth_83aa", 0x83AA}, // SP 0x1402A8860 MP 0x000000000 + {"_meth_83ab", 0x83AB}, // SP 0x140268330 MP 0x000000000 + {"_meth_83ac", 0x83AC}, // SP 0x140268410 MP 0x000000000 + {"_meth_83ad", 0x83AD}, // SP 0x1402683A0 MP 0x000000000 + {"_meth_83b0", 0x83B0}, // SP 0x1405D92F0 MP 0x14032CC20 + {"_meth_83b1", 0x83B1}, // SP 0x1402670A0 MP 0x14032B5D0 + {"_meth_83b2", 0x83B2}, // SP 0x140267250 MP 0x14032B7B0 + {"_meth_83b3", 0x83B3}, // SP 0x1404651B0 MP 0x14055F010 + {"_meth_83b4", 0x83B4}, // SP 0x1404651C0 MP 0x14055F020 + {"_meth_83b5", 0x83B5}, // SP 0x000000000 MP 0x14037BCD0 + {"_meth_83b6", 0x83B6}, // SP 0x14029C100 MP 0x140367570 + {"_meth_83b7", 0x83B7}, // SP 0x140299860 MP 0x140364840 + {"_meth_83b8", 0x83B8}, // SP 0x14028E830 MP 0x140364960 + {"_meth_83b9", 0x83B9}, // SP 0x140261C60 MP 0x14032D930 + {"_meth_83ba", 0x83BA}, // SP 0x140462CB0 MP 0x1405614F0 + {"_meth_83bb", 0x83BB}, // SP 0x140462D60 MP 0x1405615A0 + {"_meth_83bc", 0x83BC}, // SP 0x140462DE0 MP 0x140561620 + {"_meth_83bd", 0x83BD}, // SP 0x14028AB00 MP 0x000000000 + {"_meth_83be", 0x83BE}, // SP 0x140263B80 MP 0x140330060 + {"_meth_83bf", 0x83BF}, // SP 0x140263C60 MP 0x140330200 + {"_meth_83c0", 0x83C0}, // SP 0x140263F70 MP 0x140330470 + {"_meth_83c1", 0x83C1}, // SP 0x1402B3B00 MP 0x14037F840 + {"_meth_83c2", 0x83C2}, // SP 0x1402D7D50 MP 0x1400778A0 + {"_meth_83c3", 0x83C3}, // SP 0x1404623A0 MP 0x140560AC0 + {"_meth_83c4", 0x83C4}, // SP 0x1405D92F0 MP 0x14032D370 + {"_meth_83c5", 0x83C5}, // SP 0x14028AA90 MP 0x000000000 + {"_meth_83c6", 0x83C6}, // SP 0x14024AEF0 MP 0x000000000 + {"_meth_83c7", 0x83C7}, // SP 0x14024B000 MP 0x000000000 + {"_meth_83c8", 0x83C8}, // SP 0x14024B340 MP 0x000000000 + {"_meth_83c9", 0x83C9}, // SP 0x14024B420 MP 0x000000000 + {"_meth_83ca", 0x83CA}, // SP 0x14024B6D0 MP 0x000000000 + {"_meth_83cb", 0x83CB}, // SP 0x14024B660 MP 0x000000000 + {"_meth_83cc", 0x83CC}, // SP 0x14024B740 MP 0x000000000 + {"_meth_83cd", 0x83CD}, // SP 0x14024B7A0 MP 0x000000000 {"setanimclass", 0x83CE}, // SP 0x000000000 MP 0x1400781E0 {"enableanimstate", 0x83CF}, // SP 0x000000000 MP 0x140077CB0 - {"_meth_83D0", 0x83D0}, // SP 0x000000000 MP 0x140078250 + {"_meth_83d0", 0x83D0}, // SP 0x000000000 MP 0x140078250 {"getanimentry", 0x83D1}, // SP 0x000000000 MP 0x140077DF0 {"getanimentryname", 0x83D2}, // SP 0x000000000 MP 0x140077FA0 {"getanimentryalias", 0x83D3}, // SP 0x000000000 MP 0x140077E80 {"getanimentrycount", 0x83D4}, // SP 0x000000000 MP 0x140077EE0 - {"_meth_83D5", 0x83D5}, // SP 0x1402AE190 MP 0x000000000 + {"_meth_83d5", 0x83D5}, // SP 0x1402AE190 MP 0x000000000 {"issprinting", 0x83D6}, // SP 0x1402613C0 MP 0x14032CB20 - {"_meth_83D7", 0x83D7}, // SP 0x140291320 MP 0x000000000 - {"_meth_83D8", 0x83D8}, // SP 0x1402495B0 MP 0x000000000 - {"_meth_83D9", 0x83D9}, // SP 0x1405D92F0 MP 0x140358020 - {"_meth_83DA", 0x83DA}, // SP 0x140264C80 MP 0x000000000 - {"_meth_83DB", 0x83DB}, // SP 0x140264C80 MP 0x000000000 - {"_meth_83DC", 0x83DC}, // SP 0x140261B80 MP 0x14032D800 + {"_meth_83d7", 0x83D7}, // SP 0x140291320 MP 0x000000000 + {"_meth_83d8", 0x83D8}, // SP 0x1402495B0 MP 0x000000000 + {"_meth_83d9", 0x83D9}, // SP 0x1405D92F0 MP 0x140358020 + {"_meth_83da", 0x83DA}, // SP 0x140264C80 MP 0x000000000 + {"_meth_83db", 0x83DB}, // SP 0x140264C80 MP 0x000000000 + {"_meth_83dc", 0x83DC}, // SP 0x140261B80 MP 0x14032D800 {"rotateto", 0x83DD}, // SP 0x1402B3200 MP 0x14037EF90 {"getlookaheaddir", 0x83DE}, // SP 0x000000000 MP 0x14044F710 {"getpathgoalpos", 0x83DF}, // SP 0x000000000 MP 0x14044FAD0 - {"_meth_83E0", 0x83E0}, // SP 0x1402A15D0 MP 0x14036E1F0 + {"_meth_83e0", 0x83E0}, // SP 0x1402A15D0 MP 0x14036E1F0 {"setcorpsefalling", 0x83E1}, // SP 0x000000000 MP 0x140374840 {"setsurfacetype", 0x83E2}, // SP 0x14029FD00 MP 0x140358090 - {"_meth_83E3", 0x83E3}, // SP 0x1402A0C60 MP 0x140369520 - {"_meth_83E4", 0x83E4}, // SP 0x1402A20D0 MP 0x140369FE0 - {"_meth_83E5", 0x83E5}, // SP 0x1405D92F0 MP 0x14033B020 - {"_meth_83E6", 0x83E6}, // SP 0x1402A7B00 MP 0x000000000 - {"_meth_83E7", 0x83E7}, // SP 0x1402A7C90 MP 0x000000000 + {"_meth_83e3", 0x83E3}, // SP 0x1402A0C60 MP 0x140369520 + {"_meth_83e4", 0x83E4}, // SP 0x1402A20D0 MP 0x140369FE0 + {"_meth_83e5", 0x83E5}, // SP 0x1405D92F0 MP 0x14033B020 + {"_meth_83e6", 0x83E6}, // SP 0x1402A7B00 MP 0x000000000 + {"_meth_83e7", 0x83E7}, // SP 0x1402A7C90 MP 0x000000000 {"visionsetstage", 0x83E8}, // SP 0x140263140 MP 0x14032F7A0 {"hudoutlineenableforclients", 0x83E9}, // SP 0x14026D2E0 MP 0x14033B450 {"getlinkedparent", 0x83EA}, // SP 0x14028DB50 MP 0x140359B60 {"getmovingplatformparent", 0x83EB}, // SP 0x14028E2A0 MP 0x14035A4D0 - {"_meth_83EC", 0x83EC}, // SP 0x000000000 MP 0x14032CEF0 - {"_meth_83ED", 0x83ED}, // SP 0x1402ADF90 MP 0x000000000 - {"_meth_83EF", 0x83EF}, // SP 0x1402A0B60 MP 0x14036A5C0 - {"_meth_83F0", 0x83F0}, // SP 0x14029F670 MP 0x140369790 + {"_meth_83ec", 0x83EC}, // SP 0x000000000 MP 0x14032CEF0 + {"_meth_83ed", 0x83ED}, // SP 0x1402ADF90 MP 0x000000000 + {"_meth_83ef", 0x83EF}, // SP 0x1402A0B60 MP 0x14036A5C0 + {"_meth_83f0", 0x83F0}, // SP 0x14029F670 MP 0x140369790 {"makevehiclenotcollidewithplayers", 0x83F1}, // SP 0x1402913E0 MP 0x14035B490 - {"_meth_83F2", 0x83F2}, // SP 0x140269130 MP 0x000000000 - {"_meth_83F3", 0x83F3}, // SP 0x140269190 MP 0x000000000 + {"_meth_83f2", 0x83F2}, // SP 0x140269130 MP 0x000000000 + {"_meth_83f3", 0x83F3}, // SP 0x140269190 MP 0x000000000 {"setscriptablepartstate", 0x83F4}, // SP 0x1402A0760 MP 0x1403589E0 - {"_meth_83F5", 0x83F5}, // SP 0x1405D92F0 MP 0x140359100 - {"_meth_83F6", 0x83F6}, // SP 0x1402A15D0 MP 0x14036E200 - {"_meth_83F7", 0x83F7}, // SP 0x140465020 MP 0x140560DF0 - {"_meth_83F8", 0x83F8}, // SP 0x1405D92F0 MP 0x1403636B0 - {"_meth_83F9", 0x83F9}, // SP 0x1405D92F0 MP 0x140363830 + {"_meth_83f5", 0x83F5}, // SP 0x1405D92F0 MP 0x140359100 + {"_meth_83f6", 0x83F6}, // SP 0x1402A15D0 MP 0x14036E200 + {"_meth_83f7", 0x83F7}, // SP 0x140465020 MP 0x140560DF0 + {"_meth_83f8", 0x83F8}, // SP 0x1405D92F0 MP 0x1403636B0 + {"_meth_83f9", 0x83F9}, // SP 0x1405D92F0 MP 0x140363830 {"motionblurhqdisable", 0x83FA}, // SP 0x14029BA30 MP 0x140363EA0 - {"_meth_83FB", 0x83FB}, // SP 0x14029BC20 MP 0x1403640D0 - {"_meth_83FC", 0x83FC}, // SP 0x1402AA870 MP 0x000000000 - {"_meth_83FD", 0x83FD}, // SP 0x14024AD20 MP 0x000000000 + {"_meth_83fb", 0x83FB}, // SP 0x14029BC20 MP 0x1403640D0 + {"_meth_83fc", 0x83FC}, // SP 0x1402AA870 MP 0x000000000 + {"_meth_83fd", 0x83FD}, // SP 0x14024AD20 MP 0x000000000 {"worldpointtoscreenpos", 0x83FE}, // SP 0x140297A40 MP 0x140360C90 - {"_meth_83FF", 0x83FF}, // SP 0x1402974B0 MP 0x000000000 + {"_meth_83ff", 0x83FF}, // SP 0x1402974B0 MP 0x000000000 {"_meth_8400", 0x8400}, // SP 0x1402498E0 MP 0x000000000 {"_meth_8401", 0x8401}, // SP 0x000000000 MP 0x140477D90 {"_meth_8402", 0x8402}, // SP 0x140263950 MP 0x000000000 @@ -1783,11 +1783,11 @@ namespace scripting {"emissiveblend", 0x8407}, // SP 0x000000000 MP 0x140375810 {"_meth_8408", 0x8408}, // SP 0x1402687F0 MP 0x000000000 {"_meth_8409", 0x8409}, // SP 0x140268840 MP 0x000000000 - {"_meth_840A", 0x840A}, // SP 0x1402AF930 MP 0x000000000 - {"_meth_840B", 0x840B}, // SP 0x1402AE490 MP 0x000000000 - {"_meth_840C", 0x840C}, // SP 0x1402AE5D0 MP 0x000000000 - {"_meth_840D", 0x840D}, // SP 0x1402B4000 MP 0x14037FDE0 - {"_meth_840E", 0x840E}, // SP 0x1402B40B0 MP 0x14037FE90 + {"_meth_840a", 0x840A}, // SP 0x1402AF930 MP 0x000000000 + {"_meth_840b", 0x840B}, // SP 0x1402AE490 MP 0x000000000 + {"_meth_840c", 0x840C}, // SP 0x1402AE5D0 MP 0x000000000 + {"_meth_840d", 0x840D}, // SP 0x1402B4000 MP 0x14037FDE0 + {"_meth_840e", 0x840E}, // SP 0x1402B40B0 MP 0x14037FE90 {"physicsgetlinspeed", 0x840F}, // SP 0x1402B4160 MP 0x14037FF40 {"_meth_8410", 0x8410}, // SP 0x1402B41F0 MP 0x140380000 {"physicsgetangvel", 0x8411}, // SP 0x1402B42B0 MP 0x1403800E0 @@ -1799,12 +1799,12 @@ namespace scripting {"setgrenadethrowscale", 0x8417}, // SP 0x000000000 MP 0x14036F610 {"ismantling", 0x8418}, // SP 0x000000000 MP 0x140357DB0 {"_meth_8419", 0x8419}, // SP 0x000000000 MP 0x1403767E0 - {"_meth_841A", 0x841A}, // SP 0x1405D92F0 MP 0x1403630D0 - {"_meth_841B", 0x841B}, // SP 0x1405D92F0 MP 0x140363500 - {"_meth_841C", 0x841C}, // SP 0x1405D92F0 MP 0x140363590 - {"_meth_841D", 0x841D}, // SP 0x1405D92F0 MP 0x140363620 + {"_meth_841a", 0x841A}, // SP 0x1405D92F0 MP 0x1403630D0 + {"_meth_841b", 0x841B}, // SP 0x1405D92F0 MP 0x140363500 + {"_meth_841c", 0x841C}, // SP 0x1405D92F0 MP 0x140363590 + {"_meth_841d", 0x841D}, // SP 0x1405D92F0 MP 0x140363620 {"turretsetbarrelspinenabled", 0x841E}, // SP 0x140299270 MP 0x140364190 - {"_meth_841F", 0x841F}, // SP 0x000000000 MP 0x1403326E0 + {"_meth_841f", 0x841F}, // SP 0x000000000 MP 0x1403326E0 {"autospotoverlayoff", 0x8420}, // SP 0x000000000 MP 0x1403328E0 {"_meth_8421", 0x8421}, // SP 0x14029FEB0 MP 0x140369B60 {"_meth_8422", 0x8422}, // SP 0x1402A00C0 MP 0x140369E10 @@ -1815,12 +1815,12 @@ namespace scripting {"getcorpseentity", 0x8427}, // SP 0x000000000 MP 0x1403748F0 {"_meth_8428", 0x8428}, // SP 0x1402ABE20 MP 0x000000000 {"_meth_8429", 0x8429}, // SP 0x000000000 MP 0x140379520 - {"_meth_842A", 0x842A}, // SP 0x000000000 MP 0x140379B70 + {"_meth_842a", 0x842A}, // SP 0x000000000 MP 0x140379B70 {"queuedialogforplayer", 0x842B}, // SP 0x000000000 MP 0x1403785F0 {"setmlgcameradefaults", 0x842C}, // SP 0x000000000 MP 0x1403321B0 - {"_meth_842D", 0x842D}, // SP 0x000000000 MP 0x140334A60 - {"_meth_842E", 0x842E}, // SP 0x140262C10 MP 0x14032F2B0 - {"_meth_842F", 0x842F}, // SP 0x140262D40 MP 0x14032F480 + {"_meth_842d", 0x842D}, // SP 0x000000000 MP 0x140334A60 + {"_meth_842e", 0x842E}, // SP 0x140262C10 MP 0x14032F2B0 + {"_meth_842f", 0x842F}, // SP 0x140262D40 MP 0x14032F480 {"_meth_8430", 0x8430}, // SP 0x1405D92F0 MP 0x000000000 {"getlinkedchildren", 0x8431}, // SP 0x14028E020 MP 0x14035A3A0 {"_meth_8432", 0x8432}, // SP 0x000000000 MP 0x140479320 @@ -1830,12 +1830,12 @@ namespace scripting {"setscriptabledamageowner", 0x8437}, // SP 0x1402A0440 MP 0x1403586F0 {"_meth_8438", 0x8438}, // SP 0x1402A0B00 MP 0x140358FF0 {"_meth_8439", 0x8439}, // SP 0x000000000 MP 0x140379890 - {"_meth_843A", 0x843A}, // SP 0x14024B810 MP 0x000000000 - {"_meth_843B", 0x843B}, // SP 0x14024B8B0 MP 0x000000000 - {"_meth_843C", 0x843C}, // SP 0x140265900 MP 0x1403294C0 - {"_meth_843D", 0x843D}, // SP 0x14024BCE0 MP 0x000000000 - {"_meth_843E", 0x843E}, // SP 0x14029EC40 MP 0x140368630 - {"_meth_843F", 0x843F}, // SP 0x1405D92F0 MP 0x14032D4E0 + {"_meth_843a", 0x843A}, // SP 0x14024B810 MP 0x000000000 + {"_meth_843b", 0x843B}, // SP 0x14024B8B0 MP 0x000000000 + {"_meth_843c", 0x843C}, // SP 0x140265900 MP 0x1403294C0 + {"_meth_843d", 0x843D}, // SP 0x14024BCE0 MP 0x000000000 + {"_meth_843e", 0x843E}, // SP 0x14029EC40 MP 0x140368630 + {"_meth_843f", 0x843F}, // SP 0x1405D92F0 MP 0x14032D4E0 {"_meth_8440", 0x8440}, // SP 0x1404639C0 MP 0x140562210 {"_meth_8441", 0x8441}, // SP 0x140462EA0 MP 0x1405616E0 {"_meth_8442", 0x8442}, // SP 0x1402A36A0 MP 0x140358B60 @@ -1846,12 +1846,12 @@ namespace scripting {"_meth_8447", 0x8447}, // SP 0x1405D92F0 MP 0x140363840 {"_meth_8448", 0x8448}, // SP 0x1405D92F0 MP 0x140363A50 {"_meth_8449", 0x8449}, // SP 0x1402611B0 MP 0x14032C860 - {"_meth_844A", 0x844A}, // SP 0x140295480 MP 0x1403602C0 - {"_meth_844B", 0x844B}, // SP 0x140295650 MP 0x1403604C0 - {"_meth_844C", 0x844C}, // SP 0x140463020 MP 0x140561860 - {"_meth_844D", 0x844D}, // SP 0x140463040 MP 0x140561880 - {"_meth_844E", 0x844E}, // SP 0x140463060 MP 0x1405618A0 - {"_meth_844F", 0x844F}, // SP 0x140463080 MP 0x1405618C0 + {"_meth_844a", 0x844A}, // SP 0x140295480 MP 0x1403602C0 + {"_meth_844b", 0x844B}, // SP 0x140295650 MP 0x1403604C0 + {"_meth_844c", 0x844C}, // SP 0x140463020 MP 0x140561860 + {"_meth_844d", 0x844D}, // SP 0x140463040 MP 0x140561880 + {"_meth_844e", 0x844E}, // SP 0x140463060 MP 0x1405618A0 + {"_meth_844f", 0x844F}, // SP 0x140463080 MP 0x1405618C0 {"_meth_8450", 0x8450}, // SP 0x1402AC9E0 MP 0x000000000 {"_meth_8451", 0x8451}, // SP 0x1402ACB20 MP 0x000000000 {"_meth_8452", 0x8452}, // SP 0x140462F60 MP 0x1405617A0 @@ -1860,10 +1860,10 @@ namespace scripting {"_meth_8455", 0x8455}, // SP 0x1402AD1E0 MP 0x000000000 {"getvieworigin", 0x8458}, // SP 0x14029DE70 MP 0x140366600 {"_meth_8459", 0x8459}, // SP 0x140265E70 MP 0x140329A80 - {"_meth_845A", 0x845A}, // SP 0x000000000 MP 0x140359980 + {"_meth_845a", 0x845A}, // SP 0x000000000 MP 0x140359980 {"stopridingvehicle", 0x845B}, // SP 0x000000000 MP 0x14035A040 - {"_meth_845C", 0x845C}, // SP 0x140264C80 MP 0x000000000 - {"_meth_845D", 0x845D}, // SP 0x14028E7C0 MP 0x14035A8D0 + {"_meth_845c", 0x845C}, // SP 0x140264C80 MP 0x000000000 + {"_meth_845d", 0x845D}, // SP 0x14028E7C0 MP 0x14035A8D0 {"disablemissilestick", 0x845E}, // SP 0x000000000 MP 0x1403762F0 {"enablemissilestick", 0x845F}, // SP 0x000000000 MP 0x140376340 {"setmissileminimapvisible", 0x8460}, // SP 0x000000000 MP 0x140347ED0 @@ -1876,12 +1876,12 @@ namespace scripting {"_meth_8467", 0x8467}, // SP 0x1402B4950 MP 0x140380C30 {"_meth_8468", 0x8468}, // SP 0x1402A2E30 MP 0x000000000 {"_meth_8469", 0x8469}, // SP 0x1402A3290 MP 0x000000000 - {"_meth_846A", 0x846A}, // SP 0x1402A3360 MP 0x000000000 - {"_meth_846B", 0x846B}, // SP 0x1402A36C0 MP 0x000000000 - {"_meth_846C", 0x846C}, // SP 0x14028DBB0 MP 0x000000000 - {"_meth_846D", 0x846D}, // SP 0x140260B20 MP 0x000000000 - {"_meth_846E", 0x846E}, // SP 0x1402A8530 MP 0x000000000 - {"_meth_846F", 0x846F}, // SP 0x140463100 MP 0x140561940 + {"_meth_846a", 0x846A}, // SP 0x1402A3360 MP 0x000000000 + {"_meth_846b", 0x846B}, // SP 0x1402A36C0 MP 0x000000000 + {"_meth_846c", 0x846C}, // SP 0x14028DBB0 MP 0x000000000 + {"_meth_846d", 0x846D}, // SP 0x140260B20 MP 0x000000000 + {"_meth_846e", 0x846E}, // SP 0x1402A8530 MP 0x000000000 + {"_meth_846f", 0x846F}, // SP 0x140463100 MP 0x140561940 {"_meth_8470", 0x8470}, // SP 0x140463140 MP 0x140561980 {"_meth_8471", 0x8471}, // SP 0x1404631A0 MP 0x1405619E0 {"_meth_8472", 0x8472}, // SP 0x1404631F0 MP 0x140561A30 @@ -1892,12 +1892,12 @@ namespace scripting {"_meth_8477", 0x8477}, // SP 0x1402A85E0 MP 0x000000000 {"_meth_8478", 0x8478}, // SP 0x1402A86E0 MP 0x000000000 {"_meth_8479", 0x8479}, // SP 0x1405D92F0 MP 0x14032C130 - {"_meth_847A", 0x847A}, // SP 0x1405D92F0 MP 0x14032C420 - {"_meth_847B", 0x847B}, // SP 0x140462450 MP 0x140560B70 - {"_meth_847C", 0x847C}, // SP 0x1404624D0 MP 0x140560BF0 - {"_meth_847D", 0x847D}, // SP 0x140262900 MP 0x14032E940 - {"_meth_847E", 0x847E}, // SP 0x1402629A0 MP 0x14032E9D0 - {"_meth_847F", 0x847F}, // SP 0x14029CB70 MP 0x140367C30 + {"_meth_847a", 0x847A}, // SP 0x1405D92F0 MP 0x14032C420 + {"_meth_847b", 0x847B}, // SP 0x140462450 MP 0x140560B70 + {"_meth_847c", 0x847C}, // SP 0x1404624D0 MP 0x140560BF0 + {"_meth_847d", 0x847D}, // SP 0x140262900 MP 0x14032E940 + {"_meth_847e", 0x847E}, // SP 0x1402629A0 MP 0x14032E9D0 + {"_meth_847f", 0x847F}, // SP 0x14029CB70 MP 0x140367C30 {"_meth_8480", 0x8480}, // SP 0x140291DA0 MP 0x000000000 {"_meth_8481", 0x8481}, // SP 0x1405D92F0 MP 0x14032CD40 {"_meth_8482", 0x8482}, // SP 0x1405D92F0 MP 0x14032CD30 @@ -1908,12 +1908,12 @@ namespace scripting {"_meth_8487", 0x8487}, // SP 0x000000000 MP 0x140380630 {"_meth_8488", 0x8488}, // SP 0x1402B3150 MP 0x000000000 {"_meth_8489", 0x8489}, // SP 0x1405D92F0 MP 0x14032CD20 - {"_meth_848A", 0x848A}, // SP 0x140465030 MP 0x140563790 - {"_meth_848B", 0x848B}, // SP 0x140465020 MP 0x140563720 - {"_meth_848C", 0x848C}, // SP 0x1402641A0 MP 0x140330610 - {"_meth_848D", 0x848D}, // SP 0x140264320 MP 0x140330840 - {"_meth_848E", 0x848E}, // SP 0x140264550 MP 0x140330970 - {"_meth_848F", 0x848F}, // SP 0x1402694A0 MP 0x000000000 + {"_meth_848a", 0x848A}, // SP 0x140465030 MP 0x140563790 + {"_meth_848b", 0x848B}, // SP 0x140465020 MP 0x140563720 + {"_meth_848c", 0x848C}, // SP 0x1402641A0 MP 0x140330610 + {"_meth_848d", 0x848D}, // SP 0x140264320 MP 0x140330840 + {"_meth_848e", 0x848E}, // SP 0x140264550 MP 0x140330970 + {"_meth_848f", 0x848F}, // SP 0x1402694A0 MP 0x000000000 {"_meth_8490", 0x8490}, // SP 0x1405D92F0 MP 0x14035E610 {"_meth_8491", 0x8491}, // SP 0x000000000 MP 0x14037A4A0 {"_meth_8492", 0x8492}, // SP 0x000000000 MP 0x14037A510 @@ -1924,103 +1924,103 @@ namespace scripting {"_meth_8497", 0x8497}, // SP 0x000000000 MP 0x140376030 {"_meth_8498", 0x8498}, // SP 0x140266500 MP 0x14032AB70 {"_meth_8499", 0x8499}, // SP 0x140266B20 MP 0x14032AF60 - {"_meth_849A", 0x849A}, // SP 0x1405D92F0 MP 0x14032CCB0 - {"_meth_849B", 0x849B}, // SP 0x000000000 MP 0x140375470 - {"_meth_849C", 0x849C}, // SP 0x000000000 MP 0x140375490 - {"_meth_849D", 0x849D}, // SP 0x000000000 MP 0x140375640 - {"_meth_849E", 0x849E}, // SP 0x000000000 MP 0x140375650 - {"_meth_849F", 0x849F}, // SP 0x000000000 MP 0x140375660 - {"_meth_84A0", 0x84A0}, // SP 0x000000000 MP 0x140375680 - {"_meth_84A1", 0x84A1}, // SP 0x000000000 MP 0x140375670 - {"_meth_84A2", 0x84A2}, // SP 0x000000000 MP 0x1403756C0 - {"_meth_84A3", 0x84A3}, // SP 0x000000000 MP 0x1403757F0 - {"_meth_84A4", 0x84A4}, // SP 0x000000000 MP 0x1403756B0 - {"_meth_84A5", 0x84A5}, // SP 0x14029FDA0 MP 0x140369CB0 - {"_meth_84A6", 0x84A6}, // SP 0x1402A02F0 MP 0x14036A120 - {"_meth_84A7", 0x84A7}, // SP 0x1402A04A0 MP 0x14036A190 - {"_meth_84A8", 0x84A8}, // SP 0x1402A0FE0 MP 0x14036A960 - {"_meth_84A9", 0x84A9}, // SP 0x140465C50 MP 0x14055FBF0 - {"_meth_84AA", 0x84AA}, // SP 0x1402979E0 MP 0x1403625A0 - {"_meth_84AB", 0x84AB}, // SP 0x140297E40 MP 0x140362BD0 - {"_meth_84AC", 0x84AC}, // SP 0x140261E70 MP 0x14032DAE0 - {"_meth_84AD", 0x84AD}, // SP 0x1404663D0 MP 0x1405602E0 - {"_meth_84AE", 0x84AE}, // SP 0x1404664D0 MP 0x1405603E0 - {"_meth_84AF", 0x84AF}, // SP 0x000000000 MP 0x140333050 - {"_meth_84B0", 0x84B0}, // SP 0x1405D92F0 MP 0x140369850 - {"_meth_84B1", 0x84B1}, // SP 0x1402922D0 MP 0x14035E650 - {"_meth_84B2", 0x84B2}, // SP 0x1402925B0 MP 0x14035E660 - {"_meth_84B3", 0x84B3}, // SP 0x140292CD0 MP 0x14035E700 - {"_meth_84B4", 0x84B4}, // SP 0x140292FC0 MP 0x14035E720 - {"_meth_84B5", 0x84B5}, // SP 0x1405D92F0 MP 0x140364AA0 - {"_meth_84B6", 0x84B6}, // SP 0x1405D92F0 MP 0x14036BC80 - {"_meth_84B7", 0x84B7}, // SP 0x1404655C0 MP 0x14055F460 - {"_meth_84B8", 0x84B8}, // SP 0x1402A09C0 MP 0x14036A6A0 - {"_meth_84B9", 0x84B9}, // SP 0x000000000 MP 0x1403807B0 - {"_meth_84BB", 0x84BB}, // SP 0x1402643F0 MP 0x140330910 - {"_meth_84BC", 0x84BC}, // SP 0x140264500 MP 0x140330A20 - {"_meth_84BD", 0x84BD}, // SP 0x000000000 MP 0x1403330D0 - {"_meth_84BE", 0x84BE}, // SP 0x000000000 MP 0x1403335E0 - {"_meth_84BF", 0x84BF}, // SP 0x140265260 MP 0x1403311D0 - {"_meth_84C0", 0x84C0}, // SP 0x140265710 MP 0x1403291C0 - {"_meth_84C1", 0x84C1}, // SP 0x000000000 MP 0x1403766D0 - {"_meth_84C2", 0x84C2}, // SP 0x14029E430 MP 0x14036AA10 - {"_meth_84C3", 0x84C3}, // SP 0x140463250 MP 0x140561A90 - {"_meth_84C4", 0x84C4}, // SP 0x000000000 MP 0x140450E40 - {"_meth_84C5", 0x84C5}, // SP 0x000000000 MP 0x140450B10 - {"_meth_84C6", 0x84C6}, // SP 0x140260790 MP 0x14032BD80 - {"_meth_84C7", 0x84C7}, // SP 0x140260590 MP 0x000000000 - {"_meth_84C8", 0x84C8}, // SP 0x1402606E0 MP 0x000000000 - {"_meth_84C9", 0x84C9}, // SP 0x140464D30 MP 0x1405634E0 - {"_meth_84CA", 0x84CA}, // SP 0x140464DC0 MP 0x140563580 - {"_meth_84CB", 0x84CB}, // SP 0x000000000 MP 0x140334CC0 - {"_meth_84CC", 0x84CC}, // SP 0x140463270 MP 0x140561AB0 - {"_meth_84CD", 0x84CD}, // SP 0x1402A1470 MP 0x14036A8C0 - {"_meth_84CE", 0x84CE}, // SP 0x1402A15E0 MP 0x14036AD30 - {"_meth_84CF", 0x84CF}, // SP 0x14029ED60 MP 0x1403685E0 - {"_meth_84D0", 0x84D0}, // SP 0x14029EED0 MP 0x1403687A0 - {"_meth_84D1", 0x84D1}, // SP 0x14029F130 MP 0x1403687F0 - {"_meth_84D2", 0x84D2}, // SP 0x14029F300 MP 0x140368AC0 - {"_meth_84D3", 0x84D3}, // SP 0x14029F350 MP 0x140368CE0 - {"_meth_84D4", 0x84D4}, // SP 0x14029F410 MP 0x140368D50 - {"_meth_84D5", 0x84D5}, // SP 0x14029F530 MP 0x140368DF0 - {"_meth_84D6", 0x84D6}, // SP 0x14029F5E0 MP 0x140368ED0 - {"_meth_84D8", 0x84D8}, // SP 0x1402674E0 MP 0x14032B4A0 - {"_meth_84D9", 0x84D9}, // SP 0x1402B4400 MP 0x140380280 - {"_meth_84DA", 0x84DA}, // SP 0x000000000 MP 0x14035B2A0 - {"_meth_84DB", 0x84DB}, // SP 0x140248770 MP 0x000000000 - {"_meth_84DC", 0x84DC}, // SP 0x140461FF0 MP 0x000000000 - {"_meth_84DF", 0x84DF}, // SP 0x14028DF20 MP 0x14035B180 - {"_meth_84E0", 0x84E0}, // SP 0x14026E2F0 MP 0x14033C220 - {"_meth_84E1", 0x84E1}, // SP 0x1404632B0 MP 0x140561AF0 - {"_meth_84E2", 0x84E2}, // SP 0x000000000 MP 0x14036F110 - {"_meth_84E3", 0x84E3}, // SP 0x140264A30 MP 0x140331120 - {"_meth_84E4", 0x84E4}, // SP 0x1405D92F0 MP 0x1403604A0 - {"_meth_84E5", 0x84E5}, // SP 0x1402A88B0 MP 0x000000000 - {"_meth_84E6", 0x84E6}, // SP 0x1405D92F0 MP 0x14036C920 - {"_meth_84E8", 0x84E8}, // SP 0x140264970 MP 0x140330E00 - {"_meth_84E9", 0x84E9}, // SP 0x1402649D0 MP 0x140330E10 - {"_meth_84EA", 0x84EA}, // SP 0x14028ABB0 MP 0x000000000 - {"_meth_84EB", 0x84EB}, // SP 0x14029AF70 MP 0x140364720 - {"_meth_84EC", 0x84EC}, // SP 0x1402A11C0 MP 0x140359610 - {"_meth_84ED", 0x84ED}, // SP 0x140293540 MP 0x140360150 - {"_meth_84EE", 0x84EE}, // SP 0x140298540 MP 0x140361720 - {"_meth_84EF", 0x84EF}, // SP 0x14029B960 MP 0x140363B90 - {"_meth_84F0", 0x84F0}, // SP 0x1404643D0 MP 0x140562AB0 - {"_meth_84F1", 0x84F1}, // SP 0x1404644E0 MP 0x140562BE0 - {"_meth_84F2", 0x84F2}, // SP 0x1405D92F0 MP 0x14035B8C0 - {"_meth_84F3", 0x84F3}, // SP 0x1405D92F0 MP 0x14035B990 - {"_meth_84F4", 0x84F4}, // SP 0x14028E1A0 MP 0x14035B280 - {"_meth_84F5", 0x84F5}, // SP 0x14028E1A0 MP 0x14035B360 - {"_meth_84F6", 0x84F6}, // SP 0x1405D92F0 MP 0x14035B390 - {"_meth_84F7", 0x84F7}, // SP 0x14028E830 MP 0x14035B3A0 - {"_meth_84F8", 0x84F8}, // SP 0x14028E830 MP 0x14035B430 - {"_meth_84F9", 0x84F9}, // SP 0x14028E830 MP 0x14035B540 - {"_meth_84FA", 0x84FA}, // SP 0x1405D92F0 MP 0x14035B7A0 - {"_meth_84FB", 0x84FB}, // SP 0x14029EDE0 MP 0x14036EA10 - {"_meth_84FC", 0x84FC}, // SP 0x140290D70 MP 0x14035A740 - {"_meth_84FD", 0x84FD}, // SP 0x000000000 MP 0x140334AC0 - {"_meth_84FE", 0x84FE}, // SP 0x000000000 MP 0x140376800 - {"_meth_84FF", 0x84FF}, // SP 0x000000000 MP 0x1403768C0 + {"_meth_849a", 0x849A}, // SP 0x1405D92F0 MP 0x14032CCB0 + {"_meth_849b", 0x849B}, // SP 0x000000000 MP 0x140375470 + {"_meth_849c", 0x849C}, // SP 0x000000000 MP 0x140375490 + {"_meth_849d", 0x849D}, // SP 0x000000000 MP 0x140375640 + {"_meth_849e", 0x849E}, // SP 0x000000000 MP 0x140375650 + {"_meth_849f", 0x849F}, // SP 0x000000000 MP 0x140375660 + {"_meth_84a0", 0x84A0}, // SP 0x000000000 MP 0x140375680 + {"_meth_84a1", 0x84A1}, // SP 0x000000000 MP 0x140375670 + {"_meth_84a2", 0x84A2}, // SP 0x000000000 MP 0x1403756C0 + {"_meth_84a3", 0x84A3}, // SP 0x000000000 MP 0x1403757F0 + {"_meth_84a4", 0x84A4}, // SP 0x000000000 MP 0x1403756B0 + {"_meth_84a5", 0x84A5}, // SP 0x14029FDA0 MP 0x140369CB0 + {"_meth_84a6", 0x84A6}, // SP 0x1402A02F0 MP 0x14036A120 + {"_meth_84a7", 0x84A7}, // SP 0x1402A04A0 MP 0x14036A190 + {"_meth_84a8", 0x84A8}, // SP 0x1402A0FE0 MP 0x14036A960 + {"_meth_84a9", 0x84A9}, // SP 0x140465C50 MP 0x14055FBF0 + {"_meth_84aa", 0x84AA}, // SP 0x1402979E0 MP 0x1403625A0 + {"_meth_84ab", 0x84AB}, // SP 0x140297E40 MP 0x140362BD0 + {"_meth_84ac", 0x84AC}, // SP 0x140261E70 MP 0x14032DAE0 + {"_meth_84ad", 0x84AD}, // SP 0x1404663D0 MP 0x1405602E0 + {"_meth_84ae", 0x84AE}, // SP 0x1404664D0 MP 0x1405603E0 + {"_meth_84af", 0x84AF}, // SP 0x000000000 MP 0x140333050 + {"_meth_84b0", 0x84B0}, // SP 0x1405D92F0 MP 0x140369850 + {"_meth_84b1", 0x84B1}, // SP 0x1402922D0 MP 0x14035E650 + {"_meth_84b2", 0x84B2}, // SP 0x1402925B0 MP 0x14035E660 + {"_meth_84b3", 0x84B3}, // SP 0x140292CD0 MP 0x14035E700 + {"_meth_84b4", 0x84B4}, // SP 0x140292FC0 MP 0x14035E720 + {"_meth_84b5", 0x84B5}, // SP 0x1405D92F0 MP 0x140364AA0 + {"_meth_84b6", 0x84B6}, // SP 0x1405D92F0 MP 0x14036BC80 + {"_meth_84b7", 0x84B7}, // SP 0x1404655C0 MP 0x14055F460 + {"_meth_84b8", 0x84B8}, // SP 0x1402A09C0 MP 0x14036A6A0 + {"_meth_84b9", 0x84B9}, // SP 0x000000000 MP 0x1403807B0 + {"_meth_84bb", 0x84BB}, // SP 0x1402643F0 MP 0x140330910 + {"_meth_84bc", 0x84BC}, // SP 0x140264500 MP 0x140330A20 + {"_meth_84bd", 0x84BD}, // SP 0x000000000 MP 0x1403330D0 + {"_meth_84be", 0x84BE}, // SP 0x000000000 MP 0x1403335E0 + {"_meth_84bf", 0x84BF}, // SP 0x140265260 MP 0x1403311D0 + {"_meth_84c0", 0x84C0}, // SP 0x140265710 MP 0x1403291C0 + {"_meth_84c1", 0x84C1}, // SP 0x000000000 MP 0x1403766D0 + {"_meth_84c2", 0x84C2}, // SP 0x14029E430 MP 0x14036AA10 + {"_meth_84c3", 0x84C3}, // SP 0x140463250 MP 0x140561A90 + {"_meth_84c4", 0x84C4}, // SP 0x000000000 MP 0x140450E40 + {"_meth_84c5", 0x84C5}, // SP 0x000000000 MP 0x140450B10 + {"_meth_84c6", 0x84C6}, // SP 0x140260790 MP 0x14032BD80 + {"_meth_84c7", 0x84C7}, // SP 0x140260590 MP 0x000000000 + {"_meth_84c8", 0x84C8}, // SP 0x1402606E0 MP 0x000000000 + {"_meth_84c9", 0x84C9}, // SP 0x140464D30 MP 0x1405634E0 + {"_meth_84ca", 0x84CA}, // SP 0x140464DC0 MP 0x140563580 + {"_meth_84cb", 0x84CB}, // SP 0x000000000 MP 0x140334CC0 + {"_meth_84cc", 0x84CC}, // SP 0x140463270 MP 0x140561AB0 + {"_meth_84cd", 0x84CD}, // SP 0x1402A1470 MP 0x14036A8C0 + {"_meth_84ce", 0x84CE}, // SP 0x1402A15E0 MP 0x14036AD30 + {"_meth_84cf", 0x84CF}, // SP 0x14029ED60 MP 0x1403685E0 + {"_meth_84d0", 0x84D0}, // SP 0x14029EED0 MP 0x1403687A0 + {"_meth_84d1", 0x84D1}, // SP 0x14029F130 MP 0x1403687F0 + {"_meth_84d2", 0x84D2}, // SP 0x14029F300 MP 0x140368AC0 + {"_meth_84d3", 0x84D3}, // SP 0x14029F350 MP 0x140368CE0 + {"_meth_84d4", 0x84D4}, // SP 0x14029F410 MP 0x140368D50 + {"_meth_84d5", 0x84D5}, // SP 0x14029F530 MP 0x140368DF0 + {"_meth_84d6", 0x84D6}, // SP 0x14029F5E0 MP 0x140368ED0 + {"_meth_84d8", 0x84D8}, // SP 0x1402674E0 MP 0x14032B4A0 + {"_meth_84d9", 0x84D9}, // SP 0x1402B4400 MP 0x140380280 + {"_meth_84da", 0x84DA}, // SP 0x000000000 MP 0x14035B2A0 + {"_meth_84db", 0x84DB}, // SP 0x140248770 MP 0x000000000 + {"_meth_84dc", 0x84DC}, // SP 0x140461FF0 MP 0x000000000 + {"_meth_84df", 0x84DF}, // SP 0x14028DF20 MP 0x14035B180 + {"_meth_84e0", 0x84E0}, // SP 0x14026E2F0 MP 0x14033C220 + {"_meth_84e1", 0x84E1}, // SP 0x1404632B0 MP 0x140561AF0 + {"_meth_84e2", 0x84E2}, // SP 0x000000000 MP 0x14036F110 + {"_meth_84e3", 0x84E3}, // SP 0x140264A30 MP 0x140331120 + {"_meth_84e4", 0x84E4}, // SP 0x1405D92F0 MP 0x1403604A0 + {"_meth_84e5", 0x84E5}, // SP 0x1402A88B0 MP 0x000000000 + {"_meth_84e6", 0x84E6}, // SP 0x1405D92F0 MP 0x14036C920 + {"_meth_84e8", 0x84E8}, // SP 0x140264970 MP 0x140330E00 + {"_meth_84e9", 0x84E9}, // SP 0x1402649D0 MP 0x140330E10 + {"_meth_84ea", 0x84EA}, // SP 0x14028ABB0 MP 0x000000000 + {"_meth_84eb", 0x84EB}, // SP 0x14029AF70 MP 0x140364720 + {"_meth_84ec", 0x84EC}, // SP 0x1402A11C0 MP 0x140359610 + {"_meth_84ed", 0x84ED}, // SP 0x140293540 MP 0x140360150 + {"_meth_84ee", 0x84EE}, // SP 0x140298540 MP 0x140361720 + {"_meth_84ef", 0x84EF}, // SP 0x14029B960 MP 0x140363B90 + {"_meth_84f0", 0x84F0}, // SP 0x1404643D0 MP 0x140562AB0 + {"_meth_84f1", 0x84F1}, // SP 0x1404644E0 MP 0x140562BE0 + {"_meth_84f2", 0x84F2}, // SP 0x1405D92F0 MP 0x14035B8C0 + {"_meth_84f3", 0x84F3}, // SP 0x1405D92F0 MP 0x14035B990 + {"_meth_84f4", 0x84F4}, // SP 0x14028E1A0 MP 0x14035B280 + {"_meth_84f5", 0x84F5}, // SP 0x14028E1A0 MP 0x14035B360 + {"_meth_84f6", 0x84F6}, // SP 0x1405D92F0 MP 0x14035B390 + {"_meth_84f7", 0x84F7}, // SP 0x14028E830 MP 0x14035B3A0 + {"_meth_84f8", 0x84F8}, // SP 0x14028E830 MP 0x14035B430 + {"_meth_84f9", 0x84F9}, // SP 0x14028E830 MP 0x14035B540 + {"_meth_84fa", 0x84FA}, // SP 0x1405D92F0 MP 0x14035B7A0 + {"_meth_84fb", 0x84FB}, // SP 0x14029EDE0 MP 0x14036EA10 + {"_meth_84fc", 0x84FC}, // SP 0x140290D70 MP 0x14035A740 + {"_meth_84fd", 0x84FD}, // SP 0x000000000 MP 0x140334AC0 + {"_meth_84fe", 0x84FE}, // SP 0x000000000 MP 0x140376800 + {"_meth_84ff", 0x84FF}, // SP 0x000000000 MP 0x1403768C0 {"_meth_8500", 0x8500}, // SP 0x14028F5A0 MP 0x14035A550 {"_meth_8501", 0x8501}, // SP 0x14028E4D0 MP 0x140359550 {"_meth_8502", 0x8502}, // SP 0x000000000 MP 0x1403767F0 @@ -2031,12 +2031,12 @@ namespace scripting {"_meth_8507", 0x8507}, // SP 0x000000000 MP 0x14037AAF0 {"_meth_8508", 0x8508}, // SP 0x000000000 MP 0x140332BC0 {"_meth_8509", 0x8509}, // SP 0x1402AC990 MP 0x000000000 - {"_meth_850A", 0x850A}, // SP 0x1402646B0 MP 0x140330A80 - {"_meth_850B", 0x850B}, // SP 0x14026DCB0 MP 0x14033BC10 - {"_meth_850C", 0x850C}, // SP 0x000000000 MP 0x140376020 - {"_meth_850D", 0x850D}, // SP 0x14029E8F0 MP 0x1403682B0 - {"_meth_850E", 0x850E}, // SP 0x14029ED00 MP 0x140368570 - {"_meth_850F", 0x850F}, // SP 0x14029A7B0 MP 0x140362600 + {"_meth_850a", 0x850A}, // SP 0x1402646B0 MP 0x140330A80 + {"_meth_850b", 0x850B}, // SP 0x14026DCB0 MP 0x14033BC10 + {"_meth_850c", 0x850C}, // SP 0x000000000 MP 0x140376020 + {"_meth_850d", 0x850D}, // SP 0x14029E8F0 MP 0x1403682B0 + {"_meth_850e", 0x850E}, // SP 0x14029ED00 MP 0x140368570 + {"_meth_850f", 0x850F}, // SP 0x14029A7B0 MP 0x140362600 {"_meth_8510", 0x8510}, // SP 0x140267840 MP 0x14032BE50 {"_meth_8511", 0x8511}, // SP 0x140290ED0 MP 0x14035A8E0 {"_meth_8512", 0x8512}, // SP 0x1404632E0 MP 0x140561B20 @@ -2047,12 +2047,12 @@ namespace scripting {"_meth_8517", 0x8517}, // SP 0x000000000 MP 0x1403747A0 {"_meth_8518", 0x8518}, // SP 0x14026D400 MP 0x14033B580 {"_meth_8519", 0x8519}, // SP 0x000000000 MP 0x140376990 - {"_meth_851A", 0x851A}, // SP 0x140261370 MP 0x14032C9D0 - {"_meth_851B", 0x851B}, // SP 0x14029F3C0 MP 0x14036EEC0 - {"_meth_851C", 0x851C}, // SP 0x14028E830 MP 0x14036E3D0 - {"_meth_851D", 0x851D}, // SP 0x1402B4480 MP 0x140380300 - {"_meth_851E", 0x851E}, // SP 0x14028A8B0 MP 0x000000000 - {"_meth_851F", 0x851F}, // SP 0x000000000 MP 0x140333EE0 + {"_meth_851a", 0x851A}, // SP 0x140261370 MP 0x14032C9D0 + {"_meth_851b", 0x851B}, // SP 0x14029F3C0 MP 0x14036EEC0 + {"_meth_851c", 0x851C}, // SP 0x14028E830 MP 0x14036E3D0 + {"_meth_851d", 0x851D}, // SP 0x1402B4480 MP 0x140380300 + {"_meth_851e", 0x851E}, // SP 0x14028A8B0 MP 0x000000000 + {"_meth_851f", 0x851F}, // SP 0x000000000 MP 0x140333EE0 {"_meth_8520", 0x8520}, // SP 0x000000000 MP 0x14044EEC0 {"_meth_8521", 0x8521}, // SP 0x140263930 MP 0x000000000 {"_meth_8522", 0x8522}, // SP 0x000000000 MP 0x140332340 @@ -2063,12 +2063,12 @@ namespace scripting {"_meth_8527", 0x8527}, // SP 0x14026DD20 MP 0x14033BC70 {"_meth_8528", 0x8528}, // SP 0x000000000 MP 0x140332E80 {"_meth_8529", 0x8529}, // SP 0x14028F7C0 MP 0x14035C9C0 - {"_meth_852A", 0x852A}, // SP 0x140297EF0 MP 0x14035F080 - {"_meth_852B", 0x852B}, // SP 0x000000000 MP 0x140332AD0 - {"_meth_852C", 0x852C}, // SP 0x000000000 MP 0x140331F50 - {"_meth_852D", 0x852D}, // SP 0x14028E830 MP 0x14035B7E0 - {"_meth_852E", 0x852E}, // SP 0x000000000 MP 0x140376A60 - {"_meth_852F", 0x852F}, // SP 0x000000000 MP 0x1404508B0 + {"_meth_852a", 0x852A}, // SP 0x140297EF0 MP 0x14035F080 + {"_meth_852b", 0x852B}, // SP 0x000000000 MP 0x140332AD0 + {"_meth_852c", 0x852C}, // SP 0x000000000 MP 0x140331F50 + {"_meth_852d", 0x852D}, // SP 0x14028E830 MP 0x14035B7E0 + {"_meth_852e", 0x852E}, // SP 0x000000000 MP 0x140376A60 + {"_meth_852f", 0x852F}, // SP 0x000000000 MP 0x1404508B0 {"_meth_8530", 0x8530}, // SP 0x000000000 MP 0x14044F1E0 {"_meth_8531", 0x8531}, // SP 0x000000000 MP 0x1404503F0 {"_meth_8532", 0x8532}, // SP 0x000000000 MP 0x140333250 @@ -2079,12 +2079,12 @@ namespace scripting {"_meth_8537", 0x8537}, // SP 0x000000000 MP 0x1404502E0 {"_meth_8538", 0x8538}, // SP 0x000000000 MP 0x1404506F0 {"_meth_8539", 0x8539}, // SP 0x000000000 MP 0x140333F40 - {"_meth_853A", 0x853A}, // SP 0x000000000 MP 0x14037F320 - {"_meth_853B", 0x853B}, // SP 0x000000000 MP 0x14044E080 - {"_meth_853C", 0x853C}, // SP 0x14028F0D0 MP 0x14035BF40 - {"_meth_853D", 0x853D}, // SP 0x14028E830 MP 0x14032CCA0 - {"_meth_853E", 0x853E}, // SP 0x000000000 MP 0x140376AC0 - {"_meth_853F", 0x853F}, // SP 0x000000000 MP 0x14044DFF0 + {"_meth_853a", 0x853A}, // SP 0x000000000 MP 0x14037F320 + {"_meth_853b", 0x853B}, // SP 0x000000000 MP 0x14044E080 + {"_meth_853c", 0x853C}, // SP 0x14028F0D0 MP 0x14035BF40 + {"_meth_853d", 0x853D}, // SP 0x14028E830 MP 0x14032CCA0 + {"_meth_853e", 0x853E}, // SP 0x000000000 MP 0x140376AC0 + {"_meth_853f", 0x853F}, // SP 0x000000000 MP 0x14044DFF0 {"_meth_8540", 0x8540}, // SP 0x140299D70 MP 0x140363160 {"_meth_8541", 0x8541}, // SP 0x14028F260 MP 0x14035C380 {"_meth_8542", 0x8542}, // SP 0x000000000 MP 0x140376C00 @@ -2094,12 +2094,12 @@ namespace scripting {"_meth_8547", 0x8547}, // SP 0x000000000 MP 0x140450C20 {"_meth_8548", 0x8548}, // SP 0x140262130 MP 0x14032DF00 {"_meth_8549", 0x8549}, // SP 0x000000000 MP 0x140333FA0 - {"_meth_854A", 0x854A}, // SP 0x000000000 MP 0x140376C90 - {"_meth_854B", 0x854B}, // SP 0x000000000 MP 0x14044FBA0 - {"_meth_854C", 0x854C}, // SP 0x000000000 MP 0x1403331F0 - {"_meth_854D", 0x854D}, // SP 0x140290CE0 MP 0x14035C300 - {"_meth_854E", 0x854E}, // SP 0x000000000 MP 0x140450A10 - {"_meth_854F", 0x854F}, // SP 0x000000000 MP 0x14044FC10 + {"_meth_854a", 0x854A}, // SP 0x000000000 MP 0x140376C90 + {"_meth_854b", 0x854B}, // SP 0x000000000 MP 0x14044FBA0 + {"_meth_854c", 0x854C}, // SP 0x000000000 MP 0x1403331F0 + {"_meth_854d", 0x854D}, // SP 0x140290CE0 MP 0x14035C300 + {"_meth_854e", 0x854E}, // SP 0x000000000 MP 0x140450A10 + {"_meth_854f", 0x854F}, // SP 0x000000000 MP 0x14044FC10 {"_meth_8550", 0x8550}, // SP 0x1402B4720 MP 0x1403809E0 {"_meth_8551", 0x8551}, // SP 0x1402A15D0 MP 0x14035FB60 {"_meth_8552", 0x8552}, // SP 0x000000000 MP 0x140450C30 @@ -2110,12 +2110,12 @@ namespace scripting {"_meth_8557", 0x8557}, // SP 0x000000000 MP 0x1403749D0 {"_meth_8558", 0x8558}, // SP 0x000000000 MP 0x140078140 {"_meth_8559", 0x8559}, // SP 0x1405D92F0 MP 0x14032D760 - {"_meth_855A", 0x855A}, // SP 0x1405D92F0 MP 0x14032D770 - {"_meth_855B", 0x855B}, // SP 0x1405D92F0 MP 0x14032D7F0 - {"_meth_855C", 0x855C}, // SP 0x000000000 MP 0x140376CB0 - {"_meth_855D", 0x855D}, // SP 0x1402A0220 MP 0x1403585F0 - {"_meth_855E", 0x855E}, // SP 0x140293780 MP 0x14035E8C0 - {"_meth_855F", 0x855F}, // SP 0x000000000 MP 0x140374EC0 + {"_meth_855a", 0x855A}, // SP 0x1405D92F0 MP 0x14032D770 + {"_meth_855b", 0x855B}, // SP 0x1405D92F0 MP 0x14032D7F0 + {"_meth_855c", 0x855C}, // SP 0x000000000 MP 0x140376CB0 + {"_meth_855d", 0x855D}, // SP 0x1402A0220 MP 0x1403585F0 + {"_meth_855e", 0x855E}, // SP 0x140293780 MP 0x14035E8C0 + {"_meth_855f", 0x855F}, // SP 0x000000000 MP 0x140374EC0 {"_meth_8560", 0x8560}, // SP 0x000000000 MP 0x140374F70 {"_meth_8561", 0x8561}, // SP 0x140292D90 MP 0x14035FB10 {"_meth_8562", 0x8562}, // SP 0x140293080 MP 0x14035FD80 @@ -2126,12 +2126,12 @@ namespace scripting {"_meth_8567", 0x8567}, // SP 0x140248F70 MP 0x000000000 {"_meth_8568", 0x8568}, // SP 0x1402A3820 MP 0x14036E3F0 {"_meth_8569", 0x8569}, // SP 0x1402982F0 MP 0x140363510 - {"_meth_856A", 0x856A}, // SP 0x1402984C0 MP 0x140363630 - {"_meth_856B", 0x856B}, // SP 0x140296FA0 MP 0x1403619C0 - {"_meth_856C", 0x856C}, // SP 0x140297420 MP 0x140361BA0 - {"_meth_856D", 0x856D}, // SP 0x140297640 MP 0x140361E60 - {"_meth_856E", 0x856E}, // SP 0x14028ABF0 MP 0x000000000 - {"_meth_856F", 0x856F}, // SP 0x14028AC10 MP 0x000000000 + {"_meth_856a", 0x856A}, // SP 0x1402984C0 MP 0x140363630 + {"_meth_856b", 0x856B}, // SP 0x140296FA0 MP 0x1403619C0 + {"_meth_856c", 0x856C}, // SP 0x140297420 MP 0x140361BA0 + {"_meth_856d", 0x856D}, // SP 0x140297640 MP 0x140361E60 + {"_meth_856e", 0x856E}, // SP 0x14028ABF0 MP 0x000000000 + {"_meth_856f", 0x856F}, // SP 0x14028AC10 MP 0x000000000 {"_meth_8570", 0x8570}, // SP 0x14028AC60 MP 0x000000000 {"_meth_8571", 0x8571}, // SP 0x140249010 MP 0x000000000 {"_meth_8572", 0x8572}, // SP 0x14024AE00 MP 0x000000000 @@ -2142,12 +2142,12 @@ namespace scripting {"_meth_8577", 0x8577}, // SP 0x000000000 MP 0x140333650 {"_meth_8578", 0x8578}, // SP 0x140297D90 MP 0x14035FFF0 {"_meth_8579", 0x8579}, // SP 0x1402933D0 MP 0x14035FF90 - {"_meth_857A", 0x857A}, // SP 0x000000000 MP 0x1403336F0 - {"_meth_857B", 0x857B}, // SP 0x000000000 MP 0x14032B050 - {"_meth_857C", 0x857C}, // SP 0x1405D92F0 MP 0x14036D0E0 - {"_meth_857D", 0x857D}, // SP 0x000000000 MP 0x140334820 - {"_meth_857E", 0x857E}, // SP 0x000000000 MP 0x1403348E0 - {"_meth_857F", 0x857F}, // SP 0x000000000 MP 0x1403329F0 + {"_meth_857a", 0x857A}, // SP 0x000000000 MP 0x1403336F0 + {"_meth_857b", 0x857B}, // SP 0x000000000 MP 0x14032B050 + {"_meth_857c", 0x857C}, // SP 0x1405D92F0 MP 0x14036D0E0 + {"_meth_857d", 0x857D}, // SP 0x000000000 MP 0x140334820 + {"_meth_857e", 0x857E}, // SP 0x000000000 MP 0x1403348E0 + {"_meth_857f", 0x857F}, // SP 0x000000000 MP 0x1403329F0 }; std::unordered_map token_map = From 03df877e427cfd06df9e8ad660e2fc95a94ec83e Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 11 Mar 2022 19:12:55 +0100 Subject: [PATCH 066/346] Update function tables --- src/client/game/scripting/function_tables.cpp | 88 ++++++++++++++----- src/client/main.cpp | 1 - 2 files changed, 65 insertions(+), 24 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index cf233a30..1286912f 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -742,6 +742,7 @@ namespace scripting {"getchallengerewarditem", 0x2DB}, // SP 0x000000000 MP 0x14037ABB0 {"setentplayerxuidforemblem", 0x2DC}, // SP 0x000000000 MP 0x14037E1C0 {"resetentplayerxuidforemblems", 0x2DD}, // SP 0x000000000 MP 0x14037E1B0 + {"nodesetremotemissilename", 0x2DE}, {"isshipbuild", 0x2DF}, // SP 0x140292220 MP 0x14036F7F0 {"strinsertnumericdelimiters", 0x2E0}, // SP 0x140297C80 MP 0x14035EDE0 {"isscriptedagent", 0x2E1}, // SP 0x000000000 MP 0x1403788D0 @@ -782,19 +783,19 @@ namespace scripting std::unordered_map method_map = { {"motionblurhqenable", 0x8000}, // SP 0x14029B0D0 MP 0x140362FD0 - {"_meth_8001", 0x8001}, // SP 0x1402A8AC0 MP 0x000000000 + {"setturretdismountorg", 0x8001}, // SP 0x1402A8AC0 MP 0x000000000 {"setdamagestage", 0x8002}, // SP 0x000000000 MP 0x14055A000 - {"_meth_8003", 0x8003}, // SP 0x000000000 MP 0x140378300 + {"playsoundtoteam", 0x8003}, // SP 0x000000000 MP 0x140378300 {"playsoundtoplayer", 0x8004}, // SP 0x000000000 MP 0x1403784F0 {"playerhide", 0x8005}, // SP 0x000000000 MP 0x14037AB70 - {"_meth_8006", 0x8006}, // SP 0x000000000 MP 0x14037ABD0 + {"playershow", 0x8006}, // SP 0x000000000 MP 0x14037ABD0 {"showtoplayer", 0x8007}, // SP 0x000000000 MP 0x14037AC50 - {"_meth_8008", 0x8008}, // SP 0x000000000 MP 0x14037ACB0 - {"_meth_8009", 0x8009}, // SP 0x000000000 MP 0x14037ACC0 + {"threatdetectedtoplayer", 0x8008}, // SP 0x000000000 MP 0x14037ACB0 + {"clearthreatdetected", 0x8009}, // SP 0x000000000 MP 0x14037ACC0 {"enableplayeruse", 0x800A}, // SP 0x000000000 MP 0x140374B10 {"disableplayeruse", 0x800B}, // SP 0x000000000 MP 0x140374BB0 - {"_meth_800c", 0x800C}, // SP 0x000000000 MP 0x140374D70 - {"_meth_800d", 0x800D}, // SP 0x000000000 MP 0x140374C90 + {"enableammogeneration", 0x800C}, // SP 0x000000000 MP 0x140374D70 + {"disableammogeneration", 0x800D}, // SP 0x000000000 MP 0x140374C90 {"makescrambler", 0x800E}, // SP 0x000000000 MP 0x14037B890 {"makeportableradar", 0x800F}, // SP 0x000000000 MP 0x14037B930 {"clearscrambler", 0x8010}, // SP 0x000000000 MP 0x14037B910 @@ -804,25 +805,26 @@ namespace scripting {"clientclaimtrigger", 0x8014}, // SP 0x000000000 MP 0x14037B220 {"clientreleasetrigger", 0x8015}, // SP 0x000000000 MP 0x14037B300 {"releaseclaimedtrigger", 0x8016}, // SP 0x000000000 MP 0x14037B510 - {"_meth_8017", 0x8017}, // SP 0x000000000 MP 0x14037AC10 - {"_meth_8018", 0x8018}, // SP 0x000000000 MP 0x14037ACD0 - {"_meth_8019", 0x8019}, // SP 0x000000000 MP 0x140378210 - {"_meth_801a", 0x801A}, // SP 0x14028F380 MP 0x14036F540 + {"isusingonlinedataoffline", 0x8017}, // SP 0x000000000 MP 0x14037AC10 + {"getrestedtime", 0x8018}, // SP 0x000000000 MP 0x14037ACD0 + {"sendleaderboards", 0x8019}, // SP 0x000000000 MP 0x140378210 + {"isonladder", 0x801A}, // SP 0x14028F380 MP 0x14036F540 {"getcorpseanim", 0x801B}, // SP 0x000000000 MP 0x14037BD60 {"playerforcedeathanim", 0x801C}, // SP 0x000000000 MP 0x140374A30 - {"_meth_801d", 0x801D}, // SP 0x14029DCF0 MP 0x140369D40 - {"_meth_801e", 0x801E}, // SP 0x1402AD230 MP 0x000000000 - {"_meth_801f", 0x801F}, // SP 0x1402AD490 MP 0x000000000 - {"_meth_8020", 0x8020}, // SP 0x1402AD4C0 MP 0x000000000 - {"_meth_8021", 0x8021}, // SP 0x1402AD640 MP 0x000000000 - {"_meth_8022", 0x8022}, // SP 0x1402AD660 MP 0x000000000 - {"_meth_8023", 0x8023}, // SP 0x1402AD920 MP 0x14037BA50 - {"_meth_8024", 0x8024}, // SP 0x1402ADA90 MP 0x000000000 - {"_meth_8025", 0x8025}, // SP 0x1405D92F0 MP 0x14035CB60 - {"_meth_8026", 0x8026}, // SP 0x1405D92F0 MP 0x140377C40 + {"attach", 0x801D}, // SP 0x14029DCF0 MP 0x140369D40 + {"getlightfovinner", 0x801E}, // SP 0x1402AD230 MP 0x000000000 + {"getlightfovouter", 0x801F}, // SP 0x1402AD490 MP 0x000000000 + {"setlightfovrange", 0x8020}, // SP 0x1402AD4C0 MP 0x000000000 + {"getlightexponent", 0x8021}, // SP 0x1402AD640 MP 0x000000000 + {"setlightexponent", 0x8022}, // SP 0x1402AD660 MP 0x000000000 + {"startragdoll", 0x8023}, // SP 0x1402AD920 MP 0x14037BA50 + {"startragdollfromimpact", 0x8024}, // SP 0x1402ADA90 MP 0x000000000 + {"queryshouldearlyragdoll", 0x8025}, // SP 0x1405D92F0 MP 0x14035CB60 + {"shouldearlyragdoll", 0x8026}, // SP 0x1405D92F0 MP 0x140377C40 + {"_meth_8027", 0x8027}, {"_meth_8028", 0x8028}, // SP 0x1402ADE80 MP 0x000000000 - {"_meth_8029", 0x8029}, // SP 0x14029AEC0 MP 0x140362D10 - {"_meth_802a", 0x802A}, // SP 0x14029E0E0 MP 0x14036A480 + {"thermaldrawenable", 0x8029}, // SP 0x14029AEC0 MP 0x140362D10 + {"detach", 0x802A}, // SP 0x14029E0E0 MP 0x14036A480 {"detachall", 0x802B}, // SP 0x14029E180 MP 0x14036A4C0 {"getattachsize", 0x802C}, // SP 0x1402A0610 MP 0x14036C860 {"getattachmodelname", 0x802D}, // SP 0x1402A0890 MP 0x14036CE90 @@ -882,12 +884,14 @@ namespace scripting {"_meth_8063", 0x8063}, // SP 0x1402A9BC0 MP 0x000000000 {"_meth_8064", 0x8064}, // SP 0x1402AABA0 MP 0x000000000 {"_meth_8065", 0x8065}, // SP 0x1402AAC10 MP 0x000000000 + {"_meth_8066", 0x8066}, {"setmode", 0x8067}, // SP 0x1402AD9A0 MP 0x140375030 {"_meth_8068", 0x8068}, // SP 0x1402ADCD0 MP 0x140375210 {"_meth_8069", 0x8069}, // SP 0x1402ADF10 MP 0x000000000 {"islinked", 0x806A}, // SP 0x14028D6B0 MP 0x1403598E0 {"enablelinkto", 0x806B}, // SP 0x14028EA50 MP 0x14035A950 {"_meth_806c", 0x806C}, // SP 0x1402ACB60 MP 0x000000000 + {"_meth_806d", 0x806D}, {"_meth_806e", 0x806E}, // SP 0x1402A27D0 MP 0x14035AB10 {"_meth_806f", 0x806F}, // SP 0x1402A23E0 MP 0x14035A9C0 {"_meth_8070", 0x8070}, // SP 0x1402A2980 MP 0x14035B0D0 @@ -935,6 +939,10 @@ namespace scripting {"_meth_809a", 0x809A}, // SP 0x1402AC1D0 MP 0x000000000 {"useby", 0x809B}, // SP 0x1402AC470 MP 0x140377D00 {"playsound", 0x809C}, // SP 0x1402AC9B0 MP 0x140377F40 + {"_meth_809d", 0x809D}, + {"_meth_809e", 0x809E}, + {"_meth_809f", 0x809F}, + {"_meth_80a0", 0x80A0}, {"playerlinkedoffsetdisable", 0x80A1}, // SP 0x140290320 MP 0x14035CAF0 {"playerlinkedsetviewznear", 0x80A2}, // SP 0x140290680 MP 0x14035CE40 {"playerlinkedsetusebaseangleforviewclamp", 0x80A3}, // SP 0x140290960 MP 0x14035D290 @@ -956,6 +964,8 @@ namespace scripting {"setmodel", 0x80B3}, // SP 0x14029C8F0 MP 0x1403677D0 {"_meth_80b4", 0x80B4}, // SP 0x14029A0F0 MP 0x140361C30 {"_meth_80b5", 0x80B5}, // SP 0x14029A250 MP 0x140361F90 + {"_meth_80b6", 0x80B6}, + {"_meth_80b7", 0x80B7}, {"thermalvisionon", 0x80B8}, // SP 0x14029A450 MP 0x1403623A0 {"thermalvisionoff", 0x80B9}, // SP 0x14029AAF0 MP 0x140362B70 {"_meth_80ba", 0x80BA}, // SP 0x14029BF20 MP 0x140364290 @@ -963,6 +973,7 @@ namespace scripting {"_meth_80bc", 0x80BC}, // SP 0x000000000 MP 0x140364910 {"autospotoverlayon", 0x80BD}, // SP 0x000000000 MP 0x140364A50 {"_meth_80be", 0x80BE}, // SP 0x000000000 MP 0x140364D40 + {"_meth_80bf", 0x80BF}, {"setcontents", 0x80C0}, // SP 0x140297CC0 MP 0x14035FDD0 {"makeusable", 0x80C1}, // SP 0x140297E90 MP 0x1403600D0 {"makeunusable", 0x80C2}, // SP 0x140297FF0 MP 0x140360320 @@ -1059,9 +1070,14 @@ namespace scripting {"_meth_811d", 0x811D}, // SP 0x140261A30 MP 0x14032D780 {"_meth_811e", 0x811E}, // SP 0x140269090 MP 0x000000000 {"_meth_811f", 0x811F}, // SP 0x140269510 MP 0x000000000 + {"_meth_8120", 0x8120}, {"_meth_8121", 0x8121}, // SP 0x1402692D0 MP 0x000000000 {"_meth_8122", 0x8122}, // SP 0x140269350 MP 0x000000000 {"_meth_8123", 0x8123}, // SP 0x140269650 MP 0x000000000 + {"_meth_8124", 0x8124}, + {"_meth_8125", 0x8125}, + {"_meth_8126", 0x8126}, + {"_meth_8127", 0x8127}, {"_meth_8128", 0x8128}, // SP 0x140269650 MP 0x000000000 {"_meth_8129", 0x8129}, // SP 0x140269370 MP 0x000000000 {"_meth_812a", 0x812A}, // SP 0x1402680B0 MP 0x000000000 @@ -1087,6 +1103,7 @@ namespace scripting {"_meth_813e", 0x813E}, // SP 0x1402D8040 MP 0x000000000 {"_meth_813f", 0x813F}, // SP 0x1402D80E0 MP 0x000000000 {"_meth_8140", 0x8140}, // SP 0x14028A390 MP 0x000000000 + {"_meth_8141", 0x8141}, {"_meth_8142", 0x8142}, // SP 0x14028A3D0 MP 0x000000000 {"_meth_8143", 0x8143}, // SP 0x14028A370 MP 0x000000000 {"_meth_8144", 0x8144}, // SP 0x14028A410 MP 0x000000000 @@ -1175,6 +1192,10 @@ namespace scripting {"_meth_8197", 0x8197}, // SP 0x140248640 MP 0x000000000 {"_meth_8198", 0x8198}, // SP 0x1402486A0 MP 0x000000000 {"_meth_8199", 0x8199}, // SP 0x1402486F0 MP 0x000000000 + {"_meth_819a", 0x819A}, + {"_meth_819b", 0x819B}, + {"_meth_819c", 0x819C}, + {"_meth_819d", 0x819D}, {"_meth_819e", 0x819E}, // SP 0x1402487C0 MP 0x000000000 {"_meth_819f", 0x819F}, // SP 0x140248870 MP 0x000000000 {"_meth_81a0", 0x81A0}, // SP 0x1402488C0 MP 0x000000000 @@ -1282,6 +1303,7 @@ namespace scripting {"_meth_8206", 0x8206}, // SP 0x000000000 MP 0x14035AB40 {"_meth_8207", 0x8207}, // SP 0x1402AA5F0 MP 0x000000000 {"_meth_8208", 0x8208}, // SP 0x000000000 MP 0x14035ABE0 + {"_meth_8209", 0x8209}, {"_meth_820a", 0x820A}, // SP 0x000000000 MP 0x14035B100 {"_meth_820b", 0x820B}, // SP 0x000000000 MP 0x14035B170 {"_meth_820c", 0x820C}, // SP 0x000000000 MP 0x14035B380 @@ -1335,6 +1357,7 @@ namespace scripting {"_meth_823c", 0x823C}, // SP 0x14029CF00 MP 0x000000000 {"_meth_823d", 0x823D}, // SP 0x140292BA0 MP 0x000000000 {"_meth_823e", 0x823E}, // SP 0x140292DF0 MP 0x000000000 + {"_meth_823f", 0x823F}, {"_meth_8240", 0x8240}, // SP 0x1402A3880 MP 0x000000000 {"_meth_8241", 0x8241}, // SP 0x140248AD0 MP 0x000000000 {"_meth_8242", 0x8242}, // SP 0x140248EA0 MP 0x000000000 @@ -1564,6 +1587,7 @@ namespace scripting {"_meth_8322", 0x8322}, // SP 0x140263330 MP 0x14032F4E0 {"openpopupmenu", 0x8323}, // SP 0x140263430 MP 0x14032F6C0 {"openpopupmenunomouse", 0x8324}, // SP 0x140263630 MP 0x14032F930 + {"_meth_8325", 0x8325}, {"freezecontrols", 0x8326}, // SP 0x140263B10 MP 0x14032FD60 {"disableusability", 0x8327}, // SP 0x140263C10 MP 0x14032FFE0 {"enableusability", 0x8328}, // SP 0x140263E40 MP 0x1403300F0 @@ -1618,14 +1642,17 @@ namespace scripting {"botgetscriptgoalradius", 0x8359}, // SP 0x000000000 MP 0x1404785F0 {"botgetscriptgoalyaw", 0x835A}, // SP 0x000000000 MP 0x1404786F0 {"botgetscriptgoaltype", 0x835B}, // SP 0x000000000 MP 0x140478670 + {"_meth_835c", 0x835C}, {"_meth_835d", 0x835D}, // SP 0x000000000 MP 0x140478850 {"_meth_835e", 0x835E}, // SP 0x000000000 MP 0x140478E10 {"botfindnoderandom", 0x835F}, // SP 0x000000000 MP 0x140477D00 {"botmemoryevent", 0x8360}, // SP 0x000000000 MP 0x140478B70 + {"_meth_8361", 0x8361}, {"_meth_8362", 0x8362}, // SP 0x000000000 MP 0x140478EB0 {"bothasscriptgoal", 0x8363}, // SP 0x000000000 MP 0x140478890 {"botgetpersonality", 0x8364}, // SP 0x000000000 MP 0x140478420 {"_meth_8365", 0x8365}, // SP 0x000000000 MP 0x14047A1C0 + {"_meth_8366", 0x8366}, {"botsetpersonality", 0x8367}, // SP 0x000000000 MP 0x140479A70 {"botsetdifficulty", 0x8368}, // SP 0x000000000 MP 0x1404797B0 {"botgetdifficulty", 0x8369}, // SP 0x000000000 MP 0x140477E90 @@ -1635,11 +1662,13 @@ namespace scripting {"botcanseeentity", 0x836D}, // SP 0x000000000 MP 0x140477A90 {"botgetnodesonpath", 0x836E}, // SP 0x000000000 MP 0x140478230 {"_meth_836f", 0x836F}, // SP 0x000000000 MP 0x140479020 + {"_meth_8370", 0x8370}, {"_meth_8371", 0x8371}, // SP 0x000000000 MP 0x140477FD0 {"botsetawareness", 0x8372}, // SP 0x000000000 MP 0x140479720 {"_meth_8373", 0x8373}, // SP 0x000000000 MP 0x140479610 {"botgetscriptgoalnode", 0x8374}, // SP 0x000000000 MP 0x140478560 {"botgetimperfectenemyinfo", 0x8375}, // SP 0x000000000 MP 0x1404780D0 + {"_meth_8376", 0x8376}, {"botsetpathingstyle", 0x8377}, // SP 0x000000000 MP 0x1404799A0 {"botsetdifficultysetting", 0x8378}, // SP 0x000000000 MP 0x140479840 {"botgetdifficultysetting", 0x8379}, // SP 0x000000000 MP 0x140477F20 @@ -1656,6 +1685,7 @@ namespace scripting {"nodeisdisconnected", 0x8384}, // SP 0x000000000 MP 0x14032E920 {"_meth_8385", 0x8385}, // SP 0x140262C60 MP 0x14032E340 {"_meth_8386", 0x8386}, // SP 0x000000000 MP 0x14037B1B0 + {"_meth_8387", 0x8387}, {"_meth_8388", 0x8388}, // SP 0x000000000 MP 0x14044EF90 {"_meth_8389", 0x8389}, // SP 0x000000000 MP 0x14044E610 {"setagentattacker", 0x838A}, // SP 0x000000000 MP 0x14044EE40 @@ -1694,6 +1724,8 @@ namespace scripting {"_meth_83ab", 0x83AB}, // SP 0x140268330 MP 0x000000000 {"_meth_83ac", 0x83AC}, // SP 0x140268410 MP 0x000000000 {"_meth_83ad", 0x83AD}, // SP 0x1402683A0 MP 0x000000000 + {"_meth_83ae", 0x83AE}, + {"_meth_83af", 0x83AF}, {"_meth_83b0", 0x83B0}, // SP 0x1405D92F0 MP 0x14032CC20 {"_meth_83b1", 0x83B1}, // SP 0x1402670A0 MP 0x14032B5D0 {"_meth_83b2", 0x83B2}, // SP 0x140267250 MP 0x14032B7B0 @@ -1756,6 +1788,7 @@ namespace scripting {"getmovingplatformparent", 0x83EB}, // SP 0x14028E2A0 MP 0x14035A4D0 {"_meth_83ec", 0x83EC}, // SP 0x000000000 MP 0x14032CEF0 {"_meth_83ed", 0x83ED}, // SP 0x1402ADF90 MP 0x000000000 + {"_meth_83ee", 0x83EE}, {"_meth_83ef", 0x83EF}, // SP 0x1402A0B60 MP 0x14036A5C0 {"_meth_83f0", 0x83F0}, // SP 0x14029F670 MP 0x140369790 {"makevehiclenotcollidewithplayers", 0x83F1}, // SP 0x1402913E0 MP 0x14035B490 @@ -1827,6 +1860,7 @@ namespace scripting {"playsoundonmovingent", 0x8433}, // SP 0x000000000 MP 0x140377F80 {"cancelmantle", 0x8434}, // SP 0x140266DD0 MP 0x14032B210 {"hasfemalecustomizationmodel", 0x8435}, // SP 0x000000000 MP 0x140332F50 + {"_meth_8436", 0x8436}, {"setscriptabledamageowner", 0x8437}, // SP 0x1402A0440 MP 0x1403586F0 {"_meth_8438", 0x8438}, // SP 0x1402A0B00 MP 0x140358FF0 {"_meth_8439", 0x8439}, // SP 0x000000000 MP 0x140379890 @@ -1858,6 +1892,8 @@ namespace scripting {"_meth_8453", 0x8453}, // SP 0x140261E30 MP 0x14032DC80 {"_meth_8454", 0x8454}, // SP 0x1402612F0 MP 0x000000000 {"_meth_8455", 0x8455}, // SP 0x1402AD1E0 MP 0x000000000 + {"_meth_8456", 0x8456}, + {"_meth_8457", 0x8457}, {"getvieworigin", 0x8458}, // SP 0x14029DE70 MP 0x140366600 {"_meth_8459", 0x8459}, // SP 0x140265E70 MP 0x140329A80 {"_meth_845a", 0x845A}, // SP 0x000000000 MP 0x140359980 @@ -1956,6 +1992,7 @@ namespace scripting {"_meth_84b7", 0x84B7}, // SP 0x1404655C0 MP 0x14055F460 {"_meth_84b8", 0x84B8}, // SP 0x1402A09C0 MP 0x14036A6A0 {"_meth_84b9", 0x84B9}, // SP 0x000000000 MP 0x1403807B0 + {"_meth_84ba", 0x84BA}, {"_meth_84bb", 0x84BB}, // SP 0x1402643F0 MP 0x140330910 {"_meth_84bc", 0x84BC}, // SP 0x140264500 MP 0x140330A20 {"_meth_84bd", 0x84BD}, // SP 0x000000000 MP 0x1403330D0 @@ -1984,11 +2021,14 @@ namespace scripting {"_meth_84d4", 0x84D4}, // SP 0x14029F410 MP 0x140368D50 {"_meth_84d5", 0x84D5}, // SP 0x14029F530 MP 0x140368DF0 {"_meth_84d6", 0x84D6}, // SP 0x14029F5E0 MP 0x140368ED0 + {"_meth_84d7", 0x84D7}, {"_meth_84d8", 0x84D8}, // SP 0x1402674E0 MP 0x14032B4A0 {"_meth_84d9", 0x84D9}, // SP 0x1402B4400 MP 0x140380280 {"_meth_84da", 0x84DA}, // SP 0x000000000 MP 0x14035B2A0 {"_meth_84db", 0x84DB}, // SP 0x140248770 MP 0x000000000 {"_meth_84dc", 0x84DC}, // SP 0x140461FF0 MP 0x000000000 + {"_meth_84dd", 0x84DD}, + {"_meth_84de", 0x84DE}, {"_meth_84df", 0x84DF}, // SP 0x14028DF20 MP 0x14035B180 {"_meth_84e0", 0x84E0}, // SP 0x14026E2F0 MP 0x14033C220 {"_meth_84e1", 0x84E1}, // SP 0x1404632B0 MP 0x140561AF0 @@ -1997,6 +2037,7 @@ namespace scripting {"_meth_84e4", 0x84E4}, // SP 0x1405D92F0 MP 0x1403604A0 {"_meth_84e5", 0x84E5}, // SP 0x1402A88B0 MP 0x000000000 {"_meth_84e6", 0x84E6}, // SP 0x1405D92F0 MP 0x14036C920 + {"_meth_84e7", 0x84E7}, {"_meth_84e8", 0x84E8}, // SP 0x140264970 MP 0x140330E00 {"_meth_84e9", 0x84E9}, // SP 0x1402649D0 MP 0x140330E10 {"_meth_84ea", 0x84EA}, // SP 0x14028ABB0 MP 0x000000000 @@ -2091,6 +2132,7 @@ namespace scripting {"_meth_8543", 0x8543}, // SP 0x000000000 MP 0x140375800 {"_meth_8544", 0x8544}, // SP 0x000000000 MP 0x14044FA10 {"_meth_8545", 0x8545}, // SP 0x000000000 MP 0x140333640 + {"_meth_8546", 0x8546}, {"_meth_8547", 0x8547}, // SP 0x000000000 MP 0x140450C20 {"_meth_8548", 0x8548}, // SP 0x140262130 MP 0x14032DF00 {"_meth_8549", 0x8549}, // SP 0x000000000 MP 0x140333FA0 diff --git a/src/client/main.cpp b/src/client/main.cpp index 519756b2..7329eb4c 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -50,7 +50,6 @@ launcher::mode detect_mode_from_arguments() return launcher::mode::none; } - FARPROC load_binary(const launcher::mode mode) { loader loader; From 1a5a5def5f6605939b270abc5bb46443cff2b24d Mon Sep 17 00:00:00 2001 From: DoktorSAS <62484597+DoktorSAS@users.noreply.github.com> Date: Fri, 11 Mar 2022 20:02:00 +0100 Subject: [PATCH 067/346] Update functions tables --- src/client/game/scripting/function_tables.cpp | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 1286912f..611f87c0 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -1366,11 +1366,11 @@ namespace scripting {"_meth_8245", 0x8245}, // SP 0x1402A24D0 MP 0x14036C5B0 {"trackerupdate", 0x8246}, // SP 0x14028DC50 MP 0x14036E800 {"pingplayer", 0x8247}, // SP 0x000000000 MP 0x140332B50 - {"_meth_8248", 0x8248}, // SP 0x140268FE0 MP 0x140332B40 + {"buttonpressed", 0x8248}, // SP 0x140268FE0 MP 0x140332B40 {"sayteam", 0x8249}, // SP 0x000000000 MP 0x1403345F0 {"sayall", 0x824A}, // SP 0x000000000 MP 0x1403346A0 {"_meth_824b", 0x824B}, // SP 0x000000000 MP 0x140332C90 - {"_meth_824c", 0x824C}, // SP 0x140265080 MP 0x140330FE0 + {"dropitem", 0x824C}, // SP 0x140265080 MP 0x140330FE0 {"dropscavengerbag", 0x824D}, // SP 0x000000000 MP 0x140332FB0 {"setjitterparams", 0x824E}, // SP 0x140461E80 MP 0x140560640 {"sethoverparams", 0x824F}, // SP 0x140461F50 MP 0x140560710 @@ -1399,8 +1399,8 @@ namespace scripting {"finishplayerdamage", 0x8266}, // SP 0x000000000 MP 0x1403337A0 {"suicide", 0x8267}, // SP 0x000000000 MP 0x140333E20 {"_meth_8268", 0x8268}, // SP 0x000000000 MP 0x140334010 - {"_meth_8269", 0x8269}, // SP 0x000000000 MP 0x1403340A0 - {"_meth_826a", 0x826A}, // SP 0x000000000 MP 0x140334120 + {"clientiprintln", 0x8269}, // SP 0x000000000 MP 0x1403340A0 + {"clientiprintlnbold", 0x826A}, // SP 0x000000000 MP 0x140334120 {"spawn", 0x826B}, // SP 0x000000000 MP 0x1403341A0 {"_meth_826c", 0x826C}, // SP 0x000000000 MP 0x140334230 {"_meth_826d", 0x826D}, // SP 0x000000000 MP 0x140334290 @@ -1441,8 +1441,8 @@ namespace scripting {"setmaxpitchroll", 0x8290}, // SP 0x140461CC0 MP 0x140560480 {"setairresitance", 0x8291}, // SP 0x140461D80 MP 0x140560540 {"setturningability", 0x8292}, // SP 0x140461E10 MP 0x1405605D0 - {"_meth_8293", 0x8293}, // SP 0x140260F20 MP 0x140334B90 - {"_meth_8294", 0x8294}, // SP 0x000000000 MP 0x140334D50 + {"getxuid", 0x8293}, // SP 0x140260F20 MP 0x140334B90 + {"getucdidhigh", 0x8294}, // SP 0x000000000 MP 0x140334D50 {"ismlgspectator", 0x8295}, // SP 0x000000000 MP 0x140334DB0 {"getclanidhigh", 0x8296}, // SP 0x000000000 MP 0x140334E10 {"getclanidlow", 0x8297}, // SP 0x000000000 MP 0x140334E70 @@ -1535,16 +1535,16 @@ namespace scripting {"setvelocity", 0x82EE}, // SP 0x1402601C0 MP 0x14032BBE0 {"_meth_82ef", 0x82EF}, // SP 0x140260AD0 MP 0x14032C3C0 {"_meth_82f0", 0x82F0}, // SP 0x140260E80 MP 0x14032C5E0 - {"_meth_82f1", 0x82F1}, // SP 0x1402677A0 MP 0x14032BE30 + {"playsound", 0x82F1}, // SP 0x1402677A0 MP 0x14032BE30 {"_meth_82f2", 0x82F2}, // SP 0x140260130 MP 0x14032BF20 - {"_meth_82f3", 0x82F3}, // SP 0x140264AD0 MP 0x140330E20 + {"setweaponammoclip", 0x82F3}, // SP 0x140264AD0 MP 0x140330E20 {"setweaponammostock", 0x82F4}, // SP 0x140264EB0 MP 0x140331350 - {"_meth_82f5", 0x82F5}, // SP 0x140265380 MP 0x1403293A0 + {"getweaponammoclip", 0x82F5}, // SP 0x140265380 MP 0x1403293A0 {"getweaponammostock", 0x82F6}, // SP 0x1402655D0 MP 0x140329580 {"_meth_82f7", 0x82F7}, // SP 0x140265820 MP 0x140329990 {"stoplocalsound", 0x82F8}, // SP 0x140265F20 MP 0x14032A3B0 {"setclientdvar", 0x82F9}, // SP 0x140266410 MP 0x14032A990 - {"_meth_82fa", 0x82FA}, // SP 0x1402666C0 MP 0x14032B260 + {"setclientdvars", 0x82FA}, // SP 0x1402666C0 MP 0x14032B260 {"_meth_82fb", 0x82FB}, // SP 0x000000000 MP 0x14032AC30 {"_meth_82fc", 0x82FC}, // SP 0x000000000 MP 0x14032AD80 {"allowads", 0x82FD}, // SP 0x140261130 MP 0x14032C940 @@ -1562,7 +1562,7 @@ namespace scripting {"getweaponslistitems", 0x8309}, // SP 0x1402622E0 MP 0x14032E230 {"_meth_830a", 0x830A}, // SP 0x140261090 MP 0x14032C720 {"_meth_830b", 0x830B}, // SP 0x140262F00 MP 0x14032EA90 - {"_meth_830c", 0x830C}, // SP 0x140263380 MP 0x14032F210 + {"takeweapon", 0x830C}, // SP 0x140263380 MP 0x14032F210 {"takeallweapons", 0x830D}, // SP 0x1402635B0 MP 0x14032F310 {"getcurrentweapon", 0x830E}, // SP 0x140263750 MP 0x14032F5E0 {"getcurrentprimaryweapon", 0x830F}, // SP 0x140263A30 MP 0x14032F860 @@ -1570,7 +1570,7 @@ namespace scripting {"givestartammo", 0x8311}, // SP 0x1402647A0 MP 0x140330740 {"switchtoweapon", 0x8312}, // SP 0x140264CA0 MP 0x140330D20 {"switchtoweaponimmediate", 0x8313}, // SP 0x140264E50 MP 0x140330D90 - {"_meth_8314", 0x8314}, // SP 0x140265950 MP 0x140329520 + {"gethybridscopestate", 0x8314}, // SP 0x140265950 MP 0x140329520 {"switchtooffhand", 0x8315}, // SP 0x140265B80 MP 0x1403296D0 {"_meth_8316", 0x8316}, // SP 0x140264440 MP 0x140330340 {"getcustomizationbody", 0x8317}, // SP 0x140264600 MP 0x140330520 @@ -1593,7 +1593,7 @@ namespace scripting {"enableusability", 0x8328}, // SP 0x140263E40 MP 0x1403300F0 {"_meth_8329", 0x8329}, // SP 0x140266C00 MP 0x14032B640 {"_meth_832a", 0x832A}, // SP 0x140266D10 MP 0x14032B800 - {"_meth_832b", 0x832B}, // SP 0x140266EA0 MP 0x14032B9C0 + {"setreverb", 0x832B}, // SP 0x140266EA0 MP 0x14032B9C0 {"_meth_832c", 0x832C}, // SP 0x140267180 MP 0x14032B9E0 {"deactivatechannelvolumes", 0x832D}, // SP 0x140267410 MP 0x14032BB00 {"_meth_832e", 0x832E}, // SP 0x140265FA0 MP 0x140329C00 @@ -1625,7 +1625,7 @@ namespace scripting {"forcethirdpersonwhenfollowing", 0x8348}, // SP 0x000000000 MP 0x140374D30 {"disableforcethirdpersonwhenfollowing", 0x8349}, // SP 0x000000000 MP 0x140374DD0 {"_meth_834a", 0x834A}, // SP 0x140260C10 MP 0x14032C5D0 - {"_meth_834b", 0x834B}, // SP 0x000000000 MP 0x14037B380 + {"setscriptmoverkillcam", 0x834B}, // SP 0x000000000 MP 0x14037B380 {"secondaryoffhandbuttonpressed", 0x834C}, // SP 0x140261D40 MP 0x14032D9C0 {"_meth_834d", 0x834D}, // SP 0x000000000 MP 0x140374B70 {"_meth_834e", 0x834E}, // SP 0x000000000 MP 0x140374C10 @@ -1767,7 +1767,7 @@ namespace scripting {"issprinting", 0x83D6}, // SP 0x1402613C0 MP 0x14032CB20 {"_meth_83d7", 0x83D7}, // SP 0x140291320 MP 0x000000000 {"_meth_83d8", 0x83D8}, // SP 0x1402495B0 MP 0x000000000 - {"_meth_83d9", 0x83D9}, // SP 0x1405D92F0 MP 0x140358020 + {"setclothtype", 0x83D9}, // SP 0x1405D92F0 MP 0x140358020 {"_meth_83da", 0x83DA}, // SP 0x140264C80 MP 0x000000000 {"_meth_83db", 0x83DB}, // SP 0x140264C80 MP 0x000000000 {"_meth_83dc", 0x83DC}, // SP 0x140261B80 MP 0x14032D800 @@ -1876,7 +1876,7 @@ namespace scripting {"_meth_8443", 0x8443}, // SP 0x140266090 MP 0x14032A550 {"_meth_8444", 0x8444}, // SP 0x1402A8A40 MP 0x000000000 {"_meth_8445", 0x8445}, // SP 0x1402A8A80 MP 0x000000000 - {"_meth_8446", 0x8446}, // SP 0x1402A2F70 MP 0x14036CC00 + {"getcacplayerdata", 0x8446}, // SP 0x1402A2F70 MP 0x14036CC00 {"_meth_8447", 0x8447}, // SP 0x1405D92F0 MP 0x140363840 {"_meth_8448", 0x8448}, // SP 0x1405D92F0 MP 0x140363A50 {"_meth_8449", 0x8449}, // SP 0x1402611B0 MP 0x14032C860 From 289b3b50c5b3b6c0fa7d4e5887c21b57bfaa96bc Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 11 Mar 2022 20:38:28 +0100 Subject: [PATCH 068/346] Update function_tables.cpp --- src/client/game/scripting/function_tables.cpp | 164 +++++++++--------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 1286912f..899c3bdb 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -828,107 +828,107 @@ namespace scripting {"detachall", 0x802B}, // SP 0x14029E180 MP 0x14036A4C0 {"getattachsize", 0x802C}, // SP 0x1402A0610 MP 0x14036C860 {"getattachmodelname", 0x802D}, // SP 0x1402A0890 MP 0x14036CE90 - {"_meth_802e", 0x802E}, // SP 0x1402A0A90 MP 0x14036D040 - {"_meth_802f", 0x802F}, // SP 0x1402AE150 MP 0x000000000 - {"_meth_8030", 0x8030}, // SP 0x1402AE270 MP 0x000000000 - {"_meth_8031", 0x8031}, // SP 0x1402AE410 MP 0x000000000 - {"_meth_8032", 0x8032}, // SP 0x1402AE620 MP 0x000000000 - {"_meth_8033", 0x8033}, // SP 0x1402AE6E0 MP 0x000000000 - {"_meth_8034", 0x8034}, // SP 0x1402CBC10 MP 0x000000000 + {"getattachtagname", 0x802E}, // SP 0x1402A0A90 MP 0x14036D040 + {"setturretcanaidetach", 0x802F}, // SP 0x1402AE150 MP 0x000000000 + {"setturretfov", 0x8030}, // SP 0x1402AE270 MP 0x000000000 + {"setplayerturretfov", 0x8031}, // SP 0x1402AE410 MP 0x000000000 + {"lerpfov", 0x8032}, // SP 0x1402AE620 MP 0x000000000 + {"lerpfovscale", 0x8033}, // SP 0x1402AE6E0 MP 0x000000000 + {"getvalidcoverpeekouts", 0x8034}, // SP 0x1402CBC10 MP 0x000000000 {"gethighestnodestance", 0x8035}, // SP 0x1402CBBA0 MP 0x14031F650 {"doesnodeallowstance", 0x8036}, // SP 0x1402CBA70 MP 0x14031F520 - {"setforcespectatorclient", 0x8037}, // SP 0x1402CBB20 MP 0x14031F5D0 - {"_meth_8038", 0x8038}, // SP 0x1402AB240 MP 0x000000000 - {"_meth_8039", 0x8039}, // SP 0x1402AB320 MP 0x000000000 - {"_meth_803a", 0x803A}, // SP 0x1402AB6D0 MP 0x000000000 - {"_meth_803b", 0x803B}, // SP 0x1402ACA20 MP 0x000000000 - {"_meth_803c", 0x803C}, // SP 0x1402ACA40 MP 0x000000000 - {"_meth_803d", 0x803D}, // SP 0x1402ACBA0 MP 0x000000000 - {"_meth_803e", 0x803E}, // SP 0x1402AFA80 MP 0x000000000 - {"_meth_803f", 0x803F}, // SP 0x1402AFAC0 MP 0x000000000 - {"_meth_8040", 0x8040}, // SP 0x1402AFB90 MP 0x000000000 - {"_meth_8041", 0x8041}, // SP 0x1402AFC50 MP 0x000000000 - {"_meth_8042", 0x8042}, // SP 0x1402AFCA0 MP 0x000000000 - {"_meth_8043", 0x8043}, // SP 0x1402A8990 MP 0x000000000 - {"_meth_8044", 0x8044}, // SP 0x1402A89F0 MP 0x000000000 - {"_meth_8045", 0x8045}, // SP 0x14028F020 MP 0x14036EDF0 - {"_meth_8046", 0x8046}, // SP 0x14028F1F0 MP 0x14036EEE0 - {"_meth_8047", 0x8047}, // SP 0x1402ACE10 MP 0x000000000 - {"_meth_8048", 0x8048}, // SP 0x1402ACE50 MP 0x000000000 + {"doesnodeforcecombat", 0x8037}, // SP 0x1402CBB20 MP 0x14031F5D0 + {"getgunangles", 0x8038}, // SP 0x1402AB240 MP 0x000000000 + {"magicgrenade", 0x8039}, // SP 0x1402AB320 MP 0x000000000 + {"magicgrenademanual", 0x803A}, // SP 0x1402AB6D0 MP 0x000000000 + {"getentnum", 0x803B}, // SP 0x1402ACA20 MP 0x000000000 + {"launch", 0x803C}, // SP 0x1402ACA40 MP 0x000000000 + {"setsoundblend", 0x803D}, // SP 0x1402ACBA0 MP 0x000000000 + {"makefakeai", 0x803E}, // SP 0x1402AFA80 MP 0x000000000 + {"spawndrone", 0x803F}, // SP 0x1402AFAC0 MP 0x000000000 + {"setcorpseremovetimer", 0x8040}, // SP 0x1402AFB90 MP 0x000000000 + {"setlookattext", 0x8041}, // SP 0x1402AFC50 MP 0x000000000 + {"setspawnerteam", 0x8042}, // SP 0x1402AFCA0 MP 0x000000000 + {"addaieventlistener", 0x8043}, // SP 0x1402A8990 MP 0x000000000 + {"removeaieventlistener", 0x8044}, // SP 0x1402A89F0 MP 0x000000000 + {"getlightcolor", 0x8045}, // SP 0x14028F020 MP 0x14036EDF0 + {"setlightcolor", 0x8046}, // SP 0x14028F1F0 MP 0x14036EEE0 + {"getlightradius", 0x8047}, // SP 0x1402ACE10 MP 0x000000000 + {"setlightradius", 0x8048}, // SP 0x1402ACE50 MP 0x000000000 {"getattachignorecollision", 0x8049}, // SP 0x1402A1060 MP 0x14036D280 {"hidepart", 0x804A}, // SP 0x1402A1500 MP 0x14036D940 - {"hidepartallinstances", 0x804B}, // SP 0x1402A1930 MP 0x14036DC50 - {"_meth_804c", 0x804C}, // SP 0x1402A1C90 MP 0x14036E320 + {"hidepart_allinstances", 0x804B}, // SP 0x1402A1930 MP 0x14036DC50 + {"hideallparts", 0x804C}, // SP 0x1402A1C90 MP 0x14036E320 {"showpart", 0x804D}, // SP 0x1402A2000 MP 0x14036E480 - {"_meth_804e", 0x804E}, // SP 0x1402A2370 MP 0x14036ECC0 - {"_meth_804f", 0x804F}, // SP 0x1402A3670 MP 0x140358AF0 - {"_meth_8050", 0x8050}, // SP 0x1402A3AB0 MP 0x140359830 - {"_meth_8051", 0x8051}, // SP 0x1402A3AD0 MP 0x140359850 - {"_meth_8052", 0x8052}, // SP 0x1402AD0F0 MP 0x140379AD0 - {"_meth_8053", 0x8053}, // SP 0x1402A2B80 MP 0x14036B270 - {"_meth_8054", 0x8054}, // SP 0x1402AD260 MP 0x000000000 + {"showallparts", 0x804E}, // SP 0x1402A2370 MP 0x14036ECC0 + {"linkto", 0x804F}, // SP 0x1402A3670 MP 0x140358AF0 + {"linktoblendtotag", 0x8050}, // SP 0x1402A3AB0 MP 0x140359830 + {"unlink", 0x8051}, // SP 0x1402A3AD0 MP 0x140359850 + {"setnormalhealth", 0x8052}, // SP 0x1402AD0F0 MP 0x140379AD0 + {"dodamage", 0x8053}, // SP 0x1402A2B80 MP 0x14036B270 + {"kill", 0x8054}, // SP 0x1402AD260 MP 0x000000000 {"show", 0x8055}, // SP 0x1402AD6A0 MP 0x14037A9E0 {"hide", 0x8056}, // SP 0x1402AD6C0 MP 0x14037AAA0 - {"_meth_8057", 0x8057}, // SP 0x1402AD7A0 MP 0x000000000 - {"_meth_8058", 0x8058}, // SP 0x1402AD7D0 MP 0x000000000 + {"showonclient", 0x8057}, // SP 0x1402AD7A0 MP 0x000000000 + {"hideonclient", 0x8058}, // SP 0x1402AD7D0 MP 0x000000000 {"disconnectpaths", 0x8059}, // SP 0x14028E1E0 MP 0x14036F090 {"connectpaths", 0x805A}, // SP 0x14028E390 MP 0x14036F4C0 - {"_meth_805b", 0x805B}, // SP 0x14028E490 MP 0x14036F5F0 - {"_meth_805c", 0x805C}, // SP 0x14028E750 MP 0x14036F770 - {"_meth_805d", 0x805D}, // SP 0x1402A8420 MP 0x000000000 - {"_meth_805e", 0x805E}, // SP 0x1402A8440 MP 0x000000000 - {"_meth_805f", 0x805F}, // SP 0x1402A8460 MP 0x000000000 - {"_meth_8060", 0x8060}, // SP 0x1402A8480 MP 0x000000000 - {"_meth_8061", 0x8061}, // SP 0x1402A9250 MP 0x000000000 - {"_meth_8062", 0x8062}, // SP 0x1402A92D0 MP 0x000000000 - {"_meth_8063", 0x8063}, // SP 0x1402A9BC0 MP 0x000000000 - {"_meth_8064", 0x8064}, // SP 0x1402AABA0 MP 0x000000000 - {"_meth_8065", 0x8065}, // SP 0x1402AAC10 MP 0x000000000 - {"_meth_8066", 0x8066}, + {"disconnectnode", 0x805B}, // SP 0x14028E490 MP 0x14036F5F0 + {"connectnode", 0x805C}, // SP 0x14028E750 MP 0x14036F770 + {"startusingheroonlylighting", 0x805D}, // SP 0x1402A8420 MP 0x000000000 + {"stopusingheroonlylighting", 0x805E}, // SP 0x1402A8440 MP 0x000000000 + {"startusinglessfrequentlighting", 0x805F}, // SP 0x1402A8460 MP 0x000000000 + {"stopusinglessfrequentlighting", 0x8060}, // SP 0x1402A8480 MP 0x000000000 + {"setmovingplatformplayerturnrate", 0x8061}, // SP 0x1402A9250 MP 0x000000000 + {"setthermalfog", 0x8062}, // SP 0x1402A92D0 MP 0x000000000 + {"setnightvisionfog", 0x8063}, // SP 0x1402A9BC0 MP 0x000000000 + {"clearthermalfog", 0x8064}, // SP 0x1402AABA0 MP 0x000000000 + {"clearnightvisionfog", 0x8065}, // SP 0x1402AAC10 MP 0x000000000 + {"digitaldistortsetparams", 0x8066}, {"setmode", 0x8067}, // SP 0x1402AD9A0 MP 0x140375030 - {"_meth_8068", 0x8068}, // SP 0x1402ADCD0 MP 0x140375210 - {"_meth_8069", 0x8069}, // SP 0x1402ADF10 MP 0x000000000 + {"getmode", 0x8068}, // SP 0x1402ADCD0 MP 0x140375210 + {"setturretignoregoals", 0x8069}, // SP 0x1402ADF10 MP 0x000000000 {"islinked", 0x806A}, // SP 0x14028D6B0 MP 0x1403598E0 {"enablelinkto", 0x806B}, // SP 0x14028EA50 MP 0x14035A950 - {"_meth_806c", 0x806C}, // SP 0x1402ACB60 MP 0x000000000 - {"_meth_806d", 0x806D}, - {"_meth_806e", 0x806E}, // SP 0x1402A27D0 MP 0x14035AB10 - {"_meth_806f", 0x806F}, // SP 0x1402A23E0 MP 0x14035A9C0 - {"_meth_8070", 0x8070}, // SP 0x1402A2980 MP 0x14035B0D0 - {"_meth_8071", 0x8071}, // SP 0x1402A28C0 MP 0x14035AB50 - {"_meth_8072", 0x8072}, // SP 0x140291F10 MP 0x000000000 - {"_meth_8073", 0x8073}, // SP 0x1405D92F0 MP 0x000000000 - {"_meth_8074", 0x8074}, // SP 0x1405D92F0 MP 0x000000000 - {"_meth_8075", 0x8075}, // SP 0x1405D92F0 MP 0x000000000 - {"_meth_8076", 0x8076}, // SP 0x1402ACC40 MP 0x1403798B0 + {"playsoundatviewheight", 0x806C}, // SP 0x1402ACB60 MP 0x000000000 + {"prefetchsound", 0x806D}, + {"setpitch", 0x806E}, // SP 0x1402A27D0 MP 0x14035AB10 + {"scalepitch", 0x806F}, // SP 0x1402A23E0 MP 0x14035A9C0 + {"setvolume", 0x8070}, // SP 0x1402A2980 MP 0x14035B0D0 + {"scalevolume", 0x8071}, // SP 0x1402A28C0 MP 0x14035AB50 + {"enableportalgroup", 0x8072}, // SP 0x140291F10 MP 0x000000000 + {"setspeakermapmonotostereo", 0x8073}, // SP 0x1405D92F0 MP 0x000000000 + {"setspeakermapmonoto51", 0x8074}, // SP 0x1405D92F0 MP 0x000000000 + {"setdistributed2dsound", 0x8075}, // SP 0x1405D92F0 MP 0x000000000 + {"playsoundasmaster", 0x8076}, // SP 0x1402ACC40 MP 0x1403798B0 {"playloopsound", 0x8077}, // SP 0x1402ACC60 MP 0x1403798F0 - {"_meth_8078", 0x8078}, // SP 0x1402ACCD0 MP 0x000000000 - {"_meth_8079", 0x8079}, // SP 0x1402ACD40 MP 0x000000000 - {"_meth_807a", 0x807A}, // SP 0x1402ACDD0 MP 0x000000000 - {"_meth_807b", 0x807B}, // SP 0x1402ACE30 MP 0x000000000 - {"_meth_807c", 0x807C}, // SP 0x1402ACEE0 MP 0x000000000 + {"eqon", 0x8078}, // SP 0x1402ACCD0 MP 0x000000000 + {"eqoff", 0x8079}, // SP 0x1402ACD40 MP 0x000000000 + {"haseq", 0x807A}, // SP 0x1402ACDD0 MP 0x000000000 + {"iswaitingonsound", 0x807B}, // SP 0x1402ACE30 MP 0x000000000 + {"playfoley", 0x807C}, // SP 0x1402ACEE0 MP 0x000000000 {"getnormalhealth", 0x807D}, // SP 0x1402ACFF0 MP 0x1403799E0 - {"_meth_807e", 0x807E}, // SP 0x14028FA50 MP 0x14035B880 - {"_meth_807f", 0x807F}, // SP 0x14028FB40 MP 0x14035B8D0 - {"_meth_8080", 0x8080}, // SP 0x14028FB60 MP 0x14035BD70 + {"playerlinkto", 0x807E}, // SP 0x14028FA50 MP 0x14035B880 + {"playerlinktodelta", 0x807F}, // SP 0x14028FB40 MP 0x14035B8D0 + {"playerlinkweaponviewtodelta", 0x8080}, // SP 0x14028FB60 MP 0x14035BD70 {"playerlinktoabsolute", 0x8081}, // SP 0x14028FBE0 MP 0x14035C100 {"playerlinktoblend", 0x8082}, // SP 0x140292720 MP 0x14035DCB0 {"playerlinkedoffsetenable", 0x8083}, // SP 0x140290050 MP 0x14035C5A0 - {"_meth_8084", 0x8084}, // SP 0x14026DC10 MP 0x14033BBF0 - {"_meth_8085", 0x8085}, // SP 0x14026DC60 MP 0x14033BC00 - {"changefontscaleovertime", 0x8086}, // SP 0x14026E020 MP 0x14033BF50 + {"setwaypointedgestyle_secondaryarrow", 0x8084}, // SP 0x14026DC10 MP 0x14033BBF0 + {"setwaypointiconoffscreenonly", 0x8085}, // SP 0x14026DC60 MP 0x14033BC00 + {"fadeovertime", 0x8086}, // SP 0x14026E020 MP 0x14033BF50 {"scaleovertime", 0x8087}, // SP 0x14026E160 MP 0x14033C090 - {"_meth_8088", 0x8088}, // SP 0x14026E240 MP 0x14033C170 - {"_meth_8089", 0x8089}, // SP 0x14026E380 MP 0x14033C230 + {"moveovertime", 0x8088}, // SP 0x14026E240 MP 0x14033C170 + {"reset", 0x8089}, // SP 0x14026E380 MP 0x14033C230 {"destroy", 0x808A}, // SP 0x14026E3C0 MP 0x14033C310 - {"_meth_808b", 0x808B}, // SP 0x14026E500 MP 0x14033C3F0 - {"_meth_808c", 0x808C}, // SP 0x14026E440 MP 0x14033C360 - {"fadeovertime", 0x808D}, // SP 0x14026E0C0 MP 0x14033BFF0 - {"_meth_808e", 0x808E}, // SP 0x1402A83E0 MP 0x000000000 - {"_meth_808f", 0x808F}, // SP 0x1402A8400 MP 0x000000000 - {"_meth_8090", 0x8090}, // SP 0x1402A8970 MP 0x000000000 - {"_meth_8091", 0x8091}, // SP 0x1402A89D0 MP 0x000000000 - {"_meth_8092", 0x8092}, // SP 0x1402AD800 MP 0x000000000 + {"setpulsefx", 0x808B}, // SP 0x14026E500 MP 0x14033C3F0 + {"setplayernamestring", 0x808C}, // SP 0x14026E440 MP 0x14033C360 + {"changefontscaleovertime", 0x808D}, // SP 0x14026E0C0 MP 0x14033BFF0 + {"startignoringspotlight", 0x808E}, // SP 0x1402A83E0 MP 0x000000000 + {"stopignoringspotlight", 0x808F}, // SP 0x1402A8400 MP 0x000000000 + {"dontcastshadows", 0x8090}, // SP 0x1402A8970 MP 0x000000000 + {"castshadows", 0x8091}, // SP 0x1402A89D0 MP 0x000000000 + {"setstablemissile", 0x8092}, // SP 0x1402AD800 MP 0x000000000 {"playersetgroundreferenceent", 0x8093}, // SP 0x1402A9070 MP 0x1403752A0 {"dontinterpolate", 0x8094}, // SP 0x1402A0070 MP 0x140358360 {"_meth_8095", 0x8095}, // SP 0x1402AAC80 MP 0x000000000 From c112eafad03937511d0018e373018751b6ebebd8 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 11 Mar 2022 21:41:17 +0100 Subject: [PATCH 069/346] Fix client_t struct --- src/client/component/patches.cpp | 4 ++-- src/client/game/structs.hpp | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 4498e272..8cf81a71 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -259,10 +259,10 @@ namespace patches dvars::override::register_int("com_maxfps", 0, 0, 1000, game::DVAR_FLAG_SAVED); // Prevent clients from ending the game as non host by sending 'end_game' lui notification - // cmd_lui_notify_server_hook.create(0x140335A70, cmd_lui_notify_server_stub); + cmd_lui_notify_server_hook.create(0x140335A70, cmd_lui_notify_server_stub); // Prevent clients from sending invalid reliableAcknowledge - // utils::hook::call(0x1404899C6, sv_execute_client_message_stub); + utils::hook::call(0x1404899C6, sv_execute_client_message_stub); // "fix" for rare 'Out of memory error' error if (utils::flags::has_flag("memoryfix")) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index e57d54c7..a20c48d7 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1382,17 +1382,17 @@ namespace game struct clientHeader_t { int state; - char __pad0[36]; + char __pad0[44]; netadr_s remoteAddress; }; // size = ? struct client_t { clientHeader_t header; - char __pad0[3044]; + char __pad0[265164]; int reliableSequence; int reliableAcknowledge; - char __pad1[265864]; + char __pad1[265832]; gentity_s* gentity; // 268976 char name[32]; // 268984 char __pad2[8]; @@ -1401,8 +1401,10 @@ namespace game LiveClientDropType liveDropRequest; //269572 char __pad4[24]; TestClientType testClient; // 269600 - char __pad5[610012]; + char __pad5[129600]; }; // size = 661304 + + static_assert(sizeof(client_t) == 661304); } namespace sp From 8f82a74f4b1e59d5353461474ee56d48b5361fbc Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 11 Mar 2022 21:44:29 +0100 Subject: [PATCH 070/346] Small fix --- data/ui_scripts/stats/__init__.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua index 9ec572b7..f8a12274 100644 --- a/data/ui_scripts/stats/__init__.lua +++ b/data/ui_scripts/stats/__init__.lua @@ -1,4 +1,4 @@ -if (game:issingleplayer()) then +if (game:issingleplayer() or not Engine.InFrontend()) then return end From 1c1b0a8719c90a55ec97106b822aa4f0feb20e24 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 11 Mar 2022 22:07:16 +0100 Subject: [PATCH 071/346] Small change --- src/client/component/ui_scripting.cpp | 36 +++++++++++---------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index d58079cc..c4f6d06f 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -48,10 +48,8 @@ namespace ui_scripting { return hksi_lual_error_hook.invoke(s, formatted.data()); } - else - { - throw std::runtime_error(formatted); - } + + throw std::runtime_error(formatted); } int hksi_hks_error_stub(game::hks::lua_State* s, int a2) @@ -60,31 +58,27 @@ namespace ui_scripting { return hksi_hks_error_hook.invoke(s, a2); } - else - { - throw std::runtime_error("unknown error"); - } + + throw std::runtime_error("unknown error"); } - int lui_error_stub(game::hks::lua_State* s) + void lui_error_stub(game::hks::lua_State* s) { if (!error_hook_enabled) { - return lui_error_hook.invoke(s); + lui_error_hook.invoke(s); } - else + + const auto count = static_cast(s->m_apistack.top - s->m_apistack.base); + const auto arguments = get_return_values(count); + + std::string error_str = "LUI Error"; + if (count && arguments[0].is()) { - const auto count = static_cast(s->m_apistack.top - s->m_apistack.base); - const auto arguments = get_return_values(count); - - std::string error_str = "LUI Error"; - if (count && arguments[0].is()) - { - error_str = arguments[0].as(); - } - - throw std::runtime_error(error_str); + error_str = arguments[0].as(); } + + throw std::runtime_error(error_str); } void* hks_start_stub(char a1) From b4326f717784d483688acb5b7e572c91e7d3c776 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 11 Mar 2022 22:28:08 +0100 Subject: [PATCH 072/346] Add logger component --- src/client/component/logger.cpp | 180 ++++++++++++++++++++++++++++++++ src/client/component/party.cpp | 7 +- src/client/component/party.hpp | 1 + 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 src/client/component/logger.cpp diff --git a/src/client/component/logger.cpp b/src/client/component/logger.cpp new file mode 100644 index 00000000..361ac339 --- /dev/null +++ b/src/client/component/logger.cpp @@ -0,0 +1,180 @@ +#include +#include "loader/component_loader.hpp" + +#include "party.hpp" +#include "console.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include + +namespace logger +{ + namespace + { + utils::hook::detour com_error_hook; + + void print_error(const char* msg, ...) + { + char buffer[2048]; + + va_list ap; + va_start(ap, msg); + + vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap); + + va_end(ap); + + console::error(buffer); + } + + void print_com_error(int, const char* msg, ...) + { + char buffer[2048]; + + va_list ap; + va_start(ap, msg); + + vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap); + + va_end(ap); + + console::error(buffer); + } + + void com_error_stub(const int error, const char* msg, ...) + { + char buffer[2048]; + + { + va_list ap; + va_start(ap, msg); + + vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap); + + va_end(ap); + + console::error("Error: %s\n", buffer); + } + + party::clear_sv_motd(); // clear sv_motd on error if it exists + + com_error_hook.invoke(error, "%s", buffer); + } + + void print_warning(const char* msg, ...) + { + char buffer[2048]; + + va_list ap; + va_start(ap, msg); + + vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap); + + va_end(ap); + + console::warn(buffer); + } + + void print(const char* msg, ...) + { + char buffer[2048]; + + va_list ap; + va_start(ap, msg); + + vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap); + + va_end(ap); + + console::info(buffer); + } + + void print_dev(const char* msg, ...) + { + static auto* enabled = dvars::register_bool("logger_dev", false, game::DVAR_FLAG_SAVED, true); + if (!enabled->current.enabled) + { + return; + } + + char buffer[2048]; + + va_list ap; + va_start(ap, msg); + + vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap); + + va_end(ap); + + console::info(buffer); + } + + void lui_error() + { + utils::hook::call(0x140162809, print_warning); + utils::hook::call(0x140162815, print_warning); + utils::hook::call(0x14016281D, print_warning); + utils::hook::call(0x140162829, print_warning); + + utils::hook::call(0x140162E32, print_warning); + utils::hook::call(0x140162E3E, print_warning); + utils::hook::call(0x140162E46, print_warning); + utils::hook::call(0x140162E52, print_warning); + + utils::hook::call(0x140168435, print_warning); + utils::hook::call(0x140168441, print_warning); + utils::hook::call(0x140168449, print_warning); + utils::hook::call(0x140168455, print_warning); + + utils::hook::call(0x14016914D, print_warning); + utils::hook::call(0x140169161, print_warning); + + utils::hook::call(0x140169C04, print_warning); + utils::hook::call(0x140169C0C, print_warning); + utils::hook::call(0x140169C18, print_warning); + + utils::hook::call(0x140169CB7, print_warning); + utils::hook::call(0x140169CDE, print_warning); + utils::hook::call(0x140169CEA, print_warning); + utils::hook::call(0x140169D03, print_warning); + + utils::hook::call(0x14016BE72, print_warning); + utils::hook::call(0x14016C020, print_warning); + } + + void lui_interface_debug_print() + { + utils::hook::call(0x14015C0B2, print_warning); + utils::hook::call(0x140162453, print_warning); + utils::hook::call(0x1401625DF, print_warning); + utils::hook::call(0x14016713C, print_dev); + utils::hook::call(0x1401687CD, print_dev); + utils::hook::call(0x14016BB8A, print_dev); + utils::hook::call(0x14016CA9C, print_dev); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_mp()) + { + lui_error(); + lui_interface_debug_print(); + } + + if (!game::environment::is_sp()) + { + utils::hook::call(0x14051347F, print_com_error); + } + + com_error_hook.create(game::Com_Error, com_error_stub); + } + }; +} + +REGISTER_COMPONENT(logger::component) diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 0605afad..38dd7277 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -142,7 +142,7 @@ namespace party void cl_disconnect_stub(int a1) { - party::sv_motd.clear(); + party::clear_sv_motd(); cldisconnect_hook.invoke(a1); } @@ -160,6 +160,11 @@ namespace party } } + void clear_sv_motd() + { + party::sv_motd.clear(); + } + int get_client_num_by_name(const std::string& name) { for (auto i = 0; !name.empty() && i < *game::mp::svs_numclients; ++i) diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index cd90ae9f..0feb2e98 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -8,6 +8,7 @@ namespace party void connect(const game::netadr_s& target); void start_map(const std::string& mapname); + void clear_sv_motd(); int server_client_count(); int get_client_num_by_name(const std::string& name); From 2d8a3bbe5ca2070a82b3840f569be37f08d72aa3 Mon Sep 17 00:00:00 2001 From: m Date: Fri, 11 Mar 2022 16:35:50 -0600 Subject: [PATCH 073/346] nicely format LUA files --- data/ui_scripts/hud_info/__init__.lua | 4 +- data/ui_scripts/hud_info/hud.lua | 244 +++++++++--------- data/ui_scripts/hud_info/settings.lua | 242 +++++++----------- data/ui_scripts/server_list/lobby.lua | 95 +++---- data/ui_scripts/server_list/serverlist.lua | 216 ++++++++-------- data/ui_scripts/stats/__init__.lua | 278 +++++++++------------ 6 files changed, 483 insertions(+), 596 deletions(-) diff --git a/data/ui_scripts/hud_info/__init__.lua b/data/ui_scripts/hud_info/__init__.lua index 07dfbdd4..1194a4f6 100644 --- a/data/ui_scripts/hud_info/__init__.lua +++ b/data/ui_scripts/hud_info/__init__.lua @@ -1,6 +1,6 @@ if (game:issingleplayer()) then - return + return end require("settings") -require("hud") \ No newline at end of file +require("hud") diff --git a/data/ui_scripts/hud_info/hud.lua b/data/ui_scripts/hud_info/hud.lua index 94acfc63..ffc8dc07 100644 --- a/data/ui_scripts/hud_info/hud.lua +++ b/data/ui_scripts/hud_info/hud.lua @@ -4,155 +4,155 @@ local textheight = 13 local textoffsety = barheight / 2 - textheight / 2 function createinfobar() - local infobar = LUI.UIElement.new({ - left = luiglobals.GameX.IsHardcoreMode() and 160 or 228, - top = luiglobals.GameX.IsHardcoreMode() and 5 or 9, - height = barheight, - width = 70, - leftAnchor = true, - topAnchor = true - }) + local infobar = LUI.UIElement.new({ + left = luiglobals.GameX.IsHardcoreMode() and 160 or 228, + top = luiglobals.GameX.IsHardcoreMode() and 5 or 9, + height = barheight, + width = 70, + leftAnchor = true, + topAnchor = true + }) - infobar:registerAnimationState("hud_on", { - alpha = 1 - }) + infobar:registerAnimationState("hud_on", { + alpha = 1 + }) - infobar:registerAnimationState("hud_off", { - alpha = 0 - }) + infobar:registerAnimationState("hud_off", { + alpha = 0 + }) - return infobar + return infobar end function populateinfobar(infobar) - elementoffset = 0 + elementoffset = 0 - if (Engine.GetDvarBool("cg_infobar_fps")) then - infobar:addElement(infoelement({ - label = "FPS: ", - getvalue = function() - return game:getfps() - end, - width = 70, - interval = 100 - })) - end + if (Engine.GetDvarBool("cg_infobar_fps")) then + infobar:addElement(infoelement({ + label = "FPS: ", + getvalue = function() + return game:getfps() + end, + width = 70, + interval = 100 + })) + end - if (Engine.GetDvarBool("cg_infobar_ping")) then - infobar:addElement(infoelement({ - label = "Latency: ", - getvalue = function() - return game:getping() .. " ms" - end, - width = 115, - interval = 100 - })) - end + if (Engine.GetDvarBool("cg_infobar_ping")) then + infobar:addElement(infoelement({ + label = "Latency: ", + getvalue = function() + return game:getping() .. " ms" + end, + width = 115, + interval = 100 + })) + end end function infoelement(data) - local container = LUI.UIElement.new({ - bottomAnchor = true, - leftAnchor = true, - topAnchor = true, - width = data.width, - left = elementoffset - }) + local container = LUI.UIElement.new({ + bottomAnchor = true, + leftAnchor = true, + topAnchor = true, + width = data.width, + left = elementoffset + }) - elementoffset = elementoffset + data.width + 10 + elementoffset = elementoffset + data.width + 10 - local background = LUI.UIImage.new({ - bottomAnchor = true, - leftAnchor = true, - topAnchor = true, - rightAnchor = true, - material = luiglobals.RegisterMaterial("white"), - color = luiglobals.Colors.black, - alpha = 0.5 - }) + local background = LUI.UIImage.new({ + bottomAnchor = true, + leftAnchor = true, + topAnchor = true, + rightAnchor = true, + material = luiglobals.RegisterMaterial("white"), + color = luiglobals.Colors.black, + alpha = 0.5 + }) - local labelfont = CoD.TextSettings.FontBold110 + local labelfont = CoD.TextSettings.FontBold110 - local label = LUI.UIText.new({ - left = 5, - top = textoffsety, - font = labelfont.Font, - height = textheight, - leftAnchor = true, - topAnchor = true, - color = { - r = 0.8, - g = 0.8, - b = 0.8, - } - }) + local label = LUI.UIText.new({ + left = 5, + top = textoffsety, + font = labelfont.Font, + height = textheight, + leftAnchor = true, + topAnchor = true, + color = { + r = 0.8, + g = 0.8, + b = 0.8 + } + }) - label:setText(data.label) + label:setText(data.label) - local _, _, left = luiglobals.GetTextDimensions(data.label, labelfont.Font, textheight) - local value = LUI.UIText.new({ - left = left + 5, - top = textoffsety, - height = textheight, - leftAnchor = true, - topAnchor = true, - color = { - r = 0.6, - g = 0.6, - b = 0.6, - } - }) - - value:addElement(LUI.UITimer.new(data.interval, "update")) - value:setText(data.getvalue()) - value:addEventHandler("update", function() - value:setText(data.getvalue()) - end) - - container:addElement(background) - container:addElement(label) - container:addElement(value) - - return container + local _, _, left = luiglobals.GetTextDimensions(data.label, labelfont.Font, textheight) + local value = LUI.UIText.new({ + left = left + 5, + top = textoffsety, + height = textheight, + leftAnchor = true, + topAnchor = true, + color = { + r = 0.6, + g = 0.6, + b = 0.6 + } + }) + + value:addElement(LUI.UITimer.new(data.interval, "update")) + value:setText(data.getvalue()) + value:addEventHandler("update", function() + value:setText(data.getvalue()) + end) + + container:addElement(background) + container:addElement(label) + container:addElement(value) + + return container end local updatehudvisibility = mphud.updateHudVisibility mphud.updateHudVisibility = function(a1, a2) - updatehudvisibility(a1, a2) + updatehudvisibility(a1, a2) - local root = Engine.GetLuiRoot() - local menus = root:AnyActiveMenusInStack() - local infobar = root.infobar + local root = Engine.GetLuiRoot() + local menus = root:AnyActiveMenusInStack() + local infobar = root.infobar - if (not infobar) then - return - end + if (not infobar) then + return + end - if (menus) then - infobar:animateToState("hud_off") - else - infobar:animateToState("hud_on") - end + if (menus) then + infobar:animateToState("hud_off") + else + infobar:animateToState("hud_on") + end end LUI.onmenuopen("mp_hud", function(hud) - if (Engine.InFrontend()) then - return - end + if (Engine.InFrontend()) then + return + end - local infobar = createinfobar() - local root = Engine.GetLuiRoot() - root.infobar = infobar - populateinfobar(infobar) + local infobar = createinfobar() + local root = Engine.GetLuiRoot() + root.infobar = infobar + populateinfobar(infobar) - root:registerEventHandler("update_hud_infobar_settings", function() - infobar:removeAllChildren() - populateinfobar(infobar) - end) + root:registerEventHandler("update_hud_infobar_settings", function() + infobar:removeAllChildren() + populateinfobar(infobar) + end) - root:processEvent({ - name = "update_hud_infobar_settings" - }) - - hud.static:addElement(infobar) -end) \ No newline at end of file + root:processEvent({ + name = "update_hud_infobar_settings" + }) + + hud.static:addElement(infobar) +end) diff --git a/data/ui_scripts/hud_info/settings.lua b/data/ui_scripts/hud_info/settings.lua index 18014d33..bee3ca9b 100644 --- a/data/ui_scripts/hud_info/settings.lua +++ b/data/ui_scripts/hud_info/settings.lua @@ -7,173 +7,103 @@ game:addlocalizedstring("LUA_MENU_LATENCY", "Server Latency") game:addlocalizedstring("LUA_MENU_LATENCY_DESC", "Show server latency") function createdivider(menu, text) - local element = LUI.UIElement.new( { - leftAnchor = true, - rightAnchor = true, - left = 0, - right = 0, - topAnchor = true, - bottomAnchor = false, - top = 0, - bottom = 33.33 - }) + local element = LUI.UIElement.new({ + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + topAnchor = true, + bottomAnchor = false, + top = 0, + bottom = 33.33 + }) - element.scrollingToNext = true - element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { - title_bar_text = text - })) + element.scrollingToNext = true + element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { + title_bar_text = text + })) - menu.list:addElement(element) + menu.list:addElement(element) end -pcdisplay.CreateOptions = function( menu ) - LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@LUA_MENU_COLORBLIND_FILTER", - "@LUA_MENU_COLOR_BLIND_DESC", - LUI.Options.GetRenderColorBlindText, - LUI.Options.RenderColorBlindToggle, - LUI.Options.RenderColorBlindToggle - ) - - if Engine.IsMultiplayer() and Engine.GetDvarType( "cg_paintballFx" ) == luiglobals.DvarTypeTable.DvarBool then - LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@LUA_MENU_PAINTBALL", "@LUA_MENU_PAINTBALL_DESC", - LUI.Options.GetDvarEnableTextFunc("cg_paintballFx", false), - LUI.Options.ToggleDvarFunc("cg_paintballFx"), - LUI.Options.ToggleDvarFunc("cg_paintballFx") - ) - end +pcdisplay.CreateOptions = function(menu) + LUI.Options.AddButtonOptionVariant(menu, luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_COLORBLIND_FILTER", "@LUA_MENU_COLOR_BLIND_DESC", LUI.Options.GetRenderColorBlindText, + LUI.Options.RenderColorBlindToggle, LUI.Options.RenderColorBlindToggle) - LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@LUA_MENU_BLOOD", - "@LUA_MENU_BLOOD_DESC", - LUI.Options.GetDvarEnableTextFunc("cg_blood", false), - LUI.Options.ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0)), - LUI.Options.ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0)) - ) - - if not Engine.IsMultiplayer() then - LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@LUA_MENU_CROSSHAIR", - "@LUA_MENU_CROSSHAIR_DESC", - LUI.Options.GetDvarEnableTextFunc("cg_drawCrosshairOption", false), - LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption"), - LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption") - ) - - LUI.Options.CreateOptionButton( - menu, - "cg_drawDamageFeedbackOption", - "@LUA_MENU_HIT_MARKER", - "@LUA_MENU_HIT_MARKER_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - } - ) - end + if Engine.IsMultiplayer() and Engine.GetDvarType("cg_paintballFx") == luiglobals.DvarTypeTable.DvarBool then + LUI.Options.AddButtonOptionVariant(menu, luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_PAINTBALL", "@LUA_MENU_PAINTBALL_DESC", + LUI.Options.GetDvarEnableTextFunc("cg_paintballFx", false), LUI.Options.ToggleDvarFunc("cg_paintballFx"), + LUI.Options.ToggleDvarFunc("cg_paintballFx")) + end - if Engine.IsMultiplayer() then - LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@MENU_DISPLAY_KILLSTREAK_COUNTER", - "@MENU_DISPLAY_KILLSTREAK_COUNTER_DESC", - pcdisplay.GetDisplayKillstreakCounterText, - pcdisplay.DisplayKillstreakCounterToggle, - pcdisplay.DisplayKillstreakCounterToggle - ) + LUI.Options.AddButtonOptionVariant(menu, luiglobals.GenericButtonSettings.Variants.Select, "@LUA_MENU_BLOOD", + "@LUA_MENU_BLOOD_DESC", LUI.Options.GetDvarEnableTextFunc("cg_blood", false), LUI.Options + .ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0)), LUI.Options + .ToggleProfiledataFunc("showblood", Engine.GetControllerForLocalClient(0))) - LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@MENU_DISPLAY_MEDAL_SPLASHES", - "@MENU_DISPLAY_MEDAL_SPLASHES_DESC", - pcdisplay.GetDisplayMedalSplashesText, - pcdisplay.DisplayMedalSplashesToggle, - pcdisplay.DisplayMedalSplashesToggle - ) + if not Engine.IsMultiplayer() then + LUI.Options.AddButtonOptionVariant(menu, luiglobals.GenericButtonSettings.Variants.Select, + "@LUA_MENU_CROSSHAIR", "@LUA_MENU_CROSSHAIR_DESC", + LUI.Options.GetDvarEnableTextFunc("cg_drawCrosshairOption", false), + LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption"), LUI.Options.ToggleDvarFunc("cg_drawCrosshairOption")) - LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Select, - "@MENU_DISPLAY_WEAPON_EMBLEMS", - "@MENU_DISPLAY_WEAPON_EMBLEMS_DESC", - pcdisplay.GetDisplayWeaponEmblemsText, - pcdisplay.DisplayWeaponEmblemsToggle, - pcdisplay.DisplayWeaponEmblemsToggle - ) - end + LUI.Options.CreateOptionButton(menu, "cg_drawDamageFeedbackOption", "@LUA_MENU_HIT_MARKER", + "@LUA_MENU_HIT_MARKER_DESC", {{ + text = "@LUA_MENU_ENABLED", + value = true + }, { + text = "@LUA_MENU_DISABLED", + value = false + }}) + end - LUI.Options.AddButtonOptionVariant( - menu, - luiglobals.GenericButtonSettings.Variants.Common, - "@MENU_BRIGHTNESS", - "@MENU_BRIGHTNESS_DESC1", - nil, nil, nil, - pcdisplay.OpenBrightnessMenu, - nil, nil, nil - ) + if Engine.IsMultiplayer() then + LUI.Options.AddButtonOptionVariant(menu, luiglobals.GenericButtonSettings.Variants.Select, + "@MENU_DISPLAY_KILLSTREAK_COUNTER", "@MENU_DISPLAY_KILLSTREAK_COUNTER_DESC", + pcdisplay.GetDisplayKillstreakCounterText, pcdisplay.DisplayKillstreakCounterToggle, + pcdisplay.DisplayKillstreakCounterToggle) - createdivider(menu, "TELEMETRY") + LUI.Options.AddButtonOptionVariant(menu, luiglobals.GenericButtonSettings.Variants.Select, + "@MENU_DISPLAY_MEDAL_SPLASHES", "@MENU_DISPLAY_MEDAL_SPLASHES_DESC", pcdisplay.GetDisplayMedalSplashesText, + pcdisplay.DisplayMedalSplashesToggle, pcdisplay.DisplayMedalSplashesToggle) - LUI.Options.CreateOptionButton( - menu, - "cg_infobar_ping", - "@LUA_MENU_LATENCY", - "@LUA_MENU_LATENCY_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - }, nil, nil, function(value) - Engine.SetDvarBool("cg_infobar_ping", value) - Engine.GetLuiRoot():processEvent({ - name = "update_hud_infobar_settings" - }) - end - ) + LUI.Options.AddButtonOptionVariant(menu, luiglobals.GenericButtonSettings.Variants.Select, + "@MENU_DISPLAY_WEAPON_EMBLEMS", "@MENU_DISPLAY_WEAPON_EMBLEMS_DESC", pcdisplay.GetDisplayWeaponEmblemsText, + pcdisplay.DisplayWeaponEmblemsToggle, pcdisplay.DisplayWeaponEmblemsToggle) + end - LUI.Options.CreateOptionButton( - menu, - "cg_infobar_fps", - "@LUA_MENU_FPS", - "@LUA_MENU_FPS_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - }, nil, nil, function(value) - Engine.SetDvarBool("cg_infobar_fps", value) - Engine.GetLuiRoot():processEvent({ - name = "update_hud_infobar_settings" - }) - end - ) + LUI.Options.AddButtonOptionVariant(menu, luiglobals.GenericButtonSettings.Variants.Common, "@MENU_BRIGHTNESS", + "@MENU_BRIGHTNESS_DESC1", nil, nil, nil, pcdisplay.OpenBrightnessMenu, nil, nil, nil) - LUI.Options.InitScrollingList(menu.list, nil) + createdivider(menu, "TELEMETRY") + + LUI.Options.CreateOptionButton(menu, "cg_infobar_ping", "@LUA_MENU_LATENCY", "@LUA_MENU_LATENCY_DESC", {{ + text = "@LUA_MENU_ENABLED", + value = true + }, { + text = "@LUA_MENU_DISABLED", + value = false + }}, nil, nil, function(value) + Engine.SetDvarBool("cg_infobar_ping", value) + Engine.GetLuiRoot():processEvent({ + name = "update_hud_infobar_settings" + }) + end) + + LUI.Options.CreateOptionButton(menu, "cg_infobar_fps", "@LUA_MENU_FPS", "@LUA_MENU_FPS_DESC", {{ + text = "@LUA_MENU_ENABLED", + value = true + }, { + text = "@LUA_MENU_DISABLED", + value = false + }}, nil, nil, function(value) + Engine.SetDvarBool("cg_infobar_fps", value) + Engine.GetLuiRoot():processEvent({ + name = "update_hud_infobar_settings" + }) + end) + + LUI.Options.InitScrollingList(menu.list, nil) end diff --git a/data/ui_scripts/server_list/lobby.lua b/data/ui_scripts/server_list/lobby.lua index 5f7029df..9d31f6cf 100644 --- a/data/ui_scripts/server_list/lobby.lua +++ b/data/ui_scripts/server_list/lobby.lua @@ -4,65 +4,66 @@ local MPLobbyOnline = LUI.mp_menus.MPLobbyOnline game:addlocalizedstring("LUA_MENU_SERVERLIST", "SERVER LIST") function LeaveLobby(f5_arg0) - LeaveXboxLive() - if Lobby.IsInPrivateParty() == false or Lobby.IsPrivatePartyHost() then - LUI.FlowManager.RequestLeaveMenuByName("menu_xboxlive") - Engine.ExecNow("clearcontrollermap") - end + LeaveXboxLive() + if Lobby.IsInPrivateParty() == false or Lobby.IsPrivatePartyHost() then + LUI.FlowManager.RequestLeaveMenuByName("menu_xboxlive") + Engine.ExecNow("clearcontrollermap") + end end function menu_xboxlive(f16_arg0, f16_arg1) - local menu = LUI.MPLobbyBase.new(f16_arg0, { - menu_title = "@PLATFORM_UI_HEADER_PLAY_MP_CAPS", - memberListState = Lobby.MemberListStates.Prelobby - }) + local menu = LUI.MPLobbyBase.new(f16_arg0, { + menu_title = "@PLATFORM_UI_HEADER_PLAY_MP_CAPS", + memberListState = Lobby.MemberListStates.Prelobby + }) - menu:setClass(LUI.MPLobbyOnline) + menu:setClass(LUI.MPLobbyOnline) - local serverListButton = menu:AddButton("@LUA_MENU_SERVERLIST", function (a1, a2) + local serverListButton = menu:AddButton("@LUA_MENU_SERVERLIST", function(a1, a2) LUI.FlowManager.RequestAddMenu(a1, "menu_systemlink_join", true, nil) end) - serverListButton:setDisabledRefreshRate(500) - if Engine.IsCoreMode() then - menu:AddCACButton() - menu:AddBarracksButton() - menu:AddPersonalizationButton() - -- menu:AddDepotButton() - end + serverListButton:setDisabledRefreshRate(500) + if Engine.IsCoreMode() then + menu:AddCACButton() + menu:AddBarracksButton() + menu:AddPersonalizationButton() + -- menu:AddDepotButton() + end - serverListButton = menu:AddButton("@MENU_PRIVATE_MATCH", MPLobbyOnline.OnPrivateMatch, MPLobbyOnline.disablePrivateMatchButton) - serverListButton:rename("menu_xboxlive_private_match") - serverListButton:setDisabledRefreshRate(500) - if not Engine.IsCoreMode() then - local leaderboardButton = menu:AddButton("@LUA_MENU_LEADERBOARD", "OpLeaderboardMain") - leaderboardButton:rename("OperatorMenu_leaderboard") - end + serverListButton = menu:AddButton("@MENU_PRIVATE_MATCH", MPLobbyOnline.OnPrivateMatch, + MPLobbyOnline.disablePrivateMatchButton) + serverListButton:rename("menu_xboxlive_private_match") + serverListButton:setDisabledRefreshRate(500) + if not Engine.IsCoreMode() then + local leaderboardButton = menu:AddButton("@LUA_MENU_LEADERBOARD", "OpLeaderboardMain") + leaderboardButton:rename("OperatorMenu_leaderboard") + end - menu:AddOptionsButton() - local natType = Lobby.GetNATType() - if natType then - local natTypeText = Engine.Localize("NETWORK_YOURNATTYPE", natType) - local properties = CoD.CreateState(nil, nil, 2, -62, CoD.AnchorTypes.BottomRight) - properties.width = 250 - properties.height = CoD.TextSettings.BodyFontVeryTiny.Height - properties.font = CoD.TextSettings.BodyFontVeryTiny.Font - properties.color = luiglobals.Colors.white - properties.alpha = 0.25 - local self = LUI.UIText.new(properties) - self:setText(natTypeText) - menu:addElement(self) - end + menu:AddOptionsButton() + local natType = Lobby.GetNATType() + if natType then + local natTypeText = Engine.Localize("NETWORK_YOURNATTYPE", natType) + local properties = CoD.CreateState(nil, nil, 2, -62, CoD.AnchorTypes.BottomRight) + properties.width = 250 + properties.height = CoD.TextSettings.BodyFontVeryTiny.Height + properties.font = CoD.TextSettings.BodyFontVeryTiny.Font + properties.color = luiglobals.Colors.white + properties.alpha = 0.25 + local self = LUI.UIText.new(properties) + self:setText(natTypeText) + menu:addElement(self) + end - menu.isSignInMenu = true - menu:registerEventHandler("gain_focus", LUI.MPLobbyOnline.OnGainFocus) - menu:registerEventHandler("player_joined", luiglobals.Cac.PlayerJoinedEvent) - menu:registerEventHandler("exit_live_lobby", LeaveLobby) + menu.isSignInMenu = true + menu:registerEventHandler("gain_focus", LUI.MPLobbyOnline.OnGainFocus) + menu:registerEventHandler("player_joined", luiglobals.Cac.PlayerJoinedEvent) + menu:registerEventHandler("exit_live_lobby", LeaveLobby) - if Engine.IsCoreMode() then - Engine.ExecNow("eliteclan_refresh", Engine.GetFirstActiveController()) - end + if Engine.IsCoreMode() then + Engine.ExecNow("eliteclan_refresh", Engine.GetFirstActiveController()) + end - return menu + return menu end LUI.MenuBuilder.m_types_build["menu_xboxlive"] = menu_xboxlive diff --git a/data/ui_scripts/server_list/serverlist.lua b/data/ui_scripts/server_list/serverlist.lua index afc8137f..556e9cc5 100644 --- a/data/ui_scripts/server_list/serverlist.lua +++ b/data/ui_scripts/server_list/serverlist.lua @@ -2,161 +2,151 @@ local Lobby = luiglobals.Lobby local SystemLinkJoinMenu = LUI.mp_menus.SystemLinkJoinMenu if (not SystemLinkJoinMenu) then - return + return end game:addlocalizedstring("MENU_NUMPLAYERS", "Players") game:addlocalizedstring("MENU_PING", "Ping") -local offsets = { - 10, - 500, - 950, - 700, - 1100, -} +local offsets = {10, 500, 950, 700, 1100} -local columns = { - "@MENU_HOST_NAME", - "@MENU_MAP", - "@MENU_NUMPLAYERS", - "@MENU_TYPE1", - "@MENU_PING", -} +local columns = {"@MENU_HOST_NAME", "@MENU_MAP", "@MENU_NUMPLAYERS", "@MENU_TYPE1", "@MENU_PING"} function textlength(text, font, height) - local _, _, width = luiglobals.GetTextDimensions(text, font, height) - return width + local _, _, width = luiglobals.GetTextDimensions(text, font, height) + return width end function trimtext(text, font, height, maxwidth) - while (textlength(text, font, height) > maxwidth) do - text = text:sub(1, #text - 1) - end + while (textlength(text, font, height) > maxwidth) do + text = text:sub(1, #text - 1) + end - return text + return text end SystemLinkJoinMenu.AddHeaderButton = function(menu, f12_arg1, width) - local state = CoD.CreateState(0, f12_arg1, nil, nil, CoD.AnchorTypes.TopLeft) - state.width = width - local element = LUI.UIElement.new(state) - local button = SystemLinkJoinMenu.CreateButton("header", 24) + local state = CoD.CreateState(0, f12_arg1, nil, nil, CoD.AnchorTypes.TopLeft) + state.width = width + local element = LUI.UIElement.new(state) + local button = SystemLinkJoinMenu.CreateButton("header", 24) - button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.TopLeftRight), 40, LUI.Divider.Grey)) - button:makeNotFocusable() - button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.BottomLeftRight), 40, LUI.Divider.Grey)) - - local gettext = function(i) - return Engine.Localize(columns[i]) - end - - for i = 1, #offsets do - SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), nil) - end + button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.TopLeftRight), 40, + LUI.Divider.Grey)) + button:makeNotFocusable() + button:addElement(LUI.Divider.new(CoD.CreateState(nil, 0, nil, nil, CoD.AnchorTypes.BottomLeftRight), 40, + LUI.Divider.Grey)) - element:addElement(button) - menu:addElement(element) + local gettext = function(i) + return Engine.Localize(columns[i]) + end + + for i = 1, #offsets do + SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), nil) + end + + element:addElement(button) + menu:addElement(element) end SystemLinkJoinMenu.AddServerButton = function(menu, controller, index) - local button = SystemLinkJoinMenu.CreateButton(index or "header", 24) - button:makeFocusable() - button.index = index - button:addEventHandler("button_action", SystemLinkJoinMenu.OnJoinGame) + local button = SystemLinkJoinMenu.CreateButton(index or "header", 24) + button:makeFocusable() + button.index = index + button:addEventHandler("button_action", SystemLinkJoinMenu.OnJoinGame) - local gettext = function(i) - local text = Lobby.GetServerData(controller, index, i - 1) - return trimtext(text, CoD.TextSettings.TitleFontSmall.Font, 14, 400) - end - - for i = 1, #offsets do - SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), luiglobals.Colors.h1.medium_grey) - end + local gettext = function(i) + local text = Lobby.GetServerData(controller, index, i - 1) + return trimtext(text, CoD.TextSettings.TitleFontSmall.Font, 14, 400) + end - menu.list:addElement(button) - return button + for i = 1, #offsets do + SystemLinkJoinMenu.MakeText(button.textHolder, offsets[i], gettext(i), luiglobals.Colors.h1.medium_grey) + end + + menu.list:addElement(button) + return button end SystemLinkJoinMenu.MakeText = function(menu, f5_arg1, text, color) - local state = CoD.CreateState(f5_arg1, nil, f5_arg1 + 200, nil, CoD.AnchorTypes.Left) - state.font = CoD.TextSettings.TitleFontSmall.Font - state.top = -6 - state.height = 14 - state.alignment = LUI.Alignment.Left - state.glow = LUI.GlowState.None - state.color = color + local state = CoD.CreateState(f5_arg1, nil, f5_arg1 + 200, nil, CoD.AnchorTypes.Left) + state.font = CoD.TextSettings.TitleFontSmall.Font + state.top = -6 + state.height = 14 + state.alignment = LUI.Alignment.Left + state.glow = LUI.GlowState.None + state.color = color - local el = LUI.UIText.new(state) - el:registerAnimationState("focused", { - color = luiglobals.Colors.white - }) + local el = LUI.UIText.new(state) + el:registerAnimationState("focused", { + color = luiglobals.Colors.white + }) - el:registerEventHandler("focused", function(element, event) - element:animateToState("focused", 0) - end) + el:registerEventHandler("focused", function(element, event) + element:animateToState("focused", 0) + end) - el:registerEventHandler("unfocused", function(element, event) - element:animateToState("default", 0) - end) + el:registerEventHandler("unfocused", function(element, event) + element:animateToState("default", 0) + end) - el:setText(text) - menu:addElement(el) + el:setText(text) + menu:addElement(el) end function menu_systemlink_join(f19_arg0, f19_arg1) - local width = 1145 + local width = 1145 - local menu = LUI.MenuTemplate.new(f19_arg0, { - menu_title = "@PLATFORM_SYSTEM_LINK_TITLE", - menu_width = width, - menu_top_indent = 20, - disableDeco = true, - spacing = 1 - }) + local menu = LUI.MenuTemplate.new(f19_arg0, { + menu_title = "@PLATFORM_SYSTEM_LINK_TITLE", + menu_width = width, + menu_top_indent = 20, + disableDeco = true, + spacing = 1 + }) - SystemLinkJoinMenu.AddHeaderButton(menu, 80, width) - SystemLinkJoinMenu.AddLowerCounter(menu, width) - SystemLinkJoinMenu.UpdateCounterText(menu, nil) - Lobby.BuildServerList(Engine.GetFirstActiveController()) + SystemLinkJoinMenu.AddHeaderButton(menu, 80, width) + SystemLinkJoinMenu.AddLowerCounter(menu, width) + SystemLinkJoinMenu.UpdateCounterText(menu, nil) + Lobby.BuildServerList(Engine.GetFirstActiveController()) - menu.list:registerEventHandler(LUI.UIScrollIndicator.UpdateEvent, function(element, event) - SystemLinkJoinMenu.UpdateCounterText(menu, event) - end) + menu.list:registerEventHandler(LUI.UIScrollIndicator.UpdateEvent, function(element, event) + SystemLinkJoinMenu.UpdateCounterText(menu, event) + end) - SystemLinkJoinMenu.UpdateGameList(menu) - menu:registerEventHandler("updateGameList", SystemLinkJoinMenu.UpdateGameList) - menu:addElement(LUI.UITimer.new(250, "updateGameList")) + SystemLinkJoinMenu.UpdateGameList(menu) + menu:registerEventHandler("updateGameList", SystemLinkJoinMenu.UpdateGameList) + menu:addElement(LUI.UITimer.new(250, "updateGameList")) - LUI.ButtonHelperText.ClearHelperTextObjects(menu.help, { - side = "all" - }) + LUI.ButtonHelperText.ClearHelperTextObjects(menu.help, { + side = "all" + }) - menu:AddHelp({ - name = "add_button_helper_text", - button_ref = "button_alt1", - helper_text = Engine.Localize("@MENU_SB_TOOLTIP_BTN_REFRESH"), - side = "right", - clickable = true, - priority = -1000 - }, function(f21_arg0, f21_arg1) - SystemLinkJoinMenu.RefreshServers(f21_arg0, f21_arg1, menu) - end) + menu:AddHelp({ + name = "add_button_helper_text", + button_ref = "button_alt1", + helper_text = Engine.Localize("@MENU_SB_TOOLTIP_BTN_REFRESH"), + side = "right", + clickable = true, + priority = -1000 + }, function(f21_arg0, f21_arg1) + SystemLinkJoinMenu.RefreshServers(f21_arg0, f21_arg1, menu) + end) - menu:AddHelp({ - name = "add_button_helper_text", - button_ref = "button_action", - helper_text = Engine.Localize("@MENU_JOIN_GAME1"), - side = "left", - clickable = false, - priority = -1000 - }, nil, nil, true) + menu:AddHelp({ + name = "add_button_helper_text", + button_ref = "button_action", + helper_text = Engine.Localize("@MENU_JOIN_GAME1"), + side = "left", + clickable = false, + priority = -1000 + }, nil, nil, true) - menu:AddBackButton() + menu:AddBackButton() - Lobby.RefreshServerList(Engine.GetFirstActiveController()) + Lobby.RefreshServerList(Engine.GetFirstActiveController()) - return menu + return menu end LUI.MenuBuilder.m_types_build["menu_systemlink_join"] = menu_systemlink_join diff --git a/data/ui_scripts/stats/__init__.lua b/data/ui_scripts/stats/__init__.lua index f8a12274..9975bfe5 100644 --- a/data/ui_scripts/stats/__init__.lua +++ b/data/ui_scripts/stats/__init__.lua @@ -1,15 +1,17 @@ if (game:issingleplayer() or not Engine.InFrontend()) then - return + return end game:addlocalizedstring("LUA_MENU_STATS", "Stats") game:addlocalizedstring("LUA_MENU_STATS_DESC", "Edit player stats settings.") game:addlocalizedstring("LUA_MENU_UNLOCKALL_ITEMS", "Unlock all items") -game:addlocalizedstring("LUA_MENU_UNLOCKALL_ITEMS_DESC", "Whether items should be locked based on the player's stats or always unlocked.") +game:addlocalizedstring("LUA_MENU_UNLOCKALL_ITEMS_DESC", + "Whether items should be locked based on the player's stats or always unlocked.") game:addlocalizedstring("LUA_MENU_UNLOCKALL_CLASSES", "Unlock all classes") -game:addlocalizedstring("LUA_MENU_UNLOCKALL_CLASSES_DESC", "Whether classes should be locked based on the player's stats or always unlocked.") +game:addlocalizedstring("LUA_MENU_UNLOCKALL_CLASSES_DESC", + "Whether classes should be locked based on the player's stats or always unlocked.") game:addlocalizedstring("LUA_MENU_PRESTIGE", "Prestige") game:addlocalizedstring("LUA_MENU_PRESTIGE_DESC", "Edit prestige level.") @@ -23,202 +25,166 @@ game:addlocalizedstring("LUA_MENU_SETTINGS", "Settings") game:addlocalizedstring("LUA_MENU_EDIT_STATS", "Edit Stats") function createdivider(menu, text) - local element = LUI.UIElement.new( { - leftAnchor = true, - rightAnchor = true, - left = 0, - right = 0, - topAnchor = true, - bottomAnchor = false, - top = 0, - bottom = 33.33 - }) + local element = LUI.UIElement.new({ + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + topAnchor = true, + bottomAnchor = false, + top = 0, + bottom = 33.33 + }) - element.scrollingToNext = true - element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { - title_bar_text = Engine.ToUpperCase(Engine.Localize(text)) - })) + element.scrollingToNext = true + element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { + title_bar_text = Engine.ToUpperCase(Engine.Localize(text)) + })) - menu.list:addElement(element) + menu.list:addElement(element) end local personalizationbutton = LUI.MPLobbyBase.AddPersonalizationButton LUI.MPLobbyBase.AddPersonalizationButton = function(menu) - personalizationbutton(menu) - menu:AddButton("@LUA_MENU_STATS", function() - LUI.FlowManager.RequestAddMenu(nil, "stats_menu") - end) + personalizationbutton(menu) + menu:AddButton("@LUA_MENU_STATS", function() + LUI.FlowManager.RequestAddMenu(nil, "stats_menu") + end) end LUI.MenuBuilder.registerType("stats_menu", function(a1) - local menu = LUI.MenuTemplate.new(a1, { - menu_title = Engine.ToUpperCase(Engine.Localize("@LUA_MENU_STATS")), - menu_width = luiglobals.GenericMenuDims.OptionMenuWidth, - }) + local menu = LUI.MenuTemplate.new(a1, { + menu_title = Engine.ToUpperCase(Engine.Localize("@LUA_MENU_STATS")), + menu_width = luiglobals.GenericMenuDims.OptionMenuWidth + }) - createdivider(menu, "@LUA_MENU_SETTINGS") + createdivider(menu, "@LUA_MENU_SETTINGS") - LUI.Options.CreateOptionButton( - menu, - "cg_unlockall_items", - "@LUA_MENU_UNLOCKALL_ITEMS", - "@LUA_MENU_UNLOCKALL_ITEMS_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - }, - nil, - nil - ) + LUI.Options.CreateOptionButton(menu, "cg_unlockall_items", "@LUA_MENU_UNLOCKALL_ITEMS", + "@LUA_MENU_UNLOCKALL_ITEMS_DESC", {{ + text = "@LUA_MENU_ENABLED", + value = true + }, { + text = "@LUA_MENU_DISABLED", + value = false + }}, nil, nil) - LUI.Options.CreateOptionButton( - menu, - "cg_unlockall_classes", - "@LUA_MENU_UNLOCKALL_CLASSES", - "@LUA_MENU_UNLOCKALL_CLASSES_DESC", - { - { - text = "@LUA_MENU_ENABLED", - value = true - }, - { - text = "@LUA_MENU_DISABLED", - value = false - } - }, - nil, - nil - ) + LUI.Options.CreateOptionButton(menu, "cg_unlockall_classes", "@LUA_MENU_UNLOCKALL_CLASSES", + "@LUA_MENU_UNLOCKALL_CLASSES_DESC", {{ + text = "@LUA_MENU_ENABLED", + value = true + }, { + text = "@LUA_MENU_DISABLED", + value = false + }}, nil, nil) - createdivider(menu, "@LUA_MENU_EDIT_STATS") + createdivider(menu, "@LUA_MENU_EDIT_STATS") - local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 - local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 - local rank = luiglobals.Lobby.GetRankForXP(experience, prestige) + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 + local rank = luiglobals.Lobby.GetRankForXP(experience, prestige) - local saved = true - local prestigevalue = prestige - local rankvalue = rank - local rankbutton = nil + local saved = true + local prestigevalue = prestige + local rankvalue = rank + local rankbutton = nil - prestigeeditbutton(menu, function(value) - prestigevalue = value - saved = false - end) + prestigeeditbutton(menu, function(value) + prestigevalue = value + saved = false + end) - rankbutton = rankeditbutton(menu, function(value) - rankvalue = value - saved = false - end) + rankbutton = rankeditbutton(menu, function(value) + rankvalue = value + saved = false + end) - local savebutton = menu:AddButton("@LUA_MENU_SAVE", function() - Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "prestige", tonumber(prestigevalue)) + local savebutton = menu:AddButton("@LUA_MENU_SAVE", function() + Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "prestige", tonumber(prestigevalue)) - local rank = tonumber(rankvalue) - local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 - local experience = rank == 0 and 0 or luiglobals.Rank.GetRankMaxXP(tonumber(rankvalue) - 1, prestige) + local rank = tonumber(rankvalue) + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local experience = rank == 0 and 0 or luiglobals.Rank.GetRankMaxXP(tonumber(rankvalue) - 1, prestige) - Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "experience", experience) + Engine.SetPlayerData(0, CoD.StatsGroup.Ranked, "experience", experience) - saved = true - end, nil, nil, nil, { - desc_text = Engine.Localize("LUA_MENU_SAVE_DESC") - }) + saved = true + end, nil, nil, nil, { + desc_text = Engine.Localize("LUA_MENU_SAVE_DESC") + }) - LUI.Options.InitScrollingList(menu.list, nil) - LUI.Options.AddOptionTextInfo(menu) + LUI.Options.InitScrollingList(menu.list, nil) + LUI.Options.AddOptionTextInfo(menu) - menu:AddBackButton(function() - if (saved) then - LUI.FlowManager.RequestLeaveMenu(menu) - return - end + menu:AddBackButton(function() + if (saved) then + LUI.FlowManager.RequestLeaveMenu(menu) + return + end - LUI.yesnopopup({ - title = Engine.Localize("@MENU_NOTICE"), - text = Engine.Localize("@LUA_MENU_UNSAVED_CHANGES"), - callback = function(result) - if (result) then - LUI.FlowManager.RequestLeaveMenu(menu) - end - end - }) - end) + LUI.yesnopopup({ + title = Engine.Localize("@MENU_NOTICE"), + text = Engine.Localize("@LUA_MENU_UNSAVED_CHANGES"), + callback = function(result) + if (result) then + LUI.FlowManager.RequestLeaveMenu(menu) + end + end + }) + end) - return menu + return menu end) function prestigeeditbutton(menu, callback) - local options = {} - local max = luiglobals.Lobby.GetMaxPrestigeLevel() - local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local options = {} + local max = luiglobals.Lobby.GetMaxPrestigeLevel() + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 - for i = 0, max do - game:addlocalizedstring("LUA_MENU_" .. i, i .. "") + for i = 0, max do + game:addlocalizedstring("LUA_MENU_" .. i, i .. "") - table.insert(options, { - text = "@" .. i, - value = i .. "" - }) - end + table.insert(options, { + text = "@" .. i, + value = i .. "" + }) + end - Engine.SetDvarFromString("ui_prestige_level", prestige .. "") + Engine.SetDvarFromString("ui_prestige_level", prestige .. "") - LUI.Options.CreateOptionButton( - menu, - "ui_prestige_level", - "@LUA_MENU_PRESTIGE", - "@LUA_MENU_PRESTIGE_DESC", - options, - nil, - nil, - callback - ) + LUI.Options.CreateOptionButton(menu, "ui_prestige_level", "@LUA_MENU_PRESTIGE", "@LUA_MENU_PRESTIGE_DESC", options, + nil, nil, callback) end function rankeditbutton(menu, callback) - local options = {} - local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 - local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 + local options = {} + local prestige = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "prestige") or 0 + local experience = Engine.GetPlayerData(0, CoD.StatsGroup.Ranked, "experience") or 0 - local rank = luiglobals.Lobby.GetRankForXP(experience, prestige) - local max = luiglobals.Rank.GetMaxRank(prestige) - local maxprestige = luiglobals.Lobby.GetMaxPrestigeLevel() + local rank = luiglobals.Lobby.GetRankForXP(experience, prestige) + local max = luiglobals.Rank.GetMaxRank(prestige) + local maxprestige = luiglobals.Lobby.GetMaxPrestigeLevel() - for i = 0, max do - game:addlocalizedstring("LUA_MENU_" .. i, i .. "") + for i = 0, max do + game:addlocalizedstring("LUA_MENU_" .. i, i .. "") - table.insert(options, { - text = "@" .. (i + 1), - value = i .. "" - }) - end + table.insert(options, { + text = "@" .. (i + 1), + value = i .. "" + }) + end - Engine.SetDvarFromString("ui_rank_level_", rank .. "") + Engine.SetDvarFromString("ui_rank_level_", rank .. "") - return LUI.Options.CreateOptionButton( - menu, - "ui_rank_level_", - "@LUA_MENU_RANK", - "@LUA_MENU_RANK_DESC", - options, - nil, - nil, - callback - ) + return LUI.Options.CreateOptionButton(menu, "ui_rank_level_", "@LUA_MENU_RANK", "@LUA_MENU_RANK_DESC", options, nil, + nil, callback) end local isclasslocked = luiglobals.Cac.IsCustomClassLocked luiglobals.Cac.IsCustomClassLocked = function(...) - if (Engine.GetDvarBool("cg_unlockall_classes")) then - return false - end + if (Engine.GetDvarBool("cg_unlockall_classes")) then + return false + end - return isclasslocked(table.unpack({...})) + return isclasslocked(table.unpack({...})) end From 8bfb8329edbfabc45272b36bb4ec78f0dd4d5f35 Mon Sep 17 00:00:00 2001 From: DoktorSAS <62484597+DoktorSAS@users.noreply.github.com> Date: Sat, 12 Mar 2022 22:42:23 +0100 Subject: [PATCH 074/346] Update functions Named some functions Fixed some wrong named functions --- src/client/game/scripting/function_tables.cpp | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 8a869d7d..6df25003 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -820,7 +820,7 @@ namespace scripting {"startragdoll", 0x8023}, // SP 0x1402AD920 MP 0x14037BA50 {"startragdollfromimpact", 0x8024}, // SP 0x1402ADA90 MP 0x000000000 {"queryshouldearlyragdoll", 0x8025}, // SP 0x1405D92F0 MP 0x14035CB60 - {"shouldearlyragdoll", 0x8026}, // SP 0x1405D92F0 MP 0x140377C40 + {"logstring", 0x8026}, // SP 0x1405D92F0 MP 0x140377C40 - shouldearlyragdoll {"_meth_8027", 0x8027}, {"_meth_8028", 0x8028}, // SP 0x1402ADE80 MP 0x000000000 {"thermaldrawenable", 0x8029}, // SP 0x14029AEC0 MP 0x140362D10 @@ -1264,7 +1264,7 @@ namespace scripting {"missilesetflightmodedirect", 0x81DF}, // SP 0x14029AA10 MP 0x1403663A0 {"missilesetflightmodetop", 0x81E0}, // SP 0x14029AB50 MP 0x140366480 {"getlightintensity", 0x81E1}, // SP 0x14028EA00 MP 0x14036E8B0 - {"_meth_81e2", 0x81E2}, // SP 0x14028EB40 MP 0x14036EAB0 + {"setlightintensity", 0x81E2}, // SP 0x14028EB40 MP 0x14036EAB0 {"isragdoll", 0x81E3}, // SP 0x14028F2F0 MP 0x14036F2E0 {"setmovespeedscale", 0x81E4}, // SP 0x1402A2860 MP 0x14036EF80 {"cameralinkto", 0x81E5}, // SP 0x14028FFC0 MP 0x1403584E0 @@ -1369,7 +1369,7 @@ namespace scripting {"buttonpressed", 0x8248}, // SP 0x140268FE0 MP 0x140332B40 {"sayteam", 0x8249}, // SP 0x000000000 MP 0x1403345F0 {"sayall", 0x824A}, // SP 0x000000000 MP 0x1403346A0 - {"_meth_824b", 0x824B}, // SP 0x000000000 MP 0x140332C90 + {"setspawnweapon", 0x824B}, // SP 0x000000000 MP 0x140332C90 {"dropitem", 0x824C}, // SP 0x140265080 MP 0x140330FE0 {"dropscavengerbag", 0x824D}, // SP 0x000000000 MP 0x140332FB0 {"setjitterparams", 0x824E}, // SP 0x140461E80 MP 0x140560640 @@ -1471,7 +1471,7 @@ namespace scripting {"_meth_82ae", 0x82AE}, // SP 0x1402B2C10 MP 0x14037EB00 {"_meth_82af", 0x82AF}, // SP 0x1402B2D70 MP 0x14037EC90 {"_meth_82b0", 0x82B0}, // SP 0x1402B2EE0 MP 0x14037EE20 - {"rotateby", 0x82B1}, // SP 0x1402B3030 MP 0x14037EF10 + {"rotateto", 0x82B1}, // SP 0x1402B3030 MP 0x14037EF10 {"_meth_82b2", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 {"_meth_82b3", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 {"_meth_82b4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 @@ -1479,7 +1479,7 @@ namespace scripting {"_meth_82b6", 0x82B6}, // SP 0x1402B3430 MP 0x14037F030 {"_meth_82b7", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 {"_meth_82b8", 0x82B8}, // SP 0x1402B34B0 MP 0x14037F0B0 - {"_meth_82b9", 0x82B9}, // SP 0x1402B3700 MP 0x14037F3C0 + {"rotatevelocity", 0x82B9}, // SP 0x1402B3700 MP 0x14037F3C0 {"solid", 0x82BA}, // SP 0x1402B45E0 MP 0x1403808A0 {"notsolid", 0x82BB}, // SP 0x1402B4690 MP 0x140380950 {"setcandamage", 0x82BC}, // SP 0x1402B3880 MP 0x14037F590 @@ -1493,7 +1493,7 @@ namespace scripting {"_meth_82c4", 0x82C4}, // SP 0x000000000 MP 0x140331E70 {"setspectatedefaults", 0x82C5}, // SP 0x000000000 MP 0x140331EE0 {"getthirdpersoncrosshairoffset", 0x82C6}, // SP 0x000000000 MP 0x140332250 - {"_meth_82c7", 0x82C7}, // SP 0x140262950 MP 0x14032EF00 + {"disableweaponpickup", 0x82C7}, // SP 0x140262950 MP 0x14032EF00 {"_meth_82c8", 0x82C8}, // SP 0x140262A60 MP 0x14032EFF0 {"_meth_82c9", 0x82C9}, // SP 0x140262AB0 MP 0x14032F0D0 {"_meth_82ca", 0x82CA}, // SP 0x000000000 MP 0x1403322C0 @@ -1518,7 +1518,7 @@ namespace scripting {"_meth_82dd", 0x82DD}, // SP 0x140266FE0 MP 0x14032B500 {"playfx", 0x82DE}, // SP 0x140267330 MP 0x14032B9F0 {"playerrecoilscaleon", 0x82DF}, // SP 0x140267530 MP 0x14032BD00 - {"_meth_82e0", 0x82E0}, // SP 0x140267600 MP 0x14032BDD0 + {"player_recoilscaleoff", 0x82E0}, // SP 0x140267600 MP 0x14032BDD0 {"weaponlockstart", 0x82E1}, // SP 0x1402676E0 MP 0x14032C000 {"weaponlockfinalize", 0x82E2}, // SP 0x140260240 MP 0x14032C240 {"disableautoreload", 0x82E3}, // SP 0x140260540 MP 0x14032C6C0 @@ -1535,7 +1535,7 @@ namespace scripting {"setvelocity", 0x82EE}, // SP 0x1402601C0 MP 0x14032BBE0 {"_meth_82ef", 0x82EF}, // SP 0x140260AD0 MP 0x14032C3C0 {"_meth_82f0", 0x82F0}, // SP 0x140260E80 MP 0x14032C5E0 - {"playsound", 0x82F1}, // SP 0x1402677A0 MP 0x14032BE30 + {"playlocalsound", 0x82F1}, // SP 0x1402677A0 MP 0x14032BE30 {"_meth_82f2", 0x82F2}, // SP 0x140260130 MP 0x14032BF20 {"setweaponammoclip", 0x82F3}, // SP 0x140264AD0 MP 0x140330E20 {"setweaponammostock", 0x82F4}, // SP 0x140264EB0 MP 0x140331350 @@ -1554,26 +1554,26 @@ namespace scripting {"weaponlocktargettooclose", 0x8301}, // SP 0x140261CE0 MP 0x14032DBB0 {"setspreadoverride", 0x8302}, // SP 0x140262B00 MP 0x14032ED00 {"resetspreadoverride", 0x8303}, // SP 0x140262CC0 MP 0x14032EE80 - {"_meth_8304", 0x8304}, // SP 0x140262D90 MP 0x14032EF60 + {"setaimspreadmovementscale", 0x8304}, // SP 0x140262D90 MP 0x14032EF60 {"setactionslot", 0x8305}, // SP 0x140261F10 MP 0x14032DD50 {"setviewkickscale", 0x8306}, // SP 0x1402608B0 MP 0x14032CB90 {"getviewkickscale", 0x8307}, // SP 0x140260A80 MP 0x14032CCC0 - {"getweaponslistoffhands", 0x8308}, // SP 0x1402621A0 MP 0x14032E120 + {"getweaponslistall", 0x8308}, // SP 0x1402621A0 MP 0x14032E120 - getweaponslistoffhands {"getweaponslistitems", 0x8309}, // SP 0x1402622E0 MP 0x14032E230 {"_meth_830a", 0x830A}, // SP 0x140261090 MP 0x14032C720 - {"_meth_830b", 0x830B}, // SP 0x140262F00 MP 0x14032EA90 + {"giveweapon", 0x830B}, // SP 0x140262F00 MP 0x14032EA90f {"takeweapon", 0x830C}, // SP 0x140263380 MP 0x14032F210 {"takeallweapons", 0x830D}, // SP 0x1402635B0 MP 0x14032F310 {"getcurrentweapon", 0x830E}, // SP 0x140263750 MP 0x14032F5E0 {"getcurrentprimaryweapon", 0x830F}, // SP 0x140263A30 MP 0x14032F860 {"getcurrentoffhand", 0x8310}, // SP 0x140263EF0 MP 0x14032FC50 - {"givestartammo", 0x8311}, // SP 0x1402647A0 MP 0x140330740 + {"hasweapon", 0x8311}, // SP 0x1402647A0 MP 0x140330740 {"switchtoweapon", 0x8312}, // SP 0x140264CA0 MP 0x140330D20 {"switchtoweaponimmediate", 0x8313}, // SP 0x140264E50 MP 0x140330D90 {"gethybridscopestate", 0x8314}, // SP 0x140265950 MP 0x140329520 {"switchtooffhand", 0x8315}, // SP 0x140265B80 MP 0x1403296D0 {"_meth_8316", 0x8316}, // SP 0x140264440 MP 0x140330340 - {"getcustomizationbody", 0x8317}, // SP 0x140264600 MP 0x140330520 + {"getoffhandSecondaryclass", 0x8317}, // SP 0x140264600 MP 0x140330520 {"beginlocationselection", 0x8318}, // SP 0x140260C90 MP 0x14032C470 {"_meth_8319", 0x8319}, // SP 0x140261020 MP 0x14032C780 {"_meth_831a", 0x831A}, // SP 0x140263E90 MP 0x1403302E0 @@ -1612,7 +1612,7 @@ namespace scripting {"meleebuttonpressed", 0x833B}, // SP 0x1402617D0 MP 0x14032D1B0 {"jumpbuttonpressed", 0x833C}, // SP 0x1402618D0 MP 0x14032D450 {"getviewheight", 0x833D}, // SP 0x140262070 MP 0x14032DC20 - {"_meth_833e", 0x833E}, // SP 0x1402620C0 MP 0x14032DCE0 + {"isonground", 0x833E}, // SP 0x1402620C0 MP 0x14032DCE0 {"isonladder", 0x833F}, // SP 0x140262280 MP 0x14032DF80 {"setviewmodel", 0x8340}, // SP 0x1402626A0 MP 0x14032DFF0 {"_meth_8341", 0x8341}, // SP 0x140264090 MP 0x14032FF10 @@ -1786,7 +1786,7 @@ namespace scripting {"hudoutlineenableforclients", 0x83E9}, // SP 0x14026D2E0 MP 0x14033B450 {"getlinkedparent", 0x83EA}, // SP 0x14028DB50 MP 0x140359B60 {"getmovingplatformparent", 0x83EB}, // SP 0x14028E2A0 MP 0x14035A4D0 - {"_meth_83ec", 0x83EC}, // SP 0x000000000 MP 0x14032CEF0 + {"setnameplatematerial", 0x83EC}, // SP 0x000000000 MP 0x14032CEF0 {"_meth_83ed", 0x83ED}, // SP 0x1402ADF90 MP 0x000000000 {"_meth_83ee", 0x83EE}, {"_meth_83ef", 0x83EF}, // SP 0x1402A0B60 MP 0x14036A5C0 From 5d2f33bd5670558fe807550d5dcaca3d75b8a306 Mon Sep 17 00:00:00 2001 From: m Date: Sat, 12 Mar 2022 16:38:15 -0600 Subject: [PATCH 075/346] Update function_tables.cpp (skip ci) --- src/client/game/scripting/function_tables.cpp | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 6df25003..8a753d92 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -933,7 +933,7 @@ namespace scripting {"dontinterpolate", 0x8094}, // SP 0x1402A0070 MP 0x140358360 {"_meth_8095", 0x8095}, // SP 0x1402AAC80 MP 0x000000000 {"_meth_8096", 0x8096}, // SP 0x1402AAD20 MP 0x000000000 - {"_meth_8097", 0x8097}, // SP 0x1402AADC0 MP 0x140377CA0 + {"getorigin", 0x8097}, // SP 0x1402AADC0 MP 0x140377CA0 {"_meth_8098", 0x8098}, // SP 0x1402AAE70 MP 0x000000000 {"_meth_8099", 0x8099}, // SP 0x1402AAF90 MP 0x000000000 {"_meth_809a", 0x809A}, // SP 0x1402AC1D0 MP 0x000000000 @@ -952,26 +952,26 @@ namespace scripting {"_meth_80a7", 0x80A7}, // SP 0x1402960D0 MP 0x000000000 {"_meth_80a8", 0x80A8}, // SP 0x140297190 MP 0x000000000 {"_meth_80a9", 0x80A9}, // SP 0x140297C20 MP 0x000000000 - {"_meth_80aa", 0x80AA}, // SP 0x14029DDD0 MP 0x1403663C0 + {"geteye", 0x80AA}, // SP 0x14029DDD0 MP 0x1403663C0 {"istouching", 0x80AB}, // SP 0x140290390 MP 0x14035B440 {"getistouchingentities", 0x80AC}, // SP 0x1402904A0 MP 0x14035B650 - {"_meth_80ad", 0x80AD}, // SP 0x1402987B0 MP 0x14035FAA0 + {"stoploopsound", 0x80AD}, // SP 0x1402987B0 MP 0x14035FAA0 {"stopsounds", 0x80AE}, // SP 0x140290F40 MP 0x14035C610 {"playrumbleonentity", 0x80AF}, // SP 0x140299090 MP 0x140360200 {"playrumblelooponentity", 0x80B0}, // SP 0x140299200 MP 0x1403602A0 {"stoprumble", 0x80B1}, // SP 0x1402997D0 MP 0x1403608E0 {"delete", 0x80B2}, // SP 0x14029DAA0 MP 0x140366320 {"setmodel", 0x80B3}, // SP 0x14029C8F0 MP 0x1403677D0 - {"_meth_80b4", 0x80B4}, // SP 0x14029A0F0 MP 0x140361C30 - {"_meth_80b5", 0x80B5}, // SP 0x14029A250 MP 0x140361F90 + {"laseron", 0x80B4}, // SP 0x14029A0F0 MP 0x140361C30 + {"laseroff", 0x80B5}, // SP 0x14029A250 MP 0x140361F90 {"_meth_80b6", 0x80B6}, {"_meth_80b7", 0x80B7}, {"thermalvisionon", 0x80B8}, // SP 0x14029A450 MP 0x1403623A0 {"thermalvisionoff", 0x80B9}, // SP 0x14029AAF0 MP 0x140362B70 {"_meth_80ba", 0x80BA}, // SP 0x14029BF20 MP 0x140364290 {"_meth_80bb", 0x80BB}, // SP 0x14029C080 MP 0x140364630 - {"_meth_80bc", 0x80BC}, // SP 0x000000000 MP 0x140364910 - {"autospotoverlayon", 0x80BD}, // SP 0x000000000 MP 0x140364A50 + {"autospotoverlayon", 0x80BC}, // SP 0x000000000 MP 0x140364910 + {"autospotoverlayoff", 0x80BD}, // SP 0x000000000 MP 0x140364A50 {"_meth_80be", 0x80BE}, // SP 0x000000000 MP 0x140364D40 {"_meth_80bf", 0x80BF}, {"setcontents", 0x80C0}, // SP 0x140297CC0 MP 0x14035FDD0 @@ -989,8 +989,8 @@ namespace scripting {"settext", 0x80CC}, // SP 0x14026CE20 MP 0x14033AF40 {"_meth_80cd", 0x80CD}, // SP 0x1405D92F0 MP 0x14033B030 {"setshader", 0x80CE}, // SP 0x14026CEE0 MP 0x14033B040 - {"_meth_80cf", 0x80CF}, // SP 0x14026D230 MP 0x14033B3A0 - {"_meth_80d0", 0x80D0}, // SP 0x14026D3B0 MP 0x14033B530 + {"settargetent", 0x80CF}, // SP 0x14026D230 MP 0x14033B3A0 + {"cleartargetent", 0x80D0}, // SP 0x14026D3B0 MP 0x14033B530 {"_meth_80d1", 0x80D1}, // SP 0x14026D490 MP 0x14033B600 {"_meth_80d2", 0x80D2}, // SP 0x14026D560 MP 0x14033B6C0 {"_meth_80d3", 0x80D3}, // SP 0x14026D630 MP 0x14033B760 @@ -1167,14 +1167,14 @@ namespace scripting {"setturretmodechangewait", 0x817E}, // SP 0x1402994D0 MP 0x140364690 {"usetriggerrequirelookat", 0x817F}, // SP 0x140297DE0 MP 0x14035EEE0 {"getstance", 0x8180}, // SP 0x14029D1C0 MP 0x140364F90 - {"_meth_8181", 0x8181}, // SP 0x14029D430 MP 0x140365230 + {"setstance", 0x8181}, // SP 0x14029D430 MP 0x140365230 {"itemweaponsetammo", 0x8182}, // SP 0x140299FA0 MP 0x140360F20 - {"_meth_8183", 0x8183}, // SP 0x14029A5A0 MP 0x140361420 + {"getammocount", 0x8183}, // SP 0x14029A5A0 MP 0x140361420 {"gettagorigin", 0x8184}, // SP 0x14029E360 MP 0x140368090 {"gettagangles", 0x8185}, // SP 0x14029E810 MP 0x140368320 - {"_meth_8186", 0x8186}, // SP 0x14028E580 MP 0x14036D490 + {"shellshock", 0x8186}, // SP 0x14028E580 MP 0x14036D490 {"stunplayer", 0x8187}, // SP 0x14028F160 MP 0x14036DEC0 - {"_meth_8188", 0x8188}, // SP 0x14029B970 MP 0x140366E70 + {"stopshellshock", 0x8188}, // SP 0x14029B970 MP 0x140366E70 {"_meth_8189", 0x8189}, // SP 0x14029BB30 MP 0x140367230 {"setdepthoffield", 0x818A}, // SP 0x14029EF20 MP 0x140368890 {"setviewmodeldepthoffield", 0x818B}, // SP 0x14029F990 MP 0x140369900 @@ -1401,17 +1401,17 @@ namespace scripting {"_meth_8268", 0x8268}, // SP 0x000000000 MP 0x140334010 {"clientiprintln", 0x8269}, // SP 0x000000000 MP 0x1403340A0 {"clientiprintlnbold", 0x826A}, // SP 0x000000000 MP 0x140334120 - {"spawn", 0x826B}, // SP 0x000000000 MP 0x1403341A0 + {"spawnSpectator", 0x826B}, // SP 0x000000000 MP 0x1403341A0 {"_meth_826c", 0x826C}, // SP 0x000000000 MP 0x140334230 - {"_meth_826d", 0x826D}, // SP 0x000000000 MP 0x140334290 + {"cloneplayer", 0x826D}, // SP 0x000000000 MP 0x140334290 {"istalking", 0x826E}, // SP 0x000000000 MP 0x140334570 {"allowspectateteam", 0x826F}, // SP 0x000000000 MP 0x140334750 - {"_meth_8270", 0x8270}, // SP 0x000000000 MP 0x140334980 + {"_meth_8270", 0x8270}, // SP 0x000000000 MP 0x140334980 // something related to spectate team {"getguid", 0x8271}, // SP 0x000000000 MP 0x140334B20 {"_meth_8272", 0x8272}, // SP 0x1402B3CA0 MP 0x14037FA00 {"_meth_8273", 0x8273}, // SP 0x1402B3EC0 MP 0x14037FC50 {"clonebrushmodeltoscriptmodel", 0x8274}, // SP 0x1402B4500 MP 0x140380380 - {"_meth_8275", 0x8275}, // SP 0x000000000 MP 0x140380450 + {"scriptmodelplayanim", 0x8275}, // SP 0x000000000 MP 0x140380450 {"scriptmodelclearanim", 0x8276}, // SP 0x000000000 MP 0x140380700 {"_meth_8277", 0x8277}, // SP 0x000000000 MP 0x140380570 {"_meth_8278", 0x8278}, // SP 0x140465060 MP 0x1405637F0 @@ -1446,11 +1446,11 @@ namespace scripting {"ismlgspectator", 0x8295}, // SP 0x000000000 MP 0x140334DB0 {"getclanidhigh", 0x8296}, // SP 0x000000000 MP 0x140334E10 {"getclanidlow", 0x8297}, // SP 0x000000000 MP 0x140334E70 - {"_meth_8298", 0x8298}, // SP 0x000000000 MP 0x140334ED0 + {"ishost", 0x8298}, // SP 0x000000000 MP 0x140334ED0 {"getspectatingplayer", 0x8299}, // SP 0x000000000 MP 0x140334F60 {"predictstreampos", 0x829A}, // SP 0x000000000 MP 0x140334FE0 - {"_meth_829b", 0x829B}, // SP 0x000000000 MP 0x1403350D0 - {"_meth_829c", 0x829C}, // SP 0x000000000 MP 0x1403350E0 + {"updatescores", 0x829B}, // SP 0x000000000 MP 0x1403350D0 + {"updatedmscores", 0x829C}, // SP 0x000000000 MP 0x1403350E0 {"setrank", 0x829D}, // SP 0x000000000 MP 0x1403350F0 {"_meth_829e", 0x829E}, // SP 0x000000000 MP 0x140335190 {"setmlgspectator", 0x829F}, // SP 0x140260730 MP 0x14032CA40 @@ -1468,13 +1468,13 @@ namespace scripting {"rotatepitch", 0x82AB}, // SP 0x1402B2F60 MP 0x14037EEB0 {"rotateyaw", 0x82AC}, // SP 0x1402B2F70 MP 0x14037EEC0 {"rotateroll", 0x82AD}, // SP 0x1402B2F90 MP 0x14037EEE0 - {"_meth_82ae", 0x82AE}, // SP 0x1402B2C10 MP 0x14037EB00 + {"movegravity", 0x82AE}, // SP 0x1402B2C10 MP 0x14037EB00 {"_meth_82af", 0x82AF}, // SP 0x1402B2D70 MP 0x14037EC90 {"_meth_82b0", 0x82B0}, // SP 0x1402B2EE0 MP 0x14037EE20 {"rotateto", 0x82B1}, // SP 0x1402B3030 MP 0x14037EF10 {"_meth_82b2", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 - {"_meth_82b3", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 - {"_meth_82b4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 + {"rotateyaw", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 + {"_meth_82b4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 // looks similar to moveto/rotateto, wtf {"_meth_82b5", 0x82B5}, // SP 0x1402B3410 MP 0x14037F010 {"_meth_82b6", 0x82B6}, // SP 0x1402B3430 MP 0x14037F030 {"_meth_82b7", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 From de66f83efe9d182e14915bb7b01ac5b837dc56a0 Mon Sep 17 00:00:00 2001 From: m Date: Sat, 12 Mar 2022 16:42:04 -0600 Subject: [PATCH 076/346] lowercase function table --- src/client/game/scripting/function_tables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 8a753d92..f429aad0 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -1401,7 +1401,7 @@ namespace scripting {"_meth_8268", 0x8268}, // SP 0x000000000 MP 0x140334010 {"clientiprintln", 0x8269}, // SP 0x000000000 MP 0x1403340A0 {"clientiprintlnbold", 0x826A}, // SP 0x000000000 MP 0x140334120 - {"spawnSpectator", 0x826B}, // SP 0x000000000 MP 0x1403341A0 + {"spawnspectator", 0x826B}, // SP 0x000000000 MP 0x1403341A0 {"_meth_826c", 0x826C}, // SP 0x000000000 MP 0x140334230 {"cloneplayer", 0x826D}, // SP 0x000000000 MP 0x140334290 {"istalking", 0x826E}, // SP 0x000000000 MP 0x140334570 From 3cbb438e71c639d9b2396a5e22d64a58f251d1ed Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 00:56:15 +0100 Subject: [PATCH 077/346] Add dvar descriptions --- src/client/component/command.cpp | 10 +- src/client/component/dedicated.cpp | 4 +- src/client/component/exception.cpp | 2 +- src/client/component/fps.cpp | 10 +- src/client/component/game_console.cpp | 51 +- src/client/component/gameplay.cpp | 4 +- src/client/component/logger.cpp | 2 +- src/client/component/map_rotation.cpp | 6 +- src/client/component/network.cpp | 2 +- src/client/component/patches.cpp | 11 +- src/client/component/ranked.cpp | 2 +- src/client/component/renderer.cpp | 2 +- src/client/component/shaders.cpp | 3 +- src/client/component/stats.cpp | 6 +- src/client/component/updater.cpp | 3 +- src/client/component/virtuallobby.cpp | 3 +- src/client/game/dvars.cpp | 4885 ++++++++++++------------- src/client/game/dvars.hpp | 24 +- 18 files changed, 2432 insertions(+), 2598 deletions(-) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index b5c1ad40..3db38b6c 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -1,16 +1,17 @@ #include #include "loader/component_loader.hpp" + #include "command.hpp" #include "console.hpp" #include "game_console.hpp" #include "game/game.hpp" +#include "game/dvars.hpp" #include #include #include -#include "utils/io.hpp" -#include +#include namespace command { @@ -112,9 +113,12 @@ namespace command const auto current = game::Dvar_ValueToString(dvar, dvar->current); const auto reset = game::Dvar_ValueToString(dvar, dvar->reset); - console::info("\"%s\" is: \"%s\" default: \"%s\" hash: 0x%08lX", + console::info("\"%s\" is: \"%s\" default: \"%s\" hash: 0x%08lX\n", args[0], current, reset, dvar->hash); + const auto dvar_info = dvars::dvar_get_description(args[0]); + + console::info("%s\n", dvar_info.data()); console::info(" %s\n", dvars::dvar_get_domain(dvar->type, dvar->domain).data()); } else diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index 8de5e9ac..d012c16c 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -185,10 +185,10 @@ namespace dedicated #endif // Register dedicated dvar - dvars::register_bool("dedicated", true, game::DVAR_FLAG_READ); + dvars::register_bool("dedicated", true, game::DVAR_FLAG_READ, "Dedicated server"); // Add lanonly mode - dvars::register_bool("sv_lanOnly", false, game::DVAR_FLAG_NONE); + dvars::register_bool("sv_lanOnly", false, game::DVAR_FLAG_NONE, "Don't send heartbeat"); // Disable VirtualLobby dvars::override::register_bool("virtualLobbyEnabled", false, game::DVAR_FLAG_READ); diff --git a/src/client/component/exception.cpp b/src/client/component/exception.cpp index 028bb238..ae8f77db 100644 --- a/src/client/component/exception.cpp +++ b/src/client/component/exception.cpp @@ -253,7 +253,7 @@ namespace exception void post_unpack() override { dvars::cg_legacyCrashHandling = dvars::register_bool("cg_legacyCrashHandling", - false, game::DVAR_FLAG_SAVED, true); + false, game::DVAR_FLAG_SAVED, "Disable new crash handling"); } }; } diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index f0a62b69..49caf5bf 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -127,7 +127,7 @@ namespace fps game::dvar_t* cg_draw_fps_register_stub(const char* name, const char** _enum, const int value, unsigned int /*flags*/, const char* desc) { - cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, false); + cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, "Draw frames per second"); return cg_drawfps; } } @@ -160,7 +160,7 @@ namespace fps if (game::environment::is_sp()) { - cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, false); + cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, "Draw frames per second"); } if (game::environment::is_mp()) @@ -168,13 +168,13 @@ namespace fps // fix ping value utils::hook::nop(0x14025AC41, 2); - cg_drawping = dvars::register_int("cg_drawPing", 0, 0, 1, game::DVAR_FLAG_SAVED, true); + cg_drawping = dvars::register_int("cg_drawPing", 0, 0, 1, game::DVAR_FLAG_SAVED, "Choose to draw ping"); scheduler::loop(cg_draw_ping, scheduler::pipeline::renderer); } - dvars::register_bool("cg_infobar_fps", false, game::DVAR_FLAG_SAVED, true); - dvars::register_bool("cg_infobar_ping", false, game::DVAR_FLAG_SAVED, true); + dvars::register_bool("cg_infobar_fps", false, game::DVAR_FLAG_SAVED, "Show server latency"); + dvars::register_bool("cg_infobar_ping", false, game::DVAR_FLAG_SAVED, "Show FPS counter"); } }; } diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index cf7c3056..86013299 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -56,7 +56,7 @@ namespace game_console std::deque history{}; std::string fixed_input{}; - std::vector matches{}; + std::vector matches{}; float color_white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; float color_title[4] = {0.25f, 0.62f, 0.3f, 1.0f}; @@ -159,21 +159,22 @@ namespace game_console con.globals.x = game::R_TextWidth(str, 0, console_font) + con.globals.x + 6.0f; } - void draw_hint_box(const int lines, float* color, [[maybe_unused]] float offset_x = 0.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.globals.font_height + 12.0f; - const auto _y = con.globals.y - 3.0f + con.globals.font_height + 12.0f; + const auto _y = con.globals.y - 3.0f + con.globals.font_height + 12.0f + offset_y; const auto _w = (con.screen_max[0] - con.screen_min[0]) - ((con.globals.x - 6.0f) - con.screen_min[0]); draw_box(con.globals.x - 6.0f, _y, _w, _h, color); + return _h; } - void draw_hint_text(const int line, const char* text, float* color, const float offset = 0.0f) + 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.globals.font_height + con.globals.y + (con.globals.font_height * (line + 1)) + 15.0f; + const auto _y = con.globals.font_height + con.globals.y + (con.globals.font_height * (line + 1)) + 15.0f + offset_y; - game::R_AddCmdDrawText(text, 0x7FFFFFFF, console_font, con.globals.x + offset, _y, 1.0f, 1.0f, 0.0f, color, 0); + game::R_AddCmdDrawText(text, 0x7FFFFFFF, console_font, con.globals.x + offset_x, _y, 1.0f, 1.0f, 0.0f, color, 0); } bool match_compare(const std::string& input, const std::string& text, const bool exact) @@ -183,13 +184,13 @@ namespace game_console return false; } - void find_matches(std::string input, std::vector& suggestions, const bool exact) + void find_matches(std::string input, std::vector& suggestions, const bool exact) { input = utils::string::to_lower(input); for (const auto& dvar : dvars::dvar_list) { - auto name = utils::string::to_lower(dvar); + auto name = utils::string::to_lower(dvar.name); if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) { suggestions.push_back(dvar); @@ -203,7 +204,7 @@ namespace game_console if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) { - suggestions.push_back(input.data()); + suggestions.push_back({input.data(), ""}); } game::cmd_function_s* cmd = (*game::cmd_functions); @@ -215,7 +216,7 @@ namespace game_console if (match_compare(input, name, exact)) { - suggestions.push_back(cmd->name); + suggestions.push_back({cmd->name, ""}); } if (exact && suggestions.size() > 1) @@ -280,39 +281,46 @@ namespace game_console } else if (matches.size() == 1) { - auto* const dvar = game::Dvar_FindVar(matches[0].data()); - const auto line_count = dvar ? 2 : 1; + auto* const dvar = game::Dvar_FindVar(matches[0].name.data()); + const auto line_count = dvar ? 3 : 1; - draw_hint_box(line_count, dvars::con_inputHintBoxColor->current.vector); - draw_hint_text(0, matches[0].data(), dvar + const auto height = draw_hint_box(line_count, dvars::con_inputHintBoxColor->current.vector); + draw_hint_text(0, matches[0].name.data(), dvar ? dvars::con_inputDvarMatchColor->current.vector : dvars::con_inputCmdMatchColor->current.vector); if (dvar) { - const auto offset = (con.screen_max[0] - con.globals.x) / 2.5f; + const auto offset = (con.screen_max[0] - con.globals.x) / 4.f; draw_hint_text(0, game::Dvar_ValueToString(dvar, dvar->current), dvars::con_inputDvarValueColor->current.vector, offset); draw_hint_text(1, " default", dvars::con_inputDvarInactiveValueColor->current.vector); draw_hint_text(1, game::Dvar_ValueToString(dvar, dvar->reset), dvars::con_inputDvarInactiveValueColor->current.vector, offset); + draw_hint_text(2, matches[0].description.data(), + color_white, 0); + + const auto offset_y = height + 3.f; + draw_hint_box(1, dvars::con_inputHintBoxColor->current.vector, 0, offset_y); + draw_hint_text(0, dvars::dvar_get_domain(dvar->type, dvar->domain).data(), + dvars::con_inputCmdMatchColor->current.vector, 0, offset_y); } - strncpy_s(con.globals.auto_complete_choice, matches[0].data(), 64); + strncpy_s(con.globals.auto_complete_choice, matches[0].name.data(), 64); con.globals.may_auto_complete = true; } else if (matches.size() > 1) { draw_hint_box(static_cast(matches.size()), dvars::con_inputHintBoxColor->current.vector); - const auto offset = (con.screen_max[0] - con.globals.x) / 2.5f; + const auto offset = (con.screen_max[0] - con.globals.x) / 4.f; for (size_t i = 0; i < matches.size(); i++) { - auto* const dvar = game::Dvar_FindVar(matches[i].data()); + auto* const dvar = game::Dvar_FindVar(matches[i].name.data()); - draw_hint_text(static_cast(i), matches[i].data(), + draw_hint_text(static_cast(i), matches[i].name.data(), dvar ? dvars::con_inputDvarMatchColor->current.vector : dvars::con_inputCmdMatchColor->current.vector); @@ -321,10 +329,13 @@ namespace game_console { draw_hint_text(static_cast(i), game::Dvar_ValueToString(dvar, dvar->current), dvars::con_inputDvarValueColor->current.vector, offset); + + draw_hint_text(static_cast(i), matches[i].description.data(), + dvars::con_inputDvarValueColor->current.vector, offset * 1.5f); } } - strncpy_s(con.globals.auto_complete_choice, matches[0].data(), 64); + strncpy_s(con.globals.auto_complete_choice, matches[0].name.data(), 64); con.globals.may_auto_complete = true; } } diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index 115522e7..e9c28ea5 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -45,10 +45,10 @@ namespace gameplay } utils::hook::call(0x1401E8830, jump_apply_slowdown_stub); - jump_slowDownEnable = dvars::register_bool("jump_slowDownEnable", true, game::DVAR_FLAG_REPLICATED, true); + jump_slowDownEnable = dvars::register_bool("jump_slowDownEnable", true, game::DVAR_FLAG_REPLICATED, "Slow player movement after jumping"); utils::hook::call(0x1401E490F, pm_crashland_stub); - jump_enableFallDamage = dvars::register_bool("jump_enableFallDamage", true, game::DVAR_FLAG_REPLICATED, true); + jump_enableFallDamage = dvars::register_bool("jump_enableFallDamage", true, game::DVAR_FLAG_REPLICATED, "Enable fall damage"); } }; } diff --git a/src/client/component/logger.cpp b/src/client/component/logger.cpp index 361ac339..dc2ba9df 100644 --- a/src/client/component/logger.cpp +++ b/src/client/component/logger.cpp @@ -93,7 +93,7 @@ namespace logger void print_dev(const char* msg, ...) { - static auto* enabled = dvars::register_bool("logger_dev", false, game::DVAR_FLAG_SAVED, true); + static auto* enabled = dvars::register_bool("logger_dev", false, game::DVAR_FLAG_SAVED, "Print dev stuff"); if (!enabled->current.enabled) { return; diff --git a/src/client/component/map_rotation.cpp b/src/client/component/map_rotation.cpp index 216cbfcd..de1f9f83 100644 --- a/src/client/component/map_rotation.cpp +++ b/src/client/component/map_rotation.cpp @@ -162,9 +162,9 @@ namespace map_rotation scheduler::once([]() { - dvars::register_string("sv_mapRotation", "", game::DVAR_FLAG_NONE, true); - dvars::register_string("sv_mapRotationCurrent", "", game::DVAR_FLAG_NONE, true); - dvars::register_string("sv_autoPriority", "", game::DVAR_FLAG_NONE, true); + dvars::register_string("sv_mapRotation", "", game::DVAR_FLAG_NONE, ""); + dvars::register_string("sv_mapRotationCurrent", "", game::DVAR_FLAG_NONE, ""); + dvars::register_string("sv_autoPriority", "", game::DVAR_FLAG_NONE, "Lowers the process priority during map changes to not cause lags on other servers."); }, scheduler::pipeline::main); command::add("map_rotate", &perform_map_rotation); diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 226c3d05..46d4b614 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -209,7 +209,7 @@ namespace network const char* description) { game::dvar_t* dvar; - dvar = dvars::register_int("net_port", 27016, 0, 0xFFFFu, game::DVAR_FLAG_LATCHED); + dvar = dvars::register_int("net_port", 27016, 0, 0xFFFFu, game::DVAR_FLAG_LATCHED, "Network port"); // read net_port from command line command::read_startup_variable("net_port"); diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 8cf81a71..7c323ded 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -56,10 +56,10 @@ namespace patches if (game::environment::is_mp()) { // Make name save - dvars::register_string("name", get_login_username().data(), game::DVAR_FLAG_SAVED, true); + dvars::register_string("name", get_login_username().data(), game::DVAR_FLAG_SAVED, "Player name."); // Disable data validation error popup - dvars::register_int("data_validation_allow_drop", 0, 0, 0, game::DVAR_FLAG_NONE, true); + dvars::register_int("data_validation_allow_drop", 0, 0, 0, game::DVAR_FLAG_NONE, ""); } return com_register_dvars_hook.invoke(); @@ -206,7 +206,7 @@ namespace patches // client side aim assist dvar dvars::aimassist_enabled = dvars::register_bool("aimassist_enabled", true, game::DvarFlags::DVAR_FLAG_SAVED, - true); + "Enables aim assist for controllers"); utils::hook::call(0x14009EE9E, aim_assist_add_to_target_list); // isProfanity @@ -235,6 +235,9 @@ namespace patches utils::hook::nop(0x140190C16, 5); utils::hook::set(0x14021D22A, 0xEB); + // some anti tamper thing that kills performance + dvars::override::register_int("dvl", 0, 0, 0, game::DVAR_FLAG_READ); + // unlock safeArea_* utils::hook::jump(0x1402624F5, 0x140262503); utils::hook::jump(0x14026251C, 0x140262547); @@ -252,7 +255,7 @@ namespace patches dvars::override::register_int("cl_connectTimeout", 120, 120, 1800, game::DVAR_FLAG_NONE); // Seems unused dvars::override::register_int("sv_connectTimeout", 120, 120, 1800, game::DVAR_FLAG_NONE); // 60 - 0 - 1800 - dvars::register_int("scr_game_spectatetype", 1, 0, 99, game::DVAR_FLAG_REPLICATED); + dvars::register_int("scr_game_spectatetype", 1, 0, 99, game::DVAR_FLAG_REPLICATED, ""); dvars::override::register_bool("ui_drawcrosshair", true, game::DVAR_FLAG_WRITE); diff --git a/src/client/component/ranked.cpp b/src/client/component/ranked.cpp index 027e3d8f..f4776e2d 100644 --- a/src/client/component/ranked.cpp +++ b/src/client/component/ranked.cpp @@ -32,7 +32,7 @@ namespace ranked dvars::override::register_bool("xblive_privatematch", false, game::DVAR_FLAG_REPLICATED | game::DVAR_FLAG_WRITE); // Skip some check in _menus.gsc - dvars::register_bool("force_ranking", true, game::DVAR_FLAG_WRITE); + dvars::register_bool("force_ranking", true, game::DVAR_FLAG_WRITE, ""); } // Always run bots, even if xblive_privatematch is 0 diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp index b315be76..a20f66fe 100644 --- a/src/client/component/renderer.cpp +++ b/src/client/component/renderer.cpp @@ -55,7 +55,7 @@ namespace renderer return; } - dvars::r_fullbright = dvars::register_int("r_fullbright", 0, 0, 3, game::DVAR_FLAG_SAVED); + dvars::r_fullbright = dvars::register_int("r_fullbright", 0, 0, 3, game::DVAR_FLAG_SAVED, "Toggles rendering without lighting"); r_init_draw_method_hook.create(SELECT_VALUE(0x1404BD140, 0x1405C46E0), &r_init_draw_method_stub); r_update_front_end_dvar_options_hook.create(SELECT_VALUE(0x1404F8870, 0x1405FF9E0), &r_update_front_end_dvar_options_stub); diff --git a/src/client/component/shaders.cpp b/src/client/component/shaders.cpp index ec632115..11e2e0d6 100644 --- a/src/client/component/shaders.cpp +++ b/src/client/component/shaders.cpp @@ -35,7 +35,8 @@ namespace shaders const auto has_flag = utils::flags::has_flag("noshadercaching"); - disable_shader_caching = dvars::register_bool("disable_shader_caching", has_flag, game::DVAR_FLAG_SAVED, true); + disable_shader_caching = dvars::register_bool("disable_shader_caching", has_flag, + game::DVAR_FLAG_SAVED, "Disable shader caching"); if (has_flag) { dvars::override::set_bool("disable_shader_caching", 1); diff --git a/src/client/component/stats.cpp b/src/client/component/stats.cpp index 8e238178..81e7c3da 100644 --- a/src/client/component/stats.cpp +++ b/src/client/component/stats.cpp @@ -62,8 +62,10 @@ namespace stats return; } - cg_unlock_all_items = dvars::register_bool("cg_unlockall_items", false, game::DVAR_FLAG_SAVED, true); - dvars::register_bool("cg_unlockall_classes", false, game::DVAR_FLAG_SAVED, true); + cg_unlock_all_items = dvars::register_bool("cg_unlockall_items", false, game::DVAR_FLAG_SAVED, + "Whether items should be locked based on the player's stats or always unlocked."); + dvars::register_bool("cg_unlockall_classes", false, game::DVAR_FLAG_SAVED, + "Whether classes should be locked based on the player's stats or always unlocked."); is_item_unlocked_hook.create(0x140413E60, is_item_unlocked_stub); is_item_unlocked_hook2.create(0x140413860, is_item_unlocked_stub2); diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp index 9a525427..e1210cee 100644 --- a/src/client/component/updater.cpp +++ b/src/client/component/updater.cpp @@ -462,7 +462,8 @@ namespace updater void post_unpack() override { delete_old_file(); - cl_auto_update = dvars::register_bool("cg_auto_update", true, game::DVAR_FLAG_SAVED, true); + cl_auto_update = dvars::register_bool("cg_auto_update", true, game::DVAR_FLAG_SAVED, + "Automatically check for updates"); } }; } diff --git a/src/client/component/virtuallobby.cpp b/src/client/component/virtuallobby.cpp index eb6295f7..a4ebf39d 100644 --- a/src/client/component/virtuallobby.cpp +++ b/src/client/component/virtuallobby.cpp @@ -52,7 +52,8 @@ namespace virtuallobby return; } - virtualLobby_fovscale = dvars::register_float("virtualLobby_fovScale", 0.7f, 0.0f, 2.0f, game::DVAR_FLAG_SAVED); + virtualLobby_fovscale = dvars::register_float("virtualLobby_fovScale", 0.7f, 0.0f, 2.0f, + game::DVAR_FLAG_SAVED, "Field of view scaled for the virtual lobby"); utils::hook::nop(0x1400B555C, 14); utils::hook::jump(0x1400B555C, get_fovscale_stub, true); diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index 8d0c361f..d9f8b2ac 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -4,6 +4,7 @@ #include #include "game.hpp" +#include "dvars.hpp" #include #include @@ -156,2608 +157,2406 @@ namespace dvars } } - std::vector dvar_list = + std::vector dvar_list = { - {"abilities_active"}, - {"accessToSubscriberContent"}, - {"aci"}, - {"actionSlotsHide"}, - {"agent_jumpGravity"}, - {"agent_jumpSpeed"}, - {"agent_jumpWallGravity"}, - {"agent_jumpWallSpeed"}, - {"aim_autoaim_enabled"}, - {"aim_target_sentient_radius"}, - {"aimassist_enabled"}, - {"allow_cod_anywhere"}, - {"allow_online_squads"}, - {"allow_secondscreen"}, - {"allow_secondscreen_ingame_recv"}, - {"allow_secondscreen_ingame_send"}, - {"allowKillStreaks"}, - {"ammoCounterHide"}, - {"badHost_detectMinServerTime"}, - {"badhost_maxDoISuckFrames"}, - {"band_12players"}, - {"band_18players"}, - {"band_2players"}, - {"band_4players"}, - {"band_8players"}, - {"bg_alienBulletExplRadius"}, - {"bg_bulletExplDmgFactor"}, - {"bg_bulletExplRadius"}, - {"bg_compassShowEnemies"}, - {"bg_idleSwingSpeed"}, - {"bg_shieldHitEncodeHeightVM"}, - {"bg_shieldHitEncodeHeightWorld"}, - {"bg_shieldHitEncodeWidthVM"}, - {"bg_shieldHitEncodeWidthWorld"}, - {"bg_shock_lookControl"}, - {"bg_shock_lookControl_fadeTime"}, - {"bg_shock_lookControl_maxpitchspeed"}, - {"bg_shock_lookControl_maxyawspeed"}, - {"bg_shock_lookControl_mousesensitivityscale"}, - {"bg_shock_movement"}, - {"bg_shock_screenBlurBlendFadeTime"}, - {"bg_shock_screenBlurBlendTime"}, - {"bg_shock_screenFlashShotFadeTime"}, - {"bg_shock_screenFlashWhiteFadeTime"}, - {"bg_shock_screenType"}, - {"bg_shock_sound"}, - {"bg_shock_soundDryLevel"}, - {"bg_shock_soundEnd"}, - {"bg_shock_soundEndAbort"}, - {"bg_shock_soundFadeInTime"}, - {"bg_shock_soundFadeOutTime"}, - {"bg_shock_soundLoop"}, - {"bg_shock_soundLoopEndDelay"}, - {"bg_shock_soundLoopFadeTime"}, - {"bg_shock_soundLoopSilent"}, - {"bg_shock_soundModEndDelay"}, - {"bg_shock_soundRoomType"}, - {"bg_shock_soundWetLevel"}, - {"bg_shock_viewKickFadeTime"}, - {"bg_shock_viewKickPeriod"}, - {"bg_shock_viewKickRadius"}, - {"bg_shock_volume_aircraft"}, - {"bg_shock_volume_alarm"}, - {"bg_shock_volume_ambdist1"}, - {"bg_shock_volume_ambdist2"}, - {"bg_shock_volume_ambient"}, - {"bg_shock_volume_announcer"}, - {"bg_shock_volume_auto"}, - {"bg_shock_volume_auto2"}, - {"bg_shock_volume_auto2d"}, - {"bg_shock_volume_autodog"}, - {"bg_shock_volume_body"}, - {"bg_shock_volume_body2d"}, - {"bg_shock_volume_bulletflesh1"}, - {"bg_shock_volume_bulletflesh1npc"}, - {"bg_shock_volume_bulletflesh1npc_npc"}, - {"bg_shock_volume_bulletflesh2"}, - {"bg_shock_volume_bulletflesh2npc"}, - {"bg_shock_volume_bulletflesh2npc_npc"}, - {"bg_shock_volume_bulletimpact"}, - {"bg_shock_volume_bulletwhizbyin"}, - {"bg_shock_volume_bulletwhizbyout"}, - {"bg_shock_volume_effects1"}, - {"bg_shock_volume_effects2"}, - {"bg_shock_volume_effects2d1"}, - {"bg_shock_volume_effects2d2"}, - {"bg_shock_volume_effects2dlim"}, - {"bg_shock_volume_effects3"}, - {"bg_shock_volume_element"}, - {"bg_shock_volume_element2d"}, - {"bg_shock_volume_element_ext"}, - {"bg_shock_volume_element_int"}, - {"bg_shock_volume_element_lim"}, - {"bg_shock_volume_explosion1"}, - {"bg_shock_volume_explosion2"}, - {"bg_shock_volume_explosion3"}, - {"bg_shock_volume_explosion4"}, - {"bg_shock_volume_explosion5"}, - {"bg_shock_volume_explosiondist1"}, - {"bg_shock_volume_explosiondist2"}, - {"bg_shock_volume_explosiveimpact"}, - {"bg_shock_volume_foley_dog_mvmt"}, - {"bg_shock_volume_foley_dog_step"}, - {"bg_shock_volume_foley_npc_mvmt"}, - {"bg_shock_volume_foley_npc_step"}, - {"bg_shock_volume_foley_npc_weap"}, - {"bg_shock_volume_foley_plr_mvmt"}, - {"bg_shock_volume_foley_plr_step"}, - {"bg_shock_volume_foley_plr_step_unres"}, - {"bg_shock_volume_foley_plr_weap"}, - {"bg_shock_volume_hurt"}, - {"bg_shock_volume_item"}, - {"bg_shock_volume_local"}, - {"bg_shock_volume_local2"}, - {"bg_shock_volume_local3"}, - {"bg_shock_volume_menu"}, - {"bg_shock_volume_menulim1"}, - {"bg_shock_volume_menulim2"}, - {"bg_shock_volume_mission"}, - {"bg_shock_volume_missionfx"}, - {"bg_shock_volume_music"}, - {"bg_shock_volume_music_emitter"}, - {"bg_shock_volume_musicnopause"}, - {"bg_shock_volume_nonshock"}, - {"bg_shock_volume_nonshock2"}, - {"bg_shock_volume_norestrict"}, - {"bg_shock_volume_norestrict2d"}, - {"bg_shock_volume_physics"}, - {"bg_shock_volume_player1"}, - {"bg_shock_volume_player2"}, - {"bg_shock_volume_plr_weap_fire_2d"}, - {"bg_shock_volume_plr_weap_mech_2d"}, - {"bg_shock_volume_reload"}, - {"bg_shock_volume_reload2d"}, - {"bg_shock_volume_shellshock"}, - {"bg_shock_volume_vehicle"}, - {"bg_shock_volume_vehicle2d"}, - {"bg_shock_volume_vehiclelimited"}, - {"bg_shock_volume_voice"}, - {"bg_shock_volume_voice_dog"}, - {"bg_shock_volume_voice_dog_attack"}, - {"bg_shock_volume_voice_dog_dist"}, - {"bg_shock_volume_weapon"}, - {"bg_shock_volume_weapon2d"}, - {"bg_shock_volume_weapon_dist"}, - {"bg_shock_volume_weapon_drone"}, - {"bg_shock_volume_weapon_mid"}, - {"bg_swingSpeed"}, - {"bg_torsoSwingSpeed"}, - {"bg_underbarrelWeaponEnabled"}, - {"bot_AutoConnectDefault"}, - {"bot_DifficultyDefault"}, - {"ca_do_mlc"}, - {"ca_intra_only"}, - {"camera_thirdPerson"}, - {"cameraShakeRemoteHelo_Angles"}, - {"cameraShakeRemoteHelo_Freqs"}, - {"cameraShakeRemoteHelo_SpeedRange"}, - {"cameraShakeRemoteMissile_Angles"}, - {"cameraShakeRemoteMissile_Freqs"}, - {"cameraShakeRemoteMissile_SpeedRange"}, - {"cg_airstrikeKillCamFarBlur"}, - {"cg_airstrikeKillCamFarBlurDist"}, - {"cg_airstrikeKillCamFarBlurStart"}, - {"cg_airstrikeKillCamFov"}, - {"cg_airstrikeKillCamNearBlur"}, - {"cg_airstrikeKillCamNearBlurEnd"}, - {"cg_airstrikeKillCamNearBlurStart"}, - {"cg_blood"}, - {"cg_brass"}, - {"cg_centertime"}, - {"cg_chatHeight"}, - {"cg_chatTime"}, - {"cg_ColorBlind_EnemyTeam"}, - {"cg_ColorBlind_MyParty"}, - {"cg_ColorBlind_MyTeam"}, - {"cg_connectionIconSize"}, - {"cg_constantSizeHeadIcons"}, - {"cg_crosshairAlpha"}, - {"cg_crosshairAlphaMin"}, - {"cg_crosshairDynamic"}, - {"cg_crosshairEnemyColor"}, - {"cg_crosshairVerticalOffset"}, - {"cg_cullBulletAngle"}, - {"cg_cullBullets"}, - {"cg_cursorHints"}, - {"cg_deadChatWithDead"}, - {"cg_deadChatWithTeam"}, - {"cg_deadHearAllLiving"}, - {"cg_deadHearTeamLiving"}, - {"cg_descriptiveText"}, - {"cg_draw2D"}, - {"cg_drawBreathHint"}, - {"cg_drawBuildName"}, - {"cg_drawCrosshair"}, - {"cg_drawCrosshairNames"}, - {"cg_drawCrosshairNamesPosX"}, - {"cg_drawCrosshairNamesPosY"}, - {"cg_drawDamageDirection"}, - {"cg_drawDamageFlash"}, - {"cg_drawEffectNum"}, - {"cg_drawFPS"}, - {"cg_drawFPSLabels"}, - {"cg_drawFriendlyHUDGrenades"}, - {"cg_drawFriendlyNames"}, - {"cg_drawFriendlyNamesAlways"}, - {"cg_drawGun"}, - {"cg_drawHealth"}, - {"cg_drawMantleHint"}, - {"cg_drawMaterial"}, - {"cg_drawpaused"}, - {"cg_drawPing"}, - {"cg_drawScriptUsage"}, - {"cg_drawSnapshot"}, - {"cg_drawSpectatorMessages"}, - {"cg_drawStatsSource"}, - {"cg_drawTalk"}, - {"cg_drawTechset"}, - {"cg_drawTurretCrosshair"}, - {"cg_drawViewpos"}, - {"cg_equipmentSounds"}, - {"cg_errordecay"}, - {"cg_everyoneHearsEveryone"}, - {"cg_explosiveKillCamBackDist"}, - {"cg_explosiveKillCamGroundBackDist"}, - {"cg_explosiveKillCamGroundUpDist"}, - {"cg_explosiveKillCamStopDecelDist"}, - {"cg_explosiveKillCamStopDist"}, - {"cg_explosiveKillCamUpDist"}, - {"cg_explosiveKillCamWallOutDist"}, - {"cg_explosiveKillCamWallSideDist"}, - {"cg_flashbangNameFadeIn"}, - {"cg_flashbangNameFadeOut"}, - {"cg_foliagesnd_alias"}, - {"cg_footsteps"}, - {"cg_footstepsSprint"}, - {"cg_fov"}, - {"cg_fovMin"}, - {"cg_fovScale"}, - {"cg_friendlyNameFadeIn"}, - {"cg_friendlyNameFadeOut"}, - {"cg_gameBoldMessageWidth"}, - {"cg_gameMessageWidth"}, - {"cg_gun_x"}, - {"cg_gun_y"}, - {"cg_gun_z"}, - {"cg_headIconMinScreenRadius"}, - {"cg_hearKillerTime"}, - {"cg_hearVictimEnabled"}, - {"cg_hearVictimTime"}, - {"cg_heliKillCamFarBlur"}, - {"cg_heliKillCamFarBlurDist"}, - {"cg_heliKillCamFarBlurStart"}, - {"cg_heliKillCamFov"}, - {"cg_heliKillCamNearBlur"}, - {"cg_heliKillCamNearBlurEnd"}, - {"cg_heliKillCamNearBlurStart"}, - {"cg_hintFadeTime"}, - {"cg_hudChatIntermissionPosition"}, - {"cg_hudChatPosition"}, - {"cg_hudDamageIconHeight"}, - {"cg_hudDamageIconInScope"}, - {"cg_hudDamageIconOffset"}, - {"cg_hudDamageIconTime"}, - {"cg_hudDamageIconWidth"}, - {"cg_hudGrenadeIconEnabledFlash"}, - {"cg_hudGrenadeIconHeight"}, - {"cg_hudGrenadeIconInScope"}, - {"cg_hudGrenadeIconMaxHeight"}, - {"cg_hudGrenadeIconMaxRangeFlash"}, - {"cg_hudGrenadeIconMaxRangeFrag"}, - {"cg_hudGrenadeIconOffset"}, - {"cg_hudGrenadeIconWidth"}, - {"cg_hudGrenadePointerHeight"}, - {"cg_hudGrenadePointerPivot"}, - {"cg_hudGrenadePointerPulseFreq"}, - {"cg_hudGrenadePointerPulseMax"}, - {"cg_hudGrenadePointerPulseMin"}, - {"cg_hudGrenadePointerWidth"}, - {"cg_hudlegacysplitscreenscale"}, - {"cg_hudLighting_basic_additiveLumOffset"}, - {"cg_hudLighting_basic_additiveLumScale"}, - {"cg_hudLighting_basic_additiveOffset"}, - {"cg_hudLighting_basic_additiveScale"}, - {"cg_hudLighting_basic_ambientLumOffset"}, - {"cg_hudLighting_basic_ambientLumScale"}, - {"cg_hudLighting_basic_ambientOffset"}, - {"cg_hudLighting_basic_ambientScale"}, - {"cg_hudLighting_basic_diffuseLumOffset"}, - {"cg_hudLighting_basic_diffuseLumScale"}, - {"cg_hudLighting_basic_diffuseOffset"}, - {"cg_hudLighting_basic_diffuseScale"}, - {"cg_hudLighting_basic_specExponent"}, - {"cg_hudLighting_basic_specLumOffset"}, - {"cg_hudLighting_basic_specLumScale"}, - {"cg_hudLighting_basic_specOffset"}, - {"cg_hudLighting_basic_specScale"}, - {"cg_hudLighting_blood_additiveLumOffset"}, - {"cg_hudLighting_blood_additiveLumScale"}, - {"cg_hudLighting_blood_additiveOffset"}, - {"cg_hudLighting_blood_additiveScale"}, - {"cg_hudLighting_blood_ambientLumOffset"}, - {"cg_hudLighting_blood_ambientLumScale"}, - {"cg_hudLighting_blood_ambientOffset"}, - {"cg_hudLighting_blood_ambientScale"}, - {"cg_hudLighting_blood_diffuseLumOffset"}, - {"cg_hudLighting_blood_diffuseLumScale"}, - {"cg_hudLighting_blood_diffuseOffset"}, - {"cg_hudLighting_blood_diffuseScale"}, - {"cg_hudLighting_blood_specExponent"}, - {"cg_hudLighting_blood_specLumOffset"}, - {"cg_hudLighting_blood_specLumScale"}, - {"cg_hudLighting_blood_specOffset"}, - {"cg_hudLighting_blood_specScale"}, - {"cg_hudLighting_fadeSharpness"}, - {"cg_hudMapBorderWidth"}, - {"cg_hudMapFriendlyHeight"}, - {"cg_hudMapFriendlyWidth"}, - {"cg_hudMapPlayerHeight"}, - {"cg_hudMapPlayerWidth"}, - {"cg_hudMapRadarLineThickness"}, - {"cg_hudObjectiveTextScale"}, - {"cg_hudProneY"}, - {"cg_hudSayPosition"}, - {"cg_hudSplitscreenCompassElementScale"}, - {"cg_hudsplitscreencompassscale"}, - {"cg_hudsplitscreenstancescale"}, - {"cg_hudStanceFlash"}, - {"cg_hudVotePosition"}, - {"cg_invalidCmdHintBlinkInterval"}, - {"cg_invalidCmdHintDuration"}, - {"cg_javelinKillCamCloseZDist"}, - {"cg_javelinKillCamDownDist"}, - {"cg_javelinKillCamFov"}, - {"cg_javelinKillCamLookLerpDist"}, - {"cg_javelinKillCamPassDist"}, - {"cg_javelinKillCamPassTime"}, - {"cg_javelinKillCamUpDist"}, - {"cg_killCamDefaultLerpTime"}, - {"cg_killCamTurretLerpTime"}, - {"cg_landingSounds"}, - {"cg_legacyCrashHandling"}, - {"cg_mapLocationSelectionCursorSpeed"}, - {"cg_marks_ents_player_only"}, - {"cg_minCullBulletDist"}, - {"cg_objectiveText"}, - {"cg_overheadIconSize"}, - {"cg_overheadNamesFarDist"}, - {"cg_overheadNamesFarScale"}, - {"cg_overheadNamesFont"}, - {"cg_overheadNamesGlow"}, - {"cg_overheadNamesMaxDist"}, - {"cg_overheadNamesNearDist"}, - {"cg_overheadNamesSize"}, - {"cg_overheadRankSize"}, - {"cg_remoteMissileKillCamBackDist"}, - {"cg_remoteMissileKillCamUpDist"}, - {"cg_rocketKillCamBackDist"}, - {"cg_rocketKillCamUpDist"}, - {"cg_scoreboardBannerHeight"}, - {"cg_scoreboardFont"}, - {"cg_scoreboardHeaderFontScale"}, - {"cg_scoreboardHeight"}, - {"cg_scoreboardItemHeight"}, - {"cg_scoreboardMyColor"}, - {"cg_scoreboardMyPartyColor"}, - {"cg_scoreboardPingGraph"}, - {"cg_scoreboardPingHeight"}, - {"cg_scoreboardPingText"}, - {"cg_scoreboardPingWidth"}, - {"cg_scoreboardRankFontScale"}, - {"cg_scoreboardScrollStep"}, - {"cg_scoreboardTextOffset"}, - {"cg_scoreboardWidth"}, - {"cg_ScoresPing_BgColor"}, - {"cg_ScoresPing_HighColor"}, - {"cg_ScoresPing_LowColor"}, - {"cg_ScoresPing_MedColor"}, - {"cg_scriptIconSize"}, - {"cg_showmiss"}, - {"cg_sprintMeterDisabledColor"}, - {"cg_sprintMeterEmptyColor"}, - {"cg_sprintMeterFullColor"}, - {"cg_subtitleMinTime"}, - {"cg_subtitleWidthStandard"}, - {"cg_subtitleWidthWidescreen"}, - {"cg_teamChatsOnly"}, - {"cg_TeamColor_Allies"}, - {"cg_TeamColor_Axis"}, - {"cg_TeamColor_EnemyTeam"}, - {"cg_TeamColor_Free"}, - {"cg_TeamColor_MyParty"}, - {"cg_TeamColor_MyTeam"}, - {"cg_TeamColor_Spectator"}, - {"cg_turretKillCamBackDist"}, - {"cg_turretKillCamFov"}, - {"cg_turretKillCamUpDist"}, - {"cg_turretRemoteKillCamBackDist"}, - {"cg_turretRemoteKillCamFov"}, - {"cg_turretRemoteKillCamUpDist"}, - {"cg_vectorFieldsForceUniform"}, - {"cg_viewVehicleInfluence"}, - {"cg_viewZSmoothingMax"}, - {"cg_viewZSmoothingMin"}, - {"cg_viewZSmoothingTime"}, - {"cg_voiceIconSize"}, - {"cg_waterSheeting_distortionScaleFactor"}, - {"cg_waterSheeting_magnitude"}, - {"cg_waterSheeting_radius"}, - {"cg_weapHitCullAngle"}, - {"cg_weapHitCullEnable"}, - {"cg_weaponCycleDelay"}, - {"cg_weaponHintsCoD1Style"}, - {"cg_weaponVisInterval"}, - {"cg_youInKillCamSize"}, - {"cl_anglespeedkey"}, - {"cl_bypassMouseInput"}, - {"cl_connectionAttempts"}, - {"cl_connectTimeout"}, - {"cl_demo_uploadfb"}, - {"cl_dirSelConvergenceTime"}, - {"cl_freelook"}, - {"cl_hudDrawsBehindUI"}, - {"cl_ingame"}, - {"cl_inhibit_stats_upload"}, - {"cl_lessprint"}, - {"cl_loadApexDLL"}, - {"cl_loadHairDLL"}, - {"cl_loadHBAODLL"}, - {"cl_loadNVMRDLL"}, - {"cl_loadNVPSMDLL"}, - {"cl_loadTXAADLL"}, - {"cl_maxpackets"}, - {"cl_maxPing"}, - {"cl_migrationTimeout"}, - {"cl_modifiedDebugPlacement"}, - {"cl_motdString"}, - {"cl_mouseAccel"}, - {"cl_noprint"}, - {"cl_packetdup"}, - {"cl_paused"}, - {"cl_pitchspeed"}, - {"cl_pushToTalk"}, - {"cl_serverStatusResendTime"}, - {"cl_showmouserate"}, - {"cl_textChatEnabled"}, - {"cl_timeout"}, - {"cl_voice"}, - {"cl_yawspeed"}, - {"clientSideEffects"}, - {"cod_anywhere_errorMessage"}, - {"cod_anywhere_showPopup"}, - {"cod_anywhere_single_task_popup_text"}, - {"com_animCheck"}, - {"com_cinematicEndInWhite"}, - {"com_completionResolveCommand"}, - {"com_errorMessage"}, - {"com_errorResolveCommand"}, - {"com_filter_output"}, - {"com_maxfps"}, - {"com_maxFrameTime"}, - {"com_playerProfile"}, - {"com_recommendedSet"}, - {"commerce_dl_retry_step"}, - {"commerce_manifest_file_max_retry_time"}, - {"commerce_manifest_file_retry_step"}, - {"commerce_max_dl_retry_time"}, - {"commerce_max_retry_time"}, - {"commerce_retry_step"}, - {"compass"}, - {"compassClampIcons"}, - {"compassCoords"}, - {"compassECoordCutoff"}, - {"compassFriendlyHeight"}, - {"compassFriendlyWidth"}, - {"compassHideSansObjectivePointer"}, - {"compassHideVehicles"}, - {"compassMaxRange"}, - {"compassMinRadius"}, - {"compassMinRange"}, - {"compassObjectiveArrowHeight"}, - {"compassObjectiveArrowOffset"}, - {"compassObjectiveArrowRotateDist"}, - {"compassObjectiveArrowWidth"}, - {"compassObjectiveDetailDist"}, - {"compassObjectiveDrawLines"}, - {"compassObjectiveHeight"}, - {"compassObjectiveIconHeight"}, - {"compassObjectiveIconWidth"}, - {"compassObjectiveMaxHeight"}, - {"compassObjectiveMaxRange"}, - {"compassObjectiveMinAlpha"}, - {"compassObjectiveMinDistRange"}, - {"compassObjectiveMinHeight"}, - {"compassObjectiveNearbyDist"}, - {"compassObjectiveNumRings"}, - {"compassObjectiveRingSize"}, - {"compassObjectiveRingTime"}, - {"compassObjectiveTextHeight"}, - {"compassObjectiveTextScale"}, - {"compassObjectiveWidth"}, - {"compassPlayerHeight"}, - {"compassPlayerWidth"}, - {"compassPrototypeElevation"}, - {"compassPrototypeFiring"}, - {"compassRadarLineThickness"}, - {"compassRadarPingFadeTime"}, - {"compassRotation"}, - {"compassSize"}, - {"compassSoundPingFadeTime"}, - {"compassTickertapeStretch"}, - {"con_gameMsgWindow0FadeInTime"}, - {"con_gameMsgWindow0FadeOutTime"}, - {"con_gameMsgWindow0Filter"}, - {"con_gameMsgWindow0LineCount"}, - {"con_gameMsgWindow0MsgTime"}, - {"con_gameMsgWindow0ScrollTime"}, - {"con_gameMsgWindow0SplitscreenScale"}, - {"con_gameMsgWindow1FadeInTime"}, - {"con_gameMsgWindow1FadeOutTime"}, - {"con_gameMsgWindow1Filter"}, - {"con_gameMsgWindow1LineCount"}, - {"con_gameMsgWindow1MsgTime"}, - {"con_gameMsgWindow1ScrollTime"}, - {"con_gameMsgWindow1SplitscreenScale"}, - {"con_gameMsgWindow2FadeInTime"}, - {"con_gameMsgWindow2FadeOutTime"}, - {"con_gameMsgWindow2Filter"}, - {"con_gameMsgWindow2LineCount"}, - {"con_gameMsgWindow2MsgTime"}, - {"con_gameMsgWindow2ScrollTime"}, - {"con_gameMsgWindow2SplitscreenScale"}, - {"con_gameMsgWindow3FadeInTime"}, - {"con_gameMsgWindow3FadeOutTime"}, - {"con_gameMsgWindow3Filter"}, - {"con_gameMsgWindow3LineCount"}, - {"con_gameMsgWindow3MsgTime"}, - {"con_gameMsgWindow3ScrollTime"}, - {"con_gameMsgWindow3SplitscreenScale"}, - {"con_inputBoxColor"}, - {"con_inputCmdMatchColor"}, - {"con_inputDvarInactiveValueColor"}, - {"con_inputDvarMatchColor"}, - {"con_inputDvarValueColor"}, - {"con_inputHintBoxColor"}, - {"con_outputBarColor"}, - {"con_outputSliderColor"}, - {"con_outputWindowColor"}, - {"con_typewriterColorBase"}, - {"con_typewriterColorGlowCheckpoint"}, - {"con_typewriterColorGlowCompleted"}, - {"con_typewriterColorGlowFailed"}, - {"con_typewriterColorGlowUpdated"}, - {"con_typewriterDecayDuration"}, - {"con_typewriterDecayStartTime"}, - {"con_typewriterPrintSpeed"}, - {"counterDownloadInterval"}, - {"counterUploadInterval"}, - {"cpu_speed_12players"}, - {"cpu_speed_18players"}, - {"cpu_speed_8players"}, - {"cSplineDebugRender"}, - {"cSplineDebugRenderCorridor"}, - {"cSplineDebugRenderData"}, - {"cSplineDebugRenderSplineId"}, - {"dc_lobbymerge"}, - {"dedicated_dhclient"}, - {"demonwareConsideredConnectedTime"}, - {"developer"}, - {"didyouknow"}, - {"discard_playerstats_on_suspend"}, - {"drawEntityCount"}, - {"drawEntityCountPos"}, - {"drawEntityCountSize"}, - {"drawKillcamData"}, - {"drawKillcamDataPos"}, - {"drawKillcamDataSize"}, - {"drawServerBandwidth"}, - {"drawServerBandwidthPos"}, - {"ds_dcid"}, - {"ds_dcid_override"}, - {"ds_info"}, - {"ds_info_enable"}, - {"ds_introRequestTimeout"}, - {"ds_keepaliveInterval"}, - {"ds_keepaliveTimeout"}, - {"ds_parklist"}, - {"ds_pingclient_maxpings"}, - {"ds_pingclient_maxpings_per_tick"}, - {"ds_pingclient_minpings"}, - {"ds_pingclient_nowaitonline"}, - {"ds_pingclient_odsf"}, - {"ds_pingclient_resend_ms"}, - {"ds_reacquireAfterDisconnect"}, - {"ds_serverAcquireTimeout"}, - {"ds_serverAcquisitionPeriod"}, - {"ds_serverConnectTimeout"}, - {"ds_serverListExpiryPeriod"}, - {"dsping_dc_0"}, - {"dsping_dc_1"}, - {"dsping_dc_10"}, - {"dsping_dc_11"}, - {"dsping_dc_12"}, - {"dsping_dc_13"}, - {"dsping_dc_14"}, - {"dsping_dc_15"}, - {"dsping_dc_16"}, - {"dsping_dc_17"}, - {"dsping_dc_18"}, - {"dsping_dc_19"}, - {"dsping_dc_2"}, - {"dsping_dc_20"}, - {"dsping_dc_21"}, - {"dsping_dc_22"}, - {"dsping_dc_23"}, - {"dsping_dc_24"}, - {"dsping_dc_25"}, - {"dsping_dc_26"}, - {"dsping_dc_27"}, - {"dsping_dc_28"}, - {"dsping_dc_29"}, - {"dsping_dc_3"}, - {"dsping_dc_30"}, - {"dsping_dc_31"}, - {"dsping_dc_32"}, - {"dsping_dc_33"}, - {"dsping_dc_34"}, - {"dsping_dc_35"}, - {"dsping_dc_36"}, - {"dsping_dc_37"}, - {"dsping_dc_38"}, - {"dsping_dc_39"}, - {"dsping_dc_4"}, - {"dsping_dc_40"}, - {"dsping_dc_41"}, - {"dsping_dc_42"}, - {"dsping_dc_43"}, - {"dsping_dc_44"}, - {"dsping_dc_45"}, - {"dsping_dc_46"}, - {"dsping_dc_47"}, - {"dsping_dc_48"}, - {"dsping_dc_49"}, - {"dsping_dc_5"}, - {"dsping_dc_50"}, - {"dsping_dc_51"}, - {"dsping_dc_52"}, - {"dsping_dc_53"}, - {"dsping_dc_54"}, - {"dsping_dc_55"}, - {"dsping_dc_56"}, - {"dsping_dc_57"}, - {"dsping_dc_58"}, - {"dsping_dc_59"}, - {"dsping_dc_6"}, - {"dsping_dc_60"}, - {"dsping_dc_61"}, - {"dsping_dc_62"}, - {"dsping_dc_63"}, - {"dsping_dc_7"}, - {"dsping_dc_8"}, - {"dsping_dc_9"}, - {"dvl"}, - {"dw_addrHandleTimeout"}, - {"dw_ignore_hack"}, - {"dw_leaderboard_write_active"}, - {"dw_matchmaking_fall_off"}, - {"dw_presence_active"}, - {"dw_presence_coop_join_active"}, - {"dw_presence_get_delay"}, - {"dw_presence_get_rate"}, - {"dw_presence_put_delay"}, - {"dw_presence_put_rate"}, - {"dw_region_lookup_timeout"}, - {"dw_shared_presence_active"}, - {"dw_shared_presence_get_delay"}, - {"dw_shared_presence_get_rate"}, - {"dw_shared_presence_put_delay"}, - {"dw_shared_presence_put_rate"}, - {"dynEnt_active"}, - {"elite_clan_active"}, - {"elite_clan_cool_off_time"}, - {"elite_clan_delay"}, - {"elite_clan_division_icon_active"}, - {"elite_clan_get_clan_max_retry_time"}, - {"elite_clan_get_clan_retry_step"}, - {"elite_clan_get_members_max_retry_time"}, - {"elite_clan_get_members_retry_step"}, - {"elite_clan_get_private_member_profile_max_retry_time"}, - {"elite_clan_get_private_member_profile_retry_step"}, - {"elite_clan_get_private_profile_max_retry_time"}, - {"elite_clan_get_private_profile_retry_step"}, - {"elite_clan_get_public_profile_max_retry_time"}, - {"elite_clan_get_public_profile_retry_step"}, - {"elite_clan_get_team_stats_max_retry_time"}, - {"elite_clan_get_team_stats_retry_step"}, - {"elite_clan_motd_throttle_time"}, - {"elite_clan_remote_view_active"}, - {"elite_clan_remote_view_max_retry_time"}, - {"elite_clan_remote_view_retry_step"}, - {"elite_clan_send_message_to_members_max_retry_time"}, - {"elite_clan_send_message_to_members_retry_step"}, - {"elite_clan_set_private_member_profile_max_retry_time"}, - {"elite_clan_set_private_member_profile_retry_step"}, - {"elite_clan_single_task_popup_text"}, - {"elite_clan_using_title"}, - {"elite_edl"}, - {"elite_edl_xl"}, - {"enable_eliteCACDownload"}, - {"enable_eliteCACDownloadInGameLobby"}, - {"enable_recordRecentActivity"}, - {"enableAntilagReporting"}, - {"enableReportingRegisteredParties"}, - {"enableServerReporting"}, - {"entitlements_active"}, - {"entitlements_config_file_max_retry_time"}, - {"entitlements_config_file_retry_step"}, - {"entitlements_cool_off_time"}, - {"entitlements_delay"}, - {"entitlements_key_archive_max_retry_time"}, - {"entitlements_key_archive_retry_step"}, - {"entitlementSystemOk"}, - {"extendedLoadoutsEnable"}, - {"extinction_cac_enabled"}, - {"extinction_hardcore_enabled"}, - {"extinction_intel_enabled"}, - {"extinction_map_selection_enabled"}, - {"extinction_tokens_enabled"}, - {"extinctionBonus_period"}, - {"facebook_active"}, - {"facebook_delay"}, - {"facebook_friends_active"}, - {"facebook_friends_max_retry_time"}, - {"facebook_friends_refresh_time"}, - {"facebook_friends_retry_step"}, - {"facebook_friends_showing_count"}, - {"facebook_friends_throttle_time"}, - {"facebook_max_retry_time"}, - {"facebook_password"}, - {"facebook_password_asterisk"}, - {"facebook_popup_text"}, - {"facebook_retry_step"}, - {"facebook_upload_photo_active"}, - {"facebook_upload_video_active"}, - {"facebook_username"}, - {"fixedtime"}, - {"FoFIconMaxSize"}, - {"FoFIconMinSize"}, - {"FoFIconScale"}, - {"FoFIconSpawnTimeDelay"}, - {"FoFIconSpawnTimeFade"}, - {"friendsCacheSteamFriends"}, - {"friendsMaxSteamLookupsPerFrame"}, - {"friendsWidgetMinimumRefreshTimer"}, - {"fs_basegame"}, - {"fs_basepath"}, - {"fs_basepath_output"}, - {"fs_cdpath"}, - {"fs_copyfiles"}, - {"fs_debug"}, - {"fs_game"}, - {"fs_homepath"}, - {"fs_ignoreLocalized"}, - {"fx_alphaThreshold"}, - {"fx_count"}, - {"fx_cull_elem_draw"}, - {"fx_cull_elem_spawn"}, - {"fx_debugBolt"}, - {"fx_deferelem"}, - {"fx_draw"}, - {"fx_draw_omniLight"}, - {"fx_draw_simd"}, - {"fx_draw_spotLight"}, - {"fx_drawClouds"}, - {"fx_enable"}, - {"fx_freeze"}, - {"fx_killEffectOnRewind"}, - {"fx_mark_profile"}, - {"fx_marks"}, - {"fx_marks_ents"}, - {"fx_marks_nearlimit"}, - {"fx_marks_smodels"}, - {"fx_maxNumApexFx"}, - {"fx_profile"}, - {"fx_profileFilter"}, - {"fx_profileFilterElemCountZero"}, - {"fx_profileSkip"}, - {"fx_profileSort"}, - {"fx_visMinTraceDist"}, - {"g_allowvote"}, - {"g_banIPs"}, - {"g_clonePlayerMaxVelocity"}, - {"g_deadChat"}, - {"g_dropForwardSpeed"}, - {"g_dropHorzSpeedRand"}, - {"g_dropUpSpeedBase"}, - {"g_dropUpSpeedRand"}, - {"g_earthquakeEnable"}, - {"g_enableElevators"}, - {"g_fogColorIntensityReadOnly"}, - {"g_fogColorReadOnly"}, - {"g_fogHalfDistReadOnly"}, - {"g_fogMaxOpacityReadOnly"}, - {"g_fogStartDistReadOnly"}, - {"g_friendlyfireDist"}, - {"g_friendlyNameDist"}, - {"g_gametype"}, - {"g_giveAll"}, - {"g_gravity"}, - {"g_hardcore"}, - {"g_inactivity"}, - {"g_keyboarduseholdtime"}, - {"g_knockback"}, - {"g_listEntity"}, - {"g_mantleBlockTimeBuffer"}, - {"g_maxDroppedWeapons"}, - {"g_minGrenadeDamageSpeed"}, - {"g_password"}, - {"g_playerCollision"}, - {"g_playerCollisionEjectSpeed"}, - {"g_playerEjection"}, - {"g_ScoresColor_Allies"}, - {"g_ScoresColor_Axis"}, - {"g_ScoresColor_EnemyTeam"}, - {"g_ScoresColor_Free"}, - {"g_ScoresColor_MyParty"}, - {"g_ScoresColor_MyTeam"}, - {"g_ScoresColor_Spectator"}, - {"g_scriptMainMenu"}, - {"g_speed"}, - {"g_sunFogBeginFadeAngleReadOnly"}, - {"g_sunFogColorIntensityReadOnly"}, - {"g_sunFogColorReadOnly"}, - {"g_sunFogDirReadOnly"}, - {"g_sunFogEnabledReadOnly"}, - {"g_sunFogEndFadeAngleReadOnly"}, - {"g_sunFogScaleReadOnly"}, - {"g_TeamIcon_Allies"}, - {"g_TeamIcon_Axis"}, - {"g_TeamIcon_EnemyAllies"}, - {"g_TeamIcon_EnemyAxis"}, - {"g_TeamIcon_Free"}, - {"g_TeamIcon_MyAllies"}, - {"g_TeamIcon_MyAxis"}, - {"g_TeamIcon_Spectator"}, - {"g_TeamName_Allies"}, - {"g_TeamName_Axis"}, - {"g_TeamTitleColor_EnemyTeam"}, - {"g_TeamTitleColor_MyTeam"}, - {"g_TeamTitleColor_Spectator"}, - {"g_useholdspawndelay"}, - {"g_useholdtime"}, - {"g_voiceChatTalkingDuration"}, - {"gamedate"}, - {"gamedvr_active"}, - {"gameMode"}, - {"gamename"}, - {"glass_angular_vel"}, - {"glass_break"}, - {"glass_crack_pattern_scale"}, - {"glass_damageToDestroy"}, - {"glass_damageToWeaken"}, - {"glass_edge_angle"}, - {"glass_fall_delay"}, - {"glass_fall_gravity"}, - {"glass_fall_ratio"}, - {"glass_fringe_maxcoverage"}, - {"glass_fringe_maxsize"}, - {"glass_fx_chance"}, - {"glass_hinge_friction"}, - {"glass_linear_vel"}, - {"glass_max_pieces_per_frame"}, - {"glass_max_shatter_fx_per_frame"}, - {"glass_meleeDamage"}, - {"glass_physics_chance"}, - {"glass_physics_maxdist"}, - {"glass_radiusDamageMultiplier"}, - {"glass_shard_maxsize"}, - {"glass_shattered_scale"}, - {"glass_trace_interval"}, - {"gpad_button_deadzone"}, - {"gpad_dpadDebounceTime"}, - {"gpad_menu_scroll_delay_first"}, - {"gpad_menu_scroll_delay_rest_accel"}, - {"gpad_menu_scroll_delay_rest_end"}, - {"gpad_menu_scroll_delay_rest_start"}, - {"gpad_stick_deadzone_max"}, - {"gpad_stick_deadzone_min"}, - {"gpad_stick_pressed"}, - {"gpad_stick_pressed_hysteresis"}, - {"groupDownloadInterval"}, - {"groupUploadInterval"}, - {"heli_barrelMaxVelocity"}, - {"heli_barrelRotation"}, - {"heli_barrelSlowdown"}, - {"hiDef"}, - {"hud_bloodOverlayLerpRate"}, - {"hud_deathQuoteFadeTime"}, - {"hud_drawHud"}, - {"hud_enable"}, - {"hud_fade_ammodisplay"}, - {"hud_fade_compass"}, - {"hud_fade_healthbar"}, - {"hud_fade_offhand"}, - {"hud_fade_sprint"}, - {"hud_flash_period_offhand"}, - {"hud_flash_time_offhand"}, - {"hud_health_pulserate_critical"}, - {"hud_health_pulserate_injured"}, - {"hud_health_startpulse_critical"}, - {"hud_health_startpulse_injured"}, - {"hudElemPausedBrightness"}, - {"igs_announcer"}, - {"igs_crossgame"}, - {"igs_fo"}, - {"igs_s1"}, - {"igs_shp"}, - {"igs_smappacks"}, - {"igs_sosp"}, - {"igs_sripper"}, - {"igs_sve"}, - {"igs_svp"}, - {"igs_svr"}, - {"igs_svs"}, - {"igs_swap"}, - {"igs_swp"}, - {"igs_td"}, - {"in_mouse"}, - {"intro"}, - {"iotd_active"}, - {"iotd_retry"}, - {"isMatchMakingGame"}, - {"jump_enableFallDamage"}, - {"jump_height"}, - {"jump_ladderPushVel"}, - {"jump_slowDownEnable"}, - {"jump_stepSize"}, - {"laserDebug"}, - {"laserEndOffset"}, - {"laserFlarePct"}, - {"laserFlarePct_alt"}, - {"laserLight"}, - {"laserLightBeginOffset"}, - {"laserLightBodyTweak"}, - {"laserLightEndOffset"}, - {"laserLightRadius"}, - {"laserLightRadius_alt"}, - {"laserLightWithoutNightvision"}, - {"laserRadius"}, - {"laserRadius_alt"}, - {"laserRange"}, - {"laserRange_alt"}, - {"laserRangePlayer"}, - {"lb_filter"}, - {"lb_maxrows"}, - {"lb_minrefresh"}, - {"lb_readDelay"}, - {"lb_throttle_time"}, - {"lb_times_in_window"}, - {"lb_window"}, - {"live_displayLogOnErrorReason"}, - {"live_qosec_firstupdatems"}, - {"live_qosec_lastupdatems"}, - {"live_qosec_maxtime"}, - {"live_qosec_minpercent"}, - {"live_qosec_minprobes"}, - {"livestreaming_active"}, - {"loading_sre_fatal"}, - {"lobby_animationSpeed"}, - {"lobby_animationTilesHigh"}, - {"lobby_animationTilesWide"}, - {"lobby_numAnimationFrames"}, - {"lobby_searchingPartyColor"}, - {"loc_language"}, - {"loc_translate"}, - {"log_host_migration_chance"}, - {"log_mapvote_chance"}, - {"log_party_state"}, - {"log_teambalance_chance"}, - {"logger_dev"}, - {"lowAmmoWarningColor1"}, - {"lowAmmoWarningColor2"}, - {"lowAmmoWarningNoAmmoColor1"}, - {"lowAmmoWarningNoAmmoColor2"}, - {"lowAmmoWarningNoReloadColor1"}, - {"lowAmmoWarningNoReloadColor2"}, - {"lowAmmoWarningPulseFreq"}, - {"lowAmmoWarningPulseMax"}, - {"lowAmmoWarningPulseMin"}, - {"lsp_enumertion_max_retry_time"}, - {"lsp_enumertion_retry_step"}, - {"lui_FFotDSupportEnabled"}, - {"LUI_MemErrorsFatal"}, - {"lui_menuFlowEnabled"}, - {"lui_splitscreensignin_menu"}, - {"lui_splitscreenupscaling"}, - {"lui_systemlink_menu"}, - {"LUI_WorkerCmdGC"}, - {"lui_xboxlive_menu"}, - {"m_filter"}, - {"m_forward"}, - {"m_pitch"}, - {"m_side"}, - {"m_yaw"}, - {"mapname"}, - {"mapPackMPGroupFourFlags"}, - {"mapPackMPGroupFreeFlags"}, - {"mapPackMPGroupOneFlags"}, - {"mapPackMPGroupThreeFlags"}, - {"mapPackMPGroupTwoFlags"}, - {"mapvote_logging"}, - {"match_making_telemetry_chance"}, - {"matchdata_active"}, - {"matchdata_maxcompressionbuffer"}, - {"matchmaking_debug"}, - {"max_xp_per_match"}, - {"maxVoicePacketsPerSec"}, - {"maxVoicePacketsPerSecForServer"}, - {"mdsd"}, - {"melee_debug"}, - {"migration_dvarErrors"}, - {"min_wait_for_players"}, - {"missileRemoteFOV"}, - {"missileRemoteSteerPitchRange"}, - {"missileRemoteSteerPitchRate"}, - {"missileRemoteSteerYawRate"}, - {"mm_country_code"}, - {"mm_skill_calculation_type"}, - {"mm_skill_enforcement"}, - {"mm_skill_lower_bucket"}, - {"mm_skill_strict_enforcement"}, - {"mm_skill_type"}, - {"mm_skill_upper_bucket"}, - {"mm_sph_1"}, - {"mm_sph_10"}, - {"mm_sph_11"}, - {"mm_sph_12"}, - {"mm_sph_13"}, - {"mm_sph_14"}, - {"mm_sph_15"}, - {"mm_sph_16"}, - {"mm_sph_17"}, - {"mm_sph_18"}, - {"mm_sph_2"}, - {"mm_sph_3"}, - {"mm_sph_4"}, - {"mm_sph_5"}, - {"mm_sph_6"}, - {"mm_sph_7"}, - {"mm_sph_8"}, - {"mm_sph_9"}, - {"mm_split_population"}, - {"mm_test_type"}, - {"monkeytoy"}, - {"motd"}, - {"motd_store_link"}, - {"motionTrackerBlurDuration"}, - {"motionTrackerCenterX"}, - {"motionTrackerCenterY"}, - {"motionTrackerPingFadeTime"}, - {"motionTrackerPingPitchAddPerEnemy"}, - {"motionTrackerPingPitchBase"}, - {"motionTrackerPingPitchNearby"}, - {"motionTrackerPingSize"}, - {"name"}, - {"net_authPort"}, - {"net_ip"}, - {"net_masterServerPort"}, - {"net_noudp"}, - {"net_port"}, - {"net_socksEnabled"}, - {"net_socksPassword"}, - {"net_socksPort"}, - {"net_socksServer"}, - {"net_socksUsername"}, - {"netinfo_logging"}, - {"nextmap"}, - {"nightVisionDisableEffects"}, - {"nightVisionFadeInOutTime"}, - {"nightVisionPowerOnTime"}, - {"num_available_map_packs"}, - {"objectiveFontSize"}, - {"objectiveTextOffsetY"}, - {"onlinegame"}, - {"overrideNVGModelWithKnife"}, - {"overtimeTimeLimit"}, - {"p2pAuth_allow_kick"}, - {"p2pAuth_allow_steam_p2p"}, - {"p2pAuth_disable"}, - {"painVisionLerpOutRate"}, - {"painVisionTriggerHealth"}, - {"party_aliensUseDedicatedServer"}, - {"party_alternateMapVoteStatus"}, - {"party_dlc_only_intended_mappacks"}, - {"party_firstSubpartyIndex"}, - {"party_followPartyHostOutOfGames"}, - {"party_gamesize"}, - {"party_gametype"}, - {"party_inactiveHeartbeatPeriod"}, - {"party_initial_dlc_search_timer"}, - {"party_IsLocalClientSelected"}, - {"party_joinInProgressPingBias"}, - {"party_kickplayerquestion"}, - {"party_listFocus"}, - {"party_lobbyPlayerCount"}, - {"party_mapname"}, - {"party_mapvote_entrya_mapname"}, - {"party_mapvote_entryb_mapname"}, - {"party_matchedPlayerCount"}, - {"party_maxplayers"}, - {"party_maxPrivatePartyPlayers"}, - {"party_maxTeamDiff"}, - {"party_membersMissingMapPack"}, - {"party_minLobbyTime"}, - {"party_minplayers"}, - {"party_nextMapVoteStatus"}, - {"party_oneSlotOpenPingBias"}, - {"party_over25FullPingBias"}, - {"party_over50FullPingBias"}, - {"party_over75FullPingBias"}, - {"party_partyPlayerCount"}, - {"party_partyPlayerCountNum"}, - {"party_playervisible"}, - {"party_resume_dlc_search_timer"}, - {"party_search_for_dlc_content"}, - {"party_selectedIndex"}, - {"party_selectedIndexChangedTime"}, - {"party_statusString"}, - {"party_teambased"}, - {"party_teamsVisible"}, - {"party_timer"}, - {"partyChatDisallowed"}, - {"partymigrate_broadcast_interval"}, - {"partymigrate_cpuBonusPing"}, - {"partymigrate_cpuBonusThreshold"}, - {"partymigrate_logResults"}, - {"partymigrate_makeHostTimeout"}, - {"partymigrate_pingtest_active"}, - {"partymigrate_pingtest_filterThreshold"}, - {"partymigrate_pingtest_minThreshold"}, - {"partymigrate_pingtest_retry"}, - {"partymigrate_pingtest_timeout"}, - {"partymigrate_preferSameHost"}, - {"partymigrate_selectiontime"}, - {"partymigrate_timeout"}, - {"partymigrate_timeoutmax"}, - {"partymigrate_uploadtest_minThreshold"}, - {"password"}, - {"past_title_data_active"}, - {"past_title_data_read_failure_interval_hours"}, - {"past_title_data_read_success_interval_hours"}, - {"perk_armorPiercingDamage"}, - {"perk_blastShieldClampHP"}, - {"perk_blastShieldClampHP_HC"}, - {"perk_blastShieldScale"}, - {"perk_blastShieldScale_HC"}, - {"perk_bulletPenetrationMultiplier"}, - {"perk_extendedMagsMGAmmo"}, - {"perk_extendedMagsPistolAmmo"}, - {"perk_extendedMagsRifleAmmo"}, - {"perk_extendedMagsSMGAmmo"}, - {"perk_extendedMagsSpreadAmmo"}, - {"perk_extraBreath"}, - {"perk_fastRegenRate"}, - {"perk_fastRegenWaitMS"}, - {"perk_fastSnipeScale"}, - {"perk_footstepVolumeAlly"}, - {"perk_footstepVolumeEnemy"}, - {"perk_footstepVolumePlayer"}, - {"perk_footstepVolumeSelectiveHearingMin"}, - {"perk_grenadeDeath"}, - {"perk_improvedExtraBreath"}, - {"perk_lightWeightViewBobScale"}, - {"perk_parabolicAngle"}, - {"perk_parabolicIcon"}, - {"perk_parabolicRadius"}, - {"perk_quickDrawSpeedScale"}, - {"perk_quickDrawSpeedScaleSniper"}, - {"perk_scavengerMode"}, - {"perk_sprintMultiplier"}, - {"perk_sprintRecoveryMultiplierActual"}, - {"perk_sprintRecoveryMultiplierVisual"}, - {"perk_weapRateMultiplier"}, - {"perk_weapReloadMultiplier"}, - {"perk_weapSpreadMultiplier"}, - {"phys_autoDisableAngular"}, - {"phys_autoDisableFastAngular"}, - {"phys_autoDisableFastLinear"}, - {"phys_autoDisableFastTime"}, - {"phys_autoDisableLinear"}, - {"phys_autoDisableTime"}, - {"phys_bulletSpinScale"}, - {"phys_bulletUpBias"}, - {"phys_cfm"}, - {"phys_collUseEntities"}, - {"phys_contact_cfm"}, - {"phys_contact_cfm_ragdoll"}, - {"phys_contact_cfm_vehicle"}, - {"phys_contact_cfm_vehicleSoft"}, - {"phys_contact_erp"}, - {"phys_contact_erp_ragdoll"}, - {"phys_contact_erp_vehicle"}, - {"phys_contact_erp_vehicleSoft"}, - {"phys_csl"}, - {"phys_dragAngular"}, - {"phys_dragLinear"}, - {"phys_erp"}, - {"phys_frictionScale"}, - {"phys_gravity"}, - {"phys_gravity_ragdoll"}, - {"phys_gravityChangeWakeupRadius"}, - {"phys_jitterMaxMass"}, - {"phys_joint_cfm"}, - {"phys_joint_stop_cfm"}, - {"phys_joint_stop_erp"}, - {"phys_jointPullThreshold"}, - {"phys_mcv"}, - {"phys_mcv_ragdoll"}, - {"phys_mcv_vehicle"}, - {"phys_noIslands"}, - {"phys_qsi"}, - {"phys_reorderConst"}, - {"physVeh_collideWithClipOnly"}, - {"physVeh_explodeForce"}, - {"physVeh_explodeSpinScale"}, - {"physVeh_jump"}, - {"physVeh_minImpactMomentum"}, - {"physVeh_pathConstraintCfm"}, - {"physVeh_pathConstraintErp"}, - {"physVeh_slideReductionForHighSpeed"}, - {"physVeh_StepsPerFrame"}, - {"pickupPrints"}, - {"player_breath_snd_delay"}, - {"player_breath_snd_lerp"}, - {"player_current_floor"}, - {"player_MGUseRadius"}, - {"player_stunWhiteFlash"}, - {"player_throwbackInnerRadius"}, - {"player_throwbackOuterRadius"}, - {"player_useRadius"}, - {"playercard_cache_download_max_retry_time"}, - {"playercard_cache_download_retry_step"}, - {"playercard_cache_upload_max_retry_time"}, - {"playercard_cache_upload_retry_step"}, - {"playercard_cache_validity_life"}, - {"playerPositionRecordSampleTime"}, - {"playlist"}, - {"playlistAggrFilename"}, - {"playlistFilename"}, - {"playListUpdateCheckMinutes"}, - {"pm_bouncing"}, - {"pm_bouncingAllAngles"}, - {"pm_gamesetup_mode_altmodes"}, - {"pm_gamesetup_mode_altmodes_dropzone"}, - {"pm_gamesetup_mode_altmodes_gungame"}, - {"pm_gamesetup_mode_altmodes_infected"}, - {"pm_gamesetup_mode_altmodes_jug"}, - {"pm_gamesetup_mode_altmodes_mugger"}, - {"pm_gamesetup_mode_altmodes_oneinthechamber"}, - {"pm_gamesetup_mode_altmodes_teamjug"}, - {"pm_gamesetup_options_createdefaultclass"}, - {"pm_gamesetup_options_customclassrestrictions"}, - {"prestige_shop_active"}, - {"privateMatch_joinPassword"}, - {"privateMatch_serverPassword"}, - {"profileMenuOption_blacklevel"}, - {"profileMenuOption_offensiveContentMode"}, - {"profileMenuOption_safeAreaHorz"}, - {"profileMenuOption_safeAreaVert"}, - {"profileMenuOption_sensitivity"}, - {"profileMenuOption_volume"}, - {"protocol"}, - {"pt_AliensReadyUpPrivateInUse"}, - {"pt_AliensReadyUpPublicInUse"}, - {"pt_AliensReadyUpPublicStartTimerLength"}, - {"pt_allMembersDoQoS"}, - {"pt_allMembersDoQoSTimeout"}, - {"pt_backoutOnClientPresence"}, - {"pt_connectAttempts"}, - {"pt_connectTimeout"}, - {"pt_currentSearchTier"}, - {"pt_defaultSearchTier"}, - {"pt_gameStartTimerLength"}, - {"pt_logHostSelectionChance"}, - {"pt_maxSearchTier"}, - {"pt_memberTimeout"}, - {"pt_migrateBeforeAdvertise"}, - {"pt_migrationBandwidthBonusPing"}, - {"pt_migrationBandwidthBonusThreshold"}, - {"pt_migrationCPUWeight"}, - {"pt_migrationNotInstalledWeight"}, - {"pt_migrationPingBad"}, - {"pt_migrationPingWeight"}, - {"pt_migrationQuitsBad"}, - {"pt_migrationQuitsWeight"}, - {"pt_migrationRAMWeight"}, - {"pt_migrationThreshold"}, - {"pt_migrationUploadBad"}, - {"pt_migrationUploadWeight"}, - {"pt_migrationWifiPenalty"}, - {"pt_msPerTier"}, - {"pt_percentUnacceptableQoS"}, - {"pt_pregameStartTimerLength"}, - {"pt_rejoin"}, - {"pt_reservedAnonymousSlotTime"}, - {"pt_reservedCommittedSlotTime"}, - {"pt_reservedJoiningSlotTime"}, - {"pt_searchConnectAttempts"}, - {"pt_searchPauseTime"}, - {"pt_searchRandomDelay"}, - {"pt_searchResultsLifetime"}, - {"pt_searchResultsMin"}, - {"pt_startAllowingUnacceptableQos"}, - {"pt_stillConnectingWaitTime"}, - {"pt_useHostPingForDesirability"}, - {"pt_useMigrationWeights"}, - {"r_aaMode"}, - {"r_adaptiveSubdiv"}, - {"r_adaptiveSubdivBaseFactor"}, - {"r_adaptiveSubdivPatchFactor"}, - {"r_altModelLightingUpdate"}, - {"r_amdGPU"}, - {"r_amdGPUVideoMemoryScale"}, - {"r_apex_turbulence"}, - {"r_apexTurbulence_LOD_MaxDist"}, - {"r_apexTurbulence_LOD_MinDist"}, - {"r_apexTurbulence_LOD_MinPercent"}, - {"r_artUseTweaks"}, - {"r_aspectRatio"}, - {"r_aspectRatioCustom"}, - {"r_asyncCompute"}, - {"r_atlasAnimFPS"}, - {"r_autopriority"}, - {"r_blacklevel"}, - {"r_blur"}, - {"r_brightness"}, - {"r_cacheModelLighting"}, - {"r_cacheSModelLighting"}, - {"r_cc_contrastPow1"}, - {"r_cc_contrastPow2"}, - {"r_cc_contrastScale1"}, - {"r_cc_contrastScale2"}, - {"r_cc_desaturation1"}, - {"r_cc_desaturation2"}, - {"r_cc_lerp1"}, - {"r_cc_lerp2"}, - {"r_cc_mode"}, - {"r_cc_toneBias1"}, - {"r_cc_toneBias2"}, - {"r_charLightAmbient"}, - {"r_charLightAmbient_NG"}, - {"r_clampLodScale"}, - {"r_clear"}, - {"r_clearColor"}, - {"r_clearColor2"}, - {"r_cmdbuf_worker"}, - {"r_colorGradingEnable"}, - {"r_colorMap"}, - {"r_combinePostOpaqueFx"}, - {"r_contrast"}, - {"r_debugLineWidth"}, - {"r_defaultPatchCount"}, - {"r_depthPrepass"}, - {"r_desaturation"}, - {"r_detailMap"}, - {"r_diffuseColorScale"}, - {"r_displacementMap"}, - {"r_displacementPatchCount"}, - {"r_displayMaxHeight"}, - {"r_displayMaxWidth"}, - {"r_displayMode"}, - {"r_displayRefresh"}, - {"r_distortion"}, - {"r_dlightLimit"}, - {"r_dof_bias"}, - {"r_dof_enable"}, - {"r_dof_farBlur"}, - {"r_dof_farEnd"}, - {"r_dof_farStart"}, - {"r_dof_hq"}, - {"r_dof_nearBlur"}, - {"r_dof_nearEnd"}, - {"r_dof_nearStart"}, - {"r_dof_tweak"}, - {"r_dof_viewModelEnd"}, - {"r_dof_viewModelStart"}, - {"r_drawSun"}, - {"r_drawWater"}, - {"r_elevatedPriority"}, - {"r_envMapExponent"}, - {"r_envMapMaxIntensity"}, - {"r_envMapMinIntensity"}, - {"r_envMapOverride"}, - {"r_envMapSunIntensity"}, - {"r_fastModelPrimaryLightCheck"}, - {"r_fastModelPrimaryLightLink"}, - {"r_filmAltShader"}, - {"r_filmTweakBrightness"}, - {"r_filmTweakContrast"}, - {"r_filmTweakDarkTint"}, - {"r_filmTweakDesaturation"}, - {"r_filmTweakDesaturationDark"}, - {"r_filmTweakEnable"}, - {"r_filmTweakInvert"}, - {"r_filmTweakLightTint"}, - {"r_filmTweakMediumTint"}, - {"r_filmUseTweaks"}, - {"r_flushAfterExecute"}, - {"r_fog"}, - {"r_fog_depthhack_scale"}, - {"r_forceLetterbox4x3"}, - {"r_forceLod"}, - {"r_fullbright"}, - {"r_fur_shader"}, - {"r_fxaaSubpixel"}, - {"r_FXAverageColorFunc"}, - {"r_glare_amountMin"}, - {"r_glare_enable"}, - {"r_glare_mergeWithBloom"}, - {"r_glare_mirrorAmount"}, - {"r_glare_mirrorEnd"}, - {"r_glare_mirrorPower"}, - {"r_glare_mirrorStart"}, - {"r_glare_normalAmount"}, - {"r_glare_normalEnd"}, - {"r_glare_normalPower"}, - {"r_glare_normalStart"}, - {"r_glare_useTweaks"}, - {"r_globalGenericMaterialScale"}, - {"r_glow_allowed"}, - {"r_glow_allowed_script_forced"}, - {"r_hbaoBias"}, - {"r_hbaoBlurEnable"}, - {"r_hbaoBlurSharpness"}, - {"r_hbaoCoarseAO"}, - {"r_hbaoDebug"}, - {"r_hbaoDetailAO"}, - {"r_hbaoPowerExponent"}, - {"r_hbaoRadius"}, - {"r_hbaoSceneScale"}, - {"r_hbaoStrengthBlend"}, - {"r_hbaoStrengthFixed"}, - {"r_hbaoStrengthScale"}, - {"r_hbaoUseScriptScale"}, - {"r_hdrColorizationBeforeEmissive"}, - {"r_hdrSkyColorTint"}, - {"r_hdrSkyIntensity"}, - {"r_hdrSkyIntensityUseTweaks"}, - {"r_heroLighting"}, - {"r_highLodDist"}, - {"r_hudOutlineAlpha0"}, - {"r_hudOutlineAlpha1"}, - {"r_hudOutlineCurvyBlurRadius"}, - {"r_hudOutlineCurvyDarkenScale"}, - {"r_hudOutlineCurvyDepth"}, - {"r_hudOutlineCurvyLumScale"}, - {"r_hudOutlineCurvyWhen"}, - {"r_hudOutlineCurvyWidth"}, - {"r_hudOutlineEnable"}, - {"r_hudOutlineHaloBlurRadius"}, - {"r_hudOutlineHaloDarkenScale"}, - {"r_hudOutlineHaloLumScale"}, - {"r_hudOutlineHaloWhen"}, - {"r_hudOutlinePostMode"}, - {"r_hudOutlineWhen"}, - {"r_hudOutlineWidth"}, - {"r_ignore"}, - {"r_ignoref"}, - {"r_imageQuality"}, - {"r_lateAllocParamCacheAllowed"}, - {"r_lateAllocParamCacheDefault"}, - {"r_lateAllocParamCacheDisplacement"}, - {"r_lateAllocParamCacheSubdiv"}, - {"r_letterbox4x3"}, - {"r_lightCacheLessFrequentMaxDistance"}, - {"r_lightCacheLessFrequentPeriod"}, - {"r_lightGridContrast"}, - {"r_lightGridEnableTweaks"}, - {"r_lightGridIntensity"}, - {"r_lightGridSHBands"}, - {"r_lightGridUseTweakedValues"}, - {"r_lightMap"}, - {"r_litSurfaceHDRScalar"}, - {"r_loadForRenderer"}, - {"r_lockPvs"}, - {"r_lod4Dist"}, - {"r_lod5Dist"}, - {"r_lodBiasRigid"}, - {"r_lodBiasSkinned"}, - {"r_lodScaleRigid"}, - {"r_lodScaleSkinned"}, - {"r_lowestLodDist"}, - {"r_lowLodDist"}, - {"r_materialBloomDesaturation"}, - {"r_materialBloomHQDesaturation"}, - {"r_materialBloomHQEnable"}, - {"r_materialBloomHQFalloffScale1"}, - {"r_materialBloomHQFalloffScale2"}, - {"r_materialBloomHQFalloffWeight1"}, - {"r_materialBloomHQFalloffWeight2"}, - {"r_materialBloomHQGamma"}, - {"r_materialBloomHQHaziness"}, - {"r_materialBloomHQRadius"}, - {"r_materialBloomHQScriptMasterEnable"}, - {"r_materialBloomHQSensitivity"}, - {"r_materialBloomIntensity"}, - {"r_materialBloomLuminanceCutoff"}, - {"r_materialBloomPinch"}, - {"r_materialBloomRadius"}, - {"r_materialBloomUseTweaks"}, - {"r_mbCameraRotationInfluence"}, - {"r_mbCameraTranslationInfluence"}, - {"r_mbEnable"}, - {"r_mbEnableA"}, - {"r_mbFastEnable"}, - {"r_mbFastEnableA"}, - {"r_mbFastPreset"}, - {"r_mbModelVelocityScalar"}, - {"r_mbPostfxMaxNumSamples"}, - {"r_mbStaticVelocityScalar"}, - {"r_mbViewModelEnable"}, - {"r_mbViewModelVelocityScalar"}, - {"r_mediumLodDist"}, - {"r_mode"}, - {"r_monitor"}, - {"r_msaaEnable"}, - {"r_msaaResolveMode"}, - {"r_multiGPU"}, - {"r_normalMap"}, - {"r_nvidiaGPU"}, - {"r_nvidiaGPUCount"}, - {"r_offchipTessellationAllowed"}, - {"r_offchipTessellationTfThreshold"}, - {"r_offchipTessellationWaveThreshold"}, - {"r_omitUnusedRenderTargets"}, - {"r_outdoor"}, - {"r_outdoorFeather"}, - {"r_patchCountAllowed"}, - {"r_picmip"}, - {"r_picmip_bump"}, - {"r_picmip_manual"}, - {"r_picmip_spec"}, - {"r_picmip_water"}, - {"r_polygonOffsetBias"}, - {"r_polygonOffsetClamp"}, - {"r_polygonOffsetScale"}, - {"r_portalBevels"}, - {"r_portalBevelsOnly"}, - {"r_portalMinClipArea"}, - {"r_portalMinRecurseDepth"}, - {"r_portalWalkLimit"}, - {"r_postAA"}, - {"r_postfxMacroclutEnable"}, - {"r_postfxMacroclutWorker"}, - {"r_predatorAllyBrightness"}, - {"r_predatorAllyContrast"}, - {"r_predatorAllyHueRot"}, - {"r_predatorAllyOutputColorBias"}, - {"r_predatorAllyOutputColorScale"}, - {"r_predatorAllyPostBrightness"}, - {"r_predatorAllyPostContrast"}, - {"r_predatorAllyPosterHardness"}, - {"r_predatorAllySaturation"}, - {"r_predatorColdBrightness"}, - {"r_predatorColdContrast"}, - {"r_predatorColdCycleFreq"}, - {"r_predatorColdCycleMax"}, - {"r_predatorColdCycleMin"}, - {"r_predatorColdCyclePhase"}, - {"r_predatorColdHueRot"}, - {"r_predatorColdOutputColorBias"}, - {"r_predatorColdOutputColorScale"}, - {"r_predatorColdPostBrightness"}, - {"r_predatorColdPostContrast"}, - {"r_predatorColdPosterBias"}, - {"r_predatorColdPosterBiasSpeed"}, - {"r_predatorColdPosterColorCount"}, - {"r_predatorColdPosterHardness"}, - {"r_predatorColdSaturation"}, - {"r_predatorDisable"}, - {"r_predatorEnemyBrightness"}, - {"r_predatorEnemyContrast"}, - {"r_predatorEnemyHueRot"}, - {"r_predatorEnemyOutputColorBias"}, - {"r_predatorEnemyOutputColorScale"}, - {"r_predatorEnemyPostBrightness"}, - {"r_predatorEnemyPostContrast"}, - {"r_predatorEnemyPosterHardness"}, - {"r_predatorEnemySaturation"}, - {"r_predatorForce"}, - {"r_predatorHotCycleFreq"}, - {"r_predatorHotCycleMax"}, - {"r_predatorHotCycleMin"}, - {"r_predatorHotCyclePhase"}, - {"r_predatorHotPosterBias"}, - {"r_predatorHotPosterBiasSpeed"}, - {"r_predatorHotPosterColorCount"}, - {"r_preloadShaders"}, - {"r_primaryLightTweakDiffuseStrength"}, - {"r_primaryLightTweakDiffuseStrength_NG"}, - {"r_primaryLightTweakSpecularStrength"}, - {"r_primaryLightTweakSpecularStrength_NG"}, - {"r_primaryLightUseTweaks"}, - {"r_primaryLightUseTweaks_NG"}, - {"r_reactiveMotionActorRadius"}, - {"r_reactiveMotionActorVelocityMax"}, - {"r_reactiveMotionEffectorStrengthScale"}, - {"r_reactiveMotionHelicopterLimit"}, - {"r_reactiveMotionHelicopterRadius"}, - {"r_reactiveMotionHelicopterStrength"}, - {"r_reactiveMotionPlayerHeightAdjust"}, - {"r_reactiveMotionPlayerRadius"}, - {"r_reactiveMotionVelocityTailScale"}, - {"r_reactiveMotionWindAmplitudeScale"}, - {"r_reactiveMotionWindAreaScale"}, - {"r_reactiveMotionWindDir"}, - {"r_reactiveMotionWindFrequencyScale"}, - {"r_reactiveMotionWindStrength"}, - {"r_reactiveTurbulenceEnable"}, - {"r_reactiveTurbulenceVelocityClamp"}, - {"r_rendererInUse"}, - {"r_rimLight0Color"}, - {"r_rimLight0Heading"}, - {"r_rimLight0Pitch"}, - {"r_rimLightBias"}, - {"r_rimLightDiffuseIntensity"}, - {"r_rimLightPower"}, - {"r_rimLightSpecIntensity"}, - {"r_rimLightUseTweaks"}, - {"r_scaleViewport"}, - {"r_showBlurScene"}, - {"r_showBlurSceneScissor"}, - {"r_showCharacterSceneTexture"}, - {"r_showLightGrid"}, - {"r_showMissingLightGrid"}, - {"r_showModelLightingLowWaterMark"}, - {"r_showPIPTexture"}, - {"r_showPortals"}, - {"r_showPortalsOverview"}, - {"r_showReflectionProbeSelection"}, - {"r_singleCell"}, - {"r_SkinnedCacheSize"}, - {"r_SkinnedCacheThreshold"}, - {"r_skipPvs"}, - {"r_sky_fog_intensity"}, - {"r_sky_fog_max_angle"}, - {"r_sky_fog_min_angle"}, - {"r_skyFogUseTweaks"}, - {"r_smaaThreshold"}, - {"r_smodelInstancedRenderer"}, - {"r_smodelInstancedThreshold"}, - {"r_smp_backend"}, - {"r_smp_worker"}, - {"r_smp_worker_thread0"}, - {"r_smp_worker_thread1"}, - {"r_smp_worker_thread2"}, - {"r_smp_worker_thread3"}, - {"r_smp_worker_thread4"}, - {"r_smp_worker_thread5"}, - {"r_smp_worker_thread6"}, - {"r_smp_worker_thread7"}, - {"r_specularColorScale"}, - {"r_specularMap"}, - {"r_spotLightEntityShadows"}, - {"r_spotLightShadows"}, - {"r_ssao"}, - {"r_ssaoBlurSharpness"}, - {"r_ssaoBlurStep"}, - {"r_ssaoDepthScale"}, - {"r_ssaoDepthScaleViewModel"}, - {"r_ssaoDiminish"}, - {"r_ssaoFadeDepth"}, - {"r_ssaoGapFalloff"}, - {"r_ssaoGradientFalloff"}, - {"r_ssaoMinPixelWidth"}, - {"r_ssaoPower"}, - {"r_ssaoRejectDepth"}, - {"r_ssaoScriptScale"}, - {"r_ssaoStrength"}, - {"r_ssaoUseScriptScale"}, - {"r_ssaoUseTweaks"}, - {"r_ssaoWidth"}, - {"r_sse_skinning"}, - {"r_ssrFadeInDuration"}, - {"r_ssrPositionCorrection"}, - {"r_subdiv"}, - {"r_subdivLimit"}, - {"r_subdivPatchCount"}, - {"r_subdomainLimit"}, - {"r_subdomainScale"}, - {"r_subwindow"}, - {"r_sun_from_dvars"}, - {"r_sun_fx_position"}, - {"r_sunblind_fadein"}, - {"r_sunblind_fadeout"}, - {"r_sunblind_max_angle"}, - {"r_sunblind_max_darken"}, - {"r_sunblind_min_angle"}, - {"r_sunflare_fadein"}, - {"r_sunflare_fadeout"}, - {"r_sunflare_max_alpha"}, - {"r_sunflare_max_angle"}, - {"r_sunflare_max_size"}, - {"r_sunflare_min_angle"}, - {"r_sunflare_min_size"}, - {"r_sunflare_shader"}, - {"r_sunglare_fadein"}, - {"r_sunglare_fadeout"}, - {"r_sunglare_max_angle"}, - {"r_sunglare_max_lighten"}, - {"r_sunglare_min_angle"}, - {"r_sunshadowmap_cmdbuf_worker"}, - {"r_sunsprite_shader"}, - {"r_sunsprite_size"}, - {"r_surfaceHDRScalarUseTweaks"}, - {"r_tessellation"}, - {"r_tessellationCutoffDistance"}, - {"r_tessellationCutoffDistanceBase"}, - {"r_tessellationCutoffFalloff"}, - {"r_tessellationCutoffFalloffBase"}, - {"r_tessellationEyeScale"}, - {"r_tessellationFactor"}, - {"r_tessellationHeightAuto"}, - {"r_tessellationHeightScale"}, - {"r_tessellationHybrid"}, - {"r_tessellationLodBias"}, - {"r_texFilterAnisoMax"}, - {"r_texFilterAnisoMin"}, - {"r_texFilterDisable"}, - {"r_texFilterMipBias"}, - {"r_texFilterMipMode"}, - {"r_texFilterProbeBilinear"}, - {"r_texShowMipMode"}, - {"r_thermalColorOffset"}, - {"r_thermalColorScale"}, - {"r_thermalDetailScale"}, - {"r_thermalFadeColor"}, - {"r_thermalFadeControl"}, - {"r_thermalFadeMax"}, - {"r_thermalFadeMin"}, - {"r_txaa"}, - {"r_txaaDebug"}, - {"r_txaaDepthRange"}, - {"r_txaaLimitPixels1"}, - {"r_txaaLimitPixels2"}, - {"r_umbra"}, - {"r_umbraAccurateOcclusionThreshold"}, - {"r_umbraDistanceReference"}, - {"r_umbraExclusive"}, - {"r_umbraQueryParts"}, - {"r_umbraShadowCasters"}, - {"r_umbraUseDpvsCullDist"}, - {"r_unlitSurfaceHDRScalar"}, - {"r_useComputeSkinning"}, - {"r_useLayeredMaterials"}, - {"r_usePrebuiltSpotShadow"}, - {"r_usePrebuiltSunShadow"}, - {"r_useShadowGeomOpt"}, - {"r_vc_makelog"}, - {"r_vc_showlog"}, - {"r_viewModelLightAmbient"}, - {"r_viewModelLightAmbient_NG"}, - {"r_viewModelPrimaryLightTweakDiffuseStrength"}, - {"r_viewModelPrimaryLightTweakDiffuseStrength_NG"}, - {"r_viewModelPrimaryLightTweakSpecularStrength"}, - {"r_viewModelPrimaryLightTweakSpecularStrength_NG"}, - {"r_viewModelPrimaryLightUseTweaks"}, - {"r_viewModelPrimaryLightUseTweaks_NG"}, - {"r_volumeLightScatter"}, - {"r_volumeLightScatterAngularAtten"}, - {"r_volumeLightScatterBackgroundDistance"}, - {"r_volumeLightScatterColor"}, - {"r_volumeLightScatterDepthAttenFar"}, - {"r_volumeLightScatterDepthAttenNear"}, - {"r_volumeLightScatterLinearAtten"}, - {"r_volumeLightScatterQuadraticAtten"}, - {"r_volumeLightScatterUseTweaks"}, - {"r_vsync"}, - {"r_warningRepeatDelay"}, - {"r_zfar"}, - {"r_znear"}, - {"radarjamDistMax"}, - {"radarjamDistMin"}, - {"radarjamSinCurve"}, - {"radius_damage_debug"}, - {"ragdoll_baselerp_time"}, - {"ragdoll_bullet_force"}, - {"ragdoll_bullet_upbias"}, - {"ragdoll_debug"}, - {"ragdoll_debug_axisid"}, - {"ragdoll_debug_bodyid"}, - {"ragdoll_debug_boneid"}, - {"ragdoll_debug_jointid"}, - {"ragdoll_dump_anims"}, - {"ragdoll_enable"}, - {"ragdoll_explode_force"}, - {"ragdoll_explode_upbias"}, - {"ragdoll_exploding_bullet_force"}, - {"ragdoll_exploding_bullet_upbias"}, - {"ragdoll_fps"}, - {"ragdoll_idle_min_velsq"}, - {"ragdoll_jitter_scale"}, - {"ragdoll_jointlerp_time"}, - {"ragdoll_max_life"}, - {"ragdoll_max_simulating"}, - {"ragdoll_max_stretch_pct"}, - {"ragdoll_mp_limit"}, - {"ragdoll_mp_resume_share_after_killcam"}, - {"ragdoll_rotvel_scale"}, - {"ragdoll_self_collision_scale"}, - {"ragdoll_stretch_iters"}, - {"rate"}, - {"rcon_password"}, - {"relay_backoffTime"}, - {"relay_disconnectOnFailedRetries"}, - {"relay_handshakeWindow"}, - {"relay_isEnabled"}, - {"relay_sendRetryAttempts"}, - {"relay_sendThrottle"}, - {"relay_timeout"}, - {"RemoteCameraSounds_DryLevel"}, - {"RemoteCameraSounds_RoomType"}, - {"RemoteCameraSounds_WetLevel"}, - {"requireOpenNat"}, - {"reset_mm_data"}, - {"restrictMapPacksToGroups"}, - {"safeArea_adjusted_horizontal"}, - {"safeArea_adjusted_vertical"}, - {"safeArea_horizontal"}, - {"safeArea_vertical"}, - {"scr_aliens_casual"}, - {"scr_aliens_hardcore"}, - {"scr_aliens_infinite"}, - {"scr_aliens_maxagents"}, - {"scr_aliens_numlives"}, - {"scr_aliens_playerrespawndelay"}, - {"scr_aliens_promode"}, - {"scr_aliens_ricochet"}, - {"scr_aliens_roundlimit"}, - {"scr_aliens_scorelimit"}, - {"scr_aliens_timelimit"}, - {"scr_aliens_waverespawndelay"}, - {"scr_aliens_winlimit"}, - {"scr_aliens_xpscale"}, - {"scr_altBlitzSpawns"}, - {"scr_altFFASpawns"}, - {"scr_anchorSpawns"}, - {"scr_blitz_numlives"}, - {"scr_blitz_playerrespawndelay"}, - {"scr_blitz_promode"}, - {"scr_blitz_roundlimit"}, - {"scr_blitz_roundswitch"}, - {"scr_blitz_scoredelay"}, - {"scr_blitz_scorelimit"}, - {"scr_blitz_timelimit"}, - {"scr_blitz_waverespawndelay"}, - {"scr_blitz_winlimit"}, - {"scr_chaos_mode"}, - {"scr_conf_numlives"}, - {"scr_conf_playerrespawndelay"}, - {"scr_conf_promode"}, - {"scr_conf_roundlimit"}, - {"scr_conf_scorelimit"}, - {"scr_conf_timelimit"}, - {"scr_conf_waverespawndelay"}, - {"scr_conf_winlimit"}, - {"scr_cranked_numlives"}, - {"scr_cranked_playerrespawndelay"}, - {"scr_cranked_promode"}, - {"scr_cranked_roundlimit"}, - {"scr_cranked_scorelimit"}, - {"scr_cranked_scorelimit_ffa"}, - {"scr_cranked_teambased"}, - {"scr_cranked_timelimit"}, - {"scr_cranked_waverespawndelay"}, - {"scr_cranked_winlimit"}, - {"scr_default_maxagents"}, - {"scr_defcon"}, - {"scr_diehard"}, - {"scr_disableClientSpawnTraces"}, - {"scr_dm_numlives"}, - {"scr_dm_playerrespawndelay"}, - {"scr_dm_promode"}, - {"scr_dm_roundlimit"}, - {"scr_dm_scorelimit"}, - {"scr_dm_timelimit"}, - {"scr_dm_waverespawndelay"}, - {"scr_dm_winlimit"}, - {"scr_dom_numlives"}, - {"scr_dom_playerrespawndelay"}, - {"scr_dom_promode"}, - {"scr_dom_roundlimit"}, - {"scr_dom_scorelimit"}, - {"scr_dom_timelimit"}, - {"scr_dom_waverespawndelay"}, - {"scr_dom_winlimit"}, - {"scr_explBulletMod"}, - {"scr_frontlineSpawns"}, - {"scr_game_allowkillcam"}, - {"scr_game_deathpointloss"}, - {"scr_game_forceuav"}, - {"scr_game_graceperiod"}, - {"scr_game_hardpoints"}, - {"scr_game_killstreakdelay"}, - {"scr_game_onlyheadshots"}, - {"scr_game_perks"}, - {"scr_game_spectatetype"}, - {"scr_game_suicidepointloss"}, - {"scr_gameended"}, - {"scr_grind_numlives"}, - {"scr_grind_playerrespawndelay"}, - {"scr_grind_promode"}, - {"scr_grind_roundlimit"}, - {"scr_grind_scorelimit"}, - {"scr_grind_timelimit"}, - {"scr_grind_waverespawndelay"}, - {"scr_grind_winlimit"}, - {"scr_grnd_dropTime"}, - {"scr_grnd_numlives"}, - {"scr_grnd_playerrespawndelay"}, - {"scr_grnd_promode"}, - {"scr_grnd_roundlimit"}, - {"scr_grnd_scorelimit"}, - {"scr_grnd_timelimit"}, - {"scr_grnd_waverespawndelay"}, - {"scr_grnd_winlimit"}, - {"scr_grnd_zoneSwitchTime"}, - {"scr_hardcore"}, - {"scr_hardpoint_allowartillery"}, - {"scr_hardpoint_allowhelicopter"}, - {"scr_hardpoint_allowuav"}, - {"scr_horde_difficulty"}, - {"scr_horde_maxagents"}, - {"scr_horde_numlives"}, - {"scr_horde_playerrespawndelay"}, - {"scr_horde_promode"}, - {"scr_horde_roundlimit"}, - {"scr_horde_scorelimit"}, - {"scr_horde_timelimit"}, - {"scr_horde_waverespawndelay"}, - {"scr_horde_winlimit"}, - {"scr_infect_numlives"}, - {"scr_infect_playerrespawndelay"}, - {"scr_infect_promode"}, - {"scr_infect_roundlimit"}, - {"scr_infect_timelimit"}, - {"scr_infect_waverespawndelay"}, - {"scr_infect_winlimit"}, - {"scr_maxPerPlayerExplosives"}, - {"scr_mugger_numlives"}, - {"scr_mugger_playerrespawndelay"}, - {"scr_mugger_promode"}, - {"scr_mugger_roundlimit"}, - {"scr_mugger_scorelimit"}, - {"scr_mugger_timelimit"}, - {"scr_mugger_waverespawndelay"}, - {"scr_mugger_winlimit"}, - {"scr_nukeCancelMode"}, - {"scr_nukeTimer"}, - {"scr_objectivetext"}, - {"scr_oldschool"}, - {"scr_patientZero"}, - {"scr_player_forcerespawn"}, - {"scr_player_healthregentime"}, - {"scr_player_maxhealth"}, - {"scr_player_numlives"}, - {"scr_player_respawndelay"}, - {"scr_player_sprinttime"}, - {"scr_player_suicidespawndelay"}, - {"scr_playlist_type"}, - {"scr_RequiredMapAspectratio"}, - {"scr_restxp_cap"}, - {"scr_restxp_enable"}, - {"scr_restxp_levelsPerDay"}, - {"scr_restxp_minRestTime"}, - {"scr_restxp_restedAwardScale"}, - {"scr_restxp_timescale"}, - {"scr_riotShieldXPBullets"}, - {"scr_sd_bombtimer"}, - {"scr_sd_defusetime"}, - {"scr_sd_multibomb"}, - {"scr_sd_numlives"}, - {"scr_sd_planttime"}, - {"scr_sd_playerrespawndelay"}, - {"scr_sd_promode"}, - {"scr_sd_roundlimit"}, - {"scr_sd_roundswitch"}, - {"scr_sd_scorelimit"}, - {"scr_sd_timelimit"}, - {"scr_sd_waverespawndelay"}, - {"scr_sd_winlimit"}, - {"scr_siege_caprate"}, - {"scr_siege_numlives"}, - {"scr_siege_playerrespawndelay"}, - {"scr_siege_precap"}, - {"scr_siege_promode"}, - {"scr_siege_roundlimit"}, - {"scr_siege_roundswitch"}, - {"scr_siege_rushtimer"}, - {"scr_siege_rushtimeramount"}, - {"scr_siege_scorelimit"}, - {"scr_siege_timelimit"}, - {"scr_siege_waverespawndelay"}, - {"scr_siege_winlimit"}, - {"scr_sotf_crateamount"}, - {"scr_sotf_crategunamount"}, - {"scr_sotf_cratetimer"}, - {"scr_sotf_ffa_crateamount"}, - {"scr_sotf_ffa_crategunamount"}, - {"scr_sotf_ffa_cratetimer"}, - {"scr_sotf_ffa_numlives"}, - {"scr_sotf_ffa_playerrespawndelay"}, - {"scr_sotf_ffa_promode"}, - {"scr_sotf_ffa_roundlimit"}, - {"scr_sotf_ffa_scorelimit"}, - {"scr_sotf_ffa_timelimit"}, - {"scr_sotf_ffa_waverespawndelay"}, - {"scr_sotf_ffa_winlimit"}, - {"scr_sotf_numlives"}, - {"scr_sotf_playerrespawndelay"}, - {"scr_sotf_promode"}, - {"scr_sotf_roundlimit"}, - {"scr_sotf_scorelimit"}, - {"scr_sotf_timelimit"}, - {"scr_sotf_waverespawndelay"}, - {"scr_sotf_winlimit"}, - {"scr_sr_bombtimer"}, - {"scr_sr_defusetime"}, - {"scr_sr_multibomb"}, - {"scr_sr_numlives"}, - {"scr_sr_planttime"}, - {"scr_sr_playerrespawndelay"}, - {"scr_sr_promode"}, - {"scr_sr_roundlimit"}, - {"scr_sr_roundswitch"}, - {"scr_sr_scorelimit"}, - {"scr_sr_timelimit"}, - {"scr_sr_waverespawndelay"}, - {"scr_sr_winlimit"}, - {"scr_team_fftype"}, - {"scr_team_kickteamkillers"}, - {"scr_team_respawntime"}, - {"scr_team_teamkillpointloss"}, - {"scr_team_teamkillspawndelay"}, - {"scr_thirdPerson"}, - {"scr_tispawndelay"}, - {"scr_trackPlayerAbilities"}, - {"scr_war_halftime"}, - {"scr_war_numlives"}, - {"scr_war_playerrespawndelay"}, - {"scr_war_promode"}, - {"scr_war_roundlimit"}, - {"scr_war_roundswitch"}, - {"scr_war_scorelimit"}, - {"scr_war_timelimit"}, - {"scr_war_waverespawndelay"}, - {"scr_war_winlimit"}, - {"scr_xpscale"}, - {"screenshots_active"}, - {"search_weight_asn"}, - {"search_weight_country_code"}, - {"search_weight_lat_long"}, - {"sensitivity"}, - {"sentry_placement_debug"}, - {"sentry_placement_feet_offset"}, - {"sentry_placement_feet_trace_dist_z"}, - {"sentry_placement_trace_dist"}, - {"sentry_placement_trace_min_normal"}, - {"sentry_placement_trace_pitch"}, - {"sentry_placement_trace_radius"}, - {"sentry_placement_trace_radius_canon_safety"}, - {"server1"}, - {"server10"}, - {"server11"}, - {"server12"}, - {"server13"}, - {"server14"}, - {"server15"}, - {"server16"}, - {"server2"}, - {"server3"}, - {"server4"}, - {"server5"}, - {"server6"}, - {"server7"}, - {"server8"}, - {"server9"}, - {"session_immediateDeleteTinySessions"}, - {"session_modify_retry_on_failure"}, - {"session_nonblocking"}, - {"shieldBlastDamageProtection_120"}, - {"shieldBlastDamageProtection_180"}, - {"shieldBlastDamageProtection_30"}, - {"shieldBlastDamageProtection_60"}, - {"shieldImpactBulletShakeDuration"}, - {"shieldImpactBulletShakeScale"}, - {"shieldImpactExplosionHighShakeDuration"}, - {"shieldImpactExplosionHighShakeScale"}, - {"shieldImpactExplosionLowShakeDuration"}, - {"shieldImpactExplosionLowShakeScale"}, - {"shieldImpactExplosionThreshold"}, - {"shieldImpactMissileShakeDuration"}, - {"shieldImpactMissileShakeScale"}, - {"shortversion"}, - {"slide_enable"}, - {"sm_cameraOffset"}, - {"sm_dynlightAllSModels"}, - {"sm_enable"}, - {"sm_fastSunShadow"}, - {"sm_lightScore_eyeProjectDist"}, - {"sm_lightScore_spotProjectFrac"}, - {"sm_maxLightsWithShadows"}, - {"sm_minSpotLightScore"}, - {"sm_polygonOffsetBias"}, - {"sm_polygonOffsetClamp"}, - {"sm_polygonOffsetScale"}, - {"sm_qualitySpotShadow"}, - {"sm_spotDistCull"}, - {"sm_spotEnable"}, - {"sm_spotLightScoreModelScale"}, - {"sm_spotLimit"}, - {"sm_spotShadowFadeTime"}, - {"sm_strictCull"}, - {"sm_sunEnable"}, - {"sm_sunSampleSizeNear"}, - {"sm_sunShadowCenter"}, - {"sm_sunShadowCenterMode"}, - {"sm_sunShadowScale"}, - {"sm_sunShadowScaleLocked"}, - {"snd_cinematicVolumeScale"}, - {"snd_dopplerAuditionEnable"}, - {"snd_dopplerBaseSpeedOfSound"}, - {"snd_dopplerEnable"}, - {"snd_dopplerPitchMax"}, - {"snd_dopplerPitchMin"}, - {"snd_dopplerPlayerVelocityScale"}, - {"snd_dopplerSmoothing"}, - {"snd_draw3D"}, - {"snd_drawInfo"}, - {"snd_enable2D"}, - {"snd_enable3D"}, - {"snd_enableEq"}, - {"snd_enableReverb"}, - {"snd_enableStream"}, - {"snd_errorOnMissing"}, - {"snd_levelFadeTime"}, - {"snd_loadFadeTime"}, - {"snd_newWhizby"}, - {"snd_occlusionDelay"}, - {"snd_occlusionLerpTime"}, - {"snd_omnidirectionalPercentage"}, - {"snd_slaveFadeTime"}, - {"snd_touchStreamFilesOnLoad"}, - {"snd_useHardOuterEntchannelPriorities"}, - {"snd_volume"}, - {"social_feed_clans_active"}, - {"social_feed_motd_active"}, - {"social_feed_news_active"}, - {"social_feed_social_active"}, - {"social_feed_squads_active"}, - {"speech_active"}, - {"splitscreen"}, - {"squad_can_host_server"}, - {"squad_cile"}, - {"squad_dont_advertise"}, - {"squad_find_match"}, - {"squad_find_match_max_retry_time"}, - {"squad_find_match_retry_step"}, - {"squad_lobby_type"}, - {"squad_match"}, - {"squad_min_human_players"}, - {"squad_no_migrations"}, - {"squad_report_text"}, - {"squad_rxb"}, - {"squad_rxbm"}, - {"squad_send_results"}, - {"squad_team_balance"}, - {"squad_use_hosts_squad"}, - {"squad_vs_squad"}, - {"steam_ingame_p2p_throttle"}, - {"stringtable_debug"}, - {"sv_allowClientConsole"}, - {"sv_allowedClan1"}, - {"sv_allowedClan2"}, - {"sv_archiveClientsPositions"}, - {"sv_cheats"}, - {"sv_checkMinPlayers"}, - {"sv_clientArchive"}, - {"sv_connectTimeout"}, - {"sv_cumulThinkTime"}, - {"sv_error_on_baseline_failure"}, - {"sv_hostname"}, - {"sv_hugeSnapshotDelay"}, - {"sv_hugeSnapshotSize"}, - {"sv_kickBanTime"}, - {"sv_local_client_snapshot_msec"}, - {"sv_maxclients"}, - {"sv_minPingClamp"}, - {"sv_network_fps"}, - {"sv_paused"}, - {"sv_privateClients"}, - {"sv_privateClientsForClients"}, - {"sv_privatePassword"}, - {"sv_reconnectlimit"}, - {"sv_rejoinTimeout"}, - {"sv_remote_client_snapshot_msec"}, - {"sv_running"}, - {"sv_sayName"}, - {"sv_showAverageBPS"}, - {"sv_testValue"}, - {"sv_timeout"}, - {"sv_trackFrameMsecThreshold"}, - {"sv_useExtraCompress"}, - {"sv_zlib_threshold"}, - {"sv_zombietime"}, - {"svwp"}, - {"sys_configSum"}, - {"sys_configureGHz"}, - {"sys_cpuGHz"}, - {"sys_cpuName"}, - {"sys_gpu"}, - {"sys_lockThreads"}, - {"sys_quitMigrateTime"}, - {"sys_smp_allowed"}, - {"sys_SSE"}, - {"sys_sysMB"}, - {"systemlink"}, - {"tb_report"}, - {"team_rebalance"}, - {"theater_active"}, - {"thermal_playerModel"}, - {"thermalBlurFactorNoScope"}, - {"thermalBlurFactorScope"}, - {"tracer_explosiveColor1"}, - {"tracer_explosiveColor2"}, - {"tracer_explosiveColor3"}, - {"tracer_explosiveColor4"}, - {"tracer_explosiveColor5"}, - {"tracer_explosiveOverride"}, - {"tracer_explosiveWidth"}, - {"tracer_firstPersonMaxWidth"}, - {"tracer_stoppingPowerColor1"}, - {"tracer_stoppingPowerColor2"}, - {"tracer_stoppingPowerColor3"}, - {"tracer_stoppingPowerColor4"}, - {"tracer_stoppingPowerColor5"}, - {"tracer_stoppingPowerOverride"}, - {"tracer_stoppingPowerWidth"}, - {"tracer_thermalWidthMult"}, - {"transients_verbose"}, - {"ui_ability_end_milliseconds"}, - {"ui_ability_recharging"}, - {"ui_ability_timer"}, - {"ui_ac130"}, - {"ui_ac130_105mm_ammo"}, - {"ui_ac130_25mm_ammo"}, - {"ui_ac130_40mm_ammo"}, - {"ui_ac130_coord1_posx"}, - {"ui_ac130_coord1_posy"}, - {"ui_ac130_coord1_posz"}, - {"ui_ac130_coord2_posx"}, - {"ui_ac130_coord2_posy"}, - {"ui_ac130_coord2_posz"}, - {"ui_ac130_coord3_posx"}, - {"ui_ac130_coord3_posy"}, - {"ui_ac130_coord3_posz"}, - {"ui_ac130_darken"}, - {"ui_ac130_thermal"}, - {"ui_ac130_use_time"}, - {"ui_ac130_weapon"}, - {"ui_ac130usetime"}, - {"ui_activeAbility_name"}, - {"ui_adrenaline"}, - {"ui_allow_classchange"}, - {"ui_allow_controlschange"}, - {"ui_allow_teamchange"}, - {"ui_allowvote"}, - {"ui_altscene"}, - {"ui_autodetectGamepad"}, - {"ui_autodetectGamepadDone"}, - {"ui_bigFont"}, - {"ui_borderLowLightScale"}, - {"ui_browserFriendlyfire"}, - {"ui_browserKillcam"}, - {"ui_browserMod"}, - {"ui_browserShowDedicated"}, - {"ui_browserShowEmpty"}, - {"ui_browserShowFull"}, - {"ui_browserShowPassword"}, - {"ui_browserShowPure"}, - {"ui_buildLocation"}, - {"ui_buildSize"}, - {"ui_challenge_1_ref"}, - {"ui_challenge_2_ref"}, - {"ui_challenge_3_ref"}, - {"ui_challenge_4_ref"}, - {"ui_challenge_5_ref"}, - {"ui_challenge_6_ref"}, - {"ui_challenge_7_ref"}, - {"ui_changeclass_menu_open"}, - {"ui_changeteam_menu_open"}, - {"ui_cinematicsTimestamp"}, - {"ui_class_menu_open"}, - {"ui_connectScreenTextGlowColor"}, - {"ui_contextualMenuLocation"}, - {"ui_controls_menu_open"}, - {"ui_currentFeederMapIndex"}, - {"ui_currentMap"}, - {"ui_customClassName"}, - {"ui_customModeEditName"}, - {"ui_customModeName"}, - {"ui_danger_team"}, - {"ui_debugMode"}, - {"ui_disableInGameStore"}, - {"ui_disableTokenRedemption"}, - {"ui_drawCrosshair"}, - {"ui_editSquadMemberIndex"}, - {"ui_extraBigFont"}, - {"ui_eyes_on_end_milliseconds"}, - {"ui_friendlyfire"}, - {"ui_game_state"}, - {"ui_gametype"}, - {"ui_halftime"}, - {"ui_hitloc_0"}, - {"ui_hitloc_1"}, - {"ui_hitloc_2"}, - {"ui_hitloc_3"}, - {"ui_hitloc_4"}, - {"ui_hitloc_5"}, - {"ui_hitloc_damage_0"}, - {"ui_hitloc_damage_1"}, - {"ui_hitloc_damage_2"}, - {"ui_hitloc_damage_3"}, - {"ui_hitloc_damage_4"}, - {"ui_hitloc_damage_5"}, - {"ui_hud_hardcore"}, - {"ui_hud_obituaries"}, - {"ui_hud_showobjicons"}, - {"ui_inactiveBaseColor"}, - {"ui_inactivePartyColor"}, - {"ui_inhostmigration"}, - {"ui_joinGametype"}, - {"ui_juiced_end_milliseconds"}, - {"ui_killstreak_show_selections"}, - {"ui_killstreak_show_selections_icon_1"}, - {"ui_killstreak_show_selections_icon_2"}, - {"ui_killstreak_show_selections_icon_3"}, - {"ui_mapname"}, - {"ui_mapvote_entrya_gametype"}, - {"ui_mapvote_entrya_mapname"}, - {"ui_mapvote_entryb_gametype"}, - {"ui_mapvote_entryb_mapname"}, - {"ui_maxclients"}, - {"ui_missingMapName"}, - {"ui_mousePitch"}, - {"ui_multiplayer"}, - {"ui_myPartyColor"}, - {"ui_netGametype"}, - {"ui_netGametypeName"}, - {"ui_netSource"}, - {"ui_numteams"}, - {"ui_oldmapname"}, - {"ui_onlineRequired"}, - {"ui_opensummary"}, - {"ui_override_halftime"}, - {"ui_overtime"}, - {"ui_partyFull"}, - {"ui_passiveAbility_name"}, - {"ui_player_blue_eggs"}, - {"ui_player_green_eggs"}, - {"ui_player_money"}, - {"ui_player_perks"}, - {"ui_player_purple_eggs"}, - {"ui_player_red_eggs"}, - {"ui_player_weap1"}, - {"ui_player_weap2"}, - {"ui_player_yellow_eggs"}, - {"ui_playerPartyColor"}, - {"ui_playlistActionButtonAlpha"}, - {"ui_playlistCategoryDisabledColor"}, - {"ui_playlistCategoryEnabledColor"}, - {"ui_playlistPopulationRefreshTime"}, - {"ui_promotion"}, - {"ui_reaper_ammocount"}, - {"ui_reaper_targetdistance"}, - {"ui_regen_faster_end_milliseconds"}, - {"ui_remoteTankUseTime"}, - {"ui_scorelimit"}, - {"ui_selectedFeederMap"}, - {"ui_serverStatusTimeOut"}, - {"ui_showDLCMaps"}, - {"ui_showInfo"}, - {"ui_showList"}, - {"ui_showmap"}, - {"ui_showMenuOnly"}, - {"ui_showMinimap"}, - {"ui_sliderSteps"}, - {"ui_smallFont"}, - {"ui_squad_mode"}, - {"ui_textScrollFadeTime"}, - {"ui_textScrollPauseEnd"}, - {"ui_textScrollPauseStart"}, - {"ui_textScrollSpeed"}, - {"ui_timelimit"}, - {"uiscript_debug"}, - {"use_filtered_query_pass"}, - {"use_weighted_dlc_exactmatch_pass"}, - {"use_weighted_pass"}, - {"useonlinestats"}, - {"useRelativeTeamColors"}, - {"userGroup_active"}, - {"userGroup_cool_off_time"}, - {"userGroup_coop_delay"}, - {"userGroup_max_retry_time"}, - {"userGroup_refresh_time_secs"}, - {"userGroup_retry_step"}, - {"userGroup_RetryTime"}, - {"useStatsGroups"}, - {"useTagFlashSilenced"}, - {"using_mlg"}, - {"validate_apply_clamps"}, - {"validate_apply_revert"}, - {"validate_apply_revert_full"}, - {"validate_clamp_assists"}, - {"validate_clamp_experience"}, - {"validate_clamp_headshots"}, - {"validate_clamp_hits"}, - {"validate_clamp_kills"}, - {"validate_clamp_losses"}, - {"validate_clamp_misses"}, - {"validate_clamp_ties"}, - {"validate_clamp_totalshots"}, - {"validate_clamp_weaponXP"}, - {"validate_clamp_wins"}, - {"validate_drop_on_fail"}, - {"veh_aiOverSteerScale"}, - {"veh_boneControllerLodDist"}, - {"vehAudio_inAirPitchDownLerp"}, - {"vehAudio_inAirPitchUpLerp"}, - {"vehAudio_spawnVolumeTime"}, - {"vehCam_freeLook"}, - {"vehCam_mode"}, - {"vehDroneDebugDrawPath"}, - {"vehHelicopterBoundsRadius"}, - {"vehHelicopterDecelerationFwd"}, - {"vehHelicopterDecelerationSide"}, - {"vehHelicopterDecelerationUp"}, - {"vehHelicopterHeadSwayDontSwayTheTurret"}, - {"vehHelicopterHoverSpeedThreshold"}, - {"vehHelicopterInvertUpDown"}, - {"vehHelicopterJitterJerkyness"}, - {"vehHelicopterLookaheadTime"}, - {"vehHelicopterMaxAccel"}, - {"vehHelicopterMaxAccelVertical"}, - {"vehHelicopterMaxPitch"}, - {"vehHelicopterMaxRoll"}, - {"vehHelicopterMaxSpeed"}, - {"vehHelicopterMaxSpeedVertical"}, - {"vehHelicopterMaxYawAccel"}, - {"vehHelicopterMaxYawRate"}, - {"vehHelicopterPitchOffset"}, - {"vehHelicopterRightStickDeadzone"}, - {"vehHelicopterScaleMovement"}, - {"vehHelicopterSoftCollisions"}, - {"vehHelicopterStrafeDeadzone"}, - {"vehHelicopterTiltFromAcceleration"}, - {"vehHelicopterTiltFromControllerAxes"}, - {"vehHelicopterTiltFromDeceleration"}, - {"vehHelicopterTiltFromFwdAndYaw"}, - {"vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt"}, - {"vehHelicopterTiltFromVelocity"}, - {"vehHelicopterTiltMomentum"}, - {"vehHelicopterTiltSpeed"}, - {"vehHelicopterYawOnLeftStick"}, - {"vehicle_debug_render_spline_plane"}, - {"vehUGVPitchTrack"}, - {"vehUGVRollTrack"}, - {"vehUGVWheelInfluence"}, - {"version"}, - {"vid_xpos"}, - {"vid_ypos"}, - {"viewangNow"}, - {"viewModelDebugNotetracks"}, - {"viewModelHacks"}, - {"viewposNow"}, - {"waypointDebugDraw"}, - {"waypointDistScaleRangeMax"}, - {"waypointDistScaleRangeMin"}, - {"waypointDistScaleSmallest"}, - {"waypointIconHeight"}, - {"waypointIconWidth"}, - {"waypointOffscreenCornerRadius"}, - {"waypointOffscreenDistanceThresholdAlpha"}, - {"waypointOffscreenPadBottom"}, - {"waypointOffscreenPadLeft"}, - {"waypointOffscreenPadRight"}, - {"waypointOffscreenPadTop"}, - {"waypointOffscreenPointerDistance"}, - {"waypointOffscreenPointerHeight"}, - {"waypointOffscreenPointerWidth"}, - {"waypointOffscreenRoundedCorners"}, - {"waypointOffscreenScaleLength"}, - {"waypointOffscreenScaleSmallest"}, - {"waypointPlayerOffsetCrouch"}, - {"waypointPlayerOffsetProne"}, - {"waypointPlayerOffsetStand"}, - {"waypointScreenCenterFadeAdsMin"}, - {"waypointScreenCenterFadeHipMin"}, - {"waypointScreenCenterFadeRadius"}, - {"waypointSplitscreenScale"}, - {"waypointTweakY"}, - {"weap_thermoDebuffMod"}, - {"wideScreen"}, - {"winvoice_loopback"}, - {"winvoice_mic_mute"}, - {"winvoice_mic_outTime"}, - {"winvoice_mic_reclevel"}, - {"winvoice_mic_scaler"}, - {"winvoice_mic_threshold"}, - {"winvoice_save_voice"}, - {"xblive_competitionmatch"}, - {"xblive_hostingprivateparty"}, - {"xblive_loggedin"}, - {"xblive_privatematch"}, - {"xblive_privatematch_solo"}, - {"current_class_location"}, + {"accessToSubscriberContent", "Whether to display the subscriber maps."}, + {"aci", ""}, + {"actionSlotsHide", "Hide the actionslots."}, + {"ai_grenadeReturn_approachMinDot", "Minimal dot product between the approach and throw vectors to perform a grenade return"}, + {"ai_grenadeReturn_debug", "Turns on debug info for AI grenade returns"}, + {"ai_grenadeReturn_extraFuseTime", "The amount of time (in ms) to add to a grenade fuse when trying to return grenade that's below minFuseTime"}, + {"ai_grenadeReturn_minDistSqr", "Minimal distance to a grenade to consider it for a return so that transition anims will play"}, + {"ai_grenadeReturn_minFuseTime", "If the fuse time drops below this value when an ally is attempting to return a grenade, add extra fuse time"}, + {"ai_grenadeReturn_stationary", "If set, AI will attempt to return grenades that they are within pickup distance - regardless of min dist"}, + {"ai_grenadeReturn_traceToGrenade", "If set, AI will only attempt to return grenades when they have a clear sight trace to the grenade"}, + {"ai_threatUpdateInterval", "AI target threat update interval in milliseconds"}, + {"aim_autoaim_enabled", ""}, + {"aim_target_sentient_radius", "The radius used to calculate target bounds for a sentient(actor or player)"}, + {"aimassist_enabled", ""}, + {"ammoCounterHide", "Hide the Ammo Counter"}, + {"armory_contentpacks_enabled", "Allowed armory content packs. 0: none , 1: first armory content pack enabled, 2: first and second armory content pack enabled"}, + {"badHost_detectMinServerTime", "Time in MS before the bad host dection system kicks in after match start"}, + {"badhost_maxDoISuckFrames", "Max lagged frames need to end match"}, + {"band_12players", "12 player bandwidth req'd"}, + {"band_18players", "18 player bandwidth req'd"}, + {"band_2players", "2 player bandwidth req'd"}, + {"band_4players", "4 player bandwidth req'd"}, + {"band_8players", "8 player bandwidth req'd"}, + {"bg_allowScuffFootsteps", "If true, scuff sounds will be played when the player rotates in place."}, + {"bg_bulletExplDmgFactor", "Weapon damage multiplier that will be applied at the center of the slash damage area."}, + {"bg_bulletExplRadius", "The radius of the bullet splash damage, where the damage gradually falls off to 0."}, + {"bg_compassShowEnemies", "Whether enemies are visible on the compass at all times"}, + {"bg_idleSwingSpeed", "The rate at which the player's legs swing around when idle (multi-player only)"}, + {"bg_shieldHitEncodeHeightVM", "The decoding range, in height, of a client's viewmodel shield."}, + {"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."}, + {"bg_shieldHitEncodeWidthVM", "The decoding range, in width, of a client's viewmodel shield."}, + {"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."}, + {"bg_shock_fadeOverride", "Override the time for the shellshock kick effect to fade in MP"}, + {"bg_shock_lookControl", "Alter player control during shellshock"}, + {"bg_shock_lookControl_fadeTime", "The time for the shellshock player control to fade in seconds"}, + {"bg_shock_lookControl_maxpitchspeed", "Maximum pitch movement rate while shellshocked in degrees per second"}, + {"bg_shock_lookControl_maxyawspeed", "Maximum yaw movement rate while shell shocked in degrees per second"}, + {"bg_shock_lookControl_mousesensitivityscale", "Sensitivity scale to apply to a shellshocked player"}, + {"bg_shock_movement", "Affect player's movement speed duringi shellshock"}, + {"bg_shock_screenBlurBlendFadeTime", "The amount of time in seconds for the shellshock effect to fade"}, + {"bg_shock_screenBlurBlendTime", "The amount of time in seconds for the shellshock effect to fade"}, + {"bg_shock_screenFlashShotFadeTime", "In seconds, how soon from the end of the effect to start blending out the whiteout layer."}, + {"bg_shock_screenFlashWhiteFadeTime", "In seconds, how soon from the end of the effect to start blending out the whiteout layer."}, + {"bg_shock_screenType", "Shell shock screen effect type"}, + {"bg_shock_sound", "Play shell shock sound"}, + {"bg_shock_soundDryLevel", "Shell shock sound dry level"}, + {"bg_shock_soundEnd", "Shellshock end sound alias"}, + {"bg_shock_soundEndAbort", "Shellshock aborted end sound alias"}, + {"bg_shock_soundFadeInTime", "Shell shock sound fade in time in seconds"}, + {"bg_shock_soundFadeOutTime", "Shell shock sound fade out time in seconds"}, + {"bg_shock_soundLoop", "Shellshock loop alias"}, + {"bg_shock_soundLoopEndDelay", "Sound loop end offset time from the end of the shellshock in seconds"}, + {"bg_shock_soundLoopFadeTime", "Shell shock sound loop fade time in seconds"}, + {"bg_shock_soundLoopSilent", "The sound that gets blended with the shellshock loop alias"}, + {"bg_shock_soundModEndDelay", "The delay from the end of the shell shock to the end of the sound modification"}, + {"bg_shock_soundRoomType", "Shell shock sound reverb room type"}, + {"bg_shock_soundSubmix", "Shell shock submix to apply"}, + {"bg_shock_soundWetLevel", "Shell shock sound wet level"}, + {"bg_shock_viewKickFadeTime", "The time for the shellshock kick effect to fade"}, + {"bg_shock_viewKickPeriod", "The period of the shellshock view kick effect"}, + {"bg_shock_viewKickRadius", "Shell shock kick radius"}, + {"bg_swingSpeed", "The rate at which the player's legs swing around when idle (multi-player only)"}, + {"bg_torsoSwingSpeed", "The rate at which the player's torso swings around when strafing (multi-player only)"}, + {"boostcheatHeadshotsTotalCoef", ""}, + {"boostcheatHeadshotsTotalMean", ""}, + {"boostcheatHeadshotsTotalStddev", ""}, + {"boostcheatIntercept", ""}, + {"boostcheatKillerXAnomalyCoef", ""}, + {"boostcheatKillerXAnomalyMean", ""}, + {"boostcheatKillerXAnomalyStddev", ""}, + {"boostcheatKillerYAnomalyCoef", ""}, + {"boostcheatKillerYAnomalyMean", ""}, + {"boostcheatKillerYAnomalyStddev", ""}, + {"boostcheatMeanDistanceMostKilledPlayerTraveledMean", ""}, + {"boostcheatMeanDistanceVictimTraveledCoef", ""}, + {"boostcheatMeanDistanceVictimTraveledMean", ""}, + {"boostcheatMeanDistanceVictimTraveledStddev", ""}, + {"boostcheatMeanMostKilledPlayerLifetimeMillisecondsMean", ""}, + {"boostcheatMostKilledPlayerHKRatioCoef", ""}, + {"boostcheatMostKilledPlayerHKRatioMean", ""}, + {"boostcheatMostKilledPlayerHKRatioStddev", ""}, + {"boostcheatMostKilledPlayerKillsRatioCoef", ""}, + {"boostcheatMostKilledPlayerKillsRatioMean", ""}, + {"boostcheatMostKilledPlayerKillsRatioStddev", ""}, + {"boostcheatMostKilledPlayerKillsTotalCoef", ""}, + {"boostcheatMostKilledPlayerKillsTotalMean", ""}, + {"boostcheatMostKilledPlayerKillsTotalStddev", ""}, + {"boostcheatMostKilledPlayerKillTimestampsAnomalyMean", ""}, + {"boostcheatVictimXAnomalyCoef", ""}, + {"boostcheatVictimXAnomalyMean", ""}, + {"boostcheatVictimXAnomalyStddev", ""}, + {"boostcheatVictimYAnomalyCoef", ""}, + {"boostcheatVictimYAnomalyMean", ""}, + {"boostcheatVictimYAnomalyStddev", ""}, + {"bot_DifficultyDefault", "default difficulty level of bots"}, + {"ca_auto_signin", "CoD Anywhere start sign-in task automatically on startup or first party sign-in"}, + {"ca_do_mlc", "CoD Anywhere Do Multi Login check"}, + {"ca_intra_only", "CoD Anywhere Intra Network Only"}, + {"ca_require_signin", "CoD Anywhere require sign in to enter MP"}, + {"ca_show_signup_request", "CoD Anywhere should you show new users a popup requesting they create a CoD Account?"}, + {"camera_thirdPerson", "Use third person view globally"}, + {"cameraShakeRemoteHelo_Angles", "Remote helicopter gunner cam, range to shake the view."}, + {"cameraShakeRemoteHelo_Freqs", "Remote helicopter gunner cam, how fast to shake."}, + {"cameraShakeRemoteHelo_SpeedRange", "Remote helicopter gunner cam, range of missile speed to scale the shaking."}, + {"cameraShakeRemoteMissile_Angles", "Remote missile-cam, range to shake the view."}, + {"cameraShakeRemoteMissile_Freqs", "Remote missile-cam, how fast to shake."}, + {"cameraShakeRemoteMissile_SpeedRange", "Remote missile-cam, range of missile speed to scale the shaking."}, + {"cg_airstrikeCamFstop", "Airstrike kill camera aperture. Lower f-stop yields a shallower depth of field. Typical values range from 1 to 22"}, + {"cg_airstrikeKillCamFarBlur", ""}, + {"cg_airstrikeKillCamFarBlurDist", ""}, + {"cg_airstrikeKillCamFarBlurStart", ""}, + {"cg_airstrikeKillCamFov", "Airstrike kill camera field of view."}, + {"cg_airstrikeKillCamNearBlur", ""}, + {"cg_airstrikeKillCamNearBlurEnd", ""}, + {"cg_airstrikeKillCamNearBlurStart", ""}, + {"cg_blood", "Show Blood"}, + {"cg_bloodThickColor", "Color of the blood overlay's thick blood splatter"}, + {"cg_bloodThinColor", "Color of the blood overlay's thin blood splatter"}, + {"cg_brass", "Weapons eject brass"}, + {"cg_centertime", "The time for a center printed message to fade"}, + {"cg_chatHeight", "The font height of a chat message"}, + {"cg_chatTime", "The amount of time that a chat message is visible"}, + {"cg_ColorBlind_EnemyTeam", "Enemy team color for color blind people"}, + {"cg_ColorBlind_MyParty", "Player party color for color blind people"}, + {"cg_ColorBlind_MyTeam", "Player team color for color blind people"}, + {"cg_connectionIconSize", "Size of the connection icon"}, + {"cg_constantSizeHeadIcons", "Head icons are the same size regardless of distance from the player"}, + {"cg_crosshairAlpha", "The alpha value of the crosshair"}, + {"cg_crosshairAlphaMin", "The minimum alpha value of the crosshair when it fades in"}, + {"cg_crosshairDynamic", "Crosshair is Dynamic"}, + {"cg_crosshairEnemyColor", "The crosshair color when over an enemy"}, + {"cg_crosshairVerticalOffset", "Amount to vertically offset the crosshair from the center."}, + {"cg_cullBulletAngle", "Cull bullet trajectories that don't fall within this fov"}, + {"cg_cullBullets", "Whether to cull bullet fire prediction if trajectory doesn't pass your view or anywhere near you"}, + {"cg_cursorHints", "Draw cursor hints where:\n 0: no hints"}, + {"cg_deadChatWithDead", "If true, dead players can all chat together, regardless of team"}, + {"cg_deadChatWithTeam", "If true, dead players can talk to living players on their team"}, + {"cg_deadHearAllLiving", "If true, dead players can hear all living players talk"}, + {"cg_deadHearTeamLiving", "If true, dead players can hear living players on their team talk"}, + {"cg_descriptiveText", "Draw descriptive spectator messages"}, + {"cg_draw2D", "Draw 2D screen elements"}, + {"cg_drawBreathHint", "Draw a 'hold breath to steady' hint"}, + {"cg_drawBuildName", "Draw build name"}, + {"cg_drawCrosshair", "Turn on weapon crosshair"}, + {"cg_drawCrosshairNames", "Draw the name of an enemy under the crosshair"}, + {"cg_drawCrosshairNamesPosX", ""}, + {"cg_drawCrosshairNamesPosY", ""}, + {"cg_drawDamageDirection", "Draw hit direction arrow."}, + {"cg_drawDamageFlash", "Draw flash when hit."}, + {"cg_drawDoubleTapDetonateHint", "Draw a 'double tap to detonate grenade' hint"}, + {"cg_drawEffectNum", "Draw counts of effects and elements"}, + {"cg_drawFPS", "Draw frames per second"}, + {"cg_drawFPSLabels", "Draw FPS Info Labels"}, + {"cg_drawFriendlyHUDGrenades", "Draw grenade warning indicators for friendly grenades (should be true if friendly-fire is enabled)"}, + {"cg_drawFriendlyNames", "Whether to show friendly names in game"}, + {"cg_drawFriendlyNamesAlways", "Whether to always show friendly names in game (for certain gametypes)"}, + {"cg_drawGun", "Draw the view model"}, + {"cg_drawHealth", "Draw health bar"}, + {"cg_drawMantleHint", "Draw a 'press key to mantle' hint"}, + {"cg_drawMaterial", "Draw debugging information for materials"}, + {"cg_drawpaused", "Draw paused screen"}, + {"cg_drawScriptUsage", "Draw debugging information for scripts"}, + {"cg_drawSnapshot", "Draw debugging information for snapshots"}, + {"cg_drawStatsSource", "Draw stats source"}, + {"cg_drawTalk", "Controls which icons CG_TALKER ownerdraw draws"}, + {"cg_drawTurretCrosshair", "Draw a cross hair when using a turret"}, + {"cg_drawViewpos", "Draw viewpos"}, + {"cg_e3TrailerHacks", "Tweaks for trailer recording"}, + {"cg_equipmentSounds", "Play equipment sounds"}, + {"cg_errordecay", "Decay for predicted error"}, + {"cg_everyoneHearsEveryone", "If true, all players can all chat together, regardless of team or death"}, + {"cg_explosiveKillCamBackDist", "Explosive kill camera: distance of camera backwards from explosive."}, + {"cg_explosiveKillCamGroundBackDist", "Explosive kill camera when stuck to ground: distance of camera backwards from explosive."}, + {"cg_explosiveKillCamGroundUpDist", "Explosive kill camera when stuck to ground: distance of camera backwards from explosive."}, + {"cg_explosiveKillCamStopDecelDist", "Rocket and Grenade Launcher kill camera: distance from player to begin coming to rest"}, + {"cg_explosiveKillCamStopDist", "Rocket and Grenade Launcher kill camera: distance from player to begin coming to rest"}, + {"cg_explosiveKillCamUpDist", "Explosive kill camera: distance of camera backwards from explosive."}, + {"cg_explosiveKillCamWallOutDist", "Explosive kill camera when stuck to wall: distance of camera out from wall."}, + {"cg_explosiveKillCamWallSideDist", "Explosive kill camera when stuck to wall: distance of camera out from wall."}, + {"cg_flashbangNameFadeIn", "Time in milliseconds to fade in friendly names"}, + {"cg_flashbangNameFadeOut", "Time in milliseconds to fade out friendly names"}, + {"cg_foliagesnd_alias", "The sound that plays when an actor or player enters a foliage clip brush."}, + {"cg_footsteps", "Play footstep sounds that are NOT sprint"}, + {"cg_footstepsSprint", "Play sprint footstep sounds"}, + {"cg_fov", "The field of view angle in degrees"}, + {"cg_fovMin", "The minimum possible field of view"}, + {"cg_fovScale", "Scale applied to the field of view"}, + {"cg_friendlyNameFadeIn", "Time in milliseconds to fade in friendly names"}, + {"cg_friendlyNameFadeOut", "Time in milliseconds to fade out friendly names"}, + {"cg_gameBoldMessageWidth", "The maximum character width of the bold game messages"}, + {"cg_gameMessageWidth", "The maximum character width of the game messages"}, + {"cg_gun_x", "Forward position of the viewmodel"}, + {"cg_gun_y", "Right position of the viewmodel"}, + {"cg_gun_z", "Up position of the viewmodel"}, + {"cg_headIconMinScreenRadius", "The minumum radius of a head icon on the screen"}, + {"cg_hearKillerTime", "Duration (in milliseconds) to hear the person you just killed"}, + {"cg_hearVictimEnabled", "If true, you can hear the person you just killed"}, + {"cg_hearVictimTime", "Duration (in milliseconds) to hear the person you just killed"}, + {"cg_heliKillCamFarBlur", ""}, + {"cg_heliKillCamFarBlurDist", ""}, + {"cg_heliKillCamFarBlurStart", ""}, + {"cg_heliKillCamFov", "Helicopter kill camera field of view."}, + {"cg_heliKillCamFstop", "Helicopter kill camera aperture. Lower f-stop yields a shallower depth of field. Typical values range from 1 to 22"}, + {"cg_heliKillCamNearBlur", ""}, + {"cg_heliKillCamNearBlurEnd", ""}, + {"cg_heliKillCamNearBlurStart", ""}, + {"cg_hintFadeTime", "Time in milliseconds for the cursor hint to fade"}, + {"cg_hudChatIntermissionPosition", "Position of the HUD chat box during intermission"}, + {"cg_hudChatPosition", "Position of the HUD chat box"}, + {"cg_hudDamageIconHeight", "The height of the damage icon"}, + {"cg_hudDamageIconInScope", "Draw damage icons when aiming down the sight of a scoped weapon"}, + {"cg_hudDamageIconOffset", "The offset from the center of the damage icon"}, + {"cg_hudDamageIconOverlayTime", "The amount of time (in ms) for the overlay portion of the damage icon to stay on screen"}, + {"cg_hudDamageIconStartFadeTime", "The amount of time (in ms) before the damage icon begins to fade"}, + {"cg_hudDamageIconTime", "The amount of time for the damage icon to stay on screen after damage is taken"}, + {"cg_hudDamageIconWidth", "The width of the damage icon"}, + {"cg_hudGrenadeIconEnabledFlash", "Show the grenade indicator for flash grenades"}, + {"cg_hudGrenadeIconHeight", "The height of the grenade indicator icon"}, + {"cg_hudGrenadeIconInScope", "Show the grenade indicator when aiming down the sight of a scoped weapon"}, + {"cg_hudGrenadeIconMaxRangeFlash", "The minimum distance that a flashbang has to be from a player in order to be shown on the grenade indicator"}, + {"cg_hudGrenadeIconMaxRangeFrag", "The minimum distance that a grenade has to be from a player in order to be shown on the grenade indicator"}, + {"cg_hudGrenadeIconOffset", "The offset from the center of the screen for a grenade icon"}, + {"cg_hudGrenadeIconWidth", "The width of the grenade indicator icon"}, + {"cg_hudGrenadePointerHeight", "The height of the grenade indicator pointer"}, + {"cg_hudGrenadePointerPivot", "The pivot point of th grenade indicator pointer"}, + {"cg_hudGrenadePointerPulseFreq", "The number of times per second that the grenade indicator flashes in Hertz"}, + {"cg_hudGrenadePointerPulseMax", "The maximum alpha of the grenade indicator pulse. Values higher than 1 will cause the indicator to remain at full brightness for longer"}, + {"cg_hudGrenadePointerPulseMin", "The minimum alpha of the grenade indicator pulse. Values lower than 0 will cause the indicator to remain at full transparency for longer"}, + {"cg_hudGrenadePointerWidth", "The width of the grenade indicator pointer"}, + {"cg_hudLegacySplitscreenScale", "Screen scale for hud elements in splitscreen"}, + {"cg_hudLighting_basic_additiveLumOffset", "[basic] Offset applied to additive light color."}, + {"cg_hudLighting_basic_additiveLumScale", "[basic] Scale applied to additive light color."}, + {"cg_hudLighting_basic_additiveOffset", ""}, + {"cg_hudLighting_basic_additiveScale", ""}, + {"cg_hudLighting_basic_ambientLumOffset", "[basic] Offset applied to ambient light color."}, + {"cg_hudLighting_basic_ambientLumScale", "[basic] Scale applied to ambient light color."}, + {"cg_hudLighting_basic_ambientOffset", ""}, + {"cg_hudLighting_basic_ambientScale", ""}, + {"cg_hudLighting_basic_diffuseLumOffset", "[basic] Offset applied to diffuse light color."}, + {"cg_hudLighting_basic_diffuseLumScale", "[basic] Scale applied to diffuse light color."}, + {"cg_hudLighting_basic_diffuseOffset", ""}, + {"cg_hudLighting_basic_diffuseScale", ""}, + {"cg_hudLighting_basic_specExponent", "[basic] Specular exponent. Higher values result in sharper highlights."}, + {"cg_hudLighting_basic_specLumOffset", "[basic] Offset applied to spec light luminance."}, + {"cg_hudLighting_basic_specLumScale", "[basic] Scale applied to spec light luminance."}, + {"cg_hudLighting_basic_specOffset", ""}, + {"cg_hudLighting_basic_specScale", ""}, + {"cg_hudLighting_blood_additiveLumOffset", "[blood] Offset applied to additive light color."}, + {"cg_hudLighting_blood_additiveLumScale", "[blood] Scale applied to additive light color."}, + {"cg_hudLighting_blood_additiveOffset", ""}, + {"cg_hudLighting_blood_additiveScale", ""}, + {"cg_hudLighting_blood_ambientLumOffset", "[blood] Offset applied to ambient light color."}, + {"cg_hudLighting_blood_ambientLumScale", "[blood] Scale applied to ambient light color."}, + {"cg_hudLighting_blood_ambientOffset", ""}, + {"cg_hudLighting_blood_ambientScale", ""}, + {"cg_hudLighting_blood_diffuseLumOffset", "[blood] Offset applied to diffuse light color."}, + {"cg_hudLighting_blood_diffuseLumScale", "[blood] Scale applied to diffuse light color."}, + {"cg_hudLighting_blood_diffuseOffset", ""}, + {"cg_hudLighting_blood_diffuseScale", ""}, + {"cg_hudLighting_blood_specExponent", "[blood] Specular exponent. Higher values result in sharper highlights."}, + {"cg_hudLighting_blood_specLumOffset", "[blood] Offset applied to spec light luminance."}, + {"cg_hudLighting_blood_specLumScale", "[blood] Scale applied to spec light luminance."}, + {"cg_hudLighting_blood_specOffset", ""}, + {"cg_hudLighting_blood_specScale", ""}, + {"cg_hudLighting_fadeSharpness", "This controls how sharp the lines are when fading using the mask alpha. Higher values are sharper."}, + {"cg_hudMapBorderWidth", "The size of the full map's border, filled by the CG_PLAYER_FULLMAP_BORDER ownerdraw"}, + {"cg_hudMapFriendlyHeight", ""}, + {"cg_hudMapFriendlyWidth", ""}, + {"cg_hudMapPlayerHeight", ""}, + {"cg_hudMapPlayerWidth", ""}, + {"cg_hudMapRadarLineThickness", "Thickness, relative to the map width, of the radar texture that sweeps across the full screen map"}, + {"cg_hudObjectiveTextScale", ""}, + {"cg_hudProneY", "Virtual screen y coordinate of the prone blocked message"}, + {"cg_hudSayPosition", "Position of the HUD say box"}, + {"cg_hudSplitscreenCompassElementScale", "Scale value to apply to compass elements in splitscreen"}, + {"cg_hudSplitscreenCompassScale", "Scale value to apply to the compass in splitscreen"}, + {"cg_hudSplitscreenStanceScale", "Scale value to apply to the stance HUD element in splitscreen"}, + {"cg_hudStanceFlash", "The background color of the flash when the stance changes"}, + {"cg_hudVotePosition", "Position of the HUD vote box"}, + {"cg_invalidCmdHintBlinkInterval", "Blink rate of an invalid command hint"}, + {"cg_invalidCmdHintDuration", "Duration of an invalid command hint"}, + {"cg_javelinKillCamCloseZDist", "Javelin kill camera: closest distance above the target."}, + {"cg_javelinKillCamDownDist", "Javelin kill camera: distance to follow during ascent."}, + {"cg_javelinKillCamFov", "Javelin kill camera: fov"}, + {"cg_javelinKillCamLookLerpDist", "Javelin kill camera: distance over which to lerp to look at player during descent. A value of zero means don't lerp at all."}, + {"cg_javelinKillCamPassDist", "Javelin kill camera: distance away when passing."}, + {"cg_javelinKillCamPassTime", "Javelin kill camera: time in seconds to pass javelin on the way up"}, + {"cg_javelinKillCamUpDist", "Javelin kill camera: distance to follow during ascent."}, + {"cg_killCamDefaultLerpTime", "Default time used to lerp between killcam entities."}, + {"cg_killCamTurretLerpTime", "Time used to lerp to a killcam entity of the TURRET type."}, + {"cg_landingSounds", "Play landing on surface sounds"}, + {"cg_largeExplosiveKillCamBackDist", "Large Explosive kill camera: distance of camera backwards from explosive."}, + {"cg_largeExplosiveKillCamUpDist", "Large Explosive kill camera: distance of camera backwards from explosive."}, + {"cg_legacyCrashHandling", ""}, + {"cg_mapLocationSelectionCursorSpeed", "Speed of the cursor when selecting a location on the map"}, + {"cg_marks_ents_player_only", "Marks on entities from players' bullets only."}, + {"cg_minCullBulletDist", "Don't cull bullet trajectories that are within this distance to you."}, + {"cg_objectiveText", ""}, + {"cg_overheadIconSize", "The maximum size to show overhead icons like 'rank'"}, + {"cg_overheadNamesFarDist", "The far distance at which name sizes are scaled by cg_overheadNamesFarScale"}, + {"cg_overheadNamesFarScale", "The amount to scale overhead name sizes at cg_overheadNamesFarDist"}, + {"cg_overheadNamesFont", "Font for overhead names ( see menudefinition.h )"}, + {"cg_overheadNamesGlow", "Glow color for overhead names"}, + {"cg_overheadNamesMaxDist", "The maximum distance for showing friendly player names"}, + {"cg_overheadNamesNearDist", "The near distance at which names are full size"}, + {"cg_overheadNamesSize", "The maximum size to show overhead names"}, + {"cg_overheadRankSize", "The size to show rank text"}, + {"cg_remoteMissileKillCamBackDist", "Remote missile kill camera: distance of camera backwards from rocket."}, + {"cg_remoteMissileKillCamUpDist", "Remote missile kill camera: distance of camera backwards from rocket."}, + {"cg_rocketKillCamBackDist", "Rocket kill camera: distance of camera backwards from rocket."}, + {"cg_rocketKillCamUpDist", "Rocket kill camera: distance of camera backwards from rocket."}, + {"cg_scriptIconSize", "Size of Icons defined by script"}, + {"cg_showmiss", "Show prediction errors"}, + {"cg_sprintMeterDisabledColor", "The color of the sprint meter when the sprint meter is full"}, + {"cg_sprintMeterEmptyColor", "The color of the sprint meter when the sprint meter is full"}, + {"cg_sprintMeterFullColor", "The color of the sprint meter when the sprint meter is full"}, + {"cg_subtitleMinTime", "The minimum time that the subtitles are displayed on screen in seconds"}, + {"cg_subtitleWidthStandard", "The width of the subtitles on a non wide-screen"}, + {"cg_subtitleWidthWidescreen", "The width of the subtitle on a wide-screen"}, + {"cg_teamChatsOnly", "Allow chatting only on the same team"}, + {"cg_TeamColor_Allies", "Allies team color"}, + {"cg_TeamColor_Axis", "Axis team color"}, + {"cg_TeamColor_EnemyTeam", "Enemy team color"}, + {"cg_TeamColor_Free", "Free Team color"}, + {"cg_TeamColor_MyParty", "Player team color when in the same party"}, + {"cg_TeamColor_MyTeam", "Player team color"}, + {"cg_TeamColor_Spectator", "Spectator team color"}, + {"cg_turretKillCamBackDist", "Turret kill camera: distance of camera backwards from Turret."}, + {"cg_turretKillCamFov", "Turret kill camera field of view."}, + {"cg_turretKillCamUpDist", "Turret kill camera: distance of camera backwards from Turret."}, + {"cg_turretRemoteKillCamBackDist", "Remote Turret kill camera: distance of camera backwards from Turret."}, + {"cg_turretRemoteKillCamFov", "Remote Turret kill camera field of view."}, + {"cg_turretRemoteKillCamUpDist", "Remote Turret kill camera: distance of camera backwards from Turret."}, + {"cg_vectorFieldsForceUniform", "Forces all vector field assets to represent a single, uniform direction"}, + {"cg_viewVehicleInfluence", "The influence on the view angles from being in a vehicle"}, + {"cg_viewZSmoothingMax", "Threshhold for the maximum smoothing distance we'll do"}, + {"cg_viewZSmoothingMin", "Threshhold for the minimum smoothing distance it must move to smooth"}, + {"cg_viewZSmoothingTime", "Amount of time to spread the smoothing over"}, + {"cg_voiceIconSize", "Size of the 'voice' icon"}, + {"cg_waterSheeting_distortionScaleFactor", "Distortion uv scales (Default to 1)"}, + {"cg_waterSheeting_magnitude", "Distortion magnitude"}, + {"cg_waterSheeting_radius", "Tweak dev var; Glow radius in pixels at 640x480"}, + {"cg_weapHitCullAngle", "Angle of cone within which to cull back facing weapon hit effects"}, + {"cg_weapHitCullEnable", "When true, cull back facing weapon hit fx."}, + {"cg_weaponCycleDelay", "The delay after cycling to a new weapon to prevent holding down the cycle weapon button from cycling too fast"}, + {"cg_weaponHintsCoD1Style", "Draw weapon hints in CoD1 style: with the weapon name, and with the icon below"}, + {"cg_weaponVisInterval", "Do weapon vis checks once per this many frames, per centity"}, + {"cg_youInKillCamSize", "Size of the 'you' Icon in the kill cam"}, + {"cl_anglespeedkey", "Multiplier for max angle speed for game pad and keyboard"}, + {"cl_bypassMouseInput", "Bypass UI mouse input and send directly to the game"}, + {"cl_connectionAttempts", "Maximum number of connection attempts before aborting"}, + {"cl_connectTimeout", "Timeout time in seconds while connecting to a server"}, + {"cl_demo_uploadfb", "Should we upload to FB"}, + {"cl_dirSelConvergenceTime", "Time to converge to the new direction when selecting a direction on the map."}, + {"cl_force_paused", "Force the client to be paused. Can't be overridden by LUA scripts, the start button, etc."}, + {"cl_freelook", "Enable looking with mouse"}, + {"cl_hudDrawsBehindUI", "Should the HUD draw when the UI is up?"}, + {"cl_ingame", "True if the game is active"}, + {"cl_inhibit_stats_upload", "Inhibit upload of stats during demo playback"}, + {"cl_lessprint", "Print less to the console by filtering out certain spammy channels"}, + {"cl_maxpackets", "Maximum number of packets sent per frame"}, + {"cl_maxPing", "Maximum ping for the client"}, + {"cl_migrationTimeout", "Seconds to wait to hear from new host during host migration before timeout occurs"}, + {"cl_modifiedDebugPlacement", "Modify the location of debug output (outside of safe area)"}, + {"cl_motdString", ""}, + {"cl_mouseAccel", "Mouse acceleration"}, + {"cl_noprint", "Print nothing to the console"}, + {"cl_packetdup", "Enable packet duplication"}, + {"cl_pauseAudioZoneEnabled", "Enable the paused audio zone when the menus are up"}, + {"cl_paused", "Pause the game"}, + {"cl_pitchspeed", "Max pitch speed in degrees for game pad"}, + {"cl_pranks", "pranks"}, + {"cl_pushToTalk", "Do we have to press a button to talk"}, + {"cl_serverStatusResendTime", "Time in milliseconds to resend a server status message"}, + {"cl_showmouserate", "Print mouse rate debugging information to the console"}, + {"cl_textChatEnabled", "Do we want to use text chat"}, + {"cl_timeout", "Seconds with no received packets until a timeout occurs"}, + {"cl_voice", "Use voice communications"}, + {"cl_yawspeed", "Max yaw speed in degrees for game pad and keyboard"}, + {"clientSideEffects", "Enable loading _fx.gsc files on the client"}, + {"cod_anywhere_errorMessage", "CoD Anywhere error message"}, + {"cod_anywhere_showPopup", "Temp Development: Should we show the CoD Anywhere popup"}, + {"cod_anywhere_single_task_popup_text", "CoD Anywhere success message"}, + {"com_animCheck", "Check anim tree"}, + {"com_cinematicEndInWhite", "Set by script. True if cinematic ends with a white screen."}, + {"com_completionResolveCommand", "Command to run when the message box successfully closes"}, + {"com_errorMessage", "Most recent error message"}, + {"com_errorResolveCommand", "Command to run when they close the error box"}, + {"com_filter_output", "Use console filters for filtering output."}, + {"com_maxfps", "Cap frames per second"}, + {"com_maxFrameTime", "Time slows down if a frame takes longer than this many milliseconds"}, + {"com_playerProfile", "Set to the name of the profile"}, + {"com_recommendedSet", ""}, + {"commerce_dl_retry_step", "Step in m/s for the commerce download retry"}, + {"commerce_manifest_file_max_retry_time", "Max time that the commerce manifest can retry"}, + {"commerce_manifest_file_retry_step", "Step in m/s for the commerce manifest retry"}, + {"commerce_max_dl_retry_time", "Max time that the commerce download can retry"}, + {"commerce_max_retry_time", "Max time that the commerce upload can retry"}, + {"commerce_retry_step", "Step in m/s for the commerce upload retry"}, + {"compass", "Display Compass"}, + {"compassClampIcons", "If true, friendlies and enemy pings clamp to the edge of the radar. If false, they disappear off the edge."}, + {"compassCoords", "x = North-South coord base value, \ny = East-West coord base value, \nz = scale (game units per coord unit)"}, + {"compassECoordCutoff", "Left cutoff for the scrolling east-west coords"}, + {"compassFriendlyHeight", ""}, + {"compassFriendlyWidth", ""}, + {"compassHideSansObjectivePointer", "Hide the compass, but leave the obective pointer visible."}, + {"compassHideVehicles", "When enabled, disables the CG_PLAYER_COMPASS_VEHICLES ownerdraw."}, + {"compassMaxRange", "The maximum range from the player in world space that objects will be shown on the compass"}, + {"compassMinRadius", "The minimum radius from the center of the compass that objects will appear."}, + {"compassMinRange", "The minimum range from the player in world space that objects will appear on the compass"}, + {"compassObjectiveArrowHeight", ""}, + {"compassObjectiveArrowOffset", "The offset of the objective arrow inward from the edge of the compass map"}, + {"compassObjectiveArrowRotateDist", "Distance from the corner of the compass map at which the objective arrow rotates to 45 degrees"}, + {"compassObjectiveArrowWidth", ""}, + {"compassObjectiveDetailDist", "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape."}, + {"compassObjectiveDrawLines", "Draw horizontal and vertical lines to the active target, if it is within the minimap boundries"}, + {"compassObjectiveHeight", ""}, + {"compassObjectiveIconHeight", ""}, + {"compassObjectiveIconWidth", ""}, + {"compassObjectiveMaxHeight", "The maximum height that an objective is considered to be on this level"}, + {"compassObjectiveMaxRange", "The maximum range at which an objective is visible on the compass"}, + {"compassObjectiveMinAlpha", "The minimum alpha for an objective at the edge of the compass"}, + {"compassObjectiveMinDistRange", "The distance that objective transition effects play over, centered on compassObjectiveNearbyDist."}, + {"compassObjectiveMinHeight", "The minimum height that an objective is considered to be on this level"}, + {"compassObjectiveNearbyDist", "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape."}, + {"compassObjectiveNumRings", "The number of rings when a new objective appears"}, + {"compassObjectiveRingSize", "The maximum objective ring sige when a new objective appears on the compass"}, + {"compassObjectiveRingTime", "The amount of time between each ring when an objective appears"}, + {"compassObjectiveTextHeight", "Objective text height"}, + {"compassObjectiveTextScale", "Scale to apply to hud objectives"}, + {"compassObjectiveWidth", ""}, + {"compassObjectiveWraparoundTime", "How long it takes for the objective to wrap around the compass from one edge to the other"}, + {"compassPlayerHeight", ""}, + {"compassPlayerWidth", ""}, + {"compassRadarLineThickness", "Thickness, relative to the compass size, of the radar texture that sweeps across the map"}, + {"compassRadarPingFadeTime", "How long an enemy is visible on the compass after it is detected by radar"}, + {"compassRotation", "Style of compass"}, + {"compassSize", "Scale the compass"}, + {"compassSoundPingFadeTime", "The time in seconds for the sound overlay on the compass to fade"}, + {"compassTickertapeStretch", "How far the tickertape should stretch from its center."}, + {"comscore_active", "Are we allowed to enable ComScore tracking or not"}, + {"con_gameMsgWindow0FadeInTime", ""}, + {"con_gameMsgWindow0FadeOutTime", ""}, + {"con_gameMsgWindow0Filter", ""}, + {"con_gameMsgWindow0LineCount", ""}, + {"con_gameMsgWindow0MsgTime", ""}, + {"con_gameMsgWindow0ScrollTime", ""}, + {"con_gameMsgWindow1FadeInTime", ""}, + {"con_gameMsgWindow1FadeOutTime", ""}, + {"con_gameMsgWindow1Filter", ""}, + {"con_gameMsgWindow1LineCount", ""}, + {"con_gameMsgWindow1MsgTime", ""}, + {"con_gameMsgWindow1ScrollTime", ""}, + {"con_gameMsgWindow2FadeInTime", ""}, + {"con_gameMsgWindow2FadeOutTime", ""}, + {"con_gameMsgWindow2Filter", ""}, + {"con_gameMsgWindow2LineCount", ""}, + {"con_gameMsgWindow2MsgTime", ""}, + {"con_gameMsgWindow2ScrollTime", ""}, + {"con_gameMsgWindow3FadeInTime", ""}, + {"con_gameMsgWindow3FadeOutTime", ""}, + {"con_gameMsgWindow3Filter", ""}, + {"con_gameMsgWindow3LineCount", ""}, + {"con_gameMsgWindow3MsgTime", ""}, + {"con_gameMsgWindow3ScrollTime", ""}, + {"con_inputBoxColor", "Color of the console input box"}, + {"con_inputCmdMatchColor", ""}, + {"con_inputDvarInactiveValueColor", ""}, + {"con_inputDvarMatchColor", ""}, + {"con_inputDvarValueColor", ""}, + {"con_inputHintBoxColor", "Color of the console input hint box"}, + {"con_outputBarColor", "Color of the console output slider bar"}, + {"con_outputSliderColor", "Color of the console slider"}, + {"con_outputWindowColor", "Color of the console output"}, + {"con_subtitleLeading", "Leading for subtitles, calculated as a percentage of the font height"}, + {"con_typewriterColorGlowCheckpoint", ""}, + {"con_typewriterColorGlowCompleted", ""}, + {"con_typewriterColorGlowFailed", ""}, + {"con_typewriterColorGlowUpdated", ""}, + {"con_typewriterColorInteriorCheckpoint", ""}, + {"con_typewriterColorInteriorCompleted", ""}, + {"con_typewriterColorInteriorFailed", ""}, + {"con_typewriterColorInteriorUpdated", ""}, + {"con_typewriterDecayDuration", "Time (in milliseconds) to spend disolving the line away."}, + {"con_typewriterDecayStartTime", "Time (in milliseconds) to spend between the build and disolve phases."}, + {"con_typewriterPrintSpeed", "Time (in milliseconds) to print each letter in the line."}, + {"counterDownloadInterval", "Number of minutes before all the global counters are uploaded"}, + {"counterUploadInterval", "Number of minutes before all the global counters are uploaded"}, + {"cpu_speed_12players", "12 player sys_configureGHz req'd"}, + {"cpu_speed_18players", "18 player sys_configureGHz req'd"}, + {"cpu_speed_8players", "8 player sys_configureGHz req'd"}, + {"cSplineDebugRender", "Debug Render the csplines."}, + {"cSplineDebugRenderCorridor", "Debug Render the cspline corridor."}, + {"cSplineDebugRenderData", "Debug Render the cspline data."}, + {"cSplineDebugRenderSplineId", "Select a cspline - 0 for all."}, + {"dailychallenge_killswitch", "daily challenge killswitch - int with bits used to flag individual daily challenges as enabled"}, + {"dailychallenge_killswitch2", "daily challenge killswitch2 - int with bits used to flag 2nd set of individual daily challenges as enabled"}, + {"dailychallenge_period", "daily challenge period - utc value for a day"}, + {"data_validation_allow_drop", ""}, + {"dc_lobbymerge", "Allows lobby merging across data centres"}, + {"dcacheSimulateNoHDD", "When turned on, simulate no HDD for caching."}, + {"dcacheThrottleEnabled", "Enable or disable dcache upload throttling."}, + {"dcacheThrottleKBytesPerSec", "Dcache upload throttle limit in K Bytes per second."}, + {"dedicated_dhclient", "True if we're a client playing on a DH server"}, + {"demonwareConsideredConnectedTime", "Number of milliseconds after being disconnected from demonware before considering shutting down."}, + {"developer", "Enable development options"}, + {"didyouknow", ""}, + {"discard_playerstats_on_suspend", "Forces stats discard on suspend"}, + {"drawEntityCount", "Enable entity count drawing"}, + {"drawEntityCountPos", "Where to draw the entity count graph"}, + {"drawEntityCountSize", "undefined"}, + {"drawKillcamData", "Enable drawing server killcam data"}, + {"drawKillcamDataPos", "Where to draw the server killcam graph"}, + {"drawKillcamDataSize", "How big to draw the killcam data graph"}, + {"drawServerBandwidth", "Enable drawing server bandwidth"}, + {"drawServerBandwidthPos", "Where to draw the server bandwidth graph"}, + {"ds_dcid", "optional datacenter id - from playlist"}, + {"ds_dcid_override", "force datacenter id"}, + {"ds_info", "ds info string"}, + {"ds_info_enable", "Enable ds info string"}, + {"ds_introRequestTimeout", "ds intro request timeout (ms)"}, + {"ds_keepaliveInterval", "ds keepalive interval (ms)"}, + {"ds_keepaliveTimeout", "ds keepalive timeout (ms)"}, + {"ds_pingclient_max_reping_distance", "don't re-ping a datacenter if it's further away than this (miles)"}, + {"ds_pingclient_max_repings", "max # of times to re-ping a datacenter"}, + {"ds_pingclient_maxpings", "max pings to send per datacenter"}, + {"ds_pingclient_maxpings_per_tick", "max new pings each tick"}, + {"ds_pingclient_min_reping_delay", "min msec delay between re-pings"}, + {"ds_pingclient_min_reping_latency", "don't re-ping a datacenter if latency is less than this"}, + {"ds_pingclient_minpings", "min responses required per datacenter"}, + {"ds_pingclient_odsf", "does dsping set odsf flag"}, + {"dsping_dc_0", ""}, + {"dsping_dc_1", ""}, + {"dsping_dc_10", ""}, + {"dsping_dc_11", ""}, + {"dsping_dc_12", ""}, + {"dsping_dc_13", ""}, + {"dsping_dc_14", ""}, + {"dsping_dc_15", ""}, + {"dsping_dc_16", ""}, + {"dsping_dc_17", ""}, + {"dsping_dc_18", ""}, + {"dsping_dc_19", ""}, + {"dsping_dc_2", ""}, + {"dsping_dc_20", ""}, + {"dsping_dc_21", ""}, + {"dsping_dc_22", ""}, + {"dsping_dc_23", ""}, + {"dsping_dc_24", ""}, + {"dsping_dc_25", ""}, + {"dsping_dc_26", ""}, + {"dsping_dc_27", ""}, + {"dsping_dc_28", ""}, + {"dsping_dc_29", ""}, + {"dsping_dc_3", ""}, + {"dsping_dc_30", ""}, + {"dsping_dc_31", ""}, + {"dsping_dc_32", ""}, + {"dsping_dc_33", ""}, + {"dsping_dc_34", ""}, + {"dsping_dc_35", ""}, + {"dsping_dc_36", ""}, + {"dsping_dc_37", ""}, + {"dsping_dc_38", ""}, + {"dsping_dc_39", ""}, + {"dsping_dc_4", ""}, + {"dsping_dc_40", ""}, + {"dsping_dc_41", ""}, + {"dsping_dc_42", ""}, + {"dsping_dc_43", ""}, + {"dsping_dc_44", ""}, + {"dsping_dc_45", ""}, + {"dsping_dc_46", ""}, + {"dsping_dc_47", ""}, + {"dsping_dc_48", ""}, + {"dsping_dc_49", ""}, + {"dsping_dc_5", ""}, + {"dsping_dc_50", ""}, + {"dsping_dc_51", ""}, + {"dsping_dc_52", ""}, + {"dsping_dc_53", ""}, + {"dsping_dc_54", ""}, + {"dsping_dc_55", ""}, + {"dsping_dc_56", ""}, + {"dsping_dc_57", ""}, + {"dsping_dc_58", ""}, + {"dsping_dc_59", ""}, + {"dsping_dc_6", ""}, + {"dsping_dc_60", ""}, + {"dsping_dc_61", ""}, + {"dsping_dc_62", ""}, + {"dsping_dc_63", ""}, + {"dsping_dc_7", ""}, + {"dsping_dc_8", ""}, + {"dsping_dc_9", ""}, + {"dvl", "Enables the data validation system. Only available in non-retail builds."}, + {"dw_addrHandleTimeout", "Delay before destroying an addrHandle after the connection is lost\n"}, + {"dw_leaderboard_write_active", "Are leaderboard writes enabled"}, + {"dw_presence_active", "Is the demonware presence system enabled"}, + {"dw_presence_coop_join_active", "Do we allow players to join on presence for private coop matches (post session to demonware"}, + {"dw_presence_get_delay", "Number of milliseconds to wait after booting the game to fetch demonware presence"}, + {"dw_presence_get_rate", "Number of milliseconds to wait between sending presence state to demonware"}, + {"dw_presence_put_delay", "Number of milliseconds to wait in a presence state before sending to demonware"}, + {"dw_presence_put_rate", "Number of milliseconds to wait between sending presence state to demonware"}, + {"dw_region_lookup_timeout", "Timeout (in MS) after which we will accept not having found a region code and use the default"}, + {"dw_shared_presence_active", "Is the demonware shared presence system enabled"}, + {"dw_shared_presence_get_delay", "Number of milliseconds to wait after booting the game to fetch demonware presence"}, + {"dw_shared_presence_get_rate", "Number of milliseconds to wait between sending presence state to demonware"}, + {"dw_shared_presence_put_delay", "Number of milliseconds to wait in a shared presence state before sending to demonware"}, + {"dw_shared_presence_put_rate", "Number of milliseconds to wait between sending presence state to demonware"}, + {"dwBandwidthTestTaskTimeout", "default timeout for the bandwidth test task (in ms). 0 means no timeout"}, + {"dynEnt_active", "Disable/enable dynent reactions"}, + {"dynEnt_playerWakeUpRadius", "Determines threshold distance from player within which all dynents are woken up."}, + {"dynEnt_playerWakeUpZOffset", "Determines vertical distance from player's feet from which wake up sphere is centered."}, + {"elite_clan_active", "Are we allowed to show Elite Clans or not"}, + {"elite_clan_cool_off_time", "Cool off time between calls to fetch the elite clan"}, + {"elite_clan_delay", "Delay before the bdTeams calls start to Demonware. -1 means On-Demand and it will wait until the 'starteliteclan' menu call"}, + {"elite_clan_division_icon_active", "Are we allowed to show Elite Clan division icon or not"}, + {"elite_clan_get_blob_profile_max_retry_time", "Max time that the Elite Clan get private profile can retry"}, + {"elite_clan_get_blob_profile_retry_step", "Step in m/s for the Elite Clan get private profile retry"}, + {"elite_clan_get_clan_max_retry_time", "Max time that the Elite Clan get clan can retry"}, + {"elite_clan_get_clan_retry_step", "Step in m/s for the Elite Clan get clan retry"}, + {"elite_clan_get_members_max_retry_time", "Max time that the Elite Clan get members can retry"}, + {"elite_clan_get_members_retry_step", "Step in m/s for the Elite Clan get members retry"}, + {"elite_clan_get_private_member_profile_max_retry_time", "Max time that the Elite Clan get private profile can retry"}, + {"elite_clan_get_private_member_profile_retry_step", "Step in m/s for the Elite Clan get private profile retry"}, + {"elite_clan_get_public_profile_max_retry_time", "Max time that the Elite Clan get public profile can retry"}, + {"elite_clan_get_public_profile_retry_step", "Step in m/s for the Elite Clan get public profile retry"}, + {"elite_clan_get_team_stats_max_retry_time", "Max time that the Elite Clan get team stats can retry"}, + {"elite_clan_get_team_stats_retry_step", "Step in m/s for the Elite Clan get team stats retry"}, + {"elite_clan_motd_throttle_time", "Throttle time between motd update calls"}, + {"elite_clan_remote_view_active", "Are we allowed to view the clans for remote players"}, + {"elite_clan_remote_view_max_retry_time", "Max time that the Elite Clan remote viewing can retry"}, + {"elite_clan_remote_view_retry_step", "Step in m/s for the retry for viewing a remote Elite Clan"}, + {"elite_clan_send_message_to_members_max_retry_time", "Max time that the Elite Clan send message to members can retry"}, + {"elite_clan_send_message_to_members_retry_step", "Step in m/s for the Elite Clan send message to members retry"}, + {"elite_clan_set_private_member_profile_max_retry_time", "Max time that the Elite Clan set private member profile can retry"}, + {"elite_clan_set_private_member_profile_retry_step", "Step in m/s for the Elite Clan set private member profile retry"}, + {"elite_clan_single_task_popup_text", "String to be displayed on popup when a single task is being performed"}, + {"elite_clan_using_title", "Stores whether the Elite Clan title is in use by the user"}, + {"emblems_active", "Are we allowed to enable Emblems or not"}, + {"enable_recordRecentActivity", "records the timestamp of when the player was recently active to the tracker leaderboards"}, + {"enableReportingRegisteredParties", "If true then party membership data and host status will be reported in matchdata blob."}, + {"entitlements_active", "Are we allowed to show Entitlements or not"}, + {"entitlements_config_file_max_retry_time", "Max time that the Entitlements config file read can retry"}, + {"entitlements_config_file_retry_step", "Step in m/s for the Entitlements config file read retry"}, + {"entitlements_cool_off_time", "Cool off time between calls to fetch the elite clan"}, + {"entitlements_delay", "Delay before the entitlement calls start to Demonware. -1 means On-Demand and it will wait until the 'startentitlements' menu call"}, + {"entitlements_key_archive_max_retry_time", "Max time that the Entitlements key archive read can retry"}, + {"entitlements_key_archive_retry_step", "Step in m/s for the Entitlements key archive read retry"}, + {"entitlementSystemOk", "Set by the game to inform that the entitlement system is initialised"}, + {"facebook_active", "Are we allowed to show Facebook or not"}, + {"facebook_delay", "Delay before the Facebook calls start to Demonware. -1 means On-Demand and it will wait until the 'startfacebook' menu call"}, + {"facebook_friends_active", "Are we allowed to show Facebook Friends or not"}, + {"facebook_friends_max_retry_time", "Max time that the Facebook friends read can retry"}, + {"facebook_friends_refresh_time", "Time in seconds between Facebook friend refreshes"}, + {"facebook_friends_retry_step", "Step in m/s for the Facebook friends read retry"}, + {"facebook_friends_showing_count", "Contains how many facebook friends are being shown in the UI."}, + {"facebook_friends_throttle_time", "Throttle time between Facebook friend pages"}, + {"facebook_max_retry_time", "Max time that the Facebook authentication can retry"}, + {"facebook_password", "Facebook Password"}, + {"facebook_password_asterisk", "Facebook Password (Asterisk Version)"}, + {"facebook_popup_text", "Facebook Popup Text"}, + {"facebook_retry_step", "Step in m/s for the Facebook authentication retry"}, + {"facebook_upload_photo_active", "Are we allowed to Upload Photos to Facebook or not"}, + {"facebook_upload_video_active", "Are we allowed to Upload Videos to Facebook or not"}, + {"facebook_username", "Facebook Username"}, + {"fixedtime", "Use a fixed time rate for each frame"}, + {"FoFIconMaxSize", "Maximum size a Friend-or-Foe icon should ever grow to."}, + {"FoFIconMinSize", "Minimum size a Friend-or-Foe icon should ever shrink to."}, + {"FoFIconScale", "Base scale of Friend-or-Foe icons."}, + {"FoFIconSpawnTimeDelay", "How long to wait, after spawning, before showing the Friend-or-Foe icon on a player."}, + {"FoFIconSpawnTimeFade", "Length of the Friend-or-Foe icons' fade-ins."}, + {"friendsCacheSteamFriends", "Use cache of steam friends before querying steam api"}, + {"friendsMaxSteamLookupsPerFrame", "Number of steam friends to query steam status per frame when doing a refresh.\n"}, + {"friendsWidgetMinimumRefreshTimer", "Minimum delay before refreshing friends data if you aren't on the friends screen\n"}, + {"fs_basegame", "Base game name"}, + {"fs_basepath", "Base game path"}, + {"fs_basepath_output", "Base game path"}, + {"fs_cdpath", "CD path"}, + {"fs_copyfiles", "Copy all used files to another location"}, + {"fs_debug", "Enable file system debugging information"}, + {"fs_game", "Game data directory. Must be \"\" or a sub directory of 'mods/'."}, + {"fs_homepath", "Game home path"}, + {"fs_ignoreLocalized", "Ignore localized assets"}, + {"fx_alphaThreshold", "Don't draw billboard sprites, oriented sprites or tails with alpha below this threshold (0-256)."}, + {"fx_cast_shadow", "Enable transparency shadow mapping from script"}, + {"fx_count", "Debug effects count"}, + {"fx_cull_elem_draw", "Culls effect elems for drawing"}, + {"fx_cull_elem_draw_flicker", "Flicker DPVS culled effect elems"}, + {"fx_cull_elem_spawn", "Culls effect elems for spawning"}, + {"fx_debugBolt", "Debug effects bolt"}, + {"fx_deferelem", "Toggles deferred processing of elements instead of effects"}, + {"fx_dpvs_cull_elem_draw", "Culls effect elems for drawing using DPVS(2: ignore per-effect portal culling flag)"}, + {"fx_draw", ""}, + {"fx_draw_omniLight", ""}, + {"fx_draw_simd", "Draw effects using SIMD / Vector code."}, + {"fx_draw_spotLight", ""}, + {"fx_drawClouds", "Toggles the drawing of particle clouds"}, + {"fx_enable", "Toggles all effects processing"}, + {"fx_flare", "Toggles fx flare"}, + {"fx_freeze", "Freeze effects"}, + {"fx_killEffectOnRewind", "Causes effects that have been marked for a soft kill (fade out) to be killed immediately on a rewind."}, + {"fx_lightGridSampleOffset", "the length of effect sample's offset along X Axis"}, + {"fx_mark_profile", "Turn on FX profiling for marks (specify which local client, with '1' being the first.)"}, + {"fx_marks", "Toggles whether bullet hits leave marks"}, + {"fx_marks_ents", "Toggles whether bullet hits leave marks"}, + {"fx_marks_nearlimit", "Sets limit of number of decals that can exist at the same location (0 for unlimited)"}, + {"fx_marks_smodels", "Toggles whether bullet hits leave marks"}, + {"fx_physicsImpactVelocityThreshold", "Set the min normal velocity threshold in order for model physics fx to generate child impact effects."}, + {"fx_profile", "Turn on FX profiling (specify which local client, with '1' being the first.)"}, + {"fx_profileFilter", "Only show effects with this as a substring in FX profile"}, + {"fx_profileFilterElemCountZero", "Do not include FX that have a zero element count"}, + {"fx_profileSkip", "Skip the first n lines in FX profile (to see ones off bottom of screen)"}, + {"fx_profileSort", "Choose sort criteria for FX profiling"}, + {"fx_showLightGridSampleOffset", "show light grid sample offset in CreateFX mode"}, + {"fx_visMinTraceDist", "Minimum visibility trace size"}, + {"g_allowVote", "Enable voting on this server"}, + {"g_atmosFogDistanceScaleReadOnly", "scale applied to scene distance used for atmospheric fog calculation"}, + {"g_atmosFogEnabledReadOnly", "use atmospheric fog"}, + {"g_atmosFogExtinctionStrengthReadOnly", "scale out scatter contribution of atmospheric fog"}, + {"g_atmosFogHalfPlaneDistanceReadOnly", "distance at which atmospheric fog contributes half the pixels color"}, + {"g_atmosFogHazeSpreadReadOnly", "directionality of haze (1ReadOnly = all forward scatter, 0ReadOnly = all back scatter)"}, + {"g_atmosFogHazeStrengthReadOnly", "portion of atmospheric fog density that is haze (0ReadOnly = all fog, 1ReadOnly = all haze)"}, + {"g_atmosFogHeightFogBaseHeightReadOnly", "height fog is full density at this world height and below"}, + {"g_atmosFogHeightFogEnabledReadOnly", "use height for atmospheric fog"}, + {"g_atmosFogHeightFogHalfPlaneDistanceReadOnly", "at this distance above g_atmosFogHeightFogBaseHeight, height fog density is half"}, + {"g_atmosFogInScatterStrengthReadOnly", "scale in scatter contribution of atmospheric fog"}, + {"g_atmosFogSkyAngularFalloffEnabledReadOnly", "use angular sky falloff for atmospheric fog"}, + {"g_atmosFogSkyDistanceReadOnly", "distance used for sky box when applying atmospheric fog"}, + {"g_atmosFogSkyFalloffAngleRangeReadOnly", "sky fog angular falloff angle range sky fog falls off over this range from the start angle"}, + {"g_atmosFogSkyFalloffStartAngleReadOnly", "sky fog angular falloff start angle (full strength fog at this angle)"}, + {"g_atmosFogStartDistanceReadOnly", "distance from camera at which fog contribution begins"}, + {"g_atmosFogSunDirectionReadOnly", "sun direction used when calculating atmospheric fog"}, + {"g_banIPs", "IP addresses to ban from playing"}, + {"g_clonePlayerMaxVelocity", "Maximum velocity in each axis of a cloned player\n(for death animations)"}, + {"g_deadChat", "Allow dead players to chat with living players"}, + {"g_dropForwardSpeed", "Forward speed of a dropped item"}, + {"g_dropHorzSpeedRand", "Random component of the initial horizontal speed of a dropped item"}, + {"g_dropUpSpeedBase", "Base component of the initial vertical speed of a dropped item"}, + {"g_dropUpSpeedRand", "Random component of the initial vertical speed of a dropped item"}, + {"g_earthquakeEnable", "Enable camera shake"}, + {"g_fogColorIntensityReadOnly", "HDR fog color intensity that was set in the most recent call to \"setexpfog\""}, + {"g_fogColorReadOnly", "Fog color that was set in the most recent call to \"setexpfog\""}, + {"g_fogHalfDistReadOnly", ""}, + {"g_fogMaxOpacityReadOnly", "Fog max opacity that was set in the most recent call to \"setexpfog\""}, + {"g_fogStartDistReadOnly", ""}, + {"g_friendlyfireDist", "Maximum range for disabling fire at a friendly"}, + {"g_friendlyNameDist", "Maximum range for seeing a friendly's name"}, + {"g_gametype", "The current game mode"}, + {"g_giveAll", "Give all weapons"}, + {"g_hardcore", "Hardcore?"}, + {"g_heightFogBaseHeightReadOnly", "height fog is full density at this world height and below"}, + {"g_heightFogEnabledReadOnly", "use height for normal/sun fog, set in the most recent call to \"setexpfog\""}, + {"g_heightFogHalfPlaneDistanceReadOnly", "at this distance above g_heightFogBaseHeight, height fog density is half, set in the most recent call to \"setexpfog\""}, + {"g_inactivity", "Time delay before player is kicked for inactivity"}, + {"g_keyboarduseholdtime", "The time to hold down the 'use' button to activate a 'use' command on a keyboard"}, + {"g_knockback", "Maximum knockback"}, + {"g_lagged_damage_threshold", "Threshold (ms) beyond which we will report a damaged lagged client to the tracker leaderboards."}, + {"g_listEntity", "List the entities"}, + {"g_mantleBlockTimeBuffer", "Time that the client think is delayed after mantling"}, + {"g_maxDroppedWeapons", "Maximum number of dropped weapons"}, + {"g_minGrenadeDamageSpeed", "Minimum speed at which getting hit be a grenade will do damage (not the grenade explosion damage)"}, + {"g_oldschool", "Oldschool?"}, + {"g_password", "Password"}, + {"g_playerCollisionEjectSpeed", "Speed at which to push intersecting players away from each other"}, + {"g_ScoresColor_Allies", "Allies team color on scoreboard"}, + {"g_ScoresColor_Axis", "Axis team color on scoreboard"}, + {"g_ScoresColor_EnemyTeam", "Enemy team color on scoreboard"}, + {"g_ScoresColor_Free", "Free Team color on scoreboard"}, + {"g_ScoresColor_MyParty", "Player team color on scoreboard when in the same party"}, + {"g_ScoresColor_MyTeam", "Player team color on scoreboard"}, + {"g_ScoresColor_Spectator", "Spectator team color on scoreboard"}, + {"g_scriptMainMenu", ""}, + {"g_sunFogBeginFadeAngleReadOnly", "Angle from the sun direction to start fade away from the sun fog color that was set in the most recent call to \"setexpfog\""}, + {"g_sunFogColorIntensityReadOnly", "HDR sun fog color intensity that was set in the most recent call to \"setexpfog\""}, + {"g_sunFogColorReadOnly", "Sun fog color that was set in the most recent call to \"setexpfog\""}, + {"g_sunFogDirReadOnly", "Sun fog direction that was set in the most recent call to \"setexpfog\""}, + {"g_sunFogEnabledReadOnly", "Sun fog was enabled in the most recent call to \"setexpfog\""}, + {"g_sunFogEndFadeAngleReadOnly", "Angle from the sun direction to end fade away from the sun fog color that was set in the most recent call to \"setexpfog\""}, + {"g_sunFogScaleReadOnly", "Distance scale in the sun fog direction that was set in the most recent call to \"setexpfog\""}, + {"g_TeamIcon_Allies", "Icon name for the allied scores banner"}, + {"g_TeamIcon_Axis", "Icon name for the axis scores banner"}, + {"g_TeamIcon_EnemyAllies", "Icon name for the allied scores banner"}, + {"g_TeamIcon_EnemyAxis", "Icon name for the axis scores banner when you're on axis."}, + {"g_TeamIcon_Free", "Icon name for the scores of players with no team"}, + {"g_TeamIcon_MyAllies", "Icon name for the allied scores banner"}, + {"g_TeamIcon_MyAxis", "Icon name for the axis scores banner when you're on axis."}, + {"g_TeamIcon_Spectator", "Icon name for the scores of players who are spectators"}, + {"g_TeamName_Allies", "Allied team name"}, + {"g_TeamName_Axis", "Axis team name"}, + {"g_TeamTitleColor_EnemyTeam", "Enemy team color for titles"}, + {"g_TeamTitleColor_MyTeam", "Player team color for titles"}, + {"g_TeamTitleColor_Spectator", "Spectator team color for titles"}, + {"g_useholdspawndelay", "Time in milliseconds that the player is unable to 'use' after spawning"}, + {"g_useholdtime", "Time to hold the 'use' button to activate use on a gamepad"}, + {"g_voiceChatTalkingDuration", "Time after the last talk packet was received that the player is considered by the\nserver to still be talking in milliseconds"}, + {"gamedate", "The date compiled"}, + {"gamedvr_active", "Are we allowed to enable GameDVR or not"}, + {"gameMode", "Current gameMode"}, + {"gamename", "The name of the game"}, + {"glass_angular_vel", "Sets the range of angular velocities used by new glass pieces"}, + {"glass_beamDamage", "The amount of damage beam attacks do to glass"}, + {"glass_break", "Toggle whether or not glass breaks when shot"}, + {"glass_crack_pattern_scale", "The scale applied to the radius used for the crack pattern"}, + {"glass_damageToDestroy", "The amount of damage a piece of glass must take to look damaged"}, + {"glass_damageToWeaken", "The amount of damage a piece of glass must take to look damaged"}, + {"glass_edge_angle", "Sets the range of angle deflections used by new glass pieces on a supported edge"}, + {"glass_fall_delay", "Sets how long a heavy piece supported by a single edge waits before falling, based on glass_fall_ratio"}, + {"glass_fall_gravity", "Gravity for falling pieces of glass"}, + {"glass_fall_ratio", "Ratio of piece area to supporting edge length squared. Below the min, the piece never falls."}, + {"glass_fringe_maxcoverage", "The maximum portion of the original piece of glass that is allowed to remain after the glass shatters"}, + {"glass_fringe_maxsize", "The maximum area for an edge piece of glass when shattering. Pieces larger than this will be broken into smaller ones"}, + {"glass_fx_chance", "Chance to play an effect on a small piece of glass when it hits the ground"}, + {"glass_hinge_friction", "Friction used by moving glass pieces when joined like a hinge to a frame"}, + {"glass_linear_vel", "Sets the range of linear velocities used by new glass pieces"}, + {"glass_max_pieces_per_frame", "Maximum number of pieces to create in one frame. This is a guideline and not a hard limit."}, + {"glass_max_shatter_fx_per_frame", "Maximum number of shatter effects to play in one frame This is a guideline and not a hard limit."}, + {"glass_meleeDamage", "The amount of damage melee attacks do to glass"}, + {"glass_physics_chance", "The chance for a given shard of glass to use physics"}, + {"glass_physics_maxdist", "The maximum distance of a glass piece from the player to do physics"}, + {"glass_radiusDamageMultiplier", "The amount to scale damage to glass from grenades and other explosions"}, + {"glass_shard_maxsize", "The maximum area for a flying piece of glass when shattering. Pieces larger than this will be broken into smaller ones"}, + {"glass_shattered_scale", "The scale of the shattered glass material"}, + {"glass_trace_interval", "The length of time, in milliseconds, between glass piece traces"}, + {"gpad_button_deadzone", "Game pad button deadzone threshhold"}, + {"gpad_dpadDebounceTime", ""}, + {"gpad_menu_scroll_delay_first", "Menu scroll key-repeat delay, for the first repeat, in milliseconds"}, + {"gpad_menu_scroll_delay_rest_accel", "Menu scroll key-repeat delay acceleration from start to end, for repeats after the first, in milliseconds per repeat"}, + {"gpad_menu_scroll_delay_rest_end", "Menu scroll key-repeat delay end, for repeats after the first, in milliseconds"}, + {"gpad_menu_scroll_delay_rest_start", "Menu scroll key-repeat delay start, for repeats after the first, in milliseconds"}, + {"gpad_stick_deadzone_max", "Game pad maximum stick deadzone"}, + {"gpad_stick_deadzone_min", "Game pad minimum stick deadzone"}, + {"gpad_stick_pressed", "Game pad stick pressed threshhold"}, + {"gpad_stick_pressed_hysteresis", "Game pad stick pressed no-change-zone around gpad_stick_pressed to prevent bouncing"}, + {"groupDownloadInterval", "Minimum interval to wait before getting new group counts"}, + {"groupUploadInterval", "Minimum interval to wait before setting new group counts"}, + {"heli_barrelMaxVelocity", ""}, + {"heli_barrelRotation", "How much to rotate the turret barrel when a helicopter fires"}, + {"heli_barrelSlowdown", ""}, + {"hiDef", "True if the game video is running in high-def."}, + {"httpnetfs", "Stream fastfiles from the specified http server"}, + {"hud_bloodOverlayLerpRate", "Rate at which blood overlay fades out"}, + {"hud_deathQuoteFadeTime", "The time for the death quote to fade"}, + {"hud_drawHud", ""}, + {"hud_enable", "Enable hud elements"}, + {"hud_fade_ammodisplay", "The time for the ammo display to fade in seconds"}, + {"hud_fade_compass", "The time for the compass to fade in seconds"}, + {"hud_fade_healthbar", "The time for the health bar to fade in seconds"}, + {"hud_fade_offhand", "The time for the offhand weapons to fade in seconds"}, + {"hud_fade_sprint", "The time for the sprint meter to fade in seconds"}, + {"hud_flash_period_offhand", "Offhand weapons flash period on changing weapon"}, + {"hud_flash_time_offhand", "Offhand weapons flash duration on changing weapon"}, + {"hud_health_pulserate_critical", "The pulse rate of the 'critical' pulse effect"}, + {"hud_health_pulserate_injured", "The pulse rate of the 'injured' pulse effect"}, + {"hud_health_startpulse_critical", "The health level at which to start the 'injured' pulse effect"}, + {"hud_health_startpulse_injured", "The health level at which to start the 'injured' pulse effect"}, + {"hudElemPausedBrightness", "Brightness of the hudelems when the game is paused."}, + {"hudOutlineDuringADS", "Turn on the HUD outline (green for friendly, red for enemy) when you are pointing at a player while in ADS."}, + {"igs_config_dw_filename", "Name of the configuration file on DW Publisher storage."}, + {"igs_sosp", "Show Original Season Pass"}, + {"igs_td", "Show Trial DLC"}, + {"igs_version", "Version id for the In-game store. Set version number to 0, to disable update."}, + {"in_mouse", "Initialize the mouse drivers"}, + {"inpubliclobby", "Currently in a public lobby"}, + {"intro", "Intro movie should play"}, + {"inventory_addEntitlementsToLocalInventory", "bypass the exchange and directly add entitlements to the local cached player inventory."}, + {"inventory_enabled", "enable/disable the inventory feature"}, + {"inventory_enableEntitlementDLCScanning", "enable scanning of entitlement DLC."}, + {"inventory_enableRevoke", "Enable revoke on purchases you no longer have rights to."}, + {"inventory_exchangeEnabled", "enable/disable the 1st party exchange feature"}, + {"inventory_exchangeMaxConsumablesPerBoot", "The maximum number of the same consumable that can be added per boot."}, + {"inventory_exchangeRetryBaseMS", "The amount to delay with each subsequent retry as base value to be multiplied by an exponential factor 1000 = (1000, 2000, 4000, 8000 etc.)"}, + {"inventory_exchangeRetryByRound", "enable/disable retry with exponential delay one round of exchanges at a time (1, 2, 3, 1, 2, 3, 1, 2, 3 etc.), vs exponential delay per exchange (1, 1, 1, 2, 2, 2, 3, 3, 3 etc.)"}, + {"inventory_exchangeRetryMax", "The number of times to retry for each exchange."}, + {"inventory_excludeEntitlementDLCScanning", "exclude scanning of entitlement DLC (comma separated list of ids to exclude)."}, + {"inventory_ignoreDWPushNotification_claimAchievement", "ignore incoming push notifications from DW to signal item update"}, + {"inventory_ignoreDWPushNotification_itemUpdate", "ignore incoming push notifications from DW to signal item update"}, + {"inventory_taskDefaultTimeout", "default timeout for inventory tasks (in seconds)"}, + {"inventory_taskExchangeTimeout", "default timeout for inventory exchange tasks (in seconds)"}, + {"inventory_taskGetTimeout", "default timeout for inventory GET tasks (in seconds)"}, + {"inventory_triggerExchangeOnContentMount", "trigger an exchange after mounting new content packs"}, + {"inventory_triggerExchangeOnStoreExit", "trigger an exchange when exiting the store"}, + {"iotd_active", "Is the IOTD system enabled"}, + {"iotd_retry", "Can the IOTD system retry fetching data from Demonware"}, + {"jump_slowdownEnable", "Slow player movement after jumping"}, + {"laserDebug", "Enables the display of various debug info."}, + {"laserLightRadius", "undefined"}, + {"laserRadius", "undefined"}, + {"lb_filter", "Filter applied to the leaderboard display: ('none','friends','facebook_friends')"}, + {"lb_group", "GroupID applied to the leaderboard display"}, + {"lb_maxrows", "Maximum number of rows to fetch"}, + {"lb_minrefresh", "Minimum time (in seconds) between leaderboard fetches"}, + {"lb_readDelay", "Delay time between reads(in milliseconds) between leaderboard fetches"}, + {"lb_throttle_time", "Lobby throttling amount"}, + {"lb_times_in_window", "Lobby throttling window amount"}, + {"lb_window", "Lobby throttling window"}, + {"live_qosec_firstupdatems", "MS to wait before deciding to early out qos"}, + {"live_qosec_lastupdatems", "MS since last update required to early out qos"}, + {"live_qosec_minpercent", "Minimum percentage of probe results required before early outing qos"}, + {"live_qosec_minprobes", "Minimum probe results required before early outing qos"}, + {"liveanticheatunknowndvar", "Live Anti Cheat Unknown Dvar"}, + {"livestreaming_active", "Are we allowed to enable LiveStreaming or not"}, + {"loading_sre_fatal", "Loading errors prevent level from loading."}, + {"lobby_animationSpeed", "How long each frame of the animation should draw, in milliseconds"}, + {"lobby_animationTilesHigh", "How many animation tiles high is the searching_for_player texture"}, + {"lobby_animationTilesWide", "How many animation tiles wide is the searching_for_player texture"}, + {"lobby_numAnimationFrames", "How many animation tiles are in the searching_for_player texture"}, + {"lobby_searchingPartyColor", "The color to show that we're searching for that slot when shown in lobbies"}, + {"loc_language", "Language"}, + {"loc_translate", "Enable translations"}, + {"log_host_migration_chance", "The % chance of host migration results telemetry"}, + {"log_party_state", "Log party state updates to Black Box system"}, + {"logger_dev", ""}, + {"lowAmmoWarningColor1", "Color 1 of 2 to oscilate between"}, + {"lowAmmoWarningColor2", "Color 2 of 2 to oscilate between"}, + {"lowAmmoWarningNoAmmoColor1", "Like lowAmmoWarningColor1, but when no ammo."}, + {"lowAmmoWarningNoAmmoColor2", "lowAmmoWarningColor2, but when no ammo."}, + {"lowAmmoWarningNoReloadColor1", "Like lowAmmoWarningColor1, but when no ammo."}, + {"lowAmmoWarningNoReloadColor2", "lowAmmoWarningColor2, but when no ammo."}, + {"lowAmmoWarningPulseFreq", "Frequency of the pulse (oscilation between the 2 colors)"}, + {"lowAmmoWarningPulseMax", "Min of oscilation range: 0 is color1 and 1.0 is color2. Can be < 0, and the wave will clip at 0."}, + {"lowAmmoWarningPulseMin", "Max of oscilation range: 0 is color1 and 1.0 is color2. Can be > 1.0, and the wave will clip at 1.0."}, + {"lsp_enumertion_max_retry_time", "Max time that the LSP enumeration can retry"}, + {"lsp_enumertion_retry_step", "Step in m/s for the LSP enumeration retry"}, + {"lui_demoMode", "Check if the game is in demo mode."}, + {"lui_FFotDSupportEnabled", "Enables lui to update itself via the ffotd"}, + {"lui_hud_motion_angle_ease_speed", "Hud motion ease percentage of degrees per second"}, + {"lui_hud_motion_bob_scale", "Hud motion bob scale"}, + {"lui_hud_motion_enabled", "Enable hud motion"}, + {"lui_hud_motion_perspective", "value for hud motion perspective transform in pixels"}, + {"lui_hud_motion_rotation_max", "Hud motion rotation max"}, + {"lui_hud_motion_rotation_scale", "Hud motion rotation scale"}, + {"lui_hud_motion_trans_ease_speed", "Hud motion ease percentage of pixels per second"}, + {"lui_hud_motion_translation_max", "Hud motion translation max"}, + {"lui_hud_motion_translation_scale", "Hud motion translation scale"}, + {"lui_loot_duplicateredemption", "Whether a user can redeem duplicate loot items in the Armory"}, + {"LUI_MemErrorsFatal", "Out of memory errors cause drops when true, reinits the UI system if false"}, + {"lui_menuFlowEnabled", "Enables LUI menu flow"}, + {"lui_mlg_rules_unlocked", "Whether MLG rules are unlocked"}, + {"lui_priv_lobby_team", "Team selected in private match lobby"}, + {"lui_splitscreensignin_menu", "Enables the LUI splitscreensignin menu"}, + {"lui_splitscreenupscaling", "Force splitscreen upscaling off/on (-1 off, 1 on) -- requires map change"}, + {"lui_systemlink_menu", "Enables the LUI systemlink menu"}, + {"lui_waitingforgavelmessagesconfirmed", ""}, + {"lui_waitingfornetworktype", "value is LuiWaitingForNetworkType enum"}, + {"lui_waitingforonlinedatafetch_controller", "the controller index that is fetching the online stats data"}, + {"LUI_WorkerCmdGC", "Dev-only flag to enable/disable LUI workerCmd GC thread"}, + {"lui_xboxlive_menu", "Enables the LUI xboxlive menu"}, + {"m_filter", "Allow mouse movement smoothing"}, + {"m_forward", "Forward speed in units per second"}, + {"m_pitch", "Default pitch"}, + {"m_side", "Sideways motion in units per second"}, + {"m_yaw", "Default yaw"}, + {"manifestfs", "Use a manifest file to read segmented fastfiles"}, + {"mapname", "The current map name"}, + {"mapPackMPGroupFourFlags", "Map pack flags that comprise MP ala carte map pack 1"}, + {"mapPackMPGroupFreeFlags", "Map pack flags that comprise the free MP ala carte map pack"}, + {"mapPackMPGroupOneFlags", "Map pack flags that comprise MP ala carte map pack 1"}, + {"mapPackMPGroupThreeFlags", "Map pack flags that comprise MP ala carte map pack 1"}, + {"mapPackMPGroupTwoFlags", "Map pack flags that comprise MP ala carte map pack 1"}, + {"marketing_active", "Are we allowed to enable Marketing Comms or not"}, + {"marketing_refresh_time", "time in seconds to wait before refreshing marketing messages from demonware"}, + {"matchdata_active", "Are match data uploads enabled"}, + {"matchdata_maxcompressionbuffer", "Max SP match data compression buffer to use (in bytes)"}, + {"matchmaking_debug", "Enable matchmaking debugging information"}, + {"max_ping_threshold_good", "max ping value to be considered as good"}, + {"max_ping_threshold_medium", "max ping value to be considered as medium"}, + {"max_xp_per_match", ""}, + {"maxPrestigeOverride", "Overrides the maximum prestige level, disabled if 0."}, + {"maxVoicePacketsPerSec", ""}, + {"maxVoicePacketsPerSecForServer", ""}, + {"mdsd", "enable match data stat delta logging?"}, + {"melee_debug", "Turn on debug lines for melee traces"}, + {"migration_dvarErrors", "Whether to check for illegal script dvar changes."}, + {"min_wait_for_players", ""}, + {"missileRemoteFOV", "Remote missile-cam, FOV to use."}, + {"missileRemoteSteerPitchRange", "Remote-controlled missile allowed up/down range. To keep players from steering missiles above the horizon."}, + {"missileRemoteSteerPitchRate", "Remote-controlled missile up/down steering speed."}, + {"missileRemoteSteerYawRate", "Remote-controlled missile left/right steering speed."}, + {"mm_aw_onboarding_rank", "If a player is at or above this rank in AW, she is not considered onboarding"}, + {"mm_blops2_onboarding_skill", "Used to determine onboarding status for Ghosts"}, + {"mm_bucket_option", "if using bucketing, describes what pools can join with each other"}, + {"mm_country_code", "country code"}, + {"mm_ghosts_onboarding_skill", "Used to determine onboarding status for Ghosts"}, + {"mm_past_title_stats_source", "what type of information do we use from the past titles (rank vs kdr, etc)"}, + {"mm_skill_calculation_type", ""}, + {"mm_skill_enforcement", ""}, + {"mm_skill_lower_bucket", "lower mm skill bucket"}, + {"mm_skill_param_delta", "Delta parameter for Johnson SU distribution curve"}, + {"mm_skill_param_gamma", "Gamma parameter for Johnson SU distribution curve"}, + {"mm_skill_param_lambda", "Lambda parameter for Johnson SU distribution curve"}, + {"mm_skill_param_xi", "Xi parameter for Johnson SU distribution curve"}, + {"mm_skill_strict_enforcement", ""}, + {"mm_skill_type", "mm skill type"}, + {"mm_skill_upper_bucket", "upper mm skill bucket"}, + {"mm_sph_1", ""}, + {"mm_sph_10", ""}, + {"mm_sph_11", ""}, + {"mm_sph_12", ""}, + {"mm_sph_13", ""}, + {"mm_sph_14", ""}, + {"mm_sph_15", ""}, + {"mm_sph_16", ""}, + {"mm_sph_17", ""}, + {"mm_sph_18", ""}, + {"mm_sph_2", ""}, + {"mm_sph_3", ""}, + {"mm_sph_4", ""}, + {"mm_sph_5", ""}, + {"mm_sph_6", ""}, + {"mm_sph_7", ""}, + {"mm_sph_8", ""}, + {"mm_sph_9", ""}, + {"mm_split_population", ""}, + {"mm_test_type", "mm test type"}, + {"mm_use_onboarding_skill", "If set, we will for the player's skill to be the lowest available"}, + {"monkeytoy", "Restrict console access"}, + {"motd", ""}, + {"motd_store_link", "Add a link to the in-game store in the MOTD popup"}, + {"motionTrackerBlurDuration", "The motion blur duration for motion tracker dots"}, + {"motionTrackerCenterX", ""}, + {"motionTrackerCenterY", ""}, + {"motionTrackerPingFadeTime", "How long an enemy is visible on the motion tracker after being detected"}, + {"motionTrackerPingPitchAddPerEnemy", "The added percentage of pitch for each additional enemy that is detected (final pitch = base pitch * (1 + enemy count * this))"}, + {"motionTrackerPingPitchBase", "The pitch of the motion tracker sound for a nearby enemy"}, + {"motionTrackerPingPitchNearby", "The pitch of the motion tracker sound for a nearby enemy"}, + {"motionTrackerPingSize", "The width and height of the motion tracker's enemy indicators as a percentage of motion tracker scale"}, + {"msg_field_delta2", "enable the delta2 serialization."}, + {"name", "Player name"}, + {"net_authPort", "UDP port for Steam authentication"}, + {"net_ip", "Network IP Address"}, + {"net_masterServerPort", "UDP port for Steam server browser"}, + {"net_noudp", "Disable UDP"}, + {"net_port", "Network port"}, + {"net_socksEnabled", "Enable network sockets"}, + {"net_socksPassword", "Network socket password"}, + {"net_socksPort", "Network socket port"}, + {"net_socksServer", "Network socket server"}, + {"net_socksUsername", "Network socket username"}, + {"nextmap", "Next map to play"}, + {"nightVisionDisableEffects", ""}, + {"nightVisionFadeInOutTime", "How long the fade to/from black lasts when putting on or removing night vision goggles."}, + {"nightVisionPowerOnTime", "How long the black-to-nightvision fade lasts when turning on the goggles."}, + {"num_available_map_packs", "Number of map packs available for this platform"}, + {"objectiveFontSize", "Onscreen Objective Pointer - Fontsize of the icon's text."}, + {"objectiveTextOffsetY", "Onscreen Objective Pointer - Offset of the icon's text."}, + {"onlinegame", "Current game is an online game with stats, custom classes, unlocks"}, + {"overrideNVGModelWithKnife", "When true, nightvision animations will attach the weapDef's knife model instead of the night vision goggles."}, + {"overtimeTimeLimit", ""}, + {"p2pAuth_allow_steam_p2p", "Determines if Steam based P2P is allowed if direct connectivity is not possible."}, + {"p2pAuth_disable", ""}, + {"paintExplosionRadius", "The radius of the paint grenade explosion"}, + {"painVisionLerpOutRate", "Rate at which pain vision effect lerps out"}, + {"painVisionTriggerHealth", "Health (0 to 1) that will trigger the pain vision effect"}, + {"party_alternateMapVoteStatus", "Alternate map vote progress"}, + {"party_dlc_only_intended_mappacks", "When selecting next map for rotation, should any maps not in the intended search be excluded, even if available?"}, + {"party_firstSubpartyIndex", "Determines sort order and coloring of parties in lobbies. Randomly set by code. Dvar provided for debugging."}, + {"party_followPartyHostOutOfGames", "Whether we should follow our party host out of a game in progress."}, + {"party_gamesize", "Current maximum game size"}, + {"party_gametype", "Current gametype"}, + {"party_inactiveHeartbeatPeriod", "How often to send inactive party keep alive packets in milliseconds."}, + {"party_initial_dlc_search_timer", "Time until DLC enabled search should show an error dialog suggesting the user consider going to non dlc search"}, + {"party_IsLocalClientSelected", "True if selected player is a local client. Only valid when used with party feeders."}, + {"party_kickplayerquestion", "String to store the question about kicking the selected player"}, + {"party_listFocus", "True when an item in the party list has focus."}, + {"party_lobbyPlayerCount", "Number of players currently in the party/lobby"}, + {"party_mapname", "Current map name"}, + {"party_mapvote_entrya_mapname", "Primary map vote entry name"}, + {"party_mapvote_entryb_mapname", "Alternate map vote entry name"}, + {"party_matchedPlayerCount", "Number of matched players before revealing their true names"}, + {"party_maxplayers", "Maximum number of players in a party"}, + {"party_maxPrivatePartyPlayers", "Max number of players allowed in a private party."}, + {"party_maxTeamDiff", "Maximum difference allowed between teams before starting a match"}, + {"party_membersMissingMapPack", "Whether any party member is missing one of the enabled map packs. Only valid after running partyUpdateMissingMapPackDvar"}, + {"party_minLobbyTime", "Minimum time (in seconds) for a lobby to be open before auto starting a match"}, + {"party_minplayers", "Minimum number of players in a party"}, + {"party_nextMapVoteStatus", "Next map vote progress"}, + {"party_partyPlayerCount", "Number of players currently in the party/lobby"}, + {"party_partyPlayerCountNum", "Number of players currently in the party/lobby"}, + {"party_playersCoop", "True if the current playlist places all players on the allies team"}, + {"party_playervisible", "Whether selected player in party is showing true info or not. Only valid when used with party feeders."}, + {"party_randomMapVoteStatus", "Random map vote progress"}, + {"party_resume_dlc_search_timer", "Time until DLC enabled search should show an error dialog suggesting the user consider going to non dlc search"}, + {"party_search_for_dlc_content", "search for DLC enabled games else standard maps only will be used"}, + {"party_selectedIndex", "Current selected player index in the feeder."}, + {"party_selectedIndexChangedTime", "Time stamp in milliseconds when the selected index last changed."}, + {"party_statusString", "Party Status (localized )"}, + {"party_teambased", "True if the current playlist is team based"}, + {"party_teamsVisible", "teams are visible in UI"}, + {"party_timer", "Time until game begins in seconds, for UI display"}, + {"partyChatDisallowed", "Whether to disallow ps4 Live Party Chat"}, + {"partymigrate_broadcast_interval", "Time between telling people who the new host is when migrating lobby"}, + {"partymigrate_cpuBonusPing", "The ping rewarded to a CPU meeting the bonus threshold when scoring hosts."}, + {"partymigrate_cpuBonusThreshold", "The required excess %CPU speed to get a bonus when scoring hosts."}, + {"partymigrate_logResults", "Instrumentation - Whether to log the best host calculation results. 0 is disabled, 1 for games, 2 for parties, 3 for both."}, + {"partymigrate_makeHostTimeout", "Time before giving up on makeHost requests"}, + {"partymigrate_pingtest_active", "Whether to do a ping test when lobby migrating"}, + {"partymigrate_pingtest_filterThreshold", "Acceptable ping difference from best ping host for host selection (ms)"}, + {"partymigrate_pingtest_minThreshold", "Minimum meaningful ping delta for host selection (ms)"}, + {"partymigrate_pingtest_retry", "Time between ping tests when migrating lobby"}, + {"partymigrate_pingtest_timeout", "Time to give up on ping tests when migrating lobby"}, + {"partymigrate_preferSameHost", "When possible, prefer keeping the same host on migrations"}, + {"partymigrate_selectiontime", "Time before requiring a host selection when migrating lobby"}, + {"partymigrate_timeout", "Time before giving up on lobby migration if we hear nothing"}, + {"partymigrate_timeoutmax", "Time before giving up on lobby migration if we hear nothing"}, + {"partymigrate_uploadtest_minThreshold", "Minimum meaningful upload bandwidth delta for host selection (bps)"}, + {"password", ""}, + {"perk_armorPiercingDamage", ""}, + {"perk_blastShieldScale", ""}, + {"perk_blastShieldScale_HC", ""}, + {"perk_bulletPenetrationMultiplier", "Multiplier for extra bullet penetration"}, + {"perk_extendedMagsMGAmmo", "Number of extra bullets per clip for machine gun weapons with the extended mags perk."}, + {"perk_extendedMagsPistolAmmo", "Number of extra bullets per clip for pistol weapons with the extended mags perk."}, + {"perk_extendedMagsRifleAmmo", "Number of extra bullets per clip for rifle weapons with the extended mags perk."}, + {"perk_extendedMagsSMGAmmo", "Number of extra bullets per clip for sub machine gun weapons with the extended mags perk."}, + {"perk_extendedMagsSpreadAmmo", "Number of extra bullets per clip for spread weapons with the extended mags perk."}, + {"perk_extraBreath", "Number of extra seconds a player can hold his breath"}, + {"perk_fastClimb", "Scales the ladder climb time"}, + {"perk_fastRegenRate", ""}, + {"perk_fastRegenWaitMS", ""}, + {"perk_fastSnipeScale", "Scales the recovery speed of the view kick when using a sniper."}, + {"perk_footstepVolumeAlly", ""}, + {"perk_footstepVolumeEnemy", ""}, + {"perk_footstepVolumePlayer", ""}, + {"perk_footstepVolumeSelectiveHearingMin", ""}, + {"perk_improvedExtraBreath", "Number of extra seconds a player can hold his breath"}, + {"perk_lightWeightViewBobScale", "Scale for first person view movement while lightweight."}, + {"perk_numExtraLethal", "Number of extra lethal grenades"}, + {"perk_numExtraTactical", "Number of extra tactical grenades"}, + {"perk_parabolicAngle", "Eavesdrop perk's effective FOV angle"}, + {"perk_parabolicIcon", "Eavesdrop icon to use when displaying eavesdropped voice chats"}, + {"perk_parabolicRadius", "Eavesdrop perk's effective radius"}, + {"perk_quickDrawSpeedScale", "Scales the 'Hip to ADS' transition speed."}, + {"perk_quickDrawSpeedScaleSniper", "Scales the 'Hip to ADS' transition speed."}, + {"perk_scavengerMode", ""}, + {"perk_sprintMultiplier", "Multiplier for player_sprinttime"}, + {"perk_sprintRecoveryMultiplierActual", ""}, + {"perk_sprintRecoveryMultiplierVisual", ""}, + {"perk_weapRateMultiplier", "Percentage of weapon firing rate to use"}, + {"perk_weapReloadMultiplier", "Percentage of weapon reload time to use"}, + {"perk_weapSpreadMultiplier", "Percentage of weapon spread to use"}, + {"phys_autoDisableLinear", "A body must have linear velocity less than this to be considered idle."}, + {"phys_autoDisableTime", "The amount of time a body must be idle for it to go to sleep."}, + {"phys_bulletSpinScale", "Scale of the effective offset from the center of mass for the bullet impacts."}, + {"phys_bulletUpBias", "Up Bias for the direction of the bullet impact."}, + {"phys_dragAngular", "The amount of angular drag, applied globally"}, + {"phys_dragLinear", "The amount of linear drag, applied globally"}, + {"phys_gravity", "Physics gravity in units/sec^2."}, + {"phys_gravity_ragdoll", "Physics gravity used by ragdolls in units/sec^2."}, + {"phys_gravityChangeWakeupRadius", "The radius around the player within which objects get awakened when gravity changes"}, + {"phys_jitterMaxMass", "Maximum mass to jitter - jitter will fall off up to this mass"}, + {"physVeh_explodeForce", "The force applied to physics vehicles due to explosions"}, + {"physVeh_explodeSpinScale", "The max (random) offset from the center of mass at which splash damage applies its force"}, + {"physVeh_jump", "Set to 1 to make a vehicle jump."}, + {"physVeh_minContactImpulse", "The minimum impulse needed to register a contact notification"}, + {"physVeh_minImpactMomentum", "The minimum collision momentum needed to register an impact"}, + {"physVeh_StepsPerFrame", "The number of physics timesteps that the server frame will be divided into."}, + {"pickupPrints", "Print a message to the game window when picking up ammo, etc."}, + {"player_breath_snd_delay", "The delay before playing the breathe in sound"}, + {"player_breath_snd_lerp", "The interpolation rate for the player hold breath sound"}, + {"player_current_floor", ""}, + {"player_MGUseRadius", "The radius within which a player can mount a machine gun"}, + {"player_stunWhiteFlash", "If enabled, player's screens will flash white when they are stunned."}, + {"player_throwbackInnerRadius", "The radius to a live grenade player must be within initially to do a throwback"}, + {"player_throwbackOuterRadius", "The radius player is allow to throwback a grenade once the player has been in the inner radius"}, + {"player_useRadius", "The radius within which a player can use things"}, + {"playercard_cache_download_max_retry_time", "Max time that the player cache download can retry"}, + {"playercard_cache_download_retry_step", "Step in m/s for the player cache download retry"}, + {"playercard_cache_upload_max_retry_time", "Max time that the player cache upload can retry"}, + {"playercard_cache_upload_retry_step", "Step in m/s for the player cache upload retry"}, + {"playercard_cache_validity_life", "The life of a cached gamercard (it can be re-downloaded after this)"}, + {"playerPositionRecordSampleTime", "How often to sample player positions and save them into match data."}, + {"playlist", "The playlist number"}, + {"playlistAggrFilename", "Aggregated playlist filename"}, + {"playlistFilename", "Playlist filename"}, + {"playListUpdateCheckMinutes", "Minutes to wait between checking for updated playlist."}, + {"prestige_shop_active", "Are we allowed to show the Prestige Shop or not"}, + {"prestige30EasterEggEnabled", "Enables the easter egg for prestige 30 if 1, disabled if 0."}, + {"privateMatch_joinPassword", ""}, + {"privateMatch_serverPassword", ""}, + {"profileMenuOption_blacklevel", ""}, + {"profileMenuOption_offensiveContentMode", "Mode of the offensive content warning at startup - 0, skip and turn on; 1, skip and turn off; 2, ask user"}, + {"profileMenuOption_safeAreaHorz", ""}, + {"profileMenuOption_safeAreaVert", ""}, + {"profileMenuOption_volume", ""}, + {"protocol", "Protocol version"}, + {"pt_AliensReadyUpPrivateInUse", "Do we use the co-op Ready Up feature in public lobbies?"}, + {"pt_AliensReadyUpPublicInUse", "Do we use the co-op Ready Up feature in public lobbies?"}, + {"pt_AliensReadyUpPublicStartTimerLength", "co-op Ready Up start timer length in seconds"}, + {"pt_allMembersDoQoS", "Whether to send search results to all party/lobby members to get QoS data"}, + {"pt_backoutOnClientPresence", "Whether the host should backout the party on client presence. 0=fully disabled, 1=out of game only, 2=in-game also"}, + {"pt_connectAttempts", "Connect timeout when joining another game/party, per attempt"}, + {"pt_connectTimeout", "Connect timeout when joining another game/party, per attempt"}, + {"pt_gameStartTimerLength", "Time in seconds before a game start once enough party members are ready"}, + {"pt_logHostSelectionChance", "Sets the probability that we log our host selection results"}, + {"pt_memberTimeout", "Client timeout time in the general case"}, + {"pt_migrateBeforeAdvertise", "Whether lobbies made by private parties should migrate host before publishing"}, + {"pt_migrationBandwidthBonusPing", "The ping rewarded to the bonus bandwidth threshold when scoring hosts."}, + {"pt_migrationBandwidthBonusThreshold", "The required excess % upload bandwidth to get a bonus when scoring hosts."}, + {"pt_migrationCPUWeight", "How important CPU speed is when selecting a new host"}, + {"pt_migrationNotInstalledWeight", "How important not being done installing is when selecting a new host"}, + {"pt_migrationPingBad", ""}, + {"pt_migrationPingWeight", ""}, + {"pt_migrationQuitsBad", ""}, + {"pt_migrationQuitsWeight", ""}, + {"pt_migrationRAMWeight", "How important it is to have the minimum amount of RAM when selecting a new host"}, + {"pt_migrationThreshold", "Minimum amount which another client must be better than the current host to trigger a migration"}, + {"pt_migrationUploadBad", ""}, + {"pt_migrationUploadWeight", ""}, + {"pt_migrationWifiPenalty", "How important Wifi is when selecting a new host"}, + {"pt_pregameStartTimerLength", "Time in seconds before showing and starting the game start timer"}, + {"pt_rejoin", "Enable defensive rejoin command"}, + {"pt_reservedAnonymousSlotTime", "Time in milliseconds that ANONYMOUS slots will be reserved."}, + {"pt_reservedCommittedSlotTime", "Time in milliseconds that COMMITTED slots will be reserved"}, + {"pt_reservedJoiningSlotTime", "Time in milliseconds that JOINING slots will be reserved"}, + {"pt_searchConnectAttempts", "Connect timeout when joining another game/party, per attempt"}, + {"pt_searchPauseTime", "Minimum amount of time to pause between searches"}, + {"pt_searchRandomDelay", "Time period over which the search timers will get randomly delayed."}, + {"pt_searchResultsLifetime", "Time at which we consider the search results stale"}, + {"pt_searchResultsMin", "Minimum amount of time that has to pass before we'll search again for matches"}, + {"pt_stillConnectingWaitTime", "Amount of time to wait for someone to finish connecting before searching for lobbies to merge with"}, + {"pt_useMigrationWeights", "Killswitch to turn on or off the host selection by weights"}, + {"publisherFileFetchTimeout", "default timeout for publisher files FETCH tasks (in seconds)"}, + {"r_adaptiveSubdiv", "Enables screen space Catmull Clark adaptive tessellation. If disabled, models tessellate to their designed subdivision level."}, + {"r_adaptiveSubdivBaseFactor", "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation."}, + {"r_adaptiveSubdivPatchFactor", "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation."}, + {"r_allCells", "Draw all cells. Most useful for seeing if portals or cells are hiding things they should not.."}, + {"r_amdGPU", "At least on AMD GPU used for rendering."}, + {"r_aoBlurSharpness", "Controls the tolerance for depth discontinuities during the bilateral blur step. Larger values reduce the depth tolerance and effectively sharpen more edges."}, + {"r_aoBlurStep", "Step scale applied to sample offsets during the bilateral blur. A value of 1 results in a normal gaussian blur. Increasing it to 2 or 3 makes the filter larger but causes fine dithering patterns."}, + {"r_aoDiminish", "Decrease the effect of occlusion on brighter colors"}, + {"r_aoPower", "Power curve applied to AO factor"}, + {"r_aoStrength", "Strength of Ambient Occlusion effect"}, + {"r_aoUseTweaks", "Use r_ao* dvars instead of the current light set values for AO common params"}, + {"r_artUseTweaks", "Tells the game that art tweaks is enabled and script is in control (as opposed to ColorEd)."}, + {"r_aspectRatio", "Screen aspect ratio. Most widescreen monitors are 16:10 instead of 16:9."}, + {"r_asyncCompute", "Enables scheduling GPU compute shader work prior to the graphics frame, improving overlap."}, + {"r_atlasAnimFPS", "Speed to animate atlased 2d materials"}, + {"r_autopriority", "Automatically set the priority of the windows process when the game is minimized"}, + {"r_balanceLightmapOpaqueLists", "Split lightmap opaque into multiple draw lists."}, + {"r_blacklevel", "Black level (negative brightens output)"}, + {"r_blur", "Dev tweak to blur the screen"}, + {"r_blurdstGaussianBlurLevel", "MIP level to start gaussian blur at"}, + {"r_blurdstGaussianBlurRadius", "Amount to gaussian blur blur distortion render target"}, + {"r_brightness", "Brightness adjustment"}, + {"r_cacheModelLighting", "Speed up model lighting by caching previous results"}, + {"r_cacheSModelLighting", "Speed up static model lighting by caching previous results"}, + {"r_charLightAmbient", ""}, + {"r_clampLodScale", "Clamps the amount that the engine can adjust the LOD distance. 0 the engine can fully adjust. 1 the engine cannot adjust it at all. 0.5 the maximum the engine can adjust the LOD distance is 50% or the default."}, + {"r_clear", "Controls how the color buffer is cleared"}, + {"r_clearColor", "Color to clear the screen to when clearing the frame buffer"}, + {"r_clearColor2", "Color to clear every second frame to (for use during development)"}, + {"r_clutCompositeVisionSet", "Composite clut with vision set."}, + {"r_cmdbuf_worker", "Process command buffer in a separate thread"}, + {"r_colorGradingEnable", "Enable color grading."}, + {"r_colorMap", "Replace all color maps with pure black or pure white"}, + {"r_colorScaleUseTweaks", "Override color scale LightSet settings with tweak dvar values. (MP)"}, + {"r_combinePostOpaqueFx", ""}, + {"r_contrast", "Contrast adjustment"}, + {"r_darkBlur", "Apply blur (decrease of visual acuity) when dark"}, + {"r_darkBlurPower", "Power curve of blurring (decrease of visual acuity) when dark"}, + {"r_darkBlurRadius", "Radius of blurring (decrease of visual acuity) when dark"}, + {"r_darkColor", "Reduce color sensitivity when dark"}, + {"r_darkColorPower", "Power curve of color sensitivity when dark"}, + {"r_debugLineWidth", "Width of server side debug lines"}, + {"r_defaultPatchCount", "Patches per thread group for all other surfaces."}, + {"r_depthPrepass", "Enable depth prepass for various geometries"}, + {"r_depthSortEnable", "Enable sorting of transparent surfaces."}, + {"r_depthSortRange", "Range to consider depth sort,"}, + {"r_desaturation", "Desaturation adjustment"}, + {"r_detailMap", "Replace all detail maps with an image that effectively disables them"}, + {"r_diffuseColorScale", "Globally scale the diffuse color of all point lights"}, + {"r_displacementMap", "Replace all displacement maps with an image that effectively disables them"}, + {"r_displacementPatchCount", "Patches per thread group for displacement surfaces."}, + {"r_distortion", "Enable distortion"}, + {"r_distortion_script_force_off", "Force distortion off in script"}, + {"r_dlightLimit", "Maximum number of dynamic lights drawn simultaneously"}, + {"r_dof_bias", "Depth of field bias as a power function (like gamma); less than 1 is sharper"}, + {"r_dof_enable", "Enable the depth of field effect"}, + {"r_dof_farBlur", ""}, + {"r_dof_farEnd", "Depth of field far end distance, in inches"}, + {"r_dof_farStart", "Depth of field far start distance, in inches"}, + {"r_dof_nearBlur", ""}, + {"r_dof_nearEnd", "Depth of field near end distance, in inches"}, + {"r_dof_nearStart", "Depth of field near start distance, in inches"}, + {"r_dof_physical_adsFocusSpeed", "ADS focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)"}, + {"r_dof_physical_adsMaxFstop", "ADS maximum f-stop (optimal aperture and focus distance are automatically calculated for this mode)"}, + {"r_dof_physical_adsMinFstop", "ADS minimum f-stop (optimal aperture and focus distance are automatically calculated for this mode)"}, + {"r_dof_physical_bokehEnable", "Enable the bokeh depth of field effect"}, + {"r_dof_physical_bokehPreset", "Changes dof sampling quality"}, + {"r_dof_physical_bokehRotation", "Bokeh shape rotation in degrees (hexagonal and octogonal only)"}, + {"r_dof_physical_bokehShape", "Changes the bokeh shape"}, + {"r_dof_physical_bokehSharpness", "Bokeh shape sharpness, trades sharpness for stability (circular only)"}, + {"r_dof_physical_enable", "enable physical camera controls (using aperture priority)"}, + {"r_dof_physical_filmDiagonal", "Diagonal size of the film/sensor (mm). The bigger the sensor size, the bigger the circle of confusion (which means stronger blurring at all distances). Defaults to full-frame 35mm"}, + {"r_dof_physical_focusDistance", "Distance to the plane in focus for the scene"}, + {"r_dof_physical_fstop", "Aperture of the camera for the scene. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32"}, + {"r_dof_physical_hipEnable", "Enable hyperfocal mode"}, + {"r_dof_physical_hipFocusSpeed", "Hyperfocal mode focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)"}, + {"r_dof_physical_hipFstop", "Aperture of the camera for the scene in the hyperfocal mode"}, + {"r_dof_physical_hipSharpCocDiameter", "Defines what circle of confusion can be considered sharp (mm). Defaults to 0.03mm, generally accepted value for 35mm"}, + {"r_dof_physical_maxCocDiameter", "Maximum circle of confusion diameter (virtual units, might be clamped for bokeh dof)"}, + {"r_dof_physical_minFocusDistance", "Minimum focus distance (inches)"}, + {"r_dof_physical_viewModelFocusDistance", "Distance to the plane in focus for the scene"}, + {"r_dof_physical_viewModelFstop", "Aperture of the camera for the view model. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32"}, + {"r_dof_tweak", "Use dvars to set the depth of field effect; overrides r_dof_enable"}, + {"r_dof_viewModelEnd", "Depth of field viewmodel end distance, in inches"}, + {"r_dof_viewModelStart", "Depth of field viewmodel start distance, in inches"}, + {"r_drawSun", "Enable sun effects"}, + {"r_drawWater", "Enable water animation"}, + {"r_dynamicOPL", "Enable drawing vfx lights as overlapping primary light for saving gpu performance."}, + {"r_dynamicSpotLightShadows", "Enable shadows for dynamic/VFX spot lights, you should set this dvar then spawn the new light."}, + {"r_elevatedPriority", "Utilize priority elevation for process."}, + {"r_emblemBrightnessScale", "Modifier that scales the brightness of the emblem on model materials"}, + {"r_emissiveMap", "Replace all emissive maps with pure black or pure white"}, + {"r_enableNoTessBuckets", "Enables placing triangles that don't need tessellation into additional draw calls using non-tessellated shaders."}, + {"r_envBrdfLutMap", "Replace environment BRDF lookup table with pure black (no secondary specular) or pure white (maximum secondary specular)"}, + {"r_envMapExponent", "Reflection exponent."}, + {"r_envMapMaxIntensity", "Max reflection intensity based on glancing angle."}, + {"r_envMapMinIntensity", ""}, + {"r_envMapOverride", ""}, + {"r_envMapSunIntensity", "Max sun specular intensity intensity with env map materials."}, + {"r_eyePupil", " Change eye's pupil Size."}, + {"r_eyeRedness", " Change eye's redness."}, + {"r_eyeWetness", " Change eye's wetness."}, + {"r_fastModelPrimaryLightCheck", "Reduce R_GetNonSunPrimaryLightForSphere/R_GetNonSunPrimaryLightForBox function calls"}, + {"r_fastModelPrimaryLightLink", "Speed up R_LinkSphereEntityToPrimaryLights and R_LinkBoxEntityToPrimaryLights."}, + {"r_filmAltShader", "Use alternate shader (with middle tint and dark desat) for film color."}, + {"r_filmTweakBrightness", "Tweak dev var; film color brightness"}, + {"r_filmTweakContrast", "Tweak dev var; film color contrast"}, + {"r_filmTweakDarkTint", ""}, + {"r_filmTweakDesaturation", "Tweak dev var; Desaturation applied after all 3D drawing to light areas"}, + {"r_filmTweakDesaturationDark", "Tweak dev var; Additional desaturation applied after all 3D drawing to dark areas"}, + {"r_filmTweakEnable", "Tweak dev var; enable film color effects"}, + {"r_filmTweakInvert", "Tweak dev var; enable inverted video"}, + {"r_filmTweakLightTint", ""}, + {"r_filmTweakMediumTint", ""}, + {"r_filmUseTweaks", "Overide film effects with tweak dvar values."}, + {"r_flushAfterExecute", "Whether to Flush after ExecuteCommandList."}, + {"r_fog", "Set to 0 to disable fog"}, + {"r_fog_depthhack_scale", "Fog scale for depth hack surfaces"}, + {"r_fog_ev_adjust", "Fog color ev adjustment (+2 means fog color is 2 stops brighter)"}, + {"r_font_cache_debug_display", "Display the current fontcache texture on the HUD for debug purposes"}, + {"r_forceLod", "Force all level of detail to this level"}, + {"r_fullbright", "Toggles rendering without lighting"}, + {"r_fxaaSubpixel", "FXAA sub-pixel amount, lower values have more aliasing and less blur"}, + {"r_FXAverageColorFunc", "How to compute FX system average color? 0 = use IWrad equation, 1 = legacy equation, 2 = spherical harmonics 1 coefficient."}, + {"r_globalGenericMaterialScale", "Hack global generic material constants"}, + {"r_glow_allowed", "Allow glow."}, + {"r_glow_allowed_script_forced", "Force 'allow glow' to be treated as true, by script."}, + {"r_gunSightColorEntityScale", "Scale the gun sight color when over an entity."}, + {"r_gunSightColorNoneScale", "Scale the gun sight color when not over an entity."}, + {"r_hbaoBias", "HBAO bias"}, + {"r_hbaoBlurEnable", "HBAO blur enabled"}, + {"r_hbaoBlurSharpness", "HBAO blur sharpness"}, + {"r_hbaoCoarseAO", "HBAO coarse AO"}, + {"r_hbaoDebug", "Debug render HBAO occlusion"}, + {"r_hbaoDetailAO", "HBAO detail AO"}, + {"r_hbaoPowerExponent", "HBAO power exponent"}, + {"r_hbaoRadius", "HBAO radius"}, + {"r_hbaoSceneScale", "HBAO scene scale"}, + {"r_hbaoStrengthBlend", "Blend factor between the artist-tuned proportional strength r_hbaoStrengthScale*artStrength, and the fixed strength r_hbaoStrengthFixed. A value of 0.0 is fully the proportional value, and a value of 1.0 is fully the fixed value."}, + {"r_hbaoStrengthFixed", "Fixed HBAO strength. Only used if r_hbaoStrengthBlend > 0.0."}, + {"r_hbaoStrengthScale", "Scale factor to convert SSAO strength to HBAO strength. Only used if r_hbaoStrengthBlend < 1.0."}, + {"r_hbaoUseScriptScale", "Enable/disable script-controlled strength scale while HBAO is active."}, + {"r_hemiAoBlurTolerance", "Hemi SSAO Blur Tolerance (log10)"}, + {"r_hemiAoCombineResolutionsBeforeBlur", "The higher quality modes blend wide and narrow sampling patterns. The wide pattern is due to deinterleaving and requires blurring. The narrow pattern is not on a deinterleaved buffer, but it only samples every other pixel. The blur on it is optional. If you combine the two before blurring, the narrow will get blurred as well. This creates a softer effect but can remove any visible noise from having 50% sample coverage."}, + {"r_hemiAoCombineResolutionsWithMul", "When combining the wide and narrow patterns, a mul() operation can be used or a min() operation. Multiplication exaggerates the result creating even darker creases. This is an artistic choice. I think it looks less natural, but often art teams prefer more exaggerated contrast. For me, it's more about having the right AO falloff so that it's a smooth gradient rather than falling off precipitously and forming overly dark recesses."}, + {"r_hemiAoDepthSquash", "Hemi SSAO depth squash. Value is rcp."}, + {"r_hemiAoEnable", "Enable Hemi SSAO"}, + {"r_hemiAoHierarchyDepth", "Hemi SSAO recursion depth (filter width)"}, + {"r_hemiAoMaxDepthDownsample", "Use max depth value when downsampling, instead of pseudo-randomly picking a depth sample? Leaving this at the default false may produce more stable results."}, + {"r_hemiAoNoiseFilterTolerance", "This is necessary to filter out pixel shimmer due to bilateral upsampling with too much lost resolution. High frequency detail can sometimes not be reconstructed, and the noise filter fills in the missing pixels with the result of the higher resolution SSAO. Value is log10."}, + {"r_hemiAoPower", "Power curve applied to Hemi SSAO factor, not applied in game yet"}, + {"r_hemiAoQualityLevel", "Hemi SSAO quality setting"}, + {"r_hemiAoRejectionFalloff", "Controls how aggressive to fade off samples that occlude spheres but by so much as to be unreliable. This is what gives objects a dark halo around them when placed in front of a wall. If you want to fade off the halo, boost your rejection falloff. The tradeoff is that it reduces overall AO. Value is rcp."}, + {"r_hemiAoStrength", "Strength of Hemi Screen Space Ambient Occlusion effect"}, + {"r_hemiAoUpsampleTolerance", "Hemi SSAO Upsample Tolerance (log10)"}, + {"r_heroLighting", "Enable hero-only lighting"}, + {"r_highLodDist", "Distance for high level of detail"}, + {"r_hudFx", "Draw HUD Effects"}, + {"r_hudOutlineEnable", "Enables wireframe outlines to be drawn around DObjs (as a post process)."}, + {"r_hudOutlinePostMode", "hud outline apply mode"}, + {"r_hudOutlineWidth", "Set the width of the Hud Outline"}, + {"r_ignore", ""}, + {"r_ignoref", ""}, + {"r_imageQuality", "Image quality"}, + {"r_inGameVideo", "Allow in game cinematics"}, + {"r_lateAllocParamCacheAllowed", "Enable late allocation of parameter cache for VS stage."}, + {"r_lateAllocParamCacheDefault", "Late allocation of parameter cache value for sub-div materials."}, + {"r_lateAllocParamCacheDisplacement", "Late allocation of parameter cache value for sub-div materials."}, + {"r_lateAllocParamCacheSubdiv", "Late allocation of parameter cache value for sub-div materials."}, + {"r_lightCacheLessFrequentMaxDistance", "Adjust the distance fx models (and models tagged as less-frequently-lit by script) move before immediately being relit"}, + {"r_lightCacheLessFrequentPeriod", "Adjust how frequently fx models (and models tagged as less-frequently-lit by script) get relit on average (1 is every frame, 8 is every 8th frame)"}, + {"r_lightGridAvgApplyPrimaryLight", "apply primary light color onto r_showLightGridAvgProbes boxes"}, + {"r_lightGridAvgFollowCamera", "allow the r_showLightGridAvgProbes boxes following current camera position"}, + {"r_lightGridAvgProbeCount", "how many light grid avg color probes will show up)"}, + {"r_lightGridAvgTraceGround", " lock boxes to ground "}, + {"r_lightGridContrast", "Adjust the contrast of light color from the light grid"}, + {"r_lightGridDefaultFXLightingLookup", "Default FX lighting lookup location\n"}, + {"r_lightGridDefaultModelLightingLookup", "Default model lighting lookup location"}, + {"r_lightGridEnableTweaks", "Enable tweaks of the light color from the light grid"}, + {"r_lightGridIntensity", "Adjust the intensity of light color from the light grid"}, + {"r_lightGridSHBands", "Spherical harmonics bands being used for evaluating current-gen light grids colors. 0 = default, 1 = 1 band, 2 = 2 bands, 3 = 3 bands.\n"}, + {"r_lightGridUseTweakedValues", "Use tweaked values instead of default"}, + {"r_lightMap", "Replace all lightmaps with pure black or pure white"}, + {"r_litSurfaceHDRScalar", "Vision set based scalar applied to lit surfaces"}, + {"r_loadForRenderer", "Set to false to disable dx allocations (for dedicated server mode)"}, + {"r_lockPvs", "Lock the viewpoint used for determining what is visible to the current position and direction"}, + {"r_lod4Dist", "Distance for lowest level of detail 4"}, + {"r_lod5Dist", "Distance for lowest level of detail 5"}, + {"r_lodBiasRigid", ""}, + {"r_lodBiasSkinned", ""}, + {"r_lodScaleRigid", ""}, + {"r_lodScaleSkinned", ""}, + {"r_lowestLodDist", "Distance for lowest level of detail"}, + {"r_lowLodDist", "Distance for low level of detail"}, + {"r_mbEnable", "Set of objects which will be enabled for motion blur"}, + {"r_mbFastEnable", "Toggle on/off fast high quality motion blur"}, + {"r_mbFastPreset", "Changes motion blur quality"}, + {"r_mdao", "Enable the medium distance ambient occlusion feature"}, + {"r_mdaoAsyncOccluderGen", "The occluder generation step is performed via async compute"}, + {"r_mdaoBoneInfluenceRadiusScale", "Scale for the bone influence radius for mdao"}, + {"r_mdaoCapsuleStrength", "MDAO strength for capsule occluders"}, + {"r_mdaoMinBoneBoundsToOcclude", "Minimum volume of the bone collider to create occluders for"}, + {"r_mdaoOccluderCullDistance", "Culling distance for mdao occluders"}, + {"r_mdaoOccluderFadeOutStartDistance", "Fade out distance for mdao occluders"}, + {"r_mdaoUseTweaks", "Use r_mdao* dvars instead of the current light set values for MDAO"}, + {"r_mdaoVolumeStrength", "MDAO strength for volume occluders"}, + {"r_mediumLodDist", "Distance for medium level of detail"}, + {"r_mode", "Display mode"}, + {"r_modelLightingMap", "Replace all model lighting maps (light grid) with pure black"}, + {"r_monitor", "Index of the monitor to use in a multi monitor system; 0 picks automatically."}, + {"r_mpRimColor", "Change character's rim color for multiplayer"}, + {"r_mpRimDiffuseTint", "Change character's rim diffuse tint for multiplayer."}, + {"r_mpRimStrength", "Change character's rim color for multiplayer"}, + {"r_multiGPU", "Enable multi GPU compat mode."}, + {"r_normalMap", "Replace all normal maps with a flat normal map"}, + {"r_nvidiaGPU", "Enable NV API."}, + {"r_offchipTessellationAllowed", "Enable off-chip tessellation support."}, + {"r_offchipTessellationTfThreshold", "Tessellation factor threshold for off-chip."}, + {"r_offchipTessellationWaveThreshold", "Domain shader wave threshold for off-chip."}, + {"r_omitUnusedRenderTargets", "Omit unused render targets to save memory. Changing this requires a vid_restart."}, + {"r_outdoor", "Prevents snow from going indoors"}, + {"r_outdoorFeather", "Outdoor z-feathering value"}, + {"r_particleHdr", "Enable Hdr Particle Features"}, + {"r_patchCountAllowed", "Enable run-time setting of patch count per draw call."}, + {"r_picmip", "Picmip level of color maps. If r_picmip_manual is 0, this is read-only."}, + {"r_picmip_bump", "Picmip level of normal maps. If r_picmip_manual is 0, this is read-only."}, + {"r_picmip_spec", "Picmip level of specular maps. If r_picmip_manual is 0, this is read-only."}, + {"r_picmip_water", "Picmip level of water maps."}, + {"r_polygonOffsetBias", "Offset bias for decal polygons; bigger values z-fight less but poke through walls more"}, + {"r_polygonOffsetClamp", "Offset clamp for decal polygons; bigger values z-fight less but poke through walls more"}, + {"r_polygonOffsetScale", "Offset scale for decal polygons; bigger values z-fight less but poke through walls more"}, + {"r_portalBevels", "Helps cull geometry by angles of portals that are acute when projected onto the screen, value is the cosine of the angle"}, + {"r_portalBevelsOnly", "Use screen-space bounding box of portals rather than the actual shape of the portal projected onto the screen"}, + {"r_portalMinClipArea", "Don't clip child portals by a parent portal smaller than this fraction of the screen area."}, + {"r_portalMinRecurseDepth", "Ignore r_portalMinClipArea for portals with fewer than this many parent portals."}, + {"r_portalWalkLimit", "Stop portal recursion after this many iterations. Useful for debugging portal errors."}, + {"r_postAA", "Post process antialiasing mode"}, + {"r_postfx_enable", "Enable post-processing effects such as color correction, bloom, depth-of-field, etc."}, + {"r_preloadShaders", "Force D3D to draw dummy geometry with all shaders during level load; may fix long pauses at level start."}, + {"r_primaryLightTweakDiffuseStrength", "Tweak the diffuse intensity for primary lights"}, + {"r_primaryLightTweakSpecularStrength", "Tweak the specular intensity for primary lights"}, + {"r_primaryLightUseTweaks", ""}, + {"r_reactiveMotionActorRadius", "Radial distance from the ai characters that influences reactive motion models (inches)"}, + {"r_reactiveMotionActorVelocityMax", "AI velocity considered the maximum when determining the length of motion tails (inches/sec)"}, + {"r_reactiveMotionActorZOffset", "Distance from the actor origin along Z direction where the actor's reactive motion effector sphere is centered at."}, + {"r_reactiveMotionEffectorStrengthScale", "Additional scale for the effector influence, as a factor of the model part distance from the effector center and model part extents"}, + {"r_reactiveMotionHelicopterLimit", "Maximum number of helicopter entities that actively influence reactive motion. Can increase CPU cost of the scene."}, + {"r_reactiveMotionHelicopterRadius", "Radial distance from the helicopter that influences reactive motion models (inches)"}, + {"r_reactiveMotionHelicopterStrength", "Scales the influence of helicopter wind tunnel motion"}, + {"r_reactiveMotionPlayerHeightAdjust", "Amount to adjust the vertical distance of the effector from the player position (inches)"}, + {"r_reactiveMotionPlayerRadius", "Radial distance from the player that influences reactive motion models (inches)"}, + {"r_reactiveMotionPlayerZOffset", "Distance from the player origin along Z direction where the player's reactive motion effector sphere is centered at."}, + {"r_reactiveMotionVelocityTailScale", "Additional scale for the velocity-based motion tails, as a factor of the effector radius"}, + {"r_reactiveMotionWindAmplitudeScale", "Scales amplitude of wind wave motion"}, + {"r_reactiveMotionWindAreaScale", "Scales distribution of wind motion"}, + {"r_reactiveMotionWindDir", "Controls the global wind direction"}, + {"r_reactiveMotionWindFrequencyScale", "Scales frequency of wind wave motion"}, + {"r_reactiveMotionWindStrength", "Scale of the global wind direction (inches/sec)"}, + {"r_reflectionProbeMap", "Replace all reflection probes with pure black"}, + {"r_reflectionProbeNmlLuminance", "Enable/disable shader code for computing luminance during reflection probe denormalization. This is just an experiment.\n"}, + {"r_rimLight0Color", ""}, + {"r_rimLight0Heading", "Rim Light 0 heading in degrees"}, + {"r_rimLight0Pitch", "Rim Light 0 pitch in degrees -90 is noon."}, + {"r_rimLightBias", "How much to bias the n.l calculation"}, + {"r_rimLightDiffuseIntensity", "Strength of the diffuse component of the rim light."}, + {"r_rimLightFalloffMaxDistance", "Distance at which the rim light hits intensity of 100%."}, + {"r_rimLightFalloffMinDistance", "Distance at which the rim light hits intensity of 100%."}, + {"r_rimLightFalloffMinIntensity", "Intensity of the effect at and before minDistance."}, + {"r_rimLightPower", "Power to raise the n.l calculation"}, + {"r_rimLightSpecIntensity", "Strength of the spec ( additive) component of the rim light"}, + {"r_rimLightUseTweaks", "Turn on rim lighting tweaks"}, + {"r_scaleViewport", "Scale 3D viewports by this fraction. Use this to see if framerate is pixel shader bound."}, + {"r_sceneMipShowOverlay", "Toggles scene mip rendertarget overlay"}, + {"r_showLightGrid", "Show light grid debugging information (2: detailed, 3: detailed for this box only)"}, + {"r_showLightGridAvgProbes", "show an array of boxes which are using the light grid average color at its location"}, + {"r_showLightGridDetailInfo", "Show more details for light grid debugging."}, + {"r_showLightProbes", "Show the light probes at the light grid sample locations in world space centered around the camera."}, + {"r_showMissingLightGrid", "Use rainbow colors for entities that are outside the light grid"}, + {"r_showModelLightingLowWaterMark", ""}, + {"r_showPortals", "Show portals for debugging"}, + {"r_showPortalsOverview", "Render 2d XY portal overlay scaled to fit to this distance. Useful for debugging portal errors."}, + {"r_showReflectionProbeSelection", "Show reflection probe selection"}, + {"r_singleCell", "Only draw things in the same cell as the camera. Most useful for seeing how big the current cell is."}, + {"r_skipPvs", "Skipt the determination of what is in the potentially visible set (disables most drawing)"}, + {"r_sky_fog_intensity", "Amount of sky fog fading"}, + {"r_sky_fog_max_angle", "End of angular sky fog fading"}, + {"r_sky_fog_min_angle", "Start of angular sky fog fading"}, + {"r_skyFogUseTweaks", "Enable dvar control of sky fog"}, + {"r_smaaThreshold", "SMAA edge detection threshold"}, + {"r_smodelInstancedRenderer", "Render static models with instanced renderer"}, + {"r_smodelInstancedThreshold", "Minimum number of static model instances before instanced rendering is used"}, + {"r_smp_backend", "Process renderer back end in a separate thread"}, + {"r_smp_worker", "Process renderer front end in a separate thread"}, + {"r_smp_worker_thread0", ""}, + {"r_smp_worker_thread1", ""}, + {"r_smp_worker_thread2", ""}, + {"r_smp_worker_thread3", "undefined"}, + {"r_smp_worker_thread4", "undefined"}, + {"r_smp_worker_thread5", "undefined"}, + {"r_smp_worker_thread6", "undefined"}, + {"r_smp_worker_thread7", "undefined"}, + {"r_specOccMap", "Replace all specular occlusion maps with pure black (fully occluded) or pure white (not occluded)"}, + {"r_specularColorScale", "Set greater than 1 to brighten specular highlights"}, + {"r_specularMap", "Replace all specular maps with pure black (off) or pure white (super shiny)"}, + {"r_spotLightEntityShadows", "Enable entity shadows for spot lights."}, + {"r_spotLightShadows", "Enable shadows for spot lights."}, + {"r_ssao", "Screen Space Ambient Occlusion mode"}, + {"r_ssaoDebug", "Render calculated or blurred Screen Space Ambient Occlusion values"}, + {"r_ssaoDebugMip", "Selects which mip level to render when r_ssaoDebug is enabled. If 0 and r_ssaoDownsample is enabled, will render mip 1."}, + {"r_ssaoDepthScale", "Scale applied to depth values used for occlusion tests."}, + {"r_ssaoDepthScaleViewModel", "Scale applied to depth values used for occlusion tests."}, + {"r_ssaoDownsample", "Screen Space Ambient Occlusion calculation occurs at half linear resolution"}, + {"r_ssaoFadeDepth", "Depth at which the SSAO begins to fade out. It fades at even increments of this distance (e.g. it's at 1 for depth r_ssaoFadeDepth, 1/2 for depth 2*r_ssaoFadeDepth, etc.)"}, + {"r_ssaoGapFalloff", "Falloff used to blend between creases (that should darken) and silhouettes (that should not darken). Lower values falloff more quickly."}, + {"r_ssaoGradientFalloff", "Falloff used to fade out the effect for steep depth gradients (i.e. surfaces nearly parallel to the camera direction). This fixes sampling artifacts that appear for surfaces nearly parallel to the camera direction (commonly occuring for flat ground planes)."}, + {"r_ssaoMaxStrengthDepth", "Depth at which SSAO strength is at its maximum"}, + {"r_ssaoMethod", "Screen Space Ambient Occlusion method (original or IW6, both are volumetric obscurance)"}, + {"r_ssaoMinPixelWidth", "Minimum pixel width of the effect. When the effect is smaller than this, it is culled entirely."}, + {"r_ssaoMinStrengthDepth", "Depth at which SSAO strength is zero, effectively disabled"}, + {"r_ssaoMultiRes", "Screen Space Ambient Occlusion calculation occurs at half linear resolution"}, + {"r_ssaoPower", "Power curve applied to SSAO factor"}, + {"r_ssaoRejectDepth", "Depth at which the SSAO is disabled. Smaller values result in more rejected pixels which is faster, but limits the distance at which the effect is visible."}, + {"r_ssaoSampleCount", "Selects the number of samples used for SSAO"}, + {"r_ssaoScriptScale", "Allows script to lerp to disable or enable the SSAO. This applies a scalar value to the SSAO strength. When set to 0, this effectively disables SSAO."}, + {"r_ssaoStrength", "Strength of Screen Space Ambient Occlusion effect"}, + {"r_ssaoUseTweaks", "Use r_ssao* dvars instead of the current light set values for SSAO"}, + {"r_ssaoWidth", "The width of the SSAO effect, in pixels at 720p. Larger values increase area but lower effective quality."}, + {"r_sse_skinning", "Use Streaming SIMD Extensions for skinning"}, + {"r_ssrBlendScale", "Add extra scale to ssr weight versus reflection probe weight, >1 value will make ssr more obvious."}, + {"r_ssrFadeInDuration", "Duration of the screen-space reflection fade-in, which occurs whenever the reflection source buffer is invalidated due to view changes (in particular, dual-view scope transitions)."}, + {"r_ssrPositionCorrection", "Screen space reflection position correction blend factor"}, + {"r_ssrRoughnessMipParameters", "X: mirror mip; Y: roughest mip; Z: roughness middle point, may need different value for different screen resolution on PC."}, + {"r_sssBlendWeight", "Controls the blend between the wide (zero) and narrow (one) gaussians"}, + {"r_sssDebugMaterial", "Debug Feature: toggle materials with SSS"}, + {"r_sssEnable", "Enables the subsurface scattering effect (note that disabling SSS will not prevent the filter from running)"}, + {"r_sssGlobalRadius", "Controls the global radius (in inches)"}, + {"r_sssJitterRadius", "Percentage of the kernel to be jittered"}, + {"r_sssNarrowRadius", "Controls the narrow Gaussian radius"}, + {"r_sssPreset", "Changes subsurface scattering quality"}, + {"r_sssWideRadius", "Controls the wide Gaussian radius"}, + {"r_subdiv", "Enables Catmull Clark surface subdivision."}, + {"r_subdivLimit", "Set the maximum Catmull Clark subdivision level."}, + {"r_subdivPatchCount", "Patches per thread group for sub-division surfaces."}, + {"r_subdomainLimit", "Maximum number of extra tessellation subdivisions using instancing (max tess amts are 0:64, 1:128, 2:192, 3:256, max instances used are 0:1, 1:4, 2:9, 3:12)"}, + {"r_subdomainScale", "Debug only: Scales the extra subdivision amount (for values < 1, not all instanced sub triangles will draw)."}, + {"r_subwindow", "subwindow to draw: left, right, top, bottom"}, + {"r_sun_from_dvars", "Set sun flare values from dvars rather than the level"}, + {"r_sun_fx_position", "Position in degrees of the sun effect"}, + {"r_sunblind_fadein", "time in seconds to fade blind from 0% to 100%"}, + {"r_sunblind_fadeout", "time in seconds to fade blind from 100% to 0%"}, + {"r_sunblind_max_angle", "angle from sun in degrees inside which effect is max"}, + {"r_sunblind_max_darken", "0-1 fraction for how black the world is at max blind"}, + {"r_sunblind_min_angle", "angle from sun in degrees outside which effect is 0"}, + {"r_sunflare_fadein", "time in seconds to fade alpha from 0% to 100%"}, + {"r_sunflare_fadeout", "time in seconds to fade alpha from 100% to 0%"}, + {"r_sunflare_max_alpha", "0-1 vertex color and alpha of sun at max effect"}, + {"r_sunflare_max_angle", "angle from sun in degrees inside which effect is max"}, + {"r_sunflare_max_size", "largest size of flare effect in pixels at 640x480"}, + {"r_sunflare_min_angle", "angle from sun in degrees outside which effect is 0"}, + {"r_sunflare_min_size", "smallest size of flare effect in pixels at 640x480"}, + {"r_sunflare_shader", "name for flare effect; can be any material"}, + {"r_sunglare_fadein", "time in seconds to fade glare from 0% to 100%"}, + {"r_sunglare_fadeout", "time in seconds to fade glare from 100% to 0%"}, + {"r_sunglare_max_angle", "angle from sun in degrees inside which effect is max"}, + {"r_sunglare_max_lighten", "0-1 fraction for how white the world is at max glare"}, + {"r_sunglare_min_angle", "angle from sun in degrees inside which effect is max"}, + {"r_sunInfDist", "Sun infinite distance used to place sun fx"}, + {"r_sunshadowmap_cmdbuf_worker", "Process shadowmap command buffer in a separate thread"}, + {"r_sunsprite_shader", "name for static sprite; can be any material"}, + {"r_sunsprite_size", "diameter in pixels at 640x480 and 80 fov"}, + {"r_surfaceHDRScalarUseTweaks", "Enables lit and unlit surface scalar tweaks"}, + {"r_tessellation", "Enables tessellation of world geometry, with an optional cutoff distance."}, + {"r_tessellationCutoffDistance", "Distance at which world geometry ceases to tessellate."}, + {"r_tessellationCutoffFalloff", "Range over which tessellation is faded out, up to the cutoff."}, + {"r_tessellationEyeScale", "Scale applied due to eye * object normal for less tessellation on facing polygons."}, + {"r_tessellationFactor", "Target edge length, based on dividing full window height by this factor, for dynamic tessellation. Use zero to disable tessellation."}, + {"r_tessellationHeightAuto", "Correctly auto scale displacement heights for layers to grow as texture is stretched over larger surface areas to preserve feature proportions."}, + {"r_tessellationHeightScale", "Displacement height scale factor."}, + {"r_tessellationHybrid", "Hybrid per pixel displacement scale."}, + {"r_tessellationLodBias", "Displacement map lod bias."}, + {"r_texFilterAnisoMax", "Maximum anisotropy to use for texture filtering"}, + {"r_texFilterAnisoMin", "Minimum anisotropy to use for texture filtering (overridden by max)"}, + {"r_texFilterDisable", "Disables all texture filtering (uses nearest only.)"}, + {"r_texFilterMipBias", "Change the mipmap bias"}, + {"r_texFilterMipMode", "Forces all mipmaps to use a particular blend between levels (or disables mipping.)"}, + {"r_texFilterProbeBilinear", "Force reflection probe to use bilinear filter"}, + {"r_texShowMipMode", "Forces textures with the specified mip filtering to draw black."}, + {"r_thermalColorOffset", "Offset of the thermal colors (offset + scale*color)"}, + {"r_thermalColorScale", "Scale of the thermal colors (offset + scale*color)"}, + {"r_thermalDetailScale", "Scale of the detail that is added to the thermal map from the normal map (multiplies the detail amount from AssetManager)"}, + {"r_thermalFadeColor", "Color the thermal fades to at distance."}, + {"r_thermalFadeControl", "Select thermal fade mode"}, + {"r_thermalFadeMax", "Distance at which thermal stops fading"}, + {"r_thermalFadeMin", "Distance at which thermal starts fading"}, + {"r_tonemap", "HDR Tonemapping mode"}, + {"r_tonemapAdaptSpeed", "HDR Tonemap exposure adaptation speed"}, + {"r_tonemapAuto", "HDR Tonemapping performs auto-exposure"}, + {"r_tonemapAutoExposureAdjust", "HDR Tonemap Auto Exposure Adjust value (set to 0.0 for automatic adjustment)"}, + {"r_tonemapBlack", "HDR Filmic Tonemap black point"}, + {"r_tonemapBlend", "HDR Tonemapping blends between exposures"}, + {"r_tonemapCrossover", "HDR Filmic Tonemap crossover point"}, + {"r_tonemapDarkEv", "HDR Tonemap Dark EV"}, + {"r_tonemapDarkExposureAdjust", "HDR Tonemap Dark Exposure Adjust"}, + {"r_tonemapExposure", "HDR Tonemap exposure (in EV) override (only works in non-auto mode)"}, + {"r_tonemapExposureAdjust", "HDR Tonemap exposure adjustment (in EV, 0 is no adjustment, works like a camera where +1 reduces EV by 1)"}, + {"r_tonemapGamma", "HDR Tonemap gamma curve power"}, + {"r_tonemapHighlightRange", "HDR Tonemap dynamic range, which determines white point luminance"}, + {"r_tonemapLightEv", "HDR Tonemap Light EV"}, + {"r_tonemapLightExposureAdjust", "HDR Tonemap Light Exposure Adjust"}, + {"r_tonemapLockAutoExposureAdjust", "HDR Tonemapping lock auto exposure adjust"}, + {"r_tonemapMaxExposure", "HDR Tonemap maximum exposure (in EV)"}, + {"r_tonemapMaxExposureAdjust", "HDR Tonemap Max Exposure Adjust"}, + {"r_tonemapMidEv", "HDR Tonemap Mid EV"}, + {"r_tonemapMidExposureAdjust", "HDR Tonemap Mid Exposure Adjust"}, + {"r_tonemapMinExposureAdjust", "HDR Tonemap Min Exposure Adjust"}, + {"r_tonemapShoulder", "HDR Filmic Tonemap shoulder control (0 is linear)"}, + {"r_tonemapToe", "HDR Filmic Tonemap toe control (0 is linear)"}, + {"r_tonemapUseCS", "HDR Tonemapping uses compute shader."}, + {"r_tonemapUseTweaks", "Override tone map LightSet settings with tweak dvar values."}, + {"r_tonemapWhite", "HDR Filmic Tonemap white point"}, + {"r_ui3d_debug_display", "Show UI3D debug overlay"}, + {"r_ui3d_h", "ui3d texture window height"}, + {"r_ui3d_use_debug_values", "Use UI debug values"}, + {"r_ui3d_w", "ui3d texture window width"}, + {"r_ui3d_x", "ui3d texture window x"}, + {"r_ui3d_y", "ui3d texture window y"}, + {"r_uiBlurDstMode", "UI blur distortion mode. Fast uses the scene mip map render target, PostSun uses a downsampled post sun resolve buffer, PostSun HQ uses a gaussian blurred post sun resolve buffer."}, + {"r_umbra", "Enables Umbra-based portal culling."}, + {"r_umbraAccurateOcclusionThreshold", "The distance (in inches) to which accurate occlusion information is gathered. -1.0 = deduced automatically."}, + {"r_umbraExclusive", "Toggle Umbra for exclusive static culling (disables static portal dpvs)"}, + {"r_umbraQueryParts", "The number of parts the Umbra query frustum is broken into for async query processing as an M x N grid (0, 0 = all queries are synchronous)."}, + {"r_umbraUseBadPlaces", "Enable/disable ability to disable umbra when inside special volumes defined in mp/umbraBadPlaces.csv."}, + {"r_umbraUseDpvsCullDist", "Use cull distance from the DPVS instead of the far plane distance."}, + {"r_unlitSurfaceHDRScalar", "Vision set based scalar applied to unlit surfaces to balance those surfaces with the luminance of the scene"}, + {"r_useComputeSkinning", "Enables compute shader (GPU) skinning."}, + {"r_useLayeredMaterials", "Set to true to use layered materials on shader model 3 hardware"}, + {"r_useLightGridDefaultFXLightingLookup", "Enable/disable default fx lighting lookup\n"}, + {"r_useLightGridDefaultModelLightingLookup", "Enable/disable default model lighting lookup\n"}, + {"r_useShadowGeomOpt", "Enable iwRad shadow geometry optimization. It only works when we have the data generated in iwRad."}, + {"r_useSunShadowPortals", "Enable sun shadow portals when dir light change and not using cached shadow."}, + {"r_useXAnimIK", "Enables IK animation."}, + {"r_vc_makelog", "Enable logging of light grid points for the vis cache. 1 starts from scratch, 2 appends."}, + {"r_vc_showlog", "Show this many rows of light grid points for the vis cache"}, + {"r_veil", "Apply veiling luminance (HDR glow)"}, + {"r_veilAntialiasing", "Veil antialiasing mode (downsample technique used for first mip)."}, + {"r_veilBackgroundStrength", "Strength of background when applying veiling luminance (HDR glow)"}, + {"r_veilFalloffScale1", "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)"}, + {"r_veilFalloffScale2", "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)"}, + {"r_veilFalloffWeight1", "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)"}, + {"r_veilFalloffWeight2", "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)"}, + {"r_veilFilter", "Changes the veil filtering mode"}, + {"r_veilPreset", "Changes veil sampling quality"}, + {"r_veilRadius", "Controls the radius of the first Gaussian in virtual pixels (remaining Gaussians follow proportionally)."}, + {"r_veilStrength", "Strength of veiling luminance (HDR glow)"}, + {"r_veilUseTweaks", "Override veil LightSet settings with tweak dvar values."}, + {"r_velocityPrepass", "Perform velocity rendering during the depth prepass"}, + {"r_viewModelLightAmbient", ""}, + {"r_viewModelPrimaryLightTweakDiffuseStrength", "Tweak the diffuse intensity for view model primary lights"}, + {"r_viewModelPrimaryLightTweakSpecularStrength", "Tweak the specular intensity for view model primary lights"}, + {"r_viewModelPrimaryLightUseTweaks", ""}, + {"r_volumeLightScatter", "Enables volumetric light scattering"}, + {"r_volumeLightScatterAngularAtten", "Distance of sun from center of screen before angular attenuation starts for god rays"}, + {"r_volumeLightScatterBackgroundDistance", "Distance at which pixels are considered background for volume light scatter effect"}, + {"r_volumeLightScatterColor", ""}, + {"r_volumeLightScatterDepthAttenFar", "Pixels >= than this depth recieve full volume light scatter."}, + {"r_volumeLightScatterDepthAttenNear", "Pixels <= than this depth recieve no volume light scatter."}, + {"r_volumeLightScatterEv", "Light intensity (in EV) for volumetric light scattering"}, + {"r_volumeLightScatterLinearAtten", "Coefficient of linear attenuation of god rays"}, + {"r_volumeLightScatterQuadraticAtten", "Coefficient of quadratic attenuation of god rays)"}, + {"r_volumeLightScatterUseTweaks", "Enables volumetric light scattering tweaks"}, + {"r_vsync", "Enable v-sync before drawing the next frame to avoid 'tearing' artifacts."}, + {"r_warningRepeatDelay", "Number of seconds after displaying a \"per-frame\" warning before it will display again"}, + {"r_wideTessFactorsThreshold", "If a surface has more than this many triangles, process triangles in parallel instead of surfaces."}, + {"r_zfar", "Change the distance at which culling fog reaches 100% opacity; 0 is off"}, + {"r_znear", "Things closer than this aren't drawn. Reducing this increases z-fighting in the distance."}, + {"radarjamDistMax", ""}, + {"radarjamDistMin", ""}, + {"radarjamSinCurve", ""}, + {"radius_damage_debug", "Turn on debug lines for radius damage traces"}, + {"ragdoll_baselerp_time", "Default time ragdoll baselerp bones take to reach the base pose"}, + {"ragdoll_bullet_force", "Bullet force applied to ragdolls"}, + {"ragdoll_bullet_upbias", "Upward bias applied to ragdoll bullet effects"}, + {"ragdoll_dump_anims", "Dump animation data when ragdoll fails"}, + {"ragdoll_enable", "Turn on ragdoll death animations"}, + {"ragdoll_explode_force", "Explosive force applied to ragdolls"}, + {"ragdoll_explode_upbias", "Upwards bias applied to ragdoll explosion effects"}, + {"ragdoll_exploding_bullet_force", "Force applied to ragdolls from explosive bullets"}, + {"ragdoll_exploding_bullet_upbias", "Upwards bias applied to ragdoll from explosive bullets"}, + {"ragdoll_idle_min_velsq", "Minimum squared speed a ragdoll body needs to be moving before it will shut down due to time"}, + {"ragdoll_jitter_scale", "Scale up or down the effect of physics jitter on ragdolls"}, + {"ragdoll_jointlerp_time", "Default time taken to lerp down ragdoll joint friction"}, + {"ragdoll_link_to_moving_platform", "Enable client-side linking of ragdolls to script brush models when they go idle."}, + {"ragdoll_max_life", "Max lifetime of a ragdoll system in msec"}, + {"ragdoll_max_simulating", "Max number of simultaneous active ragdolls - archived"}, + {"ragdoll_max_stretch_pct", "Force ragdoll limbs to not stretch more than this percentage in one frame"}, + {"ragdoll_mp_limit", "Max number of simultaneous active ragdolls - archived"}, + {"ragdoll_mp_resume_share_after_killcam", "Msec after returning from killcam that splitscreen players will share ragdolls again."}, + {"ragdoll_resolve_penetration_bias", "Bias value on force to push ragdolls out of environment."}, + {"ragdoll_rotvel_scale", "Ragdoll rotational velocity estimate scale"}, + {"ragdoll_self_collision_scale", "Scale the size of the collision capsules used to prevent ragdoll limbs from interpenetrating"}, + {"ragdoll_stretch_iters", "Iterations to run the alternate limb solver"}, + {"rankedPlayEndMatchKeepLobby", "keep the lobby if the lobby host is in our private party."}, + {"rankedPlaylistLockoutDuration", "Time in seconds to lock the ranked play playlist if a player quit the match early."}, + {"rate", "Player's preferred network rate"}, + {"RemoteCameraSounds_DryLevel", ""}, + {"RemoteCameraSounds_RoomType", ""}, + {"RemoteCameraSounds_WetLevel", ""}, + {"requireOpenNat", ""}, + {"restrictMapPacksToGroups", "Restrict map pack usage to needing all maps in an ala carte package in order to use as search criteria"}, + {"riotshield_bullet_damage_scale", "Value to scale bullet damage to deployed riotshield."}, + {"riotshield_deploy_limit_radius", "Min distance deployed riotshields must be from each other."}, + {"riotshield_deploy_trace_parallel", "Report collisions when riotshield traces are parallel to plane of triangle. If disabled traces parallel to triangle planes do not report collisions at all."}, + {"riotshield_deployed_health", "Deployed riotshield health."}, + {"riotshield_destroyed_cleanup_time", "Time (in seconds) destroyed riotshield model persists before disappearing"}, + {"riotshield_explosive_damage_scale", "Value to scale explosive damage to deployed riotshield.."}, + {"riotshield_melee_damage_scale", "Value to scale melee damage to deployed riotshield."}, + {"riotshield_projectile_damage_scale", "Value to scale projectile damage to deployed riotshield."}, + {"s_aggregate_ping_offset", "offset to apply to aggregate ping values"}, + {"s_aggregate_ping_scale", "8-bit fixed-point aggregate ping scaler value"}, + {"s_avg_max_weighting", "weighting from 0-256 of party average ping vs. worst ping"}, + {"s_ds_pingclient_reping_wait_db", "wait this# of frames for the db thread to settle down before repinging"}, + {"s_use_aggregate_datacenter_pings", "use newer system for aggregating party pings"}, + {"safeArea_adjusted_horizontal", "User-adjustable horizontal safe area as a fraction of the screen width"}, + {"safeArea_adjusted_vertical", "User-adjustable vertical safe area as a fraction of the screen height"}, + {"safeArea_horizontal", "Horizontal safe area as a fraction of the screen width"}, + {"safeArea_vertical", "Vertical safe area as a fraction of the screen height"}, + {"scr_conf_numlives", ""}, + {"scr_conf_playerrespawndelay", ""}, + {"scr_conf_roundlimit", ""}, + {"scr_conf_scorelimit", ""}, + {"scr_conf_timelimit", ""}, + {"scr_conf_waverespawndelay", ""}, + {"scr_conf_winlimit", ""}, + {"scr_default_maxagents", ""}, + {"scr_diehard", ""}, + {"scr_disableClientSpawnTraces", ""}, + {"scr_dm_numlives", ""}, + {"scr_dm_playerrespawndelay", ""}, + {"scr_dm_roundlimit", ""}, + {"scr_dm_scorelimit", ""}, + {"scr_dm_timelimit", ""}, + {"scr_dm_waverespawndelay", ""}, + {"scr_dm_winlimit", ""}, + {"scr_dom_numlives", ""}, + {"scr_dom_playerrespawndelay", ""}, + {"scr_dom_roundlimit", ""}, + {"scr_dom_scorelimit", ""}, + {"scr_dom_timelimit", ""}, + {"scr_dom_waverespawndelay", ""}, + {"scr_dom_winlimit", ""}, + {"scr_explBulletMod", ""}, + {"scr_game_allowkillcam", "script allow killcam"}, + {"scr_game_deathpointloss", ""}, + {"scr_game_forceuav", ""}, + {"scr_game_graceperiod", ""}, + {"scr_game_hardpoints", ""}, + {"scr_game_killstreakdelay", ""}, + {"scr_game_lockspectatorpov", "Lock spectator mode globally, 0=freelook/unlocked, 1=first_person, 2=third_person"}, + {"scr_game_onlyheadshots", ""}, + {"scr_game_perks", ""}, + {"scr_game_spectatetype", ""}, + {"scr_game_suicidepointloss", ""}, + {"scr_gameended", ""}, + {"scr_hardcore", ""}, + {"scr_horde_difficulty", ""}, + {"scr_horde_maxagents", ""}, + {"scr_horde_numlives", ""}, + {"scr_horde_playerrespawndelay", ""}, + {"scr_horde_roundlimit", ""}, + {"scr_horde_scorelimit", ""}, + {"scr_horde_timelimit", ""}, + {"scr_horde_waverespawndelay", ""}, + {"scr_horde_winlimit", ""}, + {"scr_infect_numlives", ""}, + {"scr_infect_playerrespawndelay", ""}, + {"scr_infect_roundlimit", ""}, + {"scr_infect_timelimit", ""}, + {"scr_infect_waverespawndelay", ""}, + {"scr_infect_winlimit", ""}, + {"scr_isgamescom", "script use gamescom demo flow"}, + {"scr_maxPerPlayerExplosives", ""}, + {"scr_nukeCancelMode", ""}, + {"scr_nukeTimer", ""}, + {"scr_patientZero", ""}, + {"scr_player_forcerespawn", ""}, + {"scr_player_healthregentime", ""}, + {"scr_player_maxhealth", ""}, + {"scr_player_numlives", ""}, + {"scr_player_respawndelay", ""}, + {"scr_player_sprinttime", ""}, + {"scr_player_suicidespawndelay", ""}, + {"scr_RequiredMapAspectratio", ""}, + {"scr_riotShieldXPBullets", ""}, + {"scr_sd_bombtimer", ""}, + {"scr_sd_defusetime", ""}, + {"scr_sd_multibomb", ""}, + {"scr_sd_numlives", ""}, + {"scr_sd_planttime", ""}, + {"scr_sd_playerrespawndelay", ""}, + {"scr_sd_roundlimit", ""}, + {"scr_sd_roundswitch", ""}, + {"scr_sd_scorelimit", ""}, + {"scr_sd_timelimit", ""}, + {"scr_sd_waverespawndelay", ""}, + {"scr_sd_winlimit", ""}, + {"scr_sr_bombtimer", ""}, + {"scr_sr_defusetime", ""}, + {"scr_sr_multibomb", ""}, + {"scr_sr_numlives", ""}, + {"scr_sr_planttime", ""}, + {"scr_sr_playerrespawndelay", ""}, + {"scr_sr_roundlimit", ""}, + {"scr_sr_roundswitch", ""}, + {"scr_sr_scorelimit", ""}, + {"scr_sr_timelimit", ""}, + {"scr_sr_waverespawndelay", ""}, + {"scr_sr_winlimit", ""}, + {"scr_team_fftype", "script team friendly fire type"}, + {"scr_team_respawntime", ""}, + {"scr_team_teamkillpointloss", ""}, + {"scr_team_teamkillspawndelay", ""}, + {"scr_thirdPerson", ""}, + {"scr_tispawndelay", ""}, + {"scr_war_halftime", ""}, + {"scr_war_numlives", ""}, + {"scr_war_playerrespawndelay", ""}, + {"scr_war_roundlimit", ""}, + {"scr_war_roundswitch", ""}, + {"scr_war_scorelimit", ""}, + {"scr_war_timelimit", ""}, + {"scr_war_waverespawndelay", ""}, + {"scr_war_winlimit", ""}, + {"scr_xpscale", ""}, + {"screenshots_active", "Are we allowed to enable Screenshots or not"}, + {"search_weight_asn", "The weight used for the asn in weighted matchmaking."}, + {"search_weight_country_code", "The weight used for the country code in weighted matchmaking."}, + {"search_weight_lat_long", "The weight used for the lat long in weighted matchmaking."}, + {"sensitivity", "Mouse sensitivity"}, + {"sentry_placement_feet_offset", "Position of the feet from the center axis."}, + {"sentry_placement_feet_trace_dist_z", "Max distance for a foot to be considered touching the ground"}, + {"sentry_placement_trace_dist", "Distance along the trace axis where the sentry will attempt to position itself"}, + {"sentry_placement_trace_min_normal", "Minimum normal to accept a sentry position"}, + {"sentry_placement_trace_parallel", "Enable turret traces that are parallel to plane of triangle. If 0, traces parallel to triangle planes do not report collisions at all. If 2 (debug-only), then trace code ping pongs between new and old."}, + {"sentry_placement_trace_pitch", "Pitch used for the trace axis"}, + {"sentry_placement_trace_radius", "Radius of the bound used for the placement trace"}, + {"sentry_placement_trace_radius_canon_safety", "Extra radius used in the forward direction to compensate for the canon length"}, + {"server1", ""}, + {"server10", ""}, + {"server11", ""}, + {"server12", ""}, + {"server13", ""}, + {"server14", ""}, + {"server15", ""}, + {"server16", ""}, + {"server2", ""}, + {"server3", ""}, + {"server4", ""}, + {"server5", ""}, + {"server6", ""}, + {"server7", ""}, + {"server8", ""}, + {"server9", ""}, + {"session_immediateDeleteTinySessions", "Whether to immediately delete sessions with 1 user"}, + {"session_modify_retry_on_failure", "Enable session modify retry on failures."}, + {"session_nonblocking", "Non-blocking Session code"}, + {"shortversion", "Short game version"}, + {"showDebugAmmoCounter", "Show the debug ammo counter when unable to show ar ammo counter"}, + {"showPlaylistTotalPlayers", "Toggle the display of the total number of players in a playlist and online"}, + {"sm_cacheSpotShadows", "Cache spot shadow maps, improves shadow map performance at the cost of memory (requires vid_restart)"}, + {"sm_cacheSpotShadowsEnabled", "Enables caching of spot shadows."}, + {"sm_cacheSunShadow", "Cache sun shadow map, improves shadow map performance at the cost of memory (requires vid_restart)"}, + {"sm_cacheSunShadowEnabled", "Enables caching of sun-based shadows."}, + {"sm_cameraOffset", ""}, + {"sm_dynlightAllSModels", "Enable, from script, rendering all static models in dynamic light volume when shadow mapping"}, + {"sm_enable", "Enable shadow mapping"}, + {"sm_fastSunShadow", "Fast sun shadow"}, + {"sm_lightScore_eyeProjectDist", "When picking shadows for primary lights, measure distance from a point this far in front of the camera."}, + {"sm_lightScore_spotProjectFrac", "When picking shadows for primary lights, measure distance from a point this far in front of the camera."}, + {"sm_maxLightsWithShadows", "Limits how many primary lights can have shadow maps"}, + {"sm_minSpotLightScore", "Minimum score (based on intensity, radius, and position relative to the camera) for a spot light to have shadow maps."}, + {"sm_polygonOffsetBias", "Shadow map offset bias"}, + {"sm_polygonOffsetClamp", "Shadow map offset clamp"}, + {"sm_polygonOffsetPreset", "Shadow map polygon offset preset."}, + {"sm_polygonOffsetScale", "Shadow map offset scale"}, + {"sm_qualitySpotShadow", "Fast spot shadow"}, + {"sm_shadowUseTweaks", "Override shadow LightSet settings with tweak dvar values."}, + {"sm_spotDistCull", "Distance cull spot shadows"}, + {"sm_spotEnable", "Enable spot shadow mapping from script"}, + {"sm_spotFilterRadius", "Spot soft shadows filter radius"}, + {"sm_spotLightScoreModelScale", "Scale the calculated spot light score by this value if the light currently only affects static or script brush models."}, + {"sm_spotLightScoreRadiusPower", "Power to apply to light radius when determining spot light shadowing score (1.0 means radius scales up score a lot, 0.0 means don't scale score using radius)"}, + {"sm_spotLimit", "Limit number of spot shadows from script"}, + {"sm_spotShadowFadeTime", "How many seconds it takes for a primary light shadow map to fade in or out"}, + {"sm_strictCull", "Strict shadow map cull"}, + {"sm_sunEnable", "Enable sun shadow mapping from script"}, + {"sm_sunFilterRadius", "Sun soft shadows filter radius"}, + {"sm_sunSampleSizeNear", "Shadow sample size"}, + {"sm_sunShadowBoundsMax", "Max Shadow Bounds"}, + {"sm_sunShadowBoundsMin", "Min Shadow Bounds"}, + {"sm_sunShadowBoundsOverride", "Override Shadow Bounds"}, + {"sm_sunShadowCenter", "Sun shadow center, 0 0 0 means don't override"}, + {"sm_sunShadowCenterMode", "When false center value only used for far map, when true sets both maps"}, + {"sm_sunShadowScale", "Sun shadow scale optimization"}, + {"sm_sunShadowScaleLocked", "Lock usage of sm_sunShadowScale at 1"}, + {"sm_usedSunCascadeCount", "How many shadow cascade we are using"}, + {"snd_allowHeadphoneHRTF", "Enable HRTF over headphones"}, + {"snd_announcerDisabled", "Disable all in-game announcers"}, + {"snd_announcerVoicePrefix", "Local mp announcer voice to use"}, + {"snd_battlechatterDisabled", "Disable all in-game battle chatter"}, + {"snd_cinematicVolumeScale", "Scales the volume of Bink videos."}, + {"snd_detectedSpeakerConfig", "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround"}, + {"snd_dopplerAuditionEnable", "Enables doppler calculation preview mode"}, + {"snd_dopplerBaseSpeedOfSound", "The base speed of sound used in doppler calculation"}, + {"snd_dopplerEnable", "Enables doppler calculation"}, + {"snd_dopplerPitchMax", "Maximum pitch that can be legally applied by doppler"}, + {"snd_dopplerPitchMin", "Minimum pitch that can be legally applied by doppler"}, + {"snd_dopplerPlayerVelocityScale", "The scale of the player velocity, relative the the sound source velocity, when applied to the doppler calculation"}, + {"snd_dopplerSmoothing", "Smoothing factor applied to doppler to eliminate jitter or sudden acceleration changes"}, + {"snd_draw3D", "Draw the position and info of world sounds"}, + {"snd_drawInfo", "Draw debugging information for sounds"}, + {"snd_enable2D", "Enable 2D sounds"}, + {"snd_enable3D", "Enable 3D sounds"}, + {"snd_enableEq", "Enable equalization filter"}, + {"snd_enableReverb", "Enable sound reverberation"}, + {"snd_enableStream", "Enable streamed sounds"}, + {"snd_envFollowerBuffScale", "Amount of buffer to use for envelope follower. Smaller value indicates faster envelope."}, + {"snd_errorOnMissing", "Cause a Com_Error if a sound file is missing."}, + {"snd_hitsoundDisabled", "Disable the hit indicator sound"}, + {"snd_inheritSecondaryPitchVol", "Set to true for secondary aliases to inherit the pitch of the parent"}, + {"snd_levelFadeTime", "The amout of time in milliseconds for all audio to fade in at the start of a level"}, + {"snd_loadFadeTime", "Fade time for loading from a checkpoint after death."}, + {"snd_loopFadeTime", "Fade-in time for looping sounds."}, + {"snd_musicDisabled", "Disable all in-game music"}, + {"snd_musicDisabledForCustomSoundtrack", "Disable all in-game music due to user playing a custom soundtrack"}, + {"snd_occlusionDelay", "Minimum delay in (ms) between occlusion updates"}, + {"snd_occlusionLerpTime", "Time to lerp to target occlusion lerp when occluded"}, + {"snd_peakLimiterCompression", "Peak limiter compression factor. The output data is scaled by this and then normalized: F < 1 = disabled; F >= 1 enabled."}, + {"snd_peakLimiterDecay", "Peak limiter compression decay ratio."}, + {"snd_peakLimiterSustainFrames", "Number of frames to sustain the limiter peak. 1 frame = 10 msec."}, + {"snd_premixVolume", "Game sound pre-mix volume"}, + {"snd_reverbZoneOutsideFactor", "When a 3d sound is played in a different reverb zone than the player, this factor will be applied to its wet level."}, + {"snd_slaveFadeTime", "The amount of time in milliseconds for a 'slave' sound\nto fade its volumes when a master sound starts or stops"}, + {"snd_speakerConfig", "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround"}, + {"snd_touchStreamFilesOnLoad", "Check whether stream sound files exist while loading"}, + {"snd_useOldPanning", "Use old and busted panning"}, + {"snd_virtualChannelInfo", "Display virtual voice info."}, + {"snd_virtualMinDur", "The minimum duration (in seconds) of a sound if it is to be added to the virtual voice buffer."}, + {"snd_virtualMinPri", "The minimum priority of an alias if it is to be added to the virtual voice buffer."}, + {"snd_virtualMinTimeLeftToRevive", "The minimum time (in ms) left in a sample in order to attempt to revive it."}, + {"snd_virtualReviveVoices", "Whether or not to restore virtual voices."}, + {"snd_virtualWaitToReviveTime", "The minimum time (in ms) to wait before trying to revive the voice."}, + {"snd_volume", "Game sound master volume"}, + {"speech_active", "Are we allowed to enable Speech or not"}, + {"splitscreen", "Current game is a splitscreen game"}, + {"steam_ingame_p2p_throttle", "Time, in MS, to wait between P2P packet lookups when in-game"}, + {"stringtable_debug", "spam debug info for stringtable lookups"}, + {"sv_allowClientConsole", "Allow remote clients to access the console"}, + {"sv_allowedClan1", ""}, + {"sv_allowedClan2", ""}, + {"sv_archiveClientsPositions", "Archive the client positions to speed up SV_GetClientPositionsAtTime"}, + {"sv_checkMinPlayers", "Check min players. 0 disables"}, + {"sv_clientArchive", "Have the clients archive data to save bandwidth on the server"}, + {"sv_connectTimeout", "seconds without any message when a client is loading"}, + {"sv_cumulThinkTime", "Max client think per server 50 msec frame"}, + {"sv_error_on_baseline_failure", "Throw an error if the const baseline data is invalid."}, + {"sv_exponentialBackoffAfterNonAckedMsgs", "start exponential backoff on msg frequency if the client has not acked the last X messages"}, + {"sv_hostname", "Host name of the server"}, + {"sv_hugeSnapshotDelay", "How long to wait before building a new snapshot after a 'huge' snapshot is sent"}, + {"sv_hugeSnapshotSize", "Size of a snapshot to be considered 'huge'"}, + {"sv_kickBanTime", "Time in seconds for a player to be banned from the server after being kicked"}, + {"sv_local_client_snapshot_msec", "Local client snapshot rate, add to cl_penaltyTime"}, + {"sv_maxclients", "The maximum number of clients that can connect to a server"}, + {"sv_minPingClamp", "Clamp the minimum ping to this value"}, + {"sv_network_fps", "Number of times per second the server checks for net messages"}, + {"sv_numExpBackoffBeforeReleasingCachedSnapshots", "if a client is under an exponential backoff over this dvar, then we will release all the cached snapshot data he owns and will send him a baseline if he reconnects"}, + {"sv_paused", "Pause the server"}, + {"sv_privateClients", "Maximum number of private clients allowed on the server"}, + {"sv_privateClientsForClients", "The # of private clients (we send this to clients)"}, + {"sv_privatePassword", "password for the privateClient slots"}, + {"sv_reconnectlimit", "minimum seconds between connect messages"}, + {"sv_rejoinTimeout", "seconds without any message before allowing a rejoin"}, + {"sv_remote_client_snapshot_joiningstate_msec", "Remote client snapshot rate during join (until the client acked his first delta message)"}, + {"sv_remote_client_snapshot_msec", "Remote client snapshot rate, add to cl_penaltyTime"}, + {"sv_resetOnSpawn", "Have clients reset some player state fields when spawning rather than sending them over the network"}, + {"sv_running", "Server is running"}, + {"sv_sayName", ""}, + {"sv_showAverageBPS", "Show average bytes per second for net debugging"}, + {"sv_testValue", "Max antilag rewind"}, + {"sv_timeout", "seconds without any message"}, + {"sv_trackFrameMsecThreshold", "server frame time that will trigger script time tracking."}, + {"sv_useExtraCompress", "Use zlib compress for gamestate/baseline/score packets"}, + {"sv_zlib_threshold", "Message size threshold which triggers more aggressive compression"}, + {"sv_zombietime", "seconds to sync messages after disconnect"}, + {"svwp", "playerdata server write protection: 0 = disable, 1 = silent, 2 = kick"}, + {"syncTimeTimeout", "default timeout for sync time task (in seconds)"}, + {"sys_configSum", "Configuration checksum"}, + {"sys_configureGHz", "Normalized total CPU power, based on cpu type, count, and speed; used in autoconfigure"}, + {"sys_cpuGHz", "Measured CPU speed"}, + {"sys_cpuName", "CPU name description"}, + {"sys_gpu", "GPU description"}, + {"sys_lockThreads", "Prevents specified threads from changing CPUs; improves profiling and may fix some bugs, but can hurt performance"}, + {"sys_quitMigrateTime", "Time in msec to wait for host migration when user closes the window"}, + {"sys_smp_allowed", "Allow multi-threading"}, + {"sys_SSE", "Operating system allows Streaming SIMD Extensions"}, + {"sys_sysMB", "Physical memory in the system"}, + {"systemlink", "Current game is a system link game"}, + {"systemlink_host", "Local client is hosting system link game"}, + {"tb_report", "tb event record"}, + {"team_rebalance", "rebalance"}, + {"teambalance_option", "Selects active teambalance algorithm. 0 = heuristic 1 = exhaustive"}, + {"theater_active", "Are we allowed to show theater or not."}, + {"thermal_playerModel", "Model to draw for players when in thermal vision mode"}, + {"thermalBlurFactorNoScope", "Amount of blur to use when drawing blur through a weapon's thermal scope."}, + {"thermalBlurFactorScope", "Amount of blur to use when drawing blur through a weapon's thermal scope."}, + {"tokensEnabled", "Is token economy enabled"}, + {"tracer_explosiveColor1", "The 1st color of a bullet tracer when using explosive bullets"}, + {"tracer_explosiveColor2", "The 2nd color of a bullet tracer when using explosive bullets"}, + {"tracer_explosiveColor3", "The 3rd color of a bullet tracer when using explosive bullets"}, + {"tracer_explosiveColor4", "The 4th color of a bullet tracer when using explosive bullets"}, + {"tracer_explosiveColor5", "The 5th color of a bullet tracer when using explosive bullets"}, + {"tracer_explosiveOverride", "When turned on, will apply an override to the tracer settings when shooting explosive bullets."}, + {"tracer_explosiveWidth", "The width of a bullet tracer when using explosive bullets"}, + {"tracer_firstPersonMaxWidth", "The maximum width our OWN tracers can be when looking through our ADS"}, + {"tracer_stoppingPowerColor1", "The 1st color of a bullet tracer when using explosive bullets"}, + {"tracer_stoppingPowerColor2", "The 2nd color of a bullet tracer when using explosive bullets"}, + {"tracer_stoppingPowerColor3", "The 3rd color of a bullet tracer when using explosive bullets"}, + {"tracer_stoppingPowerColor4", "The 4th color of a bullet tracer when using explosive bullets"}, + {"tracer_stoppingPowerColor5", "The 5th color of a bullet tracer when using explosive bullets"}, + {"tracer_stoppingPowerOverride", "When turned on, will apply an override to the tracer settings when shooting explosive bullets."}, + {"tracer_stoppingPowerWidth", "The width of a bullet tracer when using explosive bullets"}, + {"tracer_thermalWidthMult", "The multiplier applied to the base width when viewed in thermal vision"}, + {"transients_verbose", "Verbose logging information for transient fastfiles."}, + {"triggerDLCEnumerationOnSocialConfigLoad", "Triggers a new DLC enumeration after social config has loaded."}, + {"ui_allow_controlschange", ""}, + {"ui_allow_teamchange", ""}, + {"ui_autodetectGamepad", "undefined"}, + {"ui_autodetectGamepadDone", "undefined"}, + {"ui_bigFont", "Big font scale"}, + {"ui_blurAmount", "Max amount to blur background menu items."}, + {"ui_blurDarkenAmount", "Amount to darken blurred UI."}, + {"ui_blurTime", "Time in milliseconds to fade in/out the blur."}, + {"ui_borderLowLightScale", "Scales the border color for the lowlight color on certain UI borders"}, + {"ui_browserFriendlyfire", "Friendly fire is active"}, + {"ui_browserKillcam", "Kill cam is active"}, + {"ui_browserMod", "UI Mod value"}, + {"ui_browserShowDedicated", "Show dedicated servers only"}, + {"ui_browserShowEmpty", "Show empty servers"}, + {"ui_browserShowFull", "Show full servers"}, + {"ui_browserShowPassword", "Show servers that are password protected"}, + {"ui_browserShowPure", "Show pure servers only"}, + {"ui_buildLocation", "Where to draw the build number"}, + {"ui_buildSize", "Font size to use for the build number"}, + {"ui_challenge_1_ref", ""}, + {"ui_challenge_2_ref", ""}, + {"ui_challenge_3_ref", ""}, + {"ui_challenge_4_ref", ""}, + {"ui_challenge_5_ref", ""}, + {"ui_challenge_6_ref", ""}, + {"ui_challenge_7_ref", ""}, + {"ui_changeclass_menu_open", ""}, + {"ui_changeteam_menu_open", ""}, + {"ui_cinematicsTimestamp", "Shows cinematics timestamp on subtitle UI elements."}, + {"ui_class_menu_open", ""}, + {"ui_connectScreenTextGlowColor", "Glow color applied to the mode and map name strings on the connect screen."}, + {"ui_contextualMenuLocation", "Contextual menu location from where you entered the store."}, + {"ui_controls_menu_open", ""}, + {"ui_currentFeederMapIndex", "Currently selected map"}, + {"ui_currentMap", "Current map index"}, + {"ui_customClassName", "Custom Class name"}, + {"ui_customModeEditName", "Name to give the currently edited custom game mode when editing is complete"}, + {"ui_customModeName", "Custom game mode name"}, + {"ui_danger_team", ""}, + {"ui_debugMode", "Draw ui debug info on the screen."}, + {"ui_disableInGameStore", "This will disable the ingame store button on the xbox live menu."}, + {"ui_disableTokenRedemption", "This will disable the token redemption option in the in-game store menu."}, + {"ui_drawCrosshair", "Whether to draw crosshairs."}, + {"ui_editSquadMemberIndex", "Which squad member is currently being edited"}, + {"ui_extraBigFont", "Extra big font scale"}, + {"ui_game_state", ""}, + {"ui_gametype", "Current game type"}, + {"ui_halftime", ""}, + {"ui_hitloc_0", ""}, + {"ui_hitloc_1", ""}, + {"ui_hitloc_2", ""}, + {"ui_hitloc_3", ""}, + {"ui_hitloc_4", ""}, + {"ui_hitloc_5", ""}, + {"ui_hitloc_damage_0", ""}, + {"ui_hitloc_damage_1", ""}, + {"ui_hitloc_damage_2", ""}, + {"ui_hitloc_damage_3", ""}, + {"ui_hitloc_damage_4", ""}, + {"ui_hitloc_damage_5", ""}, + {"ui_hud_hardcore", "Whether the HUD should be suppressed for hardcore mode"}, + {"ui_hud_obituaries", ""}, + {"ui_inactiveBaseColor", "The local player's rank/stats font color when shown in lobbies and parties"}, + {"ui_inactivePartyColor", ""}, + {"ui_inGameStoreOpen", "is the InGameStore open"}, + {"ui_inhostmigration", ""}, + {"ui_joinGametype", "Game join type"}, + {"ui_loadMenuName", "Frontend menu will start on this level instead of lockout"}, + {"ui_mapname", "Current map name"}, + {"ui_mapvote_entrya_gametype", "Primary map vote entry game type"}, + {"ui_mapvote_entrya_mapname", "Primary map vote entry map name"}, + {"ui_mapvote_entryb_gametype", "Secondary map vote entry game type"}, + {"ui_mapvote_entryb_mapname", "Secondary map vote entry map name"}, + {"ui_maxclients", "undefined"}, + {"ui_missingMapName", "Name of map to show in missing content error"}, + {"ui_mousePitch", ""}, + {"ui_multiplayer", "True if the game is multiplayer"}, + {"ui_myPartyColor", "Player name font color when in the same party as the local player"}, + {"ui_netGametype", "Game type"}, + {"ui_netGametypeName", "Displayed game type name"}, + {"ui_netSource", "The network source where:\n 0:Local\n 1:Internet\n 2:Favourites"}, + {"ui_onlineRequired", "UI requires online connection to be present."}, + {"ui_opensummary", ""}, + {"ui_override_halftime", ""}, + {"ui_partyFull", "True if the current party is full."}, + {"ui_playerPartyColor", ""}, + {"ui_playlistActionButtonAlpha", "The current alpha of the playlist selection button"}, + {"ui_playlistCategoryDisabledColor", "The color of playlist categories when disabled"}, + {"ui_playlistCategoryEnabledColor", "The color of playlist categories when enabled"}, + {"ui_promotion", ""}, + {"ui_remoteTankUseTime", ""}, + {"ui_scorelimit", ""}, + {"ui_selectedFeederMap", "Current preview game type"}, + {"ui_serverStatusTimeOut", "Time in milliseconds before a server status request times out"}, + {"ui_show_store", "Use to enable the store button"}, + {"ui_showDLCMaps", "Whether to display the DLC maps."}, + {"ui_showInfo", ""}, + {"ui_showList", "Show onscreen list of currently visible menus"}, + {"ui_showmap", ""}, + {"ui_showMenuOnly", "If set, only menus using this name will draw."}, + {"ui_showMinimap", ""}, + {"ui_sliderSteps", "The number of steps for a slider itemdef"}, + {"ui_smallFont", "Small font scale"}, + {"ui_textScrollFadeTime", "Text scrolling takes this long (seconds) to fade out at the end before restarting"}, + {"ui_textScrollPauseEnd", "Text scrolling waits this long (seconds) before starting"}, + {"ui_textScrollPauseStart", "Text scrolling waits this long (seconds) before starting"}, + {"ui_textScrollSpeed", "Speed at which text scrolls vertically"}, + {"ui_timelimit", ""}, + {"uiscript_debug", "spam debug info for the ui script"}, + {"unlock_breadcrumb_killswitch", "True to enable unlock breadcrumbs"}, + {"uno_current_tos_version", "Current Uno Terms of Service Version"}, + {"use_filtered_query_pass", "Dictates whether to use the filtered query for MMing or not"}, + {"use_weighted_dlc_exactmatch_pass", "Dictates whether to use a search weighted pass with the DLC match set to exact for MMing or not"}, + {"use_weighted_pass", "Dictates whether to use the search weighted pass for MMing or not"}, + {"useCPMarkerForCPOwnership", "If set, we will check the player inventory to see if he owns the redeemedItem for a contentPack if this contentPack is not available for the player"}, + {"useonlinestats", "Whether to use online stats when in offline modes"}, + {"useRelativeTeamColors", "Whether to use relative team colors."}, + {"userFileFetchTimeout", "default timeout for user files FETCH tasks (in seconds)"}, + {"userGroup_active", "Are we allowed to show Usergroups or not"}, + {"userGroup_cool_off_time", "Cool off time between calls to fetch the elite clan"}, + {"userGroup_coop_delay", "Delay between a player joining a coop lobby and the DW user group task starting"}, + {"userGroup_max_retry_time", "Max time that the usergroup read find can retry"}, + {"userGroup_refresh_time_secs", "Time in seconds between re-sending lobby group data to confirmed users."}, + {"userGroup_retry_step", "Step in m/s for the usegroup read retry"}, + {"userGroup_RetryTime", "Time in ms between sending lobby group data retrys."}, + {"useStatsGroups", "If true then StatsGroups are in use for all playerdata.ddl accessing."}, + {"useTagFlashSilenced", "When true, silenced weapons will use \"tag_flash_silenced\" instead of \"tag_flash\"."}, + {"using_mlg", "MLG feature on/off"}, + {"validate_apply_clamps", "True if individual stat validation failure reverts the value"}, + {"validate_apply_revert", "True if individual stat validation failure reverts the value"}, + {"validate_apply_revert_full", "True if any individual stat validation failure causes a full stats revert"}, + {"validate_clamp_assists", "The maximum number of assists a player can make in a match"}, + {"validate_clamp_experience", "The maximum experience a player can gain in a match"}, + {"validate_clamp_headshots", "The maximum number of headshots a player can make in a match"}, + {"validate_clamp_hits", "The maximum number of hits player can make in a match"}, + {"validate_clamp_kills", "The maximum number of kills a player can make in a match"}, + {"validate_clamp_losses", "The maximum number of losses a player can make in a match"}, + {"validate_clamp_misses", "The maximum number of misses player can make in a match"}, + {"validate_clamp_ties", "The maximum number of ties a player can make in a match"}, + {"validate_clamp_totalshots", "The maximum number of totalshots player can make in a match"}, + {"validate_clamp_weaponXP", "The maximum experience a weapon can gain in a match"}, + {"validate_clamp_wins", "The maximum number of wins a player can make in a match"}, + {"validate_drop_on_fail", "True if stats validation failure results in dropping from the match"}, + {"veh_aiOverSteerScale", "Scaler used to cause ai vehicles to over steer"}, + {"veh_boneControllerLodDist", "Distance at which bone controllers are not updated."}, + {"veh_boneControllerUnLodDist", "Distance at which bone controllers start updating when not moving."}, + {"vehAudio_inAirPitchDownLerp", "Rate at which the pitch lerps down"}, + {"vehAudio_inAirPitchUpLerp", "Rate at which the pitch lerps up"}, + {"vehAudio_spawnVolumeTime", "Seconds it takes for spawned vehicles to reach full volume."}, + {"vehCam_freeLook", "Enables free look mode"}, + {"vehCam_mode", "Camera modes: 1st person, 3rd person, or both"}, + {"vehDroneDebugDrawPath", "Debug render the drone draw paths."}, + {"vehHelicopterBoundsRadius", "The radius of the collision volume to be used when colliding with world geometry."}, + {"vehHelicopterDecelerationFwd", "Set the deceleration of the player helicopter (as a fraction of acceleration) in the direction the chopper is facing. So 1.0 makes it equal to the acceleration."}, + {"vehHelicopterDecelerationSide", "Set the side-to-side deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration."}, + {"vehHelicopterDecelerationUp", "Set the vertical deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration."}, + {"vehHelicopterHeadSwayDontSwayTheTurret", "If set, the turret will not fire through the crosshairs, but straight ahead of the vehicle, when the player is not freelooking."}, + {"vehHelicopterHoverSpeedThreshold", "The speed below which the player helicopter begins to jitter the tilt, for hovering"}, + {"vehHelicopterInvertUpDown", "Invert the altitude control on the player helicopter."}, + {"vehHelicopterJitterJerkyness", "Specifies how jerky the tilt jitter should be"}, + {"vehHelicopterLookaheadTime", "How far ahead (in seconds) the player helicopter looks ahead, to avoid hard collisions. (Like driving down the highway, you should keep 2 seconds distance between you and the vehicle in front of you)"}, + {"vehHelicopterMaxAccel", "Maximum horizontal acceleration of the player helicopter (in MPH per second)"}, + {"vehHelicopterMaxAccelVertical", "Maximum vertical acceleration of the player helicopter (in MPH per second)"}, + {"vehHelicopterMaxPitch", "Maximum pitch of the player helicopter"}, + {"vehHelicopterMaxRoll", "Maximum roll of the player helicopter"}, + {"vehHelicopterMaxSpeed", "Maximum horizontal speed of the player helicopter (in MPH)"}, + {"vehHelicopterMaxSpeedVertical", "Maximum vertical speed of the player helicopter (in MPH)"}, + {"vehHelicopterMaxYawAccel", "Maximum yaw acceleration of the player helicopter"}, + {"vehHelicopterMaxYawRate", "Maximum yaw speed of the player helicopter"}, + {"vehHelicopterPitchOffset", "The resting pitch of the helicopter"}, + {"vehHelicopterRightStickDeadzone", "Dead-zone for the axes of the right thumbstick. This helps to better control the two axes separately."}, + {"vehHelicopterScaleMovement", "Scales down the smaller of the left stick axes."}, + {"vehHelicopterSoftCollisions", "Player helicopters have soft collisions (slow down before they collide)."}, + {"vehHelicopterStrafeDeadzone", "Dead-zone so that you can fly straight forward easily without accidentally strafing (and thus rolling)."}, + {"vehHelicopterTiltFromAcceleration", "The amount of tilt caused by acceleration"}, + {"vehHelicopterTiltFromControllerAxes", "The amount of tilt caused by the desired velocity (i.e., the amount of controller stick deflection)"}, + {"vehHelicopterTiltFromDeceleration", "The amount of tilt caused by deceleration"}, + {"vehHelicopterTiltFromFwdAndYaw", "The amount of roll caused by yawing while moving forward."}, + {"vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt", "The forward speed (as a fraction of top speed) at which the tilt due to yaw reaches is maximum value."}, + {"vehHelicopterTiltFromVelocity", "The amount of tilt caused by the current velocity"}, + {"vehHelicopterTiltMomentum", "The amount of rotational momentum the helicopter has with regards to tilting."}, + {"vehHelicopterTiltSpeed", "The rate at which the player helicopter's tilt responds"}, + {"vehHelicopterYawOnLeftStick", "The yaw speed created by the left stick when pushing the stick diagonally (e.g., moving forward and strafing slightly)."}, + {"vehicle_debug_render_spline_plane", "Do we want to render the spline plane data"}, + {"vehicle_pathsmooth", "Smoothed vehicle pathing."}, + {"vehUGVPitchTrack", "UGV body pitch orientation speed"}, + {"vehUGVRollTrack", "UGV body roll orientation speed"}, + {"vehUGVWheelInfluence", "UGV wheel influence on the orientation of the body"}, + {"vehWalkerControlMode", "Walker controls (0==move no turn, 1=move and turn, 2=move relative(tank))"}, + {"version", "Game version"}, + {"vid_xpos", "Game window horizontal position"}, + {"vid_ypos", "Game window vertical position"}, + {"viewangNow", ""}, + {"viewModelDebugNotetracks", "Enable display of viewmodel notetrack debug info."}, + {"viewModelHacks", "Enabled depth hack and remove viewmodel from shadows."}, + {"viewposNow", ""}, + {"virtualLobbyActive", "Indicates the VL is actively being displayed."}, + {"virtualLobbyAllocated", "Indicates the first VL zone has been loaded."}, + {"virtualLobbyEnabled", "VirtualLobby is enabled (must be true before loading UI zone)"}, + {"virtualLobbyInFiringRange", "VirtualLobby is in firing range mode"}, + {"virtualLobbyMap", "VirtualLobby map to load (must be set before starting vl)"}, + {"virtualLobbyMembers", "Number of members in the VirtualLobby (set by script)"}, + {"virtualLobbyPresentable", "Indicates to LUA the VirtualLobby is ready to be displayed (set by script)."}, + {"virtualLobbyReady", "Indicates to LUA the VirtualLobby is loaded and running (set by script)."}, + {"vl_clan_models_loaded", "Indicates to LUA when all models are loaded for the clan highlights so it can begin the fade-in without any popping(set by script)."}, + {"voMtxEnable", "When set (e.g. via config), will enable voice over packs"}, + {"waypointAerialIconMaxSize", "Max size of aerial targeting waypoints."}, + {"waypointAerialIconMinSize", "Min size of aerial targeting waypoints."}, + {"waypointAerialIconScale", "Base scale of aerial targeting waypoints."}, + {"waypointDebugDraw", ""}, + {"waypointDistScaleRangeMax", "Distance from player that icon distance scaling ends."}, + {"waypointDistScaleRangeMin", "Distance from player that icon distance scaling ends."}, + {"waypointDistScaleSmallest", "Smallest scale that the distance effect uses."}, + {"waypointIconHeight", ""}, + {"waypointIconWidth", ""}, + {"waypointOffscreenCornerRadius", "Size of the rounded corners."}, + {"waypointOffscreenDistanceThresholdAlpha", "Distance from the threshold over which offscreen objective icons lerp their alpha."}, + {"waypointOffscreenPadBottom", ""}, + {"waypointOffscreenPadLeft", ""}, + {"waypointOffscreenPadRight", ""}, + {"waypointOffscreenPadTop", ""}, + {"waypointOffscreenPointerDistance", "Distance from the center of the offscreen objective icon to the center its arrow."}, + {"waypointOffscreenPointerHeight", ""}, + {"waypointOffscreenPointerWidth", ""}, + {"waypointOffscreenRoundedCorners", "Off-screen icons take rounded corners when true. 90-degree corners when false."}, + {"waypointOffscreenScaleLength", "How far the offscreen icon scale travels from full to smallest scale."}, + {"waypointOffscreenScaleSmallest", "Smallest scale that the offscreen effect uses."}, + {"waypointPlayerOffsetCrouch", "For waypoints pointing to players, how high to offset off of their origin when they are prone."}, + {"waypointPlayerOffsetProne", "For waypoints pointing to players, how high to offset off of their origin when they are prone."}, + {"waypointPlayerOffsetStand", "For waypoints pointing to players, how high to offset off of their origin when they are prone."}, + {"waypointScreenCenterFadeAdsMin", "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads"}, + {"waypointScreenCenterFadeHipMin", "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads"}, + {"waypointScreenCenterFadeRadius", "Radius from screen center that a waypoint will start fading out. Setting to 0 will turn this off"}, + {"waypointSplitscreenScale", "Scale applied to waypoint icons in splitscreen views."}, + {"waypointTweakY", ""}, + {"weap_thermoDebuffMod", ""}, + {"wideScreen", "True if the game video is running in 16x9 aspect, false if 4x3."}, + {"winvoice_loopback", "Echo microphone input locally"}, + {"winvoice_mic_mute", "Mute the microphone"}, + {"winvoice_mic_outTime", "Microphone voice amount of silence before we cut the mic"}, + {"winvoice_mic_reclevel", "Microphone recording level"}, + {"winvoice_mic_scaler", "Microphone scaler value"}, + {"winvoice_mic_threshold", "Microphone voice threshold"}, + {"winvoice_save_voice", "Write voice data to a file"}, + {"xanim_disableIK", "Disable inverse kinematics solvers"}, + {"xblive_competitionmatch", "MLG Rules?"}, + {"xblive_hostingprivateparty", "true only if we're hosting a party"}, + {"xblive_loggedin", "User is logged into xbox live"}, + {"xblive_privatematch", "Current game is a private match"}, + {"xblive_privatematch_solo", "Current game is an Extinction solo match"}, + {"xphys_maxJointPositionError", "If a joints with position error exceeding this value is detected, then the whole xphys system gets snapped back to the animation pose"}, }; + std::string dvar_get_description(const std::string& name) + { + const auto lower = utils::string::to_lower(name); + for (std::uint32_t i = 0; i < dvar_list.size(); i++) + { + if (utils::string::to_lower(dvar_list[i].name) == lower) + { + return dvar_list[i].description; + } + } + + return {}; + } + bool can_add_dvar_to_list(std::string name) { + const auto lower = utils::string::to_lower(name); for (std::uint32_t i = 0; i < dvar_list.size(); i++) { - if (dvar_list[i] == name) + if (utils::string::to_lower(dvar_list[i].name) == lower) { return false; } } + return true; } game::dvar_t* register_int(const std::string& name, int value, int min, int max, - game::DvarFlags flags, bool add_to_list) + game::DvarFlags flags, const std::string& description) { const auto hash = game::generateHashValue(name.data()); - if (add_to_list && can_add_dvar_to_list(name)) + if (can_add_dvar_to_list(name)) { - dvar_list.push_back(name); + dvar_list.push_back({name, description}); } return game::Dvar_RegisterInt(hash, "", value, min, max, flags); } game::dvar_t* register_bool(const std::string& name, bool value, - game::DvarFlags flags, bool add_to_list) + game::DvarFlags flags, const std::string& description) { const auto hash = game::generateHashValue(name.data()); - if (add_to_list && can_add_dvar_to_list(name)) + if (can_add_dvar_to_list(name)) { - dvar_list.push_back(name); + dvar_list.push_back({name, description}); } return game::Dvar_RegisterBool(hash, "", value, flags); } game::dvar_t* register_string(const std::string& name, const char* value, - game::DvarFlags flags, bool add_to_list) + game::DvarFlags flags, const std::string& description) { const auto hash = game::generateHashValue(name.data()); - if (add_to_list && can_add_dvar_to_list(name)) + if (can_add_dvar_to_list(name)) { - dvar_list.push_back(name); + dvar_list.push_back({name, description}); } return game::Dvar_RegisterString(hash, "", value, flags); } game::dvar_t* register_float(const std::string& name, float value, float min, - float max, game::DvarFlags flags, bool add_to_list) + float max, game::DvarFlags flags, const std::string& description) { const auto hash = game::generateHashValue(name.data()); - if (add_to_list && can_add_dvar_to_list(name)) + if (can_add_dvar_to_list(name)) { - dvar_list.push_back(name); + dvar_list.push_back({name, description}); } return game::Dvar_RegisterFloat(hash, "", value, min, max, flags); } game::dvar_t* register_vec4(const std::string& name, float x, float y, float z, - float w, float min, float max, game::DvarFlags flags, bool add_to_list) + float w, float min, float max, game::DvarFlags flags, const std::string& description) { const auto hash = game::generateHashValue(name.data()); - if (add_to_list && can_add_dvar_to_list(name)) + if (can_add_dvar_to_list(name)) { - dvar_list.push_back(name); + dvar_list.push_back({name, description}); } return game::Dvar_RegisterVec4(hash, "", x, y, z, w, min, max, flags); diff --git a/src/client/game/dvars.hpp b/src/client/game/dvars.hpp index 1a48de7c..5ac42230 100644 --- a/src/client/game/dvars.hpp +++ b/src/client/game/dvars.hpp @@ -6,6 +6,12 @@ namespace dvars { + struct dvar_info + { + std::string name; + std::string description; + }; + extern game::dvar_t* aimassist_enabled; extern game::dvar_t* con_inputBoxColor; @@ -25,14 +31,20 @@ namespace dvars extern game::dvar_t* cg_legacyCrashHandling; - extern std::vector dvar_list; + extern std::vector dvar_list; std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain); std::string dvar_get_domain(const game::dvar_type type, const game::dvar_limits& domain); + std::string dvar_get_description(const std::string& name); - game::dvar_t* register_int(const std::string& name, int value, int min, int max, game::DvarFlags flags, bool add_to_list = true); - game::dvar_t* register_bool(const std::string& name, bool value, game::DvarFlags flags, bool add_to_list = true); - game::dvar_t* register_string(const std::string& name, const char* value, game::DvarFlags flags, bool add_to_list = true); - game::dvar_t* register_float(const std::string& name, float value, float min, float max, game::DvarFlags flags, bool add_to_list = true); - game::dvar_t* register_vec4(const std::string& name, float x, float y, float z, float w, float min, float max, game::DvarFlags flags, bool add_to_list = true); + game::dvar_t* register_int(const std::string& name, int value, int min, int max, + game::DvarFlags flags, const std::string& description); + game::dvar_t* register_bool(const std::string& name, bool value, + game::DvarFlags flags, const std::string& description); + game::dvar_t* register_string(const std::string& name, const char* value, + game::DvarFlags flags, const std::string& description); + game::dvar_t* register_float(const std::string& name, float value, float min, float max, + game::DvarFlags flags, const std::string& description); + game::dvar_t* register_vec4(const std::string& name, float x, float y, float z, float w, float min, + float max, game::DvarFlags flags, const std::string& description); } From e65c6c7327ceb5905f21fc7c603bac801f645a94 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 01:07:16 +0100 Subject: [PATCH 078/346] Small fix --- src/client/game/dvars.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index d9f8b2ac..4a41495b 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -172,7 +172,6 @@ namespace dvars {"ai_threatUpdateInterval", "AI target threat update interval in milliseconds"}, {"aim_autoaim_enabled", ""}, {"aim_target_sentient_radius", "The radius used to calculate target bounds for a sentient(actor or player)"}, - {"aimassist_enabled", ""}, {"ammoCounterHide", "Hide the Ammo Counter"}, {"armory_contentpacks_enabled", "Allowed armory content packs. 0: none , 1: first armory content pack enabled, 2: first and second armory content pack enabled"}, {"badHost_detectMinServerTime", "Time in MS before the bad host dection system kicks in after match start"}, @@ -452,7 +451,6 @@ namespace dvars {"cg_landingSounds", "Play landing on surface sounds"}, {"cg_largeExplosiveKillCamBackDist", "Large Explosive kill camera: distance of camera backwards from explosive."}, {"cg_largeExplosiveKillCamUpDist", "Large Explosive kill camera: distance of camera backwards from explosive."}, - {"cg_legacyCrashHandling", ""}, {"cg_mapLocationSelectionCursorSpeed", "Speed of the cursor when selecting a location on the map"}, {"cg_marks_ents_player_only", "Marks on entities from players' bullets only."}, {"cg_minCullBulletDist", "Don't cull bullet trajectories that are within this distance to you."}, @@ -624,15 +622,6 @@ namespace dvars {"con_gameMsgWindow3LineCount", ""}, {"con_gameMsgWindow3MsgTime", ""}, {"con_gameMsgWindow3ScrollTime", ""}, - {"con_inputBoxColor", "Color of the console input box"}, - {"con_inputCmdMatchColor", ""}, - {"con_inputDvarInactiveValueColor", ""}, - {"con_inputDvarMatchColor", ""}, - {"con_inputDvarValueColor", ""}, - {"con_inputHintBoxColor", "Color of the console input hint box"}, - {"con_outputBarColor", "Color of the console output slider bar"}, - {"con_outputSliderColor", "Color of the console slider"}, - {"con_outputWindowColor", "Color of the console output"}, {"con_subtitleLeading", "Leading for subtitles, calculated as a percentage of the font height"}, {"con_typewriterColorGlowCheckpoint", ""}, {"con_typewriterColorGlowCompleted", ""}, @@ -1072,7 +1061,6 @@ namespace dvars {"loc_translate", "Enable translations"}, {"log_host_migration_chance", "The % chance of host migration results telemetry"}, {"log_party_state", "Log party state updates to Black Box system"}, - {"logger_dev", ""}, {"lowAmmoWarningColor1", "Color 1 of 2 to oscilate between"}, {"lowAmmoWarningColor2", "Color 2 of 2 to oscilate between"}, {"lowAmmoWarningNoAmmoColor1", "Like lowAmmoWarningColor1, but when no ammo."}, From c84c9398f62019776ca648b375331bf909897a72 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 03:07:17 +0100 Subject: [PATCH 079/346] Add dvar_cheats component + some fixes --- src/client/component/command.cpp | 80 +- src/client/component/dvar_cheats.cpp | 201 + src/client/component/game_console.cpp | 6 +- src/client/game/dvars.cpp | 13837 ++++++++++++++++++++---- src/client/game/dvars.hpp | 2 + src/client/game/structs.hpp | 11 +- src/client/game/symbols.hpp | 8 +- 7 files changed, 11791 insertions(+), 2354 deletions(-) create mode 100644 src/client/component/dvar_cheats.cpp diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 3db38b6c..19532a87 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -33,7 +33,7 @@ namespace command } } - void client_command(const int client_num, void* a2) + void client_command(const int client_num) { params_sv params = {}; @@ -43,7 +43,7 @@ namespace command handlers_sv[command](client_num, params); } - client_command_hook.invoke(client_num, a2); + client_command_hook.invoke(client_num); } // Shamelessly stolen from Quake3 @@ -59,8 +59,8 @@ namespace command static std::string comand_line_buffer = GetCommandLineA(); auto* command_line = comand_line_buffer.data(); - auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); //H1(1.4) - auto* com_console_lines = reinterpret_cast(0x142623FC0); //H1(1.4) + auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); + auto* com_console_lines = reinterpret_cast(0x142623FC0); auto inq = false; com_console_lines[0] = command_line; @@ -247,9 +247,9 @@ namespace command void add(const char* name, const std::function& callback) { add(name, [callback](const params&) - { - callback(); - }); + { + callback(); + }); } void add_sv(const char* name, std::function callback) @@ -288,7 +288,7 @@ namespace command } else { - utils::hook::call(0x1400D728F, &parse_commandline_stub); // MWR TEST + utils::hook::call(0x1400D728F, parse_commandline_stub); utils::hook::jump(0x14041D750, dvar_command_stub); add_commands_mp(); @@ -301,35 +301,11 @@ namespace command static void add_commands_generic() { add("quit", game::Quit); - //add("quit_hard", utils::nt::raise_hard_exception); /* this command delivers you to a windows blue screen, its quit hard from windows xD */ add("crash", []() { *reinterpret_cast(1) = 0; }); - /*add("consoleList", [](const params& params) - { - const std::string input = params.get(1); - - std::vector matches; - game_console::find_matches(input, matches, false); - - for (auto& match : matches) - { - auto* dvar = game::Dvar_FindVar(match.c_str()); - if (!dvar) - { - console::info("[CMD]\t %s\n", match.c_str()); - } - else - { - console::info("[DVAR]\t%s \"%s\"\n", match.c_str(), game::Dvar_ValueToString(dvar, dvar->current, 0)); - } - } - - console::info("Total %i matches\n", matches.size()); - });*/ - add("commandDump", [](const params& argument) { console::info("================================ COMMAND DUMP =====================================\n"); @@ -402,7 +378,7 @@ namespace command console::info("%s\n", asset_name); }, true); } - }); + });*/ add("vstr", [](const params& params) { @@ -412,12 +388,12 @@ namespace command return; } - const auto* dvarName = params.get(1); - const auto* dvar = game::Dvar_FindVar(dvarName); + const auto name = params.get(1); + const auto dvar = game::Dvar_FindVar(name); if (dvar == nullptr) { - console::info("%s doesn't exist\n", dvarName); + console::info("%s doesn't exist\n", name); return; } @@ -429,7 +405,7 @@ namespace command } execute(dvar->current.string); - });*/ + }); } static void add_commands_sp() @@ -444,8 +420,8 @@ namespace command game::sp::g_entities[0].flags ^= 1; game::CG_GameMessage(0, utils::string::va("godmode %s", game::sp::g_entities[0].flags & 1 - ? "^2on" - : "^1off")); + ? "^2on" + : "^1off")); }); add("demigod", []() @@ -458,8 +434,8 @@ namespace command game::sp::g_entities[0].flags ^= 2; game::CG_GameMessage(0, utils::string::va("demigod mode %s", game::sp::g_entities[0].flags & 2 - ? "^2on" - : "^1off")); + ? "^2on" + : "^1off")); }); add("notarget", []() @@ -472,8 +448,8 @@ namespace command game::sp::g_entities[0].flags ^= 4; game::CG_GameMessage(0, utils::string::va("notarget %s", game::sp::g_entities[0].flags & 4 - ? "^2on" - : "^1off")); + ? "^2on" + : "^1off")); }); add("noclip", []() @@ -486,8 +462,8 @@ namespace command game::sp::g_entities[0].client->flags ^= 1; game::CG_GameMessage(0, utils::string::va("noclip %s", game::sp::g_entities[0].client->flags & 1 - ? "^2on" - : "^1off")); + ? "^2on" + : "^1off")); }); add("ufo", []() @@ -500,16 +476,16 @@ namespace command game::sp::g_entities[0].client->flags ^= 2; game::CG_GameMessage(0, utils::string::va("ufo %s", game::sp::g_entities[0].client->flags & 2 - ? "^2on" - : "^1off")); + ? "^2on" + : "^1off")); }); } static void add_commands_mp() { - //client_command_hook.create(0x1402E98F0, &client_command); + client_command_hook.create(0x140336000, &client_command); - /*add_sv("god", [](const int client_num, const params_sv&) + add_sv("god", [](const int client_num, const params_sv&) { if (!game::Dvar_FindVar("sv_cheats")->current.enabled) { @@ -522,8 +498,8 @@ namespace command game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, utils::string::va("f \"godmode %s\"", game::mp::g_entities[client_num].flags & 1 - ? "^2on" - : "^1off")); + ? "^2on" + : "^1off")); }); add_sv("demigod", [](const int client_num, const params_sv&) @@ -594,7 +570,7 @@ namespace command : "^1off")); }); - add_sv("give", [](const int client_num, const params_sv& params) + /*add_sv("give", [](const int client_num, const params_sv& params) { if (!game::Dvar_FindVar("sv_cheats")->current.enabled) { diff --git a/src/client/component/dvar_cheats.cpp b/src/client/component/dvar_cheats.cpp new file mode 100644 index 00000000..be9232b3 --- /dev/null +++ b/src/client/component/dvar_cheats.cpp @@ -0,0 +1,201 @@ +#include +#include "loader/component_loader.hpp" + +#include "console.hpp" +#include "scheduler.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include + +namespace dvar_cheats +{ + void apply_sv_cheats(const game::dvar_t* dvar, const game::DvarSetSource source, game::dvar_value* value) + { + static const auto sv_cheats_hash = game::generateHashValue("sv_cheats"); + + if (dvar && dvar->hash == sv_cheats_hash) + { + // if dedi, do not allow internal to change value so servers can allow cheats if they want to + if (game::environment::is_dedi() && source == game::DvarSetSource::DVAR_SOURCE_INTERNAL) + { + value->enabled = dvar->current.enabled; + } + + // if sv_cheats was enabled and it changes to disabled, we need to reset all cheat dvars + else if (dvar->current.enabled && !value->enabled) + { + for (auto i = 0; i < *game::dvarCount; ++i) + { + const auto var = &game::dvarPool[i]; + if (var && (var->flags & game::DvarFlags::DVAR_FLAG_CHEAT)) + { + game::Dvar_Reset(var, game::DvarSetSource::DVAR_SOURCE_INTERNAL); + } + } + } + } + } + + bool dvar_flag_checks(const game::dvar_t* dvar, const game::DvarSetSource source) + { + const auto info = dvars::get_dvar_info_from_hash(dvar->hash); + const auto name = info.has_value() + ? info.value().name.data() + : utils::string::va("0x%lX", dvar->hash); + + if ((dvar->flags & game::DvarFlags::DVAR_FLAG_WRITE)) + { + console::error("%s is write protected\n", name); + return false; + } + + if ((dvar->flags & game::DvarFlags::DVAR_FLAG_READ)) + { + console::error("%s is read only\n", name); + return false; + } + + // only check cheat/replicated values when the source is external + if (source == game::DvarSetSource::DVAR_SOURCE_EXTERNAL) + { + const auto cl_ingame = game::Dvar_FindVar("cl_ingame"); + const auto sv_running = game::Dvar_FindVar("sv_running"); + + if ((dvar->flags & game::DvarFlags::DVAR_FLAG_REPLICATED) && (cl_ingame && cl_ingame->current.enabled) && ( + sv_running && !sv_running->current.enabled)) + { + console::error("%s can only be changed by the server\n", name); + return false; + } + + const auto sv_cheats = game::Dvar_FindVar("sv_cheats"); + if ((dvar->flags & game::DvarFlags::DVAR_FLAG_CHEAT) && (sv_cheats && !sv_cheats->current.enabled)) + { + console::error("%s is cheat protected\n", name); + return false; + } + } + + // pass all the flag checks, allow dvar to be changed + return true; + } + + const auto dvar_flag_checks_stub = utils::hook::assemble([](utils::hook::assembler& a) + { + const auto can_set_value = a.newLabel(); + const auto zero_source = a.newLabel(); + + a.pushad64(); + a.mov(r8, rdi); + a.mov(edx, esi); + a.mov(rcx, rbx); + a.call_aligned(apply_sv_cheats); //check if we are setting sv_cheats + a.popad64(); + a.cmp(esi, 0); + a.jz(zero_source); //if the SetSource is 0 (INTERNAL) ignore flag checks + + a.pushad64(); + a.mov(edx, esi); //source + a.mov(rcx, rbx); //dvar + a.call_aligned(dvar_flag_checks); //protect read/write/cheat/replicated dvars + a.cmp(al, 1); + a.jz(can_set_value); + + // if we get here, we are non-zero source and CANNOT set values + a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag + a.jmp(0x1404FDCAB); + + // if we get here, we are non-zero source and CAN set values + a.bind(can_set_value); + a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag + a.cmp(esi, 1); + a.jmp(0x1404FDA22); + + // if we get here, we are zero source and ignore flags + a.bind(zero_source); + a.jmp(0x1404FDA62); + }); + + void cg_set_client_dvar_from_server(const int local_client_num, void* cg, const char* dvar_id, const char* value) + { + const auto* dvar = game::Dvar_FindVar(dvar_id); + if (dvar) + { + // If we send as string, it can't be set with source SERVERCMD because the game only allows that source on real server cmd dvars. + // Just use external instead as if it was being set by the console + game::Dvar_SetFromStringByNameFromSource(dvar_id, value, game::DvarSetSource::DVAR_SOURCE_EXTERNAL); + } + else + { + // Not a dvar name, assume it is an id and the game will handle normally + game::CG_SetClientDvarFromServer(local_client_num, cg, dvar_id, value); + } + } + + void set_client_dvar_by_string(const int entity_num, const char* value) + { + const auto* dvar = game::Scr_GetString(0); // grab the original dvar again since it's never stored on stack + const auto* command = utils::string::va("q %s \"%s\"", dvar, value); + + game::SV_GameSendServerCommand(entity_num, game::SV_CMD_RELIABLE, command); + } + + const auto player_cmd_set_client_dvar = utils::hook::assemble([](utils::hook::assembler& a) + { + const auto set_by_string = a.newLabel(); + + a.pushad64(); + + // check if we didn't find a network dvar index + a.mov(ecx, dword_ptr(rsp, 0x8C8)); + a.cmp(ecx, 0); + a.je(set_by_string); + + // we found an index, handle normally + a.popad64(); + a.mov(r8d, ptr(rsp, 0x848)); + a.lea(r9, ptr(rsp, 0x30)); + a.jmp(0x1402E2E57); + + // no index, let's send the dvar as a string + a.bind(set_by_string); + a.movzx(ecx, word_ptr(rsp, 0x8C0)); //entity_num + a.lea(rdx, ptr(rsp, 0xB0)); //value + a.call_aligned(set_client_dvar_by_string); + a.popad64(); + a.jmp(0x1402E2E7D); + }); + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) + { + return; + } + + utils::hook::nop(0x1404FDA0D, 4); // let our stub handle zero-source sets + utils::hook::jump(0x1404FDA14, dvar_flag_checks_stub, true); // check extra dvar flags when setting values + + // utils::hook::nop(0x14032AACC, 5); // remove error in PlayerCmd_SetClientDvar if setting a non-network dvar + // utils::hook::set(0x14032AA9B, 0xEB); + // don't check flags on the dvars, send any existing dvar instead + // utils::hook::jump(0x14032AB14, player_cmd_set_client_dvar, true); // send non-network dvars as string + // utils::hook::call(0x1401BB782, cg_set_client_dvar_from_server); + // check for dvars being sent as string before parsing ids + + scheduler::once([]() + { + dvars::register_bool("sv_cheats", false, game::DvarFlags::DVAR_FLAG_REPLICATED, + "Allow cheat commands and dvars on this server"); + }, scheduler::pipeline::main); + } + }; +} + +REGISTER_COMPONENT(dvar_cheats::component) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 86013299..b0f81eca 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -302,7 +302,11 @@ namespace game_console color_white, 0); const auto offset_y = height + 3.f; - draw_hint_box(1, dvars::con_inputHintBoxColor->current.vector, 0, offset_y); + const auto line_count_ = dvar->type == game::dvar_type::enumeration + ? dvar->domain.enumeration.stringCount + 1 + : 1; + + draw_hint_box(line_count_, dvars::con_inputHintBoxColor->current.vector, 0, offset_y); draw_hint_text(0, dvars::dvar_get_domain(dvar->type, dvar->domain).data(), dvars::con_inputCmdMatchColor->current.vector, 0, offset_y); } diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index 4a41495b..56c1d5a1 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -157,2304 +157,11531 @@ namespace dvars } } + constexpr int generate_hash(const char* string) + { + const char* v1; + char v2, v6; + int v4, v5, v7; + char* end_ptr; + + v1 = string; + v2 = *string; + + if (v2 == 48 && v1[1] == 120) + { + return strtoul(v1 + 2, &end_ptr, 16); + } + + v4 = v2; + + if ((v2 - 65) <= 0x19u) + { + v4 = v2 + 32; + } + + v5 = 0xB3CB2E29 * static_cast(v4 ^ 0x319712C3); + + if (v2) + { + do + { + v6 = *++v1; + v7 = v6; + if ((v6 - 65) <= 0x19u) + { + v7 = v6 + 32; + } + + v5 = 0xB3CB2E29 * static_cast(v5 ^ v7); + } + while (v6); + } + + return v5; + } + std::vector dvar_list = { - {"accessToSubscriberContent", "Whether to display the subscriber maps."}, - {"aci", ""}, - {"actionSlotsHide", "Hide the actionslots."}, - {"ai_grenadeReturn_approachMinDot", "Minimal dot product between the approach and throw vectors to perform a grenade return"}, - {"ai_grenadeReturn_debug", "Turns on debug info for AI grenade returns"}, - {"ai_grenadeReturn_extraFuseTime", "The amount of time (in ms) to add to a grenade fuse when trying to return grenade that's below minFuseTime"}, - {"ai_grenadeReturn_minDistSqr", "Minimal distance to a grenade to consider it for a return so that transition anims will play"}, - {"ai_grenadeReturn_minFuseTime", "If the fuse time drops below this value when an ally is attempting to return a grenade, add extra fuse time"}, - {"ai_grenadeReturn_stationary", "If set, AI will attempt to return grenades that they are within pickup distance - regardless of min dist"}, - {"ai_grenadeReturn_traceToGrenade", "If set, AI will only attempt to return grenades when they have a clear sight trace to the grenade"}, - {"ai_threatUpdateInterval", "AI target threat update interval in milliseconds"}, - {"aim_autoaim_enabled", ""}, - {"aim_target_sentient_radius", "The radius used to calculate target bounds for a sentient(actor or player)"}, - {"ammoCounterHide", "Hide the Ammo Counter"}, - {"armory_contentpacks_enabled", "Allowed armory content packs. 0: none , 1: first armory content pack enabled, 2: first and second armory content pack enabled"}, - {"badHost_detectMinServerTime", "Time in MS before the bad host dection system kicks in after match start"}, - {"badhost_maxDoISuckFrames", "Max lagged frames need to end match"}, - {"band_12players", "12 player bandwidth req'd"}, - {"band_18players", "18 player bandwidth req'd"}, - {"band_2players", "2 player bandwidth req'd"}, - {"band_4players", "4 player bandwidth req'd"}, - {"band_8players", "8 player bandwidth req'd"}, - {"bg_allowScuffFootsteps", "If true, scuff sounds will be played when the player rotates in place."}, - {"bg_bulletExplDmgFactor", "Weapon damage multiplier that will be applied at the center of the slash damage area."}, - {"bg_bulletExplRadius", "The radius of the bullet splash damage, where the damage gradually falls off to 0."}, - {"bg_compassShowEnemies", "Whether enemies are visible on the compass at all times"}, - {"bg_idleSwingSpeed", "The rate at which the player's legs swing around when idle (multi-player only)"}, - {"bg_shieldHitEncodeHeightVM", "The decoding range, in height, of a client's viewmodel shield."}, - {"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."}, - {"bg_shieldHitEncodeWidthVM", "The decoding range, in width, of a client's viewmodel shield."}, - {"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."}, - {"bg_shock_fadeOverride", "Override the time for the shellshock kick effect to fade in MP"}, - {"bg_shock_lookControl", "Alter player control during shellshock"}, - {"bg_shock_lookControl_fadeTime", "The time for the shellshock player control to fade in seconds"}, - {"bg_shock_lookControl_maxpitchspeed", "Maximum pitch movement rate while shellshocked in degrees per second"}, - {"bg_shock_lookControl_maxyawspeed", "Maximum yaw movement rate while shell shocked in degrees per second"}, - {"bg_shock_lookControl_mousesensitivityscale", "Sensitivity scale to apply to a shellshocked player"}, - {"bg_shock_movement", "Affect player's movement speed duringi shellshock"}, - {"bg_shock_screenBlurBlendFadeTime", "The amount of time in seconds for the shellshock effect to fade"}, - {"bg_shock_screenBlurBlendTime", "The amount of time in seconds for the shellshock effect to fade"}, - {"bg_shock_screenFlashShotFadeTime", "In seconds, how soon from the end of the effect to start blending out the whiteout layer."}, - {"bg_shock_screenFlashWhiteFadeTime", "In seconds, how soon from the end of the effect to start blending out the whiteout layer."}, - {"bg_shock_screenType", "Shell shock screen effect type"}, - {"bg_shock_sound", "Play shell shock sound"}, - {"bg_shock_soundDryLevel", "Shell shock sound dry level"}, - {"bg_shock_soundEnd", "Shellshock end sound alias"}, - {"bg_shock_soundEndAbort", "Shellshock aborted end sound alias"}, - {"bg_shock_soundFadeInTime", "Shell shock sound fade in time in seconds"}, - {"bg_shock_soundFadeOutTime", "Shell shock sound fade out time in seconds"}, - {"bg_shock_soundLoop", "Shellshock loop alias"}, - {"bg_shock_soundLoopEndDelay", "Sound loop end offset time from the end of the shellshock in seconds"}, - {"bg_shock_soundLoopFadeTime", "Shell shock sound loop fade time in seconds"}, - {"bg_shock_soundLoopSilent", "The sound that gets blended with the shellshock loop alias"}, - {"bg_shock_soundModEndDelay", "The delay from the end of the shell shock to the end of the sound modification"}, - {"bg_shock_soundRoomType", "Shell shock sound reverb room type"}, - {"bg_shock_soundSubmix", "Shell shock submix to apply"}, - {"bg_shock_soundWetLevel", "Shell shock sound wet level"}, - {"bg_shock_viewKickFadeTime", "The time for the shellshock kick effect to fade"}, - {"bg_shock_viewKickPeriod", "The period of the shellshock view kick effect"}, - {"bg_shock_viewKickRadius", "Shell shock kick radius"}, - {"bg_swingSpeed", "The rate at which the player's legs swing around when idle (multi-player only)"}, - {"bg_torsoSwingSpeed", "The rate at which the player's torso swings around when strafing (multi-player only)"}, - {"boostcheatHeadshotsTotalCoef", ""}, - {"boostcheatHeadshotsTotalMean", ""}, - {"boostcheatHeadshotsTotalStddev", ""}, - {"boostcheatIntercept", ""}, - {"boostcheatKillerXAnomalyCoef", ""}, - {"boostcheatKillerXAnomalyMean", ""}, - {"boostcheatKillerXAnomalyStddev", ""}, - {"boostcheatKillerYAnomalyCoef", ""}, - {"boostcheatKillerYAnomalyMean", ""}, - {"boostcheatKillerYAnomalyStddev", ""}, - {"boostcheatMeanDistanceMostKilledPlayerTraveledMean", ""}, - {"boostcheatMeanDistanceVictimTraveledCoef", ""}, - {"boostcheatMeanDistanceVictimTraveledMean", ""}, - {"boostcheatMeanDistanceVictimTraveledStddev", ""}, - {"boostcheatMeanMostKilledPlayerLifetimeMillisecondsMean", ""}, - {"boostcheatMostKilledPlayerHKRatioCoef", ""}, - {"boostcheatMostKilledPlayerHKRatioMean", ""}, - {"boostcheatMostKilledPlayerHKRatioStddev", ""}, - {"boostcheatMostKilledPlayerKillsRatioCoef", ""}, - {"boostcheatMostKilledPlayerKillsRatioMean", ""}, - {"boostcheatMostKilledPlayerKillsRatioStddev", ""}, - {"boostcheatMostKilledPlayerKillsTotalCoef", ""}, - {"boostcheatMostKilledPlayerKillsTotalMean", ""}, - {"boostcheatMostKilledPlayerKillsTotalStddev", ""}, - {"boostcheatMostKilledPlayerKillTimestampsAnomalyMean", ""}, - {"boostcheatVictimXAnomalyCoef", ""}, - {"boostcheatVictimXAnomalyMean", ""}, - {"boostcheatVictimXAnomalyStddev", ""}, - {"boostcheatVictimYAnomalyCoef", ""}, - {"boostcheatVictimYAnomalyMean", ""}, - {"boostcheatVictimYAnomalyStddev", ""}, - {"bot_DifficultyDefault", "default difficulty level of bots"}, - {"ca_auto_signin", "CoD Anywhere start sign-in task automatically on startup or first party sign-in"}, - {"ca_do_mlc", "CoD Anywhere Do Multi Login check"}, - {"ca_intra_only", "CoD Anywhere Intra Network Only"}, - {"ca_require_signin", "CoD Anywhere require sign in to enter MP"}, - {"ca_show_signup_request", "CoD Anywhere should you show new users a popup requesting they create a CoD Account?"}, - {"camera_thirdPerson", "Use third person view globally"}, - {"cameraShakeRemoteHelo_Angles", "Remote helicopter gunner cam, range to shake the view."}, - {"cameraShakeRemoteHelo_Freqs", "Remote helicopter gunner cam, how fast to shake."}, - {"cameraShakeRemoteHelo_SpeedRange", "Remote helicopter gunner cam, range of missile speed to scale the shaking."}, - {"cameraShakeRemoteMissile_Angles", "Remote missile-cam, range to shake the view."}, - {"cameraShakeRemoteMissile_Freqs", "Remote missile-cam, how fast to shake."}, - {"cameraShakeRemoteMissile_SpeedRange", "Remote missile-cam, range of missile speed to scale the shaking."}, - {"cg_airstrikeCamFstop", "Airstrike kill camera aperture. Lower f-stop yields a shallower depth of field. Typical values range from 1 to 22"}, - {"cg_airstrikeKillCamFarBlur", ""}, - {"cg_airstrikeKillCamFarBlurDist", ""}, - {"cg_airstrikeKillCamFarBlurStart", ""}, - {"cg_airstrikeKillCamFov", "Airstrike kill camera field of view."}, - {"cg_airstrikeKillCamNearBlur", ""}, - {"cg_airstrikeKillCamNearBlurEnd", ""}, - {"cg_airstrikeKillCamNearBlurStart", ""}, - {"cg_blood", "Show Blood"}, - {"cg_bloodThickColor", "Color of the blood overlay's thick blood splatter"}, - {"cg_bloodThinColor", "Color of the blood overlay's thin blood splatter"}, - {"cg_brass", "Weapons eject brass"}, - {"cg_centertime", "The time for a center printed message to fade"}, - {"cg_chatHeight", "The font height of a chat message"}, - {"cg_chatTime", "The amount of time that a chat message is visible"}, - {"cg_ColorBlind_EnemyTeam", "Enemy team color for color blind people"}, - {"cg_ColorBlind_MyParty", "Player party color for color blind people"}, - {"cg_ColorBlind_MyTeam", "Player team color for color blind people"}, - {"cg_connectionIconSize", "Size of the connection icon"}, - {"cg_constantSizeHeadIcons", "Head icons are the same size regardless of distance from the player"}, - {"cg_crosshairAlpha", "The alpha value of the crosshair"}, - {"cg_crosshairAlphaMin", "The minimum alpha value of the crosshair when it fades in"}, - {"cg_crosshairDynamic", "Crosshair is Dynamic"}, - {"cg_crosshairEnemyColor", "The crosshair color when over an enemy"}, - {"cg_crosshairVerticalOffset", "Amount to vertically offset the crosshair from the center."}, - {"cg_cullBulletAngle", "Cull bullet trajectories that don't fall within this fov"}, - {"cg_cullBullets", "Whether to cull bullet fire prediction if trajectory doesn't pass your view or anywhere near you"}, - {"cg_cursorHints", "Draw cursor hints where:\n 0: no hints"}, - {"cg_deadChatWithDead", "If true, dead players can all chat together, regardless of team"}, - {"cg_deadChatWithTeam", "If true, dead players can talk to living players on their team"}, - {"cg_deadHearAllLiving", "If true, dead players can hear all living players talk"}, - {"cg_deadHearTeamLiving", "If true, dead players can hear living players on their team talk"}, - {"cg_descriptiveText", "Draw descriptive spectator messages"}, - {"cg_draw2D", "Draw 2D screen elements"}, - {"cg_drawBreathHint", "Draw a 'hold breath to steady' hint"}, - {"cg_drawBuildName", "Draw build name"}, - {"cg_drawCrosshair", "Turn on weapon crosshair"}, - {"cg_drawCrosshairNames", "Draw the name of an enemy under the crosshair"}, - {"cg_drawCrosshairNamesPosX", ""}, - {"cg_drawCrosshairNamesPosY", ""}, - {"cg_drawDamageDirection", "Draw hit direction arrow."}, - {"cg_drawDamageFlash", "Draw flash when hit."}, - {"cg_drawDoubleTapDetonateHint", "Draw a 'double tap to detonate grenade' hint"}, - {"cg_drawEffectNum", "Draw counts of effects and elements"}, - {"cg_drawFPS", "Draw frames per second"}, - {"cg_drawFPSLabels", "Draw FPS Info Labels"}, - {"cg_drawFriendlyHUDGrenades", "Draw grenade warning indicators for friendly grenades (should be true if friendly-fire is enabled)"}, - {"cg_drawFriendlyNames", "Whether to show friendly names in game"}, - {"cg_drawFriendlyNamesAlways", "Whether to always show friendly names in game (for certain gametypes)"}, - {"cg_drawGun", "Draw the view model"}, - {"cg_drawHealth", "Draw health bar"}, - {"cg_drawMantleHint", "Draw a 'press key to mantle' hint"}, - {"cg_drawMaterial", "Draw debugging information for materials"}, - {"cg_drawpaused", "Draw paused screen"}, - {"cg_drawScriptUsage", "Draw debugging information for scripts"}, - {"cg_drawSnapshot", "Draw debugging information for snapshots"}, - {"cg_drawStatsSource", "Draw stats source"}, - {"cg_drawTalk", "Controls which icons CG_TALKER ownerdraw draws"}, - {"cg_drawTurretCrosshair", "Draw a cross hair when using a turret"}, - {"cg_drawViewpos", "Draw viewpos"}, - {"cg_e3TrailerHacks", "Tweaks for trailer recording"}, - {"cg_equipmentSounds", "Play equipment sounds"}, - {"cg_errordecay", "Decay for predicted error"}, - {"cg_everyoneHearsEveryone", "If true, all players can all chat together, regardless of team or death"}, - {"cg_explosiveKillCamBackDist", "Explosive kill camera: distance of camera backwards from explosive."}, - {"cg_explosiveKillCamGroundBackDist", "Explosive kill camera when stuck to ground: distance of camera backwards from explosive."}, - {"cg_explosiveKillCamGroundUpDist", "Explosive kill camera when stuck to ground: distance of camera backwards from explosive."}, - {"cg_explosiveKillCamStopDecelDist", "Rocket and Grenade Launcher kill camera: distance from player to begin coming to rest"}, - {"cg_explosiveKillCamStopDist", "Rocket and Grenade Launcher kill camera: distance from player to begin coming to rest"}, - {"cg_explosiveKillCamUpDist", "Explosive kill camera: distance of camera backwards from explosive."}, - {"cg_explosiveKillCamWallOutDist", "Explosive kill camera when stuck to wall: distance of camera out from wall."}, - {"cg_explosiveKillCamWallSideDist", "Explosive kill camera when stuck to wall: distance of camera out from wall."}, - {"cg_flashbangNameFadeIn", "Time in milliseconds to fade in friendly names"}, - {"cg_flashbangNameFadeOut", "Time in milliseconds to fade out friendly names"}, - {"cg_foliagesnd_alias", "The sound that plays when an actor or player enters a foliage clip brush."}, - {"cg_footsteps", "Play footstep sounds that are NOT sprint"}, - {"cg_footstepsSprint", "Play sprint footstep sounds"}, - {"cg_fov", "The field of view angle in degrees"}, - {"cg_fovMin", "The minimum possible field of view"}, - {"cg_fovScale", "Scale applied to the field of view"}, - {"cg_friendlyNameFadeIn", "Time in milliseconds to fade in friendly names"}, - {"cg_friendlyNameFadeOut", "Time in milliseconds to fade out friendly names"}, - {"cg_gameBoldMessageWidth", "The maximum character width of the bold game messages"}, - {"cg_gameMessageWidth", "The maximum character width of the game messages"}, - {"cg_gun_x", "Forward position of the viewmodel"}, - {"cg_gun_y", "Right position of the viewmodel"}, - {"cg_gun_z", "Up position of the viewmodel"}, - {"cg_headIconMinScreenRadius", "The minumum radius of a head icon on the screen"}, - {"cg_hearKillerTime", "Duration (in milliseconds) to hear the person you just killed"}, - {"cg_hearVictimEnabled", "If true, you can hear the person you just killed"}, - {"cg_hearVictimTime", "Duration (in milliseconds) to hear the person you just killed"}, - {"cg_heliKillCamFarBlur", ""}, - {"cg_heliKillCamFarBlurDist", ""}, - {"cg_heliKillCamFarBlurStart", ""}, - {"cg_heliKillCamFov", "Helicopter kill camera field of view."}, - {"cg_heliKillCamFstop", "Helicopter kill camera aperture. Lower f-stop yields a shallower depth of field. Typical values range from 1 to 22"}, - {"cg_heliKillCamNearBlur", ""}, - {"cg_heliKillCamNearBlurEnd", ""}, - {"cg_heliKillCamNearBlurStart", ""}, - {"cg_hintFadeTime", "Time in milliseconds for the cursor hint to fade"}, - {"cg_hudChatIntermissionPosition", "Position of the HUD chat box during intermission"}, - {"cg_hudChatPosition", "Position of the HUD chat box"}, - {"cg_hudDamageIconHeight", "The height of the damage icon"}, - {"cg_hudDamageIconInScope", "Draw damage icons when aiming down the sight of a scoped weapon"}, - {"cg_hudDamageIconOffset", "The offset from the center of the damage icon"}, - {"cg_hudDamageIconOverlayTime", "The amount of time (in ms) for the overlay portion of the damage icon to stay on screen"}, - {"cg_hudDamageIconStartFadeTime", "The amount of time (in ms) before the damage icon begins to fade"}, - {"cg_hudDamageIconTime", "The amount of time for the damage icon to stay on screen after damage is taken"}, - {"cg_hudDamageIconWidth", "The width of the damage icon"}, - {"cg_hudGrenadeIconEnabledFlash", "Show the grenade indicator for flash grenades"}, - {"cg_hudGrenadeIconHeight", "The height of the grenade indicator icon"}, - {"cg_hudGrenadeIconInScope", "Show the grenade indicator when aiming down the sight of a scoped weapon"}, - {"cg_hudGrenadeIconMaxRangeFlash", "The minimum distance that a flashbang has to be from a player in order to be shown on the grenade indicator"}, - {"cg_hudGrenadeIconMaxRangeFrag", "The minimum distance that a grenade has to be from a player in order to be shown on the grenade indicator"}, - {"cg_hudGrenadeIconOffset", "The offset from the center of the screen for a grenade icon"}, - {"cg_hudGrenadeIconWidth", "The width of the grenade indicator icon"}, - {"cg_hudGrenadePointerHeight", "The height of the grenade indicator pointer"}, - {"cg_hudGrenadePointerPivot", "The pivot point of th grenade indicator pointer"}, - {"cg_hudGrenadePointerPulseFreq", "The number of times per second that the grenade indicator flashes in Hertz"}, - {"cg_hudGrenadePointerPulseMax", "The maximum alpha of the grenade indicator pulse. Values higher than 1 will cause the indicator to remain at full brightness for longer"}, - {"cg_hudGrenadePointerPulseMin", "The minimum alpha of the grenade indicator pulse. Values lower than 0 will cause the indicator to remain at full transparency for longer"}, - {"cg_hudGrenadePointerWidth", "The width of the grenade indicator pointer"}, - {"cg_hudLegacySplitscreenScale", "Screen scale for hud elements in splitscreen"}, - {"cg_hudLighting_basic_additiveLumOffset", "[basic] Offset applied to additive light color."}, - {"cg_hudLighting_basic_additiveLumScale", "[basic] Scale applied to additive light color."}, - {"cg_hudLighting_basic_additiveOffset", ""}, - {"cg_hudLighting_basic_additiveScale", ""}, - {"cg_hudLighting_basic_ambientLumOffset", "[basic] Offset applied to ambient light color."}, - {"cg_hudLighting_basic_ambientLumScale", "[basic] Scale applied to ambient light color."}, - {"cg_hudLighting_basic_ambientOffset", ""}, - {"cg_hudLighting_basic_ambientScale", ""}, - {"cg_hudLighting_basic_diffuseLumOffset", "[basic] Offset applied to diffuse light color."}, - {"cg_hudLighting_basic_diffuseLumScale", "[basic] Scale applied to diffuse light color."}, - {"cg_hudLighting_basic_diffuseOffset", ""}, - {"cg_hudLighting_basic_diffuseScale", ""}, - {"cg_hudLighting_basic_specExponent", "[basic] Specular exponent. Higher values result in sharper highlights."}, - {"cg_hudLighting_basic_specLumOffset", "[basic] Offset applied to spec light luminance."}, - {"cg_hudLighting_basic_specLumScale", "[basic] Scale applied to spec light luminance."}, - {"cg_hudLighting_basic_specOffset", ""}, - {"cg_hudLighting_basic_specScale", ""}, - {"cg_hudLighting_blood_additiveLumOffset", "[blood] Offset applied to additive light color."}, - {"cg_hudLighting_blood_additiveLumScale", "[blood] Scale applied to additive light color."}, - {"cg_hudLighting_blood_additiveOffset", ""}, - {"cg_hudLighting_blood_additiveScale", ""}, - {"cg_hudLighting_blood_ambientLumOffset", "[blood] Offset applied to ambient light color."}, - {"cg_hudLighting_blood_ambientLumScale", "[blood] Scale applied to ambient light color."}, - {"cg_hudLighting_blood_ambientOffset", ""}, - {"cg_hudLighting_blood_ambientScale", ""}, - {"cg_hudLighting_blood_diffuseLumOffset", "[blood] Offset applied to diffuse light color."}, - {"cg_hudLighting_blood_diffuseLumScale", "[blood] Scale applied to diffuse light color."}, - {"cg_hudLighting_blood_diffuseOffset", ""}, - {"cg_hudLighting_blood_diffuseScale", ""}, - {"cg_hudLighting_blood_specExponent", "[blood] Specular exponent. Higher values result in sharper highlights."}, - {"cg_hudLighting_blood_specLumOffset", "[blood] Offset applied to spec light luminance."}, - {"cg_hudLighting_blood_specLumScale", "[blood] Scale applied to spec light luminance."}, - {"cg_hudLighting_blood_specOffset", ""}, - {"cg_hudLighting_blood_specScale", ""}, - {"cg_hudLighting_fadeSharpness", "This controls how sharp the lines are when fading using the mask alpha. Higher values are sharper."}, - {"cg_hudMapBorderWidth", "The size of the full map's border, filled by the CG_PLAYER_FULLMAP_BORDER ownerdraw"}, - {"cg_hudMapFriendlyHeight", ""}, - {"cg_hudMapFriendlyWidth", ""}, - {"cg_hudMapPlayerHeight", ""}, - {"cg_hudMapPlayerWidth", ""}, - {"cg_hudMapRadarLineThickness", "Thickness, relative to the map width, of the radar texture that sweeps across the full screen map"}, - {"cg_hudObjectiveTextScale", ""}, - {"cg_hudProneY", "Virtual screen y coordinate of the prone blocked message"}, - {"cg_hudSayPosition", "Position of the HUD say box"}, - {"cg_hudSplitscreenCompassElementScale", "Scale value to apply to compass elements in splitscreen"}, - {"cg_hudSplitscreenCompassScale", "Scale value to apply to the compass in splitscreen"}, - {"cg_hudSplitscreenStanceScale", "Scale value to apply to the stance HUD element in splitscreen"}, - {"cg_hudStanceFlash", "The background color of the flash when the stance changes"}, - {"cg_hudVotePosition", "Position of the HUD vote box"}, - {"cg_invalidCmdHintBlinkInterval", "Blink rate of an invalid command hint"}, - {"cg_invalidCmdHintDuration", "Duration of an invalid command hint"}, - {"cg_javelinKillCamCloseZDist", "Javelin kill camera: closest distance above the target."}, - {"cg_javelinKillCamDownDist", "Javelin kill camera: distance to follow during ascent."}, - {"cg_javelinKillCamFov", "Javelin kill camera: fov"}, - {"cg_javelinKillCamLookLerpDist", "Javelin kill camera: distance over which to lerp to look at player during descent. A value of zero means don't lerp at all."}, - {"cg_javelinKillCamPassDist", "Javelin kill camera: distance away when passing."}, - {"cg_javelinKillCamPassTime", "Javelin kill camera: time in seconds to pass javelin on the way up"}, - {"cg_javelinKillCamUpDist", "Javelin kill camera: distance to follow during ascent."}, - {"cg_killCamDefaultLerpTime", "Default time used to lerp between killcam entities."}, - {"cg_killCamTurretLerpTime", "Time used to lerp to a killcam entity of the TURRET type."}, - {"cg_landingSounds", "Play landing on surface sounds"}, - {"cg_largeExplosiveKillCamBackDist", "Large Explosive kill camera: distance of camera backwards from explosive."}, - {"cg_largeExplosiveKillCamUpDist", "Large Explosive kill camera: distance of camera backwards from explosive."}, - {"cg_mapLocationSelectionCursorSpeed", "Speed of the cursor when selecting a location on the map"}, - {"cg_marks_ents_player_only", "Marks on entities from players' bullets only."}, - {"cg_minCullBulletDist", "Don't cull bullet trajectories that are within this distance to you."}, - {"cg_objectiveText", ""}, - {"cg_overheadIconSize", "The maximum size to show overhead icons like 'rank'"}, - {"cg_overheadNamesFarDist", "The far distance at which name sizes are scaled by cg_overheadNamesFarScale"}, - {"cg_overheadNamesFarScale", "The amount to scale overhead name sizes at cg_overheadNamesFarDist"}, - {"cg_overheadNamesFont", "Font for overhead names ( see menudefinition.h )"}, - {"cg_overheadNamesGlow", "Glow color for overhead names"}, - {"cg_overheadNamesMaxDist", "The maximum distance for showing friendly player names"}, - {"cg_overheadNamesNearDist", "The near distance at which names are full size"}, - {"cg_overheadNamesSize", "The maximum size to show overhead names"}, - {"cg_overheadRankSize", "The size to show rank text"}, - {"cg_remoteMissileKillCamBackDist", "Remote missile kill camera: distance of camera backwards from rocket."}, - {"cg_remoteMissileKillCamUpDist", "Remote missile kill camera: distance of camera backwards from rocket."}, - {"cg_rocketKillCamBackDist", "Rocket kill camera: distance of camera backwards from rocket."}, - {"cg_rocketKillCamUpDist", "Rocket kill camera: distance of camera backwards from rocket."}, - {"cg_scriptIconSize", "Size of Icons defined by script"}, - {"cg_showmiss", "Show prediction errors"}, - {"cg_sprintMeterDisabledColor", "The color of the sprint meter when the sprint meter is full"}, - {"cg_sprintMeterEmptyColor", "The color of the sprint meter when the sprint meter is full"}, - {"cg_sprintMeterFullColor", "The color of the sprint meter when the sprint meter is full"}, - {"cg_subtitleMinTime", "The minimum time that the subtitles are displayed on screen in seconds"}, - {"cg_subtitleWidthStandard", "The width of the subtitles on a non wide-screen"}, - {"cg_subtitleWidthWidescreen", "The width of the subtitle on a wide-screen"}, - {"cg_teamChatsOnly", "Allow chatting only on the same team"}, - {"cg_TeamColor_Allies", "Allies team color"}, - {"cg_TeamColor_Axis", "Axis team color"}, - {"cg_TeamColor_EnemyTeam", "Enemy team color"}, - {"cg_TeamColor_Free", "Free Team color"}, - {"cg_TeamColor_MyParty", "Player team color when in the same party"}, - {"cg_TeamColor_MyTeam", "Player team color"}, - {"cg_TeamColor_Spectator", "Spectator team color"}, - {"cg_turretKillCamBackDist", "Turret kill camera: distance of camera backwards from Turret."}, - {"cg_turretKillCamFov", "Turret kill camera field of view."}, - {"cg_turretKillCamUpDist", "Turret kill camera: distance of camera backwards from Turret."}, - {"cg_turretRemoteKillCamBackDist", "Remote Turret kill camera: distance of camera backwards from Turret."}, - {"cg_turretRemoteKillCamFov", "Remote Turret kill camera field of view."}, - {"cg_turretRemoteKillCamUpDist", "Remote Turret kill camera: distance of camera backwards from Turret."}, - {"cg_vectorFieldsForceUniform", "Forces all vector field assets to represent a single, uniform direction"}, - {"cg_viewVehicleInfluence", "The influence on the view angles from being in a vehicle"}, - {"cg_viewZSmoothingMax", "Threshhold for the maximum smoothing distance we'll do"}, - {"cg_viewZSmoothingMin", "Threshhold for the minimum smoothing distance it must move to smooth"}, - {"cg_viewZSmoothingTime", "Amount of time to spread the smoothing over"}, - {"cg_voiceIconSize", "Size of the 'voice' icon"}, - {"cg_waterSheeting_distortionScaleFactor", "Distortion uv scales (Default to 1)"}, - {"cg_waterSheeting_magnitude", "Distortion magnitude"}, - {"cg_waterSheeting_radius", "Tweak dev var; Glow radius in pixels at 640x480"}, - {"cg_weapHitCullAngle", "Angle of cone within which to cull back facing weapon hit effects"}, - {"cg_weapHitCullEnable", "When true, cull back facing weapon hit fx."}, - {"cg_weaponCycleDelay", "The delay after cycling to a new weapon to prevent holding down the cycle weapon button from cycling too fast"}, - {"cg_weaponHintsCoD1Style", "Draw weapon hints in CoD1 style: with the weapon name, and with the icon below"}, - {"cg_weaponVisInterval", "Do weapon vis checks once per this many frames, per centity"}, - {"cg_youInKillCamSize", "Size of the 'you' Icon in the kill cam"}, - {"cl_anglespeedkey", "Multiplier for max angle speed for game pad and keyboard"}, - {"cl_bypassMouseInput", "Bypass UI mouse input and send directly to the game"}, - {"cl_connectionAttempts", "Maximum number of connection attempts before aborting"}, - {"cl_connectTimeout", "Timeout time in seconds while connecting to a server"}, - {"cl_demo_uploadfb", "Should we upload to FB"}, - {"cl_dirSelConvergenceTime", "Time to converge to the new direction when selecting a direction on the map."}, - {"cl_force_paused", "Force the client to be paused. Can't be overridden by LUA scripts, the start button, etc."}, - {"cl_freelook", "Enable looking with mouse"}, - {"cl_hudDrawsBehindUI", "Should the HUD draw when the UI is up?"}, - {"cl_ingame", "True if the game is active"}, - {"cl_inhibit_stats_upload", "Inhibit upload of stats during demo playback"}, - {"cl_lessprint", "Print less to the console by filtering out certain spammy channels"}, - {"cl_maxpackets", "Maximum number of packets sent per frame"}, - {"cl_maxPing", "Maximum ping for the client"}, - {"cl_migrationTimeout", "Seconds to wait to hear from new host during host migration before timeout occurs"}, - {"cl_modifiedDebugPlacement", "Modify the location of debug output (outside of safe area)"}, - {"cl_motdString", ""}, - {"cl_mouseAccel", "Mouse acceleration"}, - {"cl_noprint", "Print nothing to the console"}, - {"cl_packetdup", "Enable packet duplication"}, - {"cl_pauseAudioZoneEnabled", "Enable the paused audio zone when the menus are up"}, - {"cl_paused", "Pause the game"}, - {"cl_pitchspeed", "Max pitch speed in degrees for game pad"}, - {"cl_pranks", "pranks"}, - {"cl_pushToTalk", "Do we have to press a button to talk"}, - {"cl_serverStatusResendTime", "Time in milliseconds to resend a server status message"}, - {"cl_showmouserate", "Print mouse rate debugging information to the console"}, - {"cl_textChatEnabled", "Do we want to use text chat"}, - {"cl_timeout", "Seconds with no received packets until a timeout occurs"}, - {"cl_voice", "Use voice communications"}, - {"cl_yawspeed", "Max yaw speed in degrees for game pad and keyboard"}, - {"clientSideEffects", "Enable loading _fx.gsc files on the client"}, - {"cod_anywhere_errorMessage", "CoD Anywhere error message"}, - {"cod_anywhere_showPopup", "Temp Development: Should we show the CoD Anywhere popup"}, - {"cod_anywhere_single_task_popup_text", "CoD Anywhere success message"}, - {"com_animCheck", "Check anim tree"}, - {"com_cinematicEndInWhite", "Set by script. True if cinematic ends with a white screen."}, - {"com_completionResolveCommand", "Command to run when the message box successfully closes"}, - {"com_errorMessage", "Most recent error message"}, - {"com_errorResolveCommand", "Command to run when they close the error box"}, - {"com_filter_output", "Use console filters for filtering output."}, - {"com_maxfps", "Cap frames per second"}, - {"com_maxFrameTime", "Time slows down if a frame takes longer than this many milliseconds"}, - {"com_playerProfile", "Set to the name of the profile"}, - {"com_recommendedSet", ""}, - {"commerce_dl_retry_step", "Step in m/s for the commerce download retry"}, - {"commerce_manifest_file_max_retry_time", "Max time that the commerce manifest can retry"}, - {"commerce_manifest_file_retry_step", "Step in m/s for the commerce manifest retry"}, - {"commerce_max_dl_retry_time", "Max time that the commerce download can retry"}, - {"commerce_max_retry_time", "Max time that the commerce upload can retry"}, - {"commerce_retry_step", "Step in m/s for the commerce upload retry"}, - {"compass", "Display Compass"}, - {"compassClampIcons", "If true, friendlies and enemy pings clamp to the edge of the radar. If false, they disappear off the edge."}, - {"compassCoords", "x = North-South coord base value, \ny = East-West coord base value, \nz = scale (game units per coord unit)"}, - {"compassECoordCutoff", "Left cutoff for the scrolling east-west coords"}, - {"compassFriendlyHeight", ""}, - {"compassFriendlyWidth", ""}, - {"compassHideSansObjectivePointer", "Hide the compass, but leave the obective pointer visible."}, - {"compassHideVehicles", "When enabled, disables the CG_PLAYER_COMPASS_VEHICLES ownerdraw."}, - {"compassMaxRange", "The maximum range from the player in world space that objects will be shown on the compass"}, - {"compassMinRadius", "The minimum radius from the center of the compass that objects will appear."}, - {"compassMinRange", "The minimum range from the player in world space that objects will appear on the compass"}, - {"compassObjectiveArrowHeight", ""}, - {"compassObjectiveArrowOffset", "The offset of the objective arrow inward from the edge of the compass map"}, - {"compassObjectiveArrowRotateDist", "Distance from the corner of the compass map at which the objective arrow rotates to 45 degrees"}, - {"compassObjectiveArrowWidth", ""}, - {"compassObjectiveDetailDist", "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape."}, - {"compassObjectiveDrawLines", "Draw horizontal and vertical lines to the active target, if it is within the minimap boundries"}, - {"compassObjectiveHeight", ""}, - {"compassObjectiveIconHeight", ""}, - {"compassObjectiveIconWidth", ""}, - {"compassObjectiveMaxHeight", "The maximum height that an objective is considered to be on this level"}, - {"compassObjectiveMaxRange", "The maximum range at which an objective is visible on the compass"}, - {"compassObjectiveMinAlpha", "The minimum alpha for an objective at the edge of the compass"}, - {"compassObjectiveMinDistRange", "The distance that objective transition effects play over, centered on compassObjectiveNearbyDist."}, - {"compassObjectiveMinHeight", "The minimum height that an objective is considered to be on this level"}, - {"compassObjectiveNearbyDist", "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape."}, - {"compassObjectiveNumRings", "The number of rings when a new objective appears"}, - {"compassObjectiveRingSize", "The maximum objective ring sige when a new objective appears on the compass"}, - {"compassObjectiveRingTime", "The amount of time between each ring when an objective appears"}, - {"compassObjectiveTextHeight", "Objective text height"}, - {"compassObjectiveTextScale", "Scale to apply to hud objectives"}, - {"compassObjectiveWidth", ""}, - {"compassObjectiveWraparoundTime", "How long it takes for the objective to wrap around the compass from one edge to the other"}, - {"compassPlayerHeight", ""}, - {"compassPlayerWidth", ""}, - {"compassRadarLineThickness", "Thickness, relative to the compass size, of the radar texture that sweeps across the map"}, - {"compassRadarPingFadeTime", "How long an enemy is visible on the compass after it is detected by radar"}, - {"compassRotation", "Style of compass"}, - {"compassSize", "Scale the compass"}, - {"compassSoundPingFadeTime", "The time in seconds for the sound overlay on the compass to fade"}, - {"compassTickertapeStretch", "How far the tickertape should stretch from its center."}, - {"comscore_active", "Are we allowed to enable ComScore tracking or not"}, - {"con_gameMsgWindow0FadeInTime", ""}, - {"con_gameMsgWindow0FadeOutTime", ""}, - {"con_gameMsgWindow0Filter", ""}, - {"con_gameMsgWindow0LineCount", ""}, - {"con_gameMsgWindow0MsgTime", ""}, - {"con_gameMsgWindow0ScrollTime", ""}, - {"con_gameMsgWindow1FadeInTime", ""}, - {"con_gameMsgWindow1FadeOutTime", ""}, - {"con_gameMsgWindow1Filter", ""}, - {"con_gameMsgWindow1LineCount", ""}, - {"con_gameMsgWindow1MsgTime", ""}, - {"con_gameMsgWindow1ScrollTime", ""}, - {"con_gameMsgWindow2FadeInTime", ""}, - {"con_gameMsgWindow2FadeOutTime", ""}, - {"con_gameMsgWindow2Filter", ""}, - {"con_gameMsgWindow2LineCount", ""}, - {"con_gameMsgWindow2MsgTime", ""}, - {"con_gameMsgWindow2ScrollTime", ""}, - {"con_gameMsgWindow3FadeInTime", ""}, - {"con_gameMsgWindow3FadeOutTime", ""}, - {"con_gameMsgWindow3Filter", ""}, - {"con_gameMsgWindow3LineCount", ""}, - {"con_gameMsgWindow3MsgTime", ""}, - {"con_gameMsgWindow3ScrollTime", ""}, - {"con_subtitleLeading", "Leading for subtitles, calculated as a percentage of the font height"}, - {"con_typewriterColorGlowCheckpoint", ""}, - {"con_typewriterColorGlowCompleted", ""}, - {"con_typewriterColorGlowFailed", ""}, - {"con_typewriterColorGlowUpdated", ""}, - {"con_typewriterColorInteriorCheckpoint", ""}, - {"con_typewriterColorInteriorCompleted", ""}, - {"con_typewriterColorInteriorFailed", ""}, - {"con_typewriterColorInteriorUpdated", ""}, - {"con_typewriterDecayDuration", "Time (in milliseconds) to spend disolving the line away."}, - {"con_typewriterDecayStartTime", "Time (in milliseconds) to spend between the build and disolve phases."}, - {"con_typewriterPrintSpeed", "Time (in milliseconds) to print each letter in the line."}, - {"counterDownloadInterval", "Number of minutes before all the global counters are uploaded"}, - {"counterUploadInterval", "Number of minutes before all the global counters are uploaded"}, - {"cpu_speed_12players", "12 player sys_configureGHz req'd"}, - {"cpu_speed_18players", "18 player sys_configureGHz req'd"}, - {"cpu_speed_8players", "8 player sys_configureGHz req'd"}, - {"cSplineDebugRender", "Debug Render the csplines."}, - {"cSplineDebugRenderCorridor", "Debug Render the cspline corridor."}, - {"cSplineDebugRenderData", "Debug Render the cspline data."}, - {"cSplineDebugRenderSplineId", "Select a cspline - 0 for all."}, - {"dailychallenge_killswitch", "daily challenge killswitch - int with bits used to flag individual daily challenges as enabled"}, - {"dailychallenge_killswitch2", "daily challenge killswitch2 - int with bits used to flag 2nd set of individual daily challenges as enabled"}, - {"dailychallenge_period", "daily challenge period - utc value for a day"}, - {"data_validation_allow_drop", ""}, - {"dc_lobbymerge", "Allows lobby merging across data centres"}, - {"dcacheSimulateNoHDD", "When turned on, simulate no HDD for caching."}, - {"dcacheThrottleEnabled", "Enable or disable dcache upload throttling."}, - {"dcacheThrottleKBytesPerSec", "Dcache upload throttle limit in K Bytes per second."}, - {"dedicated_dhclient", "True if we're a client playing on a DH server"}, - {"demonwareConsideredConnectedTime", "Number of milliseconds after being disconnected from demonware before considering shutting down."}, - {"developer", "Enable development options"}, - {"didyouknow", ""}, - {"discard_playerstats_on_suspend", "Forces stats discard on suspend"}, - {"drawEntityCount", "Enable entity count drawing"}, - {"drawEntityCountPos", "Where to draw the entity count graph"}, - {"drawEntityCountSize", "undefined"}, - {"drawKillcamData", "Enable drawing server killcam data"}, - {"drawKillcamDataPos", "Where to draw the server killcam graph"}, - {"drawKillcamDataSize", "How big to draw the killcam data graph"}, - {"drawServerBandwidth", "Enable drawing server bandwidth"}, - {"drawServerBandwidthPos", "Where to draw the server bandwidth graph"}, - {"ds_dcid", "optional datacenter id - from playlist"}, - {"ds_dcid_override", "force datacenter id"}, - {"ds_info", "ds info string"}, - {"ds_info_enable", "Enable ds info string"}, - {"ds_introRequestTimeout", "ds intro request timeout (ms)"}, - {"ds_keepaliveInterval", "ds keepalive interval (ms)"}, - {"ds_keepaliveTimeout", "ds keepalive timeout (ms)"}, - {"ds_pingclient_max_reping_distance", "don't re-ping a datacenter if it's further away than this (miles)"}, - {"ds_pingclient_max_repings", "max # of times to re-ping a datacenter"}, - {"ds_pingclient_maxpings", "max pings to send per datacenter"}, - {"ds_pingclient_maxpings_per_tick", "max new pings each tick"}, - {"ds_pingclient_min_reping_delay", "min msec delay between re-pings"}, - {"ds_pingclient_min_reping_latency", "don't re-ping a datacenter if latency is less than this"}, - {"ds_pingclient_minpings", "min responses required per datacenter"}, - {"ds_pingclient_odsf", "does dsping set odsf flag"}, - {"dsping_dc_0", ""}, - {"dsping_dc_1", ""}, - {"dsping_dc_10", ""}, - {"dsping_dc_11", ""}, - {"dsping_dc_12", ""}, - {"dsping_dc_13", ""}, - {"dsping_dc_14", ""}, - {"dsping_dc_15", ""}, - {"dsping_dc_16", ""}, - {"dsping_dc_17", ""}, - {"dsping_dc_18", ""}, - {"dsping_dc_19", ""}, - {"dsping_dc_2", ""}, - {"dsping_dc_20", ""}, - {"dsping_dc_21", ""}, - {"dsping_dc_22", ""}, - {"dsping_dc_23", ""}, - {"dsping_dc_24", ""}, - {"dsping_dc_25", ""}, - {"dsping_dc_26", ""}, - {"dsping_dc_27", ""}, - {"dsping_dc_28", ""}, - {"dsping_dc_29", ""}, - {"dsping_dc_3", ""}, - {"dsping_dc_30", ""}, - {"dsping_dc_31", ""}, - {"dsping_dc_32", ""}, - {"dsping_dc_33", ""}, - {"dsping_dc_34", ""}, - {"dsping_dc_35", ""}, - {"dsping_dc_36", ""}, - {"dsping_dc_37", ""}, - {"dsping_dc_38", ""}, - {"dsping_dc_39", ""}, - {"dsping_dc_4", ""}, - {"dsping_dc_40", ""}, - {"dsping_dc_41", ""}, - {"dsping_dc_42", ""}, - {"dsping_dc_43", ""}, - {"dsping_dc_44", ""}, - {"dsping_dc_45", ""}, - {"dsping_dc_46", ""}, - {"dsping_dc_47", ""}, - {"dsping_dc_48", ""}, - {"dsping_dc_49", ""}, - {"dsping_dc_5", ""}, - {"dsping_dc_50", ""}, - {"dsping_dc_51", ""}, - {"dsping_dc_52", ""}, - {"dsping_dc_53", ""}, - {"dsping_dc_54", ""}, - {"dsping_dc_55", ""}, - {"dsping_dc_56", ""}, - {"dsping_dc_57", ""}, - {"dsping_dc_58", ""}, - {"dsping_dc_59", ""}, - {"dsping_dc_6", ""}, - {"dsping_dc_60", ""}, - {"dsping_dc_61", ""}, - {"dsping_dc_62", ""}, - {"dsping_dc_63", ""}, - {"dsping_dc_7", ""}, - {"dsping_dc_8", ""}, - {"dsping_dc_9", ""}, - {"dvl", "Enables the data validation system. Only available in non-retail builds."}, - {"dw_addrHandleTimeout", "Delay before destroying an addrHandle after the connection is lost\n"}, - {"dw_leaderboard_write_active", "Are leaderboard writes enabled"}, - {"dw_presence_active", "Is the demonware presence system enabled"}, - {"dw_presence_coop_join_active", "Do we allow players to join on presence for private coop matches (post session to demonware"}, - {"dw_presence_get_delay", "Number of milliseconds to wait after booting the game to fetch demonware presence"}, - {"dw_presence_get_rate", "Number of milliseconds to wait between sending presence state to demonware"}, - {"dw_presence_put_delay", "Number of milliseconds to wait in a presence state before sending to demonware"}, - {"dw_presence_put_rate", "Number of milliseconds to wait between sending presence state to demonware"}, - {"dw_region_lookup_timeout", "Timeout (in MS) after which we will accept not having found a region code and use the default"}, - {"dw_shared_presence_active", "Is the demonware shared presence system enabled"}, - {"dw_shared_presence_get_delay", "Number of milliseconds to wait after booting the game to fetch demonware presence"}, - {"dw_shared_presence_get_rate", "Number of milliseconds to wait between sending presence state to demonware"}, - {"dw_shared_presence_put_delay", "Number of milliseconds to wait in a shared presence state before sending to demonware"}, - {"dw_shared_presence_put_rate", "Number of milliseconds to wait between sending presence state to demonware"}, - {"dwBandwidthTestTaskTimeout", "default timeout for the bandwidth test task (in ms). 0 means no timeout"}, - {"dynEnt_active", "Disable/enable dynent reactions"}, - {"dynEnt_playerWakeUpRadius", "Determines threshold distance from player within which all dynents are woken up."}, - {"dynEnt_playerWakeUpZOffset", "Determines vertical distance from player's feet from which wake up sphere is centered."}, - {"elite_clan_active", "Are we allowed to show Elite Clans or not"}, - {"elite_clan_cool_off_time", "Cool off time between calls to fetch the elite clan"}, - {"elite_clan_delay", "Delay before the bdTeams calls start to Demonware. -1 means On-Demand and it will wait until the 'starteliteclan' menu call"}, - {"elite_clan_division_icon_active", "Are we allowed to show Elite Clan division icon or not"}, - {"elite_clan_get_blob_profile_max_retry_time", "Max time that the Elite Clan get private profile can retry"}, - {"elite_clan_get_blob_profile_retry_step", "Step in m/s for the Elite Clan get private profile retry"}, - {"elite_clan_get_clan_max_retry_time", "Max time that the Elite Clan get clan can retry"}, - {"elite_clan_get_clan_retry_step", "Step in m/s for the Elite Clan get clan retry"}, - {"elite_clan_get_members_max_retry_time", "Max time that the Elite Clan get members can retry"}, - {"elite_clan_get_members_retry_step", "Step in m/s for the Elite Clan get members retry"}, - {"elite_clan_get_private_member_profile_max_retry_time", "Max time that the Elite Clan get private profile can retry"}, - {"elite_clan_get_private_member_profile_retry_step", "Step in m/s for the Elite Clan get private profile retry"}, - {"elite_clan_get_public_profile_max_retry_time", "Max time that the Elite Clan get public profile can retry"}, - {"elite_clan_get_public_profile_retry_step", "Step in m/s for the Elite Clan get public profile retry"}, - {"elite_clan_get_team_stats_max_retry_time", "Max time that the Elite Clan get team stats can retry"}, - {"elite_clan_get_team_stats_retry_step", "Step in m/s for the Elite Clan get team stats retry"}, - {"elite_clan_motd_throttle_time", "Throttle time between motd update calls"}, - {"elite_clan_remote_view_active", "Are we allowed to view the clans for remote players"}, - {"elite_clan_remote_view_max_retry_time", "Max time that the Elite Clan remote viewing can retry"}, - {"elite_clan_remote_view_retry_step", "Step in m/s for the retry for viewing a remote Elite Clan"}, - {"elite_clan_send_message_to_members_max_retry_time", "Max time that the Elite Clan send message to members can retry"}, - {"elite_clan_send_message_to_members_retry_step", "Step in m/s for the Elite Clan send message to members retry"}, - {"elite_clan_set_private_member_profile_max_retry_time", "Max time that the Elite Clan set private member profile can retry"}, - {"elite_clan_set_private_member_profile_retry_step", "Step in m/s for the Elite Clan set private member profile retry"}, - {"elite_clan_single_task_popup_text", "String to be displayed on popup when a single task is being performed"}, - {"elite_clan_using_title", "Stores whether the Elite Clan title is in use by the user"}, - {"emblems_active", "Are we allowed to enable Emblems or not"}, - {"enable_recordRecentActivity", "records the timestamp of when the player was recently active to the tracker leaderboards"}, - {"enableReportingRegisteredParties", "If true then party membership data and host status will be reported in matchdata blob."}, - {"entitlements_active", "Are we allowed to show Entitlements or not"}, - {"entitlements_config_file_max_retry_time", "Max time that the Entitlements config file read can retry"}, - {"entitlements_config_file_retry_step", "Step in m/s for the Entitlements config file read retry"}, - {"entitlements_cool_off_time", "Cool off time between calls to fetch the elite clan"}, - {"entitlements_delay", "Delay before the entitlement calls start to Demonware. -1 means On-Demand and it will wait until the 'startentitlements' menu call"}, - {"entitlements_key_archive_max_retry_time", "Max time that the Entitlements key archive read can retry"}, - {"entitlements_key_archive_retry_step", "Step in m/s for the Entitlements key archive read retry"}, - {"entitlementSystemOk", "Set by the game to inform that the entitlement system is initialised"}, - {"facebook_active", "Are we allowed to show Facebook or not"}, - {"facebook_delay", "Delay before the Facebook calls start to Demonware. -1 means On-Demand and it will wait until the 'startfacebook' menu call"}, - {"facebook_friends_active", "Are we allowed to show Facebook Friends or not"}, - {"facebook_friends_max_retry_time", "Max time that the Facebook friends read can retry"}, - {"facebook_friends_refresh_time", "Time in seconds between Facebook friend refreshes"}, - {"facebook_friends_retry_step", "Step in m/s for the Facebook friends read retry"}, - {"facebook_friends_showing_count", "Contains how many facebook friends are being shown in the UI."}, - {"facebook_friends_throttle_time", "Throttle time between Facebook friend pages"}, - {"facebook_max_retry_time", "Max time that the Facebook authentication can retry"}, - {"facebook_password", "Facebook Password"}, - {"facebook_password_asterisk", "Facebook Password (Asterisk Version)"}, - {"facebook_popup_text", "Facebook Popup Text"}, - {"facebook_retry_step", "Step in m/s for the Facebook authentication retry"}, - {"facebook_upload_photo_active", "Are we allowed to Upload Photos to Facebook or not"}, - {"facebook_upload_video_active", "Are we allowed to Upload Videos to Facebook or not"}, - {"facebook_username", "Facebook Username"}, - {"fixedtime", "Use a fixed time rate for each frame"}, - {"FoFIconMaxSize", "Maximum size a Friend-or-Foe icon should ever grow to."}, - {"FoFIconMinSize", "Minimum size a Friend-or-Foe icon should ever shrink to."}, - {"FoFIconScale", "Base scale of Friend-or-Foe icons."}, - {"FoFIconSpawnTimeDelay", "How long to wait, after spawning, before showing the Friend-or-Foe icon on a player."}, - {"FoFIconSpawnTimeFade", "Length of the Friend-or-Foe icons' fade-ins."}, - {"friendsCacheSteamFriends", "Use cache of steam friends before querying steam api"}, - {"friendsMaxSteamLookupsPerFrame", "Number of steam friends to query steam status per frame when doing a refresh.\n"}, - {"friendsWidgetMinimumRefreshTimer", "Minimum delay before refreshing friends data if you aren't on the friends screen\n"}, - {"fs_basegame", "Base game name"}, - {"fs_basepath", "Base game path"}, - {"fs_basepath_output", "Base game path"}, - {"fs_cdpath", "CD path"}, - {"fs_copyfiles", "Copy all used files to another location"}, - {"fs_debug", "Enable file system debugging information"}, - {"fs_game", "Game data directory. Must be \"\" or a sub directory of 'mods/'."}, - {"fs_homepath", "Game home path"}, - {"fs_ignoreLocalized", "Ignore localized assets"}, - {"fx_alphaThreshold", "Don't draw billboard sprites, oriented sprites or tails with alpha below this threshold (0-256)."}, - {"fx_cast_shadow", "Enable transparency shadow mapping from script"}, - {"fx_count", "Debug effects count"}, - {"fx_cull_elem_draw", "Culls effect elems for drawing"}, - {"fx_cull_elem_draw_flicker", "Flicker DPVS culled effect elems"}, - {"fx_cull_elem_spawn", "Culls effect elems for spawning"}, - {"fx_debugBolt", "Debug effects bolt"}, - {"fx_deferelem", "Toggles deferred processing of elements instead of effects"}, - {"fx_dpvs_cull_elem_draw", "Culls effect elems for drawing using DPVS(2: ignore per-effect portal culling flag)"}, - {"fx_draw", ""}, - {"fx_draw_omniLight", ""}, - {"fx_draw_simd", "Draw effects using SIMD / Vector code."}, - {"fx_draw_spotLight", ""}, - {"fx_drawClouds", "Toggles the drawing of particle clouds"}, - {"fx_enable", "Toggles all effects processing"}, - {"fx_flare", "Toggles fx flare"}, - {"fx_freeze", "Freeze effects"}, - {"fx_killEffectOnRewind", "Causes effects that have been marked for a soft kill (fade out) to be killed immediately on a rewind."}, - {"fx_lightGridSampleOffset", "the length of effect sample's offset along X Axis"}, - {"fx_mark_profile", "Turn on FX profiling for marks (specify which local client, with '1' being the first.)"}, - {"fx_marks", "Toggles whether bullet hits leave marks"}, - {"fx_marks_ents", "Toggles whether bullet hits leave marks"}, - {"fx_marks_nearlimit", "Sets limit of number of decals that can exist at the same location (0 for unlimited)"}, - {"fx_marks_smodels", "Toggles whether bullet hits leave marks"}, - {"fx_physicsImpactVelocityThreshold", "Set the min normal velocity threshold in order for model physics fx to generate child impact effects."}, - {"fx_profile", "Turn on FX profiling (specify which local client, with '1' being the first.)"}, - {"fx_profileFilter", "Only show effects with this as a substring in FX profile"}, - {"fx_profileFilterElemCountZero", "Do not include FX that have a zero element count"}, - {"fx_profileSkip", "Skip the first n lines in FX profile (to see ones off bottom of screen)"}, - {"fx_profileSort", "Choose sort criteria for FX profiling"}, - {"fx_showLightGridSampleOffset", "show light grid sample offset in CreateFX mode"}, - {"fx_visMinTraceDist", "Minimum visibility trace size"}, - {"g_allowVote", "Enable voting on this server"}, - {"g_atmosFogDistanceScaleReadOnly", "scale applied to scene distance used for atmospheric fog calculation"}, - {"g_atmosFogEnabledReadOnly", "use atmospheric fog"}, - {"g_atmosFogExtinctionStrengthReadOnly", "scale out scatter contribution of atmospheric fog"}, - {"g_atmosFogHalfPlaneDistanceReadOnly", "distance at which atmospheric fog contributes half the pixels color"}, - {"g_atmosFogHazeSpreadReadOnly", "directionality of haze (1ReadOnly = all forward scatter, 0ReadOnly = all back scatter)"}, - {"g_atmosFogHazeStrengthReadOnly", "portion of atmospheric fog density that is haze (0ReadOnly = all fog, 1ReadOnly = all haze)"}, - {"g_atmosFogHeightFogBaseHeightReadOnly", "height fog is full density at this world height and below"}, - {"g_atmosFogHeightFogEnabledReadOnly", "use height for atmospheric fog"}, - {"g_atmosFogHeightFogHalfPlaneDistanceReadOnly", "at this distance above g_atmosFogHeightFogBaseHeight, height fog density is half"}, - {"g_atmosFogInScatterStrengthReadOnly", "scale in scatter contribution of atmospheric fog"}, - {"g_atmosFogSkyAngularFalloffEnabledReadOnly", "use angular sky falloff for atmospheric fog"}, - {"g_atmosFogSkyDistanceReadOnly", "distance used for sky box when applying atmospheric fog"}, - {"g_atmosFogSkyFalloffAngleRangeReadOnly", "sky fog angular falloff angle range sky fog falls off over this range from the start angle"}, - {"g_atmosFogSkyFalloffStartAngleReadOnly", "sky fog angular falloff start angle (full strength fog at this angle)"}, - {"g_atmosFogStartDistanceReadOnly", "distance from camera at which fog contribution begins"}, - {"g_atmosFogSunDirectionReadOnly", "sun direction used when calculating atmospheric fog"}, - {"g_banIPs", "IP addresses to ban from playing"}, - {"g_clonePlayerMaxVelocity", "Maximum velocity in each axis of a cloned player\n(for death animations)"}, - {"g_deadChat", "Allow dead players to chat with living players"}, - {"g_dropForwardSpeed", "Forward speed of a dropped item"}, - {"g_dropHorzSpeedRand", "Random component of the initial horizontal speed of a dropped item"}, - {"g_dropUpSpeedBase", "Base component of the initial vertical speed of a dropped item"}, - {"g_dropUpSpeedRand", "Random component of the initial vertical speed of a dropped item"}, - {"g_earthquakeEnable", "Enable camera shake"}, - {"g_fogColorIntensityReadOnly", "HDR fog color intensity that was set in the most recent call to \"setexpfog\""}, - {"g_fogColorReadOnly", "Fog color that was set in the most recent call to \"setexpfog\""}, - {"g_fogHalfDistReadOnly", ""}, - {"g_fogMaxOpacityReadOnly", "Fog max opacity that was set in the most recent call to \"setexpfog\""}, - {"g_fogStartDistReadOnly", ""}, - {"g_friendlyfireDist", "Maximum range for disabling fire at a friendly"}, - {"g_friendlyNameDist", "Maximum range for seeing a friendly's name"}, - {"g_gametype", "The current game mode"}, - {"g_giveAll", "Give all weapons"}, - {"g_hardcore", "Hardcore?"}, - {"g_heightFogBaseHeightReadOnly", "height fog is full density at this world height and below"}, - {"g_heightFogEnabledReadOnly", "use height for normal/sun fog, set in the most recent call to \"setexpfog\""}, - {"g_heightFogHalfPlaneDistanceReadOnly", "at this distance above g_heightFogBaseHeight, height fog density is half, set in the most recent call to \"setexpfog\""}, - {"g_inactivity", "Time delay before player is kicked for inactivity"}, - {"g_keyboarduseholdtime", "The time to hold down the 'use' button to activate a 'use' command on a keyboard"}, - {"g_knockback", "Maximum knockback"}, - {"g_lagged_damage_threshold", "Threshold (ms) beyond which we will report a damaged lagged client to the tracker leaderboards."}, - {"g_listEntity", "List the entities"}, - {"g_mantleBlockTimeBuffer", "Time that the client think is delayed after mantling"}, - {"g_maxDroppedWeapons", "Maximum number of dropped weapons"}, - {"g_minGrenadeDamageSpeed", "Minimum speed at which getting hit be a grenade will do damage (not the grenade explosion damage)"}, - {"g_oldschool", "Oldschool?"}, - {"g_password", "Password"}, - {"g_playerCollisionEjectSpeed", "Speed at which to push intersecting players away from each other"}, - {"g_ScoresColor_Allies", "Allies team color on scoreboard"}, - {"g_ScoresColor_Axis", "Axis team color on scoreboard"}, - {"g_ScoresColor_EnemyTeam", "Enemy team color on scoreboard"}, - {"g_ScoresColor_Free", "Free Team color on scoreboard"}, - {"g_ScoresColor_MyParty", "Player team color on scoreboard when in the same party"}, - {"g_ScoresColor_MyTeam", "Player team color on scoreboard"}, - {"g_ScoresColor_Spectator", "Spectator team color on scoreboard"}, - {"g_scriptMainMenu", ""}, - {"g_sunFogBeginFadeAngleReadOnly", "Angle from the sun direction to start fade away from the sun fog color that was set in the most recent call to \"setexpfog\""}, - {"g_sunFogColorIntensityReadOnly", "HDR sun fog color intensity that was set in the most recent call to \"setexpfog\""}, - {"g_sunFogColorReadOnly", "Sun fog color that was set in the most recent call to \"setexpfog\""}, - {"g_sunFogDirReadOnly", "Sun fog direction that was set in the most recent call to \"setexpfog\""}, - {"g_sunFogEnabledReadOnly", "Sun fog was enabled in the most recent call to \"setexpfog\""}, - {"g_sunFogEndFadeAngleReadOnly", "Angle from the sun direction to end fade away from the sun fog color that was set in the most recent call to \"setexpfog\""}, - {"g_sunFogScaleReadOnly", "Distance scale in the sun fog direction that was set in the most recent call to \"setexpfog\""}, - {"g_TeamIcon_Allies", "Icon name for the allied scores banner"}, - {"g_TeamIcon_Axis", "Icon name for the axis scores banner"}, - {"g_TeamIcon_EnemyAllies", "Icon name for the allied scores banner"}, - {"g_TeamIcon_EnemyAxis", "Icon name for the axis scores banner when you're on axis."}, - {"g_TeamIcon_Free", "Icon name for the scores of players with no team"}, - {"g_TeamIcon_MyAllies", "Icon name for the allied scores banner"}, - {"g_TeamIcon_MyAxis", "Icon name for the axis scores banner when you're on axis."}, - {"g_TeamIcon_Spectator", "Icon name for the scores of players who are spectators"}, - {"g_TeamName_Allies", "Allied team name"}, - {"g_TeamName_Axis", "Axis team name"}, - {"g_TeamTitleColor_EnemyTeam", "Enemy team color for titles"}, - {"g_TeamTitleColor_MyTeam", "Player team color for titles"}, - {"g_TeamTitleColor_Spectator", "Spectator team color for titles"}, - {"g_useholdspawndelay", "Time in milliseconds that the player is unable to 'use' after spawning"}, - {"g_useholdtime", "Time to hold the 'use' button to activate use on a gamepad"}, - {"g_voiceChatTalkingDuration", "Time after the last talk packet was received that the player is considered by the\nserver to still be talking in milliseconds"}, - {"gamedate", "The date compiled"}, - {"gamedvr_active", "Are we allowed to enable GameDVR or not"}, - {"gameMode", "Current gameMode"}, - {"gamename", "The name of the game"}, - {"glass_angular_vel", "Sets the range of angular velocities used by new glass pieces"}, - {"glass_beamDamage", "The amount of damage beam attacks do to glass"}, - {"glass_break", "Toggle whether or not glass breaks when shot"}, - {"glass_crack_pattern_scale", "The scale applied to the radius used for the crack pattern"}, - {"glass_damageToDestroy", "The amount of damage a piece of glass must take to look damaged"}, - {"glass_damageToWeaken", "The amount of damage a piece of glass must take to look damaged"}, - {"glass_edge_angle", "Sets the range of angle deflections used by new glass pieces on a supported edge"}, - {"glass_fall_delay", "Sets how long a heavy piece supported by a single edge waits before falling, based on glass_fall_ratio"}, - {"glass_fall_gravity", "Gravity for falling pieces of glass"}, - {"glass_fall_ratio", "Ratio of piece area to supporting edge length squared. Below the min, the piece never falls."}, - {"glass_fringe_maxcoverage", "The maximum portion of the original piece of glass that is allowed to remain after the glass shatters"}, - {"glass_fringe_maxsize", "The maximum area for an edge piece of glass when shattering. Pieces larger than this will be broken into smaller ones"}, - {"glass_fx_chance", "Chance to play an effect on a small piece of glass when it hits the ground"}, - {"glass_hinge_friction", "Friction used by moving glass pieces when joined like a hinge to a frame"}, - {"glass_linear_vel", "Sets the range of linear velocities used by new glass pieces"}, - {"glass_max_pieces_per_frame", "Maximum number of pieces to create in one frame. This is a guideline and not a hard limit."}, - {"glass_max_shatter_fx_per_frame", "Maximum number of shatter effects to play in one frame This is a guideline and not a hard limit."}, - {"glass_meleeDamage", "The amount of damage melee attacks do to glass"}, - {"glass_physics_chance", "The chance for a given shard of glass to use physics"}, - {"glass_physics_maxdist", "The maximum distance of a glass piece from the player to do physics"}, - {"glass_radiusDamageMultiplier", "The amount to scale damage to glass from grenades and other explosions"}, - {"glass_shard_maxsize", "The maximum area for a flying piece of glass when shattering. Pieces larger than this will be broken into smaller ones"}, - {"glass_shattered_scale", "The scale of the shattered glass material"}, - {"glass_trace_interval", "The length of time, in milliseconds, between glass piece traces"}, - {"gpad_button_deadzone", "Game pad button deadzone threshhold"}, - {"gpad_dpadDebounceTime", ""}, - {"gpad_menu_scroll_delay_first", "Menu scroll key-repeat delay, for the first repeat, in milliseconds"}, - {"gpad_menu_scroll_delay_rest_accel", "Menu scroll key-repeat delay acceleration from start to end, for repeats after the first, in milliseconds per repeat"}, - {"gpad_menu_scroll_delay_rest_end", "Menu scroll key-repeat delay end, for repeats after the first, in milliseconds"}, - {"gpad_menu_scroll_delay_rest_start", "Menu scroll key-repeat delay start, for repeats after the first, in milliseconds"}, - {"gpad_stick_deadzone_max", "Game pad maximum stick deadzone"}, - {"gpad_stick_deadzone_min", "Game pad minimum stick deadzone"}, - {"gpad_stick_pressed", "Game pad stick pressed threshhold"}, - {"gpad_stick_pressed_hysteresis", "Game pad stick pressed no-change-zone around gpad_stick_pressed to prevent bouncing"}, - {"groupDownloadInterval", "Minimum interval to wait before getting new group counts"}, - {"groupUploadInterval", "Minimum interval to wait before setting new group counts"}, - {"heli_barrelMaxVelocity", ""}, - {"heli_barrelRotation", "How much to rotate the turret barrel when a helicopter fires"}, - {"heli_barrelSlowdown", ""}, - {"hiDef", "True if the game video is running in high-def."}, - {"httpnetfs", "Stream fastfiles from the specified http server"}, - {"hud_bloodOverlayLerpRate", "Rate at which blood overlay fades out"}, - {"hud_deathQuoteFadeTime", "The time for the death quote to fade"}, - {"hud_drawHud", ""}, - {"hud_enable", "Enable hud elements"}, - {"hud_fade_ammodisplay", "The time for the ammo display to fade in seconds"}, - {"hud_fade_compass", "The time for the compass to fade in seconds"}, - {"hud_fade_healthbar", "The time for the health bar to fade in seconds"}, - {"hud_fade_offhand", "The time for the offhand weapons to fade in seconds"}, - {"hud_fade_sprint", "The time for the sprint meter to fade in seconds"}, - {"hud_flash_period_offhand", "Offhand weapons flash period on changing weapon"}, - {"hud_flash_time_offhand", "Offhand weapons flash duration on changing weapon"}, - {"hud_health_pulserate_critical", "The pulse rate of the 'critical' pulse effect"}, - {"hud_health_pulserate_injured", "The pulse rate of the 'injured' pulse effect"}, - {"hud_health_startpulse_critical", "The health level at which to start the 'injured' pulse effect"}, - {"hud_health_startpulse_injured", "The health level at which to start the 'injured' pulse effect"}, - {"hudElemPausedBrightness", "Brightness of the hudelems when the game is paused."}, - {"hudOutlineDuringADS", "Turn on the HUD outline (green for friendly, red for enemy) when you are pointing at a player while in ADS."}, - {"igs_config_dw_filename", "Name of the configuration file on DW Publisher storage."}, - {"igs_sosp", "Show Original Season Pass"}, - {"igs_td", "Show Trial DLC"}, - {"igs_version", "Version id for the In-game store. Set version number to 0, to disable update."}, - {"in_mouse", "Initialize the mouse drivers"}, - {"inpubliclobby", "Currently in a public lobby"}, - {"intro", "Intro movie should play"}, - {"inventory_addEntitlementsToLocalInventory", "bypass the exchange and directly add entitlements to the local cached player inventory."}, - {"inventory_enabled", "enable/disable the inventory feature"}, - {"inventory_enableEntitlementDLCScanning", "enable scanning of entitlement DLC."}, - {"inventory_enableRevoke", "Enable revoke on purchases you no longer have rights to."}, - {"inventory_exchangeEnabled", "enable/disable the 1st party exchange feature"}, - {"inventory_exchangeMaxConsumablesPerBoot", "The maximum number of the same consumable that can be added per boot."}, - {"inventory_exchangeRetryBaseMS", "The amount to delay with each subsequent retry as base value to be multiplied by an exponential factor 1000 = (1000, 2000, 4000, 8000 etc.)"}, - {"inventory_exchangeRetryByRound", "enable/disable retry with exponential delay one round of exchanges at a time (1, 2, 3, 1, 2, 3, 1, 2, 3 etc.), vs exponential delay per exchange (1, 1, 1, 2, 2, 2, 3, 3, 3 etc.)"}, - {"inventory_exchangeRetryMax", "The number of times to retry for each exchange."}, - {"inventory_excludeEntitlementDLCScanning", "exclude scanning of entitlement DLC (comma separated list of ids to exclude)."}, - {"inventory_ignoreDWPushNotification_claimAchievement", "ignore incoming push notifications from DW to signal item update"}, - {"inventory_ignoreDWPushNotification_itemUpdate", "ignore incoming push notifications from DW to signal item update"}, - {"inventory_taskDefaultTimeout", "default timeout for inventory tasks (in seconds)"}, - {"inventory_taskExchangeTimeout", "default timeout for inventory exchange tasks (in seconds)"}, - {"inventory_taskGetTimeout", "default timeout for inventory GET tasks (in seconds)"}, - {"inventory_triggerExchangeOnContentMount", "trigger an exchange after mounting new content packs"}, - {"inventory_triggerExchangeOnStoreExit", "trigger an exchange when exiting the store"}, - {"iotd_active", "Is the IOTD system enabled"}, - {"iotd_retry", "Can the IOTD system retry fetching data from Demonware"}, - {"jump_slowdownEnable", "Slow player movement after jumping"}, - {"laserDebug", "Enables the display of various debug info."}, - {"laserLightRadius", "undefined"}, - {"laserRadius", "undefined"}, - {"lb_filter", "Filter applied to the leaderboard display: ('none','friends','facebook_friends')"}, - {"lb_group", "GroupID applied to the leaderboard display"}, - {"lb_maxrows", "Maximum number of rows to fetch"}, - {"lb_minrefresh", "Minimum time (in seconds) between leaderboard fetches"}, - {"lb_readDelay", "Delay time between reads(in milliseconds) between leaderboard fetches"}, - {"lb_throttle_time", "Lobby throttling amount"}, - {"lb_times_in_window", "Lobby throttling window amount"}, - {"lb_window", "Lobby throttling window"}, - {"live_qosec_firstupdatems", "MS to wait before deciding to early out qos"}, - {"live_qosec_lastupdatems", "MS since last update required to early out qos"}, - {"live_qosec_minpercent", "Minimum percentage of probe results required before early outing qos"}, - {"live_qosec_minprobes", "Minimum probe results required before early outing qos"}, - {"liveanticheatunknowndvar", "Live Anti Cheat Unknown Dvar"}, - {"livestreaming_active", "Are we allowed to enable LiveStreaming or not"}, - {"loading_sre_fatal", "Loading errors prevent level from loading."}, - {"lobby_animationSpeed", "How long each frame of the animation should draw, in milliseconds"}, - {"lobby_animationTilesHigh", "How many animation tiles high is the searching_for_player texture"}, - {"lobby_animationTilesWide", "How many animation tiles wide is the searching_for_player texture"}, - {"lobby_numAnimationFrames", "How many animation tiles are in the searching_for_player texture"}, - {"lobby_searchingPartyColor", "The color to show that we're searching for that slot when shown in lobbies"}, - {"loc_language", "Language"}, - {"loc_translate", "Enable translations"}, - {"log_host_migration_chance", "The % chance of host migration results telemetry"}, - {"log_party_state", "Log party state updates to Black Box system"}, - {"lowAmmoWarningColor1", "Color 1 of 2 to oscilate between"}, - {"lowAmmoWarningColor2", "Color 2 of 2 to oscilate between"}, - {"lowAmmoWarningNoAmmoColor1", "Like lowAmmoWarningColor1, but when no ammo."}, - {"lowAmmoWarningNoAmmoColor2", "lowAmmoWarningColor2, but when no ammo."}, - {"lowAmmoWarningNoReloadColor1", "Like lowAmmoWarningColor1, but when no ammo."}, - {"lowAmmoWarningNoReloadColor2", "lowAmmoWarningColor2, but when no ammo."}, - {"lowAmmoWarningPulseFreq", "Frequency of the pulse (oscilation between the 2 colors)"}, - {"lowAmmoWarningPulseMax", "Min of oscilation range: 0 is color1 and 1.0 is color2. Can be < 0, and the wave will clip at 0."}, - {"lowAmmoWarningPulseMin", "Max of oscilation range: 0 is color1 and 1.0 is color2. Can be > 1.0, and the wave will clip at 1.0."}, - {"lsp_enumertion_max_retry_time", "Max time that the LSP enumeration can retry"}, - {"lsp_enumertion_retry_step", "Step in m/s for the LSP enumeration retry"}, - {"lui_demoMode", "Check if the game is in demo mode."}, - {"lui_FFotDSupportEnabled", "Enables lui to update itself via the ffotd"}, - {"lui_hud_motion_angle_ease_speed", "Hud motion ease percentage of degrees per second"}, - {"lui_hud_motion_bob_scale", "Hud motion bob scale"}, - {"lui_hud_motion_enabled", "Enable hud motion"}, - {"lui_hud_motion_perspective", "value for hud motion perspective transform in pixels"}, - {"lui_hud_motion_rotation_max", "Hud motion rotation max"}, - {"lui_hud_motion_rotation_scale", "Hud motion rotation scale"}, - {"lui_hud_motion_trans_ease_speed", "Hud motion ease percentage of pixels per second"}, - {"lui_hud_motion_translation_max", "Hud motion translation max"}, - {"lui_hud_motion_translation_scale", "Hud motion translation scale"}, - {"lui_loot_duplicateredemption", "Whether a user can redeem duplicate loot items in the Armory"}, - {"LUI_MemErrorsFatal", "Out of memory errors cause drops when true, reinits the UI system if false"}, - {"lui_menuFlowEnabled", "Enables LUI menu flow"}, - {"lui_mlg_rules_unlocked", "Whether MLG rules are unlocked"}, - {"lui_priv_lobby_team", "Team selected in private match lobby"}, - {"lui_splitscreensignin_menu", "Enables the LUI splitscreensignin menu"}, - {"lui_splitscreenupscaling", "Force splitscreen upscaling off/on (-1 off, 1 on) -- requires map change"}, - {"lui_systemlink_menu", "Enables the LUI systemlink menu"}, - {"lui_waitingforgavelmessagesconfirmed", ""}, - {"lui_waitingfornetworktype", "value is LuiWaitingForNetworkType enum"}, - {"lui_waitingforonlinedatafetch_controller", "the controller index that is fetching the online stats data"}, - {"LUI_WorkerCmdGC", "Dev-only flag to enable/disable LUI workerCmd GC thread"}, - {"lui_xboxlive_menu", "Enables the LUI xboxlive menu"}, - {"m_filter", "Allow mouse movement smoothing"}, - {"m_forward", "Forward speed in units per second"}, - {"m_pitch", "Default pitch"}, - {"m_side", "Sideways motion in units per second"}, - {"m_yaw", "Default yaw"}, - {"manifestfs", "Use a manifest file to read segmented fastfiles"}, - {"mapname", "The current map name"}, - {"mapPackMPGroupFourFlags", "Map pack flags that comprise MP ala carte map pack 1"}, - {"mapPackMPGroupFreeFlags", "Map pack flags that comprise the free MP ala carte map pack"}, - {"mapPackMPGroupOneFlags", "Map pack flags that comprise MP ala carte map pack 1"}, - {"mapPackMPGroupThreeFlags", "Map pack flags that comprise MP ala carte map pack 1"}, - {"mapPackMPGroupTwoFlags", "Map pack flags that comprise MP ala carte map pack 1"}, - {"marketing_active", "Are we allowed to enable Marketing Comms or not"}, - {"marketing_refresh_time", "time in seconds to wait before refreshing marketing messages from demonware"}, - {"matchdata_active", "Are match data uploads enabled"}, - {"matchdata_maxcompressionbuffer", "Max SP match data compression buffer to use (in bytes)"}, - {"matchmaking_debug", "Enable matchmaking debugging information"}, - {"max_ping_threshold_good", "max ping value to be considered as good"}, - {"max_ping_threshold_medium", "max ping value to be considered as medium"}, - {"max_xp_per_match", ""}, - {"maxPrestigeOverride", "Overrides the maximum prestige level, disabled if 0."}, - {"maxVoicePacketsPerSec", ""}, - {"maxVoicePacketsPerSecForServer", ""}, - {"mdsd", "enable match data stat delta logging?"}, - {"melee_debug", "Turn on debug lines for melee traces"}, - {"migration_dvarErrors", "Whether to check for illegal script dvar changes."}, - {"min_wait_for_players", ""}, - {"missileRemoteFOV", "Remote missile-cam, FOV to use."}, - {"missileRemoteSteerPitchRange", "Remote-controlled missile allowed up/down range. To keep players from steering missiles above the horizon."}, - {"missileRemoteSteerPitchRate", "Remote-controlled missile up/down steering speed."}, - {"missileRemoteSteerYawRate", "Remote-controlled missile left/right steering speed."}, - {"mm_aw_onboarding_rank", "If a player is at or above this rank in AW, she is not considered onboarding"}, - {"mm_blops2_onboarding_skill", "Used to determine onboarding status for Ghosts"}, - {"mm_bucket_option", "if using bucketing, describes what pools can join with each other"}, - {"mm_country_code", "country code"}, - {"mm_ghosts_onboarding_skill", "Used to determine onboarding status for Ghosts"}, - {"mm_past_title_stats_source", "what type of information do we use from the past titles (rank vs kdr, etc)"}, - {"mm_skill_calculation_type", ""}, - {"mm_skill_enforcement", ""}, - {"mm_skill_lower_bucket", "lower mm skill bucket"}, - {"mm_skill_param_delta", "Delta parameter for Johnson SU distribution curve"}, - {"mm_skill_param_gamma", "Gamma parameter for Johnson SU distribution curve"}, - {"mm_skill_param_lambda", "Lambda parameter for Johnson SU distribution curve"}, - {"mm_skill_param_xi", "Xi parameter for Johnson SU distribution curve"}, - {"mm_skill_strict_enforcement", ""}, - {"mm_skill_type", "mm skill type"}, - {"mm_skill_upper_bucket", "upper mm skill bucket"}, - {"mm_sph_1", ""}, - {"mm_sph_10", ""}, - {"mm_sph_11", ""}, - {"mm_sph_12", ""}, - {"mm_sph_13", ""}, - {"mm_sph_14", ""}, - {"mm_sph_15", ""}, - {"mm_sph_16", ""}, - {"mm_sph_17", ""}, - {"mm_sph_18", ""}, - {"mm_sph_2", ""}, - {"mm_sph_3", ""}, - {"mm_sph_4", ""}, - {"mm_sph_5", ""}, - {"mm_sph_6", ""}, - {"mm_sph_7", ""}, - {"mm_sph_8", ""}, - {"mm_sph_9", ""}, - {"mm_split_population", ""}, - {"mm_test_type", "mm test type"}, - {"mm_use_onboarding_skill", "If set, we will for the player's skill to be the lowest available"}, - {"monkeytoy", "Restrict console access"}, - {"motd", ""}, - {"motd_store_link", "Add a link to the in-game store in the MOTD popup"}, - {"motionTrackerBlurDuration", "The motion blur duration for motion tracker dots"}, - {"motionTrackerCenterX", ""}, - {"motionTrackerCenterY", ""}, - {"motionTrackerPingFadeTime", "How long an enemy is visible on the motion tracker after being detected"}, - {"motionTrackerPingPitchAddPerEnemy", "The added percentage of pitch for each additional enemy that is detected (final pitch = base pitch * (1 + enemy count * this))"}, - {"motionTrackerPingPitchBase", "The pitch of the motion tracker sound for a nearby enemy"}, - {"motionTrackerPingPitchNearby", "The pitch of the motion tracker sound for a nearby enemy"}, - {"motionTrackerPingSize", "The width and height of the motion tracker's enemy indicators as a percentage of motion tracker scale"}, - {"msg_field_delta2", "enable the delta2 serialization."}, - {"name", "Player name"}, - {"net_authPort", "UDP port for Steam authentication"}, - {"net_ip", "Network IP Address"}, - {"net_masterServerPort", "UDP port for Steam server browser"}, - {"net_noudp", "Disable UDP"}, - {"net_port", "Network port"}, - {"net_socksEnabled", "Enable network sockets"}, - {"net_socksPassword", "Network socket password"}, - {"net_socksPort", "Network socket port"}, - {"net_socksServer", "Network socket server"}, - {"net_socksUsername", "Network socket username"}, - {"nextmap", "Next map to play"}, - {"nightVisionDisableEffects", ""}, - {"nightVisionFadeInOutTime", "How long the fade to/from black lasts when putting on or removing night vision goggles."}, - {"nightVisionPowerOnTime", "How long the black-to-nightvision fade lasts when turning on the goggles."}, - {"num_available_map_packs", "Number of map packs available for this platform"}, - {"objectiveFontSize", "Onscreen Objective Pointer - Fontsize of the icon's text."}, - {"objectiveTextOffsetY", "Onscreen Objective Pointer - Offset of the icon's text."}, - {"onlinegame", "Current game is an online game with stats, custom classes, unlocks"}, - {"overrideNVGModelWithKnife", "When true, nightvision animations will attach the weapDef's knife model instead of the night vision goggles."}, - {"overtimeTimeLimit", ""}, - {"p2pAuth_allow_steam_p2p", "Determines if Steam based P2P is allowed if direct connectivity is not possible."}, - {"p2pAuth_disable", ""}, - {"paintExplosionRadius", "The radius of the paint grenade explosion"}, - {"painVisionLerpOutRate", "Rate at which pain vision effect lerps out"}, - {"painVisionTriggerHealth", "Health (0 to 1) that will trigger the pain vision effect"}, - {"party_alternateMapVoteStatus", "Alternate map vote progress"}, - {"party_dlc_only_intended_mappacks", "When selecting next map for rotation, should any maps not in the intended search be excluded, even if available?"}, - {"party_firstSubpartyIndex", "Determines sort order and coloring of parties in lobbies. Randomly set by code. Dvar provided for debugging."}, - {"party_followPartyHostOutOfGames", "Whether we should follow our party host out of a game in progress."}, - {"party_gamesize", "Current maximum game size"}, - {"party_gametype", "Current gametype"}, - {"party_inactiveHeartbeatPeriod", "How often to send inactive party keep alive packets in milliseconds."}, - {"party_initial_dlc_search_timer", "Time until DLC enabled search should show an error dialog suggesting the user consider going to non dlc search"}, - {"party_IsLocalClientSelected", "True if selected player is a local client. Only valid when used with party feeders."}, - {"party_kickplayerquestion", "String to store the question about kicking the selected player"}, - {"party_listFocus", "True when an item in the party list has focus."}, - {"party_lobbyPlayerCount", "Number of players currently in the party/lobby"}, - {"party_mapname", "Current map name"}, - {"party_mapvote_entrya_mapname", "Primary map vote entry name"}, - {"party_mapvote_entryb_mapname", "Alternate map vote entry name"}, - {"party_matchedPlayerCount", "Number of matched players before revealing their true names"}, - {"party_maxplayers", "Maximum number of players in a party"}, - {"party_maxPrivatePartyPlayers", "Max number of players allowed in a private party."}, - {"party_maxTeamDiff", "Maximum difference allowed between teams before starting a match"}, - {"party_membersMissingMapPack", "Whether any party member is missing one of the enabled map packs. Only valid after running partyUpdateMissingMapPackDvar"}, - {"party_minLobbyTime", "Minimum time (in seconds) for a lobby to be open before auto starting a match"}, - {"party_minplayers", "Minimum number of players in a party"}, - {"party_nextMapVoteStatus", "Next map vote progress"}, - {"party_partyPlayerCount", "Number of players currently in the party/lobby"}, - {"party_partyPlayerCountNum", "Number of players currently in the party/lobby"}, - {"party_playersCoop", "True if the current playlist places all players on the allies team"}, - {"party_playervisible", "Whether selected player in party is showing true info or not. Only valid when used with party feeders."}, - {"party_randomMapVoteStatus", "Random map vote progress"}, - {"party_resume_dlc_search_timer", "Time until DLC enabled search should show an error dialog suggesting the user consider going to non dlc search"}, - {"party_search_for_dlc_content", "search for DLC enabled games else standard maps only will be used"}, - {"party_selectedIndex", "Current selected player index in the feeder."}, - {"party_selectedIndexChangedTime", "Time stamp in milliseconds when the selected index last changed."}, - {"party_statusString", "Party Status (localized )"}, - {"party_teambased", "True if the current playlist is team based"}, - {"party_teamsVisible", "teams are visible in UI"}, - {"party_timer", "Time until game begins in seconds, for UI display"}, - {"partyChatDisallowed", "Whether to disallow ps4 Live Party Chat"}, - {"partymigrate_broadcast_interval", "Time between telling people who the new host is when migrating lobby"}, - {"partymigrate_cpuBonusPing", "The ping rewarded to a CPU meeting the bonus threshold when scoring hosts."}, - {"partymigrate_cpuBonusThreshold", "The required excess %CPU speed to get a bonus when scoring hosts."}, - {"partymigrate_logResults", "Instrumentation - Whether to log the best host calculation results. 0 is disabled, 1 for games, 2 for parties, 3 for both."}, - {"partymigrate_makeHostTimeout", "Time before giving up on makeHost requests"}, - {"partymigrate_pingtest_active", "Whether to do a ping test when lobby migrating"}, - {"partymigrate_pingtest_filterThreshold", "Acceptable ping difference from best ping host for host selection (ms)"}, - {"partymigrate_pingtest_minThreshold", "Minimum meaningful ping delta for host selection (ms)"}, - {"partymigrate_pingtest_retry", "Time between ping tests when migrating lobby"}, - {"partymigrate_pingtest_timeout", "Time to give up on ping tests when migrating lobby"}, - {"partymigrate_preferSameHost", "When possible, prefer keeping the same host on migrations"}, - {"partymigrate_selectiontime", "Time before requiring a host selection when migrating lobby"}, - {"partymigrate_timeout", "Time before giving up on lobby migration if we hear nothing"}, - {"partymigrate_timeoutmax", "Time before giving up on lobby migration if we hear nothing"}, - {"partymigrate_uploadtest_minThreshold", "Minimum meaningful upload bandwidth delta for host selection (bps)"}, - {"password", ""}, - {"perk_armorPiercingDamage", ""}, - {"perk_blastShieldScale", ""}, - {"perk_blastShieldScale_HC", ""}, - {"perk_bulletPenetrationMultiplier", "Multiplier for extra bullet penetration"}, - {"perk_extendedMagsMGAmmo", "Number of extra bullets per clip for machine gun weapons with the extended mags perk."}, - {"perk_extendedMagsPistolAmmo", "Number of extra bullets per clip for pistol weapons with the extended mags perk."}, - {"perk_extendedMagsRifleAmmo", "Number of extra bullets per clip for rifle weapons with the extended mags perk."}, - {"perk_extendedMagsSMGAmmo", "Number of extra bullets per clip for sub machine gun weapons with the extended mags perk."}, - {"perk_extendedMagsSpreadAmmo", "Number of extra bullets per clip for spread weapons with the extended mags perk."}, - {"perk_extraBreath", "Number of extra seconds a player can hold his breath"}, - {"perk_fastClimb", "Scales the ladder climb time"}, - {"perk_fastRegenRate", ""}, - {"perk_fastRegenWaitMS", ""}, - {"perk_fastSnipeScale", "Scales the recovery speed of the view kick when using a sniper."}, - {"perk_footstepVolumeAlly", ""}, - {"perk_footstepVolumeEnemy", ""}, - {"perk_footstepVolumePlayer", ""}, - {"perk_footstepVolumeSelectiveHearingMin", ""}, - {"perk_improvedExtraBreath", "Number of extra seconds a player can hold his breath"}, - {"perk_lightWeightViewBobScale", "Scale for first person view movement while lightweight."}, - {"perk_numExtraLethal", "Number of extra lethal grenades"}, - {"perk_numExtraTactical", "Number of extra tactical grenades"}, - {"perk_parabolicAngle", "Eavesdrop perk's effective FOV angle"}, - {"perk_parabolicIcon", "Eavesdrop icon to use when displaying eavesdropped voice chats"}, - {"perk_parabolicRadius", "Eavesdrop perk's effective radius"}, - {"perk_quickDrawSpeedScale", "Scales the 'Hip to ADS' transition speed."}, - {"perk_quickDrawSpeedScaleSniper", "Scales the 'Hip to ADS' transition speed."}, - {"perk_scavengerMode", ""}, - {"perk_sprintMultiplier", "Multiplier for player_sprinttime"}, - {"perk_sprintRecoveryMultiplierActual", ""}, - {"perk_sprintRecoveryMultiplierVisual", ""}, - {"perk_weapRateMultiplier", "Percentage of weapon firing rate to use"}, - {"perk_weapReloadMultiplier", "Percentage of weapon reload time to use"}, - {"perk_weapSpreadMultiplier", "Percentage of weapon spread to use"}, - {"phys_autoDisableLinear", "A body must have linear velocity less than this to be considered idle."}, - {"phys_autoDisableTime", "The amount of time a body must be idle for it to go to sleep."}, - {"phys_bulletSpinScale", "Scale of the effective offset from the center of mass for the bullet impacts."}, - {"phys_bulletUpBias", "Up Bias for the direction of the bullet impact."}, - {"phys_dragAngular", "The amount of angular drag, applied globally"}, - {"phys_dragLinear", "The amount of linear drag, applied globally"}, - {"phys_gravity", "Physics gravity in units/sec^2."}, - {"phys_gravity_ragdoll", "Physics gravity used by ragdolls in units/sec^2."}, - {"phys_gravityChangeWakeupRadius", "The radius around the player within which objects get awakened when gravity changes"}, - {"phys_jitterMaxMass", "Maximum mass to jitter - jitter will fall off up to this mass"}, - {"physVeh_explodeForce", "The force applied to physics vehicles due to explosions"}, - {"physVeh_explodeSpinScale", "The max (random) offset from the center of mass at which splash damage applies its force"}, - {"physVeh_jump", "Set to 1 to make a vehicle jump."}, - {"physVeh_minContactImpulse", "The minimum impulse needed to register a contact notification"}, - {"physVeh_minImpactMomentum", "The minimum collision momentum needed to register an impact"}, - {"physVeh_StepsPerFrame", "The number of physics timesteps that the server frame will be divided into."}, - {"pickupPrints", "Print a message to the game window when picking up ammo, etc."}, - {"player_breath_snd_delay", "The delay before playing the breathe in sound"}, - {"player_breath_snd_lerp", "The interpolation rate for the player hold breath sound"}, - {"player_current_floor", ""}, - {"player_MGUseRadius", "The radius within which a player can mount a machine gun"}, - {"player_stunWhiteFlash", "If enabled, player's screens will flash white when they are stunned."}, - {"player_throwbackInnerRadius", "The radius to a live grenade player must be within initially to do a throwback"}, - {"player_throwbackOuterRadius", "The radius player is allow to throwback a grenade once the player has been in the inner radius"}, - {"player_useRadius", "The radius within which a player can use things"}, - {"playercard_cache_download_max_retry_time", "Max time that the player cache download can retry"}, - {"playercard_cache_download_retry_step", "Step in m/s for the player cache download retry"}, - {"playercard_cache_upload_max_retry_time", "Max time that the player cache upload can retry"}, - {"playercard_cache_upload_retry_step", "Step in m/s for the player cache upload retry"}, - {"playercard_cache_validity_life", "The life of a cached gamercard (it can be re-downloaded after this)"}, - {"playerPositionRecordSampleTime", "How often to sample player positions and save them into match data."}, - {"playlist", "The playlist number"}, - {"playlistAggrFilename", "Aggregated playlist filename"}, - {"playlistFilename", "Playlist filename"}, - {"playListUpdateCheckMinutes", "Minutes to wait between checking for updated playlist."}, - {"prestige_shop_active", "Are we allowed to show the Prestige Shop or not"}, - {"prestige30EasterEggEnabled", "Enables the easter egg for prestige 30 if 1, disabled if 0."}, - {"privateMatch_joinPassword", ""}, - {"privateMatch_serverPassword", ""}, - {"profileMenuOption_blacklevel", ""}, - {"profileMenuOption_offensiveContentMode", "Mode of the offensive content warning at startup - 0, skip and turn on; 1, skip and turn off; 2, ask user"}, - {"profileMenuOption_safeAreaHorz", ""}, - {"profileMenuOption_safeAreaVert", ""}, - {"profileMenuOption_volume", ""}, - {"protocol", "Protocol version"}, - {"pt_AliensReadyUpPrivateInUse", "Do we use the co-op Ready Up feature in public lobbies?"}, - {"pt_AliensReadyUpPublicInUse", "Do we use the co-op Ready Up feature in public lobbies?"}, - {"pt_AliensReadyUpPublicStartTimerLength", "co-op Ready Up start timer length in seconds"}, - {"pt_allMembersDoQoS", "Whether to send search results to all party/lobby members to get QoS data"}, - {"pt_backoutOnClientPresence", "Whether the host should backout the party on client presence. 0=fully disabled, 1=out of game only, 2=in-game also"}, - {"pt_connectAttempts", "Connect timeout when joining another game/party, per attempt"}, - {"pt_connectTimeout", "Connect timeout when joining another game/party, per attempt"}, - {"pt_gameStartTimerLength", "Time in seconds before a game start once enough party members are ready"}, - {"pt_logHostSelectionChance", "Sets the probability that we log our host selection results"}, - {"pt_memberTimeout", "Client timeout time in the general case"}, - {"pt_migrateBeforeAdvertise", "Whether lobbies made by private parties should migrate host before publishing"}, - {"pt_migrationBandwidthBonusPing", "The ping rewarded to the bonus bandwidth threshold when scoring hosts."}, - {"pt_migrationBandwidthBonusThreshold", "The required excess % upload bandwidth to get a bonus when scoring hosts."}, - {"pt_migrationCPUWeight", "How important CPU speed is when selecting a new host"}, - {"pt_migrationNotInstalledWeight", "How important not being done installing is when selecting a new host"}, - {"pt_migrationPingBad", ""}, - {"pt_migrationPingWeight", ""}, - {"pt_migrationQuitsBad", ""}, - {"pt_migrationQuitsWeight", ""}, - {"pt_migrationRAMWeight", "How important it is to have the minimum amount of RAM when selecting a new host"}, - {"pt_migrationThreshold", "Minimum amount which another client must be better than the current host to trigger a migration"}, - {"pt_migrationUploadBad", ""}, - {"pt_migrationUploadWeight", ""}, - {"pt_migrationWifiPenalty", "How important Wifi is when selecting a new host"}, - {"pt_pregameStartTimerLength", "Time in seconds before showing and starting the game start timer"}, - {"pt_rejoin", "Enable defensive rejoin command"}, - {"pt_reservedAnonymousSlotTime", "Time in milliseconds that ANONYMOUS slots will be reserved."}, - {"pt_reservedCommittedSlotTime", "Time in milliseconds that COMMITTED slots will be reserved"}, - {"pt_reservedJoiningSlotTime", "Time in milliseconds that JOINING slots will be reserved"}, - {"pt_searchConnectAttempts", "Connect timeout when joining another game/party, per attempt"}, - {"pt_searchPauseTime", "Minimum amount of time to pause between searches"}, - {"pt_searchRandomDelay", "Time period over which the search timers will get randomly delayed."}, - {"pt_searchResultsLifetime", "Time at which we consider the search results stale"}, - {"pt_searchResultsMin", "Minimum amount of time that has to pass before we'll search again for matches"}, - {"pt_stillConnectingWaitTime", "Amount of time to wait for someone to finish connecting before searching for lobbies to merge with"}, - {"pt_useMigrationWeights", "Killswitch to turn on or off the host selection by weights"}, - {"publisherFileFetchTimeout", "default timeout for publisher files FETCH tasks (in seconds)"}, - {"r_adaptiveSubdiv", "Enables screen space Catmull Clark adaptive tessellation. If disabled, models tessellate to their designed subdivision level."}, - {"r_adaptiveSubdivBaseFactor", "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation."}, - {"r_adaptiveSubdivPatchFactor", "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation."}, - {"r_allCells", "Draw all cells. Most useful for seeing if portals or cells are hiding things they should not.."}, - {"r_amdGPU", "At least on AMD GPU used for rendering."}, - {"r_aoBlurSharpness", "Controls the tolerance for depth discontinuities during the bilateral blur step. Larger values reduce the depth tolerance and effectively sharpen more edges."}, - {"r_aoBlurStep", "Step scale applied to sample offsets during the bilateral blur. A value of 1 results in a normal gaussian blur. Increasing it to 2 or 3 makes the filter larger but causes fine dithering patterns."}, - {"r_aoDiminish", "Decrease the effect of occlusion on brighter colors"}, - {"r_aoPower", "Power curve applied to AO factor"}, - {"r_aoStrength", "Strength of Ambient Occlusion effect"}, - {"r_aoUseTweaks", "Use r_ao* dvars instead of the current light set values for AO common params"}, - {"r_artUseTweaks", "Tells the game that art tweaks is enabled and script is in control (as opposed to ColorEd)."}, - {"r_aspectRatio", "Screen aspect ratio. Most widescreen monitors are 16:10 instead of 16:9."}, - {"r_asyncCompute", "Enables scheduling GPU compute shader work prior to the graphics frame, improving overlap."}, - {"r_atlasAnimFPS", "Speed to animate atlased 2d materials"}, - {"r_autopriority", "Automatically set the priority of the windows process when the game is minimized"}, - {"r_balanceLightmapOpaqueLists", "Split lightmap opaque into multiple draw lists."}, - {"r_blacklevel", "Black level (negative brightens output)"}, - {"r_blur", "Dev tweak to blur the screen"}, - {"r_blurdstGaussianBlurLevel", "MIP level to start gaussian blur at"}, - {"r_blurdstGaussianBlurRadius", "Amount to gaussian blur blur distortion render target"}, - {"r_brightness", "Brightness adjustment"}, - {"r_cacheModelLighting", "Speed up model lighting by caching previous results"}, - {"r_cacheSModelLighting", "Speed up static model lighting by caching previous results"}, - {"r_charLightAmbient", ""}, - {"r_clampLodScale", "Clamps the amount that the engine can adjust the LOD distance. 0 the engine can fully adjust. 1 the engine cannot adjust it at all. 0.5 the maximum the engine can adjust the LOD distance is 50% or the default."}, - {"r_clear", "Controls how the color buffer is cleared"}, - {"r_clearColor", "Color to clear the screen to when clearing the frame buffer"}, - {"r_clearColor2", "Color to clear every second frame to (for use during development)"}, - {"r_clutCompositeVisionSet", "Composite clut with vision set."}, - {"r_cmdbuf_worker", "Process command buffer in a separate thread"}, - {"r_colorGradingEnable", "Enable color grading."}, - {"r_colorMap", "Replace all color maps with pure black or pure white"}, - {"r_colorScaleUseTweaks", "Override color scale LightSet settings with tweak dvar values. (MP)"}, - {"r_combinePostOpaqueFx", ""}, - {"r_contrast", "Contrast adjustment"}, - {"r_darkBlur", "Apply blur (decrease of visual acuity) when dark"}, - {"r_darkBlurPower", "Power curve of blurring (decrease of visual acuity) when dark"}, - {"r_darkBlurRadius", "Radius of blurring (decrease of visual acuity) when dark"}, - {"r_darkColor", "Reduce color sensitivity when dark"}, - {"r_darkColorPower", "Power curve of color sensitivity when dark"}, - {"r_debugLineWidth", "Width of server side debug lines"}, - {"r_defaultPatchCount", "Patches per thread group for all other surfaces."}, - {"r_depthPrepass", "Enable depth prepass for various geometries"}, - {"r_depthSortEnable", "Enable sorting of transparent surfaces."}, - {"r_depthSortRange", "Range to consider depth sort,"}, - {"r_desaturation", "Desaturation adjustment"}, - {"r_detailMap", "Replace all detail maps with an image that effectively disables them"}, - {"r_diffuseColorScale", "Globally scale the diffuse color of all point lights"}, - {"r_displacementMap", "Replace all displacement maps with an image that effectively disables them"}, - {"r_displacementPatchCount", "Patches per thread group for displacement surfaces."}, - {"r_distortion", "Enable distortion"}, - {"r_distortion_script_force_off", "Force distortion off in script"}, - {"r_dlightLimit", "Maximum number of dynamic lights drawn simultaneously"}, - {"r_dof_bias", "Depth of field bias as a power function (like gamma); less than 1 is sharper"}, - {"r_dof_enable", "Enable the depth of field effect"}, - {"r_dof_farBlur", ""}, - {"r_dof_farEnd", "Depth of field far end distance, in inches"}, - {"r_dof_farStart", "Depth of field far start distance, in inches"}, - {"r_dof_nearBlur", ""}, - {"r_dof_nearEnd", "Depth of field near end distance, in inches"}, - {"r_dof_nearStart", "Depth of field near start distance, in inches"}, - {"r_dof_physical_adsFocusSpeed", "ADS focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)"}, - {"r_dof_physical_adsMaxFstop", "ADS maximum f-stop (optimal aperture and focus distance are automatically calculated for this mode)"}, - {"r_dof_physical_adsMinFstop", "ADS minimum f-stop (optimal aperture and focus distance are automatically calculated for this mode)"}, - {"r_dof_physical_bokehEnable", "Enable the bokeh depth of field effect"}, - {"r_dof_physical_bokehPreset", "Changes dof sampling quality"}, - {"r_dof_physical_bokehRotation", "Bokeh shape rotation in degrees (hexagonal and octogonal only)"}, - {"r_dof_physical_bokehShape", "Changes the bokeh shape"}, - {"r_dof_physical_bokehSharpness", "Bokeh shape sharpness, trades sharpness for stability (circular only)"}, - {"r_dof_physical_enable", "enable physical camera controls (using aperture priority)"}, - {"r_dof_physical_filmDiagonal", "Diagonal size of the film/sensor (mm). The bigger the sensor size, the bigger the circle of confusion (which means stronger blurring at all distances). Defaults to full-frame 35mm"}, - {"r_dof_physical_focusDistance", "Distance to the plane in focus for the scene"}, - {"r_dof_physical_fstop", "Aperture of the camera for the scene. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32"}, - {"r_dof_physical_hipEnable", "Enable hyperfocal mode"}, - {"r_dof_physical_hipFocusSpeed", "Hyperfocal mode focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)"}, - {"r_dof_physical_hipFstop", "Aperture of the camera for the scene in the hyperfocal mode"}, - {"r_dof_physical_hipSharpCocDiameter", "Defines what circle of confusion can be considered sharp (mm). Defaults to 0.03mm, generally accepted value for 35mm"}, - {"r_dof_physical_maxCocDiameter", "Maximum circle of confusion diameter (virtual units, might be clamped for bokeh dof)"}, - {"r_dof_physical_minFocusDistance", "Minimum focus distance (inches)"}, - {"r_dof_physical_viewModelFocusDistance", "Distance to the plane in focus for the scene"}, - {"r_dof_physical_viewModelFstop", "Aperture of the camera for the view model. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32"}, - {"r_dof_tweak", "Use dvars to set the depth of field effect; overrides r_dof_enable"}, - {"r_dof_viewModelEnd", "Depth of field viewmodel end distance, in inches"}, - {"r_dof_viewModelStart", "Depth of field viewmodel start distance, in inches"}, - {"r_drawSun", "Enable sun effects"}, - {"r_drawWater", "Enable water animation"}, - {"r_dynamicOPL", "Enable drawing vfx lights as overlapping primary light for saving gpu performance."}, - {"r_dynamicSpotLightShadows", "Enable shadows for dynamic/VFX spot lights, you should set this dvar then spawn the new light."}, - {"r_elevatedPriority", "Utilize priority elevation for process."}, - {"r_emblemBrightnessScale", "Modifier that scales the brightness of the emblem on model materials"}, - {"r_emissiveMap", "Replace all emissive maps with pure black or pure white"}, - {"r_enableNoTessBuckets", "Enables placing triangles that don't need tessellation into additional draw calls using non-tessellated shaders."}, - {"r_envBrdfLutMap", "Replace environment BRDF lookup table with pure black (no secondary specular) or pure white (maximum secondary specular)"}, - {"r_envMapExponent", "Reflection exponent."}, - {"r_envMapMaxIntensity", "Max reflection intensity based on glancing angle."}, - {"r_envMapMinIntensity", ""}, - {"r_envMapOverride", ""}, - {"r_envMapSunIntensity", "Max sun specular intensity intensity with env map materials."}, - {"r_eyePupil", " Change eye's pupil Size."}, - {"r_eyeRedness", " Change eye's redness."}, - {"r_eyeWetness", " Change eye's wetness."}, - {"r_fastModelPrimaryLightCheck", "Reduce R_GetNonSunPrimaryLightForSphere/R_GetNonSunPrimaryLightForBox function calls"}, - {"r_fastModelPrimaryLightLink", "Speed up R_LinkSphereEntityToPrimaryLights and R_LinkBoxEntityToPrimaryLights."}, - {"r_filmAltShader", "Use alternate shader (with middle tint and dark desat) for film color."}, - {"r_filmTweakBrightness", "Tweak dev var; film color brightness"}, - {"r_filmTweakContrast", "Tweak dev var; film color contrast"}, - {"r_filmTweakDarkTint", ""}, - {"r_filmTweakDesaturation", "Tweak dev var; Desaturation applied after all 3D drawing to light areas"}, - {"r_filmTweakDesaturationDark", "Tweak dev var; Additional desaturation applied after all 3D drawing to dark areas"}, - {"r_filmTweakEnable", "Tweak dev var; enable film color effects"}, - {"r_filmTweakInvert", "Tweak dev var; enable inverted video"}, - {"r_filmTweakLightTint", ""}, - {"r_filmTweakMediumTint", ""}, - {"r_filmUseTweaks", "Overide film effects with tweak dvar values."}, - {"r_flushAfterExecute", "Whether to Flush after ExecuteCommandList."}, - {"r_fog", "Set to 0 to disable fog"}, - {"r_fog_depthhack_scale", "Fog scale for depth hack surfaces"}, - {"r_fog_ev_adjust", "Fog color ev adjustment (+2 means fog color is 2 stops brighter)"}, - {"r_font_cache_debug_display", "Display the current fontcache texture on the HUD for debug purposes"}, - {"r_forceLod", "Force all level of detail to this level"}, - {"r_fullbright", "Toggles rendering without lighting"}, - {"r_fxaaSubpixel", "FXAA sub-pixel amount, lower values have more aliasing and less blur"}, - {"r_FXAverageColorFunc", "How to compute FX system average color? 0 = use IWrad equation, 1 = legacy equation, 2 = spherical harmonics 1 coefficient."}, - {"r_globalGenericMaterialScale", "Hack global generic material constants"}, - {"r_glow_allowed", "Allow glow."}, - {"r_glow_allowed_script_forced", "Force 'allow glow' to be treated as true, by script."}, - {"r_gunSightColorEntityScale", "Scale the gun sight color when over an entity."}, - {"r_gunSightColorNoneScale", "Scale the gun sight color when not over an entity."}, - {"r_hbaoBias", "HBAO bias"}, - {"r_hbaoBlurEnable", "HBAO blur enabled"}, - {"r_hbaoBlurSharpness", "HBAO blur sharpness"}, - {"r_hbaoCoarseAO", "HBAO coarse AO"}, - {"r_hbaoDebug", "Debug render HBAO occlusion"}, - {"r_hbaoDetailAO", "HBAO detail AO"}, - {"r_hbaoPowerExponent", "HBAO power exponent"}, - {"r_hbaoRadius", "HBAO radius"}, - {"r_hbaoSceneScale", "HBAO scene scale"}, - {"r_hbaoStrengthBlend", "Blend factor between the artist-tuned proportional strength r_hbaoStrengthScale*artStrength, and the fixed strength r_hbaoStrengthFixed. A value of 0.0 is fully the proportional value, and a value of 1.0 is fully the fixed value."}, - {"r_hbaoStrengthFixed", "Fixed HBAO strength. Only used if r_hbaoStrengthBlend > 0.0."}, - {"r_hbaoStrengthScale", "Scale factor to convert SSAO strength to HBAO strength. Only used if r_hbaoStrengthBlend < 1.0."}, - {"r_hbaoUseScriptScale", "Enable/disable script-controlled strength scale while HBAO is active."}, - {"r_hemiAoBlurTolerance", "Hemi SSAO Blur Tolerance (log10)"}, - {"r_hemiAoCombineResolutionsBeforeBlur", "The higher quality modes blend wide and narrow sampling patterns. The wide pattern is due to deinterleaving and requires blurring. The narrow pattern is not on a deinterleaved buffer, but it only samples every other pixel. The blur on it is optional. If you combine the two before blurring, the narrow will get blurred as well. This creates a softer effect but can remove any visible noise from having 50% sample coverage."}, - {"r_hemiAoCombineResolutionsWithMul", "When combining the wide and narrow patterns, a mul() operation can be used or a min() operation. Multiplication exaggerates the result creating even darker creases. This is an artistic choice. I think it looks less natural, but often art teams prefer more exaggerated contrast. For me, it's more about having the right AO falloff so that it's a smooth gradient rather than falling off precipitously and forming overly dark recesses."}, - {"r_hemiAoDepthSquash", "Hemi SSAO depth squash. Value is rcp."}, - {"r_hemiAoEnable", "Enable Hemi SSAO"}, - {"r_hemiAoHierarchyDepth", "Hemi SSAO recursion depth (filter width)"}, - {"r_hemiAoMaxDepthDownsample", "Use max depth value when downsampling, instead of pseudo-randomly picking a depth sample? Leaving this at the default false may produce more stable results."}, - {"r_hemiAoNoiseFilterTolerance", "This is necessary to filter out pixel shimmer due to bilateral upsampling with too much lost resolution. High frequency detail can sometimes not be reconstructed, and the noise filter fills in the missing pixels with the result of the higher resolution SSAO. Value is log10."}, - {"r_hemiAoPower", "Power curve applied to Hemi SSAO factor, not applied in game yet"}, - {"r_hemiAoQualityLevel", "Hemi SSAO quality setting"}, - {"r_hemiAoRejectionFalloff", "Controls how aggressive to fade off samples that occlude spheres but by so much as to be unreliable. This is what gives objects a dark halo around them when placed in front of a wall. If you want to fade off the halo, boost your rejection falloff. The tradeoff is that it reduces overall AO. Value is rcp."}, - {"r_hemiAoStrength", "Strength of Hemi Screen Space Ambient Occlusion effect"}, - {"r_hemiAoUpsampleTolerance", "Hemi SSAO Upsample Tolerance (log10)"}, - {"r_heroLighting", "Enable hero-only lighting"}, - {"r_highLodDist", "Distance for high level of detail"}, - {"r_hudFx", "Draw HUD Effects"}, - {"r_hudOutlineEnable", "Enables wireframe outlines to be drawn around DObjs (as a post process)."}, - {"r_hudOutlinePostMode", "hud outline apply mode"}, - {"r_hudOutlineWidth", "Set the width of the Hud Outline"}, - {"r_ignore", ""}, - {"r_ignoref", ""}, - {"r_imageQuality", "Image quality"}, - {"r_inGameVideo", "Allow in game cinematics"}, - {"r_lateAllocParamCacheAllowed", "Enable late allocation of parameter cache for VS stage."}, - {"r_lateAllocParamCacheDefault", "Late allocation of parameter cache value for sub-div materials."}, - {"r_lateAllocParamCacheDisplacement", "Late allocation of parameter cache value for sub-div materials."}, - {"r_lateAllocParamCacheSubdiv", "Late allocation of parameter cache value for sub-div materials."}, - {"r_lightCacheLessFrequentMaxDistance", "Adjust the distance fx models (and models tagged as less-frequently-lit by script) move before immediately being relit"}, - {"r_lightCacheLessFrequentPeriod", "Adjust how frequently fx models (and models tagged as less-frequently-lit by script) get relit on average (1 is every frame, 8 is every 8th frame)"}, - {"r_lightGridAvgApplyPrimaryLight", "apply primary light color onto r_showLightGridAvgProbes boxes"}, - {"r_lightGridAvgFollowCamera", "allow the r_showLightGridAvgProbes boxes following current camera position"}, - {"r_lightGridAvgProbeCount", "how many light grid avg color probes will show up)"}, - {"r_lightGridAvgTraceGround", " lock boxes to ground "}, - {"r_lightGridContrast", "Adjust the contrast of light color from the light grid"}, - {"r_lightGridDefaultFXLightingLookup", "Default FX lighting lookup location\n"}, - {"r_lightGridDefaultModelLightingLookup", "Default model lighting lookup location"}, - {"r_lightGridEnableTweaks", "Enable tweaks of the light color from the light grid"}, - {"r_lightGridIntensity", "Adjust the intensity of light color from the light grid"}, - {"r_lightGridSHBands", "Spherical harmonics bands being used for evaluating current-gen light grids colors. 0 = default, 1 = 1 band, 2 = 2 bands, 3 = 3 bands.\n"}, - {"r_lightGridUseTweakedValues", "Use tweaked values instead of default"}, - {"r_lightMap", "Replace all lightmaps with pure black or pure white"}, - {"r_litSurfaceHDRScalar", "Vision set based scalar applied to lit surfaces"}, - {"r_loadForRenderer", "Set to false to disable dx allocations (for dedicated server mode)"}, - {"r_lockPvs", "Lock the viewpoint used for determining what is visible to the current position and direction"}, - {"r_lod4Dist", "Distance for lowest level of detail 4"}, - {"r_lod5Dist", "Distance for lowest level of detail 5"}, - {"r_lodBiasRigid", ""}, - {"r_lodBiasSkinned", ""}, - {"r_lodScaleRigid", ""}, - {"r_lodScaleSkinned", ""}, - {"r_lowestLodDist", "Distance for lowest level of detail"}, - {"r_lowLodDist", "Distance for low level of detail"}, - {"r_mbEnable", "Set of objects which will be enabled for motion blur"}, - {"r_mbFastEnable", "Toggle on/off fast high quality motion blur"}, - {"r_mbFastPreset", "Changes motion blur quality"}, - {"r_mdao", "Enable the medium distance ambient occlusion feature"}, - {"r_mdaoAsyncOccluderGen", "The occluder generation step is performed via async compute"}, - {"r_mdaoBoneInfluenceRadiusScale", "Scale for the bone influence radius for mdao"}, - {"r_mdaoCapsuleStrength", "MDAO strength for capsule occluders"}, - {"r_mdaoMinBoneBoundsToOcclude", "Minimum volume of the bone collider to create occluders for"}, - {"r_mdaoOccluderCullDistance", "Culling distance for mdao occluders"}, - {"r_mdaoOccluderFadeOutStartDistance", "Fade out distance for mdao occluders"}, - {"r_mdaoUseTweaks", "Use r_mdao* dvars instead of the current light set values for MDAO"}, - {"r_mdaoVolumeStrength", "MDAO strength for volume occluders"}, - {"r_mediumLodDist", "Distance for medium level of detail"}, - {"r_mode", "Display mode"}, - {"r_modelLightingMap", "Replace all model lighting maps (light grid) with pure black"}, - {"r_monitor", "Index of the monitor to use in a multi monitor system; 0 picks automatically."}, - {"r_mpRimColor", "Change character's rim color for multiplayer"}, - {"r_mpRimDiffuseTint", "Change character's rim diffuse tint for multiplayer."}, - {"r_mpRimStrength", "Change character's rim color for multiplayer"}, - {"r_multiGPU", "Enable multi GPU compat mode."}, - {"r_normalMap", "Replace all normal maps with a flat normal map"}, - {"r_nvidiaGPU", "Enable NV API."}, - {"r_offchipTessellationAllowed", "Enable off-chip tessellation support."}, - {"r_offchipTessellationTfThreshold", "Tessellation factor threshold for off-chip."}, - {"r_offchipTessellationWaveThreshold", "Domain shader wave threshold for off-chip."}, - {"r_omitUnusedRenderTargets", "Omit unused render targets to save memory. Changing this requires a vid_restart."}, - {"r_outdoor", "Prevents snow from going indoors"}, - {"r_outdoorFeather", "Outdoor z-feathering value"}, - {"r_particleHdr", "Enable Hdr Particle Features"}, - {"r_patchCountAllowed", "Enable run-time setting of patch count per draw call."}, - {"r_picmip", "Picmip level of color maps. If r_picmip_manual is 0, this is read-only."}, - {"r_picmip_bump", "Picmip level of normal maps. If r_picmip_manual is 0, this is read-only."}, - {"r_picmip_spec", "Picmip level of specular maps. If r_picmip_manual is 0, this is read-only."}, - {"r_picmip_water", "Picmip level of water maps."}, - {"r_polygonOffsetBias", "Offset bias for decal polygons; bigger values z-fight less but poke through walls more"}, - {"r_polygonOffsetClamp", "Offset clamp for decal polygons; bigger values z-fight less but poke through walls more"}, - {"r_polygonOffsetScale", "Offset scale for decal polygons; bigger values z-fight less but poke through walls more"}, - {"r_portalBevels", "Helps cull geometry by angles of portals that are acute when projected onto the screen, value is the cosine of the angle"}, - {"r_portalBevelsOnly", "Use screen-space bounding box of portals rather than the actual shape of the portal projected onto the screen"}, - {"r_portalMinClipArea", "Don't clip child portals by a parent portal smaller than this fraction of the screen area."}, - {"r_portalMinRecurseDepth", "Ignore r_portalMinClipArea for portals with fewer than this many parent portals."}, - {"r_portalWalkLimit", "Stop portal recursion after this many iterations. Useful for debugging portal errors."}, - {"r_postAA", "Post process antialiasing mode"}, - {"r_postfx_enable", "Enable post-processing effects such as color correction, bloom, depth-of-field, etc."}, - {"r_preloadShaders", "Force D3D to draw dummy geometry with all shaders during level load; may fix long pauses at level start."}, - {"r_primaryLightTweakDiffuseStrength", "Tweak the diffuse intensity for primary lights"}, - {"r_primaryLightTweakSpecularStrength", "Tweak the specular intensity for primary lights"}, - {"r_primaryLightUseTweaks", ""}, - {"r_reactiveMotionActorRadius", "Radial distance from the ai characters that influences reactive motion models (inches)"}, - {"r_reactiveMotionActorVelocityMax", "AI velocity considered the maximum when determining the length of motion tails (inches/sec)"}, - {"r_reactiveMotionActorZOffset", "Distance from the actor origin along Z direction where the actor's reactive motion effector sphere is centered at."}, - {"r_reactiveMotionEffectorStrengthScale", "Additional scale for the effector influence, as a factor of the model part distance from the effector center and model part extents"}, - {"r_reactiveMotionHelicopterLimit", "Maximum number of helicopter entities that actively influence reactive motion. Can increase CPU cost of the scene."}, - {"r_reactiveMotionHelicopterRadius", "Radial distance from the helicopter that influences reactive motion models (inches)"}, - {"r_reactiveMotionHelicopterStrength", "Scales the influence of helicopter wind tunnel motion"}, - {"r_reactiveMotionPlayerHeightAdjust", "Amount to adjust the vertical distance of the effector from the player position (inches)"}, - {"r_reactiveMotionPlayerRadius", "Radial distance from the player that influences reactive motion models (inches)"}, - {"r_reactiveMotionPlayerZOffset", "Distance from the player origin along Z direction where the player's reactive motion effector sphere is centered at."}, - {"r_reactiveMotionVelocityTailScale", "Additional scale for the velocity-based motion tails, as a factor of the effector radius"}, - {"r_reactiveMotionWindAmplitudeScale", "Scales amplitude of wind wave motion"}, - {"r_reactiveMotionWindAreaScale", "Scales distribution of wind motion"}, - {"r_reactiveMotionWindDir", "Controls the global wind direction"}, - {"r_reactiveMotionWindFrequencyScale", "Scales frequency of wind wave motion"}, - {"r_reactiveMotionWindStrength", "Scale of the global wind direction (inches/sec)"}, - {"r_reflectionProbeMap", "Replace all reflection probes with pure black"}, - {"r_reflectionProbeNmlLuminance", "Enable/disable shader code for computing luminance during reflection probe denormalization. This is just an experiment.\n"}, - {"r_rimLight0Color", ""}, - {"r_rimLight0Heading", "Rim Light 0 heading in degrees"}, - {"r_rimLight0Pitch", "Rim Light 0 pitch in degrees -90 is noon."}, - {"r_rimLightBias", "How much to bias the n.l calculation"}, - {"r_rimLightDiffuseIntensity", "Strength of the diffuse component of the rim light."}, - {"r_rimLightFalloffMaxDistance", "Distance at which the rim light hits intensity of 100%."}, - {"r_rimLightFalloffMinDistance", "Distance at which the rim light hits intensity of 100%."}, - {"r_rimLightFalloffMinIntensity", "Intensity of the effect at and before minDistance."}, - {"r_rimLightPower", "Power to raise the n.l calculation"}, - {"r_rimLightSpecIntensity", "Strength of the spec ( additive) component of the rim light"}, - {"r_rimLightUseTweaks", "Turn on rim lighting tweaks"}, - {"r_scaleViewport", "Scale 3D viewports by this fraction. Use this to see if framerate is pixel shader bound."}, - {"r_sceneMipShowOverlay", "Toggles scene mip rendertarget overlay"}, - {"r_showLightGrid", "Show light grid debugging information (2: detailed, 3: detailed for this box only)"}, - {"r_showLightGridAvgProbes", "show an array of boxes which are using the light grid average color at its location"}, - {"r_showLightGridDetailInfo", "Show more details for light grid debugging."}, - {"r_showLightProbes", "Show the light probes at the light grid sample locations in world space centered around the camera."}, - {"r_showMissingLightGrid", "Use rainbow colors for entities that are outside the light grid"}, - {"r_showModelLightingLowWaterMark", ""}, - {"r_showPortals", "Show portals for debugging"}, - {"r_showPortalsOverview", "Render 2d XY portal overlay scaled to fit to this distance. Useful for debugging portal errors."}, - {"r_showReflectionProbeSelection", "Show reflection probe selection"}, - {"r_singleCell", "Only draw things in the same cell as the camera. Most useful for seeing how big the current cell is."}, - {"r_skipPvs", "Skipt the determination of what is in the potentially visible set (disables most drawing)"}, - {"r_sky_fog_intensity", "Amount of sky fog fading"}, - {"r_sky_fog_max_angle", "End of angular sky fog fading"}, - {"r_sky_fog_min_angle", "Start of angular sky fog fading"}, - {"r_skyFogUseTweaks", "Enable dvar control of sky fog"}, - {"r_smaaThreshold", "SMAA edge detection threshold"}, - {"r_smodelInstancedRenderer", "Render static models with instanced renderer"}, - {"r_smodelInstancedThreshold", "Minimum number of static model instances before instanced rendering is used"}, - {"r_smp_backend", "Process renderer back end in a separate thread"}, - {"r_smp_worker", "Process renderer front end in a separate thread"}, - {"r_smp_worker_thread0", ""}, - {"r_smp_worker_thread1", ""}, - {"r_smp_worker_thread2", ""}, - {"r_smp_worker_thread3", "undefined"}, - {"r_smp_worker_thread4", "undefined"}, - {"r_smp_worker_thread5", "undefined"}, - {"r_smp_worker_thread6", "undefined"}, - {"r_smp_worker_thread7", "undefined"}, - {"r_specOccMap", "Replace all specular occlusion maps with pure black (fully occluded) or pure white (not occluded)"}, - {"r_specularColorScale", "Set greater than 1 to brighten specular highlights"}, - {"r_specularMap", "Replace all specular maps with pure black (off) or pure white (super shiny)"}, - {"r_spotLightEntityShadows", "Enable entity shadows for spot lights."}, - {"r_spotLightShadows", "Enable shadows for spot lights."}, - {"r_ssao", "Screen Space Ambient Occlusion mode"}, - {"r_ssaoDebug", "Render calculated or blurred Screen Space Ambient Occlusion values"}, - {"r_ssaoDebugMip", "Selects which mip level to render when r_ssaoDebug is enabled. If 0 and r_ssaoDownsample is enabled, will render mip 1."}, - {"r_ssaoDepthScale", "Scale applied to depth values used for occlusion tests."}, - {"r_ssaoDepthScaleViewModel", "Scale applied to depth values used for occlusion tests."}, - {"r_ssaoDownsample", "Screen Space Ambient Occlusion calculation occurs at half linear resolution"}, - {"r_ssaoFadeDepth", "Depth at which the SSAO begins to fade out. It fades at even increments of this distance (e.g. it's at 1 for depth r_ssaoFadeDepth, 1/2 for depth 2*r_ssaoFadeDepth, etc.)"}, - {"r_ssaoGapFalloff", "Falloff used to blend between creases (that should darken) and silhouettes (that should not darken). Lower values falloff more quickly."}, - {"r_ssaoGradientFalloff", "Falloff used to fade out the effect for steep depth gradients (i.e. surfaces nearly parallel to the camera direction). This fixes sampling artifacts that appear for surfaces nearly parallel to the camera direction (commonly occuring for flat ground planes)."}, - {"r_ssaoMaxStrengthDepth", "Depth at which SSAO strength is at its maximum"}, - {"r_ssaoMethod", "Screen Space Ambient Occlusion method (original or IW6, both are volumetric obscurance)"}, - {"r_ssaoMinPixelWidth", "Minimum pixel width of the effect. When the effect is smaller than this, it is culled entirely."}, - {"r_ssaoMinStrengthDepth", "Depth at which SSAO strength is zero, effectively disabled"}, - {"r_ssaoMultiRes", "Screen Space Ambient Occlusion calculation occurs at half linear resolution"}, - {"r_ssaoPower", "Power curve applied to SSAO factor"}, - {"r_ssaoRejectDepth", "Depth at which the SSAO is disabled. Smaller values result in more rejected pixels which is faster, but limits the distance at which the effect is visible."}, - {"r_ssaoSampleCount", "Selects the number of samples used for SSAO"}, - {"r_ssaoScriptScale", "Allows script to lerp to disable or enable the SSAO. This applies a scalar value to the SSAO strength. When set to 0, this effectively disables SSAO."}, - {"r_ssaoStrength", "Strength of Screen Space Ambient Occlusion effect"}, - {"r_ssaoUseTweaks", "Use r_ssao* dvars instead of the current light set values for SSAO"}, - {"r_ssaoWidth", "The width of the SSAO effect, in pixels at 720p. Larger values increase area but lower effective quality."}, - {"r_sse_skinning", "Use Streaming SIMD Extensions for skinning"}, - {"r_ssrBlendScale", "Add extra scale to ssr weight versus reflection probe weight, >1 value will make ssr more obvious."}, - {"r_ssrFadeInDuration", "Duration of the screen-space reflection fade-in, which occurs whenever the reflection source buffer is invalidated due to view changes (in particular, dual-view scope transitions)."}, - {"r_ssrPositionCorrection", "Screen space reflection position correction blend factor"}, - {"r_ssrRoughnessMipParameters", "X: mirror mip; Y: roughest mip; Z: roughness middle point, may need different value for different screen resolution on PC."}, - {"r_sssBlendWeight", "Controls the blend between the wide (zero) and narrow (one) gaussians"}, - {"r_sssDebugMaterial", "Debug Feature: toggle materials with SSS"}, - {"r_sssEnable", "Enables the subsurface scattering effect (note that disabling SSS will not prevent the filter from running)"}, - {"r_sssGlobalRadius", "Controls the global radius (in inches)"}, - {"r_sssJitterRadius", "Percentage of the kernel to be jittered"}, - {"r_sssNarrowRadius", "Controls the narrow Gaussian radius"}, - {"r_sssPreset", "Changes subsurface scattering quality"}, - {"r_sssWideRadius", "Controls the wide Gaussian radius"}, - {"r_subdiv", "Enables Catmull Clark surface subdivision."}, - {"r_subdivLimit", "Set the maximum Catmull Clark subdivision level."}, - {"r_subdivPatchCount", "Patches per thread group for sub-division surfaces."}, - {"r_subdomainLimit", "Maximum number of extra tessellation subdivisions using instancing (max tess amts are 0:64, 1:128, 2:192, 3:256, max instances used are 0:1, 1:4, 2:9, 3:12)"}, - {"r_subdomainScale", "Debug only: Scales the extra subdivision amount (for values < 1, not all instanced sub triangles will draw)."}, - {"r_subwindow", "subwindow to draw: left, right, top, bottom"}, - {"r_sun_from_dvars", "Set sun flare values from dvars rather than the level"}, - {"r_sun_fx_position", "Position in degrees of the sun effect"}, - {"r_sunblind_fadein", "time in seconds to fade blind from 0% to 100%"}, - {"r_sunblind_fadeout", "time in seconds to fade blind from 100% to 0%"}, - {"r_sunblind_max_angle", "angle from sun in degrees inside which effect is max"}, - {"r_sunblind_max_darken", "0-1 fraction for how black the world is at max blind"}, - {"r_sunblind_min_angle", "angle from sun in degrees outside which effect is 0"}, - {"r_sunflare_fadein", "time in seconds to fade alpha from 0% to 100%"}, - {"r_sunflare_fadeout", "time in seconds to fade alpha from 100% to 0%"}, - {"r_sunflare_max_alpha", "0-1 vertex color and alpha of sun at max effect"}, - {"r_sunflare_max_angle", "angle from sun in degrees inside which effect is max"}, - {"r_sunflare_max_size", "largest size of flare effect in pixels at 640x480"}, - {"r_sunflare_min_angle", "angle from sun in degrees outside which effect is 0"}, - {"r_sunflare_min_size", "smallest size of flare effect in pixels at 640x480"}, - {"r_sunflare_shader", "name for flare effect; can be any material"}, - {"r_sunglare_fadein", "time in seconds to fade glare from 0% to 100%"}, - {"r_sunglare_fadeout", "time in seconds to fade glare from 100% to 0%"}, - {"r_sunglare_max_angle", "angle from sun in degrees inside which effect is max"}, - {"r_sunglare_max_lighten", "0-1 fraction for how white the world is at max glare"}, - {"r_sunglare_min_angle", "angle from sun in degrees inside which effect is max"}, - {"r_sunInfDist", "Sun infinite distance used to place sun fx"}, - {"r_sunshadowmap_cmdbuf_worker", "Process shadowmap command buffer in a separate thread"}, - {"r_sunsprite_shader", "name for static sprite; can be any material"}, - {"r_sunsprite_size", "diameter in pixels at 640x480 and 80 fov"}, - {"r_surfaceHDRScalarUseTweaks", "Enables lit and unlit surface scalar tweaks"}, - {"r_tessellation", "Enables tessellation of world geometry, with an optional cutoff distance."}, - {"r_tessellationCutoffDistance", "Distance at which world geometry ceases to tessellate."}, - {"r_tessellationCutoffFalloff", "Range over which tessellation is faded out, up to the cutoff."}, - {"r_tessellationEyeScale", "Scale applied due to eye * object normal for less tessellation on facing polygons."}, - {"r_tessellationFactor", "Target edge length, based on dividing full window height by this factor, for dynamic tessellation. Use zero to disable tessellation."}, - {"r_tessellationHeightAuto", "Correctly auto scale displacement heights for layers to grow as texture is stretched over larger surface areas to preserve feature proportions."}, - {"r_tessellationHeightScale", "Displacement height scale factor."}, - {"r_tessellationHybrid", "Hybrid per pixel displacement scale."}, - {"r_tessellationLodBias", "Displacement map lod bias."}, - {"r_texFilterAnisoMax", "Maximum anisotropy to use for texture filtering"}, - {"r_texFilterAnisoMin", "Minimum anisotropy to use for texture filtering (overridden by max)"}, - {"r_texFilterDisable", "Disables all texture filtering (uses nearest only.)"}, - {"r_texFilterMipBias", "Change the mipmap bias"}, - {"r_texFilterMipMode", "Forces all mipmaps to use a particular blend between levels (or disables mipping.)"}, - {"r_texFilterProbeBilinear", "Force reflection probe to use bilinear filter"}, - {"r_texShowMipMode", "Forces textures with the specified mip filtering to draw black."}, - {"r_thermalColorOffset", "Offset of the thermal colors (offset + scale*color)"}, - {"r_thermalColorScale", "Scale of the thermal colors (offset + scale*color)"}, - {"r_thermalDetailScale", "Scale of the detail that is added to the thermal map from the normal map (multiplies the detail amount from AssetManager)"}, - {"r_thermalFadeColor", "Color the thermal fades to at distance."}, - {"r_thermalFadeControl", "Select thermal fade mode"}, - {"r_thermalFadeMax", "Distance at which thermal stops fading"}, - {"r_thermalFadeMin", "Distance at which thermal starts fading"}, - {"r_tonemap", "HDR Tonemapping mode"}, - {"r_tonemapAdaptSpeed", "HDR Tonemap exposure adaptation speed"}, - {"r_tonemapAuto", "HDR Tonemapping performs auto-exposure"}, - {"r_tonemapAutoExposureAdjust", "HDR Tonemap Auto Exposure Adjust value (set to 0.0 for automatic adjustment)"}, - {"r_tonemapBlack", "HDR Filmic Tonemap black point"}, - {"r_tonemapBlend", "HDR Tonemapping blends between exposures"}, - {"r_tonemapCrossover", "HDR Filmic Tonemap crossover point"}, - {"r_tonemapDarkEv", "HDR Tonemap Dark EV"}, - {"r_tonemapDarkExposureAdjust", "HDR Tonemap Dark Exposure Adjust"}, - {"r_tonemapExposure", "HDR Tonemap exposure (in EV) override (only works in non-auto mode)"}, - {"r_tonemapExposureAdjust", "HDR Tonemap exposure adjustment (in EV, 0 is no adjustment, works like a camera where +1 reduces EV by 1)"}, - {"r_tonemapGamma", "HDR Tonemap gamma curve power"}, - {"r_tonemapHighlightRange", "HDR Tonemap dynamic range, which determines white point luminance"}, - {"r_tonemapLightEv", "HDR Tonemap Light EV"}, - {"r_tonemapLightExposureAdjust", "HDR Tonemap Light Exposure Adjust"}, - {"r_tonemapLockAutoExposureAdjust", "HDR Tonemapping lock auto exposure adjust"}, - {"r_tonemapMaxExposure", "HDR Tonemap maximum exposure (in EV)"}, - {"r_tonemapMaxExposureAdjust", "HDR Tonemap Max Exposure Adjust"}, - {"r_tonemapMidEv", "HDR Tonemap Mid EV"}, - {"r_tonemapMidExposureAdjust", "HDR Tonemap Mid Exposure Adjust"}, - {"r_tonemapMinExposureAdjust", "HDR Tonemap Min Exposure Adjust"}, - {"r_tonemapShoulder", "HDR Filmic Tonemap shoulder control (0 is linear)"}, - {"r_tonemapToe", "HDR Filmic Tonemap toe control (0 is linear)"}, - {"r_tonemapUseCS", "HDR Tonemapping uses compute shader."}, - {"r_tonemapUseTweaks", "Override tone map LightSet settings with tweak dvar values."}, - {"r_tonemapWhite", "HDR Filmic Tonemap white point"}, - {"r_ui3d_debug_display", "Show UI3D debug overlay"}, - {"r_ui3d_h", "ui3d texture window height"}, - {"r_ui3d_use_debug_values", "Use UI debug values"}, - {"r_ui3d_w", "ui3d texture window width"}, - {"r_ui3d_x", "ui3d texture window x"}, - {"r_ui3d_y", "ui3d texture window y"}, - {"r_uiBlurDstMode", "UI blur distortion mode. Fast uses the scene mip map render target, PostSun uses a downsampled post sun resolve buffer, PostSun HQ uses a gaussian blurred post sun resolve buffer."}, - {"r_umbra", "Enables Umbra-based portal culling."}, - {"r_umbraAccurateOcclusionThreshold", "The distance (in inches) to which accurate occlusion information is gathered. -1.0 = deduced automatically."}, - {"r_umbraExclusive", "Toggle Umbra for exclusive static culling (disables static portal dpvs)"}, - {"r_umbraQueryParts", "The number of parts the Umbra query frustum is broken into for async query processing as an M x N grid (0, 0 = all queries are synchronous)."}, - {"r_umbraUseBadPlaces", "Enable/disable ability to disable umbra when inside special volumes defined in mp/umbraBadPlaces.csv."}, - {"r_umbraUseDpvsCullDist", "Use cull distance from the DPVS instead of the far plane distance."}, - {"r_unlitSurfaceHDRScalar", "Vision set based scalar applied to unlit surfaces to balance those surfaces with the luminance of the scene"}, - {"r_useComputeSkinning", "Enables compute shader (GPU) skinning."}, - {"r_useLayeredMaterials", "Set to true to use layered materials on shader model 3 hardware"}, - {"r_useLightGridDefaultFXLightingLookup", "Enable/disable default fx lighting lookup\n"}, - {"r_useLightGridDefaultModelLightingLookup", "Enable/disable default model lighting lookup\n"}, - {"r_useShadowGeomOpt", "Enable iwRad shadow geometry optimization. It only works when we have the data generated in iwRad."}, - {"r_useSunShadowPortals", "Enable sun shadow portals when dir light change and not using cached shadow."}, - {"r_useXAnimIK", "Enables IK animation."}, - {"r_vc_makelog", "Enable logging of light grid points for the vis cache. 1 starts from scratch, 2 appends."}, - {"r_vc_showlog", "Show this many rows of light grid points for the vis cache"}, - {"r_veil", "Apply veiling luminance (HDR glow)"}, - {"r_veilAntialiasing", "Veil antialiasing mode (downsample technique used for first mip)."}, - {"r_veilBackgroundStrength", "Strength of background when applying veiling luminance (HDR glow)"}, - {"r_veilFalloffScale1", "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)"}, - {"r_veilFalloffScale2", "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)"}, - {"r_veilFalloffWeight1", "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)"}, - {"r_veilFalloffWeight2", "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)"}, - {"r_veilFilter", "Changes the veil filtering mode"}, - {"r_veilPreset", "Changes veil sampling quality"}, - {"r_veilRadius", "Controls the radius of the first Gaussian in virtual pixels (remaining Gaussians follow proportionally)."}, - {"r_veilStrength", "Strength of veiling luminance (HDR glow)"}, - {"r_veilUseTweaks", "Override veil LightSet settings with tweak dvar values."}, - {"r_velocityPrepass", "Perform velocity rendering during the depth prepass"}, - {"r_viewModelLightAmbient", ""}, - {"r_viewModelPrimaryLightTweakDiffuseStrength", "Tweak the diffuse intensity for view model primary lights"}, - {"r_viewModelPrimaryLightTweakSpecularStrength", "Tweak the specular intensity for view model primary lights"}, - {"r_viewModelPrimaryLightUseTweaks", ""}, - {"r_volumeLightScatter", "Enables volumetric light scattering"}, - {"r_volumeLightScatterAngularAtten", "Distance of sun from center of screen before angular attenuation starts for god rays"}, - {"r_volumeLightScatterBackgroundDistance", "Distance at which pixels are considered background for volume light scatter effect"}, - {"r_volumeLightScatterColor", ""}, - {"r_volumeLightScatterDepthAttenFar", "Pixels >= than this depth recieve full volume light scatter."}, - {"r_volumeLightScatterDepthAttenNear", "Pixels <= than this depth recieve no volume light scatter."}, - {"r_volumeLightScatterEv", "Light intensity (in EV) for volumetric light scattering"}, - {"r_volumeLightScatterLinearAtten", "Coefficient of linear attenuation of god rays"}, - {"r_volumeLightScatterQuadraticAtten", "Coefficient of quadratic attenuation of god rays)"}, - {"r_volumeLightScatterUseTweaks", "Enables volumetric light scattering tweaks"}, - {"r_vsync", "Enable v-sync before drawing the next frame to avoid 'tearing' artifacts."}, - {"r_warningRepeatDelay", "Number of seconds after displaying a \"per-frame\" warning before it will display again"}, - {"r_wideTessFactorsThreshold", "If a surface has more than this many triangles, process triangles in parallel instead of surfaces."}, - {"r_zfar", "Change the distance at which culling fog reaches 100% opacity; 0 is off"}, - {"r_znear", "Things closer than this aren't drawn. Reducing this increases z-fighting in the distance."}, - {"radarjamDistMax", ""}, - {"radarjamDistMin", ""}, - {"radarjamSinCurve", ""}, - {"radius_damage_debug", "Turn on debug lines for radius damage traces"}, - {"ragdoll_baselerp_time", "Default time ragdoll baselerp bones take to reach the base pose"}, - {"ragdoll_bullet_force", "Bullet force applied to ragdolls"}, - {"ragdoll_bullet_upbias", "Upward bias applied to ragdoll bullet effects"}, - {"ragdoll_dump_anims", "Dump animation data when ragdoll fails"}, - {"ragdoll_enable", "Turn on ragdoll death animations"}, - {"ragdoll_explode_force", "Explosive force applied to ragdolls"}, - {"ragdoll_explode_upbias", "Upwards bias applied to ragdoll explosion effects"}, - {"ragdoll_exploding_bullet_force", "Force applied to ragdolls from explosive bullets"}, - {"ragdoll_exploding_bullet_upbias", "Upwards bias applied to ragdoll from explosive bullets"}, - {"ragdoll_idle_min_velsq", "Minimum squared speed a ragdoll body needs to be moving before it will shut down due to time"}, - {"ragdoll_jitter_scale", "Scale up or down the effect of physics jitter on ragdolls"}, - {"ragdoll_jointlerp_time", "Default time taken to lerp down ragdoll joint friction"}, - {"ragdoll_link_to_moving_platform", "Enable client-side linking of ragdolls to script brush models when they go idle."}, - {"ragdoll_max_life", "Max lifetime of a ragdoll system in msec"}, - {"ragdoll_max_simulating", "Max number of simultaneous active ragdolls - archived"}, - {"ragdoll_max_stretch_pct", "Force ragdoll limbs to not stretch more than this percentage in one frame"}, - {"ragdoll_mp_limit", "Max number of simultaneous active ragdolls - archived"}, - {"ragdoll_mp_resume_share_after_killcam", "Msec after returning from killcam that splitscreen players will share ragdolls again."}, - {"ragdoll_resolve_penetration_bias", "Bias value on force to push ragdolls out of environment."}, - {"ragdoll_rotvel_scale", "Ragdoll rotational velocity estimate scale"}, - {"ragdoll_self_collision_scale", "Scale the size of the collision capsules used to prevent ragdoll limbs from interpenetrating"}, - {"ragdoll_stretch_iters", "Iterations to run the alternate limb solver"}, - {"rankedPlayEndMatchKeepLobby", "keep the lobby if the lobby host is in our private party."}, - {"rankedPlaylistLockoutDuration", "Time in seconds to lock the ranked play playlist if a player quit the match early."}, - {"rate", "Player's preferred network rate"}, - {"RemoteCameraSounds_DryLevel", ""}, - {"RemoteCameraSounds_RoomType", ""}, - {"RemoteCameraSounds_WetLevel", ""}, - {"requireOpenNat", ""}, - {"restrictMapPacksToGroups", "Restrict map pack usage to needing all maps in an ala carte package in order to use as search criteria"}, - {"riotshield_bullet_damage_scale", "Value to scale bullet damage to deployed riotshield."}, - {"riotshield_deploy_limit_radius", "Min distance deployed riotshields must be from each other."}, - {"riotshield_deploy_trace_parallel", "Report collisions when riotshield traces are parallel to plane of triangle. If disabled traces parallel to triangle planes do not report collisions at all."}, - {"riotshield_deployed_health", "Deployed riotshield health."}, - {"riotshield_destroyed_cleanup_time", "Time (in seconds) destroyed riotshield model persists before disappearing"}, - {"riotshield_explosive_damage_scale", "Value to scale explosive damage to deployed riotshield.."}, - {"riotshield_melee_damage_scale", "Value to scale melee damage to deployed riotshield."}, - {"riotshield_projectile_damage_scale", "Value to scale projectile damage to deployed riotshield."}, - {"s_aggregate_ping_offset", "offset to apply to aggregate ping values"}, - {"s_aggregate_ping_scale", "8-bit fixed-point aggregate ping scaler value"}, - {"s_avg_max_weighting", "weighting from 0-256 of party average ping vs. worst ping"}, - {"s_ds_pingclient_reping_wait_db", "wait this# of frames for the db thread to settle down before repinging"}, - {"s_use_aggregate_datacenter_pings", "use newer system for aggregating party pings"}, - {"safeArea_adjusted_horizontal", "User-adjustable horizontal safe area as a fraction of the screen width"}, - {"safeArea_adjusted_vertical", "User-adjustable vertical safe area as a fraction of the screen height"}, - {"safeArea_horizontal", "Horizontal safe area as a fraction of the screen width"}, - {"safeArea_vertical", "Vertical safe area as a fraction of the screen height"}, - {"scr_conf_numlives", ""}, - {"scr_conf_playerrespawndelay", ""}, - {"scr_conf_roundlimit", ""}, - {"scr_conf_scorelimit", ""}, - {"scr_conf_timelimit", ""}, - {"scr_conf_waverespawndelay", ""}, - {"scr_conf_winlimit", ""}, - {"scr_default_maxagents", ""}, - {"scr_diehard", ""}, - {"scr_disableClientSpawnTraces", ""}, - {"scr_dm_numlives", ""}, - {"scr_dm_playerrespawndelay", ""}, - {"scr_dm_roundlimit", ""}, - {"scr_dm_scorelimit", ""}, - {"scr_dm_timelimit", ""}, - {"scr_dm_waverespawndelay", ""}, - {"scr_dm_winlimit", ""}, - {"scr_dom_numlives", ""}, - {"scr_dom_playerrespawndelay", ""}, - {"scr_dom_roundlimit", ""}, - {"scr_dom_scorelimit", ""}, - {"scr_dom_timelimit", ""}, - {"scr_dom_waverespawndelay", ""}, - {"scr_dom_winlimit", ""}, - {"scr_explBulletMod", ""}, - {"scr_game_allowkillcam", "script allow killcam"}, - {"scr_game_deathpointloss", ""}, - {"scr_game_forceuav", ""}, - {"scr_game_graceperiod", ""}, - {"scr_game_hardpoints", ""}, - {"scr_game_killstreakdelay", ""}, - {"scr_game_lockspectatorpov", "Lock spectator mode globally, 0=freelook/unlocked, 1=first_person, 2=third_person"}, - {"scr_game_onlyheadshots", ""}, - {"scr_game_perks", ""}, - {"scr_game_spectatetype", ""}, - {"scr_game_suicidepointloss", ""}, - {"scr_gameended", ""}, - {"scr_hardcore", ""}, - {"scr_horde_difficulty", ""}, - {"scr_horde_maxagents", ""}, - {"scr_horde_numlives", ""}, - {"scr_horde_playerrespawndelay", ""}, - {"scr_horde_roundlimit", ""}, - {"scr_horde_scorelimit", ""}, - {"scr_horde_timelimit", ""}, - {"scr_horde_waverespawndelay", ""}, - {"scr_horde_winlimit", ""}, - {"scr_infect_numlives", ""}, - {"scr_infect_playerrespawndelay", ""}, - {"scr_infect_roundlimit", ""}, - {"scr_infect_timelimit", ""}, - {"scr_infect_waverespawndelay", ""}, - {"scr_infect_winlimit", ""}, - {"scr_isgamescom", "script use gamescom demo flow"}, - {"scr_maxPerPlayerExplosives", ""}, - {"scr_nukeCancelMode", ""}, - {"scr_nukeTimer", ""}, - {"scr_patientZero", ""}, - {"scr_player_forcerespawn", ""}, - {"scr_player_healthregentime", ""}, - {"scr_player_maxhealth", ""}, - {"scr_player_numlives", ""}, - {"scr_player_respawndelay", ""}, - {"scr_player_sprinttime", ""}, - {"scr_player_suicidespawndelay", ""}, - {"scr_RequiredMapAspectratio", ""}, - {"scr_riotShieldXPBullets", ""}, - {"scr_sd_bombtimer", ""}, - {"scr_sd_defusetime", ""}, - {"scr_sd_multibomb", ""}, - {"scr_sd_numlives", ""}, - {"scr_sd_planttime", ""}, - {"scr_sd_playerrespawndelay", ""}, - {"scr_sd_roundlimit", ""}, - {"scr_sd_roundswitch", ""}, - {"scr_sd_scorelimit", ""}, - {"scr_sd_timelimit", ""}, - {"scr_sd_waverespawndelay", ""}, - {"scr_sd_winlimit", ""}, - {"scr_sr_bombtimer", ""}, - {"scr_sr_defusetime", ""}, - {"scr_sr_multibomb", ""}, - {"scr_sr_numlives", ""}, - {"scr_sr_planttime", ""}, - {"scr_sr_playerrespawndelay", ""}, - {"scr_sr_roundlimit", ""}, - {"scr_sr_roundswitch", ""}, - {"scr_sr_scorelimit", ""}, - {"scr_sr_timelimit", ""}, - {"scr_sr_waverespawndelay", ""}, - {"scr_sr_winlimit", ""}, - {"scr_team_fftype", "script team friendly fire type"}, - {"scr_team_respawntime", ""}, - {"scr_team_teamkillpointloss", ""}, - {"scr_team_teamkillspawndelay", ""}, - {"scr_thirdPerson", ""}, - {"scr_tispawndelay", ""}, - {"scr_war_halftime", ""}, - {"scr_war_numlives", ""}, - {"scr_war_playerrespawndelay", ""}, - {"scr_war_roundlimit", ""}, - {"scr_war_roundswitch", ""}, - {"scr_war_scorelimit", ""}, - {"scr_war_timelimit", ""}, - {"scr_war_waverespawndelay", ""}, - {"scr_war_winlimit", ""}, - {"scr_xpscale", ""}, - {"screenshots_active", "Are we allowed to enable Screenshots or not"}, - {"search_weight_asn", "The weight used for the asn in weighted matchmaking."}, - {"search_weight_country_code", "The weight used for the country code in weighted matchmaking."}, - {"search_weight_lat_long", "The weight used for the lat long in weighted matchmaking."}, - {"sensitivity", "Mouse sensitivity"}, - {"sentry_placement_feet_offset", "Position of the feet from the center axis."}, - {"sentry_placement_feet_trace_dist_z", "Max distance for a foot to be considered touching the ground"}, - {"sentry_placement_trace_dist", "Distance along the trace axis where the sentry will attempt to position itself"}, - {"sentry_placement_trace_min_normal", "Minimum normal to accept a sentry position"}, - {"sentry_placement_trace_parallel", "Enable turret traces that are parallel to plane of triangle. If 0, traces parallel to triangle planes do not report collisions at all. If 2 (debug-only), then trace code ping pongs between new and old."}, - {"sentry_placement_trace_pitch", "Pitch used for the trace axis"}, - {"sentry_placement_trace_radius", "Radius of the bound used for the placement trace"}, - {"sentry_placement_trace_radius_canon_safety", "Extra radius used in the forward direction to compensate for the canon length"}, - {"server1", ""}, - {"server10", ""}, - {"server11", ""}, - {"server12", ""}, - {"server13", ""}, - {"server14", ""}, - {"server15", ""}, - {"server16", ""}, - {"server2", ""}, - {"server3", ""}, - {"server4", ""}, - {"server5", ""}, - {"server6", ""}, - {"server7", ""}, - {"server8", ""}, - {"server9", ""}, - {"session_immediateDeleteTinySessions", "Whether to immediately delete sessions with 1 user"}, - {"session_modify_retry_on_failure", "Enable session modify retry on failures."}, - {"session_nonblocking", "Non-blocking Session code"}, - {"shortversion", "Short game version"}, - {"showDebugAmmoCounter", "Show the debug ammo counter when unable to show ar ammo counter"}, - {"showPlaylistTotalPlayers", "Toggle the display of the total number of players in a playlist and online"}, - {"sm_cacheSpotShadows", "Cache spot shadow maps, improves shadow map performance at the cost of memory (requires vid_restart)"}, - {"sm_cacheSpotShadowsEnabled", "Enables caching of spot shadows."}, - {"sm_cacheSunShadow", "Cache sun shadow map, improves shadow map performance at the cost of memory (requires vid_restart)"}, - {"sm_cacheSunShadowEnabled", "Enables caching of sun-based shadows."}, - {"sm_cameraOffset", ""}, - {"sm_dynlightAllSModels", "Enable, from script, rendering all static models in dynamic light volume when shadow mapping"}, - {"sm_enable", "Enable shadow mapping"}, - {"sm_fastSunShadow", "Fast sun shadow"}, - {"sm_lightScore_eyeProjectDist", "When picking shadows for primary lights, measure distance from a point this far in front of the camera."}, - {"sm_lightScore_spotProjectFrac", "When picking shadows for primary lights, measure distance from a point this far in front of the camera."}, - {"sm_maxLightsWithShadows", "Limits how many primary lights can have shadow maps"}, - {"sm_minSpotLightScore", "Minimum score (based on intensity, radius, and position relative to the camera) for a spot light to have shadow maps."}, - {"sm_polygonOffsetBias", "Shadow map offset bias"}, - {"sm_polygonOffsetClamp", "Shadow map offset clamp"}, - {"sm_polygonOffsetPreset", "Shadow map polygon offset preset."}, - {"sm_polygonOffsetScale", "Shadow map offset scale"}, - {"sm_qualitySpotShadow", "Fast spot shadow"}, - {"sm_shadowUseTweaks", "Override shadow LightSet settings with tweak dvar values."}, - {"sm_spotDistCull", "Distance cull spot shadows"}, - {"sm_spotEnable", "Enable spot shadow mapping from script"}, - {"sm_spotFilterRadius", "Spot soft shadows filter radius"}, - {"sm_spotLightScoreModelScale", "Scale the calculated spot light score by this value if the light currently only affects static or script brush models."}, - {"sm_spotLightScoreRadiusPower", "Power to apply to light radius when determining spot light shadowing score (1.0 means radius scales up score a lot, 0.0 means don't scale score using radius)"}, - {"sm_spotLimit", "Limit number of spot shadows from script"}, - {"sm_spotShadowFadeTime", "How many seconds it takes for a primary light shadow map to fade in or out"}, - {"sm_strictCull", "Strict shadow map cull"}, - {"sm_sunEnable", "Enable sun shadow mapping from script"}, - {"sm_sunFilterRadius", "Sun soft shadows filter radius"}, - {"sm_sunSampleSizeNear", "Shadow sample size"}, - {"sm_sunShadowBoundsMax", "Max Shadow Bounds"}, - {"sm_sunShadowBoundsMin", "Min Shadow Bounds"}, - {"sm_sunShadowBoundsOverride", "Override Shadow Bounds"}, - {"sm_sunShadowCenter", "Sun shadow center, 0 0 0 means don't override"}, - {"sm_sunShadowCenterMode", "When false center value only used for far map, when true sets both maps"}, - {"sm_sunShadowScale", "Sun shadow scale optimization"}, - {"sm_sunShadowScaleLocked", "Lock usage of sm_sunShadowScale at 1"}, - {"sm_usedSunCascadeCount", "How many shadow cascade we are using"}, - {"snd_allowHeadphoneHRTF", "Enable HRTF over headphones"}, - {"snd_announcerDisabled", "Disable all in-game announcers"}, - {"snd_announcerVoicePrefix", "Local mp announcer voice to use"}, - {"snd_battlechatterDisabled", "Disable all in-game battle chatter"}, - {"snd_cinematicVolumeScale", "Scales the volume of Bink videos."}, - {"snd_detectedSpeakerConfig", "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround"}, - {"snd_dopplerAuditionEnable", "Enables doppler calculation preview mode"}, - {"snd_dopplerBaseSpeedOfSound", "The base speed of sound used in doppler calculation"}, - {"snd_dopplerEnable", "Enables doppler calculation"}, - {"snd_dopplerPitchMax", "Maximum pitch that can be legally applied by doppler"}, - {"snd_dopplerPitchMin", "Minimum pitch that can be legally applied by doppler"}, - {"snd_dopplerPlayerVelocityScale", "The scale of the player velocity, relative the the sound source velocity, when applied to the doppler calculation"}, - {"snd_dopplerSmoothing", "Smoothing factor applied to doppler to eliminate jitter or sudden acceleration changes"}, - {"snd_draw3D", "Draw the position and info of world sounds"}, - {"snd_drawInfo", "Draw debugging information for sounds"}, - {"snd_enable2D", "Enable 2D sounds"}, - {"snd_enable3D", "Enable 3D sounds"}, - {"snd_enableEq", "Enable equalization filter"}, - {"snd_enableReverb", "Enable sound reverberation"}, - {"snd_enableStream", "Enable streamed sounds"}, - {"snd_envFollowerBuffScale", "Amount of buffer to use for envelope follower. Smaller value indicates faster envelope."}, - {"snd_errorOnMissing", "Cause a Com_Error if a sound file is missing."}, - {"snd_hitsoundDisabled", "Disable the hit indicator sound"}, - {"snd_inheritSecondaryPitchVol", "Set to true for secondary aliases to inherit the pitch of the parent"}, - {"snd_levelFadeTime", "The amout of time in milliseconds for all audio to fade in at the start of a level"}, - {"snd_loadFadeTime", "Fade time for loading from a checkpoint after death."}, - {"snd_loopFadeTime", "Fade-in time for looping sounds."}, - {"snd_musicDisabled", "Disable all in-game music"}, - {"snd_musicDisabledForCustomSoundtrack", "Disable all in-game music due to user playing a custom soundtrack"}, - {"snd_occlusionDelay", "Minimum delay in (ms) between occlusion updates"}, - {"snd_occlusionLerpTime", "Time to lerp to target occlusion lerp when occluded"}, - {"snd_peakLimiterCompression", "Peak limiter compression factor. The output data is scaled by this and then normalized: F < 1 = disabled; F >= 1 enabled."}, - {"snd_peakLimiterDecay", "Peak limiter compression decay ratio."}, - {"snd_peakLimiterSustainFrames", "Number of frames to sustain the limiter peak. 1 frame = 10 msec."}, - {"snd_premixVolume", "Game sound pre-mix volume"}, - {"snd_reverbZoneOutsideFactor", "When a 3d sound is played in a different reverb zone than the player, this factor will be applied to its wet level."}, - {"snd_slaveFadeTime", "The amount of time in milliseconds for a 'slave' sound\nto fade its volumes when a master sound starts or stops"}, - {"snd_speakerConfig", "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround"}, - {"snd_touchStreamFilesOnLoad", "Check whether stream sound files exist while loading"}, - {"snd_useOldPanning", "Use old and busted panning"}, - {"snd_virtualChannelInfo", "Display virtual voice info."}, - {"snd_virtualMinDur", "The minimum duration (in seconds) of a sound if it is to be added to the virtual voice buffer."}, - {"snd_virtualMinPri", "The minimum priority of an alias if it is to be added to the virtual voice buffer."}, - {"snd_virtualMinTimeLeftToRevive", "The minimum time (in ms) left in a sample in order to attempt to revive it."}, - {"snd_virtualReviveVoices", "Whether or not to restore virtual voices."}, - {"snd_virtualWaitToReviveTime", "The minimum time (in ms) to wait before trying to revive the voice."}, - {"snd_volume", "Game sound master volume"}, - {"speech_active", "Are we allowed to enable Speech or not"}, - {"splitscreen", "Current game is a splitscreen game"}, - {"steam_ingame_p2p_throttle", "Time, in MS, to wait between P2P packet lookups when in-game"}, - {"stringtable_debug", "spam debug info for stringtable lookups"}, - {"sv_allowClientConsole", "Allow remote clients to access the console"}, - {"sv_allowedClan1", ""}, - {"sv_allowedClan2", ""}, - {"sv_archiveClientsPositions", "Archive the client positions to speed up SV_GetClientPositionsAtTime"}, - {"sv_checkMinPlayers", "Check min players. 0 disables"}, - {"sv_clientArchive", "Have the clients archive data to save bandwidth on the server"}, - {"sv_connectTimeout", "seconds without any message when a client is loading"}, - {"sv_cumulThinkTime", "Max client think per server 50 msec frame"}, - {"sv_error_on_baseline_failure", "Throw an error if the const baseline data is invalid."}, - {"sv_exponentialBackoffAfterNonAckedMsgs", "start exponential backoff on msg frequency if the client has not acked the last X messages"}, - {"sv_hostname", "Host name of the server"}, - {"sv_hugeSnapshotDelay", "How long to wait before building a new snapshot after a 'huge' snapshot is sent"}, - {"sv_hugeSnapshotSize", "Size of a snapshot to be considered 'huge'"}, - {"sv_kickBanTime", "Time in seconds for a player to be banned from the server after being kicked"}, - {"sv_local_client_snapshot_msec", "Local client snapshot rate, add to cl_penaltyTime"}, - {"sv_maxclients", "The maximum number of clients that can connect to a server"}, - {"sv_minPingClamp", "Clamp the minimum ping to this value"}, - {"sv_network_fps", "Number of times per second the server checks for net messages"}, - {"sv_numExpBackoffBeforeReleasingCachedSnapshots", "if a client is under an exponential backoff over this dvar, then we will release all the cached snapshot data he owns and will send him a baseline if he reconnects"}, - {"sv_paused", "Pause the server"}, - {"sv_privateClients", "Maximum number of private clients allowed on the server"}, - {"sv_privateClientsForClients", "The # of private clients (we send this to clients)"}, - {"sv_privatePassword", "password for the privateClient slots"}, - {"sv_reconnectlimit", "minimum seconds between connect messages"}, - {"sv_rejoinTimeout", "seconds without any message before allowing a rejoin"}, - {"sv_remote_client_snapshot_joiningstate_msec", "Remote client snapshot rate during join (until the client acked his first delta message)"}, - {"sv_remote_client_snapshot_msec", "Remote client snapshot rate, add to cl_penaltyTime"}, - {"sv_resetOnSpawn", "Have clients reset some player state fields when spawning rather than sending them over the network"}, - {"sv_running", "Server is running"}, - {"sv_sayName", ""}, - {"sv_showAverageBPS", "Show average bytes per second for net debugging"}, - {"sv_testValue", "Max antilag rewind"}, - {"sv_timeout", "seconds without any message"}, - {"sv_trackFrameMsecThreshold", "server frame time that will trigger script time tracking."}, - {"sv_useExtraCompress", "Use zlib compress for gamestate/baseline/score packets"}, - {"sv_zlib_threshold", "Message size threshold which triggers more aggressive compression"}, - {"sv_zombietime", "seconds to sync messages after disconnect"}, - {"svwp", "playerdata server write protection: 0 = disable, 1 = silent, 2 = kick"}, - {"syncTimeTimeout", "default timeout for sync time task (in seconds)"}, - {"sys_configSum", "Configuration checksum"}, - {"sys_configureGHz", "Normalized total CPU power, based on cpu type, count, and speed; used in autoconfigure"}, - {"sys_cpuGHz", "Measured CPU speed"}, - {"sys_cpuName", "CPU name description"}, - {"sys_gpu", "GPU description"}, - {"sys_lockThreads", "Prevents specified threads from changing CPUs; improves profiling and may fix some bugs, but can hurt performance"}, - {"sys_quitMigrateTime", "Time in msec to wait for host migration when user closes the window"}, - {"sys_smp_allowed", "Allow multi-threading"}, - {"sys_SSE", "Operating system allows Streaming SIMD Extensions"}, - {"sys_sysMB", "Physical memory in the system"}, - {"systemlink", "Current game is a system link game"}, - {"systemlink_host", "Local client is hosting system link game"}, - {"tb_report", "tb event record"}, - {"team_rebalance", "rebalance"}, - {"teambalance_option", "Selects active teambalance algorithm. 0 = heuristic 1 = exhaustive"}, - {"theater_active", "Are we allowed to show theater or not."}, - {"thermal_playerModel", "Model to draw for players when in thermal vision mode"}, - {"thermalBlurFactorNoScope", "Amount of blur to use when drawing blur through a weapon's thermal scope."}, - {"thermalBlurFactorScope", "Amount of blur to use when drawing blur through a weapon's thermal scope."}, - {"tokensEnabled", "Is token economy enabled"}, - {"tracer_explosiveColor1", "The 1st color of a bullet tracer when using explosive bullets"}, - {"tracer_explosiveColor2", "The 2nd color of a bullet tracer when using explosive bullets"}, - {"tracer_explosiveColor3", "The 3rd color of a bullet tracer when using explosive bullets"}, - {"tracer_explosiveColor4", "The 4th color of a bullet tracer when using explosive bullets"}, - {"tracer_explosiveColor5", "The 5th color of a bullet tracer when using explosive bullets"}, - {"tracer_explosiveOverride", "When turned on, will apply an override to the tracer settings when shooting explosive bullets."}, - {"tracer_explosiveWidth", "The width of a bullet tracer when using explosive bullets"}, - {"tracer_firstPersonMaxWidth", "The maximum width our OWN tracers can be when looking through our ADS"}, - {"tracer_stoppingPowerColor1", "The 1st color of a bullet tracer when using explosive bullets"}, - {"tracer_stoppingPowerColor2", "The 2nd color of a bullet tracer when using explosive bullets"}, - {"tracer_stoppingPowerColor3", "The 3rd color of a bullet tracer when using explosive bullets"}, - {"tracer_stoppingPowerColor4", "The 4th color of a bullet tracer when using explosive bullets"}, - {"tracer_stoppingPowerColor5", "The 5th color of a bullet tracer when using explosive bullets"}, - {"tracer_stoppingPowerOverride", "When turned on, will apply an override to the tracer settings when shooting explosive bullets."}, - {"tracer_stoppingPowerWidth", "The width of a bullet tracer when using explosive bullets"}, - {"tracer_thermalWidthMult", "The multiplier applied to the base width when viewed in thermal vision"}, - {"transients_verbose", "Verbose logging information for transient fastfiles."}, - {"triggerDLCEnumerationOnSocialConfigLoad", "Triggers a new DLC enumeration after social config has loaded."}, - {"ui_allow_controlschange", ""}, - {"ui_allow_teamchange", ""}, - {"ui_autodetectGamepad", "undefined"}, - {"ui_autodetectGamepadDone", "undefined"}, - {"ui_bigFont", "Big font scale"}, - {"ui_blurAmount", "Max amount to blur background menu items."}, - {"ui_blurDarkenAmount", "Amount to darken blurred UI."}, - {"ui_blurTime", "Time in milliseconds to fade in/out the blur."}, - {"ui_borderLowLightScale", "Scales the border color for the lowlight color on certain UI borders"}, - {"ui_browserFriendlyfire", "Friendly fire is active"}, - {"ui_browserKillcam", "Kill cam is active"}, - {"ui_browserMod", "UI Mod value"}, - {"ui_browserShowDedicated", "Show dedicated servers only"}, - {"ui_browserShowEmpty", "Show empty servers"}, - {"ui_browserShowFull", "Show full servers"}, - {"ui_browserShowPassword", "Show servers that are password protected"}, - {"ui_browserShowPure", "Show pure servers only"}, - {"ui_buildLocation", "Where to draw the build number"}, - {"ui_buildSize", "Font size to use for the build number"}, - {"ui_challenge_1_ref", ""}, - {"ui_challenge_2_ref", ""}, - {"ui_challenge_3_ref", ""}, - {"ui_challenge_4_ref", ""}, - {"ui_challenge_5_ref", ""}, - {"ui_challenge_6_ref", ""}, - {"ui_challenge_7_ref", ""}, - {"ui_changeclass_menu_open", ""}, - {"ui_changeteam_menu_open", ""}, - {"ui_cinematicsTimestamp", "Shows cinematics timestamp on subtitle UI elements."}, - {"ui_class_menu_open", ""}, - {"ui_connectScreenTextGlowColor", "Glow color applied to the mode and map name strings on the connect screen."}, - {"ui_contextualMenuLocation", "Contextual menu location from where you entered the store."}, - {"ui_controls_menu_open", ""}, - {"ui_currentFeederMapIndex", "Currently selected map"}, - {"ui_currentMap", "Current map index"}, - {"ui_customClassName", "Custom Class name"}, - {"ui_customModeEditName", "Name to give the currently edited custom game mode when editing is complete"}, - {"ui_customModeName", "Custom game mode name"}, - {"ui_danger_team", ""}, - {"ui_debugMode", "Draw ui debug info on the screen."}, - {"ui_disableInGameStore", "This will disable the ingame store button on the xbox live menu."}, - {"ui_disableTokenRedemption", "This will disable the token redemption option in the in-game store menu."}, - {"ui_drawCrosshair", "Whether to draw crosshairs."}, - {"ui_editSquadMemberIndex", "Which squad member is currently being edited"}, - {"ui_extraBigFont", "Extra big font scale"}, - {"ui_game_state", ""}, - {"ui_gametype", "Current game type"}, - {"ui_halftime", ""}, - {"ui_hitloc_0", ""}, - {"ui_hitloc_1", ""}, - {"ui_hitloc_2", ""}, - {"ui_hitloc_3", ""}, - {"ui_hitloc_4", ""}, - {"ui_hitloc_5", ""}, - {"ui_hitloc_damage_0", ""}, - {"ui_hitloc_damage_1", ""}, - {"ui_hitloc_damage_2", ""}, - {"ui_hitloc_damage_3", ""}, - {"ui_hitloc_damage_4", ""}, - {"ui_hitloc_damage_5", ""}, - {"ui_hud_hardcore", "Whether the HUD should be suppressed for hardcore mode"}, - {"ui_hud_obituaries", ""}, - {"ui_inactiveBaseColor", "The local player's rank/stats font color when shown in lobbies and parties"}, - {"ui_inactivePartyColor", ""}, - {"ui_inGameStoreOpen", "is the InGameStore open"}, - {"ui_inhostmigration", ""}, - {"ui_joinGametype", "Game join type"}, - {"ui_loadMenuName", "Frontend menu will start on this level instead of lockout"}, - {"ui_mapname", "Current map name"}, - {"ui_mapvote_entrya_gametype", "Primary map vote entry game type"}, - {"ui_mapvote_entrya_mapname", "Primary map vote entry map name"}, - {"ui_mapvote_entryb_gametype", "Secondary map vote entry game type"}, - {"ui_mapvote_entryb_mapname", "Secondary map vote entry map name"}, - {"ui_maxclients", "undefined"}, - {"ui_missingMapName", "Name of map to show in missing content error"}, - {"ui_mousePitch", ""}, - {"ui_multiplayer", "True if the game is multiplayer"}, - {"ui_myPartyColor", "Player name font color when in the same party as the local player"}, - {"ui_netGametype", "Game type"}, - {"ui_netGametypeName", "Displayed game type name"}, - {"ui_netSource", "The network source where:\n 0:Local\n 1:Internet\n 2:Favourites"}, - {"ui_onlineRequired", "UI requires online connection to be present."}, - {"ui_opensummary", ""}, - {"ui_override_halftime", ""}, - {"ui_partyFull", "True if the current party is full."}, - {"ui_playerPartyColor", ""}, - {"ui_playlistActionButtonAlpha", "The current alpha of the playlist selection button"}, - {"ui_playlistCategoryDisabledColor", "The color of playlist categories when disabled"}, - {"ui_playlistCategoryEnabledColor", "The color of playlist categories when enabled"}, - {"ui_promotion", ""}, - {"ui_remoteTankUseTime", ""}, - {"ui_scorelimit", ""}, - {"ui_selectedFeederMap", "Current preview game type"}, - {"ui_serverStatusTimeOut", "Time in milliseconds before a server status request times out"}, - {"ui_show_store", "Use to enable the store button"}, - {"ui_showDLCMaps", "Whether to display the DLC maps."}, - {"ui_showInfo", ""}, - {"ui_showList", "Show onscreen list of currently visible menus"}, - {"ui_showmap", ""}, - {"ui_showMenuOnly", "If set, only menus using this name will draw."}, - {"ui_showMinimap", ""}, - {"ui_sliderSteps", "The number of steps for a slider itemdef"}, - {"ui_smallFont", "Small font scale"}, - {"ui_textScrollFadeTime", "Text scrolling takes this long (seconds) to fade out at the end before restarting"}, - {"ui_textScrollPauseEnd", "Text scrolling waits this long (seconds) before starting"}, - {"ui_textScrollPauseStart", "Text scrolling waits this long (seconds) before starting"}, - {"ui_textScrollSpeed", "Speed at which text scrolls vertically"}, - {"ui_timelimit", ""}, - {"uiscript_debug", "spam debug info for the ui script"}, - {"unlock_breadcrumb_killswitch", "True to enable unlock breadcrumbs"}, - {"uno_current_tos_version", "Current Uno Terms of Service Version"}, - {"use_filtered_query_pass", "Dictates whether to use the filtered query for MMing or not"}, - {"use_weighted_dlc_exactmatch_pass", "Dictates whether to use a search weighted pass with the DLC match set to exact for MMing or not"}, - {"use_weighted_pass", "Dictates whether to use the search weighted pass for MMing or not"}, - {"useCPMarkerForCPOwnership", "If set, we will check the player inventory to see if he owns the redeemedItem for a contentPack if this contentPack is not available for the player"}, - {"useonlinestats", "Whether to use online stats when in offline modes"}, - {"useRelativeTeamColors", "Whether to use relative team colors."}, - {"userFileFetchTimeout", "default timeout for user files FETCH tasks (in seconds)"}, - {"userGroup_active", "Are we allowed to show Usergroups or not"}, - {"userGroup_cool_off_time", "Cool off time between calls to fetch the elite clan"}, - {"userGroup_coop_delay", "Delay between a player joining a coop lobby and the DW user group task starting"}, - {"userGroup_max_retry_time", "Max time that the usergroup read find can retry"}, - {"userGroup_refresh_time_secs", "Time in seconds between re-sending lobby group data to confirmed users."}, - {"userGroup_retry_step", "Step in m/s for the usegroup read retry"}, - {"userGroup_RetryTime", "Time in ms between sending lobby group data retrys."}, - {"useStatsGroups", "If true then StatsGroups are in use for all playerdata.ddl accessing."}, - {"useTagFlashSilenced", "When true, silenced weapons will use \"tag_flash_silenced\" instead of \"tag_flash\"."}, - {"using_mlg", "MLG feature on/off"}, - {"validate_apply_clamps", "True if individual stat validation failure reverts the value"}, - {"validate_apply_revert", "True if individual stat validation failure reverts the value"}, - {"validate_apply_revert_full", "True if any individual stat validation failure causes a full stats revert"}, - {"validate_clamp_assists", "The maximum number of assists a player can make in a match"}, - {"validate_clamp_experience", "The maximum experience a player can gain in a match"}, - {"validate_clamp_headshots", "The maximum number of headshots a player can make in a match"}, - {"validate_clamp_hits", "The maximum number of hits player can make in a match"}, - {"validate_clamp_kills", "The maximum number of kills a player can make in a match"}, - {"validate_clamp_losses", "The maximum number of losses a player can make in a match"}, - {"validate_clamp_misses", "The maximum number of misses player can make in a match"}, - {"validate_clamp_ties", "The maximum number of ties a player can make in a match"}, - {"validate_clamp_totalshots", "The maximum number of totalshots player can make in a match"}, - {"validate_clamp_weaponXP", "The maximum experience a weapon can gain in a match"}, - {"validate_clamp_wins", "The maximum number of wins a player can make in a match"}, - {"validate_drop_on_fail", "True if stats validation failure results in dropping from the match"}, - {"veh_aiOverSteerScale", "Scaler used to cause ai vehicles to over steer"}, - {"veh_boneControllerLodDist", "Distance at which bone controllers are not updated."}, - {"veh_boneControllerUnLodDist", "Distance at which bone controllers start updating when not moving."}, - {"vehAudio_inAirPitchDownLerp", "Rate at which the pitch lerps down"}, - {"vehAudio_inAirPitchUpLerp", "Rate at which the pitch lerps up"}, - {"vehAudio_spawnVolumeTime", "Seconds it takes for spawned vehicles to reach full volume."}, - {"vehCam_freeLook", "Enables free look mode"}, - {"vehCam_mode", "Camera modes: 1st person, 3rd person, or both"}, - {"vehDroneDebugDrawPath", "Debug render the drone draw paths."}, - {"vehHelicopterBoundsRadius", "The radius of the collision volume to be used when colliding with world geometry."}, - {"vehHelicopterDecelerationFwd", "Set the deceleration of the player helicopter (as a fraction of acceleration) in the direction the chopper is facing. So 1.0 makes it equal to the acceleration."}, - {"vehHelicopterDecelerationSide", "Set the side-to-side deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration."}, - {"vehHelicopterDecelerationUp", "Set the vertical deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration."}, - {"vehHelicopterHeadSwayDontSwayTheTurret", "If set, the turret will not fire through the crosshairs, but straight ahead of the vehicle, when the player is not freelooking."}, - {"vehHelicopterHoverSpeedThreshold", "The speed below which the player helicopter begins to jitter the tilt, for hovering"}, - {"vehHelicopterInvertUpDown", "Invert the altitude control on the player helicopter."}, - {"vehHelicopterJitterJerkyness", "Specifies how jerky the tilt jitter should be"}, - {"vehHelicopterLookaheadTime", "How far ahead (in seconds) the player helicopter looks ahead, to avoid hard collisions. (Like driving down the highway, you should keep 2 seconds distance between you and the vehicle in front of you)"}, - {"vehHelicopterMaxAccel", "Maximum horizontal acceleration of the player helicopter (in MPH per second)"}, - {"vehHelicopterMaxAccelVertical", "Maximum vertical acceleration of the player helicopter (in MPH per second)"}, - {"vehHelicopterMaxPitch", "Maximum pitch of the player helicopter"}, - {"vehHelicopterMaxRoll", "Maximum roll of the player helicopter"}, - {"vehHelicopterMaxSpeed", "Maximum horizontal speed of the player helicopter (in MPH)"}, - {"vehHelicopterMaxSpeedVertical", "Maximum vertical speed of the player helicopter (in MPH)"}, - {"vehHelicopterMaxYawAccel", "Maximum yaw acceleration of the player helicopter"}, - {"vehHelicopterMaxYawRate", "Maximum yaw speed of the player helicopter"}, - {"vehHelicopterPitchOffset", "The resting pitch of the helicopter"}, - {"vehHelicopterRightStickDeadzone", "Dead-zone for the axes of the right thumbstick. This helps to better control the two axes separately."}, - {"vehHelicopterScaleMovement", "Scales down the smaller of the left stick axes."}, - {"vehHelicopterSoftCollisions", "Player helicopters have soft collisions (slow down before they collide)."}, - {"vehHelicopterStrafeDeadzone", "Dead-zone so that you can fly straight forward easily without accidentally strafing (and thus rolling)."}, - {"vehHelicopterTiltFromAcceleration", "The amount of tilt caused by acceleration"}, - {"vehHelicopterTiltFromControllerAxes", "The amount of tilt caused by the desired velocity (i.e., the amount of controller stick deflection)"}, - {"vehHelicopterTiltFromDeceleration", "The amount of tilt caused by deceleration"}, - {"vehHelicopterTiltFromFwdAndYaw", "The amount of roll caused by yawing while moving forward."}, - {"vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt", "The forward speed (as a fraction of top speed) at which the tilt due to yaw reaches is maximum value."}, - {"vehHelicopterTiltFromVelocity", "The amount of tilt caused by the current velocity"}, - {"vehHelicopterTiltMomentum", "The amount of rotational momentum the helicopter has with regards to tilting."}, - {"vehHelicopterTiltSpeed", "The rate at which the player helicopter's tilt responds"}, - {"vehHelicopterYawOnLeftStick", "The yaw speed created by the left stick when pushing the stick diagonally (e.g., moving forward and strafing slightly)."}, - {"vehicle_debug_render_spline_plane", "Do we want to render the spline plane data"}, - {"vehicle_pathsmooth", "Smoothed vehicle pathing."}, - {"vehUGVPitchTrack", "UGV body pitch orientation speed"}, - {"vehUGVRollTrack", "UGV body roll orientation speed"}, - {"vehUGVWheelInfluence", "UGV wheel influence on the orientation of the body"}, - {"vehWalkerControlMode", "Walker controls (0==move no turn, 1=move and turn, 2=move relative(tank))"}, - {"version", "Game version"}, - {"vid_xpos", "Game window horizontal position"}, - {"vid_ypos", "Game window vertical position"}, - {"viewangNow", ""}, - {"viewModelDebugNotetracks", "Enable display of viewmodel notetrack debug info."}, - {"viewModelHacks", "Enabled depth hack and remove viewmodel from shadows."}, - {"viewposNow", ""}, - {"virtualLobbyActive", "Indicates the VL is actively being displayed."}, - {"virtualLobbyAllocated", "Indicates the first VL zone has been loaded."}, - {"virtualLobbyEnabled", "VirtualLobby is enabled (must be true before loading UI zone)"}, - {"virtualLobbyInFiringRange", "VirtualLobby is in firing range mode"}, - {"virtualLobbyMap", "VirtualLobby map to load (must be set before starting vl)"}, - {"virtualLobbyMembers", "Number of members in the VirtualLobby (set by script)"}, - {"virtualLobbyPresentable", "Indicates to LUA the VirtualLobby is ready to be displayed (set by script)."}, - {"virtualLobbyReady", "Indicates to LUA the VirtualLobby is loaded and running (set by script)."}, - {"vl_clan_models_loaded", "Indicates to LUA when all models are loaded for the clan highlights so it can begin the fade-in without any popping(set by script)."}, - {"voMtxEnable", "When set (e.g. via config), will enable voice over packs"}, - {"waypointAerialIconMaxSize", "Max size of aerial targeting waypoints."}, - {"waypointAerialIconMinSize", "Min size of aerial targeting waypoints."}, - {"waypointAerialIconScale", "Base scale of aerial targeting waypoints."}, - {"waypointDebugDraw", ""}, - {"waypointDistScaleRangeMax", "Distance from player that icon distance scaling ends."}, - {"waypointDistScaleRangeMin", "Distance from player that icon distance scaling ends."}, - {"waypointDistScaleSmallest", "Smallest scale that the distance effect uses."}, - {"waypointIconHeight", ""}, - {"waypointIconWidth", ""}, - {"waypointOffscreenCornerRadius", "Size of the rounded corners."}, - {"waypointOffscreenDistanceThresholdAlpha", "Distance from the threshold over which offscreen objective icons lerp their alpha."}, - {"waypointOffscreenPadBottom", ""}, - {"waypointOffscreenPadLeft", ""}, - {"waypointOffscreenPadRight", ""}, - {"waypointOffscreenPadTop", ""}, - {"waypointOffscreenPointerDistance", "Distance from the center of the offscreen objective icon to the center its arrow."}, - {"waypointOffscreenPointerHeight", ""}, - {"waypointOffscreenPointerWidth", ""}, - {"waypointOffscreenRoundedCorners", "Off-screen icons take rounded corners when true. 90-degree corners when false."}, - {"waypointOffscreenScaleLength", "How far the offscreen icon scale travels from full to smallest scale."}, - {"waypointOffscreenScaleSmallest", "Smallest scale that the offscreen effect uses."}, - {"waypointPlayerOffsetCrouch", "For waypoints pointing to players, how high to offset off of their origin when they are prone."}, - {"waypointPlayerOffsetProne", "For waypoints pointing to players, how high to offset off of their origin when they are prone."}, - {"waypointPlayerOffsetStand", "For waypoints pointing to players, how high to offset off of their origin when they are prone."}, - {"waypointScreenCenterFadeAdsMin", "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads"}, - {"waypointScreenCenterFadeHipMin", "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads"}, - {"waypointScreenCenterFadeRadius", "Radius from screen center that a waypoint will start fading out. Setting to 0 will turn this off"}, - {"waypointSplitscreenScale", "Scale applied to waypoint icons in splitscreen views."}, - {"waypointTweakY", ""}, - {"weap_thermoDebuffMod", ""}, - {"wideScreen", "True if the game video is running in 16x9 aspect, false if 4x3."}, - {"winvoice_loopback", "Echo microphone input locally"}, - {"winvoice_mic_mute", "Mute the microphone"}, - {"winvoice_mic_outTime", "Microphone voice amount of silence before we cut the mic"}, - {"winvoice_mic_reclevel", "Microphone recording level"}, - {"winvoice_mic_scaler", "Microphone scaler value"}, - {"winvoice_mic_threshold", "Microphone voice threshold"}, - {"winvoice_save_voice", "Write voice data to a file"}, - {"xanim_disableIK", "Disable inverse kinematics solvers"}, - {"xblive_competitionmatch", "MLG Rules?"}, - {"xblive_hostingprivateparty", "true only if we're hosting a party"}, - {"xblive_loggedin", "User is logged into xbox live"}, - {"xblive_privatematch", "Current game is a private match"}, - {"xblive_privatematch_solo", "Current game is an Extinction solo match"}, - {"xphys_maxJointPositionError", "If a joints with position error exceeding this value is detected, then the whole xphys system gets snapped back to the animation pose"}, + { + "accessToSubscriberContent", + "Whether to display the subscriber maps.", + generate_hash("accessToSubscriberContent") + }, + { + "aci", + "", + generate_hash("aci") + }, + { + "actionSlotsHide", + "Hide the actionslots.", + generate_hash("actionSlotsHide") + }, + { + "ai_grenadeReturn_approachMinDot", + "Minimal dot product between the approach and throw vectors to perform a grenade return", + generate_hash("ai_grenadeReturn_approachMinDot") + }, + { + "ai_grenadeReturn_debug", + "Turns on debug info for AI grenade returns", + generate_hash("ai_grenadeReturn_debug") + }, + { + "ai_grenadeReturn_extraFuseTime", + "The amount of time (in ms) to add to a grenade fuse when trying to return grenade that's below minFuseTime", + generate_hash("ai_grenadeReturn_extraFuseTime") + }, + { + "ai_grenadeReturn_minDistSqr", + "Minimal distance to a grenade to consider it for a return so that transition anims will play", + generate_hash("ai_grenadeReturn_minDistSqr") + }, + { + "ai_grenadeReturn_minFuseTime", + "If the fuse time drops below this value when an ally is attempting to return a grenade, add extra fuse time", + generate_hash("ai_grenadeReturn_minFuseTime") + }, + { + "ai_grenadeReturn_stationary", + "If set, AI will attempt to return grenades that they are within pickup distance - regardless of min dist", + generate_hash("ai_grenadeReturn_stationary") + }, + { + "ai_grenadeReturn_traceToGrenade", + "If set, AI will only attempt to return grenades when they have a clear sight trace to the grenade", + generate_hash("ai_grenadeReturn_traceToGrenade") + }, + { + "ai_threatUpdateInterval", + "AI target threat update interval in milliseconds", + generate_hash("ai_threatUpdateInterval") + }, + { + "aim_autoaim_enabled", + "", + generate_hash("aim_autoaim_enabled") + }, + { + "aim_target_sentient_radius", + "The radius used to calculate target bounds for a sentient(actor or player)", + generate_hash("aim_target_sentient_radius") + }, + { + "ammoCounterHide", + "Hide the Ammo Counter", + generate_hash("ammoCounterHide") + }, + { + "armory_contentpacks_enabled", + "Allowed armory content packs. 0: none , 1: first armory content pack enabled, 2: first and second armory content pack enabled", + generate_hash("armory_contentpacks_enabled") + }, + { + "badHost_detectMinServerTime", + "Time in MS before the bad host dection system kicks in after match start", + generate_hash("badHost_detectMinServerTime") + }, + { + "badhost_maxDoISuckFrames", + "Max lagged frames need to end match", + generate_hash("badhost_maxDoISuckFrames") + }, + { + "band_12players", + "12 player bandwidth req'd", + generate_hash("band_12players") + }, + { + "band_18players", + "18 player bandwidth req'd", + generate_hash("band_18players") + }, + { + "band_2players", + "2 player bandwidth req'd", + generate_hash("band_2players") + }, + { + "band_4players", + "4 player bandwidth req'd", + generate_hash("band_4players") + }, + { + "band_8players", + "8 player bandwidth req'd", + generate_hash("band_8players") + }, + { + "bg_allowScuffFootsteps", + "If true, scuff sounds will be played when the player rotates in place.", + generate_hash("bg_allowScuffFootsteps") + }, + { + "bg_bulletExplDmgFactor", + "Weapon damage multiplier that will be applied at the center of the slash damage area.", + generate_hash("bg_bulletExplDmgFactor") + }, + { + "bg_bulletExplRadius", + "The radius of the bullet splash damage, where the damage gradually falls off to 0.", + generate_hash("bg_bulletExplRadius") + }, + { + "bg_compassShowEnemies", + "Whether enemies are visible on the compass at all times", + generate_hash("bg_compassShowEnemies") + }, + { + "bg_idleSwingSpeed", + "The rate at which the player's legs swing around when idle (multi-player only)", + generate_hash("bg_idleSwingSpeed") + }, + { + "bg_shieldHitEncodeHeightVM", + "The decoding range, in height, of a client's viewmodel shield.", + generate_hash("bg_shieldHitEncodeHeightVM") + }, + { + "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.", + generate_hash("bg_shieldHitEncodeHeightWorld") + }, + { + "bg_shieldHitEncodeWidthVM", + "The decoding range, in width, of a client's viewmodel shield.", + generate_hash("bg_shieldHitEncodeWidthVM") + }, + { + "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.", + generate_hash("bg_shieldHitEncodeWidthWorld") + }, + { + "bg_shock_fadeOverride", + "Override the time for the shellshock kick effect to fade in MP", + generate_hash("bg_shock_fadeOverride") + }, + { + "bg_shock_lookControl", + "Alter player control during shellshock", + generate_hash("bg_shock_lookControl") + }, + { + "bg_shock_lookControl_fadeTime", + "The time for the shellshock player control to fade in seconds", + generate_hash("bg_shock_lookControl_fadeTime") + }, + { + "bg_shock_lookControl_maxpitchspeed", + "Maximum pitch movement rate while shellshocked in degrees per second", + generate_hash("bg_shock_lookControl_maxpitchspeed") + }, + { + "bg_shock_lookControl_maxyawspeed", + "Maximum yaw movement rate while shell shocked in degrees per second", + generate_hash("bg_shock_lookControl_maxyawspeed") + }, + { + "bg_shock_lookControl_mousesensitivityscale", + "Sensitivity scale to apply to a shellshocked player", + generate_hash("bg_shock_lookControl_mousesensitivityscale") + }, + { + "bg_shock_movement", + "Affect player's movement speed duringi shellshock", + generate_hash("bg_shock_movement") + }, + { + "bg_shock_screenBlurBlendFadeTime", + "The amount of time in seconds for the shellshock effect to fade", + generate_hash("bg_shock_screenBlurBlendFadeTime") + }, + { + "bg_shock_screenBlurBlendTime", + "The amount of time in seconds for the shellshock effect to fade", + generate_hash("bg_shock_screenBlurBlendTime") + }, + { + "bg_shock_screenFlashShotFadeTime", + "In seconds, how soon from the end of the effect to start blending out the whiteout layer.", + generate_hash("bg_shock_screenFlashShotFadeTime") + }, + { + "bg_shock_screenFlashWhiteFadeTime", + "In seconds, how soon from the end of the effect to start blending out the whiteout layer.", + generate_hash("bg_shock_screenFlashWhiteFadeTime") + }, + { + "bg_shock_screenType", + "Shell shock screen effect type", + generate_hash("bg_shock_screenType") + }, + { + "bg_shock_sound", + "Play shell shock sound", + generate_hash("bg_shock_sound") + }, + { + "bg_shock_soundDryLevel", + "Shell shock sound dry level", + generate_hash("bg_shock_soundDryLevel") + }, + { + "bg_shock_soundEnd", + "Shellshock end sound alias", + generate_hash("bg_shock_soundEnd") + }, + { + "bg_shock_soundEndAbort", + "Shellshock aborted end sound alias", + generate_hash("bg_shock_soundEndAbort") + }, + { + "bg_shock_soundFadeInTime", + "Shell shock sound fade in time in seconds", + generate_hash("bg_shock_soundFadeInTime") + }, + { + "bg_shock_soundFadeOutTime", + "Shell shock sound fade out time in seconds", + generate_hash("bg_shock_soundFadeOutTime") + }, + { + "bg_shock_soundLoop", + "Shellshock loop alias", + generate_hash("bg_shock_soundLoop") + }, + { + "bg_shock_soundLoopEndDelay", + "Sound loop end offset time from the end of the shellshock in seconds", + generate_hash("bg_shock_soundLoopEndDelay") + }, + { + "bg_shock_soundLoopFadeTime", + "Shell shock sound loop fade time in seconds", + generate_hash("bg_shock_soundLoopFadeTime") + }, + { + "bg_shock_soundLoopSilent", + "The sound that gets blended with the shellshock loop alias", + generate_hash("bg_shock_soundLoopSilent") + }, + { + "bg_shock_soundModEndDelay", + "The delay from the end of the shell shock to the end of the sound modification", + generate_hash("bg_shock_soundModEndDelay") + }, + { + "bg_shock_soundRoomType", + "Shell shock sound reverb room type", + generate_hash("bg_shock_soundRoomType") + }, + { + "bg_shock_soundSubmix", + "Shell shock submix to apply", + generate_hash("bg_shock_soundSubmix") + }, + { + "bg_shock_soundWetLevel", + "Shell shock sound wet level", + generate_hash("bg_shock_soundWetLevel") + }, + { + "bg_shock_viewKickFadeTime", + "The time for the shellshock kick effect to fade", + generate_hash("bg_shock_viewKickFadeTime") + }, + { + "bg_shock_viewKickPeriod", + "The period of the shellshock view kick effect", + generate_hash("bg_shock_viewKickPeriod") + }, + { + "bg_shock_viewKickRadius", + "Shell shock kick radius", + generate_hash("bg_shock_viewKickRadius") + }, + { + "bg_swingSpeed", + "The rate at which the player's legs swing around when idle (multi-player only)", + generate_hash("bg_swingSpeed") + }, + { + "bg_torsoSwingSpeed", + "The rate at which the player's torso swings around when strafing (multi-player only)", + generate_hash("bg_torsoSwingSpeed") + }, + { + "boostcheatHeadshotsTotalCoef", + "", + generate_hash("boostcheatHeadshotsTotalCoef") + }, + { + "boostcheatHeadshotsTotalMean", + "", + generate_hash("boostcheatHeadshotsTotalMean") + }, + { + "boostcheatHeadshotsTotalStddev", + "", + generate_hash("boostcheatHeadshotsTotalStddev") + }, + { + "boostcheatIntercept", + "", + generate_hash("boostcheatIntercept") + }, + { + "boostcheatKillerXAnomalyCoef", + "", + generate_hash("boostcheatKillerXAnomalyCoef") + }, + { + "boostcheatKillerXAnomalyMean", + "", + generate_hash("boostcheatKillerXAnomalyMean") + }, + { + "boostcheatKillerXAnomalyStddev", + "", + generate_hash("boostcheatKillerXAnomalyStddev") + }, + { + "boostcheatKillerYAnomalyCoef", + "", + generate_hash("boostcheatKillerYAnomalyCoef") + }, + { + "boostcheatKillerYAnomalyMean", + "", + generate_hash("boostcheatKillerYAnomalyMean") + }, + { + "boostcheatKillerYAnomalyStddev", + "", + generate_hash("boostcheatKillerYAnomalyStddev") + }, + { + "boostcheatMeanDistanceMostKilledPlayerTraveledMean", + "", + generate_hash("boostcheatMeanDistanceMostKilledPlayerTraveledMean") + }, + { + "boostcheatMeanDistanceVictimTraveledCoef", + "", + generate_hash("boostcheatMeanDistanceVictimTraveledCoef") + }, + { + "boostcheatMeanDistanceVictimTraveledMean", + "", + generate_hash("boostcheatMeanDistanceVictimTraveledMean") + }, + { + "boostcheatMeanDistanceVictimTraveledStddev", + "", + generate_hash("boostcheatMeanDistanceVictimTraveledStddev") + }, + { + "boostcheatMeanMostKilledPlayerLifetimeMillisecondsMean", + "", + generate_hash("boostcheatMeanMostKilledPlayerLifetimeMillisecondsMean") + }, + { + "boostcheatMostKilledPlayerHKRatioCoef", + "", + generate_hash("boostcheatMostKilledPlayerHKRatioCoef") + }, + { + "boostcheatMostKilledPlayerHKRatioMean", + "", + generate_hash("boostcheatMostKilledPlayerHKRatioMean") + }, + { + "boostcheatMostKilledPlayerHKRatioStddev", + "", + generate_hash("boostcheatMostKilledPlayerHKRatioStddev") + }, + { + "boostcheatMostKilledPlayerKillsRatioCoef", + "", + generate_hash("boostcheatMostKilledPlayerKillsRatioCoef") + }, + { + "boostcheatMostKilledPlayerKillsRatioMean", + "", + generate_hash("boostcheatMostKilledPlayerKillsRatioMean") + }, + { + "boostcheatMostKilledPlayerKillsRatioStddev", + "", + generate_hash("boostcheatMostKilledPlayerKillsRatioStddev") + }, + { + "boostcheatMostKilledPlayerKillsTotalCoef", + "", + generate_hash("boostcheatMostKilledPlayerKillsTotalCoef") + }, + { + "boostcheatMostKilledPlayerKillsTotalMean", + "", + generate_hash("boostcheatMostKilledPlayerKillsTotalMean") + }, + { + "boostcheatMostKilledPlayerKillsTotalStddev", + "", + generate_hash("boostcheatMostKilledPlayerKillsTotalStddev") + }, + { + "boostcheatMostKilledPlayerKillTimestampsAnomalyMean", + "", + generate_hash("boostcheatMostKilledPlayerKillTimestampsAnomalyMean") + }, + { + "boostcheatVictimXAnomalyCoef", + "", + generate_hash("boostcheatVictimXAnomalyCoef") + }, + { + "boostcheatVictimXAnomalyMean", + "", + generate_hash("boostcheatVictimXAnomalyMean") + }, + { + "boostcheatVictimXAnomalyStddev", + "", + generate_hash("boostcheatVictimXAnomalyStddev") + }, + { + "boostcheatVictimYAnomalyCoef", + "", + generate_hash("boostcheatVictimYAnomalyCoef") + }, + { + "boostcheatVictimYAnomalyMean", + "", + generate_hash("boostcheatVictimYAnomalyMean") + }, + { + "boostcheatVictimYAnomalyStddev", + "", + generate_hash("boostcheatVictimYAnomalyStddev") + }, + { + "bot_DifficultyDefault", + "default difficulty level of bots", + generate_hash("bot_DifficultyDefault") + }, + { + "ca_auto_signin", + "CoD Anywhere start sign-in task automatically on startup or first party sign-in", + generate_hash("ca_auto_signin") + }, + { + "ca_do_mlc", + "CoD Anywhere Do Multi Login check", + generate_hash("ca_do_mlc") + }, + { + "ca_intra_only", + "CoD Anywhere Intra Network Only", + generate_hash("ca_intra_only") + }, + { + "ca_require_signin", + "CoD Anywhere require sign in to enter MP", + generate_hash("ca_require_signin") + }, + { + "ca_show_signup_request", + "CoD Anywhere should you show new users a popup requesting they create a CoD Account?", + generate_hash("ca_show_signup_request") + }, + { + "camera_thirdPerson", + "Use third person view globally", + generate_hash("camera_thirdPerson") + }, + { + "cameraShakeRemoteHelo_Angles", + "Remote helicopter gunner cam, range to shake the view.", + generate_hash("cameraShakeRemoteHelo_Angles") + }, + { + "cameraShakeRemoteHelo_Freqs", + "Remote helicopter gunner cam, how fast to shake.", + generate_hash("cameraShakeRemoteHelo_Freqs") + }, + { + "cameraShakeRemoteHelo_SpeedRange", + "Remote helicopter gunner cam, range of missile speed to scale the shaking.", + generate_hash("cameraShakeRemoteHelo_SpeedRange") + }, + { + "cameraShakeRemoteMissile_Angles", + "Remote missile-cam, range to shake the view.", + generate_hash("cameraShakeRemoteMissile_Angles") + }, + { + "cameraShakeRemoteMissile_Freqs", + "Remote missile-cam, how fast to shake.", + generate_hash("cameraShakeRemoteMissile_Freqs") + }, + { + "cameraShakeRemoteMissile_SpeedRange", + "Remote missile-cam, range of missile speed to scale the shaking.", + generate_hash("cameraShakeRemoteMissile_SpeedRange") + }, + { + "cg_airstrikeCamFstop", + "Airstrike kill camera aperture. Lower f-stop yields a shallower depth of field. Typical values range from 1 to 22", + generate_hash("cg_airstrikeCamFstop") + }, + { + "cg_airstrikeKillCamFarBlur", + "", + generate_hash("cg_airstrikeKillCamFarBlur") + }, + { + "cg_airstrikeKillCamFarBlurDist", + "", + generate_hash("cg_airstrikeKillCamFarBlurDist") + }, + { + "cg_airstrikeKillCamFarBlurStart", + "", + generate_hash("cg_airstrikeKillCamFarBlurStart") + }, + { + "cg_airstrikeKillCamFov", + "Airstrike kill camera field of view.", + generate_hash("cg_airstrikeKillCamFov") + }, + { + "cg_airstrikeKillCamNearBlur", + "", + generate_hash("cg_airstrikeKillCamNearBlur") + }, + { + "cg_airstrikeKillCamNearBlurEnd", + "", + generate_hash("cg_airstrikeKillCamNearBlurEnd") + }, + { + "cg_airstrikeKillCamNearBlurStart", + "", + generate_hash("cg_airstrikeKillCamNearBlurStart") + }, + { + "cg_blood", + "Show Blood", + generate_hash("cg_blood") + }, + { + "cg_bloodThickColor", + "Color of the blood overlay's thick blood splatter", + generate_hash("cg_bloodThickColor") + }, + { + "cg_bloodThinColor", + "Color of the blood overlay's thin blood splatter", + generate_hash("cg_bloodThinColor") + }, + { + "cg_brass", + "Weapons eject brass", + generate_hash("cg_brass") + }, + { + "cg_centertime", + "The time for a center printed message to fade", + generate_hash("cg_centertime") + }, + { + "cg_chatHeight", + "The font height of a chat message", + generate_hash("cg_chatHeight") + }, + { + "cg_chatTime", + "The amount of time that a chat message is visible", + generate_hash("cg_chatTime") + }, + { + "cg_ColorBlind_EnemyTeam", + "Enemy team color for color blind people", + generate_hash("cg_ColorBlind_EnemyTeam") + }, + { + "cg_ColorBlind_MyParty", + "Player party color for color blind people", + generate_hash("cg_ColorBlind_MyParty") + }, + { + "cg_ColorBlind_MyTeam", + "Player team color for color blind people", + generate_hash("cg_ColorBlind_MyTeam") + }, + { + "cg_connectionIconSize", + "Size of the connection icon", + generate_hash("cg_connectionIconSize") + }, + { + "cg_constantSizeHeadIcons", + "Head icons are the same size regardless of distance from the player", + generate_hash("cg_constantSizeHeadIcons") + }, + { + "cg_crosshairAlpha", + "The alpha value of the crosshair", + generate_hash("cg_crosshairAlpha") + }, + { + "cg_crosshairAlphaMin", + "The minimum alpha value of the crosshair when it fades in", + generate_hash("cg_crosshairAlphaMin") + }, + { + "cg_crosshairDynamic", + "Crosshair is Dynamic", + generate_hash("cg_crosshairDynamic") + }, + { + "cg_crosshairEnemyColor", + "The crosshair color when over an enemy", + generate_hash("cg_crosshairEnemyColor") + }, + { + "cg_crosshairVerticalOffset", + "Amount to vertically offset the crosshair from the center.", + generate_hash("cg_crosshairVerticalOffset") + }, + { + "cg_cullBulletAngle", + "Cull bullet trajectories that don't fall within this fov", + generate_hash("cg_cullBulletAngle") + }, + { + "cg_cullBullets", + "Whether to cull bullet fire prediction if trajectory doesn't pass your view or anywhere near you", + generate_hash("cg_cullBullets") + }, + { + "cg_cursorHints", + "Draw cursor hints where:\n 0: no hints", + generate_hash("cg_cursorHints") + }, + { + "cg_deadChatWithDead", + "If true, dead players can all chat together, regardless of team", + generate_hash("cg_deadChatWithDead") + }, + { + "cg_deadChatWithTeam", + "If true, dead players can talk to living players on their team", + generate_hash("cg_deadChatWithTeam") + }, + { + "cg_deadHearAllLiving", + "If true, dead players can hear all living players talk", + generate_hash("cg_deadHearAllLiving") + }, + { + "cg_deadHearTeamLiving", + "If true, dead players can hear living players on their team talk", + generate_hash("cg_deadHearTeamLiving") + }, + { + "cg_descriptiveText", + "Draw descriptive spectator messages", + generate_hash("cg_descriptiveText") + }, + { + "cg_draw2D", + "Draw 2D screen elements", + generate_hash("cg_draw2D") + }, + { + "cg_drawBreathHint", + "Draw a 'hold breath to steady' hint", + generate_hash("cg_drawBreathHint") + }, + { + "cg_drawBuildName", + "Draw build name", + generate_hash("cg_drawBuildName") + }, + { + "cg_drawCrosshair", + "Turn on weapon crosshair", + generate_hash("cg_drawCrosshair") + }, + { + "cg_drawCrosshairNames", + "Draw the name of an enemy under the crosshair", + generate_hash("cg_drawCrosshairNames") + }, + { + "cg_drawCrosshairNamesPosX", + "", + generate_hash("cg_drawCrosshairNamesPosX") + }, + { + "cg_drawCrosshairNamesPosY", + "", + generate_hash("cg_drawCrosshairNamesPosY") + }, + { + "cg_drawDamageDirection", + "Draw hit direction arrow.", + generate_hash("cg_drawDamageDirection") + }, + { + "cg_drawDamageFlash", + "Draw flash when hit.", + generate_hash("cg_drawDamageFlash") + }, + { + "cg_drawDoubleTapDetonateHint", + "Draw a 'double tap to detonate grenade' hint", + generate_hash("cg_drawDoubleTapDetonateHint") + }, + { + "cg_drawEffectNum", + "Draw counts of effects and elements", + generate_hash("cg_drawEffectNum") + }, + { + "cg_drawFPS", + "Draw frames per second", + generate_hash("cg_drawFPS") + }, + { + "cg_drawFPSLabels", + "Draw FPS Info Labels", + generate_hash("cg_drawFPSLabels") + }, + { + "cg_drawFriendlyHUDGrenades", + "Draw grenade warning indicators for friendly grenades (should be true if friendly-fire is enabled)", + generate_hash("cg_drawFriendlyHUDGrenades") + }, + { + "cg_drawFriendlyNames", + "Whether to show friendly names in game", + generate_hash("cg_drawFriendlyNames") + }, + { + "cg_drawFriendlyNamesAlways", + "Whether to always show friendly names in game (for certain gametypes)", + generate_hash("cg_drawFriendlyNamesAlways") + }, + { + "cg_drawGun", + "Draw the view model", + generate_hash("cg_drawGun") + }, + { + "cg_drawHealth", + "Draw health bar", + generate_hash("cg_drawHealth") + }, + { + "cg_drawMantleHint", + "Draw a 'press key to mantle' hint", + generate_hash("cg_drawMantleHint") + }, + { + "cg_drawMaterial", + "Draw debugging information for materials", + generate_hash("cg_drawMaterial") + }, + { + "cg_drawpaused", + "Draw paused screen", + generate_hash("cg_drawpaused") + }, + { + "cg_drawScriptUsage", + "Draw debugging information for scripts", + generate_hash("cg_drawScriptUsage") + }, + { + "cg_drawSnapshot", + "Draw debugging information for snapshots", + generate_hash("cg_drawSnapshot") + }, + { + "cg_drawStatsSource", + "Draw stats source", + generate_hash("cg_drawStatsSource") + }, + { + "cg_drawTalk", + "Controls which icons CG_TALKER ownerdraw draws", + generate_hash("cg_drawTalk") + }, + { + "cg_drawTurretCrosshair", + "Draw a cross hair when using a turret", + generate_hash("cg_drawTurretCrosshair") + }, + { + "cg_drawViewpos", + "Draw viewpos", + generate_hash("cg_drawViewpos") + }, + { + "cg_e3TrailerHacks", + "Tweaks for trailer recording", + generate_hash("cg_e3TrailerHacks") + }, + { + "cg_equipmentSounds", + "Play equipment sounds", + generate_hash("cg_equipmentSounds") + }, + { + "cg_errordecay", + "Decay for predicted error", + generate_hash("cg_errordecay") + }, + { + "cg_everyoneHearsEveryone", + "If true, all players can all chat together, regardless of team or death", + generate_hash("cg_everyoneHearsEveryone") + }, + { + "cg_explosiveKillCamBackDist", + "Explosive kill camera: distance of camera backwards from explosive.", + generate_hash("cg_explosiveKillCamBackDist") + }, + { + "cg_explosiveKillCamGroundBackDist", + "Explosive kill camera when stuck to ground: distance of camera backwards from explosive.", + generate_hash("cg_explosiveKillCamGroundBackDist") + }, + { + "cg_explosiveKillCamGroundUpDist", + "Explosive kill camera when stuck to ground: distance of camera backwards from explosive.", + generate_hash("cg_explosiveKillCamGroundUpDist") + }, + { + "cg_explosiveKillCamStopDecelDist", + "Rocket and Grenade Launcher kill camera: distance from player to begin coming to rest", + generate_hash("cg_explosiveKillCamStopDecelDist") + }, + { + "cg_explosiveKillCamStopDist", + "Rocket and Grenade Launcher kill camera: distance from player to begin coming to rest", + generate_hash("cg_explosiveKillCamStopDist") + }, + { + "cg_explosiveKillCamUpDist", + "Explosive kill camera: distance of camera backwards from explosive.", + generate_hash("cg_explosiveKillCamUpDist") + }, + { + "cg_explosiveKillCamWallOutDist", + "Explosive kill camera when stuck to wall: distance of camera out from wall.", + generate_hash("cg_explosiveKillCamWallOutDist") + }, + { + "cg_explosiveKillCamWallSideDist", + "Explosive kill camera when stuck to wall: distance of camera out from wall.", + generate_hash("cg_explosiveKillCamWallSideDist") + }, + { + "cg_flashbangNameFadeIn", + "Time in milliseconds to fade in friendly names", + generate_hash("cg_flashbangNameFadeIn") + }, + { + "cg_flashbangNameFadeOut", + "Time in milliseconds to fade out friendly names", + generate_hash("cg_flashbangNameFadeOut") + }, + { + "cg_foliagesnd_alias", + "The sound that plays when an actor or player enters a foliage clip brush.", + generate_hash("cg_foliagesnd_alias") + }, + { + "cg_footsteps", + "Play footstep sounds that are NOT sprint", + generate_hash("cg_footsteps") + }, + { + "cg_footstepsSprint", + "Play sprint footstep sounds", + generate_hash("cg_footstepsSprint") + }, + { + "cg_fov", + "The field of view angle in degrees", + generate_hash("cg_fov") + }, + { + "cg_fovMin", + "The minimum possible field of view", + generate_hash("cg_fovMin") + }, + { + "cg_fovScale", + "Scale applied to the field of view", + generate_hash("cg_fovScale") + }, + { + "cg_friendlyNameFadeIn", + "Time in milliseconds to fade in friendly names", + generate_hash("cg_friendlyNameFadeIn") + }, + { + "cg_friendlyNameFadeOut", + "Time in milliseconds to fade out friendly names", + generate_hash("cg_friendlyNameFadeOut") + }, + { + "cg_gameBoldMessageWidth", + "The maximum character width of the bold game messages", + generate_hash("cg_gameBoldMessageWidth") + }, + { + "cg_gameMessageWidth", + "The maximum character width of the game messages", + generate_hash("cg_gameMessageWidth") + }, + { + "cg_gun_x", + "Forward position of the viewmodel", + generate_hash("cg_gun_x") + }, + { + "cg_gun_y", + "Right position of the viewmodel", + generate_hash("cg_gun_y") + }, + { + "cg_gun_z", + "Up position of the viewmodel", + generate_hash("cg_gun_z") + }, + { + "cg_headIconMinScreenRadius", + "The minumum radius of a head icon on the screen", + generate_hash("cg_headIconMinScreenRadius") + }, + { + "cg_hearKillerTime", + "Duration (in milliseconds) to hear the person you just killed", + generate_hash("cg_hearKillerTime") + }, + { + "cg_hearVictimEnabled", + "If true, you can hear the person you just killed", + generate_hash("cg_hearVictimEnabled") + }, + { + "cg_hearVictimTime", + "Duration (in milliseconds) to hear the person you just killed", + generate_hash("cg_hearVictimTime") + }, + { + "cg_heliKillCamFarBlur", + "", + generate_hash("cg_heliKillCamFarBlur") + }, + { + "cg_heliKillCamFarBlurDist", + "", + generate_hash("cg_heliKillCamFarBlurDist") + }, + { + "cg_heliKillCamFarBlurStart", + "", + generate_hash("cg_heliKillCamFarBlurStart") + }, + { + "cg_heliKillCamFov", + "Helicopter kill camera field of view.", + generate_hash("cg_heliKillCamFov") + }, + { + "cg_heliKillCamFstop", + "Helicopter kill camera aperture. Lower f-stop yields a shallower depth of field. Typical values range from 1 to 22", + generate_hash("cg_heliKillCamFstop") + }, + { + "cg_heliKillCamNearBlur", + "", + generate_hash("cg_heliKillCamNearBlur") + }, + { + "cg_heliKillCamNearBlurEnd", + "", + generate_hash("cg_heliKillCamNearBlurEnd") + }, + { + "cg_heliKillCamNearBlurStart", + "", + generate_hash("cg_heliKillCamNearBlurStart") + }, + { + "cg_hintFadeTime", + "Time in milliseconds for the cursor hint to fade", + generate_hash("cg_hintFadeTime") + }, + { + "cg_hudChatIntermissionPosition", + "Position of the HUD chat box during intermission", + generate_hash("cg_hudChatIntermissionPosition") + }, + { + "cg_hudChatPosition", + "Position of the HUD chat box", + generate_hash("cg_hudChatPosition") + }, + { + "cg_hudDamageIconHeight", + "The height of the damage icon", + generate_hash("cg_hudDamageIconHeight") + }, + { + "cg_hudDamageIconInScope", + "Draw damage icons when aiming down the sight of a scoped weapon", + generate_hash("cg_hudDamageIconInScope") + }, + { + "cg_hudDamageIconOffset", + "The offset from the center of the damage icon", + generate_hash("cg_hudDamageIconOffset") + }, + { + "cg_hudDamageIconOverlayTime", + "The amount of time (in ms) for the overlay portion of the damage icon to stay on screen", + generate_hash("cg_hudDamageIconOverlayTime") + }, + { + "cg_hudDamageIconStartFadeTime", + "The amount of time (in ms) before the damage icon begins to fade", + generate_hash("cg_hudDamageIconStartFadeTime") + }, + { + "cg_hudDamageIconTime", + "The amount of time for the damage icon to stay on screen after damage is taken", + generate_hash("cg_hudDamageIconTime") + }, + { + "cg_hudDamageIconWidth", + "The width of the damage icon", + generate_hash("cg_hudDamageIconWidth") + }, + { + "cg_hudGrenadeIconEnabledFlash", + "Show the grenade indicator for flash grenades", + generate_hash("cg_hudGrenadeIconEnabledFlash") + }, + { + "cg_hudGrenadeIconHeight", + "The height of the grenade indicator icon", + generate_hash("cg_hudGrenadeIconHeight") + }, + { + "cg_hudGrenadeIconInScope", + "Show the grenade indicator when aiming down the sight of a scoped weapon", + generate_hash("cg_hudGrenadeIconInScope") + }, + { + "cg_hudGrenadeIconMaxRangeFlash", + "The minimum distance that a flashbang has to be from a player in order to be shown on the grenade indicator", + generate_hash("cg_hudGrenadeIconMaxRangeFlash") + }, + { + "cg_hudGrenadeIconMaxRangeFrag", + "The minimum distance that a grenade has to be from a player in order to be shown on the grenade indicator", + generate_hash("cg_hudGrenadeIconMaxRangeFrag") + }, + { + "cg_hudGrenadeIconOffset", + "The offset from the center of the screen for a grenade icon", + generate_hash("cg_hudGrenadeIconOffset") + }, + { + "cg_hudGrenadeIconWidth", + "The width of the grenade indicator icon", + generate_hash("cg_hudGrenadeIconWidth") + }, + { + "cg_hudGrenadePointerHeight", + "The height of the grenade indicator pointer", + generate_hash("cg_hudGrenadePointerHeight") + }, + { + "cg_hudGrenadePointerPivot", + "The pivot point of th grenade indicator pointer", + generate_hash("cg_hudGrenadePointerPivot") + }, + { + "cg_hudGrenadePointerPulseFreq", + "The number of times per second that the grenade indicator flashes in Hertz", + generate_hash("cg_hudGrenadePointerPulseFreq") + }, + { + "cg_hudGrenadePointerPulseMax", + "The maximum alpha of the grenade indicator pulse. Values higher than 1 will cause the indicator to remain at full brightness for longer", + generate_hash("cg_hudGrenadePointerPulseMax") + }, + { + "cg_hudGrenadePointerPulseMin", + "The minimum alpha of the grenade indicator pulse. Values lower than 0 will cause the indicator to remain at full transparency for longer", + generate_hash("cg_hudGrenadePointerPulseMin") + }, + { + "cg_hudGrenadePointerWidth", + "The width of the grenade indicator pointer", + generate_hash("cg_hudGrenadePointerWidth") + }, + { + "cg_hudLegacySplitscreenScale", + "Screen scale for hud elements in splitscreen", + generate_hash("cg_hudLegacySplitscreenScale") + }, + { + "cg_hudLighting_basic_additiveLumOffset", + "[basic] Offset applied to additive light color.", + generate_hash("cg_hudLighting_basic_additiveLumOffset") + }, + { + "cg_hudLighting_basic_additiveLumScale", + "[basic] Scale applied to additive light color.", + generate_hash("cg_hudLighting_basic_additiveLumScale") + }, + { + "cg_hudLighting_basic_additiveOffset", + "", + generate_hash("cg_hudLighting_basic_additiveOffset") + }, + { + "cg_hudLighting_basic_additiveScale", + "", + generate_hash("cg_hudLighting_basic_additiveScale") + }, + { + "cg_hudLighting_basic_ambientLumOffset", + "[basic] Offset applied to ambient light color.", + generate_hash("cg_hudLighting_basic_ambientLumOffset") + }, + { + "cg_hudLighting_basic_ambientLumScale", + "[basic] Scale applied to ambient light color.", + generate_hash("cg_hudLighting_basic_ambientLumScale") + }, + { + "cg_hudLighting_basic_ambientOffset", + "", + generate_hash("cg_hudLighting_basic_ambientOffset") + }, + { + "cg_hudLighting_basic_ambientScale", + "", + generate_hash("cg_hudLighting_basic_ambientScale") + }, + { + "cg_hudLighting_basic_diffuseLumOffset", + "[basic] Offset applied to diffuse light color.", + generate_hash("cg_hudLighting_basic_diffuseLumOffset") + }, + { + "cg_hudLighting_basic_diffuseLumScale", + "[basic] Scale applied to diffuse light color.", + generate_hash("cg_hudLighting_basic_diffuseLumScale") + }, + { + "cg_hudLighting_basic_diffuseOffset", + "", + generate_hash("cg_hudLighting_basic_diffuseOffset") + }, + { + "cg_hudLighting_basic_diffuseScale", + "", + generate_hash("cg_hudLighting_basic_diffuseScale") + }, + { + "cg_hudLighting_basic_specExponent", + "[basic] Specular exponent. Higher values result in sharper highlights.", + generate_hash("cg_hudLighting_basic_specExponent") + }, + { + "cg_hudLighting_basic_specLumOffset", + "[basic] Offset applied to spec light luminance.", + generate_hash("cg_hudLighting_basic_specLumOffset") + }, + { + "cg_hudLighting_basic_specLumScale", + "[basic] Scale applied to spec light luminance.", + generate_hash("cg_hudLighting_basic_specLumScale") + }, + { + "cg_hudLighting_basic_specOffset", + "", + generate_hash("cg_hudLighting_basic_specOffset") + }, + { + "cg_hudLighting_basic_specScale", + "", + generate_hash("cg_hudLighting_basic_specScale") + }, + { + "cg_hudLighting_blood_additiveLumOffset", + "[blood] Offset applied to additive light color.", + generate_hash("cg_hudLighting_blood_additiveLumOffset") + }, + { + "cg_hudLighting_blood_additiveLumScale", + "[blood] Scale applied to additive light color.", + generate_hash("cg_hudLighting_blood_additiveLumScale") + }, + { + "cg_hudLighting_blood_additiveOffset", + "", + generate_hash("cg_hudLighting_blood_additiveOffset") + }, + { + "cg_hudLighting_blood_additiveScale", + "", + generate_hash("cg_hudLighting_blood_additiveScale") + }, + { + "cg_hudLighting_blood_ambientLumOffset", + "[blood] Offset applied to ambient light color.", + generate_hash("cg_hudLighting_blood_ambientLumOffset") + }, + { + "cg_hudLighting_blood_ambientLumScale", + "[blood] Scale applied to ambient light color.", + generate_hash("cg_hudLighting_blood_ambientLumScale") + }, + { + "cg_hudLighting_blood_ambientOffset", + "", + generate_hash("cg_hudLighting_blood_ambientOffset") + }, + { + "cg_hudLighting_blood_ambientScale", + "", + generate_hash("cg_hudLighting_blood_ambientScale") + }, + { + "cg_hudLighting_blood_diffuseLumOffset", + "[blood] Offset applied to diffuse light color.", + generate_hash("cg_hudLighting_blood_diffuseLumOffset") + }, + { + "cg_hudLighting_blood_diffuseLumScale", + "[blood] Scale applied to diffuse light color.", + generate_hash("cg_hudLighting_blood_diffuseLumScale") + }, + { + "cg_hudLighting_blood_diffuseOffset", + "", + generate_hash("cg_hudLighting_blood_diffuseOffset") + }, + { + "cg_hudLighting_blood_diffuseScale", + "", + generate_hash("cg_hudLighting_blood_diffuseScale") + }, + { + "cg_hudLighting_blood_specExponent", + "[blood] Specular exponent. Higher values result in sharper highlights.", + generate_hash("cg_hudLighting_blood_specExponent") + }, + { + "cg_hudLighting_blood_specLumOffset", + "[blood] Offset applied to spec light luminance.", + generate_hash("cg_hudLighting_blood_specLumOffset") + }, + { + "cg_hudLighting_blood_specLumScale", + "[blood] Scale applied to spec light luminance.", + generate_hash("cg_hudLighting_blood_specLumScale") + }, + { + "cg_hudLighting_blood_specOffset", + "", + generate_hash("cg_hudLighting_blood_specOffset") + }, + { + "cg_hudLighting_blood_specScale", + "", + generate_hash("cg_hudLighting_blood_specScale") + }, + { + "cg_hudLighting_fadeSharpness", + "This controls how sharp the lines are when fading using the mask alpha. Higher values are sharper.", + generate_hash("cg_hudLighting_fadeSharpness") + }, + { + "cg_hudMapBorderWidth", + "The size of the full map's border, filled by the CG_PLAYER_FULLMAP_BORDER ownerdraw", + generate_hash("cg_hudMapBorderWidth") + }, + { + "cg_hudMapFriendlyHeight", + "", + generate_hash("cg_hudMapFriendlyHeight") + }, + { + "cg_hudMapFriendlyWidth", + "", + generate_hash("cg_hudMapFriendlyWidth") + }, + { + "cg_hudMapPlayerHeight", + "", + generate_hash("cg_hudMapPlayerHeight") + }, + { + "cg_hudMapPlayerWidth", + "", + generate_hash("cg_hudMapPlayerWidth") + }, + { + "cg_hudMapRadarLineThickness", + "Thickness, relative to the map width, of the radar texture that sweeps across the full screen map", + generate_hash("cg_hudMapRadarLineThickness") + }, + { + "cg_hudObjectiveTextScale", + "", + generate_hash("cg_hudObjectiveTextScale") + }, + { + "cg_hudProneY", + "Virtual screen y coordinate of the prone blocked message", + generate_hash("cg_hudProneY") + }, + { + "cg_hudSayPosition", + "Position of the HUD say box", + generate_hash("cg_hudSayPosition") + }, + { + "cg_hudSplitscreenCompassElementScale", + "Scale value to apply to compass elements in splitscreen", + generate_hash("cg_hudSplitscreenCompassElementScale") + }, + { + "cg_hudSplitscreenCompassScale", + "Scale value to apply to the compass in splitscreen", + generate_hash("cg_hudSplitscreenCompassScale") + }, + { + "cg_hudSplitscreenStanceScale", + "Scale value to apply to the stance HUD element in splitscreen", + generate_hash("cg_hudSplitscreenStanceScale") + }, + { + "cg_hudStanceFlash", + "The background color of the flash when the stance changes", + generate_hash("cg_hudStanceFlash") + }, + { + "cg_hudVotePosition", + "Position of the HUD vote box", + generate_hash("cg_hudVotePosition") + }, + { + "cg_invalidCmdHintBlinkInterval", + "Blink rate of an invalid command hint", + generate_hash("cg_invalidCmdHintBlinkInterval") + }, + { + "cg_invalidCmdHintDuration", + "Duration of an invalid command hint", + generate_hash("cg_invalidCmdHintDuration") + }, + { + "cg_javelinKillCamCloseZDist", + "Javelin kill camera: closest distance above the target.", + generate_hash("cg_javelinKillCamCloseZDist") + }, + { + "cg_javelinKillCamDownDist", + "Javelin kill camera: distance to follow during ascent.", + generate_hash("cg_javelinKillCamDownDist") + }, + { + "cg_javelinKillCamFov", + "Javelin kill camera: fov", + generate_hash("cg_javelinKillCamFov") + }, + { + "cg_javelinKillCamLookLerpDist", + "Javelin kill camera: distance over which to lerp to look at player during descent. A value of zero means don't lerp at all.", + generate_hash("cg_javelinKillCamLookLerpDist") + }, + { + "cg_javelinKillCamPassDist", + "Javelin kill camera: distance away when passing.", + generate_hash("cg_javelinKillCamPassDist") + }, + { + "cg_javelinKillCamPassTime", + "Javelin kill camera: time in seconds to pass javelin on the way up", + generate_hash("cg_javelinKillCamPassTime") + }, + { + "cg_javelinKillCamUpDist", + "Javelin kill camera: distance to follow during ascent.", + generate_hash("cg_javelinKillCamUpDist") + }, + { + "cg_killCamDefaultLerpTime", + "Default time used to lerp between killcam entities.", + generate_hash("cg_killCamDefaultLerpTime") + }, + { + "cg_killCamTurretLerpTime", + "Time used to lerp to a killcam entity of the TURRET type.", + generate_hash("cg_killCamTurretLerpTime") + }, + { + "cg_landingSounds", + "Play landing on surface sounds", + generate_hash("cg_landingSounds") + }, + { + "cg_largeExplosiveKillCamBackDist", + "Large Explosive kill camera: distance of camera backwards from explosive.", + generate_hash("cg_largeExplosiveKillCamBackDist") + }, + { + "cg_largeExplosiveKillCamUpDist", + "Large Explosive kill camera: distance of camera backwards from explosive.", + generate_hash("cg_largeExplosiveKillCamUpDist") + }, + { + "cg_mapLocationSelectionCursorSpeed", + "Speed of the cursor when selecting a location on the map", + generate_hash("cg_mapLocationSelectionCursorSpeed") + }, + { + "cg_marks_ents_player_only", + "Marks on entities from players' bullets only.", + generate_hash("cg_marks_ents_player_only") + }, + { + "cg_minCullBulletDist", + "Don't cull bullet trajectories that are within this distance to you.", + generate_hash("cg_minCullBulletDist") + }, + { + "cg_objectiveText", + "", + generate_hash("cg_objectiveText") + }, + { + "cg_overheadIconSize", + "The maximum size to show overhead icons like 'rank'", + generate_hash("cg_overheadIconSize") + }, + { + "cg_overheadNamesFarDist", + "The far distance at which name sizes are scaled by cg_overheadNamesFarScale", + generate_hash("cg_overheadNamesFarDist") + }, + { + "cg_overheadNamesFarScale", + "The amount to scale overhead name sizes at cg_overheadNamesFarDist", + generate_hash("cg_overheadNamesFarScale") + }, + { + "cg_overheadNamesFont", + "Font for overhead names ( see menudefinition.h )", + generate_hash("cg_overheadNamesFont") + }, + { + "cg_overheadNamesGlow", + "Glow color for overhead names", + generate_hash("cg_overheadNamesGlow") + }, + { + "cg_overheadNamesMaxDist", + "The maximum distance for showing friendly player names", + generate_hash("cg_overheadNamesMaxDist") + }, + { + "cg_overheadNamesNearDist", + "The near distance at which names are full size", + generate_hash("cg_overheadNamesNearDist") + }, + { + "cg_overheadNamesSize", + "The maximum size to show overhead names", + generate_hash("cg_overheadNamesSize") + }, + { + "cg_overheadRankSize", + "The size to show rank text", + generate_hash("cg_overheadRankSize") + }, + { + "cg_remoteMissileKillCamBackDist", + "Remote missile kill camera: distance of camera backwards from rocket.", + generate_hash("cg_remoteMissileKillCamBackDist") + }, + { + "cg_remoteMissileKillCamUpDist", + "Remote missile kill camera: distance of camera backwards from rocket.", + generate_hash("cg_remoteMissileKillCamUpDist") + }, + { + "cg_rocketKillCamBackDist", + "Rocket kill camera: distance of camera backwards from rocket.", + generate_hash("cg_rocketKillCamBackDist") + }, + { + "cg_rocketKillCamUpDist", + "Rocket kill camera: distance of camera backwards from rocket.", + generate_hash("cg_rocketKillCamUpDist") + }, + { + "cg_scriptIconSize", + "Size of Icons defined by script", + generate_hash("cg_scriptIconSize") + }, + { + "cg_showmiss", + "Show prediction errors", + generate_hash("cg_showmiss") + }, + { + "cg_sprintMeterDisabledColor", + "The color of the sprint meter when the sprint meter is full", + generate_hash("cg_sprintMeterDisabledColor") + }, + { + "cg_sprintMeterEmptyColor", + "The color of the sprint meter when the sprint meter is full", + generate_hash("cg_sprintMeterEmptyColor") + }, + { + "cg_sprintMeterFullColor", + "The color of the sprint meter when the sprint meter is full", + generate_hash("cg_sprintMeterFullColor") + }, + { + "cg_subtitleMinTime", + "The minimum time that the subtitles are displayed on screen in seconds", + generate_hash("cg_subtitleMinTime") + }, + { + "cg_subtitleWidthStandard", + "The width of the subtitles on a non wide-screen", + generate_hash("cg_subtitleWidthStandard") + }, + { + "cg_subtitleWidthWidescreen", + "The width of the subtitle on a wide-screen", + generate_hash("cg_subtitleWidthWidescreen") + }, + { + "cg_teamChatsOnly", + "Allow chatting only on the same team", + generate_hash("cg_teamChatsOnly") + }, + { + "cg_TeamColor_Allies", + "Allies team color", + generate_hash("cg_TeamColor_Allies") + }, + { + "cg_TeamColor_Axis", + "Axis team color", + generate_hash("cg_TeamColor_Axis") + }, + { + "cg_TeamColor_EnemyTeam", + "Enemy team color", + generate_hash("cg_TeamColor_EnemyTeam") + }, + { + "cg_TeamColor_Free", + "Free Team color", + generate_hash("cg_TeamColor_Free") + }, + { + "cg_TeamColor_MyParty", + "Player team color when in the same party", + generate_hash("cg_TeamColor_MyParty") + }, + { + "cg_TeamColor_MyTeam", + "Player team color", + generate_hash("cg_TeamColor_MyTeam") + }, + { + "cg_TeamColor_Spectator", + "Spectator team color", + generate_hash("cg_TeamColor_Spectator") + }, + { + "cg_turretKillCamBackDist", + "Turret kill camera: distance of camera backwards from Turret.", + generate_hash("cg_turretKillCamBackDist") + }, + { + "cg_turretKillCamFov", + "Turret kill camera field of view.", + generate_hash("cg_turretKillCamFov") + }, + { + "cg_turretKillCamUpDist", + "Turret kill camera: distance of camera backwards from Turret.", + generate_hash("cg_turretKillCamUpDist") + }, + { + "cg_turretRemoteKillCamBackDist", + "Remote Turret kill camera: distance of camera backwards from Turret.", + generate_hash("cg_turretRemoteKillCamBackDist") + }, + { + "cg_turretRemoteKillCamFov", + "Remote Turret kill camera field of view.", + generate_hash("cg_turretRemoteKillCamFov") + }, + { + "cg_turretRemoteKillCamUpDist", + "Remote Turret kill camera: distance of camera backwards from Turret.", + generate_hash("cg_turretRemoteKillCamUpDist") + }, + { + "cg_vectorFieldsForceUniform", + "Forces all vector field assets to represent a single, uniform direction", + generate_hash("cg_vectorFieldsForceUniform") + }, + { + "cg_viewVehicleInfluence", + "The influence on the view angles from being in a vehicle", + generate_hash("cg_viewVehicleInfluence") + }, + { + "cg_viewZSmoothingMax", + "Threshhold for the maximum smoothing distance we'll do", + generate_hash("cg_viewZSmoothingMax") + }, + { + "cg_viewZSmoothingMin", + "Threshhold for the minimum smoothing distance it must move to smooth", + generate_hash("cg_viewZSmoothingMin") + }, + { + "cg_viewZSmoothingTime", + "Amount of time to spread the smoothing over", + generate_hash("cg_viewZSmoothingTime") + }, + { + "cg_voiceIconSize", + "Size of the 'voice' icon", + generate_hash("cg_voiceIconSize") + }, + { + "cg_waterSheeting_distortionScaleFactor", + "Distortion uv scales (Default to 1)", + generate_hash("cg_waterSheeting_distortionScaleFactor") + }, + { + "cg_waterSheeting_magnitude", + "Distortion magnitude", + generate_hash("cg_waterSheeting_magnitude") + }, + { + "cg_waterSheeting_radius", + "Tweak dev var; Glow radius in pixels at 640x480", + generate_hash("cg_waterSheeting_radius") + }, + { + "cg_weapHitCullAngle", + "Angle of cone within which to cull back facing weapon hit effects", + generate_hash("cg_weapHitCullAngle") + }, + { + "cg_weapHitCullEnable", + "When true, cull back facing weapon hit fx.", + generate_hash("cg_weapHitCullEnable") + }, + { + "cg_weaponCycleDelay", + "The delay after cycling to a new weapon to prevent holding down the cycle weapon button from cycling too fast", + generate_hash("cg_weaponCycleDelay") + }, + { + "cg_weaponHintsCoD1Style", + "Draw weapon hints in CoD1 style: with the weapon name, and with the icon below", + generate_hash("cg_weaponHintsCoD1Style") + }, + { + "cg_weaponVisInterval", + "Do weapon vis checks once per this many frames, per centity", + generate_hash("cg_weaponVisInterval") + }, + { + "cg_youInKillCamSize", + "Size of the 'you' Icon in the kill cam", + generate_hash("cg_youInKillCamSize") + }, + { + "cl_anglespeedkey", + "Multiplier for max angle speed for game pad and keyboard", + generate_hash("cl_anglespeedkey") + }, + { + "cl_bypassMouseInput", + "Bypass UI mouse input and send directly to the game", + generate_hash("cl_bypassMouseInput") + }, + { + "cl_connectionAttempts", + "Maximum number of connection attempts before aborting", + generate_hash("cl_connectionAttempts") + }, + { + "cl_connectTimeout", + "Timeout time in seconds while connecting to a server", + generate_hash("cl_connectTimeout") + }, + { + "cl_demo_uploadfb", + "Should we upload to FB", + generate_hash("cl_demo_uploadfb") + }, + { + "cl_dirSelConvergenceTime", + "Time to converge to the new direction when selecting a direction on the map.", + generate_hash("cl_dirSelConvergenceTime") + }, + { + "cl_force_paused", + "Force the client to be paused. Can't be overridden by LUA scripts, the start button, etc.", + generate_hash("cl_force_paused") + }, + { + "cl_freelook", + "Enable looking with mouse", + generate_hash("cl_freelook") + }, + { + "cl_hudDrawsBehindUI", + "Should the HUD draw when the UI is up?", + generate_hash("cl_hudDrawsBehindUI") + }, + { + "cl_ingame", + "True if the game is active", + generate_hash("cl_ingame") + }, + { + "cl_inhibit_stats_upload", + "Inhibit upload of stats during demo playback", + generate_hash("cl_inhibit_stats_upload") + }, + { + "cl_lessprint", + "Print less to the console by filtering out certain spammy channels", + generate_hash("cl_lessprint") + }, + { + "cl_maxpackets", + "Maximum number of packets sent per frame", + generate_hash("cl_maxpackets") + }, + { + "cl_maxPing", + "Maximum ping for the client", + generate_hash("cl_maxPing") + }, + { + "cl_migrationTimeout", + "Seconds to wait to hear from new host during host migration before timeout occurs", + generate_hash("cl_migrationTimeout") + }, + { + "cl_modifiedDebugPlacement", + "Modify the location of debug output (outside of safe area)", + generate_hash("cl_modifiedDebugPlacement") + }, + { + "cl_motdString", + "", + generate_hash("cl_motdString") + }, + { + "cl_mouseAccel", + "Mouse acceleration", + generate_hash("cl_mouseAccel") + }, + { + "cl_noprint", + "Print nothing to the console", + generate_hash("cl_noprint") + }, + { + "cl_packetdup", + "Enable packet duplication", + generate_hash("cl_packetdup") + }, + { + "cl_pauseAudioZoneEnabled", + "Enable the paused audio zone when the menus are up", + generate_hash("cl_pauseAudioZoneEnabled") + }, + { + "cl_paused", + "Pause the game", + generate_hash("cl_paused") + }, + { + "cl_pitchspeed", + "Max pitch speed in degrees for game pad", + generate_hash("cl_pitchspeed") + }, + { + "cl_pranks", + "pranks", + generate_hash("cl_pranks") + }, + { + "cl_pushToTalk", + "Do we have to press a button to talk", + generate_hash("cl_pushToTalk") + }, + { + "cl_serverStatusResendTime", + "Time in milliseconds to resend a server status message", + generate_hash("cl_serverStatusResendTime") + }, + { + "cl_showmouserate", + "Print mouse rate debugging information to the console", + generate_hash("cl_showmouserate") + }, + { + "cl_textChatEnabled", + "Do we want to use text chat", + generate_hash("cl_textChatEnabled") + }, + { + "cl_timeout", + "Seconds with no received packets until a timeout occurs", + generate_hash("cl_timeout") + }, + { + "cl_voice", + "Use voice communications", + generate_hash("cl_voice") + }, + { + "cl_yawspeed", + "Max yaw speed in degrees for game pad and keyboard", + generate_hash("cl_yawspeed") + }, + { + "clientSideEffects", + "Enable loading _fx.gsc files on the client", + generate_hash("clientSideEffects") + }, + { + "cod_anywhere_errorMessage", + "CoD Anywhere error message", + generate_hash("cod_anywhere_errorMessage") + }, + { + "cod_anywhere_showPopup", + "Temp Development: Should we show the CoD Anywhere popup", + generate_hash("cod_anywhere_showPopup") + }, + { + "cod_anywhere_single_task_popup_text", + "CoD Anywhere success message", + generate_hash("cod_anywhere_single_task_popup_text") + }, + { + "com_animCheck", + "Check anim tree", + generate_hash("com_animCheck") + }, + { + "com_cinematicEndInWhite", + "Set by script. True if cinematic ends with a white screen.", + generate_hash("com_cinematicEndInWhite") + }, + { + "com_completionResolveCommand", + "Command to run when the message box successfully closes", + generate_hash("com_completionResolveCommand") + }, + { + "com_errorMessage", + "Most recent error message", + generate_hash("com_errorMessage") + }, + { + "com_errorResolveCommand", + "Command to run when they close the error box", + generate_hash("com_errorResolveCommand") + }, + { + "com_filter_output", + "Use console filters for filtering output.", + generate_hash("com_filter_output") + }, + { + "com_maxfps", + "Cap frames per second", + generate_hash("com_maxfps") + }, + { + "com_maxFrameTime", + "Time slows down if a frame takes longer than this many milliseconds", + generate_hash("com_maxFrameTime") + }, + { + "com_playerProfile", + "Set to the name of the profile", + generate_hash("com_playerProfile") + }, + { + "com_recommendedSet", + "", + generate_hash("com_recommendedSet") + }, + { + "commerce_dl_retry_step", + "Step in m/s for the commerce download retry", + generate_hash("commerce_dl_retry_step") + }, + { + "commerce_manifest_file_max_retry_time", + "Max time that the commerce manifest can retry", + generate_hash("commerce_manifest_file_max_retry_time") + }, + { + "commerce_manifest_file_retry_step", + "Step in m/s for the commerce manifest retry", + generate_hash("commerce_manifest_file_retry_step") + }, + { + "commerce_max_dl_retry_time", + "Max time that the commerce download can retry", + generate_hash("commerce_max_dl_retry_time") + }, + { + "commerce_max_retry_time", + "Max time that the commerce upload can retry", + generate_hash("commerce_max_retry_time") + }, + { + "commerce_retry_step", + "Step in m/s for the commerce upload retry", + generate_hash("commerce_retry_step") + }, + { + "compass", + "Display Compass", + generate_hash("compass") + }, + { + "compassClampIcons", + "If true, friendlies and enemy pings clamp to the edge of the radar. If false, they disappear off the edge.", + generate_hash("compassClampIcons") + }, + { + "compassCoords", + "x = North-South coord base value, \ny = East-West coord base value, \nz = scale (game units per coord unit)", + generate_hash("compassCoords") + }, + { + "compassECoordCutoff", + "Left cutoff for the scrolling east-west coords", + generate_hash("compassECoordCutoff") + }, + { + "compassFriendlyHeight", + "", + generate_hash("compassFriendlyHeight") + }, + { + "compassFriendlyWidth", + "", + generate_hash("compassFriendlyWidth") + }, + { + "compassHideSansObjectivePointer", + "Hide the compass, but leave the obective pointer visible.", + generate_hash("compassHideSansObjectivePointer") + }, + { + "compassHideVehicles", + "When enabled, disables the CG_PLAYER_COMPASS_VEHICLES ownerdraw.", + generate_hash("compassHideVehicles") + }, + { + "compassMaxRange", + "The maximum range from the player in world space that objects will be shown on the compass", + generate_hash("compassMaxRange") + }, + { + "compassMinRadius", + "The minimum radius from the center of the compass that objects will appear.", + generate_hash("compassMinRadius") + }, + { + "compassMinRange", + "The minimum range from the player in world space that objects will appear on the compass", + generate_hash("compassMinRange") + }, + { + "compassObjectiveArrowHeight", + "", + generate_hash("compassObjectiveArrowHeight") + }, + { + "compassObjectiveArrowOffset", + "The offset of the objective arrow inward from the edge of the compass map", + generate_hash("compassObjectiveArrowOffset") + }, + { + "compassObjectiveArrowRotateDist", + "Distance from the corner of the compass map at which the objective arrow rotates to 45 degrees", + generate_hash("compassObjectiveArrowRotateDist") + }, + { + "compassObjectiveArrowWidth", + "", + generate_hash("compassObjectiveArrowWidth") + }, + { + "compassObjectiveDetailDist", + "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape.", + generate_hash("compassObjectiveDetailDist") + }, + { + "compassObjectiveDrawLines", + "Draw horizontal and vertical lines to the active target, if it is within the minimap boundries", + generate_hash("compassObjectiveDrawLines") + }, + { + "compassObjectiveHeight", + "", + generate_hash("compassObjectiveHeight") + }, + { + "compassObjectiveIconHeight", + "", + generate_hash("compassObjectiveIconHeight") + }, + { + "compassObjectiveIconWidth", + "", + generate_hash("compassObjectiveIconWidth") + }, + { + "compassObjectiveMaxHeight", + "The maximum height that an objective is considered to be on this level", + generate_hash("compassObjectiveMaxHeight") + }, + { + "compassObjectiveMaxRange", + "The maximum range at which an objective is visible on the compass", + generate_hash("compassObjectiveMaxRange") + }, + { + "compassObjectiveMinAlpha", + "The minimum alpha for an objective at the edge of the compass", + generate_hash("compassObjectiveMinAlpha") + }, + { + "compassObjectiveMinDistRange", + "The distance that objective transition effects play over, centered on compassObjectiveNearbyDist.", + generate_hash("compassObjectiveMinDistRange") + }, + { + "compassObjectiveMinHeight", + "The minimum height that an objective is considered to be on this level", + generate_hash("compassObjectiveMinHeight") + }, + { + "compassObjectiveNearbyDist", + "When an objective is closer than this distance (in meters), the icon will not be drawn on the tickertape.", + generate_hash("compassObjectiveNearbyDist") + }, + { + "compassObjectiveNumRings", + "The number of rings when a new objective appears", + generate_hash("compassObjectiveNumRings") + }, + { + "compassObjectiveRingSize", + "The maximum objective ring sige when a new objective appears on the compass", + generate_hash("compassObjectiveRingSize") + }, + { + "compassObjectiveRingTime", + "The amount of time between each ring when an objective appears", + generate_hash("compassObjectiveRingTime") + }, + { + "compassObjectiveTextHeight", + "Objective text height", + generate_hash("compassObjectiveTextHeight") + }, + { + "compassObjectiveTextScale", + "Scale to apply to hud objectives", + generate_hash("compassObjectiveTextScale") + }, + { + "compassObjectiveWidth", + "", + generate_hash("compassObjectiveWidth") + }, + { + "compassObjectiveWraparoundTime", + "How long it takes for the objective to wrap around the compass from one edge to the other", + generate_hash("compassObjectiveWraparoundTime") + }, + { + "compassPlayerHeight", + "", + generate_hash("compassPlayerHeight") + }, + { + "compassPlayerWidth", + "", + generate_hash("compassPlayerWidth") + }, + { + "compassRadarLineThickness", + "Thickness, relative to the compass size, of the radar texture that sweeps across the map", + generate_hash("compassRadarLineThickness") + }, + { + "compassRadarPingFadeTime", + "How long an enemy is visible on the compass after it is detected by radar", + generate_hash("compassRadarPingFadeTime") + }, + { + "compassRotation", + "Style of compass", + generate_hash("compassRotation") + }, + { + "compassSize", + "Scale the compass", + generate_hash("compassSize") + }, + { + "compassSoundPingFadeTime", + "The time in seconds for the sound overlay on the compass to fade", + generate_hash("compassSoundPingFadeTime") + }, + { + "compassTickertapeStretch", + "How far the tickertape should stretch from its center.", + generate_hash("compassTickertapeStretch") + }, + { + "comscore_active", + "Are we allowed to enable ComScore tracking or not", + generate_hash("comscore_active") + }, + { + "con_gameMsgWindow0FadeInTime", + "", + generate_hash("con_gameMsgWindow0FadeInTime") + }, + { + "con_gameMsgWindow0FadeOutTime", + "", + generate_hash("con_gameMsgWindow0FadeOutTime") + }, + { + "con_gameMsgWindow0Filter", + "", + generate_hash("con_gameMsgWindow0Filter") + }, + { + "con_gameMsgWindow0LineCount", + "", + generate_hash("con_gameMsgWindow0LineCount") + }, + { + "con_gameMsgWindow0MsgTime", + "", + generate_hash("con_gameMsgWindow0MsgTime") + }, + { + "con_gameMsgWindow0ScrollTime", + "", + generate_hash("con_gameMsgWindow0ScrollTime") + }, + { + "con_gameMsgWindow1FadeInTime", + "", + generate_hash("con_gameMsgWindow1FadeInTime") + }, + { + "con_gameMsgWindow1FadeOutTime", + "", + generate_hash("con_gameMsgWindow1FadeOutTime") + }, + { + "con_gameMsgWindow1Filter", + "", + generate_hash("con_gameMsgWindow1Filter") + }, + { + "con_gameMsgWindow1LineCount", + "", + generate_hash("con_gameMsgWindow1LineCount") + }, + { + "con_gameMsgWindow1MsgTime", + "", + generate_hash("con_gameMsgWindow1MsgTime") + }, + { + "con_gameMsgWindow1ScrollTime", + "", + generate_hash("con_gameMsgWindow1ScrollTime") + }, + { + "con_gameMsgWindow2FadeInTime", + "", + generate_hash("con_gameMsgWindow2FadeInTime") + }, + { + "con_gameMsgWindow2FadeOutTime", + "", + generate_hash("con_gameMsgWindow2FadeOutTime") + }, + { + "con_gameMsgWindow2Filter", + "", + generate_hash("con_gameMsgWindow2Filter") + }, + { + "con_gameMsgWindow2LineCount", + "", + generate_hash("con_gameMsgWindow2LineCount") + }, + { + "con_gameMsgWindow2MsgTime", + "", + generate_hash("con_gameMsgWindow2MsgTime") + }, + { + "con_gameMsgWindow2ScrollTime", + "", + generate_hash("con_gameMsgWindow2ScrollTime") + }, + { + "con_gameMsgWindow3FadeInTime", + "", + generate_hash("con_gameMsgWindow3FadeInTime") + }, + { + "con_gameMsgWindow3FadeOutTime", + "", + generate_hash("con_gameMsgWindow3FadeOutTime") + }, + { + "con_gameMsgWindow3Filter", + "", + generate_hash("con_gameMsgWindow3Filter") + }, + { + "con_gameMsgWindow3LineCount", + "", + generate_hash("con_gameMsgWindow3LineCount") + }, + { + "con_gameMsgWindow3MsgTime", + "", + generate_hash("con_gameMsgWindow3MsgTime") + }, + { + "con_gameMsgWindow3ScrollTime", + "", + generate_hash("con_gameMsgWindow3ScrollTime") + }, + { + "con_subtitleLeading", + "Leading for subtitles, calculated as a percentage of the font height", + generate_hash("con_subtitleLeading") + }, + { + "con_typewriterColorGlowCheckpoint", + "", + generate_hash("con_typewriterColorGlowCheckpoint") + }, + { + "con_typewriterColorGlowCompleted", + "", + generate_hash("con_typewriterColorGlowCompleted") + }, + { + "con_typewriterColorGlowFailed", + "", + generate_hash("con_typewriterColorGlowFailed") + }, + { + "con_typewriterColorGlowUpdated", + "", + generate_hash("con_typewriterColorGlowUpdated") + }, + { + "con_typewriterColorInteriorCheckpoint", + "", + generate_hash("con_typewriterColorInteriorCheckpoint") + }, + { + "con_typewriterColorInteriorCompleted", + "", + generate_hash("con_typewriterColorInteriorCompleted") + }, + { + "con_typewriterColorInteriorFailed", + "", + generate_hash("con_typewriterColorInteriorFailed") + }, + { + "con_typewriterColorInteriorUpdated", + "", + generate_hash("con_typewriterColorInteriorUpdated") + }, + { + "con_typewriterDecayDuration", + "Time (in milliseconds) to spend disolving the line away.", + generate_hash("con_typewriterDecayDuration") + }, + { + "con_typewriterDecayStartTime", + "Time (in milliseconds) to spend between the build and disolve phases.", + generate_hash("con_typewriterDecayStartTime") + }, + { + "con_typewriterPrintSpeed", + "Time (in milliseconds) to print each letter in the line.", + generate_hash("con_typewriterPrintSpeed") + }, + { + "counterDownloadInterval", + "Number of minutes before all the global counters are uploaded", + generate_hash("counterDownloadInterval") + }, + { + "counterUploadInterval", + "Number of minutes before all the global counters are uploaded", + generate_hash("counterUploadInterval") + }, + { + "cpu_speed_12players", + "12 player sys_configureGHz req'd", + generate_hash("cpu_speed_12players") + }, + { + "cpu_speed_18players", + "18 player sys_configureGHz req'd", + generate_hash("cpu_speed_18players") + }, + { + "cpu_speed_8players", + "8 player sys_configureGHz req'd", + generate_hash("cpu_speed_8players") + }, + { + "cSplineDebugRender", + "Debug Render the csplines.", + generate_hash("cSplineDebugRender") + }, + { + "cSplineDebugRenderCorridor", + "Debug Render the cspline corridor.", + generate_hash("cSplineDebugRenderCorridor") + }, + { + "cSplineDebugRenderData", + "Debug Render the cspline data.", + generate_hash("cSplineDebugRenderData") + }, + { + "cSplineDebugRenderSplineId", + "Select a cspline - 0 for all.", + generate_hash("cSplineDebugRenderSplineId") + }, + { + "dailychallenge_killswitch", + "daily challenge killswitch - int with bits used to flag individual daily challenges as enabled", + generate_hash("dailychallenge_killswitch") + }, + { + "dailychallenge_killswitch2", + "daily challenge killswitch2 - int with bits used to flag 2nd set of individual daily challenges as enabled", + generate_hash("dailychallenge_killswitch2") + }, + { + "dailychallenge_period", + "daily challenge period - utc value for a day", + generate_hash("dailychallenge_period") + }, + { + "data_validation_allow_drop", + "", + generate_hash("data_validation_allow_drop") + }, + { + "dc_lobbymerge", + "Allows lobby merging across data centres", + generate_hash("dc_lobbymerge") + }, + { + "dcacheSimulateNoHDD", + "When turned on, simulate no HDD for caching.", + generate_hash("dcacheSimulateNoHDD") + }, + { + "dcacheThrottleEnabled", + "Enable or disable dcache upload throttling.", + generate_hash("dcacheThrottleEnabled") + }, + { + "dcacheThrottleKBytesPerSec", + "Dcache upload throttle limit in K Bytes per second.", + generate_hash("dcacheThrottleKBytesPerSec") + }, + { + "dedicated_dhclient", + "True if we're a client playing on a DH server", + generate_hash("dedicated_dhclient") + }, + { + "demonwareConsideredConnectedTime", + "Number of milliseconds after being disconnected from demonware before considering shutting down.", + generate_hash("demonwareConsideredConnectedTime") + }, + { + "developer", + "Enable development options", + generate_hash("developer") + }, + { + "didyouknow", + "", + generate_hash("didyouknow") + }, + { + "discard_playerstats_on_suspend", + "Forces stats discard on suspend", + generate_hash("discard_playerstats_on_suspend") + }, + { + "drawEntityCount", + "Enable entity count drawing", + generate_hash("drawEntityCount") + }, + { + "drawEntityCountPos", + "Where to draw the entity count graph", + generate_hash("drawEntityCountPos") + }, + { + "drawEntityCountSize", + "undefined", + generate_hash("drawEntityCountSize") + }, + { + "drawKillcamData", + "Enable drawing server killcam data", + generate_hash("drawKillcamData") + }, + { + "drawKillcamDataPos", + "Where to draw the server killcam graph", + generate_hash("drawKillcamDataPos") + }, + { + "drawKillcamDataSize", + "How big to draw the killcam data graph", + generate_hash("drawKillcamDataSize") + }, + { + "drawServerBandwidth", + "Enable drawing server bandwidth", + generate_hash("drawServerBandwidth") + }, + { + "drawServerBandwidthPos", + "Where to draw the server bandwidth graph", + generate_hash("drawServerBandwidthPos") + }, + { + "ds_dcid", + "optional datacenter id - from playlist", + generate_hash("ds_dcid") + }, + { + "ds_dcid_override", + "force datacenter id", + generate_hash("ds_dcid_override") + }, + { + "ds_info", + "ds info string", + generate_hash("ds_info") + }, + { + "ds_info_enable", + "Enable ds info string", + generate_hash("ds_info_enable") + }, + { + "ds_introRequestTimeout", + "ds intro request timeout (ms)", + generate_hash("ds_introRequestTimeout") + }, + { + "ds_keepaliveInterval", + "ds keepalive interval (ms)", + generate_hash("ds_keepaliveInterval") + }, + { + "ds_keepaliveTimeout", + "ds keepalive timeout (ms)", + generate_hash("ds_keepaliveTimeout") + }, + { + "ds_pingclient_max_reping_distance", + "don't re-ping a datacenter if it's further away than this (miles)", + generate_hash("ds_pingclient_max_reping_distance") + }, + { + "ds_pingclient_max_repings", + "max # of times to re-ping a datacenter", + generate_hash("ds_pingclient_max_repings") + }, + { + "ds_pingclient_maxpings", + "max pings to send per datacenter", + generate_hash("ds_pingclient_maxpings") + }, + { + "ds_pingclient_maxpings_per_tick", + "max new pings each tick", + generate_hash("ds_pingclient_maxpings_per_tick") + }, + { + "ds_pingclient_min_reping_delay", + "min msec delay between re-pings", + generate_hash("ds_pingclient_min_reping_delay") + }, + { + "ds_pingclient_min_reping_latency", + "don't re-ping a datacenter if latency is less than this", + generate_hash("ds_pingclient_min_reping_latency") + }, + { + "ds_pingclient_minpings", + "min responses required per datacenter", + generate_hash("ds_pingclient_minpings") + }, + { + "ds_pingclient_odsf", + "does dsping set odsf flag", + generate_hash("ds_pingclient_odsf") + }, + { + "dsping_dc_0", + "", + generate_hash("dsping_dc_0") + }, + { + "dsping_dc_1", + "", + generate_hash("dsping_dc_1") + }, + { + "dsping_dc_10", + "", + generate_hash("dsping_dc_10") + }, + { + "dsping_dc_11", + "", + generate_hash("dsping_dc_11") + }, + { + "dsping_dc_12", + "", + generate_hash("dsping_dc_12") + }, + { + "dsping_dc_13", + "", + generate_hash("dsping_dc_13") + }, + { + "dsping_dc_14", + "", + generate_hash("dsping_dc_14") + }, + { + "dsping_dc_15", + "", + generate_hash("dsping_dc_15") + }, + { + "dsping_dc_16", + "", + generate_hash("dsping_dc_16") + }, + { + "dsping_dc_17", + "", + generate_hash("dsping_dc_17") + }, + { + "dsping_dc_18", + "", + generate_hash("dsping_dc_18") + }, + { + "dsping_dc_19", + "", + generate_hash("dsping_dc_19") + }, + { + "dsping_dc_2", + "", + generate_hash("dsping_dc_2") + }, + { + "dsping_dc_20", + "", + generate_hash("dsping_dc_20") + }, + { + "dsping_dc_21", + "", + generate_hash("dsping_dc_21") + }, + { + "dsping_dc_22", + "", + generate_hash("dsping_dc_22") + }, + { + "dsping_dc_23", + "", + generate_hash("dsping_dc_23") + }, + { + "dsping_dc_24", + "", + generate_hash("dsping_dc_24") + }, + { + "dsping_dc_25", + "", + generate_hash("dsping_dc_25") + }, + { + "dsping_dc_26", + "", + generate_hash("dsping_dc_26") + }, + { + "dsping_dc_27", + "", + generate_hash("dsping_dc_27") + }, + { + "dsping_dc_28", + "", + generate_hash("dsping_dc_28") + }, + { + "dsping_dc_29", + "", + generate_hash("dsping_dc_29") + }, + { + "dsping_dc_3", + "", + generate_hash("dsping_dc_3") + }, + { + "dsping_dc_30", + "", + generate_hash("dsping_dc_30") + }, + { + "dsping_dc_31", + "", + generate_hash("dsping_dc_31") + }, + { + "dsping_dc_32", + "", + generate_hash("dsping_dc_32") + }, + { + "dsping_dc_33", + "", + generate_hash("dsping_dc_33") + }, + { + "dsping_dc_34", + "", + generate_hash("dsping_dc_34") + }, + { + "dsping_dc_35", + "", + generate_hash("dsping_dc_35") + }, + { + "dsping_dc_36", + "", + generate_hash("dsping_dc_36") + }, + { + "dsping_dc_37", + "", + generate_hash("dsping_dc_37") + }, + { + "dsping_dc_38", + "", + generate_hash("dsping_dc_38") + }, + { + "dsping_dc_39", + "", + generate_hash("dsping_dc_39") + }, + { + "dsping_dc_4", + "", + generate_hash("dsping_dc_4") + }, + { + "dsping_dc_40", + "", + generate_hash("dsping_dc_40") + }, + { + "dsping_dc_41", + "", + generate_hash("dsping_dc_41") + }, + { + "dsping_dc_42", + "", + generate_hash("dsping_dc_42") + }, + { + "dsping_dc_43", + "", + generate_hash("dsping_dc_43") + }, + { + "dsping_dc_44", + "", + generate_hash("dsping_dc_44") + }, + { + "dsping_dc_45", + "", + generate_hash("dsping_dc_45") + }, + { + "dsping_dc_46", + "", + generate_hash("dsping_dc_46") + }, + { + "dsping_dc_47", + "", + generate_hash("dsping_dc_47") + }, + { + "dsping_dc_48", + "", + generate_hash("dsping_dc_48") + }, + { + "dsping_dc_49", + "", + generate_hash("dsping_dc_49") + }, + { + "dsping_dc_5", + "", + generate_hash("dsping_dc_5") + }, + { + "dsping_dc_50", + "", + generate_hash("dsping_dc_50") + }, + { + "dsping_dc_51", + "", + generate_hash("dsping_dc_51") + }, + { + "dsping_dc_52", + "", + generate_hash("dsping_dc_52") + }, + { + "dsping_dc_53", + "", + generate_hash("dsping_dc_53") + }, + { + "dsping_dc_54", + "", + generate_hash("dsping_dc_54") + }, + { + "dsping_dc_55", + "", + generate_hash("dsping_dc_55") + }, + { + "dsping_dc_56", + "", + generate_hash("dsping_dc_56") + }, + { + "dsping_dc_57", + "", + generate_hash("dsping_dc_57") + }, + { + "dsping_dc_58", + "", + generate_hash("dsping_dc_58") + }, + { + "dsping_dc_59", + "", + generate_hash("dsping_dc_59") + }, + { + "dsping_dc_6", + "", + generate_hash("dsping_dc_6") + }, + { + "dsping_dc_60", + "", + generate_hash("dsping_dc_60") + }, + { + "dsping_dc_61", + "", + generate_hash("dsping_dc_61") + }, + { + "dsping_dc_62", + "", + generate_hash("dsping_dc_62") + }, + { + "dsping_dc_63", + "", + generate_hash("dsping_dc_63") + }, + { + "dsping_dc_7", + "", + generate_hash("dsping_dc_7") + }, + { + "dsping_dc_8", + "", + generate_hash("dsping_dc_8") + }, + { + "dsping_dc_9", + "", + generate_hash("dsping_dc_9") + }, + { + "dvl", + "Enables the data validation system. Only available in non-retail builds.", + generate_hash("dvl") + }, + { + "dw_addrHandleTimeout", + "Delay before destroying an addrHandle after the connection is lost\n", + generate_hash("dw_addrHandleTimeout") + }, + { + "dw_leaderboard_write_active", + "Are leaderboard writes enabled", + generate_hash("dw_leaderboard_write_active") + }, + { + "dw_presence_active", + "Is the demonware presence system enabled", + generate_hash("dw_presence_active") + }, + { + "dw_presence_coop_join_active", + "Do we allow players to join on presence for private coop matches (post session to demonware", + generate_hash("dw_presence_coop_join_active") + }, + { + "dw_presence_get_delay", + "Number of milliseconds to wait after booting the game to fetch demonware presence", + generate_hash("dw_presence_get_delay") + }, + { + "dw_presence_get_rate", + "Number of milliseconds to wait between sending presence state to demonware", + generate_hash("dw_presence_get_rate") + }, + { + "dw_presence_put_delay", + "Number of milliseconds to wait in a presence state before sending to demonware", + generate_hash("dw_presence_put_delay") + }, + { + "dw_presence_put_rate", + "Number of milliseconds to wait between sending presence state to demonware", + generate_hash("dw_presence_put_rate") + }, + { + "dw_region_lookup_timeout", + "Timeout (in MS) after which we will accept not having found a region code and use the default", + generate_hash("dw_region_lookup_timeout") + }, + { + "dw_shared_presence_active", + "Is the demonware shared presence system enabled", + generate_hash("dw_shared_presence_active") + }, + { + "dw_shared_presence_get_delay", + "Number of milliseconds to wait after booting the game to fetch demonware presence", + generate_hash("dw_shared_presence_get_delay") + }, + { + "dw_shared_presence_get_rate", + "Number of milliseconds to wait between sending presence state to demonware", + generate_hash("dw_shared_presence_get_rate") + }, + { + "dw_shared_presence_put_delay", + "Number of milliseconds to wait in a shared presence state before sending to demonware", + generate_hash("dw_shared_presence_put_delay") + }, + { + "dw_shared_presence_put_rate", + "Number of milliseconds to wait between sending presence state to demonware", + generate_hash("dw_shared_presence_put_rate") + }, + { + "dwBandwidthTestTaskTimeout", + "default timeout for the bandwidth test task (in ms). 0 means no timeout", + generate_hash("dwBandwidthTestTaskTimeout") + }, + { + "dynEnt_active", + "Disable/enable dynent reactions", + generate_hash("dynEnt_active") + }, + { + "dynEnt_playerWakeUpRadius", + "Determines threshold distance from player within which all dynents are woken up.", + generate_hash("dynEnt_playerWakeUpRadius") + }, + { + "dynEnt_playerWakeUpZOffset", + "Determines vertical distance from player's feet from which wake up sphere is centered.", + generate_hash("dynEnt_playerWakeUpZOffset") + }, + { + "elite_clan_active", + "Are we allowed to show Elite Clans or not", + generate_hash("elite_clan_active") + }, + { + "elite_clan_cool_off_time", + "Cool off time between calls to fetch the elite clan", + generate_hash("elite_clan_cool_off_time") + }, + { + "elite_clan_delay", + "Delay before the bdTeams calls start to Demonware. -1 means On-Demand and it will wait until the 'starteliteclan' menu call", + generate_hash("elite_clan_delay") + }, + { + "elite_clan_division_icon_active", + "Are we allowed to show Elite Clan division icon or not", + generate_hash("elite_clan_division_icon_active") + }, + { + "elite_clan_get_blob_profile_max_retry_time", + "Max time that the Elite Clan get private profile can retry", + generate_hash("elite_clan_get_blob_profile_max_retry_time") + }, + { + "elite_clan_get_blob_profile_retry_step", + "Step in m/s for the Elite Clan get private profile retry", + generate_hash("elite_clan_get_blob_profile_retry_step") + }, + { + "elite_clan_get_clan_max_retry_time", + "Max time that the Elite Clan get clan can retry", + generate_hash("elite_clan_get_clan_max_retry_time") + }, + { + "elite_clan_get_clan_retry_step", + "Step in m/s for the Elite Clan get clan retry", + generate_hash("elite_clan_get_clan_retry_step") + }, + { + "elite_clan_get_members_max_retry_time", + "Max time that the Elite Clan get members can retry", + generate_hash("elite_clan_get_members_max_retry_time") + }, + { + "elite_clan_get_members_retry_step", + "Step in m/s for the Elite Clan get members retry", + generate_hash("elite_clan_get_members_retry_step") + }, + { + "elite_clan_get_private_member_profile_max_retry_time", + "Max time that the Elite Clan get private profile can retry", + generate_hash("elite_clan_get_private_member_profile_max_retry_time") + }, + { + "elite_clan_get_private_member_profile_retry_step", + "Step in m/s for the Elite Clan get private profile retry", + generate_hash("elite_clan_get_private_member_profile_retry_step") + }, + { + "elite_clan_get_public_profile_max_retry_time", + "Max time that the Elite Clan get public profile can retry", + generate_hash("elite_clan_get_public_profile_max_retry_time") + }, + { + "elite_clan_get_public_profile_retry_step", + "Step in m/s for the Elite Clan get public profile retry", + generate_hash("elite_clan_get_public_profile_retry_step") + }, + { + "elite_clan_get_team_stats_max_retry_time", + "Max time that the Elite Clan get team stats can retry", + generate_hash("elite_clan_get_team_stats_max_retry_time") + }, + { + "elite_clan_get_team_stats_retry_step", + "Step in m/s for the Elite Clan get team stats retry", + generate_hash("elite_clan_get_team_stats_retry_step") + }, + { + "elite_clan_motd_throttle_time", + "Throttle time between motd update calls", + generate_hash("elite_clan_motd_throttle_time") + }, + { + "elite_clan_remote_view_active", + "Are we allowed to view the clans for remote players", + generate_hash("elite_clan_remote_view_active") + }, + { + "elite_clan_remote_view_max_retry_time", + "Max time that the Elite Clan remote viewing can retry", + generate_hash("elite_clan_remote_view_max_retry_time") + }, + { + "elite_clan_remote_view_retry_step", + "Step in m/s for the retry for viewing a remote Elite Clan", + generate_hash("elite_clan_remote_view_retry_step") + }, + { + "elite_clan_send_message_to_members_max_retry_time", + "Max time that the Elite Clan send message to members can retry", + generate_hash("elite_clan_send_message_to_members_max_retry_time") + }, + { + "elite_clan_send_message_to_members_retry_step", + "Step in m/s for the Elite Clan send message to members retry", + generate_hash("elite_clan_send_message_to_members_retry_step") + }, + { + "elite_clan_set_private_member_profile_max_retry_time", + "Max time that the Elite Clan set private member profile can retry", + generate_hash("elite_clan_set_private_member_profile_max_retry_time") + }, + { + "elite_clan_set_private_member_profile_retry_step", + "Step in m/s for the Elite Clan set private member profile retry", + generate_hash("elite_clan_set_private_member_profile_retry_step") + }, + { + "elite_clan_single_task_popup_text", + "String to be displayed on popup when a single task is being performed", + generate_hash("elite_clan_single_task_popup_text") + }, + { + "elite_clan_using_title", + "Stores whether the Elite Clan title is in use by the user", + generate_hash("elite_clan_using_title") + }, + { + "emblems_active", + "Are we allowed to enable Emblems or not", + generate_hash("emblems_active") + }, + { + "enable_recordRecentActivity", + "records the timestamp of when the player was recently active to the tracker leaderboards", + generate_hash("enable_recordRecentActivity") + }, + { + "enableReportingRegisteredParties", + "If true then party membership data and host status will be reported in matchdata blob.", + generate_hash("enableReportingRegisteredParties") + }, + { + "entitlements_active", + "Are we allowed to show Entitlements or not", + generate_hash("entitlements_active") + }, + { + "entitlements_config_file_max_retry_time", + "Max time that the Entitlements config file read can retry", + generate_hash("entitlements_config_file_max_retry_time") + }, + { + "entitlements_config_file_retry_step", + "Step in m/s for the Entitlements config file read retry", + generate_hash("entitlements_config_file_retry_step") + }, + { + "entitlements_cool_off_time", + "Cool off time between calls to fetch the elite clan", + generate_hash("entitlements_cool_off_time") + }, + { + "entitlements_delay", + "Delay before the entitlement calls start to Demonware. -1 means On-Demand and it will wait until the 'startentitlements' menu call", + generate_hash("entitlements_delay") + }, + { + "entitlements_key_archive_max_retry_time", + "Max time that the Entitlements key archive read can retry", + generate_hash("entitlements_key_archive_max_retry_time") + }, + { + "entitlements_key_archive_retry_step", + "Step in m/s for the Entitlements key archive read retry", + generate_hash("entitlements_key_archive_retry_step") + }, + { + "entitlementSystemOk", + "Set by the game to inform that the entitlement system is initialised", + generate_hash("entitlementSystemOk") + }, + { + "facebook_active", + "Are we allowed to show Facebook or not", + generate_hash("facebook_active") + }, + { + "facebook_delay", + "Delay before the Facebook calls start to Demonware. -1 means On-Demand and it will wait until the 'startfacebook' menu call", + generate_hash("facebook_delay") + }, + { + "facebook_friends_active", + "Are we allowed to show Facebook Friends or not", + generate_hash("facebook_friends_active") + }, + { + "facebook_friends_max_retry_time", + "Max time that the Facebook friends read can retry", + generate_hash("facebook_friends_max_retry_time") + }, + { + "facebook_friends_refresh_time", + "Time in seconds between Facebook friend refreshes", + generate_hash("facebook_friends_refresh_time") + }, + { + "facebook_friends_retry_step", + "Step in m/s for the Facebook friends read retry", + generate_hash("facebook_friends_retry_step") + }, + { + "facebook_friends_showing_count", + "Contains how many facebook friends are being shown in the UI.", + generate_hash("facebook_friends_showing_count") + }, + { + "facebook_friends_throttle_time", + "Throttle time between Facebook friend pages", + generate_hash("facebook_friends_throttle_time") + }, + { + "facebook_max_retry_time", + "Max time that the Facebook authentication can retry", + generate_hash("facebook_max_retry_time") + }, + { + "facebook_password", + "Facebook Password", + generate_hash("facebook_password") + }, + { + "facebook_password_asterisk", + "Facebook Password (Asterisk Version)", + generate_hash("facebook_password_asterisk") + }, + { + "facebook_popup_text", + "Facebook Popup Text", + generate_hash("facebook_popup_text") + }, + { + "facebook_retry_step", + "Step in m/s for the Facebook authentication retry", + generate_hash("facebook_retry_step") + }, + { + "facebook_upload_photo_active", + "Are we allowed to Upload Photos to Facebook or not", + generate_hash("facebook_upload_photo_active") + }, + { + "facebook_upload_video_active", + "Are we allowed to Upload Videos to Facebook or not", + generate_hash("facebook_upload_video_active") + }, + { + "facebook_username", + "Facebook Username", + generate_hash("facebook_username") + }, + { + "fixedtime", + "Use a fixed time rate for each frame", + generate_hash("fixedtime") + }, + { + "FoFIconMaxSize", + "Maximum size a Friend-or-Foe icon should ever grow to.", + generate_hash("FoFIconMaxSize") + }, + { + "FoFIconMinSize", + "Minimum size a Friend-or-Foe icon should ever shrink to.", + generate_hash("FoFIconMinSize") + }, + { + "FoFIconScale", + "Base scale of Friend-or-Foe icons.", + generate_hash("FoFIconScale") + }, + { + "FoFIconSpawnTimeDelay", + "How long to wait, after spawning, before showing the Friend-or-Foe icon on a player.", + generate_hash("FoFIconSpawnTimeDelay") + }, + { + "FoFIconSpawnTimeFade", + "Length of the Friend-or-Foe icons' fade-ins.", + generate_hash("FoFIconSpawnTimeFade") + }, + { + "friendsCacheSteamFriends", + "Use cache of steam friends before querying steam api", + generate_hash("friendsCacheSteamFriends") + }, + { + "friendsMaxSteamLookupsPerFrame", + "Number of steam friends to query steam status per frame when doing a refresh.\n", + generate_hash("friendsMaxSteamLookupsPerFrame") + }, + { + "friendsWidgetMinimumRefreshTimer", + "Minimum delay before refreshing friends data if you aren't on the friends screen\n", + generate_hash("friendsWidgetMinimumRefreshTimer") + }, + { + "fs_basegame", + "Base game name", + generate_hash("fs_basegame") + }, + { + "fs_basepath", + "Base game path", + generate_hash("fs_basepath") + }, + { + "fs_basepath_output", + "Base game path", + generate_hash("fs_basepath_output") + }, + { + "fs_cdpath", + "CD path", + generate_hash("fs_cdpath") + }, + { + "fs_copyfiles", + "Copy all used files to another location", + generate_hash("fs_copyfiles") + }, + { + "fs_debug", + "Enable file system debugging information", + generate_hash("fs_debug") + }, + { + "fs_game", + "Game data directory. Must be \"\" or a sub directory of 'mods/'.", + generate_hash("fs_game") + }, + { + "fs_homepath", + "Game home path", + generate_hash("fs_homepath") + }, + { + "fs_ignoreLocalized", + "Ignore localized assets", + generate_hash("fs_ignoreLocalized") + }, + { + "fx_alphaThreshold", + "Don't draw billboard sprites, oriented sprites or tails with alpha below this threshold (0-256).", + generate_hash("fx_alphaThreshold") + }, + { + "fx_cast_shadow", + "Enable transparency shadow mapping from script", + generate_hash("fx_cast_shadow") + }, + { + "fx_count", + "Debug effects count", + generate_hash("fx_count") + }, + { + "fx_cull_elem_draw", + "Culls effect elems for drawing", + generate_hash("fx_cull_elem_draw") + }, + { + "fx_cull_elem_draw_flicker", + "Flicker DPVS culled effect elems", + generate_hash("fx_cull_elem_draw_flicker") + }, + { + "fx_cull_elem_spawn", + "Culls effect elems for spawning", + generate_hash("fx_cull_elem_spawn") + }, + { + "fx_debugBolt", + "Debug effects bolt", + generate_hash("fx_debugBolt") + }, + { + "fx_deferelem", + "Toggles deferred processing of elements instead of effects", + generate_hash("fx_deferelem") + }, + { + "fx_dpvs_cull_elem_draw", + "Culls effect elems for drawing using DPVS(2: ignore per-effect portal culling flag)", + generate_hash("fx_dpvs_cull_elem_draw") + }, + { + "fx_draw", + "", + generate_hash("fx_draw") + }, + { + "fx_draw_omniLight", + "", + generate_hash("fx_draw_omniLight") + }, + { + "fx_draw_simd", + "Draw effects using SIMD / Vector code.", + generate_hash("fx_draw_simd") + }, + { + "fx_draw_spotLight", + "", + generate_hash("fx_draw_spotLight") + }, + { + "fx_drawClouds", + "Toggles the drawing of particle clouds", + generate_hash("fx_drawClouds") + }, + { + "fx_enable", + "Toggles all effects processing", + generate_hash("fx_enable") + }, + { + "fx_flare", + "Toggles fx flare", + generate_hash("fx_flare") + }, + { + "fx_freeze", + "Freeze effects", + generate_hash("fx_freeze") + }, + { + "fx_killEffectOnRewind", + "Causes effects that have been marked for a soft kill (fade out) to be killed immediately on a rewind.", + generate_hash("fx_killEffectOnRewind") + }, + { + "fx_lightGridSampleOffset", + "the length of effect sample's offset along X Axis", + generate_hash("fx_lightGridSampleOffset") + }, + { + "fx_mark_profile", + "Turn on FX profiling for marks (specify which local client, with '1' being the first.)", + generate_hash("fx_mark_profile") + }, + { + "fx_marks", + "Toggles whether bullet hits leave marks", + generate_hash("fx_marks") + }, + { + "fx_marks_ents", + "Toggles whether bullet hits leave marks", + generate_hash("fx_marks_ents") + }, + { + "fx_marks_nearlimit", + "Sets limit of number of decals that can exist at the same location (0 for unlimited)", + generate_hash("fx_marks_nearlimit") + }, + { + "fx_marks_smodels", + "Toggles whether bullet hits leave marks", + generate_hash("fx_marks_smodels") + }, + { + "fx_physicsImpactVelocityThreshold", + "Set the min normal velocity threshold in order for model physics fx to generate child impact effects.", + generate_hash("fx_physicsImpactVelocityThreshold") + }, + { + "fx_profile", + "Turn on FX profiling (specify which local client, with '1' being the first.)", + generate_hash("fx_profile") + }, + { + "fx_profileFilter", + "Only show effects with this as a substring in FX profile", + generate_hash("fx_profileFilter") + }, + { + "fx_profileFilterElemCountZero", + "Do not include FX that have a zero element count", + generate_hash("fx_profileFilterElemCountZero") + }, + { + "fx_profileSkip", + "Skip the first n lines in FX profile (to see ones off bottom of screen)", + generate_hash("fx_profileSkip") + }, + { + "fx_profileSort", + "Choose sort criteria for FX profiling", + generate_hash("fx_profileSort") + }, + { + "fx_showLightGridSampleOffset", + "show light grid sample offset in CreateFX mode", + generate_hash("fx_showLightGridSampleOffset") + }, + { + "fx_visMinTraceDist", + "Minimum visibility trace size", + generate_hash("fx_visMinTraceDist") + }, + { + "g_allowVote", + "Enable voting on this server", + generate_hash("g_allowVote") + }, + { + "g_atmosFogDistanceScaleReadOnly", + "scale applied to scene distance used for atmospheric fog calculation", + generate_hash("g_atmosFogDistanceScaleReadOnly") + }, + { + "g_atmosFogEnabledReadOnly", + "use atmospheric fog", + generate_hash("g_atmosFogEnabledReadOnly") + }, + { + "g_atmosFogExtinctionStrengthReadOnly", + "scale out scatter contribution of atmospheric fog", + generate_hash("g_atmosFogExtinctionStrengthReadOnly") + }, + { + "g_atmosFogHalfPlaneDistanceReadOnly", + "distance at which atmospheric fog contributes half the pixels color", + generate_hash("g_atmosFogHalfPlaneDistanceReadOnly") + }, + { + "g_atmosFogHazeSpreadReadOnly", + "directionality of haze (1ReadOnly = all forward scatter, 0ReadOnly = all back scatter)", + generate_hash("g_atmosFogHazeSpreadReadOnly") + }, + { + "g_atmosFogHazeStrengthReadOnly", + "portion of atmospheric fog density that is haze (0ReadOnly = all fog, 1ReadOnly = all haze)", + generate_hash("g_atmosFogHazeStrengthReadOnly") + }, + { + "g_atmosFogHeightFogBaseHeightReadOnly", + "height fog is full density at this world height and below", + generate_hash("g_atmosFogHeightFogBaseHeightReadOnly") + }, + { + "g_atmosFogHeightFogEnabledReadOnly", + "use height for atmospheric fog", + generate_hash("g_atmosFogHeightFogEnabledReadOnly") + }, + { + "g_atmosFogHeightFogHalfPlaneDistanceReadOnly", + "at this distance above g_atmosFogHeightFogBaseHeight, height fog density is half", + generate_hash("g_atmosFogHeightFogHalfPlaneDistanceReadOnly") + }, + { + "g_atmosFogInScatterStrengthReadOnly", + "scale in scatter contribution of atmospheric fog", + generate_hash("g_atmosFogInScatterStrengthReadOnly") + }, + { + "g_atmosFogSkyAngularFalloffEnabledReadOnly", + "use angular sky falloff for atmospheric fog", + generate_hash("g_atmosFogSkyAngularFalloffEnabledReadOnly") + }, + { + "g_atmosFogSkyDistanceReadOnly", + "distance used for sky box when applying atmospheric fog", + generate_hash("g_atmosFogSkyDistanceReadOnly") + }, + { + "g_atmosFogSkyFalloffAngleRangeReadOnly", + "sky fog angular falloff angle range sky fog falls off over this range from the start angle", + generate_hash("g_atmosFogSkyFalloffAngleRangeReadOnly") + }, + { + "g_atmosFogSkyFalloffStartAngleReadOnly", + "sky fog angular falloff start angle (full strength fog at this angle)", + generate_hash("g_atmosFogSkyFalloffStartAngleReadOnly") + }, + { + "g_atmosFogStartDistanceReadOnly", + "distance from camera at which fog contribution begins", + generate_hash("g_atmosFogStartDistanceReadOnly") + }, + { + "g_atmosFogSunDirectionReadOnly", + "sun direction used when calculating atmospheric fog", + generate_hash("g_atmosFogSunDirectionReadOnly") + }, + { + "g_banIPs", + "IP addresses to ban from playing", + generate_hash("g_banIPs") + }, + { + "g_clonePlayerMaxVelocity", + "Maximum velocity in each axis of a cloned player\n(for death animations)", + generate_hash("g_clonePlayerMaxVelocity") + }, + { + "g_deadChat", + "Allow dead players to chat with living players", + generate_hash("g_deadChat") + }, + { + "g_dropForwardSpeed", + "Forward speed of a dropped item", + generate_hash("g_dropForwardSpeed") + }, + { + "g_dropHorzSpeedRand", + "Random component of the initial horizontal speed of a dropped item", + generate_hash("g_dropHorzSpeedRand") + }, + { + "g_dropUpSpeedBase", + "Base component of the initial vertical speed of a dropped item", + generate_hash("g_dropUpSpeedBase") + }, + { + "g_dropUpSpeedRand", + "Random component of the initial vertical speed of a dropped item", + generate_hash("g_dropUpSpeedRand") + }, + { + "g_earthquakeEnable", + "Enable camera shake", + generate_hash("g_earthquakeEnable") + }, + { + "g_fogColorIntensityReadOnly", + "HDR fog color intensity that was set in the most recent call to \"setexpfog\"", + generate_hash("g_fogColorIntensityReadOnly") + }, + { + "g_fogColorReadOnly", + "Fog color that was set in the most recent call to \"setexpfog\"", + generate_hash("g_fogColorReadOnly") + }, + { + "g_fogHalfDistReadOnly", + "", + generate_hash("g_fogHalfDistReadOnly") + }, + { + "g_fogMaxOpacityReadOnly", + "Fog max opacity that was set in the most recent call to \"setexpfog\"", + generate_hash("g_fogMaxOpacityReadOnly") + }, + { + "g_fogStartDistReadOnly", + "", + generate_hash("g_fogStartDistReadOnly") + }, + { + "g_friendlyfireDist", + "Maximum range for disabling fire at a friendly", + generate_hash("g_friendlyfireDist") + }, + { + "g_friendlyNameDist", + "Maximum range for seeing a friendly's name", + generate_hash("g_friendlyNameDist") + }, + { + "g_gametype", + "The current game mode", + generate_hash("g_gametype") + }, + { + "g_giveAll", + "Give all weapons", + generate_hash("g_giveAll") + }, + { + "g_hardcore", + "Hardcore?", + generate_hash("g_hardcore") + }, + { + "g_heightFogBaseHeightReadOnly", + "height fog is full density at this world height and below", + generate_hash("g_heightFogBaseHeightReadOnly") + }, + { + "g_heightFogEnabledReadOnly", + "use height for normal/sun fog, set in the most recent call to \"setexpfog\"", + generate_hash("g_heightFogEnabledReadOnly") + }, + { + "g_heightFogHalfPlaneDistanceReadOnly", + "at this distance above g_heightFogBaseHeight, height fog density is half, set in the most recent call to \"setexpfog\"", + generate_hash("g_heightFogHalfPlaneDistanceReadOnly") + }, + { + "g_inactivity", + "Time delay before player is kicked for inactivity", + generate_hash("g_inactivity") + }, + { + "g_keyboarduseholdtime", + "The time to hold down the 'use' button to activate a 'use' command on a keyboard", + generate_hash("g_keyboarduseholdtime") + }, + { + "g_knockback", + "Maximum knockback", + generate_hash("g_knockback") + }, + { + "g_lagged_damage_threshold", + "Threshold (ms) beyond which we will report a damaged lagged client to the tracker leaderboards.", + generate_hash("g_lagged_damage_threshold") + }, + { + "g_listEntity", + "List the entities", + generate_hash("g_listEntity") + }, + { + "g_mantleBlockTimeBuffer", + "Time that the client think is delayed after mantling", + generate_hash("g_mantleBlockTimeBuffer") + }, + { + "g_maxDroppedWeapons", + "Maximum number of dropped weapons", + generate_hash("g_maxDroppedWeapons") + }, + { + "g_minGrenadeDamageSpeed", + "Minimum speed at which getting hit be a grenade will do damage (not the grenade explosion damage)", + generate_hash("g_minGrenadeDamageSpeed") + }, + { + "g_oldschool", + "Oldschool?", + generate_hash("g_oldschool") + }, + { + "g_password", + "Password", + generate_hash("g_password") + }, + { + "g_playerCollisionEjectSpeed", + "Speed at which to push intersecting players away from each other", + generate_hash("g_playerCollisionEjectSpeed") + }, + { + "g_ScoresColor_Allies", + "Allies team color on scoreboard", + generate_hash("g_ScoresColor_Allies") + }, + { + "g_ScoresColor_Axis", + "Axis team color on scoreboard", + generate_hash("g_ScoresColor_Axis") + }, + { + "g_ScoresColor_EnemyTeam", + "Enemy team color on scoreboard", + generate_hash("g_ScoresColor_EnemyTeam") + }, + { + "g_ScoresColor_Free", + "Free Team color on scoreboard", + generate_hash("g_ScoresColor_Free") + }, + { + "g_ScoresColor_MyParty", + "Player team color on scoreboard when in the same party", + generate_hash("g_ScoresColor_MyParty") + }, + { + "g_ScoresColor_MyTeam", + "Player team color on scoreboard", + generate_hash("g_ScoresColor_MyTeam") + }, + { + "g_ScoresColor_Spectator", + "Spectator team color on scoreboard", + generate_hash("g_ScoresColor_Spectator") + }, + { + "g_scriptMainMenu", + "", + generate_hash("g_scriptMainMenu") + }, + { + "g_sunFogBeginFadeAngleReadOnly", + "Angle from the sun direction to start fade away from the sun fog color that was set in the most recent call to \"setexpfog\"", + generate_hash("g_sunFogBeginFadeAngleReadOnly") + }, + { + "g_sunFogColorIntensityReadOnly", + "HDR sun fog color intensity that was set in the most recent call to \"setexpfog\"", + generate_hash("g_sunFogColorIntensityReadOnly") + }, + { + "g_sunFogColorReadOnly", + "Sun fog color that was set in the most recent call to \"setexpfog\"", + generate_hash("g_sunFogColorReadOnly") + }, + { + "g_sunFogDirReadOnly", + "Sun fog direction that was set in the most recent call to \"setexpfog\"", + generate_hash("g_sunFogDirReadOnly") + }, + { + "g_sunFogEnabledReadOnly", + "Sun fog was enabled in the most recent call to \"setexpfog\"", + generate_hash("g_sunFogEnabledReadOnly") + }, + { + "g_sunFogEndFadeAngleReadOnly", + "Angle from the sun direction to end fade away from the sun fog color that was set in the most recent call to \"setexpfog\"", + generate_hash("g_sunFogEndFadeAngleReadOnly") + }, + { + "g_sunFogScaleReadOnly", + "Distance scale in the sun fog direction that was set in the most recent call to \"setexpfog\"", + generate_hash("g_sunFogScaleReadOnly") + }, + { + "g_TeamIcon_Allies", + "Icon name for the allied scores banner", + generate_hash("g_TeamIcon_Allies") + }, + { + "g_TeamIcon_Axis", + "Icon name for the axis scores banner", + generate_hash("g_TeamIcon_Axis") + }, + { + "g_TeamIcon_EnemyAllies", + "Icon name for the allied scores banner", + generate_hash("g_TeamIcon_EnemyAllies") + }, + { + "g_TeamIcon_EnemyAxis", + "Icon name for the axis scores banner when you're on axis.", + generate_hash("g_TeamIcon_EnemyAxis") + }, + { + "g_TeamIcon_Free", + "Icon name for the scores of players with no team", + generate_hash("g_TeamIcon_Free") + }, + { + "g_TeamIcon_MyAllies", + "Icon name for the allied scores banner", + generate_hash("g_TeamIcon_MyAllies") + }, + { + "g_TeamIcon_MyAxis", + "Icon name for the axis scores banner when you're on axis.", + generate_hash("g_TeamIcon_MyAxis") + }, + { + "g_TeamIcon_Spectator", + "Icon name for the scores of players who are spectators", + generate_hash("g_TeamIcon_Spectator") + }, + { + "g_TeamName_Allies", + "Allied team name", + generate_hash("g_TeamName_Allies") + }, + { + "g_TeamName_Axis", + "Axis team name", + generate_hash("g_TeamName_Axis") + }, + { + "g_TeamTitleColor_EnemyTeam", + "Enemy team color for titles", + generate_hash("g_TeamTitleColor_EnemyTeam") + }, + { + "g_TeamTitleColor_MyTeam", + "Player team color for titles", + generate_hash("g_TeamTitleColor_MyTeam") + }, + { + "g_TeamTitleColor_Spectator", + "Spectator team color for titles", + generate_hash("g_TeamTitleColor_Spectator") + }, + { + "g_useholdspawndelay", + "Time in milliseconds that the player is unable to 'use' after spawning", + generate_hash("g_useholdspawndelay") + }, + { + "g_useholdtime", + "Time to hold the 'use' button to activate use on a gamepad", + generate_hash("g_useholdtime") + }, + { + "g_voiceChatTalkingDuration", + "Time after the last talk packet was received that the player is considered by the\nserver to still be talking in milliseconds", + generate_hash("g_voiceChatTalkingDuration") + }, + { + "gamedate", + "The date compiled", + generate_hash("gamedate") + }, + { + "gamedvr_active", + "Are we allowed to enable GameDVR or not", + generate_hash("gamedvr_active") + }, + { + "gameMode", + "Current gameMode", + generate_hash("gameMode") + }, + { + "gamename", + "The name of the game", + generate_hash("gamename") + }, + { + "glass_angular_vel", + "Sets the range of angular velocities used by new glass pieces", + generate_hash("glass_angular_vel") + }, + { + "glass_beamDamage", + "The amount of damage beam attacks do to glass", + generate_hash("glass_beamDamage") + }, + { + "glass_break", + "Toggle whether or not glass breaks when shot", + generate_hash("glass_break") + }, + { + "glass_crack_pattern_scale", + "The scale applied to the radius used for the crack pattern", + generate_hash("glass_crack_pattern_scale") + }, + { + "glass_damageToDestroy", + "The amount of damage a piece of glass must take to look damaged", + generate_hash("glass_damageToDestroy") + }, + { + "glass_damageToWeaken", + "The amount of damage a piece of glass must take to look damaged", + generate_hash("glass_damageToWeaken") + }, + { + "glass_edge_angle", + "Sets the range of angle deflections used by new glass pieces on a supported edge", + generate_hash("glass_edge_angle") + }, + { + "glass_fall_delay", + "Sets how long a heavy piece supported by a single edge waits before falling, based on glass_fall_ratio", + generate_hash("glass_fall_delay") + }, + { + "glass_fall_gravity", + "Gravity for falling pieces of glass", + generate_hash("glass_fall_gravity") + }, + { + "glass_fall_ratio", + "Ratio of piece area to supporting edge length squared. Below the min, the piece never falls.", + generate_hash("glass_fall_ratio") + }, + { + "glass_fringe_maxcoverage", + "The maximum portion of the original piece of glass that is allowed to remain after the glass shatters", + generate_hash("glass_fringe_maxcoverage") + }, + { + "glass_fringe_maxsize", + "The maximum area for an edge piece of glass when shattering. Pieces larger than this will be broken into smaller ones", + generate_hash("glass_fringe_maxsize") + }, + { + "glass_fx_chance", + "Chance to play an effect on a small piece of glass when it hits the ground", + generate_hash("glass_fx_chance") + }, + { + "glass_hinge_friction", + "Friction used by moving glass pieces when joined like a hinge to a frame", + generate_hash("glass_hinge_friction") + }, + { + "glass_linear_vel", + "Sets the range of linear velocities used by new glass pieces", + generate_hash("glass_linear_vel") + }, + { + "glass_max_pieces_per_frame", + "Maximum number of pieces to create in one frame. This is a guideline and not a hard limit.", + generate_hash("glass_max_pieces_per_frame") + }, + { + "glass_max_shatter_fx_per_frame", + "Maximum number of shatter effects to play in one frame This is a guideline and not a hard limit.", + generate_hash("glass_max_shatter_fx_per_frame") + }, + { + "glass_meleeDamage", + "The amount of damage melee attacks do to glass", + generate_hash("glass_meleeDamage") + }, + { + "glass_physics_chance", + "The chance for a given shard of glass to use physics", + generate_hash("glass_physics_chance") + }, + { + "glass_physics_maxdist", + "The maximum distance of a glass piece from the player to do physics", + generate_hash("glass_physics_maxdist") + }, + { + "glass_radiusDamageMultiplier", + "The amount to scale damage to glass from grenades and other explosions", + generate_hash("glass_radiusDamageMultiplier") + }, + { + "glass_shard_maxsize", + "The maximum area for a flying piece of glass when shattering. Pieces larger than this will be broken into smaller ones", + generate_hash("glass_shard_maxsize") + }, + { + "glass_shattered_scale", + "The scale of the shattered glass material", + generate_hash("glass_shattered_scale") + }, + { + "glass_trace_interval", + "The length of time, in milliseconds, between glass piece traces", + generate_hash("glass_trace_interval") + }, + { + "gpad_button_deadzone", + "Game pad button deadzone threshhold", + generate_hash("gpad_button_deadzone") + }, + { + "gpad_dpadDebounceTime", + "", + generate_hash("gpad_dpadDebounceTime") + }, + { + "gpad_menu_scroll_delay_first", + "Menu scroll key-repeat delay, for the first repeat, in milliseconds", + generate_hash("gpad_menu_scroll_delay_first") + }, + { + "gpad_menu_scroll_delay_rest_accel", + "Menu scroll key-repeat delay acceleration from start to end, for repeats after the first, in milliseconds per repeat", + generate_hash("gpad_menu_scroll_delay_rest_accel") + }, + { + "gpad_menu_scroll_delay_rest_end", + "Menu scroll key-repeat delay end, for repeats after the first, in milliseconds", + generate_hash("gpad_menu_scroll_delay_rest_end") + }, + { + "gpad_menu_scroll_delay_rest_start", + "Menu scroll key-repeat delay start, for repeats after the first, in milliseconds", + generate_hash("gpad_menu_scroll_delay_rest_start") + }, + { + "gpad_stick_deadzone_max", + "Game pad maximum stick deadzone", + generate_hash("gpad_stick_deadzone_max") + }, + { + "gpad_stick_deadzone_min", + "Game pad minimum stick deadzone", + generate_hash("gpad_stick_deadzone_min") + }, + { + "gpad_stick_pressed", + "Game pad stick pressed threshhold", + generate_hash("gpad_stick_pressed") + }, + { + "gpad_stick_pressed_hysteresis", + "Game pad stick pressed no-change-zone around gpad_stick_pressed to prevent bouncing", + generate_hash("gpad_stick_pressed_hysteresis") + }, + { + "groupDownloadInterval", + "Minimum interval to wait before getting new group counts", + generate_hash("groupDownloadInterval") + }, + { + "groupUploadInterval", + "Minimum interval to wait before setting new group counts", + generate_hash("groupUploadInterval") + }, + { + "heli_barrelMaxVelocity", + "", + generate_hash("heli_barrelMaxVelocity") + }, + { + "heli_barrelRotation", + "How much to rotate the turret barrel when a helicopter fires", + generate_hash("heli_barrelRotation") + }, + { + "heli_barrelSlowdown", + "", + generate_hash("heli_barrelSlowdown") + }, + { + "hiDef", + "True if the game video is running in high-def.", + generate_hash("hiDef") + }, + { + "httpnetfs", + "Stream fastfiles from the specified http server", + generate_hash("httpnetfs") + }, + { + "hud_bloodOverlayLerpRate", + "Rate at which blood overlay fades out", + generate_hash("hud_bloodOverlayLerpRate") + }, + { + "hud_deathQuoteFadeTime", + "The time for the death quote to fade", + generate_hash("hud_deathQuoteFadeTime") + }, + { + "hud_drawHud", + "", + generate_hash("hud_drawHud") + }, + { + "hud_enable", + "Enable hud elements", + generate_hash("hud_enable") + }, + { + "hud_fade_ammodisplay", + "The time for the ammo display to fade in seconds", + generate_hash("hud_fade_ammodisplay") + }, + { + "hud_fade_compass", + "The time for the compass to fade in seconds", + generate_hash("hud_fade_compass") + }, + { + "hud_fade_healthbar", + "The time for the health bar to fade in seconds", + generate_hash("hud_fade_healthbar") + }, + { + "hud_fade_offhand", + "The time for the offhand weapons to fade in seconds", + generate_hash("hud_fade_offhand") + }, + { + "hud_fade_sprint", + "The time for the sprint meter to fade in seconds", + generate_hash("hud_fade_sprint") + }, + { + "hud_flash_period_offhand", + "Offhand weapons flash period on changing weapon", + generate_hash("hud_flash_period_offhand") + }, + { + "hud_flash_time_offhand", + "Offhand weapons flash duration on changing weapon", + generate_hash("hud_flash_time_offhand") + }, + { + "hud_health_pulserate_critical", + "The pulse rate of the 'critical' pulse effect", + generate_hash("hud_health_pulserate_critical") + }, + { + "hud_health_pulserate_injured", + "The pulse rate of the 'injured' pulse effect", + generate_hash("hud_health_pulserate_injured") + }, + { + "hud_health_startpulse_critical", + "The health level at which to start the 'injured' pulse effect", + generate_hash("hud_health_startpulse_critical") + }, + { + "hud_health_startpulse_injured", + "The health level at which to start the 'injured' pulse effect", + generate_hash("hud_health_startpulse_injured") + }, + { + "hudElemPausedBrightness", + "Brightness of the hudelems when the game is paused.", + generate_hash("hudElemPausedBrightness") + }, + { + "hudOutlineDuringADS", + "Turn on the HUD outline (green for friendly, red for enemy) when you are pointing at a player while in ADS.", + generate_hash("hudOutlineDuringADS") + }, + { + "igs_config_dw_filename", + "Name of the configuration file on DW Publisher storage.", + generate_hash("igs_config_dw_filename") + }, + { + "igs_sosp", + "Show Original Season Pass", + generate_hash("igs_sosp") + }, + { + "igs_td", + "Show Trial DLC", + generate_hash("igs_td") + }, + { + "igs_version", + "Version id for the In-game store. Set version number to 0, to disable update.", + generate_hash("igs_version") + }, + { + "in_mouse", + "Initialize the mouse drivers", + generate_hash("in_mouse") + }, + { + "inpubliclobby", + "Currently in a public lobby", + generate_hash("inpubliclobby") + }, + { + "intro", + "Intro movie should play", + generate_hash("intro") + }, + { + "inventory_addEntitlementsToLocalInventory", + "bypass the exchange and directly add entitlements to the local cached player inventory.", + generate_hash("inventory_addEntitlementsToLocalInventory") + }, + { + "inventory_enabled", + "enable/disable the inventory feature", + generate_hash("inventory_enabled") + }, + { + "inventory_enableEntitlementDLCScanning", + "enable scanning of entitlement DLC.", + generate_hash("inventory_enableEntitlementDLCScanning") + }, + { + "inventory_enableRevoke", + "Enable revoke on purchases you no longer have rights to.", + generate_hash("inventory_enableRevoke") + }, + { + "inventory_exchangeEnabled", + "enable/disable the 1st party exchange feature", + generate_hash("inventory_exchangeEnabled") + }, + { + "inventory_exchangeMaxConsumablesPerBoot", + "The maximum number of the same consumable that can be added per boot.", + generate_hash("inventory_exchangeMaxConsumablesPerBoot") + }, + { + "inventory_exchangeRetryBaseMS", + "The amount to delay with each subsequent retry as base value to be multiplied by an exponential factor 1000 = (1000, 2000, 4000, 8000 etc.)", + generate_hash("inventory_exchangeRetryBaseMS") + }, + { + "inventory_exchangeRetryByRound", + "enable/disable retry with exponential delay one round of exchanges at a time (1, 2, 3, 1, 2, 3, 1, 2, 3 etc.), vs exponential delay per exchange (1, 1, 1, 2, 2, 2, 3, 3, 3 etc.)", + generate_hash("inventory_exchangeRetryByRound") + }, + { + "inventory_exchangeRetryMax", + "The number of times to retry for each exchange.", + generate_hash("inventory_exchangeRetryMax") + }, + { + "inventory_excludeEntitlementDLCScanning", + "exclude scanning of entitlement DLC (comma separated list of ids to exclude).", + generate_hash("inventory_excludeEntitlementDLCScanning") + }, + { + "inventory_ignoreDWPushNotification_claimAchievement", + "ignore incoming push notifications from DW to signal item update", + generate_hash("inventory_ignoreDWPushNotification_claimAchievement") + }, + { + "inventory_ignoreDWPushNotification_itemUpdate", + "ignore incoming push notifications from DW to signal item update", + generate_hash("inventory_ignoreDWPushNotification_itemUpdate") + }, + { + "inventory_taskDefaultTimeout", + "default timeout for inventory tasks (in seconds)", + generate_hash("inventory_taskDefaultTimeout") + }, + { + "inventory_taskExchangeTimeout", + "default timeout for inventory exchange tasks (in seconds)", + generate_hash("inventory_taskExchangeTimeout") + }, + { + "inventory_taskGetTimeout", + "default timeout for inventory GET tasks (in seconds)", + generate_hash("inventory_taskGetTimeout") + }, + { + "inventory_triggerExchangeOnContentMount", + "trigger an exchange after mounting new content packs", + generate_hash("inventory_triggerExchangeOnContentMount") + }, + { + "inventory_triggerExchangeOnStoreExit", + "trigger an exchange when exiting the store", + generate_hash("inventory_triggerExchangeOnStoreExit") + }, + { + "iotd_active", + "Is the IOTD system enabled", + generate_hash("iotd_active") + }, + { + "iotd_retry", + "Can the IOTD system retry fetching data from Demonware", + generate_hash("iotd_retry") + }, + { + "jump_slowdownEnable", + "Slow player movement after jumping", + generate_hash("jump_slowdownEnable") + }, + { + "laserDebug", + "Enables the display of various debug info.", + generate_hash("laserDebug") + }, + { + "laserLightRadius", + "undefined", + generate_hash("laserLightRadius") + }, + { + "laserRadius", + "undefined", + generate_hash("laserRadius") + }, + { + "lb_filter", + "Filter applied to the leaderboard display: ('none','friends','facebook_friends')", + generate_hash("lb_filter") + }, + { + "lb_group", + "GroupID applied to the leaderboard display", + generate_hash("lb_group") + }, + { + "lb_maxrows", + "Maximum number of rows to fetch", + generate_hash("lb_maxrows") + }, + { + "lb_minrefresh", + "Minimum time (in seconds) between leaderboard fetches", + generate_hash("lb_minrefresh") + }, + { + "lb_readDelay", + "Delay time between reads(in milliseconds) between leaderboard fetches", + generate_hash("lb_readDelay") + }, + { + "lb_throttle_time", + "Lobby throttling amount", + generate_hash("lb_throttle_time") + }, + { + "lb_times_in_window", + "Lobby throttling window amount", + generate_hash("lb_times_in_window") + }, + { + "lb_window", + "Lobby throttling window", + generate_hash("lb_window") + }, + { + "live_qosec_firstupdatems", + "MS to wait before deciding to early out qos", + generate_hash("live_qosec_firstupdatems") + }, + { + "live_qosec_lastupdatems", + "MS since last update required to early out qos", + generate_hash("live_qosec_lastupdatems") + }, + { + "live_qosec_minpercent", + "Minimum percentage of probe results required before early outing qos", + generate_hash("live_qosec_minpercent") + }, + { + "live_qosec_minprobes", + "Minimum probe results required before early outing qos", + generate_hash("live_qosec_minprobes") + }, + { + "liveanticheatunknowndvar", + "Live Anti Cheat Unknown Dvar", + generate_hash("liveanticheatunknowndvar") + }, + { + "livestreaming_active", + "Are we allowed to enable LiveStreaming or not", + generate_hash("livestreaming_active") + }, + { + "loading_sre_fatal", + "Loading errors prevent level from loading.", + generate_hash("loading_sre_fatal") + }, + { + "lobby_animationSpeed", + "How long each frame of the animation should draw, in milliseconds", + generate_hash("lobby_animationSpeed") + }, + { + "lobby_animationTilesHigh", + "How many animation tiles high is the searching_for_player texture", + generate_hash("lobby_animationTilesHigh") + }, + { + "lobby_animationTilesWide", + "How many animation tiles wide is the searching_for_player texture", + generate_hash("lobby_animationTilesWide") + }, + { + "lobby_numAnimationFrames", + "How many animation tiles are in the searching_for_player texture", + generate_hash("lobby_numAnimationFrames") + }, + { + "lobby_searchingPartyColor", + "The color to show that we're searching for that slot when shown in lobbies", + generate_hash("lobby_searchingPartyColor") + }, + { + "loc_language", + "Language", + generate_hash("loc_language") + }, + { + "loc_translate", + "Enable translations", + generate_hash("loc_translate") + }, + { + "log_host_migration_chance", + "The % chance of host migration results telemetry", + generate_hash("log_host_migration_chance") + }, + { + "log_party_state", + "Log party state updates to Black Box system", + generate_hash("log_party_state") + }, + { + "lowAmmoWarningColor1", + "Color 1 of 2 to oscilate between", + generate_hash("lowAmmoWarningColor1") + }, + { + "lowAmmoWarningColor2", + "Color 2 of 2 to oscilate between", + generate_hash("lowAmmoWarningColor2") + }, + { + "lowAmmoWarningNoAmmoColor1", + "Like lowAmmoWarningColor1, but when no ammo.", + generate_hash("lowAmmoWarningNoAmmoColor1") + }, + { + "lowAmmoWarningNoAmmoColor2", + "lowAmmoWarningColor2, but when no ammo.", + generate_hash("lowAmmoWarningNoAmmoColor2") + }, + { + "lowAmmoWarningNoReloadColor1", + "Like lowAmmoWarningColor1, but when no ammo.", + generate_hash("lowAmmoWarningNoReloadColor1") + }, + { + "lowAmmoWarningNoReloadColor2", + "lowAmmoWarningColor2, but when no ammo.", + generate_hash("lowAmmoWarningNoReloadColor2") + }, + { + "lowAmmoWarningPulseFreq", + "Frequency of the pulse (oscilation between the 2 colors)", + generate_hash("lowAmmoWarningPulseFreq") + }, + { + "lowAmmoWarningPulseMax", + "Min of oscilation range: 0 is color1 and 1.0 is color2. Can be < 0, and the wave will clip at 0.", + generate_hash("lowAmmoWarningPulseMax") + }, + { + "lowAmmoWarningPulseMin", + "Max of oscilation range: 0 is color1 and 1.0 is color2. Can be > 1.0, and the wave will clip at 1.0.", + generate_hash("lowAmmoWarningPulseMin") + }, + { + "lsp_enumertion_max_retry_time", + "Max time that the LSP enumeration can retry", + generate_hash("lsp_enumertion_max_retry_time") + }, + { + "lsp_enumertion_retry_step", + "Step in m/s for the LSP enumeration retry", + generate_hash("lsp_enumertion_retry_step") + }, + { + "lui_demoMode", + "Check if the game is in demo mode.", + generate_hash("lui_demoMode") + }, + { + "lui_FFotDSupportEnabled", + "Enables lui to update itself via the ffotd", + generate_hash("lui_FFotDSupportEnabled") + }, + { + "lui_hud_motion_angle_ease_speed", + "Hud motion ease percentage of degrees per second", + generate_hash("lui_hud_motion_angle_ease_speed") + }, + { + "lui_hud_motion_bob_scale", + "Hud motion bob scale", + generate_hash("lui_hud_motion_bob_scale") + }, + { + "lui_hud_motion_enabled", + "Enable hud motion", + generate_hash("lui_hud_motion_enabled") + }, + { + "lui_hud_motion_perspective", + "value for hud motion perspective transform in pixels", + generate_hash("lui_hud_motion_perspective") + }, + { + "lui_hud_motion_rotation_max", + "Hud motion rotation max", + generate_hash("lui_hud_motion_rotation_max") + }, + { + "lui_hud_motion_rotation_scale", + "Hud motion rotation scale", + generate_hash("lui_hud_motion_rotation_scale") + }, + { + "lui_hud_motion_trans_ease_speed", + "Hud motion ease percentage of pixels per second", + generate_hash("lui_hud_motion_trans_ease_speed") + }, + { + "lui_hud_motion_translation_max", + "Hud motion translation max", + generate_hash("lui_hud_motion_translation_max") + }, + { + "lui_hud_motion_translation_scale", + "Hud motion translation scale", + generate_hash("lui_hud_motion_translation_scale") + }, + { + "lui_loot_duplicateredemption", + "Whether a user can redeem duplicate loot items in the Armory", + generate_hash("lui_loot_duplicateredemption") + }, + { + "LUI_MemErrorsFatal", + "Out of memory errors cause drops when true, reinits the UI system if false", + generate_hash("LUI_MemErrorsFatal") + }, + { + "lui_menuFlowEnabled", + "Enables LUI menu flow", + generate_hash("lui_menuFlowEnabled") + }, + { + "lui_mlg_rules_unlocked", + "Whether MLG rules are unlocked", + generate_hash("lui_mlg_rules_unlocked") + }, + { + "lui_priv_lobby_team", + "Team selected in private match lobby", + generate_hash("lui_priv_lobby_team") + }, + { + "lui_splitscreensignin_menu", + "Enables the LUI splitscreensignin menu", + generate_hash("lui_splitscreensignin_menu") + }, + { + "lui_splitscreenupscaling", + "Force splitscreen upscaling off/on (-1 off, 1 on) -- requires map change", + generate_hash("lui_splitscreenupscaling") + }, + { + "lui_systemlink_menu", + "Enables the LUI systemlink menu", + generate_hash("lui_systemlink_menu") + }, + { + "lui_waitingforgavelmessagesconfirmed", + "", + generate_hash("lui_waitingforgavelmessagesconfirmed") + }, + { + "lui_waitingfornetworktype", + "value is LuiWaitingForNetworkType enum", + generate_hash("lui_waitingfornetworktype") + }, + { + "lui_waitingforonlinedatafetch_controller", + "the controller index that is fetching the online stats data", + generate_hash("lui_waitingforonlinedatafetch_controller") + }, + { + "LUI_WorkerCmdGC", + "Dev-only flag to enable/disable LUI workerCmd GC thread", + generate_hash("LUI_WorkerCmdGC") + }, + { + "lui_xboxlive_menu", + "Enables the LUI xboxlive menu", + generate_hash("lui_xboxlive_menu") + }, + { + "m_filter", + "Allow mouse movement smoothing", + generate_hash("m_filter") + }, + { + "m_forward", + "Forward speed in units per second", + generate_hash("m_forward") + }, + { + "m_pitch", + "Default pitch", + generate_hash("m_pitch") + }, + { + "m_side", + "Sideways motion in units per second", + generate_hash("m_side") + }, + { + "m_yaw", + "Default yaw", + generate_hash("m_yaw") + }, + { + "manifestfs", + "Use a manifest file to read segmented fastfiles", + generate_hash("manifestfs") + }, + { + "mapname", + "The current map name", + generate_hash("mapname") + }, + { + "mapPackMPGroupFourFlags", + "Map pack flags that comprise MP ala carte map pack 1", + generate_hash("mapPackMPGroupFourFlags") + }, + { + "mapPackMPGroupFreeFlags", + "Map pack flags that comprise the free MP ala carte map pack", + generate_hash("mapPackMPGroupFreeFlags") + }, + { + "mapPackMPGroupOneFlags", + "Map pack flags that comprise MP ala carte map pack 1", + generate_hash("mapPackMPGroupOneFlags") + }, + { + "mapPackMPGroupThreeFlags", + "Map pack flags that comprise MP ala carte map pack 1", + generate_hash("mapPackMPGroupThreeFlags") + }, + { + "mapPackMPGroupTwoFlags", + "Map pack flags that comprise MP ala carte map pack 1", + generate_hash("mapPackMPGroupTwoFlags") + }, + { + "marketing_active", + "Are we allowed to enable Marketing Comms or not", + generate_hash("marketing_active") + }, + { + "marketing_refresh_time", + "time in seconds to wait before refreshing marketing messages from demonware", + generate_hash("marketing_refresh_time") + }, + { + "matchdata_active", + "Are match data uploads enabled", + generate_hash("matchdata_active") + }, + { + "matchdata_maxcompressionbuffer", + "Max SP match data compression buffer to use (in bytes)", + generate_hash("matchdata_maxcompressionbuffer") + }, + { + "matchmaking_debug", + "Enable matchmaking debugging information", + generate_hash("matchmaking_debug") + }, + { + "max_ping_threshold_good", + "max ping value to be considered as good", + generate_hash("max_ping_threshold_good") + }, + { + "max_ping_threshold_medium", + "max ping value to be considered as medium", + generate_hash("max_ping_threshold_medium") + }, + { + "max_xp_per_match", + "", + generate_hash("max_xp_per_match") + }, + { + "maxPrestigeOverride", + "Overrides the maximum prestige level, disabled if 0.", + generate_hash("maxPrestigeOverride") + }, + { + "maxVoicePacketsPerSec", + "", + generate_hash("maxVoicePacketsPerSec") + }, + { + "maxVoicePacketsPerSecForServer", + "", + generate_hash("maxVoicePacketsPerSecForServer") + }, + { + "mdsd", + "enable match data stat delta logging?", + generate_hash("mdsd") + }, + { + "melee_debug", + "Turn on debug lines for melee traces", + generate_hash("melee_debug") + }, + { + "migration_dvarErrors", + "Whether to check for illegal script dvar changes.", + generate_hash("migration_dvarErrors") + }, + { + "min_wait_for_players", + "", + generate_hash("min_wait_for_players") + }, + { + "missileRemoteFOV", + "Remote missile-cam, FOV to use.", + generate_hash("missileRemoteFOV") + }, + { + "missileRemoteSteerPitchRange", + "Remote-controlled missile allowed up/down range. To keep players from steering missiles above the horizon.", + generate_hash("missileRemoteSteerPitchRange") + }, + { + "missileRemoteSteerPitchRate", + "Remote-controlled missile up/down steering speed.", + generate_hash("missileRemoteSteerPitchRate") + }, + { + "missileRemoteSteerYawRate", + "Remote-controlled missile left/right steering speed.", + generate_hash("missileRemoteSteerYawRate") + }, + { + "mm_aw_onboarding_rank", + "If a player is at or above this rank in AW, she is not considered onboarding", + generate_hash("mm_aw_onboarding_rank") + }, + { + "mm_blops2_onboarding_skill", + "Used to determine onboarding status for Ghosts", + generate_hash("mm_blops2_onboarding_skill") + }, + { + "mm_bucket_option", + "if using bucketing, describes what pools can join with each other", + generate_hash("mm_bucket_option") + }, + { + "mm_country_code", + "country code", + generate_hash("mm_country_code") + }, + { + "mm_ghosts_onboarding_skill", + "Used to determine onboarding status for Ghosts", + generate_hash("mm_ghosts_onboarding_skill") + }, + { + "mm_past_title_stats_source", + "what type of information do we use from the past titles (rank vs kdr, etc)", + generate_hash("mm_past_title_stats_source") + }, + { + "mm_skill_calculation_type", + "", + generate_hash("mm_skill_calculation_type") + }, + { + "mm_skill_enforcement", + "", + generate_hash("mm_skill_enforcement") + }, + { + "mm_skill_lower_bucket", + "lower mm skill bucket", + generate_hash("mm_skill_lower_bucket") + }, + { + "mm_skill_param_delta", + "Delta parameter for Johnson SU distribution curve", + generate_hash("mm_skill_param_delta") + }, + { + "mm_skill_param_gamma", + "Gamma parameter for Johnson SU distribution curve", + generate_hash("mm_skill_param_gamma") + }, + { + "mm_skill_param_lambda", + "Lambda parameter for Johnson SU distribution curve", + generate_hash("mm_skill_param_lambda") + }, + { + "mm_skill_param_xi", + "Xi parameter for Johnson SU distribution curve", + generate_hash("mm_skill_param_xi") + }, + { + "mm_skill_strict_enforcement", + "", + generate_hash("mm_skill_strict_enforcement") + }, + { + "mm_skill_type", + "mm skill type", + generate_hash("mm_skill_type") + }, + { + "mm_skill_upper_bucket", + "upper mm skill bucket", + generate_hash("mm_skill_upper_bucket") + }, + { + "mm_sph_1", + "", + generate_hash("mm_sph_1") + }, + { + "mm_sph_10", + "", + generate_hash("mm_sph_10") + }, + { + "mm_sph_11", + "", + generate_hash("mm_sph_11") + }, + { + "mm_sph_12", + "", + generate_hash("mm_sph_12") + }, + { + "mm_sph_13", + "", + generate_hash("mm_sph_13") + }, + { + "mm_sph_14", + "", + generate_hash("mm_sph_14") + }, + { + "mm_sph_15", + "", + generate_hash("mm_sph_15") + }, + { + "mm_sph_16", + "", + generate_hash("mm_sph_16") + }, + { + "mm_sph_17", + "", + generate_hash("mm_sph_17") + }, + { + "mm_sph_18", + "", + generate_hash("mm_sph_18") + }, + { + "mm_sph_2", + "", + generate_hash("mm_sph_2") + }, + { + "mm_sph_3", + "", + generate_hash("mm_sph_3") + }, + { + "mm_sph_4", + "", + generate_hash("mm_sph_4") + }, + { + "mm_sph_5", + "", + generate_hash("mm_sph_5") + }, + { + "mm_sph_6", + "", + generate_hash("mm_sph_6") + }, + { + "mm_sph_7", + "", + generate_hash("mm_sph_7") + }, + { + "mm_sph_8", + "", + generate_hash("mm_sph_8") + }, + { + "mm_sph_9", + "", + generate_hash("mm_sph_9") + }, + { + "mm_split_population", + "", + generate_hash("mm_split_population") + }, + { + "mm_test_type", + "mm test type", + generate_hash("mm_test_type") + }, + { + "mm_use_onboarding_skill", + "If set, we will for the player's skill to be the lowest available", + generate_hash("mm_use_onboarding_skill") + }, + { + "monkeytoy", + "Restrict console access", + generate_hash("monkeytoy") + }, + { + "motd", + "", + generate_hash("motd") + }, + { + "motd_store_link", + "Add a link to the in-game store in the MOTD popup", + generate_hash("motd_store_link") + }, + { + "motionTrackerBlurDuration", + "The motion blur duration for motion tracker dots", + generate_hash("motionTrackerBlurDuration") + }, + { + "motionTrackerCenterX", + "", + generate_hash("motionTrackerCenterX") + }, + { + "motionTrackerCenterY", + "", + generate_hash("motionTrackerCenterY") + }, + { + "motionTrackerPingFadeTime", + "How long an enemy is visible on the motion tracker after being detected", + generate_hash("motionTrackerPingFadeTime") + }, + { + "motionTrackerPingPitchAddPerEnemy", + "The added percentage of pitch for each additional enemy that is detected (final pitch = base pitch * (1 + enemy count * this))", + generate_hash("motionTrackerPingPitchAddPerEnemy") + }, + { + "motionTrackerPingPitchBase", + "The pitch of the motion tracker sound for a nearby enemy", + generate_hash("motionTrackerPingPitchBase") + }, + { + "motionTrackerPingPitchNearby", + "The pitch of the motion tracker sound for a nearby enemy", + generate_hash("motionTrackerPingPitchNearby") + }, + { + "motionTrackerPingSize", + "The width and height of the motion tracker's enemy indicators as a percentage of motion tracker scale", + generate_hash("motionTrackerPingSize") + }, + { + "msg_field_delta2", + "enable the delta2 serialization.", + generate_hash("msg_field_delta2") + }, + { + "name", + "Player name", + generate_hash("name") + }, + { + "net_authPort", + "UDP port for Steam authentication", + generate_hash("net_authPort") + }, + { + "net_ip", + "Network IP Address", + generate_hash("net_ip") + }, + { + "net_masterServerPort", + "UDP port for Steam server browser", + generate_hash("net_masterServerPort") + }, + { + "net_noudp", + "Disable UDP", + generate_hash("net_noudp") + }, + { + "net_port", + "Network port", + generate_hash("net_port") + }, + { + "net_socksEnabled", + "Enable network sockets", + generate_hash("net_socksEnabled") + }, + { + "net_socksPassword", + "Network socket password", + generate_hash("net_socksPassword") + }, + { + "net_socksPort", + "Network socket port", + generate_hash("net_socksPort") + }, + { + "net_socksServer", + "Network socket server", + generate_hash("net_socksServer") + }, + { + "net_socksUsername", + "Network socket username", + generate_hash("net_socksUsername") + }, + { + "nextmap", + "Next map to play", + generate_hash("nextmap") + }, + { + "nightVisionDisableEffects", + "", + generate_hash("nightVisionDisableEffects") + }, + { + "nightVisionFadeInOutTime", + "How long the fade to/from black lasts when putting on or removing night vision goggles.", + generate_hash("nightVisionFadeInOutTime") + }, + { + "nightVisionPowerOnTime", + "How long the black-to-nightvision fade lasts when turning on the goggles.", + generate_hash("nightVisionPowerOnTime") + }, + { + "num_available_map_packs", + "Number of map packs available for this platform", + generate_hash("num_available_map_packs") + }, + { + "objectiveFontSize", + "Onscreen Objective Pointer - Fontsize of the icon's text.", + generate_hash("objectiveFontSize") + }, + { + "objectiveTextOffsetY", + "Onscreen Objective Pointer - Offset of the icon's text.", + generate_hash("objectiveTextOffsetY") + }, + { + "onlinegame", + "Current game is an online game with stats, custom classes, unlocks", + generate_hash("onlinegame") + }, + { + "overrideNVGModelWithKnife", + "When true, nightvision animations will attach the weapDef's knife model instead of the night vision goggles.", + generate_hash("overrideNVGModelWithKnife") + }, + { + "overtimeTimeLimit", + "", + generate_hash("overtimeTimeLimit") + }, + { + "p2pAuth_allow_steam_p2p", + "Determines if Steam based P2P is allowed if direct connectivity is not possible.", + generate_hash("p2pAuth_allow_steam_p2p") + }, + { + "p2pAuth_disable", + "", + generate_hash("p2pAuth_disable") + }, + { + "paintExplosionRadius", + "The radius of the paint grenade explosion", + generate_hash("paintExplosionRadius") + }, + { + "painVisionLerpOutRate", + "Rate at which pain vision effect lerps out", + generate_hash("painVisionLerpOutRate") + }, + { + "painVisionTriggerHealth", + "Health (0 to 1) that will trigger the pain vision effect", + generate_hash("painVisionTriggerHealth") + }, + { + "party_alternateMapVoteStatus", + "Alternate map vote progress", + generate_hash("party_alternateMapVoteStatus") + }, + { + "party_dlc_only_intended_mappacks", + "When selecting next map for rotation, should any maps not in the intended search be excluded, even if available?", + generate_hash("party_dlc_only_intended_mappacks") + }, + { + "party_firstSubpartyIndex", + "Determines sort order and coloring of parties in lobbies. Randomly set by code. Dvar provided for debugging.", + generate_hash("party_firstSubpartyIndex") + }, + { + "party_followPartyHostOutOfGames", + "Whether we should follow our party host out of a game in progress.", + generate_hash("party_followPartyHostOutOfGames") + }, + { + "party_gamesize", + "Current maximum game size", + generate_hash("party_gamesize") + }, + { + "party_gametype", + "Current gametype", + generate_hash("party_gametype") + }, + { + "party_inactiveHeartbeatPeriod", + "How often to send inactive party keep alive packets in milliseconds.", + generate_hash("party_inactiveHeartbeatPeriod") + }, + { + "party_initial_dlc_search_timer", + "Time until DLC enabled search should show an error dialog suggesting the user consider going to non dlc search", + generate_hash("party_initial_dlc_search_timer") + }, + { + "party_IsLocalClientSelected", + "True if selected player is a local client. Only valid when used with party feeders.", + generate_hash("party_IsLocalClientSelected") + }, + { + "party_kickplayerquestion", + "String to store the question about kicking the selected player", + generate_hash("party_kickplayerquestion") + }, + { + "party_listFocus", + "True when an item in the party list has focus.", + generate_hash("party_listFocus") + }, + { + "party_lobbyPlayerCount", + "Number of players currently in the party/lobby", + generate_hash("party_lobbyPlayerCount") + }, + { + "party_mapname", + "Current map name", + generate_hash("party_mapname") + }, + { + "party_mapvote_entrya_mapname", + "Primary map vote entry name", + generate_hash("party_mapvote_entrya_mapname") + }, + { + "party_mapvote_entryb_mapname", + "Alternate map vote entry name", + generate_hash("party_mapvote_entryb_mapname") + }, + { + "party_matchedPlayerCount", + "Number of matched players before revealing their true names", + generate_hash("party_matchedPlayerCount") + }, + { + "party_maxplayers", + "Maximum number of players in a party", + generate_hash("party_maxplayers") + }, + { + "party_maxPrivatePartyPlayers", + "Max number of players allowed in a private party.", + generate_hash("party_maxPrivatePartyPlayers") + }, + { + "party_maxTeamDiff", + "Maximum difference allowed between teams before starting a match", + generate_hash("party_maxTeamDiff") + }, + { + "party_membersMissingMapPack", + "Whether any party member is missing one of the enabled map packs. Only valid after running partyUpdateMissingMapPackDvar", + generate_hash("party_membersMissingMapPack") + }, + { + "party_minLobbyTime", + "Minimum time (in seconds) for a lobby to be open before auto starting a match", + generate_hash("party_minLobbyTime") + }, + { + "party_minplayers", + "Minimum number of players in a party", + generate_hash("party_minplayers") + }, + { + "party_nextMapVoteStatus", + "Next map vote progress", + generate_hash("party_nextMapVoteStatus") + }, + { + "party_partyPlayerCount", + "Number of players currently in the party/lobby", + generate_hash("party_partyPlayerCount") + }, + { + "party_partyPlayerCountNum", + "Number of players currently in the party/lobby", + generate_hash("party_partyPlayerCountNum") + }, + { + "party_playersCoop", + "True if the current playlist places all players on the allies team", + generate_hash("party_playersCoop") + }, + { + "party_playervisible", + "Whether selected player in party is showing true info or not. Only valid when used with party feeders.", + generate_hash("party_playervisible") + }, + { + "party_randomMapVoteStatus", + "Random map vote progress", + generate_hash("party_randomMapVoteStatus") + }, + { + "party_resume_dlc_search_timer", + "Time until DLC enabled search should show an error dialog suggesting the user consider going to non dlc search", + generate_hash("party_resume_dlc_search_timer") + }, + { + "party_search_for_dlc_content", + "search for DLC enabled games else standard maps only will be used", + generate_hash("party_search_for_dlc_content") + }, + { + "party_selectedIndex", + "Current selected player index in the feeder.", + generate_hash("party_selectedIndex") + }, + { + "party_selectedIndexChangedTime", + "Time stamp in milliseconds when the selected index last changed.", + generate_hash("party_selectedIndexChangedTime") + }, + { + "party_statusString", + "Party Status (localized )", + generate_hash("party_statusString") + }, + { + "party_teambased", + "True if the current playlist is team based", + generate_hash("party_teambased") + }, + { + "party_teamsVisible", + "teams are visible in UI", + generate_hash("party_teamsVisible") + }, + { + "party_timer", + "Time until game begins in seconds, for UI display", + generate_hash("party_timer") + }, + { + "partyChatDisallowed", + "Whether to disallow ps4 Live Party Chat", + generate_hash("partyChatDisallowed") + }, + { + "partymigrate_broadcast_interval", + "Time between telling people who the new host is when migrating lobby", + generate_hash("partymigrate_broadcast_interval") + }, + { + "partymigrate_cpuBonusPing", + "The ping rewarded to a CPU meeting the bonus threshold when scoring hosts.", + generate_hash("partymigrate_cpuBonusPing") + }, + { + "partymigrate_cpuBonusThreshold", + "The required excess %CPU speed to get a bonus when scoring hosts.", + generate_hash("partymigrate_cpuBonusThreshold") + }, + { + "partymigrate_logResults", + "Instrumentation - Whether to log the best host calculation results. 0 is disabled, 1 for games, 2 for parties, 3 for both.", + generate_hash("partymigrate_logResults") + }, + { + "partymigrate_makeHostTimeout", + "Time before giving up on makeHost requests", + generate_hash("partymigrate_makeHostTimeout") + }, + { + "partymigrate_pingtest_active", + "Whether to do a ping test when lobby migrating", + generate_hash("partymigrate_pingtest_active") + }, + { + "partymigrate_pingtest_filterThreshold", + "Acceptable ping difference from best ping host for host selection (ms)", + generate_hash("partymigrate_pingtest_filterThreshold") + }, + { + "partymigrate_pingtest_minThreshold", + "Minimum meaningful ping delta for host selection (ms)", + generate_hash("partymigrate_pingtest_minThreshold") + }, + { + "partymigrate_pingtest_retry", + "Time between ping tests when migrating lobby", + generate_hash("partymigrate_pingtest_retry") + }, + { + "partymigrate_pingtest_timeout", + "Time to give up on ping tests when migrating lobby", + generate_hash("partymigrate_pingtest_timeout") + }, + { + "partymigrate_preferSameHost", + "When possible, prefer keeping the same host on migrations", + generate_hash("partymigrate_preferSameHost") + }, + { + "partymigrate_selectiontime", + "Time before requiring a host selection when migrating lobby", + generate_hash("partymigrate_selectiontime") + }, + { + "partymigrate_timeout", + "Time before giving up on lobby migration if we hear nothing", + generate_hash("partymigrate_timeout") + }, + { + "partymigrate_timeoutmax", + "Time before giving up on lobby migration if we hear nothing", + generate_hash("partymigrate_timeoutmax") + }, + { + "partymigrate_uploadtest_minThreshold", + "Minimum meaningful upload bandwidth delta for host selection (bps)", + generate_hash("partymigrate_uploadtest_minThreshold") + }, + { + "password", + "", + generate_hash("password") + }, + { + "perk_armorPiercingDamage", + "", + generate_hash("perk_armorPiercingDamage") + }, + { + "perk_blastShieldScale", + "", + generate_hash("perk_blastShieldScale") + }, + { + "perk_blastShieldScale_HC", + "", + generate_hash("perk_blastShieldScale_HC") + }, + { + "perk_bulletPenetrationMultiplier", + "Multiplier for extra bullet penetration", + generate_hash("perk_bulletPenetrationMultiplier") + }, + { + "perk_extendedMagsMGAmmo", + "Number of extra bullets per clip for machine gun weapons with the extended mags perk.", + generate_hash("perk_extendedMagsMGAmmo") + }, + { + "perk_extendedMagsPistolAmmo", + "Number of extra bullets per clip for pistol weapons with the extended mags perk.", + generate_hash("perk_extendedMagsPistolAmmo") + }, + { + "perk_extendedMagsRifleAmmo", + "Number of extra bullets per clip for rifle weapons with the extended mags perk.", + generate_hash("perk_extendedMagsRifleAmmo") + }, + { + "perk_extendedMagsSMGAmmo", + "Number of extra bullets per clip for sub machine gun weapons with the extended mags perk.", + generate_hash("perk_extendedMagsSMGAmmo") + }, + { + "perk_extendedMagsSpreadAmmo", + "Number of extra bullets per clip for spread weapons with the extended mags perk.", + generate_hash("perk_extendedMagsSpreadAmmo") + }, + { + "perk_extraBreath", + "Number of extra seconds a player can hold his breath", + generate_hash("perk_extraBreath") + }, + { + "perk_fastClimb", + "Scales the ladder climb time", + generate_hash("perk_fastClimb") + }, + { + "perk_fastRegenRate", + "", + generate_hash("perk_fastRegenRate") + }, + { + "perk_fastRegenWaitMS", + "", + generate_hash("perk_fastRegenWaitMS") + }, + { + "perk_fastSnipeScale", + "Scales the recovery speed of the view kick when using a sniper.", + generate_hash("perk_fastSnipeScale") + }, + { + "perk_footstepVolumeAlly", + "", + generate_hash("perk_footstepVolumeAlly") + }, + { + "perk_footstepVolumeEnemy", + "", + generate_hash("perk_footstepVolumeEnemy") + }, + { + "perk_footstepVolumePlayer", + "", + generate_hash("perk_footstepVolumePlayer") + }, + { + "perk_footstepVolumeSelectiveHearingMin", + "", + generate_hash("perk_footstepVolumeSelectiveHearingMin") + }, + { + "perk_improvedExtraBreath", + "Number of extra seconds a player can hold his breath", + generate_hash("perk_improvedExtraBreath") + }, + { + "perk_lightWeightViewBobScale", + "Scale for first person view movement while lightweight.", + generate_hash("perk_lightWeightViewBobScale") + }, + { + "perk_numExtraLethal", + "Number of extra lethal grenades", + generate_hash("perk_numExtraLethal") + }, + { + "perk_numExtraTactical", + "Number of extra tactical grenades", + generate_hash("perk_numExtraTactical") + }, + { + "perk_parabolicAngle", + "Eavesdrop perk's effective FOV angle", + generate_hash("perk_parabolicAngle") + }, + { + "perk_parabolicIcon", + "Eavesdrop icon to use when displaying eavesdropped voice chats", + generate_hash("perk_parabolicIcon") + }, + { + "perk_parabolicRadius", + "Eavesdrop perk's effective radius", + generate_hash("perk_parabolicRadius") + }, + { + "perk_quickDrawSpeedScale", + "Scales the 'Hip to ADS' transition speed.", + generate_hash("perk_quickDrawSpeedScale") + }, + { + "perk_quickDrawSpeedScaleSniper", + "Scales the 'Hip to ADS' transition speed.", + generate_hash("perk_quickDrawSpeedScaleSniper") + }, + { + "perk_scavengerMode", + "", + generate_hash("perk_scavengerMode") + }, + { + "perk_sprintMultiplier", + "Multiplier for player_sprinttime", + generate_hash("perk_sprintMultiplier") + }, + { + "perk_sprintRecoveryMultiplierActual", + "", + generate_hash("perk_sprintRecoveryMultiplierActual") + }, + { + "perk_sprintRecoveryMultiplierVisual", + "", + generate_hash("perk_sprintRecoveryMultiplierVisual") + }, + { + "perk_weapRateMultiplier", + "Percentage of weapon firing rate to use", + generate_hash("perk_weapRateMultiplier") + }, + { + "perk_weapReloadMultiplier", + "Percentage of weapon reload time to use", + generate_hash("perk_weapReloadMultiplier") + }, + { + "perk_weapSpreadMultiplier", + "Percentage of weapon spread to use", + generate_hash("perk_weapSpreadMultiplier") + }, + { + "phys_autoDisableLinear", + "A body must have linear velocity less than this to be considered idle.", + generate_hash("phys_autoDisableLinear") + }, + { + "phys_autoDisableTime", + "The amount of time a body must be idle for it to go to sleep.", + generate_hash("phys_autoDisableTime") + }, + { + "phys_bulletSpinScale", + "Scale of the effective offset from the center of mass for the bullet impacts.", + generate_hash("phys_bulletSpinScale") + }, + { + "phys_bulletUpBias", + "Up Bias for the direction of the bullet impact.", + generate_hash("phys_bulletUpBias") + }, + { + "phys_dragAngular", + "The amount of angular drag, applied globally", + generate_hash("phys_dragAngular") + }, + { + "phys_dragLinear", + "The amount of linear drag, applied globally", + generate_hash("phys_dragLinear") + }, + { + "phys_gravity", + "Physics gravity in units/sec^2.", + generate_hash("phys_gravity") + }, + { + "phys_gravity_ragdoll", + "Physics gravity used by ragdolls in units/sec^2.", + generate_hash("phys_gravity_ragdoll") + }, + { + "phys_gravityChangeWakeupRadius", + "The radius around the player within which objects get awakened when gravity changes", + generate_hash("phys_gravityChangeWakeupRadius") + }, + { + "phys_jitterMaxMass", + "Maximum mass to jitter - jitter will fall off up to this mass", + generate_hash("phys_jitterMaxMass") + }, + { + "physVeh_explodeForce", + "The force applied to physics vehicles due to explosions", + generate_hash("physVeh_explodeForce") + }, + { + "physVeh_explodeSpinScale", + "The max (random) offset from the center of mass at which splash damage applies its force", + generate_hash("physVeh_explodeSpinScale") + }, + { + "physVeh_jump", + "Set to 1 to make a vehicle jump.", + generate_hash("physVeh_jump") + }, + { + "physVeh_minContactImpulse", + "The minimum impulse needed to register a contact notification", + generate_hash("physVeh_minContactImpulse") + }, + { + "physVeh_minImpactMomentum", + "The minimum collision momentum needed to register an impact", + generate_hash("physVeh_minImpactMomentum") + }, + { + "physVeh_StepsPerFrame", + "The number of physics timesteps that the server frame will be divided into.", + generate_hash("physVeh_StepsPerFrame") + }, + { + "pickupPrints", + "Print a message to the game window when picking up ammo, etc.", + generate_hash("pickupPrints") + }, + { + "player_breath_snd_delay", + "The delay before playing the breathe in sound", + generate_hash("player_breath_snd_delay") + }, + { + "player_breath_snd_lerp", + "The interpolation rate for the player hold breath sound", + generate_hash("player_breath_snd_lerp") + }, + { + "player_current_floor", + "", + generate_hash("player_current_floor") + }, + { + "player_MGUseRadius", + "The radius within which a player can mount a machine gun", + generate_hash("player_MGUseRadius") + }, + { + "player_stunWhiteFlash", + "If enabled, player's screens will flash white when they are stunned.", + generate_hash("player_stunWhiteFlash") + }, + { + "player_throwbackInnerRadius", + "The radius to a live grenade player must be within initially to do a throwback", + generate_hash("player_throwbackInnerRadius") + }, + { + "player_throwbackOuterRadius", + "The radius player is allow to throwback a grenade once the player has been in the inner radius", + generate_hash("player_throwbackOuterRadius") + }, + { + "player_useRadius", + "The radius within which a player can use things", + generate_hash("player_useRadius") + }, + { + "playercard_cache_download_max_retry_time", + "Max time that the player cache download can retry", + generate_hash("playercard_cache_download_max_retry_time") + }, + { + "playercard_cache_download_retry_step", + "Step in m/s for the player cache download retry", + generate_hash("playercard_cache_download_retry_step") + }, + { + "playercard_cache_upload_max_retry_time", + "Max time that the player cache upload can retry", + generate_hash("playercard_cache_upload_max_retry_time") + }, + { + "playercard_cache_upload_retry_step", + "Step in m/s for the player cache upload retry", + generate_hash("playercard_cache_upload_retry_step") + }, + { + "playercard_cache_validity_life", + "The life of a cached gamercard (it can be re-downloaded after this)", + generate_hash("playercard_cache_validity_life") + }, + { + "playerPositionRecordSampleTime", + "How often to sample player positions and save them into match data.", + generate_hash("playerPositionRecordSampleTime") + }, + { + "playlist", + "The playlist number", + generate_hash("playlist") + }, + { + "playlistAggrFilename", + "Aggregated playlist filename", + generate_hash("playlistAggrFilename") + }, + { + "playlistFilename", + "Playlist filename", + generate_hash("playlistFilename") + }, + { + "playListUpdateCheckMinutes", + "Minutes to wait between checking for updated playlist.", + generate_hash("playListUpdateCheckMinutes") + }, + { + "prestige_shop_active", + "Are we allowed to show the Prestige Shop or not", + generate_hash("prestige_shop_active") + }, + { + "prestige30EasterEggEnabled", + "Enables the easter egg for prestige 30 if 1, disabled if 0.", + generate_hash("prestige30EasterEggEnabled") + }, + { + "privateMatch_joinPassword", + "", + generate_hash("privateMatch_joinPassword") + }, + { + "privateMatch_serverPassword", + "", + generate_hash("privateMatch_serverPassword") + }, + { + "profileMenuOption_blacklevel", + "", + generate_hash("profileMenuOption_blacklevel") + }, + { + "profileMenuOption_offensiveContentMode", + "Mode of the offensive content warning at startup - 0, skip and turn on; 1, skip and turn off; 2, ask user", + generate_hash("profileMenuOption_offensiveContentMode") + }, + { + "profileMenuOption_safeAreaHorz", + "", + generate_hash("profileMenuOption_safeAreaHorz") + }, + { + "profileMenuOption_safeAreaVert", + "", + generate_hash("profileMenuOption_safeAreaVert") + }, + { + "profileMenuOption_volume", + "", + generate_hash("profileMenuOption_volume") + }, + { + "protocol", + "Protocol version", + generate_hash("protocol") + }, + { + "pt_AliensReadyUpPrivateInUse", + "Do we use the co-op Ready Up feature in public lobbies?", + generate_hash("pt_AliensReadyUpPrivateInUse") + }, + { + "pt_AliensReadyUpPublicInUse", + "Do we use the co-op Ready Up feature in public lobbies?", + generate_hash("pt_AliensReadyUpPublicInUse") + }, + { + "pt_AliensReadyUpPublicStartTimerLength", + "co-op Ready Up start timer length in seconds", + generate_hash("pt_AliensReadyUpPublicStartTimerLength") + }, + { + "pt_allMembersDoQoS", + "Whether to send search results to all party/lobby members to get QoS data", + generate_hash("pt_allMembersDoQoS") + }, + { + "pt_backoutOnClientPresence", + "Whether the host should backout the party on client presence. 0=fully disabled, 1=out of game only, 2=in-game also", + generate_hash("pt_backoutOnClientPresence") + }, + { + "pt_connectAttempts", + "Connect timeout when joining another game/party, per attempt", + generate_hash("pt_connectAttempts") + }, + { + "pt_connectTimeout", + "Connect timeout when joining another game/party, per attempt", + generate_hash("pt_connectTimeout") + }, + { + "pt_gameStartTimerLength", + "Time in seconds before a game start once enough party members are ready", + generate_hash("pt_gameStartTimerLength") + }, + { + "pt_logHostSelectionChance", + "Sets the probability that we log our host selection results", + generate_hash("pt_logHostSelectionChance") + }, + { + "pt_memberTimeout", + "Client timeout time in the general case", + generate_hash("pt_memberTimeout") + }, + { + "pt_migrateBeforeAdvertise", + "Whether lobbies made by private parties should migrate host before publishing", + generate_hash("pt_migrateBeforeAdvertise") + }, + { + "pt_migrationBandwidthBonusPing", + "The ping rewarded to the bonus bandwidth threshold when scoring hosts.", + generate_hash("pt_migrationBandwidthBonusPing") + }, + { + "pt_migrationBandwidthBonusThreshold", + "The required excess % upload bandwidth to get a bonus when scoring hosts.", + generate_hash("pt_migrationBandwidthBonusThreshold") + }, + { + "pt_migrationCPUWeight", + "How important CPU speed is when selecting a new host", + generate_hash("pt_migrationCPUWeight") + }, + { + "pt_migrationNotInstalledWeight", + "How important not being done installing is when selecting a new host", + generate_hash("pt_migrationNotInstalledWeight") + }, + { + "pt_migrationPingBad", + "", + generate_hash("pt_migrationPingBad") + }, + { + "pt_migrationPingWeight", + "", + generate_hash("pt_migrationPingWeight") + }, + { + "pt_migrationQuitsBad", + "", + generate_hash("pt_migrationQuitsBad") + }, + { + "pt_migrationQuitsWeight", + "", + generate_hash("pt_migrationQuitsWeight") + }, + { + "pt_migrationRAMWeight", + "How important it is to have the minimum amount of RAM when selecting a new host", + generate_hash("pt_migrationRAMWeight") + }, + { + "pt_migrationThreshold", + "Minimum amount which another client must be better than the current host to trigger a migration", + generate_hash("pt_migrationThreshold") + }, + { + "pt_migrationUploadBad", + "", + generate_hash("pt_migrationUploadBad") + }, + { + "pt_migrationUploadWeight", + "", + generate_hash("pt_migrationUploadWeight") + }, + { + "pt_migrationWifiPenalty", + "How important Wifi is when selecting a new host", + generate_hash("pt_migrationWifiPenalty") + }, + { + "pt_pregameStartTimerLength", + "Time in seconds before showing and starting the game start timer", + generate_hash("pt_pregameStartTimerLength") + }, + { + "pt_rejoin", + "Enable defensive rejoin command", + generate_hash("pt_rejoin") + }, + { + "pt_reservedAnonymousSlotTime", + "Time in milliseconds that ANONYMOUS slots will be reserved.", + generate_hash("pt_reservedAnonymousSlotTime") + }, + { + "pt_reservedCommittedSlotTime", + "Time in milliseconds that COMMITTED slots will be reserved", + generate_hash("pt_reservedCommittedSlotTime") + }, + { + "pt_reservedJoiningSlotTime", + "Time in milliseconds that JOINING slots will be reserved", + generate_hash("pt_reservedJoiningSlotTime") + }, + { + "pt_searchConnectAttempts", + "Connect timeout when joining another game/party, per attempt", + generate_hash("pt_searchConnectAttempts") + }, + { + "pt_searchPauseTime", + "Minimum amount of time to pause between searches", + generate_hash("pt_searchPauseTime") + }, + { + "pt_searchRandomDelay", + "Time period over which the search timers will get randomly delayed.", + generate_hash("pt_searchRandomDelay") + }, + { + "pt_searchResultsLifetime", + "Time at which we consider the search results stale", + generate_hash("pt_searchResultsLifetime") + }, + { + "pt_searchResultsMin", + "Minimum amount of time that has to pass before we'll search again for matches", + generate_hash("pt_searchResultsMin") + }, + { + "pt_stillConnectingWaitTime", + "Amount of time to wait for someone to finish connecting before searching for lobbies to merge with", + generate_hash("pt_stillConnectingWaitTime") + }, + { + "pt_useMigrationWeights", + "Killswitch to turn on or off the host selection by weights", + generate_hash("pt_useMigrationWeights") + }, + { + "publisherFileFetchTimeout", + "default timeout for publisher files FETCH tasks (in seconds)", + generate_hash("publisherFileFetchTimeout") + }, + { + "r_adaptiveSubdiv", + "Enables screen space Catmull Clark adaptive tessellation. If disabled, models tessellate to their designed subdivision level.", + generate_hash("r_adaptiveSubdiv") + }, + { + "r_adaptiveSubdivBaseFactor", + "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation.", + generate_hash("r_adaptiveSubdivBaseFactor") + }, + { + "r_adaptiveSubdivPatchFactor", + "Screen space Catmull Clark adaptive tessellation factor for the base model. Smaller values mean more tessellation.", + generate_hash("r_adaptiveSubdivPatchFactor") + }, + { + "r_allCells", + "Draw all cells. Most useful for seeing if portals or cells are hiding things they should not..", + generate_hash("r_allCells") + }, + { + "r_amdGPU", + "At least on AMD GPU used for rendering.", + generate_hash("r_amdGPU") + }, + { + "r_aoBlurSharpness", + "Controls the tolerance for depth discontinuities during the bilateral blur step. Larger values reduce the depth tolerance and effectively sharpen more edges.", + generate_hash("r_aoBlurSharpness") + }, + { + "r_aoBlurStep", + "Step scale applied to sample offsets during the bilateral blur. A value of 1 results in a normal gaussian blur. Increasing it to 2 or 3 makes the filter larger but causes fine dithering patterns.", + generate_hash("r_aoBlurStep") + }, + { + "r_aoDiminish", + "Decrease the effect of occlusion on brighter colors", + generate_hash("r_aoDiminish") + }, + { + "r_aoPower", + "Power curve applied to AO factor", + generate_hash("r_aoPower") + }, + { + "r_aoStrength", + "Strength of Ambient Occlusion effect", + generate_hash("r_aoStrength") + }, + { + "r_aoUseTweaks", + "Use r_ao* dvars instead of the current light set values for AO common params", + generate_hash("r_aoUseTweaks") + }, + { + "r_artUseTweaks", + "Tells the game that art tweaks is enabled and script is in control (as opposed to ColorEd).", + generate_hash("r_artUseTweaks") + }, + { + "r_aspectRatio", + "Screen aspect ratio. Most widescreen monitors are 16:10 instead of 16:9.", + generate_hash("r_aspectRatio") + }, + { + "r_asyncCompute", + "Enables scheduling GPU compute shader work prior to the graphics frame, improving overlap.", + generate_hash("r_asyncCompute") + }, + { + "r_atlasAnimFPS", + "Speed to animate atlased 2d materials", + generate_hash("r_atlasAnimFPS") + }, + { + "r_autopriority", + "Automatically set the priority of the windows process when the game is minimized", + generate_hash("r_autopriority") + }, + { + "r_balanceLightmapOpaqueLists", + "Split lightmap opaque into multiple draw lists.", + generate_hash("r_balanceLightmapOpaqueLists") + }, + { + "r_blacklevel", + "Black level (negative brightens output)", + generate_hash("r_blacklevel") + }, + { + "r_blur", + "Dev tweak to blur the screen", + generate_hash("r_blur") + }, + { + "r_blurdstGaussianBlurLevel", + "MIP level to start gaussian blur at", + generate_hash("r_blurdstGaussianBlurLevel") + }, + { + "r_blurdstGaussianBlurRadius", + "Amount to gaussian blur blur distortion render target", + generate_hash("r_blurdstGaussianBlurRadius") + }, + { + "r_brightness", + "Brightness adjustment", + generate_hash("r_brightness") + }, + { + "r_cacheModelLighting", + "Speed up model lighting by caching previous results", + generate_hash("r_cacheModelLighting") + }, + { + "r_cacheSModelLighting", + "Speed up static model lighting by caching previous results", + generate_hash("r_cacheSModelLighting") + }, + { + "r_charLightAmbient", + "", + generate_hash("r_charLightAmbient") + }, + { + "r_clampLodScale", + "Clamps the amount that the engine can adjust the LOD distance. 0 the engine can fully adjust. 1 the engine cannot adjust it at all. 0.5 the maximum the engine can adjust the LOD distance is 50% or the default.", + generate_hash("r_clampLodScale") + }, + { + "r_clear", + "Controls how the color buffer is cleared", + generate_hash("r_clear") + }, + { + "r_clearColor", + "Color to clear the screen to when clearing the frame buffer", + generate_hash("r_clearColor") + }, + { + "r_clearColor2", + "Color to clear every second frame to (for use during development)", + generate_hash("r_clearColor2") + }, + { + "r_clutCompositeVisionSet", + "Composite clut with vision set.", + generate_hash("r_clutCompositeVisionSet") + }, + { + "r_cmdbuf_worker", + "Process command buffer in a separate thread", + generate_hash("r_cmdbuf_worker") + }, + { + "r_colorGradingEnable", + "Enable color grading.", + generate_hash("r_colorGradingEnable") + }, + { + "r_colorMap", + "Replace all color maps with pure black or pure white", + generate_hash("r_colorMap") + }, + { + "r_colorScaleUseTweaks", + "Override color scale LightSet settings with tweak dvar values. (MP)", + generate_hash("r_colorScaleUseTweaks") + }, + { + "r_combinePostOpaqueFx", + "", + generate_hash("r_combinePostOpaqueFx") + }, + { + "r_contrast", + "Contrast adjustment", + generate_hash("r_contrast") + }, + { + "r_darkBlur", + "Apply blur (decrease of visual acuity) when dark", + generate_hash("r_darkBlur") + }, + { + "r_darkBlurPower", + "Power curve of blurring (decrease of visual acuity) when dark", + generate_hash("r_darkBlurPower") + }, + { + "r_darkBlurRadius", + "Radius of blurring (decrease of visual acuity) when dark", + generate_hash("r_darkBlurRadius") + }, + { + "r_darkColor", + "Reduce color sensitivity when dark", + generate_hash("r_darkColor") + }, + { + "r_darkColorPower", + "Power curve of color sensitivity when dark", + generate_hash("r_darkColorPower") + }, + { + "r_debugLineWidth", + "Width of server side debug lines", + generate_hash("r_debugLineWidth") + }, + { + "r_defaultPatchCount", + "Patches per thread group for all other surfaces.", + generate_hash("r_defaultPatchCount") + }, + { + "r_depthPrepass", + "Enable depth prepass for various geometries", + generate_hash("r_depthPrepass") + }, + { + "r_depthSortEnable", + "Enable sorting of transparent surfaces.", + generate_hash("r_depthSortEnable") + }, + { + "r_depthSortRange", + "Range to consider depth sort,", + generate_hash("r_depthSortRange") + }, + { + "r_desaturation", + "Desaturation adjustment", + generate_hash("r_desaturation") + }, + { + "r_detailMap", + "Replace all detail maps with an image that effectively disables them", + generate_hash("r_detailMap") + }, + { + "r_diffuseColorScale", + "Globally scale the diffuse color of all point lights", + generate_hash("r_diffuseColorScale") + }, + { + "r_displacementMap", + "Replace all displacement maps with an image that effectively disables them", + generate_hash("r_displacementMap") + }, + { + "r_displacementPatchCount", + "Patches per thread group for displacement surfaces.", + generate_hash("r_displacementPatchCount") + }, + { + "r_distortion", + "Enable distortion", + generate_hash("r_distortion") + }, + { + "r_distortion_script_force_off", + "Force distortion off in script", + generate_hash("r_distortion_script_force_off") + }, + { + "r_dlightLimit", + "Maximum number of dynamic lights drawn simultaneously", + generate_hash("r_dlightLimit") + }, + { + "r_dof_bias", + "Depth of field bias as a power function (like gamma); less than 1 is sharper", + generate_hash("r_dof_bias") + }, + { + "r_dof_enable", + "Enable the depth of field effect", + generate_hash("r_dof_enable") + }, + { + "r_dof_farBlur", + "", + generate_hash("r_dof_farBlur") + }, + { + "r_dof_farEnd", + "Depth of field far end distance, in inches", + generate_hash("r_dof_farEnd") + }, + { + "r_dof_farStart", + "Depth of field far start distance, in inches", + generate_hash("r_dof_farStart") + }, + { + "r_dof_nearBlur", + "", + generate_hash("r_dof_nearBlur") + }, + { + "r_dof_nearEnd", + "Depth of field near end distance, in inches", + generate_hash("r_dof_nearEnd") + }, + { + "r_dof_nearStart", + "Depth of field near start distance, in inches", + generate_hash("r_dof_nearStart") + }, + { + "r_dof_physical_adsFocusSpeed", + "ADS focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)", + generate_hash("r_dof_physical_adsFocusSpeed") + }, + { + "r_dof_physical_adsMaxFstop", + "ADS maximum f-stop (optimal aperture and focus distance are automatically calculated for this mode)", + generate_hash("r_dof_physical_adsMaxFstop") + }, + { + "r_dof_physical_adsMinFstop", + "ADS minimum f-stop (optimal aperture and focus distance are automatically calculated for this mode)", + generate_hash("r_dof_physical_adsMinFstop") + }, + { + "r_dof_physical_bokehEnable", + "Enable the bokeh depth of field effect", + generate_hash("r_dof_physical_bokehEnable") + }, + { + "r_dof_physical_bokehPreset", + "Changes dof sampling quality", + generate_hash("r_dof_physical_bokehPreset") + }, + { + "r_dof_physical_bokehRotation", + "Bokeh shape rotation in degrees (hexagonal and octogonal only)", + generate_hash("r_dof_physical_bokehRotation") + }, + { + "r_dof_physical_bokehShape", + "Changes the bokeh shape", + generate_hash("r_dof_physical_bokehShape") + }, + { + "r_dof_physical_bokehSharpness", + "Bokeh shape sharpness, trades sharpness for stability (circular only)", + generate_hash("r_dof_physical_bokehSharpness") + }, + { + "r_dof_physical_enable", + "enable physical camera controls (using aperture priority)", + generate_hash("r_dof_physical_enable") + }, + { + "r_dof_physical_filmDiagonal", + "Diagonal size of the film/sensor (mm). The bigger the sensor size, the bigger the circle of confusion (which means stronger blurring at all distances). Defaults to full-frame 35mm", + generate_hash("r_dof_physical_filmDiagonal") + }, + { + "r_dof_physical_focusDistance", + "Distance to the plane in focus for the scene", + generate_hash("r_dof_physical_focusDistance") + }, + { + "r_dof_physical_fstop", + "Aperture of the camera for the scene. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32", + generate_hash("r_dof_physical_fstop") + }, + { + "r_dof_physical_hipEnable", + "Enable hyperfocal mode", + generate_hash("r_dof_physical_hipEnable") + }, + { + "r_dof_physical_hipFocusSpeed", + "Hyperfocal mode focus speed (focus dist. far to near, focus dist. near to far, aperture opening, aperture closing)", + generate_hash("r_dof_physical_hipFocusSpeed") + }, + { + "r_dof_physical_hipFstop", + "Aperture of the camera for the scene in the hyperfocal mode", + generate_hash("r_dof_physical_hipFstop") + }, + { + "r_dof_physical_hipSharpCocDiameter", + "Defines what circle of confusion can be considered sharp (mm). Defaults to 0.03mm, generally accepted value for 35mm", + generate_hash("r_dof_physical_hipSharpCocDiameter") + }, + { + "r_dof_physical_maxCocDiameter", + "Maximum circle of confusion diameter (virtual units, might be clamped for bokeh dof)", + generate_hash("r_dof_physical_maxCocDiameter") + }, + { + "r_dof_physical_minFocusDistance", + "Minimum focus distance (inches)", + generate_hash("r_dof_physical_minFocusDistance") + }, + { + "r_dof_physical_viewModelFocusDistance", + "Distance to the plane in focus for the scene", + generate_hash("r_dof_physical_viewModelFocusDistance") + }, + { + "r_dof_physical_viewModelFstop", + "Aperture of the camera for the view model. Lower f-stop yields a shallower depth of field. Typical values range from f/1 to f/22. Rare extremes are f/0.75 and f/32", + generate_hash("r_dof_physical_viewModelFstop") + }, + { + "r_dof_tweak", + "Use dvars to set the depth of field effect; overrides r_dof_enable", + generate_hash("r_dof_tweak") + }, + { + "r_dof_viewModelEnd", + "Depth of field viewmodel end distance, in inches", + generate_hash("r_dof_viewModelEnd") + }, + { + "r_dof_viewModelStart", + "Depth of field viewmodel start distance, in inches", + generate_hash("r_dof_viewModelStart") + }, + { + "r_drawSun", + "Enable sun effects", + generate_hash("r_drawSun") + }, + { + "r_drawWater", + "Enable water animation", + generate_hash("r_drawWater") + }, + { + "r_dynamicOPL", + "Enable drawing vfx lights as overlapping primary light for saving gpu performance.", + generate_hash("r_dynamicOPL") + }, + { + "r_dynamicSpotLightShadows", + "Enable shadows for dynamic/VFX spot lights, you should set this dvar then spawn the new light.", + generate_hash("r_dynamicSpotLightShadows") + }, + { + "r_elevatedPriority", + "Utilize priority elevation for process.", + generate_hash("r_elevatedPriority") + }, + { + "r_emblemBrightnessScale", + "Modifier that scales the brightness of the emblem on model materials", + generate_hash("r_emblemBrightnessScale") + }, + { + "r_emissiveMap", + "Replace all emissive maps with pure black or pure white", + generate_hash("r_emissiveMap") + }, + { + "r_enableNoTessBuckets", + "Enables placing triangles that don't need tessellation into additional draw calls using non-tessellated shaders.", + generate_hash("r_enableNoTessBuckets") + }, + { + "r_envBrdfLutMap", + "Replace environment BRDF lookup table with pure black (no secondary specular) or pure white (maximum secondary specular)", + generate_hash("r_envBrdfLutMap") + }, + { + "r_envMapExponent", + "Reflection exponent.", + generate_hash("r_envMapExponent") + }, + { + "r_envMapMaxIntensity", + "Max reflection intensity based on glancing angle.", + generate_hash("r_envMapMaxIntensity") + }, + { + "r_envMapMinIntensity", + "", + generate_hash("r_envMapMinIntensity") + }, + { + "r_envMapOverride", + "", + generate_hash("r_envMapOverride") + }, + { + "r_envMapSunIntensity", + "Max sun specular intensity intensity with env map materials.", + generate_hash("r_envMapSunIntensity") + }, + { + "r_eyePupil", + " Change eye's pupil Size.", + generate_hash("r_eyePupil") + }, + { + "r_eyeRedness", + " Change eye's redness.", + generate_hash("r_eyeRedness") + }, + { + "r_eyeWetness", + " Change eye's wetness.", + generate_hash("r_eyeWetness") + }, + { + "r_fastModelPrimaryLightCheck", + "Reduce R_GetNonSunPrimaryLightForSphere/R_GetNonSunPrimaryLightForBox function calls", + generate_hash("r_fastModelPrimaryLightCheck") + }, + { + "r_fastModelPrimaryLightLink", + "Speed up R_LinkSphereEntityToPrimaryLights and R_LinkBoxEntityToPrimaryLights.", + generate_hash("r_fastModelPrimaryLightLink") + }, + { + "r_filmAltShader", + "Use alternate shader (with middle tint and dark desat) for film color.", + generate_hash("r_filmAltShader") + }, + { + "r_filmTweakBrightness", + "Tweak dev var; film color brightness", + generate_hash("r_filmTweakBrightness") + }, + { + "r_filmTweakContrast", + "Tweak dev var; film color contrast", + generate_hash("r_filmTweakContrast") + }, + { + "r_filmTweakDarkTint", + "", + generate_hash("r_filmTweakDarkTint") + }, + { + "r_filmTweakDesaturation", + "Tweak dev var; Desaturation applied after all 3D drawing to light areas", + generate_hash("r_filmTweakDesaturation") + }, + { + "r_filmTweakDesaturationDark", + "Tweak dev var; Additional desaturation applied after all 3D drawing to dark areas", + generate_hash("r_filmTweakDesaturationDark") + }, + { + "r_filmTweakEnable", + "Tweak dev var; enable film color effects", + generate_hash("r_filmTweakEnable") + }, + { + "r_filmTweakInvert", + "Tweak dev var; enable inverted video", + generate_hash("r_filmTweakInvert") + }, + { + "r_filmTweakLightTint", + "", + generate_hash("r_filmTweakLightTint") + }, + { + "r_filmTweakMediumTint", + "", + generate_hash("r_filmTweakMediumTint") + }, + { + "r_filmUseTweaks", + "Overide film effects with tweak dvar values.", + generate_hash("r_filmUseTweaks") + }, + { + "r_flushAfterExecute", + "Whether to Flush after ExecuteCommandList.", + generate_hash("r_flushAfterExecute") + }, + { + "r_fog", + "Set to 0 to disable fog", + generate_hash("r_fog") + }, + { + "r_fog_depthhack_scale", + "Fog scale for depth hack surfaces", + generate_hash("r_fog_depthhack_scale") + }, + { + "r_fog_ev_adjust", + "Fog color ev adjustment (+2 means fog color is 2 stops brighter)", + generate_hash("r_fog_ev_adjust") + }, + { + "r_font_cache_debug_display", + "Display the current fontcache texture on the HUD for debug purposes", + generate_hash("r_font_cache_debug_display") + }, + { + "r_forceLod", + "Force all level of detail to this level", + generate_hash("r_forceLod") + }, + { + "r_fullbright", + "Toggles rendering without lighting", + generate_hash("r_fullbright") + }, + { + "r_fxaaSubpixel", + "FXAA sub-pixel amount, lower values have more aliasing and less blur", + generate_hash("r_fxaaSubpixel") + }, + { + "r_FXAverageColorFunc", + "How to compute FX system average color? 0 = use IWrad equation, 1 = legacy equation, 2 = spherical harmonics 1 coefficient.", + generate_hash("r_FXAverageColorFunc") + }, + { + "r_globalGenericMaterialScale", + "Hack global generic material constants", + generate_hash("r_globalGenericMaterialScale") + }, + { + "r_glow_allowed", + "Allow glow.", + generate_hash("r_glow_allowed") + }, + { + "r_glow_allowed_script_forced", + "Force 'allow glow' to be treated as true, by script.", + generate_hash("r_glow_allowed_script_forced") + }, + { + "r_gunSightColorEntityScale", + "Scale the gun sight color when over an entity.", + generate_hash("r_gunSightColorEntityScale") + }, + { + "r_gunSightColorNoneScale", + "Scale the gun sight color when not over an entity.", + generate_hash("r_gunSightColorNoneScale") + }, + { + "r_hbaoBias", + "HBAO bias", + generate_hash("r_hbaoBias") + }, + { + "r_hbaoBlurEnable", + "HBAO blur enabled", + generate_hash("r_hbaoBlurEnable") + }, + { + "r_hbaoBlurSharpness", + "HBAO blur sharpness", + generate_hash("r_hbaoBlurSharpness") + }, + { + "r_hbaoCoarseAO", + "HBAO coarse AO", + generate_hash("r_hbaoCoarseAO") + }, + { + "r_hbaoDebug", + "Debug render HBAO occlusion", + generate_hash("r_hbaoDebug") + }, + { + "r_hbaoDetailAO", + "HBAO detail AO", + generate_hash("r_hbaoDetailAO") + }, + { + "r_hbaoPowerExponent", + "HBAO power exponent", + generate_hash("r_hbaoPowerExponent") + }, + { + "r_hbaoRadius", + "HBAO radius", + generate_hash("r_hbaoRadius") + }, + { + "r_hbaoSceneScale", + "HBAO scene scale", + generate_hash("r_hbaoSceneScale") + }, + { + "r_hbaoStrengthBlend", + "Blend factor between the artist-tuned proportional strength r_hbaoStrengthScale*artStrength, and the fixed strength r_hbaoStrengthFixed. A value of 0.0 is fully the proportional value, and a value of 1.0 is fully the fixed value.", + generate_hash("r_hbaoStrengthBlend") + }, + { + "r_hbaoStrengthFixed", + "Fixed HBAO strength. Only used if r_hbaoStrengthBlend > 0.0.", + generate_hash("r_hbaoStrengthFixed") + }, + { + "r_hbaoStrengthScale", + "Scale factor to convert SSAO strength to HBAO strength. Only used if r_hbaoStrengthBlend < 1.0.", + generate_hash("r_hbaoStrengthScale") + }, + { + "r_hbaoUseScriptScale", + "Enable/disable script-controlled strength scale while HBAO is active.", + generate_hash("r_hbaoUseScriptScale") + }, + { + "r_hemiAoBlurTolerance", + "Hemi SSAO Blur Tolerance (log10)", + generate_hash("r_hemiAoBlurTolerance") + }, + { + "r_hemiAoCombineResolutionsBeforeBlur", + "The higher quality modes blend wide and narrow sampling patterns. The wide pattern is due to deinterleaving and requires blurring. The narrow pattern is not on a deinterleaved buffer, but it only samples every other pixel. The blur on it is optional. If you combine the two before blurring, the narrow will get blurred as well. This creates a softer effect but can remove any visible noise from having 50% sample coverage.", + generate_hash("r_hemiAoCombineResolutionsBeforeBlur") + }, + { + "r_hemiAoCombineResolutionsWithMul", + "When combining the wide and narrow patterns, a mul() operation can be used or a min() operation. Multiplication exaggerates the result creating even darker creases. This is an artistic choice. I think it looks less natural, but often art teams prefer more exaggerated contrast. For me, it's more about having the right AO falloff so that it's a smooth gradient rather than falling off precipitously and forming overly dark recesses.", + generate_hash("r_hemiAoCombineResolutionsWithMul") + }, + { + "r_hemiAoDepthSquash", + "Hemi SSAO depth squash. Value is rcp.", + generate_hash("r_hemiAoDepthSquash") + }, + { + "r_hemiAoEnable", + "Enable Hemi SSAO", + generate_hash("r_hemiAoEnable") + }, + { + "r_hemiAoHierarchyDepth", + "Hemi SSAO recursion depth (filter width)", + generate_hash("r_hemiAoHierarchyDepth") + }, + { + "r_hemiAoMaxDepthDownsample", + "Use max depth value when downsampling, instead of pseudo-randomly picking a depth sample? Leaving this at the default false may produce more stable results.", + generate_hash("r_hemiAoMaxDepthDownsample") + }, + { + "r_hemiAoNoiseFilterTolerance", + "This is necessary to filter out pixel shimmer due to bilateral upsampling with too much lost resolution. High frequency detail can sometimes not be reconstructed, and the noise filter fills in the missing pixels with the result of the higher resolution SSAO. Value is log10.", + generate_hash("r_hemiAoNoiseFilterTolerance") + }, + { + "r_hemiAoPower", + "Power curve applied to Hemi SSAO factor, not applied in game yet", + generate_hash("r_hemiAoPower") + }, + { + "r_hemiAoQualityLevel", + "Hemi SSAO quality setting", + generate_hash("r_hemiAoQualityLevel") + }, + { + "r_hemiAoRejectionFalloff", + "Controls how aggressive to fade off samples that occlude spheres but by so much as to be unreliable. This is what gives objects a dark halo around them when placed in front of a wall. If you want to fade off the halo, boost your rejection falloff. The tradeoff is that it reduces overall AO. Value is rcp.", + generate_hash("r_hemiAoRejectionFalloff") + }, + { + "r_hemiAoStrength", + "Strength of Hemi Screen Space Ambient Occlusion effect", + generate_hash("r_hemiAoStrength") + }, + { + "r_hemiAoUpsampleTolerance", + "Hemi SSAO Upsample Tolerance (log10)", + generate_hash("r_hemiAoUpsampleTolerance") + }, + { + "r_heroLighting", + "Enable hero-only lighting", + generate_hash("r_heroLighting") + }, + { + "r_highLodDist", + "Distance for high level of detail", + generate_hash("r_highLodDist") + }, + { + "r_hudFx", + "Draw HUD Effects", + generate_hash("r_hudFx") + }, + { + "r_hudOutlineEnable", + "Enables wireframe outlines to be drawn around DObjs (as a post process).", + generate_hash("r_hudOutlineEnable") + }, + { + "r_hudOutlinePostMode", + "hud outline apply mode", + generate_hash("r_hudOutlinePostMode") + }, + { + "r_hudOutlineWidth", + "Set the width of the Hud Outline", + generate_hash("r_hudOutlineWidth") + }, + { + "r_ignore", + "", + generate_hash("r_ignore") + }, + { + "r_ignoref", + "", + generate_hash("r_ignoref") + }, + { + "r_imageQuality", + "Image quality", + generate_hash("r_imageQuality") + }, + { + "r_inGameVideo", + "Allow in game cinematics", + generate_hash("r_inGameVideo") + }, + { + "r_lateAllocParamCacheAllowed", + "Enable late allocation of parameter cache for VS stage.", + generate_hash("r_lateAllocParamCacheAllowed") + }, + { + "r_lateAllocParamCacheDefault", + "Late allocation of parameter cache value for sub-div materials.", + generate_hash("r_lateAllocParamCacheDefault") + }, + { + "r_lateAllocParamCacheDisplacement", + "Late allocation of parameter cache value for sub-div materials.", + generate_hash("r_lateAllocParamCacheDisplacement") + }, + { + "r_lateAllocParamCacheSubdiv", + "Late allocation of parameter cache value for sub-div materials.", + generate_hash("r_lateAllocParamCacheSubdiv") + }, + { + "r_lightCacheLessFrequentMaxDistance", + "Adjust the distance fx models (and models tagged as less-frequently-lit by script) move before immediately being relit", + generate_hash("r_lightCacheLessFrequentMaxDistance") + }, + { + "r_lightCacheLessFrequentPeriod", + "Adjust how frequently fx models (and models tagged as less-frequently-lit by script) get relit on average (1 is every frame, 8 is every 8th frame)", + generate_hash("r_lightCacheLessFrequentPeriod") + }, + { + "r_lightGridAvgApplyPrimaryLight", + "apply primary light color onto r_showLightGridAvgProbes boxes", + generate_hash("r_lightGridAvgApplyPrimaryLight") + }, + { + "r_lightGridAvgFollowCamera", + "allow the r_showLightGridAvgProbes boxes following current camera position", + generate_hash("r_lightGridAvgFollowCamera") + }, + { + "r_lightGridAvgProbeCount", + "how many light grid avg color probes will show up)", + generate_hash("r_lightGridAvgProbeCount") + }, + { + "r_lightGridAvgTraceGround", + " lock boxes to ground ", + generate_hash("r_lightGridAvgTraceGround") + }, + { + "r_lightGridContrast", + "Adjust the contrast of light color from the light grid", + generate_hash("r_lightGridContrast") + }, + { + "r_lightGridDefaultFXLightingLookup", + "Default FX lighting lookup location\n", + generate_hash("r_lightGridDefaultFXLightingLookup") + }, + { + "r_lightGridDefaultModelLightingLookup", + "Default model lighting lookup location", + generate_hash("r_lightGridDefaultModelLightingLookup") + }, + { + "r_lightGridEnableTweaks", + "Enable tweaks of the light color from the light grid", + generate_hash("r_lightGridEnableTweaks") + }, + { + "r_lightGridIntensity", + "Adjust the intensity of light color from the light grid", + generate_hash("r_lightGridIntensity") + }, + { + "r_lightGridSHBands", + "Spherical harmonics bands being used for evaluating current-gen light grids colors. 0 = default, 1 = 1 band, 2 = 2 bands, 3 = 3 bands.\n", + generate_hash("r_lightGridSHBands") + }, + { + "r_lightGridUseTweakedValues", + "Use tweaked values instead of default", + generate_hash("r_lightGridUseTweakedValues") + }, + { + "r_lightMap", + "Replace all lightmaps with pure black or pure white", + generate_hash("r_lightMap") + }, + { + "r_litSurfaceHDRScalar", + "Vision set based scalar applied to lit surfaces", + generate_hash("r_litSurfaceHDRScalar") + }, + { + "r_loadForRenderer", + "Set to false to disable dx allocations (for dedicated server mode)", + generate_hash("r_loadForRenderer") + }, + { + "r_lockPvs", + "Lock the viewpoint used for determining what is visible to the current position and direction", + generate_hash("r_lockPvs") + }, + { + "r_lod4Dist", + "Distance for lowest level of detail 4", + generate_hash("r_lod4Dist") + }, + { + "r_lod5Dist", + "Distance for lowest level of detail 5", + generate_hash("r_lod5Dist") + }, + { + "r_lodBiasRigid", + "", + generate_hash("r_lodBiasRigid") + }, + { + "r_lodBiasSkinned", + "", + generate_hash("r_lodBiasSkinned") + }, + { + "r_lodScaleRigid", + "", + generate_hash("r_lodScaleRigid") + }, + { + "r_lodScaleSkinned", + "", + generate_hash("r_lodScaleSkinned") + }, + { + "r_lowestLodDist", + "Distance for lowest level of detail", + generate_hash("r_lowestLodDist") + }, + { + "r_lowLodDist", + "Distance for low level of detail", + generate_hash("r_lowLodDist") + }, + { + "r_mbEnable", + "Set of objects which will be enabled for motion blur", + generate_hash("r_mbEnable") + }, + { + "r_mbFastEnable", + "Toggle on/off fast high quality motion blur", + generate_hash("r_mbFastEnable") + }, + { + "r_mbFastPreset", + "Changes motion blur quality", + generate_hash("r_mbFastPreset") + }, + { + "r_mdao", + "Enable the medium distance ambient occlusion feature", + generate_hash("r_mdao") + }, + { + "r_mdaoAsyncOccluderGen", + "The occluder generation step is performed via async compute", + generate_hash("r_mdaoAsyncOccluderGen") + }, + { + "r_mdaoBoneInfluenceRadiusScale", + "Scale for the bone influence radius for mdao", + generate_hash("r_mdaoBoneInfluenceRadiusScale") + }, + { + "r_mdaoCapsuleStrength", + "MDAO strength for capsule occluders", + generate_hash("r_mdaoCapsuleStrength") + }, + { + "r_mdaoMinBoneBoundsToOcclude", + "Minimum volume of the bone collider to create occluders for", + generate_hash("r_mdaoMinBoneBoundsToOcclude") + }, + { + "r_mdaoOccluderCullDistance", + "Culling distance for mdao occluders", + generate_hash("r_mdaoOccluderCullDistance") + }, + { + "r_mdaoOccluderFadeOutStartDistance", + "Fade out distance for mdao occluders", + generate_hash("r_mdaoOccluderFadeOutStartDistance") + }, + { + "r_mdaoUseTweaks", + "Use r_mdao* dvars instead of the current light set values for MDAO", + generate_hash("r_mdaoUseTweaks") + }, + { + "r_mdaoVolumeStrength", + "MDAO strength for volume occluders", + generate_hash("r_mdaoVolumeStrength") + }, + { + "r_mediumLodDist", + "Distance for medium level of detail", + generate_hash("r_mediumLodDist") + }, + { + "r_mode", + "Display mode", + generate_hash("r_mode") + }, + { + "r_modelLightingMap", + "Replace all model lighting maps (light grid) with pure black", + generate_hash("r_modelLightingMap") + }, + { + "r_monitor", + "Index of the monitor to use in a multi monitor system; 0 picks automatically.", + generate_hash("r_monitor") + }, + { + "r_mpRimColor", + "Change character's rim color for multiplayer", + generate_hash("r_mpRimColor") + }, + { + "r_mpRimDiffuseTint", + "Change character's rim diffuse tint for multiplayer.", + generate_hash("r_mpRimDiffuseTint") + }, + { + "r_mpRimStrength", + "Change character's rim color for multiplayer", + generate_hash("r_mpRimStrength") + }, + { + "r_multiGPU", + "Enable multi GPU compat mode.", + generate_hash("r_multiGPU") + }, + { + "r_normalMap", + "Replace all normal maps with a flat normal map", + generate_hash("r_normalMap") + }, + { + "r_nvidiaGPU", + "Enable NV API.", + generate_hash("r_nvidiaGPU") + }, + { + "r_offchipTessellationAllowed", + "Enable off-chip tessellation support.", + generate_hash("r_offchipTessellationAllowed") + }, + { + "r_offchipTessellationTfThreshold", + "Tessellation factor threshold for off-chip.", + generate_hash("r_offchipTessellationTfThreshold") + }, + { + "r_offchipTessellationWaveThreshold", + "Domain shader wave threshold for off-chip.", + generate_hash("r_offchipTessellationWaveThreshold") + }, + { + "r_omitUnusedRenderTargets", + "Omit unused render targets to save memory. Changing this requires a vid_restart.", + generate_hash("r_omitUnusedRenderTargets") + }, + { + "r_outdoor", + "Prevents snow from going indoors", + generate_hash("r_outdoor") + }, + { + "r_outdoorFeather", + "Outdoor z-feathering value", + generate_hash("r_outdoorFeather") + }, + { + "r_particleHdr", + "Enable Hdr Particle Features", + generate_hash("r_particleHdr") + }, + { + "r_patchCountAllowed", + "Enable run-time setting of patch count per draw call.", + generate_hash("r_patchCountAllowed") + }, + { + "r_picmip", + "Picmip level of color maps. If r_picmip_manual is 0, this is read-only.", + generate_hash("r_picmip") + }, + { + "r_picmip_bump", + "Picmip level of normal maps. If r_picmip_manual is 0, this is read-only.", + generate_hash("r_picmip_bump") + }, + { + "r_picmip_spec", + "Picmip level of specular maps. If r_picmip_manual is 0, this is read-only.", + generate_hash("r_picmip_spec") + }, + { + "r_picmip_water", + "Picmip level of water maps.", + generate_hash("r_picmip_water") + }, + { + "r_polygonOffsetBias", + "Offset bias for decal polygons; bigger values z-fight less but poke through walls more", + generate_hash("r_polygonOffsetBias") + }, + { + "r_polygonOffsetClamp", + "Offset clamp for decal polygons; bigger values z-fight less but poke through walls more", + generate_hash("r_polygonOffsetClamp") + }, + { + "r_polygonOffsetScale", + "Offset scale for decal polygons; bigger values z-fight less but poke through walls more", + generate_hash("r_polygonOffsetScale") + }, + { + "r_portalBevels", + "Helps cull geometry by angles of portals that are acute when projected onto the screen, value is the cosine of the angle", + generate_hash("r_portalBevels") + }, + { + "r_portalBevelsOnly", + "Use screen-space bounding box of portals rather than the actual shape of the portal projected onto the screen", + generate_hash("r_portalBevelsOnly") + }, + { + "r_portalMinClipArea", + "Don't clip child portals by a parent portal smaller than this fraction of the screen area.", + generate_hash("r_portalMinClipArea") + }, + { + "r_portalMinRecurseDepth", + "Ignore r_portalMinClipArea for portals with fewer than this many parent portals.", + generate_hash("r_portalMinRecurseDepth") + }, + { + "r_portalWalkLimit", + "Stop portal recursion after this many iterations. Useful for debugging portal errors.", + generate_hash("r_portalWalkLimit") + }, + { + "r_postAA", + "Post process antialiasing mode", + generate_hash("r_postAA") + }, + { + "r_postfx_enable", + "Enable post-processing effects such as color correction, bloom, depth-of-field, etc.", + generate_hash("r_postfx_enable") + }, + { + "r_preloadShaders", + "Force D3D to draw dummy geometry with all shaders during level load; may fix long pauses at level start.", + generate_hash("r_preloadShaders") + }, + { + "r_primaryLightTweakDiffuseStrength", + "Tweak the diffuse intensity for primary lights", + generate_hash("r_primaryLightTweakDiffuseStrength") + }, + { + "r_primaryLightTweakSpecularStrength", + "Tweak the specular intensity for primary lights", + generate_hash("r_primaryLightTweakSpecularStrength") + }, + { + "r_primaryLightUseTweaks", + "", + generate_hash("r_primaryLightUseTweaks") + }, + { + "r_reactiveMotionActorRadius", + "Radial distance from the ai characters that influences reactive motion models (inches)", + generate_hash("r_reactiveMotionActorRadius") + }, + { + "r_reactiveMotionActorVelocityMax", + "AI velocity considered the maximum when determining the length of motion tails (inches/sec)", + generate_hash("r_reactiveMotionActorVelocityMax") + }, + { + "r_reactiveMotionActorZOffset", + "Distance from the actor origin along Z direction where the actor's reactive motion effector sphere is centered at.", + generate_hash("r_reactiveMotionActorZOffset") + }, + { + "r_reactiveMotionEffectorStrengthScale", + "Additional scale for the effector influence, as a factor of the model part distance from the effector center and model part extents", + generate_hash("r_reactiveMotionEffectorStrengthScale") + }, + { + "r_reactiveMotionHelicopterLimit", + "Maximum number of helicopter entities that actively influence reactive motion. Can increase CPU cost of the scene.", + generate_hash("r_reactiveMotionHelicopterLimit") + }, + { + "r_reactiveMotionHelicopterRadius", + "Radial distance from the helicopter that influences reactive motion models (inches)", + generate_hash("r_reactiveMotionHelicopterRadius") + }, + { + "r_reactiveMotionHelicopterStrength", + "Scales the influence of helicopter wind tunnel motion", + generate_hash("r_reactiveMotionHelicopterStrength") + }, + { + "r_reactiveMotionPlayerHeightAdjust", + "Amount to adjust the vertical distance of the effector from the player position (inches)", + generate_hash("r_reactiveMotionPlayerHeightAdjust") + }, + { + "r_reactiveMotionPlayerRadius", + "Radial distance from the player that influences reactive motion models (inches)", + generate_hash("r_reactiveMotionPlayerRadius") + }, + { + "r_reactiveMotionPlayerZOffset", + "Distance from the player origin along Z direction where the player's reactive motion effector sphere is centered at.", + generate_hash("r_reactiveMotionPlayerZOffset") + }, + { + "r_reactiveMotionVelocityTailScale", + "Additional scale for the velocity-based motion tails, as a factor of the effector radius", + generate_hash("r_reactiveMotionVelocityTailScale") + }, + { + "r_reactiveMotionWindAmplitudeScale", + "Scales amplitude of wind wave motion", + generate_hash("r_reactiveMotionWindAmplitudeScale") + }, + { + "r_reactiveMotionWindAreaScale", + "Scales distribution of wind motion", + generate_hash("r_reactiveMotionWindAreaScale") + }, + { + "r_reactiveMotionWindDir", + "Controls the global wind direction", + generate_hash("r_reactiveMotionWindDir") + }, + { + "r_reactiveMotionWindFrequencyScale", + "Scales frequency of wind wave motion", + generate_hash("r_reactiveMotionWindFrequencyScale") + }, + { + "r_reactiveMotionWindStrength", + "Scale of the global wind direction (inches/sec)", + generate_hash("r_reactiveMotionWindStrength") + }, + { + "r_reflectionProbeMap", + "Replace all reflection probes with pure black", + generate_hash("r_reflectionProbeMap") + }, + { + "r_reflectionProbeNmlLuminance", + "Enable/disable shader code for computing luminance during reflection probe denormalization. This is just an experiment.\n", + generate_hash("r_reflectionProbeNmlLuminance") + }, + { + "r_rimLight0Color", + "", + generate_hash("r_rimLight0Color") + }, + { + "r_rimLight0Heading", + "Rim Light 0 heading in degrees", + generate_hash("r_rimLight0Heading") + }, + { + "r_rimLight0Pitch", + "Rim Light 0 pitch in degrees -90 is noon.", + generate_hash("r_rimLight0Pitch") + }, + { + "r_rimLightBias", + "How much to bias the n.l calculation", + generate_hash("r_rimLightBias") + }, + { + "r_rimLightDiffuseIntensity", + "Strength of the diffuse component of the rim light.", + generate_hash("r_rimLightDiffuseIntensity") + }, + { + "r_rimLightFalloffMaxDistance", + "Distance at which the rim light hits intensity of 100%.", + generate_hash("r_rimLightFalloffMaxDistance") + }, + { + "r_rimLightFalloffMinDistance", + "Distance at which the rim light hits intensity of 100%.", + generate_hash("r_rimLightFalloffMinDistance") + }, + { + "r_rimLightFalloffMinIntensity", + "Intensity of the effect at and before minDistance.", + generate_hash("r_rimLightFalloffMinIntensity") + }, + { + "r_rimLightPower", + "Power to raise the n.l calculation", + generate_hash("r_rimLightPower") + }, + { + "r_rimLightSpecIntensity", + "Strength of the spec ( additive) component of the rim light", + generate_hash("r_rimLightSpecIntensity") + }, + { + "r_rimLightUseTweaks", + "Turn on rim lighting tweaks", + generate_hash("r_rimLightUseTweaks") + }, + { + "r_scaleViewport", + "Scale 3D viewports by this fraction. Use this to see if framerate is pixel shader bound.", + generate_hash("r_scaleViewport") + }, + { + "r_sceneMipShowOverlay", + "Toggles scene mip rendertarget overlay", + generate_hash("r_sceneMipShowOverlay") + }, + { + "r_showLightGrid", + "Show light grid debugging information (2: detailed, 3: detailed for this box only)", + generate_hash("r_showLightGrid") + }, + { + "r_showLightGridAvgProbes", + "show an array of boxes which are using the light grid average color at its location", + generate_hash("r_showLightGridAvgProbes") + }, + { + "r_showLightGridDetailInfo", + "Show more details for light grid debugging.", + generate_hash("r_showLightGridDetailInfo") + }, + { + "r_showLightProbes", + "Show the light probes at the light grid sample locations in world space centered around the camera.", + generate_hash("r_showLightProbes") + }, + { + "r_showMissingLightGrid", + "Use rainbow colors for entities that are outside the light grid", + generate_hash("r_showMissingLightGrid") + }, + { + "r_showModelLightingLowWaterMark", + "", + generate_hash("r_showModelLightingLowWaterMark") + }, + { + "r_showPortals", + "Show portals for debugging", + generate_hash("r_showPortals") + }, + { + "r_showPortalsOverview", + "Render 2d XY portal overlay scaled to fit to this distance. Useful for debugging portal errors.", + generate_hash("r_showPortalsOverview") + }, + { + "r_showReflectionProbeSelection", + "Show reflection probe selection", + generate_hash("r_showReflectionProbeSelection") + }, + { + "r_singleCell", + "Only draw things in the same cell as the camera. Most useful for seeing how big the current cell is.", + generate_hash("r_singleCell") + }, + { + "r_skipPvs", + "Skipt the determination of what is in the potentially visible set (disables most drawing)", + generate_hash("r_skipPvs") + }, + { + "r_sky_fog_intensity", + "Amount of sky fog fading", + generate_hash("r_sky_fog_intensity") + }, + { + "r_sky_fog_max_angle", + "End of angular sky fog fading", + generate_hash("r_sky_fog_max_angle") + }, + { + "r_sky_fog_min_angle", + "Start of angular sky fog fading", + generate_hash("r_sky_fog_min_angle") + }, + { + "r_skyFogUseTweaks", + "Enable dvar control of sky fog", + generate_hash("r_skyFogUseTweaks") + }, + { + "r_smaaThreshold", + "SMAA edge detection threshold", + generate_hash("r_smaaThreshold") + }, + { + "r_smodelInstancedRenderer", + "Render static models with instanced renderer", + generate_hash("r_smodelInstancedRenderer") + }, + { + "r_smodelInstancedThreshold", + "Minimum number of static model instances before instanced rendering is used", + generate_hash("r_smodelInstancedThreshold") + }, + { + "r_smp_backend", + "Process renderer back end in a separate thread", + generate_hash("r_smp_backend") + }, + { + "r_smp_worker", + "Process renderer front end in a separate thread", + generate_hash("r_smp_worker") + }, + { + "r_smp_worker_thread0", + "", + generate_hash("r_smp_worker_thread0") + }, + { + "r_smp_worker_thread1", + "", + generate_hash("r_smp_worker_thread1") + }, + { + "r_smp_worker_thread2", + "", + generate_hash("r_smp_worker_thread2") + }, + { + "r_smp_worker_thread3", + "undefined", + generate_hash("r_smp_worker_thread3") + }, + { + "r_smp_worker_thread4", + "undefined", + generate_hash("r_smp_worker_thread4") + }, + { + "r_smp_worker_thread5", + "undefined", + generate_hash("r_smp_worker_thread5") + }, + { + "r_smp_worker_thread6", + "undefined", + generate_hash("r_smp_worker_thread6") + }, + { + "r_smp_worker_thread7", + "undefined", + generate_hash("r_smp_worker_thread7") + }, + { + "r_specOccMap", + "Replace all specular occlusion maps with pure black (fully occluded) or pure white (not occluded)", + generate_hash("r_specOccMap") + }, + { + "r_specularColorScale", + "Set greater than 1 to brighten specular highlights", + generate_hash("r_specularColorScale") + }, + { + "r_specularMap", + "Replace all specular maps with pure black (off) or pure white (super shiny)", + generate_hash("r_specularMap") + }, + { + "r_spotLightEntityShadows", + "Enable entity shadows for spot lights.", + generate_hash("r_spotLightEntityShadows") + }, + { + "r_spotLightShadows", + "Enable shadows for spot lights.", + generate_hash("r_spotLightShadows") + }, + { + "r_ssao", + "Screen Space Ambient Occlusion mode", + generate_hash("r_ssao") + }, + { + "r_ssaoDebug", + "Render calculated or blurred Screen Space Ambient Occlusion values", + generate_hash("r_ssaoDebug") + }, + { + "r_ssaoDebugMip", + "Selects which mip level to render when r_ssaoDebug is enabled. If 0 and r_ssaoDownsample is enabled, will render mip 1.", + generate_hash("r_ssaoDebugMip") + }, + { + "r_ssaoDepthScale", + "Scale applied to depth values used for occlusion tests.", + generate_hash("r_ssaoDepthScale") + }, + { + "r_ssaoDepthScaleViewModel", + "Scale applied to depth values used for occlusion tests.", + generate_hash("r_ssaoDepthScaleViewModel") + }, + { + "r_ssaoDownsample", + "Screen Space Ambient Occlusion calculation occurs at half linear resolution", + generate_hash("r_ssaoDownsample") + }, + { + "r_ssaoFadeDepth", + "Depth at which the SSAO begins to fade out. It fades at even increments of this distance (e.g. it's at 1 for depth r_ssaoFadeDepth, 1/2 for depth 2*r_ssaoFadeDepth, etc.)", + generate_hash("r_ssaoFadeDepth") + }, + { + "r_ssaoGapFalloff", + "Falloff used to blend between creases (that should darken) and silhouettes (that should not darken). Lower values falloff more quickly.", + generate_hash("r_ssaoGapFalloff") + }, + { + "r_ssaoGradientFalloff", + "Falloff used to fade out the effect for steep depth gradients (i.e. surfaces nearly parallel to the camera direction). This fixes sampling artifacts that appear for surfaces nearly parallel to the camera direction (commonly occuring for flat ground planes).", + generate_hash("r_ssaoGradientFalloff") + }, + { + "r_ssaoMaxStrengthDepth", + "Depth at which SSAO strength is at its maximum", + generate_hash("r_ssaoMaxStrengthDepth") + }, + { + "r_ssaoMethod", + "Screen Space Ambient Occlusion method (original or IW6, both are volumetric obscurance)", + generate_hash("r_ssaoMethod") + }, + { + "r_ssaoMinPixelWidth", + "Minimum pixel width of the effect. When the effect is smaller than this, it is culled entirely.", + generate_hash("r_ssaoMinPixelWidth") + }, + { + "r_ssaoMinStrengthDepth", + "Depth at which SSAO strength is zero, effectively disabled", + generate_hash("r_ssaoMinStrengthDepth") + }, + { + "r_ssaoMultiRes", + "Screen Space Ambient Occlusion calculation occurs at half linear resolution", + generate_hash("r_ssaoMultiRes") + }, + { + "r_ssaoPower", + "Power curve applied to SSAO factor", + generate_hash("r_ssaoPower") + }, + { + "r_ssaoRejectDepth", + "Depth at which the SSAO is disabled. Smaller values result in more rejected pixels which is faster, but limits the distance at which the effect is visible.", + generate_hash("r_ssaoRejectDepth") + }, + { + "r_ssaoSampleCount", + "Selects the number of samples used for SSAO", + generate_hash("r_ssaoSampleCount") + }, + { + "r_ssaoScriptScale", + "Allows script to lerp to disable or enable the SSAO. This applies a scalar value to the SSAO strength. When set to 0, this effectively disables SSAO.", + generate_hash("r_ssaoScriptScale") + }, + { + "r_ssaoStrength", + "Strength of Screen Space Ambient Occlusion effect", + generate_hash("r_ssaoStrength") + }, + { + "r_ssaoUseTweaks", + "Use r_ssao* dvars instead of the current light set values for SSAO", + generate_hash("r_ssaoUseTweaks") + }, + { + "r_ssaoWidth", + "The width of the SSAO effect, in pixels at 720p. Larger values increase area but lower effective quality.", + generate_hash("r_ssaoWidth") + }, + { + "r_sse_skinning", + "Use Streaming SIMD Extensions for skinning", + generate_hash("r_sse_skinning") + }, + { + "r_ssrBlendScale", + "Add extra scale to ssr weight versus reflection probe weight, >1 value will make ssr more obvious.", + generate_hash("r_ssrBlendScale") + }, + { + "r_ssrFadeInDuration", + "Duration of the screen-space reflection fade-in, which occurs whenever the reflection source buffer is invalidated due to view changes (in particular, dual-view scope transitions).", + generate_hash("r_ssrFadeInDuration") + }, + { + "r_ssrPositionCorrection", + "Screen space reflection position correction blend factor", + generate_hash("r_ssrPositionCorrection") + }, + { + "r_ssrRoughnessMipParameters", + "X: mirror mip; Y: roughest mip; Z: roughness middle point, may need different value for different screen resolution on PC.", + generate_hash("r_ssrRoughnessMipParameters") + }, + { + "r_sssBlendWeight", + "Controls the blend between the wide (zero) and narrow (one) gaussians", + generate_hash("r_sssBlendWeight") + }, + { + "r_sssDebugMaterial", + "Debug Feature: toggle materials with SSS", + generate_hash("r_sssDebugMaterial") + }, + { + "r_sssEnable", + "Enables the subsurface scattering effect (note that disabling SSS will not prevent the filter from running)", + generate_hash("r_sssEnable") + }, + { + "r_sssGlobalRadius", + "Controls the global radius (in inches)", + generate_hash("r_sssGlobalRadius") + }, + { + "r_sssJitterRadius", + "Percentage of the kernel to be jittered", + generate_hash("r_sssJitterRadius") + }, + { + "r_sssNarrowRadius", + "Controls the narrow Gaussian radius", + generate_hash("r_sssNarrowRadius") + }, + { + "r_sssPreset", + "Changes subsurface scattering quality", + generate_hash("r_sssPreset") + }, + { + "r_sssWideRadius", + "Controls the wide Gaussian radius", + generate_hash("r_sssWideRadius") + }, + { + "r_subdiv", + "Enables Catmull Clark surface subdivision.", + generate_hash("r_subdiv") + }, + { + "r_subdivLimit", + "Set the maximum Catmull Clark subdivision level.", + generate_hash("r_subdivLimit") + }, + { + "r_subdivPatchCount", + "Patches per thread group for sub-division surfaces.", + generate_hash("r_subdivPatchCount") + }, + { + "r_subdomainLimit", + "Maximum number of extra tessellation subdivisions using instancing (max tess amts are 0:64, 1:128, 2:192, 3:256, max instances used are 0:1, 1:4, 2:9, 3:12)", + generate_hash("r_subdomainLimit") + }, + { + "r_subdomainScale", + "Debug only: Scales the extra subdivision amount (for values < 1, not all instanced sub triangles will draw).", + generate_hash("r_subdomainScale") + }, + { + "r_subwindow", + "subwindow to draw: left, right, top, bottom", + generate_hash("r_subwindow") + }, + { + "r_sun_from_dvars", + "Set sun flare values from dvars rather than the level", + generate_hash("r_sun_from_dvars") + }, + { + "r_sun_fx_position", + "Position in degrees of the sun effect", + generate_hash("r_sun_fx_position") + }, + { + "r_sunblind_fadein", + "time in seconds to fade blind from 0% to 100%", + generate_hash("r_sunblind_fadein") + }, + { + "r_sunblind_fadeout", + "time in seconds to fade blind from 100% to 0%", + generate_hash("r_sunblind_fadeout") + }, + { + "r_sunblind_max_angle", + "angle from sun in degrees inside which effect is max", + generate_hash("r_sunblind_max_angle") + }, + { + "r_sunblind_max_darken", + "0-1 fraction for how black the world is at max blind", + generate_hash("r_sunblind_max_darken") + }, + { + "r_sunblind_min_angle", + "angle from sun in degrees outside which effect is 0", + generate_hash("r_sunblind_min_angle") + }, + { + "r_sunflare_fadein", + "time in seconds to fade alpha from 0% to 100%", + generate_hash("r_sunflare_fadein") + }, + { + "r_sunflare_fadeout", + "time in seconds to fade alpha from 100% to 0%", + generate_hash("r_sunflare_fadeout") + }, + { + "r_sunflare_max_alpha", + "0-1 vertex color and alpha of sun at max effect", + generate_hash("r_sunflare_max_alpha") + }, + { + "r_sunflare_max_angle", + "angle from sun in degrees inside which effect is max", + generate_hash("r_sunflare_max_angle") + }, + { + "r_sunflare_max_size", + "largest size of flare effect in pixels at 640x480", + generate_hash("r_sunflare_max_size") + }, + { + "r_sunflare_min_angle", + "angle from sun in degrees outside which effect is 0", + generate_hash("r_sunflare_min_angle") + }, + { + "r_sunflare_min_size", + "smallest size of flare effect in pixels at 640x480", + generate_hash("r_sunflare_min_size") + }, + { + "r_sunflare_shader", + "name for flare effect; can be any material", + generate_hash("r_sunflare_shader") + }, + { + "r_sunglare_fadein", + "time in seconds to fade glare from 0% to 100%", + generate_hash("r_sunglare_fadein") + }, + { + "r_sunglare_fadeout", + "time in seconds to fade glare from 100% to 0%", + generate_hash("r_sunglare_fadeout") + }, + { + "r_sunglare_max_angle", + "angle from sun in degrees inside which effect is max", + generate_hash("r_sunglare_max_angle") + }, + { + "r_sunglare_max_lighten", + "0-1 fraction for how white the world is at max glare", + generate_hash("r_sunglare_max_lighten") + }, + { + "r_sunglare_min_angle", + "angle from sun in degrees inside which effect is max", + generate_hash("r_sunglare_min_angle") + }, + { + "r_sunInfDist", + "Sun infinite distance used to place sun fx", + generate_hash("r_sunInfDist") + }, + { + "r_sunshadowmap_cmdbuf_worker", + "Process shadowmap command buffer in a separate thread", + generate_hash("r_sunshadowmap_cmdbuf_worker") + }, + { + "r_sunsprite_shader", + "name for static sprite; can be any material", + generate_hash("r_sunsprite_shader") + }, + { + "r_sunsprite_size", + "diameter in pixels at 640x480 and 80 fov", + generate_hash("r_sunsprite_size") + }, + { + "r_surfaceHDRScalarUseTweaks", + "Enables lit and unlit surface scalar tweaks", + generate_hash("r_surfaceHDRScalarUseTweaks") + }, + { + "r_tessellation", + "Enables tessellation of world geometry, with an optional cutoff distance.", + generate_hash("r_tessellation") + }, + { + "r_tessellationCutoffDistance", + "Distance at which world geometry ceases to tessellate.", + generate_hash("r_tessellationCutoffDistance") + }, + { + "r_tessellationCutoffFalloff", + "Range over which tessellation is faded out, up to the cutoff.", + generate_hash("r_tessellationCutoffFalloff") + }, + { + "r_tessellationEyeScale", + "Scale applied due to eye * object normal for less tessellation on facing polygons.", + generate_hash("r_tessellationEyeScale") + }, + { + "r_tessellationFactor", + "Target edge length, based on dividing full window height by this factor, for dynamic tessellation. Use zero to disable tessellation.", + generate_hash("r_tessellationFactor") + }, + { + "r_tessellationHeightAuto", + "Correctly auto scale displacement heights for layers to grow as texture is stretched over larger surface areas to preserve feature proportions.", + generate_hash("r_tessellationHeightAuto") + }, + { + "r_tessellationHeightScale", + "Displacement height scale factor.", + generate_hash("r_tessellationHeightScale") + }, + { + "r_tessellationHybrid", + "Hybrid per pixel displacement scale.", + generate_hash("r_tessellationHybrid") + }, + { + "r_tessellationLodBias", + "Displacement map lod bias.", + generate_hash("r_tessellationLodBias") + }, + { + "r_texFilterAnisoMax", + "Maximum anisotropy to use for texture filtering", + generate_hash("r_texFilterAnisoMax") + }, + { + "r_texFilterAnisoMin", + "Minimum anisotropy to use for texture filtering (overridden by max)", + generate_hash("r_texFilterAnisoMin") + }, + { + "r_texFilterDisable", + "Disables all texture filtering (uses nearest only.)", + generate_hash("r_texFilterDisable") + }, + { + "r_texFilterMipBias", + "Change the mipmap bias", + generate_hash("r_texFilterMipBias") + }, + { + "r_texFilterMipMode", + "Forces all mipmaps to use a particular blend between levels (or disables mipping.)", + generate_hash("r_texFilterMipMode") + }, + { + "r_texFilterProbeBilinear", + "Force reflection probe to use bilinear filter", + generate_hash("r_texFilterProbeBilinear") + }, + { + "r_texShowMipMode", + "Forces textures with the specified mip filtering to draw black.", + generate_hash("r_texShowMipMode") + }, + { + "r_thermalColorOffset", + "Offset of the thermal colors (offset + scale*color)", + generate_hash("r_thermalColorOffset") + }, + { + "r_thermalColorScale", + "Scale of the thermal colors (offset + scale*color)", + generate_hash("r_thermalColorScale") + }, + { + "r_thermalDetailScale", + "Scale of the detail that is added to the thermal map from the normal map (multiplies the detail amount from AssetManager)", + generate_hash("r_thermalDetailScale") + }, + { + "r_thermalFadeColor", + "Color the thermal fades to at distance.", + generate_hash("r_thermalFadeColor") + }, + { + "r_thermalFadeControl", + "Select thermal fade mode", + generate_hash("r_thermalFadeControl") + }, + { + "r_thermalFadeMax", + "Distance at which thermal stops fading", + generate_hash("r_thermalFadeMax") + }, + { + "r_thermalFadeMin", + "Distance at which thermal starts fading", + generate_hash("r_thermalFadeMin") + }, + { + "r_tonemap", + "HDR Tonemapping mode", + generate_hash("r_tonemap") + }, + { + "r_tonemapAdaptSpeed", + "HDR Tonemap exposure adaptation speed", + generate_hash("r_tonemapAdaptSpeed") + }, + { + "r_tonemapAuto", + "HDR Tonemapping performs auto-exposure", + generate_hash("r_tonemapAuto") + }, + { + "r_tonemapAutoExposureAdjust", + "HDR Tonemap Auto Exposure Adjust value (set to 0.0 for automatic adjustment)", + generate_hash("r_tonemapAutoExposureAdjust") + }, + { + "r_tonemapBlack", + "HDR Filmic Tonemap black point", + generate_hash("r_tonemapBlack") + }, + { + "r_tonemapBlend", + "HDR Tonemapping blends between exposures", + generate_hash("r_tonemapBlend") + }, + { + "r_tonemapCrossover", + "HDR Filmic Tonemap crossover point", + generate_hash("r_tonemapCrossover") + }, + { + "r_tonemapDarkEv", + "HDR Tonemap Dark EV", + generate_hash("r_tonemapDarkEv") + }, + { + "r_tonemapDarkExposureAdjust", + "HDR Tonemap Dark Exposure Adjust", + generate_hash("r_tonemapDarkExposureAdjust") + }, + { + "r_tonemapExposure", + "HDR Tonemap exposure (in EV) override (only works in non-auto mode)", + generate_hash("r_tonemapExposure") + }, + { + "r_tonemapExposureAdjust", + "HDR Tonemap exposure adjustment (in EV, 0 is no adjustment, works like a camera where +1 reduces EV by 1)", + generate_hash("r_tonemapExposureAdjust") + }, + { + "r_tonemapGamma", + "HDR Tonemap gamma curve power", + generate_hash("r_tonemapGamma") + }, + { + "r_tonemapHighlightRange", + "HDR Tonemap dynamic range, which determines white point luminance", + generate_hash("r_tonemapHighlightRange") + }, + { + "r_tonemapLightEv", + "HDR Tonemap Light EV", + generate_hash("r_tonemapLightEv") + }, + { + "r_tonemapLightExposureAdjust", + "HDR Tonemap Light Exposure Adjust", + generate_hash("r_tonemapLightExposureAdjust") + }, + { + "r_tonemapLockAutoExposureAdjust", + "HDR Tonemapping lock auto exposure adjust", + generate_hash("r_tonemapLockAutoExposureAdjust") + }, + { + "r_tonemapMaxExposure", + "HDR Tonemap maximum exposure (in EV)", + generate_hash("r_tonemapMaxExposure") + }, + { + "r_tonemapMaxExposureAdjust", + "HDR Tonemap Max Exposure Adjust", + generate_hash("r_tonemapMaxExposureAdjust") + }, + { + "r_tonemapMidEv", + "HDR Tonemap Mid EV", + generate_hash("r_tonemapMidEv") + }, + { + "r_tonemapMidExposureAdjust", + "HDR Tonemap Mid Exposure Adjust", + generate_hash("r_tonemapMidExposureAdjust") + }, + { + "r_tonemapMinExposureAdjust", + "HDR Tonemap Min Exposure Adjust", + generate_hash("r_tonemapMinExposureAdjust") + }, + { + "r_tonemapShoulder", + "HDR Filmic Tonemap shoulder control (0 is linear)", + generate_hash("r_tonemapShoulder") + }, + { + "r_tonemapToe", + "HDR Filmic Tonemap toe control (0 is linear)", + generate_hash("r_tonemapToe") + }, + { + "r_tonemapUseCS", + "HDR Tonemapping uses compute shader.", + generate_hash("r_tonemapUseCS") + }, + { + "r_tonemapUseTweaks", + "Override tone map LightSet settings with tweak dvar values.", + generate_hash("r_tonemapUseTweaks") + }, + { + "r_tonemapWhite", + "HDR Filmic Tonemap white point", + generate_hash("r_tonemapWhite") + }, + { + "r_ui3d_debug_display", + "Show UI3D debug overlay", + generate_hash("r_ui3d_debug_display") + }, + { + "r_ui3d_h", + "ui3d texture window height", + generate_hash("r_ui3d_h") + }, + { + "r_ui3d_use_debug_values", + "Use UI debug values", + generate_hash("r_ui3d_use_debug_values") + }, + { + "r_ui3d_w", + "ui3d texture window width", + generate_hash("r_ui3d_w") + }, + { + "r_ui3d_x", + "ui3d texture window x", + generate_hash("r_ui3d_x") + }, + { + "r_ui3d_y", + "ui3d texture window y", + generate_hash("r_ui3d_y") + }, + { + "r_uiBlurDstMode", + "UI blur distortion mode. Fast uses the scene mip map render target, PostSun uses a downsampled post sun resolve buffer, PostSun HQ uses a gaussian blurred post sun resolve buffer.", + generate_hash("r_uiBlurDstMode") + }, + { + "r_umbra", + "Enables Umbra-based portal culling.", + generate_hash("r_umbra") + }, + { + "r_umbraAccurateOcclusionThreshold", + "The distance (in inches) to which accurate occlusion information is gathered. -1.0 = deduced automatically.", + generate_hash("r_umbraAccurateOcclusionThreshold") + }, + { + "r_umbraExclusive", + "Toggle Umbra for exclusive static culling (disables static portal dpvs)", + generate_hash("r_umbraExclusive") + }, + { + "r_umbraQueryParts", + "The number of parts the Umbra query frustum is broken into for async query processing as an M x N grid (0, 0 = all queries are synchronous).", + generate_hash("r_umbraQueryParts") + }, + { + "r_umbraUseBadPlaces", + "Enable/disable ability to disable umbra when inside special volumes defined in mp/umbraBadPlaces.csv.", + generate_hash("r_umbraUseBadPlaces") + }, + { + "r_umbraUseDpvsCullDist", + "Use cull distance from the DPVS instead of the far plane distance.", + generate_hash("r_umbraUseDpvsCullDist") + }, + { + "r_unlitSurfaceHDRScalar", + "Vision set based scalar applied to unlit surfaces to balance those surfaces with the luminance of the scene", + generate_hash("r_unlitSurfaceHDRScalar") + }, + { + "r_useComputeSkinning", + "Enables compute shader (GPU) skinning.", + generate_hash("r_useComputeSkinning") + }, + { + "r_useLayeredMaterials", + "Set to true to use layered materials on shader model 3 hardware", + generate_hash("r_useLayeredMaterials") + }, + { + "r_useLightGridDefaultFXLightingLookup", + "Enable/disable default fx lighting lookup\n", + generate_hash("r_useLightGridDefaultFXLightingLookup") + }, + { + "r_useLightGridDefaultModelLightingLookup", + "Enable/disable default model lighting lookup\n", + generate_hash("r_useLightGridDefaultModelLightingLookup") + }, + { + "r_useShadowGeomOpt", + "Enable iwRad shadow geometry optimization. It only works when we have the data generated in iwRad.", + generate_hash("r_useShadowGeomOpt") + }, + { + "r_useSunShadowPortals", + "Enable sun shadow portals when dir light change and not using cached shadow.", + generate_hash("r_useSunShadowPortals") + }, + { + "r_useXAnimIK", + "Enables IK animation.", + generate_hash("r_useXAnimIK") + }, + { + "r_vc_makelog", + "Enable logging of light grid points for the vis cache. 1 starts from scratch, 2 appends.", + generate_hash("r_vc_makelog") + }, + { + "r_vc_showlog", + "Show this many rows of light grid points for the vis cache", + generate_hash("r_vc_showlog") + }, + { + "r_veil", + "Apply veiling luminance (HDR glow)", + generate_hash("r_veil") + }, + { + "r_veilAntialiasing", + "Veil antialiasing mode (downsample technique used for first mip).", + generate_hash("r_veilAntialiasing") + }, + { + "r_veilBackgroundStrength", + "Strength of background when applying veiling luminance (HDR glow)", + generate_hash("r_veilBackgroundStrength") + }, + { + "r_veilFalloffScale1", + "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)", + generate_hash("r_veilFalloffScale1") + }, + { + "r_veilFalloffScale2", + "Controls the size of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)", + generate_hash("r_veilFalloffScale2") + }, + { + "r_veilFalloffWeight1", + "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)", + generate_hash("r_veilFalloffWeight1") + }, + { + "r_veilFalloffWeight2", + "Controls the weight of individual Gaussians (Gaussians 4-6 in XYZ, where Gaussian 6 is the wider one)", + generate_hash("r_veilFalloffWeight2") + }, + { + "r_veilFilter", + "Changes the veil filtering mode", + generate_hash("r_veilFilter") + }, + { + "r_veilPreset", + "Changes veil sampling quality", + generate_hash("r_veilPreset") + }, + { + "r_veilRadius", + "Controls the radius of the first Gaussian in virtual pixels (remaining Gaussians follow proportionally).", + generate_hash("r_veilRadius") + }, + { + "r_veilStrength", + "Strength of veiling luminance (HDR glow)", + generate_hash("r_veilStrength") + }, + { + "r_veilUseTweaks", + "Override veil LightSet settings with tweak dvar values.", + generate_hash("r_veilUseTweaks") + }, + { + "r_velocityPrepass", + "Perform velocity rendering during the depth prepass", + generate_hash("r_velocityPrepass") + }, + { + "r_viewModelLightAmbient", + "", + generate_hash("r_viewModelLightAmbient") + }, + { + "r_viewModelPrimaryLightTweakDiffuseStrength", + "Tweak the diffuse intensity for view model primary lights", + generate_hash("r_viewModelPrimaryLightTweakDiffuseStrength") + }, + { + "r_viewModelPrimaryLightTweakSpecularStrength", + "Tweak the specular intensity for view model primary lights", + generate_hash("r_viewModelPrimaryLightTweakSpecularStrength") + }, + { + "r_viewModelPrimaryLightUseTweaks", + "", + generate_hash("r_viewModelPrimaryLightUseTweaks") + }, + { + "r_volumeLightScatter", + "Enables volumetric light scattering", + generate_hash("r_volumeLightScatter") + }, + { + "r_volumeLightScatterAngularAtten", + "Distance of sun from center of screen before angular attenuation starts for god rays", + generate_hash("r_volumeLightScatterAngularAtten") + }, + { + "r_volumeLightScatterBackgroundDistance", + "Distance at which pixels are considered background for volume light scatter effect", + generate_hash("r_volumeLightScatterBackgroundDistance") + }, + { + "r_volumeLightScatterColor", + "", + generate_hash("r_volumeLightScatterColor") + }, + { + "r_volumeLightScatterDepthAttenFar", + "Pixels >= than this depth recieve full volume light scatter.", + generate_hash("r_volumeLightScatterDepthAttenFar") + }, + { + "r_volumeLightScatterDepthAttenNear", + "Pixels <= than this depth recieve no volume light scatter.", + generate_hash("r_volumeLightScatterDepthAttenNear") + }, + { + "r_volumeLightScatterEv", + "Light intensity (in EV) for volumetric light scattering", + generate_hash("r_volumeLightScatterEv") + }, + { + "r_volumeLightScatterLinearAtten", + "Coefficient of linear attenuation of god rays", + generate_hash("r_volumeLightScatterLinearAtten") + }, + { + "r_volumeLightScatterQuadraticAtten", + "Coefficient of quadratic attenuation of god rays)", + generate_hash("r_volumeLightScatterQuadraticAtten") + }, + { + "r_volumeLightScatterUseTweaks", + "Enables volumetric light scattering tweaks", + generate_hash("r_volumeLightScatterUseTweaks") + }, + { + "r_vsync", + "Enable v-sync before drawing the next frame to avoid 'tearing' artifacts.", + generate_hash("r_vsync") + }, + { + "r_warningRepeatDelay", + "Number of seconds after displaying a \"per-frame\" warning before it will display again", + generate_hash("r_warningRepeatDelay") + }, + { + "r_wideTessFactorsThreshold", + "If a surface has more than this many triangles, process triangles in parallel instead of surfaces.", + generate_hash("r_wideTessFactorsThreshold") + }, + { + "r_zfar", + "Change the distance at which culling fog reaches 100% opacity; 0 is off", + generate_hash("r_zfar") + }, + { + "r_znear", + "Things closer than this aren't drawn. Reducing this increases z-fighting in the distance.", + generate_hash("r_znear") + }, + { + "radarjamDistMax", + "", + generate_hash("radarjamDistMax") + }, + { + "radarjamDistMin", + "", + generate_hash("radarjamDistMin") + }, + { + "radarjamSinCurve", + "", + generate_hash("radarjamSinCurve") + }, + { + "radius_damage_debug", + "Turn on debug lines for radius damage traces", + generate_hash("radius_damage_debug") + }, + { + "ragdoll_baselerp_time", + "Default time ragdoll baselerp bones take to reach the base pose", + generate_hash("ragdoll_baselerp_time") + }, + { + "ragdoll_bullet_force", + "Bullet force applied to ragdolls", + generate_hash("ragdoll_bullet_force") + }, + { + "ragdoll_bullet_upbias", + "Upward bias applied to ragdoll bullet effects", + generate_hash("ragdoll_bullet_upbias") + }, + { + "ragdoll_dump_anims", + "Dump animation data when ragdoll fails", + generate_hash("ragdoll_dump_anims") + }, + { + "ragdoll_enable", + "Turn on ragdoll death animations", + generate_hash("ragdoll_enable") + }, + { + "ragdoll_explode_force", + "Explosive force applied to ragdolls", + generate_hash("ragdoll_explode_force") + }, + { + "ragdoll_explode_upbias", + "Upwards bias applied to ragdoll explosion effects", + generate_hash("ragdoll_explode_upbias") + }, + { + "ragdoll_exploding_bullet_force", + "Force applied to ragdolls from explosive bullets", + generate_hash("ragdoll_exploding_bullet_force") + }, + { + "ragdoll_exploding_bullet_upbias", + "Upwards bias applied to ragdoll from explosive bullets", + generate_hash("ragdoll_exploding_bullet_upbias") + }, + { + "ragdoll_idle_min_velsq", + "Minimum squared speed a ragdoll body needs to be moving before it will shut down due to time", + generate_hash("ragdoll_idle_min_velsq") + }, + { + "ragdoll_jitter_scale", + "Scale up or down the effect of physics jitter on ragdolls", + generate_hash("ragdoll_jitter_scale") + }, + { + "ragdoll_jointlerp_time", + "Default time taken to lerp down ragdoll joint friction", + generate_hash("ragdoll_jointlerp_time") + }, + { + "ragdoll_link_to_moving_platform", + "Enable client-side linking of ragdolls to script brush models when they go idle.", + generate_hash("ragdoll_link_to_moving_platform") + }, + { + "ragdoll_max_life", + "Max lifetime of a ragdoll system in msec", + generate_hash("ragdoll_max_life") + }, + { + "ragdoll_max_simulating", + "Max number of simultaneous active ragdolls - archived", + generate_hash("ragdoll_max_simulating") + }, + { + "ragdoll_max_stretch_pct", + "Force ragdoll limbs to not stretch more than this percentage in one frame", + generate_hash("ragdoll_max_stretch_pct") + }, + { + "ragdoll_mp_limit", + "Max number of simultaneous active ragdolls - archived", + generate_hash("ragdoll_mp_limit") + }, + { + "ragdoll_mp_resume_share_after_killcam", + "Msec after returning from killcam that splitscreen players will share ragdolls again.", + generate_hash("ragdoll_mp_resume_share_after_killcam") + }, + { + "ragdoll_resolve_penetration_bias", + "Bias value on force to push ragdolls out of environment.", + generate_hash("ragdoll_resolve_penetration_bias") + }, + { + "ragdoll_rotvel_scale", + "Ragdoll rotational velocity estimate scale", + generate_hash("ragdoll_rotvel_scale") + }, + { + "ragdoll_self_collision_scale", + "Scale the size of the collision capsules used to prevent ragdoll limbs from interpenetrating", + generate_hash("ragdoll_self_collision_scale") + }, + { + "ragdoll_stretch_iters", + "Iterations to run the alternate limb solver", + generate_hash("ragdoll_stretch_iters") + }, + { + "rankedPlayEndMatchKeepLobby", + "keep the lobby if the lobby host is in our private party.", + generate_hash("rankedPlayEndMatchKeepLobby") + }, + { + "rankedPlaylistLockoutDuration", + "Time in seconds to lock the ranked play playlist if a player quit the match early.", + generate_hash("rankedPlaylistLockoutDuration") + }, + { + "rate", + "Player's preferred network rate", + generate_hash("rate") + }, + { + "RemoteCameraSounds_DryLevel", + "", + generate_hash("RemoteCameraSounds_DryLevel") + }, + { + "RemoteCameraSounds_RoomType", + "", + generate_hash("RemoteCameraSounds_RoomType") + }, + { + "RemoteCameraSounds_WetLevel", + "", + generate_hash("RemoteCameraSounds_WetLevel") + }, + { + "requireOpenNat", + "", + generate_hash("requireOpenNat") + }, + { + "restrictMapPacksToGroups", + "Restrict map pack usage to needing all maps in an ala carte package in order to use as search criteria", + generate_hash("restrictMapPacksToGroups") + }, + { + "riotshield_bullet_damage_scale", + "Value to scale bullet damage to deployed riotshield.", + generate_hash("riotshield_bullet_damage_scale") + }, + { + "riotshield_deploy_limit_radius", + "Min distance deployed riotshields must be from each other.", + generate_hash("riotshield_deploy_limit_radius") + }, + { + "riotshield_deploy_trace_parallel", + "Report collisions when riotshield traces are parallel to plane of triangle. If disabled traces parallel to triangle planes do not report collisions at all.", + generate_hash("riotshield_deploy_trace_parallel") + }, + { + "riotshield_deployed_health", + "Deployed riotshield health.", + generate_hash("riotshield_deployed_health") + }, + { + "riotshield_destroyed_cleanup_time", + "Time (in seconds) destroyed riotshield model persists before disappearing", + generate_hash("riotshield_destroyed_cleanup_time") + }, + { + "riotshield_explosive_damage_scale", + "Value to scale explosive damage to deployed riotshield..", + generate_hash("riotshield_explosive_damage_scale") + }, + { + "riotshield_melee_damage_scale", + "Value to scale melee damage to deployed riotshield.", + generate_hash("riotshield_melee_damage_scale") + }, + { + "riotshield_projectile_damage_scale", + "Value to scale projectile damage to deployed riotshield.", + generate_hash("riotshield_projectile_damage_scale") + }, + { + "s_aggregate_ping_offset", + "offset to apply to aggregate ping values", + generate_hash("s_aggregate_ping_offset") + }, + { + "s_aggregate_ping_scale", + "8-bit fixed-point aggregate ping scaler value", + generate_hash("s_aggregate_ping_scale") + }, + { + "s_avg_max_weighting", + "weighting from 0-256 of party average ping vs. worst ping", + generate_hash("s_avg_max_weighting") + }, + { + "s_ds_pingclient_reping_wait_db", + "wait this# of frames for the db thread to settle down before repinging", + generate_hash("s_ds_pingclient_reping_wait_db") + }, + { + "s_use_aggregate_datacenter_pings", + "use newer system for aggregating party pings", + generate_hash("s_use_aggregate_datacenter_pings") + }, + { + "safeArea_adjusted_horizontal", + "User-adjustable horizontal safe area as a fraction of the screen width", + generate_hash("safeArea_adjusted_horizontal") + }, + { + "safeArea_adjusted_vertical", + "User-adjustable vertical safe area as a fraction of the screen height", + generate_hash("safeArea_adjusted_vertical") + }, + { + "safeArea_horizontal", + "Horizontal safe area as a fraction of the screen width", + generate_hash("safeArea_horizontal") + }, + { + "safeArea_vertical", + "Vertical safe area as a fraction of the screen height", + generate_hash("safeArea_vertical") + }, + { + "scr_conf_numlives", + "", + generate_hash("scr_conf_numlives") + }, + { + "scr_conf_playerrespawndelay", + "", + generate_hash("scr_conf_playerrespawndelay") + }, + { + "scr_conf_roundlimit", + "", + generate_hash("scr_conf_roundlimit") + }, + { + "scr_conf_scorelimit", + "", + generate_hash("scr_conf_scorelimit") + }, + { + "scr_conf_timelimit", + "", + generate_hash("scr_conf_timelimit") + }, + { + "scr_conf_waverespawndelay", + "", + generate_hash("scr_conf_waverespawndelay") + }, + { + "scr_conf_winlimit", + "", + generate_hash("scr_conf_winlimit") + }, + { + "scr_default_maxagents", + "", + generate_hash("scr_default_maxagents") + }, + { + "scr_diehard", + "", + generate_hash("scr_diehard") + }, + { + "scr_disableClientSpawnTraces", + "", + generate_hash("scr_disableClientSpawnTraces") + }, + { + "scr_dm_numlives", + "", + generate_hash("scr_dm_numlives") + }, + { + "scr_dm_playerrespawndelay", + "", + generate_hash("scr_dm_playerrespawndelay") + }, + { + "scr_dm_roundlimit", + "", + generate_hash("scr_dm_roundlimit") + }, + { + "scr_dm_scorelimit", + "", + generate_hash("scr_dm_scorelimit") + }, + { + "scr_dm_timelimit", + "", + generate_hash("scr_dm_timelimit") + }, + { + "scr_dm_waverespawndelay", + "", + generate_hash("scr_dm_waverespawndelay") + }, + { + "scr_dm_winlimit", + "", + generate_hash("scr_dm_winlimit") + }, + { + "scr_dom_numlives", + "", + generate_hash("scr_dom_numlives") + }, + { + "scr_dom_playerrespawndelay", + "", + generate_hash("scr_dom_playerrespawndelay") + }, + { + "scr_dom_roundlimit", + "", + generate_hash("scr_dom_roundlimit") + }, + { + "scr_dom_scorelimit", + "", + generate_hash("scr_dom_scorelimit") + }, + { + "scr_dom_timelimit", + "", + generate_hash("scr_dom_timelimit") + }, + { + "scr_dom_waverespawndelay", + "", + generate_hash("scr_dom_waverespawndelay") + }, + { + "scr_dom_winlimit", + "", + generate_hash("scr_dom_winlimit") + }, + { + "scr_explBulletMod", + "", + generate_hash("scr_explBulletMod") + }, + { + "scr_game_allowkillcam", + "script allow killcam", + generate_hash("scr_game_allowkillcam") + }, + { + "scr_game_deathpointloss", + "", + generate_hash("scr_game_deathpointloss") + }, + { + "scr_game_forceuav", + "", + generate_hash("scr_game_forceuav") + }, + { + "scr_game_graceperiod", + "", + generate_hash("scr_game_graceperiod") + }, + { + "scr_game_hardpoints", + "", + generate_hash("scr_game_hardpoints") + }, + { + "scr_game_killstreakdelay", + "", + generate_hash("scr_game_killstreakdelay") + }, + { + "scr_game_lockspectatorpov", + "Lock spectator mode globally, 0=freelook/unlocked, 1=first_person, 2=third_person", + generate_hash("scr_game_lockspectatorpov") + }, + { + "scr_game_onlyheadshots", + "", + generate_hash("scr_game_onlyheadshots") + }, + { + "scr_game_perks", + "", + generate_hash("scr_game_perks") + }, + { + "scr_game_spectatetype", + "", + generate_hash("scr_game_spectatetype") + }, + { + "scr_game_suicidepointloss", + "", + generate_hash("scr_game_suicidepointloss") + }, + { + "scr_gameended", + "", + generate_hash("scr_gameended") + }, + { + "scr_hardcore", + "", + generate_hash("scr_hardcore") + }, + { + "scr_horde_difficulty", + "", + generate_hash("scr_horde_difficulty") + }, + { + "scr_horde_maxagents", + "", + generate_hash("scr_horde_maxagents") + }, + { + "scr_horde_numlives", + "", + generate_hash("scr_horde_numlives") + }, + { + "scr_horde_playerrespawndelay", + "", + generate_hash("scr_horde_playerrespawndelay") + }, + { + "scr_horde_roundlimit", + "", + generate_hash("scr_horde_roundlimit") + }, + { + "scr_horde_scorelimit", + "", + generate_hash("scr_horde_scorelimit") + }, + { + "scr_horde_timelimit", + "", + generate_hash("scr_horde_timelimit") + }, + { + "scr_horde_waverespawndelay", + "", + generate_hash("scr_horde_waverespawndelay") + }, + { + "scr_horde_winlimit", + "", + generate_hash("scr_horde_winlimit") + }, + { + "scr_infect_numlives", + "", + generate_hash("scr_infect_numlives") + }, + { + "scr_infect_playerrespawndelay", + "", + generate_hash("scr_infect_playerrespawndelay") + }, + { + "scr_infect_roundlimit", + "", + generate_hash("scr_infect_roundlimit") + }, + { + "scr_infect_timelimit", + "", + generate_hash("scr_infect_timelimit") + }, + { + "scr_infect_waverespawndelay", + "", + generate_hash("scr_infect_waverespawndelay") + }, + { + "scr_infect_winlimit", + "", + generate_hash("scr_infect_winlimit") + }, + { + "scr_isgamescom", + "script use gamescom demo flow", + generate_hash("scr_isgamescom") + }, + { + "scr_maxPerPlayerExplosives", + "", + generate_hash("scr_maxPerPlayerExplosives") + }, + { + "scr_nukeCancelMode", + "", + generate_hash("scr_nukeCancelMode") + }, + { + "scr_nukeTimer", + "", + generate_hash("scr_nukeTimer") + }, + { + "scr_patientZero", + "", + generate_hash("scr_patientZero") + }, + { + "scr_player_forcerespawn", + "", + generate_hash("scr_player_forcerespawn") + }, + { + "scr_player_healthregentime", + "", + generate_hash("scr_player_healthregentime") + }, + { + "scr_player_maxhealth", + "", + generate_hash("scr_player_maxhealth") + }, + { + "scr_player_numlives", + "", + generate_hash("scr_player_numlives") + }, + { + "scr_player_respawndelay", + "", + generate_hash("scr_player_respawndelay") + }, + { + "scr_player_sprinttime", + "", + generate_hash("scr_player_sprinttime") + }, + { + "scr_player_suicidespawndelay", + "", + generate_hash("scr_player_suicidespawndelay") + }, + { + "scr_RequiredMapAspectratio", + "", + generate_hash("scr_RequiredMapAspectratio") + }, + { + "scr_riotShieldXPBullets", + "", + generate_hash("scr_riotShieldXPBullets") + }, + { + "scr_sd_bombtimer", + "", + generate_hash("scr_sd_bombtimer") + }, + { + "scr_sd_defusetime", + "", + generate_hash("scr_sd_defusetime") + }, + { + "scr_sd_multibomb", + "", + generate_hash("scr_sd_multibomb") + }, + { + "scr_sd_numlives", + "", + generate_hash("scr_sd_numlives") + }, + { + "scr_sd_planttime", + "", + generate_hash("scr_sd_planttime") + }, + { + "scr_sd_playerrespawndelay", + "", + generate_hash("scr_sd_playerrespawndelay") + }, + { + "scr_sd_roundlimit", + "", + generate_hash("scr_sd_roundlimit") + }, + { + "scr_sd_roundswitch", + "", + generate_hash("scr_sd_roundswitch") + }, + { + "scr_sd_scorelimit", + "", + generate_hash("scr_sd_scorelimit") + }, + { + "scr_sd_timelimit", + "", + generate_hash("scr_sd_timelimit") + }, + { + "scr_sd_waverespawndelay", + "", + generate_hash("scr_sd_waverespawndelay") + }, + { + "scr_sd_winlimit", + "", + generate_hash("scr_sd_winlimit") + }, + { + "scr_sr_bombtimer", + "", + generate_hash("scr_sr_bombtimer") + }, + { + "scr_sr_defusetime", + "", + generate_hash("scr_sr_defusetime") + }, + { + "scr_sr_multibomb", + "", + generate_hash("scr_sr_multibomb") + }, + { + "scr_sr_numlives", + "", + generate_hash("scr_sr_numlives") + }, + { + "scr_sr_planttime", + "", + generate_hash("scr_sr_planttime") + }, + { + "scr_sr_playerrespawndelay", + "", + generate_hash("scr_sr_playerrespawndelay") + }, + { + "scr_sr_roundlimit", + "", + generate_hash("scr_sr_roundlimit") + }, + { + "scr_sr_roundswitch", + "", + generate_hash("scr_sr_roundswitch") + }, + { + "scr_sr_scorelimit", + "", + generate_hash("scr_sr_scorelimit") + }, + { + "scr_sr_timelimit", + "", + generate_hash("scr_sr_timelimit") + }, + { + "scr_sr_waverespawndelay", + "", + generate_hash("scr_sr_waverespawndelay") + }, + { + "scr_sr_winlimit", + "", + generate_hash("scr_sr_winlimit") + }, + { + "scr_team_fftype", + "script team friendly fire type", + generate_hash("scr_team_fftype") + }, + { + "scr_team_respawntime", + "", + generate_hash("scr_team_respawntime") + }, + { + "scr_team_teamkillpointloss", + "", + generate_hash("scr_team_teamkillpointloss") + }, + { + "scr_team_teamkillspawndelay", + "", + generate_hash("scr_team_teamkillspawndelay") + }, + { + "scr_thirdPerson", + "", + generate_hash("scr_thirdPerson") + }, + { + "scr_tispawndelay", + "", + generate_hash("scr_tispawndelay") + }, + { + "scr_war_halftime", + "", + generate_hash("scr_war_halftime") + }, + { + "scr_war_numlives", + "", + generate_hash("scr_war_numlives") + }, + { + "scr_war_playerrespawndelay", + "", + generate_hash("scr_war_playerrespawndelay") + }, + { + "scr_war_roundlimit", + "", + generate_hash("scr_war_roundlimit") + }, + { + "scr_war_roundswitch", + "", + generate_hash("scr_war_roundswitch") + }, + { + "scr_war_scorelimit", + "", + generate_hash("scr_war_scorelimit") + }, + { + "scr_war_timelimit", + "", + generate_hash("scr_war_timelimit") + }, + { + "scr_war_waverespawndelay", + "", + generate_hash("scr_war_waverespawndelay") + }, + { + "scr_war_winlimit", + "", + generate_hash("scr_war_winlimit") + }, + { + "scr_xpscale", + "", + generate_hash("scr_xpscale") + }, + { + "screenshots_active", + "Are we allowed to enable Screenshots or not", + generate_hash("screenshots_active") + }, + { + "search_weight_asn", + "The weight used for the asn in weighted matchmaking.", + generate_hash("search_weight_asn") + }, + { + "search_weight_country_code", + "The weight used for the country code in weighted matchmaking.", + generate_hash("search_weight_country_code") + }, + { + "search_weight_lat_long", + "The weight used for the lat long in weighted matchmaking.", + generate_hash("search_weight_lat_long") + }, + { + "sensitivity", + "Mouse sensitivity", + generate_hash("sensitivity") + }, + { + "sentry_placement_feet_offset", + "Position of the feet from the center axis.", + generate_hash("sentry_placement_feet_offset") + }, + { + "sentry_placement_feet_trace_dist_z", + "Max distance for a foot to be considered touching the ground", + generate_hash("sentry_placement_feet_trace_dist_z") + }, + { + "sentry_placement_trace_dist", + "Distance along the trace axis where the sentry will attempt to position itself", + generate_hash("sentry_placement_trace_dist") + }, + { + "sentry_placement_trace_min_normal", + "Minimum normal to accept a sentry position", + generate_hash("sentry_placement_trace_min_normal") + }, + { + "sentry_placement_trace_parallel", + "Enable turret traces that are parallel to plane of triangle. If 0, traces parallel to triangle planes do not report collisions at all. If 2 (debug-only), then trace code ping pongs between new and old.", + generate_hash("sentry_placement_trace_parallel") + }, + { + "sentry_placement_trace_pitch", + "Pitch used for the trace axis", + generate_hash("sentry_placement_trace_pitch") + }, + { + "sentry_placement_trace_radius", + "Radius of the bound used for the placement trace", + generate_hash("sentry_placement_trace_radius") + }, + { + "sentry_placement_trace_radius_canon_safety", + "Extra radius used in the forward direction to compensate for the canon length", + generate_hash("sentry_placement_trace_radius_canon_safety") + }, + { + "server1", + "", + generate_hash("server1") + }, + { + "server10", + "", + generate_hash("server10") + }, + { + "server11", + "", + generate_hash("server11") + }, + { + "server12", + "", + generate_hash("server12") + }, + { + "server13", + "", + generate_hash("server13") + }, + { + "server14", + "", + generate_hash("server14") + }, + { + "server15", + "", + generate_hash("server15") + }, + { + "server16", + "", + generate_hash("server16") + }, + { + "server2", + "", + generate_hash("server2") + }, + { + "server3", + "", + generate_hash("server3") + }, + { + "server4", + "", + generate_hash("server4") + }, + { + "server5", + "", + generate_hash("server5") + }, + { + "server6", + "", + generate_hash("server6") + }, + { + "server7", + "", + generate_hash("server7") + }, + { + "server8", + "", + generate_hash("server8") + }, + { + "server9", + "", + generate_hash("server9") + }, + { + "session_immediateDeleteTinySessions", + "Whether to immediately delete sessions with 1 user", + generate_hash("session_immediateDeleteTinySessions") + }, + { + "session_modify_retry_on_failure", + "Enable session modify retry on failures.", + generate_hash("session_modify_retry_on_failure") + }, + { + "session_nonblocking", + "Non-blocking Session code", + generate_hash("session_nonblocking") + }, + { + "shortversion", + "Short game version", + generate_hash("shortversion") + }, + { + "showDebugAmmoCounter", + "Show the debug ammo counter when unable to show ar ammo counter", + generate_hash("showDebugAmmoCounter") + }, + { + "showPlaylistTotalPlayers", + "Toggle the display of the total number of players in a playlist and online", + generate_hash("showPlaylistTotalPlayers") + }, + { + "sm_cacheSpotShadows", + "Cache spot shadow maps, improves shadow map performance at the cost of memory (requires vid_restart)", + generate_hash("sm_cacheSpotShadows") + }, + { + "sm_cacheSpotShadowsEnabled", + "Enables caching of spot shadows.", + generate_hash("sm_cacheSpotShadowsEnabled") + }, + { + "sm_cacheSunShadow", + "Cache sun shadow map, improves shadow map performance at the cost of memory (requires vid_restart)", + generate_hash("sm_cacheSunShadow") + }, + { + "sm_cacheSunShadowEnabled", + "Enables caching of sun-based shadows.", + generate_hash("sm_cacheSunShadowEnabled") + }, + { + "sm_cameraOffset", + "", + generate_hash("sm_cameraOffset") + }, + { + "sm_dynlightAllSModels", + "Enable, from script, rendering all static models in dynamic light volume when shadow mapping", + generate_hash("sm_dynlightAllSModels") + }, + { + "sm_enable", + "Enable shadow mapping", + generate_hash("sm_enable") + }, + { + "sm_fastSunShadow", + "Fast sun shadow", + generate_hash("sm_fastSunShadow") + }, + { + "sm_lightScore_eyeProjectDist", + "When picking shadows for primary lights, measure distance from a point this far in front of the camera.", + generate_hash("sm_lightScore_eyeProjectDist") + }, + { + "sm_lightScore_spotProjectFrac", + "When picking shadows for primary lights, measure distance from a point this far in front of the camera.", + generate_hash("sm_lightScore_spotProjectFrac") + }, + { + "sm_maxLightsWithShadows", + "Limits how many primary lights can have shadow maps", + generate_hash("sm_maxLightsWithShadows") + }, + { + "sm_minSpotLightScore", + "Minimum score (based on intensity, radius, and position relative to the camera) for a spot light to have shadow maps.", + generate_hash("sm_minSpotLightScore") + }, + { + "sm_polygonOffsetBias", + "Shadow map offset bias", + generate_hash("sm_polygonOffsetBias") + }, + { + "sm_polygonOffsetClamp", + "Shadow map offset clamp", + generate_hash("sm_polygonOffsetClamp") + }, + { + "sm_polygonOffsetPreset", + "Shadow map polygon offset preset.", + generate_hash("sm_polygonOffsetPreset") + }, + { + "sm_polygonOffsetScale", + "Shadow map offset scale", + generate_hash("sm_polygonOffsetScale") + }, + { + "sm_qualitySpotShadow", + "Fast spot shadow", + generate_hash("sm_qualitySpotShadow") + }, + { + "sm_shadowUseTweaks", + "Override shadow LightSet settings with tweak dvar values.", + generate_hash("sm_shadowUseTweaks") + }, + { + "sm_spotDistCull", + "Distance cull spot shadows", + generate_hash("sm_spotDistCull") + }, + { + "sm_spotEnable", + "Enable spot shadow mapping from script", + generate_hash("sm_spotEnable") + }, + { + "sm_spotFilterRadius", + "Spot soft shadows filter radius", + generate_hash("sm_spotFilterRadius") + }, + { + "sm_spotLightScoreModelScale", + "Scale the calculated spot light score by this value if the light currently only affects static or script brush models.", + generate_hash("sm_spotLightScoreModelScale") + }, + { + "sm_spotLightScoreRadiusPower", + "Power to apply to light radius when determining spot light shadowing score (1.0 means radius scales up score a lot, 0.0 means don't scale score using radius)", + generate_hash("sm_spotLightScoreRadiusPower") + }, + { + "sm_spotLimit", + "Limit number of spot shadows from script", + generate_hash("sm_spotLimit") + }, + { + "sm_spotShadowFadeTime", + "How many seconds it takes for a primary light shadow map to fade in or out", + generate_hash("sm_spotShadowFadeTime") + }, + { + "sm_strictCull", + "Strict shadow map cull", + generate_hash("sm_strictCull") + }, + { + "sm_sunEnable", + "Enable sun shadow mapping from script", + generate_hash("sm_sunEnable") + }, + { + "sm_sunFilterRadius", + "Sun soft shadows filter radius", + generate_hash("sm_sunFilterRadius") + }, + { + "sm_sunSampleSizeNear", + "Shadow sample size", + generate_hash("sm_sunSampleSizeNear") + }, + { + "sm_sunShadowBoundsMax", + "Max Shadow Bounds", + generate_hash("sm_sunShadowBoundsMax") + }, + { + "sm_sunShadowBoundsMin", + "Min Shadow Bounds", + generate_hash("sm_sunShadowBoundsMin") + }, + { + "sm_sunShadowBoundsOverride", + "Override Shadow Bounds", + generate_hash("sm_sunShadowBoundsOverride") + }, + { + "sm_sunShadowCenter", + "Sun shadow center, 0 0 0 means don't override", + generate_hash("sm_sunShadowCenter") + }, + { + "sm_sunShadowCenterMode", + "When false center value only used for far map, when true sets both maps", + generate_hash("sm_sunShadowCenterMode") + }, + { + "sm_sunShadowScale", + "Sun shadow scale optimization", + generate_hash("sm_sunShadowScale") + }, + { + "sm_sunShadowScaleLocked", + "Lock usage of sm_sunShadowScale at 1", + generate_hash("sm_sunShadowScaleLocked") + }, + { + "sm_usedSunCascadeCount", + "How many shadow cascade we are using", + generate_hash("sm_usedSunCascadeCount") + }, + { + "snd_allowHeadphoneHRTF", + "Enable HRTF over headphones", + generate_hash("snd_allowHeadphoneHRTF") + }, + { + "snd_announcerDisabled", + "Disable all in-game announcers", + generate_hash("snd_announcerDisabled") + }, + { + "snd_announcerVoicePrefix", + "Local mp announcer voice to use", + generate_hash("snd_announcerVoicePrefix") + }, + { + "snd_battlechatterDisabled", + "Disable all in-game battle chatter", + generate_hash("snd_battlechatterDisabled") + }, + { + "snd_cinematicVolumeScale", + "Scales the volume of Bink videos.", + generate_hash("snd_cinematicVolumeScale") + }, + { + "snd_detectedSpeakerConfig", + "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround", + generate_hash("snd_detectedSpeakerConfig") + }, + { + "snd_dopplerAuditionEnable", + "Enables doppler calculation preview mode", + generate_hash("snd_dopplerAuditionEnable") + }, + { + "snd_dopplerBaseSpeedOfSound", + "The base speed of sound used in doppler calculation", + generate_hash("snd_dopplerBaseSpeedOfSound") + }, + { + "snd_dopplerEnable", + "Enables doppler calculation", + generate_hash("snd_dopplerEnable") + }, + { + "snd_dopplerPitchMax", + "Maximum pitch that can be legally applied by doppler", + generate_hash("snd_dopplerPitchMax") + }, + { + "snd_dopplerPitchMin", + "Minimum pitch that can be legally applied by doppler", + generate_hash("snd_dopplerPitchMin") + }, + { + "snd_dopplerPlayerVelocityScale", + "The scale of the player velocity, relative the the sound source velocity, when applied to the doppler calculation", + generate_hash("snd_dopplerPlayerVelocityScale") + }, + { + "snd_dopplerSmoothing", + "Smoothing factor applied to doppler to eliminate jitter or sudden acceleration changes", + generate_hash("snd_dopplerSmoothing") + }, + { + "snd_draw3D", + "Draw the position and info of world sounds", + generate_hash("snd_draw3D") + }, + { + "snd_drawInfo", + "Draw debugging information for sounds", + generate_hash("snd_drawInfo") + }, + { + "snd_enable2D", + "Enable 2D sounds", + generate_hash("snd_enable2D") + }, + { + "snd_enable3D", + "Enable 3D sounds", + generate_hash("snd_enable3D") + }, + { + "snd_enableEq", + "Enable equalization filter", + generate_hash("snd_enableEq") + }, + { + "snd_enableReverb", + "Enable sound reverberation", + generate_hash("snd_enableReverb") + }, + { + "snd_enableStream", + "Enable streamed sounds", + generate_hash("snd_enableStream") + }, + { + "snd_envFollowerBuffScale", + "Amount of buffer to use for envelope follower. Smaller value indicates faster envelope.", + generate_hash("snd_envFollowerBuffScale") + }, + { + "snd_errorOnMissing", + "Cause a Com_Error if a sound file is missing.", + generate_hash("snd_errorOnMissing") + }, + { + "snd_hitsoundDisabled", + "Disable the hit indicator sound", + generate_hash("snd_hitsoundDisabled") + }, + { + "snd_inheritSecondaryPitchVol", + "Set to true for secondary aliases to inherit the pitch of the parent", + generate_hash("snd_inheritSecondaryPitchVol") + }, + { + "snd_levelFadeTime", + "The amout of time in milliseconds for all audio to fade in at the start of a level", + generate_hash("snd_levelFadeTime") + }, + { + "snd_loadFadeTime", + "Fade time for loading from a checkpoint after death.", + generate_hash("snd_loadFadeTime") + }, + { + "snd_loopFadeTime", + "Fade-in time for looping sounds.", + generate_hash("snd_loopFadeTime") + }, + { + "snd_musicDisabled", + "Disable all in-game music", + generate_hash("snd_musicDisabled") + }, + { + "snd_musicDisabledForCustomSoundtrack", + "Disable all in-game music due to user playing a custom soundtrack", + generate_hash("snd_musicDisabledForCustomSoundtrack") + }, + { + "snd_occlusionDelay", + "Minimum delay in (ms) between occlusion updates", + generate_hash("snd_occlusionDelay") + }, + { + "snd_occlusionLerpTime", + "Time to lerp to target occlusion lerp when occluded", + generate_hash("snd_occlusionLerpTime") + }, + { + "snd_peakLimiterCompression", + "Peak limiter compression factor. The output data is scaled by this and then normalized: F < 1 = disabled; F >= 1 enabled.", + generate_hash("snd_peakLimiterCompression") + }, + { + "snd_peakLimiterDecay", + "Peak limiter compression decay ratio.", + generate_hash("snd_peakLimiterDecay") + }, + { + "snd_peakLimiterSustainFrames", + "Number of frames to sustain the limiter peak. 1 frame = 10 msec.", + generate_hash("snd_peakLimiterSustainFrames") + }, + { + "snd_premixVolume", + "Game sound pre-mix volume", + generate_hash("snd_premixVolume") + }, + { + "snd_reverbZoneOutsideFactor", + "When a 3d sound is played in a different reverb zone than the player, this factor will be applied to its wet level.", + generate_hash("snd_reverbZoneOutsideFactor") + }, + { + "snd_slaveFadeTime", + "The amount of time in milliseconds for a 'slave' sound\nto fade its volumes when a master sound starts or stops", + generate_hash("snd_slaveFadeTime") + }, + { + "snd_speakerConfig", + "speaker configuration:\n0: autodetect\n1: mono\n2: stereo\n4: quadrophonic\n6: 5.1 surround\n8: 7.1 surround", + generate_hash("snd_speakerConfig") + }, + { + "snd_touchStreamFilesOnLoad", + "Check whether stream sound files exist while loading", + generate_hash("snd_touchStreamFilesOnLoad") + }, + { + "snd_useOldPanning", + "Use old and busted panning", + generate_hash("snd_useOldPanning") + }, + { + "snd_virtualChannelInfo", + "Display virtual voice info.", + generate_hash("snd_virtualChannelInfo") + }, + { + "snd_virtualMinDur", + "The minimum duration (in seconds) of a sound if it is to be added to the virtual voice buffer.", + generate_hash("snd_virtualMinDur") + }, + { + "snd_virtualMinPri", + "The minimum priority of an alias if it is to be added to the virtual voice buffer.", + generate_hash("snd_virtualMinPri") + }, + { + "snd_virtualMinTimeLeftToRevive", + "The minimum time (in ms) left in a sample in order to attempt to revive it.", + generate_hash("snd_virtualMinTimeLeftToRevive") + }, + { + "snd_virtualReviveVoices", + "Whether or not to restore virtual voices.", + generate_hash("snd_virtualReviveVoices") + }, + { + "snd_virtualWaitToReviveTime", + "The minimum time (in ms) to wait before trying to revive the voice.", + generate_hash("snd_virtualWaitToReviveTime") + }, + { + "snd_volume", + "Game sound master volume", + generate_hash("snd_volume") + }, + { + "speech_active", + "Are we allowed to enable Speech or not", + generate_hash("speech_active") + }, + { + "splitscreen", + "Current game is a splitscreen game", + generate_hash("splitscreen") + }, + { + "steam_ingame_p2p_throttle", + "Time, in MS, to wait between P2P packet lookups when in-game", + generate_hash("steam_ingame_p2p_throttle") + }, + { + "stringtable_debug", + "spam debug info for stringtable lookups", + generate_hash("stringtable_debug") + }, + { + "sv_allowClientConsole", + "Allow remote clients to access the console", + generate_hash("sv_allowClientConsole") + }, + { + "sv_allowedClan1", + "", + generate_hash("sv_allowedClan1") + }, + { + "sv_allowedClan2", + "", + generate_hash("sv_allowedClan2") + }, + { + "sv_archiveClientsPositions", + "Archive the client positions to speed up SV_GetClientPositionsAtTime", + generate_hash("sv_archiveClientsPositions") + }, + { + "sv_checkMinPlayers", + "Check min players. 0 disables", + generate_hash("sv_checkMinPlayers") + }, + { + "sv_clientArchive", + "Have the clients archive data to save bandwidth on the server", + generate_hash("sv_clientArchive") + }, + { + "sv_connectTimeout", + "seconds without any message when a client is loading", + generate_hash("sv_connectTimeout") + }, + { + "sv_cumulThinkTime", + "Max client think per server 50 msec frame", + generate_hash("sv_cumulThinkTime") + }, + { + "sv_error_on_baseline_failure", + "Throw an error if the const baseline data is invalid.", + generate_hash("sv_error_on_baseline_failure") + }, + { + "sv_exponentialBackoffAfterNonAckedMsgs", + "start exponential backoff on msg frequency if the client has not acked the last X messages", + generate_hash("sv_exponentialBackoffAfterNonAckedMsgs") + }, + { + "sv_hostname", + "Host name of the server", + generate_hash("sv_hostname") + }, + { + "sv_hugeSnapshotDelay", + "How long to wait before building a new snapshot after a 'huge' snapshot is sent", + generate_hash("sv_hugeSnapshotDelay") + }, + { + "sv_hugeSnapshotSize", + "Size of a snapshot to be considered 'huge'", + generate_hash("sv_hugeSnapshotSize") + }, + { + "sv_kickBanTime", + "Time in seconds for a player to be banned from the server after being kicked", + generate_hash("sv_kickBanTime") + }, + { + "sv_local_client_snapshot_msec", + "Local client snapshot rate, add to cl_penaltyTime", + generate_hash("sv_local_client_snapshot_msec") + }, + { + "sv_maxclients", + "The maximum number of clients that can connect to a server", + generate_hash("sv_maxclients") + }, + { + "sv_minPingClamp", + "Clamp the minimum ping to this value", + generate_hash("sv_minPingClamp") + }, + { + "sv_network_fps", + "Number of times per second the server checks for net messages", + generate_hash("sv_network_fps") + }, + { + "sv_numExpBackoffBeforeReleasingCachedSnapshots", + "if a client is under an exponential backoff over this dvar, then we will release all the cached snapshot data he owns and will send him a baseline if he reconnects", + generate_hash("sv_numExpBackoffBeforeReleasingCachedSnapshots") + }, + { + "sv_paused", + "Pause the server", + generate_hash("sv_paused") + }, + { + "sv_privateClients", + "Maximum number of private clients allowed on the server", + generate_hash("sv_privateClients") + }, + { + "sv_privateClientsForClients", + "The # of private clients (we send this to clients)", + generate_hash("sv_privateClientsForClients") + }, + { + "sv_privatePassword", + "password for the privateClient slots", + generate_hash("sv_privatePassword") + }, + { + "sv_reconnectlimit", + "minimum seconds between connect messages", + generate_hash("sv_reconnectlimit") + }, + { + "sv_rejoinTimeout", + "seconds without any message before allowing a rejoin", + generate_hash("sv_rejoinTimeout") + }, + { + "sv_remote_client_snapshot_joiningstate_msec", + "Remote client snapshot rate during join (until the client acked his first delta message)", + generate_hash("sv_remote_client_snapshot_joiningstate_msec") + }, + { + "sv_remote_client_snapshot_msec", + "Remote client snapshot rate, add to cl_penaltyTime", + generate_hash("sv_remote_client_snapshot_msec") + }, + { + "sv_resetOnSpawn", + "Have clients reset some player state fields when spawning rather than sending them over the network", + generate_hash("sv_resetOnSpawn") + }, + { + "sv_running", + "Server is running", + generate_hash("sv_running") + }, + { + "sv_sayName", + "", + generate_hash("sv_sayName") + }, + { + "sv_showAverageBPS", + "Show average bytes per second for net debugging", + generate_hash("sv_showAverageBPS") + }, + { + "sv_testValue", + "Max antilag rewind", + generate_hash("sv_testValue") + }, + { + "sv_timeout", + "seconds without any message", + generate_hash("sv_timeout") + }, + { + "sv_trackFrameMsecThreshold", + "server frame time that will trigger script time tracking.", + generate_hash("sv_trackFrameMsecThreshold") + }, + { + "sv_useExtraCompress", + "Use zlib compress for gamestate/baseline/score packets", + generate_hash("sv_useExtraCompress") + }, + { + "sv_zlib_threshold", + "Message size threshold which triggers more aggressive compression", + generate_hash("sv_zlib_threshold") + }, + { + "sv_zombietime", + "seconds to sync messages after disconnect", + generate_hash("sv_zombietime") + }, + { + "svwp", + "playerdata server write protection: 0 = disable, 1 = silent, 2 = kick", + generate_hash("svwp") + }, + { + "syncTimeTimeout", + "default timeout for sync time task (in seconds)", + generate_hash("syncTimeTimeout") + }, + { + "sys_configSum", + "Configuration checksum", + generate_hash("sys_configSum") + }, + { + "sys_configureGHz", + "Normalized total CPU power, based on cpu type, count, and speed; used in autoconfigure", + generate_hash("sys_configureGHz") + }, + { + "sys_cpuGHz", + "Measured CPU speed", + generate_hash("sys_cpuGHz") + }, + { + "sys_cpuName", + "CPU name description", + generate_hash("sys_cpuName") + }, + { + "sys_gpu", + "GPU description", + generate_hash("sys_gpu") + }, + { + "sys_lockThreads", + "Prevents specified threads from changing CPUs; improves profiling and may fix some bugs, but can hurt performance", + generate_hash("sys_lockThreads") + }, + { + "sys_quitMigrateTime", + "Time in msec to wait for host migration when user closes the window", + generate_hash("sys_quitMigrateTime") + }, + { + "sys_smp_allowed", + "Allow multi-threading", + generate_hash("sys_smp_allowed") + }, + { + "sys_SSE", + "Operating system allows Streaming SIMD Extensions", + generate_hash("sys_SSE") + }, + { + "sys_sysMB", + "Physical memory in the system", + generate_hash("sys_sysMB") + }, + { + "systemlink", + "Current game is a system link game", + generate_hash("systemlink") + }, + { + "systemlink_host", + "Local client is hosting system link game", + generate_hash("systemlink_host") + }, + { + "tb_report", + "tb event record", + generate_hash("tb_report") + }, + { + "team_rebalance", + "rebalance", + generate_hash("team_rebalance") + }, + { + "teambalance_option", + "Selects active teambalance algorithm. 0 = heuristic 1 = exhaustive", + generate_hash("teambalance_option") + }, + { + "theater_active", + "Are we allowed to show theater or not.", + generate_hash("theater_active") + }, + { + "thermal_playerModel", + "Model to draw for players when in thermal vision mode", + generate_hash("thermal_playerModel") + }, + { + "thermalBlurFactorNoScope", + "Amount of blur to use when drawing blur through a weapon's thermal scope.", + generate_hash("thermalBlurFactorNoScope") + }, + { + "thermalBlurFactorScope", + "Amount of blur to use when drawing blur through a weapon's thermal scope.", + generate_hash("thermalBlurFactorScope") + }, + { + "tokensEnabled", + "Is token economy enabled", + generate_hash("tokensEnabled") + }, + { + "tracer_explosiveColor1", + "The 1st color of a bullet tracer when using explosive bullets", + generate_hash("tracer_explosiveColor1") + }, + { + "tracer_explosiveColor2", + "The 2nd color of a bullet tracer when using explosive bullets", + generate_hash("tracer_explosiveColor2") + }, + { + "tracer_explosiveColor3", + "The 3rd color of a bullet tracer when using explosive bullets", + generate_hash("tracer_explosiveColor3") + }, + { + "tracer_explosiveColor4", + "The 4th color of a bullet tracer when using explosive bullets", + generate_hash("tracer_explosiveColor4") + }, + { + "tracer_explosiveColor5", + "The 5th color of a bullet tracer when using explosive bullets", + generate_hash("tracer_explosiveColor5") + }, + { + "tracer_explosiveOverride", + "When turned on, will apply an override to the tracer settings when shooting explosive bullets.", + generate_hash("tracer_explosiveOverride") + }, + { + "tracer_explosiveWidth", + "The width of a bullet tracer when using explosive bullets", + generate_hash("tracer_explosiveWidth") + }, + { + "tracer_firstPersonMaxWidth", + "The maximum width our OWN tracers can be when looking through our ADS", + generate_hash("tracer_firstPersonMaxWidth") + }, + { + "tracer_stoppingPowerColor1", + "The 1st color of a bullet tracer when using explosive bullets", + generate_hash("tracer_stoppingPowerColor1") + }, + { + "tracer_stoppingPowerColor2", + "The 2nd color of a bullet tracer when using explosive bullets", + generate_hash("tracer_stoppingPowerColor2") + }, + { + "tracer_stoppingPowerColor3", + "The 3rd color of a bullet tracer when using explosive bullets", + generate_hash("tracer_stoppingPowerColor3") + }, + { + "tracer_stoppingPowerColor4", + "The 4th color of a bullet tracer when using explosive bullets", + generate_hash("tracer_stoppingPowerColor4") + }, + { + "tracer_stoppingPowerColor5", + "The 5th color of a bullet tracer when using explosive bullets", + generate_hash("tracer_stoppingPowerColor5") + }, + { + "tracer_stoppingPowerOverride", + "When turned on, will apply an override to the tracer settings when shooting explosive bullets.", + generate_hash("tracer_stoppingPowerOverride") + }, + { + "tracer_stoppingPowerWidth", + "The width of a bullet tracer when using explosive bullets", + generate_hash("tracer_stoppingPowerWidth") + }, + { + "tracer_thermalWidthMult", + "The multiplier applied to the base width when viewed in thermal vision", + generate_hash("tracer_thermalWidthMult") + }, + { + "transients_verbose", + "Verbose logging information for transient fastfiles.", + generate_hash("transients_verbose") + }, + { + "triggerDLCEnumerationOnSocialConfigLoad", + "Triggers a new DLC enumeration after social config has loaded.", + generate_hash("triggerDLCEnumerationOnSocialConfigLoad") + }, + { + "ui_allow_controlschange", + "", + generate_hash("ui_allow_controlschange") + }, + { + "ui_allow_teamchange", + "", + generate_hash("ui_allow_teamchange") + }, + { + "ui_autodetectGamepad", + "undefined", + generate_hash("ui_autodetectGamepad") + }, + { + "ui_autodetectGamepadDone", + "undefined", + generate_hash("ui_autodetectGamepadDone") + }, + { + "ui_bigFont", + "Big font scale", + generate_hash("ui_bigFont") + }, + { + "ui_blurAmount", + "Max amount to blur background menu items.", + generate_hash("ui_blurAmount") + }, + { + "ui_blurDarkenAmount", + "Amount to darken blurred UI.", + generate_hash("ui_blurDarkenAmount") + }, + { + "ui_blurTime", + "Time in milliseconds to fade in/out the blur.", + generate_hash("ui_blurTime") + }, + { + "ui_borderLowLightScale", + "Scales the border color for the lowlight color on certain UI borders", + generate_hash("ui_borderLowLightScale") + }, + { + "ui_browserFriendlyfire", + "Friendly fire is active", + generate_hash("ui_browserFriendlyfire") + }, + { + "ui_browserKillcam", + "Kill cam is active", + generate_hash("ui_browserKillcam") + }, + { + "ui_browserMod", + "UI Mod value", + generate_hash("ui_browserMod") + }, + { + "ui_browserShowDedicated", + "Show dedicated servers only", + generate_hash("ui_browserShowDedicated") + }, + { + "ui_browserShowEmpty", + "Show empty servers", + generate_hash("ui_browserShowEmpty") + }, + { + "ui_browserShowFull", + "Show full servers", + generate_hash("ui_browserShowFull") + }, + { + "ui_browserShowPassword", + "Show servers that are password protected", + generate_hash("ui_browserShowPassword") + }, + { + "ui_browserShowPure", + "Show pure servers only", + generate_hash("ui_browserShowPure") + }, + { + "ui_buildLocation", + "Where to draw the build number", + generate_hash("ui_buildLocation") + }, + { + "ui_buildSize", + "Font size to use for the build number", + generate_hash("ui_buildSize") + }, + { + "ui_challenge_1_ref", + "", + generate_hash("ui_challenge_1_ref") + }, + { + "ui_challenge_2_ref", + "", + generate_hash("ui_challenge_2_ref") + }, + { + "ui_challenge_3_ref", + "", + generate_hash("ui_challenge_3_ref") + }, + { + "ui_challenge_4_ref", + "", + generate_hash("ui_challenge_4_ref") + }, + { + "ui_challenge_5_ref", + "", + generate_hash("ui_challenge_5_ref") + }, + { + "ui_challenge_6_ref", + "", + generate_hash("ui_challenge_6_ref") + }, + { + "ui_challenge_7_ref", + "", + generate_hash("ui_challenge_7_ref") + }, + { + "ui_changeclass_menu_open", + "", + generate_hash("ui_changeclass_menu_open") + }, + { + "ui_changeteam_menu_open", + "", + generate_hash("ui_changeteam_menu_open") + }, + { + "ui_cinematicsTimestamp", + "Shows cinematics timestamp on subtitle UI elements.", + generate_hash("ui_cinematicsTimestamp") + }, + { + "ui_class_menu_open", + "", + generate_hash("ui_class_menu_open") + }, + { + "ui_connectScreenTextGlowColor", + "Glow color applied to the mode and map name strings on the connect screen.", + generate_hash("ui_connectScreenTextGlowColor") + }, + { + "ui_contextualMenuLocation", + "Contextual menu location from where you entered the store.", + generate_hash("ui_contextualMenuLocation") + }, + { + "ui_controls_menu_open", + "", + generate_hash("ui_controls_menu_open") + }, + { + "ui_currentFeederMapIndex", + "Currently selected map", + generate_hash("ui_currentFeederMapIndex") + }, + { + "ui_currentMap", + "Current map index", + generate_hash("ui_currentMap") + }, + { + "ui_customClassName", + "Custom Class name", + generate_hash("ui_customClassName") + }, + { + "ui_customModeEditName", + "Name to give the currently edited custom game mode when editing is complete", + generate_hash("ui_customModeEditName") + }, + { + "ui_customModeName", + "Custom game mode name", + generate_hash("ui_customModeName") + }, + { + "ui_danger_team", + "", + generate_hash("ui_danger_team") + }, + { + "ui_debugMode", + "Draw ui debug info on the screen.", + generate_hash("ui_debugMode") + }, + { + "ui_disableInGameStore", + "This will disable the ingame store button on the xbox live menu.", + generate_hash("ui_disableInGameStore") + }, + { + "ui_disableTokenRedemption", + "This will disable the token redemption option in the in-game store menu.", + generate_hash("ui_disableTokenRedemption") + }, + { + "ui_drawCrosshair", + "Whether to draw crosshairs.", + generate_hash("ui_drawCrosshair") + }, + { + "ui_editSquadMemberIndex", + "Which squad member is currently being edited", + generate_hash("ui_editSquadMemberIndex") + }, + { + "ui_extraBigFont", + "Extra big font scale", + generate_hash("ui_extraBigFont") + }, + { + "ui_game_state", + "", + generate_hash("ui_game_state") + }, + { + "ui_gametype", + "Current game type", + generate_hash("ui_gametype") + }, + { + "ui_halftime", + "", + generate_hash("ui_halftime") + }, + { + "ui_hitloc_0", + "", + generate_hash("ui_hitloc_0") + }, + { + "ui_hitloc_1", + "", + generate_hash("ui_hitloc_1") + }, + { + "ui_hitloc_2", + "", + generate_hash("ui_hitloc_2") + }, + { + "ui_hitloc_3", + "", + generate_hash("ui_hitloc_3") + }, + { + "ui_hitloc_4", + "", + generate_hash("ui_hitloc_4") + }, + { + "ui_hitloc_5", + "", + generate_hash("ui_hitloc_5") + }, + { + "ui_hitloc_damage_0", + "", + generate_hash("ui_hitloc_damage_0") + }, + { + "ui_hitloc_damage_1", + "", + generate_hash("ui_hitloc_damage_1") + }, + { + "ui_hitloc_damage_2", + "", + generate_hash("ui_hitloc_damage_2") + }, + { + "ui_hitloc_damage_3", + "", + generate_hash("ui_hitloc_damage_3") + }, + { + "ui_hitloc_damage_4", + "", + generate_hash("ui_hitloc_damage_4") + }, + { + "ui_hitloc_damage_5", + "", + generate_hash("ui_hitloc_damage_5") + }, + { + "ui_hud_hardcore", + "Whether the HUD should be suppressed for hardcore mode", + generate_hash("ui_hud_hardcore") + }, + { + "ui_hud_obituaries", + "", + generate_hash("ui_hud_obituaries") + }, + { + "ui_inactiveBaseColor", + "The local player's rank/stats font color when shown in lobbies and parties", + generate_hash("ui_inactiveBaseColor") + }, + { + "ui_inactivePartyColor", + "", + generate_hash("ui_inactivePartyColor") + }, + { + "ui_inGameStoreOpen", + "is the InGameStore open", + generate_hash("ui_inGameStoreOpen") + }, + { + "ui_inhostmigration", + "", + generate_hash("ui_inhostmigration") + }, + { + "ui_joinGametype", + "Game join type", + generate_hash("ui_joinGametype") + }, + { + "ui_loadMenuName", + "Frontend menu will start on this level instead of lockout", + generate_hash("ui_loadMenuName") + }, + { + "ui_mapname", + "Current map name", + generate_hash("ui_mapname") + }, + { + "ui_mapvote_entrya_gametype", + "Primary map vote entry game type", + generate_hash("ui_mapvote_entrya_gametype") + }, + { + "ui_mapvote_entrya_mapname", + "Primary map vote entry map name", + generate_hash("ui_mapvote_entrya_mapname") + }, + { + "ui_mapvote_entryb_gametype", + "Secondary map vote entry game type", + generate_hash("ui_mapvote_entryb_gametype") + }, + { + "ui_mapvote_entryb_mapname", + "Secondary map vote entry map name", + generate_hash("ui_mapvote_entryb_mapname") + }, + { + "ui_maxclients", + "undefined", + generate_hash("ui_maxclients") + }, + { + "ui_missingMapName", + "Name of map to show in missing content error", + generate_hash("ui_missingMapName") + }, + { + "ui_mousePitch", + "", + generate_hash("ui_mousePitch") + }, + { + "ui_multiplayer", + "True if the game is multiplayer", + generate_hash("ui_multiplayer") + }, + { + "ui_myPartyColor", + "Player name font color when in the same party as the local player", + generate_hash("ui_myPartyColor") + }, + { + "ui_netGametype", + "Game type", + generate_hash("ui_netGametype") + }, + { + "ui_netGametypeName", + "Displayed game type name", + generate_hash("ui_netGametypeName") + }, + { + "ui_netSource", + "The network source where:\n 0:Local\n 1:Internet\n 2:Favourites", + generate_hash("ui_netSource") + }, + { + "ui_onlineRequired", + "UI requires online connection to be present.", + generate_hash("ui_onlineRequired") + }, + { + "ui_opensummary", + "", + generate_hash("ui_opensummary") + }, + { + "ui_override_halftime", + "", + generate_hash("ui_override_halftime") + }, + { + "ui_partyFull", + "True if the current party is full.", + generate_hash("ui_partyFull") + }, + { + "ui_playerPartyColor", + "", + generate_hash("ui_playerPartyColor") + }, + { + "ui_playlistActionButtonAlpha", + "The current alpha of the playlist selection button", + generate_hash("ui_playlistActionButtonAlpha") + }, + { + "ui_playlistCategoryDisabledColor", + "The color of playlist categories when disabled", + generate_hash("ui_playlistCategoryDisabledColor") + }, + { + "ui_playlistCategoryEnabledColor", + "The color of playlist categories when enabled", + generate_hash("ui_playlistCategoryEnabledColor") + }, + { + "ui_promotion", + "", + generate_hash("ui_promotion") + }, + { + "ui_remoteTankUseTime", + "", + generate_hash("ui_remoteTankUseTime") + }, + { + "ui_scorelimit", + "", + generate_hash("ui_scorelimit") + }, + { + "ui_selectedFeederMap", + "Current preview game type", + generate_hash("ui_selectedFeederMap") + }, + { + "ui_serverStatusTimeOut", + "Time in milliseconds before a server status request times out", + generate_hash("ui_serverStatusTimeOut") + }, + { + "ui_show_store", + "Use to enable the store button", + generate_hash("ui_show_store") + }, + { + "ui_showDLCMaps", + "Whether to display the DLC maps.", + generate_hash("ui_showDLCMaps") + }, + { + "ui_showInfo", + "", + generate_hash("ui_showInfo") + }, + { + "ui_showList", + "Show onscreen list of currently visible menus", + generate_hash("ui_showList") + }, + { + "ui_showmap", + "", + generate_hash("ui_showmap") + }, + { + "ui_showMenuOnly", + "If set, only menus using this name will draw.", + generate_hash("ui_showMenuOnly") + }, + { + "ui_showMinimap", + "", + generate_hash("ui_showMinimap") + }, + { + "ui_sliderSteps", + "The number of steps for a slider itemdef", + generate_hash("ui_sliderSteps") + }, + { + "ui_smallFont", + "Small font scale", + generate_hash("ui_smallFont") + }, + { + "ui_textScrollFadeTime", + "Text scrolling takes this long (seconds) to fade out at the end before restarting", + generate_hash("ui_textScrollFadeTime") + }, + { + "ui_textScrollPauseEnd", + "Text scrolling waits this long (seconds) before starting", + generate_hash("ui_textScrollPauseEnd") + }, + { + "ui_textScrollPauseStart", + "Text scrolling waits this long (seconds) before starting", + generate_hash("ui_textScrollPauseStart") + }, + { + "ui_textScrollSpeed", + "Speed at which text scrolls vertically", + generate_hash("ui_textScrollSpeed") + }, + { + "ui_timelimit", + "", + generate_hash("ui_timelimit") + }, + { + "uiscript_debug", + "spam debug info for the ui script", + generate_hash("uiscript_debug") + }, + { + "unlock_breadcrumb_killswitch", + "True to enable unlock breadcrumbs", + generate_hash("unlock_breadcrumb_killswitch") + }, + { + "uno_current_tos_version", + "Current Uno Terms of Service Version", + generate_hash("uno_current_tos_version") + }, + { + "use_filtered_query_pass", + "Dictates whether to use the filtered query for MMing or not", + generate_hash("use_filtered_query_pass") + }, + { + "use_weighted_dlc_exactmatch_pass", + "Dictates whether to use a search weighted pass with the DLC match set to exact for MMing or not", + generate_hash("use_weighted_dlc_exactmatch_pass") + }, + { + "use_weighted_pass", + "Dictates whether to use the search weighted pass for MMing or not", + generate_hash("use_weighted_pass") + }, + { + "useCPMarkerForCPOwnership", + "If set, we will check the player inventory to see if he owns the redeemedItem for a contentPack if this contentPack is not available for the player", + generate_hash("useCPMarkerForCPOwnership") + }, + { + "useonlinestats", + "Whether to use online stats when in offline modes", + generate_hash("useonlinestats") + }, + { + "useRelativeTeamColors", + "Whether to use relative team colors.", + generate_hash("useRelativeTeamColors") + }, + { + "userFileFetchTimeout", + "default timeout for user files FETCH tasks (in seconds)", + generate_hash("userFileFetchTimeout") + }, + { + "userGroup_active", + "Are we allowed to show Usergroups or not", + generate_hash("userGroup_active") + }, + { + "userGroup_cool_off_time", + "Cool off time between calls to fetch the elite clan", + generate_hash("userGroup_cool_off_time") + }, + { + "userGroup_coop_delay", + "Delay between a player joining a coop lobby and the DW user group task starting", + generate_hash("userGroup_coop_delay") + }, + { + "userGroup_max_retry_time", + "Max time that the usergroup read find can retry", + generate_hash("userGroup_max_retry_time") + }, + { + "userGroup_refresh_time_secs", + "Time in seconds between re-sending lobby group data to confirmed users.", + generate_hash("userGroup_refresh_time_secs") + }, + { + "userGroup_retry_step", + "Step in m/s for the usegroup read retry", + generate_hash("userGroup_retry_step") + }, + { + "userGroup_RetryTime", + "Time in ms between sending lobby group data retrys.", + generate_hash("userGroup_RetryTime") + }, + { + "useStatsGroups", + "If true then StatsGroups are in use for all playerdata.ddl accessing.", + generate_hash("useStatsGroups") + }, + { + "useTagFlashSilenced", + "When true, silenced weapons will use \"tag_flash_silenced\" instead of \"tag_flash\".", + generate_hash("useTagFlashSilenced") + }, + { + "using_mlg", + "MLG feature on/off", + generate_hash("using_mlg") + }, + { + "validate_apply_clamps", + "True if individual stat validation failure reverts the value", + generate_hash("validate_apply_clamps") + }, + { + "validate_apply_revert", + "True if individual stat validation failure reverts the value", + generate_hash("validate_apply_revert") + }, + { + "validate_apply_revert_full", + "True if any individual stat validation failure causes a full stats revert", + generate_hash("validate_apply_revert_full") + }, + { + "validate_clamp_assists", + "The maximum number of assists a player can make in a match", + generate_hash("validate_clamp_assists") + }, + { + "validate_clamp_experience", + "The maximum experience a player can gain in a match", + generate_hash("validate_clamp_experience") + }, + { + "validate_clamp_headshots", + "The maximum number of headshots a player can make in a match", + generate_hash("validate_clamp_headshots") + }, + { + "validate_clamp_hits", + "The maximum number of hits player can make in a match", + generate_hash("validate_clamp_hits") + }, + { + "validate_clamp_kills", + "The maximum number of kills a player can make in a match", + generate_hash("validate_clamp_kills") + }, + { + "validate_clamp_losses", + "The maximum number of losses a player can make in a match", + generate_hash("validate_clamp_losses") + }, + { + "validate_clamp_misses", + "The maximum number of misses player can make in a match", + generate_hash("validate_clamp_misses") + }, + { + "validate_clamp_ties", + "The maximum number of ties a player can make in a match", + generate_hash("validate_clamp_ties") + }, + { + "validate_clamp_totalshots", + "The maximum number of totalshots player can make in a match", + generate_hash("validate_clamp_totalshots") + }, + { + "validate_clamp_weaponXP", + "The maximum experience a weapon can gain in a match", + generate_hash("validate_clamp_weaponXP") + }, + { + "validate_clamp_wins", + "The maximum number of wins a player can make in a match", + generate_hash("validate_clamp_wins") + }, + { + "validate_drop_on_fail", + "True if stats validation failure results in dropping from the match", + generate_hash("validate_drop_on_fail") + }, + { + "veh_aiOverSteerScale", + "Scaler used to cause ai vehicles to over steer", + generate_hash("veh_aiOverSteerScale") + }, + { + "veh_boneControllerLodDist", + "Distance at which bone controllers are not updated.", + generate_hash("veh_boneControllerLodDist") + }, + { + "veh_boneControllerUnLodDist", + "Distance at which bone controllers start updating when not moving.", + generate_hash("veh_boneControllerUnLodDist") + }, + { + "vehAudio_inAirPitchDownLerp", + "Rate at which the pitch lerps down", + generate_hash("vehAudio_inAirPitchDownLerp") + }, + { + "vehAudio_inAirPitchUpLerp", + "Rate at which the pitch lerps up", + generate_hash("vehAudio_inAirPitchUpLerp") + }, + { + "vehAudio_spawnVolumeTime", + "Seconds it takes for spawned vehicles to reach full volume.", + generate_hash("vehAudio_spawnVolumeTime") + }, + { + "vehCam_freeLook", + "Enables free look mode", + generate_hash("vehCam_freeLook") + }, + { + "vehCam_mode", + "Camera modes: 1st person, 3rd person, or both", + generate_hash("vehCam_mode") + }, + { + "vehDroneDebugDrawPath", + "Debug render the drone draw paths.", + generate_hash("vehDroneDebugDrawPath") + }, + { + "vehHelicopterBoundsRadius", + "The radius of the collision volume to be used when colliding with world geometry.", + generate_hash("vehHelicopterBoundsRadius") + }, + { + "vehHelicopterDecelerationFwd", + "Set the deceleration of the player helicopter (as a fraction of acceleration) in the direction the chopper is facing. So 1.0 makes it equal to the acceleration.", + generate_hash("vehHelicopterDecelerationFwd") + }, + { + "vehHelicopterDecelerationSide", + "Set the side-to-side deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration.", + generate_hash("vehHelicopterDecelerationSide") + }, + { + "vehHelicopterDecelerationUp", + "Set the vertical deceleration of the player helicopter (as a fraction of acceleration). So 1.0 makes it equal to the acceleration.", + generate_hash("vehHelicopterDecelerationUp") + }, + { + "vehHelicopterHeadSwayDontSwayTheTurret", + "If set, the turret will not fire through the crosshairs, but straight ahead of the vehicle, when the player is not freelooking.", + generate_hash("vehHelicopterHeadSwayDontSwayTheTurret") + }, + { + "vehHelicopterHoverSpeedThreshold", + "The speed below which the player helicopter begins to jitter the tilt, for hovering", + generate_hash("vehHelicopterHoverSpeedThreshold") + }, + { + "vehHelicopterInvertUpDown", + "Invert the altitude control on the player helicopter.", + generate_hash("vehHelicopterInvertUpDown") + }, + { + "vehHelicopterJitterJerkyness", + "Specifies how jerky the tilt jitter should be", + generate_hash("vehHelicopterJitterJerkyness") + }, + { + "vehHelicopterLookaheadTime", + "How far ahead (in seconds) the player helicopter looks ahead, to avoid hard collisions. (Like driving down the highway, you should keep 2 seconds distance between you and the vehicle in front of you)", + generate_hash("vehHelicopterLookaheadTime") + }, + { + "vehHelicopterMaxAccel", + "Maximum horizontal acceleration of the player helicopter (in MPH per second)", + generate_hash("vehHelicopterMaxAccel") + }, + { + "vehHelicopterMaxAccelVertical", + "Maximum vertical acceleration of the player helicopter (in MPH per second)", + generate_hash("vehHelicopterMaxAccelVertical") + }, + { + "vehHelicopterMaxPitch", + "Maximum pitch of the player helicopter", + generate_hash("vehHelicopterMaxPitch") + }, + { + "vehHelicopterMaxRoll", + "Maximum roll of the player helicopter", + generate_hash("vehHelicopterMaxRoll") + }, + { + "vehHelicopterMaxSpeed", + "Maximum horizontal speed of the player helicopter (in MPH)", + generate_hash("vehHelicopterMaxSpeed") + }, + { + "vehHelicopterMaxSpeedVertical", + "Maximum vertical speed of the player helicopter (in MPH)", + generate_hash("vehHelicopterMaxSpeedVertical") + }, + { + "vehHelicopterMaxYawAccel", + "Maximum yaw acceleration of the player helicopter", + generate_hash("vehHelicopterMaxYawAccel") + }, + { + "vehHelicopterMaxYawRate", + "Maximum yaw speed of the player helicopter", + generate_hash("vehHelicopterMaxYawRate") + }, + { + "vehHelicopterPitchOffset", + "The resting pitch of the helicopter", + generate_hash("vehHelicopterPitchOffset") + }, + { + "vehHelicopterRightStickDeadzone", + "Dead-zone for the axes of the right thumbstick. This helps to better control the two axes separately.", + generate_hash("vehHelicopterRightStickDeadzone") + }, + { + "vehHelicopterScaleMovement", + "Scales down the smaller of the left stick axes.", + generate_hash("vehHelicopterScaleMovement") + }, + { + "vehHelicopterSoftCollisions", + "Player helicopters have soft collisions (slow down before they collide).", + generate_hash("vehHelicopterSoftCollisions") + }, + { + "vehHelicopterStrafeDeadzone", + "Dead-zone so that you can fly straight forward easily without accidentally strafing (and thus rolling).", + generate_hash("vehHelicopterStrafeDeadzone") + }, + { + "vehHelicopterTiltFromAcceleration", + "The amount of tilt caused by acceleration", + generate_hash("vehHelicopterTiltFromAcceleration") + }, + { + "vehHelicopterTiltFromControllerAxes", + "The amount of tilt caused by the desired velocity (i.e., the amount of controller stick deflection)", + generate_hash("vehHelicopterTiltFromControllerAxes") + }, + { + "vehHelicopterTiltFromDeceleration", + "The amount of tilt caused by deceleration", + generate_hash("vehHelicopterTiltFromDeceleration") + }, + { + "vehHelicopterTiltFromFwdAndYaw", + "The amount of roll caused by yawing while moving forward.", + generate_hash("vehHelicopterTiltFromFwdAndYaw") + }, + { + "vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt", + "The forward speed (as a fraction of top speed) at which the tilt due to yaw reaches is maximum value.", + generate_hash("vehHelicopterTiltFromFwdAndYaw_VelAtMaxTilt") + }, + { + "vehHelicopterTiltFromVelocity", + "The amount of tilt caused by the current velocity", + generate_hash("vehHelicopterTiltFromVelocity") + }, + { + "vehHelicopterTiltMomentum", + "The amount of rotational momentum the helicopter has with regards to tilting.", + generate_hash("vehHelicopterTiltMomentum") + }, + { + "vehHelicopterTiltSpeed", + "The rate at which the player helicopter's tilt responds", + generate_hash("vehHelicopterTiltSpeed") + }, + { + "vehHelicopterYawOnLeftStick", + "The yaw speed created by the left stick when pushing the stick diagonally (e.g., moving forward and strafing slightly).", + generate_hash("vehHelicopterYawOnLeftStick") + }, + { + "vehicle_debug_render_spline_plane", + "Do we want to render the spline plane data", + generate_hash("vehicle_debug_render_spline_plane") + }, + { + "vehicle_pathsmooth", + "Smoothed vehicle pathing.", + generate_hash("vehicle_pathsmooth") + }, + { + "vehUGVPitchTrack", + "UGV body pitch orientation speed", + generate_hash("vehUGVPitchTrack") + }, + { + "vehUGVRollTrack", + "UGV body roll orientation speed", + generate_hash("vehUGVRollTrack") + }, + { + "vehUGVWheelInfluence", + "UGV wheel influence on the orientation of the body", + generate_hash("vehUGVWheelInfluence") + }, + { + "vehWalkerControlMode", + "Walker controls (0==move no turn, 1=move and turn, 2=move relative(tank))", + generate_hash("vehWalkerControlMode") + }, + { + "version", + "Game version", + generate_hash("version") + }, + { + "vid_xpos", + "Game window horizontal position", + generate_hash("vid_xpos") + }, + { + "vid_ypos", + "Game window vertical position", + generate_hash("vid_ypos") + }, + { + "viewangNow", + "", + generate_hash("viewangNow") + }, + { + "viewModelDebugNotetracks", + "Enable display of viewmodel notetrack debug info.", + generate_hash("viewModelDebugNotetracks") + }, + { + "viewModelHacks", + "Enabled depth hack and remove viewmodel from shadows.", + generate_hash("viewModelHacks") + }, + { + "viewposNow", + "", + generate_hash("viewposNow") + }, + { + "virtualLobbyActive", + "Indicates the VL is actively being displayed.", + generate_hash("virtualLobbyActive") + }, + { + "virtualLobbyAllocated", + "Indicates the first VL zone has been loaded.", + generate_hash("virtualLobbyAllocated") + }, + { + "virtualLobbyEnabled", + "VirtualLobby is enabled (must be true before loading UI zone)", + generate_hash("virtualLobbyEnabled") + }, + { + "virtualLobbyInFiringRange", + "VirtualLobby is in firing range mode", + generate_hash("virtualLobbyInFiringRange") + }, + { + "virtualLobbyMap", + "VirtualLobby map to load (must be set before starting vl)", + generate_hash("virtualLobbyMap") + }, + { + "virtualLobbyMembers", + "Number of members in the VirtualLobby (set by script)", + generate_hash("virtualLobbyMembers") + }, + { + "virtualLobbyPresentable", + "Indicates to LUA the VirtualLobby is ready to be displayed (set by script).", + generate_hash("virtualLobbyPresentable") + }, + { + "virtualLobbyReady", + "Indicates to LUA the VirtualLobby is loaded and running (set by script).", + generate_hash("virtualLobbyReady") + }, + { + "vl_clan_models_loaded", + "Indicates to LUA when all models are loaded for the clan highlights so it can begin the fade-in without any popping(set by script).", + generate_hash("vl_clan_models_loaded") + }, + { + "voMtxEnable", + "When set (e.g. via config), will enable voice over packs", + generate_hash("voMtxEnable") + }, + { + "waypointAerialIconMaxSize", + "Max size of aerial targeting waypoints.", + generate_hash("waypointAerialIconMaxSize") + }, + { + "waypointAerialIconMinSize", + "Min size of aerial targeting waypoints.", + generate_hash("waypointAerialIconMinSize") + }, + { + "waypointAerialIconScale", + "Base scale of aerial targeting waypoints.", + generate_hash("waypointAerialIconScale") + }, + { + "waypointDebugDraw", + "", + generate_hash("waypointDebugDraw") + }, + { + "waypointDistScaleRangeMax", + "Distance from player that icon distance scaling ends.", + generate_hash("waypointDistScaleRangeMax") + }, + { + "waypointDistScaleRangeMin", + "Distance from player that icon distance scaling ends.", + generate_hash("waypointDistScaleRangeMin") + }, + { + "waypointDistScaleSmallest", + "Smallest scale that the distance effect uses.", + generate_hash("waypointDistScaleSmallest") + }, + { + "waypointIconHeight", + "", + generate_hash("waypointIconHeight") + }, + { + "waypointIconWidth", + "", + generate_hash("waypointIconWidth") + }, + { + "waypointOffscreenCornerRadius", + "Size of the rounded corners.", + generate_hash("waypointOffscreenCornerRadius") + }, + { + "waypointOffscreenDistanceThresholdAlpha", + "Distance from the threshold over which offscreen objective icons lerp their alpha.", + generate_hash("waypointOffscreenDistanceThresholdAlpha") + }, + { + "waypointOffscreenPadBottom", + "", + generate_hash("waypointOffscreenPadBottom") + }, + { + "waypointOffscreenPadLeft", + "", + generate_hash("waypointOffscreenPadLeft") + }, + { + "waypointOffscreenPadRight", + "", + generate_hash("waypointOffscreenPadRight") + }, + { + "waypointOffscreenPadTop", + "", + generate_hash("waypointOffscreenPadTop") + }, + { + "waypointOffscreenPointerDistance", + "Distance from the center of the offscreen objective icon to the center its arrow.", + generate_hash("waypointOffscreenPointerDistance") + }, + { + "waypointOffscreenPointerHeight", + "", + generate_hash("waypointOffscreenPointerHeight") + }, + { + "waypointOffscreenPointerWidth", + "", + generate_hash("waypointOffscreenPointerWidth") + }, + { + "waypointOffscreenRoundedCorners", + "Off-screen icons take rounded corners when true. 90-degree corners when false.", + generate_hash("waypointOffscreenRoundedCorners") + }, + { + "waypointOffscreenScaleLength", + "How far the offscreen icon scale travels from full to smallest scale.", + generate_hash("waypointOffscreenScaleLength") + }, + { + "waypointOffscreenScaleSmallest", + "Smallest scale that the offscreen effect uses.", + generate_hash("waypointOffscreenScaleSmallest") + }, + { + "waypointPlayerOffsetCrouch", + "For waypoints pointing to players, how high to offset off of their origin when they are prone.", + generate_hash("waypointPlayerOffsetCrouch") + }, + { + "waypointPlayerOffsetProne", + "For waypoints pointing to players, how high to offset off of their origin when they are prone.", + generate_hash("waypointPlayerOffsetProne") + }, + { + "waypointPlayerOffsetStand", + "For waypoints pointing to players, how high to offset off of their origin when they are prone.", + generate_hash("waypointPlayerOffsetStand") + }, + { + "waypointScreenCenterFadeAdsMin", + "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads", + generate_hash("waypointScreenCenterFadeAdsMin") + }, + { + "waypointScreenCenterFadeHipMin", + "When 'waypointScreenCenterFadeRadius' enabled, minimum amount that waypoint will fade when in ads", + generate_hash("waypointScreenCenterFadeHipMin") + }, + { + "waypointScreenCenterFadeRadius", + "Radius from screen center that a waypoint will start fading out. Setting to 0 will turn this off", + generate_hash("waypointScreenCenterFadeRadius") + }, + { + "waypointSplitscreenScale", + "Scale applied to waypoint icons in splitscreen views.", + generate_hash("waypointSplitscreenScale") + }, + { + "waypointTweakY", + "", + generate_hash("waypointTweakY") + }, + { + "weap_thermoDebuffMod", + "", + generate_hash("weap_thermoDebuffMod") + }, + { + "wideScreen", + "True if the game video is running in 16x9 aspect, false if 4x3.", + generate_hash("wideScreen") + }, + { + "winvoice_loopback", + "Echo microphone input locally", + generate_hash("winvoice_loopback") + }, + { + "winvoice_mic_mute", + "Mute the microphone", + generate_hash("winvoice_mic_mute") + }, + { + "winvoice_mic_outTime", + "Microphone voice amount of silence before we cut the mic", + generate_hash("winvoice_mic_outTime") + }, + { + "winvoice_mic_reclevel", + "Microphone recording level", + generate_hash("winvoice_mic_reclevel") + }, + { + "winvoice_mic_scaler", + "Microphone scaler value", + generate_hash("winvoice_mic_scaler") + }, + { + "winvoice_mic_threshold", + "Microphone voice threshold", + generate_hash("winvoice_mic_threshold") + }, + { + "winvoice_save_voice", + "Write voice data to a file", + generate_hash("winvoice_save_voice") + }, + { + "xanim_disableIK", + "Disable inverse kinematics solvers", + generate_hash("xanim_disableIK") + }, + { + "xblive_competitionmatch", + "MLG Rules?", + generate_hash("xblive_competitionmatch") + }, + { + "xblive_hostingprivateparty", + "true only if we're hosting a party", + generate_hash("xblive_hostingprivateparty") + }, + { + "xblive_loggedin", + "User is logged into xbox live", + generate_hash("xblive_loggedin") + }, + { + "xblive_privatematch", + "Current game is a private match", + generate_hash("xblive_privatematch") + }, + { + "xblive_privatematch_solo", + "Current game is an Extinction solo match", + generate_hash("xblive_privatematch_solo") + }, + { + "xphys_maxJointPositionError", + "If a joints with position error exceeding this value is detected, then the whole xphys system gets snapped back to the animation pose", + generate_hash("xphys_maxJointPositionError") + }, }; std::string dvar_get_description(const std::string& name) @@ -2485,6 +11712,24 @@ namespace dvars return true; } + std::optional get_dvar_info_from_hash(const int hash) + { + for (std::uint32_t i = 0; i < dvar_list.size(); i++) + { + if (dvar_list[i].hash == hash) + { + return {dvar_list[i]}; + } + } + + return {}; + } + + std::string hash_to_string(const int hash) + { + return utils::string::va("0x%lX", hash); + } + game::dvar_t* register_int(const std::string& name, int value, int min, int max, game::DvarFlags flags, const std::string& description) { diff --git a/src/client/game/dvars.hpp b/src/client/game/dvars.hpp index 5ac42230..2d1d7673 100644 --- a/src/client/game/dvars.hpp +++ b/src/client/game/dvars.hpp @@ -10,6 +10,7 @@ namespace dvars { std::string name; std::string description; + int hash; }; extern game::dvar_t* aimassist_enabled; @@ -36,6 +37,7 @@ namespace dvars std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain); std::string dvar_get_domain(const game::dvar_type type, const game::dvar_limits& domain); std::string dvar_get_description(const std::string& name); + std::optional get_dvar_info_from_hash(const int hash); game::dvar_t* register_int(const std::string& name, int value, int min, int max, game::DvarFlags flags, const std::string& description); diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index a20c48d7..60c368a1 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -940,8 +940,11 @@ namespace game dvar_value latched; dvar_value reset; dvar_limits domain; + char __pad0[0xC]; }; + static_assert(sizeof(dvar_t) == 96); + enum connstate_t { CA_DISCONNECTED = 0x0, @@ -1350,10 +1353,10 @@ namespace game struct gclient_s { - char __pad0[20708]; - char name[32]; // 20708 - char __pad1[668]; - int flags; // 21408 + char __pad0[18720]; + char name[32]; // 18720 + char __pad1[752]; + int flags; // 19504 }; // size = ? struct EntityState diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 0e0c02e4..9118b37c 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -40,6 +40,8 @@ namespace game WEAK symbol CG_GameMessage{0x1401389A0, 0x140220CC0}; WEAK symbol CG_GameMessageBold{0x140138750, 0x140220620}; + WEAK symbol CG_SetClientDvarFromServer{0, 0x140236120}; WEAK symbol CL_IsCgameInitialized{0x14017EE30, 0x140245650}; @@ -47,6 +49,10 @@ namespace game WEAK symbol Dvar_FindVar{0x1403C5D50, 0x1404FBB00}; WEAK symbol Dvar_GetCombinedString{0x140354DF0, 0x14041D830}; WEAK symbol Dvar_ValueToString{0x1403C8560, 0x1404FE660}; + WEAK symbol Dvar_Reset{0, 0x1404FCC40}; + WEAK symbol Dvar_SetFromStringByNameFromSource{0, 0x1404FD490}; + WEAK symbol Dvar_RegisterBool{0x1403C47E0, 0x1404FA540}; WEAK symbol gfxDrawMethod{0x14F05CE50, 0x14FD21180}; WEAK symbol dvarCount{0x14C217D10, 0x14D064CF4}; - WEAK symbol dvarPool{0x14C217D20, 0x14D064D00}; + WEAK symbol dvarPool{0x14C217D20, 0x14D064D00}; WEAK symbol DB_XAssetPool{0x140DE8C80, 0x140FEB5D0}; From c08a8e920101817f908df63bfbd9ea4ebc9c953f Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 03:21:37 +0100 Subject: [PATCH 080/346] Adjust console colors --- src/client/component/game_console.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index b0f81eca..deec2813 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -59,7 +59,7 @@ namespace game_console std::vector matches{}; float color_white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - float color_title[4] = {0.25f, 0.62f, 0.3f, 1.0f}; + float color_title[4] = {0.3f, 0.7f, 0.3f, 1.0f}; void clear() { @@ -782,7 +782,7 @@ namespace game_console dvars::con_outputBarColor = dvars::register_vec4("con_outputBarColor", 0.5f, 0.5f, 0.5f, 0.6f, 0.0f, 1.0f, game::DVAR_FLAG_SAVED, "color of console output bar"); - dvars::con_outputSliderColor = dvars::register_vec4("con_outputSliderColor", 1.0f, 0.8f, 0.0f, 1.0f, + dvars::con_outputSliderColor = dvars::register_vec4("con_outputSliderColor", 0.3f, 0.7f, 0.3f, 1.0f, 0.0f, 1.0f, game::DVAR_FLAG_SAVED, "color of console output slider"); dvars::con_outputWindowColor = dvars::register_vec4("con_outputWindowColor", 0.25f, 0.25f, 0.25f, 0.85f, From be19c5edc749223cd25a6f7e4fbf8e5ba1c56534 Mon Sep 17 00:00:00 2001 From: m Date: Sun, 13 Mar 2022 07:45:20 -0500 Subject: [PATCH 081/346] add listassetpool & others --- src/client/component/command.cpp | 17 ++++- src/client/component/game_console.cpp | 103 +++++++++++++------------- src/client/component/game_console.hpp | 5 +- src/client/game/symbols.hpp | 10 +++ 4 files changed, 78 insertions(+), 57 deletions(-) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 19532a87..28600228 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -277,6 +277,15 @@ namespace command } } + void enum_assets(const game::XAssetType type, const std::function& callback, const bool includeOverride) + { + game::DB_EnumXAssets_Internal(type, static_cast([](game::XAssetHeader header, void* data) + { + const auto& cb = *static_cast*>(data); + cb(header); + }), &callback, includeOverride); + } + class component final : public component_interface { public: @@ -339,7 +348,7 @@ namespace command console::info("================================ END COMMAND DUMP =================================\n"); }); - /*add("listassetpool", [](const params& params) + add("listassetpool", [](const params& params) { if (params.size() < 2) { @@ -378,7 +387,7 @@ namespace command console::info("%s\n", asset_name); }, true); } - });*/ + }); add("vstr", [](const params& params) { @@ -570,7 +579,7 @@ namespace command : "^1off")); }); - /*add_sv("give", [](const int client_num, const params_sv& params) + add_sv("give", [](const int client_num, const params_sv& params) { if (!game::Dvar_FindVar("sv_cheats")->current.enabled) { @@ -620,7 +629,7 @@ namespace command { game::G_TakePlayerWeapon(ps, wp); } - });*/ + }); } }; } diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index deec2813..913b412b 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -177,58 +177,6 @@ namespace game_console game::R_AddCmdDrawText(text, 0x7FFFFFFF, console_font, con.globals.x + offset_x, _y, 1.0f, 1.0f, 0.0f, color, 0); } - bool match_compare(const std::string& input, const std::string& text, const bool exact) - { - if (exact && text == input) return true; - if (!exact && text.find(input) != std::string::npos) return true; - return false; - } - - void find_matches(std::string input, std::vector& suggestions, const bool exact) - { - input = utils::string::to_lower(input); - - for (const auto& dvar : dvars::dvar_list) - { - auto name = utils::string::to_lower(dvar.name); - if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) - { - suggestions.push_back(dvar); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) - { - suggestions.push_back({input.data(), ""}); - } - - game::cmd_function_s* cmd = (*game::cmd_functions); - while (cmd) - { - if (cmd->name) - { - std::string name = utils::string::to_lower(cmd->name); - - if (match_compare(input, name, exact)) - { - suggestions.push_back({cmd->name, ""}); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - cmd = cmd->next; - } - } - void draw_input() { con.globals.font_height = static_cast(console_font->pixelHeight); @@ -718,6 +666,57 @@ namespace game_console return true; } + bool match_compare(const std::string& input, const std::string& text, const bool exact) + { + if (exact && text == input) return true; + if (!exact && text.find(input) != std::string::npos) return true; + return false; + } + + void find_matches(std::string input, std::vector& suggestions, const bool exact) + { + input = utils::string::to_lower(input); + + for (const auto& dvar : dvars::dvar_list) + { + auto name = utils::string::to_lower(dvar); + if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) + { + suggestions.push_back(dvar); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) + { + suggestions.push_back(input.data()); + } + + game::cmd_function_s* cmd = (*game::cmd_functions); + while (cmd) + { + if (cmd->name) + { + std::string name = utils::string::to_lower(cmd->name); + + if (game_console::match_compare(input, name, exact)) + { + suggestions.push_back(cmd->name); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + cmd = cmd->next; + } + } class component final : public component_interface { diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp index cdc001a7..e0b64753 100644 --- a/src/client/component/game_console.hpp +++ b/src/client/component/game_console.hpp @@ -4,4 +4,7 @@ namespace game_console { bool console_char_event(int local_client_num, int key); bool console_key_event(int local_client_num, int key, int down); -} \ No newline at end of file + + bool match_compare(const std::string& input, const std::string& text, const bool exact); + void find_matches(std::string input, std::vector& suggestions, const bool exact); +} diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 9118b37c..bfabfd0d 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -82,6 +82,12 @@ namespace game WEAK symbol G_Glass_Update{0x14026C570, 0x14033A640}; WEAK symbol G_GetClientScore{0, 0x140342F90}; + WEAK symbol G_GetWeaponForName{0x1402C2A90, 0x14038C300}; + WEAK symbol G_GivePlayerWeapon{0x1402C2DF0, 0x14038C750}; + WEAK symbol G_InitializeAmmo{0x140270980, 0x14033EDD0}; + WEAK symbol G_SelectWeapon{0x1402C3750, 0x14038D1B0}; + WEAK symbol G_TakePlayerWeapon{0x1402C3900, 0x14038D370}; WEAK symbol I_CleanStr{0x1403CD230, 0x140503D00}; @@ -128,6 +134,9 @@ namespace game WEAK symbol ScrPlace_GetViewPlacement{0x1401981F0, 0x140288550}; + WEAK symbol + DB_EnumXAssets_Internal{0x1401C9C10, 0x1402BA830}; + WEAK symbol DB_GetXAssetName{0x14019A390, 0x14028BE50}; WEAK symbol DB_GetXAssetTypeSize{0x14019A3B0, 0x14028BE70}; WEAK symbol dvarPool{0x14C217D20, 0x14D064D00}; WEAK symbol DB_XAssetPool{0x140DE8C80, 0x140FEB5D0}; + WEAK symbol g_assetNames{0x1408B0870, 0x140FEA240}; WEAK symbol keyCatchers{0x14243DAF0, 0x142D0BA9C}; WEAK symbol playerKeys{0x1422A873C, 0x142C19AFC}; From aca747e5d9bbb9105fd8675ad5baed7c4485698c Mon Sep 17 00:00:00 2001 From: m Date: Sun, 13 Mar 2022 07:59:35 -0500 Subject: [PATCH 082/346] small fix --- src/client/component/game_console.cpp | 10 +++++----- src/client/component/game_console.hpp | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 913b412b..1e5ce400 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -673,13 +673,13 @@ namespace game_console return false; } - void find_matches(std::string input, std::vector& suggestions, const bool exact) + void find_matches(std::string input, std::vector& suggestions, const bool exact) { input = utils::string::to_lower(input); for (const auto& dvar : dvars::dvar_list) { - auto name = utils::string::to_lower(dvar); + auto name = utils::string::to_lower(dvar.name); if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) { suggestions.push_back(dvar); @@ -693,7 +693,7 @@ namespace game_console if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) { - suggestions.push_back(input.data()); + suggestions.push_back({ input.data(), "" }); } game::cmd_function_s* cmd = (*game::cmd_functions); @@ -703,9 +703,9 @@ namespace game_console { std::string name = utils::string::to_lower(cmd->name); - if (game_console::match_compare(input, name, exact)) + if (match_compare(input, name, exact)) { - suggestions.push_back(cmd->name); + suggestions.push_back({ cmd->name, "" }); } if (exact && suggestions.size() > 1) diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp index e0b64753..0e5a1ca1 100644 --- a/src/client/component/game_console.hpp +++ b/src/client/component/game_console.hpp @@ -1,4 +1,5 @@ #pragma once +#include "game/dvars.hpp" namespace game_console { @@ -6,5 +7,5 @@ namespace game_console bool console_key_event(int local_client_num, int key, int down); bool match_compare(const std::string& input, const std::string& text, const bool exact); - void find_matches(std::string input, std::vector& suggestions, const bool exact); + void find_matches(std::string input, std::vector& suggestions, const bool exact); } From 39fa6db1fb9e9e50c91a5be06be24696f8fc2ea3 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 15:26:37 +0100 Subject: [PATCH 083/346] Fix --- src/client/component/game_console.cpp | 103 +++++++++++++------------- src/client/component/game_console.hpp | 6 +- 2 files changed, 53 insertions(+), 56 deletions(-) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 1e5ce400..deec2813 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -177,6 +177,58 @@ namespace game_console game::R_AddCmdDrawText(text, 0x7FFFFFFF, console_font, con.globals.x + offset_x, _y, 1.0f, 1.0f, 0.0f, color, 0); } + bool match_compare(const std::string& input, const std::string& text, const bool exact) + { + if (exact && text == input) return true; + if (!exact && text.find(input) != std::string::npos) return true; + return false; + } + + void find_matches(std::string input, std::vector& suggestions, const bool exact) + { + input = utils::string::to_lower(input); + + for (const auto& dvar : dvars::dvar_list) + { + auto name = utils::string::to_lower(dvar.name); + if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) + { + suggestions.push_back(dvar); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) + { + suggestions.push_back({input.data(), ""}); + } + + game::cmd_function_s* cmd = (*game::cmd_functions); + while (cmd) + { + if (cmd->name) + { + std::string name = utils::string::to_lower(cmd->name); + + if (match_compare(input, name, exact)) + { + suggestions.push_back({cmd->name, ""}); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + cmd = cmd->next; + } + } + void draw_input() { con.globals.font_height = static_cast(console_font->pixelHeight); @@ -666,57 +718,6 @@ namespace game_console return true; } - bool match_compare(const std::string& input, const std::string& text, const bool exact) - { - if (exact && text == input) return true; - if (!exact && text.find(input) != std::string::npos) return true; - return false; - } - - void find_matches(std::string input, std::vector& suggestions, const bool exact) - { - input = utils::string::to_lower(input); - - for (const auto& dvar : dvars::dvar_list) - { - auto name = utils::string::to_lower(dvar.name); - if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) - { - suggestions.push_back(dvar); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) - { - suggestions.push_back({ input.data(), "" }); - } - - game::cmd_function_s* cmd = (*game::cmd_functions); - while (cmd) - { - if (cmd->name) - { - std::string name = utils::string::to_lower(cmd->name); - - if (match_compare(input, name, exact)) - { - suggestions.push_back({ cmd->name, "" }); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - cmd = cmd->next; - } - } class component final : public component_interface { diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp index 0e5a1ca1..cdc001a7 100644 --- a/src/client/component/game_console.hpp +++ b/src/client/component/game_console.hpp @@ -1,11 +1,7 @@ #pragma once -#include "game/dvars.hpp" namespace game_console { bool console_char_event(int local_client_num, int key); bool console_key_event(int local_client_num, int key, int down); - - bool match_compare(const std::string& input, const std::string& text, const bool exact); - void find_matches(std::string input, std::vector& suggestions, const bool exact); -} +} \ No newline at end of file From 73cea1553d8b8bb67478830594dd36a73761fdf3 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 15:27:02 +0100 Subject: [PATCH 084/346] Revert "Fix" This reverts commit 39fa6db1fb9e9e50c91a5be06be24696f8fc2ea3. --- src/client/component/game_console.cpp | 103 +++++++++++++------------- src/client/component/game_console.hpp | 6 +- 2 files changed, 56 insertions(+), 53 deletions(-) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index deec2813..1e5ce400 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -177,58 +177,6 @@ namespace game_console game::R_AddCmdDrawText(text, 0x7FFFFFFF, console_font, con.globals.x + offset_x, _y, 1.0f, 1.0f, 0.0f, color, 0); } - bool match_compare(const std::string& input, const std::string& text, const bool exact) - { - if (exact && text == input) return true; - if (!exact && text.find(input) != std::string::npos) return true; - return false; - } - - void find_matches(std::string input, std::vector& suggestions, const bool exact) - { - input = utils::string::to_lower(input); - - for (const auto& dvar : dvars::dvar_list) - { - auto name = utils::string::to_lower(dvar.name); - if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) - { - suggestions.push_back(dvar); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) - { - suggestions.push_back({input.data(), ""}); - } - - game::cmd_function_s* cmd = (*game::cmd_functions); - while (cmd) - { - if (cmd->name) - { - std::string name = utils::string::to_lower(cmd->name); - - if (match_compare(input, name, exact)) - { - suggestions.push_back({cmd->name, ""}); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - cmd = cmd->next; - } - } - void draw_input() { con.globals.font_height = static_cast(console_font->pixelHeight); @@ -718,6 +666,57 @@ namespace game_console return true; } + bool match_compare(const std::string& input, const std::string& text, const bool exact) + { + if (exact && text == input) return true; + if (!exact && text.find(input) != std::string::npos) return true; + return false; + } + + void find_matches(std::string input, std::vector& suggestions, const bool exact) + { + input = utils::string::to_lower(input); + + for (const auto& dvar : dvars::dvar_list) + { + auto name = utils::string::to_lower(dvar.name); + if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) + { + suggestions.push_back(dvar); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) + { + suggestions.push_back({ input.data(), "" }); + } + + game::cmd_function_s* cmd = (*game::cmd_functions); + while (cmd) + { + if (cmd->name) + { + std::string name = utils::string::to_lower(cmd->name); + + if (match_compare(input, name, exact)) + { + suggestions.push_back({ cmd->name, "" }); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + cmd = cmd->next; + } + } class component final : public component_interface { diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp index cdc001a7..0e5a1ca1 100644 --- a/src/client/component/game_console.hpp +++ b/src/client/component/game_console.hpp @@ -1,7 +1,11 @@ #pragma once +#include "game/dvars.hpp" namespace game_console { bool console_char_event(int local_client_num, int key); bool console_key_event(int local_client_num, int key, int down); -} \ No newline at end of file + + bool match_compare(const std::string& input, const std::string& text, const bool exact); + void find_matches(std::string input, std::vector& suggestions, const bool exact); +} From 88c55dff72ad4ad9207d9ab119a1724f1cf6abc3 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 15:31:57 +0100 Subject: [PATCH 085/346] Move stuff --- src/client/component/command.cpp | 14 +--- src/client/component/fastfiles.cpp | 10 +++ src/client/component/fastfiles.hpp | 3 + src/client/component/game_console.cpp | 97 +++++++++++++-------------- src/client/component/game_console.hpp | 6 +- src/common/utils/string.cpp | 7 ++ src/common/utils/string.hpp | 2 + 7 files changed, 71 insertions(+), 68 deletions(-) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 28600228..63b66724 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -4,6 +4,7 @@ #include "command.hpp" #include "console.hpp" #include "game_console.hpp" +#include "fastfiles.hpp" #include "game/game.hpp" #include "game/dvars.hpp" @@ -277,15 +278,6 @@ namespace command } } - void enum_assets(const game::XAssetType type, const std::function& callback, const bool includeOverride) - { - game::DB_EnumXAssets_Internal(type, static_cast([](game::XAssetHeader header, void* data) - { - const auto& cb = *static_cast*>(data); - cb(header); - }), &callback, includeOverride); - } - class component final : public component_interface { public: @@ -372,14 +364,14 @@ namespace command console::info("Listing assets in pool %s\n", game::g_assetNames[type]); const std::string filter = params.get(2); - enum_assets(type, [type, filter](const game::XAssetHeader header) + fastfiles::enum_assets(type, [type, filter](const game::XAssetHeader header) { const auto asset = game::XAsset{type, header}; const auto* const asset_name = game::DB_GetXAssetName(&asset); //const auto entry = game::DB_FindXAssetEntry(type, asset_name); //TODO: display which zone the asset is from - if (!filter.empty() && !game_console::match_compare(filter, asset_name, false)) + if (!filter.empty() && !utils::string::match_compare(filter, asset_name, false)) { return; } diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index d4eda37f..22ec023c 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -35,6 +35,16 @@ namespace fastfiles }); } + void enum_assets(const game::XAssetType type, + const std::function& callback, const bool includeOverride) + { + game::DB_EnumXAssets_Internal(type, static_cast([](game::XAssetHeader header, void* data) + { + const auto& cb = *static_cast*>(data); + cb(header); + }), &callback, includeOverride); + } + class component final : public component_interface { public: diff --git a/src/client/component/fastfiles.hpp b/src/client/component/fastfiles.hpp index ac26d2ec..4f4108a0 100644 --- a/src/client/component/fastfiles.hpp +++ b/src/client/component/fastfiles.hpp @@ -5,4 +5,7 @@ namespace fastfiles { std::string get_current_fastfile(); + + void enum_assets(const game::XAssetType type, + const std::function& callback, const bool includeOverride); } diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 1e5ce400..23b63212 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -177,6 +177,51 @@ namespace game_console game::R_AddCmdDrawText(text, 0x7FFFFFFF, console_font, con.globals.x + offset_x, _y, 1.0f, 1.0f, 0.0f, color, 0); } + void find_matches(std::string input, std::vector& suggestions, const bool exact) + { + input = utils::string::to_lower(input); + + for (const auto& dvar : dvars::dvar_list) + { + auto name = utils::string::to_lower(dvar.name); + if (game::Dvar_FindVar(name.data()) && utils::string::match_compare(input, name, exact)) + { + suggestions.push_back(dvar); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) + { + suggestions.push_back({input, ""}); + } + + game::cmd_function_s* cmd = (*game::cmd_functions); + while (cmd) + { + if (cmd->name) + { + std::string name = utils::string::to_lower(cmd->name); + + if (utils::string::match_compare(input, name, exact)) + { + suggestions.push_back({cmd->name, ""}); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + cmd = cmd->next; + } + } + void draw_input() { con.globals.font_height = static_cast(console_font->pixelHeight); @@ -666,58 +711,6 @@ namespace game_console return true; } - bool match_compare(const std::string& input, const std::string& text, const bool exact) - { - if (exact && text == input) return true; - if (!exact && text.find(input) != std::string::npos) return true; - return false; - } - - void find_matches(std::string input, std::vector& suggestions, const bool exact) - { - input = utils::string::to_lower(input); - - for (const auto& dvar : dvars::dvar_list) - { - auto name = utils::string::to_lower(dvar.name); - if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) - { - suggestions.push_back(dvar); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) - { - suggestions.push_back({ input.data(), "" }); - } - - game::cmd_function_s* cmd = (*game::cmd_functions); - while (cmd) - { - if (cmd->name) - { - std::string name = utils::string::to_lower(cmd->name); - - if (match_compare(input, name, exact)) - { - suggestions.push_back({ cmd->name, "" }); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - cmd = cmd->next; - } - } - class component final : public component_interface { public: diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp index 0e5a1ca1..cdc001a7 100644 --- a/src/client/component/game_console.hpp +++ b/src/client/component/game_console.hpp @@ -1,11 +1,7 @@ #pragma once -#include "game/dvars.hpp" namespace game_console { bool console_char_event(int local_client_num, int key); bool console_key_event(int local_client_num, int key, int down); - - bool match_compare(const std::string& input, const std::string& text, const bool exact); - void find_matches(std::string input, std::vector& suggestions, const bool exact); -} +} \ No newline at end of file diff --git a/src/common/utils/string.cpp b/src/common/utils/string.cpp index 653ecff2..42486cf3 100644 --- a/src/common/utils/string.cpp +++ b/src/common/utils/string.cpp @@ -176,4 +176,11 @@ namespace utils::string return str; } + + bool match_compare(const std::string& input, const std::string& text, const bool exact) + { + if (exact && text == input) return true; + if (!exact && text.find(input) != std::string::npos) return true; + return false; + } } diff --git a/src/common/utils/string.hpp b/src/common/utils/string.hpp index 20fa4827..322ce9ce 100644 --- a/src/common/utils/string.hpp +++ b/src/common/utils/string.hpp @@ -97,4 +97,6 @@ namespace utils::string std::wstring convert(const std::string& str); std::string replace(std::string str, const std::string& from, const std::string& to); + + bool match_compare(const std::string& input, const std::string& text, const bool exact); } From 21e8d854c4e1e7004c9d38ec947479aaeaf28cad Mon Sep 17 00:00:00 2001 From: DoktorSAS <62484597+DoktorSAS@users.noreply.github.com> Date: Sun, 13 Mar 2022 18:49:22 +0100 Subject: [PATCH 086/346] Update functions table Fixed some wrong named functions added some missing one --- src/client/game/scripting/function_tables.cpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index f429aad0..134efc90 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -1088,7 +1088,7 @@ namespace scripting {"_meth_812f", 0x812F}, // SP 0x140267650 MP 0x14032B720 {"_meth_8130", 0x8130}, // SP 0x140262E20 MP 0x14032F570 {"_meth_8131", 0x8131}, // SP 0x1402684C0 MP 0x000000000 - {"_meth_8132", 0x8132}, // SP 0x140261580 MP 0x14032CD50 + {"isplanting", 0x8132}, // SP 0x140261580 MP 0x14032CD50 {"_meth_8133", 0x8133}, // SP 0x140261670 MP 0x14032CF00 {"_meth_8134", 0x8134}, // SP 0x140268530 MP 0x000000000 {"setconvergencetime", 0x8135}, // SP 0x140295E90 MP 0x140360A40 @@ -1218,9 +1218,9 @@ namespace scripting {"_meth_81b1", 0x81B1}, // SP 0x1402A15D0 MP 0x14036ADA0 {"_meth_81b2", 0x81B2}, // SP 0x1402A15D0 MP 0x14036AE60 {"viewkick", 0x81B3}, // SP 0x1402A1640 MP 0x14036AFA0 - {"_meth_81b4", 0x81B4}, // SP 0x14029B1E0 MP 0x1403668B0 + {"localtoworldcoords", 0x81B4}, // SP 0x14029B1E0 MP 0x1403668B0 {"getentitynumber", 0x81B5}, // SP 0x1402998B0 MP 0x140364980 - {"autoboltmissileeffects", 0x81B6}, // SP 0x140299AA0 MP 0x140364B50 + {"getentityvelocity", 0x81B6}, // SP 0x140299AA0 MP 0x140364B50 {"enablegrenadetouchdamage", 0x81B7}, // SP 0x140299CA0 MP 0x140364F40 {"disablegrenadetouchdamage", 0x81B8}, // SP 0x140299F20 MP 0x1403650C0 {"_meth_81b9", 0x81B9}, // SP 0x14029AF00 MP 0x1403665A0 @@ -1255,8 +1255,8 @@ namespace scripting {"_meth_81d6", 0x81D6}, // SP 0x140247930 MP 0x000000000 {"_meth_81d7", 0x81D7}, // SP 0x14029B180 MP 0x140366790 {"entityradiusdamage", 0x81D8}, // SP 0x1402A3840 MP 0x14036C130 - {"_meth_81d9", 0x81D9}, // SP 0x14028DCF0 MP 0x14036CAB0 - {"bddatachunk::deserialize", 0x81DA}, // SP 0x14028E350 MP 0x14036D0C0 + {"detonate", 0x81D9}, // SP 0x14028DCF0 MP 0x14036CAB0 + {"damageconetrace", 0x81DA}, // SP 0x14028E350 MP 0x14036D0C0 {"_meth_81db", 0x81DB}, // SP 0x14028E430 MP 0x14036D150 {"_meth_81dc", 0x81DC}, // SP 0x14029A340 MP 0x140365D80 {"_meth_81dd", 0x81DD}, // SP 0x14029A4E0 MP 0x140365E90 @@ -1475,9 +1475,9 @@ namespace scripting {"_meth_82b2", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 {"rotateyaw", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 {"_meth_82b4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 // looks similar to moveto/rotateto, wtf - {"_meth_82b5", 0x82B5}, // SP 0x1402B3410 MP 0x14037F010 - {"_meth_82b6", 0x82B6}, // SP 0x1402B3430 MP 0x14037F030 - {"_meth_82b7", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 + {"addpitch", 0x82B5}, // SP 0x1402B3410 MP 0x14037F010 + {"addyaw", 0x82B6}, // SP 0x1402B3430 MP 0x14037F030 + {"addoll", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 {"_meth_82b8", 0x82B8}, // SP 0x1402B34B0 MP 0x14037F0B0 {"rotatevelocity", 0x82B9}, // SP 0x1402B3700 MP 0x14037F3C0 {"solid", 0x82BA}, // SP 0x1402B45E0 MP 0x1403808A0 @@ -1515,7 +1515,7 @@ namespace scripting {"getbuildnumber", 0x82DA}, // SP 0x1402663A0 MP 0x14032A910 {"_meth_82db", 0x82DB}, // SP 0x140266AF0 MP 0x14032AE90 {"_meth_82dc", 0x82DC}, // SP 0x140266CD0 MP 0x14032B120 - {"_meth_82dd", 0x82DD}, // SP 0x140266FE0 MP 0x14032B500 + {"ismantling", 0x82DD}, // SP 0x140266FE0 MP 0x14032B500 {"playfx", 0x82DE}, // SP 0x140267330 MP 0x14032B9F0 {"playerrecoilscaleon", 0x82DF}, // SP 0x140267530 MP 0x14032BD00 {"player_recoilscaleoff", 0x82E0}, // SP 0x140267600 MP 0x14032BDD0 @@ -1606,8 +1606,8 @@ namespace scripting {"setorigin", 0x8335}, // SP 0x1402677C0 MP 0x14032B8D0 {"getvelocity", 0x8336}, // SP 0x1402604D0 MP 0x14032BC80 {"_meth_8337", 0x8337}, // SP 0x140260930 MP 0x14032BE70 - {"forcemantle", 0x8338}, // SP 0x140260990 MP 0x14032C0D0 - {"attackbuttonpressed", 0x8339}, // SP 0x140261500 MP 0x14032CE10 + {"getplayerangles", 0x8338}, // SP 0x140260990 MP 0x14032C0D0 + {"usebuttonpressed", 0x8339}, // SP 0x140261500 MP 0x14032CE10 {"_meth_833a", 0x833A}, // SP 0x1402615F0 MP 0x14032D0B0 {"meleebuttonpressed", 0x833B}, // SP 0x1402617D0 MP 0x14032D1B0 {"jumpbuttonpressed", 0x833C}, // SP 0x1402618D0 MP 0x14032D450 @@ -1679,7 +1679,7 @@ namespace scripting {"_meth_837e", 0x837E}, // SP 0x000000000 MP 0x1404791D0 {"getnodenumber", 0x837F}, // SP 0x000000000 MP 0x14032E760 {"setclientowner", 0x8380}, // SP 0x000000000 MP 0x14037AD60 - {"_meth_8381", 0x8381}, // SP 0x000000000 MP 0x14037A3B0 + {"setotherent", 0x8381}, // SP 0x000000000 MP 0x14037A3B0 {"setaisightlinevisible", 0x8382}, // SP 0x1402A15D0 MP 0x140358460 {"setentityowner", 0x8383}, // SP 0x000000000 MP 0x14037A980 {"nodeisdisconnected", 0x8384}, // SP 0x000000000 MP 0x14032E920 @@ -1697,7 +1697,7 @@ namespace scripting {"setgoalnode", 0x8390}, // SP 0x000000000 MP 0x140450090 {"setgoalentity", 0x8391}, // SP 0x000000000 MP 0x140450000 {"setgoalradius", 0x8392}, // SP 0x000000000 MP 0x140450260 - {"_meth_8393", 0x8393}, // SP 0x000000000 MP 0x14044FEC0 + {"scragentsetanimscale", 0x8393}, // SP 0x000000000 MP 0x14044FEC0 {"setorientmode", 0x8394}, // SP 0x000000000 MP 0x140450540 {"setanimmode", 0x8395}, // SP 0x000000000 MP 0x14044FDA0 {"setphysicsmode", 0x8396}, // SP 0x000000000 MP 0x140450780 @@ -1758,7 +1758,7 @@ namespace scripting {"_meth_83cd", 0x83CD}, // SP 0x14024B7A0 MP 0x000000000 {"setanimclass", 0x83CE}, // SP 0x000000000 MP 0x1400781E0 {"enableanimstate", 0x83CF}, // SP 0x000000000 MP 0x140077CB0 - {"_meth_83d0", 0x83D0}, // SP 0x000000000 MP 0x140078250 + {"setanimstate", 0x83D0}, // SP 0x000000000 MP 0x140078250 {"getanimentry", 0x83D1}, // SP 0x000000000 MP 0x140077DF0 {"getanimentryname", 0x83D2}, // SP 0x000000000 MP 0x140077FA0 {"getanimentryalias", 0x83D3}, // SP 0x000000000 MP 0x140077E80 @@ -1774,10 +1774,10 @@ namespace scripting {"rotateto", 0x83DD}, // SP 0x1402B3200 MP 0x14037EF90 {"getlookaheaddir", 0x83DE}, // SP 0x000000000 MP 0x14044F710 {"getpathgoalpos", 0x83DF}, // SP 0x000000000 MP 0x14044FAD0 - {"_meth_83e0", 0x83E0}, // SP 0x1402A15D0 MP 0x14036E1F0 + {"setrocketcorpse", 0x83E0}, // SP 0x1402A15D0 MP 0x14036E1F0 {"setcorpsefalling", 0x83E1}, // SP 0x000000000 MP 0x140374840 {"setsurfacetype", 0x83E2}, // SP 0x14029FD00 MP 0x140358090 - {"_meth_83e3", 0x83E3}, // SP 0x1402A0C60 MP 0x140369520 + {"aIiphysicstrace", 0x83E3}, // SP 0x1402A0C60 MP 0x140369520 {"_meth_83e4", 0x83E4}, // SP 0x1402A20D0 MP 0x140369FE0 {"_meth_83e5", 0x83E5}, // SP 0x1405D92F0 MP 0x14033B020 {"_meth_83e6", 0x83E6}, // SP 0x1402A7B00 MP 0x000000000 @@ -1872,7 +1872,7 @@ namespace scripting {"_meth_843f", 0x843F}, // SP 0x1405D92F0 MP 0x14032D4E0 {"_meth_8440", 0x8440}, // SP 0x1404639C0 MP 0x140562210 {"_meth_8441", 0x8441}, // SP 0x140462EA0 MP 0x1405616E0 - {"_meth_8442", 0x8442}, // SP 0x1402A36A0 MP 0x140358B60 + {"linkto", 0x8442}, // SP 0x1402A36A0 MP 0x140358B60 {"_meth_8443", 0x8443}, // SP 0x140266090 MP 0x14032A550 {"_meth_8444", 0x8444}, // SP 0x1402A8A40 MP 0x000000000 {"_meth_8445", 0x8445}, // SP 0x1402A8A80 MP 0x000000000 From c5b5a9336062303ba1cf8d9a582d4bac44d58107 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 21:01:29 +0100 Subject: [PATCH 087/346] Add more commands + fixes --- src/client/component/command.cpp | 392 +++++++++++++----- src/client/component/command.hpp | 2 + src/client/game/scripting/array.cpp | 335 +++++++++++++++ src/client/game/scripting/array.hpp | 87 ++++ src/client/game/scripting/execution.cpp | 11 + src/client/game/scripting/execution.hpp | 3 + src/client/game/scripting/function_tables.cpp | 28 +- .../game/scripting/lua/value_conversion.cpp | 4 +- src/client/game/scripting/script_value.cpp | 19 +- src/client/game/scripting/script_value.hpp | 5 +- src/client/game/structs.hpp | 72 ++-- src/client/game/symbols.hpp | 18 +- 12 files changed, 814 insertions(+), 162 deletions(-) create mode 100644 src/client/game/scripting/array.cpp create mode 100644 src/client/game/scripting/array.hpp diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 63b66724..32e7fa0a 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -5,10 +5,13 @@ #include "console.hpp" #include "game_console.hpp" #include "fastfiles.hpp" +#include "scheduler.hpp" #include "game/game.hpp" #include "game/dvars.hpp" +#include "game/scripting/execution.hpp" + #include #include #include @@ -134,6 +137,202 @@ namespace command return 0; } + + void client_println(int client_num, const std::string& text) + { + if (game::environment::is_sp()) + { + game::CG_GameMessage(0, text.data()); + } + else + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + utils::string::va("f \"%s\"", text.data())); + } + } + + bool check_cheats(int client_num) + { + if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + { + client_println(client_num, "Cheats are not enabled on this server"); + return false; + } + + return true; + } + + void cmd_give_weapon(const int client_num, const std::vector& params) + { + if (params.size() < 2) + { + client_println(client_num, "You did not specify a weapon name"); + return; + } + + try + { + const auto arg = params[1]; + const scripting::entity player = scripting::call("getentbynum", {client_num}).as(); + auto ps = game::SV_GetPlayerstateForClientNum(client_num); + + if (arg == "ammo") + { + const auto weapon = player.call("getcurrentweapon").as(); + player.call("givemaxammo", {weapon}); + } + else if (arg == "allammo") + { + const auto weapons = player.call("getweaponslistall").as(); + for (auto i = 0; i < weapons.size(); i++) + { + player.call("givemaxammo", {weapons[i]}); + } + } + else if (arg == "health") + { + if (params.size() > 2) + { + const auto amount = atoi(params[2].data()); + const auto health = player.get("health").as(); + player.set("health", {health + amount}); + } + else + { + const auto amount = SELECT_VALUE( + game::Dvar_FindVar("g_player_maxhealth")->current.integer, + atoi(game::Dvar_FindVar("scr_player_maxhealth")->current.string) + ); + player.set("health", {amount}); + } + } + else if (arg == "all") + { + const auto type = game::XAssetType::ASSET_TYPE_WEAPON; + fastfiles::enum_assets(type, [&player, type](const game::XAssetHeader header) + { + const auto asset = game::XAsset{type, header}; + const auto asset_name = game::DB_GetXAssetName(&asset); + + player.call("giveweapon", {asset_name}); + }, true); + } + else + { + const auto wp = game::G_GetWeaponForName(arg.data()); + if (wp) + { + if (game::G_GivePlayerWeapon(ps, wp, 0, 0, 0, 0, 0, 0)) + { + game::G_InitializeAmmo(ps, wp, 0); + game::G_SelectWeapon(0, wp); + } + } + else + { + client_println(client_num, "Weapon does not exist"); + } + } + } + catch (...) + { + } + } + + void cmd_drop_weapon(int client_num) + { + try + { + const scripting::entity player = scripting::call("getentbynum", {client_num}).as(); + const auto weapon = player.call("getcurrentweapon"); + player.call("dropitem", {weapon}); + } + catch (...) + { + } + } + + void cmd_take_weapon(int client_num, const std::vector& params) + { + if (params.size() < 2) + { + client_println(client_num, "You did not specify a weapon name"); + return; + } + + const auto& weapon = params[1]; + + try + { + const scripting::entity player = scripting::call("getentbynum", {client_num}).as(); + if (weapon == "all"s) + { + player.call("takeallweapons"); + } + else + { + player.call("takeweapon", {weapon}); + } + } + catch (...) + { + } + } + + void cmd_kill(int client_num) + { + scheduler::once([client_num]() + { + try + { + const scripting::entity player = scripting::call("getentbynum", {client_num}).as(); + player.call(SELECT_VALUE("kill", "suicide")); + } + catch (...) + { + } + }, scheduler::pipeline::server); + } + + void toggle_entity_flag(int client_num, int value, const std::string& name) + { + game::mp::g_entities[client_num].flags ^= value; + client_println(client_num, utils::string::va("%s %s", + name.data(), + game::mp::g_entities[client_num].flags & value + ? "^2on" + : "^1off")); + } + + void toggle_entity_flag(int value, const std::string& name) + { + game::sp::g_entities[0].flags ^= value; + client_println(0, utils::string::va("%s %s", + name.data(), + game::sp::g_entities[0].flags & value + ? "^2on" + : "^1off")); + } + + void toggle_client_flag(int client_num, int value, const std::string& name) + { + game::mp::g_entities[client_num].client->flags ^= value; + client_println(client_num, utils::string::va("%s %s", + name.data(), + game::mp::g_entities[client_num].client->flags & value + ? "^2on" + : "^1off")); + } + + void toggle_client_flag(int value, const std::string& name) + { + game::sp::g_entities[0].client->flags ^= value; + client_println(0, utils::string::va("%s %s", + name.data(), + game::sp::g_entities[0].client->flags & value + ? "^2on" + : "^1off")); + } } void read_startup_variable(const std::string& dvar) @@ -141,8 +340,8 @@ namespace command // parse the commandline if it's not parsed parse_command_line(); - auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); //H1(1.4) - auto* com_console_lines = reinterpret_cast(0x142623FC0); //H1(1.4) + auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); + auto* com_console_lines = reinterpret_cast(0x142623FC0); for (int i = 0; i < com_num_console_lines; i++) { @@ -190,6 +389,16 @@ namespace command return result; } + std::vector params::get_all() const + { + std::vector params_; + for (auto i = 0; i < this->size(); i++) + { + params_.push_back(this->get(i)); + } + return params_; + } + params_sv::params_sv() : nesting_(game::sv_cmd_args->nesting) { @@ -222,6 +431,16 @@ namespace command return result; } + std::vector params_sv::get_all() const + { + std::vector params_; + for (auto i = 0; i < this->size(); i++) + { + params_.push_back(this->get(i)); + } + return params_; + } + void add_raw(const char* name, void (*callback)()) { game::Cmd_AddCommandInternal(name, callback, utils::memory::get_allocator()->allocate()); @@ -418,11 +637,7 @@ namespace command return; } - game::sp::g_entities[0].flags ^= 1; - game::CG_GameMessage(0, utils::string::va("godmode %s", - game::sp::g_entities[0].flags & 1 - ? "^2on" - : "^1off")); + toggle_entity_flag(1, "godmode"); }); add("demigod", []() @@ -432,11 +647,7 @@ namespace command return; } - game::sp::g_entities[0].flags ^= 2; - game::CG_GameMessage(0, utils::string::va("demigod mode %s", - game::sp::g_entities[0].flags & 2 - ? "^2on" - : "^1off")); + toggle_entity_flag(2, "demigod mode"); }); add("notarget", []() @@ -446,11 +657,7 @@ namespace command return; } - game::sp::g_entities[0].flags ^= 4; - game::CG_GameMessage(0, utils::string::va("notarget %s", - game::sp::g_entities[0].flags & 4 - ? "^2on" - : "^1off")); + toggle_entity_flag(4, "notarget"); }); add("noclip", []() @@ -460,11 +667,7 @@ namespace command return; } - game::sp::g_entities[0].client->flags ^= 1; - game::CG_GameMessage(0, utils::string::va("noclip %s", - game::sp::g_entities[0].client->flags & 1 - ? "^2on" - : "^1off")); + toggle_client_flag(1, "noclip"); }); add("ufo", []() @@ -474,11 +677,47 @@ namespace command return; } - game::sp::g_entities[0].client->flags ^= 2; - game::CG_GameMessage(0, utils::string::va("ufo %s", - game::sp::g_entities[0].client->flags & 2 - ? "^2on" - : "^1off")); + toggle_client_flag(2, "ufo"); + }); + + add("give", [](const params& params) + { + if (!game::SV_Loaded()) + { + return; + } + + cmd_give_weapon(0, params.get_all()); + }); + + add("dropweapon", [](const params& params) + { + if (!game::SV_Loaded()) + { + return; + } + + cmd_drop_weapon(0); + }); + + add("take", [](const params& params) + { + if (!game::SV_Loaded()) + { + return; + } + + cmd_take_weapon(0, params.get_all()); + }); + + add("kill", [](const params& params) + { + if (!game::SV_Loaded()) + { + return; + } + + cmd_kill(0); }); } @@ -488,139 +727,92 @@ namespace command add_sv("god", [](const int client_num, const params_sv&) { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + if (!check_cheats(client_num)) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); return; } - game::mp::g_entities[client_num].flags ^= 1; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"godmode %s\"", - game::mp::g_entities[client_num].flags & 1 - ? "^2on" - : "^1off")); + toggle_entity_flag(client_num, 1, "godmode"); }); add_sv("demigod", [](const int client_num, const params_sv&) { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + if (!check_cheats(client_num)) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); return; } - game::mp::g_entities[client_num].flags ^= 2; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"demigod mode %s\"", - game::mp::g_entities[client_num].flags & 2 - ? "^2on" - : "^1off")); + toggle_entity_flag(client_num, 2, "demigod mode"); }); add_sv("notarget", [](const int client_num, const params_sv&) { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + if (!check_cheats(client_num)) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); return; } - game::mp::g_entities[client_num].flags ^= 4; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"notarget %s\"", - game::mp::g_entities[client_num].flags & 4 - ? "^2on" - : "^1off")); + toggle_entity_flag(client_num, 4, "notarget"); }); add_sv("noclip", [](const int client_num, const params_sv&) { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + if (!check_cheats(client_num)) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); return; } - game::mp::g_entities[client_num].client->flags ^= 1; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"noclip %s\"", - game::mp::g_entities[client_num].client->flags & 1 - ? "^2on" - : "^1off")); + toggle_client_flag(client_num, 1, "noclip"); }); add_sv("ufo", [](const int client_num, const params_sv&) { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + if (!check_cheats(client_num)) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); return; } - game::mp::g_entities[client_num].client->flags ^= 2; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"ufo %s\"", - game::mp::g_entities[client_num].client->flags & 2 - ? "^2on" - : "^1off")); + toggle_client_flag(client_num, 2, "noclip"); }); add_sv("give", [](const int client_num, const params_sv& params) { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + if (!check_cheats(client_num)) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); return; } - if (params.size() < 2) + cmd_give_weapon(client_num, params.get_all()); + }); + + add_sv("dropweapon", [](const int client_num, const params_sv& params) + { + if (!check_cheats(client_num)) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"You did not specify a weapon name\""); return; } - auto ps = game::SV_GetPlayerstateForClientNum(client_num); - const auto wp = game::G_GetWeaponForName(params.get(1)); - if (wp) - { - if (game::G_GivePlayerWeapon(ps, wp, 0, 0, 0, 0, 0, 0)) - { - game::G_InitializeAmmo(ps, wp, 0); - game::G_SelectWeapon(client_num, wp); - } - } + cmd_drop_weapon(client_num); }); add_sv("take", [](const int client_num, const params_sv& params) { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + if (!check_cheats(client_num)) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); return; } - if (params.size() < 2) + cmd_take_weapon(client_num, params.get_all()); + }); + + add_sv("kill", [](const int client_num, const params_sv& params) + { + if (!check_cheats(client_num)) { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"You did not specify a weapon name\""); return; } - auto ps = game::SV_GetPlayerstateForClientNum(client_num); - const auto wp = game::G_GetWeaponForName(params.get(1)); - if (wp) - { - game::G_TakePlayerWeapon(ps, wp); - } + cmd_kill(client_num); }); } }; diff --git a/src/client/component/command.hpp b/src/client/component/command.hpp index bd70d0c6..06228c9d 100644 --- a/src/client/component/command.hpp +++ b/src/client/component/command.hpp @@ -10,6 +10,7 @@ namespace command int size() const; const char* get(int index) const; std::string join(int index) const; + std::vector get_all() const; const char* operator[](const int index) const { @@ -28,6 +29,7 @@ namespace command int size() const; const char* get(int index) const; std::string join(int index) const; + std::vector get_all() const; const char* operator[](const int index) const { diff --git a/src/client/game/scripting/array.cpp b/src/client/game/scripting/array.cpp new file mode 100644 index 00000000..33164bd9 --- /dev/null +++ b/src/client/game/scripting/array.cpp @@ -0,0 +1,335 @@ +#include +#include "array.hpp" +#include "script_value.hpp" +#include "execution.hpp" + +namespace scripting +{ + array_value::array_value(unsigned int parent_id, unsigned int id) + : id_(id) + , parent_id_(parent_id) + { + if (!this->id_) + { + return; + } + + const auto value = game::scr_VarGlob->childVariableValue[this->id_ + 0xFA00 * (this->parent_id_ & 3)]; + game::VariableValue variable; + variable.u = value.u.u; + variable.type = (game::scriptType_e)value.type; + + this->value_ = variable; + } + + void array_value::operator=(const script_value& _value) + { + if (!this->id_) + { + return; + } + + const auto value = _value.get_raw(); + + const auto variable = &game::scr_VarGlob->childVariableValue[this->id_ + 0xFA00 * (this->parent_id_ & 3)]; + game::AddRefToValue(value.type, value.u); + game::RemoveRefToValue(variable->type, variable->u.u); + + variable->type = (char)value.type; + variable->u.u = value.u; + + this->value_ = value; + } + + array::array(const unsigned int id) + : id_(id) + { + this->add(); + } + + array::array(const array& other) : array(other.id_) + { + } + + array::array(array&& other) noexcept + { + this->id_ = other.id_; + other.id_ = 0; + } + + array::array() + { + this->id_ = make_array(); + } + + array::array(std::vector values) + { + this->id_ = make_array(); + + for (const auto& value : values) + { + this->push(value); + } + } + + array::array(std::unordered_map values) + { + this->id_ = make_array(); + + for (const auto& value : values) + { + this->set(value.first, value.second); + } + } + + array::~array() + { + this->release(); + } + + array& array::operator=(const array& other) + { + if (&other != this) + { + this->release(); + this->id_ = other.id_; + this->add(); + } + + return *this; + } + + array& array::operator=(array&& other) noexcept + { + if (&other != this) + { + this->release(); + this->id_ = other.id_; + other.id_ = 0; + } + + return *this; + } + + void array::add() const + { + if (this->id_) + { + game::AddRefToValue(game::SCRIPT_OBJECT, {static_cast(this->id_)}); + } + } + + void array::release() const + { + if (this->id_) + { + game::RemoveRefToValue(game::SCRIPT_OBJECT, {static_cast(this->id_)}); + } + } + + std::vector array::get_keys() const + { + std::vector result; + + const auto offset = 0xFA00 * (this->id_ & 3); + auto current = game::scr_VarGlob->objectVariableChildren[this->id_].firstChild; + + for (auto i = offset + current; current; i = offset + current) + { + const auto var = game::scr_VarGlob->childVariableValue[i]; + + if (var.type == game::SCRIPT_NONE) + { + current = var.nextSibling; + continue; + } + + const auto string_value = (game::scr_string_t)((unsigned __int8)var.name_lo + (var.k.keys.name_hi << 8)); + const auto* str = game::SL_ConvertToString(string_value); + + script_value key; + if (string_value < 0x40000 && str) + { + key = str; + } + else + { + key = (string_value - 0x800000) & 0xFFFFFF; + } + + result.push_back(key); + + current = var.nextSibling; + } + + return result; + } + + int array::size() const + { + return static_cast(game::scr_VarGlob->objectVariableValue[this->id_].u.f.next); + } + + unsigned int array::push(script_value value) const + { + this->set(this->size(), value); + return this->size(); + } + + void array::erase(const unsigned int index) const + { + const auto variable_id = game::FindVariable(this->id_, (index - 0x800000) & 0xFFFFFF); + if (variable_id) + { + game::RemoveVariableValue(this->id_, variable_id); + } + } + + void array::erase(const std::string& key) const + { + const auto string_value = game::SL_GetString(key.data(), 0); + const auto variable_id = game::FindVariable(this->id_, string_value); + if (variable_id) + { + game::RemoveVariableValue(this->id_, variable_id); + } + } + + script_value array::pop() const + { + const auto value = this->get(this->size() - 1); + this->erase(this->size() - 1); + return value; + } + + script_value array::get(const script_value& key) const + { + if (key.is()) + { + return this->get(key.as()); + } + else + { + return this->get(key.as()); + } + } + + script_value array::get(const std::string& key) const + { + const auto string_value = game::SL_GetString(key.data(), 0); + const auto variable_id = game::FindVariable(this->id_, string_value); + + if (!variable_id) + { + return {}; + } + + const auto value = game::scr_VarGlob->childVariableValue[variable_id + 0xFA00 * (this->id_ & 3)]; + game::VariableValue variable; + variable.u = value.u.u; + variable.type = (game::scriptType_e)value.type; + + return variable; + } + + script_value array::get(const unsigned int index) const + { + const auto variable_id = game::FindVariable(this->id_, (index - 0x800000) & 0xFFFFFF); + + if (!variable_id) + { + return {}; + } + + const auto value = game::scr_VarGlob->childVariableValue[variable_id + 0xFA00 * (this->id_ & 3)]; + game::VariableValue variable; + variable.u = value.u.u; + variable.type = (game::scriptType_e)value.type; + + return variable; + } + + void array::set(const script_value& key, const script_value& value) const + { + if (key.is()) + { + this->set(key.as(), value); + } + else + { + this->set(key.as(), value); + } + } + + void array::set(const std::string& key, const script_value& _value) const + { + const auto value = _value.get_raw(); + const auto variable_id = this->get_value_id(key); + + if (!variable_id) + { + return; + } + + const auto variable = &game::scr_VarGlob->childVariableValue[variable_id + 0xFA00 * (this->id_ & 3)]; + + game::AddRefToValue(value.type, value.u); + game::RemoveRefToValue(variable->type, variable->u.u); + + variable->type = (char)value.type; + variable->u.u = value.u; + } + + void array::set(const unsigned int index, const script_value& _value) const + { + const auto value = _value.get_raw(); + const auto variable_id = this->get_value_id(index); + + if (!variable_id) + { + return; + } + + const auto variable = &game::scr_VarGlob->childVariableValue[variable_id + 0xFA00 * (this->id_ & 3)]; + + game::AddRefToValue(value.type, value.u); + game::RemoveRefToValue(variable->type, variable->u.u); + + variable->type = (char)value.type; + variable->u.u = value.u; + } + + unsigned int array::get_entity_id() const + { + return this->id_; + } + + unsigned int array::get_value_id(const std::string& key) const + { + const auto string_value = game::SL_GetString(key.data(), 0); + const auto variable_id = game::FindVariable(this->id_, string_value); + + if (!variable_id) + { + return game::GetNewVariable(this->id_, string_value); + } + + return variable_id; + } + + unsigned int array::get_value_id(const unsigned int index) const + { + const auto variable_id = game::FindVariable(this->id_, (index - 0x800000) & 0xFFFFFF); + if (!variable_id) + { + return game::GetNewArrayVariable(this->id_, index); + } + + return variable_id; + } + + entity array::get_raw() const + { + return entity(this->id_); + } +} diff --git a/src/client/game/scripting/array.hpp b/src/client/game/scripting/array.hpp new file mode 100644 index 00000000..e78ace3b --- /dev/null +++ b/src/client/game/scripting/array.hpp @@ -0,0 +1,87 @@ +#pragma once +#include "game/game.hpp" +#include "script_value.hpp" + +namespace scripting +{ + class array_value : public script_value + { + public: + array_value(unsigned int, unsigned int); + void operator=(const script_value&); + private: + unsigned int id_; + unsigned int parent_id_; + }; + + class array final + { + public: + array(); + array(const unsigned int); + + array(std::vector); + array(std::unordered_map); + + array(const array& other); + array(array&& other) noexcept; + + ~array(); + + array& operator=(const array& other); + array& operator=(array&& other) noexcept; + + std::vector get_keys() const; + int size() const; + + unsigned int push(script_value) const; + void erase(const unsigned int) const; + void erase(const std::string&) const; + script_value pop() const; + + script_value get(const script_value&) const; + script_value get(const std::string&) const; + script_value get(const unsigned int) const; + + void set(const script_value&, const script_value&) const; + void set(const std::string&, const script_value&) const; + void set(const unsigned int, const script_value&) const; + + unsigned int get_entity_id() const; + + unsigned int get_value_id(const std::string&) const; + unsigned int get_value_id(const unsigned int) const; + + entity get_raw() const; + + array_value operator[](const int index) const + { + return {this->id_, this->get_value_id(index)}; + } + + array_value operator[](const std::string& key) const + { + return {this->id_, this->get_value_id(key)}; + } + + template + array_value operator[](const script_value& key) const + { + if (key.is()) + { + return { this->id_, this->get_value_id(key.as()) }; + } + + if (key.is()) + { + return { this->id_, this->get_value_id(key.as()) }; + } + } + + private: + void add() const; + void release() const; + + unsigned int id_; + }; +} diff --git a/src/client/game/scripting/execution.cpp b/src/client/game/scripting/execution.cpp index 29faaad4..273b4f7a 100644 --- a/src/client/game/scripting/execution.cpp +++ b/src/client/game/scripting/execution.cpp @@ -237,4 +237,15 @@ namespace scripting // Add custom fields return get_custom_field(entity, field); } + + unsigned int make_array() + { + unsigned int index = 0; + const auto variable = game::AllocVariable(&index); + variable->w.type = game::SCRIPT_ARRAY; + variable->u.f.prev = 0; + variable->u.f.next = 0; + + return index; + } } diff --git a/src/client/game/scripting/execution.hpp b/src/client/game/scripting/execution.hpp index 7fff1840..94a2678d 100644 --- a/src/client/game/scripting/execution.hpp +++ b/src/client/game/scripting/execution.hpp @@ -1,6 +1,7 @@ #pragma once #include "game/game.hpp" #include "entity.hpp" +#include "array.hpp" #include "script_value.hpp" namespace scripting @@ -33,4 +34,6 @@ namespace scripting script_value get_entity_field(const entity& entity, const std::string& field); void notify(const entity& entity, const std::string& event, const std::vector& arguments); + + unsigned int make_array(); } diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index f429aad0..300c7352 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -1494,12 +1494,12 @@ namespace scripting {"setspectatedefaults", 0x82C5}, // SP 0x000000000 MP 0x140331EE0 {"getthirdpersoncrosshairoffset", 0x82C6}, // SP 0x000000000 MP 0x140332250 {"disableweaponpickup", 0x82C7}, // SP 0x140262950 MP 0x14032EF00 - {"_meth_82c8", 0x82C8}, // SP 0x140262A60 MP 0x14032EFF0 - {"_meth_82c9", 0x82C9}, // SP 0x140262AB0 MP 0x14032F0D0 - {"_meth_82ca", 0x82CA}, // SP 0x000000000 MP 0x1403322C0 - {"getweaponslistexclusives", 0x82CB}, // SP 0x1402623D0 MP 0x14032E3A0 - {"_meth_82cc", 0x82CC}, // SP 0x1402624C0 MP 0x14032E4B0 - {"_meth_82cd", 0x82CD}, // SP 0x1402625B0 MP 0x14032E650 + {"enableweaponpickup", 0x82C8}, // SP 0x140262A60 MP 0x14032EFF0 + {"issplitscreenplayer", 0x82C9}, // SP 0x140262AB0 MP 0x14032F0D0 + {"issplitscreenplayerprimary", 0x82CA}, // SP 0x000000000 MP 0x1403322C0 + {"getweaponslistoffhands", 0x82CB}, // SP 0x1402623D0 MP 0x14032E3A0 + {"getweaponslistitems", 0x82CC}, // SP 0x1402624C0 MP 0x14032E4B0 + {"getweaponslistexclusives", 0x82CD}, // SP 0x1402625B0 MP 0x14032E650 {"getweaponslist", 0x82CE}, // SP 0x140262720 MP 0x14032E790 {"canplayerplacesentry", 0x82CF}, // SP 0x140264D00 MP 0x140331530 {"canplayerplacetank", 0x82D0}, // SP 0x1402651B0 MP 0x1403292E0 @@ -1559,8 +1559,8 @@ namespace scripting {"setviewkickscale", 0x8306}, // SP 0x1402608B0 MP 0x14032CB90 {"getviewkickscale", 0x8307}, // SP 0x140260A80 MP 0x14032CCC0 {"getweaponslistall", 0x8308}, // SP 0x1402621A0 MP 0x14032E120 - getweaponslistoffhands - {"getweaponslistitems", 0x8309}, // SP 0x1402622E0 MP 0x14032E230 - {"_meth_830a", 0x830A}, // SP 0x140261090 MP 0x14032C720 + {"getweaponslistprimaries", 0x8309}, // SP 0x1402622E0 MP 0x14032E230 + {"getnormalizedcameramovement", 0x830A}, // SP 0x140261090 MP 0x14032C720 {"giveweapon", 0x830B}, // SP 0x140262F00 MP 0x14032EA90f {"takeweapon", 0x830C}, // SP 0x140263380 MP 0x14032F210 {"takeallweapons", 0x830D}, // SP 0x1402635B0 MP 0x14032F310 @@ -1596,13 +1596,13 @@ namespace scripting {"setreverb", 0x832B}, // SP 0x140266EA0 MP 0x14032B9C0 {"_meth_832c", 0x832C}, // SP 0x140267180 MP 0x14032B9E0 {"deactivatechannelvolumes", 0x832D}, // SP 0x140267410 MP 0x14032BB00 - {"_meth_832e", 0x832E}, // SP 0x140265FA0 MP 0x140329C00 - {"_meth_832f", 0x832F}, // SP 0x140266200 MP 0x140329F00 - {"_meth_8330", 0x8330}, // SP 0x140266560 MP 0x14032A240 - {"_meth_8331", 0x8331}, // SP 0x140266820 MP 0x14032A6F0 + {"givestartammo", 0x832E}, // SP 0x140265FA0 MP 0x140329C00 + {"givemaxammo", 0x832F}, // SP 0x140266200 MP 0x140329F00 + {"getfractionstartammo", 0x8330}, // SP 0x140266560 MP 0x14032A240 + {"getfractionmaxammo", 0x8331}, // SP 0x140266820 MP 0x14032A6F0 {"isdualwielding", 0x8332}, // SP 0x140266E10 MP 0x14032ABC0 - {"_meth_8333", 0x8333}, // SP 0x140267030 MP 0x14032AD00 - {"isreloading", 0x8334}, // SP 0x140267100 MP 0x14032AEE0 + {"isreloading", 0x8333}, // SP 0x140267030 MP 0x14032AD00 + {"isswitchingweapon", 0x8334}, // SP 0x140267100 MP 0x14032AEE0 {"setorigin", 0x8335}, // SP 0x1402677C0 MP 0x14032B8D0 {"getvelocity", 0x8336}, // SP 0x1402604D0 MP 0x14032BC80 {"_meth_8337", 0x8337}, // SP 0x140260930 MP 0x14032BE70 diff --git a/src/client/game/scripting/lua/value_conversion.cpp b/src/client/game/scripting/lua/value_conversion.cpp index 3cc37e20..a838c787 100644 --- a/src/client/game/scripting/lua/value_conversion.cpp +++ b/src/client/game/scripting/lua/value_conversion.cpp @@ -21,7 +21,7 @@ namespace scripting::lua std::unordered_map values; - const auto offset = 0xA000 * (id & 3); + const auto offset = 0xFA00 * (id & 3); auto current = game::scr_VarGlob->objectVariableChildren[id].firstChild; auto idx = 1; @@ -294,7 +294,7 @@ namespace scripting::lua return entity_to_struct(state, value.get_raw().u.uintValue); } - if (value.is>()) + if (value.is()) { return entity_to_array(state, value.get_raw().u.uintValue); } diff --git a/src/client/game/scripting/script_value.cpp b/src/client/game/scripting/script_value.cpp index 7d334f17..b99d831f 100644 --- a/src/client/game/scripting/script_value.cpp +++ b/src/client/game/scripting/script_value.cpp @@ -1,7 +1,7 @@ #include #include "script_value.hpp" #include "entity.hpp" - +#include "array.hpp" namespace scripting { @@ -79,6 +79,15 @@ namespace scripting this->value_ = variable; } + script_value::script_value(const array& value) + { + game::VariableValue variable{}; + variable.type = game::SCRIPT_OBJECT; + variable.u.pointerValue = value.get_entity_id(); + + this->value_ = variable; + } + script_value::script_value(const vector& value) { game::VariableValue variable{}; @@ -194,7 +203,7 @@ namespace scripting **************************************************************/ template <> - bool script_value::is>() const + bool script_value::is() const { if (this->get_raw().type != game::SCRIPT_OBJECT) { @@ -207,6 +216,12 @@ namespace scripting return type == game::SCRIPT_ARRAY; } + template <> + array script_value::get() const + { + return array(this->get_raw().u.uintValue); + } + /*************************************************************** * Struct **************************************************************/ diff --git a/src/client/game/scripting/script_value.hpp b/src/client/game/scripting/script_value.hpp index df8a95b6..27cae79f 100644 --- a/src/client/game/scripting/script_value.hpp +++ b/src/client/game/scripting/script_value.hpp @@ -6,6 +6,7 @@ namespace scripting { class entity; + class array; class script_value { @@ -24,6 +25,7 @@ namespace scripting script_value(const std::string& value); script_value(const entity& value); + script_value(const array& value); script_value(const vector& value); @@ -43,10 +45,11 @@ namespace scripting const game::VariableValue& get_raw() const; + variable_value value_{}; + private: template T get() const; - variable_value value_{}; }; } diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 60c368a1..bf618a5d 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -186,12 +186,11 @@ namespace game struct scrVarGlob_t { - ObjectVariableValue objectVariableValue[56320]; - ObjectVariableChildren objectVariableChildren[56320]; + ObjectVariableValue objectVariableValue[40960]; + ObjectVariableChildren objectVariableChildren[40960]; unsigned __int16 childVariableBucket[65536]; ChildVariableValue childVariableValue[384000]; }; - // * enum Sys_Folder { @@ -1009,11 +1008,11 @@ namespace game enum XAssetType { ASSET_TYPE_PHYSPRESET, - ASSET_TYPE_PHYSCOLLMAP, + ASSET_TYPE_PHYS_COLLMAP, ASSET_TYPE_PHYSWATERPRESET, - ASSET_TYPE_PHYSWORLDMAP, + ASSET_TYPE_PHYS_WORLDMAP, ASSET_TYPE_PHYSCONSTRAINT, - ASSET_TYPE_XANIMPARTS, + ASSET_TYPE_XANIM, ASSET_TYPE_XMODELSURFS, ASSET_TYPE_XMODEL, ASSET_TYPE_MATERIAL, @@ -1023,36 +1022,35 @@ namespace game ASSET_TYPE_DOMAINSHADER, ASSET_TYPE_PIXELSHADER, ASSET_TYPE_VERTEXDECL, - ASSET_TYPE_TECHNIQUE_SET, + ASSET_TYPE_TECHSET, ASSET_TYPE_IMAGE, ASSET_TYPE_SOUND, - ASSET_TYPE_SOUND_SUBMIX, - ASSET_TYPE_SOUND_CURVE, - ASSET_TYPE_LPF_CURVE, - ASSET_TYPE_REVERB_CURVE, - ASSET_TYPE_SOUND_CONTEXT, + ASSET_TYPE_SOUNDSUBMIX, + ASSET_TYPE_SNDCURVE, + ASSET_TYPE_LPFCURVE, + ASSET_TYPE_REVERBSENDCURVE, + ASSET_TYPE_SNDCONTEXT, ASSET_TYPE_LOADED_SOUND, - ASSET_TYPE_CLIPMAP, - ASSET_TYPE_COMWORLD, - ASSET_TYPE_GLASSWORLD, - ASSET_TYPE_PATHDATA, + ASSET_TYPE_COL_MAP_MP, + ASSET_TYPE_COM_MAP, + ASSET_TYPE_GLASS_MAP, + ASSET_TYPE_AIPATHS, ASSET_TYPE_VEHICLE_TRACK, ASSET_TYPE_MAP_ENTS, - ASSET_TYPE_FXWORLD, - ASSET_TYPE_GFXWORLD, - ASSET_TYPE_LIGHT_DEF, + ASSET_TYPE_FX_MAP, + ASSET_TYPE_GFX_MAP, + ASSET_TYPE_LIGHTDEF, ASSET_TYPE_UI_MAP, - ASSET_TYPE_FONT, - ASSET_TYPE_MENULIST, + ASSET_TYPE_MENUFILE, ASSET_TYPE_MENU, ASSET_TYPE_ANIMCLASS, - ASSET_TYPE_LOCALIZE_ENTRY, + ASSET_TYPE_LOCALIZE, ASSET_TYPE_ATTACHMENT, ASSET_TYPE_WEAPON, - ASSET_TYPE_SNDDRIVER_GLOBALS, + ASSET_TYPE_SNDDRIVERGLOBALS, ASSET_TYPE_FX, - ASSET_TYPE_IMPACT_FX, - ASSET_TYPE_SURFACE_FX, + ASSET_TYPE_IMPACTFX, + ASSET_TYPE_SURFACEFX, ASSET_TYPE_AITYPE, ASSET_TYPE_MPTYPE, ASSET_TYPE_CHARACTER, @@ -1060,23 +1058,27 @@ namespace game ASSET_TYPE_RAWFILE, ASSET_TYPE_SCRIPTFILE, ASSET_TYPE_STRINGTABLE, - ASSET_TYPE_LEADERBOARD, - ASSET_TYPE_STRUCTURED_DATA_DEF, + ASSET_TYPE_LEADERBOARDDEF, + ASSET_TYPE_VIRTUALLEADERBOARDDEF, + ASSET_TYPE_STRUCTUREDDATADEF, + ASSET_TYPE_DDL, + ASSET_TYPE_PROTO, ASSET_TYPE_TRACER, ASSET_TYPE_VEHICLE, ASSET_TYPE_ADDON_MAP_ENTS, - ASSET_TYPE_NET_CONST_STRINGS, - ASSET_TYPE_REVERB_PRESET, - ASSET_TYPE_LUA_FILE, + ASSET_TYPE_NETCONSTSTRINGS, + ASSET_TYPE_REVERBPRESET, + ASSET_TYPE_LUAFILE, ASSET_TYPE_SCRIPTABLE, - ASSET_TYPE_EQUIPMENT_SND_TABLE, + ASSET_TYPE_EQUIPSNDTABLE, ASSET_TYPE_VECTORFIELD, - ASSET_TYPE_DOPPLER_PRESET, - ASSET_TYPE_PARTICLE_SIM_ANIMATION, + ASSET_TYPE_DOPPLERPRESET, + ASSET_TYPE_PARTICLESIMANIMATION, ASSET_TYPE_LASER, - ASSET_TYPE_SKELETON_SCRIPT, + ASSET_TYPE_SKELETONSCRIPT, ASSET_TYPE_CLUT, - ASSET_TYPE_COUNT, + ASSET_TYPE_TTF, + ASSET_TYPE_COUNT }; enum GfxDrawSceneMethod diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index bfabfd0d..257bbf15 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -13,6 +13,7 @@ namespace game WEAK symbol AddRefToObject{0x14036E5F0, 0x14043C570}; WEAK symbol RemoveRefToObject{0x14036FFE0, 0x14043DF80}; WEAK symbol AllocThread{0x14036E960, 0x14043C8E0}; + WEAK symbol AllocVariable{0x14036E9C0, 0x14043C940}; WEAK symbol Cbuf_AddText{0x140342EB0, 0x1404033B0}; WEAK symbol FS_AddLocalizedGameDirectory{0x1403B6030, 0x1404EBE20}; WEAK symbol GetVariable{0x14036FDD0, 0x1403F3730}; - + WEAK symbol GetNewVariable{0x14036FA00, 0x14043D990}; + WEAK symbol GetNewArrayVariable{0x14036F880, 0x14043D810}; WEAK symbol GScr_LoadConsts{0x1402D13E0, 0x140393810}; WEAK symbol FindVariable{0x14036F4B0, 0x14043D430}; WEAK symbol FindEntityId{0x14036F3B0, 0x14043D330}; @@ -197,21 +199,21 @@ namespace game WEAK symbol sv_cmd_args{0x14AD99A10, 0x14946BA20}; - WEAK symbol g_script_error_level{0x14A1917A8, 0x14A33C824}; - WEAK symbol g_script_error{0x14A1917B0, 0x14A33C940}; + WEAK symbol g_script_error_level{0x14BCFA4A4, 0x14A33C824}; + WEAK symbol g_script_error{0x14BCFA5C0, 0x14A33C940}; - WEAK symbol levelEntityId{0x149AF55B0, 0x149CA0730}; - WEAK symbol gameEntityId{0x149CA0734, 0x14B65E3B4}; + WEAK symbol levelEntityId{0x14B65E3B0, 0x149CA0730}; + WEAK symbol gameEntityId{0x14B65E3B4, 0x149CA0734}; WEAK symbol command_whitelist{0x141079A60, 0x14120C360}; WEAK symbol cmd_functions{0x14AD99AB8, 0x14946BAC8}; WEAK symbol cmd_args{0x14AD99960, 0x14946B970}; - WEAK symbol g_poolSize{0, 0x140FEADF0}; - WEAK symbol g_classMap{0x14080A840, 0x1412106B0}; + WEAK symbol g_poolSize{0x140DE84A0, 0x140FEADF0}; + WEAK symbol g_classMap{0x14107AAF0, 0x1412106B0}; WEAK symbol scr_VarGlob{0x14B686480, 0x149CC8800}; - WEAK symbol scr_VmPub{0x14A1938C0, 0x14A33EA40}; + WEAK symbol scr_VmPub{0x14BCFC6C0, 0x14A33EA40}; WEAK symbol scr_function_stack{0x14BD06C40, 0x14A348FC0}; WEAK symbol gfxDrawMethod{0x14F05CE50, 0x14FD21180}; From 9badba626c26df8fccdd6455c2cd18a2779d2d44 Mon Sep 17 00:00:00 2001 From: DoktorSAS <62484597+DoktorSAS@users.noreply.github.com> Date: Sun, 13 Mar 2022 21:19:17 +0100 Subject: [PATCH 088/346] Fixed lowercase --- src/client/game/scripting/function_tables.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index 134efc90..e0af4b0c 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -1777,7 +1777,7 @@ namespace scripting {"setrocketcorpse", 0x83E0}, // SP 0x1402A15D0 MP 0x14036E1F0 {"setcorpsefalling", 0x83E1}, // SP 0x000000000 MP 0x140374840 {"setsurfacetype", 0x83E2}, // SP 0x14029FD00 MP 0x140358090 - {"aIiphysicstrace", 0x83E3}, // SP 0x1402A0C60 MP 0x140369520 + {"aiphysicstrace", 0x83E3}, // SP 0x1402A0C60 MP 0x140369520 {"_meth_83e4", 0x83E4}, // SP 0x1402A20D0 MP 0x140369FE0 {"_meth_83e5", 0x83E5}, // SP 0x1405D92F0 MP 0x14033B020 {"_meth_83e6", 0x83E6}, // SP 0x1402A7B00 MP 0x000000000 From c97e354bc14580b53e2ad0bcf95b741c91a34cd8 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 23:11:49 +0100 Subject: [PATCH 089/346] Fix event_handler --- src/client/game/scripting/lua/event_handler.cpp | 4 ++-- src/client/game/scripting/lua/event_handler.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/game/scripting/lua/event_handler.cpp b/src/client/game/scripting/lua/event_handler.cpp index 7121ea63..ef8597ce 100644 --- a/src/client/game/scripting/lua/event_handler.cpp +++ b/src/client/game/scripting/lua/event_handler.cpp @@ -81,9 +81,9 @@ namespace scripting::lua { auto merger = [&](task_list& tasks) { - for(auto& task : tasks) + for (auto& task : tasks) { - if(task.id == handle.id) + if (task.id == handle.id) { task.endon_conditions.emplace_back(entity, event); } diff --git a/src/client/game/scripting/lua/event_handler.hpp b/src/client/game/scripting/lua/event_handler.hpp index fc95b704..e12dcab6 100644 --- a/src/client/game/scripting/lua/event_handler.hpp +++ b/src/client/game/scripting/lua/event_handler.hpp @@ -43,7 +43,7 @@ namespace scripting::lua sol::state& state_; std::atomic_int64_t current_listener_id_ = 0; - using task_list = std::vector; + using task_list = std::list; utils::concurrency::container new_callbacks_; utils::concurrency::container callbacks_; From 5a3247234b19e6c102f76abb752f81aa9a68228a Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 23:12:34 +0100 Subject: [PATCH 090/346] Fix bots --- src/client/component/bots.cpp | 30 ++++++++++++++++-------------- src/client/component/command.cpp | 10 +++++----- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 03323512..0c72ed89 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -19,14 +19,10 @@ namespace bots { bool can_add() { - if (party::get_client_count() < *game::mp::svs_numclients) - { - return true; - } - return false; + return party::get_client_count() < *game::mp::svs_numclients + && game::SV_Loaded() && !game::VirtualLobby_Loaded(); } - // TODO: when scripting comes, fix this to use better notifies void bot_team_join(const int entity_num) { const game::scr_entref_t entref{static_cast(entity_num), 0}; @@ -57,17 +53,20 @@ namespace bots return; } - // SV_BotGetRandomName - const auto* const bot_name = game::SV_BotGetRandomName(); - auto* bot_ent = game::SV_AddBot(bot_name); + static auto first_bot = true; + + const auto bot_name = game::SV_BotGetRandomName(); + const auto bot_ent = game::SV_AddBot(bot_name); + if (bot_ent) { spawn_bot(bot_ent->s.entityNum); } - else if (can_add()) // workaround since first bot won't ever spawn - { - add_bot(); - } + // can cause a stack overflow + // else if (can_add()) // workaround since first bot won't ever spawn + // { + // add_bot(); + // } } } @@ -83,7 +82,10 @@ namespace bots command::add("spawnBot", [](const command::params& params) { - if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) return; + if (!can_add()) + { + return; + } auto num_bots = 1; if (params.size() == 2) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 32e7fa0a..5f50c25e 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -172,8 +172,8 @@ namespace command try { - const auto arg = params[1]; - const scripting::entity player = scripting::call("getentbynum", {client_num}).as(); + const auto& arg = params[1]; + const auto player = scripting::entity({static_cast(client_num), 0}); auto ps = game::SV_GetPlayerstateForClientNum(client_num); if (arg == "ammo") @@ -243,7 +243,7 @@ namespace command { try { - const scripting::entity player = scripting::call("getentbynum", {client_num}).as(); + const auto player = scripting::entity({static_cast(client_num), 0}); const auto weapon = player.call("getcurrentweapon"); player.call("dropitem", {weapon}); } @@ -264,7 +264,7 @@ namespace command try { - const scripting::entity player = scripting::call("getentbynum", {client_num}).as(); + const auto player = scripting::entity({static_cast(client_num), 0}); if (weapon == "all"s) { player.call("takeallweapons"); @@ -285,7 +285,7 @@ namespace command { try { - const scripting::entity player = scripting::call("getentbynum", {client_num}).as(); + const auto player = scripting::entity({static_cast(client_num), 0}); player.call(SELECT_VALUE("kill", "suicide")); } catch (...) From b415019c37a539652556c1120ffd6c909183a067 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 23:40:22 +0100 Subject: [PATCH 091/346] Better fix --- .../game/scripting/lua/event_handler.cpp | 22 ++++++++++--------- .../game/scripting/lua/event_handler.hpp | 2 +- src/client/game/scripting/lua/scheduler.cpp | 10 ++++----- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/client/game/scripting/lua/event_handler.cpp b/src/client/game/scripting/lua/event_handler.cpp index ef8597ce..c009bfd0 100644 --- a/src/client/game/scripting/lua/event_handler.cpp +++ b/src/client/game/scripting/lua/event_handler.cpp @@ -31,28 +31,30 @@ namespace scripting::lua this->merge_callbacks(); this->handle_endon_conditions(event); - for (auto i = tasks.begin(); i != tasks.end();) + auto size = tasks.size(); + for (auto i = 0; i < tasks.size();) { - if (i->event != event.name || i->entity != event.entity) + const auto task = tasks[i]; + if (task.event != event.name || task.entity != event.entity) { ++i; continue; } - if (!i->is_deleted) + if (!task.is_deleted) { - if(!has_built_arguments) + if (!has_built_arguments) { has_built_arguments = true; arguments = this->build_arguments(event); } - handle_error(i->callback(sol::as_args(arguments))); + handle_error(task.callback(sol::as_args(arguments))); } - if (i->is_volatile || i->is_deleted) + if (task.is_volatile || task.is_deleted) { - i = tasks.erase(i); + tasks.erase(tasks.begin() + i); } else { @@ -144,11 +146,11 @@ namespace scripting::lua { auto deleter = [&](task_list& tasks) { - for(auto& task : tasks) + for (auto& task : tasks) { - for(auto& condition : task.endon_conditions) + for (auto& condition : task.endon_conditions) { - if(condition.first == event.entity && condition.second == event.name) + if (condition.first == event.entity && condition.second == event.name) { task.is_deleted = true; break; diff --git a/src/client/game/scripting/lua/event_handler.hpp b/src/client/game/scripting/lua/event_handler.hpp index e12dcab6..fc95b704 100644 --- a/src/client/game/scripting/lua/event_handler.hpp +++ b/src/client/game/scripting/lua/event_handler.hpp @@ -43,7 +43,7 @@ namespace scripting::lua sol::state& state_; std::atomic_int64_t current_listener_id_ = 0; - using task_list = std::list; + using task_list = std::vector; utils::concurrency::container new_callbacks_; utils::concurrency::container callbacks_; diff --git a/src/client/game/scripting/lua/scheduler.cpp b/src/client/game/scripting/lua/scheduler.cpp index 1afb7df2..77efcf09 100644 --- a/src/client/game/scripting/lua/scheduler.cpp +++ b/src/client/game/scripting/lua/scheduler.cpp @@ -23,11 +23,11 @@ namespace scripting::lua { auto deleter = [&](task_list& tasks) { - for(auto& task : tasks) + for (auto& task : tasks) { - for(auto& condition : task.endon_conditions) + for (auto& condition : task.endon_conditions) { - if(condition.first == event.entity && condition.second == event.name) + if (condition.first == event.entity && condition.second == event.name) { task.is_deleted = true; break; @@ -122,9 +122,9 @@ namespace scripting::lua { auto merger = [&](task_list& tasks) { - for(auto& task : tasks) + for (auto& task : tasks) { - if(task.id == handle.id) + if (task.id == handle.id) { task.endon_conditions.emplace_back(entity, event); } From a5986679ce131f2617fd3c367936e5f99819433f Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 13 Mar 2022 23:54:26 +0100 Subject: [PATCH 092/346] Fix build --- src/client/game/scripting/lua/event_handler.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/game/scripting/lua/event_handler.cpp b/src/client/game/scripting/lua/event_handler.cpp index c009bfd0..7d33ea64 100644 --- a/src/client/game/scripting/lua/event_handler.cpp +++ b/src/client/game/scripting/lua/event_handler.cpp @@ -31,7 +31,6 @@ namespace scripting::lua this->merge_callbacks(); this->handle_endon_conditions(event); - auto size = tasks.size(); for (auto i = 0; i < tasks.size();) { const auto task = tasks[i]; From fe593450bbdf7a221258d7fa83a9bdaf2299c7c8 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Mon, 14 Mar 2022 00:00:47 +0100 Subject: [PATCH 093/346] Finish fixing spawnBot --- src/client/component/bots.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 0c72ed89..5901e5d4 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -62,11 +62,13 @@ namespace bots { spawn_bot(bot_ent->s.entityNum); } - // can cause a stack overflow - // else if (can_add()) // workaround since first bot won't ever spawn - // { - // add_bot(); - // } + else + { + scheduler::once([]() + { + add_bot(); + }, scheduler::pipeline::server, 100ms); + } } } From 69f65f6ed91d907064b2063b78d075094ac3baf8 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Mon, 14 Mar 2022 01:55:00 +0100 Subject: [PATCH 094/346] Fix client_t (again) --- src/client/game/structs.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index bf618a5d..3437a026 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1406,10 +1406,10 @@ namespace game LiveClientDropType liveDropRequest; //269572 char __pad4[24]; TestClientType testClient; // 269600 - char __pad5[129600]; - }; // size = 661304 + char __pad5[347912]; + }; // size = 879616 - static_assert(sizeof(client_t) == 661304); + static_assert(sizeof(client_t) == 879616); } namespace sp From 59bee7ea37dab1122fe7cfebcdf975d9a267c384 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Mar 2022 17:34:54 +0000 Subject: [PATCH 095/346] Bump deps/libtommath from `04e9d1e` to `66de864` Bumps [deps/libtommath](https://github.com/libtom/libtommath) from `04e9d1e` to `66de864`. - [Release notes](https://github.com/libtom/libtommath/releases) - [Commits](https://github.com/libtom/libtommath/compare/04e9d1e7a0493910b2eb5e757d623870692ada04...66de86426e9cdb88526974c765108f01554af2b0) --- updated-dependencies: - dependency-name: deps/libtommath dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/libtommath | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtommath b/deps/libtommath index 04e9d1e7..66de8642 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit 04e9d1e7a0493910b2eb5e757d623870692ada04 +Subproject commit 66de86426e9cdb88526974c765108f01554af2b0 From 126481851de072fe573200a710ef3fba55b217f6 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 15 Mar 2022 19:06:47 +0100 Subject: [PATCH 096/346] Maybe fix build --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9db13960..591bbf89 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Check out files - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: true fetch-depth: 0 From 43fecb85e7bfcdee1c938250200d613f88b54ede Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 15 Mar 2022 19:18:49 +0100 Subject: [PATCH 097/346] Update build.yml --- .github/workflows/build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 591bbf89..8672a913 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,6 +28,8 @@ jobs: - name: Check out files uses: actions/checkout@v3 + run: | + git config --global url."https://".insteadOf git:// with: submodules: true fetch-depth: 0 From 3437da85891cb5018938ac6fdc83753b5924566f Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 15 Mar 2022 19:20:19 +0100 Subject: [PATCH 098/346] Update build.yml --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8672a913..c2804b1e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,10 +26,11 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: idk + run: git config --global url."https://".insteadOf git:// + - name: Check out files uses: actions/checkout@v3 - run: | - git config --global url."https://".insteadOf git:// with: submodules: true fetch-depth: 0 From 87bec471dcb62e89743085242896e041e74856a7 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 15 Mar 2022 19:32:52 +0100 Subject: [PATCH 099/346] Update build.yml --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c2804b1e..c8d876a7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,7 +26,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: idk + - name: Set up git config run: git config --global url."https://".insteadOf git:// - name: Check out files From 23c3f643774df8fc2b304a158dafe66918cc9c99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 15 Mar 2022 20:11:04 +0000 Subject: [PATCH 100/346] Bump deps/asmjit from `6efd4d5` to `f1a399c` Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `6efd4d5` to `f1a399c`. - [Release notes](https://github.com/asmjit/asmjit/releases) - [Commits](https://github.com/asmjit/asmjit/compare/6efd4d563dee6832224295fa3bbf1647964246c4...f1a399c4fe74d1535a4190a2b8727c51045cc914) --- updated-dependencies: - dependency-name: deps/asmjit dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/asmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/asmjit b/deps/asmjit index 6efd4d56..f1a399c4 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit 6efd4d563dee6832224295fa3bbf1647964246c4 +Subproject commit f1a399c4fe74d1535a4190a2b8727c51045cc914 From 60a0062dfd621b0bb46de77e77112e04e32f85f7 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 16 Mar 2022 00:27:49 +0100 Subject: [PATCH 101/346] Custom material stupport --- src/client/component/materials.cpp | 167 +++++++++++++++++++++++++++++ src/client/component/materials.hpp | 6 ++ src/client/game/structs.hpp | 81 +++++++++++++- src/client/game/symbols.hpp | 5 +- 4 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 src/client/component/materials.cpp create mode 100644 src/client/component/materials.hpp diff --git a/src/client/component/materials.cpp b/src/client/component/materials.cpp new file mode 100644 index 00000000..3ca18c5d --- /dev/null +++ b/src/client/component/materials.cpp @@ -0,0 +1,167 @@ +#include +#include "loader/component_loader.hpp" + +#include "materials.hpp" +#include "console.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include +#include +#include +#include + +namespace materials +{ + namespace + { + utils::hook::detour db_material_streaming_fail_hook; + utils::hook::detour material_register_handle_hook; + + struct material_data_t + { + std::unordered_map materials; + std::unordered_map images; + }; + + utils::concurrency::container material_data; + + game::GfxImage* setup_image(game::GfxImage* image, const utils::image& raw_image) + { + image->imageFormat = 0x1000003; + image->resourceSize = -1; + + D3D11_SUBRESOURCE_DATA data{}; + data.SysMemPitch = raw_image.get_width() * 4; + data.SysMemSlicePitch = data.SysMemPitch * raw_image.get_height(); + data.pSysMem = raw_image.get_buffer(); + + game::Image_Setup(image, raw_image.get_width(), raw_image.get_height(), image->depth, image->numElements, + image->imageFormat, DXGI_FORMAT_R8G8B8A8_UNORM, image->name, &data); + + return image; + } + + game::Material* create_material(const std::string& name, const std::string& data) + { + const auto white = *reinterpret_cast(SELECT_VALUE(0x141F3D860, 0x14282C330)); + + const auto material = utils::memory::get_allocator()->allocate(); + const auto texture_table = utils::memory::get_allocator()->allocate(); + const auto image = utils::memory::get_allocator()->allocate(); + + std::memcpy(material, white, sizeof(game::Material)); + std::memcpy(texture_table, white->textureTable, sizeof(game::MaterialTextureDef)); + std::memcpy(image, white->textureTable->u.image, sizeof(game::GfxImage)); + + material->name = utils::memory::get_allocator()->duplicate_string(name); + image->name = material->name; + + material->textureTable = texture_table; + material->textureTable->u.image = setup_image(image, data); + + return material; + } + + game::Material* load_material(const std::string& name) + { + return material_data.access([&](material_data_t& data_) -> game::Material* + { + if (const auto i = data_.materials.find(name); i != data_.materials.end()) + { + return i->second; + } + + std::string data{}; + if (const auto i = data_.images.find(name); i != data_.images.end()) + { + data = i->second; + } + + if (data.empty() + && !utils::io::read_file(utils::string::va("h1-mod/materials/%s.png", name.data()), &data) + && !utils::io::read_file(utils::string::va("data/materials/%s.png", name.data()), &data)) + { + return nullptr; + } + + const auto material = create_material(name, data); + data_.materials[name] = material; + + return material; + }); + } + + game::Material* try_load_material(const std::string& name) + { + try + { + return load_material(name); + } + catch (const std::exception& e) + { + console::error("Failed to load material %s: %s\n", name.data(), e.what()); + } + + return nullptr; + } + + game::Material* material_register_handle_stub(const char* name) + { + auto result = try_load_material(name); + if (result == nullptr) + { + result = material_register_handle_hook.invoke(name); + } + return result; + } + + bool db_material_streaming_fail_stub(game::Material* material) + { + const auto found = material_data.access([material](material_data_t& data_) + { + if (data_.materials.find(material->name) != data_.materials.end()) + { + return true; + } + + return false; + }); + + if (found) + { + return false; + } + + return db_material_streaming_fail_hook.invoke(material); + } + } + + void add(const std::string& name, const std::string& data) + { + material_data.access([&](material_data_t& data_) + { + data_.images[name] = data; + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_dedi()) + { + return; + } + + material_register_handle_hook.create(game::Material_RegisterHandle, material_register_handle_stub); + db_material_streaming_fail_hook.create(SELECT_VALUE(0x1401D3180, 0x1402C6260), db_material_streaming_fail_stub); + } + }; +} + +REGISTER_COMPONENT(materials::component) diff --git a/src/client/component/materials.hpp b/src/client/component/materials.hpp new file mode 100644 index 00000000..ac58b511 --- /dev/null +++ b/src/client/component/materials.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace materials +{ + void add(const std::string& name, const std::string& data); +} diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 3437a026..dc3f33c7 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1101,11 +1101,91 @@ namespace game int forceTechType; }; + struct GfxImage; + + union MaterialTextureDefInfo + { + GfxImage* image; + void* water; + }; + + struct MaterialTextureDef + { + unsigned int nameHash; + char nameStart; + char nameEnd; + char samplerState; + char semantic; + MaterialTextureDefInfo u; + char pad[1000]; + }; + + struct MaterialPass + { + void* vertexShader; + void* vertexDecl; + void* hullShader; + void* domainShader; + void* pixelShader; + char pixelOutputMask; + char perPrimArgCount; + char perObjArgCount; + char stableArgCount; + unsigned __int16 perPrimArgSize; + unsigned __int16 perObjArgSize; + unsigned __int16 stableArgSize; + char zone; + char perPrimConstantBuffer; + char perObjConstantBuffer; + char stableConstantBuffer; + unsigned int customBufferFlags; + char customSamplerFlags; + char precompiledIndex; + char stageConfig; + void* args; + }; + + struct MaterialTechnique + { + const char* name; + unsigned __int16 flags; + unsigned __int16 passCount; + MaterialPass passArray[1]; + }; + + struct MaterialTechniqueSet + { + const char* name; + unsigned __int16 flags; + char worldVertFormat; + char preDisplacementOnlyCount; + MaterialTechnique* techniques[309]; + }; + + struct GfxStateBits + { + unsigned int loadBits[3]; + char zone; + char depthStencilState[11]; + char blendState; + char rasterizerState; + }; + struct Material { const char* name; + char __pad0[0x118]; + char textureCount; + char __pad1[7]; + MaterialTechniqueSet* techniqueSet; + MaterialTextureDef* textureTable; + void* constantTable; + GfxStateBits* stateBitsTable; + char __pad2[0x108]; }; + static_assert(sizeof(Material) == 0x250); + struct Glyph { unsigned short letter; @@ -1252,7 +1332,6 @@ namespace game GfxImageLoadDef* loadDef; }; - struct GfxTexture { $3FA29451CE6F1FA138A5ABAB84BE9676 ___u0; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 257bbf15..9381150a 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -121,6 +121,9 @@ namespace game #define R_AddCmdDrawTextWithCursor(TXT, MC, F, UNK, X, Y, XS, YS, R, C, S, CP, CC) \ H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S, CP, CC, game::R_DrawSomething(S)) + WEAK symbol Image_Setup{0x1404D7D50, 0x1405DCF90}; + WEAK symbol VM_Execute{0x140376360, 0x140444350}; @@ -138,7 +141,7 @@ namespace game WEAK symbol DB_EnumXAssets_Internal{0x1401C9C10, 0x1402BA830}; - WEAK symbol DB_GetXAssetName{0x14019A390, 0x14028BE50}; + WEAK symbol DB_GetXAssetName{0x14019A390, 0x14028BE50}; WEAK symbol DB_GetXAssetTypeSize{0x14019A3B0, 0x14028BE70}; WEAK symbol Date: Wed, 16 Mar 2022 00:30:55 +0100 Subject: [PATCH 102/346] Remove this --- src/client/game/structs.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index dc3f33c7..bb7c3aec 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1117,7 +1117,6 @@ namespace game char samplerState; char semantic; MaterialTextureDefInfo u; - char pad[1000]; }; struct MaterialPass From c52cfa73b4f7e150733afcbf47e96cb5ef51efb4 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 15 Mar 2022 18:59:03 -0500 Subject: [PATCH 103/346] discord rich presence joining TODO: - add a "session ID" randomly generated string - improve the Joining game on DW initalized > main thread? - join requests with avatars in game (ui scripting) --- src/client/component/discord.cpp | 52 +++++++++++++++++++++++++++++--- src/client/component/party.cpp | 10 ++++++ src/client/component/party.hpp | 2 ++ src/client/main.cpp | 11 +++++++ 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index 5925a64a..455c510f 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -9,6 +9,7 @@ #include "party.hpp" #include +#include #include @@ -37,6 +38,12 @@ namespace discord discord_presence.partyMax = 0; discord_presence.startTimestamp = 0; discord_presence.largeImageKey = game::environment::is_sp() ? "menu_singleplayer" : "menu_multiplayer"; + + // set to blank when in lobby + discord_presence.matchSecret = ""; + discord_presence.joinSecret = ""; + discord_presence.partyId = ""; + discord_presence.state = ""; } else { @@ -59,6 +66,22 @@ namespace discord { strcpy_s(clean_hostname, "Private Match"); max_clients = game::Dvar_FindVar("sv_maxclients")->current.integer; + discord_presence.partyPrivacy = DISCORD_PARTY_PRIVATE; + } + else + { + discord_presence.partyPrivacy = DISCORD_PARTY_PUBLIC; + + // TODO: we need to make this a random string that represents the session ID + // const auto sessionId = party::get_state_challenge(); + discord_presence.partyId = "PLACEHOLDER"; + + const auto server_net_info = party::get_state_host(); + const auto server_ip_port = utils::string::va("%i.%i.%i.%i:%i", + server_net_info.ip[0], server_net_info.ip[1], server_net_info.ip[2], server_net_info.ip[3], + ntohs(server_net_info.port)); + + discord_presence.joinSecret = server_ip_port; } discord_presence.partySize = *reinterpret_cast(0x1429864C4); @@ -99,9 +122,9 @@ namespace discord handlers.ready = ready; handlers.errored = errored; handlers.disconnected = errored; - handlers.joinGame = nullptr; + handlers.joinGame = joinGame; handlers.spectateGame = nullptr; - handlers.joinRequest = nullptr; + handlers.joinRequest = joinRequest; Discord_Initialize("947125042930667530", &handlers, 1, nullptr); @@ -127,13 +150,13 @@ namespace discord private: bool initialized_ = false; - static void ready(const DiscordUser* /*request*/) + static void ready(const DiscordUser* request) { ZeroMemory(&discord_presence, sizeof(discord_presence)); discord_presence.instance = 1; - console::info("Discord: Ready\n"); + console::info("Discord: Ready on %s (%s)\n", request->username, request->userId); Discord_UpdatePresence(&discord_presence); } @@ -142,6 +165,27 @@ namespace discord { console::error("Discord: Error (%i): %s\n", error_code, message); } + + static void joinGame(const char* joinSecret) + { + console::info("Discord: Join game called with join secret: %s\n", joinSecret); + + scheduler::once([joinSecret]() + { + game::netadr_s target{}; + if (game::NET_StringToAdr(joinSecret, &target)) + { + console::info("Discord: Connecting to server: %s\n", joinSecret); + party::connect(target); + } + }, scheduler::pipeline::main); + } + + static void joinRequest(const DiscordUser* request) + { + console::info("Discord: joinRequest from %s (%s)\n", request->username, request->userId); + // Discord_Respond(request->userId, DISCORD_REPLY_YES); + } }; } diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 38dd7277..5a88eb65 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -234,6 +234,16 @@ namespace party network::send(target, "getInfo", connect_state.challenge); } + game::netadr_s get_state_host() + { + return connect_state.host; + } + + std::string get_state_challenge() + { + return connect_state.challenge; + } + void start_map(const std::string& mapname) { if (game::Live_SyncOnlineDataFlags(0) > 32) diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index 0feb2e98..13990aea 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -9,6 +9,8 @@ namespace party void start_map(const std::string& mapname); void clear_sv_motd(); + game::netadr_s get_state_host(); + std::string get_state_challenge(); int server_client_count(); int get_client_num_by_name(const std::string& name); diff --git a/src/client/main.cpp b/src/client/main.cpp index 7329eb4c..500a09c4 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -146,6 +146,16 @@ void limit_parallel_dll_loading() RegCloseKey(key); } +// solution for other processes that may launch the mod +void apply_proper_directory() +{ + char module_path[MAX_PATH]; + GetModuleFileNameA(nullptr, module_path, MAX_PATH); + PathRemoveFileSpecA(module_path); + SetCurrentDirectoryA(module_path); + SetDllDirectoryA(module_path); +} + int main() { FARPROC entry_point; @@ -169,6 +179,7 @@ int main() try { + apply_proper_directory(); remove_crash_file(); if (!component_loader::post_start()) return 0; From e939edee75167dc7862f5d7d080f7de573b20a19 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 16 Mar 2022 01:56:00 +0100 Subject: [PATCH 104/346] Dont try to load 'white' material --- src/client/component/materials.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/client/component/materials.cpp b/src/client/component/materials.cpp index 3ca18c5d..287238c0 100644 --- a/src/client/component/materials.cpp +++ b/src/client/component/materials.cpp @@ -97,6 +97,11 @@ namespace materials game::Material* try_load_material(const std::string& name) { + if (name == "white") + { + return nullptr; + } + try { return load_material(name); From dca9ed1176a0b7d73a1866a9668b75ed4c170cda Mon Sep 17 00:00:00 2001 From: m Date: Wed, 16 Mar 2022 07:38:26 -0500 Subject: [PATCH 105/346] removed git protocol submodules [skip ci] --- .gitmodules | 15 --------------- deps/libtomcrypt | 1 - deps/libtommath | 1 - deps/protobuf | 1 - deps/zlib | 1 - 5 files changed, 19 deletions(-) delete mode 160000 deps/libtomcrypt delete mode 160000 deps/libtommath delete mode 160000 deps/protobuf delete mode 160000 deps/zlib diff --git a/.gitmodules b/.gitmodules index 7230acd8..959a72ac 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,19 +28,4 @@ [submodule "deps/stb"] path = deps/stb url = https://github.com/nothings/stb.git -[submodule "deps/libtomcrypt"] - path = deps/libtomcrypt - url = git://github.com/libtom/libtomcrypt.git branch = develop -[submodule "deps/zlib"] - path = deps/zlib - url = git://github.com/madler/zlib.git - branch = develop -[submodule "deps/libtommath"] - path = deps/libtommath - url = git://github.com/libtom/libtommath.git - branch = develop -[submodule "deps/protobuf"] - path = deps/protobuf - url = git://github.com/protocolbuffers/protobuf.git - branch = 3.17.x diff --git a/deps/libtomcrypt b/deps/libtomcrypt deleted file mode 160000 index 673f5ce2..00000000 --- a/deps/libtomcrypt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 673f5ce29015a9bba3c96792920a10601b5b0718 diff --git a/deps/libtommath b/deps/libtommath deleted file mode 160000 index 66de8642..00000000 --- a/deps/libtommath +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 66de86426e9cdb88526974c765108f01554af2b0 diff --git a/deps/protobuf b/deps/protobuf deleted file mode 160000 index 5500c72c..00000000 --- a/deps/protobuf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5500c72c5b616da9f0125bcfab513987a1226e2b diff --git a/deps/zlib b/deps/zlib deleted file mode 160000 index 2014a993..00000000 --- a/deps/zlib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2014a993addbc8f1b9785d97f55fd189792c2f78 From 3e786604d50cd1fb0cf345547a235dcece167203 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 16 Mar 2022 07:42:38 -0500 Subject: [PATCH 106/346] readd submodules via http protocol --- .gitmodules | 16 ++++++++++++++++ deps/libtomcrypt | 1 + deps/libtommath | 1 + deps/protobuf | 1 + deps/zlib | 1 + 5 files changed, 20 insertions(+) create mode 160000 deps/libtomcrypt create mode 160000 deps/libtommath create mode 160000 deps/protobuf create mode 160000 deps/zlib diff --git a/.gitmodules b/.gitmodules index 959a72ac..e92c76fd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -29,3 +29,19 @@ path = deps/stb url = https://github.com/nothings/stb.git branch = develop +[submodule "deps/libtomcrypt"] + path = deps/libtomcrypt + url = https://github.com/libtom/libtomcrypt.git + branch = develop +[submodule "deps/libtommath"] + path = deps/libtommath + url = https://github.com/libtom/libtommath.git + branch = develop +[submodule "deps/protobuf"] + path = deps/protobuf + url = https://github.com/protocolbuffers/protobuf.git + branch = 3.17.x +[submodule "deps/zlib"] + path = deps/zlib + url = https://github.com/madler/zlib.git + branch = develop diff --git a/deps/libtomcrypt b/deps/libtomcrypt new file mode 160000 index 00000000..673f5ce2 --- /dev/null +++ b/deps/libtomcrypt @@ -0,0 +1 @@ +Subproject commit 673f5ce29015a9bba3c96792920a10601b5b0718 diff --git a/deps/libtommath b/deps/libtommath new file mode 160000 index 00000000..66de8642 --- /dev/null +++ b/deps/libtommath @@ -0,0 +1 @@ +Subproject commit 66de86426e9cdb88526974c765108f01554af2b0 diff --git a/deps/protobuf b/deps/protobuf new file mode 160000 index 00000000..5500c72c --- /dev/null +++ b/deps/protobuf @@ -0,0 +1 @@ +Subproject commit 5500c72c5b616da9f0125bcfab513987a1226e2b diff --git a/deps/zlib b/deps/zlib new file mode 160000 index 00000000..2014a993 --- /dev/null +++ b/deps/zlib @@ -0,0 +1 @@ +Subproject commit 2014a993addbc8f1b9785d97f55fd189792c2f78 From 3a65d1d923426163d732d49f955397783b879324 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 16 Mar 2022 05:43:54 -0700 Subject: [PATCH 107/346] Merge develop into rich-presence (#30) * Bump deps/asmjit from `6efd4d5` to `f1a399c` Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `6efd4d5` to `f1a399c`. - [Release notes](https://github.com/asmjit/asmjit/releases) - [Commits](https://github.com/asmjit/asmjit/compare/6efd4d563dee6832224295fa3bbf1647964246c4...f1a399c4fe74d1535a4190a2b8727c51045cc914) --- updated-dependencies: - dependency-name: deps/asmjit dependency-type: direct:production ... Signed-off-by: dependabot[bot] * Custom material stupport * Remove this * Dont try to load 'white' material * removed git protocol submodules [skip ci] * readd submodules via http protocol Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Federico Cecchetto Co-authored-by: fed <58637860+fedddddd@users.noreply.github.com> --- .gitmodules | 15 +-- deps/asmjit | 2 +- src/client/component/materials.cpp | 172 +++++++++++++++++++++++++++++ src/client/component/materials.hpp | 6 + src/client/game/structs.hpp | 80 +++++++++++++- src/client/game/symbols.hpp | 5 +- 6 files changed, 270 insertions(+), 10 deletions(-) create mode 100644 src/client/component/materials.cpp create mode 100644 src/client/component/materials.hpp diff --git a/.gitmodules b/.gitmodules index 7230acd8..e92c76fd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,19 +28,20 @@ [submodule "deps/stb"] path = deps/stb url = https://github.com/nothings/stb.git + branch = develop [submodule "deps/libtomcrypt"] path = deps/libtomcrypt - url = git://github.com/libtom/libtomcrypt.git - branch = develop -[submodule "deps/zlib"] - path = deps/zlib - url = git://github.com/madler/zlib.git + url = https://github.com/libtom/libtomcrypt.git branch = develop [submodule "deps/libtommath"] path = deps/libtommath - url = git://github.com/libtom/libtommath.git + url = https://github.com/libtom/libtommath.git branch = develop [submodule "deps/protobuf"] path = deps/protobuf - url = git://github.com/protocolbuffers/protobuf.git + url = https://github.com/protocolbuffers/protobuf.git branch = 3.17.x +[submodule "deps/zlib"] + path = deps/zlib + url = https://github.com/madler/zlib.git + branch = develop diff --git a/deps/asmjit b/deps/asmjit index 6efd4d56..f1a399c4 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit 6efd4d563dee6832224295fa3bbf1647964246c4 +Subproject commit f1a399c4fe74d1535a4190a2b8727c51045cc914 diff --git a/src/client/component/materials.cpp b/src/client/component/materials.cpp new file mode 100644 index 00000000..287238c0 --- /dev/null +++ b/src/client/component/materials.cpp @@ -0,0 +1,172 @@ +#include +#include "loader/component_loader.hpp" + +#include "materials.hpp" +#include "console.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include +#include +#include +#include + +namespace materials +{ + namespace + { + utils::hook::detour db_material_streaming_fail_hook; + utils::hook::detour material_register_handle_hook; + + struct material_data_t + { + std::unordered_map materials; + std::unordered_map images; + }; + + utils::concurrency::container material_data; + + game::GfxImage* setup_image(game::GfxImage* image, const utils::image& raw_image) + { + image->imageFormat = 0x1000003; + image->resourceSize = -1; + + D3D11_SUBRESOURCE_DATA data{}; + data.SysMemPitch = raw_image.get_width() * 4; + data.SysMemSlicePitch = data.SysMemPitch * raw_image.get_height(); + data.pSysMem = raw_image.get_buffer(); + + game::Image_Setup(image, raw_image.get_width(), raw_image.get_height(), image->depth, image->numElements, + image->imageFormat, DXGI_FORMAT_R8G8B8A8_UNORM, image->name, &data); + + return image; + } + + game::Material* create_material(const std::string& name, const std::string& data) + { + const auto white = *reinterpret_cast(SELECT_VALUE(0x141F3D860, 0x14282C330)); + + const auto material = utils::memory::get_allocator()->allocate(); + const auto texture_table = utils::memory::get_allocator()->allocate(); + const auto image = utils::memory::get_allocator()->allocate(); + + std::memcpy(material, white, sizeof(game::Material)); + std::memcpy(texture_table, white->textureTable, sizeof(game::MaterialTextureDef)); + std::memcpy(image, white->textureTable->u.image, sizeof(game::GfxImage)); + + material->name = utils::memory::get_allocator()->duplicate_string(name); + image->name = material->name; + + material->textureTable = texture_table; + material->textureTable->u.image = setup_image(image, data); + + return material; + } + + game::Material* load_material(const std::string& name) + { + return material_data.access([&](material_data_t& data_) -> game::Material* + { + if (const auto i = data_.materials.find(name); i != data_.materials.end()) + { + return i->second; + } + + std::string data{}; + if (const auto i = data_.images.find(name); i != data_.images.end()) + { + data = i->second; + } + + if (data.empty() + && !utils::io::read_file(utils::string::va("h1-mod/materials/%s.png", name.data()), &data) + && !utils::io::read_file(utils::string::va("data/materials/%s.png", name.data()), &data)) + { + return nullptr; + } + + const auto material = create_material(name, data); + data_.materials[name] = material; + + return material; + }); + } + + game::Material* try_load_material(const std::string& name) + { + if (name == "white") + { + return nullptr; + } + + try + { + return load_material(name); + } + catch (const std::exception& e) + { + console::error("Failed to load material %s: %s\n", name.data(), e.what()); + } + + return nullptr; + } + + game::Material* material_register_handle_stub(const char* name) + { + auto result = try_load_material(name); + if (result == nullptr) + { + result = material_register_handle_hook.invoke(name); + } + return result; + } + + bool db_material_streaming_fail_stub(game::Material* material) + { + const auto found = material_data.access([material](material_data_t& data_) + { + if (data_.materials.find(material->name) != data_.materials.end()) + { + return true; + } + + return false; + }); + + if (found) + { + return false; + } + + return db_material_streaming_fail_hook.invoke(material); + } + } + + void add(const std::string& name, const std::string& data) + { + material_data.access([&](material_data_t& data_) + { + data_.images[name] = data; + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_dedi()) + { + return; + } + + material_register_handle_hook.create(game::Material_RegisterHandle, material_register_handle_stub); + db_material_streaming_fail_hook.create(SELECT_VALUE(0x1401D3180, 0x1402C6260), db_material_streaming_fail_stub); + } + }; +} + +REGISTER_COMPONENT(materials::component) diff --git a/src/client/component/materials.hpp b/src/client/component/materials.hpp new file mode 100644 index 00000000..ac58b511 --- /dev/null +++ b/src/client/component/materials.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace materials +{ + void add(const std::string& name, const std::string& data); +} diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 3437a026..bb7c3aec 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1101,11 +1101,90 @@ namespace game int forceTechType; }; + struct GfxImage; + + union MaterialTextureDefInfo + { + GfxImage* image; + void* water; + }; + + struct MaterialTextureDef + { + unsigned int nameHash; + char nameStart; + char nameEnd; + char samplerState; + char semantic; + MaterialTextureDefInfo u; + }; + + struct MaterialPass + { + void* vertexShader; + void* vertexDecl; + void* hullShader; + void* domainShader; + void* pixelShader; + char pixelOutputMask; + char perPrimArgCount; + char perObjArgCount; + char stableArgCount; + unsigned __int16 perPrimArgSize; + unsigned __int16 perObjArgSize; + unsigned __int16 stableArgSize; + char zone; + char perPrimConstantBuffer; + char perObjConstantBuffer; + char stableConstantBuffer; + unsigned int customBufferFlags; + char customSamplerFlags; + char precompiledIndex; + char stageConfig; + void* args; + }; + + struct MaterialTechnique + { + const char* name; + unsigned __int16 flags; + unsigned __int16 passCount; + MaterialPass passArray[1]; + }; + + struct MaterialTechniqueSet + { + const char* name; + unsigned __int16 flags; + char worldVertFormat; + char preDisplacementOnlyCount; + MaterialTechnique* techniques[309]; + }; + + struct GfxStateBits + { + unsigned int loadBits[3]; + char zone; + char depthStencilState[11]; + char blendState; + char rasterizerState; + }; + struct Material { const char* name; + char __pad0[0x118]; + char textureCount; + char __pad1[7]; + MaterialTechniqueSet* techniqueSet; + MaterialTextureDef* textureTable; + void* constantTable; + GfxStateBits* stateBitsTable; + char __pad2[0x108]; }; + static_assert(sizeof(Material) == 0x250); + struct Glyph { unsigned short letter; @@ -1252,7 +1331,6 @@ namespace game GfxImageLoadDef* loadDef; }; - struct GfxTexture { $3FA29451CE6F1FA138A5ABAB84BE9676 ___u0; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 257bbf15..9381150a 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -121,6 +121,9 @@ namespace game #define R_AddCmdDrawTextWithCursor(TXT, MC, F, UNK, X, Y, XS, YS, R, C, S, CP, CC) \ H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S, CP, CC, game::R_DrawSomething(S)) + WEAK symbol Image_Setup{0x1404D7D50, 0x1405DCF90}; + WEAK symbol VM_Execute{0x140376360, 0x140444350}; @@ -138,7 +141,7 @@ namespace game WEAK symbol DB_EnumXAssets_Internal{0x1401C9C10, 0x1402BA830}; - WEAK symbol DB_GetXAssetName{0x14019A390, 0x14028BE50}; + WEAK symbol DB_GetXAssetName{0x14019A390, 0x14028BE50}; WEAK symbol DB_GetXAssetTypeSize{0x14019A3B0, 0x14028BE70}; WEAK symbol Date: Thu, 17 Mar 2022 02:35:10 +0200 Subject: [PATCH 108/346] stuff --- src/client/component/arxan.cpp | 164 ++++ src/client/component/auth.cpp | 25 +- src/client/component/binding.cpp | 138 ---- src/client/component/bots.cpp | 103 --- src/client/component/branding.cpp | 65 -- src/client/component/colors.cpp | 182 ----- src/client/component/command.cpp | 648 ---------------- src/client/component/command.hpp | 50 -- src/client/component/console.cpp | 299 -------- src/client/component/console.hpp | 35 - src/client/component/dedicated.cpp | 333 -------- src/client/component/dedicated_info.cpp | 65 -- src/client/component/demonware.cpp | 604 --------------- src/client/component/demonware.hpp | 6 - src/client/component/discord.cpp | 148 ---- src/client/component/dvars.cpp | 443 ----------- src/client/component/dvars.hpp | 28 - src/client/component/exception.cpp | 261 ------- src/client/component/fastfiles.cpp | 49 -- src/client/component/fastfiles.hpp | 8 - src/client/component/filesystem.cpp | 94 --- src/client/component/filesystem.hpp | 19 - src/client/component/fps.cpp | 174 ----- src/client/component/game_console.cpp | 793 -------------------- src/client/component/game_console.hpp | 7 - src/client/component/game_module.cpp | 3 +- src/client/component/localized_strings.cpp | 52 -- src/client/component/localized_strings.hpp | 6 - src/client/component/logfile.cpp | 317 -------- src/client/component/logfile.hpp | 13 - src/client/component/lui.cpp | 58 -- src/client/component/map_rotation.cpp | 180 ----- src/client/component/network.cpp | 11 +- src/client/component/party.cpp | 630 ---------------- src/client/component/party.hpp | 17 - src/client/component/patches.cpp | 293 -------- src/client/component/renderer.cpp | 77 -- src/client/component/scheduler.cpp | 8 +- src/client/component/scripting.cpp | 141 ---- src/client/component/scripting.hpp | 8 - src/client/component/server_list.cpp | 443 ----------- src/client/component/server_list.hpp | 12 - src/client/component/shaders.cpp | 50 -- src/client/component/slowmotion.cpp | 53 -- src/client/component/splash.cpp | 141 ---- src/client/component/system_check.cpp | 25 +- src/client/component/thread_names.cpp | 60 -- src/client/component/ui_scripting.cpp | 180 ----- src/client/component/ui_scripting.hpp | 12 - src/client/component/updater.cpp | 474 ------------ src/client/component/updater.hpp | 26 - src/client/component/videos.cpp | 55 -- src/client/component/virtuallobby.cpp | 63 -- src/client/loader/loader.cpp | 7 +- src/client/loader/loader.hpp | 2 +- src/client/resources/ui_scripts/common.lua | 164 ---- src/client/resources/ui_scripts/updater.lua | 164 ---- 57 files changed, 200 insertions(+), 8286 deletions(-) create mode 100644 src/client/component/arxan.cpp delete mode 100644 src/client/component/binding.cpp delete mode 100644 src/client/component/bots.cpp delete mode 100644 src/client/component/branding.cpp delete mode 100644 src/client/component/colors.cpp delete mode 100644 src/client/component/command.cpp delete mode 100644 src/client/component/command.hpp delete mode 100644 src/client/component/console.cpp delete mode 100644 src/client/component/console.hpp delete mode 100644 src/client/component/dedicated.cpp delete mode 100644 src/client/component/dedicated_info.cpp delete mode 100644 src/client/component/demonware.cpp delete mode 100644 src/client/component/demonware.hpp delete mode 100644 src/client/component/discord.cpp delete mode 100644 src/client/component/dvars.cpp delete mode 100644 src/client/component/dvars.hpp delete mode 100644 src/client/component/exception.cpp delete mode 100644 src/client/component/fastfiles.cpp delete mode 100644 src/client/component/fastfiles.hpp delete mode 100644 src/client/component/filesystem.cpp delete mode 100644 src/client/component/filesystem.hpp delete mode 100644 src/client/component/fps.cpp delete mode 100644 src/client/component/game_console.cpp delete mode 100644 src/client/component/game_console.hpp delete mode 100644 src/client/component/localized_strings.cpp delete mode 100644 src/client/component/localized_strings.hpp delete mode 100644 src/client/component/logfile.cpp delete mode 100644 src/client/component/logfile.hpp delete mode 100644 src/client/component/lui.cpp delete mode 100644 src/client/component/map_rotation.cpp delete mode 100644 src/client/component/party.cpp delete mode 100644 src/client/component/party.hpp delete mode 100644 src/client/component/patches.cpp delete mode 100644 src/client/component/renderer.cpp delete mode 100644 src/client/component/scripting.cpp delete mode 100644 src/client/component/scripting.hpp delete mode 100644 src/client/component/server_list.cpp delete mode 100644 src/client/component/server_list.hpp delete mode 100644 src/client/component/shaders.cpp delete mode 100644 src/client/component/slowmotion.cpp delete mode 100644 src/client/component/splash.cpp delete mode 100644 src/client/component/thread_names.cpp delete mode 100644 src/client/component/ui_scripting.cpp delete mode 100644 src/client/component/ui_scripting.hpp delete mode 100644 src/client/component/updater.cpp delete mode 100644 src/client/component/updater.hpp delete mode 100644 src/client/component/videos.cpp delete mode 100644 src/client/component/virtuallobby.cpp delete mode 100644 src/client/resources/ui_scripts/common.lua delete mode 100644 src/client/resources/ui_scripts/updater.lua diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp new file mode 100644 index 00000000..adff7199 --- /dev/null +++ b/src/client/component/arxan.cpp @@ -0,0 +1,164 @@ +#include +#include "loader/component_loader.hpp" +#include "scheduler.hpp" +#include "game/game.hpp" + +#include + +namespace arxan +{ + namespace + { + utils::hook::detour nt_close_hook; + utils::hook::detour nt_query_information_process_hook; + + NTSTATUS WINAPI nt_query_information_process_stub(const HANDLE handle, const PROCESSINFOCLASS info_class, + const PVOID info, + const ULONG info_length, const PULONG ret_length) + { + auto* orig = static_cast(nt_query_information_process_hook. + get_original()); + const auto status = orig(handle, info_class, info, info_length, ret_length); + + if (NT_SUCCESS(status)) + { + if (info_class == ProcessBasicInformation) + { + static DWORD explorer_pid = 0; + if (!explorer_pid) + { + auto* const shell_window = GetShellWindow(); + GetWindowThreadProcessId(shell_window, &explorer_pid); + } + + static_cast(info)->Reserved3 = PVOID(DWORD64(explorer_pid)); + } + else if (info_class == 30) // ProcessDebugObjectHandle + { + *static_cast(info) = nullptr; + + return 0xC0000353; + } + else if (info_class == 7) // ProcessDebugPort + { + *static_cast(info) = nullptr; + } + else if (info_class == 31) + { + *static_cast(info) = 1; + } + } + + return status; + } + + NTSTATUS NTAPI nt_close_stub(const HANDLE handle) + { + char info[16]; + if (NtQueryObject(handle, OBJECT_INFORMATION_CLASS(4), &info, 2, nullptr) >= 0 && size_t(handle) != 0x12345) + { + auto* orig = static_cast(nt_close_hook.get_original()); + return orig(handle); + } + + return STATUS_INVALID_HANDLE; + } + + LONG WINAPI exception_filter(const LPEXCEPTION_POINTERS info) + { + if (info->ExceptionRecord->ExceptionCode == STATUS_INVALID_HANDLE) + { + return EXCEPTION_CONTINUE_EXECUTION; + } + + return EXCEPTION_CONTINUE_SEARCH; + } + + void hide_being_debugged() + { + auto* const peb = PPEB(__readgsqword(0x60)); + peb->BeingDebugged = false; + *reinterpret_cast(LPSTR(peb) + 0xBC) &= ~0x70; + } + + void remove_hardware_breakpoints() + { + CONTEXT context; + ZeroMemory(&context, sizeof(context)); + context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + + auto* const thread = GetCurrentThread(); + GetThreadContext(thread, &context); + + context.Dr0 = 0; + context.Dr1 = 0; + context.Dr2 = 0; + context.Dr3 = 0; + context.Dr6 = 0; + context.Dr7 = 0; + + SetThreadContext(thread, &context); + } + + BOOL WINAPI set_thread_context_stub(const HANDLE thread, CONTEXT* context) + { + if (!game::environment::is_sp() + && game::dwGetLogOnStatus() == game::DW_LIVE_CONNECTED + && context->ContextFlags == CONTEXT_DEBUG_REGISTERS) + { + return TRUE; + } + + return SetThreadContext(thread, context); + } + } + + int just_return() + { + return 1; + } + + class component final : public component_interface + { + public: + void* load_import(const std::string& library, const std::string& function) override + { + if (function == "SetThreadContext") + { + //return set_thread_context_stub; + } + + if (function == "LoadStringA" || function == "LoadStringW") + { + return just_return; + } + + return nullptr; + } + + void post_load() override + { + hide_being_debugged(); + scheduler::loop(hide_being_debugged, scheduler::pipeline::async); + + const utils::nt::library ntdll("ntdll.dll"); + nt_close_hook.create(ntdll.get_proc("NtClose"), nt_close_stub); + nt_query_information_process_hook.create(ntdll.get_proc("NtQueryInformationProcess"), + nt_query_information_process_stub); + + AddVectoredExceptionHandler(1, exception_filter); + } + + void post_unpack() override + { + // cba to implement sp, not sure if it's even needed + if (game::environment::is_sp()) return; + + // some of arxan crashes + utils::hook::nop(0x14CDEFCAA, 6); + utils::hook::call(0x1405BCAD1, &just_return); + } + }; +} + +REGISTER_COMPONENT(arxan::component) \ No newline at end of file diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 346c8d80..c5aa8240 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -42,7 +42,7 @@ namespace auth std::string get_protected_data() { - std::string input = "X-Labs-H1Mod-Auth"; + std::string input = "X-Labs-H1STEAM-Auth"; DATA_BLOB data_in{}, data_out{}; data_in.pbData = reinterpret_cast(input.data()); @@ -177,21 +177,20 @@ namespace auth game::SV_DirectConnect(from); } - // CAN'T FIND //void* get_direct_connect_stub() //{ // return utils::hook::assemble([](utils::hook::assembler& a) - // { - // a.lea(rcx, qword_ptr(rsp, 0x20)); - // a.movaps(xmmword_ptr(rsp, 0x20), xmm0); + // { + // a.lea(rcx, qword_ptr(rsp, 0x20)); + // a.movaps(xmmword_ptr(rsp, 0x20), xmm0); - // a.pushad64(); - // a.mov(rdx, rsi); - // a.call_aligned(direct_connect); - // a.popad64(); + // a.pushad64(); + // a.mov(rdx, rsi); + // a.call_aligned(direct_connect); + // a.popad64(); - // a.jmp(0x140488CE2); // H1MP64(1.4) - // }); + // a.jmp(0x140488CE2); // H1MP64(1.4) + // }); //} } @@ -225,8 +224,8 @@ namespace auth utils::hook::jump(0x1D7542_b, 0x1D7587_b); // STEAM MAYBE `1401D7553` ON FIRST utils::hook::jump(0x1D7A82_b, 0x1D7AC8_b); // STEAM - //utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) can't find - utils::hook::call(0x12D437_b, send_connect_data_stub); // H1(1.4) + //utils::hook::jump(0x1401CAE70, get_direct_connect_stub(), true); // STEAM + utils::hook::call(0x12D437_b, send_connect_data_stub); // STEAM // Skip checks for sending connect packet utils::hook::jump(0x1402508FC, 0x140250946); diff --git a/src/client/component/binding.cpp b/src/client/component/binding.cpp deleted file mode 100644 index e40b7f42..00000000 --- a/src/client/component/binding.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "game/game.hpp" - -#include -#include - -namespace binding -{ - namespace - { - std::vector custom_binds = {}; - - utils::hook::detour cl_execute_key_hook; - - int get_num_keys() - { - return SELECT_VALUE(102, 103); - } - - int key_write_bindings_to_buffer_stub(int /*localClientNum*/, char* buffer, const int buffer_size) - { - auto bytes_used = 0; - const auto buffer_size_align = static_cast(buffer_size) - 4; - - for (auto key_index = 0; key_index < 256; ++key_index) - { - const auto* const key_button = game::Key_KeynumToString(key_index, 0, 1); - auto value = game::playerKeys->keys[key_index].binding; - - if (value && value < get_num_keys()) - { - const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used), - "bind %s \"%s\"\n", key_button, game::command_whitelist[value]); - - if (len < 0) - { - return bytes_used; - } - - bytes_used += len; - } - else if (value >= get_num_keys()) - { - value -= get_num_keys(); - if (static_cast(value) < custom_binds.size() && !custom_binds[value].empty()) - { - const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used), - "bind %s \"%s\"\n", key_button, custom_binds[value].data()); - - if (len < 0) - { - return bytes_used; - } - - bytes_used += len; - } - } - } - - buffer[bytes_used] = 0; - return bytes_used; - } - - int get_binding_for_custom_command(const char* command) - { - auto index = 0; - for (auto& bind : custom_binds) - { - if (bind == command) - { - return index; - } - index++; - } - - custom_binds.emplace_back(command); - index = static_cast(custom_binds.size()) - 1; - - return index; - } - - int key_get_binding_for_cmd_stub(const char* command) - { - // original binds - for (auto i = 0; i <= get_num_keys(); i++) - { - if (game::command_whitelist[i] && !strcmp(command, game::command_whitelist[i])) - { - return i; - } - } - - // custom binds - return get_num_keys() + get_binding_for_custom_command(command); - } - - void cl_execute_key_stub(const int local_client_num, int key, const int down, const int time) - { - if (key >= get_num_keys()) - { - key -= get_num_keys(); - - if (static_cast(key) < custom_binds.size() && !custom_binds[key].empty()) - { - game::Cbuf_AddText(local_client_num, utils::string::va("%s\n", custom_binds[key].data())); - } - - return; - } - - cl_execute_key_hook.invoke(local_client_num, key, down, time); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_dedi()) - { - return; - } - - // write all bindings to config file - utils::hook::call(SELECT_VALUE(0x1401881DB, 0x14025032F), key_write_bindings_to_buffer_stub); // H1(1.4) - - // links a custom command to an index - utils::hook::jump(SELECT_VALUE(0x140343C00, 0x1404041E0), key_get_binding_for_cmd_stub); // H1(1.4) - - // execute custom binds - cl_execute_key_hook.create(SELECT_VALUE(0x140183C70, 0x14024ACF0), &cl_execute_key_stub); // H1(1.4) - } - }; -} - -REGISTER_COMPONENT(binding::component) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp deleted file mode 100644 index 81f74628..00000000 --- a/src/client/component/bots.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "command.hpp" -#include "scheduler.hpp" -#include "network.hpp" -#include "party.hpp" - -#include "game/game.hpp" -#include "game/scripting/execution.hpp" - -#include -#include -#include - -namespace bots -{ - namespace - { - bool can_add() - { - if (party::get_client_count() < *game::mp::svs_numclients) - { - return true; - } - return false; - } - - // TODO: when scripting comes, fix this to use better notifies - void bot_team_join(const int entity_num) - { - const game::scr_entref_t entref{static_cast(entity_num), 0}; - scheduler::once([entref]() - { - scripting::notify(entref, "luinotifyserver", {"team_select", 2}); - scheduler::once([entref]() - { - auto* _class = utils::string::va("class%d", utils::cryptography::random::get_integer() % 5); - scripting::notify(entref, "luinotifyserver", {"class_select", _class}); - }, scheduler::pipeline::server, 2s); - }, scheduler::pipeline::server, 2s); - } - - void spawn_bot(const int entity_num) - { - game::SV_SpawnTestClient(&game::mp::g_entities[entity_num]); - if (game::Com_GetCurrentCoDPlayMode() == game::CODPLAYMODE_CORE) - { - bot_team_join(entity_num); - } - } - - void add_bot() - { - if (!can_add()) - { - return; - } - - // SV_BotGetRandomName - const auto* const bot_name = game::SV_BotGetRandomName(); - auto* bot_ent = game::SV_AddBot(bot_name); - if (bot_ent) - { - spawn_bot(bot_ent->s.entityNum); - } - else if (can_add()) // workaround since first bot won't ever spawn - { - add_bot(); - } - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_sp()) - { - return; - } - - command::add("spawnBot", [](const command::params& params) - { - if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) return; - - auto num_bots = 1; - if (params.size() == 2) - { - num_bots = atoi(params.get(1)); - } - - for (auto i = 0; i < (num_bots > *game::mp::svs_numclients ? *game::mp::svs_numclients : num_bots); i++) - { - scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i); - } - }); - } - }; -} - -REGISTER_COMPONENT(bots::component) \ No newline at end of file diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp deleted file mode 100644 index 2f74693b..00000000 --- a/src/client/component/branding.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "localized_strings.hpp" -#include "scheduler.hpp" -#include "command.hpp" -#include "version.hpp" - -#include "game/game.hpp" -#include "dvars.hpp" - -#include -#include - -// fonts/default.otf, fonts/defaultBold.otf, fonts/fira_mono_regular.ttf, fonts/fira_mono_bold.ttf - -namespace branding -{ - namespace - { - utils::hook::detour ui_get_formatted_build_number_hook; - - float color[4] = {0.666f, 0.666f, 0.666f, 0.666f}; - - const char* ui_get_formatted_build_number_stub() - { - const auto* const build_num = ui_get_formatted_build_number_hook.invoke(); - return utils::string::va("%s (%s)", VERSION, build_num); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - - if (game::environment::is_dedi()) - { - return; - } - - if (game::environment::is_mp()) - { - localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n"); - localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER"); - } - - dvars::override::set_string("version", utils::string::va("H1-Mod %s", VERSION)); - - ui_get_formatted_build_number_hook.create( - SELECT_VALUE(0x1403B1C40, 0x1404E74C0), ui_get_formatted_build_number_stub); - - scheduler::loop([]() - { - const auto font = game::R_RegisterFont("fonts/fira_mono_bold.ttf", 20); - - game::R_AddCmdDrawText("H1-Mod: " VERSION, 0x7FFFFFFF, font, 10.f, - 5.f + static_cast(font->pixelHeight), 1.f, 1.f, 0.0f, color, 0); - }, scheduler::pipeline::renderer); - } - }; -} - -REGISTER_COMPONENT(branding::component) diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp deleted file mode 100644 index 75eff23a..00000000 --- a/src/client/component/colors.cpp +++ /dev/null @@ -1,182 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" - -#include -#include - -namespace colors -{ - struct hsv_color - { - unsigned char h; - unsigned char s; - unsigned char v; - }; - - namespace - { - std::vector color_table; - - DWORD hsv_to_rgb(const hsv_color hsv) - { - DWORD rgb; - - if (hsv.s == 0) - { - return RGB(hsv.v, hsv.v, hsv.v); - } - - // converting to 16 bit to prevent overflow - const unsigned int h = hsv.h; - const unsigned int s = hsv.s; - const unsigned int v = hsv.v; - - const auto region = static_cast(h / 43); - const auto remainder = (h - (region * 43)) * 6; - - const auto p = static_cast((v * (255 - s)) >> 8); - const auto q = static_cast( - (v * (255 - ((s * remainder) >> 8))) >> 8); - const auto t = static_cast( - (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8); - - switch (region) - { - case 0: - rgb = RGB(v, t, p); - break; - case 1: - rgb = RGB(q, v, p); - break; - case 2: - rgb = RGB(p, v, t); - break; - case 3: - rgb = RGB(p, q, v); - break; - case 4: - rgb = RGB(t, p, v); - break; - default: - rgb = RGB(v, p, q); - break; - } - - return rgb; - } - - int color_index(const char c) - { - const auto index = c - 48; - return index >= 0xC ? 7 : index; - } - - char add(const uint8_t r, const uint8_t g, const uint8_t b) - { - const char index = '0' + static_cast(color_table.size()); - color_table.push_back(RGB(r, g, b)); - return index; - } - - void com_clean_name_stub(const char* in, char* out, const int out_size) - { - strncpy_s(out, out_size, in, _TRUNCATE); - } - - char* i_clean_str_stub(char* string) - { - utils::string::strip(string, string, static_cast(strlen(string)) + 1); - - return string; - } - - size_t get_client_name_stub(const int local_client_num, const int index, char* buf, const int size, - const size_t unk, const size_t unk2) - { - // CL_GetClientName (CL_GetClientNameAndClantag?) - const auto result = utils::hook::invoke(0x14025BAA0, local_client_num, index, buf, size, unk, unk2); - - utils::string::strip(buf, buf, size); - - return result; - } - - void rb_lookup_color_stub(const char index, DWORD* color) - { - *color = RGB(255, 255, 255); - - if (index == '8') - { - *color = *reinterpret_cast(SELECT_VALUE(0x14F142FF8, 0x14FE70634)); // H1(1.4) - } - else if (index == '9') - { - *color = *reinterpret_cast(SELECT_VALUE(0x14F142FFC, 0x14FE70638)); // H1(1.4) - } - else if (index == ':') - { - *color = hsv_to_rgb({static_cast((game::Sys_Milliseconds() / 100) % 256), 255, 255}); - } - else if (index == ';') - { - *color = *reinterpret_cast(SELECT_VALUE(0x14F143004, 0x14FE70640)); // H1(1.4) - } - else if (index == '<') - { - *color = 0xFFFCFF80; - } - else - { - *color = color_table[color_index(index)]; - } - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_dedi()) - { - return; - } - - if (!game::environment::is_sp()) - { - // allows colored name in-game - utils::hook::jump(0x140503810, com_clean_name_stub); // H1(1.4) - - // don't apply colors to overhead names - utils::hook::call(0x1400AB416, get_client_name_stub); // H1(1.4) - - // patch I_CleanStr - utils::hook::jump(0x140503D00, i_clean_str_stub); // H1(1.4) - } - - // force new colors - utils::hook::jump(SELECT_VALUE(0x140524BD0, 0x1406206A0), rb_lookup_color_stub); // H1(1.4) - - // add colors - add(0, 0, 0); // 0 - Black - add(255, 49, 49); // 1 - Red - add(134, 192, 0); // 2 - Green - add(255, 173, 34); // 3 - Yellow - add(0, 135, 193); // 4 - Blue - add(32, 197, 255); // 5 - Light Blue - add(151, 80, 221); // 6 - Pink - add(255, 255, 255); // 7 - White - - add(0, 0, 0); // 8 - Team color (axis?) - add(0, 0, 0); // 9 - Team color (allies?) - - add(0, 0, 0); // 10 - Rainbow (:) - add(0, 0, 0); - // 11 - Server color (;) - using that color in infostrings (e.g. your name) fails, ';' is an illegal character! - } - }; -} - -REGISTER_COMPONENT(colors::component) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp deleted file mode 100644 index b5c1ad40..00000000 --- a/src/client/component/command.cpp +++ /dev/null @@ -1,648 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "command.hpp" -#include "console.hpp" -#include "game_console.hpp" - -#include "game/game.hpp" - -#include -#include -#include -#include "utils/io.hpp" -#include - -namespace command -{ - namespace - { - utils::hook::detour client_command_hook; - - std::unordered_map> handlers; - std::unordered_map> handlers_sv; - - void main_handler() - { - params params = {}; - - const auto command = utils::string::to_lower(params[0]); - if (handlers.find(command) != handlers.end()) - { - handlers[command](params); - } - } - - void client_command(const int client_num, void* a2) - { - params_sv params = {}; - - const auto command = utils::string::to_lower(params[0]); - if (handlers_sv.find(command) != handlers_sv.end()) - { - handlers_sv[command](client_num, params); - } - - client_command_hook.invoke(client_num, a2); - } - - // Shamelessly stolen from Quake3 - // https://github.com/id-Software/Quake-III-Arena/blob/dbe4ddb10315479fc00086f08e25d968b4b43c49/code/qcommon/common.c#L364 - void parse_command_line() - { - static auto parsed = false; - if (parsed) - { - return; - } - - static std::string comand_line_buffer = GetCommandLineA(); - auto* command_line = comand_line_buffer.data(); - - auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); //H1(1.4) - auto* com_console_lines = reinterpret_cast(0x142623FC0); //H1(1.4) - - auto inq = false; - com_console_lines[0] = command_line; - com_num_console_lines = 0; - - while (*command_line) - { - if (*command_line == '"') - { - inq = !inq; - } - // look for a + separating character - // if commandLine came from a file, we might have real line seperators - if ((*command_line == '+' && !inq) || *command_line == '\n' || *command_line == '\r') - { - if (com_num_console_lines == 0x20) // MAX_CONSOLE_LINES - { - break; - } - com_console_lines[com_num_console_lines] = command_line + 1; - com_num_console_lines++; - *command_line = '\0'; - } - command_line++; - } - parsed = true; - } - - void parse_commandline_stub() - { - parse_command_line(); - utils::hook::invoke(0x1400D8210); - } - - game::dvar_t* dvar_command_stub() - { - const params args; - - if (args.size() <= 0) - { - return 0; - } - - const auto dvar = game::Dvar_FindVar(args[0]); - - if (dvar) - { - if (args.size() == 1) - { - const auto current = game::Dvar_ValueToString(dvar, dvar->current); - const auto reset = game::Dvar_ValueToString(dvar, dvar->reset); - - console::info("\"%s\" is: \"%s\" default: \"%s\" hash: 0x%08lX", - args[0], current, reset, dvar->hash); - - console::info(" %s\n", dvars::dvar_get_domain(dvar->type, dvar->domain).data()); - } - else - { - char command[0x1000] = { 0 }; - game::Dvar_GetCombinedString(command, 1); - game::Dvar_SetCommand(dvar->hash, "", command); - } - - return dvar; - } - - return 0; - } - } - - void read_startup_variable(const std::string& dvar) - { - // parse the commandline if it's not parsed - parse_command_line(); - - auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); //H1(1.4) - auto* com_console_lines = reinterpret_cast(0x142623FC0); //H1(1.4) - - for (int i = 0; i < com_num_console_lines; i++) - { - game::Cmd_TokenizeString(com_console_lines[i]); - - // only +set dvar value - if (game::Cmd_Argc() >= 3 && game::Cmd_Argv(0) == "set"s && game::Cmd_Argv(1) == dvar) - { - game::Dvar_SetCommand(game::generateHashValue(game::Cmd_Argv(1)), "", game::Cmd_Argv(2)); - } - - game::Cmd_EndTokenizeString(); - } - } - - params::params() - : nesting_(game::cmd_args->nesting) - { - } - - int params::size() const - { - return game::cmd_args->argc[this->nesting_]; - } - - const char* params::get(const int index) const - { - if (index >= this->size()) - { - return ""; - } - - return game::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; - } - - params_sv::params_sv() - : nesting_(game::sv_cmd_args->nesting) - { - } - - 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; - } - - void add_raw(const char* name, void (*callback)()) - { - game::Cmd_AddCommandInternal(name, callback, utils::memory::get_allocator()->allocate()); - } - - void add_test(const char* name, void (*callback)()) - { - static game::cmd_function_s cmd_test; - return game::Cmd_AddCommandInternal(name, callback, &cmd_test); - } - - void add(const char* name, const std::function& callback) - { - static game::cmd_function_s cmd_test; - - const auto command = utils::string::to_lower(name); - - if (handlers.find(command) == handlers.end()) - add_raw(name, main_handler); - - handlers[command] = callback; - } - - void add(const char* name, const std::function& callback) - { - add(name, [callback](const params&) - { - callback(); - }); - } - - void add_sv(const char* name, std::function callback) - { - // doing this so the sv command would show up in the console - add_raw(name, nullptr); - - const auto command = utils::string::to_lower(name); - - if (handlers_sv.find(command) == handlers_sv.end()) - handlers_sv[command] = std::move(callback); - } - - void execute(std::string command, const bool sync) - { - command += "\n"; - - if (sync) - { - game::Cmd_ExecuteSingleCommand(0, 0, command.data()); - } - else - { - game::Cbuf_AddText(0, command.data()); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_sp()) - { - add_commands_sp(); - } - else - { - utils::hook::call(0x1400D728F, &parse_commandline_stub); // MWR TEST - utils::hook::jump(0x14041D750, dvar_command_stub); - - add_commands_mp(); - } - - add_commands_generic(); - } - - private: - static void add_commands_generic() - { - add("quit", game::Quit); - //add("quit_hard", utils::nt::raise_hard_exception); /* this command delivers you to a windows blue screen, its quit hard from windows xD */ - add("crash", []() - { - *reinterpret_cast(1) = 0; - }); - - /*add("consoleList", [](const params& params) - { - const std::string input = params.get(1); - - std::vector matches; - game_console::find_matches(input, matches, false); - - for (auto& match : matches) - { - auto* dvar = game::Dvar_FindVar(match.c_str()); - if (!dvar) - { - console::info("[CMD]\t %s\n", match.c_str()); - } - else - { - console::info("[DVAR]\t%s \"%s\"\n", match.c_str(), game::Dvar_ValueToString(dvar, dvar->current, 0)); - } - } - - console::info("Total %i matches\n", matches.size()); - });*/ - - add("commandDump", [](const params& argument) - { - console::info("================================ COMMAND DUMP =====================================\n"); - game::cmd_function_s* cmd = (*game::cmd_functions); - std::string filename; - if (argument.size() == 2) - { - filename = "h1-mod/"; - filename.append(argument[1]); - if (!filename.ends_with(".txt")) - { - filename.append(".txt"); - } - } - int i = 0; - while (cmd) - { - if (cmd->name) - { - if (!filename.empty()) - { - const auto line = std::format("{}\r\n", cmd->name); - utils::io::write_file(filename, line, i != 0); - } - console::info("%s\n", cmd->name); - i++; - } - cmd = cmd->next; - } - console::info("\n%i commands\n", i); - console::info("================================ END COMMAND DUMP =================================\n"); - }); - - /*add("listassetpool", [](const params& params) - { - if (params.size() < 2) - { - console::info("listassetpool [filter]: list all the assets in the specified pool\n"); - - for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++) - { - console::info("%d %s\n", i, game::g_assetNames[i]); - } - } - else - { - const auto type = static_cast(atoi(params.get(1))); - - if (type < 0 || type >= game::XAssetType::ASSET_TYPE_COUNT) - { - console::error("Invalid pool passed must be between [%d, %d]\n", 0, game::XAssetType::ASSET_TYPE_COUNT - 1); - return; - } - - console::info("Listing assets in pool %s\n", game::g_assetNames[type]); - - const std::string filter = params.get(2); - enum_assets(type, [type, filter](const game::XAssetHeader header) - { - const auto asset = game::XAsset{type, header}; - const auto* const asset_name = game::DB_GetXAssetName(&asset); - //const auto entry = game::DB_FindXAssetEntry(type, asset_name); - //TODO: display which zone the asset is from - - if (!filter.empty() && !game_console::match_compare(filter, asset_name, false)) - { - return; - } - - console::info("%s\n", asset_name); - }, true); - } - }); - - add("vstr", [](const params& params) - { - if (params.size() < 2) - { - console::info("vstr : execute a variable command\n"); - return; - } - - const auto* dvarName = params.get(1); - const auto* dvar = game::Dvar_FindVar(dvarName); - - if (dvar == nullptr) - { - console::info("%s doesn't exist\n", dvarName); - return; - } - - if (dvar->type != game::dvar_type::string - && dvar->type != game::dvar_type::enumeration) - { - console::info("%s is not a string-based dvar\n", dvar->hash); - return; - } - - execute(dvar->current.string); - });*/ - } - - static void add_commands_sp() - { - add("god", []() - { - if (!game::SV_Loaded()) - { - return; - } - - game::sp::g_entities[0].flags ^= 1; - game::CG_GameMessage(0, utils::string::va("godmode %s", - game::sp::g_entities[0].flags & 1 - ? "^2on" - : "^1off")); - }); - - add("demigod", []() - { - if (!game::SV_Loaded()) - { - return; - } - - game::sp::g_entities[0].flags ^= 2; - game::CG_GameMessage(0, utils::string::va("demigod mode %s", - game::sp::g_entities[0].flags & 2 - ? "^2on" - : "^1off")); - }); - - add("notarget", []() - { - if (!game::SV_Loaded()) - { - return; - } - - game::sp::g_entities[0].flags ^= 4; - game::CG_GameMessage(0, utils::string::va("notarget %s", - game::sp::g_entities[0].flags & 4 - ? "^2on" - : "^1off")); - }); - - add("noclip", []() - { - if (!game::SV_Loaded()) - { - return; - } - - game::sp::g_entities[0].client->flags ^= 1; - game::CG_GameMessage(0, utils::string::va("noclip %s", - game::sp::g_entities[0].client->flags & 1 - ? "^2on" - : "^1off")); - }); - - add("ufo", []() - { - if (!game::SV_Loaded()) - { - return; - } - - game::sp::g_entities[0].client->flags ^= 2; - game::CG_GameMessage(0, utils::string::va("ufo %s", - game::sp::g_entities[0].client->flags & 2 - ? "^2on" - : "^1off")); - }); - } - - static void add_commands_mp() - { - //client_command_hook.create(0x1402E98F0, &client_command); - - /*add_sv("god", [](const int client_num, const params_sv&) - { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) - { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); - return; - } - - game::mp::g_entities[client_num].flags ^= 1; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"godmode %s\"", - game::mp::g_entities[client_num].flags & 1 - ? "^2on" - : "^1off")); - }); - - add_sv("demigod", [](const int client_num, const params_sv&) - { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) - { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); - return; - } - - game::mp::g_entities[client_num].flags ^= 2; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"demigod mode %s\"", - game::mp::g_entities[client_num].flags & 2 - ? "^2on" - : "^1off")); - }); - - add_sv("notarget", [](const int client_num, const params_sv&) - { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) - { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); - return; - } - - game::mp::g_entities[client_num].flags ^= 4; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"notarget %s\"", - game::mp::g_entities[client_num].flags & 4 - ? "^2on" - : "^1off")); - }); - - add_sv("noclip", [](const int client_num, const params_sv&) - { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) - { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); - return; - } - - game::mp::g_entities[client_num].client->flags ^= 1; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"noclip %s\"", - game::mp::g_entities[client_num].client->flags & 1 - ? "^2on" - : "^1off")); - }); - - add_sv("ufo", [](const int client_num, const params_sv&) - { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) - { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); - return; - } - - game::mp::g_entities[client_num].client->flags ^= 2; - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - utils::string::va("f \"ufo %s\"", - game::mp::g_entities[client_num].client->flags & 2 - ? "^2on" - : "^1off")); - }); - - add_sv("give", [](const int client_num, const params_sv& params) - { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) - { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); - return; - } - - if (params.size() < 2) - { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"You did not specify a weapon name\""); - return; - } - - auto ps = game::SV_GetPlayerstateForClientNum(client_num); - const auto wp = game::G_GetWeaponForName(params.get(1)); - if (wp) - { - if (game::G_GivePlayerWeapon(ps, wp, 0, 0, 0, 0, 0, 0)) - { - game::G_InitializeAmmo(ps, wp, 0); - game::G_SelectWeapon(client_num, wp); - } - } - }); - - add_sv("take", [](const int client_num, const params_sv& params) - { - if (!game::Dvar_FindVar("sv_cheats")->current.enabled) - { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"Cheats are not enabled on this server\""); - return; - } - - if (params.size() < 2) - { - game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, - "f \"You did not specify a weapon name\""); - return; - } - - auto ps = game::SV_GetPlayerstateForClientNum(client_num); - const auto wp = game::G_GetWeaponForName(params.get(1)); - if (wp) - { - game::G_TakePlayerWeapon(ps, wp); - } - });*/ - } - }; -} - -REGISTER_COMPONENT(command::component) diff --git a/src/client/component/command.hpp b/src/client/component/command.hpp deleted file mode 100644 index bd70d0c6..00000000 --- a/src/client/component/command.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -namespace command -{ - class params - { - public: - params(); - - int size() const; - const char* get(int index) const; - std::string join(int index) const; - - const char* operator[](const int index) const - { - return this->get(index); // - } - - private: - int nesting_; - }; - - class params_sv - { - public: - params_sv(); - - int size() const; - const char* get(int index) const; - std::string join(int index) const; - - const char* operator[](const int index) const - { - return this->get(index); // - } - - private: - int nesting_; - }; - - void read_startup_variable(const std::string& dvar); - - void add_raw(const char* name, void (*callback)()); - void add(const char* name, const std::function& callback); - void add(const char* name, const std::function& callback); - - void add_sv(const char* name, std::function callback); - - void execute(std::string command, bool sync = false); -} \ No newline at end of file diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp deleted file mode 100644 index 174beaf8..00000000 --- a/src/client/component/console.cpp +++ /dev/null @@ -1,299 +0,0 @@ -#include -#include "console.hpp" -#include "loader/component_loader.hpp" -#include "game/game.hpp" -#include "command.hpp" - -#include -#include -#include -#include - -namespace game_console -{ - void print(int type, const std::string& data); -} - -namespace console -{ - namespace - { - using message_queue = std::queue; - utils::concurrency::container messages; - - bool native_console() - { - static const auto flag = utils::flags::has_flag("nativeconsole"); - return flag; - } - - void hide_console() - { - auto* const con_window = GetConsoleWindow(); - - DWORD process; - GetWindowThreadProcessId(con_window, &process); - - if (!native_console() && (process == GetCurrentProcessId() || IsDebuggerPresent())) - { - ShowWindow(con_window, SW_HIDE); - } - } - - std::string format(va_list* ap, const char* message) - { - static thread_local char buffer[0x1000]; - - const auto count = _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), message, *ap); - - if (count < 0) return {}; - return {buffer, static_cast(count)}; - } - - void dispatch_message(const int type, const std::string& message) - { - if (native_console()) - { - printf("%s\n", message.data()); - return; - } - - game_console::print(type, message); - messages.access([&message](message_queue& msgs) - { - msgs.emplace(message); - }); - } - - void append_text(const char* text) - { - dispatch_message(con_type_info, text); - } - } - - class component final : public component_interface - { - public: - component() - { - hide_console(); - - if (native_console()) - { - setvbuf(stdout, nullptr, _IONBF, 0); - setvbuf(stderr, nullptr, _IONBF, 0); - } - else - { - (void)_pipe(this->handles_, 1024, _O_TEXT); - (void)_dup2(this->handles_[1], 1); - (void)_dup2(this->handles_[1], 2); - } - } - - void post_start() override - { - this->terminate_runner_ = false; - - this->console_runner_ = utils::thread::create_named_thread("Console IO", [this] - { - if (native_console()) - { - this->native_input(); - } - else - { - this->runner(); - } - }); - } - - void pre_destroy() override - { - this->terminate_runner_ = true; - - printf("\r\n"); - _flushall(); - - if (this->console_runner_.joinable()) - { - this->console_runner_.join(); - } - - if (this->console_thread_.joinable()) - { - this->console_thread_.join(); - } - -#ifndef NATIVE_CONSOLE - _close(this->handles_[0]); - _close(this->handles_[1]); -#endif - - messages.access([&](message_queue& msgs) - { - msgs = {}; - }); - } - - void post_unpack() override - { - // Redirect input (]command) - utils::hook::jump(SELECT_VALUE(0x1403E34C0, 0x1405141E0), append_text); // H1(1.4) - - this->initialize(); - } - - private: - volatile bool console_initialized_ = false; - volatile bool terminate_runner_ = false; - - std::thread console_runner_; - std::thread console_thread_; - - int handles_[2]{}; - - void initialize() - { - this->console_thread_ = utils::thread::create_named_thread("Console", [this]() - { - if (!native_console() && (game::environment::is_dedi() || !utils::flags::has_flag("noconsole"))) - { - game::Sys_ShowConsole(); - } - - if (!game::environment::is_dedi()) - { - // Hide that shit - ShowWindow(console::get_window(), SW_MINIMIZE); - } - - { - messages.access([&](message_queue&) - { - this->console_initialized_ = true; - }); - } - - MSG msg; - while (!this->terminate_runner_) - { - if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - command::execute("quit", false); - break; - } - - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else - { - this->log_messages(); - std::this_thread::sleep_for(1ms); - } - } - }); - } - - void log_messages() - { - /*while*/ - if (this->console_initialized_ && !messages.get_raw().empty()) - { - std::queue message_queue_copy; - - { - messages.access([&](message_queue& msgs) - { - message_queue_copy = std::move(msgs); - msgs = {}; - }); - } - - while (!message_queue_copy.empty()) - { - log_message(message_queue_copy.front()); - message_queue_copy.pop(); - } - } - - fflush(stdout); - fflush(stderr); - } - - static void log_message(const std::string& message) - { - OutputDebugStringA(message.data()); - game::Conbuf_AppendText(message.data()); - } - - void runner() - { - char buffer[1024]; - - while (!this->terminate_runner_ && this->handles_[0]) - { - const auto len = _read(this->handles_[0], buffer, sizeof(buffer)); - if (len > 0) - { - dispatch_message(con_type_info, std::string(buffer, len)); - } - else - { - std::this_thread::sleep_for(1ms); - } - } - - std::this_thread::yield(); - } - - void native_input() - { - std::string cmd; - - while (!this->terminate_runner_) - { - std::getline(std::cin, cmd); - command::execute(cmd); - } - - std::this_thread::yield(); - } - }; - - HWND get_window() - { - return *reinterpret_cast((SELECT_VALUE(0x14CF56C00, 0x14DDFC2D0))); // H1(1.4) - } - - void set_title(std::string title) - { - SetWindowText(get_window(), title.data()); - } - - void set_size(const int width, const int height) - { - RECT rect; - GetWindowRect(get_window(), &rect); - - SetWindowPos(get_window(), nullptr, rect.left, rect.top, width, height, 0); - - auto* const logo_window = *reinterpret_cast(SELECT_VALUE(0x14CF56C10, 0x14DDFC2E0)); // H1(1.4) - SetWindowPos(logo_window, nullptr, 5, 5, width - 25, 60, 0); - } - - void print(const int type, const char* fmt, ...) - { - va_list ap; - va_start(ap, fmt); - const auto result = format(&ap, fmt); - va_end(ap); - - dispatch_message(type, result); - } -} - -REGISTER_COMPONENT(console::component) diff --git a/src/client/component/console.hpp b/src/client/component/console.hpp deleted file mode 100644 index 302951a8..00000000 --- a/src/client/component/console.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -namespace console -{ - HWND get_window(); - void set_title(std::string title); - void set_size(int width, int height); - - enum console_type - { - con_type_error = 1, - con_type_warning = 3, - con_type_info = 7 - }; - - void print(int type, const char* fmt, ...); - - template - void error(const char* fmt, Args&&... args) - { - print(con_type_error, fmt, std::forward(args)...); - } - - template - void warn(const char* fmt, Args&&... args) - { - print(con_type_warning, fmt, std::forward(args)...); - } - - template - void info(const char* fmt, Args&&... args) - { - print(con_type_info, fmt, std::forward(args)...); - } -} \ No newline at end of file diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp deleted file mode 100644 index 8de5e9ac..00000000 --- a/src/client/component/dedicated.cpp +++ /dev/null @@ -1,333 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "scheduler.hpp" -#include "server_list.hpp" -#include "network.hpp" -#include "command.hpp" -#include "game/game.hpp" -#include "game/dvars.hpp" -#include "dvars.hpp" -#include "console.hpp" - -#include -#include - -namespace dedicated -{ - namespace - { - utils::hook::detour gscr_set_dynamic_dvar_hook; - utils::hook::detour com_quit_f_hook; - - void init_dedicated_server() - { - static bool initialized = false; - if (initialized) return; - initialized = true; - - // R_LoadGraphicsAssets - utils::hook::invoke(0x1405DF4B0); - } - - void send_heartbeat() - { - auto* const dvar = game::Dvar_FindVar("sv_lanOnly"); - if (dvar && dvar->current.enabled) - { - return; - } - - game::netadr_s target{}; - if (server_list::get_master_server(target)) - { - network::send(target, "heartbeat", "H1"); - } - } - - std::vector& get_startup_command_queue() - { - static std::vector startup_command_queue; - return startup_command_queue; - } - - void execute_startup_command(int client, int /*controllerIndex*/, const char* command) - { - if (game::Live_SyncOnlineDataFlags(0) == 0) - { - game::Cbuf_ExecuteBufferInternal(0, 0, command, game::Cmd_ExecuteSingleCommand); - } - else - { - get_startup_command_queue().emplace_back(command); - } - } - - void execute_startup_command_queue() - { - const auto queue = get_startup_command_queue(); - get_startup_command_queue().clear(); - - for (const auto& command : queue) - { - game::Cbuf_ExecuteBufferInternal(0, 0, command.data(), game::Cmd_ExecuteSingleCommand); - } - } - - std::vector& get_console_command_queue() - { - static std::vector console_command_queue; - return console_command_queue; - } - - void execute_console_command(const int client, const char* command) - { - if (game::Live_SyncOnlineDataFlags(0) == 0) - { - game::Cbuf_AddText(client, command); - game::Cbuf_AddText(client, "\n"); - } - else - { - get_console_command_queue().emplace_back(command); - } - } - - void execute_console_command_queue() - { - const auto queue = get_console_command_queue(); - get_console_command_queue().clear(); - - for (const auto& command : queue) - { - game::Cbuf_AddText(0, command.data()); - game::Cbuf_AddText(0, "\n"); - } - } - - void sync_gpu_stub() - { - std::this_thread::sleep_for(1ms); - } - - game::dvar_t* gscr_set_dynamic_dvar() - { - /* - auto s = game::Scr_GetString(0); - auto* dvar = game::Dvar_FindVar(s); - - if (dvar && !strncmp("scr_", dvar->name, 4)) - { - return dvar; - } - */ - - return gscr_set_dynamic_dvar_hook.invoke(); - } - - void kill_server() - { - for (auto i = 0; i < *game::mp::svs_numclients; ++i) - { - if (game::mp::svs_clients[i].header.state >= 3) - { - game::SV_GameSendServerCommand(i, game::SV_CMD_CAN_IGNORE, - utils::string::va("r \"%s\"", "EXE_ENDOFGAME")); - } - } - - com_quit_f_hook.invoke(); - } - - void sys_error_stub(const char* msg, ...) - { - char buffer[2048]; - - va_list ap; - va_start(ap, msg); - - vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap); - - va_end(ap); - - scheduler::once([]() - { - command::execute("map_rotate"); - }, scheduler::main, 3s); - - game::Com_Error(game::ERR_DROP, "%s", buffer); - } - } - - void initialize() - { - command::execute("exec default_xboxlive.cfg", true); - command::execute("onlinegame 1", true); - command::execute("xblive_privatematch 1", true); - } - - class component final : public component_interface - { - public: - void* load_import(const std::string& library, const std::string& function) override - { - return nullptr; - } - - void post_unpack() override - { - if (!game::environment::is_dedi()) - { - return; - } - -#ifdef DEBUG - printf("Starting dedicated server\n"); -#endif - - // Register dedicated dvar - dvars::register_bool("dedicated", true, game::DVAR_FLAG_READ); - - // Add lanonly mode - dvars::register_bool("sv_lanOnly", false, game::DVAR_FLAG_NONE); - - // Disable VirtualLobby - dvars::override::register_bool("virtualLobbyEnabled", false, game::DVAR_FLAG_READ); - - // Disable r_preloadShaders - dvars::override::register_bool("r_preloadShaders", false, game::DVAR_FLAG_READ); - - // Stop crashing from sys_errors - utils::hook::jump(0x140511520, sys_error_stub); - - // Hook R_SyncGpu - utils::hook::jump(0x1405E12F0, sync_gpu_stub); - - utils::hook::jump(0x140254800, init_dedicated_server); - - // delay startup commands until the initialization is done - utils::hook::call(0x1400D72D6, execute_startup_command); - - // delay console commands until the initialization is done - utils::hook::call(0x1400D808C, execute_console_command); - utils::hook::nop(0x1400D80A4, 5); - - // patch GScr_SetDynamicDvar to behave better - gscr_set_dynamic_dvar_hook.create(0x14036B600, &gscr_set_dynamic_dvar); - - utils::hook::nop(0x1404ED90E, 5); // don't load config file - utils::hook::nop(0x140403D92, 5); // ^ - utils::hook::set(0x1400DC1D0, 0xC3); // don't save config file - utils::hook::set(0x140274710, 0xC3); // disable self-registration - utils::hook::set(0x140515890, 0xC3); // init sound system (1) - utils::hook::set(0x1406574F0, 0xC3); // init sound system (2) - utils::hook::set(0x140620D10, 0xC3); // render thread - utils::hook::set(0x14025B850, 0xC3); // called from Com_Frame, seems to do renderer stuff - utils::hook::set(0x1402507B0, 0xC3); // CL_CheckForResend, which tries to connect to the local server constantly - utils::hook::set(0x1405D5178, 0x00); // r_loadForRenderer default to 0 - utils::hook::set(0x14050C2D0, 0xC3); // recommended settings check - TODO: Check hook - utils::hook::set(0x140514C00, 0xC3); // some mixer-related function called on shutdown - utils::hook::set(0x140409830, 0xC3); // dont load ui gametype stuff - - utils::hook::nop(0x140481B06, 6); // unknown check in SV_ExecuteClientMessage - utils::hook::nop(0x140480FAC, 4); // allow first slot to be occupied - utils::hook::nop(0x14025619B, 2); // properly shut down dedicated servers - utils::hook::nop(0x14025615E, 2); // ^ - utils::hook::nop(0x1402561C0, 5); // don't shutdown renderer - - utils::hook::set(0x140091840, 0xC3); // something to do with blendShapeVertsView - utils::hook::nop(0x140659A0D, 8); // sound thing - - // (COULD NOT FIND IN H1) - // utils::hook::set(0x1404D6960, 0xC3); // cpu detection stuff? - utils::hook::set(0x1405E97F0, 0xC3); // gfx stuff during fastfile loading - utils::hook::set(0x1405E9700, 0xC3); // ^ - utils::hook::set(0x1405E9790, 0xC3); // ^ - utils::hook::set(0x1402C1180, 0xC3); // ^ - utils::hook::set(0x1405E9750, 0xC3); // ^ - utils::hook::set(0x1405AD5B0, 0xC3); // directx stuff - utils::hook::set(0x1405DB150, 0xC3); // ^ - utils::hook::set(0x140625220, 0xC3); // ^ - mutex - utils::hook::set(0x1405DB650, 0xC3); // ^ - - utils::hook::set(0x14008B5F0, 0xC3); // rendering stuff - utils::hook::set(0x1405DB8B0, 0xC3); // ^ - utils::hook::set(0x1405DB9C0, 0xC3); // ^ - utils::hook::set(0x1405DC050, 0xC3); // ^ - utils::hook::set(0x1405DCBA0, 0xC3); // ^ - utils::hook::set(0x1405DD240, 0xC3); // ^ - - // shaders - utils::hook::set(0x1400916A0, 0xC3); // ^ - utils::hook::set(0x140091610, 0xC3); // ^ - utils::hook::set(0x14061ACC0, 0xC3); // ^ - mutex - - utils::hook::set(0x140516080, 0xC3); // idk - utils::hook::set(0x1405AE5F0, 0xC3); // ^ - - utils::hook::set(0x1405E0B30, 0xC3); // R_Shutdown - utils::hook::set(0x1405AE400, 0xC3); // shutdown stuff - utils::hook::set(0x1405E0C00, 0xC3); // ^ - utils::hook::set(0x1405DFE50, 0xC3); // ^ - - // utils::hook::set(0x1404B67E0, 0xC3); // sound crashes (H1 - questionable, function looks way different) - - utils::hook::set(0x14048B660, 0xC3); // disable host migration - - utils::hook::set(0x14042B2E0, 0xC3); // render synchronization lock - utils::hook::set(0x14042B210, 0xC3); // render synchronization unlock - - utils::hook::set(0x140176D2D, 0xEB); // LUI: Unable to start the LUI system due to errors in main.lua - - utils::hook::nop(0x140506ECE, 5); // Disable sound pak file loading - utils::hook::nop(0x140506ED6, 2); // ^ - utils::hook::set(0x1402C5910, 0xC3); // Disable image pak file loading - - // Reduce min required memory - utils::hook::set(0x14050C717, 0x80000000); - - utils::hook::set(0x1402BF7F0, 0xC3); // some loop - utils::hook::set(0x14007E150, 0xC3); // related to shader caching / techsets / fastfiles - - // initialize the game after onlinedataflags is 32 (workaround) - scheduler::schedule([=]() - { - if (game::Live_SyncOnlineDataFlags(0) == 32 && game::Sys_IsDatabaseReady2()) - { - scheduler::once([]() - { - command::execute("xstartprivateparty", true); - command::execute("disconnect", true); // 32 -> 0 - }, scheduler::pipeline::main, 1s); - return scheduler::cond_end; - } - - return scheduler::cond_continue; - }, scheduler::pipeline::main, 1s); - - scheduler::on_game_initialized([]() - { - initialize(); - - console::info("==================================\n"); - console::info("Server started!\n"); - console::info("==================================\n"); - - // remove disconnect command - game::Cmd_RemoveCommand("disconnect"); - - execute_startup_command_queue(); - execute_console_command_queue(); - - // Send heartbeat to dpmaster - scheduler::once(send_heartbeat, scheduler::pipeline::server); - scheduler::loop(send_heartbeat, scheduler::pipeline::server, 10min); - command::add("heartbeat", send_heartbeat); - }, scheduler::pipeline::main, 1s); - - command::add("killserver", kill_server); - com_quit_f_hook.create(0x1400DA640, &kill_server); - } - }; -} - -REGISTER_COMPONENT(dedicated::component) \ No newline at end of file diff --git a/src/client/component/dedicated_info.cpp b/src/client/component/dedicated_info.cpp deleted file mode 100644 index 55973193..00000000 --- a/src/client/component/dedicated_info.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include "console.hpp" -#include "loader/component_loader.hpp" -#include "game/game.hpp" -#include "scheduler.hpp" -#include - -namespace dedicated_info -{ - class component final : public component_interface - { - public: - void post_unpack() override - { - if (!game::environment::is_dedi()) - { - return; - } - - scheduler::loop([]() - { - auto* sv_running = game::Dvar_FindVar("sv_running"); - if (!sv_running || !sv_running->current.enabled) - { - console::set_title("H1-Mod Dedicated Server"); - return; - } - - auto* const sv_hostname = game::Dvar_FindVar("sv_hostname"); - auto* const sv_maxclients = game::Dvar_FindVar("sv_maxclients"); - auto* const mapname = game::Dvar_FindVar("mapname"); - - auto bot_count = 0; - auto client_count = 0; - - for (auto i = 0; i < sv_maxclients->current.integer; i++) - { - auto* client = &game::mp::svs_clients[i]; - auto* self = &game::mp::g_entities[i]; - - if (client->header.state >= 1 && self && self->client) - { - client_count++; - if (game::SV_BotIsBot(i)) - { - ++bot_count; - } - } - } - - std::string cleaned_hostname; - cleaned_hostname.resize(static_cast(strlen(sv_hostname->current.string) + 1)); - - utils::string::strip(sv_hostname->current.string, cleaned_hostname.data(), - static_cast(strlen(sv_hostname->current.string)) + 1); - - console::set_title(utils::string::va("%s on %s [%d/%d] (%d)", cleaned_hostname.data(), - mapname->current.string, client_count, - sv_maxclients->current.integer, bot_count)); - }, scheduler::pipeline::main, 1s); - } - }; -} - -REGISTER_COMPONENT(dedicated_info::component) \ No newline at end of file diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp deleted file mode 100644 index 4cb3362c..00000000 --- a/src/client/component/demonware.cpp +++ /dev/null @@ -1,604 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include -#include - -#include "game/game.hpp" -#include "game/demonware/servers/lobby_server.hpp" -#include "game/demonware/servers/auth3_server.hpp" -#include "game/demonware/servers/stun_server.hpp" -#include "game/demonware/servers/umbrella_server.hpp" -#include "game/demonware/server_registry.hpp" -#include - -#define TCP_BLOCKING true -#define UDP_BLOCKING false - -namespace demonware -{ - namespace - { - volatile bool exit_server; - std::thread server_thread; - utils::concurrency::container> blocking_sockets; - utils::concurrency::container> socket_map; - server_registry tcp_servers; - server_registry udp_servers; - - tcp_server* find_server(const SOCKET socket) - { - return socket_map.access([&](const std::unordered_map& map) -> tcp_server* - { - const auto entry = map.find(socket); - if (entry == map.end()) - { - return nullptr; - } - - return entry->second; - }); - } - - bool socket_link(const SOCKET socket, const uint32_t address) - { - auto* server = tcp_servers.find(address); - if (!server) - { - return false; - } - - socket_map.access([&](std::unordered_map& map) - { - map[socket] = server; - }); - - return true; - } - - void socket_unlink(const SOCKET socket) - { - socket_map.access([&](std::unordered_map& map) - { - const auto entry = map.find(socket); - if (entry != map.end()) - { - map.erase(entry); - } - }); - } - - bool is_socket_blocking(const SOCKET socket, const bool def) - { - return blocking_sockets.access([&](std::unordered_map& map) - { - const auto entry = map.find(socket); - if (entry == map.end()) - { - return def; - } - - return entry->second; - }); - } - - void remove_blocking_socket(const SOCKET socket) - { - blocking_sockets.access([&](std::unordered_map& map) - { - const auto entry = map.find(socket); - if (entry != map.end()) - { - map.erase(entry); - } - }); - } - - void add_blocking_socket(const SOCKET socket, const bool block) - { - blocking_sockets.access([&](std::unordered_map& map) - { - map[socket] = block; - }); - } - - void server_main() - { - exit_server = false; - - while (!exit_server) - { - tcp_servers.frame(); - udp_servers.frame(); - std::this_thread::sleep_for(50ms); - } - } - - namespace io - { - int getaddrinfo_stub(const char* name, const char* service, - const addrinfo* hints, addrinfo** res) - { -#ifdef DEBUG - printf("[ network ]: [getaddrinfo]: \"%s\" \"%s\"\n", name, service); -#endif - - base_server* server = tcp_servers.find(name); - if (!server) - { - server = udp_servers.find(name); - } - - if (!server) - { - return getaddrinfo(name, service, hints, res); - } - - const auto address = utils::memory::get_allocator()->allocate(); - const auto ai = utils::memory::get_allocator()->allocate(); - - auto in_addr = reinterpret_cast(address); - in_addr->sin_addr.s_addr = server->get_address(); - in_addr->sin_family = AF_INET; - - ai->ai_family = AF_INET; - ai->ai_socktype = SOCK_STREAM; - ai->ai_addr = address; - ai->ai_addrlen = sizeof(sockaddr); - ai->ai_next = nullptr; - ai->ai_flags = 0; - ai->ai_protocol = 0; - ai->ai_canonname = const_cast(name); - - *res = ai; - - return 0; - } - - void freeaddrinfo_stub(addrinfo* ai) - { - if (!utils::memory::get_allocator()->find(ai)) - { - return freeaddrinfo(ai); - } - - utils::memory::get_allocator()->free(ai->ai_addr); - utils::memory::get_allocator()->free(ai); - } - - int getpeername_stub(const SOCKET s, sockaddr* addr, socklen_t* addrlen) - { - auto* server = find_server(s); - - if (server) - { - auto in_addr = reinterpret_cast(addr); - in_addr->sin_addr.s_addr = server->get_address(); - in_addr->sin_family = AF_INET; - *addrlen = sizeof(sockaddr); - - return 0; - } - - return getpeername(s, addr, addrlen); - } - - int getsockname_stub(const SOCKET s, sockaddr* addr, socklen_t* addrlen) - { - auto* server = find_server(s); - - if (server) - { - auto in_addr = reinterpret_cast(addr); - in_addr->sin_addr.s_addr = server->get_address(); - in_addr->sin_family = AF_INET; - *addrlen = sizeof(sockaddr); - - return 0; - } - - return getsockname(s, addr, addrlen); - } - - hostent* gethostbyname_stub(const char* name) - { -#ifdef DEBUG - printf("[ network ]: [gethostbyname]: \"%s\"\n", name); -#endif - - base_server* server = tcp_servers.find(name); - if (!server) - { - server = udp_servers.find(name); - } - - if (!server) - { -#pragma warning(push) -#pragma warning(disable: 4996) - return gethostbyname(name); -#pragma warning(pop) - } - - static thread_local in_addr address{}; - address.s_addr = server->get_address(); - - static thread_local in_addr* addr_list[2]{}; - addr_list[0] = &address; - addr_list[1] = nullptr; - - static thread_local hostent host{}; - host.h_name = const_cast(name); - host.h_aliases = nullptr; - host.h_addrtype = AF_INET; - host.h_length = sizeof(in_addr); - host.h_addr_list = reinterpret_cast(addr_list); - - return &host; - } - - int connect_stub(const SOCKET s, const struct sockaddr* addr, const int len) - { - if (len == sizeof(sockaddr_in)) - { - const auto* in_addr = reinterpret_cast(addr); - if (socket_link(s, in_addr->sin_addr.s_addr)) return 0; - } - - return connect(s, addr, len); - } - - int closesocket_stub(const SOCKET s) - { - remove_blocking_socket(s); - socket_unlink(s); - - return closesocket(s); - } - - int send_stub(const SOCKET s, const char* buf, const int len, const int flags) - { - auto* server = find_server(s); - - if (server) - { - server->handle_input(buf, len); - return len; - } - - return send(s, buf, len, flags); - } - - int recv_stub(const SOCKET s, char* buf, const int len, const int flags) - { - auto* server = find_server(s); - - if (server) - { - if (server->pending_data()) - { - return static_cast(server->handle_output(buf, len)); - } - else - { - WSASetLastError(WSAEWOULDBLOCK); - return -1; - } - } - - return recv(s, buf, len, flags); - } - - int sendto_stub(const SOCKET s, const char* buf, const int len, const int flags, const sockaddr* to, - const int tolen) - { - const auto* in_addr = reinterpret_cast(to); - auto* server = udp_servers.find(in_addr->sin_addr.s_addr); - - if (server) - { - server->handle_input(buf, len, {s, to, tolen}); - return len; - } - - return sendto(s, buf, len, flags, to, tolen); - } - - int recvfrom_stub(const SOCKET s, char* buf, const int len, const int flags, struct sockaddr* from, - int* fromlen) - { - // Not supported yet - if (is_socket_blocking(s, UDP_BLOCKING)) - { - return recvfrom(s, buf, len, flags, from, fromlen); - } - - size_t result = 0; - udp_servers.for_each([&](udp_server& server) - { - if (server.pending_data(s)) - { - result = server.handle_output( - s, buf, static_cast(len), from, fromlen); - } - }); - - if (result) - { - return static_cast(result); - } - - return recvfrom(s, buf, len, flags, from, fromlen); - } - - int select_stub(const int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, - struct timeval* timeout) - { - if (exit_server) - { - return select(nfds, readfds, writefds, exceptfds, timeout); - } - - auto result = 0; - std::vector read_sockets; - std::vector write_sockets; - - socket_map.access([&](std::unordered_map& sockets) - { - for (auto& s : sockets) - { - if (readfds) - { - if (FD_ISSET(s.first, readfds)) - { - if (s.second->pending_data()) - { - read_sockets.push_back(s.first); - FD_CLR(s.first, readfds); - } - } - } - - if (writefds) - { - if (FD_ISSET(s.first, writefds)) - { - write_sockets.push_back(s.first); - FD_CLR(s.first, writefds); - } - } - - if (exceptfds) - { - if (FD_ISSET(s.first, exceptfds)) - { - FD_CLR(s.first, exceptfds); - } - } - } - }); - - if ((!readfds || readfds->fd_count == 0) && (!writefds || writefds->fd_count == 0)) - { - timeout->tv_sec = 0; - timeout->tv_usec = 0; - } - - result = select(nfds, readfds, writefds, exceptfds, timeout); - if (result < 0) result = 0; - - for (const auto& socket : read_sockets) - { - if (readfds) - { - FD_SET(socket, readfds); - result++; - } - } - - for (const auto& socket : write_sockets) - { - if (writefds) - { - FD_SET(socket, writefds); - result++; - } - } - - return result; - } - - int ioctlsocket_stub(const SOCKET s, const long cmd, u_long* argp) - { - if (static_cast(cmd) == (FIONBIO)) - { - add_blocking_socket(s, *argp == 0); - } - - return ioctlsocket(s, cmd, argp); - } - - BOOL internet_get_connected_state_stub(LPDWORD, DWORD) - { - // Allow offline play - return TRUE; - } - } - - void bd_logger_stub(char* a1, void* a2, void* a3, void* a4, const char* function, ...) - { - - } - -#ifdef DEBUG - void a(unsigned int n) - { - printf("bdAuth: Auth task failed with HTTP code [%u]\n", n); - } - - void b(unsigned int n) - { - printf("bdAuth: Decoded client ticket of unexpected size [%u]\n", n); - } - - void c(unsigned int n) - { - printf("bdAuth: Decoded server ticket of unexpected size [%u]\n", n); - } - - void d() - { - printf("bdAuth: Auth ticket magic number mismatch\n"); - } - - void e() - { - printf("bdAuth: Cross Authentication completed\n"); - } - - void f() - { - printf("bdAuth: Auth task reply contains invalid data / format\n"); - } - - void g(unsigned int n) - { - printf("bdAuth: Auth task returned with error code [%u]\n", n); - } - - void h(unsigned int n) - { - printf("bdAuth: Invalid or No Task ID [%u] in Auth reply\n", n); - } - - void i() - { - printf("bdAuth: Received reply from DemonWare Auth server\n"); - } - - void l() - { - printf("bdAuth: Unknown error\n"); - } -#endif - } - - class component final : public component_interface - { - public: - component() - { - udp_servers.create("phoenix.stun.us.demonware.net"); - udp_servers.create("phoenix.stun.eu.demonware.net"); - udp_servers.create("phoenix.stun.jp.demonware.net"); - udp_servers.create("phoenix.stun.au.demonware.net"); - - udp_servers.create("stun.us.demonware.net"); - udp_servers.create("stun.eu.demonware.net"); - udp_servers.create("stun.jp.demonware.net"); - udp_servers.create("stun.au.demonware.net"); - - tcp_servers.create("mwr-pc-steam-auth3.prod.demonware.net"); - tcp_servers.create("mwr-pc-steam-lobby.prod.demonware.net"); - tcp_servers.create("prod.umbrella.demonware.net"); - } - - void post_load() override - { - server_thread = utils::thread::create_named_thread("Demonware", server_main); - } - - void* load_import(const std::string& library, const std::string& function) override - { - if (library == "WS2_32.dll") - { - if (function == "#3") return io::closesocket_stub; - if (function == "#4") return io::connect_stub; - if (function == "#5") return io::getpeername_stub; - if (function == "#6") return io::getsockname_stub; - if (function == "#10") return io::ioctlsocket_stub; - if (function == "#16") return io::recv_stub; - if (function == "#17") return io::recvfrom_stub; - if (function == "#18") return io::select_stub; - if (function == "#19") return io::send_stub; - if (function == "#20") return io::sendto_stub; - if (function == "#52") return io::gethostbyname_stub; - if (function == "getaddrinfo") return io::getaddrinfo_stub; - if (function == "freeaddrinfo") return io::freeaddrinfo_stub; - } - - if (function == "InternetGetConnectedState") - { - return io::internet_get_connected_state_stub; - } - - return nullptr; - } - - void post_unpack() override - { - /* - mwr has upgraded some networking methods and the gethostbyname import from winsock library is no longer used - gethostbyname has been replaced with getaddrinfo - btw, still you can't get online.. - */ - utils::hook::jump(SELECT_VALUE(0x140610320, 0x1407400B0), bd_logger_stub); // H1MP64(1.4) - - if (game::environment::is_sp()) - { - utils::hook::set(0x1405FCA00, 0xC3); // bdAuthSteam H1(1.4) - utils::hook::set(0x140333A00, 0xC3); // dwNet H1(1.4) - return; - } - - utils::hook::set(0x140715039, 0x0); // CURLOPT_SSL_VERIFYPEER H1MP64(1.4) - utils::hook::set(0x140715025, 0xAF); // CURLOPT_SSL_VERIFYHOST H1MP64(1.4) - utils::hook::set(0x14095433C, 0x0); // HTTPS -> HTTP [MWR OK][S1X: 0x14088D0E8] - - //HTTPS -> HTTP - utils::hook::inject(0x14006DDA9, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x14003852E] - utils::hook::inject(0x14006E11C, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x14003884F] - utils::hook::inject(0x14006E2FB, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x140038A07] - utils::hook::inject(0x14006E9A9, "http://prod.uno.demonware.net/v1.0/"); - utils::hook::inject(0x14006ED49, "http://prod.uno.demonware.net/v1.0/"); - utils::hook::inject(0x140728170, "http://%s:%d/auth/"); - - utils::hook::set(0x14047F290, 0xC3); // SV_SendMatchData H1MP64(1.4) - utils::hook::set(0x140598990, 0xC3); // Live_CheckForFullDisconnect H1MP64(1.4) - -#ifdef DEBUG - // yes - utils::hook::call(0x140727BEB, l); - utils::hook::call(0x140727AFC, i); - utils::hook::call(0x140727E49, h); - utils::hook::call(0x140727E30, g); - utils::hook::call(0x140727E37, f); - utils::hook::call(0x140727DF2, e); - utils::hook::call(0x140727DF9, d); - utils::hook::call(0x140727CFC, c); - utils::hook::call(0x140727C82, b); - utils::hook::call(0x140727E6A, a); -#endif - // Checks X-Signature header or something - utils::hook::set(0x140728380, 0xC301B0); - // Checks extended_data and extra_data in json object - utils::hook::set(0x140728E90, 0xC301B0); - // Update check - utils::hook::set(0x1403A5390, 0xC301B0); - - // Remove some while loop in demonware that freezes the rendering for a few secs at launch - utils::hook::nop(0x14057DBC5, 5); - } - - void pre_destroy() override - { - exit_server = true; - if (server_thread.joinable()) - { - server_thread.join(); - } - } - }; -} - -REGISTER_COMPONENT(demonware::component) diff --git a/src/client/component/demonware.hpp b/src/client/component/demonware.hpp deleted file mode 100644 index d26d1ccd..00000000 --- a/src/client/component/demonware.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace demonware -{ - -} \ No newline at end of file diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp deleted file mode 100644 index 5925a64a..00000000 --- a/src/client/component/discord.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "scheduler.hpp" -#include "game/game.hpp" - -#include "console.hpp" -#include "command.hpp" -#include "network.hpp" -#include "party.hpp" - -#include - -#include - -namespace discord -{ - namespace - { - DiscordRichPresence discord_presence; - - void update_discord() - { - Discord_RunCallbacks(); - - if (!game::CL_IsCgameInitialized() || game::VirtualLobby_Loaded()) - { - discord_presence.details = game::environment::is_sp() ? "Singleplayer" : "Multiplayer"; - discord_presence.state = "Main Menu"; - - auto firingRangeDvar = game::Dvar_FindVar("virtualLobbyInFiringRange"); - if (firingRangeDvar && firingRangeDvar->current.enabled == 1) - { - discord_presence.state = "Firing Range"; - } - - discord_presence.partySize = 0; - discord_presence.partyMax = 0; - discord_presence.startTimestamp = 0; - discord_presence.largeImageKey = game::environment::is_sp() ? "menu_singleplayer" : "menu_multiplayer"; - } - else - { - const auto map = game::Dvar_FindVar("mapname")->current.string; - const auto mapname = game::UI_SafeTranslateString(utils::string::va("PRESENCE_%s%s", (game::environment::is_sp() ? "SP_" : ""), map)); - - if (game::environment::is_mp()) - { - const auto gametype = game::UI_GetGameTypeDisplayName(game::Dvar_FindVar("g_gametype")->current.string); - - discord_presence.details = utils::string::va("%s on %s", gametype, mapname); - - char clean_hostname[0x100] = {0}; - utils::string::strip(game::Dvar_FindVar("sv_hostname")->current.string, - clean_hostname, sizeof(clean_hostname)); - auto max_clients = party::server_client_count(); - - // When true, we are in Private Match - if (game::SV_Loaded()) - { - strcpy_s(clean_hostname, "Private Match"); - max_clients = game::Dvar_FindVar("sv_maxclients")->current.integer; - } - - discord_presence.partySize = *reinterpret_cast(0x1429864C4); - discord_presence.partyMax = max_clients; - discord_presence.state = clean_hostname; - discord_presence.largeImageKey = map; - } - else if (game::environment::is_sp()) - { - discord_presence.state = ""; - discord_presence.largeImageKey = map; - discord_presence.details = mapname; - } - - if (!discord_presence.startTimestamp) - { - discord_presence.startTimestamp = std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()).count(); - } - } - - Discord_UpdatePresence(&discord_presence); - } - } - - class component final : public component_interface - { - public: - void post_load() override - { - if (game::environment::is_dedi()) - { - return; - } - - DiscordEventHandlers handlers; - ZeroMemory(&handlers, sizeof(handlers)); - handlers.ready = ready; - handlers.errored = errored; - handlers.disconnected = errored; - handlers.joinGame = nullptr; - handlers.spectateGame = nullptr; - handlers.joinRequest = nullptr; - - Discord_Initialize("947125042930667530", &handlers, 1, nullptr); - - scheduler::once([]() - { - scheduler::once(update_discord, scheduler::pipeline::async); - scheduler::loop(update_discord, scheduler::pipeline::async, 5s); - }, scheduler::pipeline::main); - - initialized_ = true; - } - - void pre_destroy() override - { - if (!initialized_ || game::environment::is_dedi()) - { - return; - } - - Discord_Shutdown(); - } - - private: - bool initialized_ = false; - - static void ready(const DiscordUser* /*request*/) - { - ZeroMemory(&discord_presence, sizeof(discord_presence)); - - discord_presence.instance = 1; - - console::info("Discord: Ready\n"); - - Discord_UpdatePresence(&discord_presence); - } - - static void errored(const int error_code, const char* message) - { - console::error("Discord: Error (%i): %s\n", error_code, message); - } - }; -} - -REGISTER_COMPONENT(discord::component) \ No newline at end of file diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp deleted file mode 100644 index d9c77fdf..00000000 --- a/src/client/component/dvars.cpp +++ /dev/null @@ -1,443 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "dvars.hpp" - -#include "game/game.hpp" - -#include - -namespace dvars -{ - struct dvar_base - { - unsigned int flags{}; - }; - - struct dvar_bool : dvar_base - { - bool value{}; - }; - - struct dvar_float : dvar_base - { - float value{}; - float min{}; - float max{}; - }; - - struct dvar_vector2 : dvar_base - { - float x{}; - float y{}; - float min{}; - float max{}; - }; - - struct dvar_vector3 : dvar_base - { - - float x{}; - float y{}; - float z{}; - float min{}; - float max{}; - }; - - struct dvar_int : dvar_base - { - int value{}; - int min{}; - int max{}; - }; - - struct dvar_string : dvar_base - { - std::string value{}; - }; - - namespace - { - template - T* find_dvar(std::unordered_map& map, const std::string& name) - { - auto i = map.find(name); - if (i != map.end()) - { - return &i->second; - } - - return nullptr; - } - - template - T* find_dvar(std::unordered_map& map, const int hash) - { - for (auto i = map.begin(); i != map.end(); ++i) - { - if (game::generateHashValue(i->first.data()) == hash) - { - return &i->second; - } - } - - return nullptr; - } - - bool find_dvar(std::unordered_set& set, const std::string& name) - { - return set.find(name) != set.end(); - } - - - bool find_dvar(std::unordered_set& set, const int hash) - { - for (auto i = set.begin(); i != set.end(); ++i) - { - if (game::generateHashValue(i->data()) == hash) - { - return true; - } - } - - return false; - } - } - - namespace disable - { - static std::unordered_set set_bool_disables; - static std::unordered_set set_float_disables; - static std::unordered_set set_int_disables; - static std::unordered_set set_string_disables; - - void set_bool(const std::string& name) - { - set_bool_disables.emplace(name); - } - - void set_float(const std::string& name) - { - set_float_disables.emplace(name); - } - - void set_int(const std::string& name) - { - set_int_disables.emplace(name); - } - - void set_string(const std::string& name) - { - set_string_disables.emplace(name); - } - } - - namespace override - { - static std::unordered_map register_bool_overrides; - static std::unordered_map register_float_overrides; - static std::unordered_map register_int_overrides; - static std::unordered_map register_string_overrides; - static std::unordered_map register_vector2_overrides; - static std::unordered_map register_vector3_overrides; - - static std::unordered_map set_bool_overrides; - static std::unordered_map set_float_overrides; - static std::unordered_map set_int_overrides; - static std::unordered_map set_string_overrides; - static std::unordered_map set_from_string_overrides; - - void register_bool(const std::string& name, const bool value, const unsigned int flags) - { - dvar_bool values; - values.value = value; - values.flags = flags; - register_bool_overrides[name] = std::move(values); - } - - void register_float(const std::string& name, const float value, const float min, const float max, - const unsigned int flags) - { - dvar_float values; - values.value = value; - values.min = min; - values.max = max; - values.flags = flags; - register_float_overrides[name] = std::move(values); - } - - void register_int(const std::string& name, const int value, const int min, const int max, - const unsigned int flags) - { - dvar_int values; - values.value = value; - values.min = min; - values.max = max; - values.flags = flags; - register_int_overrides[name] = std::move(values); - } - - void register_string(const std::string& name, const std::string& value, - const unsigned int flags) - { - dvar_string values; - values.value = value; - values.flags = flags; - register_string_overrides[name] = std::move(values); - } - - void register_vec2(const std::string& name, float x, float y, float min, float max, - const unsigned int flags) - { - dvar_vector2 values; - values.x = x; - values.y = y; - values.min = min; - values.max = max; - values.flags = flags; - register_vector2_overrides[name] = std::move(values); - } - - void register_vec3(const std::string& name, float x, float y, float z, float min, - float max, const unsigned int flags) - { - dvar_vector3 values; - values.x = x; - values.y = y; - values.z = z; - values.min = min; - values.max = max; - values.flags = flags; - register_vector3_overrides[name] = std::move(values); - } - - void set_bool(const std::string& name, const bool value) - { - set_bool_overrides[name] = value; - } - - void set_float(const std::string& name, const float value) - { - set_float_overrides[name] = value; - } - - void set_int(const std::string& name, const int value) - { - set_int_overrides[name] = value; - } - - void set_string(const std::string& name, const std::string& value) - { - set_string_overrides[name] = value; - } - - void set_from_string(const std::string& name, const std::string& value) - { - set_from_string_overrides[name] = value; - } - } - - utils::hook::detour dvar_register_bool_hook; - utils::hook::detour dvar_register_float_hook; - utils::hook::detour dvar_register_int_hook; - utils::hook::detour dvar_register_string_hook; - utils::hook::detour dvar_register_vector2_hook; - utils::hook::detour dvar_register_vector3_hook; - - utils::hook::detour dvar_set_bool_hook; - utils::hook::detour dvar_set_float_hook; - utils::hook::detour dvar_set_int_hook; - utils::hook::detour dvar_set_string_hook; - utils::hook::detour dvar_set_from_string_hook; - - game::dvar_t* dvar_register_bool(const int hash, const char* name, bool value, unsigned int flags) - { - auto* var = find_dvar(override::register_bool_overrides, hash); - if (var) - { - value = var->value; - flags = var->flags; - } - - return dvar_register_bool_hook.invoke(hash, name, value, flags); - } - - game::dvar_t* dvar_register_float(const int hash, const char* name, float value, float min, float max, unsigned int flags) - { - auto* var = find_dvar(override::register_float_overrides, hash); - if (var) - { - value = var->value; - min = var->min; - max = var->max; - flags = var->flags; - } - - return dvar_register_float_hook.invoke(hash, name, value, min, max, flags); - } - - game::dvar_t* dvar_register_int(const int hash, const char* name, int value, int min, int max, unsigned int flags) - { - auto* var = find_dvar(override::register_int_overrides, hash); - if (var) - { - value = var->value; - min = var->min; - max = var->max; - flags = var->flags; - } - - return dvar_register_int_hook.invoke(hash, name, value, min, max, flags); - } - - game::dvar_t* dvar_register_string(const int hash, const char* name, const char* value, unsigned int flags) - { - auto* var = find_dvar(override::register_string_overrides, hash); - if (var) - { - value = var->value.data(); - flags = var->flags; - } - - return dvar_register_string_hook.invoke(hash, name, value, flags); - } - - game::dvar_t* dvar_register_vector2(const int hash, const char* name, float x, float y, float min, float max, - unsigned int flags) - { - auto* var = find_dvar(override::register_vector2_overrides, hash); - if (var) - { - x = var->x; - y = var->y; - min = var->min; - max = var->max; - flags = var->flags; - } - - return dvar_register_vector2_hook.invoke(hash, name, x, y, min, max, flags); - } - - game::dvar_t* dvar_register_vector3(const int hash, const char* name, float x, float y, float z, float min, - float max, unsigned int flags) - { - auto* var = find_dvar(override::register_vector3_overrides, hash); - if (var) - { - x = var->x; - y = var->y; - z = var->z; - min = var->min; - max = var->max; - flags = var->flags; - } - - return dvar_register_vector3_hook.invoke(hash, name, x, y, z, min, max, flags); - } - - void dvar_set_bool(game::dvar_t* dvar, bool boolean) - { - const auto disabled = find_dvar(disable::set_bool_disables, dvar->hash); - if (disabled) - { - return; - } - - auto* var = find_dvar(override::set_bool_overrides, dvar->hash); - if (var) - { - boolean = *var; - } - - return dvar_set_bool_hook.invoke(dvar, boolean); - } - - void dvar_set_float(game::dvar_t* dvar, float fl) - { - const auto disabled = find_dvar(disable::set_float_disables, dvar->hash); - if (disabled) - { - return; - } - - auto* var = find_dvar(override::set_float_overrides, dvar->hash); - if (var) - { - fl = *var; - } - - return dvar_set_float_hook.invoke(dvar, fl); - } - - void dvar_set_int(game::dvar_t* dvar, int integer) - { - const auto disabled = find_dvar(disable::set_int_disables, dvar->hash); - if (disabled) - { - return; - } - - auto* var = find_dvar(override::set_int_overrides, dvar->hash); - if (var) - { - integer = *var; - } - - return dvar_set_int_hook.invoke(dvar, integer); - } - - void dvar_set_string(game::dvar_t* dvar, const char* string) - { - const auto disabled = find_dvar(disable::set_string_disables, dvar->hash); - if (disabled) - { - return; - } - - auto* var = find_dvar(override::set_string_overrides, dvar->hash); - if (var) - { - string = var->data(); - } - - return dvar_set_string_hook.invoke(dvar, string); - } - - void dvar_set_from_string(game::dvar_t* dvar, const char* string, game::DvarSetSource source) - { - const auto disabled = find_dvar(disable::set_string_disables, dvar->hash); - if (disabled) - { - return; - } - - auto* var = find_dvar(override::set_from_string_overrides, dvar->hash); - if (var) - { - string = var->data(); - } - - return dvar_set_from_string_hook.invoke(dvar, string, source); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - dvar_register_bool_hook.create(SELECT_VALUE(0x1403C47E0, 0x1404FA540), &dvar_register_bool); - dvar_register_float_hook.create(SELECT_VALUE(0x1403C4BB0, 0x1404FA910), &dvar_register_float); - dvar_register_int_hook.create(SELECT_VALUE(0x1403C4CC0, 0x1404FAA20), &dvar_register_int); - dvar_register_string_hook.create(SELECT_VALUE(0x1403C4DA0, 0x1404FAB00), &dvar_register_string); - dvar_register_vector2_hook.create(SELECT_VALUE(0x1403C4E80, 0x1404FABE0), &dvar_register_vector2); - dvar_register_vector3_hook.create(SELECT_VALUE(0x1403C4FC0, 0x1404FACE0), &dvar_register_vector3); - - dvar_set_bool_hook.create(SELECT_VALUE(0x1403C7020, 0x1404FCDF0), &dvar_set_bool); - dvar_set_float_hook.create(SELECT_VALUE(0x1403C7420, 0x1404FD360), &dvar_set_float); - dvar_set_int_hook.create(SELECT_VALUE(0x1403C76C0, 0x1404FD5E0), &dvar_set_int); - dvar_set_string_hook.create(SELECT_VALUE(0x1403C7900, 0x1404FD8D0), &dvar_set_string); - dvar_set_from_string_hook.create(SELECT_VALUE(0x1403C7620, 0x1404FD520), &dvar_set_from_string); - } - }; -} - -REGISTER_COMPONENT(dvars::component) diff --git a/src/client/component/dvars.hpp b/src/client/component/dvars.hpp deleted file mode 100644 index 66d6912d..00000000 --- a/src/client/component/dvars.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -namespace dvars -{ - namespace disable - { - void set_bool(const std::string& name); - void set_float(const std::string& name); - void set_int(const std::string& name); - void set_string(const std::string& name); - } - - namespace override - { - void register_bool(const std::string& name, bool value, const unsigned int flags); - void register_float(const std::string& name, float value, float min, float max, const unsigned int flags); - void register_int(const std::string& name, int value, int min, int max, const unsigned int flags); - void register_string(const std::string& name, const std::string& value, const unsigned int flags); - void register_vec2(const std::string& name, float x, float y, float min, float max, const unsigned int flags); - void register_vec3(const std::string& name, float x, float y, float z, float min, float max, const unsigned int flags); - - void set_bool(const std::string& name, bool boolean); - void set_float(const std::string& name, float fl); - void set_int(const std::string& name, int integer); - void set_string(const std::string& name, const std::string& string); - void set_from_string(const std::string& name, const std::string& value); - } -} diff --git a/src/client/component/exception.cpp b/src/client/component/exception.cpp deleted file mode 100644 index 028bb238..00000000 --- a/src/client/component/exception.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "system_check.hpp" -#include "scheduler.hpp" - -#include "game/game.hpp" - -#include -#include -#include -#include -#include - -#include - -#include - -#include "game/dvars.hpp" - -namespace exception -{ - namespace - { - thread_local struct - { - DWORD code = 0; - PVOID address = nullptr; - } exception_data; - - struct - { - std::chrono::time_point last_recovery{}; - std::atomic recovery_counts = {0}; - } recovery_data; - - bool is_game_thread() - { - static std::vector allowed_threads = - { - game::THREAD_CONTEXT_MAIN, - }; - - const auto self_id = GetCurrentThreadId(); - for (const auto& index : allowed_threads) - { - if (game::threadIds[index] == self_id) - { - return true; - } - } - - return false; - } - - bool is_exception_interval_too_short() - { - const auto delta = std::chrono::high_resolution_clock::now() - recovery_data.last_recovery; - return delta < 1min; - } - - bool too_many_exceptions_occured() - { - return recovery_data.recovery_counts >= 3; - } - - volatile bool& is_initialized() - { - static volatile bool initialized = false; - return initialized; - } - - bool is_recoverable() - { - return is_initialized() - && is_game_thread() - && !is_exception_interval_too_short() - && !too_many_exceptions_occured(); - } - - void show_mouse_cursor() - { - while (ShowCursor(TRUE) < 0); - } - - void display_error_dialog() - { - std::string error_str = utils::string::va("Fatal error (0x%08X) at 0x%p.\n" - "A minidump has been written.\n\n", - exception_data.code, exception_data.address); - - if (!system_check::is_valid()) - { - error_str += "Make sure to get supported game files to avoid such crashes!"; - } - else - { - error_str += "Make sure to update your graphics card drivers and install operating system updates!"; - } - - utils::thread::suspend_other_threads(); - show_mouse_cursor(); - - MessageBoxA(nullptr, error_str.data(), "H1-Mod ERROR", MB_ICONERROR); - TerminateProcess(GetCurrentProcess(), exception_data.code); - } - - void reset_state() - { - if (dvars::cg_legacyCrashHandling && dvars::cg_legacyCrashHandling->current.enabled) - { - display_error_dialog(); - } - - // TODO: Add a limit for dedi restarts - if (game::environment::is_dedi()) - { - utils::nt::relaunch_self(); - utils::nt::terminate(exception_data.code); - } - - if (is_recoverable()) - { - recovery_data.last_recovery = std::chrono::high_resolution_clock::now(); - ++recovery_data.recovery_counts; - - game::Com_Error(game::ERR_DROP, "Fatal error (0x%08X) at 0x%p.\nA minidump has been written.\n\n" - "H1-Mod has tried to recover your game, but it might not run stable anymore.\n\n" - "Make sure to update your graphics card drivers and install operating system updates!\n" - "Closing or restarting Steam might also help.", - exception_data.code, exception_data.address); - } - else - { - display_error_dialog(); - } - } - - size_t get_reset_state_stub() - { - static auto* stub = utils::hook::assemble([](utils::hook::assembler& a) - { - a.sub(rsp, 0x10); - a.or_(rsp, 0x8); - a.jmp(reset_state); - }); - - return reinterpret_cast(stub); - } - - std::string get_timestamp() - { - tm ltime{}; - char timestamp[MAX_PATH] = {0}; - const auto time = _time64(nullptr); - - _localtime64_s(<ime, &time); - strftime(timestamp, sizeof(timestamp) - 1, "%Y-%m-%d-%H-%M-%S", <ime); - - return timestamp; - } - - std::string generate_crash_info(const LPEXCEPTION_POINTERS exceptioninfo) - { - std::string info{}; - const auto line = [&info](const std::string& text) - { - info.append(text); - info.append("\r\n"); - }; - - line("H1-Mod Crash Dump"); - line(""); - line("Version: "s + VERSION); - line("Environment: "s + game::environment::get_string()); - line("Timestamp: "s + get_timestamp()); - line("Clean game: "s + (system_check::is_valid() ? "Yes" : "No")); - line(utils::string::va("Exception: 0x%08X", exceptioninfo->ExceptionRecord->ExceptionCode)); - line(utils::string::va("Address: 0x%llX", exceptioninfo->ExceptionRecord->ExceptionAddress)); - -#pragma warning(push) -#pragma warning(disable: 4996) - OSVERSIONINFOEXA version_info; - ZeroMemory(&version_info, sizeof(version_info)); - version_info.dwOSVersionInfoSize = sizeof(version_info); - GetVersionExA(reinterpret_cast(&version_info)); -#pragma warning(pop) - - line(utils::string::va("OS Version: %u.%u", version_info.dwMajorVersion, version_info.dwMinorVersion)); - - return info; - } - - void write_minidump(const LPEXCEPTION_POINTERS exceptioninfo) - { - const std::string crash_name = utils::string::va("minidumps/h1-mod-crash-%d-%s.zip", - game::environment::get_real_mode(), - get_timestamp().data()); - - utils::compression::zip::archive zip_file{}; - zip_file.add("crash.dmp", create_minidump(exceptioninfo)); - zip_file.add("info.txt", generate_crash_info(exceptioninfo)); - zip_file.write(crash_name, "H1-Mod Crash Dump"); - } - - bool is_harmless_error(const LPEXCEPTION_POINTERS exceptioninfo) - { - const auto code = exceptioninfo->ExceptionRecord->ExceptionCode; - return code == STATUS_INTEGER_OVERFLOW || code == STATUS_FLOAT_OVERFLOW || code == STATUS_SINGLE_STEP; - } - - LONG WINAPI exception_filter(const LPEXCEPTION_POINTERS exceptioninfo) - { - if (is_harmless_error(exceptioninfo)) - { - return EXCEPTION_CONTINUE_EXECUTION; - } - - write_minidump(exceptioninfo); - - exception_data.code = exceptioninfo->ExceptionRecord->ExceptionCode; - exception_data.address = exceptioninfo->ExceptionRecord->ExceptionAddress; - exceptioninfo->ContextRecord->Rip = get_reset_state_stub(); - - return EXCEPTION_CONTINUE_EXECUTION; - } - - LPTOP_LEVEL_EXCEPTION_FILTER WINAPI set_unhandled_exception_filter_stub(LPTOP_LEVEL_EXCEPTION_FILTER) - { - // Don't register anything here... - return &exception_filter; - } - } - - class component final : public component_interface - { - public: - component() - { - SetUnhandledExceptionFilter(exception_filter); - } - - void post_load() override - { - SetUnhandledExceptionFilter(exception_filter); - utils::hook::jump(SetUnhandledExceptionFilter, set_unhandled_exception_filter_stub, true); - - scheduler::on_game_initialized([]() - { - is_initialized() = true; - }); - } - - void post_unpack() override - { - dvars::cg_legacyCrashHandling = dvars::register_bool("cg_legacyCrashHandling", - false, game::DVAR_FLAG_SAVED, true); - } - }; -} - -REGISTER_COMPONENT(exception::component) diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp deleted file mode 100644 index d4eda37f..00000000 --- a/src/client/component/fastfiles.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "fastfiles.hpp" - -#include "command.hpp" -#include "console.hpp" - -#include -#include - -namespace fastfiles -{ - static utils::concurrency::container current_fastfile; - - namespace - { - utils::hook::detour db_try_load_x_file_internal_hook; - - void db_try_load_x_file_internal(const char* zone_name, const int flags) - { - printf("Loading fastfile %s\n", zone_name); - current_fastfile.access([&](std::string& fastfile) - { - fastfile = zone_name; - }); - db_try_load_x_file_internal_hook.invoke(zone_name, flags); - } - } - - std::string get_current_fastfile() - { - return current_fastfile.access([&](std::string& fastfile) - { - return fastfile; - }); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - db_try_load_x_file_internal_hook.create( - SELECT_VALUE(0x1401CDDD0, 0x1402BFFE0), &db_try_load_x_file_internal); - } - }; -} - -REGISTER_COMPONENT(fastfiles::component) diff --git a/src/client/component/fastfiles.hpp b/src/client/component/fastfiles.hpp deleted file mode 100644 index ac26d2ec..00000000 --- a/src/client/component/fastfiles.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "game/game.hpp" - -namespace fastfiles -{ - std::string get_current_fastfile(); -} diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp deleted file mode 100644 index da11d2e4..00000000 --- a/src/client/component/filesystem.cpp +++ /dev/null @@ -1,94 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "filesystem.hpp" -#include "game_module.hpp" - -#include "game/game.hpp" -#include "dvars.hpp" - -#include -#include - -namespace filesystem -{ - namespace - { - bool custom_path_registered = false; - - std::string get_binary_directory() - { - const auto dir = game_module::get_host_module().get_folder(); - return utils::string::replace(dir, "/", "\\"); - } - - void register_custom_path_stub(const char* path, const char* dir) - { - if (!custom_path_registered) - { - custom_path_registered = true; - - const auto launcher_dir = get_binary_directory(); - game::FS_AddLocalizedGameDirectory(launcher_dir.data(), "data"); - } - - game::FS_AddLocalizedGameDirectory(path, dir); - } - - void fs_startup_stub(const char* gamename) - { - custom_path_registered = false; - game::FS_Startup(gamename); - } - } - - file::file(std::string name) - : name_(std::move(name)) - { - char* buffer{}; - const auto size = game::FS_ReadFile(this->name_.data(), &buffer); - - if (size >= 0 && buffer) - { - this->valid_ = true; - this->buffer_.append(buffer, size); - game::FS_FreeFile(buffer); - } - } - - bool file::exists() const - { - return this->valid_; - } - - const std::string& file::get_buffer() const - { - return this->buffer_; - } - - const std::string& file::get_name() const - { - return this->name_; - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - // Set fs_basegame - dvars::override::register_string("fs_basegame", "h1-mod", game::DVAR_FLAG_WRITE); - - utils::hook::call(SELECT_VALUE(0x1403B76E2, 0x1404ED3E2), fs_startup_stub); - if (game::environment::is_mp()) - { - utils::hook::call(0x1404ED823, fs_startup_stub); - } - - utils::hook::call(SELECT_VALUE(0x1403B8D31, 0x1404EE3D0), register_custom_path_stub); - utils::hook::call(SELECT_VALUE(0x1403B8D51, 0x1404EE3F0), register_custom_path_stub); - utils::hook::call(SELECT_VALUE(0x1403B8D90, 0x1404EE42F), register_custom_path_stub); - } - }; -} - -REGISTER_COMPONENT(filesystem::component) \ No newline at end of file diff --git a/src/client/component/filesystem.hpp b/src/client/component/filesystem.hpp deleted file mode 100644 index 6cec8c87..00000000 --- a/src/client/component/filesystem.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -namespace filesystem -{ - class file - { - public: - file(std::string name); - - bool exists() const; - const std::string& get_buffer() const; - const std::string& get_name() const; - - private: - bool valid_ = false; - std::string name_; - std::string buffer_; - }; -} \ No newline at end of file diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp deleted file mode 100644 index db471119..00000000 --- a/src/client/component/fps.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include -#include -#include - -namespace fps -{ - namespace - { - game::dvar_t* cg_drawfps; - game::dvar_t* cg_drawping; - - float fps_color_good[4] = {0.6f, 1.0f, 0.0f, 1.0f}; - float fps_color_ok[4] = {1.0f, 0.7f, 0.3f, 1.0f}; - float fps_color_bad[4] = {1.0f, 0.3f, 0.3f, 1.0f}; - float ping_color[4] = {1.0f, 1.0f, 1.0f, 0.65f}; - - struct cg_perf_data - { - std::chrono::time_point perf_start; - std::int32_t current_ms{}; - std::int32_t previous_ms{}; - std::int32_t frame_ms{}; - std::int32_t history[32]{}; - std::int32_t count{}; - std::int32_t index{}; - std::int32_t instant{}; - std::int32_t total{}; - float average{}; - float variance{}; - std::int32_t min{}; - std::int32_t max{}; - }; - - cg_perf_data cg_perf{}; - - void perf_calc_fps(cg_perf_data* data, const std::int32_t value) - { - data->history[data->index % 32] = value; - data->instant = value; - data->min = 0x7FFFFFFF; - data->max = 0; - data->average = 0.0f; - data->variance = 0.0f; - data->total = 0; - - for (auto i = 0; i < data->count; ++i) - { - const std::int32_t idx = (data->index - i) % 32; - - if (idx < 0) - { - break; - } - - data->total += data->history[idx]; - - if (data->min > data->history[idx]) - { - data->min = data->history[idx]; - } - - if (data->max < data->history[idx]) - { - data->max = data->history[idx]; - } - } - - data->average = static_cast(data->total) / static_cast(data->count); - ++data->index; - } - - void perf_update() - { - cg_perf.count = 32; - - cg_perf.current_ms = static_cast(std::chrono::duration_cast( - std::chrono::high_resolution_clock::now() - cg_perf.perf_start).count()); - cg_perf.frame_ms = cg_perf.current_ms - cg_perf.previous_ms; - cg_perf.previous_ms = cg_perf.current_ms; - - perf_calc_fps(&cg_perf, cg_perf.frame_ms); - - utils::hook::invoke(SELECT_VALUE(0x1405487A0, 0x1406575A0)); // H1(1.4) - } - - void cg_draw_fps() - { - if (cg_drawfps->current.integer > 0) - { - const auto fps = static_cast(static_cast(1000.0f / static_cast(cg_perf. - average)) - + 9.313225746154785e-10); - - const auto font = game::R_RegisterFont("fonts/fira_mono_regular.ttf", 25); - const auto fps_string = utils::string::va("%i", fps); - - const auto x = (game::ScrPlace_GetViewPlacement()->realViewportSize[0] - 15.0f) - game::R_TextWidth( - fps_string, 0x7FFFFFFF, font); - const auto y = font->pixelHeight + 10.f; - - const auto fps_color = fps >= 60 ? fps_color_good : (fps >= 30 ? fps_color_ok : fps_color_bad); - game::R_AddCmdDrawText(fps_string, 0x7FFFFFFF, font, x, y, 1.f, 1.f, 0.0f, fps_color, 6); - } - } - - void cg_draw_ping() - { - if (cg_drawping->current.integer > 0 && game::CL_IsCgameInitialized() && !game::VirtualLobby_Loaded()) - { - const auto ping = *reinterpret_cast(0x142D106F0); - - const auto font = game::R_RegisterFont("fonts/consolefont", 20); - const auto ping_string = utils::string::va("Ping: %i", ping); - - const auto x = (game::ScrPlace_GetViewPlacement()->realViewportSize[0] - 375.0f) - game::R_TextWidth( - ping_string, 0x7FFFFFFF, font); - - const auto y = font->pixelHeight + 15.f; - game::R_AddCmdDrawText(ping_string, 0x7FFFFFFF, font, x, y, 1.f, 1.f, 0.0f, ping_color, 6); - } - } - - game::dvar_t* cg_draw_fps_register_stub(const char* name, const char** _enum, const int value, unsigned int /*flags*/, - const char* desc) - { - cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, false); - return cg_drawfps; - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_dedi()) - { - return; - } - - // fps setup - cg_perf.perf_start = std::chrono::high_resolution_clock::now(); - utils::hook::call(SELECT_VALUE(0x14018D261, 0x14025B747), &perf_update); - - // change cg_drawfps flags to saved - utils::hook::call(SELECT_VALUE(0x140139F48, 0x140222A46), &cg_draw_fps_register_stub); - - scheduler::loop(cg_draw_fps, scheduler::pipeline::renderer); - - if (game::environment::is_sp()) - { - cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, false); - } - - if (game::environment::is_mp()) - { - // fix ping value - utils::hook::nop(0x14025AC41, 2); - - cg_drawping = dvars::register_int("cg_drawPing", 0, 0, 1, game::DVAR_FLAG_SAVED, true); - - scheduler::loop(cg_draw_ping, scheduler::pipeline::renderer); - } - } - }; -} - -REGISTER_COMPONENT(fps::component) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp deleted file mode 100644 index cf7c3056..00000000 --- a/src/client/component/game_console.cpp +++ /dev/null @@ -1,793 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "game_console.hpp" -#include "command.hpp" -#include "console.hpp" -#include "scheduler.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include -#include -#include - -#include "version.hpp" - -#define console_font game::R_RegisterFont("fonts/fira_mono_regular.ttf", 18) -#define material_white game::Material_RegisterHandle("white") - -namespace game_console -{ - namespace - { - struct console_globals - { - float x{}; - float y{}; - float left_x{}; - float font_height{}; - bool may_auto_complete{}; - char auto_complete_choice[64]{}; - int info_line_count{}; - }; - - using output_queue = std::deque; - - struct ingame_console - { - char buffer[256]{}; - int cursor{}; - int font_height{}; - int visible_line_count{}; - int visible_pixel_width{}; - float screen_min[2]{}; //left & top - float screen_max[2]{}; //right & bottom - console_globals globals{}; - bool output_visible{}; - int display_line_offset{}; - int 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{}; - - float color_white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - float color_title[4] = {0.25f, 0.62f, 0.3f, 1.0f}; - - void clear() - { - strncpy_s(con.buffer, "", sizeof(con.buffer)); - con.cursor = 0; - - fixed_input = ""; - matches.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(); - - con.output_visible = false; - *game::keyCatchers ^= 1; - } - - void toggle_console_output() - { - con.output_visible = con.output_visible == 0; - } - - void check_resize() - { - con.screen_min[0] = 6.0f; - con.screen_min[1] = 6.0f; - con.screen_max[0] = game::ScrPlace_GetViewPlacement()->realViewportSize[0] - 6.0f; - con.screen_max[1] = game::ScrPlace_GetViewPlacement()->realViewportSize[1] - 6.0f; - - if (console_font) - { - con.font_height = console_font->pixelHeight; - con.visible_line_count = static_cast((con.screen_max[1] - con.screen_min[1] - (con.font_height * 2) - ) - - 24.0f) / con.font_height; - con.visible_pixel_width = static_cast(((con.screen_max[0] - con.screen_min[0]) - 10.0f) - 18.0f); - } - else - { - con.font_height = 0; - con.visible_line_count = 0; - con.visible_pixel_width = 0; - } - } - - void draw_box(const float x, const float y, const float w, const float h, float* color) - { - game::vec4_t dark_color; - - dark_color[0] = color[0] * 0.5f; - dark_color[1] = color[1] * 0.5f; - dark_color[2] = color[2] * 0.5f; - dark_color[3] = color[3]; - - game::R_AddCmdDrawStretchPic(x, y, w, h, 0.0f, 0.0f, 0.0f, 0.0f, color, material_white); - game::R_AddCmdDrawStretchPic(x, y, 2.0f, h, 0.0f, 0.0f, 0.0f, 0.0f, dark_color, material_white); - game::R_AddCmdDrawStretchPic((x + w) - 2.0f, y, 2.0f, h, 0.0f, 0.0f, 0.0f, 0.0f, dark_color, - material_white); - game::R_AddCmdDrawStretchPic(x, y, w, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, dark_color, material_white); - game::R_AddCmdDrawStretchPic(x, (y + h) - 2.0f, w, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, dark_color, - material_white); - } - - void draw_input_box(const int lines, float* color) - { - draw_box( - con.globals.x - 6.0f, - con.globals.y - 6.0f, - (con.screen_max[0] - con.screen_min[0]) - ((con.globals.x - 6.0f) - con.screen_min[0]), - (lines * con.globals.font_height) + 12.0f, - color); - } - - void draw_input_text_and_over(const char* str, float* color) - { - game::R_AddCmdDrawText(str, 0x7FFFFFFF, console_font, con.globals.x, - con.globals.y + con.globals.font_height, 1.0f, - 1.0f, 0.0f, color, 0); - con.globals.x = game::R_TextWidth(str, 0, console_font) + con.globals.x + 6.0f; - } - - void 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.globals.font_height + 12.0f; - const auto _y = con.globals.y - 3.0f + con.globals.font_height + 12.0f; - const auto _w = (con.screen_max[0] - con.screen_min[0]) - ((con.globals.x - 6.0f) - con.screen_min[0]); - - draw_box(con.globals.x - 6.0f, _y, _w, _h, color); - } - - void draw_hint_text(const int line, const char* text, float* color, const float offset = 0.0f) - { - const auto _y = con.globals.font_height + con.globals.y + (con.globals.font_height * (line + 1)) + 15.0f; - - game::R_AddCmdDrawText(text, 0x7FFFFFFF, console_font, con.globals.x + offset, _y, 1.0f, 1.0f, 0.0f, color, 0); - } - - bool match_compare(const std::string& input, const std::string& text, const bool exact) - { - if (exact && text == input) return true; - if (!exact && text.find(input) != std::string::npos) return true; - return false; - } - - void find_matches(std::string input, std::vector& suggestions, const bool exact) - { - input = utils::string::to_lower(input); - - for (const auto& dvar : dvars::dvar_list) - { - auto name = utils::string::to_lower(dvar); - if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) - { - suggestions.push_back(dvar); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) - { - suggestions.push_back(input.data()); - } - - game::cmd_function_s* cmd = (*game::cmd_functions); - while (cmd) - { - if (cmd->name) - { - std::string name = utils::string::to_lower(cmd->name); - - if (match_compare(input, name, exact)) - { - suggestions.push_back(cmd->name); - } - - if (exact && suggestions.size() > 1) - { - return; - } - } - - cmd = cmd->next; - } - } - - void draw_input() - { - con.globals.font_height = static_cast(console_font->pixelHeight); - con.globals.x = con.screen_min[0] + 6.0f; - con.globals.y = con.screen_min[1] + 6.0f; - con.globals.left_x = con.screen_min[0] + 6.0f; - - draw_input_box(1, dvars::con_inputBoxColor->current.vector); - draw_input_text_and_over("H1-Mod: " VERSION ">", color_title); - - con.globals.left_x = con.globals.x; - con.globals.auto_complete_choice[0] = 0; - - game::R_AddCmdDrawTextWithCursor(con.buffer, 0x7FFFFFFF, console_font, 18, con.globals.x, - con.globals.y + con.globals.font_height, 1.0f, 1.0f, 0, color_white, 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); - } - - fixed_input = input; - } - - con.globals.may_auto_complete = false; - if (matches.size() > 24) - { - draw_hint_box(1, dvars::con_inputHintBoxColor->current.vector); - draw_hint_text(0, utils::string::va("%i matches (too many to show here)", matches.size()), - dvars::con_inputDvarMatchColor->current.vector); - } - else if (matches.size() == 1) - { - auto* const dvar = game::Dvar_FindVar(matches[0].data()); - const auto line_count = dvar ? 2 : 1; - - draw_hint_box(line_count, dvars::con_inputHintBoxColor->current.vector); - draw_hint_text(0, matches[0].data(), dvar - ? dvars::con_inputDvarMatchColor->current.vector - : dvars::con_inputCmdMatchColor->current.vector); - - if (dvar) - { - const auto offset = (con.screen_max[0] - con.globals.x) / 2.5f; - - draw_hint_text(0, game::Dvar_ValueToString(dvar, dvar->current), - dvars::con_inputDvarValueColor->current.vector, offset); - draw_hint_text(1, " default", dvars::con_inputDvarInactiveValueColor->current.vector); - draw_hint_text(1, game::Dvar_ValueToString(dvar, dvar->reset), - dvars::con_inputDvarInactiveValueColor->current.vector, offset); - } - - strncpy_s(con.globals.auto_complete_choice, matches[0].data(), 64); - con.globals.may_auto_complete = true; - } - else if (matches.size() > 1) - { - draw_hint_box(static_cast(matches.size()), dvars::con_inputHintBoxColor->current.vector); - - const auto offset = (con.screen_max[0] - con.globals.x) / 2.5f; - - for (size_t i = 0; i < matches.size(); i++) - { - auto* const dvar = game::Dvar_FindVar(matches[i].data()); - - draw_hint_text(static_cast(i), matches[i].data(), - dvar - ? dvars::con_inputDvarMatchColor->current.vector - : dvars::con_inputCmdMatchColor->current.vector); - - if (dvar) - { - draw_hint_text(static_cast(i), game::Dvar_ValueToString(dvar, dvar->current), - dvars::con_inputDvarValueColor->current.vector, offset); - } - } - - strncpy_s(con.globals.auto_complete_choice, matches[0].data(), 64); - con.globals.may_auto_complete = true; - } - } - - void draw_output_scrollbar(const float x, float y, const float width, const float height, output_queue& output) - { - const auto _x = (x + width) - 10.0f; - draw_box(_x, y, 10.0f, height, dvars::con_outputBarColor->current.vector); - - auto _height = height; - if (output.size() > con.visible_line_count) - { - const auto percentage = static_cast(con.visible_line_count) / output.size(); - _height *= percentage; - - const auto remainingSpace = height - _height; - const 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, dvars::con_outputSliderColor->current.vector); - } - - void draw_output_text(const float x, float y, output_queue& output) - { - const 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++) - { - y = console_font->pixelHeight + y; - - const auto index = i + con.display_line_offset; - if (index >= output.size()) - { - break; - } - - game::R_AddCmdDrawText(output.at(index).data(), 0x7FFF, console_font, x, y + offset, 1.0f, 1.0f, - 0.0f, color_white, 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, dvars::con_outputWindowColor->current.vector); - - const auto x = con.screen_min[0] + 6.0f; - const auto y = (con.screen_min[1] + 32.0f) + 6.0f; - const auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f; - const auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f; - - game::R_AddCmdDrawText("H1-Mod 1.4", 0x7FFFFFFF, console_font, x, - ((height - 16.0f) + y) + console_font->pixelHeight, 1.0f, 1.0f, 0.0f, color_title, 0); - - draw_output_scrollbar(x, y, width, height, output); - draw_output_text(x, y, output); - }); - } - - void draw_console() - { - check_resize(); - - if (*game::keyCatchers & 1) - { - if (!(*game::keyCatchers & 1)) - { - con.output_visible = false; - } - - if (con.output_visible) - { - draw_output_window(); - } - - draw_input(); - } - } - } - - void print_internal(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 int type, const std::string& data) - { - try - { - if (game::environment::is_dedi()) - { - return; - } - } - catch (std::exception&) - { - return; - } - - const auto lines = utils::string::split(data, '\n'); - for (const auto& line : lines) - { - print_internal(type == console::con_type_info ? line : "^"s.append(std::to_string(type)).append(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.globals.may_auto_complete) - { - const auto first_char = con.buffer[0]; - - clear(); - - if (first_char == '\\' || first_char == '/') - { - con.buffer[0] = first_char; - con.buffer[1] = '\0'; - } - - strncat_s(con.buffer, con.globals.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(); - con.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_F10) - { - if (!game::Com_InFrontEnd()) - { - return false; - } - - game::Cmd_ExecuteSingleCommand(local_client_num, 0, "lui_open menu_systemlink_join\n"); - } - - if (key == game::keyNum_t::K_GRAVE || key == game::keyNum_t::K_TILDE) - { - if (!down) - { - return false; - } - - if (game::playerKeys[local_client_num].keys[game::keyNum_t::K_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(); - - 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(); - - 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); - - console::info("]%s\n", con.buffer); - - if (history.size() > 10) - { - history.erase(history.begin() + 10); - } - - history_index = -1; - - clear(); - } - } - } - - return true; - } - - - class component final : public component_interface - { - public: - void post_load() override - { - if (game::environment::is_dedi()) - { - return; - } - - //scheduler::loop(draw_console, scheduler::pipeline::renderer); - } - - void post_unpack() override - { - scheduler::loop(draw_console, scheduler::pipeline::renderer); - - - if (game::environment::is_dedi()) - { - return; - } - - // initialize our structs - con.cursor = 0; - con.visible_line_count = 0; - con.output_visible = false; - con.display_line_offset = 0; - con.line_count = 0; - strncpy_s(con.buffer, "", 256); - - con.globals.x = 0.0f; - con.globals.y = 0.0f; - con.globals.left_x = 0.0f; - con.globals.font_height = 0.0f; - con.globals.may_auto_complete = false; - con.globals.info_line_count = 0; - strncpy_s(con.globals.auto_complete_choice, "", 64); - - // add clear command - command::add("clear", [&]() - { - clear(); - con.line_count = 0; - con.display_line_offset = 0; - con.output.access([](output_queue& output) - { - output.clear(); - }); - history_index = -1; - history.clear(); - }); - - // add our dvars - dvars::con_inputBoxColor = dvars::register_vec4("con_inputBoxColor", 0.2f, 0.2f, 0.2f, 0.9f, 0.0f, 1.0f, - game::DVAR_FLAG_SAVED, - "color of console input box"); - dvars::con_inputHintBoxColor = dvars::register_vec4("con_inputHintBoxColor", 0.3f, 0.3f, 0.3f, 1.0f, - 0.0f, 1.0f, - game::DVAR_FLAG_SAVED, "color of console input hint box"); - dvars::con_outputBarColor = dvars::register_vec4("con_outputBarColor", 0.5f, 0.5f, 0.5f, 0.6f, 0.0f, - 1.0f, game::DVAR_FLAG_SAVED, - "color of console output bar"); - dvars::con_outputSliderColor = dvars::register_vec4("con_outputSliderColor", 1.0f, 0.8f, 0.0f, 1.0f, - 0.0f, 1.0f, - game::DVAR_FLAG_SAVED, "color of console output slider"); - dvars::con_outputWindowColor = dvars::register_vec4("con_outputWindowColor", 0.25f, 0.25f, 0.25f, 0.85f, - 0.0f, - 1.0f, game::DVAR_FLAG_SAVED, "color of console output window"); - dvars::con_inputDvarMatchColor = dvars::register_vec4("con_inputDvarMatchColor", 1.0f, 1.0f, 0.8f, 1.0f, - 0.0f, - 1.0f, game::DVAR_FLAG_SAVED, "color of console matched dvar"); - dvars::con_inputDvarValueColor = dvars::register_vec4("con_inputDvarValueColor", 1.0f, 1.0f, 0.8f, 1.0f, - 0.0f, - 1.0f, game::DVAR_FLAG_SAVED, "color of console matched dvar value"); - dvars::con_inputDvarInactiveValueColor = dvars::register_vec4( - "con_inputDvarInactiveValueColor", 0.8f, 0.8f, - 0.8f, 1.0f, 0.0f, 1.0f, game::DVAR_FLAG_SAVED, - "color of console inactive dvar value"); - dvars::con_inputCmdMatchColor = dvars::register_vec4("con_inputCmdMatchColor", 0.80f, 0.80f, 1.0f, 1.0f, - 0.0f, - 1.0f, game::DVAR_FLAG_SAVED, "color of console matched command"); - } - }; -} - -REGISTER_COMPONENT(game_console::component) diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp deleted file mode 100644 index cdc001a7..00000000 --- a/src/client/component/game_console.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace game_console -{ - bool console_char_event(int local_client_num, int key); - bool console_key_event(int local_client_num, int key, int down); -} \ No newline at end of file diff --git a/src/client/component/game_module.cpp b/src/client/component/game_module.cpp index bd984624..9bc79de0 100644 --- a/src/client/component/game_module.cpp +++ b/src/client/component/game_module.cpp @@ -1,6 +1,7 @@ #include #include "loader/component_loader.hpp" #include "game_module.hpp" +#include "game/game.hpp" #include @@ -90,7 +91,7 @@ namespace game_module utils::nt::library get_game_module() { - static utils::nt::library game{HMODULE(0x140000000)}; + static utils::nt::library game{HMODULE(game::base_address)}; return game; } diff --git a/src/client/component/localized_strings.cpp b/src/client/component/localized_strings.cpp deleted file mode 100644 index 55b41d65..00000000 --- a/src/client/component/localized_strings.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "localized_strings.hpp" -#include -#include -#include -#include "game/game.hpp" - -namespace localized_strings -{ - namespace - { - utils::hook::detour seh_string_ed_get_string_hook; - - using localized_map = std::unordered_map; - utils::concurrency::container localized_overrides; - - const char* seh_string_ed_get_string(const char* reference) - { - return localized_overrides.access([&](const localized_map& map) - { - const auto entry = map.find(reference); - if (entry != map.end()) - { - return utils::string::va("%s", entry->second.data()); - } - - return seh_string_ed_get_string_hook.invoke(reference); - }); - } - } - - void override(const std::string& key, const std::string& value) - { - localized_overrides.access([&](localized_map& map) - { - map[key] = value; - }); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - // Change some localized strings - seh_string_ed_get_string_hook.create(SELECT_VALUE(0, 0x585DA0_b), &seh_string_ed_get_string); // H1-STEAM(1.15) - } - }; -} - -REGISTER_COMPONENT(localized_strings::component) diff --git a/src/client/component/localized_strings.hpp b/src/client/component/localized_strings.hpp deleted file mode 100644 index 01d15907..00000000 --- a/src/client/component/localized_strings.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -namespace localized_strings -{ - void override(const std::string& key, const std::string& value); -} \ No newline at end of file diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp deleted file mode 100644 index fc949d92..00000000 --- a/src/client/component/logfile.cpp +++ /dev/null @@ -1,317 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "scheduler.hpp" - -#include "game/scripting/entity.hpp" -#include "game/scripting/execution.hpp" -#include "game/scripting/lua/value_conversion.hpp" -#include "game/scripting/lua/error.hpp" - -#include - -#include "logfile.hpp" - -namespace logfile -{ - std::unordered_map vm_execute_hooks; - - namespace - { - utils::hook::detour scr_player_killed_hook; - utils::hook::detour scr_player_damage_hook; - - std::vector player_killed_callbacks; - std::vector player_damage_callbacks; - - utils::hook::detour vm_execute_hook; - char empty_function[2] = {0x32, 0x34}; // CHECK_CLEAR_PARAMS, END - bool hook_enabled = true; - - sol::lua_value convert_entity(lua_State* state, const game::mp::gentity_s* ent) - { - if (!ent) - { - return {}; - } - - const scripting::entity player{game::Scr_GetEntityId(ent->s.entityNum, 0)}; - return scripting::lua::convert(state, player); - } - - std::string get_weapon_name(unsigned int weapon, bool isAlternate) - { - char output[1024] = {0}; - game::BG_GetWeaponNameComplete(weapon, isAlternate, output, 1024); - return output; - } - - sol::lua_value convert_vector(lua_State* state, const float* vec) - { - if (!vec) - { - return {}; - } - - const auto vec_ = scripting::vector(vec); - return scripting::lua::convert(state, vec_); - } - - std::string convert_mod(const int meansOfDeath) - { - const auto value = reinterpret_cast(0x140FEC3F0)[meansOfDeath]; - const auto string = game::SL_ConvertToString(*value); - return string; - } - - void scr_player_killed_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, - game::mp::gentity_s* attacker, int damage, const int meansOfDeath, const unsigned int weapon, - const bool isAlternate, const float* vDir, const unsigned int hitLoc, int psTimeOffset, int deathAnimDuration) - { - { - const std::string hitloc = reinterpret_cast(0x140FEC4D0)[hitLoc]; - const auto mod_ = convert_mod(meansOfDeath); - - const auto weapon_ = get_weapon_name(weapon, isAlternate); - - for (const auto& callback : player_killed_callbacks) - { - const auto state = callback.lua_state(); - - const auto self_ = convert_entity(state, self); - const auto inflictor_ = convert_entity(state, inflictor); - const auto attacker_ = convert_entity(state, attacker); - - const auto dir = convert_vector(state, vDir); - - const auto result = callback(self_, inflictor_, attacker_, damage, - mod_, weapon_, dir, hitloc, psTimeOffset, deathAnimDuration); - - scripting::lua::handle_error(result); - - if (result.valid() && result.get_type() == sol::type::number) - { - damage = result.get(); - } - } - - if (damage == 0) - { - return; - } - } - - scr_player_killed_hook.invoke(self, inflictor, attacker, damage, meansOfDeath, - weapon, isAlternate, vDir, hitLoc, psTimeOffset, deathAnimDuration); - } - - void scr_player_damage_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, - game::mp::gentity_s* attacker, int damage, int dflags, const int meansOfDeath, - const unsigned int weapon, const bool isAlternate, const float* vPoint, - const float* vDir, const unsigned int hitLoc, const int timeOffset) - { - { - const std::string hitloc = reinterpret_cast(0x140FEC4D0)[hitLoc]; - const auto mod_ = convert_mod(meansOfDeath); - - const auto weapon_ = get_weapon_name(weapon, isAlternate); - - for (const auto& callback : player_damage_callbacks) - { - const auto state = callback.lua_state(); - - const auto self_ = convert_entity(state, self); - const auto inflictor_ = convert_entity(state, inflictor); - const auto attacker_ = convert_entity(state, attacker); - - const auto point = convert_vector(state, vPoint); - const auto dir = convert_vector(state, vDir); - - const auto result = callback(self_, inflictor_, attacker_, - damage, dflags, mod_, weapon_, point, dir, hitloc); - - scripting::lua::handle_error(result); - - if (result.valid() && result.get_type() == sol::type::number) - { - damage = result.get(); - } - } - - if (damage == 0) - { - return; - } - } - - scr_player_damage_hook.invoke(self, inflictor, attacker, damage, dflags, - meansOfDeath, weapon, isAlternate, vPoint, vDir, hitLoc, timeOffset); - } - - void client_command_stub(const int clientNum) - { - auto self = &game::mp::g_entities[clientNum]; - char cmd[1024] = {0}; - - game::SV_Cmd_ArgvBuffer(0, cmd, 1024); - - if (cmd == "say"s || cmd == "say_team"s) - { - auto hidden = false; - std::string message(game::ConcatArgs(1)); - - hidden = message[1] == '/'; - message.erase(0, hidden ? 2 : 1); - - scheduler::once([cmd, message, self]() - { - const scripting::entity level{*game::levelEntityId}; - const scripting::entity player{game::Scr_GetEntityId(self->s.entityNum, 0)}; - - scripting::notify(level, cmd, {player, message}); - scripting::notify(player, cmd, {message}); - }, scheduler::pipeline::server); - - if (hidden) - { - return; - } - } - - // ClientCommand - return utils::hook::invoke(0x140336000, clientNum); - } - - void g_shutdown_game_stub(const int freeScripts) - { - { - const scripting::entity level{*game::levelEntityId}; - scripting::notify(level, "shutdownGame_called", {1}); - } - - // G_ShutdownGame - return utils::hook::invoke(0x140345A60, freeScripts); - } - - unsigned int local_id_to_entity(unsigned int local_id) - { - const auto variable = game::scr_VarGlob->objectVariableValue[local_id]; - return variable.u.f.next; - } - - bool execute_vm_hook(const char* pos) - { - if (vm_execute_hooks.find(pos) == vm_execute_hooks.end()) - { - hook_enabled = true; - return false; - } - - if (!hook_enabled && pos > reinterpret_cast(vm_execute_hooks.size())) - { - hook_enabled = true; - return false; - } - - const auto hook = vm_execute_hooks[pos]; - const auto state = hook.lua_state(); - - const scripting::entity self = local_id_to_entity(game::scr_VmPub->function_frame->fs.localId); - - std::vector args; - - const auto top = game::scr_function_stack->top; - - for (auto* value = top; value->type != game::SCRIPT_END; --value) - { - args.push_back(scripting::lua::convert(state, *value)); - } - - const auto result = hook(self, sol::as_args(args)); - scripting::lua::handle_error(result); - - return true; - } - - void vm_execute_stub(utils::hook::assembler& a) - { - const auto replace = a.newLabel(); - const auto end = a.newLabel(); - - a.pushad64(); - - a.mov(rcx, r14); - a.call_aligned(execute_vm_hook); - - a.cmp(al, 0); - a.jne(replace); - - a.popad64(); - a.jmp(end); - - a.bind(end); - - a.movzx(r15d, byte_ptr(r14)); - a.inc(r14); - a.mov(dword_ptr(rbp, 0xA4), r15d); - - a.jmp(SELECT_VALUE(0x140376663, 0x140444653)); - - a.bind(replace); - - a.popad64(); - a.mov(r14, reinterpret_cast(empty_function)); - a.jmp(end); - } - } - - void add_player_damage_callback(const sol::protected_function& callback) - { - player_damage_callbacks.push_back(callback); - } - - void add_player_killed_callback(const sol::protected_function& callback) - { - player_killed_callbacks.push_back(callback); - } - - void clear_callbacks() - { - player_damage_callbacks.clear(); - player_killed_callbacks.clear(); - vm_execute_hooks.clear(); - } - - void enable_vm_execute_hook() - { - hook_enabled = true; - } - - void disable_vm_execute_hook() - { - hook_enabled = false; - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_sp()) - { - return; - } - - utils::hook::call(0x14048191D, client_command_stub); - - scr_player_damage_hook.create(0x14037DC50, scr_player_damage_stub); - scr_player_killed_hook.create(0x14037DF30, scr_player_killed_stub); - - utils::hook::call(0x140484EC0, g_shutdown_game_stub); - utils::hook::call(0x1404853C1, g_shutdown_game_stub); - - utils::hook::jump(SELECT_VALUE(0x140376655, 0x140444645), utils::hook::assemble(vm_execute_stub), true); - } - }; -} - -REGISTER_COMPONENT(logfile::component) \ No newline at end of file diff --git a/src/client/component/logfile.hpp b/src/client/component/logfile.hpp deleted file mode 100644 index 77f699c8..00000000 --- a/src/client/component/logfile.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace logfile -{ - extern std::unordered_map vm_execute_hooks; - - void add_player_damage_callback(const sol::protected_function& callback); - void add_player_killed_callback(const sol::protected_function& callback); - void clear_callbacks(); - - void enable_vm_execute_hook(); - void disable_vm_execute_hook(); -} \ No newline at end of file diff --git a/src/client/component/lui.cpp b/src/client/component/lui.cpp deleted file mode 100644 index d3a7edca..00000000 --- a/src/client/component/lui.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" - -#include "command.hpp" -#include "console.hpp" - -#include - -namespace lui -{ - class component final : public component_interface - { - public: - void post_unpack() override - { - // Don't show create cod account popup - //utils::hook::set(0x14017C957, 0); // H1(1.4) - -//#ifdef _DEBUG - // Enable development menus (causes issues in sp) - //utils::hook::set(SELECT_VALUE(0x1400B4ABC, 0x1401AB779), 1); -//#endif - - command::add("lui_open", [](const command::params& params) - { - if (params.size() <= 1) - { - console::info("usage: lui_open \n"); - return; - } - - game::LUI_OpenMenu(0, params[1], 0, 0, 0); - }); - - command::add("lui_open_popup", [](const command::params& params) - { - if (params.size() <= 1) - { - console::info("usage: lui_open_popup \n"); - return; - } - - game::LUI_OpenMenu(0, params[1], 1, 0, 0); - }); - - command::add("runMenuScript", [](const command::params& params) - { - const auto args_str = params.join(1); - const auto* args = args_str.data(); - game::UI_RunMenuScript(0, &args); - }); - } - }; -} - -REGISTER_COMPONENT(lui::component) diff --git a/src/client/component/map_rotation.cpp b/src/client/component/map_rotation.cpp deleted file mode 100644 index 216cbfcd..00000000 --- a/src/client/component/map_rotation.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "command.hpp" -#include "scheduler.hpp" -#include -#include -#include "game/game.hpp" -#include - -namespace map_rotation -{ - DWORD previousPriority; - namespace - { - void set_dvar(const std::string& dvar, const std::string& value) - { - command::execute(utils::string::va("%s \"%s\"", dvar.data(), value.data()), true); - } - - void set_gametype(const std::string& gametype) - { - set_dvar("g_gametype", gametype); - } - - void launch_map(const std::string& mapname) - { - command::execute(utils::string::va("map %s", mapname.data()), false); - } - - void launch_default_map() - { - auto* mapname = game::Dvar_FindVar("mapname"); - if (mapname && mapname->current.string && strlen(mapname->current.string) && mapname->current.string != - "mp_vlobby_room"s) - { - launch_map(mapname->current.string); - } - else - { - launch_map("mp_crash"); - } - } - - std::string load_current_map_rotation() - { - auto* rotation = game::Dvar_FindVar("sv_mapRotationCurrent"); - if (!strlen(rotation->current.string)) - { - rotation = game::Dvar_FindVar("sv_mapRotation"); - set_dvar("sv_mapRotationCurrent", rotation->current.string); - } - - return rotation->current.string; - } - - std::vector parse_current_map_rotation() - { - const auto rotation = load_current_map_rotation(); - return utils::string::split(rotation, ' '); - } - - void store_new_rotation(const std::vector& elements, const size_t index) - { - std::string value{}; - - for (auto i = index; i < elements.size(); ++i) - { - if (i != index) - { - value.push_back(' '); - } - - value.append(elements[i]); - } - - set_dvar("sv_mapRotationCurrent", value); - } - - void change_process_priority() - { - auto* const dvar = game::Dvar_FindVar("sv_autoPriority"); - if (dvar && dvar->current.enabled) - { - scheduler::on_game_initialized([]() - { - //printf("=======================setting OLD priority=======================\n"); - SetPriorityClass(GetCurrentProcess(), previousPriority); - }, scheduler::pipeline::main, 1s); - - previousPriority = GetPriorityClass(GetCurrentProcess()); - //printf("=======================setting NEW priority=======================\n"); - SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); - } - } - - void perform_map_rotation() - { - if (game::Live_SyncOnlineDataFlags(0) != 0) - { - scheduler::on_game_initialized(perform_map_rotation, scheduler::pipeline::main, 1s); - return; - } - - const auto rotation = parse_current_map_rotation(); - - for (size_t i = 0; !rotation.empty() && i < (rotation.size() - 1); i += 2) - { - const auto& key = rotation[i]; - const auto& value = rotation[i + 1]; - - if (key == "gametype") - { - set_gametype(value); - } - else if (key == "map") - { - store_new_rotation(rotation, i + 2); - change_process_priority(); - if (!game::SV_MapExists(value.data())) - { - printf("map_rotation: '%s' map doesn't exist!\n", value.data()); - launch_default_map(); - return; - } - launch_map(value); - return; - } - else - { - printf("Invalid map rotation key: %s\n", key.data()); - } - } - - launch_default_map(); - } - - void trigger_map_rotation() - { - scheduler::schedule([]() - { - if (game::CL_IsCgameInitialized()) - { - return scheduler::cond_continue; - } - - command::execute("map_rotate", false); - return scheduler::cond_end; - }, scheduler::pipeline::main, 1s); - } - - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (!game::environment::is_dedi()) - { - return; - } - - scheduler::once([]() - { - dvars::register_string("sv_mapRotation", "", game::DVAR_FLAG_NONE, true); - dvars::register_string("sv_mapRotationCurrent", "", game::DVAR_FLAG_NONE, true); - dvars::register_string("sv_autoPriority", "", game::DVAR_FLAG_NONE, true); - }, scheduler::pipeline::main); - - command::add("map_rotate", &perform_map_rotation); - - // Hook GScr_ExitLevel - utils::hook::jump(0x140376630, &trigger_map_rotation); // not sure if working - - previousPriority = GetPriorityClass(GetCurrentProcess()); - } - }; -} - -REGISTER_COMPONENT(map_rotation::component) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index fb2a6f55..8069d61a 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -27,15 +27,8 @@ namespace network const auto cmd_string = utils::string::to_lower(command); auto& callbacks = get_callbacks(); const auto handler = callbacks.find(cmd_string); - - if (handler == callbacks.end()) - { - return false; - } - const auto offset = cmd_string.size() + 5; - - if (message->cursize <= offset) + if (message->cursize < offset || handler == callbacks.end()) { return false; } @@ -331,4 +324,4 @@ namespace network }; } -REGISTER_COMPONENT(network::component) +REGISTER_COMPONENT(network::component) \ No newline at end of file diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp deleted file mode 100644 index 0605afad..00000000 --- a/src/client/component/party.cpp +++ /dev/null @@ -1,630 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "party.hpp" -#include "console.hpp" -#include "command.hpp" -#include "network.hpp" -#include "scheduler.hpp" -#include "server_list.hpp" - -#include "steam/steam.hpp" - -#include -#include -#include -#include - -namespace party -{ - namespace - { - struct - { - game::netadr_s host{}; - std::string challenge{}; - bool hostDefined{false}; - } connect_state; - - std::string sv_motd; - int sv_maxclients; - - void perform_game_initialization() - { - command::execute("onlinegame 1", true); - command::execute("xstartprivateparty", true); - command::execute("xblive_privatematch 1", true); - command::execute("startentitlements", true); - } - - void connect_to_party(const game::netadr_s& target, const std::string& mapname, const std::string& gametype) - { - if (game::environment::is_sp()) - { - return; - } - - if (game::Live_SyncOnlineDataFlags(0) != 0) - { - // initialize the game after onlinedataflags is 32 (workaround) - if (game::Live_SyncOnlineDataFlags(0) == 32) - { - scheduler::once([=]() - { - command::execute("xstartprivateparty", true); - command::execute("disconnect", true); // 32 -> 0 - - connect_to_party(target, mapname, gametype); - }, scheduler::pipeline::main, 1s); - return; - } - else - { - scheduler::once([=]() - { - connect_to_party(target, mapname, gametype); - }, scheduler::pipeline::main, 1s); - return; - } - } - - perform_game_initialization(); - - // exit from virtuallobby - utils::hook::invoke(0x140256D40, 1); - - // CL_ConnectFromParty - char session_info[0x100] = {}; - utils::hook::invoke(0x140251560, 0, session_info, &target, mapname.data(), gametype.data()); - } - - std::string get_dvar_string(const std::string& dvar) - { - auto* dvar_value = game::Dvar_FindVar(dvar.data()); - if (dvar_value && dvar_value->current.string) - { - return dvar_value->current.string; - } - - return {}; - } - - int get_dvar_int(const std::string& dvar) - { - auto* dvar_value = game::Dvar_FindVar(dvar.data()); - if (dvar_value && dvar_value->current.integer) - { - return dvar_value->current.integer; - } - - return -1; - } - - bool get_dvar_bool(const std::string& dvar) - { - auto* dvar_value = game::Dvar_FindVar(dvar.data()); - if (dvar_value && dvar_value->current.enabled) - { - return dvar_value->current.enabled; - } - - return false; - } - - void didyouknow_stub(const char* dvar_name, const char* string) - { - if (!party::sv_motd.empty()) - { - string = party::sv_motd.data(); - } - - // This function either does Dvar_SetString or Dvar_RegisterString for the given dvar - utils::hook::invoke(0x1404FB210, dvar_name, string); - } - - void disconnect_stub() - { - if (!game::VirtualLobby_Loaded()) - { - if (game::CL_IsCgameInitialized()) - { - // CL_ForwardCommandToServer - utils::hook::invoke(0x140253480, 0, "disconnect"); - // CL_WritePacket - utils::hook::invoke(0x14024DB10, 0); - } - // CL_Disconnect - utils::hook::invoke(0x140252060, 0); - } - } - - utils::hook::detour cldisconnect_hook; - - void cl_disconnect_stub(int a1) - { - party::sv_motd.clear(); - cldisconnect_hook.invoke(a1); - } - - const auto drop_reason_stub = utils::hook::assemble([](utils::hook::assembler& a) - { - a.mov(rdx, rdi); - a.mov(ecx, 2); - a.jmp(0x140251F78); - }); - - void menu_error(const std::string& error) - { - utils::hook::invoke(0x1400DACC0, error.data(), "MENU_NOTICE"); - utils::hook::set(0x142C1DA98, 1); - } - } - - int get_client_num_by_name(const std::string& name) - { - for (auto i = 0; !name.empty() && i < *game::mp::svs_numclients; ++i) - { - if (game::mp::g_entities[i].client) - { - char client_name[16] = {0}; - strncpy_s(client_name, game::mp::g_entities[i].client->name, sizeof(client_name)); - game::I_CleanStr(client_name); - - if (client_name == name) - { - return i; - } - } - } - return -1; - } - - void reset_connect_state() - { - connect_state = {}; - } - - int get_client_count() - { - auto count = 0; - for (auto i = 0; i < *game::mp::svs_numclients; ++i) - { - if (game::mp::svs_clients[i].header.state >= 1) - { - ++count; - } - } - - return count; - } - - int get_bot_count() - { - auto count = 0; - for (auto i = 0; i < *game::mp::svs_numclients; ++i) - { - if (game::mp::svs_clients[i].header.state >= 1 && - game::SV_BotIsBot(i)) - { - ++count; - } - } - - return count; - } - - void connect(const game::netadr_s& target) - { - if (game::environment::is_sp()) - { - return; - } - - command::execute("lui_open_popup popup_acceptinginvite", false); - - connect_state.host = target; - connect_state.challenge = utils::cryptography::random::get_challenge(); - connect_state.hostDefined = true; - - network::send(target, "getInfo", connect_state.challenge); - } - - void start_map(const std::string& mapname) - { - if (game::Live_SyncOnlineDataFlags(0) > 32) - { - scheduler::once([=]() - { - command::execute("map " + mapname, false); - }, scheduler::pipeline::main, 1s); - } - else - { - if (!game::SV_MapExists(mapname.data())) - { - console::info("Map '%s' doesn't exist.\n", mapname.data()); - return; - } - - auto* current_mapname = game::Dvar_FindVar("mapname"); - if (current_mapname && utils::string::to_lower(current_mapname->current.string) == - utils::string::to_lower(mapname) && (game::SV_Loaded() && !game::VirtualLobby_Loaded())) - { - console::info("Restarting map: %s\n", mapname.data()); - command::execute("map_restart", false); - return; - } - - if (!game::environment::is_dedi()) - { - if (game::SV_Loaded()) - { - const auto* args = "Leave"; - game::UI_RunMenuScript(0, &args); - } - - perform_game_initialization(); - } - - console::info("Starting map: %s\n", mapname.data()); - - auto* gametype = game::Dvar_FindVar("g_gametype"); - if (gametype && gametype->current.string) - { - command::execute(utils::string::va("ui_gametype %s", gametype->current.string), true); - } - command::execute(utils::string::va("ui_mapname %s", mapname.data()), true); - - /*auto* maxclients = game::Dvar_FindVar("sv_maxclients"); - if (maxclients) - { - command::execute(utils::string::va("ui_maxclients %i", maxclients->current.integer), true); - command::execute(utils::string::va("party_maxplayers %i", maxclients->current.integer), true); - }*/ - - const auto* args = "StartServer"; - game::UI_RunMenuScript(0, &args); - } - } - - int server_client_count() - { - return party::sv_maxclients; - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_sp()) - { - return; - } - - // hook disconnect command function - utils::hook::jump(0x1402521C7, disconnect_stub); - - // detour CL_Disconnect to clear motd - cldisconnect_hook.create(0x140252060, cl_disconnect_stub); - - if (game::environment::is_mp()) - { - // show custom drop reason - utils::hook::nop(0x140251EFB, 13); - utils::hook::jump(0x140251EFB, drop_reason_stub, true); - } - - // enable custom kick reason in GScr_KickPlayer - utils::hook::set(0x140376A1D, 0xEB); - - command::add("map", [](const command::params& argument) - { - if (argument.size() != 2) - { - return; - } - - start_map(argument[1]); - }); - - command::add("map_restart", []() - { - if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) - { - return; - } - *reinterpret_cast(0x14A3A91D0) = 1; // sv_map_restart - *reinterpret_cast(0x14A3A91D4) = 1; // sv_loadScripts - *reinterpret_cast(0x14A3A91D8) = 0; // sv_migrate - - utils::hook::invoke(0x14047E7F0); // SV_CheckLoadGame - }); - - command::add("fast_restart", []() - { - if (game::SV_Loaded() && !game::VirtualLobby_Loaded()) - { - game::SV_FastRestart(0); - } - }); - - command::add("reconnect", [](const command::params& argument) - { - if (!connect_state.hostDefined) - { - console::info("Cannot connect to server.\n"); - return; - } - - if (game::CL_IsCgameInitialized()) - { - command::execute("disconnect"); - command::execute("reconnect"); - } - else - { - connect(connect_state.host); - } - }); - - command::add("connect", [](const command::params& argument) - { - if (argument.size() != 2) - { - return; - } - - game::netadr_s target{}; - if (game::NET_StringToAdr(argument[1], &target)) - { - connect(target); - } - }); - - command::add("kickClient", [](const command::params& params) - { - if (params.size() < 2) - { - console::info("usage: kickClient , (optional)\n"); - return; - } - - if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) - { - return; - } - - std::string reason; - if (params.size() > 2) - { - reason = params.join(2); - } - if (reason.empty()) - { - reason = "EXE_PLAYERKICKED"; - } - - const auto client_num = atoi(params.get(1)); - if (client_num < 0 || client_num >= *game::mp::svs_numclients) - { - return; - } - - scheduler::once([client_num, reason]() - { - game::SV_KickClientNum(client_num, reason.data()); - }, scheduler::pipeline::server); - }); - - command::add("kick", [](const command::params& params) - { - if (params.size() < 2) - { - console::info("usage: kick , (optional)\n"); - return; - } - - if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) - { - return; - } - - std::string reason; - if (params.size() > 2) - { - reason = params.join(2); - } - if (reason.empty()) - { - reason = "EXE_PLAYERKICKED"; - } - - const std::string name = params.get(1); - if (name == "all"s) - { - for (auto i = 0; i < *game::mp::svs_numclients; ++i) - { - scheduler::once([i, reason]() - { - game::SV_KickClientNum(i, reason.data()); - }, scheduler::pipeline::server); - } - return; - } - - const auto client_num = get_client_num_by_name(name); - if (client_num < 0 || client_num >= *game::mp::svs_numclients) - { - return; - } - - scheduler::once([client_num, reason]() - { - game::SV_KickClientNum(client_num, reason.data()); - }, scheduler::pipeline::server); - }); - - scheduler::once([]() - { - const auto hash = game::generateHashValue("sv_sayName"); - game::Dvar_RegisterString(hash, "sv_sayName", "console", game::DvarFlags::DVAR_FLAG_NONE); - }, scheduler::pipeline::main); - - command::add("tell", [](const command::params& params) - { - if (params.size() < 3) - { - return; - } - - const auto client_num = atoi(params.get(1)); - const auto message = params.join(2); - const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string; - - game::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, - utils::string::va("%c \"%s: %s\"", 84, name, message.data())); - printf("%s -> %i: %s\n", name, client_num, message.data()); - }); - - command::add("tellraw", [](const command::params& params) - { - if (params.size() < 3) - { - return; - } - - const auto client_num = atoi(params.get(1)); - const auto message = params.join(2); - - game::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, - utils::string::va("%c \"%s\"", 84, message.data())); - printf("%i: %s\n", client_num, message.data()); - }); - - command::add("say", [](const command::params& params) - { - if (params.size() < 2) - { - return; - } - - const auto message = params.join(1); - const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string; - - game::SV_GameSendServerCommand( - -1, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s: %s\"", 84, name, message.data())); - printf("%s: %s\n", name, message.data()); - }); - - command::add("sayraw", [](const command::params& params) - { - if (params.size() < 2) - { - return; - } - - const auto message = params.join(1); - - game::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, - utils::string::va("%c \"%s\"", 84, message.data())); - printf("%s\n", message.data()); - }); - - utils::hook::call(0x1404C6E8D, didyouknow_stub); // allow custom didyouknow based on sv_motd - - network::on("getInfo", [](const game::netadr_s& target, const std::string_view& data) - { - utils::info_string info{}; - info.set("challenge", std::string{data}); - info.set("gamename", "H1"); - info.set("hostname", get_dvar_string("sv_hostname")); - info.set("gametype", get_dvar_string("g_gametype")); - info.set("sv_motd", get_dvar_string("sv_motd")); - info.set("xuid", utils::string::va("%llX", steam::SteamUser()->GetSteamID().bits)); - info.set("mapname", get_dvar_string("mapname")); - info.set("isPrivate", get_dvar_string("g_password").empty() ? "0" : "1"); - info.set("clients", utils::string::va("%i", get_client_count())); - info.set("bots", utils::string::va("%i", get_bot_count())); - info.set("sv_maxclients", utils::string::va("%i", *game::mp::svs_numclients)); - info.set("protocol", utils::string::va("%i", PROTOCOL)); - info.set("playmode", utils::string::va("%i", game::Com_GetCurrentCoDPlayMode())); - info.set("sv_running", utils::string::va("%i", get_dvar_bool("sv_running") && !game::VirtualLobby_Loaded())); - info.set("dedicated", utils::string::va("%i", get_dvar_bool("dedicated"))); - - network::send(target, "infoResponse", info.build(), '\n'); - }); - - network::on("infoResponse", [](const game::netadr_s& target, const std::string_view& data) - { - const utils::info_string info{data}; - server_list::handle_info_response(target, info); - - if (connect_state.host != target) - { - return; - } - - if (info.get("challenge") != connect_state.challenge) - { - const auto str = "Invalid challenge."; - printf("%s\n", str); - menu_error(str); - return; - } - - const auto gamename = info.get("gamename"); - if (gamename != "H1"s) - { - const auto str = "Invalid gamename."; - printf("%s\n", str); - menu_error(str); - return; - } - - const auto playmode = info.get("playmode"); - if (game::CodPlayMode(std::atoi(playmode.data())) != game::Com_GetCurrentCoDPlayMode()) - { - const auto str = "Invalid playmode."; - printf("%s\n", str); - menu_error(str); - return; - } - - const auto sv_running = info.get("sv_running"); - if (!std::atoi(sv_running.data())) - { - const auto str = "Server not running."; - printf("%s\n", str); - menu_error(str); - return; - } - - const auto mapname = info.get("mapname"); - if (mapname.empty()) - { - const auto str = "Invalid map."; - printf("%s\n", str); - menu_error(str); - return; - } - - const auto gametype = info.get("gametype"); - if (gametype.empty()) - { - const auto str = "Invalid gametype."; - printf("%s\n", str); - menu_error(str); - return; - } - - party::sv_motd = info.get("sv_motd"); - party::sv_maxclients = std::stoi(info.get("sv_maxclients")); - - connect_to_party(target, mapname, gametype); - }); - } - }; -} - -REGISTER_COMPONENT(party::component) \ No newline at end of file diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp deleted file mode 100644 index cd90ae9f..00000000 --- a/src/client/component/party.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include "game/game.hpp" - -namespace party -{ - void reset_connect_state(); - - void connect(const game::netadr_s& target); - void start_map(const std::string& mapname); - - int server_client_count(); - - int get_client_num_by_name(const std::string& name); - - int get_client_count(); - int get_bot_count(); -} \ No newline at end of file diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp deleted file mode 100644 index e9aaf21a..00000000 --- a/src/client/component/patches.cpp +++ /dev/null @@ -1,293 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "dvars.hpp" -#include "version.h" -#include "command.hpp" -#include "console.hpp" -#include "network.hpp" -#include "scheduler.hpp" -#include "filesystem.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include -#include -#include - -namespace patches -{ - namespace - { - const char* live_get_local_client_name() - { - return game::Dvar_FindVar("name")->current.string; - } - - utils::hook::detour sv_kick_client_num_hook; - - void sv_kick_client_num(const int client_num, const char* reason) - { - // Don't kick bot to equalize team balance. - if (reason == "EXE_PLAYERKICKED_BOT_BALANCE"s) - { - return; - } - return sv_kick_client_num_hook.invoke(client_num, reason); - } - - std::string get_login_username() - { - char username[UNLEN + 1]; - DWORD username_len = UNLEN + 1; - if (!GetUserNameA(username, &username_len)) - { - return "Unknown Soldier"; - } - - return std::string{ username, username_len - 1 }; - } - - utils::hook::detour com_register_dvars_hook; - - void com_register_dvars_stub() - { - if (game::environment::is_mp()) - { - // Make name save - dvars::register_string("name", get_login_username().data(), game::DVAR_FLAG_SAVED, true); - - // Disable data validation error popup - dvars::register_int("data_validation_allow_drop", 0, 0, 0, game::DVAR_FLAG_NONE, true); - } - - return com_register_dvars_hook.invoke(); - } - - int is_item_unlocked() - { - return 0; // 0 == yes - } - - void set_client_dvar_from_server_stub(void* a1, void* a2, const char* dvar, const char* value) - { - if (dvar == "cg_fov"s) - { - return; - } - - // CG_SetClientDvarFromServer - utils::hook::invoke(0x140236120, a1, a2, dvar, value); - } - - const char* db_read_raw_file_stub(const char* filename, char* buf, const int size) - { - std::string file_name = filename; - if (file_name.find(".cfg") == std::string::npos) - { - file_name.append(".cfg"); - } - - const auto file = filesystem::file(file_name); - if (file.exists()) - { - snprintf(buf, size, "%s\n", file.get_buffer().data()); - return buf; - } - - // DB_ReadRawFile - return utils::hook::invoke(SELECT_VALUE(0x1401CD4F0, 0x1402BEF10), filename, buf, size); - } - - void bsp_sys_error_stub(const char* error, const char* arg1) - { - if (game::environment::is_dedi()) - { - game::Sys_Error(error, arg1); - } - else - { - scheduler::once([]() - { - command::execute("reconnect"); - }, scheduler::pipeline::main, 1s); - game::Com_Error(game::ERR_DROP, error, arg1); - } - } - - utils::hook::detour cmd_lui_notify_server_hook; - void cmd_lui_notify_server_stub(game::mp::gentity_s* ent) - { - command::params_sv params{}; - const auto menu_id = atoi(params.get(1)); - const auto client = &game::mp::svs_clients[ent->s.entityNum]; - - // 22 => "end_game" - if (menu_id == 22 && client->header.remoteAddress.type != game::NA_LOOPBACK) - { - return; - } - - cmd_lui_notify_server_hook.invoke(ent); - } - - void sv_execute_client_message_stub(game::mp::client_t* client, game::msg_t* msg) - { - if (client->reliableAcknowledge < 0) - { - client->reliableAcknowledge = client->reliableSequence; - console::info("Negative reliableAcknowledge from %s - cl->reliableSequence is %i, reliableAcknowledge is %i\n", - client->name, client->reliableSequence, client->reliableAcknowledge); - network::send(client->header.remoteAddress, "error", "EXE_LOSTRELIABLECOMMANDS", '\n'); - return; - } - - utils::hook::invoke(0x140481A00, client, msg); - } - - void aim_assist_add_to_target_list(void* a1, void* a2) - { - if (!dvars::aimassist_enabled->current.enabled) - return; - - game::AimAssist_AddToTargetList(a1, a2); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - // Register dvars - com_register_dvars_hook.create(SELECT_VALUE(0x140351B80, 0x1400D9320), &com_register_dvars_stub); // H1(1.4) - - // Unlock fps in main menu - utils::hook::set(SELECT_VALUE(0x14018D47B, 0x14025B86B), 0xEB); // H1(1.4) - - if (!game::environment::is_dedi()) - { - // Fix mouse lag - utils::hook::nop(SELECT_VALUE(0x1403E3C05, 0x1404DB1AF), 6); - scheduler::loop([]() - { - SetThreadExecutionState(ES_DISPLAY_REQUIRED); - }, scheduler::pipeline::main); - } - - // Make cg_fov and cg_fovscale saved dvars - dvars::override::register_float("cg_fov", 65.f, 40.f, 200.f, game::DvarFlags::DVAR_FLAG_SAVED); - dvars::override::register_float("cg_fovScale", 1.f, 0.1f, 2.f, game::DvarFlags::DVAR_FLAG_SAVED); - - // Allow kbam input when gamepad is enabled - utils::hook::nop(SELECT_VALUE(0x14018797E, 0x14024EF60), 2); - utils::hook::nop(SELECT_VALUE(0x1401856DC, 0x14024C6B0), 6); - - // Allow executing custom cfg files with the "exec" command - utils::hook::call(SELECT_VALUE(0x140343855, 0x140403E28), db_read_raw_file_stub); - - if (!game::environment::is_sp()) - { - patch_mp(); - } - } - - static void patch_mp() - { - // Use name dvar - utils::hook::jump(0x14050FF90, &live_get_local_client_name); // H1(1.4) - - // Patch SV_KickClientNum - sv_kick_client_num_hook.create(0x14047ED00, &sv_kick_client_num); // H1(1.4) - - // block changing name in-game - utils::hook::set(0x14047FC90, 0xC3); // H1(1.4) - - // patch "Couldn't find the bsp for this map." error to not be fatal in mp - utils::hook::call(0x1402BA26B, bsp_sys_error_stub); // H1(1.4) - - // client side aim assist dvar - dvars::aimassist_enabled = dvars::register_bool("aimassist_enabled", true, - game::DvarFlags::DVAR_FLAG_SAVED, - true); - utils::hook::call(0x14009EE9E, aim_assist_add_to_target_list); - - // unlock all items - utils::hook::jump(0x140413E60, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable_LocalClient H1(1.4) - utils::hook::jump(0x140413860, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable H1(1.4) - utils::hook::jump(0x140412B70, is_item_unlocked); // idk ( unlocks loot etc ) H1(1.4) - - // isProfanity - utils::hook::set(0x1402877D0, 0xC3C033); // MAY BE WRONG H1(1.4) - - // disable emblems - dvars::override::register_int("emblems_active", 0, 0, 0, game::DVAR_FLAG_NONE); - utils::hook::set(0x140479590, 0xC3); // don't register commands - - // disable elite_clan - dvars::override::register_int("elite_clan_active", 0, 0, 0, game::DVAR_FLAG_NONE); - utils::hook::set(0x140585680, 0xC3); // don't register commands H1(1.4) - - // disable codPointStore - dvars::override::register_int("codPointStore_enabled", 0, 0, 0, game::DVAR_FLAG_NONE); - - // don't register every replicated dvar as a network dvar - utils::hook::nop(0x14039E58E, 5); // dvar_foreach H1(1.4) - - // patch "Server is different version" to show the server client version - utils::hook::inject(0x140480952, VERSION); // H1(1.4) - - // prevent servers overriding our fov - utils::hook::call(0x14023279E, set_client_dvar_from_server_stub); - utils::hook::nop(0x1400DAF69, 5); - utils::hook::nop(0x140190C16, 5); - utils::hook::set(0x14021D22A, 0xEB); - - // unlock safeArea_* - utils::hook::jump(0x1402624F5, 0x140262503); // H1(1.4) - utils::hook::jump(0x14026251C, 0x140262547); // H1(1.4) - dvars::override::register_int("safeArea_adjusted_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); - dvars::override::register_int("safeArea_adjusted_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); - dvars::override::register_int("safeArea_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); - dvars::override::register_int("safeArea_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); - - // move chat position on the screen above menu splashes - dvars::override::register_vec2("cg_hudChatPosition", 5, 170, 0, 640, game::DVAR_FLAG_SAVED); - - // allow servers to check for new packages more often - dvars::override::register_int("sv_network_fps", 1000, 20, 1000, game::DVAR_FLAG_SAVED); - - // Massively increate timeouts - dvars::override::register_int("cl_timeout", 90, 90, 1800, game::DVAR_FLAG_NONE); // Seems unused - dvars::override::register_int("sv_timeout", 90, 90, 1800, game::DVAR_FLAG_NONE); // 30 - 0 - 1800 - dvars::override::register_int("cl_connectTimeout", 120, 120, 1800, game::DVAR_FLAG_NONE); // Seems unused - dvars::override::register_int("sv_connectTimeout", 120, 120, 1800, game::DVAR_FLAG_NONE); // 60 - 0 - 1800 - - dvars::register_int("scr_game_spectatetype", 1, 0, 99, game::DVAR_FLAG_REPLICATED); - - dvars::override::register_int("com_maxfps", 0, 10, 1000, game::DVAR_FLAG_SAVED); - - // Prevent clients from ending the game as non host by sending 'end_game' lui notification - // cmd_lui_notify_server_hook.create(0x140335A70, cmd_lui_notify_server_stub); // H1(1.4) - - // Prevent clients from sending invalid reliableAcknowledge - // utils::hook::call(0x1404899C6, sv_execute_client_message_stub); // H1(1.4) - - // "fix" for rare 'Out of memory error' error - if (utils::flags::has_flag("memoryfix")) - { - utils::hook::jump(0x140578BE0, malloc); - utils::hook::jump(0x140578B00, _aligned_malloc); - utils::hook::jump(0x140578C40, free); - utils::hook::jump(0x140578D30, realloc); - utils::hook::jump(0x140578B60, _aligned_realloc); - } - - // Change default hostname and make it replicated - dvars::override::register_string("sv_hostname", "^2H1-Mod^7 Default Server", game::DVAR_FLAG_REPLICATED); - } - }; -} - -REGISTER_COMPONENT(patches::component) diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp deleted file mode 100644 index b315be76..00000000 --- a/src/client/component/renderer.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include - -namespace renderer -{ - namespace - { - utils::hook::detour r_init_draw_method_hook; - utils::hook::detour r_update_front_end_dvar_options_hook; - - int get_fullbright_technique() - { - return game::TECHNIQUE_UNLIT; - } - - void gfxdrawmethod() - { - game::gfxDrawMethod->drawScene = game::GFX_DRAW_SCENE_STANDARD; - - game::gfxDrawMethod->baseTechType = dvars::r_fullbright->current.enabled ? get_fullbright_technique() : game::TECHNIQUE_LIT; - game::gfxDrawMethod->emissiveTechType = dvars::r_fullbright->current.enabled ? get_fullbright_technique() : game::TECHNIQUE_EMISSIVE; - game::gfxDrawMethod->forceTechType = dvars::r_fullbright->current.enabled ? get_fullbright_technique() : 242; - } - - void r_init_draw_method_stub() - { - gfxdrawmethod(); - } - - bool r_update_front_end_dvar_options_stub() - { - if (dvars::r_fullbright->modified) - { - //game::Dvar_ClearModified(dvars::r_fullbright); - game::R_SyncRenderThread(); - - gfxdrawmethod(); - } - - return r_update_front_end_dvar_options_hook.invoke(); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_dedi() || !game::environment::is_mp()) - { - return; - } - - dvars::r_fullbright = dvars::register_int("r_fullbright", 0, 0, 3, game::DVAR_FLAG_SAVED); - - r_init_draw_method_hook.create(SELECT_VALUE(0x1404BD140, 0x1405C46E0), &r_init_draw_method_stub); - r_update_front_end_dvar_options_hook.create(SELECT_VALUE(0x1404F8870, 0x1405FF9E0), &r_update_front_end_dvar_options_stub); - - // use "saved" flags for "r_normalMap" - utils::hook::set(SELECT_VALUE(0x1404CF5CA, 0x1405D460E), game::DVAR_FLAG_SAVED); - - // use "saved" flags for "r_specularMap" - utils::hook::set(SELECT_VALUE(0x1404CF5F5, 0x1405D4639), game::DVAR_FLAG_SAVED); - - // use "saved" flags for "r_specOccMap" - utils::hook::set(SELECT_VALUE(0x1404CF620, 0x1405D4664), game::DVAR_FLAG_SAVED); - } - }; -} - -#ifdef DEBUG -REGISTER_COMPONENT(renderer::component) -#endif \ No newline at end of file diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index ac837128..9a8911eb 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -180,9 +180,9 @@ namespace scheduler void post_unpack() override { - r_end_frame_hook.create(SELECT_VALUE(0, 0x6A6300_b), scheduler::r_end_frame_stub); // H1-STEAM(1.15) - g_run_frame_hook.create(SELECT_VALUE(0, 0x417940_b), scheduler::server_frame_stub); // H1(1.15) - //main_frame_hook.create(SELECT_VALUE(0x1401CE8D0, 0x1400D8310), scheduler::main_frame_stub); can't find + r_end_frame_hook.create(SELECT_VALUE(0, 0x6A6300_b), scheduler::r_end_frame_stub); + g_run_frame_hook.create(SELECT_VALUE(0, 0x417940_b), scheduler::server_frame_stub); + main_frame_hook.create(SELECT_VALUE(0, 0x1400D8310), scheduler::main_frame_stub); // I REPEAT, ARXAN IS PAIN } void pre_destroy() override @@ -196,4 +196,4 @@ namespace scheduler }; } -REGISTER_COMPONENT(scheduler::component) +REGISTER_COMPONENT(scheduler::component) \ No newline at end of file diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp deleted file mode 100644 index e3116122..00000000 --- a/src/client/component/scripting.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include - -#include "game/scripting/entity.hpp" -#include "game/scripting/functions.hpp" -#include "game/scripting/event.hpp" -#include "game/scripting/lua/engine.hpp" -#include "game/scripting/execution.hpp" - -#include "scheduler.hpp" -#include "scripting.hpp" - -namespace scripting -{ - std::unordered_map> fields_table; - std::unordered_map> script_function_table; - - namespace - { - utils::hook::detour vm_notify_hook; - utils::hook::detour scr_load_level_hook; - utils::hook::detour g_shutdown_game_hook; - - utils::hook::detour scr_add_class_field_hook; - - utils::hook::detour scr_set_thread_position_hook; - utils::hook::detour process_script_hook; - - std::string current_file; - - void vm_notify_stub(const unsigned int notify_list_owner_id, const game::scr_string_t string_value, - game::VariableValue* top) - { - if (!game::VirtualLobby_Loaded()) - { - const auto* string = game::SL_ConvertToString(string_value); - if (string) - { - event e; - e.name = string; - e.entity = notify_list_owner_id; - - for (auto* value = top; value->type != game::SCRIPT_END; --value) - { - e.arguments.emplace_back(*value); - } - - if (e.name == "entitydeleted") - { - scripting::clear_entity_fields(e.entity); - } - - lua::engine::notify(e); - } - } - - vm_notify_hook.invoke(notify_list_owner_id, string_value, top); - } - - void scr_load_level_stub() - { - scr_load_level_hook.invoke(); - if (!game::VirtualLobby_Loaded()) - { - lua::engine::start(); - } - } - - void g_shutdown_game_stub(const int free_scripts) - { - lua::engine::stop(); - return g_shutdown_game_hook.invoke(free_scripts); - } - - void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t _name, unsigned int canonicalString, unsigned int offset) - { - const auto name = game::SL_ConvertToString(_name); - - if (fields_table[classnum].find(name) == fields_table[classnum].end()) - { - fields_table[classnum][name] = offset; - } - - scr_add_class_field_hook.invoke(classnum, _name, canonicalString, offset); - } - - void process_script_stub(const char* filename) - { - const auto file_id = atoi(filename); - if (file_id) - { - current_file = scripting::find_token(file_id); - } - else - { - current_file = filename; - } - - process_script_hook.invoke(filename); - } - - void scr_set_thread_position_stub(unsigned int threadName, const char* codePos) - { - const auto function_name = scripting::find_token(threadName); - script_function_table[current_file][function_name] = codePos; - scr_set_thread_position_hook.invoke(threadName, codePos); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_sp()) - { - return; - } - - vm_notify_hook.create(SELECT_VALUE(0x140379A00, 0x1404479F0), vm_notify_stub); - - scr_add_class_field_hook.create(SELECT_VALUE(0x140370370, 0x14043E2C0), scr_add_class_field_stub); - - scr_set_thread_position_hook.create(SELECT_VALUE(0x14036A180, 0x140437D10), scr_set_thread_position_stub); - process_script_hook.create(SELECT_VALUE(0x1403737E0, 0x1404417E0), process_script_stub); - - scr_load_level_hook.create(SELECT_VALUE(0x1402A5BE0, 0x1403727C0), scr_load_level_stub); - g_shutdown_game_hook.create(SELECT_VALUE(0x140277D40, 0x140345A60), g_shutdown_game_stub); - - scheduler::loop([]() - { - lua::engine::run_frame(); - }, scheduler::pipeline::server); - } - }; -} - -REGISTER_COMPONENT(scripting::component) \ No newline at end of file diff --git a/src/client/component/scripting.hpp b/src/client/component/scripting.hpp deleted file mode 100644 index 865ae858..00000000 --- a/src/client/component/scripting.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -namespace scripting -{ - extern std::unordered_map> fields_table; - extern std::unordered_map> script_function_table; -} \ No newline at end of file diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp deleted file mode 100644 index 1b7e759e..00000000 --- a/src/client/component/server_list.cpp +++ /dev/null @@ -1,443 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "server_list.hpp" -#include "localized_strings.hpp" -#include "network.hpp" -#include "scheduler.hpp" -#include "party.hpp" -#include "game/game.hpp" - -#include -#include -#include - -#include "console.hpp" -#include "command.hpp" - -namespace server_list -{ - namespace - { - const int server_limit = 18; - - struct server_info - { - // gotta add more to this - int clients; - int max_clients; - int bots; - int ping; - std::string host_name; - std::string map_name; - std::string game_type; - game::CodPlayMode play_mode; - char in_game; - game::netadr_s address; - }; - - struct - { - game::netadr_s address{}; - volatile bool requesting = false; - std::unordered_map queued_servers{}; - } master_state; - - std::mutex mutex; - std::vector servers; - - size_t server_list_page = 0; - volatile bool update_server_list = false; - std::chrono::high_resolution_clock::time_point last_scroll{}; - - size_t get_page_count() - { - const auto count = servers.size() / server_limit; - return count + (servers.size() % server_limit > 0); - } - - size_t get_page_base_index() - { - return server_list_page * server_limit; - } - - void refresh_server_list() - { - { - std::lock_guard _(mutex); - servers.clear(); - master_state.queued_servers.clear(); - server_list_page = 0; - } - - party::reset_connect_state(); - - if (get_master_server(master_state.address)) - { - master_state.requesting = true; - - network::send(master_state.address, "getservers", utils::string::va("H1 %i full empty", PROTOCOL)); - } - } - - void join_server(int, int, const int index) - { - std::lock_guard _(mutex); - - const auto i = static_cast(index) + get_page_base_index(); - if (i < servers.size()) - { - static auto last_index = ~0ull; - if (last_index != i) - { - last_index = i; - } - else - { - console::info("Connecting to (%d - %zu): %s\n", index, i, servers[i].host_name.data()); - party::connect(servers[i].address); - } - } - } - - void trigger_refresh() - { - update_server_list = true; - } - - int ui_feeder_count() - { - std::lock_guard _(mutex); - if (update_server_list) - { - update_server_list = false; - return 0; - } - const auto count = static_cast(servers.size()); - const auto index = get_page_base_index(); - const auto diff = count - index; - return diff > server_limit ? server_limit : static_cast(diff); - } - - const char* ui_feeder_item_text(int /*localClientNum*/, void* /*a2*/, void* /*a3*/, const int index, - const int column) - { - std::lock_guard _(mutex); - - const auto i = get_page_base_index() + index; - - if (i >= servers.size()) - { - return ""; - } - - if (column == 0) - { - return servers[i].host_name.empty() ? "" : utils::string::va("%s", servers[i].host_name.data()); - } - - if (column == 1) - { - return servers[i].map_name.empty() ? "Unknown" : utils::string::va("%s", servers[i].map_name.data()); - } - - if (column == 2) - { - return utils::string::va("%d/%d [%d]", servers[i].clients, servers[index].max_clients, - servers[i].bots); - } - - if (column == 3) - { - return servers[i].game_type.empty() ? "" : utils::string::va("%s", servers[i].game_type.data()); - } - - if (column == 4) - { - return servers[i].game_type.empty() ? "" : utils::string::va("%i", servers[i].ping); - } - - return ""; - } - - void sort_serverlist() - { - std::stable_sort(servers.begin(), servers.end(), [](const server_info& a, const server_info& b) - { - if (a.clients == b.clients) - { - return a.ping < b.ping; - } - - return a.clients > b.clients; - }); - } - - void insert_server(server_info&& server) - { - std::lock_guard _(mutex); - servers.emplace_back(std::move(server)); - sort_serverlist(); - trigger_refresh(); - } - - void do_frame_work() - { - auto& queue = master_state.queued_servers; - if (queue.empty()) - { - return; - } - - std::lock_guard _(mutex); - - size_t queried_servers = 0; - const size_t query_limit = 3; - - for (auto i = queue.begin(); i != queue.end();) - { - if (i->second) - { - const auto now = game::Sys_Milliseconds(); - if (now - i->second > 10'000) - { - i = queue.erase(i); - continue; - } - } - else if (queried_servers++ < query_limit) - { - i->second = game::Sys_Milliseconds(); - network::send(i->first, "getInfo", utils::cryptography::random::get_challenge()); - } - - ++i; - } - } - - bool is_server_list_open() - { - return game::Menu_IsMenuOpenAndVisible(0, "menu_systemlink_join"); - } - - bool is_scrolling_disabled() - { - return update_server_list || (std::chrono::high_resolution_clock::now() - last_scroll) < 500ms; - } - - bool scroll_down() - { - if (!is_server_list_open()) - { - return false; - } - - if (!is_scrolling_disabled() && server_list_page + 1 < get_page_count()) - { - last_scroll = std::chrono::high_resolution_clock::now(); - ++server_list_page; - trigger_refresh(); - } - - return true; - } - - bool scroll_up() - { - if (!is_server_list_open()) - { - return false; - } - - if (!is_scrolling_disabled() && server_list_page > 0) - { - last_scroll = std::chrono::high_resolution_clock::now(); - --server_list_page; - trigger_refresh(); - } - - return true; - } - - void resize_host_name(std::string& name) - { - name = utils::string::split(name, '\n').front(); - - game::Font_s* font = game::R_RegisterFont("fonts/default.otf", 18); - auto text_size = game::UI_TextWidth(name.data(), 32, font, 1.0f); - - while (text_size > 450) - { - text_size = game::UI_TextWidth(name.data(), 32, font, 1.0f); - name.pop_back(); - } - } - - utils::hook::detour lui_open_menu_hook; - - void lui_open_menu_stub(int controllerIndex, const char* menu, int a3, int a4, unsigned int a5) - { -#ifdef DEBUG - console::info("[LUI] %s\n", menu); -#endif - - if (!strcmp(menu, "menu_systemlink_join")) - { - refresh_server_list(); - } - - lui_open_menu_hook.invoke(controllerIndex, menu, a3, a4, a5); - } - } - - bool sl_key_event(const int key, const int down) - { - if (down) - { - if (key == game::keyNum_t::K_MWHEELUP) - { - return !scroll_up(); - } - - if (key == game::keyNum_t::K_MWHEELDOWN) - { - return !scroll_down(); - } - } - - return true; - } - - bool get_master_server(game::netadr_s& address) - { - return game::NET_StringToAdr("135.148.53.121:20810", &address); - // return game::NET_StringToAdr("master.xlabs.dev:20810", &address); - } - - void handle_info_response(const game::netadr_s& address, const utils::info_string& info) - { - // Don't show servers that aren't dedicated! - const auto dedicated = std::atoi(info.get("dedicated").data()); - if (!dedicated) - { - return; - } - - // Don't show servers that aren't running! - const auto sv_running = std::atoi(info.get("sv_running").data()); - if (!sv_running) - { - return; - } - - // Only handle servers of the same playmode! - const auto playmode = game::CodPlayMode(std::atoi(info.get("playmode").data())); - if (game::Com_GetCurrentCoDPlayMode() != playmode) - { - return; - } - - int start_time{}; - const auto now = game::Sys_Milliseconds(); - - { - std::lock_guard _(mutex); - const auto entry = master_state.queued_servers.find(address); - - if (entry == master_state.queued_servers.end() || !entry->second) - { - return; - } - - start_time = entry->second; - master_state.queued_servers.erase(entry); - } - - server_info server{}; - server.address = address; - server.host_name = info.get("hostname"); - server.map_name = game::UI_GetMapDisplayName(info.get("mapname").data()); - server.game_type = game::UI_GetGameTypeDisplayName(info.get("gametype").data()); - server.play_mode = playmode; - server.clients = atoi(info.get("clients").data()); - server.max_clients = atoi(info.get("sv_maxclients").data()); - server.bots = atoi(info.get("bots").data()); - server.ping = std::min(now - start_time, 999); - - server.in_game = 1; - - resize_host_name(server.host_name); - - insert_server(std::move(server)); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (!game::environment::is_mp()) return; - - localized_strings::override("PLATFORM_SYSTEM_LINK_TITLE", "SERVER LIST"); - - // hook LUI_OpenMenu to refresh server list for system link menu - lui_open_menu_hook.create(game::LUI_OpenMenu, lui_open_menu_stub); - - // replace UI_RunMenuScript call in LUI_CoD_LuaCall_RefreshServerList to our refresh_servers - utils::hook::call(0x14018A0C9, &refresh_server_list); - utils::hook::call(0x14018A5DE, &join_server); - utils::hook::nop(0x14018A5FD, 5); - - // do feeder stuff - utils::hook::call(0x14018A199, &ui_feeder_count); - utils::hook::call(0x14018A3B1, &ui_feeder_item_text); - - scheduler::loop(do_frame_work, scheduler::pipeline::main); - - network::on("getServersResponse", [](const game::netadr_s& target, const std::string_view& data) - { - { - std::lock_guard _(mutex); - if (!master_state.requesting || master_state.address != target) - { - return; - } - - master_state.requesting = false; - - std::optional start{}; - for (size_t i = 0; i + 6 < data.size(); ++i) - { - if (data[i + 6] == '\\') - { - start.emplace(i); - break; - } - } - - if (!start.has_value()) - { - return; - } - - for (auto i = start.value(); i + 6 < data.size(); i += 7) - { - if (data[i + 6] != '\\') - { - break; - } - - game::netadr_s address{}; - address.type = game::NA_IP; - address.localNetID = game::NS_CLIENT1; - memcpy(&address.ip[0], data.data() + i + 0, 4); - memcpy(&address.port, data.data() + i + 4, 2); - - master_state.queued_servers[address] = 0; - } - } - }); - } - }; -} - -REGISTER_COMPONENT(server_list::component) diff --git a/src/client/component/server_list.hpp b/src/client/component/server_list.hpp deleted file mode 100644 index d9974cfa..00000000 --- a/src/client/component/server_list.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "game/game.hpp" -#include - -namespace server_list -{ - bool get_master_server(game::netadr_s& address); - void handle_info_response(const game::netadr_s& address, const utils::info_string& info); - - bool sl_key_event(int key, int down); -} \ No newline at end of file diff --git a/src/client/component/shaders.cpp b/src/client/component/shaders.cpp deleted file mode 100644 index ec632115..00000000 --- a/src/client/component/shaders.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "scheduler.hpp" -#include "dvars.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include -#include -#include - -namespace shaders -{ - namespace - { - game::dvar_t* disable_shader_caching = nullptr; - - bool shader_should_show_dialog_stub() - { - return !disable_shader_caching->current.enabled; - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (!game::environment::is_mp()) - { - return; - } - - const auto has_flag = utils::flags::has_flag("noshadercaching"); - - disable_shader_caching = dvars::register_bool("disable_shader_caching", has_flag, game::DVAR_FLAG_SAVED, true); - if (has_flag) - { - dvars::override::set_bool("disable_shader_caching", 1); - dvars::override::set_from_string("disable_shader_caching", "1"); - } - - utils::hook::jump(0x14007E710, shader_should_show_dialog_stub); - } - }; -} - -REGISTER_COMPONENT(shaders::component) diff --git a/src/client/component/slowmotion.cpp b/src/client/component/slowmotion.cpp deleted file mode 100644 index 71f66dbf..00000000 --- a/src/client/component/slowmotion.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "game/game.hpp" - -#include -#include - -namespace slowmotion -{ - namespace - { - void scr_cmd_set_slow_motion() - { - if (game::Scr_GetNumParam() < 1) - { - return; - } - - int duration = 1000; - float end = 1.0f; - const float start = game::Scr_GetFloat(0); - - if (game::Scr_GetNumParam() >= 2) - { - end = game::Scr_GetFloat(1u); - } - - if (game::Scr_GetNumParam() >= 3) - { - duration = static_cast(game::Scr_GetFloat(2u) * 1000.0f); - } - - game::SV_SetConfigstring(10, utils::string::va("%i %i %g %g", *game::mp::gameTime, duration, start, end)); - game::Com_SetSlowMotion(start, end, duration); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (!game::environment::is_dedi()) - { - return; - } - - utils::hook::jump(0x140365480, scr_cmd_set_slow_motion); // H1(1.4) - } - }; -} - -REGISTER_COMPONENT(slowmotion::component) diff --git a/src/client/component/splash.cpp b/src/client/component/splash.cpp deleted file mode 100644 index 3dfd6541..00000000 --- a/src/client/component/splash.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "game/game.hpp" -#include "game_module.hpp" - -#include -#include - -namespace splash -{ - class component final : public component_interface - { - public: - void post_start() override - { - const utils::nt::library self; - image_ = LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); - } - - void post_load() override - { - if (game::environment::is_dedi()) - { - return; - } - - this->show(); - } - - void post_unpack() override - { - // Disable native splash screen - //utils::hook::nop(SELECT_VALUE(0x1403E192E, 0x1405123E2), 5); // winmain doesn't even exist in 1.15? lmao - utils::hook::jump(SELECT_VALUE(0, 0x5BE1D0_b), destroy_stub); // H1-STEAM(1.15) - utils::hook::jump(SELECT_VALUE(0, 0x5BE210_b), destroy_stub); // H1-STEAM(1.15) - } - - void pre_destroy() override - { - this->destroy(); - - MSG msg; - while (this->window_ && IsWindow(this->window_)) - { - if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else - { - std::this_thread::sleep_for(1ms); - } - } - - this->window_ = nullptr; - } - - private: - HWND window_{}; - HANDLE image_{}; - - static void destroy_stub() - { - component_loader::get()->destroy(); - } - - void destroy() const - { - if (this->window_ && IsWindow(this->window_)) - { - ShowWindow(this->window_, SW_HIDE); - DestroyWindow(this->window_); - UnregisterClassA("H1 Splash Screen", utils::nt::library{}); - } - } - - void show() - { - WNDCLASSA wnd_class; - - const auto self = game_module::get_host_module(); - - wnd_class.style = CS_DROPSHADOW; - wnd_class.cbClsExtra = 0; - wnd_class.cbWndExtra = 0; - wnd_class.lpszMenuName = nullptr; - wnd_class.lpfnWndProc = DefWindowProcA; - wnd_class.hInstance = self; - wnd_class.hIcon = LoadIconA(self, reinterpret_cast(102)); - wnd_class.hCursor = LoadCursorA(nullptr, IDC_APPSTARTING); - wnd_class.hbrBackground = reinterpret_cast(6); - wnd_class.lpszClassName = "H1 Splash Screen"; - - if (RegisterClassA(&wnd_class)) - { - const auto x_pixels = GetSystemMetrics(SM_CXFULLSCREEN); - const auto y_pixels = GetSystemMetrics(SM_CYFULLSCREEN); - - if (image_) - { - this->window_ = CreateWindowExA(WS_EX_APPWINDOW, "H1 Splash Screen", "H1", - WS_POPUP | WS_SYSMENU, - (x_pixels - 320) / 2, (y_pixels - 100) / 2, 320, 100, nullptr, - nullptr, - self, nullptr); - - if (this->window_) - { - auto* const image_window = CreateWindowExA(0, "Static", nullptr, WS_CHILD | WS_VISIBLE | 0xEu, - 0, 0, - 320, 100, this->window_, nullptr, self, nullptr); - if (image_window) - { - RECT rect; - SendMessageA(image_window, 0x172u, 0, reinterpret_cast(image_)); - GetWindowRect(image_window, &rect); - - const int width = rect.right - rect.left; - rect.left = (x_pixels - width) / 2; - - const int height = rect.bottom - rect.top; - rect.top = (y_pixels - height) / 2; - - rect.right = rect.left + width; - rect.bottom = rect.top + height; - AdjustWindowRect(&rect, WS_CHILD | WS_VISIBLE | 0xEu, 0); - SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, SWP_NOZORDER); - - ShowWindow(this->window_, SW_SHOW); - UpdateWindow(this->window_); - } - } - } - } - } - }; -} - -REGISTER_COMPONENT(splash::component) diff --git a/src/client/component/system_check.cpp b/src/client/component/system_check.cpp index 9c88bd5c..e3631248 100644 --- a/src/client/component/system_check.cpp +++ b/src/client/component/system_check.cpp @@ -51,27 +51,28 @@ namespace system_check { static std::unordered_map mp_zone_hashes = { - {"patch_common_mp.ff", "3F44B0CFB0B8E0FBD9687C2942204AB7F11E66E6E15C73B8B4A5EB5920115A31"}, + {"patch_common_mp.ff", "E45EF5F29D12A5A47F405F89FBBEE479C0A90D02141ABF852D481689514134A1"}, }; static std::unordered_map sp_zone_hashes = { // Steam doesn't necessarily deliver this file :( - {"patch_common.ff", "BB0617DD94AF2F511571E7184BBEDE76E64D97E5D0DAFDB457F00717F035EBF0"}, + {"patch_common.ff", "1D32A9770F90ED022AA76F4859B4AB178E194A703383E61AC2CE83B1E828B18F"}, }; return verify_hashes(mp_zone_hashes) && (game::environment::is_dedi() || verify_hashes(sp_zone_hashes)); } - void verify_binary_version() - { - const auto value = *reinterpret_cast(0x140001337); - if (value != 0xFFB8006D && value != 0xFFB80080) - { - throw std::runtime_error("Unsupported Call of Duty: Modern Warfare Remastered version(1.4)"); - } - } + //void verify_binary_version() + //{ + // if (*(int*)(uint64_t(GetModuleHandle(NULL)) + 0x4CCD3D) != 1251288) + // { + // MessageBoxA(0, "UNSUPPORTED VERSION MWR(1.15)", "H1MP-STEAM", MB_ICONWARNING); + + // return; + // } + //} } bool is_valid() @@ -85,12 +86,12 @@ namespace system_check public: void post_load() override { - verify_binary_version(); + //verify_binary_version(); if (!is_valid()) { MessageBoxA(nullptr, "Your game files are outdated or unsupported.\n" - "Please get the latest officially supported Call of Duty: Modern Warfare Remastered 1.4 files, or you will get random crashes and issues.", + "Please get the latest officially supported Call of Duty: Modern Warfare Remastered 1.15 STEAM files, or you will get random crashes and issues.", "Invalid game files!", MB_ICONINFORMATION); } } diff --git a/src/client/component/thread_names.cpp b/src/client/component/thread_names.cpp deleted file mode 100644 index 84b5fa70..00000000 --- a/src/client/component/thread_names.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "scheduler.hpp" - -#include "game/game.hpp" - -#include - -namespace thread_names -{ - namespace - { - void set_thread_names() - { - static std::unordered_map thread_names = - { - {game::THREAD_CONTEXT_MAIN, "Main"}, - {game::THREAD_CONTEXT_BACKEND, "Backend"}, // Renderer - {game::THREAD_CONTEXT_WORKER0, "Worker0"}, - {game::THREAD_CONTEXT_WORKER1, "Worker1"}, - {game::THREAD_CONTEXT_WORKER2, "Worker2"}, - {game::THREAD_CONTEXT_WORKER3, "Worker3"}, - {game::THREAD_CONTEXT_WORKER4, "Worker4"}, - {game::THREAD_CONTEXT_WORKER5, "Worker5"}, - {game::THREAD_CONTEXT_WORKER6, "Worker6"}, - {game::THREAD_CONTEXT_WORKER7, "Worker7"}, - {game::THREAD_CONTEXT_SERVER, "Server"}, - {game::THREAD_CONTEXT_CINEMATIC, "Cinematic"}, - {game::THREAD_CONTEXT_DATABASE, "Database"}, - {game::THREAD_CONTEXT_STREAM, "Stream"}, - {game::THREAD_CONTEXT_SNDSTREAMPACKETCALLBACK, "Snd stream packet callback"}, - {game::THREAD_CONTEXT_STATS_WRITE, "Stats write"}, - }; - - for (const auto& thread_name : thread_names) - { - const auto id = game::threadIds[thread_name.first]; - if (id) - { - utils::thread::set_name(id, thread_name.second); - } - } - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - set_thread_names(); - scheduler::once(set_thread_names, scheduler::pipeline::main); - scheduler::once(set_thread_names, scheduler::pipeline::renderer); - scheduler::once(set_thread_names, scheduler::pipeline::server); - } - }; -} - -REGISTER_COMPONENT(thread_names::component) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp deleted file mode 100644 index 941dda10..00000000 --- a/src/client/component/ui_scripting.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include "scheduler.hpp" -#include "command.hpp" - -#include "ui_scripting.hpp" - -#include "game/ui_scripting/lua/engine.hpp" -#include "game/ui_scripting/execution.hpp" -#include "game/ui_scripting/lua/error.hpp" - -#include -#include - -namespace ui_scripting -{ - namespace - { - std::unordered_map converted_functions; - - utils::hook::detour hksi_lual_error_hook; - utils::hook::detour hksi_lual_error_hook2; - utils::hook::detour hks_start_hook; - utils::hook::detour hks_shutdown_hook; - utils::hook::detour hks_allocator_hook; - utils::hook::detour hks_frame_hook; - - bool error_hook_enabled = false; - - void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...) - { - char va_buffer[2048] = {0}; - - va_list ap; - va_start(ap, fmt); - vsprintf_s(va_buffer, fmt, ap); - va_end(ap); - - const auto formatted = std::string(va_buffer); - - if (!error_hook_enabled) - { - return hksi_lual_error_hook.invoke(s, formatted.data()); - } - else - { - throw std::runtime_error(formatted); - } - } - - void* hks_start_stub(char a1) - { - const auto _1 = gsl::finally([]() - { - ui_scripting::lua::engine::start(); - }); - - return hks_start_hook.invoke(a1); - } - - void hks_shutdown_stub() - { - ui_scripting::lua::engine::stop(); - hks_shutdown_hook.invoke(); - } - - void* hks_allocator_stub(void* userData, void* oldMemory, unsigned __int64 oldSize, unsigned __int64 newSize) - { - const auto closure = reinterpret_cast(oldMemory); - if (converted_functions.find(closure) != converted_functions.end()) - { - converted_functions.erase(closure); - } - - return hks_allocator_hook.invoke(userData, oldMemory, oldSize, newSize); - } - - void hks_frame_stub() - { - const auto state = *game::hks::lua_state; - if (state) - { - ui_scripting::lua::engine::run_frame(); - } - } - } - - int main_function_handler(game::hks::lua_State* state) - { - const auto value = state->m_apistack.base[-1]; - if (value.t != game::hks::TCFUNCTION) - { - return 0; - } - - const auto closure = reinterpret_cast(value.v.cClosure); - if (converted_functions.find(closure) == converted_functions.end()) - { - return 0; - } - - const auto function = converted_functions[closure]; - const auto count = static_cast(state->m_apistack.top - state->m_apistack.base); - const auto arguments = get_return_values(count); - const auto s = function.lua_state(); - - std::vector converted_args; - - for (const auto& argument : arguments) - { - converted_args.push_back(lua::convert(s, argument)); - } - - const auto results = function(sol::as_args(converted_args)); - lua::handle_error(results); - - for (const auto& result : results) - { - push_value(lua::convert({s, result})); - } - - return results.return_count(); - } - - void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function) - { - converted_functions[closure] = function; - } - - void clear_converted_functions() - { - converted_functions.clear(); - } - - void enable_error_hook() - { - error_hook_enabled = true; - } - - void disable_error_hook() - { - error_hook_enabled = false; - } - - class component final : public component_interface - { - public: - - void post_unpack() override - { - if (game::environment::is_dedi()) - { - return; - } - - hks_start_hook.create(SELECT_VALUE(0x1400E4B40, 0x140176A40), hks_start_stub); - hks_shutdown_hook.create(SELECT_VALUE(0x1400DD3D0, 0x14016CA80), hks_shutdown_stub); - hksi_lual_error_hook.create(SELECT_VALUE(0x1400A5EA0, 0x14012F300), hksi_lual_error_stub); - hks_allocator_hook.create(SELECT_VALUE(0x14009B570, 0x14012BAC0), hks_allocator_stub); - hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), hks_frame_stub); - - if (game::environment::is_mp()) - { - hksi_lual_error_hook2.create(0x1401366B0, hksi_lual_error_stub); - } - - command::add("lui_restart", []() - { - utils::hook::invoke(SELECT_VALUE(0x1400DD3D0, 0x14016CA80)); - utils::hook::invoke(SELECT_VALUE(0x1400E6170, 0x1401780D0)); - }); - } - }; -} - -REGISTER_COMPONENT(ui_scripting::component) \ No newline at end of file diff --git a/src/client/component/ui_scripting.hpp b/src/client/component/ui_scripting.hpp deleted file mode 100644 index 2a48f6ec..00000000 --- a/src/client/component/ui_scripting.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "game/ui_scripting/lua/value_conversion.hpp" - -namespace ui_scripting -{ - int main_function_handler(game::hks::lua_State* state); - void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function); - void clear_converted_functions(); - - void enable_error_hook(); - void disable_error_hook(); -} \ No newline at end of file diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp deleted file mode 100644 index 939dbd1c..00000000 --- a/src/client/component/updater.cpp +++ /dev/null @@ -1,474 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "scheduler.hpp" -#include "dvars.hpp" -#include "updater.hpp" - -#include "version.h" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include -#include -#include -#include -#include -#include - -#define MASTER "https://master.fed0001.xyz/h1-mod/" - -#define FILES_PATH "files.json" -#define FILES_PATH_DEV "files-dev.json" - -#define DATA_PATH "data/" -#define DATA_PATH_DEV "data-dev/" - -#define ERR_UPDATE_CHECK_FAIL "Failed to check for updates" -#define ERR_DOWNLOAD_FAIL "Failed to download file " -#define ERR_WRITE_FAIL "Failed to write file " - -#define BINARY_NAME "h1-mod.exe" - -namespace updater -{ - namespace - { - game::dvar_t* cl_auto_update; - bool has_tried_update = false; - - struct status - { - bool done; - bool success; - }; - - struct file_data - { - std::string name; - std::string data; - }; - - struct update_data_t - { - bool restart_required{}; - bool cancelled{}; - status check{}; - status download{}; - std::string error{}; - std::string current_file{}; - std::vector required_files{}; - }; - - utils::concurrency::container update_data; - - std::string get_branch() - { - return GIT_BRANCH; - } - - std::string select(const std::string& main, const std::string& develop) - { - if (get_branch() == "develop") - { - return develop; - } - - return main; - } - - std::string get_data_path() - { - if (get_branch() == "develop") - { - return DATA_PATH_DEV; - } - - return DATA_PATH; - } - - void set_update_check_status(bool done, bool success, const std::string& error = {}) - { - update_data.access([done, success, error](update_data_t& data_) - { - data_.check.done = done; - data_.check.success = success; - data_.error = error; - }); - } - - void set_update_download_status(bool done, bool success, const std::string& error = {}) - { - update_data.access([done, success, error](update_data_t& data_) - { - data_.download.done = done; - data_.download.success = success; - data_.error = error; - }); - } - - bool check_file(const std::string& name, const std::string& sha) - { - std::string data; - if (!utils::io::read_file(name, &data)) - { - return false; - } - - if (utils::cryptography::sha1::compute(data, true) != sha) - { - return false; - } - - return true; - } - - std::string load_binary_name() - { - // utils::nt::library self; - // return self.get_name(); - // returns the game's name and not the client's - - return BINARY_NAME; - } - - std::string get_binary_name() - { - static const auto name = load_binary_name(); - return name; - } - - std::string get_time_str() - { - return utils::string::va("%i", uint32_t(time(nullptr))); - } - - std::optional download_file(const std::string& name) - { - return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name + "?" + get_time_str()); - } - - bool is_update_cancelled() - { - return update_data.access([](update_data_t& data_) - { - return data_.cancelled; - }); - } - - bool write_file(const std::string& name, const std::string& data) - { - if (get_binary_name() == name && - utils::io::file_exists(name) && - !utils::io::move_file(name, name + ".old")) - { - return false; - } - -#ifdef DEBUG - return utils::io::write_file("update_test/" + name, data); -#else - return utils::io::write_file(name, data); -#endif - } - - void delete_old_file() - { - utils::io::remove_file(get_binary_name() + ".old"); - } - - void reset_data() - { - update_data.access([](update_data_t& data_) - { - data_ = {}; - }); - } - - std::string get_mode_flag() - { - if (game::environment::is_mp()) - { - return "-multiplayer"; - } - - if (game::environment::is_sp()) - { - return "-singleplayer"; - } - - return {}; - } - } - - // workaround - void relaunch() - { - if (!utils::io::file_exists(BINARY_NAME)) - { - utils::nt::terminate(0); - return; - } - - STARTUPINFOA startup_info; - PROCESS_INFORMATION process_info; - - ZeroMemory(&startup_info, sizeof(startup_info)); - ZeroMemory(&process_info, sizeof(process_info)); - startup_info.cb = sizeof(startup_info); - - char current_dir[MAX_PATH]; - GetCurrentDirectoryA(sizeof(current_dir), current_dir); - - char buf[1024] = {0}; - const auto command_line = utils::string::va("%s %s", GetCommandLineA(), get_mode_flag().data()); - strcpy_s(buf, 1024, command_line); - - CreateProcess(BINARY_NAME, buf, nullptr, nullptr, false, NULL, nullptr, current_dir, - &startup_info, &process_info); - - if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread); - if (process_info.hProcess && process_info.hProcess != INVALID_HANDLE_VALUE) CloseHandle(process_info.hProcess); - - utils::nt::terminate(0); - } - - void set_has_tried_update(bool tried) - { - has_tried_update = tried; - } - - bool get_has_tried_update() - { - return has_tried_update; - } - - bool auto_updates_enabled() - { - return cl_auto_update->current.enabled; - } - - bool is_update_check_done() - { - return update_data.access([](update_data_t& data_) - { - return data_.check.done; - }); - } - - bool is_update_download_done() - { - return update_data.access([](update_data_t& data_) - { - return data_.download.done; - }); - } - - bool get_update_check_status() - { - return update_data.access([](update_data_t& data_) - { - return data_.check.success; - }); - } - - bool get_update_download_status() - { - return update_data.access([](update_data_t& data_) - { - return data_.download.success; - }); - } - - bool is_update_available() - { - return update_data.access([](update_data_t& data_) - { - return data_.required_files.size() > 0; - }); - } - - bool is_restart_required() - { - return update_data.access([](update_data_t& data_) - { - return data_.restart_required; - }); - } - - std::string get_last_error() - { - return update_data.access([](update_data_t& data_) - { - return data_.error; - }); - } - - std::string get_current_file() - { - return update_data.access([](update_data_t& data_) - { - return data_.current_file; - }); - } - - void cancel_update() - { -#ifdef DEBUG - printf("[Updater] Cancelling update\n"); -#endif - - return update_data.access([](update_data_t& data_) - { - data_.cancelled = true; - }); - } - - void start_update_check() - { - cancel_update(); - reset_data(); - -#ifdef DEBUG - printf("[Updater] starting update check\n"); -#endif - - scheduler::once([]() - { - const auto files_data = utils::http::get_data(MASTER + select(FILES_PATH, FILES_PATH_DEV) + "?" + get_time_str()); - - if (is_update_cancelled()) - { - reset_data(); - return; - } - - if (!files_data.has_value()) - { - set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); - return; - } - - rapidjson::Document j; - j.Parse(files_data.value().data()); - - if (!j.IsArray()) - { - set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); - return; - } - - std::vector required_files; - - const auto files = j.GetArray(); - for (const auto& file : files) - { - if (!file.IsArray() || file.Size() != 3 || !file[0].IsString() || !file[2].IsString()) - { - continue; - } - - const auto name = file[0].GetString(); - const auto sha = file[2].GetString(); - - if (!check_file(name, sha)) - { - if (get_binary_name() == name) - { - update_data.access([](update_data_t& data_) - { - data_.restart_required = true; - }); - } - -#ifdef DEBUG - printf("[Updater] need file %s\n", name); -#endif - - required_files.push_back(name); - } - } - - update_data.access([&required_files](update_data_t& data_) - { - data_.check.done = true; - data_.check.success = true; - data_.required_files = required_files; - }); - }, scheduler::pipeline::async); - } - - void start_update_download() - { -#ifdef DEBUG - printf("[Updater] starting update download\n"); -#endif - - if (!is_update_check_done() || !get_update_check_status() || is_update_cancelled()) - { - return; - } - - scheduler::once([]() - { - const auto required_files = update_data.access>([](update_data_t& data_) - { - return data_.required_files; - }); - - std::vector downloads; - - for (const auto& file : required_files) - { - update_data.access([file](update_data_t& data_) - { - data_.current_file = file; - }); - -#ifdef DEBUG - printf("[Updater] downloading file %s\n", file.data()); -#endif - - const auto data = download_file(file); - - if (is_update_cancelled()) - { - reset_data(); - return; - } - - if (!data.has_value()) - { - set_update_download_status(true, false, ERR_DOWNLOAD_FAIL + file); - return; - } - - downloads.push_back({file, data.value()}); - } - - for (const auto& download : downloads) - { - if (!write_file(download.name, download.data)) - { - set_update_download_status(true, false, ERR_WRITE_FAIL + download.name); - return; - } - } - - set_update_download_status(true, true); - }, scheduler::pipeline::async); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - delete_old_file(); - cl_auto_update = dvars::register_bool("cg_auto_update", true, game::DVAR_FLAG_SAVED, true); - } - }; -} - -REGISTER_COMPONENT(updater::component) diff --git a/src/client/component/updater.hpp b/src/client/component/updater.hpp deleted file mode 100644 index 9a3dd45e..00000000 --- a/src/client/component/updater.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -namespace updater -{ - void relaunch(); - - void set_has_tried_update(bool tried); - bool get_has_tried_update(); - bool auto_updates_enabled(); - - bool is_update_available(); - bool is_update_check_done(); - bool get_update_check_status(); - - bool is_update_download_done(); - bool get_update_download_status(); - - bool is_restart_required(); - - std::string get_last_error(); - std::string get_current_file(); - - void start_update_check(); - void start_update_download(); - void cancel_update(); -} \ No newline at end of file diff --git a/src/client/component/videos.cpp b/src/client/component/videos.cpp deleted file mode 100644 index a602cc8a..00000000 --- a/src/client/component/videos.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" - -#include - -namespace videos -{ - namespace - { - utils::hook::detour playvid_hook; - std::unordered_map video_replaces; - - void playvid(const char* name, const int a2, const int a3) - { - const auto vid = video_replaces.find(name); - if (vid != video_replaces.end()) - { - char path[256]; - game::Sys_BuildAbsPath(path, sizeof(path), game::SF_VIDEO, vid->second.data(), ".bik"); - - if (game::Sys_FileExists(path)) - { - name = vid->second.data(); - } - } - - return playvid_hook.invoke(name, a2, a3); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - playvid_hook.create(SELECT_VALUE(0x1404A9D00, 0x1405B0AF0), &playvid); // H1(1.4) - - if (game::environment::is_mp()) - { - video_replaces["menus_bg_comp2"] = "menus_bg_h1mod"; - video_replaces["mp_menus_bg_options"] = "menus_bg_h1mod_blur"; - } - else if (game::environment::is_sp()) - { - video_replaces["sp_menus_bg_main_menu"] = "menus_bg_h1mod_sp"; - video_replaces["sp_menus_bg_campaign"] = "menus_bg_h1mod_sp"; - video_replaces["sp_menus_bg_options"] = "menus_bg_h1mod_sp"; - } - } - }; -} - -REGISTER_COMPONENT(videos::component) diff --git a/src/client/component/virtuallobby.cpp b/src/client/component/virtuallobby.cpp deleted file mode 100644 index eb6295f7..00000000 --- a/src/client/component/virtuallobby.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include - -namespace virtuallobby -{ - namespace - { - game::dvar_t* virtualLobby_fovscale; - - const auto get_fovscale_stub = utils::hook::assemble([](utils::hook::assembler& a) - { - const auto ret = a.newLabel(); - const auto original = a.newLabel(); - - a.pushad64(); - a.mov(rax, qword_ptr(0x1425F7210)); // virtualLobbyInFiringRange - a.cmp(byte_ptr(rax, 0x10), 1); - a.je(original); - a.call_aligned(game::VirtualLobby_Loaded); - a.cmp(al, 0); - a.je(original); - - // virtuallobby - a.popad64(); - a.mov(rax, ptr(reinterpret_cast(&virtualLobby_fovscale))); - a.jmp(ret); - - // original - a.bind(original); - a.popad64(); - a.mov(rax, qword_ptr(0x1413A8580)); - a.jmp(ret); - - a.bind(ret); - a.mov(rcx, 0x142935000); - a.jmp(0x1400B556A); - }); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (!game::environment::is_mp()) - { - return; - } - - virtualLobby_fovscale = dvars::register_float("virtualLobby_fovScale", 0.7f, 0.0f, 2.0f, game::DVAR_FLAG_SAVED); - - utils::hook::nop(0x1400B555C, 14); - utils::hook::jump(0x1400B555C, get_fovscale_stub, true); - } - }; -} - -REGISTER_COMPONENT(virtuallobby::component) diff --git a/src/client/loader/loader.cpp b/src/client/loader/loader.cpp index 1bc7b41c..4ec12c7c 100644 --- a/src/client/loader/loader.cpp +++ b/src/client/loader/loader.cpp @@ -31,7 +31,7 @@ FARPROC loader::load(const utils::nt::library& library, const std::string& buffe return FARPROC(library.get_ptr() + source.get_relative_entry_point()); } -FARPROC loader::load_library(const std::string& filename) const +FARPROC loader::load_library(const std::string& filename, uint64_t* base_address) const { const auto target = utils::nt::library::load(filename); if (!target) @@ -40,10 +40,7 @@ FARPROC loader::load_library(const std::string& filename) const } const auto base = size_t(target.get_ptr()); - if(base != 0x140000000) - { - throw std::runtime_error{utils::string::va("Binary was mapped at 0x%llX (instead of 0x%llX). Something is severely broken :(", base, 0x140000000)}; - } + *base_address = base; this->load_imports(target, target); this->load_tls(target, target); diff --git a/src/client/loader/loader.hpp b/src/client/loader/loader.hpp index 2c5d86f9..0c0b5a12 100644 --- a/src/client/loader/loader.hpp +++ b/src/client/loader/loader.hpp @@ -5,7 +5,7 @@ class loader final { public: FARPROC load(const utils::nt::library& library, const std::string& buffer) const; - FARPROC load_library(const std::string& filename) const; + FARPROC load_library(const std::string& filename, uint64_t* base_address) const; void set_import_resolver(const std::function& resolver); diff --git a/src/client/resources/ui_scripts/common.lua b/src/client/resources/ui_scripts/common.lua deleted file mode 100644 index 8f68e96d..00000000 --- a/src/client/resources/ui_scripts/common.lua +++ /dev/null @@ -1,164 +0,0 @@ -menucallbacks = {} -originalmenus = {} -stack = {} - -LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event) - local oncancel = stack.oncancel - local popup = LUI.MenuBuilder.BuildRegisteredType("waiting_popup", { - message_text = stack.text, - isLiveWithCancel = true, - cancel_func = function(...) - local args = {...} - oncancel() - LUI.FlowManager.RequestLeaveMenu(args[1]) - end - }) - - local listchildren = popup:getChildById("LUIHorizontalList"):getchildren() - local children = listchildren[2]:getchildren() - popup.text = children[2] - - stack = { - ret = popup - } - - return popup -end - -LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function() - local callback = stack.callback - local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", { - popup_title = stack.title, - message_text = stack.text, - yes_action = function() - callback(true) - end, - no_action = function() - callback(false) - end - }) - - stack = { - ret = popup - } - - return popup -end - -LUI.MenuBuilder.m_types_build["generic_confirmation_popup_"] = function() - local popup = LUI.MenuBuilder.BuildRegisteredType( "generic_confirmation_popup", { - cancel_will_close = false, - popup_title = stack.title, - message_text = stack.text, - button_text = stack.buttontext, - confirmation_action = stack.callback - }) - - stack = { - ret = popup - } - - return stack.ret -end - -LUI.onmenuopen = function(name, callback) - if (not LUI.MenuBuilder.m_types_build[name]) then - return - end - - if (not menucallbacks[name]) then - menucallbacks[name] = {} - end - - table.insert(menucallbacks[name], callback) - - if (not originalmenus[name]) then - originalmenus[name] = LUI.MenuBuilder.m_types_build[name] - LUI.MenuBuilder.m_types_build[name] = function(...) - local args = {...} - local menu = originalmenus[name](table.unpack(args)) - - for k, v in luiglobals.next, menucallbacks[name] do - v(menu, table.unpack(args)) - end - - return menu - end - end -end - -local addoptionstextinfo = LUI.Options.AddOptionTextInfo -LUI.Options.AddOptionTextInfo = function(menu) - local result = addoptionstextinfo(menu) - menu.optionTextInfo = result - return result -end - -LUI.addmenubutton = function(name, data) - LUI.onmenuopen(name, function(menu) - if (not menu.list) then - return - end - - local button = menu:AddButton(data.text, data.callback, nil, true, nil, { - desc_text = data.description - }) - - local buttonlist = menu:getChildById(menu.type .. "_list") - - if (data.id) then - button.id = data.id - end - - if (data.index) then - buttonlist:removeElement(button) - buttonlist:insertElement(button, data.index) - end - - local hintbox = menu.optionTextInfo - menu:removeElement(hintbox) - - LUI.Options.InitScrollingList(menu.list, nil) - menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) - end) -end - -LUI.openmenu = function(menu, args) - stack = args - LUI.FlowManager.RequestAddMenu(nil, menu) - return stack.ret -end - -LUI.openpopupmenu = function(menu, args) - stack = args - LUI.FlowManager.RequestPopupMenu(nil, menu) - return stack.ret -end - -LUI.yesnopopup = function(data) - for k, v in luiglobals.next, data do - stack[k] = v - end - LUI.FlowManager.RequestPopupMenu(nil, "generic_yes_no_popup_") - return stack.ret -end - -LUI.confirmationpopup = function(data) - for k, v in luiglobals.next, data do - stack[k] = v - end - LUI.FlowManager.RequestPopupMenu(nil, "generic_confirmation_popup_") - return stack.ret -end - -function userdata_:getchildren() - local children = {} - local first = self:getFirstChild() - - while (first) do - table.insert(children, first) - first = first:getNextSibling() - end - - return children -end diff --git a/src/client/resources/ui_scripts/updater.lua b/src/client/resources/ui_scripts/updater.lua deleted file mode 100644 index 01d77360..00000000 --- a/src/client/resources/ui_scripts/updater.lua +++ /dev/null @@ -1,164 +0,0 @@ -updatecancelled = false -taskinterval = 100 - -updater.cancelupdate() - -function startupdatecheck(popup, autoclose) - updatecancelled = false - - local callback = function() - if (not updater.getupdatecheckstatus()) then - if (autoclose) then - LUI.FlowManager.RequestLeaveMenu(popup) - return - end - - popup.text:setText("Error: " .. updater.getlasterror()) - return - end - - if (not updater.isupdateavailable()) then - if (autoclose) then - LUI.FlowManager.RequestLeaveMenu(popup) - return - end - - popup.text:setText("No updates available") - return - end - - LUI.yesnopopup({ - title = "NOTICE", - text = "An update is available, proceed with installation?", - callback = function(result) - if (result) then - startupdatedownload(popup, autoclose) - else - LUI.FlowManager.RequestLeaveMenu(popup) - end - end - }) - end - - updater.startupdatecheck() - createtask({ - done = updater.isupdatecheckdone, - cancelled = isupdatecancelled, - callback = callback, - interval = taskinterval - }) -end - -function startupdatedownload(popup, autoclose) - updater.startupdatedownload() - - local textupdate = nil - local previousfile = nil - textupdate = game:oninterval(function() - local file = updater.getcurrentfile() - if (file == previousfile) then - return - end - - file = previousfile - popup.text:setText("Downloading file " .. updater.getcurrentfile() .. "...") - end, 10) - - local callback = function() - textupdate:clear() - - if (not updater.getupdatedownloadstatus()) then - if (autoclose) then - LUI.FlowManager.RequestLeaveMenu(popup) - return - end - - popup.text:setText("Error: " .. updater.getlasterror()) - return - end - - popup.text:setText("Update successful") - - if (updater.isrestartrequired()) then - LUI.confirmationpopup({ - title = "RESTART REQUIRED", - text = "Update requires restart", - buttontext = "RESTART", - callback = function() - updater.relaunch() - end - }) - else - if (LUI.mp_menus) then - Engine.Exec("lui_restart; lui_open mp_main_menu") - else - Engine.Exec("lui_restart") - end - end - - if (autoclose) then - LUI.FlowManager.RequestLeaveMenu(popup) - end - end - - createtask({ - done = updater.isupdatedownloaddone, - cancelled = isupdatecancelled, - callback = callback, - interval = taskinterval - }) -end - -function updaterpopup(oncancel) - return LUI.openpopupmenu("generic_waiting_popup_", { - oncancel = oncancel, - withcancel = true, - text = "Checking for updates..." - }) -end - -function createtask(data) - local interval = nil - interval = game:oninterval(function() - if (data.cancelled()) then - interval:clear() - return - end - - if (data.done()) then - interval:clear() - data.callback() - end - end, data.interval) - return interval -end - -function isupdatecancelled() - return updatecancelled -end - -function tryupdate(autoclose) - updatecancelled = false - local popup = updaterpopup(function() - updater.cancelupdate() - updatecancelled = true - end) - - startupdatecheck(popup, autoclose) -end - -function tryautoupdate() - if (not updater.autoupdatesenabled()) then - return - end - - if (not updater.gethastriedupdate()) then - game:ontimeout(function() - updater.sethastriedupdate(true) - tryupdate(true) - end, 100) - end -end - -LUI.onmenuopen("mp_main_menu", tryautoupdate) -LUI.onmenuopen("main_lockout", tryautoupdate) \ No newline at end of file From 7f1fc85ef17a8e4801023c458b25b0060765d1af Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 17 Mar 2022 02:45:35 +0200 Subject: [PATCH 109/346] remove submodules --- .gitmodules | 18 +----------------- deps/libtomcrypt | 1 - deps/libtommath | 1 - deps/protobuf | 1 - deps/zlib | 1 - 5 files changed, 1 insertion(+), 21 deletions(-) delete mode 160000 deps/libtomcrypt delete mode 160000 deps/libtommath delete mode 160000 deps/protobuf delete mode 160000 deps/zlib diff --git a/.gitmodules b/.gitmodules index 7230acd8..39bd5688 100644 --- a/.gitmodules +++ b/.gitmodules @@ -27,20 +27,4 @@ url = https://github.com/lua/lua.git [submodule "deps/stb"] path = deps/stb - url = https://github.com/nothings/stb.git -[submodule "deps/libtomcrypt"] - path = deps/libtomcrypt - url = git://github.com/libtom/libtomcrypt.git - branch = develop -[submodule "deps/zlib"] - path = deps/zlib - url = git://github.com/madler/zlib.git - branch = develop -[submodule "deps/libtommath"] - path = deps/libtommath - url = git://github.com/libtom/libtommath.git - branch = develop -[submodule "deps/protobuf"] - path = deps/protobuf - url = git://github.com/protocolbuffers/protobuf.git - branch = 3.17.x + url = https://github.com/nothings/stb.git \ No newline at end of file diff --git a/deps/libtomcrypt b/deps/libtomcrypt deleted file mode 160000 index 673f5ce2..00000000 --- a/deps/libtomcrypt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 673f5ce29015a9bba3c96792920a10601b5b0718 diff --git a/deps/libtommath b/deps/libtommath deleted file mode 160000 index 04e9d1e7..00000000 --- a/deps/libtommath +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 04e9d1e7a0493910b2eb5e757d623870692ada04 diff --git a/deps/protobuf b/deps/protobuf deleted file mode 160000 index 5500c72c..00000000 --- a/deps/protobuf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5500c72c5b616da9f0125bcfab513987a1226e2b diff --git a/deps/zlib b/deps/zlib deleted file mode 160000 index 2014a993..00000000 --- a/deps/zlib +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2014a993addbc8f1b9785d97f55fd189792c2f78 From c23ada372e013cd573346daf79ef7a3422637732 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 17 Mar 2022 03:15:30 +0200 Subject: [PATCH 110/346] readd submodules --- .gitmodules | 18 +++++++++++++++++- deps/libtomcrypt | 1 + deps/libtommath | 1 + deps/protobuf | 1 + deps/zlib | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) create mode 160000 deps/libtomcrypt create mode 160000 deps/libtommath create mode 160000 deps/protobuf create mode 160000 deps/zlib diff --git a/.gitmodules b/.gitmodules index 39bd5688..bc131f93 100644 --- a/.gitmodules +++ b/.gitmodules @@ -27,4 +27,20 @@ url = https://github.com/lua/lua.git [submodule "deps/stb"] path = deps/stb - url = https://github.com/nothings/stb.git \ No newline at end of file + url = https://github.com/nothings/stb.git +[submodule "deps/libtomcrypt"] + path = deps/libtomcrypt + url = https://github.com/libtom/libtomcrypt.git + branch = develop +[submodule "deps/libtommath"] + path = deps/libtommath + url = https://github.com/libtom/libtommath.git + branch = develop +[submodule "deps/protobuf"] + path = deps/protobuf + url = https://github.com/protocolbuffers/protobuf.git + branch = 3.17.x +[submodule "deps/zlib"] + path = deps/zlib + url = https://github.com/madler/zlib.git + branch = develop diff --git a/deps/libtomcrypt b/deps/libtomcrypt new file mode 160000 index 00000000..06a81aeb --- /dev/null +++ b/deps/libtomcrypt @@ -0,0 +1 @@ +Subproject commit 06a81aeb227424182125363f7554fad5146d6d2a diff --git a/deps/libtommath b/deps/libtommath new file mode 160000 index 00000000..66de8642 --- /dev/null +++ b/deps/libtommath @@ -0,0 +1 @@ +Subproject commit 66de86426e9cdb88526974c765108f01554af2b0 diff --git a/deps/protobuf b/deps/protobuf new file mode 160000 index 00000000..5500c72c --- /dev/null +++ b/deps/protobuf @@ -0,0 +1 @@ +Subproject commit 5500c72c5b616da9f0125bcfab513987a1226e2b diff --git a/deps/zlib b/deps/zlib new file mode 160000 index 00000000..2014a993 --- /dev/null +++ b/deps/zlib @@ -0,0 +1 @@ +Subproject commit 2014a993addbc8f1b9785d97f55fd189792c2f78 From 5fd893f45242e48df69d13a8741a9bfa672c0e4e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Mar 2022 12:55:11 -0500 Subject: [PATCH 111/346] Bump deps/libtomcrypt from `673f5ce` to `06a81ae` (#31) Bumps [deps/libtomcrypt](https://github.com/libtom/libtomcrypt) from `673f5ce` to `06a81ae`. - [Release notes](https://github.com/libtom/libtomcrypt/releases) - [Commits](https://github.com/libtom/libtomcrypt/compare/673f5ce29015a9bba3c96792920a10601b5b0718...06a81aeb227424182125363f7554fad5146d6d2a) --- updated-dependencies: - dependency-name: deps/libtomcrypt dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deps/libtomcrypt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtomcrypt b/deps/libtomcrypt index 673f5ce2..06a81aeb 160000 --- a/deps/libtomcrypt +++ b/deps/libtomcrypt @@ -1 +1 @@ -Subproject commit 673f5ce29015a9bba3c96792920a10601b5b0718 +Subproject commit 06a81aeb227424182125363f7554fad5146d6d2a From 47f66b4c0336d1e6c5b2bcbdb2ec05e86d0a864c Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 17 Mar 2022 20:58:26 +0100 Subject: [PATCH 112/346] Add LUI notify function --- src/client/game/symbols.hpp | 2 + src/client/game/ui_scripting/execution.cpp | 39 +++++++++++++++++++ src/client/game/ui_scripting/execution.hpp | 2 + src/client/game/ui_scripting/script_value.hpp | 1 + 4 files changed, 44 insertions(+) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 9381150a..f42835dd 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -146,6 +146,8 @@ namespace game WEAK symbol LUI_OpenMenu{0x14039D5F0, 0x1404CD210}; + WEAK symbol LUI_BeginEvent{0x1400D27F0, 0x140161A00}; + WEAK symbol LUI_EndEvent{0x1400D3A80, 0x140162CD0}; WEAK symbol Menu_IsMenuOpenAndVisible{0x1404709C0, 0x1404C7320}; diff --git a/src/client/game/ui_scripting/execution.cpp b/src/client/game/ui_scripting/execution.cpp index fff6b88e..cc8df795 100644 --- a/src/client/game/ui_scripting/execution.cpp +++ b/src/client/game/ui_scripting/execution.cpp @@ -37,6 +37,45 @@ namespace ui_scripting return values; } + bool notify(const std::string& name, const event_arguments& arguments) + { + const auto state = *game::hks::lua_state; + if (!game::LUI_BeginEvent(0, name.data(), state)) + { + return false; + } + + const auto _1 = gsl::finally(&disable_error_hook); + enable_error_hook(); + + const auto top = state->m_apistack.top; + try + { + const auto event = get_return_value(0).as
(); + + for (const auto& arg : arguments) + { + event.set(arg.first, arg.second); + } + } + catch (...) + { + } + + state->m_apistack.top = top; + + try + { + game::LUI_EndEvent(state); + } + catch (const std::exception& e) + { + throw std::runtime_error(std::string("Error while processing event: ") + e.what()); + } + + return true; + } + arguments call_script_function(const function& function, const arguments& arguments) { const auto state = *game::hks::lua_state; diff --git a/src/client/game/ui_scripting/execution.hpp b/src/client/game/ui_scripting/execution.hpp index 24f4dd72..4a3d3562 100644 --- a/src/client/game/ui_scripting/execution.hpp +++ b/src/client/game/ui_scripting/execution.hpp @@ -9,6 +9,8 @@ namespace ui_scripting script_value get_return_value(int offset); arguments get_return_values(int count); + bool notify(const std::string& name, const event_arguments& arguments); + arguments call_script_function(const function& function, const arguments& arguments); script_value get_field(const userdata& self, const script_value& key); diff --git a/src/client/game/ui_scripting/script_value.hpp b/src/client/game/ui_scripting/script_value.hpp index 3de52ddf..a16d2622 100644 --- a/src/client/game/ui_scripting/script_value.hpp +++ b/src/client/game/ui_scripting/script_value.hpp @@ -53,4 +53,5 @@ namespace ui_scripting }; using arguments = std::vector; + using event_arguments = std::unordered_map; } From ad6acadd4f4cc1a35b9a1ce5c11e51b910627149 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 17 Mar 2022 23:56:15 +0100 Subject: [PATCH 113/346] Fix custom materials --- src/client/component/materials.cpp | 22 ++++++++-------------- src/client/game/structs.hpp | 7 ++++++- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/client/component/materials.cpp b/src/client/component/materials.cpp index 287238c0..1b0b17c5 100644 --- a/src/client/component/materials.cpp +++ b/src/client/component/materials.cpp @@ -27,6 +27,8 @@ namespace materials std::unordered_map images; }; + char constant_table[0x20] = {}; + utils::concurrency::container material_data; game::GfxImage* setup_image(game::GfxImage* image, const utils::image& raw_image) @@ -57,6 +59,7 @@ namespace materials std::memcpy(texture_table, white->textureTable, sizeof(game::MaterialTextureDef)); std::memcpy(image, white->textureTable->u.image, sizeof(game::GfxImage)); + material->constantTable = &constant_table; material->name = utils::memory::get_allocator()->duplicate_string(name); image->name = material->name; @@ -85,6 +88,7 @@ namespace materials && !utils::io::read_file(utils::string::va("h1-mod/materials/%s.png", name.data()), &data) && !utils::io::read_file(utils::string::va("data/materials/%s.png", name.data()), &data)) { + data_.materials[name] = nullptr; return nullptr; } @@ -124,24 +128,14 @@ namespace materials return result; } - bool db_material_streaming_fail_stub(game::Material* material) + int db_material_streaming_fail_stub(game::Material* material) { - const auto found = material_data.access([material](material_data_t& data_) + if (material->constantTable == &constant_table) { - if (data_.materials.find(material->name) != data_.materials.end()) - { - return true; - } - - return false; - }); - - if (found) - { - return false; + return 0; } - return db_material_streaming_fail_hook.invoke(material); + return db_material_streaming_fail_hook.invoke(material); } } diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index bb7c3aec..40515051 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1175,7 +1175,12 @@ namespace game const char* name; char __pad0[0x118]; char textureCount; - char __pad1[7]; + char constantCount; + char stateBitsCount; + char stateFlags; + char cameraRegion; + char materialType; + char assetFlags; MaterialTechniqueSet* techniqueSet; MaterialTextureDef* textureTable; void* constantTable; From 8071edfc55611647d16b73e1e4661dffca25838c Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 18 Mar 2022 00:27:13 +0100 Subject: [PATCH 114/346] Fix stats --- src/client/component/stats.cpp | 36 +++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/client/component/stats.cpp b/src/client/component/stats.cpp index 81e7c3da..99ffdd5f 100644 --- a/src/client/component/stats.cpp +++ b/src/client/component/stats.cpp @@ -21,7 +21,7 @@ namespace stats utils::hook::detour is_item_unlocked_hook2; utils::hook::detour is_item_unlocked_hook3; - int is_item_unlocked_stub(void* a1, void* a2, void* a3) + int is_item_unlocked_stub(int a1, void* a2, int a3) { if (cg_unlock_all_items->current.enabled) { @@ -31,7 +31,7 @@ namespace stats return is_item_unlocked_hook.invoke(a1, a2, a3); } - int is_item_unlocked_stub2(void* a1, void* a2, void* a3, void* a4, void* a5, void* a6) + int is_item_unlocked_stub2(int a1, void* a2, void* a3, void* a4, int a5, void* a6) { if (cg_unlock_all_items->current.enabled) { @@ -41,7 +41,7 @@ namespace stats return is_item_unlocked_hook2.invoke(a1, a2, a3, a4, a5, a6); } - int is_item_unlocked_stub3(void* a1) + int is_item_unlocked_stub3(int a1) { if (cg_unlock_all_items->current.enabled) { @@ -50,6 +50,11 @@ namespace stats return is_item_unlocked_hook3.invoke(a1); } + + int is_item_unlocked() + { + return 0; + } } class component final : public component_interface @@ -57,19 +62,28 @@ namespace stats public: void post_unpack() override { - if (!game::environment::is_mp()) + if (game::environment::is_sp()) { return; } - cg_unlock_all_items = dvars::register_bool("cg_unlockall_items", false, game::DVAR_FLAG_SAVED, - "Whether items should be locked based on the player's stats or always unlocked."); - dvars::register_bool("cg_unlockall_classes", false, game::DVAR_FLAG_SAVED, - "Whether classes should be locked based on the player's stats or always unlocked."); + if (game::environment::is_dedi()) + { + utils::hook::jump(0x140413E60, is_item_unlocked); + utils::hook::jump(0x140413860, is_item_unlocked); + utils::hook::jump(0x140412B70, is_item_unlocked); + } + else + { + cg_unlock_all_items = dvars::register_bool("cg_unlockall_items", false, game::DVAR_FLAG_SAVED, + "Whether items should be locked based on the player's stats or always unlocked."); + dvars::register_bool("cg_unlockall_classes", false, game::DVAR_FLAG_SAVED, + "Whether classes should be locked based on the player's stats or always unlocked."); - is_item_unlocked_hook.create(0x140413E60, is_item_unlocked_stub); - is_item_unlocked_hook2.create(0x140413860, is_item_unlocked_stub2); - is_item_unlocked_hook3.create(0x140412B70, is_item_unlocked_stub3); + is_item_unlocked_hook.create(0x140413E60, is_item_unlocked_stub); + is_item_unlocked_hook2.create(0x140413860, is_item_unlocked_stub2); + is_item_unlocked_hook3.create(0x140412B70, is_item_unlocked_stub3); + } } }; } From 3d91fbc36d8f5dd30bc0cd8b431f629b9abd017f Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 18 Mar 2022 00:56:03 +0100 Subject: [PATCH 115/346] Custom font support --- src/client/component/fonts.cpp | 116 +++++++++++++++++++++++++++++++++ src/client/component/fonts.hpp | 6 ++ src/client/game/structs.hpp | 9 +++ src/client/game/symbols.hpp | 2 + 4 files changed, 133 insertions(+) create mode 100644 src/client/component/fonts.cpp create mode 100644 src/client/component/fonts.hpp diff --git a/src/client/component/fonts.cpp b/src/client/component/fonts.cpp new file mode 100644 index 00000000..ae8f37fe --- /dev/null +++ b/src/client/component/fonts.cpp @@ -0,0 +1,116 @@ +#include +#include "loader/component_loader.hpp" + +#include "fonts.hpp" +#include "console.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include +#include +#include +#include + +namespace fonts +{ + namespace + { + struct font_data_t + { + std::unordered_map fonts; + std::unordered_map raw_fonts; + }; + + utils::concurrency::container font_data; + + game::TTF* create_font(const std::string& name, const std::string& data) + { + const auto font = utils::memory::get_allocator()->allocate(); + font->name = utils::memory::get_allocator()->duplicate_string(name); + font->buffer = utils::memory::get_allocator()->duplicate_string(data); + font->len = static_cast(data.size()); + font->fontFace = 0; + return font; + } + + game::TTF* load_font(const std::string& name) + { + return font_data.access([&](font_data_t& data_) -> game::TTF* + { + if (const auto i = data_.fonts.find(name); i != data_.fonts.end()) + { + return i->second; + } + + std::string data{}; + if (const auto i = data_.raw_fonts.find(name); i != data_.raw_fonts.end()) + { + data = i->second; + } + + if (data.empty() + && !utils::io::read_file(utils::string::va("h1-mod/%s", name.data()), &data) + && !utils::io::read_file(utils::string::va("data/%s", name.data()), &data)) + { + return nullptr; + } + + const auto material = create_font(name, data); + data_.fonts[name] = material; + + return material; + }); + } + + game::TTF* try_load_font(const std::string& name) + { + try + { + return load_font(name); + } + catch (const std::exception& e) + { + console::error("Failed to load font %s: %s\n", name.data(), e.what()); + } + + return nullptr; + } + + game::TTF* db_find_xasset_header_stub(game::XAssetType type, const char* name, int create_default) + { + auto result = try_load_font(name); + if (result == nullptr) + { + result = game::DB_FindXAssetHeader(type, name, create_default).ttf; + } + return result; + } + } + + void add(const std::string& name, const std::string& data) + { + font_data.access([&](font_data_t& data_) + { + data_.raw_fonts[name] = data; + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_dedi()) + { + return; + } + + utils::hook::call(SELECT_VALUE(0x1404D41B6, 0x1405D9296), db_find_xasset_header_stub); + } + }; +} + +REGISTER_COMPONENT(fonts::component) diff --git a/src/client/component/fonts.hpp b/src/client/component/fonts.hpp new file mode 100644 index 00000000..15749bcf --- /dev/null +++ b/src/client/component/fonts.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace fonts +{ + void add(const std::string& name, const std::string& data); +} diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 40515051..4d6b3405 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1316,6 +1316,14 @@ namespace game const char* buffer; }; + struct TTF + { + const char* name; + int len; + const char* buffer; + int fontFace; + }; + struct GfxImageLoadDef { char levelCount; @@ -1387,6 +1395,7 @@ namespace game StringTable* stringTable; LuaFile* luaFile; GfxImage* image; + TTF* ttf; }; struct XAsset diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index f42835dd..1ade88ce 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -143,6 +143,8 @@ namespace game DB_EnumXAssets_Internal{0x1401C9C10, 0x1402BA830}; WEAK symbol DB_GetXAssetName{0x14019A390, 0x14028BE50}; WEAK symbol DB_GetXAssetTypeSize{0x14019A3B0, 0x14028BE70}; + WEAK symbol DB_FindXAssetHeader{0x1401CA150, 0x1402BAC70}; WEAK symbol LUI_OpenMenu{0x14039D5F0, 0x1404CD210}; From d2d5fb6654bf7f68c5b87cc3affb55996c4e2542 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Fri, 18 Mar 2022 02:40:50 +0200 Subject: [PATCH 116/346] Revert "stuff" This reverts commit 2a9ff724269dea40b1f6c3e080db6c40cf3cd4d9. --- src/client/component/arxan.cpp | 164 ---- src/client/component/auth.cpp | 25 +- src/client/component/binding.cpp | 138 ++++ src/client/component/bots.cpp | 103 +++ src/client/component/branding.cpp | 65 ++ src/client/component/colors.cpp | 182 +++++ src/client/component/command.cpp | 648 ++++++++++++++++ src/client/component/command.hpp | 50 ++ src/client/component/console.cpp | 299 ++++++++ src/client/component/console.hpp | 35 + src/client/component/dedicated.cpp | 333 ++++++++ src/client/component/dedicated_info.cpp | 65 ++ src/client/component/demonware.cpp | 604 +++++++++++++++ src/client/component/demonware.hpp | 6 + src/client/component/discord.cpp | 148 ++++ src/client/component/dvars.cpp | 443 +++++++++++ src/client/component/dvars.hpp | 28 + src/client/component/exception.cpp | 261 +++++++ src/client/component/fastfiles.cpp | 49 ++ src/client/component/fastfiles.hpp | 8 + src/client/component/filesystem.cpp | 94 +++ src/client/component/filesystem.hpp | 19 + src/client/component/fps.cpp | 174 +++++ src/client/component/game_console.cpp | 793 ++++++++++++++++++++ src/client/component/game_console.hpp | 7 + src/client/component/game_module.cpp | 3 +- src/client/component/localized_strings.cpp | 52 ++ src/client/component/localized_strings.hpp | 6 + src/client/component/logfile.cpp | 317 ++++++++ src/client/component/logfile.hpp | 13 + src/client/component/lui.cpp | 58 ++ src/client/component/map_rotation.cpp | 180 +++++ src/client/component/network.cpp | 11 +- src/client/component/party.cpp | 630 ++++++++++++++++ src/client/component/party.hpp | 17 + src/client/component/patches.cpp | 293 ++++++++ src/client/component/renderer.cpp | 77 ++ src/client/component/scheduler.cpp | 8 +- src/client/component/scripting.cpp | 141 ++++ src/client/component/scripting.hpp | 8 + src/client/component/server_list.cpp | 443 +++++++++++ src/client/component/server_list.hpp | 12 + src/client/component/shaders.cpp | 50 ++ src/client/component/slowmotion.cpp | 53 ++ src/client/component/splash.cpp | 141 ++++ src/client/component/system_check.cpp | 25 +- src/client/component/thread_names.cpp | 60 ++ src/client/component/ui_scripting.cpp | 180 +++++ src/client/component/ui_scripting.hpp | 12 + src/client/component/updater.cpp | 474 ++++++++++++ src/client/component/updater.hpp | 26 + src/client/component/videos.cpp | 55 ++ src/client/component/virtuallobby.cpp | 63 ++ src/client/loader/loader.cpp | 7 +- src/client/loader/loader.hpp | 2 +- src/client/resources/ui_scripts/common.lua | 164 ++++ src/client/resources/ui_scripts/updater.lua | 164 ++++ 57 files changed, 8286 insertions(+), 200 deletions(-) delete mode 100644 src/client/component/arxan.cpp create mode 100644 src/client/component/binding.cpp create mode 100644 src/client/component/bots.cpp create mode 100644 src/client/component/branding.cpp create mode 100644 src/client/component/colors.cpp create mode 100644 src/client/component/command.cpp create mode 100644 src/client/component/command.hpp create mode 100644 src/client/component/console.cpp create mode 100644 src/client/component/console.hpp create mode 100644 src/client/component/dedicated.cpp create mode 100644 src/client/component/dedicated_info.cpp create mode 100644 src/client/component/demonware.cpp create mode 100644 src/client/component/demonware.hpp create mode 100644 src/client/component/discord.cpp create mode 100644 src/client/component/dvars.cpp create mode 100644 src/client/component/dvars.hpp create mode 100644 src/client/component/exception.cpp create mode 100644 src/client/component/fastfiles.cpp create mode 100644 src/client/component/fastfiles.hpp create mode 100644 src/client/component/filesystem.cpp create mode 100644 src/client/component/filesystem.hpp create mode 100644 src/client/component/fps.cpp create mode 100644 src/client/component/game_console.cpp create mode 100644 src/client/component/game_console.hpp create mode 100644 src/client/component/localized_strings.cpp create mode 100644 src/client/component/localized_strings.hpp create mode 100644 src/client/component/logfile.cpp create mode 100644 src/client/component/logfile.hpp create mode 100644 src/client/component/lui.cpp create mode 100644 src/client/component/map_rotation.cpp create mode 100644 src/client/component/party.cpp create mode 100644 src/client/component/party.hpp create mode 100644 src/client/component/patches.cpp create mode 100644 src/client/component/renderer.cpp create mode 100644 src/client/component/scripting.cpp create mode 100644 src/client/component/scripting.hpp create mode 100644 src/client/component/server_list.cpp create mode 100644 src/client/component/server_list.hpp create mode 100644 src/client/component/shaders.cpp create mode 100644 src/client/component/slowmotion.cpp create mode 100644 src/client/component/splash.cpp create mode 100644 src/client/component/thread_names.cpp create mode 100644 src/client/component/ui_scripting.cpp create mode 100644 src/client/component/ui_scripting.hpp create mode 100644 src/client/component/updater.cpp create mode 100644 src/client/component/updater.hpp create mode 100644 src/client/component/videos.cpp create mode 100644 src/client/component/virtuallobby.cpp create mode 100644 src/client/resources/ui_scripts/common.lua create mode 100644 src/client/resources/ui_scripts/updater.lua diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp deleted file mode 100644 index adff7199..00000000 --- a/src/client/component/arxan.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "scheduler.hpp" -#include "game/game.hpp" - -#include - -namespace arxan -{ - namespace - { - utils::hook::detour nt_close_hook; - utils::hook::detour nt_query_information_process_hook; - - NTSTATUS WINAPI nt_query_information_process_stub(const HANDLE handle, const PROCESSINFOCLASS info_class, - const PVOID info, - const ULONG info_length, const PULONG ret_length) - { - auto* orig = static_cast(nt_query_information_process_hook. - get_original()); - const auto status = orig(handle, info_class, info, info_length, ret_length); - - if (NT_SUCCESS(status)) - { - if (info_class == ProcessBasicInformation) - { - static DWORD explorer_pid = 0; - if (!explorer_pid) - { - auto* const shell_window = GetShellWindow(); - GetWindowThreadProcessId(shell_window, &explorer_pid); - } - - static_cast(info)->Reserved3 = PVOID(DWORD64(explorer_pid)); - } - else if (info_class == 30) // ProcessDebugObjectHandle - { - *static_cast(info) = nullptr; - - return 0xC0000353; - } - else if (info_class == 7) // ProcessDebugPort - { - *static_cast(info) = nullptr; - } - else if (info_class == 31) - { - *static_cast(info) = 1; - } - } - - return status; - } - - NTSTATUS NTAPI nt_close_stub(const HANDLE handle) - { - char info[16]; - if (NtQueryObject(handle, OBJECT_INFORMATION_CLASS(4), &info, 2, nullptr) >= 0 && size_t(handle) != 0x12345) - { - auto* orig = static_cast(nt_close_hook.get_original()); - return orig(handle); - } - - return STATUS_INVALID_HANDLE; - } - - LONG WINAPI exception_filter(const LPEXCEPTION_POINTERS info) - { - if (info->ExceptionRecord->ExceptionCode == STATUS_INVALID_HANDLE) - { - return EXCEPTION_CONTINUE_EXECUTION; - } - - return EXCEPTION_CONTINUE_SEARCH; - } - - void hide_being_debugged() - { - auto* const peb = PPEB(__readgsqword(0x60)); - peb->BeingDebugged = false; - *reinterpret_cast(LPSTR(peb) + 0xBC) &= ~0x70; - } - - void remove_hardware_breakpoints() - { - CONTEXT context; - ZeroMemory(&context, sizeof(context)); - context.ContextFlags = CONTEXT_DEBUG_REGISTERS; - - auto* const thread = GetCurrentThread(); - GetThreadContext(thread, &context); - - context.Dr0 = 0; - context.Dr1 = 0; - context.Dr2 = 0; - context.Dr3 = 0; - context.Dr6 = 0; - context.Dr7 = 0; - - SetThreadContext(thread, &context); - } - - BOOL WINAPI set_thread_context_stub(const HANDLE thread, CONTEXT* context) - { - if (!game::environment::is_sp() - && game::dwGetLogOnStatus() == game::DW_LIVE_CONNECTED - && context->ContextFlags == CONTEXT_DEBUG_REGISTERS) - { - return TRUE; - } - - return SetThreadContext(thread, context); - } - } - - int just_return() - { - return 1; - } - - class component final : public component_interface - { - public: - void* load_import(const std::string& library, const std::string& function) override - { - if (function == "SetThreadContext") - { - //return set_thread_context_stub; - } - - if (function == "LoadStringA" || function == "LoadStringW") - { - return just_return; - } - - return nullptr; - } - - void post_load() override - { - hide_being_debugged(); - scheduler::loop(hide_being_debugged, scheduler::pipeline::async); - - const utils::nt::library ntdll("ntdll.dll"); - nt_close_hook.create(ntdll.get_proc("NtClose"), nt_close_stub); - nt_query_information_process_hook.create(ntdll.get_proc("NtQueryInformationProcess"), - nt_query_information_process_stub); - - AddVectoredExceptionHandler(1, exception_filter); - } - - void post_unpack() override - { - // cba to implement sp, not sure if it's even needed - if (game::environment::is_sp()) return; - - // some of arxan crashes - utils::hook::nop(0x14CDEFCAA, 6); - utils::hook::call(0x1405BCAD1, &just_return); - } - }; -} - -REGISTER_COMPONENT(arxan::component) \ No newline at end of file diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index c5aa8240..346c8d80 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -42,7 +42,7 @@ namespace auth std::string get_protected_data() { - std::string input = "X-Labs-H1STEAM-Auth"; + std::string input = "X-Labs-H1Mod-Auth"; DATA_BLOB data_in{}, data_out{}; data_in.pbData = reinterpret_cast(input.data()); @@ -177,20 +177,21 @@ namespace auth game::SV_DirectConnect(from); } + // CAN'T FIND //void* get_direct_connect_stub() //{ // return utils::hook::assemble([](utils::hook::assembler& a) - // { - // a.lea(rcx, qword_ptr(rsp, 0x20)); - // a.movaps(xmmword_ptr(rsp, 0x20), xmm0); + // { + // a.lea(rcx, qword_ptr(rsp, 0x20)); + // a.movaps(xmmword_ptr(rsp, 0x20), xmm0); - // a.pushad64(); - // a.mov(rdx, rsi); - // a.call_aligned(direct_connect); - // a.popad64(); + // a.pushad64(); + // a.mov(rdx, rsi); + // a.call_aligned(direct_connect); + // a.popad64(); - // a.jmp(0x140488CE2); // H1MP64(1.4) - // }); + // a.jmp(0x140488CE2); // H1MP64(1.4) + // }); //} } @@ -224,8 +225,8 @@ namespace auth utils::hook::jump(0x1D7542_b, 0x1D7587_b); // STEAM MAYBE `1401D7553` ON FIRST utils::hook::jump(0x1D7A82_b, 0x1D7AC8_b); // STEAM - //utils::hook::jump(0x1401CAE70, get_direct_connect_stub(), true); // STEAM - utils::hook::call(0x12D437_b, send_connect_data_stub); // STEAM + //utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) can't find + utils::hook::call(0x12D437_b, send_connect_data_stub); // H1(1.4) // Skip checks for sending connect packet utils::hook::jump(0x1402508FC, 0x140250946); diff --git a/src/client/component/binding.cpp b/src/client/component/binding.cpp new file mode 100644 index 00000000..e40b7f42 --- /dev/null +++ b/src/client/component/binding.cpp @@ -0,0 +1,138 @@ +#include +#include "loader/component_loader.hpp" +#include "game/game.hpp" + +#include +#include + +namespace binding +{ + namespace + { + std::vector custom_binds = {}; + + utils::hook::detour cl_execute_key_hook; + + int get_num_keys() + { + return SELECT_VALUE(102, 103); + } + + int key_write_bindings_to_buffer_stub(int /*localClientNum*/, char* buffer, const int buffer_size) + { + auto bytes_used = 0; + const auto buffer_size_align = static_cast(buffer_size) - 4; + + for (auto key_index = 0; key_index < 256; ++key_index) + { + const auto* const key_button = game::Key_KeynumToString(key_index, 0, 1); + auto value = game::playerKeys->keys[key_index].binding; + + if (value && value < get_num_keys()) + { + const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used), + "bind %s \"%s\"\n", key_button, game::command_whitelist[value]); + + if (len < 0) + { + return bytes_used; + } + + bytes_used += len; + } + else if (value >= get_num_keys()) + { + value -= get_num_keys(); + if (static_cast(value) < custom_binds.size() && !custom_binds[value].empty()) + { + const auto len = sprintf_s(&buffer[bytes_used], (buffer_size_align - bytes_used), + "bind %s \"%s\"\n", key_button, custom_binds[value].data()); + + if (len < 0) + { + return bytes_used; + } + + bytes_used += len; + } + } + } + + buffer[bytes_used] = 0; + return bytes_used; + } + + int get_binding_for_custom_command(const char* command) + { + auto index = 0; + for (auto& bind : custom_binds) + { + if (bind == command) + { + return index; + } + index++; + } + + custom_binds.emplace_back(command); + index = static_cast(custom_binds.size()) - 1; + + return index; + } + + int key_get_binding_for_cmd_stub(const char* command) + { + // original binds + for (auto i = 0; i <= get_num_keys(); i++) + { + if (game::command_whitelist[i] && !strcmp(command, game::command_whitelist[i])) + { + return i; + } + } + + // custom binds + return get_num_keys() + get_binding_for_custom_command(command); + } + + void cl_execute_key_stub(const int local_client_num, int key, const int down, const int time) + { + if (key >= get_num_keys()) + { + key -= get_num_keys(); + + if (static_cast(key) < custom_binds.size() && !custom_binds[key].empty()) + { + game::Cbuf_AddText(local_client_num, utils::string::va("%s\n", custom_binds[key].data())); + } + + return; + } + + cl_execute_key_hook.invoke(local_client_num, key, down, time); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_dedi()) + { + return; + } + + // write all bindings to config file + utils::hook::call(SELECT_VALUE(0x1401881DB, 0x14025032F), key_write_bindings_to_buffer_stub); // H1(1.4) + + // links a custom command to an index + utils::hook::jump(SELECT_VALUE(0x140343C00, 0x1404041E0), key_get_binding_for_cmd_stub); // H1(1.4) + + // execute custom binds + cl_execute_key_hook.create(SELECT_VALUE(0x140183C70, 0x14024ACF0), &cl_execute_key_stub); // H1(1.4) + } + }; +} + +REGISTER_COMPONENT(binding::component) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp new file mode 100644 index 00000000..81f74628 --- /dev/null +++ b/src/client/component/bots.cpp @@ -0,0 +1,103 @@ +#include +#include "loader/component_loader.hpp" + +#include "command.hpp" +#include "scheduler.hpp" +#include "network.hpp" +#include "party.hpp" + +#include "game/game.hpp" +#include "game/scripting/execution.hpp" + +#include +#include +#include + +namespace bots +{ + namespace + { + bool can_add() + { + if (party::get_client_count() < *game::mp::svs_numclients) + { + return true; + } + return false; + } + + // TODO: when scripting comes, fix this to use better notifies + void bot_team_join(const int entity_num) + { + const game::scr_entref_t entref{static_cast(entity_num), 0}; + scheduler::once([entref]() + { + scripting::notify(entref, "luinotifyserver", {"team_select", 2}); + scheduler::once([entref]() + { + auto* _class = utils::string::va("class%d", utils::cryptography::random::get_integer() % 5); + scripting::notify(entref, "luinotifyserver", {"class_select", _class}); + }, scheduler::pipeline::server, 2s); + }, scheduler::pipeline::server, 2s); + } + + void spawn_bot(const int entity_num) + { + game::SV_SpawnTestClient(&game::mp::g_entities[entity_num]); + if (game::Com_GetCurrentCoDPlayMode() == game::CODPLAYMODE_CORE) + { + bot_team_join(entity_num); + } + } + + void add_bot() + { + if (!can_add()) + { + return; + } + + // SV_BotGetRandomName + const auto* const bot_name = game::SV_BotGetRandomName(); + auto* bot_ent = game::SV_AddBot(bot_name); + if (bot_ent) + { + spawn_bot(bot_ent->s.entityNum); + } + else if (can_add()) // workaround since first bot won't ever spawn + { + add_bot(); + } + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) + { + return; + } + + command::add("spawnBot", [](const command::params& params) + { + if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) return; + + auto num_bots = 1; + if (params.size() == 2) + { + num_bots = atoi(params.get(1)); + } + + for (auto i = 0; i < (num_bots > *game::mp::svs_numclients ? *game::mp::svs_numclients : num_bots); i++) + { + scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i); + } + }); + } + }; +} + +REGISTER_COMPONENT(bots::component) \ No newline at end of file diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp new file mode 100644 index 00000000..2f74693b --- /dev/null +++ b/src/client/component/branding.cpp @@ -0,0 +1,65 @@ +#include +#include "loader/component_loader.hpp" + +#include "localized_strings.hpp" +#include "scheduler.hpp" +#include "command.hpp" +#include "version.hpp" + +#include "game/game.hpp" +#include "dvars.hpp" + +#include +#include + +// fonts/default.otf, fonts/defaultBold.otf, fonts/fira_mono_regular.ttf, fonts/fira_mono_bold.ttf + +namespace branding +{ + namespace + { + utils::hook::detour ui_get_formatted_build_number_hook; + + float color[4] = {0.666f, 0.666f, 0.666f, 0.666f}; + + const char* ui_get_formatted_build_number_stub() + { + const auto* const build_num = ui_get_formatted_build_number_hook.invoke(); + return utils::string::va("%s (%s)", VERSION, build_num); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + + if (game::environment::is_dedi()) + { + return; + } + + if (game::environment::is_mp()) + { + localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n"); + localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER"); + } + + dvars::override::set_string("version", utils::string::va("H1-Mod %s", VERSION)); + + ui_get_formatted_build_number_hook.create( + SELECT_VALUE(0x1403B1C40, 0x1404E74C0), ui_get_formatted_build_number_stub); + + scheduler::loop([]() + { + const auto font = game::R_RegisterFont("fonts/fira_mono_bold.ttf", 20); + + game::R_AddCmdDrawText("H1-Mod: " VERSION, 0x7FFFFFFF, font, 10.f, + 5.f + static_cast(font->pixelHeight), 1.f, 1.f, 0.0f, color, 0); + }, scheduler::pipeline::renderer); + } + }; +} + +REGISTER_COMPONENT(branding::component) diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp new file mode 100644 index 00000000..75eff23a --- /dev/null +++ b/src/client/component/colors.cpp @@ -0,0 +1,182 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include +#include + +namespace colors +{ + struct hsv_color + { + unsigned char h; + unsigned char s; + unsigned char v; + }; + + namespace + { + std::vector color_table; + + DWORD hsv_to_rgb(const hsv_color hsv) + { + DWORD rgb; + + if (hsv.s == 0) + { + return RGB(hsv.v, hsv.v, hsv.v); + } + + // converting to 16 bit to prevent overflow + const unsigned int h = hsv.h; + const unsigned int s = hsv.s; + const unsigned int v = hsv.v; + + const auto region = static_cast(h / 43); + const auto remainder = (h - (region * 43)) * 6; + + const auto p = static_cast((v * (255 - s)) >> 8); + const auto q = static_cast( + (v * (255 - ((s * remainder) >> 8))) >> 8); + const auto t = static_cast( + (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8); + + switch (region) + { + case 0: + rgb = RGB(v, t, p); + break; + case 1: + rgb = RGB(q, v, p); + break; + case 2: + rgb = RGB(p, v, t); + break; + case 3: + rgb = RGB(p, q, v); + break; + case 4: + rgb = RGB(t, p, v); + break; + default: + rgb = RGB(v, p, q); + break; + } + + return rgb; + } + + int color_index(const char c) + { + const auto index = c - 48; + return index >= 0xC ? 7 : index; + } + + char add(const uint8_t r, const uint8_t g, const uint8_t b) + { + const char index = '0' + static_cast(color_table.size()); + color_table.push_back(RGB(r, g, b)); + return index; + } + + void com_clean_name_stub(const char* in, char* out, const int out_size) + { + strncpy_s(out, out_size, in, _TRUNCATE); + } + + char* i_clean_str_stub(char* string) + { + utils::string::strip(string, string, static_cast(strlen(string)) + 1); + + return string; + } + + size_t get_client_name_stub(const int local_client_num, const int index, char* buf, const int size, + const size_t unk, const size_t unk2) + { + // CL_GetClientName (CL_GetClientNameAndClantag?) + const auto result = utils::hook::invoke(0x14025BAA0, local_client_num, index, buf, size, unk, unk2); + + utils::string::strip(buf, buf, size); + + return result; + } + + void rb_lookup_color_stub(const char index, DWORD* color) + { + *color = RGB(255, 255, 255); + + if (index == '8') + { + *color = *reinterpret_cast(SELECT_VALUE(0x14F142FF8, 0x14FE70634)); // H1(1.4) + } + else if (index == '9') + { + *color = *reinterpret_cast(SELECT_VALUE(0x14F142FFC, 0x14FE70638)); // H1(1.4) + } + else if (index == ':') + { + *color = hsv_to_rgb({static_cast((game::Sys_Milliseconds() / 100) % 256), 255, 255}); + } + else if (index == ';') + { + *color = *reinterpret_cast(SELECT_VALUE(0x14F143004, 0x14FE70640)); // H1(1.4) + } + else if (index == '<') + { + *color = 0xFFFCFF80; + } + else + { + *color = color_table[color_index(index)]; + } + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_dedi()) + { + return; + } + + if (!game::environment::is_sp()) + { + // allows colored name in-game + utils::hook::jump(0x140503810, com_clean_name_stub); // H1(1.4) + + // don't apply colors to overhead names + utils::hook::call(0x1400AB416, get_client_name_stub); // H1(1.4) + + // patch I_CleanStr + utils::hook::jump(0x140503D00, i_clean_str_stub); // H1(1.4) + } + + // force new colors + utils::hook::jump(SELECT_VALUE(0x140524BD0, 0x1406206A0), rb_lookup_color_stub); // H1(1.4) + + // add colors + add(0, 0, 0); // 0 - Black + add(255, 49, 49); // 1 - Red + add(134, 192, 0); // 2 - Green + add(255, 173, 34); // 3 - Yellow + add(0, 135, 193); // 4 - Blue + add(32, 197, 255); // 5 - Light Blue + add(151, 80, 221); // 6 - Pink + add(255, 255, 255); // 7 - White + + add(0, 0, 0); // 8 - Team color (axis?) + add(0, 0, 0); // 9 - Team color (allies?) + + add(0, 0, 0); // 10 - Rainbow (:) + add(0, 0, 0); + // 11 - Server color (;) - using that color in infostrings (e.g. your name) fails, ';' is an illegal character! + } + }; +} + +REGISTER_COMPONENT(colors::component) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp new file mode 100644 index 00000000..b5c1ad40 --- /dev/null +++ b/src/client/component/command.cpp @@ -0,0 +1,648 @@ +#include +#include "loader/component_loader.hpp" +#include "command.hpp" +#include "console.hpp" +#include "game_console.hpp" + +#include "game/game.hpp" + +#include +#include +#include +#include "utils/io.hpp" +#include + +namespace command +{ + namespace + { + utils::hook::detour client_command_hook; + + std::unordered_map> handlers; + std::unordered_map> handlers_sv; + + void main_handler() + { + params params = {}; + + const auto command = utils::string::to_lower(params[0]); + if (handlers.find(command) != handlers.end()) + { + handlers[command](params); + } + } + + void client_command(const int client_num, void* a2) + { + params_sv params = {}; + + const auto command = utils::string::to_lower(params[0]); + if (handlers_sv.find(command) != handlers_sv.end()) + { + handlers_sv[command](client_num, params); + } + + client_command_hook.invoke(client_num, a2); + } + + // Shamelessly stolen from Quake3 + // https://github.com/id-Software/Quake-III-Arena/blob/dbe4ddb10315479fc00086f08e25d968b4b43c49/code/qcommon/common.c#L364 + void parse_command_line() + { + static auto parsed = false; + if (parsed) + { + return; + } + + static std::string comand_line_buffer = GetCommandLineA(); + auto* command_line = comand_line_buffer.data(); + + auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); //H1(1.4) + auto* com_console_lines = reinterpret_cast(0x142623FC0); //H1(1.4) + + auto inq = false; + com_console_lines[0] = command_line; + com_num_console_lines = 0; + + while (*command_line) + { + if (*command_line == '"') + { + inq = !inq; + } + // look for a + separating character + // if commandLine came from a file, we might have real line seperators + if ((*command_line == '+' && !inq) || *command_line == '\n' || *command_line == '\r') + { + if (com_num_console_lines == 0x20) // MAX_CONSOLE_LINES + { + break; + } + com_console_lines[com_num_console_lines] = command_line + 1; + com_num_console_lines++; + *command_line = '\0'; + } + command_line++; + } + parsed = true; + } + + void parse_commandline_stub() + { + parse_command_line(); + utils::hook::invoke(0x1400D8210); + } + + game::dvar_t* dvar_command_stub() + { + const params args; + + if (args.size() <= 0) + { + return 0; + } + + const auto dvar = game::Dvar_FindVar(args[0]); + + if (dvar) + { + if (args.size() == 1) + { + const auto current = game::Dvar_ValueToString(dvar, dvar->current); + const auto reset = game::Dvar_ValueToString(dvar, dvar->reset); + + console::info("\"%s\" is: \"%s\" default: \"%s\" hash: 0x%08lX", + args[0], current, reset, dvar->hash); + + console::info(" %s\n", dvars::dvar_get_domain(dvar->type, dvar->domain).data()); + } + else + { + char command[0x1000] = { 0 }; + game::Dvar_GetCombinedString(command, 1); + game::Dvar_SetCommand(dvar->hash, "", command); + } + + return dvar; + } + + return 0; + } + } + + void read_startup_variable(const std::string& dvar) + { + // parse the commandline if it's not parsed + parse_command_line(); + + auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); //H1(1.4) + auto* com_console_lines = reinterpret_cast(0x142623FC0); //H1(1.4) + + for (int i = 0; i < com_num_console_lines; i++) + { + game::Cmd_TokenizeString(com_console_lines[i]); + + // only +set dvar value + if (game::Cmd_Argc() >= 3 && game::Cmd_Argv(0) == "set"s && game::Cmd_Argv(1) == dvar) + { + game::Dvar_SetCommand(game::generateHashValue(game::Cmd_Argv(1)), "", game::Cmd_Argv(2)); + } + + game::Cmd_EndTokenizeString(); + } + } + + params::params() + : nesting_(game::cmd_args->nesting) + { + } + + int params::size() const + { + return game::cmd_args->argc[this->nesting_]; + } + + const char* params::get(const int index) const + { + if (index >= this->size()) + { + return ""; + } + + return game::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; + } + + params_sv::params_sv() + : nesting_(game::sv_cmd_args->nesting) + { + } + + 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; + } + + void add_raw(const char* name, void (*callback)()) + { + game::Cmd_AddCommandInternal(name, callback, utils::memory::get_allocator()->allocate()); + } + + void add_test(const char* name, void (*callback)()) + { + static game::cmd_function_s cmd_test; + return game::Cmd_AddCommandInternal(name, callback, &cmd_test); + } + + void add(const char* name, const std::function& callback) + { + static game::cmd_function_s cmd_test; + + const auto command = utils::string::to_lower(name); + + if (handlers.find(command) == handlers.end()) + add_raw(name, main_handler); + + handlers[command] = callback; + } + + void add(const char* name, const std::function& callback) + { + add(name, [callback](const params&) + { + callback(); + }); + } + + void add_sv(const char* name, std::function callback) + { + // doing this so the sv command would show up in the console + add_raw(name, nullptr); + + const auto command = utils::string::to_lower(name); + + if (handlers_sv.find(command) == handlers_sv.end()) + handlers_sv[command] = std::move(callback); + } + + void execute(std::string command, const bool sync) + { + command += "\n"; + + if (sync) + { + game::Cmd_ExecuteSingleCommand(0, 0, command.data()); + } + else + { + game::Cbuf_AddText(0, command.data()); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) + { + add_commands_sp(); + } + else + { + utils::hook::call(0x1400D728F, &parse_commandline_stub); // MWR TEST + utils::hook::jump(0x14041D750, dvar_command_stub); + + add_commands_mp(); + } + + add_commands_generic(); + } + + private: + static void add_commands_generic() + { + add("quit", game::Quit); + //add("quit_hard", utils::nt::raise_hard_exception); /* this command delivers you to a windows blue screen, its quit hard from windows xD */ + add("crash", []() + { + *reinterpret_cast(1) = 0; + }); + + /*add("consoleList", [](const params& params) + { + const std::string input = params.get(1); + + std::vector matches; + game_console::find_matches(input, matches, false); + + for (auto& match : matches) + { + auto* dvar = game::Dvar_FindVar(match.c_str()); + if (!dvar) + { + console::info("[CMD]\t %s\n", match.c_str()); + } + else + { + console::info("[DVAR]\t%s \"%s\"\n", match.c_str(), game::Dvar_ValueToString(dvar, dvar->current, 0)); + } + } + + console::info("Total %i matches\n", matches.size()); + });*/ + + add("commandDump", [](const params& argument) + { + console::info("================================ COMMAND DUMP =====================================\n"); + game::cmd_function_s* cmd = (*game::cmd_functions); + std::string filename; + if (argument.size() == 2) + { + filename = "h1-mod/"; + filename.append(argument[1]); + if (!filename.ends_with(".txt")) + { + filename.append(".txt"); + } + } + int i = 0; + while (cmd) + { + if (cmd->name) + { + if (!filename.empty()) + { + const auto line = std::format("{}\r\n", cmd->name); + utils::io::write_file(filename, line, i != 0); + } + console::info("%s\n", cmd->name); + i++; + } + cmd = cmd->next; + } + console::info("\n%i commands\n", i); + console::info("================================ END COMMAND DUMP =================================\n"); + }); + + /*add("listassetpool", [](const params& params) + { + if (params.size() < 2) + { + console::info("listassetpool [filter]: list all the assets in the specified pool\n"); + + for (auto i = 0; i < game::XAssetType::ASSET_TYPE_COUNT; i++) + { + console::info("%d %s\n", i, game::g_assetNames[i]); + } + } + else + { + const auto type = static_cast(atoi(params.get(1))); + + if (type < 0 || type >= game::XAssetType::ASSET_TYPE_COUNT) + { + console::error("Invalid pool passed must be between [%d, %d]\n", 0, game::XAssetType::ASSET_TYPE_COUNT - 1); + return; + } + + console::info("Listing assets in pool %s\n", game::g_assetNames[type]); + + const std::string filter = params.get(2); + enum_assets(type, [type, filter](const game::XAssetHeader header) + { + const auto asset = game::XAsset{type, header}; + const auto* const asset_name = game::DB_GetXAssetName(&asset); + //const auto entry = game::DB_FindXAssetEntry(type, asset_name); + //TODO: display which zone the asset is from + + if (!filter.empty() && !game_console::match_compare(filter, asset_name, false)) + { + return; + } + + console::info("%s\n", asset_name); + }, true); + } + }); + + add("vstr", [](const params& params) + { + if (params.size() < 2) + { + console::info("vstr : execute a variable command\n"); + return; + } + + const auto* dvarName = params.get(1); + const auto* dvar = game::Dvar_FindVar(dvarName); + + if (dvar == nullptr) + { + console::info("%s doesn't exist\n", dvarName); + return; + } + + if (dvar->type != game::dvar_type::string + && dvar->type != game::dvar_type::enumeration) + { + console::info("%s is not a string-based dvar\n", dvar->hash); + return; + } + + execute(dvar->current.string); + });*/ + } + + static void add_commands_sp() + { + add("god", []() + { + if (!game::SV_Loaded()) + { + return; + } + + game::sp::g_entities[0].flags ^= 1; + game::CG_GameMessage(0, utils::string::va("godmode %s", + game::sp::g_entities[0].flags & 1 + ? "^2on" + : "^1off")); + }); + + add("demigod", []() + { + if (!game::SV_Loaded()) + { + return; + } + + game::sp::g_entities[0].flags ^= 2; + game::CG_GameMessage(0, utils::string::va("demigod mode %s", + game::sp::g_entities[0].flags & 2 + ? "^2on" + : "^1off")); + }); + + add("notarget", []() + { + if (!game::SV_Loaded()) + { + return; + } + + game::sp::g_entities[0].flags ^= 4; + game::CG_GameMessage(0, utils::string::va("notarget %s", + game::sp::g_entities[0].flags & 4 + ? "^2on" + : "^1off")); + }); + + add("noclip", []() + { + if (!game::SV_Loaded()) + { + return; + } + + game::sp::g_entities[0].client->flags ^= 1; + game::CG_GameMessage(0, utils::string::va("noclip %s", + game::sp::g_entities[0].client->flags & 1 + ? "^2on" + : "^1off")); + }); + + add("ufo", []() + { + if (!game::SV_Loaded()) + { + return; + } + + game::sp::g_entities[0].client->flags ^= 2; + game::CG_GameMessage(0, utils::string::va("ufo %s", + game::sp::g_entities[0].client->flags & 2 + ? "^2on" + : "^1off")); + }); + } + + static void add_commands_mp() + { + //client_command_hook.create(0x1402E98F0, &client_command); + + /*add_sv("god", [](const int client_num, const params_sv&) + { + if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"Cheats are not enabled on this server\""); + return; + } + + game::mp::g_entities[client_num].flags ^= 1; + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + utils::string::va("f \"godmode %s\"", + game::mp::g_entities[client_num].flags & 1 + ? "^2on" + : "^1off")); + }); + + add_sv("demigod", [](const int client_num, const params_sv&) + { + if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"Cheats are not enabled on this server\""); + return; + } + + game::mp::g_entities[client_num].flags ^= 2; + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + utils::string::va("f \"demigod mode %s\"", + game::mp::g_entities[client_num].flags & 2 + ? "^2on" + : "^1off")); + }); + + add_sv("notarget", [](const int client_num, const params_sv&) + { + if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"Cheats are not enabled on this server\""); + return; + } + + game::mp::g_entities[client_num].flags ^= 4; + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + utils::string::va("f \"notarget %s\"", + game::mp::g_entities[client_num].flags & 4 + ? "^2on" + : "^1off")); + }); + + add_sv("noclip", [](const int client_num, const params_sv&) + { + if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"Cheats are not enabled on this server\""); + return; + } + + game::mp::g_entities[client_num].client->flags ^= 1; + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + utils::string::va("f \"noclip %s\"", + game::mp::g_entities[client_num].client->flags & 1 + ? "^2on" + : "^1off")); + }); + + add_sv("ufo", [](const int client_num, const params_sv&) + { + if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"Cheats are not enabled on this server\""); + return; + } + + game::mp::g_entities[client_num].client->flags ^= 2; + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + utils::string::va("f \"ufo %s\"", + game::mp::g_entities[client_num].client->flags & 2 + ? "^2on" + : "^1off")); + }); + + add_sv("give", [](const int client_num, const params_sv& params) + { + if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"Cheats are not enabled on this server\""); + return; + } + + if (params.size() < 2) + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"You did not specify a weapon name\""); + return; + } + + auto ps = game::SV_GetPlayerstateForClientNum(client_num); + const auto wp = game::G_GetWeaponForName(params.get(1)); + if (wp) + { + if (game::G_GivePlayerWeapon(ps, wp, 0, 0, 0, 0, 0, 0)) + { + game::G_InitializeAmmo(ps, wp, 0); + game::G_SelectWeapon(client_num, wp); + } + } + }); + + add_sv("take", [](const int client_num, const params_sv& params) + { + if (!game::Dvar_FindVar("sv_cheats")->current.enabled) + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"Cheats are not enabled on this server\""); + return; + } + + if (params.size() < 2) + { + game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, + "f \"You did not specify a weapon name\""); + return; + } + + auto ps = game::SV_GetPlayerstateForClientNum(client_num); + const auto wp = game::G_GetWeaponForName(params.get(1)); + if (wp) + { + game::G_TakePlayerWeapon(ps, wp); + } + });*/ + } + }; +} + +REGISTER_COMPONENT(command::component) diff --git a/src/client/component/command.hpp b/src/client/component/command.hpp new file mode 100644 index 00000000..bd70d0c6 --- /dev/null +++ b/src/client/component/command.hpp @@ -0,0 +1,50 @@ +#pragma once + +namespace command +{ + class params + { + public: + params(); + + int size() const; + const char* get(int index) const; + std::string join(int index) const; + + const char* operator[](const int index) const + { + return this->get(index); // + } + + private: + int nesting_; + }; + + class params_sv + { + public: + params_sv(); + + int size() const; + const char* get(int index) const; + std::string join(int index) const; + + const char* operator[](const int index) const + { + return this->get(index); // + } + + private: + int nesting_; + }; + + void read_startup_variable(const std::string& dvar); + + void add_raw(const char* name, void (*callback)()); + void add(const char* name, const std::function& callback); + void add(const char* name, const std::function& callback); + + void add_sv(const char* name, std::function callback); + + void execute(std::string command, bool sync = false); +} \ No newline at end of file diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp new file mode 100644 index 00000000..174beaf8 --- /dev/null +++ b/src/client/component/console.cpp @@ -0,0 +1,299 @@ +#include +#include "console.hpp" +#include "loader/component_loader.hpp" +#include "game/game.hpp" +#include "command.hpp" + +#include +#include +#include +#include + +namespace game_console +{ + void print(int type, const std::string& data); +} + +namespace console +{ + namespace + { + using message_queue = std::queue; + utils::concurrency::container messages; + + bool native_console() + { + static const auto flag = utils::flags::has_flag("nativeconsole"); + return flag; + } + + void hide_console() + { + auto* const con_window = GetConsoleWindow(); + + DWORD process; + GetWindowThreadProcessId(con_window, &process); + + if (!native_console() && (process == GetCurrentProcessId() || IsDebuggerPresent())) + { + ShowWindow(con_window, SW_HIDE); + } + } + + std::string format(va_list* ap, const char* message) + { + static thread_local char buffer[0x1000]; + + const auto count = _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), message, *ap); + + if (count < 0) return {}; + return {buffer, static_cast(count)}; + } + + void dispatch_message(const int type, const std::string& message) + { + if (native_console()) + { + printf("%s\n", message.data()); + return; + } + + game_console::print(type, message); + messages.access([&message](message_queue& msgs) + { + msgs.emplace(message); + }); + } + + void append_text(const char* text) + { + dispatch_message(con_type_info, text); + } + } + + class component final : public component_interface + { + public: + component() + { + hide_console(); + + if (native_console()) + { + setvbuf(stdout, nullptr, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); + } + else + { + (void)_pipe(this->handles_, 1024, _O_TEXT); + (void)_dup2(this->handles_[1], 1); + (void)_dup2(this->handles_[1], 2); + } + } + + void post_start() override + { + this->terminate_runner_ = false; + + this->console_runner_ = utils::thread::create_named_thread("Console IO", [this] + { + if (native_console()) + { + this->native_input(); + } + else + { + this->runner(); + } + }); + } + + void pre_destroy() override + { + this->terminate_runner_ = true; + + printf("\r\n"); + _flushall(); + + if (this->console_runner_.joinable()) + { + this->console_runner_.join(); + } + + if (this->console_thread_.joinable()) + { + this->console_thread_.join(); + } + +#ifndef NATIVE_CONSOLE + _close(this->handles_[0]); + _close(this->handles_[1]); +#endif + + messages.access([&](message_queue& msgs) + { + msgs = {}; + }); + } + + void post_unpack() override + { + // Redirect input (]command) + utils::hook::jump(SELECT_VALUE(0x1403E34C0, 0x1405141E0), append_text); // H1(1.4) + + this->initialize(); + } + + private: + volatile bool console_initialized_ = false; + volatile bool terminate_runner_ = false; + + std::thread console_runner_; + std::thread console_thread_; + + int handles_[2]{}; + + void initialize() + { + this->console_thread_ = utils::thread::create_named_thread("Console", [this]() + { + if (!native_console() && (game::environment::is_dedi() || !utils::flags::has_flag("noconsole"))) + { + game::Sys_ShowConsole(); + } + + if (!game::environment::is_dedi()) + { + // Hide that shit + ShowWindow(console::get_window(), SW_MINIMIZE); + } + + { + messages.access([&](message_queue&) + { + this->console_initialized_ = true; + }); + } + + MSG msg; + while (!this->terminate_runner_) + { + if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + command::execute("quit", false); + break; + } + + TranslateMessage(&msg); + DispatchMessage(&msg); + } + else + { + this->log_messages(); + std::this_thread::sleep_for(1ms); + } + } + }); + } + + void log_messages() + { + /*while*/ + if (this->console_initialized_ && !messages.get_raw().empty()) + { + std::queue message_queue_copy; + + { + messages.access([&](message_queue& msgs) + { + message_queue_copy = std::move(msgs); + msgs = {}; + }); + } + + while (!message_queue_copy.empty()) + { + log_message(message_queue_copy.front()); + message_queue_copy.pop(); + } + } + + fflush(stdout); + fflush(stderr); + } + + static void log_message(const std::string& message) + { + OutputDebugStringA(message.data()); + game::Conbuf_AppendText(message.data()); + } + + void runner() + { + char buffer[1024]; + + while (!this->terminate_runner_ && this->handles_[0]) + { + const auto len = _read(this->handles_[0], buffer, sizeof(buffer)); + if (len > 0) + { + dispatch_message(con_type_info, std::string(buffer, len)); + } + else + { + std::this_thread::sleep_for(1ms); + } + } + + std::this_thread::yield(); + } + + void native_input() + { + std::string cmd; + + while (!this->terminate_runner_) + { + std::getline(std::cin, cmd); + command::execute(cmd); + } + + std::this_thread::yield(); + } + }; + + HWND get_window() + { + return *reinterpret_cast((SELECT_VALUE(0x14CF56C00, 0x14DDFC2D0))); // H1(1.4) + } + + void set_title(std::string title) + { + SetWindowText(get_window(), title.data()); + } + + void set_size(const int width, const int height) + { + RECT rect; + GetWindowRect(get_window(), &rect); + + SetWindowPos(get_window(), nullptr, rect.left, rect.top, width, height, 0); + + auto* const logo_window = *reinterpret_cast(SELECT_VALUE(0x14CF56C10, 0x14DDFC2E0)); // H1(1.4) + SetWindowPos(logo_window, nullptr, 5, 5, width - 25, 60, 0); + } + + void print(const int type, const char* fmt, ...) + { + va_list ap; + va_start(ap, fmt); + const auto result = format(&ap, fmt); + va_end(ap); + + dispatch_message(type, result); + } +} + +REGISTER_COMPONENT(console::component) diff --git a/src/client/component/console.hpp b/src/client/component/console.hpp new file mode 100644 index 00000000..302951a8 --- /dev/null +++ b/src/client/component/console.hpp @@ -0,0 +1,35 @@ +#pragma once + +namespace console +{ + HWND get_window(); + void set_title(std::string title); + void set_size(int width, int height); + + enum console_type + { + con_type_error = 1, + con_type_warning = 3, + con_type_info = 7 + }; + + void print(int type, const char* fmt, ...); + + template + void error(const char* fmt, Args&&... args) + { + print(con_type_error, fmt, std::forward(args)...); + } + + template + void warn(const char* fmt, Args&&... args) + { + print(con_type_warning, fmt, std::forward(args)...); + } + + template + void info(const char* fmt, Args&&... args) + { + print(con_type_info, fmt, std::forward(args)...); + } +} \ No newline at end of file diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp new file mode 100644 index 00000000..8de5e9ac --- /dev/null +++ b/src/client/component/dedicated.cpp @@ -0,0 +1,333 @@ +#include +#include "loader/component_loader.hpp" +#include "scheduler.hpp" +#include "server_list.hpp" +#include "network.hpp" +#include "command.hpp" +#include "game/game.hpp" +#include "game/dvars.hpp" +#include "dvars.hpp" +#include "console.hpp" + +#include +#include + +namespace dedicated +{ + namespace + { + utils::hook::detour gscr_set_dynamic_dvar_hook; + utils::hook::detour com_quit_f_hook; + + void init_dedicated_server() + { + static bool initialized = false; + if (initialized) return; + initialized = true; + + // R_LoadGraphicsAssets + utils::hook::invoke(0x1405DF4B0); + } + + void send_heartbeat() + { + auto* const dvar = game::Dvar_FindVar("sv_lanOnly"); + if (dvar && dvar->current.enabled) + { + return; + } + + game::netadr_s target{}; + if (server_list::get_master_server(target)) + { + network::send(target, "heartbeat", "H1"); + } + } + + std::vector& get_startup_command_queue() + { + static std::vector startup_command_queue; + return startup_command_queue; + } + + void execute_startup_command(int client, int /*controllerIndex*/, const char* command) + { + if (game::Live_SyncOnlineDataFlags(0) == 0) + { + game::Cbuf_ExecuteBufferInternal(0, 0, command, game::Cmd_ExecuteSingleCommand); + } + else + { + get_startup_command_queue().emplace_back(command); + } + } + + void execute_startup_command_queue() + { + const auto queue = get_startup_command_queue(); + get_startup_command_queue().clear(); + + for (const auto& command : queue) + { + game::Cbuf_ExecuteBufferInternal(0, 0, command.data(), game::Cmd_ExecuteSingleCommand); + } + } + + std::vector& get_console_command_queue() + { + static std::vector console_command_queue; + return console_command_queue; + } + + void execute_console_command(const int client, const char* command) + { + if (game::Live_SyncOnlineDataFlags(0) == 0) + { + game::Cbuf_AddText(client, command); + game::Cbuf_AddText(client, "\n"); + } + else + { + get_console_command_queue().emplace_back(command); + } + } + + void execute_console_command_queue() + { + const auto queue = get_console_command_queue(); + get_console_command_queue().clear(); + + for (const auto& command : queue) + { + game::Cbuf_AddText(0, command.data()); + game::Cbuf_AddText(0, "\n"); + } + } + + void sync_gpu_stub() + { + std::this_thread::sleep_for(1ms); + } + + game::dvar_t* gscr_set_dynamic_dvar() + { + /* + auto s = game::Scr_GetString(0); + auto* dvar = game::Dvar_FindVar(s); + + if (dvar && !strncmp("scr_", dvar->name, 4)) + { + return dvar; + } + */ + + return gscr_set_dynamic_dvar_hook.invoke(); + } + + void kill_server() + { + for (auto i = 0; i < *game::mp::svs_numclients; ++i) + { + if (game::mp::svs_clients[i].header.state >= 3) + { + game::SV_GameSendServerCommand(i, game::SV_CMD_CAN_IGNORE, + utils::string::va("r \"%s\"", "EXE_ENDOFGAME")); + } + } + + com_quit_f_hook.invoke(); + } + + void sys_error_stub(const char* msg, ...) + { + char buffer[2048]; + + va_list ap; + va_start(ap, msg); + + vsnprintf_s(buffer, sizeof(buffer), _TRUNCATE, msg, ap); + + va_end(ap); + + scheduler::once([]() + { + command::execute("map_rotate"); + }, scheduler::main, 3s); + + game::Com_Error(game::ERR_DROP, "%s", buffer); + } + } + + void initialize() + { + command::execute("exec default_xboxlive.cfg", true); + command::execute("onlinegame 1", true); + command::execute("xblive_privatematch 1", true); + } + + class component final : public component_interface + { + public: + void* load_import(const std::string& library, const std::string& function) override + { + return nullptr; + } + + void post_unpack() override + { + if (!game::environment::is_dedi()) + { + return; + } + +#ifdef DEBUG + printf("Starting dedicated server\n"); +#endif + + // Register dedicated dvar + dvars::register_bool("dedicated", true, game::DVAR_FLAG_READ); + + // Add lanonly mode + dvars::register_bool("sv_lanOnly", false, game::DVAR_FLAG_NONE); + + // Disable VirtualLobby + dvars::override::register_bool("virtualLobbyEnabled", false, game::DVAR_FLAG_READ); + + // Disable r_preloadShaders + dvars::override::register_bool("r_preloadShaders", false, game::DVAR_FLAG_READ); + + // Stop crashing from sys_errors + utils::hook::jump(0x140511520, sys_error_stub); + + // Hook R_SyncGpu + utils::hook::jump(0x1405E12F0, sync_gpu_stub); + + utils::hook::jump(0x140254800, init_dedicated_server); + + // delay startup commands until the initialization is done + utils::hook::call(0x1400D72D6, execute_startup_command); + + // delay console commands until the initialization is done + utils::hook::call(0x1400D808C, execute_console_command); + utils::hook::nop(0x1400D80A4, 5); + + // patch GScr_SetDynamicDvar to behave better + gscr_set_dynamic_dvar_hook.create(0x14036B600, &gscr_set_dynamic_dvar); + + utils::hook::nop(0x1404ED90E, 5); // don't load config file + utils::hook::nop(0x140403D92, 5); // ^ + utils::hook::set(0x1400DC1D0, 0xC3); // don't save config file + utils::hook::set(0x140274710, 0xC3); // disable self-registration + utils::hook::set(0x140515890, 0xC3); // init sound system (1) + utils::hook::set(0x1406574F0, 0xC3); // init sound system (2) + utils::hook::set(0x140620D10, 0xC3); // render thread + utils::hook::set(0x14025B850, 0xC3); // called from Com_Frame, seems to do renderer stuff + utils::hook::set(0x1402507B0, 0xC3); // CL_CheckForResend, which tries to connect to the local server constantly + utils::hook::set(0x1405D5178, 0x00); // r_loadForRenderer default to 0 + utils::hook::set(0x14050C2D0, 0xC3); // recommended settings check - TODO: Check hook + utils::hook::set(0x140514C00, 0xC3); // some mixer-related function called on shutdown + utils::hook::set(0x140409830, 0xC3); // dont load ui gametype stuff + + utils::hook::nop(0x140481B06, 6); // unknown check in SV_ExecuteClientMessage + utils::hook::nop(0x140480FAC, 4); // allow first slot to be occupied + utils::hook::nop(0x14025619B, 2); // properly shut down dedicated servers + utils::hook::nop(0x14025615E, 2); // ^ + utils::hook::nop(0x1402561C0, 5); // don't shutdown renderer + + utils::hook::set(0x140091840, 0xC3); // something to do with blendShapeVertsView + utils::hook::nop(0x140659A0D, 8); // sound thing + + // (COULD NOT FIND IN H1) + // utils::hook::set(0x1404D6960, 0xC3); // cpu detection stuff? + utils::hook::set(0x1405E97F0, 0xC3); // gfx stuff during fastfile loading + utils::hook::set(0x1405E9700, 0xC3); // ^ + utils::hook::set(0x1405E9790, 0xC3); // ^ + utils::hook::set(0x1402C1180, 0xC3); // ^ + utils::hook::set(0x1405E9750, 0xC3); // ^ + utils::hook::set(0x1405AD5B0, 0xC3); // directx stuff + utils::hook::set(0x1405DB150, 0xC3); // ^ + utils::hook::set(0x140625220, 0xC3); // ^ - mutex + utils::hook::set(0x1405DB650, 0xC3); // ^ + + utils::hook::set(0x14008B5F0, 0xC3); // rendering stuff + utils::hook::set(0x1405DB8B0, 0xC3); // ^ + utils::hook::set(0x1405DB9C0, 0xC3); // ^ + utils::hook::set(0x1405DC050, 0xC3); // ^ + utils::hook::set(0x1405DCBA0, 0xC3); // ^ + utils::hook::set(0x1405DD240, 0xC3); // ^ + + // shaders + utils::hook::set(0x1400916A0, 0xC3); // ^ + utils::hook::set(0x140091610, 0xC3); // ^ + utils::hook::set(0x14061ACC0, 0xC3); // ^ - mutex + + utils::hook::set(0x140516080, 0xC3); // idk + utils::hook::set(0x1405AE5F0, 0xC3); // ^ + + utils::hook::set(0x1405E0B30, 0xC3); // R_Shutdown + utils::hook::set(0x1405AE400, 0xC3); // shutdown stuff + utils::hook::set(0x1405E0C00, 0xC3); // ^ + utils::hook::set(0x1405DFE50, 0xC3); // ^ + + // utils::hook::set(0x1404B67E0, 0xC3); // sound crashes (H1 - questionable, function looks way different) + + utils::hook::set(0x14048B660, 0xC3); // disable host migration + + utils::hook::set(0x14042B2E0, 0xC3); // render synchronization lock + utils::hook::set(0x14042B210, 0xC3); // render synchronization unlock + + utils::hook::set(0x140176D2D, 0xEB); // LUI: Unable to start the LUI system due to errors in main.lua + + utils::hook::nop(0x140506ECE, 5); // Disable sound pak file loading + utils::hook::nop(0x140506ED6, 2); // ^ + utils::hook::set(0x1402C5910, 0xC3); // Disable image pak file loading + + // Reduce min required memory + utils::hook::set(0x14050C717, 0x80000000); + + utils::hook::set(0x1402BF7F0, 0xC3); // some loop + utils::hook::set(0x14007E150, 0xC3); // related to shader caching / techsets / fastfiles + + // initialize the game after onlinedataflags is 32 (workaround) + scheduler::schedule([=]() + { + if (game::Live_SyncOnlineDataFlags(0) == 32 && game::Sys_IsDatabaseReady2()) + { + scheduler::once([]() + { + command::execute("xstartprivateparty", true); + command::execute("disconnect", true); // 32 -> 0 + }, scheduler::pipeline::main, 1s); + return scheduler::cond_end; + } + + return scheduler::cond_continue; + }, scheduler::pipeline::main, 1s); + + scheduler::on_game_initialized([]() + { + initialize(); + + console::info("==================================\n"); + console::info("Server started!\n"); + console::info("==================================\n"); + + // remove disconnect command + game::Cmd_RemoveCommand("disconnect"); + + execute_startup_command_queue(); + execute_console_command_queue(); + + // Send heartbeat to dpmaster + scheduler::once(send_heartbeat, scheduler::pipeline::server); + scheduler::loop(send_heartbeat, scheduler::pipeline::server, 10min); + command::add("heartbeat", send_heartbeat); + }, scheduler::pipeline::main, 1s); + + command::add("killserver", kill_server); + com_quit_f_hook.create(0x1400DA640, &kill_server); + } + }; +} + +REGISTER_COMPONENT(dedicated::component) \ No newline at end of file diff --git a/src/client/component/dedicated_info.cpp b/src/client/component/dedicated_info.cpp new file mode 100644 index 00000000..55973193 --- /dev/null +++ b/src/client/component/dedicated_info.cpp @@ -0,0 +1,65 @@ +#include +#include "console.hpp" +#include "loader/component_loader.hpp" +#include "game/game.hpp" +#include "scheduler.hpp" +#include + +namespace dedicated_info +{ + class component final : public component_interface + { + public: + void post_unpack() override + { + if (!game::environment::is_dedi()) + { + return; + } + + scheduler::loop([]() + { + auto* sv_running = game::Dvar_FindVar("sv_running"); + if (!sv_running || !sv_running->current.enabled) + { + console::set_title("H1-Mod Dedicated Server"); + return; + } + + auto* const sv_hostname = game::Dvar_FindVar("sv_hostname"); + auto* const sv_maxclients = game::Dvar_FindVar("sv_maxclients"); + auto* const mapname = game::Dvar_FindVar("mapname"); + + auto bot_count = 0; + auto client_count = 0; + + for (auto i = 0; i < sv_maxclients->current.integer; i++) + { + auto* client = &game::mp::svs_clients[i]; + auto* self = &game::mp::g_entities[i]; + + if (client->header.state >= 1 && self && self->client) + { + client_count++; + if (game::SV_BotIsBot(i)) + { + ++bot_count; + } + } + } + + std::string cleaned_hostname; + cleaned_hostname.resize(static_cast(strlen(sv_hostname->current.string) + 1)); + + utils::string::strip(sv_hostname->current.string, cleaned_hostname.data(), + static_cast(strlen(sv_hostname->current.string)) + 1); + + console::set_title(utils::string::va("%s on %s [%d/%d] (%d)", cleaned_hostname.data(), + mapname->current.string, client_count, + sv_maxclients->current.integer, bot_count)); + }, scheduler::pipeline::main, 1s); + } + }; +} + +REGISTER_COMPONENT(dedicated_info::component) \ No newline at end of file diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp new file mode 100644 index 00000000..4cb3362c --- /dev/null +++ b/src/client/component/demonware.cpp @@ -0,0 +1,604 @@ +#include +#include "loader/component_loader.hpp" + +#include +#include + +#include "game/game.hpp" +#include "game/demonware/servers/lobby_server.hpp" +#include "game/demonware/servers/auth3_server.hpp" +#include "game/demonware/servers/stun_server.hpp" +#include "game/demonware/servers/umbrella_server.hpp" +#include "game/demonware/server_registry.hpp" +#include + +#define TCP_BLOCKING true +#define UDP_BLOCKING false + +namespace demonware +{ + namespace + { + volatile bool exit_server; + std::thread server_thread; + utils::concurrency::container> blocking_sockets; + utils::concurrency::container> socket_map; + server_registry tcp_servers; + server_registry udp_servers; + + tcp_server* find_server(const SOCKET socket) + { + return socket_map.access([&](const std::unordered_map& map) -> tcp_server* + { + const auto entry = map.find(socket); + if (entry == map.end()) + { + return nullptr; + } + + return entry->second; + }); + } + + bool socket_link(const SOCKET socket, const uint32_t address) + { + auto* server = tcp_servers.find(address); + if (!server) + { + return false; + } + + socket_map.access([&](std::unordered_map& map) + { + map[socket] = server; + }); + + return true; + } + + void socket_unlink(const SOCKET socket) + { + socket_map.access([&](std::unordered_map& map) + { + const auto entry = map.find(socket); + if (entry != map.end()) + { + map.erase(entry); + } + }); + } + + bool is_socket_blocking(const SOCKET socket, const bool def) + { + return blocking_sockets.access([&](std::unordered_map& map) + { + const auto entry = map.find(socket); + if (entry == map.end()) + { + return def; + } + + return entry->second; + }); + } + + void remove_blocking_socket(const SOCKET socket) + { + blocking_sockets.access([&](std::unordered_map& map) + { + const auto entry = map.find(socket); + if (entry != map.end()) + { + map.erase(entry); + } + }); + } + + void add_blocking_socket(const SOCKET socket, const bool block) + { + blocking_sockets.access([&](std::unordered_map& map) + { + map[socket] = block; + }); + } + + void server_main() + { + exit_server = false; + + while (!exit_server) + { + tcp_servers.frame(); + udp_servers.frame(); + std::this_thread::sleep_for(50ms); + } + } + + namespace io + { + int getaddrinfo_stub(const char* name, const char* service, + const addrinfo* hints, addrinfo** res) + { +#ifdef DEBUG + printf("[ network ]: [getaddrinfo]: \"%s\" \"%s\"\n", name, service); +#endif + + base_server* server = tcp_servers.find(name); + if (!server) + { + server = udp_servers.find(name); + } + + if (!server) + { + return getaddrinfo(name, service, hints, res); + } + + const auto address = utils::memory::get_allocator()->allocate(); + const auto ai = utils::memory::get_allocator()->allocate(); + + auto in_addr = reinterpret_cast(address); + in_addr->sin_addr.s_addr = server->get_address(); + in_addr->sin_family = AF_INET; + + ai->ai_family = AF_INET; + ai->ai_socktype = SOCK_STREAM; + ai->ai_addr = address; + ai->ai_addrlen = sizeof(sockaddr); + ai->ai_next = nullptr; + ai->ai_flags = 0; + ai->ai_protocol = 0; + ai->ai_canonname = const_cast(name); + + *res = ai; + + return 0; + } + + void freeaddrinfo_stub(addrinfo* ai) + { + if (!utils::memory::get_allocator()->find(ai)) + { + return freeaddrinfo(ai); + } + + utils::memory::get_allocator()->free(ai->ai_addr); + utils::memory::get_allocator()->free(ai); + } + + int getpeername_stub(const SOCKET s, sockaddr* addr, socklen_t* addrlen) + { + auto* server = find_server(s); + + if (server) + { + auto in_addr = reinterpret_cast(addr); + in_addr->sin_addr.s_addr = server->get_address(); + in_addr->sin_family = AF_INET; + *addrlen = sizeof(sockaddr); + + return 0; + } + + return getpeername(s, addr, addrlen); + } + + int getsockname_stub(const SOCKET s, sockaddr* addr, socklen_t* addrlen) + { + auto* server = find_server(s); + + if (server) + { + auto in_addr = reinterpret_cast(addr); + in_addr->sin_addr.s_addr = server->get_address(); + in_addr->sin_family = AF_INET; + *addrlen = sizeof(sockaddr); + + return 0; + } + + return getsockname(s, addr, addrlen); + } + + hostent* gethostbyname_stub(const char* name) + { +#ifdef DEBUG + printf("[ network ]: [gethostbyname]: \"%s\"\n", name); +#endif + + base_server* server = tcp_servers.find(name); + if (!server) + { + server = udp_servers.find(name); + } + + if (!server) + { +#pragma warning(push) +#pragma warning(disable: 4996) + return gethostbyname(name); +#pragma warning(pop) + } + + static thread_local in_addr address{}; + address.s_addr = server->get_address(); + + static thread_local in_addr* addr_list[2]{}; + addr_list[0] = &address; + addr_list[1] = nullptr; + + static thread_local hostent host{}; + host.h_name = const_cast(name); + host.h_aliases = nullptr; + host.h_addrtype = AF_INET; + host.h_length = sizeof(in_addr); + host.h_addr_list = reinterpret_cast(addr_list); + + return &host; + } + + int connect_stub(const SOCKET s, const struct sockaddr* addr, const int len) + { + if (len == sizeof(sockaddr_in)) + { + const auto* in_addr = reinterpret_cast(addr); + if (socket_link(s, in_addr->sin_addr.s_addr)) return 0; + } + + return connect(s, addr, len); + } + + int closesocket_stub(const SOCKET s) + { + remove_blocking_socket(s); + socket_unlink(s); + + return closesocket(s); + } + + int send_stub(const SOCKET s, const char* buf, const int len, const int flags) + { + auto* server = find_server(s); + + if (server) + { + server->handle_input(buf, len); + return len; + } + + return send(s, buf, len, flags); + } + + int recv_stub(const SOCKET s, char* buf, const int len, const int flags) + { + auto* server = find_server(s); + + if (server) + { + if (server->pending_data()) + { + return static_cast(server->handle_output(buf, len)); + } + else + { + WSASetLastError(WSAEWOULDBLOCK); + return -1; + } + } + + return recv(s, buf, len, flags); + } + + int sendto_stub(const SOCKET s, const char* buf, const int len, const int flags, const sockaddr* to, + const int tolen) + { + const auto* in_addr = reinterpret_cast(to); + auto* server = udp_servers.find(in_addr->sin_addr.s_addr); + + if (server) + { + server->handle_input(buf, len, {s, to, tolen}); + return len; + } + + return sendto(s, buf, len, flags, to, tolen); + } + + int recvfrom_stub(const SOCKET s, char* buf, const int len, const int flags, struct sockaddr* from, + int* fromlen) + { + // Not supported yet + if (is_socket_blocking(s, UDP_BLOCKING)) + { + return recvfrom(s, buf, len, flags, from, fromlen); + } + + size_t result = 0; + udp_servers.for_each([&](udp_server& server) + { + if (server.pending_data(s)) + { + result = server.handle_output( + s, buf, static_cast(len), from, fromlen); + } + }); + + if (result) + { + return static_cast(result); + } + + return recvfrom(s, buf, len, flags, from, fromlen); + } + + int select_stub(const int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, + struct timeval* timeout) + { + if (exit_server) + { + return select(nfds, readfds, writefds, exceptfds, timeout); + } + + auto result = 0; + std::vector read_sockets; + std::vector write_sockets; + + socket_map.access([&](std::unordered_map& sockets) + { + for (auto& s : sockets) + { + if (readfds) + { + if (FD_ISSET(s.first, readfds)) + { + if (s.second->pending_data()) + { + read_sockets.push_back(s.first); + FD_CLR(s.first, readfds); + } + } + } + + if (writefds) + { + if (FD_ISSET(s.first, writefds)) + { + write_sockets.push_back(s.first); + FD_CLR(s.first, writefds); + } + } + + if (exceptfds) + { + if (FD_ISSET(s.first, exceptfds)) + { + FD_CLR(s.first, exceptfds); + } + } + } + }); + + if ((!readfds || readfds->fd_count == 0) && (!writefds || writefds->fd_count == 0)) + { + timeout->tv_sec = 0; + timeout->tv_usec = 0; + } + + result = select(nfds, readfds, writefds, exceptfds, timeout); + if (result < 0) result = 0; + + for (const auto& socket : read_sockets) + { + if (readfds) + { + FD_SET(socket, readfds); + result++; + } + } + + for (const auto& socket : write_sockets) + { + if (writefds) + { + FD_SET(socket, writefds); + result++; + } + } + + return result; + } + + int ioctlsocket_stub(const SOCKET s, const long cmd, u_long* argp) + { + if (static_cast(cmd) == (FIONBIO)) + { + add_blocking_socket(s, *argp == 0); + } + + return ioctlsocket(s, cmd, argp); + } + + BOOL internet_get_connected_state_stub(LPDWORD, DWORD) + { + // Allow offline play + return TRUE; + } + } + + void bd_logger_stub(char* a1, void* a2, void* a3, void* a4, const char* function, ...) + { + + } + +#ifdef DEBUG + void a(unsigned int n) + { + printf("bdAuth: Auth task failed with HTTP code [%u]\n", n); + } + + void b(unsigned int n) + { + printf("bdAuth: Decoded client ticket of unexpected size [%u]\n", n); + } + + void c(unsigned int n) + { + printf("bdAuth: Decoded server ticket of unexpected size [%u]\n", n); + } + + void d() + { + printf("bdAuth: Auth ticket magic number mismatch\n"); + } + + void e() + { + printf("bdAuth: Cross Authentication completed\n"); + } + + void f() + { + printf("bdAuth: Auth task reply contains invalid data / format\n"); + } + + void g(unsigned int n) + { + printf("bdAuth: Auth task returned with error code [%u]\n", n); + } + + void h(unsigned int n) + { + printf("bdAuth: Invalid or No Task ID [%u] in Auth reply\n", n); + } + + void i() + { + printf("bdAuth: Received reply from DemonWare Auth server\n"); + } + + void l() + { + printf("bdAuth: Unknown error\n"); + } +#endif + } + + class component final : public component_interface + { + public: + component() + { + udp_servers.create("phoenix.stun.us.demonware.net"); + udp_servers.create("phoenix.stun.eu.demonware.net"); + udp_servers.create("phoenix.stun.jp.demonware.net"); + udp_servers.create("phoenix.stun.au.demonware.net"); + + udp_servers.create("stun.us.demonware.net"); + udp_servers.create("stun.eu.demonware.net"); + udp_servers.create("stun.jp.demonware.net"); + udp_servers.create("stun.au.demonware.net"); + + tcp_servers.create("mwr-pc-steam-auth3.prod.demonware.net"); + tcp_servers.create("mwr-pc-steam-lobby.prod.demonware.net"); + tcp_servers.create("prod.umbrella.demonware.net"); + } + + void post_load() override + { + server_thread = utils::thread::create_named_thread("Demonware", server_main); + } + + void* load_import(const std::string& library, const std::string& function) override + { + if (library == "WS2_32.dll") + { + if (function == "#3") return io::closesocket_stub; + if (function == "#4") return io::connect_stub; + if (function == "#5") return io::getpeername_stub; + if (function == "#6") return io::getsockname_stub; + if (function == "#10") return io::ioctlsocket_stub; + if (function == "#16") return io::recv_stub; + if (function == "#17") return io::recvfrom_stub; + if (function == "#18") return io::select_stub; + if (function == "#19") return io::send_stub; + if (function == "#20") return io::sendto_stub; + if (function == "#52") return io::gethostbyname_stub; + if (function == "getaddrinfo") return io::getaddrinfo_stub; + if (function == "freeaddrinfo") return io::freeaddrinfo_stub; + } + + if (function == "InternetGetConnectedState") + { + return io::internet_get_connected_state_stub; + } + + return nullptr; + } + + void post_unpack() override + { + /* + mwr has upgraded some networking methods and the gethostbyname import from winsock library is no longer used + gethostbyname has been replaced with getaddrinfo + btw, still you can't get online.. + */ + utils::hook::jump(SELECT_VALUE(0x140610320, 0x1407400B0), bd_logger_stub); // H1MP64(1.4) + + if (game::environment::is_sp()) + { + utils::hook::set(0x1405FCA00, 0xC3); // bdAuthSteam H1(1.4) + utils::hook::set(0x140333A00, 0xC3); // dwNet H1(1.4) + return; + } + + utils::hook::set(0x140715039, 0x0); // CURLOPT_SSL_VERIFYPEER H1MP64(1.4) + utils::hook::set(0x140715025, 0xAF); // CURLOPT_SSL_VERIFYHOST H1MP64(1.4) + utils::hook::set(0x14095433C, 0x0); // HTTPS -> HTTP [MWR OK][S1X: 0x14088D0E8] + + //HTTPS -> HTTP + utils::hook::inject(0x14006DDA9, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x14003852E] + utils::hook::inject(0x14006E11C, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x14003884F] + utils::hook::inject(0x14006E2FB, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x140038A07] + utils::hook::inject(0x14006E9A9, "http://prod.uno.demonware.net/v1.0/"); + utils::hook::inject(0x14006ED49, "http://prod.uno.demonware.net/v1.0/"); + utils::hook::inject(0x140728170, "http://%s:%d/auth/"); + + utils::hook::set(0x14047F290, 0xC3); // SV_SendMatchData H1MP64(1.4) + utils::hook::set(0x140598990, 0xC3); // Live_CheckForFullDisconnect H1MP64(1.4) + +#ifdef DEBUG + // yes + utils::hook::call(0x140727BEB, l); + utils::hook::call(0x140727AFC, i); + utils::hook::call(0x140727E49, h); + utils::hook::call(0x140727E30, g); + utils::hook::call(0x140727E37, f); + utils::hook::call(0x140727DF2, e); + utils::hook::call(0x140727DF9, d); + utils::hook::call(0x140727CFC, c); + utils::hook::call(0x140727C82, b); + utils::hook::call(0x140727E6A, a); +#endif + // Checks X-Signature header or something + utils::hook::set(0x140728380, 0xC301B0); + // Checks extended_data and extra_data in json object + utils::hook::set(0x140728E90, 0xC301B0); + // Update check + utils::hook::set(0x1403A5390, 0xC301B0); + + // Remove some while loop in demonware that freezes the rendering for a few secs at launch + utils::hook::nop(0x14057DBC5, 5); + } + + void pre_destroy() override + { + exit_server = true; + if (server_thread.joinable()) + { + server_thread.join(); + } + } + }; +} + +REGISTER_COMPONENT(demonware::component) diff --git a/src/client/component/demonware.hpp b/src/client/component/demonware.hpp new file mode 100644 index 00000000..d26d1ccd --- /dev/null +++ b/src/client/component/demonware.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace demonware +{ + +} \ No newline at end of file diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp new file mode 100644 index 00000000..5925a64a --- /dev/null +++ b/src/client/component/discord.cpp @@ -0,0 +1,148 @@ +#include +#include "loader/component_loader.hpp" +#include "scheduler.hpp" +#include "game/game.hpp" + +#include "console.hpp" +#include "command.hpp" +#include "network.hpp" +#include "party.hpp" + +#include + +#include + +namespace discord +{ + namespace + { + DiscordRichPresence discord_presence; + + void update_discord() + { + Discord_RunCallbacks(); + + if (!game::CL_IsCgameInitialized() || game::VirtualLobby_Loaded()) + { + discord_presence.details = game::environment::is_sp() ? "Singleplayer" : "Multiplayer"; + discord_presence.state = "Main Menu"; + + auto firingRangeDvar = game::Dvar_FindVar("virtualLobbyInFiringRange"); + if (firingRangeDvar && firingRangeDvar->current.enabled == 1) + { + discord_presence.state = "Firing Range"; + } + + discord_presence.partySize = 0; + discord_presence.partyMax = 0; + discord_presence.startTimestamp = 0; + discord_presence.largeImageKey = game::environment::is_sp() ? "menu_singleplayer" : "menu_multiplayer"; + } + else + { + const auto map = game::Dvar_FindVar("mapname")->current.string; + const auto mapname = game::UI_SafeTranslateString(utils::string::va("PRESENCE_%s%s", (game::environment::is_sp() ? "SP_" : ""), map)); + + if (game::environment::is_mp()) + { + const auto gametype = game::UI_GetGameTypeDisplayName(game::Dvar_FindVar("g_gametype")->current.string); + + discord_presence.details = utils::string::va("%s on %s", gametype, mapname); + + char clean_hostname[0x100] = {0}; + utils::string::strip(game::Dvar_FindVar("sv_hostname")->current.string, + clean_hostname, sizeof(clean_hostname)); + auto max_clients = party::server_client_count(); + + // When true, we are in Private Match + if (game::SV_Loaded()) + { + strcpy_s(clean_hostname, "Private Match"); + max_clients = game::Dvar_FindVar("sv_maxclients")->current.integer; + } + + discord_presence.partySize = *reinterpret_cast(0x1429864C4); + discord_presence.partyMax = max_clients; + discord_presence.state = clean_hostname; + discord_presence.largeImageKey = map; + } + else if (game::environment::is_sp()) + { + discord_presence.state = ""; + discord_presence.largeImageKey = map; + discord_presence.details = mapname; + } + + if (!discord_presence.startTimestamp) + { + discord_presence.startTimestamp = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + } + } + + Discord_UpdatePresence(&discord_presence); + } + } + + class component final : public component_interface + { + public: + void post_load() override + { + if (game::environment::is_dedi()) + { + return; + } + + DiscordEventHandlers handlers; + ZeroMemory(&handlers, sizeof(handlers)); + handlers.ready = ready; + handlers.errored = errored; + handlers.disconnected = errored; + handlers.joinGame = nullptr; + handlers.spectateGame = nullptr; + handlers.joinRequest = nullptr; + + Discord_Initialize("947125042930667530", &handlers, 1, nullptr); + + scheduler::once([]() + { + scheduler::once(update_discord, scheduler::pipeline::async); + scheduler::loop(update_discord, scheduler::pipeline::async, 5s); + }, scheduler::pipeline::main); + + initialized_ = true; + } + + void pre_destroy() override + { + if (!initialized_ || game::environment::is_dedi()) + { + return; + } + + Discord_Shutdown(); + } + + private: + bool initialized_ = false; + + static void ready(const DiscordUser* /*request*/) + { + ZeroMemory(&discord_presence, sizeof(discord_presence)); + + discord_presence.instance = 1; + + console::info("Discord: Ready\n"); + + Discord_UpdatePresence(&discord_presence); + } + + static void errored(const int error_code, const char* message) + { + console::error("Discord: Error (%i): %s\n", error_code, message); + } + }; +} + +REGISTER_COMPONENT(discord::component) \ No newline at end of file diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp new file mode 100644 index 00000000..d9c77fdf --- /dev/null +++ b/src/client/component/dvars.cpp @@ -0,0 +1,443 @@ +#include +#include "loader/component_loader.hpp" +#include "dvars.hpp" + +#include "game/game.hpp" + +#include + +namespace dvars +{ + struct dvar_base + { + unsigned int flags{}; + }; + + struct dvar_bool : dvar_base + { + bool value{}; + }; + + struct dvar_float : dvar_base + { + float value{}; + float min{}; + float max{}; + }; + + struct dvar_vector2 : dvar_base + { + float x{}; + float y{}; + float min{}; + float max{}; + }; + + struct dvar_vector3 : dvar_base + { + + float x{}; + float y{}; + float z{}; + float min{}; + float max{}; + }; + + struct dvar_int : dvar_base + { + int value{}; + int min{}; + int max{}; + }; + + struct dvar_string : dvar_base + { + std::string value{}; + }; + + namespace + { + template + T* find_dvar(std::unordered_map& map, const std::string& name) + { + auto i = map.find(name); + if (i != map.end()) + { + return &i->second; + } + + return nullptr; + } + + template + T* find_dvar(std::unordered_map& map, const int hash) + { + for (auto i = map.begin(); i != map.end(); ++i) + { + if (game::generateHashValue(i->first.data()) == hash) + { + return &i->second; + } + } + + return nullptr; + } + + bool find_dvar(std::unordered_set& set, const std::string& name) + { + return set.find(name) != set.end(); + } + + + bool find_dvar(std::unordered_set& set, const int hash) + { + for (auto i = set.begin(); i != set.end(); ++i) + { + if (game::generateHashValue(i->data()) == hash) + { + return true; + } + } + + return false; + } + } + + namespace disable + { + static std::unordered_set set_bool_disables; + static std::unordered_set set_float_disables; + static std::unordered_set set_int_disables; + static std::unordered_set set_string_disables; + + void set_bool(const std::string& name) + { + set_bool_disables.emplace(name); + } + + void set_float(const std::string& name) + { + set_float_disables.emplace(name); + } + + void set_int(const std::string& name) + { + set_int_disables.emplace(name); + } + + void set_string(const std::string& name) + { + set_string_disables.emplace(name); + } + } + + namespace override + { + static std::unordered_map register_bool_overrides; + static std::unordered_map register_float_overrides; + static std::unordered_map register_int_overrides; + static std::unordered_map register_string_overrides; + static std::unordered_map register_vector2_overrides; + static std::unordered_map register_vector3_overrides; + + static std::unordered_map set_bool_overrides; + static std::unordered_map set_float_overrides; + static std::unordered_map set_int_overrides; + static std::unordered_map set_string_overrides; + static std::unordered_map set_from_string_overrides; + + void register_bool(const std::string& name, const bool value, const unsigned int flags) + { + dvar_bool values; + values.value = value; + values.flags = flags; + register_bool_overrides[name] = std::move(values); + } + + void register_float(const std::string& name, const float value, const float min, const float max, + const unsigned int flags) + { + dvar_float values; + values.value = value; + values.min = min; + values.max = max; + values.flags = flags; + register_float_overrides[name] = std::move(values); + } + + void register_int(const std::string& name, const int value, const int min, const int max, + const unsigned int flags) + { + dvar_int values; + values.value = value; + values.min = min; + values.max = max; + values.flags = flags; + register_int_overrides[name] = std::move(values); + } + + void register_string(const std::string& name, const std::string& value, + const unsigned int flags) + { + dvar_string values; + values.value = value; + values.flags = flags; + register_string_overrides[name] = std::move(values); + } + + void register_vec2(const std::string& name, float x, float y, float min, float max, + const unsigned int flags) + { + dvar_vector2 values; + values.x = x; + values.y = y; + values.min = min; + values.max = max; + values.flags = flags; + register_vector2_overrides[name] = std::move(values); + } + + void register_vec3(const std::string& name, float x, float y, float z, float min, + float max, const unsigned int flags) + { + dvar_vector3 values; + values.x = x; + values.y = y; + values.z = z; + values.min = min; + values.max = max; + values.flags = flags; + register_vector3_overrides[name] = std::move(values); + } + + void set_bool(const std::string& name, const bool value) + { + set_bool_overrides[name] = value; + } + + void set_float(const std::string& name, const float value) + { + set_float_overrides[name] = value; + } + + void set_int(const std::string& name, const int value) + { + set_int_overrides[name] = value; + } + + void set_string(const std::string& name, const std::string& value) + { + set_string_overrides[name] = value; + } + + void set_from_string(const std::string& name, const std::string& value) + { + set_from_string_overrides[name] = value; + } + } + + utils::hook::detour dvar_register_bool_hook; + utils::hook::detour dvar_register_float_hook; + utils::hook::detour dvar_register_int_hook; + utils::hook::detour dvar_register_string_hook; + utils::hook::detour dvar_register_vector2_hook; + utils::hook::detour dvar_register_vector3_hook; + + utils::hook::detour dvar_set_bool_hook; + utils::hook::detour dvar_set_float_hook; + utils::hook::detour dvar_set_int_hook; + utils::hook::detour dvar_set_string_hook; + utils::hook::detour dvar_set_from_string_hook; + + game::dvar_t* dvar_register_bool(const int hash, const char* name, bool value, unsigned int flags) + { + auto* var = find_dvar(override::register_bool_overrides, hash); + if (var) + { + value = var->value; + flags = var->flags; + } + + return dvar_register_bool_hook.invoke(hash, name, value, flags); + } + + game::dvar_t* dvar_register_float(const int hash, const char* name, float value, float min, float max, unsigned int flags) + { + auto* var = find_dvar(override::register_float_overrides, hash); + if (var) + { + value = var->value; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_float_hook.invoke(hash, name, value, min, max, flags); + } + + game::dvar_t* dvar_register_int(const int hash, const char* name, int value, int min, int max, unsigned int flags) + { + auto* var = find_dvar(override::register_int_overrides, hash); + if (var) + { + value = var->value; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_int_hook.invoke(hash, name, value, min, max, flags); + } + + game::dvar_t* dvar_register_string(const int hash, const char* name, const char* value, unsigned int flags) + { + auto* var = find_dvar(override::register_string_overrides, hash); + if (var) + { + value = var->value.data(); + flags = var->flags; + } + + return dvar_register_string_hook.invoke(hash, name, value, flags); + } + + game::dvar_t* dvar_register_vector2(const int hash, const char* name, float x, float y, float min, float max, + unsigned int flags) + { + auto* var = find_dvar(override::register_vector2_overrides, hash); + if (var) + { + x = var->x; + y = var->y; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_vector2_hook.invoke(hash, name, x, y, min, max, flags); + } + + game::dvar_t* dvar_register_vector3(const int hash, const char* name, float x, float y, float z, float min, + float max, unsigned int flags) + { + auto* var = find_dvar(override::register_vector3_overrides, hash); + if (var) + { + x = var->x; + y = var->y; + z = var->z; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_vector3_hook.invoke(hash, name, x, y, z, min, max, flags); + } + + void dvar_set_bool(game::dvar_t* dvar, bool boolean) + { + const auto disabled = find_dvar(disable::set_bool_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_bool_overrides, dvar->hash); + if (var) + { + boolean = *var; + } + + return dvar_set_bool_hook.invoke(dvar, boolean); + } + + void dvar_set_float(game::dvar_t* dvar, float fl) + { + const auto disabled = find_dvar(disable::set_float_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_float_overrides, dvar->hash); + if (var) + { + fl = *var; + } + + return dvar_set_float_hook.invoke(dvar, fl); + } + + void dvar_set_int(game::dvar_t* dvar, int integer) + { + const auto disabled = find_dvar(disable::set_int_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_int_overrides, dvar->hash); + if (var) + { + integer = *var; + } + + return dvar_set_int_hook.invoke(dvar, integer); + } + + void dvar_set_string(game::dvar_t* dvar, const char* string) + { + const auto disabled = find_dvar(disable::set_string_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_string_overrides, dvar->hash); + if (var) + { + string = var->data(); + } + + return dvar_set_string_hook.invoke(dvar, string); + } + + void dvar_set_from_string(game::dvar_t* dvar, const char* string, game::DvarSetSource source) + { + const auto disabled = find_dvar(disable::set_string_disables, dvar->hash); + if (disabled) + { + return; + } + + auto* var = find_dvar(override::set_from_string_overrides, dvar->hash); + if (var) + { + string = var->data(); + } + + return dvar_set_from_string_hook.invoke(dvar, string, source); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + dvar_register_bool_hook.create(SELECT_VALUE(0x1403C47E0, 0x1404FA540), &dvar_register_bool); + dvar_register_float_hook.create(SELECT_VALUE(0x1403C4BB0, 0x1404FA910), &dvar_register_float); + dvar_register_int_hook.create(SELECT_VALUE(0x1403C4CC0, 0x1404FAA20), &dvar_register_int); + dvar_register_string_hook.create(SELECT_VALUE(0x1403C4DA0, 0x1404FAB00), &dvar_register_string); + dvar_register_vector2_hook.create(SELECT_VALUE(0x1403C4E80, 0x1404FABE0), &dvar_register_vector2); + dvar_register_vector3_hook.create(SELECT_VALUE(0x1403C4FC0, 0x1404FACE0), &dvar_register_vector3); + + dvar_set_bool_hook.create(SELECT_VALUE(0x1403C7020, 0x1404FCDF0), &dvar_set_bool); + dvar_set_float_hook.create(SELECT_VALUE(0x1403C7420, 0x1404FD360), &dvar_set_float); + dvar_set_int_hook.create(SELECT_VALUE(0x1403C76C0, 0x1404FD5E0), &dvar_set_int); + dvar_set_string_hook.create(SELECT_VALUE(0x1403C7900, 0x1404FD8D0), &dvar_set_string); + dvar_set_from_string_hook.create(SELECT_VALUE(0x1403C7620, 0x1404FD520), &dvar_set_from_string); + } + }; +} + +REGISTER_COMPONENT(dvars::component) diff --git a/src/client/component/dvars.hpp b/src/client/component/dvars.hpp new file mode 100644 index 00000000..66d6912d --- /dev/null +++ b/src/client/component/dvars.hpp @@ -0,0 +1,28 @@ +#pragma once + +namespace dvars +{ + namespace disable + { + void set_bool(const std::string& name); + void set_float(const std::string& name); + void set_int(const std::string& name); + void set_string(const std::string& name); + } + + namespace override + { + void register_bool(const std::string& name, bool value, const unsigned int flags); + void register_float(const std::string& name, float value, float min, float max, const unsigned int flags); + void register_int(const std::string& name, int value, int min, int max, const unsigned int flags); + void register_string(const std::string& name, const std::string& value, const unsigned int flags); + void register_vec2(const std::string& name, float x, float y, float min, float max, const unsigned int flags); + void register_vec3(const std::string& name, float x, float y, float z, float min, float max, const unsigned int flags); + + void set_bool(const std::string& name, bool boolean); + void set_float(const std::string& name, float fl); + void set_int(const std::string& name, int integer); + void set_string(const std::string& name, const std::string& string); + void set_from_string(const std::string& name, const std::string& value); + } +} diff --git a/src/client/component/exception.cpp b/src/client/component/exception.cpp new file mode 100644 index 00000000..028bb238 --- /dev/null +++ b/src/client/component/exception.cpp @@ -0,0 +1,261 @@ +#include +#include "loader/component_loader.hpp" +#include "system_check.hpp" +#include "scheduler.hpp" + +#include "game/game.hpp" + +#include +#include +#include +#include +#include + +#include + +#include + +#include "game/dvars.hpp" + +namespace exception +{ + namespace + { + thread_local struct + { + DWORD code = 0; + PVOID address = nullptr; + } exception_data; + + struct + { + std::chrono::time_point last_recovery{}; + std::atomic recovery_counts = {0}; + } recovery_data; + + bool is_game_thread() + { + static std::vector allowed_threads = + { + game::THREAD_CONTEXT_MAIN, + }; + + const auto self_id = GetCurrentThreadId(); + for (const auto& index : allowed_threads) + { + if (game::threadIds[index] == self_id) + { + return true; + } + } + + return false; + } + + bool is_exception_interval_too_short() + { + const auto delta = std::chrono::high_resolution_clock::now() - recovery_data.last_recovery; + return delta < 1min; + } + + bool too_many_exceptions_occured() + { + return recovery_data.recovery_counts >= 3; + } + + volatile bool& is_initialized() + { + static volatile bool initialized = false; + return initialized; + } + + bool is_recoverable() + { + return is_initialized() + && is_game_thread() + && !is_exception_interval_too_short() + && !too_many_exceptions_occured(); + } + + void show_mouse_cursor() + { + while (ShowCursor(TRUE) < 0); + } + + void display_error_dialog() + { + std::string error_str = utils::string::va("Fatal error (0x%08X) at 0x%p.\n" + "A minidump has been written.\n\n", + exception_data.code, exception_data.address); + + if (!system_check::is_valid()) + { + error_str += "Make sure to get supported game files to avoid such crashes!"; + } + else + { + error_str += "Make sure to update your graphics card drivers and install operating system updates!"; + } + + utils::thread::suspend_other_threads(); + show_mouse_cursor(); + + MessageBoxA(nullptr, error_str.data(), "H1-Mod ERROR", MB_ICONERROR); + TerminateProcess(GetCurrentProcess(), exception_data.code); + } + + void reset_state() + { + if (dvars::cg_legacyCrashHandling && dvars::cg_legacyCrashHandling->current.enabled) + { + display_error_dialog(); + } + + // TODO: Add a limit for dedi restarts + if (game::environment::is_dedi()) + { + utils::nt::relaunch_self(); + utils::nt::terminate(exception_data.code); + } + + if (is_recoverable()) + { + recovery_data.last_recovery = std::chrono::high_resolution_clock::now(); + ++recovery_data.recovery_counts; + + game::Com_Error(game::ERR_DROP, "Fatal error (0x%08X) at 0x%p.\nA minidump has been written.\n\n" + "H1-Mod has tried to recover your game, but it might not run stable anymore.\n\n" + "Make sure to update your graphics card drivers and install operating system updates!\n" + "Closing or restarting Steam might also help.", + exception_data.code, exception_data.address); + } + else + { + display_error_dialog(); + } + } + + size_t get_reset_state_stub() + { + static auto* stub = utils::hook::assemble([](utils::hook::assembler& a) + { + a.sub(rsp, 0x10); + a.or_(rsp, 0x8); + a.jmp(reset_state); + }); + + return reinterpret_cast(stub); + } + + std::string get_timestamp() + { + tm ltime{}; + char timestamp[MAX_PATH] = {0}; + const auto time = _time64(nullptr); + + _localtime64_s(<ime, &time); + strftime(timestamp, sizeof(timestamp) - 1, "%Y-%m-%d-%H-%M-%S", <ime); + + return timestamp; + } + + std::string generate_crash_info(const LPEXCEPTION_POINTERS exceptioninfo) + { + std::string info{}; + const auto line = [&info](const std::string& text) + { + info.append(text); + info.append("\r\n"); + }; + + line("H1-Mod Crash Dump"); + line(""); + line("Version: "s + VERSION); + line("Environment: "s + game::environment::get_string()); + line("Timestamp: "s + get_timestamp()); + line("Clean game: "s + (system_check::is_valid() ? "Yes" : "No")); + line(utils::string::va("Exception: 0x%08X", exceptioninfo->ExceptionRecord->ExceptionCode)); + line(utils::string::va("Address: 0x%llX", exceptioninfo->ExceptionRecord->ExceptionAddress)); + +#pragma warning(push) +#pragma warning(disable: 4996) + OSVERSIONINFOEXA version_info; + ZeroMemory(&version_info, sizeof(version_info)); + version_info.dwOSVersionInfoSize = sizeof(version_info); + GetVersionExA(reinterpret_cast(&version_info)); +#pragma warning(pop) + + line(utils::string::va("OS Version: %u.%u", version_info.dwMajorVersion, version_info.dwMinorVersion)); + + return info; + } + + void write_minidump(const LPEXCEPTION_POINTERS exceptioninfo) + { + const std::string crash_name = utils::string::va("minidumps/h1-mod-crash-%d-%s.zip", + game::environment::get_real_mode(), + get_timestamp().data()); + + utils::compression::zip::archive zip_file{}; + zip_file.add("crash.dmp", create_minidump(exceptioninfo)); + zip_file.add("info.txt", generate_crash_info(exceptioninfo)); + zip_file.write(crash_name, "H1-Mod Crash Dump"); + } + + bool is_harmless_error(const LPEXCEPTION_POINTERS exceptioninfo) + { + const auto code = exceptioninfo->ExceptionRecord->ExceptionCode; + return code == STATUS_INTEGER_OVERFLOW || code == STATUS_FLOAT_OVERFLOW || code == STATUS_SINGLE_STEP; + } + + LONG WINAPI exception_filter(const LPEXCEPTION_POINTERS exceptioninfo) + { + if (is_harmless_error(exceptioninfo)) + { + return EXCEPTION_CONTINUE_EXECUTION; + } + + write_minidump(exceptioninfo); + + exception_data.code = exceptioninfo->ExceptionRecord->ExceptionCode; + exception_data.address = exceptioninfo->ExceptionRecord->ExceptionAddress; + exceptioninfo->ContextRecord->Rip = get_reset_state_stub(); + + return EXCEPTION_CONTINUE_EXECUTION; + } + + LPTOP_LEVEL_EXCEPTION_FILTER WINAPI set_unhandled_exception_filter_stub(LPTOP_LEVEL_EXCEPTION_FILTER) + { + // Don't register anything here... + return &exception_filter; + } + } + + class component final : public component_interface + { + public: + component() + { + SetUnhandledExceptionFilter(exception_filter); + } + + void post_load() override + { + SetUnhandledExceptionFilter(exception_filter); + utils::hook::jump(SetUnhandledExceptionFilter, set_unhandled_exception_filter_stub, true); + + scheduler::on_game_initialized([]() + { + is_initialized() = true; + }); + } + + void post_unpack() override + { + dvars::cg_legacyCrashHandling = dvars::register_bool("cg_legacyCrashHandling", + false, game::DVAR_FLAG_SAVED, true); + } + }; +} + +REGISTER_COMPONENT(exception::component) diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp new file mode 100644 index 00000000..d4eda37f --- /dev/null +++ b/src/client/component/fastfiles.cpp @@ -0,0 +1,49 @@ +#include +#include "loader/component_loader.hpp" +#include "fastfiles.hpp" + +#include "command.hpp" +#include "console.hpp" + +#include +#include + +namespace fastfiles +{ + static utils::concurrency::container current_fastfile; + + namespace + { + utils::hook::detour db_try_load_x_file_internal_hook; + + void db_try_load_x_file_internal(const char* zone_name, const int flags) + { + printf("Loading fastfile %s\n", zone_name); + current_fastfile.access([&](std::string& fastfile) + { + fastfile = zone_name; + }); + db_try_load_x_file_internal_hook.invoke(zone_name, flags); + } + } + + std::string get_current_fastfile() + { + return current_fastfile.access([&](std::string& fastfile) + { + return fastfile; + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + db_try_load_x_file_internal_hook.create( + SELECT_VALUE(0x1401CDDD0, 0x1402BFFE0), &db_try_load_x_file_internal); + } + }; +} + +REGISTER_COMPONENT(fastfiles::component) diff --git a/src/client/component/fastfiles.hpp b/src/client/component/fastfiles.hpp new file mode 100644 index 00000000..ac26d2ec --- /dev/null +++ b/src/client/component/fastfiles.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "game/game.hpp" + +namespace fastfiles +{ + std::string get_current_fastfile(); +} diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp new file mode 100644 index 00000000..da11d2e4 --- /dev/null +++ b/src/client/component/filesystem.cpp @@ -0,0 +1,94 @@ +#include +#include "loader/component_loader.hpp" +#include "filesystem.hpp" +#include "game_module.hpp" + +#include "game/game.hpp" +#include "dvars.hpp" + +#include +#include + +namespace filesystem +{ + namespace + { + bool custom_path_registered = false; + + std::string get_binary_directory() + { + const auto dir = game_module::get_host_module().get_folder(); + return utils::string::replace(dir, "/", "\\"); + } + + void register_custom_path_stub(const char* path, const char* dir) + { + if (!custom_path_registered) + { + custom_path_registered = true; + + const auto launcher_dir = get_binary_directory(); + game::FS_AddLocalizedGameDirectory(launcher_dir.data(), "data"); + } + + game::FS_AddLocalizedGameDirectory(path, dir); + } + + void fs_startup_stub(const char* gamename) + { + custom_path_registered = false; + game::FS_Startup(gamename); + } + } + + file::file(std::string name) + : name_(std::move(name)) + { + char* buffer{}; + const auto size = game::FS_ReadFile(this->name_.data(), &buffer); + + if (size >= 0 && buffer) + { + this->valid_ = true; + this->buffer_.append(buffer, size); + game::FS_FreeFile(buffer); + } + } + + bool file::exists() const + { + return this->valid_; + } + + const std::string& file::get_buffer() const + { + return this->buffer_; + } + + const std::string& file::get_name() const + { + return this->name_; + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + // Set fs_basegame + dvars::override::register_string("fs_basegame", "h1-mod", game::DVAR_FLAG_WRITE); + + utils::hook::call(SELECT_VALUE(0x1403B76E2, 0x1404ED3E2), fs_startup_stub); + if (game::environment::is_mp()) + { + utils::hook::call(0x1404ED823, fs_startup_stub); + } + + utils::hook::call(SELECT_VALUE(0x1403B8D31, 0x1404EE3D0), register_custom_path_stub); + utils::hook::call(SELECT_VALUE(0x1403B8D51, 0x1404EE3F0), register_custom_path_stub); + utils::hook::call(SELECT_VALUE(0x1403B8D90, 0x1404EE42F), register_custom_path_stub); + } + }; +} + +REGISTER_COMPONENT(filesystem::component) \ No newline at end of file diff --git a/src/client/component/filesystem.hpp b/src/client/component/filesystem.hpp new file mode 100644 index 00000000..6cec8c87 --- /dev/null +++ b/src/client/component/filesystem.hpp @@ -0,0 +1,19 @@ +#pragma once + +namespace filesystem +{ + class file + { + public: + file(std::string name); + + bool exists() const; + const std::string& get_buffer() const; + const std::string& get_name() const; + + private: + bool valid_ = false; + std::string name_; + std::string buffer_; + }; +} \ No newline at end of file diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp new file mode 100644 index 00000000..db471119 --- /dev/null +++ b/src/client/component/fps.cpp @@ -0,0 +1,174 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include + +namespace fps +{ + namespace + { + game::dvar_t* cg_drawfps; + game::dvar_t* cg_drawping; + + float fps_color_good[4] = {0.6f, 1.0f, 0.0f, 1.0f}; + float fps_color_ok[4] = {1.0f, 0.7f, 0.3f, 1.0f}; + float fps_color_bad[4] = {1.0f, 0.3f, 0.3f, 1.0f}; + float ping_color[4] = {1.0f, 1.0f, 1.0f, 0.65f}; + + struct cg_perf_data + { + std::chrono::time_point perf_start; + std::int32_t current_ms{}; + std::int32_t previous_ms{}; + std::int32_t frame_ms{}; + std::int32_t history[32]{}; + std::int32_t count{}; + std::int32_t index{}; + std::int32_t instant{}; + std::int32_t total{}; + float average{}; + float variance{}; + std::int32_t min{}; + std::int32_t max{}; + }; + + cg_perf_data cg_perf{}; + + void perf_calc_fps(cg_perf_data* data, const std::int32_t value) + { + data->history[data->index % 32] = value; + data->instant = value; + data->min = 0x7FFFFFFF; + data->max = 0; + data->average = 0.0f; + data->variance = 0.0f; + data->total = 0; + + for (auto i = 0; i < data->count; ++i) + { + const std::int32_t idx = (data->index - i) % 32; + + if (idx < 0) + { + break; + } + + data->total += data->history[idx]; + + if (data->min > data->history[idx]) + { + data->min = data->history[idx]; + } + + if (data->max < data->history[idx]) + { + data->max = data->history[idx]; + } + } + + data->average = static_cast(data->total) / static_cast(data->count); + ++data->index; + } + + void perf_update() + { + cg_perf.count = 32; + + cg_perf.current_ms = static_cast(std::chrono::duration_cast( + std::chrono::high_resolution_clock::now() - cg_perf.perf_start).count()); + cg_perf.frame_ms = cg_perf.current_ms - cg_perf.previous_ms; + cg_perf.previous_ms = cg_perf.current_ms; + + perf_calc_fps(&cg_perf, cg_perf.frame_ms); + + utils::hook::invoke(SELECT_VALUE(0x1405487A0, 0x1406575A0)); // H1(1.4) + } + + void cg_draw_fps() + { + if (cg_drawfps->current.integer > 0) + { + const auto fps = static_cast(static_cast(1000.0f / static_cast(cg_perf. + average)) + + 9.313225746154785e-10); + + const auto font = game::R_RegisterFont("fonts/fira_mono_regular.ttf", 25); + const auto fps_string = utils::string::va("%i", fps); + + const auto x = (game::ScrPlace_GetViewPlacement()->realViewportSize[0] - 15.0f) - game::R_TextWidth( + fps_string, 0x7FFFFFFF, font); + const auto y = font->pixelHeight + 10.f; + + const auto fps_color = fps >= 60 ? fps_color_good : (fps >= 30 ? fps_color_ok : fps_color_bad); + game::R_AddCmdDrawText(fps_string, 0x7FFFFFFF, font, x, y, 1.f, 1.f, 0.0f, fps_color, 6); + } + } + + void cg_draw_ping() + { + if (cg_drawping->current.integer > 0 && game::CL_IsCgameInitialized() && !game::VirtualLobby_Loaded()) + { + const auto ping = *reinterpret_cast(0x142D106F0); + + const auto font = game::R_RegisterFont("fonts/consolefont", 20); + const auto ping_string = utils::string::va("Ping: %i", ping); + + const auto x = (game::ScrPlace_GetViewPlacement()->realViewportSize[0] - 375.0f) - game::R_TextWidth( + ping_string, 0x7FFFFFFF, font); + + const auto y = font->pixelHeight + 15.f; + game::R_AddCmdDrawText(ping_string, 0x7FFFFFFF, font, x, y, 1.f, 1.f, 0.0f, ping_color, 6); + } + } + + game::dvar_t* cg_draw_fps_register_stub(const char* name, const char** _enum, const int value, unsigned int /*flags*/, + const char* desc) + { + cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, false); + return cg_drawfps; + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_dedi()) + { + return; + } + + // fps setup + cg_perf.perf_start = std::chrono::high_resolution_clock::now(); + utils::hook::call(SELECT_VALUE(0x14018D261, 0x14025B747), &perf_update); + + // change cg_drawfps flags to saved + utils::hook::call(SELECT_VALUE(0x140139F48, 0x140222A46), &cg_draw_fps_register_stub); + + scheduler::loop(cg_draw_fps, scheduler::pipeline::renderer); + + if (game::environment::is_sp()) + { + cg_drawfps = dvars::register_int("cg_drawFps", 0, 0, 2, game::DVAR_FLAG_SAVED, false); + } + + if (game::environment::is_mp()) + { + // fix ping value + utils::hook::nop(0x14025AC41, 2); + + cg_drawping = dvars::register_int("cg_drawPing", 0, 0, 1, game::DVAR_FLAG_SAVED, true); + + scheduler::loop(cg_draw_ping, scheduler::pipeline::renderer); + } + } + }; +} + +REGISTER_COMPONENT(fps::component) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp new file mode 100644 index 00000000..cf7c3056 --- /dev/null +++ b/src/client/component/game_console.cpp @@ -0,0 +1,793 @@ +#include +#include "loader/component_loader.hpp" +#include "game_console.hpp" +#include "command.hpp" +#include "console.hpp" +#include "scheduler.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include + +#include "version.hpp" + +#define console_font game::R_RegisterFont("fonts/fira_mono_regular.ttf", 18) +#define material_white game::Material_RegisterHandle("white") + +namespace game_console +{ + namespace + { + struct console_globals + { + float x{}; + float y{}; + float left_x{}; + float font_height{}; + bool may_auto_complete{}; + char auto_complete_choice[64]{}; + int info_line_count{}; + }; + + using output_queue = std::deque; + + struct ingame_console + { + char buffer[256]{}; + int cursor{}; + int font_height{}; + int visible_line_count{}; + int visible_pixel_width{}; + float screen_min[2]{}; //left & top + float screen_max[2]{}; //right & bottom + console_globals globals{}; + bool output_visible{}; + int display_line_offset{}; + int 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{}; + + float color_white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + float color_title[4] = {0.25f, 0.62f, 0.3f, 1.0f}; + + void clear() + { + strncpy_s(con.buffer, "", sizeof(con.buffer)); + con.cursor = 0; + + fixed_input = ""; + matches.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(); + + con.output_visible = false; + *game::keyCatchers ^= 1; + } + + void toggle_console_output() + { + con.output_visible = con.output_visible == 0; + } + + void check_resize() + { + con.screen_min[0] = 6.0f; + con.screen_min[1] = 6.0f; + con.screen_max[0] = game::ScrPlace_GetViewPlacement()->realViewportSize[0] - 6.0f; + con.screen_max[1] = game::ScrPlace_GetViewPlacement()->realViewportSize[1] - 6.0f; + + if (console_font) + { + con.font_height = console_font->pixelHeight; + con.visible_line_count = static_cast((con.screen_max[1] - con.screen_min[1] - (con.font_height * 2) + ) - + 24.0f) / con.font_height; + con.visible_pixel_width = static_cast(((con.screen_max[0] - con.screen_min[0]) - 10.0f) - 18.0f); + } + else + { + con.font_height = 0; + con.visible_line_count = 0; + con.visible_pixel_width = 0; + } + } + + void draw_box(const float x, const float y, const float w, const float h, float* color) + { + game::vec4_t dark_color; + + dark_color[0] = color[0] * 0.5f; + dark_color[1] = color[1] * 0.5f; + dark_color[2] = color[2] * 0.5f; + dark_color[3] = color[3]; + + game::R_AddCmdDrawStretchPic(x, y, w, h, 0.0f, 0.0f, 0.0f, 0.0f, color, material_white); + game::R_AddCmdDrawStretchPic(x, y, 2.0f, h, 0.0f, 0.0f, 0.0f, 0.0f, dark_color, material_white); + game::R_AddCmdDrawStretchPic((x + w) - 2.0f, y, 2.0f, h, 0.0f, 0.0f, 0.0f, 0.0f, dark_color, + material_white); + game::R_AddCmdDrawStretchPic(x, y, w, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, dark_color, material_white); + game::R_AddCmdDrawStretchPic(x, (y + h) - 2.0f, w, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, dark_color, + material_white); + } + + void draw_input_box(const int lines, float* color) + { + draw_box( + con.globals.x - 6.0f, + con.globals.y - 6.0f, + (con.screen_max[0] - con.screen_min[0]) - ((con.globals.x - 6.0f) - con.screen_min[0]), + (lines * con.globals.font_height) + 12.0f, + color); + } + + void draw_input_text_and_over(const char* str, float* color) + { + game::R_AddCmdDrawText(str, 0x7FFFFFFF, console_font, con.globals.x, + con.globals.y + con.globals.font_height, 1.0f, + 1.0f, 0.0f, color, 0); + con.globals.x = game::R_TextWidth(str, 0, console_font) + con.globals.x + 6.0f; + } + + void 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.globals.font_height + 12.0f; + const auto _y = con.globals.y - 3.0f + con.globals.font_height + 12.0f; + const auto _w = (con.screen_max[0] - con.screen_min[0]) - ((con.globals.x - 6.0f) - con.screen_min[0]); + + draw_box(con.globals.x - 6.0f, _y, _w, _h, color); + } + + void draw_hint_text(const int line, const char* text, float* color, const float offset = 0.0f) + { + const auto _y = con.globals.font_height + con.globals.y + (con.globals.font_height * (line + 1)) + 15.0f; + + game::R_AddCmdDrawText(text, 0x7FFFFFFF, console_font, con.globals.x + offset, _y, 1.0f, 1.0f, 0.0f, color, 0); + } + + bool match_compare(const std::string& input, const std::string& text, const bool exact) + { + if (exact && text == input) return true; + if (!exact && text.find(input) != std::string::npos) return true; + return false; + } + + void find_matches(std::string input, std::vector& suggestions, const bool exact) + { + input = utils::string::to_lower(input); + + for (const auto& dvar : dvars::dvar_list) + { + auto name = utils::string::to_lower(dvar); + if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact)) + { + suggestions.push_back(dvar); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + if (suggestions.size() == 0 && game::Dvar_FindVar(input.data())) + { + suggestions.push_back(input.data()); + } + + game::cmd_function_s* cmd = (*game::cmd_functions); + while (cmd) + { + if (cmd->name) + { + std::string name = utils::string::to_lower(cmd->name); + + if (match_compare(input, name, exact)) + { + suggestions.push_back(cmd->name); + } + + if (exact && suggestions.size() > 1) + { + return; + } + } + + cmd = cmd->next; + } + } + + void draw_input() + { + con.globals.font_height = static_cast(console_font->pixelHeight); + con.globals.x = con.screen_min[0] + 6.0f; + con.globals.y = con.screen_min[1] + 6.0f; + con.globals.left_x = con.screen_min[0] + 6.0f; + + draw_input_box(1, dvars::con_inputBoxColor->current.vector); + draw_input_text_and_over("H1-Mod: " VERSION ">", color_title); + + con.globals.left_x = con.globals.x; + con.globals.auto_complete_choice[0] = 0; + + game::R_AddCmdDrawTextWithCursor(con.buffer, 0x7FFFFFFF, console_font, 18, con.globals.x, + con.globals.y + con.globals.font_height, 1.0f, 1.0f, 0, color_white, 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); + } + + fixed_input = input; + } + + con.globals.may_auto_complete = false; + if (matches.size() > 24) + { + draw_hint_box(1, dvars::con_inputHintBoxColor->current.vector); + draw_hint_text(0, utils::string::va("%i matches (too many to show here)", matches.size()), + dvars::con_inputDvarMatchColor->current.vector); + } + else if (matches.size() == 1) + { + auto* const dvar = game::Dvar_FindVar(matches[0].data()); + const auto line_count = dvar ? 2 : 1; + + draw_hint_box(line_count, dvars::con_inputHintBoxColor->current.vector); + draw_hint_text(0, matches[0].data(), dvar + ? dvars::con_inputDvarMatchColor->current.vector + : dvars::con_inputCmdMatchColor->current.vector); + + if (dvar) + { + const auto offset = (con.screen_max[0] - con.globals.x) / 2.5f; + + draw_hint_text(0, game::Dvar_ValueToString(dvar, dvar->current), + dvars::con_inputDvarValueColor->current.vector, offset); + draw_hint_text(1, " default", dvars::con_inputDvarInactiveValueColor->current.vector); + draw_hint_text(1, game::Dvar_ValueToString(dvar, dvar->reset), + dvars::con_inputDvarInactiveValueColor->current.vector, offset); + } + + strncpy_s(con.globals.auto_complete_choice, matches[0].data(), 64); + con.globals.may_auto_complete = true; + } + else if (matches.size() > 1) + { + draw_hint_box(static_cast(matches.size()), dvars::con_inputHintBoxColor->current.vector); + + const auto offset = (con.screen_max[0] - con.globals.x) / 2.5f; + + for (size_t i = 0; i < matches.size(); i++) + { + auto* const dvar = game::Dvar_FindVar(matches[i].data()); + + draw_hint_text(static_cast(i), matches[i].data(), + dvar + ? dvars::con_inputDvarMatchColor->current.vector + : dvars::con_inputCmdMatchColor->current.vector); + + if (dvar) + { + draw_hint_text(static_cast(i), game::Dvar_ValueToString(dvar, dvar->current), + dvars::con_inputDvarValueColor->current.vector, offset); + } + } + + strncpy_s(con.globals.auto_complete_choice, matches[0].data(), 64); + con.globals.may_auto_complete = true; + } + } + + void draw_output_scrollbar(const float x, float y, const float width, const float height, output_queue& output) + { + const auto _x = (x + width) - 10.0f; + draw_box(_x, y, 10.0f, height, dvars::con_outputBarColor->current.vector); + + auto _height = height; + if (output.size() > con.visible_line_count) + { + const auto percentage = static_cast(con.visible_line_count) / output.size(); + _height *= percentage; + + const auto remainingSpace = height - _height; + const 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, dvars::con_outputSliderColor->current.vector); + } + + void draw_output_text(const float x, float y, output_queue& output) + { + const 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++) + { + y = console_font->pixelHeight + y; + + const auto index = i + con.display_line_offset; + if (index >= output.size()) + { + break; + } + + game::R_AddCmdDrawText(output.at(index).data(), 0x7FFF, console_font, x, y + offset, 1.0f, 1.0f, + 0.0f, color_white, 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, dvars::con_outputWindowColor->current.vector); + + const auto x = con.screen_min[0] + 6.0f; + const auto y = (con.screen_min[1] + 32.0f) + 6.0f; + const auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f; + const auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f; + + game::R_AddCmdDrawText("H1-Mod 1.4", 0x7FFFFFFF, console_font, x, + ((height - 16.0f) + y) + console_font->pixelHeight, 1.0f, 1.0f, 0.0f, color_title, 0); + + draw_output_scrollbar(x, y, width, height, output); + draw_output_text(x, y, output); + }); + } + + void draw_console() + { + check_resize(); + + if (*game::keyCatchers & 1) + { + if (!(*game::keyCatchers & 1)) + { + con.output_visible = false; + } + + if (con.output_visible) + { + draw_output_window(); + } + + draw_input(); + } + } + } + + void print_internal(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 int type, const std::string& data) + { + try + { + if (game::environment::is_dedi()) + { + return; + } + } + catch (std::exception&) + { + return; + } + + const auto lines = utils::string::split(data, '\n'); + for (const auto& line : lines) + { + print_internal(type == console::con_type_info ? line : "^"s.append(std::to_string(type)).append(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.globals.may_auto_complete) + { + const auto first_char = con.buffer[0]; + + clear(); + + if (first_char == '\\' || first_char == '/') + { + con.buffer[0] = first_char; + con.buffer[1] = '\0'; + } + + strncat_s(con.buffer, con.globals.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(); + con.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_F10) + { + if (!game::Com_InFrontEnd()) + { + return false; + } + + game::Cmd_ExecuteSingleCommand(local_client_num, 0, "lui_open menu_systemlink_join\n"); + } + + if (key == game::keyNum_t::K_GRAVE || key == game::keyNum_t::K_TILDE) + { + if (!down) + { + return false; + } + + if (game::playerKeys[local_client_num].keys[game::keyNum_t::K_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(); + + 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(); + + 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); + + console::info("]%s\n", con.buffer); + + if (history.size() > 10) + { + history.erase(history.begin() + 10); + } + + history_index = -1; + + clear(); + } + } + } + + return true; + } + + + class component final : public component_interface + { + public: + void post_load() override + { + if (game::environment::is_dedi()) + { + return; + } + + //scheduler::loop(draw_console, scheduler::pipeline::renderer); + } + + void post_unpack() override + { + scheduler::loop(draw_console, scheduler::pipeline::renderer); + + + if (game::environment::is_dedi()) + { + return; + } + + // initialize our structs + con.cursor = 0; + con.visible_line_count = 0; + con.output_visible = false; + con.display_line_offset = 0; + con.line_count = 0; + strncpy_s(con.buffer, "", 256); + + con.globals.x = 0.0f; + con.globals.y = 0.0f; + con.globals.left_x = 0.0f; + con.globals.font_height = 0.0f; + con.globals.may_auto_complete = false; + con.globals.info_line_count = 0; + strncpy_s(con.globals.auto_complete_choice, "", 64); + + // add clear command + command::add("clear", [&]() + { + clear(); + con.line_count = 0; + con.display_line_offset = 0; + con.output.access([](output_queue& output) + { + output.clear(); + }); + history_index = -1; + history.clear(); + }); + + // add our dvars + dvars::con_inputBoxColor = dvars::register_vec4("con_inputBoxColor", 0.2f, 0.2f, 0.2f, 0.9f, 0.0f, 1.0f, + game::DVAR_FLAG_SAVED, + "color of console input box"); + dvars::con_inputHintBoxColor = dvars::register_vec4("con_inputHintBoxColor", 0.3f, 0.3f, 0.3f, 1.0f, + 0.0f, 1.0f, + game::DVAR_FLAG_SAVED, "color of console input hint box"); + dvars::con_outputBarColor = dvars::register_vec4("con_outputBarColor", 0.5f, 0.5f, 0.5f, 0.6f, 0.0f, + 1.0f, game::DVAR_FLAG_SAVED, + "color of console output bar"); + dvars::con_outputSliderColor = dvars::register_vec4("con_outputSliderColor", 1.0f, 0.8f, 0.0f, 1.0f, + 0.0f, 1.0f, + game::DVAR_FLAG_SAVED, "color of console output slider"); + dvars::con_outputWindowColor = dvars::register_vec4("con_outputWindowColor", 0.25f, 0.25f, 0.25f, 0.85f, + 0.0f, + 1.0f, game::DVAR_FLAG_SAVED, "color of console output window"); + dvars::con_inputDvarMatchColor = dvars::register_vec4("con_inputDvarMatchColor", 1.0f, 1.0f, 0.8f, 1.0f, + 0.0f, + 1.0f, game::DVAR_FLAG_SAVED, "color of console matched dvar"); + dvars::con_inputDvarValueColor = dvars::register_vec4("con_inputDvarValueColor", 1.0f, 1.0f, 0.8f, 1.0f, + 0.0f, + 1.0f, game::DVAR_FLAG_SAVED, "color of console matched dvar value"); + dvars::con_inputDvarInactiveValueColor = dvars::register_vec4( + "con_inputDvarInactiveValueColor", 0.8f, 0.8f, + 0.8f, 1.0f, 0.0f, 1.0f, game::DVAR_FLAG_SAVED, + "color of console inactive dvar value"); + dvars::con_inputCmdMatchColor = dvars::register_vec4("con_inputCmdMatchColor", 0.80f, 0.80f, 1.0f, 1.0f, + 0.0f, + 1.0f, game::DVAR_FLAG_SAVED, "color of console matched command"); + } + }; +} + +REGISTER_COMPONENT(game_console::component) diff --git a/src/client/component/game_console.hpp b/src/client/component/game_console.hpp new file mode 100644 index 00000000..cdc001a7 --- /dev/null +++ b/src/client/component/game_console.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace game_console +{ + bool console_char_event(int local_client_num, int key); + bool console_key_event(int local_client_num, int key, int down); +} \ No newline at end of file diff --git a/src/client/component/game_module.cpp b/src/client/component/game_module.cpp index 9bc79de0..bd984624 100644 --- a/src/client/component/game_module.cpp +++ b/src/client/component/game_module.cpp @@ -1,7 +1,6 @@ #include #include "loader/component_loader.hpp" #include "game_module.hpp" -#include "game/game.hpp" #include @@ -91,7 +90,7 @@ namespace game_module utils::nt::library get_game_module() { - static utils::nt::library game{HMODULE(game::base_address)}; + static utils::nt::library game{HMODULE(0x140000000)}; return game; } diff --git a/src/client/component/localized_strings.cpp b/src/client/component/localized_strings.cpp new file mode 100644 index 00000000..55b41d65 --- /dev/null +++ b/src/client/component/localized_strings.cpp @@ -0,0 +1,52 @@ +#include +#include "loader/component_loader.hpp" +#include "localized_strings.hpp" +#include +#include +#include +#include "game/game.hpp" + +namespace localized_strings +{ + namespace + { + utils::hook::detour seh_string_ed_get_string_hook; + + using localized_map = std::unordered_map; + utils::concurrency::container localized_overrides; + + const char* seh_string_ed_get_string(const char* reference) + { + return localized_overrides.access([&](const localized_map& map) + { + const auto entry = map.find(reference); + if (entry != map.end()) + { + return utils::string::va("%s", entry->second.data()); + } + + return seh_string_ed_get_string_hook.invoke(reference); + }); + } + } + + void override(const std::string& key, const std::string& value) + { + localized_overrides.access([&](localized_map& map) + { + map[key] = value; + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + // Change some localized strings + seh_string_ed_get_string_hook.create(SELECT_VALUE(0, 0x585DA0_b), &seh_string_ed_get_string); // H1-STEAM(1.15) + } + }; +} + +REGISTER_COMPONENT(localized_strings::component) diff --git a/src/client/component/localized_strings.hpp b/src/client/component/localized_strings.hpp new file mode 100644 index 00000000..01d15907 --- /dev/null +++ b/src/client/component/localized_strings.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace localized_strings +{ + void override(const std::string& key, const std::string& value); +} \ No newline at end of file diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp new file mode 100644 index 00000000..fc949d92 --- /dev/null +++ b/src/client/component/logfile.cpp @@ -0,0 +1,317 @@ +#include +#include "loader/component_loader.hpp" +#include "scheduler.hpp" + +#include "game/scripting/entity.hpp" +#include "game/scripting/execution.hpp" +#include "game/scripting/lua/value_conversion.hpp" +#include "game/scripting/lua/error.hpp" + +#include + +#include "logfile.hpp" + +namespace logfile +{ + std::unordered_map vm_execute_hooks; + + namespace + { + utils::hook::detour scr_player_killed_hook; + utils::hook::detour scr_player_damage_hook; + + std::vector player_killed_callbacks; + std::vector player_damage_callbacks; + + utils::hook::detour vm_execute_hook; + char empty_function[2] = {0x32, 0x34}; // CHECK_CLEAR_PARAMS, END + bool hook_enabled = true; + + sol::lua_value convert_entity(lua_State* state, const game::mp::gentity_s* ent) + { + if (!ent) + { + return {}; + } + + const scripting::entity player{game::Scr_GetEntityId(ent->s.entityNum, 0)}; + return scripting::lua::convert(state, player); + } + + std::string get_weapon_name(unsigned int weapon, bool isAlternate) + { + char output[1024] = {0}; + game::BG_GetWeaponNameComplete(weapon, isAlternate, output, 1024); + return output; + } + + sol::lua_value convert_vector(lua_State* state, const float* vec) + { + if (!vec) + { + return {}; + } + + const auto vec_ = scripting::vector(vec); + return scripting::lua::convert(state, vec_); + } + + std::string convert_mod(const int meansOfDeath) + { + const auto value = reinterpret_cast(0x140FEC3F0)[meansOfDeath]; + const auto string = game::SL_ConvertToString(*value); + return string; + } + + void scr_player_killed_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, + game::mp::gentity_s* attacker, int damage, const int meansOfDeath, const unsigned int weapon, + const bool isAlternate, const float* vDir, const unsigned int hitLoc, int psTimeOffset, int deathAnimDuration) + { + { + const std::string hitloc = reinterpret_cast(0x140FEC4D0)[hitLoc]; + const auto mod_ = convert_mod(meansOfDeath); + + const auto weapon_ = get_weapon_name(weapon, isAlternate); + + for (const auto& callback : player_killed_callbacks) + { + const auto state = callback.lua_state(); + + const auto self_ = convert_entity(state, self); + const auto inflictor_ = convert_entity(state, inflictor); + const auto attacker_ = convert_entity(state, attacker); + + const auto dir = convert_vector(state, vDir); + + const auto result = callback(self_, inflictor_, attacker_, damage, + mod_, weapon_, dir, hitloc, psTimeOffset, deathAnimDuration); + + scripting::lua::handle_error(result); + + if (result.valid() && result.get_type() == sol::type::number) + { + damage = result.get(); + } + } + + if (damage == 0) + { + return; + } + } + + scr_player_killed_hook.invoke(self, inflictor, attacker, damage, meansOfDeath, + weapon, isAlternate, vDir, hitLoc, psTimeOffset, deathAnimDuration); + } + + void scr_player_damage_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, + game::mp::gentity_s* attacker, int damage, int dflags, const int meansOfDeath, + const unsigned int weapon, const bool isAlternate, const float* vPoint, + const float* vDir, const unsigned int hitLoc, const int timeOffset) + { + { + const std::string hitloc = reinterpret_cast(0x140FEC4D0)[hitLoc]; + const auto mod_ = convert_mod(meansOfDeath); + + const auto weapon_ = get_weapon_name(weapon, isAlternate); + + for (const auto& callback : player_damage_callbacks) + { + const auto state = callback.lua_state(); + + const auto self_ = convert_entity(state, self); + const auto inflictor_ = convert_entity(state, inflictor); + const auto attacker_ = convert_entity(state, attacker); + + const auto point = convert_vector(state, vPoint); + const auto dir = convert_vector(state, vDir); + + const auto result = callback(self_, inflictor_, attacker_, + damage, dflags, mod_, weapon_, point, dir, hitloc); + + scripting::lua::handle_error(result); + + if (result.valid() && result.get_type() == sol::type::number) + { + damage = result.get(); + } + } + + if (damage == 0) + { + return; + } + } + + scr_player_damage_hook.invoke(self, inflictor, attacker, damage, dflags, + meansOfDeath, weapon, isAlternate, vPoint, vDir, hitLoc, timeOffset); + } + + void client_command_stub(const int clientNum) + { + auto self = &game::mp::g_entities[clientNum]; + char cmd[1024] = {0}; + + game::SV_Cmd_ArgvBuffer(0, cmd, 1024); + + if (cmd == "say"s || cmd == "say_team"s) + { + auto hidden = false; + std::string message(game::ConcatArgs(1)); + + hidden = message[1] == '/'; + message.erase(0, hidden ? 2 : 1); + + scheduler::once([cmd, message, self]() + { + const scripting::entity level{*game::levelEntityId}; + const scripting::entity player{game::Scr_GetEntityId(self->s.entityNum, 0)}; + + scripting::notify(level, cmd, {player, message}); + scripting::notify(player, cmd, {message}); + }, scheduler::pipeline::server); + + if (hidden) + { + return; + } + } + + // ClientCommand + return utils::hook::invoke(0x140336000, clientNum); + } + + void g_shutdown_game_stub(const int freeScripts) + { + { + const scripting::entity level{*game::levelEntityId}; + scripting::notify(level, "shutdownGame_called", {1}); + } + + // G_ShutdownGame + return utils::hook::invoke(0x140345A60, freeScripts); + } + + unsigned int local_id_to_entity(unsigned int local_id) + { + const auto variable = game::scr_VarGlob->objectVariableValue[local_id]; + return variable.u.f.next; + } + + bool execute_vm_hook(const char* pos) + { + if (vm_execute_hooks.find(pos) == vm_execute_hooks.end()) + { + hook_enabled = true; + return false; + } + + if (!hook_enabled && pos > reinterpret_cast(vm_execute_hooks.size())) + { + hook_enabled = true; + return false; + } + + const auto hook = vm_execute_hooks[pos]; + const auto state = hook.lua_state(); + + const scripting::entity self = local_id_to_entity(game::scr_VmPub->function_frame->fs.localId); + + std::vector args; + + const auto top = game::scr_function_stack->top; + + for (auto* value = top; value->type != game::SCRIPT_END; --value) + { + args.push_back(scripting::lua::convert(state, *value)); + } + + const auto result = hook(self, sol::as_args(args)); + scripting::lua::handle_error(result); + + return true; + } + + void vm_execute_stub(utils::hook::assembler& a) + { + const auto replace = a.newLabel(); + const auto end = a.newLabel(); + + a.pushad64(); + + a.mov(rcx, r14); + a.call_aligned(execute_vm_hook); + + a.cmp(al, 0); + a.jne(replace); + + a.popad64(); + a.jmp(end); + + a.bind(end); + + a.movzx(r15d, byte_ptr(r14)); + a.inc(r14); + a.mov(dword_ptr(rbp, 0xA4), r15d); + + a.jmp(SELECT_VALUE(0x140376663, 0x140444653)); + + a.bind(replace); + + a.popad64(); + a.mov(r14, reinterpret_cast(empty_function)); + a.jmp(end); + } + } + + void add_player_damage_callback(const sol::protected_function& callback) + { + player_damage_callbacks.push_back(callback); + } + + void add_player_killed_callback(const sol::protected_function& callback) + { + player_killed_callbacks.push_back(callback); + } + + void clear_callbacks() + { + player_damage_callbacks.clear(); + player_killed_callbacks.clear(); + vm_execute_hooks.clear(); + } + + void enable_vm_execute_hook() + { + hook_enabled = true; + } + + void disable_vm_execute_hook() + { + hook_enabled = false; + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) + { + return; + } + + utils::hook::call(0x14048191D, client_command_stub); + + scr_player_damage_hook.create(0x14037DC50, scr_player_damage_stub); + scr_player_killed_hook.create(0x14037DF30, scr_player_killed_stub); + + utils::hook::call(0x140484EC0, g_shutdown_game_stub); + utils::hook::call(0x1404853C1, g_shutdown_game_stub); + + utils::hook::jump(SELECT_VALUE(0x140376655, 0x140444645), utils::hook::assemble(vm_execute_stub), true); + } + }; +} + +REGISTER_COMPONENT(logfile::component) \ No newline at end of file diff --git a/src/client/component/logfile.hpp b/src/client/component/logfile.hpp new file mode 100644 index 00000000..77f699c8 --- /dev/null +++ b/src/client/component/logfile.hpp @@ -0,0 +1,13 @@ +#pragma once + +namespace logfile +{ + extern std::unordered_map vm_execute_hooks; + + void add_player_damage_callback(const sol::protected_function& callback); + void add_player_killed_callback(const sol::protected_function& callback); + void clear_callbacks(); + + void enable_vm_execute_hook(); + void disable_vm_execute_hook(); +} \ No newline at end of file diff --git a/src/client/component/lui.cpp b/src/client/component/lui.cpp new file mode 100644 index 00000000..d3a7edca --- /dev/null +++ b/src/client/component/lui.cpp @@ -0,0 +1,58 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include "command.hpp" +#include "console.hpp" + +#include + +namespace lui +{ + class component final : public component_interface + { + public: + void post_unpack() override + { + // Don't show create cod account popup + //utils::hook::set(0x14017C957, 0); // H1(1.4) + +//#ifdef _DEBUG + // Enable development menus (causes issues in sp) + //utils::hook::set(SELECT_VALUE(0x1400B4ABC, 0x1401AB779), 1); +//#endif + + command::add("lui_open", [](const command::params& params) + { + if (params.size() <= 1) + { + console::info("usage: lui_open \n"); + return; + } + + game::LUI_OpenMenu(0, params[1], 0, 0, 0); + }); + + command::add("lui_open_popup", [](const command::params& params) + { + if (params.size() <= 1) + { + console::info("usage: lui_open_popup \n"); + return; + } + + game::LUI_OpenMenu(0, params[1], 1, 0, 0); + }); + + command::add("runMenuScript", [](const command::params& params) + { + const auto args_str = params.join(1); + const auto* args = args_str.data(); + game::UI_RunMenuScript(0, &args); + }); + } + }; +} + +REGISTER_COMPONENT(lui::component) diff --git a/src/client/component/map_rotation.cpp b/src/client/component/map_rotation.cpp new file mode 100644 index 00000000..216cbfcd --- /dev/null +++ b/src/client/component/map_rotation.cpp @@ -0,0 +1,180 @@ +#include +#include "loader/component_loader.hpp" +#include "command.hpp" +#include "scheduler.hpp" +#include +#include +#include "game/game.hpp" +#include + +namespace map_rotation +{ + DWORD previousPriority; + namespace + { + void set_dvar(const std::string& dvar, const std::string& value) + { + command::execute(utils::string::va("%s \"%s\"", dvar.data(), value.data()), true); + } + + void set_gametype(const std::string& gametype) + { + set_dvar("g_gametype", gametype); + } + + void launch_map(const std::string& mapname) + { + command::execute(utils::string::va("map %s", mapname.data()), false); + } + + void launch_default_map() + { + auto* mapname = game::Dvar_FindVar("mapname"); + if (mapname && mapname->current.string && strlen(mapname->current.string) && mapname->current.string != + "mp_vlobby_room"s) + { + launch_map(mapname->current.string); + } + else + { + launch_map("mp_crash"); + } + } + + std::string load_current_map_rotation() + { + auto* rotation = game::Dvar_FindVar("sv_mapRotationCurrent"); + if (!strlen(rotation->current.string)) + { + rotation = game::Dvar_FindVar("sv_mapRotation"); + set_dvar("sv_mapRotationCurrent", rotation->current.string); + } + + return rotation->current.string; + } + + std::vector parse_current_map_rotation() + { + const auto rotation = load_current_map_rotation(); + return utils::string::split(rotation, ' '); + } + + void store_new_rotation(const std::vector& elements, const size_t index) + { + std::string value{}; + + for (auto i = index; i < elements.size(); ++i) + { + if (i != index) + { + value.push_back(' '); + } + + value.append(elements[i]); + } + + set_dvar("sv_mapRotationCurrent", value); + } + + void change_process_priority() + { + auto* const dvar = game::Dvar_FindVar("sv_autoPriority"); + if (dvar && dvar->current.enabled) + { + scheduler::on_game_initialized([]() + { + //printf("=======================setting OLD priority=======================\n"); + SetPriorityClass(GetCurrentProcess(), previousPriority); + }, scheduler::pipeline::main, 1s); + + previousPriority = GetPriorityClass(GetCurrentProcess()); + //printf("=======================setting NEW priority=======================\n"); + SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); + } + } + + void perform_map_rotation() + { + if (game::Live_SyncOnlineDataFlags(0) != 0) + { + scheduler::on_game_initialized(perform_map_rotation, scheduler::pipeline::main, 1s); + return; + } + + const auto rotation = parse_current_map_rotation(); + + for (size_t i = 0; !rotation.empty() && i < (rotation.size() - 1); i += 2) + { + const auto& key = rotation[i]; + const auto& value = rotation[i + 1]; + + if (key == "gametype") + { + set_gametype(value); + } + else if (key == "map") + { + store_new_rotation(rotation, i + 2); + change_process_priority(); + if (!game::SV_MapExists(value.data())) + { + printf("map_rotation: '%s' map doesn't exist!\n", value.data()); + launch_default_map(); + return; + } + launch_map(value); + return; + } + else + { + printf("Invalid map rotation key: %s\n", key.data()); + } + } + + launch_default_map(); + } + + void trigger_map_rotation() + { + scheduler::schedule([]() + { + if (game::CL_IsCgameInitialized()) + { + return scheduler::cond_continue; + } + + command::execute("map_rotate", false); + return scheduler::cond_end; + }, scheduler::pipeline::main, 1s); + } + + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (!game::environment::is_dedi()) + { + return; + } + + scheduler::once([]() + { + dvars::register_string("sv_mapRotation", "", game::DVAR_FLAG_NONE, true); + dvars::register_string("sv_mapRotationCurrent", "", game::DVAR_FLAG_NONE, true); + dvars::register_string("sv_autoPriority", "", game::DVAR_FLAG_NONE, true); + }, scheduler::pipeline::main); + + command::add("map_rotate", &perform_map_rotation); + + // Hook GScr_ExitLevel + utils::hook::jump(0x140376630, &trigger_map_rotation); // not sure if working + + previousPriority = GetPriorityClass(GetCurrentProcess()); + } + }; +} + +REGISTER_COMPONENT(map_rotation::component) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 8069d61a..fb2a6f55 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -27,8 +27,15 @@ namespace network const auto cmd_string = utils::string::to_lower(command); auto& callbacks = get_callbacks(); const auto handler = callbacks.find(cmd_string); + + if (handler == callbacks.end()) + { + return false; + } + const auto offset = cmd_string.size() + 5; - if (message->cursize < offset || handler == callbacks.end()) + + if (message->cursize <= offset) { return false; } @@ -324,4 +331,4 @@ namespace network }; } -REGISTER_COMPONENT(network::component) \ No newline at end of file +REGISTER_COMPONENT(network::component) diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp new file mode 100644 index 00000000..0605afad --- /dev/null +++ b/src/client/component/party.cpp @@ -0,0 +1,630 @@ +#include +#include "loader/component_loader.hpp" + +#include "party.hpp" +#include "console.hpp" +#include "command.hpp" +#include "network.hpp" +#include "scheduler.hpp" +#include "server_list.hpp" + +#include "steam/steam.hpp" + +#include +#include +#include +#include + +namespace party +{ + namespace + { + struct + { + game::netadr_s host{}; + std::string challenge{}; + bool hostDefined{false}; + } connect_state; + + std::string sv_motd; + int sv_maxclients; + + void perform_game_initialization() + { + command::execute("onlinegame 1", true); + command::execute("xstartprivateparty", true); + command::execute("xblive_privatematch 1", true); + command::execute("startentitlements", true); + } + + void connect_to_party(const game::netadr_s& target, const std::string& mapname, const std::string& gametype) + { + if (game::environment::is_sp()) + { + return; + } + + if (game::Live_SyncOnlineDataFlags(0) != 0) + { + // initialize the game after onlinedataflags is 32 (workaround) + if (game::Live_SyncOnlineDataFlags(0) == 32) + { + scheduler::once([=]() + { + command::execute("xstartprivateparty", true); + command::execute("disconnect", true); // 32 -> 0 + + connect_to_party(target, mapname, gametype); + }, scheduler::pipeline::main, 1s); + return; + } + else + { + scheduler::once([=]() + { + connect_to_party(target, mapname, gametype); + }, scheduler::pipeline::main, 1s); + return; + } + } + + perform_game_initialization(); + + // exit from virtuallobby + utils::hook::invoke(0x140256D40, 1); + + // CL_ConnectFromParty + char session_info[0x100] = {}; + utils::hook::invoke(0x140251560, 0, session_info, &target, mapname.data(), gametype.data()); + } + + std::string get_dvar_string(const std::string& dvar) + { + auto* dvar_value = game::Dvar_FindVar(dvar.data()); + if (dvar_value && dvar_value->current.string) + { + return dvar_value->current.string; + } + + return {}; + } + + int get_dvar_int(const std::string& dvar) + { + auto* dvar_value = game::Dvar_FindVar(dvar.data()); + if (dvar_value && dvar_value->current.integer) + { + return dvar_value->current.integer; + } + + return -1; + } + + bool get_dvar_bool(const std::string& dvar) + { + auto* dvar_value = game::Dvar_FindVar(dvar.data()); + if (dvar_value && dvar_value->current.enabled) + { + return dvar_value->current.enabled; + } + + return false; + } + + void didyouknow_stub(const char* dvar_name, const char* string) + { + if (!party::sv_motd.empty()) + { + string = party::sv_motd.data(); + } + + // This function either does Dvar_SetString or Dvar_RegisterString for the given dvar + utils::hook::invoke(0x1404FB210, dvar_name, string); + } + + void disconnect_stub() + { + if (!game::VirtualLobby_Loaded()) + { + if (game::CL_IsCgameInitialized()) + { + // CL_ForwardCommandToServer + utils::hook::invoke(0x140253480, 0, "disconnect"); + // CL_WritePacket + utils::hook::invoke(0x14024DB10, 0); + } + // CL_Disconnect + utils::hook::invoke(0x140252060, 0); + } + } + + utils::hook::detour cldisconnect_hook; + + void cl_disconnect_stub(int a1) + { + party::sv_motd.clear(); + cldisconnect_hook.invoke(a1); + } + + const auto drop_reason_stub = utils::hook::assemble([](utils::hook::assembler& a) + { + a.mov(rdx, rdi); + a.mov(ecx, 2); + a.jmp(0x140251F78); + }); + + void menu_error(const std::string& error) + { + utils::hook::invoke(0x1400DACC0, error.data(), "MENU_NOTICE"); + utils::hook::set(0x142C1DA98, 1); + } + } + + int get_client_num_by_name(const std::string& name) + { + for (auto i = 0; !name.empty() && i < *game::mp::svs_numclients; ++i) + { + if (game::mp::g_entities[i].client) + { + char client_name[16] = {0}; + strncpy_s(client_name, game::mp::g_entities[i].client->name, sizeof(client_name)); + game::I_CleanStr(client_name); + + if (client_name == name) + { + return i; + } + } + } + return -1; + } + + void reset_connect_state() + { + connect_state = {}; + } + + int get_client_count() + { + auto count = 0; + for (auto i = 0; i < *game::mp::svs_numclients; ++i) + { + if (game::mp::svs_clients[i].header.state >= 1) + { + ++count; + } + } + + return count; + } + + int get_bot_count() + { + auto count = 0; + for (auto i = 0; i < *game::mp::svs_numclients; ++i) + { + if (game::mp::svs_clients[i].header.state >= 1 && + game::SV_BotIsBot(i)) + { + ++count; + } + } + + return count; + } + + void connect(const game::netadr_s& target) + { + if (game::environment::is_sp()) + { + return; + } + + command::execute("lui_open_popup popup_acceptinginvite", false); + + connect_state.host = target; + connect_state.challenge = utils::cryptography::random::get_challenge(); + connect_state.hostDefined = true; + + network::send(target, "getInfo", connect_state.challenge); + } + + void start_map(const std::string& mapname) + { + if (game::Live_SyncOnlineDataFlags(0) > 32) + { + scheduler::once([=]() + { + command::execute("map " + mapname, false); + }, scheduler::pipeline::main, 1s); + } + else + { + if (!game::SV_MapExists(mapname.data())) + { + console::info("Map '%s' doesn't exist.\n", mapname.data()); + return; + } + + auto* current_mapname = game::Dvar_FindVar("mapname"); + if (current_mapname && utils::string::to_lower(current_mapname->current.string) == + utils::string::to_lower(mapname) && (game::SV_Loaded() && !game::VirtualLobby_Loaded())) + { + console::info("Restarting map: %s\n", mapname.data()); + command::execute("map_restart", false); + return; + } + + if (!game::environment::is_dedi()) + { + if (game::SV_Loaded()) + { + const auto* args = "Leave"; + game::UI_RunMenuScript(0, &args); + } + + perform_game_initialization(); + } + + console::info("Starting map: %s\n", mapname.data()); + + auto* gametype = game::Dvar_FindVar("g_gametype"); + if (gametype && gametype->current.string) + { + command::execute(utils::string::va("ui_gametype %s", gametype->current.string), true); + } + command::execute(utils::string::va("ui_mapname %s", mapname.data()), true); + + /*auto* maxclients = game::Dvar_FindVar("sv_maxclients"); + if (maxclients) + { + command::execute(utils::string::va("ui_maxclients %i", maxclients->current.integer), true); + command::execute(utils::string::va("party_maxplayers %i", maxclients->current.integer), true); + }*/ + + const auto* args = "StartServer"; + game::UI_RunMenuScript(0, &args); + } + } + + int server_client_count() + { + return party::sv_maxclients; + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) + { + return; + } + + // hook disconnect command function + utils::hook::jump(0x1402521C7, disconnect_stub); + + // detour CL_Disconnect to clear motd + cldisconnect_hook.create(0x140252060, cl_disconnect_stub); + + if (game::environment::is_mp()) + { + // show custom drop reason + utils::hook::nop(0x140251EFB, 13); + utils::hook::jump(0x140251EFB, drop_reason_stub, true); + } + + // enable custom kick reason in GScr_KickPlayer + utils::hook::set(0x140376A1D, 0xEB); + + command::add("map", [](const command::params& argument) + { + if (argument.size() != 2) + { + return; + } + + start_map(argument[1]); + }); + + command::add("map_restart", []() + { + if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) + { + return; + } + *reinterpret_cast(0x14A3A91D0) = 1; // sv_map_restart + *reinterpret_cast(0x14A3A91D4) = 1; // sv_loadScripts + *reinterpret_cast(0x14A3A91D8) = 0; // sv_migrate + + utils::hook::invoke(0x14047E7F0); // SV_CheckLoadGame + }); + + command::add("fast_restart", []() + { + if (game::SV_Loaded() && !game::VirtualLobby_Loaded()) + { + game::SV_FastRestart(0); + } + }); + + command::add("reconnect", [](const command::params& argument) + { + if (!connect_state.hostDefined) + { + console::info("Cannot connect to server.\n"); + return; + } + + if (game::CL_IsCgameInitialized()) + { + command::execute("disconnect"); + command::execute("reconnect"); + } + else + { + connect(connect_state.host); + } + }); + + command::add("connect", [](const command::params& argument) + { + if (argument.size() != 2) + { + return; + } + + game::netadr_s target{}; + if (game::NET_StringToAdr(argument[1], &target)) + { + connect(target); + } + }); + + command::add("kickClient", [](const command::params& params) + { + if (params.size() < 2) + { + console::info("usage: kickClient , (optional)\n"); + return; + } + + if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) + { + return; + } + + std::string reason; + if (params.size() > 2) + { + reason = params.join(2); + } + if (reason.empty()) + { + reason = "EXE_PLAYERKICKED"; + } + + const auto client_num = atoi(params.get(1)); + if (client_num < 0 || client_num >= *game::mp::svs_numclients) + { + return; + } + + scheduler::once([client_num, reason]() + { + game::SV_KickClientNum(client_num, reason.data()); + }, scheduler::pipeline::server); + }); + + command::add("kick", [](const command::params& params) + { + if (params.size() < 2) + { + console::info("usage: kick , (optional)\n"); + return; + } + + if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) + { + return; + } + + std::string reason; + if (params.size() > 2) + { + reason = params.join(2); + } + if (reason.empty()) + { + reason = "EXE_PLAYERKICKED"; + } + + const std::string name = params.get(1); + if (name == "all"s) + { + for (auto i = 0; i < *game::mp::svs_numclients; ++i) + { + scheduler::once([i, reason]() + { + game::SV_KickClientNum(i, reason.data()); + }, scheduler::pipeline::server); + } + return; + } + + const auto client_num = get_client_num_by_name(name); + if (client_num < 0 || client_num >= *game::mp::svs_numclients) + { + return; + } + + scheduler::once([client_num, reason]() + { + game::SV_KickClientNum(client_num, reason.data()); + }, scheduler::pipeline::server); + }); + + scheduler::once([]() + { + const auto hash = game::generateHashValue("sv_sayName"); + game::Dvar_RegisterString(hash, "sv_sayName", "console", game::DvarFlags::DVAR_FLAG_NONE); + }, scheduler::pipeline::main); + + command::add("tell", [](const command::params& params) + { + if (params.size() < 3) + { + return; + } + + const auto client_num = atoi(params.get(1)); + const auto message = params.join(2); + const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string; + + game::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, + utils::string::va("%c \"%s: %s\"", 84, name, message.data())); + printf("%s -> %i: %s\n", name, client_num, message.data()); + }); + + command::add("tellraw", [](const command::params& params) + { + if (params.size() < 3) + { + return; + } + + const auto client_num = atoi(params.get(1)); + const auto message = params.join(2); + + game::SV_GameSendServerCommand(client_num, game::SV_CMD_CAN_IGNORE, + utils::string::va("%c \"%s\"", 84, message.data())); + printf("%i: %s\n", client_num, message.data()); + }); + + command::add("say", [](const command::params& params) + { + if (params.size() < 2) + { + return; + } + + const auto message = params.join(1); + const auto* const name = game::Dvar_FindVar("sv_sayName")->current.string; + + game::SV_GameSendServerCommand( + -1, game::SV_CMD_CAN_IGNORE, utils::string::va("%c \"%s: %s\"", 84, name, message.data())); + printf("%s: %s\n", name, message.data()); + }); + + command::add("sayraw", [](const command::params& params) + { + if (params.size() < 2) + { + return; + } + + const auto message = params.join(1); + + game::SV_GameSendServerCommand(-1, game::SV_CMD_CAN_IGNORE, + utils::string::va("%c \"%s\"", 84, message.data())); + printf("%s\n", message.data()); + }); + + utils::hook::call(0x1404C6E8D, didyouknow_stub); // allow custom didyouknow based on sv_motd + + network::on("getInfo", [](const game::netadr_s& target, const std::string_view& data) + { + utils::info_string info{}; + info.set("challenge", std::string{data}); + info.set("gamename", "H1"); + info.set("hostname", get_dvar_string("sv_hostname")); + info.set("gametype", get_dvar_string("g_gametype")); + info.set("sv_motd", get_dvar_string("sv_motd")); + info.set("xuid", utils::string::va("%llX", steam::SteamUser()->GetSteamID().bits)); + info.set("mapname", get_dvar_string("mapname")); + info.set("isPrivate", get_dvar_string("g_password").empty() ? "0" : "1"); + info.set("clients", utils::string::va("%i", get_client_count())); + info.set("bots", utils::string::va("%i", get_bot_count())); + info.set("sv_maxclients", utils::string::va("%i", *game::mp::svs_numclients)); + info.set("protocol", utils::string::va("%i", PROTOCOL)); + info.set("playmode", utils::string::va("%i", game::Com_GetCurrentCoDPlayMode())); + info.set("sv_running", utils::string::va("%i", get_dvar_bool("sv_running") && !game::VirtualLobby_Loaded())); + info.set("dedicated", utils::string::va("%i", get_dvar_bool("dedicated"))); + + network::send(target, "infoResponse", info.build(), '\n'); + }); + + network::on("infoResponse", [](const game::netadr_s& target, const std::string_view& data) + { + const utils::info_string info{data}; + server_list::handle_info_response(target, info); + + if (connect_state.host != target) + { + return; + } + + if (info.get("challenge") != connect_state.challenge) + { + const auto str = "Invalid challenge."; + printf("%s\n", str); + menu_error(str); + return; + } + + const auto gamename = info.get("gamename"); + if (gamename != "H1"s) + { + const auto str = "Invalid gamename."; + printf("%s\n", str); + menu_error(str); + return; + } + + const auto playmode = info.get("playmode"); + if (game::CodPlayMode(std::atoi(playmode.data())) != game::Com_GetCurrentCoDPlayMode()) + { + const auto str = "Invalid playmode."; + printf("%s\n", str); + menu_error(str); + return; + } + + const auto sv_running = info.get("sv_running"); + if (!std::atoi(sv_running.data())) + { + const auto str = "Server not running."; + printf("%s\n", str); + menu_error(str); + return; + } + + const auto mapname = info.get("mapname"); + if (mapname.empty()) + { + const auto str = "Invalid map."; + printf("%s\n", str); + menu_error(str); + return; + } + + const auto gametype = info.get("gametype"); + if (gametype.empty()) + { + const auto str = "Invalid gametype."; + printf("%s\n", str); + menu_error(str); + return; + } + + party::sv_motd = info.get("sv_motd"); + party::sv_maxclients = std::stoi(info.get("sv_maxclients")); + + connect_to_party(target, mapname, gametype); + }); + } + }; +} + +REGISTER_COMPONENT(party::component) \ No newline at end of file diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp new file mode 100644 index 00000000..cd90ae9f --- /dev/null +++ b/src/client/component/party.hpp @@ -0,0 +1,17 @@ +#pragma once +#include "game/game.hpp" + +namespace party +{ + void reset_connect_state(); + + void connect(const game::netadr_s& target); + void start_map(const std::string& mapname); + + int server_client_count(); + + int get_client_num_by_name(const std::string& name); + + int get_client_count(); + int get_bot_count(); +} \ No newline at end of file diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp new file mode 100644 index 00000000..e9aaf21a --- /dev/null +++ b/src/client/component/patches.cpp @@ -0,0 +1,293 @@ +#include +#include "loader/component_loader.hpp" + +#include "dvars.hpp" +#include "version.h" +#include "command.hpp" +#include "console.hpp" +#include "network.hpp" +#include "scheduler.hpp" +#include "filesystem.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include + +namespace patches +{ + namespace + { + const char* live_get_local_client_name() + { + return game::Dvar_FindVar("name")->current.string; + } + + utils::hook::detour sv_kick_client_num_hook; + + void sv_kick_client_num(const int client_num, const char* reason) + { + // Don't kick bot to equalize team balance. + if (reason == "EXE_PLAYERKICKED_BOT_BALANCE"s) + { + return; + } + return sv_kick_client_num_hook.invoke(client_num, reason); + } + + std::string get_login_username() + { + char username[UNLEN + 1]; + DWORD username_len = UNLEN + 1; + if (!GetUserNameA(username, &username_len)) + { + return "Unknown Soldier"; + } + + return std::string{ username, username_len - 1 }; + } + + utils::hook::detour com_register_dvars_hook; + + void com_register_dvars_stub() + { + if (game::environment::is_mp()) + { + // Make name save + dvars::register_string("name", get_login_username().data(), game::DVAR_FLAG_SAVED, true); + + // Disable data validation error popup + dvars::register_int("data_validation_allow_drop", 0, 0, 0, game::DVAR_FLAG_NONE, true); + } + + return com_register_dvars_hook.invoke(); + } + + int is_item_unlocked() + { + return 0; // 0 == yes + } + + void set_client_dvar_from_server_stub(void* a1, void* a2, const char* dvar, const char* value) + { + if (dvar == "cg_fov"s) + { + return; + } + + // CG_SetClientDvarFromServer + utils::hook::invoke(0x140236120, a1, a2, dvar, value); + } + + const char* db_read_raw_file_stub(const char* filename, char* buf, const int size) + { + std::string file_name = filename; + if (file_name.find(".cfg") == std::string::npos) + { + file_name.append(".cfg"); + } + + const auto file = filesystem::file(file_name); + if (file.exists()) + { + snprintf(buf, size, "%s\n", file.get_buffer().data()); + return buf; + } + + // DB_ReadRawFile + return utils::hook::invoke(SELECT_VALUE(0x1401CD4F0, 0x1402BEF10), filename, buf, size); + } + + void bsp_sys_error_stub(const char* error, const char* arg1) + { + if (game::environment::is_dedi()) + { + game::Sys_Error(error, arg1); + } + else + { + scheduler::once([]() + { + command::execute("reconnect"); + }, scheduler::pipeline::main, 1s); + game::Com_Error(game::ERR_DROP, error, arg1); + } + } + + utils::hook::detour cmd_lui_notify_server_hook; + void cmd_lui_notify_server_stub(game::mp::gentity_s* ent) + { + command::params_sv params{}; + const auto menu_id = atoi(params.get(1)); + const auto client = &game::mp::svs_clients[ent->s.entityNum]; + + // 22 => "end_game" + if (menu_id == 22 && client->header.remoteAddress.type != game::NA_LOOPBACK) + { + return; + } + + cmd_lui_notify_server_hook.invoke(ent); + } + + void sv_execute_client_message_stub(game::mp::client_t* client, game::msg_t* msg) + { + if (client->reliableAcknowledge < 0) + { + client->reliableAcknowledge = client->reliableSequence; + console::info("Negative reliableAcknowledge from %s - cl->reliableSequence is %i, reliableAcknowledge is %i\n", + client->name, client->reliableSequence, client->reliableAcknowledge); + network::send(client->header.remoteAddress, "error", "EXE_LOSTRELIABLECOMMANDS", '\n'); + return; + } + + utils::hook::invoke(0x140481A00, client, msg); + } + + void aim_assist_add_to_target_list(void* a1, void* a2) + { + if (!dvars::aimassist_enabled->current.enabled) + return; + + game::AimAssist_AddToTargetList(a1, a2); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + // Register dvars + com_register_dvars_hook.create(SELECT_VALUE(0x140351B80, 0x1400D9320), &com_register_dvars_stub); // H1(1.4) + + // Unlock fps in main menu + utils::hook::set(SELECT_VALUE(0x14018D47B, 0x14025B86B), 0xEB); // H1(1.4) + + if (!game::environment::is_dedi()) + { + // Fix mouse lag + utils::hook::nop(SELECT_VALUE(0x1403E3C05, 0x1404DB1AF), 6); + scheduler::loop([]() + { + SetThreadExecutionState(ES_DISPLAY_REQUIRED); + }, scheduler::pipeline::main); + } + + // Make cg_fov and cg_fovscale saved dvars + dvars::override::register_float("cg_fov", 65.f, 40.f, 200.f, game::DvarFlags::DVAR_FLAG_SAVED); + dvars::override::register_float("cg_fovScale", 1.f, 0.1f, 2.f, game::DvarFlags::DVAR_FLAG_SAVED); + + // Allow kbam input when gamepad is enabled + utils::hook::nop(SELECT_VALUE(0x14018797E, 0x14024EF60), 2); + utils::hook::nop(SELECT_VALUE(0x1401856DC, 0x14024C6B0), 6); + + // Allow executing custom cfg files with the "exec" command + utils::hook::call(SELECT_VALUE(0x140343855, 0x140403E28), db_read_raw_file_stub); + + if (!game::environment::is_sp()) + { + patch_mp(); + } + } + + static void patch_mp() + { + // Use name dvar + utils::hook::jump(0x14050FF90, &live_get_local_client_name); // H1(1.4) + + // Patch SV_KickClientNum + sv_kick_client_num_hook.create(0x14047ED00, &sv_kick_client_num); // H1(1.4) + + // block changing name in-game + utils::hook::set(0x14047FC90, 0xC3); // H1(1.4) + + // patch "Couldn't find the bsp for this map." error to not be fatal in mp + utils::hook::call(0x1402BA26B, bsp_sys_error_stub); // H1(1.4) + + // client side aim assist dvar + dvars::aimassist_enabled = dvars::register_bool("aimassist_enabled", true, + game::DvarFlags::DVAR_FLAG_SAVED, + true); + utils::hook::call(0x14009EE9E, aim_assist_add_to_target_list); + + // unlock all items + utils::hook::jump(0x140413E60, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable_LocalClient H1(1.4) + utils::hook::jump(0x140413860, is_item_unlocked); // LiveStorage_IsItemUnlockedFromTable H1(1.4) + utils::hook::jump(0x140412B70, is_item_unlocked); // idk ( unlocks loot etc ) H1(1.4) + + // isProfanity + utils::hook::set(0x1402877D0, 0xC3C033); // MAY BE WRONG H1(1.4) + + // disable emblems + dvars::override::register_int("emblems_active", 0, 0, 0, game::DVAR_FLAG_NONE); + utils::hook::set(0x140479590, 0xC3); // don't register commands + + // disable elite_clan + dvars::override::register_int("elite_clan_active", 0, 0, 0, game::DVAR_FLAG_NONE); + utils::hook::set(0x140585680, 0xC3); // don't register commands H1(1.4) + + // disable codPointStore + dvars::override::register_int("codPointStore_enabled", 0, 0, 0, game::DVAR_FLAG_NONE); + + // don't register every replicated dvar as a network dvar + utils::hook::nop(0x14039E58E, 5); // dvar_foreach H1(1.4) + + // patch "Server is different version" to show the server client version + utils::hook::inject(0x140480952, VERSION); // H1(1.4) + + // prevent servers overriding our fov + utils::hook::call(0x14023279E, set_client_dvar_from_server_stub); + utils::hook::nop(0x1400DAF69, 5); + utils::hook::nop(0x140190C16, 5); + utils::hook::set(0x14021D22A, 0xEB); + + // unlock safeArea_* + utils::hook::jump(0x1402624F5, 0x140262503); // H1(1.4) + utils::hook::jump(0x14026251C, 0x140262547); // H1(1.4) + dvars::override::register_int("safeArea_adjusted_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_int("safeArea_adjusted_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_int("safeArea_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_int("safeArea_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); + + // move chat position on the screen above menu splashes + dvars::override::register_vec2("cg_hudChatPosition", 5, 170, 0, 640, game::DVAR_FLAG_SAVED); + + // allow servers to check for new packages more often + dvars::override::register_int("sv_network_fps", 1000, 20, 1000, game::DVAR_FLAG_SAVED); + + // Massively increate timeouts + dvars::override::register_int("cl_timeout", 90, 90, 1800, game::DVAR_FLAG_NONE); // Seems unused + dvars::override::register_int("sv_timeout", 90, 90, 1800, game::DVAR_FLAG_NONE); // 30 - 0 - 1800 + dvars::override::register_int("cl_connectTimeout", 120, 120, 1800, game::DVAR_FLAG_NONE); // Seems unused + dvars::override::register_int("sv_connectTimeout", 120, 120, 1800, game::DVAR_FLAG_NONE); // 60 - 0 - 1800 + + dvars::register_int("scr_game_spectatetype", 1, 0, 99, game::DVAR_FLAG_REPLICATED); + + dvars::override::register_int("com_maxfps", 0, 10, 1000, game::DVAR_FLAG_SAVED); + + // Prevent clients from ending the game as non host by sending 'end_game' lui notification + // cmd_lui_notify_server_hook.create(0x140335A70, cmd_lui_notify_server_stub); // H1(1.4) + + // Prevent clients from sending invalid reliableAcknowledge + // utils::hook::call(0x1404899C6, sv_execute_client_message_stub); // H1(1.4) + + // "fix" for rare 'Out of memory error' error + if (utils::flags::has_flag("memoryfix")) + { + utils::hook::jump(0x140578BE0, malloc); + utils::hook::jump(0x140578B00, _aligned_malloc); + utils::hook::jump(0x140578C40, free); + utils::hook::jump(0x140578D30, realloc); + utils::hook::jump(0x140578B60, _aligned_realloc); + } + + // Change default hostname and make it replicated + dvars::override::register_string("sv_hostname", "^2H1-Mod^7 Default Server", game::DVAR_FLAG_REPLICATED); + } + }; +} + +REGISTER_COMPONENT(patches::component) diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp new file mode 100644 index 00000000..b315be76 --- /dev/null +++ b/src/client/component/renderer.cpp @@ -0,0 +1,77 @@ +#include +#include "loader/component_loader.hpp" +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include + +namespace renderer +{ + namespace + { + utils::hook::detour r_init_draw_method_hook; + utils::hook::detour r_update_front_end_dvar_options_hook; + + int get_fullbright_technique() + { + return game::TECHNIQUE_UNLIT; + } + + void gfxdrawmethod() + { + game::gfxDrawMethod->drawScene = game::GFX_DRAW_SCENE_STANDARD; + + game::gfxDrawMethod->baseTechType = dvars::r_fullbright->current.enabled ? get_fullbright_technique() : game::TECHNIQUE_LIT; + game::gfxDrawMethod->emissiveTechType = dvars::r_fullbright->current.enabled ? get_fullbright_technique() : game::TECHNIQUE_EMISSIVE; + game::gfxDrawMethod->forceTechType = dvars::r_fullbright->current.enabled ? get_fullbright_technique() : 242; + } + + void r_init_draw_method_stub() + { + gfxdrawmethod(); + } + + bool r_update_front_end_dvar_options_stub() + { + if (dvars::r_fullbright->modified) + { + //game::Dvar_ClearModified(dvars::r_fullbright); + game::R_SyncRenderThread(); + + gfxdrawmethod(); + } + + return r_update_front_end_dvar_options_hook.invoke(); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_dedi() || !game::environment::is_mp()) + { + return; + } + + dvars::r_fullbright = dvars::register_int("r_fullbright", 0, 0, 3, game::DVAR_FLAG_SAVED); + + r_init_draw_method_hook.create(SELECT_VALUE(0x1404BD140, 0x1405C46E0), &r_init_draw_method_stub); + r_update_front_end_dvar_options_hook.create(SELECT_VALUE(0x1404F8870, 0x1405FF9E0), &r_update_front_end_dvar_options_stub); + + // use "saved" flags for "r_normalMap" + utils::hook::set(SELECT_VALUE(0x1404CF5CA, 0x1405D460E), game::DVAR_FLAG_SAVED); + + // use "saved" flags for "r_specularMap" + utils::hook::set(SELECT_VALUE(0x1404CF5F5, 0x1405D4639), game::DVAR_FLAG_SAVED); + + // use "saved" flags for "r_specOccMap" + utils::hook::set(SELECT_VALUE(0x1404CF620, 0x1405D4664), game::DVAR_FLAG_SAVED); + } + }; +} + +#ifdef DEBUG +REGISTER_COMPONENT(renderer::component) +#endif \ No newline at end of file diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index 9a8911eb..ac837128 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -180,9 +180,9 @@ namespace scheduler void post_unpack() override { - r_end_frame_hook.create(SELECT_VALUE(0, 0x6A6300_b), scheduler::r_end_frame_stub); - g_run_frame_hook.create(SELECT_VALUE(0, 0x417940_b), scheduler::server_frame_stub); - main_frame_hook.create(SELECT_VALUE(0, 0x1400D8310), scheduler::main_frame_stub); // I REPEAT, ARXAN IS PAIN + r_end_frame_hook.create(SELECT_VALUE(0, 0x6A6300_b), scheduler::r_end_frame_stub); // H1-STEAM(1.15) + g_run_frame_hook.create(SELECT_VALUE(0, 0x417940_b), scheduler::server_frame_stub); // H1(1.15) + //main_frame_hook.create(SELECT_VALUE(0x1401CE8D0, 0x1400D8310), scheduler::main_frame_stub); can't find } void pre_destroy() override @@ -196,4 +196,4 @@ namespace scheduler }; } -REGISTER_COMPONENT(scheduler::component) \ No newline at end of file +REGISTER_COMPONENT(scheduler::component) diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp new file mode 100644 index 00000000..e3116122 --- /dev/null +++ b/src/client/component/scripting.cpp @@ -0,0 +1,141 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include + +#include "game/scripting/entity.hpp" +#include "game/scripting/functions.hpp" +#include "game/scripting/event.hpp" +#include "game/scripting/lua/engine.hpp" +#include "game/scripting/execution.hpp" + +#include "scheduler.hpp" +#include "scripting.hpp" + +namespace scripting +{ + std::unordered_map> fields_table; + std::unordered_map> script_function_table; + + namespace + { + utils::hook::detour vm_notify_hook; + utils::hook::detour scr_load_level_hook; + utils::hook::detour g_shutdown_game_hook; + + utils::hook::detour scr_add_class_field_hook; + + utils::hook::detour scr_set_thread_position_hook; + utils::hook::detour process_script_hook; + + std::string current_file; + + void vm_notify_stub(const unsigned int notify_list_owner_id, const game::scr_string_t string_value, + game::VariableValue* top) + { + if (!game::VirtualLobby_Loaded()) + { + const auto* string = game::SL_ConvertToString(string_value); + if (string) + { + event e; + e.name = string; + e.entity = notify_list_owner_id; + + for (auto* value = top; value->type != game::SCRIPT_END; --value) + { + e.arguments.emplace_back(*value); + } + + if (e.name == "entitydeleted") + { + scripting::clear_entity_fields(e.entity); + } + + lua::engine::notify(e); + } + } + + vm_notify_hook.invoke(notify_list_owner_id, string_value, top); + } + + void scr_load_level_stub() + { + scr_load_level_hook.invoke(); + if (!game::VirtualLobby_Loaded()) + { + lua::engine::start(); + } + } + + void g_shutdown_game_stub(const int free_scripts) + { + lua::engine::stop(); + return g_shutdown_game_hook.invoke(free_scripts); + } + + void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t _name, unsigned int canonicalString, unsigned int offset) + { + const auto name = game::SL_ConvertToString(_name); + + if (fields_table[classnum].find(name) == fields_table[classnum].end()) + { + fields_table[classnum][name] = offset; + } + + scr_add_class_field_hook.invoke(classnum, _name, canonicalString, offset); + } + + void process_script_stub(const char* filename) + { + const auto file_id = atoi(filename); + if (file_id) + { + current_file = scripting::find_token(file_id); + } + else + { + current_file = filename; + } + + process_script_hook.invoke(filename); + } + + void scr_set_thread_position_stub(unsigned int threadName, const char* codePos) + { + const auto function_name = scripting::find_token(threadName); + script_function_table[current_file][function_name] = codePos; + scr_set_thread_position_hook.invoke(threadName, codePos); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (game::environment::is_sp()) + { + return; + } + + vm_notify_hook.create(SELECT_VALUE(0x140379A00, 0x1404479F0), vm_notify_stub); + + scr_add_class_field_hook.create(SELECT_VALUE(0x140370370, 0x14043E2C0), scr_add_class_field_stub); + + scr_set_thread_position_hook.create(SELECT_VALUE(0x14036A180, 0x140437D10), scr_set_thread_position_stub); + process_script_hook.create(SELECT_VALUE(0x1403737E0, 0x1404417E0), process_script_stub); + + scr_load_level_hook.create(SELECT_VALUE(0x1402A5BE0, 0x1403727C0), scr_load_level_stub); + g_shutdown_game_hook.create(SELECT_VALUE(0x140277D40, 0x140345A60), g_shutdown_game_stub); + + scheduler::loop([]() + { + lua::engine::run_frame(); + }, scheduler::pipeline::server); + } + }; +} + +REGISTER_COMPONENT(scripting::component) \ No newline at end of file diff --git a/src/client/component/scripting.hpp b/src/client/component/scripting.hpp new file mode 100644 index 00000000..865ae858 --- /dev/null +++ b/src/client/component/scripting.hpp @@ -0,0 +1,8 @@ +#pragma once +#include + +namespace scripting +{ + extern std::unordered_map> fields_table; + extern std::unordered_map> script_function_table; +} \ No newline at end of file diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp new file mode 100644 index 00000000..1b7e759e --- /dev/null +++ b/src/client/component/server_list.cpp @@ -0,0 +1,443 @@ +#include +#include "loader/component_loader.hpp" +#include "server_list.hpp" +#include "localized_strings.hpp" +#include "network.hpp" +#include "scheduler.hpp" +#include "party.hpp" +#include "game/game.hpp" + +#include +#include +#include + +#include "console.hpp" +#include "command.hpp" + +namespace server_list +{ + namespace + { + const int server_limit = 18; + + struct server_info + { + // gotta add more to this + int clients; + int max_clients; + int bots; + int ping; + std::string host_name; + std::string map_name; + std::string game_type; + game::CodPlayMode play_mode; + char in_game; + game::netadr_s address; + }; + + struct + { + game::netadr_s address{}; + volatile bool requesting = false; + std::unordered_map queued_servers{}; + } master_state; + + std::mutex mutex; + std::vector servers; + + size_t server_list_page = 0; + volatile bool update_server_list = false; + std::chrono::high_resolution_clock::time_point last_scroll{}; + + size_t get_page_count() + { + const auto count = servers.size() / server_limit; + return count + (servers.size() % server_limit > 0); + } + + size_t get_page_base_index() + { + return server_list_page * server_limit; + } + + void refresh_server_list() + { + { + std::lock_guard _(mutex); + servers.clear(); + master_state.queued_servers.clear(); + server_list_page = 0; + } + + party::reset_connect_state(); + + if (get_master_server(master_state.address)) + { + master_state.requesting = true; + + network::send(master_state.address, "getservers", utils::string::va("H1 %i full empty", PROTOCOL)); + } + } + + void join_server(int, int, const int index) + { + std::lock_guard _(mutex); + + const auto i = static_cast(index) + get_page_base_index(); + if (i < servers.size()) + { + static auto last_index = ~0ull; + if (last_index != i) + { + last_index = i; + } + else + { + console::info("Connecting to (%d - %zu): %s\n", index, i, servers[i].host_name.data()); + party::connect(servers[i].address); + } + } + } + + void trigger_refresh() + { + update_server_list = true; + } + + int ui_feeder_count() + { + std::lock_guard _(mutex); + if (update_server_list) + { + update_server_list = false; + return 0; + } + const auto count = static_cast(servers.size()); + const auto index = get_page_base_index(); + const auto diff = count - index; + return diff > server_limit ? server_limit : static_cast(diff); + } + + const char* ui_feeder_item_text(int /*localClientNum*/, void* /*a2*/, void* /*a3*/, const int index, + const int column) + { + std::lock_guard _(mutex); + + const auto i = get_page_base_index() + index; + + if (i >= servers.size()) + { + return ""; + } + + if (column == 0) + { + return servers[i].host_name.empty() ? "" : utils::string::va("%s", servers[i].host_name.data()); + } + + if (column == 1) + { + return servers[i].map_name.empty() ? "Unknown" : utils::string::va("%s", servers[i].map_name.data()); + } + + if (column == 2) + { + return utils::string::va("%d/%d [%d]", servers[i].clients, servers[index].max_clients, + servers[i].bots); + } + + if (column == 3) + { + return servers[i].game_type.empty() ? "" : utils::string::va("%s", servers[i].game_type.data()); + } + + if (column == 4) + { + return servers[i].game_type.empty() ? "" : utils::string::va("%i", servers[i].ping); + } + + return ""; + } + + void sort_serverlist() + { + std::stable_sort(servers.begin(), servers.end(), [](const server_info& a, const server_info& b) + { + if (a.clients == b.clients) + { + return a.ping < b.ping; + } + + return a.clients > b.clients; + }); + } + + void insert_server(server_info&& server) + { + std::lock_guard _(mutex); + servers.emplace_back(std::move(server)); + sort_serverlist(); + trigger_refresh(); + } + + void do_frame_work() + { + auto& queue = master_state.queued_servers; + if (queue.empty()) + { + return; + } + + std::lock_guard _(mutex); + + size_t queried_servers = 0; + const size_t query_limit = 3; + + for (auto i = queue.begin(); i != queue.end();) + { + if (i->second) + { + const auto now = game::Sys_Milliseconds(); + if (now - i->second > 10'000) + { + i = queue.erase(i); + continue; + } + } + else if (queried_servers++ < query_limit) + { + i->second = game::Sys_Milliseconds(); + network::send(i->first, "getInfo", utils::cryptography::random::get_challenge()); + } + + ++i; + } + } + + bool is_server_list_open() + { + return game::Menu_IsMenuOpenAndVisible(0, "menu_systemlink_join"); + } + + bool is_scrolling_disabled() + { + return update_server_list || (std::chrono::high_resolution_clock::now() - last_scroll) < 500ms; + } + + bool scroll_down() + { + if (!is_server_list_open()) + { + return false; + } + + if (!is_scrolling_disabled() && server_list_page + 1 < get_page_count()) + { + last_scroll = std::chrono::high_resolution_clock::now(); + ++server_list_page; + trigger_refresh(); + } + + return true; + } + + bool scroll_up() + { + if (!is_server_list_open()) + { + return false; + } + + if (!is_scrolling_disabled() && server_list_page > 0) + { + last_scroll = std::chrono::high_resolution_clock::now(); + --server_list_page; + trigger_refresh(); + } + + return true; + } + + void resize_host_name(std::string& name) + { + name = utils::string::split(name, '\n').front(); + + game::Font_s* font = game::R_RegisterFont("fonts/default.otf", 18); + auto text_size = game::UI_TextWidth(name.data(), 32, font, 1.0f); + + while (text_size > 450) + { + text_size = game::UI_TextWidth(name.data(), 32, font, 1.0f); + name.pop_back(); + } + } + + utils::hook::detour lui_open_menu_hook; + + void lui_open_menu_stub(int controllerIndex, const char* menu, int a3, int a4, unsigned int a5) + { +#ifdef DEBUG + console::info("[LUI] %s\n", menu); +#endif + + if (!strcmp(menu, "menu_systemlink_join")) + { + refresh_server_list(); + } + + lui_open_menu_hook.invoke(controllerIndex, menu, a3, a4, a5); + } + } + + bool sl_key_event(const int key, const int down) + { + if (down) + { + if (key == game::keyNum_t::K_MWHEELUP) + { + return !scroll_up(); + } + + if (key == game::keyNum_t::K_MWHEELDOWN) + { + return !scroll_down(); + } + } + + return true; + } + + bool get_master_server(game::netadr_s& address) + { + return game::NET_StringToAdr("135.148.53.121:20810", &address); + // return game::NET_StringToAdr("master.xlabs.dev:20810", &address); + } + + void handle_info_response(const game::netadr_s& address, const utils::info_string& info) + { + // Don't show servers that aren't dedicated! + const auto dedicated = std::atoi(info.get("dedicated").data()); + if (!dedicated) + { + return; + } + + // Don't show servers that aren't running! + const auto sv_running = std::atoi(info.get("sv_running").data()); + if (!sv_running) + { + return; + } + + // Only handle servers of the same playmode! + const auto playmode = game::CodPlayMode(std::atoi(info.get("playmode").data())); + if (game::Com_GetCurrentCoDPlayMode() != playmode) + { + return; + } + + int start_time{}; + const auto now = game::Sys_Milliseconds(); + + { + std::lock_guard _(mutex); + const auto entry = master_state.queued_servers.find(address); + + if (entry == master_state.queued_servers.end() || !entry->second) + { + return; + } + + start_time = entry->second; + master_state.queued_servers.erase(entry); + } + + server_info server{}; + server.address = address; + server.host_name = info.get("hostname"); + server.map_name = game::UI_GetMapDisplayName(info.get("mapname").data()); + server.game_type = game::UI_GetGameTypeDisplayName(info.get("gametype").data()); + server.play_mode = playmode; + server.clients = atoi(info.get("clients").data()); + server.max_clients = atoi(info.get("sv_maxclients").data()); + server.bots = atoi(info.get("bots").data()); + server.ping = std::min(now - start_time, 999); + + server.in_game = 1; + + resize_host_name(server.host_name); + + insert_server(std::move(server)); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (!game::environment::is_mp()) return; + + localized_strings::override("PLATFORM_SYSTEM_LINK_TITLE", "SERVER LIST"); + + // hook LUI_OpenMenu to refresh server list for system link menu + lui_open_menu_hook.create(game::LUI_OpenMenu, lui_open_menu_stub); + + // replace UI_RunMenuScript call in LUI_CoD_LuaCall_RefreshServerList to our refresh_servers + utils::hook::call(0x14018A0C9, &refresh_server_list); + utils::hook::call(0x14018A5DE, &join_server); + utils::hook::nop(0x14018A5FD, 5); + + // do feeder stuff + utils::hook::call(0x14018A199, &ui_feeder_count); + utils::hook::call(0x14018A3B1, &ui_feeder_item_text); + + scheduler::loop(do_frame_work, scheduler::pipeline::main); + + network::on("getServersResponse", [](const game::netadr_s& target, const std::string_view& data) + { + { + std::lock_guard _(mutex); + if (!master_state.requesting || master_state.address != target) + { + return; + } + + master_state.requesting = false; + + std::optional start{}; + for (size_t i = 0; i + 6 < data.size(); ++i) + { + if (data[i + 6] == '\\') + { + start.emplace(i); + break; + } + } + + if (!start.has_value()) + { + return; + } + + for (auto i = start.value(); i + 6 < data.size(); i += 7) + { + if (data[i + 6] != '\\') + { + break; + } + + game::netadr_s address{}; + address.type = game::NA_IP; + address.localNetID = game::NS_CLIENT1; + memcpy(&address.ip[0], data.data() + i + 0, 4); + memcpy(&address.port, data.data() + i + 4, 2); + + master_state.queued_servers[address] = 0; + } + } + }); + } + }; +} + +REGISTER_COMPONENT(server_list::component) diff --git a/src/client/component/server_list.hpp b/src/client/component/server_list.hpp new file mode 100644 index 00000000..d9974cfa --- /dev/null +++ b/src/client/component/server_list.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "game/game.hpp" +#include + +namespace server_list +{ + bool get_master_server(game::netadr_s& address); + void handle_info_response(const game::netadr_s& address, const utils::info_string& info); + + bool sl_key_event(int key, int down); +} \ No newline at end of file diff --git a/src/client/component/shaders.cpp b/src/client/component/shaders.cpp new file mode 100644 index 00000000..ec632115 --- /dev/null +++ b/src/client/component/shaders.cpp @@ -0,0 +1,50 @@ +#include +#include "loader/component_loader.hpp" + +#include "scheduler.hpp" +#include "dvars.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include + +namespace shaders +{ + namespace + { + game::dvar_t* disable_shader_caching = nullptr; + + bool shader_should_show_dialog_stub() + { + return !disable_shader_caching->current.enabled; + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (!game::environment::is_mp()) + { + return; + } + + const auto has_flag = utils::flags::has_flag("noshadercaching"); + + disable_shader_caching = dvars::register_bool("disable_shader_caching", has_flag, game::DVAR_FLAG_SAVED, true); + if (has_flag) + { + dvars::override::set_bool("disable_shader_caching", 1); + dvars::override::set_from_string("disable_shader_caching", "1"); + } + + utils::hook::jump(0x14007E710, shader_should_show_dialog_stub); + } + }; +} + +REGISTER_COMPONENT(shaders::component) diff --git a/src/client/component/slowmotion.cpp b/src/client/component/slowmotion.cpp new file mode 100644 index 00000000..71f66dbf --- /dev/null +++ b/src/client/component/slowmotion.cpp @@ -0,0 +1,53 @@ +#include +#include "loader/component_loader.hpp" +#include "game/game.hpp" + +#include +#include + +namespace slowmotion +{ + namespace + { + void scr_cmd_set_slow_motion() + { + if (game::Scr_GetNumParam() < 1) + { + return; + } + + int duration = 1000; + float end = 1.0f; + const float start = game::Scr_GetFloat(0); + + if (game::Scr_GetNumParam() >= 2) + { + end = game::Scr_GetFloat(1u); + } + + if (game::Scr_GetNumParam() >= 3) + { + duration = static_cast(game::Scr_GetFloat(2u) * 1000.0f); + } + + game::SV_SetConfigstring(10, utils::string::va("%i %i %g %g", *game::mp::gameTime, duration, start, end)); + game::Com_SetSlowMotion(start, end, duration); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (!game::environment::is_dedi()) + { + return; + } + + utils::hook::jump(0x140365480, scr_cmd_set_slow_motion); // H1(1.4) + } + }; +} + +REGISTER_COMPONENT(slowmotion::component) diff --git a/src/client/component/splash.cpp b/src/client/component/splash.cpp new file mode 100644 index 00000000..3dfd6541 --- /dev/null +++ b/src/client/component/splash.cpp @@ -0,0 +1,141 @@ +#include +#include "loader/component_loader.hpp" +#include "game/game.hpp" +#include "game_module.hpp" + +#include +#include + +namespace splash +{ + class component final : public component_interface + { + public: + void post_start() override + { + const utils::nt::library self; + image_ = LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); + } + + void post_load() override + { + if (game::environment::is_dedi()) + { + return; + } + + this->show(); + } + + void post_unpack() override + { + // Disable native splash screen + //utils::hook::nop(SELECT_VALUE(0x1403E192E, 0x1405123E2), 5); // winmain doesn't even exist in 1.15? lmao + utils::hook::jump(SELECT_VALUE(0, 0x5BE1D0_b), destroy_stub); // H1-STEAM(1.15) + utils::hook::jump(SELECT_VALUE(0, 0x5BE210_b), destroy_stub); // H1-STEAM(1.15) + } + + void pre_destroy() override + { + this->destroy(); + + MSG msg; + while (this->window_ && IsWindow(this->window_)) + { + if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + else + { + std::this_thread::sleep_for(1ms); + } + } + + this->window_ = nullptr; + } + + private: + HWND window_{}; + HANDLE image_{}; + + static void destroy_stub() + { + component_loader::get()->destroy(); + } + + void destroy() const + { + if (this->window_ && IsWindow(this->window_)) + { + ShowWindow(this->window_, SW_HIDE); + DestroyWindow(this->window_); + UnregisterClassA("H1 Splash Screen", utils::nt::library{}); + } + } + + void show() + { + WNDCLASSA wnd_class; + + const auto self = game_module::get_host_module(); + + wnd_class.style = CS_DROPSHADOW; + wnd_class.cbClsExtra = 0; + wnd_class.cbWndExtra = 0; + wnd_class.lpszMenuName = nullptr; + wnd_class.lpfnWndProc = DefWindowProcA; + wnd_class.hInstance = self; + wnd_class.hIcon = LoadIconA(self, reinterpret_cast(102)); + wnd_class.hCursor = LoadCursorA(nullptr, IDC_APPSTARTING); + wnd_class.hbrBackground = reinterpret_cast(6); + wnd_class.lpszClassName = "H1 Splash Screen"; + + if (RegisterClassA(&wnd_class)) + { + const auto x_pixels = GetSystemMetrics(SM_CXFULLSCREEN); + const auto y_pixels = GetSystemMetrics(SM_CYFULLSCREEN); + + if (image_) + { + this->window_ = CreateWindowExA(WS_EX_APPWINDOW, "H1 Splash Screen", "H1", + WS_POPUP | WS_SYSMENU, + (x_pixels - 320) / 2, (y_pixels - 100) / 2, 320, 100, nullptr, + nullptr, + self, nullptr); + + if (this->window_) + { + auto* const image_window = CreateWindowExA(0, "Static", nullptr, WS_CHILD | WS_VISIBLE | 0xEu, + 0, 0, + 320, 100, this->window_, nullptr, self, nullptr); + if (image_window) + { + RECT rect; + SendMessageA(image_window, 0x172u, 0, reinterpret_cast(image_)); + GetWindowRect(image_window, &rect); + + const int width = rect.right - rect.left; + rect.left = (x_pixels - width) / 2; + + const int height = rect.bottom - rect.top; + rect.top = (y_pixels - height) / 2; + + rect.right = rect.left + width; + rect.bottom = rect.top + height; + AdjustWindowRect(&rect, WS_CHILD | WS_VISIBLE | 0xEu, 0); + SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, SWP_NOZORDER); + + ShowWindow(this->window_, SW_SHOW); + UpdateWindow(this->window_); + } + } + } + } + } + }; +} + +REGISTER_COMPONENT(splash::component) diff --git a/src/client/component/system_check.cpp b/src/client/component/system_check.cpp index e3631248..9c88bd5c 100644 --- a/src/client/component/system_check.cpp +++ b/src/client/component/system_check.cpp @@ -51,28 +51,27 @@ namespace system_check { static std::unordered_map mp_zone_hashes = { - {"patch_common_mp.ff", "E45EF5F29D12A5A47F405F89FBBEE479C0A90D02141ABF852D481689514134A1"}, + {"patch_common_mp.ff", "3F44B0CFB0B8E0FBD9687C2942204AB7F11E66E6E15C73B8B4A5EB5920115A31"}, }; static std::unordered_map sp_zone_hashes = { // Steam doesn't necessarily deliver this file :( - {"patch_common.ff", "1D32A9770F90ED022AA76F4859B4AB178E194A703383E61AC2CE83B1E828B18F"}, + {"patch_common.ff", "BB0617DD94AF2F511571E7184BBEDE76E64D97E5D0DAFDB457F00717F035EBF0"}, }; return verify_hashes(mp_zone_hashes) && (game::environment::is_dedi() || verify_hashes(sp_zone_hashes)); } - //void verify_binary_version() - //{ - // if (*(int*)(uint64_t(GetModuleHandle(NULL)) + 0x4CCD3D) != 1251288) - // { - // MessageBoxA(0, "UNSUPPORTED VERSION MWR(1.15)", "H1MP-STEAM", MB_ICONWARNING); - - // return; - // } - //} + void verify_binary_version() + { + const auto value = *reinterpret_cast(0x140001337); + if (value != 0xFFB8006D && value != 0xFFB80080) + { + throw std::runtime_error("Unsupported Call of Duty: Modern Warfare Remastered version(1.4)"); + } + } } bool is_valid() @@ -86,12 +85,12 @@ namespace system_check public: void post_load() override { - //verify_binary_version(); + verify_binary_version(); if (!is_valid()) { MessageBoxA(nullptr, "Your game files are outdated or unsupported.\n" - "Please get the latest officially supported Call of Duty: Modern Warfare Remastered 1.15 STEAM files, or you will get random crashes and issues.", + "Please get the latest officially supported Call of Duty: Modern Warfare Remastered 1.4 files, or you will get random crashes and issues.", "Invalid game files!", MB_ICONINFORMATION); } } diff --git a/src/client/component/thread_names.cpp b/src/client/component/thread_names.cpp new file mode 100644 index 00000000..84b5fa70 --- /dev/null +++ b/src/client/component/thread_names.cpp @@ -0,0 +1,60 @@ +#include +#include "loader/component_loader.hpp" + +#include "scheduler.hpp" + +#include "game/game.hpp" + +#include + +namespace thread_names +{ + namespace + { + void set_thread_names() + { + static std::unordered_map thread_names = + { + {game::THREAD_CONTEXT_MAIN, "Main"}, + {game::THREAD_CONTEXT_BACKEND, "Backend"}, // Renderer + {game::THREAD_CONTEXT_WORKER0, "Worker0"}, + {game::THREAD_CONTEXT_WORKER1, "Worker1"}, + {game::THREAD_CONTEXT_WORKER2, "Worker2"}, + {game::THREAD_CONTEXT_WORKER3, "Worker3"}, + {game::THREAD_CONTEXT_WORKER4, "Worker4"}, + {game::THREAD_CONTEXT_WORKER5, "Worker5"}, + {game::THREAD_CONTEXT_WORKER6, "Worker6"}, + {game::THREAD_CONTEXT_WORKER7, "Worker7"}, + {game::THREAD_CONTEXT_SERVER, "Server"}, + {game::THREAD_CONTEXT_CINEMATIC, "Cinematic"}, + {game::THREAD_CONTEXT_DATABASE, "Database"}, + {game::THREAD_CONTEXT_STREAM, "Stream"}, + {game::THREAD_CONTEXT_SNDSTREAMPACKETCALLBACK, "Snd stream packet callback"}, + {game::THREAD_CONTEXT_STATS_WRITE, "Stats write"}, + }; + + for (const auto& thread_name : thread_names) + { + const auto id = game::threadIds[thread_name.first]; + if (id) + { + utils::thread::set_name(id, thread_name.second); + } + } + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + set_thread_names(); + scheduler::once(set_thread_names, scheduler::pipeline::main); + scheduler::once(set_thread_names, scheduler::pipeline::renderer); + scheduler::once(set_thread_names, scheduler::pipeline::server); + } + }; +} + +REGISTER_COMPONENT(thread_names::component) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp new file mode 100644 index 00000000..941dda10 --- /dev/null +++ b/src/client/component/ui_scripting.cpp @@ -0,0 +1,180 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "scheduler.hpp" +#include "command.hpp" + +#include "ui_scripting.hpp" + +#include "game/ui_scripting/lua/engine.hpp" +#include "game/ui_scripting/execution.hpp" +#include "game/ui_scripting/lua/error.hpp" + +#include +#include + +namespace ui_scripting +{ + namespace + { + std::unordered_map converted_functions; + + utils::hook::detour hksi_lual_error_hook; + utils::hook::detour hksi_lual_error_hook2; + utils::hook::detour hks_start_hook; + utils::hook::detour hks_shutdown_hook; + utils::hook::detour hks_allocator_hook; + utils::hook::detour hks_frame_hook; + + bool error_hook_enabled = false; + + void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...) + { + char va_buffer[2048] = {0}; + + va_list ap; + va_start(ap, fmt); + vsprintf_s(va_buffer, fmt, ap); + va_end(ap); + + const auto formatted = std::string(va_buffer); + + if (!error_hook_enabled) + { + return hksi_lual_error_hook.invoke(s, formatted.data()); + } + else + { + throw std::runtime_error(formatted); + } + } + + void* hks_start_stub(char a1) + { + const auto _1 = gsl::finally([]() + { + ui_scripting::lua::engine::start(); + }); + + return hks_start_hook.invoke(a1); + } + + void hks_shutdown_stub() + { + ui_scripting::lua::engine::stop(); + hks_shutdown_hook.invoke(); + } + + void* hks_allocator_stub(void* userData, void* oldMemory, unsigned __int64 oldSize, unsigned __int64 newSize) + { + const auto closure = reinterpret_cast(oldMemory); + if (converted_functions.find(closure) != converted_functions.end()) + { + converted_functions.erase(closure); + } + + return hks_allocator_hook.invoke(userData, oldMemory, oldSize, newSize); + } + + void hks_frame_stub() + { + const auto state = *game::hks::lua_state; + if (state) + { + ui_scripting::lua::engine::run_frame(); + } + } + } + + int main_function_handler(game::hks::lua_State* state) + { + const auto value = state->m_apistack.base[-1]; + if (value.t != game::hks::TCFUNCTION) + { + return 0; + } + + const auto closure = reinterpret_cast(value.v.cClosure); + if (converted_functions.find(closure) == converted_functions.end()) + { + return 0; + } + + const auto function = converted_functions[closure]; + const auto count = static_cast(state->m_apistack.top - state->m_apistack.base); + const auto arguments = get_return_values(count); + const auto s = function.lua_state(); + + std::vector converted_args; + + for (const auto& argument : arguments) + { + converted_args.push_back(lua::convert(s, argument)); + } + + const auto results = function(sol::as_args(converted_args)); + lua::handle_error(results); + + for (const auto& result : results) + { + push_value(lua::convert({s, result})); + } + + return results.return_count(); + } + + void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function) + { + converted_functions[closure] = function; + } + + void clear_converted_functions() + { + converted_functions.clear(); + } + + void enable_error_hook() + { + error_hook_enabled = true; + } + + void disable_error_hook() + { + error_hook_enabled = false; + } + + class component final : public component_interface + { + public: + + void post_unpack() override + { + if (game::environment::is_dedi()) + { + return; + } + + hks_start_hook.create(SELECT_VALUE(0x1400E4B40, 0x140176A40), hks_start_stub); + hks_shutdown_hook.create(SELECT_VALUE(0x1400DD3D0, 0x14016CA80), hks_shutdown_stub); + hksi_lual_error_hook.create(SELECT_VALUE(0x1400A5EA0, 0x14012F300), hksi_lual_error_stub); + hks_allocator_hook.create(SELECT_VALUE(0x14009B570, 0x14012BAC0), hks_allocator_stub); + hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), hks_frame_stub); + + if (game::environment::is_mp()) + { + hksi_lual_error_hook2.create(0x1401366B0, hksi_lual_error_stub); + } + + command::add("lui_restart", []() + { + utils::hook::invoke(SELECT_VALUE(0x1400DD3D0, 0x14016CA80)); + utils::hook::invoke(SELECT_VALUE(0x1400E6170, 0x1401780D0)); + }); + } + }; +} + +REGISTER_COMPONENT(ui_scripting::component) \ No newline at end of file diff --git a/src/client/component/ui_scripting.hpp b/src/client/component/ui_scripting.hpp new file mode 100644 index 00000000..2a48f6ec --- /dev/null +++ b/src/client/component/ui_scripting.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "game/ui_scripting/lua/value_conversion.hpp" + +namespace ui_scripting +{ + int main_function_handler(game::hks::lua_State* state); + void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function); + void clear_converted_functions(); + + void enable_error_hook(); + void disable_error_hook(); +} \ No newline at end of file diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp new file mode 100644 index 00000000..939dbd1c --- /dev/null +++ b/src/client/component/updater.cpp @@ -0,0 +1,474 @@ +#include +#include "loader/component_loader.hpp" + +#include "scheduler.hpp" +#include "dvars.hpp" +#include "updater.hpp" + +#include "version.h" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include +#include +#include +#include +#include +#include + +#define MASTER "https://master.fed0001.xyz/h1-mod/" + +#define FILES_PATH "files.json" +#define FILES_PATH_DEV "files-dev.json" + +#define DATA_PATH "data/" +#define DATA_PATH_DEV "data-dev/" + +#define ERR_UPDATE_CHECK_FAIL "Failed to check for updates" +#define ERR_DOWNLOAD_FAIL "Failed to download file " +#define ERR_WRITE_FAIL "Failed to write file " + +#define BINARY_NAME "h1-mod.exe" + +namespace updater +{ + namespace + { + game::dvar_t* cl_auto_update; + bool has_tried_update = false; + + struct status + { + bool done; + bool success; + }; + + struct file_data + { + std::string name; + std::string data; + }; + + struct update_data_t + { + bool restart_required{}; + bool cancelled{}; + status check{}; + status download{}; + std::string error{}; + std::string current_file{}; + std::vector required_files{}; + }; + + utils::concurrency::container update_data; + + std::string get_branch() + { + return GIT_BRANCH; + } + + std::string select(const std::string& main, const std::string& develop) + { + if (get_branch() == "develop") + { + return develop; + } + + return main; + } + + std::string get_data_path() + { + if (get_branch() == "develop") + { + return DATA_PATH_DEV; + } + + return DATA_PATH; + } + + void set_update_check_status(bool done, bool success, const std::string& error = {}) + { + update_data.access([done, success, error](update_data_t& data_) + { + data_.check.done = done; + data_.check.success = success; + data_.error = error; + }); + } + + void set_update_download_status(bool done, bool success, const std::string& error = {}) + { + update_data.access([done, success, error](update_data_t& data_) + { + data_.download.done = done; + data_.download.success = success; + data_.error = error; + }); + } + + bool check_file(const std::string& name, const std::string& sha) + { + std::string data; + if (!utils::io::read_file(name, &data)) + { + return false; + } + + if (utils::cryptography::sha1::compute(data, true) != sha) + { + return false; + } + + return true; + } + + std::string load_binary_name() + { + // utils::nt::library self; + // return self.get_name(); + // returns the game's name and not the client's + + return BINARY_NAME; + } + + std::string get_binary_name() + { + static const auto name = load_binary_name(); + return name; + } + + std::string get_time_str() + { + return utils::string::va("%i", uint32_t(time(nullptr))); + } + + std::optional download_file(const std::string& name) + { + return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name + "?" + get_time_str()); + } + + bool is_update_cancelled() + { + return update_data.access([](update_data_t& data_) + { + return data_.cancelled; + }); + } + + bool write_file(const std::string& name, const std::string& data) + { + if (get_binary_name() == name && + utils::io::file_exists(name) && + !utils::io::move_file(name, name + ".old")) + { + return false; + } + +#ifdef DEBUG + return utils::io::write_file("update_test/" + name, data); +#else + return utils::io::write_file(name, data); +#endif + } + + void delete_old_file() + { + utils::io::remove_file(get_binary_name() + ".old"); + } + + void reset_data() + { + update_data.access([](update_data_t& data_) + { + data_ = {}; + }); + } + + std::string get_mode_flag() + { + if (game::environment::is_mp()) + { + return "-multiplayer"; + } + + if (game::environment::is_sp()) + { + return "-singleplayer"; + } + + return {}; + } + } + + // workaround + void relaunch() + { + if (!utils::io::file_exists(BINARY_NAME)) + { + utils::nt::terminate(0); + return; + } + + STARTUPINFOA startup_info; + PROCESS_INFORMATION process_info; + + ZeroMemory(&startup_info, sizeof(startup_info)); + ZeroMemory(&process_info, sizeof(process_info)); + startup_info.cb = sizeof(startup_info); + + char current_dir[MAX_PATH]; + GetCurrentDirectoryA(sizeof(current_dir), current_dir); + + char buf[1024] = {0}; + const auto command_line = utils::string::va("%s %s", GetCommandLineA(), get_mode_flag().data()); + strcpy_s(buf, 1024, command_line); + + CreateProcess(BINARY_NAME, buf, nullptr, nullptr, false, NULL, nullptr, current_dir, + &startup_info, &process_info); + + if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread); + if (process_info.hProcess && process_info.hProcess != INVALID_HANDLE_VALUE) CloseHandle(process_info.hProcess); + + utils::nt::terminate(0); + } + + void set_has_tried_update(bool tried) + { + has_tried_update = tried; + } + + bool get_has_tried_update() + { + return has_tried_update; + } + + bool auto_updates_enabled() + { + return cl_auto_update->current.enabled; + } + + bool is_update_check_done() + { + return update_data.access([](update_data_t& data_) + { + return data_.check.done; + }); + } + + bool is_update_download_done() + { + return update_data.access([](update_data_t& data_) + { + return data_.download.done; + }); + } + + bool get_update_check_status() + { + return update_data.access([](update_data_t& data_) + { + return data_.check.success; + }); + } + + bool get_update_download_status() + { + return update_data.access([](update_data_t& data_) + { + return data_.download.success; + }); + } + + bool is_update_available() + { + return update_data.access([](update_data_t& data_) + { + return data_.required_files.size() > 0; + }); + } + + bool is_restart_required() + { + return update_data.access([](update_data_t& data_) + { + return data_.restart_required; + }); + } + + std::string get_last_error() + { + return update_data.access([](update_data_t& data_) + { + return data_.error; + }); + } + + std::string get_current_file() + { + return update_data.access([](update_data_t& data_) + { + return data_.current_file; + }); + } + + void cancel_update() + { +#ifdef DEBUG + printf("[Updater] Cancelling update\n"); +#endif + + return update_data.access([](update_data_t& data_) + { + data_.cancelled = true; + }); + } + + void start_update_check() + { + cancel_update(); + reset_data(); + +#ifdef DEBUG + printf("[Updater] starting update check\n"); +#endif + + scheduler::once([]() + { + const auto files_data = utils::http::get_data(MASTER + select(FILES_PATH, FILES_PATH_DEV) + "?" + get_time_str()); + + if (is_update_cancelled()) + { + reset_data(); + return; + } + + if (!files_data.has_value()) + { + set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); + return; + } + + rapidjson::Document j; + j.Parse(files_data.value().data()); + + if (!j.IsArray()) + { + set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); + return; + } + + std::vector required_files; + + const auto files = j.GetArray(); + for (const auto& file : files) + { + if (!file.IsArray() || file.Size() != 3 || !file[0].IsString() || !file[2].IsString()) + { + continue; + } + + const auto name = file[0].GetString(); + const auto sha = file[2].GetString(); + + if (!check_file(name, sha)) + { + if (get_binary_name() == name) + { + update_data.access([](update_data_t& data_) + { + data_.restart_required = true; + }); + } + +#ifdef DEBUG + printf("[Updater] need file %s\n", name); +#endif + + required_files.push_back(name); + } + } + + update_data.access([&required_files](update_data_t& data_) + { + data_.check.done = true; + data_.check.success = true; + data_.required_files = required_files; + }); + }, scheduler::pipeline::async); + } + + void start_update_download() + { +#ifdef DEBUG + printf("[Updater] starting update download\n"); +#endif + + if (!is_update_check_done() || !get_update_check_status() || is_update_cancelled()) + { + return; + } + + scheduler::once([]() + { + const auto required_files = update_data.access>([](update_data_t& data_) + { + return data_.required_files; + }); + + std::vector downloads; + + for (const auto& file : required_files) + { + update_data.access([file](update_data_t& data_) + { + data_.current_file = file; + }); + +#ifdef DEBUG + printf("[Updater] downloading file %s\n", file.data()); +#endif + + const auto data = download_file(file); + + if (is_update_cancelled()) + { + reset_data(); + return; + } + + if (!data.has_value()) + { + set_update_download_status(true, false, ERR_DOWNLOAD_FAIL + file); + return; + } + + downloads.push_back({file, data.value()}); + } + + for (const auto& download : downloads) + { + if (!write_file(download.name, download.data)) + { + set_update_download_status(true, false, ERR_WRITE_FAIL + download.name); + return; + } + } + + set_update_download_status(true, true); + }, scheduler::pipeline::async); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + delete_old_file(); + cl_auto_update = dvars::register_bool("cg_auto_update", true, game::DVAR_FLAG_SAVED, true); + } + }; +} + +REGISTER_COMPONENT(updater::component) diff --git a/src/client/component/updater.hpp b/src/client/component/updater.hpp new file mode 100644 index 00000000..9a3dd45e --- /dev/null +++ b/src/client/component/updater.hpp @@ -0,0 +1,26 @@ +#pragma once + +namespace updater +{ + void relaunch(); + + void set_has_tried_update(bool tried); + bool get_has_tried_update(); + bool auto_updates_enabled(); + + bool is_update_available(); + bool is_update_check_done(); + bool get_update_check_status(); + + bool is_update_download_done(); + bool get_update_download_status(); + + bool is_restart_required(); + + std::string get_last_error(); + std::string get_current_file(); + + void start_update_check(); + void start_update_download(); + void cancel_update(); +} \ No newline at end of file diff --git a/src/client/component/videos.cpp b/src/client/component/videos.cpp new file mode 100644 index 00000000..a602cc8a --- /dev/null +++ b/src/client/component/videos.cpp @@ -0,0 +1,55 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" + +#include + +namespace videos +{ + namespace + { + utils::hook::detour playvid_hook; + std::unordered_map video_replaces; + + void playvid(const char* name, const int a2, const int a3) + { + const auto vid = video_replaces.find(name); + if (vid != video_replaces.end()) + { + char path[256]; + game::Sys_BuildAbsPath(path, sizeof(path), game::SF_VIDEO, vid->second.data(), ".bik"); + + if (game::Sys_FileExists(path)) + { + name = vid->second.data(); + } + } + + return playvid_hook.invoke(name, a2, a3); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + playvid_hook.create(SELECT_VALUE(0x1404A9D00, 0x1405B0AF0), &playvid); // H1(1.4) + + if (game::environment::is_mp()) + { + video_replaces["menus_bg_comp2"] = "menus_bg_h1mod"; + video_replaces["mp_menus_bg_options"] = "menus_bg_h1mod_blur"; + } + else if (game::environment::is_sp()) + { + video_replaces["sp_menus_bg_main_menu"] = "menus_bg_h1mod_sp"; + video_replaces["sp_menus_bg_campaign"] = "menus_bg_h1mod_sp"; + video_replaces["sp_menus_bg_options"] = "menus_bg_h1mod_sp"; + } + } + }; +} + +REGISTER_COMPONENT(videos::component) diff --git a/src/client/component/virtuallobby.cpp b/src/client/component/virtuallobby.cpp new file mode 100644 index 00000000..eb6295f7 --- /dev/null +++ b/src/client/component/virtuallobby.cpp @@ -0,0 +1,63 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include + +namespace virtuallobby +{ + namespace + { + game::dvar_t* virtualLobby_fovscale; + + const auto get_fovscale_stub = utils::hook::assemble([](utils::hook::assembler& a) + { + const auto ret = a.newLabel(); + const auto original = a.newLabel(); + + a.pushad64(); + a.mov(rax, qword_ptr(0x1425F7210)); // virtualLobbyInFiringRange + a.cmp(byte_ptr(rax, 0x10), 1); + a.je(original); + a.call_aligned(game::VirtualLobby_Loaded); + a.cmp(al, 0); + a.je(original); + + // virtuallobby + a.popad64(); + a.mov(rax, ptr(reinterpret_cast(&virtualLobby_fovscale))); + a.jmp(ret); + + // original + a.bind(original); + a.popad64(); + a.mov(rax, qword_ptr(0x1413A8580)); + a.jmp(ret); + + a.bind(ret); + a.mov(rcx, 0x142935000); + a.jmp(0x1400B556A); + }); + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (!game::environment::is_mp()) + { + return; + } + + virtualLobby_fovscale = dvars::register_float("virtualLobby_fovScale", 0.7f, 0.0f, 2.0f, game::DVAR_FLAG_SAVED); + + utils::hook::nop(0x1400B555C, 14); + utils::hook::jump(0x1400B555C, get_fovscale_stub, true); + } + }; +} + +REGISTER_COMPONENT(virtuallobby::component) diff --git a/src/client/loader/loader.cpp b/src/client/loader/loader.cpp index 4ec12c7c..1bc7b41c 100644 --- a/src/client/loader/loader.cpp +++ b/src/client/loader/loader.cpp @@ -31,7 +31,7 @@ FARPROC loader::load(const utils::nt::library& library, const std::string& buffe return FARPROC(library.get_ptr() + source.get_relative_entry_point()); } -FARPROC loader::load_library(const std::string& filename, uint64_t* base_address) const +FARPROC loader::load_library(const std::string& filename) const { const auto target = utils::nt::library::load(filename); if (!target) @@ -40,7 +40,10 @@ FARPROC loader::load_library(const std::string& filename, uint64_t* base_address } const auto base = size_t(target.get_ptr()); - *base_address = base; + if(base != 0x140000000) + { + throw std::runtime_error{utils::string::va("Binary was mapped at 0x%llX (instead of 0x%llX). Something is severely broken :(", base, 0x140000000)}; + } this->load_imports(target, target); this->load_tls(target, target); diff --git a/src/client/loader/loader.hpp b/src/client/loader/loader.hpp index 0c0b5a12..2c5d86f9 100644 --- a/src/client/loader/loader.hpp +++ b/src/client/loader/loader.hpp @@ -5,7 +5,7 @@ class loader final { public: FARPROC load(const utils::nt::library& library, const std::string& buffer) const; - FARPROC load_library(const std::string& filename, uint64_t* base_address) const; + FARPROC load_library(const std::string& filename) const; void set_import_resolver(const std::function& resolver); diff --git a/src/client/resources/ui_scripts/common.lua b/src/client/resources/ui_scripts/common.lua new file mode 100644 index 00000000..8f68e96d --- /dev/null +++ b/src/client/resources/ui_scripts/common.lua @@ -0,0 +1,164 @@ +menucallbacks = {} +originalmenus = {} +stack = {} + +LUI.MenuBuilder.m_types_build["generic_waiting_popup_"] = function (menu, event) + local oncancel = stack.oncancel + local popup = LUI.MenuBuilder.BuildRegisteredType("waiting_popup", { + message_text = stack.text, + isLiveWithCancel = true, + cancel_func = function(...) + local args = {...} + oncancel() + LUI.FlowManager.RequestLeaveMenu(args[1]) + end + }) + + local listchildren = popup:getChildById("LUIHorizontalList"):getchildren() + local children = listchildren[2]:getchildren() + popup.text = children[2] + + stack = { + ret = popup + } + + return popup +end + +LUI.MenuBuilder.m_types_build["generic_yes_no_popup_"] = function() + local callback = stack.callback + local popup = LUI.MenuBuilder.BuildRegisteredType("generic_yesno_popup", { + popup_title = stack.title, + message_text = stack.text, + yes_action = function() + callback(true) + end, + no_action = function() + callback(false) + end + }) + + stack = { + ret = popup + } + + return popup +end + +LUI.MenuBuilder.m_types_build["generic_confirmation_popup_"] = function() + local popup = LUI.MenuBuilder.BuildRegisteredType( "generic_confirmation_popup", { + cancel_will_close = false, + popup_title = stack.title, + message_text = stack.text, + button_text = stack.buttontext, + confirmation_action = stack.callback + }) + + stack = { + ret = popup + } + + return stack.ret +end + +LUI.onmenuopen = function(name, callback) + if (not LUI.MenuBuilder.m_types_build[name]) then + return + end + + if (not menucallbacks[name]) then + menucallbacks[name] = {} + end + + table.insert(menucallbacks[name], callback) + + if (not originalmenus[name]) then + originalmenus[name] = LUI.MenuBuilder.m_types_build[name] + LUI.MenuBuilder.m_types_build[name] = function(...) + local args = {...} + local menu = originalmenus[name](table.unpack(args)) + + for k, v in luiglobals.next, menucallbacks[name] do + v(menu, table.unpack(args)) + end + + return menu + end + end +end + +local addoptionstextinfo = LUI.Options.AddOptionTextInfo +LUI.Options.AddOptionTextInfo = function(menu) + local result = addoptionstextinfo(menu) + menu.optionTextInfo = result + return result +end + +LUI.addmenubutton = function(name, data) + LUI.onmenuopen(name, function(menu) + if (not menu.list) then + return + end + + local button = menu:AddButton(data.text, data.callback, nil, true, nil, { + desc_text = data.description + }) + + local buttonlist = menu:getChildById(menu.type .. "_list") + + if (data.id) then + button.id = data.id + end + + if (data.index) then + buttonlist:removeElement(button) + buttonlist:insertElement(button, data.index) + end + + local hintbox = menu.optionTextInfo + menu:removeElement(hintbox) + + LUI.Options.InitScrollingList(menu.list, nil) + menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) + end) +end + +LUI.openmenu = function(menu, args) + stack = args + LUI.FlowManager.RequestAddMenu(nil, menu) + return stack.ret +end + +LUI.openpopupmenu = function(menu, args) + stack = args + LUI.FlowManager.RequestPopupMenu(nil, menu) + return stack.ret +end + +LUI.yesnopopup = function(data) + for k, v in luiglobals.next, data do + stack[k] = v + end + LUI.FlowManager.RequestPopupMenu(nil, "generic_yes_no_popup_") + return stack.ret +end + +LUI.confirmationpopup = function(data) + for k, v in luiglobals.next, data do + stack[k] = v + end + LUI.FlowManager.RequestPopupMenu(nil, "generic_confirmation_popup_") + return stack.ret +end + +function userdata_:getchildren() + local children = {} + local first = self:getFirstChild() + + while (first) do + table.insert(children, first) + first = first:getNextSibling() + end + + return children +end diff --git a/src/client/resources/ui_scripts/updater.lua b/src/client/resources/ui_scripts/updater.lua new file mode 100644 index 00000000..01d77360 --- /dev/null +++ b/src/client/resources/ui_scripts/updater.lua @@ -0,0 +1,164 @@ +updatecancelled = false +taskinterval = 100 + +updater.cancelupdate() + +function startupdatecheck(popup, autoclose) + updatecancelled = false + + local callback = function() + if (not updater.getupdatecheckstatus()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end + + popup.text:setText("Error: " .. updater.getlasterror()) + return + end + + if (not updater.isupdateavailable()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end + + popup.text:setText("No updates available") + return + end + + LUI.yesnopopup({ + title = "NOTICE", + text = "An update is available, proceed with installation?", + callback = function(result) + if (result) then + startupdatedownload(popup, autoclose) + else + LUI.FlowManager.RequestLeaveMenu(popup) + end + end + }) + end + + updater.startupdatecheck() + createtask({ + done = updater.isupdatecheckdone, + cancelled = isupdatecancelled, + callback = callback, + interval = taskinterval + }) +end + +function startupdatedownload(popup, autoclose) + updater.startupdatedownload() + + local textupdate = nil + local previousfile = nil + textupdate = game:oninterval(function() + local file = updater.getcurrentfile() + if (file == previousfile) then + return + end + + file = previousfile + popup.text:setText("Downloading file " .. updater.getcurrentfile() .. "...") + end, 10) + + local callback = function() + textupdate:clear() + + if (not updater.getupdatedownloadstatus()) then + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + return + end + + popup.text:setText("Error: " .. updater.getlasterror()) + return + end + + popup.text:setText("Update successful") + + if (updater.isrestartrequired()) then + LUI.confirmationpopup({ + title = "RESTART REQUIRED", + text = "Update requires restart", + buttontext = "RESTART", + callback = function() + updater.relaunch() + end + }) + else + if (LUI.mp_menus) then + Engine.Exec("lui_restart; lui_open mp_main_menu") + else + Engine.Exec("lui_restart") + end + end + + if (autoclose) then + LUI.FlowManager.RequestLeaveMenu(popup) + end + end + + createtask({ + done = updater.isupdatedownloaddone, + cancelled = isupdatecancelled, + callback = callback, + interval = taskinterval + }) +end + +function updaterpopup(oncancel) + return LUI.openpopupmenu("generic_waiting_popup_", { + oncancel = oncancel, + withcancel = true, + text = "Checking for updates..." + }) +end + +function createtask(data) + local interval = nil + interval = game:oninterval(function() + if (data.cancelled()) then + interval:clear() + return + end + + if (data.done()) then + interval:clear() + data.callback() + end + end, data.interval) + return interval +end + +function isupdatecancelled() + return updatecancelled +end + +function tryupdate(autoclose) + updatecancelled = false + local popup = updaterpopup(function() + updater.cancelupdate() + updatecancelled = true + end) + + startupdatecheck(popup, autoclose) +end + +function tryautoupdate() + if (not updater.autoupdatesenabled()) then + return + end + + if (not updater.gethastriedupdate()) then + game:ontimeout(function() + updater.sethastriedupdate(true) + tryupdate(true) + end, 100) + end +end + +LUI.onmenuopen("mp_main_menu", tryautoupdate) +LUI.onmenuopen("main_lockout", tryautoupdate) \ No newline at end of file From c998bf633b2aaf41fdf9b3f8aea792a297553764 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Fri, 18 Mar 2022 02:54:50 +0200 Subject: [PATCH 117/346] loader [skip ci] --- src/client/loader/loader.cpp | 7 ++----- src/client/loader/loader.hpp | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/client/loader/loader.cpp b/src/client/loader/loader.cpp index 1bc7b41c..4ec12c7c 100644 --- a/src/client/loader/loader.cpp +++ b/src/client/loader/loader.cpp @@ -31,7 +31,7 @@ FARPROC loader::load(const utils::nt::library& library, const std::string& buffe return FARPROC(library.get_ptr() + source.get_relative_entry_point()); } -FARPROC loader::load_library(const std::string& filename) const +FARPROC loader::load_library(const std::string& filename, uint64_t* base_address) const { const auto target = utils::nt::library::load(filename); if (!target) @@ -40,10 +40,7 @@ FARPROC loader::load_library(const std::string& filename) const } const auto base = size_t(target.get_ptr()); - if(base != 0x140000000) - { - throw std::runtime_error{utils::string::va("Binary was mapped at 0x%llX (instead of 0x%llX). Something is severely broken :(", base, 0x140000000)}; - } + *base_address = base; this->load_imports(target, target); this->load_tls(target, target); diff --git a/src/client/loader/loader.hpp b/src/client/loader/loader.hpp index 2c5d86f9..0c0b5a12 100644 --- a/src/client/loader/loader.hpp +++ b/src/client/loader/loader.hpp @@ -5,7 +5,7 @@ class loader final { public: FARPROC load(const utils::nt::library& library, const std::string& buffer) const; - FARPROC load_library(const std::string& filename) const; + FARPROC load_library(const std::string& filename, uint64_t* base_address) const; void set_import_resolver(const std::function& resolver); From aabe0b427b95faff16180c03de68dbd5529e5180 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Fri, 18 Mar 2022 02:58:43 +0200 Subject: [PATCH 118/346] arxan class [skip ci] --- src/client/component/arxan.cpp | 164 +++++++++++++++++++++++++++++++++ src/client/main.cpp | 50 ++++++---- 2 files changed, 195 insertions(+), 19 deletions(-) create mode 100644 src/client/component/arxan.cpp diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp new file mode 100644 index 00000000..adff7199 --- /dev/null +++ b/src/client/component/arxan.cpp @@ -0,0 +1,164 @@ +#include +#include "loader/component_loader.hpp" +#include "scheduler.hpp" +#include "game/game.hpp" + +#include + +namespace arxan +{ + namespace + { + utils::hook::detour nt_close_hook; + utils::hook::detour nt_query_information_process_hook; + + NTSTATUS WINAPI nt_query_information_process_stub(const HANDLE handle, const PROCESSINFOCLASS info_class, + const PVOID info, + const ULONG info_length, const PULONG ret_length) + { + auto* orig = static_cast(nt_query_information_process_hook. + get_original()); + const auto status = orig(handle, info_class, info, info_length, ret_length); + + if (NT_SUCCESS(status)) + { + if (info_class == ProcessBasicInformation) + { + static DWORD explorer_pid = 0; + if (!explorer_pid) + { + auto* const shell_window = GetShellWindow(); + GetWindowThreadProcessId(shell_window, &explorer_pid); + } + + static_cast(info)->Reserved3 = PVOID(DWORD64(explorer_pid)); + } + else if (info_class == 30) // ProcessDebugObjectHandle + { + *static_cast(info) = nullptr; + + return 0xC0000353; + } + else if (info_class == 7) // ProcessDebugPort + { + *static_cast(info) = nullptr; + } + else if (info_class == 31) + { + *static_cast(info) = 1; + } + } + + return status; + } + + NTSTATUS NTAPI nt_close_stub(const HANDLE handle) + { + char info[16]; + if (NtQueryObject(handle, OBJECT_INFORMATION_CLASS(4), &info, 2, nullptr) >= 0 && size_t(handle) != 0x12345) + { + auto* orig = static_cast(nt_close_hook.get_original()); + return orig(handle); + } + + return STATUS_INVALID_HANDLE; + } + + LONG WINAPI exception_filter(const LPEXCEPTION_POINTERS info) + { + if (info->ExceptionRecord->ExceptionCode == STATUS_INVALID_HANDLE) + { + return EXCEPTION_CONTINUE_EXECUTION; + } + + return EXCEPTION_CONTINUE_SEARCH; + } + + void hide_being_debugged() + { + auto* const peb = PPEB(__readgsqword(0x60)); + peb->BeingDebugged = false; + *reinterpret_cast(LPSTR(peb) + 0xBC) &= ~0x70; + } + + void remove_hardware_breakpoints() + { + CONTEXT context; + ZeroMemory(&context, sizeof(context)); + context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + + auto* const thread = GetCurrentThread(); + GetThreadContext(thread, &context); + + context.Dr0 = 0; + context.Dr1 = 0; + context.Dr2 = 0; + context.Dr3 = 0; + context.Dr6 = 0; + context.Dr7 = 0; + + SetThreadContext(thread, &context); + } + + BOOL WINAPI set_thread_context_stub(const HANDLE thread, CONTEXT* context) + { + if (!game::environment::is_sp() + && game::dwGetLogOnStatus() == game::DW_LIVE_CONNECTED + && context->ContextFlags == CONTEXT_DEBUG_REGISTERS) + { + return TRUE; + } + + return SetThreadContext(thread, context); + } + } + + int just_return() + { + return 1; + } + + class component final : public component_interface + { + public: + void* load_import(const std::string& library, const std::string& function) override + { + if (function == "SetThreadContext") + { + //return set_thread_context_stub; + } + + if (function == "LoadStringA" || function == "LoadStringW") + { + return just_return; + } + + return nullptr; + } + + void post_load() override + { + hide_being_debugged(); + scheduler::loop(hide_being_debugged, scheduler::pipeline::async); + + const utils::nt::library ntdll("ntdll.dll"); + nt_close_hook.create(ntdll.get_proc("NtClose"), nt_close_stub); + nt_query_information_process_hook.create(ntdll.get_proc("NtQueryInformationProcess"), + nt_query_information_process_stub); + + AddVectoredExceptionHandler(1, exception_filter); + } + + void post_unpack() override + { + // cba to implement sp, not sure if it's even needed + if (game::environment::is_sp()) return; + + // some of arxan crashes + utils::hook::nop(0x14CDEFCAA, 6); + utils::hook::call(0x1405BCAD1, &just_return); + } + }; +} + +REGISTER_COMPONENT(arxan::component) \ No newline at end of file diff --git a/src/client/main.cpp b/src/client/main.cpp index 519756b2..71979cbf 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -51,7 +51,7 @@ launcher::mode detect_mode_from_arguments() } -FARPROC load_binary(const launcher::mode mode) +FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) { loader loader; utils::nt::library self; @@ -97,11 +97,11 @@ FARPROC load_binary(const launcher::mode mode) if (!utils::io::read_file(binary, &data)) { throw std::runtime_error(utils::string::va( - "Failed to read game binary (%s)!\nPlease copy the h1-mod.exe into your Call of Duty: Modern Warfare Remastered installation folder and run it from there.", + "Failed to read game binary (%s)!\nPlease copy the h1x.exe into your Call of Duty: Modern Warfare Remastered installation folder and run it from there.", binary.data())); } - return loader.load_library(binary); + return loader.load_library(binary, base_address); } void remove_crash_file() @@ -111,10 +111,10 @@ void remove_crash_file() void enable_dpi_awareness() { - const utils::nt::library user32{"user32.dll"}; + const utils::nt::library user32{ "user32.dll" }; const auto set_dpi = user32 - ? user32.get_proc("SetProcessDpiAwarenessContext") - : nullptr; + ? user32.get_proc("SetProcessDpiAwarenessContext") + : nullptr; if (set_dpi) { set_dpi(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); @@ -149,48 +149,60 @@ void limit_parallel_dll_loading() int main() { + ShowWindow(GetConsoleWindow(), SW_HIDE); + FARPROC entry_point; enable_dpi_awareness(); - // This requires admin privilege, but I suppose many - // people will start with admin rights if it crashes. limit_parallel_dll_loading(); srand(uint32_t(time(nullptr))); + remove_crash_file(); { auto premature_shutdown = true; const auto _ = gsl::finally([&premature_shutdown]() - { - if (premature_shutdown) { - component_loader::pre_destroy(); - } - }); + if (premature_shutdown) + { + component_loader::pre_destroy(); + } + }); try { - remove_crash_file(); - - if (!component_loader::post_start()) return 0; + if (!component_loader::post_start()) + { + return 0; + } auto mode = detect_mode_from_arguments(); if (mode == launcher::mode::none) { const launcher launcher; mode = launcher.run(); - if (mode == launcher::mode::none) return 0; + if (mode == launcher::mode::none) + { + return 0; + } } game::environment::set_mode(mode); - entry_point = load_binary(mode); + uint64_t base_address{}; + entry_point = load_binary(mode, &base_address); if (!entry_point) { throw std::runtime_error("Unable to load binary into memory"); } - if (!component_loader::post_load()) return 0; + game::base_address = base_address; + //verify_version(); + + if (!component_loader::post_load()) + { + return 0; + } premature_shutdown = false; } From 369b0f3a1c5924e1321ecf96323be167ba95089e Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Fri, 18 Mar 2022 03:19:50 +0200 Subject: [PATCH 119/346] small clean up [skip ci] also no compiler err's --- src/client/component/bots.cpp | 103 - src/client/component/logfile.cpp | 317 -- src/client/component/logfile.hpp | 13 - src/client/component/lui.cpp | 58 - src/client/component/scripting.cpp | 141 - src/client/component/scripting.hpp | 8 - src/client/component/shaders.cpp | 50 - src/client/component/slowmotion.cpp | 53 - src/client/component/thread_names.cpp | 60 - src/client/component/ui_scripting.cpp | 180 - src/client/component/ui_scripting.hpp | 12 - src/client/component/updater.cpp | 474 --- src/client/component/updater.hpp | 26 - src/client/component/videos.cpp | 55 - src/client/component/virtuallobby.cpp | 63 - src/client/game/scripting/entity.cpp | 120 - src/client/game/scripting/entity.hpp | 50 - src/client/game/scripting/event.hpp | 13 - src/client/game/scripting/execution.cpp | 240 -- src/client/game/scripting/execution.hpp | 36 - src/client/game/scripting/function_tables.cpp | 3480 ----------------- src/client/game/scripting/functions.cpp | 106 - src/client/game/scripting/functions.hpp | 16 - src/client/game/scripting/lua/context.cpp | 542 --- src/client/game/scripting/lua/context.hpp | 45 - src/client/game/scripting/lua/engine.cpp | 75 - src/client/game/scripting/lua/engine.hpp | 11 - src/client/game/scripting/lua/error.cpp | 37 - src/client/game/scripting/lua/error.hpp | 8 - .../game/scripting/lua/event_handler.cpp | 174 - .../game/scripting/lua/event_handler.hpp | 58 - src/client/game/scripting/lua/scheduler.cpp | 171 - src/client/game/scripting/lua/scheduler.hpp | 54 - .../game/scripting/lua/value_conversion.cpp | 319 -- .../game/scripting/lua/value_conversion.hpp | 11 - src/client/game/scripting/safe_execution.cpp | 72 - src/client/game/scripting/safe_execution.hpp | 10 - src/client/game/scripting/script_value.cpp | 278 -- src/client/game/scripting/script_value.hpp | 52 - src/client/game/scripting/stack_isolation.cpp | 27 - src/client/game/scripting/stack_isolation.hpp | 25 - src/client/game/scripting/variable_value.cpp | 68 - src/client/game/scripting/variable_value.hpp | 27 - src/client/game/scripting/vector.cpp | 85 - src/client/game/scripting/vector.hpp | 31 - src/client/game/symbols.hpp | 2 + src/client/game/ui_scripting/execution.cpp | 161 - src/client/game/ui_scripting/execution.hpp | 18 - src/client/game/ui_scripting/lua/context.cpp | 239 -- src/client/game/ui_scripting/lua/context.hpp | 42 - src/client/game/ui_scripting/lua/engine.cpp | 73 - src/client/game/ui_scripting/lua/engine.hpp | 8 - src/client/game/ui_scripting/lua/error.cpp | 18 - src/client/game/ui_scripting/lua/error.hpp | 8 - .../game/ui_scripting/lua/scheduler.cpp | 122 - .../game/ui_scripting/lua/scheduler.hpp | 50 - .../ui_scripting/lua/value_conversion.cpp | 144 - .../ui_scripting/lua/value_conversion.hpp | 9 - src/client/game/ui_scripting/script_value.cpp | 274 -- src/client/game/ui_scripting/script_value.hpp | 56 - src/client/game/ui_scripting/types.cpp | 276 -- src/client/game/ui_scripting/types.hpp | 89 - src/client/main.cpp | 2 +- 63 files changed, 3 insertions(+), 9442 deletions(-) delete mode 100644 src/client/component/bots.cpp delete mode 100644 src/client/component/logfile.cpp delete mode 100644 src/client/component/logfile.hpp delete mode 100644 src/client/component/lui.cpp delete mode 100644 src/client/component/scripting.cpp delete mode 100644 src/client/component/scripting.hpp delete mode 100644 src/client/component/shaders.cpp delete mode 100644 src/client/component/slowmotion.cpp delete mode 100644 src/client/component/thread_names.cpp delete mode 100644 src/client/component/ui_scripting.cpp delete mode 100644 src/client/component/ui_scripting.hpp delete mode 100644 src/client/component/updater.cpp delete mode 100644 src/client/component/updater.hpp delete mode 100644 src/client/component/videos.cpp delete mode 100644 src/client/component/virtuallobby.cpp delete mode 100644 src/client/game/scripting/entity.cpp delete mode 100644 src/client/game/scripting/entity.hpp delete mode 100644 src/client/game/scripting/event.hpp delete mode 100644 src/client/game/scripting/execution.cpp delete mode 100644 src/client/game/scripting/execution.hpp delete mode 100644 src/client/game/scripting/function_tables.cpp delete mode 100644 src/client/game/scripting/functions.cpp delete mode 100644 src/client/game/scripting/functions.hpp delete mode 100644 src/client/game/scripting/lua/context.cpp delete mode 100644 src/client/game/scripting/lua/context.hpp delete mode 100644 src/client/game/scripting/lua/engine.cpp delete mode 100644 src/client/game/scripting/lua/engine.hpp delete mode 100644 src/client/game/scripting/lua/error.cpp delete mode 100644 src/client/game/scripting/lua/error.hpp delete mode 100644 src/client/game/scripting/lua/event_handler.cpp delete mode 100644 src/client/game/scripting/lua/event_handler.hpp delete mode 100644 src/client/game/scripting/lua/scheduler.cpp delete mode 100644 src/client/game/scripting/lua/scheduler.hpp delete mode 100644 src/client/game/scripting/lua/value_conversion.cpp delete mode 100644 src/client/game/scripting/lua/value_conversion.hpp delete mode 100644 src/client/game/scripting/safe_execution.cpp delete mode 100644 src/client/game/scripting/safe_execution.hpp delete mode 100644 src/client/game/scripting/script_value.cpp delete mode 100644 src/client/game/scripting/script_value.hpp delete mode 100644 src/client/game/scripting/stack_isolation.cpp delete mode 100644 src/client/game/scripting/stack_isolation.hpp delete mode 100644 src/client/game/scripting/variable_value.cpp delete mode 100644 src/client/game/scripting/variable_value.hpp delete mode 100644 src/client/game/scripting/vector.cpp delete mode 100644 src/client/game/scripting/vector.hpp delete mode 100644 src/client/game/ui_scripting/execution.cpp delete mode 100644 src/client/game/ui_scripting/execution.hpp delete mode 100644 src/client/game/ui_scripting/lua/context.cpp delete mode 100644 src/client/game/ui_scripting/lua/context.hpp delete mode 100644 src/client/game/ui_scripting/lua/engine.cpp delete mode 100644 src/client/game/ui_scripting/lua/engine.hpp delete mode 100644 src/client/game/ui_scripting/lua/error.cpp delete mode 100644 src/client/game/ui_scripting/lua/error.hpp delete mode 100644 src/client/game/ui_scripting/lua/scheduler.cpp delete mode 100644 src/client/game/ui_scripting/lua/scheduler.hpp delete mode 100644 src/client/game/ui_scripting/lua/value_conversion.cpp delete mode 100644 src/client/game/ui_scripting/lua/value_conversion.hpp delete mode 100644 src/client/game/ui_scripting/script_value.cpp delete mode 100644 src/client/game/ui_scripting/script_value.hpp delete mode 100644 src/client/game/ui_scripting/types.cpp delete mode 100644 src/client/game/ui_scripting/types.hpp diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp deleted file mode 100644 index 81f74628..00000000 --- a/src/client/component/bots.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "command.hpp" -#include "scheduler.hpp" -#include "network.hpp" -#include "party.hpp" - -#include "game/game.hpp" -#include "game/scripting/execution.hpp" - -#include -#include -#include - -namespace bots -{ - namespace - { - bool can_add() - { - if (party::get_client_count() < *game::mp::svs_numclients) - { - return true; - } - return false; - } - - // TODO: when scripting comes, fix this to use better notifies - void bot_team_join(const int entity_num) - { - const game::scr_entref_t entref{static_cast(entity_num), 0}; - scheduler::once([entref]() - { - scripting::notify(entref, "luinotifyserver", {"team_select", 2}); - scheduler::once([entref]() - { - auto* _class = utils::string::va("class%d", utils::cryptography::random::get_integer() % 5); - scripting::notify(entref, "luinotifyserver", {"class_select", _class}); - }, scheduler::pipeline::server, 2s); - }, scheduler::pipeline::server, 2s); - } - - void spawn_bot(const int entity_num) - { - game::SV_SpawnTestClient(&game::mp::g_entities[entity_num]); - if (game::Com_GetCurrentCoDPlayMode() == game::CODPLAYMODE_CORE) - { - bot_team_join(entity_num); - } - } - - void add_bot() - { - if (!can_add()) - { - return; - } - - // SV_BotGetRandomName - const auto* const bot_name = game::SV_BotGetRandomName(); - auto* bot_ent = game::SV_AddBot(bot_name); - if (bot_ent) - { - spawn_bot(bot_ent->s.entityNum); - } - else if (can_add()) // workaround since first bot won't ever spawn - { - add_bot(); - } - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_sp()) - { - return; - } - - command::add("spawnBot", [](const command::params& params) - { - if (!game::SV_Loaded() || game::VirtualLobby_Loaded()) return; - - auto num_bots = 1; - if (params.size() == 2) - { - num_bots = atoi(params.get(1)); - } - - for (auto i = 0; i < (num_bots > *game::mp::svs_numclients ? *game::mp::svs_numclients : num_bots); i++) - { - scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i); - } - }); - } - }; -} - -REGISTER_COMPONENT(bots::component) \ No newline at end of file diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp deleted file mode 100644 index fc949d92..00000000 --- a/src/client/component/logfile.cpp +++ /dev/null @@ -1,317 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "scheduler.hpp" - -#include "game/scripting/entity.hpp" -#include "game/scripting/execution.hpp" -#include "game/scripting/lua/value_conversion.hpp" -#include "game/scripting/lua/error.hpp" - -#include - -#include "logfile.hpp" - -namespace logfile -{ - std::unordered_map vm_execute_hooks; - - namespace - { - utils::hook::detour scr_player_killed_hook; - utils::hook::detour scr_player_damage_hook; - - std::vector player_killed_callbacks; - std::vector player_damage_callbacks; - - utils::hook::detour vm_execute_hook; - char empty_function[2] = {0x32, 0x34}; // CHECK_CLEAR_PARAMS, END - bool hook_enabled = true; - - sol::lua_value convert_entity(lua_State* state, const game::mp::gentity_s* ent) - { - if (!ent) - { - return {}; - } - - const scripting::entity player{game::Scr_GetEntityId(ent->s.entityNum, 0)}; - return scripting::lua::convert(state, player); - } - - std::string get_weapon_name(unsigned int weapon, bool isAlternate) - { - char output[1024] = {0}; - game::BG_GetWeaponNameComplete(weapon, isAlternate, output, 1024); - return output; - } - - sol::lua_value convert_vector(lua_State* state, const float* vec) - { - if (!vec) - { - return {}; - } - - const auto vec_ = scripting::vector(vec); - return scripting::lua::convert(state, vec_); - } - - std::string convert_mod(const int meansOfDeath) - { - const auto value = reinterpret_cast(0x140FEC3F0)[meansOfDeath]; - const auto string = game::SL_ConvertToString(*value); - return string; - } - - void scr_player_killed_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, - game::mp::gentity_s* attacker, int damage, const int meansOfDeath, const unsigned int weapon, - const bool isAlternate, const float* vDir, const unsigned int hitLoc, int psTimeOffset, int deathAnimDuration) - { - { - const std::string hitloc = reinterpret_cast(0x140FEC4D0)[hitLoc]; - const auto mod_ = convert_mod(meansOfDeath); - - const auto weapon_ = get_weapon_name(weapon, isAlternate); - - for (const auto& callback : player_killed_callbacks) - { - const auto state = callback.lua_state(); - - const auto self_ = convert_entity(state, self); - const auto inflictor_ = convert_entity(state, inflictor); - const auto attacker_ = convert_entity(state, attacker); - - const auto dir = convert_vector(state, vDir); - - const auto result = callback(self_, inflictor_, attacker_, damage, - mod_, weapon_, dir, hitloc, psTimeOffset, deathAnimDuration); - - scripting::lua::handle_error(result); - - if (result.valid() && result.get_type() == sol::type::number) - { - damage = result.get(); - } - } - - if (damage == 0) - { - return; - } - } - - scr_player_killed_hook.invoke(self, inflictor, attacker, damage, meansOfDeath, - weapon, isAlternate, vDir, hitLoc, psTimeOffset, deathAnimDuration); - } - - void scr_player_damage_stub(game::mp::gentity_s* self, const game::mp::gentity_s* inflictor, - game::mp::gentity_s* attacker, int damage, int dflags, const int meansOfDeath, - const unsigned int weapon, const bool isAlternate, const float* vPoint, - const float* vDir, const unsigned int hitLoc, const int timeOffset) - { - { - const std::string hitloc = reinterpret_cast(0x140FEC4D0)[hitLoc]; - const auto mod_ = convert_mod(meansOfDeath); - - const auto weapon_ = get_weapon_name(weapon, isAlternate); - - for (const auto& callback : player_damage_callbacks) - { - const auto state = callback.lua_state(); - - const auto self_ = convert_entity(state, self); - const auto inflictor_ = convert_entity(state, inflictor); - const auto attacker_ = convert_entity(state, attacker); - - const auto point = convert_vector(state, vPoint); - const auto dir = convert_vector(state, vDir); - - const auto result = callback(self_, inflictor_, attacker_, - damage, dflags, mod_, weapon_, point, dir, hitloc); - - scripting::lua::handle_error(result); - - if (result.valid() && result.get_type() == sol::type::number) - { - damage = result.get(); - } - } - - if (damage == 0) - { - return; - } - } - - scr_player_damage_hook.invoke(self, inflictor, attacker, damage, dflags, - meansOfDeath, weapon, isAlternate, vPoint, vDir, hitLoc, timeOffset); - } - - void client_command_stub(const int clientNum) - { - auto self = &game::mp::g_entities[clientNum]; - char cmd[1024] = {0}; - - game::SV_Cmd_ArgvBuffer(0, cmd, 1024); - - if (cmd == "say"s || cmd == "say_team"s) - { - auto hidden = false; - std::string message(game::ConcatArgs(1)); - - hidden = message[1] == '/'; - message.erase(0, hidden ? 2 : 1); - - scheduler::once([cmd, message, self]() - { - const scripting::entity level{*game::levelEntityId}; - const scripting::entity player{game::Scr_GetEntityId(self->s.entityNum, 0)}; - - scripting::notify(level, cmd, {player, message}); - scripting::notify(player, cmd, {message}); - }, scheduler::pipeline::server); - - if (hidden) - { - return; - } - } - - // ClientCommand - return utils::hook::invoke(0x140336000, clientNum); - } - - void g_shutdown_game_stub(const int freeScripts) - { - { - const scripting::entity level{*game::levelEntityId}; - scripting::notify(level, "shutdownGame_called", {1}); - } - - // G_ShutdownGame - return utils::hook::invoke(0x140345A60, freeScripts); - } - - unsigned int local_id_to_entity(unsigned int local_id) - { - const auto variable = game::scr_VarGlob->objectVariableValue[local_id]; - return variable.u.f.next; - } - - bool execute_vm_hook(const char* pos) - { - if (vm_execute_hooks.find(pos) == vm_execute_hooks.end()) - { - hook_enabled = true; - return false; - } - - if (!hook_enabled && pos > reinterpret_cast(vm_execute_hooks.size())) - { - hook_enabled = true; - return false; - } - - const auto hook = vm_execute_hooks[pos]; - const auto state = hook.lua_state(); - - const scripting::entity self = local_id_to_entity(game::scr_VmPub->function_frame->fs.localId); - - std::vector args; - - const auto top = game::scr_function_stack->top; - - for (auto* value = top; value->type != game::SCRIPT_END; --value) - { - args.push_back(scripting::lua::convert(state, *value)); - } - - const auto result = hook(self, sol::as_args(args)); - scripting::lua::handle_error(result); - - return true; - } - - void vm_execute_stub(utils::hook::assembler& a) - { - const auto replace = a.newLabel(); - const auto end = a.newLabel(); - - a.pushad64(); - - a.mov(rcx, r14); - a.call_aligned(execute_vm_hook); - - a.cmp(al, 0); - a.jne(replace); - - a.popad64(); - a.jmp(end); - - a.bind(end); - - a.movzx(r15d, byte_ptr(r14)); - a.inc(r14); - a.mov(dword_ptr(rbp, 0xA4), r15d); - - a.jmp(SELECT_VALUE(0x140376663, 0x140444653)); - - a.bind(replace); - - a.popad64(); - a.mov(r14, reinterpret_cast(empty_function)); - a.jmp(end); - } - } - - void add_player_damage_callback(const sol::protected_function& callback) - { - player_damage_callbacks.push_back(callback); - } - - void add_player_killed_callback(const sol::protected_function& callback) - { - player_killed_callbacks.push_back(callback); - } - - void clear_callbacks() - { - player_damage_callbacks.clear(); - player_killed_callbacks.clear(); - vm_execute_hooks.clear(); - } - - void enable_vm_execute_hook() - { - hook_enabled = true; - } - - void disable_vm_execute_hook() - { - hook_enabled = false; - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_sp()) - { - return; - } - - utils::hook::call(0x14048191D, client_command_stub); - - scr_player_damage_hook.create(0x14037DC50, scr_player_damage_stub); - scr_player_killed_hook.create(0x14037DF30, scr_player_killed_stub); - - utils::hook::call(0x140484EC0, g_shutdown_game_stub); - utils::hook::call(0x1404853C1, g_shutdown_game_stub); - - utils::hook::jump(SELECT_VALUE(0x140376655, 0x140444645), utils::hook::assemble(vm_execute_stub), true); - } - }; -} - -REGISTER_COMPONENT(logfile::component) \ No newline at end of file diff --git a/src/client/component/logfile.hpp b/src/client/component/logfile.hpp deleted file mode 100644 index 77f699c8..00000000 --- a/src/client/component/logfile.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -namespace logfile -{ - extern std::unordered_map vm_execute_hooks; - - void add_player_damage_callback(const sol::protected_function& callback); - void add_player_killed_callback(const sol::protected_function& callback); - void clear_callbacks(); - - void enable_vm_execute_hook(); - void disable_vm_execute_hook(); -} \ No newline at end of file diff --git a/src/client/component/lui.cpp b/src/client/component/lui.cpp deleted file mode 100644 index d3a7edca..00000000 --- a/src/client/component/lui.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" - -#include "command.hpp" -#include "console.hpp" - -#include - -namespace lui -{ - class component final : public component_interface - { - public: - void post_unpack() override - { - // Don't show create cod account popup - //utils::hook::set(0x14017C957, 0); // H1(1.4) - -//#ifdef _DEBUG - // Enable development menus (causes issues in sp) - //utils::hook::set(SELECT_VALUE(0x1400B4ABC, 0x1401AB779), 1); -//#endif - - command::add("lui_open", [](const command::params& params) - { - if (params.size() <= 1) - { - console::info("usage: lui_open \n"); - return; - } - - game::LUI_OpenMenu(0, params[1], 0, 0, 0); - }); - - command::add("lui_open_popup", [](const command::params& params) - { - if (params.size() <= 1) - { - console::info("usage: lui_open_popup \n"); - return; - } - - game::LUI_OpenMenu(0, params[1], 1, 0, 0); - }); - - command::add("runMenuScript", [](const command::params& params) - { - const auto args_str = params.join(1); - const auto* args = args_str.data(); - game::UI_RunMenuScript(0, &args); - }); - } - }; -} - -REGISTER_COMPONENT(lui::component) diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp deleted file mode 100644 index e3116122..00000000 --- a/src/client/component/scripting.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include - -#include "game/scripting/entity.hpp" -#include "game/scripting/functions.hpp" -#include "game/scripting/event.hpp" -#include "game/scripting/lua/engine.hpp" -#include "game/scripting/execution.hpp" - -#include "scheduler.hpp" -#include "scripting.hpp" - -namespace scripting -{ - std::unordered_map> fields_table; - std::unordered_map> script_function_table; - - namespace - { - utils::hook::detour vm_notify_hook; - utils::hook::detour scr_load_level_hook; - utils::hook::detour g_shutdown_game_hook; - - utils::hook::detour scr_add_class_field_hook; - - utils::hook::detour scr_set_thread_position_hook; - utils::hook::detour process_script_hook; - - std::string current_file; - - void vm_notify_stub(const unsigned int notify_list_owner_id, const game::scr_string_t string_value, - game::VariableValue* top) - { - if (!game::VirtualLobby_Loaded()) - { - const auto* string = game::SL_ConvertToString(string_value); - if (string) - { - event e; - e.name = string; - e.entity = notify_list_owner_id; - - for (auto* value = top; value->type != game::SCRIPT_END; --value) - { - e.arguments.emplace_back(*value); - } - - if (e.name == "entitydeleted") - { - scripting::clear_entity_fields(e.entity); - } - - lua::engine::notify(e); - } - } - - vm_notify_hook.invoke(notify_list_owner_id, string_value, top); - } - - void scr_load_level_stub() - { - scr_load_level_hook.invoke(); - if (!game::VirtualLobby_Loaded()) - { - lua::engine::start(); - } - } - - void g_shutdown_game_stub(const int free_scripts) - { - lua::engine::stop(); - return g_shutdown_game_hook.invoke(free_scripts); - } - - void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t _name, unsigned int canonicalString, unsigned int offset) - { - const auto name = game::SL_ConvertToString(_name); - - if (fields_table[classnum].find(name) == fields_table[classnum].end()) - { - fields_table[classnum][name] = offset; - } - - scr_add_class_field_hook.invoke(classnum, _name, canonicalString, offset); - } - - void process_script_stub(const char* filename) - { - const auto file_id = atoi(filename); - if (file_id) - { - current_file = scripting::find_token(file_id); - } - else - { - current_file = filename; - } - - process_script_hook.invoke(filename); - } - - void scr_set_thread_position_stub(unsigned int threadName, const char* codePos) - { - const auto function_name = scripting::find_token(threadName); - script_function_table[current_file][function_name] = codePos; - scr_set_thread_position_hook.invoke(threadName, codePos); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (game::environment::is_sp()) - { - return; - } - - vm_notify_hook.create(SELECT_VALUE(0x140379A00, 0x1404479F0), vm_notify_stub); - - scr_add_class_field_hook.create(SELECT_VALUE(0x140370370, 0x14043E2C0), scr_add_class_field_stub); - - scr_set_thread_position_hook.create(SELECT_VALUE(0x14036A180, 0x140437D10), scr_set_thread_position_stub); - process_script_hook.create(SELECT_VALUE(0x1403737E0, 0x1404417E0), process_script_stub); - - scr_load_level_hook.create(SELECT_VALUE(0x1402A5BE0, 0x1403727C0), scr_load_level_stub); - g_shutdown_game_hook.create(SELECT_VALUE(0x140277D40, 0x140345A60), g_shutdown_game_stub); - - scheduler::loop([]() - { - lua::engine::run_frame(); - }, scheduler::pipeline::server); - } - }; -} - -REGISTER_COMPONENT(scripting::component) \ No newline at end of file diff --git a/src/client/component/scripting.hpp b/src/client/component/scripting.hpp deleted file mode 100644 index 865ae858..00000000 --- a/src/client/component/scripting.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -namespace scripting -{ - extern std::unordered_map> fields_table; - extern std::unordered_map> script_function_table; -} \ No newline at end of file diff --git a/src/client/component/shaders.cpp b/src/client/component/shaders.cpp deleted file mode 100644 index ec632115..00000000 --- a/src/client/component/shaders.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "scheduler.hpp" -#include "dvars.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include -#include -#include - -namespace shaders -{ - namespace - { - game::dvar_t* disable_shader_caching = nullptr; - - bool shader_should_show_dialog_stub() - { - return !disable_shader_caching->current.enabled; - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (!game::environment::is_mp()) - { - return; - } - - const auto has_flag = utils::flags::has_flag("noshadercaching"); - - disable_shader_caching = dvars::register_bool("disable_shader_caching", has_flag, game::DVAR_FLAG_SAVED, true); - if (has_flag) - { - dvars::override::set_bool("disable_shader_caching", 1); - dvars::override::set_from_string("disable_shader_caching", "1"); - } - - utils::hook::jump(0x14007E710, shader_should_show_dialog_stub); - } - }; -} - -REGISTER_COMPONENT(shaders::component) diff --git a/src/client/component/slowmotion.cpp b/src/client/component/slowmotion.cpp deleted file mode 100644 index 71f66dbf..00000000 --- a/src/client/component/slowmotion.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "game/game.hpp" - -#include -#include - -namespace slowmotion -{ - namespace - { - void scr_cmd_set_slow_motion() - { - if (game::Scr_GetNumParam() < 1) - { - return; - } - - int duration = 1000; - float end = 1.0f; - const float start = game::Scr_GetFloat(0); - - if (game::Scr_GetNumParam() >= 2) - { - end = game::Scr_GetFloat(1u); - } - - if (game::Scr_GetNumParam() >= 3) - { - duration = static_cast(game::Scr_GetFloat(2u) * 1000.0f); - } - - game::SV_SetConfigstring(10, utils::string::va("%i %i %g %g", *game::mp::gameTime, duration, start, end)); - game::Com_SetSlowMotion(start, end, duration); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (!game::environment::is_dedi()) - { - return; - } - - utils::hook::jump(0x140365480, scr_cmd_set_slow_motion); // H1(1.4) - } - }; -} - -REGISTER_COMPONENT(slowmotion::component) diff --git a/src/client/component/thread_names.cpp b/src/client/component/thread_names.cpp deleted file mode 100644 index 84b5fa70..00000000 --- a/src/client/component/thread_names.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "scheduler.hpp" - -#include "game/game.hpp" - -#include - -namespace thread_names -{ - namespace - { - void set_thread_names() - { - static std::unordered_map thread_names = - { - {game::THREAD_CONTEXT_MAIN, "Main"}, - {game::THREAD_CONTEXT_BACKEND, "Backend"}, // Renderer - {game::THREAD_CONTEXT_WORKER0, "Worker0"}, - {game::THREAD_CONTEXT_WORKER1, "Worker1"}, - {game::THREAD_CONTEXT_WORKER2, "Worker2"}, - {game::THREAD_CONTEXT_WORKER3, "Worker3"}, - {game::THREAD_CONTEXT_WORKER4, "Worker4"}, - {game::THREAD_CONTEXT_WORKER5, "Worker5"}, - {game::THREAD_CONTEXT_WORKER6, "Worker6"}, - {game::THREAD_CONTEXT_WORKER7, "Worker7"}, - {game::THREAD_CONTEXT_SERVER, "Server"}, - {game::THREAD_CONTEXT_CINEMATIC, "Cinematic"}, - {game::THREAD_CONTEXT_DATABASE, "Database"}, - {game::THREAD_CONTEXT_STREAM, "Stream"}, - {game::THREAD_CONTEXT_SNDSTREAMPACKETCALLBACK, "Snd stream packet callback"}, - {game::THREAD_CONTEXT_STATS_WRITE, "Stats write"}, - }; - - for (const auto& thread_name : thread_names) - { - const auto id = game::threadIds[thread_name.first]; - if (id) - { - utils::thread::set_name(id, thread_name.second); - } - } - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - set_thread_names(); - scheduler::once(set_thread_names, scheduler::pipeline::main); - scheduler::once(set_thread_names, scheduler::pipeline::renderer); - scheduler::once(set_thread_names, scheduler::pipeline::server); - } - }; -} - -REGISTER_COMPONENT(thread_names::component) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp deleted file mode 100644 index 941dda10..00000000 --- a/src/client/component/ui_scripting.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include "scheduler.hpp" -#include "command.hpp" - -#include "ui_scripting.hpp" - -#include "game/ui_scripting/lua/engine.hpp" -#include "game/ui_scripting/execution.hpp" -#include "game/ui_scripting/lua/error.hpp" - -#include -#include - -namespace ui_scripting -{ - namespace - { - std::unordered_map converted_functions; - - utils::hook::detour hksi_lual_error_hook; - utils::hook::detour hksi_lual_error_hook2; - utils::hook::detour hks_start_hook; - utils::hook::detour hks_shutdown_hook; - utils::hook::detour hks_allocator_hook; - utils::hook::detour hks_frame_hook; - - bool error_hook_enabled = false; - - void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...) - { - char va_buffer[2048] = {0}; - - va_list ap; - va_start(ap, fmt); - vsprintf_s(va_buffer, fmt, ap); - va_end(ap); - - const auto formatted = std::string(va_buffer); - - if (!error_hook_enabled) - { - return hksi_lual_error_hook.invoke(s, formatted.data()); - } - else - { - throw std::runtime_error(formatted); - } - } - - void* hks_start_stub(char a1) - { - const auto _1 = gsl::finally([]() - { - ui_scripting::lua::engine::start(); - }); - - return hks_start_hook.invoke(a1); - } - - void hks_shutdown_stub() - { - ui_scripting::lua::engine::stop(); - hks_shutdown_hook.invoke(); - } - - void* hks_allocator_stub(void* userData, void* oldMemory, unsigned __int64 oldSize, unsigned __int64 newSize) - { - const auto closure = reinterpret_cast(oldMemory); - if (converted_functions.find(closure) != converted_functions.end()) - { - converted_functions.erase(closure); - } - - return hks_allocator_hook.invoke(userData, oldMemory, oldSize, newSize); - } - - void hks_frame_stub() - { - const auto state = *game::hks::lua_state; - if (state) - { - ui_scripting::lua::engine::run_frame(); - } - } - } - - int main_function_handler(game::hks::lua_State* state) - { - const auto value = state->m_apistack.base[-1]; - if (value.t != game::hks::TCFUNCTION) - { - return 0; - } - - const auto closure = reinterpret_cast(value.v.cClosure); - if (converted_functions.find(closure) == converted_functions.end()) - { - return 0; - } - - const auto function = converted_functions[closure]; - const auto count = static_cast(state->m_apistack.top - state->m_apistack.base); - const auto arguments = get_return_values(count); - const auto s = function.lua_state(); - - std::vector converted_args; - - for (const auto& argument : arguments) - { - converted_args.push_back(lua::convert(s, argument)); - } - - const auto results = function(sol::as_args(converted_args)); - lua::handle_error(results); - - for (const auto& result : results) - { - push_value(lua::convert({s, result})); - } - - return results.return_count(); - } - - void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function) - { - converted_functions[closure] = function; - } - - void clear_converted_functions() - { - converted_functions.clear(); - } - - void enable_error_hook() - { - error_hook_enabled = true; - } - - void disable_error_hook() - { - error_hook_enabled = false; - } - - class component final : public component_interface - { - public: - - void post_unpack() override - { - if (game::environment::is_dedi()) - { - return; - } - - hks_start_hook.create(SELECT_VALUE(0x1400E4B40, 0x140176A40), hks_start_stub); - hks_shutdown_hook.create(SELECT_VALUE(0x1400DD3D0, 0x14016CA80), hks_shutdown_stub); - hksi_lual_error_hook.create(SELECT_VALUE(0x1400A5EA0, 0x14012F300), hksi_lual_error_stub); - hks_allocator_hook.create(SELECT_VALUE(0x14009B570, 0x14012BAC0), hks_allocator_stub); - hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), hks_frame_stub); - - if (game::environment::is_mp()) - { - hksi_lual_error_hook2.create(0x1401366B0, hksi_lual_error_stub); - } - - command::add("lui_restart", []() - { - utils::hook::invoke(SELECT_VALUE(0x1400DD3D0, 0x14016CA80)); - utils::hook::invoke(SELECT_VALUE(0x1400E6170, 0x1401780D0)); - }); - } - }; -} - -REGISTER_COMPONENT(ui_scripting::component) \ No newline at end of file diff --git a/src/client/component/ui_scripting.hpp b/src/client/component/ui_scripting.hpp deleted file mode 100644 index 2a48f6ec..00000000 --- a/src/client/component/ui_scripting.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "game/ui_scripting/lua/value_conversion.hpp" - -namespace ui_scripting -{ - int main_function_handler(game::hks::lua_State* state); - void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function); - void clear_converted_functions(); - - void enable_error_hook(); - void disable_error_hook(); -} \ No newline at end of file diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp deleted file mode 100644 index 939dbd1c..00000000 --- a/src/client/component/updater.cpp +++ /dev/null @@ -1,474 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "scheduler.hpp" -#include "dvars.hpp" -#include "updater.hpp" - -#include "version.h" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include -#include -#include -#include -#include -#include - -#define MASTER "https://master.fed0001.xyz/h1-mod/" - -#define FILES_PATH "files.json" -#define FILES_PATH_DEV "files-dev.json" - -#define DATA_PATH "data/" -#define DATA_PATH_DEV "data-dev/" - -#define ERR_UPDATE_CHECK_FAIL "Failed to check for updates" -#define ERR_DOWNLOAD_FAIL "Failed to download file " -#define ERR_WRITE_FAIL "Failed to write file " - -#define BINARY_NAME "h1-mod.exe" - -namespace updater -{ - namespace - { - game::dvar_t* cl_auto_update; - bool has_tried_update = false; - - struct status - { - bool done; - bool success; - }; - - struct file_data - { - std::string name; - std::string data; - }; - - struct update_data_t - { - bool restart_required{}; - bool cancelled{}; - status check{}; - status download{}; - std::string error{}; - std::string current_file{}; - std::vector required_files{}; - }; - - utils::concurrency::container update_data; - - std::string get_branch() - { - return GIT_BRANCH; - } - - std::string select(const std::string& main, const std::string& develop) - { - if (get_branch() == "develop") - { - return develop; - } - - return main; - } - - std::string get_data_path() - { - if (get_branch() == "develop") - { - return DATA_PATH_DEV; - } - - return DATA_PATH; - } - - void set_update_check_status(bool done, bool success, const std::string& error = {}) - { - update_data.access([done, success, error](update_data_t& data_) - { - data_.check.done = done; - data_.check.success = success; - data_.error = error; - }); - } - - void set_update_download_status(bool done, bool success, const std::string& error = {}) - { - update_data.access([done, success, error](update_data_t& data_) - { - data_.download.done = done; - data_.download.success = success; - data_.error = error; - }); - } - - bool check_file(const std::string& name, const std::string& sha) - { - std::string data; - if (!utils::io::read_file(name, &data)) - { - return false; - } - - if (utils::cryptography::sha1::compute(data, true) != sha) - { - return false; - } - - return true; - } - - std::string load_binary_name() - { - // utils::nt::library self; - // return self.get_name(); - // returns the game's name and not the client's - - return BINARY_NAME; - } - - std::string get_binary_name() - { - static const auto name = load_binary_name(); - return name; - } - - std::string get_time_str() - { - return utils::string::va("%i", uint32_t(time(nullptr))); - } - - std::optional download_file(const std::string& name) - { - return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name + "?" + get_time_str()); - } - - bool is_update_cancelled() - { - return update_data.access([](update_data_t& data_) - { - return data_.cancelled; - }); - } - - bool write_file(const std::string& name, const std::string& data) - { - if (get_binary_name() == name && - utils::io::file_exists(name) && - !utils::io::move_file(name, name + ".old")) - { - return false; - } - -#ifdef DEBUG - return utils::io::write_file("update_test/" + name, data); -#else - return utils::io::write_file(name, data); -#endif - } - - void delete_old_file() - { - utils::io::remove_file(get_binary_name() + ".old"); - } - - void reset_data() - { - update_data.access([](update_data_t& data_) - { - data_ = {}; - }); - } - - std::string get_mode_flag() - { - if (game::environment::is_mp()) - { - return "-multiplayer"; - } - - if (game::environment::is_sp()) - { - return "-singleplayer"; - } - - return {}; - } - } - - // workaround - void relaunch() - { - if (!utils::io::file_exists(BINARY_NAME)) - { - utils::nt::terminate(0); - return; - } - - STARTUPINFOA startup_info; - PROCESS_INFORMATION process_info; - - ZeroMemory(&startup_info, sizeof(startup_info)); - ZeroMemory(&process_info, sizeof(process_info)); - startup_info.cb = sizeof(startup_info); - - char current_dir[MAX_PATH]; - GetCurrentDirectoryA(sizeof(current_dir), current_dir); - - char buf[1024] = {0}; - const auto command_line = utils::string::va("%s %s", GetCommandLineA(), get_mode_flag().data()); - strcpy_s(buf, 1024, command_line); - - CreateProcess(BINARY_NAME, buf, nullptr, nullptr, false, NULL, nullptr, current_dir, - &startup_info, &process_info); - - if (process_info.hThread && process_info.hThread != INVALID_HANDLE_VALUE) CloseHandle(process_info.hThread); - if (process_info.hProcess && process_info.hProcess != INVALID_HANDLE_VALUE) CloseHandle(process_info.hProcess); - - utils::nt::terminate(0); - } - - void set_has_tried_update(bool tried) - { - has_tried_update = tried; - } - - bool get_has_tried_update() - { - return has_tried_update; - } - - bool auto_updates_enabled() - { - return cl_auto_update->current.enabled; - } - - bool is_update_check_done() - { - return update_data.access([](update_data_t& data_) - { - return data_.check.done; - }); - } - - bool is_update_download_done() - { - return update_data.access([](update_data_t& data_) - { - return data_.download.done; - }); - } - - bool get_update_check_status() - { - return update_data.access([](update_data_t& data_) - { - return data_.check.success; - }); - } - - bool get_update_download_status() - { - return update_data.access([](update_data_t& data_) - { - return data_.download.success; - }); - } - - bool is_update_available() - { - return update_data.access([](update_data_t& data_) - { - return data_.required_files.size() > 0; - }); - } - - bool is_restart_required() - { - return update_data.access([](update_data_t& data_) - { - return data_.restart_required; - }); - } - - std::string get_last_error() - { - return update_data.access([](update_data_t& data_) - { - return data_.error; - }); - } - - std::string get_current_file() - { - return update_data.access([](update_data_t& data_) - { - return data_.current_file; - }); - } - - void cancel_update() - { -#ifdef DEBUG - printf("[Updater] Cancelling update\n"); -#endif - - return update_data.access([](update_data_t& data_) - { - data_.cancelled = true; - }); - } - - void start_update_check() - { - cancel_update(); - reset_data(); - -#ifdef DEBUG - printf("[Updater] starting update check\n"); -#endif - - scheduler::once([]() - { - const auto files_data = utils::http::get_data(MASTER + select(FILES_PATH, FILES_PATH_DEV) + "?" + get_time_str()); - - if (is_update_cancelled()) - { - reset_data(); - return; - } - - if (!files_data.has_value()) - { - set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); - return; - } - - rapidjson::Document j; - j.Parse(files_data.value().data()); - - if (!j.IsArray()) - { - set_update_check_status(true, false, ERR_UPDATE_CHECK_FAIL); - return; - } - - std::vector required_files; - - const auto files = j.GetArray(); - for (const auto& file : files) - { - if (!file.IsArray() || file.Size() != 3 || !file[0].IsString() || !file[2].IsString()) - { - continue; - } - - const auto name = file[0].GetString(); - const auto sha = file[2].GetString(); - - if (!check_file(name, sha)) - { - if (get_binary_name() == name) - { - update_data.access([](update_data_t& data_) - { - data_.restart_required = true; - }); - } - -#ifdef DEBUG - printf("[Updater] need file %s\n", name); -#endif - - required_files.push_back(name); - } - } - - update_data.access([&required_files](update_data_t& data_) - { - data_.check.done = true; - data_.check.success = true; - data_.required_files = required_files; - }); - }, scheduler::pipeline::async); - } - - void start_update_download() - { -#ifdef DEBUG - printf("[Updater] starting update download\n"); -#endif - - if (!is_update_check_done() || !get_update_check_status() || is_update_cancelled()) - { - return; - } - - scheduler::once([]() - { - const auto required_files = update_data.access>([](update_data_t& data_) - { - return data_.required_files; - }); - - std::vector downloads; - - for (const auto& file : required_files) - { - update_data.access([file](update_data_t& data_) - { - data_.current_file = file; - }); - -#ifdef DEBUG - printf("[Updater] downloading file %s\n", file.data()); -#endif - - const auto data = download_file(file); - - if (is_update_cancelled()) - { - reset_data(); - return; - } - - if (!data.has_value()) - { - set_update_download_status(true, false, ERR_DOWNLOAD_FAIL + file); - return; - } - - downloads.push_back({file, data.value()}); - } - - for (const auto& download : downloads) - { - if (!write_file(download.name, download.data)) - { - set_update_download_status(true, false, ERR_WRITE_FAIL + download.name); - return; - } - } - - set_update_download_status(true, true); - }, scheduler::pipeline::async); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - delete_old_file(); - cl_auto_update = dvars::register_bool("cg_auto_update", true, game::DVAR_FLAG_SAVED, true); - } - }; -} - -REGISTER_COMPONENT(updater::component) diff --git a/src/client/component/updater.hpp b/src/client/component/updater.hpp deleted file mode 100644 index 9a3dd45e..00000000 --- a/src/client/component/updater.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -namespace updater -{ - void relaunch(); - - void set_has_tried_update(bool tried); - bool get_has_tried_update(); - bool auto_updates_enabled(); - - bool is_update_available(); - bool is_update_check_done(); - bool get_update_check_status(); - - bool is_update_download_done(); - bool get_update_download_status(); - - bool is_restart_required(); - - std::string get_last_error(); - std::string get_current_file(); - - void start_update_check(); - void start_update_download(); - void cancel_update(); -} \ No newline at end of file diff --git a/src/client/component/videos.cpp b/src/client/component/videos.cpp deleted file mode 100644 index a602cc8a..00000000 --- a/src/client/component/videos.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" - -#include - -namespace videos -{ - namespace - { - utils::hook::detour playvid_hook; - std::unordered_map video_replaces; - - void playvid(const char* name, const int a2, const int a3) - { - const auto vid = video_replaces.find(name); - if (vid != video_replaces.end()) - { - char path[256]; - game::Sys_BuildAbsPath(path, sizeof(path), game::SF_VIDEO, vid->second.data(), ".bik"); - - if (game::Sys_FileExists(path)) - { - name = vid->second.data(); - } - } - - return playvid_hook.invoke(name, a2, a3); - } - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - playvid_hook.create(SELECT_VALUE(0x1404A9D00, 0x1405B0AF0), &playvid); // H1(1.4) - - if (game::environment::is_mp()) - { - video_replaces["menus_bg_comp2"] = "menus_bg_h1mod"; - video_replaces["mp_menus_bg_options"] = "menus_bg_h1mod_blur"; - } - else if (game::environment::is_sp()) - { - video_replaces["sp_menus_bg_main_menu"] = "menus_bg_h1mod_sp"; - video_replaces["sp_menus_bg_campaign"] = "menus_bg_h1mod_sp"; - video_replaces["sp_menus_bg_options"] = "menus_bg_h1mod_sp"; - } - } - }; -} - -REGISTER_COMPONENT(videos::component) diff --git a/src/client/component/virtuallobby.cpp b/src/client/component/virtuallobby.cpp deleted file mode 100644 index eb6295f7..00000000 --- a/src/client/component/virtuallobby.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include "loader/component_loader.hpp" - -#include "game/game.hpp" -#include "game/dvars.hpp" - -#include - -namespace virtuallobby -{ - namespace - { - game::dvar_t* virtualLobby_fovscale; - - const auto get_fovscale_stub = utils::hook::assemble([](utils::hook::assembler& a) - { - const auto ret = a.newLabel(); - const auto original = a.newLabel(); - - a.pushad64(); - a.mov(rax, qword_ptr(0x1425F7210)); // virtualLobbyInFiringRange - a.cmp(byte_ptr(rax, 0x10), 1); - a.je(original); - a.call_aligned(game::VirtualLobby_Loaded); - a.cmp(al, 0); - a.je(original); - - // virtuallobby - a.popad64(); - a.mov(rax, ptr(reinterpret_cast(&virtualLobby_fovscale))); - a.jmp(ret); - - // original - a.bind(original); - a.popad64(); - a.mov(rax, qword_ptr(0x1413A8580)); - a.jmp(ret); - - a.bind(ret); - a.mov(rcx, 0x142935000); - a.jmp(0x1400B556A); - }); - } - - class component final : public component_interface - { - public: - void post_unpack() override - { - if (!game::environment::is_mp()) - { - return; - } - - virtualLobby_fovscale = dvars::register_float("virtualLobby_fovScale", 0.7f, 0.0f, 2.0f, game::DVAR_FLAG_SAVED); - - utils::hook::nop(0x1400B555C, 14); - utils::hook::jump(0x1400B555C, get_fovscale_stub, true); - } - }; -} - -REGISTER_COMPONENT(virtuallobby::component) diff --git a/src/client/game/scripting/entity.cpp b/src/client/game/scripting/entity.cpp deleted file mode 100644 index b81dea1b..00000000 --- a/src/client/game/scripting/entity.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include "entity.hpp" -#include "script_value.hpp" -#include "execution.hpp" - -namespace scripting -{ - entity::entity() - : entity(0) - { - } - - entity::entity(const entity& other) : entity(other.entity_id_) - { - } - - entity::entity(entity&& other) noexcept - { - this->entity_id_ = other.entity_id_; - other.entity_id_ = 0; - } - - entity::entity(const unsigned int entity_id) - : entity_id_(entity_id) - { - this->add(); - } - - entity::entity(game::scr_entref_t entref) - : entity(game::FindEntityId(entref.entnum, entref.classnum)) - { - } - - entity::~entity() - { - this->release(); - } - - entity& entity::operator=(const entity& other) - { - if (&other != this) - { - this->release(); - this->entity_id_ = other.entity_id_; - this->add(); - } - - return *this; - } - - entity& entity::operator=(entity&& other) noexcept - { - if (&other != this) - { - this->release(); - this->entity_id_ = other.entity_id_; - other.entity_id_ = 0; - } - - return *this; - } - - unsigned int entity::get_entity_id() const - { - return this->entity_id_; - } - - game::scr_entref_t entity::get_entity_reference() const - { - if (!this->entity_id_) - { - const auto not_null = static_cast(~0ui16); - return game::scr_entref_t{not_null, not_null}; - } - - return game::Scr_GetEntityIdRef(this->get_entity_id()); - } - - bool entity::operator==(const entity& other) const noexcept - { - return this->get_entity_id() == other.get_entity_id(); - } - - bool entity::operator!=(const entity& other) const noexcept - { - return !this->operator==(other); - } - - void entity::add() const - { - if (this->entity_id_) - { - game::AddRefToValue(game::SCRIPT_OBJECT, {static_cast(this->entity_id_)}); - } - } - - void entity::release() const - { - if (this->entity_id_) - { - game::RemoveRefToValue(game::SCRIPT_OBJECT, {static_cast(this->entity_id_)}); - } - } - - void entity::set(const std::string& field, const script_value& value) const - { - set_entity_field(*this, field, value); - } - - template <> - script_value entity::get(const std::string& field) const - { - return get_entity_field(*this, field); - } - - script_value entity::call(const std::string& name, const std::vector& arguments) const - { - return call_function(name, *this, arguments); - } -} diff --git a/src/client/game/scripting/entity.hpp b/src/client/game/scripting/entity.hpp deleted file mode 100644 index b1702379..00000000 --- a/src/client/game/scripting/entity.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -#include "game/game.hpp" -#include "script_value.hpp" - -namespace scripting -{ - class entity final - { - public: - entity(); - entity(unsigned int entity_id); - entity(game::scr_entref_t entref); - - entity(const entity& other); - entity(entity&& other) noexcept; - - ~entity(); - - entity& operator=(const entity& other); - entity& operator=(entity&& other) noexcept; - - void set(const std::string& field, const script_value& value) const; - - template - T get(const std::string& field) const; - - script_value call(const std::string& name, const std::vector& arguments = {}) const; - - unsigned int get_entity_id() const; - game::scr_entref_t get_entity_reference() const; - - bool operator ==(const entity& other) const noexcept; - bool operator !=(const entity& other) const noexcept; - - private: - unsigned int entity_id_; - - void add() const; - void release() const; - }; - - template <> - script_value entity::get(const std::string& field) const; - - template - T entity::get(const std::string& field) const - { - return this->get(field).as(); - } -} diff --git a/src/client/game/scripting/event.hpp b/src/client/game/scripting/event.hpp deleted file mode 100644 index bc1d53e0..00000000 --- a/src/client/game/scripting/event.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "script_value.hpp" -#include "entity.hpp" - -namespace scripting -{ - struct event - { - std::string name; - entity entity{}; - std::vector arguments; - }; -} diff --git a/src/client/game/scripting/execution.cpp b/src/client/game/scripting/execution.cpp deleted file mode 100644 index 29faaad4..00000000 --- a/src/client/game/scripting/execution.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include -#include "execution.hpp" -#include "safe_execution.hpp" -#include "stack_isolation.hpp" - -#include "component/scripting.hpp" - -namespace scripting -{ - namespace - { - game::VariableValue* allocate_argument() - { - game::VariableValue* value_ptr = ++game::scr_VmPub->top; - ++game::scr_VmPub->inparamcount; - return value_ptr; - } - - void push_value(const script_value& value) - { - auto* value_ptr = allocate_argument(); - *value_ptr = value.get_raw(); - - game::AddRefToValue(value_ptr->type, value_ptr->u); - } - - int get_field_id(const int classnum, const std::string& field) - { - if (scripting::fields_table[classnum].find(field) != scripting::fields_table[classnum].end()) - { - return scripting::fields_table[classnum][field]; - } - - return -1; - } - - script_value get_return_value() - { - if (game::scr_VmPub->inparamcount == 0) - { - return {}; - } - - game::Scr_ClearOutParams(); - game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount; - game::scr_VmPub->inparamcount = 0; - - return script_value(game::scr_VmPub->top[1 - game::scr_VmPub->outparamcount]); - } - } - - void notify(const entity& entity, const std::string& event, const std::vector& arguments) - { - stack_isolation _; - for (auto i = arguments.rbegin(); i != arguments.rend(); ++i) - { - push_value(*i); - } - - const auto event_id = game::SL_GetString(event.data(), 0); - game::Scr_NotifyId(entity.get_entity_id(), event_id, game::scr_VmPub->inparamcount); - } - - script_value call_function(const std::string& name, const entity& entity, - const std::vector& arguments) - { - const auto entref = entity.get_entity_reference(); - - const auto is_method_call = *reinterpret_cast(&entref) != -1; - const auto function = find_function(name, !is_method_call); - if (function == nullptr) - { - throw std::runtime_error("Unknown "s + (is_method_call ? "method" : "function") + " '" + name + "'"); - } - - stack_isolation _; - - for (auto i = arguments.rbegin(); i != arguments.rend(); ++i) - { - push_value(*i); - } - - game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount; - game::scr_VmPub->inparamcount = 0; - - if (!safe_execution::call(function, entref)) - { - throw std::runtime_error( - "Error executing "s + (is_method_call ? "method" : "function") + " '" + name + "'"); - } - - return get_return_value(); - } - - script_value call_function(const std::string& name, const std::vector& arguments) - { - return call_function(name, entity(), arguments); - } - - template <> - script_value call(const std::string& name, const std::vector& arguments) - { - return call_function(name, arguments); - } - - script_value exec_ent_thread(const entity& entity, const char* pos, const std::vector& arguments) - { - const auto id = entity.get_entity_id(); - - stack_isolation _; - for (auto i = arguments.rbegin(); i != arguments.rend(); ++i) - { - scripting::push_value(*i); - } - - game::AddRefToObject(id); - - const auto local_id = game::AllocThread(id); - const auto result = game::VM_Execute(local_id, pos, (unsigned int)arguments.size()); - game::RemoveRefToObject(result); - - return get_return_value(); - } - - const char* get_function_pos(const std::string& filename, const std::string& function) - { - if (scripting::script_function_table.find(filename) == scripting::script_function_table.end()) - { - throw std::runtime_error("File '" + filename + "' not found"); - }; - - const auto functions = scripting::script_function_table[filename]; - if (functions.find(function) == functions.end()) - { - throw std::runtime_error("Function '" + function + "' in file '" + filename + "' not found"); - } - - return functions.at(function); - } - - script_value call_script_function(const entity& entity, const std::string& filename, - const std::string& function, const std::vector& arguments) - { - const auto pos = get_function_pos(filename, function); - return exec_ent_thread(entity, pos, arguments); - } - - static std::unordered_map> custom_fields; - - script_value get_custom_field(const entity& entity, const std::string& field) - { - auto& fields = custom_fields[entity.get_entity_id()]; - const auto _field = fields.find(field); - if (_field != fields.end()) - { - return _field->second; - } - return {}; - } - - void set_custom_field(const entity& entity, const std::string& field, const script_value& value) - { - const auto id = entity.get_entity_id(); - - if (custom_fields[id].find(field) != custom_fields[id].end()) - { - custom_fields[id][field] = value; - return; - } - - custom_fields[id].insert(std::make_pair(field, value)); - } - - void clear_entity_fields(const entity& entity) - { - const auto id = entity.get_entity_id(); - - if (custom_fields.find(id) != custom_fields.end()) - { - custom_fields[id].clear(); - } - } - - void clear_custom_fields() - { - custom_fields.clear(); - } - - void set_entity_field(const entity& entity, const std::string& field, const script_value& value) - { - const auto entref = entity.get_entity_reference(); - const int id = get_field_id(entref.classnum, field); - - if (id != -1) - { - stack_isolation _; - push_value(value); - - game::scr_VmPub->outparamcount = game::scr_VmPub->inparamcount; - game::scr_VmPub->inparamcount = 0; - - if (!safe_execution::set_entity_field(entref, id)) - { - throw std::runtime_error("Failed to set value for field '" + field + "'"); - } - } - else - { - // Read custom fields - set_custom_field(entity, field, value); - } - } - - script_value get_entity_field(const entity& entity, const std::string& field) - { - const auto entref = entity.get_entity_reference(); - const auto id = get_field_id(entref.classnum, field); - - if (id != -1) - { - stack_isolation _; - - game::VariableValue value{}; - if (!safe_execution::get_entity_field(entref, id, &value)) - { - throw std::runtime_error("Failed to get value for field '" + field + "'"); - } - - const auto __ = gsl::finally([value]() - { - game::RemoveRefToValue(value.type, value.u); - }); - - return value; - } - - // Add custom fields - return get_custom_field(entity, field); - } -} diff --git a/src/client/game/scripting/execution.hpp b/src/client/game/scripting/execution.hpp deleted file mode 100644 index 7fff1840..00000000 --- a/src/client/game/scripting/execution.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include "game/game.hpp" -#include "entity.hpp" -#include "script_value.hpp" - -namespace scripting -{ - script_value call_function(const std::string& name, const std::vector& arguments); - script_value call_function(const std::string& name, const entity& entity, - const std::vector& arguments); - - template - T call(const std::string& name, const std::vector& arguments = {}); - - template <> - script_value call(const std::string& name, const std::vector& arguments); - - template - T call(const std::string& name, const std::vector& arguments) - { - return call(name, arguments).as(); - } - - script_value exec_ent_thread(const entity& entity, const char* pos, const std::vector& arguments); - const char* get_function_pos(const std::string& filename, const std::string& function); - script_value call_script_function(const entity& entity, const std::string& filename, - const std::string& function, const std::vector& arguments); - - void clear_entity_fields(const entity& entity); - void clear_custom_fields(); - - void set_entity_field(const entity& entity, const std::string& field, const script_value& value); - script_value get_entity_field(const entity& entity, const std::string& field); - - void notify(const entity& entity, const std::string& event, const std::vector& arguments); -} diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp deleted file mode 100644 index 9a70a9dd..00000000 --- a/src/client/game/scripting/function_tables.cpp +++ /dev/null @@ -1,3480 +0,0 @@ -#include - -// This file has been generated. -// Do not touch! - -// https://github.com/xensik/gsc-tool/blob/dev/src/h1/xsk/resolver.cpp :) - -namespace scripting -{ - std::unordered_map function_map = - { - {"_func_001", 0x001}, // SP 0x14029D940 MP 0x140368EA0 - {"getweaponarray", 0x002}, // SP 0x14028F750 MP 0x140357B80 - {"_func_003", 0x003}, // SP 0x1405D92F0 MP 0x1403668A0 - {"_func_004", 0x004}, // SP 0x1402ACD70 MP 0x000000000 - {"_func_005", 0x005}, // SP 0x1402ADB70 MP 0x000000000 - {"_func_006", 0x006}, // SP 0x1402A8E20 MP 0x000000000 - {"_func_007", 0x007}, // SP 0x1402A8B20 MP 0x000000000 - {"_func_008", 0x008}, // SP 0x1402A8B40 MP 0x000000000 - {"_func_009", 0x009}, // SP 0x1402A8BC0 MP 0x000000000 - {"_func_00A", 0x00A}, // SP 0x1402A8B60 MP 0x000000000 - {"_func_00B", 0x00B}, // SP 0x1402A8960 MP 0x000000000 - {"_func_00C", 0x00C}, // SP 0x1402ADBE0 MP 0x000000000 - {"_func_00D", 0x00D}, // SP 0x1402ADC60 MP 0x000000000 - {"_func_00E", 0x00E}, // SP 0x1402ADC90 MP 0x000000000 - {"_func_00F", 0x00F}, // SP 0x1405D92F0 MP 0x1403669E0 - {"_func_010", 0x010}, // SP 0x14029AF60 MP 0x1403669F0 - {"_func_011", 0x011}, // SP 0x14029AF60 MP 0x140366D40 - {"_func_012", 0x012}, // SP 0x1405D92F0 MP 0x140367400 - {"_func_013", 0x013}, // SP 0x1405D92F0 MP 0x140367520 - {"_func_014", 0x014}, // SP 0x1405D92F0 MP 0x140367530 - {"_func_015", 0x015}, // SP 0x1405D92F0 MP 0x1403675E0 - {"_func_016", 0x016}, // SP 0x1405D92F0 MP 0x140367660 - {"_func_017", 0x017}, // SP 0x1405D92F0 MP 0x140367890 - {"spawnturret", 0x018}, // SP 0x14029D650 MP 0x140368B10 - {"canspawnturret", 0x019}, // SP 0x14029D870 MP 0x140368E80 - {"_func_01A", 0x01A}, // SP 0x14029C9B0 MP 0x1403678A0 - {"_func_01B", 0x01B}, // SP 0x1402AB640 MP 0x000000000 - {"_func_01C", 0x01C}, // SP 0x1402AB670 MP 0x000000000 - {"_func_01D", 0x01D}, // SP 0x1402AB7A0 MP 0x000000000 - {"_func_01E", 0x01E}, // SP 0x1402AB960 MP 0x000000000 - {"badplace_delete", 0x01F}, // SP 0x14028F340 MP 0x140358600 - {"badplace_cylinder", 0x020}, // SP 0x14028F4B0 MP 0x140358C50 - {"badplace_arc", 0x021}, // SP 0x14028F830 MP 0x140359110 - {"badplace_brush", 0x022}, // SP 0x14028FF10 MP 0x140359CB0 - {"_func_023", 0x023}, // SP 0x1402AC9D0 MP 0x000000000 - {"_func_024", 0x024}, // SP 0x1402CC640 MP 0x000000000 - {"_func_025", 0x025}, // SP 0x1402CC6E0 MP 0x000000000 - {"_func_026", 0x026}, // SP 0x1402CC570 MP 0x000000000 - {"_func_027", 0x027}, // SP 0x1402CC430 MP 0x000000000 - {"_func_02A", 0x02A}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_02B", 0x02B}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_02C", 0x02C}, // SP 0x1402ACD10 MP 0x000000000 - {"_func_02D", 0x02D}, // SP 0x14029C9B0 MP 0x140367950 - {"_func_02E", 0x02E}, // SP 0x14029CAC0 MP 0x140367980 - {"isdefined", 0x02F}, // SP 0x14029D000 MP 0x140368520 - {"isvalidmissile", 0x030}, // SP 0x14029D3E0 MP 0x140368A70 - {"_func_031", 0x031}, // SP 0x14029D630 MP 0x140368D30 - {"_func_032", 0x032}, // SP 0x14029E0A0 MP 0x14036A580 - {"_func_033", 0x033}, // SP 0x14029E220 MP 0x14036A7C0 - {"setdynamicdvar", 0x034}, // SP 0x14029EB20 MP 0x14036AE70 - {"_func_035", 0x035}, // SP 0x000000000 MP 0x14036B600 - {"_func_036", 0x036}, // SP 0x14029F8F0 MP 0x14036BB60 - {"setdvar", 0x037}, // SP 0x14029F1C0 MP 0x14036B7F0 - {"_func_038", 0x038}, // SP 0x14029F8F0 MP 0x14036C070 - {"getdvar", 0x039}, // SP 0x14029FE30 MP 0x14036C350 - {"getdvarint", 0x03A}, // SP 0x1402A0270 MP 0x14036C7B0 - {"getdvarfloat", 0x03B}, // SP 0x1402A0810 MP 0x14036CDD0 - {"getdvarvector", 0x03C}, // SP 0x1402A10E0 MP 0x14036D190 - {"_func_03D", 0x03D}, // SP 0x1402A1A50 MP 0x14036DB40 - {"_func_03E", 0x03E}, // SP 0x1402A1A60 MP 0x14036DD80 - {"_func_03F", 0x03F}, // SP 0x1402A1AC0 MP 0x14036DDA0 - {"getentbynum", 0x040}, // SP 0x1402A1C50 MP 0x14036DF50 - {"_func_041", 0x041}, // SP 0x1402A1D10 MP 0x000000000 - {"_func_042", 0x042}, // SP 0x1402A1D20 MP 0x000000000 - {"_func_043", 0x043}, // SP 0x1402A1D30 MP 0x14036E110 - {"_func_044", 0x044}, // SP 0x1402ABBE0 MP 0x000000000 - {"_func_045", 0x045}, // SP 0x1402ABCF0 MP 0x000000000 - {"_func_046", 0x046}, // SP 0x1402ABD30 MP 0x000000000 - {"_func_047", 0x047}, // SP 0x1402ABD90 MP 0x1403775E0 - {"_func_048", 0x048}, // SP 0x1402ABE60 MP 0x140377840 - {"_func_049", 0x049}, // SP 0x1402ABF90 MP 0x000000000 - {"_func_04A", 0x04A}, // SP 0x1402ABFC0 MP 0x000000000 - {"_func_04B", 0x04B}, // SP 0x1402AC0E0 MP 0x000000000 - {"_func_04C", 0x04C}, // SP 0x1402AC210 MP 0x000000000 - {"_func_04D", 0x04D}, // SP 0x1402AC520 MP 0x000000000 - {"_func_04E", 0x04E}, // SP 0x1402AC6F0 MP 0x000000000 - {"_func_04F", 0x04F}, // SP 0x1402AC720 MP 0x000000000 - {"_func_050", 0x050}, // SP 0x1402AC740 MP 0x000000000 - {"_func_051", 0x051}, // SP 0x1402AC760 MP 0x000000000 - {"_func_052", 0x052}, // SP 0x1402AC780 MP 0x000000000 - {"_func_053", 0x053}, // SP 0x1402AC830 MP 0x000000000 - {"_func_054", 0x054}, // SP 0x1402AD6E0 MP 0x000000000 - {"_func_055", 0x055}, // SP 0x1402AAEC0 MP 0x000000000 - {"_func_056", 0x056}, // SP 0x1402AAF60 MP 0x000000000 - {"_func_057", 0x057}, // SP 0x1402AB040 MP 0x000000000 - {"_func_058", 0x058}, // SP 0x1402AB060 MP 0x000000000 - {"_func_059", 0x059}, // SP 0x1402AB140 MP 0x000000000 - {"_func_05A", 0x05A}, // SP 0x1402AB1E0 MP 0x000000000 - {"_func_05B", 0x05B}, // SP 0x1402AB2A0 MP 0x000000000 - {"_func_05C", 0x05C}, // SP 0x1402AB420 MP 0x000000000 - {"_func_05D", 0x05D}, // SP 0x1402AB4A0 MP 0x000000000 - {"_func_05E", 0x05E}, // SP 0x1402AB620 MP 0x000000000 - {"_func_05F", 0x05F}, // SP 0x1402A2410 MP 0x14036E740 - {"_func_060", 0x060}, // SP 0x1402A2910 MP 0x14036ED60 - {"_func_061", 0x061}, // SP 0x1402A3170 MP 0x14036F3E0 - {"_func_062", 0x062}, // SP 0x1402A34D0 MP 0x140357CA0 - {"getweaponreticlename", 0x063}, // SP 0x14028DEA0 MP 0x140358890 - {"_func_064", 0x064}, // SP 0x14028E0B0 MP 0x140358B80 - {"getanimlength", 0x065}, // SP 0x14028FB80 MP 0x14035AB80 - {"animhasnotetrack", 0x066}, // SP 0x14028FD60 MP 0x14035B110 - {"getnotetracktimes", 0x067}, // SP 0x14028FDC0 MP 0x14035B220 - {"spawn", 0x068}, // SP 0x14029D0C0 MP 0x140368410 - {"spawnloopsound", 0x069}, // SP 0x14029D0C0 MP 0x140368410 - {"_func_06A", 0x06A}, // SP 0x140444BB0 MP 0x14036AF90 - {"_func_06B", 0x06B}, // SP 0x14029E950 MP 0x140366EF0 - {"_func_06C", 0x06C}, // SP 0x1402BBCA0 MP 0x000000000 - {"_func_06D", 0x06D}, // SP 0x1402BB830 MP 0x000000000 - {"_func_06E", 0x06E}, // SP 0x1402BB990 MP 0x000000000 - {"_func_06F", 0x06F}, // SP 0x14025D860 MP 0x140375D40 - {"_func_070", 0x070}, // SP 0x14025D770 MP 0x140375F10 - {"_func_071", 0x071}, // SP 0x14025D630 MP 0x000000000 - {"_func_072", 0x072}, // SP 0x1402AB510 MP 0x000000000 - {"_func_073", 0x073}, // SP 0x1402981B0 MP 0x140364BC0 - {"_func_074", 0x074}, // SP 0x1402AFD80 MP 0x000000000 - {"_func_075", 0x075}, // SP 0x1402AFEA0 MP 0x000000000 - {"_func_076", 0x076}, // SP 0x1402A78A0 MP 0x000000000 - {"_func_077", 0x077}, // SP 0x1402A79D0 MP 0x000000000 - {"_func_078", 0x078}, // SP 0x14029E170 MP 0x140367970 - {"_func_079", 0x079}, // SP 0x14029E210 MP 0x140367990 - {"_func_07A", 0x07A}, // SP 0x14029E2D0 MP 0x140367D70 - {"_func_07B", 0x07B}, // SP 0x14029E320 MP 0x140367F30 - {"_func_07C", 0x07C}, // SP 0x14029E330 MP 0x140367F40 - {"_func_07D", 0x07D}, // SP 0x14029E730 MP 0x140367FA0 - {"_func_07E", 0x07E}, // SP 0x1402A7BF0 MP 0x000000000 - {"_func_07F", 0x07F}, // SP 0x1402A8BB0 MP 0x000000000 - {"_func_080", 0x080}, // SP 0x1402A7A80 MP 0x000000000 - {"_func_081", 0x081}, // SP 0x1402AAE30 MP 0x000000000 - {"_func_083", 0x083}, // SP 0x1402AAE50 MP 0x000000000 - {"_func_084", 0x084}, // SP 0x1402AAEA0 MP 0x000000000 - {"_func_085", 0x085}, // SP 0x1402A8CB0 MP 0x000000000 - {"_func_086", 0x086}, // SP 0x1402A9990 MP 0x000000000 - {"_func_087", 0x087}, // SP 0x1402A99B0 MP 0x000000000 - {"_func_088", 0x088}, // SP 0x1402A9100 MP 0x000000000 - {"_func_089", 0x089}, // SP 0x1402A99D0 MP 0x000000000 - {"_func_08A", 0x08A}, // SP 0x1402A9A70 MP 0x000000000 - {"_func_08B", 0x08B}, // SP 0x1402AB690 MP 0x000000000 - {"_func_08C", 0x08C}, // SP 0x1402ABB90 MP 0x000000000 - {"bullettracepassed", 0x08D}, // SP 0x14029F480 MP 0x140367410 - {"_func_08E", 0x08E}, // SP 0x14029F7A0 MP 0x140367670 - {"_func_08F", 0x08F}, // SP 0x14029FF90 MP 0x140367E20 - {"_func_090", 0x090}, // SP 0x1402A0360 MP 0x140368180 - {"_func_091", 0x091}, // SP 0x1402A2670 MP 0x14036A300 - {"getangledelta", 0x092}, // SP 0x14028F3D0 MP 0x14036E210 - {"getangledelta3d", 0x093}, // SP 0x14028FA60 MP 0x14036E910 - {"getnorthyaw", 0x094}, // SP 0x1402903E0 MP 0x140357C50 - {"_func_095", 0x095}, // SP 0x1402A7970 MP 0x000000000 - {"_func_096", 0x096}, // SP 0x1402A7A50 MP 0x000000000 - {"_func_097", 0x097}, // SP 0x1402A9B20 MP 0x000000000 - {"_func_098", 0x098}, // SP 0x1402A9B70 MP 0x000000000 - {"_func_099", 0x099}, // SP 0x1402A9AE0 MP 0x000000000 - {"_func_09A", 0x09A}, // SP 0x1402AE4D0 MP 0x000000000 - {"_func_09B", 0x09B}, // SP 0x1402BB040 MP 0x000000000 - {"_func_09C", 0x09C}, // SP 0x1402BB410 MP 0x000000000 - {"_func_09D", 0x09D}, // SP 0x1402BB6F0 MP 0x000000000 - {"_func_09E", 0x09E}, // SP 0x1402BB6B0 MP 0x000000000 - {"_func_09F", 0x09F}, // SP 0x1402BC260 MP 0x000000000 - {"_func_0A0", 0x0A0}, // SP 0x1402BBF00 MP 0x000000000 - {"_func_0A1", 0x0A1}, // SP 0x1402BB590 MP 0x000000000 - {"_func_0A2", 0x0A2}, // SP 0x1402BB520 MP 0x000000000 - {"_func_0A3", 0x0A3}, // SP 0x1402BC390 MP 0x000000000 - {"_func_0A4", 0x0A4}, // SP 0x1402BB060 MP 0x000000000 - {"_func_0A5", 0x0A5}, // SP 0x1402BB4A0 MP 0x000000000 - {"_func_0A6", 0x0A6}, // SP 0x1402BB630 MP 0x000000000 - {"_func_0A7", 0x0A7}, // SP 0x1402BB710 MP 0x000000000 - {"_func_0A8", 0x0A8}, // SP 0x1402BBB80 MP 0x000000000 - {"_func_0A9", 0x0A9}, // SP 0x1402BB510 MP 0x000000000 - {"_func_0AA", 0x0AA}, // SP 0x1402BC380 MP 0x000000000 - {"_func_0AB", 0x0AB}, // SP 0x1402BC140 MP 0x000000000 - {"_func_0AC", 0x0AC}, // SP 0x1402BB090 MP 0x000000000 - {"_func_0AD", 0x0AD}, // SP 0x1402BB2C0 MP 0x000000000 - {"_func_0AE", 0x0AE}, // SP 0x1402BB1C0 MP 0x000000000 - {"_func_0AF", 0x0AF}, // SP 0x1402BBDB0 MP 0x000000000 - {"_func_0B0", 0x0B0}, // SP 0x140290420 MP 0x140357E90 - {"setslowmotion", 0x0B1}, // SP 0x14029BC60 MP 0x140365480 - {"randomint", 0x0B2}, // SP 0x1402A2ED0 MP 0x14036A770 - {"randomfloat", 0x0B3}, // SP 0x1402A3140 MP 0x14036A9E0 - {"randomintrange", 0x0B4}, // SP 0x1402A3240 MP 0x14036ACD0 - {"randomfloatrange", 0x0B5}, // SP 0x1402A3310 MP 0x14036AE10 - {"sin", 0x0B6}, // SP 0x1402A3440 MP 0x14036B240 - {"cos", 0x0B7}, // SP 0x1402A34A0 MP 0x14036B550 - {"tan", 0x0B8}, // SP 0x1402A3610 MP 0x14036B5A0 - {"asin", 0x0B9}, // SP 0x1402A37D0 MP 0x14036B720 - {"acos", 0x0BA}, // SP 0x1402A3A60 MP 0x14036B7A0 - {"atan", 0x0BB}, // SP 0x14028D680 MP 0x14036BAE0 - {"int", 0x0BC}, // SP 0x14028DAE0 MP 0x14036BBF0 - {"float", 0x0BD}, // SP 0x14028DE30 MP 0x14036C000 - {"abs", 0x0BE}, // SP 0x14028DFC0 MP 0x14036C320 - {"_func_0BF", 0x0BF}, // SP 0x14028DFF0 MP 0x14036C580 - {"_func_0C0", 0x0C0}, // SP 0x1402B7A30 MP 0x000000000 - {"_func_0C1", 0x0C1}, // SP 0x1402B7B50 MP 0x000000000 - {"_func_0C2", 0x0C2}, // SP 0x1402B7BF0 MP 0x000000000 - {"getnode", 0x0C3}, // SP 0x1402CBED0 MP 0x14031FA00 - {"getnodearray", 0x0C4}, // SP 0x1402CBFE0 MP 0x14031FB10 - {"getallnodes", 0x0C5}, // SP 0x1402CBCD0 MP 0x14031F7E0 - {"_func_0C6", 0x0C6}, // SP 0x1402CC0F0 MP 0x14031FCC0 - {"_func_0C7", 0x0C7}, // SP 0x1402CC100 MP 0x14031FCD0 - {"_func_0C8", 0x0C8}, // SP 0x1402CBD20 MP 0x14031F830 - {"_func_0C9", 0x0C9}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_0CA", 0x0CA}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_0CB", 0x0CB}, // SP 0x140468CF0 MP 0x000000000 - {"_func_0CC", 0x0CC}, // SP 0x140468DD0 MP 0x000000000 - {"_func_0CD", 0x0CD}, // SP 0x140468CA0 MP 0x000000000 - {"isarray", 0x0CE}, // SP 0x140291BF0 MP 0x14035E620 - {"isai", 0x0CF}, // SP 0x1402ADC10 MP 0x140377460 - {"getindexforluincstring", 0x0D0}, // SP 0x14029DB50 MP 0x140369C50 - {"issentient", 0x0D1}, // SP 0x14029D7D0 MP 0x140368DA0 - {"_func_0D2", 0x0D2}, // SP 0x1402ADD90 MP 0x000000000 - {"_func_0D3", 0x0D3}, // SP 0x1402ADED0 MP 0x000000000 - {"_func_0D4", 0x0D4}, // SP 0x1402ADF60 MP 0x000000000 - {"_func_0D5", 0x0D5}, // SP 0x1402ADFD0 MP 0x000000000 - {"_func_0D6", 0x0D6}, // SP 0x1402AE020 MP 0x000000000 - {"_func_0D7", 0x0D7}, // SP 0x1402AE4E0 MP 0x000000000 - {"_func_0D8", 0x0D8}, // SP 0x1402AE4F0 MP 0x000000000 - {"_func_0D9", 0x0D9}, // SP 0x1402AE7A0 MP 0x000000000 - {"_func_0DA", 0x0DA}, // SP 0x1402AF980 MP 0x000000000 - {"_func_0DB", 0x0DB}, // SP 0x1402AFBD0 MP 0x000000000 - {"_func_0DC", 0x0DC}, // SP 0x1402AFB20 MP 0x000000000 - {"_func_0DD", 0x0DD}, // SP 0x1402AFCE0 MP 0x000000000 - {"_func_0DE", 0x0DE}, // SP 0x1402AFE20 MP 0x000000000 - {"_func_0DF", 0x0DF}, // SP 0x14029CAC0 MP 0x000000000 - {"_func_0E0", 0x0E0}, // SP 0x1402A7830 MP 0x000000000 - {"_func_0E1", 0x0E1}, // SP 0x14028E170 MP 0x14036C720 - {"floor", 0x0E2}, // SP 0x14028E1C0 MP 0x14036C750 - {"ceil", 0x0E3}, // SP 0x14028E260 MP 0x14036C770 - {"exp", 0x0E4}, // SP 0x14028E280 MP 0x14036C790 - {"exp", 0x0E5}, // SP 0x14028E370 MP 0x14036C820 - {"log", 0x0E6}, // SP 0x14028E410 MP 0x14036C840 - {"sqrt", 0x0E7}, // SP 0x14028E470 MP 0x14036CB80 - {"squared", 0x0E8}, // SP 0x14028E4B0 MP 0x14036CBA0 - {"_func_0E9", 0x0E9}, // SP 0x14028E770 MP 0x14036CE40 - {"_func_0EA", 0x0EA}, // SP 0x14028E8C0 MP 0x14036CF30 - {"angleclamp180", 0x0EB}, // SP 0x14028E920 MP 0x14036CFB0 - {"vectorfromlinetopoint", 0x0EC}, // SP 0x140290740 MP 0x14036E5A0 - {"pointonsegmentnearesttopoint", 0x0ED}, // SP 0x140290B60 MP 0x14036EB30 - {"_func_0EE", 0x0EE}, // SP 0x140291260 MP 0x14036F6E0 - {"_func_0EF", 0x0EF}, // SP 0x1402913A0 MP 0x14036F790 - {"_func_0F0", 0x0F0}, // SP 0x140291600 MP 0x140357E10 - {"_func_0F1", 0x0F1}, // SP 0x1402918C0 MP 0x140357FB0 - {"_func_0F2", 0x0F2}, // SP 0x140291930 MP 0x140358030 - {"_func_0F3", 0x0F3}, // SP 0x140291AF0 MP 0x140358130 - {"_func_0F4", 0x0F4}, // SP 0x140291B30 MP 0x140358190 - {"_func_0F5", 0x0F5}, // SP 0x140291C20 MP 0x1403581E0 - {"_func_0F6", 0x0F6}, // SP 0x140291EB0 MP 0x140358570 - {"_func_0F7", 0x0F7}, // SP 0x140291F80 MP 0x140358640 - {"axistoangles", 0x0F8}, // SP 0x140292690 MP 0x140359050 - {"_func_0F9", 0x0F9}, // SP 0x1402ABB50 MP 0x1403771E0 - {"_func_0FA", 0x0FA}, // SP 0x1402ABB60 MP 0x140377260 - {"_func_0FB", 0x0FB}, // SP 0x000000000 MP 0x14037B950 - {"_func_0FC", 0x0FC}, // SP 0x000000000 MP 0x140374E10 - {"getmapcustom", 0x0FD}, // SP 0x000000000 MP 0x140378260 - {"_func_0FE", 0x0FE}, // SP 0x000000000 MP 0x1403765A0 - {"incrementcounter", 0x0FF}, // SP 0x1402AE370 MP 0x140374FE0 - {"getcountertotal", 0x100}, // SP 0x1402AE3C0 MP 0x140375100 - {"_func_101", 0x101}, // SP 0x1402A1AE0 MP 0x000000000 - {"_func_102", 0x102}, // SP 0x14028E970 MP 0x000000000 - {"_func_103", 0x103}, // SP 0x14028ED80 MP 0x000000000 - {"_func_104", 0x104}, // SP 0x1405D92F0 MP 0x14042C2C0 - {"_func_105", 0x105}, // SP 0x1405D92F0 MP 0x14042C2D0 - {"_func_106", 0x106}, // SP 0x14028D7F0 MP 0x000000000 - {"createthreatbiasgroup", 0x107}, // SP 0x1402D79E0 MP 0x1400774E0 - {"threatbiasgroupexists", 0x108}, // SP 0x1402D7A10 MP 0x140077510 - {"getthreatbias", 0x109}, // SP 0x1402D7A50 MP 0x140077550 - {"setthreatbias", 0x10A}, // SP 0x1402D7AB0 MP 0x1400775B0 - {"setthreatbiasagainstall", 0x10B}, // SP 0x1402D7B30 MP 0x140077630 - {"setignoremegroup", 0x10C}, // SP 0x1402D7B80 MP 0x140077680 - {"isenemyteam", 0x10D}, // SP 0x1402D7CC0 MP 0x140077820 - {"_func_10E", 0x10E}, // SP 0x1402B7530 MP 0x000000000 - {"_func_10F", 0x10F}, // SP 0x1402B77F0 MP 0x000000000 - {"_func_110", 0x110}, // SP 0x1402B7800 MP 0x000000000 - {"_func_111", 0x111}, // SP 0x1402B7810 MP 0x000000000 - {"_func_112", 0x112}, // SP 0x1402B79C0 MP 0x000000000 - {"_func_113", 0x113}, // SP 0x1402B7A20 MP 0x000000000 - {"vectornormalize", 0x114}, // SP 0x140292150 MP 0x1403587A0 - {"vectortoangles", 0x115}, // SP 0x140292290 MP 0x140358A90 - {"vectortoyaw", 0x116}, // SP 0x1402924D0 MP 0x140358B10 - {"vectorlerp", 0x117}, // SP 0x140292510 MP 0x140358E60 - {"anglestoup", 0x118}, // SP 0x140292C80 MP 0x1403596E0 - {"_func_119", 0x119}, // SP 0x140292D50 MP 0x140359890 - {"_func_11A", 0x11A}, // SP 0x140292F80 MP 0x140359930 - {"anglesdelta", 0x11B}, // SP 0x1402930E0 MP 0x140359BC0 - {"_func_11C", 0x11C}, // SP 0x1402934C0 MP 0x14035A0F0 - {"_func_11D", 0x11D}, // SP 0x140293670 MP 0x14035A280 - {"_func_11E", 0x11E}, // SP 0x1402956B0 MP 0x14035B550 - {"_func_11F", 0x11F}, // SP 0x140295850 MP 0x14035B7F0 - {"issubstr", 0x120}, // SP 0x140296960 MP 0x14035CB70 - {"isendstr", 0x121}, // SP 0x1402969A0 MP 0x14035CD40 - {"getsubstr", 0x122}, // SP 0x140296BB0 MP 0x14035CF80 - {"tolower", 0x123}, // SP 0x140296DC0 MP 0x14035D360 - {"_func_124", 0x124}, // SP 0x140297230 MP 0x14035DA90 - {"_func_125", 0x125}, // SP 0x140297970 MP 0x14035E690 - {"_func_126", 0x126}, // SP 0x14029FA50 MP 0x1403679A0 - {"getuavstrengthmax", 0x127}, // SP 0x000000000 MP 0x14037B790 - {"getuavstrengthlevelshowenemyfastsweep", 0x128}, // SP 0x000000000 MP 0x14037B7A0 - {"isdedicatedserver", 0x129}, // SP 0x000000000 MP 0x14037B7B0 - {"worldentnumber", 0x12A}, // SP 0x000000000 MP 0x14037B7C0 - {"blockteamradar", 0x12B}, // SP 0x000000000 MP 0x14037B7D0 - {"unblockteamradar", 0x12C}, // SP 0x000000000 MP 0x14037B830 - {"isteamradarblocked", 0x12D}, // SP 0x000000000 MP 0x14037B8B0 - {"_func_12E", 0x12E}, // SP 0x000000000 MP 0x140378110 - {"_func_12F", 0x12F}, // SP 0x000000000 MP 0x14037A7B0 - {"_func_130", 0x130}, // SP 0x000000000 MP 0x140378420 - {"sendmatchdata", 0x131}, // SP 0x000000000 MP 0x140378490 - {"_func_132", 0x132}, // SP 0x000000000 MP 0x140378F40 - {"_func_133", 0x133}, // SP 0x000000000 MP 0x14037A820 - {"_func_134", 0x134}, // SP 0x000000000 MP 0x140378FE0 - {"setmatchdataid", 0x135}, // SP 0x000000000 MP 0x140378DD0 - {"_func_136", 0x136}, // SP 0x000000000 MP 0x140378F70 - {"getmatchdata", 0x137}, // SP 0x000000000 MP 0x140378290 - {"_func_138", 0x138}, // SP 0x000000000 MP 0x14037A8D0 - {"sendclientmatchdata", 0x139}, // SP 0x000000000 MP 0x14037ADE0 - {"getbuildversion", 0x13A}, // SP 0x000000000 MP 0x14037AEB0 - {"getsquadassaultelo", 0x13B}, // SP 0x000000000 MP 0x14037B0E0 - {"getsystemtime", 0x13C}, // SP 0x000000000 MP 0x14037B100 - {"getmatchrulesdata", 0x13D}, // SP 0x000000000 MP 0x14037AA30 - {"isusingmatchrulesdata", 0x13E}, // SP 0x000000000 MP 0x14037AB20 - {"_func_13F", 0x13F}, // SP 0x000000000 MP 0x1403769E0 - {"ishairrunning", 0x140}, // SP 0x1402ACD00 MP 0x140378030 - {"setmapcenter", 0x141}, // SP 0x000000000 MP 0x14037B550 - {"setgameendtime", 0x142}, // SP 0x000000000 MP 0x14037B5A0 - {"visionsetthermal", 0x143}, // SP 0x1402ABA00 MP 0x140376D40 - {"visionsetpain", 0x144}, // SP 0x1402ABA10 MP 0x1403770E0 - {"visionsetpostapply", 0x145}, // SP 0x1402ABA20 MP 0x140377160 - {"_func_146", 0x146}, // SP 0x1402A12A0 MP 0x1403699C0 - {"_func_147", 0x147}, // SP 0x140298040 MP 0x14035F250 - {"_func_148", 0x148}, // SP 0x140298370 MP 0x14035F7A0 - {"_func_149", 0x149}, // SP 0x14029E7B0 MP 0x140366DA0 - {"_func_14A", 0x14A}, // SP 0x14029ECC0 MP 0x140366E30 - {"_func_14B", 0x14B}, // SP 0x14029F2B0 MP 0x1403673D0 - {"_func_14C", 0x14C}, // SP 0x14029F3E0 MP 0x140367540 - {"_func_14D", 0x14D}, // SP 0x14029F5B0 MP 0x1403675F0 - {"_func_14E", 0x14E}, // SP 0x1402982C0 MP 0x14035F470 - {"_func_14F", 0x14F}, // SP 0x14029EDB0 MP 0x1403670E0 - {"loadfx", 0x150}, // SP 0x140290A80 MP 0x1403583B0 - {"_func_151", 0x151}, // SP 0x140291730 MP 0x140359620 - {"playfxontag", 0x152}, // SP 0x140292A40 MP 0x14035AF90 - {"stopfxontag", 0x153}, // SP 0x140294440 MP 0x14035C4B0 - {"_func_154", 0x154}, // SP 0x140294DD0 MP 0x14035D560 - {"playloopedfx", 0x155}, // SP 0x140474350 MP 0x14037DA70 - {"spawnfx", 0x156}, // SP 0x1404746B0 MP 0x14037E2D0 - {"triggerfx", 0x157}, // SP 0x140474940 MP 0x14037E8B0 - {"_func_158", 0x158}, // SP 0x140292ED0 MP 0x14035B2B0 - {"_func_159", 0x159}, // SP 0x140474640 MP 0x14037E1D0 - {"_func_15A", 0x15A}, // SP 0x140293D50 MP 0x14035BFE0 - {"_func_15B", 0x15B}, // SP 0x000000000 MP 0x1403778C0 - {"_func_15C", 0x15C}, // SP 0x000000000 MP 0x140377920 - {"clientannouncement", 0x15D}, // SP 0x000000000 MP 0x1403779A0 - {"setteammode", 0x15E}, // SP 0x000000000 MP 0x140377A40 - {"getteamscore", 0x15F}, // SP 0x000000000 MP 0x140377BE0 - {"setteamscore", 0x160}, // SP 0x000000000 MP 0x140377C50 - {"setclientnamemode", 0x161}, // SP 0x000000000 MP 0x140377D70 - {"updateclientnames", 0x162}, // SP 0x000000000 MP 0x140377DC0 - {"getteamplayersalive", 0x163}, // SP 0x000000000 MP 0x140377EB0 - {"_func_164", 0x164}, // SP 0x000000000 MP 0x140375460 - {"_func_165", 0x165}, // SP 0x000000000 MP 0x140375480 - {"_func_166", 0x166}, // SP 0x000000000 MP 0x1403754A0 - {"_func_167", 0x167}, // SP 0x000000000 MP 0x1403756D0 - {"_func_168", 0x168}, // SP 0x000000000 MP 0x1403759C0 - {"_func_169", 0x169}, // SP 0x000000000 MP 0x1403760D0 - {"_func_16A", 0x16A}, // SP 0x14029F100 MP 0x1403673A0 - {"_func_16B", 0x16B}, // SP 0x000000000 MP 0x140376BE0 - {"_func_16C", 0x16C}, // SP 0x000000000 MP 0x140376C60 - {"map_restart", 0x16D}, // SP 0x000000000 MP 0x140376550 - {"exitlevel", 0x16E}, // SP 0x000000000 MP 0x140376630 - {"_func_16F", 0x16F}, // SP 0x000000000 MP 0x140376680 - {"addagent", 0x170}, // SP 0x000000000 MP 0x140376860 - {"_func_171", 0x171}, // SP 0x000000000 MP 0x140378020 - {"_func_172", 0x172}, // SP 0x000000000 MP 0x140376880 - {"_func_173", 0x173}, // SP 0x000000000 MP 0x140376B60 - {"mapexists", 0x174}, // SP 0x000000000 MP 0x140376910 - {"isvalidgametype", 0x175}, // SP 0x000000000 MP 0x140376950 - {"_func_176", 0x176}, // SP 0x000000000 MP 0x140378040 - {"setplayerteamrank", 0x177}, // SP 0x000000000 MP 0x140378050 - {"_func_178", 0x178}, // SP 0x000000000 MP 0x140378100 - {"setteamradar", 0x179}, // SP 0x000000000 MP 0x14037B5D0 - {"getteamradar", 0x17A}, // SP 0x000000000 MP 0x14037B640 - {"setteamradarstrength", 0x17B}, // SP 0x000000000 MP 0x14037B6A0 - {"getteamradarstrength", 0x17C}, // SP 0x000000000 MP 0x14037B720 - {"getuavstrengthmin", 0x17D}, // SP 0x000000000 MP 0x14037B780 - {"_func_17E", 0x17E}, // SP 0x140295500 MP 0x14035E730 - {"physicsexplosionsphere", 0x17F}, // SP 0x140296890 MP 0x14035FE90 - {"physicsradiusjolt", 0x180}, // SP 0x140295F60 MP 0x14035F2D0 - {"physicsradiusjitter", 0x181}, // SP 0x1402963A0 MP 0x14035F900 - {"_func_182", 0x182}, // SP 0x140299880 MP 0x140362E20 - {"_func_183", 0x183}, // SP 0x140299900 MP 0x140363010 - {"_func_184", 0x184}, // SP 0x140299F70 MP 0x140363800 - {"_func_185", 0x185}, // SP 0x14029A180 MP 0x140363920 - {"_func_186", 0x186}, // SP 0x14029A220 MP 0x140363B00 - {"_func_187", 0x187}, // SP 0x14029A4B0 MP 0x140363E60 - {"isexplosivedamagemod", 0x188}, // SP 0x1402A2800 MP 0x14036ADB0 - {"radiusdamage", 0x189}, // SP 0x1402A3690 MP 0x14036C110 - {"setplayerignoreradiusdamage", 0x18A}, // SP 0x14028DFA0 MP 0x14036CF90 - {"_func_18B", 0x18B}, // SP 0x1402A3950 MP 0x14036C1E0 - {"_func_18C", 0x18C}, // SP 0x14029B460 MP 0x140366A00 - {"getnumparts", 0x18D}, // SP 0x14029A830 MP 0x140363F40 - {"_func_18E", 0x18E}, // SP 0x1402B76D0 MP 0x140383170 - {"_func_18F", 0x18F}, // SP 0x000000000 MP 0x1403831D0 - {"objective_team", 0x190}, // SP 0x000000000 MP 0x140383310 - {"objective_player", 0x191}, // SP 0x000000000 MP 0x1403833B0 - {"_func_192", 0x192}, // SP 0x000000000 MP 0x140383410 - {"_func_193", 0x193}, // SP 0x000000000 MP 0x1403834B0 - {"_func_194", 0x194}, // SP 0x000000000 MP 0x1403835B0 - {"_func_195", 0x195}, // SP 0x000000000 MP 0x1403835F0 - {"objective_playermask_showtoall", 0x196}, // SP 0x000000000 MP 0x140382DA0 - {"_func_197", 0x197}, // SP 0x000000000 MP 0x140382DE0 - {"_func_198", 0x198}, // SP 0x1402AD860 MP 0x140377360 - {"_func_199", 0x199}, // SP 0x1402AD8C0 MP 0x1403773E0 - {"_func_19A", 0x19A}, // SP 0x1405D92F0 MP 0x140377C30 - {"getent", 0x19B}, // SP 0x1402B9570 MP 0x1403845D0 - {"getentarray", 0x19C}, // SP 0x1402B95E0 MP 0x1403846A0 - {"_func_19D", 0x19D}, // SP 0x000000000 MP 0x140384C00 - {"spawnplane", 0x19E}, // SP 0x000000000 MP 0x140377670 - {"spawnstruct", 0x19F}, // SP 0x140374110 MP 0x140442170 - {"_func_1A0", 0x1A0}, // SP 0x000000000 MP 0x140377A90 - {"isalive", 0x1A1}, // SP 0x1402AD940 MP 0x140377410 - {"isspawner", 0x1A2}, // SP 0x1402ADB20 MP 0x1403774F0 - {"_func_1A3", 0x1A3}, // SP 0x140282D00 MP 0x14034F8E0 - {"missile_createattractorent", 0x1A4}, // SP 0x140282D10 MP 0x14034F8F0 - {"missile_createattractororigin", 0x1A5}, // SP 0x140282FD0 MP 0x14034FBA0 - {"_func_1A6", 0x1A6}, // SP 0x140282FE0 MP 0x14034FBB0 - {"_func_1A7", 0x1A7}, // SP 0x140282FF0 MP 0x14034FBC0 - {"playsoundatpos", 0x1A8}, // SP 0x000000000 MP 0x140378150 - {"newhudelem", 0x1A9}, // SP 0x14026F000 MP 0x14033CF50 - {"newclienthudelem", 0x1AA}, // SP 0x14026EFB0 MP 0x14033CEF0 - {"newteamhudelem", 0x1AB}, // SP 0x000000000 MP 0x14033CF80 - {"resettimeout", 0x1AC}, // SP 0x140375910 MP 0x1404438F0 - {"isplayer", 0x1AD}, // SP 0x1402ADB90 MP 0x140377390 - {"isplayernumber", 0x1AE}, // SP 0x000000000 MP 0x1403774C0 - {"getpartname", 0x1AF}, // SP 0x14029A9A0 MP 0x140364120 - {"_func_1B0", 0x1B0}, // SP 0x14029CDC0 MP 0x140363D50 - {"_func_1B1", 0x1B1}, // SP 0x1402999A0 MP 0x140360B10 - {"_func_1B2", 0x1B2}, // SP 0x14029AA30 MP 0x140361AC0 - {"_func_1B3", 0x1B3}, // SP 0x14029ADB0 MP 0x140361CE0 - {"_func_1B4", 0x1B4}, // SP 0x14029B360 MP 0x1403622D0 - {"_func_1B5", 0x1B5}, // SP 0x14029B580 MP 0x140362520 - {"_func_1B6", 0x1B6}, // SP 0x14029B020 MP 0x140361EC0 - {"_func_1B7", 0x1B7}, // SP 0x14029B7A0 MP 0x140362920 - {"weaponclass", 0x1B8}, // SP 0x14029B8E0 MP 0x140362A60 - {"getnextarraykey", 0x1B9}, // SP 0x1402A35D0 MP 0x14036D000 - {"_func_1BA", 0x1BA}, // SP 0x14028D850 MP 0x14036D690 - {"_func_1BB", 0x1BB}, // SP 0x14029CCC0 MP 0x1403664F0 - {"tablelookupistringbyrow", 0x1BC}, // SP 0x14029D970 MP 0x1403671B0 - {"_func_1BD", 0x1BD}, // SP 0x14029CF50 MP 0x1403667F0 - {"tablelookuprownum", 0x1BE}, // SP 0x14029DC10 MP 0x140367320 - {"_func_1BF", 0x1BF}, // SP 0x14029D280 MP 0x140366C90 - {"tableexists", 0x1C0}, // SP 0x14029D820 MP 0x140366DE0 - {"getmissileowner", 0x1C1}, // SP 0x14029AD10 MP 0x140366490 - {"_func_1C2", 0x1C2}, // SP 0x140294EF0 MP 0x14035E270 - {"getweaponflashtagname", 0x1C3}, // SP 0x140295DC0 MP 0x14035F290 - {"averagepoint", 0x1C4}, // SP 0x14029A870 MP 0x140363F90 - {"_func_1C5", 0x1C5}, // SP 0x14029AB60 MP 0x140364300 - {"getspawnerarray", 0x1C6}, // SP 0x140466C40 MP 0x140564030 - {"playrumbleonposition", 0x1C7}, // SP 0x140299410 MP 0x140360540 - {"playrumblelooponposition", 0x1C8}, // SP 0x140299470 MP 0x1403605E0 - {"_func_1C9", 0x1C9}, // SP 0x1402996F0 MP 0x140360670 - {"soundexists", 0x1CA}, // SP 0x140290B30 MP 0x14035C2D0 - {"_func_1CB", 0x1CB}, // SP 0x1405D92F0 MP 0x14036B580 - {"_func_1CC", 0x1CC}, // SP 0x1405D92F0 MP 0x14036B590 - {"_func_1CD", 0x1CD}, // SP 0x1405D92F0 MP 0x14036B710 - {"_func_1CE", 0x1CE}, // SP 0x1405D92F0 MP 0x14036B770 - {"_func_1CF", 0x1CF}, // SP 0x1405D92F0 MP 0x14036B780 - {"_func_1D0", 0x1D0}, // SP 0x1405D92F0 MP 0x14036B790 - {"setminimap", 0x1D1}, // SP 0x1402A2200 MP 0x14036C3C0 - {"_func_1D2", 0x1D2}, // SP 0x1402A28F0 MP 0x14036CA90 - {"_func_1D3", 0x1D3}, // SP 0x1402A3410 MP 0x14036CDA0 - {"getfirstarraykey", 0x1D4}, // SP 0x1402A3470 MP 0x14036CF00 - {"getglass", 0x1D5}, // SP 0x14029AD60 MP 0x1403644F0 - {"getglassarray", 0x1D6}, // SP 0x14029B110 MP 0x1403647D0 - {"getglassorigin", 0x1D7}, // SP 0x14029B410 MP 0x1403649E0 - {"isglassdestroyed", 0x1D8}, // SP 0x14029B630 MP 0x140364CF0 - {"destroyglass", 0x1D9}, // SP 0x14029B850 MP 0x140365010 - {"_func_1DA", 0x1DA}, // SP 0x14029B9F0 MP 0x1403651E0 - {"_func_1DB", 0x1DB}, // SP 0x14029C0E0 MP 0x140365F50 - {"_func_1DC", 0x1DC}, // SP 0x14029C160 MP 0x140366130 - {"objective_add", 0x1DD}, // SP 0x1402B7080 MP 0x140382E50 - {"_func_1DE", 0x1DE}, // SP 0x1402B74F0 MP 0x140382F80 - {"objective_state", 0x1DF}, // SP 0x1402B77E0 MP 0x140382FF0 - {"objective_icon", 0x1E0}, // SP 0x1402B7820 MP 0x140383090 - {"_func_1E1", 0x1E1}, // SP 0x1402B7900 MP 0x000000000 - {"objective_position", 0x1E2}, // SP 0x1402B7980 MP 0x1403830D0 - {"objective_current", 0x1E3}, // SP 0x1402B7A10 MP 0x140383230 - {"_func_1E4", 0x1E4}, // SP 0x14029BA70 MP 0x140362C20 - {"_func_1E5", 0x1E5}, // SP 0x14029BE70 MP 0x140362F00 - {"_func_1E6", 0x1E6}, // SP 0x14029BF80 MP 0x140363300 - {"_func_1E7", 0x1E7}, // SP 0x14029C9D0 MP 0x140363950 - {"isweaponcliponly", 0x1E8}, // SP 0x14029D050 MP 0x140364220 - {"_func_1E9", 0x1E9}, // SP 0x14029D330 MP 0x140364590 - {"_func_1EA", 0x1EA}, // SP 0x14029D720 MP 0x140364870 - {"_func_1EB", 0x1EB}, // SP 0x14029D9F0 MP 0x140364E70 - {"_func_1EC", 0x1EC}, // SP 0x14045D5C0 MP 0x14055A900 - {"getvehiclenodearray", 0x1ED}, // SP 0x14045D6B0 MP 0x14055A9F0 - {"_func_1EE", 0x1EE}, // SP 0x14045D550 MP 0x14055A890 - {"_func_1EF", 0x1EF}, // SP 0x1404669B0 MP 0x140563DA0 - {"_func_1F0", 0x1F0}, // SP 0x140466CC0 MP 0x140564110 - {"spawnvehicle", 0x1F1}, // SP 0x140466D20 MP 0x140564170 - {"vehicle_getarray", 0x1F2}, // SP 0x1404669F0 MP 0x140563DE0 - {"pow", 0x1F3}, // SP 0x14028E710 MP 0x14036CBC0 - {"_func_1F4", 0x1F4}, // SP 0x14028D7B0 MP 0x14036BB10 - {"botgetmemoryevents", 0x1F5}, // SP 0x000000000 MP 0x14047A600 - {"botautoconnectenabled", 0x1F6}, // SP 0x000000000 MP 0x14047ABF0 - {"botzonegetcount", 0x1F7}, // SP 0x000000000 MP 0x14047AC20 - {"botzonesetteam", 0x1F8}, // SP 0x000000000 MP 0x14047AF10 - {"_func_1F9", 0x1F9}, // SP 0x000000000 MP 0x14047AD50 - {"botmemoryflags", 0x1FA}, // SP 0x000000000 MP 0x14047A940 - {"botflagmemoryevents", 0x1FB}, // SP 0x000000000 MP 0x14047A320 - {"botzonegetindoorpercent", 0x1FC}, // SP 0x000000000 MP 0x14047ACF0 - {"botsentientswap", 0x1FD}, // SP 0x000000000 MP 0x14047A990 - {"isbot", 0x1FE}, // SP 0x000000000 MP 0x14047AF70 - {"isagent", 0x1FF}, // SP 0x000000000 MP 0x14037B2B0 - {"getmaxagents", 0x200}, // SP 0x000000000 MP 0x140450E50 - {"_func_201", 0x201}, // SP 0x000000000 MP 0x14047A310 - {"botgetclosestnavigablepoint", 0x202}, // SP 0x000000000 MP 0x14047A550 - {"getnodesintrigger", 0x203}, // SP 0x000000000 MP 0x14031FCE0 - {"nodesvisible", 0x204}, // SP 0x1402CC4A0 MP 0x140320EA0 - {"_func_205", 0x205}, // SP 0x1402CC110 MP 0x14031FDD0 - {"_func_206", 0x206}, // SP 0x000000000 MP 0x1403201B0 - {"getzonenearest", 0x207}, // SP 0x000000000 MP 0x1403201C0 - {"_func_208", 0x208}, // SP 0x000000000 MP 0x140320320 - {"_func_209", 0x209}, // SP 0x000000000 MP 0x140320A10 - {"_func_20A", 0x20A}, // SP 0x000000000 MP 0x140320960 - {"getnodezone", 0x20B}, // SP 0x000000000 MP 0x14031FC20 - {"_func_20C", 0x20C}, // SP 0x000000000 MP 0x140320600 - {"getzonenodeforindex", 0x20D}, // SP 0x000000000 MP 0x1403202E0 - {"_func_20E", 0x20E}, // SP 0x1402AFFC0 MP 0x14037AE40 - {"_func_211", 0x211}, // SP 0x000000000 MP 0x140320C70 - {"findentrances", 0x212}, // SP 0x000000000 MP 0x14031F6F0 - {"badplace_global", 0x213}, // SP 0x000000000 MP 0x14035A190 - {"_func_214", 0x214}, // SP 0x000000000 MP 0x140375150 - {"_func_215", 0x215}, // SP 0x1402CBE10 MP 0x14031F940 - {"disconnectnodepair", 0x216}, // SP 0x14028E840 MP 0x14036F800 - {"connectnodepair", 0x217}, // SP 0x14028EAC0 MP 0x140357F30 - {"_func_218", 0x218}, // SP 0x1402AE000 MP 0x000000000 - {"_func_21B", 0x21B}, // SP 0x1405D92F0 MP 0x1403780E0 - {"_func_21C", 0x21C}, // SP 0x000000000 MP 0x140374FD0 - {"_func_21D", 0x21D}, // SP 0x14037AA30 MP 0x000000000 - {"_func_21E", 0x21E}, // SP 0x14037AC70 MP 0x000000000 - {"_func_21F", 0x21F}, // SP 0x14037ABB0 MP 0x000000000 - {"_func_220", 0x220}, // SP 0x14037AB50 MP 0x000000000 - {"_func_221", 0x221}, // SP 0x14037A730 MP 0x000000000 - {"_func_222", 0x222}, // SP 0x14037A7B0 MP 0x000000000 - {"_func_223", 0x223}, // SP 0x14037A760 MP 0x000000000 - {"_func_224", 0x224}, // SP 0x14037A7F0 MP 0x000000000 - {"distance2dsquared", 0x225}, // SP 0x1402914F0 MP 0x140357BF0 - {"getangledelta3d", 0x226}, // SP 0x14028FE10 MP 0x14036F1C0 - {"activateclientexploder", 0x227}, // SP 0x140290710 MP 0x14035B7B0 - {"_func_228", 0x228}, // SP 0x1402909E0 MP 0x14035CED0 - {"_func_229", 0x229}, // SP 0x140290DF0 MP 0x14035D200 - {"trajectorycalculateexitangle", 0x22A}, // SP 0x140290FA0 MP 0x14035D4C0 - {"_func_22B", 0x22B}, // SP 0x1402911D0 MP 0x14035D830 - {"trajectorycomputedeltaheightattime", 0x22C}, // SP 0x140291530 MP 0x14035DFB0 - {"trajectoryestimatedesiredinairtime", 0x22D}, // SP 0x140291910 MP 0x14035E0B0 - {"_func_22E", 0x22E}, // SP 0x1405D92F0 MP 0x140367D60 - {"ispointinvolume", 0x22F}, // SP 0x140291190 MP 0x14036F5A0 - {"_func_230", 0x230}, // SP 0x1402AB600 MP 0x000000000 - {"_func_231", 0x231}, // SP 0x1402AB4F0 MP 0x000000000 - {"_func_232", 0x232}, // SP 0x1402AB4D0 MP 0x000000000 - {"_func_234", 0x234}, // SP 0x1405D92F0 MP 0x1403605D0 - {"getscriptablearray", 0x236}, // SP 0x140294380 MP 0x140360720 - {"_func_237", 0x237}, // SP 0x140297840 MP 0x140360C40 - {"_func_238", 0x238}, // SP 0x1402A87C0 MP 0x14037B1D0 - {"_func_239", 0x239}, // SP 0x1402AA280 MP 0x000000000 - {"_func_23A", 0x23A}, // SP 0x140292220 MP 0x14035E710 - {"_func_23B", 0x23B}, // SP 0x140292220 MP 0x14035E860 - {"_func_23D", 0x23D}, // SP 0x1402A06D0 MP 0x1403686B0 - {"_func_23E", 0x23E}, // SP 0x1402A0900 MP 0x140368C00 - {"_func_23F", 0x23F}, // SP 0x14029DDC0 MP 0x140365220 - {"_func_240", 0x240}, // SP 0x14029DDC0 MP 0x140365440 - {"_func_241", 0x241}, // SP 0x1402ACD00 MP 0x140365460 - {"_func_242", 0x242}, // SP 0x1402ACD00 MP 0x140365470 - {"_func_243", 0x243}, // SP 0x1402ACD00 MP 0x140365630 - {"_func_244", 0x244}, // SP 0x000000000 MP 0x1403784C0 - {"_func_245", 0x245}, // SP 0x140292D40 MP 0x14035FAF0 - {"_func_246", 0x246}, // SP 0x000000000 MP 0x1403784E0 - {"_func_247", 0x247}, // SP 0x000000000 MP 0x140378DA0 - {"_func_248", 0x248}, // SP 0x000000000 MP 0x140378DB0 - {"_func_249", 0x249}, // SP 0x000000000 MP 0x140378DC0 - {"_func_24A", 0x24A}, // SP 0x1402A8F70 MP 0x000000000 - {"_func_24B", 0x24B}, // SP 0x1402A8FF0 MP 0x000000000 - {"_func_24C", 0x24C}, // SP 0x1402946A0 MP 0x14035ABF0 - {"_func_24D", 0x24D}, // SP 0x140290110 MP 0x14036DF90 - {"_func_24E", 0x24E}, // SP 0x140292B00 MP 0x140359490 - {"_func_24F", 0x24F}, // SP 0x1402ABB80 MP 0x000000000 - {"_func_250", 0x250}, // SP 0x1405D92F0 MP 0x140360370 - {"_func_251", 0x251}, // SP 0x1405D92F0 MP 0x1403604B0 - {"_func_252", 0x252}, // SP 0x1405D92F0 MP 0x140360530 - {"_func_253", 0x253}, // SP 0x140293F90 MP 0x14035A6C0 - {"_func_254", 0x254}, // SP 0x140293FF0 MP 0x14035A7C0 - {"_func_255", 0x255}, // SP 0x140294500 MP 0x14035A9F0 - {"_func_256", 0x256}, // SP 0x000000000 MP 0x1403844C0 - {"_func_257", 0x257}, // SP 0x1402ADE20 MP 0x000000000 - {"_func_258", 0x258}, // SP 0x14029F640 MP 0x1403677A0 - {"_func_259", 0x259}, // SP 0x14029F710 MP 0x1403678C0 - {"getcsplinecount", 0x25A}, // SP 0x1402954E0 MP 0x1403611E0 - {"getcsplinepointcount", 0x25B}, // SP 0x1402955F0 MP 0x140361200 - {"getcsplinelength", 0x25C}, // SP 0x140295790 MP 0x1403613C0 - {"getcsplinepointid", 0x25D}, // SP 0x140295AD0 MP 0x1403615F0 - {"getcsplinepointlabel", 0x25E}, // SP 0x140295E00 MP 0x140361A30 - {"getcsplinepointtension", 0x25F}, // SP 0x140296150 MP 0x140361DD0 - {"_func_260", 0x260}, // SP 0x1402965B0 MP 0x140362020 - {"_func_261", 0x261}, // SP 0x140296740 MP 0x140362470 - {"_func_262", 0x262}, // SP 0x140296B10 MP 0x140362680 - {"getcsplinepointdisttonextpoint", 0x263}, // SP 0x140296CE0 MP 0x140362AE0 - {"_func_264", 0x264}, // SP 0x140296EE0 MP 0x140362D50 - {"_func_265", 0x265}, // SP 0x1402970D0 MP 0x140363430 - {"_func_266", 0x266}, // SP 0x140297580 MP 0x1403636C0 - {"setnojipscore", 0x267}, // SP 0x140297820 MP 0x140363AB0 - {"setnojiptime", 0x268}, // SP 0x140297820 MP 0x140363C90 - {"getpredictedentityposition", 0x269}, // SP 0x000000000 MP 0x14037AEC0 - {"_func_26A", 0x26A}, // SP 0x1405D92F0 MP 0x140363F80 - {"_func_26B", 0x26B}, // SP 0x1405D92F0 MP 0x140364110 - {"_func_26C", 0x26C}, // SP 0x1405D92F0 MP 0x1403642F0 - {"_func_26D", 0x26D}, // SP 0x1405D92F0 MP 0x1403644E0 - {"_func_26E", 0x26E}, // SP 0x1405D92F0 MP 0x140364540 - {"_func_26F", 0x26F}, // SP 0x1405D92F0 MP 0x140364700 - {"queuedialog", 0x270}, // SP 0x000000000 MP 0x140378930 - {"_func_271", 0x271}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_272", 0x272}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_273", 0x273}, // SP 0x1405D92F0 MP 0x140364710 - {"_func_274", 0x274}, // SP 0x1405D92F0 MP 0x140364860 - {"_func_275", 0x275}, // SP 0x1405D92F0 MP 0x140364970 - {"_func_276", 0x276}, // SP 0x1405D92F0 MP 0x1403649D0 - {"triggerportableradarping", 0x277}, // SP 0x000000000 MP 0x14037B980 - {"botgetteamlimit", 0x279}, // SP 0x000000000 MP 0x14047A900 - {"spawnfxforclient", 0x27A}, // SP 0x000000000 MP 0x14037E430 - {"botgetteamdifficulty", 0x27B}, // SP 0x000000000 MP 0x14047A8C0 - {"_func_27C", 0x27C}, // SP 0x1405D92F0 MP 0x1403675D0 - {"_func_27D", 0x27D}, // SP 0x14029CAC0 MP 0x14033CF40 - {"_func_27E", 0x27E}, // SP 0x1405D92F0 MP 0x140363CE0 - {"_func_27F", 0x27F}, // SP 0x1405D92F0 MP 0x140363E50 - {"_func_280", 0x280}, // SP 0x1405D92F0 MP 0x140360610 - {"_func_281", 0x281}, // SP 0x14029DC90 MP 0x140369F80 - {"getstarttime", 0x282}, // SP 0x000000000 MP 0x14037BBD0 - {"getbuildnumber", 0x283}, // SP 0x000000000 MP 0x14037BBE0 - {"_func_284", 0x284}, // SP 0x000000000 MP 0x14037BC00 - {"_func_285", 0x285}, // SP 0x000000000 MP 0x1403748B0 - {"_func_286", 0x286}, // SP 0x000000000 MP 0x140374B00 - {"_func_287", 0x287}, // SP 0x1405D92F0 MP 0x140360660 - {"_func_288", 0x288}, // SP 0x000000000 MP 0x1403772E0 - {"_func_289", 0x289}, // SP 0x000000000 MP 0x140376690 - {"_func_28A", 0x28A}, // SP 0x1402ACD00 MP 0x140365450 - {"_func_28B", 0x28B}, // SP 0x140295B60 MP 0x14035BD90 - {"_func_28C", 0x28C}, // SP 0x140296230 MP 0x14035C6E0 - {"_func_28D", 0x28D}, // SP 0x000000000 MP 0x1400777C0 - {"_func_28E", 0x28E}, // SP 0x000000000 MP 0x1403767D0 - {"_func_28F", 0x28F}, // SP 0x000000000 MP 0x140320120 - {"_func_290", 0x290}, // SP 0x000000000 MP 0x1403775D0 - {"_func_291", 0x291}, // SP 0x14029E770 MP 0x140368040 - {"_func_292", 0x292}, // SP 0x14029E7F0 MP 0x140368150 - {"_func_293", 0x293}, // SP 0x1402ADDE0 MP 0x000000000 - {"_func_294", 0x294}, // SP 0x1402988E0 MP 0x140365640 - {"_func_295", 0x295}, // SP 0x14029C2F0 MP 0x140368F40 - {"_func_296", 0x296}, // SP 0x14029B680 MP 0x140364D50 - {"_func_297", 0x297}, // SP 0x14029BD80 MP 0x140365540 - {"_func_298", 0x298}, // SP 0x14029C1B0 MP 0x140366230 - {"_func_299", 0x299}, // SP 0x1402ABA30 MP 0x000000000 - {"_func_29A", 0x29A}, // SP 0x1405D92F0 MP 0x14035B9A0 - {"_func_29B", 0x29B}, // SP 0x140291040 MP 0x14036F330 - {"_func_29C", 0x29C}, // SP 0x14029D240 MP 0x140368760 - {"_func_29D", 0x29D}, // SP 0x14029DE30 MP 0x1403674E0 - {"_func_29E", 0x29E}, // SP 0x14029DEC0 MP 0x140367620 - {"_func_29F", 0x29F}, // SP 0x000000000 MP 0x140375690 - {"_func_2A0", 0x2A0}, // SP 0x000000000 MP 0x1403756A0 - {"_func_2A1", 0x2A1}, // SP 0x14029D890 MP 0x140364AB0 - {"_func_2A2", 0x2A2}, // SP 0x1402ABC20 MP 0x000000000 - {"_func_2A3", 0x2A3}, // SP 0x1402A2F20 MP 0x14036F010 - {"_func_2A4", 0x2A4}, // SP 0x140290710 MP 0x14035B890 - {"_func_2A5", 0x2A5}, // SP 0x14029DF00 MP 0x14036D0F0 - {"_func_2A6", 0x2A6}, // SP 0x1405D92F0 MP 0x14036DAE0 - {"_func_2A7", 0x2A7}, // SP 0x1405D92F0 MP 0x14036DA60 - {"_func_2A8", 0x2A8}, // SP 0x000000000 MP 0x140376390 - {"_func_2A9", 0x2A9}, // SP 0x1402AE820 MP 0x000000000 - {"_func_2AA", 0x2AA}, // SP 0x14029AE80 MP 0x140364550 - {"_func_2AB", 0x2AB}, // SP 0x1405D92F0 MP 0x14036E590 - {"_func_2AC", 0x2AC}, // SP 0x1402ACD00 MP 0x14036E310 - {"_func_2AD", 0x2AD}, // SP 0x1405D92F0 MP 0x14036E3E0 - {"_func_2AE", 0x2AE}, // SP 0x1405D92F0 MP 0x14036E470 - {"_func_2AF", 0x2AF}, // SP 0x1405D92F0 MP 0x14036E730 - {"_func_2B0", 0x2B0}, // SP 0x000000000 MP 0x140375320 - {"_func_2B1", 0x2B1}, // SP 0x000000000 MP 0x1403753F0 - {"_func_2B2", 0x2B2}, // SP 0x000000000 MP 0x140375430 - {"_func_2B3", 0x2B3}, // SP 0x000000000 MP 0x140375A40 - {"_func_2B4", 0x2B4}, // SP 0x1405D92F0 MP 0x14035C9D0 - {"_func_2B5", 0x2B5}, // SP 0x1405D92F0 MP 0x14035D920 - {"_func_2B6", 0x2B6}, // SP 0x140291AD0 MP 0x14035E150 - {"_func_2B7", 0x2B7}, // SP 0x1402A85B0 MP 0x000000000 - {"_func_2B8", 0x2B8}, // SP 0x000000000 MP 0x140378570 - {"_func_2B9", 0x2B9}, // SP 0x000000000 MP 0x1403787D0 - {"_func_2BA", 0x2BA}, // SP 0x000000000 MP 0x140378850 - {"_func_2BB", 0x2BB}, // SP 0x000000000 MP 0x140379930 - {"_func_2BC", 0x2BC}, // SP 0x14028EBB0 MP 0x140359E00 - {"_func_2BD", 0x2BD}, // SP 0x1402A8640 MP 0x000000000 - {"_func_2BE", 0x2BE}, // SP 0x14029B310 MP 0x140366D50 - {"_func_2BF", 0x2BF}, // SP 0x000000000 MP 0x140383570 - {"_func_2C0", 0x2C0}, // SP 0x1405D92F0 MP 0x14036E8A0 - {"_func_2C1", 0x2C1}, // SP 0x1405D92F0 MP 0x14036E900 - {"_func_2C2", 0x2C2}, // SP 0x140291E10 MP 0x14035E670 - {"_func_2C3", 0x2C3}, // SP 0x1402A1A30 MP 0x14036DA40 - {"_func_2C4", 0x2C4}, // SP 0x1402A1A30 MP 0x14036DAC0 - {"_func_2C5", 0x2C5}, // SP 0x1402A8810 MP 0x000000000 - {"_func_2C6", 0x2C6}, // SP 0x000000000 MP 0x140379A80 - {"_func_2C6", 0x2C7}, // SP 0x000000000 MP 0x140320DC0 - {"_func_2C8", 0x2C8}, // SP 0x000000000 MP 0x140320E20 - {"_func_2C9", 0x2C9}, // SP 0x000000000 MP 0x14037E5E0 - {"_func_2CA", 0x2CA}, // SP 0x000000000 MP 0x14037E650 - {"_func_2CB", 0x2CB}, // SP 0x000000000 MP 0x14037BC40 - {"_func_2CC", 0x2CC}, // SP 0x000000000 MP 0x14037BD00 - {"_func_2CD", 0x2CD}, // SP 0x000000000 MP 0x140374820 - {"_func_2CE", 0x2CE}, // SP 0x1402A79A0 MP 0x000000000 - {"_func_2CF", 0x2CF}, // SP 0x000000000 MP 0x14037AB40 - {"_func_2D4", 0x2D4}, // SP 0x1402A7CB0 MP 0x000000000 - {"_func_2D5", 0x2D5}, // SP 0x14029E120 MP 0x14036D640 - {"_func_2D6", 0x2D6}, // SP 0x000000000 MP 0x14037BE30 - {"_func_2D7", 0x2D7}, // SP 0x1405D92F0 MP 0x14036DB50 - {"_func_2D8", 0x2D8}, // SP 0x1402ABB70 MP 0x000000000 - {"_func_2D9", 0x2D9}, // SP 0x000000000 MP 0x140320D50 - {"_func_2DA", 0x2DA}, // SP 0x1405D92F0 MP 0x000000000 - {"_func_2DB", 0x2DB}, // SP 0x000000000 MP 0x14037ABB0 - {"_func_2DC", 0x2DC}, // SP 0x000000000 MP 0x14037E1C0 - {"_func_2DD", 0x2DD}, // SP 0x000000000 MP 0x14037E1B0 - {"_func_2DF", 0x2DF}, // SP 0x140292220 MP 0x14036F7F0 - {"_func_2E0", 0x2E0}, // SP 0x140297C80 MP 0x14035EDE0 - {"_func_2E1", 0x2E1}, // SP 0x000000000 MP 0x1403788D0 - {"_func_2E2", 0x2E2}, // SP 0x1405D92F0 MP 0x14035B3B0 - {"_func_2E3", 0x2E3}, // SP 0x1405D92F0 MP 0x14035D0B0 - {"_func_2E4", 0x2E4}, // SP 0x1405D92F0 MP 0x14035E170 - {"_func_2E5", 0x2E5}, // SP 0x1402A8730 MP 0x000000000 - {"_func_2E6", 0x2E6}, // SP 0x140295A10 MP 0x14035EFF0 - {"_func_2E7", 0x2E7}, // SP 0x140295CF0 MP 0x14035F120 - {"_func_2E8", 0x2E8}, // SP 0x1402AC850 MP 0x000000000 - {"_func_2E9", 0x2E9}, // SP 0x14029E760 MP 0x140366680 - {"_func_2EA", 0x2EA}, // SP 0x000000000 MP 0x140376DC0 - {"_func_2EB", 0x2EB}, // SP 0x000000000 MP 0x140377540 - {"_func_2EC", 0x2EC}, // SP 0x000000000 MP 0x140377880 - {"_func_2ED", 0x2ED}, // SP 0x1402ACD00 MP 0x14036BA50 - {"_func_2EE", 0x2EE}, // SP 0x1402A1E10 MP 0x14036BA60 - {"_func_2EF", 0x2EF}, // SP 0x1402A1FB0 MP 0x14036BA70 - {"_func_2F0", 0x2F0}, // SP 0x1402A21F0 MP 0x14036BB50 - {"_func_2F1", 0x2F1}, // SP 0x1402ACD00 MP 0x14036BC60 - {"_func_2F2", 0x2F2}, // SP 0x1402A1E10 MP 0x14036BC70 - {"_func_2F3", 0x2F3}, // SP 0x1402A1FB0 MP 0x14036BF90 - {"_func_2F4", 0x2F4}, // SP 0x1402A21F0 MP 0x14036C100 - {"_func_2F5", 0x2F5}, // SP 0x1402A1E10 MP 0x14036C120 - {"_func_2F6", 0x2F6}, // SP 0x1402A1FB0 MP 0x14036C170 - {"_func_2F7", 0x2F7}, // SP 0x1402A21F0 MP 0x14036C310 - {"_func_2F8", 0x2F8}, // SP 0x14028D700 MP 0x1403582B0 - {"_func_2F9", 0x2F9}, // SP 0x14029CAC0 MP 0x14036D300 - {"_func_2FA", 0x2FA}, // SP 0x14029CAC0 MP 0x14036DDC0 - {"_func_2FB", 0x2FB}, // SP 0x14029DB60 MP 0x140365110 - {"_func_2FC", 0x2FC}, // SP 0x14029CB20 MP 0x140367DD0 - {"_func_2FD", 0x2FD}, // SP 0x14029CEA0 MP 0x140368000 - {"_func_2FE", 0x2FE}, // SP 0x14029CEE0 MP 0x140368290 - {"_func_2FF", 0x2FF}, // SP 0x000000000 MP 0x140367110 - {"_func_300", 0x300}, // SP 0x000000000 MP 0x140377870 - {"_func_301", 0x301}, // SP 0x1405D92F0 MP 0x140363E90 - }; - - std::unordered_map method_map = - { - {"motionblurhqenable", 0x8000}, // SP 0x14029B0D0 MP 0x140362FD0 - {"_meth_8001", 0x8001}, // SP 0x1402A8AC0 MP 0x000000000 - {"setdamagestage", 0x8002}, // SP 0x000000000 MP 0x14055A000 - {"_meth_8003", 0x8003}, // SP 0x000000000 MP 0x140378300 - {"playsoundtoplayer", 0x8004}, // SP 0x000000000 MP 0x1403784F0 - {"playerhide", 0x8005}, // SP 0x000000000 MP 0x14037AB70 - {"_meth_8006", 0x8006}, // SP 0x000000000 MP 0x14037ABD0 - {"showtoplayer", 0x8007}, // SP 0x000000000 MP 0x14037AC50 - {"_meth_8008", 0x8008}, // SP 0x000000000 MP 0x14037ACB0 - {"_meth_8009", 0x8009}, // SP 0x000000000 MP 0x14037ACC0 - {"enableplayeruse", 0x800A}, // SP 0x000000000 MP 0x140374B10 - {"disableplayeruse", 0x800B}, // SP 0x000000000 MP 0x140374BB0 - {"_meth_800C", 0x800C}, // SP 0x000000000 MP 0x140374D70 - {"_meth_800D", 0x800D}, // SP 0x000000000 MP 0x140374C90 - {"makescrambler", 0x800E}, // SP 0x000000000 MP 0x14037B890 - {"makeportableradar", 0x800F}, // SP 0x000000000 MP 0x14037B930 - {"clearscrambler", 0x8010}, // SP 0x000000000 MP 0x14037B910 - {"clearportableradar", 0x8011}, // SP 0x000000000 MP 0x14037B960 - {"addplayermantleblockage", 0x8012}, // SP 0x000000000 MP 0x1403760E0 - {"setteamfortrigger", 0x8013}, // SP 0x000000000 MP 0x14037B130 - {"clientclaimtrigger", 0x8014}, // SP 0x000000000 MP 0x14037B220 - {"clientreleasetrigger", 0x8015}, // SP 0x000000000 MP 0x14037B300 - {"releaseclaimedtrigger", 0x8016}, // SP 0x000000000 MP 0x14037B510 - {"_meth_8017", 0x8017}, // SP 0x000000000 MP 0x14037AC10 - {"_meth_8018", 0x8018}, // SP 0x000000000 MP 0x14037ACD0 - {"_meth_8019", 0x8019}, // SP 0x000000000 MP 0x140378210 - {"_meth_801A", 0x801A}, // SP 0x14028F380 MP 0x14036F540 - {"getcorpseanim", 0x801B}, // SP 0x000000000 MP 0x14037BD60 - {"playerforcedeathanim", 0x801C}, // SP 0x000000000 MP 0x140374A30 - {"_meth_801D", 0x801D}, // SP 0x14029DCF0 MP 0x140369D40 - {"_meth_801E", 0x801E}, // SP 0x1402AD230 MP 0x000000000 - {"_meth_801F", 0x801F}, // SP 0x1402AD490 MP 0x000000000 - {"_meth_8020", 0x8020}, // SP 0x1402AD4C0 MP 0x000000000 - {"_meth_8021", 0x8021}, // SP 0x1402AD640 MP 0x000000000 - {"_meth_8022", 0x8022}, // SP 0x1402AD660 MP 0x000000000 - {"_meth_8023", 0x8023}, // SP 0x1402AD920 MP 0x14037BA50 - {"_meth_8024", 0x8024}, // SP 0x1402ADA90 MP 0x000000000 - {"_meth_8025", 0x8025}, // SP 0x1405D92F0 MP 0x14035CB60 - {"_meth_8026", 0x8026}, // SP 0x1405D92F0 MP 0x140377C40 - {"_meth_8028", 0x8028}, // SP 0x1402ADE80 MP 0x000000000 - {"_meth_8029", 0x8029}, // SP 0x14029AEC0 MP 0x140362D10 - {"_meth_802A", 0x802A}, // SP 0x14029E0E0 MP 0x14036A480 - {"detachall", 0x802B}, // SP 0x14029E180 MP 0x14036A4C0 - {"getattachsize", 0x802C}, // SP 0x1402A0610 MP 0x14036C860 - {"getattachmodelname", 0x802D}, // SP 0x1402A0890 MP 0x14036CE90 - {"_meth_802E", 0x802E}, // SP 0x1402A0A90 MP 0x14036D040 - {"_meth_802F", 0x802F}, // SP 0x1402AE150 MP 0x000000000 - {"_meth_8030", 0x8030}, // SP 0x1402AE270 MP 0x000000000 - {"_meth_8031", 0x8031}, // SP 0x1402AE410 MP 0x000000000 - {"_meth_8032", 0x8032}, // SP 0x1402AE620 MP 0x000000000 - {"_meth_8033", 0x8033}, // SP 0x1402AE6E0 MP 0x000000000 - {"_meth_8034", 0x8034}, // SP 0x1402CBC10 MP 0x000000000 - {"gethighestnodestance", 0x8035}, // SP 0x1402CBBA0 MP 0x14031F650 - {"doesnodeallowstance", 0x8036}, // SP 0x1402CBA70 MP 0x14031F520 - {"setforcespectatorclient", 0x8037}, // SP 0x1402CBB20 MP 0x14031F5D0 - {"_meth_8038", 0x8038}, // SP 0x1402AB240 MP 0x000000000 - {"_meth_8039", 0x8039}, // SP 0x1402AB320 MP 0x000000000 - {"_meth_803A", 0x803A}, // SP 0x1402AB6D0 MP 0x000000000 - {"_meth_803B", 0x803B}, // SP 0x1402ACA20 MP 0x000000000 - {"_meth_803C", 0x803C}, // SP 0x1402ACA40 MP 0x000000000 - {"_meth_803D", 0x803D}, // SP 0x1402ACBA0 MP 0x000000000 - {"_meth_803E", 0x803E}, // SP 0x1402AFA80 MP 0x000000000 - {"_meth_803F", 0x803F}, // SP 0x1402AFAC0 MP 0x000000000 - {"_meth_8040", 0x8040}, // SP 0x1402AFB90 MP 0x000000000 - {"_meth_8041", 0x8041}, // SP 0x1402AFC50 MP 0x000000000 - {"_meth_8042", 0x8042}, // SP 0x1402AFCA0 MP 0x000000000 - {"_meth_8043", 0x8043}, // SP 0x1402A8990 MP 0x000000000 - {"_meth_8044", 0x8044}, // SP 0x1402A89F0 MP 0x000000000 - {"_meth_8045", 0x8045}, // SP 0x14028F020 MP 0x14036EDF0 - {"_meth_8046", 0x8046}, // SP 0x14028F1F0 MP 0x14036EEE0 - {"_meth_8047", 0x8047}, // SP 0x1402ACE10 MP 0x000000000 - {"_meth_8048", 0x8048}, // SP 0x1402ACE50 MP 0x000000000 - {"getattachignorecollision", 0x8049}, // SP 0x1402A1060 MP 0x14036D280 - {"hidepart", 0x804A}, // SP 0x1402A1500 MP 0x14036D940 - {"hidepartallinstances", 0x804B}, // SP 0x1402A1930 MP 0x14036DC50 - {"_meth_804C", 0x804C}, // SP 0x1402A1C90 MP 0x14036E320 - {"showpart", 0x804D}, // SP 0x1402A2000 MP 0x14036E480 - {"_meth_804E", 0x804E}, // SP 0x1402A2370 MP 0x14036ECC0 - {"_meth_804F", 0x804F}, // SP 0x1402A3670 MP 0x140358AF0 - {"_meth_8050", 0x8050}, // SP 0x1402A3AB0 MP 0x140359830 - {"_meth_8051", 0x8051}, // SP 0x1402A3AD0 MP 0x140359850 - {"_meth_8052", 0x8052}, // SP 0x1402AD0F0 MP 0x140379AD0 - {"_meth_8053", 0x8053}, // SP 0x1402A2B80 MP 0x14036B270 - {"_meth_8054", 0x8054}, // SP 0x1402AD260 MP 0x000000000 - {"show", 0x8055}, // SP 0x1402AD6A0 MP 0x14037A9E0 - {"hide", 0x8056}, // SP 0x1402AD6C0 MP 0x14037AAA0 - {"_meth_8057", 0x8057}, // SP 0x1402AD7A0 MP 0x000000000 - {"_meth_8058", 0x8058}, // SP 0x1402AD7D0 MP 0x000000000 - {"disconnectpaths", 0x8059}, // SP 0x14028E1E0 MP 0x14036F090 - {"connectpaths", 0x805A}, // SP 0x14028E390 MP 0x14036F4C0 - {"_meth_805B", 0x805B}, // SP 0x14028E490 MP 0x14036F5F0 - {"_meth_805C", 0x805C}, // SP 0x14028E750 MP 0x14036F770 - {"_meth_805D", 0x805D}, // SP 0x1402A8420 MP 0x000000000 - {"_meth_805E", 0x805E}, // SP 0x1402A8440 MP 0x000000000 - {"_meth_805F", 0x805F}, // SP 0x1402A8460 MP 0x000000000 - {"_meth_8060", 0x8060}, // SP 0x1402A8480 MP 0x000000000 - {"_meth_8061", 0x8061}, // SP 0x1402A9250 MP 0x000000000 - {"_meth_8062", 0x8062}, // SP 0x1402A92D0 MP 0x000000000 - {"_meth_8063", 0x8063}, // SP 0x1402A9BC0 MP 0x000000000 - {"_meth_8064", 0x8064}, // SP 0x1402AABA0 MP 0x000000000 - {"_meth_8065", 0x8065}, // SP 0x1402AAC10 MP 0x000000000 - {"setmode", 0x8067}, // SP 0x1402AD9A0 MP 0x140375030 - {"_meth_8068", 0x8068}, // SP 0x1402ADCD0 MP 0x140375210 - {"_meth_8069", 0x8069}, // SP 0x1402ADF10 MP 0x000000000 - {"islinked", 0x806A}, // SP 0x14028D6B0 MP 0x1403598E0 - {"enablelinkto", 0x806B}, // SP 0x14028EA50 MP 0x14035A950 - {"_meth_806C", 0x806C}, // SP 0x1402ACB60 MP 0x000000000 - {"_meth_806E", 0x806E}, // SP 0x1402A27D0 MP 0x14035AB10 - {"_meth_806F", 0x806F}, // SP 0x1402A23E0 MP 0x14035A9C0 - {"_meth_8070", 0x8070}, // SP 0x1402A2980 MP 0x14035B0D0 - {"_meth_8071", 0x8071}, // SP 0x1402A28C0 MP 0x14035AB50 - {"_meth_8072", 0x8072}, // SP 0x140291F10 MP 0x000000000 - {"_meth_8073", 0x8073}, // SP 0x1405D92F0 MP 0x000000000 - {"_meth_8074", 0x8074}, // SP 0x1405D92F0 MP 0x000000000 - {"_meth_8075", 0x8075}, // SP 0x1405D92F0 MP 0x000000000 - {"_meth_8076", 0x8076}, // SP 0x1402ACC40 MP 0x1403798B0 - {"playloopsound", 0x8077}, // SP 0x1402ACC60 MP 0x1403798F0 - {"_meth_8078", 0x8078}, // SP 0x1402ACCD0 MP 0x000000000 - {"_meth_8079", 0x8079}, // SP 0x1402ACD40 MP 0x000000000 - {"_meth_807A", 0x807A}, // SP 0x1402ACDD0 MP 0x000000000 - {"_meth_807B", 0x807B}, // SP 0x1402ACE30 MP 0x000000000 - {"_meth_807C", 0x807C}, // SP 0x1402ACEE0 MP 0x000000000 - {"getnormalhealth", 0x807D}, // SP 0x1402ACFF0 MP 0x1403799E0 - {"_meth_807E", 0x807E}, // SP 0x14028FA50 MP 0x14035B880 - {"_meth_807F", 0x807F}, // SP 0x14028FB40 MP 0x14035B8D0 - {"_meth_8080", 0x8080}, // SP 0x14028FB60 MP 0x14035BD70 - {"playerlinktoabsolute", 0x8081}, // SP 0x14028FBE0 MP 0x14035C100 - {"playerlinktoblend", 0x8082}, // SP 0x140292720 MP 0x14035DCB0 - {"playerlinkedoffsetenable", 0x8083}, // SP 0x140290050 MP 0x14035C5A0 - {"_meth_8084", 0x8084}, // SP 0x14026DC10 MP 0x14033BBF0 - {"_meth_8085", 0x8085}, // SP 0x14026DC60 MP 0x14033BC00 - {"changefontscaleovertime", 0x8086}, // SP 0x14026E020 MP 0x14033BF50 - {"scaleovertime", 0x8087}, // SP 0x14026E160 MP 0x14033C090 - {"_meth_8088", 0x8088}, // SP 0x14026E240 MP 0x14033C170 - {"_meth_8089", 0x8089}, // SP 0x14026E380 MP 0x14033C230 - {"destroy", 0x808A}, // SP 0x14026E3C0 MP 0x14033C310 - {"_meth_808B", 0x808B}, // SP 0x14026E500 MP 0x14033C3F0 - {"_meth_808C", 0x808C}, // SP 0x14026E440 MP 0x14033C360 - {"fadeovertime", 0x808D}, // SP 0x14026E0C0 MP 0x14033BFF0 - {"_meth_808E", 0x808E}, // SP 0x1402A83E0 MP 0x000000000 - {"_meth_808F", 0x808F}, // SP 0x1402A8400 MP 0x000000000 - {"_meth_8090", 0x8090}, // SP 0x1402A8970 MP 0x000000000 - {"_meth_8091", 0x8091}, // SP 0x1402A89D0 MP 0x000000000 - {"_meth_8092", 0x8092}, // SP 0x1402AD800 MP 0x000000000 - {"playersetgroundreferenceent", 0x8093}, // SP 0x1402A9070 MP 0x1403752A0 - {"dontinterpolate", 0x8094}, // SP 0x1402A0070 MP 0x140358360 - {"_meth_8095", 0x8095}, // SP 0x1402AAC80 MP 0x000000000 - {"_meth_8096", 0x8096}, // SP 0x1402AAD20 MP 0x000000000 - {"_meth_8097", 0x8097}, // SP 0x1402AADC0 MP 0x140377CA0 - {"_meth_8098", 0x8098}, // SP 0x1402AAE70 MP 0x000000000 - {"_meth_8099", 0x8099}, // SP 0x1402AAF90 MP 0x000000000 - {"_meth_809A", 0x809A}, // SP 0x1402AC1D0 MP 0x000000000 - {"useby", 0x809B}, // SP 0x1402AC470 MP 0x140377D00 - {"playsound", 0x809C}, // SP 0x1402AC9B0 MP 0x140377F40 - {"playerlinkedoffsetdisable", 0x80A1}, // SP 0x140290320 MP 0x14035CAF0 - {"playerlinkedsetviewznear", 0x80A2}, // SP 0x140290680 MP 0x14035CE40 - {"playerlinkedsetusebaseangleforviewclamp", 0x80A3}, // SP 0x140290960 MP 0x14035D290 - {"_meth_80A4", 0x80A4}, // SP 0x140294B30 MP 0x14035F4A0 - {"_meth_80A5", 0x80A5}, // SP 0x140295300 MP 0x14035FD70 - {"_meth_80A6", 0x80A6}, // SP 0x1402958C0 MP 0x000000000 - {"_meth_80A7", 0x80A7}, // SP 0x1402960D0 MP 0x000000000 - {"_meth_80A8", 0x80A8}, // SP 0x140297190 MP 0x000000000 - {"_meth_80A9", 0x80A9}, // SP 0x140297C20 MP 0x000000000 - {"_meth_80AA", 0x80AA}, // SP 0x14029DDD0 MP 0x1403663C0 - {"istouching", 0x80AB}, // SP 0x140290390 MP 0x14035B440 - {"getistouchingentities", 0x80AC}, // SP 0x1402904A0 MP 0x14035B650 - {"_meth_80AD", 0x80AD}, // SP 0x1402987B0 MP 0x14035FAA0 - {"stopsounds", 0x80AE}, // SP 0x140290F40 MP 0x14035C610 - {"playrumbleonentity", 0x80AF}, // SP 0x140299090 MP 0x140360200 - {"playrumblelooponentity", 0x80B0}, // SP 0x140299200 MP 0x1403602A0 - {"stoprumble", 0x80B1}, // SP 0x1402997D0 MP 0x1403608E0 - {"delete", 0x80B2}, // SP 0x14029DAA0 MP 0x140366320 - {"setmodel", 0x80B3}, // SP 0x14029C8F0 MP 0x1403677D0 - {"_meth_80B4", 0x80B4}, // SP 0x14029A0F0 MP 0x140361C30 - {"_meth_80B5", 0x80B5}, // SP 0x14029A250 MP 0x140361F90 - {"thermalvisionon", 0x80B8}, // SP 0x14029A450 MP 0x1403623A0 - {"thermalvisionoff", 0x80B9}, // SP 0x14029AAF0 MP 0x140362B70 - {"_meth_80BA", 0x80BA}, // SP 0x14029BF20 MP 0x140364290 - {"_meth_80BB", 0x80BB}, // SP 0x14029C080 MP 0x140364630 - {"_meth_80BC", 0x80BC}, // SP 0x000000000 MP 0x140364910 - {"autospotoverlayon", 0x80BD}, // SP 0x000000000 MP 0x140364A50 - {"_meth_80BE", 0x80BE}, // SP 0x000000000 MP 0x140364D40 - {"setcontents", 0x80C0}, // SP 0x140297CC0 MP 0x14035FDD0 - {"makeusable", 0x80C1}, // SP 0x140297E90 MP 0x1403600D0 - {"makeunusable", 0x80C2}, // SP 0x140297FF0 MP 0x140360320 - {"_meth_80C3", 0x80C3}, // SP 0x1402A1730 MP 0x140359740 - {"_meth_80C4", 0x80C4}, // SP 0x1402A1A80 MP 0x140359DC0 - {"_meth_80C5", 0x80C5}, // SP 0x140266A20 MP 0x000000000 - {"_meth_80C6", 0x80C6}, // SP 0x1402634D0 MP 0x000000000 - {"_meth_80C7", 0x80C7}, // SP 0x1404657D0 MP 0x000000000 - {"_meth_80C8", 0x80C8}, // SP 0x140463A30 MP 0x000000000 - {"_meth_80C9", 0x80C9}, // SP 0x140465630 MP 0x000000000 - {"_meth_80CA", 0x80CA}, // SP 0x1404656C0 MP 0x000000000 - {"_meth_80CB", 0x80CB}, // SP 0x140464F50 MP 0x000000000 - {"settext", 0x80CC}, // SP 0x14026CE20 MP 0x14033AF40 - {"_meth_80CD", 0x80CD}, // SP 0x1405D92F0 MP 0x14033B030 - {"setshader", 0x80CE}, // SP 0x14026CEE0 MP 0x14033B040 - {"_meth_80CF", 0x80CF}, // SP 0x14026D230 MP 0x14033B3A0 - {"_meth_80D0", 0x80D0}, // SP 0x14026D3B0 MP 0x14033B530 - {"_meth_80D1", 0x80D1}, // SP 0x14026D490 MP 0x14033B600 - {"_meth_80D2", 0x80D2}, // SP 0x14026D560 MP 0x14033B6C0 - {"_meth_80D3", 0x80D3}, // SP 0x14026D630 MP 0x14033B760 - {"_meth_80D4", 0x80D4}, // SP 0x14026D700 MP 0x14033B810 - {"_meth_80D5", 0x80D5}, // SP 0x14026D7D0 MP 0x14033B8D0 - {"_meth_80D6", 0x80D6}, // SP 0x14026D8A0 MP 0x14033B970 - {"setclock", 0x80D7}, // SP 0x14026D970 MP 0x14033BA20 - {"setclockup", 0x80D8}, // SP 0x14026D990 MP 0x14033BA40 - {"setvalue", 0x80D9}, // SP 0x14026D9B0 MP 0x14033BA60 - {"setwaypoint", 0x80DA}, // SP 0x14026DA50 MP 0x14033BAE0 - {"_meth_80DB", 0x80DB}, // SP 0x14026DBC0 MP 0x14033BBE0 - {"setcursorhint", 0x80DC}, // SP 0x1402983E0 MP 0x1403607E0 - {"sethintstring", 0x80DD}, // SP 0x140299300 MP 0x140361060 - {"_meth_80DE", 0x80DE}, // SP 0x000000000 MP 0x140375C60 - {"forceusehinton", 0x80DF}, // SP 0x140299730 MP 0x140361260 - {"_meth_80E0", 0x80E0}, // SP 0x140299930 MP 0x140361530 - {"_meth_80E1", 0x80E1}, // SP 0x140298080 MP 0x140360440 - {"_meth_80E2", 0x80E2}, // SP 0x140298160 MP 0x140360570 - {"entitywillneverchange", 0x80E3}, // SP 0x1405D92F0 MP 0x140360620 - {"_meth_80E4", 0x80E4}, // SP 0x140291140 MP 0x14035D1B0 - {"_meth_80E5", 0x80E5}, // SP 0x1402912D0 MP 0x14035D310 - {"isfiringturret", 0x80E6}, // SP 0x140291490 MP 0x14035D460 - {"startbarrelspin", 0x80E7}, // SP 0x1402915B0 MP 0x14035D650 - {"stopbarrelspin", 0x80E8}, // SP 0x1402916E0 MP 0x14035D8D0 - {"getbarrelspinrate", 0x80E9}, // SP 0x140291A10 MP 0x14035DA40 - {"_meth_80EA", 0x80EA}, // SP 0x000000000 MP 0x14035C870 - {"remotecontrolturretoff", 0x80EB}, // SP 0x000000000 MP 0x14035CDD0 - {"_meth_80EC", 0x80EC}, // SP 0x140293380 MP 0x14035E870 - {"getturretowner", 0x80ED}, // SP 0x140293430 MP 0x14035EE50 - {"_meth_80EE", 0x80EE}, // SP 0x140268590 MP 0x000000000 - {"_meth_80EF", 0x80EF}, // SP 0x1402685F0 MP 0x000000000 - {"_meth_80F0", 0x80F0}, // SP 0x140268640 MP 0x000000000 - {"_meth_80F1", 0x80F1}, // SP 0x140268690 MP 0x000000000 - {"_meth_80F2", 0x80F2}, // SP 0x1402686F0 MP 0x000000000 - {"_meth_80F3", 0x80F3}, // SP 0x140268750 MP 0x000000000 - {"_meth_80F4", 0x80F4}, // SP 0x1402687A0 MP 0x000000000 - {"_meth_80F5", 0x80F5}, // SP 0x140268AF0 MP 0x000000000 - {"_meth_80F6", 0x80F6}, // SP 0x140268CC0 MP 0x000000000 - {"_meth_80F7", 0x80F7}, // SP 0x140268D20 MP 0x000000000 - {"_meth_80F8", 0x80F8}, // SP 0x140268D80 MP 0x000000000 - {"_meth_80F9", 0x80F9}, // SP 0x140268E10 MP 0x000000000 - {"_meth_80FA", 0x80FA}, // SP 0x140268EC0 MP 0x000000000 - {"_meth_80FB", 0x80FB}, // SP 0x140262E80 MP 0x14032F050 - {"_meth_80FC", 0x80FC}, // SP 0x140268890 MP 0x000000000 - {"_meth_80FD", 0x80FD}, // SP 0x1402688E0 MP 0x000000000 - {"_meth_80FE", 0x80FE}, // SP 0x1402689B0 MP 0x000000000 - {"_meth_80FF", 0x80FF}, // SP 0x140268A40 MP 0x000000000 - {"_meth_8100", 0x8100}, // SP 0x1402611F0 MP 0x14032CF70 - {"_meth_8101", 0x8101}, // SP 0x140261420 MP 0x14032D270 - {"_meth_8102", 0x8102}, // SP 0x140268930 MP 0x000000000 - {"_meth_8103", 0x8103}, // SP 0x1402616E0 MP 0x000000000 - {"_meth_8104", 0x8104}, // SP 0x1402667A0 MP 0x000000000 - {"setsentryowner", 0x8105}, // SP 0x1402935E0 MP 0x14035EF40 - {"setsentrycarrier", 0x8106}, // SP 0x140293F00 MP 0x14035F1B0 - {"setturretminimapvisible", 0x8107}, // SP 0x1402942F0 MP 0x14035F6D0 - {"settargetentity", 0x8108}, // SP 0x140294600 MP 0x14035F860 - {"snaptotargetentity", 0x8109}, // SP 0x140294A20 MP 0x14035FB70 - {"cleartargetentity", 0x810A}, // SP 0x140294E90 MP 0x14035FE30 - {"getturrettarget", 0x810B}, // SP 0x140295270 MP 0x140360040 - {"setplayerspread", 0x810C}, // SP 0x1402957F0 MP 0x1403606C0 - {"_meth_810D", 0x810D}, // SP 0x140295A70 MP 0x140360990 - {"_meth_810E", 0x810E}, // SP 0x140295D50 MP 0x1403609A0 - {"_meth_810F", 0x810F}, // SP 0x14028A710 MP 0x000000000 - {"_meth_8110", 0x8110}, // SP 0x14028A730 MP 0x000000000 - {"_meth_8111", 0x8111}, // SP 0x14028A750 MP 0x000000000 - {"_meth_8112", 0x8112}, // SP 0x14028A770 MP 0x000000000 - {"_meth_8113", 0x8113}, // SP 0x14028A790 MP 0x000000000 - {"_meth_8114", 0x8114}, // SP 0x14028A7B0 MP 0x000000000 - {"_meth_8115", 0x8115}, // SP 0x14028A7C0 MP 0x000000000 - {"_meth_8116", 0x8116}, // SP 0x14028A7E0 MP 0x000000000 - {"_meth_8117", 0x8117}, // SP 0x14028A800 MP 0x000000000 - {"_meth_8118", 0x8118}, // SP 0x14028A8E0 MP 0x000000000 - {"_meth_8119", 0x8119}, // SP 0x14028A960 MP 0x000000000 - {"_meth_811A", 0x811A}, // SP 0x140261760 MP 0x14032D140 - {"_meth_811B", 0x811B}, // SP 0x140261870 MP 0x14032D2D0 - {"_meth_811C", 0x811C}, // SP 0x140261950 MP 0x14032D630 - {"_meth_811D", 0x811D}, // SP 0x140261A30 MP 0x14032D780 - {"_meth_811E", 0x811E}, // SP 0x140269090 MP 0x000000000 - {"_meth_811F", 0x811F}, // SP 0x140269510 MP 0x000000000 - {"_meth_8121", 0x8121}, // SP 0x1402692D0 MP 0x000000000 - {"_meth_8122", 0x8122}, // SP 0x140269350 MP 0x000000000 - {"_meth_8123", 0x8123}, // SP 0x140269650 MP 0x000000000 - {"_meth_8128", 0x8128}, // SP 0x140269650 MP 0x000000000 - {"_meth_8129", 0x8129}, // SP 0x140269370 MP 0x000000000 - {"_meth_812A", 0x812A}, // SP 0x1402680B0 MP 0x000000000 - {"_meth_812B", 0x812B}, // SP 0x1402681E0 MP 0x000000000 - {"_meth_812C", 0x812C}, // SP 0x1402691F0 MP 0x000000000 - {"_meth_812D", 0x812D}, // SP 0x140268290 MP 0x000000000 - {"_meth_812E", 0x812E}, // SP 0x140267290 MP 0x14032B170 - {"_meth_812F", 0x812F}, // SP 0x140267650 MP 0x14032B720 - {"_meth_8130", 0x8130}, // SP 0x140262E20 MP 0x14032F570 - {"_meth_8131", 0x8131}, // SP 0x1402684C0 MP 0x000000000 - {"_meth_8132", 0x8132}, // SP 0x140261580 MP 0x14032CD50 - {"_meth_8133", 0x8133}, // SP 0x140261670 MP 0x14032CF00 - {"_meth_8134", 0x8134}, // SP 0x140268530 MP 0x000000000 - {"setconvergencetime", 0x8135}, // SP 0x140295E90 MP 0x140360A40 - {"setconvergenceheightpercent", 0x8136}, // SP 0x140296650 MP 0x140360E90 - {"setturretteam", 0x8137}, // SP 0x1402967E0 MP 0x140361150 - {"_meth_8138", 0x8138}, // SP 0x140296C90 MP 0x140361320 - {"startfiring", 0x8139}, // SP 0x140296D70 MP 0x140361370 - {"stopfiring", 0x813A}, // SP 0x140296E90 MP 0x1403615A0 - {"_meth_813B", 0x813B}, // SP 0x1402D7DD0 MP 0x140077920 - {"freeentitysentient", 0x813C}, // SP 0x1402D7EE0 MP 0x140077A40 - {"_meth_813D", 0x813D}, // SP 0x1402D7FE0 MP 0x000000000 - {"_meth_813E", 0x813E}, // SP 0x1402D8040 MP 0x000000000 - {"_meth_813F", 0x813F}, // SP 0x1402D80E0 MP 0x000000000 - {"_meth_8140", 0x8140}, // SP 0x14028A390 MP 0x000000000 - {"_meth_8142", 0x8142}, // SP 0x14028A3D0 MP 0x000000000 - {"_meth_8143", 0x8143}, // SP 0x14028A370 MP 0x000000000 - {"_meth_8144", 0x8144}, // SP 0x14028A410 MP 0x000000000 - {"_meth_8145", 0x8145}, // SP 0x14028A490 MP 0x000000000 - {"_meth_8146", 0x8146}, // SP 0x14028A4B0 MP 0x000000000 - {"_meth_8147", 0x8147}, // SP 0x14028A4C0 MP 0x000000000 - {"_meth_8148", 0x8148}, // SP 0x14028A4E0 MP 0x000000000 - {"_meth_8149", 0x8149}, // SP 0x14028A500 MP 0x000000000 - {"_meth_814A", 0x814A}, // SP 0x14028A520 MP 0x000000000 - {"_meth_814B", 0x814B}, // SP 0x14028A530 MP 0x000000000 - {"_meth_814C", 0x814C}, // SP 0x14028A550 MP 0x000000000 - {"_meth_814D", 0x814D}, // SP 0x14028A570 MP 0x000000000 - {"_meth_814E", 0x814E}, // SP 0x14028A590 MP 0x000000000 - {"_meth_814F", 0x814F}, // SP 0x14028A5A0 MP 0x000000000 - {"_meth_8150", 0x8150}, // SP 0x14028A5C0 MP 0x000000000 - {"_meth_8151", 0x8151}, // SP 0x14028A5E0 MP 0x000000000 - {"_meth_8152", 0x8152}, // SP 0x14028A650 MP 0x000000000 - {"_meth_8153", 0x8153}, // SP 0x14028A690 MP 0x000000000 - {"_meth_8154", 0x8154}, // SP 0x14028A6E0 MP 0x000000000 - {"_meth_8155", 0x8155}, // SP 0x14028A700 MP 0x000000000 - {"_meth_8156", 0x8156}, // SP 0x1405D92F0 MP 0x140361680 - {"_meth_8157", 0x8157}, // SP 0x140297730 MP 0x140362260 - {"_meth_8158", 0x8158}, // SP 0x140297890 MP 0x140362410 - {"_meth_8159", 0x8159}, // SP 0x140297D20 MP 0x1403629F0 - {"_meth_815A", 0x815A}, // SP 0x140297F90 MP 0x140362CB0 - {"setautorotationdelay", 0x815B}, // SP 0x1402980D0 MP 0x140363040 - {"_meth_815C", 0x815C}, // SP 0x140298800 MP 0x1403638A0 - {"restoredefaultdroppitch", 0x815D}, // SP 0x140298880 MP 0x140363B30 - {"turretfiredisable", 0x815E}, // SP 0x140299040 MP 0x140363CF0 - {"_meth_815F", 0x815F}, // SP 0x1402495F0 MP 0x000000000 - {"_meth_8160", 0x8160}, // SP 0x1402496C0 MP 0x000000000 - {"_meth_8161", 0x8161}, // SP 0x140249790 MP 0x000000000 - {"_meth_8162", 0x8162}, // SP 0x140249810 MP 0x000000000 - {"_meth_8163", 0x8163}, // SP 0x140249950 MP 0x000000000 - {"_meth_8164", 0x8164}, // SP 0x140249A30 MP 0x000000000 - {"_meth_8165", 0x8165}, // SP 0x140249AC0 MP 0x000000000 - {"_meth_8166", 0x8166}, // SP 0x140249B00 MP 0x000000000 - {"_meth_8167", 0x8167}, // SP 0x140249BE0 MP 0x000000000 - {"_meth_8168", 0x8168}, // SP 0x140249C70 MP 0x000000000 - {"_meth_8169", 0x8169}, // SP 0x140262B90 MP 0x14032E0A0 - {"_meth_816A", 0x816A}, // SP 0x140249D10 MP 0x000000000 - {"_meth_816B", 0x816B}, // SP 0x140249EE0 MP 0x000000000 - {"_meth_816C", 0x816C}, // SP 0x14024A0E0 MP 0x000000000 - {"_meth_816D", 0x816D}, // SP 0x14024A200 MP 0x000000000 - {"_meth_816E", 0x816E}, // SP 0x14024A2D0 MP 0x000000000 - {"_meth_816F", 0x816F}, // SP 0x14024A3F0 MP 0x000000000 - {"_meth_8170", 0x8170}, // SP 0x14024A480 MP 0x000000000 - {"_meth_8171", 0x8171}, // SP 0x14024A5C0 MP 0x000000000 - {"_meth_8172", 0x8172}, // SP 0x14024A630 MP 0x000000000 - {"_meth_8173", 0x8173}, // SP 0x14024A710 MP 0x000000000 - {"_meth_8174", 0x8174}, // SP 0x14024A880 MP 0x000000000 - {"_meth_8175", 0x8175}, // SP 0x14024AAD0 MP 0x000000000 - {"_meth_8176", 0x8176}, // SP 0x14024AB30 MP 0x000000000 - {"_meth_8177", 0x8177}, // SP 0x14024AB90 MP 0x000000000 - {"_meth_8178", 0x8178}, // SP 0x14024AC50 MP 0x000000000 - {"getenemysqdist", 0x8179}, // SP 0x1402D77E0 MP 0x1400772C0 - {"_meth_817A", 0x817A}, // SP 0x1402D7820 MP 0x140077300 - {"setthreatbiasgroup", 0x817B}, // SP 0x1402D7BE0 MP 0x1400776E0 - {"getthreatbiasgroup", 0x817C}, // SP 0x1402D7C50 MP 0x140077750 - {"turretfireenable", 0x817D}, // SP 0x140299220 MP 0x140363EE0 - {"setturretmodechangewait", 0x817E}, // SP 0x1402994D0 MP 0x140364690 - {"usetriggerrequirelookat", 0x817F}, // SP 0x140297DE0 MP 0x14035EEE0 - {"getstance", 0x8180}, // SP 0x14029D1C0 MP 0x140364F90 - {"_meth_8181", 0x8181}, // SP 0x14029D430 MP 0x140365230 - {"itemweaponsetammo", 0x8182}, // SP 0x140299FA0 MP 0x140360F20 - {"_meth_8183", 0x8183}, // SP 0x14029A5A0 MP 0x140361420 - {"gettagorigin", 0x8184}, // SP 0x14029E360 MP 0x140368090 - {"gettagangles", 0x8185}, // SP 0x14029E810 MP 0x140368320 - {"_meth_8186", 0x8186}, // SP 0x14028E580 MP 0x14036D490 - {"stunplayer", 0x8187}, // SP 0x14028F160 MP 0x14036DEC0 - {"_meth_8188", 0x8188}, // SP 0x14029B970 MP 0x140366E70 - {"_meth_8189", 0x8189}, // SP 0x14029BB30 MP 0x140367230 - {"setdepthoffield", 0x818A}, // SP 0x14029EF20 MP 0x140368890 - {"setviewmodeldepthoffield", 0x818B}, // SP 0x14029F990 MP 0x140369900 - {"_meth_818C", 0x818C}, // SP 0x1402A15D0 MP 0x14036AD20 - {"_meth_818D", 0x818D}, // SP 0x140247D90 MP 0x000000000 - {"_meth_818E", 0x818E}, // SP 0x140247DE0 MP 0x000000000 - {"_meth_818F", 0x818F}, // SP 0x140247E50 MP 0x000000000 - {"_meth_8190", 0x8190}, // SP 0x140247E90 MP 0x000000000 - {"_meth_8191", 0x8191}, // SP 0x140247F00 MP 0x000000000 - {"_meth_8192", 0x8192}, // SP 0x140247F90 MP 0x000000000 - {"_meth_8193", 0x8193}, // SP 0x140248160 MP 0x000000000 - {"_meth_8194", 0x8194}, // SP 0x1402484A0 MP 0x000000000 - {"_meth_8195", 0x8195}, // SP 0x1402485A0 MP 0x000000000 - {"_meth_8196", 0x8196}, // SP 0x1402485F0 MP 0x000000000 - {"_meth_8197", 0x8197}, // SP 0x140248640 MP 0x000000000 - {"_meth_8198", 0x8198}, // SP 0x1402486A0 MP 0x000000000 - {"_meth_8199", 0x8199}, // SP 0x1402486F0 MP 0x000000000 - {"_meth_819E", 0x819E}, // SP 0x1402487C0 MP 0x000000000 - {"_meth_819F", 0x819F}, // SP 0x140248870 MP 0x000000000 - {"_meth_81A0", 0x81A0}, // SP 0x1402488C0 MP 0x000000000 - {"getnegotiationstartnode", 0x81A1}, // SP 0x140248970 MP 0x14044F980 - {"getnegotiationendnode", 0x81A2}, // SP 0x1402489E0 MP 0x14044F830 - {"getnegotiationnextnode", 0x81A3}, // SP 0x140248A50 MP 0x14044F8D0 - {"_meth_81A4", 0x81A4}, // SP 0x140248B30 MP 0x000000000 - {"_meth_81A5", 0x81A5}, // SP 0x140248BD0 MP 0x000000000 - {"_meth_81A6", 0x81A6}, // SP 0x140248CC0 MP 0x000000000 - {"_meth_81A7", 0x81A7}, // SP 0x140248DD0 MP 0x000000000 - {"_meth_81A8", 0x81A8}, // SP 0x140247750 MP 0x000000000 - {"_meth_81A9", 0x81A9}, // SP 0x140248E30 MP 0x000000000 - {"_meth_81AA", 0x81AA}, // SP 0x140248FB0 MP 0x000000000 - {"_meth_81AB", 0x81AB}, // SP 0x1402490D0 MP 0x000000000 - {"_meth_81AC", 0x81AC}, // SP 0x140249170 MP 0x000000000 - {"_meth_81AD", 0x81AD}, // SP 0x140249290 MP 0x000000000 - {"_meth_81AE", 0x81AE}, // SP 0x140249460 MP 0x000000000 - {"_meth_81AF", 0x81AF}, // SP 0x1402494B0 MP 0x000000000 - {"_meth_81B0", 0x81B0}, // SP 0x140249500 MP 0x000000000 - {"_meth_81B1", 0x81B1}, // SP 0x1402A15D0 MP 0x14036ADA0 - {"_meth_81B2", 0x81B2}, // SP 0x1402A15D0 MP 0x14036AE60 - {"viewkick", 0x81B3}, // SP 0x1402A1640 MP 0x14036AFA0 - {"_meth_81B4", 0x81B4}, // SP 0x14029B1E0 MP 0x1403668B0 - {"_meth_81B5", 0x81B5}, // SP 0x1402998B0 MP 0x140364980 - {"autoboltmissileeffects", 0x81B6}, // SP 0x140299AA0 MP 0x140364B50 - {"enablegrenadetouchdamage", 0x81B7}, // SP 0x140299CA0 MP 0x140364F40 - {"disablegrenadetouchdamage", 0x81B8}, // SP 0x140299F20 MP 0x1403650C0 - {"_meth_81B9", 0x81B9}, // SP 0x14029AF00 MP 0x1403665A0 - {"_meth_81BA", 0x81BA}, // SP 0x14024AF80 MP 0x000000000 - {"_meth_81BB", 0x81BB}, // SP 0x14024B160 MP 0x000000000 - {"_meth_81BC", 0x81BC}, // SP 0x14024B3B0 MP 0x000000000 - {"_meth_81BD", 0x81BD}, // SP 0x14024B4F0 MP 0x000000000 - {"_meth_81BE", 0x81BE}, // SP 0x14024B570 MP 0x000000000 - {"_meth_81BF", 0x81BF}, // SP 0x14024B910 MP 0x000000000 - {"_meth_81C0", 0x81C0}, // SP 0x14024BA40 MP 0x000000000 - {"_meth_81C1", 0x81C1}, // SP 0x14024BB20 MP 0x000000000 - {"_meth_81C2", 0x81C2}, // SP 0x14024BB90 MP 0x000000000 - {"_meth_81C3", 0x81C3}, // SP 0x14024BC40 MP 0x000000000 - {"_meth_81C4", 0x81C4}, // SP 0x1402D7F30 MP 0x140077AA0 - {"_meth_81C5", 0x81C5}, // SP 0x1402D7F90 MP 0x140077B00 - {"_meth_81C6", 0x81C6}, // SP 0x14024BD90 MP 0x000000000 - {"_meth_81C7", 0x81C7}, // SP 0x14024C010 MP 0x000000000 - {"_meth_81C8", 0x81C8}, // SP 0x14024C150 MP 0x000000000 - {"_meth_81C9", 0x81C9}, // SP 0x14024C240 MP 0x000000000 - {"_meth_81CA", 0x81CA}, // SP 0x14024C250 MP 0x000000000 - {"_meth_81CB", 0x81CB}, // SP 0x14024C270 MP 0x000000000 - {"_meth_81CC", 0x81CC}, // SP 0x14024C290 MP 0x000000000 - {"_meth_81CD", 0x81CD}, // SP 0x14024C2F0 MP 0x000000000 - {"_meth_81CE", 0x81CE}, // SP 0x14024C360 MP 0x000000000 - {"_meth_81CF", 0x81CF}, // SP 0x14024C430 MP 0x000000000 - {"_meth_81D0", 0x81D0}, // SP 0x14024C520 MP 0x000000000 - {"_meth_81D1", 0x81D1}, // SP 0x14024C560 MP 0x000000000 - {"_meth_81D2", 0x81D2}, // SP 0x14024C5A0 MP 0x000000000 - {"_meth_81D3", 0x81D3}, // SP 0x14024C5E0 MP 0x000000000 - {"_meth_81D4", 0x81D4}, // SP 0x140247BF0 MP 0x000000000 - {"_meth_81D5", 0x81D5}, // SP 0x140247CE0 MP 0x000000000 - {"_meth_81D6", 0x81D6}, // SP 0x140247930 MP 0x000000000 - {"_meth_81D7", 0x81D7}, // SP 0x14029B180 MP 0x140366790 - {"entityradiusdamage", 0x81D8}, // SP 0x1402A3840 MP 0x14036C130 - {"_meth_81D9", 0x81D9}, // SP 0x14028DCF0 MP 0x14036CAB0 - {"bddatachunk::deserialize", 0x81DA}, // SP 0x14028E350 MP 0x14036D0C0 - {"_meth_81DB", 0x81DB}, // SP 0x14028E430 MP 0x14036D150 - {"_meth_81DC", 0x81DC}, // SP 0x14029A340 MP 0x140365D80 - {"_meth_81DD", 0x81DD}, // SP 0x14029A4E0 MP 0x140365E90 - {"_meth_81DE", 0x81DE}, // SP 0x14029A700 MP 0x140366180 - {"missilesetflightmodedirect", 0x81DF}, // SP 0x14029AA10 MP 0x1403663A0 - {"missilesetflightmodetop", 0x81E0}, // SP 0x14029AB50 MP 0x140366480 - {"getlightintensity", 0x81E1}, // SP 0x14028EA00 MP 0x14036E8B0 - {"_meth_81E2", 0x81E2}, // SP 0x14028EB40 MP 0x14036EAB0 - {"isragdoll", 0x81E3}, // SP 0x14028F2F0 MP 0x14036F2E0 - {"setmovespeedscale", 0x81E4}, // SP 0x1402A2860 MP 0x14036EF80 - {"cameralinkto", 0x81E5}, // SP 0x14028FFC0 MP 0x1403584E0 - {"cameraunlink", 0x81E6}, // SP 0x1402900C0 MP 0x140358750 - {"_meth_81E7", 0x81E7}, // SP 0x140248F30 MP 0x000000000 - {"_meth_81E8", 0x81E8}, // SP 0x1402491F0 MP 0x000000000 - {"_meth_81E9", 0x81E9}, // SP 0x140249230 MP 0x000000000 - {"_meth_81EA", 0x81EA}, // SP 0x140249370 MP 0x000000000 - {"_meth_81EB", 0x81EB}, // SP 0x140249650 MP 0x000000000 - {"_meth_81EC", 0x81EC}, // SP 0x140249710 MP 0x000000000 - {"_meth_81ED", 0x81ED}, // SP 0x1402499B0 MP 0x000000000 - {"_meth_81EE", 0x81EE}, // SP 0x140249A70 MP 0x000000000 - {"_meth_81EF", 0x81EF}, // SP 0x140249B80 MP 0x000000000 - {"_meth_81F0", 0x81F0}, // SP 0x140249C30 MP 0x000000000 - {"_meth_81F1", 0x81F1}, // SP 0x140249CC0 MP 0x000000000 - {"_meth_81F2", 0x81F2}, // SP 0x140249E00 MP 0x000000000 - {"_meth_81F3", 0x81F3}, // SP 0x140249E50 MP 0x000000000 - {"_meth_81F4", 0x81F4}, // SP 0x14024A010 MP 0x000000000 - {"_meth_81F5", 0x81F5}, // SP 0x14024A080 MP 0x000000000 - {"_meth_81F6", 0x81F6}, // SP 0x14024A190 MP 0x000000000 - {"_meth_81F7", 0x81F7}, // SP 0x14024A330 MP 0x000000000 - {"_meth_81F8", 0x81F8}, // SP 0x14024A390 MP 0x000000000 - {"_meth_81F9", 0x81F9}, // SP 0x14024A260 MP 0x000000000 - {"_meth_81FA", 0x81FA}, // SP 0x14024A440 MP 0x000000000 - {"_meth_81FB", 0x81FB}, // SP 0x14024A4F0 MP 0x000000000 - {"_meth_81FC", 0x81FC}, // SP 0x14024A6B0 MP 0x000000000 - {"_meth_81FD", 0x81FD}, // SP 0x14024A780 MP 0x000000000 - {"_meth_81FE", 0x81FE}, // SP 0x14024A950 MP 0x000000000 - {"_meth_81FF", 0x81FF}, // SP 0x14024AC00 MP 0x000000000 - {"_meth_8200", 0x8200}, // SP 0x14024AD60 MP 0x000000000 - {"_meth_8201", 0x8201}, // SP 0x14024AE60 MP 0x000000000 - {"_meth_8202", 0x8202}, // SP 0x14024B1D0 MP 0x000000000 - {"_meth_8203", 0x8203}, // SP 0x14024B2C0 MP 0x000000000 - {"controlslinkto", 0x8204}, // SP 0x1402905D0 MP 0x140358F20 - {"controlsunlink", 0x8205}, // SP 0x1402908B0 MP 0x1403593C0 - {"_meth_8206", 0x8206}, // SP 0x000000000 MP 0x14035AB40 - {"_meth_8207", 0x8207}, // SP 0x1402AA5F0 MP 0x000000000 - {"_meth_8208", 0x8208}, // SP 0x000000000 MP 0x14035ABE0 - {"_meth_820A", 0x820A}, // SP 0x000000000 MP 0x14035B100 - {"_meth_820B", 0x820B}, // SP 0x000000000 MP 0x14035B170 - {"_meth_820C", 0x820C}, // SP 0x000000000 MP 0x14035B380 - {"_meth_820D", 0x820D}, // SP 0x000000000 MP 0x14035B210 - {"_meth_820E", 0x820E}, // SP 0x000000000 MP 0x14035B270 - {"drivevehicleandcontrolturret", 0x820F}, // SP 0x140291CD0 MP 0x14035C250 - {"drivevehicleandcontrolturretoff", 0x8210}, // SP 0x140292090 MP 0x14035C420 - {"_meth_8211", 0x8211}, // SP 0x1402923D0 MP 0x14035C930 - {"_meth_8212", 0x8212}, // SP 0x1402931B0 MP 0x14035CBB0 - {"_meth_8213", 0x8213}, // SP 0x1402940E0 MP 0x14035D6A0 - {"_meth_8214", 0x8214}, // SP 0x140296080 MP 0x14035F750 - {"_meth_8215", 0x8215}, // SP 0x1402961E0 MP 0x14035F810 - {"_meth_8216", 0x8216}, // SP 0x140296540 MP 0x14035FB00 - {"_meth_8217", 0x8217}, // SP 0x1402966E0 MP 0x14035FC80 - {"circle", 0x8218}, // SP 0x1402990B0 MP 0x1403620D0 - {"rect", 0x8219}, // SP 0x140299540 MP 0x140362730 - {"_meth_821A", 0x821A}, // SP 0x140299B00 MP 0x140362E50 - {"transfermarkstonewscriptmodel", 0x821B}, // SP 0x14029A1B0 MP 0x140363790 - {"setwatersheeting", 0x821C}, // SP 0x140290290 MP 0x140358930 - {"_meth_821D", 0x821D}, // SP 0x1402A29B0 MP 0x000000000 - {"_meth_821E", 0x821E}, // SP 0x1402A32F0 MP 0x000000000 - {"setweaponhudiconoverride", 0x821F}, // SP 0x140296A30 MP 0x14035FC90 - {"getweaponhudiconoverride", 0x8220}, // SP 0x140297010 MP 0x140360380 - {"_meth_8221", 0x8221}, // SP 0x1402976A0 MP 0x1403609B0 - {"_meth_8222", 0x8222}, // SP 0x140299CF0 MP 0x1403635A0 - {"_meth_8223", 0x8223}, // SP 0x140299B90 MP 0x1403630E0 - {"_meth_8224", 0x8224}, // SP 0x14029A2C0 MP 0x140363C10 - {"_meth_8225", 0x8225}, // SP 0x14029DF50 MP 0x140365F70 - {"_meth_8226", 0x8226}, // SP 0x1402A17F0 MP 0x14036B0B0 - {"vehicleturretcontroloff", 0x8227}, // SP 0x140464260 MP 0x140562970 - {"isturretready", 0x8228}, // SP 0x140464340 MP 0x1405629E0 - {"_meth_8229", 0x8229}, // SP 0x140464570 MP 0x140562C70 - {"dospawn", 0x822A}, // SP 0x1404646D0 MP 0x140562D90 - {"isphysveh", 0x822B}, // SP 0x1404647A0 MP 0x140562E80 - {"crash", 0x822C}, // SP 0x140464840 MP 0x140562F80 - {"launch", 0x822D}, // SP 0x140464980 MP 0x1405630A0 - {"disablecrashing", 0x822E}, // SP 0x140464B20 MP 0x140563240 - {"enablecrashing", 0x822F}, // SP 0x140464C10 MP 0x140563310 - {"setspeed", 0x8230}, // SP 0x140464C90 MP 0x1405633E0 - {"setconveyorbelt", 0x8231}, // SP 0x140464E50 MP 0x140563610 - {"freevehicle", 0x8232}, // SP 0x000000000 MP 0x1405609B0 - {"_meth_8233", 0x8233}, // SP 0x140290E70 MP 0x000000000 - {"_meth_8234", 0x8234}, // SP 0x1402910E0 MP 0x000000000 - {"_meth_8235", 0x8235}, // SP 0x140291670 MP 0x000000000 - {"_meth_8236", 0x8236}, // SP 0x140291A60 MP 0x000000000 - {"_meth_8237", 0x8237}, // SP 0x140292010 MP 0x000000000 - {"_meth_8238", 0x8238}, // SP 0x140292230 MP 0x000000000 - {"_meth_8239", 0x8239}, // SP 0x14029C2A0 MP 0x000000000 - {"_meth_823A", 0x823A}, // SP 0x14029CAD0 MP 0x000000000 - {"_meth_823B", 0x823B}, // SP 0x14029CD70 MP 0x000000000 - {"_meth_823C", 0x823C}, // SP 0x14029CF00 MP 0x000000000 - {"_meth_823D", 0x823D}, // SP 0x140292BA0 MP 0x000000000 - {"_meth_823E", 0x823E}, // SP 0x140292DF0 MP 0x000000000 - {"_meth_8240", 0x8240}, // SP 0x1402A3880 MP 0x000000000 - {"_meth_8241", 0x8241}, // SP 0x140248AD0 MP 0x000000000 - {"_meth_8242", 0x8242}, // SP 0x140248EA0 MP 0x000000000 - {"_meth_8243", 0x8243}, // SP 0x1402A1AF0 MP 0x14036B910 - {"_meth_8244", 0x8244}, // SP 0x1402A1E20 MP 0x14036BE30 - {"_meth_8245", 0x8245}, // SP 0x1402A24D0 MP 0x14036C5B0 - {"trackerupdate", 0x8246}, // SP 0x14028DC50 MP 0x14036E800 - {"pingplayer", 0x8247}, // SP 0x000000000 MP 0x140332B50 - {"_meth_8248", 0x8248}, // SP 0x140268FE0 MP 0x140332B40 - {"sayteam", 0x8249}, // SP 0x000000000 MP 0x1403345F0 - {"sayall", 0x824A}, // SP 0x000000000 MP 0x1403346A0 - {"_meth_824B", 0x824B}, // SP 0x000000000 MP 0x140332C90 - {"_meth_824C", 0x824C}, // SP 0x140265080 MP 0x140330FE0 - {"dropscavengerbag", 0x824D}, // SP 0x000000000 MP 0x140332FB0 - {"setjitterparams", 0x824E}, // SP 0x140461E80 MP 0x140560640 - {"sethoverparams", 0x824F}, // SP 0x140461F50 MP 0x140560710 - {"joltbody", 0x8250}, // SP 0x140462070 MP 0x1405607B0 - {"freevehicle", 0x8251}, // SP 0x140462250 MP 0x1405609B0 - {"_meth_8252", 0x8252}, // SP 0x140462300 MP 0x140560A20 - {"getvehicleowner", 0x8253}, // SP 0x140462550 MP 0x140560C70 - {"setvehiclelookattext", 0x8254}, // SP 0x1404625D0 MP 0x140560CF0 - {"setvehicleteam", 0x8255}, // SP 0x140462660 MP 0x140560D80 - {"neargoalnotifydist", 0x8256}, // SP 0x1404626E0 MP 0x140560F10 - {"setgoalpos", 0x8257}, // SP 0x140462750 MP 0x140560F80 - {"setgoalyaw", 0x8258}, // SP 0x140462840 MP 0x1405610A0 - {"cleargoalyaw", 0x8259}, // SP 0x1404628D0 MP 0x140561130 - {"settargetyaw", 0x825A}, // SP 0x140462950 MP 0x1405611B0 - {"cleartargetyaw", 0x825B}, // SP 0x1404629E0 MP 0x140561240 - {"helisetgoal", 0x825C}, // SP 0x140462A60 MP 0x1405612C0 - {"_meth_825D", 0x825D}, // SP 0x140463320 MP 0x140561B60 - {"setturrettargetent", 0x825E}, // SP 0x140463410 MP 0x140561C60 - {"clearturrettargetent", 0x825F}, // SP 0x140463510 MP 0x140561D60 - {"canturrettargetpoint", 0x8260}, // SP 0x1404635A0 MP 0x140561DF0 - {"setlookatent", 0x8261}, // SP 0x1404638A0 MP 0x1405620F0 - {"clearlookatent", 0x8262}, // SP 0x140463950 MP 0x1405621A0 - {"setweapon", 0x8263}, // SP 0x140463AB0 MP 0x140562280 - {"_meth_8264", 0x8264}, // SP 0x140463B20 MP 0x1405622F0 - {"vehicleturretcontrolon", 0x8265}, // SP 0x1404641D0 MP 0x1405628F0 - {"finishplayerdamage", 0x8266}, // SP 0x000000000 MP 0x1403337A0 - {"suicide", 0x8267}, // SP 0x000000000 MP 0x140333E20 - {"_meth_8268", 0x8268}, // SP 0x000000000 MP 0x140334010 - {"_meth_8269", 0x8269}, // SP 0x000000000 MP 0x1403340A0 - {"_meth_826A", 0x826A}, // SP 0x000000000 MP 0x140334120 - {"spawn", 0x826B}, // SP 0x000000000 MP 0x1403341A0 - {"_meth_826C", 0x826C}, // SP 0x000000000 MP 0x140334230 - {"_meth_826D", 0x826D}, // SP 0x000000000 MP 0x140334290 - {"istalking", 0x826E}, // SP 0x000000000 MP 0x140334570 - {"allowspectateteam", 0x826F}, // SP 0x000000000 MP 0x140334750 - {"_meth_8270", 0x8270}, // SP 0x000000000 MP 0x140334980 - {"getguid", 0x8271}, // SP 0x000000000 MP 0x140334B20 - {"_meth_8272", 0x8272}, // SP 0x1402B3CA0 MP 0x14037FA00 - {"_meth_8273", 0x8273}, // SP 0x1402B3EC0 MP 0x14037FC50 - {"clonebrushmodeltoscriptmodel", 0x8274}, // SP 0x1402B4500 MP 0x140380380 - {"_meth_8275", 0x8275}, // SP 0x000000000 MP 0x140380450 - {"scriptmodelclearanim", 0x8276}, // SP 0x000000000 MP 0x140380700 - {"_meth_8277", 0x8277}, // SP 0x000000000 MP 0x140380570 - {"_meth_8278", 0x8278}, // SP 0x140465060 MP 0x1405637F0 - {"attachpath", 0x8279}, // SP 0x1404651E0 MP 0x14055F040 - {"getattachpos", 0x827A}, // SP 0x1404652F0 MP 0x14055F170 - {"startpath", 0x827B}, // SP 0x1404654A0 MP 0x14055F340 - {"setswitchnode", 0x827C}, // SP 0x140465740 MP 0x14055F4D0 - {"setwaitspeed", 0x827D}, // SP 0x140465840 MP 0x14055F560 - {"finishdamage", 0x827E}, // SP 0x000000000 MP 0x14055F5E0 - {"setspeed", 0x827F}, // SP 0x1404658C0 MP 0x14055F840 - {"setspeedimmediate", 0x8280}, // SP 0x140465930 MP 0x14055F8B0 - {"_meth_8281", 0x8281}, // SP 0x140465AC0 MP 0x14055FA60 - {"getspeed", 0x8282}, // SP 0x140465BE0 MP 0x14055FB80 - {"getvelocity", 0x8283}, // SP 0x140465CD0 MP 0x14055FC70 - {"getbodyvelocity", 0x8284}, // SP 0x140465D40 MP 0x14055FCE0 - {"getsteering", 0x8285}, // SP 0x140465DB0 MP 0x14055FD50 - {"getthrottle", 0x8286}, // SP 0x140465E30 MP 0x14055FDE0 - {"turnengineoff", 0x8287}, // SP 0x140465EA0 MP 0x14055FE50 - {"turnengineon", 0x8288}, // SP 0x140465F00 MP 0x14055FEC0 - {"_meth_8289", 0x8289}, // SP 0x140465F60 MP 0x000000000 - {"getgoalspeedmph", 0x828A}, // SP 0x140466020 MP 0x14055FF30 - {"_meth_828B", 0x828B}, // SP 0x140466090 MP 0x14055FFA0 - {"setacceleration", 0x828C}, // SP 0x140466100 MP 0x140560010 - {"resumespeed", 0x828D}, // SP 0x140466170 MP 0x140560080 - {"setyawspeed", 0x828E}, // SP 0x140466200 MP 0x140560110 - {"setyawspeedbyname", 0x828F}, // SP 0x140466360 MP 0x140560270 - {"setmaxpitchroll", 0x8290}, // SP 0x140461CC0 MP 0x140560480 - {"setairresitance", 0x8291}, // SP 0x140461D80 MP 0x140560540 - {"setturningability", 0x8292}, // SP 0x140461E10 MP 0x1405605D0 - {"_meth_8293", 0x8293}, // SP 0x140260F20 MP 0x140334B90 - {"_meth_8294", 0x8294}, // SP 0x000000000 MP 0x140334D50 - {"ismlgspectator", 0x8295}, // SP 0x000000000 MP 0x140334DB0 - {"getclanidhigh", 0x8296}, // SP 0x000000000 MP 0x140334E10 - {"getclanidlow", 0x8297}, // SP 0x000000000 MP 0x140334E70 - {"_meth_8298", 0x8298}, // SP 0x000000000 MP 0x140334ED0 - {"getspectatingplayer", 0x8299}, // SP 0x000000000 MP 0x140334F60 - {"predictstreampos", 0x829A}, // SP 0x000000000 MP 0x140334FE0 - {"_meth_829B", 0x829B}, // SP 0x000000000 MP 0x1403350D0 - {"_meth_829C", 0x829C}, // SP 0x000000000 MP 0x1403350E0 - {"setrank", 0x829D}, // SP 0x000000000 MP 0x1403350F0 - {"_meth_829E", 0x829E}, // SP 0x000000000 MP 0x140335190 - {"setmlgspectator", 0x829F}, // SP 0x140260730 MP 0x14032CA40 - {"visionsyncwithplayer", 0x82A0}, // SP 0x000000000 MP 0x14032ED90 - {"showhudsplash", 0x82A1}, // SP 0x140263850 MP 0x14032FB10 - {"setperk", 0x82A2}, // SP 0x140265490 MP 0x1403297E0 - {"_meth_82A3", 0x82A3}, // SP 0x1402659A0 MP 0x140329D00 - {"_meth_82A4", 0x82A4}, // SP 0x1402661B0 MP 0x14032A460 - {"_meth_82A5", 0x82A5}, // SP 0x140265D40 MP 0x14032A0A0 - {"registerparty", 0x82A6}, // SP 0x000000000 MP 0x1403323C0 - {"_meth_82A7", 0x82A7}, // SP 0x000000000 MP 0x1403324F0 - {"_meth_82A8", 0x82A8}, // SP 0x1405D92F0 MP 0x14032A8F0 - {"_meth_82A9", 0x82A9}, // SP 0x1405D92F0 MP 0x14032A900 - {"moveto", 0x82AA}, // SP 0x1402B2A10 MP 0x14037E950 - {"rotatepitch", 0x82AB}, // SP 0x1402B2F60 MP 0x14037EEB0 - {"rotateyaw", 0x82AC}, // SP 0x1402B2F70 MP 0x14037EEC0 - {"rotateroll", 0x82AD}, // SP 0x1402B2F90 MP 0x14037EEE0 - {"_meth_82AE", 0x82AE}, // SP 0x1402B2C10 MP 0x14037EB00 - {"_meth_82AF", 0x82AF}, // SP 0x1402B2D70 MP 0x14037EC90 - {"_meth_82B0", 0x82B0}, // SP 0x1402B2EE0 MP 0x14037EE20 - {"rotateby", 0x82B1}, // SP 0x1402B3030 MP 0x14037EF10 - {"_meth_82B2", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 - {"_meth_82B3", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 - {"_meth_82B4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 - {"_meth_82B5", 0x82B5}, // SP 0x1402B3410 MP 0x14037F010 - {"_meth_82B6", 0x82B6}, // SP 0x1402B3430 MP 0x14037F030 - {"_meth_82B7", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 - {"_meth_82B8", 0x82B8}, // SP 0x1402B34B0 MP 0x14037F0B0 - {"_meth_82B9", 0x82B9}, // SP 0x1402B3700 MP 0x14037F3C0 - {"solid", 0x82BA}, // SP 0x1402B45E0 MP 0x1403808A0 - {"notsolid", 0x82BB}, // SP 0x1402B4690 MP 0x140380950 - {"setcandamage", 0x82BC}, // SP 0x1402B3880 MP 0x14037F590 - {"setcanradiusdamage", 0x82BD}, // SP 0x1402B38E0 MP 0x14037F5F0 - {"physicslaunchclient", 0x82BE}, // SP 0x1402B3960 MP 0x14037F670 - {"_meth_82BF", 0x82BF}, // SP 0x000000000 MP 0x1403351A0 - {"_meth_82C0", 0x82C0}, // SP 0x000000000 MP 0x1403351B0 - {"setcarddisplayslot", 0x82C1}, // SP 0x000000000 MP 0x1403351C0 - {"regweaponforfxremoval", 0x82C2}, // SP 0x000000000 MP 0x1403352B0 - {"laststandrevive", 0x82C3}, // SP 0x000000000 MP 0x140331E00 - {"_meth_82C4", 0x82C4}, // SP 0x000000000 MP 0x140331E70 - {"setspectatedefaults", 0x82C5}, // SP 0x000000000 MP 0x140331EE0 - {"getthirdpersoncrosshairoffset", 0x82C6}, // SP 0x000000000 MP 0x140332250 - {"_meth_82C7", 0x82C7}, // SP 0x140262950 MP 0x14032EF00 - {"_meth_82C8", 0x82C8}, // SP 0x140262A60 MP 0x14032EFF0 - {"_meth_82C9", 0x82C9}, // SP 0x140262AB0 MP 0x14032F0D0 - {"_meth_82CA", 0x82CA}, // SP 0x000000000 MP 0x1403322C0 - {"getweaponslistexclusives", 0x82CB}, // SP 0x1402623D0 MP 0x14032E3A0 - {"_meth_82CC", 0x82CC}, // SP 0x1402624C0 MP 0x14032E4B0 - {"_meth_82CD", 0x82CD}, // SP 0x1402625B0 MP 0x14032E650 - {"getweaponslist", 0x82CE}, // SP 0x140262720 MP 0x14032E790 - {"canplayerplacesentry", 0x82CF}, // SP 0x140264D00 MP 0x140331530 - {"canplayerplacetank", 0x82D0}, // SP 0x1402651B0 MP 0x1403292E0 - {"visionsetnakedforplayer", 0x82D1}, // SP 0x140263410 MP 0x14032FC00 - {"visionsetnightforplayer", 0x82D2}, // SP 0x1402636D0 MP 0x14032FC10 - {"visionsetmissilecamforplayer", 0x82D3}, // SP 0x1402636F0 MP 0x14032FC30 - {"visionsetthermalforplayer", 0x82D4}, // SP 0x140263710 MP 0x14032FD20 - {"visionsetpainforplayer", 0x82D5}, // SP 0x140263730 MP 0x14032FD40 - {"setblurforplayer", 0x82D6}, // SP 0x140264890 MP 0x140330B80 - {"_meth_82D7", 0x82D7}, // SP 0x140264C80 MP 0x140331310 - {"_meth_82D8", 0x82D8}, // SP 0x140264C80 MP 0x140331330 - {"_meth_82D9", 0x82D9}, // SP 0x1402ABE90 MP 0x000000000 - {"getbuildnumber", 0x82DA}, // SP 0x1402663A0 MP 0x14032A910 - {"_meth_82DB", 0x82DB}, // SP 0x140266AF0 MP 0x14032AE90 - {"_meth_82DC", 0x82DC}, // SP 0x140266CD0 MP 0x14032B120 - {"_meth_82DD", 0x82DD}, // SP 0x140266FE0 MP 0x14032B500 - {"playfx", 0x82DE}, // SP 0x140267330 MP 0x14032B9F0 - {"playerrecoilscaleon", 0x82DF}, // SP 0x140267530 MP 0x14032BD00 - {"_meth_82E0", 0x82E0}, // SP 0x140267600 MP 0x14032BDD0 - {"weaponlockstart", 0x82E1}, // SP 0x1402676E0 MP 0x14032C000 - {"weaponlockfinalize", 0x82E2}, // SP 0x140260240 MP 0x14032C240 - {"disableautoreload", 0x82E3}, // SP 0x140260540 MP 0x14032C6C0 - {"setentertime", 0x82E4}, // SP 0x1402605E0 MP 0x14032C7F0 - {"usinggamepad", 0x82E5}, // SP 0x000000000 MP 0x140332300 - {"_meth_82E6", 0x82E6}, // SP 0x000000000 MP 0x140332380 - {"_meth_82E7", 0x82E7}, // SP 0x000000000 MP 0x140332390 - {"_meth_82E8", 0x82E8}, // SP 0x000000000 MP 0x1403323B0 - {"_meth_82E9", 0x82E9}, // SP 0x000000000 MP 0x1403323A0 - {"_meth_82EA", 0x82EA}, // SP 0x1402628A0 MP 0x14032E5C0 - {"_meth_82EB", 0x82EB}, // SP 0x1402619B0 MP 0x14032D5A0 - {"_meth_82EC", 0x82EC}, // SP 0x140261AA0 MP 0x14032D6D0 - {"issighted", 0x82ED}, // SP 0x140263D40 MP 0x14032FA10 - {"setvelocity", 0x82EE}, // SP 0x1402601C0 MP 0x14032BBE0 - {"_meth_82EF", 0x82EF}, // SP 0x140260AD0 MP 0x14032C3C0 - {"_meth_82F0", 0x82F0}, // SP 0x140260E80 MP 0x14032C5E0 - {"_meth_82F1", 0x82F1}, // SP 0x1402677A0 MP 0x14032BE30 - {"_meth_82F2", 0x82F2}, // SP 0x140260130 MP 0x14032BF20 - {"_meth_82F3", 0x82F3}, // SP 0x140264AD0 MP 0x140330E20 - {"setweaponammostock", 0x82F4}, // SP 0x140264EB0 MP 0x140331350 - {"_meth_82F5", 0x82F5}, // SP 0x140265380 MP 0x1403293A0 - {"getweaponammostock", 0x82F6}, // SP 0x1402655D0 MP 0x140329580 - {"_meth_82F7", 0x82F7}, // SP 0x140265820 MP 0x140329990 - {"stoplocalsound", 0x82F8}, // SP 0x140265F20 MP 0x14032A3B0 - {"setclientdvar", 0x82F9}, // SP 0x140266410 MP 0x14032A990 - {"_meth_82FA", 0x82FA}, // SP 0x1402666C0 MP 0x14032B260 - {"_meth_82FB", 0x82FB}, // SP 0x000000000 MP 0x14032AC30 - {"_meth_82FC", 0x82FC}, // SP 0x000000000 MP 0x14032AD80 - {"allowads", 0x82FD}, // SP 0x140261130 MP 0x14032C940 - {"_meth_82FE", 0x82FE}, // SP 0x140261440 MP 0x14032CAB0 - {"_meth_82FF", 0x82FF}, // SP 0x140261B20 MP 0x14032D890 - {"_meth_8300", 0x8300}, // SP 0x140261C00 MP 0x14032DA40 - {"weaponlocktargettooclose", 0x8301}, // SP 0x140261CE0 MP 0x14032DBB0 - {"setspreadoverride", 0x8302}, // SP 0x140262B00 MP 0x14032ED00 - {"resetspreadoverride", 0x8303}, // SP 0x140262CC0 MP 0x14032EE80 - {"_meth_8304", 0x8304}, // SP 0x140262D90 MP 0x14032EF60 - {"setactionslot", 0x8305}, // SP 0x140261F10 MP 0x14032DD50 - {"setviewkickscale", 0x8306}, // SP 0x1402608B0 MP 0x14032CB90 - {"getviewkickscale", 0x8307}, // SP 0x140260A80 MP 0x14032CCC0 - {"getweaponslistoffhands", 0x8308}, // SP 0x1402621A0 MP 0x14032E120 - {"getweaponslistitems", 0x8309}, // SP 0x1402622E0 MP 0x14032E230 - {"_meth_830A", 0x830A}, // SP 0x140261090 MP 0x14032C720 - {"_meth_830B", 0x830B}, // SP 0x140262F00 MP 0x14032EA90 - {"_meth_830C", 0x830C}, // SP 0x140263380 MP 0x14032F210 - {"takeallweapons", 0x830D}, // SP 0x1402635B0 MP 0x14032F310 - {"getcurrentweapon", 0x830E}, // SP 0x140263750 MP 0x14032F5E0 - {"getcurrentprimaryweapon", 0x830F}, // SP 0x140263A30 MP 0x14032F860 - {"getcurrentoffhand", 0x8310}, // SP 0x140263EF0 MP 0x14032FC50 - {"givestartammo", 0x8311}, // SP 0x1402647A0 MP 0x140330740 - {"switchtoweapon", 0x8312}, // SP 0x140264CA0 MP 0x140330D20 - {"switchtoweaponimmediate", 0x8313}, // SP 0x140264E50 MP 0x140330D90 - {"_meth_8314", 0x8314}, // SP 0x140265950 MP 0x140329520 - {"switchtooffhand", 0x8315}, // SP 0x140265B80 MP 0x1403296D0 - {"_meth_8316", 0x8316}, // SP 0x140264440 MP 0x140330340 - {"getcustomizationbody", 0x8317}, // SP 0x140264600 MP 0x140330520 - {"beginlocationselection", 0x8318}, // SP 0x140260C90 MP 0x14032C470 - {"_meth_8319", 0x8319}, // SP 0x140261020 MP 0x14032C780 - {"_meth_831A", 0x831A}, // SP 0x140263E90 MP 0x1403302E0 - {"_meth_831B", 0x831B}, // SP 0x140264020 MP 0x140330410 - {"_meth_831C", 0x831C}, // SP 0x140264150 MP 0x1403305B0 - {"_meth_831D", 0x831D}, // SP 0x140264270 MP 0x1403306E0 - {"_meth_831E", 0x831E}, // SP 0x140264660 MP 0x140330B20 - {"_meth_831F", 0x831F}, // SP 0x140264750 MP 0x140330CC0 - {"setaimspreadmovementscale", 0x8320}, // SP 0x1402631F0 MP 0x14032F130 - {"closemenu", 0x8321}, // SP 0x140263290 MP 0x14032F3A0 - {"_meth_8322", 0x8322}, // SP 0x140263330 MP 0x14032F4E0 - {"openpopupmenu", 0x8323}, // SP 0x140263430 MP 0x14032F6C0 - {"openpopupmenunomouse", 0x8324}, // SP 0x140263630 MP 0x14032F930 - {"freezecontrols", 0x8326}, // SP 0x140263B10 MP 0x14032FD60 - {"disableusability", 0x8327}, // SP 0x140263C10 MP 0x14032FFE0 - {"enableusability", 0x8328}, // SP 0x140263E40 MP 0x1403300F0 - {"_meth_8329", 0x8329}, // SP 0x140266C00 MP 0x14032B640 - {"_meth_832A", 0x832A}, // SP 0x140266D10 MP 0x14032B800 - {"_meth_832B", 0x832B}, // SP 0x140266EA0 MP 0x14032B9C0 - {"_meth_832C", 0x832C}, // SP 0x140267180 MP 0x14032B9E0 - {"deactivatechannelvolumes", 0x832D}, // SP 0x140267410 MP 0x14032BB00 - {"_meth_832E", 0x832E}, // SP 0x140265FA0 MP 0x140329C00 - {"_meth_832F", 0x832F}, // SP 0x140266200 MP 0x140329F00 - {"_meth_8330", 0x8330}, // SP 0x140266560 MP 0x14032A240 - {"_meth_8331", 0x8331}, // SP 0x140266820 MP 0x14032A6F0 - {"isdualwielding", 0x8332}, // SP 0x140266E10 MP 0x14032ABC0 - {"_meth_8333", 0x8333}, // SP 0x140267030 MP 0x14032AD00 - {"isreloading", 0x8334}, // SP 0x140267100 MP 0x14032AEE0 - {"setorigin", 0x8335}, // SP 0x1402677C0 MP 0x14032B8D0 - {"getvelocity", 0x8336}, // SP 0x1402604D0 MP 0x14032BC80 - {"_meth_8337", 0x8337}, // SP 0x140260930 MP 0x14032BE70 - {"forcemantle", 0x8338}, // SP 0x140260990 MP 0x14032C0D0 - {"attackbuttonpressed", 0x8339}, // SP 0x140261500 MP 0x14032CE10 - {"_meth_833A", 0x833A}, // SP 0x1402615F0 MP 0x14032D0B0 - {"meleebuttonpressed", 0x833B}, // SP 0x1402617D0 MP 0x14032D1B0 - {"jumpbuttonpressed", 0x833C}, // SP 0x1402618D0 MP 0x14032D450 - {"getviewheight", 0x833D}, // SP 0x140262070 MP 0x14032DC20 - {"_meth_833E", 0x833E}, // SP 0x1402620C0 MP 0x14032DCE0 - {"isonladder", 0x833F}, // SP 0x140262280 MP 0x14032DF80 - {"setviewmodel", 0x8340}, // SP 0x1402626A0 MP 0x14032DFF0 - {"_meth_8341", 0x8341}, // SP 0x140264090 MP 0x14032FF10 - {"_meth_8342", 0x8342}, // SP 0x1402642C0 MP 0x140330170 - {"_meth_8343", 0x8343}, // SP 0x140260360 MP 0x000000000 - {"_meth_8344", 0x8344}, // SP 0x140260640 MP 0x000000000 - {"_meth_8345", 0x8345}, // SP 0x1402607E0 MP 0x000000000 - {"_meth_8346", 0x8346}, // SP 0x1402609E0 MP 0x000000000 - {"_meth_8347", 0x8347}, // SP 0x14026D000 MP 0x14033B150 - {"forcethirdpersonwhenfollowing", 0x8348}, // SP 0x000000000 MP 0x140374D30 - {"disableforcethirdpersonwhenfollowing", 0x8349}, // SP 0x000000000 MP 0x140374DD0 - {"_meth_834A", 0x834A}, // SP 0x140260C10 MP 0x14032C5D0 - {"_meth_834B", 0x834B}, // SP 0x000000000 MP 0x14037B380 - {"secondaryoffhandbuttonpressed", 0x834C}, // SP 0x140261D40 MP 0x14032D9C0 - {"_meth_834D", 0x834D}, // SP 0x000000000 MP 0x140374B70 - {"_meth_834E", 0x834E}, // SP 0x000000000 MP 0x140374C10 - {"botsetflag", 0x834F}, // SP 0x000000000 MP 0x1404798E0 - {"botsetstance", 0x8350}, // SP 0x000000000 MP 0x14047A0F0 - {"botsetscriptmove", 0x8351}, // SP 0x000000000 MP 0x140479F70 - {"_meth_8352", 0x8352}, // SP 0x000000000 MP 0x140479BC0 - {"_meth_8353", 0x8353}, // SP 0x000000000 MP 0x140479DB0 - {"botclearscriptgoal", 0x8354}, // SP 0x000000000 MP 0x140477C80 - {"getnearestnode", 0x8355}, // SP 0x000000000 MP 0x140479B00 - {"botclearscriptenemy", 0x8356}, // SP 0x000000000 MP 0x140477C00 - {"botsetattacker", 0x8357}, // SP 0x000000000 MP 0x1404796A0 - {"botgetscriptgoal", 0x8358}, // SP 0x000000000 MP 0x1404784A0 - {"botgetscriptgoalradius", 0x8359}, // SP 0x000000000 MP 0x1404785F0 - {"botgetscriptgoalyaw", 0x835A}, // SP 0x000000000 MP 0x1404786F0 - {"botgetscriptgoaltype", 0x835B}, // SP 0x000000000 MP 0x140478670 - {"_meth_835D", 0x835D}, // SP 0x000000000 MP 0x140478850 - {"_meth_835E", 0x835E}, // SP 0x000000000 MP 0x140478E10 - {"botfindnoderandom", 0x835F}, // SP 0x000000000 MP 0x140477D00 - {"botmemoryevent", 0x8360}, // SP 0x000000000 MP 0x140478B70 - {"_meth_8362", 0x8362}, // SP 0x000000000 MP 0x140478EB0 - {"bothasscriptgoal", 0x8363}, // SP 0x000000000 MP 0x140478890 - {"botgetpersonality", 0x8364}, // SP 0x000000000 MP 0x140478420 - {"_meth_8365", 0x8365}, // SP 0x000000000 MP 0x14047A1C0 - {"botsetpersonality", 0x8367}, // SP 0x000000000 MP 0x140479A70 - {"botsetdifficulty", 0x8368}, // SP 0x000000000 MP 0x1404797B0 - {"botgetdifficulty", 0x8369}, // SP 0x000000000 MP 0x140477E90 - {"botgetworldclosestedge", 0x836A}, // SP 0x000000000 MP 0x140478770 - {"_meth_836B", 0x836B}, // SP 0x000000000 MP 0x140478990 - {"botpredictseepoint", 0x836C}, // SP 0x000000000 MP 0x140479420 - {"botcanseeentity", 0x836D}, // SP 0x000000000 MP 0x140477A90 - {"botgetnodesonpath", 0x836E}, // SP 0x000000000 MP 0x140478230 - {"_meth_836F", 0x836F}, // SP 0x000000000 MP 0x140479020 - {"_meth_8371", 0x8371}, // SP 0x000000000 MP 0x140477FD0 - {"botsetawareness", 0x8372}, // SP 0x000000000 MP 0x140479720 - {"_meth_8373", 0x8373}, // SP 0x000000000 MP 0x140479610 - {"botgetscriptgoalnode", 0x8374}, // SP 0x000000000 MP 0x140478560 - {"botgetimperfectenemyinfo", 0x8375}, // SP 0x000000000 MP 0x1404780D0 - {"botsetpathingstyle", 0x8377}, // SP 0x000000000 MP 0x1404799A0 - {"botsetdifficultysetting", 0x8378}, // SP 0x000000000 MP 0x140479840 - {"botgetdifficultysetting", 0x8379}, // SP 0x000000000 MP 0x140477F20 - {"botgetpathdist", 0x837A}, // SP 0x000000000 MP 0x1404782F0 - {"_meth_837B", 0x837B}, // SP 0x000000000 MP 0x140478910 - {"_meth_837C", 0x837C}, // SP 0x000000000 MP 0x140479510 - {"botclearbutton", 0x837D}, // SP 0x000000000 MP 0x140477B70 - {"_meth_837E", 0x837E}, // SP 0x000000000 MP 0x1404791D0 - {"getnodenumber", 0x837F}, // SP 0x000000000 MP 0x14032E760 - {"setclientowner", 0x8380}, // SP 0x000000000 MP 0x14037AD60 - {"_meth_8381", 0x8381}, // SP 0x000000000 MP 0x14037A3B0 - {"setaisightlinevisible", 0x8382}, // SP 0x1402A15D0 MP 0x140358460 - {"setentityowner", 0x8383}, // SP 0x000000000 MP 0x14037A980 - {"nodeisdisconnected", 0x8384}, // SP 0x000000000 MP 0x14032E920 - {"_meth_8385", 0x8385}, // SP 0x140262C60 MP 0x14032E340 - {"_meth_8386", 0x8386}, // SP 0x000000000 MP 0x14037B1B0 - {"_meth_8388", 0x8388}, // SP 0x000000000 MP 0x14044EF90 - {"_meth_8389", 0x8389}, // SP 0x000000000 MP 0x14044E610 - {"setagentattacker", 0x838A}, // SP 0x000000000 MP 0x14044EE40 - {"_meth_838B", 0x838B}, // SP 0x000000000 MP 0x14044E0E0 - {"agentcanseesentient", 0x838C}, // SP 0x000000000 MP 0x14044DF00 - {"setwaypoint", 0x838D}, // SP 0x000000000 MP 0x140450B20 - {"setgoalpos", 0x838E}, // SP 0x000000000 MP 0x140450120 - {"getgoalpos", 0x838F}, // SP 0x000000000 MP 0x14044F670 - {"setgoalnode", 0x8390}, // SP 0x000000000 MP 0x140450090 - {"setgoalentity", 0x8391}, // SP 0x000000000 MP 0x140450000 - {"setgoalradius", 0x8392}, // SP 0x000000000 MP 0x140450260 - {"_meth_8393", 0x8393}, // SP 0x000000000 MP 0x14044FEC0 - {"setorientmode", 0x8394}, // SP 0x000000000 MP 0x140450540 - {"setanimmode", 0x8395}, // SP 0x000000000 MP 0x14044FDA0 - {"setphysicsmode", 0x8396}, // SP 0x000000000 MP 0x140450780 - {"setclipmode", 0x8397}, // SP 0x000000000 MP 0x14044FF60 - {"setmaxturnspeed", 0x8398}, // SP 0x000000000 MP 0x140450370 - {"getmaxturnspeed", 0x8399}, // SP 0x000000000 MP 0x14044F7A0 - {"beginmelee", 0x839A}, // SP 0x000000000 MP 0x14044F2A0 - {"getmlgspectatorteam", 0x839B}, // SP 0x000000000 MP 0x140450840 - {"dotrajectory", 0x839C}, // SP 0x000000000 MP 0x14044F5D0 - {"doanimlerp", 0x839D}, // SP 0x000000000 MP 0x14044F480 - {"setviewheight", 0x839E}, // SP 0x000000000 MP 0x140450AA0 - {"claimnode", 0x839F}, // SP 0x000000000 MP 0x14044F370 - {"relinquishclaimednode", 0x83A0}, // SP 0x000000000 MP 0x14044FC90 - {"_meth_83A1", 0x83A1}, // SP 0x14026DD90 MP 0x14033BCE0 - {"_meth_83A2", 0x83A2}, // SP 0x14026DE40 MP 0x14033BD90 - {"_meth_83A3", 0x83A3}, // SP 0x14026DEB0 MP 0x14033BDF0 - {"_meth_83A4", 0x83A4}, // SP 0x14026DF20 MP 0x14033BE50 - {"_meth_83A5", 0x83A5}, // SP 0x1402A84A0 MP 0x000000000 - {"_meth_83A6", 0x83A6}, // SP 0x140260B80 MP 0x14032CDC0 - {"_meth_83A7", 0x83A7}, // SP 0x140260DE0 MP 0x14032CEA0 - {"_meth_83A8", 0x83A8}, // SP 0x140268480 MP 0x000000000 - {"_meth_83A9", 0x83A9}, // SP 0x1402A8750 MP 0x000000000 - {"_meth_83AA", 0x83AA}, // SP 0x1402A8860 MP 0x000000000 - {"_meth_83AB", 0x83AB}, // SP 0x140268330 MP 0x000000000 - {"_meth_83AC", 0x83AC}, // SP 0x140268410 MP 0x000000000 - {"_meth_83AD", 0x83AD}, // SP 0x1402683A0 MP 0x000000000 - {"_meth_83B0", 0x83B0}, // SP 0x1405D92F0 MP 0x14032CC20 - {"_meth_83B1", 0x83B1}, // SP 0x1402670A0 MP 0x14032B5D0 - {"_meth_83B2", 0x83B2}, // SP 0x140267250 MP 0x14032B7B0 - {"_meth_83B3", 0x83B3}, // SP 0x1404651B0 MP 0x14055F010 - {"_meth_83B4", 0x83B4}, // SP 0x1404651C0 MP 0x14055F020 - {"_meth_83B5", 0x83B5}, // SP 0x000000000 MP 0x14037BCD0 - {"_meth_83B6", 0x83B6}, // SP 0x14029C100 MP 0x140367570 - {"_meth_83B7", 0x83B7}, // SP 0x140299860 MP 0x140364840 - {"_meth_83B8", 0x83B8}, // SP 0x14028E830 MP 0x140364960 - {"_meth_83B9", 0x83B9}, // SP 0x140261C60 MP 0x14032D930 - {"_meth_83BA", 0x83BA}, // SP 0x140462CB0 MP 0x1405614F0 - {"_meth_83BB", 0x83BB}, // SP 0x140462D60 MP 0x1405615A0 - {"_meth_83BC", 0x83BC}, // SP 0x140462DE0 MP 0x140561620 - {"_meth_83BD", 0x83BD}, // SP 0x14028AB00 MP 0x000000000 - {"_meth_83BE", 0x83BE}, // SP 0x140263B80 MP 0x140330060 - {"_meth_83BF", 0x83BF}, // SP 0x140263C60 MP 0x140330200 - {"_meth_83C0", 0x83C0}, // SP 0x140263F70 MP 0x140330470 - {"_meth_83C1", 0x83C1}, // SP 0x1402B3B00 MP 0x14037F840 - {"_meth_83C2", 0x83C2}, // SP 0x1402D7D50 MP 0x1400778A0 - {"_meth_83C3", 0x83C3}, // SP 0x1404623A0 MP 0x140560AC0 - {"_meth_83C4", 0x83C4}, // SP 0x1405D92F0 MP 0x14032D370 - {"_meth_83C5", 0x83C5}, // SP 0x14028AA90 MP 0x000000000 - {"_meth_83C6", 0x83C6}, // SP 0x14024AEF0 MP 0x000000000 - {"_meth_83C7", 0x83C7}, // SP 0x14024B000 MP 0x000000000 - {"_meth_83C8", 0x83C8}, // SP 0x14024B340 MP 0x000000000 - {"_meth_83C9", 0x83C9}, // SP 0x14024B420 MP 0x000000000 - {"_meth_83CA", 0x83CA}, // SP 0x14024B6D0 MP 0x000000000 - {"_meth_83CB", 0x83CB}, // SP 0x14024B660 MP 0x000000000 - {"_meth_83CC", 0x83CC}, // SP 0x14024B740 MP 0x000000000 - {"_meth_83CD", 0x83CD}, // SP 0x14024B7A0 MP 0x000000000 - {"setanimclass", 0x83CE}, // SP 0x000000000 MP 0x1400781E0 - {"enableanimstate", 0x83CF}, // SP 0x000000000 MP 0x140077CB0 - {"_meth_83D0", 0x83D0}, // SP 0x000000000 MP 0x140078250 - {"getanimentry", 0x83D1}, // SP 0x000000000 MP 0x140077DF0 - {"getanimentryname", 0x83D2}, // SP 0x000000000 MP 0x140077FA0 - {"getanimentryalias", 0x83D3}, // SP 0x000000000 MP 0x140077E80 - {"getanimentrycount", 0x83D4}, // SP 0x000000000 MP 0x140077EE0 - {"_meth_83D5", 0x83D5}, // SP 0x1402AE190 MP 0x000000000 - {"issprinting", 0x83D6}, // SP 0x1402613C0 MP 0x14032CB20 - {"_meth_83D7", 0x83D7}, // SP 0x140291320 MP 0x000000000 - {"_meth_83D8", 0x83D8}, // SP 0x1402495B0 MP 0x000000000 - {"_meth_83D9", 0x83D9}, // SP 0x1405D92F0 MP 0x140358020 - {"_meth_83DA", 0x83DA}, // SP 0x140264C80 MP 0x000000000 - {"_meth_83DB", 0x83DB}, // SP 0x140264C80 MP 0x000000000 - {"_meth_83DC", 0x83DC}, // SP 0x140261B80 MP 0x14032D800 - {"rotateto", 0x83DD}, // SP 0x1402B3200 MP 0x14037EF90 - {"getlookaheaddir", 0x83DE}, // SP 0x000000000 MP 0x14044F710 - {"getpathgoalpos", 0x83DF}, // SP 0x000000000 MP 0x14044FAD0 - {"_meth_83E0", 0x83E0}, // SP 0x1402A15D0 MP 0x14036E1F0 - {"setcorpsefalling", 0x83E1}, // SP 0x000000000 MP 0x140374840 - {"setsurfacetype", 0x83E2}, // SP 0x14029FD00 MP 0x140358090 - {"_meth_83E3", 0x83E3}, // SP 0x1402A0C60 MP 0x140369520 - {"_meth_83E4", 0x83E4}, // SP 0x1402A20D0 MP 0x140369FE0 - {"_meth_83E5", 0x83E5}, // SP 0x1405D92F0 MP 0x14033B020 - {"_meth_83E6", 0x83E6}, // SP 0x1402A7B00 MP 0x000000000 - {"_meth_83E7", 0x83E7}, // SP 0x1402A7C90 MP 0x000000000 - {"visionsetstage", 0x83E8}, // SP 0x140263140 MP 0x14032F7A0 - {"hudoutlineenableforclients", 0x83E9}, // SP 0x14026D2E0 MP 0x14033B450 - {"getlinkedparent", 0x83EA}, // SP 0x14028DB50 MP 0x140359B60 - {"getmovingplatformparent", 0x83EB}, // SP 0x14028E2A0 MP 0x14035A4D0 - {"_meth_83EC", 0x83EC}, // SP 0x000000000 MP 0x14032CEF0 - {"_meth_83ED", 0x83ED}, // SP 0x1402ADF90 MP 0x000000000 - {"_meth_83EF", 0x83EF}, // SP 0x1402A0B60 MP 0x14036A5C0 - {"_meth_83F0", 0x83F0}, // SP 0x14029F670 MP 0x140369790 - {"makevehiclenotcollidewithplayers", 0x83F1}, // SP 0x1402913E0 MP 0x14035B490 - {"_meth_83F2", 0x83F2}, // SP 0x140269130 MP 0x000000000 - {"_meth_83F3", 0x83F3}, // SP 0x140269190 MP 0x000000000 - {"setscriptablepartstate", 0x83F4}, // SP 0x1402A0760 MP 0x1403589E0 - {"_meth_83F5", 0x83F5}, // SP 0x1405D92F0 MP 0x140359100 - {"_meth_83F6", 0x83F6}, // SP 0x1402A15D0 MP 0x14036E200 - {"_meth_83F7", 0x83F7}, // SP 0x140465020 MP 0x140560DF0 - {"_meth_83F8", 0x83F8}, // SP 0x1405D92F0 MP 0x1403636B0 - {"_meth_83F9", 0x83F9}, // SP 0x1405D92F0 MP 0x140363830 - {"motionblurhqdisable", 0x83FA}, // SP 0x14029BA30 MP 0x140363EA0 - {"_meth_83FB", 0x83FB}, // SP 0x14029BC20 MP 0x1403640D0 - {"_meth_83FC", 0x83FC}, // SP 0x1402AA870 MP 0x000000000 - {"_meth_83FD", 0x83FD}, // SP 0x14024AD20 MP 0x000000000 - {"worldpointtoscreenpos", 0x83FE}, // SP 0x140297A40 MP 0x140360C90 - {"_meth_83FF", 0x83FF}, // SP 0x1402974B0 MP 0x000000000 - {"_meth_8400", 0x8400}, // SP 0x1402498E0 MP 0x000000000 - {"_meth_8401", 0x8401}, // SP 0x000000000 MP 0x140477D90 - {"_meth_8402", 0x8402}, // SP 0x140263950 MP 0x000000000 - {"_meth_8403", 0x8403}, // SP 0x140268F10 MP 0x000000000 - {"_meth_8404", 0x8404}, // SP 0x1402977A0 MP 0x000000000 - {"_meth_8405", 0x8405}, // SP 0x1402978F0 MP 0x000000000 - {"_meth_8406", 0x8406}, // SP 0x14029A680 MP 0x000000000 - {"emissiveblend", 0x8407}, // SP 0x000000000 MP 0x140375810 - {"_meth_8408", 0x8408}, // SP 0x1402687F0 MP 0x000000000 - {"_meth_8409", 0x8409}, // SP 0x140268840 MP 0x000000000 - {"_meth_840A", 0x840A}, // SP 0x1402AF930 MP 0x000000000 - {"_meth_840B", 0x840B}, // SP 0x1402AE490 MP 0x000000000 - {"_meth_840C", 0x840C}, // SP 0x1402AE5D0 MP 0x000000000 - {"_meth_840D", 0x840D}, // SP 0x1402B4000 MP 0x14037FDE0 - {"_meth_840E", 0x840E}, // SP 0x1402B40B0 MP 0x14037FE90 - {"physicsgetlinspeed", 0x840F}, // SP 0x1402B4160 MP 0x14037FF40 - {"_meth_8410", 0x8410}, // SP 0x1402B41F0 MP 0x140380000 - {"physicsgetangvel", 0x8411}, // SP 0x1402B42B0 MP 0x1403800E0 - {"physicsgetangspeed", 0x8412}, // SP 0x1402B4340 MP 0x1403801A0 - {"disablemissileboosting", 0x8413}, // SP 0x000000000 MP 0x14035A430 - {"enablemissileboosting", 0x8414}, // SP 0x000000000 MP 0x14035A480 - {"canspawntestclient", 0x8415}, // SP 0x000000000 MP 0x140376790 - {"spawntestclient", 0x8416}, // SP 0x000000000 MP 0x1403767B0 - {"setgrenadethrowscale", 0x8417}, // SP 0x000000000 MP 0x14036F610 - {"ismantling", 0x8418}, // SP 0x000000000 MP 0x140357DB0 - {"_meth_8419", 0x8419}, // SP 0x000000000 MP 0x1403767E0 - {"_meth_841A", 0x841A}, // SP 0x1405D92F0 MP 0x1403630D0 - {"_meth_841B", 0x841B}, // SP 0x1405D92F0 MP 0x140363500 - {"_meth_841C", 0x841C}, // SP 0x1405D92F0 MP 0x140363590 - {"_meth_841D", 0x841D}, // SP 0x1405D92F0 MP 0x140363620 - {"turretsetbarrelspinenabled", 0x841E}, // SP 0x140299270 MP 0x140364190 - {"_meth_841F", 0x841F}, // SP 0x000000000 MP 0x1403326E0 - {"autospotoverlayoff", 0x8420}, // SP 0x000000000 MP 0x1403328E0 - {"_meth_8421", 0x8421}, // SP 0x14029FEB0 MP 0x140369B60 - {"_meth_8422", 0x8422}, // SP 0x1402A00C0 MP 0x140369E10 - {"doanimrelative", 0x8423}, // SP 0x000000000 MP 0x14044F520 - {"_meth_8424", 0x8424}, // SP 0x1402B30B0 MP 0x000000000 - {"_meth_8425", 0x8425}, // SP 0x1402B3280 MP 0x000000000 - {"_meth_8426", 0x8426}, // SP 0x1402B3320 MP 0x000000000 - {"getcorpseentity", 0x8427}, // SP 0x000000000 MP 0x1403748F0 - {"_meth_8428", 0x8428}, // SP 0x1402ABE20 MP 0x000000000 - {"_meth_8429", 0x8429}, // SP 0x000000000 MP 0x140379520 - {"_meth_842A", 0x842A}, // SP 0x000000000 MP 0x140379B70 - {"queuedialogforplayer", 0x842B}, // SP 0x000000000 MP 0x1403785F0 - {"setmlgcameradefaults", 0x842C}, // SP 0x000000000 MP 0x1403321B0 - {"_meth_842D", 0x842D}, // SP 0x000000000 MP 0x140334A60 - {"_meth_842E", 0x842E}, // SP 0x140262C10 MP 0x14032F2B0 - {"_meth_842F", 0x842F}, // SP 0x140262D40 MP 0x14032F480 - {"_meth_8430", 0x8430}, // SP 0x1405D92F0 MP 0x000000000 - {"getlinkedchildren", 0x8431}, // SP 0x14028E020 MP 0x14035A3A0 - {"_meth_8432", 0x8432}, // SP 0x000000000 MP 0x140479320 - {"playsoundonmovingent", 0x8433}, // SP 0x000000000 MP 0x140377F80 - {"cancelmantle", 0x8434}, // SP 0x140266DD0 MP 0x14032B210 - {"hasfemalecustomizationmodel", 0x8435}, // SP 0x000000000 MP 0x140332F50 - {"setscriptabledamageowner", 0x8437}, // SP 0x1402A0440 MP 0x1403586F0 - {"_meth_8438", 0x8438}, // SP 0x1402A0B00 MP 0x140358FF0 - {"_meth_8439", 0x8439}, // SP 0x000000000 MP 0x140379890 - {"_meth_843A", 0x843A}, // SP 0x14024B810 MP 0x000000000 - {"_meth_843B", 0x843B}, // SP 0x14024B8B0 MP 0x000000000 - {"_meth_843C", 0x843C}, // SP 0x140265900 MP 0x1403294C0 - {"_meth_843D", 0x843D}, // SP 0x14024BCE0 MP 0x000000000 - {"_meth_843E", 0x843E}, // SP 0x14029EC40 MP 0x140368630 - {"_meth_843F", 0x843F}, // SP 0x1405D92F0 MP 0x14032D4E0 - {"_meth_8440", 0x8440}, // SP 0x1404639C0 MP 0x140562210 - {"_meth_8441", 0x8441}, // SP 0x140462EA0 MP 0x1405616E0 - {"_meth_8442", 0x8442}, // SP 0x1402A36A0 MP 0x140358B60 - {"_meth_8443", 0x8443}, // SP 0x140266090 MP 0x14032A550 - {"_meth_8444", 0x8444}, // SP 0x1402A8A40 MP 0x000000000 - {"_meth_8445", 0x8445}, // SP 0x1402A8A80 MP 0x000000000 - {"_meth_8446", 0x8446}, // SP 0x1402A2F70 MP 0x14036CC00 - {"_meth_8447", 0x8447}, // SP 0x1405D92F0 MP 0x140363840 - {"_meth_8448", 0x8448}, // SP 0x1405D92F0 MP 0x140363A50 - {"_meth_8449", 0x8449}, // SP 0x1402611B0 MP 0x14032C860 - {"_meth_844A", 0x844A}, // SP 0x140295480 MP 0x1403602C0 - {"_meth_844B", 0x844B}, // SP 0x140295650 MP 0x1403604C0 - {"_meth_844C", 0x844C}, // SP 0x140463020 MP 0x140561860 - {"_meth_844D", 0x844D}, // SP 0x140463040 MP 0x140561880 - {"_meth_844E", 0x844E}, // SP 0x140463060 MP 0x1405618A0 - {"_meth_844F", 0x844F}, // SP 0x140463080 MP 0x1405618C0 - {"_meth_8450", 0x8450}, // SP 0x1402AC9E0 MP 0x000000000 - {"_meth_8451", 0x8451}, // SP 0x1402ACB20 MP 0x000000000 - {"_meth_8452", 0x8452}, // SP 0x140462F60 MP 0x1405617A0 - {"_meth_8453", 0x8453}, // SP 0x140261E30 MP 0x14032DC80 - {"_meth_8454", 0x8454}, // SP 0x1402612F0 MP 0x000000000 - {"_meth_8455", 0x8455}, // SP 0x1402AD1E0 MP 0x000000000 - {"getvieworigin", 0x8458}, // SP 0x14029DE70 MP 0x140366600 - {"_meth_8459", 0x8459}, // SP 0x140265E70 MP 0x140329A80 - {"_meth_845A", 0x845A}, // SP 0x000000000 MP 0x140359980 - {"stopridingvehicle", 0x845B}, // SP 0x000000000 MP 0x14035A040 - {"_meth_845C", 0x845C}, // SP 0x140264C80 MP 0x000000000 - {"_meth_845D", 0x845D}, // SP 0x14028E7C0 MP 0x14035A8D0 - {"disablemissilestick", 0x845E}, // SP 0x000000000 MP 0x1403762F0 - {"enablemissilestick", 0x845F}, // SP 0x000000000 MP 0x140376340 - {"setmissileminimapvisible", 0x8460}, // SP 0x000000000 MP 0x140347ED0 - {"isoffhandweaponreadytothrow", 0x8461}, // SP 0x1402675A0 MP 0x14032B560 - {"isleaning", 0x8462}, // SP 0x1402614A0 MP 0x14032CC30 - {"makecollidewithitemclip", 0x8463}, // SP 0x140291970 MP 0x14035B8F0 - {"_meth_8464", 0x8464}, // SP 0x140261DC0 MP 0x000000000 - {"visionsetpostapplyforplayer", 0x8465}, // SP 0x000000000 MP 0x14032FE10 - {"_meth_8466", 0x8466}, // SP 0x1402B47A0 MP 0x140380A60 - {"_meth_8467", 0x8467}, // SP 0x1402B4950 MP 0x140380C30 - {"_meth_8468", 0x8468}, // SP 0x1402A2E30 MP 0x000000000 - {"_meth_8469", 0x8469}, // SP 0x1402A3290 MP 0x000000000 - {"_meth_846A", 0x846A}, // SP 0x1402A3360 MP 0x000000000 - {"_meth_846B", 0x846B}, // SP 0x1402A36C0 MP 0x000000000 - {"_meth_846C", 0x846C}, // SP 0x14028DBB0 MP 0x000000000 - {"_meth_846D", 0x846D}, // SP 0x140260B20 MP 0x000000000 - {"_meth_846E", 0x846E}, // SP 0x1402A8530 MP 0x000000000 - {"_meth_846F", 0x846F}, // SP 0x140463100 MP 0x140561940 - {"_meth_8470", 0x8470}, // SP 0x140463140 MP 0x140561980 - {"_meth_8471", 0x8471}, // SP 0x1404631A0 MP 0x1405619E0 - {"_meth_8472", 0x8472}, // SP 0x1404631F0 MP 0x140561A30 - {"_meth_8473", 0x8473}, // SP 0x140463210 MP 0x140561A50 - {"_meth_8474", 0x8474}, // SP 0x140291B70 MP 0x14035E030 - {"_meth_8475", 0x8475}, // SP 0x140291E30 MP 0x14035E0D0 - {"_meth_8476", 0x8476}, // SP 0x140263970 MP 0x14032FE30 - {"_meth_8477", 0x8477}, // SP 0x1402A85E0 MP 0x000000000 - {"_meth_8478", 0x8478}, // SP 0x1402A86E0 MP 0x000000000 - {"_meth_8479", 0x8479}, // SP 0x1405D92F0 MP 0x14032C130 - {"_meth_847A", 0x847A}, // SP 0x1405D92F0 MP 0x14032C420 - {"_meth_847B", 0x847B}, // SP 0x140462450 MP 0x140560B70 - {"_meth_847C", 0x847C}, // SP 0x1404624D0 MP 0x140560BF0 - {"_meth_847D", 0x847D}, // SP 0x140262900 MP 0x14032E940 - {"_meth_847E", 0x847E}, // SP 0x1402629A0 MP 0x14032E9D0 - {"_meth_847F", 0x847F}, // SP 0x14029CB70 MP 0x140367C30 - {"_meth_8480", 0x8480}, // SP 0x140291DA0 MP 0x000000000 - {"_meth_8481", 0x8481}, // SP 0x1405D92F0 MP 0x14032CD40 - {"_meth_8482", 0x8482}, // SP 0x1405D92F0 MP 0x14032CD30 - {"_meth_8483", 0x8483}, // SP 0x000000000 MP 0x14044E5B0 - {"_meth_8484", 0x8484}, // SP 0x140464FB0 MP 0x140563710 - {"_meth_8485", 0x8485}, // SP 0x1404630B0 MP 0x1405618F0 - {"_meth_8486", 0x8486}, // SP 0x000000000 MP 0x14044DF90 - {"_meth_8487", 0x8487}, // SP 0x000000000 MP 0x140380630 - {"_meth_8488", 0x8488}, // SP 0x1402B3150 MP 0x000000000 - {"_meth_8489", 0x8489}, // SP 0x1405D92F0 MP 0x14032CD20 - {"_meth_848A", 0x848A}, // SP 0x140465030 MP 0x140563790 - {"_meth_848B", 0x848B}, // SP 0x140465020 MP 0x140563720 - {"_meth_848C", 0x848C}, // SP 0x1402641A0 MP 0x140330610 - {"_meth_848D", 0x848D}, // SP 0x140264320 MP 0x140330840 - {"_meth_848E", 0x848E}, // SP 0x140264550 MP 0x140330970 - {"_meth_848F", 0x848F}, // SP 0x1402694A0 MP 0x000000000 - {"_meth_8490", 0x8490}, // SP 0x1405D92F0 MP 0x14035E610 - {"_meth_8491", 0x8491}, // SP 0x000000000 MP 0x14037A4A0 - {"_meth_8492", 0x8492}, // SP 0x000000000 MP 0x14037A510 - {"_meth_8493", 0x8493}, // SP 0x1402ACF90 MP 0x000000000 - {"_meth_8494", 0x8494}, // SP 0x1402AD070 MP 0x000000000 - {"_meth_8495", 0x8495}, // SP 0x140268C60 MP 0x000000000 - {"_meth_8496", 0x8496}, // SP 0x000000000 MP 0x140375380 - {"_meth_8497", 0x8497}, // SP 0x000000000 MP 0x140376030 - {"_meth_8498", 0x8498}, // SP 0x140266500 MP 0x14032AB70 - {"_meth_8499", 0x8499}, // SP 0x140266B20 MP 0x14032AF60 - {"_meth_849A", 0x849A}, // SP 0x1405D92F0 MP 0x14032CCB0 - {"_meth_849B", 0x849B}, // SP 0x000000000 MP 0x140375470 - {"_meth_849C", 0x849C}, // SP 0x000000000 MP 0x140375490 - {"_meth_849D", 0x849D}, // SP 0x000000000 MP 0x140375640 - {"_meth_849E", 0x849E}, // SP 0x000000000 MP 0x140375650 - {"_meth_849F", 0x849F}, // SP 0x000000000 MP 0x140375660 - {"_meth_84A0", 0x84A0}, // SP 0x000000000 MP 0x140375680 - {"_meth_84A1", 0x84A1}, // SP 0x000000000 MP 0x140375670 - {"_meth_84A2", 0x84A2}, // SP 0x000000000 MP 0x1403756C0 - {"_meth_84A3", 0x84A3}, // SP 0x000000000 MP 0x1403757F0 - {"_meth_84A4", 0x84A4}, // SP 0x000000000 MP 0x1403756B0 - {"_meth_84A5", 0x84A5}, // SP 0x14029FDA0 MP 0x140369CB0 - {"_meth_84A6", 0x84A6}, // SP 0x1402A02F0 MP 0x14036A120 - {"_meth_84A7", 0x84A7}, // SP 0x1402A04A0 MP 0x14036A190 - {"_meth_84A8", 0x84A8}, // SP 0x1402A0FE0 MP 0x14036A960 - {"_meth_84A9", 0x84A9}, // SP 0x140465C50 MP 0x14055FBF0 - {"_meth_84AA", 0x84AA}, // SP 0x1402979E0 MP 0x1403625A0 - {"_meth_84AB", 0x84AB}, // SP 0x140297E40 MP 0x140362BD0 - {"_meth_84AC", 0x84AC}, // SP 0x140261E70 MP 0x14032DAE0 - {"_meth_84AD", 0x84AD}, // SP 0x1404663D0 MP 0x1405602E0 - {"_meth_84AE", 0x84AE}, // SP 0x1404664D0 MP 0x1405603E0 - {"_meth_84AF", 0x84AF}, // SP 0x000000000 MP 0x140333050 - {"_meth_84B0", 0x84B0}, // SP 0x1405D92F0 MP 0x140369850 - {"_meth_84B1", 0x84B1}, // SP 0x1402922D0 MP 0x14035E650 - {"_meth_84B2", 0x84B2}, // SP 0x1402925B0 MP 0x14035E660 - {"_meth_84B3", 0x84B3}, // SP 0x140292CD0 MP 0x14035E700 - {"_meth_84B4", 0x84B4}, // SP 0x140292FC0 MP 0x14035E720 - {"_meth_84B5", 0x84B5}, // SP 0x1405D92F0 MP 0x140364AA0 - {"_meth_84B6", 0x84B6}, // SP 0x1405D92F0 MP 0x14036BC80 - {"_meth_84B7", 0x84B7}, // SP 0x1404655C0 MP 0x14055F460 - {"_meth_84B8", 0x84B8}, // SP 0x1402A09C0 MP 0x14036A6A0 - {"_meth_84B9", 0x84B9}, // SP 0x000000000 MP 0x1403807B0 - {"_meth_84BB", 0x84BB}, // SP 0x1402643F0 MP 0x140330910 - {"_meth_84BC", 0x84BC}, // SP 0x140264500 MP 0x140330A20 - {"_meth_84BD", 0x84BD}, // SP 0x000000000 MP 0x1403330D0 - {"_meth_84BE", 0x84BE}, // SP 0x000000000 MP 0x1403335E0 - {"_meth_84BF", 0x84BF}, // SP 0x140265260 MP 0x1403311D0 - {"_meth_84C0", 0x84C0}, // SP 0x140265710 MP 0x1403291C0 - {"_meth_84C1", 0x84C1}, // SP 0x000000000 MP 0x1403766D0 - {"_meth_84C2", 0x84C2}, // SP 0x14029E430 MP 0x14036AA10 - {"_meth_84C3", 0x84C3}, // SP 0x140463250 MP 0x140561A90 - {"_meth_84C4", 0x84C4}, // SP 0x000000000 MP 0x140450E40 - {"_meth_84C5", 0x84C5}, // SP 0x000000000 MP 0x140450B10 - {"_meth_84C6", 0x84C6}, // SP 0x140260790 MP 0x14032BD80 - {"_meth_84C7", 0x84C7}, // SP 0x140260590 MP 0x000000000 - {"_meth_84C8", 0x84C8}, // SP 0x1402606E0 MP 0x000000000 - {"_meth_84C9", 0x84C9}, // SP 0x140464D30 MP 0x1405634E0 - {"_meth_84CA", 0x84CA}, // SP 0x140464DC0 MP 0x140563580 - {"_meth_84CB", 0x84CB}, // SP 0x000000000 MP 0x140334CC0 - {"_meth_84CC", 0x84CC}, // SP 0x140463270 MP 0x140561AB0 - {"_meth_84CD", 0x84CD}, // SP 0x1402A1470 MP 0x14036A8C0 - {"_meth_84CE", 0x84CE}, // SP 0x1402A15E0 MP 0x14036AD30 - {"_meth_84CF", 0x84CF}, // SP 0x14029ED60 MP 0x1403685E0 - {"_meth_84D0", 0x84D0}, // SP 0x14029EED0 MP 0x1403687A0 - {"_meth_84D1", 0x84D1}, // SP 0x14029F130 MP 0x1403687F0 - {"_meth_84D2", 0x84D2}, // SP 0x14029F300 MP 0x140368AC0 - {"_meth_84D3", 0x84D3}, // SP 0x14029F350 MP 0x140368CE0 - {"_meth_84D4", 0x84D4}, // SP 0x14029F410 MP 0x140368D50 - {"_meth_84D5", 0x84D5}, // SP 0x14029F530 MP 0x140368DF0 - {"_meth_84D6", 0x84D6}, // SP 0x14029F5E0 MP 0x140368ED0 - {"_meth_84D8", 0x84D8}, // SP 0x1402674E0 MP 0x14032B4A0 - {"_meth_84D9", 0x84D9}, // SP 0x1402B4400 MP 0x140380280 - {"_meth_84DA", 0x84DA}, // SP 0x000000000 MP 0x14035B2A0 - {"_meth_84DB", 0x84DB}, // SP 0x140248770 MP 0x000000000 - {"_meth_84DC", 0x84DC}, // SP 0x140461FF0 MP 0x000000000 - {"_meth_84DF", 0x84DF}, // SP 0x14028DF20 MP 0x14035B180 - {"_meth_84E0", 0x84E0}, // SP 0x14026E2F0 MP 0x14033C220 - {"_meth_84E1", 0x84E1}, // SP 0x1404632B0 MP 0x140561AF0 - {"_meth_84E2", 0x84E2}, // SP 0x000000000 MP 0x14036F110 - {"_meth_84E3", 0x84E3}, // SP 0x140264A30 MP 0x140331120 - {"_meth_84E4", 0x84E4}, // SP 0x1405D92F0 MP 0x1403604A0 - {"_meth_84E5", 0x84E5}, // SP 0x1402A88B0 MP 0x000000000 - {"_meth_84E6", 0x84E6}, // SP 0x1405D92F0 MP 0x14036C920 - {"_meth_84E8", 0x84E8}, // SP 0x140264970 MP 0x140330E00 - {"_meth_84E9", 0x84E9}, // SP 0x1402649D0 MP 0x140330E10 - {"_meth_84EA", 0x84EA}, // SP 0x14028ABB0 MP 0x000000000 - {"_meth_84EB", 0x84EB}, // SP 0x14029AF70 MP 0x140364720 - {"_meth_84EC", 0x84EC}, // SP 0x1402A11C0 MP 0x140359610 - {"_meth_84ED", 0x84ED}, // SP 0x140293540 MP 0x140360150 - {"_meth_84EE", 0x84EE}, // SP 0x140298540 MP 0x140361720 - {"_meth_84EF", 0x84EF}, // SP 0x14029B960 MP 0x140363B90 - {"_meth_84F0", 0x84F0}, // SP 0x1404643D0 MP 0x140562AB0 - {"_meth_84F1", 0x84F1}, // SP 0x1404644E0 MP 0x140562BE0 - {"_meth_84F2", 0x84F2}, // SP 0x1405D92F0 MP 0x14035B8C0 - {"_meth_84F3", 0x84F3}, // SP 0x1405D92F0 MP 0x14035B990 - {"_meth_84F4", 0x84F4}, // SP 0x14028E1A0 MP 0x14035B280 - {"_meth_84F5", 0x84F5}, // SP 0x14028E1A0 MP 0x14035B360 - {"_meth_84F6", 0x84F6}, // SP 0x1405D92F0 MP 0x14035B390 - {"_meth_84F7", 0x84F7}, // SP 0x14028E830 MP 0x14035B3A0 - {"_meth_84F8", 0x84F8}, // SP 0x14028E830 MP 0x14035B430 - {"_meth_84F9", 0x84F9}, // SP 0x14028E830 MP 0x14035B540 - {"_meth_84FA", 0x84FA}, // SP 0x1405D92F0 MP 0x14035B7A0 - {"_meth_84FB", 0x84FB}, // SP 0x14029EDE0 MP 0x14036EA10 - {"_meth_84FC", 0x84FC}, // SP 0x140290D70 MP 0x14035A740 - {"_meth_84FD", 0x84FD}, // SP 0x000000000 MP 0x140334AC0 - {"_meth_84FE", 0x84FE}, // SP 0x000000000 MP 0x140376800 - {"_meth_84FF", 0x84FF}, // SP 0x000000000 MP 0x1403768C0 - {"_meth_8500", 0x8500}, // SP 0x14028F5A0 MP 0x14035A550 - {"_meth_8501", 0x8501}, // SP 0x14028E4D0 MP 0x140359550 - {"_meth_8502", 0x8502}, // SP 0x000000000 MP 0x1403767F0 - {"_meth_8503", 0x8503}, // SP 0x14028F6E0 MP 0x14035C670 - {"_meth_8504", 0x8504}, // SP 0x000000000 MP 0x14037A470 - {"_meth_8505", 0x8505}, // SP 0x000000000 MP 0x140374F20 - {"_meth_8506", 0x8506}, // SP 0x000000000 MP 0x14037ADD0 - {"_meth_8507", 0x8507}, // SP 0x000000000 MP 0x14037AAF0 - {"_meth_8508", 0x8508}, // SP 0x000000000 MP 0x140332BC0 - {"_meth_8509", 0x8509}, // SP 0x1402AC990 MP 0x000000000 - {"_meth_850A", 0x850A}, // SP 0x1402646B0 MP 0x140330A80 - {"_meth_850B", 0x850B}, // SP 0x14026DCB0 MP 0x14033BC10 - {"_meth_850C", 0x850C}, // SP 0x000000000 MP 0x140376020 - {"_meth_850D", 0x850D}, // SP 0x14029E8F0 MP 0x1403682B0 - {"_meth_850E", 0x850E}, // SP 0x14029ED00 MP 0x140368570 - {"_meth_850F", 0x850F}, // SP 0x14029A7B0 MP 0x140362600 - {"_meth_8510", 0x8510}, // SP 0x140267840 MP 0x14032BE50 - {"_meth_8511", 0x8511}, // SP 0x140290ED0 MP 0x14035A8E0 - {"_meth_8512", 0x8512}, // SP 0x1404632E0 MP 0x140561B20 - {"_meth_8513", 0x8513}, // SP 0x140463300 MP 0x140561B40 - {"_meth_8514", 0x8514}, // SP 0x14028E830 MP 0x14032B9B0 - {"_meth_8515", 0x8515}, // SP 0x14028E830 MP 0x14032B9D0 - {"_meth_8516", 0x8516}, // SP 0x140299C10 MP 0x140361690 - {"_meth_8517", 0x8517}, // SP 0x000000000 MP 0x1403747A0 - {"_meth_8518", 0x8518}, // SP 0x14026D400 MP 0x14033B580 - {"_meth_8519", 0x8519}, // SP 0x000000000 MP 0x140376990 - {"_meth_851A", 0x851A}, // SP 0x140261370 MP 0x14032C9D0 - {"_meth_851B", 0x851B}, // SP 0x14029F3C0 MP 0x14036EEC0 - {"_meth_851C", 0x851C}, // SP 0x14028E830 MP 0x14036E3D0 - {"_meth_851D", 0x851D}, // SP 0x1402B4480 MP 0x140380300 - {"_meth_851E", 0x851E}, // SP 0x14028A8B0 MP 0x000000000 - {"_meth_851F", 0x851F}, // SP 0x000000000 MP 0x140333EE0 - {"_meth_8520", 0x8520}, // SP 0x000000000 MP 0x14044EEC0 - {"_meth_8521", 0x8521}, // SP 0x140263930 MP 0x000000000 - {"_meth_8522", 0x8522}, // SP 0x000000000 MP 0x140332340 - {"_meth_8523", 0x8523}, // SP 0x1405D92F0 MP 0x140358DC0 - {"_meth_8524", 0x8524}, // SP 0x14028DDD0 MP 0x140359FE0 - {"_meth_8525", 0x8525}, // SP 0x000000000 MP 0x140374C50 - {"_meth_8526", 0x8526}, // SP 0x000000000 MP 0x140374CF0 - {"_meth_8527", 0x8527}, // SP 0x14026DD20 MP 0x14033BC70 - {"_meth_8528", 0x8528}, // SP 0x000000000 MP 0x140332E80 - {"_meth_8529", 0x8529}, // SP 0x14028F7C0 MP 0x14035C9C0 - {"_meth_852A", 0x852A}, // SP 0x140297EF0 MP 0x14035F080 - {"_meth_852B", 0x852B}, // SP 0x000000000 MP 0x140332AD0 - {"_meth_852C", 0x852C}, // SP 0x000000000 MP 0x140331F50 - {"_meth_852D", 0x852D}, // SP 0x14028E830 MP 0x14035B7E0 - {"_meth_852E", 0x852E}, // SP 0x000000000 MP 0x140376A60 - {"_meth_852F", 0x852F}, // SP 0x000000000 MP 0x1404508B0 - {"_meth_8530", 0x8530}, // SP 0x000000000 MP 0x14044F1E0 - {"_meth_8531", 0x8531}, // SP 0x000000000 MP 0x1404503F0 - {"_meth_8532", 0x8532}, // SP 0x000000000 MP 0x140333250 - {"_meth_8533", 0x8533}, // SP 0x000000000 MP 0x14044EC20 - {"_meth_8534", 0x8534}, // SP 0x000000000 MP 0x140450670 - {"_meth_8535", 0x8535}, // SP 0x000000000 MP 0x14044FD10 - {"_meth_8536", 0x8536}, // SP 0x000000000 MP 0x1404504B0 - {"_meth_8537", 0x8537}, // SP 0x000000000 MP 0x1404502E0 - {"_meth_8538", 0x8538}, // SP 0x000000000 MP 0x1404506F0 - {"_meth_8539", 0x8539}, // SP 0x000000000 MP 0x140333F40 - {"_meth_853A", 0x853A}, // SP 0x000000000 MP 0x14037F320 - {"_meth_853B", 0x853B}, // SP 0x000000000 MP 0x14044E080 - {"_meth_853C", 0x853C}, // SP 0x14028F0D0 MP 0x14035BF40 - {"_meth_853D", 0x853D}, // SP 0x14028E830 MP 0x14032CCA0 - {"_meth_853E", 0x853E}, // SP 0x000000000 MP 0x140376AC0 - {"_meth_853F", 0x853F}, // SP 0x000000000 MP 0x14044DFF0 - {"_meth_8540", 0x8540}, // SP 0x140299D70 MP 0x140363160 - {"_meth_8541", 0x8541}, // SP 0x14028F260 MP 0x14035C380 - {"_meth_8542", 0x8542}, // SP 0x000000000 MP 0x140376C00 - {"_meth_8543", 0x8543}, // SP 0x000000000 MP 0x140375800 - {"_meth_8544", 0x8544}, // SP 0x000000000 MP 0x14044FA10 - {"_meth_8545", 0x8545}, // SP 0x000000000 MP 0x140333640 - {"_meth_8547", 0x8547}, // SP 0x000000000 MP 0x140450C20 - {"_meth_8548", 0x8548}, // SP 0x140262130 MP 0x14032DF00 - {"_meth_8549", 0x8549}, // SP 0x000000000 MP 0x140333FA0 - {"_meth_854A", 0x854A}, // SP 0x000000000 MP 0x140376C90 - {"_meth_854B", 0x854B}, // SP 0x000000000 MP 0x14044FBA0 - {"_meth_854C", 0x854C}, // SP 0x000000000 MP 0x1403331F0 - {"_meth_854D", 0x854D}, // SP 0x140290CE0 MP 0x14035C300 - {"_meth_854E", 0x854E}, // SP 0x000000000 MP 0x140450A10 - {"_meth_854F", 0x854F}, // SP 0x000000000 MP 0x14044FC10 - {"_meth_8550", 0x8550}, // SP 0x1402B4720 MP 0x1403809E0 - {"_meth_8551", 0x8551}, // SP 0x1402A15D0 MP 0x14035FB60 - {"_meth_8552", 0x8552}, // SP 0x000000000 MP 0x140450C30 - {"_meth_8553", 0x8553}, // SP 0x000000000 MP 0x140375E30 - {"_meth_8554", 0x8554}, // SP 0x000000000 MP 0x14044F3F0 - {"_meth_8555", 0x8555}, // SP 0x000000000 MP 0x140450D30 - {"_meth_8556", 0x8556}, // SP 0x000000000 MP 0x140374980 - {"_meth_8557", 0x8557}, // SP 0x000000000 MP 0x1403749D0 - {"_meth_8558", 0x8558}, // SP 0x000000000 MP 0x140078140 - {"_meth_8559", 0x8559}, // SP 0x1405D92F0 MP 0x14032D760 - {"_meth_855A", 0x855A}, // SP 0x1405D92F0 MP 0x14032D770 - {"_meth_855B", 0x855B}, // SP 0x1405D92F0 MP 0x14032D7F0 - {"_meth_855C", 0x855C}, // SP 0x000000000 MP 0x140376CB0 - {"_meth_855D", 0x855D}, // SP 0x1402A0220 MP 0x1403585F0 - {"_meth_855E", 0x855E}, // SP 0x140293780 MP 0x14035E8C0 - {"_meth_855F", 0x855F}, // SP 0x000000000 MP 0x140374EC0 - {"_meth_8560", 0x8560}, // SP 0x000000000 MP 0x140374F70 - {"_meth_8561", 0x8561}, // SP 0x140292D90 MP 0x14035FB10 - {"_meth_8562", 0x8562}, // SP 0x140293080 MP 0x14035FD80 - {"_meth_8563", 0x8563}, // SP 0x1402B2FB0 MP 0x14037EF00 - {"_meth_8564", 0x8564}, // SP 0x1402CBB60 MP 0x14031F610 - {"_meth_8565", 0x8565}, // SP 0x1402478E0 MP 0x000000000 - {"_meth_8566", 0x8566}, // SP 0x1402A8F10 MP 0x000000000 - {"_meth_8567", 0x8567}, // SP 0x140248F70 MP 0x000000000 - {"_meth_8568", 0x8568}, // SP 0x1402A3820 MP 0x14036E3F0 - {"_meth_8569", 0x8569}, // SP 0x1402982F0 MP 0x140363510 - {"_meth_856A", 0x856A}, // SP 0x1402984C0 MP 0x140363630 - {"_meth_856B", 0x856B}, // SP 0x140296FA0 MP 0x1403619C0 - {"_meth_856C", 0x856C}, // SP 0x140297420 MP 0x140361BA0 - {"_meth_856D", 0x856D}, // SP 0x140297640 MP 0x140361E60 - {"_meth_856E", 0x856E}, // SP 0x14028ABF0 MP 0x000000000 - {"_meth_856F", 0x856F}, // SP 0x14028AC10 MP 0x000000000 - {"_meth_8570", 0x8570}, // SP 0x14028AC60 MP 0x000000000 - {"_meth_8571", 0x8571}, // SP 0x140249010 MP 0x000000000 - {"_meth_8572", 0x8572}, // SP 0x14024AE00 MP 0x000000000 - {"_meth_8573", 0x8573}, // SP 0x140260B70 MP 0x14032C5C0 - {"_meth_8574", 0x8574}, // SP 0x140265AD0 MP 0x140329B40 - {"_meth_8575", 0x8575}, // SP 0x140265C90 MP 0x140329E40 - {"_meth_8576", 0x8576}, // SP 0x000000000 MP 0x140478050 - {"_meth_8577", 0x8577}, // SP 0x000000000 MP 0x140333650 - {"_meth_8578", 0x8578}, // SP 0x140297D90 MP 0x14035FFF0 - {"_meth_8579", 0x8579}, // SP 0x1402933D0 MP 0x14035FF90 - {"_meth_857A", 0x857A}, // SP 0x000000000 MP 0x1403336F0 - {"_meth_857B", 0x857B}, // SP 0x000000000 MP 0x14032B050 - {"_meth_857C", 0x857C}, // SP 0x1405D92F0 MP 0x14036D0E0 - {"_meth_857D", 0x857D}, // SP 0x000000000 MP 0x140334820 - {"_meth_857E", 0x857E}, // SP 0x000000000 MP 0x1403348E0 - {"_meth_857F", 0x857F}, // SP 0x000000000 MP 0x1403329F0 - }; - - std::unordered_map token_map = - { - {"pl#", 0x001}, - {"-", 0x002}, - {"radius`", 0x003}, - {"note:", 0x004}, - {"_", 0x005}, - {"_custom", 0x006}, - {"a", 0x007}, - {"ability", 0x008}, - {"accumulate", 0x009}, - {"accuracy", 0x00A}, - {"actionslot1", 0x00B}, - {"actionslot2", 0x00C}, - {"actionslot3", 0x00D}, - {"actionslot4", 0x00E}, - {"actionslot5", 0x00F}, - {"actionslot6", 0x010}, - {"actionslot7", 0x011}, - {"actionslot8", 0x012}, - {"activator", 0x013}, - {"active", 0x014}, - {"activecostume", 0x015}, - {"activeemblemslot", 0x016}, - {"activesquadmember", 0x017}, - {"activevisionset", 0x018}, - {"activevisionsetduration", 0x019}, - {"agent", 0x01A}, - {"agenthealth", 0x01B}, - {"agentname", 0x01C}, - {"agentteam", 0x01D}, - {"ai_event", 0x01E}, - {"ai_sight_line_cycle_group", 0x01F}, - {"ai_sight_line_group", 0x020}, - {"aim_highest_bone", 0x021}, - {"aim_vis_bone", 0x022}, - {"aiSpread", 0x023}, - {"aisquadmembers", 0x024}, - {"alert", 0x025}, - {"alertlevel", 0x026}, - {"alertlevelint", 0x027}, - {"alien", 0x028}, - {"alienplayerloadout", 0x029}, - {"alienplayerstats", 0x02A}, - {"aliensession", 0x02B}, - {"alignx", 0x02C}, - {"aligny", 0x02D}, - {"all", 0x02E}, - {"allies", 0x02F}, - {"allowcrouch", 0x030}, - {"allowdeath", 0x031}, - {"allowjump", 0x032}, - {"allowladders", 0x033}, - {"allowpain", 0x034}, - {"allowprone", 0x035}, - {"allstreaksrestricted", 0x036}, - {"alpha", 0x037}, - {"altmode", 0x038}, - {"always", 0x039}, - {"ambient", 0x03A}, - {"ambienttrack", 0x03B}, - {"ambienttrack_ac130", 0x03C}, - {"ambush", 0x03D}, - {"ambush_nodes_only", 0x03E}, - {"angle_deltas", 0x03F}, - {"anglelerprate", 0x040}, - {"angles", 0x041}, - {"anim_angle_delta", 0x042}, - {"anim_deltas", 0x043}, - {"anim_pose", 0x044}, - {"anim_will_finish", 0x045}, - {"animation", 0x046}, - {"animscript", 0x047}, - {"archived", 0x048}, - {"archivetime", 0x049}, - {"armor", 0x04A}, - {"asleep", 0x04B}, - {"aspectratio", 0x04C}, - {"assaultstreaks", 0x04D}, - {"assignedbucket", 0x04E}, - {"assists", 0x04F}, - {"attachment", 0x050}, - {"attachmentclassrestricted", 0x051}, - {"attachmentrestricted", 0x052}, - {"attachments", 0x053}, - {"attachtag", 0x054}, - {"attacker", 0x055}, - {"attackeraccuracy", 0x056}, - {"attackercount", 0x057}, - {"attackerisjuggernaut", 0x058}, - {"attackerpos", 0x059}, - {"author", 0x05A}, - {"auto_ai", 0x05B}, - {"auto_change", 0x05C}, - {"auto_nonai", 0x05D}, - {"avoidanceboundshalfsize", 0x05E}, - {"awards", 0x05F}, - {"axis", 0x060}, - {"b", 0x061}, - {"back", 0x062}, - {"back_left", 0x063}, - {"back_low", 0x064}, - {"back_mid", 0x065}, - {"back_right", 0x066}, - {"back_up", 0x067}, - {"background", 0x068}, - {"bad_guys", 0x069}, - {"bad_path", 0x06A}, - {"badplaceawareness", 0x06B}, - {"ball_off", 0x06C}, - {"ball_on", 0x06D}, - {"ball_pass", 0x06E}, - {"bandwidthdown", 0x06F}, - {"bandwidthtestcount", 0x070}, - {"bandwidthup", 0x071}, - {"baselineoverflow_max", 0x072}, - {"baselineoverflow_worst", 0x073}, - {"battery_discharge_begin", 0x074}, - {"battery_discharge_end", 0x075}, - {"begin", 0x076}, - {"begin_custom_anim", 0x077}, - {"begin_firing", 0x078}, - {"begin_firing_left", 0x079}, - {"bestweapon", 0x07A}, - {"bestweaponindex", 0x07B}, - {"bipods", 0x07C}, - {"birthtime", 0x07D}, - {"bl_rotor1", 0x07E}, - {"bl_rotor2", 0x07F}, - {"bl_rotor3", 0x080}, - {"blackops2prestige", 0x081}, - {"blackops2rank", 0x082}, - {"blade_hide", 0x083}, - {"blade_show", 0x084}, - {"blockfriendlies", 0x085}, - {"blurradius", 0x086}, - {"body", 0x087}, - {"body_animate_jnt", 0x088}, - {"bottomarc", 0x089}, - {"br_rotor1", 0x08A}, - {"br_rotor2", 0x08B}, - {"br_rotor3", 0x08C}, - {"breadcrumbheader", 0x08D}, - {"buff", 0x08E}, - {"bullet_hitshield", 0x08F}, - {"bullethit", 0x090}, - {"bulletwhizby", 0x091}, - {"c", 0x092}, - {"callingcardindex", 0x093}, - {"camo", 0x094}, - {"cancel_location", 0x095}, - {"canclimbladders", 0x096}, - {"canjumppath", 0x097}, - {"cardicon", 0x098}, - {"cardnameplate", 0x099}, - {"cardtitle", 0x09A}, - {"cgmchecksum", 0x09B}, - {"ch_prestige", 0x09C}, - {"ch_prestige_max", 0x09D}, - {"chainfallback", 0x09E}, - {"chainnode", 0x09F}, - {"challengeprogress", 0x0A0}, - {"challengestate", 0x0A1}, - {"chest", 0x0A2}, - {"churnscores", 0x0A3}, - {"chyron_message1", 0x0A4}, - {"chyron_message2", 0x0A5}, - {"chyron_message3", 0x0A6}, - {"civilian", 0x0A7}, - {"clanidhigh", 0x0A8}, - {"clanidlow", 0x0A9}, - {"classname", 0x0AA}, - {"clipdistance", 0x0AB}, - {"code_classname", 0x0AC}, - {"code_damageradius", 0x0AD}, - {"code_move", 0x0AE}, - {"code_move_slide", 0x0AF}, - {"codecallback_agentadded", 0x0B0}, - {"codecallback_agentdamaged", 0x0B1}, - {"codecallback_agentkilled", 0x0B2}, - {"codecallback_bullethitentity", 0x0B3}, - {"codecallback_codeendgame", 0x0B4}, - {"codecallback_entitydamage", 0x0B5}, - {"codecallback_entityoutofworld", 0x0B6}, - {"codecallback_handleinstantmessage", 0x0B7}, - {"codecallback_hostmigration", 0x0B8}, - {"codecallback_leaderdialog", 0x0B9}, - {"codecallback_partymembers", 0x0BA}, - {"codecallback_playerconnect", 0x0BB}, - {"codecallback_playerdamage", 0x0BC}, - {"codecallback_playerdisconnect", 0x0BD}, - {"codecallback_playergrenadesuicide", 0x0BE}, - {"codecallback_playerkilled", 0x0BF}, - {"codecallback_playerlaststand", 0x0C0}, - {"codecallback_playermigrated", 0x0C1}, - {"codecallback_startgametype", 0x0C2}, - {"codecallback_vehicledamage", 0x0C3}, - {"color", 0x0C4}, - {"color_blind_toggled", 0x0C5}, - {"combat", 0x0C6}, - {"combatmode", 0x0C7}, - {"combatrecord", 0x0C8}, - {"commonoption", 0x0C9}, - {"confirm_location", 0x0CA}, - {"connection_id", 0x0CB}, - {"connectionidchunkhigh", 0x0CC}, - {"connectionidchunklow", 0x0CD}, - {"consolegame", 0x0CE}, - {"consoleidchunkhigh", 0x0CF}, - {"consoleidchunklow", 0x0D0}, - {"constrained", 0x0D1}, - {"contact", 0x0D2}, - {"contextleanenabled", 0x0D3}, - {"convergencetime", 0x0D4}, - {"coopactivesquadmember", 0x0D5}, - {"coopsquadmembers", 0x0D6}, - {"costumes", 0x0D7}, - {"count", 0x0D8}, - {"cover", 0x0D9}, - {"cover_approach", 0x0DA}, - {"coversearchinterval", 0x0DB}, - {"createstruct", 0x0DC}, - {"createtime", 0x0DD}, - {"criticalbulletdamagedist", 0x0DE}, - {"crouch", 0x0DF}, - {"currency", 0x0E0}, - {"current", 0x0E1}, - {"currentanimtime", 0x0E2}, - {"currentgen", 0x0E3}, - {"currentwinstreak", 0x0E4}, - {"cursorhint", 0x0E5}, - {"custom_attach_00", 0x0E6}, - {"custom_attach_01", 0x0E7}, - {"custom_attach_02", 0x0E8}, - {"custom_attach_03", 0x0E9}, - {"custom_attach_04", 0x0EA}, - {"custom_attach_05", 0x0EB}, - {"custom_attach_06", 0x0EC}, - {"custom_attach_07", 0x0ED}, - {"custom_attach_08", 0x0EE}, - {"custom_attach_09", 0x0EF}, - {"custom_attach_10", 0x0F0}, - {"custom_attach_11", 0x0F1}, - {"custom_attach_12", 0x0F2}, - {"custom_attach_13", 0x0F3}, - {"custom_attach_14", 0x0F4}, - {"custom_attach_15", 0x0F5}, - {"customclasses", 0x0F6}, - {"customization_loaded", 0x0F7}, - {"d", 0x0F8}, - {"dailychallengeid", 0x0F9}, - {"damage", 0x0FA}, - {"damage_notdone", 0x0FB}, - {"damagedir", 0x0FC}, - {"damagelocation", 0x0FD}, - {"damagemod", 0x0FE}, - {"damagemultiplier", 0x0FF}, - {"damageshield", 0x100}, - {"damagetaken", 0x101}, - {"damageweapon", 0x102}, - {"damageyaw", 0x103}, - {"dangerreactduration", 0x104}, - {"datalength", 0x105}, - {"dcid", 0x106}, - {"dead", 0x107}, - {"death", 0x108}, - {"deathangles", 0x109}, - {"deathinvulnerabletime", 0x10A}, - {"deathplant", 0x10B}, - {"deathpos", 0x10C}, - {"deaths", 0x10D}, - {"deathshield", 0x10E}, - {"defaultclasses", 0x10F}, - {"defense", 0x110}, - {"defense_level", 0x111}, - {"delayeddeath", 0x112}, - {"deploy_riotshield", 0x113}, - {"desc", 0x114}, - {"descmodified", 0x115}, - {"desiredangle", 0x116}, - {"destructible_type", 0x117}, - {"detectable", 0x118}, - {"detected", 0x119}, - {"detonate", 0x11A}, - {"device_id_high", 0x11B}, - {"device_id_low", 0x11C}, - {"deviceconnectionhistory", 0x11D}, - {"deviceusefrequency", 0x11E}, - {"diequietly", 0x11F}, - {"diffusefraction", 0x120}, - {"direct", 0x121}, - {"disable", 0x122}, - {"disableplayeradsloscheck", 0x123}, - {"dlight", 0x124}, - {"dmg", 0x125}, - {"dodamagetoall", 0x126}, - {"dodangerreact", 0x127}, - {"doffar", 0x128}, - {"dofnear", 0x129}, - {"dofphysicalfocusdistance", 0x12A}, - {"dofphysicalfstop", 0x12B}, - {"dog", 0x12C}, - {"doghandler", 0x12D}, - {"doingambush", 0x12E}, - {"done", 0x12F}, - {"dontavoidplayer", 0x130}, - {"dotofdeath", 0x131}, - {"down", 0x132}, - {"downaimlimit", 0x133}, - {"drawoncompass", 0x134}, - {"dropweapon", 0x135}, - {"duration", 0x136}, - {"eftarc", 0x137}, - {"empty", 0x138}, - {"empty_offhand", 0x139}, - {"enable", 0x13A}, - {"enablehudlighting", 0x13B}, - {"enableshadows", 0x13C}, - {"end_firing", 0x13D}, - {"end_firing_left", 0x13E}, - {"end_script", 0x13F}, - {"enddeaths", 0x140}, - {"endkills", 0x141}, - {"enemy", 0x142}, - {"enemy_sighted", 0x143}, - {"enemy_sighted_lost", 0x144}, - {"enemy_visible", 0x145}, - {"enemyname", 0x146}, - {"enemyplatform", 0x147}, - {"enemyradarmode", 0x148}, - {"enemyxuidhigh", 0x149}, - {"enemyxuidlow", 0x14A}, - {"energy_fire", 0x14B}, - {"engagemaxdist", 0x14C}, - {"engagemaxfalloffdist", 0x14D}, - {"engagemindist", 0x14E}, - {"engageminfalloffdist", 0x14F}, - {"enhanceable", 0x150}, - {"entity", 0x151}, - {"entitydeleted", 0x152}, - {"entityoverflow_max", 0x153}, - {"entityoverflow_worst", 0x154}, - {"equipment", 0x155}, - {"equipmentsetups", 0x156}, - {"escaped", 0x157}, - {"exclusive", 0x158}, - {"exo_ability_activate", 0x159}, - {"exo_adrenaline_fire", 0x15A}, - {"exo_boost", 0x15B}, - {"exo_dodge", 0x15C}, - {"exo_power", 0x15D}, - {"exo_slide", 0x15E}, - {"exo_slide_hit_player", 0x15F}, - {"exoattachment1", 0x160}, - {"exoattachment2", 0x161}, - {"experience", 0x162}, - {"explode", 0x163}, - {"exposedduration", 0x164}, - {"extracustomclassesentitlement", 0x165}, - {"extracustomclassesprestige", 0x166}, - {"extrascore0", 0x167}, - {"extrascore1", 0x168}, - {"face_angle", 0x169}, - {"face_angle_3d", 0x16A}, - {"face_angle_abs", 0x16B}, - {"face_angle_rel", 0x16C}, - {"face_current", 0x16D}, - {"face_default", 0x16E}, - {"face_direction", 0x16F}, - {"face_enemy", 0x170}, - {"face_enemy_or_motion", 0x171}, - {"face_goal", 0x172}, - {"face_motion", 0x173}, - {"face_point", 0x174}, - {"facemotion", 0x175}, - {"failed", 0x176}, - {"falling", 0x177}, - {"fast_radar", 0x178}, - {"favoriteenemy", 0x179}, - {"finalaccuracy", 0x17A}, - {"first_person", 0x17B}, - {"firstplayedsptime", 0x17C}, - {"fixednode", 0x17D}, - {"fixednodesaferadius", 0x17E}, - {"fl_rotor1", 0x17F}, - {"fl_rotor2", 0x180}, - {"fl_rotor3", 0x181}, - {"flash", 0x182}, - {"flashbang", 0x183}, - {"foley", 0x184}, - {"follow", 0x185}, - {"followmax", 0x186}, - {"followmin", 0x187}, - {"font", 0x188}, - {"fontscale", 0x189}, - {"foot_ik_active", 0x18A}, - {"foot_ik_blend_in", 0x18B}, - {"foot_ik_blend_out", 0x18C}, - {"foot_ik_inactive", 0x18D}, - {"footstepdetectdist", 0x18E}, - {"footstepdetectdistsprint", 0x18F}, - {"footstepdetectdistwalk", 0x190}, - {"force_off", 0x191}, - {"force_on", 0x192}, - {"force_fully_on", 0x193}, - {"forcepartyskillignore", 0x194}, - {"forceragdollimmediate", 0x195}, - {"forcespectatorclient", 0x196}, - {"foregrip_off", 0x197}, - {"foreground", 0x198}, - {"forward", 0x199}, - {"fov", 0x19A}, - {"fovcosine", 0x19B}, - {"fovcosinebusy", 0x19C}, - {"fovcosinez", 0x19D}, - {"fr_rotor1", 0x19E}, - {"fr_rotor2", 0x19F}, - {"fr_rotor3", 0x1A0}, - {"fraction", 0x1A1}, - {"frag", 0x1A2}, - {"free", 0x1A3}, - {"freecamera", 0x1A4}, - {"freelook", 0x1A5}, - {"frequency", 0x1A6}, - {"friendlyfire", 0x1A7}, - {"front_left", 0x1A8}, - {"front_right", 0x1A9}, - {"frontshieldanglecos", 0x1AA}, - {"fs_concrete", 0x1AB}, - {"fs_dirt", 0x1AC}, - {"fs_metal", 0x1AD}, - {"fs_wood", 0x1AE}, - {"game_extrainfo", 0x1AF}, - {"gamecount", 0x1B0}, - {"gamertag", 0x1B1}, - {"gamesplayed", 0x1B2}, - {"gametype", 0x1B3}, - {"gender", 0x1B4}, - {"ghostsprestige", 0x1B5}, - {"ghostsrank", 0x1B6}, - {"glass", 0x1B7}, - {"glass_damaged", 0x1B8}, - {"glass_destroyed", 0x1B9}, - {"globalcostume", 0x1BA}, - {"gloves", 0x1BB}, - {"glowalpha", 0x1BC}, - {"glowcolor", 0x1BD}, - {"goal", 0x1BE}, - {"goal_changed", 0x1BF}, - {"goal_reached", 0x1C0}, - {"goal_yaw", 0x1C1}, - {"goalheight", 0x1C2}, - {"goalpos", 0x1C3}, - {"goalradius", 0x1C4}, - {"goaltime", 0x1C5}, - {"goalweight", 0x1C6}, - {"goingtoruntopos", 0x1C7}, - {"gravity", 0x1C8}, - {"gravity_noclip", 0x1C9}, - {"grenade", 0x1CA}, - {"grenade_fire", 0x1CB}, - {"grenade_off", 0x1CC}, - {"grenade_on", 0x1CD}, - {"grenade_pullback", 0x1CE}, - {"grenade_return_hand_tag", 0x1CF}, - {"grenadeammo", 0x1D0}, - {"grenadeawareness", 0x1D1}, - {"grenadedanger", 0x1D2}, - {"grenadeweapon", 0x1D3}, - {"ground_slam", 0x1D4}, - {"ground_slam_hit_player", 0x1D5}, - {"groundentchanged", 0x1D6}, - {"groundtype", 0x1D7}, - {"gunblockedbywall", 0x1D8}, - {"gunshot", 0x1D9}, - {"gunshot_teammate", 0x1DA}, - {"hardcoremodeon", 0x1DB}, - {"hasdoublexpitem", 0x1DC}, - {"hasradar", 0x1DD}, - {"hasvalidcostumeselfieimage", 0x1DE}, - {"head", 0x1DF}, - {"headicon", 0x1E0}, - {"headiconteam", 0x1E1}, - {"headshots", 0x1E2}, - {"health", 0x1E3}, - {"healthregen", 0x1E4}, - {"height", 0x1E5}, - {"helmet", 0x1E6}, - {"hidein3rdperson", 0x1E7}, - {"hidewhendead", 0x1E8}, - {"hidewhenindemo", 0x1E9}, - {"hidewheninmenu", 0x1EA}, - {"high_priority", 0x1EB}, - {"highlyawareradius", 0x1EC}, - {"hindlegstraceoffset", 0x1ED}, - {"hintstring", 0x1EE}, - {"hit_by_missile", 0x1EF}, - {"horzalign", 0x1F0}, - {"host_sucks_end_game", 0x1F1}, - {"hostfailures", 0x1F2}, - {"hostquits", 0x1F3}, - {"hostsuccesses", 0x1F4}, - {"human", 0x1F5}, - {"iconnew", 0x1F6}, - {"iconunlocked", 0x1F7}, - {"ignoreall", 0x1F8}, - {"ignoreclosefoliage", 0x1F9}, - {"ignoreexplosionevents", 0x1FA}, - {"ignoreforfixednodesafecheck", 0x1FB}, - {"ignoreme", 0x1FC}, - {"ignorerandombulletdamage", 0x1FD}, - {"ignoresuppression", 0x1FE}, - {"ignoretriggers", 0x1FF}, - {"ikweight", 0x200}, - {"index", 0x201}, - {"infinite_energy", 0x202}, - {"info_notnull", 0x203}, - {"info_player_start", 0x204}, - {"init", 0x205}, - {"initstructs", 0x206}, - {"insolid", 0x207}, - {"intermission", 0x208}, - {"interval", 0x209}, - {"inuse", 0x20A}, - {"invalid_parent", 0x20B}, - {"invisible", 0x20C}, - {"isradarblocked", 0x20D}, - {"item", 0x20E}, - {"j_exo_rcket_arm02", 0x20F}, - {"j_exoclav04_l", 0x210}, - {"j_exoclav04_r", 0x211}, - {"j_exohip04_l", 0x212}, - {"j_exohip04_r", 0x213}, - {"j_eyeball_le", 0x214}, - {"j_eyeball_ri", 0x215}, - {"j_gun", 0x216}, - {"j_head", 0x217}, - {"j_hip_l", 0x218}, - {"j_hip_r", 0x219}, - {"j_knee_le", 0x21A}, - {"j_knee_ri", 0x21B}, - {"j_left_elbow", 0x21C}, - {"j_left_hand", 0x21D}, - {"j_left_shoulder", 0x21E}, - {"j_mainroot", 0x21F}, - {"j_neck", 0x220}, - {"j_right_elbow", 0x221}, - {"j_right_hand", 0x222}, - {"j_right_hand_placement", 0x223}, - {"j_right_shoulder", 0x224}, - {"j_rocket", 0x225}, - {"j_spine4", 0x226}, - {"j_spinelower", 0x227}, - {"j_spineupper", 0x228}, - {"jumpcost", 0x229}, - {"jumping", 0x22A}, - {"justclass", 0x22B}, - {"kdratio", 0x22C}, - {"keepclaimednode", 0x22D}, - {"keepclaimednodeifvalid", 0x22E}, - {"keepnodeduringscriptedanim", 0x22F}, - {"key1", 0x230}, - {"key2", 0x231}, - {"kill_timestamp", 0x232}, - {"killanimscript", 0x233}, - {"killcamentity", 0x234}, - {"killcamentitylookat", 0x235}, - {"kills", 0x236}, - {"killstreak", 0x237}, - {"killstreakcount", 0x238}, - {"killstreakrestricted", 0x239}, - {"killstreakunlocked", 0x23A}, - {"knife_off", 0x23B}, - {"knife_on", 0x23C}, - {"known_event", 0x23D}, - {"label", 0x23E}, - {"ladder_down", 0x23F}, - {"ladder_up", 0x240}, - {"land", 0x241}, - {"last_stand_count", 0x242}, - {"lastattacker", 0x243}, - {"lastenemysightpos", 0x244}, - {"lastplayedtime", 0x245}, - {"laststand", 0x246}, - {"leanamount", 0x247}, - {"ledge", 0x248}, - {"left", 0x249}, - {"leftaimlimit", 0x24A}, - {"leftarc", 0x24B}, - {"lethal", 0x24C}, - {"lifecount", 0x24D}, - {"light", 0x24E}, - {"lives", 0x24F}, - {"loadouts", 0x250}, - {"lockorientation", 0x251}, - {"lod", 0x252}, - {"look", 0x253}, - {"lookahead", 0x254}, - {"lookaheaddir", 0x255}, - {"lookaheaddist", 0x256}, - {"lookaheadhitsstairs", 0x257}, - {"lookforward", 0x258}, - {"lookright", 0x259}, - {"looktarget", 0x25A}, - {"lookup", 0x25B}, - {"loot", 0x25C}, - {"lootnew", 0x25D}, - {"loses", 0x25E}, - {"low_priority", 0x25F}, - {"lowresbackground", 0x260}, - {"luinotifyserver", 0x261}, - {"mag_eject", 0x262}, - {"mag_eject_left", 0x263}, - {"main", 0x264}, - {"manual", 0x265}, - {"manual_ai", 0x266}, - {"manual_change", 0x267}, - {"map", 0x268}, - {"matchid", 0x269}, - {"matchmakingsettingsversion", 0x26A}, - {"matchmakingtesttype", 0x26B}, - {"max_time", 0x26C}, - {"maxfaceenemydist", 0x26D}, - {"maxhealth", 0x26E}, - {"maxrange", 0x26F}, - {"maxsightdistsqrd", 0x270}, - {"maxturnspeed", 0x271}, - {"maxvisibledist", 0x272}, - {"melee_fired", 0x273}, - {"melee_hit_react", 0x274}, - {"meleeattackdist", 0x275}, - {"menuresponse", 0x276}, - {"micro_dlc_bits_last_gen", 0x277}, - {"micro_dlc_bits_next_gen", 0x278}, - {"middle_left", 0x279}, - {"middle_right", 0x27A}, - {"migrateablequits", 0x27B}, - {"min_energy", 0x27C}, - {"min_time", 0x27D}, - {"minpaindamage", 0x27E}, - {"minusedistsq", 0x27F}, - {"missile_fire", 0x280}, - {"missile_passed_target", 0x281}, - {"missile_stuck", 0x282}, - {"mlgversion", 0x283}, - {"mod", 0x284}, - {"mod_crush", 0x285}, - {"mod_energy", 0x286}, - {"mod_explosive", 0x287}, - {"mod_explosive_bullet", 0x288}, - {"mod_falling", 0x289}, - {"mod_grenade", 0x28A}, - {"mod_grenade_splash", 0x28B}, - {"mod_head_shot", 0x28C}, - {"mod_impact", 0x28D}, - {"mod_melee", 0x28E}, - {"mod_melee_alien", 0x28F}, - {"mod_melee_alt", 0x290}, - {"mod_melee_dog", 0x291}, - {"mod_pistol_bullet", 0x292}, - {"mod_projectile", 0x293}, - {"mod_projectile_splash", 0x294}, - {"mod_rifle_bullet", 0x295}, - {"mod_suicide", 0x296}, - {"mod_trigger_hurt", 0x297}, - {"mod_unknown", 0x298}, - {"model", 0x299}, - {"modeprefix", 0x29A}, - {"modifiers", 0x29B}, - {"motiontrackerenabled", 0x29C}, - {"mounted_dlc_bits", 0x29D}, - {"movedone", 0x29E}, - {"movemode", 0x29F}, - {"munition", 0x2A0}, - {"munition_level", 0x2A1}, - {"mw3prestige", 0x2A2}, - {"mw3rank", 0x2A3}, - {"name", 0x2A4}, - {"namemodified", 0x2A5}, - {"near_goal", 0x2A6}, - {"nearz", 0x2A7}, - {"neutral", 0x2A8}, - {"never", 0x2A9}, - {"newenemyreactiondistsq", 0x2AA}, - {"newentitlement", 0x2AB}, - {"nextgen", 0x2AC}, - {"nextreadblackops2", 0x2AD}, - {"nextreadghosts0", 0x2AE}, - {"nextreadghosts1", 0x2AF}, - {"nextreadmw3", 0x2B0}, - {"night_vision_off", 0x2B1}, - {"night_vision_on", 0x2B2}, - {"no_bot_random_path", 0x2B3}, - {"no_cover", 0x2B4}, - {"no_gravity", 0x2B5}, - {"noattackeraccuracymod", 0x2B6}, - {"noclip", 0x2B7}, - {"node", 0x2B8}, - {"node_not_safe", 0x2B9}, - {"node_out_of_range", 0x2BA}, - {"node_relinquished", 0x2BB}, - {"node_taken", 0x2BC}, - {"nodeoffsetpos", 0x2BD}, - {"nododgemove", 0x2BE}, - {"nogravity", 0x2BF}, - {"nogrenadereturnthrow", 0x2C0}, - {"noncombat", 0x2C1}, - {"none", 0x2C2}, - {"nonmigrateablequits", 0x2C3}, - {"nophysics", 0x2C4}, - {"normal", 0x2C5}, - {"normal_radar", 0x2C6}, - {"northyaw", 0x2C7}, - {"notifyname", 0x2C8}, - {"notinsolid", 0x2C9}, - {"num0", 0x2CA}, - {"num1", 0x2CB}, - {"num2", 0x2CC}, - {"num3", 0x2CD}, - {"num4", 0x2CE}, - {"objective", 0x2CF}, - {"obstacle", 0x2D0}, - {"offense", 0x2D1}, - {"offense_level", 0x2D2}, - {"offhand", 0x2D3}, - {"offhand_end", 0x2D4}, - {"offhandweapon", 0x2D5}, - {"oldtime", 0x2D6}, - {"ondeactivate", 0x2D7}, - {"onenterstate", 0x2D8}, - {"only_sky", 0x2D9}, - {"onlygoodnearestnodes", 0x2DA}, - {"onwifi", 0x2DB}, - {"operationsdeadline", 0x2DC}, - {"oriented", 0x2DD}, - {"orientto_complete", 0x2DE}, - {"origin", 0x2DF}, - {"other", 0x2E0}, - {"over", 0x2E1}, - {"owner", 0x2E2}, - {"pacifist", 0x2E3}, - {"pacifistwait", 0x2E4}, - {"pain", 0x2E5}, - {"pantssize", 0x2E6}, - {"parentindex", 0x2E7}, - {"parentname", 0x2E8}, - {"partyid", 0x2E9}, - {"pasttitledata", 0x2EA}, - {"patch", 0x2EB}, - {"patchbacking", 0x2EC}, - {"path_blocked", 0x2ED}, - {"path_changed", 0x2EE}, - {"path_dir_change", 0x2EF}, - {"path_enemy", 0x2F0}, - {"path_need_dodge", 0x2F1}, - {"path_set", 0x2F2}, - {"pathenemyfightdist", 0x2F3}, - {"pathenemylookahead", 0x2F4}, - {"pathgoalpos", 0x2F5}, - {"pathlookaheaddist", 0x2F6}, - {"pathrandompercent", 0x2F7}, - {"pc", 0x2F8}, - {"pccg", 0x2F9}, - {"pelvis", 0x2FA}, - {"perk1", 0x2FB}, - {"perk2", 0x2FC}, - {"perk3", 0x2FD}, - {"perk4", 0x2FE}, - {"perk5", 0x2FF}, - {"perk6", 0x300}, - {"perkclassrestricted", 0x301}, - {"perkrestricted", 0x302}, - {"perks", 0x303}, - {"perkslots", 0x304}, - {"pers", 0x305}, - {"persistentperksunlocked", 0x306}, - {"persistentweaponsunlocked", 0x307}, - {"phone_off", 0x308}, - {"phone_on", 0x309}, - {"physics_finished", 0x30A}, - {"physics_impact", 0x30B}, - {"pickup", 0x30C}, - {"pickup_riotshield", 0x30D}, - {"pistol", 0x30E}, - {"pitchamount", 0x30F}, - {"pitchconvergencetime", 0x310}, - {"plane_waypoint", 0x311}, - {"playedblackops2", 0x312}, - {"playedghosts", 0x313}, - {"playedmw3", 0x314}, - {"player", 0x315}, - {"player_controller", 0x316}, - {"player_pushed", 0x317}, - {"playercardbackground", 0x318}, - {"playercardpatch", 0x319}, - {"playercardpatchbacking", 0x31A}, - {"playerconnectionhistory", 0x31B}, - {"playerid", 0x31C}, - {"playerip", 0x31D}, - {"playername", 0x31E}, - {"playerpositions", 0x31F}, - {"players", 0x320}, - {"playerSpread", 0x321}, - {"playerxuidhigh", 0x322}, - {"playerxuidlow", 0x323}, - {"playing", 0x324}, - {"points", 0x325}, - {"position", 0x326}, - {"positioninworld", 0x327}, - {"postsharpturnlookaheaddist", 0x328}, - {"precache", 0x329}, - {"predicted_projectile_impact", 0x32A}, - {"prestige", 0x32B}, - {"prestigedoublexp", 0x32C}, - {"prestigedoublexpmaxtimeplayed", 0x32D}, - {"prestigeshoptokens", 0x32E}, - {"prestigeshoptokensentitlement", 0x32F}, - {"prevanimdelta", 0x330}, - {"prevnode", 0x331}, - {"prevscript", 0x332}, - {"primary", 0x333}, - {"primaryattachment1", 0x334}, - {"primaryattachment2", 0x335}, - {"primaryattachment3", 0x336}, - {"primaryattachments", 0x337}, - {"primaryattachkit", 0x338}, - {"primarycamo", 0x339}, - {"primaryfurniturekit", 0x33A}, - {"primaryoffhand", 0x33B}, - {"primaryreticle", 0x33C}, - {"primaryweapon", 0x33D}, - {"privatematchactivesquadmember", 0x33E}, - {"privatematchcustomclasses", 0x33F}, - {"privatematchsquadmembers", 0x340}, - {"projectile_impact", 0x341}, - {"projectile_impact_player", 0x342}, - {"prone", 0x343}, - {"proneok", 0x344}, - {"providecoveringfire", 0x345}, - {"ps3", 0x346}, - {"ps4", 0x347}, - {"psoffsettime", 0x348}, - {"pushable", 0x349}, - {"radaralwayson", 0x34A}, - {"radarmode", 0x34B}, - {"radarshowenemydirection", 0x34C}, - {"radarstrength", 0x34D}, - {"radius", 0x34E}, - {"ragdoll_early_result", 0x34F}, - {"raise_riotshield", 0x350}, - {"rank", 0x351}, - {"rate", 0x352}, - {"reached_end_node", 0x353}, - {"reached_wait_node", 0x354}, - {"reached_wait_speed", 0x355}, - {"reactiontargetpos", 0x356}, - {"realtimedelta", 0x357}, - {"receiver", 0x358}, - {"recipename", 0x359}, - {"reciprocality", 0x35A}, - {"reflection_clear_color", 0x35B}, - {"reinforcement", 0x35C}, - {"relativedir", 0x35D}, - {"relativeoffset", 0x35E}, - {"reload", 0x35F}, - {"reload_start", 0x360}, - {"remotemissilespawn", 0x361}, - {"rendertotexture", 0x362}, - {"reportindex", 0x363}, - {"reports", 0x364}, - {"reputation", 0x365}, - {"requestarrivalnotify", 0x366}, - {"requirement_beat100waves", 0x367}, - {"requirement_beat200waves", 0x368}, - {"requirement_beat50waves", 0x369}, - {"requirement_beatenzombies", 0x36A}, - {"requirement_maxarmorproficiency", 0x36B}, - {"requirement_maxweaponproficiency", 0x36C}, - {"requirement_playedallmaps", 0x36D}, - {"requirement_unlockedprison", 0x36E}, - {"requirement_unlockedtier2", 0x36F}, - {"requirement_unlockedtier3", 0x370}, - {"reserved", 0x371}, - {"respawndelay", 0x372}, - {"result", 0x373}, - {"reticle", 0x374}, - {"return_pitch", 0x375}, - {"reverse", 0x376}, - {"revives", 0x377}, - {"right", 0x378}, - {"rightaimlimit", 0x379}, - {"rightarc", 0x37A}, - {"riotshield_damaged", 0x37B}, - {"riotshield_hit", 0x37C}, - {"rocket", 0x37D}, - {"rocket_off", 0x37E}, - {"rocket_on", 0x37F}, - {"rotatedone", 0x380}, - {"rotation", 0x381}, - {"run", 0x382}, - {"runcost", 0x383}, - {"runto_arrived", 0x384}, - {"safetochangescript", 0x385}, - {"scavenger", 0x386}, - {"scope_cap", 0x387}, - {"scope_center", 0x388}, - {"scope_top", 0x389}, - {"score", 0x38A}, - {"script", 0x38B}, - {"script_brushmodel", 0x38C}, - {"script_clut", 0x38D}, - {"script_context", 0x38E}, - {"script_delay", 0x38F}, - {"script_goal_changed", 0x390}, - {"script_label", 0x391}, - {"script_lightset", 0x392}, - {"script_linkname", 0x393}, - {"script_model", 0x394}, - {"script_noteworthy", 0x395}, - {"script_origin", 0x396}, - {"script_parent", 0x397}, - {"script_parentname", 0x398}, - {"script_pushable", 0x399}, - {"script_vehicle", 0x39A}, - {"script_vehicle_collision", 0x39B}, - {"script_vehicle_collmap", 0x39C}, - {"script_vehicle_corpse", 0x39D}, - {"script_visionset", 0x39E}, - {"script_water", 0x39F}, - {"script_reverb", 0x3A0}, - {"script_zone", 0x3A1}, - {"scriptable", 0x3A2}, - {"scriptableactor", 0x3A3}, - {"scripted_viewmodel_anim", 0x3A4}, - {"scriptedarrivalent", 0x3A5}, - {"search_end", 0x3A6}, - {"secondary", 0x3A7}, - {"secondaryattachment1", 0x3A8}, - {"secondaryattachment2", 0x3A9}, - {"secondaryattachments", 0x3AA}, - {"secondaryattachkit", 0x3AB}, - {"secondarycamo", 0x3AC}, - {"secondaryfurniturekit", 0x3AD}, - {"secondaryoffhand", 0x3AE}, - {"secondaryreticle", 0x3AF}, - {"secondaryweapon", 0x3B0}, - {"sentry", 0x3B1}, - {"sentry_manual", 0x3B2}, - {"sentry_offline", 0x3B3}, - {"servertimecount", 0x3B4}, - {"servertimeexceedcount", 0x3B5}, - {"servertimemax", 0x3B6}, - {"servertimetotal", 0x3B7}, - {"servertimetotalexceed", 0x3B8}, - {"sessionstate", 0x3B9}, - {"sessionteam", 0x3BA}, - {"sharpturn", 0x3BB}, - {"sharpturnlookaheaddist", 0x3BC}, - {"sharpturnnotifydist", 0x3BD}, - {"sharpturntooclosetodestdist", 0x3BE}, - {"shirt", 0x3BF}, - {"showinkillcam", 0x3C0}, - {"showkillcam", 0x3C1}, - {"sightlatency", 0x3C2}, - {"silenced_shot", 0x3C3}, - {"skill_points", 0x3C4}, - {"skillbucket", 0x3C5}, - {"skillrating", 0x3C6}, - {"skillratingtype", 0x3C7}, - {"slidevelocity", 0x3C8}, - {"slowmo_active", 0x3C9}, - {"slowmo_passive", 0x3CA}, - {"smoke", 0x3CB}, - {"snd_channelvolprio_holdbreath", 0x3CC}, - {"snd_channelvolprio_pain", 0x3CD}, - {"snd_channelvolprio_shellshock", 0x3CE}, - {"snd_enveffectsprio_level", 0x3CF}, - {"snd_enveffectsprio_shellshock", 0x3D0}, - {"sort", 0x3D1}, - {"sound_blend", 0x3D2}, - {"soundeventdone", 0x3D3}, - {"space", 0x3D4}, - {"spawned", 0x3D5}, - {"spawner", 0x3D6}, - {"spawnflags", 0x3D7}, - {"spawnpos", 0x3D8}, - {"spawntime", 0x3D9}, - {"specialgrenade", 0x3DA}, - {"spectatekillcam", 0x3DB}, - {"spectating_cycle", 0x3DC}, - {"spectator", 0x3DD}, - {"speechcommand", 0x3DE}, - {"speed", 0x3DF}, - {"splatter", 0x3E0}, - {"splineplanereachednode", 0x3E1}, - {"sprint_begin", 0x3E2}, - {"sprint_end", 0x3E3}, - {"sprint_slide_begin", 0x3E4}, - {"sprint_slide_end", 0x3E5}, - {"squad_base", 0x3E6}, - {"squad_mode", 0x3E7}, - {"squad_name", 0x3E8}, - {"squadhq", 0x3E9}, - {"squadmembers", 0x3EA}, - {"squadmemxp", 0x3EB}, - {"squadname", 0x3EC}, - {"stairs", 0x3ED}, - {"stairsstate", 0x3EE}, - {"stand", 0x3EF}, - {"start_blend", 0x3F0}, - {"start_move", 0x3F1}, - {"start_ragdoll", 0x3F2}, - {"startdeaths", 0x3F3}, - {"startdeploy_riotshield", 0x3F4}, - {"startingoffsetforlife", 0x3F5}, - {"startkills", 0x3F6}, - {"state_changed", 0x3F7}, - {"statelocked", 0x3F8}, - {"stencil_disable", 0x3F9}, - {"stencil_onesided", 0x3FA}, - {"stencil_twosided", 0x3FB}, - {"stencilfunc_always", 0x3FC}, - {"stencilfunc_equal", 0x3FD}, - {"stencilfunc_greater", 0x3FE}, - {"stencilfunc_greaterequal", 0x3FF}, - {"stencilfunc_less", 0x400}, - {"stencilfunc_lessequal", 0x401}, - {"stencilfunc_never", 0x402}, - {"stencilfunc_notequal", 0x403}, - {"stencilop_decr", 0x404}, - {"stencilop_decrsat", 0x405}, - {"stencilop_incr", 0x406}, - {"stencilop_incrsat", 0x407}, - {"stencilop_invert", 0x408}, - {"stencilop_keep", 0x409}, - {"stencilop_replace", 0x40A}, - {"stencilop_zero", 0x40B}, - {"stop", 0x40C}, - {"stop_soon", 0x40D}, - {"stopanimdistsq", 0x40E}, - {"stopsoonnotifydist", 0x40F}, - {"streak", 0x410}, - {"streaktype", 0x411}, - {"suckedashost", 0x412}, - {"suncolor", 0x413}, - {"sundirection", 0x414}, - {"sunlight", 0x415}, - {"support", 0x416}, - {"support_level", 0x417}, - {"suppression", 0x418}, - {"suppression_end", 0x419}, - {"suppressionduration", 0x41A}, - {"suppressionmeter", 0x41B}, - {"suppressionstarttime", 0x41C}, - {"suppressionTime", 0x41D}, - {"suppressionwait", 0x41E}, - {"surfacetype", 0x41F}, - {"surprisedbymedistsq", 0x420}, - {"swimmer", 0x421}, - {"switched_var_grenade", 0x422}, - {"syncedmeleetarget", 0x423}, - {"tactical", 0x424}, - {"tag", 0x425}, - {"tag_ai_aim_target", 0x426}, - {"tag_aim", 0x427}, - {"tag_aim_animated", 0x428}, - {"tag_aim_pivot", 0x429}, - {"tag_barrel", 0x42A}, - {"tag_blade_off", 0x42B}, - {"tag_body", 0x42C}, - {"tag_brass", 0x42D}, - {"tag_brass_2", 0x42E}, - {"tag_butt", 0x42F}, - {"tag_camera", 0x430}, - {"tag_clip", 0x431}, - {"tag_clip_dual", 0x432}, - {"tag_clip_dual2", 0x433}, - {"tag_detach", 0x434}, - {"tag_engine_left", 0x435}, - {"tag_engine_right", 0x436}, - {"tag_eotech_reticle", 0x437}, - {"tag_eye", 0x438}, - {"tag_flash", 0x439}, - {"tag_flash_11", 0x43A}, - {"tag_flash_2", 0x43B}, - {"tag_flash_22", 0x43C}, - {"tag_flash_3", 0x43D}, - {"tag_flash_launcher", 0x43E}, - {"tag_flash_silenced", 0x43F}, - {"tag_fx", 0x440}, - {"tag_gasmask", 0x441}, - {"tag_gasmask2", 0x442}, - {"tag_ik_ankle_fl", 0x443}, - {"tag_ik_ankle_fr", 0x444}, - {"tag_ik_ankle_kl", 0x445}, - {"tag_ik_ankle_kr", 0x446}, - {"tag_ik_ankle_ml", 0x447}, - {"tag_ik_ankle_mr", 0x448}, - {"tag_ik_footflat_fl", 0x449}, - {"tag_ik_footflat_fr", 0x44A}, - {"tag_ik_footflat_kl", 0x44B}, - {"tag_ik_footflat_kr", 0x44C}, - {"tag_ik_footflat_ml", 0x44D}, - {"tag_ik_footflat_mr", 0x44E}, - {"tag_ik_hip_fl", 0x44F}, - {"tag_ik_hip_fr", 0x450}, - {"tag_ik_hip_kl", 0x451}, - {"tag_ik_hip_kr", 0x452}, - {"tag_ik_hip_ml", 0x453}, - {"tag_ik_hip_mr", 0x454}, - {"tag_ik_knee_fl", 0x455}, - {"tag_ik_knee_fr", 0x456}, - {"tag_ik_knee_kl", 0x457}, - {"tag_ik_knee_kr", 0x458}, - {"tag_ik_knee_ml", 0x459}, - {"tag_ik_knee_mr", 0x45A}, - {"tag_ik_loc_le", 0x45B}, - {"tag_ik_loc_le_foregrip", 0x45C}, - {"tag_ik_loc_le_launcher", 0x45D}, - {"tag_ik_loc_le_shotgun", 0x45E}, - {"tag_ik_target", 0x45F}, - {"tag_inhand", 0x460}, - {"tag_jetblast_fx", 0x461}, - {"tag_jetpack", 0x462}, - {"tag_knife_attach", 0x463}, - {"tag_knife_fx", 0x464}, - {"tag_laser", 0x465}, - {"tag_launcher", 0x466}, - {"tag_magnifier_eotech_reticle", 0x467}, - {"tag_mobile_cover_upright", 0x468}, - {"tag_motion_tracker_bl", 0x469}, - {"tag_motion_tracker_br", 0x46A}, - {"tag_motion_tracker_fx", 0x46B}, - {"tag_motion_tracker_tl", 0x46C}, - {"tag_origin", 0x46D}, - {"tag_player", 0x46E}, - {"tag_popout", 0x46F}, - {"tag_rail_master_off", 0x470}, - {"tag_rail_master_on", 0x471}, - {"tag_rail_side_off", 0x472}, - {"tag_rail_side_on", 0x473}, - {"tag_reticle_acog", 0x474}, - {"tag_reticle_default", 0x475}, - {"tag_reticle_default2", 0x476}, - {"tag_reticle_hamr", 0x477}, - {"tag_reticle_on", 0x478}, - {"tag_reticle_red_dot", 0x479}, - {"tag_reticle_reflex", 0x47A}, - {"tag_reticle_tavor_scope", 0x47B}, - {"tag_reticle_thermal_scope", 0x47C}, - {"tag_rider", 0x47D}, - {"tag_riot_shield", 0x47E}, - {"tag_rocket", 0x47F}, - {"tag_scope_ads_off", 0x480}, - {"tag_scope_ads_on", 0x481}, - {"tag_shield_back", 0x482}, - {"tag_shotgun", 0x483}, - {"tag_show_alt", 0x484}, - {"tag_sight_off", 0x485}, - {"tag_sight_on", 0x486}, - {"tag_stow_back_mid_attach", 0x487}, - {"tag_stowed_back", 0x488}, - {"tag_stowed_hip_rear", 0x489}, - {"tag_sync", 0x48A}, - {"tag_tip", 0x48B}, - {"tag_turret", 0x48C}, - {"tag_turret_base", 0x48D}, - {"tag_turret_pitch", 0x48E}, - {"tag_turret_yaw", 0x48F}, - {"tag_weapon", 0x490}, - {"tag_weapon_chest", 0x491}, - {"tag_weapon_left", 0x492}, - {"tag_weapon_right", 0x493}, - {"tag_wheel_back_left", 0x494}, - {"tag_wheel_back_right", 0x495}, - {"tag_wheel_front_left", 0x496}, - {"tag_wheel_front_right", 0x497}, - {"tag_wheel_middle_left", 0x498}, - {"tag_wheel_middle_right", 0x499}, - {"tag_wheel_spin_left01", 0x49A}, - {"tag_wheel_spin_left02", 0x49B}, - {"tag_wheel_spin_left03", 0x49C}, - {"tag_wheel_spin_right01", 0x49D}, - {"tag_wheel_spin_right02", 0x49E}, - {"tag_wheel_spin_right03", 0x49F}, - {"takedamage", 0x4A0}, - {"target", 0x4A1}, - {"target_script_trigger", 0x4A2}, - {"targetname", 0x4A3}, - {"team", 0x4A4}, - {"team3", 0x4A5}, - {"teambalanced", 0x4A6}, - {"teammode_axisallies", 0x4A7}, - {"teammode_ffa", 0x4A8}, - {"teammovewaittime", 0x4A9}, - {"their_score", 0x4AA}, - {"thermal", 0x4AB}, - {"thermalbodymaterial", 0x4AC}, - {"third_person", 0x4AD}, - {"threatbias", 0x4AE}, - {"threatbiasgroup", 0x4AF}, - {"threatsightdelayenabled", 0x4B0}, - {"threatsightdelayfalloff", 0x4B1}, - {"threshold", 0x4B2}, - {"throwingknife", 0x4B3}, - {"time", 0x4B4}, - {"timeplayedtotal", 0x4B5}, - {"titlenew", 0x4B6}, - {"titleunlocked", 0x4B7}, - {"top", 0x4B8}, - {"toparc", 0x4B9}, - {"totalxp", 0x4BA}, - {"touch", 0x4BB}, - {"touching_platform", 0x4BC}, - {"traverse_complete", 0x4BD}, - {"traverse_soon", 0x4BE}, - {"traversecost", 0x4BF}, - {"traversesoonnotifydist", 0x4C0}, - {"trend", 0x4C1}, - {"trigger", 0x4C2}, - {"trigger_damage", 0x4C3}, - {"trigger_use", 0x4C4}, - {"trigger_use_touch", 0x4C5}, - {"truck_cam", 0x4C6}, - {"turnrate", 0x4C7}, - {"turret_deactivate", 0x4C8}, - {"turret_fire", 0x4C9}, - {"turret_no_vis", 0x4CA}, - {"turret_not_on_target", 0x4CB}, - {"turret_on_target", 0x4CC}, - {"turret_on_vistarget", 0x4CD}, - {"turret_pitch_clamped", 0x4CE}, - {"turret_rotate_stopped", 0x4CF}, - {"turret_yaw_clamped", 0x4D0}, - {"turretinvulnerability", 0x4D1}, - {"turretownerchange", 0x4D2}, - {"turretstatechange", 0x4D3}, - {"type", 0x4D4}, - {"ucdidhigh", 0x4D5}, - {"ucdidlow", 0x4D6}, - {"unlockedcamo", 0x4D7}, - {"unlockedreticles", 0x4D8}, - {"unlockpoints", 0x4D9}, - {"unresolved_collision", 0x4DA}, - {"up", 0x4DB}, - {"upaimlimit", 0x4DC}, - {"upgradechallengeprogress", 0x4DD}, - {"upgradechallengestage", 0x4DE}, - {"upgradepoints", 0x4DF}, - {"upgradepurchased", 0x4E0}, - {"useable", 0x4E1}, - {"usechokepoints", 0x4E2}, - {"usecombatscriptatcover", 0x4E3}, - {"usedemblemslots", 0x4E4}, - {"useorcaavoidance", 0x4E5}, - {"usepathsmoothingvalues", 0x4E6}, - {"veh_boatbounce", 0x4E7}, - {"veh_boost_activated", 0x4E8}, - {"veh_boost_deactivated", 0x4E9}, - {"veh_brake", 0x4EA}, - {"veh_collision", 0x4EB}, - {"veh_contact", 0x4EC}, - {"veh_jolt", 0x4ED}, - {"veh_landed", 0x4EE}, - {"veh_leftground", 0x4EF}, - {"veh_pathdir", 0x4F0}, - {"veh_pathspeed", 0x4F1}, - {"veh_pathtype", 0x4F2}, - {"veh_predictedcollision", 0x4F3}, - {"veh_speed", 0x4F4}, - {"veh_throttle", 0x4F5}, - {"veh_topspeed", 0x4F6}, - {"veh_transmission", 0x4F7}, - {"vehicle_dismount", 0x4F8}, - {"vehicle_mount", 0x4F9}, - {"vehicletype", 0x4FA}, - {"velocity", 0x4FB}, - {"vertalign", 0x4FC}, - {"visionsetmissilecam", 0x4FD}, - {"visionsetmissilecamduration", 0x4FE}, - {"visionsetnaked", 0x4FF}, - {"visionsetnakedduration", 0x500}, - {"visionsetnight", 0x501}, - {"visionsetnightduration", 0x502}, - {"visionsetpain", 0x503}, - {"visionsetpainduration", 0x504}, - {"visionsetthermal", 0x505}, - {"visionsetthermalduration", 0x506}, - {"vote", 0x507}, - {"wait", 0x508}, - {"walk", 0x509}, - {"walkdist", 0x50A}, - {"walkdistfacingmotion", 0x50B}, - {"wastacticalinsertion", 0x50C}, - {"waypoint_reached", 0x50D}, - {"weapon", 0x50E}, - {"weapon_change", 0x50F}, - {"weapon_dropped", 0x510}, - {"weapon_fired", 0x511}, - {"weapon_model_change", 0x512}, - {"weapon_switch_invalid", 0x513}, - {"weapon_switch_started", 0x514}, - {"weapon_taken", 0x515}, - {"weaponchange", 0x516}, - {"weaponclassrestricted", 0x517}, - {"weaponinfo", 0x518}, - {"weaponrank", 0x519}, - {"weaponrestricted", 0x51A}, - {"weaponsetups", 0x51B}, - {"weaponstats", 0x51C}, - {"weeklychallengeid", 0x51D}, - {"weight", 0x51E}, - {"width", 0x51F}, - {"wildcard1", 0x520}, - {"wildcard2", 0x521}, - {"wildcard3", 0x522}, - {"wildcardslots", 0x523}, - {"win_streak", 0x524}, - {"winlossratio", 0x525}, - {"wins", 0x526}, - {"won_match", 0x527}, - {"world", 0x528}, - {"worldmodel", 0x529}, - {"worldspawn", 0x52A}, - {"x", 0x52B}, - {"xb3", 0x52C}, - {"xenon", 0x52D}, - {"xp", 0x52E}, - {"xp_multiplier", 0x52F}, - {"xpmaxmultipliertimeplayed", 0x530}, - {"xpmultiplier", 0x531}, - {"xuid", 0x532}, - {"y", 0x533}, - {"yawconvergencetime", 0x534}, - {"your_score", 0x535}, - {"z", 0x536}, - {"zonly_physics", 0x537}, - {"codescripts/delete", 0x53D}, - {"codescripts/struct", 0x53E}, - {"codescripts/message", 0x53F}, - {"maps/mp/gametypes/_callbacksetup", 0x540}, - }; -} diff --git a/src/client/game/scripting/functions.cpp b/src/client/game/scripting/functions.cpp deleted file mode 100644 index 3452c767..00000000 --- a/src/client/game/scripting/functions.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include "functions.hpp" - -#include - -namespace scripting -{ - namespace - { - std::unordered_map lowercase_map( - const std::unordered_map& old_map) - { - std::unordered_map new_map{}; - for (auto& entry : old_map) - { - new_map[utils::string::to_lower(entry.first)] = entry.second; - } - - return new_map; - } - - const std::unordered_map& get_methods() - { - static auto methods = lowercase_map(method_map); - return methods; - } - - const std::unordered_map& get_functions() - { - static auto function = lowercase_map(function_map); - return function; - } - - int find_function_index(const std::string& name, const bool prefer_global) - { - const auto target = utils::string::to_lower(name); - - const auto& primary_map = prefer_global - ? get_functions() - : get_methods(); - const auto& secondary_map = !prefer_global - ? get_functions() - : get_methods(); - - auto function_entry = primary_map.find(target); - if (function_entry != primary_map.end()) - { - return function_entry->second; - } - - function_entry = secondary_map.find(target); - if (function_entry != secondary_map.end()) - { - return function_entry->second; - } - - return -1; - } - - script_function get_function_by_index(const unsigned index) - { - static const auto function_table = SELECT_VALUE(0x149668F50, 0x147DD1850); - static const auto method_table = SELECT_VALUE(0x14966A670, 0x147DD2F50); - - if (index < 0x2DF) - { - return reinterpret_cast(function_table)[index]; - } - - return reinterpret_cast(method_table)[index - 0x8000]; - } - } - - std::string find_token(unsigned int id) - { - for (const auto& token : token_map) - { - if (token.second == id) - { - return token.first; - } - } - - return utils::string::va("_ID%i", id); - } - - unsigned int find_token_id(const std::string& name) - { - const auto result = token_map.find(name); - - if (result != token_map.end()) - { - return result->second; - } - - return 0; - } - - script_function find_function(const std::string& name, const bool prefer_global) - { - const auto index = find_function_index(name, prefer_global); - if (index < 0) return nullptr; - - return get_function_by_index(index); - } -} diff --git a/src/client/game/scripting/functions.hpp b/src/client/game/scripting/functions.hpp deleted file mode 100644 index 0422bcf7..00000000 --- a/src/client/game/scripting/functions.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include "game/game.hpp" - -namespace scripting -{ - extern std::unordered_map method_map; - extern std::unordered_map function_map; - extern std::unordered_map token_map; - - using script_function = void(*)(game::scr_entref_t); - - std::string find_token(unsigned int id); - unsigned int find_token_id(const std::string& name); - - script_function find_function(const std::string& name, const bool prefer_global); -} diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp deleted file mode 100644 index 7aaa9f89..00000000 --- a/src/client/game/scripting/lua/context.cpp +++ /dev/null @@ -1,542 +0,0 @@ -#include -#include "context.hpp" -#include "error.hpp" -#include "value_conversion.hpp" - -#include "../execution.hpp" -#include "../functions.hpp" - -#include "../../../component/command.hpp" -#include "../../../component/logfile.hpp" -#include "../../../component/scripting.hpp" - -#include -#include - -namespace scripting::lua -{ - namespace - { - - vector normalize_vector(const vector& vec) - { - const auto length = sqrt( - (vec.get_x() * vec.get_x()) + - (vec.get_y() * vec.get_y()) + - (vec.get_z() * vec.get_z()) - ); - - return vector( - vec.get_x() / length, - vec.get_y() / length, - vec.get_z() / length - ); - } - - void setup_io(sol::state& state) - { - state["io"]["fileexists"] = utils::io::file_exists; - state["io"]["writefile"] = utils::io::write_file; - state["io"]["remove_file"] = utils::io::remove_file; - state["io"]["filesize"] = utils::io::file_size; - state["io"]["createdirectory"] = utils::io::create_directory; - state["io"]["directoryexists"] = utils::io::directory_exists; - state["io"]["directoryisempty"] = utils::io::directory_is_empty; - state["io"]["listfiles"] = utils::io::list_files; - state["io"]["copyfolder"] = utils::io::copy_folder; - state["io"]["readfile"] = static_cast(utils::io::read_file); - } - - void setup_vector_type(sol::state& state) - { - auto vector_type = state.new_usertype("vector", sol::constructors()); - vector_type["x"] = sol::property(&vector::get_x, &vector::set_x); - vector_type["y"] = sol::property(&vector::get_y, &vector::set_y); - vector_type["z"] = sol::property(&vector::get_z, &vector::set_z); - - vector_type["r"] = sol::property(&vector::get_x, &vector::set_x); - vector_type["g"] = sol::property(&vector::get_y, &vector::set_y); - vector_type["b"] = sol::property(&vector::get_z, &vector::set_z); - - vector_type[sol::meta_function::addition] = sol::overload( - [](const vector& a, const vector& b) - { - return vector( - a.get_x() + b.get_x(), - a.get_y() + b.get_y(), - a.get_z() + b.get_z() - ); - }, - [](const vector& a, const int value) - { - return vector( - a.get_x() + value, - a.get_y() + value, - a.get_z() + value - ); - } - ); - - vector_type[sol::meta_function::subtraction] = sol::overload( - [](const vector& a, const vector& b) - { - return vector( - a.get_x() - b.get_x(), - a.get_y() - b.get_y(), - a.get_z() - b.get_z() - ); - }, - [](const vector& a, const int value) - { - return vector( - a.get_x() - value, - a.get_y() - value, - a.get_z() - value - ); - } - ); - - vector_type[sol::meta_function::multiplication] = sol::overload( - [](const vector& a, const vector& b) - { - return vector( - a.get_x() * b.get_x(), - a.get_y() * b.get_y(), - a.get_z() * b.get_z() - ); - }, - [](const vector& a, const int value) - { - return vector( - a.get_x() * value, - a.get_y() * value, - a.get_z() * value - ); - } - ); - - vector_type[sol::meta_function::division] = sol::overload( - [](const vector& a, const vector& b) - { - return vector( - a.get_x() / b.get_x(), - a.get_y() / b.get_y(), - a.get_z() / b.get_z() - ); - }, - [](const vector& a, const int value) - { - return vector( - a.get_x() / value, - a.get_y() / value, - a.get_z() / value - ); - } - ); - - vector_type[sol::meta_function::equal_to] = [](const vector& a, const vector& b) - { - return a.get_x() == b.get_x() && - a.get_y() == b.get_y() && - a.get_z() == b.get_z(); - }; - - vector_type[sol::meta_function::length] = [](const vector& a) - { - return sqrt((a.get_x() * a.get_x()) + (a.get_y() * a.get_y()) + (a.get_z() * a.get_z())); - }; - - vector_type[sol::meta_function::to_string] = [](const vector& a) - { - return utils::string::va("{x: %f, y: %f, z: %f}", a.get_x(), a.get_y(), a.get_z()); - }; - - vector_type["normalize"] = [](const vector& a) - { - return normalize_vector(a); - }; - } - - void setup_entity_type(sol::state& state, event_handler& handler, scheduler& scheduler) - { - state["level"] = entity{*game::levelEntityId}; - - auto entity_type = state.new_usertype("entity"); - - for (const auto& func : method_map) - { - const auto name = utils::string::to_lower(func.first); - entity_type[name.data()] = [name](const entity& entity, const sol::this_state s, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - return convert(s, entity.call(name, arguments)); - }; - } - - entity_type["set"] = [](const entity& entity, const std::string& field, - const sol::lua_value& value) - { - entity.set(field, convert(value)); - }; - - entity_type["get"] = [](const entity& entity, const sol::this_state s, const std::string& field) - { - return convert(s, entity.get(field)); - }; - - entity_type["notify"] = [](const entity& entity, const sol::this_state s, const std::string& event, - sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - notify(entity, event, arguments); - }; - - entity_type["onnotify"] = [&handler](const entity& entity, const std::string& event, - const event_callback& callback) - { - event_listener listener{}; - listener.callback = callback; - listener.entity = entity; - listener.event = event; - listener.is_volatile = false; - - return handler.add_event_listener(std::move(listener)); - }; - - entity_type["onnotifyonce"] = [&handler](const entity& entity, const std::string& event, - const event_callback& callback) - { - event_listener listener{}; - listener.callback = callback; - listener.entity = entity; - listener.event = event; - listener.is_volatile = true; - - return handler.add_event_listener(std::move(listener)); - }; - - entity_type["call"] = [](const entity& entity, const sol::this_state s, const std::string& function, - sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - return convert(s, entity.call(function, arguments)); - }; - - entity_type[sol::meta_function::new_index] = [](const entity& entity, const std::string& field, - const sol::lua_value& value) - { - entity.set(field, convert(value)); - }; - - entity_type[sol::meta_function::index] = [](const entity& entity, const sol::this_state s, const std::string& field) - { - return convert(s, entity.get(field)); - }; - - entity_type["getstruct"] = [](const entity& entity, const sol::this_state s) - { - const auto id = entity.get_entity_id(); - return scripting::lua::entity_to_struct(s, id); - }; - - entity_type["struct"] = sol::property([](const entity& entity, const sol::this_state s) - { - const auto id = entity.get_entity_id(); - return scripting::lua::entity_to_struct(s, id); - }); - - entity_type["scriptcall"] = [](const entity& entity, const sol::this_state s, const std::string& filename, - const std::string function, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - return convert(s, call_script_function(entity, filename, function, arguments)); - }; - - struct game - { - }; - auto game_type = state.new_usertype("game_"); - state["game"] = game(); - - for (const auto& func : function_map) - { - const auto name = utils::string::to_lower(func.first); - game_type[name] = [name](const game&, const sol::this_state s, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - return convert(s, call(name, arguments)); - }; - } - - game_type["call"] = [](const game&, const sol::this_state s, const std::string& function, - sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - return convert(s, call(function, arguments)); - }; - - game_type["ontimeout"] = [&scheduler](const game&, const sol::protected_function& callback, - const long long milliseconds) - { - return scheduler.add(callback, milliseconds, true); - }; - - game_type["oninterval"] = [&scheduler](const game&, const sol::protected_function& callback, - const long long milliseconds) - { - return scheduler.add(callback, milliseconds, false); - }; - - game_type["executecommand"] = [](const game&, const std::string& command) - { - command::execute(command, false); - }; - - game_type["onplayerdamage"] = [](const game&, const sol::protected_function& callback) - { - logfile::add_player_damage_callback(callback); - }; - - game_type["onplayerkilled"] = [](const game&, const sol::protected_function& callback) - { - logfile::add_player_killed_callback(callback); - }; - - game_type["getgamevar"] = [](const sol::this_state s) - { - const auto value = ::game::scr_VarGlob->childVariableValue[*::game::gameEntityId]; - - ::game::VariableValue variable{}; - variable.type = value.type; - variable.u.uintValue = value.u.u.uintValue; - - return convert(s, variable); - }; - - game_type["getfunctions"] = [entity_type](const game&, const sol::this_state s, const std::string& filename) - { - if (scripting::script_function_table.find(filename) == scripting::script_function_table.end()) - { - throw std::runtime_error("File '" + filename + "' not found"); - } - - auto functions = sol::table::create(s.lua_state()); - - for (const auto& function : scripting::script_function_table[filename]) - { - functions[function.first] = sol::overload( - [filename, function](const entity& entity, const sol::this_state s, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - gsl::finally(&logfile::enable_vm_execute_hook); - logfile::disable_vm_execute_hook(); - - return convert(s, call_script_function(entity, filename, function.first, arguments)); - }, - [filename, function](const sol::this_state s, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - gsl::finally(&logfile::enable_vm_execute_hook); - logfile::disable_vm_execute_hook(); - - return convert(s, call_script_function(*::game::levelEntityId, filename, function.first, arguments)); - } - ); - } - - return functions; - }; - - game_type["scriptcall"] = [](const game&, const sol::this_state s, const std::string& filename, - const std::string function, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - gsl::finally(&logfile::enable_vm_execute_hook); - logfile::disable_vm_execute_hook(); - - return convert(s, call_script_function(*::game::levelEntityId, filename, function, arguments)); - }; - - game_type["detour"] = [](const game&, const sol::this_state s, const std::string& filename, - const std::string function_name, const sol::protected_function& function) - { - const auto pos = get_function_pos(filename, function_name); - logfile::vm_execute_hooks[pos] = function; - - auto detour = sol::table::create(function.lua_state()); - - detour["disable"] = [pos]() - { - logfile::vm_execute_hooks.erase(pos); - }; - - detour["enable"] = [pos, function]() - { - logfile::vm_execute_hooks[pos] = function; - }; - - detour["invoke"] = sol::overload( - [filename, function_name](const entity& entity, const sol::this_state s, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - gsl::finally(&logfile::enable_vm_execute_hook); - logfile::disable_vm_execute_hook(); - - return convert(s, call_script_function(entity, filename, function_name, arguments)); - }, - [filename, function_name](const sol::this_state s, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - gsl::finally(&logfile::enable_vm_execute_hook); - logfile::disable_vm_execute_hook(); - - return convert(s, call_script_function(*::game::levelEntityId, filename, function_name, arguments)); - } - ); - - return detour; - }; - } - } - - context::context(std::string folder) - : folder_(std::move(folder)) - , scheduler_(state_) - , event_handler_(state_) - - { - this->state_.open_libraries(sol::lib::base, - sol::lib::package, - sol::lib::io, - sol::lib::string, - sol::lib::os, - sol::lib::math, - sol::lib::table); - - this->state_["include"] = [this](const std::string& file) - { - this->load_script(file); - }; - - sol::function old_require = this->state_["require"]; - auto base_path = utils::string::replace(this->folder_, "/", ".") + "."; - this->state_["require"] = [base_path, old_require](const std::string& path) - { - return old_require(base_path + path); - }; - - this->state_["scriptdir"] = [this]() - { - return this->folder_; - }; - - setup_io(this->state_); - setup_vector_type(this->state_); - setup_entity_type(this->state_, this->event_handler_, this->scheduler_); - - printf("Loading script '%s'\n", this->folder_.data()); - this->load_script("__init__"); - } - - context::~context() - { - this->collect_garbage(); - this->scheduler_.clear(); - this->event_handler_.clear(); - this->state_ = {}; - } - - void context::run_frame() - { - this->scheduler_.run_frame(); - this->collect_garbage(); - } - - void context::notify(const event& e) - { - this->scheduler_.dispatch(e); - this->event_handler_.dispatch(e); - } - - void context::collect_garbage() - { - this->state_.collect_garbage(); - } - - void context::load_script(const std::string& script) - { - if (!this->loaded_scripts_.emplace(script).second) - { - return; - } - - const auto file = (std::filesystem::path{this->folder_} / (script + ".lua")).generic_string(); - handle_error(this->state_.safe_script_file(file, &sol::script_pass_on_error)); - } -} diff --git a/src/client/game/scripting/lua/context.hpp b/src/client/game/scripting/lua/context.hpp deleted file mode 100644 index 79a5e905..00000000 --- a/src/client/game/scripting/lua/context.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "../event.hpp" - -#pragma warning(push) -#pragma warning(disable: 4702) - -#define SOL_ALL_SAFETIES_ON 1 -#define SOL_PRINT_ERRORS 0 -#include - -#pragma warning(pop) - -#include "scheduler.hpp" -#include "event_handler.hpp" - -namespace scripting::lua -{ - class context - { - public: - context(std::string folder); - ~context(); - - context(context&&) noexcept = delete; - context& operator=(context&&) noexcept = delete; - - context(const context&) = delete; - context& operator=(const context&) = delete; - - void run_frame(); - void notify(const event& e); - void collect_garbage(); - - private: - sol::state state_{}; - std::string folder_; - std::unordered_set loaded_scripts_; - - scheduler scheduler_; - event_handler event_handler_; - - void load_script(const std::string& script); - }; -} diff --git a/src/client/game/scripting/lua/engine.cpp b/src/client/game/scripting/lua/engine.cpp deleted file mode 100644 index 351ad04b..00000000 --- a/src/client/game/scripting/lua/engine.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include "engine.hpp" -#include "context.hpp" - -#include "../execution.hpp" -#include "../../../component/logfile.hpp" -#include "../../../component/game_module.hpp" - -#include - -namespace scripting::lua::engine -{ - namespace - { - auto& get_scripts() - { - static std::vector> scripts{}; - return scripts; - } - - void load_scripts(const std::string& script_dir) - { - if (!utils::io::directory_exists(script_dir)) - { - return; - } - - const auto scripts = utils::io::list_files(script_dir); - - for (const auto& script : scripts) - { - if (std::filesystem::is_directory(script) && utils::io::file_exists(script + "/__init__.lua")) - { - get_scripts().push_back(std::make_unique(script)); - } - } - } - } - - void stop() - { - logfile::clear_callbacks(); - get_scripts().clear(); - } - - void start() - { - // No SP until there is a concept - if (game::environment::is_sp()) - { - return; - } - - stop(); - load_scripts(game_module::get_host_module().get_folder() + "/data/scripts/"); - load_scripts("h1-mod/scripts/"); - load_scripts("data/scripts/"); - } - - void notify(const event& e) - { - for (auto& script : get_scripts()) - { - script->notify(e); - } - } - - void run_frame() - { - for (auto& script : get_scripts()) - { - script->run_frame(); - } - } -} diff --git a/src/client/game/scripting/lua/engine.hpp b/src/client/game/scripting/lua/engine.hpp deleted file mode 100644 index 471316cd..00000000 --- a/src/client/game/scripting/lua/engine.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "../event.hpp" - -namespace scripting::lua::engine -{ - void start(); - void stop(); - void notify(const event& e); - void run_frame(); -} diff --git a/src/client/game/scripting/lua/error.cpp b/src/client/game/scripting/lua/error.cpp deleted file mode 100644 index 935db0f0..00000000 --- a/src/client/game/scripting/lua/error.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include "error.hpp" -#include "../execution.hpp" - -#include "component/console.hpp" - -namespace scripting::lua -{ - namespace - { - void notify_error() - { - try - { - call("iprintln", {"^1Script execution error!"}); - } - catch (...) - { - } - } - } - - void handle_error(const sol::protected_function_result& result) - { - if (!result.valid()) - { - console::error("************** Script execution error **************\n"); - - const sol::error err = result; - console::error("%s\n", err.what()); - - console::error("****************************************************\n"); - - notify_error(); - } - } -} diff --git a/src/client/game/scripting/lua/error.hpp b/src/client/game/scripting/lua/error.hpp deleted file mode 100644 index dab56bee..00000000 --- a/src/client/game/scripting/lua/error.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "context.hpp" - -namespace scripting::lua -{ - void handle_error(const sol::protected_function_result& result); -} diff --git a/src/client/game/scripting/lua/event_handler.cpp b/src/client/game/scripting/lua/event_handler.cpp deleted file mode 100644 index 7121ea63..00000000 --- a/src/client/game/scripting/lua/event_handler.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include "std_include.hpp" -#include "context.hpp" -#include "error.hpp" -#include "value_conversion.hpp" - -namespace scripting::lua -{ - event_handler::event_handler(sol::state& state) - : state_(state) - { - auto event_listener_handle_type = state.new_usertype("event_listener_handle"); - - event_listener_handle_type["clear"] = [this](const event_listener_handle& handle) - { - this->remove(handle); - }; - - event_listener_handle_type["endon"] = [this](const event_listener_handle& handle, const entity& entity, const std::string& event) - { - this->add_endon_condition(handle, entity, event); - }; - } - - void event_handler::dispatch(const event& event) - { - bool has_built_arguments = false; - event_arguments arguments{}; - - callbacks_.access([&](task_list& tasks) - { - this->merge_callbacks(); - this->handle_endon_conditions(event); - - for (auto i = tasks.begin(); i != tasks.end();) - { - if (i->event != event.name || i->entity != event.entity) - { - ++i; - continue; - } - - if (!i->is_deleted) - { - if(!has_built_arguments) - { - has_built_arguments = true; - arguments = this->build_arguments(event); - } - - handle_error(i->callback(sol::as_args(arguments))); - } - - if (i->is_volatile || i->is_deleted) - { - i = tasks.erase(i); - } - else - { - ++i; - } - } - }); - } - - event_listener_handle event_handler::add_event_listener(event_listener&& listener) - { - const uint64_t id = ++this->current_listener_id_; - listener.id = id; - listener.is_deleted = false; - - new_callbacks_.access([&listener](task_list& tasks) - { - tasks.emplace_back(std::move(listener)); - }); - - return {id}; - } - - void event_handler::add_endon_condition(const event_listener_handle& handle, const entity& entity, - const std::string& event) - { - auto merger = [&](task_list& tasks) - { - for(auto& task : tasks) - { - if(task.id == handle.id) - { - task.endon_conditions.emplace_back(entity, event); - } - } - }; - - callbacks_.access([&](task_list& tasks) - { - merger(tasks); - new_callbacks_.access(merger); - }); - } - - void event_handler::clear() - { - callbacks_.access([&](task_list& tasks) - { - new_callbacks_.access([&](task_list& new_tasks) - { - new_tasks.clear(); - tasks.clear(); - }); - }); - } - - void event_handler::remove(const event_listener_handle& handle) - { - auto mask_as_deleted = [&](task_list& tasks) - { - for (auto& task : tasks) - { - if (task.id == handle.id) - { - task.is_deleted = true; - break; - } - } - }; - - callbacks_.access(mask_as_deleted); - new_callbacks_.access(mask_as_deleted); - } - - void event_handler::merge_callbacks() - { - callbacks_.access([&](task_list& tasks) - { - new_callbacks_.access([&](task_list& new_tasks) - { - tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), - std::move_iterator(new_tasks.end())); - new_tasks = {}; - }); - }); - } - - void event_handler::handle_endon_conditions(const event& event) - { - auto deleter = [&](task_list& tasks) - { - for(auto& task : tasks) - { - for(auto& condition : task.endon_conditions) - { - if(condition.first == event.entity && condition.second == event.name) - { - task.is_deleted = true; - break; - } - } - } - }; - - callbacks_.access(deleter); - } - - event_arguments event_handler::build_arguments(const event& event) const - { - event_arguments arguments; - - for (const auto& argument : event.arguments) - { - arguments.emplace_back(convert(this->state_, argument)); - } - - return arguments; - } -} diff --git a/src/client/game/scripting/lua/event_handler.hpp b/src/client/game/scripting/lua/event_handler.hpp deleted file mode 100644 index fc95b704..00000000 --- a/src/client/game/scripting/lua/event_handler.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -namespace scripting::lua -{ - using event_arguments = std::vector; - using event_callback = sol::protected_function; - - class event_listener_handle - { - public: - uint64_t id = 0; - }; - - class event_listener final : public event_listener_handle - { - public: - std::string event = {}; - entity entity{}; - event_callback callback = {}; - bool is_volatile = false; - bool is_deleted = false; - std::vector> endon_conditions{}; - }; - - class event_handler final - { - public: - event_handler(sol::state& state); - - event_handler(event_handler&&) noexcept = delete; - event_handler& operator=(event_handler&&) noexcept = delete; - - event_handler(const scheduler&) = delete; - event_handler& operator=(const event_handler&) = delete; - - void dispatch(const event& event); - - event_listener_handle add_event_listener(event_listener&& listener); - - void clear(); - - private: - sol::state& state_; - std::atomic_int64_t current_listener_id_ = 0; - - using task_list = std::vector; - utils::concurrency::container new_callbacks_; - utils::concurrency::container callbacks_; - - void remove(const event_listener_handle& handle); - void merge_callbacks(); - void handle_endon_conditions(const event& event); - - void add_endon_condition(const event_listener_handle& handle, const entity& entity, const std::string& event); - - event_arguments build_arguments(const event& event) const; - }; -} diff --git a/src/client/game/scripting/lua/scheduler.cpp b/src/client/game/scripting/lua/scheduler.cpp deleted file mode 100644 index 1afb7df2..00000000 --- a/src/client/game/scripting/lua/scheduler.cpp +++ /dev/null @@ -1,171 +0,0 @@ -#include "std_include.hpp" -#include "context.hpp" -#include "error.hpp" - -namespace scripting::lua -{ - scheduler::scheduler(sol::state& state) - { - auto task_handle_type = state.new_usertype("task_handle"); - - task_handle_type["clear"] = [this](const task_handle& handle) - { - this->remove(handle); - }; - - task_handle_type["endon"] = [this](const task_handle& handle, const entity& entity, const std::string& event) - { - this->add_endon_condition(handle, entity, event); - }; - } - - void scheduler::dispatch(const event& event) - { - auto deleter = [&](task_list& tasks) - { - for(auto& task : tasks) - { - for(auto& condition : task.endon_conditions) - { - if(condition.first == event.entity && condition.second == event.name) - { - task.is_deleted = true; - break; - } - } - } - }; - - callbacks_.access([&](task_list& tasks) - { - deleter(tasks); - new_callbacks_.access(deleter); - }); - } - - void scheduler::run_frame() - { - callbacks_.access([&](task_list& tasks) - { - this->merge_callbacks(); - - for (auto i = tasks.begin(); i != tasks.end();) - { - const auto now = std::chrono::high_resolution_clock::now(); - const auto diff = now - i->last_call; - - if (diff < i->delay) - { - ++i; - continue; - } - - i->last_call = now; - - if (!i->is_deleted) - { - handle_error(i->callback()); - } - - if (i->is_volatile || i->is_deleted) - { - i = tasks.erase(i); - } - else - { - ++i; - } - } - }); - } - - void scheduler::clear() - { - callbacks_.access([&](task_list& tasks) - { - new_callbacks_.access([&](task_list& new_tasks) - { - new_tasks.clear(); - tasks.clear(); - }); - }); - } - - task_handle scheduler::add(const sol::protected_function& callback, const long long milliseconds, - const bool is_volatile) - { - return this->add(callback, std::chrono::milliseconds(milliseconds), is_volatile); - } - - task_handle scheduler::add(const sol::protected_function& callback, const std::chrono::milliseconds delay, - const bool is_volatile) - { - const uint64_t id = ++this->current_task_id_; - - task task; - task.is_volatile = is_volatile; - task.callback = callback; - task.delay = delay; - task.last_call = std::chrono::steady_clock::now(); - task.id = id; - task.is_deleted = false; - - new_callbacks_.access([&task](task_list& tasks) - { - tasks.emplace_back(std::move(task)); - }); - - return {id}; - } - - void scheduler::add_endon_condition(const task_handle& handle, const entity& entity, const std::string& event) - { - auto merger = [&](task_list& tasks) - { - for(auto& task : tasks) - { - if(task.id == handle.id) - { - task.endon_conditions.emplace_back(entity, event); - } - } - }; - - callbacks_.access([&](task_list& tasks) - { - merger(tasks); - new_callbacks_.access(merger); - }); - } - - void scheduler::remove(const task_handle& handle) - { - auto mask_as_deleted = [&](task_list& tasks) - { - for (auto& task : tasks) - { - if (task.id == handle.id) - { - task.is_deleted = true; - break; - } - } - }; - - callbacks_.access(mask_as_deleted); - new_callbacks_.access(mask_as_deleted); - } - - void scheduler::merge_callbacks() - { - callbacks_.access([&](task_list& tasks) - { - new_callbacks_.access([&](task_list& new_tasks) - { - tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), - std::move_iterator(new_tasks.end())); - new_tasks = {}; - }); - }); - } -} diff --git a/src/client/game/scripting/lua/scheduler.hpp b/src/client/game/scripting/lua/scheduler.hpp deleted file mode 100644 index 17c90797..00000000 --- a/src/client/game/scripting/lua/scheduler.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -#include - -namespace scripting::lua -{ - class context; - - class task_handle - { - public: - uint64_t id = 0; - }; - - class task final : public task_handle - { - public: - std::chrono::steady_clock::time_point last_call{}; - sol::protected_function callback{}; - std::chrono::milliseconds delay{}; - bool is_volatile = false; - bool is_deleted = false; - std::vector> endon_conditions{}; - }; - - class scheduler final - { - public: - scheduler(sol::state& state); - - scheduler(scheduler&&) noexcept = delete; - scheduler& operator=(scheduler&&) noexcept = delete; - - scheduler(const scheduler&) = delete; - scheduler& operator=(const scheduler&) = delete; - - void dispatch(const event& event); - void run_frame(); - void clear(); - - task_handle add(const sol::protected_function& callback, long long milliseconds, bool is_volatile); - task_handle add(const sol::protected_function& callback, std::chrono::milliseconds delay, bool is_volatile); - - private: - using task_list = std::vector; - utils::concurrency::container new_callbacks_; - utils::concurrency::container callbacks_; - std::atomic_int64_t current_task_id_ = 0; - - void add_endon_condition(const task_handle& handle, const entity& entity, const std::string& event); - - void remove(const task_handle& handle); - void merge_callbacks(); - }; -} diff --git a/src/client/game/scripting/lua/value_conversion.cpp b/src/client/game/scripting/lua/value_conversion.cpp deleted file mode 100644 index 3cc37e20..00000000 --- a/src/client/game/scripting/lua/value_conversion.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#include -#include "value_conversion.hpp" -#include "../functions.hpp" -#include "../execution.hpp" -#include ".../../component/logfile.hpp" - -namespace scripting::lua -{ - namespace - { - struct array_value - { - int index; - script_value value; - }; - - sol::lua_value entity_to_array(lua_State* state, unsigned int id) - { - auto table = sol::table::create(state); - auto metatable = sol::table::create(state); - - std::unordered_map values; - - const auto offset = 0xA000 * (id & 3); - - auto current = game::scr_VarGlob->objectVariableChildren[id].firstChild; - auto idx = 1; - - for (auto i = offset + current; current; i = offset + current) - { - const auto var = game::scr_VarGlob->childVariableValue[i]; - - if (var.type == game::SCRIPT_NONE) - { - current = var.nextSibling; - continue; - } - - const auto string_value = (game::scr_string_t)((unsigned __int8)var.name_lo + (var.k.keys.name_hi << 8)); - const auto* str = game::SL_ConvertToString(string_value); - - std::string key = string_value < 0x40000 && str - ? str - : std::to_string(idx++); - - game::VariableValue variable{}; - variable.type = var.type; - variable.u = var.u.u; - - array_value value; - value.index = i; - value.value = variable; - - values[key] = value; - - current = var.nextSibling; - } - - table["getkeys"] = [values]() - { - std::vector _keys; - - for (const auto& entry : values) - { - _keys.push_back(entry.first); - } - - return _keys; - }; - - metatable[sol::meta_function::new_index] = [values](const sol::table t, const sol::this_state s, - const sol::lua_value& key_value, const sol::lua_value& value) - { - const auto key = key_value.is() - ? std::to_string(key_value.as()) - : key_value.as(); - - if (values.find(key) == values.end()) - { - return; - } - - const auto i = values.at(key).index; - const auto variable = &game::scr_VarGlob->childVariableValue[i]; - - const auto new_variable = convert({s, value}).get_raw(); - - game::AddRefToValue(new_variable.type, new_variable.u); - game::RemoveRefToValue(variable->type, variable->u.u); - - variable->type = (char)new_variable.type; - variable->u.u = new_variable.u; - }; - - metatable[sol::meta_function::index] = [values](const sol::table t, const sol::this_state s, - const sol::lua_value& key_value) - { - const auto key = key_value.is() - ? std::to_string(key_value.as()) - : key_value.as(); - - if (values.find(key) == values.end()) - { - return sol::lua_value{s, sol::lua_nil}; - } - - return convert(s, values.at(key).value); - }; - - metatable[sol::meta_function::length] = [values]() - { - return values.size(); - }; - - table[sol::metatable_key] = metatable; - - return {state, table}; - } - - game::VariableValue convert_function(sol::lua_value value) - { - const auto function = value.as(); - const auto index = reinterpret_cast(logfile::vm_execute_hooks.size()); - - logfile::vm_execute_hooks[index] = function; - - game::VariableValue func; - func.type = game::SCRIPT_FUNCTION; - func.u.codePosValue = index; - - return func; - } - - sol::lua_value convert_function(lua_State* state, const char* pos) - { - return sol::overload( - [pos](const entity& entity, const sol::this_state s, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - return convert(s, exec_ent_thread(entity, pos, arguments)); - }, - [pos](const sol::this_state s, sol::variadic_args va) - { - std::vector arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - return convert(s, exec_ent_thread(*game::levelEntityId, pos, arguments)); - } - ); - } - } - - sol::lua_value entity_to_struct(lua_State* state, unsigned int parent_id) - { - auto table = sol::table::create(state); - auto metatable = sol::table::create(state); - - const auto offset = 64000 * (parent_id & 3); - - metatable[sol::meta_function::new_index] = [offset, parent_id](const sol::table t, const sol::this_state s, - const sol::lua_value& field, const sol::lua_value& value) - { - const auto id = field.is() - ? scripting::find_token_id(field.as()) - : field.as(); - - if (!id) - { - return; - } - - const auto variable_id = game::GetVariable(parent_id, id); - const auto variable = &game::scr_VarGlob->childVariableValue[variable_id + offset]; - const auto new_variable = convert({s, value}).get_raw(); - - game::AddRefToValue(new_variable.type, new_variable.u); - game::RemoveRefToValue(variable->type, variable->u.u); - - variable->type = (char)new_variable.type; - variable->u.u = new_variable.u; - }; - - metatable[sol::meta_function::index] = [offset, parent_id](const sol::table t, const sol::this_state s, - const sol::lua_value& field) - { - const auto id = field.is() - ? scripting::find_token_id(field.as()) - : field.as(); - - if (!id) - { - return sol::lua_value{s, sol::lua_nil}; - } - - const auto variable_id = game::FindVariable(parent_id, id); - if (!variable_id) - { - return sol::lua_value{s, sol::lua_nil}; - } - - const auto variable = game::scr_VarGlob->childVariableValue[variable_id + offset]; - - game::VariableValue result{}; - result.u = variable.u.u; - result.type = (game::scriptType_e)variable.type; - - return convert(s, result); - }; - - table[sol::metatable_key] = metatable; - - return {state, table}; - } - - script_value convert(const sol::lua_value& value) - { - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return convert_function(value); - } - - return {}; - } - - sol::lua_value convert(lua_State* state, const script_value& value) - { - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is>()) - { - return entity_to_struct(state, value.get_raw().u.uintValue); - } - - if (value.is>()) - { - return entity_to_array(state, value.get_raw().u.uintValue); - } - - if (value.is>()) - { - return convert_function(state, value.get_raw().u.codePosValue); - } - - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is()) - { - return {state, value.as()}; - } - - return {state, sol::lua_nil}; - } -} diff --git a/src/client/game/scripting/lua/value_conversion.hpp b/src/client/game/scripting/lua/value_conversion.hpp deleted file mode 100644 index 93256f80..00000000 --- a/src/client/game/scripting/lua/value_conversion.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "context.hpp" - -namespace scripting::lua -{ - sol::lua_value entity_to_struct(lua_State* state, unsigned int parent_id); - - script_value convert(const sol::lua_value& value); - sol::lua_value convert(lua_State* state, const script_value& value); -} diff --git a/src/client/game/scripting/safe_execution.cpp b/src/client/game/scripting/safe_execution.cpp deleted file mode 100644 index 92daa3b7..00000000 --- a/src/client/game/scripting/safe_execution.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include "safe_execution.hpp" - -#pragma warning(push) -#pragma warning(disable: 4611) - -namespace scripting::safe_execution -{ - namespace - { - bool execute_with_seh(const script_function function, const game::scr_entref_t& entref) - { - __try - { - function(entref); - return true; - } - __except (EXCEPTION_EXECUTE_HANDLER) - { - return false; - } - } - } - - bool call(const script_function function, const game::scr_entref_t& entref) - { - *game::g_script_error_level += 1; - if (game::_setjmp(&game::g_script_error[*game::g_script_error_level])) - { - *game::g_script_error_level -= 1; - return false; - } - - const auto result = execute_with_seh(function, entref); - *game::g_script_error_level -= 1; - return result; - } - - bool set_entity_field(const game::scr_entref_t& entref, const int offset) - { - *game::g_script_error_level += 1; - if (game::_setjmp(&game::g_script_error[*game::g_script_error_level])) - { - *game::g_script_error_level -= 1; - return false; - } - - game::Scr_SetObjectField(entref.classnum, entref.entnum, offset); - - *game::g_script_error_level -= 1; - return true; - } - - bool get_entity_field(const game::scr_entref_t& entref, const int offset, game::VariableValue* value) - { - *game::g_script_error_level += 1; - if (game::_setjmp(&game::g_script_error[*game::g_script_error_level])) - { - value->type = game::SCRIPT_NONE; - value->u.intValue = 0; - *game::g_script_error_level -= 1; - return false; - } - - game::GetEntityFieldValue(value, entref.classnum, entref.entnum, offset); - - *game::g_script_error_level -= 1; - return true; - } -} - -#pragma warning(pop) diff --git a/src/client/game/scripting/safe_execution.hpp b/src/client/game/scripting/safe_execution.hpp deleted file mode 100644 index 6eea59d2..00000000 --- a/src/client/game/scripting/safe_execution.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "functions.hpp" - -namespace scripting::safe_execution -{ - bool call(script_function function, const game::scr_entref_t& entref); - - bool set_entity_field(const game::scr_entref_t& entref, int offset); - bool get_entity_field(const game::scr_entref_t& entref, int offset, game::VariableValue* value); -} diff --git a/src/client/game/scripting/script_value.cpp b/src/client/game/scripting/script_value.cpp deleted file mode 100644 index 7d334f17..00000000 --- a/src/client/game/scripting/script_value.cpp +++ /dev/null @@ -1,278 +0,0 @@ -#include -#include "script_value.hpp" -#include "entity.hpp" - - -namespace scripting -{ - /*************************************************************** - * Constructors - **************************************************************/ - - script_value::script_value(const game::VariableValue& value) - : value_(value) - { - } - - script_value::script_value(const int value) - { - game::VariableValue variable{}; - variable.type = game::SCRIPT_INTEGER; - variable.u.intValue = value; - - this->value_ = variable; - } - - script_value::script_value(const unsigned int value) - { - game::VariableValue variable{}; - variable.type = game::SCRIPT_INTEGER; - variable.u.uintValue = value; - - this->value_ = variable; - } - - script_value::script_value(const bool value) - : script_value(static_cast(value)) - { - } - - script_value::script_value(const float value) - { - game::VariableValue variable{}; - variable.type = game::SCRIPT_FLOAT; - variable.u.floatValue = value; - - this->value_ = variable; - } - - script_value::script_value(const double value) - : script_value(static_cast(value)) - { - } - - script_value::script_value(const char* value) - { - game::VariableValue variable{}; - variable.type = game::SCRIPT_STRING; - variable.u.stringValue = game::SL_GetString(value, 0); - - const auto _ = gsl::finally([&variable]() - { - game::RemoveRefToValue(variable.type, variable.u); - }); - - this->value_ = variable; - } - - script_value::script_value(const std::string& value) - : script_value(value.data()) - { - } - - script_value::script_value(const entity& value) - { - game::VariableValue variable{}; - variable.type = game::SCRIPT_OBJECT; - variable.u.pointerValue = value.get_entity_id(); - - this->value_ = variable; - } - - script_value::script_value(const vector& value) - { - game::VariableValue variable{}; - variable.type = game::SCRIPT_VECTOR; - variable.u.vectorValue = game::Scr_AllocVector(value); - - const auto _ = gsl::finally([&variable]() - { - game::RemoveRefToValue(variable.type, variable.u); - }); - - this->value_ = variable; - } - - /*************************************************************** - * Integer - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().type == game::SCRIPT_INTEGER; - } - - template <> - bool script_value::is() const - { - return this->is(); - } - - template <> - bool script_value::is() const - { - return this->is(); - } - - template <> - int script_value::get() const - { - return this->get_raw().u.intValue; - } - - template <> - unsigned int script_value::get() const - { - return this->get_raw().u.uintValue; - } - - template <> - bool script_value::get() const - { - return this->get_raw().u.uintValue != 0; - } - - /*************************************************************** - * Float - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().type == game::SCRIPT_FLOAT; - } - - template <> - bool script_value::is() const - { - return this->is(); - } - - template <> - float script_value::get() const - { - return this->get_raw().u.floatValue; - } - - template <> - double script_value::get() const - { - return static_cast(this->get_raw().u.floatValue); - } - - /*************************************************************** - * String - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().type == game::SCRIPT_STRING; - } - - template <> - bool script_value::is() const - { - return this->is(); - } - - template <> - const char* script_value::get() const - { - return game::SL_ConvertToString(static_cast(this->get_raw().u.stringValue)); - } - - template <> - std::string script_value::get() const - { - return this->get(); - } - - /*************************************************************** - * Array - **************************************************************/ - - template <> - bool script_value::is>() const - { - if (this->get_raw().type != game::SCRIPT_OBJECT) - { - return false; - } - - const auto id = this->get_raw().u.uintValue; - const auto type = game::scr_VarGlob->objectVariableValue[id].w.type; - - return type == game::SCRIPT_ARRAY; - } - - /*************************************************************** - * Struct - **************************************************************/ - - template <> - bool script_value::is>() const - { - if (this->get_raw().type != game::SCRIPT_OBJECT) - { - return false; - } - - const auto id = this->get_raw().u.uintValue; - const auto type = game::scr_VarGlob->objectVariableValue[id].w.type; - - return type == game::SCRIPT_STRUCT; - } - - /*************************************************************** - * Function - **************************************************************/ - - template <> - bool script_value::is>() const - { - return this->get_raw().type == game::SCRIPT_FUNCTION; - } - - /*************************************************************** - * Entity - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().type == game::SCRIPT_OBJECT; - } - - template <> - entity script_value::get() const - { - return entity(this->get_raw().u.pointerValue); - } - - /*************************************************************** - * Vector - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().type == game::SCRIPT_VECTOR; - } - - template <> - vector script_value::get() const - { - return this->get_raw().u.vectorValue; - } - - /*************************************************************** - * - **************************************************************/ - - const game::VariableValue& script_value::get_raw() const - { - return this->value_.get(); - } -} diff --git a/src/client/game/scripting/script_value.hpp b/src/client/game/scripting/script_value.hpp deleted file mode 100644 index df8a95b6..00000000 --- a/src/client/game/scripting/script_value.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once -#include "game/game.hpp" -#include "variable_value.hpp" -#include "vector.hpp" - -namespace scripting -{ - class entity; - - class script_value - { - public: - script_value() = default; - script_value(const game::VariableValue& value); - - script_value(int value); - script_value(unsigned int value); - script_value(bool value); - - script_value(float value); - script_value(double value); - - script_value(const char* value); - script_value(const std::string& value); - - script_value(const entity& value); - - script_value(const vector& value); - - template - bool is() const; - - template - T as() const - { - if (!this->is()) - { - throw std::runtime_error("Invalid type"); - } - - return get(); - } - - const game::VariableValue& get_raw() const; - - private: - template - T get() const; - - variable_value value_{}; - }; -} diff --git a/src/client/game/scripting/stack_isolation.cpp b/src/client/game/scripting/stack_isolation.cpp deleted file mode 100644 index 646e2584..00000000 --- a/src/client/game/scripting/stack_isolation.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include "stack_isolation.hpp" - -namespace scripting -{ - stack_isolation::stack_isolation() - { - this->in_param_count_ = game::scr_VmPub->inparamcount; - this->out_param_count_ = game::scr_VmPub->outparamcount; - this->top_ = game::scr_VmPub->top; - this->max_stack_ = game::scr_VmPub->maxstack; - - game::scr_VmPub->top = this->stack_; - game::scr_VmPub->maxstack = &this->stack_[ARRAYSIZE(this->stack_) - 1]; - game::scr_VmPub->inparamcount = 0; - game::scr_VmPub->outparamcount = 0; - } - - stack_isolation::~stack_isolation() - { - game::Scr_ClearOutParams(); - game::scr_VmPub->inparamcount = this->in_param_count_; - game::scr_VmPub->outparamcount = this->out_param_count_; - game::scr_VmPub->top = this->top_; - game::scr_VmPub->maxstack = this->max_stack_; - } -} diff --git a/src/client/game/scripting/stack_isolation.hpp b/src/client/game/scripting/stack_isolation.hpp deleted file mode 100644 index 8dffd4bc..00000000 --- a/src/client/game/scripting/stack_isolation.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include "game/game.hpp" - -namespace scripting -{ - class stack_isolation final - { - public: - stack_isolation(); - ~stack_isolation(); - - stack_isolation(stack_isolation&&) = delete; - stack_isolation(const stack_isolation&) = delete; - stack_isolation& operator=(stack_isolation&&) = delete; - stack_isolation& operator=(const stack_isolation&) = delete; - - private: - game::VariableValue stack_[512]{}; - - game::VariableValue* max_stack_; - game::VariableValue* top_; - unsigned int in_param_count_; - unsigned int out_param_count_; - }; -} diff --git a/src/client/game/scripting/variable_value.cpp b/src/client/game/scripting/variable_value.cpp deleted file mode 100644 index 69a20023..00000000 --- a/src/client/game/scripting/variable_value.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include "variable_value.hpp" - -namespace scripting -{ - variable_value::variable_value(const game::VariableValue& value) - { - this->assign(value); - } - - variable_value::variable_value(const variable_value& other) noexcept - { - this->operator=(other); - } - - variable_value::variable_value(variable_value&& other) noexcept - { - this->operator=(std::move(other)); - } - - variable_value& variable_value::operator=(const variable_value& other) noexcept - { - if (this != &other) - { - this->release(); - this->assign(other.value_); - } - - return *this; - } - - variable_value& variable_value::operator=(variable_value&& other) noexcept - { - if (this != &other) - { - this->release(); - this->value_ = other.value_; - other.value_.type = game::SCRIPT_NONE; - } - - return *this; - } - - variable_value::~variable_value() - { - this->release(); - } - - const game::VariableValue& variable_value::get() const - { - return this->value_; - } - - void variable_value::assign(const game::VariableValue& value) - { - this->value_ = value; - game::AddRefToValue(this->value_.type, this->value_.u); - } - - void variable_value::release() - { - if (this->value_.type != game::SCRIPT_NONE) - { - game::RemoveRefToValue(this->value_.type, this->value_.u); - this->value_.type = game::SCRIPT_NONE; - } - } -} diff --git a/src/client/game/scripting/variable_value.hpp b/src/client/game/scripting/variable_value.hpp deleted file mode 100644 index 7a962612..00000000 --- a/src/client/game/scripting/variable_value.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include "game/game.hpp" - -namespace scripting -{ - class variable_value - { - public: - variable_value() = default; - variable_value(const game::VariableValue& value); - variable_value(const variable_value& other) noexcept; - variable_value(variable_value&& other) noexcept; - - variable_value& operator=(const variable_value& other) noexcept; - variable_value& operator=(variable_value&& other) noexcept; - - ~variable_value(); - - const game::VariableValue& get() const; - - private: - void assign(const game::VariableValue& value); - void release(); - - game::VariableValue value_{{0}, game::SCRIPT_NONE}; - }; -} diff --git a/src/client/game/scripting/vector.cpp b/src/client/game/scripting/vector.cpp deleted file mode 100644 index e3b66dcd..00000000 --- a/src/client/game/scripting/vector.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include "vector.hpp" - -namespace scripting -{ - vector::vector(const float* value) - { - for (auto i = 0; i < 3; ++i) - { - this->value_[i] = value[i]; - } - } - - vector::vector(const game::vec3_t& value) - : vector(&value[0]) - { - } - - vector::vector(const float x, const float y, const float z) - { - this->value_[0] = x; - this->value_[1] = y; - this->value_[2] = z; - } - - vector::operator game::vec3_t&() - { - return this->value_; - } - - vector::operator const game::vec3_t&() const - { - return this->value_; - } - - game::vec_t& vector::operator[](const size_t i) - { - if (i >= 3) - { - throw std::runtime_error("Out of bounds."); - } - - return this->value_[i]; - } - - const game::vec_t& vector::operator[](const size_t i) const - { - if (i >= 3) - { - throw std::runtime_error("Out of bounds."); - } - - return this->value_[i]; - } - - float vector::get_x() const - { - return this->operator[](0); - } - - float vector::get_y() const - { - return this->operator[](1); - } - - float vector::get_z() const - { - return this->operator[](2); - } - - void vector::set_x(const float value) - { - this->operator[](0) = value; - } - - void vector::set_y(const float value) - { - this->operator[](1) = value; - } - - void vector::set_z(const float value) - { - this->operator[](2) = value; - } -} diff --git a/src/client/game/scripting/vector.hpp b/src/client/game/scripting/vector.hpp deleted file mode 100644 index 70b146d6..00000000 --- a/src/client/game/scripting/vector.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include "game/game.hpp" - -namespace scripting -{ - class vector final - { - public: - vector() = default; - vector(const float* value); - vector(const game::vec3_t& value); - vector(float x, float y, float z); - - operator game::vec3_t&(); - operator const game::vec3_t&() const; - - game::vec_t& operator[](size_t i); - const game::vec_t& operator[](size_t i) const; - - float get_x() const; - float get_y() const; - float get_z() const; - - void set_x(float value); - void set_y(float value); - void set_z(float value); - - private: - game::vec3_t value_{0}; - }; -} diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 01c5cadd..283e7cb8 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -27,6 +27,8 @@ namespace game WEAK symbol AimAssist_AddToTargetList{0, 0x9D0F0}; + WEAK symbol dwGetLogOnStatus{ 0, 0x14053CCB0 }; // S1 + WEAK symbol BG_GetWeaponNameComplete{0x430550, 0x1F9670}; diff --git a/src/client/game/ui_scripting/execution.cpp b/src/client/game/ui_scripting/execution.cpp deleted file mode 100644 index fff6b88e..00000000 --- a/src/client/game/ui_scripting/execution.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include "execution.hpp" -#include "component/ui_scripting.hpp" - -#include - -namespace ui_scripting -{ - void push_value(const script_value& value) - { - const auto state = *game::hks::lua_state; - const auto value_ = value.get_raw(); - *state->m_apistack.top = value_; - state->m_apistack.top++; - } - - script_value get_return_value(int offset) - { - const auto state = *game::hks::lua_state; - return state->m_apistack.top[-1 - offset]; - } - - arguments get_return_values(int count) - { - arguments values; - - for (auto i = count - 1; i >= 0; i--) - { - values.push_back(get_return_value(i)); - } - - if (values.size() == 0) - { - values.push_back({}); - } - - return values; - } - - arguments call_script_function(const function& function, const arguments& arguments) - { - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - push_value(function); - for (auto i = arguments.begin(); i != arguments.end(); ++i) - { - push_value(*i); - } - - const auto _1 = gsl::finally(&disable_error_hook); - enable_error_hook(); - - try - { - game::hks::vm_call_internal(state, static_cast(arguments.size()), -1, 0); - const auto count = static_cast(state->m_apistack.top - state->m_apistack.base); - return get_return_values(count); - } - catch (const std::exception& e) - { - throw std::runtime_error(std::string("Error executing script function: ") + e.what()); - } - } - - script_value get_field(const userdata& self, const script_value& key) - { - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - push_value(key); - - const auto _1 = gsl::finally(&disable_error_hook); - enable_error_hook(); - - game::hks::HksObject value{}; - game::hks::HksObject userdata{}; - userdata.t = game::hks::TUSERDATA; - userdata.v.ptr = self.ptr; - - try - { - game::hks::hks_obj_gettable(&value, state, &userdata, &state->m_apistack.top[-1]); - return value; - } - catch (const std::exception& e) - { - throw std::runtime_error(std::string("Error getting userdata field: ") + e.what()); - } - } - - script_value get_field(const table& self, const script_value& key) - { - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - push_value(key); - - const auto _1 = gsl::finally(&disable_error_hook); - enable_error_hook(); - - game::hks::HksObject value{}; - game::hks::HksObject userdata{}; - userdata.t = game::hks::TTABLE; - userdata.v.ptr = self.ptr; - - try - { - game::hks::hks_obj_gettable(&value, state, &userdata, &state->m_apistack.top[-1]); - return value; - } - catch (const std::exception& e) - { - throw std::runtime_error(std::string("Error getting table field: ") + e.what()); - } - } - - void set_field(const userdata& self, const script_value& key, const script_value& value) - { - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - const auto _1 = gsl::finally(&disable_error_hook); - enable_error_hook(); - - game::hks::HksObject userdata{}; - userdata.t = game::hks::TUSERDATA; - userdata.v.ptr = self.ptr; - - try - { - game::hks::hks_obj_settable(state, &userdata, &key.get_raw(), &value.get_raw()); - } - catch (const std::exception& e) - { - throw std::runtime_error(std::string("Error setting userdata field: ") + e.what()); - } - } - - void set_field(const table& self, const script_value& key, const script_value& value) - { - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - const auto _1 = gsl::finally(&disable_error_hook); - enable_error_hook(); - - game::hks::HksObject userdata{}; - userdata.t = game::hks::TTABLE; - userdata.v.ptr = self.ptr; - - try - { - game::hks::hks_obj_settable(state, &userdata, &key.get_raw(), &value.get_raw()); - } - catch (const std::exception& e) - { - throw std::runtime_error(std::string("Error setting table field: ") + e.what()); - } - } -} diff --git a/src/client/game/ui_scripting/execution.hpp b/src/client/game/ui_scripting/execution.hpp deleted file mode 100644 index 24f4dd72..00000000 --- a/src/client/game/ui_scripting/execution.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include "game/game.hpp" -#include "types.hpp" -#include "script_value.hpp" - -namespace ui_scripting -{ - void push_value(const script_value& value); - script_value get_return_value(int offset); - arguments get_return_values(int count); - - arguments call_script_function(const function& function, const arguments& arguments); - - script_value get_field(const userdata& self, const script_value& key); - script_value get_field(const table& self, const script_value& key); - void set_field(const userdata& self, const script_value& key, const script_value& value); - void set_field(const table& self, const script_value& key, const script_value& value); -} diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp deleted file mode 100644 index afa00d5d..00000000 --- a/src/client/game/ui_scripting/lua/context.cpp +++ /dev/null @@ -1,239 +0,0 @@ -#include -#include "context.hpp" -#include "error.hpp" -#include "value_conversion.hpp" -#include "../script_value.hpp" -#include "../execution.hpp" - -#include "../../../component/ui_scripting.hpp" -#include "../../../component/command.hpp" -#include "../../../component/updater.hpp" - -#include "component/game_console.hpp" -#include "component/scheduler.hpp" - -#include -#include -#include - -namespace ui_scripting::lua -{ - namespace - { - void setup_types(sol::state& state, scheduler& scheduler) - { - struct game - { - }; - auto game_type = state.new_usertype("game_"); - state["game"] = game(); - - game_type["ontimeout"] = [&scheduler](const game&, const sol::protected_function& callback, - const long long milliseconds) - { - return scheduler.add(callback, milliseconds, true); - }; - - game_type["oninterval"] = [&scheduler](const game&, const sol::protected_function& callback, - const long long milliseconds) - { - return scheduler.add(callback, milliseconds, false); - }; - - auto userdata_type = state.new_usertype("userdata_"); - - userdata_type["new"] = sol::property( - [](const userdata& userdata, const sol::this_state s) - { - return convert(s, userdata.get("new")); - }, - [](const userdata& userdata, const sol::this_state s, const sol::lua_value& value) - { - userdata.set("new", convert({s, value})); - } - ); - - - userdata_type["get"] = [](const userdata& userdata, const sol::this_state s, - const sol::lua_value& key) - { - return convert(s, userdata.get(convert({s, key}))); - }; - - userdata_type["set"] = [](const userdata& userdata, const sol::this_state s, - const sol::lua_value& key, const sol::lua_value& value) - { - userdata.set(convert({s, key}), convert({s, value})); - }; - - userdata_type[sol::meta_function::index] = [](const userdata& userdata, const sol::this_state s, - const sol::lua_value& key) - { - return convert(s, userdata.get(convert({s, key}))); - }; - - userdata_type[sol::meta_function::new_index] = [](const userdata& userdata, const sol::this_state s, - const sol::lua_value& key, const sol::lua_value& value) - { - userdata.set(convert({s, key}), convert({s, value})); - }; - - auto table_type = state.new_usertype
("table_"); - - table_type["new"] = sol::property( - [](const table& table, const sol::this_state s) - { - return convert(s, table.get("new")); - }, - [](const table& table, const sol::this_state s, const sol::lua_value& value) - { - table.set("new", convert({s, value})); - } - ); - - table_type["get"] = [](const table& table, const sol::this_state s, - const sol::lua_value& key) - { - return convert(s, table.get(convert({s, key}))); - }; - - table_type["set"] = [](const table& table, const sol::this_state s, - const sol::lua_value& key, const sol::lua_value& value) - { - table.set(convert({s, key}), convert({s, value})); - }; - - table_type[sol::meta_function::index] = [](const table& table, const sol::this_state s, - const sol::lua_value& key) - { - return convert(s, table.get(convert({s, key}))); - }; - - table_type[sol::meta_function::new_index] = [](const table& table, const sol::this_state s, - const sol::lua_value& key, const sol::lua_value& value) - { - table.set(convert({s, key}), convert({s, value})); - }; - - auto function_type = state.new_usertype("function_"); - - function_type[sol::meta_function::call] = [](const function& function, const sol::this_state s, sol::variadic_args va) - { - arguments arguments{}; - - for (auto arg : va) - { - arguments.push_back(convert({s, arg})); - } - - const auto values = function.call(arguments); - std::vector returns; - - for (const auto& value : values) - { - returns.push_back(convert(s, value)); - } - - return sol::as_returns(returns); - }; - - state["luiglobals"] = table((*::game::hks::lua_state)->globals.v.table); - state["CoD"] = state["luiglobals"]["CoD"]; - state["LUI"] = state["luiglobals"]["LUI"]; - state["Engine"] = state["luiglobals"]["Engine"]; - state["Game"] = state["luiglobals"]["Game"]; - - auto updater_table = sol::table::create(state.lua_state()); - - updater_table["relaunch"] = updater::relaunch; - - updater_table["sethastriedupdate"] = updater::set_has_tried_update; - updater_table["gethastriedupdate"] = updater::get_has_tried_update; - updater_table["autoupdatesenabled"] = updater::auto_updates_enabled; - - updater_table["startupdatecheck"] = updater::start_update_check; - updater_table["isupdatecheckdone"] = updater::is_update_check_done; - updater_table["getupdatecheckstatus"] = updater::get_update_check_status; - updater_table["isupdateavailable"] = updater::is_update_available; - - updater_table["startupdatedownload"] = updater::start_update_download; - updater_table["isupdatedownloaddone"] = updater::is_update_download_done; - updater_table["getupdatedownloadstatus"] = updater::get_update_download_status; - updater_table["cancelupdate"] = updater::cancel_update; - updater_table["isrestartrequired"] = updater::is_restart_required; - - updater_table["getlasterror"] = updater::get_last_error; - updater_table["getcurrentfile"] = updater::get_current_file; - - state["updater"] = updater_table; - } - } - - context::context(std::string data, script_type type) - : scheduler_(state_) - { - this->state_.open_libraries(sol::lib::base, - sol::lib::package, - sol::lib::io, - sol::lib::string, - sol::lib::os, - sol::lib::math, - sol::lib::table); - - setup_types(this->state_, this->scheduler_); - - if (type == script_type::file) - { - this->folder_ = data; - - this->state_["include"] = [this](const std::string& file) - { - this->load_script(file); - }; - - sol::function old_require = this->state_["require"]; - auto base_path = utils::string::replace(this->folder_, "/", ".") + "."; - this->state_["require"] = [base_path, old_require](const std::string& path) - { - return old_require(base_path + path); - }; - - this->state_["scriptdir"] = [this]() - { - return this->folder_; - }; - - printf("Loading ui script '%s'\n", this->folder_.data()); - this->load_script("__init__"); - } - - if (type == script_type::code) - { - handle_error(this->state_.safe_script(data, &sol::script_pass_on_error)); - } - } - - context::~context() - { - this->state_.collect_garbage(); - this->scheduler_.clear(); - this->state_ = {}; - } - - void context::run_frame() - { - this->scheduler_.run_frame(); - this->state_.collect_garbage(); - } - - void context::load_script(const std::string& script) - { - if (!this->loaded_scripts_.emplace(script).second) - { - return; - } - - const auto file = (std::filesystem::path{this->folder_} / (script + ".lua")).generic_string(); - handle_error(this->state_.safe_script_file(file, &sol::script_pass_on_error)); - } -} diff --git a/src/client/game/ui_scripting/lua/context.hpp b/src/client/game/ui_scripting/lua/context.hpp deleted file mode 100644 index 866c601e..00000000 --- a/src/client/game/ui_scripting/lua/context.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#pragma warning(push) -#pragma warning(disable: 4702) - -#define SOL_ALL_SAFETIES_ON 1 -#define SOL_PRINT_ERRORS 0 -#include - -#include "scheduler.hpp" - -namespace ui_scripting::lua -{ - enum script_type - { - file, - code - }; - - class context - { - public: - context(std::string folder, script_type type); - ~context(); - - context(context&&) noexcept = delete; - context& operator=(context&&) noexcept = delete; - - context(const context&) = delete; - context& operator=(const context&) = delete; - - void run_frame(); - - private: - sol::state state_{}; - std::string folder_; - std::unordered_set loaded_scripts_; - - scheduler scheduler_; - - void load_script(const std::string& script); - }; -} diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp deleted file mode 100644 index 93713530..00000000 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include "engine.hpp" -#include "context.hpp" - -#include "../../../component/ui_scripting.hpp" -#include "../../../component/game_module.hpp" - -#include - -namespace ui_scripting::lua::engine -{ - namespace - { - const auto lui_common = utils::nt::load_resource(LUI_COMMON); - const auto lui_updater = utils::nt::load_resource(LUI_UPDATER); - - auto& get_scripts() - { - static std::vector> scripts{}; - return scripts; - } - - void load_scripts(const std::string& script_dir) - { - if (!utils::io::directory_exists(script_dir)) - { - return; - } - - const auto scripts = utils::io::list_files(script_dir); - - for (const auto& script : scripts) - { - if (std::filesystem::is_directory(script) && utils::io::file_exists(script + "/__init__.lua")) - { - get_scripts().push_back(std::make_unique(script, script_type::file)); - } - } - } - - void load_code(const std::string& code) - { - get_scripts().push_back(std::make_unique(code, script_type::code)); - } - } - - void start() - { - clear_converted_functions(); - get_scripts().clear(); - - load_code(lui_common); - load_code(lui_updater); - - load_scripts(game_module::get_host_module().get_folder() + "/data/ui_scripts/"); - load_scripts("h1-mod/ui_scripts/"); - load_scripts("data/ui_scripts/"); - } - - void stop() - { - clear_converted_functions(); - get_scripts().clear(); - } - - void run_frame() - { - for (auto& script : get_scripts()) - { - script->run_frame(); - } - } -} diff --git a/src/client/game/ui_scripting/lua/engine.hpp b/src/client/game/ui_scripting/lua/engine.hpp deleted file mode 100644 index bbcf427c..00000000 --- a/src/client/game/ui_scripting/lua/engine.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -namespace ui_scripting::lua::engine -{ - void start(); - void stop(); - void run_frame(); -} diff --git a/src/client/game/ui_scripting/lua/error.cpp b/src/client/game/ui_scripting/lua/error.cpp deleted file mode 100644 index d13b4896..00000000 --- a/src/client/game/ui_scripting/lua/error.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "error.hpp" - -namespace ui_scripting::lua -{ - void handle_error(const sol::protected_function_result& result) - { - if (!result.valid()) - { - printf("************** UI Script execution error **************\n"); - - const sol::error err = result; - printf("%s\n", err.what()); - - printf("****************************************************\n"); - } - } -} diff --git a/src/client/game/ui_scripting/lua/error.hpp b/src/client/game/ui_scripting/lua/error.hpp deleted file mode 100644 index 28a5c453..00000000 --- a/src/client/game/ui_scripting/lua/error.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "context.hpp" - -namespace ui_scripting::lua -{ - void handle_error(const sol::protected_function_result& result); -} diff --git a/src/client/game/ui_scripting/lua/scheduler.cpp b/src/client/game/ui_scripting/lua/scheduler.cpp deleted file mode 100644 index 18e779b6..00000000 --- a/src/client/game/ui_scripting/lua/scheduler.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "std_include.hpp" -#include "context.hpp" -#include "error.hpp" - -namespace ui_scripting::lua -{ - scheduler::scheduler(sol::state& state) - { - auto task_handle_type = state.new_usertype("task_handle"); - - task_handle_type["clear"] = [this](const task_handle& handle) - { - this->remove(handle); - }; - } - - void scheduler::run_frame() - { - callbacks_.access([&](task_list& tasks) - { - this->merge_callbacks(); - - for (auto i = tasks.begin(); i != tasks.end();) - { - const auto now = std::chrono::high_resolution_clock::now(); - const auto diff = now - i->last_call; - - if (diff < i->delay) - { - ++i; - continue; - } - - i->last_call = now; - - if (!i->is_deleted) - { - handle_error(i->callback()); - } - - if (i->is_volatile || i->is_deleted) - { - i = tasks.erase(i); - } - else - { - ++i; - } - } - }); - } - - void scheduler::clear() - { - callbacks_.access([&](task_list& tasks) - { - new_callbacks_.access([&](task_list& new_tasks) - { - new_tasks.clear(); - tasks.clear(); - }); - }); - } - - task_handle scheduler::add(const sol::protected_function& callback, const long long milliseconds, - const bool is_volatile) - { - return this->add(callback, std::chrono::milliseconds(milliseconds), is_volatile); - } - - task_handle scheduler::add(const sol::protected_function& callback, const std::chrono::milliseconds delay, - const bool is_volatile) - { - const uint64_t id = ++this->current_task_id_; - - task task; - task.is_volatile = is_volatile; - task.callback = callback; - task.delay = delay; - task.last_call = std::chrono::steady_clock::now(); - task.id = id; - task.is_deleted = false; - - new_callbacks_.access([&task](task_list& tasks) - { - tasks.emplace_back(std::move(task)); - }); - - return {id}; - } - - void scheduler::remove(const task_handle& handle) - { - auto mask_as_deleted = [&](task_list& tasks) - { - for (auto& task : tasks) - { - if (task.id == handle.id) - { - task.is_deleted = true; - break; - } - } - }; - - callbacks_.access(mask_as_deleted); - new_callbacks_.access(mask_as_deleted); - } - - void scheduler::merge_callbacks() - { - callbacks_.access([&](task_list& tasks) - { - new_callbacks_.access([&](task_list& new_tasks) - { - tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), - std::move_iterator(new_tasks.end())); - new_tasks = {}; - }); - }); - } -} diff --git a/src/client/game/ui_scripting/lua/scheduler.hpp b/src/client/game/ui_scripting/lua/scheduler.hpp deleted file mode 100644 index 1935e25e..00000000 --- a/src/client/game/ui_scripting/lua/scheduler.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -#include - -namespace ui_scripting::lua -{ - class context; - - class task_handle - { - public: - uint64_t id = 0; - }; - - class task final : public task_handle - { - public: - std::chrono::steady_clock::time_point last_call{}; - sol::protected_function callback{}; - std::chrono::milliseconds delay{}; - bool is_volatile = false; - bool is_deleted = false; - }; - - class scheduler final - { - public: - scheduler(sol::state& state); - - scheduler(scheduler&&) noexcept = delete; - scheduler& operator=(scheduler&&) noexcept = delete; - - scheduler(const scheduler&) = delete; - scheduler& operator=(const scheduler&) = delete; - - void run_frame(); - void clear(); - - task_handle add(const sol::protected_function& callback, long long milliseconds, bool is_volatile); - task_handle add(const sol::protected_function& callback, std::chrono::milliseconds delay, bool is_volatile); - - private: - using task_list = std::vector; - utils::concurrency::container new_callbacks_; - utils::concurrency::container callbacks_; - std::atomic_int64_t current_task_id_ = 0; - - void remove(const task_handle& handle); - void merge_callbacks(); - }; -} diff --git a/src/client/game/ui_scripting/lua/value_conversion.cpp b/src/client/game/ui_scripting/lua/value_conversion.cpp deleted file mode 100644 index 38376cdf..00000000 --- a/src/client/game/ui_scripting/lua/value_conversion.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include "value_conversion.hpp" -#include "../execution.hpp" -#include "../../../component/ui_scripting.hpp" - -namespace ui_scripting::lua -{ - namespace - { - table convert_table(const sol::table& t) - { - table res{}; - - t.for_each([res](const sol::object& key, const sol::object& value) - { - res.set(convert(key), convert(value)); - }); - - return res; - } - - script_value convert_function(const sol::protected_function& function) - { - const auto closure = game::hks::cclosure_Create(*game::hks::lua_state, main_function_handler, 0, 0, 0); - add_converted_function(closure, function); - - game::hks::HksObject value{}; - value.t = game::hks::TCFUNCTION; - value.v.cClosure = closure; - - return value; - } - } - - script_value convert(const sol::lua_value& value) - { - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is
()) - { - return {value.as
()}; - } - - if (value.is()) - { - return {value.as()}; - } - - if (value.is()) - { - return {convert_table(value.as())}; - } - - if (value.is()) - { - return {convert_function(value.as())}; - } - - return {}; - } - - sol::lua_value convert(lua_State* state, const script_value& value) - { - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is()) - { - return {state, value.as()}; - } - - if (value.is
()) - { - return {state, value.as
()}; - } - - if (value.is()) - { - return {state, value.as()}; - } - - return {state, sol::lua_nil}; - } -} diff --git a/src/client/game/ui_scripting/lua/value_conversion.hpp b/src/client/game/ui_scripting/lua/value_conversion.hpp deleted file mode 100644 index 21a67e33..00000000 --- a/src/client/game/ui_scripting/lua/value_conversion.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once -#include "context.hpp" -#include "../script_value.hpp" - -namespace ui_scripting::lua -{ - script_value convert(const sol::lua_value& value); - sol::lua_value convert(lua_State* state, const script_value& value); -} diff --git a/src/client/game/ui_scripting/script_value.cpp b/src/client/game/ui_scripting/script_value.cpp deleted file mode 100644 index 34d17020..00000000 --- a/src/client/game/ui_scripting/script_value.cpp +++ /dev/null @@ -1,274 +0,0 @@ -#include -#include "execution.hpp" -#include "types.hpp" -#include "script_value.hpp" - -namespace ui_scripting -{ - /*************************************************************** - * Constructors - **************************************************************/ - - script_value::script_value(const game::hks::HksObject& value) - : value_(value) - { - } - - script_value::script_value(const int value) - { - game::hks::HksObject obj{}; - obj.t = game::hks::TNUMBER; - obj.v.number = static_cast(value); - - this->value_ = obj; - } - - script_value::script_value(const unsigned int value) - { - game::hks::HksObject obj{}; - obj.t = game::hks::TNUMBER; - obj.v.number = static_cast(value); - - this->value_ = obj; - } - - script_value::script_value(const bool value) - { - game::hks::HksObject obj{}; - obj.t = game::hks::TBOOLEAN; - obj.v.boolean = value; - - this->value_ = obj; - } - - script_value::script_value(const float value) - { - game::hks::HksObject obj{}; - obj.t = game::hks::TNUMBER; - obj.v.number = static_cast(value); - - this->value_ = obj; - } - - script_value::script_value(const double value) - : script_value(static_cast(value)) - { - } - - script_value::script_value(const char* value) - { - game::hks::HksObject obj{}; - - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - game::hks::hksi_lua_pushlstring(state, value, (unsigned int)strlen(value)); - obj = state->m_apistack.top[-1]; - - this->value_ = obj; - } - - script_value::script_value(const std::string& value) - : script_value(value.data()) - { - } - - script_value::script_value(const lightuserdata& value) - { - this->value_.t = game::hks::TLIGHTUSERDATA; - this->value_.v.ptr = value.ptr; - } - - script_value::script_value(const userdata& value) - { - this->value_.t = game::hks::TUSERDATA; - this->value_.v.ptr = value.ptr; - } - - script_value::script_value(const table& value) - { - this->value_.t = game::hks::TTABLE; - this->value_.v.ptr = value.ptr; - } - - script_value::script_value(const function& value) - { - this->value_.t = value.type; - this->value_.v.ptr = value.ptr; - } - - /*************************************************************** - * Integer - **************************************************************/ - - template <> - bool script_value::is() const - { - const auto number = this->get_raw().v.number; - return this->get_raw().t == game::hks::TNUMBER && static_cast(number) == number; - } - - template <> - bool script_value::is() const - { - return this->is(); - } - - template <> - int script_value::get() const - { - return static_cast(this->get_raw().v.number); - } - - template <> - unsigned int script_value::get() const - { - return static_cast(this->get_raw().v.number); - } - - /*************************************************************** - * Boolean - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().t == game::hks::TBOOLEAN; - } - - template <> - bool script_value::get() const - { - return this->get_raw().v.boolean; - } - - /*************************************************************** - * Float - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().t == game::hks::TNUMBER; - } - - template <> - bool script_value::is() const - { - return this->is(); - } - - template <> - float script_value::get() const - { - return this->get_raw().v.number; - } - - template <> - double script_value::get() const - { - return static_cast(this->get_raw().v.number); - } - - /*************************************************************** - * String - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().t == game::hks::TSTRING; - } - - template <> - bool script_value::is() const - { - return this->is(); - } - - template <> - const char* script_value::get() const - { - return this->get_raw().v.str->m_data; - } - - template <> - std::string script_value::get() const - { - return this->get(); - } - - /*************************************************************** - * Lightuserdata - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().t == game::hks::TLIGHTUSERDATA; - } - - template <> - lightuserdata script_value::get() const - { - return this->get_raw().v.ptr; - } - - /*************************************************************** - * Userdata - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().t == game::hks::TUSERDATA; - } - - template <> - userdata script_value::get() const - { - return this->get_raw().v.ptr; - } - - /*************************************************************** - * Table - **************************************************************/ - - template <> - bool script_value::is
() const - { - return this->get_raw().t == game::hks::TTABLE; - } - - template <> - table script_value::get() const - { - return this->get_raw().v.table; - } - - /*************************************************************** - * Function - **************************************************************/ - - template <> - bool script_value::is() const - { - return this->get_raw().t == game::hks::TIFUNCTION - || this->get_raw().t == game::hks::TCFUNCTION; - } - - template <> - function script_value::get() const - { - return { this->get_raw().v.cClosure, this->get_raw().t }; - } - - /*************************************************************** - * - **************************************************************/ - - const game::hks::HksObject& script_value::get_raw() const - { - return this->value_; - } -} diff --git a/src/client/game/ui_scripting/script_value.hpp b/src/client/game/ui_scripting/script_value.hpp deleted file mode 100644 index 3de52ddf..00000000 --- a/src/client/game/ui_scripting/script_value.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once -#include "game/game.hpp" - -namespace ui_scripting -{ - class lightuserdata; - class userdata; - class table; - class function; - - class script_value - { - public: - script_value() = default; - script_value(const game::hks::HksObject& value); - - script_value(int value); - script_value(unsigned int value); - script_value(bool value); - - script_value(float value); - script_value(double value); - - script_value(const char* value); - script_value(const std::string& value); - - script_value(const lightuserdata& value); - script_value(const userdata& value); - script_value(const table& value); - script_value(const function& value); - - template - bool is() const; - - template - T as() const - { - if (!this->is()) - { - throw std::runtime_error("Invalid type"); - } - - return get(); - } - - const game::hks::HksObject& get_raw() const; - - private: - template - T get() const; - - game::hks::HksObject value_{}; - }; - - using arguments = std::vector; -} diff --git a/src/client/game/ui_scripting/types.cpp b/src/client/game/ui_scripting/types.cpp deleted file mode 100644 index 37032b1b..00000000 --- a/src/client/game/ui_scripting/types.cpp +++ /dev/null @@ -1,276 +0,0 @@ -#include -#include "types.hpp" -#include "execution.hpp" - -namespace ui_scripting -{ - /*************************************************************** - * Lightuserdata - **************************************************************/ - - lightuserdata::lightuserdata(void* ptr_) - : ptr(ptr_) - { - } - - /*************************************************************** - * Userdata - **************************************************************/ - - userdata::userdata(void* ptr_) - : ptr(ptr_) - { - this->add(); - } - - userdata::userdata(const userdata& other) - { - this->operator=(other); - } - - userdata::userdata(userdata&& other) noexcept - { - this->ptr = other.ptr; - this->ref = other.ref; - other.ref = 0; - } - - userdata::~userdata() - { - this->release(); - } - - userdata& userdata::operator=(const userdata& other) - { - if (&other != this) - { - this->release(); - this->ptr = other.ptr; - this->ref = other.ref; - this->add(); - } - - return *this; - } - - userdata& userdata::operator=(userdata&& other) noexcept - { - if (&other != this) - { - this->release(); - this->ptr = other.ptr; - this->ref = other.ref; - other.ref = 0; - } - - return *this; - } - - void userdata::add() - { - game::hks::HksObject value{}; - value.v.ptr = this->ptr; - value.t = game::hks::TUSERDATA; - - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - push_value(value); - - this->ref = game::hks::hksi_luaL_ref(*game::hks::lua_state, -10000); - } - - void userdata::release() - { - if (this->ref) - { - game::hks::hksi_luaL_unref(*game::hks::lua_state, -10000, this->ref); - } - } - - void userdata::set(const script_value& key, const script_value& value) const - { - set_field(*this, key, value); - } - - script_value userdata::get(const script_value& key) const - { - return get_field(*this, key); - } - - /*************************************************************** - * Table - **************************************************************/ - - table::table() - { - const auto state = *game::hks::lua_state; - this->ptr = game::hks::Hashtable_Create(state, 0, 0); - this->add(); - } - - table::table(game::hks::HashTable* ptr_) - : ptr(ptr_) - { - this->add(); - } - - table::table(const table& other) - { - this->operator=(other); - } - - table::table(table&& other) noexcept - { - this->ptr = other.ptr; - this->ref = other.ref; - other.ref = 0; - } - - table::~table() - { - this->release(); - } - - table& table::operator=(const table& other) - { - if (&other != this) - { - this->release(); - this->ptr = other.ptr; - this->ref = other.ref; - this->add(); - } - - return *this; - } - - table& table::operator=(table&& other) noexcept - { - if (&other != this) - { - this->release(); - this->ptr = other.ptr; - this->ref = other.ref; - other.ref = 0; - } - - return *this; - } - - void table::add() - { - game::hks::HksObject value{}; - value.v.table = this->ptr; - value.t = game::hks::TTABLE; - - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - push_value(value); - - this->ref = game::hks::hksi_luaL_ref(*game::hks::lua_state, -10000); - } - - void table::release() - { - if (this->ref) - { - game::hks::hksi_luaL_unref(*game::hks::lua_state, -10000, this->ref); - } - } - - void table::set(const script_value& key, const script_value& value) const - { - set_field(*this, key, value); - } - - script_value table::get(const script_value& key) const - { - return get_field(*this, key); - } - - /*************************************************************** - * Function - **************************************************************/ - - function::function(game::hks::cclosure* ptr_, game::hks::HksObjectType type_) - : ptr(ptr_) - , type(type_) - { - this->add(); - } - - function::function(const function& other) - { - this->operator=(other); - } - - function::function(function&& other) noexcept - { - this->ptr = other.ptr; - this->type = other.type; - this->ref = other.ref; - other.ref = 0; - } - - function::~function() - { - this->release(); - } - - function& function::operator=(const function& other) - { - if (&other != this) - { - this->release(); - this->ptr = other.ptr; - this->type = other.type; - this->ref = other.ref; - this->add(); - } - - return *this; - } - - function& function::operator=(function&& other) noexcept - { - if (&other != this) - { - this->release(); - this->ptr = other.ptr; - this->type = other.type; - this->ref = other.ref; - other.ref = 0; - } - - return *this; - } - - void function::add() - { - game::hks::HksObject value{}; - value.v.cClosure = this->ptr; - value.t = this->type; - - const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; - - push_value(value); - - this->ref = game::hks::hksi_luaL_ref(*game::hks::lua_state, -10000); - } - - void function::release() - { - if (this->ref) - { - game::hks::hksi_luaL_unref(*game::hks::lua_state, -10000, this->ref); - } - } - - arguments function::call(const arguments& arguments) const - { - return call_script_function(*this, arguments); - } -} diff --git a/src/client/game/ui_scripting/types.hpp b/src/client/game/ui_scripting/types.hpp deleted file mode 100644 index 1924407f..00000000 --- a/src/client/game/ui_scripting/types.hpp +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once -#include "game/game.hpp" -#include "script_value.hpp" - -namespace ui_scripting -{ - class lightuserdata - { - public: - lightuserdata(void*); - void* ptr; - }; - - class userdata - { - public: - userdata(void*); - - userdata(const userdata& other); - userdata(userdata&& other) noexcept; - - ~userdata(); - - userdata& operator=(const userdata& other); - userdata& operator=(userdata&& other) noexcept; - - script_value get(const script_value& key) const; - void set(const script_value& key, const script_value& value) const; - - void* ptr; - - private: - void add(); - void release(); - - int ref{}; - }; - - class table - { - public: - table(); - table(game::hks::HashTable* ptr_); - - table(const table& other); - table(table&& other) noexcept; - - ~table(); - - table& operator=(const table& other); - table& operator=(table&& other) noexcept; - - script_value get(const script_value& key) const; - void set(const script_value& key, const script_value& value) const; - - game::hks::HashTable* ptr; - - private: - void add(); - void release(); - - int ref{}; - }; - - class function - { - public: - function(game::hks::cclosure*, game::hks::HksObjectType); - - function(const function& other); - function(function&& other) noexcept; - - ~function(); - - function& operator=(const function& other); - function& operator=(function&& other) noexcept; - - arguments call(const arguments& arguments) const; - - game::hks::cclosure* ptr; - game::hks::HksObjectType type; - - private: - void add(); - void release(); - - int ref{}; - }; -} diff --git a/src/client/main.cpp b/src/client/main.cpp index 71979cbf..7cab2c45 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -97,7 +97,7 @@ FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) if (!utils::io::read_file(binary, &data)) { throw std::runtime_error(utils::string::va( - "Failed to read game binary (%s)!\nPlease copy the h1x.exe into your Call of Duty: Modern Warfare Remastered installation folder and run it from there.", + "Failed to read game binary (%s)!\nPlease copy the h1-mod.exe into your Call of Duty: Modern Warfare Remastered installation folder and run it from there.", binary.data())); } From 38a153865f5a68efba0d45b38ae630338984e422 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Fri, 18 Mar 2022 03:24:04 +0200 Subject: [PATCH 120/346] no unable to load error --- src/client/component/arxan.cpp | 22 +++++++++------------- src/client/main.cpp | 19 ++++++++++++++----- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp index adff7199..dd38b620 100644 --- a/src/client/component/arxan.cpp +++ b/src/client/component/arxan.cpp @@ -47,6 +47,8 @@ namespace arxan { *static_cast(info) = 1; } + + //https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess } return status; @@ -113,11 +115,6 @@ namespace arxan } } - int just_return() - { - return 1; - } - class component final : public component_interface { public: @@ -128,11 +125,6 @@ namespace arxan //return set_thread_context_stub; } - if (function == "LoadStringA" || function == "LoadStringW") - { - return just_return; - } - return nullptr; } @@ -145,7 +137,7 @@ namespace arxan nt_close_hook.create(ntdll.get_proc("NtClose"), nt_close_stub); nt_query_information_process_hook.create(ntdll.get_proc("NtQueryInformationProcess"), nt_query_information_process_stub); - + // https://www.geoffchappell.com/studies/windows/win32/ntdll/api/index.htm AddVectoredExceptionHandler(1, exception_filter); } @@ -155,8 +147,12 @@ namespace arxan if (game::environment::is_sp()) return; // some of arxan crashes - utils::hook::nop(0x14CDEFCAA, 6); - utils::hook::call(0x1405BCAD1, &just_return); + utils::hook::nop(0xCDEFCAA_b, 6); + utils::hook::nop(0x930FCAA_b, 6); + utils::hook::nop(0x867B66_b, 4); + utils::hook::nop(0x81F0C0_b, 6); + utils::hook::nop(0x5813609_b, 6); + utils::hook::nop(0x8DD678_b, 0xEB); } }; } diff --git a/src/client/main.cpp b/src/client/main.cpp index 7cab2c45..247d18a0 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -50,6 +50,10 @@ launcher::mode detect_mode_from_arguments() return launcher::mode::none; } +int returning() +{ + return 1; +} FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) { @@ -75,6 +79,11 @@ FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) return get_proc_address; } + if (function == "LoadStringA" || function == "LoadStringW") + { + return returning; + } + return component_loader::load_import(library, function); }); @@ -162,12 +171,12 @@ int main() { auto premature_shutdown = true; const auto _ = gsl::finally([&premature_shutdown]() + { + if (premature_shutdown) { - if (premature_shutdown) - { - component_loader::pre_destroy(); - } - }); + component_loader::pre_destroy(); + } + }); try { From 71e62b44965583d08c0194d12326d736405ed87b Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Fri, 18 Mar 2022 03:28:44 +0200 Subject: [PATCH 121/346] game launching errors [skip ci] --- src/client/component/arxan.cpp | 1 + src/client/component/game_module.cpp | 3 +- src/client/component/splash.cpp | 141 -------------------------- src/client/component/system_check.cpp | 15 +-- 4 files changed, 5 insertions(+), 155 deletions(-) delete mode 100644 src/client/component/splash.cpp diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp index dd38b620..c59ae317 100644 --- a/src/client/component/arxan.cpp +++ b/src/client/component/arxan.cpp @@ -153,6 +153,7 @@ namespace arxan utils::hook::nop(0x81F0C0_b, 6); utils::hook::nop(0x5813609_b, 6); utils::hook::nop(0x8DD678_b, 0xEB); + //utils::hook::nop(0xB3D96_b, 4); } }; } diff --git a/src/client/component/game_module.cpp b/src/client/component/game_module.cpp index bd984624..8774634d 100644 --- a/src/client/component/game_module.cpp +++ b/src/client/component/game_module.cpp @@ -3,6 +3,7 @@ #include "game_module.hpp" #include +#include namespace game_module { @@ -90,7 +91,7 @@ namespace game_module utils::nt::library get_game_module() { - static utils::nt::library game{HMODULE(0x140000000)}; + static utils::nt::library game{HMODULE(game::base_address)}; return game; } diff --git a/src/client/component/splash.cpp b/src/client/component/splash.cpp deleted file mode 100644 index 3dfd6541..00000000 --- a/src/client/component/splash.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include -#include "loader/component_loader.hpp" -#include "game/game.hpp" -#include "game_module.hpp" - -#include -#include - -namespace splash -{ - class component final : public component_interface - { - public: - void post_start() override - { - const utils::nt::library self; - image_ = LoadImageA(self, MAKEINTRESOURCE(IMAGE_SPLASH), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); - } - - void post_load() override - { - if (game::environment::is_dedi()) - { - return; - } - - this->show(); - } - - void post_unpack() override - { - // Disable native splash screen - //utils::hook::nop(SELECT_VALUE(0x1403E192E, 0x1405123E2), 5); // winmain doesn't even exist in 1.15? lmao - utils::hook::jump(SELECT_VALUE(0, 0x5BE1D0_b), destroy_stub); // H1-STEAM(1.15) - utils::hook::jump(SELECT_VALUE(0, 0x5BE210_b), destroy_stub); // H1-STEAM(1.15) - } - - void pre_destroy() override - { - this->destroy(); - - MSG msg; - while (this->window_ && IsWindow(this->window_)) - { - if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else - { - std::this_thread::sleep_for(1ms); - } - } - - this->window_ = nullptr; - } - - private: - HWND window_{}; - HANDLE image_{}; - - static void destroy_stub() - { - component_loader::get()->destroy(); - } - - void destroy() const - { - if (this->window_ && IsWindow(this->window_)) - { - ShowWindow(this->window_, SW_HIDE); - DestroyWindow(this->window_); - UnregisterClassA("H1 Splash Screen", utils::nt::library{}); - } - } - - void show() - { - WNDCLASSA wnd_class; - - const auto self = game_module::get_host_module(); - - wnd_class.style = CS_DROPSHADOW; - wnd_class.cbClsExtra = 0; - wnd_class.cbWndExtra = 0; - wnd_class.lpszMenuName = nullptr; - wnd_class.lpfnWndProc = DefWindowProcA; - wnd_class.hInstance = self; - wnd_class.hIcon = LoadIconA(self, reinterpret_cast(102)); - wnd_class.hCursor = LoadCursorA(nullptr, IDC_APPSTARTING); - wnd_class.hbrBackground = reinterpret_cast(6); - wnd_class.lpszClassName = "H1 Splash Screen"; - - if (RegisterClassA(&wnd_class)) - { - const auto x_pixels = GetSystemMetrics(SM_CXFULLSCREEN); - const auto y_pixels = GetSystemMetrics(SM_CYFULLSCREEN); - - if (image_) - { - this->window_ = CreateWindowExA(WS_EX_APPWINDOW, "H1 Splash Screen", "H1", - WS_POPUP | WS_SYSMENU, - (x_pixels - 320) / 2, (y_pixels - 100) / 2, 320, 100, nullptr, - nullptr, - self, nullptr); - - if (this->window_) - { - auto* const image_window = CreateWindowExA(0, "Static", nullptr, WS_CHILD | WS_VISIBLE | 0xEu, - 0, 0, - 320, 100, this->window_, nullptr, self, nullptr); - if (image_window) - { - RECT rect; - SendMessageA(image_window, 0x172u, 0, reinterpret_cast(image_)); - GetWindowRect(image_window, &rect); - - const int width = rect.right - rect.left; - rect.left = (x_pixels - width) / 2; - - const int height = rect.bottom - rect.top; - rect.top = (y_pixels - height) / 2; - - rect.right = rect.left + width; - rect.bottom = rect.top + height; - AdjustWindowRect(&rect, WS_CHILD | WS_VISIBLE | 0xEu, 0); - SetWindowPos(this->window_, nullptr, rect.left, rect.top, rect.right - rect.left, - rect.bottom - rect.top, SWP_NOZORDER); - - ShowWindow(this->window_, SW_SHOW); - UpdateWindow(this->window_); - } - } - } - } - } - }; -} - -REGISTER_COMPONENT(splash::component) diff --git a/src/client/component/system_check.cpp b/src/client/component/system_check.cpp index 9c88bd5c..7b381f4f 100644 --- a/src/client/component/system_check.cpp +++ b/src/client/component/system_check.cpp @@ -51,27 +51,18 @@ namespace system_check { static std::unordered_map mp_zone_hashes = { - {"patch_common_mp.ff", "3F44B0CFB0B8E0FBD9687C2942204AB7F11E66E6E15C73B8B4A5EB5920115A31"}, + {"patch_common_mp.ff", "E45EF5F29D12A5A47F405F89FBBEE479C0A90D02141ABF852D481689514134A1"}, }; static std::unordered_map sp_zone_hashes = { // Steam doesn't necessarily deliver this file :( - {"patch_common.ff", "BB0617DD94AF2F511571E7184BBEDE76E64D97E5D0DAFDB457F00717F035EBF0"}, + {"patch_common.ff", "1D32A9770F90ED022AA76F4859B4AB178E194A703383E61AC2CE83B1E828B18F"}, }; return verify_hashes(mp_zone_hashes) && (game::environment::is_dedi() || verify_hashes(sp_zone_hashes)); } - - void verify_binary_version() - { - const auto value = *reinterpret_cast(0x140001337); - if (value != 0xFFB8006D && value != 0xFFB80080) - { - throw std::runtime_error("Unsupported Call of Duty: Modern Warfare Remastered version(1.4)"); - } - } } bool is_valid() @@ -85,8 +76,6 @@ namespace system_check public: void post_load() override { - verify_binary_version(); - if (!is_valid()) { MessageBoxA(nullptr, "Your game files are outdated or unsupported.\n" From a73db20efb0b75ee151a718b86b290968676d7a0 Mon Sep 17 00:00:00 2001 From: m Date: Fri, 18 Mar 2022 17:47:07 -0500 Subject: [PATCH 122/346] fix safeArea + naming of ui_drawCrosshair --- src/client/component/patches.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 7c323ded..594879f1 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -241,10 +241,10 @@ namespace patches // unlock safeArea_* utils::hook::jump(0x1402624F5, 0x140262503); utils::hook::jump(0x14026251C, 0x140262547); - dvars::override::register_int("safeArea_adjusted_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); - dvars::override::register_int("safeArea_adjusted_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); - dvars::override::register_int("safeArea_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); - dvars::override::register_int("safeArea_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_float("safeArea_adjusted_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_float("safeArea_adjusted_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_float("safeArea_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); + dvars::override::register_float("safeArea_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); // allow servers to check for new packages more often dvars::override::register_int("sv_network_fps", 1000, 20, 1000, game::DVAR_FLAG_SAVED); @@ -257,7 +257,7 @@ namespace patches dvars::register_int("scr_game_spectatetype", 1, 0, 99, game::DVAR_FLAG_REPLICATED, ""); - dvars::override::register_bool("ui_drawcrosshair", true, game::DVAR_FLAG_WRITE); + dvars::override::register_bool("ui_drawCrosshair", true, game::DVAR_FLAG_WRITE); dvars::override::register_int("com_maxfps", 0, 0, 1000, game::DVAR_FLAG_SAVED); From 857a61a5d6eb0dee8a1666d026f8b6bb7381591b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Mar 2022 13:01:59 -0500 Subject: [PATCH 123/346] Bump deps/asmjit from `f1a399c` to `21a31b8` (#32) --- deps/asmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/asmjit b/deps/asmjit index f1a399c4..21a31b8a 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit f1a399c4fe74d1535a4190a2b8727c51045cc914 +Subproject commit 21a31b8a338da3341d2b423f85913597b8ec3d63 From 002b1146d4fa61994a6464cd6a24d11c1c0311e1 Mon Sep 17 00:00:00 2001 From: quaK <38787176+Joelrau@users.noreply.github.com> Date: Wed, 23 Mar 2022 04:31:01 +0200 Subject: [PATCH 124/346] disable components --- src/client/component/auth.cpp | 2 +- src/client/component/binding.cpp | 2 +- src/client/component/branding.cpp | 2 +- src/client/component/colors.cpp | 2 +- src/client/component/command.cpp | 2 +- src/client/component/console.cpp | 2 +- src/client/component/dedicated.cpp | 2 +- src/client/component/dedicated_info.cpp | 2 +- src/client/component/demonware.cpp | 2 +- src/client/component/discord.cpp | 2 +- src/client/component/dvars.cpp | 2 +- src/client/component/exception.cpp | 2 +- src/client/component/fastfiles.cpp | 2 +- src/client/component/filesystem.cpp | 2 +- src/client/component/fps.cpp | 2 +- src/client/component/game_console.cpp | 2 +- src/client/component/input.cpp | 2 +- src/client/component/localized_strings.cpp | 2 +- src/client/component/map_rotation.cpp | 2 +- src/client/component/network.cpp | 2 +- src/client/component/party.cpp | 2 +- src/client/component/patches.cpp | 2 +- src/client/component/redirect.cpp | 2 +- src/client/component/renderer.cpp | 2 +- src/client/component/scheduler.cpp | 2 +- src/client/component/server_list.cpp | 2 +- src/client/component/steam_proxy.cpp | 2 +- src/client/component/system_check.cpp | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 346c8d80..a2842e63 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -242,4 +242,4 @@ namespace auth }; } -REGISTER_COMPONENT(auth::component) +//REGISTER_COMPONENT(auth::component) diff --git a/src/client/component/binding.cpp b/src/client/component/binding.cpp index e40b7f42..15828dfe 100644 --- a/src/client/component/binding.cpp +++ b/src/client/component/binding.cpp @@ -135,4 +135,4 @@ namespace binding }; } -REGISTER_COMPONENT(binding::component) +//REGISTER_COMPONENT(binding::component) diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp index 2f74693b..a95c5aa2 100644 --- a/src/client/component/branding.cpp +++ b/src/client/component/branding.cpp @@ -62,4 +62,4 @@ namespace branding }; } -REGISTER_COMPONENT(branding::component) +//REGISTER_COMPONENT(branding::component) diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp index 75eff23a..aa2631cb 100644 --- a/src/client/component/colors.cpp +++ b/src/client/component/colors.cpp @@ -179,4 +179,4 @@ namespace colors }; } -REGISTER_COMPONENT(colors::component) +//REGISTER_COMPONENT(colors::component) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index b5c1ad40..b0b131bb 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -645,4 +645,4 @@ namespace command }; } -REGISTER_COMPONENT(command::component) +//REGISTER_COMPONENT(command::component) diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 174beaf8..8b39323f 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -296,4 +296,4 @@ namespace console } } -REGISTER_COMPONENT(console::component) +//REGISTER_COMPONENT(console::component) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index 8de5e9ac..d1399e4d 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -330,4 +330,4 @@ namespace dedicated }; } -REGISTER_COMPONENT(dedicated::component) \ No newline at end of file +//REGISTER_COMPONENT(dedicated::component) \ No newline at end of file diff --git a/src/client/component/dedicated_info.cpp b/src/client/component/dedicated_info.cpp index 55973193..65aa148e 100644 --- a/src/client/component/dedicated_info.cpp +++ b/src/client/component/dedicated_info.cpp @@ -62,4 +62,4 @@ namespace dedicated_info }; } -REGISTER_COMPONENT(dedicated_info::component) \ No newline at end of file +//REGISTER_COMPONENT(dedicated_info::component) \ No newline at end of file diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp index 4cb3362c..35aa1999 100644 --- a/src/client/component/demonware.cpp +++ b/src/client/component/demonware.cpp @@ -601,4 +601,4 @@ namespace demonware }; } -REGISTER_COMPONENT(demonware::component) +//REGISTER_COMPONENT(demonware::component) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index 5925a64a..889fc6ec 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -145,4 +145,4 @@ namespace discord }; } -REGISTER_COMPONENT(discord::component) \ No newline at end of file +//REGISTER_COMPONENT(discord::component) \ No newline at end of file diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp index d9c77fdf..d9633b87 100644 --- a/src/client/component/dvars.cpp +++ b/src/client/component/dvars.cpp @@ -440,4 +440,4 @@ namespace dvars }; } -REGISTER_COMPONENT(dvars::component) +//REGISTER_COMPONENT(dvars::component) diff --git a/src/client/component/exception.cpp b/src/client/component/exception.cpp index 028bb238..3867ef27 100644 --- a/src/client/component/exception.cpp +++ b/src/client/component/exception.cpp @@ -258,4 +258,4 @@ namespace exception }; } -REGISTER_COMPONENT(exception::component) +//REGISTER_COMPONENT(exception::component) diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index d4eda37f..ab1b2534 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -46,4 +46,4 @@ namespace fastfiles }; } -REGISTER_COMPONENT(fastfiles::component) +//REGISTER_COMPONENT(fastfiles::component) diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp index da11d2e4..66cd4a4d 100644 --- a/src/client/component/filesystem.cpp +++ b/src/client/component/filesystem.cpp @@ -91,4 +91,4 @@ namespace filesystem }; } -REGISTER_COMPONENT(filesystem::component) \ No newline at end of file +//REGISTER_COMPONENT(filesystem::component) \ No newline at end of file diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index db471119..e1ff307a 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -171,4 +171,4 @@ namespace fps }; } -REGISTER_COMPONENT(fps::component) +//REGISTER_COMPONENT(fps::component) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index cf7c3056..854e2f94 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -790,4 +790,4 @@ namespace game_console }; } -REGISTER_COMPONENT(game_console::component) +//REGISTER_COMPONENT(game_console::component) diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 6d28f601..a577e01b 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -51,4 +51,4 @@ namespace input }; } -REGISTER_COMPONENT(input::component) +//REGISTER_COMPONENT(input::component) diff --git a/src/client/component/localized_strings.cpp b/src/client/component/localized_strings.cpp index 55b41d65..00bb90f3 100644 --- a/src/client/component/localized_strings.cpp +++ b/src/client/component/localized_strings.cpp @@ -49,4 +49,4 @@ namespace localized_strings }; } -REGISTER_COMPONENT(localized_strings::component) +//REGISTER_COMPONENT(localized_strings::component) diff --git a/src/client/component/map_rotation.cpp b/src/client/component/map_rotation.cpp index 216cbfcd..0da94237 100644 --- a/src/client/component/map_rotation.cpp +++ b/src/client/component/map_rotation.cpp @@ -177,4 +177,4 @@ namespace map_rotation }; } -REGISTER_COMPONENT(map_rotation::component) +//REGISTER_COMPONENT(map_rotation::component) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index fb2a6f55..129e7ffb 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -331,4 +331,4 @@ namespace network }; } -REGISTER_COMPONENT(network::component) +//REGISTER_COMPONENT(network::component) diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 0605afad..650e8c08 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -627,4 +627,4 @@ namespace party }; } -REGISTER_COMPONENT(party::component) \ No newline at end of file +//REGISTER_COMPONENT(party::component) \ No newline at end of file diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index e9aaf21a..99a8ad2e 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -290,4 +290,4 @@ namespace patches }; } -REGISTER_COMPONENT(patches::component) +//REGISTER_COMPONENT(patches::component) diff --git a/src/client/component/redirect.cpp b/src/client/component/redirect.cpp index 0443df55..9d3cc65f 100644 --- a/src/client/component/redirect.cpp +++ b/src/client/component/redirect.cpp @@ -80,4 +80,4 @@ namespace redirect }; } -REGISTER_COMPONENT(redirect::component) +//REGISTER_COMPONENT(redirect::component) diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp index b315be76..157cae74 100644 --- a/src/client/component/renderer.cpp +++ b/src/client/component/renderer.cpp @@ -73,5 +73,5 @@ namespace renderer } #ifdef DEBUG -REGISTER_COMPONENT(renderer::component) +//REGISTER_COMPONENT(renderer::component) #endif \ No newline at end of file diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index ac837128..2182784d 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -196,4 +196,4 @@ namespace scheduler }; } -REGISTER_COMPONENT(scheduler::component) +//REGISTER_COMPONENT(scheduler::component) diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index 1b7e759e..b5e0db1e 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -440,4 +440,4 @@ namespace server_list }; } -REGISTER_COMPONENT(server_list::component) +//REGISTER_COMPONENT(server_list::component) diff --git a/src/client/component/steam_proxy.cpp b/src/client/component/steam_proxy.cpp index 5fa54708..2454e01e 100644 --- a/src/client/component/steam_proxy.cpp +++ b/src/client/component/steam_proxy.cpp @@ -185,4 +185,4 @@ namespace steam_proxy } } -REGISTER_COMPONENT(steam_proxy::component) +//REGISTER_COMPONENT(steam_proxy::component) diff --git a/src/client/component/system_check.cpp b/src/client/component/system_check.cpp index 7b381f4f..3a51c715 100644 --- a/src/client/component/system_check.cpp +++ b/src/client/component/system_check.cpp @@ -86,4 +86,4 @@ namespace system_check }; } -REGISTER_COMPONENT(system_check::component) +//REGISTER_COMPONENT(system_check::component) From fbb65958bbfd8c101530e9669fd175e63653d3f0 Mon Sep 17 00:00:00 2001 From: quaK <38787176+Joelrau@users.noreply.github.com> Date: Wed, 23 Mar 2022 04:32:09 +0200 Subject: [PATCH 125/346] update --- src/client/component/arxan.cpp | 12 ++++++------ src/client/component/game_module.cpp | 4 ++++ src/client/main.cpp | 17 ++++++----------- src/client/std_include.cpp | 17 +++++++++++++++++ src/client/std_include.hpp | 5 ++++- 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp index c59ae317..528de35e 100644 --- a/src/client/component/arxan.cpp +++ b/src/client/component/arxan.cpp @@ -147,12 +147,12 @@ namespace arxan if (game::environment::is_sp()) return; // some of arxan crashes - utils::hook::nop(0xCDEFCAA_b, 6); - utils::hook::nop(0x930FCAA_b, 6); - utils::hook::nop(0x867B66_b, 4); - utils::hook::nop(0x81F0C0_b, 6); - utils::hook::nop(0x5813609_b, 6); - utils::hook::nop(0x8DD678_b, 0xEB); + // utils::hook::nop(0xCDEFCAA_b, 6); + // utils::hook::nop(0x930FCAA_b, 6); + // utils::hook::nop(0x867B66_b, 4); + // utils::hook::nop(0x81F0C0_b, 6); + // utils::hook::nop(0x5813609_b, 6); + // utils::hook::nop(0x8DD678_b, 0xEB); //utils::hook::nop(0xB3D96_b, 4); } }; diff --git a/src/client/component/game_module.cpp b/src/client/component/game_module.cpp index 8774634d..0ec79d45 100644 --- a/src/client/component/game_module.cpp +++ b/src/client/component/game_module.cpp @@ -111,7 +111,11 @@ namespace game_module void post_load() override { +#ifdef INJECT_HOST_AS_LIB hook_module_resolving(); +#else + assert(get_host_module() == get_game_module()); +#endif } }; } diff --git a/src/client/main.cpp b/src/client/main.cpp index 247d18a0..c6f7ad62 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -22,7 +22,7 @@ BOOL WINAPI system_parameters_info_a(const UINT uiAction, const UINT uiParam, co FARPROC WINAPI get_proc_address(const HMODULE hModule, const LPCSTR lpProcName) { - if (lpProcName == "GlobalMemoryStatusEx"s) + if (lpProcName == "InitializeCriticalSectionEx"s) { component_loader::post_unpack(); } @@ -50,11 +50,6 @@ launcher::mode detect_mode_from_arguments() return launcher::mode::none; } -int returning() -{ - return 1; -} - FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) { loader loader; @@ -79,11 +74,6 @@ FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) return get_proc_address; } - if (function == "LoadStringA" || function == "LoadStringW") - { - return returning; - } - return component_loader::load_import(library, function); }); @@ -110,7 +100,12 @@ FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) binary.data())); } +#ifdef INJECT_HOST_AS_LIB return loader.load_library(binary, base_address); +#else + *base_address = 0x140000000; + return loader.load(self, data); +#endif } void remove_crash_file() diff --git a/src/client/std_include.cpp b/src/client/std_include.cpp index efe6cd64..75331ed0 100644 --- a/src/client/std_include.cpp +++ b/src/client/std_include.cpp @@ -1,6 +1,23 @@ #include +#pragma comment(linker, "/merge:.data=.cld") +#pragma comment(linker, "/merge:.rdata=.clr") +#pragma comment(linker, "/merge:.cl=.main") +#pragma comment(linker, "/merge:.text=.main") +#pragma comment(linker, "/stack:0x1000000") + +#ifdef INJECT_HOST_AS_LIB #pragma comment(linker, "/base:0x160000000") +#else +#pragma comment(linker, "/base:0x140000000") +#endif + +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language=''\"") + +#ifndef INJECT_HOST_AS_LIB +#pragma bss_seg(".payload") +char payload_data[BINARY_PAYLOAD_SIZE]; +#endif extern "C" { diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index 98a00a2d..0fd21793 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -1,6 +1,9 @@ #pragma once -#define BINARY_PAYLOAD_SIZE 0x12000000 +#define BINARY_PAYLOAD_SIZE 0x14000000 + +// Decide whether to load the game as lib or to inject it +//#define INJECT_HOST_AS_LIB #pragma warning(push) #pragma warning(disable: 4100) From 4cb4d38d4a3b4f476bc5820248661b52f0d66ce4 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Mon, 28 Mar 2022 02:21:24 +0200 Subject: [PATCH 126/346] Small fix --- src/client/component/materials.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/client/component/materials.cpp b/src/client/component/materials.cpp index 1b0b17c5..99b22a45 100644 --- a/src/client/component/materials.cpp +++ b/src/client/component/materials.cpp @@ -49,8 +49,7 @@ namespace materials game::Material* create_material(const std::string& name, const std::string& data) { - const auto white = *reinterpret_cast(SELECT_VALUE(0x141F3D860, 0x14282C330)); - + const auto white = material_register_handle_hook.invoke("white"); const auto material = utils::memory::get_allocator()->allocate(); const auto texture_table = utils::memory::get_allocator()->allocate(); const auto image = utils::memory::get_allocator()->allocate(); From 906d1ee677c29db53281f5a8874163a4cf48eed7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 16:41:34 -0500 Subject: [PATCH 127/346] Bump deps/GSL from `4377f6e` to `3837236` (#33) Bumps [deps/GSL](https://github.com/Microsoft/GSL) from `4377f6e` to `3837236`. - [Release notes](https://github.com/Microsoft/GSL/releases) - [Commits](https://github.com/Microsoft/GSL/compare/4377f6e603c64a86c934f1546aa9db482f2e1a4e...383723676cd548d615159701ac3d050f8dd1e128) --- updated-dependencies: - dependency-name: deps/GSL dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deps/GSL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/GSL b/deps/GSL index 4377f6e6..38372367 160000 --- a/deps/GSL +++ b/deps/GSL @@ -1 +1 @@ -Subproject commit 4377f6e603c64a86c934f1546aa9db482f2e1a4e +Subproject commit 383723676cd548d615159701ac3d050f8dd1e128 From 0c81d5b064c10ead9df314638b472a2cabb4a42b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 16:41:48 -0500 Subject: [PATCH 128/346] Bump deps/libtommath from `66de864` to `5108f12` (#34) Bumps [deps/libtommath](https://github.com/libtom/libtommath) from `66de864` to `5108f12`. - [Release notes](https://github.com/libtom/libtommath/releases) - [Commits](https://github.com/libtom/libtommath/compare/66de86426e9cdb88526974c765108f01554af2b0...5108f12350b6daa4aa5dbc846517ad1db2f8388a) --- updated-dependencies: - dependency-name: deps/libtommath dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deps/libtommath | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtommath b/deps/libtommath index 66de8642..5108f123 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit 66de86426e9cdb88526974c765108f01554af2b0 +Subproject commit 5108f12350b6daa4aa5dbc846517ad1db2f8388a From a35abd7b4f2576fb6e5dea2046bcc7282a489d4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 16:41:57 -0500 Subject: [PATCH 129/346] Bump deps/zlib from `2014a99` to `21767c6` (#35) Bumps [deps/zlib](https://github.com/madler/zlib) from `2014a99` to `21767c6`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/2014a993addbc8f1b9785d97f55fd189792c2f78...21767c654d31d2dccdde4330529775c6c5fd5389) --- updated-dependencies: - dependency-name: deps/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deps/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/zlib b/deps/zlib index 2014a993..21767c65 160000 --- a/deps/zlib +++ b/deps/zlib @@ -1 +1 @@ -Subproject commit 2014a993addbc8f1b9785d97f55fd189792c2f78 +Subproject commit 21767c654d31d2dccdde4330529775c6c5fd5389 From 27501da8876a74996bada8064d48ed3d936f28a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Mar 2022 16:42:05 -0500 Subject: [PATCH 130/346] Bump deps/asmjit from `21a31b8` to `7342f7d` (#36) Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `21a31b8` to `7342f7d`. - [Release notes](https://github.com/asmjit/asmjit/releases) - [Commits](https://github.com/asmjit/asmjit/compare/21a31b8a338da3341d2b423f85913597b8ec3d63...7342f7d78d8cd3088bb7b475c3f7ec52f7619980) --- updated-dependencies: - dependency-name: deps/asmjit dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deps/asmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/asmjit b/deps/asmjit index 21a31b8a..7342f7d7 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit 21a31b8a338da3341d2b423f85913597b8ec3d63 +Subproject commit 7342f7d78d8cd3088bb7b475c3f7ec52f7619980 From fdbc5b91c15668ea307e222b64ed719bab19b990 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Mar 2022 17:28:58 +0000 Subject: [PATCH 131/346] Bump deps/zlib from `21767c6` to `ce12773` Bumps [deps/zlib](https://github.com/madler/zlib) from `21767c6` to `ce12773`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/21767c654d31d2dccdde4330529775c6c5fd5389...ce12773790517034317274f5c65ba70cfeea29f7) --- updated-dependencies: - dependency-name: deps/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/zlib b/deps/zlib index 21767c65..ce127737 160000 --- a/deps/zlib +++ b/deps/zlib @@ -1 +1 @@ -Subproject commit 21767c654d31d2dccdde4330529775c6c5fd5389 +Subproject commit ce12773790517034317274f5c65ba70cfeea29f7 From c5abe3701b0861f9b47a1de52dcb05518dfe6a30 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 31 Mar 2022 17:36:08 +0000 Subject: [PATCH 132/346] Bump deps/zlib from `ce12773` to `ec3df00` Bumps [deps/zlib](https://github.com/madler/zlib) from `ce12773` to `ec3df00`. - [Release notes](https://github.com/madler/zlib/releases) - [Commits](https://github.com/madler/zlib/compare/ce12773790517034317274f5c65ba70cfeea29f7...ec3df00224d4b396e2ac6586ab5d25f673caa4c2) --- updated-dependencies: - dependency-name: deps/zlib dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/zlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/zlib b/deps/zlib index ce127737..ec3df002 160000 --- a/deps/zlib +++ b/deps/zlib @@ -1 +1 @@ -Subproject commit ce12773790517034317274f5c65ba70cfeea29f7 +Subproject commit ec3df00224d4b396e2ac6586ab5d25f673caa4c2 From 548247f9b9c941e52dfcea435302087c6368cb05 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 3 Apr 2022 14:33:45 +0200 Subject: [PATCH 133/346] Update function_tables.cpp --- src/client/game/scripting/function_tables.cpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index b36aea0f..b3c66253 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -1457,36 +1457,36 @@ namespace scripting {"visionsyncwithplayer", 0x82A0}, // SP 0x000000000 MP 0x14032ED90 {"showhudsplash", 0x82A1}, // SP 0x140263850 MP 0x14032FB10 {"setperk", 0x82A2}, // SP 0x140265490 MP 0x1403297E0 - {"_meth_82a3", 0x82A3}, // SP 0x1402659A0 MP 0x140329D00 - {"_meth_82a4", 0x82A4}, // SP 0x1402661B0 MP 0x14032A460 - {"_meth_82a5", 0x82A5}, // SP 0x140265D40 MP 0x14032A0A0 + {"hasperk", 0x82A3}, // SP 0x1402659A0 MP 0x140329D00 + {"clearperks", 0x82A4}, // SP 0x1402661B0 MP 0x14032A460 + {"unsetperk", 0x82A5}, // SP 0x140265D40 MP 0x14032A0A0 {"registerparty", 0x82A6}, // SP 0x000000000 MP 0x1403323C0 - {"_meth_82a7", 0x82A7}, // SP 0x000000000 MP 0x1403324F0 - {"_meth_82a8", 0x82A8}, // SP 0x1405D92F0 MP 0x14032A8F0 - {"_meth_82a9", 0x82A9}, // SP 0x1405D92F0 MP 0x14032A900 + {"getfireteammembers", 0x82A7}, // SP 0x000000000 MP 0x1403324F0 + {"noclip", 0x82A8}, // SP 0x1405D92F0 MP 0x14032A8F0 + {"ufo", 0x82A9}, // SP 0x1405D92F0 MP 0x14032A900 {"moveto", 0x82AA}, // SP 0x1402B2A10 MP 0x14037E950 - {"rotatepitch", 0x82AB}, // SP 0x1402B2F60 MP 0x14037EEB0 - {"rotateyaw", 0x82AC}, // SP 0x1402B2F70 MP 0x14037EEC0 - {"rotateroll", 0x82AD}, // SP 0x1402B2F90 MP 0x14037EEE0 + {"movex", 0x82AB}, // SP 0x1402B2F60 MP 0x14037EEB0 + {"movey", 0x82AC}, // SP 0x1402B2F70 MP 0x14037EEC0 + {"movez", 0x82AD}, // SP 0x1402B2F90 MP 0x14037EEE0 {"movegravity", 0x82AE}, // SP 0x1402B2C10 MP 0x14037EB00 - {"_meth_82af", 0x82AF}, // SP 0x1402B2D70 MP 0x14037EC90 - {"_meth_82b0", 0x82B0}, // SP 0x1402B2EE0 MP 0x14037EE20 + {"moveslide", 0x82AF}, // SP 0x1402B2D70 MP 0x14037EC90 + {"stopmoveslide", 0x82B0}, // SP 0x1402B2EE0 MP 0x14037EE20 {"rotateto", 0x82B1}, // SP 0x1402B3030 MP 0x14037EF10 - {"_meth_82b2", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 + {"rotatepitch", 0x82B2}, // SP 0x1402B3460 MP 0x14037F060 {"rotateyaw", 0x82B3}, // SP 0x1402B3470 MP 0x14037F070 - {"_meth_82b4", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 // looks similar to moveto/rotateto, wtf + {"rotateroll", 0x82B4}, // SP 0x1402B3490 MP 0x14037F090 // looks similar to moveto/rotateto, wtf {"addpitch", 0x82B5}, // SP 0x1402B3410 MP 0x14037F010 {"addyaw", 0x82B6}, // SP 0x1402B3430 MP 0x14037F030 - {"addoll", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 - {"_meth_82b8", 0x82B8}, // SP 0x1402B34B0 MP 0x14037F0B0 + {"addroll", 0x82B7}, // SP 0x1402B3450 MP 0x14037F050 + {"vibrate", 0x82B8}, // SP 0x1402B34B0 MP 0x14037F0B0 {"rotatevelocity", 0x82B9}, // SP 0x1402B3700 MP 0x14037F3C0 {"solid", 0x82BA}, // SP 0x1402B45E0 MP 0x1403808A0 {"notsolid", 0x82BB}, // SP 0x1402B4690 MP 0x140380950 {"setcandamage", 0x82BC}, // SP 0x1402B3880 MP 0x14037F590 {"setcanradiusdamage", 0x82BD}, // SP 0x1402B38E0 MP 0x14037F5F0 {"physicslaunchclient", 0x82BE}, // SP 0x1402B3960 MP 0x14037F670 - {"_meth_82bf", 0x82BF}, // SP 0x000000000 MP 0x1403351A0 - {"_meth_82c0", 0x82C0}, // SP 0x000000000 MP 0x1403351B0 + {"setcardicon", 0x82BF}, // SP 0x000000000 MP 0x1403351A0 + {"setcardnameplate", 0x82C0}, // SP 0x000000000 MP 0x1403351B0 {"setcarddisplayslot", 0x82C1}, // SP 0x000000000 MP 0x1403351C0 {"regweaponforfxremoval", 0x82C2}, // SP 0x000000000 MP 0x1403352B0 {"laststandrevive", 0x82C3}, // SP 0x000000000 MP 0x140331E00 From 81e9ee451a70d2a91aae2caf3b6cbec3b34edf51 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 5 Apr 2022 01:30:24 +0200 Subject: [PATCH 134/346] Scripting changes + SP support --- premake5.lua | 1 + src/client/component/logfile.cpp | 2 +- src/client/component/scripting.cpp | 92 ++++++++++++++----- src/client/game/scripting/execution.cpp | 90 +++++++++--------- src/client/game/scripting/execution.hpp | 9 +- src/client/game/scripting/functions.cpp | 35 ++++++- src/client/game/scripting/functions.hpp | 2 +- src/client/game/scripting/lua/context.cpp | 41 ++++++++- src/client/game/scripting/lua/engine.cpp | 28 ++++-- src/client/game/scripting/lua/engine.hpp | 1 + .../game/scripting/lua/value_conversion.cpp | 55 ++++------- src/client/game/symbols.hpp | 7 +- src/client/game/ui_scripting/lua/engine.cpp | 11 +++ 13 files changed, 249 insertions(+), 125 deletions(-) diff --git a/premake5.lua b/premake5.lua index 16043516..9823d960 100644 --- a/premake5.lua +++ b/premake5.lua @@ -264,6 +264,7 @@ filter {} filter "configurations:Debug" optimize "Debug" + buildoptions {"/bigobj"} defines {"DEBUG", "_DEBUG"} filter {} diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp index fc949d92..d1886ca0 100644 --- a/src/client/component/logfile.cpp +++ b/src/client/component/logfile.cpp @@ -212,7 +212,7 @@ namespace logfile return false; } - const auto hook = vm_execute_hooks[pos]; + const auto& hook = vm_execute_hooks[pos]; const auto state = hook.lua_state(); const scripting::entity self = local_id_to_entity(game::scr_VmPub->function_frame->fs.localId); diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index e3116122..f8730c86 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -2,7 +2,6 @@ #include "loader/component_loader.hpp" #include "game/game.hpp" -#include #include "game/scripting/entity.hpp" #include "game/scripting/functions.hpp" @@ -13,6 +12,8 @@ #include "scheduler.hpp" #include "scripting.hpp" +#include + namespace scripting { std::unordered_map> fields_table; @@ -21,6 +22,7 @@ namespace scripting namespace { utils::hook::detour vm_notify_hook; + utils::hook::detour vm_execute_hook; utils::hook::detour scr_load_level_hook; utils::hook::detour g_shutdown_game_hook; @@ -29,7 +31,10 @@ namespace scripting utils::hook::detour scr_set_thread_position_hook; utils::hook::detour process_script_hook; + utils::hook::detour sl_get_canonical_string_hook; + std::string current_file; + unsigned int current_file_id{}; void vm_notify_stub(const unsigned int notify_list_owner_id, const game::scr_string_t string_value, game::VariableValue* top) @@ -48,11 +53,6 @@ namespace scripting e.arguments.emplace_back(*value); } - if (e.name == "entitydeleted") - { - scripting::clear_entity_fields(e.entity); - } - lua::engine::notify(e); } } @@ -60,6 +60,16 @@ namespace scripting vm_notify_hook.invoke(notify_list_owner_id, string_value, top); } + unsigned int vm_execute_stub() + { + if (!lua::engine::is_running()) + { + lua::engine::start(); + } + + return vm_execute_hook.invoke(); + } + void scr_load_level_stub() { scr_load_level_hook.invoke(); @@ -71,20 +81,25 @@ namespace scripting void g_shutdown_game_stub(const int free_scripts) { + if (free_scripts) + { + script_function_table.clear(); + } + lua::engine::stop(); return g_shutdown_game_hook.invoke(free_scripts); } - void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t _name, unsigned int canonicalString, unsigned int offset) + void scr_add_class_field_stub(unsigned int classnum, game::scr_string_t name, unsigned int canonical_string, unsigned int offset) { - const auto name = game::SL_ConvertToString(_name); + const auto name_str = game::SL_ConvertToString(name); - if (fields_table[classnum].find(name) == fields_table[classnum].end()) + if (fields_table[classnum].find(name_str) == fields_table[classnum].end()) { - fields_table[classnum][name] = offset; + fields_table[classnum][name_str] = offset; } - scr_add_class_field_hook.invoke(classnum, _name, canonicalString, offset); + scr_add_class_field_hook.invoke(classnum, name, canonical_string, offset); } void process_script_stub(const char* filename) @@ -92,21 +107,49 @@ namespace scripting const auto file_id = atoi(filename); if (file_id) { - current_file = scripting::find_token(file_id); + current_file_id = file_id; } else { + current_file_id = 0; current_file = filename; } process_script_hook.invoke(filename); } - void scr_set_thread_position_stub(unsigned int threadName, const char* codePos) + void add_function(const std::string& file, unsigned int id, const char* pos) { - const auto function_name = scripting::find_token(threadName); - script_function_table[current_file][function_name] = codePos; - scr_set_thread_position_hook.invoke(threadName, codePos); + const auto function_names = scripting::find_token(id); + for (const auto& name : function_names) + { + script_function_table[file][name] = pos; + } + } + + void scr_set_thread_position_stub(unsigned int thread_name, const char* code_pos) + { + if (current_file_id) + { + const auto names = scripting::find_token(current_file_id); + for (const auto& name : names) + { + add_function(name, thread_name, code_pos); + } + } + else + { + add_function(current_file, thread_name, code_pos); + } + + scr_set_thread_position_hook.invoke(thread_name, code_pos); + } + + unsigned int sl_get_canonical_string_stub(const char* str) + { + const auto result = sl_get_canonical_string_hook.invoke(str); + scripting::token_map[str] = result; + return result; } } @@ -115,11 +158,6 @@ namespace scripting public: void post_unpack() override { - if (game::environment::is_sp()) - { - return; - } - vm_notify_hook.create(SELECT_VALUE(0x140379A00, 0x1404479F0), vm_notify_stub); scr_add_class_field_hook.create(SELECT_VALUE(0x140370370, 0x14043E2C0), scr_add_class_field_stub); @@ -127,9 +165,19 @@ namespace scripting scr_set_thread_position_hook.create(SELECT_VALUE(0x14036A180, 0x140437D10), scr_set_thread_position_stub); process_script_hook.create(SELECT_VALUE(0x1403737E0, 0x1404417E0), process_script_stub); - scr_load_level_hook.create(SELECT_VALUE(0x1402A5BE0, 0x1403727C0), scr_load_level_stub); + if (!game::environment::is_sp()) + { + scr_load_level_hook.create(SELECT_VALUE(0x1402A5BE0, 0x1403727C0), scr_load_level_stub); + } + else + { + vm_execute_hook.create(SELECT_VALUE(0x140376590, 0x140444580), vm_execute_stub); + } + g_shutdown_game_hook.create(SELECT_VALUE(0x140277D40, 0x140345A60), g_shutdown_game_stub); + sl_get_canonical_string_hook.create(game::SL_GetCanonicalString, sl_get_canonical_string_stub); + scheduler::loop([]() { lua::engine::run_frame(); diff --git a/src/client/game/scripting/execution.cpp b/src/client/game/scripting/execution.cpp index 273b4f7a..1380ab1e 100644 --- a/src/client/game/scripting/execution.cpp +++ b/src/client/game/scripting/execution.cpp @@ -145,47 +145,6 @@ namespace scripting return exec_ent_thread(entity, pos, arguments); } - static std::unordered_map> custom_fields; - - script_value get_custom_field(const entity& entity, const std::string& field) - { - auto& fields = custom_fields[entity.get_entity_id()]; - const auto _field = fields.find(field); - if (_field != fields.end()) - { - return _field->second; - } - return {}; - } - - void set_custom_field(const entity& entity, const std::string& field, const script_value& value) - { - const auto id = entity.get_entity_id(); - - if (custom_fields[id].find(field) != custom_fields[id].end()) - { - custom_fields[id][field] = value; - return; - } - - custom_fields[id].insert(std::make_pair(field, value)); - } - - void clear_entity_fields(const entity& entity) - { - const auto id = entity.get_entity_id(); - - if (custom_fields.find(id) != custom_fields.end()) - { - custom_fields[id].clear(); - } - } - - void clear_custom_fields() - { - custom_fields.clear(); - } - void set_entity_field(const entity& entity, const std::string& field, const script_value& value) { const auto entref = entity.get_entity_reference(); @@ -206,8 +165,7 @@ namespace scripting } else { - // Read custom fields - set_custom_field(entity, field, value); + set_object_variable(entity.get_entity_id(), field, value); } } @@ -234,8 +192,7 @@ namespace scripting return value; } - // Add custom fields - return get_custom_field(entity, field); + return get_object_variable(entity.get_entity_id(), field); } unsigned int make_array() @@ -248,4 +205,47 @@ namespace scripting return index; } + + void set_object_variable(const unsigned int parent_id, const unsigned int id, const script_value& value) + { + const auto offset = 0xFA00 * (parent_id & 3); + const auto variable_id = game::GetVariable(parent_id, id); + const auto variable = &game::scr_VarGlob->childVariableValue[variable_id + offset]; + const auto& raw_value = value.get_raw(); + + game::AddRefToValue(raw_value.type, raw_value.u); + game::RemoveRefToValue(variable->type, variable->u.u); + + variable->type = static_cast(raw_value.type); + variable->u.u = raw_value.u; + } + + void set_object_variable(const unsigned int parent_id, const std::string& name, const script_value& value) + { + const auto id = scripting::find_token_id(name); + set_object_variable(parent_id, id, value); + } + + script_value get_object_variable(const unsigned int parent_id, const unsigned int id) + { + const auto offset = 0xFA00 * (parent_id & 3); + const auto variable_id = game::FindVariable(parent_id, id); + if (!variable_id) + { + return {}; + } + + const auto variable = &game::scr_VarGlob->childVariableValue[variable_id + offset]; + game::VariableValue value{}; + value.type = static_cast(variable->type); + value.u = variable->u.u; + + return value; + } + + script_value get_object_variable(const unsigned int parent_id, const std::string& name) + { + const auto id = scripting::find_token_id(name); + return get_object_variable(parent_id, id); + } } diff --git a/src/client/game/scripting/execution.hpp b/src/client/game/scripting/execution.hpp index 94a2678d..9ec6f62f 100644 --- a/src/client/game/scripting/execution.hpp +++ b/src/client/game/scripting/execution.hpp @@ -27,13 +27,16 @@ namespace scripting script_value call_script_function(const entity& entity, const std::string& filename, const std::string& function, const std::vector& arguments); - void clear_entity_fields(const entity& entity); - void clear_custom_fields(); - void set_entity_field(const entity& entity, const std::string& field, const script_value& value); script_value get_entity_field(const entity& entity, const std::string& field); void notify(const entity& entity, const std::string& event, const std::vector& arguments); unsigned int make_array(); + + script_value get_object_variable(const unsigned int parent_id, const unsigned int id); + script_value get_object_variable(const unsigned int parent_id, const std::string& name); + + void set_object_variable(const unsigned int parent_id, const std::string& name, const script_value& value); + void set_object_variable(const unsigned int parent_id, const unsigned int id, const script_value& value); } diff --git a/src/client/game/scripting/functions.cpp b/src/client/game/scripting/functions.cpp index 0f233547..ab2c0b9f 100644 --- a/src/client/game/scripting/functions.cpp +++ b/src/client/game/scripting/functions.cpp @@ -69,19 +69,40 @@ namespace scripting return reinterpret_cast(method_table)[index - 0x8000]; } + + unsigned int parse_token_id(const std::string& name) + { + if (name.starts_with("_ID")) + { + return static_cast(std::strtol(name.substr(3).data(), nullptr, 10)); + } + + if (name.starts_with("_id_")) + { + return static_cast(std::strtol(name.substr(4).data(), nullptr, 16)); + } + + return 0; + } } - std::string find_token(unsigned int id) + std::vector find_token(unsigned int id) { + std::vector results; + + results.push_back(utils::string::va("_id_%X", id)); + results.push_back(utils::string::va("_ID%i", id)); + for (const auto& token : token_map) { if (token.second == id) { - return token.first; + results.push_back(token.first); + break; } } - return utils::string::va("_ID%i", id); + return results; } unsigned int find_token_id(const std::string& name) @@ -93,7 +114,13 @@ namespace scripting return result->second; } - return 0; + const auto parsed_id = parse_token_id(name); + if (parsed_id) + { + return parsed_id; + } + + return game::SL_GetCanonicalString(name.data()); } script_function find_function(const std::string& name, const bool prefer_global) diff --git a/src/client/game/scripting/functions.hpp b/src/client/game/scripting/functions.hpp index 0422bcf7..95c51763 100644 --- a/src/client/game/scripting/functions.hpp +++ b/src/client/game/scripting/functions.hpp @@ -9,7 +9,7 @@ namespace scripting using script_function = void(*)(game::scr_entref_t); - std::string find_token(unsigned int id); + std::vector find_token(unsigned int id); unsigned int find_token_id(const std::string& name); script_function find_function(const std::string& name, const bool prefer_global); diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index 7aaa9f89..cb24ff3e 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -17,7 +17,6 @@ namespace scripting::lua { namespace { - vector normalize_vector(const vector& vec) { const auto length = sqrt( @@ -155,12 +154,52 @@ namespace scripting::lua { return normalize_vector(a); }; + + vector_type["normalize"] = [](const vector& a) + { + return normalize_vector(a); + }; + + vector_type["toangles"] = [](const vector& a) + { + return call("vectortoangles", {a}).as(); + }; + + vector_type["toyaw"] = [](const vector& a) + { + return call("vectortoyaw", {a}).as(); + }; + + vector_type["tolerp"] = [](const vector& a) + { + return call("vectortolerp", {a}).as(); + }; + + vector_type["toup"] = [](const vector& a) + { + return call("anglestoup", {a}).as(); + }; + + vector_type["toright"] = [](const vector& a) + { + return call("anglestoright", {a}).as(); + }; + + vector_type["toforward"] = [](const vector& a) + { + return call("anglestoforward", {a}).as(); + }; } void setup_entity_type(sol::state& state, event_handler& handler, scheduler& scheduler) { state["level"] = entity{*game::levelEntityId}; + if (game::environment::is_sp()) + { + state["player"] = call("getentbynum", {0}).as(); + } + auto entity_type = state.new_usertype("entity"); for (const auto& func : method_map) diff --git a/src/client/game/scripting/lua/engine.cpp b/src/client/game/scripting/lua/engine.cpp index d481dc76..390a5995 100644 --- a/src/client/game/scripting/lua/engine.cpp +++ b/src/client/game/scripting/lua/engine.cpp @@ -11,6 +11,8 @@ namespace scripting::lua::engine { namespace { + bool running = false; + auto& get_scripts() { static std::vector> scripts{}; @@ -38,21 +40,30 @@ namespace scripting::lua::engine void stop() { + running = false; logfile::clear_callbacks(); get_scripts().clear(); } void start() { - // No SP until there is a concept - if (game::environment::is_sp()) - { - return; - } - stop(); + load_scripts("h1-mod/scripts/"); load_scripts("data/scripts/"); + + if (game::environment::is_sp()) + { + load_scripts("h1-mod/scripts/sp/"); + load_scripts("data/scripts/sp/"); + } + else + { + load_scripts("h1-mod/scripts/mp/"); + load_scripts("data/scripts/mp/"); + } + + running = true; } void notify(const event& e) @@ -70,4 +81,9 @@ namespace scripting::lua::engine script->run_frame(); } } + + bool is_running() + { + return running; + } } diff --git a/src/client/game/scripting/lua/engine.hpp b/src/client/game/scripting/lua/engine.hpp index 471316cd..2df0b0ef 100644 --- a/src/client/game/scripting/lua/engine.hpp +++ b/src/client/game/scripting/lua/engine.hpp @@ -8,4 +8,5 @@ namespace scripting::lua::engine void stop(); void notify(const event& e); void run_frame(); + bool is_running(); } diff --git a/src/client/game/scripting/lua/value_conversion.cpp b/src/client/game/scripting/lua/value_conversion.cpp index a838c787..a12abc8e 100644 --- a/src/client/game/scripting/lua/value_conversion.cpp +++ b/src/client/game/scripting/lua/value_conversion.cpp @@ -165,56 +165,33 @@ namespace scripting::lua auto table = sol::table::create(state); auto metatable = sol::table::create(state); - const auto offset = 64000 * (parent_id & 3); - - metatable[sol::meta_function::new_index] = [offset, parent_id](const sol::table t, const sol::this_state s, + metatable[sol::meta_function::new_index] = [parent_id](const sol::table t, const sol::this_state s, const sol::lua_value& field, const sol::lua_value& value) { - const auto id = field.is() - ? scripting::find_token_id(field.as()) - : field.as(); - - if (!id) + const auto new_variable = convert({s, value}); + if (field.is()) { - return; + scripting::set_object_variable(parent_id, field.as(), new_variable); + } + else if (field.is()) + { + scripting::set_object_variable(parent_id, field.as(), new_variable); } - - const auto variable_id = game::GetVariable(parent_id, id); - const auto variable = &game::scr_VarGlob->childVariableValue[variable_id + offset]; - const auto new_variable = convert({s, value}).get_raw(); - - game::AddRefToValue(new_variable.type, new_variable.u); - game::RemoveRefToValue(variable->type, variable->u.u); - - variable->type = (char)new_variable.type; - variable->u.u = new_variable.u; }; - metatable[sol::meta_function::index] = [offset, parent_id](const sol::table t, const sol::this_state s, + metatable[sol::meta_function::index] = [parent_id](const sol::table t, const sol::this_state s, const sol::lua_value& field) { - const auto id = field.is() - ? scripting::find_token_id(field.as()) - : field.as(); - - if (!id) + if (field.is()) { - return sol::lua_value{s, sol::lua_nil}; + return convert(s, scripting::get_object_variable(parent_id, field.as())); + } + else if (field.is()) + { + return convert(s, scripting::get_object_variable(parent_id, field.as())); } - const auto variable_id = game::FindVariable(parent_id, id); - if (!variable_id) - { - return sol::lua_value{s, sol::lua_nil}; - } - - const auto variable = game::scr_VarGlob->childVariableValue[variable_id + offset]; - - game::VariableValue result{}; - result.u = variable.u.u; - result.type = (game::scriptType_e)variable.type; - - return convert(s, result); + return sol::lua_value{s, sol::lua_nil}; }; table[sol::metatable_key] = metatable; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 1ade88ce..1f277cee 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -70,7 +70,7 @@ namespace game WEAK symbol FS_Startup{0x1403B85D0, 0x1404EDD30}; WEAK symbol FS_AddLocalizedGameDirectory{0x1403B6030, 0x1404EBE20}; - WEAK symbol GetVariable{0x14036FDD0, 0x1403F3730}; + WEAK symbol GetVariable{0x14036FDD0, 0x14043DD70}; WEAK symbol GetNewVariable{0x14036FA00, 0x14043D990}; WEAK symbol GetNewArrayVariable{0x14036F880, 0x14043D810}; WEAK symbol GScr_LoadConsts{0x1402D13E0, 0x140393810}; @@ -136,6 +136,7 @@ namespace game WEAK symbol Scr_ClearOutParams{0x140374460, 0x140442510}; WEAK symbol Scr_GetEntityIdRef{0x140372D50, 0x140440D80}; WEAK symbol Scr_GetEntityId{0x140372CA0, 0x140440CD0}; + WEAK symbol Scr_SetObjectField{0x1402B9F60, 0x140385330}; WEAK symbol ScrPlace_GetViewPlacement{0x1401981F0, 0x140288550}; @@ -155,8 +156,8 @@ namespace game WEAK symbol SL_FindString{0x14036D700, 0x14043B470}; WEAK symbol SL_GetString{0x14036D9A0, 0x14043B840}; - WEAK symbol SL_ConvertToString{0x14036D420, 0x14043B170}; - WEAK symbol Scr_SetObjectField{0x1402B9F60, 0x140385330}; + WEAK symbol SL_ConvertToString{0x14036D420, 0x14043B170}; + WEAK symbol SL_GetCanonicalString{0x14036A310, 0x140437EA0}; WEAK symbol SV_DirectConnect{0, 0x140480860}; WEAK symbol SV_Cmd_ArgvBuffer{0x1403446C0, 0x140404CA0}; diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index 8faf198c..cc3d3d33 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -54,6 +54,17 @@ namespace ui_scripting::lua::engine load_scripts("h1-mod/ui_scripts/"); load_scripts("data/ui_scripts/"); + + if (game::environment::is_sp()) + { + load_scripts("h1-mod/ui_scripts/sp/"); + load_scripts("data/ui_scripts/sp/"); + } + else + { + load_scripts("h1-mod/ui_scripts/mp/"); + load_scripts("data/ui_scripts/mp/"); + } } void stop() From 03d38d5a10bbeb8aa9d78b2abb470d28efbc53a0 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 5 Apr 2022 01:54:13 +0200 Subject: [PATCH 135/346] Add some functions --- src/client/component/scripting.cpp | 1 + src/client/component/scripting.hpp | 3 + src/client/game/scripting/lua/context.cpp | 71 ++++++++++++++++++++ src/client/game/symbols.hpp | 2 + src/client/game/ui_scripting/lua/context.cpp | 69 +++++++++++++++++++ 5 files changed, 146 insertions(+) diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index f8730c86..9aa37307 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -18,6 +18,7 @@ namespace scripting { std::unordered_map> fields_table; std::unordered_map> script_function_table; + utils::concurrency::container shared_table; namespace { diff --git a/src/client/component/scripting.hpp b/src/client/component/scripting.hpp index 865ae858..5794bff2 100644 --- a/src/client/component/scripting.hpp +++ b/src/client/component/scripting.hpp @@ -3,6 +3,9 @@ namespace scripting { + using shared_table_t = std::unordered_map; + extern std::unordered_map> fields_table; extern std::unordered_map> script_function_table; + extern utils::concurrency::container shared_table; } \ No newline at end of file diff --git a/src/client/game/scripting/lua/context.cpp b/src/client/game/scripting/lua/context.cpp index cb24ff3e..396b3837 100644 --- a/src/client/game/scripting/lua/context.cpp +++ b/src/client/game/scripting/lua/context.cpp @@ -9,6 +9,7 @@ #include "../../../component/command.hpp" #include "../../../component/logfile.hpp" #include "../../../component/scripting.hpp" +#include "../../../component/fastfiles.hpp" #include #include @@ -501,6 +502,76 @@ namespace scripting::lua return detour; }; + + game_type["assetlist"] = [](const game&, const sol::this_state s, const std::string& type_string) + { + auto table = sol::table::create(s.lua_state()); + auto index = 1; + auto type_index = -1; + + for (auto i = 0; i < ::game::XAssetType::ASSET_TYPE_COUNT; i++) + { + if (type_string == ::game::g_assetNames[i]) + { + type_index = i; + } + } + + if (type_index == -1) + { + throw std::runtime_error("Asset type does not exist"); + } + + const auto type = static_cast<::game::XAssetType>(type_index); + fastfiles::enum_assets(type, [type, &table, &index](const ::game::XAssetHeader header) + { + const auto asset = ::game::XAsset{type, header}; + const std::string asset_name = ::game::DB_GetXAssetName(&asset); + table[index++] = asset_name; + }, true); + + return table; + }; + + game_type["sharedset"] = [](const game&, const std::string& key, const std::string& value) + { + scripting::shared_table.access([key, value](scripting::shared_table_t& table) + { + table[key] = value; + }); + }; + + game_type["sharedget"] = [](const game&, const std::string& key) + { + std::string result; + scripting::shared_table.access([key, &result](scripting::shared_table_t& table) + { + result = table[key]; + }); + return result; + }; + + game_type["sharedclear"] = [](const game&) + { + scripting::shared_table.access([](scripting::shared_table_t& table) + { + table.clear(); + }); + }; + + game_type["getentbyref"] = [](const game&, const sol::this_state s, + const unsigned int entnum, const unsigned int classnum) + { + const auto id = ::game::Scr_GetEntityId(entnum, classnum); + if (id) + { + return convert(s, scripting::entity{id}); + } + else + { + return sol::lua_value{s, sol::lua_nil}; + } + }; } } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 1f277cee..974cbab9 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -43,6 +43,8 @@ namespace game WEAK symbol CG_GameMessageBold{0x140138750, 0x140220620}; WEAK symbol CG_SetClientDvarFromServer{0, 0x140236120}; + WEAK symbol CG_GetWeaponDisplayName{0x14016EC30, 0x1400B5840}; WEAK symbol CL_IsCgameInitialized{0x14017EE30, 0x140245650}; diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 96286cdd..0d975d0d 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -10,6 +10,8 @@ #include "../../../component/updater.hpp" #include "../../../component/fps.hpp" #include "../../../component/localized_strings.hpp" +#include "../../../component/fastfiles.hpp" +#include "../../../component/scripting.hpp" #include "component/game_console.hpp" #include "component/scheduler.hpp" @@ -68,6 +70,73 @@ namespace ui_scripting::lua localized_strings::override(string, value); }; + game_type["sharedset"] = [](const game&, const std::string& key, const std::string& value) + { + scripting::shared_table.access([key, value](scripting::shared_table_t& table) + { + table[key] = value; + }); + }; + + game_type["sharedget"] = [](const game&, const std::string& key) + { + std::string result; + scripting::shared_table.access([key, &result](scripting::shared_table_t& table) + { + result = table[key]; + }); + return result; + }; + + game_type["sharedclear"] = [](const game&) + { + scripting::shared_table.access([](scripting::shared_table_t& table) + { + table.clear(); + }); + }; + + game_type["assetlist"] = [](const game&, const sol::this_state s, const std::string& type_string) + { + auto table = sol::table::create(s.lua_state()); + auto index = 1; + auto type_index = -1; + + for (auto i = 0; i < ::game::XAssetType::ASSET_TYPE_COUNT; i++) + { + if (type_string == ::game::g_assetNames[i]) + { + type_index = i; + } + } + + if (type_index == -1) + { + throw std::runtime_error("Asset type does not exist"); + } + + const auto type = static_cast<::game::XAssetType>(type_index); + fastfiles::enum_assets(type, [type, &table, &index](const ::game::XAssetHeader header) + { + const auto asset = ::game::XAsset{type, header}; + const std::string asset_name = ::game::DB_GetXAssetName(&asset); + table[index++] = asset_name; + }, true); + + return table; + }; + + game_type["getweapondisplayname"] = [](const game&, const std::string& name) + { + const auto alternate = name.starts_with("alt_"); + const auto weapon = ::game::G_GetWeaponForName(name.data()); + + char buffer[0x400] = {0}; + ::game::CG_GetWeaponDisplayName(weapon, alternate, buffer, 0x400); + + return std::string(buffer); + }; + auto userdata_type = state.new_usertype("userdata_"); userdata_type["new"] = sol::property( From 684028bc9578ab2b98c3f93db1f13aaf006d74b0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Apr 2022 12:57:10 -0500 Subject: [PATCH 136/346] Bump deps/asmjit from `7342f7d` to `752eb38` (#41) Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `7342f7d` to `752eb38`. - [Release notes](https://github.com/asmjit/asmjit/releases) - [Commits](https://github.com/asmjit/asmjit/compare/7342f7d78d8cd3088bb7b475c3f7ec52f7619980...752eb38a4dbe590995cbadaff06baadd8378eeeb) --- updated-dependencies: - dependency-name: deps/asmjit dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deps/asmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/asmjit b/deps/asmjit index 7342f7d7..752eb38a 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit 7342f7d78d8cd3088bb7b475c3f7ec52f7619980 +Subproject commit 752eb38a4dbe590995cbadaff06baadd8378eeeb From 0915c68fd1c726358a6c914718cafd6fa08d35f6 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 5 Apr 2022 21:41:02 +0200 Subject: [PATCH 137/346] Add lui key events + fixes --- src/client/component/input.cpp | 13 +++++ src/client/game/symbols.hpp | 3 + src/client/game/ui_scripting/execution.cpp | 65 +++++++++++++--------- src/client/game/ui_scripting/types.cpp | 34 +++++++++++ src/client/game/ui_scripting/types.hpp | 24 ++++++++ 5 files changed, 112 insertions(+), 27 deletions(-) diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index a10ac12a..c1b39b9d 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -4,6 +4,7 @@ #include "game/game.hpp" #include "game_console.hpp" +#include "game/ui_scripting/execution.hpp" #include @@ -16,6 +17,12 @@ namespace input void cl_char_event_stub(const int local_client_num, const int key) { + ui_scripting::notify("keypress", + { + {"keynum", key}, + {"key", game::Key_KeynumToString(key, 0, 1)}, + }); + if (!game_console::console_char_event(local_client_num, key)) { return; @@ -26,6 +33,12 @@ namespace input void cl_key_event_stub(const int local_client_num, const int key, const int down) { + ui_scripting::notify(down ? "keydown" : "keyup", + { + {"keynum", key}, + {"key", game::Key_KeynumToString(key, 0, 1)}, + }); + if (!game_console::console_key_event(local_client_num, key, down)) { return; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 974cbab9..6653b555 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -153,6 +153,8 @@ namespace game int a3, int a4, unsigned int a5)> LUI_OpenMenu{0x14039D5F0, 0x1404CD210}; WEAK symbol LUI_BeginEvent{0x1400D27F0, 0x140161A00}; WEAK symbol LUI_EndEvent{0x1400D3A80, 0x140162CD0}; + WEAK symbol LUI_EnterCriticalSection{0x1400D3B70, 0x140162DC0}; + WEAK symbol LUI_LeaveCriticalSection{0x1400D8DB0, 0x140168150}; WEAK symbol Menu_IsMenuOpenAndVisible{0x1404709C0, 0x1404C7320}; @@ -273,5 +275,6 @@ namespace game int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x14008B5D0, 0x14011B540}; WEAK symbol hksi_luaL_ref{0x1400A64D0, 0x140136D30}; WEAK symbol hksi_luaL_unref{0x14009EF10, 0x14012F610}; + WEAK symbol closePendingUpvalues{0x14008EA00, 0x14011E970}; } } diff --git a/src/client/game/ui_scripting/execution.cpp b/src/client/game/ui_scripting/execution.cpp index cc8df795..716fe1ca 100644 --- a/src/client/game/ui_scripting/execution.cpp +++ b/src/client/game/ui_scripting/execution.cpp @@ -40,53 +40,53 @@ namespace ui_scripting bool notify(const std::string& name, const event_arguments& arguments) { const auto state = *game::hks::lua_state; - if (!game::LUI_BeginEvent(0, name.data(), state)) + if (!state) { return false; } - - const auto _1 = gsl::finally(&disable_error_hook); - enable_error_hook(); - const auto top = state->m_apistack.top; + const auto _1 = gsl::finally(game::LUI_LeaveCriticalSection); + game::LUI_EnterCriticalSection(); + try { - const auto event = get_return_value(0).as
(); + const auto globals = table((*::game::hks::lua_state)->globals.v.table); + const auto engine = globals.get("Engine").as
(); + const auto root = engine.get("GetLuiRoot").as().call({})[0].as(); + const auto process_event = root.get("processEvent").as(); + + table event{}; + event.set("name", name); for (const auto& arg : arguments) { event.set(arg.first, arg.second); } - } - catch (...) - { - } - state->m_apistack.top = top; - - try - { - game::LUI_EndEvent(state); + process_event.call({root, event}); + return true; } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error while processing event: ") + e.what()); + printf("Error processing event '%s' %s\n", name.data(), e.what()); + return false; } - - return true; } arguments call_script_function(const function& function, const arguments& arguments) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + stack stack; push_value(function); for (auto i = arguments.begin(); i != arguments.end(); ++i) { push_value(*i); } + const auto num_args = static_cast(arguments.size()); + stack.save(num_args + 1); + const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); @@ -98,6 +98,7 @@ namespace ui_scripting } catch (const std::exception& e) { + stack.fix(); throw std::runtime_error(std::string("Error executing script function: ") + e.what()); } } @@ -105,9 +106,10 @@ namespace ui_scripting script_value get_field(const userdata& self, const script_value& key) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + stack stack; push_value(key); + stack.save(1); const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); @@ -124,16 +126,18 @@ namespace ui_scripting } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error getting userdata field: ") + e.what()); + stack.fix(); + throw std::runtime_error("Error getting userdata field: "s + e.what()); } } script_value get_field(const table& self, const script_value& key) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + stack stack; push_value(key); + stack.save(1); const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); @@ -150,14 +154,17 @@ namespace ui_scripting } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error getting table field: ") + e.what()); + stack.fix(); + throw std::runtime_error("Error getting table field: "s + e.what()); } } void set_field(const userdata& self, const script_value& key, const script_value& value) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + + stack stack; + stack.save(0); const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); @@ -172,14 +179,17 @@ namespace ui_scripting } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error setting userdata field: ") + e.what()); + stack.fix(); + throw std::runtime_error("Error setting userdata field: "s + e.what()); } } void set_field(const table& self, const script_value& key, const script_value& value) { const auto state = *game::hks::lua_state; - state->m_apistack.top = state->m_apistack.base; + + stack stack; + stack.save(0); const auto _1 = gsl::finally(&disable_error_hook); enable_error_hook(); @@ -194,7 +204,8 @@ namespace ui_scripting } catch (const std::exception& e) { - throw std::runtime_error(std::string("Error setting table field: ") + e.what()); + stack.fix(); + throw std::runtime_error("Error setting table field: "s + e.what()); } } } diff --git a/src/client/game/ui_scripting/types.cpp b/src/client/game/ui_scripting/types.cpp index 37032b1b..66e8d497 100644 --- a/src/client/game/ui_scripting/types.cpp +++ b/src/client/game/ui_scripting/types.cpp @@ -273,4 +273,38 @@ namespace ui_scripting { return call_script_function(*this, arguments); } + + /*************************************************************** + * Stack + **************************************************************/ + + stack::stack() + { + this->state = *game::hks::lua_state; + this->state->m_apistack.top = this->state->m_apistack.base; + } + + void stack::save(int num_args) + { + this->num_args_ = num_args; + this->num_calls_ = state->m_numberOfCCalls; + this->base_bottom_ = state->m_apistack.base - state->m_apistack.bottom; + this->top_bottom_ = state->m_apistack.top - state->m_apistack.bottom; + this->callstack_ = state->m_callStack.m_current - state->m_callStack.m_records; + } + + void stack::fix() + { + this->state->m_numberOfCCalls = this->num_calls_; + + game::hks::closePendingUpvalues(this->state, &this->state->m_apistack.bottom[this->top_bottom_ - this->num_args_]); + this->state->m_callStack.m_current = &this->state->m_callStack.m_records[this->callstack_]; + + this->state->m_apistack.base = &this->state->m_apistack.bottom[this->base_bottom_]; + this->state->m_apistack.top = &this->state->m_apistack.bottom[this->top_bottom_ - static_cast(this->num_args_ + 1)]; + + this->state->m_apistack.bottom[this->top_bottom_].t = this->state->m_apistack.top[-1].t; + this->state->m_apistack.bottom[this->top_bottom_].v.ptr = this->state->m_apistack.top[-1].v.ptr; + this->state->m_apistack.top = &this->state->m_apistack.bottom[this->top_bottom_ + 1]; + } } diff --git a/src/client/game/ui_scripting/types.hpp b/src/client/game/ui_scripting/types.hpp index 1924407f..bc2f7216 100644 --- a/src/client/game/ui_scripting/types.hpp +++ b/src/client/game/ui_scripting/types.hpp @@ -86,4 +86,28 @@ namespace ui_scripting int ref{}; }; + + class stack final + { + public: + stack(); + + void save(int num_args); + void fix(); + + stack(stack&&) = delete; + stack(const stack&) = delete; + stack& operator=(stack&&) = delete; + stack& operator=(const stack&) = delete; + + private: + game::hks::lua_State* state; + + int num_args_; + int num_calls_; + + uint64_t base_bottom_; + uint64_t top_bottom_; + uint64_t callstack_; + }; } From 6e1a7c35b930c53612d70177d658d2e8705536e5 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 5 Apr 2022 22:16:41 +0200 Subject: [PATCH 138/346] Add sp player notify function --- src/client/game/ui_scripting/lua/context.cpp | 46 ++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 0d975d0d..1db94910 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -2,6 +2,7 @@ #include "context.hpp" #include "error.hpp" #include "value_conversion.hpp" +#include "../../scripting/execution.hpp" #include "../script_value.hpp" #include "../execution.hpp" @@ -262,6 +263,51 @@ namespace ui_scripting::lua updater_table["getcurrentfile"] = updater::get_current_file; state["updater"] = updater_table; + + if (::game::environment::is_sp()) + { + struct player + { + }; + auto player_type = state.new_usertype("player_"); + state["player"] = player(); + + player_type["notify"] = [](const player&, const sol::this_state s, const std::string& name, sol::variadic_args va) + { + if (!::game::CL_IsCgameInitialized() || !::game::sp::g_entities[0].client) + { + throw std::runtime_error("Not in game"); + } + + const sol::state_view view{s}; + const auto to_string = view["tostring"].get(); + + std::vector args{}; + for (auto arg : va) + { + args.push_back(to_string.call(arg).get()); + } + + ::scheduler::once([s, name, args]() + { + try + { + std::vector arguments{}; + + for (const auto& arg : args) + { + arguments.push_back(arg); + } + + const auto player = scripting::call("getentbynum", {0}).as(); + scripting::notify(player, name, arguments); + } + catch (...) + { + } + }, ::scheduler::pipeline::server); + }; + } } } From 652ea25c997e51d85f75fda5b28c628d3666e629 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 5 Apr 2022 22:16:47 +0200 Subject: [PATCH 139/346] Update function_tables.cpp --- src/client/game/scripting/function_tables.cpp | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/client/game/scripting/function_tables.cpp b/src/client/game/scripting/function_tables.cpp index b3c66253..e0cba30c 100644 --- a/src/client/game/scripting/function_tables.cpp +++ b/src/client/game/scripting/function_tables.cpp @@ -931,12 +931,12 @@ namespace scripting {"setstablemissile", 0x8092}, // SP 0x1402AD800 MP 0x000000000 {"playersetgroundreferenceent", 0x8093}, // SP 0x1402A9070 MP 0x1403752A0 {"dontinterpolate", 0x8094}, // SP 0x1402A0070 MP 0x140358360 - {"_meth_8095", 0x8095}, // SP 0x1402AAC80 MP 0x000000000 - {"_meth_8096", 0x8096}, // SP 0x1402AAD20 MP 0x000000000 + {"dospawn", 0x8095}, // SP 0x1402AAC80 MP 0x000000000 + {"stalingradspawn", 0x8096}, // SP 0x1402AAD20 MP 0x000000000 {"getorigin", 0x8097}, // SP 0x1402AADC0 MP 0x140377CA0 - {"_meth_8098", 0x8098}, // SP 0x1402AAE70 MP 0x000000000 - {"_meth_8099", 0x8099}, // SP 0x1402AAF90 MP 0x000000000 - {"_meth_809a", 0x809A}, // SP 0x1402AC1D0 MP 0x000000000 + {"getcentroid", 0x8098}, // SP 0x1402AAE70 MP 0x000000000 + {"getshootatpos", 0x8099}, // SP 0x1402AAF90 MP 0x000000000 + {"getdebugeye", 0x809A}, // SP 0x1402AC1D0 MP 0x000000000 {"useby", 0x809B}, // SP 0x1402AC470 MP 0x140377D00 {"playsound", 0x809C}, // SP 0x1402AC9B0 MP 0x140377F40 {"_meth_809d", 0x809D}, @@ -1336,14 +1336,14 @@ namespace scripting {"vehicleturretcontroloff", 0x8227}, // SP 0x140464260 MP 0x140562970 {"isturretready", 0x8228}, // SP 0x140464340 MP 0x1405629E0 {"_meth_8229", 0x8229}, // SP 0x140464570 MP 0x140562C70 - {"dospawn", 0x822A}, // SP 0x1404646D0 MP 0x140562D90 - {"isphysveh", 0x822B}, // SP 0x1404647A0 MP 0x140562E80 - {"crash", 0x822C}, // SP 0x140464840 MP 0x140562F80 - {"launch", 0x822D}, // SP 0x140464980 MP 0x1405630A0 - {"disablecrashing", 0x822E}, // SP 0x140464B20 MP 0x140563240 - {"enablecrashing", 0x822F}, // SP 0x140464C10 MP 0x140563310 - {"setspeed", 0x8230}, // SP 0x140464C90 MP 0x1405633E0 - {"setconveyorbelt", 0x8231}, // SP 0x140464E50 MP 0x140563610 + {"vehicle_dospawn", 0x822A}, // SP 0x1404646D0 MP 0x140562D90 + {"vehicle_isphysveh", 0x822B}, // SP 0x1404647A0 MP 0x140562E80 + {"vehphys_crash", 0x822C}, // SP 0x140464840 MP 0x140562F80 + {"vehphys_launch", 0x822D}, // SP 0x140464980 MP 0x1405630A0 + {"vehphys_disablecrashing", 0x822E}, // SP 0x140464B20 MP 0x140563240 + {"vehphys_enablecrashing", 0x822F}, // SP 0x140464C10 MP 0x140563310 + {"vehphys_setspeed", 0x8230}, // SP 0x140464C90 MP 0x1405633E0 + {"vehphys_setconveyorbelt", 0x8231}, // SP 0x140464E50 MP 0x140563610 {"freevehicle", 0x8232}, // SP 0x000000000 MP 0x1405609B0 {"_meth_8233", 0x8233}, // SP 0x140290E70 MP 0x000000000 {"_meth_8234", 0x8234}, // SP 0x1402910E0 MP 0x000000000 @@ -1393,8 +1393,8 @@ namespace scripting {"canturrettargetpoint", 0x8260}, // SP 0x1404635A0 MP 0x140561DF0 {"setlookatent", 0x8261}, // SP 0x1404638A0 MP 0x1405620F0 {"clearlookatent", 0x8262}, // SP 0x140463950 MP 0x1405621A0 - {"setweapon", 0x8263}, // SP 0x140463AB0 MP 0x140562280 - {"_meth_8264", 0x8264}, // SP 0x140463B20 MP 0x1405622F0 + {"setvehweapon", 0x8263}, // SP 0x140463AB0 MP 0x140562280 + {"fireweapon", 0x8264}, // SP 0x140463B20 MP 0x1405622F0 {"vehicleturretcontrolon", 0x8265}, // SP 0x1404641D0 MP 0x1405628F0 {"finishplayerdamage", 0x8266}, // SP 0x000000000 MP 0x1403337A0 {"suicide", 0x8267}, // SP 0x000000000 MP 0x140333E20 @@ -1421,16 +1421,16 @@ namespace scripting {"setswitchnode", 0x827C}, // SP 0x140465740 MP 0x14055F4D0 {"setwaitspeed", 0x827D}, // SP 0x140465840 MP 0x14055F560 {"finishdamage", 0x827E}, // SP 0x000000000 MP 0x14055F5E0 - {"setspeed", 0x827F}, // SP 0x1404658C0 MP 0x14055F840 - {"setspeedimmediate", 0x8280}, // SP 0x140465930 MP 0x14055F8B0 - {"_meth_8281", 0x8281}, // SP 0x140465AC0 MP 0x14055FA60 - {"getspeed", 0x8282}, // SP 0x140465BE0 MP 0x14055FB80 - {"getvelocity", 0x8283}, // SP 0x140465CD0 MP 0x14055FC70 - {"getbodyvelocity", 0x8284}, // SP 0x140465D40 MP 0x14055FCE0 - {"getsteering", 0x8285}, // SP 0x140465DB0 MP 0x14055FD50 - {"getthrottle", 0x8286}, // SP 0x140465E30 MP 0x14055FDE0 - {"turnengineoff", 0x8287}, // SP 0x140465EA0 MP 0x14055FE50 - {"turnengineon", 0x8288}, // SP 0x140465F00 MP 0x14055FEC0 + {"vehicle_setspeed", 0x827F}, // SP 0x1404658C0 MP 0x14055F840 + {"vehicle_setspeedimmediate", 0x8280}, // SP 0x140465930 MP 0x14055F8B0 + {"vehicle_rotateyaw", 0x8281}, // SP 0x140465AC0 MP 0x14055FA60 + {"vehicle_getspeed", 0x8282}, // SP 0x140465BE0 MP 0x14055FB80 + {"vehicle_getvelocity", 0x8283}, // SP 0x140465CD0 MP 0x14055FC70 + {"vehicle_getbodyvelocity", 0x8284}, // SP 0x140465D40 MP 0x14055FCE0 + {"vehicle_getsteering", 0x8285}, // SP 0x140465DB0 MP 0x14055FD50 + {"vehicle_getthrottle", 0x8286}, // SP 0x140465E30 MP 0x14055FDE0 + {"vehicle_turnengineoff", 0x8287}, // SP 0x140465EA0 MP 0x14055FE50 + {"vehicle_turnengineon", 0x8288}, // SP 0x140465F00 MP 0x14055FEC0 {"_meth_8289", 0x8289}, // SP 0x140465F60 MP 0x000000000 {"getgoalspeedmph", 0x828A}, // SP 0x140466020 MP 0x14055FF30 {"_meth_828b", 0x828B}, // SP 0x140466090 MP 0x14055FFA0 @@ -1509,15 +1509,15 @@ namespace scripting {"visionsetthermalforplayer", 0x82D4}, // SP 0x140263710 MP 0x14032FD20 {"visionsetpainforplayer", 0x82D5}, // SP 0x140263730 MP 0x14032FD40 {"setblurforplayer", 0x82D6}, // SP 0x140264890 MP 0x140330B80 - {"_meth_82d7", 0x82D7}, // SP 0x140264C80 MP 0x140331310 - {"_meth_82d8", 0x82D8}, // SP 0x140264C80 MP 0x140331330 - {"_meth_82d9", 0x82D9}, // SP 0x1402ABE90 MP 0x000000000 - {"getbuildnumber", 0x82DA}, // SP 0x1402663A0 MP 0x14032A910 - {"_meth_82db", 0x82DB}, // SP 0x140266AF0 MP 0x14032AE90 - {"_meth_82dc", 0x82DC}, // SP 0x140266CD0 MP 0x14032B120 + {"getplayerweaponmodel", 0x82D7}, // SP 0x140264C80 MP 0x140331310 + {"getplayerknifemodel", 0x82D8}, // SP 0x140264C80 MP 0x140331330 + {"updateplayermodelwithweapons", 0x82D9}, // SP 0x1402ABE90 MP 0x000000000 + {"notifyonplayercommand", 0x82DA}, // SP 0x1402663A0 MP 0x14032A910 + {"canmantle", 0x82DB}, // SP 0x140266AF0 MP 0x14032AE90 + {"forcemantle", 0x82DC}, // SP 0x140266CD0 MP 0x14032B120 {"ismantling", 0x82DD}, // SP 0x140266FE0 MP 0x14032B500 {"playfx", 0x82DE}, // SP 0x140267330 MP 0x14032B9F0 - {"playerrecoilscaleon", 0x82DF}, // SP 0x140267530 MP 0x14032BD00 + {"player_recoilscaleon", 0x82DF}, // SP 0x140267530 MP 0x14032BD00 {"player_recoilscaleoff", 0x82E0}, // SP 0x140267600 MP 0x14032BDD0 {"weaponlockstart", 0x82E1}, // SP 0x1402676E0 MP 0x14032C000 {"weaponlockfinalize", 0x82E2}, // SP 0x140260240 MP 0x14032C240 From f2642e0c8fd5a76433884f55e2f5893183c51d9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Apr 2022 17:37:09 +0000 Subject: [PATCH 140/346] Bump deps/rapidjson from `8261c1d` to `fcb23c2` Bumps [deps/rapidjson](https://github.com/Tencent/rapidjson) from `8261c1d` to `fcb23c2`. - [Release notes](https://github.com/Tencent/rapidjson/releases) - [Commits](https://github.com/Tencent/rapidjson/compare/8261c1ddf43f10de00fd8c9a67811d1486b2c784...fcb23c2dbf561ec0798529be4f66394d3e4996d8) --- updated-dependencies: - dependency-name: deps/rapidjson dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/rapidjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rapidjson b/deps/rapidjson index 8261c1dd..fcb23c2d 160000 --- a/deps/rapidjson +++ b/deps/rapidjson @@ -1 +1 @@ -Subproject commit 8261c1ddf43f10de00fd8c9a67811d1486b2c784 +Subproject commit fcb23c2dbf561ec0798529be4f66394d3e4996d8 From d0228b92b7bd6940d520e10e3b57b39abb225359 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 8 Apr 2022 16:18:00 +0200 Subject: [PATCH 141/346] SP mods --- data/ui_scripts/mods/__init__.lua | 3 + data/ui_scripts/mods/loading.lua | 116 ++++++ src/client/component/filesystem.cpp | 39 ++ src/client/component/filesystem.hpp | 4 + src/client/component/fonts.cpp | 26 +- src/client/component/fonts.hpp | 1 + src/client/component/game_console.cpp | 2 +- src/client/component/input.cpp | 27 +- src/client/component/materials.cpp | 45 ++- src/client/component/materials.hpp | 1 + src/client/component/mods.cpp | 119 ++++++ src/client/component/mods.hpp | 6 + src/client/game/scripting/lua/engine.cpp | 22 +- src/client/game/symbols.hpp | 5 +- src/client/game/ui_scripting/lua/context.cpp | 33 ++ src/client/game/ui_scripting/lua/engine.cpp | 22 +- src/client/resource.hpp | 2 + src/client/resource.rc | 2 + src/client/resources/json.lua | 388 +++++++++++++++++++ src/common/utils/io.cpp | 5 + src/common/utils/io.hpp | 1 + 21 files changed, 831 insertions(+), 38 deletions(-) create mode 100644 data/ui_scripts/mods/__init__.lua create mode 100644 data/ui_scripts/mods/loading.lua create mode 100644 src/client/component/mods.cpp create mode 100644 src/client/component/mods.hpp create mode 100644 src/client/resources/json.lua diff --git a/data/ui_scripts/mods/__init__.lua b/data/ui_scripts/mods/__init__.lua new file mode 100644 index 00000000..1ca1f8d2 --- /dev/null +++ b/data/ui_scripts/mods/__init__.lua @@ -0,0 +1,3 @@ +if (game:issingleplayer()) then + require("loading") +end diff --git a/data/ui_scripts/mods/loading.lua b/data/ui_scripts/mods/loading.lua new file mode 100644 index 00000000..16cc3084 --- /dev/null +++ b/data/ui_scripts/mods/loading.lua @@ -0,0 +1,116 @@ +game:addlocalizedstring("MENU_MODS", "MODS") +game:addlocalizedstring("MENU_MODS_DESC", "Load installed mods.") +game:addlocalizedstring("LUA_MENU_MOD_DESC_DEFAULT", "Load &&1.") +game:addlocalizedstring("LUA_MENU_MOD_DESC", "&&1\nAuthor: &&2\nVersion: &&3") +game:addlocalizedstring("LUA_MENU_OPEN_STORE", "Open store") +game:addlocalizedstring("LUA_MENU_OPEN_STORE_DESC", "Download and install mods.") +game:addlocalizedstring("LUA_MENU_LOADED_MOD", "Loaded mod: ^2&&1") +game:addlocalizedstring("LUA_MENU_AVAILABLE_MODS", "Available mods") +game:addlocalizedstring("LUA_MENU_UNLOAD", "Unload") +game:addlocalizedstring("LUA_MENU_UNLOAD_DESC", "Unload the currently loaded mod.") + +function createdivider(menu, text) + local element = LUI.UIElement.new( { + leftAnchor = true, + rightAnchor = true, + left = 0, + right = 0, + topAnchor = true, + bottomAnchor = false, + top = 0, + bottom = 33.33 + }) + + element.scrollingToNext = true + element:addElement(LUI.MenuBuilder.BuildRegisteredType("h1_option_menu_titlebar", { + title_bar_text = Engine.ToUpperCase(text) + })) + + menu.list:addElement(element) +end + +function string:truncate(length) + if (#self <= length) then + return self + end + + return self:sub(1, length - 3) .. "..." +end + +LUI.addmenubutton("main_campaign", { + index = 6, + text = "@MENU_MODS", + description = Engine.Localize("@MENU_MODS_DESC"), + callback = function() + LUI.FlowManager.RequestAddMenu(nil, "mods_menu") + end +}) + +function getmodname(path) + local name = path + local desc = Engine.Localize("@LUA_MENU_MOD_DESC_DEFAULT", name) + local infofile = path .. "/info.json" + + if (io.fileexists(infofile)) then + pcall(function() + local data = json.decode(io.readfile(infofile)) + desc = Engine.Localize("@LUA_MENU_MOD_DESC", + data.description, data.author, data.version) + name = data.name + end) + end + + return name, desc +end + +LUI.MenuBuilder.m_types_build["mods_menu"] = function(a1) + local menu = LUI.MenuTemplate.new(a1, { + menu_title = "@MENU_MODS", + exclusiveController = 0, + menu_width = 400, + menu_top_indent = LUI.MenuTemplate.spMenuOffset, + showTopRightSmallBar = true + }) + + local modfolder = game:getloadedmod() + if (modfolder ~= "") then + createdivider(menu, Engine.Localize("@LUA_MENU_LOADED_MOD", getmodname(modfolder):truncate(24))) + + menu:AddButton("@LUA_MENU_UNLOAD", function() + Engine.Exec("unloadmod") + end, nil, true, nil, { + desc_text = Engine.Localize("@LUA_MENU_UNLOAD_DESC") + }) + end + + createdivider(menu, Engine.Localize("@LUA_MENU_AVAILABLE_MODS")) + + if (io.directoryexists("mods")) then + local mods = io.listfiles("mods/") + for i = 1, #mods do + if (io.directoryexists(mods[i]) and not io.directoryisempty(mods[i])) then + local name, desc = getmodname(mods[i]) + + if (mods[i] ~= modfolder) then + game:addlocalizedstring(name, name) + menu:AddButton(name, function() + Engine.Exec("loadmod " .. mods[i]) + end, nil, true, nil, { + desc_text = desc + }) + end + end + end + end + + menu:AddBackButton(function(a1) + Engine.PlaySound(CoD.SFX.MenuBack) + LUI.FlowManager.RequestLeaveMenu(a1) + end) + + LUI.Options.InitScrollingList(menu.list, nil) + menu:CreateBottomDivider() + menu.optionTextInfo = LUI.Options.AddOptionTextInfo(menu) + + return menu +end diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp index da11d2e4..d1827936 100644 --- a/src/client/component/filesystem.cpp +++ b/src/client/component/filesystem.cpp @@ -8,6 +8,7 @@ #include #include +#include namespace filesystem { @@ -70,6 +71,40 @@ namespace filesystem return this->name_; } + std::unordered_set& get_search_paths() + { + static std::unordered_set search_paths{}; + return search_paths; + } + + std::string read_file(const std::string& path) + { + for (const auto& search_path : get_search_paths()) + { + const auto path_ = search_path + "/" + path; + if (utils::io::file_exists(path_)) + { + return utils::io::read_file(path_); + } + } + + return {}; + } + + bool read_file(const std::string& path, std::string* data) + { + for (const auto& search_path : get_search_paths()) + { + const auto path_ = search_path + "/" + path; + if (utils::io::read_file(path_, data)) + { + return true; + } + } + + return false; + } + class component final : public component_interface { public: @@ -87,6 +122,10 @@ namespace filesystem utils::hook::call(SELECT_VALUE(0x1403B8D31, 0x1404EE3D0), register_custom_path_stub); utils::hook::call(SELECT_VALUE(0x1403B8D51, 0x1404EE3F0), register_custom_path_stub); utils::hook::call(SELECT_VALUE(0x1403B8D90, 0x1404EE42F), register_custom_path_stub); + + get_search_paths().insert("."); + get_search_paths().insert("h1-mod"); + get_search_paths().insert("data"); } }; } diff --git a/src/client/component/filesystem.hpp b/src/client/component/filesystem.hpp index 6cec8c87..c3d36dc6 100644 --- a/src/client/component/filesystem.hpp +++ b/src/client/component/filesystem.hpp @@ -16,4 +16,8 @@ namespace filesystem std::string name_; std::string buffer_; }; + + std::unordered_set& get_search_paths(); + std::string read_file(const std::string& path); + bool read_file(const std::string& path, std::string* data); } \ No newline at end of file diff --git a/src/client/component/fonts.cpp b/src/client/component/fonts.cpp index ae8f37fe..32f55399 100644 --- a/src/client/component/fonts.cpp +++ b/src/client/component/fonts.cpp @@ -3,6 +3,7 @@ #include "fonts.hpp" #include "console.hpp" +#include "filesystem.hpp" #include "game/game.hpp" #include "game/dvars.hpp" @@ -36,6 +37,13 @@ namespace fonts return font; } + void free_font(game::TTF* font) + { + utils::memory::get_allocator()->free(font->buffer); + utils::memory::get_allocator()->free(font->name); + utils::memory::get_allocator()->free(font); + } + game::TTF* load_font(const std::string& name) { return font_data.access([&](font_data_t& data_) -> game::TTF* @@ -51,9 +59,7 @@ namespace fonts data = i->second; } - if (data.empty() - && !utils::io::read_file(utils::string::va("h1-mod/%s", name.data()), &data) - && !utils::io::read_file(utils::string::va("data/%s", name.data()), &data)) + if (data.empty() && !filesystem::read_file(name, &data)) { return nullptr; } @@ -98,6 +104,20 @@ namespace fonts }); } + void clear() + { + font_data.access([&](font_data_t& data_) + { + for (auto& font : data_.fonts) + { + free_font(font.second); + } + + data_.fonts.clear(); + utils::hook::set(SELECT_VALUE(0x14F09DBB8, 0x14FD61EE8), 0); // reset registered font count + }); + } + class component final : public component_interface { public: diff --git a/src/client/component/fonts.hpp b/src/client/component/fonts.hpp index 15749bcf..c2d22869 100644 --- a/src/client/component/fonts.hpp +++ b/src/client/component/fonts.hpp @@ -3,4 +3,5 @@ namespace fonts { void add(const std::string& name, const std::string& data); + void clear(); } diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 23b63212..26d492ce 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -571,7 +571,7 @@ namespace game_console { if (key == game::keyNum_t::K_F10) { - if (!game::Com_InFrontEnd()) + if (!game::Com_InFrontend()) { return false; } diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index c1b39b9d..7801bcbd 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -15,13 +15,21 @@ namespace input utils::hook::detour cl_char_event_hook; utils::hook::detour cl_key_event_hook; + bool lui_running() + { + return *game::hks::lua_state != nullptr; + } + void cl_char_event_stub(const int local_client_num, const int key) { - ui_scripting::notify("keypress", + if (lui_running()) { - {"keynum", key}, - {"key", game::Key_KeynumToString(key, 0, 1)}, - }); + ui_scripting::notify("keypress", + { + {"keynum", key}, + {"key", game::Key_KeynumToString(key, 0, 1)}, + }); + } if (!game_console::console_char_event(local_client_num, key)) { @@ -33,11 +41,14 @@ namespace input void cl_key_event_stub(const int local_client_num, const int key, const int down) { - ui_scripting::notify(down ? "keydown" : "keyup", + if (lui_running()) { - {"keynum", key}, - {"key", game::Key_KeynumToString(key, 0, 1)}, - }); + ui_scripting::notify(down ? "keydown" : "keyup", + { + {"keynum", key}, + {"key", game::Key_KeynumToString(key, 0, 1)}, + }); + } if (!game_console::console_key_event(local_client_num, key, down)) { diff --git a/src/client/component/materials.cpp b/src/client/component/materials.cpp index 99b22a45..4fbb3ed8 100644 --- a/src/client/component/materials.cpp +++ b/src/client/component/materials.cpp @@ -3,6 +3,7 @@ #include "materials.hpp" #include "console.hpp" +#include "filesystem.hpp" #include "game/game.hpp" #include "game/dvars.hpp" @@ -20,6 +21,7 @@ namespace materials { utils::hook::detour db_material_streaming_fail_hook; utils::hook::detour material_register_handle_hook; + utils::hook::detour db_get_material_index_hook; struct material_data_t { @@ -68,6 +70,16 @@ namespace materials return material; } + void free_material(game::Material* material) + { + material->textureTable->u.image->textures.___u0.map->Release(); + material->textureTable->u.image->textures.shaderView->Release(); + utils::memory::get_allocator()->free(material->textureTable->u.image); + utils::memory::get_allocator()->free(material->textureTable); + utils::memory::get_allocator()->free(material->name); + utils::memory::get_allocator()->free(material); + } + game::Material* load_material(const std::string& name) { return material_data.access([&](material_data_t& data_) -> game::Material* @@ -83,9 +95,7 @@ namespace materials data = i->second; } - if (data.empty() - && !utils::io::read_file(utils::string::va("h1-mod/materials/%s.png", name.data()), &data) - && !utils::io::read_file(utils::string::va("data/materials/%s.png", name.data()), &data)) + if (data.empty() && !filesystem::read_file(utils::string::va("materials/%s.png", name.data()), &data)) { data_.materials[name] = nullptr; return nullptr; @@ -136,6 +146,16 @@ namespace materials return db_material_streaming_fail_hook.invoke(material); } + + unsigned int db_get_material_index_stub(game::Material* material) + { + if (material->constantTable == &constant_table) + { + return 0; + } + + return db_get_material_index_hook.invoke(material); + } } void add(const std::string& name, const std::string& data) @@ -146,6 +166,24 @@ namespace materials }); } + void clear() + { + material_data.access([&](material_data_t& data_) + { + for (auto& material : data_.materials) + { + if (material.second == nullptr) + { + continue; + } + + free_material(material.second); + } + + data_.materials.clear(); + }); + } + class component final : public component_interface { public: @@ -158,6 +196,7 @@ namespace materials material_register_handle_hook.create(game::Material_RegisterHandle, material_register_handle_stub); db_material_streaming_fail_hook.create(SELECT_VALUE(0x1401D3180, 0x1402C6260), db_material_streaming_fail_stub); + db_get_material_index_hook.create(SELECT_VALUE(0x1401CAD00, 0x1402BBB20), db_get_material_index_stub); } }; } diff --git a/src/client/component/materials.hpp b/src/client/component/materials.hpp index ac58b511..3a548548 100644 --- a/src/client/component/materials.hpp +++ b/src/client/component/materials.hpp @@ -3,4 +3,5 @@ namespace materials { void add(const std::string& name, const std::string& data); + void clear(); } diff --git a/src/client/component/mods.cpp b/src/client/component/mods.cpp new file mode 100644 index 00000000..ea6a9027 --- /dev/null +++ b/src/client/component/mods.cpp @@ -0,0 +1,119 @@ +#include +#include "loader/component_loader.hpp" + +#include "game/game.hpp" +#include "game/dvars.hpp" + +#include "command.hpp" +#include "console.hpp" +#include "scheduler.hpp" +#include "filesystem.hpp" +#include "materials.hpp" +#include "fonts.hpp" +#include "mods.hpp" + +#include +#include + +namespace mods +{ + std::string mod_path{}; + + namespace + { + utils::hook::detour db_release_xassets_hook; + bool release_assets = false; + + void db_release_xassets_stub() + { + if (release_assets) + { + materials::clear(); + fonts::clear(); + } + + db_release_xassets_hook.invoke(); + } + + void restart() + { + scheduler::once([]() + { + release_assets = true; + game::Com_Shutdown(""); + release_assets = false; + }, scheduler::pipeline::main); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + if (!game::environment::is_sp()) + { + return; + } + + if (!utils::io::directory_exists("mods")) + { + utils::io::create_directory("mods"); + } + + db_release_xassets_hook.create(SELECT_VALUE(0x1401CD560, 0x1402BF160), db_release_xassets_stub); + + command::add("loadmod", [](const command::params& params) + { + if (params.size() < 2) + { + console::info("Usage: loadmod mods/"); + return; + } + + if (!game::Com_InFrontend()) + { + console::info("Cannot load mod while in-game!\n"); + game::CG_GameMessage(0, "^1Cannot unload mod while in-game!"); + return; + } + + const auto path = params.get(1); + if (!utils::io::directory_exists(path)) + { + console::info("Mod %s not found!\n", path); + return; + } + + console::info("Loading mod %s\n", path); + filesystem::get_search_paths().erase(mod_path); + filesystem::get_search_paths().insert(path); + mod_path = path; + restart(); + }); + + command::add("unloadmod", [](const command::params& params) + { + if (mod_path.empty()) + { + console::info("No mod loaded\n"); + return; + } + + if (!game::Com_InFrontend()) + { + console::info("Cannot unload mod while in-game!\n"); + game::CG_GameMessage(0, "^1Cannot unload mod while in-game!"); + return; + } + + console::info("Unloading mod %s\n", mod_path.data()); + filesystem::get_search_paths().erase(mod_path); + mod_path.clear(); + restart(); + }); + } + }; +} + +REGISTER_COMPONENT(mods::component) diff --git a/src/client/component/mods.hpp b/src/client/component/mods.hpp new file mode 100644 index 00000000..364a2f11 --- /dev/null +++ b/src/client/component/mods.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace mods +{ + extern std::string mod_path; +} \ No newline at end of file diff --git a/src/client/game/scripting/lua/engine.cpp b/src/client/game/scripting/lua/engine.cpp index 390a5995..936c8e1f 100644 --- a/src/client/game/scripting/lua/engine.cpp +++ b/src/client/game/scripting/lua/engine.cpp @@ -4,6 +4,7 @@ #include "../execution.hpp" #include "../../../component/logfile.hpp" +#include "../../../component/filesystem.hpp" #include @@ -49,18 +50,17 @@ namespace scripting::lua::engine { stop(); - load_scripts("h1-mod/scripts/"); - load_scripts("data/scripts/"); - - if (game::environment::is_sp()) + for (const auto& path : filesystem::get_search_paths()) { - load_scripts("h1-mod/scripts/sp/"); - load_scripts("data/scripts/sp/"); - } - else - { - load_scripts("h1-mod/scripts/mp/"); - load_scripts("data/scripts/mp/"); + load_scripts(path + "/scripts/"); + if (game::environment::is_sp()) + { + load_scripts(path + "/scripts/sp/"); + } + else + { + load_scripts(path + "/scripts/mp/"); + } } running = true; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 6653b555..58058533 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -33,10 +33,12 @@ namespace game WEAK symbol Com_Frame_Try_Block_Function{0x1401CE8D0, 0x1400D8310}; WEAK symbol Com_GetCurrentCoDPlayMode{0, 0x1405039A0}; - WEAK symbol Com_InFrontEnd{0x1400E4B30, 0x140176A30}; + WEAK symbol Com_InFrontend{0x1400E4B30, 0x140176A30}; WEAK symbol Com_SetSlowMotion{0, 0x1400DB790}; WEAK symbol Com_Error{0x1403509C0, 0x1400D78A0}; WEAK symbol Com_Quit_f{0x140352BE0, 0x1400DA830}; + WEAK symbol Com_Shutdown{0x140353B70, 0x1400DB8A0}; + WEAK symbol Quit{0x140352D90, 0x1400DA830}; WEAK symbol CG_GameMessage{0x1401389A0, 0x140220CC0}; @@ -47,6 +49,7 @@ namespace game bool isAlternate, char* outputBuffer, int bufferLen)> CG_GetWeaponDisplayName{0x14016EC30, 0x1400B5840}; WEAK symbol CL_IsCgameInitialized{0x14017EE30, 0x140245650}; + WEAK symbol CL_VirtualLobbyShutdown{0, 0x140256D40}; WEAK symbol Dvar_SetCommand{0x1403C72B0, 0x1404FD0A0}; WEAK symbol Dvar_FindVar{0x1403C5D50, 0x1404FBB00}; diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index 1db94910..d9a930f9 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -13,6 +13,7 @@ #include "../../../component/localized_strings.hpp" #include "../../../component/fastfiles.hpp" #include "../../../component/scripting.hpp" +#include "../../../component/mods.hpp" #include "component/game_console.hpp" #include "component/scheduler.hpp" @@ -25,6 +26,31 @@ namespace ui_scripting::lua { namespace { + const auto json_script = utils::nt::load_resource(LUA_JSON); + + void setup_json(sol::state& state) + { + const auto json = state.safe_script(json_script, &sol::script_pass_on_error); + handle_error(json); + state["json"] = json; + } + + void setup_io(sol::state& state) + { + state["io"]["fileexists"] = utils::io::file_exists; + state["io"]["writefile"] = utils::io::write_file; + state["io"]["movefile"] = utils::io::move_file; + state["io"]["filesize"] = utils::io::file_size; + state["io"]["createdirectory"] = utils::io::create_directory; + state["io"]["directoryexists"] = utils::io::directory_exists; + state["io"]["directoryisempty"] = utils::io::directory_is_empty; + state["io"]["listfiles"] = utils::io::list_files; + state["io"]["copyfolder"] = utils::io::copy_folder; + state["io"]["removefile"] = utils::io::remove_file; + state["io"]["removedirectory"] = utils::io::remove_directory; + state["io"]["readfile"] = static_cast(utils::io::read_file); + } + void setup_types(sol::state& state, scheduler& scheduler) { struct game @@ -138,6 +164,11 @@ namespace ui_scripting::lua return std::string(buffer); }; + game_type["getloadedmod"] = [](const game&) + { + return mods::mod_path; + }; + auto userdata_type = state.new_usertype("userdata_"); userdata_type["new"] = sol::property( @@ -322,6 +353,8 @@ namespace ui_scripting::lua sol::lib::math, sol::lib::table); + setup_json(this->state_); + setup_io(this->state_); setup_types(this->state_, this->scheduler_); if (type == script_type::file) diff --git a/src/client/game/ui_scripting/lua/engine.cpp b/src/client/game/ui_scripting/lua/engine.cpp index cc3d3d33..a52b1b9e 100644 --- a/src/client/game/ui_scripting/lua/engine.cpp +++ b/src/client/game/ui_scripting/lua/engine.cpp @@ -3,6 +3,7 @@ #include "context.hpp" #include "../../../component/ui_scripting.hpp" +#include "../../../component/filesystem.hpp" #include #include @@ -52,18 +53,17 @@ namespace ui_scripting::lua::engine load_code(lui_common); load_code(lui_updater); - load_scripts("h1-mod/ui_scripts/"); - load_scripts("data/ui_scripts/"); - - if (game::environment::is_sp()) + for (const auto& path : filesystem::get_search_paths()) { - load_scripts("h1-mod/ui_scripts/sp/"); - load_scripts("data/ui_scripts/sp/"); - } - else - { - load_scripts("h1-mod/ui_scripts/mp/"); - load_scripts("data/ui_scripts/mp/"); + load_scripts(path + "/ui_scripts/"); + if (game::environment::is_sp()) + { + load_scripts(path + "/ui_scripts/sp/"); + } + else + { + load_scripts(path + "/ui_scripts/mp/"); + } } } diff --git a/src/client/resource.hpp b/src/client/resource.hpp index adc92d9c..ceb43a33 100644 --- a/src/client/resource.hpp +++ b/src/client/resource.hpp @@ -18,3 +18,5 @@ #define LUI_COMMON 309 #define LUI_UPDATER 310 + +#define LUA_JSON 311 diff --git a/src/client/resource.rc b/src/client/resource.rc index c53c106a..2996abfa 100644 --- a/src/client/resource.rc +++ b/src/client/resource.rc @@ -121,6 +121,8 @@ ICON_IMAGE RCDATA "resources/icon.png" LUI_COMMON RCDATA "resources/ui_scripts/common.lua" LUI_UPDATER RCDATA "resources/ui_scripts/updater.lua" +LUA_JSON RCDATA "resources/json.lua" + #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/client/resources/json.lua b/src/client/resources/json.lua new file mode 100644 index 00000000..711ef786 --- /dev/null +++ b/src/client/resources/json.lua @@ -0,0 +1,388 @@ +-- +-- json.lua +-- +-- Copyright (c) 2020 rxi +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy of +-- this software and associated documentation files (the "Software"), to deal in +-- the Software without restriction, including without limitation the rights to +-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +-- of the Software, and to permit persons to whom the Software is furnished to do +-- so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in all +-- copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-- SOFTWARE. +-- + +local json = { _version = "0.1.2" } + +------------------------------------------------------------------------------- +-- Encode +------------------------------------------------------------------------------- + +local encode + +local escape_char_map = { + [ "\\" ] = "\\", + [ "\"" ] = "\"", + [ "\b" ] = "b", + [ "\f" ] = "f", + [ "\n" ] = "n", + [ "\r" ] = "r", + [ "\t" ] = "t", +} + +local escape_char_map_inv = { [ "/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if rawget(val, 1) ~= nil or next(val) == nil then + -- Treat as array -- check keys are valid and it is not sparse + local n = 0 + for k in pairs(val) do + if type(k) ~= "number" then + error("invalid table: mixed or invalid key types") + end + n = n + 1 + end + if n ~= #val then + error("invalid table: sparse array") + end + -- Encode + for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) + end + stack[val] = nil + return "[" .. table.concat(res, ",") .. "]" + + else + -- Treat as an object + for k, v in pairs(val) do + if type(k) ~= "string" then + error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) + end + stack[val] = nil + return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + -- Check for NaN, -inf and inf + if val ~= val or val <= -math.huge or val >= math.huge then + error("unexpected number value '" .. tostring(val) .. "'") + end + return string.format("%.14g", val) +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then + return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + + +function json.encode(val) + return ( encode(val) ) +end + + +------------------------------------------------------------------------------- +-- Decode +------------------------------------------------------------------------------- + +local parse + +local function create_set(...) + local res = {} + for i = 1, select("#", ...) do + res[ select(i, ...) ] = true + end + return res +end + +local space_chars = create_set(" ", "\t", "\r", "\n") +local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") +local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") +local literals = create_set("true", "false", "null") + +local literal_map = { + [ "true" ] = true, + [ "false" ] = false, + [ "null" ] = nil, +} + + +local function next_char(str, idx, set, negate) + for i = idx, #str do + if set[str:sub(i, i)] ~= negate then + return i + end + end + return #str + 1 +end + + +local function decode_error(str, idx, msg) + local line_count = 1 + local col_count = 1 + for i = 1, idx - 1 do + col_count = col_count + 1 + if str:sub(i, i) == "\n" then + line_count = line_count + 1 + col_count = 1 + end + end + error( string.format("%s at line %d col %d", msg, line_count, col_count) ) +end + + +local function codepoint_to_utf8(n) + -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa + local f = math.floor + if n <= 0x7f then + return string.char(n) + elseif n <= 0x7ff then + return string.char(f(n / 64) + 192, n % 64 + 128) + elseif n <= 0xffff then + return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) + elseif n <= 0x10ffff then + return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, + f(n % 4096 / 64) + 128, n % 64 + 128) + end + error( string.format("invalid unicode codepoint '%x'", n) ) +end + + +local function parse_unicode_escape(s) + local n1 = tonumber( s:sub(1, 4), 16 ) + local n2 = tonumber( s:sub(7, 10), 16 ) + -- Surrogate pair? + if n2 then + return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) + else + return codepoint_to_utf8(n1) + end +end + + +local function parse_string(str, i) + local res = "" + local j = i + 1 + local k = j + + while j <= #str do + local x = str:byte(j) + + if x < 32 then + decode_error(str, j, "control character in string") + + elseif x == 92 then -- `\`: Escape + res = res .. str:sub(k, j - 1) + j = j + 1 + local c = str:sub(j, j) + if c == "u" then + local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) + or str:match("^%x%x%x%x", j + 1) + or decode_error(str, j - 1, "invalid unicode escape in string") + res = res .. parse_unicode_escape(hex) + j = j + #hex + else + if not escape_chars[c] then + decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") + end + res = res .. escape_char_map_inv[c] + end + k = j + 1 + + elseif x == 34 then -- `"`: End of string + res = res .. str:sub(k, j - 1) + return res, j + 1 + end + + j = j + 1 + end + + decode_error(str, i, "expected closing quote for string") +end + + +local function parse_number(str, i) + local x = next_char(str, i, delim_chars) + local s = str:sub(i, x - 1) + local n = tonumber(s) + if not n then + decode_error(str, i, "invalid number '" .. s .. "'") + end + return n, x +end + + +local function parse_literal(str, i) + local x = next_char(str, i, delim_chars) + local word = str:sub(i, x - 1) + if not literals[word] then + decode_error(str, i, "invalid literal '" .. word .. "'") + end + return literal_map[word], x +end + + +local function parse_array(str, i) + local res = {} + local n = 1 + i = i + 1 + while 1 do + local x + i = next_char(str, i, space_chars, true) + -- Empty / end of array? + if str:sub(i, i) == "]" then + i = i + 1 + break + end + -- Read token + x, i = parse(str, i) + res[n] = x + n = n + 1 + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "]" then break end + if chr ~= "," then decode_error(str, i, "expected ']' or ','") end + end + return res, i +end + + +local function parse_object(str, i) + local res = {} + i = i + 1 + while 1 do + local key, val + i = next_char(str, i, space_chars, true) + -- Empty / end of object? + if str:sub(i, i) == "}" then + i = i + 1 + break + end + -- Read key + if str:sub(i, i) ~= '"' then + decode_error(str, i, "expected string for key") + end + key, i = parse(str, i) + -- Read ':' delimiter + i = next_char(str, i, space_chars, true) + if str:sub(i, i) ~= ":" then + decode_error(str, i, "expected ':' after key") + end + i = next_char(str, i + 1, space_chars, true) + -- Read value + val, i = parse(str, i) + -- Set + res[key] = val + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "}" then break end + if chr ~= "," then decode_error(str, i, "expected '}' or ','") end + end + return res, i +end + + +local char_func_map = { + [ '"' ] = parse_string, + [ "0" ] = parse_number, + [ "1" ] = parse_number, + [ "2" ] = parse_number, + [ "3" ] = parse_number, + [ "4" ] = parse_number, + [ "5" ] = parse_number, + [ "6" ] = parse_number, + [ "7" ] = parse_number, + [ "8" ] = parse_number, + [ "9" ] = parse_number, + [ "-" ] = parse_number, + [ "t" ] = parse_literal, + [ "f" ] = parse_literal, + [ "n" ] = parse_literal, + [ "[" ] = parse_array, + [ "{" ] = parse_object, +} + + +parse = function(str, idx) + local chr = str:sub(idx, idx) + local f = char_func_map[chr] + if f then + return f(str, idx) + end + decode_error(str, idx, "unexpected character '" .. chr .. "'") +end + + +function json.decode(str) + if type(str) ~= "string" then + error("expected argument of type string, got " .. type(str)) + end + local res, idx = parse(str, next_char(str, 1, space_chars, true)) + idx = next_char(str, idx, space_chars, true) + if idx <= #str then + decode_error(str, idx, "trailing garbage") + end + return res +end + + +return json diff --git a/src/common/utils/io.cpp b/src/common/utils/io.cpp index 4968f449..9b161d39 100644 --- a/src/common/utils/io.cpp +++ b/src/common/utils/io.cpp @@ -104,6 +104,11 @@ namespace utils::io return std::filesystem::is_empty(directory); } + bool remove_directory(const std::string& directory) + { + return std::filesystem::remove_all(directory); + } + std::vector list_files(const std::string& directory) { std::vector files; diff --git a/src/common/utils/io.hpp b/src/common/utils/io.hpp index ab4ebaa4..38344987 100644 --- a/src/common/utils/io.hpp +++ b/src/common/utils/io.hpp @@ -16,6 +16,7 @@ namespace utils::io bool create_directory(const std::string& directory); bool directory_exists(const std::string& directory); bool directory_is_empty(const std::string& directory); + bool remove_directory(const std::string& directory); std::vector list_files(const std::string& directory); void copy_folder(const std::filesystem::path& src, const std::filesystem::path& target); } From a9b0ecd71c3e11d15ed156200d3c6fe141545bac Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 8 Apr 2022 18:24:35 +0200 Subject: [PATCH 142/346] Some fixes --- src/client/component/logfile.cpp | 4 ++-- src/client/game/scripting/lua/engine.cpp | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp index d1886ca0..08ce07dd 100644 --- a/src/client/component/logfile.cpp +++ b/src/client/component/logfile.cpp @@ -296,6 +296,8 @@ namespace logfile public: void post_unpack() override { + utils::hook::jump(SELECT_VALUE(0x140376655, 0x140444645), utils::hook::assemble(vm_execute_stub), true); + if (game::environment::is_sp()) { return; @@ -308,8 +310,6 @@ namespace logfile utils::hook::call(0x140484EC0, g_shutdown_game_stub); utils::hook::call(0x1404853C1, g_shutdown_game_stub); - - utils::hook::jump(SELECT_VALUE(0x140376655, 0x140444645), utils::hook::assemble(vm_execute_stub), true); } }; } diff --git a/src/client/game/scripting/lua/engine.cpp b/src/client/game/scripting/lua/engine.cpp index 936c8e1f..6d025409 100644 --- a/src/client/game/scripting/lua/engine.cpp +++ b/src/client/game/scripting/lua/engine.cpp @@ -49,7 +49,7 @@ namespace scripting::lua::engine void start() { stop(); - + running = true; for (const auto& path : filesystem::get_search_paths()) { load_scripts(path + "/scripts/"); @@ -62,8 +62,6 @@ namespace scripting::lua::engine load_scripts(path + "/scripts/mp/"); } } - - running = true; } void notify(const event& e) From abdb230e91932d184420e468b62a5da0801416fc Mon Sep 17 00:00:00 2001 From: Clayton <42688647+netadr@users.noreply.github.com> Date: Sat, 9 Apr 2022 01:15:51 -0400 Subject: [PATCH 143/346] Add debug-dir option for setting the VS working directory (#43) --- premake5.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/premake5.lua b/premake5.lua index 9823d960..fc9e6e5b 100644 --- a/premake5.lua +++ b/premake5.lua @@ -321,6 +321,10 @@ if _OPTIONS["copy-to"] then postbuildcommands {"copy /y \"$(TargetPath)\" \"" .. _OPTIONS["copy-to"] .. "\""} end +if _OPTIONS["debug-dir"] then + debugdir ( _OPTIONS["debug-dir"] ) +end + dependencies.imports() project "tlsdll" From 7de974e9c8eaf94a7798026466873d4ff06c7938 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 10 Apr 2022 21:40:20 +0200 Subject: [PATCH 144/346] Add g_dumpScripts dvar --- src/client/component/scripting.cpp | 33 ++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index 9aa37307..b31e2329 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -2,6 +2,7 @@ #include "loader/component_loader.hpp" #include "game/game.hpp" +#include "game/dvars.hpp" #include "game/scripting/entity.hpp" #include "game/scripting/functions.hpp" @@ -13,6 +14,8 @@ #include "scripting.hpp" #include +#include +#include namespace scripting { @@ -34,9 +37,13 @@ namespace scripting utils::hook::detour sl_get_canonical_string_hook; + utils::hook::detour db_find_xasset_header_hook; + std::string current_file; unsigned int current_file_id{}; + game::dvar_t* g_dump_scripts; + void vm_notify_stub(const unsigned int notify_list_owner_id, const game::scr_string_t string_value, game::VariableValue* top) { @@ -152,6 +159,26 @@ namespace scripting scripting::token_map[str] = result; return result; } + + game::XAssetHeader db_find_xasset_header_stub(game::XAssetType type, const char* name, int allow_create_default) + { + const auto result = db_find_xasset_header_hook.invoke(type, name, allow_create_default); + if (!g_dump_scripts->current.enabled || type != game::XAssetType::ASSET_TYPE_SCRIPTFILE) + { + return result; + } + + std::string buffer; + buffer.append(result.scriptfile->name, strlen(result.scriptfile->name) + 1); + buffer.append(reinterpret_cast(&result.scriptfile->compressedLen), 4); + buffer.append(reinterpret_cast(&result.scriptfile->len), 4); + buffer.append(reinterpret_cast(&result.scriptfile->bytecodeLen), 4); + buffer.append(result.scriptfile->buffer, result.scriptfile->compressedLen); + buffer.append(result.scriptfile->bytecode, result.scriptfile->bytecodeLen); + utils::io::write_file(utils::string::va("gsc_dump/%s.gscbin", name), buffer); + + return result; + } } class component final : public component_interface @@ -165,6 +192,7 @@ namespace scripting scr_set_thread_position_hook.create(SELECT_VALUE(0x14036A180, 0x140437D10), scr_set_thread_position_stub); process_script_hook.create(SELECT_VALUE(0x1403737E0, 0x1404417E0), process_script_stub); + sl_get_canonical_string_hook.create(game::SL_GetCanonicalString, sl_get_canonical_string_stub); if (!game::environment::is_sp()) { @@ -177,7 +205,8 @@ namespace scripting g_shutdown_game_hook.create(SELECT_VALUE(0x140277D40, 0x140345A60), g_shutdown_game_stub); - sl_get_canonical_string_hook.create(game::SL_GetCanonicalString, sl_get_canonical_string_stub); + db_find_xasset_header_hook.create(game::DB_FindXAssetHeader, db_find_xasset_header_stub); + g_dump_scripts = dvars::register_bool("g_dumpScripts", false, game::DVAR_FLAG_NONE, "Dump GSC scripts"); scheduler::loop([]() { @@ -187,4 +216,4 @@ namespace scripting }; } -REGISTER_COMPONENT(scripting::component) \ No newline at end of file +REGISTER_COMPONENT(scripting::component) From b30b690b1ab2c8548664d33aa5cdd092c9c29371 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 10 Apr 2022 21:40:27 +0200 Subject: [PATCH 145/346] Update main.html --- src/client/resources/main.html | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/client/resources/main.html b/src/client/resources/main.html index 887b6863..52a2756f 100644 --- a/src/client/resources/main.html +++ b/src/client/resources/main.html @@ -18,8 +18,7 @@ body { -ms-overflow-style: none; margin: 0; - /* Also we can use image incoder https://www.base64-image.de/ */ - background: url(https://cdn.discordapp.com/attachments/895680402142941194/935150813901365268/360_F_176672598_cJ4yPCFhxvDXm9Cu7vDLIcXpvTMQJ9zm.jpg) no-repeat center center fixed; + background: url('data:image/jpeg;base64,/9j/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAA8cAVoAAxslRxwBAAACAAQA/+EMgWh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSfvu78nIGlkPSdXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQnPz4KPHg6eG1wbWV0YSB4bWxuczp4PSdhZG9iZTpuczptZXRhLycgeDp4bXB0az0nSW1hZ2U6OkV4aWZUb29sIDEwLjEwJz4KPHJkZjpSREYgeG1sbnM6cmRmPSdodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjJz4KCiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0nJwogIHhtbG5zOnRpZmY9J2h0dHA6Ly9ucy5hZG9iZS5jb20vdGlmZi8xLjAvJz4KICA8dGlmZjpSZXNvbHV0aW9uVW5pdD4yPC90aWZmOlJlc29sdXRpb25Vbml0PgogIDx0aWZmOlhSZXNvbHV0aW9uPjMwMC8xPC90aWZmOlhSZXNvbHV0aW9uPgogIDx0aWZmOllSZXNvbHV0aW9uPjMwMC8xPC90aWZmOllSZXNvbHV0aW9uPgogPC9yZGY6RGVzY3JpcHRpb24+CgogPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9JycKICB4bWxuczp4bXBNTT0naHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyc+CiAgPHhtcE1NOkRvY3VtZW50SUQ+YWRvYmU6ZG9jaWQ6c3RvY2s6Y2YxZTI3ZTYtN2Q3ZS00MTg4LTlhOGItNzAyNzdiOTRmZmExPC94bXBNTTpEb2N1bWVudElEPgogIDx4bXBNTTpJbnN0YW5jZUlEPnhtcC5paWQ6ZWQwYmQ4OTItYWMzOS00MTdmLWFkNmQtNTQyM2EyY2IzNDI5PC94bXBNTTpJbnN0YW5jZUlEPgogPC9yZGY6RGVzY3JpcHRpb24+CjwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9J3cnPz7/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/wAALCAFoAhwBAREA/8QAGQABAQEBAQEAAAAAAAAAAAAAAQIAAwQH/8QAGRABAQEBAQEAAAAAAAAAAAAAAAERAhJh/9oACAEBAAA/APhXNdOavmunNdOa6c1fNdOa6c105rpzV810lXzVyrlXKuVcqpVyrlVKqVUqpVSnTp062tra2totGi0Wi1NqbU2ptTam1FqbUWotTai1FqLUWotRai1HVRa52o6qLUWo6qLUWvPzXTmr5rpzXTmr5rpzXTmunNXzXTmunNXKvmrlXKuVcqpVyrlVKqVUqpVTpUplMp062tp0a3oaLRaLRam0WptTai1NqbUWptRanqotRai1FqLUWotR1UWotR1UWotR1UWotcOavmr5rpzXTmr5rpzXTmr5rpzV810lXKvmrlXKuVUq5VyqlVKuVUqpVSmVUradOtra2traNGtqbRam0WptTam1NqLU2ptRai1NqLUWotRai1Nrnai1FqLU2udqbUWotcOavmunNXzXTmr5rpzV8105q+avmunNXKuVcq5VSrlXKqVUq5VSqlVKqUyqlOtp1tOto1tGj0NFotFqbU2ptTam1NqbUWptRam1FqLUWp6qLUWotRai1FqLUWotRam1w5q+a6c1fNXzXSVfNdOavmr5rpzV81cq5VyqlXKuVUq5VSqlVKqVUqpTKqdHTra2nRra2jW0WjU2i1NotTam1NqbUWptTai1NqLUWptRai1FqLU2otRai1HVRai1OuHNXzXTmr5q5XSVfNXzV8105q+auVcq5VSrlXKqVcqpVSqlXKZVSqlMqtOnW062to1tGto0am0WptFqbU2ptTam1NqLU2otTai1NqLUWptRai1FqLUWptRai1OuErpzVyr5q+auVcrpKvmr5q5VyrlXKqVcqpVyqlXKqVUqpVSmVUplVKZTradb03oa2totGi0WptFqbRam1NqbU2otTam1FqbUWptRam1FqLUWptRai1FqbUWptcZVyrlXKuVfNXzVyr5q5V81cq5VyqlXKqVcqpVSqlVKqVUqpTKZVadOnW1tbW0a2jRo0WptFotTam1NqbU2ptTam1FqbUWptRam1FqbUWotTai1FqbUWptcZVyrlXKvmrlXKuVcq5VyrlVKuVUq5VSqlXKqVUqpTKqVUplVplMp1vR1tbW0a2i0aLRaLRam1NotTam1NqbU2otTam1FqbU2otTai1FqbUWptRai1NqdcZV81cq5VSrlXKuVcq5VyrlVKuVUq5VSqlVKqVUqpVSqlMqpTKdOnTra2tra2jRotGjRaLU2i1NqbRam1NqLU2ptTam1FqbUWptRam1FqbUWptRam1OuMq5VyrlVKuVcq5VSr5q5VyqlXKqVUqpVyqlVKqUyqlVKZVTo6Z0fR9N6PpvTa3oa2jW9C9C9J0XoXpNotTam1NqbU2ptTam1NqLU2ptRam1FqbUWptRam1NqdcZVyqlXKuVUq5VyqlXKuVUq5VSqlXKqVUqpVSqlM6VOjOlTozoyq9N6Po+m9H03pvQ9N6HoXoeheheheham9C1NqbU2i1NqbUWptTam1NqLU2ptRam1NqLU2otTanXKVUq5VSrlXKqVcqpVyrlVKqVcqpVSqlVKqVUqpTOlSmdKnRnRnR0zpvR9H03pvTem0em9D0PQvQtFqbRaLU2ptTaLU2ptTam1NqbUWptTam1FqbU2otTam1NqdcpVSqlXKqVcqpVyqlXKqVcqpVSqlVKqVUqpVSmVUqp0Z0Z0dV6b0fR9H03pvR9N6HpvQ9N6F6FotFqbRaLU2ptFqbU2ptTam1NqbU2ptTam1FqbU2ptTai1No1xlXKqVUq5VSrlVKqVcqpVSrlVKqVUplVKqVUpnSp0dVOjKfR9HTp9Np1vTem9N6Gto9DW1NranRam0WptFqbU2i1NqbU2ptTam1NqbU2otTam1NqbU2ptcpVSrlVKqVUq5VSqlXKqVUqpVSqlVKqVUplVKqUymVU6OnTp9N6Po63pvR9N6b0PTeheh6GjRaLRaLU2i1NqbRam1NqbRam1NqbU2ptTam1NqLU2ptTaNcpVSqlVKuVUqpVSrlVKqVUqpVSqlVKZVSmVUqpTKdVKZ0fR063o+m9H03pvTem9NrWjR6Gi0XoaLRam0WptFqbRam1NqbU2i1NqbU2ptTam1NqbU2ptTa5yqlVKqVUqpVSqlXKqVUqpVSmVUqpVSmVUplVKZTKdVplOtp0+m0+m1vTem1vTaNGi0aLRaLRaLU2i1NotTam0WptTam0WptTam1NqbU2ptFqbU65yqlVKqVUqpVSqlVKqVUqpVSmVUqpTKqUyqlMp1Up0ynT6bT6Otrej6bW1tb0NbR6GtaNTotFo0WptFqbRam0WptTam0WptTam1NotTam1NqbRrnKZVSqlVKqVUqpVSqlVKqUyqlVKZVSmVUplMqtOmU6ZTradbTradbW1tbRraNGtotGi1No0aLU2i1NotTaLU2ptFqbU2i1NqbU2i1NqbRrnKZVSqlVKqVUqpTKqVUqpTKqVUplMqpTKqUymUymU6dOtp062tp1vTem9N6Gto1tGi0Wi0Wi0WptFotTaLU2i1NqbRam0WptTaLU2ptFqbRrnKZVSqlVKZVSqlVKqUyqlMqpTKqUyqlMplMplOnTp06dbTra2nW1tbW0a2to0aNFo0Wi0Wi0WptFotTaLU2i1NotTam0WptFqbU2i0a5ymVUqpTKqVUqpTKqVUplVKZTKqUymVUp0ymU6dOtp062nW062tra2traNbRraNGjRaLRotFqbRaLU2i1NotFqbU2i1NotTaLU2i1OolMqpTKqVUplVKqUyqlMqpTKZVSmU6ZVSmU6dbTp062nW062tra2tra2to1tGjW0aLRaNFqbRaLRam0Wi1Oi1NotFqbRam0WptFo1zlMqpTKqUyqlVKZVSmVUplMqpTKZTp06dOnTp062nW062tradbW0a2traNbRo0WjWtGptFotFotFqbRaLU2i0WptFqbRam0Wi0a5ymVUplVKZVSmVUplVKZTKqU6ZTplOmU6dOnTradbTradbW1tbW1tbW0a2jW0aNGjRaLRotFotGptFotFqbRaLRam0am0Wi0a5yqlMplVKdVKZVSmUyqlOmUynTplOmU6dOnW06dbTra2nW1tbW1tbRra2jW0aNGjRo1tTaLRaLRaLRam0Wi0am0Wi1OjRaNRKZTKqUymVUplMqpTplMp06qVtVradOnTradOtp1tOtra2tp0a2tra2jW0a2jRaNbRotGjRaLU6LRaNFotTaNFotFqbRaESmUyqlMplVKZTplVKdOmU6ZTKdMp1tOnTradbTra2nW1tbW1tbW1tbRraNbRraLRotGjRaNFotGi0WjU2i0WjRaLRqbQiKhlMplMqpTplMp0ymU6qVtOnTp062nTradbTra2nW1tbW1tbW1tbRrb9Gto1tGjRo1rRotGjRaNTotGjRaNGi0WjQgwynTKqUymUynTplOmU6dOnW06dOtp062nfra2nW1tbW362/W362tra2jW1tGto0a1o0WjRaNFo0aLRo0WjRaLRotFotCITqjDKdMp06ZTplOnTp1tOnTradOtrb9Otradbfrb9bTra2to362/W362jW0b9bW0aNFo1tGi0aLRo0WjRaNGijRoo1kSmGU6TplMp0ynTp06dbTp0ytp062nW062nW1tOtra2tra2traNbW0a2jW0a2jRo1rRotGi0aNGjWo0UaNA0JlJlbTDph06ZTplOmU62nTK2nTraZTra2nfra2nW1tbfra2trb9bW1tGtraNbW0aNbRo0a2jRo0aNa0aKNA0aG0IlJOk6Tp0tp06dOtp062nW06dbW062tp362tp1tbW1tbW0a2tv0a2traNbRo1tFo1rRotGitoGgaG0DQNSdJ1jKTp0nW06dOtpOtp1tOtp1tOtv1tOtra2tv1t+tv1t+tv1tbW1tGtraNbW0aNbRo1tGjW0DQNYaBoFrDUmVjpMpLadJ1jpbTp1tOtp1tOtradZtOtra2tra2tra2to1tbRra2jW0a2jQ2ga2gaG0DQ2gaG1OsZSdLaTp1jpbTp1tLadbTra2nW062tra2nfrb9bfra2tv1t+tv0a2traNbRra2jW0aw0No0NoGhtA1gNZLGUtpOltJbSdbS2nWOtpbTraxbW1tbW062tra2jW1tbW1g2to1hrawGsNGsNDaA2gaw0JMpbSTrHS2nWOnWOtpbTrMdbW1tLa2tp1tbW1tbW0a2trDW1tbWDaNYa2htGhtA1tA1gGGplJbSdLHWOljrFtOs2nW0tra2nWbTra2tra2tra2tobWbW0a2sNbRrNo1ho1hraBrBtA1gGOsdLHSx1jraWOtrHW06zNp1tbWLM2tra2trMwZtbRrM2jW0NraGGhhrBtDaA2hJ0tpY6WOsW06x1tLNp1tYtra2nW1mZmZmZmZtGtrawbW0azDW0No1ho1m0aGGsAx1i2ljpZtOlm06zHW0szadbW1mZizMwZmbW1tGszDW0M2jWYaGbQG0azDQG0sdLNpY62ljraWbW06zHW1tbW0szMzMzMzDW1tbW0M2jW1mGtoYawbRrMNDNr/2Q==') no-repeat center center fixed; background-size: cover; background-position: center; background-repeat: no-repeat; @@ -416,8 +415,7 @@
- - +
Singleplayer @@ -435,7 +433,7 @@
- +
Multiplayer @@ -462,7 +460,7 @@
-
+

Special thanks to all contributors.

This project is based on S1x and H2-mod. From 6b8915a3eca31eec04a24c8ec9c7b696c3cfe541 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sun, 10 Apr 2022 22:10:10 +0200 Subject: [PATCH 146/346] Create .gitattributes --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..fb3ee9ff --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.html linguist-detectable=false \ No newline at end of file From f65a942897c976794c242f0c8f66c8fe8a6fd965 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Mon, 11 Apr 2022 11:05:21 +0200 Subject: [PATCH 147/346] Discord in game join requests --- data/ui_scripts/discord/__init__.lua | 272 +++++++++++++++++++ src/client/component/discord.cpp | 116 +++++++- src/client/component/discord.hpp | 7 + src/client/component/input.cpp | 9 +- src/client/component/materials.cpp | 8 + src/client/component/materials.hpp | 1 + src/client/component/scheduler.cpp | 11 + src/client/component/scheduler.hpp | 3 + src/client/component/ui_scripting.cpp | 20 +- src/client/component/ui_scripting.hpp | 2 + src/client/game/ui_scripting/lua/context.cpp | 74 +++-- src/client/game/ui_scripting/types.cpp | 40 +++ src/client/game/ui_scripting/types.hpp | 13 + 13 files changed, 514 insertions(+), 62 deletions(-) create mode 100644 data/ui_scripts/discord/__init__.lua create mode 100644 src/client/component/discord.hpp diff --git a/data/ui_scripts/discord/__init__.lua b/data/ui_scripts/discord/__init__.lua new file mode 100644 index 00000000..cd2e70fc --- /dev/null +++ b/data/ui_scripts/discord/__init__.lua @@ -0,0 +1,272 @@ +if (game:issingleplayer() or Engine.InFrontend()) then + return +end + +local container = LUI.UIVerticalList.new({ + topAnchor = true, + rightAnchor = true, + top = 20, + right = 200, + width = 200, + spacing = 5, +}) + +function canasktojoin(userid) + history = history or {} + if (history[userid] ~= nil) then + return false + end + + history[userid] = true + game:ontimeout(function() + history[userid] = nil + end, 15000) + + return true +end + +function truncatename(name, length) + if (#name <= length - 3) then + return name + end + + return name:sub(1, length - 3) .. "..." +end + +function addrequest(request) + if (not canasktojoin(request.userid)) then + return + end + + if (container.temp) then + container:removeElement(container.temp) + container.temp = nil + end + + local invite = LUI.UIElement.new({ + leftAnchor = true, + rightAnchor = true, + height = 75, + }) + + invite:registerAnimationState("move_in", { + leftAnchor = true, + height = 75, + width = 200, + left = -220, + }) + + invite:animateToState("move_in", 100) + + local background = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + rightAnchor = true, + bottomAnchor = true, + top = 1, + left = 1, + bottom = -1, + right = -1, + material = luiglobals.RegisterMaterial("white"), + color = { + r = 0, + b = 0, + g = 0, + }, + alpha = 0.6, + }) + + local border = LUI.UIImage.new({ + topAnchor = true, + leftAnchor = true, + rightAnchor = true, + bottomAnchor = true, + material = luiglobals.RegisterMaterial("btn_focused_rect_innerglow"), + }) + + border:setup9SliceImage(10, 5, 0.25, 0.12) + + local paddingvalue = 10 + local padding = LUI.UIElement.new({ + topAnchor = true, + leftAnchor = true, + rightAnchor = true, + bottomAnchor = true, + top = paddingvalue, + left = paddingvalue, + right = -paddingvalue, + bottom = -paddingvalue, + }) + + local avatarmaterial = discord.getavatarmaterial(request.userid) + local avatar = LUI.UIImage.new({ + leftAnchor = true, + topAnchor = true, + width = 32, + height = 32, + left = 1, + material = luiglobals.RegisterMaterial(avatarmaterial) + }) + + local username = LUI.UIText.new({ + leftAnchor = true, + topAnchor = true, + height = 12, + left = 32 + paddingvalue, + color = luiglobals.Colors.white, + alignment = LUI.Alignment.Left, + rightAnchor = true, + font = CoD.TextSettings.BodyFontBold.Font + }) + + username:setText(string.format("%s^7#%s requested to join your game!", + truncatename(request.username, 18), request.discriminator)) + + local buttons = LUI.UIElement.new({ + leftAnchor = true, + rightAnchor = true, + topAnchor = true, + top = 37, + height = 18, + }) + + local createbutton = function(text, left) + local button = LUI.UIElement.new({ + leftAnchor = left, + rightAnchor = not left, + topAnchor = true, + height = 18, + width = 85, + material = luiglobals.RegisterMaterial("btn_focused_rect_innerglow"), + }) + + local center = LUI.UIText.new({ + rightAnchor = true, + height = 12, + width = 85, + top = -6.5, + alignment = LUI.Alignment.Center, + font = CoD.TextSettings.BodyFontBold.Font + }) + + button:setup9SliceImage(10, 5, 0.25, 0.12) + center:setText(text) + button:addElement(center) + + return button + end + + buttons:addElement(createbutton("[F1] Accept", true)) + buttons:addElement(createbutton("[F2] Deny")) + + local fadeouttime = 50 + local timeout = 10 * 1000 - fadeouttime + + local function close() + container:processEvent({ + name = "update_navigation", + dispatchToChildren = true + }) + invite:animateToState("fade_out", fadeouttime) + invite:addElement(LUI.UITimer.new(fadeouttime + 50, "remove")) + + invite:registerEventHandler("remove", function() + container:removeElement(invite) + if (container.temp) then + container:removeElement(container.temp) + container.temp = nil + end + local temp = LUI.UIElement.new({}) + container.temp = temp + container:addElement(temp) + end) + end + + buttons:registerEventHandler("keydown_", function(element, event) + if (event.key == "F1") then + close() + discord.respond(request.userid, discord.reply.yes) + end + + if (event.key == "F2") then + close() + discord.respond(request.userid, discord.reply.no) + end + end) + + invite:registerAnimationState("fade_out", { + leftAnchor = true, + rightAnchor = true, + height = 75, + alpha = 0, + left = 0 + }) + + invite:addElement(LUI.UITimer.new(timeout, "end_invite")) + invite:registerEventHandler("end_invite", function() + close() + discord.respond(request.userid, discord.reply.ignore) + end) + + local bar = LUI.UIImage.new({ + bottomAnchor = true, + leftAnchor = true, + bottom = -3, + left = 3, + width = 200 - 6, + material = luiglobals.RegisterMaterial("white"), + height = 2, + color = { + r = 92 / 255, + g = 206 / 255, + b = 113 / 255, + } + }) + + bar:registerAnimationState("closing", { + bottomAnchor = true, + leftAnchor = true, + bottom = -3, + left = 3, + width = 0, + height = 2, + }) + + bar:animateToState("closing", timeout) + + avatar:registerEventHandler("update", function() + local avatarmaterial = discord.getavatarmaterial(request.userid) + avatar:setImage(luiglobals.RegisterMaterial(avatarmaterial)) + end) + + avatar:addElement(LUI.UITimer.new(100, "update")) + + invite:addElement(background) + invite:addElement(bar) + invite:addElement(border) + invite:addElement(padding) + padding:addElement(username) + padding:addElement(avatar) + padding:addElement(buttons) + + container:addElement(invite) +end + +container:registerEventHandler("keydown", function(element, event) + local first = container:getFirstChild() + + if (not first) then + return + end + + first:processEvent({ + name = "keydown_", + key = event.key + }) +end) + +LUI.roots.UIRoot0:registerEventHandler("discord_join_request", function(element, event) + addrequest(event.request) +end) + +LUI.roots.UIRoot0:addElement(container) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index 455c510f..65fb74be 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -7,12 +7,25 @@ #include "command.hpp" #include "network.hpp" #include "party.hpp" +#include "materials.hpp" + +#include "ui_scripting.hpp" +#include "game/ui_scripting/execution.hpp" #include #include +#include #include +#define DEFAULT_AVATAR "discord_default_avatar" +#define AVATAR "discord_avatar_%s" + +#define DEFAULT_AVATAR_URL "https://cdn.discordapp.com/embed/avatars/0.png" +#define AVATAR_URL "https://cdn.discordapp.com/avatars/%s/%s.png?size=128" + +#include "discord.hpp" + namespace discord { namespace @@ -21,8 +34,6 @@ namespace discord void update_discord() { - Discord_RunCallbacks(); - if (!game::CL_IsCgameInitialized() || game::VirtualLobby_Loaded()) { discord_presence.details = game::environment::is_sp() ? "Singleplayer" : "Multiplayer"; @@ -105,6 +116,51 @@ namespace discord Discord_UpdatePresence(&discord_presence); } + + void download_user_avatar(const std::string& id, const std::string& avatar) + { + const auto data = utils::http::get_data( + utils::string::va(AVATAR_URL, id.data(), avatar.data())); + if (data.has_value()) + { + materials::add(utils::string::va(AVATAR, id.data()), data.value()); + } + } + + bool has_default_avatar = false; + void download_default_avatar() + { + const auto data = utils::http::get_data(DEFAULT_AVATAR_URL); + if (data.has_value()) + { + has_default_avatar = true; + materials::add(DEFAULT_AVATAR, data.value()); + } + } + } + + std::string get_avatar_material(const std::string& id) + { + const auto avatar_name = utils::string::va(AVATAR, id.data()); + if (materials::exists(avatar_name)) + { + return avatar_name; + } + + if (has_default_avatar) + { + return DEFAULT_AVATAR; + } + + return "black"; + } + + void respond(const std::string& id, int reply) + { + scheduler::once([=]() + { + Discord_Respond(id.data(), reply); + }, scheduler::pipeline::async); } class component final : public component_interface @@ -122,16 +178,19 @@ namespace discord handlers.ready = ready; handlers.errored = errored; handlers.disconnected = errored; - handlers.joinGame = joinGame; + handlers.joinGame = join_game; handlers.spectateGame = nullptr; - handlers.joinRequest = joinRequest; + handlers.joinRequest = join_request; Discord_Initialize("947125042930667530", &handlers, 1, nullptr); + scheduler::once(download_default_avatar, scheduler::pipeline::async); + scheduler::once([]() { scheduler::once(update_discord, scheduler::pipeline::async); scheduler::loop(update_discord, scheduler::pipeline::async, 5s); + scheduler::loop(Discord_RunCallbacks, scheduler::pipeline::async, 1s); }, scheduler::pipeline::main); initialized_ = true; @@ -153,11 +212,8 @@ namespace discord static void ready(const DiscordUser* request) { ZeroMemory(&discord_presence, sizeof(discord_presence)); - discord_presence.instance = 1; - console::info("Discord: Ready on %s (%s)\n", request->username, request->userId); - Discord_UpdatePresence(&discord_presence); } @@ -166,25 +222,55 @@ namespace discord console::error("Discord: Error (%i): %s\n", error_code, message); } - static void joinGame(const char* joinSecret) + static void join_game(const char* join_secret) { - console::info("Discord: Join game called with join secret: %s\n", joinSecret); + console::info("Discord: Join game called with join secret: %s\n", join_secret); - scheduler::once([joinSecret]() + std::string secret = join_secret; + scheduler::once([=]() { game::netadr_s target{}; - if (game::NET_StringToAdr(joinSecret, &target)) + if (game::NET_StringToAdr(secret.data(), &target)) { - console::info("Discord: Connecting to server: %s\n", joinSecret); + console::info("Discord: Connecting to server: %s\n", secret.data()); party::connect(target); } }, scheduler::pipeline::main); } - static void joinRequest(const DiscordUser* request) + static void join_request(const DiscordUser* request) { - console::info("Discord: joinRequest from %s (%s)\n", request->username, request->userId); - // Discord_Respond(request->userId, DISCORD_REPLY_YES); + console::info("Discord: join_request from %s (%s)\n", request->username, request->userId); + + if (game::Com_InFrontend() || !ui_scripting::lui_running()) + { + Discord_Respond(request->userId, DISCORD_REPLY_IGNORE); + return; + } + + std::string user_id = request->userId; + std::string avatar = request->avatar; + std::string discriminator = request->discriminator; + std::string username = request->username; + + scheduler::once([=]() + { + const ui_scripting::table request_table{}; + request_table.set("avatar", avatar); + request_table.set("discriminator", discriminator); + request_table.set("userid", user_id); + request_table.set("username", username); + + ui_scripting::notify("discord_join_request", + { + {"request", request_table} + }); + }, scheduler::pipeline::lui); + + if (!materials::exists(utils::string::va(AVATAR, user_id.data()))) + { + download_user_avatar(user_id, avatar); + } } }; } diff --git a/src/client/component/discord.hpp b/src/client/component/discord.hpp new file mode 100644 index 00000000..5399f952 --- /dev/null +++ b/src/client/component/discord.hpp @@ -0,0 +1,7 @@ +#pragma once + +namespace discord +{ + std::string get_avatar_material(const std::string& id); + void respond(const std::string& id, int reply); +} diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 7801bcbd..43aff87c 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -4,6 +4,7 @@ #include "game/game.hpp" #include "game_console.hpp" +#include "ui_scripting.hpp" #include "game/ui_scripting/execution.hpp" #include @@ -15,14 +16,10 @@ namespace input utils::hook::detour cl_char_event_hook; utils::hook::detour cl_key_event_hook; - bool lui_running() - { - return *game::hks::lua_state != nullptr; - } void cl_char_event_stub(const int local_client_num, const int key) { - if (lui_running()) + if (ui_scripting::lui_running()) { ui_scripting::notify("keypress", { @@ -41,7 +38,7 @@ namespace input void cl_key_event_stub(const int local_client_num, const int key, const int down) { - if (lui_running()) + if (ui_scripting::lui_running()) { ui_scripting::notify(down ? "keydown" : "keyup", { diff --git a/src/client/component/materials.cpp b/src/client/component/materials.cpp index 4fbb3ed8..c5fed9a2 100644 --- a/src/client/component/materials.cpp +++ b/src/client/component/materials.cpp @@ -166,6 +166,14 @@ namespace materials }); } + bool exists(const std::string& name) + { + return material_data.access([&](material_data_t& data_) + { + return data_.images.find(name) != data_.images.end(); + }); + } + void clear() { material_data.access([&](material_data_t& data_) diff --git a/src/client/component/materials.hpp b/src/client/component/materials.hpp index 3a548548..0c02227f 100644 --- a/src/client/component/materials.hpp +++ b/src/client/component/materials.hpp @@ -3,5 +3,6 @@ namespace materials { void add(const std::string& name, const std::string& data); + bool exists(const std::string& name); void clear(); } diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index de9b4983..68d82dd1 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -88,6 +88,7 @@ namespace scheduler utils::hook::detour r_end_frame_hook; utils::hook::detour g_run_frame_hook; utils::hook::detour main_frame_hook; + utils::hook::detour hks_frame_hook; void execute(const pipeline type) { @@ -112,6 +113,15 @@ namespace scheduler main_frame_hook.invoke(); execute(pipeline::main); } + + void hks_frame_stub() + { + const auto state = *game::hks::lua_state; + if (state) + { + execute(pipeline::lui); + } + } } void schedule(const std::function& callback, const pipeline type, @@ -183,6 +193,7 @@ namespace scheduler r_end_frame_hook.create(SELECT_VALUE(0x1404F7310, 0x1405FE470), scheduler::r_end_frame_stub); g_run_frame_hook.create(SELECT_VALUE(0x1402772D0, 0x14033A640), scheduler::server_frame_stub); main_frame_hook.create(SELECT_VALUE(0x1401CE8D0, 0x1400D8310), scheduler::main_frame_stub); + hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), scheduler::hks_frame_stub); } void pre_destroy() override diff --git a/src/client/component/scheduler.hpp b/src/client/component/scheduler.hpp index f26c60ce..68f78d54 100644 --- a/src/client/component/scheduler.hpp +++ b/src/client/component/scheduler.hpp @@ -16,6 +16,9 @@ namespace scheduler // The game's main thread main, + // LUI context + lui, + count, }; diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index c4f6d06f..c6b44883 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -93,6 +93,7 @@ namespace ui_scripting void hks_shutdown_stub() { + converted_functions.clear(); ui_scripting::lua::engine::stop(); hks_shutdown_hook.invoke(); } @@ -107,15 +108,6 @@ namespace ui_scripting return hks_allocator_hook.invoke(userData, oldMemory, oldSize, newSize); } - - void hks_frame_stub() - { - const auto state = *game::hks::lua_state; - if (state) - { - ui_scripting::lua::engine::run_frame(); - } - } } int main_function_handler(game::hks::lua_State* state) @@ -132,7 +124,7 @@ namespace ui_scripting return 0; } - const auto function = converted_functions[closure]; + const auto& function = converted_functions[closure]; const auto count = static_cast(state->m_apistack.top - state->m_apistack.base); const auto arguments = get_return_values(count); const auto s = function.lua_state(); @@ -175,6 +167,11 @@ namespace ui_scripting error_hook_enabled = false; } + bool lui_running() + { + return *game::hks::lua_state != nullptr; + } + class component final : public component_interface { public: @@ -186,11 +183,12 @@ namespace ui_scripting return; } + scheduler::loop(ui_scripting::lua::engine::run_frame, scheduler::pipeline::lui); + hks_start_hook.create(SELECT_VALUE(0x1400E4B40, 0x140176A40), hks_start_stub); hks_shutdown_hook.create(SELECT_VALUE(0x1400DD3D0, 0x14016CA80), hks_shutdown_stub); hksi_lual_error_hook.create(SELECT_VALUE(0x1400A5EA0, 0x14012F300), hksi_lual_error_stub); hks_allocator_hook.create(SELECT_VALUE(0x14009B570, 0x14012BAC0), hks_allocator_stub); - hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), hks_frame_stub); lui_error_hook.create(SELECT_VALUE(0x14007D7D0, 0x14010C9E0), lui_error_stub); hksi_hks_error_hook.create(SELECT_VALUE(0x14009DD80, 0x14012E390), hksi_hks_error_stub); diff --git a/src/client/component/ui_scripting.hpp b/src/client/component/ui_scripting.hpp index 2a48f6ec..b95710b3 100644 --- a/src/client/component/ui_scripting.hpp +++ b/src/client/component/ui_scripting.hpp @@ -9,4 +9,6 @@ namespace ui_scripting void enable_error_hook(); void disable_error_hook(); + + bool lui_running(); } \ No newline at end of file diff --git a/src/client/game/ui_scripting/lua/context.cpp b/src/client/game/ui_scripting/lua/context.cpp index d9a930f9..4a6294b6 100644 --- a/src/client/game/ui_scripting/lua/context.cpp +++ b/src/client/game/ui_scripting/lua/context.cpp @@ -14,10 +14,13 @@ #include "../../../component/fastfiles.hpp" #include "../../../component/scripting.hpp" #include "../../../component/mods.hpp" +#include "../../../component/discord.hpp" #include "component/game_console.hpp" #include "component/scheduler.hpp" +#include + #include #include #include @@ -265,36 +268,6 @@ namespace ui_scripting::lua return sol::as_returns(returns); }; - state["luiglobals"] = table((*::game::hks::lua_state)->globals.v.table); - state["CoD"] = state["luiglobals"]["CoD"]; - state["LUI"] = state["luiglobals"]["LUI"]; - state["Engine"] = state["luiglobals"]["Engine"]; - state["Game"] = state["luiglobals"]["Game"]; - - auto updater_table = sol::table::create(state.lua_state()); - - updater_table["relaunch"] = updater::relaunch; - - updater_table["sethastriedupdate"] = updater::set_has_tried_update; - updater_table["gethastriedupdate"] = updater::get_has_tried_update; - updater_table["autoupdatesenabled"] = updater::auto_updates_enabled; - - updater_table["startupdatecheck"] = updater::start_update_check; - updater_table["isupdatecheckdone"] = updater::is_update_check_done; - updater_table["getupdatecheckstatus"] = updater::get_update_check_status; - updater_table["isupdateavailable"] = updater::is_update_available; - - updater_table["startupdatedownload"] = updater::start_update_download; - updater_table["isupdatedownloaddone"] = updater::is_update_download_done; - updater_table["getupdatedownloadstatus"] = updater::get_update_download_status; - updater_table["cancelupdate"] = updater::cancel_update; - updater_table["isrestartrequired"] = updater::is_restart_required; - - updater_table["getlasterror"] = updater::get_last_error; - updater_table["getcurrentfile"] = updater::get_current_file; - - state["updater"] = updater_table; - if (::game::environment::is_sp()) { struct player @@ -339,6 +312,47 @@ namespace ui_scripting::lua }, ::scheduler::pipeline::server); }; } + + state["luiglobals"] = table((*::game::hks::lua_state)->globals.v.table); + state["CoD"] = state["luiglobals"]["CoD"]; + state["LUI"] = state["luiglobals"]["LUI"]; + state["Engine"] = state["luiglobals"]["Engine"]; + state["Game"] = state["luiglobals"]["Game"]; + + auto updater_table = sol::table::create(state.lua_state()); + + updater_table["relaunch"] = updater::relaunch; + + updater_table["sethastriedupdate"] = updater::set_has_tried_update; + updater_table["gethastriedupdate"] = updater::get_has_tried_update; + updater_table["autoupdatesenabled"] = updater::auto_updates_enabled; + + updater_table["startupdatecheck"] = updater::start_update_check; + updater_table["isupdatecheckdone"] = updater::is_update_check_done; + updater_table["getupdatecheckstatus"] = updater::get_update_check_status; + updater_table["isupdateavailable"] = updater::is_update_available; + + updater_table["startupdatedownload"] = updater::start_update_download; + updater_table["isupdatedownloaddone"] = updater::is_update_download_done; + updater_table["getupdatedownloadstatus"] = updater::get_update_download_status; + updater_table["cancelupdate"] = updater::cancel_update; + updater_table["isrestartrequired"] = updater::is_restart_required; + + updater_table["getlasterror"] = updater::get_last_error; + updater_table["getcurrentfile"] = updater::get_current_file; + + state["updater"] = updater_table; + + auto discord_table = sol::table::create(state.lua_state()); + + discord_table["respond"] = discord::respond; + discord_table["getavatarmaterial"] = discord::get_avatar_material; + discord_table["reply"] = sol::table::create(state.lua_state()); + discord_table["reply"]["yes"] = DISCORD_REPLY_YES; + discord_table["reply"]["ignore"] = DISCORD_REPLY_IGNORE; + discord_table["reply"]["no"] = DISCORD_REPLY_NO; + + state["discord"] = discord_table; } } diff --git a/src/client/game/ui_scripting/types.cpp b/src/client/game/ui_scripting/types.cpp index 66e8d497..4323df0a 100644 --- a/src/client/game/ui_scripting/types.cpp +++ b/src/client/game/ui_scripting/types.cpp @@ -13,6 +13,16 @@ namespace ui_scripting { } + bool lightuserdata::operator==(const lightuserdata& other) + { + return this->ptr == other.ptr; + } + + bool lightuserdata::operator!=(const lightuserdata& other) + { + return this->ptr != other.ptr; + } + /*************************************************************** * Userdata **************************************************************/ @@ -66,6 +76,16 @@ namespace ui_scripting return *this; } + bool userdata::operator==(const userdata& other) + { + return this->ptr == other.ptr; + } + + bool userdata::operator!=(const userdata& other) + { + return this->ptr != other.ptr; + } + void userdata::add() { game::hks::HksObject value{}; @@ -158,6 +178,16 @@ namespace ui_scripting return *this; } + bool table::operator==(const table& other) + { + return this->ptr == other.ptr; + } + + bool table::operator!=(const table& other) + { + return this->ptr != other.ptr; + } + void table::add() { game::hks::HksObject value{}; @@ -247,6 +277,16 @@ namespace ui_scripting return *this; } + bool function::operator==(const function& other) + { + return this->ptr == other.ptr; + } + + bool function::operator!=(const function& other) + { + return this->ptr != other.ptr; + } + void function::add() { game::hks::HksObject value{}; diff --git a/src/client/game/ui_scripting/types.hpp b/src/client/game/ui_scripting/types.hpp index bc2f7216..0eb4aeda 100644 --- a/src/client/game/ui_scripting/types.hpp +++ b/src/client/game/ui_scripting/types.hpp @@ -8,6 +8,10 @@ namespace ui_scripting { public: lightuserdata(void*); + + bool operator==(const lightuserdata& other); + bool operator!=(const lightuserdata& other); + void* ptr; }; @@ -24,6 +28,9 @@ namespace ui_scripting userdata& operator=(const userdata& other); userdata& operator=(userdata&& other) noexcept; + bool operator==(const userdata& other); + bool operator!=(const userdata& other); + script_value get(const script_value& key) const; void set(const script_value& key, const script_value& value) const; @@ -50,6 +57,9 @@ namespace ui_scripting table& operator=(const table& other); table& operator=(table&& other) noexcept; + bool operator==(const table& other); + bool operator!=(const table& other); + script_value get(const script_value& key) const; void set(const script_value& key, const script_value& value) const; @@ -75,6 +85,9 @@ namespace ui_scripting function& operator=(const function& other); function& operator=(function&& other) noexcept; + bool operator==(const function& other); + bool operator!=(const function& other); + arguments call(const arguments& arguments) const; game::hks::cclosure* ptr; From 2ae2831d06cd1d082e3bf422ba89a92b7f00288b Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Mon, 11 Apr 2022 11:42:42 +0200 Subject: [PATCH 148/346] Set partyId --- src/client/component/discord.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index 65fb74be..d75f9641 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -67,7 +67,7 @@ namespace discord discord_presence.details = utils::string::va("%s on %s", gametype, mapname); - char clean_hostname[0x100] = {0}; + char clean_hostname[0x80] = {0}; utils::string::strip(game::Dvar_FindVar("sv_hostname")->current.string, clean_hostname, sizeof(clean_hostname)); auto max_clients = party::server_client_count(); @@ -81,18 +81,22 @@ namespace discord } else { - discord_presence.partyPrivacy = DISCORD_PARTY_PUBLIC; - - // TODO: we need to make this a random string that represents the session ID - // const auto sessionId = party::get_state_challenge(); - discord_presence.partyId = "PLACEHOLDER"; - const auto server_net_info = party::get_state_host(); const auto server_ip_port = utils::string::va("%i.%i.%i.%i:%i", - server_net_info.ip[0], server_net_info.ip[1], server_net_info.ip[2], server_net_info.ip[3], - ntohs(server_net_info.port)); + server_net_info.ip[0], + server_net_info.ip[1], + server_net_info.ip[2], + server_net_info.ip[3], + ntohs(server_net_info.port) + ); + char party_id[0x80] = {0}; + const auto server_ip_port_hash = utils::cryptography::sha1::compute(server_ip_port, true); + strcpy_s(party_id, 0x80, server_ip_port_hash.data()); + + discord_presence.partyId = party_id; discord_presence.joinSecret = server_ip_port; + discord_presence.partyPrivacy = DISCORD_PARTY_PUBLIC; } discord_presence.partySize = *reinterpret_cast(0x1429864C4); From 17bb717222a226dc8cbe91f103b4fa51d2ca05c4 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Mon, 11 Apr 2022 12:12:26 +0200 Subject: [PATCH 149/346] Some fixes --- src/client/component/discord.cpp | 46 ++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index d75f9641..3698e30f 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -8,6 +8,7 @@ #include "network.hpp" #include "party.hpp" #include "materials.hpp" +#include "discord.hpp" #include "ui_scripting.hpp" #include "game/ui_scripting/execution.hpp" @@ -24,8 +25,6 @@ #define DEFAULT_AVATAR_URL "https://cdn.discordapp.com/embed/avatars/0.png" #define AVATAR_URL "https://cdn.discordapp.com/avatars/%s/%s.png?size=128" -#include "discord.hpp" - namespace discord { namespace @@ -36,11 +35,11 @@ namespace discord { if (!game::CL_IsCgameInitialized() || game::VirtualLobby_Loaded()) { - discord_presence.details = game::environment::is_sp() ? "Singleplayer" : "Multiplayer"; + discord_presence.details = SELECT_VALUE("Singleplayer", "Multiplayer"); discord_presence.state = "Main Menu"; - auto firingRangeDvar = game::Dvar_FindVar("virtualLobbyInFiringRange"); - if (firingRangeDvar && firingRangeDvar->current.enabled == 1) + const auto in_firing_range = game::Dvar_FindVar("virtualLobbyInFiringRange"); + if (in_firing_range && in_firing_range->current.enabled == 1) { discord_presence.state = "Firing Range"; } @@ -48,7 +47,7 @@ namespace discord discord_presence.partySize = 0; discord_presence.partyMax = 0; discord_presence.startTimestamp = 0; - discord_presence.largeImageKey = game::environment::is_sp() ? "menu_singleplayer" : "menu_multiplayer"; + discord_presence.largeImageKey = SELECT_VALUE("menu_singleplayer", "menu_multiplayer"); // set to blank when in lobby discord_presence.matchSecret = ""; @@ -58,16 +57,18 @@ namespace discord } else { + static char details[0x80] = {0}; const auto map = game::Dvar_FindVar("mapname")->current.string; - const auto mapname = game::UI_SafeTranslateString(utils::string::va("PRESENCE_%s%s", (game::environment::is_sp() ? "SP_" : ""), map)); + const auto mapname = game::UI_SafeTranslateString( + utils::string::va("PRESENCE_%s%s", SELECT_VALUE("SP_", ""), map)); if (game::environment::is_mp()) { - const auto gametype = game::UI_GetGameTypeDisplayName(game::Dvar_FindVar("g_gametype")->current.string); + const auto gametype = game::UI_GetGameTypeDisplayName( + game::Dvar_FindVar("g_gametype")->current.string); + strcpy_s(details, 0x80, utils::string::va("%s on %s", gametype, mapname)); - discord_presence.details = utils::string::va("%s on %s", gametype, mapname); - - char clean_hostname[0x80] = {0}; + static char clean_hostname[0x80] = {0}; utils::string::strip(game::Dvar_FindVar("sv_hostname")->current.string, clean_hostname, sizeof(clean_hostname)); auto max_clients = party::server_client_count(); @@ -83,19 +84,22 @@ namespace discord { const auto server_net_info = party::get_state_host(); const auto server_ip_port = utils::string::va("%i.%i.%i.%i:%i", - server_net_info.ip[0], - server_net_info.ip[1], - server_net_info.ip[2], - server_net_info.ip[3], - ntohs(server_net_info.port) + static_cast(server_net_info.ip[0]), + static_cast(server_net_info.ip[1]), + static_cast(server_net_info.ip[2]), + static_cast(server_net_info.ip[3]), + static_cast(ntohs(server_net_info.port)) ); - char party_id[0x80] = {0}; - const auto server_ip_port_hash = utils::cryptography::sha1::compute(server_ip_port, true); + static char join_secret[0x80] = {0}; + strcpy_s(join_secret, 0x80, server_ip_port); + + static char party_id[0x80] = {0}; + const auto server_ip_port_hash = utils::cryptography::sha1::compute(server_ip_port, true).substr(0, 8); strcpy_s(party_id, 0x80, server_ip_port_hash.data()); discord_presence.partyId = party_id; - discord_presence.joinSecret = server_ip_port; + discord_presence.joinSecret = join_secret; discord_presence.partyPrivacy = DISCORD_PARTY_PUBLIC; } @@ -108,9 +112,11 @@ namespace discord { discord_presence.state = ""; discord_presence.largeImageKey = map; - discord_presence.details = mapname; + strcpy_s(details, 0x80, mapname); } + discord_presence.details = details; + if (!discord_presence.startTimestamp) { discord_presence.startTimestamp = std::chrono::duration_cast( From f882847bc5e04dff00379640ec124abe4a25e154 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Apr 2022 13:42:36 -0500 Subject: [PATCH 150/346] Bump deps/asmjit from `752eb38` to `a4cb51b` (#45) Bumps [deps/asmjit](https://github.com/asmjit/asmjit) from `752eb38` to `a4cb51b`. - [Release notes](https://github.com/asmjit/asmjit/releases) - [Commits](https://github.com/asmjit/asmjit/compare/752eb38a4dbe590995cbadaff06baadd8378eeeb...a4cb51b532af0f8137c4182914244c3b05d7745f) --- updated-dependencies: - dependency-name: deps/asmjit dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deps/asmjit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/asmjit b/deps/asmjit index 752eb38a..a4cb51b5 160000 --- a/deps/asmjit +++ b/deps/asmjit @@ -1 +1 @@ -Subproject commit 752eb38a4dbe590995cbadaff06baadd8378eeeb +Subproject commit a4cb51b532af0f8137c4182914244c3b05d7745f From d3138d5d8caa58385c91f3f627f3522a87fbaa5f Mon Sep 17 00:00:00 2001 From: Mauro Cipriani Date: Wed, 13 Apr 2022 21:27:11 +0200 Subject: [PATCH 151/346] Added aa events dvars (#46) --- src/client/game/dvars.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index 56c1d5a1..cbd3843e 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -11682,6 +11682,31 @@ namespace dvars "If a joints with position error exceeding this value is detected, then the whole xphys system gets snapped back to the animation pose", generate_hash("xphys_maxJointPositionError") }, + { + "aa_player_kills", + "Player kills", + generate_hash("aa_player_kills") + }, + { + "aa_player_damage_dealt", + "Player damages dealt", + generate_hash("aa_player_damage_dealt") + }, + { + "aa_ads_damage_dealt", + "Player damages dealt in ads", + generate_hash("aa_ads_damage_dealt") + }, + { + "aa_deaths", + "Player deaths", + generate_hash("aa_deaths") + }, + { + "aa_time_tracking", + "Time in game", + generate_hash("aa_time_tracking") + }, }; std::string dvar_get_description(const std::string& name) From b06b3f5e1044076fd98cc159973d1953a3ae1845 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Apr 2022 17:37:04 +0000 Subject: [PATCH 152/346] Bump deps/sol2 from `50b62c9` to `6409634` Bumps [deps/sol2](https://github.com/ThePhD/sol2) from `50b62c9` to `6409634`. - [Release notes](https://github.com/ThePhD/sol2/releases) - [Commits](https://github.com/ThePhD/sol2/compare/50b62c9346750b7c2c406c9e4c546f96b0bf021d...64096348465b980e2f1d0e5ba9cbeea8782e8f27) --- updated-dependencies: - dependency-name: deps/sol2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/sol2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/sol2 b/deps/sol2 index 50b62c93..64096348 160000 --- a/deps/sol2 +++ b/deps/sol2 @@ -1 +1 @@ -Subproject commit 50b62c9346750b7c2c406c9e4c546f96b0bf021d +Subproject commit 64096348465b980e2f1d0e5ba9cbeea8782e8f27 From c9662d6fe2125817086c1e2e15c7729b94f60a89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Apr 2022 17:33:28 +0000 Subject: [PATCH 153/346] Bump deps/GSL from `3837236` to `2bfd495` Bumps [deps/GSL](https://github.com/Microsoft/GSL) from `3837236` to `2bfd495`. - [Release notes](https://github.com/Microsoft/GSL/releases) - [Commits](https://github.com/Microsoft/GSL/compare/383723676cd548d615159701ac3d050f8dd1e128...2bfd4950802a223dde37a08a205812b6dfdfeb61) --- updated-dependencies: - dependency-name: deps/GSL dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/GSL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/GSL b/deps/GSL index 38372367..2bfd4950 160000 --- a/deps/GSL +++ b/deps/GSL @@ -1 +1 @@ -Subproject commit 383723676cd548d615159701ac3d050f8dd1e128 +Subproject commit 2bfd4950802a223dde37a08a205812b6dfdfeb61 From 1ec677c574b27b5938fcbcd033d337fa6885e3df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Apr 2022 17:33:13 +0000 Subject: [PATCH 154/346] Bump deps/GSL from `2bfd495` to `f21f29d` Bumps [deps/GSL](https://github.com/Microsoft/GSL) from `2bfd495` to `f21f29d`. - [Release notes](https://github.com/Microsoft/GSL/releases) - [Commits](https://github.com/Microsoft/GSL/compare/2bfd4950802a223dde37a08a205812b6dfdfeb61...f21f29d210939d4025069576e5891665b001f402) --- updated-dependencies: - dependency-name: deps/GSL dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/GSL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/GSL b/deps/GSL index 2bfd4950..f21f29d2 160000 --- a/deps/GSL +++ b/deps/GSL @@ -1 +1 @@ -Subproject commit 2bfd4950802a223dde37a08a205812b6dfdfeb61 +Subproject commit f21f29d210939d4025069576e5891665b001f402 From b17e9047c088b3e1828d536548d5344b2671c584 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 May 2022 12:02:23 -0500 Subject: [PATCH 155/346] Bump deps/GSL from `f21f29d` to `da01eb2` (#53) Bumps [deps/GSL](https://github.com/Microsoft/GSL) from `f21f29d` to `da01eb2`. - [Release notes](https://github.com/Microsoft/GSL/releases) - [Commits](https://github.com/Microsoft/GSL/compare/f21f29d210939d4025069576e5891665b001f402...da01eb28dbb75bed11a51acff0f80ecedd622573) --- updated-dependencies: - dependency-name: deps/GSL dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deps/GSL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/GSL b/deps/GSL index f21f29d2..da01eb28 160000 --- a/deps/GSL +++ b/deps/GSL @@ -1 +1 @@ -Subproject commit f21f29d210939d4025069576e5891665b001f402 +Subproject commit da01eb28dbb75bed11a51acff0f80ecedd622573 From e95cbf8e90140ab47108954f56c795981fbc3472 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 May 2022 12:02:33 -0500 Subject: [PATCH 156/346] Bump deps/libtommath from `5108f12` to `4b47368` (#52) Bumps [deps/libtommath](https://github.com/libtom/libtommath) from `5108f12` to `4b47368`. - [Release notes](https://github.com/libtom/libtommath/releases) - [Commits](https://github.com/libtom/libtommath/compare/5108f12350b6daa4aa5dbc846517ad1db2f8388a...4b47368501321c795d5b54d87a5bab35a21a7940) --- updated-dependencies: - dependency-name: deps/libtommath dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deps/libtommath | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/libtommath b/deps/libtommath index 5108f123..4b473685 160000 --- a/deps/libtommath +++ b/deps/libtommath @@ -1 +1 @@ -Subproject commit 5108f12350b6daa4aa5dbc846517ad1db2f8388a +Subproject commit 4b47368501321c795d5b54d87a5bab35a21a7940 From e0b00865bbf74eb4ee05805f57c15089334ddf36 Mon Sep 17 00:00:00 2001 From: yoyothebest Date: Thu, 5 May 2022 13:38:28 +0300 Subject: [PATCH 157/346] Added dvars (#54) --- src/client/game/dvars.cpp | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index cbd3843e..f34fd1dd 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -3732,6 +3732,11 @@ namespace dvars "Minimum visibility trace size", generate_hash("fx_visMinTraceDist") }, + { + "g_ai", + "Enable AI.", + generate_hash("g_ai") + }, { "g_allowVote", "Enable voting on this server", @@ -9587,6 +9592,66 @@ namespace dvars "Non-blocking Session code", generate_hash("session_nonblocking") }, + { + "sf_use_bw", + "Intel Cheat - CoD Noir.", + generate_hash("sf_use_bw") + }, + { + "sf_use_chaplin", + "Intel Cheat - Ragtime Warfare.", + generate_hash("sf_use_chaplin") + }, + { + "sf_use_clustergrenade", + "Intel Cheat - Cluster Bombs.", + generate_hash("sf_use_clustergrenade") + }, + { + "sf_use_contrast", + "Intel Cheat - Super Contrast.", + generate_hash("sf_use_contrast") + }, + { + "sf_use_ignoreammo", + "Intel Cheat - Infinite Ammo.", + generate_hash("sf_use_ignoreammo") + }, + { + "sf_use_invert", + "Intel Cheat - Photo-Negative.", + generate_hash("sf_use_invert") + }, + { + "sf_use_lemonade_mode", + "Intel Cheat - Lemon-nade.", + generate_hash("sf_use_lemonade_mode") + }, + { + "sf_use_melon_mode", + "Intel Cheat - Melon Heads.", + generate_hash("sf_use_melon_mode") + }, + { + "sf_use_ragdoll_mode", + "Intel Cheat - Ragdoll Impact.", + generate_hash("sf_use_ragdoll_mode") + }, + { + "sf_use_slowmo", + "Intel Cheat - Slow-Mo Ability.", + generate_hash("sf_use_slowmo") + }, + { + "sf_use_tire_explosion", + "Intel Cheat - A Bad Year.", + generate_hash("sf_use_tire_explosion") + }, + { + "sf_use_tracksuit_mode", + "Intel Cheat - Zakhaev's Sons.", + generate_hash("sf_use_tracksuit_mode") + }, { "shortversion", "Short game version", @@ -10332,6 +10397,11 @@ namespace dvars "Amount of blur to use when drawing blur through a weapon's thermal scope.", generate_hash("thermalBlurFactorScope") }, + { + "timescale", + "Set the game speed.", + generate_hash("timescale") + }, { "tokensEnabled", "Is token economy enabled", From 3e59966fbd7142c4dfa0dffd853bd5e8e7f3cae7 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 5 May 2022 15:23:50 +0300 Subject: [PATCH 158/346] fullbright --- src/client/component/renderer.cpp | 18 ++++++++++++------ src/client/game/symbols.hpp | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp index a20f66fe..1f6c4137 100644 --- a/src/client/component/renderer.cpp +++ b/src/client/component/renderer.cpp @@ -14,7 +14,15 @@ namespace renderer int get_fullbright_technique() { - return game::TECHNIQUE_UNLIT; + switch (dvars::r_fullbright->current.integer) + { + case 3: + return 13; + case 2: + return 25; + default: + return game::TECHNIQUE_UNLIT; + } } void gfxdrawmethod() @@ -35,7 +43,7 @@ namespace renderer { if (dvars::r_fullbright->modified) { - //game::Dvar_ClearModified(dvars::r_fullbright); + game::Dvar_ClearModified(dvars::r_fullbright); game::R_SyncRenderThread(); gfxdrawmethod(); @@ -50,7 +58,7 @@ namespace renderer public: void post_unpack() override { - if (game::environment::is_dedi() || !game::environment::is_mp()) + if (game::environment::is_dedi()) { return; } @@ -72,6 +80,4 @@ namespace renderer }; } -#ifdef DEBUG -REGISTER_COMPONENT(renderer::component) -#endif \ No newline at end of file +REGISTER_COMPONENT(renderer::component) \ No newline at end of file diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 58058533..9acc02d3 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -53,6 +53,7 @@ namespace game WEAK symbol Dvar_SetCommand{0x1403C72B0, 0x1404FD0A0}; WEAK symbol Dvar_FindVar{0x1403C5D50, 0x1404FBB00}; + WEAK symbol Dvar_ClearModified{0x1403C5C20, 0x1404FB930}; WEAK symbol Dvar_GetCombinedString{0x140354DF0, 0x14041D830}; WEAK symbol Dvar_ValueToString{0x1403C8560, 0x1404FE660}; WEAK symbol Dvar_Reset{0, 0x1404FCC40}; From 116c147135645f72e283b74f30451dd8b06e688f Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 5 May 2022 15:25:55 +0300 Subject: [PATCH 159/346] implement pm_bouncing & g_gravity --- src/client/component/gameplay.cpp | 51 +++++++++++++++++++++++++++++++ src/client/game/dvars.cpp | 4 +++ src/client/game/dvars.hpp | 4 +++ 3 files changed, 59 insertions(+) diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index e9c28ea5..c02bd004 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -32,6 +32,47 @@ namespace gameplay utils::hook::invoke(0x1401E2D00, ps, pml); } } + + const auto pm_bouncing_stub_mp = utils::hook::assemble([](utils::hook::assembler& a) + { + const auto no_bounce = a.newLabel(); + const auto loc_1401EAF9D = a.newLabel(); + + a.push(rax); + + a.mov(rax, qword_ptr(reinterpret_cast(&dvars::pm_bouncing))); + a.mov(al, byte_ptr(rax, 0x10)); + a.cmp(byte_ptr(rbp, -0x2D), al); + + a.pop(rax); + a.jz(no_bounce); + a.jmp(0x1401EB000); + + a.bind(no_bounce); + a.cmp(dword_ptr(rsp, 0x70), 0); + a.jnz(loc_1401EAF9D); + a.jmp(0x1401EAFF1); + + a.bind(loc_1401EAF9D); + a.jmp(0x1401EAF9D); + }); + + const auto client_end_frame_stub = utils::hook::assemble([](utils::hook::assembler& a) + { + a.push(rax); + + a.mov(rax, qword_ptr(reinterpret_cast(&dvars::g_gravity))); + a.mov(eax, dword_ptr(rax, 0x10)); + a.mov(word_ptr(rbx, 0x34), ax); + + a.pop(rax); + + // Game code hook skipped + a.mov(eax, dword_ptr(rbx, 0x494C)); + a.mov(rdi, rcx); + + a.jmp(0x140322F82); + }); } class component final : public component_interface @@ -49,6 +90,16 @@ namespace gameplay utils::hook::call(0x1401E490F, pm_crashland_stub); jump_enableFallDamage = dvars::register_bool("jump_enableFallDamage", true, game::DVAR_FLAG_REPLICATED, "Enable fall damage"); + + // Implement bouncing dvar + dvars::pm_bouncing = dvars::register_bool("pm_bouncing", false, + game::DVAR_FLAG_REPLICATED, "Enable bouncing"); + utils::hook::jump(0x1401EAFE4, pm_bouncing_stub_mp, true); + + dvars::g_gravity = dvars::register_int("g_gravity", 800, std::numeric_limits::min(), + std::numeric_limits::max(), game::DVAR_FLAG_REPLICATED, ""); + utils::hook::jump(0x140322F72, client_end_frame_stub, true); + utils::hook::nop(0x140322F68, 1); // Nop skipped opcode } }; } diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index f34fd1dd..4834bd64 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -27,6 +27,10 @@ namespace dvars game::dvar_t* r_fullbright; game::dvar_t* r_chams; + game::dvar_t* g_gravity = nullptr; + + game::dvar_t* pm_bouncing = nullptr; + game::dvar_t* cg_legacyCrashHandling; std::string dvar_get_vector_domain(const int components, const game::dvar_limits& domain) diff --git a/src/client/game/dvars.hpp b/src/client/game/dvars.hpp index 2d1d7673..87154b5e 100644 --- a/src/client/game/dvars.hpp +++ b/src/client/game/dvars.hpp @@ -30,6 +30,10 @@ namespace dvars extern game::dvar_t* r_fullbright; extern game::dvar_t* r_chams; + extern game::dvar_t* g_gravity; + + extern game::dvar_t* pm_bouncing; + extern game::dvar_t* cg_legacyCrashHandling; extern std::vector dvar_list; From 667a0005e088a44ffaa7122e579cf364cef40b7c Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 5 May 2022 16:58:36 +0300 Subject: [PATCH 160/346] collision & ejection --- src/client/component/gameplay.cpp | 30 ++++++++++++++++++++++++++++++ src/client/game/dvars.cpp | 2 ++ src/client/game/dvars.hpp | 2 ++ src/client/game/structs.hpp | 10 ++++++++++ 4 files changed, 44 insertions(+) diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index c02bd004..061a9c19 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -25,6 +25,26 @@ namespace gameplay } } + int stuck_in_client_stub(void* entity) + { + if (dvars::g_playerEjection->current.enabled) + { + return utils::hook::invoke(0x140326CE0, entity); // StuckInClient + } + + return 0; + } + + void cm_transformed_capsule_trace_stub(game::trace_t* results, const float* start, const float* end, + game::Bounds* bounds, game::Bounds* capsule, int contents, const float* origin, const float* angles) + { + if (dvars::g_playerCollision->current.enabled) + { + utils::hook::invoke(0x1403FF860, + results, start, end, bounds, capsule, contents, origin, angles); // CM_TransformedCapsuleTrace + } + } + void pm_crashland_stub(game::mp::playerState_s* ps, void* pml) { if (jump_enableFallDamage->current.enabled) @@ -91,6 +111,16 @@ namespace gameplay utils::hook::call(0x1401E490F, pm_crashland_stub); jump_enableFallDamage = dvars::register_bool("jump_enableFallDamage", true, game::DVAR_FLAG_REPLICATED, "Enable fall damage"); + dvars::g_playerEjection = dvars::register_bool("g_playerEjection", true, game::DVAR_FLAG_REPLICATED, + "Flag whether player ejection is on or off"); + utils::hook::call(0x140323333, stuck_in_client_stub); + + // Implement player collision dvar + dvars::g_playerCollision = dvars::register_bool("g_playerCollision", true, game::DVAR_FLAG_REPLICATED, + "Flag whether player collision is on or off"); + utils::hook::call(0x14049D7CF, cm_transformed_capsule_trace_stub); // SV_ClipMoveToEntity + utils::hook::call(0x140240BC3, cm_transformed_capsule_trace_stub); // CG_ClipMoveToEntity + // Implement bouncing dvar dvars::pm_bouncing = dvars::register_bool("pm_bouncing", false, game::DVAR_FLAG_REPLICATED, "Enable bouncing"); diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index 4834bd64..8f0c5dba 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -21,6 +21,8 @@ namespace dvars game::dvar_t* con_inputDvarValueColor = nullptr; game::dvar_t* con_inputDvarInactiveValueColor = nullptr; game::dvar_t* con_inputCmdMatchColor = nullptr; + game::dvar_t* g_playerEjection = nullptr; + game::dvar_t* g_playerCollision = nullptr; game::dvar_t* jump_enableFallDamage; diff --git a/src/client/game/dvars.hpp b/src/client/game/dvars.hpp index 87154b5e..34f6d714 100644 --- a/src/client/game/dvars.hpp +++ b/src/client/game/dvars.hpp @@ -24,6 +24,8 @@ namespace dvars extern game::dvar_t* con_inputDvarValueColor; extern game::dvar_t* con_inputDvarInactiveValueColor; extern game::dvar_t* con_inputCmdMatchColor; + extern game::dvar_t* g_playerEjection; + extern game::dvar_t* g_playerCollision; extern game::dvar_t* jump_enableFallDamage; diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 4d6b3405..9d1907c8 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1428,6 +1428,16 @@ namespace game SV_LIVE_DROP_DISCONNECT = 0x1, }; + struct trace_t + { + }; + + struct Bounds + { + float midPoint[3]; + float halfSize[3]; + }; + namespace mp { struct cachedSnapshot_t From 1cd666a1e840fc9bf4360960438b48bd5a9b3bb8 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 5 May 2022 18:28:54 +0300 Subject: [PATCH 161/346] player_sustainammo oops i missed this one --- src/client/component/gameplay.cpp | 15 +++++++++++++++ src/client/game/dvars.cpp | 1 + src/client/game/dvars.hpp | 1 + src/client/game/structs.hpp | 13 +++++++++++++ 4 files changed, 30 insertions(+) diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index 061a9c19..31635184 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -14,6 +14,8 @@ namespace gameplay { namespace { + utils::hook::detour pm_weapon_use_ammo_hook; + game::dvar_t* jump_slowDownEnable; game::dvar_t* jump_enableFallDamage; @@ -53,6 +55,15 @@ namespace gameplay } } + void pm_weapon_use_ammo_stub(game::playerState_s* ps, game::Weapon weapon, + bool is_alternate, int amount, game::PlayerHandIndex hand) + { + if (!dvars::player_sustainAmmo->current.enabled) + { + pm_weapon_use_ammo_hook.invoke(ps, weapon, is_alternate, amount, hand); + } + } + const auto pm_bouncing_stub_mp = utils::hook::assemble([](utils::hook::assembler& a) { const auto no_bounce = a.newLabel(); @@ -100,6 +111,10 @@ namespace gameplay public: void post_unpack() override { + dvars::player_sustainAmmo = dvars::register_bool("player_sustainAmmo", false, + game::DVAR_FLAG_REPLICATED, "Firing weapon will not decrease clip ammo"); + pm_weapon_use_ammo_hook.create(SELECT_VALUE(0x14042E380, 0x1401F6B90), &pm_weapon_use_ammo_stub); + if (game::environment::is_sp()) { return; diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index 8f0c5dba..f46d7d5b 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -23,6 +23,7 @@ namespace dvars game::dvar_t* con_inputCmdMatchColor = nullptr; game::dvar_t* g_playerEjection = nullptr; game::dvar_t* g_playerCollision = nullptr; + game::dvar_t* player_sustainAmmo = nullptr; game::dvar_t* jump_enableFallDamage; diff --git a/src/client/game/dvars.hpp b/src/client/game/dvars.hpp index 34f6d714..24c4afb5 100644 --- a/src/client/game/dvars.hpp +++ b/src/client/game/dvars.hpp @@ -26,6 +26,7 @@ namespace dvars extern game::dvar_t* con_inputCmdMatchColor; extern game::dvar_t* g_playerEjection; extern game::dvar_t* g_playerCollision; + extern game::dvar_t* player_sustainAmmo; extern game::dvar_t* jump_enableFallDamage; diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 9d1907c8..6fa0cf2f 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1438,6 +1438,19 @@ namespace game float halfSize[3]; }; + enum PlayerHandIndex + { + WEAPON_HAND_DEFAULT = 0x0, + WEAPON_HAND_RIGHT = 0x0, + WEAPON_HAND_LEFT = 0x1, + NUM_WEAPON_HANDS = 0x2, + }; + + union Weapon + { + unsigned int data; + }; + namespace mp { struct cachedSnapshot_t From ddcbcd2bb3df10beffa59f9fb0873fba689a67b2 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 5 May 2022 21:59:50 +0300 Subject: [PATCH 162/346] g_speed implementation thx to fed for his help --- src/client/component/gameplay.cpp | 17 +++++++++++++++++ src/client/game/dvars.cpp | 2 ++ src/client/game/dvars.hpp | 2 ++ 3 files changed, 21 insertions(+) diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index 31635184..040fa30e 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -88,6 +88,18 @@ namespace gameplay a.jmp(0x1401EAF9D); }); + const auto g_speed_stub = utils::hook::assemble([](utils::hook::assembler& a) + { + a.mov(rax, qword_ptr(reinterpret_cast(&dvars::g_speed))); + a.mov(eax, dword_ptr(rax, 0x10)); + + // original code + a.mov(dword_ptr(r14, 0x36), ax); + a.movzx(eax, word_ptr(r14, 0x3A)); + + a.jmp(0x140323DBC); + }); + const auto client_end_frame_stub = utils::hook::assemble([](utils::hook::assembler& a) { a.push(rax); @@ -130,6 +142,11 @@ namespace gameplay "Flag whether player ejection is on or off"); utils::hook::call(0x140323333, stuck_in_client_stub); + utils::hook::nop(0x140323DAD, 15); + utils::hook::jump(0x140323DAD, g_speed_stub, true); + dvars::g_speed = dvars::register_int("g_speed", 190, std::numeric_limits::min(), std::numeric_limits::max(), + game::DVAR_FLAG_REPLICATED, "changes the speed of the player"); + // Implement player collision dvar dvars::g_playerCollision = dvars::register_bool("g_playerCollision", true, game::DVAR_FLAG_REPLICATED, "Flag whether player collision is on or off"); diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index f46d7d5b..9587788a 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -30,6 +30,8 @@ namespace dvars game::dvar_t* r_fullbright; game::dvar_t* r_chams; + game::dvar_t* g_speed = nullptr; + game::dvar_t* g_gravity = nullptr; game::dvar_t* pm_bouncing = nullptr; diff --git a/src/client/game/dvars.hpp b/src/client/game/dvars.hpp index 24c4afb5..2d3f85be 100644 --- a/src/client/game/dvars.hpp +++ b/src/client/game/dvars.hpp @@ -33,6 +33,8 @@ namespace dvars extern game::dvar_t* r_fullbright; extern game::dvar_t* r_chams; + extern game::dvar_t* g_speed; + extern game::dvar_t* g_gravity; extern game::dvar_t* pm_bouncing; From 5a567c16bacda93cc195f844198d87992fcf5aea Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 5 May 2022 21:07:49 +0200 Subject: [PATCH 163/346] Add best fullbright tech --- src/client/component/renderer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp index 1f6c4137..fea92f58 100644 --- a/src/client/component/renderer.cpp +++ b/src/client/component/renderer.cpp @@ -16,6 +16,8 @@ namespace renderer { switch (dvars::r_fullbright->current.integer) { + case 4: + return 3; case 3: return 13; case 2: @@ -63,7 +65,7 @@ namespace renderer return; } - dvars::r_fullbright = dvars::register_int("r_fullbright", 0, 0, 3, game::DVAR_FLAG_SAVED, "Toggles rendering without lighting"); + dvars::r_fullbright = dvars::register_int("r_fullbright", 0, 0, 4, game::DVAR_FLAG_SAVED, "Toggles rendering without lighting"); r_init_draw_method_hook.create(SELECT_VALUE(0x1404BD140, 0x1405C46E0), &r_init_draw_method_stub); r_update_front_end_dvar_options_hook.create(SELECT_VALUE(0x1404F8870, 0x1405FF9E0), &r_update_front_end_dvar_options_stub); From 77289501cae21b4591e7c5d6b936dd779d16833f Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 5 May 2022 21:09:56 +0200 Subject: [PATCH 164/346] Small fix --- src/client/component/patches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 594879f1..179cae0f 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -227,7 +227,7 @@ namespace patches utils::hook::nop(0x14039E58E, 5); // dvar_foreach // patch "Server is different version" to show the server client version - utils::hook::inject(0x140480952, VERSION); + utils::hook::inject(0x140480955, VERSION); // prevent servers overriding our fov utils::hook::call(0x14023279E, set_client_dvar_from_server_stub); From 01888572ea963603274d13ca5d2183d407383c24 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 5 May 2022 21:10:11 +0200 Subject: [PATCH 165/346] Add g_gravity description --- src/client/component/gameplay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index 040fa30e..e520a13b 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -159,7 +159,7 @@ namespace gameplay utils::hook::jump(0x1401EAFE4, pm_bouncing_stub_mp, true); dvars::g_gravity = dvars::register_int("g_gravity", 800, std::numeric_limits::min(), - std::numeric_limits::max(), game::DVAR_FLAG_REPLICATED, ""); + std::numeric_limits::max(), game::DVAR_FLAG_REPLICATED, "Game gravity in inches per second squared"); utils::hook::jump(0x140322F72, client_end_frame_stub, true); utils::hook::nop(0x140322F68, 1); // Nop skipped opcode } From 954fde4013772833072a5283495eabba4db00e12 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 5 May 2022 21:21:38 +0200 Subject: [PATCH 166/346] Small fix --- src/client/component/network.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 46d4b614..2a361b67 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -284,11 +284,10 @@ namespace network dvars::override::register_int("sv_remote_client_snapshot_msec", 33, 33, 100, game::DVAR_FLAG_NONE); // ignore impure client - utils::hook::jump(0x140481B58, reinterpret_cast(0x140481BEE)); + utils::hook::jump(0x140481B58, 0x140481BEE); // don't send checksum - utils::hook::set(0x140513433, 0); - utils::hook::set(0x14051345A, 0); + utils::hook::set(0x1404F6398, 0); // don't read checksum utils::hook::set(0x1404F6620, 0xC301B0); From 57828f61ec1e3de0dd8ddd5000227d65d6ecacc6 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Mon, 9 May 2022 02:00:58 +0300 Subject: [PATCH 167/346] timescale implementation --- src/client/component/gameplay.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index e520a13b..9a7c4f83 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -15,6 +15,7 @@ namespace gameplay namespace { utils::hook::detour pm_weapon_use_ammo_hook; + utils::hook::detour pm_player_trace_hook; game::dvar_t* jump_slowDownEnable; game::dvar_t* jump_enableFallDamage; @@ -132,6 +133,18 @@ namespace gameplay return; } + auto* timescale = dvars::register_float("timescale", 1.0f, 0.1f, 50.0f, game::DVAR_FLAG_REPLICATED, "Changes Timescale of the game"); + utils::hook::inject(0x1400D89A4, ×cale->current.value); + utils::hook::inject(0x1400DA9D1, ×cale->current.value); + utils::hook::inject(0x1400DB7A9, ×cale->current.value); + utils::hook::inject(0x1400DB7C6, ×cale->current.value); + utils::hook::inject(0x1400DB83C, ×cale->current.value); + utils::hook::inject(0x1400DB9CC, ×cale->current.value); + utils::hook::inject(0x1400DBAF0, ×cale->current.value); + utils::hook::inject(0x1400DBE72, ×cale->current.value); + utils::hook::inject(0x1400DBE9C, ×cale->current.value); + + utils::hook::call(0x1401E8830, jump_apply_slowdown_stub); jump_slowDownEnable = dvars::register_bool("jump_slowDownEnable", true, game::DVAR_FLAG_REPLICATED, "Slow player movement after jumping"); From 74cbf1ba9e8fd9074546113b4b3150e22491c535 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Mon, 9 May 2022 02:04:45 +0300 Subject: [PATCH 168/346] elevators but not yet --- src/client/component/gameplay.cpp | 50 ++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index 9a7c4f83..f506ee13 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -117,6 +117,46 @@ namespace gameplay a.jmp(0x140322F82); }); + + void pm_player_trace_stub(game::pmove_t* pm, game::trace_t* trace, const float* f3, + const float* f4, const game::Bounds* bounds, int a6, int a7) + { + pm_player_trace_hook.invoke(pm, trace, f3, f4, bounds, a6, a7); + + // By setting startsolid to false we allow the player to clip through solid objects above their head + if (dvars::g_enableElevators->current.enabled) + { + trace->startsolid = false; + } + } + + void pm_trace_stub(utils::hook::assembler& a) + { + const auto stand = a.newLabel(); + const auto allsolid = a.newLabel(); + + a.call(qword_ptr(r10, r15)); // Game code + + a.push(rax); + + a.mov(rax, qword_ptr(reinterpret_cast(&dvars::g_enableElevators))); + a.mov(al, byte_ptr(rax, 0x10)); + a.cmp(al, 1); + + a.pop(rax); + + a.jz(stand); // Always stand up + + a.cmp(byte_ptr(rsp, 0x89), 0); // Game code trace[0].allsolid == false + a.jnz(allsolid); + + a.bind(stand); + a.and_(dword_ptr(rbx, 0x54), 0xFFFFFFFD); + a.jmp(0x1401E1CDF); + + a.bind(allsolid); + a.jmp(0x1401E1CE1); + } } class component final : public component_interface @@ -133,6 +173,15 @@ namespace gameplay return; } +#ifdef DEBUG + // Influence PM_JitterPoint code flow so the trace->startsolid checks are 'ignored' + pm_player_trace_hook.create(0x1401E8BE0, &pm_player_trace_stub); + + // If g_enableElevators is 1 the 'ducked' flag will always be removed from the player state + utils::hook::jump(0x1401E1CD1, utils::hook::assemble(pm_trace_stub), true); + dvars::g_enableElevators = dvars::register_bool("g_enableElevators", false, game::DvarFlags::DVAR_FLAG_NONE, ""); +#endif + auto* timescale = dvars::register_float("timescale", 1.0f, 0.1f, 50.0f, game::DVAR_FLAG_REPLICATED, "Changes Timescale of the game"); utils::hook::inject(0x1400D89A4, ×cale->current.value); utils::hook::inject(0x1400DA9D1, ×cale->current.value); @@ -144,7 +193,6 @@ namespace gameplay utils::hook::inject(0x1400DBE72, ×cale->current.value); utils::hook::inject(0x1400DBE9C, ×cale->current.value); - utils::hook::call(0x1401E8830, jump_apply_slowdown_stub); jump_slowDownEnable = dvars::register_bool("jump_slowDownEnable", true, game::DVAR_FLAG_REPLICATED, "Slow player movement after jumping"); From 233ff5d57bc8c186826ec6546dede2e1ed0c395b Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Mon, 9 May 2022 02:09:05 +0300 Subject: [PATCH 169/346] forgot those --- src/client/component/gameplay.cpp | 2 +- src/client/game/dvars.cpp | 1 + src/client/game/dvars.hpp | 1 + src/client/game/structs.hpp | 7 +++++++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index f506ee13..fbee0b3c 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -179,7 +179,7 @@ namespace gameplay // If g_enableElevators is 1 the 'ducked' flag will always be removed from the player state utils::hook::jump(0x1401E1CD1, utils::hook::assemble(pm_trace_stub), true); - dvars::g_enableElevators = dvars::register_bool("g_enableElevators", false, game::DvarFlags::DVAR_FLAG_NONE, ""); + dvars::g_enableElevators = dvars::register_bool("g_enableElevators", false, game::DvarFlags::DVAR_FLAG_NONE, "Enables Elevators"); #endif auto* timescale = dvars::register_float("timescale", 1.0f, 0.1f, 50.0f, game::DVAR_FLAG_REPLICATED, "Changes Timescale of the game"); diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index 9587788a..96007b98 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -24,6 +24,7 @@ namespace dvars game::dvar_t* g_playerEjection = nullptr; game::dvar_t* g_playerCollision = nullptr; game::dvar_t* player_sustainAmmo = nullptr; + game::dvar_t* g_enableElevators = nullptr; game::dvar_t* jump_enableFallDamage; diff --git a/src/client/game/dvars.hpp b/src/client/game/dvars.hpp index 2d3f85be..349fe850 100644 --- a/src/client/game/dvars.hpp +++ b/src/client/game/dvars.hpp @@ -27,6 +27,7 @@ namespace dvars extern game::dvar_t* g_playerEjection; extern game::dvar_t* g_playerCollision; extern game::dvar_t* player_sustainAmmo; + extern game::dvar_t* g_enableElevators; extern game::dvar_t* jump_enableFallDamage; diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index 6fa0cf2f..a9ff21b8 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -1430,6 +1430,9 @@ namespace game struct trace_t { + char __pad0[41]; + bool allsolid; + bool startsolid; }; struct Bounds @@ -1438,6 +1441,10 @@ namespace game float halfSize[3]; }; + struct pmove_t + { + }; + enum PlayerHandIndex { WEAPON_HAND_DEFAULT = 0x0, From f6bef763dd36a8a90c6719f298c4de1615bc96f0 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Wed, 11 May 2022 23:14:48 +0300 Subject: [PATCH 170/346] remove this --- src/client/component/arxan.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp index 528de35e..02989710 100644 --- a/src/client/component/arxan.cpp +++ b/src/client/component/arxan.cpp @@ -145,17 +145,8 @@ namespace arxan { // cba to implement sp, not sure if it's even needed if (game::environment::is_sp()) return; - - // some of arxan crashes - // utils::hook::nop(0xCDEFCAA_b, 6); - // utils::hook::nop(0x930FCAA_b, 6); - // utils::hook::nop(0x867B66_b, 4); - // utils::hook::nop(0x81F0C0_b, 6); - // utils::hook::nop(0x5813609_b, 6); - // utils::hook::nop(0x8DD678_b, 0xEB); - //utils::hook::nop(0xB3D96_b, 4); } }; } -REGISTER_COMPONENT(arxan::component) \ No newline at end of file +REGISTER_COMPONENT(arxan::component) From 1afc395e107070b6c263832aee5083da23bf1731 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 May 2022 17:40:06 +0000 Subject: [PATCH 171/346] Bump deps/rapidjson from `fcb23c2` to `2b2c804` Bumps [deps/rapidjson](https://github.com/Tencent/rapidjson) from `fcb23c2` to `2b2c804`. - [Release notes](https://github.com/Tencent/rapidjson/releases) - [Commits](https://github.com/Tencent/rapidjson/compare/fcb23c2dbf561ec0798529be4f66394d3e4996d8...2b2c80450031028439ba2a17a09ef5aa10f2159b) --- updated-dependencies: - dependency-name: deps/rapidjson dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- deps/rapidjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/rapidjson b/deps/rapidjson index fcb23c2d..2b2c8045 160000 --- a/deps/rapidjson +++ b/deps/rapidjson @@ -1 +1 @@ -Subproject commit fcb23c2dbf561ec0798529be4f66394d3e4996d8 +Subproject commit 2b2c80450031028439ba2a17a09ef5aa10f2159b From 0b082d5540cd237a863714db6d17536cc73f2ccf Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 17 May 2022 10:38:54 +0200 Subject: [PATCH 172/346] Basic 1.15 support --- premake5.lua | 2 +- src/client/component/arxan.cpp | 20 +++++++++++++++++++- src/client/main.cpp | 3 ++- src/client/std_include.cpp | 13 +++++++------ src/client/std_include.hpp | 2 +- src/client/steam/steam.cpp | 9 +++++++++ 6 files changed, 39 insertions(+), 10 deletions(-) diff --git a/premake5.lua b/premake5.lua index 16043516..299c9b69 100644 --- a/premake5.lua +++ b/premake5.lua @@ -302,7 +302,7 @@ targetname "h1-mod" pchheader "std_include.hpp" pchsource "src/client/std_include.cpp" -linkoptions {"/IGNORE:4254", "/DYNAMICBASE:NO", "/SAFESEH:NO", "/LARGEADDRESSAWARE", "/LAST:.main", "/PDBCompress"} +linkoptions {"/IGNORE:4254", "/SAFESEH:NO", "/LARGEADDRESSAWARE", "/PDBCompress"} files {"./src/client/**.rc", "./src/client/**.hpp", "./src/client/**.cpp", "./src/client/resources/**.*"} diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp index 02989710..98b3d108 100644 --- a/src/client/component/arxan.cpp +++ b/src/client/component/arxan.cpp @@ -9,6 +9,24 @@ namespace arxan { namespace { + DWORD get_steam_pid() + { + static DWORD pid = 0; //234567;//GetCurrentProcessId(); + if (pid) return pid; + + HKEY hRegKey; + + if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_QUERY_VALUE, + &hRegKey) != ERROR_SUCCESS) + return pid; + + DWORD dwLength = sizeof(pid); + RegQueryValueExA(hRegKey, "pid", nullptr, nullptr, reinterpret_cast(&pid), &dwLength); + RegCloseKey(hRegKey); + + return pid; + } + utils::hook::detour nt_close_hook; utils::hook::detour nt_query_information_process_hook; @@ -31,7 +49,7 @@ namespace arxan GetWindowThreadProcessId(shell_window, &explorer_pid); } - static_cast(info)->Reserved3 = PVOID(DWORD64(explorer_pid)); + static_cast(info)->Reserved3 = PVOID(DWORD64(get_steam_pid())); } else if (info_class == 30) // ProcessDebugObjectHandle { diff --git a/src/client/main.cpp b/src/client/main.cpp index c6f7ad62..a8c3a78b 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -57,7 +57,8 @@ FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) loader.set_import_resolver([self](const std::string& library, const std::string& function) -> void* { - if (library == "steam_api64.dll") + if (library == "steam_api64.dll" + && function != "SteamAPI_GetSteamInstallPath") // Arxan requires one valid steam api import - maybe SteamAPI_Shutdown is better? { return self.get_proc(function); } diff --git a/src/client/std_include.cpp b/src/client/std_include.cpp index 75331ed0..5622d708 100644 --- a/src/client/std_include.cpp +++ b/src/client/std_include.cpp @@ -1,15 +1,15 @@ #include +#pragma comment(linker, "/stack:0x1000000") + +#ifdef INJECT_HOST_AS_LIB +//#pragma comment(linker, "/base:0x160000000") +#else +#pragma comment(linker, "/base:0x140000000") #pragma comment(linker, "/merge:.data=.cld") #pragma comment(linker, "/merge:.rdata=.clr") #pragma comment(linker, "/merge:.cl=.main") #pragma comment(linker, "/merge:.text=.main") -#pragma comment(linker, "/stack:0x1000000") - -#ifdef INJECT_HOST_AS_LIB -#pragma comment(linker, "/base:0x160000000") -#else -#pragma comment(linker, "/base:0x140000000") #endif #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language=''\"") @@ -47,3 +47,4 @@ extern "C" return -1; } } + diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index 0fd21793..e43275c3 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -3,7 +3,7 @@ #define BINARY_PAYLOAD_SIZE 0x14000000 // Decide whether to load the game as lib or to inject it -//#define INJECT_HOST_AS_LIB +#define INJECT_HOST_AS_LIB #pragma warning(push) #pragma warning(disable: 4100) diff --git a/src/client/steam/steam.cpp b/src/client/steam/steam.cpp index b6fb0dbe..bad30c5a 100644 --- a/src/client/steam/steam.cpp +++ b/src/client/steam/steam.cpp @@ -1,6 +1,8 @@ #include #include "steam.hpp" +#include + namespace steam { uint64_t callbacks::call_id_ = 0; @@ -108,6 +110,13 @@ namespace steam bool SteamAPI_Init() { + const std::filesystem::path steam_path = steam::SteamAPI_GetSteamInstallPath(); + if (steam_path.empty()) return true; + + ::utils::nt::library::load(steam_path / "tier0_s64.dll"); + ::utils::nt::library::load(steam_path / "vstdlib_s64.dll"); + ::utils::nt::library::load(steam_path / "gameoverlayrenderer64.dll"); + ::utils::nt::library::load(steam_path / "steamclient64.dll"); return true; } From ade15a246da08e984475d3c485c665b5a72fc06f Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 17 May 2022 11:38:49 +0200 Subject: [PATCH 173/346] Fix hooking --- src/client/main.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/client/main.cpp b/src/client/main.cpp index a8c3a78b..e8d7dcff 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -20,16 +20,6 @@ BOOL WINAPI system_parameters_info_a(const UINT uiAction, const UINT uiParam, co return SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni); } -FARPROC WINAPI get_proc_address(const HMODULE hModule, const LPCSTR lpProcName) -{ - if (lpProcName == "InitializeCriticalSectionEx"s) - { - component_loader::post_unpack(); - } - - return GetProcAddress(hModule, lpProcName); -} - launcher::mode detect_mode_from_arguments() { if (utils::flags::has_flag("dedicated")) @@ -70,10 +60,6 @@ FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) { return system_parameters_info_a; } - else if (function == "GetProcAddress") - { - return get_proc_address; - } return component_loader::load_import(library, function); }); From 6cd21e1b21356898959f9c8978372cf1254c9c46 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 17 May 2022 11:39:16 +0200 Subject: [PATCH 174/346] Fix scheduler --- src/client/component/scheduler.cpp | 32 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index 2182784d..5a657a4c 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -75,7 +75,8 @@ namespace scheduler { new_callbacks_.access([&](task_list& new_tasks) { - tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), std::move_iterator(new_tasks.end())); + tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), + std::move_iterator(new_tasks.end())); new_tasks = {}; }); }); @@ -98,7 +99,7 @@ namespace scheduler void r_end_frame_stub() { execute(pipeline::renderer); - r_end_frame_hook.invoke(); + //r_end_frame_hook.invoke(); } void server_frame_stub() @@ -115,7 +116,7 @@ namespace scheduler } void schedule(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) + const std::chrono::milliseconds delay) { assert(type >= 0 && type < pipeline::count); @@ -128,7 +129,7 @@ namespace scheduler } void loop(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) + const std::chrono::milliseconds delay) { schedule([callback]() { @@ -138,7 +139,7 @@ namespace scheduler } void once(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) + const std::chrono::milliseconds delay) { schedule([callback]() { @@ -148,7 +149,7 @@ namespace scheduler } void on_game_initialized(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) + const std::chrono::milliseconds delay) { schedule([=]() { @@ -180,8 +181,21 @@ namespace scheduler void post_unpack() override { - r_end_frame_hook.create(SELECT_VALUE(0, 0x6A6300_b), scheduler::r_end_frame_stub); // H1-STEAM(1.15) - g_run_frame_hook.create(SELECT_VALUE(0, 0x417940_b), scheduler::server_frame_stub); // H1(1.15) + utils::hook::jump(SELECT_VALUE(0, 0x6A6300_b), utils::hook::assemble([](utils::hook::assembler& a) + { + a.pushad64(); + a.call_aligned(r_end_frame_stub); + a.popad64(); + + a.sub(rsp, 0x28); + a.call(0x6A5C20_b); + a.mov(rax, 0xEAB4308_b); + a.mov(rax, qword_ptr(rax)); + a.jmp(0x6A6310_b); + }), true); + + //r_end_frame_hook.create(SELECT_VALUE(0, 0x6A6300_b), scheduler::r_end_frame_stub); // H1-STEAM(1.15) + //g_run_frame_hook.create(SELECT_VALUE(0, 0x417940_b), scheduler::server_frame_stub); // H1(1.15) //main_frame_hook.create(SELECT_VALUE(0x1401CE8D0, 0x1400D8310), scheduler::main_frame_stub); can't find } @@ -196,4 +210,4 @@ namespace scheduler }; } -//REGISTER_COMPONENT(scheduler::component) +REGISTER_COMPONENT(scheduler::component) From 601c211cd710609859887d28ece64bb32c9ee624 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Tue, 17 May 2022 12:05:51 +0200 Subject: [PATCH 175/346] Some branding stuff --- src/client/component/branding.cpp | 19 ++++++++++--------- src/client/game/symbols.hpp | 4 ++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp index a95c5aa2..4618a9b0 100644 --- a/src/client/component/branding.cpp +++ b/src/client/component/branding.cpp @@ -34,7 +34,6 @@ namespace branding public: void post_unpack() override { - if (game::environment::is_dedi()) { return; @@ -42,24 +41,26 @@ namespace branding if (game::environment::is_mp()) { - localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n"); - localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER"); + //localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n"); + //localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER"); } - dvars::override::set_string("version", utils::string::va("H1-Mod %s", VERSION)); + //dvars::override::set_string("version", utils::string::va("H1-Mod %s", VERSION)); ui_get_formatted_build_number_hook.create( - SELECT_VALUE(0x1403B1C40, 0x1404E74C0), ui_get_formatted_build_number_stub); + SELECT_VALUE(0x1403B1C40, 0x1DF300_b), ui_get_formatted_build_number_stub); scheduler::loop([]() { const auto font = game::R_RegisterFont("fonts/fira_mono_bold.ttf", 20); - - game::R_AddCmdDrawText("H1-Mod: " VERSION, 0x7FFFFFFF, font, 10.f, - 5.f + static_cast(font->pixelHeight), 1.f, 1.f, 0.0f, color, 0); + if (font) + { + game::R_AddCmdDrawText("H1-Mod: " VERSION, 0x7FFFFFFF, font, 10.f, + 5.f + static_cast(font->pixelHeight), 1.f, 1.f, 0.0f, color, 0); + } }, scheduler::pipeline::renderer); } }; } -//REGISTER_COMPONENT(branding::component) +REGISTER_COMPONENT(branding::component) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 283e7cb8..f6f58353 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -96,8 +96,8 @@ namespace game float* color, Material* material)> R_AddCmdDrawStretchPic{0x17E5C0, 0x2443A0}; WEAK symbol R_RegisterFont{ 0x4D4100, 0x67F630 }; // H1MP(1.15) WEAK symbol R_TextWidth{0x4D43B0, 0x5D94A0}; - WEAK symbol R_GetFontHeight{0x5EA360, 0x5D92C0}; - WEAK symbol R_DrawSomething{0x4D37B0, 0x5D8890}; + WEAK symbol R_GetFontHeight{0x5EA360, 0x67F710}; + WEAK symbol R_DrawSomething{0x4D37B0, 0x67ECE0}; WEAK symbol R_SyncRenderThread{0x4F8240, 0x5FF3A0}; WEAK symbol H1_AddBaseDrawTextCmd{ 0x4F3DC0,0x6A3080 }; // H1MP(1.15) From 31d18eb618719bdcf681b2d1f69c5e8c457d9e86 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Tue, 17 May 2022 17:56:26 +0300 Subject: [PATCH 176/346] 1.04 -> 1.15 --- premake5.lua | 2 +- src/client/component/arxan.cpp | 163 ++++++++++ src/client/component/auth.cpp | 20 +- src/client/component/binding.cpp | 2 +- src/client/component/bots.cpp | 2 +- src/client/component/branding.cpp | 19 +- src/client/component/chat.cpp | 2 +- src/client/component/colors.cpp | 2 +- src/client/component/command.cpp | 2 +- src/client/component/console.cpp | 2 +- src/client/component/dedicated.cpp | 2 +- src/client/component/dedicated_info.cpp | 2 +- src/client/component/demonware.cpp | 2 +- src/client/component/discord.cpp | 2 +- src/client/component/dvar_cheats.cpp | 2 +- src/client/component/dvars.cpp | 2 +- src/client/component/exception.cpp | 2 +- src/client/component/fastfiles.cpp | 2 +- src/client/component/filesystem.cpp | 2 +- src/client/component/fonts.cpp | 2 +- src/client/component/fps.cpp | 2 +- src/client/component/game_console.cpp | 2 +- src/client/component/game_module.cpp | 7 +- src/client/component/gameplay.cpp | 2 +- src/client/component/input.cpp | 2 +- src/client/component/localized_strings.cpp | 4 +- src/client/component/logfile.cpp | 2 +- src/client/component/logger.cpp | 2 +- src/client/component/lui.cpp | 2 +- src/client/component/map_rotation.cpp | 2 +- src/client/component/materials.cpp | 2 +- src/client/component/mods.cpp | 2 +- src/client/component/network.cpp | 2 +- src/client/component/party.cpp | 2 +- src/client/component/patches.cpp | 2 +- src/client/component/ranked.cpp | 2 +- src/client/component/redirect.cpp | 2 +- src/client/component/renderer.cpp | 2 +- src/client/component/scheduler.cpp | 38 ++- src/client/component/scripting.cpp | 2 +- src/client/component/server_list.cpp | 2 +- src/client/component/shaders.cpp | 2 +- src/client/component/slowmotion.cpp | 2 +- src/client/component/splash.cpp | 2 +- src/client/component/stats.cpp | 2 +- src/client/component/steam_proxy.cpp | 2 +- src/client/component/system_check.cpp | 8 +- src/client/component/thread_names.cpp | 2 +- src/client/component/ui_scripting.cpp | 2 +- src/client/component/updater.cpp | 2 +- src/client/component/videos.cpp | 2 +- src/client/component/virtuallobby.cpp | 2 +- src/client/game/game.cpp | 13 + src/client/game/game.hpp | 7 +- src/client/game/symbols.hpp | 356 ++++++++++----------- src/client/loader/loader.cpp | 7 +- src/client/loader/loader.hpp | 2 +- src/client/main.cpp | 40 ++- src/client/std_include.cpp | 19 +- src/client/std_include.hpp | 5 +- src/client/steam/steam.cpp | 11 +- 61 files changed, 516 insertions(+), 293 deletions(-) create mode 100644 src/client/component/arxan.cpp diff --git a/premake5.lua b/premake5.lua index fc9e6e5b..82b0ad32 100644 --- a/premake5.lua +++ b/premake5.lua @@ -303,7 +303,7 @@ targetname "h1-mod" pchheader "std_include.hpp" pchsource "src/client/std_include.cpp" -linkoptions {"/IGNORE:4254", "/DYNAMICBASE:NO", "/SAFESEH:NO", "/LARGEADDRESSAWARE", "/LAST:.main", "/PDBCompress"} +linkoptions {"/IGNORE:4254", "/SAFESEH:NO", "/LARGEADDRESSAWARE", "/PDBCompress"} files {"./src/client/**.rc", "./src/client/**.hpp", "./src/client/**.cpp", "./src/client/resources/**.*"} diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp new file mode 100644 index 00000000..cd8293b1 --- /dev/null +++ b/src/client/component/arxan.cpp @@ -0,0 +1,163 @@ +#include +#include "loader/component_loader.hpp" +#include "scheduler.hpp" +#include "game/game.hpp" + +#include + +namespace arxan +{ + namespace + { + DWORD get_steam_pid() + { + static DWORD pid = 0; //234567;//GetCurrentProcessId(); + if (pid) return pid; + + HKEY hRegKey; + + if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_QUERY_VALUE, + &hRegKey) != ERROR_SUCCESS) + return pid; + + DWORD dwLength = sizeof(pid); + RegQueryValueExA(hRegKey, "pid", nullptr, nullptr, reinterpret_cast(&pid), &dwLength); + RegCloseKey(hRegKey); + + return pid; + } + + utils::hook::detour nt_close_hook; + utils::hook::detour nt_query_information_process_hook; + + NTSTATUS WINAPI nt_query_information_process_stub(const HANDLE handle, const PROCESSINFOCLASS info_class, + const PVOID info, + const ULONG info_length, const PULONG ret_length) + { + auto* orig = static_cast(nt_query_information_process_hook. + get_original()); + const auto status = orig(handle, info_class, info, info_length, ret_length); + + if (NT_SUCCESS(status)) + { + if (info_class == ProcessBasicInformation) + { + static DWORD explorer_pid = 0; + if (!explorer_pid) + { + auto* const shell_window = GetShellWindow(); + GetWindowThreadProcessId(shell_window, &explorer_pid); + } + + static_cast(info)->Reserved3 = PVOID(DWORD64(get_steam_pid())); + } + else if (info_class == 30) // ProcessDebugObjectHandle + { + *static_cast(info) = nullptr; + + return 0xC0000353; + } + else if (info_class == 7) // ProcessDebugPort + { + *static_cast(info) = nullptr; + } + else if (info_class == 31) + { + *static_cast(info) = 1; + } + + //https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess + } + + return status; + } + + NTSTATUS NTAPI nt_close_stub(const HANDLE handle) + { + char info[16]; + if (NtQueryObject(handle, OBJECT_INFORMATION_CLASS(4), &info, 2, nullptr) >= 0 && size_t(handle) != 0x12345) + { + auto* orig = static_cast(nt_close_hook.get_original()); + return orig(handle); + } + + return STATUS_INVALID_HANDLE; + } + + LONG WINAPI exception_filter(const LPEXCEPTION_POINTERS info) + { + if (info->ExceptionRecord->ExceptionCode == STATUS_INVALID_HANDLE) + { + return EXCEPTION_CONTINUE_EXECUTION; + } + + return EXCEPTION_CONTINUE_SEARCH; + } + + void hide_being_debugged() + { + auto* const peb = PPEB(__readgsqword(0x60)); + peb->BeingDebugged = false; + *reinterpret_cast(LPSTR(peb) + 0xBC) &= ~0x70; + } + + void remove_hardware_breakpoints() + { + CONTEXT context; + ZeroMemory(&context, sizeof(context)); + context.ContextFlags = CONTEXT_DEBUG_REGISTERS; + + auto* const thread = GetCurrentThread(); + GetThreadContext(thread, &context); + + context.Dr0 = 0; + context.Dr1 = 0; + context.Dr2 = 0; + context.Dr3 = 0; + context.Dr6 = 0; + context.Dr7 = 0; + + SetThreadContext(thread, &context); + } + + BOOL WINAPI set_thread_context_stub(const HANDLE thread, CONTEXT* context) + { + return SetThreadContext(thread, context); + } + } + + class component final : public component_interface + { + public: + void* load_import(const std::string& library, const std::string& function) override + { + if (function == "SetThreadContext") + { + //return set_thread_context_stub; + } + + return nullptr; + } + + void post_load() override + { + hide_being_debugged(); + scheduler::loop(hide_being_debugged, scheduler::pipeline::async); + + const utils::nt::library ntdll("ntdll.dll"); + nt_close_hook.create(ntdll.get_proc("NtClose"), nt_close_stub); + nt_query_information_process_hook.create(ntdll.get_proc("NtQueryInformationProcess"), + nt_query_information_process_stub); + // https://www.geoffchappell.com/studies/windows/win32/ntdll/api/index.htm + AddVectoredExceptionHandler(1, exception_filter); + } + + void post_unpack() override + { + // cba to implement sp, not sure if it's even needed + if (game::environment::is_sp()) return; + } + }; +} + +REGISTER_COMPONENT(arxan::component) \ No newline at end of file diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index f0950e96..d5a67aa7 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -218,19 +218,19 @@ namespace auth } else { - utils::hook::jump(0x140571E07, 0x140571E5A); // H1(1.4) - utils::hook::jump(0x14004B223, 0x14004B4F2); // H1(1.4) - utils::hook::jump(0x14004B4AD, 0x14004B4F2); // H1(1.4) - utils::hook::jump(0x140572F6F, 0x140572FB0); // H1(1.4) - utils::hook::jump(0x140573470, 0x1405734B6); // H1(1.4) + utils::hook::jump(0x1D6193_b, 0x1D61FA_b); // 1.15 + utils::hook::jump(0x60153_b, 0x60426_b); // 1.15 + utils::hook::jump(0x603E1_b, 0x60426_b); // 1.15 + utils::hook::jump(0x1D7542_b, 0x1D7587_b); // 1.15, MAYBE `1D7553` ON FIRST + utils::hook::jump(0x1D7A82_b, 0x1D7AC8_b); // 1.15 - utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) - utils::hook::call(0x140250ED2, send_connect_data_stub); // H1(1.4) + //utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) couldn't find + utils::hook::call(0x12D437_b, send_connect_data_stub); // 1.15 // Skip checks for sending connect packet - utils::hook::jump(0x1402508FC, 0x140250946); + utils::hook::jump(0x12CDFC_b, 0x12CE5C_b); // 1.15 // Don't instantly timeout the connecting client ? not sure about this - utils::hook::set(0x14025136B, 0xC3); + //utils::hook::set(0x14025136B, 0xC3); // gonna lookup for this soon } command::add("guid", []() @@ -241,4 +241,4 @@ namespace auth }; } -REGISTER_COMPONENT(auth::component) +//REGISTER_COMPONENT(auth::component) diff --git a/src/client/component/binding.cpp b/src/client/component/binding.cpp index e40b7f42..15828dfe 100644 --- a/src/client/component/binding.cpp +++ b/src/client/component/binding.cpp @@ -135,4 +135,4 @@ namespace binding }; } -REGISTER_COMPONENT(binding::component) +//REGISTER_COMPONENT(binding::component) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 5901e5d4..089ac700 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -106,4 +106,4 @@ namespace bots }; } -REGISTER_COMPONENT(bots::component) \ No newline at end of file +//REGISTER_COMPONENT(bots::component) \ No newline at end of file diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp index 2f74693b..7d168135 100644 --- a/src/client/component/branding.cpp +++ b/src/client/component/branding.cpp @@ -34,7 +34,6 @@ namespace branding public: void post_unpack() override { - if (game::environment::is_dedi()) { return; @@ -42,24 +41,26 @@ namespace branding if (game::environment::is_mp()) { - localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n"); - localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER"); + //localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n"); + //localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER"); } - dvars::override::set_string("version", utils::string::va("H1-Mod %s", VERSION)); + //dvars::override::set_string("version", utils::string::va("H1-Mod %s", VERSION)); ui_get_formatted_build_number_hook.create( - SELECT_VALUE(0x1403B1C40, 0x1404E74C0), ui_get_formatted_build_number_stub); + SELECT_VALUE(0x0, 0x1DF300_b), ui_get_formatted_build_number_stub); scheduler::loop([]() { const auto font = game::R_RegisterFont("fonts/fira_mono_bold.ttf", 20); - - game::R_AddCmdDrawText("H1-Mod: " VERSION, 0x7FFFFFFF, font, 10.f, - 5.f + static_cast(font->pixelHeight), 1.f, 1.f, 0.0f, color, 0); + if (font) + { + game::R_AddCmdDrawText("H1-Mod: " VERSION, 0x7FFFFFFF, font, 10.f, + 5.f + static_cast(font->pixelHeight), 1.f, 1.f, 0.0f, color, 0); + } }, scheduler::pipeline::renderer); } }; } -REGISTER_COMPONENT(branding::component) +//REGISTER_COMPONENT(branding::component) \ No newline at end of file diff --git a/src/client/component/chat.cpp b/src/client/component/chat.cpp index 912624f5..c2102f17 100644 --- a/src/client/component/chat.cpp +++ b/src/client/component/chat.cpp @@ -49,4 +49,4 @@ namespace chat }; } -REGISTER_COMPONENT(chat::component) +//REGISTER_COMPONENT(chat::component) diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp index 75eff23a..aa2631cb 100644 --- a/src/client/component/colors.cpp +++ b/src/client/component/colors.cpp @@ -179,4 +179,4 @@ namespace colors }; } -REGISTER_COMPONENT(colors::component) +//REGISTER_COMPONENT(colors::component) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 5f50c25e..ba460c92 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -818,4 +818,4 @@ namespace command }; } -REGISTER_COMPONENT(command::component) +//REGISTER_COMPONENT(command::component) diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 174beaf8..8b39323f 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -296,4 +296,4 @@ namespace console } } -REGISTER_COMPONENT(console::component) +//REGISTER_COMPONENT(console::component) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index d012c16c..e1439d82 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -330,4 +330,4 @@ namespace dedicated }; } -REGISTER_COMPONENT(dedicated::component) \ No newline at end of file +//REGISTER_COMPONENT(dedicated::component) \ No newline at end of file diff --git a/src/client/component/dedicated_info.cpp b/src/client/component/dedicated_info.cpp index 55973193..65aa148e 100644 --- a/src/client/component/dedicated_info.cpp +++ b/src/client/component/dedicated_info.cpp @@ -62,4 +62,4 @@ namespace dedicated_info }; } -REGISTER_COMPONENT(dedicated_info::component) \ No newline at end of file +//REGISTER_COMPONENT(dedicated_info::component) \ No newline at end of file diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp index d74889a5..5363cbd7 100644 --- a/src/client/component/demonware.cpp +++ b/src/client/component/demonware.cpp @@ -596,4 +596,4 @@ namespace demonware }; } -REGISTER_COMPONENT(demonware::component) +//REGISTER_COMPONENT(demonware::component) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index 3698e30f..b69cc99f 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -285,4 +285,4 @@ namespace discord }; } -REGISTER_COMPONENT(discord::component) \ No newline at end of file +//REGISTER_COMPONENT(discord::component) \ No newline at end of file diff --git a/src/client/component/dvar_cheats.cpp b/src/client/component/dvar_cheats.cpp index be9232b3..fba24253 100644 --- a/src/client/component/dvar_cheats.cpp +++ b/src/client/component/dvar_cheats.cpp @@ -198,4 +198,4 @@ namespace dvar_cheats }; } -REGISTER_COMPONENT(dvar_cheats::component) +//REGISTER_COMPONENT(dvar_cheats::component) diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp index d9c77fdf..d9633b87 100644 --- a/src/client/component/dvars.cpp +++ b/src/client/component/dvars.cpp @@ -440,4 +440,4 @@ namespace dvars }; } -REGISTER_COMPONENT(dvars::component) +//REGISTER_COMPONENT(dvars::component) diff --git a/src/client/component/exception.cpp b/src/client/component/exception.cpp index ae8f77db..ea64a4aa 100644 --- a/src/client/component/exception.cpp +++ b/src/client/component/exception.cpp @@ -258,4 +258,4 @@ namespace exception }; } -REGISTER_COMPONENT(exception::component) +//REGISTER_COMPONENT(exception::component) diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index 22ec023c..2cb5ace4 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -56,4 +56,4 @@ namespace fastfiles }; } -REGISTER_COMPONENT(fastfiles::component) +//REGISTER_COMPONENT(fastfiles::component) diff --git a/src/client/component/filesystem.cpp b/src/client/component/filesystem.cpp index d1827936..4a4d049b 100644 --- a/src/client/component/filesystem.cpp +++ b/src/client/component/filesystem.cpp @@ -130,4 +130,4 @@ namespace filesystem }; } -REGISTER_COMPONENT(filesystem::component) \ No newline at end of file +//REGISTER_COMPONENT(filesystem::component) \ No newline at end of file diff --git a/src/client/component/fonts.cpp b/src/client/component/fonts.cpp index 32f55399..989b112a 100644 --- a/src/client/component/fonts.cpp +++ b/src/client/component/fonts.cpp @@ -133,4 +133,4 @@ namespace fonts }; } -REGISTER_COMPONENT(fonts::component) +//REGISTER_COMPONENT(fonts::component) diff --git a/src/client/component/fps.cpp b/src/client/component/fps.cpp index 49caf5bf..ac219e3b 100644 --- a/src/client/component/fps.cpp +++ b/src/client/component/fps.cpp @@ -179,4 +179,4 @@ namespace fps }; } -REGISTER_COMPONENT(fps::component) +//REGISTER_COMPONENT(fps::component) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 26d492ce..2e8dfd9d 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -797,4 +797,4 @@ namespace game_console }; } -REGISTER_COMPONENT(game_console::component) +//REGISTER_COMPONENT(game_console::component) diff --git a/src/client/component/game_module.cpp b/src/client/component/game_module.cpp index bd984624..0ec79d45 100644 --- a/src/client/component/game_module.cpp +++ b/src/client/component/game_module.cpp @@ -3,6 +3,7 @@ #include "game_module.hpp" #include +#include namespace game_module { @@ -90,7 +91,7 @@ namespace game_module utils::nt::library get_game_module() { - static utils::nt::library game{HMODULE(0x140000000)}; + static utils::nt::library game{HMODULE(game::base_address)}; return game; } @@ -110,7 +111,11 @@ namespace game_module void post_load() override { +#ifdef INJECT_HOST_AS_LIB hook_module_resolving(); +#else + assert(get_host_module() == get_game_module()); +#endif } }; } diff --git a/src/client/component/gameplay.cpp b/src/client/component/gameplay.cpp index fbee0b3c..aeb9ff68 100644 --- a/src/client/component/gameplay.cpp +++ b/src/client/component/gameplay.cpp @@ -227,4 +227,4 @@ namespace gameplay }; } -REGISTER_COMPONENT(gameplay::component) +//REGISTER_COMPONENT(gameplay::component) diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 43aff87c..ea2fa309 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -72,4 +72,4 @@ namespace input }; } -REGISTER_COMPONENT(input::component) +//REGISTER_COMPONENT(input::component) diff --git a/src/client/component/localized_strings.cpp b/src/client/component/localized_strings.cpp index 975c76f3..cd9d4718 100644 --- a/src/client/component/localized_strings.cpp +++ b/src/client/component/localized_strings.cpp @@ -44,9 +44,9 @@ namespace localized_strings void post_unpack() override { // Change some localized strings - seh_string_ed_get_string_hook.create(SELECT_VALUE(0x1403924A0, 0x1404BB2A0), &seh_string_ed_get_string); + seh_string_ed_get_string_hook.create(SELECT_VALUE(0x0, 0x585DA0_b), &seh_string_ed_get_string); // 1.15 } }; } -REGISTER_COMPONENT(localized_strings::component) +//REGISTER_COMPONENT(localized_strings::component) diff --git a/src/client/component/logfile.cpp b/src/client/component/logfile.cpp index 08ce07dd..6251ebcc 100644 --- a/src/client/component/logfile.cpp +++ b/src/client/component/logfile.cpp @@ -314,4 +314,4 @@ namespace logfile }; } -REGISTER_COMPONENT(logfile::component) \ No newline at end of file +//REGISTER_COMPONENT(logfile::component) \ No newline at end of file diff --git a/src/client/component/logger.cpp b/src/client/component/logger.cpp index dc2ba9df..218efe39 100644 --- a/src/client/component/logger.cpp +++ b/src/client/component/logger.cpp @@ -177,4 +177,4 @@ namespace logger }; } -REGISTER_COMPONENT(logger::component) +//REGISTER_COMPONENT(logger::component) diff --git a/src/client/component/lui.cpp b/src/client/component/lui.cpp index 9bc87113..d8736114 100644 --- a/src/client/component/lui.cpp +++ b/src/client/component/lui.cpp @@ -55,4 +55,4 @@ namespace lui }; } -REGISTER_COMPONENT(lui::component) +//REGISTER_COMPONENT(lui::component) diff --git a/src/client/component/map_rotation.cpp b/src/client/component/map_rotation.cpp index de1f9f83..7147c2cb 100644 --- a/src/client/component/map_rotation.cpp +++ b/src/client/component/map_rotation.cpp @@ -177,4 +177,4 @@ namespace map_rotation }; } -REGISTER_COMPONENT(map_rotation::component) +//REGISTER_COMPONENT(map_rotation::component) diff --git a/src/client/component/materials.cpp b/src/client/component/materials.cpp index c5fed9a2..c870039c 100644 --- a/src/client/component/materials.cpp +++ b/src/client/component/materials.cpp @@ -209,4 +209,4 @@ namespace materials }; } -REGISTER_COMPONENT(materials::component) +//REGISTER_COMPONENT(materials::component) diff --git a/src/client/component/mods.cpp b/src/client/component/mods.cpp index ea6a9027..db73d83c 100644 --- a/src/client/component/mods.cpp +++ b/src/client/component/mods.cpp @@ -116,4 +116,4 @@ namespace mods }; } -REGISTER_COMPONENT(mods::component) +//REGISTER_COMPONENT(mods::component) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 2a361b67..d1212d81 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -323,4 +323,4 @@ namespace network }; } -REGISTER_COMPONENT(network::component) +//REGISTER_COMPONENT(network::component) diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 5a88eb65..3638d266 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -642,4 +642,4 @@ namespace party }; } -REGISTER_COMPONENT(party::component) \ No newline at end of file +//REGISTER_COMPONENT(party::component) \ No newline at end of file diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 179cae0f..7d5d75fc 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -283,4 +283,4 @@ namespace patches }; } -REGISTER_COMPONENT(patches::component) +//REGISTER_COMPONENT(patches::component) diff --git a/src/client/component/ranked.cpp b/src/client/component/ranked.cpp index f4776e2d..4ec15b44 100644 --- a/src/client/component/ranked.cpp +++ b/src/client/component/ranked.cpp @@ -44,4 +44,4 @@ namespace ranked }; } -REGISTER_COMPONENT(ranked::component) +//REGISTER_COMPONENT(ranked::component) diff --git a/src/client/component/redirect.cpp b/src/client/component/redirect.cpp index 0443df55..9d3cc65f 100644 --- a/src/client/component/redirect.cpp +++ b/src/client/component/redirect.cpp @@ -80,4 +80,4 @@ namespace redirect }; } -REGISTER_COMPONENT(redirect::component) +//REGISTER_COMPONENT(redirect::component) diff --git a/src/client/component/renderer.cpp b/src/client/component/renderer.cpp index fea92f58..666ae0f0 100644 --- a/src/client/component/renderer.cpp +++ b/src/client/component/renderer.cpp @@ -82,4 +82,4 @@ namespace renderer }; } -REGISTER_COMPONENT(renderer::component) \ No newline at end of file +//REGISTER_COMPONENT(renderer::component) \ No newline at end of file diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index 68d82dd1..f24ac54e 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -75,7 +75,8 @@ namespace scheduler { new_callbacks_.access([&](task_list& new_tasks) { - tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), std::move_iterator(new_tasks.end())); + tasks.insert(tasks.end(), std::move_iterator(new_tasks.begin()), + std::move_iterator(new_tasks.end())); new_tasks = {}; }); }); @@ -88,7 +89,7 @@ namespace scheduler utils::hook::detour r_end_frame_hook; utils::hook::detour g_run_frame_hook; utils::hook::detour main_frame_hook; - utils::hook::detour hks_frame_hook; + //utils::hook::detour hks_frame_hook; //no scripting for now void execute(const pipeline type) { @@ -99,7 +100,7 @@ namespace scheduler void r_end_frame_stub() { execute(pipeline::renderer); - r_end_frame_hook.invoke(); + //r_end_frame_hook.invoke(); } void server_frame_stub() @@ -125,7 +126,7 @@ namespace scheduler } void schedule(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) + const std::chrono::milliseconds delay) { assert(type >= 0 && type < pipeline::count); @@ -138,7 +139,7 @@ namespace scheduler } void loop(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) + const std::chrono::milliseconds delay) { schedule([callback]() { @@ -148,7 +149,7 @@ namespace scheduler } void once(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) + const std::chrono::milliseconds delay) { schedule([callback]() { @@ -158,7 +159,7 @@ namespace scheduler } void on_game_initialized(const std::function& callback, const pipeline type, - const std::chrono::milliseconds delay) + const std::chrono::milliseconds delay) { schedule([=]() { @@ -190,10 +191,23 @@ namespace scheduler void post_unpack() override { - r_end_frame_hook.create(SELECT_VALUE(0x1404F7310, 0x1405FE470), scheduler::r_end_frame_stub); - g_run_frame_hook.create(SELECT_VALUE(0x1402772D0, 0x14033A640), scheduler::server_frame_stub); - main_frame_hook.create(SELECT_VALUE(0x1401CE8D0, 0x1400D8310), scheduler::main_frame_stub); - hks_frame_hook.create(SELECT_VALUE(0x1400E37F0, 0x1401755B0), scheduler::hks_frame_stub); + utils::hook::jump(SELECT_VALUE(0, 0x6A6300_b), utils::hook::assemble([](utils::hook::assembler& a) + { + a.pushad64(); + a.call_aligned(r_end_frame_stub); + a.popad64(); + + a.sub(rsp, 0x28); + a.call(0x6A5C20_b); + a.mov(rax, 0xEAB4308_b); + a.mov(rax, qword_ptr(rax)); + a.jmp(0x6A6310_b); + }), true); + + //r_end_frame_hook.create(SELECT_VALUE(0x0, 0x6A6300_b), scheduler::r_end_frame_stub); + //g_run_frame_hook.create(SELECT_VALUE(0x0, 0x417940_b), scheduler::server_frame_stub); + //main_frame_hook.create(SELECT_VALUE(0x0, 0x0), scheduler::main_frame_stub); + //hks_frame_hook.create(SELECT_VALUE(0x0, 0x0), scheduler::hks_frame_stub); // no scripting for now } void pre_destroy() override @@ -207,4 +221,4 @@ namespace scheduler }; } -REGISTER_COMPONENT(scheduler::component) +//REGISTER_COMPONENT(scheduler::component) \ No newline at end of file diff --git a/src/client/component/scripting.cpp b/src/client/component/scripting.cpp index b31e2329..56acae83 100644 --- a/src/client/component/scripting.cpp +++ b/src/client/component/scripting.cpp @@ -216,4 +216,4 @@ namespace scripting }; } -REGISTER_COMPONENT(scripting::component) +//REGISTER_COMPONENT(scripting::component) diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index bbe3cb0d..cca9fd72 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -423,4 +423,4 @@ namespace server_list }; } -REGISTER_COMPONENT(server_list::component) +//REGISTER_COMPONENT(server_list::component) diff --git a/src/client/component/shaders.cpp b/src/client/component/shaders.cpp index 11e2e0d6..60d74ddc 100644 --- a/src/client/component/shaders.cpp +++ b/src/client/component/shaders.cpp @@ -48,4 +48,4 @@ namespace shaders }; } -REGISTER_COMPONENT(shaders::component) +//REGISTER_COMPONENT(shaders::component) diff --git a/src/client/component/slowmotion.cpp b/src/client/component/slowmotion.cpp index f75f8a7e..486230d9 100644 --- a/src/client/component/slowmotion.cpp +++ b/src/client/component/slowmotion.cpp @@ -50,4 +50,4 @@ namespace slowmotion }; } -REGISTER_COMPONENT(slowmotion::component) +//REGISTER_COMPONENT(slowmotion::component) diff --git a/src/client/component/splash.cpp b/src/client/component/splash.cpp index c9ec30be..716be76c 100644 --- a/src/client/component/splash.cpp +++ b/src/client/component/splash.cpp @@ -138,4 +138,4 @@ namespace splash }; } -REGISTER_COMPONENT(splash::component) +//REGISTER_COMPONENT(splash::component) diff --git a/src/client/component/stats.cpp b/src/client/component/stats.cpp index 99ffdd5f..7c373b29 100644 --- a/src/client/component/stats.cpp +++ b/src/client/component/stats.cpp @@ -88,4 +88,4 @@ namespace stats }; } -REGISTER_COMPONENT(stats::component) +//REGISTER_COMPONENT(stats::component) diff --git a/src/client/component/steam_proxy.cpp b/src/client/component/steam_proxy.cpp index 5fa54708..2454e01e 100644 --- a/src/client/component/steam_proxy.cpp +++ b/src/client/component/steam_proxy.cpp @@ -185,4 +185,4 @@ namespace steam_proxy } } -REGISTER_COMPONENT(steam_proxy::component) +//REGISTER_COMPONENT(steam_proxy::component) diff --git a/src/client/component/system_check.cpp b/src/client/component/system_check.cpp index 9c88bd5c..3a86b5de 100644 --- a/src/client/component/system_check.cpp +++ b/src/client/component/system_check.cpp @@ -51,13 +51,13 @@ namespace system_check { static std::unordered_map mp_zone_hashes = { - {"patch_common_mp.ff", "3F44B0CFB0B8E0FBD9687C2942204AB7F11E66E6E15C73B8B4A5EB5920115A31"}, + {"patch_common_mp.ff", "E45EF5F29D12A5A47F405F89FBBEE479C0A90D02141ABF852D481689514134A1"}, }; static std::unordered_map sp_zone_hashes = { // Steam doesn't necessarily deliver this file :( - {"patch_common.ff", "BB0617DD94AF2F511571E7184BBEDE76E64D97E5D0DAFDB457F00717F035EBF0"}, + {"patch_common.ff", "1D32A9770F90ED022AA76F4859B4AB178E194A703383E61AC2CE83B1E828B18F"}, }; @@ -85,7 +85,7 @@ namespace system_check public: void post_load() override { - verify_binary_version(); + //verify_binary_version(); if (!is_valid()) { @@ -97,4 +97,4 @@ namespace system_check }; } -REGISTER_COMPONENT(system_check::component) +//REGISTER_COMPONENT(system_check::component) diff --git a/src/client/component/thread_names.cpp b/src/client/component/thread_names.cpp index 84b5fa70..ebd36a6d 100644 --- a/src/client/component/thread_names.cpp +++ b/src/client/component/thread_names.cpp @@ -57,4 +57,4 @@ namespace thread_names }; } -REGISTER_COMPONENT(thread_names::component) +//REGISTER_COMPONENT(thread_names::component) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index c6b44883..f4dffb32 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -206,4 +206,4 @@ namespace ui_scripting }; } -REGISTER_COMPONENT(ui_scripting::component) \ No newline at end of file +//REGISTER_COMPONENT(ui_scripting::component) \ No newline at end of file diff --git a/src/client/component/updater.cpp b/src/client/component/updater.cpp index e1210cee..4403d821 100644 --- a/src/client/component/updater.cpp +++ b/src/client/component/updater.cpp @@ -468,4 +468,4 @@ namespace updater }; } -REGISTER_COMPONENT(updater::component) +//REGISTER_COMPONENT(updater::component) diff --git a/src/client/component/videos.cpp b/src/client/component/videos.cpp index c17dd899..04b9d2c5 100644 --- a/src/client/component/videos.cpp +++ b/src/client/component/videos.cpp @@ -52,4 +52,4 @@ namespace videos }; } -REGISTER_COMPONENT(videos::component) +//REGISTER_COMPONENT(videos::component) diff --git a/src/client/component/virtuallobby.cpp b/src/client/component/virtuallobby.cpp index a4ebf39d..a68f755a 100644 --- a/src/client/component/virtuallobby.cpp +++ b/src/client/component/virtuallobby.cpp @@ -61,4 +61,4 @@ namespace virtuallobby }; } -REGISTER_COMPONENT(virtuallobby::component) +//REGISTER_COMPONENT(virtuallobby::component) diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 9045761b..95fb0793 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -3,6 +3,14 @@ namespace game { + uint64_t base_address; + + void load_base_address() + { + const auto module = GetModuleHandle(NULL); + base_address = uint64_t(module); + } + int Cmd_Argc() { return cmd_args->argc[cmd_args->nesting]; @@ -102,3 +110,8 @@ namespace game } } } + +uintptr_t operator"" _b(const uintptr_t ptr) +{ + return game::base_address + ptr; +} \ No newline at end of file diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 47041ca9..1d6ab0c8 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -5,10 +5,13 @@ #define SELECT_VALUE(sp, mp) (game::environment::is_sp() ? (sp) : (mp)) -#define SERVER_CD_KEY "S1X-CD-Key" +#define SERVER_CD_KEY "H1MOD-CD-Key" namespace game { + extern uint64_t base_address; + void load_base_address(); + namespace environment { launcher::mode get_mode(); @@ -67,4 +70,6 @@ namespace game bool VirtualLobby_Loaded(); } +uintptr_t operator"" _b(const uintptr_t ptr); + #include "symbols.hpp" diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 9acc02d3..83ba3e8d 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -8,119 +8,119 @@ namespace game * Functions **************************************************************/ - WEAK symbol AddRefToValue{0x14036E600, 0x14043C580}; - WEAK symbol RemoveRefToValue{0x1403700F0, 0x14043E090}; - WEAK symbol AddRefToObject{0x14036E5F0, 0x14043C570}; - WEAK symbol RemoveRefToObject{0x14036FFE0, 0x14043DF80}; - WEAK symbol AllocThread{0x14036E960, 0x14043C8E0}; - WEAK symbol AllocVariable{0x14036E9C0, 0x14043C940}; + WEAK symbol AddRefToValue{0x0, 0x0}; + WEAK symbol RemoveRefToValue{0x0, 0x0}; + WEAK symbol AddRefToObject{0x0, 0x0}; + WEAK symbol RemoveRefToObject{0x0, 0x0}; + WEAK symbol AllocThread{0x0, 0x0}; + WEAK symbol AllocVariable{0x0, 0x0}; - WEAK symbol Cbuf_AddText{0x140342EB0, 0x1404033B0}; + WEAK symbol Cbuf_AddText{0x0, 0x1CF480}; // 1.15 WEAK symbol Cbuf_ExecuteBufferInternal{0x140342FC0, 0x1404034C0}; - WEAK symbol Conbuf_AppendText{0x1403E3300, 0x140513FF0}; - WEAK symbol ConcatArgs{0x1402697F0, 0x140335D70}; - WEAK symbol Cmd_ExecuteSingleCommand{0x140343980, 0x140403F60}; - WEAK symbol Cmd_AddCommandInternal{0x1403433E0, 0x140403950}; - WEAK symbol Cmd_RemoveCommand{0x140343FF0, 0x1404045D0}; - WEAK symbol Cmd_TokenizeString{0x140344110, 0x1404046F0}; - WEAK symbol Cmd_EndTokenizeString{0x140343630, 0x140403C20}; + void (int, int, const char*))> Cbuf_ExecuteBufferInternal{0x0, 0x0}; + WEAK symbol Conbuf_AppendText{0x0, 0x0}; + WEAK symbol ConcatArgs{0x0, 0x0}; + WEAK symbol Cmd_ExecuteSingleCommand{0x0, 0x0}; + WEAK symbol Cmd_AddCommandInternal{0x0, 0x0}; + WEAK symbol Cmd_RemoveCommand{0x0, 0x0}; + WEAK symbol Cmd_TokenizeString{0x0, 0x0}; + WEAK symbol Cmd_EndTokenizeString{0x0, 0x0}; - WEAK symbol AimAssist_AddToTargetList{0, 0x14009D0F0}; + WEAK symbol AimAssist_AddToTargetList{0x0, 0x0}; WEAK symbol BG_GetWeaponNameComplete{0x140430550, 0x1401F9670}; + char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x0, 0x0}; - WEAK symbol Com_Frame_Try_Block_Function{0x1401CE8D0, 0x1400D8310}; - WEAK symbol Com_GetCurrentCoDPlayMode{0, 0x1405039A0}; - WEAK symbol Com_InFrontend{0x1400E4B30, 0x140176A30}; - WEAK symbol Com_SetSlowMotion{0, 0x1400DB790}; - WEAK symbol Com_Error{0x1403509C0, 0x1400D78A0}; - WEAK symbol Com_Quit_f{0x140352BE0, 0x1400DA830}; - WEAK symbol Com_Shutdown{0x140353B70, 0x1400DB8A0}; + WEAK symbol Com_Frame_Try_Block_Function{0x0, 0x0}; + WEAK symbol Com_GetCurrentCoDPlayMode{0x0, 0x0}; + WEAK symbol Com_InFrontend{0x0, 0x0}; + WEAK symbol Com_SetSlowMotion{0x0, 0x0}; + WEAK symbol Com_Error{0x0, 0x0}; + WEAK symbol Com_Quit_f{0x0, 0x0}; + WEAK symbol Com_Shutdown{0x0, 0x0}; - WEAK symbol Quit{0x140352D90, 0x1400DA830}; + WEAK symbol Quit{0x0, 0x0}; - WEAK symbol CG_GameMessage{0x1401389A0, 0x140220CC0}; - WEAK symbol CG_GameMessageBold{0x140138750, 0x140220620}; + WEAK symbol CG_GameMessage{0x0, 0x0}; + WEAK symbol CG_GameMessageBold{0x0, 0x0}; WEAK symbol CG_SetClientDvarFromServer{0, 0x140236120}; + const char* dvar, const char* value)> CG_SetClientDvarFromServer{0x0, 0x0}; WEAK symbol CG_GetWeaponDisplayName{0x14016EC30, 0x1400B5840}; + bool isAlternate, char* outputBuffer, int bufferLen)> CG_GetWeaponDisplayName{0x0, 0x0}; - WEAK symbol CL_IsCgameInitialized{0x14017EE30, 0x140245650}; - WEAK symbol CL_VirtualLobbyShutdown{0, 0x140256D40}; + WEAK symbol CL_IsCgameInitialized{0x0, 0x0}; + WEAK symbol CL_VirtualLobbyShutdown{0x0, 0x0}; - WEAK symbol Dvar_SetCommand{0x1403C72B0, 0x1404FD0A0}; - WEAK symbol Dvar_FindVar{0x1403C5D50, 0x1404FBB00}; - WEAK symbol Dvar_ClearModified{0x1403C5C20, 0x1404FB930}; - WEAK symbol Dvar_GetCombinedString{0x140354DF0, 0x14041D830}; - WEAK symbol Dvar_ValueToString{0x1403C8560, 0x1404FE660}; - WEAK symbol Dvar_Reset{0, 0x1404FCC40}; + WEAK symbol Dvar_SetCommand{0x0, 0x0}; + WEAK symbol Dvar_FindVar{0x0, 0x0}; + WEAK symbol Dvar_ClearModified{0x0, 0x0}; + WEAK symbol Dvar_GetCombinedString{0x0, 0x0}; + WEAK symbol Dvar_ValueToString{0x0, 0x0}; + WEAK symbol Dvar_Reset{0x0, 0x0}; WEAK symbol Dvar_SetFromStringByNameFromSource{0, 0x1404FD490}; + DvarSetSource)> Dvar_SetFromStringByNameFromSource{0x0, 0x0}; WEAK symbol Dvar_RegisterBool{0x1403C47E0, 0x1404FA540}; + unsigned int flags)> Dvar_RegisterBool{0x0, 0x0}; WEAK symbol Dvar_RegisterInt{0x1403C4CC0, 0x1404FAA20}; + unsigned int flags)> Dvar_RegisterInt{0x0, 0x0}; WEAK symbol Dvar_RegisterFloat{0x1403C4BB0, 0x1404FA910}; + float max, unsigned int flags)> Dvar_RegisterFloat{0x0, 0x0}; WEAK symbol Dvar_RegisterString{0x1403C4DA0, 0x1404FAB00}; + unsigned int flags)> Dvar_RegisterString{0x0, 0x0}; WEAK symbol Dvar_RegisterVec4{0x1403C5220, 0x1404FAF40}; + float w, float min, float max, unsigned int flags)> Dvar_RegisterVec4{0x0, 0x0}; - WEAK symbol FS_ReadFile{0x1403B9020, 0x1404EE720}; - WEAK symbol FS_FreeFile{0x1403B9010, 0x1404EE710}; - WEAK symbol FS_Startup{0x1403B85D0, 0x1404EDD30}; - WEAK symbol FS_AddLocalizedGameDirectory{0x1403B6030, 0x1404EBE20}; + WEAK symbol FS_ReadFile{0x0, 0x0}; + WEAK symbol FS_FreeFile{0x0, 0x0}; + WEAK symbol FS_Startup{0x0, 0x0}; + WEAK symbol FS_AddLocalizedGameDirectory{0x0, 0x0}; - WEAK symbol GetVariable{0x14036FDD0, 0x14043DD70}; - WEAK symbol GetNewVariable{0x14036FA00, 0x14043D990}; - WEAK symbol GetNewArrayVariable{0x14036F880, 0x14043D810}; - WEAK symbol GScr_LoadConsts{0x1402D13E0, 0x140393810}; - WEAK symbol FindVariable{0x14036F4B0, 0x14043D430}; - WEAK symbol FindEntityId{0x14036F3B0, 0x14043D330}; - WEAK symbol RemoveVariableValue{0x140370190, 0x14043E130}; + WEAK symbol GetVariable{0x0, 0x0}; + WEAK symbol GetNewVariable{0x0, 0x0}; + WEAK symbol GetNewArrayVariable{0x0, 0x0}; + WEAK symbol GScr_LoadConsts{0x0, 0x0}; + WEAK symbol FindVariable{0x0, 0x0}; + WEAK symbol FindEntityId{0x0, 0x0}; + WEAK symbol RemoveVariableValue{0x0, 0x0}; WEAK symbol GetEntityFieldValue{0x140373780, 0x140441780}; + int entnum, int offset)> GetEntityFieldValue{0x0, 0x0}; - WEAK symbol generateHashValue{0x1400FE8A0, 0x1401B1010}; + WEAK symbol generateHashValue{0x0, 0x0}; - WEAK symbol G_Glass_Update{0x14026C570, 0x14033A640}; - WEAK symbol G_GetClientScore{0, 0x140342F90}; - WEAK symbol G_GetWeaponForName{0x1402C2A90, 0x14038C300}; + WEAK symbol G_Glass_Update{0x0, 0x0}; + WEAK symbol G_GetClientScore{0x0, 0x0}; + WEAK symbol G_GetWeaponForName{0x0, 0x0}; WEAK symbol G_GivePlayerWeapon{0x1402C2DF0, 0x14038C750}; - WEAK symbol G_InitializeAmmo{0x140270980, 0x14033EDD0}; - WEAK symbol G_SelectWeapon{0x1402C3750, 0x14038D1B0}; - WEAK symbol G_TakePlayerWeapon{0x1402C3900, 0x14038D370}; + int startInAltMode, int, int, int, char, ...)> G_GivePlayerWeapon{0x0, 0x0}; + WEAK symbol G_InitializeAmmo{0x0, 0x0}; + WEAK symbol G_SelectWeapon{0x0, 0x0}; + WEAK symbol G_TakePlayerWeapon{0x0, 0x0}; - WEAK symbol I_CleanStr{0x1403CD230, 0x140503D00}; + WEAK symbol I_CleanStr{0x0, 0x0}; - WEAK symbol Key_KeynumToString{0x140187CC0, 0x14024FE10}; + WEAK symbol Key_KeynumToString{0x0, 0x0}; - WEAK symbol Live_SyncOnlineDataFlags{0, 0x14059A700}; + WEAK symbol Live_SyncOnlineDataFlags{0x0, 0x0}; - WEAK symbol Material_RegisterHandle{0x1404E48B0, 0x1405EAB30}; + WEAK symbol Material_RegisterHandle{0x0, 0x0}; - WEAK symbol NetadrToSockadr{0x1403C11C0, 0x1404F62F0}; - WEAK symbol NET_OutOfBandPrint{0x140357560, 0x1404255D0}; - WEAK symbol NET_SendLoopPacket{0, 0x140425790}; - WEAK symbol NET_StringToAdr{0, 0x140425870}; + WEAK symbol NetadrToSockadr{0x0, 0x0}; + WEAK symbol NET_OutOfBandPrint{0x0, 0x0}; + WEAK symbol NET_SendLoopPacket{0x0, 0x0}; + WEAK symbol NET_StringToAdr{0x0, 0x0}; WEAK symbol R_AddCmdDrawStretchPic{0x14017E5C0, 0x1402443A0}; - WEAK symbol R_RegisterFont{0x1404D4100, 0x1405D91E0}; - WEAK symbol R_TextWidth{0x1404D43B0, 0x1405D94A0}; - WEAK symbol R_GetFontHeight{0x1405EA360, 0x1405D92C0}; - WEAK symbol R_DrawSomething{0x1404D37B0, 0x1405D8890}; - WEAK symbol R_SyncRenderThread{0x1404F8240, 0x1405FF3A0}; + float* color, Material* material)> R_AddCmdDrawStretchPic{0x0, 0x0}; + WEAK symbol R_RegisterFont{0x0, 0x67F630}; // 1.15 + WEAK symbol R_TextWidth{0x0, 0x0}; + WEAK symbol R_GetFontHeight{0x0, 0x67F710}; // 1.15 + WEAK symbol R_DrawSomething{0x0, 0x67ECE0}; // 1.15 + WEAK symbol R_SyncRenderThread{0x0, 0x0}; WEAK symbol H1_AddBaseDrawTextCmd{0x1404F3DC0, 0x1405FB1F0}; + void* style_unk)> H1_AddBaseDrawTextCmd{0x0, 0x6A3080}; // 1.15 #define R_AddCmdDrawText(TXT, MC, F, X, Y, XS, YS, R, C, S) \ H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S,-1, 0, game::R_DrawSomething(S)) @@ -128,157 +128,155 @@ namespace game H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S, CP, CC, game::R_DrawSomething(S)) WEAK symbol Image_Setup{0x1404D7D50, 0x1405DCF90}; + uint32_t imageFlags, DXGI_FORMAT imageFormat, const char* name, const D3D11_SUBRESOURCE_DATA* initData)> Image_Setup{0x0, 0x0}; WEAK symbol VM_Execute{0x140376360, 0x140444350}; + unsigned int paramcount)> VM_Execute{0x0, 0x0}; WEAK symbol Scr_NotifyId{0x140375800, 0x1404437E0}; - WEAK symbol Scr_AllocVector{0x140370930, 0x14043E7D0}; - WEAK symbol Scr_GetFloat{0x140374D20, 0x140442D10}; - WEAK symbol Scr_GetString{0x140375210, 0x140443150}; - WEAK symbol Scr_GetNumParam{0x140374F30, 0x140442E70}; - WEAK symbol Scr_ClearOutParams{0x140374460, 0x140442510}; - WEAK symbol Scr_GetEntityIdRef{0x140372D50, 0x140440D80}; - WEAK symbol Scr_GetEntityId{0x140372CA0, 0x140440CD0}; - WEAK symbol Scr_SetObjectField{0x1402B9F60, 0x140385330}; + unsigned int paramcount)> Scr_NotifyId{0x0, 0x0}; + WEAK symbol Scr_AllocVector{0x0, 0x0}; + WEAK symbol Scr_GetFloat{0x0, 0x0}; + WEAK symbol Scr_GetString{0x0, 0x0}; + WEAK symbol Scr_GetNumParam{0x0, 0x0}; + WEAK symbol Scr_ClearOutParams{0x0, 0x0}; + WEAK symbol Scr_GetEntityIdRef{0x0, 0x0}; + WEAK symbol Scr_GetEntityId{0x0, 0x0}; + WEAK symbol Scr_SetObjectField{0x0, 0x0}; - WEAK symbol ScrPlace_GetViewPlacement{0x1401981F0, 0x140288550}; + WEAK symbol ScrPlace_GetViewPlacement{0x0, 0x0}; WEAK symbol - DB_EnumXAssets_Internal{0x1401C9C10, 0x1402BA830}; - WEAK symbol DB_GetXAssetName{0x14019A390, 0x14028BE50}; - WEAK symbol DB_GetXAssetTypeSize{0x14019A3B0, 0x14028BE70}; + DB_EnumXAssets_Internal{0x0, 0x0}; + WEAK symbol DB_GetXAssetName{0x0, 0x0}; + WEAK symbol DB_GetXAssetTypeSize{0x0, 0x0}; WEAK symbol DB_FindXAssetHeader{0x1401CA150, 0x1402BAC70}; + int createDefault)> DB_FindXAssetHeader{0x0, 0x0}; WEAK symbol LUI_OpenMenu{0x14039D5F0, 0x1404CD210}; - WEAK symbol LUI_BeginEvent{0x1400D27F0, 0x140161A00}; - WEAK symbol LUI_EndEvent{0x1400D3A80, 0x140162CD0}; - WEAK symbol LUI_EnterCriticalSection{0x1400D3B70, 0x140162DC0}; - WEAK symbol LUI_LeaveCriticalSection{0x1400D8DB0, 0x140168150}; + int a3, int a4, unsigned int a5)> LUI_OpenMenu{0x0, 0x0}; + WEAK symbol LUI_BeginEvent{0x0, 0x0}; + WEAK symbol LUI_EndEvent{0x0, 0x0}; + WEAK symbol LUI_EnterCriticalSection{0x0, 0x0}; + WEAK symbol LUI_LeaveCriticalSection{0x0, 0x0}; - WEAK symbol Menu_IsMenuOpenAndVisible{0x1404709C0, 0x1404C7320}; + WEAK symbol Menu_IsMenuOpenAndVisible{0x0, 0x0}; - WEAK symbol SL_FindString{0x14036D700, 0x14043B470}; - WEAK symbol SL_GetString{0x14036D9A0, 0x14043B840}; - WEAK symbol SL_ConvertToString{0x14036D420, 0x14043B170}; - WEAK symbol SL_GetCanonicalString{0x14036A310, 0x140437EA0}; + WEAK symbol SL_FindString{0x0, 0x0}; + WEAK symbol SL_GetString{0x0, 0x0}; + WEAK symbol SL_ConvertToString{0x0, 0x0}; + WEAK symbol SL_GetCanonicalString{0x0, 0x0}; - WEAK symbol SV_DirectConnect{0, 0x140480860}; - WEAK symbol SV_Cmd_ArgvBuffer{0x1403446C0, 0x140404CA0}; - WEAK symbol SV_Cmd_TokenizeString{0x140344740, 0x140404D20}; - WEAK symbol SV_Cmd_EndTokenizedString{0x140344700, 0x140404CE0}; + WEAK symbol SV_DirectConnect{0x0, 0x0}; + WEAK symbol SV_Cmd_ArgvBuffer{0x0, 0x0}; + WEAK symbol SV_Cmd_TokenizeString{0x0, 0x0}; + WEAK symbol SV_Cmd_EndTokenizedString{0x0, 0x0}; - WEAK symbol SV_AddBot{0, 0x140480190}; - WEAK symbol SV_BotIsBot{0, 0x14046E6C0}; - WEAK symbol SV_BotGetRandomName{0, 0x14046DBA0}; - WEAK symbol SV_SpawnTestClient{0, 0x1404832A0}; + WEAK symbol SV_AddBot{0x0, 0x0}; + WEAK symbol SV_BotIsBot{0x0, 0x0}; + WEAK symbol SV_BotGetRandomName{0x0, 0x0}; + WEAK symbol SV_SpawnTestClient{0x0, 0x0}; - WEAK symbol SV_GetGuid{0, 0x140484B90}; - WEAK symbol SV_GetClientPing{0, 0x140484B70}; - WEAK symbol SV_GetPlayerstateForClientNum{0x1404426D0, 0x140484C10}; - WEAK symbol SV_SetConfigstring{0, 0x140486720}; - WEAK symbol SV_Loaded{0x140442F60, 0x1404864A0}; - WEAK symbol SV_KickClientNum{0, 0x14047ED00}; - WEAK symbol SV_MapExists{0, 0x14047ED60}; - WEAK symbol SV_ExecuteClientCommand{0, 0x140481870}; - WEAK symbol SV_FastRestart{0, 0x14047E990}; - WEAK symbol SV_GameSendServerCommand{ - 0x1403F3A70, 0x140484AD0 - }; + WEAK symbol SV_GetGuid{0x0, 0x0}; + WEAK symbol SV_GetClientPing{0x0, 0x0}; + WEAK symbol SV_GetPlayerstateForClientNum{0x0, 0x0}; + WEAK symbol SV_SetConfigstring{0x0, 0x0}; + WEAK symbol SV_Loaded{0x0, 0x0}; + WEAK symbol SV_KickClientNum{0x0, 0x0}; + WEAK symbol SV_MapExists{0x0, 0x0}; + WEAK symbol SV_ExecuteClientCommand{0x0, 0x0}; + WEAK symbol SV_FastRestart{0x0, 0x0}; + WEAK symbol SV_GameSendServerCommand{0x0, 0x0}; - WEAK symbol Sys_ShowConsole{0x1403E3B90, 0x140514910}; - WEAK symbol Sys_Error{0x1403E0C40, 0x140511520}; + WEAK symbol Sys_ShowConsole{0x0, 0x0}; + WEAK symbol Sys_Error{0x0, 0x0}; WEAK symbol - Sys_BuildAbsPath{0x1403CFF90, 0x140507010}; - WEAK symbol Sys_Milliseconds{0x1403E2B10, 0x140513710}; - WEAK symbol Sys_IsDatabaseReady2{0x1403580B0, 0x14042B090}; - WEAK symbol Sys_SendPacket{0x1403E2820, 0x1405133B0}; - WEAK symbol Sys_FileExists{0x1403E0CE0, 0x1405115E0}; + Sys_BuildAbsPath{0x0, 0x0}; + WEAK symbol Sys_Milliseconds{0x0, 0x0}; + WEAK symbol Sys_IsDatabaseReady2{0x0, 0x0}; + WEAK symbol Sys_SendPacket{0x0, 0x0}; + WEAK symbol Sys_FileExists{0x0, 0x0}; - WEAK symbol UI_GetMapDisplayName{0, 0x140408CC0}; - WEAK symbol UI_GetGameTypeDisplayName{0, 0x1404086A0}; - WEAK symbol UI_RunMenuScript{0x14039EFF0, 0x1404CFE60}; - WEAK symbol UI_TextWidth{0x1403A0F20, 0x1404D21A0}; + WEAK symbol UI_GetMapDisplayName{0x0, 0x0}; + WEAK symbol UI_GetGameTypeDisplayName{0x0, 0x0}; + WEAK symbol UI_RunMenuScript{0x0, 0x0}; + WEAK symbol UI_TextWidth{0x0, 0x0}; - WEAK symbol UI_SafeTranslateString{0x140350430, 0x14041C580}; + WEAK symbol UI_SafeTranslateString{0x0, 0x0}; - WEAK symbol longjmp{0x140648FD4, 0x140779F64}; - WEAK symbol _setjmp{0x1406BFD30, 0x1407F5F90}; + WEAK symbol longjmp{0x0, 0x0}; + WEAK symbol _setjmp{0x0, 0x0}; /*************************************************************** * Variables **************************************************************/ - WEAK symbol sv_cmd_args{0x14AD99A10, 0x14946BA20}; + WEAK symbol sv_cmd_args{0x0, 0x0}; - WEAK symbol g_script_error_level{0x14BCFA4A4, 0x14A33C824}; - WEAK symbol g_script_error{0x14BCFA5C0, 0x14A33C940}; + WEAK symbol g_script_error_level{0x0, 0x0}; + WEAK symbol g_script_error{0x0, 0x0}; - WEAK symbol levelEntityId{0x14B65E3B0, 0x149CA0730}; - WEAK symbol gameEntityId{0x14B65E3B4, 0x149CA0734}; + WEAK symbol levelEntityId{0x0, 0x0}; + WEAK symbol gameEntityId{0x0, 0x0}; - WEAK symbol command_whitelist{0x141079A60, 0x14120C360}; - WEAK symbol cmd_functions{0x14AD99AB8, 0x14946BAC8}; - WEAK symbol cmd_args{0x14AD99960, 0x14946B970}; + WEAK symbol command_whitelist{0x0, 0x0}; + WEAK symbol cmd_functions{0x0, 0x344DF18}; // 1.15 + WEAK symbol cmd_args{0x0, 0x0}; - WEAK symbol g_poolSize{0x140DE84A0, 0x140FEADF0}; - WEAK symbol g_classMap{0x14107AAF0, 0x1412106B0}; + WEAK symbol g_poolSize{0x0, 0x0}; + WEAK symbol g_classMap{0x0, 0x0}; - WEAK symbol scr_VarGlob{0x14B686480, 0x149CC8800}; - WEAK symbol scr_VmPub{0x14BCFC6C0, 0x14A33EA40}; - WEAK symbol scr_function_stack{0x14BD06C40, 0x14A348FC0}; + WEAK symbol scr_VarGlob{0x0, 0x0}; + WEAK symbol scr_VmPub{0x0, 0x0}; + WEAK symbol scr_function_stack{0x0, 0x0}; - WEAK symbol gfxDrawMethod{0x14F05CE50, 0x14FD21180}; + WEAK symbol gfxDrawMethod{0x0, 0x0}; - WEAK symbol dvarCount{0x14C217D10, 0x14D064CF4}; - WEAK symbol dvarPool{0x14C217D20, 0x14D064D00}; + WEAK symbol dvarCount{0x0, 0x0}; + WEAK symbol dvarPool{0x0, 0x0}; - WEAK symbol DB_XAssetPool{0x140DE8C80, 0x140FEB5D0}; - WEAK symbol g_assetNames{0x1408B0870, 0x140FEA240}; + WEAK symbol DB_XAssetPool{0x0, 0x0}; + WEAK symbol g_assetNames{0x0, 0x0}; - WEAK symbol keyCatchers{0x14243DAF0, 0x142D0BA9C}; - WEAK symbol playerKeys{0x1422A873C, 0x142C19AFC}; + WEAK symbol keyCatchers{0x0, 0x0}; + WEAK symbol playerKeys{0x0, 0x0}; - WEAK symbol query_socket{0, 0x14DDFBF98}; + WEAK symbol query_socket{0x0, 0x0}; - WEAK symbol threadIds{0x14B19B880, 0x149810E00}; + WEAK symbol threadIds{0x0, 0x0}; namespace mp { - WEAK symbol g_entities{0, 0x14621E530}; - WEAK symbol svs_clients{0, 0x14B204A10}; - WEAK symbol svs_numclients{0, 0x14B204A0C}; - WEAK symbol gameTime{0, 0x14621BDBC}; + WEAK symbol g_entities{0x0, 0x71F19E0}; // 1.15 + WEAK symbol svs_clients{0x0, 0x0}; + WEAK symbol svs_numclients{0x0, 0x0}; + WEAK symbol gameTime{0x0, 0x0}; - WEAK symbol ping{0, 0x142D106F0}; + WEAK symbol ping{0x0, 0x0}; - WEAK symbol sv_serverId_value{0, 0x14A3E99B8}; + WEAK symbol sv_serverId_value{0x0, 0x0}; - WEAK symbol virtualLobby_loaded{0, 0x142D077FD}; + WEAK symbol virtualLobby_loaded{0x0, 0x0}; } namespace sp { - WEAK symbol g_entities{0x14550DD90, 0}; + WEAK symbol g_entities{0x0, 0x0}; } namespace hks { - WEAK symbol lua_state{0x141E2C2F8, 0x1426D3D08}; - WEAK symbol hksi_lua_pushlstring{0x14004DA90, 0x1400624F0}; - WEAK symbol hks_obj_getfield{0x14009C0A0, 0x14012C600}; - WEAK symbol hks_obj_settable{0x14009D240, 0x14012D820}; - WEAK symbol hks_obj_gettable{0x14009C580, 0x14012CAE0}; - WEAK symbol vm_call_internal{0x1400C87A0, 0x140159EB0}; - WEAK symbol Hashtable_Create{0x14008B3B0, 0x14011B320}; + WEAK symbol lua_state{0x0, 0x0}; + WEAK symbol hksi_lua_pushlstring{0x0, 0x0}; + WEAK symbol hks_obj_getfield{0x0, 0x0}; + WEAK symbol hks_obj_settable{0x0, 0x0}; + WEAK symbol hks_obj_gettable{0x0, 0x0}; + WEAK symbol vm_call_internal{0x0, 0x0}; + WEAK symbol Hashtable_Create{0x0, 0x0}; WEAK symbol cclosure_Create{0x14008B5D0, 0x14011B540}; - WEAK symbol hksi_luaL_ref{0x1400A64D0, 0x140136D30}; - WEAK symbol hksi_luaL_unref{0x14009EF10, 0x14012F610}; - WEAK symbol closePendingUpvalues{0x14008EA00, 0x14011E970}; + int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x0, 0x0}; + WEAK symbol hksi_luaL_ref{0x0, 0x0}; + WEAK symbol hksi_luaL_unref{0x0, 0x0}; + WEAK symbol closePendingUpvalues{0x0, 0x0}; } } diff --git a/src/client/loader/loader.cpp b/src/client/loader/loader.cpp index 1bc7b41c..4ec12c7c 100644 --- a/src/client/loader/loader.cpp +++ b/src/client/loader/loader.cpp @@ -31,7 +31,7 @@ FARPROC loader::load(const utils::nt::library& library, const std::string& buffe return FARPROC(library.get_ptr() + source.get_relative_entry_point()); } -FARPROC loader::load_library(const std::string& filename) const +FARPROC loader::load_library(const std::string& filename, uint64_t* base_address) const { const auto target = utils::nt::library::load(filename); if (!target) @@ -40,10 +40,7 @@ FARPROC loader::load_library(const std::string& filename) const } const auto base = size_t(target.get_ptr()); - if(base != 0x140000000) - { - throw std::runtime_error{utils::string::va("Binary was mapped at 0x%llX (instead of 0x%llX). Something is severely broken :(", base, 0x140000000)}; - } + *base_address = base; this->load_imports(target, target); this->load_tls(target, target); diff --git a/src/client/loader/loader.hpp b/src/client/loader/loader.hpp index 2c5d86f9..0c0b5a12 100644 --- a/src/client/loader/loader.hpp +++ b/src/client/loader/loader.hpp @@ -5,7 +5,7 @@ class loader final { public: FARPROC load(const utils::nt::library& library, const std::string& buffer) const; - FARPROC load_library(const std::string& filename) const; + FARPROC load_library(const std::string& filename, uint64_t* base_address) const; void set_import_resolver(const std::function& resolver); diff --git a/src/client/main.cpp b/src/client/main.cpp index 500a09c4..224c93b2 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -20,16 +20,6 @@ BOOL WINAPI system_parameters_info_a(const UINT uiAction, const UINT uiParam, co return SystemParametersInfoA(uiAction, uiParam, pvParam, fWinIni); } -FARPROC WINAPI get_proc_address(const HMODULE hModule, const LPCSTR lpProcName) -{ - if (lpProcName == "GlobalMemoryStatusEx"s) - { - component_loader::post_unpack(); - } - - return GetProcAddress(hModule, lpProcName); -} - launcher::mode detect_mode_from_arguments() { if (utils::flags::has_flag("dedicated")) @@ -50,14 +40,15 @@ launcher::mode detect_mode_from_arguments() return launcher::mode::none; } -FARPROC load_binary(const launcher::mode mode) +FARPROC load_binary(const launcher::mode mode, uint64_t* base_address) { loader loader; utils::nt::library self; loader.set_import_resolver([self](const std::string& library, const std::string& function) -> void* { - if (library == "steam_api64.dll") + if (library == "steam_api64.dll" + && function != "SteamAPI_GetSteamInstallPath") // Arxan requires one valid steam api import - maybe SteamAPI_Shutdown is better? { return self.get_proc(function); } @@ -69,10 +60,6 @@ FARPROC load_binary(const launcher::mode mode) { return system_parameters_info_a; } - else if (function == "GetProcAddress") - { - return get_proc_address; - } return component_loader::load_import(library, function); }); @@ -99,8 +86,13 @@ FARPROC load_binary(const launcher::mode mode) "Failed to read game binary (%s)!\nPlease copy the h1-mod.exe into your Call of Duty: Modern Warfare Remastered installation folder and run it from there.", binary.data())); } - - return loader.load_library(binary); + +#ifdef INJECT_HOST_AS_LIB + return loader.load_library(binary, base_address); +#else + *base_address = 0x140000000; + return loader.load(self, data); +#endif } void remove_crash_file() @@ -158,6 +150,8 @@ void apply_proper_directory() int main() { + ShowWindow(GetConsoleWindow(), SW_HIDE); + FARPROC entry_point; enable_dpi_awareness(); @@ -166,6 +160,7 @@ int main() limit_parallel_dll_loading(); srand(uint32_t(time(nullptr))); + remove_crash_file(); { auto premature_shutdown = true; @@ -179,8 +174,8 @@ int main() try { - apply_proper_directory(); - remove_crash_file(); + //apply_proper_directory(); + //remove_crash_file(); if (!component_loader::post_start()) return 0; @@ -194,12 +189,15 @@ int main() game::environment::set_mode(mode); - entry_point = load_binary(mode); + uint64_t base_address{}; + entry_point = load_binary(mode, &base_address); if (!entry_point) { throw std::runtime_error("Unable to load binary into memory"); } + game::base_address = base_address; + if (!component_loader::post_load()) return 0; premature_shutdown = false; diff --git a/src/client/std_include.cpp b/src/client/std_include.cpp index efe6cd64..20f99122 100644 --- a/src/client/std_include.cpp +++ b/src/client/std_include.cpp @@ -1,6 +1,23 @@ #include -#pragma comment(linker, "/base:0x160000000") +#pragma comment(linker, "/stack:0x1000000") + +#ifdef INJECT_HOST_AS_LIB +//#pragma comment(linker, "/base:0x160000000") +#else +#pragma comment(linker, "/base:0x140000000") +#pragma comment(linker, "/merge:.data=.cld") +#pragma comment(linker, "/merge:.rdata=.clr") +#pragma comment(linker, "/merge:.cl=.main") +#pragma comment(linker, "/merge:.text=.main") +#endif + +#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language=''\"") + +#ifndef INJECT_HOST_AS_LIB +#pragma bss_seg(".payload") +char payload_data[BINARY_PAYLOAD_SIZE]; +#endif extern "C" { diff --git a/src/client/std_include.hpp b/src/client/std_include.hpp index 98a00a2d..e43275c3 100644 --- a/src/client/std_include.hpp +++ b/src/client/std_include.hpp @@ -1,6 +1,9 @@ #pragma once -#define BINARY_PAYLOAD_SIZE 0x12000000 +#define BINARY_PAYLOAD_SIZE 0x14000000 + +// Decide whether to load the game as lib or to inject it +#define INJECT_HOST_AS_LIB #pragma warning(push) #pragma warning(disable: 4100) diff --git a/src/client/steam/steam.cpp b/src/client/steam/steam.cpp index b6fb0dbe..18ecd7d6 100644 --- a/src/client/steam/steam.cpp +++ b/src/client/steam/steam.cpp @@ -1,6 +1,8 @@ #include #include "steam.hpp" +#include + namespace steam { uint64_t callbacks::call_id_ = 0; @@ -108,6 +110,13 @@ namespace steam bool SteamAPI_Init() { + const std::filesystem::path steam_path = steam::SteamAPI_GetSteamInstallPath(); + if (steam_path.empty()) return true; + + ::utils::nt::library::load(steam_path / "tier0_s64.dll"); + ::utils::nt::library::load(steam_path / "vstdlib_s64.dll"); + ::utils::nt::library::load(steam_path / "gameoverlayrenderer64.dll"); + ::utils::nt::library::load(steam_path / "steamclient64.dll"); return true; } @@ -235,4 +244,4 @@ namespace steam } } -} +} \ No newline at end of file From d66771e7c5794214788a53ea0c00c437c07cd154 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Tue, 17 May 2022 18:08:53 +0300 Subject: [PATCH 177/346] small fix --- src/client/component/branding.cpp | 2 +- src/client/component/scheduler.cpp | 2 +- src/client/game/game.hpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp index 7d168135..fd7e84e8 100644 --- a/src/client/component/branding.cpp +++ b/src/client/component/branding.cpp @@ -63,4 +63,4 @@ namespace branding }; } -//REGISTER_COMPONENT(branding::component) \ No newline at end of file +REGISTER_COMPONENT(branding::component) \ No newline at end of file diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index f24ac54e..1c8b7287 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -221,4 +221,4 @@ namespace scheduler }; } -//REGISTER_COMPONENT(scheduler::component) \ No newline at end of file +REGISTER_COMPONENT(scheduler::component) \ No newline at end of file diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index 1d6ab0c8..d1e623af 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -40,10 +40,10 @@ namespace game { if (environment::is_sp()) { - return sp_object_; + return reinterpret_cast((uint64_t)sp_object_ + base_address); } - return mp_object_; + return reinterpret_cast((uint64_t)mp_object_ + base_address); } operator T* () const From f67ac544de3666d260daf79b8f63094ce2e078c3 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 17 May 2022 10:10:28 -0500 Subject: [PATCH 178/346] notes and changes [skip ci] --- src/client/component/system_check.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/component/system_check.cpp b/src/client/component/system_check.cpp index 3a86b5de..6954de1a 100644 --- a/src/client/component/system_check.cpp +++ b/src/client/component/system_check.cpp @@ -64,12 +64,13 @@ namespace system_check return verify_hashes(mp_zone_hashes) && (game::environment::is_dedi() || verify_hashes(sp_zone_hashes)); } + // need to update these values void verify_binary_version() { const auto value = *reinterpret_cast(0x140001337); if (value != 0xFFB8006D && value != 0xFFB80080) { - throw std::runtime_error("Unsupported Call of Duty: Modern Warfare Remastered version(1.4)"); + throw std::runtime_error("Unsupported Call of Duty: Modern Warfare Remastered version (1.15)"); } } } @@ -90,7 +91,7 @@ namespace system_check if (!is_valid()) { MessageBoxA(nullptr, "Your game files are outdated or unsupported.\n" - "Please get the latest officially supported Call of Duty: Modern Warfare Remastered 1.4 files, or you will get random crashes and issues.", + "Please get the latest officially supported Call of Duty: Modern Warfare Remastered files, or you will get random crashes and issues.", "Invalid game files!", MB_ICONINFORMATION); } } From 122de8127217e3535df116261027b8715fc3e38d Mon Sep 17 00:00:00 2001 From: m Date: Tue, 17 May 2022 10:31:31 -0500 Subject: [PATCH 179/346] disclaimer [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f835f69e..de63ca3f 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

An experimental client for Call of Duty Modern Warfare Remastered (version 1.04). -Support for the latest version (1.15) is planned for the future. +Research for the latest Steam version of the game (1.15) is on the `1.15` branch. [This project is based on S1x.](https://github.com/XLabsProject/s1x-client) ## Compile from source From 7805115bd6faa1e96b5f0c05566a5ee02d118466 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 17 May 2022 10:44:51 -0500 Subject: [PATCH 180/346] credits + version [skip ci] --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index de63ca3f..61080be3 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,9 @@

-An experimental client for Call of Duty Modern Warfare Remastered (version 1.04). -Research for the latest Steam version of the game (1.15) is on the `1.15` branch. +An experimental client for Call of Duty Modern Warfare Remastered (version `1.4.814118.0-0.32767`). +Research for the latest Steam version of the game is on the `1.15` branch. + [This project is based on S1x.](https://github.com/XLabsProject/s1x-client) ## Compile from source @@ -26,8 +27,8 @@ Research for the latest Steam version of the game (1.15) is on the `1.15` branch - [XLabsProject](https://github.com/XLabsProject) - codebase and iw6x/s1x research - [quaK](https://github.com/Joelrau) - lots of insight and help - [fed](https://github.com/fedddddd) - fixed DW/networking, work from [h2-mod](https://github.com/fedddddd/h2-mod) -- [mjkzy](https://github.com/mjkzy) - porting code from s1x -- [Skull](https://github.com/skkuull) - initial porting of s1x +- [Skull](https://github.com/skkuull) + [mjkzy](https://github.com/mjkzy) - porting code from s1x +- [momo5502](https://github.com/momo5502) - Arxan/Steam research, developer of x labs clients :D ## Disclaimer From befa637f874ebfbd648b1d62e5fd861804738e35 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Tue, 17 May 2022 19:56:53 +0200 Subject: [PATCH 181/346] Stuff --- src/client/component/console.cpp | 292 +++--------------- src/client/component/demonware.cpp | 110 ++++--- src/client/game/demonware/data_types.hpp | 37 +++ .../game/demonware/services/bdStorage.cpp | 41 ++- 4 files changed, 187 insertions(+), 293 deletions(-) diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 8b39323f..78ed8422 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -1,14 +1,10 @@ #include #include "console.hpp" #include "loader/component_loader.hpp" + #include "game/game.hpp" #include "command.hpp" -#include -#include -#include -#include - namespace game_console { void print(int type, const std::string& data); @@ -18,271 +14,50 @@ namespace console { namespace { - using message_queue = std::queue; - utils::concurrency::container messages; - - bool native_console() + DWORD WINAPI console(LPVOID) { - static const auto flag = utils::flags::has_flag("nativeconsole"); - return flag; - } + FreeConsole(); + AllocConsole(); + AttachConsole(GetCurrentProcessId()); - void hide_console() - { - auto* const con_window = GetConsoleWindow(); + (void)freopen("CONIN$", "r", stdin); + (void)freopen("CONOUT$", "w", stdout); - DWORD process; - GetWindowThreadProcessId(con_window, &process); - - if (!native_console() && (process == GetCurrentProcessId() || IsDebuggerPresent())) - { - ShowWindow(con_window, SW_HIDE); - } - } - - std::string format(va_list* ap, const char* message) - { - static thread_local char buffer[0x1000]; - - const auto count = _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), message, *ap); - - if (count < 0) return {}; - return {buffer, static_cast(count)}; - } - - void dispatch_message(const int type, const std::string& message) - { - if (native_console()) - { - printf("%s\n", message.data()); - return; - } - - game_console::print(type, message); - messages.access([&message](message_queue& msgs) - { - msgs.emplace(message); - }); - } - - void append_text(const char* text) - { - dispatch_message(con_type_info, text); - } - } - - class component final : public component_interface - { - public: - component() - { - hide_console(); - - if (native_console()) - { - setvbuf(stdout, nullptr, _IONBF, 0); - setvbuf(stderr, nullptr, _IONBF, 0); - } - else - { - (void)_pipe(this->handles_, 1024, _O_TEXT); - (void)_dup2(this->handles_[1], 1); - (void)_dup2(this->handles_[1], 2); - } - } - - void post_start() override - { - this->terminate_runner_ = false; - - this->console_runner_ = utils::thread::create_named_thread("Console IO", [this] - { - if (native_console()) - { - this->native_input(); - } - else - { - this->runner(); - } - }); - } - - void pre_destroy() override - { - this->terminate_runner_ = true; - - printf("\r\n"); - _flushall(); - - if (this->console_runner_.joinable()) - { - this->console_runner_.join(); - } - - if (this->console_thread_.joinable()) - { - this->console_thread_.join(); - } - -#ifndef NATIVE_CONSOLE - _close(this->handles_[0]); - _close(this->handles_[1]); -#endif - - messages.access([&](message_queue& msgs) - { - msgs = {}; - }); - } - - void post_unpack() override - { - // Redirect input (]command) - utils::hook::jump(SELECT_VALUE(0x1403E34C0, 0x1405141E0), append_text); // H1(1.4) - - this->initialize(); - } - - private: - volatile bool console_initialized_ = false; - volatile bool terminate_runner_ = false; - - std::thread console_runner_; - std::thread console_thread_; - - int handles_[2]{}; - - void initialize() - { - this->console_thread_ = utils::thread::create_named_thread("Console", [this]() - { - if (!native_console() && (game::environment::is_dedi() || !utils::flags::has_flag("noconsole"))) - { - game::Sys_ShowConsole(); - } - - if (!game::environment::is_dedi()) - { - // Hide that shit - ShowWindow(console::get_window(), SW_MINIMIZE); - } - - { - messages.access([&](message_queue&) - { - this->console_initialized_ = true; - }); - } - - MSG msg; - while (!this->terminate_runner_) - { - if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - command::execute("quit", false); - break; - } - - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else - { - this->log_messages(); - std::this_thread::sleep_for(1ms); - } - } - }); - } - - void log_messages() - { - /*while*/ - if (this->console_initialized_ && !messages.get_raw().empty()) - { - std::queue message_queue_copy; - - { - messages.access([&](message_queue& msgs) - { - message_queue_copy = std::move(msgs); - msgs = {}; - }); - } - - while (!message_queue_copy.empty()) - { - log_message(message_queue_copy.front()); - message_queue_copy.pop(); - } - } - - fflush(stdout); - fflush(stderr); - } - - static void log_message(const std::string& message) - { - OutputDebugStringA(message.data()); - game::Conbuf_AppendText(message.data()); - } - - void runner() - { - char buffer[1024]; - - while (!this->terminate_runner_ && this->handles_[0]) - { - const auto len = _read(this->handles_[0], buffer, sizeof(buffer)); - if (len > 0) - { - dispatch_message(con_type_info, std::string(buffer, len)); - } - else - { - std::this_thread::sleep_for(1ms); - } - } - - std::this_thread::yield(); - } - - void native_input() - { std::string cmd; - while (!this->terminate_runner_) + while (true) { std::getline(std::cin, cmd); - command::execute(cmd); + } - std::this_thread::yield(); + return 0; } - }; - - HWND get_window() - { - return *reinterpret_cast((SELECT_VALUE(0x14CF56C00, 0x14DDFC2D0))); // H1(1.4) } - void set_title(std::string title) + std::string format(va_list* ap, const char* message) { - SetWindowText(get_window(), title.data()); + static thread_local char buffer[0x1000]; + + const auto count = _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), message, *ap); + + if (count < 0) return {}; + return { buffer, static_cast(count) }; } - void set_size(const int width, const int height) + void dispatch_message(const int type, const std::string& message) { - RECT rect; - GetWindowRect(get_window(), &rect); + //if (native_console()) + //{ + printf("%s\n", message.data()); + // return; + //} - SetWindowPos(get_window(), nullptr, rect.left, rect.top, width, height, 0); - - auto* const logo_window = *reinterpret_cast(SELECT_VALUE(0x14CF56C10, 0x14DDFC2E0)); // H1(1.4) - SetWindowPos(logo_window, nullptr, 5, 5, width - 25, 60, 0); + //game_console::print(type, message); + //messages.access([&message](message_queue& msgs) + // { + // msgs.emplace(message); + // }); } void print(const int type, const char* fmt, ...) @@ -294,6 +69,15 @@ namespace console dispatch_message(type, result); } + + class component final : public component_interface + { + public: + void post_start() override + { + CreateThread(0, 0, console, 0, 0, 0); + } + }; } -//REGISTER_COMPONENT(console::component) +REGISTER_COMPONENT(console::component) diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp index 35aa1999..7c2b1460 100644 --- a/src/client/component/demonware.cpp +++ b/src/client/component/demonware.cpp @@ -297,7 +297,7 @@ namespace demonware if (server) { - server->handle_input(buf, len, {s, to, tolen}); + server->handle_input(buf, len, { s, to, tolen }); return len; } @@ -425,9 +425,9 @@ namespace demonware } } - void bd_logger_stub(char* a1, void* a2, void* a3, void* a4, const char* function, ...) + void bd_logger_stub() { - + //printf("logged\n"); } #ifdef DEBUG @@ -481,6 +481,32 @@ namespace demonware printf("bdAuth: Unknown error\n"); } #endif + + utils::hook::detour kekw_hook; + bool kekw_stub(__int64 a1, __int64 a2, __int64* a3) + { + // Checks X-Signature header or something + utils::hook::set(0x7D4AB0_b, 0xC301B0); + // Checks extended_data and extra_data in json object + utils::hook::set(0x7D55C0_b, 0xC301B0); + return kekw_hook.invoke(a1, a2, a3); + } + + void* allocate_somewhere_near(uint8_t* base_address) + { + const size_t PAGE_SIZE = 0x1000; + size_t offset = 0; + while (true) + { + offset += PAGE_SIZE; + auto res = VirtualAlloc(base_address - offset, PAGE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (res) + { + std::memset(res, 0, PAGE_SIZE); + return res; + } + } + } } class component final : public component_interface @@ -542,52 +568,64 @@ namespace demonware gethostbyname has been replaced with getaddrinfo btw, still you can't get online.. */ - utils::hook::jump(SELECT_VALUE(0x140610320, 0x1407400B0), bd_logger_stub); // H1MP64(1.4) + //utils::hook::jump(SELECT_VALUE(0, 0x7EBC20_b), bd_logger_stub); if (game::environment::is_sp()) { - utils::hook::set(0x1405FCA00, 0xC3); // bdAuthSteam H1(1.4) - utils::hook::set(0x140333A00, 0xC3); // dwNet H1(1.4) + // utils::hook::set(0x1405FCA00, 0xC3); // bdAuthSteam H1(1.4) + // utils::hook::set(0x140333A00, 0xC3); // dwNet H1(1.4) return; } - utils::hook::set(0x140715039, 0x0); // CURLOPT_SSL_VERIFYPEER H1MP64(1.4) - utils::hook::set(0x140715025, 0xAF); // CURLOPT_SSL_VERIFYHOST H1MP64(1.4) - utils::hook::set(0x14095433C, 0x0); // HTTPS -> HTTP [MWR OK][S1X: 0x14088D0E8] + utils::hook::set(0x7C0AD9_b, 0x0); // CURLOPT_SSL_VERIFYPEER H1MP64(1.15) + utils::hook::set(0x7C0AC5_b, 0xAF); // CURLOPT_SSL_VERIFYHOST H1MP64(1.15) + utils::hook::set(0xA1327C_b, 0x0); // HTTPS -> HTTP [MWR OK][S1X: 0x14088D0E8] //HTTPS -> HTTP - utils::hook::inject(0x14006DDA9, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x14003852E] - utils::hook::inject(0x14006E11C, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x14003884F] - utils::hook::inject(0x14006E2FB, "http://prod.umbrella.demonware.net/v1.0/"); // ---> [H1MP1.4 - S1X: 0x140038A07] - utils::hook::inject(0x14006E9A9, "http://prod.uno.demonware.net/v1.0/"); - utils::hook::inject(0x14006ED49, "http://prod.uno.demonware.net/v1.0/"); - utils::hook::inject(0x140728170, "http://%s:%d/auth/"); + char* umbrella = (char*)allocate_somewhere_near((uint8_t*)game::base_address); + std::memcpy(umbrella, "http://prod.umbrella.demonware.net/v1.0/", sizeof("http://prod.umbrella.demonware.net/v1.0/")); - utils::hook::set(0x14047F290, 0xC3); // SV_SendMatchData H1MP64(1.4) - utils::hook::set(0x140598990, 0xC3); // Live_CheckForFullDisconnect H1MP64(1.4) + utils::hook::inject(0x8615F_b, umbrella); + utils::hook::inject(0x8638C_b, umbrella); -#ifdef DEBUG - // yes - utils::hook::call(0x140727BEB, l); - utils::hook::call(0x140727AFC, i); - utils::hook::call(0x140727E49, h); - utils::hook::call(0x140727E30, g); - utils::hook::call(0x140727E37, f); - utils::hook::call(0x140727DF2, e); - utils::hook::call(0x140727DF9, d); - utils::hook::call(0x140727CFC, c); - utils::hook::call(0x140727C82, b); - utils::hook::call(0x140727E6A, a); -#endif + char* uno = (char*)allocate_somewhere_near((uint8_t*)game::base_address); + std::memcpy(uno, "http://prod.uno.demonware.net/v1.0/", sizeof("http://prod.uno.demonware.net/v1.0/")); + + utils::hook::inject(0x86C56_b, uno); + utils::hook::inject(0x86F96_b, uno); + + BYTE bytes[] = { 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x25, 0x73, 0x3A, 0x25, 0x64, 0x2F, 0x61, 0x75, 0x74, 0x68, 0x2F, 0x0 }; // KEKW + std::memcpy((void*)0x9EDB08_b, bytes, sizeof(bytes)); //utils::hook::inject(0x140728170, "http://%s:%d/auth/"); :DDD + + //utils::hook::set(0x14047F290, 0xC3); // SV_SendMatchData H1MP64(1.4) + //utils::hook::set(0x140598990, 0xC3); // Live_CheckForFullDisconnect H1MP64(1.4) + +//#ifdef DEBUG +// // yes +// utils::hook::call(0x140727BEB, l); +// utils::hook::call(0x140727AFC, i); +// utils::hook::call(0x140727E49, h); +// utils::hook::call(0x140727E30, g); +// utils::hook::call(0x140727E37, f); +// utils::hook::call(0x140727DF2, e); +// utils::hook::call(0x140727DF9, d); +// utils::hook::call(0x140727CFC, c); +// utils::hook::call(0x140727C82, b); +// utils::hook::call(0x140727E6A, a); +//#endif // Checks X-Signature header or something - utils::hook::set(0x140728380, 0xC301B0); + //utils::hook::set(0x7D4AB0_b, 0xC301B0); // Checks extended_data and extra_data in json object - utils::hook::set(0x140728E90, 0xC301B0); + //utils::hook::set(0x7D55C0_b, 0xC301B0); // Update check - utils::hook::set(0x1403A5390, 0xC301B0); - + //utils::hook::set(0x1403A5390, 0xC301B0); + // Remove some while loop in demonware that freezes the rendering for a few secs at launch - utils::hook::nop(0x14057DBC5, 5); + //utils::hook::nop(0x14057DBC5, 5); + + MessageBoxA(0, "TEST", "", 0); + kekw_hook.create(0x7AC600_b, kekw_stub); + MessageBoxA(0, "TEST2", "", 0); } void pre_destroy() override @@ -601,4 +639,4 @@ namespace demonware }; } -//REGISTER_COMPONENT(demonware::component) +REGISTER_COMPONENT(demonware::component) diff --git a/src/client/game/demonware/data_types.hpp b/src/client/game/demonware/data_types.hpp index fb108190..579e2248 100644 --- a/src/client/game/demonware/data_types.hpp +++ b/src/client/game/demonware/data_types.hpp @@ -170,4 +170,41 @@ namespace demonware buffer->read_blob(&this->data); } }; + + class bdFile2 final : public bdTaskResult + { + public: + uint32_t unk1; + uint32_t unk2; + uint32_t unk3; + bool priv; + uint64_t owner_id; + std::string platform; + std::string filename; + std::string data; + + void serialize(byte_buffer* buffer) override + { + buffer->write_uint32(this->unk1); + buffer->write_uint32(this->unk2); + buffer->write_uint32(this->unk3); + buffer->write_bool(this->priv); + buffer->write_uint64(this->owner_id); + buffer->write_string(this->platform); + buffer->write_string(this->filename); + buffer->write_blob(this->data); + } + + void deserialize(byte_buffer* buffer) override + { + buffer->read_uint32(&this->unk1); + buffer->read_uint32(&this->unk2); + buffer->read_uint32(&this->unk3); + buffer->read_bool(&this->priv); + buffer->read_uint64(&this->owner_id); + buffer->read_string(&this->platform); + buffer->read_string(&this->filename); + buffer->read_blob(&this->data); + } + }; } diff --git a/src/client/game/demonware/services/bdStorage.cpp b/src/client/game/demonware/services/bdStorage.cpp index 2e7f026c..9f398868 100644 --- a/src/client/game/demonware/services/bdStorage.cpp +++ b/src/client/game/demonware/services/bdStorage.cpp @@ -172,15 +172,45 @@ namespace demonware const auto path = get_user_file_path(filename); utils::io::write_file(path, data); - auto* info = new bdFileInfo; + auto* info = new bdFile2; - info->file_id = *reinterpret_cast(utils::cryptography::sha1::compute(filename).data()); + // int + // int + // int + // byte (priv) + // int64 (owner) + // string (platform) + // string (file) + // blob + // size + // data + // int + // int + // int + // byte + // int64 + // string (platform) + // string (file) + // blob + // size + // data + + info->unk1 = 0; + info->unk2 = 0; + info->unk3 = 0; + info->priv = false; + info->owner_id = owner; + info->platform = platform; + info->filename = filename; + info->data = data; + + /*info->file_id = *reinterpret_cast(utils::cryptography::sha1::compute(filename).data()); info->filename = filename; info->create_time = uint32_t(time(nullptr)); info->modified_time = info->create_time; info->file_size = uint32_t(data.size()); info->owner_id = uint64_t(owner); - info->priv = priv; + info->priv = priv;*/ #ifdef DEBUG printf("[DW]: [bdStorage]: set user file: %s\n", filename.data()); @@ -213,6 +243,8 @@ namespace demonware auto reply = server->create_reply(this->task_id()); + printf("%i\n", numfiles); + for (uint32_t i = 0; i < numfiles; i++) { std::string filename, data; @@ -221,6 +253,9 @@ namespace demonware const auto path = get_user_file_path(filename); if (!utils::io::read_file(path, &data)) { +#ifdef DEBUG + printf("[DW]: [bdStorage]: get user file: missing file: %s, %s, %s\n", game.data(), filename.data(), platform.data()); +#endif continue; } From 4a8dcfaf9e8788bb25e97e5007154bac8eff6327 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 17 May 2022 13:03:29 -0500 Subject: [PATCH 182/346] Stuff Co-Authored-By: fed <58637860+fedddddd@users.noreply.github.com> --- src/client/component/console.cpp | 292 +++--------------- src/client/component/demonware.cpp | 115 ++++--- src/client/game/demonware/data_types.hpp | 37 +++ .../game/demonware/services/bdStorage.cpp | 41 ++- 4 files changed, 192 insertions(+), 293 deletions(-) diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 8b39323f..78ed8422 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -1,14 +1,10 @@ #include #include "console.hpp" #include "loader/component_loader.hpp" + #include "game/game.hpp" #include "command.hpp" -#include -#include -#include -#include - namespace game_console { void print(int type, const std::string& data); @@ -18,271 +14,50 @@ namespace console { namespace { - using message_queue = std::queue; - utils::concurrency::container messages; - - bool native_console() + DWORD WINAPI console(LPVOID) { - static const auto flag = utils::flags::has_flag("nativeconsole"); - return flag; - } + FreeConsole(); + AllocConsole(); + AttachConsole(GetCurrentProcessId()); - void hide_console() - { - auto* const con_window = GetConsoleWindow(); + (void)freopen("CONIN$", "r", stdin); + (void)freopen("CONOUT$", "w", stdout); - DWORD process; - GetWindowThreadProcessId(con_window, &process); - - if (!native_console() && (process == GetCurrentProcessId() || IsDebuggerPresent())) - { - ShowWindow(con_window, SW_HIDE); - } - } - - std::string format(va_list* ap, const char* message) - { - static thread_local char buffer[0x1000]; - - const auto count = _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), message, *ap); - - if (count < 0) return {}; - return {buffer, static_cast(count)}; - } - - void dispatch_message(const int type, const std::string& message) - { - if (native_console()) - { - printf("%s\n", message.data()); - return; - } - - game_console::print(type, message); - messages.access([&message](message_queue& msgs) - { - msgs.emplace(message); - }); - } - - void append_text(const char* text) - { - dispatch_message(con_type_info, text); - } - } - - class component final : public component_interface - { - public: - component() - { - hide_console(); - - if (native_console()) - { - setvbuf(stdout, nullptr, _IONBF, 0); - setvbuf(stderr, nullptr, _IONBF, 0); - } - else - { - (void)_pipe(this->handles_, 1024, _O_TEXT); - (void)_dup2(this->handles_[1], 1); - (void)_dup2(this->handles_[1], 2); - } - } - - void post_start() override - { - this->terminate_runner_ = false; - - this->console_runner_ = utils::thread::create_named_thread("Console IO", [this] - { - if (native_console()) - { - this->native_input(); - } - else - { - this->runner(); - } - }); - } - - void pre_destroy() override - { - this->terminate_runner_ = true; - - printf("\r\n"); - _flushall(); - - if (this->console_runner_.joinable()) - { - this->console_runner_.join(); - } - - if (this->console_thread_.joinable()) - { - this->console_thread_.join(); - } - -#ifndef NATIVE_CONSOLE - _close(this->handles_[0]); - _close(this->handles_[1]); -#endif - - messages.access([&](message_queue& msgs) - { - msgs = {}; - }); - } - - void post_unpack() override - { - // Redirect input (]command) - utils::hook::jump(SELECT_VALUE(0x1403E34C0, 0x1405141E0), append_text); // H1(1.4) - - this->initialize(); - } - - private: - volatile bool console_initialized_ = false; - volatile bool terminate_runner_ = false; - - std::thread console_runner_; - std::thread console_thread_; - - int handles_[2]{}; - - void initialize() - { - this->console_thread_ = utils::thread::create_named_thread("Console", [this]() - { - if (!native_console() && (game::environment::is_dedi() || !utils::flags::has_flag("noconsole"))) - { - game::Sys_ShowConsole(); - } - - if (!game::environment::is_dedi()) - { - // Hide that shit - ShowWindow(console::get_window(), SW_MINIMIZE); - } - - { - messages.access([&](message_queue&) - { - this->console_initialized_ = true; - }); - } - - MSG msg; - while (!this->terminate_runner_) - { - if (PeekMessageA(&msg, nullptr, NULL, NULL, PM_REMOVE)) - { - if (msg.message == WM_QUIT) - { - command::execute("quit", false); - break; - } - - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else - { - this->log_messages(); - std::this_thread::sleep_for(1ms); - } - } - }); - } - - void log_messages() - { - /*while*/ - if (this->console_initialized_ && !messages.get_raw().empty()) - { - std::queue message_queue_copy; - - { - messages.access([&](message_queue& msgs) - { - message_queue_copy = std::move(msgs); - msgs = {}; - }); - } - - while (!message_queue_copy.empty()) - { - log_message(message_queue_copy.front()); - message_queue_copy.pop(); - } - } - - fflush(stdout); - fflush(stderr); - } - - static void log_message(const std::string& message) - { - OutputDebugStringA(message.data()); - game::Conbuf_AppendText(message.data()); - } - - void runner() - { - char buffer[1024]; - - while (!this->terminate_runner_ && this->handles_[0]) - { - const auto len = _read(this->handles_[0], buffer, sizeof(buffer)); - if (len > 0) - { - dispatch_message(con_type_info, std::string(buffer, len)); - } - else - { - std::this_thread::sleep_for(1ms); - } - } - - std::this_thread::yield(); - } - - void native_input() - { std::string cmd; - while (!this->terminate_runner_) + while (true) { std::getline(std::cin, cmd); - command::execute(cmd); + } - std::this_thread::yield(); + return 0; } - }; - - HWND get_window() - { - return *reinterpret_cast((SELECT_VALUE(0x14CF56C00, 0x14DDFC2D0))); // H1(1.4) } - void set_title(std::string title) + std::string format(va_list* ap, const char* message) { - SetWindowText(get_window(), title.data()); + static thread_local char buffer[0x1000]; + + const auto count = _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), message, *ap); + + if (count < 0) return {}; + return { buffer, static_cast(count) }; } - void set_size(const int width, const int height) + void dispatch_message(const int type, const std::string& message) { - RECT rect; - GetWindowRect(get_window(), &rect); + //if (native_console()) + //{ + printf("%s\n", message.data()); + // return; + //} - SetWindowPos(get_window(), nullptr, rect.left, rect.top, width, height, 0); - - auto* const logo_window = *reinterpret_cast(SELECT_VALUE(0x14CF56C10, 0x14DDFC2E0)); // H1(1.4) - SetWindowPos(logo_window, nullptr, 5, 5, width - 25, 60, 0); + //game_console::print(type, message); + //messages.access([&message](message_queue& msgs) + // { + // msgs.emplace(message); + // }); } void print(const int type, const char* fmt, ...) @@ -294,6 +69,15 @@ namespace console dispatch_message(type, result); } + + class component final : public component_interface + { + public: + void post_start() override + { + CreateThread(0, 0, console, 0, 0, 0); + } + }; } -//REGISTER_COMPONENT(console::component) +REGISTER_COMPONENT(console::component) diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp index 5363cbd7..7c2b1460 100644 --- a/src/client/component/demonware.cpp +++ b/src/client/component/demonware.cpp @@ -297,7 +297,7 @@ namespace demonware if (server) { - server->handle_input(buf, len, {s, to, tolen}); + server->handle_input(buf, len, { s, to, tolen }); return len; } @@ -425,9 +425,9 @@ namespace demonware } } - void bd_logger_stub(char* a1, void* a2, void* a3, void* a4, const char* function, ...) + void bd_logger_stub() { - + //printf("logged\n"); } #ifdef DEBUG @@ -481,6 +481,32 @@ namespace demonware printf("bdAuth: Unknown error\n"); } #endif + + utils::hook::detour kekw_hook; + bool kekw_stub(__int64 a1, __int64 a2, __int64* a3) + { + // Checks X-Signature header or something + utils::hook::set(0x7D4AB0_b, 0xC301B0); + // Checks extended_data and extra_data in json object + utils::hook::set(0x7D55C0_b, 0xC301B0); + return kekw_hook.invoke(a1, a2, a3); + } + + void* allocate_somewhere_near(uint8_t* base_address) + { + const size_t PAGE_SIZE = 0x1000; + size_t offset = 0; + while (true) + { + offset += PAGE_SIZE; + auto res = VirtualAlloc(base_address - offset, PAGE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (res) + { + std::memset(res, 0, PAGE_SIZE); + return res; + } + } + } } class component final : public component_interface @@ -537,52 +563,69 @@ namespace demonware void post_unpack() override { - utils::hook::jump(SELECT_VALUE(0x140610320, 0x1407400B0), bd_logger_stub); + /* + mwr has upgraded some networking methods and the gethostbyname import from winsock library is no longer used + gethostbyname has been replaced with getaddrinfo + btw, still you can't get online.. + */ + //utils::hook::jump(SELECT_VALUE(0, 0x7EBC20_b), bd_logger_stub); if (game::environment::is_sp()) { - utils::hook::set(0x1405FCA00, 0xC3); // bdAuthSteam - utils::hook::set(0x140333A00, 0xC3); // dwNet + // utils::hook::set(0x1405FCA00, 0xC3); // bdAuthSteam H1(1.4) + // utils::hook::set(0x140333A00, 0xC3); // dwNet H1(1.4) return; } - utils::hook::set(0x140715039, 0x0); // CURLOPT_SSL_VERIFYPEER - utils::hook::set(0x140715025, 0xAF); // CURLOPT_SSL_VERIFYHOST - utils::hook::set(0x14095433C, 0x0); // HTTPS -> HTTP + utils::hook::set(0x7C0AD9_b, 0x0); // CURLOPT_SSL_VERIFYPEER H1MP64(1.15) + utils::hook::set(0x7C0AC5_b, 0xAF); // CURLOPT_SSL_VERIFYHOST H1MP64(1.15) + utils::hook::set(0xA1327C_b, 0x0); // HTTPS -> HTTP [MWR OK][S1X: 0x14088D0E8] //HTTPS -> HTTP - utils::hook::inject(0x14006DDA9, "http://prod.umbrella.demonware.net/v1.0/"); - utils::hook::inject(0x14006E11C, "http://prod.umbrella.demonware.net/v1.0/"); - utils::hook::inject(0x14006E2FB, "http://prod.umbrella.demonware.net/v1.0/"); - utils::hook::inject(0x14006E9A9, "http://prod.uno.demonware.net/v1.0/"); - utils::hook::inject(0x14006ED49, "http://prod.uno.demonware.net/v1.0/"); - utils::hook::inject(0x140728170, "http://%s:%d/auth/"); + char* umbrella = (char*)allocate_somewhere_near((uint8_t*)game::base_address); + std::memcpy(umbrella, "http://prod.umbrella.demonware.net/v1.0/", sizeof("http://prod.umbrella.demonware.net/v1.0/")); - utils::hook::set(0x14047F290, 0xC3); // SV_SendMatchData - utils::hook::set(0x140598990, 0xC3); // Live_CheckForFullDisconnect + utils::hook::inject(0x8615F_b, umbrella); + utils::hook::inject(0x8638C_b, umbrella); -#ifdef DEBUG - // yes - utils::hook::call(0x140727BEB, l); - utils::hook::call(0x140727AFC, i); - utils::hook::call(0x140727E49, h); - utils::hook::call(0x140727E30, g); - utils::hook::call(0x140727E37, f); - utils::hook::call(0x140727DF2, e); - utils::hook::call(0x140727DF9, d); - utils::hook::call(0x140727CFC, c); - utils::hook::call(0x140727C82, b); - utils::hook::call(0x140727E6A, a); -#endif + char* uno = (char*)allocate_somewhere_near((uint8_t*)game::base_address); + std::memcpy(uno, "http://prod.uno.demonware.net/v1.0/", sizeof("http://prod.uno.demonware.net/v1.0/")); + + utils::hook::inject(0x86C56_b, uno); + utils::hook::inject(0x86F96_b, uno); + + BYTE bytes[] = { 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x25, 0x73, 0x3A, 0x25, 0x64, 0x2F, 0x61, 0x75, 0x74, 0x68, 0x2F, 0x0 }; // KEKW + std::memcpy((void*)0x9EDB08_b, bytes, sizeof(bytes)); //utils::hook::inject(0x140728170, "http://%s:%d/auth/"); :DDD + + //utils::hook::set(0x14047F290, 0xC3); // SV_SendMatchData H1MP64(1.4) + //utils::hook::set(0x140598990, 0xC3); // Live_CheckForFullDisconnect H1MP64(1.4) + +//#ifdef DEBUG +// // yes +// utils::hook::call(0x140727BEB, l); +// utils::hook::call(0x140727AFC, i); +// utils::hook::call(0x140727E49, h); +// utils::hook::call(0x140727E30, g); +// utils::hook::call(0x140727E37, f); +// utils::hook::call(0x140727DF2, e); +// utils::hook::call(0x140727DF9, d); +// utils::hook::call(0x140727CFC, c); +// utils::hook::call(0x140727C82, b); +// utils::hook::call(0x140727E6A, a); +//#endif // Checks X-Signature header or something - utils::hook::set(0x140728380, 0xC301B0); + //utils::hook::set(0x7D4AB0_b, 0xC301B0); // Checks extended_data and extra_data in json object - utils::hook::set(0x140728E90, 0xC301B0); + //utils::hook::set(0x7D55C0_b, 0xC301B0); // Update check - utils::hook::set(0x1403A5390, 0xC301B0); - + //utils::hook::set(0x1403A5390, 0xC301B0); + // Remove some while loop in demonware that freezes the rendering for a few secs at launch - utils::hook::nop(0x14057DBC5, 5); + //utils::hook::nop(0x14057DBC5, 5); + + MessageBoxA(0, "TEST", "", 0); + kekw_hook.create(0x7AC600_b, kekw_stub); + MessageBoxA(0, "TEST2", "", 0); } void pre_destroy() override @@ -596,4 +639,4 @@ namespace demonware }; } -//REGISTER_COMPONENT(demonware::component) +REGISTER_COMPONENT(demonware::component) diff --git a/src/client/game/demonware/data_types.hpp b/src/client/game/demonware/data_types.hpp index fb108190..579e2248 100644 --- a/src/client/game/demonware/data_types.hpp +++ b/src/client/game/demonware/data_types.hpp @@ -170,4 +170,41 @@ namespace demonware buffer->read_blob(&this->data); } }; + + class bdFile2 final : public bdTaskResult + { + public: + uint32_t unk1; + uint32_t unk2; + uint32_t unk3; + bool priv; + uint64_t owner_id; + std::string platform; + std::string filename; + std::string data; + + void serialize(byte_buffer* buffer) override + { + buffer->write_uint32(this->unk1); + buffer->write_uint32(this->unk2); + buffer->write_uint32(this->unk3); + buffer->write_bool(this->priv); + buffer->write_uint64(this->owner_id); + buffer->write_string(this->platform); + buffer->write_string(this->filename); + buffer->write_blob(this->data); + } + + void deserialize(byte_buffer* buffer) override + { + buffer->read_uint32(&this->unk1); + buffer->read_uint32(&this->unk2); + buffer->read_uint32(&this->unk3); + buffer->read_bool(&this->priv); + buffer->read_uint64(&this->owner_id); + buffer->read_string(&this->platform); + buffer->read_string(&this->filename); + buffer->read_blob(&this->data); + } + }; } diff --git a/src/client/game/demonware/services/bdStorage.cpp b/src/client/game/demonware/services/bdStorage.cpp index 2e7f026c..9f398868 100644 --- a/src/client/game/demonware/services/bdStorage.cpp +++ b/src/client/game/demonware/services/bdStorage.cpp @@ -172,15 +172,45 @@ namespace demonware const auto path = get_user_file_path(filename); utils::io::write_file(path, data); - auto* info = new bdFileInfo; + auto* info = new bdFile2; - info->file_id = *reinterpret_cast(utils::cryptography::sha1::compute(filename).data()); + // int + // int + // int + // byte (priv) + // int64 (owner) + // string (platform) + // string (file) + // blob + // size + // data + // int + // int + // int + // byte + // int64 + // string (platform) + // string (file) + // blob + // size + // data + + info->unk1 = 0; + info->unk2 = 0; + info->unk3 = 0; + info->priv = false; + info->owner_id = owner; + info->platform = platform; + info->filename = filename; + info->data = data; + + /*info->file_id = *reinterpret_cast(utils::cryptography::sha1::compute(filename).data()); info->filename = filename; info->create_time = uint32_t(time(nullptr)); info->modified_time = info->create_time; info->file_size = uint32_t(data.size()); info->owner_id = uint64_t(owner); - info->priv = priv; + info->priv = priv;*/ #ifdef DEBUG printf("[DW]: [bdStorage]: set user file: %s\n", filename.data()); @@ -213,6 +243,8 @@ namespace demonware auto reply = server->create_reply(this->task_id()); + printf("%i\n", numfiles); + for (uint32_t i = 0; i < numfiles; i++) { std::string filename, data; @@ -221,6 +253,9 @@ namespace demonware const auto path = get_user_file_path(filename); if (!utils::io::read_file(path, &data)) { +#ifdef DEBUG + printf("[DW]: [bdStorage]: get user file: missing file: %s, %s, %s\n", game.data(), filename.data(), platform.data()); +#endif continue; } From 7f1d5e9b2072044bb85272e413e38c2e06f9ee81 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Tue, 17 May 2022 22:56:11 +0300 Subject: [PATCH 183/346] some stuff --- src/client/component/branding.cpp | 4 +- src/client/component/colors.cpp | 18 ++--- src/client/component/console.cpp | 5 -- src/client/component/input.cpp | 6 +- src/client/component/localized_strings.cpp | 2 +- src/client/component/network.cpp | 81 +++++++++++----------- src/client/component/ui_scripting.cpp | 18 ++--- src/client/game/symbols.hpp | 74 ++++++++++---------- 8 files changed, 101 insertions(+), 107 deletions(-) diff --git a/src/client/component/branding.cpp b/src/client/component/branding.cpp index fd7e84e8..58765332 100644 --- a/src/client/component/branding.cpp +++ b/src/client/component/branding.cpp @@ -41,8 +41,8 @@ namespace branding if (game::environment::is_mp()) { - //localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n"); - //localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER"); + localized_strings::override("LUA_MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER\n"); + localized_strings::override("MENU_MULTIPLAYER_CAPS", "H1-MOD: MULTIPLAYER"); } //dvars::override::set_string("version", utils::string::va("H1-Mod %s", VERSION)); diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp index aa2631cb..ec563b89 100644 --- a/src/client/component/colors.cpp +++ b/src/client/component/colors.cpp @@ -96,7 +96,7 @@ namespace colors const size_t unk, const size_t unk2) { // CL_GetClientName (CL_GetClientNameAndClantag?) - const auto result = utils::hook::invoke(0x14025BAA0, local_client_num, index, buf, size, unk, unk2); + const auto result = utils::hook::invoke(0x343BA0_b, local_client_num, index, buf, size, unk, unk2); utils::string::strip(buf, buf, size); @@ -109,11 +109,11 @@ namespace colors if (index == '8') { - *color = *reinterpret_cast(SELECT_VALUE(0x14F142FF8, 0x14FE70634)); // H1(1.4) + *color = *reinterpret_cast(SELECT_VALUE(0x0, 0xEA749B4_b)); // 1.15 } else if (index == '9') { - *color = *reinterpret_cast(SELECT_VALUE(0x14F142FFC, 0x14FE70638)); // H1(1.4) + *color = *reinterpret_cast(SELECT_VALUE(0x0, 0xEA749B8_b)); // 1.15 } else if (index == ':') { @@ -121,7 +121,7 @@ namespace colors } else if (index == ';') { - *color = *reinterpret_cast(SELECT_VALUE(0x14F143004, 0x14FE70640)); // H1(1.4) + *color = *reinterpret_cast(SELECT_VALUE(0x0, 0xEA749C0_b)); // 1.15 } else if (index == '<') { @@ -147,17 +147,17 @@ namespace colors if (!game::environment::is_sp()) { // allows colored name in-game - utils::hook::jump(0x140503810, com_clean_name_stub); // H1(1.4) + utils::hook::jump(0x5AEDF0_b, com_clean_name_stub); // 1.15 // don't apply colors to overhead names - utils::hook::call(0x1400AB416, get_client_name_stub); // H1(1.4) + utils::hook::call(0xF7B85_b, get_client_name_stub); // 1.15 // patch I_CleanStr - utils::hook::jump(0x140503D00, i_clean_str_stub); // H1(1.4) + utils::hook::jump(0x5AF2E0_b, i_clean_str_stub); // 1.15 } // force new colors - utils::hook::jump(SELECT_VALUE(0x140524BD0, 0x1406206A0), rb_lookup_color_stub); // H1(1.4) + utils::hook::jump(SELECT_VALUE(0x0, 0x6C9460_b), rb_lookup_color_stub); // 1.15 // add colors add(0, 0, 0); // 0 - Black @@ -179,4 +179,4 @@ namespace colors }; } -//REGISTER_COMPONENT(colors::component) +REGISTER_COMPONENT(colors::component) diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 78ed8422..39f3f9dd 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -28,7 +28,6 @@ namespace console while (true) { std::getline(std::cin, cmd); - } return 0; @@ -47,11 +46,7 @@ namespace console void dispatch_message(const int type, const std::string& message) { - //if (native_console()) - //{ printf("%s\n", message.data()); - // return; - //} //game_console::print(type, message); //messages.access([&message](message_queue& msgs) diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index ea2fa309..023a317b 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -66,10 +66,10 @@ namespace input return; } - cl_char_event_hook.create(SELECT_VALUE(0x1401871A0, 0x14024E810), cl_char_event_stub); - cl_key_event_hook.create(SELECT_VALUE(0x1401874D0, 0x14024EA60), cl_key_event_stub); + cl_char_event_hook.create(SELECT_VALUE(0x0, 0x12C8F0_b), cl_char_event_stub); + cl_key_event_hook.create(SELECT_VALUE(0x0, 0x135A70_b), cl_key_event_stub); } }; } -//REGISTER_COMPONENT(input::component) +REGISTER_COMPONENT(input::component) diff --git a/src/client/component/localized_strings.cpp b/src/client/component/localized_strings.cpp index cd9d4718..e66fc692 100644 --- a/src/client/component/localized_strings.cpp +++ b/src/client/component/localized_strings.cpp @@ -49,4 +49,4 @@ namespace localized_strings }; } -//REGISTER_COMPONENT(localized_strings::component) +REGISTER_COMPONENT(localized_strings::component) diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index d1212d81..88d5ccb7 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -60,11 +60,11 @@ namespace network // Command handled a.popad64(); a.mov(al, 1); - a.jmp(0x140252AF8); + a.jmp(0x12FCAA_b); a.bind(return_unhandled); a.popad64(); - a.jmp(0x14025234C); + a.jmp(0x12F3AC_b); } int net_compare_base_address(const game::netadr_s* a1, const game::netadr_s* a2) @@ -110,7 +110,7 @@ namespace network if (net_interface && net_interface != "localhost"s) { // Sys_StringToSockaddr - utils::hook::invoke(0x1404F6580, net_interface, &address); + utils::hook::invoke(0x59E810_b, net_interface, &address); } address.sin_family = AF_INET; @@ -229,53 +229,52 @@ namespace network } // redirect dw_sendto to raw socket - //utils::hook::jump(0x1404D850A, reinterpret_cast(0x1404D849A)); - utils::hook::call(0x140513467, dw_send_to_stub); + utils::hook::call(0x5BDB47_b, dw_send_to_stub); utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub); // intercept command handling - utils::hook::jump(0x140252327, utils::hook::assemble(handle_command_stub), true); + utils::hook::jump(0x12F387_b, utils::hook::assemble(handle_command_stub), true); // handle xuid without secure connection - utils::hook::nop(0x140486AAF, 6); + utils::hook::nop(0x554222_b, 6); - utils::hook::jump(0x140424F20, net_compare_address); - utils::hook::jump(0x140424F70, net_compare_base_address); + utils::hook::jump(0x4F1800_b, net_compare_address); + utils::hook::jump(0x4F1850_b, net_compare_base_address); // don't establish secure conenction - utils::hook::set(0x14027EA4D, 0xEB); - utils::hook::set(0x14027EB1E, 0xEB); - utils::hook::set(0x14027EF8D, 0xEB); - utils::hook::set(0x14025081F, 0xEB); + utils::hook::set(0x358C8D_b, 0xEB); + utils::hook::set(0x358D5E_b, 0xEB); + utils::hook::set(0x3591CD_b, 0xEB); + utils::hook::set(0x12CD0F_b, 0xEB); // ignore unregistered connection - utils::hook::jump(0x140480F46, 0x140480EE5); - utils::hook::set(0x140480F3B, 0xEB); + utils::hook::jump(0x54E2D1_b, 0x54E270_b); + utils::hook::set(0x54E2C6_b, 0xEB); // disable xuid verification - utils::hook::set(0x14005B62D, 0xEB); - utils::hook::set(0x14005B649, 0xEB); + utils::hook::set(0x728BF_b, 0xEB); + //utils::hook::set(0x14005B649, 0xEB); // not found // disable xuid verification - utils::hook::nop(0x14048382C, 2); - utils::hook::set(0x140483889, 0xEB); + utils::hook::nop(0x5509D9_b, 2); + utils::hook::set(0x550A36_b, 0xEB); // ignore configstring mismatch - utils::hook::set(0x1402591C9, 0xEB); + //utils::hook::set(0x1402591C9, 0xEB); // not found // ignore dw handle in SV_PacketEvent - utils::hook::set(0x1404898E2, 0xEB); - utils::hook::call(0x1404898D6, &net_compare_address); + utils::hook::set(0x1CBC22_b, 0xEB); + utils::hook::call(0x1CBC16_b, &net_compare_address); // ignore dw handle in SV_FindClientByAddress - utils::hook::set(0x140488EFD, 0xEB); - utils::hook::call(0x140488EF1, &net_compare_address); + utils::hook::set(0x1CB24D_b, 0xEB); + utils::hook::call(0x1CB241_b, &net_compare_address); // ignore dw handle in SV_DirectConnect - utils::hook::set(0x140480C58, 0xEB); - utils::hook::set(0x140480E6F, 0xEB); - utils::hook::call(0x140480C4B, &net_compare_address); - utils::hook::call(0x140480E62, &net_compare_address); + utils::hook::set(0x54DFE8_b, 0xEB); + utils::hook::set(0x54E1FD_b, 0xEB); + utils::hook::call(0x54DFDB_b, &net_compare_address); + utils::hook::call(0x54E1F0_b, &net_compare_address); // increase cl_maxpackets dvars::override::register_int("cl_maxpackets", 1000, 1, 1000, game::DVAR_FLAG_SAVED); @@ -284,31 +283,31 @@ namespace network dvars::override::register_int("sv_remote_client_snapshot_msec", 33, 33, 100, game::DVAR_FLAG_NONE); // ignore impure client - utils::hook::jump(0x140481B58, 0x140481BEE); + utils::hook::jump(0x54EDD3_b, 0x54EE69_b); // don't send checksum - utils::hook::set(0x1404F6398, 0); + utils::hook::set(0x59E628_b, 0); // don't read checksum - utils::hook::set(0x1404F6620, 0xC301B0); + utils::hook::set(0x59E8B0_b, 0xC301B0); // don't try to reconnect client - utils::hook::call(0x140480DFF, reconnect_migratated_client); - utils::hook::nop(0x140480DDB, 4); // this crashes when reconnecting for some reason + utils::hook::call(0x54E18C_b, reconnect_migratated_client); + utils::hook::nop(0x54E168_b, 4); // this crashes when reconnecting for some reason // allow server owner to modify net_port before the socket bind - utils::hook::call(0x140512BE5, register_netport_stub); - utils::hook::call(0x140512D20, register_netport_stub); + utils::hook::call(0x5BD2B5_b, register_netport_stub); + utils::hook::call(0x5BD3F0_b, register_netport_stub); // increase allowed packet size const auto max_packet_size = 0x20000; - utils::hook::set(0x1404255F1, max_packet_size); - utils::hook::set(0x140425630, max_packet_size); - utils::hook::set(0x140425522, max_packet_size); - utils::hook::set(0x140425545, max_packet_size); + utils::hook::set(0x4F1ED1_b, max_packet_size); + utils::hook::set(0x4F1F10_b, max_packet_size); + utils::hook::set(0x4F1E02_b, max_packet_size); + utils::hook::set(0x4F1E25_b, max_packet_size); // ignore built in "print" oob command and add in our own - utils::hook::set(0x14025280E, 0xEB); + utils::hook::set(0x12F817_b, 0xEB); on("print", [](const game::netadr_s&, const std::string_view& data) { const std::string message{data}; @@ -317,7 +316,7 @@ namespace network // Use our own socket since the game's socket doesn't work with non localhost addresses // why? no idea - utils::hook::jump(0x140512B40, create_socket); + utils::hook::jump(0x5BD210_b, create_socket); } } }; diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index f4dffb32..46bf5332 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -185,22 +185,22 @@ namespace ui_scripting scheduler::loop(ui_scripting::lua::engine::run_frame, scheduler::pipeline::lui); - hks_start_hook.create(SELECT_VALUE(0x1400E4B40, 0x140176A40), hks_start_stub); - hks_shutdown_hook.create(SELECT_VALUE(0x1400DD3D0, 0x14016CA80), hks_shutdown_stub); - hksi_lual_error_hook.create(SELECT_VALUE(0x1400A5EA0, 0x14012F300), hksi_lual_error_stub); - hks_allocator_hook.create(SELECT_VALUE(0x14009B570, 0x14012BAC0), hks_allocator_stub); - lui_error_hook.create(SELECT_VALUE(0x14007D7D0, 0x14010C9E0), lui_error_stub); - hksi_hks_error_hook.create(SELECT_VALUE(0x14009DD80, 0x14012E390), hksi_hks_error_stub); + hks_start_hook.create(SELECT_VALUE(0x0, 0x27A790_b), hks_start_stub); // 1.15 + hks_shutdown_hook.create(SELECT_VALUE(0x0, 0x2707C0_b), hks_shutdown_stub); // 1.15 + hksi_lual_error_hook.create(SELECT_VALUE(0x0, 0x22F930_b), hksi_lual_error_stub); // 1.15 + hks_allocator_hook.create(SELECT_VALUE(0x0, 0x22C010_b), hks_allocator_stub); // 1.15 + lui_error_hook.create(SELECT_VALUE(0x0, 0x20BA80_b), lui_error_stub); // 1.15 + hksi_hks_error_hook.create(SELECT_VALUE(0x0, 0x22EA10_b), hksi_hks_error_stub); // 1.15 if (game::environment::is_mp()) { - hksi_lual_error_hook2.create(0x1401366B0, hksi_lual_error_stub); + hksi_lual_error_hook2.create(0x2365E0_b, hksi_lual_error_stub); // 1.15 } command::add("lui_restart", []() { - utils::hook::invoke(SELECT_VALUE(0x1400DD3D0, 0x14016CA80)); - utils::hook::invoke(SELECT_VALUE(0x1400E6170, 0x1401780D0)); + utils::hook::invoke(SELECT_VALUE(0x0, 0x2707C0_b)); // 1.15 + utils::hook::invoke(SELECT_VALUE(0x0, 0x27BEC0_b)); // 1.15 }); } }; diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 83ba3e8d..75bd2671 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -8,66 +8,66 @@ namespace game * Functions **************************************************************/ - WEAK symbol AddRefToValue{0x0, 0x0}; - WEAK symbol RemoveRefToValue{0x0, 0x0}; - WEAK symbol AddRefToObject{0x0, 0x0}; - WEAK symbol RemoveRefToObject{0x0, 0x0}; - WEAK symbol AllocThread{0x0, 0x0}; + WEAK symbol AddRefToValue{0x0, 0x5090E0}; + WEAK symbol RemoveRefToValue{0x0, 0x50ABF0}; + WEAK symbol AddRefToObject{0x0, 0x5090D0}; + WEAK symbol RemoveRefToObject{0x0, 0x50AAE0}; + WEAK symbol AllocThread{0x0, 0x509440}; WEAK symbol AllocVariable{0x0, 0x0}; - WEAK symbol Cbuf_AddText{0x0, 0x1CF480}; // 1.15 + WEAK symbol Cbuf_AddText{0x0, 0x1CF480}; WEAK symbol Cbuf_ExecuteBufferInternal{0x0, 0x0}; + void (int, int, const char*))> Cbuf_ExecuteBufferInternal{0x0, 0x155BC0}; WEAK symbol Conbuf_AppendText{0x0, 0x0}; - WEAK symbol ConcatArgs{0x0, 0x0}; + WEAK symbol ConcatArgs{0x0, 0x413050}; WEAK symbol Cmd_ExecuteSingleCommand{0x0, 0x0}; - WEAK symbol Cmd_AddCommandInternal{0x0, 0x0}; - WEAK symbol Cmd_RemoveCommand{0x0, 0x0}; + WEAK symbol Cmd_AddCommandInternal{0x0, 0x156880}; + WEAK symbol Cmd_RemoveCommand{0x0, 0x157690}; WEAK symbol Cmd_TokenizeString{0x0, 0x0}; WEAK symbol Cmd_EndTokenizeString{0x0, 0x0}; - WEAK symbol AimAssist_AddToTargetList{0x0, 0x0}; + WEAK symbol AimAssist_AddToTargetList{0x0, 0xE66C0}; WEAK symbol BG_GetWeaponNameComplete{0x0, 0x0}; + char* output, unsigned int maxStringLen)> BG_GetWeaponNameComplete{0x0, 0x2E2500}; WEAK symbol Com_Frame_Try_Block_Function{0x0, 0x0}; - WEAK symbol Com_GetCurrentCoDPlayMode{0x0, 0x0}; - WEAK symbol Com_InFrontend{0x0, 0x0}; - WEAK symbol Com_SetSlowMotion{0x0, 0x0}; + WEAK symbol Com_GetCurrentCoDPlayMode{0x0, 0x5AEF80}; + WEAK symbol Com_InFrontend{0x0, 0x76A40}; + WEAK symbol Com_SetSlowMotion{0x0, 0x17E5F0}; WEAK symbol Com_Error{0x0, 0x0}; - WEAK symbol Com_Quit_f{0x0, 0x0}; + WEAK symbol Com_Quit_f{0x0, 0x1F9280}; WEAK symbol Com_Shutdown{0x0, 0x0}; - WEAK symbol Quit{0x0, 0x0}; + WEAK symbol Quit{0x0, 0x1F9280}; - WEAK symbol CG_GameMessage{0x0, 0x0}; - WEAK symbol CG_GameMessageBold{0x0, 0x0}; + WEAK symbol CG_GameMessage{0x0, 0x316210}; + WEAK symbol CG_GameMessageBold{0x0, 0x3122F0}; WEAK symbol CG_SetClientDvarFromServer{0x0, 0x0}; WEAK symbol CG_GetWeaponDisplayName{0x0, 0x0}; - WEAK symbol CL_IsCgameInitialized{0x0, 0x0}; + WEAK symbol CL_IsCgameInitialized{0x0, 0x76A40}; WEAK symbol CL_VirtualLobbyShutdown{0x0, 0x0}; - WEAK symbol Dvar_SetCommand{0x0, 0x0}; - WEAK symbol Dvar_FindVar{0x0, 0x0}; + WEAK symbol Dvar_SetCommand{0x0, 0x1857D0}; + WEAK symbol Dvar_FindVar{0x0, 0x183EB0}; WEAK symbol Dvar_ClearModified{0x0, 0x0}; - WEAK symbol Dvar_GetCombinedString{0x0, 0x0}; + WEAK symbol Dvar_GetCombinedString{0x0, 0x4EA020}; WEAK symbol Dvar_ValueToString{0x0, 0x0}; - WEAK symbol Dvar_Reset{0x0, 0x0}; + WEAK symbol Dvar_Reset{0x0, 0x185390}; WEAK symbol Dvar_SetFromStringByNameFromSource{0x0, 0x0}; + DvarSetSource)> Dvar_SetFromStringByNameFromSource{0x0, 0x185BD0}; WEAK symbol Dvar_RegisterBool{0x0, 0x0}; + unsigned int flags)> Dvar_RegisterBool{0x0, 0x182340}; WEAK symbol Dvar_RegisterInt{0x0, 0x0}; + unsigned int flags)> Dvar_RegisterInt{0x0, 0x182A10}; WEAK symbol Dvar_RegisterFloat{0x0, 0x0}; + float max, unsigned int flags)> Dvar_RegisterFloat{0x0, 0x182900}; WEAK symbol Dvar_RegisterString{0x0, 0x0}; + unsigned int flags)> Dvar_RegisterString{0x0, 0x182AF0}; WEAK symbol Dvar_RegisterVec4{0x0, 0x0}; @@ -103,7 +103,7 @@ namespace game WEAK symbol Live_SyncOnlineDataFlags{0x0, 0x0}; - WEAK symbol Material_RegisterHandle{0x0, 0x0}; + WEAK symbol Material_RegisterHandle{0x0, 0x692360}; WEAK symbol NetadrToSockadr{0x0, 0x0}; WEAK symbol NET_OutOfBandPrint{0x0, 0x0}; @@ -112,15 +112,15 @@ namespace game WEAK symbol R_AddCmdDrawStretchPic{0x0, 0x0}; - WEAK symbol R_RegisterFont{0x0, 0x67F630}; // 1.15 + WEAK symbol R_RegisterFont{0x0, 0x67F630}; WEAK symbol R_TextWidth{0x0, 0x0}; - WEAK symbol R_GetFontHeight{0x0, 0x67F710}; // 1.15 - WEAK symbol R_DrawSomething{0x0, 0x67ECE0}; // 1.15 + WEAK symbol R_GetFontHeight{0x0, 0x67F710}; + WEAK symbol R_DrawSomething{0x0, 0x67ECE0}; WEAK symbol R_SyncRenderThread{0x0, 0x0}; WEAK symbol H1_AddBaseDrawTextCmd{0x0, 0x6A3080}; // 1.15 + void* style_unk)> H1_AddBaseDrawTextCmd{0x0, 0x6A3080}; #define R_AddCmdDrawText(TXT, MC, F, X, Y, XS, YS, R, C, S) \ H1_AddBaseDrawTextCmd(TXT, MC, F, game::R_GetFontHeight(F), X, Y, XS, YS, R, C, S,-1, 0, game::R_DrawSomething(S)) @@ -220,7 +220,7 @@ namespace game WEAK symbol gameEntityId{0x0, 0x0}; WEAK symbol command_whitelist{0x0, 0x0}; - WEAK symbol cmd_functions{0x0, 0x344DF18}; // 1.15 + WEAK symbol cmd_functions{0x0, 0x344DF18}; WEAK symbol cmd_args{0x0, 0x0}; WEAK symbol g_poolSize{0x0, 0x0}; @@ -238,7 +238,7 @@ namespace game WEAK symbol DB_XAssetPool{0x0, 0x0}; WEAK symbol g_assetNames{0x0, 0x0}; - WEAK symbol keyCatchers{0x0, 0x0}; + WEAK symbol keyCatchers{0x0, 0x2EC82C4}; WEAK symbol playerKeys{0x0, 0x0}; WEAK symbol query_socket{0x0, 0x0}; @@ -247,7 +247,7 @@ namespace game namespace mp { - WEAK symbol g_entities{0x0, 0x71F19E0}; // 1.15 + WEAK symbol g_entities{0x0, 0x71F19E0}; WEAK symbol svs_clients{0x0, 0x0}; WEAK symbol svs_numclients{0x0, 0x0}; WEAK symbol gameTime{0x0, 0x0}; From 2678d41c535f4af7edd72ce03d4df43a7a031638 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 18 May 2022 01:56:15 +0200 Subject: [PATCH 184/346] Fixes + some cleanup --- src/client/component/auth.cpp | 35 +++++++------ src/client/component/demonware.cpp | 50 ++++++++----------- .../game/demonware/services/bdStorage.cpp | 31 ------------ .../game/demonware/services/bdUNK80.cpp | 3 +- 4 files changed, 42 insertions(+), 77 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index a2842e63..f633f740 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -213,33 +213,36 @@ namespace auth // Patch steam id bit check if (game::environment::is_sp()) { - utils::hook::jump(0x140475C17, 0x140475C6A); // H1(1.4) - utils::hook::jump(0x140476AFF, 0x140476B40); // H1(1.4) - utils::hook::jump(0x140476FA4, 0x140476FF2); // H1(1.4) + //utils::hook::jump(0x140475C17, 0x140475C6A); // H1(1.4) + //utils::hook::jump(0x140476AFF, 0x140476B40); // H1(1.4) + //utils::hook::jump(0x140476FA4, 0x140476FF2); // H1(1.4) } else { - utils::hook::jump(0x1D6193_b, 0x1D61FA_b); // STEAM - utils::hook::jump(0x60153_b, 0x60426_b); // STEAM - utils::hook::jump(0x603E1_b, 0x60426_b); // STEAM - utils::hook::jump(0x1D7542_b, 0x1D7587_b); // STEAM MAYBE `1401D7553` ON FIRST - utils::hook::jump(0x1D7A82_b, 0x1D7AC8_b); // STEAM + // kill "disconnected from steam" error + utils::hook::nop(0x1D61DF_b, 0x11); + + /*utils::hook::nop(0x1D6193_b, 103); // STEAM + utils::hook::nop(0x60153_b, 0x60426 - 0x60153); // STEAM + utils::hook::nop(0x603E1_b, 0x60426 - 0x603E1); // STEAM + utils::hook::nop(0x1D7553_b, 0x1D7587 - 0x1D7553); // STEAM MAYBE `1401D7553` ON FIRST + utils::hook::nop(0x1D7A82_b, 0x1D7AC8 - 0x1D7A82); // STEAM*/ //utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) can't find - utils::hook::call(0x12D437_b, send_connect_data_stub); // H1(1.4) + //utils::hook::call(0x12D437_b, send_connect_data_stub); // H1(1.4) // Skip checks for sending connect packet - utils::hook::jump(0x1402508FC, 0x140250946); + //utils::hook::jump(0x1402508FC, 0x140250946); // Don't instantly timeout the connecting client ? not sure about this - utils::hook::set(0x14025136B, 0xC3); + //utils::hook::set(0x14025136B, 0xC3); } - command::add("guid", []() - { - printf("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits); - }); + //command::add("guid", []() + //{ + // printf("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits); + //}); } }; } -//REGISTER_COMPONENT(auth::component) +REGISTER_COMPONENT(auth::component) diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp index 7c2b1460..fd5afcae 100644 --- a/src/client/component/demonware.cpp +++ b/src/client/component/demonware.cpp @@ -482,14 +482,15 @@ namespace demonware } #endif - utils::hook::detour kekw_hook; - bool kekw_stub(__int64 a1, __int64 a2, __int64* a3) + utils::hook::detour handle_auth_reply_hook; + bool handle_auth_reply_stub(void* a1, void* a2, void* a3) { - // Checks X-Signature header or something + // Skip bdAuth::validateResponseSignature utils::hook::set(0x7D4AB0_b, 0xC301B0); - // Checks extended_data and extra_data in json object + // Skip bdAuth::processPlatformData utils::hook::set(0x7D55C0_b, 0xC301B0); - return kekw_hook.invoke(a1, a2, a3); + + return handle_auth_reply_hook.invoke(a1, a2, a3); } void* allocate_somewhere_near(uint8_t* base_address) @@ -563,13 +564,6 @@ namespace demonware void post_unpack() override { - /* - mwr has upgraded some networking methods and the gethostbyname import from winsock library is no longer used - gethostbyname has been replaced with getaddrinfo - btw, still you can't get online.. - */ - //utils::hook::jump(SELECT_VALUE(0, 0x7EBC20_b), bd_logger_stub); - if (game::environment::is_sp()) { // utils::hook::set(0x1405FCA00, 0xC3); // bdAuthSteam H1(1.4) @@ -577,11 +571,11 @@ namespace demonware return; } - utils::hook::set(0x7C0AD9_b, 0x0); // CURLOPT_SSL_VERIFYPEER H1MP64(1.15) - utils::hook::set(0x7C0AC5_b, 0xAF); // CURLOPT_SSL_VERIFYHOST H1MP64(1.15) - utils::hook::set(0xA1327C_b, 0x0); // HTTPS -> HTTP [MWR OK][S1X: 0x14088D0E8] + utils::hook::set(0x7C0AD9_b, 0x0); // CURLOPT_SSL_VERIFYPEER + utils::hook::set(0x7C0AC5_b, 0xAF); // CURLOPT_SSL_VERIFYHOST + utils::hook::set(0xA1327C_b, 0x0); // HTTPS -> HTTP - //HTTPS -> HTTP + // HTTPS -> HTTP char* umbrella = (char*)allocate_somewhere_near((uint8_t*)game::base_address); std::memcpy(umbrella, "http://prod.umbrella.demonware.net/v1.0/", sizeof("http://prod.umbrella.demonware.net/v1.0/")); @@ -597,8 +591,10 @@ namespace demonware BYTE bytes[] = { 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x25, 0x73, 0x3A, 0x25, 0x64, 0x2F, 0x61, 0x75, 0x74, 0x68, 0x2F, 0x0 }; // KEKW std::memcpy((void*)0x9EDB08_b, bytes, sizeof(bytes)); //utils::hook::inject(0x140728170, "http://%s:%d/auth/"); :DDD - //utils::hook::set(0x14047F290, 0xC3); // SV_SendMatchData H1MP64(1.4) - //utils::hook::set(0x140598990, 0xC3); // Live_CheckForFullDisconnect H1MP64(1.4) + // utils::hook::set(0x4DCCE0_b, 0xC301B0); + + // utils::hook::set(0x19F8C0_b, 0xC3); SV_SendMatchData, not sure + utils::hook::set(0x1A3340_b, 0xC3); // Live_CheckForFullDisconnect //#ifdef DEBUG // // yes @@ -613,19 +609,15 @@ namespace demonware // utils::hook::call(0x140727C82, b); // utils::hook::call(0x140727E6A, a); //#endif - // Checks X-Signature header or something - //utils::hook::set(0x7D4AB0_b, 0xC301B0); - // Checks extended_data and extra_data in json object - //utils::hook::set(0x7D55C0_b, 0xC301B0); - // Update check - //utils::hook::set(0x1403A5390, 0xC301B0); + // Remove some while loop that freezes the rendering for a few secs while connecting + utils::hook::nop(0x625555_b, 5); - // Remove some while loop in demonware that freezes the rendering for a few secs at launch - //utils::hook::nop(0x14057DBC5, 5); + handle_auth_reply_hook.create(0x7AC600_b, handle_auth_reply_stub); - MessageBoxA(0, "TEST", "", 0); - kekw_hook.create(0x7AC600_b, kekw_stub); - MessageBoxA(0, "TEST2", "", 0); + // Skip update check in Live_SyncOnlineDataFlags + utils::hook::set(0x47A6D0_b, 0xC301B0); + // Remove update failed popup + utils::hook::set(0x47B2B0_b, 0xC301B0); } void pre_destroy() override diff --git a/src/client/game/demonware/services/bdStorage.cpp b/src/client/game/demonware/services/bdStorage.cpp index 9f398868..873a8119 100644 --- a/src/client/game/demonware/services/bdStorage.cpp +++ b/src/client/game/demonware/services/bdStorage.cpp @@ -174,27 +174,6 @@ namespace demonware auto* info = new bdFile2; - // int - // int - // int - // byte (priv) - // int64 (owner) - // string (platform) - // string (file) - // blob - // size - // data - // int - // int - // int - // byte - // int64 - // string (platform) - // string (file) - // blob - // size - // data - info->unk1 = 0; info->unk2 = 0; info->unk3 = 0; @@ -204,14 +183,6 @@ namespace demonware info->filename = filename; info->data = data; - /*info->file_id = *reinterpret_cast(utils::cryptography::sha1::compute(filename).data()); - info->filename = filename; - info->create_time = uint32_t(time(nullptr)); - info->modified_time = info->create_time; - info->file_size = uint32_t(data.size()); - info->owner_id = uint64_t(owner); - info->priv = priv;*/ - #ifdef DEBUG printf("[DW]: [bdStorage]: set user file: %s\n", filename.data()); #endif @@ -243,8 +214,6 @@ namespace demonware auto reply = server->create_reply(this->task_id()); - printf("%i\n", numfiles); - for (uint32_t i = 0; i < numfiles; i++) { std::string filename, data; diff --git a/src/client/game/demonware/services/bdUNK80.cpp b/src/client/game/demonware/services/bdUNK80.cpp index 7478d3f5..65c458c4 100644 --- a/src/client/game/demonware/services/bdUNK80.cpp +++ b/src/client/game/demonware/services/bdUNK80.cpp @@ -5,7 +5,8 @@ namespace demonware { bdUNK80::bdUNK80() : service(80, "bdUNK80") { - this->register_task(42, &bdUNK80::unk42); + this->register_task(42, &bdUNK80::unk42); // COD POINTS purchase ? + // this->register_task(43, &bdUNK80::unk43); COD POINTS purchase ? this->register_task(49, &bdUNK80::unk49); this->register_task(60, &bdUNK80::unk60); this->register_task(130, &bdUNK80::unk130); From 85c6664cdcc4f57d264f0fa85b1f2b996f8131be Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 18 May 2022 02:02:20 +0200 Subject: [PATCH 185/346] Update bdStorage.cpp --- src/client/game/demonware/services/bdStorage.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/client/game/demonware/services/bdStorage.cpp b/src/client/game/demonware/services/bdStorage.cpp index e184b5a7..873a8119 100644 --- a/src/client/game/demonware/services/bdStorage.cpp +++ b/src/client/game/demonware/services/bdStorage.cpp @@ -214,8 +214,6 @@ namespace demonware auto reply = server->create_reply(this->task_id()); - printf("%i\n", numfiles); - for (uint32_t i = 0; i < numfiles; i++) { std::string filename, data; From 33cb65146f8d0a81e2cba6e8d2e45692d1b2b64a Mon Sep 17 00:00:00 2001 From: m Date: Tue, 17 May 2022 21:26:04 -0500 Subject: [PATCH 186/346] readme changes [skip ci] --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f835f69e..f2eccfcf 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,9 @@

-An experimental client for Call of Duty Modern Warfare Remastered (version 1.04). -Support for the latest version (1.15) is planned for the future. +An experimental client for the latest Steam version of Call of Duty: Modern Warfare Remastered (version `1.15.1251288.0-0.32767`). +This branch is being actively worked on and researched. For now, refer to the `develop`/`main` branch for playable versions. + [This project is based on S1x.](https://github.com/XLabsProject/s1x-client) ## Compile from source From d5073559b71999202ebb85362e32a419bdc4fdfc Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 18 May 2022 10:26:48 +0200 Subject: [PATCH 187/346] Fixes --- src/client/component/auth.cpp | 2 +- src/client/component/colors.cpp | 2 +- src/client/component/console.cpp | 8 ++------ src/client/component/input.cpp | 2 +- src/client/component/localized_strings.cpp | 2 +- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 4ebebd8f..f633f740 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -245,4 +245,4 @@ namespace auth }; } -//REGISTER_COMPONENT(auth::component) +REGISTER_COMPONENT(auth::component) diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp index ec563b89..1487675b 100644 --- a/src/client/component/colors.cpp +++ b/src/client/component/colors.cpp @@ -179,4 +179,4 @@ namespace colors }; } -REGISTER_COMPONENT(colors::component) +//REGISTER_COMPONENT(colors::component) diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index 39f3f9dd..cfe8afef 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -16,12 +16,8 @@ namespace console { DWORD WINAPI console(LPVOID) { - FreeConsole(); - AllocConsole(); - AttachConsole(GetCurrentProcessId()); - - (void)freopen("CONIN$", "r", stdin); - (void)freopen("CONOUT$", "w", stdout); + ShowWindow(GetConsoleWindow(), SW_SHOW); + SetConsoleTitle("H1-Mod"); std::string cmd; diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 023a317b..ad615b34 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -72,4 +72,4 @@ namespace input }; } -REGISTER_COMPONENT(input::component) +//REGISTER_COMPONENT(input::component) diff --git a/src/client/component/localized_strings.cpp b/src/client/component/localized_strings.cpp index e66fc692..cd9d4718 100644 --- a/src/client/component/localized_strings.cpp +++ b/src/client/component/localized_strings.cpp @@ -49,4 +49,4 @@ namespace localized_strings }; } -REGISTER_COMPONENT(localized_strings::component) +//REGISTER_COMPONENT(localized_strings::component) From b9e9369637f488177d82d6dc9d6845831a04a2d8 Mon Sep 17 00:00:00 2001 From: quaK <38787176+Joelrau@users.noreply.github.com> Date: Wed, 18 May 2022 14:35:39 +0300 Subject: [PATCH 188/346] Add console input --- src/client/component/binding.cpp | 2 +- src/client/component/command.cpp | 2 +- src/client/component/console.cpp | 20 ++++++++++++++++---- src/client/component/console.hpp | 9 +++++++++ src/client/component/dedicated.cpp | 8 ++++---- src/client/component/game_console.cpp | 2 +- src/client/game/symbols.hpp | 2 +- 7 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/client/component/binding.cpp b/src/client/component/binding.cpp index 15828dfe..ab101b1d 100644 --- a/src/client/component/binding.cpp +++ b/src/client/component/binding.cpp @@ -103,7 +103,7 @@ namespace binding if (static_cast(key) < custom_binds.size() && !custom_binds[key].empty()) { - game::Cbuf_AddText(local_client_num, utils::string::va("%s\n", custom_binds[key].data())); + game::Cbuf_AddText(local_client_num, 0, utils::string::va("%s\n", custom_binds[key].data())); } return; diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index ba460c92..4ed2b282 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -493,7 +493,7 @@ namespace command } else { - game::Cbuf_AddText(0, command.data()); + game::Cbuf_AddText(0, 0, command.data()); } } diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index cfe8afef..c813372a 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -14,6 +14,8 @@ namespace console { namespace { + static bool ingame = false; + DWORD WINAPI console(LPVOID) { ShowWindow(GetConsoleWindow(), SW_SHOW); @@ -24,6 +26,10 @@ namespace console while (true) { std::getline(std::cin, cmd); + if (ingame) + { + game::Cbuf_AddText(0, 0, cmd.data()); + } } return 0; @@ -45,10 +51,6 @@ namespace console printf("%s\n", message.data()); //game_console::print(type, message); - //messages.access([&message](message_queue& msgs) - // { - // msgs.emplace(message); - // }); } void print(const int type, const char* fmt, ...) @@ -68,6 +70,16 @@ namespace console { CreateThread(0, 0, console, 0, 0, 0); } + + void post_unpack() override + { + ingame = true; + } + + void pre_destroy() override + { + ingame = false; + } }; } diff --git a/src/client/component/console.hpp b/src/client/component/console.hpp index 302951a8..8dcf5fab 100644 --- a/src/client/component/console.hpp +++ b/src/client/component/console.hpp @@ -9,6 +9,7 @@ namespace console enum console_type { con_type_error = 1, + con_type_dev = 2, con_type_warning = 3, con_type_info = 7 }; @@ -21,6 +22,14 @@ namespace console print(con_type_error, fmt, std::forward(args)...); } + template + void debug(const char* fmt, Args&&... args) + { +#ifdef DEBUG + print(2, fmt, std::forward(args)...); +#endif + } + template void warn(const char* fmt, Args&&... args) { diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index e1439d82..2acfcce5 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -83,8 +83,8 @@ namespace dedicated { if (game::Live_SyncOnlineDataFlags(0) == 0) { - game::Cbuf_AddText(client, command); - game::Cbuf_AddText(client, "\n"); + game::Cbuf_AddText(client, 0, command); + game::Cbuf_AddText(client, 0, "\n"); } else { @@ -99,8 +99,8 @@ namespace dedicated for (const auto& command : queue) { - game::Cbuf_AddText(0, command.data()); - game::Cbuf_AddText(0, "\n"); + game::Cbuf_AddText(0, 0, command.data()); + game::Cbuf_AddText(0, 0, "\n"); } } diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 2e8dfd9d..85fd4ff8 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -680,7 +680,7 @@ namespace game_console if (key == game::keyNum_t::K_ENTER) { - game::Cbuf_AddText(0, utils::string::va("%s \n", fixed_input.data())); + game::Cbuf_AddText(0, 0, utils::string::va("%s \n", fixed_input.data())); if (history_index != -1) { diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 75bd2671..d6650edc 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -15,7 +15,7 @@ namespace game WEAK symbol AllocThread{0x0, 0x509440}; WEAK symbol AllocVariable{0x0, 0x0}; - WEAK symbol Cbuf_AddText{0x0, 0x1CF480}; + WEAK symbol Cbuf_AddText{0x0, 0x1CF480}; WEAK symbol Cbuf_ExecuteBufferInternal{0x0, 0x155BC0}; WEAK symbol Conbuf_AppendText{0x0, 0x0}; From 9b0f3b6d58f1ca6d39da0ea0d8fb4e14c80660d1 Mon Sep 17 00:00:00 2001 From: quaK <38787176+Joelrau@users.noreply.github.com> Date: Wed, 18 May 2022 14:37:00 +0300 Subject: [PATCH 189/346] Update console.hpp --- src/client/component/console.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/component/console.hpp b/src/client/component/console.hpp index 8dcf5fab..4101a3a6 100644 --- a/src/client/component/console.hpp +++ b/src/client/component/console.hpp @@ -9,7 +9,7 @@ namespace console enum console_type { con_type_error = 1, - con_type_dev = 2, + con_type_debug = 2, con_type_warning = 3, con_type_info = 7 }; @@ -26,7 +26,7 @@ namespace console void debug(const char* fmt, Args&&... args) { #ifdef DEBUG - print(2, fmt, std::forward(args)...); + print(con_type_debug, fmt, std::forward(args)...); #endif } From 5c71e5342cb5a0d47f35bebf8f13bdf4c6909427 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 18 May 2022 14:16:58 +0200 Subject: [PATCH 190/346] Fix starting matches --- src/client/component/demonware.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp index 67e8e6b2..cabe4d69 100644 --- a/src/client/component/demonware.cpp +++ b/src/client/component/demonware.cpp @@ -508,6 +508,12 @@ namespace demonware } } } + + void request_start_match_stub() + { + const auto* args = "StartServer"; + utils::hook::invoke(0x1E35B0_b, 0, &args); + } } class component final : public component_interface @@ -616,6 +622,13 @@ namespace demonware utils::hook::set(0x47A6D0_b, 0xC301B0); // Remove update failed popup utils::hook::set(0x47B2B0_b, 0xC301B0); + + // xpartygo -> just start the match + utils::hook::jump(0x355B80_b, request_start_match_stub, true); + + utils::hook::set(0x396AD0_b, 0xC301B0); // DB_IsZoneLoaded("ffotd") + utils::hook::set(0x4DD600_b, 0xC300B0); // dont use ffotd + utils::hook::set(0x4DD5B0_b, 0xC300B0); // dont dl ffotd } void pre_destroy() override From 2eccb7ce475aaeef203bd20bd3e3a83465ac2747 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Wed, 18 May 2022 14:21:32 +0200 Subject: [PATCH 191/346] Remove steam parent spoofing as only T7 needs this --- src/client/component/arxan.cpp | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/client/component/arxan.cpp b/src/client/component/arxan.cpp index cd8293b1..3f77095f 100644 --- a/src/client/component/arxan.cpp +++ b/src/client/component/arxan.cpp @@ -9,24 +9,6 @@ namespace arxan { namespace { - DWORD get_steam_pid() - { - static DWORD pid = 0; //234567;//GetCurrentProcessId(); - if (pid) return pid; - - HKEY hRegKey; - - if (RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Valve\\Steam\\ActiveProcess", 0, KEY_QUERY_VALUE, - &hRegKey) != ERROR_SUCCESS) - return pid; - - DWORD dwLength = sizeof(pid); - RegQueryValueExA(hRegKey, "pid", nullptr, nullptr, reinterpret_cast(&pid), &dwLength); - RegCloseKey(hRegKey); - - return pid; - } - utils::hook::detour nt_close_hook; utils::hook::detour nt_query_information_process_hook; @@ -49,7 +31,7 @@ namespace arxan GetWindowThreadProcessId(shell_window, &explorer_pid); } - static_cast(info)->Reserved3 = PVOID(DWORD64(get_steam_pid())); + static_cast(info)->Reserved3 = PVOID(DWORD64(explorer_pid)); } else if (info_class == 30) // ProcessDebugObjectHandle { From bbe90c89d3fd0e56b324b8ac8baeaf07aa231a1b Mon Sep 17 00:00:00 2001 From: quaK <38787176+Joelrau@users.noreply.github.com> Date: Wed, 18 May 2022 16:39:04 +0300 Subject: [PATCH 192/346] Add command stuff not finished --- src/client/component/command.cpp | 28 ++++++++++++++-------------- src/client/game/game.cpp | 8 ++++++++ src/client/game/game.hpp | 2 ++ src/client/game/symbols.hpp | 22 +++++++++++----------- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index 4ed2b282..a8771df2 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -63,8 +63,8 @@ namespace command static std::string comand_line_buffer = GetCommandLineA(); auto* command_line = comand_line_buffer.data(); - auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); - auto* com_console_lines = reinterpret_cast(0x142623FC0); + auto& com_num_console_lines = *reinterpret_cast(0x35634B8_b); + auto* com_console_lines = reinterpret_cast(0x35634C0_b); auto inq = false; com_console_lines[0] = command_line; @@ -96,7 +96,7 @@ namespace command void parse_commandline_stub() { parse_command_line(); - utils::hook::invoke(0x1400D8210); + utils::hook::invoke(0x15A4F0_b); } game::dvar_t* dvar_command_stub() @@ -127,9 +127,9 @@ namespace command } else { - char command[0x1000] = { 0 }; - game::Dvar_GetCombinedString(command, 1); - game::Dvar_SetCommand(dvar->hash, "", command); + //char command[0x1000] = { 0 }; <-- CRASHES??!?!?!?! + //game::Dvar_GetCombinedString(command, 1); + //game::Dvar_SetCommand(dvar->hash, "", command); } return dvar; @@ -340,12 +340,12 @@ namespace command // parse the commandline if it's not parsed parse_command_line(); - auto& com_num_console_lines = *reinterpret_cast(0x142623FB4); - auto* com_console_lines = reinterpret_cast(0x142623FC0); + auto& com_num_console_lines = *reinterpret_cast(0x35634B8_b); + auto* com_console_lines = reinterpret_cast(0x35634C0_b); for (int i = 0; i < com_num_console_lines; i++) { - game::Cmd_TokenizeString(com_console_lines[i]); + game::Cmd_TokenizeString(com_console_lines[i]); // need to re-create this function // only +set dvar value if (game::Cmd_Argc() >= 3 && game::Cmd_Argv(0) == "set"s && game::Cmd_Argv(1) == dvar) @@ -353,7 +353,7 @@ namespace command game::Dvar_SetCommand(game::generateHashValue(game::Cmd_Argv(1)), "", game::Cmd_Argv(2)); } - game::Cmd_EndTokenizeString(); + game::Cmd_EndTokenizeString(); // need to re-create this function } } @@ -508,8 +508,8 @@ namespace command } else { - utils::hook::call(0x1400D728F, parse_commandline_stub); - utils::hook::jump(0x14041D750, dvar_command_stub); + utils::hook::call(0x157D8F_b, parse_commandline_stub); + //utils::hook::jump(0x4E9F40_b, dvar_command_stub); add_commands_mp(); } @@ -723,7 +723,7 @@ namespace command static void add_commands_mp() { - client_command_hook.create(0x140336000, &client_command); + client_command_hook.create(0x4132E0_b, &client_command); add_sv("god", [](const int client_num, const params_sv&) { @@ -818,4 +818,4 @@ namespace command }; } -//REGISTER_COMPONENT(command::component) +REGISTER_COMPONENT(command::component) diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 95fb0793..980d3ad1 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -36,6 +36,14 @@ namespace game return !game::environment::is_sp() && *mp::virtualLobby_loaded == 1; } + void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text) + { + if (clientNum == -1) + SV_SendServerCommand(0, type, "%s", text); + else + SV_SendServerCommand(&mp::svs_clients[clientNum], type, "%s", text); + } + namespace environment { launcher::mode mode = launcher::mode::none; diff --git a/src/client/game/game.hpp b/src/client/game/game.hpp index d1e623af..0d261d36 100644 --- a/src/client/game/game.hpp +++ b/src/client/game/game.hpp @@ -68,6 +68,8 @@ namespace game const char* SV_Cmd_Argv(int index); bool VirtualLobby_Loaded(); + + void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text); } uintptr_t operator"" _b(const uintptr_t ptr); diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index d6650edc..fd70192e 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -20,11 +20,11 @@ namespace game void (int, int, const char*))> Cbuf_ExecuteBufferInternal{0x0, 0x155BC0}; WEAK symbol Conbuf_AppendText{0x0, 0x0}; WEAK symbol ConcatArgs{0x0, 0x413050}; - WEAK symbol Cmd_ExecuteSingleCommand{0x0, 0x0}; + WEAK symbol Cmd_ExecuteSingleCommand{0x0, 0x156E90}; WEAK symbol Cmd_AddCommandInternal{0x0, 0x156880}; WEAK symbol Cmd_RemoveCommand{0x0, 0x157690}; - WEAK symbol Cmd_TokenizeString{0x0, 0x0}; - WEAK symbol Cmd_EndTokenizeString{0x0, 0x0}; + WEAK symbol Cmd_TokenizeString{0x0, 0x0}; // not a function + WEAK symbol Cmd_EndTokenizeString{0x0, 0x0}; // not a function WEAK symbol AimAssist_AddToTargetList{0x0, 0xE66C0}; @@ -39,7 +39,7 @@ namespace game WEAK symbol Com_Quit_f{0x0, 0x1F9280}; WEAK symbol Com_Shutdown{0x0, 0x0}; - WEAK symbol Quit{0x0, 0x1F9280}; + WEAK symbol Quit{0x0, 0x17CF50}; WEAK symbol CG_GameMessage{0x0, 0x316210}; WEAK symbol CG_GameMessageBold{0x0, 0x3122F0}; @@ -55,7 +55,7 @@ namespace game WEAK symbol Dvar_FindVar{0x0, 0x183EB0}; WEAK symbol Dvar_ClearModified{0x0, 0x0}; WEAK symbol Dvar_GetCombinedString{0x0, 0x4EA020}; - WEAK symbol Dvar_ValueToString{0x0, 0x0}; + WEAK symbol Dvar_ValueToString{0x0, 0x187000}; WEAK symbol Dvar_Reset{0x0, 0x185390}; WEAK symbol Dvar_SetFromStringByNameFromSource{0x0, 0x185BD0}; @@ -86,7 +86,7 @@ namespace game WEAK symbol GetEntityFieldValue{0x0, 0x0}; - WEAK symbol generateHashValue{0x0, 0x0}; + WEAK symbol generateHashValue{0x0, 0x183F80}; WEAK symbol G_Glass_Update{0x0, 0x0}; WEAK symbol G_GetClientScore{0x0, 0x0}; @@ -186,7 +186,7 @@ namespace game WEAK symbol SV_MapExists{0x0, 0x0}; WEAK symbol SV_ExecuteClientCommand{0x0, 0x0}; WEAK symbol SV_FastRestart{0x0, 0x0}; - WEAK symbol SV_GameSendServerCommand{0x0, 0x0}; + WEAK symbol SV_SendServerCommand{0x0, 0x1CC040}; WEAK symbol Sys_ShowConsole{0x0, 0x0}; WEAK symbol Sys_Error{0x0, 0x0}; @@ -221,7 +221,7 @@ namespace game WEAK symbol command_whitelist{0x0, 0x0}; WEAK symbol cmd_functions{0x0, 0x344DF18}; - WEAK symbol cmd_args{0x0, 0x0}; + WEAK symbol cmd_args{0x0, 0x2ED1E00}; WEAK symbol g_poolSize{0x0, 0x0}; WEAK symbol g_classMap{0x0, 0x0}; @@ -248,15 +248,15 @@ namespace game namespace mp { WEAK symbol g_entities{0x0, 0x71F19E0}; - WEAK symbol svs_clients{0x0, 0x0}; - WEAK symbol svs_numclients{0x0, 0x0}; + WEAK symbol svs_clients{0x0, 0x2DC3390}; + WEAK symbol svs_numclients{0x0, 0x2DC338C}; WEAK symbol gameTime{0x0, 0x0}; WEAK symbol ping{0x0, 0x0}; WEAK symbol sv_serverId_value{0x0, 0x0}; - WEAK symbol virtualLobby_loaded{0x0, 0x0}; + WEAK symbol virtualLobby_loaded{0x0, 0x2E6EC9D}; } namespace sp From f27844f19e909e4f39a27ed39dc81cc047fb9217 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 18 May 2022 09:23:01 -0500 Subject: [PATCH 193/346] tiny address changes [skip ci] --- src/client/component/patches.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 7d5d75fc..3d4fedbe 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -73,7 +73,7 @@ namespace patches } // CG_SetClientDvarFromServer - utils::hook::invoke(0x140236120, a1, a2, dvar, value); + utils::hook::invoke(0x11AA90_b, a1, a2, dvar, value); } const char* db_read_raw_file_stub(const char* filename, char* buf, const int size) @@ -230,12 +230,12 @@ namespace patches utils::hook::inject(0x140480955, VERSION); // prevent servers overriding our fov - utils::hook::call(0x14023279E, set_client_dvar_from_server_stub); - utils::hook::nop(0x1400DAF69, 5); - utils::hook::nop(0x140190C16, 5); - utils::hook::set(0x14021D22A, 0xEB); + utils::hook::call(0xF4500_b, set_client_dvar_from_server_stub); + // utils::hook::nop(0x1400DAF69, 5); + // utils::hook::nop(0x140190C16, 5); + utils::hook::set(0x307F39_b, 0xEB); - // some anti tamper thing that kills performance + // some anti tamper thing that kills performance (not needed in H1?) dvars::override::register_int("dvl", 0, 0, 0, game::DVAR_FLAG_READ); // unlock safeArea_* From f5765d5c1502b6cf75797b18b4200e105077aa69 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 18 May 2022 19:00:16 +0200 Subject: [PATCH 194/346] Dvar fixes --- src/client/component/command.cpp | 19 ++++++------ src/client/component/dvars.cpp | 44 +++++++++++++++++++++++++-- src/client/component/game_console.cpp | 6 ++-- src/client/game/dvars.cpp | 3 ++ src/client/game/structs.hpp | 3 ++ src/client/game/symbols.hpp | 2 +- 6 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index a8771df2..a83e0f85 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -22,6 +22,7 @@ namespace command namespace { utils::hook::detour client_command_hook; + utils::hook::detour parse_commandline_hook; std::unordered_map> handlers; std::unordered_map> handlers_sv; @@ -96,7 +97,7 @@ namespace command void parse_commandline_stub() { parse_command_line(); - utils::hook::invoke(0x15A4F0_b); + parse_commandline_hook.invoke(); } game::dvar_t* dvar_command_stub() @@ -114,8 +115,8 @@ namespace command { if (args.size() == 1) { - const auto current = game::Dvar_ValueToString(dvar, dvar->current); - const auto reset = game::Dvar_ValueToString(dvar, dvar->reset); + const auto current = game::Dvar_ValueToString(dvar, true, dvar->current); + const auto reset = game::Dvar_ValueToString(dvar, true, dvar->reset); console::info("\"%s\" is: \"%s\" default: \"%s\" hash: 0x%08lX\n", args[0], current, reset, dvar->hash); @@ -127,9 +128,9 @@ namespace command } else { - //char command[0x1000] = { 0 }; <-- CRASHES??!?!?!?! - //game::Dvar_GetCombinedString(command, 1); - //game::Dvar_SetCommand(dvar->hash, "", command); + char command[0x1000] = {0}; + game::Dvar_GetCombinedString(command, 1); + game::Dvar_SetCommand(dvar->hash, "", command); } return dvar; @@ -454,8 +455,6 @@ namespace command void add(const char* name, const std::function& callback) { - static game::cmd_function_s cmd_test; - const auto command = utils::string::to_lower(name); if (handlers.find(command) == handlers.end()) @@ -508,8 +507,8 @@ namespace command } else { - utils::hook::call(0x157D8F_b, parse_commandline_stub); - //utils::hook::jump(0x4E9F40_b, dvar_command_stub); + // parse_commandline_hook.create(0x157D50_b, parse_commandline_stub); + utils::hook::jump(0x4E9F40_b, dvar_command_stub, true); add_commands_mp(); } diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp index d9633b87..90690e76 100644 --- a/src/client/component/dvars.cpp +++ b/src/client/component/dvars.cpp @@ -249,6 +249,38 @@ namespace dvars utils::hook::detour dvar_set_string_hook; utils::hook::detour dvar_set_from_string_hook; + utils::hook::detour dvar_re_register_hook; + utils::hook::detour dvar_register_new_hook; + + game::dvar_type get_normal_type(const game::dvar_type type) + { + switch (type) + { + case game::dvar_type::boolean_hashed: + return game::dvar_type::boolean; + case game::dvar_type::integer_hashed: + return game::dvar_type::integer; + case game::dvar_type::value_hashed: + return game::dvar_type::value; + default: + return type; + } + } + + void dvar_re_register_stub(game::dvar_t* dvar, const int hash, const char* name, game::dvar_type type, + const unsigned int flags, game::dvar_value* value, game::dvar_limits* domain) + { + type = get_normal_type(type); + dvar_re_register_hook.invoke(dvar, hash, name, type, flags, value, domain); + } + + game::dvar_t* dvar_register_new_stub(const int hash, const char* name, game::dvar_type type, + const unsigned int flags, game::dvar_value* value, game::dvar_limits* domain) + { + type = get_normal_type(type); + return dvar_register_new_hook.invoke(hash, name, type, flags, value, domain); + } + game::dvar_t* dvar_register_bool(const int hash, const char* name, bool value, unsigned int flags) { auto* var = find_dvar(override::register_bool_overrides, hash); @@ -424,7 +456,13 @@ namespace dvars public: void post_unpack() override { - dvar_register_bool_hook.create(SELECT_VALUE(0x1403C47E0, 0x1404FA540), &dvar_register_bool); + if (game::environment::is_mp()) + { + dvar_register_new_hook.create(0x184DF0_b, dvar_register_new_stub); + dvar_re_register_hook.create(0x185150_b, dvar_re_register_stub); + } + + /*dvar_register_bool_hook.create(SELECT_VALUE(0x1403C47E0, 0x1404FA540), &dvar_register_bool); dvar_register_float_hook.create(SELECT_VALUE(0x1403C4BB0, 0x1404FA910), &dvar_register_float); dvar_register_int_hook.create(SELECT_VALUE(0x1403C4CC0, 0x1404FAA20), &dvar_register_int); dvar_register_string_hook.create(SELECT_VALUE(0x1403C4DA0, 0x1404FAB00), &dvar_register_string); @@ -435,9 +473,9 @@ namespace dvars dvar_set_float_hook.create(SELECT_VALUE(0x1403C7420, 0x1404FD360), &dvar_set_float); dvar_set_int_hook.create(SELECT_VALUE(0x1403C76C0, 0x1404FD5E0), &dvar_set_int); dvar_set_string_hook.create(SELECT_VALUE(0x1403C7900, 0x1404FD8D0), &dvar_set_string); - dvar_set_from_string_hook.create(SELECT_VALUE(0x1403C7620, 0x1404FD520), &dvar_set_from_string); + dvar_set_from_string_hook.create(SELECT_VALUE(0x1403C7620, 0x1404FD520), &dvar_set_from_string);*/ } }; } -//REGISTER_COMPONENT(dvars::component) +REGISTER_COMPONENT(dvars::component) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 85fd4ff8..95816851 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -286,10 +286,10 @@ namespace game_console { const auto offset = (con.screen_max[0] - con.globals.x) / 4.f; - draw_hint_text(0, game::Dvar_ValueToString(dvar, dvar->current), + draw_hint_text(0, game::Dvar_ValueToString(dvar, true, dvar->current), dvars::con_inputDvarValueColor->current.vector, offset); draw_hint_text(1, " default", dvars::con_inputDvarInactiveValueColor->current.vector); - draw_hint_text(1, game::Dvar_ValueToString(dvar, dvar->reset), + draw_hint_text(1, game::Dvar_ValueToString(dvar, true, dvar->reset), dvars::con_inputDvarInactiveValueColor->current.vector, offset); draw_hint_text(2, matches[0].description.data(), color_white, 0); @@ -324,7 +324,7 @@ namespace game_console if (dvar) { - draw_hint_text(static_cast(i), game::Dvar_ValueToString(dvar, dvar->current), + draw_hint_text(static_cast(i), game::Dvar_ValueToString(dvar, true, dvar->current), dvars::con_inputDvarValueColor->current.vector, offset); draw_hint_text(static_cast(i), matches[i].description.data(), diff --git a/src/client/game/dvars.cpp b/src/client/game/dvars.cpp index 96007b98..2a126848 100644 --- a/src/client/game/dvars.cpp +++ b/src/client/game/dvars.cpp @@ -72,9 +72,11 @@ namespace dvars switch (type) { case game::dvar_type::boolean: + case game::dvar_type::boolean_hashed: return "Domain is 0 or 1"s; case game::dvar_type::value: + case game::dvar_type::value_hashed: if (domain.value.min == -FLT_MAX) { if (domain.value.max == FLT_MAX) @@ -106,6 +108,7 @@ namespace dvars return dvar_get_vector_domain(4, domain); case game::dvar_type::integer: + case game::dvar_type::integer_hashed: if (domain.enumeration.stringCount == INT_MIN) { if (domain.integer.max == INT_MAX) diff --git a/src/client/game/structs.hpp b/src/client/game/structs.hpp index a9ff21b8..ead2784b 100644 --- a/src/client/game/structs.hpp +++ b/src/client/game/structs.hpp @@ -881,11 +881,14 @@ namespace game enum dvar_type : std::int8_t { boolean = 0, + boolean_hashed = 10, value = 1, + value_hashed = 11, vec2 = 2, vec3 = 3, vec4 = 4, integer = 5, + integer_hashed = 12, enumeration = 6, string = 7, color = 8, diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index fd70192e..a41be9d5 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -55,7 +55,7 @@ namespace game WEAK symbol Dvar_FindVar{0x0, 0x183EB0}; WEAK symbol Dvar_ClearModified{0x0, 0x0}; WEAK symbol Dvar_GetCombinedString{0x0, 0x4EA020}; - WEAK symbol Dvar_ValueToString{0x0, 0x187000}; + WEAK symbol Dvar_ValueToString{0x0, 0x187000}; WEAK symbol Dvar_Reset{0x0, 0x185390}; WEAK symbol Dvar_SetFromStringByNameFromSource{0x0, 0x185BD0}; From 711b0e3e9402abf76ccbf0d923c16d2fd735a99b Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 18 May 2022 19:39:35 +0200 Subject: [PATCH 195/346] Actually this breaks stuff --- src/client/component/dvars.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp index 90690e76..93f2fd21 100644 --- a/src/client/component/dvars.cpp +++ b/src/client/component/dvars.cpp @@ -458,8 +458,8 @@ namespace dvars { if (game::environment::is_mp()) { - dvar_register_new_hook.create(0x184DF0_b, dvar_register_new_stub); - dvar_re_register_hook.create(0x185150_b, dvar_re_register_stub); + // dvar_register_new_hook.create(0x184DF0_b, dvar_register_new_stub); + // dvar_re_register_hook.create(0x185150_b, dvar_re_register_stub); } /*dvar_register_bool_hook.create(SELECT_VALUE(0x1403C47E0, 0x1404FA540), &dvar_register_bool); From 58c7ace27713e518fc6555b2c432b413691f3788 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 18 May 2022 21:47:26 +0200 Subject: [PATCH 196/346] Fix crash at end of game --- src/client/component/demonware.cpp | 36 ++++++------------------------ 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp index cabe4d69..37bdfdae 100644 --- a/src/client/component/demonware.cpp +++ b/src/client/component/demonware.cpp @@ -581,38 +581,16 @@ namespace demonware utils::hook::set(0x7C0AC5_b, 0xAF); // CURLOPT_SSL_VERIFYHOST utils::hook::set(0xA1327C_b, 0x0); // HTTPS -> HTTP - // HTTPS -> HTTP - char* umbrella = (char*)allocate_somewhere_near((uint8_t*)game::base_address); - std::memcpy(umbrella, "http://prod.umbrella.demonware.net/v1.0/", sizeof("http://prod.umbrella.demonware.net/v1.0/")); + std::memcpy(reinterpret_cast(0x8D0298_b), + "http://prod.umbrella.demonware.net/v1.0/", sizeof("http://prod.umbrella.demonware.net/v1.0/")); + std::memcpy(reinterpret_cast(0x8D05A8_b), + "http://prod.uno.demonware.net/v1.0/", sizeof("http://prod.uno.demonware.net/v1.0/")); + std::memcpy(reinterpret_cast(0x9EDB08_b), "http://%s:%d/auth/", sizeof("http://%s:%d/auth/")); - utils::hook::inject(0x8615F_b, umbrella); - utils::hook::inject(0x8638C_b, umbrella); - - char* uno = (char*)allocate_somewhere_near((uint8_t*)game::base_address); - std::memcpy(uno, "http://prod.uno.demonware.net/v1.0/", sizeof("http://prod.uno.demonware.net/v1.0/")); - - utils::hook::inject(0x86C56_b, uno); - utils::hook::inject(0x86F96_b, uno); - - BYTE bytes[] = { 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x25, 0x73, 0x3A, 0x25, 0x64, 0x2F, 0x61, 0x75, 0x74, 0x68, 0x2F, 0x0 }; // KEKW - std::memcpy((void*)0x9EDB08_b, bytes, sizeof(bytes)); //utils::hook::inject(0x140728170, "http://%s:%d/auth/"); :DDD - - // utils::hook::set(0x19F8C0_b, 0xC3); SV_SendMatchData, not sure + // utils::hook::set(0x19F8C0_b, 0xC3); // SV_SendMatchData, not sure + utils::hook::nop(0x19BB67_b, 5); // LiveStorage_SendMatchDataComplete utils::hook::set(0x1A3340_b, 0xC3); // Live_CheckForFullDisconnect -//#ifdef DEBUG -// // yes -// utils::hook::call(0x140727BEB, l); -// utils::hook::call(0x140727AFC, i); -// utils::hook::call(0x140727E49, h); -// utils::hook::call(0x140727E30, g); -// utils::hook::call(0x140727E37, f); -// utils::hook::call(0x140727DF2, e); -// utils::hook::call(0x140727DF9, d); -// utils::hook::call(0x140727CFC, c); -// utils::hook::call(0x140727C82, b); -// utils::hook::call(0x140727E6A, a); -//#endif // Remove some while loop that freezes the rendering for a few secs while connecting utils::hook::nop(0x625555_b, 5); From 6da3aa162e0480156945fd627e7db039a3425b59 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Wed, 18 May 2022 22:00:02 +0200 Subject: [PATCH 197/346] Exception component --- src/client/component/exception.cpp | 8 +++++--- src/client/component/scheduler.cpp | 14 ++++++++------ src/client/game/demonware/services/bdStorage.cpp | 2 +- src/client/game/symbols.hpp | 4 ++-- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/client/component/exception.cpp b/src/client/component/exception.cpp index ea64a4aa..598473ad 100644 --- a/src/client/component/exception.cpp +++ b/src/client/component/exception.cpp @@ -84,9 +84,10 @@ namespace exception void display_error_dialog() { - std::string error_str = utils::string::va("Fatal error (0x%08X) at 0x%p.\n" + std::string error_str = utils::string::va("Fatal error (0x%08X) at 0x%p (0x%p).\n" "A minidump has been written.\n\n", - exception_data.code, exception_data.address); + exception_data.code, exception_data.address, + reinterpret_cast(exception_data.address) - game::base_address); if (!system_check::is_valid()) { @@ -176,6 +177,7 @@ namespace exception line("Clean game: "s + (system_check::is_valid() ? "Yes" : "No")); line(utils::string::va("Exception: 0x%08X", exceptioninfo->ExceptionRecord->ExceptionCode)); line(utils::string::va("Address: 0x%llX", exceptioninfo->ExceptionRecord->ExceptionAddress)); + line(utils::string::va("Base: 0x%llX", game::base_address)); #pragma warning(push) #pragma warning(disable: 4996) @@ -258,4 +260,4 @@ namespace exception }; } -//REGISTER_COMPONENT(exception::component) +REGISTER_COMPONENT(exception::component) diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index 1c8b7287..177ec4be 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -100,7 +100,6 @@ namespace scheduler void r_end_frame_stub() { execute(pipeline::renderer); - //r_end_frame_hook.invoke(); } void server_frame_stub() @@ -109,10 +108,14 @@ namespace scheduler execute(pipeline::server); } - void main_frame_stub() + void* main_frame_stub() { - main_frame_hook.invoke(); - execute(pipeline::main); + const auto _0 = gsl::finally([]() + { + execute(pipeline::main); + }); + + return main_frame_hook.invoke(); } void hks_frame_stub() @@ -204,9 +207,8 @@ namespace scheduler a.jmp(0x6A6310_b); }), true); - //r_end_frame_hook.create(SELECT_VALUE(0x0, 0x6A6300_b), scheduler::r_end_frame_stub); //g_run_frame_hook.create(SELECT_VALUE(0x0, 0x417940_b), scheduler::server_frame_stub); - //main_frame_hook.create(SELECT_VALUE(0x0, 0x0), scheduler::main_frame_stub); + main_frame_hook.create(SELECT_VALUE(0x0, 0x3438B0_b), scheduler::main_frame_stub); //hks_frame_hook.create(SELECT_VALUE(0x0, 0x0), scheduler::hks_frame_stub); // no scripting for now } diff --git a/src/client/game/demonware/services/bdStorage.cpp b/src/client/game/demonware/services/bdStorage.cpp index 873a8119..1cae2206 100644 --- a/src/client/game/demonware/services/bdStorage.cpp +++ b/src/client/game/demonware/services/bdStorage.cpp @@ -18,7 +18,7 @@ namespace demonware this->register_task(12, &bdStorage::unk12); this->map_publisher_resource("motd-.*\\.txt", DW_MOTD); - this->map_publisher_resource("ffotd-.*\\.ff", DW_FASTFILE); + // this->map_publisher_resource("ffotd-.*\\.ff", DW_FASTFILE); this->map_publisher_resource("playlists(_.+)?\\.aggr", DW_PLAYLISTS); } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index a41be9d5..92c1fe01 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -101,7 +101,7 @@ namespace game WEAK symbol Key_KeynumToString{0x0, 0x0}; - WEAK symbol Live_SyncOnlineDataFlags{0x0, 0x0}; + WEAK symbol Live_SyncOnlineDataFlags{0x0, 0x1A5C10}; WEAK symbol Material_RegisterHandle{0x0, 0x692360}; @@ -193,7 +193,7 @@ namespace game WEAK symbol Sys_BuildAbsPath{0x0, 0x0}; WEAK symbol Sys_Milliseconds{0x0, 0x0}; - WEAK symbol Sys_IsDatabaseReady2{0x0, 0x0}; + WEAK symbol Sys_IsDatabaseReady2{0x0, 0x4F79C0}; WEAK symbol Sys_SendPacket{0x0, 0x0}; WEAK symbol Sys_FileExists{0x0, 0x0}; From 85fddd73e1655414b7cc039b92629c42adbeae54 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 19 May 2022 01:32:00 +0300 Subject: [PATCH 198/346] stuff --- src/client/component/dedicated.cpp | 130 ++++++++++----------- src/client/component/dvars.cpp | 22 ++-- src/client/component/localized_strings.cpp | 2 +- src/client/component/server_list.cpp | 10 +- src/client/component/stats.cpp | 14 +-- src/client/game/symbols.hpp | 2 +- 6 files changed, 90 insertions(+), 90 deletions(-) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index 2acfcce5..15a4bd80 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -26,7 +26,7 @@ namespace dedicated initialized = true; // R_LoadGraphicsAssets - utils::hook::invoke(0x1405DF4B0); + utils::hook::invoke(0x686310_b); } void send_heartbeat() @@ -197,96 +197,96 @@ namespace dedicated dvars::override::register_bool("r_preloadShaders", false, game::DVAR_FLAG_READ); // Stop crashing from sys_errors - utils::hook::jump(0x140511520, sys_error_stub); + utils::hook::jump(0x1D8710_b, sys_error_stub); // Hook R_SyncGpu - utils::hook::jump(0x1405E12F0, sync_gpu_stub); + utils::hook::jump(0x688620_b, sync_gpu_stub); - utils::hook::jump(0x140254800, init_dedicated_server); + utils::hook::jump(0x135600_b, init_dedicated_server); // delay startup commands until the initialization is done - utils::hook::call(0x1400D72D6, execute_startup_command); + utils::hook::call(0x157DDA_b, execute_startup_command); - // delay console commands until the initialization is done - utils::hook::call(0x1400D808C, execute_console_command); - utils::hook::nop(0x1400D80A4, 5); + // delay console commands until the initialization is done // COULDN'T FOUND + //utils::hook::call(0x1400D808C, execute_console_command); + //utils::hook::nop(0x1400D80A4, 5); // patch GScr_SetDynamicDvar to behave better - gscr_set_dynamic_dvar_hook.create(0x14036B600, &gscr_set_dynamic_dvar); + gscr_set_dynamic_dvar_hook.create(0x43CF60_b, &gscr_set_dynamic_dvar); - utils::hook::nop(0x1404ED90E, 5); // don't load config file - utils::hook::nop(0x140403D92, 5); // ^ - utils::hook::set(0x1400DC1D0, 0xC3); // don't save config file - utils::hook::set(0x140274710, 0xC3); // disable self-registration - utils::hook::set(0x140515890, 0xC3); // init sound system (1) - utils::hook::set(0x1406574F0, 0xC3); // init sound system (2) - utils::hook::set(0x140620D10, 0xC3); // render thread - utils::hook::set(0x14025B850, 0xC3); // called from Com_Frame, seems to do renderer stuff - utils::hook::set(0x1402507B0, 0xC3); // CL_CheckForResend, which tries to connect to the local server constantly - utils::hook::set(0x1405D5178, 0x00); // r_loadForRenderer default to 0 - utils::hook::set(0x14050C2D0, 0xC3); // recommended settings check - TODO: Check hook - utils::hook::set(0x140514C00, 0xC3); // some mixer-related function called on shutdown - utils::hook::set(0x140409830, 0xC3); // dont load ui gametype stuff + //utils::hook::nop(0x1404ED90E, 5); // don't load config file // NOT FOUND + utils::hook::nop(0x156C46_b, 5); // ^ // NOT SURE + utils::hook::set(0x17F470_b, 0xC3); // don't save config file + utils::hook::set(0x351AA0_b, 0xC3); // disable self-registration + utils::hook::set(0x5BF4E0_b, 0xC3); // init sound system (1) + utils::hook::set(0x702650_b, 0xC3); // init sound system (2) NOT SURE + //utils::hook::set(0x140620D10, 0xC3); // render thread ARXAN'D + utils::hook::set(0x343950_b, 0xC3); // called from Com_Frame, seems to do renderer stuff + utils::hook::set(0x12CCA0_b, 0xC3); // CL_CheckForResend, which tries to connect to the local server constantly + utils::hook::set(0x67ADCE_b, 0x00); // r_loadForRenderer default to 0 NOT SURE + utils::hook::set(0x5B7AF0_b, 0xC3); // recommended settings check - TODO: Check hook + utils::hook::set(0x5BE850_b, 0xC3); // some mixer-related function called on shutdown + utils::hook::set(0x4DEA50_b, 0xC3); // dont load ui gametype stuff - utils::hook::nop(0x140481B06, 6); // unknown check in SV_ExecuteClientMessage - utils::hook::nop(0x140480FAC, 4); // allow first slot to be occupied - utils::hook::nop(0x14025619B, 2); // properly shut down dedicated servers - utils::hook::nop(0x14025615E, 2); // ^ - utils::hook::nop(0x1402561C0, 5); // don't shutdown renderer + utils::hook::nop(0x54ED81_b, 6); // unknown check in SV_ExecuteClientMessage + utils::hook::nop(0x54E337_b, 4); // allow first slot to be occupied + utils::hook::nop(0x13ABCB_b, 2); // properly shut down dedicated servers + utils::hook::nop(0x13AB8E_b, 2); // ^ + utils::hook::nop(0x13ABF0_b, 5); // don't shutdown renderer - utils::hook::set(0x140091840, 0xC3); // something to do with blendShapeVertsView - utils::hook::nop(0x140659A0D, 8); // sound thing + utils::hook::set(0xAA290_b, 0xC3); // something to do with blendShapeVertsView + utils::hook::nop(0x70465D_b, 8); // sound thing // (COULD NOT FIND IN H1) // utils::hook::set(0x1404D6960, 0xC3); // cpu detection stuff? - utils::hook::set(0x1405E97F0, 0xC3); // gfx stuff during fastfile loading - utils::hook::set(0x1405E9700, 0xC3); // ^ - utils::hook::set(0x1405E9790, 0xC3); // ^ - utils::hook::set(0x1402C1180, 0xC3); // ^ - utils::hook::set(0x1405E9750, 0xC3); // ^ - utils::hook::set(0x1405AD5B0, 0xC3); // directx stuff - utils::hook::set(0x1405DB150, 0xC3); // ^ - utils::hook::set(0x140625220, 0xC3); // ^ - mutex - utils::hook::set(0x1405DB650, 0xC3); // ^ + utils::hook::set(0x690F30_b, 0xC3); // gfx stuff during fastfile loading + utils::hook::set(0x690E00_b, 0xC3); // ^ + utils::hook::set(0x690ED0_b, 0xC3); // ^ + //utils::hook::set(0x1402C1180, 0xC3); // ^ NOT FOUND? + utils::hook::set(0x690E50_b, 0xC3); // ^ MAAAAAAAAAAAYBE NOTTTT + utils::hook::set(0x651BA0_b, 0xC3); // directx stuff + utils::hook::set(0x681950_b, 0xC3); // ^ + utils::hook::set(0x6CE390_b, 0xC3); // ^ - mutex + utils::hook::set(0x681ED0_b, 0xC3); // ^ - utils::hook::set(0x14008B5F0, 0xC3); // rendering stuff - utils::hook::set(0x1405DB8B0, 0xC3); // ^ - utils::hook::set(0x1405DB9C0, 0xC3); // ^ - utils::hook::set(0x1405DC050, 0xC3); // ^ - utils::hook::set(0x1405DCBA0, 0xC3); // ^ - utils::hook::set(0x1405DD240, 0xC3); // ^ + utils::hook::set(0xA3CD0_b, 0xC3); // rendering stuff + utils::hook::set(0x682150_b, 0xC3); // ^ + utils::hook::set(0x682260_b, 0xC3); // ^ + utils::hook::set(0x6829C0_b, 0xC3); // ^ + utils::hook::set(0x6834A0_b, 0xC3); // ^ + utils::hook::set(0x683B40_b, 0xC3); // ^ // shaders - utils::hook::set(0x1400916A0, 0xC3); // ^ - utils::hook::set(0x140091610, 0xC3); // ^ - utils::hook::set(0x14061ACC0, 0xC3); // ^ - mutex + utils::hook::set(0xAA090_b, 0xC3); // ^ + utils::hook::set(0xA9FE0_b, 0xC3); // ^ + utils::hook::set(0x6C38D0_b, 0xC3); // ^ - mutex - utils::hook::set(0x140516080, 0xC3); // idk - utils::hook::set(0x1405AE5F0, 0xC3); // ^ + utils::hook::set(0x5BFD10_b, 0xC3); // idk + utils::hook::set(0x652E10_b, 0xC3); // ^ - utils::hook::set(0x1405E0B30, 0xC3); // R_Shutdown - utils::hook::set(0x1405AE400, 0xC3); // shutdown stuff - utils::hook::set(0x1405E0C00, 0xC3); // ^ - utils::hook::set(0x1405DFE50, 0xC3); // ^ + utils::hook::set(0x687D20_b, 0xC3); // R_Shutdown + utils::hook::set(0x652BA0_b, 0xC3); // shutdown stuff + utils::hook::set(0x687DF0_b, 0xC3); // ^ + //utils::hook::set(0x1405DFE50, 0xC3); // ^ COULDN'T FOUND // utils::hook::set(0x1404B67E0, 0xC3); // sound crashes (H1 - questionable, function looks way different) - utils::hook::set(0x14048B660, 0xC3); // disable host migration + utils::hook::set(0x556250_b, 0xC3); // disable host migration - utils::hook::set(0x14042B2E0, 0xC3); // render synchronization lock - utils::hook::set(0x14042B210, 0xC3); // render synchronization unlock + utils::hook::set(0x4F7C10_b, 0xC3); // render synchronization lock + utils::hook::set(0x42B210_b, 0xC3); // render synchronization unlock - utils::hook::set(0x140176D2D, 0xEB); // LUI: Unable to start the LUI system due to errors in main.lua + utils::hook::set(0x27AA9D_b, 0xEB); // LUI: Unable to start the LUI system due to errors in main.lua - utils::hook::nop(0x140506ECE, 5); // Disable sound pak file loading - utils::hook::nop(0x140506ED6, 2); // ^ - utils::hook::set(0x1402C5910, 0xC3); // Disable image pak file loading + utils::hook::nop(0x5B25BE_b, 5); // Disable sound pak file loading + utils::hook::nop(0x5B25C6_b, 2); // ^ + utils::hook::set(0x3A0BA0_b, 0xC3); // Disable image pak file loading // Reduce min required memory - utils::hook::set(0x14050C717, 0x80000000); + utils::hook::set(0x5B7F37_b, 0x80000000); - utils::hook::set(0x1402BF7F0, 0xC3); // some loop - utils::hook::set(0x14007E150, 0xC3); // related to shader caching / techsets / fastfiles + utils::hook::set(0x399E10_b, 0xC3); // some loop + utils::hook::set(0x1D48B0_b, 0xC3); // related to shader caching / techsets / fastfiles // initialize the game after onlinedataflags is 32 (workaround) scheduler::schedule([=]() @@ -318,14 +318,14 @@ namespace dedicated execute_startup_command_queue(); execute_console_command_queue(); - // Send heartbeat to dpmaster + // Send heartbeat to master scheduler::once(send_heartbeat, scheduler::pipeline::server); scheduler::loop(send_heartbeat, scheduler::pipeline::server, 10min); command::add("heartbeat", send_heartbeat); }, scheduler::pipeline::main, 1s); command::add("killserver", kill_server); - com_quit_f_hook.create(0x1400DA640, &kill_server); + com_quit_f_hook.create(0x17CD00_b, &kill_server); } }; } diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp index 93f2fd21..f1eca327 100644 --- a/src/client/component/dvars.cpp +++ b/src/client/component/dvars.cpp @@ -462,18 +462,18 @@ namespace dvars // dvar_re_register_hook.create(0x185150_b, dvar_re_register_stub); } - /*dvar_register_bool_hook.create(SELECT_VALUE(0x1403C47E0, 0x1404FA540), &dvar_register_bool); - dvar_register_float_hook.create(SELECT_VALUE(0x1403C4BB0, 0x1404FA910), &dvar_register_float); - dvar_register_int_hook.create(SELECT_VALUE(0x1403C4CC0, 0x1404FAA20), &dvar_register_int); - dvar_register_string_hook.create(SELECT_VALUE(0x1403C4DA0, 0x1404FAB00), &dvar_register_string); - dvar_register_vector2_hook.create(SELECT_VALUE(0x1403C4E80, 0x1404FABE0), &dvar_register_vector2); - dvar_register_vector3_hook.create(SELECT_VALUE(0x1403C4FC0, 0x1404FACE0), &dvar_register_vector3); + dvar_register_bool_hook.create(SELECT_VALUE(0x0, 0x182340_b), &dvar_register_bool); // good + //dvar_register_float_hook.create(SELECT_VALUE(0x0, 0x182900_b), &dvar_register_float); // FLOAT HASHED (TYPE 11 INSTEAD OF 1) + dvar_register_int_hook.create(SELECT_VALUE(0x0, 0x182A10_b), &dvar_register_int); // goood + //dvar_register_string_hook.create(SELECT_VALUE(0x0, 0x182AF0_b), &dvar_register_string); // INT HASHED (TYPE 12, INSTEAD OF 7) + //dvar_register_vector2_hook.create(SELECT_VALUE(0x0, 0x182BD0_b), &dvar_register_vector2); // STRING (TYPE 7 INSTEAD OF 2) + //dvar_register_vector3_hook.create(SELECT_VALUE(0x0, 0x182CB0_b), &dvar_register_vector3); // VEC2 (TYPE 2 INSTEAD OF 3) - dvar_set_bool_hook.create(SELECT_VALUE(0x1403C7020, 0x1404FCDF0), &dvar_set_bool); - dvar_set_float_hook.create(SELECT_VALUE(0x1403C7420, 0x1404FD360), &dvar_set_float); - dvar_set_int_hook.create(SELECT_VALUE(0x1403C76C0, 0x1404FD5E0), &dvar_set_int); - dvar_set_string_hook.create(SELECT_VALUE(0x1403C7900, 0x1404FD8D0), &dvar_set_string); - dvar_set_from_string_hook.create(SELECT_VALUE(0x1403C7620, 0x1404FD520), &dvar_set_from_string);*/ + dvar_set_bool_hook.create(SELECT_VALUE(0x0, 0x185520_b), &dvar_set_bool); // good + dvar_set_float_hook.create(SELECT_VALUE(0x0, 0x185AA0_b), &dvar_set_float); // good + dvar_set_int_hook.create(SELECT_VALUE(0x0, 0x185D10_b), &dvar_set_int); // good + dvar_set_string_hook.create(SELECT_VALUE(0x0, 0x186080_b), &dvar_set_string); // good + dvar_set_from_string_hook.create(SELECT_VALUE(0x0, 0x185C60_b), &dvar_set_from_string); // good } }; } diff --git a/src/client/component/localized_strings.cpp b/src/client/component/localized_strings.cpp index cd9d4718..207a62e5 100644 --- a/src/client/component/localized_strings.cpp +++ b/src/client/component/localized_strings.cpp @@ -49,4 +49,4 @@ namespace localized_strings }; } -//REGISTER_COMPONENT(localized_strings::component) +REGISTER_COMPONENT(localized_strings::component) \ No newline at end of file diff --git a/src/client/component/server_list.cpp b/src/client/component/server_list.cpp index cca9fd72..342ba50e 100644 --- a/src/client/component/server_list.cpp +++ b/src/client/component/server_list.cpp @@ -366,13 +366,13 @@ namespace server_list lui_open_menu_hook.create(game::LUI_OpenMenu, lui_open_menu_stub); // replace UI_RunMenuScript call in LUI_CoD_LuaCall_RefreshServerList to our refresh_servers - utils::hook::call(0x14018A0C9, &refresh_server_list); - utils::hook::call(0x14018A5DE, &join_server); - utils::hook::nop(0x14018A5FD, 5); + utils::hook::call(0x28E049_b, &refresh_server_list); + utils::hook::call(0x28E55E_b, &join_server); + utils::hook::nop(0x28E57D_b, 5); // do feeder stuff - utils::hook::call(0x14018A199, &ui_feeder_count); - utils::hook::call(0x14018A3B1, &ui_feeder_item_text); + utils::hook::call(0x28E119_b, &ui_feeder_count); + utils::hook::call(0x28E331_b, &ui_feeder_item_text); scheduler::loop(do_frame_work, scheduler::pipeline::main); diff --git a/src/client/component/stats.cpp b/src/client/component/stats.cpp index 7c373b29..af886473 100644 --- a/src/client/component/stats.cpp +++ b/src/client/component/stats.cpp @@ -69,9 +69,9 @@ namespace stats if (game::environment::is_dedi()) { - utils::hook::jump(0x140413E60, is_item_unlocked); - utils::hook::jump(0x140413860, is_item_unlocked); - utils::hook::jump(0x140412B70, is_item_unlocked); + utils::hook::jump(0x19E6E0_b, is_item_unlocked); + utils::hook::jump(0x19E070_b, is_item_unlocked); + utils::hook::jump(0x19D390_b, is_item_unlocked); } else { @@ -80,12 +80,12 @@ namespace stats dvars::register_bool("cg_unlockall_classes", false, game::DVAR_FLAG_SAVED, "Whether classes should be locked based on the player's stats or always unlocked."); - is_item_unlocked_hook.create(0x140413E60, is_item_unlocked_stub); - is_item_unlocked_hook2.create(0x140413860, is_item_unlocked_stub2); - is_item_unlocked_hook3.create(0x140412B70, is_item_unlocked_stub3); + is_item_unlocked_hook.create(0x19E6E0_b, is_item_unlocked_stub); + is_item_unlocked_hook2.create(0x19E070_b, is_item_unlocked_stub2); + is_item_unlocked_hook3.create(0x19D390_b, is_item_unlocked_stub3); } } }; } -//REGISTER_COMPONENT(stats::component) +REGISTER_COMPONENT(stats::component) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 92c1fe01..1223c64a 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -35,7 +35,7 @@ namespace game WEAK symbol Com_GetCurrentCoDPlayMode{0x0, 0x5AEF80}; WEAK symbol Com_InFrontend{0x0, 0x76A40}; WEAK symbol Com_SetSlowMotion{0x0, 0x17E5F0}; - WEAK symbol Com_Error{0x0, 0x0}; + WEAK symbol Com_Error{0x0, 0x159860}; WEAK symbol Com_Quit_f{0x0, 0x1F9280}; WEAK symbol Com_Shutdown{0x0, 0x0}; From ad716d75713abb264cf4b04ac564c7062cf03c19 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 00:36:32 +0200 Subject: [PATCH 199/346] Party connect --- src/client/component/auth.cpp | 69 ++++++++++++++++++++------------ src/client/component/network.cpp | 34 +++++++--------- src/client/component/party.cpp | 44 ++++++++++---------- src/client/game/game.cpp | 4 ++ src/client/game/symbols.hpp | 22 +++++----- 5 files changed, 96 insertions(+), 77 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index f633f740..8cda99a5 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -89,7 +89,7 @@ namespace auth return utils::string::va("0x%lX", value); } - int send_connect_data_stub(game::netsrc_t sock, game::netadr_s* adr, const char* format, const int len) + bool send_connect_data(game::netsrc_t sock, game::netadr_s* adr, const char* format, const int len) { std::string connect_string(format, len); game::SV_Cmd_TokenizeString(connect_string.data()); @@ -162,7 +162,7 @@ namespace auth if (xuid != key.get_hash()) { - //MessageBoxA(nullptr, steam_id.data(), std::to_string(key.get_hash()).data(), 0); + MessageBoxA(nullptr, steam_id.data(), std::to_string(key.get_hash()).data(), 0); network::send(*from, "error", utils::string::va("XUID doesn't match the certificate: %llX != %llX", xuid, key.get_hash()), '\n'); return; @@ -177,22 +177,43 @@ namespace auth game::SV_DirectConnect(from); } - // CAN'T FIND - //void* get_direct_connect_stub() - //{ - // return utils::hook::assemble([](utils::hook::assembler& a) - // { - // a.lea(rcx, qword_ptr(rsp, 0x20)); - // a.movaps(xmmword_ptr(rsp, 0x20), xmm0); + void* get_direct_connect_stub() + { + return utils::hook::assemble([](utils::hook::assembler& a) + { + a.lea(rcx, qword_ptr(rsp, 0x20)); + a.movaps(xmmword_ptr(rsp, 0x20), xmm0); - // a.pushad64(); - // a.mov(rdx, rsi); - // a.call_aligned(direct_connect); - // a.popad64(); + a.pushad64(); + a.mov(rdx, rsi); + a.call_aligned(direct_connect); + a.popad64(); - // a.jmp(0x140488CE2); // H1MP64(1.4) - // }); - //} + a.jmp(0x1CAF64_b); + }); + } + + void* get_send_connect_data_stub() + { + return utils::hook::assemble([](utils::hook::assembler& a) + { + const auto false_ = a.newLabel(); + const auto original = a.newLabel(); + + a.mov(ecx, eax); + a.lea(r8, qword_ptr(rbp, 0x4C0)); + a.mov(r9d, ebx); + a.lea(rdx, qword_ptr(rsp, 0x30)); + + a.pushad64(); + a.call_aligned(send_connect_data); + a.test(al, al); + a.popad64(); + + a.mov(rbx, qword_ptr(rsp, 0x9F0)); + a.jmp(0x12D446_b); + }); + } } uint64_t get_guid() @@ -228,19 +249,17 @@ namespace auth utils::hook::nop(0x1D7553_b, 0x1D7587 - 0x1D7553); // STEAM MAYBE `1401D7553` ON FIRST utils::hook::nop(0x1D7A82_b, 0x1D7AC8 - 0x1D7A82); // STEAM*/ - //utils::hook::jump(0x140488BC1, get_direct_connect_stub(), true); // H1(1.4) can't find - //utils::hook::call(0x12D437_b, send_connect_data_stub); // H1(1.4) + utils::hook::jump(0x1CAE70_b, get_direct_connect_stub(), true); + utils::hook::jump(0x12D426_b, get_send_connect_data_stub(), true); - // Skip checks for sending connect packet - //utils::hook::jump(0x1402508FC, 0x140250946); // Don't instantly timeout the connecting client ? not sure about this - //utils::hook::set(0x14025136B, 0xC3); + utils::hook::set(0x12D93C_b, 0xC3); } - //command::add("guid", []() - //{ - // printf("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits); - //}); + command::add("guid", []() + { + printf("Your guid: %llX\n", steam::SteamUser()->GetSteamID().bits); + }); } }; } diff --git a/src/client/component/network.cpp b/src/client/component/network.cpp index 88d5ccb7..5f77a26b 100644 --- a/src/client/component/network.cpp +++ b/src/client/component/network.cpp @@ -116,11 +116,11 @@ namespace network address.sin_family = AF_INET; address.sin_port = ntohs(static_cast(port)); - const auto sock = ::socket(AF_INET, SOCK_DGRAM, protocol); + const auto sock = socket(AF_INET, SOCK_DGRAM, protocol); u_long arg = 1; ioctlsocket(sock, FIONBIO, &arg); - char optval[4] = { 1 }; + char optval[4] = {1}; setsockopt(sock, 0xFFFF, 32, optval, 4); if (bind(sock, reinterpret_cast(&address), sizeof(address)) != -1) @@ -229,8 +229,8 @@ namespace network } // redirect dw_sendto to raw socket - utils::hook::call(0x5BDB47_b, dw_send_to_stub); - utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub); + utils::hook::jump(0x5EEC90_b, dw_send_to_stub, true); + utils::hook::jump(game::Sys_SendPacket, dw_send_to_stub, true); // intercept command handling utils::hook::jump(0x12F387_b, utils::hook::assemble(handle_command_stub), true); @@ -238,8 +238,8 @@ namespace network // handle xuid without secure connection utils::hook::nop(0x554222_b, 6); - utils::hook::jump(0x4F1800_b, net_compare_address); - utils::hook::jump(0x4F1850_b, net_compare_base_address); + utils::hook::jump(0x4F1800_b, net_compare_address, true); + utils::hook::jump(0x4F1850_b, net_compare_base_address, true); // don't establish secure conenction utils::hook::set(0x358C8D_b, 0xEB); @@ -248,33 +248,29 @@ namespace network utils::hook::set(0x12CD0F_b, 0xEB); // ignore unregistered connection - utils::hook::jump(0x54E2D1_b, 0x54E270_b); + utils::hook::jump(0x54E2D1_b, 0x54E270_b, true); utils::hook::set(0x54E2C6_b, 0xEB); // disable xuid verification utils::hook::set(0x728BF_b, 0xEB); - //utils::hook::set(0x14005B649, 0xEB); // not found // disable xuid verification utils::hook::nop(0x5509D9_b, 2); utils::hook::set(0x550A36_b, 0xEB); // ignore configstring mismatch - //utils::hook::set(0x1402591C9, 0xEB); // not found + utils::hook::set(0x341261_b, 0xEB); // ignore dw handle in SV_PacketEvent utils::hook::set(0x1CBC22_b, 0xEB); - utils::hook::call(0x1CBC16_b, &net_compare_address); + utils::hook::jump(0x4F1850_b, &net_compare_address, true); // ignore dw handle in SV_FindClientByAddress utils::hook::set(0x1CB24D_b, 0xEB); - utils::hook::call(0x1CB241_b, &net_compare_address); // ignore dw handle in SV_DirectConnect utils::hook::set(0x54DFE8_b, 0xEB); utils::hook::set(0x54E1FD_b, 0xEB); - utils::hook::call(0x54DFDB_b, &net_compare_address); - utils::hook::call(0x54E1F0_b, &net_compare_address); // increase cl_maxpackets dvars::override::register_int("cl_maxpackets", 1000, 1, 1000, game::DVAR_FLAG_SAVED); @@ -283,7 +279,7 @@ namespace network dvars::override::register_int("sv_remote_client_snapshot_msec", 33, 33, 100, game::DVAR_FLAG_NONE); // ignore impure client - utils::hook::jump(0x54EDD3_b, 0x54EE69_b); + utils::hook::jump(0x54EDD3_b, 0x54EE69_b, true); // don't send checksum utils::hook::set(0x59E628_b, 0); @@ -292,12 +288,12 @@ namespace network utils::hook::set(0x59E8B0_b, 0xC301B0); // don't try to reconnect client - utils::hook::call(0x54E18C_b, reconnect_migratated_client); + utils::hook::jump(0x54D220_b, reconnect_migratated_client, true); utils::hook::nop(0x54E168_b, 4); // this crashes when reconnecting for some reason // allow server owner to modify net_port before the socket bind - utils::hook::call(0x5BD2B5_b, register_netport_stub); - utils::hook::call(0x5BD3F0_b, register_netport_stub); + // utils::hook::call(0x5BD2B5_b, register_netport_stub); + // utils::hook::call(0x5BD3F0_b, register_netport_stub); // increase allowed packet size const auto max_packet_size = 0x20000; @@ -316,10 +312,10 @@ namespace network // Use our own socket since the game's socket doesn't work with non localhost addresses // why? no idea - utils::hook::jump(0x5BD210_b, create_socket); + utils::hook::jump(0x5BD210_b, create_socket, true); } } }; } -//REGISTER_COMPONENT(network::component) +REGISTER_COMPONENT(network::component) diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 3638d266..fda85945 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -71,11 +71,11 @@ namespace party perform_game_initialization(); // exit from virtuallobby - utils::hook::invoke(0x140256D40, 1); + utils::hook::invoke(0x13C9C0_b, 1); // CL_ConnectFromParty char session_info[0x100] = {}; - utils::hook::invoke(0x140251560, 0, session_info, &target, mapname.data(), gametype.data()); + utils::hook::invoke(0x12DFF0_b, 0, session_info, &target, mapname.data(), gametype.data()); } std::string get_dvar_string(const std::string& dvar) @@ -129,12 +129,12 @@ namespace party if (game::CL_IsCgameInitialized()) { // CL_ForwardCommandToServer - utils::hook::invoke(0x140253480, 0, "disconnect"); + // utils::hook::invoke(0x140253480, 0, "disconnect"); // CL_WritePacket - utils::hook::invoke(0x14024DB10, 0); + // utils::hook::invoke(0x14024DB10, 0); } // CL_Disconnect - utils::hook::invoke(0x140252060, 0); + // utils::hook::invoke(0x140252060, 0); } } @@ -148,15 +148,15 @@ namespace party const auto drop_reason_stub = utils::hook::assemble([](utils::hook::assembler& a) { - a.mov(rdx, rdi); - a.mov(ecx, 2); - a.jmp(0x140251F78); + // a.mov(rdx, rdi); + // a.mov(ecx, 2); + // a.jmp(0x140251F78); }); void menu_error(const std::string& error) { - utils::hook::invoke(0x1400DACC0, error.data(), "MENU_NOTICE"); - utils::hook::set(0x142C1DA98, 1); + //utils::hook::invoke(0x1400DACC0, error.data(), "MENU_NOTICE"); + //utils::hook::set(0x142C1DA98, 1); } } @@ -318,20 +318,20 @@ namespace party } // hook disconnect command function - utils::hook::jump(0x1402521C7, disconnect_stub); + // utils::hook::jump(0x1402521C7, disconnect_stub); // detour CL_Disconnect to clear motd - cldisconnect_hook.create(0x140252060, cl_disconnect_stub); + // cldisconnect_hook.create(0x140252060, cl_disconnect_stub); if (game::environment::is_mp()) { // show custom drop reason - utils::hook::nop(0x140251EFB, 13); - utils::hook::jump(0x140251EFB, drop_reason_stub, true); + // utils::hook::nop(0x140251EFB, 13); + // utils::hook::jump(0x140251EFB, drop_reason_stub, true); } // enable custom kick reason in GScr_KickPlayer - utils::hook::set(0x140376A1D, 0xEB); + // utils::hook::set(0x140376A1D, 0xEB); command::add("map", [](const command::params& argument) { @@ -349,11 +349,11 @@ namespace party { return; } - *reinterpret_cast(0x14A3A91D0) = 1; // sv_map_restart - *reinterpret_cast(0x14A3A91D4) = 1; // sv_loadScripts - *reinterpret_cast(0x14A3A91D8) = 0; // sv_migrate + // *reinterpret_cast(0x14A3A91D0) = 1; // sv_map_restart + // *reinterpret_cast(0x14A3A91D4) = 1; // sv_loadScripts + // *reinterpret_cast(0x14A3A91D8) = 0; // sv_migrate - utils::hook::invoke(0x14047E7F0); // SV_CheckLoadGame + // utils::hook::invoke(0x14047E7F0); // SV_CheckLoadGame }); command::add("fast_restart", []() @@ -546,7 +546,7 @@ namespace party printf("%s\n", message.data()); }); - utils::hook::call(0x1404C6E8D, didyouknow_stub); // allow custom didyouknow based on sv_motd + // utils::hook::call(0x1404C6E8D, didyouknow_stub); // allow custom didyouknow based on sv_motd network::on("getInfo", [](const game::netadr_s& target, const std::string_view& data) { @@ -573,7 +573,7 @@ namespace party network::on("infoResponse", [](const game::netadr_s& target, const std::string_view& data) { const utils::info_string info{data}; - server_list::handle_info_response(target, info); + // server_list::handle_info_response(target, info); if (connect_state.host != target) { @@ -642,4 +642,4 @@ namespace party }; } -//REGISTER_COMPONENT(party::component) \ No newline at end of file +REGISTER_COMPONENT(party::component) \ No newline at end of file diff --git a/src/client/game/game.cpp b/src/client/game/game.cpp index 980d3ad1..f7c4a2ba 100644 --- a/src/client/game/game.cpp +++ b/src/client/game/game.cpp @@ -39,9 +39,13 @@ namespace game void SV_GameSendServerCommand(int clientNum, svscmd_type type, const char* text) { if (clientNum == -1) + { SV_SendServerCommand(0, type, "%s", text); + } else + { SV_SendServerCommand(&mp::svs_clients[clientNum], type, "%s", text); + } } namespace environment diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 1223c64a..424d035c 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -105,10 +105,10 @@ namespace game WEAK symbol Material_RegisterHandle{0x0, 0x692360}; - WEAK symbol NetadrToSockadr{0x0, 0x0}; - WEAK symbol NET_OutOfBandPrint{0x0, 0x0}; - WEAK symbol NET_SendLoopPacket{0x0, 0x0}; - WEAK symbol NET_StringToAdr{0x0, 0x0}; + WEAK symbol NetadrToSockadr{0x0, 0x59E580}; + WEAK symbol NET_OutOfBandPrint{0x0, 0x4F1EB0}; + WEAK symbol NET_SendLoopPacket{0x0, 0x4F2070}; + WEAK symbol NET_StringToAdr{0x0, 0x4F2150}; WEAK symbol R_AddCmdDrawStretchPic{0x0, 0x0}; @@ -167,13 +167,13 @@ namespace game WEAK symbol SL_ConvertToString{0x0, 0x0}; WEAK symbol SL_GetCanonicalString{0x0, 0x0}; - WEAK symbol SV_DirectConnect{0x0, 0x0}; + WEAK symbol SV_DirectConnect{0x0, 0x54DBF0}; WEAK symbol SV_Cmd_ArgvBuffer{0x0, 0x0}; - WEAK symbol SV_Cmd_TokenizeString{0x0, 0x0}; - WEAK symbol SV_Cmd_EndTokenizedString{0x0, 0x0}; + WEAK symbol SV_Cmd_TokenizeString{0x0, 0x1CACE0}; + WEAK symbol SV_Cmd_EndTokenizedString{0x0, 0x1CACA0}; WEAK symbol SV_AddBot{0x0, 0x0}; - WEAK symbol SV_BotIsBot{0x0, 0x0}; + WEAK symbol SV_BotIsBot{0x0, 0x53B6D0}; WEAK symbol SV_BotGetRandomName{0x0, 0x0}; WEAK symbol SV_SpawnTestClient{0x0, 0x0}; @@ -194,7 +194,7 @@ namespace game Sys_BuildAbsPath{0x0, 0x0}; WEAK symbol Sys_Milliseconds{0x0, 0x0}; WEAK symbol Sys_IsDatabaseReady2{0x0, 0x4F79C0}; - WEAK symbol Sys_SendPacket{0x0, 0x0}; + WEAK symbol Sys_SendPacket{0x0, 0x5BDA90}; WEAK symbol Sys_FileExists{0x0, 0x0}; WEAK symbol UI_GetMapDisplayName{0x0, 0x0}; @@ -211,7 +211,7 @@ namespace game * Variables **************************************************************/ - WEAK symbol sv_cmd_args{0x0, 0x0}; + WEAK symbol sv_cmd_args{0x0, 0x2ED1EB0}; WEAK symbol g_script_error_level{0x0, 0x0}; WEAK symbol g_script_error{0x0, 0x0}; @@ -241,7 +241,7 @@ namespace game WEAK symbol keyCatchers{0x0, 0x2EC82C4}; WEAK symbol playerKeys{0x0, 0x0}; - WEAK symbol query_socket{0x0, 0x0}; + WEAK symbol query_socket{0x0, 0xC9DCD38}; WEAK symbol threadIds{0x0, 0x0}; From 5bac327e7b2c5f50e196b637c5b73245e57de0b0 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 00:44:04 +0200 Subject: [PATCH 200/346] Comment this --- src/client/component/auth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 8cda99a5..6b19fb87 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -162,7 +162,7 @@ namespace auth if (xuid != key.get_hash()) { - MessageBoxA(nullptr, steam_id.data(), std::to_string(key.get_hash()).data(), 0); + //MessageBoxA(nullptr, steam_id.data(), std::to_string(key.get_hash()).data(), 0); network::send(*from, "error", utils::string::va("XUID doesn't match the certificate: %llX != %llX", xuid, key.get_hash()), '\n'); return; From 6754420e8477d5e846199c267a2ea1677be2aba8 Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 19 May 2022 01:45:52 +0300 Subject: [PATCH 201/346] Update README.md [skip ci] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 61080be3..d5129478 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

An experimental client for Call of Duty Modern Warfare Remastered (version `1.4.814118.0-0.32767`). -Research for the latest Steam version of the game is on the `1.15` branch. +Research for the latest Steam version of the game is on the [1.15](https://github.com/h1-mod/h1-mod/tree/1.15) branch. [This project is based on S1x.](https://github.com/XLabsProject/s1x-client) From 9f8c47eaae4762d6bf2ddc64385d5fb948da1dfd Mon Sep 17 00:00:00 2001 From: Skull Merlin <86374920+skkuull@users.noreply.github.com> Date: Thu, 19 May 2022 01:53:59 +0300 Subject: [PATCH 202/346] change note & typo's [skip ci] --- src/client/component/dedicated.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index 15a4bd80..b0c9d841 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -207,7 +207,8 @@ namespace dedicated // delay startup commands until the initialization is done utils::hook::call(0x157DDA_b, execute_startup_command); - // delay console commands until the initialization is done // COULDN'T FOUND + // Cbuf_AddText is inlined + // delay console commands until the initialization is done //utils::hook::call(0x1400D808C, execute_console_command); //utils::hook::nop(0x1400D80A4, 5); @@ -242,8 +243,8 @@ namespace dedicated utils::hook::set(0x690F30_b, 0xC3); // gfx stuff during fastfile loading utils::hook::set(0x690E00_b, 0xC3); // ^ utils::hook::set(0x690ED0_b, 0xC3); // ^ - //utils::hook::set(0x1402C1180, 0xC3); // ^ NOT FOUND? - utils::hook::set(0x690E50_b, 0xC3); // ^ MAAAAAAAAAAAYBE NOTTTT + //utils::hook::set(0x1402C1180, 0xC3); // ^ NOT FOUND + utils::hook::set(0x690E50_b, 0xC3); // ^ NOT SURE utils::hook::set(0x651BA0_b, 0xC3); // directx stuff utils::hook::set(0x681950_b, 0xC3); // ^ utils::hook::set(0x6CE390_b, 0xC3); // ^ - mutex @@ -267,7 +268,7 @@ namespace dedicated utils::hook::set(0x687D20_b, 0xC3); // R_Shutdown utils::hook::set(0x652BA0_b, 0xC3); // shutdown stuff utils::hook::set(0x687DF0_b, 0xC3); // ^ - //utils::hook::set(0x1405DFE50, 0xC3); // ^ COULDN'T FOUND + //utils::hook::set(0x1405DFE50, 0xC3); // ^ NOT FOUND // utils::hook::set(0x1404B67E0, 0xC3); // sound crashes (H1 - questionable, function looks way different) From 16867939e25197a6a602f0c9edbb3e855b5adc45 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 18 May 2022 18:17:03 -0500 Subject: [PATCH 203/346] find missing addresses, still needs revision --- src/client/component/dedicated.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index b0c9d841..e1558865 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -207,21 +207,20 @@ namespace dedicated // delay startup commands until the initialization is done utils::hook::call(0x157DDA_b, execute_startup_command); - // Cbuf_AddText is inlined // delay console commands until the initialization is done - //utils::hook::call(0x1400D808C, execute_console_command); - //utils::hook::nop(0x1400D80A4, 5); + //utils::hook::call(0x1400D808C, execute_console_command); // Cbuf_AddText is inlined + //utils::hook::nop(0x1400D80A4, 5); // ^ // patch GScr_SetDynamicDvar to behave better gscr_set_dynamic_dvar_hook.create(0x43CF60_b, &gscr_set_dynamic_dvar); - //utils::hook::nop(0x1404ED90E, 5); // don't load config file // NOT FOUND - utils::hook::nop(0x156C46_b, 5); // ^ // NOT SURE + //utils::hook::nop(0x1404ED90E, 5); // don't load config file (NOTE: Cbuf_AddText is inlined) + utils::hook::nop(0x156C46_b, 5); // ^ utils::hook::set(0x17F470_b, 0xC3); // don't save config file utils::hook::set(0x351AA0_b, 0xC3); // disable self-registration utils::hook::set(0x5BF4E0_b, 0xC3); // init sound system (1) - utils::hook::set(0x702650_b, 0xC3); // init sound system (2) NOT SURE - //utils::hook::set(0x140620D10, 0xC3); // render thread ARXAN'D + utils::hook::set(0x701820_b, 0xC3); // init sound system (2) (Skull says 0x702650, I say otherwise) + utils::hook::set(0x6C9B10_b, 0xC3); // render thread utils::hook::set(0x343950_b, 0xC3); // called from Com_Frame, seems to do renderer stuff utils::hook::set(0x12CCA0_b, 0xC3); // CL_CheckForResend, which tries to connect to the local server constantly utils::hook::set(0x67ADCE_b, 0x00); // r_loadForRenderer default to 0 NOT SURE @@ -243,8 +242,8 @@ namespace dedicated utils::hook::set(0x690F30_b, 0xC3); // gfx stuff during fastfile loading utils::hook::set(0x690E00_b, 0xC3); // ^ utils::hook::set(0x690ED0_b, 0xC3); // ^ - //utils::hook::set(0x1402C1180, 0xC3); // ^ NOT FOUND - utils::hook::set(0x690E50_b, 0xC3); // ^ NOT SURE + utils::hook::set(0x39C610_b, 0xC3); // ^ + utils::hook::set(0x690E50_b, 0xC3); // ^ utils::hook::set(0x651BA0_b, 0xC3); // directx stuff utils::hook::set(0x681950_b, 0xC3); // ^ utils::hook::set(0x6CE390_b, 0xC3); // ^ - mutex @@ -268,7 +267,7 @@ namespace dedicated utils::hook::set(0x687D20_b, 0xC3); // R_Shutdown utils::hook::set(0x652BA0_b, 0xC3); // shutdown stuff utils::hook::set(0x687DF0_b, 0xC3); // ^ - //utils::hook::set(0x1405DFE50, 0xC3); // ^ NOT FOUND + utils::hook::set(0x686DE0_b, 0xC3); // ^ // utils::hook::set(0x1404B67E0, 0xC3); // sound crashes (H1 - questionable, function looks way different) From b14af3433ec8bc6dde0565a36cd67b02b0d90852 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 18 May 2022 19:14:06 -0500 Subject: [PATCH 204/346] input + game console, symbol changes playerKeys isn't working though :P --- src/client/component/game_console.cpp | 11 ++++++----- src/client/component/input.cpp | 7 +++++-- src/client/game/symbols.hpp | 18 +++++++++--------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index 95816851..a0f34f28 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -391,7 +391,7 @@ namespace game_console const auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f; const auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f; - game::R_AddCmdDrawText("H1-Mod 1.4", 0x7FFFFFFF, console_font, x, + game::R_AddCmdDrawText("H1-Mod 1.15", 0x7FFFFFFF, console_font, x, ((height - 16.0f) + y) + console_font->pixelHeight, 1.0f, 1.0f, 0.0f, color_title, 0); draw_output_scrollbar(x, y, width, height, output); @@ -586,7 +586,9 @@ namespace game_console return false; } - if (game::playerKeys[local_client_num].keys[game::keyNum_t::K_SHIFT].down) + const auto shift_down = game::playerKeys[local_client_num].keys[game::keyNum_t::K_SHIFT].down; + console::info("shift down? %d", shift_down); + if (shift_down) { if (!(*game::keyCatchers & 1)) toggle_console(); @@ -721,14 +723,13 @@ namespace game_console return; } - //scheduler::loop(draw_console, scheduler::pipeline::renderer); + scheduler::loop(draw_console, scheduler::pipeline::renderer); } void post_unpack() override { scheduler::loop(draw_console, scheduler::pipeline::renderer); - if (game::environment::is_dedi()) { return; @@ -797,4 +798,4 @@ namespace game_console }; } -//REGISTER_COMPONENT(game_console::component) +REGISTER_COMPONENT(game_console::component) diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index ad615b34..45f55e08 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -16,9 +16,9 @@ namespace input utils::hook::detour cl_char_event_hook; utils::hook::detour cl_key_event_hook; - void cl_char_event_stub(const int local_client_num, const int key) { + /* if (ui_scripting::lui_running()) { ui_scripting::notify("keypress", @@ -27,6 +27,7 @@ namespace input {"key", game::Key_KeynumToString(key, 0, 1)}, }); } + */ if (!game_console::console_char_event(local_client_num, key)) { @@ -38,6 +39,7 @@ namespace input void cl_key_event_stub(const int local_client_num, const int key, const int down) { + /* if (ui_scripting::lui_running()) { ui_scripting::notify(down ? "keydown" : "keyup", @@ -46,6 +48,7 @@ namespace input {"key", game::Key_KeynumToString(key, 0, 1)}, }); } + */ if (!game_console::console_key_event(local_client_num, key, down)) { @@ -72,4 +75,4 @@ namespace input }; } -//REGISTER_COMPONENT(input::component) +REGISTER_COMPONENT(input::component) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 424d035c..c943c028 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -48,7 +48,7 @@ namespace game WEAK symbol CG_GetWeaponDisplayName{0x0, 0x0}; - WEAK symbol CL_IsCgameInitialized{0x0, 0x76A40}; + WEAK symbol CL_IsCgameInitialized{0x0, 0x33C640}; WEAK symbol CL_VirtualLobbyShutdown{0x0, 0x0}; WEAK symbol Dvar_SetCommand{0x0, 0x1857D0}; @@ -69,7 +69,7 @@ namespace game WEAK symbol Dvar_RegisterString{0x0, 0x182AF0}; WEAK symbol Dvar_RegisterVec4{0x0, 0x0}; + float w, float min, float max, unsigned int flags)> Dvar_RegisterVec4{0x0, 0x183010}; WEAK symbol FS_ReadFile{0x0, 0x0}; WEAK symbol FS_FreeFile{0x0, 0x0}; @@ -111,9 +111,9 @@ namespace game WEAK symbol NET_StringToAdr{0x0, 0x4F2150}; WEAK symbol R_AddCmdDrawStretchPic{0x0, 0x0}; + float* color, Material* material)> R_AddCmdDrawStretchPic{0x0, 0x33B2B0}; WEAK symbol R_RegisterFont{0x0, 0x67F630}; - WEAK symbol R_TextWidth{0x0, 0x0}; + WEAK symbol R_TextWidth{0x0, 0x67F8F0}; WEAK symbol R_GetFontHeight{0x0, 0x67F710}; WEAK symbol R_DrawSomething{0x0, 0x67ECE0}; WEAK symbol R_SyncRenderThread{0x0, 0x0}; @@ -144,7 +144,7 @@ namespace game WEAK symbol Scr_GetEntityId{0x0, 0x0}; WEAK symbol Scr_SetObjectField{0x0, 0x0}; - WEAK symbol ScrPlace_GetViewPlacement{0x0, 0x0}; + WEAK symbol ScrPlace_GetViewPlacement{0x0, 0x362840}; WEAK symbol DB_EnumXAssets_Internal{0x0, 0x0}; @@ -181,7 +181,7 @@ namespace game WEAK symbol SV_GetClientPing{0x0, 0x0}; WEAK symbol SV_GetPlayerstateForClientNum{0x0, 0x0}; WEAK symbol SV_SetConfigstring{0x0, 0x0}; - WEAK symbol SV_Loaded{0x0, 0x0}; + WEAK symbol SV_Loaded{0x0, 0x553970}; WEAK symbol SV_KickClientNum{0x0, 0x0}; WEAK symbol SV_MapExists{0x0, 0x0}; WEAK symbol SV_ExecuteClientCommand{0x0, 0x0}; @@ -198,11 +198,11 @@ namespace game WEAK symbol Sys_FileExists{0x0, 0x0}; WEAK symbol UI_GetMapDisplayName{0x0, 0x0}; - WEAK symbol UI_GetGameTypeDisplayName{0x0, 0x0}; + WEAK symbol UI_GetGameTypeDisplayName{0x0, 0x4DD8C0}; WEAK symbol UI_RunMenuScript{0x0, 0x0}; WEAK symbol UI_TextWidth{0x0, 0x0}; - WEAK symbol UI_SafeTranslateString{0x0, 0x0}; + WEAK symbol UI_SafeTranslateString{0x0, 0x4E8BC0}; WEAK symbol longjmp{0x0, 0x0}; WEAK symbol _setjmp{0x0, 0x0}; @@ -239,7 +239,7 @@ namespace game WEAK symbol g_assetNames{0x0, 0x0}; WEAK symbol keyCatchers{0x0, 0x2EC82C4}; - WEAK symbol playerKeys{0x0, 0x0}; + WEAK symbol playerKeys{0x0, 0x2999D00}; WEAK symbol query_socket{0x0, 0xC9DCD38}; From 8531a72a94dc410fff94144e043c86b466db1adc Mon Sep 17 00:00:00 2001 From: m Date: Wed, 18 May 2022 19:14:19 -0500 Subject: [PATCH 205/346] document `dvl` dvar [skip ci] --- src/client/component/patches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 3d4fedbe..73fdbdfe 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -235,7 +235,7 @@ namespace patches // utils::hook::nop(0x140190C16, 5); utils::hook::set(0x307F39_b, 0xEB); - // some anti tamper thing that kills performance (not needed in H1?) + // some [data validation] anti tamper thing that kills performance dvars::override::register_int("dvl", 0, 0, 0, game::DVAR_FLAG_READ); // unlock safeArea_* From b4e78484b8a46d11ac39d7e17efe1307e3310579 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 02:27:46 +0200 Subject: [PATCH 206/346] Almost finish dedi --- src/client/component/dedicated.cpp | 44 ++++++++++++++++-------------- src/client/component/fastfiles.cpp | 4 +-- src/client/component/stats.cpp | 8 +++--- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index e1558865..5ff6fa3c 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -197,34 +197,35 @@ namespace dedicated dvars::override::register_bool("r_preloadShaders", false, game::DVAR_FLAG_READ); // Stop crashing from sys_errors - utils::hook::jump(0x1D8710_b, sys_error_stub); + utils::hook::jump(0x1D8710_b, sys_error_stub, true); // Hook R_SyncGpu - utils::hook::jump(0x688620_b, sync_gpu_stub); + utils::hook::jump(0x688620_b, sync_gpu_stub, true); - utils::hook::jump(0x135600_b, init_dedicated_server); + utils::hook::jump(0x135600_b, init_dedicated_server, true); // delay startup commands until the initialization is done - utils::hook::call(0x157DDA_b, execute_startup_command); + // utils::hook::call(0x157DDA_b, execute_startup_command); - // delay console commands until the initialization is done - //utils::hook::call(0x1400D808C, execute_console_command); // Cbuf_AddText is inlined - //utils::hook::nop(0x1400D80A4, 5); // ^ + // delay console commands until the initialization is done // COULDN'T FOUND + // utils::hook::call(0x1400D808C, execute_console_command); + // utils::hook::nop(0x1400D80A4, 5); // patch GScr_SetDynamicDvar to behave better gscr_set_dynamic_dvar_hook.create(0x43CF60_b, &gscr_set_dynamic_dvar); - //utils::hook::nop(0x1404ED90E, 5); // don't load config file (NOTE: Cbuf_AddText is inlined) - utils::hook::nop(0x156C46_b, 5); // ^ + utils::hook::nop(0x189514_b, 248); // don't load config file + utils::hook::nop(0x156C46_b, 5); // ^ // NOT SURE utils::hook::set(0x17F470_b, 0xC3); // don't save config file utils::hook::set(0x351AA0_b, 0xC3); // disable self-registration utils::hook::set(0x5BF4E0_b, 0xC3); // init sound system (1) - utils::hook::set(0x701820_b, 0xC3); // init sound system (2) (Skull says 0x702650, I say otherwise) + utils::hook::set(0x701820_b, 0xC3); // init sound system (2) + utils::hook::set(0x701850_b, 0xC3); // init sound system (3) utils::hook::set(0x6C9B10_b, 0xC3); // render thread utils::hook::set(0x343950_b, 0xC3); // called from Com_Frame, seems to do renderer stuff utils::hook::set(0x12CCA0_b, 0xC3); // CL_CheckForResend, which tries to connect to the local server constantly - utils::hook::set(0x67ADCE_b, 0x00); // r_loadForRenderer default to 0 NOT SURE - utils::hook::set(0x5B7AF0_b, 0xC3); // recommended settings check - TODO: Check hook + utils::hook::set(0x67ADCE_b, 0x00); // r_loadForRenderer default to 0 + utils::hook::set(0x5B7AF0_b, 0xC3); // recommended settings check utils::hook::set(0x5BE850_b, 0xC3); // some mixer-related function called on shutdown utils::hook::set(0x4DEA50_b, 0xC3); // dont load ui gametype stuff @@ -242,14 +243,14 @@ namespace dedicated utils::hook::set(0x690F30_b, 0xC3); // gfx stuff during fastfile loading utils::hook::set(0x690E00_b, 0xC3); // ^ utils::hook::set(0x690ED0_b, 0xC3); // ^ - utils::hook::set(0x39C610_b, 0xC3); // ^ + utils::hook::set(0x39B980_b, 0xC3); // ^ utils::hook::set(0x690E50_b, 0xC3); // ^ utils::hook::set(0x651BA0_b, 0xC3); // directx stuff utils::hook::set(0x681950_b, 0xC3); // ^ utils::hook::set(0x6CE390_b, 0xC3); // ^ - mutex utils::hook::set(0x681ED0_b, 0xC3); // ^ - utils::hook::set(0xA3CD0_b, 0xC3); // rendering stuff + utils::hook::set(0x0A3CD0_b, 0xC3); // rendering stuff utils::hook::set(0x682150_b, 0xC3); // ^ utils::hook::set(0x682260_b, 0xC3); // ^ utils::hook::set(0x6829C0_b, 0xC3); // ^ @@ -257,8 +258,8 @@ namespace dedicated utils::hook::set(0x683B40_b, 0xC3); // ^ // shaders - utils::hook::set(0xAA090_b, 0xC3); // ^ - utils::hook::set(0xA9FE0_b, 0xC3); // ^ + utils::hook::set(0x0AA090_b, 0xC3); // ^ + utils::hook::set(0x0A9FE0_b, 0xC3); // ^ utils::hook::set(0x6C38D0_b, 0xC3); // ^ - mutex utils::hook::set(0x5BFD10_b, 0xC3); // idk @@ -267,16 +268,18 @@ namespace dedicated utils::hook::set(0x687D20_b, 0xC3); // R_Shutdown utils::hook::set(0x652BA0_b, 0xC3); // shutdown stuff utils::hook::set(0x687DF0_b, 0xC3); // ^ - utils::hook::set(0x686DE0_b, 0xC3); // ^ + utils::hook::set(0x686DE0_b, 0xC3); // ^ COULDN'T FOUND // utils::hook::set(0x1404B67E0, 0xC3); // sound crashes (H1 - questionable, function looks way different) utils::hook::set(0x556250_b, 0xC3); // disable host migration utils::hook::set(0x4F7C10_b, 0xC3); // render synchronization lock - utils::hook::set(0x42B210_b, 0xC3); // render synchronization unlock + utils::hook::set(0x4F7B40_b, 0xC3); // render synchronization unlock utils::hook::set(0x27AA9D_b, 0xEB); // LUI: Unable to start the LUI system due to errors in main.lua + utils::hook::set(0x27AAC5_b, 0xEB); // LUI: Unable to start the LUI system due to errors in depot.lua + utils::hook::set(0x27AADC_b, 0xEB); // ^ utils::hook::nop(0x5B25BE_b, 5); // Disable sound pak file loading utils::hook::nop(0x5B25C6_b, 2); // ^ @@ -286,7 +289,8 @@ namespace dedicated utils::hook::set(0x5B7F37_b, 0x80000000); utils::hook::set(0x399E10_b, 0xC3); // some loop - utils::hook::set(0x1D48B0_b, 0xC3); // related to shader caching / techsets / fastfiles + utils::hook::set(0x1D48B0_b, 0xC3); // related to shader caching / techsets / fastfilesc + utils::hook::set(0x3A1940_b, 0xC3); // DB_ReadPackedLoadedSounds // initialize the game after onlinedataflags is 32 (workaround) scheduler::schedule([=]() @@ -330,4 +334,4 @@ namespace dedicated }; } -//REGISTER_COMPONENT(dedicated::component) \ No newline at end of file +REGISTER_COMPONENT(dedicated::component) \ No newline at end of file diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index 2cb5ace4..f7fb38c5 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -51,9 +51,9 @@ namespace fastfiles void post_unpack() override { db_try_load_x_file_internal_hook.create( - SELECT_VALUE(0x1401CDDD0, 0x1402BFFE0), &db_try_load_x_file_internal); + SELECT_VALUE(0, 0x39A620_b), &db_try_load_x_file_internal); } }; } -//REGISTER_COMPONENT(fastfiles::component) +REGISTER_COMPONENT(fastfiles::component) diff --git a/src/client/component/stats.cpp b/src/client/component/stats.cpp index af886473..8da3fa78 100644 --- a/src/client/component/stats.cpp +++ b/src/client/component/stats.cpp @@ -69,9 +69,9 @@ namespace stats if (game::environment::is_dedi()) { - utils::hook::jump(0x19E6E0_b, is_item_unlocked); - utils::hook::jump(0x19E070_b, is_item_unlocked); - utils::hook::jump(0x19D390_b, is_item_unlocked); + utils::hook::jump(0x19E6E0_b, is_item_unlocked, true); + utils::hook::jump(0x19E070_b, is_item_unlocked, true); + utils::hook::jump(0x19D390_b, is_item_unlocked, true); } else { @@ -88,4 +88,4 @@ namespace stats }; } -REGISTER_COMPONENT(stats::component) +// REGISTER_COMPONENT(stats::component) From fe1110a580bf0f152f22edd347d268febd59b4a7 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 17:01:34 +0200 Subject: [PATCH 207/346] Some fixes --- src/client/component/dedicated.cpp | 10 +++++----- src/client/component/demonware.cpp | 2 +- src/client/component/party.cpp | 26 +++++++++++++------------- src/client/component/splash.cpp | 8 ++++---- src/client/game/symbols.hpp | 4 ++-- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/client/component/dedicated.cpp b/src/client/component/dedicated.cpp index 5ff6fa3c..3871a764 100644 --- a/src/client/component/dedicated.cpp +++ b/src/client/component/dedicated.cpp @@ -215,7 +215,7 @@ namespace dedicated gscr_set_dynamic_dvar_hook.create(0x43CF60_b, &gscr_set_dynamic_dvar); utils::hook::nop(0x189514_b, 248); // don't load config file - utils::hook::nop(0x156C46_b, 5); // ^ // NOT SURE + utils::hook::nop(0x156C46_b, 5); // ^ utils::hook::set(0x17F470_b, 0xC3); // don't save config file utils::hook::set(0x351AA0_b, 0xC3); // disable self-registration utils::hook::set(0x5BF4E0_b, 0xC3); // init sound system (1) @@ -268,7 +268,7 @@ namespace dedicated utils::hook::set(0x687D20_b, 0xC3); // R_Shutdown utils::hook::set(0x652BA0_b, 0xC3); // shutdown stuff utils::hook::set(0x687DF0_b, 0xC3); // ^ - utils::hook::set(0x686DE0_b, 0xC3); // ^ COULDN'T FOUND + utils::hook::set(0x686DE0_b, 0xC3); // ^ // utils::hook::set(0x1404B67E0, 0xC3); // sound crashes (H1 - questionable, function looks way different) @@ -288,9 +288,9 @@ namespace dedicated // Reduce min required memory utils::hook::set(0x5B7F37_b, 0x80000000); - utils::hook::set(0x399E10_b, 0xC3); // some loop - utils::hook::set(0x1D48B0_b, 0xC3); // related to shader caching / techsets / fastfilesc - utils::hook::set(0x3A1940_b, 0xC3); // DB_ReadPackedLoadedSounds + utils::hook::set(0x399E10_b, 0xC3); // some loop + utils::hook::set(0x1D48B0_b, 0xC3); // related to shader caching / techsets / fastfilesc + utils::hook::set(0x3A1940_b, 0xC3); // DB_ReadPackedLoadedSounds // initialize the game after onlinedataflags is 32 (workaround) scheduler::schedule([=]() diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp index 37bdfdae..632a2422 100644 --- a/src/client/component/demonware.cpp +++ b/src/client/component/demonware.cpp @@ -512,7 +512,7 @@ namespace demonware void request_start_match_stub() { const auto* args = "StartServer"; - utils::hook::invoke(0x1E35B0_b, 0, &args); + game::UI_RunMenuScript(0, &args); } } diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index fda85945..37fd040b 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -148,15 +148,15 @@ namespace party const auto drop_reason_stub = utils::hook::assemble([](utils::hook::assembler& a) { - // a.mov(rdx, rdi); - // a.mov(ecx, 2); - // a.jmp(0x140251F78); + a.mov(rdx, rsi); + a.mov(ecx, 2); + a.jmp(0x12EF27_b); }); void menu_error(const std::string& error) { - //utils::hook::invoke(0x1400DACC0, error.data(), "MENU_NOTICE"); - //utils::hook::set(0x142C1DA98, 1); + utils::hook::invoke(0x17D770_b, error.data(), "MENU_NOTICE"); + utils::hook::set(0x2ED2F78_b, 1); } } @@ -282,7 +282,6 @@ namespace party } console::info("Starting map: %s\n", mapname.data()); - auto* gametype = game::Dvar_FindVar("g_gametype"); if (gametype && gametype->current.string) { @@ -326,12 +325,12 @@ namespace party if (game::environment::is_mp()) { // show custom drop reason - // utils::hook::nop(0x140251EFB, 13); - // utils::hook::jump(0x140251EFB, drop_reason_stub, true); + // utils::hook::nop(0x12EF4E_b, 13); + // utils::hook::jump(0x12EF4E_b, drop_reason_stub, true); } // enable custom kick reason in GScr_KickPlayer - // utils::hook::set(0x140376A1D, 0xEB); + // utils::hook::set(0xE423D_b, 0xEB); command::add("map", [](const command::params& argument) { @@ -349,11 +348,12 @@ namespace party { return; } - // *reinterpret_cast(0x14A3A91D0) = 1; // sv_map_restart - // *reinterpret_cast(0x14A3A91D4) = 1; // sv_loadScripts - // *reinterpret_cast(0x14A3A91D8) = 0; // sv_migrate - // utils::hook::invoke(0x14047E7F0); // SV_CheckLoadGame + *reinterpret_cast(0xB7B8E60_b) = 1; // sv_map_restart + *reinterpret_cast(0xB7B8E64_b) = 1; // sv_loadScripts + *reinterpret_cast(0xB7B8E68_b) = 0; // sv_migrate + + utils::hook::invoke(0x54BD50_b); // SV_CheckLoadGame }); command::add("fast_restart", []() diff --git a/src/client/component/splash.cpp b/src/client/component/splash.cpp index 716be76c..37b0e417 100644 --- a/src/client/component/splash.cpp +++ b/src/client/component/splash.cpp @@ -30,9 +30,9 @@ namespace splash void post_unpack() override { // Disable native splash screen - utils::hook::nop(SELECT_VALUE(0x1403E192E, 0x1405123E2), 5); - utils::hook::jump(SELECT_VALUE(0x1403E2E70, 0x140513AF0), destroy_stub); - utils::hook::jump(SELECT_VALUE(0x1403E2EB0, 0x140513B30), destroy_stub); + utils::hook::set(SELECT_VALUE(0, 0x5BDF20_b), 0xC3); + utils::hook::jump(SELECT_VALUE(0, 0x5BE1D0_b), destroy_stub, true); + utils::hook::jump(SELECT_VALUE(0, 0x5BE210_b), destroy_stub, true); } void pre_destroy() override @@ -138,4 +138,4 @@ namespace splash }; } -//REGISTER_COMPONENT(splash::component) +REGISTER_COMPONENT(splash::component) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index c943c028..fc1cd08d 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -183,7 +183,7 @@ namespace game WEAK symbol SV_SetConfigstring{0x0, 0x0}; WEAK symbol SV_Loaded{0x0, 0x553970}; WEAK symbol SV_KickClientNum{0x0, 0x0}; - WEAK symbol SV_MapExists{0x0, 0x0}; + WEAK symbol SV_MapExists{0x0, 0x54C0C0}; WEAK symbol SV_ExecuteClientCommand{0x0, 0x0}; WEAK symbol SV_FastRestart{0x0, 0x0}; WEAK symbol SV_SendServerCommand{0x0, 0x1CC040}; @@ -199,7 +199,7 @@ namespace game WEAK symbol UI_GetMapDisplayName{0x0, 0x0}; WEAK symbol UI_GetGameTypeDisplayName{0x0, 0x4DD8C0}; - WEAK symbol UI_RunMenuScript{0x0, 0x0}; + WEAK symbol UI_RunMenuScript{0x0, 0x1E35B0}; WEAK symbol UI_TextWidth{0x0, 0x0}; WEAK symbol UI_SafeTranslateString{0x0, 0x4E8BC0}; From 3bf917463658464feccd12441aff12816f26e916 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 17:37:16 +0200 Subject: [PATCH 208/346] Fix console --- src/client/component/game_console.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp index a0f34f28..6f67d4a5 100644 --- a/src/client/component/game_console.cpp +++ b/src/client/component/game_console.cpp @@ -587,11 +587,12 @@ namespace game_console } const auto shift_down = game::playerKeys[local_client_num].keys[game::keyNum_t::K_SHIFT].down; - console::info("shift down? %d", shift_down); if (shift_down) { if (!(*game::keyCatchers & 1)) + { toggle_console(); + } toggle_console_output(); return false; From 17936ed2b58d3ff7e3520d87e88bdd091528a6a6 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 17:37:27 +0200 Subject: [PATCH 209/346] This too --- src/client/game/symbols.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index fc1cd08d..0fea5b49 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -239,7 +239,7 @@ namespace game WEAK symbol g_assetNames{0x0, 0x0}; WEAK symbol keyCatchers{0x0, 0x2EC82C4}; - WEAK symbol playerKeys{0x0, 0x2999D00}; + WEAK symbol playerKeys{0x0, 0x2999E1C}; WEAK symbol query_socket{0x0, 0xC9DCD38}; From aeb7cbb1d3f4df2f1660eab68a04191133a80ec6 Mon Sep 17 00:00:00 2001 From: m Date: Thu, 19 May 2022 11:35:15 -0500 Subject: [PATCH 210/346] temp progress, have to find client count l8r [skip ci] --- src/client/component/discord.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index b69cc99f..97c3a027 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -53,7 +53,6 @@ namespace discord discord_presence.matchSecret = ""; discord_presence.joinSecret = ""; discord_presence.partyId = ""; - discord_presence.state = ""; } else { @@ -103,7 +102,7 @@ namespace discord discord_presence.partyPrivacy = DISCORD_PARTY_PUBLIC; } - discord_presence.partySize = *reinterpret_cast(0x1429864C4); + discord_presence.partySize = 1; //*reinterpret_cast(0x1429864C4); discord_presence.partyMax = max_clients; discord_presence.state = clean_hostname; discord_presence.largeImageKey = map; @@ -188,13 +187,13 @@ namespace discord handlers.ready = ready; handlers.errored = errored; handlers.disconnected = errored; - handlers.joinGame = join_game; + handlers.joinGame = nullptr; //join_game handlers.spectateGame = nullptr; - handlers.joinRequest = join_request; + handlers.joinRequest = nullptr; //join_request Discord_Initialize("947125042930667530", &handlers, 1, nullptr); - scheduler::once(download_default_avatar, scheduler::pipeline::async); + //scheduler::once(download_default_avatar, scheduler::pipeline::async); scheduler::once([]() { @@ -285,4 +284,4 @@ namespace discord }; } -//REGISTER_COMPONENT(discord::component) \ No newline at end of file +REGISTER_COMPONENT(discord::component) From 58f0227568c9d57fb295de485ca3d446550a458f Mon Sep 17 00:00:00 2001 From: m Date: Thu, 19 May 2022 11:42:09 -0500 Subject: [PATCH 211/346] bots component, crashing somewhere? --- src/client/component/bots.cpp | 2 +- src/client/component/scheduler.cpp | 2 +- src/client/game/symbols.hpp | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/client/component/bots.cpp b/src/client/component/bots.cpp index 089ac700..67398577 100644 --- a/src/client/component/bots.cpp +++ b/src/client/component/bots.cpp @@ -106,4 +106,4 @@ namespace bots }; } -//REGISTER_COMPONENT(bots::component) \ No newline at end of file +REGISTER_COMPONENT(bots::component) diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index 177ec4be..abe01fff 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -207,7 +207,7 @@ namespace scheduler a.jmp(0x6A6310_b); }), true); - //g_run_frame_hook.create(SELECT_VALUE(0x0, 0x417940_b), scheduler::server_frame_stub); + g_run_frame_hook.create(SELECT_VALUE(0x0, 0x417940_b), scheduler::server_frame_stub); main_frame_hook.create(SELECT_VALUE(0x0, 0x3438B0_b), scheduler::main_frame_stub); //hks_frame_hook.create(SELECT_VALUE(0x0, 0x0), scheduler::hks_frame_stub); // no scripting for now } diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index 0fea5b49..b9d0d716 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -134,7 +134,7 @@ namespace game unsigned int paramcount)> VM_Execute{0x0, 0x0}; WEAK symbol Scr_NotifyId{0x0, 0x0}; + unsigned int paramcount)> Scr_NotifyId{0x0, 0x510340}; WEAK symbol Scr_AllocVector{0x0, 0x0}; WEAK symbol Scr_GetFloat{0x0, 0x0}; WEAK symbol Scr_GetString{0x0, 0x0}; @@ -163,7 +163,7 @@ namespace game WEAK symbol Menu_IsMenuOpenAndVisible{0x0, 0x0}; WEAK symbol SL_FindString{0x0, 0x0}; - WEAK symbol SL_GetString{0x0, 0x0}; + WEAK symbol SL_GetString{0x0, 0x5083A0}; WEAK symbol SL_ConvertToString{0x0, 0x0}; WEAK symbol SL_GetCanonicalString{0x0, 0x0}; @@ -172,10 +172,10 @@ namespace game WEAK symbol SV_Cmd_TokenizeString{0x0, 0x1CACE0}; WEAK symbol SV_Cmd_EndTokenizedString{0x0, 0x1CACA0}; - WEAK symbol SV_AddBot{0x0, 0x0}; + WEAK symbol SV_AddBot{0x0, 0x54D4F0}; WEAK symbol SV_BotIsBot{0x0, 0x53B6D0}; - WEAK symbol SV_BotGetRandomName{0x0, 0x0}; - WEAK symbol SV_SpawnTestClient{0x0, 0x0}; + WEAK symbol SV_BotGetRandomName{0x0, 0x53ABD0}; + WEAK symbol SV_SpawnTestClient{0x0, 0x550580}; WEAK symbol SV_GetGuid{0x0, 0x0}; WEAK symbol SV_GetClientPing{0x0, 0x0}; @@ -227,7 +227,7 @@ namespace game WEAK symbol g_classMap{0x0, 0x0}; WEAK symbol scr_VarGlob{0x0, 0x0}; - WEAK symbol scr_VmPub{0x0, 0x0}; + WEAK symbol scr_VmPub{0x0, 0xB7AE3C0}; WEAK symbol scr_function_stack{0x0, 0x0}; WEAK symbol gfxDrawMethod{0x0, 0x0}; From 3d6934d97c2d7931d5f78df54032c5a5c226ec11 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 19:09:17 +0200 Subject: [PATCH 212/346] Finish dvars.cpp + some patches --- src/client/component/command.cpp | 4 +- src/client/component/dvars.cpp | 106 +++++++++++++++++-------------- src/client/component/patches.cpp | 43 +++++++------ src/client/component/ranked.cpp | 16 ++--- 4 files changed, 88 insertions(+), 81 deletions(-) diff --git a/src/client/component/command.cpp b/src/client/component/command.cpp index a83e0f85..90c06bca 100644 --- a/src/client/component/command.cpp +++ b/src/client/component/command.cpp @@ -118,8 +118,8 @@ namespace command const auto current = game::Dvar_ValueToString(dvar, true, dvar->current); const auto reset = game::Dvar_ValueToString(dvar, true, dvar->reset); - console::info("\"%s\" is: \"%s\" default: \"%s\" hash: 0x%08lX\n", - args[0], current, reset, dvar->hash); + console::info("\"%s\" is: \"%s\" default: \"%s\" hash: 0x%08lX type: %i\n", + args[0], current, reset, dvar->hash, dvar->type); const auto dvar_info = dvars::dvar_get_description(args[0]); diff --git a/src/client/component/dvars.cpp b/src/client/component/dvars.cpp index f1eca327..8b6b5770 100644 --- a/src/client/component/dvars.cpp +++ b/src/client/component/dvars.cpp @@ -237,8 +237,11 @@ namespace dvars } utils::hook::detour dvar_register_bool_hook; + utils::hook::detour dvar_register_bool_hashed_hook; utils::hook::detour dvar_register_float_hook; + utils::hook::detour dvar_register_float_hashed_hook; utils::hook::detour dvar_register_int_hook; + utils::hook::detour dvar_register_int_hashed_hook; utils::hook::detour dvar_register_string_hook; utils::hook::detour dvar_register_vector2_hook; utils::hook::detour dvar_register_vector3_hook; @@ -249,38 +252,6 @@ namespace dvars utils::hook::detour dvar_set_string_hook; utils::hook::detour dvar_set_from_string_hook; - utils::hook::detour dvar_re_register_hook; - utils::hook::detour dvar_register_new_hook; - - game::dvar_type get_normal_type(const game::dvar_type type) - { - switch (type) - { - case game::dvar_type::boolean_hashed: - return game::dvar_type::boolean; - case game::dvar_type::integer_hashed: - return game::dvar_type::integer; - case game::dvar_type::value_hashed: - return game::dvar_type::value; - default: - return type; - } - } - - void dvar_re_register_stub(game::dvar_t* dvar, const int hash, const char* name, game::dvar_type type, - const unsigned int flags, game::dvar_value* value, game::dvar_limits* domain) - { - type = get_normal_type(type); - dvar_re_register_hook.invoke(dvar, hash, name, type, flags, value, domain); - } - - game::dvar_t* dvar_register_new_stub(const int hash, const char* name, game::dvar_type type, - const unsigned int flags, game::dvar_value* value, game::dvar_limits* domain) - { - type = get_normal_type(type); - return dvar_register_new_hook.invoke(hash, name, type, flags, value, domain); - } - game::dvar_t* dvar_register_bool(const int hash, const char* name, bool value, unsigned int flags) { auto* var = find_dvar(override::register_bool_overrides, hash); @@ -293,6 +264,18 @@ namespace dvars return dvar_register_bool_hook.invoke(hash, name, value, flags); } + game::dvar_t* dvar_register_bool_hashed(const int hash, const char* name, bool value, unsigned int flags) + { + auto* var = find_dvar(override::register_bool_overrides, hash); + if (var) + { + value = var->value; + flags = var->flags; + } + + return dvar_register_bool_hashed_hook.invoke(hash, name, value, flags); + } + game::dvar_t* dvar_register_float(const int hash, const char* name, float value, float min, float max, unsigned int flags) { auto* var = find_dvar(override::register_float_overrides, hash); @@ -307,6 +290,20 @@ namespace dvars return dvar_register_float_hook.invoke(hash, name, value, min, max, flags); } + game::dvar_t* dvar_register_float_hashed(const int hash, const char* name, float value, float min, float max, unsigned int flags) + { + auto* var = find_dvar(override::register_float_overrides, hash); + if (var) + { + value = var->value; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_float_hashed_hook.invoke(hash, name, value, min, max, flags); + } + game::dvar_t* dvar_register_int(const int hash, const char* name, int value, int min, int max, unsigned int flags) { auto* var = find_dvar(override::register_int_overrides, hash); @@ -321,6 +318,20 @@ namespace dvars return dvar_register_int_hook.invoke(hash, name, value, min, max, flags); } + game::dvar_t* dvar_register_int_hashed(const int hash, const char* name, int value, int min, int max, unsigned int flags) + { + auto* var = find_dvar(override::register_int_overrides, hash); + if (var) + { + value = var->value; + min = var->min; + max = var->max; + flags = var->flags; + } + + return dvar_register_int_hashed_hook.invoke(hash, name, value, min, max, flags); + } + game::dvar_t* dvar_register_string(const int hash, const char* name, const char* value, unsigned int flags) { auto* var = find_dvar(override::register_string_overrides, hash); @@ -456,24 +467,21 @@ namespace dvars public: void post_unpack() override { - if (game::environment::is_mp()) - { - // dvar_register_new_hook.create(0x184DF0_b, dvar_register_new_stub); - // dvar_re_register_hook.create(0x185150_b, dvar_re_register_stub); - } + dvar_register_bool_hook.create(SELECT_VALUE(0x0, 0x182340_b), &dvar_register_bool); + dvar_register_bool_hashed_hook.create(SELECT_VALUE(0x0, 0x182420_b), &dvar_register_bool_hashed); + dvar_register_float_hook.create(SELECT_VALUE(0x0, 0x1827F0_b), &dvar_register_float); + dvar_register_float_hashed_hook.create(SELECT_VALUE(0x0, 0x182900_b), &dvar_register_float_hashed); + dvar_register_int_hook.create(SELECT_VALUE(0x0, 0x182A10_b), &dvar_register_int); + dvar_register_int_hashed_hook.create(SELECT_VALUE(0x0, 0x182AF0_b), &dvar_register_int_hashed); + dvar_register_string_hook.create(SELECT_VALUE(0x0, 0x182BD0_b), &dvar_register_string); + dvar_register_vector2_hook.create(SELECT_VALUE(0x0, 0x182CB0_b), &dvar_register_vector2); + dvar_register_vector3_hook.create(SELECT_VALUE(0x0, 0x182DB0_b), &dvar_register_vector3); - dvar_register_bool_hook.create(SELECT_VALUE(0x0, 0x182340_b), &dvar_register_bool); // good - //dvar_register_float_hook.create(SELECT_VALUE(0x0, 0x182900_b), &dvar_register_float); // FLOAT HASHED (TYPE 11 INSTEAD OF 1) - dvar_register_int_hook.create(SELECT_VALUE(0x0, 0x182A10_b), &dvar_register_int); // goood - //dvar_register_string_hook.create(SELECT_VALUE(0x0, 0x182AF0_b), &dvar_register_string); // INT HASHED (TYPE 12, INSTEAD OF 7) - //dvar_register_vector2_hook.create(SELECT_VALUE(0x0, 0x182BD0_b), &dvar_register_vector2); // STRING (TYPE 7 INSTEAD OF 2) - //dvar_register_vector3_hook.create(SELECT_VALUE(0x0, 0x182CB0_b), &dvar_register_vector3); // VEC2 (TYPE 2 INSTEAD OF 3) - - dvar_set_bool_hook.create(SELECT_VALUE(0x0, 0x185520_b), &dvar_set_bool); // good - dvar_set_float_hook.create(SELECT_VALUE(0x0, 0x185AA0_b), &dvar_set_float); // good - dvar_set_int_hook.create(SELECT_VALUE(0x0, 0x185D10_b), &dvar_set_int); // good - dvar_set_string_hook.create(SELECT_VALUE(0x0, 0x186080_b), &dvar_set_string); // good - dvar_set_from_string_hook.create(SELECT_VALUE(0x0, 0x185C60_b), &dvar_set_from_string); // good + dvar_set_bool_hook.create(SELECT_VALUE(0x0, 0x185520_b), &dvar_set_bool); + dvar_set_float_hook.create(SELECT_VALUE(0x0, 0x185AA0_b), &dvar_set_float); + dvar_set_int_hook.create(SELECT_VALUE(0x0, 0x185D10_b), &dvar_set_int); + dvar_set_string_hook.create(SELECT_VALUE(0x0, 0x186080_b), &dvar_set_string); + dvar_set_from_string_hook.create(SELECT_VALUE(0x0, 0x185C60_b), &dvar_set_from_string); } }; } diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index 73fdbdfe..d102e3ec 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -65,6 +65,8 @@ namespace patches return com_register_dvars_hook.invoke(); } + utils::hook::detour set_client_dvar_from_server_hook; + void set_client_dvar_from_server_stub(void* a1, void* a2, const char* dvar, const char* value) { if (dvar == "cg_fov"s || dvar == "cg_fovMin"s) @@ -72,8 +74,7 @@ namespace patches return; } - // CG_SetClientDvarFromServer - utils::hook::invoke(0x11AA90_b, a1, a2, dvar, value); + set_client_dvar_from_server_hook.invoke(0x11AA90_b, a1, a2, dvar, value); } const char* db_read_raw_file_stub(const char* filename, char* buf, const int size) @@ -156,15 +157,15 @@ namespace patches void post_unpack() override { // Register dvars - com_register_dvars_hook.create(SELECT_VALUE(0x140351B80, 0x1400D9320), &com_register_dvars_stub); + //com_register_dvars_hook.create(SELECT_VALUE(0x140351B80, 0x1400D9320), &com_register_dvars_stub); // Unlock fps in main menu - utils::hook::set(SELECT_VALUE(0x14018D47B, 0x14025B86B), 0xEB); + utils::hook::set(SELECT_VALUE(0, 0x34396B_b), 0xEB); if (!game::environment::is_dedi()) { // Fix mouse lag - utils::hook::nop(SELECT_VALUE(0x1403E3C05, 0x1404DB1AF), 6); + // utils::hook::nop(SELECT_VALUE(0x1403E3C05, 0x1404DB1AF), 6); scheduler::loop([]() { SetThreadExecutionState(ES_DISPLAY_REQUIRED); @@ -177,11 +178,11 @@ namespace patches dvars::override::register_float("cg_fovMin", 1.f, 1.0f, 90.f, game::DvarFlags::DVAR_FLAG_SAVED); // Allow kbam input when gamepad is enabled - utils::hook::nop(SELECT_VALUE(0x14018797E, 0x14024EF60), 2); - utils::hook::nop(SELECT_VALUE(0x1401856DC, 0x14024C6B0), 6); + // utils::hook::nop(SELECT_VALUE(0x14018797E, 0x14024EF60), 2); + // utils::hook::nop(SELECT_VALUE(0x1401856DC, 0x14024C6B0), 6); // Allow executing custom cfg files with the "exec" command - utils::hook::call(SELECT_VALUE(0x140343855, 0x140403E28), db_read_raw_file_stub); + // utils::hook::call(SELECT_VALUE(0x140343855, 0x140403E28), db_read_raw_file_stub); if (!game::environment::is_sp()) { @@ -192,10 +193,10 @@ namespace patches static void patch_mp() { // Use name dvar - utils::hook::jump(0x14050FF90, &live_get_local_client_name); + //utils::hook::jump(0x5BB9C0_b, &live_get_local_client_name, true); // Patch SV_KickClientNum - sv_kick_client_num_hook.create(0x14047ED00, &sv_kick_client_num); + /*sv_kick_client_num_hook.create(0x14047ED00, &sv_kick_client_num); // block changing name in-game utils::hook::set(0x14047FC90, 0xC3); @@ -218,29 +219,29 @@ namespace patches // disable elite_clan dvars::override::register_int("elite_clan_active", 0, 0, 0, game::DVAR_FLAG_NONE); - utils::hook::set(0x140585680, 0xC3); // don't register commands + utils::hook::set(0x140585680, 0xC3); // don't register commands*/ // disable codPointStore dvars::override::register_int("codPointStore_enabled", 0, 0, 0, game::DVAR_FLAG_NONE); // don't register every replicated dvar as a network dvar - utils::hook::nop(0x14039E58E, 5); // dvar_foreach + utils::hook::nop(0x47408E_b, 5); // dvar_foreach // patch "Server is different version" to show the server client version - utils::hook::inject(0x140480955, VERSION); + // utils::hook::inject(0x140480955, VERSION); // prevent servers overriding our fov - utils::hook::call(0xF4500_b, set_client_dvar_from_server_stub); - // utils::hook::nop(0x1400DAF69, 5); - // utils::hook::nop(0x140190C16, 5); + set_client_dvar_from_server_hook.create(0x11AA90_b, set_client_dvar_from_server_stub); + utils::hook::nop(0x17DA96_b, 0x16); + utils::hook::nop(0xE00BE_b, 0x17); utils::hook::set(0x307F39_b, 0xEB); // some [data validation] anti tamper thing that kills performance dvars::override::register_int("dvl", 0, 0, 0, game::DVAR_FLAG_READ); // unlock safeArea_* - utils::hook::jump(0x1402624F5, 0x140262503); - utils::hook::jump(0x14026251C, 0x140262547); + /*utils::hook::jump(0x1402624F5, 0x140262503); + utils::hook::jump(0x14026251C, 0x140262547);*/ dvars::override::register_float("safeArea_adjusted_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); dvars::override::register_float("safeArea_adjusted_vertical", 1, 0, 1, game::DVAR_FLAG_SAVED); dvars::override::register_float("safeArea_horizontal", 1, 0, 1, game::DVAR_FLAG_SAVED); @@ -262,7 +263,7 @@ namespace patches dvars::override::register_int("com_maxfps", 0, 0, 1000, game::DVAR_FLAG_SAVED); // Prevent clients from ending the game as non host by sending 'end_game' lui notification - cmd_lui_notify_server_hook.create(0x140335A70, cmd_lui_notify_server_stub); + /*cmd_lui_notify_server_hook.create(0x140335A70, cmd_lui_notify_server_stub); // Prevent clients from sending invalid reliableAcknowledge utils::hook::call(0x1404899C6, sv_execute_client_message_stub); @@ -275,7 +276,7 @@ namespace patches utils::hook::jump(0x140578C40, free); utils::hook::jump(0x140578D30, realloc); utils::hook::jump(0x140578B60, _aligned_realloc); - } + }*/ // Change default hostname and make it replicated dvars::override::register_string("sv_hostname", "^2H1-Mod^7 Default Server", game::DVAR_FLAG_REPLICATED); @@ -283,4 +284,4 @@ namespace patches }; } -//REGISTER_COMPONENT(patches::component) +REGISTER_COMPONENT(patches::component) diff --git a/src/client/component/ranked.cpp b/src/client/component/ranked.cpp index 4ec15b44..955a1984 100644 --- a/src/client/component/ranked.cpp +++ b/src/client/component/ranked.cpp @@ -27,21 +27,19 @@ namespace ranked dvars::override::register_bool("xblive_privatematch", false, game::DVAR_FLAG_REPLICATED); } - if (game::environment::is_dedi() && !utils::flags::has_flag("unranked")) + if (game::environment::is_dedi()) { dvars::override::register_bool("xblive_privatematch", false, game::DVAR_FLAG_REPLICATED | game::DVAR_FLAG_WRITE); - - // Skip some check in _menus.gsc - dvars::register_bool("force_ranking", true, game::DVAR_FLAG_WRITE, ""); + dvars::register_bool("force_ranking", true, game::DVAR_FLAG_WRITE, ""); // Skip some check in _menus.gsc } // Always run bots, even if xblive_privatematch is 0 - utils::hook::set(0x1401D9300, 0xC301B0); // BG_BotSystemEnabled - utils::hook::set(0x1401D90D0, 0xC301B0); // BG_AISystemEnabled - utils::hook::set(0x1401D92A0, 0xC301B0); // BG_BotFastFileEnabled - utils::hook::set(0x1401D9400, 0xC301B0); // BG_BotsUsingTeamDifficulty + utils::hook::set(0x2C10B0_b, 0xC301B0); // BG_BotSystemEnabled + utils::hook::set(0x2C0E60_b, 0xC301B0); // BG_AISystemEnabled + utils::hook::set(0x2C1040_b, 0xC301B0); // BG_BotFastFileEnabled + utils::hook::set(0x2C11B0_b, 0xC301B0); // BG_BotsUsingTeamDifficulty } }; } -//REGISTER_COMPONENT(ranked::component) +REGISTER_COMPONENT(ranked::component) From 3d1c1d3aa9b3b428710d1d62e29597be0047d137 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 20:15:27 +0200 Subject: [PATCH 213/346] Use name dvar --- src/client/component/patches.cpp | 44 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index d102e3ec..b5ef6e43 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -49,22 +49,6 @@ namespace patches return std::string{ username, username_len - 1 }; } - utils::hook::detour com_register_dvars_hook; - - void com_register_dvars_stub() - { - if (game::environment::is_mp()) - { - // Make name save - dvars::register_string("name", get_login_username().data(), game::DVAR_FLAG_SAVED, "Player name."); - - // Disable data validation error popup - dvars::register_int("data_validation_allow_drop", 0, 0, 0, game::DVAR_FLAG_NONE, ""); - } - - return com_register_dvars_hook.invoke(); - } - utils::hook::detour set_client_dvar_from_server_hook; void set_client_dvar_from_server_stub(void* a1, void* a2, const char* dvar, const char* value) @@ -149,6 +133,17 @@ namespace patches game::AimAssist_AddToTargetList(a1, a2); } + + void* sub_5BB990_stub() + { + auto v0 = !utils::hook::invoke(0x1B19E0_b, 0x3426D20_b); + auto result = *reinterpret_cast(0x3426D20_b); + if (v0) + { + result = reinterpret_cast(0xB807260_b); + } + return result; + } } class component final : public component_interface @@ -156,16 +151,13 @@ namespace patches public: void post_unpack() override { - // Register dvars - //com_register_dvars_hook.create(SELECT_VALUE(0x140351B80, 0x1400D9320), &com_register_dvars_stub); - // Unlock fps in main menu utils::hook::set(SELECT_VALUE(0, 0x34396B_b), 0xEB); if (!game::environment::is_dedi()) { // Fix mouse lag - // utils::hook::nop(SELECT_VALUE(0x1403E3C05, 0x1404DB1AF), 6); + utils::hook::nop(SELECT_VALUE(0, 0x5BFF89_b), 6); scheduler::loop([]() { SetThreadExecutionState(ES_DISPLAY_REQUIRED); @@ -193,7 +185,17 @@ namespace patches static void patch_mp() { // Use name dvar - //utils::hook::jump(0x5BB9C0_b, &live_get_local_client_name, true); + utils::hook::nop(0x5BB990_b, 0x27); // clear function + // jmp from 0x5BB9C0 to 0x5BB9A2 (leave some space for far jmp above) + utils::hook::set(0x5BB9C0_b, 0xE0EB); + utils::hook::jump(0x5BB9A2_b, &live_get_local_client_name, true); + utils::hook::jump(0x5BB990_b, sub_5BB990_stub, true); // replace original function + + // Make name save + dvars::override::register_string("name", get_login_username().data(), game::DVAR_FLAG_SAVED); + + // Disable data validation error popup + dvars::override::register_int("data_validation_allow_drop", 0, 0, 0, game::DVAR_FLAG_NONE); // Patch SV_KickClientNum /*sv_kick_client_num_hook.create(0x14047ED00, &sv_kick_client_num); From 09d7243ddc3a56be20a6c51383c75a54033c6380 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 21:04:57 +0200 Subject: [PATCH 214/346] Fix name dvar --- src/client/component/patches.cpp | 21 ++++++++++++++++++++- src/client/game/symbols.hpp | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/client/component/patches.cpp b/src/client/component/patches.cpp index b5ef6e43..ddf8190d 100644 --- a/src/client/component/patches.cpp +++ b/src/client/component/patches.cpp @@ -46,7 +46,23 @@ namespace patches return "Unknown Soldier"; } - return std::string{ username, username_len - 1 }; + return std::string{username, username_len - 1}; + } + + utils::hook::detour com_register_dvars_hook; + + void com_register_dvars_stub() + { + if (game::environment::is_mp()) + { + // Make name save + dvars::register_string("name", get_login_username().data(), game::DVAR_FLAG_SAVED, "Player name."); + + // Disable data validation error popup + dvars::register_int("data_validation_allow_drop", 0, 0, 0, game::DVAR_FLAG_NONE, ""); + } + + return com_register_dvars_hook.invoke(); } utils::hook::detour set_client_dvar_from_server_hook; @@ -151,6 +167,9 @@ namespace patches public: void post_unpack() override { + // Register dvars + com_register_dvars_hook.create(SELECT_VALUE(0, 0x15BB60_b), &com_register_dvars_stub); + // Unlock fps in main menu utils::hook::set(SELECT_VALUE(0, 0x34396B_b), 0xEB); diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index b9d0d716..ef5f6802 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -65,9 +65,9 @@ namespace game WEAK symbol Dvar_RegisterInt{0x0, 0x182A10}; WEAK symbol Dvar_RegisterFloat{0x0, 0x182900}; + float max, unsigned int flags)> Dvar_RegisterFloat{0x0, 0x1827F0}; WEAK symbol Dvar_RegisterString{0x0, 0x182AF0}; + unsigned int flags)> Dvar_RegisterString{0x0, 0x182BD0}; WEAK symbol Dvar_RegisterVec4{0x0, 0x183010}; From 1b3f3e496b39f54fc9bfe0ec4512c69a1cd5c7c3 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 21:45:00 +0200 Subject: [PATCH 215/346] Map rotation --- src/client/component/console.cpp | 51 ++++++++++++++------------- src/client/component/map_rotation.cpp | 14 ++++---- 2 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index c813372a..b0430888 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -5,6 +5,8 @@ #include "game/game.hpp" #include "command.hpp" +#include + namespace game_console { void print(int type, const std::string& data); @@ -14,26 +16,8 @@ namespace console { namespace { - static bool ingame = false; - - DWORD WINAPI console(LPVOID) - { - ShowWindow(GetConsoleWindow(), SW_SHOW); - SetConsoleTitle("H1-Mod"); - - std::string cmd; - - while (true) - { - std::getline(std::cin, cmd); - if (ingame) - { - game::Cbuf_AddText(0, 0, cmd.data()); - } - } - - return 0; - } + bool kill = false; + std::thread console_thread; } std::string format(va_list* ap, const char* message) @@ -43,7 +27,7 @@ namespace console const auto count = _vsnprintf_s(buffer, sizeof(buffer), sizeof(buffer), message, *ap); if (count < 0) return {}; - return { buffer, static_cast(count) }; + return {buffer, static_cast(count)}; } void dispatch_message(const int type, const std::string& message) @@ -66,19 +50,36 @@ namespace console class component final : public component_interface { public: - void post_start() override + component() { - CreateThread(0, 0, console, 0, 0, 0); + ShowWindow(GetConsoleWindow(), SW_HIDE); } void post_unpack() override { - ingame = true; + ShowWindow(GetConsoleWindow(), SW_SHOW); + SetConsoleTitle("H1-Mod"); + + console_thread = utils::thread::create_named_thread("Console", []() + { + std::string cmd; + + while (!kill) + { + std::getline(std::cin, cmd); + game::Cbuf_AddText(0, 0, cmd.data()); + } + }); } void pre_destroy() override { - ingame = false; + kill = true; + + if (console_thread.joinable()) + { + console_thread.join(); + } } }; } diff --git a/src/client/component/map_rotation.cpp b/src/client/component/map_rotation.cpp index 7147c2cb..6f749304 100644 --- a/src/client/component/map_rotation.cpp +++ b/src/client/component/map_rotation.cpp @@ -9,9 +9,10 @@ namespace map_rotation { - DWORD previousPriority; namespace { + DWORD previous_priority{}; + void set_dvar(const std::string& dvar, const std::string& value) { command::execute(utils::string::va("%s \"%s\"", dvar.data(), value.data()), true); @@ -84,10 +85,10 @@ namespace map_rotation scheduler::on_game_initialized([]() { //printf("=======================setting OLD priority=======================\n"); - SetPriorityClass(GetCurrentProcess(), previousPriority); + SetPriorityClass(GetCurrentProcess(), previous_priority); }, scheduler::pipeline::main, 1s); - previousPriority = GetPriorityClass(GetCurrentProcess()); + previous_priority = GetPriorityClass(GetCurrentProcess()); //printf("=======================setting NEW priority=======================\n"); SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); } @@ -147,7 +148,6 @@ namespace map_rotation return scheduler::cond_end; }, scheduler::pipeline::main, 1s); } - } class component final : public component_interface @@ -170,11 +170,11 @@ namespace map_rotation command::add("map_rotate", &perform_map_rotation); // Hook GScr_ExitLevel - utils::hook::jump(0x140376630, &trigger_map_rotation); // not sure if working + utils::hook::jump(0xE2670_b, &trigger_map_rotation, true); // not sure if working - previousPriority = GetPriorityClass(GetCurrentProcess()); + previous_priority = GetPriorityClass(GetCurrentProcess()); } }; } -//REGISTER_COMPONENT(map_rotation::component) +REGISTER_COMPONENT(map_rotation::component) From 6f248d609ac9fad0fccb3034e586b86553c45731 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Thu, 19 May 2022 22:08:14 +0200 Subject: [PATCH 216/346] Dvar cheats Co-Authored-By: Skull Merlin <86374920+skkuull@users.noreply.github.com> --- src/client/component/dvar_cheats.cpp | 132 ++++++++------------------- src/client/game/symbols.hpp | 4 +- 2 files changed, 41 insertions(+), 95 deletions(-) diff --git a/src/client/component/dvar_cheats.cpp b/src/client/component/dvar_cheats.cpp index fba24253..66c49e6c 100644 --- a/src/client/component/dvar_cheats.cpp +++ b/src/client/component/dvar_cheats.cpp @@ -83,92 +83,45 @@ namespace dvar_cheats return true; } - const auto dvar_flag_checks_stub = utils::hook::assemble([](utils::hook::assembler& a) + void* get_dvar_flag_checks_stub() { - const auto can_set_value = a.newLabel(); - const auto zero_source = a.newLabel(); - - a.pushad64(); - a.mov(r8, rdi); - a.mov(edx, esi); - a.mov(rcx, rbx); - a.call_aligned(apply_sv_cheats); //check if we are setting sv_cheats - a.popad64(); - a.cmp(esi, 0); - a.jz(zero_source); //if the SetSource is 0 (INTERNAL) ignore flag checks - - a.pushad64(); - a.mov(edx, esi); //source - a.mov(rcx, rbx); //dvar - a.call_aligned(dvar_flag_checks); //protect read/write/cheat/replicated dvars - a.cmp(al, 1); - a.jz(can_set_value); - - // if we get here, we are non-zero source and CANNOT set values - a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag - a.jmp(0x1404FDCAB); - - // if we get here, we are non-zero source and CAN set values - a.bind(can_set_value); - a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag - a.cmp(esi, 1); - a.jmp(0x1404FDA22); - - // if we get here, we are zero source and ignore flags - a.bind(zero_source); - a.jmp(0x1404FDA62); - }); - - void cg_set_client_dvar_from_server(const int local_client_num, void* cg, const char* dvar_id, const char* value) - { - const auto* dvar = game::Dvar_FindVar(dvar_id); - if (dvar) + return utils::hook::assemble([](utils::hook::assembler& a) { - // If we send as string, it can't be set with source SERVERCMD because the game only allows that source on real server cmd dvars. - // Just use external instead as if it was being set by the console - game::Dvar_SetFromStringByNameFromSource(dvar_id, value, game::DvarSetSource::DVAR_SOURCE_EXTERNAL); - } - else - { - // Not a dvar name, assume it is an id and the game will handle normally - game::CG_SetClientDvarFromServer(local_client_num, cg, dvar_id, value); - } + const auto can_set_value = a.newLabel(); + const auto zero_source = a.newLabel(); + + a.pushad64(); + a.mov(r8, rdi); + a.mov(edx, esi); + a.mov(rcx, rbx); + a.call_aligned(apply_sv_cheats); // check if we are setting sv_cheats + a.popad64(); + a.cmp(esi, 0); + a.jz(zero_source); // if the SetSource is 0 (INTERNAL) ignore flag checks + + a.pushad64(); + a.mov(edx, esi); // source + a.mov(rcx, rbx); // dvar + a.call_aligned(dvar_flag_checks); // protect read/write/cheat/replicated dvars + a.cmp(al, 1); + a.jz(can_set_value); + + // if we get here, we are non-zero source and CANNOT set values + a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag + a.jmp(0x18655C_b); + + // if we get here, we are non-zero source and CAN set values + a.bind(can_set_value); + a.popad64(); // if I do this before the jz it won't work. for some reason the popad64 is affecting the ZR flag + a.cmp(esi, 1); + a.jmp(0x1861EE_b); + + // if we get here, we are zero source and ignore flags + a.bind(zero_source); + a.jmp(0x18628F_b); + }); } - void set_client_dvar_by_string(const int entity_num, const char* value) - { - const auto* dvar = game::Scr_GetString(0); // grab the original dvar again since it's never stored on stack - const auto* command = utils::string::va("q %s \"%s\"", dvar, value); - - game::SV_GameSendServerCommand(entity_num, game::SV_CMD_RELIABLE, command); - } - - const auto player_cmd_set_client_dvar = utils::hook::assemble([](utils::hook::assembler& a) - { - const auto set_by_string = a.newLabel(); - - a.pushad64(); - - // check if we didn't find a network dvar index - a.mov(ecx, dword_ptr(rsp, 0x8C8)); - a.cmp(ecx, 0); - a.je(set_by_string); - - // we found an index, handle normally - a.popad64(); - a.mov(r8d, ptr(rsp, 0x848)); - a.lea(r9, ptr(rsp, 0x30)); - a.jmp(0x1402E2E57); - - // no index, let's send the dvar as a string - a.bind(set_by_string); - a.movzx(ecx, word_ptr(rsp, 0x8C0)); //entity_num - a.lea(rdx, ptr(rsp, 0xB0)); //value - a.call_aligned(set_client_dvar_by_string); - a.popad64(); - a.jmp(0x1402E2E7D); - }); - class component final : public component_interface { public: @@ -179,23 +132,16 @@ namespace dvar_cheats return; } - utils::hook::nop(0x1404FDA0D, 4); // let our stub handle zero-source sets - utils::hook::jump(0x1404FDA14, dvar_flag_checks_stub, true); // check extra dvar flags when setting values - - // utils::hook::nop(0x14032AACC, 5); // remove error in PlayerCmd_SetClientDvar if setting a non-network dvar - // utils::hook::set(0x14032AA9B, 0xEB); - // don't check flags on the dvars, send any existing dvar instead - // utils::hook::jump(0x14032AB14, player_cmd_set_client_dvar, true); // send non-network dvars as string - // utils::hook::call(0x1401BB782, cg_set_client_dvar_from_server); - // check for dvars being sent as string before parsing ids + utils::hook::nop(0x1861D4_b, 8); // let our stub handle zero-source sets + utils::hook::jump(0x1861DF_b, get_dvar_flag_checks_stub(), true); // check extra dvar flags when setting values scheduler::once([]() { dvars::register_bool("sv_cheats", false, game::DvarFlags::DVAR_FLAG_REPLICATED, - "Allow cheat commands and dvars on this server"); + "Allow cheat commands and dvars on this server"); }, scheduler::pipeline::main); } }; } -//REGISTER_COMPONENT(dvar_cheats::component) +REGISTER_COMPONENT(dvar_cheats::component) diff --git a/src/client/game/symbols.hpp b/src/client/game/symbols.hpp index ef5f6802..a99508f6 100644 --- a/src/client/game/symbols.hpp +++ b/src/client/game/symbols.hpp @@ -232,8 +232,8 @@ namespace game WEAK symbol gfxDrawMethod{0x0, 0x0}; - WEAK symbol dvarCount{0x0, 0x0}; - WEAK symbol dvarPool{0x0, 0x0}; + WEAK symbol dvarCount{0x0, 0x2999C34}; + WEAK symbol dvarPool{0x0, 0x344DF20}; WEAK symbol DB_XAssetPool{0x0, 0x0}; WEAK symbol g_assetNames{0x0, 0x0}; From 46ebc3fb15fb74d2712fff1170b7fe4ef9a6aaf7 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 20 May 2022 00:05:51 +0200 Subject: [PATCH 217/346] Console changes + colors --- src/client/component/auth.cpp | 6 ------ src/client/component/colors.cpp | 23 ++++++++++++++++++----- src/client/component/console.cpp | 6 +++--- src/client/component/fastfiles.cpp | 2 +- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/client/component/auth.cpp b/src/client/component/auth.cpp index 6b19fb87..a337cacd 100644 --- a/src/client/component/auth.cpp +++ b/src/client/component/auth.cpp @@ -243,12 +243,6 @@ namespace auth // kill "disconnected from steam" error utils::hook::nop(0x1D61DF_b, 0x11); - /*utils::hook::nop(0x1D6193_b, 103); // STEAM - utils::hook::nop(0x60153_b, 0x60426 - 0x60153); // STEAM - utils::hook::nop(0x603E1_b, 0x60426 - 0x603E1); // STEAM - utils::hook::nop(0x1D7553_b, 0x1D7587 - 0x1D7553); // STEAM MAYBE `1401D7553` ON FIRST - utils::hook::nop(0x1D7A82_b, 0x1D7AC8 - 0x1D7A82); // STEAM*/ - utils::hook::jump(0x1CAE70_b, get_direct_connect_stub(), true); utils::hook::jump(0x12D426_b, get_send_connect_data_stub(), true); diff --git a/src/client/component/colors.cpp b/src/client/component/colors.cpp index 1487675b..84e2025f 100644 --- a/src/client/component/colors.cpp +++ b/src/client/component/colors.cpp @@ -147,17 +147,30 @@ namespace colors if (!game::environment::is_sp()) { // allows colored name in-game - utils::hook::jump(0x5AEDF0_b, com_clean_name_stub); // 1.15 + utils::hook::jump(0x5AEDF0_b, com_clean_name_stub, true); // don't apply colors to overhead names - utils::hook::call(0xF7B85_b, get_client_name_stub); // 1.15 + utils::hook::jump(0xF7B6A_b, utils::hook::assemble([](utils::hook::assembler& a) + { + a.lea(rax, qword_ptr(rbp, -0x10)); + a.mov(dword_ptr(rsp, 0x28), 0xB); + a.mov(r9d, 0x20); + a.mov(qword_ptr(rsp, 0x20), rax); + a.lea(r8, qword_ptr(rbp)); + + a.pushad64(); + a.call_aligned(get_client_name_stub); + a.popad64(); + + a.jmp(0xF7B8A_b); + }), true); // patch I_CleanStr - utils::hook::jump(0x5AF2E0_b, i_clean_str_stub); // 1.15 + utils::hook::jump(0x5AF2E0_b, i_clean_str_stub, true); } // force new colors - utils::hook::jump(SELECT_VALUE(0x0, 0x6C9460_b), rb_lookup_color_stub); // 1.15 + utils::hook::jump(SELECT_VALUE(0x0, 0x6C9460_b), rb_lookup_color_stub, true); // add colors add(0, 0, 0); // 0 - Black @@ -179,4 +192,4 @@ namespace colors }; } -//REGISTER_COMPONENT(colors::component) +REGISTER_COMPONENT(colors::component) diff --git a/src/client/component/console.cpp b/src/client/component/console.cpp index b0430888..a54b60ee 100644 --- a/src/client/component/console.cpp +++ b/src/client/component/console.cpp @@ -6,6 +6,7 @@ #include "command.hpp" #include +#include namespace game_console { @@ -32,9 +33,8 @@ namespace console void dispatch_message(const int type, const std::string& message) { - printf("%s\n", message.data()); - - //game_console::print(type, message); + printf(message.data()); + game_console::print(type, message); } void print(const int type, const char* fmt, ...) diff --git a/src/client/component/fastfiles.cpp b/src/client/component/fastfiles.cpp index f7fb38c5..bfb64af9 100644 --- a/src/client/component/fastfiles.cpp +++ b/src/client/component/fastfiles.cpp @@ -18,7 +18,7 @@ namespace fastfiles void db_try_load_x_file_internal(const char* zone_name, const int flags) { - printf("Loading fastfile %s\n", zone_name); + console::info("Loading fastfile %s\n", zone_name); current_fastfile.access([&](std::string& fastfile) { fastfile = zone_name; From 09ac8757e8b5a1ef17ef1923b06d2d844ff23313 Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Fri, 20 May 2022 00:06:09 +0200 Subject: [PATCH 218/346] LUI scripting --- src/client/component/discord.cpp | 7 +- src/client/component/input.cpp | 5 - src/client/component/lui.cpp | 10 +- src/client/component/scheduler.cpp | 4 +- src/client/component/stats.cpp | 2 +- src/client/component/ui_scripting.cpp | 394 ++++++++--- src/client/component/ui_scripting.hpp | 49 +- src/client/game/structs.hpp | 261 ++++++- src/client/game/symbols.hpp | 37 +- src/client/game/ui_scripting/execution.cpp | 200 +++--- src/client/game/ui_scripting/execution.hpp | 5 +- src/client/game/ui_scripting/lua/context.cpp | 428 ----------- src/client/game/ui_scripting/lua/context.hpp | 42 -- src/client/game/ui_scripting/lua/engine.cpp | 83 --- src/client/game/ui_scripting/lua/engine.hpp | 8 - src/client/game/ui_scripting/lua/error.cpp | 18 - src/client/game/ui_scripting/lua/error.hpp | 8 - .../game/ui_scripting/lua/scheduler.cpp | 122 ---- .../game/ui_scripting/lua/scheduler.hpp | 50 -- .../ui_scripting/lua/value_conversion.cpp | 144 ---- .../ui_scripting/lua/value_conversion.hpp | 9 - src/client/game/ui_scripting/script_value.cpp | 203 +++++- src/client/game/ui_scripting/script_value.hpp | 210 +++++- src/client/game/ui_scripting/types.cpp | 665 +++++++++--------- src/client/game/ui_scripting/types.hpp | 184 ++--- 25 files changed, 1506 insertions(+), 1642 deletions(-) delete mode 100644 src/client/game/ui_scripting/lua/context.cpp delete mode 100644 src/client/game/ui_scripting/lua/context.hpp delete mode 100644 src/client/game/ui_scripting/lua/engine.cpp delete mode 100644 src/client/game/ui_scripting/lua/engine.hpp delete mode 100644 src/client/game/ui_scripting/lua/error.cpp delete mode 100644 src/client/game/ui_scripting/lua/error.hpp delete mode 100644 src/client/game/ui_scripting/lua/scheduler.cpp delete mode 100644 src/client/game/ui_scripting/lua/scheduler.hpp delete mode 100644 src/client/game/ui_scripting/lua/value_conversion.cpp delete mode 100644 src/client/game/ui_scripting/lua/value_conversion.hpp diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index 97c3a027..a567fa92 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -10,7 +10,6 @@ #include "materials.hpp" #include "discord.hpp" -#include "ui_scripting.hpp" #include "game/ui_scripting/execution.hpp" #include @@ -187,13 +186,13 @@ namespace discord handlers.ready = ready; handlers.errored = errored; handlers.disconnected = errored; - handlers.joinGame = nullptr; //join_game + handlers.joinGame = nullptr; handlers.spectateGame = nullptr; - handlers.joinRequest = nullptr; //join_request + handlers.joinRequest = nullptr; Discord_Initialize("947125042930667530", &handlers, 1, nullptr); - //scheduler::once(download_default_avatar, scheduler::pipeline::async); + scheduler::once(download_default_avatar, scheduler::pipeline::async); scheduler::once([]() { diff --git a/src/client/component/input.cpp b/src/client/component/input.cpp index 45f55e08..d31dc888 100644 --- a/src/client/component/input.cpp +++ b/src/client/component/input.cpp @@ -4,7 +4,6 @@ #include "game/game.hpp" #include "game_console.hpp" -#include "ui_scripting.hpp" #include "game/ui_scripting/execution.hpp" #include @@ -18,7 +17,6 @@ namespace input void cl_char_event_stub(const int local_client_num, const int key) { - /* if (ui_scripting::lui_running()) { ui_scripting::notify("keypress", @@ -27,7 +25,6 @@ namespace input {"key", game::Key_KeynumToString(key, 0, 1)}, }); } - */ if (!game_console::console_char_event(local_client_num, key)) { @@ -39,7 +36,6 @@ namespace input void cl_key_event_stub(const int local_client_num, const int key, const int down) { - /* if (ui_scripting::lui_running()) { ui_scripting::notify(down ? "keydown" : "keyup", @@ -48,7 +44,6 @@ namespace input {"key", game::Key_KeynumToString(key, 0, 1)}, }); } - */ if (!game_console::console_key_event(local_client_num, key, down)) { diff --git a/src/client/component/lui.cpp b/src/client/component/lui.cpp index d8736114..53f652b4 100644 --- a/src/client/component/lui.cpp +++ b/src/client/component/lui.cpp @@ -15,14 +15,6 @@ namespace lui public: void post_unpack() override { - // Don't show create cod account popup - //utils::hook::set(0x14017C957, 0); - -//#ifdef _DEBUG - // Enable development menus (causes issues in sp) - //utils::hook::set(SELECT_VALUE(0x1400B4ABC, 0x1401AB779), 1); -//#endif - command::add("lui_open", [](const command::params& params) { if (params.size() <= 1) @@ -55,4 +47,4 @@ namespace lui }; } -//REGISTER_COMPONENT(lui::component) +REGISTER_COMPONENT(lui::component) diff --git a/src/client/component/scheduler.cpp b/src/client/component/scheduler.cpp index abe01fff..a5ef6f97 100644 --- a/src/client/component/scheduler.cpp +++ b/src/client/component/scheduler.cpp @@ -89,7 +89,7 @@ namespace scheduler utils::hook::detour r_end_frame_hook; utils::hook::detour g_run_frame_hook; utils::hook::detour main_frame_hook; - //utils::hook::detour hks_frame_hook; //no scripting for now + utils::hook::detour hks_frame_hook; void execute(const pipeline type) { @@ -209,7 +209,7 @@ namespace scheduler g_run_frame_hook.create(SELECT_VALUE(0x0, 0x417940_b), scheduler::server_frame_stub); main_frame_hook.create(SELECT_VALUE(0x0, 0x3438B0_b), scheduler::main_frame_stub); - //hks_frame_hook.create(SELECT_VALUE(0x0, 0x0), scheduler::hks_frame_stub); // no scripting for now + hks_frame_hook.create(SELECT_VALUE(0x0, 0x2792E0_b), scheduler::hks_frame_stub); } void pre_destroy() override diff --git a/src/client/component/stats.cpp b/src/client/component/stats.cpp index 8da3fa78..2684feb1 100644 --- a/src/client/component/stats.cpp +++ b/src/client/component/stats.cpp @@ -88,4 +88,4 @@ namespace stats }; } -// REGISTER_COMPONENT(stats::component) +REGISTER_COMPONENT(stats::component) diff --git a/src/client/component/ui_scripting.cpp b/src/client/component/ui_scripting.cpp index 46bf5332..75b89a0b 100644 --- a/src/client/component/ui_scripting.cpp +++ b/src/client/component/ui_scripting.cpp @@ -7,164 +7,339 @@ #include "scheduler.hpp" #include "command.hpp" -#include "ui_scripting.hpp" +#include "localized_strings.hpp" +#include "console.hpp" +#include "game_module.hpp" +#include "fps.hpp" +#include "server_list.hpp" -#include "game/ui_scripting/lua/engine.hpp" #include "game/ui_scripting/execution.hpp" -#include "game/ui_scripting/lua/error.hpp" +#include "game/scripting/execution.hpp" + +#include "ui_scripting.hpp" #include #include +#include namespace ui_scripting { namespace { - std::unordered_map converted_functions; + std::unordered_map> converted_functions; - utils::hook::detour hksi_lual_error_hook; - utils::hook::detour hksi_lual_error_hook2; utils::hook::detour hks_start_hook; utils::hook::detour hks_shutdown_hook; - utils::hook::detour hks_allocator_hook; - utils::hook::detour hks_frame_hook; - utils::hook::detour lui_error_hook; - utils::hook::detour hksi_hks_error_hook; + utils::hook::detour hks_package_require_hook; - bool error_hook_enabled = false; + utils::hook::detour hks_load_hook; + utils::hook::detour db_find_xasset_header_hook; - void hksi_lual_error_stub(game::hks::lua_State* s, const char* fmt, ...) + struct script { - char va_buffer[2048] = {0}; + std::string name; + std::string root; + }; - va_list ap; - va_start(ap, fmt); - vsprintf_s(va_buffer, fmt, ap); - va_end(ap); + struct globals_t + { + std::string in_require_script; + std::vector