Handle OBSE INI tweaks.

This commit is contained in:
Mikaël Capelle
2020-11-15 19:47:33 +01:00
parent c1385c7b96
commit 83d39ee762
3 changed files with 117 additions and 8 deletions
+10
View File
@@ -7,6 +7,16 @@ This plugin can be used to install BAIN archives containing a wizard script (`wi
Go to the [releases page](https://github.com/Holt59/modorganizer-installer_wizard/releases) and download
the latest release for your MO2 version.
### A few words on INI Tweaks
Mod Organizer 2 does not currently manage INI Tweaks, so the Wizard installer is partially functional
regarding them.
- The installer will create proper INI Tweaks when requested, but these will not be applied
to the game INI files automatically. If INI Tweaks are present, a pop-up should appear at
the end of the installation.
- INI Tweaks for OBSE script are directly applied to the OBSE scripts.
## How to contribute?
### Setting-up the environment
-2
View File
@@ -311,8 +311,6 @@ class WizardInstaller(mobase.IPluginInstallerSimple):
for filename, tweaks in alltweaks.items():
print(tweaks)
# Find the original file (if any):
o_entry = tree.find(filename)
o_filename: Optional[str] = None
+107 -6
View File
@@ -1,7 +1,9 @@
# -*- encoding: utf-8 -*-
import re
from pathlib import Path
from typing import List, Mapping
from typing import Dict, List, Mapping
from wizard.tweaks import WizardINISetting, WizardINISettingEdit
@@ -47,9 +49,107 @@ def make_standard_ini_tweaks(tweaks: List[WizardINISetting]) -> str:
return "\n".join(lines[:-1])
def merge_standard_ini_tweaks(tweaks: List[WizardINISetting], file: Path) -> str:
print(f"Cannot merge INI Tweaks for {file.name}.", file=sys.stderr)
return make_standard_ini_tweaks(tweaks)
def merge_obscript_ini_tweaks(tweaks: List[WizardINISetting], file: Path) -> str:
# This is from Wrye Bash (and the function is inspired from Wrye Bash):
reComment = re.compile(";.*", re.U)
reDeleted = re.compile("" r";-(\w.*?)$", re.U)
reSet = re.compile("" r"\s*set\s+(.+?)\s+to\s+(.*)", re.I | re.U)
reSetGS = re.compile("" r"\s*setGS\s+(.+?)\s+(.*)", re.I | re.U)
reSetNGS = re.compile("" r"\s*SetNumericGameSetting\s+(.+?)\s+(.*)", re.I | re.U)
_regex_tuples = (
(reSet, "set", "set {} to {}"),
(reSetGS, "setgs", "setGS {} {}"),
(reSetNGS, "setnumericgamesetting", "SetNumericGameSetting {} {}"),
)
def _parse_obse_line(line):
for regex, sectionKey, format_string in _regex_tuples:
match = regex.match(line)
if match:
return match, sectionKey, format_string
return None, None, None
# Read the original file:
with open(file, "r") as fp:
olines = fp.readlines()
# Map setting name to value:
settings: Dict[str, Dict[str, WizardINISettingEdit]] = {}
deleted: Dict[str, Dict[str, WizardINISetting]] = {}
for tweak in tweaks:
if isinstance(tweak, WizardINISettingEdit):
if tweak.section not in settings:
settings[tweak.section.lower()] = {}
settings[tweak.section.lower()][tweak.setting] = tweak
else:
if tweak.section not in deleted:
deleted[tweak.section.lower()] = {}
deleted[tweak.section.lower()][tweak.setting] = tweak
# Create the lines:
lines = []
for line in olines:
line = line.rstrip()
maDeleted = reDeleted.match(line)
if maDeleted:
stripped = maDeleted.group(1)
else:
stripped = line
stripped = reComment.sub("", stripped).strip()
match, section_key, format_string = _parse_obse_line(stripped)
if match:
setting = match.group(1)
if section_key in settings and setting in settings[section_key]:
value = settings[section_key][setting].value
line = format_string.format(setting, value)
comment = ""
if settings[section_key][setting].comment:
comment = settings[section_key][setting].comment # type: ignore
comment += " "
comment += f"(set by MO2 via Wizard, was {match.group(2)})"
line = f"{line} ; {comment}"
del settings[section_key][setting]
elif (
not maDeleted
and section_key in deleted
and setting in deleted[section_key]
):
line = f";-{line}"
lines.append(line)
for section in settings.values():
for setting in section.values():
if setting.section.lower() == "set":
line = f"{setting.section} {setting.setting} to {setting.value}"
else:
line = f"{setting.section} {setting.setting} {setting.value}"
if setting.comment:
comment = setting.comment + " (set by MO2 via Wizard)"
else:
comment = "(set by MO2 via Wizard)"
line = f"{line} ; {comment}"
lines.append(line)
return "\n".join(lines)
def make_ini_tweaks(tweaks: List[WizardINISetting]) -> str:
is_set = [tw.section in ("set", "setGS", "SetNumericGameSetting") for tw in tweaks]
is_set = [
tw.section.lower() in ("set", "setgs", "setnumericgamesetting") for tw in tweaks
]
# Assume there is no mix.
if all(is_set):
@@ -60,11 +160,12 @@ def make_ini_tweaks(tweaks: List[WizardINISetting]) -> str:
def merge_ini_tweaks(tweaks: List[WizardINISetting], file: Path) -> str:
is_set = [tw.section in ("set", "setGS", "SetNumericGameSetting") for tw in tweaks]
is_set = [
tw.section.lower() in ("set", "setgs", "setnumericgamesetting") for tw in tweaks
]
# Assume there is no mix.
if all(is_set):
pass
return merge_obscript_ini_tweaks(tweaks, file)
else:
pass
return ""
return merge_standard_ini_tweaks(tweaks, file)