From 06826ca53dd54e73169514b3de2f81f2a7ca31f4 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Thu, 12 Mar 2026 07:20:42 -0500 Subject: Add native Root Builder and OMOD Installer plugins - libs/rootbuilder_native/: Native C++ port of rootbuilder.py (IPluginTool) - Root/ dir scanning, copy (reflink/CoW) and symlink modes - JSON manifest tracking, backup/restore, auto-deploy hooks - Legacy migration and third-party conflict detection - libs/installer_omod_native/: Native C++ port of installer_omod.py - Handles .omod archives (Oblivion Mod Manager format) - Binary config parsing, .NET string format, CRC file parsing - zlib raw deflate and LZMA decompression - Repackages to zip for MO2's installation manager - Added both to build-inner.sh plugin packaging Co-Authored-By: Claude Opus 4.6 --- libs/installer_omod_native/src/omodinstaller.h | 101 +++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 libs/installer_omod_native/src/omodinstaller.h (limited to 'libs/installer_omod_native/src/omodinstaller.h') diff --git a/libs/installer_omod_native/src/omodinstaller.h b/libs/installer_omod_native/src/omodinstaller.h new file mode 100644 index 0000000..de48b77 --- /dev/null +++ b/libs/installer_omod_native/src/omodinstaller.h @@ -0,0 +1,101 @@ +#ifndef OMODINSTALLER_H +#define OMODINSTALLER_H + +#include + +#include +#include +#include + +#include +#include + +class OmodInstaller : public MOBase::IPluginInstallerCustom +{ + Q_OBJECT + Q_INTERFACES(MOBase::IPlugin MOBase::IPluginInstaller MOBase::IPluginInstallerCustom) + Q_PLUGIN_METADATA(IID "com.tannin.ModOrganizer.PluginInstallerCustom/1.0") + +public: + OmodInstaller(); + + // IPlugin + bool init(MOBase::IOrganizer* organizer) override; + QString name() const override; + QString localizedName() const override; + QString author() const override; + QString description() const override; + MOBase::VersionInfo version() const override; + QList settings() const override; + + // IPluginInstaller + unsigned int priority() const override; + bool isManualInstaller() const override; + bool isArchiveSupported(std::shared_ptr tree) const override; + + // IPluginInstallerCustom + bool isArchiveSupported(const QString& archiveName) const override; + std::set supportedExtensions() const override; + EInstallResult install(MOBase::GuessedValue& modName, QString gameName, + const QString& archiveName, const QString& version, + int nexusID) override; + +private: + MOBase::IOrganizer* m_organizer = nullptr; + + // OMOD config parsed from the binary "config" entry. + struct OmodConfig + { + uint8_t fileVersion = 0; + QString modName; + int32_t major = 0; + int32_t minor = 0; + QString authorName; + QString email; + QString website; + QString desc; + uint8_t compressionType = 0; // 0 = deflate, 1 = lzma + }; + + // Entry from data.crc / plugins.crc. + struct CrcEntry + { + QString path; + uint32_t crc = 0; + int64_t size = 0; + }; + + // Binary reader helper over a QByteArray. + class BinaryReader + { + public: + explicit BinaryReader(const QByteArray& data); + + uint8_t readByte(); + int32_t readInt32LE(); + uint32_t readUInt32LE(); + int64_t readInt64LE(); + void skip(int bytes); + int read7BitEncodedInt(); + QString readNetString(); + QByteArray readBytes(int count); + bool atEnd() const; + + private: + const QByteArray& m_data; + int m_pos = 0; + }; + + OmodConfig parseConfig(const QByteArray& data); + std::vector parseCrcFile(const QByteArray& data); + QByteArray decompressStream(const QByteArray& data, uint8_t compressionType); + + EInstallResult doInstall(MOBase::GuessedValue& modName, + const QString& archiveName); + + void extractStream(const QString& omodDir, const QString& streamName, + const QString& crcName, uint8_t compressionType, + const QString& outDir); +}; + +#endif // OMODINSTALLER_H -- cgit v1.3.1