6arelyFuture eb318d32c5
All checks were successful
check-formatting / check-formatting (push) Successful in 4m8s
fix many issues with this repo
2025-04-11 10:41:28 +02:00

137 lines
3.8 KiB
C++

#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/dvars.hpp"
#include "game/engine/scoped_critical_section.hpp"
#include <utils/hook.hpp>
#include "command.hpp"
#include "scheduler.hpp"
namespace debug {
namespace {
void com_assert_f() { assert("a" && false); }
void com_bug_f(const command::params& params) {
char new_file_name[MAX_PATH]{};
char to_ospath[MAX_PATH]{};
char from_ospath[MAX_PATH]{};
const char* bug{};
if (!*game::logfile) {
game::Com_PrintError(game::CON_CHANNEL_ERROR,
"CopyFile failed: logfile wasn't opened\n");
return;
}
if (params.size() == 2) {
bug = params.get(1);
} else {
assert(dvars::bug_name);
bug = dvars::bug_name->current.string;
}
game::Com_sprintf(new_file_name, sizeof(new_file_name), "%s_%s.log", bug,
game::Live_GetLocalClientName(game::CONTROLLER_INDEX_0));
game::engine::scoped_critical_section lock(game::CRITSECT_CONSOLE,
game::SCOPED_CRITSECT_NORMAL);
if (*game::logfile) {
game::FS_FCloseFile(*game::logfile);
*game::logfile = 0;
}
game::FS_BuildOSPath(std::filesystem::current_path().string().c_str(), "",
"console.log", from_ospath);
game::FS_BuildOSPath(std::filesystem::current_path().string().c_str(), "",
new_file_name, to_ospath);
const auto result = CopyFileA(from_ospath, to_ospath, 0);
game::Com_OpenLogFile();
lock.leave_crit_sect();
if (!result) {
game::Com_PrintError(game::CON_CHANNEL_ERROR, "CopyFile failed(%d) %s %s\n",
GetLastError(), "console.log", new_file_name);
}
}
void com_bug_name_inc_f() {
char buf[MAX_PATH]{};
if (std::strlen(dvars::bug_name->current.string) < 4) {
game::Dvar_SetString(dvars::bug_name, "bug0");
return;
}
if (std::strncmp(dvars::bug_name->current.string, "bug", 3) != 0) {
game::Dvar_SetString(dvars::bug_name, "bug0");
return;
}
const auto n = std::strtol(dvars::bug_name->current.string + 3, nullptr, 10);
game::Com_sprintf(buf, sizeof(buf), "bug%d", n + 1);
game::Dvar_SetString(dvars::bug_name, buf);
}
void g_print_fast_file_errors(const char* fastfile) {
assert(fastfile);
const auto rawfile_buf_large = std::make_unique<char[]>(0x18000);
auto* rawfile_buf = rawfile_buf_large.get();
auto* text = game::DB_ReadRawFile(fastfile, rawfile_buf, 0x18000);
assert(text);
if (*text) {
game::Com_PrintError(game::CON_CHANNEL_ERROR,
"There were errors when building fast file '%s'\n",
fastfile);
game::Com_PrintError(game::CON_CHANNEL_ERROR, "%s", text);
} else {
game::Com_Printf(game::CON_CHANNEL_DONT_FILTER,
"There were no errors when building fast file '%s'\n",
fastfile);
}
}
void g_init_game_stub() {
utils::hook::invoke<void>(0x4D6410);
g_print_fast_file_errors("code_post_gfx");
g_print_fast_file_errors("common");
g_print_fast_file_errors((*dvars::sv_mapname)->current.string);
}
} // namespace
class component final : public component_interface {
public:
static_assert(sizeof(RTL_CRITICAL_SECTION) == 0x18);
void post_load() override {
utils::hook::set<void (*)()>(0x604203, com_assert_f);
scheduler::once(
[] {
dvars::bug_name = game::Dvar_RegisterString(
"bug_name", "bug0", game::DVAR_CHEAT | game::DVAR_CODINFO,
"Name appended to the copied console log");
},
scheduler::pipeline::main);
command::add("bug", com_bug_f);
command::add("bug_name_inc", com_bug_name_inc_f);
#ifdef _DEBUG
utils::hook(0x4C79DF, g_init_game_stub, HOOK_CALL)
.install() // hook*
->quick(); // Scr_FreeEntityList
#endif
}
};
} // namespace debug
REGISTER_COMPONENT(debug::component)