Transfered client-updates to two components (jsonfile and internal).

This commit is contained in:
FrozenCow 2011-05-21 02:01:26 +02:00
parent 9fa46597d1
commit d5b4f6c8c4
11 changed files with 271 additions and 245 deletions

View File

@ -2,6 +2,13 @@
components:
- class: org.dynmap.ClientConfigurationComponent
- class: org.dynmap.InternalClientUpdateComponent
sendhealth: true
#- class: org.dynmap.JsonFileClientUpdateComponent
# sendhealth: true
# interval: 1
- class: org.dynmap.SimpleWebChatComponent
#- class: org.dynmap.herochat.HeroWebChatComponent
# # Control which HeroChat channel messages from web are directed to
@ -11,6 +18,7 @@ components:
# - Global
# #- Trade
# #- Haggle
- class: org.dynmap.ClientComponent
type: chat
- class: org.dynmap.ClientComponent
@ -23,7 +31,7 @@ components:
- class: org.dynmap.ClientComponent
type: playermarkers
showplayerfaces: true
showplayerhealth: false
showplayerhealth: true
#- class: org.dynmap.ClientComponent
# type: digitalclock
- class: org.dynmap.ClientComponent

View File

@ -1,41 +1,29 @@
package org.dynmap;
import java.io.IOException;
import java.io.Writer;
import org.bukkit.ChatColor;
import org.json.simple.JSONAware;
import org.json.simple.JSONStreamAware;
public class Client {
public static class Update {
public long timestamp;
public long servertime;
public boolean hasStorm;
public boolean isThundering;
public Player[] players;
public Object[] updates;
}
public static class Player {
public String type = "player";
public String name;
public String world;
public double x, y, z;
public int health;
public String account;
public Player(String name, String world, double x, double y, double z, int health, String account) {
this.name = ChatColor.stripColor(name);
this.world = world;
this.x = x;
this.y = y;
this.z = z;
this.health = health;
this.account = account;
}
}
public static class Stamped {
public static class Update implements JSONAware, JSONStreamAware {
public long timestamp = System.currentTimeMillis();
@Override
public String toJSONString() {
return org.dynmap.web.Json.stringifyJson(this);
}
public static class ChatMessage extends Stamped {
@Override
public void writeJSONString(Writer w) throws IOException {
// TODO: This isn't the best...
w.write(toJSONString());
}
}
public static class ChatMessage extends Update {
public String type = "chat";
public String source;
public String playerName;
@ -51,7 +39,7 @@ public class Client {
}
}
public static class PlayerJoinMessage extends Stamped {
public static class PlayerJoinMessage extends Update {
public String type = "playerjoin";
public String playerName;
public String account;
@ -61,7 +49,7 @@ public class Client {
}
}
public static class PlayerQuitMessage extends Stamped {
public static class PlayerQuitMessage extends Update {
public String type = "playerquit";
public String playerName;
public String account;
@ -71,7 +59,7 @@ public class Client {
}
}
public static class Tile extends Stamped {
public static class Tile extends Update {
public String type = "tile";
public String name;

View File

@ -0,0 +1,58 @@
package org.dynmap;
import static org.dynmap.JSONUtils.a;
import static org.dynmap.JSONUtils.s;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
public class ClientUpdateComponent extends Component {
public ClientUpdateComponent(final DynmapPlugin plugin, ConfigurationNode configuration) {
super(plugin, configuration);
plugin.events.addListener("buildclientupdate", new Event.Listener<ClientUpdateEvent>() {
@Override
public void triggered(ClientUpdateEvent e) {
buildClientUpdate(e);
}
});
}
protected void buildClientUpdate(ClientUpdateEvent e) {
World world = e.world.world;
JSONObject u = e.update;
long since = e.timestamp;
String worldName = world.getName();
s(u, "servertime", world.getTime() % 24000);
s(u, "hasStorm", world.hasStorm());
s(u, "isThundering", world.isThundering());
s(u, "players", new JSONArray());
Player[] players = plugin.playerList.getVisiblePlayers();
for(int i=0;i<players.length;i++) {
Player p = players[i];
Location pl = p.getLocation();
JSONObject jp = new JSONObject();
s(jp, "type", "player");
s(jp, "name", p.getDisplayName());
s(jp, "account", p.getName());
s(jp, "world", p.getWorld().getName());
s(jp, "x", pl.getX());
s(jp, "y", pl.getY());
s(jp, "z", pl.getZ());
if (configuration.getBoolean("sendhealth", false)) {
s(jp, "health", p.getHealth());
}
a(u, "players", jp);
}
s(u, "updates", new JSONArray());
for(Object update : plugin.mapManager.getWorldUpdates(worldName, since)) {
a(u, "updates", (Client.Update)update);
}
}
}

View File

@ -0,0 +1,15 @@
package org.dynmap;
import org.json.simple.JSONObject;
public class ClientUpdateEvent {
public long timestamp;
public DynmapWorld world;
public JSONObject update;
public ClientUpdateEvent(long timestamp, DynmapWorld world, JSONObject update) {
this.timestamp = timestamp;
this.world = world;
this.update = update;
}
}

View File

@ -94,16 +94,7 @@ public class DynmapPlugin extends JavaPlugin {
mapManager = new MapManager(this, configuration);
mapManager.startRendering();
if (!configuration.getBoolean("disable-webserver", false)) {
loadWebserver();
}
if (configuration.getBoolean("jsonfile", false)) {
jsonConfig();
int jsonInterval = configuration.getInteger("jsonfile-interval", 1) * 1000;
timer = new Timer();
timer.scheduleAtFixedRate(new JsonTimerTask(this, configuration), jsonInterval, jsonInterval);
}
enabledTriggers.clear();
List<String> triggers = configuration.getStrings("render-triggers", new ArrayList<String>());
@ -121,11 +112,15 @@ public class DynmapPlugin extends JavaPlugin {
registerEvents();
if (!configuration.getBoolean("disable-webserver", false)) {
startWebserver();
}
/* Print version info */
PluginDescriptionFile pdfFile = this.getDescription();
Log.info("version " + pdfFile.getVersion() + " is enabled" );
events.<Object>trigger("initialized", null);
}
public void loadWebserver() {
@ -145,7 +140,6 @@ public class DynmapPlugin extends JavaPlugin {
webServer = new HttpServer(bindAddress, port);
webServer.handlers.put("/", new FilesystemHandler(getFile(configuration.getString("webpath", "web"))));
webServer.handlers.put("/tiles/", new FilesystemHandler(tilesDirectory));
webServer.handlers.put("/up/", new ClientUpdateHandler(this, configuration.getBoolean("health-in-json", false)));
webServer.handlers.put("/up/configuration", new ClientConfigurationHandler(this));
if (configuration.getBoolean("allowwebchat", false)) {
@ -388,27 +382,6 @@ public class DynmapPlugin extends JavaPlugin {
return true;
}
private void jsonConfig() {
File outputFile;
JSONObject clientConfiguration = new JSONObject();
events.trigger("buildclientconfiguration", clientConfiguration);
File webpath = new File(configuration.getString("webpath", "web"), "standalone/dynmap_config.json");
if (webpath.isAbsolute())
outputFile = webpath;
else
outputFile = new File(getDataFolder(), webpath.toString());
try {
FileOutputStream fos = new FileOutputStream(outputFile);
fos.write(clientConfiguration.toJSONString().getBytes());
fos.close();
} catch (FileNotFoundException ex) {
Log.severe("Exception while writing JSON-configuration-file.", ex);
} catch (IOException ioe) {
Log.severe("Exception while writing JSON-configuration-file.", ioe);
}
}
public void webChat(String name, String message) {
mapManager.pushUpdate(new Client.ChatMessage("web", null, name, message, null));
Log.info("[WEB]" + name + ": " + message);

View File

@ -0,0 +1,12 @@
package org.dynmap;
import org.dynmap.web.handlers.ClientUpdateHandler;
public class InternalClientUpdateComponent extends ClientUpdateComponent {
public InternalClientUpdateComponent(DynmapPlugin plugin, ConfigurationNode configuration) {
super(plugin, configuration);
plugin.webServer.handlers.put("/up/", new ClientUpdateHandler(plugin));
}
}

View File

@ -0,0 +1,141 @@
package org.dynmap;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.dynmap.web.Json;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import static org.dynmap.JSONUtils.*;
public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
protected TimerTask task;
protected Timer timer;
protected long jsonInterval;
protected long lastTimestamp = 0;
protected JSONParser parser = new JSONParser();
public JsonFileClientUpdateComponent(final DynmapPlugin plugin, ConfigurationNode configuration) {
super(plugin, configuration);
jsonInterval = (long)(configuration.getFloat("interval", 1) * 1000);
task = new TimerTask() {
@Override
public void run() {
writeUpdates();
}
};
timer = new Timer();
timer.scheduleAtFixedRate(task, jsonInterval, jsonInterval);
plugin.events.addListener("buildclientconfiguration", new Event.Listener<JSONObject>() {
@Override
public void triggered(JSONObject t) {
s(t, "jsonfile", true);
}
});
plugin.events.addListener("initialized", new Event.Listener<Object>() {
@Override
public void triggered(Object t) {
writeConfiguration();
}
});
}
protected void writeConfiguration() {
File outputFile;
JSONObject clientConfiguration = new JSONObject();
plugin.events.trigger("buildclientconfiguration", clientConfiguration);
File webpath = new File(plugin.configuration.getString("webpath", "web"), "standalone/dynmap_config.json");
if (webpath.isAbsolute())
outputFile = webpath;
else
outputFile = new File(plugin.getDataFolder(), webpath.toString());
try {
FileOutputStream fos = new FileOutputStream(outputFile);
fos.write(clientConfiguration.toJSONString().getBytes());
fos.close();
} catch (FileNotFoundException ex) {
Log.severe("Exception while writing JSON-configuration-file.", ex);
} catch (IOException ioe) {
Log.severe("Exception while writing JSON-configuration-file.", ioe);
}
}
protected void writeUpdates() {
long current = System.currentTimeMillis();
File outputFile;
//Handles Updates
for (DynmapWorld dynmapWorld : plugin.mapManager.worlds.values()) {
World world = dynmapWorld.world;
current = System.currentTimeMillis();
JSONObject update = new JSONObject();
update.put("timestamp", current);
ClientUpdateEvent clientUpdate = new ClientUpdateEvent(current, dynmapWorld, update);
plugin.events.trigger("buildclientupdate", clientUpdate);
File webWorldPath = new File(this.configuration.getString("webpath", "web"), "standalone/dynmap_" + world.getName() + ".json");
if (webWorldPath.isAbsolute())
outputFile = webWorldPath;
else {
outputFile = new File(plugin.getDataFolder(), webWorldPath.toString());
}
try {
FileOutputStream fos = new FileOutputStream(outputFile);
fos.write(Json.stringifyJson(update).getBytes());
fos.close();
} catch (FileNotFoundException ex) {
Log.severe("Exception while writing JSON-file.", ex);
} catch (IOException ioe) {
Log.severe("Exception while writing JSON-file.", ioe);
}
plugin.events.<ClientUpdateEvent>trigger("clientupdatewritten", clientUpdate);
}
lastTimestamp = System.currentTimeMillis();
plugin.events.<Object>trigger("clientupdateswritten", null);
}
protected void handleWebChat() {
File webPath = new File(configuration.getString("webpath", "web"));
if (!webPath.isAbsolute()) {
webPath = new File(plugin.getDataFolder(), webPath.toString());
}
File webchatFile = new File(webPath, "standalone/dynmap_webchat.json");
if (webchatFile.exists() && lastTimestamp != 0) {
JSONArray jsonMsgs = null;
try {
FileReader inputFileReader = new FileReader(webchatFile);
jsonMsgs = (JSONArray) parser.parse(inputFileReader);
inputFileReader.close();
} catch (IOException ex) {
Log.severe("Exception while reading JSON-file.", ex);
} catch (ParseException ex) {
Log.severe("Exception while parsing JSON-file.", ex);
}
if (jsonMsgs != null) {
Iterator<?> iter = jsonMsgs.iterator();
while (iter.hasNext()) {
JSONObject o = (JSONObject) iter.next();
if (Long.parseLong(String.valueOf(o.get("timestamp"))) >= (lastTimestamp)) {
plugin.webChat(String.valueOf(o.get("name")), String.valueOf(o.get("message")));
}
}
}
}
}
}

View File

@ -1,123 +0,0 @@
package org.dynmap;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.TimerTask;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.dynmap.web.Json;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
class JsonTimerTask extends TimerTask {
private final DynmapPlugin plugin;
private Server server;
private MapManager mapManager;
private ConfigurationNode configuration;
private ConfigurationNode regions;
private static final JSONParser parser = new JSONParser();
private long lastTimestamp = 0;
public JsonTimerTask(DynmapPlugin instance, ConfigurationNode config) {
this.plugin = instance;
this.server = this.plugin.getServer();
this.mapManager = this.plugin.getMapManager();
this.configuration = config;
}
public void run() {
long jsonInterval = configuration.getInteger("jsonfile-interval", 1) * 1000;
long current = System.currentTimeMillis();
File outputFile;
boolean showHealth = configuration.getBoolean("health-in-json", false);
//Handles Reading WebChat
if (configuration.getNode("web").getBoolean("allowwebchat", false)) {
File webChatPath = new File(this.configuration.getString("webpath", "web"), "standalone/dynmap_webchat.json");
if (webChatPath.isAbsolute())
outputFile = webChatPath;
else {
outputFile = new File(plugin.getDataFolder(), webChatPath.toString());
}
if (webChatPath.exists() && lastTimestamp != 0) {
JSONArray jsonMsgs = null;
try {
FileReader inputFileReader = new FileReader(webChatPath);
jsonMsgs = (JSONArray) parser.parse(inputFileReader);
inputFileReader.close();
} catch (IOException ex) {
Log.severe("Exception while reading JSON-file.", ex);
} catch (ParseException ex) {
Log.severe("Exception while parsing JSON-file.", ex);
}
if (jsonMsgs != null) {
Iterator<?> iter = jsonMsgs.iterator();
while (iter.hasNext()) {
JSONObject o = (JSONObject) iter.next();
if (Long.parseLong(String.valueOf(o.get("timestamp"))) >= (lastTimestamp)) {
plugin.webChat(String.valueOf(o.get("name")), String.valueOf(o.get("message")));
}
}
}
}
}
//Handles Updates
for (DynmapWorld dynmapWorld : plugin.mapManager.worlds.values()) {
World world = dynmapWorld.world;
current = System.currentTimeMillis();
Client.Update update = new Client.Update();
WorldUpdate worldUpdate = new WorldUpdate(dynmapWorld, update);
plugin.events.trigger("buildingupdate", worldUpdate);
update.timestamp = current;
update.servertime = world.getTime() % 24000;
update.hasStorm = world.hasStorm();
update.isThundering = world.isThundering();
Player[] players = plugin.playerList.getVisiblePlayers();
update.players = new Client.Player[players.length];
for (int i = 0; i < players.length; i++) {
Player p = players[i];
Location pl = p.getLocation();
update.players[i] = new Client.Player(p.getDisplayName(), pl.getWorld().getName(), pl.getX(), pl.getY(), pl.getZ(), showHealth?p.getHealth():-1,
p.getName());
}
update.updates = mapManager.getWorldUpdates(world.getName(), current - (jsonInterval + 10000));
plugin.events.trigger("buildupdate", worldUpdate);
File webWorldPath = new File(this.configuration.getString("webpath", "web"), "standalone/dynmap_" + world.getName() + ".json");
if (webWorldPath.isAbsolute())
outputFile = webWorldPath;
else {
outputFile = new File(plugin.getDataFolder(), webWorldPath.toString());
}
try {
FileOutputStream fos = new FileOutputStream(outputFile);
fos.write(Json.stringifyJson(update).getBytes());
fos.close();
} catch (FileNotFoundException ex) {
Log.severe("Exception while writing JSON-file.", ex);
} catch (IOException ioe) {
Log.severe("Exception while writing JSON-file.", ioe);
}
plugin.events.<Object>trigger("updatewritten", worldUpdate);
}
lastTimestamp = System.currentTimeMillis();
plugin.events.<Object>trigger("updateswritten", null);
}
}

View File

@ -1,11 +0,0 @@
package org.dynmap;
public class WorldUpdate {
public DynmapWorld world;
public Client.Update update;
public WorldUpdate(DynmapWorld world, Client.Update update) {
this.world = world;
this.update = update;
}
}

View File

@ -8,11 +8,11 @@ import java.util.Map;
import org.bukkit.World;
import org.dynmap.ClientComponent;
import org.dynmap.ClientUpdateEvent;
import org.dynmap.ConfigurationNode;
import org.dynmap.DynmapPlugin;
import org.dynmap.Event;
import org.dynmap.Log;
import org.dynmap.WorldUpdate;
import org.dynmap.web.Json;
public class RegionsComponent extends ClientComponent {
@ -27,15 +27,15 @@ public class RegionsComponent extends ClientComponent {
// For external webserver.
//Parse region file for multi world style
if (configuration.getBoolean("useworldpath", false)) {
plugin.events.addListener("updatewritten", new Event.Listener<WorldUpdate>() {
plugin.events.addListener("clientupdatewritten", new Event.Listener<ClientUpdateEvent>() {
@Override
public void triggered(WorldUpdate t) {
public void triggered(ClientUpdateEvent t) {
World world = t.world.world;
parseRegionFile(world.getName() + "/" + configuration.getString("filename", "regions.yml"), configuration.getString("filename", "regions.yml").replace(".", "_" + world.getName() + ".yml"));
}
});
} else {
plugin.events.addListener("updateswritten", new Event.Listener<Object>() {
plugin.events.addListener("clientupdateswritten", new Event.Listener<Object>() {
@Override
public void triggered(Object t) {
parseRegionFile(configuration.getString("filename", "regions.yml"), configuration.getString("filename", "regions.yml"));

View File

@ -11,7 +11,9 @@ import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.util.config.Configuration;
import org.dynmap.Client;
import org.dynmap.ClientUpdateEvent;
import org.dynmap.DynmapPlugin;
import org.dynmap.DynmapWorld;
import org.dynmap.MapManager;
import org.dynmap.PlayerList;
import org.dynmap.web.HttpField;
@ -26,11 +28,9 @@ import static org.dynmap.JSONUtils.*;
public class ClientUpdateHandler implements HttpHandler {
private DynmapPlugin plugin;
private boolean showHealth;
public ClientUpdateHandler(DynmapPlugin plugin, boolean showHealth) {
public ClientUpdateHandler(DynmapPlugin plugin) {
this.plugin = plugin;
this.showHealth = showHealth;
}
Pattern updatePathPattern = Pattern.compile("world/([^/]+)/([0-9]*)");
@ -48,12 +48,11 @@ public class ClientUpdateHandler implements HttpHandler {
String worldName = match.group(1);
String timeKey = match.group(2);
World world = plugin.getServer().getWorld(worldName);
if (world == null) {
DynmapWorld dynmapWorld = plugin.mapManager.getWorld(worldName);
if (dynmapWorld == null || dynmapWorld.world == null) {
response.status = WorldNotFound;
return;
}
long current = System.currentTimeMillis();
long since = 0;
@ -65,42 +64,8 @@ public class ClientUpdateHandler implements HttpHandler {
}
JSONObject u = new JSONObject();
//plugin.events.trigger("buildclientupdate", update);
s(u, "timestamp", current);
s(u, "servertime", world.getTime() % 24000);
s(u, "hasStorm", world.hasStorm());
s(u, "isThundering", world.isThundering());
s(u, "players", new JSONArray());
Player[] players = plugin.playerList.getVisiblePlayers();
for(int i=0;i<players.length;i++) {
Player p = players[i];
Location pl = p.getLocation();
JSONObject jp = new JSONObject();
s(jp, "type", "player");
s(jp, "name", p.getDisplayName());
s(jp, "account", p.getName());
s(jp, "world", p.getWorld().getName());
s(jp, "x", pl.getX());
s(jp, "y", pl.getY());
s(jp, "z", pl.getZ());
if (showHealth) {
s(jp, "health", p.getHealth());
}
a(u, "players", jp);
}
s(u, "updates", new JSONArray());
for(Object update : plugin.mapManager.getWorldUpdates(worldName, since)) {
if (update instanceof Client.Tile) {
Client.Tile tile = (Client.Tile)update;
JSONObject t = new JSONObject();
s(t, "type", "tile");
s(t, "timestamp", tile.timestamp);
s(t, "name", tile.name);
a(u, "updates", t);
}
}
plugin.events.trigger("buildclientupdate", new ClientUpdateEvent(since, dynmapWorld, u));
byte[] bytes = u.toJSONString().getBytes();