diff --git a/include/SKSE/API.h b/include/SKSE/API.h index f84eb7f48..830307c7d 100644 --- a/include/SKSE/API.h +++ b/include/SKSE/API.h @@ -12,7 +12,7 @@ namespace SKSE { - void Init(const LoadInterface* a_intfc) noexcept; + void Init(const LoadInterface* a_intfc, const bool a_log = false) noexcept; void RegisterForAPIInitEvent(std::function a_fn); PluginHandle GetPluginHandle() noexcept; diff --git a/include/SKSE/Interfaces.h b/include/SKSE/Interfaces.h index a519212cd..4a1086ad4 100644 --- a/include/SKSE/Interfaces.h +++ b/include/SKSE/Interfaces.h @@ -381,9 +381,30 @@ namespace SKSE kVersionIndependentEx_NoStructUse = 1 << 0, }; - constexpr void AuthorEmail(std::string_view a_email) noexcept { SetCharBuffer(a_email, std::span{ supportEmail }); } + constexpr void PluginVersion(REL::Version a_version) noexcept { pluginVersion = a_version.pack(); } + + [[nodiscard]] constexpr REL::Version GetPluginVersion() const noexcept { return REL::Version::unpack(pluginVersion); } + + constexpr void PluginName(std::string_view a_plugin) noexcept { SetCharBuffer(a_plugin, std::span{ pluginName }); } + + [[nodiscard]] constexpr std::string_view GetPluginName() const noexcept { return std::string_view{ pluginName }; } + constexpr void AuthorName(std::string_view a_name) noexcept { SetCharBuffer(a_name, std::span{ author }); } + [[nodiscard]] constexpr std::string_view GetAuthorName() const noexcept { return std::string_view{ author }; } + + constexpr void AuthorEmail(std::string_view a_email) noexcept { SetCharBuffer(a_email, std::span{ supportEmail }); } + + [[nodiscard]] constexpr std::string_view GetAuthorEmail() const noexcept { return std::string_view{ supportEmail }; } + + constexpr void UsesAddressLibrary() noexcept { versionIndependence |= kVersionIndependent_AddressLibraryPostAE; } + constexpr void UsesSigScanning() noexcept { versionIndependence |= kVersionIndependent_Signatures; } + constexpr void UsesUpdatedStructs() noexcept { versionIndependence |= kVersionIndependent_StructsPost629; } + + constexpr void UsesNoStructs() noexcept { versionIndependenceEx |= kVersionIndependentEx_NoStructUse; } + + constexpr void MinimumRequiredXSEVersion(REL::Version a_version) noexcept { xseMinimum = a_version.pack(); } + constexpr void CompatibleVersions(std::initializer_list a_versions) noexcept { assert(a_versions.size() < std::size(compatibleVersions) - 1); @@ -394,14 +415,7 @@ namespace SKSE [](const REL::Version& a_version) noexcept { return a_version.pack(); }); } - constexpr void MinimumRequiredXSEVersion(REL::Version a_version) noexcept { xseMinimum = a_version.pack(); } - constexpr void PluginName(std::string_view a_plugin) noexcept { SetCharBuffer(a_plugin, std::span{ pluginName }); } - constexpr void PluginVersion(REL::Version a_version) noexcept { pluginVersion = a_version.pack(); } - constexpr void UsesAddressLibrary() noexcept { versionIndependence |= kVersionIndependent_AddressLibraryPostAE; } - constexpr void UsesSigScanning() noexcept { versionIndependence |= kVersionIndependent_Signatures; } - constexpr void UsesUpdatedStructs() noexcept { versionIndependence |= kVersionIndependent_StructsPost629; } - - constexpr void UsesNoStructs() noexcept { versionIndependenceEx |= kVersionIndependentEx_NoStructUse; } + [[nodiscard]] static const PluginVersionData* GetSingleton() noexcept; const std::uint32_t dataVersion{ kVersion }; std::uint32_t pluginVersion = 0; @@ -435,3 +449,6 @@ namespace SKSE static_assert(sizeof(PluginVersionData) == 0x350); #endif } + +#define SKSEPluginLoad(...) extern "C" [[maybe_unused]] __declspec(dllexport) bool SKSEPlugin_Load(__VA_ARGS__) +#define SKSEPluginVersion extern "C" [[maybe_unused]] __declspec(dllexport) constinit SKSE::PluginVersionData SKSEPlugin_Version diff --git a/include/SKSE/Logger.h b/include/SKSE/Logger.h index 338367225..1e1d09a6e 100644 --- a/include/SKSE/Logger.h +++ b/include/SKSE/Logger.h @@ -39,6 +39,8 @@ namespace SKSE::log void add_papyrus_sink(std::regex a_filter); void remove_papyrus_sink(); + + void init(); } #undef SKSE_MAKE_SOURCE_LOGGER diff --git a/src/SKSE/API.cpp b/src/SKSE/API.cpp index c157b8283..5587a9579 100644 --- a/src/SKSE/API.cpp +++ b/src/SKSE/API.cpp @@ -69,12 +69,16 @@ namespace SKSE } } - void Init(const LoadInterface* a_intfc) noexcept + void Init(const LoadInterface* a_intfc, const bool a_log) noexcept { if (!a_intfc) { stl::report_and_fail("interface is null"sv); } + if (a_log) { + log::init(); + } + (void)REL::Module::get(); (void)REL::IDDatabase::get(); diff --git a/src/SKSE/Interfaces.cpp b/src/SKSE/Interfaces.cpp index 5fa091224..6cf961398 100644 --- a/src/SKSE/Interfaces.cpp +++ b/src/SKSE/Interfaces.cpp @@ -341,4 +341,9 @@ namespace SKSE assert(this); return reinterpret_cast(this); } + + const PluginVersionData* PluginVersionData::GetSingleton() noexcept + { + return reinterpret_cast(REX::W32::GetProcAddress(REX::W32::GetCurrentModule(), "SKSEPlugin_Version")); + } } diff --git a/src/SKSE/Logger.cpp b/src/SKSE/Logger.cpp index 424ba6fed..bf3809246 100644 --- a/src/SKSE/Logger.cpp +++ b/src/SKSE/Logger.cpp @@ -9,6 +9,9 @@ #include "SKSE/API.h" +#include +#include + namespace SKSE { namespace Impl @@ -113,5 +116,32 @@ namespace SKSE } }); } + + void init() + { + auto path = log_directory(); + if (!path) { + return; + } + + const auto data = PluginVersionData::GetSingleton(); + *path /= std::format("{}.log", data->GetPluginName()); + + std::vector sinks{ + std::make_shared(path->string(), true), + std::make_shared() + }; + + auto logger = std::make_shared("Global", sinks.begin(), sinks.end()); +#ifndef NDEBUG + logger->set_level(spdlog::level::debug); + logger->flush_on(spdlog::level::debug); +#else + logger->set_level(spdlog::level::info); + logger->flush_on(spdlog::level::info); +#endif + spdlog::set_default_logger(std::move(logger)); + spdlog::set_pattern("[%T.%e] [%=5t] [%L] %v"); + } } }