From bb0d7802c0b4dcd3645275f18e6740b912ce5b95 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 18 Oct 2014 22:45:28 +0300 Subject: hercules: add tool to convert tmx to mapcahce.dat Untested. --- hercules/.gitignore | 1 + hercules/maptool.py | 104 +++++++++++++++++++++++++++++++++++++++++++++++++ hercules/tmxtocache.py | 1 + 3 files changed, 106 insertions(+) create mode 120000 hercules/tmxtocache.py diff --git a/hercules/.gitignore b/hercules/.gitignore index 9092a2d..8eb80be 100644 --- a/hercules/.gitignore +++ b/hercules/.gitignore @@ -1,3 +1,4 @@ clientdata maps serverdata +mapcache \ No newline at end of file diff --git a/hercules/maptool.py b/hercules/maptool.py index c6917d7..c8b65cc 100755 --- a/hercules/maptool.py +++ b/hercules/maptool.py @@ -19,6 +19,7 @@ import zlib import struct import shutil from sets import Set +from xml.dom import minidom def detectCommand(): if sys.argv[0][-12:] == "/listmaps.py": @@ -41,6 +42,8 @@ def detectCommand(): return "homunculusestoxml" elif sys.argv[0][-15:] == "/skillstoxml.py": return "skillstoxml" + elif sys.argv[0][-14:] == "/tmxtocache.py": + return "tmxtocache" return "help" def makeDir(path): @@ -73,6 +76,22 @@ def readFile(path): with open(path, "r") as f: return f.read() +def writeInt32(f, i): + f.write(struct.pack("I", i)) + +def writeInt16(f, i): + f.write(struct.pack("H", i)) + +def writeMapName(f, name): + if len(name) > 12: + name = name[:12] + while len(name) < 12: + name = name + '\x00' + f.write(struct.pack("12s", name)) + +def writeData(f, data): + f.write(data) + def getTileData(mapData, x, y, sx): data = mapData[y * sx + x] arr = array.array("B") @@ -491,6 +510,88 @@ def convertSkillsToXml(): data = data + tpl.format(skillId, name, description) saveFile(destDir + "skills.xml", skills.format(data)) +def getTmxFiles(srcDir): + for name in os.listdir(srcDir): + fileName = srcDir + name + if os.path.isfile(fileName) == False: + continue + if name.endswith(".tmx") == False: + continue + yield fileName + +def recreateMapCache(): + destDir = "mapcache/" + srcDir = "clientdata/maps/" + makeDir(destDir) + sz = 0L + mapsCount = 0 + with open(destDir + "map_cache.dat", "wb") as w: + writeInt32(w, 0) # file size + writeInt16(w, 0) # maps count + writeInt16(w, 0) # padding + for fileName in getTmxFiles(srcDir): + dom = minidom.parse(fileName) + root = dom.documentElement + firstgid = 0 + for tileset in root.getElementsByTagName("tileset"): + try: + name = tileset.attributes["name"].value + except: + name = "" + if name == "Collision": + firstgid = int(tileset.attributes["firstgid"].value) + break + + for layer in root.getElementsByTagName("layer"): + if layer.attributes["name"].value == "Collision": + data = layer.getElementsByTagName("data") + if data is None or len(data) != 1: + continue + data = data[0] + width = int(layer.attributes["width"].value) + height = int(layer.attributes["height"].value) + encoding = data.attributes["encoding"].value + compression = data.attributes["compression"].value + if encoding == "base64": + binData = data.childNodes[0].data.strip() + binData = binData.decode('base64') + if compression == "gzip": + dc = zlib.decompressobj(16 + zlib.MAX_WBITS) + else: + dc = zlib.decompressobj() + layerData = dc.decompress(binData) + arr = array.array("I") + arr.fromstring(layerData) + else: + print "map format not supported: " + fileName + continue + tiles = [] + for tile in arr: + if tile == 0: + tileType = 0 + else: + tileType = tile - firstgid; + if tileType == 0 or tileType == 4: + tiles.append(0) + else: + tiles.append(1) + comp = zlib.compressobj() + binData = struct.pack(str(len(tiles))+"B", *tiles) + binData = zlib.compress(binData) + idx = fileName.rfind("/") + 1 + mapName = fileName[idx:-4] + writeMapName(w, mapName) + writeInt16(w, width) + writeInt16(w, height) + writeInt32(w, len(binData)) + writeData(w, binData) + print fileName + mapsCount = mapsCount + 1 + sz = sz + 8 + len(binData) + break + w.seek(0); + writeInt32(w, sz) + writeInt16(w, mapsCount) def readMapCache(path, cmd): if cmd == "help": @@ -516,6 +617,9 @@ def readMapCache(path, cmd): elif cmd == "skillstoxml": convertSkillsToXml(); return + elif cmd == "tmxtocache": + recreateMapCache(); + return with open(path, "rb") as f: size = readInt32(f) diff --git a/hercules/tmxtocache.py b/hercules/tmxtocache.py new file mode 120000 index 0000000..df2b3e6 --- /dev/null +++ b/hercules/tmxtocache.py @@ -0,0 +1 @@ +maptool.py \ No newline at end of file -- cgit v1.2.3-70-g09d2