Browse Source

new map symbol and listing players by distance

master
poikilos 8 years ago
committed by Jacob Gustafson
parent
commit
6683371d83
  1. 3
      README.md
  2. 67
      listplayersbydistance.py
  3. 50
      minetestoffline.py
  4. BIN
      web/chunkymapdata_default/images/station.png

3
README.md

@ -62,6 +62,8 @@ screen -t chunkymapregen python $HOME/chunkymap/generator.py
## Changes ## Changes
* (2017-02-16) list players by distance feature added
* (2017-02-16) Fixed some long-standing syntax and logic errors in get_pos, and missing colons in switch_player_file_contents
* (2016-03-22) Detect exceptions in mintestmapper (such as database locked) and do NOT mark the chunk as is_empty * (2016-03-22) Detect exceptions in mintestmapper (such as database locked) and do NOT mark the chunk as is_empty
* optionally hide player location * optionally hide player location
* (2016-03-22) Make a method (in chunkymap.php) to echo the map as an html5 canvas * (2016-03-22) Make a method (in chunkymap.php) to echo the map as an html5 canvas
@ -187,6 +189,7 @@ chmod +x set-minutely-crontab-job.sh && ./set-minutely-crontab-job.sh
(the installer will automatically download and install numpy and Pillow -- see also install-on-windows-manually.md) (the installer will automatically download and install numpy and Pillow -- see also install-on-windows-manually.md)
## Known Issues ## Known Issues
* audit switch_player_file_contents, since had syntax errors preventing run on 2017-02-16, though hadn't worked on it for months
* var debug_adjustment = 1.345; is needed in JavaScript to resize map markers correctly to same scale as map size (for unknown reason) * var debug_adjustment = 1.345; is needed in JavaScript to resize map markers correctly to same scale as map size (for unknown reason)
* webapp: save selected world to a config file (click world on first visit to write initial config) instead of being silently autoselected * webapp: save selected world to a config file (click world on first visit to write initial config) instead of being silently autoselected
* Fix chunk generation and draw decachunks to canvas (so singleimage.py is not required to be run before generator.py) * Fix chunk generation and draw decachunks to canvas (so singleimage.py is not required to be run before generator.py)

67
listplayersbydistance.py

@ -0,0 +1,67 @@
from minetestoffline import *
import math
# (used below)
def list_players_by_distance(single_axis_enable):
#from ast import literal_eval # as make_tuple
#players_path = os.path.join(minetestinfo.get_var("primary_world_path"), "players")
players_path = "C:\\Users\\jgustafson\\Desktop\\Backup\\fcalocal\\home\\owner\\.minetest\\worlds\\FCAGameAWorld\\players"
#extra_path = os.path.join(dest_players_path, "extra_players")
players = dict()
if os.path.isdir(players_path):
folder_path = players_path
for sub_name in os.listdir(folder_path):
sub_path = os.path.join(folder_path,sub_name)
if os.path.isfile(sub_path):
if (sub_name[:1]!="."):
#is_player_file = False
print("EXAMINING "+sub_name)
players[sub_name] = MinetestPlayer(sub_name)
players[sub_name].load_from_file(sub_path)
playerid_max_len = 0
for key in players:
players[key].tag = True
if len(players[key].playerid) > playerid_max_len:
playerid_max_len = len(players[key].playerid)
is_more = True
while is_more:
is_more = False
min_abs = 32000 # ok since max worldgen limit of Minetest is 31000
min_dist = math.sqrt(32000**2 * 32000**2)
min_key = None
for key in players:
if players[key].tag:
is_more = True
pos = players[key].get_pos()
if single_axis_enable:
this_max_abs = abs(pos[0])
# get max axis intentionally, to sort properly
# skip y (height axis) intentionally
if abs(pos[2])>this_max_abs:
this_max_abs = abs(pos[2])
if this_max_abs<=min_abs:
min_abs = this_max_abs
min_key = key
#if abs(pos[2])<=min_abs:
# min_abs = pos[2]
# min_key = key
else:
dist = math.sqrt(pos[0]**2 * pos[2]**2)
if dist<=min_dist:
min_dist = dist
min_key = key
if min_key is not None:
players[min_key].tag = False
id_padding = ""
if (len(players[min_key].playerid)<playerid_max_len):
id_padding = ' '*(playerid_max_len-len(players[min_key].playerid))
print(players[min_key].playerid + ","+id_padding+" \"" + str(players[min_key].get_pos())+"\"")
list_players_by_distance(True)
raw_input("Press enter to exit...")

50
minetestoffline.py

