From 6fe3cf9f6becc6853587c34998c94b9d54137051 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Wed, 15 Apr 2026 15:25:35 -0500 Subject: Mirror synced plugins across case variants, fix OMOD logging syncPluginsBack previously updated the profile from the newest case variant but left the stale sibling (e.g. lowercase plugins.txt after LOOT edited Plugins.txt) untouched in the prefix, so anything reading the prefix before the next deployPlugins saw divergent content. Mirror the newest variant into every sibling after the profile sync. installer_omod.py called mobase.log / mobase.LogLevel which the Python bindings do not expose, crashing .omod installs with AttributeError. Route messages through stderr so the Python runner forwards them to MOBase::log::error. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/plugins/installer_omod.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/installer_omod.py b/src/plugins/installer_omod.py index 2a586c1..973b9ba 100644 --- a/src/plugins/installer_omod.py +++ b/src/plugins/installer_omod.py @@ -13,6 +13,7 @@ import lzma import os import shutil import struct +import sys import tempfile import zipfile import zlib @@ -21,6 +22,14 @@ from pathlib import Path import mobase +def _log_error(msg: str) -> None: + print(f"[OMOD] {msg}", file=sys.stderr) + + +def _log_warn(msg: str) -> None: + print(f"[OMOD] WARNING: {msg}", file=sys.stderr) + + class OmodInstaller(mobase.IPluginInstallerCustom): _organizer: mobase.IOrganizer @@ -79,7 +88,7 @@ class OmodInstaller(mobase.IPluginInstallerCustom): try: return self._do_install(mod_name, archive_name) except Exception as e: - mobase.log(mobase.LogLevel.ERROR, f"OMOD install failed: {e}") + _log_error(f"OMOD install failed: {e}") return mobase.InstallResult.FAILED def _do_install( @@ -91,7 +100,7 @@ class OmodInstaller(mobase.IPluginInstallerCustom): names = zf.namelist() if "config" not in names: - mobase.log(mobase.LogLevel.WARNING, "OMOD: no config entry found") + _log_warn("no config entry found") return mobase.InstallResult.NOT_ATTEMPTED config = self._parse_config(zf.read("config")) @@ -127,9 +136,7 @@ class OmodInstaller(mobase.IPluginInstallerCustom): file_list.append(rel) if not file_list: - mobase.log( - mobase.LogLevel.WARNING, "OMOD: no files extracted" - ) + _log_warn("no files extracted") return mobase.InstallResult.FAILED # Repackage as a standard zip for MO2's installer. @@ -155,10 +162,7 @@ class OmodInstaller(mobase.IPluginInstallerCustom): if stream_name not in names: return if crc_name not in names: - mobase.log( - mobase.LogLevel.WARNING, - f"OMOD: {stream_name} present but {crc_name} missing", - ) + _log_warn(f"{stream_name} present but {crc_name} missing") return file_list = self._parse_crc_file(zf.read(crc_name)) @@ -171,11 +175,10 @@ class OmodInstaller(mobase.IPluginInstallerCustom): offset = 0 for path, size in file_list: if offset + size > len(decompressed): - mobase.log( - mobase.LogLevel.WARNING, - f"OMOD: truncated stream for {path} " + _log_warn( + f"truncated stream for {path} " f"(need {size} bytes at offset {offset}, " - f"have {len(decompressed)})", + f"have {len(decompressed)})" ) break -- cgit v1.3.1