diff options
| author | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-04-28 20:11:14 -0500 |
|---|---|---|
| committer | SulfurNitride <SulfurNitride@users.noreply.github.com> | 2026-04-28 20:11:14 -0500 |
| commit | fbfdd7b1171e692a663bf221075abfe0e0ef0ab9 (patch) | |
| tree | 941e0d6e576cc53542b4bb8d1165887351972a79 /libs | |
| parent | 817524ce9e1146cfad05b7a2e7d41495bcde537b (diff) | |
Native port of SKSELogRedirector plugin family (sysdmp), default off
Three FileMapper variants — Steam SSE, GOG, VR — that redirect
<docs>/My Games/<X> onto a sibling folder so SKSE writes logs to the
right place. Only one applies per game; all default off so the user
opts in to the matching variant.
Layout mirrors game_bethesda: shared static lib in src/common/ with the
QObject base (init/author/version/settings/enabledByDefault/mappings),
three plugin .so subdirs each adding Q_PLUGIN_METADATA + their own
name/description and destFolderName override. Q_PLUGIN_METADATA can
only appear once per .so, hence the split.
Paths preserved verbatim from the upstream .py — including the SSE
variant's "Skyrim.INI" sibling folder, which is intentional: a Skyrim
bug sometimes creates a directory of that name and the redirect makes
SKSE find logs in SSE's docs folder.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/skse_log_redirector/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/common/CMakeLists.txt | 26 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/common/skseLogRedirectorBase.cpp | 62 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/common/skseLogRedirectorBase.h | 48 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/gog/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/gog/skseLogRedirectorGOG.cpp | 22 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/gog/skseLogRedirectorGOG.h | 17 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/sse/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/sse/skseLogRedirector.cpp | 24 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/sse/skseLogRedirector.h | 17 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/vr/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/vr/skseLogRedirectorVR.cpp | 22 | ||||
| -rw-r--r-- | libs/skse_log_redirector/src/vr/skseLogRedirectorVR.h | 17 | ||||
| -rw-r--r-- | libs/skse_log_redirector/vcpkg.json | 15 |
15 files changed, 320 insertions, 0 deletions
diff --git a/libs/skse_log_redirector/CMakeLists.txt b/libs/skse_log_redirector/CMakeLists.txt new file mode 100644 index 0000000..3e10a97 --- /dev/null +++ b/libs/skse_log_redirector/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.16) + +project(skse_log_redirector) + +add_subdirectory(src) diff --git a/libs/skse_log_redirector/src/CMakeLists.txt b/libs/skse_log_redirector/src/CMakeLists.txt new file mode 100644 index 0000000..5ab9468 --- /dev/null +++ b/libs/skse_log_redirector/src/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.16) + +add_subdirectory(common) +add_subdirectory(sse) +add_subdirectory(gog) +add_subdirectory(vr) diff --git a/libs/skse_log_redirector/src/common/CMakeLists.txt b/libs/skse_log_redirector/src/common/CMakeLists.txt new file mode 100644 index 0000000..7aefbda --- /dev/null +++ b/libs/skse_log_redirector/src/common/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.16) + +add_library(skse_log_redirector_common STATIC + skseLogRedirectorBase.cpp + skseLogRedirectorBase.h +) + +set_target_properties(skse_log_redirector_common PROPERTIES + AUTOMOC ON + CXX_STANDARD 23 + CXX_STANDARD_REQUIRED ON + POSITION_INDEPENDENT_CODE ON +) + +target_include_directories(skse_log_redirector_common + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_compile_options(skse_log_redirector_common PRIVATE + "-idirafter" "${CMAKE_SOURCE_DIR}/libs/uibase/include/uibase" +) +set_property(TARGET skse_log_redirector_common APPEND PROPERTY AUTOMOC_MOC_OPTIONS + "-I${CMAKE_SOURCE_DIR}/libs/uibase/include/uibase" +) + +target_link_libraries(skse_log_redirector_common PUBLIC mo2::uibase) diff --git a/libs/skse_log_redirector/src/common/skseLogRedirectorBase.cpp b/libs/skse_log_redirector/src/common/skseLogRedirectorBase.cpp new file mode 100644 index 0000000..8b35201 --- /dev/null +++ b/libs/skse_log_redirector/src/common/skseLogRedirectorBase.cpp @@ -0,0 +1,62 @@ +#include "skseLogRedirectorBase.h" + +#include <uibase/imoinfo.h> +#include <uibase/iplugingame.h> +#include <uibase/pluginsetting.h> +#include <uibase/versioninfo.h> + +#include <QDir> + +using namespace MOBase; + +bool SkseLogRedirectorBase::init(IOrganizer* moInfo) +{ + m_organizer = moInfo; + return true; +} + +QString SkseLogRedirectorBase::author() const +{ + return "sysdmp"; +} + +VersionInfo SkseLogRedirectorBase::version() const +{ + return VersionInfo(0, 0, 1); +} + +QList<PluginSetting> SkseLogRedirectorBase::settings() const +{ + return {}; +} + +bool SkseLogRedirectorBase::enabledByDefault() const +{ + return false; +} + +MappingType SkseLogRedirectorBase::mappings() const +{ + MappingType result; + if (m_organizer == nullptr) { + return result; + } + const IPluginGame* game = m_organizer->managedGame(); + if (game == nullptr) { + return result; + } + + const QString docsPath = game->documentsDirectory().absolutePath(); + // Sibling folder under "My Games" — e.g. <docs>/../Skyrim. QDir::cleanPath + // collapses the "..", matching pathlib.Path.resolve() in the upstream .py. + const QString siblingPath = + QDir::cleanPath(docsPath + QStringLiteral("/../") + destFolderName()); + + Mapping m; + m.source = docsPath; + m.destination = siblingPath; + m.isDirectory = true; + m.createTarget = true; + result.push_back(std::move(m)); + return result; +} diff --git a/libs/skse_log_redirector/src/common/skseLogRedirectorBase.h b/libs/skse_log_redirector/src/common/skseLogRedirectorBase.h new file mode 100644 index 0000000..ec2399e --- /dev/null +++ b/libs/skse_log_redirector/src/common/skseLogRedirectorBase.h @@ -0,0 +1,48 @@ +#pragma once + +#include <uibase/filemapping.h> +#include <uibase/iplugin.h> +#include <uibase/ipluginfilemapper.h> + +#include <QList> +#include <QObject> +#include <QString> + +namespace MOBase +{ +struct PluginSetting; +class IOrganizer; +} // namespace MOBase + +// Shared base for the SKSELogRedirector plugin family (sysdmp). Each variant +// (Steam SSE, GOG, VR) only differs in the destination folder name under +// "My Games" — everything else is identical, so the variants subclass this +// base and override destFolderName(). +// +// All variants are off by default: only one is applicable per game and the +// user opts into the matching one. +class SkseLogRedirectorBase : public QObject, + public MOBase::IPlugin, + public MOBase::IPluginFileMapper +{ + Q_OBJECT + Q_INTERFACES(MOBase::IPlugin MOBase::IPluginFileMapper) + +public: + // IPlugin + bool init(MOBase::IOrganizer* moInfo) override; + QString author() const override; + MOBase::VersionInfo version() const override; + QList<MOBase::PluginSetting> settings() const override; + bool enabledByDefault() const override; + + // IPluginFileMapper + MappingType mappings() const override; + +protected: + // Sibling folder name under "My Games" — e.g. "Skyrim", "Skyrim VR", + // "Skyrim Special Edition", "Skyrim.INI". + virtual QString destFolderName() const = 0; + + MOBase::IOrganizer* m_organizer = nullptr; +}; diff --git a/libs/skse_log_redirector/src/gog/CMakeLists.txt b/libs/skse_log_redirector/src/gog/CMakeLists.txt new file mode 100644 index 0000000..ef78d3e --- /dev/null +++ b/libs/skse_log_redirector/src/gog/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.16) + +add_library(skse_log_redirector_gog SHARED + skseLogRedirectorGOG.cpp + skseLogRedirectorGOG.h +) +mo2_configure_plugin(skse_log_redirector_gog NO_SOURCES WARNINGS OFF) +target_link_libraries(skse_log_redirector_gog PRIVATE + mo2::uibase + skse_log_redirector_common +) + +mo2_install_plugin(skse_log_redirector_gog) diff --git a/libs/skse_log_redirector/src/gog/skseLogRedirectorGOG.cpp b/libs/skse_log_redirector/src/gog/skseLogRedirectorGOG.cpp new file mode 100644 index 0000000..c1da77b --- /dev/null +++ b/libs/skse_log_redirector/src/gog/skseLogRedirectorGOG.cpp @@ -0,0 +1,22 @@ +#include "skseLogRedirectorGOG.h" + +QString SkseLogRedirectorGOG::name() const +{ + return "SKSE Log Redirector GOG"; +} + +QString SkseLogRedirectorGOG::localizedName() const +{ + return tr("SKSE Log Redirector GOG"); +} + +QString SkseLogRedirectorGOG::description() const +{ + return tr("Redirects \"\\Documents\\My Games\\Skyrim Special Edition\" to " + "\"\\Documents\\My Games\\Skyrim Special Edition GOG\" via VFS."); +} + +QString SkseLogRedirectorGOG::destFolderName() const +{ + return QStringLiteral("Skyrim Special Edition"); +} diff --git a/libs/skse_log_redirector/src/gog/skseLogRedirectorGOG.h b/libs/skse_log_redirector/src/gog/skseLogRedirectorGOG.h new file mode 100644 index 0000000..683bf31 --- /dev/null +++ b/libs/skse_log_redirector/src/gog/skseLogRedirectorGOG.h @@ -0,0 +1,17 @@ +#pragma once + +#include "skseLogRedirectorBase.h" + +class SkseLogRedirectorGOG : public SkseLogRedirectorBase +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.sysdmp.SKSELogRedirectorGOG") + +public: + QString name() const override; + QString localizedName() const override; + QString description() const override; + +protected: + QString destFolderName() const override; +}; diff --git a/libs/skse_log_redirector/src/sse/CMakeLists.txt b/libs/skse_log_redirector/src/sse/CMakeLists.txt new file mode 100644 index 0000000..36a06ec --- /dev/null +++ b/libs/skse_log_redirector/src/sse/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.16) + +add_library(skse_log_redirector SHARED + skseLogRedirector.cpp + skseLogRedirector.h +) +mo2_configure_plugin(skse_log_redirector NO_SOURCES WARNINGS OFF) +target_link_libraries(skse_log_redirector PRIVATE + mo2::uibase + skse_log_redirector_common +) + +mo2_install_plugin(skse_log_redirector) diff --git a/libs/skse_log_redirector/src/sse/skseLogRedirector.cpp b/libs/skse_log_redirector/src/sse/skseLogRedirector.cpp new file mode 100644 index 0000000..20cc44c --- /dev/null +++ b/libs/skse_log_redirector/src/sse/skseLogRedirector.cpp @@ -0,0 +1,24 @@ +#include "skseLogRedirector.h" + +QString SkseLogRedirector::name() const +{ + return "SKSE Log Redirector"; +} + +QString SkseLogRedirector::localizedName() const +{ + return tr("SKSE Log Redirector"); +} + +QString SkseLogRedirector::description() const +{ + return tr("Redirects \"\\Documents\\My Games\\SKYRIM.INI\" to " + "\"\\Documents\\My Games\\Skyrim Special Edition\" via VFS."); +} + +QString SkseLogRedirector::destFolderName() const +{ + // Verbatim from upstream .py: "Skyrim.INI" can be a directory created by a + // Skyrim bug; redirecting it makes SKSE find logs in the SSE docs. + return QStringLiteral("Skyrim.INI"); +} diff --git a/libs/skse_log_redirector/src/sse/skseLogRedirector.h b/libs/skse_log_redirector/src/sse/skseLogRedirector.h new file mode 100644 index 0000000..5074550 --- /dev/null +++ b/libs/skse_log_redirector/src/sse/skseLogRedirector.h @@ -0,0 +1,17 @@ +#pragma once + +#include "skseLogRedirectorBase.h" + +class SkseLogRedirector : public SkseLogRedirectorBase +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.sysdmp.SKSELogRedirector") + +public: + QString name() const override; + QString localizedName() const override; + QString description() const override; + +protected: + QString destFolderName() const override; +}; diff --git a/libs/skse_log_redirector/src/vr/CMakeLists.txt b/libs/skse_log_redirector/src/vr/CMakeLists.txt new file mode 100644 index 0000000..00e5ac2 --- /dev/null +++ b/libs/skse_log_redirector/src/vr/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.16) + +add_library(skse_log_redirector_vr SHARED + skseLogRedirectorVR.cpp + skseLogRedirectorVR.h +) +mo2_configure_plugin(skse_log_redirector_vr NO_SOURCES WARNINGS OFF) +target_link_libraries(skse_log_redirector_vr PRIVATE + mo2::uibase + skse_log_redirector_common +) + +mo2_install_plugin(skse_log_redirector_vr) diff --git a/libs/skse_log_redirector/src/vr/skseLogRedirectorVR.cpp b/libs/skse_log_redirector/src/vr/skseLogRedirectorVR.cpp new file mode 100644 index 0000000..caf9d86 --- /dev/null +++ b/libs/skse_log_redirector/src/vr/skseLogRedirectorVR.cpp @@ -0,0 +1,22 @@ +#include "skseLogRedirectorVR.h" + +QString SkseLogRedirectorVR::name() const +{ + return "SKSE Log Redirector (test build with VR workaround)"; +} + +QString SkseLogRedirectorVR::localizedName() const +{ + return tr("SKSE Log Redirector (test build with VR workaround)"); +} + +QString SkseLogRedirectorVR::description() const +{ + return tr("Redirects \"\\Documents\\My Games\\Skyrim VR\" to " + "\"\\Documents\\My Games\\Skyrim Special Edition\" via VFS."); +} + +QString SkseLogRedirectorVR::destFolderName() const +{ + return QStringLiteral("Skyrim VR"); +} diff --git a/libs/skse_log_redirector/src/vr/skseLogRedirectorVR.h b/libs/skse_log_redirector/src/vr/skseLogRedirectorVR.h new file mode 100644 index 0000000..bce099f --- /dev/null +++ b/libs/skse_log_redirector/src/vr/skseLogRedirectorVR.h @@ -0,0 +1,17 @@ +#pragma once + +#include "skseLogRedirectorBase.h" + +class SkseLogRedirectorVR : public SkseLogRedirectorBase +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.sysdmp.SKSELogRedirectorVR") + +public: + QString name() const override; + QString localizedName() const override; + QString description() const override; + +protected: + QString destFolderName() const override; +}; diff --git a/libs/skse_log_redirector/vcpkg.json b/libs/skse_log_redirector/vcpkg.json new file mode 100644 index 0000000..a639ce6 --- /dev/null +++ b/libs/skse_log_redirector/vcpkg.json @@ -0,0 +1,15 @@ +{ + "features": { + "standalone": { + "description": "Build Standalone.", + "dependencies": ["mo2-cmake"] + } + }, + "vcpkg-configuration": { + "default-registry": { + "kind": "git", + "repository": "https://github.com/ModOrganizer2/vcpkg-registry", + "baseline": "8beb2e0efa9c17dd6d17bb05288dd1e40727f673" + } + } +} |
