Compare commits

...

8 Commits

5 changed files with 110 additions and 100 deletions

@ -3,6 +3,10 @@ Minetest-c55 changelog
This should contain all the major changes. This should contain all the major changes.
For minor stuff, refer to the commit log of the repository. For minor stuff, refer to the commit log of the repository.
0.2.20110922_2:
- Move PLATFORM_LIBS around to make sqlite3 link with libdl on some distros
- sectors2sqlite.py and minetestmapper.py fixes
0.2.20110922_1: 0.2.20110922_1:
- Make client report a newer version number to the server than 2011-07-31 does and make server disallow old clients - Make client report a newer version number to the server than 2011-07-31 does and make server disallow old clients

@ -188,10 +188,10 @@ if(BUILD_CLIENT)
${PNG_LIBRARIES} ${PNG_LIBRARIES}
${X11_LIBRARIES} ${X11_LIBRARIES}
${GETTEXT_LIBRARY} ${GETTEXT_LIBRARY}
${PLATFORM_LIBS}
${CLIENT_PLATFORM_LIBS}
${JTHREAD_LIBRARY} ${JTHREAD_LIBRARY}
${SQLITE3_LIBRARY} ${SQLITE3_LIBRARY}
${PLATFORM_LIBS}
${CLIENT_PLATFORM_LIBS}
) )
endif(BUILD_CLIENT) endif(BUILD_CLIENT)
@ -200,9 +200,9 @@ if(BUILD_SERVER)
target_link_libraries( target_link_libraries(
${PROJECT_NAME}server ${PROJECT_NAME}server
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
${PLATFORM_LIBS}
${JTHREAD_LIBRARY} ${JTHREAD_LIBRARY}
${SQLITE3_LIBRARY} ${SQLITE3_LIBRARY}
${PLATFORM_LIBS}
) )
endif(BUILD_SERVER) endif(BUILD_SERVER)

@ -24,7 +24,7 @@ f 128 79 0 # CONTENT_CHEST
80d 219 202 178 # CONTENT_MOSSYCOBBLE 80d 219 202 178 # CONTENT_MOSSYCOBBLE
80e 78 154 6 # CONTENT_GRAVEL 80e 78 154 6 # CONTENT_GRAVEL
80f 204 0 0 # CONTENT_SANDSTONE 80f 204 0 0 # CONTENT_SANDSTONE
810 211 215 207 # CONTENT_CACTUS 810 0 215 0 # CONTENT_CACTUS
811 170 50 25 # CONTENT_BRICK 811 170 50 25 # CONTENT_BRICK
812 104 78 42 # CONTENT_CLAY 812 104 78 42 # CONTENT_CLAY
813 58 105 18 # CONTENT_PAPYRUS 813 58 105 18 # CONTENT_PAPYRUS
@ -33,3 +33,4 @@ f 128 79 0 # CONTENT_CHEST
816 62 101 25 # CONTENT_JUNGLEGRASS 816 62 101 25 # CONTENT_JUNGLEGRASS
817 255 153 255 # CONTENT_NC 817 255 153 255 # CONTENT_NC
818 102 50 255 # CONTENT_NC_RB 818 102 50 255 # CONTENT_NC_RB
819 200 0 0 # CONTENT_APPLE

152
util/minetestmapper.py Executable file → Normal file

