Browse Source

save metadata as yaml

Discard minetestmapper numpy output after analyzing and saving relevant
data as YAML. Read YAML in php to get size of map tiles.
poikilos 10 years ago
committed by Jacob Gustafson
parent
commit
b818a95926
  1. 1
      README.md
  2. 365
      chunkymap-regen.py
  3. 170
      web/chunkymap.php
  4. 3
      web/index-example.php

1
README.md

@ -57,6 +57,7 @@ This program comes without any warranty, to the extent permitted by applicable l
* edit chunkymap_regen.py and change world_name to your world name
## Known Issues
* index-example.php should read the size of the chunks -- see near is_file($chunk_genresult_path) in chunkymap.php
* Show player location (and optionally turn off)
* Make a php file that shows the map on an html5 canvas (refresh players every 10 seconds, check for new map chunks every minute)
* Make players invisible if they stay in one spot too long (consider them logged out by that method alone since not requiring mods)

365
chunkymap-regen.py

@ -1,6 +1,7 @@
#!/usr/bin/env python2
import os
import subprocess
import traceback
# REQUIRES: see README.md
# The way to do a full render is deleting all files from the folder self.chunkymap_data_path such as /var/www/html/minetest/chunkymapdata (or chunkymap in current directory on Windows)
@ -15,12 +16,49 @@ import subprocess
class MTChunk:
x = None
z = None
is_player_here = None
is_player_in_this_chunk = None
is_fresh = None
width = None
height = None
is_marked = None
is_marked_empty = None
image_w = None
image_h = None
image_left = None
image_top = None
image_right = None
image_bottom = None
def __init__(self):
self.is_player_here = False
self.is_player_in_this_chunk = False
self.is_fresh = False
self.is_marked = False
self.is_marked_empty = False
def save_yaml(self, yml_path):
try:
outs = open(yml_path, 'w')
outs.write("is_marked_empty:"+str(self.is_marked_empty)+"\n")
outs.write("is_marked:"+str(self.is_marked)+"\n")
if self.width is not None:
outs.write("width:"+str(self.width)+"\n")
if self.height is not None:
outs.write("height:"+str(self.height)+"\n")
if self.image_w is not None:
outs.write("image_w:"+str(self.image_w)+"\n")
if self.image_h is not None:
outs.write("image_h:"+str(self.image_h)+"\n")
if self.image_left is not None:
outs.write("image_left:"+str(self.image_left)+"\n")
if self.image_top is not None:
outs.write("image_top:"+str(self.image_top)+"\n")
if self.image_right is not None:
outs.write("image_right:"+str(self.image_right)+"\n")
if self.image_bottom is not None:
outs.write("image_bottom:"+str(self.image_bottom)+"\n")
outs.close()
except:
print("Could not finish saving chunk metadata to '"+str(yml_path)+"': "+str(traceback.format_exc()))
class MTChunks:
@ -44,7 +82,7 @@ class MTChunks:
chunkz_min = 0
chunkx_max = 0
chunkz_max = 0
chunk_size = 80
chunk_size = None
#values for command arguments:
maxheight = 50
minheight = -25
@ -53,6 +91,8 @@ class MTChunks:
#total_generated_count = 0
#endregion values to save to YAML
world_blacklist = None
def __init__(self): #formerly checkpaths() in global scope
self.chunks = {}
self.username = "owner"
@ -87,25 +127,29 @@ class MTChunks:
self.worlds_path = os.path.join(self.dotminetest_path,"worlds")
self.world_path = os.path.join(self.worlds_path, self.world_name)
auto_chosen_world = False
self.world_blacklist = list()
self.world_blacklist.append("abiyahhgamebv7world1")
if not os.path.isdir(self.world_path):
#for item in os.walk(self.worlds_path):
print ("LOOKING FOR WORLDS IN " + self.worlds_path)
for dirname, dirnames, filenames in os.walk(self.worlds_path):
index = 0
for j in range(0,len(dirnames)):
i = len(dirnames) - 0 - 1
if dirnames[i][0] == ".":
print (" SKIPPING "+dirnames[i])
dirnames.remove_at(i)
#index = 0
#for j in range(0,len(dirnames)):
# i = len(dirnames) - 0 - 1
# if dirnames[i][0] == ".":
# print (" SKIPPING "+dirnames[i])
# dirnames.remove_at(i)
for subdirname in dirnames:
print (" EXAMINING "+subdirname)
if (index == len(dirnames)-1): # skip first one because the one on my computer is big
if subdirname[0]!=".":
#if (index == len(dirnames)-1): # skip first one because the one on my computer is big
if subdirname not in self.world_blacklist:
self.world_name = subdirname
self.world_path = os.path.join(dirname, subdirname) # os.path.join(self.worlds_path, "try7amber")
print (" CHOSE "+self.world_path)
auto_chosen_world = True
break
index += 1
#index += 1
if auto_chosen_world:
break
self.python_exe_path = "python"
@ -132,11 +176,82 @@ class MTChunks:
self.chunkx_max = 0
self.chunkz_max = 0
self.chunk_size = 80
self.maxheight = 50
self.minheight = -25
self.chunk_size = 16
self.maxheight = 64
self.minheight = -32
self.pixelspernode = 1
def set_from_genresult(self, mtchunk, chunk_luid):
dest_genresult_path = self.get_chunk_genresult_path(chunk_luid)
result = False
if os.path.isfile(dest_genresult_path):
#may have data such as:
#Result image (w=80 h=80) will be written to chunk_x0z0.png
#Unknown node names: meze:meze default:stone_with_iron air default:dirt_with_snow default:stone_with_copper default:snow
#Unknown node ids: 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7
#Drawing image
#Saving to: chunk_x0z0.png
#('PNG Region: ', [0, 64, 0, 64])
#('Pixels PerNode: ', 1)
#('border: ', 0)
mtchunk.is_marked = True
ins = open(dest_genresult_path, 'r')
line = True
while line:
line = ins.readline()
if line:
line_strip = line.strip()
if "data does not exist" in line_strip:
mtchunk.is_marked_empty = True
break
elif "Result image" in line_strip:
oparen_index = line_strip.find("(")
if (oparen_index>-1):
cparen_index = line_strip.find(")", oparen_index+1)
if (cparen_index>-1):
operations_string = line_strip[oparen_index+1:cparen_index]
operation_list = operations_string.split(" ")
#if len(operation_list)==2:
for operation_string in operation_list:
if "=" in operation_string:
chunks = operation_string.split("=")
if len(chunks)==2:
if chunks[0].strip()=="w":
try:
mtchunk.image_w=int(chunks[1].strip())
except:
print("Bad value for image w:"+str(chunks[1]))
elif chunks[0].strip()=="h":
try:
mtchunk.image_h=int(chunks[1].strip())
except:
print("Bad value for image h:"+str(chunks[1]))
else:
print("Bad name for image variable so ignoring variable named '"+str(chunks[0])+"'")
else:
print("Bad assignment (not 2 sides) so ignoring command '"+operation_string+"'")
else:
print("Bad assignment (operator) so ignoring command '"+operation_string+"'")
#else:
# print("Bad assignment count so ignoring operations string '"+operations_string+"'")
elif "PNG Region" in line_strip:
obracket_index = line_strip.find("[")
if obracket_index>-1:
cbracket_index = line_strip.find("]", obracket_index+1)
if cbracket_index>-1:
rect_values_string = line_strip[obracket_index+1:cbracket_index]
rect_values_list = rect_values_string.split(",")
if len(rect_values_list)==4:
#pngregion=[pngminx, pngmaxx, pngminz, pngmaxz] #from minetestmapper-numpy.py
mtchunk.image_left=int(rect_values_list[0].strip())
mtchunk.image_right=int(rect_values_list[1].strip())
mtchunk.image_top=int(rect_values_list[2].strip())
mtchunk.image_bottom=int(rect_values_list[3].strip())
else:
print("Bad map rect, so ignoring: "+rect_values_string)
ins.close()
def get_dict_from_conf_file(self, path,assignment_operator="="):
results = None
print ("Checking "+str(path)+" for settings...")
@ -196,22 +311,67 @@ class MTChunks:
def get_chunk_genresult_tmp_path(self, chunk_luid):
return os.path.join(os.path.dirname(__file__), self.get_chunk_genresult_name(chunk_luid))
def get_chunk_yaml_name(self, chunk_luid):
return "chunk_"+chunk_luid+".yml"
def is_chunk_yaml_present(self, chunk_luid):
return os.path.isfile(self.get_chunk_yaml_path(chunk_luid))
def get_chunk_yaml_path(self, chunk_luid):
return os.path.join(self.chunkymap_data_path, self.get_chunk_yaml_name(chunk_luid))
def is_chunk_yaml_marked(self, chunk_luid):
yaml_path = self.get_chunk_yaml_path(chunk_luid)
result = False
if os.path.isfile(yaml_path):
result = True
#ins = open(yaml_path, 'r')
#line = True
#while line:
# line = ins.readline()
# if line:
# line_strip = line.strip()
# if "is_marked_empty:" in line_strip:
# result = True
# break
#ins.close()
return result
def is_chunk_yaml_marked_empty(self, chunk_luid):
yaml_path = self.get_chunk_yaml_path(chunk_luid)
result = False
if os.path.isfile(yaml_path):
ins = open(yaml_path, 'r')
line = True
while line:
line = ins.readline()
if line:
line_strip = line.strip()
prevalue_string="is_marked_empty:"
if line_strip[:len(prevalue_string)]==prevalue_string:
result = bool(line_strip[len(prevalue_string):].strip())
break
ins.close()
return result
def get_chunk_genresult_path(self, chunk_luid):
return os.path.join(self.chunkymap_data_path, self.get_chunk_genresult_name(chunk_luid))
#deprecated
def is_genresult_marked(self, chunk_luid):
result = False
dest_genresult_path = self.get_chunk_genresult_path(chunk_luid)
#is_empty_chunk = False
if os.path.isfile(dest_genresult_path):
result = True
return result
#deprecated
def is_genresult_marked_empty(self, chunk_luid):
dest_genresult_path = self.get_chunk_genresult_path(chunk_luid)
result = False
if os.path.isfile(dest_genresult_path):
ins = open(dest_genresult_path)
ins = open(dest_genresult_path, 'r')
line = True
while line:
line = ins.readline()
@ -233,29 +393,29 @@ class MTChunks:
def remove_chunk_image(self, chunk_luid):
result = False
png_path = self.get_chunk_image_path(chunk_luid)
if os.path.isfile(png_path):
tmp_png_path = self.get_chunk_image_path(chunk_luid)
if os.path.isfile(tmp_png_path):
result = True
os.remove(png_path)
os.remove(tmp_png_path)
return result
def remove_chunk(self, chunk_luid):
result = False
out_path = self.get_chunk_genresult_path(chunk_luid)
png_path = self.get_chunk_image_path(chunk_luid)
tmp_png_path = self.get_chunk_image_path(chunk_luid)
if os.path.isfile(out_path):
os.remove(out_path)
result = True
if os.path.isfile(png_path):
os.remove(png_path)
if os.path.isfile(tmp_png_path):
os.remove(tmp_png_path)
result = True
return result
def is_chunk_rendered_on_dest(self, chunk_luid): #formerly is_chunk_empty_on_dest (reversed)
is_rendered = False
#is_chunk_out_empty = self.is_genresult_marked_empty(chunk_luid)
#is_chunk_out_empty = self.is_chunk_yaml_marked_empty(chunk_luid)
#dest_genresult_path = self.get_chunk_genresult_path(chunk_luid)
dest_png_path = self.get_chunk_image_name(chunk_luid)
dest_png_path = self.get_chunk_image_path(chunk_luid)
if os.path.isfile(dest_png_path):
#os.remove(dest_genresult_path)
is_rendered = True
@ -269,7 +429,7 @@ class MTChunks:
result = False
chunk_luid = self.get_chunk_luid(x,z)
png_name = self.get_chunk_image_name(chunk_luid)
png_path = self.get_chunk_image_tmp_path(chunk_luid)
tmp_png_path = self.get_chunk_image_tmp_path(chunk_luid)
cmd_suffix = ""
genresult_name = self.get_chunk_genresult_name(chunk_luid)
genresult_path = self.get_chunk_genresult_tmp_path(chunk_luid)
@ -281,13 +441,13 @@ class MTChunks:
z_max = z * self.chunk_size + self.chunk_size - 1
#print ("generating x = " + str(x_min) + " to " + str(x_max) + " , z = " + str(z_min) + " to " + str(z_max))
cmd_string = self.python_exe_path + " \""+self.mtmn_path + "\" --region " + str(x_min) + " " + str(x_max) + " " + str(z_min) + " " + str(z_max) + " --maxheight "+str(self.maxheight)+" --minheight "+str(self.minheight)+" --pixelspernode "+str(self.pixelspernode)+" \""+self.world_path+"\" \""+png_path+"\"" + cmd_suffix
cmd_string = self.python_exe_path + " \""+self.mtmn_path + "\" --region " + str(x_min) + " " + str(x_max) + " " + str(z_min) + " " + str(z_max) + " --maxheight "+str(self.maxheight)+" --minheight "+str(self.minheight)+" --pixelspernode "+str(self.pixelspernode)+" \""+self.world_path+"\" \""+tmp_png_path+"\"" + cmd_suffix
dest_png_path = self.get_chunk_image_path(chunk_luid)
dest_genresult_path = self.get_chunk_genresult_path(chunk_luid)
#is_empty_chunk = is_genresult_marked(chunk_luid) and is_genresult_marked_empty(chunk_luid)
#is_empty_chunk = is_chunk_yaml_marked(chunk_luid) and is_chunk_yaml_marked_empty(chunk_luid)
print (cmd_string)
subprocess.call(cmd_string, shell=True) # TODO: remember not to allow arbitrary command execution, which could happen if input contains ';' when using shell=True
if os.path.isfile(png_path):
if os.path.isfile(tmp_png_path):
result = True
try:
if (os.path.isfile(dest_png_path)):
@ -295,24 +455,34 @@ class MTChunks:
except:
print ("Could not finish deleting '"+dest_png_path+"'")
try:
os.rename(png_path, dest_png_path)
os.rename(tmp_png_path, dest_png_path)
print("(moved to '"+dest_png_path+"')")
self.prepare_chunk_meta(chunk_luid)
self.chunks[chunk_luid].is_fresh = True
except:
print ("Could not finish moving '"+png_path+"' to '"+dest_png_path+"'")
print ("Could not finish moving '"+tmp_png_path+"' to '"+dest_png_path+"'")
try:
if (os.path.isfile(dest_genresult_path)):
os.remove(dest_genresult_path)
if self.is_save_output_ok:
os.rename(genresult_path, dest_genresult_path)
print("(moved to '"+dest_genresult_path+"')")
#os.rename(genresult_path, dest_genresult_path)
#print("(moved to '"+dest_genresult_path+"')")
tmp_chunk = MTChunk()
self.set_from_genresult(tmp_chunk,chunk_luid)
chunk_yaml_path = self.get_chunk_yaml_path(chunk_luid)
tmp_chunk.save_yaml(chunk_yaml_path)
print("(saved yaml to '"+chunk_yaml_path+"')")
os.remove(genresult_path)
else:
if os.path.isfile(genresult_path):
os.remove(genresult_path)
except:
print ("Could not finish deleting/moving output")
return result
def check_players(self):
@ -326,6 +496,8 @@ class MTChunks:
self.deny_http_access(chunkymap_players_path)
players_path = os.path.join(self.world_path, "players")
player_count = 0
player_written_count = 0
for dirname, dirnames, filenames in os.walk(players_path):
for filename in filenames:
file_fullname = os.path.join(players_path,filename)
@ -334,9 +506,9 @@ class MTChunks:
player_name = None
player_position = None
if (filename[:len(badstart_string)]!=badstart_string):
ins = open(file_fullname)
ins = open(file_fullname, 'r')
line = True
has_enough_data = False
is_enough_data = False
while line:
line = ins.readline()
if line:
@ -350,7 +522,7 @@ class MTChunks:
player_position = found_value
if (player_name is not None) and (player_position is not None):
has_enough_data = True
is_enough_data = True
break
ins.close()
player_dest_path = os.path.join(chunkymap_players_path,filename+".yml")
@ -359,30 +531,45 @@ class MTChunks:
tuple_noparen_pos_string = player_position.strip("() \n\r")
pos_strings = tuple_noparen_pos_string.split(",")
if len(pos_strings) == 3:
player_x = int(pos_strings[player_x])
player_y = int(pos_strings[player_y])
player_z = int(pos_strings[player_z])
player_x = None
player_y = None
player_z = None
try:
player_x = float(pos_strings[0])
player_y = float(pos_strings[1])
player_z = float(pos_strings[2])
except:
player_x = int(pos_strings[0])
player_y = int(pos_strings[1])
player_z = int(pos_strings[2])
chunk_x = int((float(player_x)/self.chunk_size))
chunk_y = int((float(player_y)/self.chunk_size))
chunk_z = int((float(player_z)/self.chunk_size))
chunk_luid = self.get_chunk_luid(chunk_x, chunk_z)
self.prepare_chunk_meta()
self.chunks[chunk_luid].is_player_here = True
self.prepare_chunk_meta(chunk_luid)
self.chunks[chunk_luid].is_player_in_this_chunk = True
else:
print("Player '"+filename+"' has bad position data--should be 3-length (x,y,z) in position value: "+str(pos_strings))
if has_enough_data:
#if is_enough_data:
#if player_name!="singleplayer":
map_player_dict = self.get_dict_from_conf_file(player_dest_path,":")
if (map_player_dict is None) or (map_player_dict["position"]!=player_position):
outs = open(player_dest_path, 'w')
if player_name is not None:
outs.write("name:"+player_name+"\n") # python automatically uses correct newline for your os when you put "\n"
if player_position is not None:
outs.write("position:"+player_position+"\n")
outs.write("is_enough_data:"+str(is_enough_data))
outs.close()
player_written_count += 1
player_count += 1
def is_player_at_luid(self, chunk_luid):
result = False
if chunk_luid in self.chunks.keys():
result = self.chunks[chunk_luid].is_player_here
result = self.chunks[chunk_luid].is_player_in_this_chunk
return result
def is_chunk_fresh(self, chunk_luid):
@ -396,7 +583,7 @@ class MTChunks:
self.check_players()
self.chunkymap_data_path=os.path.join(self.website_root,"chunkymapdata")
yaml_name = "generated.yml"
yaml_path = os.path.join(self.chunkymap_data_path, yaml_name)
world_yaml_path = os.path.join(self.chunkymap_data_path, yaml_name)
if not os.path.isdir(self.chunkymap_data_path):
os.mkdir(self.chunkymap_data_path)
@ -406,21 +593,22 @@ class MTChunks:
if not os.path.isfile(htaccess_path):
self.deny_http_access(self.chunkymap_data_path)
mapvars = self.get_dict_from_conf_file(yaml_path,":")
mapvars = self.get_dict_from_conf_file(world_yaml_path,":")
#is_testonly == (os_name=="windows")
if mapvars is not None and set(['self.world_name']).issubset(mapvars):
if mapvars is not None and set(['world_name']).issubset(mapvars):
#print (" (FOUND self.world_name)")
if mapvars["self.world_name"] != self.world_name:
print ("REMOVING data since from different world (map '"+str(mapvars["self.world_name"])+"' is not '"+str(self.world_name)+"')...")
if mapvars["world_name"] != self.world_name:
print ("REMOVING data since from different world (map '"+str(mapvars["world_name"])+"' is not '"+str(self.world_name)+"')...")
for dirname, dirnames, filenames in os.walk(self.chunkymap_data_path):
index = 0
for j in range(0,len(filenames)):
i = len(filenames) - 0 - 1
if filenames[i][0] == ".":
print (" SKIPPING "+filenames[i])
filenames.remove_at(i)
#index = 0
#for j in range(0,len(filenames)):
# i = len(filenames) - 0 - 1
# if filenames[i][0] == ".":
# print (" SKIPPING "+filenames[i])
# filenames.remove_at(i)
for filename in filenames:
if filename[0] != ".":
file_fullname = os.path.join(self.chunkymap_data_path,filename)
print (" EXAMINING "+filename)
badstart_string = "chunk"
@ -428,7 +616,19 @@ class MTChunks:
os.remove(file_fullname)
elif filename==yaml_name:
os.remove(file_fullname)
for dirname, dirnames, filenames in os.walk(os.path.join(self.chunkymap_data_path, "players")):
#for j in range(0,len(filenames)):
# i = len(filenames) - 0 - 1
# if filenames[i][0] == ".":
# print (" SKIPPING "+filenames[i])
# filenames.remove_at(i)
for filename in filenames:
if filename[0] != ".":
file_fullname = os.path.join(self.chunkymap_data_path,filename)
print (" EXAMINING "+filename)
badend_string = ".yml"
if (len(filename) >= len(badend_string)) and (filename[len(filename)-len(badend_string):]==badend_string):
os.remove(file_fullname)
self.chunkx_min = 0
self.chunkz_min = 0
self.chunkx_max = 0
@ -437,6 +637,12 @@ class MTChunks:
newchunk_luid_list = list()
outline_generates_count = 1
is_changed = False
is_different_world = False
#if str(self.world_name) != str(mapvars["world_name"]):
# is_different_world = True
# print("FULL RENDER since chosen world name '"+self.world_name+"' does not match previously rendered world name '"+mapvars["world_name"]+"'")
while outline_generates_count > 0:
outline_generates_count = 0
for z in range (self.chunkz_min,self.chunkz_max+1):
@ -449,32 +655,44 @@ class MTChunks:
if is_outline:
chunk_luid = self.get_chunk_luid(x,z)
is_player_here = self.is_player_at_luid(chunk_luid)
#if (is_different_world): #instead, see above where all chunk files and player files are deleted
# self.remove_chunk(chunk_luid)
is_player_in_this_chunk = self.is_player_at_luid(chunk_luid)
is_render_needed = False
if not self.is_chunk_fresh(chunk_luid):
if is_player_here:
if self.is_genresult_marked(chunk_luid):
if self.is_genresult_marked_empty(chunk_luid):
if is_player_in_this_chunk:
if self.is_chunk_yaml_marked(chunk_luid):
if self.is_chunk_yaml_marked_empty(chunk_luid):
is_render_needed = True
print (chunk_luid+": RENDERING non-fresh marked empty chunk (player present in it)")
print (chunk_luid+": RENDERING nonfresh previously marked empty (player in it)")
else:
print (chunk_luid+": SKIPPING non-fresh marked chunk (player present in it)")
print (chunk_luid+": SKIPPING nonfresh previously marked (player in it)")
else:
is_render_needed = True
print (chunk_luid+": RENDERING non-fresh unmarked chunk (player present in it)")
print (chunk_luid+": RENDERING nonfresh unmarked (player in it)")
else:
if (not self.is_genresult_marked(chunk_luid)):
if (not self.is_chunk_yaml_marked(chunk_luid)):
is_render_needed = True
print (chunk_luid+": RENDERING non-fresh unmarked chunk (skipped other checks since player not present in it)")
print (chunk_luid+": RENDERING nonfresh unmarked (simple check since has no player)")
else:
print (chunk_luid+": SKIPPING non-fresh marked chunk (skipped other checks since player not present in it)")
print (chunk_luid+": SKIPPING nonfresh previously marked (simple check since has no player)")
else:
print (chunk_luid+": SKIPPING fresh chunk")
#if (not self.is_genresult_marked(chunk_luid)):
#if (not self.is_chunk_yaml_marked(chunk_luid)):
#is_render_needed = True
# This should never happen since keeping the output of minetestmapper-numpy.py (after analyzing that output) is deprecated:
#if self.is_genresult_marked(chunk_luid) and not self.is_chunk_yaml_present(chunk_luid):
# tmp_chunk = MTChunk()
# self.set_from_genresult(tmp_chunk,chunk_luid)
# chunk_yaml_path = self.get_chunk_yaml_path(chunk_luid)
# tmp_chunk.save_yaml(chunk_yaml_path)
# print("(saved yaml to '"+chunk_yaml_path+"')")
if is_render_needed:
if (self.render_chunk(x,z)):
total_generated_count += 1
@ -483,10 +701,12 @@ class MTChunks:
if self.is_chunk_rendered_on_dest(chunk_luid):
total_generated_count += 1
outline_generates_count += 1
png_path = self.get_chunk_image_path(chunk_luid)
print(chunk_luid+": Skipping existing map tile file " + png_path + " (delete it to re-render)")
tmp_png_path = self.get_chunk_image_path(chunk_luid)
print(chunk_luid+": Skipping existing map tile file " + tmp_png_path + " (delete it to re-render)")
#elif is_empty_chunk:
#print("Skipping empty chunk " + chunk_luid)
#else:
#print(chunk_luid+": Not rendered on dest.")
print ("") # blank line before next z so output is more readable
self.chunkx_min -= 1
self.chunkz_min -= 1
@ -506,22 +726,21 @@ class MTChunks:
new_map_dict["world_path"]=str(self.world_path)
new_map_dict["chunkymap_data_path"]=str(self.chunkymap_data_path)
new_map_dict["total_generated_count"]=str(total_generated_count)
is_changed = False
if mapvars is None:
print ("SAVING '" + yaml_path + "' since nothing was loaded or it did not exist")
print ("SAVING '" + world_yaml_path + "' since nothing was loaded or it did not exist")
is_changed = True
else:
for this_key in new_map_dict.iterkeys():
if (this_key not in mapvars.keys()):
is_changed = True
print ("SAVING '" + yaml_path + "' since " + str(this_key) + " not in mapvars")
print ("SAVING '" + world_yaml_path + "' since " + str(this_key) + " not in mapvars")
break
elif (str(mapvars[this_key]) != str(new_map_dict[this_key])):
is_changed = True
print ("SAVING '" + yaml_path + "' since new " + this_key + " value " + str(mapvars[this_key]) + " not same as saved value " + str(mapvars[this_key]) + "")
print ("SAVING '" + world_yaml_path + "' since new " + this_key + " value " + str(new_map_dict[this_key]) + " not same as saved value " + str(mapvars[this_key]) + "")
break
if is_changed:
outs = open(yaml_path, 'w')
outs = open(world_yaml_path, 'w')
outs.write("world_name:"+str(self.world_name) + "\n")
outs.write("chunk_size:"+str(self.chunk_size) + "\n")
outs.write("pixelspernode:"+str(self.pixelspernode) + "\n")
@ -538,7 +757,7 @@ class MTChunks:
outs.write("total_generated_count:"+str(total_generated_count) + "\n")
outs.close()
else:
print ("(Not saving '"+yaml_path+"' since same value of each current variable is already in file as loaded)")
print ("(Not saving '"+world_yaml_path+"' since same value of each current variable is already in file as loaded)")
else:
print ("failed since this folder must contain colors.txt and minetestmapper-numpy.py")

