From 737bcb98d91c407b14d0eabdcb4242d938565bbd Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sun, 24 Jul 2011 23:23:24 -0500 Subject: [PATCH] Improve handling of /reload, clean up dead code --- src/main/java/org/dynmap/Cache.java | 111 ------------------ src/main/java/org/dynmap/ColorScheme.java | 3 + .../org/dynmap/DynmapPlayerChatListener.java | 9 +- src/main/java/org/dynmap/DynmapPlugin.java | 4 + src/main/java/org/dynmap/DynmapWorld.java | 8 +- .../dynmap/InternalClientUpdateComponent.java | 2 +- .../dynmap/JsonFileClientUpdateComponent.java | 77 +++++++----- src/main/java/org/dynmap/MapManager.java | 52 +++++--- .../org/dynmap/SimpleWebChatComponent.java | 9 +- src/main/java/org/dynmap/StaleQueue.java | 50 -------- src/main/java/org/dynmap/flat/FlatMap.java | 12 +- .../java/org/dynmap/hdmap/HDBlockModels.java | 5 + .../org/dynmap/hdmap/IsoHDPerspective.java | 14 +-- .../java/org/dynmap/hdmap/TexturePack.java | 5 +- .../org/dynmap/herochat/HeroChatHandler.java | 3 +- .../dynmap/kzedmap/DefaultTileRenderer.java | 34 +++--- src/main/java/org/dynmap/kzedmap/KzedMap.java | 78 +----------- .../org/dynmap/utils/DynmapBufferedImage.java | 88 ++++++++++++++ src/main/java/org/dynmap/web/HttpServer.java | 21 ++++ .../org/dynmap/web/HttpServerConnection.java | 21 +++- .../web/handlers/ClientUpdateHandler.java | 5 +- .../org/dynmap/web/handlers/FileHandler.java | 5 +- .../web/handlers/SendMessageHandler.java | 1 - 23 files changed, 279 insertions(+), 338 deletions(-) delete mode 100644 src/main/java/org/dynmap/Cache.java delete mode 100644 src/main/java/org/dynmap/StaleQueue.java create mode 100644 src/main/java/org/dynmap/utils/DynmapBufferedImage.java diff --git a/src/main/java/org/dynmap/Cache.java b/src/main/java/org/dynmap/Cache.java deleted file mode 100644 index 056681e9..00000000 --- a/src/main/java/org/dynmap/Cache.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.dynmap; - -import java.util.HashMap; - -public class Cache { - private final int size; - private int len; - - private CacheNode head; - private CacheNode tail; - - private class CacheNode { - public CacheNode prev; - public CacheNode next; - public K key; - public V value; - - public CacheNode(K key, V value) { - this.key = key; - this.value = value; - prev = null; - next = null; - } - - public void unlink() { - if (prev == null) { - head = next; - } else { - prev.next = next; - } - - if (next == null) { - tail = prev; - } else { - next.prev = prev; - } - - prev = null; - next = null; - - len--; - } - - public void append() { - if (tail == null) { - head = this; - tail = this; - } else { - tail.next = this; - prev = tail; - tail = this; - } - - len++; - } - } - - private HashMap map; - - public Cache(int size) { - this.size = size; - len = 0; - - head = null; - tail = null; - - map = new HashMap(); - } - - /* - * returns value for key, if key exists in the cache otherwise null - */ - public V get(K key) { - CacheNode n = map.get(key); - if (n == null) - return null; - return n.value; - } - - /* - * puts a new key-value pair in the cache if the key existed already, the - * value is updated, and the old value is returned if the key didn't exist, - * it is added; the oldest value (now pushed out of the cache) may be - * returned, or null if the cache isn't yet full - */ - public V put(K key, V value) { - CacheNode n = map.get(key); - if (n == null) { - V ret = null; - - if (len >= size) { - CacheNode first = head; - first.unlink(); - map.remove(first.key); - ret = first.value; - } - - CacheNode add = new CacheNode(key, value); - add.append(); - map.put(key, add); - - return ret; - } else { - n.unlink(); - V old = n.value; - n.value = value; - n.append(); - return old; - } - } -} diff --git a/src/main/java/org/dynmap/ColorScheme.java b/src/main/java/org/dynmap/ColorScheme.java index 0216560e..1d6bd922 100644 --- a/src/main/java/org/dynmap/ColorScheme.java +++ b/src/main/java/org/dynmap/ColorScheme.java @@ -235,4 +235,7 @@ public class ColorScheme { else return null; } + public static void reset() { + cache.clear(); + } } diff --git a/src/main/java/org/dynmap/DynmapPlayerChatListener.java b/src/main/java/org/dynmap/DynmapPlayerChatListener.java index 64d3fcb4..f367c630 100644 --- a/src/main/java/org/dynmap/DynmapPlayerChatListener.java +++ b/src/main/java/org/dynmap/DynmapPlayerChatListener.java @@ -15,19 +15,22 @@ public class DynmapPlayerChatListener extends PlayerListener { @Override public void onPlayerChat(PlayerChatEvent event) { if(event.isCancelled()) return; - plugin.mapManager.pushUpdate(new Client.ChatMessage("player", "", + if(plugin.mapManager != null) + plugin.mapManager.pushUpdate(new Client.ChatMessage("player", "", event.getPlayer().getDisplayName(), event.getMessage(), event.getPlayer().getName())); } @Override public void onPlayerJoin(PlayerJoinEvent event) { - plugin.mapManager.pushUpdate(new Client.PlayerJoinMessage(event.getPlayer().getDisplayName(), event.getPlayer().getName())); + if(plugin.mapManager != null) + plugin.mapManager.pushUpdate(new Client.PlayerJoinMessage(event.getPlayer().getDisplayName(), event.getPlayer().getName())); } @Override public void onPlayerQuit(PlayerQuitEvent event) { - plugin.mapManager.pushUpdate(new Client.PlayerQuitMessage(event.getPlayer().getDisplayName(), event.getPlayer().getName())); + if(plugin.mapManager != null) + plugin.mapManager.pushUpdate(new Client.PlayerQuitMessage(event.getPlayer().getDisplayName(), event.getPlayer().getName())); } } diff --git a/src/main/java/org/dynmap/DynmapPlugin.java b/src/main/java/org/dynmap/DynmapPlugin.java index 736cfd23..c85fe5da 100644 --- a/src/main/java/org/dynmap/DynmapPlugin.java +++ b/src/main/java/org/dynmap/DynmapPlugin.java @@ -176,6 +176,9 @@ public class DynmapPlugin extends JavaPlugin { @Override public void onEnable() { + /* Start with clean events */ + events = new Events(); + permissions = NijikokunPermissions.create(getServer(), "dynmap"); if (permissions == null) permissions = new OpPermissions(new String[] { "fullrender", "reload" }); @@ -303,6 +306,7 @@ public class DynmapPlugin extends JavaPlugin { if (mapManager != null) { mapManager.stopRendering(); + mapManager = null; } if (webServer != null) { diff --git a/src/main/java/org/dynmap/DynmapWorld.java b/src/main/java/org/dynmap/DynmapWorld.java index ec47de0a..38241d7c 100644 --- a/src/main/java/org/dynmap/DynmapWorld.java +++ b/src/main/java/org/dynmap/DynmapWorld.java @@ -7,7 +7,7 @@ import org.bukkit.World; import org.bukkit.Location; import org.dynmap.debug.Debug; import org.dynmap.kzedmap.KzedMap; -import org.dynmap.kzedmap.KzedMap.KzedBufferedImage; +import org.dynmap.utils.DynmapBufferedImage; import org.dynmap.utils.FileLockManager; import org.dynmap.utils.MapChunkCache; @@ -361,7 +361,7 @@ public class DynmapWorld { Debug.debug("processZoomFile(" + pd.baseprefix + "," + zf.getPath() + "," + tx + "," + ty + ")"); int width = 128, height = 128; BufferedImage zIm = null; - KzedBufferedImage kzIm = null; + DynmapBufferedImage kzIm = null; int[] argb = new int[width*height]; int step = pd.stepsize << pd.zoomlevel; int ztx = tx; @@ -370,7 +370,7 @@ public class DynmapWorld { ty = ty - (pd.neg_step_y?step:0); /* Adjust for negative step */ /* create image buffer */ - kzIm = KzedMap.allocateBufferedImage(width, height); + kzIm = DynmapBufferedImage.allocateBufferedImage(width, height); zIm = kzIm.buf_img; for(int i = 0; i < 4; i++) { @@ -434,7 +434,7 @@ public class DynmapWorld { } } finally { FileLockManager.releaseWriteLock(zf); - KzedMap.freeBufferedImage(kzIm); + DynmapBufferedImage.freeBufferedImage(kzIm); } } } diff --git a/src/main/java/org/dynmap/InternalClientUpdateComponent.java b/src/main/java/org/dynmap/InternalClientUpdateComponent.java index 782232a7..59436a7c 100644 --- a/src/main/java/org/dynmap/InternalClientUpdateComponent.java +++ b/src/main/java/org/dynmap/InternalClientUpdateComponent.java @@ -47,7 +47,7 @@ public class InternalClientUpdateComponent extends ClientUpdateComponent { protected void webChat(String name, String message) { // TODO: Change null to something meaningful. plugin.mapManager.pushUpdate(new Client.ChatMessage("web", null, name, message, null)); - Log.info(plugin.configuration.getString("webprefix", "\u00A72[WEB] ") + name + ": " + plugin.configuration.getString("websuffix", "\u00A7f") + message); + Log.info(unescapeString(plugin.configuration.getString("webprefix", "\u00A72[WEB] ")) + name + ": " + unescapeString(plugin.configuration.getString("websuffix", "\u00A7f")) + message); ChatEvent event = new ChatEvent("web", name, message); plugin.events.trigger("webchat", event); } diff --git a/src/main/java/org/dynmap/JsonFileClientUpdateComponent.java b/src/main/java/org/dynmap/JsonFileClientUpdateComponent.java index 6f4980f1..9d0ab90a 100644 --- a/src/main/java/org/dynmap/JsonFileClientUpdateComponent.java +++ b/src/main/java/org/dynmap/JsonFileClientUpdateComponent.java @@ -22,8 +22,6 @@ import static org.dynmap.JSONUtils.*; import java.nio.charset.Charset; public class JsonFileClientUpdateComponent extends ClientUpdateComponent { - protected TimerTask task; - protected Timer timer; protected long jsonInterval; protected long currentTimestamp = 0; protected long lastTimestamp = 0; @@ -39,7 +37,7 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent { final boolean allowwebchat = configuration.getBoolean("allowwebchat", false); jsonInterval = (long)(configuration.getFloat("writeinterval", 1) * 1000); hidewebchatip = configuration.getBoolean("hidewebchatip", false); - task = new TimerTask() { + MapManager.scheduleDelayedJob(new Runnable() { @Override public void run() { currentTimestamp = System.currentTimeMillis(); @@ -48,10 +46,9 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent { handleWebChat(); } lastTimestamp = currentTimestamp; - } - }; - timer = new Timer(); - timer.scheduleAtFixedRate(task, jsonInterval, jsonInterval); + MapManager.scheduleDelayedJob(this, jsonInterval); + }}, jsonInterval); + plugin.events.addListener("buildclientconfiguration", new Event.Listener() { @Override public void triggered(JSONObject t) { @@ -84,6 +81,7 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent { return new File(plugin.getDataFolder(), webpath.toString()); } + private static final int RETRY_LIMIT = 5; protected void writeConfiguration() { File outputFile; File outputTempFile; @@ -91,17 +89,27 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent { plugin.events.trigger("buildclientconfiguration", clientConfiguration); outputFile = getStandaloneFile("dynmap_config.json"); outputTempFile = getStandaloneFile("dynmap_config.json.new"); - - try { - FileOutputStream fos = new FileOutputStream(outputTempFile); - fos.write(clientConfiguration.toJSONString().getBytes("UTF-8")); - fos.close(); - outputFile.delete(); - outputTempFile.renameTo(outputFile); - } catch (FileNotFoundException ex) { - Log.severe("Exception while writing JSON-configuration-file.", ex); - } catch (IOException ioe) { - Log.severe("Exception while writing JSON-configuration-file.", ioe); + + int retrycnt = 0; + boolean done = false; + while(!done) { + try { + FileOutputStream fos = new FileOutputStream(outputTempFile); + fos.write(clientConfiguration.toJSONString().getBytes("UTF-8")); + fos.close(); + outputFile.delete(); + outputTempFile.renameTo(outputFile); + done = true; + } catch (IOException ioe) { + if(retrycnt < RETRY_LIMIT) { + try { Thread.sleep(20 * (1 << retrycnt)); } catch (InterruptedException ix) {} + retrycnt++; + } + else { + Log.severe("Exception while writing JSON-configuration-file.", ioe); + done = true; + } + } } } @@ -120,16 +128,26 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent { outputFile = getStandaloneFile("dynmap_" + world.getName() + ".json"); outputTempFile = getStandaloneFile("dynmap_" + world.getName() + ".json.new"); - try { - FileOutputStream fos = new FileOutputStream(outputTempFile); - fos.write(Json.stringifyJson(update).getBytes("UTF-8")); - fos.close(); - outputFile.delete(); - outputTempFile.renameTo(outputFile); - } catch (FileNotFoundException ex) { - Log.severe("Exception while writing JSON-file.", ex); - } catch (IOException ioe) { - Log.severe("Exception while writing JSON-file.", ioe); + int retrycnt = 0; + boolean done = false; + while(!done) { + try { + FileOutputStream fos = new FileOutputStream(outputTempFile); + fos.write(Json.stringifyJson(update).getBytes("UTF-8")); + fos.close(); + outputFile.delete(); + outputTempFile.renameTo(outputFile); + done = true; + } catch (IOException ioe) { + if(retrycnt < RETRY_LIMIT) { + try { Thread.sleep(20 * (1 << retrycnt)); } catch (InterruptedException ix) {} + retrycnt++; + } + else { + Log.severe("Exception while writing JSON-file.", ioe); + done = true; + } + } } plugin.events.trigger("clientupdatewritten", clientUpdate); } @@ -179,7 +197,7 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent { protected void webChat(String name, String message) { // TODO: Change null to something meaningful. plugin.mapManager.pushUpdate(new Client.ChatMessage("web", null, name, message, null)); - Log.info(plugin.configuration.getString("webprefix", "\u00A2[WEB] ") + name + ": " + plugin.configuration.getString("websuffix", "\u00A7f") + message); + Log.info(unescapeString(plugin.configuration.getString("webprefix", "\u00A2[WEB] ")) + name + ": " + unescapeString(plugin.configuration.getString("websuffix", "\u00A7f")) + message); ChatEvent event = new ChatEvent("web", name, message); plugin.events.trigger("webchat", event); } @@ -187,6 +205,5 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent { @Override public void dispose() { super.dispose(); - timer.cancel(); } } diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java index 1c5106e4..38db854d 100644 --- a/src/main/java/org/dynmap/MapManager.java +++ b/src/main/java/org/dynmap/MapManager.java @@ -1,7 +1,6 @@ package org.dynmap; import java.io.File; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -12,8 +11,6 @@ import java.util.List; import java.util.Map; import java.util.TreeSet; import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ScheduledFuture; @@ -21,7 +18,6 @@ import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; -import org.bukkit.ChunkSnapshot; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.scheduler.BukkitScheduler; @@ -29,7 +25,6 @@ import org.bukkit.command.CommandSender; import org.dynmap.DynmapWorld.AutoGenerateOption; import org.dynmap.debug.Debug; import org.dynmap.hdmap.HDMapManager; -import org.dynmap.utils.LRULinkedHashMap; import org.dynmap.utils.LegacyMapChunkCache; import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.NewMapChunkCache; @@ -66,7 +61,7 @@ public class MapManager { public SnapshotCache sscache; /* Thread pool for processing renders */ - private DynmapScheduledThreadPoolExecutor renderpool; + private DynmapScheduledThreadPoolExecutor render_pool; private static final int POOL_SIZE = 3; private HashMap mapstats = new HashMap(); @@ -102,6 +97,9 @@ public class MapManager { DynmapScheduledThreadPoolExecutor() { super(POOL_SIZE); this.setThreadFactory(new OurThreadFactory()); + /* Set shutdown policy to stop everything */ + setContinueExistingPeriodicTasksAfterShutdownPolicy(false); + setExecuteExistingDelayedTasksAfterShutdownPolicy(false); } protected void afterExecute(Runnable r, Throwable x) { @@ -337,10 +335,10 @@ public class MapManager { if(tile0 == null) { /* fullrender */ long tend = System.currentTimeMillis(); if(timeslice_int > (tend-tstart)) { /* We were fast enough */ - renderpool.schedule(this, timeslice_int - (tend-tstart), TimeUnit.MILLISECONDS); + scheduleDelayedJob(this, timeslice_int - (tend-tstart)); } else { /* Schedule to run ASAP */ - renderpool.execute(this); + scheduleDelayedJob(this, 0); } } else { @@ -360,7 +358,7 @@ public class MapManager { boolean isday = new_servertime >= 0 && new_servertime < 13700; w.servertime = new_servertime; if(wasday != isday) { - MapManager.mapman.pushUpdate(w.world, new Client.DayNight(isday)); + pushUpdate(w.world, new Client.DayNight(isday)); } } return 0; @@ -371,7 +369,7 @@ public class MapManager { } catch (Exception ix) { Log.severe(ix); } - renderpool.schedule(this, 5, TimeUnit.SECONDS); + scheduleDelayedJob(this, 5000); } } @@ -382,7 +380,7 @@ public class MapManager { for(DynmapWorld w : wl) { w.freshenZoomOutFiles(); } - renderpool.schedule(this, zoomout_period, TimeUnit.SECONDS); + scheduleDelayedJob(this, zoomout_period*1000); Debug.debug("DoZoomOutProcessing finished"); } } @@ -390,6 +388,8 @@ public class MapManager { public MapManager(DynmapPlugin plugin, ConfigurationNode configuration) { plug_in = plugin; mapman = this; + /* Clear color scheme */ + ColorScheme.reset(); /* Initialize HD map manager */ hdmapman = new HDMapManager(); hdmapman.loadHDShaders(plugin); @@ -400,7 +400,7 @@ public class MapManager { this.tileQueue = new AsynchronousQueue(new Handler() { @Override public void handle(MapTile t) { - renderpool.execute(new FullWorldRenderState(t)); + scheduleDelayedJob(new FullWorldRenderState(t), 0); } }, (int) (configuration.getDouble("renderinterval", 0.5) * 1000)); @@ -441,7 +441,8 @@ public class MapManager { active_renders.put(wname, rndr); /* Add to active table */ } /* Schedule first tile to be worked */ - renderpool.execute(rndr); + scheduleDelayedJob(rndr, 0); + sender.sendMessage("Full render starting on world '" + wname + "'..."); } @@ -463,7 +464,7 @@ public class MapManager { active_renders.put(wname, rndr); /* Add to active table */ } /* Schedule first tile to be worked */ - renderpool.execute(rndr); + scheduleDelayedJob(rndr, 0); sender.sendMessage("Render of " + radius + " block radius starting on world '" + wname + "'..."); } @@ -583,16 +584,31 @@ public class MapManager { tileQueue.push(tile); } + public static void scheduleDelayedJob(Runnable job, long delay_in_msec) { + if((mapman != null) && (mapman.render_pool != null)) { + if(delay_in_msec > 0) + mapman.render_pool.schedule(job, delay_in_msec, TimeUnit.MILLISECONDS); + else + mapman.render_pool.execute(job); + } + } + public void startRendering() { tileQueue.start(); - renderpool = new DynmapScheduledThreadPoolExecutor(); - renderpool.schedule(new DoZoomOutProcessing(), 60000, TimeUnit.MILLISECONDS); - renderpool.schedule(new CheckWorldTimes(), 5, TimeUnit.SECONDS); + render_pool = new DynmapScheduledThreadPoolExecutor(); + scheduleDelayedJob(new DoZoomOutProcessing(), 60000); + scheduleDelayedJob(new CheckWorldTimes(), 5000); } public void stopRendering() { - renderpool.shutdown(); + render_pool.shutdown(); + try { + render_pool.awaitTermination(5, TimeUnit.SECONDS); + } catch (InterruptedException ix) { + } tileQueue.stop(); + mapman = null; + hdmapman = null; } private HashMap worldTileDirectories = new HashMap(); diff --git a/src/main/java/org/dynmap/SimpleWebChatComponent.java b/src/main/java/org/dynmap/SimpleWebChatComponent.java index b1e1f9dc..241f5425 100644 --- a/src/main/java/org/dynmap/SimpleWebChatComponent.java +++ b/src/main/java/org/dynmap/SimpleWebChatComponent.java @@ -44,17 +44,20 @@ public class SimpleWebChatComponent extends Component { @Override public void onPlayerChat(PlayerChatEvent event) { if(event.isCancelled()) return; - plugin.mapManager.pushUpdate(new Client.ChatMessage("player", "", event.getPlayer().getDisplayName(), event.getMessage(), event.getPlayer().getName())); + if(plugin.mapManager != null) + plugin.mapManager.pushUpdate(new Client.ChatMessage("player", "", event.getPlayer().getDisplayName(), event.getMessage(), event.getPlayer().getName())); } @Override public void onPlayerJoin(PlayerJoinEvent event) { - plugin.mapManager.pushUpdate(new Client.PlayerJoinMessage(event.getPlayer().getDisplayName(), event.getPlayer().getName())); + if(plugin.mapManager != null) + plugin.mapManager.pushUpdate(new Client.PlayerJoinMessage(event.getPlayer().getDisplayName(), event.getPlayer().getName())); } @Override public void onPlayerQuit(PlayerQuitEvent event) { - plugin.mapManager.pushUpdate(new Client.PlayerQuitMessage(event.getPlayer().getDisplayName(), event.getPlayer().getName())); + if(plugin.mapManager != null) + plugin.mapManager.pushUpdate(new Client.PlayerQuitMessage(event.getPlayer().getDisplayName(), event.getPlayer().getName())); } } diff --git a/src/main/java/org/dynmap/StaleQueue.java b/src/main/java/org/dynmap/StaleQueue.java deleted file mode 100644 index 26172607..00000000 --- a/src/main/java/org/dynmap/StaleQueue.java +++ /dev/null @@ -1,50 +0,0 @@ -package org.dynmap; - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.NoSuchElementException; -import java.util.Set; - -public class StaleQueue { - /* a list of MapTiles to be updated */ - private LinkedList staleTilesQueue; - private Set staleTiles; - - public StaleQueue() { - staleTilesQueue = new LinkedList(); - staleTiles = new HashSet(); - } - - public int size() { - return staleTilesQueue.size(); - } - - /* put a MapTile that needs to be regenerated on the list of stale tiles */ - public boolean pushStaleTile(MapTile m) { - synchronized (MapManager.lock) { - if (staleTiles.add(m)) { - staleTilesQueue.addLast(m); - return true; - } - return false; - } - } - - /* - * get next MapTile that needs to be regenerated, or null the mapTile is - * removed from the list of stale tiles! - */ - public MapTile popStaleTile() { - synchronized (MapManager.lock) { - try { - MapTile t = staleTilesQueue.removeFirst(); - if (!staleTiles.remove(t)) { - // This should never happen. - } - return t; - } catch (NoSuchElementException e) { - return null; - } - } - } -} diff --git a/src/main/java/org/dynmap/flat/FlatMap.java b/src/main/java/org/dynmap/flat/FlatMap.java index ac844aa6..d0cb9dda 100644 --- a/src/main/java/org/dynmap/flat/FlatMap.java +++ b/src/main/java/org/dynmap/flat/FlatMap.java @@ -26,7 +26,7 @@ import org.dynmap.MapType; import org.dynmap.MapType.MapStep; import org.dynmap.debug.Debug; import org.dynmap.kzedmap.KzedMap; -import org.dynmap.kzedmap.KzedMap.KzedBufferedImage; +import org.dynmap.utils.DynmapBufferedImage; import org.dynmap.utils.FileLockManager; import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.MapIterator; @@ -134,12 +134,12 @@ public class FlatMap extends MapType { Color rslt = new Color(); int[] pixel = new int[4]; int[] pixel_day = null; - KzedBufferedImage im = KzedMap.allocateBufferedImage(t.size, t.size); + DynmapBufferedImage im = DynmapBufferedImage.allocateBufferedImage(t.size, t.size); int[] argb_buf = im.argb_buf; - KzedBufferedImage im_day = null; + DynmapBufferedImage im_day = null; int[] argb_buf_day = null; if(night_and_day) { - im_day = KzedMap.allocateBufferedImage(t.size, t.size); + im_day = DynmapBufferedImage.allocateBufferedImage(t.size, t.size); argb_buf_day = im_day.argb_buf; pixel_day = new int[4]; } @@ -300,7 +300,7 @@ public class FlatMap extends MapType { } } finally { FileLockManager.releaseWriteLock(outputFile); - KzedMap.freeBufferedImage(im); + DynmapBufferedImage.freeBufferedImage(im); } MapManager.mapman.updateStatistics(tile, null, true, tile_update, !rendered); @@ -332,7 +332,7 @@ public class FlatMap extends MapType { } } finally { FileLockManager.releaseWriteLock(dayfile); - KzedMap.freeBufferedImage(im_day); + DynmapBufferedImage.freeBufferedImage(im_day); } MapManager.mapman.updateStatistics(tile, "day", true, tile_update, !rendered); } diff --git a/src/main/java/org/dynmap/hdmap/HDBlockModels.java b/src/main/java/org/dynmap/hdmap/HDBlockModels.java index 9a5e546e..f1b78e63 100644 --- a/src/main/java/org/dynmap/hdmap/HDBlockModels.java +++ b/src/main/java/org/dynmap/hdmap/HDBlockModels.java @@ -265,6 +265,11 @@ public class HDBlockModels { * Load models */ public static void loadModels(File datadir) { + /* Reset models-by-ID-Data cache */ + models_by_id_data.clear(); + /* Reset scaled models by scale cache */ + scaled_models_by_scale.clear(); + /* Load block models */ InputStream in = TexturePack.class.getResourceAsStream("/models.txt"); if(in != null) { diff --git a/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java b/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java index c52d9cda..92f342b6 100644 --- a/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java +++ b/src/main/java/org/dynmap/hdmap/IsoHDPerspective.java @@ -26,8 +26,8 @@ import org.dynmap.debug.Debug; import org.dynmap.utils.MapIterator.BlockStep; import org.dynmap.hdmap.TexturePack.BlockTransparency; import org.dynmap.hdmap.TexturePack.HDTextureMap; -import org.dynmap.kzedmap.KzedMap.KzedBufferedImage; import org.dynmap.kzedmap.KzedMap; +import org.dynmap.utils.DynmapBufferedImage; import org.dynmap.utils.FileLockManager; import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.MapIterator; @@ -836,8 +836,8 @@ public class IsoHDPerspective implements HDPerspective { /* Check if nether world */ boolean isnether = tile.getWorld().getEnvironment() == Environment.NETHER; /* Create buffered image for each */ - KzedBufferedImage im[] = new KzedBufferedImage[numshaders]; - KzedBufferedImage dayim[] = new KzedBufferedImage[numshaders]; + DynmapBufferedImage im[] = new DynmapBufferedImage[numshaders]; + DynmapBufferedImage dayim[] = new DynmapBufferedImage[numshaders]; int[][] argb_buf = new int[numshaders][]; int[][] day_argb_buf = new int[numshaders][]; @@ -848,10 +848,10 @@ public class IsoHDPerspective implements HDPerspective { need_emittedlightlevel = true; if(shader.isSkyLightLevelNeeded() || lighting.isSkyLightLevelNeeded()) need_skylightlevel = true; - im[i] = KzedMap.allocateBufferedImage(tileWidth, tileHeight); + im[i] = DynmapBufferedImage.allocateBufferedImage(tileWidth, tileHeight); argb_buf[i] = im[i].argb_buf; if(lighting.isNightAndDayEnabled()) { - dayim[i] = KzedMap.allocateBufferedImage(tileWidth, tileHeight); + dayim[i] = DynmapBufferedImage.allocateBufferedImage(tileWidth, tileHeight); day_argb_buf[i] = dayim[i].argb_buf; } } @@ -931,7 +931,7 @@ public class IsoHDPerspective implements HDPerspective { } } finally { FileLockManager.releaseWriteLock(f); - KzedMap.freeBufferedImage(im[i]); + DynmapBufferedImage.freeBufferedImage(im[i]); } MapManager.mapman.updateStatistics(tile, prefix, true, tile_update, !rendered[i]); /* Handle day image, if needed */ @@ -964,7 +964,7 @@ public class IsoHDPerspective implements HDPerspective { } } finally { FileLockManager.releaseWriteLock(f); - KzedMap.freeBufferedImage(dayim[i]); + DynmapBufferedImage.freeBufferedImage(dayim[i]); } MapManager.mapman.updateStatistics(tile, prefix, true, tile_update, !rendered[i]); } diff --git a/src/main/java/org/dynmap/hdmap/TexturePack.java b/src/main/java/org/dynmap/hdmap/TexturePack.java index daea9b4d..367ccda0 100644 --- a/src/main/java/org/dynmap/hdmap/TexturePack.java +++ b/src/main/java/org/dynmap/hdmap/TexturePack.java @@ -22,6 +22,7 @@ import javax.imageio.ImageIO; import org.dynmap.Color; import org.dynmap.DynmapPlugin; import org.dynmap.Log; +import org.dynmap.utils.DynmapBufferedImage; import org.dynmap.utils.MapIterator.BlockStep; import org.dynmap.kzedmap.KzedMap; import org.dynmap.utils.MapIterator; @@ -553,7 +554,7 @@ public class TexturePack { System.arraycopy(terrain_argb[i],native_scale*y,outbuf,((i>>4)*native_scale+y)*terrain_width + (i & 0xF)*native_scale, native_scale); } } - BufferedImage img = KzedMap.createBufferedImage(outbuf, terrain_width, terrain_height); + BufferedImage img = DynmapBufferedImage.createBufferedImage(outbuf, terrain_width, terrain_height); ImageIO.write(img, "png", f); } @@ -561,6 +562,8 @@ public class TexturePack { * Load texture pack mappings */ public static void loadTextureMapping(File datadir) { + /* Start clean with texture packs - need to be loaded after mapping */ + packs.clear(); /* Initialize map with blank map for all entries */ HDTextureMap.initializeTable(); /* Load block models */ diff --git a/src/main/java/org/dynmap/herochat/HeroChatHandler.java b/src/main/java/org/dynmap/herochat/HeroChatHandler.java index f3771183..7e2afd23 100644 --- a/src/main/java/org/dynmap/herochat/HeroChatHandler.java +++ b/src/main/java/org/dynmap/herochat/HeroChatHandler.java @@ -230,12 +230,13 @@ public class HeroChatHandler { hcchannels.contains(c.getNick())) { if(cce.isSentByPlayer()) { /* Player message? */ org.bukkit.entity.Player p = plugin.getServer().getPlayer(cce.getSource()); - if(p != null) + if((p != null) && (plugin.mapManager != null)) { plugin.mapManager.pushUpdate(new Client.ChatMessage("player", c.getNick(), p.getDisplayName(), cce.getMessage(), p.getName())); + } } } } diff --git a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java index a2296230..a0b71f7d 100644 --- a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java +++ b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java @@ -20,7 +20,7 @@ import org.dynmap.DynmapWorld; import org.dynmap.MapManager; import org.dynmap.TileHashManager; import org.dynmap.debug.Debug; -import org.dynmap.kzedmap.KzedMap.KzedBufferedImage; +import org.dynmap.utils.DynmapBufferedImage; import org.dynmap.utils.FileLockManager; import org.dynmap.utils.MapChunkCache; import org.dynmap.utils.MapIterator; @@ -119,15 +119,15 @@ public class DefaultTileRenderer implements MapTileRenderer { public boolean render(MapChunkCache cache, KzedMapTile tile, File outputFile) { World world = tile.getWorld(); boolean isnether = (world.getEnvironment() == Environment.NETHER); - KzedBufferedImage im = KzedMap.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight); - KzedBufferedImage zim = KzedMap.allocateBufferedImage(KzedMap.tileWidth/2, KzedMap.tileHeight/2); + DynmapBufferedImage im = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight); + DynmapBufferedImage zim = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth/2, KzedMap.tileHeight/2); boolean isempty = true; - KzedBufferedImage im_day = null; - KzedBufferedImage zim_day = null; + DynmapBufferedImage im_day = null; + DynmapBufferedImage zim_day = null; if(night_and_day) { - im_day = KzedMap.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight); - zim_day = KzedMap.allocateBufferedImage(KzedMap.tileWidth/2, KzedMap.tileHeight/2); + im_day = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight); + zim_day = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth/2, KzedMap.tileHeight/2); } int ix = KzedMap.anchorx + tile.px / 2 + tile.py / 2 - ((127-maximumHeight)/2); @@ -255,9 +255,9 @@ public class DefaultTileRenderer implements MapTileRenderer { } private void doFileWrites(final File fname, final KzedMapTile mtile, - final KzedBufferedImage img, final KzedBufferedImage img_day, + final DynmapBufferedImage img, final DynmapBufferedImage img_day, final KzedZoomedMapTile zmtile, final File zoomFile, - final KzedBufferedImage zimg, final KzedBufferedImage zimg_day, boolean rendered) { + final DynmapBufferedImage zimg, final DynmapBufferedImage zimg_day, boolean rendered) { /* Get coordinates of zoomed tile */ int ox = (mtile.px == zmtile.getTileX())?0:KzedMap.tileWidth/2; @@ -288,7 +288,7 @@ public class DefaultTileRenderer implements MapTileRenderer { } } finally { FileLockManager.releaseWriteLock(fname); - KzedMap.freeBufferedImage(img); + DynmapBufferedImage.freeBufferedImage(img); } MapManager.mapman.updateStatistics(mtile, null, true, updated_fname, !rendered); @@ -318,7 +318,7 @@ public class DefaultTileRenderer implements MapTileRenderer { } } finally { FileLockManager.releaseWriteLock(dfname); - KzedMap.freeBufferedImage(img_day); + DynmapBufferedImage.freeBufferedImage(img_day); } MapManager.mapman.updateStatistics(mtile, "day", true, updated_dfname, !rendered); } @@ -337,7 +337,7 @@ public class DefaultTileRenderer implements MapTileRenderer { } } finally { FileLockManager.releaseWriteLock(zoomFile); - KzedMap.freeBufferedImage(zimg); + DynmapBufferedImage.freeBufferedImage(zimg); } MapManager.mapman.updateStatistics(zmtile, null, true, ztile_updated, !rendered); @@ -355,16 +355,16 @@ public class DefaultTileRenderer implements MapTileRenderer { } } finally { FileLockManager.releaseWriteLock(zoomFile_day); - KzedMap.freeBufferedImage(zimg_day); + DynmapBufferedImage.freeBufferedImage(zimg_day); } MapManager.mapman.updateStatistics(zmtile, "day", true, ztile_updated, !rendered); } } private void saveZoomedTile(final KzedZoomedMapTile zmtile, final File zoomFile, - final KzedBufferedImage zimg, int ox, int oy, String subkey) { + final DynmapBufferedImage zimg, int ox, int oy, String subkey) { BufferedImage zIm = null; - KzedBufferedImage kzIm = null; + DynmapBufferedImage kzIm = null; try { zIm = ImageIO.read(zoomFile); } catch (IOException e) { @@ -374,7 +374,7 @@ public class DefaultTileRenderer implements MapTileRenderer { boolean zIm_allocated = false; if (zIm == null) { /* create new one */ - kzIm = KzedMap.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight); + kzIm = DynmapBufferedImage.allocateBufferedImage(KzedMap.tileWidth, KzedMap.tileHeight); zIm = kzIm.buf_img; zIm_allocated = true; Debug.debug("New zoom-out tile created " + zmtile.getFilename()); @@ -399,7 +399,7 @@ public class DefaultTileRenderer implements MapTileRenderer { } if(zIm_allocated) - KzedMap.freeBufferedImage(kzIm); + DynmapBufferedImage.freeBufferedImage(kzIm); else zIm.flush(); diff --git a/src/main/java/org/dynmap/kzedmap/KzedMap.java b/src/main/java/org/dynmap/kzedmap/KzedMap.java index 9f8c92f4..08ff8b3c 100644 --- a/src/main/java/org/dynmap/kzedmap/KzedMap.java +++ b/src/main/java/org/dynmap/kzedmap/KzedMap.java @@ -19,6 +19,7 @@ import org.dynmap.MapManager; import org.dynmap.MapTile; import org.dynmap.MapType; import org.dynmap.MapType.MapStep; +import org.dynmap.utils.DynmapBufferedImage; import org.dynmap.utils.MapChunkCache; import org.json.simple.JSONObject; import java.awt.image.DataBufferInt; @@ -50,20 +51,6 @@ public class KzedMap extends MapType { MapTileRenderer[] renderers; private boolean isbigmap; - /* BufferedImage with direct access to its ARGB-formatted data buffer */ - public static class KzedBufferedImage { - public BufferedImage buf_img; - public int[] argb_buf; - public int width; - public int height; - } - - /* BufferedImage cache - we use the same things a lot... */ - private static Object lock = new Object(); - private static HashMap> imgcache = - new HashMap>(); /* Indexed by resolution - X<<32+Y */ - private static final int CACHE_LIMIT = 10; - public KzedMap(ConfigurationNode configuration) { Log.verboseinfo("Loading renderers for map '" + getClass().toString() + "'..."); List renderers = configuration.createInstances("renderers", new Class[0], new Object[0]); @@ -267,52 +254,6 @@ public class KzedMap extends MapType { return y - (y % zTileHeight); } - /** - * Allocate buffered image from pool, if possible - * @param x - x dimension - * @param y - y dimension - */ - public static KzedBufferedImage allocateBufferedImage(int x, int y) { - KzedBufferedImage img = null; - synchronized(lock) { - long k = (x<<16) + y; - LinkedList ll = imgcache.get(k); - if(ll != null) { - img = ll.poll(); - } - } - if(img != null) { /* Got it - reset it for use */ - Arrays.fill(img.argb_buf, 0); - } - else { - img = new KzedBufferedImage(); - img.width = x; - img.height = y; - img.argb_buf = new int[x*y]; - } - img.buf_img = createBufferedImage(img.argb_buf, img.width, img.height); - return img; - } - - /** - * Return buffered image to pool - */ - public static void freeBufferedImage(KzedBufferedImage img) { - img.buf_img.flush(); - img.buf_img = null; /* Toss bufferedimage - seems to hold on to other memory */ - synchronized(lock) { - long k = (img.width<<16) + img.height; - LinkedList ll = imgcache.get(k); - if(ll == null) { - ll = new LinkedList(); - imgcache.put(k, ll); - } - if(ll.size() < CACHE_LIMIT) { - ll.add(img); - img = null; - } - } - } public boolean isBiomeDataNeeded() { for(MapTileRenderer r : renderers) { @@ -382,21 +323,4 @@ public class KzedMap extends MapType { renderer.buildClientConfiguration(worldObject, world, this); } } - - /* ARGB band masks */ - private static final int [] band_masks = {0xFF0000, 0xFF00, 0xff, 0xff000000}; - - /** - * Build BufferedImage from provided ARGB array and dimensions - */ - public static BufferedImage createBufferedImage(int[] argb_buf, int w, int h) { - /* Create integer-base data buffer */ - DataBuffer db = new DataBufferInt (argb_buf, w*h); - /* Create writable raster */ - WritableRaster raster = Raster.createPackedRaster(db, w, h, w, band_masks, null); - /* RGB color model */ - ColorModel color_model = ColorModel.getRGBdefault (); - /* Return buffered image */ - return new BufferedImage (color_model, raster, false, null); - } } diff --git a/src/main/java/org/dynmap/utils/DynmapBufferedImage.java b/src/main/java/org/dynmap/utils/DynmapBufferedImage.java new file mode 100644 index 00000000..cae66fc4 --- /dev/null +++ b/src/main/java/org/dynmap/utils/DynmapBufferedImage.java @@ -0,0 +1,88 @@ +package org.dynmap.utils; + +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; + +public class DynmapBufferedImage { + public BufferedImage buf_img; + public int[] argb_buf; + public int width; + public int height; + + /* BufferedImage cache - we use the same things a lot... */ + private static Object lock = new Object(); + private static HashMap> imgcache = + new HashMap>(); /* Indexed by resolution - X<<32+Y */ + private static final int CACHE_LIMIT = 10; + + /** + * Allocate buffered image from pool, if possible + * @param x - x dimension + * @param y - y dimension + */ + public static DynmapBufferedImage allocateBufferedImage(int x, int y) { + DynmapBufferedImage img = null; + synchronized(lock) { + long k = (x<<16) + y; + LinkedList ll = imgcache.get(k); + if(ll != null) { + img = ll.poll(); + } + } + if(img != null) { /* Got it - reset it for use */ + Arrays.fill(img.argb_buf, 0); + } + else { + img = new DynmapBufferedImage(); + img.width = x; + img.height = y; + img.argb_buf = new int[x*y]; + } + img.buf_img = createBufferedImage(img.argb_buf, img.width, img.height); + return img; + } + + /** + * Return buffered image to pool + */ + public static void freeBufferedImage(DynmapBufferedImage img) { + img.buf_img.flush(); + img.buf_img = null; /* Toss bufferedimage - seems to hold on to other memory */ + synchronized(lock) { + long k = (img.width<<16) + img.height; + LinkedList ll = imgcache.get(k); + if(ll == null) { + ll = new LinkedList(); + imgcache.put(k, ll); + } + if(ll.size() < CACHE_LIMIT) { + ll.add(img); + img = null; + } + } + } + + /* ARGB band masks */ + private static final int [] band_masks = {0xFF0000, 0xFF00, 0xff, 0xff000000}; + + /** + * Build BufferedImage from provided ARGB array and dimensions + */ + public static BufferedImage createBufferedImage(int[] argb_buf, int w, int h) { + /* Create integer-base data buffer */ + DataBuffer db = new DataBufferInt (argb_buf, w*h); + /* Create writable raster */ + WritableRaster raster = Raster.createPackedRaster(db, w, h, w, band_masks, null); + /* RGB color model */ + ColorModel color_model = ColorModel.getRGBdefault (); + /* Return buffered image */ + return new BufferedImage (color_model, raster, false, null); + } +} \ No newline at end of file diff --git a/src/main/java/org/dynmap/web/HttpServer.java b/src/main/java/org/dynmap/web/HttpServer.java index 3119c176..d82a02ec 100644 --- a/src/main/java/org/dynmap/web/HttpServer.java +++ b/src/main/java/org/dynmap/web/HttpServer.java @@ -11,6 +11,7 @@ import java.net.Socket; import java.net.SocketAddress; import java.util.Collections; import java.util.HashSet; +import java.util.IdentityHashMap; import java.util.SortedMap; import java.util.TreeMap; import java.util.logging.Logger; @@ -28,6 +29,9 @@ public class HttpServer extends Thread { private boolean check_banned_ips; public SortedMap handlers = new TreeMap(Collections.reverseOrder()); + + private Object lock = new Object(); + private HashSet active_connections = new HashSet(); public HttpServer(InetAddress bindAddress, int port, boolean check_banned_ips) { this.bindAddress = bindAddress; @@ -62,6 +66,9 @@ public class HttpServer extends Thread { } HttpServerConnection requestThread = new HttpServerConnection(socket, this); + synchronized(lock) { + active_connections.add(requestThread); + } requestThread.start(); } catch (IOException e) { if(listeningThread != null) /* Only report this if we didn't initiate the shutdown */ @@ -83,11 +90,25 @@ public class HttpServer extends Thread { sock.close(); sock = null; } + /* And kill off the active connections */ + HashSet sc; + synchronized(lock) { + sc = new HashSet(active_connections); + } + for(HttpServerConnection c : sc) { + c.shutdownConnection(); + } } catch (IOException e) { Log.warning("Exception while closing socket for webserver shutdown", e); } } + public void connectionEnded(HttpServerConnection c) { + synchronized(lock) { + active_connections.remove(c); + } + } + private HashSet banned_ips = new HashSet(); private HashSet banned_ips_notified = new HashSet(); private long last_loaded = 0; diff --git a/src/main/java/org/dynmap/web/HttpServerConnection.java b/src/main/java/org/dynmap/web/HttpServerConnection.java index 411149ab..7a2afe22 100644 --- a/src/main/java/org/dynmap/web/HttpServerConnection.java +++ b/src/main/java/org/dynmap/web/HttpServerConnection.java @@ -19,13 +19,13 @@ import java.net.InetSocketAddress; public class HttpServerConnection extends Thread { protected static final Logger log = Logger.getLogger("Minecraft"); - protected static final String LOG_PREFIX = "[dynmap] "; private static Pattern requestHeaderLine = Pattern.compile("^(\\S+)\\s+(\\S+)\\s+HTTP/(.+)$"); private static Pattern requestHeaderField = Pattern.compile("^([^:]+):\\s*(.+)$"); private Socket socket; private HttpServer server; + private boolean do_shutdown; private PrintStream printOut; private StringWriter sw = new StringWriter(); @@ -35,6 +35,7 @@ public class HttpServerConnection extends Thread { public HttpServerConnection(Socket socket, HttpServer server) { this.socket = socket; this.server = server; + do_shutdown = false; } private final static void readLine(InputStream in, StringWriter sw) throws IOException { @@ -232,8 +233,10 @@ public class HttpServerConnection extends Thread { } catch (IOException e) { } catch (Exception e) { - Log.severe("Exception while handling request: ", e); - e.printStackTrace(); + if(!do_shutdown) { + Log.severe("Exception while handling request: ", e); + e.printStackTrace(); + } } finally { if (socket != null) { try { @@ -241,6 +244,18 @@ public class HttpServerConnection extends Thread { } catch (IOException ex) { } } + server.connectionEnded(this); + } + } + public void shutdownConnection() { + try { + do_shutdown = true; + if(socket != null) { + socket.close(); + } + join(); /* Wait for thread to die */ + } catch (IOException iox) { + } catch (InterruptedException ix) { } } } diff --git a/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java b/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java index 90b3ed43..9c6ab99f 100644 --- a/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java +++ b/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java @@ -38,7 +38,10 @@ public class ClientUpdateHandler implements HttpHandler { String worldName = match.group(1); String timeKey = match.group(2); - DynmapWorld dynmapWorld = plugin.mapManager.getWorld(worldName); + DynmapWorld dynmapWorld = null; + if(plugin.mapManager != null) { + dynmapWorld = plugin.mapManager.getWorld(worldName); + } if (dynmapWorld == null || dynmapWorld.world == null) { response.status = WorldNotFound; return; diff --git a/src/main/java/org/dynmap/web/handlers/FileHandler.java b/src/main/java/org/dynmap/web/handlers/FileHandler.java index ba4e3eb7..36e7c3d1 100644 --- a/src/main/java/org/dynmap/web/handlers/FileHandler.java +++ b/src/main/java/org/dynmap/web/handlers/FileHandler.java @@ -16,10 +16,7 @@ import org.dynmap.web.HttpStatus; public abstract class FileHandler implements HttpHandler { protected static final Logger log = Logger.getLogger("Minecraft"); - protected static final String LOG_PREFIX = "[dynmap] "; - //BUG-this breaks re-entrancy of this handler, which is called from multiple threads (one per request) - //private byte[] readBuffer = new byte[40960]; - //Replace with pool of buffers + private LinkedList bufferpool = new LinkedList(); private Object lock = new Object(); private static final int MAX_FREE_IN_POOL = 2; diff --git a/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java b/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java index 4e915149..369546f1 100644 --- a/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java +++ b/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java @@ -18,7 +18,6 @@ import org.json.simple.parser.JSONParser; public class SendMessageHandler implements HttpHandler { protected static final Logger log = Logger.getLogger("Minecraft"); - protected static final String LOG_PREFIX = "[dynmap] "; private static final JSONParser parser = new JSONParser(); public Event onMessageReceived = new Event();