All checks were successful
check-formatting / check-formatting (push) Successful in 4m8s
118 lines
3.1 KiB
C++
118 lines
3.1 KiB
C++
#include <std_include.hpp>
|
|
#include "loader/component_loader.hpp"
|
|
#include "game/dvars.hpp"
|
|
|
|
#include <utils/hook.hpp>
|
|
|
|
#include "gsc/extension.hpp"
|
|
|
|
#include "game_log.hpp"
|
|
#include "scheduler.hpp"
|
|
|
|
namespace game_log {
|
|
namespace {
|
|
int log_file = 0;
|
|
|
|
void g_scr_log_print() {
|
|
char string[1024]{};
|
|
std::size_t i_string_len = 0;
|
|
|
|
const auto i_num_parms = game::Scr_GetNumParam();
|
|
for (std::size_t i = 0; i < i_num_parms; ++i) {
|
|
const auto* psz_token = game::Scr_GetString(i);
|
|
const auto i_token_len = std::strlen(psz_token);
|
|
|
|
i_string_len += i_token_len;
|
|
if (i_string_len >= sizeof(string)) {
|
|
// Do not overflow the buffer
|
|
break;
|
|
}
|
|
|
|
game::I_strncat(string, sizeof(string), psz_token);
|
|
}
|
|
|
|
log_printf("%s", string);
|
|
}
|
|
|
|
void g_init_game_stub() {
|
|
game::Com_Printf(game::CON_CHANNEL_SERVER,
|
|
"------- Game Initialization -------\n");
|
|
game::Com_Printf(game::CON_CHANNEL_SERVER, "gamename: iw4x-sp\n");
|
|
game::Com_Printf(game::CON_CHANNEL_SERVER, "gamedate: %s\n", __DATE__);
|
|
|
|
if (*dvars::g_log->current.string == '\0') {
|
|
game::Com_Printf(game::CON_CHANNEL_SERVER, "Not logging to disk.\n");
|
|
} else {
|
|
game::FS_FOpenFileByMode(dvars::g_log->current.string, &log_file,
|
|
game::FS_APPEND_SYNC);
|
|
|
|
if (!log_file) {
|
|
game::Com_PrintWarning(game::CON_CHANNEL_SERVER,
|
|
"WARNING: Couldn't open logfile: %s\n");
|
|
} else {
|
|
log_printf(
|
|
"------------------------------------------------------------\n");
|
|
log_printf("InitGame\n");
|
|
}
|
|
}
|
|
|
|
utils::hook::invoke<void>(0x4FA880); // Vehicle_ClearServerDefs
|
|
}
|
|
|
|
void g_shutdown_game_stub() {
|
|
if (log_file) {
|
|
log_printf("ShutdownGame:\n");
|
|
log_printf(
|
|
"------------------------------------------------------------\n");
|
|
|
|
game::FS_FCloseFile(log_file);
|
|
log_file = 0;
|
|
}
|
|
|
|
utils::hook::invoke<void>(0x455F90); // Actor_ClearThreatBiasGroups
|
|
}
|
|
} // namespace
|
|
|
|
void log_printf(const char* fmt, ...) {
|
|
char string[1024]{};
|
|
char string2[1024]{};
|
|
va_list ap;
|
|
|
|
if (!log_file) {
|
|
return;
|
|
}
|
|
|
|
va_start(ap, fmt);
|
|
vsnprintf(string2, sizeof(string2), fmt, ap);
|
|
va_end(ap);
|
|
string2[sizeof(string2) - 1] = '\0';
|
|
|
|
const auto time = game::level->time / 1000;
|
|
const auto len =
|
|
game::Com_sprintf(string, sizeof(string), "%3i:%i%i %s", time / 60,
|
|
time % 60 / 10, time % 60 % 10, string2);
|
|
game::FS_Write(string, len, log_file);
|
|
}
|
|
|
|
class component final : public component_interface {
|
|
public:
|
|
static_assert(offsetof(game::level_locals_t, time) == 0x34);
|
|
|
|
void post_load() override {
|
|
utils::hook(0x4C75E0, g_init_game_stub, HOOK_CALL).install()->quick();
|
|
utils::hook(0x418B5A, g_shutdown_game_stub, HOOK_CALL).install()->quick();
|
|
|
|
scheduler::once(
|
|
[] {
|
|
dvars::g_log = game::Dvar_RegisterString(
|
|
"g_log", "games_sp.log", game::DVAR_NONE, "Log file name");
|
|
},
|
|
scheduler::pipeline::main);
|
|
|
|
gsc::add_function("logprint", g_scr_log_print);
|
|
}
|
|
};
|
|
} // namespace game_log
|
|
|
|
REGISTER_COMPONENT(game_log::component)
|