mirror of
https://forge.banditvault.co.uk/racoon/MinecraftConsoles.git
synced 2026-05-22 04:44:37 +00:00
127 lines
3.5 KiB
C++
127 lines
3.5 KiB
C++
#include "stdafx.h"
|
|
|
|
#ifdef _WINDOWS64
|
|
|
|
#include "Windows64_Log.h"
|
|
|
|
#include <cstdio>
|
|
#include <cstdarg>
|
|
#include <cstring>
|
|
|
|
namespace LceLog
|
|
{
|
|
|
|
static FILE* s_logFile = nullptr;
|
|
static char s_logPath[MAX_PATH] = {};
|
|
static char s_prevLogPath[MAX_PATH] = {};
|
|
|
|
static void BuildLogPaths()
|
|
{
|
|
char exePath[MAX_PATH] = {};
|
|
GetModuleFileNameA(nullptr, exePath, MAX_PATH);
|
|
|
|
char* lastSlash = strrchr(exePath, '\\');
|
|
if (lastSlash)
|
|
{
|
|
*(lastSlash + 1) = '\0';
|
|
}
|
|
|
|
char logsDir[MAX_PATH] = {};
|
|
_snprintf_s(logsDir, sizeof(logsDir), _TRUNCATE, "%slogs", exePath);
|
|
|
|
// Ensure logs folder exists; ignore failure when it already exists.
|
|
CreateDirectoryA(logsDir, nullptr);
|
|
|
|
_snprintf_s(s_logPath, sizeof(s_logPath), _TRUNCATE, "%s\\lcelive.log", logsDir);
|
|
_snprintf_s(s_prevLogPath, sizeof(s_prevLogPath), _TRUNCATE, "%s\\lcelive.previous.log", logsDir);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Init — open logs\lcelive.log (rotating the previous one).
|
|
// ---------------------------------------------------------------------------
|
|
void Init()
|
|
{
|
|
BuildLogPaths();
|
|
|
|
// Rotate: lcelive.log -> lcelive.previous.log
|
|
if (s_logPath[0] != '\0' && s_prevLogPath[0] != '\0')
|
|
{
|
|
remove(s_prevLogPath);
|
|
rename(s_logPath, s_prevLogPath);
|
|
}
|
|
|
|
if (fopen_s(&s_logFile, s_logPath, "w") != 0 || !s_logFile)
|
|
{
|
|
s_logFile = nullptr;
|
|
OutputDebugStringA("[LceLog] Failed to open logs\\lcelive.log\n");
|
|
return;
|
|
}
|
|
|
|
// Write header so it's easy to tell sessions apart.
|
|
SYSTEMTIME st = {};
|
|
GetLocalTime(&st);
|
|
char header[128];
|
|
snprintf(header, sizeof(header),
|
|
"=== LCELive session started %04d-%02d-%02d %02d:%02d:%02d ===\n",
|
|
st.wYear, st.wMonth, st.wDay,
|
|
st.wHour, st.wMinute, st.wSecond);
|
|
fputs(header, s_logFile);
|
|
fflush(s_logFile);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Shutdown — flush and close.
|
|
// ---------------------------------------------------------------------------
|
|
void Shutdown()
|
|
{
|
|
if (!s_logFile)
|
|
return;
|
|
|
|
fputs("=== session ended ===\n", s_logFile);
|
|
fflush(s_logFile);
|
|
fclose(s_logFile);
|
|
s_logFile = nullptr;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Write — timestamped log entry. Safe to call before Init (silently skipped)
|
|
// and from any thread (FILE* writes are internally serialised on MSVC CRT).
|
|
// ---------------------------------------------------------------------------
|
|
void Write(const char* fmt, ...)
|
|
{
|
|
if (!s_logFile && !IsDebuggerPresent())
|
|
return;
|
|
|
|
// Build timestamp
|
|
SYSTEMTIME st = {};
|
|
GetLocalTime(&st);
|
|
char timeBuf[24];
|
|
snprintf(timeBuf, sizeof(timeBuf), "%02d:%02d:%02d.%03d",
|
|
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
|
|
|
// Format the caller's message
|
|
char msgBuf[2048];
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
vsnprintf(msgBuf, sizeof(msgBuf) - 1, fmt, args);
|
|
va_end(args);
|
|
msgBuf[sizeof(msgBuf) - 1] = '\0';
|
|
|
|
// Full line: "[HH:MM:SS.mmm] message\n"
|
|
char line[2048 + 32];
|
|
snprintf(line, sizeof(line), "[%s] %s\n", timeBuf, msgBuf);
|
|
|
|
if (s_logFile)
|
|
{
|
|
fputs(line, s_logFile);
|
|
fflush(s_logFile); // flush every write — we want to see crashes
|
|
}
|
|
|
|
// Also send to VS Output window when a debugger is attached.
|
|
OutputDebugStringA(line);
|
|
}
|
|
|
|
} // namespace LceLog
|
|
|
|
#endif // _WINDOWS64
|