mirror of
https://github.com/encounter/dynmap.git
synced 2026-03-30 11:08:39 -07:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5482ddaa89 | |||
| 47455eb912 | |||
| 32a1c20fd0 | |||
| b85c38e3a7 | |||
| 5bc4de6a8b | |||
| 2d20fd11f7 | |||
| 6a4bb59d60 | |||
| ab45edb82c | |||
| 4f6bc05180 | |||
| 076681e188 | |||
| b7abfe7c06 | |||
| 3a88ac66a6 | |||
| d3b9367794 | |||
| 666840fc8b | |||
| 62f4c12147 | |||
| 4b3f2280b6 | |||
| df55606023 | |||
| 6fc5fddd44 | |||
| dea285c160 | |||
| 204641a4b0 |
@@ -4,8 +4,10 @@
|
||||
<artifactId>dynmap</artifactId>
|
||||
<name>dynmap</name>
|
||||
<properties>
|
||||
<timestamp>${maven.build.timestamp}</timestamp>
|
||||
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<BUILD_NUMBER>Dev</BUILD_NUMBER>
|
||||
<BUILD_NUMBER>Dev${timestamp}</BUILD_NUMBER>
|
||||
</properties>
|
||||
<url>http://github.com/webbukkit/dynmap/</url>
|
||||
<issueManagement>
|
||||
@@ -92,7 +94,7 @@
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.3.2-R3.0</version>
|
||||
<version>1.4.7-R1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dynmap</groupId>
|
||||
@@ -136,5 +138,5 @@
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<version>1.7</version>
|
||||
<version>1.8</version>
|
||||
</project>
|
||||
|
||||
@@ -44,7 +44,7 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
|
||||
nmsblockarray = getNMSClass("[Lnet.minecraft.server.Block;");
|
||||
nmsmaterial = getNMSClass("net.minecraft.server.Material");
|
||||
blockbyid = getField(nmsblock, new String[] { "byId" }, nmsblockarray);
|
||||
blockname = getPrivateField(nmsblock, new String[] { "name" }, String.class);
|
||||
blockname = getPrivateField(nmsblock, new String[] { "name", "b" }, String.class);
|
||||
material = getField(nmsblock, new String[] { "material" }, nmsmaterial);
|
||||
|
||||
/* Set up biomebase fields */
|
||||
|
||||
@@ -2,8 +2,13 @@ package org.dynmap.bukkit;
|
||||
/**
|
||||
* Bukkit specific implementation of DynmapWorld
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.permissions.Permission;
|
||||
@@ -12,6 +17,7 @@ import org.dynmap.DynmapChunk;
|
||||
import org.dynmap.DynmapLocation;
|
||||
import org.dynmap.DynmapWorld;
|
||||
import org.dynmap.utils.MapChunkCache;
|
||||
import org.dynmap.utils.TileFlags;
|
||||
|
||||
public class BukkitWorld extends DynmapWorld {
|
||||
private World world;
|
||||
@@ -160,4 +166,58 @@ public class BukkitWorld extends DynmapWorld {
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
// Return false if unimplemented
|
||||
@Override
|
||||
public int getChunkMap(TileFlags map) {
|
||||
map.clear();
|
||||
if (world == null) return -1;
|
||||
int cnt = 0;
|
||||
// Mark loaded chunks
|
||||
for(Chunk c : world.getLoadedChunks()) {
|
||||
map.setFlag(c.getX(), c.getZ(), true);
|
||||
cnt++;
|
||||
}
|
||||
File f = world.getWorldFolder();
|
||||
File regiondir = new File(f, "region");
|
||||
File[] lst = regiondir.listFiles();
|
||||
if(lst != null) {
|
||||
byte[] hdr = new byte[4096];
|
||||
for(File rf : lst) {
|
||||
if(!rf.getName().endsWith(".mca")) {
|
||||
continue;
|
||||
}
|
||||
String[] parts = rf.getName().split("\\.");
|
||||
if((!parts[0].equals("r")) && (parts.length != 4)) continue;
|
||||
|
||||
RandomAccessFile rfile = null;
|
||||
int x = 0, z = 0;
|
||||
try {
|
||||
x = Integer.parseInt(parts[1]);
|
||||
z = Integer.parseInt(parts[2]);
|
||||
rfile = new RandomAccessFile(rf, "r");
|
||||
rfile.read(hdr, 0, hdr.length);
|
||||
} catch (IOException iox) {
|
||||
Arrays.fill(hdr, (byte)0);
|
||||
} catch (NumberFormatException nfx) {
|
||||
Arrays.fill(hdr, (byte)0);
|
||||
} finally {
|
||||
if(rfile != null) {
|
||||
try { rfile.close(); } catch (IOException iox) {}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
int v = hdr[4*i] | hdr[4*i + 1] | hdr[4*i + 2] | hdr[4*i + 3];
|
||||
if (v == 0) continue;
|
||||
int xx = (x << 5) | (i & 0x1F);
|
||||
int zz = (z << 5) | ((i >> 5) & 0x1F);
|
||||
if (!map.setFlag(xx, zz, true)) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerBedLeaveEvent;
|
||||
import org.bukkit.event.player.PlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
@@ -111,6 +110,18 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
private Method ismodloaded;
|
||||
private HashMap<String, BukkitWorld> world_by_name = new HashMap<String, BukkitWorld>();
|
||||
private HashSet<String> modsused = new HashSet<String>();
|
||||
// TPS calculator
|
||||
private double tps;
|
||||
private long lasttick;
|
||||
private long perTickLimit;
|
||||
private long cur_tick_starttime;
|
||||
private long avgticklen = 50000000;
|
||||
|
||||
private int chunks_in_cur_tick = 0;
|
||||
private long cur_tick;
|
||||
private long prev_tick;
|
||||
|
||||
private HashMap<String, Integer> sortWeights = new HashMap<String, Integer>();
|
||||
/* Lookup cache */
|
||||
private World last_world;
|
||||
private BukkitWorld last_bworld;
|
||||
@@ -199,8 +210,6 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
public class BukkitServer implements DynmapServerInterface {
|
||||
/* Chunk load handling */
|
||||
private Object loadlock = new Object();
|
||||
private int chunks_in_cur_tick = 0;
|
||||
private long cur_tick;
|
||||
|
||||
@Override
|
||||
public int getBlockIDAt(String wname, int x, int y, int z) {
|
||||
@@ -275,7 +284,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
break;
|
||||
case WORLD_SPAWN_CHANGE:
|
||||
pm.registerEvents(new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onSpawnChange(SpawnChangeEvent evt) {
|
||||
BukkitWorld w = getWorld(evt.getWorld());
|
||||
core.listenerManager.processWorldEvent(EventType.WORLD_SPAWN_CHANGE, w);
|
||||
@@ -288,7 +297,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
break;
|
||||
case PLAYER_BED_LEAVE:
|
||||
pm.registerEvents(new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onPlayerBedLeave(PlayerBedLeaveEvent evt) {
|
||||
DynmapPlayer p = new BukkitPlayer(evt.getPlayer());
|
||||
core.listenerManager.processPlayerEvent(EventType.PLAYER_BED_LEAVE, p);
|
||||
@@ -296,42 +305,26 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}, DynmapPlugin.this);
|
||||
break;
|
||||
case PLAYER_CHAT:
|
||||
try {
|
||||
Class.forName("org.bukkit.event.player.AsyncPlayerChatEvent");
|
||||
pm.registerEvents(new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent evt) {
|
||||
if(evt.isCancelled()) return;
|
||||
final Player p = evt.getPlayer();
|
||||
final String msg = evt.getMessage();
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(DynmapPlugin.this, new Runnable() {
|
||||
public void run() {
|
||||
DynmapPlayer dp = null;
|
||||
if(p != null)
|
||||
dp = new BukkitPlayer(p);
|
||||
core.listenerManager.processChatEvent(EventType.PLAYER_CHAT, dp, msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, DynmapPlugin.this);
|
||||
} catch (ClassNotFoundException cnfx) {
|
||||
pm.registerEvents(new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
public void onPlayerChat(PlayerChatEvent evt) {
|
||||
if(evt.isCancelled()) return;
|
||||
DynmapPlayer p = null;
|
||||
if(evt.getPlayer() != null)
|
||||
p = new BukkitPlayer(evt.getPlayer());
|
||||
core.listenerManager.processChatEvent(EventType.PLAYER_CHAT, p, evt.getMessage());
|
||||
}
|
||||
}, DynmapPlugin.this);
|
||||
}
|
||||
pm.registerEvents(new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent evt) {
|
||||
final Player p = evt.getPlayer();
|
||||
final String msg = evt.getMessage();
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(DynmapPlugin.this, new Runnable() {
|
||||
public void run() {
|
||||
DynmapPlayer dp = null;
|
||||
if(p != null)
|
||||
dp = new BukkitPlayer(p);
|
||||
core.listenerManager.processChatEvent(EventType.PLAYER_CHAT, dp, msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, DynmapPlugin.this);
|
||||
break;
|
||||
case BLOCK_BREAK:
|
||||
pm.registerEvents(new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockBreak(BlockBreakEvent evt) {
|
||||
if(evt.isCancelled()) return;
|
||||
Block b = evt.getBlock();
|
||||
if(b == null) return; /* Work around for stupid mods.... */
|
||||
Location l = b.getLocation();
|
||||
@@ -342,9 +335,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
break;
|
||||
case SIGN_CHANGE:
|
||||
pm.registerEvents(new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onSignChange(SignChangeEvent evt) {
|
||||
if(evt.isCancelled()) return;
|
||||
Block b = evt.getBlock();
|
||||
Location l = b.getLocation();
|
||||
String[] lines = evt.getLines(); /* Note: changes to this change event - intentional */
|
||||
@@ -456,22 +448,25 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
final MapChunkCache cc = c;
|
||||
|
||||
while(!cc.isDoneLoading()) {
|
||||
synchronized(loadlock) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
if(cur_tick != (now/50)) { /* New tick? */
|
||||
chunks_in_cur_tick = mapManager.getMaxChunkLoadsPerTick();
|
||||
cur_tick = now/50;
|
||||
}
|
||||
}
|
||||
Future<Boolean> f = core.getServer().callSyncMethod(new Callable<Boolean>() {
|
||||
public Boolean call() throws Exception {
|
||||
boolean exhausted;
|
||||
boolean exhausted = true;
|
||||
|
||||
synchronized(loadlock) {
|
||||
if (prev_tick != cur_tick) {
|
||||
prev_tick = cur_tick;
|
||||
cur_tick_starttime = System.nanoTime();
|
||||
}
|
||||
if(chunks_in_cur_tick > 0) {
|
||||
chunks_in_cur_tick -= cc.loadChunks(chunks_in_cur_tick);
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int cnt = chunks_in_cur_tick;
|
||||
if (cnt > 5) cnt = 5;
|
||||
chunks_in_cur_tick -= cc.loadChunks(cnt);
|
||||
exhausted = (chunks_in_cur_tick == 0) || ((System.nanoTime() - cur_tick_starttime) > perTickLimit);
|
||||
done = exhausted || cc.isDoneLoading();
|
||||
}
|
||||
}
|
||||
exhausted = (chunks_in_cur_tick == 0);
|
||||
}
|
||||
return exhausted;
|
||||
}
|
||||
@@ -526,6 +521,11 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getServerTPS() {
|
||||
return tps;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Player access abstraction class
|
||||
@@ -629,6 +629,22 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public int getSortWeight() {
|
||||
Integer wt = sortWeights.get(getName());
|
||||
if (wt != null)
|
||||
return wt;
|
||||
return 0;
|
||||
}
|
||||
@Override
|
||||
public void setSortWeight(int wt) {
|
||||
if (wt == 0) {
|
||||
sortWeights.remove(getName());
|
||||
}
|
||||
else {
|
||||
sortWeights.put(getName(), wt);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Handler for generic console command sender */
|
||||
public class BukkitCommandSender implements DynmapCommandSender {
|
||||
@@ -664,6 +680,13 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean hasPermissionNode(String node) {
|
||||
if (sender != null) {
|
||||
return sender.hasPermission(node);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void loadExtraBiomes() {
|
||||
@@ -771,7 +794,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
/* See if we need to wait before enabling core */
|
||||
if(!readyToEnable()) {
|
||||
Listener pl = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onPluginEnabled(PluginEnableEvent evt) {
|
||||
if (!readyToEnable()) {
|
||||
spb.markPluginEnabled(evt.getPlugin());
|
||||
@@ -786,6 +809,16 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
else {
|
||||
doEnable();
|
||||
}
|
||||
// Start tps calculation
|
||||
lasttick = System.nanoTime();
|
||||
tps = 20.0;
|
||||
perTickLimit = core.getMaxTickUseMS() * 1000000;
|
||||
|
||||
getServer().getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
|
||||
public void run() {
|
||||
processTick();
|
||||
}
|
||||
}, 1, 1);
|
||||
}
|
||||
|
||||
private boolean readyToEnable() {
|
||||
@@ -807,7 +840,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
return;
|
||||
}
|
||||
playerList = core.playerList;
|
||||
sscache = new SnapshotCache(core.getSnapShotCacheSize());
|
||||
sscache = new SnapshotCache(core.getSnapShotCacheSize(), core.useSoftRefInSnapShotCache());
|
||||
|
||||
/* Get map manager from core */
|
||||
mapManager = core.getMapManager();
|
||||
@@ -847,7 +880,24 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}
|
||||
Log.info("Disabled");
|
||||
}
|
||||
|
||||
|
||||
private void processTick() {
|
||||
long now = System.nanoTime();
|
||||
long elapsed = now - lasttick;
|
||||
lasttick = now;
|
||||
avgticklen = ((avgticklen * 99) / 100) + (elapsed / 100);
|
||||
tps = (double)1E9 / (double)avgticklen;
|
||||
if (mapManager != null) {
|
||||
chunks_in_cur_tick = mapManager.getMaxChunkLoadsPerTick();
|
||||
}
|
||||
cur_tick++;
|
||||
|
||||
// Tick core
|
||||
if (core != null) {
|
||||
core.serverTick(tps);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
|
||||
DynmapCommandSender dsender;
|
||||
@@ -974,12 +1024,18 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
private void registerPlayerLoginListener() {
|
||||
Listener pl = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onPlayerJoin(PlayerJoinEvent evt) {
|
||||
DynmapPlayer dp = new BukkitPlayer(evt.getPlayer());
|
||||
core.listenerManager.processPlayerEvent(EventType.PLAYER_JOIN, dp);
|
||||
final DynmapPlayer dp = new BukkitPlayer(evt.getPlayer());
|
||||
// Give other handlers a change to prep player (nicknames and such from Essentials)
|
||||
getServer().getScheduler().scheduleSyncDelayedTask(DynmapPlugin.this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
core.listenerManager.processPlayerEvent(EventType.PLAYER_JOIN, dp);
|
||||
}
|
||||
}, 2);
|
||||
}
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onPlayerQuit(PlayerQuitEvent evt) {
|
||||
DynmapPlayer dp = new BukkitPlayer(evt.getPlayer());
|
||||
core.listenerManager.processPlayerEvent(EventType.PLAYER_QUIT, dp);
|
||||
@@ -1067,10 +1123,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onplace) {
|
||||
Listener placelistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
@@ -1082,10 +1136,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onbreak) {
|
||||
Listener breaklistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Block b = event.getBlock();
|
||||
if(b == null) return; /* Stupid mod workaround */
|
||||
Location loc = b.getLocation();
|
||||
@@ -1099,10 +1151,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onleaves) {
|
||||
Listener leaveslistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onLeavesDecay(LeavesDecayEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
@@ -1116,10 +1166,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onburn) {
|
||||
Listener burnlistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockBurn(BlockBurnEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
@@ -1133,10 +1181,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onblockphysics) {
|
||||
Listener physlistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockPhysics(BlockPhysicsEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Block b = event.getBlock();
|
||||
Material m = b.getType();
|
||||
if(m == null) return;
|
||||
@@ -1159,10 +1205,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onblockfromto) {
|
||||
Listener fromtolistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockFromTo(BlockFromToEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Block b = event.getBlock();
|
||||
Material m = b.getType();
|
||||
if((m != Material.WOOD_PLATE) && (m != Material.STONE_PLATE) && (m != null))
|
||||
@@ -1178,10 +1222,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onpiston) {
|
||||
Listener pistonlistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Block b = event.getBlock();
|
||||
Location loc = b.getLocation();
|
||||
BlockFace dir;
|
||||
@@ -1204,10 +1246,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockPistonExtend(BlockPistonExtendEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Block b = event.getBlock();
|
||||
Location loc = b.getLocation();
|
||||
BlockFace dir;
|
||||
@@ -1235,10 +1275,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onblockspread) {
|
||||
Listener spreadlistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockSpread(BlockSpreadEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
@@ -1250,10 +1288,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onblockform) {
|
||||
Listener formlistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockForm(BlockFormEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
@@ -1265,10 +1301,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onblockfade) {
|
||||
Listener fadelistener = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockFade(BlockFadeEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
@@ -1281,28 +1315,21 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
onblockgrow = core.isTrigger("blockgrow");
|
||||
|
||||
if(onblockgrow) {
|
||||
try {
|
||||
Class.forName("org.bukkit.event.block.BlockGrowEvent");
|
||||
Listener growTrigger = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
public void onBlockGrow(BlockGrowEvent event) {
|
||||
if(event.isCancelled())
|
||||
return;
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockgrow");
|
||||
}
|
||||
};
|
||||
pm.registerEvents(growTrigger, this);
|
||||
} catch (ClassNotFoundException cnfx) {
|
||||
/* Pre-R5 - no grow event yet */
|
||||
}
|
||||
Listener growTrigger = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockGrow(BlockGrowEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
sscache.invalidateSnapshot(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
|
||||
mapManager.touch(wn, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "blockgrow");
|
||||
}
|
||||
};
|
||||
pm.registerEvents(growTrigger, this);
|
||||
}
|
||||
|
||||
if(onblockredstone) {
|
||||
Listener redstoneTrigger = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onBlockRedstone(BlockRedstoneEvent event) {
|
||||
Location loc = event.getBlock().getLocation();
|
||||
String wn = getWorld(loc.getWorld()).getName();
|
||||
@@ -1315,7 +1342,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
/* Register player event trigger handlers */
|
||||
Listener playerTrigger = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
if(onplayerjoin) {
|
||||
Location loc = event.getPlayer().getLocation();
|
||||
@@ -1330,7 +1357,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
if(onplayermove) {
|
||||
Listener playermove = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
Location loc = event.getPlayer().getLocation();
|
||||
mapManager.touch(getWorld(loc.getWorld()).getName(), loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), "playermove");
|
||||
@@ -1341,7 +1368,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}
|
||||
/* Register entity event triggers */
|
||||
Listener entityTrigger = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
Location loc = event.getLocation();
|
||||
String wname = getWorld(loc.getWorld()).getName();
|
||||
@@ -1374,13 +1401,13 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
|
||||
/* Register world event triggers */
|
||||
Listener worldTrigger = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onWorldLoad(WorldLoadEvent event) {
|
||||
BukkitWorld w = getWorld(event.getWorld());
|
||||
if(core.processWorldLoad(w)) /* Have core process load first - fire event listeners if good load after */
|
||||
core.listenerManager.processWorldEvent(EventType.WORLD_LOAD, w);
|
||||
}
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onWorldUnload(WorldUnloadEvent event) {
|
||||
BukkitWorld w = getWorld(event.getWorld());
|
||||
if(w != null) {
|
||||
@@ -1389,7 +1416,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
core.processWorldUnload(w);
|
||||
}
|
||||
}
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onStructureGrow(StructureGrowEvent event) {
|
||||
Location loc = event.getLocation();
|
||||
String wname = getWorld(loc.getWorld()).getName();
|
||||
@@ -1423,7 +1450,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
ongeneratechunk = core.isTrigger("chunkgenerated");
|
||||
if(ongeneratechunk) {
|
||||
Listener chunkTrigger = new Listener() {
|
||||
@EventHandler(priority=EventPriority.MONITOR)
|
||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=true)
|
||||
public void onChunkPopulate(ChunkPopulateEvent event) {
|
||||
Chunk c = event.getChunk();
|
||||
ChunkSnapshot cs = c.getChunkSnapshot();
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.dynmap.bukkit;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@@ -20,9 +21,10 @@ public class SnapshotCache {
|
||||
private ReferenceQueue<SnapshotRec> refqueue;
|
||||
private long cache_attempts;
|
||||
private long cache_success;
|
||||
|
||||
private boolean softref;
|
||||
|
||||
private static class CacheRec {
|
||||
WeakReference<SnapshotRec> ref;
|
||||
Reference<SnapshotRec> ref;
|
||||
boolean hasbiome;
|
||||
boolean hasrawbiome;
|
||||
boolean hasblockdata;
|
||||
@@ -32,12 +34,12 @@ public class SnapshotCache {
|
||||
@SuppressWarnings("serial")
|
||||
public class CacheHashMap extends LinkedHashMap<String, CacheRec> {
|
||||
private int limit;
|
||||
private IdentityHashMap<WeakReference<SnapshotRec>, String> reverselookup;
|
||||
private IdentityHashMap<Reference<SnapshotRec>, String> reverselookup;
|
||||
|
||||
public CacheHashMap(int lim) {
|
||||
super(16, (float)0.75, true);
|
||||
limit = lim;
|
||||
reverselookup = new IdentityHashMap<WeakReference<SnapshotRec>, String>();
|
||||
reverselookup = new IdentityHashMap<Reference<SnapshotRec>, String>();
|
||||
}
|
||||
protected boolean removeEldestEntry(Map.Entry<String, CacheRec> last) {
|
||||
boolean remove = (size() >= limit);
|
||||
@@ -51,9 +53,10 @@ public class SnapshotCache {
|
||||
/**
|
||||
* Create snapshot cache
|
||||
*/
|
||||
public SnapshotCache(int max_size) {
|
||||
public SnapshotCache(int max_size, boolean softref) {
|
||||
snapcache = new CacheHashMap(max_size);
|
||||
refqueue = new ReferenceQueue<SnapshotRec>();
|
||||
this.softref = softref;
|
||||
}
|
||||
private String getKey(String w, int cx, int cz) {
|
||||
return w + ":" + cx + ":" + cz;
|
||||
@@ -127,7 +130,10 @@ public class SnapshotCache {
|
||||
rec.hasbiome = biome;
|
||||
rec.hasrawbiome = biomeraw;
|
||||
rec.hashighesty = highesty;
|
||||
rec.ref = new WeakReference<SnapshotRec>(ss, refqueue);
|
||||
if (softref)
|
||||
rec.ref = new SoftReference<SnapshotRec>(ss, refqueue);
|
||||
else
|
||||
rec.ref = new WeakReference<SnapshotRec>(ss, refqueue);
|
||||
CacheRec prevrec = snapcache.put(key, rec);
|
||||
if(prevrec != null) {
|
||||
snapcache.reverselookup.remove(prevrec.ref);
|
||||
|
||||
@@ -39,7 +39,7 @@ public class BukkitPermissions implements PermissionProvider {
|
||||
}
|
||||
@Override
|
||||
public Set<String> hasOfflinePermissions(String player, Set<String> perms) {
|
||||
Player p = Bukkit.getPlayerExact(name);
|
||||
Player p = Bukkit.getPlayerExact(player);
|
||||
HashSet<String> hasperms = null;
|
||||
if (p != null) {
|
||||
hasperms = new HashSet<String>();
|
||||
|
||||
@@ -26,6 +26,8 @@ components:
|
||||
hidewebchatip: false
|
||||
trustclientname: false
|
||||
includehiddenplayers: false
|
||||
# (optional) if true, color codes in player display names are used
|
||||
use-name-colors: false
|
||||
# (optional) if true, player login IDs will be used for web chat when their IPs match
|
||||
use-player-login-ip: true
|
||||
# (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored
|
||||
@@ -48,6 +50,8 @@ components:
|
||||
protected-player-info: false
|
||||
# If true, hide players with invisibility potion effects active
|
||||
hide-if-invisiblity-potion: true
|
||||
# If true, player names are not shown on map, chat, list
|
||||
hidenames: false
|
||||
#- class: org.dynmap.JsonFileClientUpdateComponent
|
||||
# writeinterval: 1
|
||||
# sendhealth: true
|
||||
@@ -56,6 +60,7 @@ components:
|
||||
# webchat-interval: 5
|
||||
# hidewebchatip: false
|
||||
# includehiddenplayers: false
|
||||
# use-name-colors: false
|
||||
# use-player-login-ip: false
|
||||
# require-player-login-ip: false
|
||||
# block-banned-player-chat: true
|
||||
@@ -69,6 +74,7 @@ components:
|
||||
# # Limit length of single chat messages
|
||||
# chatlengthlimit: 256
|
||||
# hide-if-invisiblity-potion: true
|
||||
# hidenames: false
|
||||
|
||||
- class: org.dynmap.SimpleWebChatComponent
|
||||
allowchat: true
|
||||
@@ -305,14 +311,29 @@ progressloginterval: 100
|
||||
# Interval the browser should poll for updates.
|
||||
updaterate: 2000
|
||||
|
||||
# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more user's are logged in
|
||||
# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more users are logged in
|
||||
fullrenderplayerlimit: 0
|
||||
# If nonzero, server will pause update render processing when 'updateplayerlimit' or more users are logged in
|
||||
updateplayerlimit: 0
|
||||
# Target limit on server thread use - msec per tick
|
||||
per-tick-time-limit: 50
|
||||
# If TPS of server is below this setting, update renders processing is paused
|
||||
update-min-tps: 18.0
|
||||
# If TPS of server is below this setting, full/radius renders processing is paused
|
||||
fullrender-min-tps: 18.0
|
||||
# If TPS of server is below this setting, zoom out processing is paused
|
||||
zoomout-min-tps: 18.0
|
||||
|
||||
showplayerfacesinmenu: true
|
||||
|
||||
# Control whether players that are hidden or not on current map are grayed out (true=yes)
|
||||
grayplayerswhenhidden: true
|
||||
|
||||
# Use player permissions to order player list: first to last, players are ordered by first permission listed that they have
|
||||
# That is, anyone with first listed permission goes before anyone with second, etc, with users with none of the nodes going last
|
||||
player-sort-permission-nodes:
|
||||
- bukkit.command.op
|
||||
|
||||
# Set sidebaropened: 'true' to pin menu sidebar opened permanently, 'pinned' to default the sidebar to pinned, but allow it to unpin
|
||||
#sidebaropened: true
|
||||
|
||||
@@ -360,6 +381,8 @@ msg:
|
||||
players: "Players"
|
||||
chatrequireslogin: "Chat Requires Login"
|
||||
chatnotallowed: "You are not permitted to send chat messages"
|
||||
hiddennamejoin: "Player joined"
|
||||
hiddennamequit: "Player quit"
|
||||
|
||||
# URL for client configuration (only need to be tailored for proxies or other non-standard configurations)
|
||||
url:
|
||||
@@ -394,6 +417,11 @@ custom-commands:
|
||||
preupdatecommand: ""
|
||||
# Command run just after any image file is written or updated: run with single parameter with fully qualified file name
|
||||
postupdatecommand: ""
|
||||
|
||||
# Snapshot cache size, in chunks
|
||||
snapshotcachesize: 500
|
||||
# Snapshot cache uses soft references (true), else weak references (false)
|
||||
soft-ref-cache: true
|
||||
|
||||
# Set to true to enable verbose startup messages - can help with debugging map configuration problems
|
||||
# Set to false for a much quieter startup log
|
||||
|
||||
@@ -3,7 +3,7 @@ main: org.dynmap.bukkit.DynmapPlugin
|
||||
version: "${project.version}-${BUILD_NUMBER}"
|
||||
authors: [mikeprimm]
|
||||
website: "http://www.minecraftforum.net/topic/1543523-dynmap-dynamic-web-based-maps-for-minecraft/"
|
||||
softdepend: [ Permissions, PermissionEx, bPermissions, PermissionsBukkit ]
|
||||
softdepend: [ Permissions, PermissionEx, bPermissions, PermissionsBukkit, GroupManager ]
|
||||
commands:
|
||||
dynmap:
|
||||
description: Controls Dynmap.
|
||||
@@ -30,6 +30,9 @@ commands:
|
||||
/<command> resetstats - Reset render statistics.
|
||||
/<command> sendtoweb msg - Send message to web users
|
||||
/<command> purgequeue - Set tile update queue to empty
|
||||
/<command> purgequeue worldname - Set tile update queue to empty for world 'worldname'
|
||||
/<command> purgemap worldname mapname - Delete all the tiles for map 'mapname' of world 'worldname'
|
||||
/<command> purgeworld worldname - Delete all the files for world 'worldname'
|
||||
/<command> pause - Show render pause state
|
||||
/<command> pause <all|none|full|update> - Set render pause state
|
||||
/<command> ids-for-ip <ipaddress> - Show player IDs that have logged in from given IP address
|
||||
@@ -87,6 +90,17 @@ commands:
|
||||
/<command> listcircles - list details of all circles
|
||||
/<command> updatecircle <label> <arg>:<value> ... - update attributes of circle with given label
|
||||
/<command> updatecircle id:<id> <arg>:<value> ... - update attributes of circle with given ID
|
||||
/<command> getdesc id:<id> type:<icon|area|circle|line> - get description for marker with given ID
|
||||
/<command> getdesc <label> type:<icon|area|circle|line> - get description for marker with given label
|
||||
/<command> resetdesc id:<id> type:<icon|area|circle|line> - clear description for marker with given ID
|
||||
/<command> resetdesc <label> type:<icon|area|circle|line> - clear description for marker with given label
|
||||
/<command> appenddesc id:<id> type:<icon|area|circle|line> desc:"text" - append text line to description for marker with given ID
|
||||
/<command> appenddesc <label> type:<icon|area|circle|line> desc:"text" - append text line to description for marker with given label
|
||||
/<command> importdesc id:<id> type:<icon|area|circle|line> file:<filename> - import description from given file for marker with given ID
|
||||
/<command> importdesc <label> type:<icon|area|circle|line> file:<filename> - import description from given file for marker with given label
|
||||
/<command> importlabel id:<id> type:<icon|area|circle|line> file:<filename> - import label with markup from given file for marker with given ID
|
||||
/<command> importlabel <label> type:<icon|area|circle|line> file:<filename> - import label with markup from given file for marker with given label
|
||||
/<command> getlabel id:<id> type:<icon|area|circle|line> - get label for marker with given ID
|
||||
|
||||
dmap:
|
||||
description: List and modify dynmap configuration
|
||||
@@ -120,6 +134,8 @@ permissions:
|
||||
dynmap.resetstats: true
|
||||
dynmap.sendtoweb: true
|
||||
dynmap.purgequeue: true
|
||||
dynmap.purgemap: true
|
||||
dynmap.purgeworld: true
|
||||
dynmap.ids-for-ip: true
|
||||
dynmap.ips-for-id: true
|
||||
dynmap.webregister: true
|
||||
@@ -147,6 +163,12 @@ permissions:
|
||||
dynmap.marker.updatecircle: true
|
||||
dynmap.marker.listcircles: true
|
||||
dynmap.marker.deletecircle: true
|
||||
dynmap.marker.getdesc: true
|
||||
dynmap.marker.resetdesc: true
|
||||
dynmap.marker.appenddesc: true
|
||||
dynmap.marker.importdesc: true
|
||||
dynmap.marker.getlabel: true
|
||||
dynmap.marker.importlabel: true
|
||||
dynmap.dmap.worldlist: true
|
||||
dynmap.dmap.worldset: true
|
||||
dynmap.dmap.worldreset: true
|
||||
@@ -199,6 +221,12 @@ permissions:
|
||||
dynmap.purgequeue:
|
||||
description: Allows /dynmap purgequeue
|
||||
default: op
|
||||
dynmap.purgemap:
|
||||
description: Allows /dynmap purgemap
|
||||
default: op
|
||||
dynmap.purgeworld:
|
||||
description: Allows /dynmap purgeworld
|
||||
default: op
|
||||
dynmap.pause:
|
||||
description: Allows /dynmap pause
|
||||
default: op
|
||||
@@ -292,6 +320,24 @@ permissions:
|
||||
dynmap.marker.deletecircle:
|
||||
description: Allows /dmarker deletecircle
|
||||
default: op
|
||||
dynmap.marker.getdesc:
|
||||
description: Allows /dmarker getdesc
|
||||
default: op
|
||||
dynmap.marker.resetdesc:
|
||||
description: Allows /dmarker resetdesc
|
||||
default: op
|
||||
dynmap.marker.appenddesc:
|
||||
description: Allows /dmarker appenddesc
|
||||
default: op
|
||||
dynmap.marker.importdesc:
|
||||
description: Allows /dmarker importdesc
|
||||
default: op
|
||||
dynmap.marker.getlabel:
|
||||
description: Allows /dmarker getlabel
|
||||
default: op
|
||||
dynmap.marker.importlabel:
|
||||
description: Allows /dmarker importlabel
|
||||
default: op
|
||||
dynmap.dmap.worldlist:
|
||||
description: Allows /dmap worldlist
|
||||
default: op
|
||||
|
||||
Reference in New Issue
Block a user