@ -29,10 +29,9 @@ import time
import getopt import getopt
import sys import sys
import array import array
import cStringIO
from PIL import Image, ImageDraw, ImageFont, ImageColor from PIL import Image, ImageDraw, ImageFont, ImageColor
CONTENT_WATER = [2, 9]
TRANSLATION_TABLE = { TRANSLATION_TABLE = {
1: 0x800, # CONTENT_GRASS 1: 0x800, # CONTENT_GRASS
4: 0x801, # CONTENT_TREE 4: 0x801, # CONTENT_TREE
@ -88,9 +87,19 @@ 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 getIntegerAsBlock(i): def unsignedToSigned(i, max_positive):
return i%4096, int(i/4096)%4096, int(i/16777216)%4096 if i < max_positive:
return i
else:
return i - 2*max_positive
def getIntegerAsBlock(i):
x = unsignedToSigned(i % 4096, 2048)
i = int((i - x) / 4096)
y = unsignedToSigned(i % 4096, 2048)
i = int((i - y) / 4096)
z = unsignedToSigned(i % 4096, 2048)
return x,y,z
def limit(i, l, h): def limit(i, l, h):
if(i > h): if(i > h):
@ -101,14 +110,15 @@ def limit(i, l, h):
def usage(): def usage():
print "TODO: Help" print("TODO: Help")
try: try:
opts, args = getopt.getopt(sys.argv[1:], "hi:o:", ["help", "input=", opts, args = getopt.getopt(sys.argv[1:], "hi:o:", ["help", "input=",
"output=", "bgcolor=", "scalecolor=", "origincolor=", "output=", "bgcolor=", "scalecolor=", "origincolor=",
"playercolor=", "draworigin", "drawplayers", "drawscale"]) "playercolor=", "draworigin", "drawplayers", "drawscale",
except getopt.GetoptError, err: "drawunderground"])
except getopt.GetoptError as err:
# print help information and exit: # print help information and exit:
print str(err) # will print something like "option -a not recognized" print(str(err)) # will print something like "option -a not recognized"
usage() usage()
sys.exit(2) sys.exit(2)
@ -122,6 +132,7 @@ playercolor = "red"
drawscale = False drawscale = False
drawplayers = False drawplayers = False
draworigin = False draworigin = False
drawunderground = False
sector_xmin = -1500 / 16 sector_xmin = -1500 / 16
sector_xmax = 1500 / 16 sector_xmax = 1500 / 16
@ -151,6 +162,8 @@ for o, a in opts:
drawplayers = True drawplayers = True
elif o == "--draworigin": elif o == "--draworigin":
draworigin = True draworigin = True
elif o == "--drawunderground":
drawunderground = True
else: else:
assert False, "unhandled option" assert False, "unhandled option"
@ -190,7 +203,7 @@ if os.path.exists(path + "map.sqlite"):
if not r: if not r:
break break
x, y, z = getIntegerAsBlock (r[0]) x, y, z = getIntegerAsBlock(r[0])
if x < sector_xmin or x > sector_xmax: if x < sector_xmin or x > sector_xmax:
continue continue
@ -223,6 +236,9 @@ if os.path.exists(path + "sectors"):
xlist.append(x) xlist.append(x)
zlist.append(z) zlist.append(z)
# Get rid of doubles
xlist, zlist = zip(*sorted(set(zip(xlist, zlist))))
minx = min(xlist) minx = min(xlist)
minz = min(zlist) minz = min(zlist)
maxx = max(xlist) maxx = max(xlist)
@ -231,7 +247,7 @@ maxz = max(zlist)
w = (maxx - minx) * 16 + 16 w = (maxx - minx) * 16 + 16
h = (maxz - minz) * 16 + 16 h = (maxz - minz) * 16 + 16
print "w=" + str(w) + " h=" + str(h) print("w=" + str(w) + " h=" + str(h))
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)
@ -241,12 +257,15 @@ stuff = {}
starttime = time.time() starttime = time.time()
CONTENT_WATER = 2
def data_is_air(d): def content_is_water(d):
return d in [2, 9]
def content_is_air(d):
return d in [126, 127, 254] return d in [126, 127, 254]
def read_content(mapdata, version, datapos):
def read_blocknum(mapdata, version, datapos):
if version == 20: if version == 20:
if mapdata[datapos] < 0x80: if mapdata[datapos] < 0x80:
return mapdata[datapos] return mapdata[datapos]
@ -258,7 +277,7 @@ def read_blocknum(mapdata, version, datapos):
raise Exception("Unsupported map format: " + str(version)) raise Exception("Unsupported map format: " + str(version))
def read_mapdata(f, version, pixellist, water): def read_mapdata(f, version, pixellist, water, day_night_differs):
global stuff # oh my :-) global stuff # oh my :-)
dec_o = zlib.decompressobj() dec_o = zlib.decompressobj()
@ -270,34 +289,35 @@ def read_mapdata(f, version, pixellist, water):
f.close() f.close()
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
chunkypos = ypos * 16 chunkypos = ypos * 16
chunkzpos = zpos * 16 chunkzpos = zpos * 16
blocknum = 0 content = 0
datapos = 0 datapos = 0
for (x, z) in reversed(pixellist): for (x, z) in reversed(pixellist):
for y in reversed(range(16)): for y in reversed(range(16)):
datapos = x + y * 16 + z * 256 datapos = x + y * 16 + z * 256
blocknum = read_blocknum(mapdata, version, datapos) content = read_content(mapdata, version, datapos)
if not data_is_air(blocknum) and blocknum in colors: if content_is_air(content):
if blocknum in CONTENT_WATER: pass
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, blocknum, water[(x, z)]) chunkypos + y, content, water[(x, z)], day_night_differs)
else: elif content in colors:
pixellist.remove((x, z))
# 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, blocknum, water[(x, z)]) chunkypos + y, content, water[(x, z)], day_night_differs)
pixellist.remove((x, z))
break break
elif not data_is_air(blocknum) and blocknum not in colors: else:
print "strange block: %s/%s/%s x: %d y: %d z: %d \ print("strange block: %s/%s/%s x: %d y: %d z: %d \
block id: %x" % (xhex, zhex, yhex, x, y, z, blocknum) block id: %x" % (xhex, zhex, yhex, x, y, z, content))
# Go through all sectors. # Go through all sectors.
for n in range(len(xlist)): for n in range(len(xlist)):
@ -337,8 +357,9 @@ for n in range(len(xlist)):
sectortype = "" sectortype = ""
if cur: if cur:
ps = getBlockAsInteger((xpos, 0, zpos)) psmin = getBlockAsInteger((xpos, -2048, zpos))
cur.execute("SELECT `pos` FROM `blocks` WHERE `pos`>=? AND `pos`<?", (ps, ps + 4096)) psmax = getBlockAsInteger((xpos, 2047, zpos))
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:
@ -383,28 +404,22 @@ for n in range(len(xlist)):
water[(x, z)] = 0 water[(x, z)] = 0
# Go through the Y axis from top to bottom. # Go through the Y axis from top to bottom.
ylist2 = []
for ypos in reversed(ylist): for ypos in reversed(ylist):
yhex = int_to_hex4(ypos) yhex = int_to_hex4(ypos)
filename = ""
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
filename = "mtm_tmp" f = cStringIO.StringIO(r[0])
f = file(filename, 'wb')
f.write(r[0])
f.close()
else: else:
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.
@ -412,43 +427,16 @@ for n in range(len(xlist)):
flags = f.read(1) flags = f.read(1)
# Checking day and night differs -flag # Checking day and night differs -flag
if not ord(flags) & 2: day_night_differs = ((ord(flags) & 2) != 0)
ylist2.append((ypos, filename))
f.close()
continue
read_mapdata(f, version, pixellist, water) read_mapdata(f, version, pixellist, water, day_night_differs)
# 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
if len(pixellist) > 0: print("Drawing image")
for (ypos, filename) in ylist2:
ps = getBlockAsInteger((xpos, ypos, zpos))
cur.execute("SELECT `data` FROM `blocks` WHERE `pos`==? LIMIT 1", (ps,))
r = cur.fetchone()
if not r:
continue
filename = "mtm_tmp"
f = file(filename, 'wb')
f.write(r[0])
f.close()
f = file(filename, "rb")
version = ord(f.read(1))
flags = f.read(1)
read_mapdata(f, version, pixellist, water)
# After finding all the pixels in the sector, we can move on
# to the next sector without having to continue the Y axis.
if(len(pixellist) == 0):
break
print "Drawing image"
# Drawing the picture # Drawing the picture
starttime = time.time() starttime = time.time()
n = 0 n = 0
@ -474,18 +462,29 @@ for (x, z) in stuff.iterkeys():
n += 1 n += 1
(r, g, b) = colors[stuff[(x, z)][1]] (r, g, b) = colors[stuff[(x, z)][1]]
dnd = stuff[(x, z)][3] # day/night differs?
if not dnd and not drawunderground:
if stuff[(x, z)][2] > 0: # water
(r, g, b) = colors[CONTENT_WATER]
else:
continue
# Comparing heights of a couple of adjacent blocks and changing # Comparing heights of a couple of adjacent blocks and changing
# brightness accordingly. # brightness accordingly.
try: try:
c = stuff[(x, z)][1]
c1 = stuff[(x - 1, z)][1] c1 = stuff[(x - 1, z)][1]
c2 = stuff[(x, z + 1)][1] c2 = stuff[(x, z + 1)][1]
c = stuff[(x, z)][1] dnd1 = stuff[(x - 1, z)][3]
if c1 not in CONTENT_WATER and c2 not in CONTENT_WATER and \ dnd2 = stuff[(x, z + 1)][3]
c not in CONTENT_WATER: if not dnd:
y1 = stuff[(x - 1, z)][0] d = -69
y2 = stuff[(x, z + 1)][0] elif not content_is_water(c1) and not content_is_water(c2) and \
not content_is_water(c):
y = stuff[(x, z)][0] y = stuff[(x, z)][0]
y1 = stuff[(x - 1, z)][0] if dnd1 else y
y2 = stuff[(x, z + 1)][0] if dnd2 else y
d = ((y - y1) + (y - y2)) * 12 d = ((y - y1) + (y - y2)) * 12
else: else:
d = 0 d = 0
@ -542,10 +541,10 @@ if drawplayers:
p = string.split(line) p = string.split(line)
if p[0] == "name": if p[0] == "name":
name = p[2] name = p[2]
print filename + ": name = " + name print(filename + ": name = " + name)
if p[0] == "position": if p[0] == "position":
position = string.split(p[2][1:-1], ",") position = string.split(p[2][1:-1], ",")
print filename + ": position = " + p[2] print(filename + ": position = " + p[2])
if len(name) > 0 and len(position) == 3: if len(name) > 0 and len(position) == 3:
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))
@ -557,8 +556,5 @@ if drawplayers:
except OSError: except OSError:
pass pass
if os.path.isfile("mtm_tmp"): print("Saving")
os.remove("mtm_tmp")
print "Saving"
im.save(output) im.save(output)

