diff --git a/src/main/java/org/dynmap/Client.java b/src/main/java/org/dynmap/Client.java index 307784c7..0d00991e 100644 --- a/src/main/java/org/dynmap/Client.java +++ b/src/main/java/org/dynmap/Client.java @@ -30,7 +30,7 @@ public class Client { public static class Stamped { public long timestamp = System.currentTimeMillis(); } - + public static class ChatMessage extends Stamped { public String type = "chat"; public String source; @@ -43,7 +43,7 @@ public class Client { this.message = ChatColor.stripColor(message); } } - + public static class PlayerJoinMessage extends Stamped { public String type = "playerjoin"; public String playerName; @@ -51,7 +51,7 @@ public class Client { this.playerName = ChatColor.stripColor(playerName); } } - + public static class PlayerQuitMessage extends Stamped { public String type = "playerquit"; public String playerName; diff --git a/src/main/java/org/dynmap/Color.java b/src/main/java/org/dynmap/Color.java index 4c7fe0ae..18812e2e 100644 --- a/src/main/java/org/dynmap/Color.java +++ b/src/main/java/org/dynmap/Color.java @@ -7,9 +7,9 @@ package org.dynmap; public class Color { /* RGBA value */ private int val; - + public static final int TRANSPARENT = 0; - + public Color(int red, int green, int blue, int alpha) { setRGBA(red, green, blue, alpha); } diff --git a/src/main/java/org/dynmap/ColorScheme.java b/src/main/java/org/dynmap/ColorScheme.java index bd59b34d..7c0ae59f 100644 --- a/src/main/java/org/dynmap/ColorScheme.java +++ b/src/main/java/org/dynmap/ColorScheme.java @@ -15,9 +15,9 @@ import org.dynmap.debug.Debug; public class ColorScheme { protected static final Logger log = Logger.getLogger("Minecraft"); private static final HashMap cache = new HashMap(); - + public String name; - /* Switch to arrays - faster than map */ + /* Switch to arrays - faster than map */ public Color[][] colors; /* [blk-type][step] */ public Color[][][] datacolors; /* [bkt-type][blk-dat][step] */ @@ -26,11 +26,11 @@ public class ColorScheme { this.colors = colors; this.datacolors = datacolors; } - + private static File getColorSchemeDirectory() { return new File(DynmapPlugin.dataDirectory, "colorschemes"); } - + public static ColorScheme getScheme(String name) { if (name == null) name = "default"; @@ -41,7 +41,7 @@ public class ColorScheme { } return scheme; } - + public static ColorScheme loadScheme(String name) { File colorSchemeFile = new File(getColorSchemeDirectory(), name + ".txt"); Color[][] colors = new Color[256][]; diff --git a/src/main/java/org/dynmap/DynmapPlayerChatListener.java b/src/main/java/org/dynmap/DynmapPlayerChatListener.java index f7676e34..51a03d28 100644 --- a/src/main/java/org/dynmap/DynmapPlayerChatListener.java +++ b/src/main/java/org/dynmap/DynmapPlayerChatListener.java @@ -28,4 +28,4 @@ public class DynmapPlayerChatListener extends PlayerListener { plugin.mapManager.pushUpdate(new Client.PlayerQuitMessage(event.getPlayer().getDisplayName())); } -} \ No newline at end of file +} diff --git a/src/main/java/org/dynmap/DynmapPlugin.java b/src/main/java/org/dynmap/DynmapPlugin.java index 51631af8..d719aef3 100644 --- a/src/main/java/org/dynmap/DynmapPlugin.java +++ b/src/main/java/org/dynmap/DynmapPlugin.java @@ -72,7 +72,7 @@ public class DynmapPlugin extends JavaPlugin { public HttpServer getWebServer() { return webServer; } - + public void onEnable() { permissions = NijikokunPermissions.create(getServer(), "dynmap"); if (permissions == null) @@ -108,14 +108,14 @@ public class DynmapPlugin extends JavaPlugin { } hchand = new HeroChatHandler(configuration, this, getServer()); - + enabledTriggers.clear(); for (Object trigger : configuration.getList("render-triggers")) { enabledTriggers.add((String) trigger); } registerEvents(); - + /* Print version info */ PluginDescriptionFile pdfFile = this.getDescription(); log.info("[dynmap] version " + pdfFile.getVersion() + " is enabled" ); @@ -152,7 +152,7 @@ public class DynmapPlugin extends JavaPlugin { } }); }}; - + webServer.handlers.put("/up/sendmessage", messageHandler); } @@ -408,7 +408,7 @@ public class DynmapPlugin extends JavaPlugin { mapManager.pushUpdate(new Client.ChatMessage("web", name, message)); log.info("[WEB]" + name + ": " + message); /* Let HeroChat take a look - only broadcast to players if it doesn't handle it */ - if(hchand.sendWebMessageToHeroChat(name, message) == false) + if(hchand.sendWebMessageToHeroChat(name, message) == false) getServer().broadcastMessage("[WEB]" + name + ": " + message); } } diff --git a/src/main/java/org/dynmap/Event.java b/src/main/java/org/dynmap/Event.java index 9cba4e97..f387d978 100644 --- a/src/main/java/org/dynmap/Event.java +++ b/src/main/java/org/dynmap/Event.java @@ -5,21 +5,21 @@ import java.util.List; public class Event { private List> listeners = new LinkedList>(); - + public synchronized void addListener(Listener l) { listeners.add(l); } - + public synchronized void removeListener(Listener l) { listeners.remove(l); } - + public synchronized void trigger(T t) { for (Listener l : listeners) { l.triggered(t); } } - + public interface Listener { void triggered(T t); } diff --git a/src/main/java/org/dynmap/HeroChatHandler.java b/src/main/java/org/dynmap/HeroChatHandler.java index 3f84a7d9..59243367 100644 --- a/src/main/java/org/dynmap/HeroChatHandler.java +++ b/src/main/java/org/dynmap/HeroChatHandler.java @@ -151,7 +151,7 @@ public class HeroChatHandler { .forName("com.herocraftonline.dthielke.herochat.channels.Channel"); getname = channel.getMethod("getName"); getnick = channel.getMethod("getNick", new Class[0]); - sendmessage = channel.getMethod("sendMessage", new Class[] { + sendmessage = channel.getMethod("sendMessage", new Class[] { String.class, String.class, String.class, boolean.class } ); isgood = true; } catch (ClassNotFoundException cnfx) { @@ -256,7 +256,7 @@ public class HeroChatHandler { log.severe("[dynmap] Cannot load HeroChat channel event class!"); return; } - + /* Register event handler */ plugin.getServer().getPluginManager().registerEvent(Event.Type.CUSTOM_EVENT, new OurEventListener(), Event.Priority.Monitor, plugin); diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java index bda34f63..a5eab8c6 100644 --- a/src/main/java/org/dynmap/MapManager.java +++ b/src/main/java/org/dynmap/MapManager.java @@ -33,7 +33,7 @@ public class MapManager { public AsynchronousQueue tileQueue; public AsynchronousQueue writeQueue; - + public Map worlds = new HashMap(); public Map inactiveworlds = new HashMap(); private BukkitScheduler scheduler; @@ -48,7 +48,7 @@ public class MapManager { public static final Object lock = new Object(); public static MapManager mapman; /* Our singleton */ - + private static class ImageWriter { Runnable run; } @@ -62,7 +62,7 @@ public class MapManager { HashSet rendered = null; LinkedList renderQueue = null; MapTile tile0 = null; - + /* Full world, all maps render */ FullWorldRenderState(DynmapWorld dworld, Location l) { world = dworld; @@ -71,16 +71,16 @@ public class MapManager { rendered = new HashSet(); renderQueue = new LinkedList(); } - + /* Single tile render - used for incremental renders */ FullWorldRenderState(MapTile t) { world = worlds.get(t.getWorld().getName()); tile0 = t; } - + public void run() { MapTile tile; - + if(tile0 == null) { /* Not single tile render */ /* If render queue is empty, start next map */ if(renderQueue.isEmpty()) { @@ -144,12 +144,12 @@ public class MapManager { for(Entity e: cc.getEntities()) e.remove(); } - /* Since we only remember ones we loaded, and we're synchronous, no player has + /* Since we only remember ones we loaded, and we're synchronous, no player has * moved, so it must be safe (also prevent chunk leak, which appears to happen * because isChunkInUse defined "in use" as being within 256 blocks of a player, * while the actual in-use chunk area for a player where the chunks are managed * by the MC base server is 21x21 (or about a 160 block radius) */ - w.unloadChunk(c.x, c.z, false, false); + w.unloadChunk(c.x, c.z, false, false); } if(tile0 == null) { /* fullrender */ /* Schedule the next tile to be worked */ @@ -159,20 +159,20 @@ public class MapManager { } public MapManager(DynmapPlugin plugin, ConfigurationNode configuration) { - + mapman = this; - + this.tileQueue = new AsynchronousQueue(new Handler() { @Override public void handle(MapTile t) { if(do_sync_render) - scheduler.scheduleSyncDelayedTask(plug_in, + scheduler.scheduleSyncDelayedTask(plug_in, new FullWorldRenderState(t), 1); else render(t); } }, (int) (configuration.getDouble("renderinterval", 0.5) * 1000)); - + this.writeQueue = new AsynchronousQueue( new Handler() { @Override @@ -184,7 +184,7 @@ public class MapManager { do_timesliced_render = configuration.getBoolean("timeslicerender", true); timeslice_interval = configuration.getDouble("timesliceinterval", 0.5); do_sync_render = configuration.getBoolean("renderonsync", true); - + for(Object worldConfigurationObj : (List)configuration.getProperty("worlds")) { Map worldConfiguration = (Map)worldConfigurationObj; String worldName = (String)worldConfiguration.get("name"); @@ -195,21 +195,21 @@ public class MapManager { } } inactiveworlds.put(worldName, world); - + World bukkitWorld = plugin.getServer().getWorld(worldName); if (bukkitWorld != null) activateWorld(bukkitWorld); } - + scheduler = plugin.getServer().getScheduler(); plug_in = plugin; - + tileQueue.start(); writeQueue.start(); } - - + + void renderFullWorld(Location l) { DynmapWorld world = worlds.get(l.getWorld().getName()); if (world == null) { @@ -232,7 +232,7 @@ public class MapManager { return; } World w = world.world; - + log.info("Full render starting on world '" + w.getName() + "'..."); for (MapType map : world.maps) { int requiredChunkCount = 200; @@ -303,7 +303,7 @@ public class MapManager { log.info("Activated world '" + w.getName() + "' in Dynmap."); } } - + private MapType[] loadMapTypes(List mapConfigurations) { Event.Listener invalitateListener = new Event.Listener() { @Override @@ -332,7 +332,7 @@ public class MapManager { mapTypes.toArray(result); return result; } - + public int touch(Location l) { DynmapWorld world = worlds.get(l.getWorld().getName()); if (world == null) @@ -352,24 +352,24 @@ public class MapManager { Debug.debug("Invalidating tile " + tile.getFilename()); tileQueue.push(tile); } - + public void startRendering() { tileQueue.start(); writeQueue.start(); } - + public void stopRendering() { tileQueue.stop(); writeQueue.stop(); } - + public boolean render(MapTile tile) { boolean result = tile.getMap().render(tile, getTileFile(tile)); //Do update after async file write - + return result; - } - + } + private HashMap worldTileDirectories = new HashMap(); public File getTileFile(MapTile tile) { World world = tile.getWorld(); @@ -381,7 +381,7 @@ public class MapManager { if (!worldTileDirectory.isDirectory() && !worldTileDirectory.mkdirs()) { log.warning("Could not create directory for tiles ('" + worldTileDirectory + "')."); } - return new File(worldTileDirectory, tile.getFilename()); + return new File(worldTileDirectory, tile.getFilename()); } public void pushUpdate(Object update) { @@ -389,29 +389,29 @@ public class MapManager { world.updates.pushUpdate(update); } } - + public void pushUpdate(World world, Object update) { pushUpdate(world.getName(), update); } - + public void pushUpdate(String worldName, Object update) { DynmapWorld world = worlds.get(worldName); world.updates.pushUpdate(update); } - + public Object[] getWorldUpdates(String worldName, long since) { DynmapWorld world = worlds.get(worldName); if (world == null) return new Object[0]; return world.updates.getUpdatedObjects(since); } - + public void enqueueImageWrite(Runnable run) { ImageWriter handler = new ImageWriter(); handler.run = run; writeQueue.push(handler); } - + public boolean doSyncRender() { return do_sync_render; } diff --git a/src/main/java/org/dynmap/MapTile.java b/src/main/java/org/dynmap/MapTile.java index 9484a352..8ab828eb 100644 --- a/src/main/java/org/dynmap/MapTile.java +++ b/src/main/java/org/dynmap/MapTile.java @@ -9,7 +9,7 @@ public abstract class MapTile { public World getWorld() { return world; } - + public MapType getMap() { return map; } @@ -20,12 +20,12 @@ public abstract class MapTile { this.world = world; this.map = map; } - + @Override public int hashCode() { return getFilename().hashCode() ^ getWorld().hashCode(); } - + @Override public boolean equals(Object obj) { if (obj instanceof MapTile) { diff --git a/src/main/java/org/dynmap/MapType.java b/src/main/java/org/dynmap/MapType.java index 64ff0f24..006d1846 100644 --- a/src/main/java/org/dynmap/MapType.java +++ b/src/main/java/org/dynmap/MapType.java @@ -6,7 +6,7 @@ import org.bukkit.Location; public abstract class MapType { public Event onTileInvalidated = new Event(); - + public abstract MapTile[] getTiles(Location l); public abstract MapTile[] getAdjecentTiles(MapTile tile); diff --git a/src/main/java/org/dynmap/PlayerList.java b/src/main/java/org/dynmap/PlayerList.java index 3954264c..75e6f3e6 100644 --- a/src/main/java/org/dynmap/PlayerList.java +++ b/src/main/java/org/dynmap/PlayerList.java @@ -87,7 +87,7 @@ public class PlayerList { visiblePlayers.toArray(result); return result; } - + public Player[] getVisiblePlayers() { ArrayList visiblePlayers = new ArrayList(); Player[] onlinePlayers = server.getOnlinePlayers(); diff --git a/src/main/java/org/dynmap/UpdateQueue.java b/src/main/java/org/dynmap/UpdateQueue.java index 995a57c5..3dfb244a 100644 --- a/src/main/java/org/dynmap/UpdateQueue.java +++ b/src/main/java/org/dynmap/UpdateQueue.java @@ -13,7 +13,7 @@ public class UpdateQueue { public void pushUpdate(Object obj) { synchronized (lock) { - /* Do inside lock - prevent delay between time and actual work */ + /* Do inside lock - prevent delay between time and actual work */ long now = System.currentTimeMillis(); long deadline = now - maxUpdateAge; ListIterator i = updateQueue.listIterator(0); @@ -49,7 +49,7 @@ public class UpdateQueue { break; } } - + // Reverse output. updates = new Object[tmpupdates.size()]; for (int i = 0; i < updates.length; i++) { diff --git a/src/main/java/org/dynmap/debug/Debug.java b/src/main/java/org/dynmap/debug/Debug.java index 727d268d..d6973e6f 100644 --- a/src/main/java/org/dynmap/debug/Debug.java +++ b/src/main/java/org/dynmap/debug/Debug.java @@ -8,15 +8,15 @@ public class Debug { public synchronized static void addDebugger(Debugger d) { debuggers.add(d); } - + public synchronized static void removeDebugger(Debugger d) { debuggers.remove(d); } - + public synchronized static void clearDebuggers() { debuggers.clear(); } - + public synchronized static void debug(String message) { for(int i = 0; i < debuggers.size(); i++) debuggers.get(i).debug(message); } diff --git a/src/main/java/org/dynmap/debug/LogDebugger.java b/src/main/java/org/dynmap/debug/LogDebugger.java index c52ecd85..3c5911a8 100644 --- a/src/main/java/org/dynmap/debug/LogDebugger.java +++ b/src/main/java/org/dynmap/debug/LogDebugger.java @@ -9,10 +9,10 @@ import org.bukkit.plugin.java.JavaPlugin; public class LogDebugger implements Debugger { protected static final Logger log = Logger.getLogger("Minecraft"); private static String prepend = "dynmap: "; - + public LogDebugger(JavaPlugin plugin, Map configuration) { } - + @Override public void debug(String message) { log.info(prepend + message); diff --git a/src/main/java/org/dynmap/debug/NullDebugger.java b/src/main/java/org/dynmap/debug/NullDebugger.java index 6d2fca74..7b4b689a 100644 --- a/src/main/java/org/dynmap/debug/NullDebugger.java +++ b/src/main/java/org/dynmap/debug/NullDebugger.java @@ -9,7 +9,7 @@ public class NullDebugger implements Debugger { public NullDebugger(JavaPlugin plugin, Map configuration) { } - + public void debug(String message) { } diff --git a/src/main/java/org/dynmap/flat/FlatMap.java b/src/main/java/org/dynmap/flat/FlatMap.java index b9e2abd3..f509cef5 100644 --- a/src/main/java/org/dynmap/flat/FlatMap.java +++ b/src/main/java/org/dynmap/flat/FlatMap.java @@ -24,7 +24,7 @@ public class FlatMap extends MapType { private String prefix; private ColorScheme colorScheme; private int maximumHeight = 127; - + public FlatMap(Map configuration) { prefix = (String) configuration.get("prefix"); colorScheme = ColorScheme.getScheme((String) configuration.get("colorscheme")); @@ -91,36 +91,36 @@ public class FlatMap extends MapType { int my; int blockType; if(isnether) { - /* Scan until we hit air */ - my = 127; - while((blockType = w.getBlockTypeIdAt(mx, my, mz)) != 0) { - my--; - if(my < 0) { /* Solid - use top */ - my = 127; - blockType = w.getBlockTypeIdAt(mx, my, mz); - break; - } - } - if(blockType == 0) { /* Hit air - now find non-air */ - while((blockType = w.getBlockTypeIdAt(mx, my, mz)) == 0) { - my--; - if(my < 0) { - my = 0; - break; - } - } - } + /* Scan until we hit air */ + my = 127; + while((blockType = w.getBlockTypeIdAt(mx, my, mz)) != 0) { + my--; + if(my < 0) { /* Solid - use top */ + my = 127; + blockType = w.getBlockTypeIdAt(mx, my, mz); + break; + } + } + if(blockType == 0) { /* Hit air - now find non-air */ + while((blockType = w.getBlockTypeIdAt(mx, my, mz)) == 0) { + my--; + if(my < 0) { + my = 0; + break; + } + } + } } else { - my = w.getHighestBlockYAt(mx, mz) - 1; - if(my > maximumHeight) my = maximumHeight; - blockType = w.getBlockTypeIdAt(mx, my, mz); + my = w.getHighestBlockYAt(mx, mz) - 1; + if(my > maximumHeight) my = maximumHeight; + blockType = w.getBlockTypeIdAt(mx, my, mz); } byte data = 0; Color[] colors = colorScheme.colors[blockType]; if(colorScheme.datacolors[blockType] != null) { - data = w.getBlockAt(mx, my, mz).getData(); - colors = colorScheme.datacolors[blockType][data]; + data = w.getBlockAt(mx, my, mz).getData(); + colors = colorScheme.datacolors[blockType][data]; } if (colors == null) continue; @@ -129,26 +129,26 @@ public class FlatMap extends MapType { continue; boolean below = my < 64; - + // Make height range from 0 - 1 (1 - 0 for below and 0 - 1 above) float height = (below ? 64 - my : my - 64) / 64.0f; - + // Defines the 'step' in coloring. float step = 10 / 128.0f; - + // The step applied to height. float scale = ((int)(height/step))*step; // Make the smaller values change the color (slightly) more than the higher values. scale = (float)Math.pow(scale, 1.1f); - + // Don't let the color go fully white or fully black. scale *= 0.8f; - + pixel[0] = c.getRed(); pixel[1] = c.getGreen(); pixel[2] = c.getBlue(); - + if (below) { pixel[0] -= pixel[0] * scale; pixel[1] -= pixel[1] * scale; @@ -158,7 +158,7 @@ public class FlatMap extends MapType { pixel[1] += (255-pixel[1]) * scale; pixel[2] += (255-pixel[2]) * scale; } - + raster.setPixel(t.size-y-1, x, pixel); rendered = true; } @@ -167,19 +167,19 @@ public class FlatMap extends MapType { final MapTile mtile = tile; final BufferedImage img = im; MapManager.mapman.enqueueImageWrite(new Runnable() { - public void run() { - Debug.debug("saving image " + fname.getPath()); - try { - ImageIO.write(img, "png", fname); - } catch (IOException e) { - Debug.error("Failed to save image: " + fname.getPath(), e); - } catch (java.lang.NullPointerException e) { - Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e); - } - img.flush(); - MapManager.mapman.pushUpdate(mtile.getWorld(), - new Client.Tile(mtile.getFilename())); - } + public void run() { + Debug.debug("saving image " + fname.getPath()); + try { + ImageIO.write(img, "png", fname); + } catch (IOException e) { + Debug.error("Failed to save image: " + fname.getPath(), e); + } catch (java.lang.NullPointerException e) { + Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e); + } + img.flush(); + MapManager.mapman.pushUpdate(mtile.getWorld(), + new Client.Tile(mtile.getFilename())); + } }); return rendered; diff --git a/src/main/java/org/dynmap/kzedmap/CaveTileRenderer.java b/src/main/java/org/dynmap/kzedmap/CaveTileRenderer.java index 3c1f557f..142c4e86 100644 --- a/src/main/java/org/dynmap/kzedmap/CaveTileRenderer.java +++ b/src/main/java/org/dynmap/kzedmap/CaveTileRenderer.java @@ -20,11 +20,11 @@ public class CaveTileRenderer extends DefaultTileRenderer { return; int id = world.getBlockTypeIdAt(x, y, z); - if(isnether) { /* Make ceiling into air in nether */ - if(id != 0) - id = 0; - else - isnether = false; + if(isnether) { /* Make ceiling into air in nether */ + if(id != 0) + id = 0; + else + isnether = false; } switch (seq) { diff --git a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java index 8e034835..3ad9e98f 100644 --- a/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java +++ b/src/main/java/org/dynmap/kzedmap/DefaultTileRenderer.java @@ -26,10 +26,10 @@ public class DefaultTileRenderer implements MapTileRenderer { protected String name; protected int maximumHeight = 127; protected ColorScheme colorScheme; - + protected HashSet highlightBlocks = new HashSet(); protected Color highlightColor = new Color(255, 0, 0); - + @Override public String getName() { return name; @@ -60,10 +60,10 @@ public class DefaultTileRenderer implements MapTileRenderer { /* Don't mess with existing height-clipped renders */ if(maximumHeight < 127) - isnether = false; - + isnether = false; + int jx, jz; - + int x, y; Color c1 = new Color(); @@ -87,7 +87,7 @@ public class DefaultTileRenderer implements MapTileRenderer { r.setPixel(x - 1, y, rgb); isempty = false; } - + jx++; jz++; @@ -126,90 +126,90 @@ public class DefaultTileRenderer implements MapTileRenderer { final File fname = outputFile; final KzedMapTile mtile = tile; final BufferedImage img = im; - final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(), - (KzedMap) mtile.getMap(), mtile); - final File zoomFile = MapManager.mapman.getTileFile(zmtile); - - MapManager.mapman.enqueueImageWrite(new Runnable() { - public void run() { - doFileWrites(fname, mtile, img, zmtile, zoomFile); - } - }); + final KzedZoomedMapTile zmtile = new KzedZoomedMapTile(mtile.getWorld(), + (KzedMap) mtile.getMap(), mtile); + final File zoomFile = MapManager.mapman.getTileFile(zmtile); + + MapManager.mapman.enqueueImageWrite(new Runnable() { + public void run() { + doFileWrites(fname, mtile, img, zmtile, zoomFile); + } + }); return !isempty; } - + private void doFileWrites(final File fname, final KzedMapTile mtile, - final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) { - Debug.debug("saving image " + fname.getPath()); - try { - ImageIO.write(img, "png", fname); - } catch (IOException e) { - Debug.error("Failed to save image: " + fname.getPath(), e); - } catch (java.lang.NullPointerException e) { - Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e); - } - mtile.file = fname; - // Since we've already got the new tile, and we're on an async thread, just - // make the zoomed tile here - int px = mtile.px; - int py = mtile.py; - int zpx = zmtile.getTileX(); - int zpy = zmtile.getTileY(); + final BufferedImage img, final KzedZoomedMapTile zmtile, final File zoomFile) { + Debug.debug("saving image " + fname.getPath()); + try { + ImageIO.write(img, "png", fname); + } catch (IOException e) { + Debug.error("Failed to save image: " + fname.getPath(), e); + } catch (java.lang.NullPointerException e) { + Debug.error("Failed to save image (NullPointerException): " + fname.getPath(), e); + } + mtile.file = fname; + // Since we've already got the new tile, and we're on an async thread, just + // make the zoomed tile here + int px = mtile.px; + int py = mtile.py; + int zpx = zmtile.getTileX(); + int zpy = zmtile.getTileY(); - /* scaled size */ - int scw = KzedMap.tileWidth / 2; - int sch = KzedMap.tileHeight / 2; + /* scaled size */ + int scw = KzedMap.tileWidth / 2; + int sch = KzedMap.tileHeight / 2; - /* origin in zoomed-out tile */ - int ox = 0; - int oy = 0; + /* origin in zoomed-out tile */ + int ox = 0; + int oy = 0; - if (zpx != px) - ox = scw; - if (zpy != py) - oy = sch; + if (zpx != px) + ox = scw; + if (zpy != py) + oy = sch; - BufferedImage zIm = null; - try { - zIm = ImageIO.read(zoomFile); - } catch (IOException e) { - } catch (IndexOutOfBoundsException e) { - } + BufferedImage zIm = null; + try { + zIm = ImageIO.read(zoomFile); + } catch (IOException e) { + } catch (IndexOutOfBoundsException e) { + } - if (zIm == null) { - /* create new one */ - zIm = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB); - Debug.debug("New zoom-out tile created " + zmtile.getFilename()); - } else { - Debug.debug("Loaded zoom-out tile from " + zmtile.getFilename()); - } - - /* blit scaled rendered tile onto zoom-out tile */ - Graphics2D g2 = zIm.createGraphics(); - g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); - g2.drawImage(img, ox, oy, scw, sch, null); + if (zIm == null) { + /* create new one */ + zIm = new BufferedImage(KzedMap.tileWidth, KzedMap.tileHeight, BufferedImage.TYPE_INT_RGB); + Debug.debug("New zoom-out tile created " + zmtile.getFilename()); + } else { + Debug.debug("Loaded zoom-out tile from " + zmtile.getFilename()); + } - img.flush(); + /* blit scaled rendered tile onto zoom-out tile */ + Graphics2D g2 = zIm.createGraphics(); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + g2.drawImage(img, ox, oy, scw, sch, null); - /* save zoom-out tile */ - - try { - ImageIO.write(zIm, "png", zoomFile); - Debug.debug("Saved zoom-out tile at " + zoomFile.getName()); - } catch (IOException e) { - Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e); - } catch (java.lang.NullPointerException e) { - Debug.error("Failed to save zoom-out tile (NullPointerException): " + zoomFile.getName(), e); - } - zIm.flush(); - /* Push updates for both files.*/ - MapManager.mapman.pushUpdate(mtile.getWorld(), - new Client.Tile(mtile.getFilename())); - MapManager.mapman.pushUpdate(zmtile.getWorld(), - new Client.Tile(zmtile.getFilename())); + img.flush(); + + /* save zoom-out tile */ + + try { + ImageIO.write(zIm, "png", zoomFile); + Debug.debug("Saved zoom-out tile at " + zoomFile.getName()); + } catch (IOException e) { + Debug.error("Failed to save zoom-out tile: " + zoomFile.getName(), e); + } catch (java.lang.NullPointerException e) { + Debug.error("Failed to save zoom-out tile (NullPointerException): " + zoomFile.getName(), e); + } + zIm.flush(); + /* Push updates for both files.*/ + MapManager.mapman.pushUpdate(mtile.getWorld(), + new Client.Tile(mtile.getFilename())); + MapManager.mapman.pushUpdate(zmtile.getWorld(), + new Client.Tile(zmtile.getFilename())); } - + protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result) { result.setTransparent(); @@ -219,19 +219,19 @@ public class DefaultTileRenderer implements MapTileRenderer { } int id = world.getBlockTypeIdAt(x, y, z); byte data = 0; - if(isnether) { /* Make bedrock ceiling into air in nether */ - if(id != 0) { - /* Remember first color we see, in case we wind up solid */ - if(result.isTransparent()) - if(colorScheme.colors[id] != null) - result.setColor(colorScheme.colors[id][seq]); - id = 0; - } - else - isnether = false; + if(isnether) { /* Make bedrock ceiling into air in nether */ + if(id != 0) { + /* Remember first color we see, in case we wind up solid */ + if(result.isTransparent()) + if(colorScheme.colors[id] != null) + result.setColor(colorScheme.colors[id][seq]); + id = 0; + } + else + isnether = false; } - if(colorScheme.datacolors[id] != null) { /* If data colored */ - data = world.getBlockAt(x, y, z).getData(); + if(colorScheme.datacolors[id] != null) { /* If data colored */ + data = world.getBlockAt(x, y, z).getData(); } switch (seq) { case 0: @@ -257,9 +257,9 @@ public class DefaultTileRenderer implements MapTileRenderer { } Color[] colors; if(data != 0) - colors = colorScheme.datacolors[id][data]; + colors = colorScheme.datacolors[id][data]; else - colors = colorScheme.colors[id]; + colors = colorScheme.colors[id]; if (colors != null) { Color c = colors[seq]; if (c.getAlpha() > 0) { diff --git a/src/main/java/org/dynmap/kzedmap/HighlightTileRenderer.java b/src/main/java/org/dynmap/kzedmap/HighlightTileRenderer.java index 826fed17..30fa8db6 100644 --- a/src/main/java/org/dynmap/kzedmap/HighlightTileRenderer.java +++ b/src/main/java/org/dynmap/kzedmap/HighlightTileRenderer.java @@ -21,7 +21,7 @@ public class HighlightTileRenderer extends DefaultTileRenderer { highlightBlocks.add((Integer)highlightObj); } } - + @Override protected void scan(World world, int x, int y, int z, int seq, boolean isnether, final Color result) { result.setTransparent(); @@ -31,20 +31,20 @@ public class HighlightTileRenderer extends DefaultTileRenderer { } int id = world.getBlockTypeIdAt(x, y, z); - if(isnether) { /* Make bedrock ceiling into air in nether */ - if(id != 0) { - /* Remember first color we see, in case we wind up solid */ - if(result.isTransparent()) - if(colorScheme.colors[id] != null) - result.setColor(colorScheme.colors[id][seq]); - id = 0; - } - else - isnether = false; + if(isnether) { /* Make bedrock ceiling into air in nether */ + if(id != 0) { + /* Remember first color we see, in case we wind up solid */ + if(result.isTransparent()) + if(colorScheme.colors[id] != null) + result.setColor(colorScheme.colors[id][seq]); + id = 0; + } + else + isnether = false; } byte data = 0; - if(colorScheme.datacolors[id] != null) { /* If data colored */ - data = world.getBlockAt(x, y, z).getData(); + if(colorScheme.datacolors[id] != null) { /* If data colored */ + data = world.getBlockAt(x, y, z).getData(); } switch (seq) { @@ -67,9 +67,9 @@ public class HighlightTileRenderer extends DefaultTileRenderer { if (id != 0) { Color[] colors; if(data != 0) - colors = colorScheme.datacolors[id][data]; + colors = colorScheme.datacolors[id][data]; else - colors = colorScheme.colors[id]; + colors = colorScheme.colors[id]; if (colors != null) { Color c = colors[seq]; @@ -85,9 +85,9 @@ public class HighlightTileRenderer extends DefaultTileRenderer { * if (c.getAlpha() == 255) { return c; } */ /* this block is transparent, so recurse */ - + // No need to blend if result is opaque. - if (result.getAlpha() < 255) { + if (result.getAlpha() < 255) { int cr = result.getRed(); int cg = result.getGreen(); int cb = result.getBlue(); @@ -96,7 +96,7 @@ public class HighlightTileRenderer extends DefaultTileRenderer { cg *= ca; cb *= ca; int na = 255 - ca; - + result.setRGBA((c.getRed() * na + cr) >> 8, (c.getGreen() * na + cg) >> 8, (c.getBlue() * na + cb) >> 8, Math.min(255, c.getAlpha()+ca) // Not really correct, but gets the job done without recursion while still looking ok. ); diff --git a/src/main/java/org/dynmap/kzedmap/KzedMap.java b/src/main/java/org/dynmap/kzedmap/KzedMap.java index 8c44acf2..7da79a28 100644 --- a/src/main/java/org/dynmap/kzedmap/KzedMap.java +++ b/src/main/java/org/dynmap/kzedmap/KzedMap.java @@ -67,7 +67,7 @@ public class KzedMap extends MapType { @Override public MapTile[] getTiles(Location l) { World world = l.getWorld(); - + int x = l.getBlockX(); int y = l.getBlockY(); int z = l.getBlockZ(); @@ -141,7 +141,7 @@ public class KzedMap extends MapType { /** * Test if point x,z is inside rectangle with corner at r0x,r0z and with * size vectors s1x,s1z and s2x,s2z - * + * */ private boolean testPointInRectangle(int x, int z, int r0x, int r0z, int s1x, int s1z, int s2x, int s2z) { @@ -150,7 +150,7 @@ public class KzedMap extends MapType { int dots1 = xr*s1x + zr*s1z; int dots2 = xr*s2x + zr*s2z; /* If dot product of relative point and each side is between zero and dot product - * of each side and itself, we're inside + * of each side and itself, we're inside */ if((dots1 >= 0) && (dots1 <= (s1x*s1x+s1z*s1z)) && (dots2 >= 0) && (dots2 <= (s2x*s2x+s2z*s2z))) { @@ -162,11 +162,11 @@ public class KzedMap extends MapType { public DynmapChunk[] getRequiredChunks(MapTile tile) { if (tile instanceof KzedMapTile) { KzedMapTile t = (KzedMapTile) tile; - + int ix = KzedMap.anchorx + t.px / 2 + t.py / 2; //int iy = 127; int iz = KzedMap.anchorz + t.px / 2 - t.py / 2; - + int x1 = ix - KzedMap.tileHeight / 2; int x2 = ix + KzedMap.tileWidth / 2 + KzedMap.tileHeight / 2; @@ -183,10 +183,10 @@ public class KzedMap extends MapType { * render path to y=0), correspond to ix-64, iz+64 to * ix,iz+128 to ix+64,iz+64 to ix,iz. Projection of * the prism on to the x,z plane (which is all that matters for - * chunks) yields a diagonal rectangular area from ix-64(x1),iz+64 - * to ix,iz+128(z2) to ix+128(x2),iz to ix+64,iz-64(z1). + * chunks) yields a diagonal rectangular area from ix-64(x1),iz+64 + * to ix,iz+128(z2) to ix+128(x2),iz to ix+64,iz-64(z1). * Chunks outside this are not needed - we scan a simple rectangle - * (chunk grid aligned) and skip adding the ones that are outside. + * (chunk grid aligned) and skip adding the ones that are outside. * This results in 42% less chunks being loaded. */ ArrayList chunks = new ArrayList(); @@ -211,7 +211,7 @@ public class KzedMap extends MapType { chunks.add(chunk); } } - + DynmapChunk[] result = new DynmapChunk[chunks.size()]; chunks.toArray(result); return result; diff --git a/src/main/java/org/dynmap/kzedmap/KzedMapTile.java b/src/main/java/org/dynmap/kzedmap/KzedMapTile.java index 3bab1245..78453ff2 100644 --- a/src/main/java/org/dynmap/kzedmap/KzedMapTile.java +++ b/src/main/java/org/dynmap/kzedmap/KzedMapTile.java @@ -9,7 +9,7 @@ public class KzedMapTile extends MapTile { public KzedMap map; public MapTileRenderer renderer; public int px, py; - + // Hack. public File file = null; diff --git a/src/main/java/org/dynmap/web/BoundInputStream.java b/src/main/java/org/dynmap/web/BoundInputStream.java index 66665f16..0cf9b54d 100644 --- a/src/main/java/org/dynmap/web/BoundInputStream.java +++ b/src/main/java/org/dynmap/web/BoundInputStream.java @@ -8,12 +8,12 @@ public class BoundInputStream extends InputStream { protected static final Logger log = Logger.getLogger("Minecraft"); private InputStream base; private long bound; - + public BoundInputStream(InputStream base, long bound) { this.base = base; this.bound = bound; } - + @Override public int read() throws IOException { if (bound <= 0) return -1; @@ -22,17 +22,17 @@ public class BoundInputStream extends InputStream { bound--; return r; } - + @Override public int available() throws IOException { return (int)Math.min(base.available(), bound); } - + @Override public boolean markSupported() { return false; } - + @Override public int read(byte[] b, int off, int len) throws IOException { if (bound <= 0) return -1; @@ -41,19 +41,19 @@ public class BoundInputStream extends InputStream { bound -= r; return r; } - + @Override public int read(byte[] b) throws IOException { return read(b, 0, b.length); } - + @Override public long skip(long n) throws IOException { long r = base.skip(Math.min(bound, n)); bound -= r; return r; } - + @Override public void close() throws IOException { base.close(); diff --git a/src/main/java/org/dynmap/web/HttpRequest.java b/src/main/java/org/dynmap/web/HttpRequest.java index db25e396..a2cb2746 100644 --- a/src/main/java/org/dynmap/web/HttpRequest.java +++ b/src/main/java/org/dynmap/web/HttpRequest.java @@ -9,5 +9,5 @@ public class HttpRequest { public String path; public String version; public Map fields = new HashMap(); - public InputStream body; + public InputStream body; } diff --git a/src/main/java/org/dynmap/web/HttpResponse.java b/src/main/java/org/dynmap/web/HttpResponse.java index 102f249e..5b0c80b8 100644 --- a/src/main/java/org/dynmap/web/HttpResponse.java +++ b/src/main/java/org/dynmap/web/HttpResponse.java @@ -10,7 +10,7 @@ public class HttpResponse { public String version = "1.1"; public HttpStatus status = null; public Map fields = new HashMap(); - + private OutputStream body; public OutputStream getBody() throws IOException { if (body != null) { @@ -21,7 +21,7 @@ public class HttpResponse { } return null; } - + public HttpResponse(HttpServerConnection connection, OutputStream body) { this.connection = connection; this.body = body; diff --git a/src/main/java/org/dynmap/web/HttpServerConnection.java b/src/main/java/org/dynmap/web/HttpServerConnection.java index 6b6d2225..67a1ecb5 100644 --- a/src/main/java/org/dynmap/web/HttpServerConnection.java +++ b/src/main/java/org/dynmap/web/HttpServerConnection.java @@ -21,10 +21,10 @@ public class HttpServerConnection extends Thread { 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 PrintStream printOut; private StringWriter sw = new StringWriter(); private Matcher requestHeaderLineMatcher; @@ -45,7 +45,7 @@ public class HttpServerConnection extends Thread { sw.append(c); } } - + private final String readLine(InputStream in) throws IOException { readLine(in, sw); String r = sw.toString(); @@ -55,16 +55,16 @@ public class HttpServerConnection extends Thread { private final boolean readRequestHeader(InputStream in, HttpRequest request) throws IOException { String statusLine = readLine(in); - + if (statusLine == null) return false; - + if (requestHeaderLineMatcher == null) { requestHeaderLineMatcher = requestHeaderLine.matcher(statusLine); } else { requestHeaderLineMatcher.reset(statusLine); } - + Matcher m = requestHeaderLineMatcher; if (!m.matches()) return false; @@ -79,7 +79,7 @@ public class HttpServerConnection extends Thread { } else { requestHeaderFieldMatcher.reset(line); } - + m = requestHeaderFieldMatcher; // Warning: unknown lines are ignored. if (m.matches()) { @@ -109,7 +109,7 @@ public class HttpServerConnection extends Thread { out.append("\r\n"); out.flush(); } - + public final void writeResponseHeader(HttpResponse response) throws IOException { writeResponseHeader(printOut, response); } @@ -121,16 +121,16 @@ public class HttpServerConnection extends Thread { socket.setSoTimeout(5000); InputStream in = socket.getInputStream(); BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream(), 40960); - + printOut = new PrintStream(out, false); while (true) { HttpRequest request = new HttpRequest(); - + if (!readRequestHeader(in, request)) { socket.close(); return; } - + long bound = -1; BoundInputStream boundBody = null; { @@ -166,9 +166,9 @@ public class HttpServerConnection extends Thread { socket.close(); return; } - + HttpResponse response = new HttpResponse(this, out); - + try { handler.handle(relativePath, request, response); } catch (IOException e) { @@ -187,9 +187,9 @@ public class HttpServerConnection extends Thread { //socket.close(); //return; } - + boolean isKeepalive = !"close".equals(request.fields.get(HttpField.Connection)) && !"close".equals(response.fields.get(HttpField.Connection)); - + String contentLength = response.fields.get("Content-Length"); if (isKeepalive && contentLength == null) { // A handler has been a bad boy, but we're here to fix it. diff --git a/src/main/java/org/dynmap/web/HttpStatus.java b/src/main/java/org/dynmap/web/HttpStatus.java index e4aaa3d6..efe5353f 100644 --- a/src/main/java/org/dynmap/web/HttpStatus.java +++ b/src/main/java/org/dynmap/web/HttpStatus.java @@ -3,20 +3,20 @@ package org.dynmap.web; public final class HttpStatus { private int code; private String text; - + public int getCode() { return code; } - + public String getText() { return text; } - + public HttpStatus(int code, String text) { this.code = code; this.text = text; } - + // Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html public static final HttpStatus Continue = new HttpStatus(100, "Continue"); public static final HttpStatus SwitchingProtocols = new HttpStatus(101, "Switching Protocols"); diff --git a/src/main/java/org/dynmap/web/Json.java b/src/main/java/org/dynmap/web/Json.java index dd3a86a0..882b00fb 100644 --- a/src/main/java/org/dynmap/web/Json.java +++ b/src/main/java/org/dynmap/web/Json.java @@ -13,7 +13,7 @@ public class Json { appendJson(o, sb); return sb.toString(); } - + public static void appendJson(Object o, StringBuilder s) { if (o == null) { s.append("null"); @@ -59,7 +59,7 @@ public class Json { } else if (o instanceof Object) /* TODO: Always true, maybe interface? */ { s.append("{"); boolean first = true; - + Class c = o.getClass(); for(Field field : c.getFields()) { if (!Modifier.isPublic(field.getModifiers())) @@ -73,7 +73,7 @@ public class Json { } catch (IllegalAccessException e) { continue; } - + if (first) first = false; else diff --git a/src/main/java/org/dynmap/web/handlers/ClientConfigurationHandler.java b/src/main/java/org/dynmap/web/handlers/ClientConfigurationHandler.java index 52c5591b..56edb4c1 100644 --- a/src/main/java/org/dynmap/web/handlers/ClientConfigurationHandler.java +++ b/src/main/java/org/dynmap/web/handlers/ClientConfigurationHandler.java @@ -20,18 +20,18 @@ public class ClientConfigurationHandler implements HttpHandler { public void handle(String path, HttpRequest request, HttpResponse response) throws Exception { if (cachedConfiguration == null) { String s = Json.stringifyJson(configuration); - + cachedConfiguration = s.getBytes(); } String dateStr = new Date().toString(); - + response.fields.put("Date", dateStr); response.fields.put("Content-Type", "text/plain"); response.fields.put("Expires", "Thu, 01 Dec 1994 16:00:00 GMT"); response.fields.put("Last-modified", dateStr); response.fields.put("Content-Length", Integer.toString(cachedConfiguration.length)); response.status = HttpStatus.OK; - + BufferedOutputStream out = null; out = new BufferedOutputStream(response.getBody()); out.write(cachedConfiguration); diff --git a/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java b/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java index 09d57459..d123f1a8 100644 --- a/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java +++ b/src/main/java/org/dynmap/web/handlers/ClientUpdateHandler.java @@ -31,26 +31,26 @@ public class ClientUpdateHandler implements HttpHandler { } Pattern updatePathPattern = Pattern.compile("world/([^/]+)/([0-9]*)"); - private static final HttpStatus WorldNotFound = new HttpStatus(HttpStatus.NotFound.getCode(), "World Not Found"); + private static final HttpStatus WorldNotFound = new HttpStatus(HttpStatus.NotFound.getCode(), "World Not Found"); @Override public void handle(String path, HttpRequest request, HttpResponse response) throws Exception { - + Matcher match = updatePathPattern.matcher(path); - + if (!match.matches()) { response.status = HttpStatus.Forbidden; return; } - + String worldName = match.group(1); String timeKey = match.group(2); - + World world = server.getWorld(worldName); if (world == null) { response.status = WorldNotFound; return; } - + long current = System.currentTimeMillis(); long since = 0; @@ -60,14 +60,14 @@ public class ClientUpdateHandler implements HttpHandler { } catch (NumberFormatException e) { } } - + Client.Update update = new Client.Update(); update.timestamp = current; update.servertime = world.getTime() % 24000; update.hasStorm = world.hasStorm(); update.isThundering = world.isThundering(); - - + + Player[] players = playerList.getVisiblePlayers(); update.players = new Client.Player[players.length]; for(int i=0;i 0) return path.substring(dotindex); return null; } - + protected final String formatPath(String path) { int qmark = path.indexOf('?'); if (qmark >= 0) @@ -54,11 +54,11 @@ public abstract class FileHandler implements HttpHandler { path = getDefaultFilename(path); return path; } - + protected String getDefaultFilename(String path) { return path + "index.html"; } - + @Override public void handle(String path, HttpRequest request, HttpResponse response) throws Exception { InputStream fileInput = null; @@ -69,10 +69,10 @@ public abstract class FileHandler implements HttpHandler { response.status = HttpStatus.NotFound; return; } - + String extension = getExtension(path); String mimeType = getMimeTypeFromExtension(extension); - + response.fields.put(HttpField.ContentType, mimeType); response.status = HttpStatus.OK; OutputStream out = response.getBody(); diff --git a/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java b/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java index 9ad5a3dc..fa630c37 100644 --- a/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java +++ b/src/main/java/org/dynmap/web/handlers/FilesystemHandler.java @@ -32,4 +32,4 @@ public class FilesystemHandler extends FileHandler { } return null; } -} \ No newline at end of file +} diff --git a/src/main/java/org/dynmap/web/handlers/JarFileHandler.java b/src/main/java/org/dynmap/web/handlers/JarFileHandler.java index abcb8e56..c822fa59 100644 --- a/src/main/java/org/dynmap/web/handlers/JarFileHandler.java +++ b/src/main/java/org/dynmap/web/handlers/JarFileHandler.java @@ -16,4 +16,4 @@ public class JarFileHandler extends FileHandler { protected InputStream getFileInput(String path, HttpRequest request, HttpResponse response) { return this.getClass().getResourceAsStream(root + "/" + path); } -} \ No newline at end of file +} diff --git a/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java b/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java index 5f7d257a..6c6294fd 100644 --- a/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java +++ b/src/main/java/org/dynmap/web/handlers/SendMessageHandler.java @@ -17,16 +17,16 @@ import org.json.simple.parser.JSONParser; public class SendMessageHandler implements HttpHandler { protected static final Logger log = Logger.getLogger("Minecraft"); - + private static final JSONParser parser = new JSONParser(); public Event onMessageReceived = new Event(); - + public int maximumMessageInterval = 1000; public String spamMessage = "\"You may only chat once every %interval% seconds.\""; private HashMap disallowedUsers = new HashMap(); private LinkedList disallowedUserQueue = new LinkedList(); private Object disallowedUsersLock = new Object(); - + @Override public void handle(String path, HttpRequest request, HttpResponse response) throws Exception { if (!request.method.equals(HttpMethod.Post)) { @@ -36,14 +36,14 @@ public class SendMessageHandler implements HttpHandler { } InputStreamReader reader = new InputStreamReader(request.body); - + JSONObject o = (JSONObject)parser.parse(reader); final Message message = new Message(); message.name = String.valueOf(o.get("name")); message.message = String.valueOf(o.get("message")); final long now = System.currentTimeMillis(); - + synchronized(disallowedUsersLock) { // Allow users that user that are now allowed to send messages. while (!disallowedUserQueue.isEmpty()) { @@ -55,7 +55,7 @@ public class SendMessageHandler implements HttpHandler { break; } } - + WebUser user = disallowedUsers.get(message.name); if (user == null) { user = new WebUser() {{ @@ -71,14 +71,14 @@ public class SendMessageHandler implements HttpHandler { return; } } - + onMessageReceived.trigger(message); - + response.fields.put(HttpField.ContentLength, "0"); response.status = HttpStatus.OK; response.getBody(); } - + public static class Message { public String name; public String message;