diff --git a/mods/src/log_history.h b/mods/src/log_history.h new file mode 100644 index 00000000..25f1ef70 --- /dev/null +++ b/mods/src/log_history.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +// Keep the extension intact: community_patch.log.1 is the newest previous session. +inline void RotateLogHistory(const std::filesystem::path& log) +{ + namespace fs = std::filesystem; + const auto backup = [&](int index) { return fs::path(log.string() + "." + std::to_string(index)); }; + fs::remove(backup(5)); + for (int index = 4; index >= 1; --index) { + if (fs::exists(backup(index))) { + fs::rename(backup(index), backup(index + 1)); + } + } + if (fs::exists(log)) { + fs::rename(log, backup(1)); + } +} diff --git a/mods/src/patches/patches.cc b/mods/src/patches/patches.cc index 16ab0903..26f30b49 100644 --- a/mods/src/patches/patches.cc +++ b/mods/src/patches/patches.cc @@ -1,5 +1,6 @@ #include "patches.h" #include "file.h" +#include "log_history.h" #include "version.h" #include @@ -70,7 +71,15 @@ __int64 il2cpp_init_hook(auto original, const char* domain_name) File::Init(); - auto file_logger = spdlog::basic_logger_mt("default", File::Log(), true); + std::string rotation_error; + try { + RotateLogHistory(File::Log()); + } catch (const std::filesystem::filesystem_error& error) { + rotation_error = error.what(); + } + + // Append if rotation failed so an existing log is never truncated. + auto file_logger = spdlog::basic_logger_mt("default", File::Log(), false); auto sink = std::make_shared(); file_logger->sinks().push_back(sink); spdlog::set_default_logger(file_logger); @@ -80,6 +89,9 @@ __int64 il2cpp_init_hook(auto original, const char* domain_name) spdlog::set_level(log_level); spdlog::flush_on(log_level); + if (!rotation_error.empty()) { + spdlog::warn("Failed to rotate log history; preserving existing log: {}", rotation_error); + } #if VERSION_PATCH if constexpr (sizeof(VERSION_COMMIT_HASH) > 1) {