mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-29 12:07:41 +01:00
Merge remote branch 'upstream/master'
This commit is contained in:
commit
e2ea48ed1b
@ -9,17 +9,23 @@ import java.util.Map;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
public class ClientComponent extends Component {
|
||||
|
||||
private boolean disabled;
|
||||
|
||||
public ClientComponent(final DynmapPlugin plugin, final ConfigurationNode configuration) {
|
||||
super(plugin, configuration);
|
||||
plugin.events.addListener("buildclientconfiguration", new Event.Listener<JSONObject>() {
|
||||
@Override
|
||||
public void triggered(JSONObject root) {
|
||||
buildClientConfiguration(root);
|
||||
if(!disabled)
|
||||
buildClientConfiguration(root);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void disableComponent() {
|
||||
disabled = true;
|
||||
}
|
||||
|
||||
protected void buildClientConfiguration(JSONObject root) {
|
||||
JSONObject o = createClientConfiguration();
|
||||
a(root, "components", o);
|
||||
|
@ -11,10 +11,13 @@ import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.dynmap.utils.BlockLightLevel;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
public class ClientUpdateComponent extends Component {
|
||||
private BlockLightLevel bll = new BlockLightLevel();
|
||||
|
||||
public ClientUpdateComponent(final DynmapPlugin plugin, ConfigurationNode configuration) {
|
||||
super(plugin, configuration);
|
||||
plugin.events.addListener("buildclientupdate", new Event.Listener<ClientUpdateEvent>() {
|
||||
@ -53,9 +56,14 @@ public class ClientUpdateComponent extends Component {
|
||||
hide = true;
|
||||
}
|
||||
if(hideifunder < 15) {
|
||||
/*TODO: when pull accepted for getSkyLightLevel(), switch to that */
|
||||
if(pl.getWorld().getHighestBlockYAt(pl) > pl.getBlockY())
|
||||
hide = true;
|
||||
if(bll.isReady()) { /* If we can get real sky level */
|
||||
if(bll.getSkyLightLevel(pl.getBlock()) <= hideifunder)
|
||||
hide = true;
|
||||
}
|
||||
else {
|
||||
if(pl.getWorld().getHighestBlockYAt(pl) > pl.getBlockY())
|
||||
hide = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't leak player location for world not visible on maps, or if sendposition disbaled */
|
||||
|
@ -222,6 +222,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
permissions = new OpPermissions(new String[] { "fullrender", "cancelrender", "radiusrender", "resetstats", "reload", "purgequeue" });
|
||||
|
||||
dataDirectory = this.getDataFolder();
|
||||
if(dataDirectory.exists() == false)
|
||||
dataDirectory.mkdirs();
|
||||
|
||||
/* Initialize confguration.txt if needed */
|
||||
File f = new File(this.getDataFolder(), "configuration.txt");
|
||||
@ -432,7 +434,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
mapManager.sscache.invalidateSnapshot(loc);
|
||||
if(onplace) {
|
||||
mapManager.touch(loc);
|
||||
mapManager.touch(loc, "blockplace");
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,7 +445,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
mapManager.sscache.invalidateSnapshot(loc);
|
||||
if(onbreak) {
|
||||
mapManager.touch(loc);
|
||||
mapManager.touch(loc, "blockbreak");
|
||||
}
|
||||
}
|
||||
|
||||
@ -454,7 +456,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
mapManager.sscache.invalidateSnapshot(loc);
|
||||
if(onleaves) {
|
||||
mapManager.touch(loc);
|
||||
mapManager.touch(loc, "leavesdecay");
|
||||
}
|
||||
}
|
||||
|
||||
@ -465,7 +467,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
mapManager.sscache.invalidateSnapshot(loc);
|
||||
if(onburn) {
|
||||
mapManager.touch(loc);
|
||||
mapManager.touch(loc, "blockburn");
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,7 +478,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
mapManager.sscache.invalidateSnapshot(loc);
|
||||
if(onblockform) {
|
||||
mapManager.touch(loc);
|
||||
mapManager.touch(loc, "blockform");
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,7 +489,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
mapManager.sscache.invalidateSnapshot(loc);
|
||||
if(onblockfade) {
|
||||
mapManager.touch(loc);
|
||||
mapManager.touch(loc, "blockfade");
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,7 +500,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
mapManager.sscache.invalidateSnapshot(loc);
|
||||
if(onblockspread) {
|
||||
mapManager.touch(loc);
|
||||
mapManager.touch(loc, "blockspread");
|
||||
}
|
||||
}
|
||||
|
||||
@ -516,7 +518,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
dir = BlockFace.NORTH;
|
||||
}
|
||||
if(onpiston) {
|
||||
mapManager.touchVolume(loc, b.getRelative(dir, 2).getLocation());
|
||||
mapManager.touchVolume(loc, b.getRelative(dir, 2).getLocation(), "pistonretract");
|
||||
}
|
||||
for(int i = 0; i < 2; i++) {
|
||||
b = b.getRelative(dir, 1);
|
||||
@ -537,7 +539,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
dir = BlockFace.NORTH;
|
||||
}
|
||||
if(onpiston) {
|
||||
mapManager.touchVolume(loc, b.getRelative(dir, 1+event.getLength()).getLocation());
|
||||
mapManager.touchVolume(loc, b.getRelative(dir, 1+event.getLength()).getLocation(), "pistonextend");
|
||||
}
|
||||
for(int i = 0; i < 1+event.getLength(); i++) {
|
||||
b = b.getRelative(dir, 1);
|
||||
@ -577,12 +579,12 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
PlayerListener playerTrigger = new PlayerListener() {
|
||||
@Override
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
mapManager.touch(event.getPlayer().getLocation());
|
||||
mapManager.touch(event.getPlayer().getLocation(), "playerjoin");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
mapManager.touch(event.getPlayer().getLocation());
|
||||
mapManager.touch(event.getPlayer().getLocation(), "playermove");
|
||||
}
|
||||
};
|
||||
|
||||
@ -602,7 +604,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
Location loc = b.getLocation();
|
||||
mapManager.sscache.invalidateSnapshot(loc);
|
||||
if(onexplosion) {
|
||||
mapManager.touch(loc);
|
||||
mapManager.touch(loc, "entityexplode");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -620,13 +622,13 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
/* Touch extreme corners */
|
||||
int x = event.getChunk().getX() << 4;
|
||||
int z = event.getChunk().getZ() << 4;
|
||||
mapManager.touchVolume(new Location(event.getWorld(), x, 0, z), new Location(event.getWorld(), x+16, 128, z+16));
|
||||
mapManager.touchVolume(new Location(event.getWorld(), x, 0, z), new Location(event.getWorld(), x+16, 128, z+16), "chunkload");
|
||||
}
|
||||
@Override
|
||||
public void onChunkPopulate(ChunkPopulateEvent event) {
|
||||
int x = event.getChunk().getX() << 4;
|
||||
int z = event.getChunk().getZ() << 4;
|
||||
mapManager.touchVolume(new Location(event.getWorld(), x, 0, z), new Location(event.getWorld(), x+16, 128, z+16));
|
||||
mapManager.touchVolume(new Location(event.getWorld(), x, 0, z), new Location(event.getWorld(), x+16, 128, z+16), "chunkgenerate");
|
||||
}
|
||||
@Override
|
||||
public void onWorldLoad(WorldLoadEvent event) {
|
||||
@ -725,6 +727,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
"radiusrender",
|
||||
"reload",
|
||||
"stats",
|
||||
"triggerstats",
|
||||
"resetstats",
|
||||
"sendtoweb",
|
||||
"purgequeue" }));
|
||||
@ -753,7 +756,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if (c.equals("render") && checkPlayerPermission(sender,"render")) {
|
||||
if (player != null) {
|
||||
int invalidates = mapManager.touch(player.getLocation());
|
||||
int invalidates = mapManager.touch(player.getLocation(), "render");
|
||||
sender.sendMessage("Queued " + invalidates + " tiles" + (invalidates == 0
|
||||
? " (world is not loaded?)"
|
||||
: "..."));
|
||||
@ -860,6 +863,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
mapManager.printStats(sender, null);
|
||||
else
|
||||
mapManager.printStats(sender, args[1]);
|
||||
} else if (c.equals("triggerstats") && checkPlayerPermission(sender, "stats")) {
|
||||
mapManager.printTriggerStats(sender);
|
||||
} else if (c.equals("resetstats") && checkPlayerPermission(sender, "resetstats")) {
|
||||
if(args.length == 1)
|
||||
mapManager.resetStats(sender, null);
|
||||
@ -1322,9 +1327,9 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public int triggerRenderOfVolume(Location l0, Location l1) {
|
||||
if(mapManager != null) {
|
||||
if(l1 == null)
|
||||
return mapManager.touch(l0);
|
||||
return mapManager.touch(l0, "api");
|
||||
else
|
||||
return mapManager.touchVolume(l0, l1);
|
||||
return mapManager.touchVolume(l0, l1, "api");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -80,6 +80,14 @@ public class MapManager {
|
||||
int updatedcnt;
|
||||
int transparentcnt;
|
||||
}
|
||||
|
||||
private HashMap<String, TriggerStats> trigstats = new HashMap<String, TriggerStats>();
|
||||
|
||||
private static class TriggerStats {
|
||||
long callsmade;
|
||||
long callswithtiles;
|
||||
long tilesqueued;
|
||||
}
|
||||
|
||||
public DynmapWorld getWorld(String name) {
|
||||
DynmapWorld world = worldsLookup.get(name);
|
||||
@ -862,8 +870,8 @@ public class MapManager {
|
||||
for(ConfigurationNode tile : tiles) {
|
||||
MapTile mt = MapTile.restoreTile(w, tile); /* Restore tile, if possible */
|
||||
if(mt != null) {
|
||||
invalidateTile(mt);
|
||||
cnt++;
|
||||
if(invalidateTile(mt))
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if(cnt > 0)
|
||||
@ -916,7 +924,7 @@ public class MapManager {
|
||||
}
|
||||
}
|
||||
|
||||
public int touch(Location l) {
|
||||
public int touch(Location l, String reason) {
|
||||
DynmapWorld world = getWorld(l.getWorld().getName());
|
||||
if (world == null)
|
||||
return 0;
|
||||
@ -924,14 +932,26 @@ public class MapManager {
|
||||
for (int i = 0; i < world.maps.size(); i++) {
|
||||
MapTile[] tiles = world.maps.get(i).getTiles(l);
|
||||
for (int j = 0; j < tiles.length; j++) {
|
||||
invalidateTile(tiles[j]);
|
||||
invalidates++;
|
||||
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 int touchVolume(Location l0, Location l1) {
|
||||
public int touchVolume(Location l0, Location l1, String reason) {
|
||||
DynmapWorld world = getWorld(l0.getWorld().getName());
|
||||
if (world == null)
|
||||
return 0;
|
||||
@ -939,16 +959,27 @@ public class MapManager {
|
||||
for (int i = 0; i < world.maps.size(); i++) {
|
||||
MapTile[] tiles = world.maps.get(i).getTiles(l0, l1);
|
||||
for (int j = 0; j < tiles.length; j++) {
|
||||
invalidateTile(tiles[j]);
|
||||
invalidates++;
|
||||
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 invalidateTile(MapTile tile) {
|
||||
if(tileQueue.push(tile))
|
||||
Debug.debug("Invalidating tile " + tile.getFilename());
|
||||
public boolean invalidateTile(MapTile tile) {
|
||||
return tileQueue.push(tile);
|
||||
}
|
||||
|
||||
public static boolean scheduleDelayedJob(Runnable job, long delay_in_msec) {
|
||||
@ -1149,6 +1180,19 @@ public class MapManager {
|
||||
act += wn + " ";
|
||||
sender.sendMessage(" Active render jobs: " + act);
|
||||
}
|
||||
/**
|
||||
* Print trigger statistics command
|
||||
*/
|
||||
public void printTriggerStats(CommandSender sender) {
|
||||
sender.sendMessage("Render Trigger Statistics:");
|
||||
synchronized(lock) {
|
||||
for(String k: new TreeSet<String>(trigstats.keySet())) {
|
||||
TriggerStats ts = trigstats.get(k);
|
||||
sender.sendMessage(" " + k + ": calls=" + ts.callsmade + ", calls-adding-tiles=" + ts.callswithtiles + ", tiles-added=" + ts.tilesqueued);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset statistics
|
||||
*/
|
||||
@ -1163,6 +1207,12 @@ public class MapManager {
|
||||
ms.updatedcnt = 0;
|
||||
ms.transparentcnt = 0;
|
||||
}
|
||||
for(String k : trigstats.keySet()) {
|
||||
TriggerStats ts = trigstats.get(k);
|
||||
ts.callsmade = 0;
|
||||
ts.callswithtiles = 0;
|
||||
ts.tilesqueued = 0;
|
||||
}
|
||||
}
|
||||
sscache.resetStats();
|
||||
sender.sendMessage("Tile Render Statistics reset");
|
||||
|
@ -38,13 +38,7 @@ public abstract class MapTile {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof MapTile) {
|
||||
MapTile t = (MapTile)obj;
|
||||
return getFilename().equals(t.getFilename()) && getWorld().equals(t.getWorld());
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
public abstract boolean equals(Object obj);
|
||||
|
||||
public abstract String getKey();
|
||||
|
||||
|
@ -81,7 +81,7 @@ public class KzedZoomedMapTile extends MapTile {
|
||||
if (obj instanceof KzedZoomedMapTile) {
|
||||
return ((KzedZoomedMapTile) obj).originalTile.equals(originalTile);
|
||||
}
|
||||
return super.equals(obj);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@ import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
import org.bukkit.util.config.ConfigurationNode;
|
||||
import org.dynmap.Client;
|
||||
@ -52,6 +53,7 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
private HashMap<String, MarkerSetImpl> markersets = new HashMap<String, MarkerSetImpl>();
|
||||
private HashMap<String, List<Location>> pointaccum = new HashMap<String, List<Location>>();
|
||||
private Server server;
|
||||
private Plugin dynmap;
|
||||
static MarkerAPIImpl api;
|
||||
|
||||
/* Built-in icons */
|
||||
@ -153,6 +155,30 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
msg = "setupdated";
|
||||
}
|
||||
}
|
||||
|
||||
private boolean stop = false;
|
||||
private Set<String> dirty_worlds = new HashSet<String>();
|
||||
private boolean dirty_markers = false;
|
||||
|
||||
private class DoFileWrites implements Runnable {
|
||||
public void run() {
|
||||
if(stop)
|
||||
return;
|
||||
/* Write markers first - drives JSON updates too */
|
||||
if(dirty_markers) {
|
||||
doSaveMarkers();
|
||||
dirty_markers = false;
|
||||
}
|
||||
/* Process any dirty worlds */
|
||||
if(!dirty_worlds.isEmpty()) {
|
||||
for(String world : dirty_worlds) {
|
||||
writeMarkersFile(world);
|
||||
}
|
||||
dirty_worlds.clear();
|
||||
}
|
||||
server.getScheduler().scheduleSyncDelayedTask(dynmap, this, 20);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton initializer
|
||||
@ -162,6 +188,7 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
api.cleanup(plugin);
|
||||
}
|
||||
api = new MarkerAPIImpl();
|
||||
api.dynmap = plugin;
|
||||
api.server = plugin.getServer();
|
||||
/* Initialize persistence file name */
|
||||
api.markerpersist = new File(plugin.getDataFolder(), "markers.yml");
|
||||
@ -200,16 +227,28 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
api.freshenMarkerFiles();
|
||||
/* Add listener so we update marker files for other worlds as they become active */
|
||||
plugin.events.addListener("worldactivated", api);
|
||||
|
||||
api.scheduleWriteJob(); /* Start write job */
|
||||
|
||||
return api;
|
||||
}
|
||||
|
||||
private void scheduleWriteJob() {
|
||||
server.getScheduler().scheduleSyncDelayedTask(dynmap, new DoFileWrites(), 20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup
|
||||
*/
|
||||
public void cleanup(DynmapPlugin plugin) {
|
||||
plugin.events.removeListener("worldactivated", api);
|
||||
|
||||
stop = true;
|
||||
if(dirty_markers) {
|
||||
doSaveMarkers();
|
||||
dirty_markers = false;
|
||||
}
|
||||
|
||||
for(MarkerIconImpl icn : markericons.values())
|
||||
icn.cleanup();
|
||||
markericons.clear();
|
||||
@ -348,6 +387,11 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
* Save persistence for markers
|
||||
*/
|
||||
static void saveMarkers() {
|
||||
if(api != null) {
|
||||
api.dirty_markers = true;
|
||||
}
|
||||
}
|
||||
private void doSaveMarkers() {
|
||||
if(api != null) {
|
||||
Configuration conf = new Configuration(api.markerpersist); /* Make configuration object */
|
||||
/* First, save icon definitions */
|
||||
@ -386,7 +430,7 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
private void freshenMarkerFiles() {
|
||||
if(MapManager.mapman != null) {
|
||||
for(DynmapWorld w : MapManager.mapman.worlds) {
|
||||
writeMarkersFile(w.world.getName());
|
||||
dirty_worlds.add(w.world.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -430,7 +474,7 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
static void markerUpdated(MarkerImpl marker, MarkerUpdate update) {
|
||||
/* Freshen marker file for the world for this marker */
|
||||
if(api != null)
|
||||
api.writeMarkersFile(marker.getWorld());
|
||||
api.dirty_worlds.add(marker.getWorld());
|
||||
/* Enqueue client update */
|
||||
if(MapManager.mapman != null)
|
||||
MapManager.mapman.pushUpdate(marker.getWorld(), new MarkerUpdated(marker, update == MarkerUpdate.DELETED));
|
||||
@ -443,7 +487,7 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
static void areaMarkerUpdated(AreaMarkerImpl marker, MarkerUpdate update) {
|
||||
/* Freshen marker file for the world for this marker */
|
||||
if(api != null)
|
||||
api.writeMarkersFile(marker.getWorld());
|
||||
api.dirty_worlds.add(marker.getWorld());
|
||||
/* Enqueue client update */
|
||||
if(MapManager.mapman != null)
|
||||
MapManager.mapman.pushUpdate(marker.getWorld(), new AreaMarkerUpdated(marker, update == MarkerUpdate.DELETED));
|
||||
@ -1381,7 +1425,7 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
/**
|
||||
* Write markers file for given world
|
||||
*/
|
||||
public void writeMarkersFile(String wname) {
|
||||
private void writeMarkersFile(String wname) {
|
||||
Map<String, Object> markerdata = new HashMap<String, Object>();
|
||||
|
||||
File f = new File(markertiledir, "marker_" + wname + ".json");
|
||||
@ -1465,7 +1509,7 @@ public class MarkerAPIImpl implements MarkerAPI, Event.Listener<DynmapWorld> {
|
||||
@Override
|
||||
public void triggered(DynmapWorld t) {
|
||||
/* Update markers for now-active world */
|
||||
writeMarkersFile(t.world.getName());
|
||||
dirty_worlds.add(t.world.getName());
|
||||
}
|
||||
|
||||
/* Remove icon */
|
||||
|
@ -52,11 +52,11 @@ public class MarkerSignManager {
|
||||
set = v.substring(4);
|
||||
evt.setLine(i, "");
|
||||
}
|
||||
else if(label.length() == 0) {
|
||||
label = escapeMarkup(v);
|
||||
}
|
||||
else {
|
||||
label = label + "<br/>" + escapeMarkup(v);
|
||||
else if(v.length() > 0) {
|
||||
if(label.length() > 0) {
|
||||
label = label + "<br/>";
|
||||
}
|
||||
label = label + escapeMarkup(v);
|
||||
}
|
||||
}
|
||||
/* Get the set and see if the marker is already defined */
|
||||
|
@ -24,16 +24,32 @@ public class RegionsComponent extends ClientComponent {
|
||||
private TownyConfigHandler towny;
|
||||
private FactionsConfigHandler factions;
|
||||
private String regiontype;
|
||||
|
||||
private static String deprecated_ids[] = { "Residence", "Factions", "Towny", "WorldGuard" };
|
||||
private static String deprecated_new_plugins[] = { "dynmap-residence", "Dynmap-Factions", "Dynmap-Towny", "Dynmap-WorldGuard" };
|
||||
|
||||
public RegionsComponent(final DynmapPlugin plugin, final ConfigurationNode configuration) {
|
||||
super(plugin, configuration);
|
||||
|
||||
regiontype = configuration.getString("name", "WorldGuard");
|
||||
/* Check if a deprecated component */
|
||||
for(int i = 0; i < deprecated_ids.length; i++) {
|
||||
if(regiontype.equals(deprecated_ids[i])) { /* If match */
|
||||
/* See if new plugin is installed - disable if it is */
|
||||
if(plugin.getServer().getPluginManager().getPlugin(deprecated_new_plugins[i]) != null) {
|
||||
Log.info("Region component for '" + regiontype + "' disabled, replaced by '" + deprecated_new_plugins[i] + "' plugin, which is installed");
|
||||
disableComponent();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
Log.info("Region component for '" + regiontype + "' has been DEPRECATED - migrate to '" + deprecated_new_plugins[i] + "' plugin");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For internal webserver.
|
||||
String fname = configuration.getString("filename", "regions.yml");
|
||||
|
||||
regiontype = configuration.getString("name", "WorldGuard");
|
||||
|
||||
|
||||
/* Load special handler for Towny */
|
||||
if(regiontype.equals("Towny")) {
|
||||
towny = new TownyConfigHandler(configuration);
|
||||
|
80
src/main/java/org/dynmap/utils/BlockLightLevel.java
Normal file
80
src/main/java/org/dynmap/utils/BlockLightLevel.java
Normal file
@ -0,0 +1,80 @@
|
||||
package org.dynmap.utils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.dynmap.Log;
|
||||
|
||||
/**
|
||||
* Wrapper for accessing raw light levels for given block
|
||||
*/
|
||||
public class BlockLightLevel {
|
||||
private Method gethandle;
|
||||
private Method getrawlight;
|
||||
private Object enum_sky;
|
||||
private Object enum_block;
|
||||
private boolean ready;
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public BlockLightLevel() {
|
||||
/* Get CraftChunk.getChunkSnapshot(boolean,boolean,boolean) and CraftChunk.getHandle() */
|
||||
try {
|
||||
Class c = Class.forName("org.bukkit.craftbukkit.CraftChunk");
|
||||
gethandle = c.getDeclaredMethod("getHandle", new Class[0]);
|
||||
Class enumskyblock = Class.forName("net.minecraft.server.EnumSkyBlock");
|
||||
Object[] enumvals = enumskyblock.getEnumConstants();
|
||||
for(int i = 0; i < enumvals.length; i++) {
|
||||
String ev = enumvals[i].toString();
|
||||
if(ev.equals("Sky")) {
|
||||
enum_sky = enumvals[i];
|
||||
}
|
||||
else if(ev.equals("Block")) {
|
||||
enum_block = enumvals[i];
|
||||
}
|
||||
}
|
||||
Class cc = Class.forName("net.minecraft.server.Chunk");
|
||||
getrawlight = cc.getDeclaredMethod("a", new Class[] { enumskyblock, int.class, int.class, int.class });
|
||||
} catch (ClassNotFoundException cnfx) {
|
||||
} catch (NoSuchMethodException nsmx) {
|
||||
}
|
||||
if((gethandle != null) && (enum_sky != null) && (enum_block != null) && (getrawlight != null)) {
|
||||
ready = true;
|
||||
}
|
||||
else {
|
||||
Log.warning("Block raw light level API not available");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return ready;
|
||||
}
|
||||
|
||||
public int getSkyLightLevel(Block b) {
|
||||
try {
|
||||
Object hand = gethandle.invoke(b.getChunk());
|
||||
if(hand != null) {
|
||||
Integer v = (Integer)getrawlight.invoke(hand, enum_sky, b.getX() & 0xF, b.getY() & 0x7F, b.getZ() & 0xF);
|
||||
return v;
|
||||
}
|
||||
} catch (InvocationTargetException itx) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getBlockLightLevel(Block b) {
|
||||
try {
|
||||
Object hand = gethandle.invoke(b.getChunk());
|
||||
if(hand != null) {
|
||||
Integer v = (Integer)getrawlight.invoke(hand, enum_block, b.getX() & 0xF, b.getY() & 0x7F, b.getZ() & 0xF);
|
||||
return v;
|
||||
}
|
||||
} catch (InvocationTargetException itx) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -113,129 +113,6 @@ components:
|
||||
# timeout: 1800 # in seconds (1800 seconds = 30 minutes)
|
||||
# redirecturl: inactive.html
|
||||
# #showmessage: 'You were inactive for too long.'
|
||||
|
||||
#- class: org.dynmap.regions.RegionsComponent
|
||||
# type: regions
|
||||
# name: WorldGuard
|
||||
# useworldpath: true
|
||||
# filename: regions.yml
|
||||
# basenode: regions
|
||||
# use3dregions: true
|
||||
# regionstyle:
|
||||
# strokeColor: "#FF0000"
|
||||
# strokeOpacity: 0.8
|
||||
# strokeWeight: 3
|
||||
# fillColor: "#FF0000"
|
||||
# fillOpacity: 0.35
|
||||
# # Optional setting to limit which regions to show, by name - if commented out, all regions are shown
|
||||
# visibleregions:
|
||||
# - homebase
|
||||
# - miningsite
|
||||
# # Optional setting to hide specific regions, by name
|
||||
# hiddenregions:
|
||||
# - hiddenplace
|
||||
# - secretsite
|
||||
# # Optional per-region overrides for regionstyle (any defined replace those in regionstyle)
|
||||
# customstyle:
|
||||
# homebase:
|
||||
# strokeColor: "#00FF00"
|
||||
# # Optional - make layer hidden by default
|
||||
# hidebydefault: true
|
||||
# # Optional - ordering priority in layer menu (low goes before high - default is 0)
|
||||
# layerprio: 1
|
||||
|
||||
#- class: org.dynmap.regions.RegionsComponent
|
||||
# type: regions
|
||||
# name: Residence
|
||||
# useworldpath: false
|
||||
# filename: res.yml
|
||||
# basenode: Residences
|
||||
# use3dregions: false
|
||||
# infowindow: '<div class="infowindow"><span style="font-size:120%;">%regionname%</span><br /> Owner <span style="font-weight:bold;">%playerowners%</span><br />Flags<br /><span style="font-weight:bold;">%flags%</span></div>'
|
||||
# regionstyle:
|
||||
# strokeColor: "#FF0000"
|
||||
# strokeOpacity: 0.8
|
||||
# strokeWeight: 3
|
||||
# fillColor: "#FF0000"
|
||||
# fillOpacity: 0.35
|
||||
# # Optional setting to limit which regions to show, by name - if commented out, all regions are shown
|
||||
# visibleregions:
|
||||
# - homebase
|
||||
# - miningsite
|
||||
# - area.subzone1
|
||||
# # Optional setting to hide specific regions, by name
|
||||
# hiddenregions:
|
||||
# - hiddenplace
|
||||
# - secretsite
|
||||
# # Optional per-region overrides for regionstyle (any defined replace those in regionstyle)
|
||||
# customstyle:
|
||||
# homebase:
|
||||
# strokeColor: "#00FF00"
|
||||
# # Optional groups (subareas under a residence) overrides for regionstyle (any defined replace those in regionstyle)
|
||||
# groupstyle:
|
||||
# homebase:
|
||||
# strokeColor: "#007F00"
|
||||
# # Optional - make layer hidden by default
|
||||
# hidebydefault: true
|
||||
# # Optional - ordering priority in layer menu (low goes before high - default is 0)
|
||||
# layerprio: 1
|
||||
|
||||
#- class: org.dynmap.regions.RegionsComponent
|
||||
# type: regions
|
||||
# name: Towny
|
||||
# use3dregions: false
|
||||
# infowindow: '<div class="infowindow"><span style="font-size:120%;">%regionname% (%nation%)</span><br /> Mayor <span style="font-weight:bold;">%playerowners%</span><br /> Associates <span style="font-weight:bold;">%playermanagers%</span><br/>Flags<br /><span style="font-weight:bold;">%flags%</span></div>'
|
||||
# regionstyle:
|
||||
# strokeColor: "#FF0000"
|
||||
# strokeOpacity: 0.8
|
||||
# strokeWeight: 3
|
||||
# fillColor: "#FF0000"
|
||||
# fillOpacity: 0.35
|
||||
# # Optional setting to limit which regions to show, by name - if commented out, all regions are shown
|
||||
# visibleregions:
|
||||
# - homebase
|
||||
# - miningsite
|
||||
# # Optional setting to hide specific regions, by name
|
||||
# hiddenregions:
|
||||
# - hiddenplace
|
||||
# - secretsite
|
||||
# # Optional per-town overrides for regionstyle (any defined replace those in regionstyle)
|
||||
# customstyle:
|
||||
# homebase:
|
||||
# strokeColor: "#00FF00"
|
||||
# # Optional per-nation overrides for regionstyle (any defined replace those in regionstyle)
|
||||
# groupstyle:
|
||||
# MyNation:
|
||||
# strokeColor: "#007F00"
|
||||
# # Optional - make layer hidden by default
|
||||
# hidebydefault: true
|
||||
|
||||
#- class: org.dynmap.regions.RegionsComponent
|
||||
# type: regions
|
||||
# name: Factions
|
||||
# use3dregions: false
|
||||
# infowindow: '<div class="infowindow"><span style="font-size:120%;">%regionname%</span><br />Flags<br /><span style="font-weight:bold;">%flags%</span></div>'
|
||||
# regionstyle:
|
||||
# strokeColor: "#FF0000"
|
||||
# strokeOpacity: 0.8
|
||||
# strokeWeight: 3
|
||||
# fillColor: "#FF0000"
|
||||
# fillOpacity: 0.35
|
||||
# # Optional setting to limit which regions to show, by name - if commented out, all regions are shown
|
||||
# visibleregions:
|
||||
# - faction1
|
||||
# - faction2
|
||||
# # Optional setting to hide specific regions, by name
|
||||
# hiddenregions:
|
||||
# - hiddenfaction
|
||||
# # Optional per-faction overrides for regionstyle (any defined replace those in regionstyle)
|
||||
# customstyle:
|
||||
# faction1:
|
||||
# strokeColor: "#00FF00"
|
||||
# # Optional - make layer hidden by default
|
||||
# hidebydefault: true
|
||||
# # Optional - ordering priority in layer menu (low goes before high - default is 0)
|
||||
# layerprio: 1
|
||||
|
||||
#- class: org.dynmap.TestComponent
|
||||
# stuff: "This is some configuration-value"
|
||||
@ -281,7 +158,7 @@ enabletilehash: true
|
||||
# Control behavior for new (1.9+) compass orientation (sunrise moved 90 degrees: east is now what used to be south)
|
||||
# default is 'pre19' for 1.8 server (existing orientation), 'newrose' for 1.9+ (preserve maps, rotate rose)
|
||||
# 'newnorth' is used to rotate maps and rose (requires fullrender of any HDMap map - same as 'newrose' for FlatMap or KzedMap)
|
||||
#compass-mode: newnorth
|
||||
compass-mode: newnorth
|
||||
|
||||
# Enable Industrial Craft 2 block rendering support
|
||||
#ic2-support: true
|
||||
|
@ -8,7 +8,7 @@ commands:
|
||||
description: Controls Dynmap.
|
||||
usage: |
|
||||
/<command> hide - hides the player from the map.
|
||||
/<command> hide TheDude - hides the player 'TheDude' from the map.
|
||||
/<command> hide TheDude - hides the player 'TheDude' on the map.
|
||||
/<command> show - shows the player on the map.
|
||||
/<command> show TheDude - shows the player 'TheDude' on the map.
|
||||
/<command> render - Renders the tile at your location.
|
||||
@ -21,6 +21,7 @@ commands:
|
||||
/<command> cancelrender world - Cancels any active renders of world 'world'
|
||||
/<command> stats - Show render statistics.
|
||||
/<command> stats world - Show render statistics for maps on world 'world'.
|
||||
/<command> triggerstats - Show render trigger statistics
|
||||
/<command> resetstats - Reset render statistics.
|
||||
/<command> resetstats world - Reset render statistics for maps on world 'world'.
|
||||
/<command> sendtoweb msg - Send message to web users
|
||||
@ -125,7 +126,7 @@ permissions:
|
||||
description: Allows /dynmap reload
|
||||
default: op
|
||||
dynmap.stats:
|
||||
description: Allows /dynmap stats or /dynmap stats <world>
|
||||
description: Allows /dynmap stats, /dynmap stats <world>, or /dynmap triggerstats
|
||||
default: true
|
||||
dynmap.resetstats:
|
||||
description: Allows /dynmap resetstats or /dynmap resetstats <world>
|
||||
|
@ -92,29 +92,35 @@ block:id=26,data=11,top=6135,bottom=6135,south=152,east=7151,west=151,transparen
|
||||
# Bed - foot - pointing south
|
||||
block:id=26,data=3,top=6134,bottom=6134,north=149,east=7150,west=150,transparency=TRANSPARENT
|
||||
# Powered rail - heading east-west - unpowered
|
||||
block:id=27,data=0,top=4163,bottom=4163,transparency=TRANSPARENT
|
||||
# Powered rail - incline to east - unpowered
|
||||
# Powered rail - incline to west - unpowered
|
||||
block:id=27,data=0,data=4,data=5,top=4163,bottom=4163,allsides=4,transparency=TRANSPARENT
|
||||
block:id=27,data=4,data=5,top=4163,bottom=4163,east=163,west=163,transparency=TRANSPARENT
|
||||
# Powered rail - heading east-west - powered
|
||||
block:id=27,data=8,top=4179,bottom=4179,transparency=TRANSPARENT
|
||||
# Powered rail - incline to east - powered
|
||||
# Powered rail - incline to west - powered
|
||||
block:id=27,data=8,data=12,data=13,top=4179,bottom=4179,allsides=4,transparency=TRANSPARENT
|
||||
block:id=27,data=12,data=13,top=4179,bottom=4179,east=179,west=179,transparency=TRANSPARENT
|
||||
# Powered rail - heading north-south - unpowered
|
||||
block:id=27,data=1,top=163,bottom=163,transparency=TRANSPARENT
|
||||
# Powered rail - inclined to north - unpowered
|
||||
# Powered rail - inclined to south - unpowered
|
||||
block:id=27,data=1,data=2,data=3,top=163,bottom=163,allsides=4,transparency=TRANSPARENT
|
||||
# Powered rail - heading north-sout - powered
|
||||
block:id=27,data=2,data=3,top=163,bottom=163,north=163,south=163,transparency=TRANSPARENT
|
||||
# Powered rail - heading north-south - powered
|
||||
block:id=27,data=9,top=179,bottom=179,transparency=TRANSPARENT
|
||||
# Powered rail - inclined to north - powered
|
||||
# Powered rail - inclined to south - powered
|
||||
block:id=27,data=9,data=10,data=11,top=179,bottom=179,allsides=4,transparency=TRANSPARENT
|
||||
block:id=27,data=10,data=11,top=179,bottom=179,north=179,south=179,transparency=TRANSPARENT
|
||||
# Detector rail - heading east-west
|
||||
block:id=28,data=0,top=4195,bottom=4195,transparency=TRANSPARENT
|
||||
# Detector rail - incline to east
|
||||
# Detector rail - incline to west
|
||||
block:id=28,data=0,data=4,data=5,top=4195,bottom=4195,allsides=4,transparency=TRANSPARENT
|
||||
block:id=28,data=4,data=5,top=4195,bottom=4195,east=195,west=195,transparency=TRANSPARENT
|
||||
# Detector rail - heading north-south
|
||||
block:id=28,data=1,top=195,bottom=195,transparency=TRANSPARENT
|
||||
# Detector rail - incline to north
|
||||
# Detector rail - incline to south
|
||||
block:id=28,data=1,data=2,data=3,top=195,bottom=195,allsides=4,transparency=TRANSPARENT
|
||||
block:id=28,data=2,data=3,top=195,bottom=195,north=195,south=195,transparency=TRANSPARENT
|
||||
# Sticky piston - facing down
|
||||
block:id=29,data=0,top=109,bottom=106,allsides=5108
|
||||
# Sticky piston - facing up
|
||||
@ -377,7 +383,7 @@ block:id=66,data=0,top=4128,bottom=4128,transparency=TRANSPARENT
|
||||
# Rail - incline to west
|
||||
block:id=66,data=4,data=5,top=4128,bottom=4128,east=128,west=128,transparency=TRANSPARENT
|
||||
# Rail - heading north-south
|
||||
block:id=66,data=1,top=128,bottom=128,allsides=4,transparency=TRANSPARENT
|
||||
block:id=66,data=1,top=128,bottom=128,transparency=TRANSPARENT
|
||||
# Rail - incline to north
|
||||
# Rail - incline to south
|
||||
block:id=66,data=2,data=3,top=128,bottom=128,north=128,south=128,transparency=TRANSPARENT
|
||||
|
Loading…
Reference in New Issue
Block a user