mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-29 12:07:41 +01:00
Changed the way templates and world-configuration are handled.
This commit is contained in:
parent
de0ad58344
commit
108e9d24c4
@ -111,9 +111,10 @@ defaultworld: world
|
||||
# template world - this is used for worlds that exist but aren't defined in the worlds section.
|
||||
# Also, it supplies the "maps" section for worlds lacking a maps section, and the "center"
|
||||
# for worlds lacking a "center" section.
|
||||
template:
|
||||
templates:
|
||||
# Template for normal world
|
||||
normal:
|
||||
enabled: true
|
||||
center:
|
||||
x: 0
|
||||
y: 64
|
||||
@ -151,6 +152,7 @@ template:
|
||||
maximumheight: 127
|
||||
# Nether world template
|
||||
nether:
|
||||
enabled: true
|
||||
center:
|
||||
x: 0
|
||||
y: 64
|
||||
@ -169,18 +171,18 @@ template:
|
||||
prefix: nt
|
||||
maximumheight: 127
|
||||
colorscheme: default
|
||||
# This list of worlds will be hidden - they will not be automatically initialized by templates
|
||||
hiddenworlds:
|
||||
- MyHiddenWorld
|
||||
- AnotherHiddenWorld
|
||||
|
||||
# The maptypes Dynmap will use to render.
|
||||
worlds:
|
||||
# Worlds can be handled by templates, based on world type
|
||||
# To override, provide name and title here. Any other sections that are provided will
|
||||
# be used instead of the template's value (center, maps).
|
||||
# You can override the properties of the template by specifying them in this section
|
||||
# for example 'Title: "My Awesome World"'
|
||||
#- name: world
|
||||
# title: "World"
|
||||
# Use 'enabled: false' to disable a certain world.
|
||||
# enabled: false
|
||||
# Use 'template: mycustomtemplate' to use the properties specified in the template 'mycustomtemplate' to this world. Default it is set to the environment-name (normal or nether).
|
||||
# template: mycustomtemplate
|
||||
# Rest of comes from template - uncomment to tailor for world specifically
|
||||
# center:
|
||||
# x: 0
|
||||
|
@ -19,9 +19,12 @@ public class ClientConfigurationComponent extends Component {
|
||||
s(t, "joinmessage", c.getString("joinmessage", "%playername% joined"));
|
||||
s(t, "quitmessage", c.getString("quitmessage", "%playername% quit"));
|
||||
s(t, "spammessage", c.getString("spammessage", "You may only chat once every %interval% seconds."));
|
||||
s(t, "defaultzoom", c.getInteger("defaultzoom", 0));
|
||||
|
||||
for(ConfigurationNode wn : plugin.configuration.getNodes("worlds")) {
|
||||
DynmapWorld world = plugin.mapManager.getWorld(wn.getString("name"));
|
||||
DynmapWorld defaultWorld = null;
|
||||
for(DynmapWorld world : plugin.mapManager.getWorlds()) {
|
||||
if (defaultWorld == null) defaultWorld = world;
|
||||
ConfigurationNode wn = world.configuration;
|
||||
JSONObject wo = new JSONObject();
|
||||
s(wo, "name", wn.getString("name"));
|
||||
s(wo, "title", wn.getString("title"));
|
||||
@ -34,6 +37,7 @@ public class ClientConfigurationComponent extends Component {
|
||||
mt.buildClientConfiguration(wo);
|
||||
}
|
||||
}
|
||||
s(t, "defaultworld", c.getString("defaultworld", defaultWorld == null ? "world" : defaultWorld.world.getName()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -10,6 +10,11 @@ import java.util.Set;
|
||||
|
||||
public class ConfigurationNode implements Map<String, Object> {
|
||||
public Map<String, Object> entries;
|
||||
|
||||
public ConfigurationNode() {
|
||||
entries = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
public ConfigurationNode(org.bukkit.util.config.ConfigurationNode node) {
|
||||
entries = new HashMap<String, Object>();
|
||||
for(String key : node.getKeys(null)) {
|
||||
@ -18,6 +23,9 @@ public class ConfigurationNode implements Map<String, Object> {
|
||||
}
|
||||
|
||||
public ConfigurationNode(Map<String, Object> map) {
|
||||
if (map == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
entries = map;
|
||||
}
|
||||
|
||||
@ -152,6 +160,28 @@ public class ConfigurationNode implements Map<String, Object> {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
public void extend(Map<String, Object> other) {
|
||||
if (other != null)
|
||||
extendMap(this, other);
|
||||
}
|
||||
|
||||
private final static void extendMap(Map<String, Object> left, Map<String, Object> right) {
|
||||
ConfigurationNode original = new ConfigurationNode(left);
|
||||
for(Map.Entry<String, Object> entry : right.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Map<?, ?>) {
|
||||
ConfigurationNode subnode = original.getNode(key);
|
||||
if (subnode == null) {
|
||||
original.put(key, subnode = new ConfigurationNode());
|
||||
}
|
||||
extendMap(subnode, (Map<String, Object>)value);
|
||||
} else {
|
||||
original.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T createInstance(Class<?>[] constructorParameters, Object[] constructorArguments) {
|
||||
String typeName = getString("class");
|
||||
try {
|
||||
|
@ -74,8 +74,6 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
org.bukkit.util.config.Configuration bukkitConfiguration = new org.bukkit.util.config.Configuration(new File(this.getDataFolder(), "configuration.txt"));
|
||||
bukkitConfiguration.load();
|
||||
configuration = new ConfigurationNode(bukkitConfiguration);
|
||||
|
||||
processWorldTemplates(configuration);
|
||||
|
||||
loadDebuggers();
|
||||
|
||||
@ -150,20 +148,24 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
int componentCount = componentManager.components.size();
|
||||
for(Component component : componentManager.components) {
|
||||
component.dispose();
|
||||
if (componentManager != null) {
|
||||
int componentCount = componentManager.components.size();
|
||||
for(Component component : componentManager.components) {
|
||||
component.dispose();
|
||||
}
|
||||
componentManager.clear();
|
||||
Log.info("Unloaded " + componentCount + " components.");
|
||||
}
|
||||
componentManager.clear();
|
||||
Log.info("Unloaded " + componentCount + " components.");
|
||||
|
||||
mapManager.stopRendering();
|
||||
if (mapManager != null) {
|
||||
mapManager.stopRendering();
|
||||
}
|
||||
|
||||
if (webServer != null) {
|
||||
webServer.shutdown();
|
||||
webServer = null;
|
||||
}
|
||||
|
||||
|
||||
Debug.clearDebuggers();
|
||||
}
|
||||
|
||||
@ -344,10 +346,7 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
}
|
||||
} else if (c.equals("reload") && checkPlayerPermission(sender, "reload")) {
|
||||
sender.sendMessage("Reloading Dynmap...");
|
||||
is_reload = true;
|
||||
onDisable();
|
||||
onEnable();
|
||||
is_reload = false;
|
||||
reload();
|
||||
sender.sendMessage("Dynmap reloaded");
|
||||
return true;
|
||||
}
|
||||
@ -365,86 +364,67 @@ public class DynmapPlugin extends JavaPlugin {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* Prepare for sky worlds... */
|
||||
private static final String[] templateworldtypes = { "normal", "nether" };
|
||||
private static final Environment[] templateworldenv = { Environment.NORMAL, Environment.NETHER };
|
||||
|
||||
private void processWorldTemplates(ConfigurationNode node) {
|
||||
ConfigurationNode template = node.getNode("template");
|
||||
if(template == null)
|
||||
return;
|
||||
List<ConfigurationNode> worlds = node.getNodes("worlds");
|
||||
boolean worldsupdated = false;
|
||||
/* Initialize even if no worlds section */
|
||||
if(worlds == null) {
|
||||
worlds = new ArrayList<ConfigurationNode>();
|
||||
worldsupdated = true;
|
||||
}
|
||||
List<String> hiddenworlds = node.getStrings("hiddenworlds", Collections.EMPTY_LIST);
|
||||
|
||||
/* Iternate by world type - so that order in templateworldtypes drives our default order */
|
||||
for(int wtype = 0; wtype < templateworldtypes.length; wtype++) {
|
||||
ConfigurationNode typetemplate = template.getNode(templateworldtypes[wtype]);
|
||||
if(typetemplate == null)
|
||||
continue;
|
||||
for(World w : getServer().getWorlds()) { /* Roll through worlds */
|
||||
String wn = w.getName();
|
||||
/* Skip processing on hidden worlds */
|
||||
if(hiddenworlds.contains(wn))
|
||||
continue;
|
||||
/* Find node for this world, if any */
|
||||
ConfigurationNode world = null;
|
||||
int index;
|
||||
for(index = 0; index < worlds.size(); index++) {
|
||||
ConfigurationNode ww = worlds.get(index);
|
||||
if(wn.equals(ww.getString("name", ""))) {
|
||||
world = ww;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Check type of world - skip if not right for current template */
|
||||
if(w.getEnvironment() != templateworldenv[wtype])
|
||||
continue;
|
||||
/* World not found - need to use template */
|
||||
if(world == null) {
|
||||
ConfigurationNode newworldnode = new ConfigurationNode(new HashMap<String,Object>(typetemplate)); /* Copy it */
|
||||
newworldnode.put("name", w.getName());
|
||||
newworldnode.put("title", w.getName());
|
||||
worlds.add(newworldnode);
|
||||
worldsupdated = true;
|
||||
Log.info("World '" + w.getName() + "' configuration inherited from template");
|
||||
}
|
||||
else { /* Else, definition is there, but may be incomplete */
|
||||
boolean wupd = false;
|
||||
List<ConfigurationNode> tempmaps = typetemplate.getList("maps");
|
||||
if((tempmaps != null) && (world.get("maps") == null)) { /* World with no maps section */
|
||||
world.put("maps", tempmaps);
|
||||
Log.info("World '" + w.getName() + "' configuration inherited maps from template");
|
||||
wupd = true;
|
||||
}
|
||||
ConfigurationNode tempcenter = typetemplate.getNode("center");
|
||||
if((tempcenter != null) && (world.get("center") == null)) { /* World with no center */
|
||||
world.put("center", new ConfigurationNode(new HashMap<String,Object>(tempcenter)));
|
||||
Log.info("World '" + w.getName() + "' configuration inherited center from template");
|
||||
wupd = true;
|
||||
}
|
||||
if(world.getString("title", null) == null) {
|
||||
world.put("title", w.getName());
|
||||
wupd = true;
|
||||
}
|
||||
if(wupd) {
|
||||
worldsupdated = true;
|
||||
worlds.set(index, world);
|
||||
}
|
||||
}
|
||||
public ConfigurationNode getWorldConfiguration(World world) {
|
||||
ConfigurationNode finalConfiguration = new ConfigurationNode();
|
||||
finalConfiguration.put("name", world.getName());
|
||||
finalConfiguration.put("title", world.getName());
|
||||
|
||||
ConfigurationNode worldConfiguration = getWorldConfigurationNode(world.getName());
|
||||
|
||||
// Get the template.
|
||||
ConfigurationNode templateConfiguration = null;
|
||||
if (worldConfiguration != null) {
|
||||
String templateName = worldConfiguration.getString("template");
|
||||
if (templateName != null) {
|
||||
templateConfiguration = getTemplateConfigurationNode(templateName);
|
||||
}
|
||||
}
|
||||
if(worldsupdated) {
|
||||
node.put("worlds", worlds);
|
||||
|
||||
// Template not found, using default template.
|
||||
if (templateConfiguration == null) {
|
||||
templateConfiguration = getDefaultTemplateConfigurationNode(world);
|
||||
}
|
||||
|
||||
// Merge the finalConfiguration, templateConfiguration and worldConfiguration.
|
||||
finalConfiguration.extend(templateConfiguration);
|
||||
finalConfiguration.extend(worldConfiguration);
|
||||
|
||||
Log.info("Configuration of world " + world.getName());
|
||||
for(Map.Entry<String, Object> e : finalConfiguration.entrySet()) {
|
||||
Log.info(e.getKey() + ": " + e.getValue());
|
||||
}
|
||||
|
||||
return finalConfiguration;
|
||||
}
|
||||
|
||||
public boolean isReload() {
|
||||
return is_reload;
|
||||
private ConfigurationNode getDefaultTemplateConfigurationNode(World world) {
|
||||
Environment environment = world.getEnvironment();
|
||||
String environmentName = environment.name().toLowerCase();
|
||||
Log.info("Using environment as template: " + environmentName);
|
||||
return getTemplateConfigurationNode(environmentName);
|
||||
}
|
||||
|
||||
private ConfigurationNode getWorldConfigurationNode(String worldName) {
|
||||
for(ConfigurationNode worldNode : configuration.getNodes("worlds")) {
|
||||
if (worldName.equals(worldNode.getString("name"))) {
|
||||
return worldNode;
|
||||
}
|
||||
}
|
||||
return new ConfigurationNode();
|
||||
}
|
||||
|
||||
private ConfigurationNode getTemplateConfigurationNode(String templateName) {
|
||||
ConfigurationNode templatesNode = configuration.getNode("templates");
|
||||
if (templatesNode != null) {
|
||||
return templatesNode.getNode(templateName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
pluginManager.disablePlugin(this);
|
||||
pluginManager.enablePlugin(this);
|
||||
}
|
||||
}
|
||||
|
@ -9,4 +9,5 @@ public class DynmapWorld {
|
||||
public World world;
|
||||
public List<MapType> maps = new ArrayList<MapType>();
|
||||
public UpdateQueue updates = new UpdateQueue();
|
||||
public ConfigurationNode configuration;
|
||||
}
|
||||
|
@ -57,6 +57,12 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
|
||||
writeConfiguration();
|
||||
}
|
||||
});
|
||||
plugin.events.addListener("worldactivated", new Event.Listener<DynmapWorld>() {
|
||||
@Override
|
||||
public void triggered(DynmapWorld t) {
|
||||
writeConfiguration();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected File getStandaloneFile(String filename) {
|
||||
@ -87,7 +93,7 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
|
||||
protected void writeUpdates() {
|
||||
File outputFile;
|
||||
//Handles Updates
|
||||
for (DynmapWorld dynmapWorld : plugin.mapManager.worlds.values()) {
|
||||
for (DynmapWorld dynmapWorld : plugin.mapManager.getWorlds()) {
|
||||
World world = dynmapWorld.world;
|
||||
|
||||
JSONObject update = new JSONObject();
|
||||
|
@ -1,9 +1,12 @@
|
||||
package org.dynmap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
@ -17,8 +20,8 @@ public class MapManager {
|
||||
public AsynchronousQueue<MapTile> tileQueue;
|
||||
public AsynchronousQueue<ImageWriter> writeQueue;
|
||||
|
||||
public Map<String, DynmapWorld> worlds = new HashMap<String, DynmapWorld>();
|
||||
public Map<String, DynmapWorld> inactiveworlds = new HashMap<String, DynmapWorld>();
|
||||
public List<DynmapWorld> worlds = new ArrayList<DynmapWorld>();
|
||||
public Map<String, DynmapWorld> worldsLookup = new HashMap<String, DynmapWorld>();
|
||||
private BukkitScheduler scheduler;
|
||||
private DynmapPlugin plug_in;
|
||||
private double timeslice_interval = 0.0;
|
||||
@ -35,13 +38,14 @@ public class MapManager {
|
||||
}
|
||||
|
||||
public DynmapWorld getWorld(String name) {
|
||||
DynmapWorld world = worlds.get(name);
|
||||
if(world == null) {
|
||||
world = inactiveworlds.get(name);
|
||||
}
|
||||
DynmapWorld world = worldsLookup.get(name);
|
||||
return world;
|
||||
}
|
||||
|
||||
public Collection<DynmapWorld> getWorlds() {
|
||||
return worlds;
|
||||
}
|
||||
|
||||
private class FullWorldRenderState implements Runnable {
|
||||
DynmapWorld world; /* Which world are we rendering */
|
||||
Location loc; /* Start location */
|
||||
@ -64,7 +68,7 @@ public class MapManager {
|
||||
|
||||
/* Single tile render - used for incremental renders */
|
||||
FullWorldRenderState(MapTile t) {
|
||||
world = worlds.get(t.getWorld().getName());
|
||||
world = getWorld(t.getWorld().getName());
|
||||
tile0 = t;
|
||||
}
|
||||
|
||||
@ -136,7 +140,7 @@ public class MapManager {
|
||||
}
|
||||
|
||||
public MapManager(DynmapPlugin plugin, ConfigurationNode configuration) {
|
||||
|
||||
plug_in = plugin;
|
||||
mapman = this;
|
||||
|
||||
this.tileQueue = new AsynchronousQueue<MapTile>(new Handler<MapTile>() {
|
||||
@ -157,42 +161,18 @@ public class MapManager {
|
||||
|
||||
timeslice_interval = configuration.getDouble("timesliceinterval", 0.5);
|
||||
|
||||
for(ConfigurationNode worldConfiguration : configuration.getNodes("worlds")) {
|
||||
String worldName = worldConfiguration.getString("name");
|
||||
DynmapWorld world = new DynmapWorld();
|
||||
|
||||
Event.Listener<MapTile> invalitateListener = new Event.Listener<MapTile>() {
|
||||
@Override
|
||||
public void triggered(MapTile t) {
|
||||
invalidateTile(t);
|
||||
}
|
||||
};
|
||||
|
||||
Log.info("Loading maps of world '" + worldName + "'...");
|
||||
for(MapType map : worldConfiguration.<MapType>createInstances("maps", new Class<?>[0], new Object[0])) {
|
||||
map.onTileInvalidated.addListener(invalitateListener);
|
||||
world.maps.add(map);
|
||||
}
|
||||
Log.info("Loaded " + world.maps.size() + " maps of world '" + worldName + "'.");
|
||||
|
||||
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();
|
||||
|
||||
for (World world : plug_in.getServer().getWorlds()) {
|
||||
activateWorld(world);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void renderFullWorld(Location l) {
|
||||
DynmapWorld world = worlds.get(l.getWorld().getName());
|
||||
DynmapWorld world = getWorld(l.getWorld().getName());
|
||||
if (world == null) {
|
||||
Log.severe("Could not render: world '" + l.getWorld().getName() + "' not defined in configuration.");
|
||||
return;
|
||||
@ -211,21 +191,36 @@ public class MapManager {
|
||||
}
|
||||
|
||||
public void activateWorld(World w) {
|
||||
DynmapWorld world = inactiveworlds.get(w.getName());
|
||||
if (world == null) {
|
||||
world = worlds.get(w.getName());
|
||||
} else {
|
||||
inactiveworlds.remove(w.getName());
|
||||
ConfigurationNode worldConfiguration = plug_in.getWorldConfiguration(w);
|
||||
if (!worldConfiguration.getBoolean("enabled", false)) {
|
||||
Log.info("World '" + w.getName() + "' disabled");
|
||||
return;
|
||||
}
|
||||
if (world != null) {
|
||||
world.world = w;
|
||||
worlds.put(w.getName(), world);
|
||||
Log.info("Activated world '" + w.getName() + "' in Dynmap.");
|
||||
String worldName = w.getName();
|
||||
|
||||
Event.Listener<MapTile> invalitateListener = new Event.Listener<MapTile>() {
|
||||
@Override
|
||||
public void triggered(MapTile t) {
|
||||
invalidateTile(t);
|
||||
}
|
||||
};
|
||||
|
||||
DynmapWorld dynmapWorld = new DynmapWorld();
|
||||
dynmapWorld.world = w;
|
||||
dynmapWorld.configuration = worldConfiguration;
|
||||
Log.info("Loading maps of world '" + worldName + "'...");
|
||||
for(MapType map : worldConfiguration.<MapType>createInstances("maps", new Class<?>[0], new Object[0])) {
|
||||
map.onTileInvalidated.addListener(invalitateListener);
|
||||
dynmapWorld.maps.add(map);
|
||||
}
|
||||
Log.info("Loaded " + dynmapWorld.maps.size() + " maps of world '" + worldName + "'.");
|
||||
worlds.add(dynmapWorld);
|
||||
worldsLookup.put(w.getName(), dynmapWorld);
|
||||
plug_in.events.trigger("worldactivated", dynmapWorld);
|
||||
}
|
||||
|
||||
public int touch(Location l) {
|
||||
DynmapWorld world = worlds.get(l.getWorld().getName());
|
||||
DynmapWorld world = getWorld(l.getWorld().getName());
|
||||
if (world == null)
|
||||
return 0;
|
||||
int invalidates = 0;
|
||||
@ -276,7 +271,7 @@ public class MapManager {
|
||||
}
|
||||
|
||||
public void pushUpdate(Object update) {
|
||||
for(DynmapWorld world : worlds.values()) {
|
||||
for(DynmapWorld world : getWorlds()) {
|
||||
world.updates.pushUpdate(update);
|
||||
}
|
||||
}
|
||||
@ -286,12 +281,12 @@ public class MapManager {
|
||||
}
|
||||
|
||||
public void pushUpdate(String worldName, Object update) {
|
||||
DynmapWorld world = worlds.get(worldName);
|
||||
DynmapWorld world = getWorld(worldName);
|
||||
world.updates.pushUpdate(update);
|
||||
}
|
||||
|
||||
public Object[] getWorldUpdates(String worldName, long since) {
|
||||
DynmapWorld world = worlds.get(worldName);
|
||||
DynmapWorld world = getWorld(worldName);
|
||||
if (world == null)
|
||||
return new Object[0];
|
||||
return world.updates.getUpdatedObjects(since);
|
||||
|
@ -5,6 +5,8 @@ import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.dynmap.DynmapPlugin;
|
||||
import org.dynmap.DynmapWorld;
|
||||
import org.dynmap.Event;
|
||||
import org.dynmap.web.HttpHandler;
|
||||
import org.dynmap.web.HttpRequest;
|
||||
import org.dynmap.web.HttpResponse;
|
||||
@ -16,6 +18,12 @@ public class ClientConfigurationHandler implements HttpHandler {
|
||||
private byte[] cachedConfiguration = null;
|
||||
public ClientConfigurationHandler(DynmapPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
plugin.events.addListener("worldactivated", new Event.Listener<DynmapWorld>() {
|
||||
@Override
|
||||
public void triggered(DynmapWorld t) {
|
||||
cachedConfiguration = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void handle(String path, HttpRequest request, HttpResponse response) throws Exception {
|
||||
|
Loading…
Reference in New Issue
Block a user