146 lines
4.3 KiB
Python
Executable File
146 lines
4.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Generate config_player.xml from SERVER.xml mod list preserving load order."""
|
|
|
|
import os
|
|
import sys
|
|
import xml.etree.ElementTree as ET
|
|
|
|
MODLIST_PATH = "/mnt/nvme/B/SteamLibrary/steamapps/common/Barotrauma/ModLists/SERVER.xml"
|
|
LOCALMODS_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "LocalMods")
|
|
OUTPUT = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config_player.xml")
|
|
WORKSHOP_DIR = "/mnt/nvme/B/SteamLibrary/steamapps/workshop/content/602960"
|
|
|
|
|
|
def log_ok(msg: str, indent: int = 0):
|
|
prefix = " " * indent + "\033[92m✓\033[0m"
|
|
print(f"{prefix} {msg}")
|
|
|
|
|
|
def log_info(msg: str, indent: int = 0):
|
|
prefix = " " * indent + "•"
|
|
print(f"{prefix} {msg}")
|
|
|
|
|
|
def log_warn(msg: str, indent: int = 0):
|
|
prefix = " " * indent + "\033[93m⚠\033[0m"
|
|
print(f"{prefix} {msg}")
|
|
|
|
|
|
def log_err(msg: str, indent: int = 0):
|
|
prefix = " " * indent + "\033[91m✗\033[0m"
|
|
print(f"{prefix} {msg}", file=sys.stderr)
|
|
|
|
|
|
def get_workshop_name(mod_id: str) -> str | None:
|
|
fl_path = os.path.join(WORKSHOP_DIR, mod_id, "filelist.xml")
|
|
if os.path.isfile(fl_path):
|
|
try:
|
|
return ET.parse(fl_path).getroot().get("name")
|
|
except Exception:
|
|
return None
|
|
return None
|
|
|
|
|
|
def find_mod_folder(name: str) -> str | None:
|
|
name_lower = name.lower()
|
|
if not os.path.isdir(LOCALMODS_DIR):
|
|
return None
|
|
for d in os.listdir(LOCALMODS_DIR):
|
|
if d.lower() == name_lower:
|
|
return d
|
|
return None
|
|
|
|
|
|
def resolve_mod_path(name: str, mod_id: str | None = None) -> str:
|
|
folder = find_mod_folder(name)
|
|
if folder and os.path.isfile(os.path.join(LOCALMODS_DIR, folder, "filelist.xml")):
|
|
return f"LocalMods/{folder}/filelist.xml"
|
|
|
|
if mod_id:
|
|
workshop_name = get_workshop_name(mod_id)
|
|
if workshop_name:
|
|
folder = find_mod_folder(workshop_name)
|
|
if folder and os.path.isfile(os.path.join(LOCALMODS_DIR, folder, "filelist.xml")):
|
|
return f"LocalMods/{folder}/filelist.xml"
|
|
|
|
return f"LocalMods/{name}/filelist.xml"
|
|
|
|
|
|
def main():
|
|
print()
|
|
print("╔══════════════════════════════════════════╗")
|
|
print("║ Autogen Config from SERVER.xml order ║")
|
|
print("╚══════════════════════════════════════════╝")
|
|
print()
|
|
|
|
if not os.path.isfile(MODLIST_PATH):
|
|
log_err(f"Mod list not found: {MODLIST_PATH}")
|
|
sys.exit(1)
|
|
|
|
log_info(f"Reading: {MODLIST_PATH}")
|
|
try:
|
|
tree = ET.parse(MODLIST_PATH)
|
|
root = tree.getroot()
|
|
except Exception as e:
|
|
log_err(f"Parse error: {e}")
|
|
sys.exit(1)
|
|
|
|
entries = list(root)
|
|
log_info(f"Total entries in mod list: {len(entries)}")
|
|
print()
|
|
|
|
resolved = []
|
|
missing = []
|
|
|
|
for el in entries:
|
|
tag = el.tag
|
|
if tag == "Vanilla":
|
|
continue
|
|
|
|
name = el.get("name", "").strip()
|
|
mod_id = el.get("id", "").strip() if tag == "Workshop" else None
|
|
|
|
if not name:
|
|
continue
|
|
|
|
path = resolve_mod_path(name, mod_id)
|
|
resolved.append(path)
|
|
|
|
full_path = os.path.join(os.path.dirname(OUTPUT), path)
|
|
if os.path.isfile(full_path):
|
|
log_ok(f"{name}", indent=1)
|
|
else:
|
|
missing.append(name)
|
|
log_warn(f"{name} — filelist.xml not found, adding anyway", indent=1)
|
|
|
|
print()
|
|
log_info(f"Mods resolved: {len([r for r in resolved if r])}")
|
|
if missing:
|
|
log_warn(f"Missing from LocalMods: {len(missing)}")
|
|
for m in missing:
|
|
log_info(f" {m}", indent=1)
|
|
|
|
print()
|
|
log_info("Generating config_player.xml...")
|
|
|
|
barotrauma = ET.Element("Barotrauma")
|
|
cps = ET.SubElement(barotrauma, "contentpackages")
|
|
ET.SubElement(cps, "corepackage", path="Content/ContentPackages/Vanilla.xml")
|
|
reg = ET.SubElement(cps, "regularpackages")
|
|
|
|
for r in resolved:
|
|
ET.SubElement(reg, "package", path=r)
|
|
|
|
ET.indent(barotrauma)
|
|
xml_str = ET.tostring(barotrauma, encoding="unicode", xml_declaration=True)
|
|
|
|
with open(OUTPUT, "w") as f:
|
|
f.write(xml_str)
|
|
|
|
log_ok(f"Written {OUTPUT}")
|
|
print()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|