summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-10-31 01:08:46 +0300
committerAndrei Karas <akaras@inbox.ru>2014-10-31 12:19:12 +0300
commit746192af34a65504cb86a4eca068a8f0fbb361f5 (patch)
tree12d399627720f7fc72e66deb64bac7ef0d9eb71e
parent63f135d8af2a81a78626d6229d077e3f91a35288 (diff)
downloadevol-tools-746192af34a65504cb86a4eca068a8f0fbb361f5.tar.gz
evol-tools-746192af34a65504cb86a4eca068a8f0fbb361f5.tar.bz2
evol-tools-746192af34a65504cb86a4eca068a8f0fbb361f5.tar.xz
evol-tools-746192af34a65504cb86a4eca068a8f0fbb361f5.zip
hercules: split implimentation to many files.
-rw-r--r--hercules/.gitignore4
-rw-r--r--hercules/code/__init__.py0
-rw-r--r--hercules/code/clienttoserver/__init__.py0
-rw-r--r--hercules/code/clienttoserver/maps.py96
-rw-r--r--hercules/code/fileutils.py62
-rw-r--r--hercules/code/server/__init__.py0
-rw-r--r--hercules/code/server/maps.py35
-rw-r--r--hercules/code/servertoclient/__init__.py0
-rw-r--r--hercules/code/servertoclient/homunculuses.py29
-rw-r--r--hercules/code/servertoclient/items.py138
-rw-r--r--hercules/code/servertoclient/maps.py48
-rw-r--r--hercules/code/servertoclient/mercenaries.py29
-rw-r--r--hercules/code/servertoclient/monsters.py39
-rw-r--r--hercules/code/servertoclient/pets.py29
-rw-r--r--hercules/code/servertoclient/quests.py37
-rw-r--r--hercules/code/servertoclient/skills.py33
-rw-r--r--hercules/code/stringutils.py28
-rw-r--r--hercules/code/tileutils.py48
-rwxr-xr-xhercules/convert_mapcache_to_tmx.py24
-rwxr-xr-xhercules/convert_server_to_client.py21
-rwxr-xr-xhercules/convert_tmx_to_mapcache.py9
-rwxr-xr-xhercules/extract_mapcache.py24
l---------hercules/extractmaps.py1
l---------hercules/homunculusestoxml.py1
l---------hercules/itemstoxml.py1
-rwxr-xr-xhercules/list_mapcache.py24
l---------hercules/listmaps.py1
l---------hercules/mapstotmx.py1
-rwxr-xr-xhercules/maptool.py641
l---------hercules/mercenariestoxml.py1
l---------hercules/monsterstoxml.py1
l---------hercules/petstoxml.py1
l---------hercules/queststoxml.py1
l---------hercules/skillstoxml.py1
l---------hercules/tmxtocache.py1
35 files changed, 756 insertions, 653 deletions
diff --git a/hercules/.gitignore b/hercules/.gitignore
index 8eb80be..96ea0f2 100644
--- a/hercules/.gitignore
+++ b/hercules/.gitignore
@@ -1,4 +1,6 @@
clientdata
maps
serverdata
-mapcache \ No newline at end of file
+mapcache
+
+*.pyc
diff --git a/hercules/code/__init__.py b/hercules/code/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/hercules/code/__init__.py
diff --git a/hercules/code/clienttoserver/__init__.py b/hercules/code/clienttoserver/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/hercules/code/clienttoserver/__init__.py
diff --git a/hercules/code/clienttoserver/maps.py b/hercules/code/clienttoserver/maps.py
new file mode 100644
index 0000000..a401cd3
--- /dev/null
+++ b/hercules/code/clienttoserver/maps.py
@@ -0,0 +1,96 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import array
+import os
+import zlib
+import struct
+from xml.dom import minidom
+
+from code.fileutils import *
+
+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
+ sz = sz + 8
+ 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 + 12 + 8 + len(binData)
+ break
+ w.seek(0);
+ writeInt32(w, sz)
+ writeInt16(w, mapsCount)
diff --git a/hercules/code/fileutils.py b/hercules/code/fileutils.py
new file mode 100644
index 0000000..150cb8c
--- /dev/null
+++ b/hercules/code/fileutils.py
@@ -0,0 +1,62 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import array
+import os
+import struct
+import shutil
+
+def readInt32(f):
+ data = f.read(4)
+ arr = array.array("I")
+ arr.fromstring(data)
+ return arr[0]
+
+def readInt16(f):
+ data = f.read(2)
+ arr = array.array("H")
+ arr.fromstring(data)
+ return arr[0]
+
+def readMapName(f):
+ data = f.read(12)
+ data = str(data)
+ while data[-1] == '\x00':
+ data = data[:-1]
+ return data
+
+def readData(f, sz):
+ return f.read(sz)
+
+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 copyFile(src, dst, name):
+ shutil.copyfile(src + name, dst + name)
+
+def saveFile(fileName, data):
+ with open(fileName, "w") as w:
+ w.write(data)
+
+def makeDir(path):
+ if not os.path.exists(path):
+ os.makedirs(path)
diff --git a/hercules/code/server/__init__.py b/hercules/code/server/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/hercules/code/server/__init__.py
diff --git a/hercules/code/server/maps.py b/hercules/code/server/maps.py
new file mode 100644
index 0000000..2de4bfa
--- /dev/null
+++ b/hercules/code/server/maps.py
@@ -0,0 +1,35 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import zlib
+
+from code.fileutils import *
+
+def listMapCache(f, mapsCount):
+ print "Known maps:"
+ print "{0:12} {1:<4}x {2:<4} {3:<10}".format("Map name", "sx", "sy", "compressed size")
+ for i in xrange(0, mapsCount):
+ name = readMapName(f)
+ sx = readInt16(f)
+ sy = readInt16(f)
+ sz = readInt32(f)
+ print "{0:12} {1:<4}x {2:<4} {3:<10}".format(name, sx, sy, sz)
+ f.seek(sz, 1)
+
+def extractMaps(f, mapsCount):
+ destDir = "maps/"
+ makeDir(destDir)
+ for i in xrange(0, mapsCount):
+ name = readMapName(f)
+ sx = readInt16(f)
+ sy = readInt16(f)
+ sz = readInt32(f)
+ data = readData(f, sz)
+ dc = zlib.decompressobj()
+ data = dc.decompress(data)
+ with open(destDir + name, "wb") as w:
+ w.write(struct.pack("H", sx))
+ w.write(struct.pack("H", sy))
+ w.write(data)
diff --git a/hercules/code/servertoclient/__init__.py b/hercules/code/servertoclient/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/hercules/code/servertoclient/__init__.py
diff --git a/hercules/code/servertoclient/homunculuses.py b/hercules/code/servertoclient/homunculuses.py
new file mode 100644
index 0000000..96c133b
--- /dev/null
+++ b/hercules/code/servertoclient/homunculuses.py
@@ -0,0 +1,29 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import re
+
+from code.fileutils import *
+
+def convertHomunculuses():
+ destDir = "clientdata/"
+ templatesDir = "templates/"
+ homunculusesDbFile = "serverdata/db/re/homunculus_db.txt"
+ fieldsSplit = re.compile(",")
+ makeDir(destDir)
+ tpl = readFile(templatesDir + "homunculus.tpl")
+ homunculuses = readFile(templatesDir + "homunculuses.xml")
+ data = ""
+ homunculusSprite = "<sprite>monsters/tortuga.xml</sprite>";
+ with open(homunculusesDbFile, "r") as f:
+ for line in f:
+ if line == "" or line[0:2] == "//":
+ continue
+ rows = fieldsSplit.split(line)
+ if len(rows) < 9:
+ continue
+ homunculusId = rows[0]
+ data = data + tpl.format(homunculusId, homunculusSprite)
+ saveFile(destDir + "homunculuses.xml", homunculuses.format(data))
diff --git a/hercules/code/servertoclient/items.py b/hercules/code/servertoclient/items.py
new file mode 100644
index 0000000..9acb581
--- /dev/null
+++ b/hercules/code/servertoclient/items.py
@@ -0,0 +1,138 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import re
+from sets import Set
+
+from code.fileutils import *
+from code.stringutils import *
+
+def prepStat(val, text):
+ if val != "0" and val != "":
+ return " {0}=\"{1}\"\n".format(text, val)
+ return ""
+
+def convertItems():
+ destDir = "clientdata/"
+ templatesDir = "templates/"
+ itemsDbFile = "serverdata/sql-files/item_db_re.sql"
+ fieldsSplit = re.compile(",")
+ bracketsSplit = re.compile("[(]|[)]")
+ makeDir(destDir)
+ tpl = readFile(templatesDir + "item.tpl")
+ items = readFile(templatesDir + "items.xml")
+ data = ""
+ ids = Set()
+ with open(itemsDbFile, "r") as f:
+ for line in f:
+ if len(line) < 10 or line[0:2] == "//" or line[0:12] != "REPLACE INTO":
+ continue
+ rows = bracketsSplit.split(line)
+ if len(rows) < 2:
+ continue
+ rows = fieldsSplit.split(rows[1])
+ if len(rows) < 31:
+ continue
+ rows = stripQuotes2(rows)
+ itemId = rows[0]
+ name = rows[1]
+ name2 = rows[2]
+ itemType = rows[3]
+ priceBuy = rows[4]
+ priceSell = rows[5]
+ weight = rows[6]
+ atk = rows[7]
+ matk = rows[8]
+ defence = rows[9]
+ attackRange = rows[10]
+ slots = rows[11]
+ equipJobs = rows[12]
+ equipUpper = rows[12]
+ equipGender = rows[14]
+ equipLocations = rows[15]
+ weaponLevel = rows[16]
+ equipLevelMin = rows[17]
+ equipLevelMax = rows[18]
+ refinable = rows[19]
+ view = rows[20]
+ bindOnEquip = rows[21]
+ buyInStore = rows[22]
+ delay = rows[23]
+ tradeFlag = rows[24]
+ tradeGroup = rows[25]
+ nouseFlag = rows[26]
+ nouseGroup = rows[27]
+ stackAmount = rows[28]
+ stackFlag = rows[29]
+ sprite = rows[30]
+
+ name = name.replace("\\'", "'")
+ image = ""
+
+ statStr = prepStat(atk, "attack")
+ statStr = statStr + prepStat(matk, "mattack")
+ statStr = statStr + prepStat(defence, "defence")
+ statStr = statStr + prepStat(weight, "weight")
+ statStr = statStr + prepStat(attackRange, "range")
+ statStr = statStr + prepStat(delay, "speed")
+# print itemId + "," + equipLocations
+# typeStr = "other"
+ typeStr = "equip-legs"
+ spriteStr = "equipment/legs/trousers-male.xml"
+ image = "generic/box-fish.png"
+ if itemType == 0 or itemType == 2 or itemType == 18: # usable
+ image = "usable/bread.png"
+ typeStr = "usable"
+ spriteStr = "";
+ elif equipLocations == "0":
+ image = "usable/bread.png"
+ typeStr = "usable"
+ spriteStr = "";
+ elif equipLocations == "1":
+ image = "equipment/legs/shorts.png|S:#4d4d4d,514d47,686868,706662,919191,99917b,b6b6b6,c0b698,dfdfdf,e4dfca"
+ typeStr = "equip-legs"
+ spriteStr = "equipment/legs/shorts-male.xml|#4d4d4d,514d47,686868,706662,919191,99917b,b6b6b6,c0b698,dfdfdf,e0d5bf";
+ elif equipLocations == "2":
+ image = "equipment/weapons/knife.png"
+ typeStr = "equip-1hand"
+ spriteStr = "equipment/weapons/knife.xml";
+ elif equipLocations == "4":
+ image = "equipment/hands/armbands.png"
+ typeStr = "equip-arms"
+ spriteStr = "equipment/hands/armbands-male.xml";
+ elif equipLocations == "16":
+ image = "equipment/chest/cottonshirt.png|S:#3c3c3c,3e3c38,4d4d4d,514d47,686868,706662,919191,99917b,b6b6b6,c0b698,dfdfdf,e4dfca"
+ typeStr = "equip-torso"
+ spriteStr = "equipment/chest/cottonshirt-male.xml|#43413d,59544f,7a706c,8a8176,a69e88,d1c7a7,e0d5bf";
+ elif equipLocations == "64":
+ image = "equipment/feet/boots.png|S:#3c3c3c,40332d,4d4d4d,5e4a3d,686868,705740,919191,a1825d,b6b6b6,b59767,dfdfdf,dbbf88"
+ typeStr = "equip-feet"
+ spriteStr = "equipment/feet/boots-male.xml|#40332d,5e4a3d,705740,a1825d,b59767,dbbf88";
+ elif equipLocations == "136":
+ image = "equipment/chest/cottonshirt.png|S:#3c3c3c,3e3c38,4d4d4d,514d47,686868,706662,919191,99917b,b6b6b6,c0b698,dfdfdf,e4dfca"
+ typeStr = "equip-torso"
+ spriteStr = "equipment/chest/cottonshirt-male.xml|#43413d,59544f,7a706c,8a8176,a69e88,d1c7a7,e0d5bf";
+ elif equipLocations == "256":
+ image = "equipment/head/bandana.png"
+ typeStr = "equip-head"
+ spriteStr = "equipment/head/bandana-male.xml";
+ elif equipLocations == "512":
+ # no sprites in evol
+ image = "equipment/chest/sailorshirt.png"
+ typeStr = "equip-torso"
+ spriteStr = "equipment/chest/shirt-male.xml|#131913,1b231d,233129,35433e,4e6059,6c8279;#72571e,836737,a5854d,b18f45";
+
+ name = strToXml(name);
+
+ if itemId not in ids:
+ ids.add(itemId)
+ data = data + tpl.format(itemId, name, 0,
+ statStr, image, typeStr, spriteStr)
+ if view != "0" and view not in ids:
+ ids.add(view)
+ data = data + tpl.format(view, name, 0,
+ statStr, image, typeStr, spriteStr)
+
+ saveFile(destDir + "items.xml", items.format(data))
diff --git a/hercules/code/servertoclient/maps.py b/hercules/code/servertoclient/maps.py
new file mode 100644
index 0000000..e0a7641
--- /dev/null
+++ b/hercules/code/servertoclient/maps.py
@@ -0,0 +1,48 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import zlib
+
+from code.fileutils import *
+from code.tileutils import *
+
+def covertToTmx(f, mapsCount):
+ destDir = "clientdata/"
+ mapsDir = destDir + "maps/"
+ tilesetsDir = destDir + "graphics/tilesets/"
+ templatesDir = "templates/"
+ makeDir(mapsDir)
+ makeDir(tilesetsDir)
+ copyFile(templatesDir, tilesetsDir, "collision.png")
+ copyFile(templatesDir, tilesetsDir, "tileset.png")
+ tmx = readFile("templates/template.tmx")
+ for i in xrange(0, mapsCount):
+ name = readMapName(f)
+ print "converting map [{0:4}/{1:4}]: {2}".format(i, mapsCount + 1, name)
+ sx = readInt16(f)
+ sy = readInt16(f)
+ sz = readInt32(f)
+ mapData = readData(f, sz)
+ dc = zlib.decompressobj()
+ mapData = dc.decompress(mapData)
+ ground = ""
+ collision = ""
+ fringe = ""
+ for y in xrange(0, sy):
+ for x in xrange(0, sx):
+ tileData = getTileData(mapData, x, y, sx)
+ tile = getTile(tileData)
+ if x + 1 == sx and y + 1 == sy:
+ ground = ground + tile[0]
+ collision = collision + tile[1]
+ fringe = fringe + "0";
+ else:
+ ground = ground + tile[0] + ","
+ collision = collision + tile[1] + ","
+ fringe = fringe + "0,";
+ ground = ground + "\n"
+ collision = collision + "\n"
+ fringe = fringe + "\n"
+ saveFile(mapsDir + name + ".tmx", tmx.format(sx, sy, ground, collision, fringe))
diff --git a/hercules/code/servertoclient/mercenaries.py b/hercules/code/servertoclient/mercenaries.py
new file mode 100644
index 0000000..2b8c5f3
--- /dev/null
+++ b/hercules/code/servertoclient/mercenaries.py
@@ -0,0 +1,29 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import re
+
+from code.fileutils import *
+
+def convertMercenaries():
+ destDir = "clientdata/"
+ templatesDir = "templates/"
+ mercenariesDbFile = "serverdata/db/mercenary_db.txt"
+ fieldsSplit = re.compile(",")
+ makeDir(destDir)
+ tpl = readFile(templatesDir + "mercenary.tpl")
+ mercenaries = readFile(templatesDir + "mercenaries.xml")
+ data = ""
+ mercenarySprite = "<sprite>monsters/croc.xml</sprite>";
+ with open(mercenariesDbFile, "r") as f:
+ for line in f:
+ if line == "" or line[0:2] == "//":
+ continue
+ rows = fieldsSplit.split(line)
+ if len(rows) < 9:
+ continue
+ mercenaryId = rows[0]
+ data = data + tpl.format(mercenaryId, mercenarySprite)
+ saveFile(destDir + "mercenaries.xml", mercenaries.format(data))
diff --git a/hercules/code/servertoclient/monsters.py b/hercules/code/servertoclient/monsters.py
new file mode 100644
index 0000000..d08ce66
--- /dev/null
+++ b/hercules/code/servertoclient/monsters.py
@@ -0,0 +1,39 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import re
+from sets import Set
+
+from code.fileutils import *
+from code.stringutils import *
+
+def convertMonsters():
+ destDir = "clientdata/"
+ templatesDir = "templates/"
+ monstersDbFile = "serverdata/sql-files/mob_db_re.sql"
+ fieldsSplit = re.compile(",")
+ bracketsSplit = re.compile("[(]|[)]")
+ makeDir(destDir)
+ tpl = readFile(templatesDir + "monster.tpl")
+ monsters = readFile(templatesDir + "monsters.xml")
+ data = ""
+ ids = Set()
+ monsterSprite = """<sprite>monsters/blub.xml</sprite>
+ <sprite>accessories/blub-tentacle.xml|#3e4164,3a3968,544a82,64437a,7d6db4,a26392,8f99c4,d294ab,b3cdcd,e7b8b8,d9ecd1,f0e8c5</sprite>""";
+ with open(monstersDbFile, "r") as f:
+ for line in f:
+ if len(line) < 10 or line[0:2] == "//" or line[0:12] != "REPLACE INTO":
+ continue
+ rows = bracketsSplit.split(line)
+ if len(rows) < 2:
+ continue
+ rows = fieldsSplit.split(rows[1])
+ if len(rows) < 5:
+ continue
+ monsterId = rows[0]
+ name = strToXml(stripQuotes(rows[2]))
+ data = data + tpl.format(monsterId, name, monsterSprite)
+
+ saveFile(destDir + "monsters.xml", monsters.format(data))
diff --git a/hercules/code/servertoclient/pets.py b/hercules/code/servertoclient/pets.py
new file mode 100644
index 0000000..fa1219b
--- /dev/null
+++ b/hercules/code/servertoclient/pets.py
@@ -0,0 +1,29 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import re
+
+from code.fileutils import *
+
+def convertPets():
+ destDir = "clientdata/"
+ templatesDir = "templates/"
+ petsDbFile = "serverdata/db/pet_db.txt"
+ fieldsSplit = re.compile(",")
+ makeDir(destDir)
+ tpl = readFile(templatesDir + "pet.tpl")
+ pets = readFile(templatesDir + "pets.xml")
+ data = ""
+ petSprite = "<sprite>monsters/tortuga.xml</sprite>";
+ with open(petsDbFile, "r") as f:
+ for line in f:
+ if line == "" or line[0:2] == "//":
+ continue
+ rows = fieldsSplit.split(line)
+ if len(rows) < 9:
+ continue
+ petId = rows[0]
+ data = data + tpl.format(petId, petSprite)
+ saveFile(destDir + "pets.xml", pets.format(data))
diff --git a/hercules/code/servertoclient/quests.py b/hercules/code/servertoclient/quests.py
new file mode 100644
index 0000000..6243ae9
--- /dev/null
+++ b/hercules/code/servertoclient/quests.py
@@ -0,0 +1,37 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import re
+
+from code.fileutils import *
+from code.stringutils import *
+
+def convertQuests():
+ destDir = "clientdata/"
+ templatesDir = "templates/"
+ questsDbFile = "serverdata/db/quest_db.txt"
+ fieldsSplit = re.compile(",")
+ makeDir(destDir)
+ tpl = readFile(templatesDir + "quest.tpl")
+ quests = readFile(templatesDir + "quests.xml")
+ data = ""
+ with open(questsDbFile, "r") as f:
+ for line in f:
+ if line == "" or line[0:2] == "//":
+ continue
+ rows = fieldsSplit.split(line)
+ if len(rows) < 9:
+ continue
+ questId = rows[0]
+ text = rows[8]
+ if text[-1] == "\n":
+ text = text[:-1]
+ text = strToXml(stripQuotes(text))
+ name = text
+ if len(name) > 20:
+ name = name[:19]
+
+ data = data + tpl.format(questId, name, text + ": " + str(questId))
+ saveFile(destDir + "quests.xml", quests.format(data))
diff --git a/hercules/code/servertoclient/skills.py b/hercules/code/servertoclient/skills.py
new file mode 100644
index 0000000..022e874
--- /dev/null
+++ b/hercules/code/servertoclient/skills.py
@@ -0,0 +1,33 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import re
+
+from code.fileutils import *
+
+def convertSkillsToXml():
+ destDir = "clientdata/"
+ templatesDir = "templates/"
+ skillsDbFile = "serverdata/db/re/skill_db.txt"
+ fieldsSplit = re.compile(",")
+ makeDir(destDir)
+ tpl = readFile(templatesDir + "skill.tpl")
+ skills = readFile(templatesDir + "skills.xml")
+ data = ""
+ with open(skillsDbFile, "r") as f:
+ for line in f:
+ if line == "" or line[0:2] == "//":
+ continue
+ rows = fieldsSplit.split(line)
+ if len(rows) < 9:
+ continue
+ skillId = rows[0]
+ name = rows[15].strip()
+ description = rows[16].strip()
+ idx = description.find ("//")
+ if idx > 1:
+ description = description[:idx]
+ data = data + tpl.format(skillId, name, description)
+ saveFile(destDir + "skills.xml", skills.format(data))
diff --git a/hercules/code/stringutils.py b/hercules/code/stringutils.py
new file mode 100644
index 0000000..09e3cf8
--- /dev/null
+++ b/hercules/code/stringutils.py
@@ -0,0 +1,28 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+def stripQuotes(data):
+ if len(data) == 0:
+ return data
+ if data[-1] == "\"":
+ data = data[:-1]
+ if data[0] == "\"":
+ data = data[1:]
+ if data[-1] == "'":
+ data = data[:-1]
+ if data[0] == "'":
+ data = data[1:]
+ return data
+
+def stripQuotes2(data):
+ for idx in xrange(0, len(data)):
+ data[idx] = stripQuotes(data[idx])
+ return data
+
+def strToXml(data):
+ data = data.replace("&", "&amp;");
+ data = data.replace("<", "&lt;");
+ data = data.replace(">", "&gt;");
+ return data
diff --git a/hercules/code/tileutils.py b/hercules/code/tileutils.py
new file mode 100644
index 0000000..c5457e7
--- /dev/null
+++ b/hercules/code/tileutils.py
@@ -0,0 +1,48 @@
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import array
+
+def getTileData(mapData, x, y, sx):
+ data = mapData[y * sx + x]
+ arr = array.array("B")
+ arr.fromstring(data)
+ data = arr[0]
+ return data
+
+def getTile(data):
+ normal = 0
+ collison = 0
+ if data == 0: # 000 normal walkable
+ normal = 1
+ collision = 5
+ elif data == 1: # 001 non walkable
+ normal = 2
+ collision = 6
+ elif data == 2: # 010 same with 0
+ normal = 1
+ collision = 5
+ elif data == 3: # 011 same with 0, but water
+ normal = 3
+ collision = 5
+ elif data == 4: # 100 same with 0
+ normal = 1
+ collision = 5
+ elif data == 5: # 101 same with 1, but shootable (for now not supported!!!)
+ normal = 4
+ collision = 6
+ elif data == 6: # 110 same with 0
+ normal = 1
+ collision = 5
+ return (str(normal), str(collision))
+
+def getGroundTile(flag):
+ return str(flag + 1)
+
+def getCollisionTile(flag):
+ if flag == 0:
+ return "0"
+ return "4"
+
diff --git a/hercules/convert_mapcache_to_tmx.py b/hercules/convert_mapcache_to_tmx.py
new file mode 100755
index 0000000..bcc50ac
--- /dev/null
+++ b/hercules/convert_mapcache_to_tmx.py
@@ -0,0 +1,24 @@
+#! /usr/bin/env python
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import os
+
+from code.fileutils import *
+from code.servertoclient.maps import *
+
+def runFunction(path):
+ with open(path, "rb") as f:
+ size = readInt32(f)
+ if os.path.getsize(path) != size:
+ print "Map cache corrupted, wrong file size."
+ exit(1)
+ mapsCount = readInt16(f)
+ print "Maps count: " + str(mapsCount)
+ readInt16(f) # padding
+ covertToTmx(f, mapsCount)
+
+
+runFunction("serverdata/db/re/map_cache.dat")
diff --git a/hercules/convert_server_to_client.py b/hercules/convert_server_to_client.py
new file mode 100755
index 0000000..379a292
--- /dev/null
+++ b/hercules/convert_server_to_client.py
@@ -0,0 +1,21 @@
+#! /usr/bin/env python
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+from code.servertoclient.homunculuses import *
+from code.servertoclient.items import *
+from code.servertoclient.mercenaries import *
+from code.servertoclient.monsters import *
+from code.servertoclient.pets import *
+from code.servertoclient.quests import *
+from code.servertoclient.skills import *
+
+convertHomunculuses();
+convertItems()
+convertMercenaries();
+convertMonsters();
+convertPets();
+convertSkillsToXml();
+convertQuests()
diff --git a/hercules/convert_tmx_to_mapcache.py b/hercules/convert_tmx_to_mapcache.py
new file mode 100755
index 0000000..a41816b
--- /dev/null
+++ b/hercules/convert_tmx_to_mapcache.py
@@ -0,0 +1,9 @@
+#! /usr/bin/env python
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+from code.clienttoserver.maps import *
+
+recreateMapCache();
diff --git a/hercules/extract_mapcache.py b/hercules/extract_mapcache.py
new file mode 100755
index 0000000..fc82404
--- /dev/null
+++ b/hercules/extract_mapcache.py
@@ -0,0 +1,24 @@
+#! /usr/bin/env python
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import os
+
+from code.fileutils import *
+from code.server.maps import *
+
+
+def runFunction(path):
+ with open(path, "rb") as f:
+ size = readInt32(f)
+ if os.path.getsize(path) != size:
+ print "Map cache corrupted, wrong file size."
+ exit(1)
+ mapsCount = readInt16(f)
+ print "Maps count: " + str(mapsCount)
+ readInt16(f) # padding
+ extractMaps(f, mapsCount)
+
+runFunction("serverdata/db/re/map_cache.dat")
diff --git a/hercules/extractmaps.py b/hercules/extractmaps.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/extractmaps.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/homunculusestoxml.py b/hercules/homunculusestoxml.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/homunculusestoxml.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/itemstoxml.py b/hercules/itemstoxml.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/itemstoxml.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/list_mapcache.py b/hercules/list_mapcache.py
new file mode 100755
index 0000000..79a7910
--- /dev/null
+++ b/hercules/list_mapcache.py
@@ -0,0 +1,24 @@
+#! /usr/bin/env python
+# -*- coding: utf8 -*-
+#
+# Copyright (C) 2014 Evol Online
+# Author: Andrei Karas (4144)
+
+import os
+
+from code.fileutils import *
+from code.server.maps import *
+
+def runFunction(path):
+ with open(path, "rb") as f:
+ size = readInt32(f)
+ if os.path.getsize(path) != size:
+ print "Map cache corrupted, wrong file size."
+ exit(1)
+ mapsCount = readInt16(f)
+ print "Maps count: " + str(mapsCount)
+ readInt16(f) # padding
+ listMapCache(f, mapsCount)
+
+
+runFunction("serverdata/db/re/map_cache.dat")
diff --git a/hercules/listmaps.py b/hercules/listmaps.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/listmaps.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/mapstotmx.py b/hercules/mapstotmx.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/mapstotmx.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/maptool.py b/hercules/maptool.py
deleted file mode 100755
index 3b30d61..0000000
--- a/hercules/maptool.py
+++ /dev/null
@@ -1,641 +0,0 @@
-#! /usr/bin/env python
-# -*- coding: utf8 -*-
-#
-# Copyright (C) 2014 Evol Online
-# Author: Andrei Karas (4144)
-
-import array
-import base64
-import gzip
-import os
-import re
-import datetime
-import xml
-import csv
-import ogg.vorbis
-import StringIO
-import sys
-import zlib
-import struct
-import shutil
-from sets import Set
-from xml.dom import minidom
-
-def detectCommand():
- if sys.argv[0][-12:] == "/listmaps.py":
- return "listmaps"
- elif sys.argv[0][-15:] == "/extractmaps.py":
- return "extractmaps"
- elif sys.argv[0][-13:] == "/mapstotmx.py":
- return "mapstotmx"
- elif sys.argv[0][-15:] == "/queststoxml.py":
- return "queststoxml"
- elif sys.argv[0][-14:] == "/itemstoxml.py":
- return "itemstoxml"
- elif sys.argv[0][-17:] == "/monsterstoxml.py":
- return "monsterstoxml"
- elif sys.argv[0][-20:] == "/mercenariestoxml.py":
- return "mercenariestoxml"
- elif sys.argv[0][-13:] == "/petstoxml.py":
- return "petstoxml"
- elif sys.argv[0][-21:] == "/homunculusestoxml.py":
- 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):
- if not os.path.exists(path):
- os.makedirs(path)
-
-def readInt32(f):
- data = f.read(4)
- arr = array.array("I")
- arr.fromstring(data)
- return arr[0]
-
-def readInt16(f):
- data = f.read(2)
- arr = array.array("H")
- arr.fromstring(data)
- return arr[0]
-
-def readMapName(f):
- data = f.read(12)
- data = str(data)
- while data[-1] == '\x00':
- data = data[:-1]
- return data
-
-def readData(f, sz):
- return f.read(sz)
-
-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")
- arr.fromstring(data)
- data = arr[0]
- return data
-
-def getTile(data):
- normal = 0
- collison = 0
- if data == 0: # 000 normal walkable
- normal = 1
- collision = 5
- elif data == 1: # 001 non walkable
- normal = 2
- collision = 6
- elif data == 2: # 010 same with 0
- normal = 1
- collision = 5
- elif data == 3: # 011 same with 0, but water
- normal = 3
- collision = 5
- elif data == 4: # 100 same with 0
- normal = 1
- collision = 5
- elif data == 5: # 101 same with 1, but shootable (for now not supported!!!)
- normal = 4
- collision = 6
- elif data == 6: # 110 same with 0
- normal = 1
- collision = 5
- return (str(normal), str(collision))
-
-def getGroundTile(flag):
- return str(flag + 1)
-
-def getCollisionTile(flag):
- if flag == 0:
- return "0"
- return "4"
-
-def copyFile(src, dst, name):
- shutil.copyfile(src + name, dst + name)
-
-def saveFile(fileName, data):
- with open(fileName, "w") as w:
- w.write(data)
-
-def stripQuotes(data):
- if len(data) == 0:
- return data
- if data[-1] == "\"":
- data = data[:-1]
- if data[0] == "\"":
- data = data[1:]
- if data[-1] == "'":
- data = data[:-1]
- if data[0] == "'":
- data = data[1:]
- return data
-
-def stripQuotes2(data):
- for idx in xrange(0, len(data)):
- data[idx] = stripQuotes(data[idx])
- return data
-
-def strToXml(data):
- data = data.replace("&", "&amp;");
- data = data.replace("<", "&lt;");
- data = data.replace(">", "&gt;");
- return data
-
-def printHelp():
- print "Unknown options selected."
- print ""
- print "Use list.py for list maps in cache"
- print "Use extract.py to extract maps from cache"
- exit(0)
-
-def listMapCache(f, mapsCount):
- print "Known maps:"
- print "{0:12} {1:<4}x {2:<4} {3:<10}".format("Map name", "sx", "sy", "compressed size")
- for i in xrange(0, mapsCount):
- name = readMapName(f)
- sx = readInt16(f)
- sy = readInt16(f)
- sz = readInt32(f)
- print "{0:12} {1:<4}x {2:<4} {3:<10}".format(name, sx, sy, sz)
- f.seek(sz, 1)
-
-def extractMaps(f, mapsCount):
- destDir = "maps/"
- makeDir(destDir)
- for i in xrange(0, mapsCount):
- name = readMapName(f)
- sx = readInt16(f)
- sy = readInt16(f)
- sz = readInt32(f)
- data = readData(f, sz)
- dc = zlib.decompressobj()
- data = dc.decompress(data)
- with open(destDir + name, "wb") as w:
- w.write(struct.pack("H", sx))
- w.write(struct.pack("H", sy))
- w.write(data)
-
-def covertToTmx(f, mapsCount):
- destDir = "clientdata/"
- mapsDir = destDir + "maps/"
- tilesetsDir = destDir + "graphics/tilesets/"
- templatesDir = "templates/"
- makeDir(mapsDir)
- makeDir(tilesetsDir)
- copyFile(templatesDir, tilesetsDir, "collision.png")
- copyFile(templatesDir, tilesetsDir, "tileset.png")
- tmx = readFile("templates/template.tmx")
- for i in xrange(0, mapsCount):
- name = readMapName(f)
- print "converting map [{0:4}/{1:4}]: {2}".format(i, mapsCount + 1, name)
- sx = readInt16(f)
- sy = readInt16(f)
- sz = readInt32(f)
- mapData = readData(f, sz)
- dc = zlib.decompressobj()
- mapData = dc.decompress(mapData)
- ground = ""
- collision = ""
- fringe = ""
- for y in xrange(0, sy):
- for x in xrange(0, sx):
- tileData = getTileData(mapData, x, y, sx)
- tile = getTile(tileData)
- if x + 1 == sx and y + 1 == sy:
- ground = ground + tile[0]
- collision = collision + tile[1]
- fringe = fringe + "0";
- else:
- ground = ground + tile[0] + ","
- collision = collision + tile[1] + ","
- fringe = fringe + "0,";
- ground = ground + "\n"
- collision = collision + "\n"
- fringe = fringe + "\n"
- saveFile(mapsDir + name + ".tmx", tmx.format(sx, sy, ground, collision, fringe))
-
-def covertQuests():
- destDir = "clientdata/"
- templatesDir = "templates/"
- questsDbFile = "serverdata/db/quest_db.txt"
- fieldsSplit = re.compile(",")
- makeDir(destDir)
- tpl = readFile(templatesDir + "quest.tpl")
- quests = readFile(templatesDir + "quests.xml")
- data = ""
- with open(questsDbFile, "r") as f:
- for line in f:
- if line == "" or line[0:2] == "//":
- continue
- rows = fieldsSplit.split(line)
- if len(rows) < 9:
- continue
- questId = rows[0]
- text = rows[8]
- if text[-1] == "\n":
- text = text[:-1]
- text = strToXml(stripQuotes(text))
- name = text
- if len(name) > 20:
- name = name[:19]
-
- data = data + tpl.format(questId, name, text + ": " + str(questId))
- saveFile(destDir + "quests.xml", quests.format(data))
-
-def prepStat(val, text):
- if val != "0" and val != "":
- return " {0}=\"{1}\"\n".format(text, val)
- return ""
-
-def convertItems():
- destDir = "clientdata/"
- templatesDir = "templates/"
- itemsDbFile = "serverdata/sql-files/item_db_re.sql"
- fieldsSplit = re.compile(",")
- bracketsSplit = re.compile("[(]|[)]")
- makeDir(destDir)
- tpl = readFile(templatesDir + "item.tpl")
- items = readFile(templatesDir + "items.xml")
- data = ""
- ids = Set()
- with open(itemsDbFile, "r") as f:
- for line in f:
- if len(line) < 10 or line[0:2] == "//" or line[0:12] != "REPLACE INTO":
- continue
- rows = bracketsSplit.split(line)
- if len(rows) < 2:
- continue
- rows = fieldsSplit.split(rows[1])
- if len(rows) < 31:
- continue
- rows = stripQuotes2(rows)
- itemId = rows[0]
- name = rows[1]
- name2 = rows[2]
- itemType = rows[3]
- priceBuy = rows[4]
- priceSell = rows[5]
- weight = rows[6]
- atk = rows[7]
- matk = rows[8]
- defence = rows[9]
- attackRange = rows[10]
- slots = rows[11]
- equipJobs = rows[12]
- equipUpper = rows[12]
- equipGender = rows[14]
- equipLocations = rows[15]
- weaponLevel = rows[16]
- equipLevelMin = rows[17]
- equipLevelMax = rows[18]
- refinable = rows[19]
- view = rows[20]
- bindOnEquip = rows[21]
- buyInStore = rows[22]
- delay = rows[23]
- tradeFlag = rows[24]
- tradeGroup = rows[25]
- nouseFlag = rows[26]
- nouseGroup = rows[27]
- stackAmount = rows[28]
- stackFlag = rows[29]
- sprite = rows[30]
-
- name = name.replace("\\'", "'")
- image = ""
-
- statStr = prepStat(atk, "attack")
- statStr = statStr + prepStat(matk, "mattack")
- statStr = statStr + prepStat(defence, "defence")
- statStr = statStr + prepStat(weight, "weight")
- statStr = statStr + prepStat(attackRange, "range")
- statStr = statStr + prepStat(delay, "speed")
-# print itemId + "," + equipLocations
-# typeStr = "other"
- typeStr = "equip-legs"
- spriteStr = "equipment/legs/trousers-male.xml"
- image = "generic/box-fish.png"
- if itemType == 0 or itemType == 2 or itemType == 18: # usable
- image = "usable/bread.png"
- typeStr = "usable"
- spriteStr = "";
- elif equipLocations == "0":
- image = "usable/bread.png"
- typeStr = "usable"
- spriteStr = "";
- elif equipLocations == "1":
- image = "equipment/legs/shorts.png|S:#4d4d4d,514d47,686868,706662,919191,99917b,b6b6b6,c0b698,dfdfdf,e4dfca"
- typeStr = "equip-legs"
- spriteStr = "equipment/legs/shorts-male.xml|#4d4d4d,514d47,686868,706662,919191,99917b,b6b6b6,c0b698,dfdfdf,e0d5bf";
- elif equipLocations == "2":
- image = "equipment/weapons/knife.png"
- typeStr = "equip-1hand"
- spriteStr = "equipment/weapons/knife.xml";
- elif equipLocations == "4":
- image = "equipment/hands/armbands.png"
- typeStr = "equip-arms"
- spriteStr = "equipment/hands/armbands-male.xml";
- elif equipLocations == "16":
- image = "equipment/chest/cottonshirt.png|S:#3c3c3c,3e3c38,4d4d4d,514d47,686868,706662,919191,99917b,b6b6b6,c0b698,dfdfdf,e4dfca"
- typeStr = "equip-torso"
- spriteStr = "equipment/chest/cottonshirt-male.xml|#43413d,59544f,7a706c,8a8176,a69e88,d1c7a7,e0d5bf";
- elif equipLocations == "64":
- image = "equipment/feet/boots.png|S:#3c3c3c,40332d,4d4d4d,5e4a3d,686868,705740,919191,a1825d,b6b6b6,b59767,dfdfdf,dbbf88"
- typeStr = "equip-feet"
- spriteStr = "equipment/feet/boots-male.xml|#40332d,5e4a3d,705740,a1825d,b59767,dbbf88";
- elif equipLocations == "136":
- image = "equipment/chest/cottonshirt.png|S:#3c3c3c,3e3c38,4d4d4d,514d47,686868,706662,919191,99917b,b6b6b6,c0b698,dfdfdf,e4dfca"
- typeStr = "equip-torso"
- spriteStr = "equipment/chest/cottonshirt-male.xml|#43413d,59544f,7a706c,8a8176,a69e88,d1c7a7,e0d5bf";
- elif equipLocations == "256":
- image = "equipment/head/bandana.png"
- typeStr = "equip-head"
- spriteStr = "equipment/head/bandana-male.xml";
- elif equipLocations == "512":
- # no sprites in evol
- image = "equipment/chest/sailorshirt.png"
- typeStr = "equip-torso"
- spriteStr = "equipment/chest/shirt-male.xml|#131913,1b231d,233129,35433e,4e6059,6c8279;#72571e,836737,a5854d,b18f45";
-
- name = strToXml(name);
-
- if itemId not in ids:
- ids.add(itemId)
- data = data + tpl.format(itemId, name, 0,
- statStr, image, typeStr, spriteStr)
- if view != "0" and view not in ids:
- ids.add(view)
- data = data + tpl.format(view, name, 0,
- statStr, image, typeStr, spriteStr)
-
- saveFile(destDir + "items.xml", items.format(data))
-
-def convertMonsters():
- destDir = "clientdata/"
- templatesDir = "templates/"
- monstersDbFile = "serverdata/sql-files/mob_db_re.sql"
- fieldsSplit = re.compile(",")
- bracketsSplit = re.compile("[(]|[)]")
- makeDir(destDir)
- tpl = readFile(templatesDir + "monster.tpl")
- monsters = readFile(templatesDir + "monsters.xml")
- data = ""
- ids = Set()
- monsterSprite = """<sprite>monsters/blub.xml</sprite>
- <sprite>accessories/blub-tentacle.xml|#3e4164,3a3968,544a82,64437a,7d6db4,a26392,8f99c4,d294ab,b3cdcd,e7b8b8,d9ecd1,f0e8c5</sprite>""";
- with open(monstersDbFile, "r") as f:
- for line in f:
- if len(line) < 10 or line[0:2] == "//" or line[0:12] != "REPLACE INTO":
- continue
- rows = bracketsSplit.split(line)
- if len(rows) < 2:
- continue
- rows = fieldsSplit.split(rows[1])
- if len(rows) < 5:
- continue
- monsterId = rows[0]
- name = strToXml(stripQuotes(rows[2]))
- data = data + tpl.format(monsterId, name, monsterSprite)
-
- saveFile(destDir + "monsters.xml", monsters.format(data))
-
-def convertMercenaries():
- destDir = "clientdata/"
- templatesDir = "templates/"
- mercenariesDbFile = "serverdata/db/mercenary_db.txt"
- fieldsSplit = re.compile(",")
- makeDir(destDir)
- tpl = readFile(templatesDir + "mercenary.tpl")
- mercenaries = readFile(templatesDir + "mercenaries.xml")
- data = ""
- mercenarySprite = "<sprite>monsters/croc.xml</sprite>";
- with open(mercenariesDbFile, "r") as f:
- for line in f:
- if line == "" or line[0:2] == "//":
- continue
- rows = fieldsSplit.split(line)
- if len(rows) < 9:
- continue
- mercenaryId = rows[0]
- data = data + tpl.format(mercenaryId, mercenarySprite)
- saveFile(destDir + "mercenaries.xml", mercenaries.format(data))
-
-def convertPets():
- destDir = "clientdata/"
- templatesDir = "templates/"
- petsDbFile = "serverdata/db/pet_db.txt"
- fieldsSplit = re.compile(",")
- makeDir(destDir)
- tpl = readFile(templatesDir + "pet.tpl")
- pets = readFile(templatesDir + "pets.xml")
- data = ""
- petSprite = "<sprite>monsters/tortuga.xml</sprite>";
- with open(petsDbFile, "r") as f:
- for line in f:
- if line == "" or line[0:2] == "//":
- continue
- rows = fieldsSplit.split(line)
- if len(rows) < 9:
- continue
- petId = rows[0]
- data = data + tpl.format(petId, petSprite)
- saveFile(destDir + "pets.xml", pets.format(data))
-
-def convertHomunculuses():
- destDir = "clientdata/"
- templatesDir = "templates/"
- homunculusesDbFile = "serverdata/db/re/homunculus_db.txt"
- fieldsSplit = re.compile(",")
- makeDir(destDir)
- tpl = readFile(templatesDir + "homunculus.tpl")
- homunculuses = readFile(templatesDir + "homunculuses.xml")
- data = ""
- homunculusSprite = "<sprite>monsters/tortuga.xml</sprite>";
- with open(homunculusesDbFile, "r") as f:
- for line in f:
- if line == "" or line[0:2] == "//":
- continue
- rows = fieldsSplit.split(line)
- if len(rows) < 9:
- continue
- homunculusId = rows[0]
- data = data + tpl.format(homunculusId, homunculusSprite)
- saveFile(destDir + "homunculuses.xml", homunculuses.format(data))
-
-def convertSkillsToXml():
- destDir = "clientdata/"
- templatesDir = "templates/"
- skillsDbFile = "serverdata/db/re/skill_db.txt"
- fieldsSplit = re.compile(",")
- makeDir(destDir)
- tpl = readFile(templatesDir + "skill.tpl")
- skills = readFile(templatesDir + "skills.xml")
- data = ""
- with open(skillsDbFile, "r") as f:
- for line in f:
- if line == "" or line[0:2] == "//":
- continue
- rows = fieldsSplit.split(line)
- if len(rows) < 9:
- continue
- skillId = rows[0]
- name = rows[15].strip()
- description = rows[16].strip()
- idx = description.find ("//")
- if idx > 1:
- description = description[:idx]
- 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
- sz = sz + 8
- 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 + 12 + 8 + len(binData)
- break
- w.seek(0);
- writeInt32(w, sz)
- writeInt16(w, mapsCount)
-
-def readMapCache(path, cmd):
- if cmd == "help":
- printHelp()
- if cmd == "queststoxml":
- covertQuests()
- return
- elif cmd == "itemstoxml":
- convertItems()
- return
- elif cmd == "monsterstoxml":
- convertMonsters();
- return
- elif cmd == "mercenariestoxml":
- convertMercenaries();
- return
- elif cmd == "petstoxml":
- convertPets();
- return
- elif cmd == "homunculusestoxml":
- convertHomunculuses();
- return
- elif cmd == "skillstoxml":
- convertSkillsToXml();
- return
- elif cmd == "tmxtocache":
- recreateMapCache();
- return
-
- with open(path, "rb") as f:
- size = readInt32(f)
- if os.path.getsize(path) != size:
- print "Map cache corrupted, wrong file size."
- exit(1)
- mapsCount = readInt16(f)
- print "Maps count: " + str(mapsCount)
- readInt16(f) # padding
- if cmd == "listmaps":
- listMapCache(f, mapsCount)
- elif cmd == "extractmaps":
- extractMaps(f, mapsCount)
- elif cmd == "mapstotmx":
- covertToTmx(f, mapsCount)
-
-
-readMapCache("serverdata/db/re/map_cache.dat", detectCommand())
diff --git a/hercules/mercenariestoxml.py b/hercules/mercenariestoxml.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/mercenariestoxml.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/monsterstoxml.py b/hercules/monsterstoxml.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/monsterstoxml.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/petstoxml.py b/hercules/petstoxml.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/petstoxml.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/queststoxml.py b/hercules/queststoxml.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/queststoxml.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/skillstoxml.py b/hercules/skillstoxml.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/skillstoxml.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file
diff --git a/hercules/tmxtocache.py b/hercules/tmxtocache.py
deleted file mode 120000
index df2b3e6..0000000
--- a/hercules/tmxtocache.py
+++ /dev/null
@@ -1 +0,0 @@
-maptool.py \ No newline at end of file