diff --git a/lib/allpay b/lib/allpay index 18c55a90..7abba1f0 160000 --- a/lib/allpay +++ b/lib/allpay @@ -1 +1 @@ -Subproject commit 18c55a9070a5e64b2cb0737940290643f324fa7d +Subproject commit 7abba1f0040862e9fabdafb3d44c6cf0b914cc7c diff --git a/pom.xml b/pom.xml index bce86ba9..59bdb602 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.onarandombox.multiversecore Multiverse-Core - 2.2 + 2.3 Multiverse-Core World Management Plugin @@ -16,6 +16,10 @@ onarandombox http://repo.onarandombox.com/content/groups/public + + Bukkit Offical + http://repo.bukkit.org/content/repositories/public + @@ -77,7 +81,7 @@ - ${project.basedir}/lib/allpay/src + ${project.basedir}/lib/allpay/src/main/java ${project.basedir}/lib/commandhandler/src ${project.basedir}/lib/commandhandler/lib/ShellParser/src @@ -162,7 +166,7 @@ org.bukkit bukkit - 1.0.0-R1-SNAPSHOT + 1.1-R1 jar compile @@ -229,6 +233,13 @@ jar compile + + ca.agnate + EconXP + 1.0.0 + jar + compile + diff --git a/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java b/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java index 496e7826..00c6cf65 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MVWorld.java @@ -22,6 +22,7 @@ import org.bukkit.GameMode; import org.bukkit.Location; 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; @@ -67,6 +68,7 @@ public class MVWorld implements MultiverseWorld { private Permission ignoreperm; private static final Map TIME_ALIASES; + private WorldType type; static { Map staticTimes = new HashMap(); @@ -89,6 +91,7 @@ public class MVWorld implements MultiverseWorld { this.name = world.getName(); this.seed = seed; this.environment = world.getEnvironment(); + this.type = world.getWorldType(); // Initialize our lists this.initLists(); @@ -106,6 +109,8 @@ public class MVWorld implements MultiverseWorld { } 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>(); @@ -203,6 +208,15 @@ 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(); } /** @@ -235,7 +249,16 @@ public class MVWorld implements MultiverseWorld { */ public boolean setActualKeepSpawnInMemory() { // Ensure the memory setting is correct - this.world.setKeepSpawnInMemory(this.getKnownProperty("memory", Boolean.class).getValue()); + this.getCBWorld().setKeepSpawnInMemory(this.getKnownProperty("memory", Boolean.class).getValue()); + return true; + } + + /** + * Used by the active difficulty-property to set the "actual" property. + * @return True if the property was successfully set. + */ + public boolean setActualDifficulty() { + this.getCBWorld().setDifficulty(this.getKnownProperty("difficulty", Difficulty.class).getValue()); return true; } @@ -392,7 +415,12 @@ public class MVWorld implements MultiverseWorld { return false; } - private void syncMobs() { + /** + * 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()); @@ -534,18 +562,16 @@ public class MVWorld implements MultiverseWorld { 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 (NoSuchMethodException e) { - System.out.println(e); - return false; - } catch (IllegalAccessException e) { - System.out.println(e); - return false; - } catch (InvocationTargetException e) { - System.out.println(e); + } catch (Exception e) { + e.printStackTrace(); return false; } } @@ -595,6 +621,14 @@ public class MVWorld implements MultiverseWorld { return this.name; } + /** + * {@inheritDoc} + */ + @Override + public String getPermissibleName() { + return this.name.toLowerCase(); + } + /** * {@inheritDoc} */ @@ -977,7 +1011,7 @@ public class MVWorld implements MultiverseWorld { + "' is Located at: " + plugin.getLocationManipulation().locationToString(configLocation)); } else { // If it's a standard end world, let's check in a better place: - Location newerSpawn = null; + Location newerSpawn; newerSpawn = bs.getTopBlock(new Location(w, 0, 0, 0)); if (newerSpawn != null) { this.setSpawnLocation(newerSpawn); @@ -1118,6 +1152,14 @@ public class MVWorld implements MultiverseWorld { return String.format("%d:%02d", hours, minutes); } + /** + * {@inheritDoc} + */ + @Override + public WorldType getWorldType() { + return this.type; + } + /** * Used by the active time-property to set the "actual" property. * @return True if the property was successfully set. diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java index 6970b35c..33497df4 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java @@ -28,21 +28,17 @@ import com.onarandombox.MultiverseCore.event.MVVersionEvent; import com.onarandombox.MultiverseCore.listeners.MVEntityListener; import com.onarandombox.MultiverseCore.listeners.MVPlayerListener; import com.onarandombox.MultiverseCore.listeners.MVPluginListener; -import com.onarandombox.MultiverseCore.listeners.MVPortalAdjustListener; import com.onarandombox.MultiverseCore.listeners.MVWeatherListener; import com.onarandombox.MultiverseCore.utils.*; import com.pneumaticraft.commandhandler.CommandHandler; 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.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.Event.Priority; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; @@ -61,7 +57,7 @@ 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 = 10; + private static final int PROTOCOL = 12; // Global Multiverse config variable, states whether or not // Multiverse should stop other plugins from teleporting players // to worlds. @@ -153,8 +149,6 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core { // Setup the block/player/entity listener. private MVPlayerListener playerListener = new MVPlayerListener(this); - private MVPortalAdjustListener portalAdjustListener = new MVPortalAdjustListener(this); - private MVEntityListener entityListener = new MVEntityListener(this); private MVPluginListener pluginListener = new MVPluginListener(this); private MVWeatherListener weatherListener = new MVWeatherListener(this); @@ -168,7 +162,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core { private int pluginCount; private DestinationFactory destFactory; private SpoutInterface spoutInterface = null; - private static final double ALLPAY_VERSION = 3; + private static final double ALLPAY_VERSION = 5; private static final double CH_VERSION = 4; private MultiverseMessaging messaging; private BlockSafety blockSafety; @@ -322,28 +316,10 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core { */ private void registerEvents() { PluginManager pm = getServer().getPluginManager(); - pm.registerEvent(Event.Type.PLAYER_TELEPORT, this.playerListener, Priority.Highest, this); // Cancel Teleports if needed. - pm.registerEvent(Event.Type.PLAYER_JOIN, this.playerListener, Priority.Normal, this); // To create the Player Session - pm.registerEvent(Event.Type.PLAYER_QUIT, this.playerListener, Priority.Normal, this); // To remove Player Sessions - pm.registerEvent(Event.Type.PLAYER_RESPAWN, this.playerListener, Priority.Low, this); // Let plugins which specialize in (re)spawning carry more weight. - pm.registerEvent(Event.Type.PLAYER_LOGIN, this.playerListener, Priority.Low, this); // Let plugins which specialize in (re)spawning carry more weight. - pm.registerEvent(Event.Type.PLAYER_CHAT, this.playerListener, Priority.Normal, this); // To prepend the world name - pm.registerEvent(Event.Type.PLAYER_PORTAL, this.playerListener, Priority.High, this); - // We want this high to have it go last, so it can cancel if needbe. - - pm.registerEvent(Event.Type.PLAYER_PORTAL, this.portalAdjustListener, Priority.Lowest, this); // To handle portal correction - pm.registerEvent(Event.Type.PLAYER_CHANGED_WORLD, this.playerListener, Priority.Monitor, this); // To switch gamemode - - pm.registerEvent(Event.Type.ENTITY_REGAIN_HEALTH, this.entityListener, Priority.Normal, this); - pm.registerEvent(Event.Type.ENTITY_DAMAGE, this.entityListener, Priority.Normal, this); // To Allow/Disallow fake PVP - pm.registerEvent(Event.Type.CREATURE_SPAWN, this.entityListener, Priority.Normal, this); // To prevent all or certain animals/monsters from spawning. - pm.registerEvent(Event.Type.FOOD_LEVEL_CHANGE, this.entityListener, Priority.Normal, this); - - pm.registerEvent(Event.Type.PLUGIN_ENABLE, this.pluginListener, Priority.Monitor, this); - pm.registerEvent(Event.Type.PLUGIN_DISABLE, this.pluginListener, Priority.Monitor, this); - - pm.registerEvent(Event.Type.WEATHER_CHANGE, this.weatherListener, Priority.Normal, this); - pm.registerEvent(Event.Type.THUNDER_CHANGE, this.weatherListener, Priority.Normal, this); + pm.registerEvents(this.playerListener, this); + pm.registerEvents(this.entityListener, this); + pm.registerEvents(this.pluginListener, this); + pm.registerEvents(this.weatherListener, this); } /** @@ -584,33 +560,6 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core { return MultiverseCore.LOG_TAG; } - // TODO This code should get moved somewhere more appropriate, but for now, it's here. - // TODO oh, and it should be static. - /** - * Converts a {@link String} into an {@link Environment}. - * - * @param env The environment as {@link String} - * @return The environment as {@link Environment} - */ - public Environment getEnvFromString(String env) { - // Don't reference the enum directly as there aren't that many, and we can be more forgiving to users this way - if (env.equalsIgnoreCase("HELL") || env.equalsIgnoreCase("NETHER")) - env = "NETHER"; - - if (env.equalsIgnoreCase("END") || env.equalsIgnoreCase("THEEND") || env.equalsIgnoreCase("STARWARS")) - env = "THE_END"; - - if (env.equalsIgnoreCase("NORMAL") || env.equalsIgnoreCase("WORLD")) - env = "NORMAL"; - - try { - // If the value wasn't found, maybe it's new, try checking the enum directly. - return Environment.valueOf(env); - } catch (IllegalArgumentException e) { - return null; - } - } - /** * Shows a message that the given world is not a MultiverseWorld. * @@ -720,15 +669,6 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core { public void setSpout() { this.spoutInterface = new SpoutInterface(); this.commandHandler.registerCommand(new SpoutCommand(this)); - if (FirstSpawnOverride) { - this.log(Level.WARNING, "Disabling MV's 'firstspawnoverride', since spout doesn't handle new players well yet."); - this.log(Level.WARNING, "This means *new players* may not spawn where you've set your \"mvspawn\" AND"); - this.log(Level.WARNING, "the config value 'firstspawnworld' will have NO effect!!!"); - this.log(Level.WARNING, "Talk to the Spout devs to get this fixed!"); - this.log(Level.WARNING, " --FernFerret"); - FirstSpawnOverride = false; - this.multiverseConfig.set("firstspawnoverride", false); - } } /** @@ -757,6 +697,24 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core { return this.playerListener; } + /** + * Gets the {@link MVEntityListener}. + * + * @return The {@link MVEntityListener}. + */ + public MVEntityListener getEntityListener() { + return this.entityListener; + } + + /** + * Gets the {@link MVWeatherListener}. + * + * @return The {@link MVWeatherListener}. + */ + public MVWeatherListener getWeatherListener() { + return this.weatherListener; + } + /** * Saves the Multiverse-Config. * diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java index 75cc9da7..40300ef0 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/api/MVWorldManager.java @@ -10,6 +10,7 @@ package com.onarandombox.MultiverseCore.api; import com.onarandombox.MultiverseCore.utils.PurgeWorlds; import org.bukkit.World; import org.bukkit.World.Environment; +import org.bukkit.WorldType; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.generator.ChunkGenerator; @@ -32,10 +33,11 @@ public interface MVWorldManager { * @param seedString The seed in the form of a string. * If the seed is a Long, * it will be interpreted as such. + * @param type The Type of the world to be made. * @param generator The Custom generator plugin to use. * @return True if the world is added, false if not. */ - boolean addWorld(String name, Environment env, String seedString, String generator); + boolean addWorld(String name, Environment env, String seedString, WorldType type, String generator); /** * Add a new World to the Multiverse Setup. @@ -45,11 +47,12 @@ public interface MVWorldManager { * @param seedString The seed in the form of a string. * If the seed is a Long, * it will be interpreted as such. + * @param type The Type of the world to be made. * @param generator The Custom generator plugin to use. * @param useSpawnAdjust If true, multiverse will search for a safe spawn. If not, It will not modify the level.dat. * @return True if the world is added, false if not. */ - boolean addWorld(String name, Environment env, String seedString, String generator, boolean useSpawnAdjust); + boolean addWorld(String name, Environment env, String seedString, WorldType type, String generator, boolean useSpawnAdjust); /** * Remove the world from the Multiverse list, from the diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseWorld.java b/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseWorld.java index 7d878328..fb473ce8 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseWorld.java +++ b/src/main/java/com/onarandombox/MultiverseCore/api/MultiverseWorld.java @@ -15,6 +15,7 @@ import org.bukkit.Difficulty; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.WorldType; import org.bukkit.command.CommandSender; import org.bukkit.permissions.Permission; @@ -22,8 +23,6 @@ import java.util.List; /** * The API for a Multiverse Handled World. - *

