From 76e88275c06d88d0f2d8c23c1bc5fd5ae1352ce2 Mon Sep 17 00:00:00 2001 From: Will Toohey Date: Fri, 10 Jul 2026 20:06:00 +1000 Subject: [PATCH] Do our best to unpack mojibake'd texture manifests --- pyproject.toml | 2 +- src/ifstools/handlers/generic_file.py | 8 +++++++- src/ifstools/handlers/md5_folder.py | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 101f90e..dfcd6de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "ifstools" -version = "2.1" +version = "2.2" description = "Extractor/repacker for Konmai IFS files" readme = "README.md" authors = [ diff --git a/src/ifstools/handlers/generic_file.py b/src/ifstools/handlers/generic_file.py index c17172f..9536f20 100644 --- a/src/ifstools/handlers/generic_file.py +++ b/src/ifstools/handlers/generic_file.py @@ -2,6 +2,7 @@ import os import lxml.etree as etree from kbinxml import KBinXML +from kbinxml.kbinxml import KBinException from .. import utils from .node import Node @@ -37,7 +38,12 @@ class GenericFile(Node): data = self.ifs_data.get(self.start, self.size) if convert_kbin and self.name.endswith('.xml') and KBinXML.is_binary_xml(data): - data = KBinXML(data).to_text().encode('utf8') + try: + data = KBinXML(data).to_text().encode('utf8') + except KBinException as e: + if 'convert_illegal_things' in e.args[0]: + print("Corrupt xml found, trying to decode as utf8") + data = KBinXML(data, convert_illegal_things=True).to_text().encode('utf8') return data def _load_from_filesystem(self, **kwargs): diff --git a/src/ifstools/handlers/md5_folder.py b/src/ifstools/handlers/md5_folder.py index 7505a39..94d0093 100644 --- a/src/ifstools/handlers/md5_folder.py +++ b/src/ifstools/handlers/md5_folder.py @@ -1,6 +1,7 @@ from hashlib import md5 from kbinxml import KBinXML +from kbinxml.kbinxml import KBinException from .generic_folder import GenericFolder @@ -20,6 +21,7 @@ class MD5Folder(GenericFolder): self.info_kbin = None self.info_file = None + self.encoding_override = None for filename, file in self.files.items(): if filename.endswith('.xml'): self.info_file = file @@ -29,7 +31,15 @@ class MD5Folder(GenericFolder): # _super_ references to info XML breaks things - just extract what we can return - self.info_kbin = KBinXML(self.info_file.load(convert_kbin = False)) + kbin_raw = self.info_file.load(convert_kbin = False) + try: + self.info_kbin = KBinXML(kbin_raw) + except KBinException as e: + if 'convert_illegal_things' in e.args[0]: + print("Corrupt texturelist xml found, trying to decode as utf8") + self.info_kbin = KBinXML(kbin_raw, convert_illegal_things=True) + self.encoding_override = 'utf8' + self._apply_md5() def _apply_md5(self): @@ -39,7 +49,7 @@ class MD5Folder(GenericFolder): def _apply_md5_folder(self, plain_list, folder): for plain in plain_list: - hashed = md5(plain.encode(self.info_kbin.encoding)).hexdigest() + hashed = md5(plain.encode(self.encoding_override or self.info_kbin.encoding)).hexdigest() if self.extension: plain += self.extension