This commit is contained in:
Rim
2024-06-09 18:45:58 -04:00
24 changed files with 1267 additions and 1027 deletions

View File

@ -218,7 +218,7 @@ namespace blackbox
std::string generate_crash_info(const LPEXCEPTION_POINTERS exceptioninfo)
{
const auto& build_info = game::version_string;
std::string build_info = game::Com_GetVersionString();
const auto main_module = utilities::nt::library{};
const auto rip_address = exceptioninfo->ExceptionRecord->ExceptionAddress;

View File

@ -0,0 +1,212 @@
#include <std_include.hpp>
#include "command.hpp"
#include "definitions/game.hpp"
#include <utilities/hook.hpp>
#include <utilities/string.hpp>
#include <utilities/memory.hpp>
namespace command
{
namespace
{
std::unordered_map<std::string, command_param_function>& get_command_map()
{
static std::unordered_map<std::string, command_param_function> command_map{};
return command_map;
}
std::unordered_map<std::string, sv_command_param_function>& get_sv_command_map()
{
static std::unordered_map<std::string, sv_command_param_function> command_map{};
return command_map;
}
void execute_custom_command()
{
const params params{};
const auto command = utilities::string::to_lower(params[0]);
auto& map = get_command_map();
const auto entry = map.find(command);
if (entry != map.end())
{
entry->second(params);
}
}
void execute_custom_sv_command()
{
const params_sv params{};
const auto command = utilities::string::to_lower(params[0]);
auto& map = get_sv_command_map();
const auto entry = map.find(command);
if (entry != map.end())
{
entry->second(params);
}
}
game::CmdArgs* get_cmd_args()
{
return game::Sys_GetTLS()->cmdArgs;
}
}
params::params()
: nesting_(get_cmd_args()->nesting)
{
assert(this->nesting_ < game::CMD_MAX_NESTING);
}
params::params(const std::string& text)
: needs_end_(true)
{
auto* cmd_args = get_cmd_args();
game::Cmd_TokenizeStringKernel(0, 0, text.data(),
512 - cmd_args->totalUsedArgvPool, false, cmd_args);
this->nesting_ = cmd_args->nesting;
}
params::~params()
{
if (this->needs_end_)
{
game::Cmd_EndTokenizedString();
}
}
int params::size() const
{
return get_cmd_args()->argc[this->nesting_];
}
params_sv::params_sv()
: nesting_(game::sv_cmd_args->nesting)
{
assert(this->nesting_ < game::CMD_MAX_NESTING);
}
params_sv::params_sv(const std::string& text)
: needs_end_(true)
{
game::SV_Cmd_TokenizeString(text.data());
this->nesting_ = game::sv_cmd_args->nesting;
}
params_sv::~params_sv()
{
if (this->needs_end_)
{
game::SV_Cmd_EndTokenizedString();
}
}
int params_sv::size() const
{
return game::sv_cmd_args->argc[this->nesting_];
}
const char* params_sv::get(const int index) const
{
if (index >= this->size())
{
return "";
}
return game::sv_cmd_args->argv[this->nesting_][index];
}
std::string params_sv::join(const int index) const
{
std::string result;
for (auto i = index; i < this->size(); ++i)
{
if (i > index) result.append(" ");
result.append(this->get(i));
}
return result;
}
const char* params::get(const int index) const
{
if (index >= this->size())
{
return "";
}
return get_cmd_args()->argv[this->nesting_][index];
}
std::string params::join(const int index) const
{
std::string result = {};
for (auto i = index; i < this->size(); i++)
{
if (i > index) result.append(" ");
result.append(this->get(i));
}
return result;
}
void add(const std::string& command, command_function function, const char* desc)
{
add(command, [f = std::move(function)](const params&)
{
f();
});
}
void add(const std::string& command, command_param_function function, const char* desc)
{
auto lower_command = utilities::string::to_lower(command);
auto& map = get_command_map();
const auto is_registered = map.contains(lower_command);
map[std::move(lower_command)] = std::move(function);
if (is_registered)
{
return;
}
auto& allocator = *utilities::memory::get_allocator();
auto* cmd_function = allocator.allocate<game::cmd_function_t>();
auto cmdRef = game::AssetRef(command.data());
variables::commands_table.push_back({ command, desc, fnv1a::generate_hash(command.data()) });
game::Cmd_AddCommandInternal(&cmdRef, execute_custom_command, cmd_function);
}
void add_sv(const std::string& command, sv_command_param_function function, const char* desc)
{
auto lower_command = utilities::string::to_lower(command);
auto& map = get_sv_command_map();
const auto is_registered = map.contains(lower_command);
map[std::move(lower_command)] = std::move(function);
if (is_registered)
{
return;
}
auto& allocator = *utilities::memory::get_allocator();
auto cmdRef = game::AssetRef(command.data());
variables::commands_table.push_back({ command, desc, fnv1a::generate_hash(command.data()) });
game::Cmd_AddCommandInternal(&cmdRef, game::Cbuf_AddServerText_f,
allocator.allocate<game::cmd_function_t>());
game::Cmd_AddServerCommandInternal(&cmdRef, execute_custom_sv_command,
allocator.allocate<game::cmd_function_t>());
}
}

View File

@ -0,0 +1,67 @@
#pragma once
namespace command
{
class params
{
public:
params();
params(const std::string& text);
~params();
params(params&&) = delete;
params(const params&) = delete;
params& operator=(params&&) = delete;
params& operator=(const params&) = delete;
[[nodiscard]] int size() const;
[[nodiscard]] const char* get(int index) const;
[[nodiscard]] std::string join(int index) const;
[[nodiscard]] const char* operator[](const int index) const
{
return this->get(index); //
}
private:
bool needs_end_{false};
int nesting_;
};
class params_sv
{
public:
params_sv();
params_sv(const std::string& text);
~params_sv();
params_sv(params_sv&&) = delete;
params_sv(const params_sv&) = delete;
params_sv& operator=(params_sv&&) = delete;
params_sv& operator=(const params_sv&) = delete;
[[nodiscard]] int size() const;
[[nodiscard]] const char* get(int index) const;
[[nodiscard]] std::string join(int index) const;
[[nodiscard]] const char* operator[](const int index) const
{
return this->get(index); //
}
private:
bool needs_end_{false};
int nesting_;
};
using command_function = std::function<void()>;
using command_param_function = std::function<void(const params&)>;
using sv_command_param_function = std::function<void(const params_sv&)>;
void add(const std::string& command, command_function function, const char* desc = "");
void add(const std::string& command, command_param_function function, const char* desc = "");
void add_sv(const std::string& command, sv_command_param_function function, const char* desc = "");
}

View File

@ -1,6 +1,5 @@
#include <std_include.hpp>
#include "definitions/game.hpp"
#include "definitions/game_runtime_errors.hpp"
#include "component/scheduler.hpp"
#include "loader/component_loader.hpp"
@ -74,7 +73,7 @@ namespace debugging
void sys_error_stub(uint32_t code, const char* message)
{
const char* error_message = game::runtime_errors::get_error_message(code);
const char* error_message = runtime_errors::get_error_message(code);
if (error_message)
{

View File

@ -13,7 +13,7 @@ namespace dvars
{
void fetch_dvar_pointers()
{
for (auto& dvar : variables::dvars_record)
for (auto& dvar : variables::dvars_table)
{
dvar.pointer = spoofcall::invoke<uintptr_t>(game::Dvar_FindVar, dvar.name.data());
}
@ -248,9 +248,9 @@ namespace dvars
{
if (hashRef == 0) return NULL;
auto it = std::find_if(variables::dvars_record.begin(), variables::dvars_record.end(), [&hashRef](variables::varEntry& i) { return i.fnv1a == hashRef; });
auto it = std::find_if(variables::dvars_table.begin(), variables::dvars_table.end(), [&hashRef](variables::varEntry& i) { return i.fnv1a == hashRef; });
if (it != variables::dvars_record.end() && it->pointer)
if (it != variables::dvars_table.end() && it->pointer)
{
return reinterpret_cast<game::dvar_t*>(it->pointer);
}
@ -265,9 +265,9 @@ namespace dvars
game::dvar_t* find_dvar(const std::string& nameRef)
{
auto it = std::find_if(variables::dvars_record.begin(), variables::dvars_record.end(), [&nameRef](variables::varEntry& i) { return utilities::string::compare(i.name, nameRef); });
auto it = std::find_if(variables::dvars_table.begin(), variables::dvars_table.end(), [&nameRef](variables::varEntry& i) { return utilities::string::compare(i.name, nameRef); });
if (it != variables::dvars_record.end() && it->pointer)
if (it != variables::dvars_table.end() && it->pointer)
{
return reinterpret_cast<game::dvar_t*>(it->pointer);
}

View File

@ -184,7 +184,7 @@ namespace game_console
{
double required_ratio = exact ? 1.00 : 0.01;
for (const auto& dvar : variables::dvars_record)
for (const auto& dvar : variables::dvars_table)
{
if (dvars::find_dvar(dvar.fnv1a) && utilities::string::match(input, dvar.name) >= required_ratio)
{
@ -202,7 +202,7 @@ namespace game_console
suggestions.push_back({ input, "", fnv1a::generate_hash(input.data()), reinterpret_cast<uintptr_t>(dvars::find_dvar(input)) });
}
for (const auto& cmd : variables::commands_record)
for (const auto& cmd : variables::commands_table)
{
if (utilities::string::match(input, cmd.name) >= required_ratio)
{
@ -374,7 +374,13 @@ namespace game_console
auto width = (con.screen_max[0] - con.screen_min[0]) - 12.0f;
auto height = ((con.screen_max[1] - con.screen_min[1]) - 32.0f) - 12.0f;
game::R_AddCmdDrawText(game::version_string.data(), 0x7FFFFFFF, R_DrawTextFont, x, ((height - 16.0f) + y) + con.font_height, con.font_scale, con.font_scale, 0.0f, con_outputVersionStringColor, 0);
char sysinfo_version[256];
bool result1 = utilities::hook::invoke<bool>(game::Live_SystemInfo, 0, 0, sysinfo_version, 256);
char sysinfo_livebits[256];
bool result2 = utilities::hook::invoke<bool>(game::Live_SystemInfo, 0, 1, sysinfo_livebits, 256);
const char* info = utilities::string::va("Project-BO4 1.0.0, Engine Version: %s, LiveBits: %s", sysinfo_version, sysinfo_livebits);
game::R_AddCmdDrawText(info, 0x7FFFFFFF, R_DrawTextFont, x, ((height - 16.0f) + y) + con.font_height, con.font_scale, con.font_scale, 0.0f, con_outputVersionStringColor, 0);
draw_output_scrollbar(x, y, width, height, output);
draw_output_text(x, y, output);

View File

@ -3,7 +3,6 @@
#include "gsc_custom.hpp"
#include "hashes.hpp"
#include "definitions/game.hpp"
#include "definitions/game_runtime_errors.hpp"
#include "definitions/xassets.hpp"
#include "loader/component_loader.hpp"
#include "component/scheduler.hpp"
@ -53,7 +52,7 @@ namespace gsc_funcs
vsprintf_s(buffer[inst], message, va);
va_end(va);
game::ScrVm_Error(game::runtime_errors::custom_error_id, inst, buffer[inst], terminal);
game::ScrVm_Error(runtime_errors::custom_error_id, inst, buffer[inst], terminal);
}
const char* lookup_hash(game::scriptInstance_t inst, const char* type, uint64_t hash)
@ -1329,13 +1328,13 @@ namespace gsc_funcs
break;
default:
// put custom message for our id
if (code == game::runtime_errors::custom_error_id)
if (code == runtime_errors::custom_error_id)
{
game::scrVarPub[inst].error_message = unused;
}
else
{
game::scrVarPub[inst].error_message = game::runtime_errors::get_error_message(code);
game::scrVarPub[inst].error_message = runtime_errors::get_error_message(code);
}
break;
}

View File

@ -72,11 +72,6 @@ namespace logger
write(LOG_TYPE_INFO, " T8-Mod Initializing ... %s[0x%llX]", utilities::nt::library{}.get_name().c_str(), utilities::nt::library{}.get_ptr());
write(LOG_TYPE_INFO, "=======================================================================================================");
}
void post_unpack() override
{
/* PLACE_HOLDER */
}
};
}
REGISTER_COMPONENT(logger::component)

View File

@ -1,15 +1,15 @@
#include <std_include.hpp>
#include "definitions/xassets.hpp"
#include "definitions/game.hpp"
#include "game_console.hpp"
#include "gsc_funcs.hpp"
#include "gsc_custom.hpp"
#include "dvars.hpp"
#include "hashes.hpp"
#include "command.hpp"
#include "game_console.hpp"
#include "loader/component_loader.hpp"
#include "definitions/xassets.hpp"
#include "definitions/game.hpp"
#include <utilities/io.hpp>
#include <utilities/hook.hpp>
@ -1094,7 +1094,7 @@ namespace mods {
mod_storage storage{};
void load_mods_cmd()
void mods_reload_f()
{
if (!game::Com_IsRunningUILevel())
{
@ -1267,8 +1267,7 @@ namespace mods {
hksl_loadfile_hook.create(0x14375D6A0_g, hksl_loadfile_stub);
bg_cache_sync_hook.create(0x1405CE0B0_g, bg_cache_sync_stub);
// register load mods command
Cmd_AddCommand("reload_mods", load_mods_cmd);
command::add("reload_mods", mods_reload_f, "Reload the shield mods");
}
};
}