diff --git a/base/src/main/java/com/mvplugin/core/AbstractMultiverseWorld.java b/base/src/main/java/com/mvplugin/core/AbstractMultiverseWorld.java index 9782bb7d..0a09033a 100644 --- a/base/src/main/java/com/mvplugin/core/AbstractMultiverseWorld.java +++ b/base/src/main/java/com/mvplugin/core/AbstractMultiverseWorld.java @@ -7,7 +7,6 @@ import com.mvplugin.core.minecraft.GameMode; import com.mvplugin.core.minecraft.PlayerPosition; import com.mvplugin.core.minecraft.PortalType; import com.mvplugin.core.minecraft.WorldEnvironment; -import com.mvplugin.core.minecraft.WorldType; import java.util.List; @@ -19,19 +18,14 @@ abstract class AbstractMultiverseWorld implements MultiverseWorld { this.worldProperties = worldProperties; } - @Override - public WorldType getWorldType() { - return null; //To change body of implemented methods use File | Settings | File Templates. - } - @Override public WorldEnvironment getEnvironment() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return getProperties().get(WorldProperties.ENVIRONMENT); } @Override - public void setEnvironment(WorldEnvironment environment) { - //To change body of implemented methods use File | Settings | File Templates. + public void setEnvironment(final WorldEnvironment environment) { + getProperties().set(WorldProperties.ENVIRONMENT, environment); } @Override @@ -261,12 +255,12 @@ abstract class AbstractMultiverseWorld implements MultiverseWorld { @Override public boolean getAdjustSpawn() { - return false; //To change body of implemented methods use File | Settings | File Templates. + return getProperties().get(WorldProperties.ADJUST_SPAWN); } @Override - public void setAdjustSpawn(boolean adjust) { - //To change body of implemented methods use File | Settings | File Templates. + public void setAdjustSpawn(final boolean adjust) { + getProperties().set(WorldProperties.ADJUST_SPAWN, adjust); } @Override diff --git a/base/src/main/java/com/mvplugin/core/AbstractWorldManager.java b/base/src/main/java/com/mvplugin/core/AbstractWorldManager.java index 85710ae5..e22cd76c 100644 --- a/base/src/main/java/com/mvplugin/core/AbstractWorldManager.java +++ b/base/src/main/java/com/mvplugin/core/AbstractWorldManager.java @@ -16,11 +16,11 @@ import java.util.Map; abstract class AbstractWorldManager implements WorldManager { protected final MultiverseCore core; - private final Map worldMap; + protected final Map worldsMap; protected AbstractWorldManager(final MultiverseCore core) { this.core = core; - this.worldMap = new HashMap(); + this.worldsMap = new HashMap(); } @Override @@ -60,12 +60,12 @@ abstract class AbstractWorldManager implements WorldManager { @Override public MultiverseWorld addWorld(WorldCreationSettings settings) throws WorldCreationException { - if (this.worldMap.containsKey(settings.name())) { + if (this.worldsMap.containsKey(settings.name())) { throw new WorldCreationException(new BundledMessage(Language.WORLD_ALREADY_EXISTS, settings.name())); } MultiverseWorld mvWorld = createWorld(settings); mvWorld.setAdjustSpawn(settings.adjustSpawn()); - this.worldMap.put(settings.name(), mvWorld); + this.worldsMap.put(settings.name(), mvWorld); return mvWorld; } @@ -102,11 +102,11 @@ abstract class AbstractWorldManager implements WorldManager { @Override public boolean isMVWorld(final String name) { - return this.worldMap.containsKey(name); + return this.worldsMap.containsKey(name); } @Override public Collection getMVWorlds() { - return Collections.unmodifiableCollection(this.worldMap.values()); + return Collections.unmodifiableCollection(this.worldsMap.values()); } } diff --git a/base/src/main/java/com/mvplugin/core/api/MultiverseCore.java b/base/src/main/java/com/mvplugin/core/api/MultiverseCore.java index 3cdb0428..303a69d7 100644 --- a/base/src/main/java/com/mvplugin/core/api/MultiverseCore.java +++ b/base/src/main/java/com/mvplugin/core/api/MultiverseCore.java @@ -8,11 +8,11 @@ import com.dumptruckman.minecraft.pluginbase.plugin.PluginBase; * This API contains a bunch of useful things you can get out of Multiverse in general! * This is the class you should cast your plugin to unless you need more Implementation specific API. */ -public interface MultiverseCore extends PluginBase { +public interface MultiverseCore extends MultiversePlugin, PluginBase { /** * Gets the primary class responsible for managing Multiverse Worlds. * * @return {@link WorldManager}. */ - WorldManager getMVWorldManager(); + WorldManager getWorldManager(); } diff --git a/base/src/main/java/com/mvplugin/core/api/MultiversePlugin.java b/base/src/main/java/com/mvplugin/core/api/MultiversePlugin.java new file mode 100644 index 00000000..7d188ccf --- /dev/null +++ b/base/src/main/java/com/mvplugin/core/api/MultiversePlugin.java @@ -0,0 +1,27 @@ +package com.mvplugin.core.api; + +public interface MultiversePlugin { + + /** + * Gets the reference to MultiverseCore. + * + * @return A valid {@link MultiverseCore}. + */ + MultiverseCore getCore(); + + /** + * Sets the reference to MultiverseCore. + * + * @param core A valid {@link MultiverseCore}. + */ + void setCore(MultiverseCore core); + + /** + * Allows Multiverse or a plugin to query another Multiverse plugin to see what version its protocol is. This + * number + * should change when something will break the code. + * + * @return The Integer protocol version. + */ + int getProtocolVersion(); +} diff --git a/base/src/main/java/com/mvplugin/core/api/WorldManager.java b/base/src/main/java/com/mvplugin/core/api/WorldManager.java index 7b599b44..f8abb895 100644 --- a/base/src/main/java/com/mvplugin/core/api/WorldManager.java +++ b/base/src/main/java/com/mvplugin/core/api/WorldManager.java @@ -288,11 +288,6 @@ public interface WorldManager { */ List getUnloadedWorlds(); - /** - * This method populates an internal list and needs to be called after multiverse initialization. - */ - //TODO void getDefaultWorldGenerators(); - /** * Saves the world config to disk. * diff --git a/base/src/main/java/com/mvplugin/core/api/WorldProperties.java b/base/src/main/java/com/mvplugin/core/api/WorldProperties.java index b3347a0e..b3778262 100644 --- a/base/src/main/java/com/mvplugin/core/api/WorldProperties.java +++ b/base/src/main/java/com/mvplugin/core/api/WorldProperties.java @@ -5,6 +5,7 @@ import com.dumptruckman.minecraft.pluginbase.properties.ListProperty; import com.dumptruckman.minecraft.pluginbase.properties.Properties; import com.dumptruckman.minecraft.pluginbase.properties.PropertyFactory; import com.dumptruckman.minecraft.pluginbase.properties.SimpleProperty; +import com.mvplugin.core.minecraft.WorldEnvironment; /** * Houses all of the properties for a Multiverse world. @@ -14,54 +15,65 @@ public interface WorldProperties extends Properties { SimpleProperty ALIAS = PropertyFactory.newProperty(String.class, "alias", "") .comment("World aliases allow you to name a world differently than what the folder name is.") .comment("This lets you choose fancy names for your worlds while keeping the folders nice and neat.") - .description(Descriptions.ALIAS) + //.description(Descriptions.ALIAS) .build(); SimpleProperty HIDDEN = PropertyFactory.newProperty(Boolean.class, "hidden", false) .comment("The hidden property allows you to have a world that exists but does not show up in lists.") - .description(Descriptions.HIDDEN) + //.description(Descriptions.HIDDEN) .build(); SimpleProperty PREFIX_CHAT = PropertyFactory.newProperty(Boolean.class, "prefixChat", true) .comment("The prefixChat property adds the world's name (or alias) as a prefix to chat messages.") .comment("Please note, this property can be disabled globally in the configuration.") - .description(Descriptions.PREFIX_CHAT) + //.description(Descriptions.PREFIX_CHAT) .build(); SimpleProperty SEED = PropertyFactory.newProperty(Long.class, "seed", 0L) .comment("The seed property allows you to change the world's seed.") - .description(Descriptions.SEED) + //.description(Descriptions.SEED) .build(); SimpleProperty GENERATOR = PropertyFactory.newProperty(String.class, "generator", "") .comment("The generator property allows you to specify the generator used to generate this world.") - .description(Descriptions.GENERATOR) + //.description(Descriptions.GENERATOR) + .build(); + + SimpleProperty ENVIRONMENT = PropertyFactory.newProperty(WorldEnvironment.class, "environment", WorldEnvironment.NORMAL) + .comment("The environment property the Minecraft world environment such as NORMAL, NETHER, THE_END") + //.description(Descriptions.ENVIRONMENT) .build(); SimpleProperty PLAYER_LIMIT = PropertyFactory.newProperty(Integer.class, "playerLimit", -1) .comment("The player limit property limits the number of players in a world at a time.") .comment("A value of -1 or lower signifies no player limit.") - .description(Descriptions.PLAYER_LIMIT) + //.description(Descriptions.PLAYER_LIMIT) .build(); + SimpleProperty ADJUST_SPAWN = PropertyFactory.newProperty(Boolean.class, "adjustSpawn", true) + .comment("The adjust spawn property determines whether or not Multiverse will make adjustments to the world's spawn location if it is unsafe.") + //.description(Descriptions.ADJUST_SPAWN) + .build(); + + SimpleProperty AUTO_LOAD = PropertyFactory.newProperty(Boolean.class, "autoLoad", true) .comment("This property dictates whether this world is loaded automatically on startup or not.") - .description(Descriptions.AUTO_LOAD) + //.description(Descriptions.AUTO_LOAD) .build(); SimpleProperty BED_RESPAWN = PropertyFactory.newProperty(Boolean.class, "bedRespawn", true) .comment("This property specifies if a player dying in this world should respawn in their bed or not.") - .description(Descriptions.BED_RESPAWN) + //.description(Descriptions.BED_RESPAWN) .build(); SimpleProperty HUNGER = PropertyFactory.newProperty(Boolean.class, "hunger", true) .comment("This property specifies if hunger is depleted in this world") - .description(Descriptions.HUNGER) + //.description(Descriptions.HUNGER) .build(); ListProperty BLACK_LIST = PropertyFactory.newListProperty(String.class, "worldBlacklist") .comment("This property allows you to specify worlds that people cannot go to from this specified world.") - .description(Descriptions.BLACK_LIST) + //.description(Descriptions.BLACK_LIST) .build(); /** @@ -85,10 +97,16 @@ public interface WorldProperties extends Properties { public static final Message GENERATOR = new Message("world_properties.descriptions.generator", "The generator property allows you to specify the generator used to generate this world."); + public static final Message ENVIRONMENT = new Message("world_properties.descriptions.environment", + "The environment property the Minecraft world environment such as NORMAL, NETHER, THE_END"); + public static final Message PLAYER_LIMIT = new Message("world_properties.descriptions.playerLimit", "The player limit property limits the number of players in a world at a time.", "A value of -1 or lower signifies no player limit."); + public static final Message ADJUST_SPAWN = new Message("world_properties.descriptions.adjustSpawn", + "The adjust spawn property determines whether or not Multiverse will make adjustments to the world's spawn location if it is unsafe."); + public static final Message AUTO_LOAD = new Message("world_properties.descriptions.autoLoad", "This value dictates whether this world is loaded automatically on startup or not."); diff --git a/base/src/main/java/com/mvplugin/core/command/ImportCommand.java b/base/src/main/java/com/mvplugin/core/command/ImportCommand.java index 2ffe2377..0cc9d433 100644 --- a/base/src/main/java/com/mvplugin/core/command/ImportCommand.java +++ b/base/src/main/java/com/mvplugin/core/command/ImportCommand.java @@ -93,7 +93,7 @@ public class ImportCommand extends MultiverseCommand { } // Make sure we don't already know about this world. - if (core.getMVWorldManager().isMVWorld(worldName)) { + if (core.getWorldManager().isMVWorld(worldName)) { core.getMessager().message(sender, Language.WORLD_ALREADY_EXISTS, worldName); return true; } @@ -114,7 +114,7 @@ public class ImportCommand extends MultiverseCommand { if (worldFile.exists() && env != null) { core.getMessager().messageAndLog(sender, STARTING_IMPORT, worldName); try { - core.getMVWorldManager().addWorld(worldName, environment, null, null, null, generator, useSpawnAdjust); + core.getWorldManager().addWorld(worldName, environment, null, null, null, generator, useSpawnAdjust); core.getMessager().messageAndLog(sender, IMPORT_COMPLETE); } catch (WorldCreationException e) { core.getMessager().messageAndLog(sender, IMPORT_FAILED); @@ -164,12 +164,12 @@ public class ImportCommand extends MultiverseCommand { } File[] files = worldFolder.listFiles(); String worldList = ""; - Collection worlds = core.getMVWorldManager().getMVWorlds(); + Collection worlds = core.getWorldManager().getMVWorlds(); List worldStrings = new ArrayList(); for (MultiverseWorld world : worlds) { worldStrings.add(world.getName()); } - for (String world : core.getMVWorldManager().getUnloadedWorlds()) { + for (String world : core.getWorldManager().getUnloadedWorlds()) { worldStrings.add(world); } ChatColor currColor = ChatColor.WHITE; diff --git a/bukkit/src/main/java/com/mvplugin/core/BukkitWorld.java b/bukkit/src/main/java/com/mvplugin/core/BukkitWorld.java index 493bdb1f..069c1c98 100644 --- a/bukkit/src/main/java/com/mvplugin/core/BukkitWorld.java +++ b/bukkit/src/main/java/com/mvplugin/core/BukkitWorld.java @@ -2,6 +2,8 @@ package com.mvplugin.core; import com.mvplugin.core.api.BukkitMultiverseWorld; import com.mvplugin.core.api.WorldProperties; +import com.mvplugin.core.minecraft.WorldType; +import com.mvplugin.core.util.Convert; import org.bukkit.Bukkit; import org.bukkit.World; @@ -11,11 +13,13 @@ class BukkitWorld extends AbstractMultiverseWorld implements BukkitMultiverseWor private final String name; private final UUID worldUID; + private final WorldType worldType; BukkitWorld(final World world, final WorldProperties worldProperties) { super(worldProperties); this.name = world.getName(); this.worldUID = world.getUID(); + this.worldType = Convert.fromBukkit(world.getWorldType()); } @Override @@ -28,6 +32,11 @@ class BukkitWorld extends AbstractMultiverseWorld implements BukkitMultiverseWor return this.worldUID; } + @Override + public WorldType getWorldType() { + return worldType; + } + @Override public World getBukkitWorld() { final World world = Bukkit.getWorld(worldUID); diff --git a/bukkit/src/main/java/com/mvplugin/core/BukkitWorldManager.java b/bukkit/src/main/java/com/mvplugin/core/BukkitWorldManager.java index 2ce28dc5..8ad723d6 100644 --- a/bukkit/src/main/java/com/mvplugin/core/BukkitWorldManager.java +++ b/bukkit/src/main/java/com/mvplugin/core/BukkitWorldManager.java @@ -1,5 +1,6 @@ package com.mvplugin.core; +import com.dumptruckman.minecraft.pluginbase.logging.Logging; import com.dumptruckman.minecraft.pluginbase.messaging.BundledMessage; import com.mvplugin.core.api.BukkitMultiverseWorld; import com.mvplugin.core.api.WorldProperties; @@ -8,15 +9,20 @@ import com.mvplugin.core.util.Convert; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.WorldCreator; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; import java.io.File; +import java.io.FilenameFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.logging.Level; public class BukkitWorldManager extends AbstractWorldManager { @@ -24,12 +30,100 @@ public class BukkitWorldManager extends AbstractWorldManager { private final File worldsFolder; private final Map worldPropertiesMap; + private final Map defaultGens; public BukkitWorldManager(MultiverseCorePlugin plugin) { super(plugin); this.plugin = plugin; this.worldsFolder = new File(plugin.getDataFolder(), "worlds"); this.worldPropertiesMap = new HashMap(); + this.defaultGens = new HashMap(); + initializeDefaultWorldGenerators(); + initializeWorlds(); + } + + private void initializeDefaultWorldGenerators() { + File[] files = this.plugin.getServerFolder().listFiles(new FilenameFilter() { + @Override + public boolean accept(File file, String s) { + return s.equalsIgnoreCase("bukkit.yml"); + } + }); + if (files != null && files.length == 1) { + FileConfiguration bukkitConfig = YamlConfiguration.loadConfiguration(files[0]); + if (bukkitConfig.isConfigurationSection("worlds")) { + Set keys = bukkitConfig.getConfigurationSection("worlds").getKeys(false); + for (String key : keys) { + defaultGens.put(key, bukkitConfig.getString("worlds." + key + ".generator", "")); + } + } + } else { + Logging.warning("Could not read 'bukkit.yml'. Any Default worldgenerators will not be loaded!"); + } + } + + private void initializeWorlds() { + StringBuilder builder = new StringBuilder(); + for (final World w : this.plugin.getServer().getWorlds()) { + try { + worldsMap.put(w.getName(), getBukkitWorld(w)); + if (builder.length() != 0) { + builder.append(", "); + } + builder.append(w.getName()); + } catch (IOException e) { + Logging.severe("Multiverse could not initialize loaded Bukkit world '%s'", w.getName()); + } + } + + for (File file : getPotentialWorldFiles()) { + final String worldName = getWorldNameFromFile(file); + if (worldsMap.containsKey(worldName)) { + continue; + } + try { + WorldProperties worldProperties = getWorldProperties(file); + if (worldProperties.get(WorldProperties.AUTO_LOAD)) { + addWorld(worldName, worldProperties.get(WorldProperties.ENVIRONMENT), null, null, + null, worldProperties.get(WorldProperties.GENERATOR), + worldProperties.get(WorldProperties.ADJUST_SPAWN)); + if (builder.length() != 0) { + builder.append(", "); + } + builder.append(worldName); + } else { + Logging.fine("Not loading '%s' because it is set to autoLoad: false", worldName); + } + } catch (IOException e) { + Logging.getLogger().log(Level.WARNING, String.format("Could not load world from file '%s'", file), e); + } catch (WorldCreationException e) { + Logging.getLogger().log(Level.WARNING, String.format("Error while attempting to load world '%s'", worldName), e); + } + } + + // Simple Output to the Console to show how many Worlds were loaded. + Logging.config("Multiverse is now managing: %s", builder.toString()); + } + + private String getWorldNameFromFile(final File file) { + final String simpleName = file.getName(); + if (simpleName.endsWith(".yml")) { + return simpleName.substring(0, simpleName.indexOf(".yml")); + } + return simpleName; + } + + private File[] getPotentialWorldFiles() { + return worldsFolder.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".yml"); + } + }); + } + + private WorldProperties getWorldProperties(final File file) throws IOException { + return new YamlWorldProperties(file); } @Override @@ -41,7 +135,7 @@ public class BukkitWorldManager extends AbstractWorldManager { if (worldPropertiesMap.containsKey(worldName)) { return worldPropertiesMap.get(worldName); } else { - final WorldProperties worldProperties = new YamlWorldProperties(plugin, new File(worldsFolder, worldName + ".yml")); + final WorldProperties worldProperties = getWorldProperties(new File(worldsFolder, worldName + ".yml")); worldPropertiesMap.put(worldName, worldProperties); return worldProperties; } @@ -85,12 +179,16 @@ public class BukkitWorldManager extends AbstractWorldManager { try { final World w = c.createWorld(); - return new BukkitWorld(w, getWorldProperties(w.getName())); + return getBukkitWorld(w); } catch (Exception e) { throw new WorldCreationException(new BundledMessage(BukkitLanguage.CREATE_WORLD_ERROR, settings.name()), e); } } + private BukkitWorld getBukkitWorld(final World world) throws IOException { + return new BukkitWorld(world, getWorldProperties(world.getName())); + } + @Override public List getUnloadedWorlds() { return Collections.unmodifiableList(new ArrayList(worldPropertiesMap.keySet())); diff --git a/bukkit/src/main/java/com/mvplugin/core/MultiverseCorePlugin.java b/bukkit/src/main/java/com/mvplugin/core/MultiverseCorePlugin.java index 3563d179..76836f6d 100644 --- a/bukkit/src/main/java/com/mvplugin/core/MultiverseCorePlugin.java +++ b/bukkit/src/main/java/com/mvplugin/core/MultiverseCorePlugin.java @@ -12,6 +12,7 @@ import java.io.IOException; */ public class MultiverseCorePlugin extends AbstractBukkitPlugin implements MultiverseCore { + private static final int PROTOCOL = 19; private static final String COMMAND_PREFIX = "mv"; private BukkitWorldManager worldManager; @@ -22,13 +23,16 @@ public class MultiverseCorePlugin extends AbstractBukkitPlugin imple @Override protected void onPluginLoad() { - worldManager = new BukkitWorldManager(this); getCommandHandler().registerCommand(ImportCommand.class); } @Override public void onPluginEnable() { + worldManager = new BukkitWorldManager(this); + } + protected void onReloadConfig() { + worldManager = new BukkitWorldManager(this); } @Override @@ -47,7 +51,20 @@ public class MultiverseCorePlugin extends AbstractBukkitPlugin imple } @Override - public BukkitWorldManager getMVWorldManager() { + public BukkitWorldManager getWorldManager() { return this.worldManager; } + + @Override + public MultiverseCore getCore() { + return this; + } + + @Override + public void setCore(MultiverseCore core) { } + + @Override + public int getProtocolVersion() { + return PROTOCOL; + } } diff --git a/bukkit/src/main/java/com/mvplugin/core/YamlCoreConfig.java b/bukkit/src/main/java/com/mvplugin/core/YamlCoreConfig.java index d3484c2a..c07dd55c 100644 --- a/bukkit/src/main/java/com/mvplugin/core/YamlCoreConfig.java +++ b/bukkit/src/main/java/com/mvplugin/core/YamlCoreConfig.java @@ -12,6 +12,6 @@ import java.io.IOException; class YamlCoreConfig extends YamlProperties implements CoreConfig { public YamlCoreConfig(MultiverseCorePlugin plugin) throws IOException { - super(plugin, true, true, new File(plugin.getDataFolder(), "config.yml"), CoreConfig.class); + super(true, true, new File(plugin.getDataFolder(), "config.yml"), CoreConfig.class); } } diff --git a/bukkit/src/main/java/com/mvplugin/core/YamlWorldProperties.java b/bukkit/src/main/java/com/mvplugin/core/YamlWorldProperties.java index 7bcf8432..772189dc 100644 --- a/bukkit/src/main/java/com/mvplugin/core/YamlWorldProperties.java +++ b/bukkit/src/main/java/com/mvplugin/core/YamlWorldProperties.java @@ -1,6 +1,5 @@ package com.mvplugin.core; -import com.dumptruckman.minecraft.pluginbase.plugin.BukkitPlugin; import com.dumptruckman.minecraft.pluginbase.properties.YamlProperties; import com.mvplugin.core.api.WorldProperties; @@ -13,7 +12,7 @@ import java.io.IOException; */ class YamlWorldProperties extends YamlProperties implements WorldProperties { - YamlWorldProperties(BukkitPlugin plugin, File configFile) throws IOException { - super(plugin, false, true, configFile, WorldProperties.class); + YamlWorldProperties(File configFile) throws IOException { + super(false, true, configFile, WorldProperties.class); } } diff --git a/bukkit/src/main/java/com/mvplugin/core/util/Convert.java b/bukkit/src/main/java/com/mvplugin/core/util/Convert.java index 665a6630..8b8f9b5e 100644 --- a/bukkit/src/main/java/com/mvplugin/core/util/Convert.java +++ b/bukkit/src/main/java/com/mvplugin/core/util/Convert.java @@ -16,6 +16,10 @@ public final class Convert { return WorldType.valueOf(t.name()); } + public static com.mvplugin.core.minecraft.WorldType fromBukkit(WorldType t) { + return com.mvplugin.core.minecraft.WorldType.valueOf(t.name()); + } + public static Environment toBukkit(WorldEnvironment e) { return Environment.valueOf(e.name()); }