aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDLL/logging/logging.cpp
diff options
context:
space:
mode:
authorEmma Miler <emma.pi@protonmail.com>2022-12-19 19:32:16 +0100
committerGitHub <noreply@github.com>2022-12-19 19:32:16 +0100
commite04f3b36accccb590a2d51b4829256b9964ac3fd (patch)
tree20ee30c82e6f53e6e772be2e1b9613eebca12bf3 /NorthstarDLL/logging/logging.cpp
parent33f18a735986dcd136bf8ba70ad8331306c28227 (diff)
downloadNorthstarLauncher-e04f3b36accccb590a2d51b4829256b9964ac3fd.tar.gz
NorthstarLauncher-e04f3b36accccb590a2d51b4829256b9964ac3fd.zip
Restructuring (#365)
* Remove launcher proxy * Restructuring * More restructuring * Fix include dirs * Fix merge * Remove clang thing * Filters * Oops
Diffstat (limited to 'NorthstarDLL/logging/logging.cpp')
-rw-r--r--NorthstarDLL/logging/logging.cpp205
1 files changed, 205 insertions, 0 deletions
diff --git a/NorthstarDLL/logging/logging.cpp b/NorthstarDLL/logging/logging.cpp
new file mode 100644
index 00000000..6bb57170
--- /dev/null
+++ b/NorthstarDLL/logging/logging.cpp
@@ -0,0 +1,205 @@
+#include "pch.h"
+#include "logging.h"
+#include "core/convar/convar.h"
+#include "core/convar/concommand.h"
+#include "config/profile.h"
+#include "core/tier0.h"
+#include "spdlog/sinks/basic_file_sink.h"
+
+#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;
+}; // 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("[%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 = NULL;
+ 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 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);
+
+ 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::fs);
+ loggers.push_back(NS::log::rpak);
+ loggers.push_back(NS::log::echo);
+}