From dd8a84165b77bc5f93aa2bb12c265cada4afaaa1 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sat, 3 Sep 2011 01:06:00 -0500 Subject: [PATCH] Add marker update/delete events for client --- src/main/java/org/dynmap/Client.java | 33 +++++++ src/main/java/org/dynmap/MapManager.java | 3 +- .../dynmap/markers/impl/MarkerAPIImpl.java | 98 +++++++++++++++++-- 3 files changed, 126 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/dynmap/Client.java b/src/main/java/org/dynmap/Client.java index dbf882fc..c227bb26 100644 --- a/src/main/java/org/dynmap/Client.java +++ b/src/main/java/org/dynmap/Client.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.io.Writer; import org.bukkit.ChatColor; +import org.dynmap.markers.Marker; +import org.dynmap.markers.MarkerSet; import org.json.simple.JSONAware; import org.json.simple.JSONStreamAware; @@ -77,4 +79,35 @@ public class Client { } } + public static class MarkerUpdate extends Update { + public String type = "marker"; + public int x, y, z; + public String id; + public String label; + public String icon; + public String set; + + public MarkerUpdate(Marker m, boolean deleted) { + this.id = m.getMarkerID(); + this.label = m.getLabel(); + this.x = m.getX(); + this.y = m.getY(); + this.z = m.getZ(); + this.set = m.getMarkerSet().getMarkerSetID(); + this.icon = m.getMarkerIcon().getMarkerIconID(); + if(deleted) type = "markerdeleted"; + } + } + + public static class MarkerSetUpdate extends Update { + public String type = "markerset"; + public String id; + public String label; + + public MarkerSetUpdate(MarkerSet markerset, boolean deleted) { + this.id = markerset.getMarkerSetID(); + this.label = markerset.getMarkerSetLabel(); + if(deleted) type = "markersetdeleted"; + } + } } diff --git a/src/main/java/org/dynmap/MapManager.java b/src/main/java/org/dynmap/MapManager.java index 42c3d851..d5dd3621 100644 --- a/src/main/java/org/dynmap/MapManager.java +++ b/src/main/java/org/dynmap/MapManager.java @@ -790,7 +790,8 @@ public class MapManager { public void pushUpdate(String worldName, Object update) { DynmapWorld world = getWorld(worldName); - world.updates.pushUpdate(update); + if(world != null) + world.updates.pushUpdate(update); } public Object[] getWorldUpdates(String worldName, long since) { diff --git a/src/main/java/org/dynmap/markers/impl/MarkerAPIImpl.java b/src/main/java/org/dynmap/markers/impl/MarkerAPIImpl.java index 677b7d8b..e002354d 100644 --- a/src/main/java/org/dynmap/markers/impl/MarkerAPIImpl.java +++ b/src/main/java/org/dynmap/markers/impl/MarkerAPIImpl.java @@ -2,6 +2,7 @@ package org.dynmap.markers.impl; import java.io.File; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -13,28 +14,37 @@ import java.util.Map; import java.util.Set; import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.util.config.Configuration; import org.bukkit.util.config.ConfigurationNode; +import org.dynmap.Client; +import org.dynmap.ClientUpdateEvent; import org.dynmap.DynmapPlugin; +import org.dynmap.DynmapWorld; +import org.dynmap.Event; import org.dynmap.Log; +import org.dynmap.MapManager; import org.dynmap.markers.Marker; import org.dynmap.markers.MarkerAPI; import org.dynmap.markers.MarkerIcon; import org.dynmap.markers.MarkerSet; +import org.dynmap.web.Json; /** * Implementation class for MarkerAPI - should not be called directly */ -public class MarkerAPIImpl implements MarkerAPI { +public class MarkerAPIImpl implements MarkerAPI, Event.Listener { private File markerpersist; private File markerdir; /* Local store for markers (internal) */ private File markertiledir; /* Marker directory for web server (under tiles) */ private HashMap markericons = new HashMap(); private HashMap markersets = new HashMap(); + private Server server; static MarkerAPIImpl api; /* Built-in icons */ @@ -54,9 +64,10 @@ public class MarkerAPIImpl implements MarkerAPI { */ public static MarkerAPI initializeMarkerAPI(DynmapPlugin plugin) { if(api != null) { - api.cleanup(); + api.cleanup(plugin); } api = new MarkerAPIImpl(); + api.server = plugin.getServer(); /* Initialize persistence file name */ api.markerpersist = new File(plugin.getDataFolder(), "markers.yml"); /* Load persistence */ @@ -84,6 +95,10 @@ public class MarkerAPIImpl implements MarkerAPI { for(MarkerIcon ico : api.getMarkerIcons()) { api.publishMarkerIcon(ico); } + /* Freshen files */ + api.freshenMarkerFiles(); + /* Add listener so we update marker files for other worlds as they become active */ + plugin.events.addListener("worldactivated", api); return api; } @@ -91,7 +106,9 @@ public class MarkerAPIImpl implements MarkerAPI { /** * Cleanup */ - private void cleanup() { + private void cleanup(DynmapPlugin plugin) { + plugin.events.removeListener("worldactivated", api); + for(MarkerIconImpl icn : markericons.values()) icn.cleanup(); markericons.clear(); @@ -225,7 +242,6 @@ public class MarkerAPIImpl implements MarkerAPI { */ static void saveMarkers() { if(api != null) { - Log.info("saveMarkers()"); Configuration conf = new Configuration(api.markerpersist); /* Make configuration object */ /* First, save icon definitions */ HashMap icons = new HashMap(); @@ -252,15 +268,23 @@ public class MarkerAPIImpl implements MarkerAPI { /* And write it out */ if(!conf.save()) Log.severe("Error writing markers - " + api.markerpersist.getPath()); + /* Refresh JSON files */ + api.freshenMarkerFiles(); + } + } + + private void freshenMarkerFiles() { + if(MapManager.mapman != null) { + for(DynmapWorld w : MapManager.mapman.worlds) { + writeMarkersFile(w.world.getName()); + } } } /** * Load persistence */ - private boolean loadMarkers() { - cleanup(); - + private boolean loadMarkers() { Configuration conf = new Configuration(api.markerpersist); /* Make configuration object */ conf.load(); /* Load persistence */ /* Get icons */ @@ -295,6 +319,12 @@ public class MarkerAPIImpl implements MarkerAPI { */ static void markerUpdated(MarkerImpl marker, MarkerUpdate update) { Log.info("markerUpdated(" + marker.getMarkerID() + "," + update + ")"); + /* Freshen marker file for the world for this marker */ + if(api != null) + api.writeMarkersFile(marker.getWorld()); + /* Enqueue client update */ + if(MapManager.mapman != null) + MapManager.mapman.pushUpdate(marker.getWorld(), new Client.MarkerUpdate(marker, update == MarkerUpdate.DELETED)); } /** * Signal marker set update @@ -303,6 +333,12 @@ public class MarkerAPIImpl implements MarkerAPI { */ static void markerSetUpdated(MarkerSetImpl markerset, MarkerUpdate update) { Log.info("markerSetUpdated(" + markerset.getMarkerSetID() + "," + update + ")"); + /* Freshen all marker files */ + if(api != null) + api.freshenMarkerFiles(); + /* Enqueue client update */ + if(MapManager.mapman != null) + MapManager.mapman.pushUpdate(new Client.MarkerSetUpdate(markerset, update == MarkerUpdate.DELETED)); } /** @@ -377,4 +413,52 @@ public class MarkerAPIImpl implements MarkerAPI { } return true; } + + /** + * Write markers file for given world + */ + public void writeMarkersFile(String wname) { + Map markerdata = new HashMap(); + + File f = new File(markertiledir, "marker_" + wname + ".json"); + + markerdata.put("timestamp", Long.valueOf(System.currentTimeMillis())); /* Add timestamp */ + + for(MarkerSet ms : markersets.values()) { + HashMap msdata = new HashMap(); + msdata.put("label", ms.getMarkerSetLabel()); + HashMap markers = new HashMap(); + for(Marker m : ms.getMarkers()) { + if(m.getWorld().equals(wname) == false) continue; + + HashMap mdata = new HashMap(); + mdata.put("x", m.getX()); + mdata.put("y", m.getY()); + mdata.put("z", m.getZ()); + mdata.put("icon", m.getMarkerIcon().getMarkerIconID()); + /* Add to markers */ + markers.put(m.getMarkerID(), mdata); + } + msdata.put("markers", markers); /* Add markers to set data */ + + markerdata.put(ms.getMarkerSetID(), msdata); /* Add marker set data to world marker data */ + } + FileOutputStream fos = null; + try { + fos = new FileOutputStream(f); + fos.write(Json.stringifyJson(markerdata).getBytes()); + } catch (FileNotFoundException ex) { + Log.severe("Exception while writing JSON-file.", ex); + } catch (IOException ioe) { + Log.severe("Exception while writing JSON-file.", ioe); + } finally { + if(fos != null) try { fos.close(); } catch (IOException x) {} + } + } + + @Override + public void triggered(DynmapWorld t) { + /* Update markers for now-active world */ + writeMarkersFile(t.world.getName()); + } }