Multiverse-Core/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java

1239 lines
47 KiB
Java

/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2011. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import buscript.Buscript;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MVWorld.NullLocation;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.Core;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import com.onarandombox.MultiverseCore.api.MVPlugin;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
import com.onarandombox.MultiverseCore.api.MultiverseMessaging;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.commands.AnchorCommand;
import com.onarandombox.MultiverseCore.commands.CheckCommand;
import com.onarandombox.MultiverseCore.commands.CloneCommand;
import com.onarandombox.MultiverseCore.commands.ConfigCommand;
import com.onarandombox.MultiverseCore.commands.ConfirmCommand;
import com.onarandombox.MultiverseCore.commands.CoordCommand;
import com.onarandombox.MultiverseCore.commands.CreateCommand;
import com.onarandombox.MultiverseCore.commands.DebugCommand;
import com.onarandombox.MultiverseCore.commands.DeleteCommand;
import com.onarandombox.MultiverseCore.commands.EnvironmentCommand;
import com.onarandombox.MultiverseCore.commands.GameruleCommand;
import com.onarandombox.MultiverseCore.commands.GamerulesCommand;
import com.onarandombox.MultiverseCore.commands.GeneratorCommand;
import com.onarandombox.MultiverseCore.commands.HelpCommand;
import com.onarandombox.MultiverseCore.commands.ImportCommand;
import com.onarandombox.MultiverseCore.commands.InfoCommand;
import com.onarandombox.MultiverseCore.commands.ListCommand;
import com.onarandombox.MultiverseCore.commands.LoadCommand;
import com.onarandombox.MultiverseCore.commands.ModifyAddCommand;
import com.onarandombox.MultiverseCore.commands.ModifyClearCommand;
import com.onarandombox.MultiverseCore.commands.ModifyCommand;
import com.onarandombox.MultiverseCore.commands.ModifyRemoveCommand;
import com.onarandombox.MultiverseCore.commands.ModifySetCommand;
import com.onarandombox.MultiverseCore.commands.PurgeCommand;
import com.onarandombox.MultiverseCore.commands.RegenCommand;
import com.onarandombox.MultiverseCore.commands.ReloadCommand;
import com.onarandombox.MultiverseCore.commands.RemoveCommand;
import com.onarandombox.MultiverseCore.commands.ScriptCommand;
import com.onarandombox.MultiverseCore.commands.SetSpawnCommand;
import com.onarandombox.MultiverseCore.commands.SilentCommand;
import com.onarandombox.MultiverseCore.commands.SpawnCommand;
import com.onarandombox.MultiverseCore.commands.TeleportCommand;
import com.onarandombox.MultiverseCore.commands.UnloadCommand;
import com.onarandombox.MultiverseCore.commands.VersionCommand;
import com.onarandombox.MultiverseCore.commands.WhoCommand;
import com.onarandombox.MultiverseCore.commandtools.queue.CommandQueueManager;
import com.onarandombox.MultiverseCore.destination.AnchorDestination;
import com.onarandombox.MultiverseCore.destination.BedDestination;
import com.onarandombox.MultiverseCore.destination.CannonDestination;
import com.onarandombox.MultiverseCore.destination.DestinationFactory;
import com.onarandombox.MultiverseCore.destination.ExactDestination;
import com.onarandombox.MultiverseCore.destination.PlayerDestination;
import com.onarandombox.MultiverseCore.destination.WorldDestination;
import com.onarandombox.MultiverseCore.event.MVDebugModeEvent;
import com.onarandombox.MultiverseCore.event.MVVersionEvent;
import com.onarandombox.MultiverseCore.listeners.MVAsyncPlayerChatListener;
import com.onarandombox.MultiverseCore.listeners.MVChatListener;
import com.onarandombox.MultiverseCore.listeners.MVEntityListener;
import com.onarandombox.MultiverseCore.listeners.MVMapListener;
import com.onarandombox.MultiverseCore.listeners.MVPlayerChatListener;
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
import com.onarandombox.MultiverseCore.listeners.MVPortalListener;
import com.onarandombox.MultiverseCore.listeners.MVWeatherListener;
import com.onarandombox.MultiverseCore.listeners.MVWorldInitListener;
import com.onarandombox.MultiverseCore.listeners.MVWorldListener;
import com.onarandombox.MultiverseCore.utils.AnchorManager;
import com.onarandombox.MultiverseCore.utils.CompatibilityLayer;
import com.onarandombox.MultiverseCore.utils.MVEconomist;
import com.onarandombox.MultiverseCore.utils.MVMessaging;
import com.onarandombox.MultiverseCore.utils.MVPermissions;
import com.onarandombox.MultiverseCore.utils.MVPlayerSession;
import com.onarandombox.MultiverseCore.utils.MaterialConverter;
import com.onarandombox.MultiverseCore.utils.TestingMode;
import com.onarandombox.MultiverseCore.utils.metrics.MetricsConfigurator;
import com.onarandombox.MultiverseCore.utils.SimpleBlockSafety;
import com.onarandombox.MultiverseCore.utils.SimpleLocationManipulation;
import com.onarandombox.MultiverseCore.utils.SimpleSafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper;
import com.onarandombox.MultiverseCore.utils.VaultHandler;
import com.onarandombox.MultiverseCore.utils.WorldManager;
import com.pneumaticraft.commandhandler.CommandHandler;
import me.main__.util.SerializationConfig.NoSuchPropertyException;
import me.main__.util.SerializationConfig.SerializationConfig;
import org.bukkit.ChatColor;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
/**
* The implementation of the Multiverse-{@link Core}.
*/
public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
private static final int PROTOCOL = 24;
// TODO: Investigate if this one is really needed to be static.
// Doubt it. -- FernFerret
private static Map<String, String> teleportQueue = new HashMap<String, String>();
private AnchorManager anchorManager = new AnchorManager(this);
// TODO please let's make this non-static
private volatile MultiverseCoreConfiguration config;
public MultiverseCore() {
super();
}
/**
* This is for unit testing.
* @param loader The PluginLoader to use.
* @param description The Description file to use.
* @param dataFolder The folder that other datafiles can be found in.
* @param file The location of the plugin.
*/
public MultiverseCore(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) {
super(loader, description, dataFolder, file);
}
/**
* This method is used to find out who is teleporting a player.
* @param playerName The teleported player (the teleportee).
* @return The player that teleported the other one (the teleporter).
*/
public static String getPlayerTeleporter(String playerName) {
if (teleportQueue.containsKey(playerName)) {
String teleportee = teleportQueue.get(playerName);
teleportQueue.remove(playerName);
return teleportee;
}
return null;
}
/**
* This method is used to add a teleportation to the teleportQueue.
*
* @param teleporter The name of the player that initiated the teleportation.
* @param teleportee The name of the player that was teleported.
*/
public static void addPlayerToTeleportQueue(String teleporter, String teleportee) {
Logging.finest("Adding mapping '%s' => '%s' to teleport queue", teleporter, teleportee);
teleportQueue.put(teleportee, teleporter);
}
/**
* {@inheritDoc}
* @deprecated This is now deprecated, nobody needs it any longer.
* All version info-dumping is now done with {@link MVVersionEvent}.
*/
@Override
@Deprecated
public String dumpVersionInfo(String buffer) {
return buffer;
}
@Override
public MultiverseCore getCore() {
return this;
}
@Override
public void setCore(MultiverseCore core) {
// This method is required by the interface (so core is effectively a plugin of itself) and therefore
// this is never used.
}
@Override
public int getProtocolVersion() {
return MultiverseCore.PROTOCOL;
}
// Setup our Map for our Commands using the CommandHandler.
private CommandHandler commandHandler;
private CommandQueueManager commandQueueManager;
private static final String LOG_TAG = "[Multiverse-Core]";
// Multiverse Permissions Handler
private MVPermissions ph;
// Configurations
private FileConfiguration multiverseConfig = null;
private final MVWorldManager worldManager = new WorldManager(this);
// Setup the block/player/entity listener.
private final MVPlayerListener playerListener = new MVPlayerListener(this);
private final MVEntityListener entityListener = new MVEntityListener(this);
private final MVWeatherListener weatherListener = new MVWeatherListener(this);
private final MVPortalListener portalListener = new MVPortalListener(this);
private final MVWorldListener worldListener = new MVWorldListener(this);
private MVChatListener chatListener;
// HashMap to contain information relating to the Players.
private HashMap<String, MVPlayerSession> playerSessions;
private MVEconomist economist;
private Buscript buscript;
private int pluginCount;
private DestinationFactory destFactory;
private MultiverseMessaging messaging;
private BlockSafety blockSafety;
private LocationManipulation locationManipulation;
private SafeTTeleporter safeTTeleporter;
private UnsafeCallWrapper unsafeCallWrapper;
private File serverFolder = new File(System.getProperty("user.dir"));
@Override
public void onLoad() {
// Register our config
SerializationConfig.registerAll(MultiverseCoreConfiguration.class);
// Register our world
SerializationConfig.registerAll(WorldProperties.class);
// Create our DataFolder
getDataFolder().mkdirs();
// Setup our Debug Log
Logging.init(this);
SerializationConfig.initLogging(Logging.getLogger());
// Setup our BlockSafety
this.blockSafety = new SimpleBlockSafety(this);
// Setup our LocationManipulation
this.locationManipulation = new SimpleLocationManipulation();
// Setup our SafeTTeleporter
this.safeTTeleporter = new SimpleSafeTTeleporter(this);
this.unsafeCallWrapper = new UnsafeCallWrapper(this);
// Setup our CompatibilityLayer
CompatibilityLayer.init();
}
@Override
@Deprecated
public VaultHandler getVaultHandler() {
return getEconomist().getVaultHandler();
}
public MVEconomist getEconomist() {
return economist;
}
/**
* {@inheritDoc}
*/
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(new MVWorldInitListener(this), this);
this.messaging = new MVMessaging();
this.economist = new MVEconomist(this);
// Load the defaultWorldGenerators
this.worldManager.getDefaultWorldGenerators();
this.registerEvents();
// Setup Permissions, we'll do an initial check for the Permissions plugin then fall back on isOP().
this.ph = new MVPermissions(this);
// Setup the command manager
this.commandHandler = new CommandHandler(this, this.ph);
this.commandQueueManager = new CommandQueueManager(this);
// Call the Function to assign all the Commands to their Class.
this.registerCommands();
// Initialize the Destination factor AFTER the commands
this.initializeDestinationFactory();
this.playerSessions = new HashMap<String, MVPlayerSession>();
// Start the Update Checker
// updateCheck = new UpdateChecker(this.getDescription().getName(), this.getDescription().getVersion());
// Call the Function to load all the Worlds and setup the HashMap
// When called with null, it tries to load ALL
// this function will be called every time a plugin registers a new envtype with MV
// Setup & Load our Configuration files.
loadConfigs();
if (this.multiverseConfig != null) {
Logging.setShowingConfig(!getMVConfig().getSilentStart());
this.worldManager.loadDefaultWorlds();
this.worldManager.loadWorlds(true);
} else {
Logging.severe("Your configs were not loaded. Very little will function in Multiverse.");
}
this.anchorManager.loadAnchors();
// Now set the firstspawnworld (after the worlds are loaded):
this.worldManager.setFirstSpawnWorld(getMVConfig().getFirstSpawnWorld());
try {
getMVConfig().setFirstSpawnWorld(this.worldManager.getFirstSpawnWorld().getName());
} catch (NullPointerException e) {
// A test that had no worlds loaded was being run. This should never happen in production
}
this.saveMVConfig();
// Register async or sync player chat according to config
try {
Class.forName("org.bukkit.event.player.AsyncPlayerChatEvent");
} catch (ClassNotFoundException e) {
getMVConfig().setUseAsyncChat(false);
}
if (getMVConfig().getUseAsyncChat()) {
this.chatListener = new MVAsyncPlayerChatListener(this, this.playerListener);
} else {
this.chatListener = new MVPlayerChatListener(this, this.playerListener);
}
getServer().getPluginManager().registerEvents(this.chatListener, this);
this.initializeBuscript();
this.setupMetrics();
// Output a little snippet to show it's enabled.
Logging.config("Version %s (API v%s) Enabled - By %s", this.getDescription().getVersion(), PROTOCOL, getAuthors());
if (getMVConfig().isShowingDonateMessage()) {
getLogger().config("Help dumptruckman keep this project alive. Become a patron! https://www.patreon.com/dumptruckman");
getLogger().config("One time donations are also appreciated: https://www.paypal.me/dumptruckman");
}
}
private void setupMetrics() {
if (TestingMode.isDisabled()) {
MetricsConfigurator.configureMetrics(this);
}
}
/**
* Initializes the buscript javascript library.
*/
private void initializeBuscript() {
buscript = null;
if (this.getMVConfig().getEnableBuscript()) {
try {
buscript = new Buscript(this);
// Add global variable "multiverse" to javascript environment
buscript.setScriptVariable("multiverse", this);
} catch (NullPointerException e) {
Logging.warning("Buscript failed to load! The script command will be disabled! " +
"If you would like not to see this message, " +
"use `/mv conf enablebuscript false` to disable Buscript from loading.");
}
}
}
private void initializeDestinationFactory() {
this.destFactory = new DestinationFactory(this);
this.destFactory.registerDestinationType(WorldDestination.class, "");
this.destFactory.registerDestinationType(WorldDestination.class, "w");
this.destFactory.registerDestinationType(ExactDestination.class, "e");
this.destFactory.registerDestinationType(PlayerDestination.class, "pl");
this.destFactory.registerDestinationType(CannonDestination.class, "ca");
this.destFactory.registerDestinationType(BedDestination.class, "b");
this.destFactory.registerDestinationType(AnchorDestination.class, "a");
}
/**
* Function to Register all the Events needed.
*/
private void registerEvents() {
PluginManager pm = getServer().getPluginManager();
pm.registerEvents(this.playerListener, this);
pm.registerEvents(this.entityListener, this);
pm.registerEvents(this.weatherListener, this);
pm.registerEvents(this.portalListener, this);
Logging.info(ChatColor.GREEN + "We are aware of the warning about the deprecated event. There is no alternative that allows us to do what we need to do and performance impact is negligible. It is safe to ignore.");
pm.registerEvents(this.worldListener, this);
pm.registerEvents(new MVMapListener(this), this);
}
/**
* {@inheritDoc}
*/
@Override
public void loadConfigs() {
// Now grab the Configuration Files.
this.multiverseConfig = YamlConfiguration.loadConfiguration(new File(getDataFolder(), "config.yml"));
InputStream resourceURL = this.getClass().getResourceAsStream("/defaults/config.yml");
// Read in our default config with UTF-8 now
Configuration coreDefaults;
try {
coreDefaults = YamlConfiguration.loadConfiguration(new BufferedReader(new InputStreamReader(resourceURL, "UTF-8")));
this.multiverseConfig.setDefaults(coreDefaults);
} catch (UnsupportedEncodingException e) {
Logging.severe("Couldn't load default config with UTF-8 encoding. Details follow:");
e.printStackTrace();
Logging.severe("Default configs NOT loaded.");
}
this.multiverseConfig.options().copyDefaults(false);
this.multiverseConfig.options().copyHeader(true);
MultiverseCoreConfiguration wantedConfig = null;
try {
wantedConfig = (MultiverseCoreConfiguration) multiverseConfig.get("multiverse-configuration");
} catch (Exception ignore) {
} finally {
config = ((wantedConfig == null) ? new MultiverseCoreConfiguration() : wantedConfig);
}
this.migrateWorldConfig();
this.worldManager.loadWorldConfig(new File(getDataFolder(), "worlds.yml"));
this.messaging.setCooldown(getMVConfig().getMessageCooldown());
// Remove old values.
this.multiverseConfig.set("enforcegamemodes", null);
this.multiverseConfig.set("bedrespawn", null);
this.multiverseConfig.set("opfallback", null);
// Old Config Format
this.migrate22Values();
this.saveMVConfigs();
int level = Logging.getDebugLevel();
Logging.setDebugLevel(getMVConfig().getGlobalDebug());
if (level != Logging.getDebugLevel()) {
getServer().getPluginManager().callEvent(new MVDebugModeEvent(level));
}
}
/**
* Thes are the MV config 2.0-2.2 values,
* they should be migrated to the new format.
*/
private void migrate22Values() {
if (this.multiverseConfig.isSet("worldnameprefix")) {
Logging.config("Migrating 'worldnameprefix'...");
this.getMVConfig().setPrefixChat(this.multiverseConfig.getBoolean("worldnameprefix"));
this.multiverseConfig.set("worldnameprefix", null);
}
if (this.multiverseConfig.isSet("firstspawnworld")) {
Logging.config("Migrating 'firstspawnworld'...");
this.getMVConfig().setFirstSpawnWorld(this.multiverseConfig.getString("firstspawnworld"));
this.multiverseConfig.set("firstspawnworld", null);
}
if (this.multiverseConfig.isSet("enforceaccess")) {
Logging.config("Migrating 'enforceaccess'...");
this.getMVConfig().setEnforceAccess(this.multiverseConfig.getBoolean("enforceaccess"));
this.multiverseConfig.set("enforceaccess", null);
}
if (this.multiverseConfig.isSet("displaypermerrors")) {
Logging.config("Migrating 'displaypermerrors'...");
this.getMVConfig().setDisplayPermErrors(this.multiverseConfig.getBoolean("displaypermerrors"));
this.multiverseConfig.set("displaypermerrors", null);
}
if (this.multiverseConfig.isSet("teleportintercept")) {
Logging.config("Migrating 'teleportintercept'...");
this.getMVConfig().setTeleportIntercept(this.multiverseConfig.getBoolean("teleportintercept"));
this.multiverseConfig.set("teleportintercept", null);
}
if (this.multiverseConfig.isSet("firstspawnoverride")) {
Logging.config("Migrating 'firstspawnoverride'...");
this.getMVConfig().setFirstSpawnOverride(this.multiverseConfig.getBoolean("firstspawnoverride"));
this.multiverseConfig.set("firstspawnoverride", null);
}
if (this.multiverseConfig.isSet("messagecooldown")) {
Logging.config("Migrating 'messagecooldown'...");
this.getMVConfig().setMessageCooldown(this.multiverseConfig.getInt("messagecooldown"));
this.multiverseConfig.set("messagecooldown", null);
}
if (this.multiverseConfig.isSet("debug")) {
Logging.config("Migrating 'debug'...");
this.getMVConfig().setGlobalDebug(this.multiverseConfig.getInt("debug"));
this.multiverseConfig.set("debug", null);
}
if (this.multiverseConfig.isSet("version")) {
Logging.config("Migrating 'version'...");
this.multiverseConfig.set("version", null);
}
}
private static final char PATH_SEPARATOR = '\uF8FF';
/**
* Migrate the worlds.yml to SerializationConfig.
*/
private void migrateWorldConfig() { // SUPPRESS CHECKSTYLE: MethodLength
FileConfiguration wconf = new YamlConfiguration();
wconf.options().pathSeparator(PATH_SEPARATOR);
File worldsFile = new File(getDataFolder(), "worlds.yml");
try {
wconf.load(worldsFile);
} catch (IOException e) {
Logging.warning("Cannot load worlds.yml");
} catch (InvalidConfigurationException e) {
Logging.warning("Your worlds.yml is invalid!");
}
if (!wconf.isConfigurationSection("worlds")) { // empty config
Logging.fine("No worlds to migrate!");
return;
}
Map<String, Object> values = wconf.getConfigurationSection("worlds").getValues(false);
boolean wasChanged = false;
Map<String, Object> newValues = new LinkedHashMap<String, Object>(values.size());
for (Map.Entry<String, Object> entry : values.entrySet()) {
if (entry.getValue() instanceof WorldProperties) {
// fine
newValues.put(entry.getKey(), entry.getValue());
} else if (entry.getValue() instanceof ConfigurationSection) {
Logging.fine("Migrating: " + entry.getKey());
// we have to migrate this
WorldProperties world = new WorldProperties(Collections.emptyMap());
ConfigurationSection section = (ConfigurationSection) entry.getValue();
// migrate animals and monsters
if (section.isConfigurationSection("animals")) {
ConfigurationSection animalSection = section.getConfigurationSection("animals");
if (animalSection.contains("spawn")) {
if (animalSection.isBoolean("spawn"))
world.setAllowAnimalSpawn(animalSection.getBoolean("spawn"));
else
world.setAllowAnimalSpawn(Boolean.parseBoolean(animalSection.getString("spawn")));
}
if (animalSection.isList("exceptions")) {
world.getAnimalList().clear();
world.getAnimalList().addAll(animalSection.getStringList("exceptions"));
}
}
if (section.isConfigurationSection("monsters")) {
ConfigurationSection monsterSection = section.getConfigurationSection("monsters");
if (monsterSection.contains("spawn")) {
if (monsterSection.isBoolean("spawn"))
world.setAllowMonsterSpawn(monsterSection.getBoolean("spawn"));
else
world.setAllowMonsterSpawn(Boolean.parseBoolean(monsterSection.getString("spawn")));
}
if (monsterSection.isList("exceptions")) {
world.getMonsterList().clear();
world.getMonsterList().addAll(monsterSection.getStringList("exceptions"));
}
}
// migrate entryfee
if (section.isConfigurationSection("entryfee")) {
ConfigurationSection feeSection = section.getConfigurationSection("entryfee");
if (feeSection.isInt("currency")) {
world.setCurrency(MaterialConverter.convertConfigType(feeSection, "currency"));
}
if (feeSection.isDouble("amount"))
world.setPrice(feeSection.getDouble("amount"));
else if (feeSection.isInt("amount"))
world.setPrice(feeSection.getInt("amount"));
}
// migrate pvp
if (section.isBoolean("pvp")) {
world.setPVPMode(section.getBoolean("pvp"));
}
// migrate alias
if (section.isConfigurationSection("alias")) {
ConfigurationSection aliasSection = section.getConfigurationSection("alias");
if (aliasSection.isString("color"))
world.setColor(aliasSection.getString("color"));
if (aliasSection.isString("name"))
world.setAlias(aliasSection.getString("name"));
}
// migrate worldblacklist
if (section.isList("worldblacklist")) {
world.getWorldBlacklist().clear();
world.getWorldBlacklist().addAll(section.getStringList("worldblacklist"));
}
// migrate scale
if (section.isDouble("scale")) {
world.setScaling(section.getDouble("scale"));
}
// migrate gamemode
if (section.isString("gamemode")) {
final GameMode gameMode = GameMode.valueOf(section.getString("gamemode").toUpperCase());
if (gameMode != null) {
world.setGameMode(gameMode);
}
}
// migrate hunger
if (section.isBoolean("hunger")) {
world.setHunger(section.getBoolean("hunger"));
}
// migrate hidden
if (section.isBoolean("hidden")) {
world.setHidden(section.getBoolean("hidden"));
}
// migrate autoheal
if (section.isBoolean("autoheal")) {
world.setAutoHeal(section.getBoolean("autoheal"));
}
// migrate portalform
if (section.isString("portalform")) {
try {
world.setProperty("portalform", section.getString("portalform"), true);
} catch (NoSuchPropertyException e) {
throw new RuntimeException("Who forgot to update the migrator?", e);
}
}
// migrate environment
if (section.isString("environment")) {
try {
world.setProperty("environment", section.getString("environment"), true);
} catch (NoSuchPropertyException e) {
throw new RuntimeException("Who forgot to update the migrator?", e);
}
}
// migrate generator
if (section.isString("generator")) {
world.setGenerator(section.getString("generator"));
}
// migrate seed
if (section.isLong("seed")) {
world.setSeed(section.getLong("seed"));
}
// migrate weather
if (section.isBoolean("allowweather")) {
world.setEnableWeather(section.getBoolean("allowweather"));
}
// migrate adjustspawn
if (section.isBoolean("adjustspawn")) {
world.setAdjustSpawn(section.getBoolean("adjustspawn"));
}
// migrate autoload
if (section.isBoolean("autoload")) {
world.setAutoLoad(section.getBoolean("autoload"));
}
// migrate bedrespawn
if (section.isBoolean("bedrespawn")) {
world.setBedRespawn(section.getBoolean("bedrespawn"));
}
// migrate spawn
if (section.isConfigurationSection("spawn")) {
ConfigurationSection spawnSect = section.getConfigurationSection("spawn");
Location spawnLoc = new NullLocation();
if (spawnSect.isDouble("yaw"))
spawnLoc.setYaw((float) spawnSect.getDouble("yaw"));
if (spawnSect.isDouble("pitch"))
spawnLoc.setPitch((float) spawnSect.getDouble("pitch"));
if (spawnSect.isDouble("x"))
spawnLoc.setX(spawnSect.getDouble("x"));
if (spawnSect.isDouble("y"))
spawnLoc.setY(spawnSect.getDouble("y"));
if (spawnSect.isDouble("z"))
spawnLoc.setZ(spawnSect.getDouble("z"));
world.setSpawnLocation(spawnLoc);
}
// migrate difficulty
if (section.isString("difficulty")) {
Difficulty difficulty;
try {
difficulty = Difficulty.valueOf(section.getString("difficulty").toUpperCase());
} catch (IllegalArgumentException e) {
Logging.warning("Could not parse difficulty: " + section.getString("difficulty"));
Logging.warning("Setting world " + entry.getKey() + " difficulty to NORMAL");
difficulty = Difficulty.NORMAL;
}
if (difficulty != null) {
world.setDifficulty(difficulty);
}
}
// migrate keepspawninmemory
if (section.isBoolean("keepspawninmemory")) {
world.setKeepSpawnInMemory(section.getBoolean("keepspawninmemory"));
}
newValues.put(entry.getKey(), world);
wasChanged = true;
} else {
// huh?
Logging.warning("Removing unknown entry in the config: " + entry);
// just don't add to newValues
wasChanged = true;
}
}
if (wasChanged) {
// clear config
wconf.set("worlds", null);
// and rebuild it
ConfigurationSection rootSection = wconf.createSection("worlds");
for (Map.Entry<String, Object> entry : newValues.entrySet()) {
rootSection.set(entry.getKey(), entry.getValue());
}
try {
wconf.save(new File(getDataFolder(), "worlds.yml"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* {@inheritDoc}
*/
@Override
public MultiverseMessaging getMessaging() {
return this.messaging;
}
/**
* Register Multiverse-Core commands to Command Manager.
*/
private void registerCommands() {
// Intro Commands
this.commandHandler.registerCommand(new HelpCommand(this));
this.commandHandler.registerCommand(new VersionCommand(this));
this.commandHandler.registerCommand(new ListCommand(this));
this.commandHandler.registerCommand(new InfoCommand(this));
this.commandHandler.registerCommand(new CreateCommand(this));
this.commandHandler.registerCommand(new CloneCommand(this));
this.commandHandler.registerCommand(new ImportCommand(this));
this.commandHandler.registerCommand(new ReloadCommand(this));
this.commandHandler.registerCommand(new SetSpawnCommand(this));
this.commandHandler.registerCommand(new CoordCommand(this));
this.commandHandler.registerCommand(new TeleportCommand(this));
this.commandHandler.registerCommand(new WhoCommand(this));
this.commandHandler.registerCommand(new SpawnCommand(this));
// Dangerous Commands
this.commandHandler.registerCommand(new UnloadCommand(this));
this.commandHandler.registerCommand(new LoadCommand(this));
this.commandHandler.registerCommand(new RemoveCommand(this));
this.commandHandler.registerCommand(new DeleteCommand(this));
this.commandHandler.registerCommand(new RegenCommand(this));
this.commandHandler.registerCommand(new ConfirmCommand(this));
// Modification commands
this.commandHandler.registerCommand(new ModifyCommand(this));
this.commandHandler.registerCommand(new PurgeCommand(this));
this.commandHandler.registerCommand(new ModifyAddCommand(this));
this.commandHandler.registerCommand(new ModifySetCommand(this));
this.commandHandler.registerCommand(new ModifyRemoveCommand(this));
this.commandHandler.registerCommand(new ModifyClearCommand(this));
this.commandHandler.registerCommand(new ConfigCommand(this));
this.commandHandler.registerCommand(new AnchorCommand(this));
// Misc Commands
this.commandHandler.registerCommand(new EnvironmentCommand(this));
this.commandHandler.registerCommand(new DebugCommand(this));
this.commandHandler.registerCommand(new SilentCommand(this));
this.commandHandler.registerCommand(new GeneratorCommand(this));
this.commandHandler.registerCommand(new CheckCommand(this));
this.commandHandler.registerCommand(new ScriptCommand(this));
this.commandHandler.registerCommand(new GameruleCommand(this));
this.commandHandler.registerCommand(new GamerulesCommand(this));
}
/**
* {@inheritDoc}
*/
@Override
public void onDisable() {
this.saveMVConfigs();
Logging.shutdown();
}
/**
* {@inheritDoc}
*/
@Override
public MVPlayerSession getPlayerSession(Player player) {
if (this.playerSessions.containsKey(player.getName())) {
return this.playerSessions.get(player.getName());
} else {
this.playerSessions.put(player.getName(), new MVPlayerSession(player, getMVConfig()));
return this.playerSessions.get(player.getName());
}
}
/**
* {@inheritDoc}
*/
@Override
public MVPermissions getMVPerms() {
return this.ph;
}
/**
* {@inheritDoc}
*/
@Override
public boolean onCommand(CommandSender sender, Command command, String commandLabel, String[] args) {
if (!this.isEnabled()) {
sender.sendMessage("This plugin is Disabled!");
return true;
}
ArrayList<String> allArgs = new ArrayList<String>(Arrays.asList(args));
allArgs.add(0, command.getName());
try {
return this.commandHandler.locateAndRunCommand(sender, allArgs, getMVConfig().getDisplayPermErrors());
} catch (Exception e) {
e.printStackTrace();
sender.sendMessage(ChatColor.RED + "An internal error occurred when attempting to perform this command.");
if (sender.isOp())
sender.sendMessage(ChatColor.RED + "Details were printed to the server console and logs, please add that to your bug report.");
else
sender.sendMessage(ChatColor.RED + "Try again and contact the server owner or an admin if this problem persists.");
return true;
}
}
/**
* {@inheritDoc}
*
* @deprecated This is now deprecated, nobody needs it any longer.
* All logging is now done with {@link Logging}.
*/
@Override
@Deprecated
public void log(Level level, String msg) {
Logging.log(level, msg);
}
/**
* Logs a message at the specified level.
*
* @param level The Log-{@link Level}.
* @param msg The message to log.
*
* @deprecated Replaced by {@link Logging}. Please refrain from using this from a third party plugin as the
* messages will appear to originate from Multiverse-Core.
*/
@Deprecated
public static void staticLog(Level level, String msg) {
Logging.log(level, msg);
}
/**
* Print messages to the Debug Log, if the servers in Debug Mode then we also want to print the messages to the
* standard Server Console.
*
* @param level The Log-{@link Level}
* @param msg The message
*
* @deprecated Replaced by {@link Logging}. Please refrain from using this from a third party plugin as the
* messages will appear to originate from Multiverse-Core.
*/
@Deprecated
public static void staticDebugLog(Level level, String msg) {
Logging.log(level, msg);
}
/**
* {@inheritDoc}
*/
@Override
public String getAuthors() {
String authors = "";
List<String> auths = this.getDescription().getAuthors();
if (auths.size() == 0) {
return "";
}
if (auths.size() == 1) {
return auths.get(0);
}
for (int i = 0; i < auths.size(); i++) {
if (i == this.getDescription().getAuthors().size() - 1) {
authors += " and " + this.getDescription().getAuthors().get(i);
} else {
authors += ", " + this.getDescription().getAuthors().get(i);
}
}
return authors.substring(2);
}
/**
* {@inheritDoc}
*/
@Override
public CommandHandler getCommandHandler() {
return this.commandHandler;
}
/**
* {@inheritDoc}
*/
@Override
@Deprecated
public CommandQueueManager getCommandQueueManager() {
return commandQueueManager;
}
/**
* Gets the log-tag.
*
* @return The log-tag
*/
// TODO this should be static!
public String getTag() {
return MultiverseCore.LOG_TAG;
}
/**
* Shows a message that the given world is not a MultiverseWorld.
*
* @param sender The {@link CommandSender} that should receive the message
* @param worldName The name of the invalid world
*/
public void showNotMVWorldMessage(CommandSender sender, String worldName) {
sender.sendMessage("Multiverse doesn't know about " + ChatColor.DARK_AQUA + worldName + ChatColor.WHITE + " yet.");
sender.sendMessage("Type " + ChatColor.DARK_AQUA + "/mv import ?" + ChatColor.WHITE + " for help!");
}
/**
* Removes a player-session.
*
* @param player The {@link Player} that owned the session.
*/
public void removePlayerSession(Player player) {
if (this.playerSessions.containsKey(player.getName())) {
this.playerSessions.remove(player.getName());
}
}
/**
* {@inheritDoc}
*/
@Override
public int getPluginCount() {
return this.pluginCount;
}
/**
* {@inheritDoc}
*/
@Override
public void incrementPluginCount() {
this.pluginCount += 1;
}
/**
* {@inheritDoc}
*/
@Override
public void decrementPluginCount() {
this.pluginCount -= 1;
}
/**
* {@inheritDoc}
*/
@Override
public DestinationFactory getDestFactory() {
return this.destFactory;
}
/**
* This is a convenience method to allow the QueuedCommand system to call it. You should NEVER call this directly.
*
* @param teleporter The Person requesting that the teleport should happen.
* @param p Player The Person being teleported.
* @param l The potentially unsafe location.
*/
public void teleportPlayer(CommandSender teleporter, Player p, Location l) {
// This command is the override, and MUST NOT TELEPORT SAFELY
this.getSafeTTeleporter().safelyTeleport(teleporter, p, l, false);
}
/**
* Gets the server's root-folder as {@link File}.
*
* @return The server's root-folder
*/
public File getServerFolder() {
return serverFolder;
}
/**
* Sets this server's root-folder.
*
* @param newServerFolder The new server-root
*/
public void setServerFolder(File newServerFolder) {
if (!newServerFolder.isDirectory())
throw new IllegalArgumentException("That's not a folder!");
this.serverFolder = newServerFolder;
}
/**
* {@inheritDoc}
*/
@Override
public MVWorldManager getMVWorldManager() {
return this.worldManager;
}
/**
* Gets the {@link MVPlayerListener}.
*
* @return The {@link MVPlayerListener}.
*/
public MVPlayerListener getPlayerListener() {
return this.playerListener;
}
/**
* Gets the {@link MVChatListener}.
*
* @return The {@link MVChatListener}.
*/
public MVChatListener getChatListener() {
return this.chatListener;
}
/**
* 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.
*
* @return Whether the Multiverse-Config was successfully saved
*/
public boolean saveMVConfig() {
try {
this.multiverseConfig.set("multiverse-configuration", getMVConfig());
this.multiverseConfig.save(new File(getDataFolder(), "config.yml"));
return true;
} catch (IOException e) {
Logging.severe("Could not save Multiverse config.yml config. Please check your file permissions.");
return false;
}
}
/**
* Saves the world config.
*
* @return Whether the world-config was successfully saved
*/
public boolean saveWorldConfig() {
return this.worldManager.saveWorldsConfig();
}
/**
* {@inheritDoc}
*/
@Override
public boolean saveMVConfigs() {
return this.saveMVConfig() && this.saveWorldConfig();
}
/**
* NOT deprecated for the time as queued commands use this.
* However, this is not in the API and other plugins should therefore not use it.
*
* @param name World to delete
* @return True if success, false if fail.
*/
public Boolean deleteWorld(String name) {
return this.worldManager.deleteWorld(name);
}
/**
* NOT deprecated for the time as queued commands use this.
* However, this is not in the API and other plugins should therefore not use it.
*
* @param oldName World to copy
* @param newName World to create
* @param generator The Custom generator plugin to use.
* @return True if success, false if fail.
*/
public Boolean cloneWorld(String oldName, String newName, String generator) {
return this.worldManager.cloneWorld(oldName, newName, generator);
}
/**
* {@inheritDoc}
* @deprecated This is deprecated! Do not use!
*/
@Override
@Deprecated
public Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed) {
return this.worldManager.regenWorld(name, useNewSeed, randomSeed, seed, false);
}
/**
* {@inheritDoc}
* @deprecated This is deprecated! Do not use!
*/
@Override
@Deprecated
public Boolean regenWorld(String name, Boolean useNewSeed, Boolean randomSeed, String seed, Boolean keepGameRules) {
return this.worldManager.regenWorld(name, useNewSeed, randomSeed, seed, keepGameRules);
}
/**
* {@inheritDoc}
*/
@Override
public AnchorManager getAnchorManager() {
return this.anchorManager;
}
/**
* {@inheritDoc}
*/
@Override
public BlockSafety getBlockSafety() {
return blockSafety;
}
/**
* {@inheritDoc}
*/
@Override
public void setBlockSafety(BlockSafety bs) {
if (bs == null) {
throw new NullPointerException("block safety may not be null.");
}
this.blockSafety = bs;
}
/**
* {@inheritDoc}
*/
@Override
public LocationManipulation getLocationManipulation() {
return locationManipulation;
}
/**
* {@inheritDoc}
*/
@Override
public void setLocationManipulation(LocationManipulation locationManipulation) {
this.locationManipulation = locationManipulation;
}
/**
* {@inheritDoc}
*/
@Override
public SafeTTeleporter getSafeTTeleporter() {
return safeTTeleporter;
}
/**
* {@inheritDoc}
*/
@Override
public void setSafeTTeleporter(SafeTTeleporter safeTTeleporter) {
this.safeTTeleporter = safeTTeleporter;
}
/**
* {@inheritDoc}
*/
@Override
public MultiverseCoreConfig getMVConfig() {
return config;
}
/**
* This method is currently used by other plugins.
* It will be removed in 2.4
* @return The Multiverse config.
* @deprecated This is deprecated.
*/
@Deprecated
public static MultiverseCoreConfiguration getStaticConfig() {
return MultiverseCoreConfiguration.getInstance();
}
@Override
public Buscript getScriptAPI() {
return buscript;
}
public UnsafeCallWrapper getUnsafeCallWrapper() {
return this.unsafeCallWrapper;
}
}