- * Currently INCOMPLETE */ public interface MultiverseWorld { @@ -146,6 +145,18 @@ public interface MultiverseWorld { */ String getName(); + /** + * Gets the lowercased name of the world. This method is required, since the permissables + * lowercase all permissions when recalculating. + *

+ * Note: This also means if a user has worlds named: world and WORLD, that they can both + * exist, and both be teleported to independently, but their permissions **cannot** be + * uniqueified at this time. See bug report #. + * + * @return The lowercased name of the world. + */ + String getPermissibleName(); + /** * Gets the alias of this world. *

@@ -536,7 +547,7 @@ public interface MultiverseWorld { /** * Sets the current time in a world. - * + *

* This method will take the following formats: * 11:37am * 4:30p @@ -552,4 +563,14 @@ public interface MultiverseWorld { * @return The time as a short string: 12:34pm */ String getTime(); + + /** + * Gets the type of this world. As of 1.1-R1 this will be: + * FLAT or NORMAL + *

+ * This is *not* the generator. + * + * @return The Type of this world. + */ + WorldType getWorldType(); } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java index e6613c17..ffc3533d 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java @@ -12,6 +12,7 @@ import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.pneumaticraft.commandhandler.CommandHandler; import org.bukkit.ChatColor; import org.bukkit.World.Environment; +import org.bukkit.WorldType; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.permissions.PermissionDefault; @@ -28,8 +29,8 @@ public class CreateCommand extends MultiverseCommand { public CreateCommand(MultiverseCore plugin) { super(plugin); this.setName("Create World"); - this.setCommandUsage("/mv create" + ChatColor.GREEN + " {NAME} {ENV}" + ChatColor.GOLD + " -s [SEED] -g [GENERATOR[:ID]] [-n]"); - this.setArgRange(2, 7); // SUPPRESS CHECKSTYLE: MagicNumberCheck + this.setCommandUsage("/mv create" + ChatColor.GREEN + " {NAME} {ENV}" + ChatColor.GOLD + " -s [SEED] -g [GENERATOR[:ID]] -t [WORLDTYPE] [-n]"); + this.setArgRange(2, 9); // SUPPRESS CHECKSTYLE: MagicNumberCheck this.addKey("mvcreate"); this.addKey("mvc"); this.addKey("mv create"); @@ -37,6 +38,7 @@ public class CreateCommand extends MultiverseCommand { this.addCommandExample("/mv create " + ChatColor.GOLD + "world" + ChatColor.GREEN + " normal"); this.addCommandExample("/mv create " + ChatColor.GOLD + "lavaland" + ChatColor.RED + " nether"); this.addCommandExample("/mv create " + ChatColor.GOLD + "starwars" + ChatColor.AQUA + " end"); + this.addCommandExample("/mv create " + ChatColor.GOLD + "flatroom" + ChatColor.GREEN + " normal" + ChatColor.AQUA + " -t flat"); this.addCommandExample("/mv create " + ChatColor.GOLD + "gargamel" + ChatColor.GREEN + " normal" + ChatColor.DARK_AQUA + " -s gargamel"); this.addCommandExample("/mv create " + ChatColor.GOLD + "moonworld" + ChatColor.GREEN + " normal" + ChatColor.DARK_AQUA + " -g BukkitFullOfMoon"); this.worldManager = this.plugin.getMVWorldManager(); @@ -49,6 +51,7 @@ public class CreateCommand extends MultiverseCommand { String env = args.get(1); String seed = CommandHandler.getFlag("-s", args); String generator = CommandHandler.getFlag("-g", args); + String typeString = CommandHandler.getFlag("-t", args); boolean useSpawnAdjust = true; for (String s : args) { if (s.equalsIgnoreCase("-n")) { @@ -61,16 +64,27 @@ public class CreateCommand extends MultiverseCommand { return; } - Environment environment = this.plugin.getEnvFromString(env); + Environment environment = EnvironmentCommand.getEnvFromString(env); if (environment == null) { sender.sendMessage(ChatColor.RED + "That is not a valid environment."); EnvironmentCommand.showEnvironments(sender); return; } + // If they didn't specify a type, default to NORMAL + if (typeString == null) { + typeString = "NORMAL"; + } + WorldType type = EnvironmentCommand.getWorldTypeFromString(typeString); + if (type == null) { + sender.sendMessage(ChatColor.RED + "That is not a valid World Type."); + EnvironmentCommand.showWorldTypes(sender); + return; + } + Command.broadcastCommandMessage(sender, "Starting creation of world '" + worldName + "'..."); - if (this.worldManager.addWorld(worldName, environment, seed, generator, useSpawnAdjust)) { + if (this.worldManager.addWorld(worldName, environment, seed, type, generator, useSpawnAdjust)) { Command.broadcastCommandMessage(sender, "Complete!"); } else { Command.broadcastCommandMessage(sender, "FAILED."); diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/EnvironmentCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/EnvironmentCommand.java index 5612340c..4531b39e 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/EnvironmentCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/EnvironmentCommand.java @@ -9,6 +9,8 @@ package com.onarandombox.MultiverseCore.commands; import com.onarandombox.MultiverseCore.MultiverseCore; import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.WorldType; import org.bukkit.command.CommandSender; import org.bukkit.permissions.PermissionDefault; @@ -26,10 +28,11 @@ public class EnvironmentCommand extends MultiverseCommand { this.setArgRange(0, 0); this.addKey("mvenv"); this.addKey("mv env"); + this.addKey("mv type"); this.addKey("mv environment"); this.addKey("mv environments"); this.addCommandExample("/mv env"); - this.setPermission("multiverse.core.list.environments", "Lists valid known environments.", PermissionDefault.OP); + this.setPermission("multiverse.core.list.environments", "Lists valid known environments/world types.", PermissionDefault.OP); } /** @@ -43,9 +46,67 @@ public class EnvironmentCommand extends MultiverseCommand { sender.sendMessage(ChatColor.RED + "NETHER"); sender.sendMessage(ChatColor.AQUA + "END"); } + /** + * Shows all valid known world types to a {@link CommandSender}. + * + * @param sender The {@link CommandSender}. + */ + public static void showWorldTypes(CommandSender sender) { + sender.sendMessage(ChatColor.YELLOW + "Valid World Types are:"); + sender.sendMessage(String.format("%sNORMAL %sor %sFLAT", + ChatColor.GREEN, ChatColor.WHITE, ChatColor.AQUA)); + } @Override public void runCommand(CommandSender sender, List args) { EnvironmentCommand.showEnvironments(sender); + EnvironmentCommand.showWorldTypes(sender); + } + + /** + * Converts a {@link String} into a {@link WorldType}. + * + * @param type The WorldType as a {@link String} + * @return The WorldType as a {@link WorldType} + */ + public static WorldType getWorldTypeFromString(String type) { + // Don't reference the enum directly as there aren't that many, and we can be more forgiving to users this way + if (type.equalsIgnoreCase("normal")) + type = "NORMAL"; + if (type.equalsIgnoreCase("flat")) + type = "FLAT"; + try { + // Now that we've converted a potentially unfriendly value + // to a friendly one, get it from the ENUM! + return WorldType.valueOf(type); + } catch (IllegalArgumentException e) { + return null; + } + } + + /** + * Converts a {@link String} into an {@link org.bukkit.World.Environment}. + * + * @param env The environment as {@link String} + * @return The environment as {@link org.bukkit.World.Environment} + */ + public static World.Environment getEnvFromString(String env) { + // Don't reference the enum directly as there aren't that many, and we can be more forgiving to users this way + if (env.equalsIgnoreCase("HELL") || env.equalsIgnoreCase("NETHER")) + env = "NETHER"; + + if (env.equalsIgnoreCase("END") || env.equalsIgnoreCase("THEEND") || env.equalsIgnoreCase("STARWARS")) + env = "THE_END"; + + if (env.equalsIgnoreCase("NORMAL") || env.equalsIgnoreCase("WORLD")) + env = "NORMAL"; + + try { + // Now that we've converted a potentially unfriendly value + // to a friendly one, get it from the ENUM! + return World.Environment.valueOf(env); + } catch (IllegalArgumentException e) { + return null; + } } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/HelpCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/HelpCommand.java index 656345fd..90913026 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/HelpCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/HelpCommand.java @@ -5,8 +5,6 @@ * with this project. * ******************************************************************************/ -// TODO maybe remove this comment...? -// This file is no longer licensed under that silly CC license. I have blanked it out and will start implementaiton of my own in a few days. For now there is no help. package com.onarandombox.MultiverseCore.commands; import com.onarandombox.MultiverseCore.MultiverseCore; diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/ImportCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/ImportCommand.java index 4c197a0c..bbb1edbc 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/ImportCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/ImportCommand.java @@ -13,6 +13,7 @@ import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.pneumaticraft.commandhandler.CommandHandler; import org.bukkit.ChatColor; import org.bukkit.World.Environment; +import org.bukkit.WorldType; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.permissions.PermissionDefault; @@ -32,12 +33,13 @@ public class ImportCommand extends MultiverseCommand { public ImportCommand(MultiverseCore plugin) { super(plugin); this.setName("Import World"); - this.setCommandUsage("/mv import" + ChatColor.GREEN + " {NAME} {ENV} " + ChatColor.GOLD + " -g [GENERATOR[:ID]] [-n]"); - this.setArgRange(1, 3); + this.setCommandUsage("/mv import" + ChatColor.GREEN + " {NAME} {ENV} " + ChatColor.GOLD + " -g [GENERATOR[:ID]] [-n] -t [TYPE]"); + this.setArgRange(2, 5); // SUPPRESS CHECKSTYLE: MagicNumberCheck this.addKey("mvimport"); this.addKey("mvim"); this.addKey("mv import"); this.addCommandExample("/mv import " + ChatColor.GOLD + "gargamel" + ChatColor.GREEN + " normal"); + this.addCommandExample("/mv import " + ChatColor.GOLD + "flatroom" + ChatColor.GREEN + " normal" + ChatColor.AQUA + " -t flat"); this.addCommandExample("/mv import " + ChatColor.GOLD + "hell_world" + ChatColor.GREEN + " nether"); this.addCommandExample("/mv import " + ChatColor.GOLD + "CleanRoom" + ChatColor.GREEN + " normal" + ChatColor.DARK_AQUA + " CleanRoomGenerator"); this.setPermission("multiverse.core.import", "Imports a new world of the specified type.", PermissionDefault.OP); @@ -126,6 +128,7 @@ public class ImportCommand extends MultiverseCommand { File worldFile = new File(this.plugin.getServer().getWorldContainer(), worldName); String generator = CommandHandler.getFlag("-g", args); + String typeString = CommandHandler.getFlag("-t", args); boolean useSpawnAdjust = true; for (String s : args) { if (s.equalsIgnoreCase("-n")) { @@ -134,16 +137,27 @@ public class ImportCommand extends MultiverseCommand { } String env = args.get(1); - Environment environment = this.plugin.getEnvFromString(env); + Environment environment = EnvironmentCommand.getEnvFromString(env); if (environment == null) { sender.sendMessage(ChatColor.RED + "That is not a valid environment."); EnvironmentCommand.showEnvironments(sender); return; } + // If they didn't specify a type, default to NORMAL + if (typeString == null) { + typeString = "NORMAL"; + } + WorldType type = EnvironmentCommand.getWorldTypeFromString(typeString); + if (type == null) { + sender.sendMessage(ChatColor.RED + "That is not a valid World Type."); + EnvironmentCommand.showWorldTypes(sender); + return; + } + if (worldFile.exists() && env != null) { - Command.broadcastCommandMessage(sender, "Starting import of world '" + worldName + "'..."); - if (this.worldManager.addWorld(worldName, environment, null, generator, useSpawnAdjust)) + Command.broadcastCommandMessage(sender, String.format("Starting import of world '%s'...", worldName)); + if (this.worldManager.addWorld(worldName, environment, null, type, generator, useSpawnAdjust)) Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Complete!"); else Command.broadcastCommandMessage(sender, ChatColor.RED + "Failed!"); diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/InfoCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/InfoCommand.java index 8b04903c..c33b06ec 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/InfoCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/InfoCommand.java @@ -109,6 +109,7 @@ public class InfoCommand extends MultiverseCommand { message.add(new FancyMessage("World Name: ", world.getName(), colors)); message.add(new FancyMessage("World Alias: ", world.getColoredWorldString(), colors)); message.add(new FancyMessage("Game Mode: ", world.getGameMode().toString(), colors)); + message.add(new FancyMessage("World Type: ", world.getWorldType().toString(), colors)); //message.add(new FancyMessage("Game Mode: ", StringUtils.capitalize(world.getGameMode().toString()), colors)); Location spawn = world.getSpawnLocation(); message.add(new FancyMessage("Spawn Location: ", plugin.getLocationManipulation().strCoords(spawn), colors)); diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/DifficultyConfigProperty.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/DifficultyConfigProperty.java index ac457e03..42b692c6 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/DifficultyConfigProperty.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/DifficultyConfigProperty.java @@ -106,7 +106,7 @@ public class DifficultyConfigProperty implements MVActiveConfigProperty - * Used to double-monitor {@link Type#PLAYER_PORTAL}. - */ -public class MVPortalAdjustListener extends PlayerListener { - - private MultiverseCore plugin; - - public MVPortalAdjustListener(MultiverseCore core) { - this.plugin = core; - } - - @Override - public void onPlayerPortal(PlayerPortalEvent event) { - this.plugin.log(Level.FINE, "CALLING CORE-ADJUST!!!"); - if (event.isCancelled() || event.getFrom() == null) { - return; - } - - // REMEMBER! getTo MAY be NULL HERE!!! - // If the player was actually outside of the portal, adjust the from location - if (event.getFrom().getWorld().getBlockAt(event.getFrom()).getType() != Material.PORTAL) { - Location newloc = SafeTTeleporter.findPortalBlockNextTo(event.getFrom()); - // TODO: Fix this. Currently, we only check for PORTAL blocks. I'll have to figure out what - // TODO: we want to do here. - if (newloc != null) { - event.setFrom(newloc); - } - } - // Wait for the adjust, then return! - if (event.getTo() == null) { - return; - } - } -} diff --git a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWeatherListener.java b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWeatherListener.java index d6a0ad81..358803e1 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWeatherListener.java +++ b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVWeatherListener.java @@ -9,22 +9,30 @@ package com.onarandombox.MultiverseCore.listeners; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.api.MultiverseWorld; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; import org.bukkit.event.weather.ThunderChangeEvent; import org.bukkit.event.weather.WeatherChangeEvent; -import org.bukkit.event.weather.WeatherListener; /** - * Multiverse's {@link WeatherListener}. + * Multiverse's Weather {@link Listener}. */ -public class MVWeatherListener extends WeatherListener { +public class MVWeatherListener implements Listener { private MultiverseCore plugin; public MVWeatherListener(MultiverseCore plugin) { this.plugin = plugin; } - @Override - public void onWeatherChange(WeatherChangeEvent event) { + /** + * This method is called when the weather changes. + * @param event The Event that was fired. + */ + @EventHandler + public void weatherChange(WeatherChangeEvent event) { + if (event.isCancelled()) { + return; + } MultiverseWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getWorld().getName()); if (world != null) { // If it's going to start raining and we have weather disabled @@ -32,8 +40,15 @@ public class MVWeatherListener extends WeatherListener { } } - @Override - public void onThunderChange(ThunderChangeEvent event) { + /** + * This method is called when a big storm is going to start. + * @param event The Event that was fired. + */ + @EventHandler + public void thunderChange(ThunderChangeEvent event) { + if (event.isCancelled()) { + return; + } MultiverseWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getWorld().getName()); if (world != null) { // If it's going to start raining and we have weather disabled diff --git a/src/main/java/com/onarandombox/MultiverseCore/listeners/MultiverseCoreListener.java b/src/main/java/com/onarandombox/MultiverseCore/listeners/MultiverseCoreListener.java index e81e9539..fa1adf67 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/listeners/MultiverseCoreListener.java +++ b/src/main/java/com/onarandombox/MultiverseCore/listeners/MultiverseCoreListener.java @@ -7,9 +7,6 @@ package com.onarandombox.MultiverseCore.listeners; -import org.bukkit.event.CustomEventListener; -import org.bukkit.event.Event; - import com.onarandombox.MultiverseCore.event.MVConfigReloadEvent; import com.onarandombox.MultiverseCore.event.MVPlayerTouchedPortalEvent; import com.onarandombox.MultiverseCore.event.MVRespawnEvent; @@ -17,80 +14,66 @@ import com.onarandombox.MultiverseCore.event.MVTeleportEvent; import com.onarandombox.MultiverseCore.event.MVVersionEvent; import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent; import com.onarandombox.MultiverseCore.event.MVWorldPropertyChangeEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; /** * Subclasses of this listener can be used to conveniently listen to MultiverseCore-events. */ -public abstract class MultiverseCoreListener extends CustomEventListener { - /** - * {@inheritDoc} - */ - @Override - public final void onCustomEvent(Event event) { - if (event.getEventName().equals("MVConfigReload") && event instanceof MVConfigReloadEvent) { - onMVConfigReload((MVConfigReloadEvent) event); - } else if (event.getEventName().equals("MVPlayerTouchedPortalEvent") && event instanceof MVPlayerTouchedPortalEvent) { - onPlayerTouchedPortal((MVPlayerTouchedPortalEvent) event); - } else if (event.getEventName().equals("MVRespawn") && event instanceof MVRespawnEvent) { - onPlayerRespawn((MVRespawnEvent) event); - } else if (event.getEventName().equals("SafeTTeleporter") && event instanceof MVTeleportEvent) { - onPlayerTeleport((MVTeleportEvent) event); - } else if (event.getEventName().equals("MVVersionEvent") && event instanceof MVVersionEvent) { - onVersionRequest((MVVersionEvent) event); - } else if (event.getEventName().equals("MVWorldDeleteEvent") && event instanceof MVWorldDeleteEvent) { - onWorldDelete((MVWorldDeleteEvent) event); - } else if (event.getEventName().equals("MVWorldPropertyChange") && event instanceof MVWorldPropertyChangeEvent) { - onWorldPropertyChange((MVWorldPropertyChangeEvent) event); - } - } - +public abstract class MultiverseCoreListener implements Listener { /** * Called when a {@link MVWorldPropertyChangeEvent} is fired. * @param event The event. */ - public void onWorldPropertyChange(MVWorldPropertyChangeEvent event) { + @EventHandler + public void worldPropertyChange(MVWorldPropertyChangeEvent event) { } /** * Called when a {@link MVWorldDeleteEvent} is fired. * @param event The event. */ - public void onWorldDelete(MVWorldDeleteEvent event) { + @EventHandler + public void worldDelete(MVWorldDeleteEvent event) { } /** * Called when a {@link MVVersionEvent} is fired. * @param event The event. */ - public void onVersionRequest(MVVersionEvent event) { + @EventHandler + public void versionRequest(MVVersionEvent event) { } /** * Called when a {@link MVTeleportEvent} is fired. * @param event The event. */ - public void onPlayerTeleport(MVTeleportEvent event) { + @EventHandler + public void playerTeleport(MVTeleportEvent event) { } /** * Called when a {@link MVRespawnEvent} is fired. * @param event The event. */ - public void onPlayerRespawn(MVRespawnEvent event) { + @EventHandler + public void playerRespawn(MVRespawnEvent event) { } /** * Called when a {@link MVPlayerTouchedPortalEvent} is fired. * @param event The event. */ - public void onPlayerTouchedPortal(MVPlayerTouchedPortalEvent event) { + @EventHandler + public void playerTouchedPortal(MVPlayerTouchedPortalEvent event) { } /** * Called when a {@link MVConfigReloadEvent} is fired. * @param event The event. */ - public void onMVConfigReload(MVConfigReloadEvent event) { + @EventHandler + public void configReload(MVConfigReloadEvent event) { } - } diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/LocationManipulation.java b/src/main/java/com/onarandombox/MultiverseCore/utils/LocationManipulation.java index ba18ccb3..eeb8203c 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/LocationManipulation.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/LocationManipulation.java @@ -17,6 +17,7 @@ import org.bukkit.util.Vector; import java.text.DecimalFormat; import java.util.Collections; import java.util.HashMap; +import java.util.Locale; import java.util.Map; /** @@ -60,7 +61,10 @@ public class LocationManipulation { if (location == null) { return ""; } - return String.format("%s:%.2f,%.2f,%.2f:%.2f:%.2f", location.getWorld().getName(), + // We set the locale to ENGLISH here so we always save with the format: + // world:1.2,5.4,3.6:1.8:21.3 + // Otherwise we blow up when parsing! + return String.format(Locale.ENGLISH, "%s:%.2f,%.2f,%.2f:%.2f:%.2f", location.getWorld().getName(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); } diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java b/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java index 5c5712c9..2be0c287 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java @@ -128,7 +128,7 @@ public class PermissionTools { // If the toWorld isn't controlled by MV, // We don't care. - if(toWorld == null) { + if (toWorld == null) { return true; } @@ -148,7 +148,7 @@ public class PermissionTools { if (!bank.hasEnough(teleporterPlayer, toWorld.getPrice(), toWorld.getCurrency(), errString)) { return false; } else if (pay) { - bank.pay(teleporterPlayer, toWorld.getPrice(), toWorld.getCurrency()); + bank.give(teleporterPlayer, toWorld.getPrice(), toWorld.getCurrency()); } } return true; diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java index 71390cd8..b8bc41fb 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/WorldManager.java @@ -11,10 +11,12 @@ import com.onarandombox.MultiverseCore.MVWorld; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MultiverseWorld; +import com.onarandombox.MultiverseCore.commands.EnvironmentCommand; import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent; import org.bukkit.World; import org.bukkit.World.Environment; import org.bukkit.WorldCreator; +import org.bukkit.WorldType; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -80,16 +82,16 @@ public class WorldManager implements MVWorldManager { * {@inheritDoc} */ @Override - public boolean addWorld(String name, Environment env, String seedString, String generator) { - return this.addWorld(name, env, seedString, generator, true); + public boolean addWorld(String name, Environment env, String seedString, WorldType type, String generator) { + return this.addWorld(name, env, seedString, type, generator, true); } /** * {@inheritDoc} */ @Override - public boolean addWorld(String name, Environment env, String seedString, String generator, boolean useSpawnAdjust) { - plugin.log(Level.FINE, "Adding world with: " + name + ", " + env.toString() + ", " + seedString + ", " + generator); + public boolean addWorld(String name, Environment env, String seedString, WorldType type, String generator, boolean useSpawnAdjust) { + plugin.log(Level.FINE, "Adding world with: " + name + ", " + env.toString() + ", " + seedString + ", " + type.toString() + ", " + generator); Long seed = null; WorldCreator c = new WorldCreator(name); if (seedString != null && seedString.length() > 0) { @@ -101,27 +103,26 @@ public class WorldManager implements MVWorldManager { c.seed(seed); } - // TODO: Use the fancy kind with the commandSender if (generator != null && generator.length() != 0) { c.generator(generator); } c.environment(env); + c.type(type); - World world = null; + World world; + StringBuilder builder = new StringBuilder(); + builder.append("Loading World & Settings - '").append(name).append("'"); + builder.append(" - Env: ").append(env); + builder.append(" - Type: ").append(type); if (seed != null) { - if (generator != null) { - this.plugin.log(Level.INFO, "Loading World & Settings - '" + name + "' - " + env + " with seed: " + seed + " & Custom Generator: " + generator); - } else { - this.plugin.log(Level.INFO, "Loading World & Settings - '" + name + "' - " + env + " with seed: " + seed); - } - } else { - if (generator != null) { - this.plugin.log(Level.INFO, "Loading World & Settings - '" + name + "' - " + env + " & Custom Generator: " + generator); - } else { - this.plugin.log(Level.INFO, "Loading World & Settings - '" + name + "' - " + env); - } + builder.append(" & seed: ").append(seed); } + if (generator != null) { + builder.append(" & generator: ").append(generator); + } + this.plugin.log(Level.INFO, builder.toString()); + try { world = c.createWorld(); } catch (Exception e) { @@ -275,10 +276,12 @@ public class WorldManager implements MVWorldManager { if ((worldKeys != null) && (worldKeys.contains(name))) { // Grab the initial values from the config file. String environment = this.configWorlds.getString("worlds." + name + ".environment", "NORMAL"); // Grab the Environment as a String. + String type = this.configWorlds.getString("worlds." + name + ".type", "NORMAL"); String seedString = this.configWorlds.getString("worlds." + name + ".seed", ""); String generatorString = this.configWorlds.getString("worlds." + name + ".generator"); - addWorld(name, this.plugin.getEnvFromString(environment), seedString, generatorString); + addWorld(name, EnvironmentCommand.getEnvFromString(environment), seedString, + EnvironmentCommand.getWorldTypeFromString(type), generatorString); if (this.unloadedWorlds.contains(name)) { this.unloadedWorlds.remove(name); } @@ -464,9 +467,9 @@ public class WorldManager implements MVWorldManager { String name = w.getName(); if (!worldStrings.contains(name)) { if (this.defaultGens.containsKey(name)) { - this.addWorld(name, w.getEnvironment(), w.getSeed() + "", this.defaultGens.get(name)); + this.addWorld(name, w.getEnvironment(), w.getSeed() + "", w.getWorldType(), this.defaultGens.get(name)); } else { - this.addWorld(name, w.getEnvironment(), w.getSeed() + "", null); + this.addWorld(name, w.getEnvironment(), w.getSeed() + "", w.getWorldType(), null); } } @@ -537,7 +540,8 @@ public class WorldManager implements MVWorldManager { continue; } // Grab the initial values from the config file. - String environment = this.configWorlds.getString("worlds." + worldKey + ".environment", "NORMAL"); // Grab the Environment as a String. + String environment = this.configWorlds.getString("worlds." + worldKey + ".environment", "NORMAL"); + String type = this.configWorlds.getString("worlds." + worldKey + ".type", "NORMAL"); String seedString = this.configWorlds.getString("worlds." + worldKey + ".seed", null); if (seedString == null) { seedString = this.configWorlds.getLong("worlds." + worldKey + ".seed") + ""; @@ -548,7 +552,9 @@ public class WorldManager implements MVWorldManager { this.plugin.log(Level.WARNING, "Found SKYLANDS world. Not importing automatically, as it won't work atm :("); continue; } - addWorld(worldKey, this.plugin.getEnvFromString(environment), seedString, generatorString); + // TODO: UNCOMMENT BEFORE RELEASE + addWorld(worldKey, EnvironmentCommand.getEnvFromString(environment), seedString, + EnvironmentCommand.getWorldTypeFromString(type), generatorString); // Increment the world count count++; diff --git a/src/test/java/com/onarandombox/MultiverseCore/test/TestWorldProperties.java b/src/test/java/com/onarandombox/MultiverseCore/test/TestWorldProperties.java new file mode 100644 index 00000000..45412ccf --- /dev/null +++ b/src/test/java/com/onarandombox/MultiverseCore/test/TestWorldProperties.java @@ -0,0 +1,344 @@ +/****************************************************************************** + * Multiverse 2 Copyright (c) the Multiverse Team 2012. * + * 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.test; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.*; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Difficulty; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.weather.ThunderChangeEvent; +import org.bukkit.event.weather.WeatherChangeEvent; +import org.bukkit.permissions.Permission; +import org.bukkit.plugin.PluginManager; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.internal.verification.VerificationModeFactory; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import com.onarandombox.MultiverseCore.MultiverseCore; +import com.onarandombox.MultiverseCore.api.MVWorldManager; +import com.onarandombox.MultiverseCore.api.MultiverseWorld; +import com.onarandombox.MultiverseCore.test.utils.TestInstanceCreator; +import com.onarandombox.MultiverseCore.utils.WorldManager; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({ PluginManager.class, MultiverseCore.class, Permission.class, Bukkit.class, + WeatherChangeEvent.class, ThunderChangeEvent.class, PlayerChatEvent.class, + PlayerJoinEvent.class, PlayerRespawnEvent.class, EntityRegainHealthEvent.class, + FoodLevelChangeEvent.class, WorldManager.class }) +public class TestWorldProperties { + + private TestInstanceCreator creator; + private MultiverseCore core; + private CommandSender mockCommandSender; + + // Events + private WeatherChangeEvent weatherChangeOffEvent; + private WeatherChangeEvent weatherChangeOnEvent; + private ThunderChangeEvent thunderChangeOffEvent; + private ThunderChangeEvent thunderChangeOnEvent; + private Player mockPlayer; + private PlayerChatEvent playerChatEvent; + private Player mockNewPlayer; + private PlayerJoinEvent playerNewJoinEvent; + private PlayerJoinEvent playerJoinEvent; + private PlayerRespawnEvent playerRespawnBed; + private PlayerRespawnEvent playerRespawnNormal; + private Entity mockEntity; + private EntityRegainHealthEvent entityRegainHealthEvent; + private FoodLevelChangeEvent entityFoodLevelChangeEvent; + private FoodLevelChangeEvent entityFoodLevelRiseEvent; + + @Before + public void setUp() throws Exception { + creator = new TestInstanceCreator(); + assertTrue(creator.setUp()); + core = creator.getCore(); + mockCommandSender = creator.getCommandSender(); + } + + @After + public void tearDown() throws Exception { + creator.tearDown(); + } + + @Test + public void test() { + // Initialize a fake command + Command mockCommand = mock(Command.class); + when(mockCommand.getName()).thenReturn("mv"); + + // Import the first world + String[] normalArgs = new String[] { "import", "world", "normal" }; + core.onCommand(mockCommandSender, mockCommand, "", normalArgs); + verify(mockCommandSender).sendMessage("Starting import of world 'world'..."); + verify(mockCommandSender).sendMessage(ChatColor.GREEN + "Complete!"); + + // Import a second world + String[] netherArgs = new String[] { "import", "world_nether", "nether" }; + core.onCommand(mockCommandSender, mockCommand, "", netherArgs); + verify(mockCommandSender).sendMessage("Starting import of world 'world_nether'..."); + verify(mockCommandSender, VerificationModeFactory.times(2)).sendMessage( + ChatColor.GREEN + "Complete!"); + + // //////////////////////////////////////////////// + // let's set some world-properties + // we can test the API with this, too :D + MVWorldManager worldManager = core.getMVWorldManager(); + assertNotNull(worldManager); + + MultiverseWorld mvWorld = worldManager.getMVWorld("world"); + MultiverseWorld netherWorld = worldManager.getMVWorld("world_nether"); + assertNotNull(mvWorld); + assertNotNull(netherWorld); + assertSame(mvWorld, worldManager.getFirstSpawnWorld()); + assertSame(mvWorld, worldManager.getSpawnWorld()); + + /* ***************************** * + * Check defaults + * ***************************** */ + assertFalse(mvWorld.isHidden()); + assertEquals(mvWorld.getName(), mvWorld.getAlias()); + assertEquals(ChatColor.WHITE, mvWorld.getColor()); + assertTrue(mvWorld.isPVPEnabled()); + assertEquals((Object) 1D, (Object) mvWorld.getScaling()); // we're casting this to objects to use + // assertEquals(Object,Object) instead of assertEquals(double,double) + assertNull(mvWorld.getRespawnToWorld()); + assertTrue(mvWorld.isWeatherEnabled()); + World cbWorld = mvWorld.getCBWorld(); + when(cbWorld.getDifficulty()).thenReturn(Difficulty.NORMAL); + assertEquals(Difficulty.NORMAL, mvWorld.getDifficulty()); + assertTrue(mvWorld.canAnimalsSpawn()); + assertTrue(mvWorld.canMonstersSpawn()); + assertEquals(-1, mvWorld.getCurrency()); + assertEquals(0, mvWorld.getPrice(), 0); + assertTrue(mvWorld.getHunger()); + assertTrue(mvWorld.getAutoHeal()); + assertTrue(mvWorld.getAdjustSpawn()); + assertEquals(GameMode.SURVIVAL, mvWorld.getGameMode()); + assertTrue(mvWorld.isKeepingSpawnInMemory()); + assertTrue(mvWorld.getBedRespawn()); + assertTrue(mvWorld.getAutoLoad()); + assertEquals(new Location(mvWorld.getCBWorld(), 0, 64, 0), mvWorld.getSpawnLocation()); + + /* ****************************************** * + * Call some events and verify behavior + * ****************************************** */ + createEvents(mvWorld); + + // call both weather change events + core.getWeatherListener().weatherChange(weatherChangeOffEvent); + assertFalse(weatherChangeOffEvent.isCancelled()); + core.getWeatherListener().weatherChange(weatherChangeOnEvent); + assertFalse(weatherChangeOnEvent.isCancelled()); + + // call both thunder change events + core.getWeatherListener().thunderChange(thunderChangeOffEvent); + assertFalse(thunderChangeOffEvent.isCancelled()); + core.getWeatherListener().thunderChange(thunderChangeOnEvent); + assertFalse(thunderChangeOnEvent.isCancelled()); + + // call player chat event + MultiverseCore.PrefixChat = true; + core.getPlayerListener().playerChat(playerChatEvent); + verify(playerChatEvent).setFormat("[" + mvWorld.getColoredWorldString() + "]" + "format"); + MultiverseCore.PrefixChat = false; + core.getPlayerListener().playerChat(playerChatEvent); + verify(playerChatEvent, times(1)).setFormat(anyString()); // only ONE TIME (not the 2nd time!) + + // call player join events + core.getPlayerListener().playerJoin(playerJoinEvent); + verify(mockPlayer, never()).teleport(any(Location.class)); + core.getPlayerListener().playerJoin(playerNewJoinEvent); + verify(mockNewPlayer).teleport(worldManager.getFirstSpawnWorld().getSpawnLocation()); + + // call player respawn events + core.getPlayerListener().playerRespawn(playerRespawnBed); + // bedrespawn is on so nothing should happen + verify(playerRespawnBed, never()).setRespawnLocation(any(Location.class)); + core.getPlayerListener().playerRespawn(playerRespawnNormal); + verify(playerRespawnNormal).setRespawnLocation(mvWorld.getSpawnLocation()); + + // call entity regain health event + core.getEntityListener().entityRegainHealth(entityRegainHealthEvent); + // autoheal is on so nothing should happen + verify(entityRegainHealthEvent, never()).setCancelled(true); + + + /* ************************ * + * Modify & Verify + * ************************ */ + mvWorld.setHidden(true); + assertEquals(true, mvWorld.isHidden()); + mvWorld.setAlias("alias"); + assertEquals("alias", mvWorld.getAlias()); + assertTrue(mvWorld.setColor("BLACK")); + ChatColor oldColor = mvWorld.getColor(); + assertFalse(mvWorld.setColor("INVALID COLOR")); + assertEquals(oldColor, mvWorld.getColor()); + assertEquals(oldColor.toString() + "alias" + ChatColor.WHITE.toString(), mvWorld.getColoredWorldString()); + mvWorld.setPVPMode(false); + assertEquals(false, mvWorld.isPVPEnabled()); + assertTrue(mvWorld.setScaling(2D)); + assertEquals((Object) 2D, (Object) mvWorld.getScaling()); + assertFalse(mvWorld.setRespawnToWorld("INVALID WORLD")); + assertTrue(mvWorld.setRespawnToWorld("world_nether")); + assertSame(worldManager.getMVWorld("world_nether").getCBWorld(), + mvWorld.getRespawnToWorld()); + mvWorld.setEnableWeather(false); + assertEquals(false, mvWorld.isWeatherEnabled()); + assertTrue(mvWorld.setDifficulty("PEACEFUL")); + Difficulty oldDifficulty = mvWorld.getDifficulty(); + assertFalse(mvWorld.setDifficulty("INVALID DIFFICULTY")); + assertEquals(oldDifficulty, mvWorld.getDifficulty()); + mvWorld.setAllowAnimalSpawn(false); + assertEquals(false, mvWorld.canAnimalsSpawn()); + mvWorld.setAllowMonsterSpawn(false); + assertEquals(false, mvWorld.canMonstersSpawn()); + mvWorld.setCurrency(1); + assertEquals(1, mvWorld.getCurrency()); + mvWorld.setPrice(1D); + assertEquals((Object) 1D, (Object) mvWorld.getPrice()); + mvWorld.setHunger(false); + assertEquals(false, mvWorld.getHunger()); + mvWorld.setAutoHeal(false); + assertEquals(false, mvWorld.getAutoHeal()); + mvWorld.setAdjustSpawn(false); + assertEquals(false, mvWorld.getAdjustSpawn()); + assertTrue(mvWorld.setGameMode("CREATIVE")); + GameMode oldGamemode = mvWorld.getGameMode(); + assertFalse(mvWorld.setGameMode("INVALID GAMEMODE")); + assertEquals(oldGamemode, mvWorld.getGameMode()); + mvWorld.setKeepSpawnInMemory(false); + assertEquals(false, mvWorld.isKeepingSpawnInMemory()); + mvWorld.setBedRespawn(false); + assertEquals(false, mvWorld.getBedRespawn()); + mvWorld.setAutoLoad(false); + assertEquals(false, mvWorld.getAutoLoad()); + mvWorld.setSpawnLocation(new Location(mvWorld.getCBWorld(), 1, 1, 1)); + assertEquals(new Location(mvWorld.getCBWorld(), 1, 1, 1), mvWorld.getSpawnLocation()); + + /* ****************************************** * + * Call some events and verify behavior + * ****************************************** */ + // We have to recreate the events and the mock-objects + createEvents(mvWorld); + + // call both weather change events + core.getWeatherListener().weatherChange(weatherChangeOffEvent); + assertFalse(weatherChangeOffEvent.isCancelled()); + core.getWeatherListener().weatherChange(weatherChangeOnEvent); + assertTrue(weatherChangeOnEvent.isCancelled()); + + // call both thunder change events + core.getWeatherListener().thunderChange(thunderChangeOffEvent); + assertFalse(thunderChangeOffEvent.isCancelled()); + core.getWeatherListener().thunderChange(thunderChangeOnEvent); + assertTrue(thunderChangeOnEvent.isCancelled()); + + // call player chat event + MultiverseCore.PrefixChat = true; + core.getPlayerListener().playerChat(playerChatEvent); + // never because it's hidden! + verify(playerChatEvent, never()).setFormat( + "[" + mvWorld.getColoredWorldString() + "]" + "format"); + mvWorld.setHidden(false); + core.getPlayerListener().playerChat(playerChatEvent); + verify(playerChatEvent).setFormat("[" + mvWorld.getColoredWorldString() + "]" + "format"); + MultiverseCore.PrefixChat = false; + core.getPlayerListener().playerChat(playerChatEvent); + verify(playerChatEvent, times(1)).setFormat(anyString()); // only ONE TIME (not the 2nd time!) + + // call player join events + core.getPlayerListener().playerJoin(playerJoinEvent); + verify(mockPlayer, never()).teleport(any(Location.class)); + core.getPlayerListener().playerJoin(playerNewJoinEvent); + verify(mockNewPlayer).teleport(new Location(mvWorld.getCBWorld(), 1, 1, 1)); + + // call player respawn events + core.getPlayerListener().playerRespawn(playerRespawnBed); + // bedrespawn is off so something should happen (and we've set respawn to nether...) + verify(playerRespawnBed).setRespawnLocation(netherWorld.getSpawnLocation()); + core.getPlayerListener().playerRespawn(playerRespawnNormal); + verify(playerRespawnNormal).setRespawnLocation(netherWorld.getSpawnLocation()); + + // call entity regain health event + core.getEntityListener().entityRegainHealth(entityRegainHealthEvent); + // autoheal is off so something should happen + verify(entityRegainHealthEvent).setCancelled(true); + } + + public void createEvents(MultiverseWorld mvWorld) { + //// Weather events + // weather change + weatherChangeOffEvent = new WeatherChangeEvent(mvWorld.getCBWorld(), false); + weatherChangeOnEvent = new WeatherChangeEvent(mvWorld.getCBWorld(), true); + // thunder change + thunderChangeOffEvent = new ThunderChangeEvent(mvWorld.getCBWorld(), false); + thunderChangeOnEvent = new ThunderChangeEvent(mvWorld.getCBWorld(), true); + //// Player events + // player chat + mockPlayer = mock(Player.class); + when(mockPlayer.getWorld()).thenReturn(mvWorld.getCBWorld()); + when(mockPlayer.hasPlayedBefore()).thenReturn(true); + playerChatEvent = PowerMockito.mock(PlayerChatEvent.class); + when(playerChatEvent.getPlayer()).thenReturn(mockPlayer); + when(playerChatEvent.getFormat()).thenReturn("format"); + // player join + mockNewPlayer = mock(Player.class); + when(mockNewPlayer.hasPlayedBefore()).thenReturn(false); + playerJoinEvent = PowerMockito.mock(PlayerJoinEvent.class); + when(playerJoinEvent.getPlayer()).thenReturn(mockPlayer); + playerNewJoinEvent = PowerMockito.mock(PlayerJoinEvent.class); + when(playerNewJoinEvent.getPlayer()).thenReturn(mockNewPlayer); + // player respawn + playerRespawnBed = PowerMockito.mock(PlayerRespawnEvent.class); + when(playerRespawnBed.getPlayer()).thenReturn(mockPlayer); + when(playerRespawnBed.isBedSpawn()).thenReturn(true); + playerRespawnNormal = PowerMockito.mock(PlayerRespawnEvent.class); + when(playerRespawnNormal.getPlayer()).thenReturn(mockPlayer); + when(playerRespawnNormal.isBedSpawn()).thenReturn(false); + //// Entity events + mockEntity = mock(Entity.class); + // entity regain health + entityRegainHealthEvent = PowerMockito.mock(EntityRegainHealthEvent.class); + when(entityRegainHealthEvent.getRegainReason()).thenReturn(RegainReason.REGEN); + when(mockEntity.getLocation()).thenReturn(new Location(mvWorld.getCBWorld(), 0, 0, 0)); + when(entityRegainHealthEvent.getEntity()).thenReturn(mockEntity); + // entity food level change event + entityFoodLevelChangeEvent = PowerMockito.mock(FoodLevelChangeEvent.class); + // this won't do anything since we're not mocking a player, + // but the plugin should be able to handle this! + when(entityFoodLevelChangeEvent.getEntity()).thenReturn(mockEntity); + entityFoodLevelRiseEvent = PowerMockito.mock(FoodLevelChangeEvent.class); + when(mockPlayer.getFoodLevel()).thenReturn(2); + when(entityFoodLevelRiseEvent.getEntity()).thenReturn(mockPlayer); + when(entityFoodLevelRiseEvent.getFoodLevel()).thenReturn(3); + } +} diff --git a/src/test/java/com/onarandombox/MultiverseCore/test/TestWorldStuff.java b/src/test/java/com/onarandombox/MultiverseCore/test/TestWorldStuff.java index 707776c0..894cf2f2 100644 --- a/src/test/java/com/onarandombox/MultiverseCore/test/TestWorldStuff.java +++ b/src/test/java/com/onarandombox/MultiverseCore/test/TestWorldStuff.java @@ -168,6 +168,41 @@ public class TestWorldStuff { } @Test + public void testNullWorld() { + // Pull a core instance from the server. + Plugin plugin = mockServer.getPluginManager().getPlugin("Multiverse-Core"); + + // Make sure Core is not null + assertNotNull(plugin); + + // Make sure Core is enabled + assertTrue(plugin.isEnabled()); + + // Initialize a fake command + Command mockCommand = mock(Command.class); + when(mockCommand.getName()).thenReturn("mv"); + + // Ensure that there are no worlds imported. This is a fresh setup. + assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size()); + + // Create the NULL world + // The safe check is now BALLS SLOW. Use the -n to skip checking. + String[] normalArgs = new String[]{ "create", "nullworld", "normal", "-n" }; + plugin.onCommand(mockCommandSender, mockCommand, "", normalArgs); + + // We should now have one world! + assertEquals(1, creator.getCore().getMVWorldManager().getMVWorlds().size()); + + // Verify + verify(mockCommandSender).sendMessage("Starting creation of world 'nullworld'..."); + verify(mockCommandSender).sendMessage("Complete!"); + + WorldCreatorMatcher matcher = new WorldCreatorMatcher(new WorldCreator("nullworld")); + verify(mockServer).createWorld(Matchers.argThat(matcher)); + } + + @Test + // TODO Migrate this to TestWorldProperties public void testModifyGameMode() { // Pull a core instance from the server. Plugin plugin = mockServer.getPluginManager().getPlugin("Multiverse-Core"); diff --git a/src/test/java/com/onarandombox/MultiverseCore/test/utils/MockBlock.java b/src/test/java/com/onarandombox/MultiverseCore/test/utils/MockBlock.java index b5d12199..57e6a331 100644 --- a/src/test/java/com/onarandombox/MultiverseCore/test/utils/MockBlock.java +++ b/src/test/java/com/onarandombox/MultiverseCore/test/utils/MockBlock.java @@ -12,6 +12,9 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.*; +import org.bukkit.inventory.ItemStack; + +import java.util.Collection; /** * Multiverse 2 @@ -27,35 +30,31 @@ public class MockBlock implements Block{ } /** - * Gets the metadata for this block - * - * @return block specific metadata + * {@inheritDoc} */ @Override public byte getData() { return 0; } - /** @deprecated use {@link #getRelative(org.bukkit.block.BlockFace face)} */ + /** + * {@inheritDoc} + */ @Override public Block getFace(BlockFace face) { return null; } - /** @deprecated use {@link #getRelative(org.bukkit.block.BlockFace face, int distance)} */ + /** + * {@inheritDoc} + */ @Override public Block getFace(BlockFace face, int distance) { return null; } /** - * Gets the block at the given offsets - * - * @param modX X-coordinate offset - * @param modY Y-coordinate offset - * @param modZ Z-coordinate offset - * - * @return Block at the given offsets + * {@inheritDoc} */ @Override public Block getRelative(int modX, int modY, int modZ) { @@ -63,15 +62,7 @@ public class MockBlock implements Block{ } /** - * Gets the block at the given face
- *
- * This method is equal to getRelative(face, 1) - * - * @param face Face of this block to return - * - * @return Block at the given face - * - * @see #getRelative(org.bukkit.block.BlockFace, int) + * {@inheritDoc} */ @Override public Block getRelative(BlockFace face) { @@ -79,20 +70,7 @@ public class MockBlock implements Block{ } /** - * Gets the block at the given distance of the given face
- *
- * For example, the following method places water at 100,102,100; two blocks - * above 100,100,100. - *

-     * Block block = world.getBlockAt(100,100,100);
-     * Block shower = block.getFace(BlockFace.UP, 2);
-     * shower.setType(Material.WATER);
-     * 
- * - * @param face Face of this block to return - * @param distance Distance to get the block at - * - * @return Block at the given face + * {@inheritDoc} */ @Override public Block getRelative(BlockFace face, int distance) { @@ -100,9 +78,7 @@ public class MockBlock implements Block{ } /** - * Gets the type of this block - * - * @return block type + * {@inheritDoc} */ @Override public Material getType() { @@ -110,29 +86,33 @@ public class MockBlock implements Block{ } /** - * Gets the type-id of this block - * - * @return block type-id + * {@inheritDoc} */ @Override public int getTypeId() { - return 0; //To change body of implemented methods use File | Settings | File Templates. + return 0; } /** - * Gets the light level between 0-15 - * - * @return light level + * {@inheritDoc} */ @Override public byte getLightLevel() { - return 0; //To change body of implemented methods use File | Settings | File Templates. + return 0; + } + + @Override + public byte getLightFromSky() { + return 0; + } + + @Override + public byte getLightFromBlocks() { + return 0; } /** - * Gets the world which contains this Block - * - * @return World containing this block + * {@inheritDoc} */ @Override public World getWorld() { @@ -140,9 +120,7 @@ public class MockBlock implements Block{ } /** - * Gets the x-coordinate of this block - * - * @return x-coordinate + * {@inheritDoc} */ @Override public int getX() { @@ -150,9 +128,7 @@ public class MockBlock implements Block{ } /** - * Gets the y-coordinate of this block - * - * @return y-coordinate + * {@inheritDoc} */ @Override public int getY() { @@ -160,9 +136,7 @@ public class MockBlock implements Block{ } /** - * Gets the z-coordinate of this block - * - * @return z-coordinate + * {@inheritDoc} */ @Override public int getZ() { @@ -170,9 +144,7 @@ public class MockBlock implements Block{ } /** - * Gets the Location of the block - * - * @return Location of block + * {@inheritDoc} */ @Override public Location getLocation() { @@ -180,34 +152,26 @@ public class MockBlock implements Block{ } /** - * Gets the chunk which contains this block - * - * @return Containing Chunk + * {@inheritDoc} */ @Override public Chunk getChunk() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return null; } /** - * Sets the metadata for this block - * - * @param data New block specific metadata + * {@inheritDoc} */ @Override public void setData(byte data) { - //To change body of implemented methods use File | Settings | File Templates. } @Override public void setData(byte data, boolean applyPhyiscs) { - //To change body of implemented methods use File | Settings | File Templates. } /** - * Sets the type of this block - * - * @param type Material to change this block to + * {@inheritDoc} */ @Override public void setType(Material type) { @@ -215,145 +179,97 @@ public class MockBlock implements Block{ } /** - * Sets the type-id of this block - * - * @param type Type-Id to change this block to - * - * @return whether the block was changed + * {@inheritDoc} */ @Override public boolean setTypeId(int type) { - return false; //To change body of implemented methods use File | Settings | File Templates. + return false; } @Override public boolean setTypeId(int type, boolean applyPhysics) { - return false; //To change body of implemented methods use File | Settings | File Templates. + return false; } @Override public boolean setTypeIdAndData(int type, byte data, boolean applyPhyiscs) { - return false; //To change body of implemented methods use File | Settings | File Templates. + return false; } /** - * Gets the face relation of this block compared to the given block
- *
- * For example: - *
-     * Block current = world.getBlockAt(100, 100, 100);
-     * Block target = world.getBlockAt(100, 101, 100);
-     *
-     * current.getFace(target) == BlockFace.Up;
-     * 
- *
- * If the given block is not connected to this block, null may be returned - * - * @param block Block to compare against this block - * - * @return BlockFace of this block which has the requested block, or null + * {@inheritDoc} */ @Override public BlockFace getFace(Block block) { - return null; //To change body of implemented methods use File | Settings | File Templates. + return null; } /** - * Captures the current state of this block. You may then cast that state - * into any accepted type, such as Furnace or Sign. - *

- * The returned object will never be updated, and you are not guaranteed that - * (for example) a sign is still a sign after you capture its state. - * - * @return BlockState with the current state of this block. + * {@inheritDoc} */ @Override public BlockState getState() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return null; } /** - * Returns the biome that this block resides in - * - * @return Biome type containing this block + * {@inheritDoc} */ @Override public Biome getBiome() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return null; } /** - * Returns true if the block is being powered by Redstone. - * - * @return True if the block is powered. + * {@inheritDoc} */ @Override public boolean isBlockPowered() { - return false; //To change body of implemented methods use File | Settings | File Templates. + return false; } /** - * Returns true if the block is being indirectly powered by Redstone. - * - * @return True if the block is indirectly powered. + * {@inheritDoc} */ @Override public boolean isBlockIndirectlyPowered() { - return false; //To change body of implemented methods use File | Settings | File Templates. + return false; } /** - * Returns true if the block face is being powered by Redstone. - * - * @param face The block face - * - * @return True if the block face is powered. + * {@inheritDoc} */ @Override public boolean isBlockFacePowered(BlockFace face) { - return false; //To change body of implemented methods use File | Settings | File Templates. + return false; } /** - * Returns true if the block face is being indirectly powered by Redstone. - * - * @param face The block face - * - * @return True if the block face is indirectly powered. + * {@inheritDoc} */ @Override public boolean isBlockFaceIndirectlyPowered(BlockFace face) { - return false; //To change body of implemented methods use File | Settings | File Templates. + return false; } /** - * Returns the redstone power being provided to this block face - * - * @param face the face of the block to query or BlockFace.SELF for the block itself - * - * @return The power level. + * {@inheritDoc} */ @Override public int getBlockPower(BlockFace face) { - return 0; //To change body of implemented methods use File | Settings | File Templates. + return 0; } /** - * Returns the redstone power being provided to this block - * - * @return The power level. + * {@inheritDoc} */ @Override public int getBlockPower() { - return 0; //To change body of implemented methods use File | Settings | File Templates. + return 0; } /** - * Checks if this block is empty. - *

- * A block is considered empty when {@link #getType()} returns {@link org.bukkit.Material#AIR}. - * - * @return true if this block is empty + * {@inheritDoc} */ @Override public boolean isEmpty() { @@ -361,46 +277,54 @@ public class MockBlock implements Block{ } /** - * Checks if this block is liquid. - *

- * A block is considered liquid when {@link #getType()} returns {@link org.bukkit.Material#WATER}, {@link - * org.bukkit.Material#STATIONARY_WATER}, {@link org.bukkit.Material#LAVA} or {@link - * org.bukkit.Material#STATIONARY_LAVA}. - * - * @return true if this block is liquid + * {@inheritDoc} */ @Override public boolean isLiquid() { - return false; //To change body of implemented methods use File | Settings | File Templates. + return false; } /** - * Gets the temperature of the biome of this block - * - * @return Temperature of this block + * {@inheritDoc} */ @Override public double getTemperature() { - return 0; //To change body of implemented methods use File | Settings | File Templates. + return 0; } /** - * Gets the humidity of the biome of this block - * - * @return Humidity of this block + * {@inheritDoc} */ @Override public double getHumidity() { - return 0; //To change body of implemented methods use File | Settings | File Templates. + return 0; } /** - * Returns the reaction of the block when moved by a piston - * - * @return reaction + * {@inheritDoc} */ @Override public PistonMoveReaction getPistonMoveReaction() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return null; + } + + @Override + public boolean breakNaturally() { + return false; + } + + @Override + public boolean breakNaturally(ItemStack itemStack) { + return false; + } + + @Override + public Collection getDrops() { + return null; + } + + @Override + public Collection getDrops(ItemStack itemStack) { + return null; } } diff --git a/src/test/java/com/onarandombox/MultiverseCore/test/utils/MockWorldFactory.java b/src/test/java/com/onarandombox/MultiverseCore/test/utils/MockWorldFactory.java index 1df477ae..c0f22b03 100644 --- a/src/test/java/com/onarandombox/MultiverseCore/test/utils/MockWorldFactory.java +++ b/src/test/java/com/onarandombox/MultiverseCore/test/utils/MockWorldFactory.java @@ -7,8 +7,7 @@ package com.onarandombox.MultiverseCore.test.utils; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; import java.io.File; import java.util.ArrayList; @@ -19,9 +18,9 @@ import java.util.Map; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; +import org.bukkit.WorldType; +import org.bukkit.block.Block; import org.bukkit.generator.ChunkGenerator; -import org.mockito.ArgumentMatcher; -import org.mockito.Matchers; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -32,60 +31,16 @@ public class MockWorldFactory { private MockWorldFactory() { } - private static class LocationMatcher extends ArgumentMatcher { - private Location l; - - public LocationMatcher(Location location) { - this.l = location; - } - - public boolean matches(Object creator) { - return creator.equals(l); - } - } - - private static class LocationMatcherAbove extends LocationMatcher { - - public LocationMatcherAbove(Location location) { - super(location); - } - - public boolean matches(Object creator) { - Util.log("Checking above..."); - if (super.l == null || creator == null) { - return false; - } - boolean equal = ((Location) creator).getBlockY() >= super.l.getBlockY(); - Util.log("Checking equals/\\..." + equal); - return equal; - } - } - - private static class LocationMatcherBelow extends LocationMatcher { - - public LocationMatcherBelow(Location location) { - super(location); - } - - public boolean matches(Object creator) { - if (super.l == null || creator == null) { - return false; - } - boolean equal = ((Location) creator).getBlockY() < super.l.getBlockY(); - Util.log("Checking equals\\/..." + equal); - return equal; - } - } - private static void registerWorld(World world) { createdWorlds.put(world.getName(), world); } - private static World basics(String world, World.Environment env) { + private static World basics(String world, World.Environment env, WorldType type) { World mockWorld = mock(World.class); when(mockWorld.getName()).thenReturn(world); when(mockWorld.getEnvironment()).thenReturn(env); - when(mockWorld.getSpawnLocation()).thenReturn(new Location(mockWorld, 0, 0, 0)); + when(mockWorld.getWorldType()).thenReturn(type); + when(mockWorld.getSpawnLocation()).thenReturn(new Location(mockWorld, 0, 64, 0)); when(mockWorld.getWorldFolder()).thenAnswer(new Answer() { public File answer(InvocationOnMock invocation) throws Throwable { if (!(invocation.getMock() instanceof World)) @@ -93,23 +48,92 @@ public class MockWorldFactory { World thiss = (World) invocation.getMock(); return new File(TestInstanceCreator.serverDirectory, thiss.getName()); - }}); - LocationMatcherAbove matchWorldAbove = new LocationMatcherAbove(new Location(mockWorld, 0, 0, 0)); - LocationMatcherBelow matchWorldBelow = new LocationMatcherBelow(new Location(mockWorld, 0, 0, 0)); - when(mockWorld.getBlockAt(Matchers.argThat(matchWorldAbove))).thenReturn(new MockBlock(new Location(mockWorld, 0, 0, 0), Material.AIR)); - when(mockWorld.getBlockAt(Matchers.argThat(matchWorldBelow))).thenReturn(new MockBlock(new Location(mockWorld, 0, 0, 0), Material.STONE)); + } + }); + when(mockWorld.getBlockAt(any(Location.class))).thenAnswer(new Answer() { + public Block answer(InvocationOnMock invocation) throws Throwable { + Location loc; + try { + loc = (Location) invocation.getArguments()[0]; + } catch (Exception e) { + return null; + } + Material blockType = Material.AIR; + Block mockBlock = mock(Block.class); + if (loc.getBlockY() < 64) { + blockType = Material.DIRT; + } + + when(mockBlock.getType()).thenReturn(blockType); + when(mockBlock.getTypeId()).thenReturn(blockType.getId()); + when(mockBlock.getWorld()).thenReturn(loc.getWorld()); + when(mockBlock.getX()).thenReturn(loc.getBlockX()); + when(mockBlock.getY()).thenReturn(loc.getBlockY()); + when(mockBlock.getZ()).thenReturn(loc.getBlockZ()); + when(mockBlock.getLocation()).thenReturn(loc); + when(mockBlock.isEmpty()).thenReturn(blockType == Material.AIR); + return mockBlock; + } + }); return mockWorld; } - public static World makeNewMockWorld(String world, World.Environment env) { - World w = basics(world, env); + private static World nullWorld(String world, World.Environment env, WorldType type) { + World mockWorld = mock(World.class); + when(mockWorld.getName()).thenReturn(world); + when(mockWorld.getEnvironment()).thenReturn(env); + when(mockWorld.getWorldType()).thenReturn(type); + when(mockWorld.getSpawnLocation()).thenReturn(new Location(mockWorld, 0, 64, 0)); + when(mockWorld.getWorldFolder()).thenAnswer(new Answer() { + public File answer(InvocationOnMock invocation) throws Throwable { + if (!(invocation.getMock() instanceof World)) + return null; + + World thiss = (World) invocation.getMock(); + return new File(TestInstanceCreator.serverDirectory, thiss.getName()); + } + }); + when(mockWorld.getBlockAt(any(Location.class))).thenAnswer(new Answer() { + public Block answer(InvocationOnMock invocation) throws Throwable { + Location loc; + try { + loc = (Location) invocation.getArguments()[0]; + } catch (Exception e) { + return null; + } + + Block mockBlock = mock(Block.class); + Material blockType = Material.AIR; + + when(mockBlock.getType()).thenReturn(blockType); + when(mockBlock.getTypeId()).thenReturn(blockType.getId()); + when(mockBlock.getWorld()).thenReturn(loc.getWorld()); + when(mockBlock.getX()).thenReturn(loc.getBlockX()); + when(mockBlock.getY()).thenReturn(loc.getBlockY()); + when(mockBlock.getZ()).thenReturn(loc.getBlockZ()); + when(mockBlock.getLocation()).thenReturn(loc); + when(mockBlock.isEmpty()).thenReturn(blockType == Material.AIR); + return mockBlock; + } + }); + return mockWorld; + } + + public static World makeNewMockWorld(String world, World.Environment env, WorldType type) { + World w = basics(world, env, type); registerWorld(w); return w; } - public static World makeNewMockWorld(String world, World.Environment env, long seed, + public static World makeNewNullMockWorld(String world, World.Environment env, WorldType type) { + World w = nullWorld(world, env, type); + registerWorld(w); + return w; + } + + public static World makeNewMockWorld(String world, World.Environment env, WorldType type, long seed, ChunkGenerator generator) { - World mockWorld = basics(world, env); + World mockWorld = basics(world, env, type); when(mockWorld.getGenerator()).thenReturn(generator); when(mockWorld.getSeed()).thenReturn(seed); registerWorld(mockWorld); @@ -121,7 +145,13 @@ public class MockWorldFactory { } public static List getWorlds() { - return new ArrayList(createdWorlds.values()); + // we have to invert the order! + ArrayList myList = new ArrayList(createdWorlds.values()); + List retList = new ArrayList(); + for (int i = (myList.size() - 1); i >= 0; i--) { + retList.add(myList.get(i)); + } + return retList; } public static void clearWorlds() { diff --git a/src/test/java/com/onarandombox/MultiverseCore/test/utils/TestInstanceCreator.java b/src/test/java/com/onarandombox/MultiverseCore/test/utils/TestInstanceCreator.java index ce6471ef..716b5163 100644 --- a/src/test/java/com/onarandombox/MultiverseCore/test/utils/TestInstanceCreator.java +++ b/src/test/java/com/onarandombox/MultiverseCore/test/utils/TestInstanceCreator.java @@ -26,9 +26,11 @@ import org.bukkit.World; import org.bukkit.WorldCreator; import org.bukkit.command.CommandSender; import org.bukkit.permissions.Permission; +import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitScheduler; import org.mockito.Matchers; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; @@ -36,6 +38,9 @@ import org.powermock.api.mockito.PowerMockito; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.api.MultiverseWorld; +import com.onarandombox.MultiverseCore.listeners.MVEntityListener; +import com.onarandombox.MultiverseCore.listeners.MVPlayerListener; +import com.onarandombox.MultiverseCore.listeners.MVWeatherListener; import com.onarandombox.MultiverseCore.utils.FileUtils; import com.onarandombox.MultiverseCore.utils.WorldManager; @@ -122,12 +127,45 @@ public class TestInstanceCreator { } catch (Exception e) { return null; } - return MockWorldFactory.makeNewMockWorld(arg.name(), arg.environment()); + // Add special case for creating null worlds. + // Not sure I like doing it this way, but this is a special case + if (arg.name().equalsIgnoreCase("nullworld")) { + return MockWorldFactory.makeNewNullMockWorld(arg.name(), arg.environment(), arg.type()); + } + return MockWorldFactory.makeNewMockWorld(arg.name(), arg.environment(), arg.type()); } }); when(mockServer.unloadWorld(anyString(), anyBoolean())).thenReturn(true); + // add mock scheduler + BukkitScheduler mockScheduler = mock(BukkitScheduler.class); + when(mockScheduler.scheduleSyncDelayedTask(any(Plugin.class), any(Runnable.class), anyLong())). + thenAnswer(new Answer() { + public Integer answer(InvocationOnMock invocation) throws Throwable { + Runnable arg; + try { + arg = (Runnable) invocation.getArguments()[1]; + } catch (Exception e) { + return null; + } + arg.run(); + return null; + }}); + when(mockScheduler.scheduleSyncDelayedTask(any(Plugin.class), any(Runnable.class))). + thenAnswer(new Answer() { + public Integer answer(InvocationOnMock invocation) throws Throwable { + Runnable arg; + try { + arg = (Runnable) invocation.getArguments()[1]; + } catch (Exception e) { + return null; + } + arg.run(); + return null; + }}); + when(mockServer.getScheduler()).thenReturn(mockScheduler); + // Set server Field serverfield = JavaPlugin.class.getDeclaredField("server"); serverfield.setAccessible(true); @@ -139,6 +177,24 @@ public class TestInstanceCreator { worldmanagerfield.setAccessible(true); worldmanagerfield.set(core, wm); + // Set playerListener + MVPlayerListener pl = PowerMockito.spy(new MVPlayerListener(core)); + Field playerlistenerfield = MultiverseCore.class.getDeclaredField("playerListener"); + playerlistenerfield.setAccessible(true); + playerlistenerfield.set(core, pl); + + // Set entityListener + MVEntityListener el = PowerMockito.spy(new MVEntityListener(core)); + Field entitylistenerfield = MultiverseCore.class.getDeclaredField("entityListener"); + entitylistenerfield.setAccessible(true); + entitylistenerfield.set(core, el); + + // Set weatherListener + MVWeatherListener wl = PowerMockito.spy(new MVWeatherListener(core)); + Field weatherlistenerfield = MultiverseCore.class.getDeclaredField("weatherListener"); + weatherlistenerfield.setAccessible(true); + weatherlistenerfield.set(core, wl); + // Init our command sender final Logger commandSenderLogger = Logger.getLogger("CommandSender"); commandSenderLogger.setParent(Util.logger);