What about this?

This commit is contained in:
main() 2012-11-10 02:09:52 +01:00
parent 2a56398d10
commit ac8965f1f0
20 changed files with 358 additions and 304 deletions

View File

@ -16,6 +16,7 @@ import com.mvplugin.minecraft.WorldType;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;
/**
* The API for a Multiverse Handled World.
@ -510,4 +511,8 @@ public interface MultiverseWorld {
* @return A List of world names.
*/
List<String> getWorldBlacklist();
// TODO this workaround, simply stated, sucks. there has to be a better way.
Callable<?> getAPISpecificObjectCallable();
void setAPISpecificObjectCallable(Callable<?> apiObject);
}

View File

@ -12,48 +12,91 @@ import java.io.IOException;
* This API contains all of the world managing
* functions that your heart desires!
*/
public interface WorldManager<W extends MultiverseWorld> {
/**
* Add a new World to the Multiverse Setup.
*
* @param name World Name
* @param env Environment Type
* @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 generateStructures If true, this world will get NPC villages.
* @param generator The Custom generator plugin to use.
* @return True if the world is added, false if not.
*/
boolean addWorld(String name,
WorldEnvironment env,
String seedString,
WorldType type,
Boolean generateStructures,
String generator) throws WorldCreationException;
public interface WorldManager {
public static final class WorldCreationSettings {
private String name;
private WorldEnvironment env;
private Long seed;
private WorldType type;
private boolean generateStructures = true;
private Generator generator;
private boolean adjustSpawn = true;
public WorldCreationSettings(String name) {
this.name = name;
}
public String name() {
return name;
}
public WorldEnvironment env() {
return env;
}
public Long seed() {
return seed;
}
public WorldType type() {
return type;
}
public boolean generateStructures() {
return generateStructures;
}
public Generator generator() {
return generator;
}
public boolean adjustSpawn() {
return adjustSpawn;
}
public WorldCreationSettings name(String n) {
this.name = n;
return this;
}
public WorldCreationSettings env(WorldEnvironment e) {
this.env = e;
return this;
}
public WorldCreationSettings seed(Long l) {
this.seed = l;
return this;
}
public WorldCreationSettings type(WorldType t) {
this.type = t;
return this;
}
public WorldCreationSettings generateStructures(boolean b) {
this.generateStructures = b;
return this;
}
public WorldCreationSettings generator(Generator g) {
this.generator = g;
return this;
}
public WorldCreationSettings adjustSpawn(boolean a) {
this.adjustSpawn = a;
return this;
}
}
/**
* Add a new World to the Multiverse Setup.
*
* @param name World Name
* @param env Environment Type
* @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 generateStructures If true, this world will get NPC villages.
* @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.
* Adds a new World to the Multiverse Setup.
* @param settings Settings for the world creation
* @return The new world
* @throws WorldCreationException If world creation fails
*/
boolean addWorld(String name,
WorldEnvironment env,
String seedString,
WorldType type,
Boolean generateStructures,
String generator,
boolean useSpawnAdjust) throws WorldCreationException;
MultiverseWorld addWorld(WorldCreationSettings settings) throws WorldCreationException;
/**
* Make a copy of a world.

View File

@ -0,0 +1,13 @@
package com.mvplugin.integration;
public final class APICollection {
private final WorldAPI worldAPI;
public APICollection(WorldAPI wapi) {
this.worldAPI = wapi;
}
public WorldAPI getWorldAPI() {
return this.worldAPI;
}
}

View File

@ -0,0 +1,7 @@
package com.mvplugin.integration;
import com.mvplugin.MVCore;
public interface Bootstrap {
MVCore getPlugin(APICollection api);
}

View File

@ -0,0 +1,21 @@
package com.mvplugin.integration;
import java.util.concurrent.Callable;
import com.mvplugin.MultiverseWorld;
import com.mvplugin.WorldCreationException;
import com.mvplugin.WorldManager.WorldCreationSettings;
public interface WorldAPI {
/**
* Creates a {@link MultiverseWorld} with the given properties.
*
* If a Minecraft world is already loaded with this name, null will be returned. If a Minecraft world already
* exists but it not loaded, it will be loaded instead.
*
* @param settings Settings for this world creation.
* @return An api-specific object or null if a Minecraft world by this name is already loaded.
* @throws WorldCreationException If any problems occured while trying to create the world.
*/
Callable<?> createWorld(WorldCreationSettings settings) throws WorldCreationException;
}

View File

@ -1,4 +1,4 @@
package com.mvplugin.minecraft;
public class Generator {
public interface Generator {
}

View File

@ -1,88 +0,0 @@
package com.mvplugin.impl;
import com.dumptruckman.minecraft.pluginbase.locale.BundledMessage;
import com.mvplugin.MVCore;
import com.mvplugin.MultiverseWorld;
import com.mvplugin.WorldCreationException;
import com.mvplugin.WorldManager;
import com.mvplugin.impl.util.Language;
import com.mvplugin.minecraft.WorldEnvironment;
import com.mvplugin.minecraft.WorldType;
import java.util.HashMap;
import java.util.Map;
public abstract class AbstractWorldManager<W extends MultiverseWorld> implements WorldManager<W> {
protected final MVCore core;
private final Map<String, W> worldMap;
protected AbstractWorldManager(final MVCore core) {
this.core = core;
worldMap = new HashMap<String, W>();
}
@Override
public boolean addWorld(String name, WorldEnvironment env, String seedString, WorldType type, Boolean generateStructures, String generator) throws WorldCreationException {
return this.addWorld(name, env, seedString, type, generateStructures, generator, true);
}
@Override
public boolean addWorld(String name,
WorldEnvironment env,
String seedString,
WorldType type,
Boolean generateStructures,
String generator,
boolean useSpawnAdjust) throws WorldCreationException {
if (this.worldMap.containsKey(name)) {
throw new WorldCreationException(new BundledMessage(Language.WORLD_ALREADY_EXISTS, name));
}
Long seed = null;
if (seedString != null && seedString.length() > 0) {
try {
seed = Long.parseLong(seedString);
} catch (NumberFormatException numberformatexception) {
seed = (long) seedString.hashCode();
}
}
// TODO: Use the fancy kind with the commandSender | dumptruckman has no idea what this means..
if (generator != null && generator.length() == 0) {
generator = null;
}
W mvWorld = createWorld(name, env, seed, type, generateStructures, generator);
mvWorld.setAdjustSpawn(useSpawnAdjust);
this.worldMap.put(name, mvWorld);
return true;
}
/**
* Creates a {@link W} with the given properties.
*
* If a Minecraft world is already loaded with this name, null will be returned. If a Minecraft world already
* exists but it not loaded, it will be loaded instead.
*
* @param name The name for the world. May not be null.
* @param env The environment for the world. May not be null.
* @param seed The seed for the world. Null means a random seed will be used if creating a new Minecraft world.
* @param type The world type for the world. Null means the Minecraft default will be used if creating a new
* Minecraft world or, if loading a world, the loaded world's type will be used.
* @param generateStructures Whether or not to generate structures for the world. Null means the Minecraft default
* will be used if creating a new world or, if loading a world, the loaded world's
* setting will be used.
* @param generator The name of the generator for the world. Null may be used to specify no generator.
* @return A new {@link W} or null if a Minecraft world by this name is already loaded.
* @throws WorldCreationException If any problems occured while trying to create the world.
*/
protected abstract W createWorld(String name,
WorldEnvironment env,
Long seed,
WorldType type,
Boolean generateStructures,
String generator) throws WorldCreationException;
}

View File

@ -9,12 +9,14 @@ import com.mvplugin.minecraft.WorldEnvironment;
import com.mvplugin.minecraft.WorldType;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.Callable;
public abstract class AbstractMultiverseWorld implements MultiverseWorld {
public class BaseMultiverseWorld implements MultiverseWorld {
private final WorldProperties worldProperties;
private Callable<?> apiObject;
protected AbstractMultiverseWorld(final WorldProperties worldProperties) {
protected BaseMultiverseWorld(final WorldProperties worldProperties) {
this.worldProperties = worldProperties;
}
@ -322,4 +324,26 @@ public abstract class AbstractMultiverseWorld implements MultiverseWorld {
public List<String> getWorldBlacklist() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String getName() {
// TODO Auto-generated method stub
return null;
}
@Override
public UUID getWorldUID() {
// TODO Auto-generated method stub
return null;
}
@Override
public Callable<?> getAPISpecificObjectCallable() {
return this.apiObject;
}
@Override
public void setAPISpecificObjectCallable(Callable<?> apiObject) {
this.apiObject = apiObject;
}
}

View File

@ -0,0 +1,11 @@
package com.mvplugin.impl;
import com.mvplugin.integration.APICollection;
public class BasePlugin implements MVCore {
private BaseWorldManager worldManager;
public BasePlugin(APICollection api) {
this.worldManager = new BaseWorldManager(this, api.getWorldAPI());
}
}

View File

@ -0,0 +1,39 @@
package com.mvplugin.impl;
import com.dumptruckman.minecraft.pluginbase.locale.BundledMessage;
import com.mvplugin.MVCore;
import com.mvplugin.MultiverseWorld;
import com.mvplugin.WorldCreationException;
import com.mvplugin.WorldManager;
import com.mvplugin.impl.util.Language;
import com.mvplugin.integration.WorldAPI;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
public class BaseWorldManager implements WorldManager {
protected final MVCore core;
private WorldAPI creator;
private final Map<String, MultiverseWorld> worldMap;
protected BaseWorldManager(final MVCore core, final WorldAPI creator) {
this.core = core;
this.creator = creator;
this.worldMap = new HashMap<String, MultiverseWorld>();
}
@Override
public MultiverseWorld addWorld(WorldCreationSettings settings) throws WorldCreationException {
if (this.worldMap.containsKey(settings.name())) {
throw new WorldCreationException(new BundledMessage(Language.WORLD_ALREADY_EXISTS, settings.name()));
}
Callable<?> callable = this.creator.createWorld(settings);
MultiverseWorld mvWorld = new BaseMultiverseWorld(null); // TODO world properties
mvWorld.setAPISpecificObjectCallable(callable);
this.worldMap.put(settings.name(), mvWorld);
return mvWorld;
}
}

View File

@ -0,0 +1,11 @@
package com.mvplugin.impl;
import com.mvplugin.MVCore;
import com.mvplugin.integration.APICollection;
public final class Bootstrap implements com.mvplugin.integration.Bootstrap {
@Override
public MVCore getPlugin(APICollection api) {
return new BasePlugin(api);
}
}

View File

@ -234,14 +234,6 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Base Dependency -->
<dependency>
<groupId>com.mvplugin</groupId>
<artifactId>MultiverseCore-Base</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- PluginBase Dependency -->
<dependency>
<groupId>com.dumptruckman.minecraft</groupId>

View File

@ -1,41 +0,0 @@
package com.mvplugin.integration.bukkit;
import com.mvplugin.integration.bukkit.api.BukkitMultiverseWorld;
import com.mvplugin.impl.AbstractMultiverseWorld;
import com.mvplugin.impl.WorldProperties;
import org.bukkit.Bukkit;
import org.bukkit.World;
import java.util.UUID;
class BukkitWorld extends AbstractMultiverseWorld implements BukkitMultiverseWorld {
private final String name;
private final UUID worldUID;
BukkitWorld(final World world, final WorldProperties worldProperties) {
super(worldProperties);
this.name = world.getName();
this.worldUID = world.getUID();
}
@Override
public String getName() {
return this.name;
}
@Override
public UUID getWorldUID() {
return this.worldUID;
}
@Override
public World getBukkitWorld() {
final World world = Bukkit.getWorld(worldUID);
if (world == null) {
throw new NullPointerException("Multiverse lost track of Bukkit world '" + this.name + "'");
}
return world;
}
}

View File

@ -0,0 +1,66 @@
package com.mvplugin.integration.bukkit;
import com.dumptruckman.minecraft.pluginbase.locale.BundledMessage;
import com.mvplugin.MVCore;
import com.mvplugin.WorldCreationException;
import com.mvplugin.WorldManager.WorldCreationSettings;
import com.mvplugin.integration.WorldAPI;
import com.mvplugin.integration.bukkit.util.BukkitLanguage;
import com.mvplugin.integration.bukkit.util.Convert;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.WorldCreator;
import java.io.File;
import java.util.concurrent.Callable;
public class BukkitWorldAPI implements WorldAPI {
private final MVCore plugin;
private final File worldsFolder;
public BukkitWorldAPI(MVCore plugin, File worldsFolder) {
this.plugin = plugin;
this.worldsFolder = worldsFolder;
}
/**
* {@inheritDoc}
*/
@Override
public Callable<?> createWorld(WorldCreationSettings settings) throws WorldCreationException {
if (Bukkit.getWorld(settings.name()) != null)
return null;
final WorldCreator c = WorldCreator.name(settings.name());
if (settings.env() != null)
c.environment(Convert.toBukkit(settings.env()));
if (settings.type() != null)
c.type(Convert.toBukkit(settings.type()));
if (settings.seed() != null)
c.seed(settings.seed());
c.generateStructures(settings.generateStructures());
if (settings.generator() instanceof ChunkGenerator)
c.generator((ChunkGenerator)settings.generator());
else if (settings.generator() != null)
throw new WorldCreationException(new BundledMessage(BukkitLanguage.WGEN_UNKNOWN_GENERATOR, settings.generator()));
try {
final World w = c.createWorld();
final String name = w.getName();
return new Callable<World>() {
@Override
public World call() throws Exception {
World w = Bukkit.getWorld(name);
if (w == null)
throw new NullPointerException("Multiverse lost track of Bukkit world '" + name + "'");
return w;
}
};
} catch (Exception e) {
throw new WorldCreationException(new BundledMessage(BukkitLanguage.CREATE_WORLD_ERROR, settings.name()), e);
}
}
}

View File

@ -1,76 +0,0 @@
package com.mvplugin.integration.bukkit;
import com.dumptruckman.minecraft.pluginbase.locale.BundledMessage;
import com.dumptruckman.minecraft.pluginbase.util.Logging;
import com.mvplugin.WorldCreationException;
import com.mvplugin.integration.bukkit.api.BukkitMultiverseWorld;
import com.mvplugin.impl.AbstractWorldManager;
import com.mvplugin.impl.WorldProperties;
import com.mvplugin.minecraft.WorldEnvironment;
import com.mvplugin.minecraft.WorldType;
import com.mvplugin.integration.bukkit.util.BukkitLanguage;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.WorldCreator;
import java.io.File;
import java.io.IOException;
public class BukkitWorldManager extends AbstractWorldManager<BukkitMultiverseWorld> {
private final MultiverseCore plugin;
private final File worldsFolder;
BukkitWorldManager(final MultiverseCore core) {
super(core);
this.plugin = core;
worldsFolder = new File(core.getDataFolder(), "worlds");
}
//@Override TODO decide about config-api relationship
public WorldProperties getWorldProperties(final String worldName) throws IOException {
return new YamlWorldProperties(plugin, new File(worldsFolder, worldName + ".yml"));
}
@Override
public BukkitMultiverseWorld createWorld(String name, WorldEnvironment env, Long seed, WorldType type,
Boolean generateStructures, String generator) throws WorldCreationException {
if (Bukkit.getWorld(name) != null) {
return null;
}
final WorldCreator c = new WorldCreator(name);
if (seed != null) {
c.seed(seed);
}
if (generator != null) {
c.generator(generator);
}
c.environment(Environment.valueOf(env.toString()));
if (type != null) {
c.type(org.bukkit.WorldType.valueOf(type.toString()));
}
if (generateStructures != null) {
c.generateStructures(generateStructures);
}
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) {
builder.append(" & seed: ").append(seed);
}
if (generator != null) {
builder.append(" & generator: ").append(generator);
}
Logging.info(builder.toString());
try {
final World world = c.createWorld();
return new BukkitWorld(world, getWorldProperties(name));
} catch (Exception e) {
throw new WorldCreationException(new BundledMessage(BukkitLanguage.CREATE_WORLD_ERROR, name), e);
}
}
}

View File

@ -0,0 +1,49 @@
package com.mvplugin.integration.bukkit;
import com.dumptruckman.minecraft.pluginbase.plugin.AbstractBukkitPlugin;
import com.mvplugin.MVCore;
import com.mvplugin.WorldManager;
import com.mvplugin.integration.APICollection;
import com.mvplugin.integration.Bootstrap;
import java.io.IOException;
/**
* The primary Bukkit plugin implementation of Multiverse-Core.
*/
// TODO: Some magic that automatically hooks up abstract base libs because we can't know what libs the base uses
public class MVCoreBukkitIntegration extends AbstractBukkitPlugin<CoreConfig> {
private static final String COMMAND_PREFIX = "mv";
private MVCore plugin;
public MVCoreBukkitIntegration() {
this.setPermissionName("multiverse.core");
}
@Override
protected void onPluginLoad() {
// TODO dynamically choose MVCore-implementation
Bootstrap bootstrap = Class.forName("com.mvplugin.impl.Bootstrap").asSubclass(Bootstrap.class).newInstance();
plugin = bootstrap.getPlugin(new APICollection(new BukkitWorldAPI(plugin, this.getServer().getWorldContainer())));
}
@Override
public String getCommandPrefix() {
return COMMAND_PREFIX;
}
@Override
protected CoreConfig newConfigInstance() throws IOException {
return new YamlCoreConfig(this);
}
@Override
protected boolean useDatabase() {
return false;
}
public MVCore getImplementation() {
return this.plugin;
}
}

View File

@ -1,46 +0,0 @@
package com.mvplugin.integration.bukkit;
import com.dumptruckman.minecraft.pluginbase.plugin.AbstractBukkitPlugin;
import com.mvplugin.impl.CoreConfig;
import com.mvplugin.impl.MVCore;
import java.io.IOException;
/**
* The primary Bukkit plugin implementation of Multiverse-Core.
*/
public class MultiverseCore extends AbstractBukkitPlugin<CoreConfig> implements MVCore {
private static final String COMMAND_PREFIX = "mv";
private BukkitWorldManager worldManager;
public MultiverseCore() {
this.setPermissionName("multiverse.core");
}
@Override
protected void onPluginLoad() {
worldManager = new BukkitWorldManager(this);
}
@Override
public String getCommandPrefix() {
return COMMAND_PREFIX;
}
@Override
protected CoreConfig newConfigInstance() throws IOException {
return new YamlCoreConfig(this);
}
@Override
protected boolean useDatabase() {
return false;
}
@Override
public BukkitWorldManager getMVWorldManager() {
return this.worldManager;
}
}

View File

@ -11,7 +11,7 @@ import java.io.IOException;
*/
class YamlCoreConfig extends YamlProperties implements CoreConfig {
public YamlCoreConfig(MultiverseCore plugin) throws IOException {
public YamlCoreConfig(MVCoreBukkitIntegration plugin) throws IOException {
super(plugin, true, true, new File(plugin.getDataFolder(), "config.yml"), CoreConfig.class);
}
}

View File

@ -3,7 +3,8 @@ package com.mvplugin.integration.bukkit.util;
import com.dumptruckman.minecraft.pluginbase.locale.Message;
public class BukkitLanguage {
public static final Message CREATE_WORLD_ERROR = new Message("worlds.create_world_error",
"&aBukkit&f experienced a problem while attempting to create '&b%s&f'!");
public static final Message WGEN_UNKNOWN_GENERATOR = new Message("worlds.create.unknown_generator",
"I can't create a &bBukkit&f world that uses the generator &c%s&f!");
}

View File

@ -0,0 +1,23 @@
package com.mvplugin.integration.bukkit.util;
import org.bukkit.Difficulty;
import org.bukkit.World.Environment;
import org.bukkit.WorldType;
import com.mvplugin.minecraft.WorldEnvironment;
public final class Convert {
private Convert() {}
public static Difficulty toBukkit(com.mvplugin.minecraft.Difficulty d) {
return Difficulty.valueOf(d.name());
}
public static WorldType toBukkit(com.mvplugin.minecraft.WorldType t) {
return WorldType.valueOf(t.name());
}
public static Environment toBukkit(WorldEnvironment e) {
return Environment.valueOf(e.name());
}
}