This is the backend--don't call it directly. instead do include_once('chunkymap.php'); To use the map, go to viewchunkymap.php instead."; } $minute=60; $player_file_age_expired_max_seconds=20*$minute-1; $player_file_age_idle_max_seconds=5*$minute-1; //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'); } else { echo ""; } $chunkymap_anchor_name="chunkymap_top"; $is_verbose = false; if ($is_verbose) echo "REQUEST..."; foreach($_REQUEST as $key => $value) { //in case auto_globals is not enabled $GLOBALS[$key]=$value; if ($is_verbose) echo "$key:$value..."; } if ($is_verbose) echo "timezone..."; date_default_timezone_set('EST'); //required by PHP >=5.1.0 if ($is_verbose) echo "globals..."; //$x=0; //$z=0; //$zoom=25; if (!isset($x)) { $x=0; } if (!isset($z)) { $z=0; } if (!isset($zoom)) { $zoom=.25; } $chunkymapdata_path = "chunkymapdata"; $chunkymapdata_worlds_path = $chunkymapdata_path."/worlds"; $chunkymapdata_thisworld_path = null; $showplayers=true; // NOT OPTIONAL for table version: $chunkymap_tile_original_w=16; $chunkymap_tile_original_h=16; $chunk_dimension_min=$chunkymap_tile_original_w; if ($chunkymap_tile_original_h<$chunk_dimension_min) $chunk_dimension_min=$chunkymap_tile_original_h; $chunkymap_change_zoom_multiplier=1.5; $chunkymap_camera_pan_delta=.5; $chunkymap_view_min_zoom=0.0173415299; //1.0/$chunk_dimension_min; //should be a number that would get to exactly 100 eventually if multiplied by chunkymap_zoom_delta repeatedly (such as 0.09765625 if chunkymap_zoom_delta were 2); 0.005 was avoided since tiles used to be 80x80 pixels $chunkymap_view_max_zoom=16585998.48141; //13107200.0; $decachunk_prefix_string="decachunk_"; $decachunk_prefix_then_x_string=$decachunk_prefix_string."x"; $chunk_prefix_string="chunk_"; $chunk_prefix_then_x_string=$chunk_prefix_string."x"; $z_opener="z"; $dot_yaml=".yml"; $decachunk_dot_and_ext=".jpg"; $chunk_dot_and_ext = ".png"; //$more_attribs_string="; -webkit-filter: opacity(0%); filter: opacity(0%)"; $more_attribs_string=""; $td_decachunk_placeholder_content=""; $td_chunk_placeholder_content=""; $td_1px_placeholder_content=""; function echo_error($val) { if (!isset($val)) { $val="Unknown Error"; } echo ''.$val.'
'."\n"; } function get_dict_from_conf($path, $assignment_operator) { global $is_verbose; if ($is_verbose) echo "get_dict..."; $handle = fopen($path, "r"); $result = null; if ($handle) { while (($line = fgets($handle)) !== false) { $line_strip = trim($line); if (strlen($line_strip)>0) { if (substr($line_strip,0,1)!="#") { $ao_index = strpos($line_strip, $assignment_operator); if ($ao_index>0 and $ao_index<(strlen($line_strip)-1)) { //skip blank variable OR value $found_name = substr($line_strip, 0, $ao_index); $found_value_index = $ao_index + 1; $found_value = substr($line_strip, $found_value_index, strlen($line_strip)-$found_value_index); if ($result===null) { $result = array(); } $result[$found_name]=$found_value; } } } } fclose($handle); } else { echo "Failed to read $path (run chunkymap-cronjob script as root first, otherwise see README.md in minetest-chunkymap to ensure installation is correct).
"; } return $result; }//end get_dict_from_conf $map_dict = null; //startsWith and endsWith are from: //Salmon A. stackoverflow. . 5 Feb 2016. 19 Feb, 2016. function startsWith($haystack, $needle) { // search backwards starting from haystack length characters from the end return $needle === "" || strrpos($haystack, $needle, -strlen($haystack)) !== false; } function endsWith($haystack, $needle) { // search forward starting from end minus needle length characters return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false); } //NOTE: This function is here since the builtin is_int checks type (which is not needed in this webapp) and the builtin is_numeric includes decimal and exponent (see http://php.net/manual/en/function.is-numeric.php) function is_int_string($val) { global $is_verbose; if ($is_verbose) echo "is_int_string..."; $result = true; $int_chars="0123456789-"; for ($i=0; $i(missing world name)"; // } function get_chunk_folder_path_from_chunky_coords($chunky_x, $chunky_z) { global $chunkymapdata_thisworld_path; //NOTE: floor converts -.5 to -1 (and -1.5 to -2) but .5 to 0 $decachunk_x = get_decachunky_coord_from_chunky_coord($chunky_x); $decachunk_z = get_decachunky_coord_from_chunky_coord($chunky_z); //if ($chunky_x<0) { $decachunk_x = $chunky_x + $chunky_x%10; } //else { $decachunk_x = $chunky_x - $chunky_x%10; } //if ($chunky_z<0) { $decachunk_z = $chunky_z + $chunky_z%10; } //else { $decachunk_z = $chunky_z - $chunky_z%10; } $result = $chunkymapdata_thisworld_path.'/16px/'.$decachunk_x.'/'.$decachunk_z; return $result; } function get_decachunk_folder_path_from_location($location_x, $location_z) { global $chunkymapdata_thisworld_path; //NOTE: floor converts -.5 to -1 (and -1.5 to -2) but .5 to 0 $chunky_x = get_chunky_coord_from_location($location_x); $chunky_z = get_chunky_coord_from_location($location_z); $decachunky_x = get_decachunky_coord_from_chunky_coord($chunky_x); $decachunky_z = get_decachunky_coord_from_chunky_coord($chunky_z); $hectochunk_x = get_hectochunky_coord_from_decachunky_coord($decachunky_x); $hectochunk_z = get_hectochunky_coord_from_decachunky_coord($decachunky_z); $result = $chunkymapdata_thisworld_path.'/160px/'.$hectochunk_x.'/'.$hectochunk_z; return $result; } function get_decachunk_folder_path_from_decachunk($chunky_x, $chunky_z) { global $chunkymapdata_thisworld_path; //NOTE: floor converts -.5 to -1 (and -1.5 to -2) but .5 to 0 $hectochunk_x = get_hectochunky_coord_from_decachunky_coord($chunky_x); $hectochunk_z = get_hectochunky_coord_from_decachunky_coord($chunky_z); $result = $chunkymapdata_thisworld_path.'/160px/'.$hectochunk_x.'/'.$hectochunk_z; return $result; } function get_chunky_coord_from_location($location_coord) { $chunk_coord = intval(floor((float)$location_coord/16)); return $chunk_coord; } function get_decachunky_coord_from_chunky_coord($chunky_x) { return intval(floor((float)$chunky_x/10.0)); } function get_hectochunky_coord_from_decachunky_coord($chunky_x) { return intval(floor((float)$chunky_x/10.0)); } function get_decachunky_coord_from_location($location_x) { $chunk_x = get_chunky_coord_from_location($location_x); $decachunk_x = get_decachunky_coord_from_chunky_coord($chunk_x); return $decachunk_x; } function get_decachunk_image_path_from_decachunk($decachunky_x, $decachunky_z) { return get_decachunk_folder_path_from_decachunk($decachunky_x, $decachunky_z)."/".get_decachunk_image_name_from_decachunk($decachunky_x, $decachunky_z); } function get_decachunk_image_name_from_decachunk($decachunky_x, $decachunky_z) { global $decachunk_prefix_string; global $decachunk_dot_and_ext; return "$decachunk_prefix_string"."$decachunky_x"."z"."$decachunky_z"."$decachunk_dot_and_ext"; } function get_chunk_yaml_path_from_chunky_coords($chunky_x, $chunky_z) { return get_chunk_folder_path_from_chunky_coords($chunky_x, $chunky_z).'/'.get_chunk_yaml_file_name($chunky_x, $chunky_z); } function get_chunk_image_path_from_chunky_coords($chunky_x, $chunky_z) { return get_chunk_folder_path_from_chunky_coords($chunky_x, $chunky_z).'/'.get_chunk_file_name($chunky_x, $chunky_z); } function get_chunk_yaml_file_name($chunky_x, $chunky_z) { global $chunk_prefix_then_x_string; global $dot_yaml; global $z_opener; return $chunk_prefix_then_x_string.$chunky_x.$z_opener.$chunky_z.$dot_yaml; } function get_chunk_file_name($chunky_x, $chunky_z) { global $chunk_prefix_then_x_string; global $dot_yaml; global $z_opener; global $chunk_dot_and_ext; return $chunk_prefix_then_x_string.$chunky_x.$z_opener.$chunky_z."$chunk_dot_and_ext"; } function get_javascript_bool_value($this_bool) { $result = "false"; if ($this_bool == true) { $result = "true"; } return $result; } function get_javascript_int_value($this_val) { $result = $this_val; if ($this_val === null) { $result = "null"; } else { $this_val = intval($this_val); $result = "$this_val"; } return $result; } function get_markers_from_dir($chunkymap_markers_path) { global $chunkymapdata_thisworld_path; global $player_file_age_expired_max_seconds; global $player_file_age_idle_max_seconds; global $show_expired_players_enable; $markers=array(); $markers_count=0; if (is_dir($chunkymap_markers_path)) { if ($handle = opendir($chunkymap_markers_path)) { while (false !== ($file_name = readdir($handle))) { if (substr($file_name, 0, 1) != ".") { $file_name_lower = strtolower($file_name); if (endsWith($file_name_lower, ".yml")) { $file_path = $chunkymap_markers_path."/".$file_name; $marker_vars = get_dict_from_conf($file_path, ":"); if (isset($marker_vars["x"]) and isset($marker_vars["z"])) { $is_expired=false; $is_idle=false; if (isset($marker_vars["utc_mtime"])) { $last_player_update_time = strtotime($marker_vars["utc_mtime"]); if (time()-$last_player_update_time > $player_file_age_expired_max_seconds) { $is_expired=true; } elseif (time()-$last_player_update_time > $player_file_age_idle_max_seconds) { $is_idle=true; } if ($is_expired===false) { $markers[$markers_count]["utc_mtime"] = $marker_vars["utc_mtime"]; } } if (($show_expired_players_enable===true) or ($is_expired===false)) { $markers[$markers_count]["x"] = $marker_vars["x"]; $markers[$markers_count]["z"] = $marker_vars["z"]; $markers[$markers_count]["is_idle"] = $is_idle; $markers[$markers_count]["is_expired"] = $is_expired; if (isset($marker_vars["y"])) { $markers[$markers_count]["y"] = $marker_vars["y"]; } if (isset($marker_vars["image"])) { $try_path = "$chunkymapdata_thisworld_path/".$marker_vars["image"]; if (is_file($try_path)) { $markers[$markers_count]["image"] = $try_path; //this is the normal place to store them actually } else { $markers[$markers_count]["image"] = $marker_vars["image"]; } } else { if (isset($marker_vars["index"])) { $try_path = "$chunkymapdata_thisworld_path/players/".$marker_vars["index"].".jpg"; if (is_file($try_path)) { $markers[$markers_count]["image"] = $try_path; echo_error("detected image $try_path\r\n"); } else { $try_path = "$chunkymapdata_thisworld_path/players/".$marker_vars["index"].".png"; if (is_file($try_path)) { $markers[$markers_count]["image"] = $try_path; } } } else { echo_error("missing index in marker file $file_name\r\n"); } } if (isset($marker_vars["name"])) { $markers[$markers_count]["name"] = $marker_vars["name"]; } if (isset($marker_vars["index"])) { $markers[$markers_count]["index"] = $marker_vars["index"]; //for ajax to get player location with neither playerid nor name known } if (isset($marker_vars["playerid"])) { $markers[$markers_count]["playerid"] = $marker_vars["playerid"]; } $markers_count+=1; } } else { echo_error("Bad location in marker file '$file_path'"); } } } } } } else { echo ""; } return $markers; } //chunks_enable: shows chunk png images instead of decachunk jpg images (slower) //visual_debug_enable: draws colored rectangles based on yml files instead of drawing images function echo_chunkymap_canvas($show_player_names_enable, $decachunks_enable, $chunks_enable, $visual_debug_enable, $html4_mode_enable) { global $x; global $z; global $zoom; global $chunkymap_view_max_zoom; global $chunkymap_view_min_zoom; global $showplayers; global $chunkymap_change_zoom_multiplier; global $chunkymap_camera_pan_delta; global $world_name; global $chunkymapdata_thisworld_path; check_world(); if (isset($world_name)) { $chunks_per_tile_x_count = 10; $chunks_per_tile_z_count = 10; //use decachunk jpgs by default for speed: $tile_w = 160; $tile_h = 160; if (isset($chunks_enable) and ($chunks_enable===true)) { $tile_w = 16; $tile_h = 16; $chunks_per_tile_x_count = 1; $chunks_per_tile_z_count = 1; } else { $chunks_enable=false; } $locations_per_tile_x_count = $chunks_per_tile_x_count*16; $locations_per_tile_z_count = $chunks_per_tile_z_count*16; if ($zoom<$chunkymap_view_min_zoom) $zoom = $chunkymap_view_min_zoom; if ($zoom>$chunkymap_view_max_zoom) $zoom = $chunkymap_view_max_zoom; $EM_PER_WIDTH_COUNT = 800.0/12.0; //ultimately derived from 12pt font on 800x600 display--no really, this is right $camera_w = (800) * (1.0/$zoom); //screen should be 800pt wide always (so 12pt is similar on all screens and only varies with physical size of screen in inches, and since pt was invented to replace px) $camera_left = $x-$camera_w/2.0; $camera_h = $camera_w; //start with square camera to make sure enough chunks are loaded and since neither screen height nor ratio can be known from php since it is only run on server-side $camera_top = $z+$camera_h/2.0; //plus since cartesian until drawn [then flipped] $chunky_view_x = get_chunky_coord_from_location($x); $chunky_view_z = get_chunky_coord_from_location($z); #tile is either chunk or decachunk $min_tiley_x = -1; $max_tiley_x = 0; $min_tiley_z = -1; $max_tiley_z = 0; $camera_right = $camera_left+$camera_w; $camera_bottom = $camera_top-$camera_h; //minus since cartesian until drawn [then flipped] //Only whether the near edges are in the canvas matters (get bottom of max since always cartesian until drawn [then inverted]): $min_tiley_x__chunk_location_right = $min_tiley_x*$locations_per_tile_x_count+$locations_per_tile_x_count; $max_tiley_x__chunk_location_left = $max_tiley_x*$locations_per_tile_x_count; $min_tiley_z__chunk_location_top = $min_tiley_z*$locations_per_tile_z_count; $max_tiley_z__chunk_location_bottom = $max_tiley_z*$locations_per_tile_z_count+$locations_per_tile_z_count; while ($min_tiley_x__chunk_location_right>$camera_left) { $min_tiley_x -= 1; $min_tiley_x__chunk_location_right = $min_tiley_x*$locations_per_tile_x_count+$locations_per_tile_x_count; } while ($max_tiley_x__chunk_location_left<$camera_right) { $max_tiley_x += 1; $max_tiley_x__chunk_location_left = $max_tiley_x*$locations_per_tile_x_count; } while ($min_tiley_z__chunk_location_top>$camera_bottom) { $min_tiley_z -= 1; $min_tiley_z__chunk_location_top = $min_tiley_z*$locations_per_tile_z_count; } while ($max_tiley_z__chunk_location_bottom<$camera_top) { $max_tiley_z += 1; $max_tiley_z__chunk_location_bottom = $max_tiley_z*$locations_per_tile_z_count+$locations_per_tile_z_count; } $tile_x_count = $max_tiley_x-$min_tiley_x+1; $tile_z_count = $max_tiley_z-$min_tiley_z+1; $si_yml_path = "$chunkymapdata_thisworld_path/singleimage.yml"; $si_metadata = null; $si_left = null; $si_top = null; $si_w = null; $si_h = null; $si_bottom = null; $si_right = null; if (is_file($si_yml_path)) { $si_metadata = get_dict_from_conf($si_yml_path, ":"); if ($si_metadata!==null) { if (isset($si_metadata["image_top"]) and isset($si_metadata["image_bottom"])) { if ($si_metadata["image_top"]<$si_metadata["image_bottom"]) { $cartesian_bottom = $si_metadata["image_top"]; $si_metadata["image_top"] = $si_metadata["image_bottom"]; $si_metadata["image_bottom"] = $cartesian_bottom; } } if (isset($si_metadata["image_left"])) { $si_left=$si_metadata["image_left"]; } if (isset($si_metadata["image_top"])) { $si_top=$si_metadata["image_top"]; } if (isset($si_metadata["image_w"])) { $si_w=$si_metadata["image_w"]; } if (isset($si_metadata["image_h"])) { $si_h=$si_metadata["image_h"]; } if (isset($si_metadata["image_bottom"])) { $si_bottom = $si_metadata["image_bottom"]; } elseif (isset($si_metadata["image_top"]) and isset($si_metadata["image_h"])) { $si_bottom=$si_top-$si_h; //minus since cartesian (which is assured above) } if (isset($si_metadata["image_right"])) { $si_right = $si_metadata["image_right"]; } elseif (isset($si_metadata["image_left"]) and isset($si_metadata["image_w"])) { $si_right=$si_left+$si_w; } } } $markers = get_markers_from_dir($chunkymapdata_thisworld_path."/markers"); $players = get_markers_from_dir($chunkymapdata_thisworld_path."/players"); $index = 0; $players_count = count($players); while ($index<$players_count) { $this_player = $players[$index]; $img_src = "$chunkymapdata_thisworld_path/players/singleplayer.png"; if (!isset($players[$index]["image"])) { $players[$index]["image"] = $img_src; } if (isset($players[$index]["image"])) { if (isset($players[$index]["index"])) { $public_index=$players[$index]["index"]; $players[$index]["img_id"] = "player"."$public_index"."_img"; //echo ("players[index][img_id]:".$players[$index]["img_id"]); } else { echo_error("Missing index for player\r\n"); } } else { echo echo_error("Missing image for player\r\n"); } $index++; } //echo ("finished adding id to $players_count player(s)\r\n"); //img_id is actually only needed for canvas drawing $index = 0; $markers_count = count($markers); while ($index<$markers_count) { if (isset($markers[$index]["image"])) { if (isset($markers[$index]["index"])) { $public_index=$markers[$index]["index"]; $markers[$index]["img_id"] = "marker"."$public_index"."_img"; } else { echo_error("Missing index for marker "+$markers[$index]["name"]); } } $index++; } //images are echoed further down if ($html4_mode_enable!==true) { //image-rendering: -moz-crisp-edges; image-rendering:-o-crisp-edges; image-rendering: -webkit-optimize-contrast; image-rendering: crisp-edges; -ms-interpolation-mode: nearest-neighbor; echo ' '; echo ' '; }//end if not $html4_mode_enable global $td_decachunk_placeholder_content; global $td_chunk_placeholder_content; $td_tile_placeholder_content = null; if ($chunks_enable) { $td_tile_placeholder_content = $td_chunk_placeholder_content; } else { $td_tile_placeholder_content = $td_decachunk_placeholder_content; } $si_path = "$chunkymapdata_thisworld_path/singleimage.jpg"; $si_yml_path = "$chunkymapdata_thisworld_path/singleimage.yml"; if (is_file($si_path) and is_file($si_yml_path)) { $style_append=""; if ($html4_mode_enable===true) { echo ''."\r\n"; } else { $style_append="; visibility:hidden"; echo '
'."\r\n"; } echo ' '."\r\n"; echo '
'."\r\n"; $style_append=""; $players_count = count($players); $index=0; while ($index<$players_count) { $this_player = $players[$index]; $public_index = $this_player["index"]; // z-index:999; $zoomed_head_w="1%"; $img_style=""; $img_border_style="border: 1px solid white;"; $text_style="color:white;"; $img_id = null; $img_enable = true; $img_src = "$chunkymapdata_thisworld_path/players/singleplayer.png"; if (!isset($this_player["image"])) { $this_player["image"] = $img_src; } if (isset($this_player["image"])) { $img_src = $this_player["image"]; if (isset($this_player["img_id"])) { //this is only needed for changing canvas drawing location via ajax $img_id = $this_player["img_id"]; $img_enable = true; } else { echo "missing player img_id\r\n"; } } else { echo "missing player image\r\n"; } //$text = "$public_index"; $text = ""; if ($show_player_names_enable) { if (isset($this_player["name"])) { $text = $this_player["name"]; } } if ($this_player["is_expired"]===true) { //should only be used for debug $img_border_style="border: 1px solid rgba(128,128,128,.5);"; $img_style.="opacity: 0.1; filter: alpha(opacity=10);"; //filter is for IE8 and below $text_style="color:white; opacity: 0.4; filter: alpha(opacity=40);"; //filter is for IE8 and below $text.=" (expired)"; } elseif ($this_player["is_idle"]===true) { $img_border_style="border: 1px solid rgba(128,128,128,.5);"; $img_style.="opacity: 0.4; filter: alpha(opacity=40);"; //filter is for IE8 and below $text_style="color:white; opacity: 0.4; filter: alpha(opacity=40);"; //filter is for IE8 and below } $rel_x = "50%"; //TODO: NOT YET IMPLEMENTED (determine from actual location) $rel_z = "50%"; //TODO: NOT YET IMPLEMENTED (determine from actual location) echo "
\r\n"; if ($img_enable===true) { $id_string = ""; if ($img_id!==null) { $id_string=" id=\"$img_id\""; } echo " \r\n"; } echo " $text
\r\n"; $index++; }//end for player $markers_count = count($markers); $index=0; echo "\r\n"; while ($index<$markers_count) { $this_marker = $markers[$index]; $public_index = $this_marker["index"]; // z-index:999; $zoomed_head_w="2%"; $img_style=""; $img_border_style="border: 1px solid white;"; $text_style="color:white;"; $img_id = "marker"."$public_index"."_img"; $img_enable = false; $img_src = null; $text = ""; if (isset($this_marker["image"])) { $img_enable = true; $img_src = $this_marker["image"]; } else { $text = "$public_index"; } if (isset($this_marker["name"])) { $text = $this_marker["name"]; } if ($this_marker["is_expired"]===true) { //should only be used for debug $img_border_style="border: 1px solid rgba(128,128,128,.5);"; $img_style.="opacity: 0.1; filter: alpha(opacity=10);"; //filter is for IE8 and below $text_style="color:white; opacity: 0.4; filter: alpha(opacity=40);"; //filter is for IE8 and below $text.=" (expired)"; } elseif ($this_marker["is_idle"]===true) { $img_border_style="border: 1px solid rgba(128,128,128,.5);"; $img_style.="opacity: 0.4; filter: alpha(opacity=40);"; //filter is for IE8 and below $text_style="color:white; opacity: 0.4; filter: alpha(opacity=40);"; //filter is for IE8 and below } $rel_x = "50%"; //TODO: NOT YET IMPLEMENTED (determine from actual location) $rel_z = "50%"; //TODO: NOT YET IMPLEMENTED (determine from actual location) echo "
\r\n"; if ($img_enable===true) { echo " \r\n"; } echo " $text
\r\n"; $index++; }//end for marker echo ' '."\r\n"; echo '
'."\r\n"; } //echo ""; echo ''; echo ''; echo ''; echo ''; echo ''; $this_tiley_z=$max_tiley_z; //start at max since screen is inverted cartesian if (($decachunks_enable==true) or ($chunks_enable==true)) { if ($visual_debug_enable!==true) { //this table loads the images then is hidden when javascript runs successfully, but it is also a map though not very functional if ($html4_mode_enable===true) { echo ''."\r\n"; } else { echo '
'."\r\n"; } echo ' '."\r\n"; echo ' '."\r\n"; echo " '."\r\n"; echo ' '."\r\n"; echo ' '."\r\n"; $cell_perc=intval(round(100.0/$tile_x_count)); echo ' '."\r\n"; echo " '."\r\n"; echo ' '."\r\n"; echo " '."\r\n"; echo ' '."\r\n"; echo ' '."\r\n"; echo ' '."\r\n"; echo " '."\r\n"; echo ' '."\r\n"; echo ' '."\r\n"; echo ''."\r\n"; } } else { if ($html4_mode_enable===true) { //else see above for singleimage (if singleimage doesn't exist, this should run though) //echo 'There is nothing to do for html4_mode_enable since neither chunks nor decachunks were enabled (singleimage html4 is not yet implemented).'; } } if ($html4_mode_enable===true) { echo '
Powered by Chunkymap
'; } } else { //not isset($world_name) echo "

Choose world:

"; echo ""; } //TODO: $zoom SHOULD BE interpreted so each block (pixel) is 1pt: 1066x600 pt canvas would have 66+2/3 blocks horizontally, is 37.5 blocks vertically //so, at zoom 1.0 canvas should show 60 chunks across (6 decachunks across) }//end echo_chunkymap_canvas function check_world() { global $chunkymapdata_thisworld_path; global $world_name; global $chunkymapdata_worlds_path; if (!isset($world_name)) { if ($handle = opendir($chunkymapdata_worlds_path)) { while (false !== ($file_name = readdir($handle))) { if (substr($file_name, 0, 1) != ".") { $file_path = $chunkymapdata_worlds_path."/".$file_name; if (is_dir($file_path)) { $world_name=$file_name; break; } } } closedir($handle); } } if (isset($world_name)) { $chunkymapdata_thisworld_path = $chunkymapdata_worlds_path."/".$world_name; } } ?>