#include #include "loader/component_loader.hpp" #include "branding.hpp" #include "filesystem.hpp" #include #include namespace log_file { namespace { void com_open_log_file_stub() { time_t aclock; char time[32]{}; char log_file[game::MAX_OSPATH]; if (!game::Sys_IsMainThread() || *game::opening_qconsole) { return; } *game::opening_qconsole = true; tm new_time{}; _time64(&aclock); _localtime64_s(&new_time, &aclock); for (auto i = 0; i < 16; ++i) { const auto* file_name = (i == 0) ? "console.log" : utils::string::va("{0}.{1:03}", "console.log", i); game::I_strncpyz(log_file, file_name, sizeof(log_file)); if (!filesystem::file_rotate(log_file)) { continue; } *game::logfile = game::FS_FOpenTextFileWrite(log_file); if (*game::logfile) { game::Com_Printf(game::CON_CHANNEL_SYSTEM, "\'%s\'\n", game::Com_GetCommandLine()); (void)asctime_s(time, sizeof(time), &new_time); game::Com_Printf(game::CON_CHANNEL_SYSTEM, "Build %s. Logfile opened on %s\n", branding::get_build_number(), time); break; // Stop attempting further backups } } *game::opening_qconsole = false; *game::com_consoleLogOpenFailed = *game::logfile == 0; } } // namespace class component final : public component_interface { public: void post_load() override { utils::hook(0x603103, com_open_log_file_stub, HOOK_CALL) .install() // hook* ->quick(); } }; } // namespace log_file REGISTER_COMPONENT(log_file::component)