Browse Source

display backend and mapper_path being used

and improve PEP8 compliance of minetestmapper fork (already submitted
pull request from github.com/expertmm/minetest)
master
poikilos 8 years ago
committed by Jacob Gustafson
parent
commit
269852a4f0
  1. 129
      minetestmapper-expertmm.py
  2. 2
      singleimage.py

129
minetestmapper-expertmm.py

@ -1,13 +1,7 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# This program is free software. It comes without any warranty, to # Made by Jogge, modified by: celeron55, expertmm
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the WTFPL
# Public License, Version 2, as published by Sam Hocevar. See
# COPYING for more details.
# Made by Jogge, modified by celeron55
# 2011-05-29: j0gge: initial release # 2011-05-29: j0gge: initial release
# 2011-05-30: celeron55: simultaneous support for sectors/sectors2, removed # 2011-05-30: celeron55: simultaneous support for sectors/sectors2, removed
# 2011-06-02: j0gge: command line parameters, coordinates, players, ... # 2011-06-02: j0gge: command line parameters, coordinates, players, ...
@ -16,6 +10,9 @@
# 2011-07-30: WF: Support for content types extension, refactoring # 2011-07-30: WF: Support for content types extension, refactoring
# 2011-07-30: erlehmann: PEP 8 compliance. # 2011-07-30: erlehmann: PEP 8 compliance.
# 2016-03-08: expertmm: geometry and region params # 2016-03-08: expertmm: geometry and region params
# 2017-03-17: expertmm: removed license from this file (this file should fall
# under the license of minetest)
# 2017-04-12: expertmm: PEP8 compliance
# Requires Python Imaging Library: http://www.pythonware.com/products/pil/ # Requires Python Imaging Library: http://www.pythonware.com/products/pil/
@ -89,12 +86,14 @@ def int_to_hex4(i):
def getBlockAsInteger(p): def getBlockAsInteger(p):
return p[2]*16777216 + p[1]*4096 + p[0] return p[2]*16777216 + p[1]*4096 + p[0]
def unsignedToSigned(i, max_positive): def unsignedToSigned(i, max_positive):
if i < max_positive: if i < max_positive:
return i return i
else: else:
return i - 2*max_positive return i - 2*max_positive
def getIntegerAsBlock(i): def getIntegerAsBlock(i):
x = unsignedToSigned(i % 4096, 2048) x = unsignedToSigned(i % 4096, 2048)
i = int((i - x) / 4096) i = int((i - x) / 4096)
@ -103,6 +102,7 @@ def getIntegerAsBlock(i):
z = unsignedToSigned(i % 4096, 2048) z = unsignedToSigned(i % 4096, 2048)
return x, y, z return x, y, z
def limit(i, l, h): def limit(i, l, h):
if(i > h): if(i > h):
i = h i = h
@ -110,17 +110,24 @@ def limit(i, l, h):
i = l i = l
return i return i
def readU8(f): def readU8(f):
return ord(f.read(1)) return ord(f.read(1))
def readU16(f): def readU16(f):
return ord(f.read(1))*256 + ord(f.read(1)) return ord(f.read(1))*256 + ord(f.read(1))
def readU32(f): def readU32(f):
return ord(f.read(1))*256*256*256 + ord(f.read(1))*256*256 + ord(f.read(1))*256 + ord(f.read(1)) return ord(f.read(1))*256*256*256 + ord(f.read(1))*256*256 + \
ord(f.read(1))*256 + ord(f.read(1))
def readS32(f): def readS32(f):
return unsignedToSigned(ord(f.read(1))*256*256*256 + ord(f.read(1))*256*256 + ord(f.read(1))*256 + ord(f.read(1)), 2**31) return unsignedToSigned(ord(f.read(1))*256*256*256 +
ord(f.read(1))*256*256 + ord(f.read(1))*256 +
ord(f.read(1)), 2**31)
usagetext = """minetestmapper.py [options] usagetext = """minetestmapper.py [options]
-i/--input <world_path> -i/--input <world_path>
@ -226,24 +233,24 @@ if geometry_string is not None:
nonchunky_xmax = nonchunky_xmin + this_width - 1 # inclusive rect nonchunky_xmax = nonchunky_xmin + this_width - 1 # inclusive rect
nonchunky_zmin = z nonchunky_zmin = z
nonchunky_zmax = nonchunky_zmin + this_height - 1 # inclusive rect nonchunky_zmax = nonchunky_zmin + this_height - 1 # inclusive rect
print("#geometry:") print("#geometry:" + "\n" +
print("# x:" + str(x)) "# x:" + str(x) + "\n" +
print("# z:" + str(z)) "# z:" + str(z) + "\n" +
print("# width:" + str(this_width)) "# width:" + str(this_width) + "\n" +
print("# height:" + str(this_height)) "# height:" + str(this_height) + "\n" +
print("region:") "region:" + "\n" +
print(" xmin:" + str(nonchunky_xmin)) " xmin:" + str(nonchunky_xmin) + "\n" +
print(" xmax:" + str(nonchunky_xmax)) " xmax:" + str(nonchunky_xmax) + "\n" +
print(" zmin:" + str(nonchunky_zmin)) " zmin:" + str(nonchunky_zmin) + "\n" +
print(" zmax:" + str(nonchunky_zmax)) " zmax:" + str(nonchunky_zmax))
else: else:
print("ERROR: Missing coordinates in '" + geometry_string + print("ERROR: Missing coordinates in '" + geometry_string +
"' for geometry (must be in the form: x:z+width+height)") "' for geometry (must be in the form: x:z+width+height)")
usage() usage()
sys.exit(2) sys.exit(2)
else: else:
print("ERROR: Incorrect value '" + geometry_string + print("ERROR: Incorrect geometry syntax '" + geometry_string +
"' for geometry (must be in the form: x:z+width+height)") "' (must be in the form: x:z+width+height)")
usage() usage()
sys.exit(2) sys.exit(2)
elif region_string is not None: elif region_string is not None:
@ -258,11 +265,11 @@ elif region_string is not None:
nonchunky_xmax = int(xmax_string) nonchunky_xmax = int(xmax_string)
nonchunky_zmin = int(zmin_string) nonchunky_zmin = int(zmin_string)
nonchunky_zmax = int(zmax_string) nonchunky_zmax = int(zmax_string)
print("region:") print("region:" + "\n" +
print(" xmin:" + str(nonchunky_xmin)) " xmin:" + str(nonchunky_xmin) + "\n" +
print(" xmax:" + str(nonchunky_xmax)) " xmax:" + str(nonchunky_xmax) + "\n" +
print(" zmin:" + str(nonchunky_zmin)) " zmin:" + str(nonchunky_zmin) + "\n" +
print(" zmax:" + str(nonchunky_zmax)) " zmax:" + str(nonchunky_zmax))
else: else:
print("ERROR: Incorrect value '" + region_string + print("ERROR: Incorrect value '" + region_string +
"' for region (must be in the form: xmin:xmax,zmin:zmax)") "' for region (must be in the form: xmin:xmax,zmin:zmax)")
@ -411,8 +418,8 @@ maxz = max(zlist)
w = (maxx - minx) * 16 + 16 w = (maxx - minx) * 16 + 16
h = (maxz - minz) * 16 + 16 h = (maxz - minz) * 16 + 16
print("Result image (w=" + str(w) + " h=" + str(h) + ") will be written to " print("Result image (w=" + str(w) + " h=" + str(h) + ") will be written to " +
+ output) output)
im = Image.new("RGB", (w + border, h + border), bgcolor) im = Image.new("RGB", (w + border, h + border), bgcolor)
draw = ImageDraw.Draw(im) draw = ImageDraw.Draw(im)
@ -427,15 +434,19 @@ starttime = time.time()
CONTENT_WATER = 2 CONTENT_WATER = 2
def content_is_ignore(d): def content_is_ignore(d):
return d in [0, "ignore"] return d in [0, "ignore"]
def content_is_water(d): def content_is_water(d):
return d in [2, 9] return d in [2, 9]
def content_is_air(d): def content_is_air(d):
return d in [126, 127, 254, "air"] return d in [126, 127, 254, "air"]
def read_content(mapdata, version, datapos): def read_content(mapdata, version, datapos):
if version >= 24: if version >= 24:
return (mapdata[datapos*2] << 8) | (mapdata[datapos*2 + 1]) return (mapdata[datapos*2] << 8) | (mapdata[datapos*2 + 1])
@ -450,13 +461,14 @@ def read_content(mapdata, version, datapos):
raise Exception("Unsupported map format: " + str(version)) raise Exception("Unsupported map format: " + str(version))
def read_mapdata(mapdata, version, pixellist, water, day_night_differs, id_to_name): def read_mapdata(mapdata, version, pixellist, water, day_night_differs,
id_to_name):
global stuff # oh my :-) global stuff # oh my :-)
global unknown_node_names global unknown_node_names
global unknown_node_ids global unknown_node_ids
if(len(mapdata) < 4096): if(len(mapdata) < 4096):
print("bad: " + xhex + "/" + zhex + "/" + yhex + " " + \ print("bad: " + xhex + "/" + zhex + "/" + yhex + " " +
str(len(mapdata))) str(len(mapdata)))
else: else:
chunkxpos = xpos * 16 chunkxpos = xpos * 16
@ -481,25 +493,31 @@ def read_mapdata(mapdata, version, pixellist, water, day_night_differs, id_to_na
elif content_is_water(content): elif content_is_water(content):
water[(x, z)] += 1 water[(x, z)] += 1
# Add dummy stuff for drawing sea without seabed # Add dummy stuff for drawing sea without seabed
stuff[(chunkxpos + x, chunkzpos + z)] = ( stuff[(chunkxpos + x, chunkzpos + z)] = (chunkypos + y,
chunkypos + y, content, water[(x, z)], day_night_differs) content,
water[(x, z)],
day_night_differs)
elif content in colors: elif content in colors:
# Memorize information on the type and height of # Memorize information on the type and height of
# the block and for drawing the picture. # the block and for drawing the picture.
stuff[(chunkxpos + x, chunkzpos + z)] = ( stuff[(chunkxpos + x, chunkzpos + z)] = (chunkypos + y,
chunkypos + y, content, water[(x, z)], day_night_differs) content,
water[(x, z)],
day_night_differs)
pixellist.remove((x, z)) pixellist.remove((x, z))
break break
else: else:
if type(content) == str: if type(content) == str:
if content not in unknown_node_names: if content not in unknown_node_names:
unknown_node_names.append(content) unknown_node_names.append(content)
#print("unknown node: %s/%s/%s x: %d y: %d z: %d block name: %s" # print("unknown node: %s/%s/%s x: %d y: %d z: %d" +
# " block name: %s"
# % (xhex, zhex, yhex, x, y, z, content)) # % (xhex, zhex, yhex, x, y, z, content))
else: else:
if content not in unknown_node_ids: if content not in unknown_node_ids:
unknown_node_ids.append(content) unknown_node_ids.append(content)
#print("unknown node: %s/%s/%s x: %d y: %d z: %d block id: %x" # print("unknown node: %s/%s/%s x: %d y: %d z: %d" +
# " block id: %x"
# % (xhex, zhex, yhex, x, y, z, content)) # % (xhex, zhex, yhex, x, y, z, content))
@ -520,10 +538,10 @@ for n in range(len(xlist)):
remaining_s = time_guess - dtime remaining_s = time_guess - dtime
remaining_minutes = int(remaining_s / 60) remaining_minutes = int(remaining_s / 60)
remaining_s -= remaining_minutes * 60 remaining_s -= remaining_minutes * 60
print("Processing sector " + str(n) + " of " + str(len(xlist)) print("Processing sector " + str(n) + " of " + str(len(xlist)) +
+ " (" + str(round(100.0 * n / len(xlist), 1)) + "%)" " (" + str(round(100.0 * n / len(xlist), 1)) + "%)" +
+ " (ETA: " + str(remaining_minutes) + "m " " (ETA: " + str(remaining_minutes) + "m " +
+ str(int(remaining_s)) + "s)") str(int(remaining_s)) + "s)")
xpos = xlist[n] xpos = xlist[n]
zpos = zlist[n] zpos = zlist[n]
@ -543,7 +561,9 @@ for n in range(len(xlist)):
if cur: if cur:
psmin = getBlockAsInteger((xpos, -2048, zpos)) psmin = getBlockAsInteger((xpos, -2048, zpos))
psmax = getBlockAsInteger((xpos, 2047, zpos)) psmax = getBlockAsInteger((xpos, 2047, zpos))
cur.execute("SELECT `pos` FROM `blocks` WHERE `pos`>=? AND `pos`<=? AND (`pos` - ?) % 4096 = 0", (psmin, psmax, psmin)) cur.execute("SELECT `pos` FROM `blocks` WHERE `pos`>=?"
" AND `pos`<=? AND (`pos` - ?) % 4096 = 0",
(psmin, psmax, psmin))
while True: while True:
r = cur.fetchone() r = cur.fetchone()
if not r: if not r:
@ -596,7 +616,8 @@ for n in range(len(xlist)):
if sectortype == "sqlite": if sectortype == "sqlite":
ps = getBlockAsInteger((xpos, ypos, zpos)) ps = getBlockAsInteger((xpos, ypos, zpos))
cur.execute("SELECT `data` FROM `blocks` WHERE `pos`==? LIMIT 1", (ps,)) cur.execute("SELECT `data` FROM `blocks`"
" WHERE `pos`==? LIMIT 1", (ps,))
r = cur.fetchone() r = cur.fetchone()
if not r: if not r:
continue continue
@ -605,7 +626,8 @@ for n in range(len(xlist)):
if sectortype == "old": if sectortype == "old":
filename = path + "sectors/" + sector1 + "/" + yhex.lower() filename = path + "sectors/" + sector1 + "/" + yhex.lower()
else: else:
filename = path + "sectors2/" + sector2 + "/" + yhex.lower() filename = path + "sectors2/" + sector2 + "/" + \
yhex.lower()
f = file(filename, "rb") f = file(filename, "rb")
# Let's just memorize these even though it's not really necessary. # Let's just memorize these even though it's not really necessary.
@ -638,7 +660,7 @@ for n in range(len(xlist)):
mapdata = [] mapdata = []
# Reuse the unused tail of the file # Reuse the unused tail of the file
f.close(); f.close()
f = cStringIO.StringIO(dec_o.unused_data) f = cStringIO.StringIO(dec_o.unused_data)
# print("unused data: "+repr(dec_o.unused_data)) # print("unused data: "+repr(dec_o.unused_data))
@ -651,7 +673,7 @@ for n in range(len(xlist)):
metaliststr = [] metaliststr = []
# Reuse the unused tail of the file # Reuse the unused tail of the file
f.close(); f.close()
f = cStringIO.StringIO(dec_o.unused_data) f = cStringIO.StringIO(dec_o.unused_data)
# print("* dec_o.unused_data: "+repr(dec_o.unused_data)) # print("* dec_o.unused_data: "+repr(dec_o.unused_data))
data_after_node_metadata = dec_o.unused_data data_after_node_metadata = dec_o.unused_data
@ -711,14 +733,16 @@ for n in range(len(xlist)):
readS32(f) readS32(f)
readS32(f) readS32(f)
read_mapdata(mapdata, version, pixellist, water, day_night_differs, id_to_name) read_mapdata(mapdata, version, pixellist, water, day_night_differs,
id_to_name)
# After finding all the pixels in the sector, we can move on to # After finding all the pixels in the sector, we can move on to
# the next sector without having to continue the Y axis. # the next sector without having to continue the Y axis.
if(len(pixellist) == 0): if(len(pixellist) == 0):
break break
except Exception as e: except Exception as e:
print("Error at ("+str(xpos)+","+str(ypos)+","+str(zpos)+"): "+str(e)) print("Error at (" + str(xpos) + "," + str(ypos) + "," +
str(zpos) + "): " + str(e))
sys.stdout.write("Block data: ") sys.stdout.write("Block data: ")
for c in r[0]: for c in r[0]:
sys.stdout.write("%2.2x " % ord(c)) sys.stdout.write("%2.2x " % ord(c))
@ -748,10 +772,10 @@ for (x, z) in stuff.iterkeys():
remaining_s = time_guess - dtime remaining_s = time_guess - dtime
remaining_minutes = int(remaining_s / 60) remaining_minutes = int(remaining_s / 60)
remaining_s -= remaining_minutes * 60 remaining_s -= remaining_minutes * 60
print("Drawing pixel " + str(n) + " of " + str(listlen) print("Drawing pixel " + str(n) + " of " + str(listlen) +
+ " (" + str(round(100.0 * n / listlen, 1)) + "%)" " (" + str(round(100.0 * n / listlen, 1)) + "%)" +
+ " (ETA: " + str(remaining_minutes) + "m " " (ETA: " + str(remaining_minutes) + "m " +
+ str(int(remaining_s)) + "s)") str(int(remaining_s)) + "s)")
n += 1 n += 1
(r, g, b) = colors[stuff[(x, z)][1]] (r, g, b) = colors[stuff[(x, z)][1]]
@ -842,7 +866,8 @@ if drawplayers:
x = (int(float(position[0]) / 10 - minx * 16)) x = (int(float(position[0]) / 10 - minx * 16))
z = int(h - (float(position[2]) / 10 - minz * 16)) z = int(h - (float(position[2]) / 10 - minz * 16))
draw.ellipse((x - 2 + border, z - 2 + border, draw.ellipse((x - 2 + border, z - 2 + border,
x + 2 + border, z + 2 + border), outline=playercolor) x + 2 + border, z + 2 + border),
outline=playercolor)
draw.text((x + 2 + border, z + 2 + border), name, draw.text((x + 2 + border, z + 2 + border), name,
font=font, fill=playercolor) font=font, fill=playercolor)
f.close() f.close()

2
singleimage.py

@ -115,6 +115,8 @@ class ChunkymapOfflineRenderer:
print("") print("")
print("Running") print("Running")
print(" "+cmd_string) print(" "+cmd_string)
print(" mapper_path: " + self.minetestmapper_py_path)
print(" backend: " + self.backend_string)
print(" # (this may take a while...)") print(" # (this may take a while...)")
if os.path.isfile(tmp_png_path): if os.path.isfile(tmp_png_path):
os.remove(tmp_png_path) os.remove(tmp_png_path)

Loading…
Cancel
Save