diff options
-rw-r--r-- | hercules/code/clienttoserver/maps.py | 222 | ||||
-rw-r--r-- | hercules/code/fileutils.py | 4 |
2 files changed, 118 insertions, 108 deletions
diff --git a/hercules/code/clienttoserver/maps.py b/hercules/code/clienttoserver/maps.py index b8ee14c..62874b0 100644 --- a/hercules/code/clienttoserver/maps.py +++ b/hercules/code/clienttoserver/maps.py @@ -5,13 +5,14 @@ import array import csv +import md5 import os import zlib import struct import StringIO from xml.dom import minidom -from code.fileutils import makeDir, writeInt16, writeInt32, writeMapName, writeData +from code.fileutils import makeDir, writeInt16, writeInt32, writeMapName, writeData, removeDir def getTmxFiles(srcDir): names = [] @@ -24,7 +25,7 @@ def getTmxFiles(srcDir): continue if name.endswith(".tmx") == False: continue - yield fileName + yield (fileName, name) def findFirstGid(tilesets, tile): found = -1 @@ -58,115 +59,120 @@ def convertTileType(tile): tile = 1 return tile -def recreateMapCache(): - destDir = "../../server-data/db/re/" - srcDir = "../../client-data/maps/" - makeDir(destDir) - sz = 0L - mapsCount = 0 +# map file format +# +# int16 version; +# uint8 md5_checksum[16]; +# int16 xs; +# int16 ys; +# int32 len; +# ...data... + +def recreateMap(names): collisionLayerName = "collision" - with open(destDir + "map_cache.dat", "wb") as w: - writeInt32(w, 0) # file size - writeInt16(w, 0) # maps count - writeInt16(w, 0) # padding - sz = sz + 8 - for fileName in getTmxFiles(srcDir): - dom = minidom.parse(fileName) - root = dom.documentElement - tilesets = [] - for tileset in root.getElementsByTagName("tileset"): - tilesets.append(int(tileset.attributes["firstgid"].value)) + destDir = "../../server-data/maps/re/" + tmxName = names[0] + mCaheName = destDir + names[1][:-3] + "mcache" + with open(mCaheName, "wb") as w: + print (tmxName, mCaheName) + dom = minidom.parse(tmxName) + root = dom.documentElement + tilesets = [] + for tileset in root.getElementsByTagName("tileset"): + tilesets.append(int(tileset.attributes["firstgid"].value)) + tilesets.sort(reverse = True) + found = False + for layer in root.getElementsByTagName("layer"): + if layer.attributes["name"].value.lower() == collisionLayerName: + 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 + try: + compression = data.attributes["compression"].value + except: + compression = "" - tilesets.sort(reverse = True) + tiles = [] + 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) + for tile in arr: + if tile == 0: + tileType = 0 + else: + firstgid = findFirstGid(tilesets, tile) + tileType = convertTileType(tile - firstgid); + tiles.append(tileType) + elif encoding == "csv": + binData = data.childNodes[0].data.strip() + f = StringIO.StringIO(binData) + arr = list(csv.reader(f, delimiter=',', quotechar='|')) + for row in arr: + for item in row: + if item != "": + tile = int(item) + if tile == 0: + tileType = 0 + else: + firstgid = findFirstGid(tilesets, tile) + tileType = convertTileType(tile - firstgid); + # tmx collision format + # 0 - walkable ground + # 1 - non walkable wall + # 2 - air allowed shootable too + # 3 - water allowed water, shootable too + # 4 - sit, walkable ground + # 5 - none - found = False - for layer in root.getElementsByTagName("layer"): - if layer.attributes["name"].value.lower() == collisionLayerName: - 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 - try: - compression = data.attributes["compression"].value - except: - compression = "" + # server collision format + # 000 0 - walkable, shootable + # 001 1 - wall + # 010 2 - same with 0 + # 011 3 - walkable, shootable, water + # 100 4 - same with 0 + # 101 5 - shootable + # 110 6 - same with 0 + # 111 7 - none + if tileType > 128 or tileType < 0: + tileType = 1 + tiles.append(tileType) + f.close() + else: + print "map format not supported: " + tmxName + continue + + #comp = zlib.compressobj() + binData = struct.pack(str(len(tiles))+"B", *tiles) + binData = zlib.compress(binData) + writeInt16(w, 1) + writeData(w, md5.new(binData).digest()) # 16 bytes + writeInt16(w, width) + writeInt16(w, height) + writeInt32(w, len(binData)) + writeData(w, binData) + print tmxName + found = True + break + if found == False: + print "Error: missing collision layer in file: {0}".format(tmxName) - tiles = [] - 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) - for tile in arr: - if tile == 0: - tileType = 0 - else: - firstgid = findFirstGid(tilesets, tile) - tileType = convertTileType(tile - firstgid); - tiles.append(tileType) - elif encoding == "csv": - binData = data.childNodes[0].data.strip() - f = StringIO.StringIO(binData) - arr = list(csv.reader(f, delimiter=',', quotechar='|')) - for row in arr: - for item in row: - if item != "": - tile = int(item) - if tile == 0: - tileType = 0 - else: - firstgid = findFirstGid(tilesets, tile) - tileType = convertTileType(tile - firstgid); - # tmx collision format - # 0 - walkable ground - # 1 - non walkable wall - # 2 - air allowed shootable too - # 3 - water allowed water, shootable too - # 4 - sit, walkable ground - # 5 - none - # server collision format - # 000 0 - walkable, shootable - # 001 1 - wall - # 010 2 - same with 0 - # 011 3 - walkable, shootable, water - # 100 4 - same with 0 - # 101 5 - shootable - # 110 6 - same with 0 - # 111 7 - none - if tileType > 128 or tileType < 0: - tileType = 1 - tiles.append(tileType) - f.close() - else: - print "map format not supported: " + fileName - continue - #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 + 12 + 8 + len(binData) - found = True - break - if found == False: - print "Error: missing collision layer in file: {0}".format(fileName) - w.seek(0); - writeInt32(w, sz) - writeInt16(w, mapsCount) +def recreateMapCache(): + destDir = "../../server-data/maps/re/" + srcDir = "../../client-data/maps/" + removeDir(destDir) + makeDir(destDir) + for names in getTmxFiles(srcDir): + recreateMap(names) diff --git a/hercules/code/fileutils.py b/hercules/code/fileutils.py index 2cf106b..a0635d4 100644 --- a/hercules/code/fileutils.py +++ b/hercules/code/fileutils.py @@ -70,6 +70,10 @@ def makeDir(path): if not os.path.exists(path): os.makedirs(path) +def removeDir(path): + if os.path.exists(path): + shutil.rmtree(path) + def removeAllFiles(path): if os.path.exists(path): shutil.rmtree(path) |