Last active
October 17, 2023 21:44
-
-
Save nekiro/d4b74302bc85010e68eda07e55e62d33 to your computer and use it in GitHub Desktop.
Item name to item id converter script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import sys | |
| sys.modules["_elementtree"] = None | |
| import xml.etree.ElementTree as ET | |
| import os | |
| from pathlib import Path | |
| items = {} | |
| # stolen from https://stackoverflow.com/a/36430270 | |
| class LineNumberingParser(ET.XMLParser): | |
| def _start(self, *args, **kwargs): | |
| # Here we assume the default XML parser which is expat | |
| # and copy its element position attributes into output Elements | |
| element = super(self.__class__, self)._start(*args, **kwargs) | |
| element._start_line_number = self.parser.CurrentLineNumber | |
| element._start_column_number = self.parser.CurrentColumnNumber | |
| element._start_byte_index = self.parser.CurrentByteIndex | |
| return element | |
| def _end(self, *args, **kwargs): | |
| element = super(self.__class__, self)._end(*args, **kwargs) | |
| element._end_line_number = self.parser.CurrentLineNumber | |
| element._end_column_number = self.parser.CurrentColumnNumber | |
| element._end_byte_index = self.parser.CurrentByteIndex | |
| return element | |
| def convertMonster(path, name, outPath): | |
| path = os.path.join(path, name) | |
| if not os.path.exists(path): | |
| print("Couldn't find xml file at path {}", path) | |
| return | |
| print("Converting {}".format(name)) | |
| root = ET.parse(path, parser=LineNumberingParser(target=ET.TreeBuilder(insert_comments=True))).getroot() | |
| loot = root.find("loot") | |
| if loot is None: | |
| return | |
| commentsLines = {} | |
| for child in loot: | |
| item_name = child.attrib.get("name") | |
| id = child.attrib.get("id") | |
| if item_name is None or id is not None: | |
| continue | |
| child.attrib.pop("name") | |
| id = items.get(item_name.lower()) | |
| if id is None: | |
| continue | |
| # trickery to add new attribute as the first attribute, google didn't tell me how to do this in etree :( | |
| copy = list(child.attrib.items()) | |
| copy.insert(0, ("id", id)) | |
| child.attrib = dict(copy) | |
| # store to add item name comments | |
| commentsLines[child._start_line_number - 1] = item_name # dont ask me why it counts lines wrong, but - 1 fixes it, probably declaration? | |
| outFile = os.path.join(outPath, name) | |
| # save to file | |
| ET.ElementTree(root).write(os.path.join(outPath, name), encoding='utf-8', xml_declaration=True) | |
| # add comments with item name | |
| with open(outFile, "r") as f: | |
| lines = f.readlines() | |
| lines.append("\n") | |
| for key, value in commentsLines.items(): | |
| lines[key] = "{} <!-- {} -->\n".format(lines[key].rstrip("\n"), value) | |
| with open(outFile, "w") as f: | |
| f.writelines(lines) | |
| def convertMonsters(path): | |
| path = Path(path).resolve() | |
| if not os.path.exists(path): | |
| exit("Unable to resolve monsters directory, aborting...") | |
| print("Resolved monsters path {}".format(path)) | |
| outPath = os.path.join(Path(input("Out directory path (if out not present will create one)")).resolve(), "out") | |
| # ensure out directory is present | |
| if not os.path.exists(outPath): | |
| os.makedirs(outPath) | |
| print("Resolved output path {}".format(outPath)) | |
| # convert | |
| for file in os.listdir(path): | |
| if file.endswith(".xml"): | |
| convertMonster(path, file, outPath) | |
| def readItems(path): | |
| path = os.path.join(Path(path).resolve(), "items.xml") | |
| if not os.path.exists(path): | |
| exit('Unable to find items.xml in given path, aborting...') | |
| print("Resolved items path {}".format(path)) | |
| root = ET.parse(path).getroot() | |
| for elem in root: | |
| name = elem.attrib.get("name") | |
| id = elem.attrib.get("id") | |
| if name is None or id is None: | |
| continue | |
| items[name.lower()] = id | |
| if __name__ == "__main__": | |
| # read items first | |
| readItems(input("Path to items directory: ")) | |
| # monsters | |
| convertMonsters(input("Path to monster directory: ")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment