Compare commits

...

20 Commits

Author SHA1 Message Date
Mike Primm 5482ddaa89 Add 2 tick delay to player join processing - allows nicknames to be set before we send message to web 2013-07-05 10:57:19 -05:00
Mike Primm 47455eb912 Add 'hidenames' option, and supporting messages 2013-07-05 09:31:32 -05:00
Mike Primm 32a1c20fd0 Bandaid for MrApple's CB 1.6.1 2013-07-01 19:31:59 -05:00
Mike Primm b85c38e3a7 Add softref option for chunk snapshot cache 2013-06-25 01:09:25 -05:00
Mike Primm 5bc4de6a8b Add zoomout-min-tps setting 2013-06-24 21:44:01 -05:00
Mike Primm 2d20fd11f7 Update dev version format 2013-06-24 20:24:05 -05:00
Mike Primm 6a4bb59d60 Add permission node for /dynmap purgeworld command 2013-06-23 15:11:32 -05:00
Mike Primm ab45edb82c Add settings for TPS limits and per-tick msec limits 2013-06-19 23:20:38 -05:00
Mike Primm 4f6bc05180 Add help for /dynmap purgequeue <world> 2013-06-15 18:10:50 -05:00
Mike Primm 076681e188 Add help and permission node for /dynmap purgemap 2013-06-15 18:07:45 -05:00
Mike Primm b7abfe7c06 Add settings for player-sort-permission-nodes support 2013-06-14 01:49:49 -05:00
Mike Primm 3a88ac66a6 Add use-name-colors setting to control option to use name color markup 2013-06-02 19:28:03 -05:00
Mike Primm d3b9367794 Add 'updateplayerlimit' setting default 2013-06-02 16:31:35 -05:00
Mike Primm 666840fc8b Add help and permissions for /dmarker importdesc, importlabel, getlabel 2013-05-27 09:09:49 -05:00
Mike Primm 62f4c12147 Bump bukkit dependency to 1.4.7 2013-05-27 08:33:49 -05:00
Mike Primm 4b3f2280b6 Add command help and permissions for /dmarker description commands 2013-05-26 14:03:46 -05:00
Mike Primm df55606023 Add method for discovering all chunks in world 2013-05-24 23:59:08 -05:00
Mike Primm 6fc5fddd44 Back to 1.8 2013-05-15 20:53:56 -05:00
Mike Primm dea285c160 Back to 1.7.1 for bug fix 2013-05-15 19:35:06 -05:00
Mike Primm 204641a4b0 Bump to 1.8 2013-05-14 22:06:00 -05:00
8 changed files with 297 additions and 128 deletions
+5 -3
View File
@@ -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;
}
}
+142 -115
View File
@@ -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>();
+29 -1
View File
@@ -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
+47 -1
View File
@@ -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