@ -3,7 +3,7 @@
# Loads block files from sectors folders into map.sqlite database. # Loads block files from sectors folders into map.sqlite database.
# The sectors folder should be safe to remove after this prints "Finished." # The sectors folder should be safe to remove after this prints "Finished."
import time, os import time, os, sys
try: try:
import sqlite3 import sqlite3
@ -23,10 +23,14 @@ if os.path.isdir(path + 'sectors/'):
if not paths: if not paths:
exit('Could not find sectors folder at ' + path + 'sectors2/ or ' + path + 'sectors/') exit('Could not find sectors folder at ' + path + 'sectors2/ or ' + path + 'sectors/')
def uint(u): def parseSigned12bit(u):
u = int('0x'+u, 16) u = int('0x'+u, 16)
return (u if u < 2**11 else u - 2**12) return (u if u < 2**11 else u - 2**12)
def parseSigned16bit(u):
u = int('0x'+u, 16)
return (u if u < 2**15 else u - 2**16)
def int64(u): def int64(u):
while u >= 2**63: while u >= 2**63:
u -= 2**64 u -= 2**64
@ -38,12 +42,12 @@ def int64(u):
def getSectorPos(dirname): def getSectorPos(dirname):
if len(dirname) == 8: if len(dirname) == 8:
# Old layout # Old layout
x = uint(dirname[:4]) x = parseSigned16bit(dirname[:4])
z = uint(dirname[4:]) z = parseSigned16bit(dirname[4:])
elif len(dirname) == 7: elif len(dirname) == 7:
# New layout # New layout
x = uint(dirname[:3]) x = parseSigned12bit(dirname[:3])
z = uint(dirname[4:]) z = parseSigned12bit(dirname[4:])
else: else:
print('Terrible sector at ' + dirname) print('Terrible sector at ' + dirname)
return return
@ -60,7 +64,7 @@ def getBlockPos(sectordir, blockfile):
if len(blockfile) != 4: if len(blockfile) != 4:
print("Invalid block filename: " + blockfile) print("Invalid block filename: " + blockfile)
y = uint(blockfile) y = parseSigned16bit(blockfile)
return p2d[0], y, p2d[1] return p2d[0], y, p2d[1]
@ -110,8 +114,13 @@ for base in paths:
continue continue
f = open(root+'/'+block, 'rb') f = open(root+'/'+block, 'rb')
cur.execute('INSERT OR IGNORE INTO `blocks` VALUES(?, ?)', (pos, f.read())) blob = f.read()
f.close() f.close()
if sys.version_info.major == 2:
blob = buffer(blob)
else:
blob = memoryview(blob)
cur.execute('INSERT OR IGNORE INTO `blocks` VALUES(?, ?)', (pos, blob))
count += 1 count += 1
if(time.time() - t > 3): if(time.time() - t > 3):