diff --git a/config/mv_checks.xml b/config/mv_checks.xml
index 73be9841..54710f7b 100644
--- a/config/mv_checks.xml
+++ b/config/mv_checks.xml
@@ -76,7 +76,10 @@
-
+
+
+
+
diff --git a/pom.xml b/pom.xml
index 0f364d57..4d7b82d2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0com.onarandombox.multiversecoreMultiverse-Core
- 2.4
+ 2.5Multiverse-CoreWorld Management Plugin
@@ -25,6 +25,16 @@
DynMapTBD
-->
+
+
+ mcstats
+ http://repo.mcstats.org/content/repositories/snapshots
+
+
+
+ herocraft
+ http://ci.herocraftonline.com/plugin/repository/everything/
+
@@ -106,12 +116,6 @@
-
-
- org.apache.maven.plugins
- maven-source-plugin
- 2.1.2
- org.apache.maven.pluginsmaven-surefire-plugin
@@ -141,6 +145,33 @@
${project.basedir}/config/mv_checks.xml
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.1.2
+
+
+ attach-sources
+ package
+
+ jar-no-fork
+
+
+
+
+
+ maven-javadoc-plugin
+ 2.8.1
+
+
+ javadoc-jar
+ verify
+
+ jar
+
+
+
+ org.apache.maven.pluginsmaven-shade-plugin
@@ -155,8 +186,11 @@
me.main__.util:SerializationConfig
- com.fernferret.allpay:AllPaycom.pneumaticraft.commandhandler:CommandHandler
+ com.dumptruckman.minecraft:buscript
+ org.mcstats:metrics
+ com.dumptruckman.minecraft:Logging
+ com.fernferret.allpay:AllPay
@@ -172,6 +206,22 @@
com.pneumaticraft.commandhandlercom.pneumaticraft.commandhandler.multiverse
+
+ buscript
+ buscript.multiverse
+
+
+ org.mcstats
+ org.mcstats.multiverse
+
+
+ com.dumptruckman.minecraft.util.Logging
+ com.onarandombox.MultiverseCore.utils.CoreLogging
+
+
+ com.dumptruckman.minecraft.util.DebugLog
+ com.onarandombox.MultiverseCore.utils.DebugFileLogger
+
@@ -185,38 +235,45 @@
org.bukkitbukkit
- 1.2.3-R0.2-SNAPSHOT
+ 1.3.2-R2.1-SNAPSHOTjarcompile
-
+
+ End of Spout -->
me.main__.utilSerializationConfig
- 1.3
+ 1.6bjarcompile
-
+
com.fernferret.allpayAllPay
- 9
+ 10jarcompile
-
+
+ net.milkbowl.vault
+ Vault
+ 1.2.19-SNAPSHOT
+ jar
+ compile
+
+
com.pneumaticraft.commandhandler
@@ -242,6 +299,33 @@
compile
+
+
+ com.dumptruckman.minecraft
+ buscript
+ 1.0
+ jar
+ compile
+
+
+
+
+ org.mcstats
+ metrics
+ 1.2-SNAPSHOT
+ jar
+ compile
+
+
+
+
+ com.dumptruckman.minecraft
+ Logging
+ 1.0.6
+ jar
+ compile
+
+
junit
diff --git a/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java b/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java
index 3d376a39..5a59f5db 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java
@@ -9,14 +9,23 @@ package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
-import com.onarandombox.MultiverseCore.configuration.ConfigPropertyFactory;
-import com.onarandombox.MultiverseCore.configuration.MVActiveConfigProperty;
-import com.onarandombox.MultiverseCore.configuration.MVConfigProperty;
+import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
+import com.onarandombox.MultiverseCore.configuration.EntryFee;
+import com.onarandombox.MultiverseCore.configuration.SpawnLocation;
+import com.onarandombox.MultiverseCore.configuration.SpawnSettings;
+import com.onarandombox.MultiverseCore.configuration.WorldPropertyValidator;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import com.onarandombox.MultiverseCore.enums.EnglishChatColor;
-import com.onarandombox.MultiverseCore.event.MVWorldPropertyChangeEvent;
+import com.onarandombox.MultiverseCore.enums.EnglishChatStyle;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
-import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
+import me.main__.util.SerializationConfig.ChangeDeniedException;
+import me.main__.util.SerializationConfig.IllegalPropertyValueException;
+import me.main__.util.SerializationConfig.NoSuchPropertyException;
+import me.main__.util.SerializationConfig.Property;
+import me.main__.util.SerializationConfig.SerializationConfig;
+import me.main__.util.SerializationConfig.Serializor;
+import me.main__.util.SerializationConfig.ValidateAllWith;
+import me.main__.util.SerializationConfig.VirtualProperty;
import org.bukkit.ChatColor;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
@@ -25,15 +34,15 @@ import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.WorldType;
import org.bukkit.command.CommandSender;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
+import org.bukkit.util.Vector;
+import org.json.simple.JSONObject;
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Method;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -46,157 +55,520 @@ import java.util.regex.Pattern;
/**
* The implementation of a Multiverse handled world.
*/
-public class MVWorld implements MultiverseWorld {
+@SerializableAs("MVWorld")
+@ValidateAllWith(WorldPropertyValidator.class)
+public class MVWorld extends SerializationConfig implements MultiverseWorld {
+ private static final int SPAWN_LOCATION_SEARCH_TOLERANCE = 16;
+ private static final int SPAWN_LOCATION_SEARCH_RADIUS = 16;
+
+ private static final Map PROPERTY_ALIASES;
+
+ static {
+ PROPERTY_ALIASES = new HashMap();
+ PROPERTY_ALIASES.put("curr", "currency");
+ PROPERTY_ALIASES.put("scaling", "scale");
+ PROPERTY_ALIASES.put("aliascolor", "color");
+ PROPERTY_ALIASES.put("heal", "autoHeal");
+ PROPERTY_ALIASES.put("storm", "allowWeather");
+ PROPERTY_ALIASES.put("weather", "allowWeather");
+ PROPERTY_ALIASES.put("spawnmemory", "keepSpawnInMemory");
+ PROPERTY_ALIASES.put("memory", "keepSpawnInMemory");
+ PROPERTY_ALIASES.put("mode", "gameMode");
+ PROPERTY_ALIASES.put("diff", "difficulty");
+ PROPERTY_ALIASES.put("spawnlocation", "spawn");
+ PROPERTY_ALIASES.put("animals", "spawning.animals.spawn");
+ PROPERTY_ALIASES.put("monsters", "spawning.monsters.spawn");
+ }
+ /*
+ * We have to use setCBWorld(), setPlugin() and initPerms() to prepare this object for use.
+ */
+ public MVWorld(Map values) {
+ super(values);
+ }
private MultiverseCore plugin; // Hold the Plugin Instance.
- private FileConfiguration config; // Hold the Configuration File.
- private ConfigurationSection worldSection; // Holds the section of the config file for this world.
- private World world; // The World Instance.
- private Environment environment; // Hold the Environment type EG Environment.NETHER / Environment.NORMAL
- private Long seed; // The world seed
+ private volatile Reference world = new WeakReference(null); // A reference to the World Instance.
private String name; // The Worlds Name, EG its folder name.
- private Map> masterList;
- private Map> propertyList;
+ /**
+ * Validates the scale-property.
+ */
+ private final class ScalePropertyValidator extends WorldPropertyValidator {
+ @Override
+ public Double validateChange(String property, Double newValue, Double oldValue,
+ MVWorld object) throws ChangeDeniedException {
+ if (newValue <= 0) {
+ plugin.log(Level.FINE, "Someone tried to set a scale <= 0, aborting!");
+ throw new ChangeDeniedException();
+ }
+ return super.validateChange(property, newValue, oldValue, object);
+ }
+ }
+
+ /**
+ * Validates the respawnWorld-property.
+ */
+ private final class RespawnWorldPropertyValidator extends WorldPropertyValidator {
+ @Override
+ public String validateChange(String property, String newValue, String oldValue,
+ MVWorld object) throws ChangeDeniedException {
+ if (!plugin.getMVWorldManager().isMVWorld(newValue))
+ throw new ChangeDeniedException();
+ return super.validateChange(property, newValue, oldValue, object);
+ }
+ }
+
+ /**
+ * Serializor for the time-property.
+ */
+ private static final class TimePropertySerializor implements Serializor {
+ // BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
+ private static final String TIME_REGEX = "(\\d\\d?):?(\\d\\d)(a|p)?m?";
+ private static final Map TIME_ALIASES;
+ static {
+ Map staticTimes = new HashMap();
+ staticTimes.put("morning", "8:00");
+ staticTimes.put("day", "12:00");
+ staticTimes.put("noon", "12:00");
+ staticTimes.put("midnight", "0:00");
+ staticTimes.put("night", "20:00");
+
+ // now set TIME_ALIASES to a "frozen" map
+ TIME_ALIASES = Collections.unmodifiableMap(staticTimes);
+ }
+
+ @Override
+ public String serialize(Long from) {
+ // I'm tired, so they get time in 24 hour for now.
+ // Someone else can add 12 hr format if they want :P
+
+ int hours = (int) ((from / 1000 + 8) % 24);
+ int minutes = (int) (60 * (from % 1000) / 1000);
+
+ return String.format("%d:%02d", hours, minutes);
+ }
+
+ @Override
+ public Long deserialize(String serialized, Class wanted) throws IllegalPropertyValueException {
+ if (TIME_ALIASES.containsKey(serialized.toLowerCase())) {
+ serialized = TIME_ALIASES.get(serialized.toLowerCase());
+ }
+ // Regex that extracts a time in the following formats:
+ // 11:11pm, 11:11, 23:11, 1111, 1111p, and the aliases at the top of this file.
+ Pattern pattern = Pattern.compile(TIME_REGEX, Pattern.CASE_INSENSITIVE);
+ Matcher matcher = pattern.matcher(serialized);
+ matcher.find();
+ int hour = 0;
+ double minute = 0;
+ int count = matcher.groupCount();
+ if (count >= 2) {
+ hour = Integer.parseInt(matcher.group(1));
+ minute = Integer.parseInt(matcher.group(2));
+ }
+ // If there were 4 matches (all, hour, min, am/pm)
+ if (count == 4) {
+ // We want 24 hour time for calcs, but if they
+ // added a p[m], turn it into a 24 hr one.
+ if (matcher.group(3).equals("p")) {
+ hour += 12;
+ }
+ }
+ // Translate 24th hour to 0th hour.
+ if (hour == 24) {
+ hour = 0;
+ }
+ // Clamp the hour
+ if (hour > 23 || hour < 0) {
+ throw new IllegalPropertyValueException("Illegal hour!");
+ }
+ // Clamp the minute
+ if (minute > 59 || minute < 0) {
+ throw new IllegalPropertyValueException("Illegal minute!");
+ }
+ // 60 seconds in a minute, time needs to be in hrs * 1000, per
+ // the bukkit docs.
+ double totaltime = (hour + (minute / 60.0)) * 1000;
+ // Somehow there's an 8 hour offset...
+ totaltime -= 8000;
+ if (totaltime < 0) {
+ totaltime = 24000 + totaltime;
+ }
+
+ return (long) totaltime;
+ }
+ // END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
+ }
+
+ /**
+ * Used to apply the allowWeather-property.
+ */
+ private final class AllowWeatherPropertyValidator extends WorldPropertyValidator {
+ @Override
+ public Boolean validateChange(String property, Boolean newValue, Boolean oldValue,
+ MVWorld object) throws ChangeDeniedException {
+ if (!newValue) {
+ world.get().setStorm(false);
+ world.get().setThundering(false);
+ }
+ return super.validateChange(property, newValue, oldValue, object);
+ }
+ }
+
+ /**
+ * Used to apply the spawning-property.
+ */
+ private final class SpawningPropertyValidator extends WorldPropertyValidator {
+ @Override
+ public Boolean validateChange(String property, Boolean newValue, Boolean oldValue,
+ MVWorld object) throws ChangeDeniedException {
+ boolean allowMonsters, allowAnimals;
+ if (getAnimalList().isEmpty()) {
+ allowAnimals = canAnimalsSpawn();
+ } else {
+ allowAnimals = true;
+ }
+ if (getMonsterList().isEmpty()) {
+ allowMonsters = canMonstersSpawn();
+ } else {
+ allowMonsters = true;
+ }
+ world.get().setSpawnFlags(allowMonsters, allowAnimals);
+ plugin.getMVWorldManager().getTheWorldPurger().purgeWorld(MVWorld.this);
+ return super.validateChange(property, newValue, oldValue, object);
+ }
+ }
+
+ /**
+ * Serializor for the difficulty-property.
+ */
+ private static final class DifficultyPropertySerializor implements Serializor {
+ @Override
+ public String serialize(Difficulty from) {
+ return from.toString();
+ }
+
+ @Override
+ public Difficulty deserialize(String serialized, Class wanted) throws IllegalPropertyValueException {
+ try {
+ return Difficulty.getByValue(Integer.parseInt(serialized));
+ } catch (Exception e) {
+ }
+ try {
+ return Difficulty.valueOf(serialized.toUpperCase());
+ } catch (Exception e) {
+ }
+ throw new IllegalPropertyValueException();
+ }
+ }
+
+ /**
+ * Serializor for the gameMode-property.
+ */
+ private static final class GameModePropertySerializor implements Serializor {
+ @Override
+ public String serialize(GameMode from) {
+ return from.toString();
+ }
+
+ @Override
+ public GameMode deserialize(String serialized, Class wanted) throws IllegalPropertyValueException {
+ try {
+ return GameMode.getByValue(Integer.parseInt(serialized));
+ } catch (NumberFormatException nfe) {
+ }
+ try {
+ return GameMode.valueOf(serialized.toUpperCase());
+ } catch (Exception e) {
+ }
+ throw new IllegalPropertyValueException();
+ }
+ }
+
+
+ /**
+ * Used to apply the gameMode-property.
+ */
+ private final class GameModePropertyValidator extends WorldPropertyValidator {
+ @Override
+ public GameMode validateChange(String property, GameMode newValue, GameMode oldValue,
+ MVWorld object) throws ChangeDeniedException {
+ for (Player p : plugin.getServer().getWorld(getName()).getPlayers()) {
+ plugin.log(Level.FINER, String.format("Setting %s's GameMode to %s",
+ p.getName(), newValue.toString()));
+ plugin.getPlayerListener().handleGameMode(p, MVWorld.this);
+ }
+ return super.validateChange(property, newValue, oldValue, object);
+ }
+ }
+
+ /**
+ * Validator for the spawnLocation-property.
+ */
+ private final class SpawnLocationPropertyValidator extends WorldPropertyValidator {
+ @Override
+ public Location validateChange(String property, Location newValue, Location oldValue,
+ MVWorld object) throws ChangeDeniedException {
+ if (newValue == null)
+ throw new ChangeDeniedException();
+ if (adjustSpawn) {
+ BlockSafety bs = plugin.getBlockSafety();
+ // verify that the location is safe
+ if (!bs.playerCanSpawnHereSafely(newValue)) {
+ // it's not ==> find a better one!
+ plugin.log(Level.WARNING, String.format("Somebody tried to set the spawn location for '%s' to an unsafe value! Adjusting...", getAlias()));
+ plugin.log(Level.WARNING, "Old Location: " + plugin.getLocationManipulation().strCoordsRaw(oldValue));
+ plugin.log(Level.WARNING, "New (unsafe) Location: " + plugin.getLocationManipulation().strCoordsRaw(newValue));
+ SafeTTeleporter teleporter = plugin.getSafeTTeleporter();
+ newValue = teleporter.getSafeLocation(newValue, SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
+ if (newValue == null) {
+ plugin.log(Level.WARNING, "Couldn't fix the location. I have to abort the spawn location-change :/");
+ throw new ChangeDeniedException();
+ }
+ plugin.log(Level.WARNING, "New (safe) Location: " + plugin.getLocationManipulation().strCoordsRaw(newValue));
+ }
+ }
+ return super.validateChange(property, newValue, oldValue, object);
+ }
+ }
+
+ /**
+ * Serializor for the color-property.
+ */
+ private static final class EnumPropertySerializor> implements Serializor {
+ @Override
+ public String serialize(T from) {
+ return from.toString();
+ }
+
+ @Override
+ public T deserialize(String serialized, Class wanted) throws IllegalPropertyValueException {
+ try {
+ return Enum.valueOf(wanted, serialized.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ throw new IllegalPropertyValueException(e);
+ }
+ }
+ }
+
+ // --------------------------------------------------------------
+ // Begin properties
+ @Property(description = "Sorry, 'hidden' must either be: true or false.")
+ private volatile boolean hidden;
+ @Property(description = "Alias must be a valid string.")
+ private volatile String alias;
+ @Property(serializor = EnumPropertySerializor.class, description = "Sorry, 'color' must be a valid color-name.")
+ private volatile EnglishChatColor color;
+ @Property(serializor = EnumPropertySerializor.class, description = "Sorry, 'style' must be a valid style-name.")
+ private volatile EnglishChatStyle style;
+ @Property(description = "Sorry, 'pvp' must either be: true or false.", virtualType = Boolean.class, persistVirtual = true)
+ private volatile VirtualProperty pvp = new VirtualProperty() {
+ @Override
+ public void set(Boolean newValue) {
+ world.get().setPVP(newValue);
+ }
+
+ @Override
+ public Boolean get() {
+ return world.get().getPVP();
+ }
+ };
+ @Property(validator = ScalePropertyValidator.class, description = "Scale must be a positive double value. ex: 2.3")
+ private volatile double scale;
+ @Property(validator = RespawnWorldPropertyValidator.class, description = "You must set this to the NAME not alias of a world.")
+ private volatile String respawnWorld;
+ @Property(validator = AllowWeatherPropertyValidator.class, description = "Sorry, this must either be: true or false.")
+ private volatile boolean allowWeather;
+ @Property(serializor = DifficultyPropertySerializor.class, virtualType = Difficulty.class, persistVirtual = true,
+ description = "Difficulty must be set as one of the following: peaceful easy normal hard")
+ private volatile VirtualProperty difficulty = new VirtualProperty() {
+ @Override
+ public void set(Difficulty newValue) {
+ world.get().setDifficulty(newValue);
+ }
+
+ @Override
+ public Difficulty get() {
+ return world.get().getDifficulty();
+ }
+ };
+ @Property(validator = SpawningPropertyValidator.class, description = "Sorry, 'animals' must either be: true or false.")
+ private volatile SpawnSettings spawning;
+ @Property
+ private volatile EntryFee entryfee;
+ @Property(description = "Sorry, 'hunger' must either be: true or false.")
+ private volatile boolean hunger;
+ @Property(description = "Sorry, 'autoheal' must either be: true or false.")
+ private volatile boolean autoHeal;
+ @Property(description = "Sorry, 'adjustspawn' must either be: true or false.")
+ private volatile boolean adjustSpawn;
+ @Property(serializor = EnumPropertySerializor.class, description = "Allow portal forming must be NONE, ALL, NETHER or END.")
+ private volatile AllowedPortalType portalForm;
+ @Property(serializor = GameModePropertySerializor.class, validator = GameModePropertyValidator.class,
+ description = "GameMode must be set as one of the following: survival creative")
+ private volatile GameMode gameMode;
+ @Property(description = "Sorry, this must either be: true or false.", virtualType = Boolean.class, persistVirtual = true)
+ private volatile VirtualProperty keepSpawnInMemory = new VirtualProperty() {
+ @Override
+ public void set(Boolean newValue) {
+ world.get().setKeepSpawnInMemory(newValue);
+ }
+
+ @Override
+ public Boolean get() {
+ return world.get().getKeepSpawnInMemory();
+ }
+ };
+ @Property
+ private volatile SpawnLocation spawnLocation;
+ @Property(validator = SpawnLocationPropertyValidator.class, virtualType = Location.class,
+ description = "There is no help available for this variable. Go bug Rigby90 about it.")
+ private volatile VirtualProperty spawn = new VirtualProperty() {
+ @Override
+ public void set(Location newValue) {
+ if (getCBWorld() != null)
+ getCBWorld().setSpawnLocation(newValue.getBlockX(), newValue.getBlockY(), newValue.getBlockZ());
+
+ spawnLocation = new SpawnLocation(newValue);
+ }
+
+ @Override
+ public Location get() {
+ spawnLocation.setWorld(getCBWorld());
+ // basically, everybody should accept our "SpawnLocation", right?
+ // so just returning it should be fine
+ return spawnLocation;
+ }
+ };
+ @Property(description = "Set this to false ONLY if you don't want this world to load itself on server restart.")
+ private volatile boolean autoLoad;
+ @Property(description = "If a player dies in this world, shoudld they go to their bed?")
+ private volatile boolean bedRespawn;
+ @Property
+ private volatile List worldBlacklist;
+ @Property(serializor = TimePropertySerializor.class, virtualType = Long.class,
+ description = "Set the time to whatever you want! (Will NOT freeze time)")
+ private volatile VirtualProperty time = new VirtualProperty() {
+ @Override
+ public void set(Long newValue) {
+ world.get().setTime(newValue);
+ }
+
+ @Override
+ public Long get() {
+ return world.get().getTime();
+ }
+ };
+ @Property
+ private volatile Environment environment;
+ @Property
+ private volatile long seed;
+ @Property
+ private volatile String generator;
+ // End of properties
+ // --------------------------------------------------------------
private Permission permission;
private Permission exempt;
-
- private boolean canSave = false; // Prevents all the setters from constantly saving to the config when being called from the constructor.
- private Map propertyAliases;
private Permission ignoreperm;
- private static final Map TIME_ALIASES;
- private WorldType type;
-
- static {
- Map staticTimes = new HashMap();
- staticTimes.put("morning", "8:00");
- staticTimes.put("day", "12:00");
- staticTimes.put("noon", "12:00");
- staticTimes.put("midnight", "0:00");
- staticTimes.put("night", "20:00");
-
- // now set TIME_ALIASES to a "frozen" map
- TIME_ALIASES = Collections.unmodifiableMap(staticTimes);
+ public MVWorld(boolean fixSpawn) {
+ super();
+ if (!fixSpawn) {
+ this.adjustSpawn = false;
+ }
}
- public MVWorld(World world, FileConfiguration config, MultiverseCore instance, Long seed, String generatorString, boolean fixSpawn) {
- this.config = config;
- this.plugin = instance;
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void copyValues(SerializationConfig other) {
+ super.copyValues(other);
+ }
- // Set local values that CANNOT be changed by user
- this.world = world;
- this.name = world.getName();
- this.seed = seed;
- this.environment = world.getEnvironment();
- this.type = world.getWorldType();
-
- // Initialize our lists
- this.initLists();
- worldSection = config.getConfigurationSection("worlds." + this.name);
- if (worldSection == null) {
- config.createSection("worlds." + this.name);
- worldSection = config.getConfigurationSection("worlds." + this.name);
+ /**
+ * Null-location.
+ */
+ @SerializableAs("MVNullLocation (It's a bug if you see this in your config file)")
+ public static final class NullLocation extends SpawnLocation {
+ public NullLocation() {
+ super(0, -1, 0);
}
- // Write these files to the config (once it's saved)
- if (generatorString != null) {
- worldSection.set("generator", generatorString);
+
+ @Override
+ public Location clone() {
+ throw new UnsupportedOperationException();
+ };
+
+ @Override
+ public Map serialize() {
+ return Collections.EMPTY_MAP;
}
- if (seed != null) {
- worldSection.set("seed", this.seed);
+
+ /**
+ * Let Bukkit be able to deserialize this.
+ * @param args The map.
+ * @return The deserialized object.
+ */
+ public static NullLocation deserialize(Map args) {
+ return new NullLocation();
}
- worldSection.set("environment", this.environment.toString());
- worldSection.set("type", this.type.toString());
-
- // Start NEW config awesomeness.
- ConfigPropertyFactory fac = new ConfigPropertyFactory(this.worldSection);
- this.propertyList = new HashMap>();
- // The format of these are either:
- // getNewProperty(name, defaultValue, helpText)
- // or
- // getNewProperty(name, defaultValue, yamlConfigNode, helpText)
- //
- // If the first type is used, name is used as the yamlConfigNode
- this.propertyList.put("hidden", fac.getNewProperty("hidden", false,
- "Sorry, 'hidden' must either be:" + ChatColor.GREEN + " true " + ChatColor.WHITE + "or" + ChatColor.RED + " false" + ChatColor.WHITE + "."));
- this.propertyList.put("alias", fac.getNewProperty("alias", "", "alias.name",
- "Alias must be a valid string."));
- this.propertyList.put("color", fac.getNewProperty("color", EnglishChatColor.WHITE, "alias.color",
- "Sorry, 'color' must either one of: " + EnglishChatColor.getAllColors()));
- this.propertyList.put("pvp", fac.getNewProperty("pvp", true, "pvp",
- "Sorry, 'pvp' must either be:" + ChatColor.GREEN + " true " + ChatColor.WHITE
- + "or" + ChatColor.RED + " false" + ChatColor.WHITE + ".", "setActualPVP"));
- this.propertyList.put("scale", fac.getNewProperty("scale", this.getDefaultScale(this.environment), "scale",
- "Scale must be a positive double value. ex: " + ChatColor.GOLD + "2.3", "verifyScaleSetProperly"));
- this.propertyList.put("respawn", fac.getNewProperty("respawn", "", "respawnworld",
- "You must set this to the " + ChatColor.GOLD + " NAME" + ChatColor.RED + " not alias of a world."));
- this.propertyList.put("weather", fac.getNewProperty("weather", true, "allowweather",
- "Sorry, 'weather' must either be:" + ChatColor.GREEN + " true " + ChatColor.WHITE
- + "or" + ChatColor.RED + " false" + ChatColor.WHITE + ".", "setActualWeather"));
- this.propertyList.put("difficulty", fac.getNewProperty("difficulty", Difficulty.EASY,
- "Difficulty must be set as one of the following: " + ChatColor.GREEN + "peaceful "
- + ChatColor.AQUA + "easy " + ChatColor.GOLD + "normal " + ChatColor.RED + "hard"));
- this.propertyList.put("animals", fac.getNewProperty("animals", true, "animals.spawn",
- "Sorry, 'animals' must either be:" + ChatColor.GREEN + " true " + ChatColor.WHITE
- + "or" + ChatColor.RED + " false" + ChatColor.WHITE + ".", "syncMobs"));
- this.propertyList.put("monsters", fac.getNewProperty("monsters", true, "monsters.spawn",
- "Sorry, 'monsters' must either be:" + ChatColor.GREEN + " true " + ChatColor.WHITE
- + "or" + ChatColor.RED + " false" + ChatColor.WHITE + ".", "syncMobs"));
- this.propertyList.put("currency", fac.getNewProperty("currency", -1, "entryfee.currency",
- "Currency must be an integer between -1 and the highest Minecraft item ID."));
- this.propertyList.put("price", fac.getNewProperty("price", 0.0, "entryfee.price",
- "Price must be a double value. ex: " + ChatColor.GOLD + "1.2" + ChatColor.WHITE
- + ". Set to a negative value to give players money for entering this world."));
- this.propertyList.put("hunger", fac.getNewProperty("hunger", true,
- "Sorry, 'hunger' must either be:" + ChatColor.GREEN + " true " + ChatColor.WHITE + "or" + ChatColor.RED + " false" + ChatColor.WHITE + "."));
- this.propertyList.put("autoheal", fac.getNewProperty("autoheal", true,
- "Sorry, 'autoheal' must either be:" + ChatColor.GREEN + " true " + ChatColor.WHITE + "or" + ChatColor.RED + " false" + ChatColor.WHITE + "."));
- this.propertyList.put("adjustspawn", fac.getNewProperty("adjustspawn", true,
- "Sorry, 'adjustspawn' must either be:" + ChatColor.GREEN + " true " + ChatColor.WHITE
- + "or" + ChatColor.RED + " false" + ChatColor.WHITE + "."));
- this.propertyList.put("portalform", fac.getNewProperty("portalform", AllowedPortalType.ALL,
- "Allow portal forming must be NONE, ALL, NETHER or END."));
- if (!fixSpawn) {
- this.setAdjustSpawn(false);
+ @Override
+ public Vector toVector() {
+ throw new UnsupportedOperationException();
}
- this.propertyList.put("gamemode", fac.getNewProperty("gamemode", GameMode.SURVIVAL,
- "GameMode must be set as one of the following: " + ChatColor.RED + "survival " + ChatColor.GREEN + "creative "));
- this.propertyList.put("memory", fac.getNewProperty("keepspawninmemory", true, "keepspawninmemory",
- "Sorry, 'memory' must either be:" + ChatColor.GREEN + " true "
- + ChatColor.WHITE + "or" + ChatColor.RED + " false" + ChatColor.WHITE + ".", "setActualKeepSpawnInMemory"));
- this.propertyList.put("spawn", fac.getNewProperty("spawn", this.world.getSpawnLocation(), "spawn",
- "There is no help available for this variable. Go bug Rigby90 about it.", "setActualKeepSpawnInMemory"));
- this.propertyList.put("autoload", fac.getNewProperty("autoload", true,
- "Set this to false ONLY if you don't want this world to load itself on server restart."));
- this.propertyList.put("bedrespawn", fac.getNewProperty("bedrespawn", true, "If a player dies in this world, shoudld they go to their bed?"));
- this.propertyList.put("time", fac.getNewProperty("time", "", "Set the time to whatever you want! (Will NOT freeze time)", "setActualTime", true));
- this.getKnownProperty("spawn", Location.class).setValue(this.readSpawnFromConfig(this.getCBWorld()));
+ @Override
+ public int hashCode() {
+ return -1;
+ };
- // Set aliases
- this.propertyAliases = new HashMap();
- this.propertyAliases.put("curr", "currency");
- this.propertyAliases.put("scaling", "scale");
- this.propertyAliases.put("aliascolor", "color");
- this.propertyAliases.put("heal", "autoheal");
- this.propertyAliases.put("storm", "weather");
- this.propertyAliases.put("spawnmemory", "memory");
- this.propertyAliases.put("mode", "gamemode");
- this.propertyAliases.put("diff", "difficulty");
+ @Override
+ public String toString() {
+ return "NULL LOCATION";
+ };
+ }
- // Things I haven't converted yet.
- this.getMobExceptions();
- List tempWorldBlacklist = worldSection.getStringList("worldblacklist");
- if (tempWorldBlacklist != null)
- this.getWorldBlacklist().addAll(tempWorldBlacklist);
+ /**
+ * Sets the CB-World.
+ *
+ * This is used to set some values after deserialization.
+ * @param cbWorld The new world.
+ * @param thePlugin The reference to the plugin.
+ */
+ public void init(World cbWorld, MultiverseCore thePlugin) {
+ this.plugin = thePlugin;
- // Enable and do the save.
- this.canSave = true;
- this.saveConfig();
+ // Weak reference so the CB-World can be unloaded even if this object still exists!
+ this.world = new WeakReference(cbWorld);
+ this.environment = cbWorld.getEnvironment();
+ this.seed = cbWorld.getSeed();
+ this.name = cbWorld.getName();
+ if (this.spawnLocation instanceof NullLocation)
+ this.spawnLocation = new SpawnLocation(readSpawnFromWorld(cbWorld));
+ this.initPerms();
+
+ this.flushPendingVPropChanges();
+ }
+
+ /**
+ * This prepares the MVWorld for unloading.
+ */
+ public void tearDown() {
+ try {
+ this.buildVPropChanges();
+ } catch (IllegalStateException e) {
+ // do nothing
+ }
+ }
+
+ /**
+ * Initializes permissions.
+ */
+ private void initPerms() {
this.permission = new Permission("multiverse.access." + this.getName(), "Allows access to " + this.getName(), PermissionDefault.OP);
// This guy is special. He shouldn't be added to any parent perms.
this.ignoreperm = new Permission("mv.bypass.gamemode." + this.getName(),
@@ -216,79 +588,93 @@ public class MVWorld implements MultiverseWorld {
} catch (IllegalArgumentException e) {
this.plugin.log(Level.FINER, "Permissions nodes were already added for " + this.name);
}
-
- // Sync all active settings.
- this.setActualPVP();
- this.verifyScaleSetProperly();
- this.setActualKeepSpawnInMemory();
- this.setActualDifficulty();
- this.setActualGameMode();
- this.setActualSpawn();
- this.syncMobs();
}
- /**
- * Used by the active PVP-property to set the "actual" PVP-property.
- * @return True if the property was successfully set.
- */
- public boolean setActualPVP() {
- // Set the PVP mode
- this.world.setPVP(this.getKnownProperty("pvp", Boolean.class).getValue());
- return true;
- }
-
- /**
- * Used by the active scale-property to set the "actual" scale-property.
- * @return True if the property was successfully set.
- */
- public boolean verifyScaleSetProperly() {
- // Ensure the scale is above 0
- if (this.getKnownProperty("scale", Double.class).getValue() <= 0) {
- // Disallow negative or 0 scalings.
- this.getKnownProperty("scale", Double.class).setValue(1.0);
- this.plugin.log(Level.WARNING, "Someone tried to set a scale <= 0, defaulting to 1.");
+ private Location readSpawnFromWorld(World w) {
+ Location location = w.getSpawnLocation();
+ // Set the worldspawn to our configspawn
+ BlockSafety bs = this.plugin.getBlockSafety();
+ // Verify that location was safe
+ if (!bs.playerCanSpawnHereSafely(location)) {
+ if (!this.getAdjustSpawn()) {
+ this.plugin.log(Level.FINE, "Spawn location from world.dat file was unsafe!!");
+ this.plugin.log(Level.FINE, "NOT adjusting spawn for '" + this.getAlias() + "' because you told me not to.");
+ this.plugin.log(Level.FINE, "To turn on spawn adjustment for this world simply type:");
+ this.plugin.log(Level.FINE, "/mvm set adjustspawn true " + this.getAlias());
+ return location;
+ }
+ // If it's not, find a better one.
+ SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
+ this.plugin.log(Level.WARNING, "Spawn location from world.dat file was unsafe. Adjusting...");
+ this.plugin.log(Level.WARNING, "Original Location: " + plugin.getLocationManipulation().strCoordsRaw(location));
+ Location newSpawn = teleporter.getSafeLocation(location,
+ SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
+ // I think we could also do this, as I think this is what Notch does.
+ // Not sure how it will work in the nether...
+ //Location newSpawn = this.spawnLocation.getWorld().getHighestBlockAt(this.spawnLocation).getLocation();
+ if (newSpawn != null) {
+ this.plugin.log(Level.INFO, String.format("New Spawn for '%s' is located at: %s",
+ this.getName(), plugin.getLocationManipulation().locationToString(newSpawn)));
+ return newSpawn;
+ } else {
+ // If it's a standard end world, let's check in a better place:
+ Location newerSpawn;
+ newerSpawn = bs.getTopBlock(new Location(w, 0, 0, 0));
+ if (newerSpawn != null) {
+ this.plugin.log(Level.INFO, String.format("New Spawn for '%s' is located at: %s",
+ this.getName(), plugin.getLocationManipulation().locationToString(newerSpawn)));
+ return newerSpawn;
+ } else {
+ this.plugin.log(Level.SEVERE, "Safe spawn NOT found!!!");
+ }
+ }
}
- return true;
+ return location;
}
/**
- * Used by the active keepSpawnInMemory-property to set the "actual" property.
- * @return True if the property was successfully set.
+ * {@inheritDoc}
*/
- public boolean setActualKeepSpawnInMemory() {
- // Ensure the memory setting is correct
- this.getCBWorld().setKeepSpawnInMemory(this.getKnownProperty("memory", Boolean.class).getValue());
- return true;
+ @Override
+ protected void setDefaults() {
+ this.hidden = false;
+ this.alias = new String();
+ this.color = EnglishChatColor.WHITE;
+ this.style = EnglishChatStyle.NORMAL;
+ this.scale = getDefaultScale(environment);
+ this.respawnWorld = new String();
+ this.allowWeather = true;
+ this.spawning = new SpawnSettings();
+ this.entryfee = new EntryFee();
+ this.hunger = true;
+ this.autoHeal = true;
+ this.adjustSpawn = true;
+ this.portalForm = AllowedPortalType.ALL;
+ this.gameMode = GameMode.SURVIVAL;
+ this.spawnLocation = (world != null) ? new SpawnLocation(world.get().getSpawnLocation()) : new NullLocation();
+ this.autoLoad = true;
+ this.bedRespawn = true;
+ this.worldBlacklist = new ArrayList();
+ this.generator = null;
}
/**
- * Used by the active difficulty-property to set the "actual" property.
- * @return True if the property was successfully set.
+ * getAliases().
+ * @return The alias-map.
+ * @see SerializationConfig
*/
- public boolean setActualDifficulty() {
- this.getCBWorld().setDifficulty(this.getKnownProperty("difficulty", Difficulty.class).getValue());
- return true;
+ protected static Map getAliases() {
+ return PROPERTY_ALIASES;
}
- /**
- * Used by the active spawn-property to set the "actual" property.
- * @return True if the property was successfully set.
- */
- public boolean setActualSpawn() {
- // Set the spawn location
- Location spawnLocation = this.getKnownProperty("spawn", Location.class).getValue();
- this.getCBWorld().setSpawnLocation(spawnLocation.getBlockX(), spawnLocation.getBlockY(), spawnLocation.getBlockZ());
- return true;
- }
-
- private double getDefaultScale(Environment environment) {
+ private static double getDefaultScale(Environment environment) {
if (environment == Environment.NETHER) {
return 8.0; // SUPPRESS CHECKSTYLE: MagicNumberCheck
}
return 1.0;
}
- private void addToUpperLists(Permission permission) {
+ private void addToUpperLists(Permission perm) {
Permission all = this.plugin.getServer().getPluginManager().getPermission("multiverse.*");
Permission allWorlds = this.plugin.getServer().getPluginManager().getPermission("multiverse.access.*");
Permission allExemption = this.plugin.getServer().getPluginManager().getPermission("multiverse.exempt.*");
@@ -297,7 +683,7 @@ public class MVWorld implements MultiverseWorld {
allWorlds = new Permission("multiverse.access.*");
this.plugin.getServer().getPluginManager().addPermission(allWorlds);
}
- allWorlds.getChildren().put(permission.getName(), true);
+ allWorlds.getChildren().put(perm.getName(), true);
if (allExemption == null) {
allExemption = new Permission("multiverse.exempt.*");
this.plugin.getServer().getPluginManager().addPermission(allExemption);
@@ -314,289 +700,178 @@ public class MVWorld implements MultiverseWorld {
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(allWorlds);
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public World getCBWorld() {
+ return this.world.get();
+ }
+
/**
* {@inheritDoc}
*/
@Override
public String getColoredWorldString() {
- EnglishChatColor worldColor = this.getKnownProperty("color", EnglishChatColor.class).getValue();
- String alias = this.getKnownProperty("alias", String.class).getValue();
- if (worldColor == null) {
- this.setKnownProperty("color", "WHITE", null);
- return alias + ChatColor.WHITE;
- } else if (worldColor.getColor() == null) {
- return alias + ChatColor.WHITE;
- }
if (alias.length() == 0) {
alias = this.getName();
}
- return worldColor.getColor() + alias + ChatColor.WHITE;
- }
- // TODO: Migrate this method.
- private void getMobExceptions() {
- List temp;
- temp = this.worldSection.getStringList("animals.exceptions");
- // Add Animals to the exclusion list
- if (temp != null) {
- for (String s : temp) {
- this.masterList.get("animals").add(s.toUpperCase());
- }
- }
- temp = this.worldSection.getStringList("monsters.exceptions");
- // Add Monsters to the exclusion list
- if (temp != null) {
- for (String s : temp) {
- this.masterList.get("monsters").add(s.toUpperCase());
- }
+ if ((color == null) || (color.getColor() == null)) {
+ this.setPropertyValueUnchecked("color", EnglishChatColor.WHITE);
}
+
+ StringBuilder nameBuilder = new StringBuilder().append(color.getColor());
+ if (style.getColor() != null)
+ nameBuilder.append(style.getColor());
+ nameBuilder.append(alias).append(ChatColor.WHITE).toString();
+
+ return nameBuilder.toString();
}
/**
* {@inheritDoc}
+ *
+ * @deprecated This is deprecated.
*/
@Override
- public World getCBWorld() {
- return this.world;
- }
-
- private void initLists() {
- this.masterList = new HashMap>();
- this.masterList.put("worldblacklist", new ArrayList());
- this.masterList.put("animals", new ArrayList());
- this.masterList.put("monsters", new ArrayList());
+ @Deprecated
+ public boolean clearList(String property) {
+ return clearVariable(property);
}
/**
* {@inheritDoc}
+ *
+ * @deprecated This is deprecated.
*/
@Override
+ @Deprecated
public boolean clearVariable(String property) {
- if (this.masterList.keySet().contains(property)) {
- this.masterList.get(property).clear();
- } else {
+ List list = getOldAndEvilList(property);
+ if (list == null)
return false;
- }
- this.worldSection.set(property.toLowerCase(), new ArrayList());
- this.saveConfig();
+ list.clear();
return true;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean addToVariable(String property, String value) {
- property = property.toLowerCase();
- if (this.masterList.keySet().contains(property)) {
-
- if (property.equals("animals") || property.equals("monsters")) {
- this.masterList.get(property).add(value.toUpperCase());
- this.worldSection.set(property.toLowerCase() + ".exceptions", this.masterList.get(property));
- this.syncMobs();
- } else {
- this.masterList.get(property).add(value);
- this.worldSection.set(property.toLowerCase(), this.masterList.get(property));
- }
- saveConfig();
- return true;
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean removeFromVariable(String property, String value) {
- property = property.toLowerCase();
- if (this.masterList.keySet().contains(property)) {
-
- if (property.equals("animals") || property.equals("monsters")) {
- this.masterList.get(property).remove(value.toUpperCase());
- this.worldSection.set(property + ".exceptions", this.masterList.get(property));
- this.syncMobs();
- } else {
- this.masterList.get(property).remove(value);
- this.worldSection.set(property, this.masterList.get(property));
- }
- saveConfig();
- return true;
- }
- return false;
- }
-
- /**
- * Ensure that the value of the animals and monsters config
- * properties are set in accordance with the current animals
- * and monsters in the world, respectively.
- */
- public void syncMobs() {
-
- if (this.getAnimalList().isEmpty()) {
- this.world.setSpawnFlags(this.world.getAllowMonsters(), this.getKnownProperty("animals", Boolean.class).getValue());
- } else {
- this.world.setSpawnFlags(this.world.getAllowMonsters(), true);
- }
- if (this.getMonsterList().isEmpty()) {
- this.world.setSpawnFlags(this.getKnownProperty("monsters", Boolean.class).getValue(), this.world.getAllowAnimals());
- } else {
- this.world.setSpawnFlags(true, this.world.getAllowAnimals());
- }
- this.plugin.getMVWorldManager().getTheWorldPurger().purgeWorld(this);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setKeepSpawnInMemory(boolean value) {
- this.getKnownProperty("memory", Boolean.class).setValue(value);
- saveConfig();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- // TODO: Provide better feedback
- public boolean setProperty(String name, String value, CommandSender sender) throws PropertyDoesNotExistException {
- if (!this.isValidPropertyName(name)) {
- throw new PropertyDoesNotExistException(name);
- }
- return this.setKnownProperty(name, value, sender) || this.setKnownProperty(this.propertyAliases.get(name), value, sender);
-
- }
-
- private boolean isValidPropertyName(String name) {
- return this.propertyList.containsKey(name) || this.propertyAliases.containsKey(name);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public String getPropertyValue(String name) throws PropertyDoesNotExistException {
- if (this.propertyList.containsKey(name)) {
- return this.getKnownProperty(name, Object.class).toString();
- }
- throw new PropertyDoesNotExistException(name);
- }
-
/**
* {@inheritDoc}
*
- * @deprecated Use {@link #getProperty(String, Class)} instead
+ * @deprecated This is deprecated.
*/
@Override
@Deprecated
- public MVConfigProperty> getProperty(String property) throws PropertyDoesNotExistException {
- return getProperty(property, Object.class);
+ public boolean addToVariable(String property, String value) {
+ List list = getOldAndEvilList(property);
+ if (list == null)
+ return false;
+ list.add(value);
+ return true;
}
/**
* {@inheritDoc}
+ *
+ * @deprecated This is deprecated.
*/
@Override
- public MVConfigProperty getProperty(String name, Class expected) throws PropertyDoesNotExistException {
- MVConfigProperty p = this.getKnownProperty(name, expected);
- if (p == null) {
- throw new PropertyDoesNotExistException(name);
- }
- return p;
+ @Deprecated
+ public boolean removeFromVariable(String property, String value) {
+ List list = getOldAndEvilList(property);
+ if (list == null)
+ return false;
+ list.remove(value);
+ return true;
}
/**
- * This method should only be used from inside this class when it is KNOWN that the property exists.
- *
- * @param name The known name of a property
- * @param expected The Type of the expected value
- * @return The property object.
+ * @deprecated This is deprecated.
*/
- @SuppressWarnings("unchecked")
- private MVConfigProperty getKnownProperty(String name, Class expected) {
- try {
- if (this.propertyList.containsKey(name)) {
- return (MVConfigProperty) this.propertyList.get(name);
- } else if (this.propertyAliases.containsKey(name)) {
- // If the property was defined in the alias table, make sure to grab the actual name
- return (MVConfigProperty) this.propertyList.get(this.propertyAliases.get(name));
- }
- } catch (ClassCastException e) {
- return null;
- }
+ @Deprecated
+ private List getOldAndEvilList(String property) {
+ if (property.equalsIgnoreCase("worldblacklist"))
+ return this.worldBlacklist;
+ else if (property.equalsIgnoreCase("animals"))
+ return this.spawning.getAnimalSettings().getExceptions();
+ else if (property.equalsIgnoreCase("monsters"))
+ return this.spawning.getMonsterSettings().getExceptions();
return null;
}
/**
- * This method should only be used from inside this class when it is KNOWN that the property exists.
+ * {@inheritDoc}
*
- * @param name The known name of a property.
- * @param value The value that is trying to be set.
- * @param sender The person sending the command, MAY BE NULL.
- * @return True if the property was saved, false if not.
+ * @deprecated This is deprecated.
*/
- private boolean setKnownProperty(String name, String value, CommandSender sender) {
- MVConfigProperty> property;
- if (this.propertyList.containsKey(name)) {
- property = this.getKnownProperty(name, Object.class);
- } else if (this.propertyAliases.containsKey(name)) {
- return this.setKnownProperty(this.propertyAliases.get(name), value, sender);
- } else {
- return false;
- }
- // Only allow people to cancel events when they're not the initializations.
- if (this.canSave) {
- MVWorldPropertyChangeEvent propertyChangeEvent = new MVWorldPropertyChangeEvent(this, sender, name, value);
- this.plugin.getServer().getPluginManager().callEvent(propertyChangeEvent);
- if (propertyChangeEvent.isCancelled()) {
- this.plugin.log(Level.FINE, "Someone else cancelled the WorldPropertyChanged Event!!!");
- return false;
- }
- value = propertyChangeEvent.getNewValue();
- }
- if (property.parseValue(value)) {
- if (property instanceof MVActiveConfigProperty) {
- return this.setActiveProperty((MVActiveConfigProperty>) property);
- }
- this.saveConfig();
- return true;
- }
- return false;
+ @Override
+ @Deprecated
+ public com.onarandombox.MultiverseCore.configuration.MVConfigProperty getProperty(String property,
+ Class expected) throws PropertyDoesNotExistException {
+ throw new UnsupportedOperationException("'MVConfigProperty getProperty(String,Class)' is no longer supported!");
}
- private boolean setActiveProperty(MVActiveConfigProperty> property) {
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated This is deprecated.
+ */
+ @Override
+ @Deprecated
+ public boolean setProperty(String name, String value, CommandSender sender) throws PropertyDoesNotExistException {
+ return this.setPropertyValue(name, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getPropertyValue(String property) throws PropertyDoesNotExistException {
try {
- if (property.getMethod() == null) {
- // This property did not have a method.
- this.saveConfig();
- return true;
- }
- Method method = this.getClass().getMethod(property.getMethod());
- Object returnVal = method.invoke(this);
- if (returnVal instanceof Boolean) {
- if ((Boolean) returnVal) {
- this.saveConfig();
- }
- return (Boolean) returnVal;
- } else {
- this.saveConfig();
- return true;
- }
- } catch (Exception e) {
- // TODO: I don't care about 3 catches,
- // TODO: I hate pokemon errors :/ - FernFerret
- e.printStackTrace();
- return false;
+ return this.getProperty(property, true);
+ } catch (NoSuchPropertyException e) {
+ throw new PropertyDoesNotExistException(property, e);
}
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean setPropertyValue(String property, String value) throws PropertyDoesNotExistException {
+ try {
+ return this.setProperty(property, value, true);
+ } catch (NoSuchPropertyException e) {
+ throw new PropertyDoesNotExistException(property, e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getPropertyHelp(String property) throws PropertyDoesNotExistException {
+ try {
+ return this.getPropertyDescription(property, true);
+ } catch (NoSuchPropertyException e) {
+ throw new PropertyDoesNotExistException(property, e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public WorldType getWorldType() {
+ // This variable is not settable in-game, therefore does not get a property.
+ return world.get().getWorldType();
+ }
+
/**
* {@inheritDoc}
*/
@Override
public Environment getEnvironment() {
- // This variable is not settable in-game, therefore does not get a property.
return this.environment;
}
@@ -605,16 +880,14 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setEnvironment(Environment environment) {
- // This variable is not settable in-game, therefore does not get a property.
- this.environment = environment;
+ this.setPropertyValueUnchecked("environment", environment);
}
/**
* {@inheritDoc}
*/
@Override
- public Long getSeed() {
- // This variable is not settable in-game, therefore does not get a property.
+ public long getSeed() {
return this.seed;
}
@@ -622,9 +895,24 @@ public class MVWorld implements MultiverseWorld {
* {@inheritDoc}
*/
@Override
- public void setSeed(Long seed) {
- // This variable is not settable in-game, therefore does not get a property.
- this.seed = seed;
+ public void setSeed(long seed) {
+ this.setPropertyValueUnchecked("seed", seed);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getGenerator() {
+ return this.generator;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setGenerator(String generator) {
+ this.setPropertyValueUnchecked("generator", generator);
}
/**
@@ -649,12 +937,10 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public String getAlias() {
- String alias = this.getKnownProperty("alias", String.class).getValue();
- if (alias == null || alias.length() == 0) {
+ if (this.alias == null || this.alias.length() == 0) {
return this.name;
}
- return alias;
-
+ return this.alias;
}
/**
@@ -662,7 +948,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setAlias(String alias) {
- this.setKnownProperty("alias", alias, null);
+ this.setPropertyValueUnchecked("alias", alias);
}
/**
@@ -670,7 +956,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean canAnimalsSpawn() {
- return this.getKnownProperty("animals", Boolean.class).getValue();
+ return this.spawning.getAnimalSettings().doSpawn();
}
/**
@@ -678,7 +964,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setAllowAnimalSpawn(boolean animals) {
- this.setKnownProperty("animals", animals + "", null);
+ this.setPropertyValueUnchecked("spawning.animals.spawn", animals);
}
/**
@@ -686,7 +972,8 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public List getAnimalList() {
- return this.masterList.get("animals");
+ // These don't fire events at the moment. Should they?
+ return this.spawning.getAnimalSettings().getExceptions();
}
/**
@@ -694,7 +981,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean canMonstersSpawn() {
- return this.getKnownProperty("monsters", Boolean.class).getValue();
+ return this.spawning.getMonsterSettings().doSpawn();
}
/**
@@ -702,7 +989,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setAllowMonsterSpawn(boolean monsters) {
- this.setKnownProperty("monsters", monsters + "", null);
+ this.setPropertyValueUnchecked("spawning.monsters.spawn", monsters);
}
/**
@@ -710,7 +997,8 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public List getMonsterList() {
- return this.masterList.get("monsters");
+ // These don't fire events at the moment. Should they?
+ return this.spawning.getMonsterSettings().getExceptions();
}
/**
@@ -718,7 +1006,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean isPVPEnabled() {
- return this.getKnownProperty("pvp", Boolean.class).getValue();
+ return this.pvp.get();
}
/**
@@ -726,7 +1014,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setPVPMode(boolean pvp) {
- this.setKnownProperty("pvp", pvp + "", null);
+ this.setPropertyValueUnchecked("pvp", pvp);
}
/**
@@ -734,7 +1022,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean isHidden() {
- return this.getKnownProperty("hidden", Boolean.class).getValue();
+ return this.hidden;
}
/**
@@ -742,7 +1030,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setHidden(boolean hidden) {
- this.setKnownProperty("hidden", hidden + "", null);
+ this.setPropertyValueUnchecked("hidden", hidden);
}
/**
@@ -750,7 +1038,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public List getWorldBlacklist() {
- return this.masterList.get("worldblacklist");
+ return this.worldBlacklist;
}
/**
@@ -758,7 +1046,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public double getScaling() {
- return this.getKnownProperty("scale", Double.class).getValue();
+ return this.scale;
}
/**
@@ -766,7 +1054,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean setScaling(double scaling) {
- return this.setKnownProperty("scale", scaling + "", null);
+ return this.setPropertyValueUnchecked("scale", scaling);
}
/**
@@ -774,13 +1062,16 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean setColor(String aliasColor) {
- return this.setKnownProperty("color", aliasColor, null);
+ return this.setPropertyUnchecked("color", aliasColor);
}
/**
* {@inheritDoc}
+ *
+ * @deprecated This is deprecated.
*/
- @Override // TODO This method should be static. (Maybe EnglishChatColor would be a good place?)
+ @Override
+ @Deprecated
public boolean isValidAliasColor(String aliasColor) {
return (EnglishChatColor.fromString(aliasColor) != null);
}
@@ -790,22 +1081,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public ChatColor getColor() {
- return this.getKnownProperty("color", EnglishChatColor.class).getValue().getColor();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean clearList(String property) {
- if (this.masterList.containsKey(property)) {
- this.masterList.get(property).clear();
- this.worldSection.set(property.toLowerCase(), this.masterList.get(property));
- this.syncMobs();
- saveConfig();
- return true;
- }
- return false;
+ return this.color.getColor();
}
/**
@@ -824,7 +1100,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public World getRespawnToWorld() {
- return (this.plugin.getServer().getWorld(this.getKnownProperty("respawn", String.class).getValue()));
+ return this.plugin.getServer().getWorld(respawnWorld);
}
/**
@@ -833,7 +1109,7 @@ public class MVWorld implements MultiverseWorld {
@Override
public boolean setRespawnToWorld(String respawnToWorld) {
if (!this.plugin.getMVWorldManager().isMVWorld(respawnToWorld)) return false;
- return this.setKnownProperty("respawn", respawnToWorld, null);
+ return this.setPropertyValueUnchecked("respawnWorld", respawnToWorld);
}
/**
@@ -849,7 +1125,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public int getCurrency() {
- return this.getKnownProperty("curr", Integer.class).getValue();
+ return this.entryfee.getCurrency();
}
/**
@@ -857,7 +1133,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setCurrency(int currency) {
- this.setKnownProperty("curr", currency + "", null);
+ this.setPropertyValueUnchecked("entryfee.currency", currency);
}
/**
@@ -865,7 +1141,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public double getPrice() {
- return this.getKnownProperty("price", Double.class).getValue();
+ return this.entryfee.getAmount();
}
/**
@@ -873,7 +1149,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setPrice(double price) {
- this.setKnownProperty("price", price + "", null);
+ this.setPropertyValueUnchecked("entryfee.amount", price);
}
/**
@@ -884,40 +1160,17 @@ public class MVWorld implements MultiverseWorld {
return this.exempt;
}
- private void saveConfig() {
- if (this.canSave) {
- try {
- this.config.save(new File(this.plugin.getDataFolder(), "worlds.yml"));
- } catch (IOException e) {
- this.plugin.log(Level.SEVERE, "Could not save worlds.yml. Please check your filesystem permissions.");
- }
- }
- }
-
/**
* {@inheritDoc}
*/
@Override
- public boolean setGameMode(String gameMode) {
- return this.setKnownProperty("mode", gameMode, null);
+ public boolean setGameMode(String mode) {
+ return this.setPropertyUnchecked("gameMode", mode);
}
- /**
- * Sets the actual gamemode by iterating through players.
- *
- * gameMode is not used, but it's in the reflection template.
- *
- * Needs a bit o' refactoring.
- *
- * @return True if the gamemodes of players were set successfully. (always)
- */
- public boolean setActualGameMode() {
- for (Player p : this.plugin.getServer().getWorld(this.getName()).getPlayers()) {
- this.plugin.log(Level.FINER, String.format("Setting %s's GameMode to %s",
- p.getName(), this.getKnownProperty("mode", GameMode.class).getValue().toString()));
- this.plugin.getPlayerListener().handleGameMode(p, this);
- }
- return true;
+ @Override
+ public boolean setGameMode(GameMode mode) {
+ return this.setPropertyValueUnchecked("gameMode", mode);
}
/**
@@ -925,7 +1178,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public GameMode getGameMode() {
- return this.getKnownProperty("mode", GameMode.class).getValue();
+ return this.gameMode;
}
/**
@@ -933,20 +1186,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setEnableWeather(boolean weather) {
- this.setKnownProperty("weather", weather + "", null);
- }
-
- /**
- * Used by the active weather-property to set the "actual" property.
- * @return True if the property was successfully set.
- */
- public boolean setActualWeather() {
- // Disable any current weather
- if (!this.getKnownProperty("weather", Boolean.class).getValue()) {
- this.getCBWorld().setStorm(false);
- this.getCBWorld().setThundering(false);
- }
- return true;
+ this.setPropertyValueUnchecked("allowWeather", weather);
}
/**
@@ -954,7 +1194,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean isWeatherEnabled() {
- return this.getKnownProperty("weather", Boolean.class).getValue();
+ return this.allowWeather;
}
/**
@@ -962,15 +1202,15 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean isKeepingSpawnInMemory() {
- return this.getKnownProperty("memory", Boolean.class).getValue();
+ return this.keepSpawnInMemory.get();
}
/**
* {@inheritDoc}
*/
@Override
- public void setHunger(boolean hunger) {
- this.setKnownProperty("hunger", hunger + "", null);
+ public void setKeepSpawnInMemory(boolean value) {
+ this.setPropertyValueUnchecked("keepSpawnInMemory", value);
}
/**
@@ -978,69 +1218,15 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean getHunger() {
- return this.getKnownProperty("hunger", Boolean.class).getValue();
+ return this.hunger;
}
/**
* {@inheritDoc}
*/
@Override
- public void setSpawnLocation(Location l) {
- this.getCBWorld().setSpawnLocation(l.getBlockX(), l.getBlockY(), l.getBlockZ());
- this.getKnownProperty("spawn", Location.class).setValue(l);
- this.saveConfig();
- }
-
- private static final int SPAWN_LOCATION_SEARCH_TOLERANCE = 16;
- private static final int SPAWN_LOCATION_SEARCH_RADIUS = 16;
-
- private Location readSpawnFromConfig(World w) {
- Location spawnLocation = w.getSpawnLocation();
- Location configLocation = this.getSpawnLocation();
-
- // Set the worldspawn to our configspawn
- w.setSpawnLocation(configLocation.getBlockX(), configLocation.getBlockY(), configLocation.getBlockZ());
- SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
- BlockSafety bs = this.plugin.getBlockSafety();
- // Verify that location was safe
- if (!bs.playerCanSpawnHereSafely(configLocation)) {
- if (!this.getAdjustSpawn()) {
- this.plugin.log(Level.FINE, "Spawn location from world.dat file was unsafe!!");
- this.plugin.log(Level.FINE, "NOT adjusting spawn for '" + this.getAlias() + "' because you told me not to.");
- this.plugin.log(Level.FINE, "To turn on spawn adjustment for this world simply type:");
- this.plugin.log(Level.FINE, "/mvm set adjustspawn true " + this.getAlias());
- return configLocation;
- }
- // If it's not, find a better one.
- this.plugin.log(Level.WARNING, "Spawn location from world.dat file was unsafe. Adjusting...");
- this.plugin.log(Level.WARNING, "Original Location: " + plugin.getLocationManipulation().strCoordsRaw(spawnLocation));
- Location newSpawn = teleporter.getSafeLocation(spawnLocation,
- SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
- // I think we could also do this, as I think this is what Notch does.
- // Not sure how it will work in the nether...
- //Location newSpawn = this.spawnLocation.getWorld().getHighestBlockAt(this.spawnLocation).getLocation();
- if (newSpawn != null) {
- this.setSpawnLocation(newSpawn);
- configLocation = this.getSpawnLocation();
- this.plugin.log(Level.INFO, "New Spawn for '" + this.getName()
- + "' is Located at: " + plugin.getLocationManipulation().locationToString(configLocation));
- } else {
- // If it's a standard end world, let's check in a better place:
- Location newerSpawn;
- newerSpawn = bs.getTopBlock(new Location(w, 0, 0, 0));
- if (newerSpawn != null) {
- this.setSpawnLocation(newerSpawn);
- configLocation = this.getSpawnLocation();
- this.plugin.log(Level.INFO, "New Spawn for '" + this.getName()
- + "' is Located at: " + plugin.getLocationManipulation().locationToString(configLocation));
- } else {
- this.plugin.log(Level.SEVERE, "New safe spawn NOT found!!!");
- }
-
-
- }
- }
- return configLocation;
+ public void setHunger(boolean hunger) {
+ this.setPropertyValueUnchecked("hunger", hunger);
}
/**
@@ -1048,7 +1234,15 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public Location getSpawnLocation() {
- return this.getKnownProperty("spawn", Location.class).getValue();
+ return this.spawn.get();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setSpawnLocation(Location l) {
+ this.setPropertyValueUnchecked("spawn", l);
}
/**
@@ -1056,20 +1250,23 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public Difficulty getDifficulty() {
- return this.getCBWorld().getDifficulty();
+ return this.difficulty.get();
}
/**
* {@inheritDoc}
+ *
+ * @deprecated This is deprecated.
*/
@Override
+ @Deprecated
public boolean setDifficulty(String difficulty) {
- if (this.setKnownProperty("diff", difficulty, null)) {
- // Set the difficulty
- this.getCBWorld().setDifficulty(this.getKnownProperty("diff", Difficulty.class).getValue());
- return true;
- }
- return false;
+ return this.setPropertyUnchecked("difficulty", difficulty);
+ }
+
+ @Override
+ public boolean setDifficulty(Difficulty difficulty) {
+ return this.setPropertyValueUnchecked("difficulty", difficulty);
}
/**
@@ -1077,7 +1274,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean getAutoHeal() {
- return this.getKnownProperty("autoheal", Boolean.class).getValue();
+ return this.autoHeal;
}
/**
@@ -1085,7 +1282,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setAutoHeal(boolean heal) {
- this.setKnownProperty("autoheal", heal + "", null);
+ this.setPropertyValueUnchecked("autoHeal", heal);
}
/**
@@ -1093,7 +1290,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setAdjustSpawn(boolean adjust) {
- this.setKnownProperty("adjustspawn", adjust + "", null);
+ this.setPropertyValueUnchecked("adjustSpawn", adjust);
}
/**
@@ -1101,15 +1298,15 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean getAdjustSpawn() {
- return this.getKnownProperty("adjustspawn", Boolean.class).getValue();
+ return this.adjustSpawn;
}
/**
* {@inheritDoc}
*/
@Override
- public void setAutoLoad(boolean autoLoad) {
- this.setKnownProperty("autoload", autoLoad + "", null);
+ public void setAutoLoad(boolean load) {
+ this.setPropertyValueUnchecked("autoLoad", load);
}
/**
@@ -1117,7 +1314,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean getAutoLoad() {
- return this.getKnownProperty("autoload", Boolean.class).getValue();
+ return this.autoLoad;
}
/**
@@ -1125,7 +1322,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public void setBedRespawn(boolean respawn) {
- this.setKnownProperty("bedrespawn", respawn + "", null);
+ this.setPropertyValueUnchecked("bedRespawn", respawn);
}
/**
@@ -1133,7 +1330,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public boolean getBedRespawn() {
- return this.getKnownProperty("bedrespawn", Boolean.class).getValue();
+ return this.bedRespawn;
}
/**
@@ -1141,13 +1338,14 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public String getAllPropertyNames() {
- ChatColor color = ChatColor.AQUA;
- String result = "";
- for (String propertyNames : this.propertyList.keySet()) {
- result += color + propertyNames + " ";
- color = (color == ChatColor.AQUA) ? ChatColor.GOLD : ChatColor.AQUA;
+ ChatColor myColor = ChatColor.AQUA;
+ StringBuilder result = new StringBuilder();
+ Map serialized = this.serialize();
+ for (String key : serialized.keySet()) {
+ result.append(myColor).append(key).append(' ');
+ myColor = (myColor == ChatColor.AQUA) ? ChatColor.GOLD : ChatColor.AQUA;
}
- return result;
+ return result.toString();
}
/**
@@ -1155,32 +1353,15 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public String getTime() {
- long time = this.getCBWorld().getTime();
- // I'm tired, so they get time in 24 hour for now.
- // Someone else can add 12 hr format if they want :P
-
- // BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
- int hours = (int) ((time / 1000 + 8) % 24);
- int minutes = (int) (60 * (time % 1000) / 1000);
- // END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
-
- return String.format("%d:%02d", hours, minutes);
+ return this.getPropertyUnchecked("time");
}
/**
* {@inheritDoc}
*/
@Override
- public WorldType getWorldType() {
- return this.type;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void allowPortalMaking(AllowedPortalType type) {
- this.setKnownProperty("portalform", type.toString(), null);
+ public boolean setTime(String timeAsString) {
+ return this.setPropertyUnchecked("time", timeAsString);
}
/**
@@ -1188,80 +1369,42 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public AllowedPortalType getAllowedPortals() {
- return this.getKnownProperty("portalform", AllowedPortalType.class).getValue();
- }
-
- /**
- * Used by the active time-property to set the "actual" property.
- * @return True if the property was successfully set.
- */
- public boolean setActualTime() {
- return this.setTime(this.getKnownProperty("time", String.class).toString());
+ return portalForm;
}
/**
* {@inheritDoc}
*/
@Override
- // BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
- public boolean setTime(String timeAsString) {
- if (TIME_ALIASES.containsKey(timeAsString.toLowerCase())) {
- return this.setTime(TIME_ALIASES.get(timeAsString.toLowerCase()));
- }
- // Regex that extracts a time in the following formats:
- // 11:11pm, 11:11, 23:11, 1111, 1111p, and the aliases at the top of this file.
- String timeRegex = "(\\d\\d?):?(\\d\\d)(a|p)?m?";
- Pattern pattern = Pattern.compile(timeRegex, Pattern.CASE_INSENSITIVE);
- Matcher matcher = pattern.matcher(timeAsString);
- matcher.find();
- int hour = 0;
- double minute = 0;
- int count = matcher.groupCount();
- if (count >= 2) {
- hour = Integer.parseInt(matcher.group(1));
- minute = Integer.parseInt(matcher.group(2));
- }
- // If there were 4 matches (all, hour, min, ampm)
- if (count == 4) {
- // We want 24 hour time for calcs, but if they
- // added a p[m], turn it into a 24 hr one.
- if (matcher.group(3).equals("p")) {
- hour += 12;
- }
- }
- // Translate 24th hour to 0th hour.
- if (hour == 24) { // SUPPRESS CHECKSTYLE MagicNumberCheck
- hour = 0;
- }
- // Clamp the hour
- if (hour > 23 || hour < 0) {
- return false;
- }
- // Clamp the minute
- if (minute > 59 || minute < 0) {
- return false;
- }
- // 60 seconds in a minute, time needs to be in hrs * 1000, per
- // the bukkit docs.
- double totaltime = (hour + (minute / 60.0)) * 1000;
- // Somehow there's an 8 hour offset...
- totaltime -= 8000;
- if (totaltime < 0) {
- totaltime = 24000 + totaltime;
- }
-
- this.getCBWorld().setTime((long) totaltime);
- return true;
+ public void allowPortalMaking(AllowedPortalType portalType) {
+ this.setPropertyValueUnchecked("portalForm", portalType);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ChatColor getStyle() {
+ return style.getColor();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean setStyle(String style) {
+ return this.setPropertyUnchecked("style", style);
}
- // END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
@Override
public String toString() {
- StringBuilder toStringBuilder = new StringBuilder();
- toStringBuilder.append(this.getClass().getSimpleName());
- toStringBuilder.append('@');
- toStringBuilder.append(this.hashCode());
- toStringBuilder.append(" (Name: '").append(this.getName()).append("')");
- return toStringBuilder.toString();
+ final JSONObject jsonData = new JSONObject();
+ jsonData.put("Name", getName());
+ jsonData.put("Env", getEnvironment().toString());
+ jsonData.put("Type", getWorldType().toString());
+ jsonData.put("Gen", getGenerator());
+ final JSONObject topLevel = new JSONObject();
+ topLevel.put(getClass().getSimpleName() + "@" + hashCode(), jsonData);
+ return topLevel.toString();
}
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java
index f7881a3e..b7f648fc 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java
@@ -7,6 +7,8 @@
package com.onarandombox.MultiverseCore;
+import buscript.Buscript;
+import com.dumptruckman.minecraft.util.Logging;
import com.fernferret.allpay.AllPay;
import com.fernferret.allpay.GenericBank;
import com.onarandombox.MultiverseCore.api.BlockSafety;
@@ -18,7 +20,38 @@ import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
import com.onarandombox.MultiverseCore.api.MultiverseMessaging;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
-import com.onarandombox.MultiverseCore.commands.*;
+import com.onarandombox.MultiverseCore.commands.AnchorCommand;
+import com.onarandombox.MultiverseCore.commands.CheckCommand;
+import com.onarandombox.MultiverseCore.commands.CloneCommand;
+import com.onarandombox.MultiverseCore.commands.ConfigCommand;
+import com.onarandombox.MultiverseCore.commands.ConfirmCommand;
+import com.onarandombox.MultiverseCore.commands.CoordCommand;
+import com.onarandombox.MultiverseCore.commands.CreateCommand;
+import com.onarandombox.MultiverseCore.commands.DebugCommand;
+import com.onarandombox.MultiverseCore.commands.DeleteCommand;
+import com.onarandombox.MultiverseCore.commands.EnvironmentCommand;
+import com.onarandombox.MultiverseCore.commands.GeneratorCommand;
+import com.onarandombox.MultiverseCore.commands.HelpCommand;
+import com.onarandombox.MultiverseCore.commands.ImportCommand;
+import com.onarandombox.MultiverseCore.commands.InfoCommand;
+import com.onarandombox.MultiverseCore.commands.ListCommand;
+import com.onarandombox.MultiverseCore.commands.LoadCommand;
+import com.onarandombox.MultiverseCore.commands.ModifyAddCommand;
+import com.onarandombox.MultiverseCore.commands.ModifyClearCommand;
+import com.onarandombox.MultiverseCore.commands.ModifyCommand;
+import com.onarandombox.MultiverseCore.commands.ModifyRemoveCommand;
+import com.onarandombox.MultiverseCore.commands.ModifySetCommand;
+import com.onarandombox.MultiverseCore.commands.PurgeCommand;
+import com.onarandombox.MultiverseCore.commands.RegenCommand;
+import com.onarandombox.MultiverseCore.commands.ReloadCommand;
+import com.onarandombox.MultiverseCore.commands.RemoveCommand;
+import com.onarandombox.MultiverseCore.commands.ScriptCommand;
+import com.onarandombox.MultiverseCore.commands.SetSpawnCommand;
+import com.onarandombox.MultiverseCore.commands.SpawnCommand;
+import com.onarandombox.MultiverseCore.commands.TeleportCommand;
+import com.onarandombox.MultiverseCore.commands.UnloadCommand;
+import com.onarandombox.MultiverseCore.commands.VersionCommand;
+import com.onarandombox.MultiverseCore.commands.WhoCommand;
import com.onarandombox.MultiverseCore.destination.AnchorDestination;
import com.onarandombox.MultiverseCore.destination.BedDestination;
import com.onarandombox.MultiverseCore.destination.CannonDestination;
@@ -27,52 +60,73 @@ import com.onarandombox.MultiverseCore.destination.ExactDestination;
import com.onarandombox.MultiverseCore.destination.PlayerDestination;
import com.onarandombox.MultiverseCore.destination.WorldDestination;
import com.onarandombox.MultiverseCore.event.MVVersionEvent;
+import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
+import com.onarandombox.MultiverseCore.listeners.MVAsyncPlayerChatListener;
+import com.onarandombox.MultiverseCore.listeners.MVChatListener;
import com.onarandombox.MultiverseCore.listeners.MVEntityListener;
+import com.onarandombox.MultiverseCore.listeners.MVPlayerChatListener;
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
import com.onarandombox.MultiverseCore.listeners.MVPluginListener;
-import com.onarandombox.MultiverseCore.listeners.MVWeatherListener;
import com.onarandombox.MultiverseCore.listeners.MVPortalListener;
import com.onarandombox.MultiverseCore.plugins.DynmapConnector;
-import com.onarandombox.MultiverseCore.utils.*;
+import com.onarandombox.MultiverseCore.listeners.MVWeatherListener;
+import com.onarandombox.MultiverseCore.utils.AnchorManager;
+import com.onarandombox.MultiverseCore.utils.MVMessaging;
+import com.onarandombox.MultiverseCore.utils.MVPermissions;
+import com.onarandombox.MultiverseCore.utils.MVPlayerSession;
+import com.onarandombox.MultiverseCore.utils.SimpleBlockSafety;
+import com.onarandombox.MultiverseCore.utils.SimpleLocationManipulation;
+import com.onarandombox.MultiverseCore.utils.SimpleSafeTTeleporter;
+import com.onarandombox.MultiverseCore.utils.WorldManager;
import com.pneumaticraft.commandhandler.CommandHandler;
-
import me.main__.util.SerializationConfig.SerializationConfig;
-
+import net.milkbowl.vault.economy.Economy;
+import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
+import org.bukkit.World.Environment;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.Configuration;
+import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.server.PluginDisableEvent;
+import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.plugin.PluginManager;
+import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
+import org.mcstats.Metrics;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.Random;
+import java.util.Set;
import java.util.logging.Level;
-import java.util.logging.Logger;
/**
* The implementation of the Multiverse-{@link Core}.
*/
-public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
- private static final int PROTOCOL = 14;
+public class MultiverseCore extends JavaPlugin implements MVPlugin, Core, Listener {
+ private static final int PROTOCOL = 18;
// TODO: Investigate if this one is really needed to be static.
// Doubt it. -- FernFerret
private static Map teleportQueue = new HashMap();
private AnchorManager anchorManager = new AnchorManager(this);
- // TODO please let's make this non-static
private MultiverseCoreConfiguration config;
private DynmapConnector dynmapConnecter;
+ private volatile MultiverseCoreConfiguration config;
/**
* This method is used to find out who is teleporting a player.
@@ -95,7 +149,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
* @param teleportee The name of the player that was teleported.
*/
public static void addPlayerToTeleportQueue(String teleporter, String teleportee) {
- staticLog(Level.FINEST, "Adding mapping '" + teleporter + "' => '" + teleportee + "' to teleport queue");
+ Logging.finest( "Adding mapping '%s' => '%s' to teleport queue", teleporter, teleportee);
teleportQueue.put(teleportee, teleporter);
}
@@ -131,10 +185,6 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
return MultiverseCore.PROTOCOL;
}
- // Useless stuff to keep us going.
- private static final Logger LOGGER = Logger.getLogger("Minecraft");
- private static DebugLog debugLog;
-
// Setup our Map for our Commands using the CommandHandler.
private CommandHandler commandHandler;
@@ -146,22 +196,25 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
// Configurations
private FileConfiguration multiverseConfig = null;
- private MVWorldManager worldManager = new WorldManager(this);
+ private final MVWorldManager worldManager = new WorldManager(this);
// Setup the block/player/entity listener.
- private MVPlayerListener playerListener = new MVPlayerListener(this);
- private MVEntityListener entityListener = new MVEntityListener(this);
- private MVPluginListener pluginListener = new MVPluginListener(this);
- private MVWeatherListener weatherListener = new MVWeatherListener(this);
- private MVPortalListener portalListener = new MVPortalListener(this);
+ private final MVPlayerListener playerListener = new MVPlayerListener(this);
+ private final MVEntityListener entityListener = new MVEntityListener(this);
+ private final MVPluginListener pluginListener = new MVPluginListener(this);
+ private final MVWeatherListener weatherListener = new MVWeatherListener(this);
+ private final MVPortalListener portalListener = new MVPortalListener(this);
+ private MVChatListener chatListener;
// HashMap to contain information relating to the Players.
private HashMap playerSessions;
+ private Economy vaultEco = null;
private GenericBank bank = null;
private AllPay banker;
+ private Buscript buscript;
private int pluginCount;
private DestinationFactory destFactory;
- private SpoutInterface spoutInterface = null;
+ //private SpoutInterface spoutInterface = null;
private MultiverseMessaging messaging;
private BlockSafety blockSafety;
private LocationManipulation locationManipulation;
@@ -173,10 +226,13 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
public void onLoad() {
// Register our config
SerializationConfig.registerAll(MultiverseCoreConfiguration.class);
+ // Register our world
+ SerializationConfig.registerAll(MVWorld.class);
// Create our DataFolder
getDataFolder().mkdirs();
// Setup our Debug Log
- debugLog = new DebugLog("Multiverse-Core", getDataFolder() + File.separator + "debug.log");
+ Logging.init(this);
+ SerializationConfig.initLogging(Logging.getLogger());
// Setup our BlockSafety
this.blockSafety = new SimpleBlockSafety(this);
// Setup our LocationManipulation
@@ -199,10 +255,19 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
* {@inheritDoc}
*/
@Override
+ @Deprecated
public GenericBank getBank() {
return this.bank;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Economy getVaultEconomy() {
+ return vaultEco;
+ }
+
/**
* {@inheritDoc}
*/
@@ -242,19 +307,33 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
if (this.multiverseConfig != null) {
this.worldManager.loadDefaultWorlds();
this.worldManager.loadWorlds(true);
+ Logging.setDebugLevel(getMVConfig().getGlobalDebug());
} else {
this.log(Level.SEVERE, "Your configs were not loaded. Very little will function in Multiverse.");
}
this.anchorManager.loadAnchors();
// Now set the firstspawnworld (after the worlds are loaded):
- this.worldManager.setFirstSpawnWorld(config.getFirstSpawnWorld());
+ this.worldManager.setFirstSpawnWorld(getMVConfig().getFirstSpawnWorld());
try {
- config.setFirstSpawnWorld(this.worldManager.getFirstSpawnWorld().getName());
+ getMVConfig().setFirstSpawnWorld(this.worldManager.getFirstSpawnWorld().getName());
} catch (NullPointerException e) {
// A test that had no worlds loaded was being run. This should never happen in production
}
this.saveMVConfig();
+ // Register async or sync player chat according to config
+ try {
+ Class.forName("org.bukkit.event.player.AsyncPlayerChatEvent");
+ } catch (ClassNotFoundException e) {
+ getMVConfig().setUseAsyncChat(false);
+ }
+ if (getMVConfig().getUseAsyncChat()) {
+ this.chatListener = new MVAsyncPlayerChatListener(this, this.playerListener);
+ } else {
+ this.chatListener = new MVPlayerChatListener(this, this.playerListener);
+ }
+ getServer().getPluginManager().registerEvents(this.chatListener, this);
+ /*
// Check to see if spout was already loaded (most likely):
if (this.getServer().getPluginManager().getPlugin("Spout") != null) {
this.setSpout();
@@ -265,6 +344,146 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
if (this.getServer().getPluginManager().getPlugin("dynmap") != null) {
this.getDynmap();
this.log(Level.INFO, "Dynmap integration enabled.");
+ */
+
+ this.initializeBuscript();
+ this.setupMetrics();
+ // Listen out for vault.
+ getServer().getPluginManager().registerEvents(this, this);
+ this.setupVaultEconomy();
+ }
+
+ private boolean setupVaultEconomy() {
+ if (Bukkit.getPluginManager().getPlugin("Vault") != null) {
+ final RegisteredServiceProvider economyProvider
+ = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
+ if (economyProvider != null) {
+ Logging.fine("Vault economy enabled.");
+ vaultEco = economyProvider.getProvider();
+ } else {
+ Logging.finer("Vault economy not detected.");
+ vaultEco = null;
+ }
+ } else {
+ Logging.finer("Vault was not found.");
+ vaultEco = null;
+ }
+
+ return (vaultEco != null);
+ }
+
+ @EventHandler
+ private void vaultEnabled(PluginEnableEvent event) {
+ if (event.getPlugin() != null && event.getPlugin().getName().equals("Vault")) {
+ setupVaultEconomy();
+ }
+ }
+
+ @EventHandler
+ private void vaultDisabled(PluginDisableEvent event) {
+ if (event.getPlugin() != null && event.getPlugin().getName().equals("Vault")) {
+ Logging.fine("Vault economy disabled");
+ setupVaultEconomy();
+ }
+ }
+
+ /**
+ * Initializes the buscript javascript library.
+ */
+ private void initializeBuscript() {
+ buscript = new Buscript(this);
+ // Add global variable "multiverse" to javascript environment
+ buscript.getGlobalScope().put("multiverse", buscript.getGlobalScope(), this);
+ }
+
+ /**
+ * Plotter for Environment-Values.
+ */
+ private static final class EnvironmentPlotter extends Metrics.Plotter {
+ private MultiverseCore core;
+ private final Environment env;
+
+ public EnvironmentPlotter(MultiverseCore core, Environment env) {
+ super(envToString(env));
+ this.core = core;
+ this.env = env;
+ }
+
+ private static String envToString(Environment env) {
+ return new StringBuilder().append(env.name().toUpperCase().charAt(0))
+ .append(env.name().toLowerCase().substring(1)).toString();
+ }
+
+ @Override
+ public int getValue() {
+ int count = 0;
+ for (MultiverseWorld w : core.getMVWorldManager().getMVWorlds())
+ if (w.getEnvironment() == env)
+ count++;
+ core.log(Level.FINE, String.format("Tracking %d worlds of type %s", count, env));
+ return count;
+ }
+ }
+
+ /**
+ * Plotter for Generator-Values.
+ */
+ private static final class GeneratorPlotter extends Metrics.Plotter {
+ private MultiverseCore core;
+ private final String gen;
+
+ public GeneratorPlotter(MultiverseCore core, String gen) {
+ super(gen);
+ this.core = core;
+ this.gen = gen;
+ }
+
+ @Override
+ public int getValue() {
+ int count = 0;
+ for (MultiverseWorld w : core.getMVWorldManager().getMVWorlds())
+ if (gen.equals(w.getGenerator()))
+ count++;
+ core.log(Level.FINE, String.format("Tracking %d worlds of type %s", count, gen));
+ return count;
+ }
+ }
+
+ private void setupMetrics() {
+ try {
+ Metrics m = new Metrics(this);
+
+ Metrics.Graph envGraph = m.createGraph("worlds_by_env");
+ for (Environment env : Environment.values())
+ envGraph.addPlotter(new EnvironmentPlotter(this, env));
+
+ m.addCustomData(new Metrics.Plotter("Loaded worlds") {
+ @Override
+ public int getValue() {
+ return getMVWorldManager().getMVWorlds().size();
+ }
+ });
+ m.addCustomData(new Metrics.Plotter("Total number of worlds") {
+ @Override
+ public int getValue() {
+ return getMVWorldManager().getMVWorlds().size()
+ + getMVWorldManager().getUnloadedWorlds().size();
+ }
+ });
+
+ Set gens = new HashSet();
+ for (MultiverseWorld w : this.getMVWorldManager().getMVWorlds())
+ gens.add(w.getGenerator());
+ gens.remove(null);
+ gens.remove("null");
+ Metrics.Graph genGraph = m.createGraph("custom_gens");
+ for (String gen : gens)
+ genGraph.addPlotter(new GeneratorPlotter(this, gen));
+
+ m.start();
+ log(Level.FINE, "Metrics have run!");
+ } catch (IOException e) {
+ log(Level.WARNING, "There was an issue while enabling metrics: " + e.getMessage());
}
}
@@ -303,18 +522,18 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
this.multiverseConfig.setDefaults(coreDefaults);
this.multiverseConfig.options().copyDefaults(false);
this.multiverseConfig.options().copyHeader(true);
- this.worldManager.loadWorldConfig(new File(getDataFolder(), "worlds.yml"));
MultiverseCoreConfiguration wantedConfig = null;
try {
wantedConfig = (MultiverseCoreConfiguration) multiverseConfig.get("multiverse-configuration");
- } catch (Exception e) {
- // We're just thinking "no risk no fun" and therefore have to catch and forget this exception
+ } catch (Exception ignore) {
} finally {
config = ((wantedConfig == null) ? new MultiverseCoreConfiguration() : wantedConfig);
}
+ this.migrateWorldConfig();
+ this.worldManager.loadWorldConfig(new File(getDataFolder(), "worlds.yml"));
- this.messaging.setCooldown(config.getMessageCooldown());
+ this.messaging.setCooldown(getMVConfig().getMessageCooldown());
// Remove old values.
this.multiverseConfig.set("enforcegamemodes", null);
@@ -333,42 +552,42 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
private void migrate22Values() {
if (this.multiverseConfig.isSet("worldnameprefix")) {
this.log(Level.INFO, "Migrating 'worldnameprefix'...");
- this.config.setPrefixChat(this.multiverseConfig.getBoolean("worldnameprefix"));
+ this.getMVConfig().setPrefixChat(this.multiverseConfig.getBoolean("worldnameprefix"));
this.multiverseConfig.set("worldnameprefix", null);
}
if (this.multiverseConfig.isSet("firstspawnworld")) {
this.log(Level.INFO, "Migrating 'firstspawnworld'...");
- this.config.setFirstSpawnWorld(this.multiverseConfig.getString("firstspawnworld"));
+ this.getMVConfig().setFirstSpawnWorld(this.multiverseConfig.getString("firstspawnworld"));
this.multiverseConfig.set("firstspawnworld", null);
}
if (this.multiverseConfig.isSet("enforceaccess")) {
this.log(Level.INFO, "Migrating 'enforceaccess'...");
- this.config.setEnforceAccess(this.multiverseConfig.getBoolean("enforceaccess"));
+ this.getMVConfig().setEnforceAccess(this.multiverseConfig.getBoolean("enforceaccess"));
this.multiverseConfig.set("enforceaccess", null);
}
if (this.multiverseConfig.isSet("displaypermerrors")) {
this.log(Level.INFO, "Migrating 'displaypermerrors'...");
- this.config.setDisplayPermErrors(this.multiverseConfig.getBoolean("displaypermerrors"));
+ this.getMVConfig().setDisplayPermErrors(this.multiverseConfig.getBoolean("displaypermerrors"));
this.multiverseConfig.set("displaypermerrors", null);
}
if (this.multiverseConfig.isSet("teleportintercept")) {
this.log(Level.INFO, "Migrating 'teleportintercept'...");
- this.config.setTeleportIntercept(this.multiverseConfig.getBoolean("teleportintercept"));
+ this.getMVConfig().setTeleportIntercept(this.multiverseConfig.getBoolean("teleportintercept"));
this.multiverseConfig.set("teleportintercept", null);
}
if (this.multiverseConfig.isSet("firstspawnoverride")) {
this.log(Level.INFO, "Migrating 'firstspawnoverride'...");
- this.config.setFirstSpawnOverride(this.multiverseConfig.getBoolean("firstspawnoverride"));
+ this.getMVConfig().setFirstSpawnOverride(this.multiverseConfig.getBoolean("firstspawnoverride"));
this.multiverseConfig.set("firstspawnoverride", null);
}
if (this.multiverseConfig.isSet("messagecooldown")) {
this.log(Level.INFO, "Migrating 'messagecooldown'...");
- this.config.setMessageCooldown(this.multiverseConfig.getInt("messagecooldown"));
+ this.getMVConfig().setMessageCooldown(this.multiverseConfig.getInt("messagecooldown"));
this.multiverseConfig.set("messagecooldown", null);
}
if (this.multiverseConfig.isSet("debug")) {
this.log(Level.INFO, "Migrating 'debug'...");
- this.config.setGlobalDebug(this.multiverseConfig.getInt("debug"));
+ this.getMVConfig().setGlobalDebug(this.multiverseConfig.getInt("debug"));
this.multiverseConfig.set("debug", null);
}
if (this.multiverseConfig.isSet("version")) {
@@ -377,6 +596,216 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
}
}
+ /**
+ * Migrate the worlds.yml to SerializationConfig.
+ */
+ private void migrateWorldConfig() { // SUPPRESS CHECKSTYLE: MethodLength
+ FileConfiguration wconf = YamlConfiguration
+ .loadConfiguration(new File(getDataFolder(), "worlds.yml"));
+
+ if (!wconf.isConfigurationSection("worlds")) { // empty config
+ this.log(Level.FINE, "No worlds to migrate!");
+ return;
+ }
+
+ Map values = wconf.getConfigurationSection("worlds").getValues(false);
+
+ boolean wasChanged = false;
+ Map newValues = new LinkedHashMap(values.size());
+ for (Map.Entry entry : values.entrySet()) {
+ if (entry.getValue() instanceof MVWorld) {
+ // fine
+ newValues.put(entry.getKey(), entry.getValue());
+ } else if (entry.getValue() instanceof ConfigurationSection) {
+ this.log(Level.FINE, "Migrating: " + entry.getKey());
+ // we have to migrate this
+ MVWorld world = new MVWorld(Collections.EMPTY_MAP);
+ ConfigurationSection section = (ConfigurationSection) entry.getValue();
+
+ // migrate animals and monsters
+ if (section.isConfigurationSection("animals")) {
+ ConfigurationSection animalSection = section.getConfigurationSection("animals");
+ if (animalSection.contains("spawn")) {
+ if (animalSection.isBoolean("spawn"))
+ world.setAllowAnimalSpawn(animalSection.getBoolean("spawn"));
+ else
+ world.setAllowAnimalSpawn(Boolean.parseBoolean(animalSection.getString("spawn")));
+ }
+ if (animalSection.isList("exceptions")) {
+ world.getAnimalList().clear();
+ world.getAnimalList().addAll(animalSection.getStringList("exceptions"));
+ }
+ }
+ if (section.isConfigurationSection("monsters")) {
+ ConfigurationSection monsterSection = section.getConfigurationSection("monsters");
+ if (monsterSection.contains("spawn")) {
+ if (monsterSection.isBoolean("spawn"))
+ world.setAllowMonsterSpawn(monsterSection.getBoolean("spawn"));
+ else
+ world.setAllowMonsterSpawn(Boolean.parseBoolean(monsterSection.getString("spawn")));
+ }
+ if (monsterSection.isList("exceptions")) {
+ world.getMonsterList().clear();
+ world.getMonsterList().addAll(monsterSection.getStringList("exceptions"));
+ }
+ }
+
+ // migrate entryfee
+ if (section.isConfigurationSection("entryfee")) {
+ ConfigurationSection feeSection = section.getConfigurationSection("entryfee");
+ if (feeSection.isInt("currency"))
+ world.setCurrency(feeSection.getInt("currency"));
+
+ if (feeSection.isDouble("amount"))
+ world.setPrice(feeSection.getDouble("amount"));
+ else if (feeSection.isInt("amount"))
+ world.setPrice(feeSection.getInt("amount"));
+ }
+
+ // migrate pvp
+ if (section.isBoolean("pvp")) {
+ world.setPVPMode(section.getBoolean("pvp"));
+ }
+
+ // migrate alias
+ if (section.isConfigurationSection("alias")) {
+ ConfigurationSection aliasSection = section.getConfigurationSection("alias");
+ if (aliasSection.isString("color"))
+ world.setColor(aliasSection.getString("color"));
+ if (aliasSection.isString("name"))
+ world.setAlias(aliasSection.getString("name"));
+ }
+
+ // migrate worldblacklist
+ if (section.isList("worldblacklist")) {
+ world.getWorldBlacklist().clear();
+ world.getWorldBlacklist().addAll(section.getStringList("worldblacklist"));
+ }
+
+ // migrate scale
+ if (section.isDouble("scale")) {
+ world.setScaling(section.getDouble("scale"));
+ }
+
+ // migrate gamemode
+ if (section.isString("gamemode")) {
+ try {
+ world.setPropertyValue("gamemode", section.getString("gamemode"));
+ } catch (PropertyDoesNotExistException e) {
+ throw new RuntimeException("Who forgot to update the migrator?", e);
+ }
+ }
+
+ // migrate hunger
+ if (section.isBoolean("hunger")) {
+ world.setHunger(section.getBoolean("hunger"));
+ }
+
+ // migrate hidden
+ if (section.isBoolean("hidden")) {
+ world.setHidden(section.getBoolean("hidden"));
+ }
+
+ // migrate autoheal
+ if (section.isBoolean("autoheal")) {
+ world.setAutoHeal(section.getBoolean("autoheal"));
+ }
+
+ // migrate portalform
+ if (section.isString("portalform")) {
+ try {
+ world.setPropertyValue("portalform", section.getString("portalform"));
+ } catch (PropertyDoesNotExistException e) {
+ throw new RuntimeException("Who forgot to update the migrator?", e);
+ }
+ }
+
+ // migrate environment
+ if (section.isString("environment")) {
+ try {
+ world.setPropertyValue("environment", section.getString("environment"));
+ } catch (PropertyDoesNotExistException e) {
+ throw new RuntimeException("Who forgot to update the migrator?", e);
+ }
+ }
+
+ // migrate generator
+ if (section.isString("generator")) {
+ world.setGenerator(section.getString("generator"));
+ }
+
+ // migrate seed
+ if (section.isLong("seed")) {
+ world.setSeed(section.getLong("seed"));
+ }
+
+ // migrate weather
+ if (section.isBoolean("allowweather")) {
+ world.setEnableWeather(section.getBoolean("allowweather"));
+ }
+
+ // migrate adjustspawn
+ if (section.isBoolean("adjustspawn")) {
+ world.setAdjustSpawn(section.getBoolean("adjustspawn"));
+ }
+
+ // migrate autoload
+ if (section.isBoolean("autoload")) {
+ world.setAutoLoad(section.getBoolean("autoload"));
+ }
+
+ // migrate bedrespawn
+ if (section.isBoolean("bedrespawn")) {
+ world.setBedRespawn(section.getBoolean("bedrespawn"));
+ }
+
+ // migrate spawn
+ if (section.isConfigurationSection("spawn")) {
+ ConfigurationSection spawnSect = section.getConfigurationSection("spawn");
+ Location spawnLoc = world.getSpawnLocation();
+ if (spawnSect.isDouble("yaw"))
+ spawnLoc.setYaw((float) spawnSect.getDouble("yaw"));
+ if (spawnSect.isDouble("pitch"))
+ spawnLoc.setPitch((float) spawnSect.getDouble("pitch"));
+ if (spawnSect.isDouble("x"))
+ spawnLoc.setX(spawnSect.getDouble("x"));
+ if (spawnSect.isDouble("y"))
+ spawnLoc.setY(spawnSect.getDouble("y"));
+ if (spawnSect.isDouble("z"))
+ spawnLoc.setZ(spawnSect.getDouble("z"));
+
+ world.setSpawnLocation(spawnLoc);
+ }
+
+ newValues.put(entry.getKey(), world);
+ wasChanged = true;
+ } else {
+ // huh?
+ this.log(Level.WARNING, "Removing unknown entry in the config: " + entry);
+ // just don't add to newValues
+ wasChanged = true;
+ }
+ }
+
+ if (wasChanged) {
+ // clear config
+ wconf.set("worlds", null);
+
+ // and rebuild it
+ ConfigurationSection rootSection = wconf.createSection("worlds");
+ for (Map.Entry entry : newValues.entrySet()) {
+ rootSection.set(entry.getKey(), entry.getValue());
+ }
+
+ try {
+ wconf.save(new File(getDataFolder(), "worlds.yml"));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
/**
* {@inheritDoc}
*/
@@ -395,6 +824,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
this.commandHandler.registerCommand(new ListCommand(this));
this.commandHandler.registerCommand(new InfoCommand(this));
this.commandHandler.registerCommand(new CreateCommand(this));
+ this.commandHandler.registerCommand(new CloneCommand(this));
this.commandHandler.registerCommand(new ImportCommand(this));
this.commandHandler.registerCommand(new ReloadCommand(this));
this.commandHandler.registerCommand(new SetSpawnCommand(this));
@@ -423,6 +853,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
this.commandHandler.registerCommand(new DebugCommand(this));
this.commandHandler.registerCommand(new GeneratorCommand(this));
this.commandHandler.registerCommand(new CheckCommand(this));
+ this.commandHandler.registerCommand(new ScriptCommand(this));
}
/**
@@ -430,10 +861,11 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*/
@Override
public void onDisable() {
- debugLog.close();
+ this.saveMVConfigs();
this.banker = null;
this.bank = null;
log(Level.INFO, "- Disabled");
+ Logging.shutdown();
}
/**
@@ -444,7 +876,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
if (this.playerSessions.containsKey(player.getName())) {
return this.playerSessions.get(player.getName());
} else {
- this.playerSessions.put(player.getName(), new MVPlayerSession(player, config));
+ this.playerSessions.put(player.getName(), new MVPlayerSession(player, getMVConfig()));
return this.playerSessions.get(player.getName());
}
}
@@ -479,7 +911,17 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
}
ArrayList allArgs = new ArrayList(Arrays.asList(args));
allArgs.add(0, command.getName());
- return this.commandHandler.locateAndRunCommand(sender, allArgs, config.getDisplayPermErrors());
+ try {
+ return this.commandHandler.locateAndRunCommand(sender, allArgs, getMVConfig().getDisplayPermErrors());
+ } catch (Exception e) {
+ e.printStackTrace();
+ sender.sendMessage(ChatColor.RED + "An internal error occurred when attempting to perform this command.");
+ if (sender.isOp())
+ sender.sendMessage(ChatColor.RED + "Details were printed to the server console and logs, please add that to your bug report.");
+ else
+ sender.sendMessage(ChatColor.RED + "Try again and contact the server owner or an admin if this problem persists.");
+ return true;
+ }
}
/**
@@ -487,7 +929,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*/
@Override
public void log(Level level, String msg) {
- staticLog(level, msg);
+ Logging.log(level, msg);
}
/**
@@ -495,33 +937,28 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*
* @param level The Log-{@link Level}.
* @param msg The message to log.
+ *
+ * @deprecated Replaced by {@link Logging}. Please refrain from using this from a third party plugin as the
+ * messages will appear to originate from Multiverse-Core.
*/
+ @Deprecated
public static void staticLog(Level level, String msg) {
- if (level == Level.FINE && MultiverseCoreConfiguration.getInstance().getGlobalDebug() >= 1) {
- staticDebugLog(Level.INFO, msg);
- return;
- } else if (level == Level.FINER && MultiverseCoreConfiguration.getInstance().getGlobalDebug() >= 2) {
- staticDebugLog(Level.INFO, msg);
- return;
- } else if (level == Level.FINEST && MultiverseCoreConfiguration.getInstance().getGlobalDebug() >= 3) {
- staticDebugLog(Level.INFO, msg);
- return;
- } else if (level != Level.FINE && level != Level.FINER && level != Level.FINEST) {
- LOGGER.log(level, String.format("%s %s", LOG_TAG, msg));
- debugLog.log(level, String.format("%s %s", LOG_TAG, msg));
- }
+ Logging.log(level, msg);
}
/**
- * Print messages to the Debug Log, if the servers in Debug Mode then we also wan't to print the messages to the
+ * Print messages to the Debug Log, if the servers in Debug Mode then we also want to print the messages to the
* standard Server Console.
*
* @param level The Log-{@link Level}
* @param msg The message
+ *
+ * @deprecated Replaced by {@link Logging}. Please refrain from using this from a third party plugin as the
+ * messages will appear to originate from Multiverse-Core.
*/
+ @Deprecated
public static void staticDebugLog(Level level, String msg) {
- LOGGER.log(level, "[MVCore-Debug] " + msg);
- debugLog.log(level, "[MVCore-Debug] " + msg);
+ Logging.log(level, msg);
}
/**
@@ -617,6 +1054,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
* {@inheritDoc}
*/
@Override
+ @Deprecated
public AllPay getBanker() {
return this.banker;
}
@@ -625,6 +1063,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
* {@inheritDoc}
*/
@Override
+ @Deprecated
public void setBank(GenericBank bank) {
this.bank = bank;
}
@@ -670,9 +1109,10 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
this.serverFolder = newServerFolder;
}
+ /*
/**
* Initializes Spout.
- */
+ * /
public void setSpout() {
this.spoutInterface = new SpoutInterface();
this.commandHandler.registerCommand(new SpoutCommand(this));
@@ -682,10 +1122,11 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
* Gets our {@link SpoutInterface}.
*
* @return The {@link SpoutInterface} we're using.
- */
+ * /
public SpoutInterface getSpout() {
return this.spoutInterface;
}
+ */
/**
* {@inheritDoc}
@@ -704,6 +1145,15 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
return this.playerListener;
}
+ /**
+ * Gets the {@link MVChatListener}.
+ *
+ * @return The {@link MVChatListener}.
+ */
+ public MVChatListener getChatListener() {
+ return this.chatListener;
+ }
+
/**
* Gets the {@link MVEntityListener}.
*
@@ -729,7 +1179,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*/
public boolean saveMVConfig() {
try {
- this.multiverseConfig.set("multiverse-configuration", config);
+ this.multiverseConfig.set("multiverse-configuration", getMVConfig());
this.multiverseConfig.save(new File(getDataFolder(), "config.yml"));
return true;
} catch (IOException e) {
@@ -766,38 +1216,27 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
return this.worldManager.deleteWorld(name);
}
+ /**
+ * NOT deprecated for the time as queued commands use this.
+ * However, this is not in the API and other plugins should therefore not use it.
+ *
+ * @param oldName World to copy
+ * @param newName World to create
+ * @param generator The Custom generator plugin to use.
+ * @return True if success, false if fail.
+ */
+ public Boolean cloneWorld(String oldName, String newName, String generator) {
+ return this.worldManager.cloneWorld(oldName, newName, generator);
+ }
+
/**
* {@inheritDoc}
+ * @deprecated This is deprecated!
*/
@Override
+ @Deprecated
public Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed) {
- MultiverseWorld world = this.worldManager.getMVWorld(name);
- if (world == null) {
- return false;
- }
-
- List ps = world.getCBWorld().getPlayers();
-
- if (useNewSeed) {
- // Set the worldseed.
- if (randomSeed) {
- Random random = new Random();
- Long newseed = random.nextLong();
- seed = newseed.toString();
- }
- ((WorldManager) this.worldManager).getConfigWorlds().set("worlds." + name + ".seed", seed);
- }
- if (this.worldManager.deleteWorld(name, false)) {
- this.worldManager.loadWorlds(false);
- SafeTTeleporter teleporter = this.getSafeTTeleporter();
- Location newSpawn = this.getServer().getWorld(name).getSpawnLocation();
- // Send all players that were in the old world, BACK to it!
- for (Player p : ps) {
- teleporter.safelyTeleport(null, p, newSpawn, true);
- }
- return true;
- }
- return false;
+ return this.worldManager.regenWorld(name, useNewSeed, randomSeed, seed);
}
/**
@@ -889,5 +1328,9 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
public void setDynmap() {
this.dynmapConnecter = new DynmapConnector(this.getServer().getPluginManager().getPlugin("dynmap"), this);
+
+ @Override
+ public Buscript getScriptAPI() {
+ return buscript;
}
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCoreConfiguration.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCoreConfiguration.java
index 25e95cfc..29f8a471 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCoreConfiguration.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCoreConfiguration.java
@@ -1,12 +1,13 @@
package com.onarandombox.MultiverseCore;
-import java.util.Map;
-
+import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
-
+import me.main__.util.SerializationConfig.NoSuchPropertyException;
import me.main__.util.SerializationConfig.Property;
import me.main__.util.SerializationConfig.SerializationConfig;
+import java.util.Map;
+
/**
* Our configuration.
*/
@@ -21,6 +22,13 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
MultiverseCoreConfiguration.instance = instance;
}
+ /**
+ * @return True if the static instance of config is set.
+ */
+ public static boolean isSet() {
+ return instance != null;
+ }
+
/**
* Gets the statically saved instance.
* @return The statically saved instance.
@@ -32,25 +40,27 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
}
@Property
- private boolean enforceaccess;
+ private volatile boolean enforceaccess;
@Property
- private boolean prefixchat;
+ private volatile boolean prefixchat;
@Property
- private boolean teleportintercept;
+ private volatile boolean useasyncchat;
@Property
- private boolean firstspawnoverride;
+ private volatile boolean teleportintercept;
@Property
- private boolean displaypermerrors;
+ private volatile boolean firstspawnoverride;
@Property
- private int globaldebug;
+ private volatile boolean displaypermerrors;
@Property
- private int messagecooldown;
+ private volatile int globaldebug;
@Property
- private double version;
+ private volatile int messagecooldown;
@Property
- private String firstspawnworld;
+ private volatile double version;
@Property
- private int teleportcooldown;
+ private volatile String firstspawnworld;
+ @Property
+ private volatile int teleportcooldown;
public MultiverseCoreConfiguration() {
super();
@@ -66,9 +76,10 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
* {@inheritDoc}
*/
@Override
- public void setDefaults() {
+ protected void setDefaults() {
// BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
enforceaccess = false;
+ useasyncchat = true;
prefixchat = true;
teleportintercept = true;
firstspawnoverride = true;
@@ -80,6 +91,18 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean setConfigProperty(String property, String value) {
+ try {
+ return this.setProperty(property, value, true);
+ } catch (NoSuchPropertyException e) {
+ return false;
+ }
+ }
+
// And here we go:
/**
@@ -176,6 +199,7 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
@Override
public void setGlobalDebug(int globalDebug) {
this.globaldebug = globalDebug;
+ Logging.setDebugLevel(globalDebug);
}
/**
@@ -241,4 +265,14 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
public void setTeleportCooldown(int teleportCooldown) {
this.teleportcooldown = teleportCooldown;
}
+
+ @Override
+ public void setUseAsyncChat(boolean useAsyncChat) {
+ this.useasyncchat = useAsyncChat;
+ }
+
+ @Override
+ public boolean getUseAsyncChat() {
+ return this.useasyncchat;
+ }
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/BlockSafety.java b/src/main/java/com/onarandombox/MultiverseCore/api/BlockSafety.java
index db25a17e..5dc4f7eb 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/api/BlockSafety.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/api/BlockSafety.java
@@ -35,6 +35,13 @@ public interface BlockSafety {
*/
boolean playerCanSpawnHereSafely(Location l);
+ /**
+ * Gets a safe bed spawn location OR null if the bed is invalid.
+ * @param l The location of the bead head (block with the pillow on it).
+ * @return Safe location around the bed or null if no location was found.
+ */
+ Location getSafeBedSpawn(Location l);
+
/**
* Gets the location of the top block at the specified {@link Location}.
* @param l Any {@link Location}.
diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/Core.java b/src/main/java/com/onarandombox/MultiverseCore/api/Core.java
index 01c684d0..f8c59283 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/api/Core.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/api/Core.java
@@ -7,11 +7,19 @@
package com.onarandombox.MultiverseCore.api;
+import buscript.Buscript;
import com.fernferret.allpay.AllPay;
import com.fernferret.allpay.GenericBank;
import com.onarandombox.MultiverseCore.destination.DestinationFactory;
-import com.onarandombox.MultiverseCore.utils.*;
+import com.onarandombox.MultiverseCore.utils.AnchorManager;
+import com.onarandombox.MultiverseCore.utils.MVPermissions;
+import com.onarandombox.MultiverseCore.utils.MVPlayerSession;
+import com.onarandombox.MultiverseCore.utils.SimpleBlockSafety;
+import com.onarandombox.MultiverseCore.utils.SimpleLocationManipulation;
+import com.onarandombox.MultiverseCore.utils.SimpleSafeTTeleporter;
+import com.onarandombox.MultiverseCore.utils.WorldManager;
import com.pneumaticraft.commandhandler.CommandHandler;
+import net.milkbowl.vault.economy.Economy;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
@@ -35,9 +43,18 @@ public interface Core {
* Gets the Banking system that Multiverse-Core has hooked into.
*
* @return A {@link GenericBank} that can be used for payments.
+ * @deprecated Now using vault, see {@link #getVaultEconomy}
*/
+ @Deprecated
GenericBank getBank();
+ /**
+ * Returns the Vault economy system if Vault is present and has an economy system enabled.
+ *
+ * @return The vault economy system or null if not configured.
+ */
+ Economy getVaultEconomy();
+
/**
* Reloads the Multiverse Configuration files:
* worlds.yml and config.yml.
@@ -128,21 +145,28 @@ public interface Core {
* @param seed The seed of the world.
*
* @return True if success, false if fail.
+ *
+ * @deprecated Use {@link MVWorldManager#regenWorld(String, boolean, boolean, String)} instead.
*/
+ @Deprecated
Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed);
/**
* Sets the {@link GenericBank}-Bank AllPay is using.
*
* @param bank The new {@link GenericBank}
+ * @deprecated Now using vault, see {@link #getVaultEconomy}
*/
+ @Deprecated
void setBank(GenericBank bank);
/**
* Gets this plugin's {@link AllPay}-Banker.
*
* @return An {@link AllPay}-Banker
+ * @deprecated Now using vault, see {@link #getVaultEconomy}
*/
+ @Deprecated
AllPay getBanker();
/**
@@ -222,4 +246,11 @@ public interface Core {
* @return The configuration.
*/
MultiverseCoreConfig getMVConfig();
+
+ /**
+ * Gets the buscript object for Multiverse. This is what handles Javascript processing.
+ *
+ * @return The Multiverse buscript object.
+ */
+ Buscript getScriptAPI();
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java
index f13da921..597ee32b 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java
@@ -60,6 +60,16 @@ public interface MVWorldManager {
boolean addWorld(String name, Environment env, String seedString, WorldType type, Boolean generateStructures,
String generator, boolean useSpawnAdjust);
+ /**
+ * Make a copy of a world.
+ *
+ * @param oldName Name of world to be copied
+ * @param newName Name of world to be created
+ * @param generator The Custom generator plugin to use.
+ * @return True if the world is copied successfully, false if not.
+ */
+ boolean cloneWorld(String oldName, String newName, String generator);
+
/**
* Remove the world from the Multiverse list, from the
* config and deletes the folder.
@@ -245,4 +255,16 @@ public interface MVWorldManager {
* @return The {@link MultiverseWorld} new players should spawn in.
*/
MultiverseWorld getFirstSpawnWorld();
+
+ /**
+ * Regenerates a world.
+ *
+ * @param name Name of the world to regenerate
+ * @param useNewSeed If a new seed should be used
+ * @param randomSeed IF the new seed should be random
+ * @param seed The seed of the world.
+ *
+ * @return True if success, false if fail.
+ */
+ boolean regenWorld(String name, boolean useNewSeed, boolean randomSeed, String seed);
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseCoreConfig.java b/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseCoreConfig.java
index 25f6fad4..abd9ace0 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseCoreConfig.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseCoreConfig.java
@@ -12,7 +12,7 @@ public interface MultiverseCoreConfig extends ConfigurationSerializable {
* @param value The value.
* @return True on success, false if the operation failed.
*/
- boolean setProperty(String property, String value);
+ boolean setConfigProperty(String property, String value);
/**
* Sets portalCooldown.
@@ -133,4 +133,16 @@ public interface MultiverseCoreConfig extends ConfigurationSerializable {
* @return enforceAccess.
*/
boolean getEnforceAccess();
+
+ /**
+ * Sets useasyncchat.
+ * @param useAsyncChat The new value.
+ */
+ void setUseAsyncChat(boolean useAsyncChat);
+
+ /**
+ * Gets useasyncchat.
+ * @return useasyncchat.
+ */
+ boolean getUseAsyncChat();
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/MultiversePlugin.java b/src/main/java/com/onarandombox/MultiverseCore/api/MultiversePlugin.java
new file mode 100644
index 00000000..a6a064b8
--- /dev/null
+++ b/src/main/java/com/onarandombox/MultiverseCore/api/MultiversePlugin.java
@@ -0,0 +1,161 @@
+package com.onarandombox.MultiverseCore.api;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.logging.Level;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import com.onarandombox.MultiverseCore.MultiverseCore;
+import com.onarandombox.MultiverseCore.utils.DebugLog;
+import com.pneumaticraft.commandhandler.CommandHandler;
+
+/**
+ * Make things easier for MV-Plugins!
+ */
+public abstract class MultiversePlugin extends JavaPlugin implements MVPlugin {
+ private MultiverseCore core;
+ /**
+ * Prefix for standard log entrys.
+ */
+ protected String logTag;
+ private DebugLog debugLog;
+
+ /**
+ * {@inheritDoc}
+ *
+ * Note: You can't override this, use {@link #onPluginEnable()} instead!
+ * @see #onPluginEnable()
+ */
+ @Override
+ public final void onEnable() {
+ MultiverseCore theCore = (MultiverseCore) this.getServer().getPluginManager().getPlugin("Multiverse-Core");
+ if (theCore == null) {
+ this.getLogger().severe("Core not found! The plugin dev needs to add a dependency!");
+ this.getLogger().severe("Disabling!");
+ this.getServer().getPluginManager().disablePlugin(this);
+ return;
+ }
+ if (theCore.getProtocolVersion() < this.getProtocolVersion()) {
+ this.getLogger().severe("You need a newer version of Multiverse-Core!");
+ this.getLogger().severe("Disabling!");
+ this.getServer().getPluginManager().disablePlugin(this);
+ return;
+ }
+ this.setCore(theCore);
+
+ this.getServer().getLogger().info(String.format("%s - Version %s enabled - By %s",
+ this.getDescription().getName(), this.getDescription().getVersion(), getAuthors()));
+ getDataFolder().mkdirs();
+ File debugLogFile = new File(getDataFolder(), "debug.log");
+ try {
+ debugLogFile.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ debugLog = new DebugLog(this.getDescription().getName(), getDataFolder() + File.separator + "debug.log");
+ debugLog.setTag(String.format("[%s-Debug]", this.getDescription().getName()));
+
+ this.onPluginEnable();
+ }
+
+ /**
+ * Parse the Authors Array into a readable String with ',' and 'and'.
+ *
+ * @return The readable authors-{@link String}
+ */
+ protected String getAuthors() {
+ String authors = "";
+ List auths = this.getDescription().getAuthors();
+ if (auths.size() == 0) {
+ return "";
+ }
+
+ if (auths.size() == 1) {
+ return auths.get(0);
+ }
+
+ for (int i = 0; i < auths.size(); i++) {
+ if (i == this.getDescription().getAuthors().size() - 1) {
+ authors += " and " + this.getDescription().getAuthors().get(i);
+ } else {
+ authors += ", " + this.getDescription().getAuthors().get(i);
+ }
+ }
+ return authors.substring(2);
+ }
+
+ /**
+ * Called when the plugin is enabled.
+ * @see #onEnable()
+ */
+ protected abstract void onPluginEnable();
+
+ /**
+ * You can register commands here.
+ * @param handler The CommandHandler.
+ */
+ protected abstract void registerCommands(CommandHandler handler);
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!this.isEnabled()) {
+ sender.sendMessage("This plugin is Disabled!");
+ return true;
+ }
+
+ ArrayList allArgs = new ArrayList(args.length + 1);
+ allArgs.add(command.getName());
+ allArgs.addAll(Arrays.asList(args));
+ return this.getCore().getCommandHandler().locateAndRunCommand(sender, allArgs);
+ }
+
+ @Override
+ public void log(Level level, String msg) {
+ int debugLevel = this.getCore().getMVConfig().getGlobalDebug();
+ if ((level == Level.FINE && debugLevel >= 1) || (level == Level.FINER && debugLevel >= 2)
+ || (level == Level.FINEST && debugLevel >= 3)) {
+ debugLog.log(level, msg);
+ } else if (level != Level.FINE && level != Level.FINER && level != Level.FINEST) {
+ String message = new StringBuilder(getLogTag()).append(msg).toString();
+ this.getServer().getLogger().log(level, message);
+ debugLog.log(level, message);
+ }
+ }
+
+ private String getLogTag() {
+ if (logTag == null)
+ logTag = String.format("[%s]", this.getDescription().getName());
+ return logTag;
+ }
+
+ /**
+ * Sets the debug log-tag.
+ * @param tag The new tag.
+ */
+ protected final void setDebugLogTag(String tag) {
+ this.debugLog.setTag(tag);
+ }
+
+ @Override
+ public final String dumpVersionInfo(String buffer) {
+ throw new UnsupportedOperationException("This is gone.");
+ }
+
+ @Override
+ public final MultiverseCore getCore() {
+ if (this.core == null)
+ throw new IllegalStateException("Core is null!");
+ return this.core;
+ }
+
+ @Override
+ public final void setCore(MultiverseCore core) {
+ this.core = core;
+ }
+}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseWorld.java b/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseWorld.java
index 46961803..2266594c 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseWorld.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseWorld.java
@@ -7,7 +7,6 @@
package com.onarandombox.MultiverseCore.api;
-import com.onarandombox.MultiverseCore.configuration.MVConfigProperty;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
@@ -26,7 +25,6 @@ import java.util.List;
* The API for a Multiverse Handled World.
*/
public interface MultiverseWorld {
-
/**
* Returns the Bukkit world object that this world describes.
*
@@ -35,79 +33,24 @@ public interface MultiverseWorld {
World getCBWorld();
/**
- * Adds the property to the given value.
- * It will throw a PropertyDoesNotExistException if the property is not found.
+ * Gets the name of this world. The name cannot be changed.
+ *
+ * Note for plugin developers: Usually {@link #getAlias()}
+ * is what you want to use instead of this method.
*
- * @param property The name of a world property to set.
- * @param value A value in string representation, it will be parsed to the correct type.
- * @param sender The sender who wants this value to be set.
- * @return True if the value was set, false if not.
- * @throws PropertyDoesNotExistException Thrown if the property was not found in the world.
+ * @return The name of the world as a String.
*/
- boolean setProperty(String property, String value, CommandSender sender) throws PropertyDoesNotExistException;
+ String getName();
/**
- * Gets the actual MVConfigProperty from this world.
- * It will throw a PropertyDoesNotExistException if the property is not found.
+ * Gets the type of this world. As of 1.2 this will be:
+ * FLAT, NORMAL or VERSION_1_1
+ *
+ * This is not the generator.
*
- * @param property The name of a world property to get.
- * @return A valid MVWorldProperty.
- * @throws PropertyDoesNotExistException Thrown if the property was not found in the world.
- * @deprecated Use {@link #getProperty(String, Class)} instead
+ * @return The Type of this world.
*/
- @Deprecated
- MVConfigProperty> getProperty(String property) throws PropertyDoesNotExistException;
-
- /**
- * Gets the string representation of a property.
- * It will throw a PropertyDoesNotExistException if the property is not found.
- *
- * @param property The name of a world property to get.
- * @return A valid MVWorldProperty.
- * @throws PropertyDoesNotExistException Thrown if the property was not found in the world.
- */
- String getPropertyValue(String property) throws PropertyDoesNotExistException;
-
- /**
- * Gets the actual MVConfigProperty from this world.
- * It will throw a PropertyDoesNotExistException if the property is not found.
- *
- * @param property The name of a world property to get.
- * @param expected The type of the expected property. Use Object.class if this doesn't matter for you.
- * @param The type of the expected property.
- *
- * @return A valid MVWorldProperty.
- *
- * @throws PropertyDoesNotExistException Thrown if the property was not found in the world.
- */
- MVConfigProperty getProperty(String property, Class expected) throws PropertyDoesNotExistException;
-
- /**
- * Removes all values from the given property. The property must be a {@link com.onarandombox.MultiverseCore.enums.AddProperties}.
- *
- * @param property The name of a {@link com.onarandombox.MultiverseCore.enums.AddProperties} to clear.
- * @return True if it was cleared, false if not.
- */
- boolean clearVariable(String property);
-
- /**
- * Adds a value to the given property. The property must be a {@link com.onarandombox.MultiverseCore.enums.AddProperties}.
- *
- * @param property The name of a {@link com.onarandombox.MultiverseCore.enums.AddProperties} to add a value to.
- * @param value A value in string representation, it will be parsed to the correct type.
- * @return True if the value was added, false if not.
- */
- boolean addToVariable(String property, String value);
-
- /**
- * Removes a value from the given property. The property must be a {@link com.onarandombox.MultiverseCore.enums.AddProperties}.
- *
- * @param property The name of a {@link com.onarandombox.MultiverseCore.enums.AddProperties} to remove a value
- * from.
- * @param value A value in string representation, it will be parsed to the correct type.
- * @return True if the value was removed, false if not.
- */
- boolean removeFromVariable(String property, String value);
+ WorldType getWorldType();
/**
* Gets the environment of this world.
@@ -125,27 +68,168 @@ public interface MultiverseWorld {
*/
void setEnvironment(World.Environment environment);
+ /**
+ * Gets the difficulty of this world.
+ *
+ * @return The difficulty of this world.
+ */
+ Difficulty getDifficulty();
+
+ /**
+ * Sets the difficulty of this world and returns true if success.
+ * Valid string values are either an integer of difficulty(0-3) or
+ * the name that resides in the Bukkit enum, ex. {@code PEACEFUL}
+ *
+ * @param difficulty The difficulty to set the world to as a string.
+ * @return True if success, false if the provided string
+ * could not be translated to a difficulty.
+ * @deprecated Use {@link #setDifficulty(Difficulty)} or, if you have to
+ * pass a string, use {@link #setPropertyValue(String, String)} instead.
+ */
+ @Deprecated
+ boolean setDifficulty(String difficulty);
+
+ /**
+ * Sets the difficulty of this world and returns {@code true} on success.
+ * Valid string values are either an integer of difficulty(0-3) or
+ * the name that resides in the Bukkit enum, ex. PEACEFUL
+ *
+ * @param difficulty The new difficulty.
+ * @return True if success, false if the operation failed... for whatever reason.
+ */
+ boolean setDifficulty(Difficulty difficulty);
+
/**
* Gets the world seed of this world.
*
* @return The Long version of the seed.
*/
- Long getSeed();
+ long getSeed();
/**
* Sets the seed of this world.
*
* @param seed A Long that is the seed.
*/
- void setSeed(Long seed);
+ void setSeed(long seed);
/**
- * Gets the name of this world. This cannot be changed.
+ * Gets the generator of this world.
*
- * @return The name of the world as a String.
+ * @return The name of the generator.
*/
- String getName();
+ String getGenerator();
+ /**
+ * Sets the generator of this world.
+ *
+ * @param generator The new generator's name.
+ */
+ void setGenerator(String generator);
+
+ /**
+ * Gets the help-message for a property.
+ * @param property The name of the property.
+ * @return The help-message.
+ * @throws PropertyDoesNotExistException Thrown if the property was not found.
+ */
+ String getPropertyHelp(String property) throws PropertyDoesNotExistException;
+
+ /**
+ * Gets a property as {@link String}.
+ *
+ * @param property The name of a world property to get.
+ * @return The string-representation of that property.
+ * @throws PropertyDoesNotExistException Thrown if the property was not found in the world.
+ */
+ String getPropertyValue(String property) throws PropertyDoesNotExistException;
+
+ /**
+ * Sets a property to a given value.
+ *
+ * @param property The name of a world property to set.
+ * @param value A value in string representation, it will be parsed to the correct type.
+ * @return True if the value was set, false if not.
+ * @throws PropertyDoesNotExistException Thrown if the property was not found in the world.
+ */
+ boolean setPropertyValue(String property, String value) throws PropertyDoesNotExistException;
+
+ /**
+ * Gets the actual MVConfigProperty from this world.
+ * It will throw a PropertyDoesNotExistException if the property is not found.
+ *
+ * @param property The name of a world property to get.
+ * @param expected The type of the expected property. Use Object.class if this doesn't matter for you.
+ * @param The type of the expected property.
+ *
+ * @return A valid MVWorldProperty.
+ *
+ * @throws PropertyDoesNotExistException Thrown if the property was not found in the world.
+ * @deprecated We don't use {@link com.onarandombox.MultiverseCore.configuration.MVConfigProperty} any longer!
+ */
+ @Deprecated
+ com.onarandombox.MultiverseCore.configuration.MVConfigProperty getProperty(String property, Class expected) throws PropertyDoesNotExistException;
+
+ // old config
+ /**
+ * Adds the property to the given value.
+ * It will throw a PropertyDoesNotExistException if the property is not found.
+ *
+ * @param property The name of a world property to set.
+ * @param value A value in string representation, it will be parsed to the correct type.
+ * @param sender The sender who wants this value to be set.
+ * @return True if the value was set, false if not.
+ * @throws PropertyDoesNotExistException Thrown if the property was not found in the world.
+ * @deprecated Use {@link #setPropertyValue(String, String)} instead.
+ */
+ @Deprecated
+ boolean setProperty(String property, String value, CommandSender sender) throws PropertyDoesNotExistException;
+
+ /**
+ * Adds a value to the given property. The property must be a {@link com.onarandombox.MultiverseCore.enums.AddProperties}.
+ *
+ * @param property The name of a {@link com.onarandombox.MultiverseCore.enums.AddProperties} to add a value to.
+ * @param value A value in string representation, it will be parsed to the correct type.
+ * @return True if the value was added, false if not.
+ * @deprecated We changed the entire world-config-system. This is not compatible any more.
+ */
+ @Deprecated
+ boolean addToVariable(String property, String value);
+
+ /**
+ * Removes a value from the given property. The property must be a {@link com.onarandombox.MultiverseCore.enums.AddProperties}.
+ *
+ * @param property The name of a {@link com.onarandombox.MultiverseCore.enums.AddProperties} to remove a value
+ * from.
+ * @param value A value in string representation, it will be parsed to the correct type.
+ * @return True if the value was removed, false if not.
+ * @deprecated We changed the entire world-config-system. This is not compatible any more.
+ */
+ @Deprecated
+ boolean removeFromVariable(String property, String value);
+
+ /**
+ * Removes all values from the given property. The property must be a {@link com.onarandombox.MultiverseCore.enums.AddProperties}.
+ *
+ * @param property The name of a {@link com.onarandombox.MultiverseCore.enums.AddProperties} to clear.
+ * @return True if it was cleared, false if not.
+ * @deprecated We changed the entire world-config-system. This is not compatible any more.
+ */
+ @Deprecated
+ boolean clearVariable(String property);
+
+ /**
+ * Clears a list property (sets it to []).
+ *
+ * @param property The property to clear.
+ * @return True if success, false if fail.
+ * @deprecated We changed the entire world-config-system. This is not compatible any more.
+ */
+ @Deprecated
+ boolean clearList(String property);
+ // end of old config stuff
+
+ // permission stuff
/**
* Gets the lowercased name of the world. This method is required, since the permissables
* lowercase all permissions when recalculating.
@@ -158,6 +242,21 @@ public interface MultiverseWorld {
*/
String getPermissibleName();
+ /**
+ * Gets the permission required to enter this world.
+ *
+ * @return The permission required to be exempt from charges to/from this world.
+ */
+ Permission getAccessPermission();
+
+ /**
+ * Gets the permission required to be exempt when entering.
+ *
+ * @return The permission required to be exempt when entering.
+ */
+ Permission getExemptPermission();
+ // end of permission stuff
+
/**
* Gets the alias of this world.
*
@@ -174,6 +273,13 @@ public interface MultiverseWorld {
*/
void setAlias(String alias);
+ /**
+ * Gets the color that this world's name/alias will display as.
+ *
+ * @return The color of this world.
+ */
+ ChatColor getColor();
+
/**
* Sets the color that this world's name/alias will display as.
*
@@ -183,18 +289,29 @@ public interface MultiverseWorld {
boolean setColor(String color);
/**
- * Gets the color that this world's name/alias will display as.
+ * Gets the style that this world's name/alias will display as.
*
- * @return The color of this world.
+ * @return The style of this world. {@code null} for "normal" style.
*/
- ChatColor getColor();
+ ChatColor getStyle();
+
+ /**
+ * Sets the style that this world's name/alias will display as.
+ *
+ * @param style A valid style name.
+ * @return True if the style was set, false if not.
+ */
+ boolean setStyle(String style);
/**
* Tells you if someone entered a valid color.
*
* @param color A string that may translate to a color.
* @return True if it is a color, false if not.
+ *
+ * @deprecated This has been moved: {@link com.onarandombox.MultiverseCore.enums.EnglishChatColor#isValidAliasColor(String)}
*/
+ @Deprecated
boolean isValidAliasColor(String color);
/**
@@ -204,6 +321,7 @@ public interface MultiverseWorld {
*/
String getColoredWorldString();
+ // animals&monster stuff
/**
* Gets whether or not animals are allowed to spawn in this world.
*
@@ -211,6 +329,22 @@ public interface MultiverseWorld {
*/
boolean canAnimalsSpawn();
+ /**
+ * Sets whether or not animals can spawn.
+ * If there are values in {@link #getAnimalList()} and this is false,
+ * those animals become the exceptions, and will spawn
+ *
+ * @param allowAnimalSpawn True to allow spawning of monsters, false to prevent.
+ */
+ void setAllowAnimalSpawn(boolean allowAnimalSpawn);
+
+ /**
+ * Returns a list of animals. This list always negates the {@link #canAnimalsSpawn()} result.
+ *
+ * @return A list of animals that will spawn if {@link #canAnimalsSpawn()} is false.
+ */
+ List getAnimalList();
+
/**
* Gets whether or not monsters are allowed to spawn in this world.
*
@@ -219,7 +353,31 @@ public interface MultiverseWorld {
boolean canMonstersSpawn();
/**
- * Turn pvp on or off. This setting is used to set the world's PVP mode, and thus relies on fakePVP
+ * Sets whether or not monsters can spawn.
+ * If there are values in {@link #getMonsterList()} and this is false,
+ * those monsters become the exceptions, and will spawn
+ *
+ * @param allowMonsterSpawn True to allow spawning of monsters, false to prevent.
+ */
+ void setAllowMonsterSpawn(boolean allowMonsterSpawn);
+
+ /**
+ * Returns a list of monsters. This list always negates the {@link #canMonstersSpawn()} result.
+ *
+ * @return A list of monsters that will spawn if {@link #canMonstersSpawn()} is false.
+ */
+ List getMonsterList();
+ // end of animal&monster stuff
+
+ /**
+ * Gets whether or not PVP is enabled in this world in some form (fake or not).
+ *
+ * @return True if players can take damage from other players.
+ */
+ boolean isPVPEnabled();
+
+ /**
+ * Turn pvp on or off. This setting is used to set the world's PVP mode.
*
* @param pvpMode True to enable PVP damage, false to disable it.
*/
@@ -234,13 +392,6 @@ public interface MultiverseWorld {
@Deprecated
boolean getFakePVP();
- /**
- * Gets whether or not PVP is enabled in this world in some form (fake or not).
- *
- * @return True if players can take damage from other players.
- */
- boolean isPVPEnabled();
-
/**
* Gets whether or not this world will display in chat, mvw and mvl regardless if a user has the
* access permissions to go to this world.
@@ -257,6 +408,13 @@ public interface MultiverseWorld {
*/
void setHidden(boolean hidden);
+ /**
+ * Gets whether weather is enabled in this world.
+ *
+ * @return True if weather events will occur, false if not.
+ */
+ boolean isWeatherEnabled();
+
/**
* Sets whether or not there will be weather events in a given world.
* If set to false, Multiverse will disable the weather in the world immediately.
@@ -266,11 +424,11 @@ public interface MultiverseWorld {
void setEnableWeather(boolean enableWeather);
/**
- * Gets whether weather is enabled in this world.
+ * Gets whether or not CraftBukkit is keeping the chunks for this world in memory.
*
- * @return True if weather events will occur, false if not.
+ * @return True if CraftBukkit is keeping spawn chunks in memory.
*/
- boolean isWeatherEnabled();
+ boolean isKeepingSpawnInMemory();
/**
* If true, tells Craftbukkit to keep a worlds spawn chunks loaded in memory (default: true)
@@ -282,29 +440,11 @@ public interface MultiverseWorld {
void setKeepSpawnInMemory(boolean keepSpawnInMemory);
/**
- * Gets whether or not CraftBukkit is keeping the chunks for this world in memory.
+ * Gets the spawn location of this world.
*
- * @return True if CraftBukkit is keeping spawn chunks in memory.
+ * @return The spawn location of this world.
*/
- boolean isKeepingSpawnInMemory();
-
- /**
- * Sets the difficulty of this world and returns true if success.
- * Valid string values are either an integer of difficulty(0-3) or
- * the name that resides in the Bukkit enum, ex. PEACEFUL
- *
- * @param difficulty The difficulty to set the world to as a string.
- * @return True if success, false if the provided string
- * could not be translated to a difficulty.
- */
- boolean setDifficulty(String difficulty);
-
- /**
- * Gets the difficulty of this world.
- *
- * @return The difficulty of this world.
- */
- Difficulty getDifficulty();
+ Location getSpawnLocation();
/**
* Sets the spawn location for a world.
@@ -314,11 +454,11 @@ public interface MultiverseWorld {
void setSpawnLocation(Location spawnLocation);
/**
- * Gets the spawn location of this world.
+ * Gets whether or not the hunger level of players will go down in a world.
*
- * @return The spawn location of this world.
+ * @return True if it will go down, false if it will remain steady.
*/
- Location getSpawnLocation();
+ boolean getHunger();
/**
* Sets whether or not the hunger level of players will go down in a world.
@@ -328,22 +468,6 @@ public interface MultiverseWorld {
*/
void setHunger(boolean hungerEnabled);
- /**
- * Gets whether or not the hunger level of players will go down in a world.
- *
- * @return True if it will go down, false if it will remain steady.
- */
- boolean getHunger();
-
- /**
- * Sets the game mode of this world.
- *
- * @param gameMode A valid game mode string (either
- * an int ex. 0 or a string ex. creative).
- * @return True if the game mode was successfully changed, false if not.
- */
- boolean setGameMode(String gameMode);
-
/**
* Gets the GameMode of this world.
*
@@ -352,18 +476,31 @@ public interface MultiverseWorld {
GameMode getGameMode();
/**
- * Gets the permission required to enter this world.
+ * Sets the game mode of this world.
*
- * @return The permission required to be exempt from charges to/from this world.
+ * @param gameMode A valid game mode string (either
+ * an int ex. 0 or a string ex. creative).
+ * @return True if the game mode was successfully changed, false if not.
+ * @deprecated Use {@link #setGameMode(GameMode)} instead. If you have to
+ * pass a string, use {@link #setPropertyValue(String, String)}.
*/
- Permission getAccessPermission();
+ @Deprecated
+ boolean setGameMode(String gameMode);
/**
- * Gets the permission required to be exempt when entering.
+ * Sets the game mode of this world.
*
- * @return The permission required to be exempt when entering.
+ * @param gameMode The new {@link GameMode}.
+ * @return True if the game mode was successfully changed, false if not.
*/
- Permission getExemptPermission();
+ boolean setGameMode(GameMode gameMode);
+
+ /**
+ * Gets the amount of currency it requires to enter this world.
+ *
+ * @return The amount it costs to enter this world.
+ */
+ double getPrice();
/**
* Sets the price for entry to this world.
@@ -375,11 +512,11 @@ public interface MultiverseWorld {
void setPrice(double price);
/**
- * Gets the amount of currency it requires to enter this world.
+ * Gets the Type of currency that will be used when users enter this world.
*
- * @return The amount it costs to enter this world.
+ * @return The Type of currency that will be used when users enter this world.
*/
- double getPrice();
+ int getCurrency();
/**
* Sets the type of item that will be required given the price is not 0.
@@ -390,11 +527,11 @@ public interface MultiverseWorld {
void setCurrency(int item);
/**
- * Gets the Type of currency that will be used when users enter this world.
+ * Gets the world players will respawn in if they die in this one.
*
- * @return The Type of currency that will be used when users enter this world.
+ * @return A world that exists on the server.
*/
- int getCurrency();
+ World getRespawnToWorld();
/**
* Sets the world players will respawn in if they die in this one.
@@ -406,11 +543,12 @@ public interface MultiverseWorld {
boolean setRespawnToWorld(String respawnWorld);
/**
- * Gets the world players will respawn in if they die in this one.
+ * Gets the scaling value of this world.Really only has an effect if you use
+ * Multiverse-NetherPortals.
*
- * @return A world that exists on the server.
+ * @return This world's non-negative, non-zero scale.
*/
- World getRespawnToWorld();
+ double getScaling();
/**
* Sets the scale of this world. Really only has an effect if you use
@@ -422,60 +560,11 @@ public interface MultiverseWorld {
boolean setScaling(double scaling);
/**
- * Gets the scaling value of this world.Really only has an effect if you use
- * Multiverse-NetherPortals.
+ * Gets whether or not a world will auto-heal players if the difficulty is on peaceful.
*
- * @return This world's non-negative, non-zero scale.
+ * @return True if the world should heal (default), false if not.
*/
- double getScaling();
-
- /**
- * Gets a list of all the worlds that players CANNOT travel to from this world,
- * regardless of their access permissions.
- *
- * @return A List of world names.
- */
- List getWorldBlacklist();
-
- /**
- * Returns a list of animals. This list always negates the {@link #canAnimalsSpawn()} result.
- *
- * @return A list of animals that will spawn if {@link #canAnimalsSpawn()} is false.
- */
- List getAnimalList();
-
- /**
- * Sets whether or not animals can spawn.
- * If there are values in {@link #getAnimalList()} and this is false,
- * those animals become the exceptions, and will spawn
- *
- * @param allowAnimalSpawn True to allow spawning of monsters, false to prevent.
- */
- void setAllowAnimalSpawn(boolean allowAnimalSpawn);
-
- /**
- * Returns a list of monsters. This list always negates the {@link #canMonstersSpawn()} ()} result.
- *
- * @return A list of monsters that will spawn if {@link #canMonstersSpawn()} is false.
- */
- List getMonsterList();
-
- /**
- * Sets whether or not monsters can spawn.
- * If there are values in {@link #getMonsterList()} and this is false,
- * those monsters become the exceptions, and will spawn
- *
- * @param allowMonsterSpawn True to allow spawning of monsters, false to prevent.
- */
- void setAllowMonsterSpawn(boolean allowMonsterSpawn);
-
- /**
- * Clears a list property (sets it to []).
- *
- * @param property The property to clear.
- * @return True if success, false if fail.
- */
- boolean clearList(String property);
+ boolean getAutoHeal();
/**
* Sets whether or not a world will auto-heal players if the difficulty is on peaceful.
@@ -485,11 +574,11 @@ public interface MultiverseWorld {
void setAutoHeal(boolean heal);
/**
- * Gets whether or not a world will auto-heal players if the difficulty is on peaceful.
+ * Gets whether or not Multiverse should auto-adjust the spawn for this world.
*
- * @return True if the world should heal (default), false if not.
+ * @return True if Multiverse should adjust the spawn, false if not.
*/
- boolean getAutoHeal();
+ boolean getAdjustSpawn();
/**
* Sets whether or not Multiverse should auto-adjust the spawn for this world.
@@ -499,11 +588,11 @@ public interface MultiverseWorld {
void setAdjustSpawn(boolean adjust);
/**
- * Gets whether or not Multiverse should auto-adjust the spawn for this world.
+ * Gets whether or not Multiverse should auto-load this world.
*
- * @return True if Multiverse should adjust the spawn, false if not.
+ * @return True if Multiverse should auto-load this world.
*/
- boolean getAdjustSpawn();
+ boolean getAutoLoad();
/**
* Sets whether or not Multiverse should auto-load this world.
@@ -515,11 +604,12 @@ public interface MultiverseWorld {
void setAutoLoad(boolean autoLoad);
/**
- * Gets whether or not Multiverse should auto-load this world.
+ * Gets whether or not a player who dies in this world will respawn in their
+ * bed or follow the normal respawn pattern.
*
- * @return True if Multiverse should auto-load this world.
+ * @return True if players dying in this world should respawn at their bed.
*/
- boolean getAutoLoad();
+ boolean getBedRespawn();
/**
* Sets whether or not a player who dies in this world will respawn in their
@@ -532,19 +622,10 @@ public interface MultiverseWorld {
void setBedRespawn(boolean autoLoad);
/**
- * Gets whether or not a player who dies in this world will respawn in their
- * bed or follow the normal respawn pattern.
- *
- * @return True if players dying in this world should respawn at their bed.
+ * Same as {@link #getTime()}, but returns a string.
+ * @return The time as a short string: 12:34pm
*/
- boolean getBedRespawn();
-
- /**
- * Gets all the names of all properties that can be SET.
- *
- * @return All property names, with alternating colors.
- */
- String getAllPropertyNames();
+ String getTime();
/**
* Sets the current time in a world.
@@ -559,22 +640,6 @@ public interface MultiverseWorld {
*/
boolean setTime(String timeAsString);
- /**
- * Same as {@link #getTime()}, but returns a string.
- * @return The time as a short string: 12:34pm
- */
- String getTime();
-
- /**
- * Gets the type of this world. As of 1.2 this will be:
- * FLAT, NORMAL or VERSION_1_1
- *
- * This is *not* the generator.
- *
- * @return The Type of this world.
- */
- WorldType getWorldType();
-
/**
* Sets The types of portals that are allowed in this world.
*
@@ -588,4 +653,20 @@ public interface MultiverseWorld {
* @return The type of portals that are allowed.
*/
AllowedPortalType getAllowedPortals();
+
+ // properties that are not "getter+setter" style
+ /**
+ * Gets a list of all the worlds that players CANNOT travel to from this world,
+ * regardless of their access permissions.
+ *
+ * @return A List of world names.
+ */
+ List getWorldBlacklist();
+
+ /**
+ * Gets all the names of all properties that can be SET.
+ *
+ * @return All property names, with alternating colors.
+ */
+ String getAllPropertyNames();
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/WorldPurger.java b/src/main/java/com/onarandombox/MultiverseCore/api/WorldPurger.java
index 6be96bba..a52b73f3 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/api/WorldPurger.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/api/WorldPurger.java
@@ -3,14 +3,14 @@ package com.onarandombox.MultiverseCore.api;
import java.util.List;
import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Entity;
/**
* Used to remove animals from worlds that don't belong there.
*/
public interface WorldPurger {
-
/**
- * Synchronizes the given world with it's settings.
+ * Synchronizes the given worlds with their settings.
*
* @param worlds A list of {@link MultiverseWorld}
*/
@@ -46,4 +46,23 @@ public interface WorldPurger {
void purgeWorld(MultiverseWorld mvworld, List thingsToKill, boolean negateAnimals,
boolean negateMonsters, CommandSender sender);
+ /**
+ * Determines whether the specified creature should be killed.
+ *
+ * @param e The creature.
+ * @param thingsToKill A {@link List} of animals/monsters to be killed.
+ * @param negateAnimals Whether the monsters in the list should be negated.
+ * @param negateMonsters Whether the animals in the list should be negated.
+ * @return {@code true} if the creature should be killed, otherwise {@code false}.
+ */
+ boolean shouldWeKillThisCreature(Entity e, List thingsToKill, boolean negateAnimals, boolean negateMonsters);
+
+ /**
+ * Determines whether the specified creature should be killed and automatically reads the params from a world object.
+ *
+ * @param w The world.
+ * @param e The creature.
+ * @return {@code true} if the creature should be killed, otherwise {@code false}.
+ */
+ boolean shouldWeKillThisCreature(MultiverseWorld w, Entity e);
}
diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/AnchorCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/AnchorCommand.java
index 731e6f95..55d0b2cf 100644
--- a/src/main/java/com/onarandombox/MultiverseCore/commands/AnchorCommand.java
+++ b/src/main/java/com/onarandombox/MultiverseCore/commands/AnchorCommand.java
@@ -11,6 +11,7 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
+import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import java.util.ArrayList;
@@ -34,7 +35,11 @@ public class AnchorCommand extends PaginatedCoreCommand {
this.addCommandExample("/mv anchor " + ChatColor.GREEN + "otherthing");
this.addCommandExample("/mv anchor " + ChatColor.GREEN + "awesomething " + ChatColor.RED + "-d");
this.addCommandExample("/mv anchors ");
- this.setPermission("multiverse.core.anchor", "Allows management of Anchor Destinations.", PermissionDefault.OP);
+ this.setPermission("multiverse.core.anchor.list", "Allows a player to list all anchors.", PermissionDefault.OP);
+ this.addAdditonalPermission(new Permission("multiverse.core.anchor.create",
+ "Allows a player to create anchors.", PermissionDefault.OP));
+ this.addAdditonalPermission(new Permission("multiverse.core.anchor.delete",
+ "Allows a player to delete anchors.", PermissionDefault.OP));
this.setItemsPerPage(8); // SUPPRESS CHECKSTYLE: MagicNumberCheck
}
@@ -49,6 +54,11 @@ public class AnchorCommand extends PaginatedCoreCommand {
}
private void showList(CommandSender sender, List args) {
+ if (!this.plugin.getMVPerms().hasPermission(sender, "multiverse.core.anchor.list", true)) {
+ sender.sendMessage(ChatColor.RED + "You don't have the permission to list anchors!");
+ return;
+ }
+
sender.sendMessage(ChatColor.LIGHT_PURPLE + "====[ Multiverse Anchor List ]====");
Player p = null;
if (sender instanceof Player) {
@@ -105,10 +115,14 @@ public class AnchorCommand extends PaginatedCoreCommand {
return;
}
if (args.size() == 2 && args.get(1).equalsIgnoreCase("-d")) {
- if (this.plugin.getAnchorManager().deleteAnchor(args.get(0))) {
- sender.sendMessage("Anchor '" + args.get(0) + "' was successfully " + ChatColor.RED + "deleted!");
+ if (!this.plugin.getMVPerms().hasPermission(sender, "multiverse.core.anchor.delete", true)) {
+ sender.sendMessage(ChatColor.RED + "You don't have the permission to delete anchors!");
} else {
- sender.sendMessage("Anchor '" + args.get(0) + "' was " + ChatColor.RED + " NOT " + ChatColor.WHITE + "deleted!");
+ if (this.plugin.getAnchorManager().deleteAnchor(args.get(0))) {
+ sender.sendMessage("Anchor '" + args.get(0) + "' was successfully " + ChatColor.RED + "deleted!");
+ } else {
+ sender.sendMessage("Anchor '" + args.get(0) + "' was " + ChatColor.RED + " NOT " + ChatColor.WHITE + "deleted!");
+ }
}
return;
}
@@ -118,13 +132,16 @@ public class AnchorCommand extends PaginatedCoreCommand {
return;
}
- Player player = (Player) sender;
- if (this.plugin.getAnchorManager().saveAnchorLocation(args.get(0), player.getLocation())) {
- sender.sendMessage("Anchor '" + args.get(0) + "' was successfully " + ChatColor.GREEN + "created!");
+ if (!this.plugin.getMVPerms().hasPermission(sender, "multiverse.core.anchor.create", true)) {
+ sender.sendMessage(ChatColor.RED + "You don't have the permission to create anchors!");
} else {
- sender.sendMessage("Anchor '" + args.get(0) + "' was " + ChatColor.RED + " NOT " + ChatColor.WHITE + "created!");
+ Player player = (Player) sender;
+ if (this.plugin.getAnchorManager().saveAnchorLocation(args.get(0), player.getLocation())) {
+ sender.sendMessage("Anchor '" + args.get(0) + "' was successfully " + ChatColor.GREEN + "created!");
+ } else {
+ sender.sendMessage("Anchor '" + args.get(0) + "' was " + ChatColor.RED + " NOT " + ChatColor.WHITE + "created!");
+ }
}
-
}
@Override
diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/CloneCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/CloneCommand.java
new file mode 100644
index 00000000..9dce1d69
--- /dev/null
+++ b/src/main/java/com/onarandombox/MultiverseCore/commands/CloneCommand.java
@@ -0,0 +1,60 @@
+/******************************************************************************
+ * Multiverse 2 Copyright (c) the Multiverse Team 2011. *
+ * Multiverse 2 is licensed under the BSD License. *
+ * For more information please check the README.md file included *
+ * with this project. *
+ ******************************************************************************/
+
+package com.onarandombox.MultiverseCore.commands;
+
+import com.onarandombox.MultiverseCore.MultiverseCore;
+import com.onarandombox.MultiverseCore.api.MVWorldManager;
+import com.pneumaticraft.commandhandler.CommandHandler;
+import org.bukkit.ChatColor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.permissions.PermissionDefault;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Creates a clone of a world.
+ */
+public class CloneCommand extends MultiverseCommand {
+ private MVWorldManager worldManager;
+
+ public CloneCommand(MultiverseCore plugin) {
+ super(plugin);
+ this.setName("Clone World");
+ this.setCommandUsage("/mv clone" + ChatColor.GREEN + " {TARGET} {NAME}" + ChatColor.GOLD + " -g [GENERATOR[:ID]]");
+ this.setArgRange(2, 4); // SUPPRESS CHECKSTYLE: MagicNumberCheck
+ this.addKey("mvclone");
+ this.addKey("mvcl");
+ this.addKey("mv cl");
+ this.addKey("mv clone");
+ this.addCommandExample("/mv clone " + ChatColor.GOLD + "world" + ChatColor.GREEN + " world_backup");
+ this.addCommandExample("/mv clone " + ChatColor.GOLD + "skyblock_pristine" + ChatColor.GREEN + " skyblock");
+ this.addCommandExample("To clone a world that uses a generator:");
+ this.addCommandExample("/mv clone " + ChatColor.GOLD + "CleanRoom"
+ + ChatColor.GREEN + " CleanRoomCopy" + ChatColor.DARK_AQUA + " -g CleanRoomGenerator");
+ this.setPermission("multiverse.core.clone", "Clones a world.", PermissionDefault.OP);
+ this.worldManager = this.plugin.getMVWorldManager();
+ }
+
+ @Override
+ public void runCommand(CommandSender sender, List args) {
+ Class>[] paramTypes = {String.class, String.class, String.class};
+ List