@ -10,6 +10,7 @@ from expertmm import *
from minetestinfo import * from minetestinfo import *
import time import time
from ast import literal_eval # as make_tuple
#C:\Users\jgustafson\Desktop\Backup\fcalocal\home\owner\.minetest\worlds\FCAGameAWorld\players #C:\Users\jgustafson\Desktop\Backup\fcalocal\home\owner\.minetest\worlds\FCAGameAWorld\players
#minetest_players_path = "C:\\Users\\jgustafson\\Desktop\\Backup\\fcalocal\\home\\owner\\.minetest\\worlds\\FCAGameAWorld\\players" #minetest_players_path = "C:\\Users\\jgustafson\\Desktop\\Backup\\fcalocal\\home\\owner\\.minetest\\worlds\\FCAGameAWorld\\players"
@ -24,6 +25,7 @@ min_date_string = None
#min_date_string = "2016-03-15 12:12:00" #min_date_string = "2016-03-15 12:12:00"
DEBUG_TXT_TIME_FORMAT_STRING="%Y-%m-%d %H:%M:%S" DEBUG_TXT_TIME_FORMAT_STRING="%Y-%m-%d %H:%M:%S"
is_start_now = False is_start_now = False
interactive_enable = False
def confirm_min_date(): def confirm_min_date():
global min_date_string global min_date_string
@ -78,8 +80,9 @@ except:
print("Could not finish getting world folder name.") print("Could not finish getting world folder name.")
view_traceback() view_traceback()
try: try:
deprecated_irl_person_csv_name = world_name + " - Minetest Users - Real Names.txt" deprecated_irl_person_csv_name = world_name + " - Minetest Users - Real Names.txt" #RENAMED to:
irl_person_csv_name = "irl_person_info.csv" irl_person_csv_name = "irl_person_info.csv"
# C:\Users\jgustafson\Desktop\Backup\fcalocal\home\owner\.minetest\worlds\FCAGameAWorld\irl_person_info.csv
print("") print("")
if os.path.isdir(minetestinfo.get_var("primary_world_path")): if os.path.isdir(minetestinfo.get_var("primary_world_path")):
irl_person_csv_path = os.path.join(minetestinfo.get_var("primary_world_path"), irl_person_csv_name) irl_person_csv_path = os.path.join(minetestinfo.get_var("primary_world_path"), irl_person_csv_name)
@ -123,6 +126,7 @@ class MinetestInventoryItem:
return leftover return leftover
def get_item_as_inventory_line(self): def get_item_as_inventory_line(self):
global interactive_enable
result = None result = None
is_msg = False is_msg = False
if self.name is not None: if self.name is not None:
@ -151,8 +155,9 @@ class MinetestInventoryItem:
owner_msg = " owned by "+self.owner owner_msg = " owned by "+self.owner
print("ERROR in get_item_as_inventory_line: name is None for item"+owner_msg) print("ERROR in get_item_as_inventory_line: name is None for item"+owner_msg)
is_msg = True is_msg = True
if is_msg: if interactive_enable:
raw_input("Press enter to continue...") if is_msg:
raw_input("Press enter to continue...")
return result return result
def set_from_inventory_line(self, line): def set_from_inventory_line(self, line):
@ -164,7 +169,7 @@ class MinetestInventoryItem:
parts = line.strip().split(" ") parts = line.strip().split(" ")
is_warning = False is_warning = False
if (len(parts)!=2) and (len(parts)!=3) and (len(parts)!=4): if (len(parts)!=2) and (len(parts)!=3) and (len(parts)!=4):
print("inventory has extra unknown params that will be ignored but saved: "+line) print("inventory has extra unknown params that will be ignored but retained: "+line)
is_warning = True is_warning = True
if len(parts)>=2: if len(parts)>=2:
if parts[0]=="Item": if parts[0]=="Item":
@ -183,8 +188,10 @@ class MinetestInventoryItem:
else: else:
print("Failed to parse line since too few ("+len(parts)+") param(s).") print("Failed to parse line since too few ("+len(parts)+") param(s).")
is_warning = True is_warning = True
if is_warning: global interactive_enable
raw_input("Press enter to continue...") if interactive_enable:
if is_warning:
raw_input("Press enter to continue...")
else: else:
self.name = "Empty" self.name = "Empty"
@ -218,6 +225,7 @@ class MinetestInventory:
return qty return qty
def write_to_stream(self, outs): def write_to_stream(self, outs):
global interactive_enable
if self.name is not None: if self.name is not None:
#if self.width is not None: #if self.width is not None:
if self.width is None: if self.width is None:
@ -232,13 +240,15 @@ class MinetestInventory:
outs.write("EndInventoryList"+"\n") outs.write("EndInventoryList"+"\n")
else: else:
print("ERROR in minetestinventory.write_to: items is None") print("ERROR in minetestinventory.write_to: items is None")
raw_input("Press enter to continue...") if interactive_enable:
raw_input("Press enter to continue...")
#else: #else:
# print("ERROR in minetestinventory.write_to: width is None") # print("ERROR in minetestinventory.write_to: width is None")
# raw_input("Press enter to continue...") # raw_input("Press enter to continue...")
else: else:
print("ERROR in minetestinventory.write_to: name is None") print("ERROR in minetestinventory.write_to: name is None")
raw_input("Press enter to continue...") if interactive_enable:
raw_input("Press enter to continue...")
class MinetestPlayer: class MinetestPlayer:
@ -246,6 +256,7 @@ class MinetestPlayer:
_player_args = None _player_args = None
inventories = None inventories = None
oops_list = None oops_list = None
tag = None
def __init__(self, playerid): def __init__(self, playerid):
self._player_args = {} self._player_args = {}
@ -260,25 +271,30 @@ class MinetestPlayer:
self.playerid = playerid self.playerid = playerid
self.inventories = list() self.inventories = list()
#Set multiplied internal pos using actual pos
def set_pos(self, pos): def set_pos(self, pos):
if (len(pos)==3): if (len(pos)==3):
self._player_args["position"] = float(pos[0])*minetest_player_pos_multiplier, float(pos[1])*minetest_player_pos_multiplier, float(pos[2])*minetest_player_pos_multiplier self._player_args["position"] = float(pos[0])*minetest_player_pos_multiplier, float(pos[1])*minetest_player_pos_multiplier, float(pos[2])*minetest_player_pos_multiplier
else: else:
print("Failed to set position since length of tuple recieved is not 3: "+str(pos)) print("Failed to set position since length of tuple recieved is not 3: "+str(pos))
#Get actual pos from internal multiplied pos
def get_pos(self): def get_pos(self):
result = None result = None
if self._player_args is not None: if self._player_args is not None:
if "position" in self._player_args if "position" in self._player_args:
if isinstance(self._player_args["position"], str):
self._player_args["position"] = literal_eval(self._player_args["position"])
element_count = len(self._player_args["position"]) element_count = len(self._player_args["position"])
if (element_count!=3): if (element_count!=3):
if element_count>1: #if element_count>1:
if element_count==2: if element_count==2:
self.set_pos(self._player_args["position"][0]/minetest_player_pos_multiplier, 8.0, self._player_args["position"][1]/minetest_player_pos_multiplier) self.set_pos(self._player_args["position"][0]/minetest_player_pos_multiplier, 8.0, self._player_args["position"][1]/minetest_player_pos_multiplier)
print("ERROR in get_pos: Element count "+str(element_count)+" too low (should have numbers for 3 axes) for player position, so repaired by using as x and z, resulting in "+str(self.get_pos())) print("ERROR in get_pos: Element count "+str(element_count)+" too low (should have numbers for 3 axes) for player position, so repaired by using as x and z, resulting in "+str(self.get_pos()))
else if element_count!=3: elif element_count>3:
self.set_pos(self._player_args["position"][0]/minetest_player_pos_multiplier, self._player_args["position"][1]/minetest_player_pos_multiplier, self._player_args["position"][2]/minetest_player_pos_multiplier) self.set_pos(self._player_args["position"][0]/minetest_player_pos_multiplier, self._player_args["position"][1]/minetest_player_pos_multiplier, self._player_args["position"][2]/minetest_player_pos_multiplier)
print("ERROR in get_pos: Element count "+str(element_count)+" incorrect (should have numbers for 3 axes) for player position, so set to "+str(self.get_pos())) print("ERROR in get_pos: Element count "+str(element_count)+" incorrect (should have numbers for 3 axes) for player position, so set to "+str(self.get_pos()))
else: else:
self.set_pos(0,0,0) self.set_pos(0,0,0)
print("ERROR in get_pos: Element count "+str(element_count)+" too low (should have numbers for 3 axes) for player position, so set to 0,0,0") print("ERROR in get_pos: Element count "+str(element_count)+" too low (should have numbers for 3 axes) for player position, so set to 0,0,0")
@ -760,7 +776,7 @@ def set_player_names_to_file_names():
## debug_log_replay_to_offline_player_storage(debug_path, players_offline_storage_path, min_date_string) ## debug_log_replay_to_offline_player_storage(debug_path, players_offline_storage_path, min_date_string)
#debug_log_replay_to_offline_player_storage(debug_txt_path, players_offline_storage_path, min_date_string) #debug_log_replay_to_offline_player_storage(debug_txt_path, players_offline_storage_path, min_date_string)
def switch_player_file_contents(player1_path, player2_path) def switch_player_file_contents(player1_path, player2_path):
#switches everything except name #switches everything except name
player1 = MinetestPlayer(os.path.basename(player1_path)) player1 = MinetestPlayer(os.path.basename(player1_path))

BIN
web/chunkymapdata_default/images/station.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Loading…
Cancel
Save