Compare commits

...
Author SHA1 Message Date
main() caf4f1b566 Bukkit perms are broken.
Or at least they don't work the way they (in my opinion) should. Take a
look at HierarchyPermission.java for a detailed explanation.
2013-04-13 02:26:19 +02:00
main() 4a66a2f5bb If the debug level is >= 1: stacktrace 2013-03-18 18:02:55 +01:00
main() a8040abd52 "Not MV's fault"-Message for getChunkGenerator()
If a plugin, for whatever weird reason, gets loaded and enabled correctly,
but just getDefaultWorldGenerator() throws, people might think it's MV's
fault. Not anymore.
2013-03-18 17:27:03 +01:00
Jeremy Wood 72a14719ac Now using apache commons for file operations. Hopefully we will get more success with deleting and copying stuff. May fix Inventories test failures. 2013-03-11 15:35:05 -04:00
main() 2b827a1fae Style fixes. 2013-03-02 13:13:24 +01:00
main() e45520c43b Update checkstyle. 2013-03-02 13:13:09 +01:00
main() 0fb33d12d6 Now mocking plugin.getLogger() in the tests.
Fixes the test issues with AllPay.
2013-03-02 12:31:31 +01:00
main() ebe44ed99e Fixed the GenericBank imports 2013-03-02 12:24:05 +01:00
Jeremy Wood 23ba7fe73b Updated to AllPay 13. 2013-02-26 09:49:38 -05:00
Jeremy Wood 4efa97ee0e Removing deprecated getMVConfiguration() method because I suspect it could be related to some issues. 2013-02-20 13:56:24 -05:00
Jeremy Wood 8bfe3a5473 Don't try to set search radius when portal travel agent is null. Fixes #1072. 2013-02-04 15:15:52 -05:00
Jeremy Wood 07a38e3e58 Should fix issue where gamemode/flight change on /reload of server due to permission issues. 2013-01-02 13:20:52 -05:00
Jeremy Wood 360c63fad9 Updated to AllPay 11 2013-01-02 11:44:38 -05:00
Jeremy Wood 2a5edc4f91 Added argument check to setBlockSafety. 2012-12-27 16:02:46 -05:00
main() fa9191dd8f The message now CLEARLY states that it's not Multiverse's fault. 2012-12-22 15:26:20 +01:00
main() 4043d5abcb Getting the generator is now wrapped in a try block.
The Bukkit API calls a plugin method. If that method throws exceptions, they fall through right into our face and then Bukkit blames us. Not good.
Thanks andrewkm for mentioning this.
2012-12-22 00:53:03 +01:00
Jeremy Wood eff56f74da Changed the default portal search radius back to match vanilla's 128 instead of 16. 2012-12-21 10:14:45 -05:00
Jeremy Wood d97a9bccde Now building against Vault 1.2.20 which is hosted on our own repo now. 2012-12-13 08:50:32 -05:00
Jeremy Wood 55741b524d Added bats to animals for the time being. Fixes #996 2012-12-10 23:27:55 -05:00
Jeremy Wood 186d3f15a4 Woo, Travis.ci! 2012-12-10 12:04:26 -08:00
Jeremy Wood 841f6f05df Added "/mv gamerule" and "/mv gamerules" for setting and listing game rules per world. Fixes #987. 2012-12-03 15:05:58 -05:00
Jeremy Wood ebc2a516bb Added world property 'allowFlight' to disable flying per world. Does not have an override permission yet. Adds #440. 2012-12-03 11:59:01 -05:00
Jeremy Wood 9e029ad6ae Maps can now be made for non default worlds! Fixes #972 2012-11-30 13:08:15 -05:00
main() b2135a8f42 Added world seed to the info command.
Fixes #627.
2012-11-28 14:39:07 +01:00
Jeremy Wood 8cbffd1cee Now building against Bukkit 1.4.5-R0.2 2012-11-27 15:59:24 -05:00
Jeremy Wood ff22077adf New worlds now use the correct scale. Fixes #979. 2012-11-27 14:09:33 -05:00
Jeremy Wood 60c0a1ab92 Fixed world spawns not keeping pitch + yaw. Fixes #976 2012-11-23 12:30:11 -05:00
Jeremy Wood 58eeecbcb8 Fixed issue where Multiverse always checks block safety to fix world spawns on startup/reload. 2012-11-23 11:49:14 -05:00
Jeremy Wood 876456b932 Fixed up some migration issues caused by WorldProperties refactor. Fixes #968. 2012-11-19 14:05:07 -05:00
Jeremy Wood 18db50ca56 MVWorld now throws IllegalStateException when it cannot obtain a world reference. This should help pinpoint the source of sometimes cryptic exceptions elsewhere. 2012-11-15 13:49:11 -05:00
Jeremy Wood cce1ccc967 Now caches the world properties before unloading the world in order to prevent NPE on unload then load. Really fixes #947. 2012-11-15 09:30:19 -05:00
Jeremy Wood e5537dd8f1 "mv regen" now respects world type! 2012-11-14 20:55:12 -05:00
Jeremy Wood 0c7ba2ae67 Fixed tests for entity purger changes. 2012-11-14 15:52:21 -05:00
Jeremy Wood bbfc672582 Improved world purger debug. 2012-11-14 15:19:09 -05:00
Jeremy Wood a65dc4966b Now removes projectiles shot by the entities removed by the purger. Should fix #958. 2012-11-14 15:11:55 -05:00
Jeremy Wood 4780f87278 Now uses world UUID to retrieve world reference. 2012-11-14 14:24:10 -05:00
Jeremy Wood b11d911e4a Newly created END worlds will now use a scale of 16. This will result in people ending up invariably closer to the end island when teleporting in while using MV-NetherPortals. 2012-11-14 13:58:08 -05:00
Jeremy Wood 155aad8bf2 Multiverse now uses it's own portal search radius by default (16 blocks instead of bukkit's 128). 2 new configuration options added to adjust this behaviour. 2012-11-14 13:52:37 -05:00
Jeremy Wood 6e1d4ef961 Block safety debugging moved to finest level. 2012-11-14 12:52:33 -05:00
Jeremy Wood cfa5a04e3a Fixes #960 2012-11-14 09:08:04 -05:00
Jeremy Wood 7d1c47c2fc Shifted world properties to its own class WorldProperties so we can now only initialize an MVWorld if there is a 'more solid' world reference. Let's hope this works! Should fix #947 2012-11-13 17:30:35 -05:00
Jeremy Wood 957c55955d Now using SerializationConfig 1.7 2012-11-13 13:39:22 -05:00
main() 0226ab9609 Style again. 2012-11-06 17:52:29 +01:00
Jeremy Wood b888561d98 Added package-private method for setting MVWorld plugin and name. Fixes #923. 2012-11-05 13:08:37 -05:00
Jeremy Wood f210851294 Changed how we deal with CB world reference. Partially fixes #923. 2012-11-05 13:02:03 -05:00
main() 73e394d5ec Style. 2012-11-05 16:40:06 +01:00
42 changed files with 1750 additions and 780 deletions

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
language: java
jdk:
- oraclejdk6
notifications:
email: false
-1
View File
@@ -104,7 +104,6 @@
</module>
<module name="LeftCurly"/>
<module name="RightCurly"/>
<module name="DoubleCheckedLocking"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="HiddenField">
+35 -7
View File
@@ -26,10 +26,10 @@
<url>http://repo.mcstats.org/content/repositories/snapshots</url>
</repository>
<!-- Required for Vault -->
<repository>
<!--repository>
<id>herocraft</id>
<url>http://ci.herocraftonline.com/plugin/repository/everything/</url>
</repository>
</repository-->
</repositories>
<pluginRepositories>
@@ -134,7 +134,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.8</version>
<version>2.10</version>
<configuration>
<enableRulesSummary>true</enableRulesSummary>
<configLocation>${project.basedir}/config/mv_checks.xml</configLocation>
@@ -220,17 +220,45 @@
</relocations>
</configuration>
</execution>
<execution>
<id>apache-commons-io</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>org.apache.commons:commons-io</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.apache.commons</pattern>
<shadedPattern>org.apache.commons.multiverse</shadedPattern>
</relocation>
</relocations>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Bukkit Dependency -->
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.3.2-R2.1-SNAPSHOT</version>
<version>1.4.5-R0.2</version>
<!-- If you want the lates, use this -->
<!-- <version>LATEST</version> -->
<type>jar</type>
@@ -248,7 +276,7 @@
<dependency>
<groupId>me.main__.util</groupId>
<artifactId>SerializationConfig</artifactId>
<version>1.6c</version>
<version>1.7</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
@@ -257,14 +285,14 @@
<dependency>
<groupId>com.fernferret.allpay</groupId>
<artifactId>AllPay</artifactId>
<version>10</version>
<version>13</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>Vault</artifactId>
<version>1.2.19-SNAPSHOT</version>
<version>1.2.20</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
File diff suppressed because it is too large. Load diff
@@ -10,7 +10,8 @@ package com.onarandombox.MultiverseCore;
import buscript.Buscript;
import com.dumptruckman.minecraft.util.Logging;
import com.fernferret.allpay.AllPay;
import com.fernferret.allpay.GenericBank;
import com.fernferret.allpay.commons.GenericBank;
import com.onarandombox.MultiverseCore.MVWorld.NullLocation;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.Core;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
@@ -30,6 +31,8 @@ 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;
@@ -61,10 +64,10 @@ import com.onarandombox.MultiverseCore.destination.ExactDestination;
import com.onarandombox.MultiverseCore.destination.PlayerDestination;
import com.onarandombox.MultiverseCore.destination.WorldDestination;
import com.onarandombox.MultiverseCore.event.MVVersionEvent;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
import com.onarandombox.MultiverseCore.listeners.MVAsyncPlayerChatListener;
import com.onarandombox.MultiverseCore.listeners.MVChatListener;
import com.onarandombox.MultiverseCore.listeners.MVEntityListener;
import com.onarandombox.MultiverseCore.listeners.MVMapListener;
import com.onarandombox.MultiverseCore.listeners.MVPlayerChatListener;
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
import com.onarandombox.MultiverseCore.listeners.MVPluginListener;
@@ -77,11 +80,15 @@ import com.onarandombox.MultiverseCore.utils.MVPlayerSession;
import com.onarandombox.MultiverseCore.utils.SimpleBlockSafety;
import com.onarandombox.MultiverseCore.utils.SimpleLocationManipulation;
import com.onarandombox.MultiverseCore.utils.SimpleSafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.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.World.Environment;
import org.bukkit.command.Command;
@@ -212,6 +219,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
private BlockSafety blockSafety;
private LocationManipulation locationManipulation;
private SafeTTeleporter safeTTeleporter;
private UnsafeCallWrapper unsafeCallWrapper;
private File serverFolder = new File(System.getProperty("user.dir"));
@@ -220,7 +228,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
// Register our config
SerializationConfig.registerAll(MultiverseCoreConfiguration.class);
// Register our world
SerializationConfig.registerAll(MVWorld.class);
SerializationConfig.registerAll(WorldProperties.class);
// Create our DataFolder
getDataFolder().mkdirs();
// Setup our Debug Log
@@ -232,16 +240,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
this.locationManipulation = new SimpleLocationManipulation();
// Setup our SafeTTeleporter
this.safeTTeleporter = new SimpleSafeTTeleporter(this);
}
/**
* {@inheritDoc}
* @deprecated This is deprecated.
*/
@Override
@Deprecated
public FileConfiguration getMVConfiguration() {
return this.multiverseConfig;
this.unsafeCallWrapper = new UnsafeCallWrapper(this);
}
/**
@@ -460,7 +459,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
pm.registerEvents(this.pluginListener, this);
pm.registerEvents(this.weatherListener, this);
pm.registerEvents(this.portalListener, this);
pm.registerEvents(new MVMapListener(this), this);
}
/**
@@ -565,13 +564,13 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
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 MVWorld) {
if (entry.getValue() instanceof WorldProperties) {
// fine
newValues.put(entry.getKey(), entry.getValue());
} else if (entry.getValue() instanceof ConfigurationSection) {
this.log(Level.FINE, "Migrating: " + entry.getKey());
// we have to migrate this
MVWorld world = new MVWorld(Collections.EMPTY_MAP);
WorldProperties world = new WorldProperties(Collections.EMPTY_MAP);
ConfigurationSection section = (ConfigurationSection) entry.getValue();
// migrate animals and monsters
@@ -641,10 +640,9 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
// migrate gamemode
if (section.isString("gamemode")) {
try {
world.setPropertyValue("gamemode", section.getString("gamemode"));
} catch (PropertyDoesNotExistException e) {
throw new RuntimeException("Who forgot to update the migrator?", e);
final GameMode gameMode = GameMode.valueOf(section.getString("gamemode").toUpperCase());
if (gameMode != null) {
world.setGameMode(gameMode);
}
}
@@ -666,8 +664,8 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
// migrate portalform
if (section.isString("portalform")) {
try {
world.setPropertyValue("portalform", section.getString("portalform"));
} catch (PropertyDoesNotExistException e) {
world.setProperty("portalform", section.getString("portalform"), true);
} catch (NoSuchPropertyException e) {
throw new RuntimeException("Who forgot to update the migrator?", e);
}
}
@@ -675,8 +673,8 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
// migrate environment
if (section.isString("environment")) {
try {
world.setPropertyValue("environment", section.getString("environment"));
} catch (PropertyDoesNotExistException e) {
world.setProperty("environment", section.getString("environment"), true);
} catch (NoSuchPropertyException e) {
throw new RuntimeException("Who forgot to update the migrator?", e);
}
}
@@ -714,7 +712,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
// migrate spawn
if (section.isConfigurationSection("spawn")) {
ConfigurationSection spawnSect = section.getConfigurationSection("spawn");
Location spawnLoc = world.getSpawnLocation();
Location spawnLoc = new NullLocation();
if (spawnSect.isDouble("yaw"))
spawnLoc.setYaw((float) spawnSect.getDouble("yaw"));
if (spawnSect.isDouble("pitch"))
@@ -729,6 +727,19 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
world.setSpawnLocation(spawnLoc);
}
// migrate difficulty
if (section.isString("difficulty")) {
final Difficulty difficulty = Difficulty.valueOf(section.getString("difficulty").toUpperCase());
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 {
@@ -807,6 +818,8 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
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));
}
/**
@@ -1214,6 +1227,9 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*/
@Override
public void setBlockSafety(BlockSafety bs) {
if (bs == null) {
throw new NullPointerException("block safety may not be null.");
}
this.blockSafety = bs;
}
@@ -1272,4 +1288,8 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
public Buscript getScriptAPI() {
return buscript;
}
public UnsafeCallWrapper getUnsafeCallWrapper() {
return this.unsafeCallWrapper;
}
}
@@ -1,12 +1,10 @@
package com.onarandombox.MultiverseCore;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
import me.main__.util.SerializationConfig.NoSuchPropertyException;
import me.main__.util.SerializationConfig.Property;
import me.main__.util.SerializationConfig.SerializationConfig;
import com.dumptruckman.minecraft.util.*;
import com.onarandombox.MultiverseCore.api.*;
import me.main__.util.SerializationConfig.*;
import java.util.Map;
import java.util.*;
/**
* Our configuration.
@@ -63,6 +61,10 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
private volatile String firstspawnworld;
@Property
private volatile int teleportcooldown;
@Property
private volatile boolean defaultportalsearch;
@Property
private volatile int portalsearchradius;
public MultiverseCoreConfiguration() {
super();
@@ -91,6 +93,8 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
teleportcooldown = 1000;
this.version = 2.9;
silentstart = false;
defaultportalsearch = false;
portalsearchradius = 128;
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
}
@@ -289,4 +293,24 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
public boolean getSilentStart() {
return silentstart;
}
@Override
public void setUseDefaultPortalSearch(boolean useDefaultPortalSearch) {
defaultportalsearch = useDefaultPortalSearch;
}
@Override
public boolean isUsingDefaultPortalSearch() {
return defaultportalsearch;
}
@Override
public void setPortalSearchRadius(int searchRadius) {
this.portalsearchradius = searchRadius;
}
@Override
public int getPortalSearchRadius() {
return portalsearchradius;
}
}
@@ -0,0 +1,638 @@
package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.MVWorld.NullLocation;
import com.onarandombox.MultiverseCore.configuration.EntryFee;
import com.onarandombox.MultiverseCore.configuration.SpawnLocation;
import com.onarandombox.MultiverseCore.configuration.SpawnSettings;
import com.onarandombox.MultiverseCore.configuration.WorldPropertyValidator;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import com.onarandombox.MultiverseCore.enums.EnglishChatColor;
import com.onarandombox.MultiverseCore.enums.EnglishChatStyle;
import me.main__.util.SerializationConfig.IllegalPropertyValueException;
import me.main__.util.SerializationConfig.Property;
import me.main__.util.SerializationConfig.SerializationConfig;
import me.main__.util.SerializationConfig.Serializor;
import me.main__.util.SerializationConfig.Validator;
import me.main__.util.SerializationConfig.VirtualProperty;
import org.bukkit.ChatColor;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World.Environment;
import org.bukkit.configuration.serialization.SerializableAs;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* This is a property class, I think we don't need that much javadoc.
* BEGIN CHECKSTYLE-SUPPRESSION: Javadoc
*/
@SerializableAs("MVWorld")
public class WorldProperties extends SerializationConfig {
private static final Map<String, String> PROPERTY_ALIASES;
static {
PROPERTY_ALIASES = new HashMap<String, String>();
PROPERTY_ALIASES.put("curr", "currency");
PROPERTY_ALIASES.put("scaling", "scale");
PROPERTY_ALIASES.put("aliascolor", "color");
PROPERTY_ALIASES.put("heal", "autoHeal");
PROPERTY_ALIASES.put("storm", "allowWeather");
PROPERTY_ALIASES.put("weather", "allowWeather");
PROPERTY_ALIASES.put("spawnmemory", "keepSpawnInMemory");
PROPERTY_ALIASES.put("memory", "keepSpawnInMemory");
PROPERTY_ALIASES.put("mode", "gameMode");
PROPERTY_ALIASES.put("diff", "difficulty");
PROPERTY_ALIASES.put("spawnlocation", "spawn");
PROPERTY_ALIASES.put("limit", "playerLimit");
PROPERTY_ALIASES.put("animals", "spawning.animals.spawn");
PROPERTY_ALIASES.put("monsters", "spawning.monsters.spawn");
PROPERTY_ALIASES.put("animalsrate", "spawning.animals.spawnrate");
PROPERTY_ALIASES.put("monstersrate", "spawning.monsters.spawnrate");
PROPERTY_ALIASES.put("flight", "allowFlight");
PROPERTY_ALIASES.put("fly", "allowFlight");
PROPERTY_ALIASES.put("allowfly", "allowFlight");
}
public WorldProperties(Map<String, Object> values) {
super(values);
}
public WorldProperties() {
super();
}
public WorldProperties(final boolean fixSpawn, final Environment environment) {
super();
if (!fixSpawn) {
this.adjustSpawn = false;
}
setScaling(getDefaultScale(environment));
}
void setMVWorld(MVWorld world) {
registerObjectUsing(world);
registerGlobalValidator(new WorldPropertyValidator());
}
/**
* Serializor for the color-property.
*/
private static final class EnumPropertySerializor<T extends Enum<T>> implements Serializor<T, String> {
@Override
public String serialize(T from) {
return from.toString();
}
@Override
public T deserialize(String serialized, Class<T> wanted) throws IllegalPropertyValueException {
try {
return Enum.valueOf(wanted, serialized.toUpperCase());
} catch (IllegalArgumentException e) {
throw new IllegalPropertyValueException(e);
}
}
}
/**
* Serializor for the difficulty-property.
*/
private static final class DifficultyPropertySerializor implements Serializor<Difficulty, String> {
@Override
public String serialize(Difficulty from) {
return from.toString();
}
@Override
public Difficulty deserialize(String serialized, Class<Difficulty> wanted) throws IllegalPropertyValueException {
try {
return Difficulty.getByValue(Integer.parseInt(serialized));
} catch (Exception e) {
}
try {
return Difficulty.valueOf(serialized.toUpperCase());
} catch (Exception e) {
}
throw new IllegalPropertyValueException();
}
}
/**
* Serializor for the gameMode-property.
*/
private static final class GameModePropertySerializor implements Serializor<GameMode, String> {
@Override
public String serialize(GameMode from) {
return from.toString();
}
@Override
public GameMode deserialize(String serialized, Class<GameMode> wanted) throws IllegalPropertyValueException {
try {
return GameMode.getByValue(Integer.parseInt(serialized));
} catch (NumberFormatException nfe) {
}
try {
return GameMode.valueOf(serialized.toUpperCase());
} catch (Exception e) {
}
throw new IllegalPropertyValueException();
}
}
/**
* Serializor for the time-property.
*/
private static final class TimePropertySerializor implements Serializor<Long, String> {
// BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
private static final String TIME_REGEX = "(\\d\\d?):?(\\d\\d)(a|p)?m?";
private static final Map<String, String> TIME_ALIASES;
static {
Map<String, String> staticTimes = new HashMap<String, String>();
staticTimes.put("morning", "8:00");
staticTimes.put("day", "12:00");
staticTimes.put("noon", "12:00");
staticTimes.put("midnight", "0:00");
staticTimes.put("night", "20:00");
// now set TIME_ALIASES to a "frozen" map
TIME_ALIASES = Collections.unmodifiableMap(staticTimes);
}
@Override
public String serialize(Long from) {
// I'm tired, so they get time in 24 hour for now.
// Someone else can add 12 hr format if they want :P
int hours = (int) ((from / 1000 + 8) % 24);
int minutes = (int) (60 * (from % 1000) / 1000);
return String.format("%d:%02d", hours, minutes);
}
@Override
public Long deserialize(String serialized, Class<Long> wanted) throws IllegalPropertyValueException {
if (TIME_ALIASES.containsKey(serialized.toLowerCase())) {
serialized = TIME_ALIASES.get(serialized.toLowerCase());
}
// Regex that extracts a time in the following formats:
// 11:11pm, 11:11, 23:11, 1111, 1111p, and the aliases at the top of this file.
Pattern pattern = Pattern.compile(TIME_REGEX, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(serialized);
matcher.find();
int hour = 0;
double minute = 0;
int count = matcher.groupCount();
if (count >= 2) {
hour = Integer.parseInt(matcher.group(1));
minute = Integer.parseInt(matcher.group(2));
}
// If there were 4 matches (all, hour, min, am/pm)
if (count == 4) {
// We want 24 hour time for calcs, but if they
// added a p[m], turn it into a 24 hr one.
if (matcher.group(3).equals("p")) {
hour += 12;
}
}
// Translate 24th hour to 0th hour.
if (hour == 24) {
hour = 0;
}
// Clamp the hour
if (hour > 23 || hour < 0) {
throw new IllegalPropertyValueException("Illegal hour!");
}
// Clamp the minute
if (minute > 59 || minute < 0) {
throw new IllegalPropertyValueException("Illegal minute!");
}
// 60 seconds in a minute, time needs to be in hrs * 1000, per
// the bukkit docs.
double totaltime = (hour + (minute / 60.0)) * 1000;
// Somehow there's an 8 hour offset...
totaltime -= 8000;
if (totaltime < 0) {
totaltime = 24000 + totaltime;
}
return (long) totaltime;
}
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
}
// --------------------------------------------------------------
// Begin properties
@Property(description = "Sorry, 'hidden' must either be: true or false.")
private volatile boolean hidden;
@Property(description = "Alias must be a valid string.")
private volatile String alias;
@Property(serializor = EnumPropertySerializor.class, description = "Sorry, 'color' must be a valid color-name.")
private volatile EnglishChatColor color;
@Property(serializor = EnumPropertySerializor.class, description = "Sorry, 'style' must be a valid style-name.")
private volatile EnglishChatStyle style;
@Property(description = "Sorry, 'pvp' must either be: true or false.", virtualType = Boolean.class, persistVirtual = true)
volatile VirtualProperty<Boolean> pvp; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property(description = "Scale must be a positive double value. ex: 2.3")
private volatile double scale;
@Property(description = "You must set this to the NAME not alias of a world.")
private volatile String respawnWorld;
@Property(description = "Sorry, this must either be: true or false.")
private volatile boolean allowWeather;
@Property(serializor = DifficultyPropertySerializor.class, virtualType = Difficulty.class, persistVirtual = true,
description = "Difficulty must be set as one of the following: peaceful easy normal hard")
volatile VirtualProperty<Difficulty> difficulty; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property(description = "Sorry, 'animals' must either be: true or false.")
private volatile SpawnSettings spawning;
@Property
private volatile EntryFee entryfee;
@Property(description = "Sorry, 'hunger' must either be: true or false.")
private volatile boolean hunger;
@Property(description = "Sorry, 'autoheal' must either be: true or false.")
private volatile boolean autoHeal;
@Property(description = "Sorry, 'adjustspawn' must either be: true or false.")
private volatile boolean adjustSpawn;
@Property(serializor = EnumPropertySerializor.class, description = "Allow portal forming must be NONE, ALL, NETHER or END.")
private volatile AllowedPortalType portalForm;
@Property(serializor = GameModePropertySerializor.class, description = "GameMode must be set as one of the following: survival creative")
private volatile GameMode gameMode;
@Property(description = "Sorry, this must either be: true or false.", virtualType = Boolean.class, persistVirtual = true)
volatile VirtualProperty<Boolean> keepSpawnInMemory; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property
volatile SpawnLocation spawnLocation; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property(virtualType = Location.class,
description = "There is no help available for this variable. Go bug Rigby90 about it.")
volatile VirtualProperty<Location> spawn; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property(description = "Set this to false ONLY if you don't want this world to load itself on server restart.")
private volatile boolean autoLoad;
@Property(description = "If a player dies in this world, shoudld they go to their bed?")
private volatile boolean bedRespawn;
@Property
private volatile List<String> worldBlacklist;
@Property(serializor = TimePropertySerializor.class, virtualType = Long.class,
description = "Set the time to whatever you want! (Will NOT freeze time)")
volatile VirtualProperty<Long> time; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property
volatile Environment environment; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property
volatile long seed; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property
private volatile String generator;
@Property
private volatile int playerLimit;
@Property
private volatile boolean allowFlight;
// End of properties
// --------------------------------------------------------------
void setValidator(String fieldName, Validator validator) {
registerValidator(fieldName, validator); //To change body of overridden methods use File | Settings | File Templates.
}
/**
* {@inheritDoc}
*/
@Override
public void copyValues(SerializationConfig other) {
super.copyValues(other);
}
/**
* This prepares the MVWorld for unloading.
*/
public void cacheVirtualProperties() {
try {
this.buildVPropChanges();
} catch (IllegalStateException e) {
// do nothing
}
}
/**
* {@inheritDoc}
*/
@Override
protected void setDefaults() {
this.hidden = false;
this.alias = new String();
this.color = EnglishChatColor.WHITE;
this.style = EnglishChatStyle.NORMAL;
this.scale = 1D;
this.respawnWorld = new String();
this.allowWeather = true;
this.spawning = new SpawnSettings();
this.entryfee = new EntryFee();
this.hunger = true;
this.autoHeal = true;
this.adjustSpawn = true;
this.portalForm = AllowedPortalType.ALL;
this.gameMode = GameMode.SURVIVAL;
this.spawnLocation = new NullLocation();
this.autoLoad = true;
this.bedRespawn = true;
this.worldBlacklist = new ArrayList<String>();
this.generator = null;
this.playerLimit = -1;
this.allowFlight = true;
}
private static double getDefaultScale(Environment environment) {
if (environment == Environment.NETHER) {
return 8.0; // SUPPRESS CHECKSTYLE: MagicNumberCheck
} else if (environment == Environment.THE_END) {
return 16.0; // SUPPRESS CHECKSTYLE: MagicNumberCheck
}
return 1.0;
}
/**
* getAliases().
* @return The alias-map.
* @see SerializationConfig
*/
protected static Map<String, String> getAliases() {
return PROPERTY_ALIASES;
}
void flushChanges() {
this.flushPendingVPropChanges();
}
String getAlias() {
return this.alias;
}
public void setAlias(String alias) {
this.setPropertyValueUnchecked("alias", alias);
}
public Environment getEnvironment() {
return this.environment;
}
public void setEnvironment(Environment environment) {
this.setPropertyValueUnchecked("environment", environment);
}
public long getSeed() {
return this.seed;
}
public void setSeed(long seed) {
this.setPropertyValueUnchecked("seed", seed);
}
public String getGenerator() {
return this.generator;
}
public void setGenerator(String generator) {
this.setPropertyValueUnchecked("generator", generator);
}
public int getPlayerLimit() {
return this.playerLimit;
}
public void setPlayerLimit(int limit) {
this.setPropertyValueUnchecked("playerLimit", limit);
}
public boolean canAnimalsSpawn() {
return this.spawning.getAnimalSettings().doSpawn();
}
public void setAllowAnimalSpawn(boolean animals) {
this.setPropertyValueUnchecked("spawning.animals.spawn", animals);
}
public List<String> getAnimalList() {
// These don't fire events at the moment. Should they?
return this.spawning.getAnimalSettings().getExceptions();
}
public boolean canMonstersSpawn() {
return this.spawning.getMonsterSettings().doSpawn();
}
public void setAllowMonsterSpawn(boolean monsters) {
this.setPropertyValueUnchecked("spawning.monsters.spawn", monsters);
}
public int getAnimalSpawnRate() {
return this.spawning.getAnimalSettings().getSpawnRate();
}
public int getMonsterSpawnRate() {
return this.spawning.getMonsterSettings().getSpawnRate();
}
public List<String> getMonsterList() {
// These don't fire events at the moment. Should they?
return this.spawning.getMonsterSettings().getExceptions();
}
public boolean isPVPEnabled() {
return this.pvp.get();
}
public void setPVPMode(boolean pvp) {
this.setPropertyValueUnchecked("pvp", pvp);
}
public boolean isHidden() {
return this.hidden;
}
public void setHidden(boolean hidden) {
this.setPropertyValueUnchecked("hidden", hidden);
}
public List<String> getWorldBlacklist() {
return this.worldBlacklist;
}
public double getScaling() {
return this.scale;
}
public boolean setScaling(double scaling) {
return this.setPropertyValueUnchecked("scale", scaling);
}
public boolean setColor(String aliasColor) {
return this.setPropertyUnchecked("color", aliasColor);
}
public boolean setColor(EnglishChatColor color) {
return this.setPropertyValueUnchecked("color", color);
}
public EnglishChatColor getColor() {
return this.color;
}
public String getRespawnToWorld() {
return this.respawnWorld;
}
public boolean setRespawnToWorld(String respawnToWorld) {
return this.setPropertyValueUnchecked("respawnWorld", respawnToWorld);
}
public int getCurrency() {
return this.entryfee.getCurrency();
}
public void setCurrency(int currency) {
this.setPropertyValueUnchecked("entryfee.currency", currency);
}
public double getPrice() {
return this.entryfee.getAmount();
}
public void setPrice(double price) {
this.setPropertyValueUnchecked("entryfee.amount", price);
}
public boolean setGameMode(String mode) {
return this.setPropertyUnchecked("gameMode", mode);
}
public boolean setGameMode(GameMode mode) {
return this.setPropertyValueUnchecked("gameMode", mode);
}
public GameMode getGameMode() {
return this.gameMode;
}
public void setEnableWeather(boolean weather) {
this.setPropertyValueUnchecked("allowWeather", weather);
}
public boolean isWeatherEnabled() {
return this.allowWeather;
}
public boolean isKeepingSpawnInMemory() {
return this.keepSpawnInMemory.get();
}
public void setKeepSpawnInMemory(boolean value) {
this.setPropertyValueUnchecked("keepSpawnInMemory", value);
}
public boolean getHunger() {
return this.hunger;
}
public void setHunger(boolean hunger) {
this.setPropertyValueUnchecked("hunger", hunger);
}
public Location getSpawnLocation() {
return this.spawn.get();
}
public void setSpawnLocation(Location l) {
this.setPropertyValueUnchecked("spawn", l);
}
public Difficulty getDifficulty() {
return this.difficulty.get();
}
@Deprecated // SUPPRESS CHECKSTYLE: Deprecated
public boolean setDifficulty(String difficulty) {
return this.setPropertyUnchecked("difficulty", difficulty);
}
public boolean setDifficulty(Difficulty difficulty) {
return this.setPropertyValueUnchecked("difficulty", difficulty);
}
public boolean getAutoHeal() {
return this.autoHeal;
}
public void setAutoHeal(boolean heal) {
this.setPropertyValueUnchecked("autoHeal", heal);
}
public void setAdjustSpawn(boolean adjust) {
this.setPropertyValueUnchecked("adjustSpawn", adjust);
}
public boolean getAdjustSpawn() {
return this.adjustSpawn;
}
public void setAutoLoad(boolean load) {
this.setPropertyValueUnchecked("autoLoad", load);
}
public boolean getAutoLoad() {
return this.autoLoad;
}
public void setBedRespawn(boolean respawn) {
this.setPropertyValueUnchecked("bedRespawn", respawn);
}
public boolean getBedRespawn() {
return this.bedRespawn;
}
public String getAllPropertyNames() {
ChatColor myColor = ChatColor.AQUA;
StringBuilder result = new StringBuilder();
Map<String, Object> serialized = this.serialize();
for (String key : serialized.keySet()) {
result.append(myColor).append(key).append(' ');
myColor = (myColor == ChatColor.AQUA) ? ChatColor.GOLD : ChatColor.AQUA;
}
return result.toString();
}
public String getTime() {
return this.getPropertyUnchecked("time");
}
public boolean setTime(String timeAsString) {
return this.setPropertyUnchecked("time", timeAsString);
}
public AllowedPortalType getAllowedPortals() {
return portalForm;
}
public void allowPortalMaking(AllowedPortalType portalType) {
this.setPropertyValueUnchecked("portalForm", portalType);
}
public EnglishChatStyle getStyle() {
return style;
}
public boolean setStyle(String style) {
return this.setPropertyUnchecked("style", style);
}
public boolean getAllowFlight() {
return this.allowFlight;
}
public void setAllowFlight(final boolean allowFlight) {
this.setPropertyValueUnchecked("allowFlight", allowFlight);
}
}
@@ -9,7 +9,7 @@ package com.onarandombox.MultiverseCore.api;
import buscript.Buscript;
import com.fernferret.allpay.AllPay;
import com.fernferret.allpay.GenericBank;
import com.fernferret.allpay.commons.GenericBank;
import com.onarandombox.MultiverseCore.destination.DestinationFactory;
import com.onarandombox.MultiverseCore.utils.AnchorManager;
import com.onarandombox.MultiverseCore.utils.MVPermissions;
@@ -18,9 +18,7 @@ import com.onarandombox.MultiverseCore.utils.SimpleBlockSafety;
import com.onarandombox.MultiverseCore.utils.SimpleLocationManipulation;
import com.onarandombox.MultiverseCore.utils.SimpleSafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.VaultHandler;
import com.onarandombox.MultiverseCore.utils.WorldManager;
import com.pneumaticraft.commandhandler.CommandHandler;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
/**
@@ -30,15 +28,6 @@ import org.bukkit.entity.Player;
*/
public interface Core {
/**
* Gets the Multiverse config file.
*
* @return The Multiverse config file.
* @deprecated Don't modify the config-file manually!
*/
@Deprecated
FileConfiguration getMVConfiguration();
/**
* Gets the Banking system that Multiverse-Core has hooked into.
*
@@ -30,14 +30,14 @@ public interface MVPlugin extends LoggablePlugin {
/**
* Gets the reference to MultiverseCore.
*
* @return A valid {@link MultiverseCore}.
* @return A valid {@link com.onarandombox.MultiverseCore}.
*/
MultiverseCore getCore();
/**
* Sets the reference to MultiverseCore.
*
* @param core A valid {@link MultiverseCore}.
* @param core A valid {@link com.onarandombox.MultiverseCore}.
*/
void setCore(MultiverseCore core);
@@ -159,4 +159,32 @@ public interface MultiverseCoreConfig extends ConfigurationSerializable {
* @return true if we are suppressing startup messages.
*/
boolean getSilentStart();
/**
* Sets whether or not to let Bukkit determine portal search radius on its own or if Multiverse should give input.
*
* @param useDefaultPortalSearch True to let Bukkit determine portal search radius on its own.
*/
void setUseDefaultPortalSearch(boolean useDefaultPortalSearch);
/**
* Gets whether or not Bukkit will be determining portal search radius on its own or if Multiverse should help.
*
* @return True means Bukkit will use its own default values.
*/
boolean isUsingDefaultPortalSearch();
/**
* Sets the radius at which vanilla style portals will be searched for to connect to worlds together.
*
* @param searchRadius The portal search radius.
*/
void setPortalSearchRadius(int searchRadius);
/**
* Gets the radius at which vanilla style portals will be searched for to connect to worlds together.
*
* @return The portal search radius.
*/
int getPortalSearchRadius();
}
@@ -9,7 +9,6 @@ package com.onarandombox.MultiverseCore.api;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
import org.bukkit.ChatColor;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
@@ -620,11 +619,11 @@ public interface MultiverseWorld {
* @param autoLoad True if players dying in this world respawn at their bed.
*/
void setBedRespawn(boolean autoLoad);
/**
* Sets the player limit for this world after which players without an override
* permission node will not be allowed in. A value of -1 or less signifies no limit
*
*
* @param limit The new limit
*/
void setPlayerLimit(int limit);
@@ -632,7 +631,7 @@ public interface MultiverseWorld {
/**
* Gets the player limit for this world after which players without an override
* permission node will not be allowed in. A value of -1 or less signifies no limit
*
*
* @return The player limit
*/
int getPlayerLimit();
@@ -685,4 +684,18 @@ public interface MultiverseWorld {
* @return All property names, with alternating colors.
*/
String getAllPropertyNames();
/**
* Whether or not players are allowed to fly in this world.
*
* @return True if players allowed to fly in this world.
*/
boolean getAllowFlight();
/**
* Sets whether or not players are allowed to fly in this world.
*
* @param allowFlight True to allow flight in this world.
*/
void setAllowFlight(final boolean allowFlight);
}
@@ -0,0 +1,75 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2011. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionDefault;
import java.util.List;
/**
* Allows management of Anchor Destinations.
*/
public class GameruleCommand extends MultiverseCommand {
public GameruleCommand(MultiverseCore plugin) {
super(plugin);
this.setName("Set a Minecraft Game Rule for a World.");
this.setCommandUsage("/mv gamerule " + ChatColor.GREEN + "{RULE} {VALUE}" + ChatColor.GOLD + " [WORLD]");
this.setArgRange(2, 3);
this.addKey("mv gamerule");
this.addKey("mv rule");
this.addKey("mvgamerule");
this.addKey("mvrule");
this.addCommandExample("/mv gamerule " + ChatColor.GREEN + "doMobLoot false");
this.addCommandExample("/mvrule " + ChatColor.GREEN + "keepInventory true " + ChatColor.RED + "world_nether");
this.setPermission("multiverse.core.gamerule.set", "Allows a player to set a gamerule.", PermissionDefault.OP);
}
@Override
public void runCommand(CommandSender sender, List<String> args) {
// We NEED a world from the command line
final Player p;
if (sender instanceof Player) {
p = (Player) sender;
} else {
p = null;
}
if (args.size() == 2 && p == null) {
sender.sendMessage("From the command line, WORLD is required.");
sender.sendMessage(this.getCommandDesc());
sender.sendMessage(this.getCommandUsage());
sender.sendMessage("Nothing changed.");
return;
}
final String gameRule = args.get(0);
final String value = args.get(1);
final World world;
if (args.size() == 2) {
world = p.getWorld();
} else {
world = Bukkit.getWorld(args.get(2));
}
if (world.setGameRuleValue(gameRule, value)) {
sender.sendMessage(ChatColor.GREEN + "Success!" + ChatColor.WHITE + " Gamerule " + ChatColor.AQUA + gameRule
+ ChatColor.WHITE + " was set to " + ChatColor.GREEN + value);
} else {
sender.sendMessage(ChatColor.RED + "Failure!" + ChatColor.WHITE + " Gamerule " + ChatColor.AQUA + gameRule
+ ChatColor.WHITE + " cannot be set to " + ChatColor.RED + value);
}
}
}
@@ -0,0 +1,76 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2011. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionDefault;
import java.util.List;
/**
* Allows management of Anchor Destinations.
*/
public class GamerulesCommand extends MultiverseCommand {
public GamerulesCommand(MultiverseCore plugin) {
super(plugin);
this.setName("List the Minecraft Game Rules for a World.");
this.setCommandUsage("/mv gamerules" + ChatColor.GOLD + " [WORLD]");
this.setArgRange(0, 1);
this.addKey("mv gamerules");
this.addKey("mv rules");
this.addKey("mvgamerules");
this.addKey("mvrules");
this.addCommandExample("/mv gamerules");
this.addCommandExample("/mvrules " + ChatColor.RED + "world_nether");
this.setPermission("multiverse.core.gamerule.list", "Allows a player to list gamerules.", PermissionDefault.OP);
}
@Override
public void runCommand(CommandSender sender, List<String> args) {
// We NEED a world from the command line
final Player p;
if (sender instanceof Player) {
p = (Player) sender;
} else {
p = null;
}
if (args.size() == 0 && p == null) {
sender.sendMessage("From the command line, WORLD is required.");
sender.sendMessage(this.getCommandDesc());
sender.sendMessage(this.getCommandUsage());
sender.sendMessage("Nothing changed.");
return;
}
final World world;
if (args.size() == 0) {
world = p.getWorld();
} else {
world = Bukkit.getWorld(args.get(0));
}
final StringBuilder gameRules = new StringBuilder();
for (final String gameRule : world.getGameRules()) {
if (gameRules.length() != 0) {
gameRules.append(ChatColor.WHITE).append(", ");
}
gameRules.append(ChatColor.AQUA).append(gameRule).append(ChatColor.WHITE).append(": ");
gameRules.append(ChatColor.GREEN).append(world.getGameRuleValue(gameRule));
}
sender.sendMessage("=== Gamerules for " + ChatColor.AQUA + world.getName() + ChatColor.WHITE + " ===");
sender.sendMessage(gameRules.toString());
}
}
@@ -122,7 +122,8 @@ public class InfoCommand extends MultiverseCommand {
//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));
message.add(new FancyMessage("World Scale: ", world.getScaling() + "", colors));
message.add(new FancyMessage("World Scale: ", String.valueOf(world.getScaling()), colors));
message.add(new FancyMessage("World Seed: ", String.valueOf(world.getSeed()), colors));
if (world.getPrice() > 0) {
final String formattedAmount;
if (world.getCurrency() <= 0 && plugin.getVaultHandler().getEconomy() != null) {
@@ -64,6 +64,9 @@ public class SetSpawnCommand extends MultiverseCommand {
foundWorld.setAdjustSpawn(false);
}
sender.sendMessage("Spawn was set to: " + plugin.getLocationManipulation().strCoords(p.getLocation()));
if (!plugin.saveWorldConfig()) {
sender.sendMessage(ChatColor.RED + "There was an issue saving worlds.yml! Your changes will only be temporary!");
}
} else {
w.setSpawnLocation(l.getBlockX(), l.getBlockY(), l.getBlockZ());
sender.sendMessage("Multiverse does not know about this world, only X,Y and Z set. Please import it to set the spawn fully (Pitch/Yaws).");
@@ -0,0 +1,43 @@
package com.onarandombox.MultiverseCore.listeners;
import com.onarandombox.MultiverseCore.MultiverseCore;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.MapInitializeEvent;
import org.bukkit.map.MapView;
/**
* A listener for bukkit map events.
*/
public class MVMapListener implements Listener {
private final MultiverseCore plugin;
public MVMapListener(final MultiverseCore plugin) {
this.plugin = plugin;
}
/**
* This method is called when a map is initialized.
* @param event The event that was fired.
*/
@EventHandler
public void mapInitialize(final MapInitializeEvent event) {
for (final Player player : Bukkit.getOnlinePlayers()) {
if ((player.getItemInHand().getType() == Material.MAP
|| player.getItemInHand().getType() == Material.EMPTY_MAP)
&& player.getItemInHand().getDurability() == event.getMap().getId()) {
final Location playerLoc = player.getLocation();
final MapView map = event.getMap();
map.setCenterX(playerLoc.getBlockX());
map.setCenterZ(playerLoc.getBlockZ());
map.setWorld(playerLoc.getWorld());
return;
}
}
}
}
@@ -13,6 +13,7 @@ import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.event.MVRespawnEvent;
import com.onarandombox.MultiverseCore.utils.PermissionTools;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
@@ -125,7 +126,7 @@ public class MVPlayerListener implements Listener {
}
}
// Handle the Players GameMode setting for the new world.
this.handleGameMode(event.getPlayer(), event.getPlayer().getWorld());
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
playerWorld.put(p.getName(), p.getWorld().getName());
}
@@ -136,7 +137,7 @@ public class MVPlayerListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void playerChangedWorld(PlayerChangedWorldEvent event) {
// Permissions now determine whether or not to handle a gamemode.
this.handleGameMode(event.getPlayer(), event.getPlayer().getWorld());
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
playerWorld.put(event.getPlayer().getName(), event.getPlayer().getWorld().getName());
}
@@ -193,7 +194,7 @@ public class MVPlayerListener implements Listener {
+ "' don't have the FUNDS required to enter it.");
return;
}
// Check if player is allowed to enter the world if we're enforcing permissions
if (plugin.getMVConfig().getEnforceAccess()) {
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, teleporter, teleportee));
@@ -208,7 +209,7 @@ public class MVPlayerListener implements Listener {
this.plugin.log(Level.FINE, "Player '" + teleportee.getName()
+ "' was allowed to go to '" + toWorld.getAlias() + "' because enforceaccess is off.");
}
// Does a limit actually exist?
if (toWorld.getPlayerLimit() > -1) {
// Are there equal or more people on the world than the limit?
@@ -224,7 +225,7 @@ public class MVPlayerListener implements Listener {
}
}
}
// By this point anything cancelling the event has returned on the method, meaning the teleport is a success \o/
this.stateSuccess(teleportee.getName(), toWorld.getAlias());
}
@@ -299,6 +300,9 @@ public class MVPlayerListener implements Listener {
+ "' was allowed to go to '" + event.getTo().getWorld().getName()
+ "' because enforceaccess is off.");
}
if (!plugin.getMVConfig().isUsingDefaultPortalSearch() && event.getPortalTravelAgent() != null) {
event.getPortalTravelAgent().setSearchRadius(plugin.getMVConfig().getPortalSearchRadius());
}
}
private void sendPlayerToDefaultWorld(final Player player) {
@@ -313,13 +317,13 @@ public class MVPlayerListener implements Listener {
}
// FOLLOWING 2 Methods and Private class handle Per Player GameModes.
private void handleGameMode(Player player, World world) {
private void handleGameModeAndFlight(Player player, World world) {
MultiverseWorld mvWorld = this.worldManager.getMVWorld(world.getName());
if (mvWorld != null) {
this.handleGameMode(player, mvWorld);
this.handleGameModeAndFlight(player, mvWorld);
} else {
this.plugin.log(Level.FINER, "Not handling gamemode for world '" + world.getName()
this.plugin.log(Level.FINER, "Not handling gamemode and flight for world '" + world.getName()
+ "' not managed by Multiverse.");
}
}
@@ -329,28 +333,40 @@ public class MVPlayerListener implements Listener {
* @param player The {@link Player}.
* @param world The world the player is in.
*/
public void handleGameMode(final Player player, final MultiverseWorld world) {
public void handleGameModeAndFlight(final Player player, final MultiverseWorld world) {
// We perform this task one tick later to MAKE SURE that the player actually reaches the
// destination world, otherwise we'd be changing the player mode if they havent moved anywhere.
if (!this.pt.playerCanIgnoreGameModeRestriction(world, player)) {
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin,
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin,
new Runnable() {
@Override
public void run() {
// Check that the player is in the new world and they haven't been teleported elsewhere or the event cancelled.
if (player.getWorld() == world.getCBWorld()) {
Logging.fine("Handling gamemode for player: %s, Changing to %s", player.getName(), world.getGameMode().toString());
Logging.finest("From World: %s", player.getWorld());
Logging.finest("To World: %s", world);
player.setGameMode(world.getGameMode());
if (!MVPlayerListener.this.pt.playerCanIgnoreGameModeRestriction(world, player)) {
// Check that the player is in the new world and they haven't been teleported elsewhere or the event cancelled.
if (player.getWorld() == world.getCBWorld()) {
Logging.fine("Handling gamemode for player: %s, Changing to %s", player.getName(), world.getGameMode().toString());
Logging.finest("From World: %s", player.getWorld());
Logging.finest("To World: %s", world);
player.setGameMode(world.getGameMode());
// Check if their flight mode should change
// TODO need a override permission for this
if (player.getAllowFlight() && !world.getAllowFlight() && player.getGameMode() != GameMode.CREATIVE) {
player.setAllowFlight(false);
if (player.isFlying()) {
player.setFlying(false);
}
} else if (world.getAllowFlight()) {
if (player.getGameMode() == GameMode.CREATIVE) {
player.setAllowFlight(true);
}
}
} else {
Logging.fine("The gamemode/allowfly was NOT changed for player '%s' because he is now in world '%s' instead of world '%s'",
player.getName(), player.getWorld().getName(), world.getName());
}
} else {
Logging.fine("The gamemode was NOT changed for player '%s' because he is now in world '%s' instead of world '%s'",
player.getName(), player.getWorld().getName(), world.getName());
MVPlayerListener.this.plugin.log(Level.FINE, "Player: " + player.getName() + " is IMMUNE to gamemode changes!");
}
}
}, 1L);
} else {
this.plugin.log(Level.FINE, "Player: " + player.getName() + " is IMMUNE to gamemode changes!");
}
}
}
@@ -0,0 +1,52 @@
package com.onarandombox.MultiverseCore.permissions;
import org.bukkit.Bukkit;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.PermissionDefault;
/**
* Provides improved parent-child relationships for permissions. This is the standard implementation of {@link PermissionNode}.
* <p>
* Apparently parents override their children in Bukkit:
* Let {@code permissionA} be a parent permission of {@code permissionB}, setting {@code permissionB} to {@code true}.
* Now a player has {@code permissionA=true} and {@code permissionB=false}. Result: Both are {@code true}.
* Another player has {@code permissionA=false} and {@code permissionB=true}. Result: Both are {@code false}.
* <p>
* This is completely useless for things like MV's world access permissions where you could for example want to deny
* access to all worlds by default, with a few exceptions.
* <p>
* This class takes over all the permission hierarchy checks and provides a way that makes sense. In the
* above examples, the effective permissions would be equal to the permissions that were set.
*/
public class HierarchyPermission implements PermissionNode {
private final PermissionNode parent;
private final Permission permission;
public HierarchyPermission(final PermissionNode parent, final String permission, final String description) {
this.parent = parent;
Permission p = Bukkit.getServer().getPluginManager().getPermission(permission);
if (p == null)
p = new Permission(permission, description, PermissionDefault.FALSE);
else {
p.getChildren().clear();
//p.recalculatePermissibles(); // Not necessary because it's done automatically after setting the default
p.setDefault(PermissionDefault.FALSE);
}
this.permission = p;
}
/**
* Checks whether a given {@link Permissible} has this {@link HierarchyPermission}.
*
* @param permissible The {@link Permissible} that might have the permission.
* @return Whether it has the permission.
*/
public boolean has(Permissible permissible) {
if (permissible.isPermissionSet(permission))
return permissible.hasPermission(permission);
// ask the guy over there
return parent.has(permissible);
}
}
@@ -0,0 +1,38 @@
package com.onarandombox.MultiverseCore.permissions;
import org.bukkit.permissions.Permissible;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a permission node with dynamically created children.
*/
public class PermissionCollection {
private final PermissionNode root;
private final Map<String, PermissionNode> elements;
private final String prefix;
private final String description;
public PermissionCollection(PermissionNode parent, String prefix, String description) {
if (!prefix.endsWith("."))
throw new IllegalArgumentException("The prefix must end with a dot!");
this.root = new HierarchyPermission(parent, prefix + "*", description);
this.elements = new HashMap<String, PermissionNode>();
this.prefix = prefix;
this.description = description;
}
/**
* Checks whether a given {@link Permissible} has a specified element permission.
*
* @param p The {@link Permissible}.
* @param element The element.
* @return Whether the {@link Permissible} has the permission.
*/
public boolean has(Permissible p, String element) {
if (!this.elements.containsKey(element))
this.elements.put(element, new HierarchyPermission(root, prefix + element, description));
return this.elements.get(element).has(p);
}
}
@@ -0,0 +1,30 @@
package com.onarandombox.MultiverseCore.permissions;
import org.bukkit.permissions.Permissible;
/**
* A node in a permissions hierarchy.
*
* @see HierarchyPermission
*/
public interface PermissionNode {
static final class OperatorDefault implements PermissionNode {
@Override
public boolean has(final Permissible permissible) {
return permissible.isOp();
}
}
/**
* This {@link HierarchyPermission} depends on the operator state. Ops have it, non-ops don't.
*/
PermissionNode OP_DEFAULT = new OperatorDefault();
/**
* Checks whether a given {@link Permissible} has this node.
*
* @param permissible The {@link Permissible} that might have the permission.
* @return Whether it has the permission.
*/
boolean has(Permissible permissible);
}
@@ -0,0 +1,21 @@
package com.onarandombox.MultiverseCore.permissions;
/**
* Permission nodes.
*/
public class Permissions {
protected Permissions() {
throw new UnsupportedOperationException();
}
/**
* The {@code multiverse.*} permission.
*/
public static final HierarchyPermission MV_ROOT = new HierarchyPermission(PermissionNode.OP_DEFAULT,
"multiverse.*", "Provides access to all Multiverse features.");
/**
* The {@code multiverse.access.*} family of permissions.
*/
public static final PermissionCollection ACCESS = new PermissionCollection(MV_ROOT, "multiverse.access.", "World access");
}
@@ -0,0 +1,4 @@
/**
* Contains permissions utility classes.
*/
package com.onarandombox.MultiverseCore.permissions;
@@ -73,28 +73,28 @@ public class BlockSafety {
if (this.isSolidBlock(world.getBlockAt(actual).getType())
|| this.isSolidBlock(upOne.getBlock().getType())) {
Logging.finer("Error Here (Actual)? (%s)[%s]", actual.getBlock().getType(),
Logging.finest("Error Here (Actual)? (%s)[%s]", actual.getBlock().getType(),
this.isSolidBlock(actual.getBlock().getType()));
Logging.finer("Error Here (upOne)? (%s)[%s]", upOne.getBlock().getType(),
Logging.finest("Error Here (upOne)? (%s)[%s]", upOne.getBlock().getType(),
this.isSolidBlock(upOne.getBlock().getType()));
return false;
}
if (downOne.getBlock().getType() == Material.LAVA || downOne.getBlock().getType() == Material.STATIONARY_LAVA) {
Logging.finer("Error Here (downOne)? (%s)[%s]", downOne.getBlock().getType(),
Logging.finest("Error Here (downOne)? (%s)[%s]", downOne.getBlock().getType(),
this.isSolidBlock(downOne.getBlock().getType()));
return false;
}
if (downOne.getBlock().getType() == Material.FIRE) {
Logging.finer("There's fire below! (%s)[%s]", actual.getBlock().getType(),
Logging.finest("There's fire below! (%s)[%s]", actual.getBlock().getType(),
this.isSolidBlock(actual.getBlock().getType()));
return false;
}
if (isBlockAboveAir(actual)) {
Logging.finer("Is block above air [%s]", isBlockAboveAir(actual));
Logging.finer("Has 2 blocks of water below [%s]", this.hasTwoBlocksofWaterBelow(actual));
Logging.finest("Is block above air [%s]", isBlockAboveAir(actual));
Logging.finest("Has 2 blocks of water below [%s]", this.hasTwoBlocksofWaterBelow(actual));
return this.hasTwoBlocksofWaterBelow(actual);
}
return true;
@@ -7,13 +7,10 @@
package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.util.Logging;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Logger;
/**
@@ -31,16 +28,11 @@ public class FileUtils {
* @return true if the folder was successfully deleted.
*/
public static boolean deleteFolder(File file) {
if (file.exists()) {
boolean ret = true;
// If the file exists, and it has more than one file in it.
if (file.isDirectory()) {
for (File f : file.listFiles()) {
ret = ret && deleteFolder(f);
}
}
return ret && file.delete();
} else {
try {
org.apache.commons.io.FileUtils.deleteDirectory(file);
return true;
} catch (IOException e) {
Logging.warning(e.getMessage());
return false;
}
}
@@ -52,16 +44,11 @@ public class FileUtils {
* @return true if the contents were successfully deleted
*/
public static boolean deleteFolderContents(File file) {
if (file.exists()) {
boolean ret = true;
// If the file exists, and it has more than one file in it.
if (file.isDirectory()) {
for (File f : file.listFiles()) {
ret = ret && deleteFolder(f);
}
}
return ret;
} else {
try {
org.apache.commons.io.FileUtils.cleanDirectory(file);
return true;
} catch (IOException e) {
Logging.warning(e.getMessage());
return false;
}
}
@@ -77,46 +64,12 @@ public class FileUtils {
* @return if it had success
*/
public static boolean copyFolder(File source, File target, Logger log) {
InputStream in = null;
OutputStream out = null;
try {
if (source.isDirectory()) {
if (!target.exists())
target.mkdir();
String[] children = source.list();
// for (int i=0; i<children.length; i++) {
for (String child : children) {
copyFolder(new File(source, child), new File(target, child), log);
}
} else {
in = new FileInputStream(source);
out = new FileOutputStream(target);
byte[] buf = new byte[COPY_BLOCK_SIZE];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
org.apache.commons.io.FileUtils.copyDirectory(source, target);
return true;
} catch (FileNotFoundException e) {
log.warning("Exception while copying file: " + e.getMessage());
} catch (IOException e) {
log.warning("Exception while copying file: " + e.getMessage());
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignore) { }
}
if (out != null) {
try {
out.close();
} catch (IOException ignore) { }
}
log.warning(e.getMessage());
return false;
}
return false;
}
}
@@ -11,6 +11,7 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.permissions.Permissions;
import com.pneumaticraft.commandhandler.PermissionsInterface;
import org.bukkit.ChatColor;
import org.bukkit.Location;
@@ -103,18 +104,15 @@ public class MVPermissions implements PermissionsInterface {
this.plugin.log(Level.FINEST, "EnforceAccess is OFF. Player was allowed in " + w.getAlias());
return true;
}
return this.hasPermission(p, "multiverse.access." + w.getName(), false);
return Permissions.ACCESS.has(p, w.getName());
}
private boolean canEnterLocation(Player p, Location l) {
if (l == null) {
if (l == null)
return false;
}
String worldName = l.getWorld().getName();
if (!this.plugin.getMVWorldManager().isMVWorld(worldName)) {
return false;
}
return this.hasPermission(p, "multiverse.access." + worldName, false);
return this.plugin.getMVWorldManager().isMVWorld(worldName) && Permissions.ACCESS.has(p, worldName);
}
/**
@@ -7,7 +7,7 @@
package com.onarandombox.MultiverseCore.utils;
import com.fernferret.allpay.GenericBank;
import com.fernferret.allpay.commons.GenericBank;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import org.bukkit.command.CommandSender;
@@ -257,17 +257,24 @@ public class PermissionTools {
}
return true;
}
/**
* Checks to see if a player can bypass the player limit.
*
* @param toWorld The world travelling to.
* @param teleporter The player that initiated the teleport.
* @param teleportee The player travelling.
* @return True if they can bypass the player limit.
*/
public boolean playerCanBypassPlayerLimit(MultiverseWorld toWorld, CommandSender teleporter, Player teleportee) {
if (teleporter == null) {
teleporter = teleportee;
}
if (!(teleporter instanceof Player)) {
return true;
return true;
}
MVPermissions perms = plugin.getMVPerms();
if (perms.hasPermission(teleportee, "mv.bypass.playerlimit." + toWorld.getName(), false)) {
return true;
@@ -7,10 +7,10 @@
package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Animals;
@@ -18,13 +18,15 @@ import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Ghast;
import org.bukkit.entity.Golem;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Squid;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
/**
* Utility class that removes animals from worlds that don't belong there.
@@ -33,8 +35,16 @@ public class SimpleWorldPurger implements WorldPurger {
private MultiverseCore plugin;
private Class<Entity> ambientClass = null;
public SimpleWorldPurger(MultiverseCore plugin) {
this.plugin = plugin;
try {
Class entityClass = Class.forName("org.bukkit.entity.Ambient");
if (Entity.class.isAssignableFrom(entityClass)) {
ambientClass = entityClass;
}
} catch (ClassNotFoundException ignore) { }
}
/**
@@ -86,18 +96,41 @@ public class SimpleWorldPurger implements WorldPurger {
if (world == null) {
return;
}
int projectilesKilled = 0;
int entitiesKilled = 0;
boolean specifiedAll = thingsToKill.contains("ALL");
boolean specifiedAnimals = thingsToKill.contains("ANIMALS") || specifiedAll;
boolean specifiedMonsters = thingsToKill.contains("MONSTERS") || specifiedAll;
for (Entity e : world.getEntities()) {
List<Entity> worldEntities = world.getEntities();
List<LivingEntity> livingEntities = new ArrayList<LivingEntity>(worldEntities.size());
List<Projectile> projectiles = new ArrayList<Projectile>(worldEntities.size());
for (final Entity e : worldEntities) {
if (e instanceof Projectile) {
final Projectile p = (Projectile) e;
if (p.getShooter() != null) {
projectiles.add((Projectile) e);
}
} else if (e instanceof LivingEntity) {
livingEntities.add((LivingEntity) e);
}
}
for (final LivingEntity e : livingEntities) {
if (killDecision(e, thingsToKill, negateAnimals, negateMonsters, specifiedAnimals, specifiedMonsters)) {
final Iterator<Projectile> it = projectiles.iterator();
while (it.hasNext()) {
final Projectile p = it.next();
if (p.getShooter().equals(e)) {
p.remove();
it.remove();
projectilesKilled++;
}
}
e.remove();
entitiesKilled++;
}
}
if (sender != null) {
sender.sendMessage(entitiesKilled + " entities purged from the world '" + world.getName() + "'");
sender.sendMessage(entitiesKilled + " entities purged from the world '" + world.getName() + "' along with " + projectilesKilled + " projectiles that belonged to them.");
}
}
@@ -105,10 +138,11 @@ public class SimpleWorldPurger implements WorldPurger {
boolean negateMonsters, boolean specifiedAnimals, boolean specifiedMonsters) {
boolean negate = false;
boolean specified = false;
if (e instanceof Golem || e instanceof Squid || e instanceof Animals) {
if (e instanceof Golem || e instanceof Squid || e instanceof Animals
|| (ambientClass != null && ambientClass.isInstance(e))) {
// it's an animal
if (specifiedAnimals && !negateAnimals) {
this.plugin.log(Level.FINEST, "Removing an entity because I was told to remove all animals: " + e);
Logging.finest("Removing an entity because I was told to remove all animals in world %s: %s", e.getWorld().getName(), e);
return true;
}
if (specifiedAnimals)
@@ -117,7 +151,7 @@ public class SimpleWorldPurger implements WorldPurger {
} else if (e instanceof Monster || e instanceof Ghast || e instanceof Slime) {
// it's a monster
if (specifiedMonsters && !negateMonsters) {
this.plugin.log(Level.FINEST, "Removing an entity because I was told to remove all monsters: " + e);
Logging.finest("Removing an entity because I was told to remove all monsters in world %s: %s", e.getWorld().getName(), e);
return true;
}
if (specifiedMonsters)
@@ -129,14 +163,14 @@ public class SimpleWorldPurger implements WorldPurger {
if (type != null && type.equals(e.getType())) {
specified = true;
if (!negate) {
this.plugin.log(Level.FINEST, "Removing an entity because it WAS specified and we are NOT negating: " + e);
Logging.finest("Removing an entity because it WAS specified and we are NOT negating in world %s: %s", e.getWorld().getName(), e);
return true;
}
break;
}
}
if (!specified && negate) {
this.plugin.log(Level.FINEST, "Removing an entity because it was NOT specified and we ARE negating: " + e);
Logging.finest("Removing an entity because it was NOT specified and we ARE negating in world %s: %s", e.getWorld().getName(), e);
return true;
}
@@ -0,0 +1,44 @@
package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.api.Core;
import java.util.concurrent.Callable;
/**
* Wraps calls that could result in exceptions that are not Multiverse's fault.
*/
public class UnsafeCallWrapper {
private final Core core;
public UnsafeCallWrapper(Core core) {
this.core = core;
}
/**
* Wraps calls that could result in exceptions that are not Multiverse's fault.
*
* @param callable The potentially unsafe call.
* @param plugin The plugin that's probably the culprit.
* @param action What MV was attempting to do (error message, format string).
* @param formatArgs The formatting arguments for the error message.
* The exception that was thrown will be appended to these objects.
* @param <T> The type of the return value.
* @return The return value or null if the call failed.
*/
public <T> T wrap(Callable<T> callable, String plugin, String action, Object... formatArgs) {
try {
// We're ready to catch you! JUMP!
return callable.call();
} catch (Throwable t) {
Object[] actualFormatArgs = new Object[formatArgs.length + 1];
System.arraycopy(formatArgs, 0, actualFormatArgs, 0, formatArgs.length);
actualFormatArgs[formatArgs.length] = t;
Logging.warning(action, actualFormatArgs);
Logging.warning("This is a bug in %s, NOT a bug in Multiverse!", plugin);
if (core.getMVConfig().getGlobalDebug() >= 1)
t.printStackTrace();
return null;
}
}
}
@@ -24,8 +24,8 @@ public class VaultHandler implements Listener {
private boolean setupVaultEconomy() {
if (Bukkit.getPluginManager().getPlugin("Vault") != null) {
final RegisteredServiceProvider<Economy> economyProvider
= Bukkit.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
final RegisteredServiceProvider<Economy> economyProvider =
Bukkit.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
if (economyProvider != null) {
Logging.fine("Vault economy enabled.");
economy = economyProvider.getProvider();
@@ -41,6 +41,9 @@ public class VaultHandler implements Listener {
return (economy != null);
}
/**
* Listens for Vault plugin events.
*/
private class VaultListener implements Listener {
@EventHandler
private void vaultEnabled(PluginEnableEvent event) {
@@ -10,6 +10,7 @@ package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.MVWorld;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.WorldProperties;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
@@ -41,6 +42,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -52,14 +54,14 @@ public class WorldManager implements MVWorldManager {
private final MultiverseCore plugin;
private final WorldPurger worldPurger;
private final Map<String, MultiverseWorld> worlds;
private Map<String, MVWorld> worldsFromTheConfig;
private Map<String, WorldProperties> worldsFromTheConfig;
private FileConfiguration configWorlds = null;
private Map<String, String> defaultGens;
private String firstSpawn;
public WorldManager(MultiverseCore core) {
this.plugin = core;
this.worldsFromTheConfig = new HashMap<String, MVWorld>();
this.worldsFromTheConfig = new HashMap<String, WorldProperties>();
this.worlds = new ConcurrentHashMap<String, MultiverseWorld>();
this.worldPurger = new SimpleWorldPurger(plugin);
}
@@ -207,8 +209,10 @@ public class WorldManager implements MVWorldManager {
}
// Important: doLoad() needs the MVWorld-object in worldsFromTheConfig
if (!worldsFromTheConfig.containsKey(name))
worldsFromTheConfig.put(name, new MVWorld(useSpawnAdjust));
if (!worldsFromTheConfig.containsKey(name)) {
WorldProperties props = new WorldProperties(useSpawnAdjust, env);
worldsFromTheConfig.put(name, props);
}
StringBuilder builder = new StringBuilder();
builder.append("Loading World & Settings - '").append(name).append("'");
@@ -238,16 +242,21 @@ public class WorldManager implements MVWorldManager {
* {@inheritDoc}
*/
@Override
public ChunkGenerator getChunkGenerator(String generator, String generatorID, String worldName) {
public ChunkGenerator getChunkGenerator(String generator, final String generatorID, final String worldName) {
if (generator == null) {
return null;
}
Plugin myPlugin = this.plugin.getServer().getPluginManager().getPlugin(generator);
final Plugin myPlugin = this.plugin.getServer().getPluginManager().getPlugin(generator);
if (myPlugin == null) {
return null;
} else {
return myPlugin.getDefaultWorldGenerator(worldName, generatorID);
return plugin.getUnsafeCallWrapper().wrap(new Callable<ChunkGenerator>() {
@Override
public ChunkGenerator call() throws Exception {
return myPlugin.getDefaultWorldGenerator(worldName, generatorID);
}
}, myPlugin.getName(), "Failed to get the default chunk generator: %s");
}
}
@@ -308,12 +317,10 @@ public class WorldManager implements MVWorldManager {
@Override
public boolean unloadWorld(String name) {
if (this.worlds.containsKey(name)) {
this.worldsFromTheConfig.get(name).cacheVirtualProperties();
if (this.unloadWorldFromBukkit(name, true)) {
this.worlds.remove(name);
Logging.info("World '%s' was unloaded from memory.", name);
this.worldsFromTheConfig.get(name).tearDown();
return true;
} else {
Logging.warning("World '%s' could not be unloaded. Is it a default world?", name);
@@ -355,21 +362,32 @@ public class WorldManager implements MVWorldManager {
}
private boolean doLoad(String name) {
return doLoad(name, false);
return doLoad(name, false, null);
}
private boolean doLoad(String name, boolean ignoreExists) {
private boolean doLoad(String name, boolean ignoreExists, WorldType type) {
if (!worldsFromTheConfig.containsKey(name))
throw new IllegalArgumentException("That world doesn't exist!");
MVWorld world = worldsFromTheConfig.get(name);
WorldCreator creator = WorldCreator.name(name);
final WorldProperties world = worldsFromTheConfig.get(name);
final WorldCreator creator = WorldCreator.name(name);
creator.environment(world.getEnvironment()).seed(world.getSeed());
if ((world.getGenerator() != null) && (!world.getGenerator().equals("null")))
creator.generator(world.getGenerator());
if (type != null) {
creator.type(type);
}
return doLoad(creator, ignoreExists);
boolean generatorSuccess = true;
if ((world.getGenerator() != null) && (!world.getGenerator().equals("null")))
generatorSuccess = null != plugin.getUnsafeCallWrapper().wrap(new Callable<Object>() {
@Override
public Object call() throws Exception {
creator.generator(world.getGenerator());
return new Object();
}
}, "the generator plugin", "Failed to set the generator for world '%s' to '%s': %s", name, world.getGenerator());
return generatorSuccess && doLoad(creator, ignoreExists);
}
private boolean doLoad(WorldCreator creator, boolean ignoreExists) {
@@ -385,7 +403,7 @@ public class WorldManager implements MVWorldManager {
return false;
}
MVWorld mvworld = worldsFromTheConfig.get(worldName);
WorldProperties mvworld = worldsFromTheConfig.get(worldName);
World cbworld;
try {
cbworld = creator.createWorld();
@@ -394,9 +412,9 @@ public class WorldManager implements MVWorldManager {
brokenWorld(worldName);
return false;
}
mvworld.init(cbworld, plugin);
this.worldPurger.purgeWorld(mvworld);
this.worlds.put(worldName, mvworld);
MVWorld world = new MVWorld(plugin, cbworld, mvworld);
this.worldPurger.purgeWorld(world);
this.worlds.put(worldName, world);
return true;
}
@@ -636,7 +654,7 @@ public class WorldManager implements MVWorldManager {
this.worlds.clear();
}
for (Map.Entry<String, MVWorld> entry : worldsFromTheConfig.entrySet()) {
for (Map.Entry<String, WorldProperties> entry : worldsFromTheConfig.entrySet()) {
if (worlds.containsKey(entry.getKey())) {
continue;
}
@@ -696,31 +714,23 @@ public class WorldManager implements MVWorldManager {
// load world-objects
Stack<String> worldKeys = new Stack<String>();
worldKeys.addAll(this.configWorlds.getConfigurationSection("worlds").getKeys(false));
Map<String, MVWorld> newWorldsFromTheConfig = new HashMap<String, MVWorld>();
Map<String, WorldProperties> newWorldsFromTheConfig = new HashMap<String, WorldProperties>();
while (!worldKeys.isEmpty()) {
String key = worldKeys.pop();
String path = "worlds" + SEPARATOR + key;
Object obj = this.configWorlds.get(path);
if ((obj != null) && (obj instanceof MVWorld)) {
if ((obj != null) && (obj instanceof WorldProperties)) {
String worldName = key.replaceAll(String.valueOf(SEPARATOR), ".");
MVWorld mvWorld = null;
WorldProperties props = (WorldProperties) obj;
if (this.worldsFromTheConfig.containsKey(worldName)) {
// Object-Recycling :D
// TODO Why is is checking worldsFromTheConfig and then getting from worlds? So confused... (DTM)
mvWorld = (MVWorld) this.worlds.get(worldName);
MVWorld mvWorld = (MVWorld) this.worlds.get(worldName);
if (mvWorld != null) {
mvWorld.copyValues((MVWorld) obj);
mvWorld.copyValues((WorldProperties) obj);
}
}
if (mvWorld == null) {
// we have to use a new one
World cbworld = this.plugin.getServer().getWorld(worldName);
mvWorld = (MVWorld) obj;
if (cbworld != null) {
mvWorld.init(cbworld, this.plugin);
}
}
newWorldsFromTheConfig.put(worldName, mvWorld);
newWorldsFromTheConfig.put(worldName, props);
} else if (this.configWorlds.isConfigurationSection(path)) {
ConfigurationSection section = this.configWorlds.getConfigurationSection(path);
Set<String> subkeys = section.getKeys(false);
@@ -742,7 +752,7 @@ public class WorldManager implements MVWorldManager {
try {
this.configWorlds.options().pathSeparator(SEPARATOR);
this.configWorlds.set("worlds", null);
for (Map.Entry<String, ? extends MultiverseWorld> entry : worldsFromTheConfig.entrySet()) {
for (Map.Entry<String, WorldProperties> entry : worldsFromTheConfig.entrySet()) {
this.configWorlds.set("worlds" + SEPARATOR + entry.getKey(), entry.getValue());
}
this.configWorlds.save(new File(this.plugin.getDataFolder(), "worlds.yml"));
@@ -797,9 +807,10 @@ public class WorldManager implements MVWorldManager {
world.setSeed(theSeed);
}
WorldType type = world.getWorldType();
if (this.deleteWorld(name, false, false)) {
this.doLoad(name, true);
this.doLoad(name, true, type);
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
Location newSpawn = world.getSpawnLocation();
// Send all players that were in the old world, BACK to it!
+17
View File
@@ -215,3 +215,20 @@ commands:
description: Reduces startup messages
usage: |
/<command> [true|false]
mvgamerule:
description: Sets a gamerule.
usage: |
/<command> {RULE} {VALUE} [WORLD]
mvrule:
description: Sets a gamerule.
usage: |
/<command> {RULE} {VALUE} [WORLD]
mvgamerules:
description: Lists the gamerules.
usage: |
/<command> [WORLD]
mvrules:
description: Lists the gamerules.
usage: |
/<command> [WORLD]
@@ -5,17 +5,11 @@
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.File;
package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.api.Core;
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
import junit.framework.Assert;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@@ -28,9 +22,12 @@ import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.Core;
import com.onarandombox.MultiverseCore.test.utils.TestInstanceCreator;
import java.io.File;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ MultiverseCore.class, PluginDescriptionFile.class })
@@ -1,13 +1,9 @@
package com.onarandombox.MultiverseCore.test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.listeners.MVEntityListener;
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@@ -24,11 +20,13 @@ import org.junit.runner.RunWith;
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.listeners.MVEntityListener;
import com.onarandombox.MultiverseCore.test.utils.TestInstanceCreator;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ MultiverseCore.class, PluginDescriptionFile.class })
@@ -1,8 +1,7 @@
package com.onarandombox.MultiverseCore.test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
import org.bukkit.Server;
import org.bukkit.World.Environment;
import org.bukkit.command.Command;
@@ -15,9 +14,9 @@ import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.test.utils.TestInstanceCreator;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(PowerMockRunner.class)
@@ -5,21 +5,20 @@
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.test;
package com.onarandombox.MultiverseCore;
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.configuration.SpawnLocation;
import com.onarandombox.MultiverseCore.listeners.MVAsyncPlayerChatListener;
import com.onarandombox.MultiverseCore.test.utils.TestInstanceCreator;
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
import com.onarandombox.MultiverseCore.utils.WorldManager;
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.configuration.file.FileConfiguration;
@@ -299,7 +298,7 @@ public class TestWorldProperties {
assertTrue(core.saveMVConfigs());
// change a value here
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(core.getDataFolder(), "worlds.yml"));
MVWorld worldObj = (MVWorld) config.get("worlds.world");
WorldProperties worldObj = (WorldProperties) config.get("worlds.world");
assertTrue(worldObj.setColor("GREEN"));
config.set("worlds.world", worldObj);
config.save(new File(core.getDataFolder(), "worlds.yml"));
@@ -332,17 +331,18 @@ public class TestWorldProperties {
}
public void createEvents(MultiverseWorld mvWorld) {
final World world = mvWorld.getCBWorld();
//// Weather events
// weather change
weatherChangeOffEvent = new WeatherChangeEvent(mvWorld.getCBWorld(), false);
weatherChangeOnEvent = new WeatherChangeEvent(mvWorld.getCBWorld(), true);
weatherChangeOffEvent = new WeatherChangeEvent(world, false);
weatherChangeOnEvent = new WeatherChangeEvent(world, true);
// thunder change
thunderChangeOffEvent = new ThunderChangeEvent(mvWorld.getCBWorld(), false);
thunderChangeOnEvent = new ThunderChangeEvent(mvWorld.getCBWorld(), true);
thunderChangeOffEvent = new ThunderChangeEvent(world, false);
thunderChangeOnEvent = new ThunderChangeEvent(world, true);
//// Player events
// player chat
mockPlayer = mock(Player.class);
when(mockPlayer.getWorld()).thenReturn(mvWorld.getCBWorld());
when(mockPlayer.getWorld()).thenReturn(world);
when(mockPlayer.hasPlayedBefore()).thenReturn(true);
when(mockPlayer.hasPermission("multiverse.access.world")).thenReturn(true);
when(mockPlayer.getName()).thenReturn("MultiverseMan");
@@ -368,7 +368,7 @@ public class TestWorldProperties {
// entity regain health
entityRegainHealthEvent = PowerMockito.mock(EntityRegainHealthEvent.class);
when(entityRegainHealthEvent.getRegainReason()).thenReturn(RegainReason.REGEN);
when(mockHumanEntity.getLocation()).thenReturn(new Location(mvWorld.getCBWorld(), 0, 0, 0));
when(mockHumanEntity.getLocation()).thenReturn(new Location(world, 0, 0, 0));
when(entityRegainHealthEvent.getEntity()).thenReturn(mockHumanEntity);
// entity food level change event
entityFoodLevelChangeEvent = PowerMockito.mock(FoodLevelChangeEvent.class);
@@ -1,10 +1,8 @@
package com.onarandombox.MultiverseCore.test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.util.Arrays;
package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@@ -18,10 +16,10 @@ import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import com.onarandombox.MultiverseCore.test.utils.TestInstanceCreator;
import java.util.Arrays;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ MultiverseCore.class, PluginDescriptionFile.class })
@@ -113,10 +111,13 @@ public class TestWorldPurger {
}
private void createAnimals() {
World world = mvWorld.getCBWorld();
sheep = mock(Sheep.class);
when(sheep.getType()).thenReturn(EntityType.SHEEP);
when(sheep.getWorld()).thenReturn(world);
zombie = mock(Zombie.class);
when(zombie.getType()).thenReturn(EntityType.ZOMBIE);
when(zombie.getWorld()).thenReturn(world);
when(cbworld.getEntities()).thenReturn(Arrays.asList((Entity) sheep, (Entity) zombie));
}
}
@@ -5,15 +5,18 @@
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.test;
package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
import com.onarandombox.MultiverseCore.test.utils.TestInstanceCreator;
import com.onarandombox.MultiverseCore.test.utils.WorldCreatorMatcher;
import com.onarandombox.MultiverseCore.utils.TestInstanceCreator;
import com.onarandombox.MultiverseCore.utils.WorldCreatorMatcher;
import com.onarandombox.MultiverseCore.utils.WorldManager;
import org.bukkit.*;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Server;
import org.bukkit.WorldCreator;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permission;
@@ -5,7 +5,7 @@
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.test.utils;
package com.onarandombox.MultiverseCore.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -5,16 +5,7 @@
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.test.utils;
import static org.mockito.Mockito.*;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
package com.onarandombox.MultiverseCore.utils;
import org.bukkit.Difficulty;
import org.bukkit.Location;
@@ -26,9 +17,20 @@ import org.bukkit.generator.ChunkGenerator;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.WeakHashMap;
import static org.mockito.Mockito.*;
public class MockWorldFactory {
private static final Map<String, World> createdWorlds = new HashMap<String, World>();
private static final Map<UUID, World> worldUIDS = new HashMap<UUID, World>();
private static final Map<World, Boolean> pvpStates = new WeakHashMap<World, Boolean>();
private static final Map<World, Boolean> keepSpawnInMemoryStates = new WeakHashMap<World, Boolean>();
@@ -39,6 +41,7 @@ public class MockWorldFactory {
private static void registerWorld(World world) {
createdWorlds.put(world.getName(), world);
worldUIDS.put(world.getUID(), world);
new File(TestInstanceCreator.worldsDirectory, world.getName()).mkdir();
}
@@ -132,6 +135,7 @@ public class MockWorldFactory {
return mockBlock;
}
});
when(mockWorld.getUID()).thenReturn(UUID.randomUUID());
return mockWorld;
}
@@ -203,6 +207,10 @@ public class MockWorldFactory {
return createdWorlds.get(name);
}
public static World getWorld(UUID worldUID) {
return worldUIDS.get(worldUID);
}
public static List<World> getWorlds() {
// we have to invert the order!
ArrayList<World> myList = new ArrayList<World>(createdWorlds.values());
@@ -217,5 +225,6 @@ public class MockWorldFactory {
for (String name : createdWorlds.keySet())
new File(TestInstanceCreator.worldsDirectory, name).delete();
createdWorlds.clear();
worldUIDS.clear();
}
}
@@ -5,7 +5,7 @@
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.test.utils;
package com.onarandombox.MultiverseCore.utils;
import buscript.Buscript;
import com.onarandombox.MultiverseCore.MultiverseCore;
@@ -13,8 +13,6 @@ 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;
import junit.framework.Assert;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -38,6 +36,7 @@ import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -77,6 +76,7 @@ public class TestInstanceCreator {
when(pdf.getAuthors()).thenReturn(new ArrayList<String>());
doReturn(pdf).when(core).getDescription();
doReturn(true).when(core).isEnabled();
doReturn(Util.logger).when(core).getLogger();
core.setServerFolder(serverDirectory);
// Add Core to the list of loaded plugins
@@ -122,6 +122,19 @@ public class TestInstanceCreator {
}
});
when(mockServer.getWorld(any(UUID.class))).thenAnswer(new Answer<World>() {
@Override
public World answer(InvocationOnMock invocation) throws Throwable {
UUID arg;
try {
arg = (UUID) invocation.getArguments()[0];
} catch (Exception e) {
return null;
}
return MockWorldFactory.getWorld(arg);
}
});
when(mockServer.getWorlds()).thenAnswer(new Answer<List<World>>() {
@Override
public List<World> answer(InvocationOnMock invocation) throws Throwable {
@@ -5,7 +5,7 @@
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.test.utils;
package com.onarandombox.MultiverseCore.utils;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
@@ -5,7 +5,7 @@
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.test.utils;
package com.onarandombox.MultiverseCore.utils;
import org.bukkit.WorldCreator;
import org.mockito.ArgumentMatcher;