138 lines
2.9 KiB
C++
138 lines
2.9 KiB
C++
#include <std_include.hpp>
|
|
#include <loader/module_loader.hpp>
|
|
#include "game/game.hpp"
|
|
|
|
#include <utils/hook.hpp>
|
|
|
|
#include "game_log.hpp"
|
|
#include "scheduler.hpp"
|
|
#include "file_system.hpp"
|
|
#include "scripting.hpp"
|
|
#include "console.hpp"
|
|
|
|
const game::native::dvar_t* game_log::g_log;
|
|
const game::native::dvar_t* game_log::g_logSync;
|
|
|
|
int game_log::log_file_ = 0;
|
|
|
|
void game_log::g_log_printf(const char* fmt, ...)
|
|
{
|
|
char buf[1024]{};
|
|
char out[1024]{};
|
|
|
|
va_list va;
|
|
va_start(va, fmt);
|
|
vsnprintf_s(buf, _TRUNCATE, fmt, va);
|
|
va_end(va);
|
|
|
|
if (!log_file_)
|
|
{
|
|
return;
|
|
}
|
|
|
|
const auto time = game::native::mp::level->time / 1000;
|
|
const auto len = sprintf_s(out, "%3i:%i%i %s", time / 60, time % 60 / 10, time % 60 % 10, buf);
|
|
|
|
file_system::write(out, len, log_file_);
|
|
}
|
|
|
|
void game_log::gscr_log_print()
|
|
{
|
|
char buf[1024]{};
|
|
std::size_t out_chars = 0;
|
|
|
|
for (std::size_t i = 0; i < game::native::Scr_GetNumParam(); ++i)
|
|
{
|
|
const auto* value = game::native::Scr_GetString(i);
|
|
const auto len = std::strlen(value);
|
|
|
|
out_chars += len;
|
|
if (out_chars >= sizeof(buf))
|
|
{
|
|
// Do not overflow the buffer
|
|
break;
|
|
}
|
|
|
|
strncat_s(buf, value, _TRUNCATE);
|
|
}
|
|
|
|
g_log_printf("%s", buf);
|
|
}
|
|
|
|
void game_log::g_init_game_stub()
|
|
{
|
|
console::info("------- Game Initialization -------\n");
|
|
console::info("gamename: %s\n", reinterpret_cast<const char*>(0x7FFC68));
|
|
console::info("gamedate: %s\n", __DATE__);
|
|
|
|
const auto* log = g_log->current.string;
|
|
|
|
if (!*log)
|
|
{
|
|
console::info("Not logging to disk.\n");
|
|
}
|
|
else
|
|
{
|
|
file_system::open_file_by_mode(log, &log_file_, game::native::FS_APPEND_SYNC);
|
|
|
|
if (!log_file_)
|
|
{
|
|
console::info("WARNING: Couldn't open logfile: %s\n", log);
|
|
}
|
|
else
|
|
{
|
|
console::info("Logging to disk: '%s'.\n", log);
|
|
g_log_printf("------------------------------------------------------------\n");
|
|
g_log_printf("InitGame\n");
|
|
}
|
|
}
|
|
|
|
utils::hook::invoke<void>(0x5C2800);
|
|
}
|
|
|
|
void game_log::g_shutdown_game_stub(int free_scripts)
|
|
{
|
|
console::info("==== ShutdownGame (%d) ====\n", free_scripts);
|
|
|
|
if (log_file_)
|
|
{
|
|
g_log_printf("ShutdownGame:\n");
|
|
g_log_printf("------------------------------------------------------------\n");
|
|
|
|
game::native::FS_FCloseFile(log_file_);
|
|
log_file_ = 0;
|
|
}
|
|
|
|
utils::hook::invoke<void>(0x50C100, free_scripts);
|
|
}
|
|
|
|
void game_log::exit_level_stub()
|
|
{
|
|
g_log_printf("ExitLevel: executed\n");
|
|
}
|
|
|
|
void game_log::post_load()
|
|
{
|
|
if (!game::is_mp())
|
|
{
|
|
return;
|
|
}
|
|
|
|
utils::hook::set<void(*)()>(0x8AC858, gscr_log_print);
|
|
|
|
utils::hook(0x50D135, g_init_game_stub, HOOK_CALL).install()->quick();
|
|
scripting::on_shutdown(g_shutdown_game_stub);
|
|
|
|
utils::hook(0x50D5F4, exit_level_stub, HOOK_JUMP).install()->quick();
|
|
|
|
scheduler::once([]
|
|
{
|
|
g_log = game::native::Dvar_RegisterString("g_log", "games_mp.log",
|
|
game::native::DVAR_ARCHIVE, "Log file name");
|
|
g_logSync = game::native::Dvar_RegisterBool("g_logSync", false,
|
|
game::native::DVAR_NONE, "Enable synchronous logging");
|
|
}, scheduler::pipeline::main);
|
|
}
|
|
|
|
REGISTER_MODULE(game_log)
|