170
web/chunkymap.php

@ -2,6 +2,7 @@
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
//NOTE: for parse errors, MUST add the following line to php.ini (such as /etc/php5/apache2/php.ini): display_errors = on
if (is_file('browser.php')) {
include_once('browser.php');
@ -259,6 +260,65 @@ function echo_chunkymap_table() {
$chunkz_min = 0;
$chunkx_max = 0;
$chunkz_max = 0;
global $showplayers;
$players = array();
$player_count = 0;
if ($showplayers==true) {
$chunkymap_players_path = $chunkymapdata_path."/players";
if ($handle = opendir($chunkymap_players_path)) {
while (false !== ($file = readdir($handle))) {
if (substr($file, 0, 1) != ".") {
$file_lower = strtolower($file);
if (endsWith($file_lower, ".yml")) {
$player_id=substr($file,0,strlen($file)-4); //-4 for .yml
$file_path = $chunkymap_players_path."/".$file;
$player_dict = get_dict_from_conf($file_path);
$player_dict["id"]=$player_id;
//$players[$player_count]=get_dict_from_conf($file_path);
//$players[$player_count]["id"]=$player_id;
if (isset($player_dict["position"])) {
$tuple_string=trim($player_dict["position"]);
if ( startsWith($tuple_string, "(") and endsWith($tuple_string, ")") ) {
$tuple_string=substr($tuple_string,1,strlen($tuple_string)-2);
}
$coordinates = explode(",", $tuple_string);
if (count($coordinates)==3) {
$chunk_luid = "x".$x."z".$z;
if (!isset($chunk_assoc[$chunk_luid])) {
$chunk_assoc[$chunk_luid] = array();
}
if (!isset($chunk_assoc[$chunk_luid]["players"])) {
$chunk_assoc[$chunk_luid]["players"] = array();
}
if (!isset($chunk_assoc[$chunk_luid]["players_count"])) {
$chunk_assoc[$chunk_luid]["players_count"] = 0;
}
if (isset($player_dict["name"])) {
$chunk_assoc[$chunk_luid][ "players" ][ $chunk_assoc[$chunk_luid]["players_count"] ][ "name" ] = $player_dict["name"]
}
else {
$chunk_assoc[$chunk_luid][ "players" ][ $chunk_assoc[$chunk_luid]["players_count"] ][ "name" ] = $player_dict["id"]
}
$chunk_assoc[$chunk_luid]["players_count"] += 1;
}
else {
echo_error("Bad coordinates $tuple_string for player.");
}
}
//$player_count++;
}
}
}
}
}
if (isset($chunk_assoc[$chunk_luid]["players_count"])) {
$nonprivate_name_beginning_char_count = 2;
for ($player_count=0; $player_count<$chunk_assoc[$chunk_luid]["players_count"]; $player_count++) {
//echo "<div >".substr($chunk_assoc[$chunk_luid]["players"][$player_count]["name"], 0, $nonprivate_name_beginning_char_count)."</div>";
}
}
//if ($map_dict != null) {
// $chunkx_min = $map_dict["chunkx_min"];
// $chunkz_min = $map_dict["chunkz_min"];
@ -281,7 +341,10 @@ function echo_chunkymap_table() {
$z = substr($file_lower, $z_opener_index + strlen($z_opener), $z_len);
if (is_int_string($x) and is_int_string($z)) {
$chunk_luid = "x".$x."z".$z;
$chunk_assoc[$chunk_luid] = true;
if (!isset($chunk_assoc[$chunk_luid])) {
$chunk_assoc[$chunk_luid] = array();
}
$chunk_assoc[$chunk_luid]["is_rendered"] = true;
if ($is_verbose) echo "$chunk_luid,";
if ($x<$chunkx_min) {
$chunkx_min=(int)$x;
@ -320,22 +383,123 @@ function echo_chunkymap_table() {
$scale=(float)$chunkymap_view_zoom_multiplier; // no longer /100
$zoomed_w=(int)((float)$chunkymap_tile_original_w*$scale+.5);
$zoomed_h=(int)((float)$chunkymap_tile_original_h*$scale+.5);
$genresult_suffix_then_dot_then_ext="_mapper_result.txt";
$dot_yaml=".yml";
while ($z >= $chunkz_min) {
echo_hold( " <tr>\r\n");
$x = (int)$chunkx_min;
while ($x <= $chunkx_max) {
echo_hold( " <td width=\"1\" style=\"padding:0px; background-color:lightgray\">");
$this_zoomed_w = $zoomed_w;
$this_zoomed_h = $zoomed_h;
$chunk_yaml_name = $x_opener.$x.$z_opener.$z.$dot_yaml;
$chunk_yaml_path = $chunkymapdata_path.'/'.$chunk_yaml_name;
//$chunk_genresult_name = $x_opener.$x.$z_opener.$z.$genresult_suffix_then_dot_then_ext;
//$chunk_genresult_path = $chunkymapdata_path.'/'.$chunk_img_name;
$td_style_suffix="";
$element_align_style_suffix="";
$alignment_comment="";
//if (is_file($chunk_genresult_path)) {
// contains lines such as:
// Result image (w=80 h=64) will be written to chunk_x0z1.png
// ('PNG Region: ', [0, 64, 80, 128])
// ('Pixels PerNode: ', 1)
// where PNG Region's list value is an exclusive rect ordered as x1, y1, x2, y2
//$found_original_w = null;
//$found_original_h = null;
//$this_zoomed_w=(int)((float)$found_original_w*$scale+.5);
//this_zoomed_h=(int)((float)$found_original_h*$scale+.5);
//}
if (is_file($chunk_yaml_path)) {
// contains lines such as:
//is_marked_empty:False
//is_marked:True
//image_w:80
//image_h:80
//image_left:0
//image_top:64
//image_right:-80
//image_bottom:-16
// where if is_marked_empty, the remaining values don't exist
$expected_left = (int)$x * (int)$chunkymap_tile_original_w;
$expected_top = (int)$z * (int)$chunkymap_tile_original_h;
$expected_right = (int)$x + (int)$chunkymap_tile_original_w;
$expected_bottom = (int)$z + (int)$chunkymap_tile_original_h;
$chunk_dict = get_dict_from_conf($chunk_yaml_path,":");
if (isset($chunk_dict["image_w"])) {
$this_zoomed_w=(int)((float)$chunk_dict["image_w"]*$scale+.5);
}
if (isset($chunk_dict["image_h"])) {
$this_zoomed_h=(int)((float)$chunk_dict["image_h"]*$scale+.5);
}
//TODO: use image_* to determine (if the doesn't touch certain sides of image_w x image_h rect, change the following accordingly)
if (isset($chunk_dict["image_left"])) {
if (isset($chunk_dict["image_right"])) {
if ( (int)$chunk_dict["image_left"] > $expected_left ) {
$td_style_suffix.="text-align:right;";
$alignment_comment.="<!-- image_left:".$chunk_dict["image_left"]." is greater than expected $expected_left-->";
}
//elseif ( (int)$chunk_dict["image_right"] < $expected_right ) {
// $td_style_suffix.="text-align:left;";
//}
else {
$td_style_suffix.="text-align:left;";
$alignment_comment.="<!-- image_left:".$chunk_dict["image_left"]." was the expected $expected_left-->";
}
}
}
//if (isset($chunk_dict["image_right"])) {
// if ( (int)$chunk_dict["image_right"] != $expected_right ) {
// $td_style_suffix.="text-align:left;";
// }
// //else {
// // $td_style_suffix.="text-align:left;";
// //}
//}
if (isset($chunk_dict["image_top"])) {
if (isset($chunk_dict["image_bottom"])) {
if ( (int)$chunk_dict["image_top"] > $expected_top) {
$element_align_style_suffix.="vertical-align:bottom;";
$alignment_comment.="<!-- image_top:".$chunk_dict["image_top"]." is greater than expected $expected_top-->";
}
//elseif ( (int)$chunk_dict["image_bottom"] < $expected_bottom) {
// $element_align_style_suffix.="vertical-align:top;";
//}
else {
$element_align_style_suffix.="vertical-align:top;";
$alignment_comment.="<!-- image_top:".$chunk_dict["image_top"]." was the expected $expected_top-->";
}
}
}
//if (isset($chunk_dict["image_bottom"])) {
// if ( (int)$chunk_dict["image_bottom"] != $expected_bottom) {
// $element_align_style_suffix.="vertical-align:top;";
// }
// //else {
// // $element_align_style_suffix.="vertical-align:bottom;";
// //}
//}
//$element_align_style_suffix.="vertical-align:left;";
}
echo_hold( " <td width=\"1\" style=\"padding:0px; background-color:lightgray; $td_style_suffix $element_align_style_suffix\">");
$chunk_luid = "x".$x."z".$z;
$chunk_img_name = $x_opener.$x.$z_opener.$z."$dot_and_ext";
$chunk_img_path = $chunkymapdata_path.'/'.$chunk_img_name;
if (is_file($chunk_img_path)) {
echo_hold( "<img style=\"width:$zoomed_w; height:$zoomed_h\" class=\"maptileimg\" src=\"$chunk_img_path\"");
echo_hold( "<img class=\"maptileimg\" style=\"width:$this_zoomed_w; height:$this_zoomed_h;\" src=\"$chunk_img_path\"/>");
}
else {
//echo_hold( "<span style=\"font-size:1px\">&nbsp;</span>");
}
//echo " <br/>".$x.",0,".$z;
echo_hold($alignment_comment);
echo_hold( "</td>\r\n");
$x++;
}

3
web/index-example.php

@ -2,6 +2,9 @@
<title>Chunkymap Example Page</title>
<body style="font-family:calibri,sans">
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
//echo "php started...";
if (is_file('chunkymap.php')) {
//echo "including...";

Loading…
Cancel
Save