diff options
Diffstat (limited to 'NorthstarDLL/logging.cpp')
-rw-r--r-- | NorthstarDLL/logging.cpp | 509 |
1 files changed, 257 insertions, 252 deletions
diff --git a/NorthstarDLL/logging.cpp b/NorthstarDLL/logging.cpp index 7fb0df3a..ac22f58c 100644 --- a/NorthstarDLL/logging.cpp +++ b/NorthstarDLL/logging.cpp @@ -1,253 +1,258 @@ -#include "pch.h" -#include "logging.h" -#include "convar.h" -#include "concommand.h" -#include "configurables.h" -#include "bitbuf.h" -#include "spdlog/sinks/basic_file_sink.h" - -#include <iomanip> -#include <sstream> -#include <Psapi.h> - -AUTOHOOK_INIT() - -ConVar* Cvar_spewlog_enable; - -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"} -}; - -AUTOHOOK(EngineSpewFunc, engine.dll + 0x11CA80, -void,, (void* pEngineServer, SpewType_t type, const char* format, va_list args), -{ - 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 - - spdlog::info("[SERVER {}] {}", typeStr, formatted); -}) - -// used for printing the output of status -AUTOHOOK(Status_ConMsg, engine.dll + 0x15ABD0, -void,, (const char* text, ...), -{ - 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); -}) - -AUTOHOOK(CClientState_ProcessPrint, engine.dll + 0x1A1530, -bool,, (__int64 thisptr, __int64 msg), -{ - 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; -}) - -ConVar* Cvar_cl_showtextmsg; - -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; -}; - -ICenterPrint* pInternalCenterPrint = NULL; - -enum class TextMsgPrintType_t -{ - HUD_PRINTNOTIFY = 1, - HUD_PRINTCONSOLE, - HUD_PRINTTALK, - HUD_PRINTCENTER -}; - -AUTOHOOK(TextMsg, client.dll + 0x198710, -void,, (BFRead* msg), -{ - 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; - } -}) - -AUTOHOOK(ConCommand_echo, engine.dll + 0x123680, -void,, (const CCommand& arg), -{ - if (arg.ArgC() >= 2) - spdlog::info("[echo] {}", arg.ArgS()); -}) - -// 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 - { - // 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(¤tTime, (GetNorthstarPrefix() + "/logs/nslog%Y-%m-%d %H-%M-%S.txt").c_str()); - spdlog::default_logger()->sinks().push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(stream.str(), false)); - spdlog::flush_on(spdlog::level::info); - } -} - -void InitialiseLogging() -{ - AllocConsole(); - - // don't redirect conout if already open - FILE* pConoutFile = fopen("CONOUT$", "w"); - if (pConoutFile) - { - fclose(pConoutFile); - freopen("CONOUT$", "w", stdout); - freopen("CONOUT$", "w", stderr); - } - - spdlog::default_logger()->set_pattern("[%H:%M:%S] [%l] %v"); -} - -ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", EngineSpewFuncHooks, ConCommand, [](HMODULE baseAddress) -{ - AUTOHOOK_DISPATCH_MODULE(engine.dll) - - Cvar_spewlog_enable = new ConVar("spewlog_enable", "1", FCVAR_NONE, "Enables/disables whether the engine spewfunc should be logged"); -}) - -ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientPrintHooks, ConVar, [](HMODULE baseAddress) -{ - AUTOHOOK_DISPATCH_MODULE(client.dll) - - Cvar_cl_showtextmsg = new ConVar("cl_showtextmsg", "1", FCVAR_NONE, "Enable/disable text messages printing on the screen."); - pInternalCenterPrint = (ICenterPrint*)((char*)baseAddress + 0x216E940); +#include "pch.h"
+#include "logging.h"
+#include "convar.h"
+#include "concommand.h"
+#include "configurables.h"
+#include "bitbuf.h"
+#include "spdlog/sinks/basic_file_sink.h"
+
+#include <iomanip>
+#include <sstream>
+#include <Psapi.h>
+
+AUTOHOOK_INIT()
+
+ConVar* Cvar_spewlog_enable;
+
+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"}
+};
+
+AUTOHOOK(EngineSpewFunc, engine.dll + 0x11CA80,
+void,, (void* pEngineServer, SpewType_t type, const char* format, va_list args))
+{
+ 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
+
+ spdlog::info("[SERVER {}] {}", typeStr, formatted);
+}
+
+// used for printing the output of status
+AUTOHOOK(Status_ConMsg, engine.dll + 0x15ABD0,
+void,, (const char* text, ...))
+{
+ 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);
+}
+
+AUTOHOOK(CClientState_ProcessPrint, engine.dll + 0x1A1530,
+bool,, (__int64 thisptr, __int64 msg))
+{
+ 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;
+}
+
+ConVar* Cvar_cl_showtextmsg;
+
+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;
+};
+
+ICenterPrint* pInternalCenterPrint = NULL;
+
+enum class TextMsgPrintType_t
+{
+ HUD_PRINTNOTIFY = 1,
+ HUD_PRINTCONSOLE,
+ HUD_PRINTTALK,
+ HUD_PRINTCENTER
+};
+
+AUTOHOOK(TextMsg, client.dll + 0x198710,
+void,, (BFRead* msg))
+{
+ 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;
+ }
+}
+
+AUTOHOOK(ConCommand_echo, engine.dll + 0x123680,
+void,, (const CCommand& arg))
+{
+ if (arg.ArgC() >= 2)
+ spdlog::info("[echo] {}", arg.ArgS());
+}
+
+// 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
+ {
+ // 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(¤tTime, (GetNorthstarPrefix() + "/logs/nslog%Y-%m-%d %H-%M-%S.txt").c_str());
+ spdlog::default_logger()->sinks().push_back(std::make_shared<spdlog::sinks::basic_file_sink_mt>(stream.str(), false));
+ spdlog::flush_on(spdlog::level::info);
+ }
+}
+
+void InitialiseLogging()
+{
+ AllocConsole();
+
+ // don't redirect conout if already open
+ /* FILE* pConoutFile = fopen("CONOUT$", "w");
+ if (pConoutFile)
+ {
+ fclose(pConoutFile);
+ freopen("CONOUT$", "w", stdout);
+ freopen("CONOUT$", "w", stderr);
+ }*/
+
+ // Bind stdin to receive console input.
+ FILE* fp;
+ freopen_s(&fp, "CONOUT$", "w", stdout);
+ freopen_s(&fp, "CONOUT$", "W", stderr);
+
+ spdlog::default_logger()->set_pattern("[%H:%M:%S] [%l] %v");
+}
+
+ON_DLL_LOAD_CLIENT_RELIESON("engine.dll", EngineSpewFuncHooks, ConCommand, [](HMODULE baseAddress)
+{
+ AUTOHOOK_DISPATCH_MODULE(engine.dll)
+
+ Cvar_spewlog_enable = new ConVar("spewlog_enable", "1", FCVAR_NONE, "Enables/disables whether the engine spewfunc should be logged");
+})
+
+ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ClientPrintHooks, ConVar, [](HMODULE baseAddress)
+{
+ AUTOHOOK_DISPATCH_MODULE(client.dll)
+
+ Cvar_cl_showtextmsg = new ConVar("cl_showtextmsg", "1", FCVAR_NONE, "Enable/disable text messages printing on the screen.");
+ pInternalCenterPrint = (ICenterPrint*)((char*)baseAddress + 0x216E940);
})
\ No newline at end of file |