diff --git a/src/main/java/org/dynmap/DynmapBlockListener.java b/src/main/java/org/dynmap/DynmapBlockListener.java new file mode 100644 index 00000000..829ebf8f --- /dev/null +++ b/src/main/java/org/dynmap/DynmapBlockListener.java @@ -0,0 +1,24 @@ +package org.dynmap; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.logging.Logger; +import org.bukkit.*; +import org.bukkit.event.block.*; + +public class DynmapBlockListener extends BlockListener { + private static final Logger log = Logger.getLogger("Minecraft"); + private MapManager mgr; + + public DynmapBlockListener(MapManager mgr) { + this.mgr = mgr; + } + + @Override + public void onBlockPlaced(BlockPlacedEvent event) { + Block blockPlaced = event.getBlock(); + if(mgr.touch(blockPlaced.getX(), blockPlaced.getY(), blockPlaced.getZ())) + mgr.debug(/*player.getName() + */" touch " + blockPlaced.getX() + "," + blockPlaced.getY() + "," + blockPlaced.getZ() + " from onBlockCreate"); + } +} diff --git a/src/main/java/org/dynmap/map.java b/src/main/java/org/dynmap/DynmapPlugin.java similarity index 84% rename from src/main/java/org/dynmap/map.java rename to src/main/java/org/dynmap/DynmapPlugin.java index 6942f649..d126fb04 100644 --- a/src/main/java/org/dynmap/map.java +++ b/src/main/java/org/dynmap/DynmapPlugin.java @@ -9,16 +9,19 @@ import org.bukkit.event.*; import org.bukkit.event.Event.Priority; import org.bukkit.plugin.*; import org.bukkit.plugin.java.*; +import org.dynmap.debug.BukkitPlayerDebugger; -public class map extends JavaPlugin { +public class DynmapPlugin extends JavaPlugin { protected static final Logger log = Logger.getLogger("Minecraft"); private WebServer server = null; private MapManager mgr = null; - private MapListener listener = null; + private DynmapBlockListener listener = null; + + private BukkitPlayerDebugger debugger = new BukkitPlayerDebugger(this); - public map(PluginLoader pluginLoader, Server instance, PluginDescriptionFile desc, File plugin, ClassLoader cLoader) { + public DynmapPlugin(PluginLoader pluginLoader, Server instance, PluginDescriptionFile desc, File plugin, ClassLoader cLoader) { super(pluginLoader, instance, desc, plugin, cLoader); } @@ -30,7 +33,7 @@ public class map extends JavaPlugin { public void onEnable() { log.info("Map INIT"); - mgr = new MapManager(this); + mgr = new MapManager(getWorld(), debugger); mgr.startManager(); try { @@ -39,7 +42,7 @@ public class map extends JavaPlugin { log.info("position failed to start WebServer (IOException)"); } - listener = new MapListener(mgr); + listener = new DynmapBlockListener(mgr); registerEvents(); } @@ -73,5 +76,6 @@ public class map extends JavaPlugin { etc.getInstance().addCommand("/removesign", " [name] - removes a named sign to the map"); etc.getInstance().addCommand("/listsigns", " - list all named signs"); etc.getInstance().addCommand("/tpsign", " [name] - teleport to a named sign");*/ + } } diff --git a/src/main/java/org/dynmap/MapListener.java b/src/main/java/org/dynmap/MapListener.java deleted file mode 100644 index 694d2e6b..00000000 --- a/src/main/java/org/dynmap/MapListener.java +++ /dev/null @@ -1,163 +0,0 @@ -package org.dynmap; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.logging.Logger; -import org.bukkit.*; -import org.bukkit.event.block.*; - -public class MapListener extends BlockListener { - private static final Logger log = Logger.getLogger("Minecraft"); - private MapManager mgr; - - public MapListener(MapManager mgr) - { - this.mgr = mgr; - } - - @Override - public void onBlockPlaced(BlockPlacedEvent event) { - Block blockPlaced = event.getBlock(); - if(mgr.touch(blockPlaced.getX(), blockPlaced.getY(), blockPlaced.getZ())) - mgr.debug(/*player.getName() + */" touch " + blockPlaced.getX() + "," + blockPlaced.getY() + "," + blockPlaced.getZ() + " from onBlockCreate"); - } - -/* - @Override - public boolean onBlockCreate(Player player, Block blockPlaced, Block blockClicked, int itemInHand) - { - if(mgr.touch(blockPlaced.getX(), blockPlaced.getY(), blockPlaced.getZ())) - mgr.debug(player.getName() + " touch " + blockPlaced.getX() + "," + blockPlaced.getY() + "," + blockPlaced.getZ() + " from onBlockCreate"); - return false; - } - - @Override - public boolean onBlockDestroy(Player player, Block block) - { - int x = block.getX(); - int y = block.getY(); - int z = block.getZ(); - if(x == 0 && y == 0 && z == 0) - return false; - - if(mgr.touch(x, y, z)) - mgr.debug(player.getName() + " touch " + x + "," + y + "," + z + " from onBlockBreak"); - - return false; - } - - @Override - public void onLogin(Player player) - { - mgr.getPlayerImage(player); - } - - @Override - public boolean onCommand(Player player, String[] split) - { - if(!player.canUseCommand(split[0])) - return false; - - if(split[0].equals("/map_wait")) { - if(split.length < 2) { - mgr.renderWait = 1000; - } else { - try { - mgr.renderWait = Integer.parseInt(split[1]); - } catch(NumberFormatException e) { - player.sendMessage(Colors.Rose + "Invalid number"); - } - } - return true; - } - - if(split[0].equals("/map_regen")) { - mgr.regenerate((int) player.getX(), (int) player.getY(), (int) player.getZ()); - player.sendMessage(Colors.Rose + "Map regeneration in progress"); - return true; - } - - if(split[0].equals("/map_stat")) { - player.sendMessage(Colors.Rose + "Stale tiles: " + mgr.getStaleCount() + " Recent updates: " + mgr.getRecentUpdateCount()); - return true; - } - - if(split[0].equals("/map_debug")) { - mgr.debugPlayer = player.getName(); - return true; - } - - if(split[0].equals("/map_nodebug")) { - mgr.debugPlayer = null; - return true; - } - - if(split[0].equals("/addsign")) { - if(split.length < 2) - { - player.sendMessage("Map> " + Colors.Red + "Usage: /addsign [name]"); - } - else - { - if (mgr.addSign(player, split[1], player.getX(), player.getY(), player.getZ())) - { - player.sendMessage("Map> " + Colors.White + "Sign \"" + split[1] + "\" added successfully"); - } - } - return true; - } - - if(split[0].equals("/removesign")) { - if(split.length < 2) - { - player.sendMessage("Map> " + Colors.Red + "Usage: /removesign [name]"); - } - else - { - if (mgr.removeSign(player, split[1])) - { - player.sendMessage("Map> " + Colors.White + "Sign \"" + split[1] + "\" removed successfully"); - } - } - return true; - } - - if(split[0].equals("/listsigns")) { - String msg = ""; - Collection values = mgr.signs.values(); - Iterator it = values.iterator(); - while(it.hasNext()) - { - Warp sign = it.next(); - String line = " - " + sign.Name + "\t"; - msg += line; - } - player.sendMessage("" + Colors.White + msg); - return true; - } - - if(split[0].equals("/tpsign")) { - if(split.length < 2) - { - player.sendMessage("Map> " + Colors.Red + "Usage: /tpsign [name]"); - } - else - { - if (mgr.teleportToSign(player, split[1])) - { - //player.sendMessage("Map> " + Colors.White + ""); - } - } - return true; - } - - if(split[0].equals("/map_regenzoom")) { - mgr.regenerateZoom((int) player.getX(), (int) player.getY(), (int) player.getZ()); - player.sendMessage(Colors.Rose + "regenerateZoom done"); - return true; - } - - return false; - }*/ -} diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java index c4bad9b1..f3608e53 100644 --- a/src/main/java/org/dynmap/MapManager.java +++ b/src/main/java/org/dynmap/MapManager.java @@ -33,13 +33,15 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.bukkit.*; +import org.dynmap.debug.Debugger; import javax.imageio.ImageIO; public class MapManager extends Thread { protected static final Logger log = Logger.getLogger("Minecraft"); - public map etc; + private World world; + private Debugger debugger; /* dimensions of a map tile */ public static final int tileWidth = 128; @@ -106,62 +108,21 @@ public class MapManager extends Thread { /* zoomed-out tile cache */ public Cache zoomCache; - - /* data source */ - public String datasource = "flatfile"; - - /* which markers to show (spawn,homes,warps,signs,players,all,none) */ - public String showmarkers = "all"; - - /* booleans designating what to show on the map */ - public Boolean showSpawn = false; - public Boolean showHomes = false; - public Boolean showWarps = false; - public Boolean showSigns = false; - public Boolean showPlayers = false; - public Boolean generatePortraits = false; public void debug(String msg) { - if(debugPlayer == null) return; - Server s = etc.getServer(); - Player p = s.getPlayer(debugPlayer); - if(p == null) return; - p.sendMessage("Map> " + Color.RED + msg); + debugger.debug(msg); } - public MapManager(map plugin) + public MapManager(World world, Debugger debugger) { - etc = plugin; - /* load configuration */ - /*PropertiesFile properties; + this.world = world; + this.debugger = debugger; - properties = new PropertiesFile("server.properties"); - try { - tilepath = properties.getString("map-tilepath", "tiles/"); - colorsetpath = properties.getString("map-colorsetpath", "colors.txt"); - signspath = properties.getString("map-signspath", "signs.txt"); - serverport = Integer.parseInt(properties.getString("map-serverport", "8123")); - datasource = properties.getString("data-source", "flatfile"); - showmarkers = properties.getString("map-showmarkers", "all"); - generatePortraits = !properties.getString("map-generateportraits", "0").equals("0"); - } catch(Exception ex) { - log.log(Level.SEVERE, "Exception while reading properties for dynamic map", ex); - }*/ tilepath = "/srv/http/dynmap/tiles/"; colorsetpath = "colors.txt"; signspath = "signs.txt"; serverport = 8123; - datasource = "flatfile"; - showmarkers = "all"; - { - showSpawn = true; - showHomes = true; - showWarps = true; - showSigns = true; - showPlayers = true; - } - generatePortraits = false; tileStore = new HashMap(); staleTiles = new LinkedList(); @@ -169,10 +130,6 @@ public class MapManager extends Thread { tileUpdates = new LinkedList(); caveTileUpdates = new LinkedList(); zoomCache = new Cache(zoomCacheSize); - -// signs = new HashMap(); - -// loadShowOptions(); } /* tile X for position x */ @@ -219,8 +176,6 @@ public class MapManager extends Thread { /* load colorset */ File cfile = new File(colorsetpath); - - //loadSigns(); try { Scanner scanner = new Scanner(cfile); @@ -463,7 +418,7 @@ public class MapManager extends Thread { if(t == null) { /* no maptile exists, need to create one */ - t = new MapTile(etc, px, py, ztilex(px), ztiley(py)); + t = new MapTile(world, px, py, ztilex(px), ztiley(py)); tileStore.put(key, t); return t; } else { @@ -505,13 +460,10 @@ public class MapManager extends Thread { Vector open = new Vector(); open.add(first); - Server s = etc.getServer(); - World w = etc.getWorld(); - while(open.size() > 0) { MapTile t = open.remove(open.size() - 1); if(t.stale) continue; - int h = w.getHighestBlockYAt(t.mx, t.mz); + int h = world.getHighestBlockYAt(t.mx, t.mz); log.info("walking: " + t.mx + ", " + t.mz + ", h = " + h); if(h < 1) @@ -671,296 +623,4 @@ public class MapManager extends Thread { return good; } - - /* adds a sign to the map */ -/* public boolean addSign(Player player, String name, double px, double py, double pz) - { - if (signs.containsKey(name)) - { - player.sendMessage("Map> " + Colors.Red + "Sign \"" + name + "\" already exists."); - return false; - } - - Warp sign = new Warp(); - sign.Name = name; - sign.Location = new Location(px,py,pz); - signs.put(name, sign); - - try - { - saveSigns(); - return true; - } - catch(IOException e) - { - log.log(Level.SEVERE, "Failed to save signs.txt", e); - } - - return false; - }*/ - - /* removes a sign from the map */ -/* public boolean removeSign(Player player, String name) - { - if (signs.containsKey(name)) - { - Warp sign = signs.get(name); - - signs.remove(name); - - try - { - saveSigns(); - return true; - } - catch(IOException e) - { - log.log(Level.SEVERE, "Failed to save signs.txt", e); - } - } - else - { - player.sendMessage("Map> " + Colors.Red + "Sign \"" + name + "\" does not exist."); - } - - return false; - }*/ - - /* teleports a user to a sign */ -/* public boolean teleportToSign(Player player, String name) - { - if (signs.containsKey(name)) - { - Warp sign = signs.get(name); - - player.teleportTo(sign.Location.x, sign.Location.y, sign.Location.z, 0, 0); - } - else - { - player.sendMessage("Map> " + Colors.Red + "Sign \"" + name + "\" does not exist."); - } - - return false; - }*/ - - /* load the map sign file */ -/* private void loadSigns() - { - Scanner scanner = null; - try - { - scanner = new Scanner(new FileInputStream(signspath), "UTF-8"); - while (scanner.hasNextLine()) - { - String line = scanner.nextLine(); - String[] values = line.split(":"); - String name = ""; - Double x = 0.0,y = 0.0,z = 0.0; - - // If user has old style of file (CSV) - if (values.length == 1) - { - values = line.split(","); - } - - // If user has old style of file (owners) - if (values.length == 5) - { - name = values[0]; - x = Double.parseDouble(values[2]); - y = Double.parseDouble(values[3]); - z = Double.parseDouble(values[4]); - } - else if (values.length == 4) - { - name = values[0]; - x = Double.parseDouble(values[1]); - y = Double.parseDouble(values[2]); - z = Double.parseDouble(values[3]); - } - else - { - log.log(Level.INFO, "Failed to load sign: " + values[0]); - } - - // If a sign was loaded, add it to the hash - if (name.isEmpty() == false && x != 0.0 && y != 0.0 && z != 0.0) - { - Warp sign = new Warp(); - sign.Name = name; - sign.Location = new Location(x, y, z); - signs.put(sign.Name, sign); - } - } - } - catch(FileNotFoundException e) - { - // No need to log FileNotFoundException - } - finally - { - if (scanner != null) scanner.close(); - } - }*/ - - /* save the map sign file */ -/* private void saveSigns() throws IOException - { - Writer out = null; - try - { - out = new OutputStreamWriter(new FileOutputStream(signspath), "UTF-8"); - Collection values = signs.values(); - Iterator it = values.iterator(); - while(it.hasNext()) - { - Warp sign = it.next(); - String line = sign.Name + ":" + sign.Location.x + ":" + sign.Location.y + ":" + sign.Location.z + "\n"; - out.write(line); - } - } - catch(UnsupportedEncodingException e) - { - log.log(Level.SEVERE, "Unsupported encoding", e); - } - catch(FileNotFoundException e) - { - log.log(Level.SEVERE, "signs.txt not found", e); - } - finally - { - if (out != null) out.close(); - } - }*/ - - /* TODO: Is there a cleaner way to get warps/homes than using custom DataSource classes to expose the protected properties? */ - -/* protected List loadWarps() - { - List warps = null; - - if (datasource.equals("flatfile")) { - DMFlatFileSource ds = new DMFlatFileSource(); - ds.initialize(); - ds.loadWarps(); - warps = ds.getAllWarps(); - } - else if (datasource.equals("mysql")) { - DMMySQLSource ds = new DMMySQLSource(); - ds.initialize(); - ds.loadWarps(); - warps = ds.getAllWarps(); - } - - return warps; - } - - protected List loadHomes() - { - List homes = null; - - if (datasource.equals("flatfile")) { - DMFlatFileSource ds = new DMFlatFileSource(); - ds.initialize(); - ds.loadHomes(); - homes = ds.getAllHomes(); - } - else if (datasource.equals("mysql")) { - DMMySQLSource ds = new DMMySQLSource(); - ds.initialize(); - ds.loadHomes(); - homes = ds.getAllHomes(); - } - - return homes; - } - - private void loadShowOptions() - { - String[] values = showmarkers.split(","); - - for (int i = 0; i < values.length; i++) - { - String opt = values[i]; - - if (opt.equals("all")) - { - showSpawn = true; - showHomes = true; - showWarps = true; - showSigns = true; - showPlayers = true; - } - else if (opt.equals("none")) - { - showSpawn = false; - showHomes = false; - showWarps = false; - showSigns = false; - showPlayers = false; - } - else if (opt.equals("spawn")) - { - showSpawn = true; - } - else if (opt.equals("homes")) - { - showHomes = true; - } - else if (opt.equals("warps")) - { - showWarps = true; - } - else if (opt.equals("signs")) - { - showSigns = true; - } - else if (opt.equals("players")) - { - showPlayers = true; - } - } - } - - protected void getPlayerImage(Player player) - { - if (!generatePortraits) return; - String urlString = "http://www.minecraft.net/skin/" + player.getName() + ".png"; - String filename = tilepath + player.getName() + ".png"; - - if (downloadPlayerImage(urlString, filename) == false) { - downloadPlayerImage("http://www.minecraft.net/img/char.png", filename); - } - } - - private Boolean downloadPlayerImage(String urlString, String filename) - { - BufferedImage img = null; - Boolean success = false; - File out = null; - - try - { - img = ImageIO.read(new URL(urlString)); - out = new File(filename); - - BufferedImage imgCropped = img.getSubimage(8, 8, 8, 8); - BufferedImage imgResized = new BufferedImage(24, 24, BufferedImage.TYPE_INT_ARGB); - - Graphics2D g = imgResized.createGraphics(); - g.drawImage(imgCropped, 0, 0, 24, 24, null); - g.dispose(); - - ImageIO.write(imgResized, "png", out); - success = true; - } - catch(IOException e) { - //log.log(Level.INFO, "Failed to fetch player image " + filename, e); - } - catch(NullPointerException e) { - //log.log(Level.INFO, "Failed to fetch player image " + filename, e); - } - - return success; - }*/ } diff --git a/src/main/java/org/dynmap/MapTile.java b/src/main/java/org/dynmap/MapTile.java index 8bbfdf29..db346947 100644 --- a/src/main/java/org/dynmap/MapTile.java +++ b/src/main/java/org/dynmap/MapTile.java @@ -16,6 +16,8 @@ import org.bukkit.Server; public class MapTile { protected static final Logger log = Logger.getLogger("Minecraft"); + private World world; + /* projection position */ public int px, py; @@ -31,11 +33,10 @@ public class MapTile { /* whether the cave map of this tile needs to be updated */ boolean staleCave = false; - private map etc; /* create new MapTile */ - public MapTile(map etc, int px, int py, int zpx, int zpy) + public MapTile(World world, int px, int py, int zpx, int zpy) { - this.etc = etc; + this.world = world; this.px = px; this.py = py; this.zpx = zpx; @@ -56,12 +57,10 @@ public class MapTile { int z2 = mz + MapManager.tileWidth / 2 + 64; int x, z; - Server s = etc.getServer(); - World w = etc.getWorld(); for(x=x1; x warps = mgr.loadWarps(); - - if (warps != null) { - for(Warp warp : warps) { - sb.append(warp.Name + " warp " + warp.Location.getX() + " " + warp.Location.getY() + " " + warp.Location.getZ() + "\n"); - } - } - } - - if (mgr.showHomes) { - List homes = mgr.loadHomes(); - - if (homes != null) { - for(Warp warp : homes) { - sb.append(warp.Name + " home " + warp.Location.x + " " + warp.Location.y + " " + warp.Location.z + "\n"); - } - } - } - - if (mgr.showSpawn) { - Location spawnLocation = etc.getServer().getSpawnLocation(); - - sb.append("Spawn spawn " + spawnLocation.x + " " + spawnLocation.y + " " + spawnLocation.z + "\n"); - }*/ - synchronized(mgr.lock) { for(TileUpdate tu : mgr.tileUpdates) { if(tu.at >= cutoff) { diff --git a/src/main/java/org/dynmap/debug/BukkitPlayerDebugger.java b/src/main/java/org/dynmap/debug/BukkitPlayerDebugger.java new file mode 100644 index 00000000..4d71a85d --- /dev/null +++ b/src/main/java/org/dynmap/debug/BukkitPlayerDebugger.java @@ -0,0 +1,76 @@ +package org.dynmap.debug; + +import java.util.HashSet; + +import org.bukkit.Player; +import org.bukkit.event.Event; +import org.bukkit.event.Event.Priority; +import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.event.player.PlayerListener; +import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.java.JavaPlugin; + +public class BukkitPlayerDebugger implements Debugger { + private JavaPlugin plugin; + private HashSet debugees = new HashSet(); + private String debugCommand; + private String undebugCommand; + private String prepend; + + public BukkitPlayerDebugger(JavaPlugin plugin) { + this.plugin = plugin; + + PluginDescriptionFile pdfFile = plugin.getDescription(); + debugCommand = "/debug_" + pdfFile.getName(); + undebugCommand = "/undebug_" + pdfFile.getName(); + prepend = pdfFile.getName() + ": "; + } + + public void enable() { + plugin.getServer().getPluginManager().registerEvent(Event.Type.PLAYER_COMMAND, new CommandListener(), Priority.Normal, plugin); + plugin.getServer().getPluginManager().registerEvent(Event.Type.PLAYER_QUIT, new CommandListener(), Priority.Normal, plugin); + } + + public void disable() { + clearDebugees(); + } + + public void addDebugee(Player p) { + debugees.add(p); + } + + public void removeDebugee(Player p) { + debugees.remove(p); + } + + public void clearDebugees() { + debugees.clear(); + } + + public void debug(String message) { + for (Player p : debugees) { + p.sendMessage(prepend + message); + } + } + + protected class CommandListener extends PlayerListener { + @Override + public void onPlayerCommand(PlayerChatEvent event) { + String[] split = event.getMessage().split(" "); + Player player = event.getPlayer(); + if (split[0].equalsIgnoreCase(debugCommand)) { + addDebugee(player); + event.setCancelled(true); + } else if (split[0].equalsIgnoreCase(undebugCommand)) { + removeDebugee(player); + event.setCancelled(true); + } + } + + @Override + public void onPlayerQuit(PlayerEvent event) { + removeDebugee(event.getPlayer()); + } + } +} diff --git a/src/main/java/org/dynmap/debug/Debugger.java b/src/main/java/org/dynmap/debug/Debugger.java new file mode 100644 index 00000000..43f5cbe3 --- /dev/null +++ b/src/main/java/org/dynmap/debug/Debugger.java @@ -0,0 +1,5 @@ +package org.dynmap.debug; + +public interface Debugger { + void debug(String message); +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 434ec96a..245488a0 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,3 +1,3 @@ name: Dynamic Map -main: org.dynmap.map +main: org.dynmap.DynmapPlugin version: 0.1