Compare commits

..

9 Commits

18 changed files with 449 additions and 227 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.dynmap</groupId>
<artifactId>dynmap</artifactId>
<version>0.29</version>
<version>0.29.2</version>
<name>dynmap</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -42,10 +42,10 @@ public class ClientConfigurationComponent extends Component {
JSONObject wo = new JSONObject();
s(wo, "name", wn.getString("name"));
s(wo, "title", wn.getString("title"));
Location spawn = world.world.getSpawnLocation();
s(wo, "center/x", wn.getDouble("center/x", spawn.getX()));
s(wo, "center/y", wn.getDouble("center/y", spawn.getY()));
s(wo, "center/z", wn.getDouble("center/z", spawn.getZ()));
DynmapLocation spawn = world.getSpawnLocation();
s(wo, "center/x", wn.getDouble("center/x", spawn.x));
s(wo, "center/y", wn.getDouble("center/y", spawn.y));
s(wo, "center/z", wn.getDouble("center/z", spawn.z));
s(wo, "bigworld", world.bigworld);
s(wo, "extrazoomout", world.getExtraZoomOutLevels());
a(t, "worlds", wo);
@@ -55,7 +55,7 @@ public class ClientConfigurationComponent extends Component {
if(defmap == null) defmap = mt.getName();
}
}
s(t, "defaultworld", c.getString("defaultworld", defaultWorld == null ? "world" : defaultWorld.world.getName()));
s(t, "defaultworld", c.getString("defaultworld", defaultWorld == null ? "world" : defaultWorld.getName()));
s(t, "defaultmap", c.getString("defaultmap", defmap == null ? "surface" : defmap));
if(c.getString("followmap", null) != null)
s(t, "followmap", c.getString("followmap"));
@@ -26,7 +26,7 @@ public class ClientUpdateComponent extends Component {
}
protected void buildClientUpdate(ClientUpdateEvent e) {
World world = e.world.world;
DynmapWorld world = e.world;
JSONObject u = e.update;
long since = e.timestamp;
String worldName = world.getName();
+2 -2
View File
@@ -4,12 +4,12 @@ package org.dynmap;
* Generic block location
*/
public class DynmapLocation {
public int x, y, z;
public double x, y, z;
public String world;
public DynmapLocation() {}
public DynmapLocation(String w, int x, int y, int z) {
public DynmapLocation(String w, double x, double y, double z) {
world = w;
this.x = x; this.y = y; this.z = z;
}
+102 -75
View File
@@ -25,7 +25,6 @@ import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.CustomEventListener;
@@ -58,12 +57,14 @@ import org.bukkit.event.world.ChunkPopulateEvent;
import org.bukkit.event.world.SpawnChangeEvent;
import org.bukkit.event.world.WorldListener;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.dynmap.debug.Debug;
import org.dynmap.debug.Debugger;
import org.dynmap.hdmap.HDBlockModels;
import org.dynmap.hdmap.HDMapManager;
import org.dynmap.hdmap.TexturePack;
import org.dynmap.markers.MarkerAPI;
import org.dynmap.markers.impl.MarkerAPIImpl;
@@ -91,6 +92,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
boolean waterbiomeshading = false;
boolean fencejoin = false;
boolean bettergrass = false;
public CompassMode compassmode = CompassMode.PRE19;
private int config_hashcode; /* Used to signal need to reload web configuration (world changes, config update, etc) */
private int fullrenderplayerlimit; /* Number of online players that will cause fullrender processing to pause */
@@ -106,7 +108,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
/* Flag to let code know that we're doing reload - make sure we don't double-register event handlers */
public boolean is_reload = false;
private boolean generate_only = false;
private static boolean ignore_chunk_loads = false; /* Flag keep us from processing our own chunk loads */
private HashMap<Event.Type, List<Listener>> event_handlers = new HashMap<Event.Type, List<Listener>>();
@@ -125,7 +126,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
}
/* Add/Replace branches in configuration tree with contribution from a separate file */
@SuppressWarnings("unchecked")
private void mergeConfigurationBranch(ConfigurationNode cfgnode, String branch, boolean replace_existing, boolean islist) {
Object srcbranch = cfgnode.getObject(branch);
if(srcbranch == null)
@@ -255,6 +255,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
bukkitConfiguration.load();
configuration = new ConfigurationNode(bukkitConfiguration);
/* Add options to avoid 0.29 re-render (fixes very inconsistent with previous maps) */
HDMapManager.usegeneratedtextures = configuration.getBoolean("use-generated-textures", false);
HDMapManager.waterlightingfix = configuration.getBoolean("correct-water-lighting", false);
HDMapManager.biomeshadingfix = configuration.getBoolean("correct-biome-shading", false);
/* Load block models */
HDBlockModels.loadModels(dataDirectory, configuration);
/* Load texture mappings */
@@ -282,6 +287,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
waterbiomeshading = configuration.getBoolean("waterbiomeshaded", !getServer().getVersion().contains("(MC: 1.8"));
/* Default fence-to-block-join off for 1.8, on after */
fencejoin = configuration.getBoolean("fence-to-block-join", !getServer().getVersion().contains("(MC: 1.8"));
/* Default compassmode to pre19, to newrose after */
String cmode = configuration.getString("compass-mode", getServer().getVersion().contains("(MC: 1.8")?"pre19":"newrose");
if(cmode.equals("newnorth"))
@@ -510,10 +516,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockPlace(BlockPlaceEvent event) {
if(event.isCancelled())
return;
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onplace) {
mapManager.touch(dloc, "blockplace");
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockplace");
}
}
@@ -521,10 +528,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockBreak(BlockBreakEvent event) {
if(event.isCancelled())
return;
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onbreak) {
mapManager.touch(dloc, "blockbreak");
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockbreak");
}
}
@@ -532,10 +540,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onLeavesDecay(LeavesDecayEvent event) {
if(event.isCancelled())
return;
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onleaves) {
mapManager.touch(dloc, "leavesdecay");
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "leavesdecay");
}
}
@@ -543,10 +552,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockBurn(BlockBurnEvent event) {
if(event.isCancelled())
return;
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onburn) {
mapManager.touch(dloc, "blockburn");
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockburn");
}
}
@@ -554,10 +564,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockForm(BlockFormEvent event) {
if(event.isCancelled())
return;
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockform) {
mapManager.touch(dloc, "blockform");
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockform");
}
}
@@ -565,10 +576,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockFade(BlockFadeEvent event) {
if(event.isCancelled())
return;
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockfade) {
mapManager.touch(dloc, "blockfade");
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfade");
}
}
@@ -576,10 +588,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockSpread(BlockSpreadEvent event) {
if(event.isCancelled())
return;
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockspread) {
mapManager.touch(dloc, "blockspread");
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockspread");
}
}
@@ -587,24 +600,27 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
public void onBlockFromTo(BlockFromToEvent event) {
if(event.isCancelled())
return;
DynmapLocation dloc = toLoc(event.getToBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
Location loc = event.getToBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockfromto)
mapManager.touch(dloc, "blockfromto");
dloc = toLoc(event.getBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfromto");
loc = event.getBlock().getLocation();
wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockfromto)
mapManager.touch(dloc, "blockfromto");
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockfromto");
}
@Override
public void onBlockPhysics(BlockPhysicsEvent event) {
if(event.isCancelled())
return;
DynmapLocation dloc = toLoc(event.getBlock().getLocation());
mapManager.sscache.invalidateSnapshot(dloc);
Location loc = event.getBlock().getLocation();
String wn = loc.getWorld().getName();
mapManager.sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
if(onblockphysics) {
mapManager.touch(dloc, "blockphysics");
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockphysics");
}
}
@@ -620,17 +636,18 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
} catch (ClassCastException ccx) {
dir = BlockFace.NORTH;
}
DynmapLocation dloc = toLoc(loc);
mapManager.sscache.invalidateSnapshot(dloc);
String wn = loc.getWorld().getName();
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
if(onpiston)
mapManager.touch(dloc, "pistonretract");
mapManager.touch(wn, x, y, z, "pistonretract");
for(int i = 0; i < 2; i++) {
dloc.x += dir.getModX();
dloc.y += dir.getModY();
dloc.z += dir.getModZ();
mapManager.sscache.invalidateSnapshot(dloc);
x += dir.getModX();
y += dir.getModY();
z += dir.getModZ();
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
if(onpiston)
mapManager.touch(dloc, "pistonretract");
mapManager.touch(wn, x, y, z, "pistonretract");
}
}
@Override
@@ -639,24 +656,24 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
return;
Block b = event.getBlock();
Location loc = b.getLocation();
DynmapLocation dloc = toLoc(loc);
mapManager.sscache.invalidateSnapshot(dloc);
BlockFace dir;
try { /* Workaround Bukkit bug = http://leaky.bukkit.org/issues/1227 */
dir = event.getDirection();
} catch (ClassCastException ccx) {
dir = BlockFace.NORTH;
}
mapManager.sscache.invalidateSnapshot(dloc);
String wn = loc.getWorld().getName();
int x = loc.getBlockX(), y = loc.getBlockY(), z = loc.getBlockZ();
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
if(onpiston)
mapManager.touch(dloc, "pistonretract");
mapManager.touch(wn, x, y, z, "pistonretract");
for(int i = 0; i < 1+event.getLength(); i++) {
dloc.x += dir.getModX();
dloc.y += dir.getModY();
dloc.z += dir.getModZ();
mapManager.sscache.invalidateSnapshot(dloc);
x += dir.getModX();
y += dir.getModY();
z += dir.getModZ();
mapManager.sscache.invalidateSnapshot(wn, x, y, z);
if(onpiston)
mapManager.touch(dloc, "pistonretract");
mapManager.touch(wn, x, y, z, "pistonretract");
}
}
};
@@ -696,22 +713,16 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
registerEvent(Event.Type.BLOCK_PISTON_RETRACT, blockTrigger);
/* Register player event trigger handlers */
PlayerListener playerTrigger = new PlayerListener() {
private DynmapLocation dloc = new DynmapLocation();
private DynmapLocation toLoc(Location loc) {
dloc.x = loc.getBlockX(); dloc.y = loc.getBlockY();
dloc.z = loc.getBlockZ(); dloc.world = loc.getWorld().getName();
return dloc;
}
@Override
public void onPlayerJoin(PlayerJoinEvent event) {
toLoc(event.getPlayer().getLocation());
mapManager.touch(dloc, "playerjoin");
Location loc = event.getPlayer().getLocation();
mapManager.touch(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "playerjoin");
}
@Override
public void onPlayerMove(PlayerMoveEvent event) {
toLoc(event.getPlayer().getLocation());
mapManager.touch(dloc, "playermove");
Location loc = event.getPlayer().getLocation();
mapManager.touch(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "playermove");
}
};
@@ -758,7 +769,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
/* Register world event triggers */
WorldListener worldTrigger = new WorldListener() {
private DynmapLocation dloc = new DynmapLocation();
@Override
public void onChunkLoad(ChunkLoadEvent event) {
if(ignore_chunk_loads)
@@ -782,6 +792,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
updateConfigHashcode();
mapManager.activateWorld(event.getWorld());
}
@Override
public void onWorldUnload(WorldUnloadEvent event) {
updateConfigHashcode();
mapManager.deactivateWorld(event.getWorld().getName());
}
};
ongeneratechunk = isTrigger("chunkgenerated");
@@ -795,6 +810,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
// To link configuration to real loaded worlds.
registerEvent(Event.Type.WORLD_LOAD, worldTrigger);
registerEvent(Event.Type.WORLD_UNLOAD, worldTrigger);
}
private static File combinePaths(File parent, String path) {
@@ -910,10 +926,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
if (c.equals("render") && checkPlayerPermission(sender,"render")) {
if (player != null) {
int invalidates = mapManager.touch(toLoc(player.getLocation()), "render");
sender.sendMessage("Queued " + invalidates + " tiles" + (invalidates == 0
? " (world is not loaded?)"
: "..."));
Location loc = player.getLocation();
mapManager.touch(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "render");
sender.sendMessage("Tile render queued.");
}
else {
sender.sendMessage("Command can only be issued by player.");
@@ -1015,7 +1032,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
w = mapManager.getWorld(wname);
if(w != null) {
DynmapLocation spawn = w.getSpawnLocation();
DynmapLocation loc = new DynmapLocation(wname, w.configuration.getInteger("center/x", spawn.x), w.configuration.getInteger("center/y", spawn.y), w.configuration.getInteger("center/z", spawn.z));
DynmapLocation loc = new DynmapLocation(wname, w.configuration.getDouble("center/x", spawn.x), w.configuration.getDouble("center/y", spawn.y), w.configuration.getDouble("center/z", spawn.z));
mapManager.renderFullWorld(loc,sender, map, false);
}
else
@@ -1546,6 +1563,16 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
}
}
@Override
public void onWorldUnload(WorldUnloadEvent event) {
/* Call listeners */
List<Listener> ll = event_handlers.get(event.getType());
if(ll != null) {
for(Listener l : ll) {
((WorldListener)l).onWorldUnload(event);
}
}
}
@Override
public void onChunkLoad(ChunkLoadEvent event) {
/* Call listeners */
List<Listener> ll = event_handlers.get(event.getType());
@@ -1636,6 +1663,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
pm.registerEvent(type, ourBlockEventHandler, Event.Priority.Monitor, this);
break;
case WORLD_LOAD:
case WORLD_UNLOAD:
case CHUNK_LOAD:
case CHUNK_POPULATED:
case SPAWN_CHANGE:
@@ -1690,12 +1718,12 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
*
* @param l0 - first location (required)
* @param l1 - second location (if null, only single point invalidated (l0))
* @return number of tiles queued to be rerendered
* @return zero or higher if request queued, -1 if error
*/
public int triggerRenderOfVolume(Location l0, Location l1) {
if(mapManager != null) {
if(l1 == null)
return mapManager.touch(l0.getWorld().getName(), l0.getBlockX(), l0.getBlockY(), l0.getBlockZ(), "api");
mapManager.touch(l0.getWorld().getName(), l0.getBlockX(), l0.getBlockY(), l0.getBlockZ(), "api");
else {
int minx = Math.min(l0.getBlockX(), l1.getBlockX());
int maxx = Math.max(l0.getBlockX(), l1.getBlockX());
@@ -1704,7 +1732,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
int minz = Math.min(l0.getBlockZ(), l1.getBlockZ());
int maxz = Math.max(l0.getBlockZ(), l1.getBlockZ());
return mapManager.touchVolume(l0.getWorld().getName(), minx, miny, minz, maxx, maxy, maxz, "api");
mapManager.touchVolume(l0.getWorld().getName(), minx, miny, minz, maxx, maxy, maxz, "api");
}
}
return 0;
@@ -1875,23 +1903,22 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
@Override
public int triggerRenderOfBlock(String wid, int x, int y, int z) {
if(mapManager != null)
return mapManager.touch(wid, x, y, z, "api");
else
return 0;
mapManager.touch(wid, x, y, z, "api");
return 0;
}
@Override
public int triggerRenderOfVolume(String wid, int minx, int miny, int minz, int maxx, int maxy, int maxz) {
if(mapManager != null) {
if((minx == maxx) && (miny == maxy) && (minz == maxz))
return mapManager.touch(wid, minx, miny, minz, "api");
mapManager.touch(wid, minx, miny, minz, "api");
else
return mapManager.touchVolume(wid, minx, miny, minz, maxx, maxy, maxz, "api");
mapManager.touchVolume(wid, minx, miny, minz, maxx, maxy, maxz, "api");
}
return 0;
}
private DynmapLocation toLoc(Location l) {
return new DynmapLocation(l.getWorld().getName(), l.getBlockX(), l.getBlockY(), l.getBlockZ());
}
}
}
+26 -3
View File
@@ -1,5 +1,7 @@
package org.dynmap;
import static org.dynmap.JSONUtils.s;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -26,7 +28,7 @@ public class DynmapWorld {
FORMAPONLY,
PERMANENT
}
public World world;
private World world;
public List<MapType> maps = new ArrayList<MapType>();
public UpdateQueue updates = new UpdateQueue();
public ConfigurationNode configuration;
@@ -46,7 +48,12 @@ public class DynmapWorld {
private HashSet<String> zoomoutupdates[] = new HashSet[0];
private boolean checkts = true; /* Check timestamps on first run with new configuration */
private boolean cancelled;
private String wname;
public DynmapWorld(World w) {
world = w;
wname = w.getName();
}
@SuppressWarnings("unchecked")
public void setExtraZoomOutLevels(int lvl) {
extrazoomoutlevels = lvl;
@@ -489,7 +496,7 @@ public class DynmapWorld {
}
/* Get world name */
public String getName() {
return world.getName();
return wname;
}
/* Get world spawn location */
public DynmapLocation getSpawnLocation() {
@@ -501,6 +508,22 @@ public class DynmapWorld {
}
public int hashCode() {
return world.hashCode();
return wname.hashCode();
}
public long getTime() {
return world.getTime();
}
public boolean hasStorm() {
return world.hasStorm();
}
public boolean isThundering() {
return world.isThundering();
}
public World getWorld() {
return world;
}
}
@@ -142,15 +142,13 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
if(plugin.mapManager == null) return;
//Handles Updates
for (DynmapWorld dynmapWorld : plugin.mapManager.getWorlds()) {
World world = dynmapWorld.world;
JSONObject update = new JSONObject();
update.put("timestamp", currentTimestamp);
ClientUpdateEvent clientUpdate = new ClientUpdateEvent(currentTimestamp - 30000, dynmapWorld, update);
plugin.events.trigger("buildclientupdate", clientUpdate);
outputFile = getStandaloneFile("dynmap_" + world.getName() + ".json");
outputTempFile = getStandaloneFile("dynmap_" + world.getName() + ".json.new");
outputFile = getStandaloneFile("dynmap_" + dynmapWorld.getName() + ".json");
outputTempFile = getStandaloneFile("dynmap_" + dynmapWorld.getName() + ".json.new");
int retrycnt = 0;
boolean done = false;
while(!done) {
+188 -86
View File
@@ -11,6 +11,7 @@ import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
@@ -86,6 +87,34 @@ public class MapManager {
private DynmapScheduledThreadPoolExecutor render_pool;
private static final int POOL_SIZE = 3;
/* Touch event queues */
private static class TouchEvent {
int x, y, z;
String world;
String reason;
@Override
public int hashCode() {
return (x << 16) ^ (y << 24) ^ z;
}
@Override
public boolean equals(Object o) {
if(this == o) return true;
TouchEvent te = (TouchEvent)o;
if((x != te.x) || (y != te.y) || (z != te.z) || (world.equals(te.world) == false))
return false;
return true;
}
}
private static class TouchVolumeEvent {
int xmin, ymin, zmin;
int xmax, ymax, zmax;
String world;
String reason;
}
private ConcurrentHashMap<TouchEvent, Object> touch_events = new ConcurrentHashMap<TouchEvent, Object>();
private LinkedList<TouchVolumeEvent> touch_volume_events = new LinkedList<TouchVolumeEvent>();
private Object touch_lock = new Object();
private HashMap<String, MapStats> mapstats = new HashMap<String, MapStats>();
private static class MapStats {
@@ -94,9 +123,10 @@ public class MapManager {
int updatedcnt;
int transparentcnt;
}
/* synchronized using 'lock' */
private HashMap<String, TriggerStats> trigstats = new HashMap<String, TriggerStats>();
private static class TriggerStats {
long callsmade;
long callswithtiles;
@@ -235,10 +265,10 @@ public class MapManager {
rendertype = RENDERTYPE_FULLRENDER;
}
else {
cxmin = (l.x - radius)>>4;
czmin = (l.z - radius)>>4;
cxmax = (l.x + radius+15)>>4;
czmax = (l.z + radius+15)>>4;
cxmin = ((int)l.x - radius)>>4;
czmin = ((int)l.z - radius)>>4;
cxmax = ((int)l.x + radius + 15)>>4;
czmax = ((int)l.z + radius + 15)>>4;
rendertype = RENDERTYPE_RADIUSRENDER;
}
this.mapname = mapname;
@@ -320,7 +350,7 @@ public class MapManager {
public HashMap<String,Object> saveState() {
HashMap<String,Object> v = new HashMap<String,Object>();
v.put("world", world.world.getName());
v.put("world", world.getName());
v.put("locX", loc.x);
v.put("locY", loc.y);
v.put("locZ", loc.z);
@@ -390,10 +420,10 @@ public class MapManager {
double rendtime = total_render_ns.doubleValue() * 0.000001 / rendercalls.get();
if(activemapcnt > 1)
sendMessage(String.format("%s of maps [%s] of '%s' completed - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render)",
rendertype, activemaps, world.world.getName(), rendercnt, msecpertile, rendtime));
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
else
sendMessage(String.format("%s of map '%s' of '%s' completed - %d tiles rendered (%.2f msec/map-tile, %.2f msec per render)",
rendertype, activemaps, world.world.getName(), rendercnt, msecpertile, rendtime));
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
/* Now, if fullrender, use the render bitmap to purge obsolete tiles */
if(rendertype.equals(RENDERTYPE_FULLRENDER)) {
if(activemapcnt == 1) {
@@ -428,7 +458,7 @@ public class MapManager {
}
}
if(map_index >= world.maps.size()) { /* Last one done? */
sendMessage(rendertype + " of '" + world.world.getName() + "' finished.");
sendMessage(rendertype + " of '" + world.getName() + "' finished.");
cleanup();
return;
}
@@ -453,7 +483,7 @@ public class MapManager {
renderedmaps.addAll(map.getMapsSharingRender(world));
/* Now, prime the render queue */
for (MapTile mt : map.getTiles(world, loc.x, loc.y, loc.z)) {
for (MapTile mt : map.getTiles(world, (int)loc.x, (int)loc.y, (int)loc.z)) {
if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) {
found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true);
renderQueue.add(mt);
@@ -462,7 +492,7 @@ public class MapManager {
if(!updaterender) { /* Only add other seed points for fullrender */
/* Add spawn location too (helps with some worlds where 0,64,0 may not be generated */
DynmapLocation sloc = world.getSpawnLocation();
for (MapTile mt : map.getTiles(world, sloc.x, sloc.y, sloc.z)) {
for (MapTile mt : map.getTiles(world, (int)sloc.x, (int)sloc.y, (int)sloc.z)) {
if (!found.getFlag(mt.tileOrdinalX(), mt.tileOrdinalY())) {
found.setFlag(mt.tileOrdinalX(), mt.tileOrdinalY(), true);
renderQueue.add(mt);
@@ -470,7 +500,7 @@ public class MapManager {
}
if(world.seedloc != null) {
for(DynmapLocation seed : world.seedloc) {
for (MapTile mt : map.getTiles(world, seed.x, seed.y, seed.z)) {
for (MapTile mt : map.getTiles(world, (int)seed.x, (int)seed.y, (int)seed.z)) {
if (!found.getFlag(mt.tileOrdinalX(),mt.tileOrdinalY())) {
found.setFlag(mt.tileOrdinalX(),mt.tileOrdinalY(), true);
renderQueue.add(mt);
@@ -499,8 +529,7 @@ public class MapManager {
}
tile = tile0;
}
World w = world.world;
boolean notdone = true;
if(tileset != null) {
@@ -513,14 +542,14 @@ public class MapManager {
final long ts = tstart;
Future<Boolean> future = mapman.render_pool.submit(new Callable<Boolean>() {
public Boolean call() {
return processTile(mt, mt.world.world, ts, cnt);
return processTile(mt, ts, cnt);
}
});
rslt.add(future);
}
}
/* Now, do our render (first one) */
notdone = processTile(tileset.get(0), w, tstart, cnt);
notdone = processTile(tileset.get(0), tstart, cnt);
/* Now, join with others */
for(int i = 0; i < rslt.size(); i++) {
try {
@@ -535,7 +564,7 @@ public class MapManager {
timeaccum = save_timeaccum + System.currentTimeMillis() - tstart;
}
else {
notdone = processTile(tile, w, tstart, 1);
notdone = processTile(tile, tstart, 1);
}
if(notdone) {
@@ -557,7 +586,7 @@ public class MapManager {
}
}
private boolean processTile(MapTile tile, World w, long tstart, int parallelcnt) {
private boolean processTile(MapTile tile, long tstart, int parallelcnt) {
/* Get list of chunks required for tile */
List<DynmapChunk> requiredChunks = tile.getRequiredChunks();
/* If we are doing radius limit render, see if any are inside limits */
@@ -622,10 +651,10 @@ public class MapManager {
double msecpertile = (double)timeaccum / (double)rendercnt / (double)activemapcnt;
if(activemapcnt > 1)
sendMessage(String.format("%s of maps [%s] of '%s' in progress - %d tiles rendered each (%.2f msec/map-tile, %.2f msec per render)",
rendertype, activemaps, world.world.getName(), rendercnt, msecpertile, rendtime));
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
else
sendMessage(String.format("%s of map '%s' of '%s' in progress - %d tiles rendered (%.2f msec/tile, %.2f msec per render)",
rendertype, activemaps, world.world.getName(), rendercnt, msecpertile, rendtime));
rendertype, activemaps, world.getName(), rendercnt, msecpertile, rendtime));
}
}
}
@@ -655,7 +684,7 @@ public class MapManager {
Future<Integer> f = scheduler.callSyncMethod(plug_in, new Callable<Integer>() {
public Integer call() throws Exception {
for(DynmapWorld w : worlds) {
int new_servertime = (int)(w.world.getTime() % 24000);
int new_servertime = (int)(w.getTime() % 24000);
/* Check if we went from night to day */
boolean wasday = w.servertime >= 0 && w.servertime < 13700;
boolean isday = new_servertime >= 0 && new_servertime < 13700;
@@ -688,6 +717,13 @@ public class MapManager {
}
}
private class DoTouchProcessing implements Runnable {
public void run() {
processTouchEvents();
scheduleDelayedJob(this, 1000); /* Once per second */
}
}
public MapManager(DynmapPlugin plugin, ConfigurationNode configuration) {
plug_in = plugin;
mapman = this;
@@ -838,8 +874,7 @@ public class MapManager {
}
String worldName = w.getName();
DynmapWorld dynmapWorld = new DynmapWorld();
dynmapWorld.world = w;
DynmapWorld dynmapWorld = new DynmapWorld(w);
dynmapWorld.configuration = worldConfiguration;
Log.verboseinfo("Loading maps of world '" + worldName + "'...");
for(MapType map : worldConfiguration.<MapType>createInstances("maps", new Class<?>[0], new Object[0])) {
@@ -928,7 +963,7 @@ public class MapManager {
else {
int insertIndex;
for(insertIndex = 0; insertIndex < worlds.size(); insertIndex++) {
Integer nextWorldIndex = indexLookup.get(worlds.get(insertIndex).world.getName());
Integer nextWorldIndex = indexLookup.get(worlds.get(insertIndex).getName());
if (nextWorldIndex == null || worldIndex < nextWorldIndex.intValue()) {
break;
}
@@ -941,9 +976,13 @@ public class MapManager {
if(saverestorepending)
loadPending(dynmapWorld);
}
public void deactivateWorld(String wname) {
Log.warning("World unloading not properly supported");
}
private void loadPending(DynmapWorld w) {
String wname = w.world.getName();
String wname = w.getName();
File f = new File(plug_in.getDataFolder(), wname + ".pending");
if(f.exists()) {
org.bukkit.util.config.Configuration saved = new org.bukkit.util.config.Configuration(f);
@@ -982,7 +1021,7 @@ public class MapManager {
List<MapTile> mt = tileQueue.popAll();
for(DynmapWorld w : worlds) {
boolean dosave = false;
File f = new File(plug_in.getDataFolder(), w.world.getName() + ".pending");
File f = new File(plug_in.getDataFolder(), w.getName() + ".pending");
org.bukkit.util.config.Configuration saved = new org.bukkit.util.config.Configuration(f);
ArrayList<ConfigurationNode> savedtiles = new ArrayList<ConfigurationNode>();
for(MapTile tile : mt) {
@@ -995,77 +1034,44 @@ public class MapManager {
if(savedtiles.size() > 0) { /* Something to save? */
saved.setProperty("tiles", savedtiles);
dosave = true;
Log.info("Saved " + savedtiles.size() + " pending tile renders in world '" + w.world.getName());
Log.info("Saved " + savedtiles.size() + " pending tile renders in world '" + w.getName());
}
FullWorldRenderState job = active_renders.get(w.world.getName());
FullWorldRenderState job = active_renders.get(w.getName());
if(job != null) {
saved.setProperty("job", job.saveState());
dosave = true;
Log.info("Saved active render job in world '" + w.world.getName());
Log.info("Saved active render job in world '" + w.getName());
}
if(dosave) {
saved.save();
Log.info("Saved " + savedtiles.size() + " pending tile renders in world '" + w.world.getName());
Log.info("Saved " + savedtiles.size() + " pending tile renders in world '" + w.getName());
}
}
}
public int touch(DynmapLocation l, String reason) {
return touch(l.world, l.x, l.y, l.z, reason);
}
public int touch(String wname, int x, int y, int z, String reason) {
DynmapWorld world = getWorld(wname);
if (world == null)
return 0;
int invalidates = 0;
for (int i = 0; i < world.maps.size(); i++) {
MapTile[] tiles = world.maps.get(i).getTiles(world, x, y, z);
for (int j = 0; j < tiles.length; j++) {
if(invalidateTile(tiles[j]))
invalidates++;
}
}
if(reason != null) {
TriggerStats ts = trigstats.get(reason);
if(ts == null) {
ts = new TriggerStats();
trigstats.put(reason, ts);
}
ts.callsmade++;
if(invalidates > 0) {
ts.callswithtiles++;
ts.tilesqueued += invalidates;
}
}
return invalidates;
public void touch(String wname, int x, int y, int z, String reason) {
TouchEvent evt = new TouchEvent();
evt.world = wname;
evt.x = x;
evt.y = y;
evt.z = z;
evt.reason = reason;
touch_events.putIfAbsent(evt, reason);
}
public int touchVolume(String wname, int minx, int miny, int minz, int maxx, int maxy, int maxz, String reason) {
DynmapWorld world = getWorld(wname);
if (world == null)
return 0;
int invalidates = 0;
for (int i = 0; i < world.maps.size(); i++) {
MapTile[] tiles = world.maps.get(i).getTiles(world, minx, miny, minz, maxx, maxy, maxz);
for (int j = 0; j < tiles.length; j++) {
if(invalidateTile(tiles[j]))
invalidates++;
}
public void touchVolume(String wname, int minx, int miny, int minz, int maxx, int maxy, int maxz, String reason) {
TouchVolumeEvent evt = new TouchVolumeEvent();
evt.world = wname;
evt.xmin = minx;
evt.xmax = maxx;
evt.ymin = miny;
evt.ymax = maxy;
evt.zmin = minz;
evt.zmax = maxz;
evt.reason = reason;
synchronized(touch_lock) {
touch_volume_events.add(evt);
}
if(reason != null) {
TriggerStats ts = trigstats.get(reason);
if(ts == null) {
ts = new TriggerStats();
trigstats.put(reason, ts);
}
ts.callsmade++;
if(invalidates > 0) {
ts.callswithtiles++;
ts.tilesqueued += invalidates;
}
}
return invalidates;
}
public boolean invalidateTile(MapTile tile) {
@@ -1089,10 +1095,11 @@ public class MapManager {
tileQueue.start();
scheduleDelayedJob(new DoZoomOutProcessing(), 60000);
scheduleDelayedJob(new CheckWorldTimes(), 5000);
scheduleDelayedJob(new DoTouchProcessing(), 1000);
/* Resume pending jobs */
for(FullWorldRenderState job : active_renders.values()) {
scheduleDelayedJob(job, 5000);
Log.info("Resumed render starting on world '" + job.world.world.getName() + "'...");
Log.info("Resumed render starting on world '" + job.world.getName() + "'...");
}
}
@@ -1169,7 +1176,7 @@ public class MapManager {
c.setHiddenFillStyle(w.hiddenchunkstyle);
}
c.setChunks(w.world, chunks);
c.setChunks(w.getWorld(), chunks);
if(c.setChunkDataTypes(blockdata, biome, highesty, rawbiome) == false)
Log.severe("CraftBukkit build does not support biome APIs");
if(chunks.size() == 0) { /* No chunks to get? */
@@ -1401,4 +1408,99 @@ public class MapManager {
}
}
}
/**
* Process touch events
*/
private void processTouchEvents() {
ArrayList<TouchEvent> te = null;
ArrayList<TouchVolumeEvent> tve = null;
if(touch_events.isEmpty() == false) {
te = new ArrayList<TouchEvent>(touch_events.keySet());
for(int i = 0; i < te.size(); i++) {
touch_events.remove(te.get(i));
}
}
synchronized(touch_lock) {
if(touch_volume_events.isEmpty() == false) {
tve = new ArrayList<TouchVolumeEvent>(touch_volume_events);
touch_volume_events.clear();
}
}
DynmapWorld world = null;
String wname = "";
/* If any touch events, process them */
if(te != null) {
for(TouchEvent evt : te) {
int invalidates = 0;
/* If different world, look it up */
if(evt.world.equals(wname) == false) {
wname = evt.world;
world = getWorld(wname);
}
if(world == null) continue;
for (int i = 0; i < world.maps.size(); i++) {
MapTile[] tiles = world.maps.get(i).getTiles(world, evt.x, evt.y, evt.z);
for (int j = 0; j < tiles.length; j++) {
if(invalidateTile(tiles[j]))
invalidates++;
}
}
if(evt.reason != null) {
synchronized(lock) {
TriggerStats ts = trigstats.get(evt.reason);
if(ts == null) {
ts = new TriggerStats();
trigstats.put(evt.reason, ts);
}
ts.callsmade++;
if(invalidates > 0) {
ts.callswithtiles++;
ts.tilesqueued += invalidates;
}
}
}
}
te.clear(); /* Clean up set */
}
/* If any volume touches */
if(tve != null) {
for(TouchVolumeEvent evt : tve) {
/* If different world, look it up */
if(evt.world.equals(wname) == false) {
wname = evt.world;
world = getWorld(wname);
}
if(world == null) continue;
int invalidates = 0;
for (int i = 0; i < world.maps.size(); i++) {
MapTile[] tiles = world.maps.get(i).getTiles(world, evt.xmin, evt.ymin, evt.zmin, evt.xmax, evt.ymax, evt.zmax);
for (int j = 0; j < tiles.length; j++) {
if(invalidateTile(tiles[j]))
invalidates++;
}
}
if(evt.reason != null) {
synchronized(lock) {
TriggerStats ts = trigstats.get(evt.reason);
if(ts == null) {
ts = new TriggerStats();
trigstats.put(evt.reason, ts);
}
ts.callsmade++;
if(invalidates > 0) {
ts.callswithtiles++;
ts.tilesqueued += invalidates;
}
}
}
}
/* Clean up */
tve.clear();
}
}
}
@@ -61,23 +61,22 @@ public class MarkersComponent extends ClientComponent {
World w = event.getWorld(); /* Get the world */
Location loc = w.getSpawnLocation(); /* Get location of spawn */
if(loc != null)
addUpdateWorld(w, loc);
addUpdateWorld(w, new DynmapLocation(w.getName(), loc.getX(), loc.getY(), loc.getZ()));
}
public void onSpawnChange(SpawnChangeEvent event) {
World w = event.getWorld(); /* Get the world */
Location loc = w.getSpawnLocation(); /* Get location of spawn */
if(loc != null)
addUpdateWorld(w, loc);
addUpdateWorld(w, new DynmapLocation(w.getName(), loc.getX(), loc.getY(), loc.getZ()));
}
};
plugin.registerEvent(org.bukkit.event.Event.Type.WORLD_LOAD, wl);
plugin.registerEvent(org.bukkit.event.Event.Type.SPAWN_CHANGE, wl);
/* Initialize already loaded worlds */
for(DynmapWorld w : plugin.getMapManager().getWorlds()) {
World world = w.world;
Location loc = world.getSpawnLocation();
DynmapLocation loc = w.getSpawnLocation();
if(loc != null)
addUpdateWorld(world, loc);
addUpdateWorld(w.getWorld(), loc);
}
}
/* If showing offline players as markers */
@@ -195,17 +194,17 @@ public class MarkersComponent extends ClientComponent {
}
}
private void addUpdateWorld(World w, Location loc) {
private void addUpdateWorld(World w, DynmapLocation loc) {
MarkerSet ms = api.getMarkerSet(MarkerSet.DEFAULT);
if(ms != null) {
String spawnid = "_spawn_" + w.getName();
Marker m = ms.findMarker(spawnid); /* See if defined */
if(m == null) { /* Not defined yet, add it */
ms.createMarker(spawnid, spawnlbl, w.getName(), loc.getX(), loc.getY(), loc.getZ(),
ms.createMarker(spawnid, spawnlbl, w.getName(), loc.x, loc.y, loc.z,
spawnicon, false);
}
else {
m.setLocation(w.getName(), loc.getX(), loc.getY(), loc.getZ());
m.setLocation(w.getName(), loc.z, loc.y, loc.z);
}
}
}
+1 -1
View File
@@ -554,7 +554,7 @@ public class FlatMap extends MapType {
@Override
public String getKey(String prefix) {
return world.world.getName() + "." + map.getPrefix();
return world.getName() + "." + map.getPrefix();
}
public boolean isHightestBlockYDataNeeded() { return true; }
@@ -21,9 +21,13 @@ public class HDMapManager {
public HashSet<HDMap> maps = new HashSet<HDMap>();
public HashMap<String, ArrayList<HDMap>> maps_by_world_perspective = new HashMap<String, ArrayList<HDMap>>();
public static boolean usegeneratedtextures;
public static boolean waterlightingfix;
public static boolean biomeshadingfix;
public void loadHDShaders(DynmapPlugin plugin) {
Log.verboseinfo("Loading shaders...");
File f = new File(plugin.getDataFolder(), "shaders.txt");
if(!plugin.updateUsingDefaultResource("/shaders.txt", f, "shaders")) {
return;
+90 -16
View File
@@ -75,6 +75,7 @@ public class TexturePack {
private static final int COLORMOD_PINETONED = 13;
private static final int COLORMOD_BIRCHTONED = 14;
private static final int COLORMOD_LILYTONED = 15;
private static final int COLORMOD_OLD_WATERSHADED = 16;
/* Special tile index values */
private static final int BLOCKINDEX_BLANK = -1;
@@ -120,6 +121,8 @@ public class TexturePack {
private int terrain_width, terrain_height;
private int native_scale;
private int water_toned_op = COLORMOD_WATERTONED;
private static final int IMG_GRASSCOLOR = 0;
private static final int IMG_FOLIAGECOLOR = 1;
private static final int IMG_WATER = 2;
@@ -173,6 +176,7 @@ public class TexturePack {
for(int i = 0; i < texmaps.length; i++) {
texmaps[i] = this;
}
}
public HDTextureMap(List<Integer> blockids, int databits, int[] faces, BlockTransparency trans, boolean userender) {
@@ -234,15 +238,20 @@ public class TexturePack {
private TexturePack(String tpname) throws FileNotFoundException {
ZipFile zf = null;
File texturedir = getTexturePackDirectory();
boolean use_generate = HDMapManager.usegeneratedtextures;
if(HDMapManager.biomeshadingfix == false)
water_toned_op = COLORMOD_OLD_WATERSHADED;
/* Set up for enough files */
imgs = new LoadedImage[IMG_CNT + addonfiles.size()];
/* Generate still and flowing water defaults */
generateWater();
generateWaterFlowing();
generateLava();
generateLavaFlow();
if(use_generate) {
generateWater();
generateWaterFlowing();
generateLava();
generateLavaFlow();
}
generateFire();
File f = new File(texturedir, tpname);
@@ -262,11 +271,27 @@ public class TexturePack {
}
loadTerrainPNG(is);
is.close();
/* Patch in generated defaults */
patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER);
patchTextureWithImage(IMG_WATERMOVING, BLOCKINDEX_MOVINGWATER);
patchTextureWithImage(IMG_LAVA, BLOCKINDEX_STATIONARYLAVA);
patchTextureWithImage(IMG_LAVAMOVING, BLOCKINDEX_MOVINGLAVA);
/* If not generating water, load it */
if(!use_generate) {
ze = zf.getEntry(WATER_PNG);
if(ze == null) {
File ff = new File(texturedir, STANDARDTP + "/" + WATER_PNG);
is = new FileInputStream(ff);
}
else {
is = zf.getInputStream(ze);
}
loadImage(is, IMG_WATER);
patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER);
patchTextureWithImage(IMG_WATER, BLOCKINDEX_MOVINGWATER);
is.close();
}
else {
patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER);
patchTextureWithImage(IMG_WATERMOVING, BLOCKINDEX_MOVINGWATER);
patchTextureWithImage(IMG_LAVA, BLOCKINDEX_STATIONARYLAVA);
patchTextureWithImage(IMG_LAVAMOVING, BLOCKINDEX_MOVINGLAVA);
}
patchTextureWithImage(IMG_FIRE, BLOCKINDEX_FIRE);
/* Try to find and load misc/grasscolor.png */
@@ -365,12 +390,26 @@ public class TexturePack {
fis = new FileInputStream(f);
loadTerrainPNG(fis);
fis.close();
/* Patch in generated defaults */
patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER);
patchTextureWithImage(IMG_WATERMOVING, BLOCKINDEX_MOVINGWATER);
patchTextureWithImage(IMG_LAVA, BLOCKINDEX_STATIONARYLAVA);
patchTextureWithImage(IMG_LAVAMOVING, BLOCKINDEX_MOVINGLAVA);
if(use_generate == false) { /* Not using generated - load water */
/* Check for misc/water.png */
f = new File(texturedir, tpname + "/" + WATER_PNG);
if(!f.canRead()) {
f = new File(texturedir, STANDARDTP + "/" + WATER_PNG);
}
fis = new FileInputStream(f);
loadImage(fis, IMG_WATER);
patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER);
patchTextureWithImage(IMG_WATER, BLOCKINDEX_MOVINGWATER);
fis.close();
}
else {
patchTextureWithImage(IMG_WATER, BLOCKINDEX_STATIONARYWATER);
patchTextureWithImage(IMG_WATERMOVING, BLOCKINDEX_MOVINGWATER);
patchTextureWithImage(IMG_LAVA, BLOCKINDEX_STATIONARYLAVA);
patchTextureWithImage(IMG_LAVAMOVING, BLOCKINDEX_MOVINGLAVA);
}
/* Patch in generated value */
patchTextureWithImage(IMG_FIRE, BLOCKINDEX_FIRE);
/* Check for misc/grasscolor.png */
@@ -454,6 +493,7 @@ public class TexturePack {
this.terrain_width = tp.terrain_width;
this.terrain_height = tp.terrain_height;
this.native_scale = tp.native_scale;
this.water_toned_op = tp.water_toned_op;
this.imgs = tp.imgs;
}
@@ -833,6 +873,27 @@ public class TexturePack {
}
}
/**
* Translate face ID - in case we've got options to fix it
*/
private static int translateFaceID(int id) {
int f = (id / 1000);
switch(f) {
case COLORMOD_PINETONED:
case COLORMOD_BIRCHTONED:
case COLORMOD_LILYTONED:
if(HDMapManager.biomeshadingfix == false) {
id = (COLORMOD_FOLIAGETONED * 1000) + (id % 1000);
}
break;
case COLORMOD_WATERTONED:
if(HDMapManager.biomeshadingfix == false) {
id = (COLORMOD_OLD_WATERSHADED * 1000) + (id % 1000);
}
break;
}
return id;
}
/**
* Load texture pack mappings from texture.txt file
*/
@@ -909,6 +970,10 @@ public class TexturePack {
trans = BlockTransparency.OPAQUE;
Log.severe("Texture mapping has invalid transparency setting - " + av[1] + " - line " + rdr.getLineNumber() + " of " + txtname);
}
/* If no water lighting fix */
if((blkids.contains(8) || blkids.contains(9)) && (HDMapManager.waterlightingfix == false)) {
trans = BlockTransparency.TRANSPARENT; /* Treat water as transparent if no fix */
}
}
else if(av[0].equals("userenderdata")) {
userenderdata = av[1].equals("true");
@@ -934,6 +999,8 @@ public class TexturePack {
if(databits < 0) databits = 0xFFFF;
/* If we have everything, build block */
if(blkids.size() > 0) {
for(int i = 0; i < faces.length; i++)
faces[i] = translateFaceID(faces[i]);
HDTextureMap map = new HDTextureMap(blkids, databits, faces, trans, userenderdata);
map.addToTable();
cnt++;
@@ -1023,6 +1090,7 @@ public class TexturePack {
}
}
}
}
/* Process any ore hiding mappings */
@@ -1095,7 +1163,7 @@ public class TexturePack {
}
/* If water block, to watercolor tone op */
if((blkid == 8) || (blkid == 9)) {
textop = COLORMOD_WATERTONED;
textop = water_toned_op;
}
}
@@ -1225,6 +1293,8 @@ public class TexturePack {
break;
}
break;
case COLORMOD_OLD_WATERSHADED:
break;
}
/* Read color from texture */
rslt.setARGB(texture[v*native_scale + u]);
@@ -1252,6 +1322,10 @@ public class TexturePack {
case COLORMOD_LILYTONED:
clrmult = 0xFF208030; /* from BlockLilyPad.java in MCP */
break;
case COLORMOD_OLD_WATERSHADED: /* Legacy water shading (wrong, but folks used it */
if(ss.do_water_shading)
li = imgs[IMG_WATERCOLOR];
break;
}
if(li != null) {
if((li.argb == null) || (!ss.do_biome_shading)) {
@@ -500,7 +500,7 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
private void freshenMarkerFiles() {
if(MapManager.mapman != null) {
for(DynmapWorld w : MapManager.mapman.worlds) {
dirty_worlds.add(w.world.getName());
dirty_worlds.add(w.getName());
}
}
}
@@ -1599,7 +1599,7 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
@Override
public void triggered(DynmapWorld t) {
/* Update markers for now-active world */
dirty_worlds.add(t.world.getName());
dirty_worlds.add(t.getName());
}
/* Remove icon */
@@ -8,7 +8,6 @@ import java.util.LinkedHashMap;
import java.util.Map;
import org.bukkit.ChunkSnapshot;
import org.dynmap.DynmapLocation;
public class SnapshotCache {
private CacheHashMap snapcache;
@@ -49,24 +48,9 @@ public class SnapshotCache {
snapcache = new CacheHashMap(max_size);
refqueue = new ReferenceQueue<ChunkSnapshot>();
}
private String getKey(DynmapLocation loc) {
return loc.world + ":" + (loc.x>>4) + ":" + (loc.z>>4);
}
private String getKey(String w, int cx, int cz) {
return w + ":" + cx + ":" + cz;
}
/**
* Invalidate cached snapshot, if in cache
*/
public void invalidateSnapshot(DynmapLocation loc) {
String key = getKey(loc);
CacheRec rec = snapcache.remove(key);
if(rec != null) {
snapcache.reverselookup.remove(rec.ref);
rec.ref.clear();
}
processRefQueue();
}
/**
* Invalidate cached snapshot, if in cache
*/
@@ -77,7 +61,7 @@ public class SnapshotCache {
snapcache.reverselookup.remove(rec.ref);
rec.ref.clear();
}
processRefQueue();
//processRefQueue();
}
/**
* Invalidate cached snapshot, if in cache
@@ -93,7 +77,7 @@ public class SnapshotCache {
}
}
}
processRefQueue();
//processRefQueue();
}
/**
* Look for chunk snapshot in cache
@@ -14,6 +14,8 @@ import org.json.simple.JSONObject;
public class ClientConfigurationHandler implements HttpHandler {
private DynmapPlugin plugin;
private byte[] cachedConfiguration = null;
private int cached_config_hashcode = 0;
public ClientConfigurationHandler(DynmapPlugin plugin) {
this.plugin = plugin;
plugin.events.addListener("worldactivated", new Event.Listener<DynmapWorld>() {
@@ -25,13 +27,14 @@ public class ClientConfigurationHandler implements HttpHandler {
}
@Override
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
if (cachedConfiguration == null) {
if ((cachedConfiguration == null) || (plugin.getConfigHashcode() != cached_config_hashcode)) {
JSONObject configurationObject = new JSONObject();
plugin.events.<JSONObject>trigger("buildclientconfiguration", configurationObject);
String s = configurationObject.toJSONString();
cachedConfiguration = s.getBytes("UTF-8");
cached_config_hashcode = plugin.getConfigHashcode();
}
String dateStr = new Date().toString();
@@ -42,7 +42,7 @@ public class ClientUpdateHandler implements HttpHandler {
if(plugin.mapManager != null) {
dynmapWorld = plugin.mapManager.getWorld(worldName);
}
if (dynmapWorld == null || dynmapWorld.world == null) {
if (dynmapWorld == null) {
response.status = WorldNotFound;
return;
}
+8
View File
@@ -188,6 +188,14 @@ enabletilehash: true
# Optional - enabled BetterGrass style rendering of grass and snow block sides
#better-grass: true
# Pre 0.29 render options - set all three to false if you want same results as 0.28 (i.e. you have existing maps and don't want to render)
# use-generated-textures: if true, use generated textures (same as client); false is static, pre 0.29 textures
# correct-water-lighting: if true, use corrected water lighting (same as client); false is legacy, pre 0.29 water (darker)
# correct-biome-shading: if true, use fixed color mappings for birch, pine, lily, and proper water shading (same as client); false is pre 0.29
use-generated-textures: true
correct-water-lighting: true
correct-biome-shading: true
# Control loading of player faces (if set to false, skins are never fetched)
#fetchskins: false
+2 -2
View File
@@ -812,7 +812,7 @@ DynMap.prototype = {
else
return ((a.name < b.name) ? -1 : ((a.name > b.name) ? 1 : 0));
});
if(me.options.showlayercontrol) {
if(me.options.showlayercontrol != "false") {
for(i = 0; i < me.layersetlist.length; i++) {
me.layercontrol.removeLayer(me.layersetlist[i].layer);
}
@@ -827,7 +827,7 @@ DynMap.prototype = {
for(i = 0; i < me.layersetlist.length; i++) {
if(me.layersetlist[i].layer === layer) {
me.layersetlist.splice(i, 1);
if(me.options.showlayercontrol)
if(me.options.showlayercontrol != "false")
me.layercontrol.removeLayer(layer);
break;
}