aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDLL/logging
diff options
context:
space:
mode:
Diffstat (limited to 'NorthstarDLL/logging')
-rw-r--r--NorthstarDLL/logging/crashhandler.cpp590
-rw-r--r--NorthstarDLL/logging/crashhandler.h97
-rw-r--r--NorthstarDLL/logging/logging.cpp302
-rw-r--r--NorthstarDLL/logging/logging.h136
-rw-r--r--NorthstarDLL/logging/loghooks.cpp261
-rw-r--r--NorthstarDLL/logging/loghooks.h1
-rw-r--r--NorthstarDLL/logging/sourceconsole.cpp91
-rw-r--r--NorthstarDLL/logging/sourceconsole.h85
8 files changed, 0 insertions, 1563 deletions
diff --git a/NorthstarDLL/logging/crashhandler.cpp b/NorthstarDLL/logging/crashhandler.cpp
deleted file mode 100644
index a01de5a1..00000000
--- a/NorthstarDLL/logging/crashhandler.cpp
+++ /dev/null
@@ -1,590 +0,0 @@
-#include "crashhandler.h"
-#include "config/profile.h"
-#include "dedicated/dedicated.h"
-#include "util/version.h"
-#include "mods/modmanager.h"
-#include "plugins/plugins.h"
-
-#include <minidumpapiset.h>
-
-#define CRASHHANDLER_MAX_FRAMES 32
-#define CRASHHANDLER_GETMODULEHANDLE_FAIL "GetModuleHandleExA failed!"
-
-//-----------------------------------------------------------------------------
-// Purpose: Vectored exception callback
-//-----------------------------------------------------------------------------
-LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS* pExceptionInfo)
-{
- g_pCrashHandler->Lock();
-
- g_pCrashHandler->SetExceptionInfos(pExceptionInfo);
-
- // Check if we should handle this
- // NOTE [Fifty]: This gets called before even a try{} catch() {} can handle an exception
- // we don't handle these unless "-crash_handle_all" is passed as a launch arg
- if (!g_pCrashHandler->IsExceptionFatal() && !g_pCrashHandler->GetAllFatal())
- {
- g_pCrashHandler->Unlock();
- return EXCEPTION_CONTINUE_SEARCH;
- }
-
- // Don't run if a debbuger is attached
- if (IsDebuggerPresent())
- {
- g_pCrashHandler->Unlock();
- return EXCEPTION_CONTINUE_SEARCH;
- }
-
- // Prevent recursive calls
- if (g_pCrashHandler->GetState())
- {
- g_pCrashHandler->Unlock();
- ExitProcess(1);
- }
-
- g_pCrashHandler->SetState(true);
-
- // Needs to be called first as we use the members this sets later on
- g_pCrashHandler->SetCrashedModule();
-
- // Format
- g_pCrashHandler->FormatException();
- g_pCrashHandler->FormatCallstack();
- g_pCrashHandler->FormatRegisters();
- g_pCrashHandler->FormatLoadedMods();
- g_pCrashHandler->FormatLoadedPlugins();
- g_pCrashHandler->FormatModules();
-
- // Flush
- NS::log::FlushLoggers();
-
- // Write minidump
- g_pCrashHandler->WriteMinidump();
-
- // Show message box
- g_pCrashHandler->ShowPopUpMessage();
-
- g_pCrashHandler->Unlock();
-
- // We showed the "Northstar has crashed" message box
- // make sure we terminate
- if (!g_pCrashHandler->IsExceptionFatal())
- ExitProcess(1);
-
- return EXCEPTION_EXECUTE_HANDLER;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: console control signal handler
-//-----------------------------------------------------------------------------
-BOOL WINAPI ConsoleCtrlRoutine(DWORD dwCtrlType)
-{
- // NOTE [Fifty]: When closing the process by closing the console we don't want
- // to trigger the crash handler so we remove it
- switch (dwCtrlType)
- {
- case CTRL_CLOSE_EVENT:
- spdlog::info("Exiting due to console close...");
- delete g_pCrashHandler;
- g_pCrashHandler = nullptr;
- std::exit(EXIT_SUCCESS);
- return TRUE;
- }
-
- return FALSE;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Constructor
-//-----------------------------------------------------------------------------
-CCrashHandler::CCrashHandler()
- : m_hExceptionFilter(nullptr)
- , m_pExceptionInfos(nullptr)
- , m_bHasSetConsolehandler(false)
- , m_bAllExceptionsFatal(false)
- , m_bHasShownCrashMsg(false)
- , m_bState(false)
-{
- Init();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Destructor
-//-----------------------------------------------------------------------------
-CCrashHandler::~CCrashHandler()
-{
- Shutdown();
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Initilazes crash handler
-//-----------------------------------------------------------------------------
-void CCrashHandler::Init()
-{
- m_hExceptionFilter = AddVectoredExceptionHandler(TRUE, ExceptionFilter);
- m_bHasSetConsolehandler = SetConsoleCtrlHandler(ConsoleCtrlRoutine, TRUE);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Shutdowns crash handler
-//-----------------------------------------------------------------------------
-void CCrashHandler::Shutdown()
-{
- if (m_hExceptionFilter)
- {
- RemoveVectoredExceptionHandler(m_hExceptionFilter);
- m_hExceptionFilter = nullptr;
- }
-
- if (m_bHasSetConsolehandler)
- {
- SetConsoleCtrlHandler(ConsoleCtrlRoutine, FALSE);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Sets the exception info
-//-----------------------------------------------------------------------------
-void CCrashHandler::SetExceptionInfos(EXCEPTION_POINTERS* pExceptionPointers)
-{
- m_pExceptionInfos = pExceptionPointers;
-}
-//-----------------------------------------------------------------------------
-// Purpose: Sets the exception stirngs for message box
-//-----------------------------------------------------------------------------
-void CCrashHandler::SetCrashedModule()
-{
- LPCSTR pCrashAddress = static_cast<LPCSTR>(m_pExceptionInfos->ExceptionRecord->ExceptionAddress);
- HMODULE hCrashedModule;
- if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, pCrashAddress, &hCrashedModule))
- {
- m_svCrashedModule = CRASHHANDLER_GETMODULEHANDLE_FAIL;
- m_svCrashedOffset = "";
-
- DWORD dwErrorID = GetLastError();
- if (dwErrorID != 0)
- {
- LPSTR pszBuffer;
- DWORD dwSize = FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- dwErrorID,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR)&pszBuffer,
- 0,
- NULL);
-
- if (dwSize > 0)
- {
- m_svError = pszBuffer;
- LocalFree(pszBuffer);
- }
- }
-
- return;
- }
-
- // Get module filename
- CHAR szCrashedModulePath[MAX_PATH];
- GetModuleFileNameExA(GetCurrentProcess(), hCrashedModule, szCrashedModulePath, sizeof(szCrashedModulePath));
-
- const CHAR* pszCrashedModuleFileName = strrchr(szCrashedModulePath, '\\') + 1;
-
- // Get relative address
- LPCSTR pModuleBase = reinterpret_cast<LPCSTR>(pCrashAddress - reinterpret_cast<LPCSTR>(hCrashedModule));
-
- m_svCrashedModule = pszCrashedModuleFileName;
- m_svCrashedOffset = fmt::format("{:#x}", reinterpret_cast<DWORD64>(pModuleBase));
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Gets the exception null terminated stirng
-//-----------------------------------------------------------------------------
-
-const CHAR* CCrashHandler::GetExceptionString() const
-{
- return GetExceptionString(m_pExceptionInfos->ExceptionRecord->ExceptionCode);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Gets the exception null terminated stirng
-//-----------------------------------------------------------------------------
-const CHAR* CCrashHandler::GetExceptionString(DWORD dwExceptionCode) const
-{
- // clang-format off
- switch (dwExceptionCode)
- {
- case EXCEPTION_ACCESS_VIOLATION: return "EXCEPTION_ACCESS_VIOLATION";
- case EXCEPTION_DATATYPE_MISALIGNMENT: return "EXCEPTION_DATATYPE_MISALIGNMENT";
- case EXCEPTION_BREAKPOINT: return "EXCEPTION_BREAKPOINT";
- case EXCEPTION_SINGLE_STEP: return "EXCEPTION_SINGLE_STEP";
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
- case EXCEPTION_FLT_DENORMAL_OPERAND: return "EXCEPTION_FLT_DENORMAL_OPERAND";
- case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
- case EXCEPTION_FLT_INEXACT_RESULT: return "EXCEPTION_FLT_INEXACT_RESULT";
- case EXCEPTION_FLT_INVALID_OPERATION: return "EXCEPTION_FLT_INVALID_OPERATION";
- case EXCEPTION_FLT_OVERFLOW: return "EXCEPTION_FLT_OVERFLOW";
- case EXCEPTION_FLT_STACK_CHECK: return "EXCEPTION_FLT_STACK_CHECK";
- case EXCEPTION_FLT_UNDERFLOW: return "EXCEPTION_FLT_UNDERFLOW";
- case EXCEPTION_INT_DIVIDE_BY_ZERO: return "EXCEPTION_INT_DIVIDE_BY_ZERO";
- case EXCEPTION_INT_OVERFLOW: return "EXCEPTION_INT_OVERFLOW";
- case EXCEPTION_PRIV_INSTRUCTION: return "EXCEPTION_PRIV_INSTRUCTION";
- case EXCEPTION_IN_PAGE_ERROR: return "EXCEPTION_IN_PAGE_ERROR";
- case EXCEPTION_ILLEGAL_INSTRUCTION: return "EXCEPTION_ILLEGAL_INSTRUCTION";
- case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
- case EXCEPTION_STACK_OVERFLOW: return "EXCEPTION_STACK_OVERFLOW";
- case EXCEPTION_INVALID_DISPOSITION: return "EXCEPTION_INVALID_DISPOSITION";
- case EXCEPTION_GUARD_PAGE: return "EXCEPTION_GUARD_PAGE";
- case EXCEPTION_INVALID_HANDLE: return "EXCEPTION_INVALID_HANDLE";
- case 3765269347: return "RUNTIME_EXCEPTION";
- }
- // clang-format on
- return "UNKNOWN_EXCEPTION";
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns true if exception is known
-//-----------------------------------------------------------------------------
-bool CCrashHandler::IsExceptionFatal() const
-{
- return IsExceptionFatal(m_pExceptionInfos->ExceptionRecord->ExceptionCode);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Returns true if exception is known
-//-----------------------------------------------------------------------------
-bool CCrashHandler::IsExceptionFatal(DWORD dwExceptionCode) const
-{
- // clang-format off
- switch (dwExceptionCode)
- {
- case EXCEPTION_ACCESS_VIOLATION:
- case EXCEPTION_DATATYPE_MISALIGNMENT:
- case EXCEPTION_BREAKPOINT:
- case EXCEPTION_SINGLE_STEP:
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- case EXCEPTION_FLT_DENORMAL_OPERAND:
- case EXCEPTION_FLT_DIVIDE_BY_ZERO:
- case EXCEPTION_FLT_INEXACT_RESULT:
- case EXCEPTION_FLT_INVALID_OPERATION:
- case EXCEPTION_FLT_OVERFLOW:
- case EXCEPTION_FLT_STACK_CHECK:
- case EXCEPTION_FLT_UNDERFLOW:
- case EXCEPTION_INT_DIVIDE_BY_ZERO:
- case EXCEPTION_INT_OVERFLOW:
- case EXCEPTION_PRIV_INSTRUCTION:
- case EXCEPTION_IN_PAGE_ERROR:
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- case EXCEPTION_STACK_OVERFLOW:
- case EXCEPTION_INVALID_DISPOSITION:
- case EXCEPTION_GUARD_PAGE:
- case EXCEPTION_INVALID_HANDLE:
- return true;
- }
- // clang-format on
- return false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Shows a message box
-//-----------------------------------------------------------------------------
-void CCrashHandler::ShowPopUpMessage()
-{
- if (m_bHasShownCrashMsg)
- return;
-
- m_bHasShownCrashMsg = true;
-
- if (!IsDedicatedServer())
- {
- std::string svMessage = fmt::format(
- "Northstar has crashed! Crash info can be found at {}/logs!\n\n{}\n{} + {}",
- GetNorthstarPrefix(),
- GetExceptionString(),
- m_svCrashedModule,
- m_svCrashedOffset);
-
- MessageBoxA(GetForegroundWindow(), svMessage.c_str(), "Northstar has crashed!", MB_ICONERROR | MB_OK);
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCrashHandler::FormatException()
-{
- spdlog::error("-------------------------------------------");
- spdlog::error("Northstar has crashed!");
- spdlog::error("\tVersion: {}", version);
- if (!m_svError.empty())
- {
- spdlog::info("\tEncountered an error when gathering crash information!");
- spdlog::info("\tWinApi Error: {}", m_svError.c_str());
- }
- spdlog::error("\t{}", GetExceptionString());
-
- DWORD dwExceptionCode = m_pExceptionInfos->ExceptionRecord->ExceptionCode;
- if (dwExceptionCode == EXCEPTION_ACCESS_VIOLATION || dwExceptionCode == EXCEPTION_IN_PAGE_ERROR)
- {
- ULONG_PTR uExceptionInfo0 = m_pExceptionInfos->ExceptionRecord->ExceptionInformation[0];
- ULONG_PTR uExceptionInfo1 = m_pExceptionInfos->ExceptionRecord->ExceptionInformation[1];
-
- if (!uExceptionInfo0)
- spdlog::error("\tAttempted to read from: {:#x}", uExceptionInfo1);
- else if (uExceptionInfo0 == 1)
- spdlog::error("\tAttempted to write to: {:#x}", uExceptionInfo1);
- else if (uExceptionInfo0 == 8)
- spdlog::error("\tData Execution Prevention (DEP) at: {:#x}", uExceptionInfo1);
- else
- spdlog::error("\tUnknown access violation at: {:#x}", uExceptionInfo1);
- }
-
- spdlog::error("\tAt: {} + {}", m_svCrashedModule, m_svCrashedOffset);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCrashHandler::FormatCallstack()
-{
- spdlog::error("Callstack:");
-
- PVOID pFrames[CRASHHANDLER_MAX_FRAMES];
-
- int iFrames = RtlCaptureStackBackTrace(0, CRASHHANDLER_MAX_FRAMES, pFrames, NULL);
-
- // Above call gives us frames after the crash occured, we only want to print the ones starting from where
- // the exception was called
- bool bSkipExceptionHandlingFrames = true;
-
- // We ran into an error when getting the offset, just print all frames
- if (m_svCrashedOffset.empty())
- bSkipExceptionHandlingFrames = false;
-
- for (int i = 0; i < iFrames; i++)
- {
- const CHAR* pszModuleFileName;
-
- LPCSTR pAddress = static_cast<LPCSTR>(pFrames[i]);
- HMODULE hModule;
- if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, pAddress, &hModule))
- {
- pszModuleFileName = CRASHHANDLER_GETMODULEHANDLE_FAIL;
- // If we fail here it's too late to do any damage control
- }
- else
- {
- CHAR szModulePath[MAX_PATH];
- GetModuleFileNameExA(GetCurrentProcess(), hModule, szModulePath, sizeof(szModulePath));
- pszModuleFileName = strrchr(szModulePath, '\\') + 1;
- }
-
- // Get relative address
- LPCSTR pCrashOffset = reinterpret_cast<LPCSTR>(pAddress - reinterpret_cast<LPCSTR>(hModule));
- std::string svCrashOffset = fmt::format("{:#x}", reinterpret_cast<DWORD64>(pCrashOffset));
-
- // Should we log this frame
- if (bSkipExceptionHandlingFrames)
- {
- if (m_svCrashedModule == pszModuleFileName && m_svCrashedOffset == svCrashOffset)
- {
- bSkipExceptionHandlingFrames = false;
- }
- else
- {
- continue;
- }
- }
-
- // Log module + offset
- spdlog::error("\t{} + {:#x}", pszModuleFileName, reinterpret_cast<DWORD64>(pCrashOffset));
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCrashHandler::FormatFlags(const CHAR* pszRegister, DWORD nValue)
-{
- spdlog::error("\t{}: {:#b}", pszRegister, nValue);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCrashHandler::FormatIntReg(const CHAR* pszRegister, DWORD64 nValue)
-{
- spdlog::error("\t{}: {:#x}", pszRegister, nValue);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCrashHandler::FormatFloatReg(const CHAR* pszRegister, M128A nValue)
-{
- DWORD nVec[4] = {
- static_cast<DWORD>(nValue.Low & UINT_MAX),
- static_cast<DWORD>(nValue.Low >> 32),
- static_cast<DWORD>(nValue.High & UINT_MAX),
- static_cast<DWORD>(nValue.High >> 32)};
-
- spdlog::error(
- "\t{}: [ {:G}, {:G}, {:G}, {:G} ]; [ {:#x}, {:#x}, {:#x}, {:#x} ]",
- pszRegister,
- static_cast<float>(nVec[0]),
- static_cast<float>(nVec[1]),
- static_cast<float>(nVec[2]),
- static_cast<float>(nVec[3]),
- nVec[0],
- nVec[1],
- nVec[2],
- nVec[3]);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCrashHandler::FormatRegisters()
-{
- spdlog::error("Registers:");
-
- PCONTEXT pContext = m_pExceptionInfos->ContextRecord;
-
- FormatFlags("Flags:", pContext->ContextFlags);
-
- FormatIntReg("Rax", pContext->Rax);
- FormatIntReg("Rcx", pContext->Rcx);
- FormatIntReg("Rdx", pContext->Rdx);
- FormatIntReg("Rbx", pContext->Rbx);
- FormatIntReg("Rsp", pContext->Rsp);
- FormatIntReg("Rbp", pContext->Rbp);
- FormatIntReg("Rsi", pContext->Rsi);
- FormatIntReg("Rdi", pContext->Rdi);
- FormatIntReg("R8 ", pContext->R8);
- FormatIntReg("R9 ", pContext->R9);
- FormatIntReg("R10", pContext->R10);
- FormatIntReg("R11", pContext->R11);
- FormatIntReg("R12", pContext->R12);
- FormatIntReg("R13", pContext->R13);
- FormatIntReg("R14", pContext->R14);
- FormatIntReg("R15", pContext->R15);
- FormatIntReg("Rip", pContext->Rip);
-
- FormatFloatReg("Xmm0 ", pContext->Xmm0);
- FormatFloatReg("Xmm1 ", pContext->Xmm1);
- FormatFloatReg("Xmm2 ", pContext->Xmm2);
- FormatFloatReg("Xmm3 ", pContext->Xmm3);
- FormatFloatReg("Xmm4 ", pContext->Xmm4);
- FormatFloatReg("Xmm5 ", pContext->Xmm5);
- FormatFloatReg("Xmm6 ", pContext->Xmm6);
- FormatFloatReg("Xmm7 ", pContext->Xmm7);
- FormatFloatReg("Xmm8 ", pContext->Xmm8);
- FormatFloatReg("Xmm9 ", pContext->Xmm9);
- FormatFloatReg("Xmm10", pContext->Xmm10);
- FormatFloatReg("Xmm11", pContext->Xmm11);
- FormatFloatReg("Xmm12", pContext->Xmm12);
- FormatFloatReg("Xmm13", pContext->Xmm13);
- FormatFloatReg("Xmm14", pContext->Xmm14);
- FormatFloatReg("Xmm15", pContext->Xmm15);
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCrashHandler::FormatLoadedMods()
-{
- if (g_pModManager)
- {
- spdlog::error("Enabled mods:");
- for (const Mod& mod : g_pModManager->m_LoadedMods)
- {
- if (!mod.m_bEnabled)
- continue;
-
- spdlog::error("\t{}", mod.Name);
- }
-
- spdlog::error("Disabled mods:");
- for (const Mod& mod : g_pModManager->m_LoadedMods)
- {
- if (mod.m_bEnabled)
- continue;
-
- spdlog::error("\t{}", mod.Name);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCrashHandler::FormatLoadedPlugins()
-{
- if (g_pPluginManager)
- {
- spdlog::error("Loaded Plugins:");
- for (const Plugin& plugin : g_pPluginManager->m_vLoadedPlugins)
- {
- spdlog::error("\t{}", plugin.name);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CCrashHandler::FormatModules()
-{
- spdlog::error("Loaded modules:");
- HMODULE hModules[1024];
- DWORD cbNeeded;
-
- if (EnumProcessModules(GetCurrentProcess(), hModules, sizeof(hModules), &cbNeeded))
- {
- for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
- {
- CHAR szModulePath[MAX_PATH];
- if (GetModuleFileNameExA(GetCurrentProcess(), hModules[i], szModulePath, sizeof(szModulePath)))
- {
- const CHAR* pszModuleFileName = strrchr(szModulePath, '\\') + 1;
- spdlog::error("\t{}", pszModuleFileName);
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Writes minidump to disk
-//-----------------------------------------------------------------------------
-void CCrashHandler::WriteMinidump()
-{
- time_t time = std::time(nullptr);
- tm currentTime = *std::localtime(&time);
- std::stringstream stream;
- stream << std::put_time(&currentTime, (GetNorthstarPrefix() + "/logs/nsdump%Y-%m-%d %H-%M-%S.dmp").c_str());
-
- HANDLE hMinidumpFile = CreateFileA(stream.str().c_str(), GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
- if (hMinidumpFile)
- {
- MINIDUMP_EXCEPTION_INFORMATION dumpExceptionInfo;
- dumpExceptionInfo.ThreadId = GetCurrentThreadId();
- dumpExceptionInfo.ExceptionPointers = m_pExceptionInfos;
- dumpExceptionInfo.ClientPointers = false;
-
- MiniDumpWriteDump(
- GetCurrentProcess(),
- GetCurrentProcessId(),
- hMinidumpFile,
- MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
- &dumpExceptionInfo,
- nullptr,
- nullptr);
- CloseHandle(hMinidumpFile);
- }
- else
- spdlog::error("Failed to write minidump file {}!", stream.str());
-}
-
-//-----------------------------------------------------------------------------
-CCrashHandler* g_pCrashHandler = nullptr;
diff --git a/NorthstarDLL/logging/crashhandler.h b/NorthstarDLL/logging/crashhandler.h
deleted file mode 100644
index c059a8ca..00000000
--- a/NorthstarDLL/logging/crashhandler.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#pragma once
-
-#include <mutex>
-
-//-----------------------------------------------------------------------------
-// Purpose: Exception handling
-//-----------------------------------------------------------------------------
-class CCrashHandler
-{
-public:
- CCrashHandler();
- ~CCrashHandler();
-
- void Init();
- void Shutdown();
-
- void Lock()
- {
- m_Mutex.lock();
- }
-
- void Unlock()
- {
- m_Mutex.unlock();
- }
-
- void SetState(bool bState)
- {
- m_bState = bState;
- }
-
- bool GetState() const
- {
- return m_bState;
- }
-
- void SetAllFatal(bool bState)
- {
- m_bAllExceptionsFatal = bState;
- }
-
- bool GetAllFatal() const
- {
- return m_bAllExceptionsFatal;
- }
-
- //-----------------------------------------------------------------------------
- // Exception helpers
- //-----------------------------------------------------------------------------
- void SetExceptionInfos(EXCEPTION_POINTERS* pExceptionPointers);
-
- void SetCrashedModule();
-
- const CHAR* GetExceptionString() const;
- const CHAR* GetExceptionString(DWORD dwExceptionCode) const;
-
- bool IsExceptionFatal() const;
- bool IsExceptionFatal(DWORD dwExceptionCode) const;
-
- //-----------------------------------------------------------------------------
- // Formatting
- //-----------------------------------------------------------------------------
- void ShowPopUpMessage();
-
- void FormatException();
- void FormatCallstack();
- void FormatFlags(const CHAR* pszRegister, DWORD nValue);
- void FormatIntReg(const CHAR* pszRegister, DWORD64 nValue);
- void FormatFloatReg(const CHAR* pszRegister, M128A nValue);
- void FormatRegisters();
- void FormatLoadedMods();
- void FormatLoadedPlugins();
- void FormatModules();
-
- //-----------------------------------------------------------------------------
- // Minidump
- //-----------------------------------------------------------------------------
- void WriteMinidump();
-
-private:
- PVOID m_hExceptionFilter;
- EXCEPTION_POINTERS* m_pExceptionInfos;
-
- bool m_bHasSetConsolehandler;
- bool m_bAllExceptionsFatal;
- bool m_bHasShownCrashMsg;
- bool m_bState;
-
- std::string m_svCrashedModule;
- std::string m_svCrashedOffset;
-
- std::string m_svError;
-
- std::mutex m_Mutex;
-};
-
-extern CCrashHandler* g_pCrashHandler;
diff --git a/NorthstarDLL/logging/logging.cpp b/NorthstarDLL/logging/logging.cpp
deleted file mode 100644
index 3416bb8c..00000000
--- a/NorthstarDLL/logging/logging.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-#include "logging.h"
-#include "core/convar/convar.h"
-#include "core/convar/concommand.h"
-#include "config/profile.h"
-#include "core/tier0.h"
-#include "util/version.h"
-#include "spdlog/sinks/basic_file_sink.h"
-
-#include <winternl.h>
-#include <cstdlib>
-#include <iomanip>
-#include <sstream>
-
-AUTOHOOK_INIT()
-
-std::vector<std::shared_ptr<ColoredLogger>> loggers {};
-
-namespace NS::log
-{
- std::shared_ptr<ColoredLogger> SCRIPT_UI;
- std::shared_ptr<ColoredLogger> SCRIPT_CL;
- std::shared_ptr<ColoredLogger> SCRIPT_SV;
-
- std::shared_ptr<ColoredLogger> NATIVE_UI;
- std::shared_ptr<ColoredLogger> NATIVE_CL;
- std::shared_ptr<ColoredLogger> NATIVE_SV;
- std::shared_ptr<ColoredLogger> NATIVE_EN;
-
- std::shared_ptr<ColoredLogger> fs;
- std::shared_ptr<ColoredLogger> rpak;
- std::shared_ptr<ColoredLogger> echo;
-
- std::shared_ptr<ColoredLogger> NORTHSTAR;
- std::shared_ptr<ColoredLogger> PLUGINSYS;
-}; // namespace NS::log
-
-// This needs to be called after hooks are loaded so we can access the command line args
-void CreateLogFiles()
-{
- if (strstr(GetCommandLineA(), "-disablelogs"))
- {
- spdlog::default_logger()->set_level(spdlog::level::off);
- }
- else
- {
- try
- {
- // todo: might be good to delete logs that are too old
- time_t time = std::time(nullptr);
- tm currentTime = *std::localtime(&time);
- std::stringstream stream;
-
- stream << std::put_time(&currentTime, (GetNorthstarPrefix() + "/logs/nslog%Y-%m-%d %H-%M-%S.txt").c_str());
- auto sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>(stream.str(), false);
- sink->set_pattern("[%Y-%m-%d] [%H:%M:%S] [%n] [%l] %v");
- for (auto& logger : loggers)
- {
- logger->sinks().push_back(sink);
- }
- spdlog::flush_on(spdlog::level::info);
- }
- catch (...)
- {
- spdlog::error("Failed creating log file!");
- MessageBoxA(
- 0, "Failed creating log file! Make sure the profile directory is writable.", "Northstar Warning", MB_ICONWARNING | MB_OK);
- }
- }
-}
-
-void ExternalConsoleSink::sink_it_(const spdlog::details::log_msg& msg)
-{
- throw std::runtime_error("sink_it_ called on SourceConsoleSink with pure log_msg. This is an error!");
-}
-
-void ExternalConsoleSink::custom_sink_it_(const custom_log_msg& msg)
-{
- spdlog::memory_buf_t formatted;
- spdlog::sinks::base_sink<std::mutex>::formatter_->format(msg, formatted);
-
- std::string out = "";
- // if ansi colour is turned off, just use WriteConsoleA and return
- if (!g_bSpdLog_UseAnsiColor)
- {
- out += fmt::to_string(formatted);
- }
-
- // print to the console with colours
- else
- {
- // get message string
- std::string str = fmt::to_string(formatted);
-
- std::string levelColor = m_LogColours[msg.level];
- std::string name {msg.logger_name.begin(), msg.logger_name.end()};
-
- std::string name_str = "[NAME]";
- int name_pos = str.find(name_str);
- str.replace(name_pos, name_str.length(), msg.origin->ANSIColor + "[" + name + "]" + default_color);
-
- std::string level_str = "[LVL]";
- int level_pos = str.find(level_str);
- str.replace(level_pos, level_str.length(), levelColor + "[" + std::string(level_names[msg.level]) + "]" + default_color);
-
- out += str;
- }
- // print the string to the console - this is definitely bad i think
- HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
- auto ignored = WriteConsoleA(handle, out.c_str(), std::strlen(out.c_str()), nullptr, nullptr);
- (void)ignored;
-}
-
-void ExternalConsoleSink::flush_()
-{
- std::cout << std::flush;
-}
-
-void CustomSink::custom_log(const custom_log_msg& msg)
-{
- std::lock_guard<std::mutex> lock(mutex_);
- custom_sink_it_(msg);
-}
-
-void InitialiseConsole()
-{
- if (AllocConsole() == FALSE)
- {
- std::cout << "[*] Failed to create a console window, maybe a console already exists?" << std::endl;
- }
- else
- {
- freopen("CONOUT$", "w", stdout);
- freopen("CONOUT$", "w", stderr);
- }
-
- // this if statement is adapted from r5sdk
- if (!strstr(GetCommandLineA(), "-noansiclr"))
- {
- g_bSpdLog_UseAnsiColor = true;
- DWORD dwMode = 0;
- HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
-
- GetConsoleMode(hOutput, &dwMode);
- dwMode |= ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
-
- if (!SetConsoleMode(hOutput, dwMode)) // Some editions of Windows have 'VirtualTerminalLevel' disabled by default.
- {
- // If 'VirtualTerminalLevel' can't be set, just disable ANSI color, since it wouldnt work anyway.
- spdlog::warn("could not set VirtualTerminalLevel. Disabling color output");
- g_bSpdLog_UseAnsiColor = false;
- }
- }
-}
-
-void RegisterLogger(std::shared_ptr<ColoredLogger> logger)
-{
- loggers.push_back(logger);
-}
-
-void RegisterCustomSink(std::shared_ptr<CustomSink> sink)
-{
- for (auto& logger : loggers)
- {
- logger->custom_sinks_.push_back(sink);
- }
-};
-
-void InitialiseLogging()
-{
- // create a logger, and set it to default
- NS::log::NORTHSTAR = std::make_shared<ColoredLogger>("NORTHSTAR", NS::Colors::NORTHSTAR, true);
- NS::log::NORTHSTAR->sinks().clear();
- loggers.push_back(NS::log::NORTHSTAR);
- spdlog::set_default_logger(NS::log::NORTHSTAR);
-
- // create our console sink
- auto sink = std::make_shared<ExternalConsoleSink>();
- // set the pattern
- if (g_bSpdLog_UseAnsiColor)
- // dont put the log level in the pattern if we are using colours, as the colour will show the log level
- sink->set_pattern("[%H:%M:%S] [NAME] [LVL] %v");
- else
- sink->set_pattern("[%H:%M:%S] [%n] [%l] %v");
-
- // add our sink to the logger
- NS::log::NORTHSTAR->custom_sinks_.push_back(sink);
-
- NS::log::SCRIPT_UI = std::make_shared<ColoredLogger>("SCRIPT UI", NS::Colors::SCRIPT_UI);
- NS::log::SCRIPT_CL = std::make_shared<ColoredLogger>("SCRIPT CL", NS::Colors::SCRIPT_CL);
- NS::log::SCRIPT_SV = std::make_shared<ColoredLogger>("SCRIPT SV", NS::Colors::SCRIPT_SV);
-
- NS::log::NATIVE_UI = std::make_shared<ColoredLogger>("NATIVE UI", NS::Colors::NATIVE_UI);
- NS::log::NATIVE_CL = std::make_shared<ColoredLogger>("NATIVE CL", NS::Colors::NATIVE_CL);
- NS::log::NATIVE_SV = std::make_shared<ColoredLogger>("NATIVE SV", NS::Colors::NATIVE_SV);
- NS::log::NATIVE_EN = std::make_shared<ColoredLogger>("NATIVE EN", NS::Colors::NATIVE_ENGINE);
-
- NS::log::fs = std::make_shared<ColoredLogger>("FILESYSTM", NS::Colors::FILESYSTEM);
- NS::log::rpak = std::make_shared<ColoredLogger>("RPAK_FSYS", NS::Colors::RPAK);
- NS::log::echo = std::make_shared<ColoredLogger>("ECHO", NS::Colors::ECHO);
-
- NS::log::PLUGINSYS = std::make_shared<ColoredLogger>("PLUGINSYS", NS::Colors::PLUGINSYS);
-
- loggers.push_back(NS::log::SCRIPT_UI);
- loggers.push_back(NS::log::SCRIPT_CL);
- loggers.push_back(NS::log::SCRIPT_SV);
-
- loggers.push_back(NS::log::NATIVE_UI);
- loggers.push_back(NS::log::NATIVE_CL);
- loggers.push_back(NS::log::NATIVE_SV);
- loggers.push_back(NS::log::NATIVE_EN);
-
- loggers.push_back(NS::log::PLUGINSYS);
-
- loggers.push_back(NS::log::fs);
- loggers.push_back(NS::log::rpak);
- loggers.push_back(NS::log::echo);
-}
-
-void NS::log::FlushLoggers()
-{
- for (auto& logger : loggers)
- logger->flush();
-
- spdlog::default_logger()->flush();
-}
-
-// Wine specific functions
-typedef const char*(CDECL* wine_get_host_version_type)(const char**, const char**);
-wine_get_host_version_type wine_get_host_version;
-
-typedef const char*(CDECL* wine_get_build_id_type)(void);
-wine_get_build_id_type wine_get_build_id;
-
-// Not exported Winapi methods
-typedef NTSTATUS(WINAPI* RtlGetVersion_type)(PRTL_OSVERSIONINFOW);
-RtlGetVersion_type RtlGetVersion;
-
-void StartupLog()
-{
- spdlog::info("NorthstarLauncher version: {}", version);
- spdlog::info("Command line: {}", GetCommandLineA());
- spdlog::info("Using profile: {}", GetNorthstarPrefix());
-
- HMODULE ntdll = GetModuleHandleA("ntdll.dll");
- if (!ntdll)
- {
- // How did we get here
- spdlog::info("Operating System: Unknown");
- return;
- }
-
- wine_get_host_version = (wine_get_host_version_type)GetProcAddress(ntdll, "wine_get_host_version");
- if (wine_get_host_version)
- {
- // Load the rest of the functions we need
- wine_get_build_id = (wine_get_build_id_type)GetProcAddress(ntdll, "wine_get_build_id");
-
- const char* sysname;
- wine_get_host_version(&sysname, NULL);
-
- spdlog::info("Operating System: {} (Wine)", sysname);
- spdlog::info("Wine build: {}", wine_get_build_id());
-
- // STEAM_COMPAT_TOOL_PATHS is a colon separated lists of all compat tool paths used
- // The first one tends to be the Proton path itself
- // We extract the basename out of it to get the name used
- char* compatToolPtr = std::getenv("STEAM_COMPAT_TOOL_PATHS");
- if (compatToolPtr)
- {
- std::string_view compatToolPath(compatToolPtr);
-
- auto protonBasenameEnd = compatToolPath.find(":");
- if (protonBasenameEnd == std::string_view::npos)
- protonBasenameEnd = 0;
- auto protonBasenameStart = compatToolPath.rfind("/", protonBasenameEnd) + 1;
- if (protonBasenameStart == std::string_view::npos)
- protonBasenameStart = 0;
-
- spdlog::info("Proton build: {}", compatToolPath.substr(protonBasenameStart, protonBasenameEnd - protonBasenameStart));
- }
- }
- else
- {
- // We are real Windows (hopefully)
- const char* win_ver = "Unknown";
-
- RTL_OSVERSIONINFOW osvi;
- osvi.dwOSVersionInfoSize = sizeof(osvi);
-
- RtlGetVersion = (RtlGetVersion_type)GetProcAddress(ntdll, "RtlGetVersion");
- if (RtlGetVersion && !RtlGetVersion(&osvi))
- {
- // Version reference table
- // https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoa#remarks
- spdlog::info("Operating System: Windows (NT{}.{})", osvi.dwMajorVersion, osvi.dwMinorVersion);
- }
- else
- {
- spdlog::info("Operating System: Windows");
- }
- }
-}
diff --git a/NorthstarDLL/logging/logging.h b/NorthstarDLL/logging/logging.h
deleted file mode 100644
index 5056af27..00000000
--- a/NorthstarDLL/logging/logging.h
+++ /dev/null
@@ -1,136 +0,0 @@
-#pragma once
-#include "spdlog/sinks/base_sink.h"
-#include "spdlog/logger.h"
-#include "squirrel/squirrel.h"
-#include "core/math/color.h"
-
-void CreateLogFiles();
-void InitialiseLogging();
-void InitialiseConsole();
-void StartupLog();
-
-class ColoredLogger;
-
-struct custom_log_msg : spdlog::details::log_msg
-{
-public:
- custom_log_msg(ColoredLogger* origin, spdlog::details::log_msg msg) : origin(origin), spdlog::details::log_msg(msg) {}
-
- ColoredLogger* origin;
-};
-
-class CustomSink : public spdlog::sinks::base_sink<std::mutex>
-{
-public:
- void custom_log(const custom_log_msg& msg);
- virtual void custom_sink_it_(const custom_log_msg& msg)
- {
- throw std::runtime_error("Pure virtual call to CustomSink::custom_sink_it_");
- }
-};
-
-class ColoredLogger : public spdlog::logger
-{
-public:
- std::string ANSIColor;
- SourceColor SRCColor;
-
- std::vector<std::shared_ptr<CustomSink>> custom_sinks_;
-
- ColoredLogger(std::string name, Color color, bool first = false) : spdlog::logger(*spdlog::default_logger())
- {
- name_ = std::move(name);
- if (!first)
- {
- custom_sinks_ = dynamic_pointer_cast<ColoredLogger>(spdlog::default_logger())->custom_sinks_;
- }
-
- ANSIColor = color.ToANSIColor();
- SRCColor = color.ToSourceColor();
- }
-
- void sink_it_(const spdlog::details::log_msg& msg)
- {
- custom_log_msg custom_msg {this, msg};
-
- // Ugh
- for (auto& sink : sinks_)
- {
- SPDLOG_TRY
- {
- sink->log(custom_msg);
- }
- SPDLOG_LOGGER_CATCH()
- }
-
- for (auto& sink : custom_sinks_)
- {
- SPDLOG_TRY
- {
- sink->custom_log(custom_msg);
- }
- SPDLOG_LOGGER_CATCH()
- }
-
- if (should_flush_(custom_msg))
- {
- flush_();
- }
- }
-};
-
-namespace NS::log
-{
- // Squirrel
- extern std::shared_ptr<ColoredLogger> SCRIPT_UI;
- extern std::shared_ptr<ColoredLogger> SCRIPT_CL;
- extern std::shared_ptr<ColoredLogger> SCRIPT_SV;
-
- // Native code
- extern std::shared_ptr<ColoredLogger> NATIVE_UI;
- extern std::shared_ptr<ColoredLogger> NATIVE_CL;
- extern std::shared_ptr<ColoredLogger> NATIVE_SV;
- extern std::shared_ptr<ColoredLogger> NATIVE_EN;
-
- // File system
- extern std::shared_ptr<ColoredLogger> fs;
- // RPak
- extern std::shared_ptr<ColoredLogger> rpak;
- // Echo
- extern std::shared_ptr<ColoredLogger> echo;
-
- extern std::shared_ptr<ColoredLogger> NORTHSTAR;
-
- extern std::shared_ptr<ColoredLogger> PLUGINSYS;
-
- void FlushLoggers();
-}; // namespace NS::log
-
-void RegisterCustomSink(std::shared_ptr<CustomSink> sink);
-void RegisterLogger(std::shared_ptr<ColoredLogger> logger);
-
-inline bool g_bSpdLog_UseAnsiColor = true;
-
-// Could maybe use some different names here, idk
-static const char* level_names[] {"trac", "dbug", "info", "warn", "errr", "crit", "off"};
-
-// spdlog logger, for cool colour things
-class ExternalConsoleSink : public CustomSink
-{
-private:
- std::map<spdlog::level::level_enum, std::string> m_LogColours = {
- {spdlog::level::trace, NS::Colors::TRACE.ToANSIColor()},
- {spdlog::level::debug, NS::Colors::DEBUG.ToANSIColor()},
- {spdlog::level::info, NS::Colors::INFO.ToANSIColor()},
- {spdlog::level::warn, NS::Colors::WARN.ToANSIColor()},
- {spdlog::level::err, NS::Colors::ERR.ToANSIColor()},
- {spdlog::level::critical, NS::Colors::CRIT.ToANSIColor()},
- {spdlog::level::off, NS::Colors::OFF.ToANSIColor()}};
-
- std::string default_color = "\033[39;49m";
-
-protected:
- void sink_it_(const spdlog::details::log_msg& msg) override;
- void custom_sink_it_(const custom_log_msg& msg);
- void flush_() override;
-};
diff --git a/NorthstarDLL/logging/loghooks.cpp b/NorthstarDLL/logging/loghooks.cpp
deleted file mode 100644
index 7efb5b99..00000000
--- a/NorthstarDLL/logging/loghooks.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-#include "logging.h"
-#include "loghooks.h"
-#include "core/convar/convar.h"
-#include "core/convar/concommand.h"
-#include "core/math/bitbuf.h"
-#include "config/profile.h"
-#include "core/tier0.h"
-#include "squirrel/squirrel.h"
-#include <iomanip>
-#include <sstream>
-
-AUTOHOOK_INIT()
-
-ConVar* Cvar_spewlog_enable;
-ConVar* Cvar_cl_showtextmsg;
-
-enum class TextMsgPrintType_t
-{
- HUD_PRINTNOTIFY = 1,
- HUD_PRINTCONSOLE,
- HUD_PRINTTALK,
- HUD_PRINTCENTER
-};
-
-class ICenterPrint
-{
-public:
- virtual void ctor() = 0;
- virtual void Clear(void) = 0;
- virtual void ColorPrint(int r, int g, int b, int a, wchar_t* text) = 0;
- virtual void ColorPrint(int r, int g, int b, int a, char* text) = 0;
- virtual void Print(wchar_t* text) = 0;
- virtual void Print(char* text) = 0;
- virtual void SetTextColor(int r, int g, int b, int a) = 0;
-};
-
-enum class SpewType_t
-{
- SPEW_MESSAGE = 0,
-
- SPEW_WARNING,
- SPEW_ASSERT,
- SPEW_ERROR,
- SPEW_LOG,
-
- SPEW_TYPE_COUNT
-};
-
-const std::unordered_map<SpewType_t, const char*> PrintSpewTypes = {
- {SpewType_t::SPEW_MESSAGE, "SPEW_MESSAGE"},
- {SpewType_t::SPEW_WARNING, "SPEW_WARNING"},
- {SpewType_t::SPEW_ASSERT, "SPEW_ASSERT"},
- {SpewType_t::SPEW_ERROR, "SPEW_ERROR"},
- {SpewType_t::SPEW_LOG, "SPEW_LOG"}};
-
-// these are used to define the base text colour for these things
-const std::unordered_map<SpewType_t, spdlog::level::level_enum> PrintSpewLevels = {
- {SpewType_t::SPEW_MESSAGE, spdlog::level::level_enum::info},
- {SpewType_t::SPEW_WARNING, spdlog::level::level_enum::warn},
- {SpewType_t::SPEW_ASSERT, spdlog::level::level_enum::err},
- {SpewType_t::SPEW_ERROR, spdlog::level::level_enum::err},
- {SpewType_t::SPEW_LOG, spdlog::level::level_enum::info}};
-
-const std::unordered_map<SpewType_t, const char> PrintSpewTypes_Short = {
- {SpewType_t::SPEW_MESSAGE, 'M'},
- {SpewType_t::SPEW_WARNING, 'W'},
- {SpewType_t::SPEW_ASSERT, 'A'},
- {SpewType_t::SPEW_ERROR, 'E'},
- {SpewType_t::SPEW_LOG, 'L'}};
-
-ICenterPrint* pInternalCenterPrint = NULL;
-
-// clang-format off
-AUTOHOOK(TextMsg, client.dll + 0x198710,
-void,, (BFRead* msg))
-// clang-format on
-{
- TextMsgPrintType_t msg_dest = (TextMsgPrintType_t)msg->ReadByte();
-
- char text[256];
- msg->ReadString(text, sizeof(text));
-
- if (!Cvar_cl_showtextmsg->GetBool())
- return;
-
- switch (msg_dest)
- {
- case TextMsgPrintType_t::HUD_PRINTCENTER:
- pInternalCenterPrint->Print(text);
- break;
-
- default:
- spdlog::warn("Unimplemented TextMsg type {}! printing to console", msg_dest);
- [[fallthrough]];
-
- case TextMsgPrintType_t::HUD_PRINTCONSOLE:
- auto endpos = strlen(text);
- if (text[endpos - 1] == '\n')
- text[endpos - 1] = '\0'; // cut off repeated newline
-
- spdlog::info(text);
- break;
- }
-}
-
-// clang-format off
-AUTOHOOK(Hook_fprintf, engine.dll + 0x51B1F0,
-int,, (void* const stream, const char* const format, ...))
-// clang-format on
-{
- va_list va;
- va_start(va, format);
-
- SQChar buf[1024];
- int charsWritten = vsnprintf_s(buf, _TRUNCATE, format, va);
-
- if (charsWritten > 0)
- {
- if (buf[charsWritten - 1] == '\n')
- buf[charsWritten - 1] = '\0';
- NS::log::NATIVE_EN->info("{}", buf);
- }
-
- va_end(va);
- return 0;
-}
-
-// clang-format off
-AUTOHOOK(ConCommand_echo, engine.dll + 0x123680,
-void,, (const CCommand& arg))
-// clang-format on
-{
- if (arg.ArgC() >= 2)
- NS::log::echo->info("{}", arg.ArgS());
-}
-
-// clang-format off
-AUTOHOOK(EngineSpewFunc, engine.dll + 0x11CA80,
-void, __fastcall, (void* pEngineServer, SpewType_t type, const char* format, va_list args))
-// clang-format on
-{
- if (!Cvar_spewlog_enable->GetBool())
- return;
-
- const char* typeStr = PrintSpewTypes.at(type);
- char formatted[2048] = {0};
- bool bShouldFormat = true;
-
- // because titanfall 2 is quite possibly the worst thing to yet exist, it sometimes gives invalid specifiers which will crash
- // ttf2sdk had a way to prevent them from crashing but it doesnt work in debug builds
- // so we use this instead
- for (int i = 0; format[i]; i++)
- {
- if (format[i] == '%')
- {
- switch (format[i + 1])
- {
- // this is fucking awful lol
- case 'd':
- case 'i':
- case 'u':
- case 'x':
- case 'X':
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- case 'a':
- case 'A':
- case 'c':
- case 's':
- case 'p':
- case 'n':
- case '%':
- case '-':
- case '+':
- case ' ':
- case '#':
- case '*':
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- break;
-
- default:
- {
- bShouldFormat = false;
- break;
- }
- }
- }
- }
-
- if (bShouldFormat)
- vsnprintf(formatted, sizeof(formatted), format, args);
- else
- spdlog::warn("Failed to format {} \"{}\"", typeStr, format);
-
- auto endpos = strlen(formatted);
- if (formatted[endpos - 1] == '\n')
- formatted[endpos - 1] = '\0'; // cut off repeated newline
-
- NS::log::NATIVE_SV->log(PrintSpewLevels.at(type), "{}", formatted);
-}
-
-// used for printing the output of status
-// clang-format off
-AUTOHOOK(Status_ConMsg, engine.dll + 0x15ABD0,
-void,, (const char* text, ...))
-// clang-format on
-{
- char formatted[2048];
- va_list list;
-
- va_start(list, text);
- vsprintf_s(formatted, text, list);
- va_end(list);
-
- auto endpos = strlen(formatted);
- if (formatted[endpos - 1] == '\n')
- formatted[endpos - 1] = '\0'; // cut off repeated newline
-
- spdlog::info(formatted);
-}
-
-// clang-format off
-AUTOHOOK(CClientState_ProcessPrint, engine.dll + 0x1A1530,
-bool,, (void* thisptr, uintptr_t msg))
-// clang-format on
-{
- char* text = *(char**)(msg + 0x20);
-
- auto endpos = strlen(text);
- if (text[endpos - 1] == '\n')
- text[endpos - 1] = '\0'; // cut off repeated newline
-
- spdlog::info(text);
- return true;
-}
-
-ON_DLL_LOAD_RELIESON("engine.dll", EngineSpewFuncHooks, ConVar, (CModule module))
-{
- AUTOHOOK_DISPATCH_MODULE(engine.dll)
-
- Cvar_spewlog_enable = new ConVar("spewlog_enable", "0", FCVAR_NONE, "Enables/disables whether the engine spewfunc should be logged");
-}
-
-ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientPrintHooks, ConVar, (CModule module))
-{
- AUTOHOOK_DISPATCH_MODULE(client.dll)
-
- Cvar_cl_showtextmsg = new ConVar("cl_showtextmsg", "1", FCVAR_NONE, "Enable/disable text messages printing on the screen.");
- pInternalCenterPrint = module.Offset(0x216E940).RCast<ICenterPrint*>();
-}
diff --git a/NorthstarDLL/logging/loghooks.h b/NorthstarDLL/logging/loghooks.h
deleted file mode 100644
index 6f70f09b..00000000
--- a/NorthstarDLL/logging/loghooks.h
+++ /dev/null
@@ -1 +0,0 @@
-#pragma once
diff --git a/NorthstarDLL/logging/sourceconsole.cpp b/NorthstarDLL/logging/sourceconsole.cpp
deleted file mode 100644
index e436d1d4..00000000
--- a/NorthstarDLL/logging/sourceconsole.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-#include "core/convar/convar.h"
-#include "sourceconsole.h"
-#include "core/sourceinterface.h"
-#include "core/convar/concommand.h"
-#include "util/printcommands.h"
-
-SourceInterface<CGameConsole>* g_pSourceGameConsole;
-
-void ConCommand_toggleconsole(const CCommand& arg)
-{
- if ((*g_pSourceGameConsole)->IsConsoleVisible())
- (*g_pSourceGameConsole)->Hide();
- else
- (*g_pSourceGameConsole)->Activate();
-}
-
-void ConCommand_showconsole(const CCommand& arg)
-{
- (*g_pSourceGameConsole)->Activate();
-}
-
-void ConCommand_hideconsole(const CCommand& arg)
-{
- (*g_pSourceGameConsole)->Hide();
-}
-
-void SourceConsoleSink::custom_sink_it_(const custom_log_msg& msg)
-{
- if (!(*g_pSourceGameConsole)->m_bInitialized)
- return;
-
- spdlog::memory_buf_t formatted;
- spdlog::sinks::base_sink<std::mutex>::formatter_->format(msg, formatted);
-
- // get message string
- std::string str = fmt::to_string(formatted);
-
- SourceColor levelColor = m_LogColours[msg.level];
- std::string name {msg.logger_name.begin(), msg.logger_name.end()};
-
- (*g_pSourceGameConsole)->m_pConsole->m_pConsolePanel->ColorPrint(msg.origin->SRCColor, ("[" + name + "]").c_str());
- (*g_pSourceGameConsole)->m_pConsole->m_pConsolePanel->Print(" ");
- (*g_pSourceGameConsole)->m_pConsole->m_pConsolePanel->ColorPrint(levelColor, ("[" + std::string(level_names[msg.level]) + "]").c_str());
- (*g_pSourceGameConsole)->m_pConsole->m_pConsolePanel->Print(" ");
- (*g_pSourceGameConsole)->m_pConsole->m_pConsolePanel->Print(fmt::to_string(formatted).c_str());
-}
-
-void SourceConsoleSink::sink_it_(const spdlog::details::log_msg& msg)
-{
- throw std::runtime_error("sink_it_ called on SourceConsoleSink with pure log_msg. This is an error!");
-}
-
-void SourceConsoleSink::flush_() {}
-
-// clang-format off
-HOOK(OnCommandSubmittedHook, OnCommandSubmitted,
-void, __fastcall, (CConsoleDialog* consoleDialog, const char* pCommand))
-// clang-format on
-{
- consoleDialog->m_pConsolePanel->Print("] ");
- consoleDialog->m_pConsolePanel->Print(pCommand);
- consoleDialog->m_pConsolePanel->Print("\n");
-
- TryPrintCvarHelpForCommand(pCommand);
-
- OnCommandSubmitted(consoleDialog, pCommand);
-}
-
-// called from sourceinterface.cpp in client createinterface hooks, on GameClientExports001
-void InitialiseConsoleOnInterfaceCreation()
-{
- (*g_pSourceGameConsole)->Initialize();
- // hook OnCommandSubmitted so we print inputted commands
- OnCommandSubmittedHook.Dispatch((LPVOID)(*g_pSourceGameConsole)->m_pConsole->m_vtable->OnCommandSubmitted);
-
- auto consoleSink = std::make_shared<SourceConsoleSink>();
- if (g_bSpdLog_UseAnsiColor)
- consoleSink->set_pattern("%v"); // no need to include the level in the game console, the text colour signifies it anyway
- else
- consoleSink->set_pattern("[%n] [%l] %v"); // no colour, so we should show the level for colourblind people
- RegisterCustomSink(consoleSink);
-}
-
-ON_DLL_LOAD_CLIENT_RELIESON("client.dll", SourceConsole, ConCommand, (CModule module))
-{
- g_pSourceGameConsole = new SourceInterface<CGameConsole>("client.dll", "GameConsole004");
-
- RegisterConCommand("toggleconsole", ConCommand_toggleconsole, "Show/hide the console.", FCVAR_DONTRECORD);
- RegisterConCommand("showconsole", ConCommand_showconsole, "Show the console.", FCVAR_DONTRECORD);
- RegisterConCommand("hideconsole", ConCommand_hideconsole, "Hide the console.", FCVAR_DONTRECORD);
-}
diff --git a/NorthstarDLL/logging/sourceconsole.h b/NorthstarDLL/logging/sourceconsole.h
deleted file mode 100644
index 44d73843..00000000
--- a/NorthstarDLL/logging/sourceconsole.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#pragma once
-#include "core/sourceinterface.h"
-#include "spdlog/sinks/base_sink.h"
-#include <map>
-
-class EditablePanel
-{
-public:
- virtual ~EditablePanel() = 0;
- unsigned char unknown[0x2B0];
-};
-
-class IConsoleDisplayFunc
-{
-public:
- virtual void ColorPrint(const SourceColor& clr, const char* pMessage) = 0;
- virtual void Print(const char* pMessage) = 0;
- virtual void DPrint(const char* pMessage) = 0;
-};
-
-class CConsolePanel : public EditablePanel, public IConsoleDisplayFunc
-{
-};
-
-class CConsoleDialog
-{
-public:
- struct VTable
- {
- void* unknown[298];
- void (*OnCommandSubmitted)(CConsoleDialog* consoleDialog, const char* pCommand);
- };
-
- VTable* m_vtable;
- unsigned char unknown[0x398];
- CConsolePanel* m_pConsolePanel;
-};
-
-class CGameConsole
-{
-public:
- virtual ~CGameConsole() = 0;
-
- // activates the console, makes it visible and brings it to the foreground
- virtual void Activate() = 0;
-
- virtual void Initialize() = 0;
-
- // hides the console
- virtual void Hide() = 0;
-
- // clears the console
- virtual void Clear() = 0;
-
- // return true if the console has focus
- virtual bool IsConsoleVisible() = 0;
-
- virtual void SetParent(int parent) = 0;
-
- bool m_bInitialized;
- CConsoleDialog* m_pConsole;
-};
-
-extern SourceInterface<CGameConsole>* g_pSourceGameConsole;
-
-// spdlog logger
-class SourceConsoleSink : public CustomSink
-{
-private:
- std::map<spdlog::level::level_enum, SourceColor> m_LogColours = {
- {spdlog::level::trace, NS::Colors::TRACE.ToSourceColor()},
- {spdlog::level::debug, NS::Colors::DEBUG.ToSourceColor()},
- {spdlog::level::info, NS::Colors::INFO.ToSourceColor()},
- {spdlog::level::warn, NS::Colors::WARN.ToSourceColor()},
- {spdlog::level::err, NS::Colors::ERR.ToSourceColor()},
- {spdlog::level::critical, NS::Colors::CRIT.ToSourceColor()},
- {spdlog::level::off, NS::Colors::OFF.ToSourceColor()}};
-
-protected:
- void custom_sink_it_(const custom_log_msg& msg);
- void sink_it_(const spdlog::details::log_msg& msg) override;
- void flush_() override;
-};
-
-void InitialiseConsoleOnInterfaceCreation();