Browse Source

improved modularization and freshness detection

ready to be main event loop but loop not programmed yet
master
poikilos 10 years ago
committed by Jacob Gustafson
parent
commit
cacaa892cf
  1. 918
      chunkymap-regen.py

918
chunkymap-regen.py

@ -3,431 +3,549 @@ import os
import subprocess import subprocess
# REQUIRES: see README.md # REQUIRES: see README.md
# The way to do a full render is deleting all files from the folder chunkymap_data_path such as /var/www/html/minetest/chunkymapdata (or chunkymap in current directory on Windows) # 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)
#minetestmapper-numpy.py calculates the region as follows: #minetestmapper-numpy.py calculates the region as follows:
#(XMIN','XMAX','ZMIN','ZMAX'), default = (-2000,2000,-2000,2000) #(XMIN','XMAX','ZMIN','ZMAX'), default = (-2000,2000,-2000,2000)
#sector_xmin,sector_xmax,sector_zmin,sector_zmax = numpy.array(args.region)/16 #sector_xmin,sector_xmax,sector_zmin,sector_zmax = numpy.array(args.region)/16
#sector_ymin = args.minheight/16 #sector_ymin = args.self.minheight/16
#sector_ymax = args.maxheight/16 #sector_ymax = args.self.maxheight/16
#region server-specific options #region server-specific options
input_string = ""
username = "owner"
os_name="linux"
if (os.path.sep!="/"):
os_name="windows"
#input_string = input("Which username contains minetest/util/minetestmapper-numpy.py (minetest not .minetest) ["+username+"]?")
if (len(input_string)>0):
username = input_string
website_root="/var/www/html/minetest"
chunkymap_data_path=os.path.join(website_root,"chunkymapdata")
#input_string = input("What is the root folder of your minetest website ["+website_root+"]?")
if (len(input_string)>0):
website_root = input_string
world_name = "FCAGameAWorld"
#input_string = input("What is the game name ["+world_name+"]")
if (len(input_string)>0):
world_name = input_string
#region server-specific options
profiles_path = "/home"
if os_name=="windows":
profiles_path = "C:\\Users"
profile_path = os.path.join(profiles_path, username)
#if (not os.path.isdir(profile_path)):
# profile_path = os.path.join(profiles_path, "jgustafson")
dotminetest_path = os.path.join(profile_path,".minetest")
if (os_name=="windows"): dotminetest_path = "C:\\games\\Minetest"
worlds_path = os.path.join(dotminetest_path,"worlds")
world_path = os.path.join(worlds_path, world_name)
auto_chosen_world = False
if not os.path.isdir(world_path):
#for item in os.walk(worlds_path):
print ("LOOKING FOR WORLDS IN " + worlds_path)
for dirname, dirnames, filenames in os.walk(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)
for subdirname in dirnames:
print (" EXAMINING "+subdirname)
if (index == len(dirnames)-1): # skip first one because the one on my computer is big
world_name = subdirname
world_path = os.path.join(dirname, subdirname) # os.path.join(worlds_path, "try7amber")
print (" CHOSE "+world_path)
auto_chosen_world = True
break
index += 1
if auto_chosen_world:
break
python_exe_path = "python"
try:
alt_path = "C:\\python27\python.exe"
if os.path.isfile(alt_path):
python_exe_path = alt_path
except:
pass # do nothing, probably linux
mtmn_path = os.path.join( profile_path, "minetest/util/minetestmapper-numpy.py" )
colors_path = os.path.join( profile_path, "minetest/util/colors.txt" )
if os_name=="windows":
mtmn_path = os.path.join(os.path.dirname(__file__), "minetestmapper-numpy.py")
colors_path = os.path.join(os.path.dirname(__file__), "colors.txt")
website_root = os.path.dirname(__file__)
class MTChunk: class MTChunk:
x = None x = None
z = None z = None
is_player_here = None is_player_here = None
is_fresh = None
def __init__(self): def __init__(self):
self.is_player_here = False self.is_player_here = False
self.is_fresh = False
class MTChunks:
is_save_output_ok = True
website_root = None
def get_dict_from_conf_file(path,assignment_operator="="): username = None
results = None os_name = None
print ("Checking "+str(path)+" for settings...") chunkymap_data_path = None
if os.path.isfile(path): profiles_path = None
results = {} profile_path = None
ins = open(path, 'r') worlds_path = None
line = True is_save_output_ok = None
while line: mtmn_path = None
line = ins.readline() colors_path = None
if line and len(line)>0: python_exe_path = None
line_strip=line.strip() chunks = None
if not line_strip[0]=="#": # if not comment
if not line_strip[0]=="-": # ignore yaml arrays
ao_index = line_strip.find(assignment_operator)
if ao_index>=1: # intentionally skip zero-length variable names
if ao_index<len(line_strip)-1: # skip yaml implicit nulls or yaml objects
result_name = line_strip[:ao_index].strip()
result_value = line_strip[ao_index+1:].strip()
print (" CHECKING... "+result_name+":"+result_value)
results[result_name]=result_value
ins.close()
return results
def deny_http_access(dir_path):
htaccess_name = ".htaccess"
htaccess_path = os.path.join(dir_path, htaccess_name)
outs = open(htaccess_path, 'w')
outs.write("IndexIgnore *"+"\n")
outs.write("<Files .htaccess>"+"\n")
outs.write("order allow,deny"+"\n")
outs.write("deny from all"+"\n")
outs.write("</Files>"+"\n")
outs.write("<Files *.php>"+"\n")
outs.write("order allow,deny"+"\n")
outs.write("deny from all"+"\n")
outs.write("</Files>"+"\n")
outs.close()
#locally unique identifier (unique to world only)
def get_chunk_luid(x,z):
return "x"+str(x)+"z"+str(z)
def get_chunk_image_name(chunk_luid):
return "chunk_"+chunk_luid+".png"
def get_chunk_image_tmp_path(chunk_luid):
return os.path.join(os.path.dirname(__file__), get_chunk_image_name(chunk_luid))
def get_chunk_image_path(chunk_luid):
return os.path.join(chunkymap_data_path, get_chunk_image_name(chunk_luid))
def get_chunk_mapper_out_name(chunk_luid):
return "chunk_"+chunk_luid+"_mapper_result.txt"
def get_chunk_mapper_out_tmp_path(chunk_luid):
return os.path.join(os.path.dirname(__file__), get_chunk_mapper_out_name(chunk_luid))
def get_chunk_mapper_out_path(chunk_luid):
return os.path.join(chunkymap_data_path, get_chunk_mapper_out_name(chunk_luid))
def remove_chunk(chunk_luid):
result = False
out_path = get_chunk_mapper_out_path(chunk_luid)
png_path = 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)
result = True
return result
def is_mapper_out_marked(chunk_luid):
result = False
dest_mapper_out_path = get_chunk_mapper_out_path(chunk_luid)
#is_empty_chunk = False
if os.path.isfile(dest_mapper_out_path):
result = True
return result
def is_mapper_out_marked_empty(chunk_luid):
dest_mapper_out_path = get_chunk_mapper_out_path(chunk_luid)
result = False
if os.path.isfile(dest_mapper_out_path):
ins = open(dest_mapper_out_path)
line = True
while line:
line = ins.readline()
if line:
line_strip = line.strip()
if "data does not exist" in line_strip:
result = True
break
ins.close()
return result
def remove_mapper_out(chunk_luid):
dest_mapper_out_path = get_chunk_mapper_out_path(chunk_luid)
if os.path.isfile(dest_mapper_out_path):
os.remove(dest_mapper_out_path)
def remove_chunk_image(chunk_luid):
png_path = get_chunk_image_path(chunk_luid)
if os.path.isfile(png_path):
os.remove(png_path)
def is_chunk_rendered_on_dest(chunk_luid): #formerly is_chunk_empty_on_dest (reversed)
is_rendered = False
#is_chunk_out_empty = is_mapper_out_marked_empty(chunk_luid)
#dest_mapper_out_path = get_chunk_mapper_out_path(chunk_luid)
dest_png_path = get_chunk_image_name(chunk_luid)
if os.path.isfile(dest_png_path):
#os.remove(dest_mapper_out_path)
is_rendered = True
return is_rendered
if os.path.isfile(mtmn_path) and os.path.isfile(colors_path):
chunkymap_data_path=os.path.join(website_root,"chunkymapdata")
yaml_name = "generated.yml"
yaml_path = os.path.join(chunkymap_data_path, yaml_name)
if not os.path.isdir(chunkymap_data_path):
os.mkdir(chunkymap_data_path)
chunkymap_players_name = "players"
chunkymap_players_path = os.path.join(chunkymap_data_path, chunkymap_players_name)
htaccess_path = os.path.join(chunkymap_data_path,".htaccess")
if not os.path.isdir(chunkymap_players_path):
os.makedirs(chunkymap_players_path)
if not os.path.isfile(htaccess_path):
deny_http_access(chunkymap_data_path)
htaccess_path = os.path.join(chunkymap_players_path,".htaccess")
if not os.path.isfile(htaccess_path):
deny_http_access(chunkymap_players_path)
if not os.path.isdir(chunkymap_players_path):
os.makedirs(chunkymap_players_path)
players_path = os.path.join(world_path, "players")
for dirname, dirnames, filenames in os.walk(players_path):
for filename in filenames:
file_fullname = os.path.join(players_path,filename)
#print (" EXAMINING "+filename)
badstart_string = "."
player_name = None
player_position = None
if (filename[:len(badstart_string)]!=badstart_string):
ins = open(file_fullname)
line = True
has_enough_data = False
while line:
line = ins.readline()
if line:
ao_index = line.find("=")
if ao_index > 0:
found_name = line[:ao_index].strip()
found_value = line[ao_index+1:].strip()
if found_name=="name":
player_name = found_value
elif found_name=="position":
player_position = found_value
if (player_name is not None) and (player_position is not None):
has_enough_data = True
break
ins.close()
player_dest_path = os.path.join(chunkymap_players_path,filename+".yml")
if has_enough_data:
#if player_name!="singleplayer":
map_player_dict = 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')
outs.write("name:"+player_name+"\n") # python automatically uses correct newline for your os when you put "\n"
outs.write("position:"+player_position+"\n")
outs.close()
mapvars = get_dict_from_conf_file(yaml_path,":")
#is_testonly == (os_name=="windows")
if mapvars is not None and set(['world_name']).issubset(mapvars):
#print (" (FOUND world_name)")
if mapvars["world_name"] != world_name:
print ("REMOVING data since from different world (map '"+str(mapvars["world_name"])+"' is not '"+str(world_name)+"')...")
for dirname, dirnames, filenames in os.walk(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)
for filename in filenames:
file_fullname = os.path.join(chunkymap_data_path,filename)
print (" EXAMINING "+filename)
badstart_string = "chunk"
if (len(filename) >= len(badstart_string)) and (filename[:len(badstart_string)]==badstart_string):
os.remove(file_fullname)
elif filename==yaml_name:
os.remove(file_fullname)
chunks = {}
#region values to save to YAML #region values to save to YAML
chunk_size = 80 world_name = None
world_path = None
chunkx_min = 0 chunkx_min = 0
chunkz_min = 0 chunkz_min = 0
chunkx_max = 0 chunkx_max = 0
chunkz_max = 0 chunkz_max = 0
total_generated_count = 0 chunk_size = 80
#values for command arguments: #values for command arguments:
maxheight = 50 maxheight = 50
minheight = -25 minheight = -25
pixelspernode = 1 pixelspernode = 1
#ALSO save to YAML: #ALSO save to YAML:
#world_name #total_generated_count = 0
#world_path
#endregion values to save to YAML #endregion values to save to YAML
newchunk_luid_list = list()
square_generates_count = 1 def __init__(self): #formerly checkpaths() in global scope
while square_generates_count > 0: self.chunks = {}
square_generates_count = 0 self.username = "owner"
for z in range (chunkz_min,chunkz_max+1): self.website_root="/var/www/html/minetest"
for x in range(chunkx_min,chunkx_max+1): self.world_name = "FCAGameAWorld"
#python ~/minetest/util/minetestmapper-numpy.py --region -1200 800 -1200 800 --drawscale --maxheight 100 --minheight -50 --pixelspernode 1 ~/.minetest/worlds/FCAGameAWorld ~/map.png os_name="linux"
#sudo mv ~/map.png /var/www/html/minetest/images/map.png
input_string = ""
#only generate the edges (since started with region 0 0 0 0) and expanding from there until no png is created: if (os.path.sep!="/"):
is_outline = (x==chunkx_min) or (x==chunkx_max) or (z==chunkz_min) or (z==chunkz_max) os_name="windows"
if is_outline: #input_string = input("Which self.username contains minetest/util/minetestmapper-numpy.py (minetest not .minetest) ["+self.username+"]?")
chunk_luid = get_chunk_luid(x,z) if (len(input_string)>0):
png_name = get_chunk_image_name(chunk_luid) self.username = input_string
png_path = get_chunk_image_path(chunk_luid)
x_min = x * chunk_size #input_string = input("What is the root folder of your minetest website ["+self.website_root+"]?")
x_max = x * chunk_size + chunk_size - 1 if (len(input_string)>0):
z_min = z * chunk_size self.website_root = input_string
z_max = z * chunk_size + chunk_size - 1 self.chunkymap_data_path=os.path.join(self.website_root,"chunkymapdata")
cmd_suffix = "" #input_string = input("What is the game name ["+self.world_name+"]")
mapper_out_name = get_chunk_mapper_out_name(chunk_luid) if (len(input_string)>0):
mapper_out_path = get_chunk_mapper_out_tmp_path(chunk_luid) self.world_name = input_string
if is_save_output_ok: #region server-specific options
cmd_suffix = " > \""+mapper_out_path+"\"" self.profiles_path = "/home"
#print ("generating x = " + str(x_min) + " to " + str(x_max) + " , z = " + str(z_min) + " to " + str(z_max)) if os_name=="windows":
cmd_string = python_exe_path + " \""+mtmn_path + "\" --region " + str(x_min) + " " + str(x_max) + " " + str(z_min) + " " + str(z_max) + " --maxheight "+str(maxheight)+" --minheight "+str(minheight)+" --pixelspernode "+str(pixelspernode)+" \""+world_path+"\" \""+png_path+"\"" + cmd_suffix self.profiles_path = "C:\\Users"
dest_png_path = get_chunk_image_tmp_path(chunk_luid) self.profile_path = os.path.join(self.profiles_path, self.username)
dest_mapper_out_path = get_chunk_mapper_out_path(chunk_luid) #if (not os.path.isdir(self.profile_path)):
is_empty_chunk = is_chunk_empty_on_dest(chunk_luid) # self.profile_path = os.path.join(self.profiles_path, "jgustafson")
if full_render or ((not os.path.isfile(dest_png_path)) and (not is_empty_chunk)): self.dotminetest_path = os.path.join(self.profile_path,".minetest")
print (cmd_string) if (os_name=="windows"): self.dotminetest_path = "C:\\games\\Minetest"
subprocess.call(cmd_string, shell=True) # TODO: remember not to allow arbitrary command execution, which could happen if input contains ';' when using shell=True self.worlds_path = os.path.join(self.dotminetest_path,"worlds")
if os.path.isfile(png_path): self.world_path = os.path.join(self.worlds_path, self.world_name)
total_generated_count += 1 auto_chosen_world = False
square_generates_count += 1 if not os.path.isdir(self.world_path):
try: #for item in os.walk(self.worlds_path):
if (os.path.isfile(dest_png_path)): print ("LOOKING FOR WORLDS IN " + self.worlds_path)
os.remove(dest_png_path) for dirname, dirnames, filenames in os.walk(self.worlds_path):
except: index = 0
print ("Could not finish deleting '"+dest_png_path+"'") for j in range(0,len(dirnames)):
try: i = len(dirnames) - 0 - 1
os.rename(png_path, dest_png_path) if dirnames[i][0] == ".":
print("(moved to '"+dest_png_path+"')") print (" SKIPPING "+dirnames[i])
except: dirnames.remove_at(i)
print ("Could not finish moving '"+png_path+"' to '"+dest_png_path+"'") for subdirname in dirnames:
try: print (" EXAMINING "+subdirname)
if (os.path.isfile(dest_mapper_out_path)): if (index == len(dirnames)-1): # skip first one because the one on my computer is big
os.remove(dest_mapper_out_path) self.world_name = subdirname
if is_save_output_ok: self.world_path = os.path.join(dirname, subdirname) # os.path.join(self.worlds_path, "try7amber")
os.rename(mapper_out_path, dest_mapper_out_path) print (" CHOSE "+self.world_path)
print("(moved to '"+dest_mapper_out_path+"')") auto_chosen_world = True
break
index += 1
if auto_chosen_world:
break
self.python_exe_path = "python"
self.is_save_output_ok = True # this is probably required to avoid minutely writes
try:
alt_path = "C:\\python27\python.exe"
if os.path.isfile(alt_path):
self.python_exe_path = alt_path
except:
pass # do nothing, probably linux
self.mtmn_path = os.path.join( self.profile_path, "minetest/util/minetestmapper-numpy.py" )
self.colors_path = os.path.join( self.profile_path, "minetest/util/colors.txt" )
if os_name=="windows":
self.mtmn_path = os.path.join(os.path.dirname(__file__), "minetestmapper-numpy.py")
self.colors_path = os.path.join(os.path.dirname(__file__), "colors.txt")
self.website_root = os.path.dirname(__file__)
self.chunkx_min = 0
self.chunkz_min = 0
self.chunkx_max = 0
self.chunkz_max = 0
self.chunk_size = 80
self.maxheight = 50
self.minheight = -25
self.pixelspernode = 1
def get_dict_from_conf_file(self, path,assignment_operator="="):
results = None
print ("Checking "+str(path)+" for settings...")
if os.path.isfile(path):
results = {}
ins = open(path, 'r')
line = True
while line:
line = ins.readline()
if line and len(line)>0:
line_strip=line.strip()
if not line_strip[0]=="#": # if not comment
if not line_strip[0]=="-": # ignore yaml arrays
ao_index = line_strip.find(assignment_operator)
if ao_index>=1: # intentionally skip zero-length variable names
if ao_index<len(line_strip)-1: # skip yaml implicit nulls or yaml objects
result_name = line_strip[:ao_index].strip()
result_value = line_strip[ao_index+1:].strip()
print (" CHECKING... "+result_name+":"+result_value)
results[result_name]=result_value
ins.close()
return results
def deny_http_access(self, dir_path):
htaccess_name = ".htaccess"
htaccess_path = os.path.join(dir_path, htaccess_name)
outs = open(htaccess_path, 'w')
outs.write("IndexIgnore *"+"\n")
outs.write("<Files .htaccess>"+"\n")
outs.write("order allow,deny"+"\n")
outs.write("deny from all"+"\n")
outs.write("</Files>"+"\n")
outs.write("<Files *.php>"+"\n")
outs.write("order allow,deny"+"\n")
outs.write("deny from all"+"\n")
outs.write("</Files>"+"\n")
outs.close()
#locally unique identifier (unique to world only)
def get_chunk_luid(self, x,z):
return "x"+str(x)+"z"+str(z)
def get_chunk_image_name(self, chunk_luid):
return "chunk_"+chunk_luid+".png"
def get_chunk_image_tmp_path(self, chunk_luid):
return os.path.join(os.path.dirname(__file__), self.get_chunk_image_name(chunk_luid))
def get_chunk_image_path(self, chunk_luid):
return os.path.join(self.chunkymap_data_path, self.get_chunk_image_name(chunk_luid))
def get_chunk_genresult_name(self, chunk_luid):
return "chunk_"+chunk_luid+"_mapper_result.txt"
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_genresult_path(self, chunk_luid):
return os.path.join(self.chunkymap_data_path, self.get_chunk_genresult_name(chunk_luid))
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
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)
line = True
while line:
line = ins.readline()
if line:
line_strip = line.strip()
if "data does not exist" in line_strip:
result = True
break
ins.close()
return result
def remove_genresult(self, chunk_luid):
result = False
dest_genresult_path = self.get_chunk_genresult_path(chunk_luid)
if os.path.isfile(dest_genresult_path):
result = True
os.remove(dest_genresult_path)
return result
def remove_chunk_image(self, chunk_luid):
result = False
png_path = self.get_chunk_image_path(chunk_luid)
if os.path.isfile(png_path):
result = True
os.remove(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)
if os.path.isfile(out_path):
os.remove(out_path)
result = True
if os.path.isfile(png_path):
os.remove(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)
#dest_genresult_path = self.get_chunk_genresult_path(chunk_luid)
dest_png_path = self.get_chunk_image_name(chunk_luid)
if os.path.isfile(dest_png_path):
#os.remove(dest_genresult_path)
is_rendered = True
return is_rendered
def prepare_chunk_meta(self, chunk_luid):
if chunk_luid not in self.chunks.keys():
self.chunks[chunk_luid] = MTChunk()
def render_chunk(self, x, z):
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)
cmd_suffix = ""
genresult_name = self.get_chunk_genresult_name(chunk_luid)
genresult_path = self.get_chunk_genresult_tmp_path(chunk_luid)
if self.is_save_output_ok:
cmd_suffix = " > \""+genresult_path+"\""
x_min = x * self.chunk_size
x_max = x * self.chunk_size + self.chunk_size - 1
z_min = z * self.chunk_size
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
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)
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):
result = True
try:
if (os.path.isfile(dest_png_path)):
os.remove(dest_png_path)
except:
print ("Could not finish deleting '"+dest_png_path+"'")
try:
os.rename(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+"'")
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+"')")
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):
self.chunkymap_data_path=os.path.join(self.website_root,"chunkymapdata")
chunkymap_players_name = "players"
chunkymap_players_path = os.path.join(self.chunkymap_data_path, chunkymap_players_name)
htaccess_path = os.path.join(chunkymap_players_path,".htaccess")
if not os.path.isdir(chunkymap_players_path):
os.makedirs(chunkymap_players_path)
if not os.path.isfile(htaccess_path):
self.deny_http_access(chunkymap_players_path)
players_path = os.path.join(self.world_path, "players")
for dirname, dirnames, filenames in os.walk(players_path):
for filename in filenames:
file_fullname = os.path.join(players_path,filename)
#print (" EXAMINING "+filename)
badstart_string = "."
player_name = None
player_position = None
if (filename[:len(badstart_string)]!=badstart_string):
ins = open(file_fullname)
line = True
has_enough_data = False
while line:
line = ins.readline()
if line:
ao_index = line.find("=")
if ao_index > 0:
found_name = line[:ao_index].strip()
found_value = line[ao_index+1:].strip()
if found_name=="name":
player_name = found_value
elif found_name=="position":
player_position = found_value
if (player_name is not None) and (player_position is not None):
has_enough_data = True
break
ins.close()
player_dest_path = os.path.join(chunkymap_players_path,filename+".yml")
if player_position is not None:
# mark chunk
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])
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
else: else:
if os.path.isfile(mapper_out_path): print("Player '"+filename+"' has bad position data--should be 3-length (x,y,z) in position value: "+str(pos_strings))
os.remove(mapper_out_path)
except: if has_enough_data:
print ("Could not finish deleting/moving output") #if player_name!="singleplayer":
else: map_player_dict = self.get_dict_from_conf_file(player_dest_path,":")
if os.path.isfile(dest_png_path): if (map_player_dict is None) or (map_player_dict["position"]!=player_position):
total_generated_count += 1 outs = open(player_dest_path, 'w')
square_generates_count += 1 outs.write("name:"+player_name+"\n") # python automatically uses correct newline for your os when you put "\n"
print("Skipping existing map tile file " + png_name + " (delete it to re-render)") outs.write("position:"+player_position+"\n")
elif is_empty_chunk: outs.close()
print("Skipping empty chunk " + chunk_luid + " since not full_render") def is_player_at_luid(self, chunk_luid):
print ("") # blank line before next z so output is human readable result = False
chunkx_min -= 1 if chunk_luid in self.chunks.keys():
chunkz_min -= 1 result = self.chunks[chunk_luid].is_player_here
chunkx_max += 1 return result
chunkz_max += 1
#end while square outline (1-chunk-thick outline) generated any png files def is_chunk_fresh(self, chunk_luid):
new_map_dict = {} result = False
new_map_dict["world_name"]=str(world_name) if chunk_luid in self.chunks.keys():
new_map_dict["chunk_size"]=str(chunk_size) result = self.chunks[chunk_luid].is_fresh
new_map_dict["pixelspernode"]=str(pixelspernode) return result
new_map_dict["chunkx_min"]=str(chunkx_min)
new_map_dict["chunkx_max"]=str(chunkx_max) def run(self):
new_map_dict["chunkz_min"]=str(chunkz_min) if os.path.isfile(self.mtmn_path) and os.path.isfile(self.colors_path):
new_map_dict["chunkz_max"]=str(chunkz_max) self.check_players()
new_map_dict["maxheight"]=str(maxheight) self.chunkymap_data_path=os.path.join(self.website_root,"chunkymapdata")
new_map_dict["minheight"]=str(minheight) yaml_name = "generated.yml"
new_map_dict["world_path"]=str(world_path) yaml_path = os.path.join(self.chunkymap_data_path, yaml_name)
new_map_dict["chunkymap_data_path"]=str(chunkymap_data_path) if not os.path.isdir(self.chunkymap_data_path):
new_map_dict["total_generated_count"]=str(total_generated_count) os.mkdir(self.chunkymap_data_path)
is_changed = False
if mapvars is None: htaccess_path = os.path.join(self.chunkymap_data_path,".htaccess")
print ("SAVING '" + yaml_path + "' since nothing was loaded or it did not exist") if not os.path.isdir(self.chunkymap_data_path):
is_changed = True os.makedirs(self.chunkymap_data_path)
else: if not os.path.isfile(htaccess_path):
for this_key in new_map_dict.iterkeys(): self.deny_http_access(self.chunkymap_data_path)
if (this_key not in mapvars.keys()):
is_changed = True mapvars = self.get_dict_from_conf_file(yaml_path,":")
print ("SAVING '" + yaml_path + "' since " + str(this_key) + " not in mapvars") #is_testonly == (os_name=="windows")
break
elif (str(mapvars[this_key]) != str(new_map_dict[this_key])): if mapvars is not None and set(['self.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)+"')...")
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)
for filename in filenames:
file_fullname = os.path.join(self.chunkymap_data_path,filename)
print (" EXAMINING "+filename)
badstart_string = "chunk"
if (len(filename) >= len(badstart_string)) and (filename[:len(badstart_string)]==badstart_string):
os.remove(file_fullname)
elif filename==yaml_name:
os.remove(file_fullname)
self.chunkx_min = 0
self.chunkz_min = 0
self.chunkx_max = 0
self.chunkz_max = 0
total_generated_count = 0
newchunk_luid_list = list()
outline_generates_count = 1
while outline_generates_count > 0:
outline_generates_count = 0
for z in range (self.chunkz_min,self.chunkz_max+1):
for x in range(self.chunkx_min,self.chunkx_max+1):
#python ~/minetest/util/minetestmapper-numpy.py --region -1200 800 -1200 800 --drawscale --maxheight 100 --minheight -50 --pixelspernode 1 ~/.minetest/worlds/FCAGameAWorld ~/map.png
#sudo mv ~/map.png /var/www/html/minetest/images/map.png
#only generate the edges (since started with region 0 0 0 0) and expanding from there until no png is created:
is_outline = (x==self.chunkx_min) or (x==self.chunkx_max) or (z==self.chunkz_min) or (z==self.chunkz_max)
if is_outline:
chunk_luid = self.get_chunk_luid(x,z)
is_player_here = 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):
is_render_needed = True
print (chunk_luid+": RENDERING non-fresh marked empty chunk (player present in it)")
else:
print (chunk_luid+": SKIPPING non-fresh marked chunk (player present in it)")
else:
is_render_needed = True
print (chunk_luid+": RENDERING non-fresh unmarked chunk (player present in it)")
else:
if (not self.is_genresult_marked(chunk_luid)):
is_render_needed = True
print (chunk_luid+": RENDERING non-fresh unmarked chunk (skipped other checks since player not present in it)")
else:
print (chunk_luid+": SKIPPING non-fresh marked chunk (skipped other checks since player not present in it)")
else:
print (chunk_luid+": SKIPPING fresh chunk")
#if (not self.is_genresult_marked(chunk_luid)):
#is_render_needed = True
if is_render_needed:
if (self.render_chunk(x,z)):
total_generated_count += 1
outline_generates_count += 1
else:
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)")
#elif is_empty_chunk:
#print("Skipping empty chunk " + chunk_luid)
print ("") # blank line before next z so output is more readable
self.chunkx_min -= 1
self.chunkz_min -= 1
self.chunkx_max += 1
self.chunkz_max += 1
#end while square outline (1-chunk-thick outline) generated any png files
new_map_dict = {}
new_map_dict["world_name"]=str(self.world_name)
new_map_dict["chunk_size"]=str(self.chunk_size)
new_map_dict["pixelspernode"]=str(self.pixelspernode)
new_map_dict["chunkx_min"]=str(self.chunkx_min)
new_map_dict["chunkx_max"]=str(self.chunkx_max)
new_map_dict["chunkz_min"]=str(self.chunkz_min)
new_map_dict["chunkz_max"]=str(self.chunkz_max)
new_map_dict["maxheight"]=str(self.maxheight)
new_map_dict["minheight"]=str(self.minheight)
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")
is_changed = True 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]) + "") else:
break for this_key in new_map_dict.iterkeys():
if is_changed: if (this_key not in mapvars.keys()):
outs = open(yaml_path, 'w') is_changed = True
outs.write("world_name:"+str(world_name) + "\n") print ("SAVING '" + yaml_path + "' since " + str(this_key) + " not in mapvars")
outs.write("chunk_size:"+str(chunk_size) + "\n") break
outs.write("pixelspernode:"+str(pixelspernode) + "\n") elif (str(mapvars[this_key]) != str(new_map_dict[this_key])):
outs.write("chunkx_min:"+str(chunkx_min) + "\n") is_changed = True
outs.write("chunkx_max:"+str(chunkx_max) + "\n") print ("SAVING '" + yaml_path + "' since new " + this_key + " value " + str(mapvars[this_key]) + " not same as saved value " + str(mapvars[this_key]) + "")
outs.write("chunkz_min:"+str(chunkz_min) + "\n") break
outs.write("chunkz_max:"+str(chunkz_max) + "\n") if is_changed:
#values for command arguments: outs = open(yaml_path, 'w')
outs.write("maxheight:"+str(maxheight) + "\n") outs.write("world_name:"+str(self.world_name) + "\n")
outs.write("minheight:"+str(minheight) + "\n") outs.write("chunk_size:"+str(self.chunk_size) + "\n")
#ALSO save to YAML: outs.write("pixelspernode:"+str(self.pixelspernode) + "\n")
outs.write("world_path:"+str(world_path) + "\n") outs.write("chunkx_min:"+str(self.chunkx_min) + "\n")
outs.write("chunkymap_data_path:"+str(chunkymap_data_path) + "\n") outs.write("chunkx_max:"+str(self.chunkx_max) + "\n")
outs.write("total_generated_count:"+str(total_generated_count) + "\n") outs.write("chunkz_min:"+str(self.chunkz_min) + "\n")
outs.write("chunkz_max:"+str(self.chunkz_max) + "\n")
outs.close() #values for command arguments:
else: outs.write("maxheight:"+str(self.maxheight) + "\n")
print ("(Not saving '"+yaml_path+"' since same value of each current variable is already in file as loaded)") outs.write("minheight:"+str(self.minheight) + "\n")
else: #ALSO save to YAML:
print ("failed since this folder must contain colors.txt and minetestmapper-numpy.py") outs.write("world_path:"+str(self.world_path) + "\n")
outs.write("chunkymap_data_path:"+str(self.chunkymap_data_path) + "\n")
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)")
else:
print ("failed since this folder must contain colors.txt and minetestmapper-numpy.py")
def main():
#args = parse_args()
mtchunks = MTChunks()
mtchunks.run()
if __name__ == '__main__':
main()

Loading…
Cancel
Save