Compare commits

...
50 Commits
Author SHA1 Message Date
Eric Stokes 2eb61af76f Remove Structures and Types from import
Fixes #466
2012-02-05 20:32:09 -07:00
Eric Stokes ad9d4e41ff Remove EGG, that's for chickens, silly. 2012-02-05 00:10:36 -07:00
Eric Stokes 6a2e0e5810 Fix Portals being blocked in End
This Fixes #463
This is caused by a bug in Bukkit/Bukkit@b2364780cb see line 38 of EntityCreatePortalEvent
2012-02-04 23:46:40 -07:00
Eric Stokes a9c6582487 Fix bypass perms. Fixes #443
I had a typo and didn't add the parent perms :(

Sorry about this big breakage... should be fixed.
2012-02-04 18:06:50 -07:00
Eric Stokes b66028e0e0 Lots of cleanup prepping for 2.3AB 2012-02-04 17:40:12 -07:00
Eric Stokes 3ac4e55dc2 Minor bug fixed preparing for 2.3
Fix chatPrefix -> chatprefix
Fix portalcooldown -> teleportcooldown
Fix made teleportcooldown show up in the config
Add New warnings to the default.
2012-02-04 10:14:58 -07:00
Eric Stokes 950991ff1b Removed old checks, cleanup poop
Add in the deprecated config method to not break other plugins
Fix handling of unloaded worlds in info and list
2012-02-04 09:10:56 -07:00
main() a1b07065b2 Merge branch 'master' of github.com:Multiverse/Multiverse-Core into config-changes
Conflicts:
	src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java
	src/main/java/com/onarandombox/MultiverseCore/MultiverseCoreConfiguration.java
	src/main/java/com/onarandombox/MultiverseCore/commands/ConfigCommand.java
	src/main/java/com/onarandombox/MultiverseCore/utils/MVPermissions.java
	src/main/resources/defaults/config.yml
2012-02-04 15:19:37 +01:00
main() a1075224d3 Fixed config... 2012-02-04 14:22:55 +01:00
Eric Stokes d707a9f9a8 Made config command more hardcoded, but work. 2012-02-04 00:18:48 -07:00
Eric Stokes 90b04aa798 Add migrater for new configs, remove default, it's autogenned now 2012-02-03 23:36:17 -07:00
main() 5d1532e811 Updated build instructions in README (goodbye, submodules!) 2012-02-02 17:25:53 +01:00
main() 443d62580b CommandHandler is now mavenized, we can delete the submodule! 2012-02-02 17:20:46 +01:00
Eric Stokes 541819ea8f Move to shaded CH, this will break all MV plugins 2012-02-01 21:44:15 -07:00
Eric Stokes b09ea0e66a Add shading relocation so we don't conflict anymore! 2012-02-01 19:37:33 -07:00
Eric Stokes 8272e121f4 Update to allpay 6 2012-02-01 19:13:47 -07:00
main() 5d2534f497 Goodbye economy-dependencies! 2012-02-01 18:07:27 -07:00
main() 1e7eef90f9 Now using AllPay as maven-dependency, not as git-submodule. 2012-02-01 17:13:59 +01:00
main() 44df567936 Now using SerializationConfig. 2012-02-01 16:28:23 +01:00
main() d595cb9a31 Added SerializationConfig-dependency, including it with the shade-plugin. 2012-01-31 20:49:55 +01:00
Eric Stokes e8a72d19e1 Fix checkstyle violations 2012-01-29 15:56:57 -07:00
Eric Stokes dde3b63fb9 Fix non-active properties not saving.
Fixes #409
2012-01-29 15:40:16 -07:00
Eric Stokes 87d4d4e1f4 Allow generate-structures to be used per world 2012-01-29 12:41:48 -07:00
Eric Stokes 7aca740296 Fix javadocs in PortalTypeConfigProperty 2012-01-29 12:37:40 -07:00
Eric Stokes 6c9bc6951f Many small fixes.
- Update to 1.1-R2
 - Fix the '--list' not working with the import
 - Fix typo in new portalform catcher
 - Fix 'the_end' not working on import/create
2012-01-29 12:11:41 -07:00
Eric Stokes 74726b44ab Mid commit on adding portal prevention 2012-01-29 09:33:56 -07:00
Eric Stokes 18a57bf975 Allow eggs to spawn monsters 2012-01-28 08:27:57 -07:00
main() b2578b1736 "No newline at end of file" deserves more than only an information. 2012-01-28 15:48:46 +01:00
main() eec765bc48 Merge branch 'util-refactoring' 2012-01-28 15:41:58 +01:00
main() 060c0b1b44 (Re)designed PurgeWorlds/WorldPurger for extension. 2012-01-28 15:06:45 +01:00
Eric Stokes ba90228586 Fix anchors pages not being accessable
Fixes #434
2012-01-27 22:24:50 -07:00
main() 8017172f0e ...
-.-
RAGE!
2012-01-26 19:00:31 +01:00
main() b4ea5e9299 Change in SafeTTeleporter: We can SET the BlockSafety! 2012-01-26 18:56:54 +01:00
main() 59f2c8b62e (Re)designed SafeTTeleporter for extension. 2012-01-26 18:55:09 +01:00
main() 9a28158e5f Merge branch 'master' of github.com:Multiverse/Multiverse-Core into util-refactoring 2012-01-26 18:28:29 +01:00
Eric Stokes 4d97453881 Add the rest of the required items for the new events 2012-01-25 18:14:46 -07:00
Eric Stokes 8488f9db3c Remove the MVVersionRequestEvent, Update pom
I've had enough of our repo being fussy. Just adding the bukkit repos too.
We'll get the proxy stuff working eventually...
2012-01-25 17:13:30 -07:00
main() 51586c7dd5 More tests :D 2012-01-25 21:03:09 +01:00
Eric Stokes 7b74384a8e Fix compatibility with new tests.
Note: @main-- the new tests are balls slow for doing location generation. Like, they take 1s per check, which made the old one run for 16x16x9 seconds (making the test run take about 38.4 minutes)

For now, I've added a special case for nullterrains, which uses the new -n param to skip checking.
2012-01-24 20:32:39 -07:00
main() 33afa4d0d7 Now using the new listeners from ecb97fd5c1 2012-01-24 19:18:03 -07:00
main() 0980e0a201 Merge branch 'master' of github.com:Multiverse/Multiverse-Core into new-tests
Conflicts:
	src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java
2012-01-23 19:05:21 +01:00
main() 8bab4ae606 Merge branch 'master' of github.com:Multiverse/Multiverse-Core into new-tests 2012-01-11 16:44:59 +01:00
main() a1299239a2 Added more checks 2012-01-07 21:26:51 +01:00
main() 7cdb52e740 Yay for colored messages! 2012-01-07 21:26:23 +01:00
main() e2d6652ef1 One single missing char that kept breaking everything.
It took me half an hour to find this -.-
RAGE!
2012-01-07 17:13:00 +01:00
main() 814725a2ba Merge branch 'master' of github.com:Multiverse/Multiverse-Core into new-tests
Conflicts:
	src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java
2012-01-07 16:10:18 +01:00
main() da6e6145f2 (Re)designed MVMessaging for extension. 2012-01-07 16:05:16 +01:00
main() ee715b13b0 (Re)designed LocationManipulation for extension. 2012-01-07 16:02:23 +01:00
main() a18611fb76 (Re)designed BlockSafety for extension. 2012-01-06 21:11:51 +01:00
main() 9173a15eb9 Started work on tons of new tests 2011-12-31 18:34:04 +01:00
73 changed files with 3196 additions and 552 deletions

No files matched your search

-7
View File
@@ -1,7 +0,0 @@
[submodule "lib/allpay"]
path = lib/allpay
url = git://github.com/FernFerret/AllPay.git
[submodule "lib/commandhandler"]
path = lib/commandhandler
url = git://github.com/PneumatiCraft/CommandHandler.git
branch = notrie
+2 -5
View File
@@ -1,11 +1,8 @@
Building
========
Update the submodules after you clone and before you build with maven.
Simply build the source with maven:
```
$ git submodule update --init --recursive
$ mvn install
```
$ mvn install
More details are available on the [build instructions wiki page](https://github.com/Multiverse/Multiverse-Core/wiki/Building).
+1 -3
View File
@@ -13,9 +13,7 @@
<module name="JavadocPackage">
<property name="allowLegacy" value="true"/>
</module>
<module name="NewlineAtEndOfFile">
<property name="severity" value="info"/>
</module>
<module name="NewlineAtEndOfFile" />
<module name="Translation"/>
<module name="FileLength"/>
<module name="FileTabCharacter">
Submodule lib/allpay deleted from 7abba1f004.
+56 -74
View File
@@ -16,6 +16,10 @@
<id>onarandombox</id>
<url>http://repo.onarandombox.com/content/groups/public</url>
</repository>
<repository>
<id>Bukkit Official</id>
<url>http://repo.bukkit.org/content/repositories/public</url>
</repository>
</repositories>
<pluginRepositories>
@@ -63,28 +67,6 @@
<target>1.6</target>
</configuration>
</plugin>
<!-- Build Helper - Additional Source Folders -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-wsdl-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.basedir}/lib/allpay/src/main/java</source>
<source>${project.basedir}/lib/commandhandler/src</source>
<source>${project.basedir}/lib/commandhandler/lib/ShellParser/src</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>maven-replacer-plugin</artifactId>
@@ -154,6 +136,42 @@
<configLocation>${project.basedir}/config/mv_checks.xml</configLocation>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>me.main__.util:SerializationConfig</include>
<include>com.fernferret.allpay:AllPay</include>
<include>com.pneumaticraft.commandhandler:CommandHandler</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>com.fernferret.allpay</pattern>
<shadedPattern>com.fernferret.allpay.multiverse</shadedPattern>
</relocation>
<relocation>
<pattern>me.main__.util</pattern>
<shadedPattern>me.main__.util.multiverse</shadedPattern>
</relocation>
<relocation>
<pattern>com.pneumaticraft.commandhandler</pattern>
<shadedPattern>com.pneumaticraft.commandhandler.multiverse</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
@@ -162,7 +180,7 @@
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.1-R1-SNAPSHOT</version>
<version>1.1-R3</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
@@ -174,69 +192,33 @@
<version>dev-SNAPSHOT</version>
</dependency>
<!-- End of Spout -->
<!-- Start of Economy Dependencies -->
<!-- SerializationConfig Dependency -->
<dependency>
<groupId>cosine.boseconomy</groupId>
<artifactId>BOSEconomy</artifactId>
<version>0.6.2</version>
<groupId>me.main__.util</groupId>
<artifactId>SerializationConfig</artifactId>
<version>1.1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- End of SerializationConfig Dependency -->
<!-- Start of AllPay Dependency -->
<dependency>
<groupId>fr.crafter.tickleman.RealShop</groupId>
<artifactId>RealShop</artifactId>
<version>0.63</version>
<groupId>com.fernferret.allpay</groupId>
<artifactId>AllPay</artifactId>
<version>8</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- End of AllPay Dependency -->
<!-- Start of CommandHandler Dependency -->
<dependency>
<groupId>com.iCo6</groupId>
<artifactId>iConomy</artifactId>
<version>6.0</version>
<groupId>com.pneumaticraft.commandhandler</groupId>
<artifactId>CommandHandler</artifactId>
<version>6</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.iConomy</groupId>
<artifactId>iConomy</artifactId>
<version>5.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.nijiko.coelho.iConomy</groupId>
<artifactId>iConomy</artifactId>
<version>4.65</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.earth2me.essentials</groupId>
<artifactId>Essentials</artifactId>
<version>2.4.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.ashtheking.currency</groupId>
<artifactId>MultiCurrency</artifactId>
<version>0.09</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ca.agnate</groupId>
<artifactId>EconXP</artifactId>
<version>1.0.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- End of Economy Dependencies -->
<!-- End of CommandHandler Dependency -->
<!-- Start of Test Dependencies -->
<dependency>
<groupId>junit</groupId>
@@ -7,16 +7,16 @@
package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.configuration.ConfigPropertyFactory;
import com.onarandombox.MultiverseCore.configuration.MVActiveConfigProperty;
import com.onarandombox.MultiverseCore.configuration.MVConfigProperty;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import com.onarandombox.MultiverseCore.enums.EnglishChatColor;
import com.onarandombox.MultiverseCore.event.MVWorldPropertyChangeEvent;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
import com.onarandombox.MultiverseCore.utils.BlockSafety;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import com.onarandombox.MultiverseCore.utils.SafeTTeleporter;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import org.bukkit.ChatColor;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
@@ -33,7 +33,6 @@ import org.bukkit.permissions.PermissionDefault;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
@@ -158,6 +157,8 @@ public class MVWorld implements MultiverseWorld {
this.propertyList.put("adjustspawn", fac.getNewProperty("adjustspawn", true,
"Sorry, 'adjustspawn' must either be:" + ChatColor.GREEN + " true " + ChatColor.WHITE
+ "or" + ChatColor.RED + " false" + ChatColor.WHITE + "."));
this.propertyList.put("portalform", fac.getNewProperty("portalform", AllowedPortalType.ALL,
"Allow portal forming must be NONE, ALL, NETHER or END."));
if (!fixSpawn) {
this.setAdjustSpawn(false);
}
@@ -205,7 +206,11 @@ public class MVWorld implements MultiverseWorld {
this.plugin.getServer().getPluginManager().addPermission(this.permission);
this.plugin.getServer().getPluginManager().addPermission(this.exempt);
this.plugin.getServer().getPluginManager().addPermission(this.ignoreperm);
addToUpperLists(this.permission);
// Add the permission and exempt to parents.
this.addToUpperLists(this.permission);
// Add ignore to it's parent:
this.ignoreperm.addParent("mv.bypass.gamemode.*", true);
} catch (IllegalArgumentException e) {
this.plugin.log(Level.FINER, "Permissions nodes were already added for " + this.name);
}
@@ -433,7 +438,7 @@ public class MVWorld implements MultiverseWorld {
} else {
this.world.setSpawnFlags(true, this.world.getAllowAnimals());
}
this.plugin.getMVWorldManager().getWorldPurger().purgeWorld(null, this);
this.plugin.getMVWorldManager().getTheWorldPurger().purgeWorld(this);
}
/**
@@ -513,6 +518,7 @@ public class MVWorld implements MultiverseWorld {
return (MVConfigProperty<T>) this.propertyList.get(this.propertyAliases.get(name));
}
} catch (ClassCastException e) {
return null;
}
return null;
}
@@ -558,6 +564,7 @@ public class MVWorld implements MultiverseWorld {
try {
if (property.getMethod() == null) {
// This property did not have a method.
this.saveConfig();
return true;
}
Method method = this.getClass().getMethod(property.getMethod());
@@ -572,6 +579,8 @@ public class MVWorld implements MultiverseWorld {
return true;
}
} catch (Exception e) {
// TODO: I don't care about 3 catches,
// TODO: I hate pokemon errors :/ - FernFerret
e.printStackTrace();
return false;
}
@@ -986,8 +995,8 @@ public class MVWorld implements MultiverseWorld {
// Set the worldspawn to our configspawn
w.setSpawnLocation(configLocation.getBlockX(), configLocation.getBlockY(), configLocation.getBlockZ());
SafeTTeleporter teleporter = this.plugin.getTeleporter();
BlockSafety bs = new BlockSafety();
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
BlockSafety bs = this.plugin.getBlockSafety();
// Verify that location was safe
if (!bs.playerCanSpawnHereSafely(configLocation)) {
if (!this.getAdjustSpawn()) {
@@ -999,7 +1008,7 @@ public class MVWorld implements MultiverseWorld {
}
// If it's not, find a better one.
this.plugin.log(Level.WARNING, "Spawn location from world.dat file was unsafe. Adjusting...");
this.plugin.log(Level.WARNING, "Original Location: " + LocationManipulation.strCoordsRaw(spawnLocation));
this.plugin.log(Level.WARNING, "Original Location: " + plugin.getLocationManipulation().strCoordsRaw(spawnLocation));
Location newSpawn = teleporter.getSafeLocation(spawnLocation,
SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
// I think we could also do this, as I think this is what Notch does.
@@ -1008,16 +1017,17 @@ public class MVWorld implements MultiverseWorld {
if (newSpawn != null) {
this.setSpawnLocation(newSpawn);
configLocation = this.getSpawnLocation();
this.plugin.log(Level.INFO, "New Spawn for '" + this.getName() + "' is Located at: " + LocationManipulation.locationToString(configLocation));
this.plugin.log(Level.INFO, "New Spawn for '" + this.getName()
+ "' is Located at: " + plugin.getLocationManipulation().locationToString(configLocation));
} else {
// If it's a standard end world, let's check in a better place:
Location newerSpawn = null;
Location newerSpawn;
newerSpawn = bs.getTopBlock(new Location(w, 0, 0, 0));
if (newerSpawn != null) {
this.setSpawnLocation(newerSpawn);
configLocation = this.getSpawnLocation();
this.plugin.log(Level.INFO, "New Spawn for '" + this.getName()
+ "' is Located at: " + LocationManipulation.locationToString(configLocation));
+ "' is Located at: " + plugin.getLocationManipulation().locationToString(configLocation));
} else {
this.plugin.log(Level.SEVERE, "New safe spawn NOT found!!!");
}
@@ -1160,6 +1170,22 @@ public class MVWorld implements MultiverseWorld {
return this.type;
}
/**
* {@inheritDoc}
*/
@Override
public void allowPortalMaking(AllowedPortalType type) {
this.setKnownProperty("portalform", type.toString(), null);
}
/**
* {@inheritDoc}
*/
@Override
public AllowedPortalType getAllowedPortals() {
return this.getKnownProperty("portalform", AllowedPortalType.class).getValue();
}
/**
* Used by the active time-property to set the "actual" property.
* @return True if the property was successfully set.
@@ -9,10 +9,15 @@ package com.onarandombox.MultiverseCore;
import com.fernferret.allpay.AllPay;
import com.fernferret.allpay.GenericBank;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.Core;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import com.onarandombox.MultiverseCore.api.MVPlugin;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
import com.onarandombox.MultiverseCore.api.MultiverseMessaging;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.commands.*;
import com.onarandombox.MultiverseCore.destination.AnchorDestination;
import com.onarandombox.MultiverseCore.destination.BedDestination;
@@ -26,15 +31,12 @@ import com.onarandombox.MultiverseCore.listeners.MVEntityListener;
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
import com.onarandombox.MultiverseCore.listeners.MVPluginListener;
import com.onarandombox.MultiverseCore.listeners.MVWeatherListener;
import com.onarandombox.MultiverseCore.utils.AnchorManager;
import com.onarandombox.MultiverseCore.utils.DebugLog;
import com.onarandombox.MultiverseCore.utils.MVMessaging;
import com.onarandombox.MultiverseCore.utils.MVPermissions;
import com.onarandombox.MultiverseCore.utils.MVPlayerSession;
import com.onarandombox.MultiverseCore.utils.SafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.SpoutInterface;
import com.onarandombox.MultiverseCore.utils.WorldManager;
import com.onarandombox.MultiverseCore.listeners.MVPortalListener;
import com.onarandombox.MultiverseCore.utils.*;
import com.pneumaticraft.commandhandler.CommandHandler;
import me.main__.util.SerializationConfig.SerializationConfig;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.Command;
@@ -61,21 +63,14 @@ import java.util.logging.Logger;
* The implementation of the Multiverse-{@link Core}.
*/
public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
private static final int PROTOCOL = 12;
// Global Multiverse config variable, states whether or not
// Multiverse should stop other plugins from teleporting players
// to worlds.
// TODO This is REALLY bad style! We have to change this!
// No, I'm NOT going to suppress these warnings because we HAVE TO CHANGE THIS!
public static boolean EnforceAccess;
public static boolean PrefixChat;
public static boolean DisplayPermErrors;
public static boolean TeleportIntercept;
public static boolean FirstSpawnOverride;
public static Map<String, String> teleportQueue = new HashMap<String, String>();
public static int GlobalDebug = 0;
private static final int PROTOCOL = 14;
// TODO: Investigate if this one is really needed to be static.
// Doubt it. -- FernFerret
private static Map<String, String> teleportQueue = new HashMap<String, String>();
private AnchorManager anchorManager = new AnchorManager(this);
// TODO please let's make this non-static
private static MultiverseCoreConfiguration config;
/**
* This method is used to find out who is teleporting a player.
@@ -153,12 +148,10 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
// Setup the block/player/entity listener.
private MVPlayerListener playerListener = new MVPlayerListener(this);
private MVEntityListener entityListener = new MVEntityListener(this);
private MVPluginListener pluginListener = new MVPluginListener(this);
private MVWeatherListener weatherListener = new MVWeatherListener(this);
//public UpdateChecker updateCheck;
private MVPortalListener portalListener = new MVPortalListener(this);
// HashMap to contain information relating to the Players.
private HashMap<String, MVPlayerSession> playerSessions;
@@ -167,24 +160,35 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
private int pluginCount;
private DestinationFactory destFactory;
private SpoutInterface spoutInterface = null;
private static final double ALLPAY_VERSION = 5;
private static final double CH_VERSION = 4;
private MVMessaging messaging;
private MultiverseMessaging messaging;
private BlockSafety blockSafety;
private LocationManipulation locationManipulation;
private SafeTTeleporter safeTTeleporter;
private File serverFolder = new File(System.getProperty("user.dir"));
@Override
public void onLoad() {
// Register our config
SerializationConfig.registerAll(MultiverseCoreConfiguration.class);
// Create our DataFolder
getDataFolder().mkdirs();
// Setup our Debug Log
debugLog = new DebugLog("Multiverse-Core", getDataFolder() + File.separator + "debug.log");
// Setup our BlockSafety
this.blockSafety = new SimpleBlockSafety(this);
// Setup our LocationManipulation
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;
}
@@ -202,12 +206,6 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*/
@Override
public void onEnable() {
//this.worldManager = new WorldManager(this);
// Perform initial checks for AllPay
if (!this.validateAllpay() || !this.validateCH()) {
this.getServer().getPluginManager().disablePlugin(this);
return;
}
this.messaging = new MVMessaging();
this.banker = new AllPay(this, LOG_TAG + " ");
// Output a little snippet to show it's enabled.
@@ -248,12 +246,9 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
this.anchorManager.loadAnchors();
// Now set the firstspawnworld (after the worlds are loaded):
// Default as the server.props world.
this.worldManager.setFirstSpawnWorld(this.multiverseConfig.getString("firstspawnworld", getDefaultWorldName()));
// We have to set this one here, if it's not present, we don't know the name of the default world.
// and this one won't be in the defaults yml file.
this.worldManager.setFirstSpawnWorld(config.getFirstSpawnWorld());
try {
this.multiverseConfig.set("firstspawnworld", this.worldManager.getFirstSpawnWorld().getName());
config.setFirstSpawnWorld(this.worldManager.getFirstSpawnWorld().getName());
} catch (NullPointerException e) {
// A test that had no worlds loaded was being run. This should never happen in production
}
@@ -265,40 +260,6 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
}
}
private boolean validateAllpay() {
try {
this.banker = new AllPay(this, "Verify");
if (this.banker.getVersion() >= ALLPAY_VERSION) {
return true;
}
} catch (Throwable t) {
}
LOGGER.info(String.format("%s - Version %s was NOT ENABLED!!!", LOG_TAG, this.getDescription().getVersion()));
LOGGER.info(String.format("%s A plugin that has loaded before %s has an incompatible version of AllPay (an internal library)!",
LOG_TAG, this.getDescription().getName()));
LOGGER.info(String.format("%s The Following Plugins MAY out of date: %s", LOG_TAG, AllPay.pluginsThatUseUs.toString()));
LOGGER.info(String.format("%s This plugin needs AllPay v%f or higher and another plugin has loaded v%f!",
LOG_TAG, ALLPAY_VERSION, this.banker.getVersion()));
return false;
}
private boolean validateCH() {
try {
this.commandHandler = new CommandHandler(this, null);
if (this.commandHandler.getVersion() >= CH_VERSION) {
return true;
}
} catch (Throwable t) {
}
LOGGER.info(String.format("%s - Version %s was NOT ENABLED!!!", LOG_TAG, this.getDescription().getVersion()));
LOGGER.info(String.format("%s A plugin that has loaded before %s has an incompatible version of CommandHandler (an internal library)!",
LOG_TAG, this.getDescription().getName()));
LOGGER.info(String.format("%s Please contact this plugin author!!!", LOG_TAG));
LOGGER.info(String.format("%s This plugin needs CommandHandler v%f or higher and another plugin has loaded v%f!",
LOG_TAG, CH_VERSION, this.commandHandler.getVersion()));
return false;
}
private void initializeDestinationFactory() {
this.destFactory = new DestinationFactory(this);
this.destFactory.registerDestinationType(WorldDestination.class, "");
@@ -319,6 +280,8 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
pm.registerEvents(this.entityListener, this);
pm.registerEvents(this.pluginListener, this);
pm.registerEvents(this.weatherListener, this);
pm.registerEvents(this.portalListener, this);
}
/**
@@ -330,53 +293,87 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
this.multiverseConfig = YamlConfiguration.loadConfiguration(new File(getDataFolder(), "config.yml"));
Configuration coreDefaults = YamlConfiguration.loadConfiguration(this.getClass().getResourceAsStream("/defaults/config.yml"));
this.multiverseConfig.setDefaults(coreDefaults);
this.multiverseConfig.options().copyDefaults(true);
this.saveMVConfig();
this.multiverseConfig = YamlConfiguration.loadConfiguration(new File(getDataFolder(), "config.yml"));
this.multiverseConfig.options().copyDefaults(false);
this.multiverseConfig.options().copyHeader(true);
this.worldManager.loadWorldConfig(new File(getDataFolder(), "worlds.yml"));
// Setup the Debug option, we'll default to false because this option will not be in the default config.
GlobalDebug = this.multiverseConfig.getInt("debug", 0);
// Lets cache these values due to the fact that they will be accessed many times.
EnforceAccess = this.multiverseConfig.getBoolean("enforceaccess", false);
PrefixChat = this.multiverseConfig.getBoolean("worldnameprefix", true);
// Should MV Intercept teleports by other plugins?
TeleportIntercept = this.multiverseConfig.getBoolean("teleportintercept", true);
// Should MV do the first spawn stuff?
FirstSpawnOverride = this.multiverseConfig.getBoolean("firstspawnoverride", true);
// Should permissions errors display to users?
DisplayPermErrors = this.multiverseConfig.getBoolean("displaypermerrors", true);
MultiverseCoreConfiguration wantedConfig = null;
try {
wantedConfig = (MultiverseCoreConfiguration) multiverseConfig.get("multiverse-configuration");
} catch (Exception e) {
// We're just thinking "no risk no fun" and therefore have to catch and forget this exception
} finally {
config = ((wantedConfig == null) ? new MultiverseCoreConfiguration() : wantedConfig);
}
this.messaging.setCooldown(this.multiverseConfig.getInt("messagecooldown", 5000)); // SUPPRESS CHECKSTYLE: MagicNumberCheck
// Update the version of the config!
this.multiverseConfig.set("version", coreDefaults.get("version"));
this.messaging.setCooldown(config.getMessageCooldown());
// Remove old values.
this.multiverseConfig.set("enforcegamemodes", null);
this.multiverseConfig.set("bedrespawn", null);
this.multiverseConfig.set("opfallback", null);
// Old Config Format
this.migrate22Values();
this.saveMVConfigs();
}
/**
* Safely return a world name.
* (The tests call this with no worlds loaded)
*
* @return The default world name.
* Thes are the MV config 2.0-2.2 values,
* they should be migrated to the new format.
*/
private String getDefaultWorldName() {
if (this.getServer().getWorlds().size() > 0) {
return this.getServer().getWorlds().get(0).getName();
private void migrate22Values() {
if (this.multiverseConfig.isSet("worldnameprefix")) {
this.log(Level.INFO, "Migrating 'worldnameprefix'...");
this.config.setPrefixChat(this.multiverseConfig.getBoolean("worldnameprefix"));
this.multiverseConfig.set("worldnameprefix", null);
}
if (this.multiverseConfig.isSet("firstspawnworld")) {
this.log(Level.INFO, "Migrating 'firstspawnworld'...");
this.config.setFirstSpawnWorld(this.multiverseConfig.getString("firstspawnworld"));
this.multiverseConfig.set("firstspawnworld", null);
}
if (this.multiverseConfig.isSet("enforceaccess")) {
this.log(Level.INFO, "Migrating 'enforceaccess'...");
this.config.setEnforceAccess(this.multiverseConfig.getBoolean("enforceaccess"));
this.multiverseConfig.set("enforceaccess", null);
}
if (this.multiverseConfig.isSet("displaypermerrors")) {
this.log(Level.INFO, "Migrating 'displaypermerrors'...");
this.config.setDisplayPermErrors(this.multiverseConfig.getBoolean("displaypermerrors"));
this.multiverseConfig.set("displaypermerrors", null);
}
if (this.multiverseConfig.isSet("teleportintercept")) {
this.log(Level.INFO, "Migrating 'teleportintercept'...");
this.config.setTeleportIntercept(this.multiverseConfig.getBoolean("teleportintercept"));
this.multiverseConfig.set("teleportintercept", null);
}
if (this.multiverseConfig.isSet("firstspawnoverride")) {
this.log(Level.INFO, "Migrating 'firstspawnoverride'...");
this.config.setFirstSpawnOverride(this.multiverseConfig.getBoolean("firstspawnoverride"));
this.multiverseConfig.set("firstspawnoverride", null);
}
if (this.multiverseConfig.isSet("messagecooldown")) {
this.log(Level.INFO, "Migrating 'messagecooldown'...");
this.config.setMessageCooldown(this.multiverseConfig.getInt("messagecooldown"));
this.multiverseConfig.set("messagecooldown", null);
}
if (this.multiverseConfig.isSet("debug")) {
this.log(Level.INFO, "Migrating 'debug'...");
this.config.setGlobalDebug(this.multiverseConfig.getInt("debug"));
this.multiverseConfig.set("debug", null);
}
if (this.multiverseConfig.isSet("version")) {
this.log(Level.INFO, "Migrating 'version'...");
this.multiverseConfig.set("version", null);
}
return "";
}
/**
* {@inheritDoc}
*/
@Override
public MVMessaging getMessaging() {
public MultiverseMessaging getMessaging() {
return this.messaging;
}
@@ -439,17 +436,20 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
if (this.playerSessions.containsKey(player.getName())) {
return this.playerSessions.get(player.getName());
} else {
this.playerSessions.put(player.getName(), new MVPlayerSession(player, this.multiverseConfig, this));
this.playerSessions.put(player.getName(), new MVPlayerSession(player, config));
return this.playerSessions.get(player.getName());
}
}
/**
* {@inheritDoc}
*
* @deprecated This is deprecated.
*/
@Override
public SafeTTeleporter getTeleporter() {
return new SafeTTeleporter(this);
@Deprecated
public com.onarandombox.MultiverseCore.utils.SafeTTeleporter getTeleporter() {
return new com.onarandombox.MultiverseCore.utils.SafeTTeleporter(this);
}
/**
@@ -471,7 +471,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
}
ArrayList<String> allArgs = new ArrayList<String>(Arrays.asList(args));
allArgs.add(0, command.getName());
return this.commandHandler.locateAndRunCommand(sender, allArgs, DisplayPermErrors);
return this.commandHandler.locateAndRunCommand(sender, allArgs, config.getDisplayPermErrors());
}
/**
@@ -489,13 +489,13 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
* @param msg The message to log.
*/
public static void staticLog(Level level, String msg) {
if (level == Level.FINE && GlobalDebug >= 1) {
if (level == Level.FINE && config.getGlobalDebug() >= 1) {
staticDebugLog(Level.INFO, msg);
return;
} else if (level == Level.FINER && GlobalDebug >= 2) {
} else if (level == Level.FINER && config.getGlobalDebug() >= 2) {
staticDebugLog(Level.INFO, msg);
return;
} else if (level == Level.FINEST && GlobalDebug >= 3) {
} else if (level == Level.FINEST && config.getGlobalDebug() >= 3) {
staticDebugLog(Level.INFO, msg);
return;
} else if (level != Level.FINE && level != Level.FINER && level != Level.FINEST) {
@@ -638,7 +638,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*/
public void teleportPlayer(CommandSender teleporter, Player p, Location l) {
// This command is the override, and MUST NOT TELEPORT SAFELY
this.getTeleporter().safelyTeleport(teleporter, p, l, false);
this.getSafeTTeleporter().safelyTeleport(teleporter, p, l, false);
}
/**
@@ -696,6 +696,24 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
return this.playerListener;
}
/**
* Gets the {@link MVEntityListener}.
*
* @return The {@link MVEntityListener}.
*/
public MVEntityListener getEntityListener() {
return this.entityListener;
}
/**
* Gets the {@link MVWeatherListener}.
*
* @return The {@link MVWeatherListener}.
*/
public MVWeatherListener getWeatherListener() {
return this.weatherListener;
}
/**
* Saves the Multiverse-Config.
*
@@ -703,6 +721,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*/
public boolean saveMVConfig() {
try {
this.multiverseConfig.set("multiverse-configuration", config);
this.multiverseConfig.save(new File(getDataFolder(), "config.yml"));
return true;
} catch (IOException e) {
@@ -762,7 +781,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
}
if (this.worldManager.deleteWorld(name, false)) {
this.worldManager.loadWorlds(false);
SafeTTeleporter teleporter = this.getTeleporter();
SafeTTeleporter teleporter = this.getSafeTTeleporter();
Location newSpawn = this.getServer().getWorld(name).getSpawnLocation();
// Send all players that were in the old world, BACK to it!
for (Player p : ps) {
@@ -781,4 +800,70 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
return this.anchorManager;
}
/**
* {@inheritDoc}
*/
@Override
public BlockSafety getBlockSafety() {
return blockSafety;
}
/**
* {@inheritDoc}
*/
@Override
public void setBlockSafety(BlockSafety bs) {
this.blockSafety = bs;
}
/**
* {@inheritDoc}
*/
@Override
public LocationManipulation getLocationManipulation() {
return locationManipulation;
}
/**
* {@inheritDoc}
*/
@Override
public void setLocationManipulation(LocationManipulation locationManipulation) {
this.locationManipulation = locationManipulation;
}
/**
* {@inheritDoc}
*/
@Override
public SafeTTeleporter getSafeTTeleporter() {
return safeTTeleporter;
}
/**
* {@inheritDoc}
*/
@Override
public void setSafeTTeleporter(SafeTTeleporter safeTTeleporter) {
this.safeTTeleporter = safeTTeleporter;
}
/**
* {@inheritDoc}
*/
@Override
public MultiverseCoreConfig getMVConfig() {
return config;
}
/**
* This method is currently used by other plugins.
* It will be removed in 2.4
* @return The Multiverse config.
* @deprecated This is deprecated.
*/
@Deprecated
public static MultiverseCoreConfiguration getStaticConfig() {
return config;
}
}
@@ -0,0 +1,222 @@
package com.onarandombox.MultiverseCore;
import java.util.Map;
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
import me.main__.util.SerializationConfig.Property;
import me.main__.util.SerializationConfig.SerializationConfig;
/**
* Our configuration.
*/
public class MultiverseCoreConfiguration extends SerializationConfig implements MultiverseCoreConfig {
@Property
private boolean enforceaccess;
@Property
private boolean prefixchat;
@Property
private boolean teleportintercept;
@Property
private boolean firstspawnoverride;
@Property
private boolean displaypermerrors;
@Property
private int globaldebug;
@Property
private int messagecooldown;
@Property
private double version;
@Property
private String firstspawnworld;
@Property
private int teleportcooldown;
public MultiverseCoreConfiguration() {
super();
}
public MultiverseCoreConfiguration(Map<String, Object> values) {
super(values);
}
/**
* {@inheritDoc}
*/
@Override
public void setDefaults() {
// BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
enforceaccess = false;
prefixchat = true;
teleportintercept = true;
firstspawnoverride = true;
displaypermerrors = true;
globaldebug = 0;
messagecooldown = 5000;
teleportcooldown = 1000;
this.version = 2.9;
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
}
// And here we go:
/**
* {@inheritDoc}
*/
@Override
public boolean getEnforceAccess() {
return this.enforceaccess;
}
/**
* {@inheritDoc}
*/
@Override
public void setEnforceAccess(boolean enforceAccess) {
this.enforceaccess = enforceAccess;
}
/**
* {@inheritDoc}
*/
@Override
public boolean getPrefixChat() {
return this.prefixchat;
}
/**
* {@inheritDoc}
*/
@Override
public void setPrefixChat(boolean prefixChat) {
this.prefixchat = prefixChat;
}
/**
* {@inheritDoc}
*/
@Override
public boolean getTeleportIntercept() {
return this.teleportintercept;
}
/**
* {@inheritDoc}
*/
@Override
public void setTeleportIntercept(boolean teleportIntercept) {
this.teleportintercept = teleportIntercept;
}
/**
* {@inheritDoc}
*/
@Override
public boolean getFirstSpawnOverride() {
return this.firstspawnoverride;
}
/**
* {@inheritDoc}
*/
@Override
public void setFirstSpawnOverride(boolean firstSpawnOverride) {
this.firstspawnoverride = firstSpawnOverride;
}
/**
* {@inheritDoc}
*/
@Override
public boolean getDisplayPermErrors() {
return this.displaypermerrors;
}
/**
* {@inheritDoc}
*/
@Override
public void setDisplayPermErrors(boolean displayPermErrors) {
this.displaypermerrors = displayPermErrors;
}
/**
* {@inheritDoc}
*/
@Override
public int getGlobalDebug() {
return this.globaldebug;
}
/**
* {@inheritDoc}
*/
@Override
public void setGlobalDebug(int globalDebug) {
this.globaldebug = globalDebug;
}
/**
* {@inheritDoc}
*/
@Override
public int getMessageCooldown() {
return this.messagecooldown;
}
/**
* {@inheritDoc}
*/
@Override
public void setMessageCooldown(int messageCooldown) {
this.messagecooldown = messageCooldown;
}
/**
* {@inheritDoc}
*/
@Override
public double getVersion() {
return this.version;
}
/**
* {@inheritDoc}
*/
@Override
public void setVersion(int version) {
this.version = version;
}
/**
* {@inheritDoc}
*/
@Override
public String getFirstSpawnWorld() {
return this.firstspawnworld;
}
/**
* {@inheritDoc}
*/
@Override
public void setFirstSpawnWorld(String firstSpawnWorld) {
this.firstspawnworld = firstSpawnWorld;
}
/**
* {@inheritDoc}
*/
@Override
public int getTeleportCooldown() {
return this.teleportcooldown;
}
/**
* {@inheritDoc}
*/
@Override
public void setTeleportCooldown(int teleportCooldown) {
this.teleportcooldown = teleportCooldown;
}
}
@@ -0,0 +1,72 @@
package com.onarandombox.MultiverseCore.api;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Vehicle;
/**
* Used to get block/location-related information.
*/
public interface BlockSafety {
/**
* This function checks whether the block at the given coordinates are above air or not.
* @param l The {@link Location} of the block.
* @return True if the block at that {@link Location} is above air.
*/
boolean isBlockAboveAir(Location l);
/**
* Checks if a player can spawn safely at the given coordinates.
* @param world The {@link World}.
* @param x The x-coordinate.
* @param y The y-coordinate.
* @param z The z-coordinate.
* @return True if a player can spawn safely at the given coordinates.
*/
boolean playerCanSpawnHereSafely(World world, double x, double y, double z);
/**
* This function checks whether the block at the coordinates given is safe or not by checking for Lava/Fire/Air
* etc. This also ensures there is enough space for a player to spawn!
*
* @param l The {@link Location}
* @return Whether the player can spawn safely at the given {@link Location}
*/
boolean playerCanSpawnHereSafely(Location l);
/**
* Gets the location of the top block at the specified {@link Location}.
* @param l Any {@link Location}.
* @return The {@link Location} of the top-block.
*/
Location getTopBlock(Location l);
/**
* Gets the location of the top block at the specified {@link Location}.
* @param l Any {@link Location}.
* @return The {@link Location} of the top-block.
*/
Location getBottomBlock(Location l);
/**
* Checks if an entity would be on track at the specified {@link Location}.
* @param l The {@link Location}.
* @return True if an entity would be on tracks at the specified {@link Location}.
*/
boolean isEntitiyOnTrack(Location l);
/**
* Checks if the specified {@link Minecart} can spawn safely.
* @param cart The {@link Minecart}.
* @return True if the minecart can spawn safely.
*/
boolean canSpawnCartSafely(Minecart cart);
/**
* Checks if the specified {@link Vehicle} can spawn safely.
* @param vehicle The {@link Vehicle}.
* @return True if the vehicle can spawn safely.
*/
boolean canSpawnVehicleSafely(Vehicle vehicle);
}
@@ -26,7 +26,9 @@ public interface Core {
* Gets the Multiverse config file.
*
* @return The Multiverse config file.
* @deprecated Don't modify the config-file manually!
*/
@Deprecated
FileConfiguration getMVConfiguration();
/**
@@ -46,9 +48,9 @@ public interface Core {
* Gets the Multiverse message system. This allows you to send messages
* to users at specified intervals.
*
* @return The loaded {@link MVMessaging}.
* @return The loaded {@link MultiverseMessaging}.
*/
MVMessaging getMessaging();
MultiverseMessaging getMessaging();
/**
* Gets the {@link MVPlayerSession} for the given player.
@@ -66,8 +68,11 @@ public interface Core {
* safe teleports.
*
* @return A non-null {@link SafeTTeleporter}.
*
* @deprecated Use {@link #getSafeTTeleporter()} instead.
*/
SafeTTeleporter getTeleporter();
@Deprecated
com.onarandombox.MultiverseCore.utils.SafeTTeleporter getTeleporter();
/**
* Multiverse uses an advanced permissions setup, this object
@@ -163,4 +168,58 @@ public interface Core {
* @return The readable authors-{@link String}
*/
String getAuthors();
/**
* Gets the {@link BlockSafety} this {@link Core} is using.
* @return The {@link BlockSafety} this {@link Core} is using.
* @see BlockSafety
* @see SimpleBlockSafety
*/
BlockSafety getBlockSafety();
/**
* Sets the {@link BlockSafety} this {@link Core} is using.
* @param blockSafety The new {@link BlockSafety}.
* @see BlockSafety
* @see SimpleBlockSafety
*/
void setBlockSafety(BlockSafety blockSafety);
/**
* Gets the {@link LocationManipulation} this {@link Core} is using.
* @return The {@link LocationManipulation} this {@link Core} is using.
* @see LocationManipulation
* @see SimpleLocationManipulation
*/
LocationManipulation getLocationManipulation();
/**
* Sets the {@link LocationManipulation} this {@link Core} is using.
* @param locationManipulation The new {@link LocationManipulation}.
* @see LocationManipulation
* @see SimpleLocationManipulation
*/
void setLocationManipulation(LocationManipulation locationManipulation);
/**
* Gets the {@link SafeTTeleporter} this {@link Core} is using.
* @return The {@link SafeTTeleporter} this {@link Core} is using.
* @see SafeTTeleporter
* @see SimpleSafeTTeleporter
*/
SafeTTeleporter getSafeTTeleporter();
/**
* Sets the {@link SafeTTeleporter} this {@link Core} is using.
* @param safeTTeleporter The new {@link SafeTTeleporter}.
* @see SafeTTeleporter
* @see SimpleSafeTTeleporter
*/
void setSafeTTeleporter(SafeTTeleporter safeTTeleporter);
/**
* Gets the {@link MultiverseCoreConfig}.
* @return The configuration.
*/
MultiverseCoreConfig getMVConfig();
}
@@ -0,0 +1,99 @@
package com.onarandombox.MultiverseCore.api;
import org.bukkit.Location;
import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
/**
* Used to manipulate locations.
*/
public interface LocationManipulation {
/**
* Convert a Location into a Colon separated string to allow us to store it in text.
* <p>
* WORLD:X,Y,Z:yaw:pitch
* <p>
* The corresponding String2Loc function is {@link #stringToLocation}
*
* @param location The Location to save.
* @return The location as a string in this format: WORLD:x,y,z:yaw:pitch
*/
String locationToString(Location location);
/**
* This method simply does some rounding, rather than forcing a call to the server to get the blockdata.
*
* @param l The location to round to the block location
* @return A rounded location.
*/
Location getBlockLocation(Location l);
/**
* Returns a new location from a given string. The format is as follows:
* <p>
* WORLD:X,Y,Z:yaw:pitch
* <p>
* The corresponding Location2String function is {@link #stringToLocation}
*
* @param locationString The location represented as a string (WORLD:X,Y,Z:yaw:pitch)
* @return A new location defined by the string or null if the string was invalid.
*/
Location stringToLocation(String locationString);
/**
* Returns a colored string with the coords.
*
* @param l The {@link Location}
* @return The {@link String}
*/
String strCoords(Location l);
/**
* Converts a location to a printable readable formatted string including pitch/yaw.
*
* @param l The {@link Location}
* @return The {@link String}
*/
String strCoordsRaw(Location l);
/**
* Return the NESW Direction a Location is facing.
*
* @param location The {@link Location}
* @return The NESW Direction
*/
String getDirection(Location location);
/**
* Returns the float yaw position for the given cardinal direction.
*
* @param orientation The cardinal direction
* @return The yaw
*/
float getYaw(String orientation);
/**
* Returns a speed float from a given vector.
*
* @param v The {@link Vector}
* @return The speed
*/
float getSpeed(Vector v);
/**
* Returns a translated vector from the given direction.
*
* @param v The old {@link Vector}
* @param direction The new direction
* @return The translated {@link Vector}
*/
Vector getTranslatedVector(Vector v, String direction);
/**
* Returns the next Location that a {@link Vehicle} is traveling at.
*
* @param v The {@link Vehicle}
* @return The {@link Location}
*/
Location getNextBlock(Vehicle v);
}
@@ -8,6 +8,8 @@
package com.onarandombox.MultiverseCore.api;
import com.onarandombox.MultiverseCore.utils.PurgeWorlds;
import com.onarandombox.MultiverseCore.utils.SimpleWorldPurger;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.WorldType;
@@ -28,31 +30,35 @@ public interface MVWorldManager {
/**
* Add a new World to the Multiverse Setup.
*
* @param name World Name
* @param env Environment Type
* @param seedString The seed in the form of a string.
* If the seed is a Long,
* it will be interpreted as such.
* @param type The Type of the world to be made.
* @param generator The Custom generator plugin to use.
* @param name World Name
* @param env Environment Type
* @param seedString The seed in the form of a string.
* If the seed is a Long,
* it will be interpreted as such.
* @param type The Type of the world to be made.
* @param generateStructures If true, this world will get NPC villages.
* @param generator The Custom generator plugin to use.
* @return True if the world is added, false if not.
*/
boolean addWorld(String name, Environment env, String seedString, WorldType type, String generator);
boolean addWorld(String name, Environment env, String seedString, WorldType type, Boolean generateStructures,
String generator);
/**
* Add a new World to the Multiverse Setup.
*
* @param name World Name
* @param env Environment Type
* @param seedString The seed in the form of a string.
* If the seed is a Long,
* it will be interpreted as such.
* @param type The Type of the world to be made.
* @param generator The Custom generator plugin to use.
* @param name World Name
* @param env Environment Type
* @param seedString The seed in the form of a string.
* If the seed is a Long,
* it will be interpreted as such.
* @param type The Type of the world to be made.
* @param generateStructures If true, this world will get NPC villages.
* @param generator The Custom generator plugin to use.
* @param useSpawnAdjust If true, multiverse will search for a safe spawn. If not, It will not modify the level.dat.
* @return True if the world is added, false if not.
*/
boolean addWorld(String name, Environment env, String seedString, WorldType type, String generator, boolean useSpawnAdjust);
boolean addWorld(String name, Environment env, String seedString, WorldType type, Boolean generateStructures,
String generator, boolean useSpawnAdjust);
/**
* Remove the world from the Multiverse list, from the
@@ -168,9 +174,21 @@ public interface MVWorldManager {
* Return the World Purger.
*
* @return A valid {@link PurgeWorlds}.
* @deprecated {@link PurgeWorlds} is deprecated!
*/
@Deprecated
PurgeWorlds getWorldPurger();
/**
* Gets the {@link WorldPurger}.
* <p>
* TODO: Remove {@link #getWorldPurger()} and replace it with this method.
* @return The {@link WorldPurger} this {@link MVWorldManager} is using.
* @see WorldPurger
* @see SimpleWorldPurger
*/
WorldPurger getTheWorldPurger();
/**
* Gets the world players will spawn in on first join.
* Currently this always returns worlds.get(0) from Bukkit.
@@ -0,0 +1,136 @@
package com.onarandombox.MultiverseCore.api;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
/**
* The configuration of MultiverseCore.
*/
public interface MultiverseCoreConfig extends ConfigurationSerializable {
/**
* Sets a property using a {@link String}.
* @param property The name of the property.
* @param value The value.
* @return True on success, false if the operation failed.
*/
boolean setProperty(String property, String value);
/**
* Sets portalCooldown.
* @param portalCooldown The new value.
*/
void setTeleportCooldown(int portalCooldown);
/**
* Gets portalCooldown.
* @return portalCooldown.
*/
int getTeleportCooldown();
/**
* Sets firstSpawnWorld.
* @param firstSpawnWorld The new value.
*/
void setFirstSpawnWorld(String firstSpawnWorld);
/**
* Gets firstSpawnWorld.
* @return firstSpawnWorld.
*/
String getFirstSpawnWorld();
/**
* Sets version.
* @param version The new value.
*/
void setVersion(int version);
/**
* Gets version.
* @return version.
*/
double getVersion();
/**
* Sets messageCooldown.
* @param messageCooldown The new value.
*/
void setMessageCooldown(int messageCooldown);
/**
* Gets messageCooldown.
* @return messageCooldown.
*/
int getMessageCooldown();
/**
* Sets globalDebug.
* @param globalDebug The new value.
*/
void setGlobalDebug(int globalDebug);
/**
* Gets globalDebug.
* @return globalDebug.
*/
int getGlobalDebug();
/**
* Sets displayPermErrors.
* @param displayPermErrors The new value.
*/
void setDisplayPermErrors(boolean displayPermErrors);
/**
* Gets displayPermErrors.
* @return displayPermErrors.
*/
boolean getDisplayPermErrors();
/**
* Sets firstSpawnOverride.
* @param firstSpawnOverride The new value.
*/
void setFirstSpawnOverride(boolean firstSpawnOverride);
/**
* Gets firstSpawnOverride.
* @return firstSpawnOverride.
*/
boolean getFirstSpawnOverride();
/**
* Sets teleportIntercept.
* @param teleportIntercept The new value.
*/
void setTeleportIntercept(boolean teleportIntercept);
/**
* Gets teleportIntercept.
* @return teleportIntercept.
*/
boolean getTeleportIntercept();
/**
* Sets prefixChat.
* @param prefixChat The new value.
*/
void setPrefixChat(boolean prefixChat);
/**
* Gets prefixChat.
* @return prefixChat.
*/
boolean getPrefixChat();
/**
* Sets enforceAccess.
* @param enforceAccess The new value.
*/
void setEnforceAccess(boolean enforceAccess);
/**
* Gets enforceAccess.
* @return enforceAccess.
*/
boolean getEnforceAccess();
}
@@ -0,0 +1,56 @@
package com.onarandombox.MultiverseCore.api;
import java.util.Collection;
import org.bukkit.command.CommandSender;
/**
* Multiverse-messaging.
*/
public interface MultiverseMessaging {
/**
* Sets the message-cooldown.
* @param milliseconds The new message-cooldown in milliseconds.
*/
void setCooldown(int milliseconds);
/**
* Sends a message to the specified sender if the cooldown has passed.
*
* @param sender The person/console to send the message to.
* @param message The message to send.
* @param ignoreCooldown If true this message will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
*/
boolean sendMessage(CommandSender sender, String message, boolean ignoreCooldown);
/**
* Sends a group of messages to the specified sender if the cooldown has passed.
* This method is needed, since sending many messages in quick succession would violate
* the cooldown.
*
* @param sender The person/console to send the message to.
* @param messages The messages to send.
* @param ignoreCooldown If true these messages will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
*/
boolean sendMessages(CommandSender sender, String[] messages, boolean ignoreCooldown);
/**
* Sends a group of messages to the specified sender if the cooldown has passed.
* This method is needed, since sending many messages in quick succession would violate
* the cooldown.
*
* @param sender The person/console to send the message to.
* @param messages The messages to send.
* @param ignoreCooldown If true these messages will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
*/
boolean sendMessages(CommandSender sender, Collection<String> messages, boolean ignoreCooldown);
/**
* Gets the message-cooldown.
* @return The message-cooldown.
*/
int getCooldown();
}
@@ -8,6 +8,7 @@
package com.onarandombox.MultiverseCore.api;
import com.onarandombox.MultiverseCore.configuration.MVConfigProperty;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
import org.bukkit.ChatColor;
@@ -573,4 +574,18 @@ public interface MultiverseWorld {
* @return The Type of this world.
*/
WorldType getWorldType();
/**
* Sets The types of portals that are allowed in this world.
*
* @param type The type of portals allowed in this world.
*/
void allowPortalMaking(AllowedPortalType type);
/**
* Gets which type(s) of portals are allowed to be constructed in this world.
*
* @return The type of portals that are allowed.
*/
AllowedPortalType getAllowedPortals();
}
@@ -0,0 +1,71 @@
package com.onarandombox.MultiverseCore.api;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import com.onarandombox.MultiverseCore.enums.TeleportResult;
/**
* Used to safely teleport people.
*/
public interface SafeTTeleporter {
/**
* Gets the next safe location around the given location.
* @param l A {@link Location}.
* @return A safe {@link Location}.
*/
Location getSafeLocation(Location l);
/**
* Gets the next safe location around the given location.
* @param l A {@link Location}.
* @param tolerance The tolerance.
* @param radius The radius.
* @return A safe {@link Location}.
*/
Location getSafeLocation(Location l, int tolerance, int radius);
/**
* Safely teleport the entity to the MVDestination. This will perform checks to see if the place is safe, and if
* it's not, will adjust the final destination accordingly.
*
* @param teleporter Person who performed the teleport command.
* @param teleportee Entity to teleport
* @param d Destination to teleport them to
* @return true for success, false for failure
*/
TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, MVDestination d);
/**
* Safely teleport the entity to the Location. This may perform checks to
* see if the place is safe, and if
* it's not, will adjust the final destination accordingly.
*
* @param teleporter Person who issued the teleport command.
* @param teleportee Entity to teleport.
* @param location Location to teleport them to.
* @param safely Should the destination be checked for safety before teleport?
* @return true for success, false for failure.
*/
TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, Location location,
boolean safely);
/**
* Returns a safe location for the entity to spawn at.
*
* @param e The entity to spawn
* @param d The MVDestination to take the entity to.
* @return A new location to spawn the entity at.
*/
Location getSafeLocation(Entity e, MVDestination d);
/**
* Finds a portal-block next to the specified {@link Location}.
* @param l The {@link Location}
* @return The next portal-block's {@link Location}.
*/
Location findPortalBlockNextTo(Location l);
}
@@ -0,0 +1,49 @@
package com.onarandombox.MultiverseCore.api;
import java.util.List;
import org.bukkit.command.CommandSender;
/**
* Used to remove animals from worlds that don't belong there.
*/
public interface WorldPurger {
/**
* Synchronizes the given world with it's settings.
*
* @param worlds A list of {@link MultiverseWorld}
*/
void purgeWorlds(List<MultiverseWorld> worlds);
/**
* Convenience method for {@link #purgeWorld(CommandSender, MultiverseWorld, List, boolean, boolean)} that takes the settings from the world-config.
*
* @param world The {@link MultiverseWorld}.
*/
void purgeWorld(MultiverseWorld world);
/**
* Clear all animals/monsters that do not belong to a world according to the config.
*
* @param mvworld The {@link MultiverseWorld}.
* @param thingsToKill A {@link List} of animals/monsters to be killed.
* @param negateAnimals Whether the monsters in the list should be negated.
* @param negateMonsters Whether the animals in the list should be negated.
*/
void purgeWorld(MultiverseWorld mvworld, List<String> thingsToKill, boolean negateAnimals,
boolean negateMonsters);
/**
* Clear all animals/monsters that do not belong to a world according to the config.
*
* @param mvworld The {@link MultiverseWorld}.
* @param thingsToKill A {@link List} of animals/monsters to be killed.
* @param negateAnimals Whether the monsters in the list should be negated.
* @param negateMonsters Whether the animals in the list should be negated.
* @param sender The {@link CommandSender} that initiated the action. He will/should be notified.
*/
void purgeWorld(MultiverseWorld mvworld, List<String> thingsToKill, boolean negateAnimals,
boolean negateMonsters, CommandSender sender);
}
@@ -85,6 +85,8 @@ public class AnchorCommand extends PaginatedCoreCommand<String> {
if (filterObject.getPage() > totalPages) {
filterObject.setPage(totalPages);
} else if (filterObject.getPage() < 1) {
filterObject.setPage(1);
}
sender.sendMessage(ChatColor.AQUA + " Page " + filterObject.getPage() + " of " + totalPages);
@@ -98,7 +100,11 @@ public class AnchorCommand extends PaginatedCoreCommand<String> {
this.showList(sender, args);
return;
}
if (args.size() == 2) {
if (args.size() == 1 && (this.getPageAndFilter(args).getPage() != 1 || args.get(0).equals("1"))) {
this.showList(sender, args);
return;
}
if (args.size() == 2 && args.get(1).equalsIgnoreCase("-d")) {
if (this.plugin.getAnchorManager().deleteAnchor(args.get(0))) {
sender.sendMessage("Anchor '" + args.get(0) + "' was successfully " + ChatColor.RED + "deleted!");
} else {
@@ -111,6 +117,7 @@ public class AnchorCommand extends PaginatedCoreCommand<String> {
sender.sendMessage("You must be a player to create Anchors.");
return;
}
Player player = (Player) sender;
if (this.plugin.getAnchorManager().saveAnchorLocation(args.get(0), player.getLocation())) {
sender.sendMessage("Anchor '" + args.get(0) + "' was successfully " + ChatColor.GREEN + "created!");
@@ -8,12 +8,12 @@
package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.enums.ConfigProperty;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.PermissionDefault;
import java.util.List;
import java.util.Map;
/**
* Allows you to set Global MV Variables.
@@ -28,7 +28,6 @@ public class ConfigCommand extends MultiverseCommand {
this.addKey("mvconfig");
this.addKey("mv conf");
this.addKey("mvconf");
this.addCommandExample("All values: " + ConfigProperty.getAllValues());
this.addCommandExample("/mv config show");
this.addCommandExample("/mv config " + ChatColor.GREEN + "debug" + ChatColor.AQUA + " 3");
this.addCommandExample("/mv config " + ChatColor.GREEN + "enforceaccess" + ChatColor.AQUA + " false");
@@ -38,55 +37,31 @@ public class ConfigCommand extends MultiverseCommand {
@Override
public void runCommand(CommandSender sender, List<String> args) {
if (args.size() <= 1) {
String[] allProps = ConfigProperty.getAllValues().split(" ");
String currentvals = "";
for (String prop : allProps) {
currentvals += ChatColor.GREEN;
currentvals += prop;
currentvals += ChatColor.WHITE;
currentvals += " = ";
currentvals += ChatColor.GOLD;
currentvals += this.plugin.getMVConfiguration().get(prop, "NOT SET");
currentvals += ChatColor.WHITE;
currentvals += ", ";
StringBuilder builder = new StringBuilder();
Map<String, Object> serializedConfig = this.plugin.getMVConfig().serialize();
for (Map.Entry<String, Object> entry : serializedConfig.entrySet()) {
builder.append(ChatColor.GREEN);
builder.append(entry.getKey());
builder.append(ChatColor.WHITE).append(" = ").append(ChatColor.GOLD);
builder.append(entry.getValue().toString());
builder.append(ChatColor.WHITE).append(", ");
}
sender.sendMessage(currentvals.substring(0, currentvals.length() - 2));
String message = builder.toString();
message = message.substring(0, message.length() - 2);
sender.sendMessage(message);
return;
}
if (!this.plugin.getMVConfig().setProperty(args.get(0).toLowerCase(), args.get(1))) {
sender.sendMessage(String.format("%sSetting '%s' to '%s' failed!", ChatColor.RED, args.get(0).toLowerCase(), args.get(1)));
return;
}
// special rule
if (args.get(0).equalsIgnoreCase("firstspawnworld")) {
this.plugin.getMVConfiguration().set(args.get(0).toLowerCase(), args.get(1));
// Don't forget to set the world!
this.plugin.getMVWorldManager().setFirstSpawnWorld(args.get(1));
} else if (args.get(0).equalsIgnoreCase("messagecooldown") || args.get(0).equalsIgnoreCase("teleportcooldown")
|| args.get(0).equalsIgnoreCase("debug")) {
try {
this.plugin.getMVConfiguration().set(args.get(0).toLowerCase(), Integer.parseInt(args.get(1)));
} catch (NumberFormatException e) {
sender.sendMessage(ChatColor.RED + "Sorry, " + ChatColor.AQUA + args.get(0) + ChatColor.WHITE + " must be an integer!");
return;
}
} else {
ConfigProperty property = null;
try {
property = ConfigProperty.valueOf(args.get(0).toLowerCase());
} catch (IllegalArgumentException e) {
sender.sendMessage(ChatColor.RED + "Sorry, " + ChatColor.AQUA
+ args.get(0) + ChatColor.WHITE + " you can't set " + ChatColor.AQUA + args.get(0));
sender.sendMessage(ChatColor.GREEN + "Valid values are:");
sender.sendMessage(ConfigProperty.getAllValues());
return;
}
if (property != null) {
try {
this.plugin.getMVConfiguration().set(args.get(0).toLowerCase(), Boolean.parseBoolean(args.get(1)));
} catch (Exception e) {
sender.sendMessage(ChatColor.RED + "Sorry, " + ChatColor.AQUA + args.get(0) + ChatColor.WHITE + " must be true or false!");
return;
}
}
}
if (this.plugin.saveMVConfigs()) {
sender.sendMessage(ChatColor.GREEN + "SUCCESS!" + ChatColor.WHITE + " Values were updated successfully!");
this.plugin.loadConfigs();
@@ -10,7 +10,6 @@ package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.World;
@@ -61,8 +60,8 @@ public class CoordCommand extends MultiverseCommand {
DecimalFormat df = new DecimalFormat();
df.setMinimumFractionDigits(0);
df.setMaximumFractionDigits(2);
p.sendMessage(ChatColor.AQUA + "Coordinates: " + ChatColor.WHITE + LocationManipulation.strCoords(p.getLocation()));
p.sendMessage(ChatColor.AQUA + "Direction: " + ChatColor.WHITE + LocationManipulation.getDirection(p.getLocation()));
p.sendMessage(ChatColor.AQUA + "Coordinates: " + ChatColor.WHITE + plugin.getLocationManipulation().strCoords(p.getLocation()));
p.sendMessage(ChatColor.AQUA + "Direction: " + ChatColor.WHITE + plugin.getLocationManipulation().getDirection(p.getLocation()));
p.sendMessage(ChatColor.AQUA + "Block: " + ChatColor.WHITE + Material.getMaterial(world.getBlockTypeIdAt(p.getLocation())));
} else {
sender.sendMessage("This command needs to be used from a Player.");
@@ -29,8 +29,9 @@ public class CreateCommand extends MultiverseCommand {
public CreateCommand(MultiverseCore plugin) {
super(plugin);
this.setName("Create World");
this.setCommandUsage("/mv create" + ChatColor.GREEN + " {NAME} {ENV}" + ChatColor.GOLD + " -s [SEED] -g [GENERATOR[:ID]] -t [WORLDTYPE] [-n]");
this.setArgRange(2, 9); // SUPPRESS CHECKSTYLE: MagicNumberCheck
this.setCommandUsage(String.format("/mv create %s{NAME} {ENV} %s-s [SEED] -g [GENERATOR[:ID]] -t [WORLDTYPE] [-n] -a [true|false]",
ChatColor.GREEN, ChatColor.GOLD));
this.setArgRange(2, 11); // SUPPRESS CHECKSTYLE: MagicNumberCheck
this.addKey("mvcreate");
this.addKey("mvc");
this.addKey("mv create");
@@ -51,6 +52,11 @@ public class CreateCommand extends MultiverseCommand {
String env = args.get(1);
String seed = CommandHandler.getFlag("-s", args);
String generator = CommandHandler.getFlag("-g", args);
boolean allowStructures = true;
String structureString = CommandHandler.getFlag("-a", args);
if (structureString != null) {
allowStructures = Boolean.parseBoolean(structureString);
}
String typeString = CommandHandler.getFlag("-t", args);
boolean useSpawnAdjust = true;
for (String s : args) {
@@ -58,6 +64,7 @@ public class CreateCommand extends MultiverseCommand {
useSpawnAdjust = false;
}
}
if (worldFile.exists() || this.worldManager.isMVWorld(worldName)) {
sender.sendMessage(ChatColor.RED + "A Folder/World already exists with this name!");
sender.sendMessage(ChatColor.RED + "If you are confident it is a world you can import with /mvimport");
@@ -84,7 +91,7 @@ public class CreateCommand extends MultiverseCommand {
Command.broadcastCommandMessage(sender, "Starting creation of world '" + worldName + "'...");
if (this.worldManager.addWorld(worldName, environment, seed, type, generator, useSpawnAdjust)) {
if (this.worldManager.addWorld(worldName, environment, seed, type, allowStructures, generator, useSpawnAdjust)) {
Command.broadcastCommandMessage(sender, "Complete!");
} else {
Command.broadcastCommandMessage(sender, "FAILED.");
@@ -36,14 +36,14 @@ public class DebugCommand extends MultiverseCommand {
public void runCommand(CommandSender sender, List<String> args) {
if (args.size() == 1) {
if (args.get(0).equalsIgnoreCase("off")) {
MultiverseCore.GlobalDebug = 0;
plugin.getMVConfig().setGlobalDebug(0);
} else {
try {
int debugLevel = Integer.parseInt(args.get(0));
if (debugLevel > 3 || debugLevel < 0) {
throw new NumberFormatException();
}
MultiverseCore.GlobalDebug = debugLevel;
plugin.getMVConfig().setGlobalDebug(debugLevel);
} catch (NumberFormatException e) {
sender.sendMessage(ChatColor.RED + "Error" + ChatColor.WHITE
+ " setting debug level. Please use a number 0-3 " + ChatColor.AQUA + "(3 being many many messages!)");
@@ -55,10 +55,10 @@ public class DebugCommand extends MultiverseCommand {
}
private void displayDebugMode(CommandSender sender) {
if (MultiverseCore.GlobalDebug == 0) {
if (plugin.getMVConfig().getGlobalDebug() == 0) {
sender.sendMessage("Multiverse Debug mode is " + ChatColor.RED + "OFF");
} else {
sender.sendMessage("Multiverse Debug mode is " + ChatColor.GREEN + MultiverseCore.GlobalDebug);
sender.sendMessage("Multiverse Debug mode is " + ChatColor.GREEN + plugin.getMVConfig().getGlobalDebug());
this.plugin.log(Level.FINE, "Multiverse Debug ENABLED");
}
}
@@ -91,6 +91,7 @@ public class EnvironmentCommand extends MultiverseCommand {
* @return The environment as {@link org.bukkit.World.Environment}
*/
public static World.Environment getEnvFromString(String env) {
env = env.toUpperCase();
// Don't reference the enum directly as there aren't that many, and we can be more forgiving to users this way
if (env.equalsIgnoreCase("HELL") || env.equalsIgnoreCase("NETHER"))
env = "NETHER";
@@ -33,14 +33,14 @@ public class ImportCommand extends MultiverseCommand {
public ImportCommand(MultiverseCore plugin) {
super(plugin);
this.setName("Import World");
this.setCommandUsage("/mv import" + ChatColor.GREEN + " {NAME} {ENV} " + ChatColor.GOLD + " -g [GENERATOR[:ID]] [-n] -t [TYPE]");
this.setArgRange(2, 5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
this.setCommandUsage("/mv import" + ChatColor.GREEN + " {NAME} {ENV}" + ChatColor.GOLD + " -g [GENERATOR[:ID]] [-n]");
this.setArgRange(1, 5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
this.addKey("mvimport");
this.addKey("mvim");
this.addKey("mv import");
this.addCommandExample("/mv import " + ChatColor.GOLD + "gargamel" + ChatColor.GREEN + " normal");
this.addCommandExample("/mv import " + ChatColor.GOLD + "flatroom" + ChatColor.GREEN + " normal" + ChatColor.AQUA + " -t flat");
this.addCommandExample("/mv import " + ChatColor.GOLD + "hell_world" + ChatColor.GREEN + " nether");
this.addCommandExample("To import a world that uses a generator, you'll need the generator:");
this.addCommandExample("/mv import " + ChatColor.GOLD + "CleanRoom" + ChatColor.GREEN + " normal" + ChatColor.DARK_AQUA + " CleanRoomGenerator");
this.setPermission("multiverse.core.import", "Imports a new world of the specified type.", PermissionDefault.OP);
this.worldManager = this.plugin.getMVWorldManager();
@@ -128,7 +128,6 @@ public class ImportCommand extends MultiverseCommand {
File worldFile = new File(this.plugin.getServer().getWorldContainer(), worldName);
String generator = CommandHandler.getFlag("-g", args);
String typeString = CommandHandler.getFlag("-t", args);
boolean useSpawnAdjust = true;
for (String s : args) {
if (s.equalsIgnoreCase("-n")) {
@@ -144,20 +143,9 @@ public class ImportCommand extends MultiverseCommand {
return;
}
// If they didn't specify a type, default to NORMAL
if (typeString == null) {
typeString = "NORMAL";
}
WorldType type = EnvironmentCommand.getWorldTypeFromString(typeString);
if (type == null) {
sender.sendMessage(ChatColor.RED + "That is not a valid World Type.");
EnvironmentCommand.showWorldTypes(sender);
return;
}
if (worldFile.exists() && env != null) {
Command.broadcastCommandMessage(sender, String.format("Starting import of world '%s'...", worldName));
if (this.worldManager.addWorld(worldName, environment, null, type, generator, useSpawnAdjust))
if (this.worldManager.addWorld(worldName, environment, null, null, null, generator, useSpawnAdjust))
Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Complete!");
else
Command.broadcastCommandMessage(sender, ChatColor.RED + "Failed!");
@@ -14,7 +14,6 @@ import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.FancyColorScheme;
import com.onarandombox.MultiverseCore.utils.FancyHeader;
import com.onarandombox.MultiverseCore.utils.FancyMessage;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
@@ -62,9 +61,13 @@ public class InfoCommand extends MultiverseCommand {
return;
}
} else if (args.size() == 1) {
if (this.worldManager.getMVWorld(args.get(0)) != null) {
if (this.worldManager.isMVWorld(args.get(0))) {
// then we have a world!
worldName = args.get(0);
} else if (this.worldManager.getUnloadedWorlds().contains(args.get(0))) {
sender.sendMessage("That world exists, but it is unloaded!");
sender.sendMessage(String.format("You can load it with: %s/mv load %s", ChatColor.AQUA, args.get(0)));
return;
} else {
if (sender instanceof Player) {
Player p = (Player) sender;
@@ -94,8 +97,11 @@ public class InfoCommand extends MultiverseCommand {
p = (Player) sender;
}
showPage(pageNum, sender, this.buildEntireCommand(this.worldManager.getMVWorld(worldName), p));
} else if (this.worldManager.getUnloadedWorlds().contains(worldName)) {
sender.sendMessage("That world exists, but it is unloaded!");
sender.sendMessage(String.format("You can load it with: %s/mv load %s", ChatColor.AQUA, worldName));
} else if (this.plugin.getServer().getWorld(worldName) != null) {
sender.sendMessage("That world exists, but multiverse does not know about it!");
sender.sendMessage("That world exists, but Multiverse does not know about it!");
sender.sendMessage("You can import it with" + ChatColor.AQUA + "/mv import " + ChatColor.GREEN + worldName + ChatColor.LIGHT_PURPLE + "{ENV}");
sender.sendMessage("For available environments type " + ChatColor.GREEN + "/mv env");
}
@@ -110,10 +116,11 @@ public class InfoCommand extends MultiverseCommand {
message.add(new FancyMessage("World Name: ", world.getName(), colors));
message.add(new FancyMessage("World Alias: ", world.getColoredWorldString(), colors));
message.add(new FancyMessage("Game Mode: ", world.getGameMode().toString(), colors));
message.add(new FancyMessage("World Type: ", world.getWorldType().toString(), colors));
message.add(new FancyMessage("Difficulty: ", world.getDifficulty().toString(), colors));
//message.add(new FancyMessage("Game Mode: ", StringUtils.capitalize(world.getGameMode().toString()), colors));
Location spawn = world.getSpawnLocation();
message.add(new FancyMessage("Spawn Location: ", LocationManipulation.strCoords(spawn), colors));
message.add(new FancyMessage("Spawn Location: ", plugin.getLocationManipulation().strCoords(spawn), colors));
message.add(new FancyMessage("World Scale: ", world.getScaling() + "", colors));
if (world.getPrice() > 0) {
message.add(new FancyMessage("Price to enter this world: ",
@@ -136,7 +143,8 @@ public class InfoCommand extends MultiverseCommand {
// Page 2
message = new ArrayList<FancyText>();
message.add(new FancyHeader("More World Settings", colors));
message.add(new FancyMessage("Difficulty: ", world.getDifficulty().toString(), colors));
message.add(new FancyMessage("World Type: ", world.getWorldType().toString(), colors));
message.add(new FancyMessage("Structures: ", world.getCBWorld().canGenerateStructures() + "", colors));
message.add(new FancyMessage("Weather: ", world.isWeatherEnabled() + "", colors));
message.add(new FancyMessage("Players will get hungry: ", world.getHunger() + "", colors));
message.add(new FancyMessage("Keep spawn in memory: ", world.isKeepingSpawnInMemory() + "", colors));
@@ -52,14 +52,16 @@ public class ListCommand extends PaginatedCoreCommand<String> {
} else if (env == Environment.THE_END) {
color = ChatColor.AQUA;
}
String outputCache = world.getColoredWorldString() + ChatColor.WHITE + " - " + color + world.getEnvironment();
StringBuilder builder = new StringBuilder();
builder.append(world.getColoredWorldString()).append(ChatColor.WHITE);
builder.append(" - ").append(color).append(world.getEnvironment());
if (world.isHidden()) {
if (p == null || p.hasPermission("multiverse.core.modify")) {
if (p == null || this.plugin.getMVPerms().hasPermission(p, "multiverse.core.modify", true)) {
// Prefix hidden worlds with an "[H]"
worldList.add(ChatColor.GRAY + "[H]" + outputCache);
worldList.add(ChatColor.GRAY + "[H]" + builder.toString());
}
} else {
worldList.add(outputCache);
worldList.add(builder.toString());
}
}
for (String name : this.plugin.getMVWorldManager().getUnloadedWorlds()) {
@@ -8,7 +8,7 @@
package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.utils.MVMessaging;
import com.onarandombox.MultiverseCore.api.MultiverseMessaging;
import com.pneumaticraft.commandhandler.Command;
import org.bukkit.command.CommandSender;
@@ -24,9 +24,9 @@ public abstract class MultiverseCommand extends Command {
*/
protected MultiverseCore plugin;
/**
* The reference to {@link MVMessaging}.
* The reference to {@link MultiverseMessaging}.
*/
protected MVMessaging messaging;
protected MultiverseMessaging messaging;
public MultiverseCommand(MultiverseCore plugin) {
super(plugin);
@@ -10,7 +10,7 @@ package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.PurgeWorlds;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@@ -78,7 +78,7 @@ public class PurgeCommand extends MultiverseCommand {
worldsToRemoveEntitiesFrom.add(this.worldManager.getMVWorld(worldName));
}
PurgeWorlds purger = this.worldManager.getWorldPurger();
WorldPurger purger = this.worldManager.getTheWorldPurger();
ArrayList<String> thingsToKill = new ArrayList<String>();
if (deathName.equalsIgnoreCase("all") || deathName.equalsIgnoreCase("animals") || deathName.equalsIgnoreCase("monsters")) {
thingsToKill.add(deathName.toUpperCase());
@@ -86,7 +86,7 @@ public class PurgeCommand extends MultiverseCommand {
Collections.addAll(thingsToKill, deathName.toUpperCase().split(","));
}
for (MultiverseWorld w : worldsToRemoveEntitiesFrom) {
purger.purgeWorld(sender, w, thingsToKill, false, false);
purger.purgeWorld(w, thingsToKill, false, false, sender);
}
}
}
@@ -8,9 +8,8 @@
package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.BlockSafety;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
@@ -56,7 +55,7 @@ public class SetSpawnCommand extends MultiverseCommand {
MultiverseWorld foundWorld = this.plugin.getMVWorldManager().getMVWorld(w.getName());
if (foundWorld != null) {
foundWorld.setSpawnLocation(p.getLocation());
BlockSafety bs = new BlockSafety();
BlockSafety bs = this.plugin.getBlockSafety();
if (!bs.playerCanSpawnHereSafely(p.getLocation()) && foundWorld.getAdjustSpawn()) {
sender.sendMessage("It looks like that location would normally be unsafe. But I trust you.");
sender.sendMessage("I'm turning off the Safe-T-Teleporter for spawns to this world.");
@@ -64,7 +63,7 @@ public class SetSpawnCommand extends MultiverseCommand {
sender.sendMessage(ChatColor.AQUA + "/mvm set adjustspawn true " + foundWorld.getAlias());
foundWorld.setAdjustSpawn(false);
}
sender.sendMessage("Spawn was set to: " + LocationManipulation.strCoords(p.getLocation()));
sender.sendMessage("Spawn was set to: " + plugin.getLocationManipulation().strCoords(p.getLocation()));
} 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).");
@@ -85,6 +85,6 @@ public class SpawnCommand extends MultiverseCommand {
} else {
spawnLocation = player.getWorld().getSpawnLocation();
}
this.plugin.getTeleporter().safelyTeleport(player, player, spawnLocation, false);
this.plugin.getSafeTTeleporter().safelyTeleport(player, player, spawnLocation, false);
}
}
@@ -14,8 +14,7 @@ import com.onarandombox.MultiverseCore.destination.InvalidDestination;
import com.onarandombox.MultiverseCore.destination.WorldDestination;
import com.onarandombox.MultiverseCore.enums.TeleportResult;
import com.onarandombox.MultiverseCore.event.MVTeleportEvent;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import com.onarandombox.MultiverseCore.utils.SafeTTeleporter;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
@@ -43,7 +42,7 @@ public class TeleportCommand extends MultiverseCommand {
this.setArgRange(1, 2);
this.addKey("mvtp");
this.addKey("mv tp");
this.playerTeleporter = new SafeTTeleporter(this.plugin);
this.playerTeleporter = this.plugin.getSafeTTeleporter();
this.setPermission(menu);
}
@@ -111,7 +110,7 @@ public class TeleportCommand extends MultiverseCommand {
return;
}
if (MultiverseCore.EnforceAccess && teleporter != null && !this.plugin.getMVPerms().canEnterDestination(teleporter, d)) {
if (plugin.getMVConfig().getEnforceAccess() && teleporter != null && !this.plugin.getMVPerms().canEnterDestination(teleporter, d)) {
if (teleportee.equals(teleporter)) {
teleporter.sendMessage("Doesn't look like you're allowed to go " + ChatColor.RED + "there...");
} else {
@@ -163,7 +162,8 @@ public class TeleportCommand extends MultiverseCommand {
}
TeleportResult result = this.playerTeleporter.safelyTeleport(teleporter, teleportee, d);
if (result == TeleportResult.FAIL_UNSAFE) {
this.plugin.log(Level.FINE, "Could not teleport " + teleportee.getName() + " to " + LocationManipulation.strCoordsRaw(d.getLocation(teleportee)));
this.plugin.log(Level.FINE, "Could not teleport " + teleportee.getName()
+ " to " + plugin.getLocationManipulation().strCoordsRaw(d.getLocation(teleportee)));
this.plugin.log(Level.FINE, "Queueing Command");
Class<?>[] paramTypes = { CommandSender.class, Player.class, Location.class };
List<Object> items = new ArrayList<Object>();
@@ -53,16 +53,16 @@ public class VersionCommand extends MultiverseCommand {
buffer.append("[Multiverse-Core] Economy being used: ").append(this.plugin.getBank().getEconUsed()).append('\n');
buffer.append("[Multiverse-Core] Permissions Plugin: ").append(this.plugin.getMVPerms().getType()).append('\n');
buffer.append("[Multiverse-Core] Dumping Config Values: (version ")
.append(this.plugin.getMVConfiguration().getDouble("version", -1)).append(")").append('\n');
buffer.append("[Multiverse-Core] messagecooldown: ").append(this.plugin.getMessaging().getCooldown()).append('\n');
buffer.append("[Multiverse-Core] teleportcooldown: ").append("Not yet IMPLEMENTED").append('\n');
buffer.append("[Multiverse-Core] worldnameprefix: ").append(MultiverseCore.PrefixChat).append('\n');
buffer.append("[Multiverse-Core] enforceaccess: ").append(MultiverseCore.EnforceAccess).append('\n');
buffer.append("[Multiverse-Core] displaypermerrors: ").append(MultiverseCore.DisplayPermErrors).append('\n');
buffer.append("[Multiverse-Core] teleportintercept: ").append(MultiverseCore.TeleportIntercept).append('\n');
buffer.append("[Multiverse-Core] firstspawnoverride: ").append(MultiverseCore.FirstSpawnOverride).append('\n');
buffer.append("[Multiverse-Core] firstspawnworld: ").append(this.plugin.getMVConfiguration().getString("firstspawnworld", "NOT SET")).append('\n');
buffer.append("[Multiverse-Core] debug: ").append(MultiverseCore.GlobalDebug).append('\n');
.append(this.plugin.getMVConfig().getVersion()).append(")").append('\n');
buffer.append("[Multiverse-Core] messagecooldown: ").append(plugin.getMessaging().getCooldown()).append('\n');
buffer.append("[Multiverse-Core] teleportcooldown: ").append(plugin.getMVConfig().getTeleportCooldown()).append('\n');
buffer.append("[Multiverse-Core] worldnameprefix: ").append(plugin.getMVConfig().getPrefixChat()).append('\n');
buffer.append("[Multiverse-Core] enforceaccess: ").append(plugin.getMVConfig().getEnforceAccess()).append('\n');
buffer.append("[Multiverse-Core] displaypermerrors: ").append(plugin.getMVConfig().getDisplayPermErrors()).append('\n');
buffer.append("[Multiverse-Core] teleportintercept: ").append(plugin.getMVConfig().getTeleportIntercept()).append('\n');
buffer.append("[Multiverse-Core] firstspawnoverride: ").append(plugin.getMVConfig().getFirstSpawnOverride()).append('\n');
buffer.append("[Multiverse-Core] firstspawnworld: ").append(plugin.getMVConfig().getFirstSpawnWorld()).append('\n');
buffer.append("[Multiverse-Core] debug: ").append(plugin.getMVConfig().getGlobalDebug()).append('\n');
buffer.append("[Multiverse-Core] Special Code: FRN002").append('\n');
MVVersionEvent versionEvent = new MVVersionEvent(buffer.toString());
@@ -7,6 +7,7 @@
package com.onarandombox.MultiverseCore.configuration;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import com.onarandombox.MultiverseCore.enums.EnglishChatColor;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
@@ -233,9 +234,9 @@ public class ConfigPropertyFactory {
return new GameModeConfigProperty(this.section, name, defaultValue, node, help);
}
// GameMode
// Location
/**
* Constructs a new ConfigProperty.
* Constructs a new LocationConfigProperty.
*
* @param name The name of this ConfigProperty.
* @param defaultValue The default-value.
@@ -273,6 +274,19 @@ public class ConfigPropertyFactory {
return new LocationConfigProperty(this.section, name, defaultValue, node, help, method);
}
// GameMode
/**
* Constructs a new ConfigProperty.
*
* @param name The name of this ConfigProperty.
* @param defaultValue The default-value.
* @param help The text that's displayed when a user failed to set the property.
* @return The ConfigProperty.
*/
public PortalTypeConfigProperty getNewProperty(String name, AllowedPortalType defaultValue, String help) {
return new PortalTypeConfigProperty(this.section, name, defaultValue, help);
}
/**
* Constructs a new ActiveStringConfigProperty
*
@@ -61,6 +61,7 @@ public class LocationConfigProperty implements MVActiveConfigProperty<Location>
*/
@Override
public boolean parseValue(String value) {
// TODO: oh my god, what should we do here?
Location parsed = LocationManipulation.stringToLocation(value);
return this.setValue(parsed);
}
@@ -108,6 +109,7 @@ public class LocationConfigProperty implements MVActiveConfigProperty<Location>
double yaw = this.section.getDouble(this.configNode + ".yaw", defaultValue.getYaw());
String w = this.section.getString(this.configNode + ".world", defaultValue.getWorld().getName());
Location found = LocationManipulation.stringToLocation(w + ":" + x + "," + y + "," + z + ":" + yaw + ":" + pitch);
// TODO: oh my god, what should we do here?
if (found != null) {
return found;
}
@@ -116,6 +118,7 @@ public class LocationConfigProperty implements MVActiveConfigProperty<Location>
@Override
public String toString() {
// TODO: oh my god, what should we do here?
return LocationManipulation.strCoordsRaw(this.value);
}
@@ -23,7 +23,8 @@ import java.util.logging.Level;
*/
/**
* @deprecated This isn't used any more, is it?
* This will be gone in 2.4.
* @deprecated This isn't used any more, is it? No. No it is not.
*/
@Deprecated
public abstract class MVConfigMigrator {
@@ -0,0 +1,97 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2012. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.configuration;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import org.bukkit.configuration.ConfigurationSection;
/**
* A {@link AllowedPortalType} config-property.
*/
public class PortalTypeConfigProperty implements MVConfigProperty<AllowedPortalType> {
private String name;
private AllowedPortalType value;
private String configNode;
private ConfigurationSection section;
private String help;
public PortalTypeConfigProperty(ConfigurationSection section, String name, AllowedPortalType defaultValue, String help) {
this(section, name, defaultValue, name, help);
}
public PortalTypeConfigProperty(ConfigurationSection section, String name, AllowedPortalType defaultValue, String configNode, String help) {
this.name = name;
this.configNode = configNode;
this.section = section;
this.help = help;
this.value = defaultValue;
this.parseValue(this.section.getString(this.configNode, defaultValue.toString()));
}
/**
* {@inheritDoc}
*/
@Override
public String getName() {
return this.name;
}
/**
* {@inheritDoc}
*/
@Override
public AllowedPortalType getValue() {
return this.value;
}
/**
* {@inheritDoc}
*/
@Override
public boolean setValue(AllowedPortalType value) {
if (value == null) {
return false;
}
this.value = value;
this.section.set(configNode, this.value.toString());
return true;
}
/**
* {@inheritDoc}
*/
@Override
public boolean parseValue(String value) {
try {
return this.setValue(AllowedPortalType.valueOf(value.toUpperCase()));
} catch (Exception e) {
return false;
}
}
/**
* {@inheritDoc}
*/
@Override
public String getConfigNode() {
return this.configNode;
}
/**
* {@inheritDoc}
*/
@Override
public String getHelp() {
return this.help;
}
@Override
public String toString() {
return value.toString();
}
}
@@ -8,9 +8,9 @@
package com.onarandombox.MultiverseCore.destination;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.Core;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.java.JavaPlugin;
@@ -93,6 +93,9 @@ public class WorldDestination implements MVDestination {
*/
@Override
public void setDestination(JavaPlugin plugin, String destination) {
// TODO Taking a JavaPlugin here is rather useless, if we keep casting it up to MultiverseCore.
// We should change that.
Core core = (Core) plugin;
String[] items = destination.split(":");
if (items.length > 3) {
isValid = false;
@@ -100,19 +103,20 @@ public class WorldDestination implements MVDestination {
}
if (items.length == 1 && ((MultiverseCore) plugin).getMVWorldManager().isMVWorld(items[0])) {
isValid = true;
this.world = ((MultiverseCore) plugin).getMVWorldManager().getMVWorld(items[0]);
this.world = core.getMVWorldManager().getMVWorld(items[0]);
return;
}
if (items.length == 2 && ((MultiverseCore) plugin).getMVWorldManager().isMVWorld(items[0])) {
this.world = ((MultiverseCore) plugin).getMVWorldManager().getMVWorld(items[0]);
this.yaw = LocationManipulation.getYaw(items[1]);
this.world = core.getMVWorldManager().getMVWorld(items[0]);
this.yaw = core.getLocationManipulation().getYaw(items[1]);
return;
}
if (items[0].equalsIgnoreCase("w") && ((MultiverseCore) plugin).getMVWorldManager().isMVWorld(items[1])) {
this.world = ((MultiverseCore) plugin).getMVWorldManager().getMVWorld(items[1]);
isValid = true;
if (items.length == 3) {
this.yaw = LocationManipulation.getYaw(items[2]);
// TODO: oh my god, what should we do here?
this.yaw = core.getLocationManipulation().getYaw(items[2]);
}
}
}
@@ -0,0 +1,46 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2012. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.enums;
import org.bukkit.PortalType;
/**
* Custom enum that adds all/none for allowing portal creation.
*/
public enum AllowedPortalType {
/**
* No portals are allowed.
*/
NONE(PortalType.CUSTOM),
/**
* All portal types are allowed.
*/
ALL(PortalType.CUSTOM),
/**
* Only Nether style portals are allowed.
*/
NETHER(PortalType.NETHER),
/**
* Only Ender style portals are allowed.
*/
END(PortalType.ENDER);
private PortalType type;
AllowedPortalType(PortalType type) {
this.type = type;
}
/**
* Gets the text.
* @return The text.
*/
public PortalType getActualPortalType() {
return this.type;
}
}
@@ -1,64 +0,0 @@
/******************************************************************************
* 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.enums;
/**
* An enum containing all config-properties that can be set.
*/
public enum ConfigProperty {
/**
* How long to leave in between sending a message to the player. (NOT YET IMPLEMENTED)
*/
messagecooldown,
/**
* How fast are people allowed to use /MVTP (NOT YET IMPLEMENTED).
*/
teleportcooldown,
/**
* Prefix chat-messages with world-names.
*/
worldnameprefix,
/**
* If value is set to false, Multiverse will NOT enforce world access permissions.
*/
enforceaccess,
/**
* Whether users should get detailed information about the permissions they would need.
*/
displaypermerrors,
/**
* Debug-information.
*/
debug,
/**
* The world new users will spawn in.
*/
firstspawnworld,
/**
* Whether Multiverse should intercept teleports.
*/
teleportintercept,
/**
* Whether Multiverse should override the first spawn.
*/
firstspawnoverride;
/**
* Constructs a string containing all values in this enum.
*
* @return That {@link String}.
*/
public static String getAllValues() {
String buffer = "";
for (ConfigProperty c : ConfigProperty.values()) {
// All values will NOT Contain spaces.
buffer += c.toString() + " ";
}
return buffer;
}
}
@@ -8,6 +8,7 @@
package com.onarandombox.MultiverseCore.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import java.util.List;
@@ -23,6 +24,24 @@ public class MVConfigReloadEvent extends Event {
this.configsLoaded = configsLoaded;
}
private static final HandlerList HANDLERS = new HandlerList();
/**
* {@inheritDoc}
*/
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
/**
* Gets the handler list. This is required by the event system.
* @return A list of HANDLERS.
*/
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* Adds a config to this event.
* @param config The config to add.
@@ -11,6 +11,7 @@ import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* This event is thrown when a portal is touched.
@@ -26,6 +27,24 @@ public class MVPlayerTouchedPortalEvent extends Event implements Cancellable {
this.l = l;
}
private static final HandlerList HANDLERS = new HandlerList();
/**
* {@inheritDoc}
*/
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
/**
* Gets the handler list. This is required by the event system.
* @return A list of HANDLERS.
*/
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* Gets the {@link Location} of the portal-block that was touched.
* @return The {@link Location} of the portal-block that was touched.
@@ -10,6 +10,7 @@ package com.onarandombox.MultiverseCore.event;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when a player is respawning.
@@ -27,6 +28,24 @@ public class MVRespawnEvent extends Event {
this.respawnMethod = respawnMethod;
}
private static final HandlerList HANDLERS = new HandlerList();
/**
* {@inheritDoc}
*/
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
/**
* Gets the handler list. This is required by the event system.
* @return A list of HANDLERS.
*/
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* Gets the {@link Player} that's respawning.
* @return The {@link Player} that's respawning.
@@ -8,12 +8,14 @@
package com.onarandombox.MultiverseCore.event;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Event that gets called when a player use the /mvtp command.
@@ -33,6 +35,24 @@ public class MVTeleportEvent extends Event implements Cancellable {
this.useSafeTeleport = safeTeleport;
}
private static final HandlerList HANDLERS = new HandlerList();
/**
* {@inheritDoc}
*/
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
/**
* Gets the handler list. This is required by the event system.
* @return A list of HANDLERS.
*/
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* Returns the player who will be teleported by this event.
*
@@ -1,6 +1,7 @@
package com.onarandombox.MultiverseCore.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Called when somebody requests version information about Multiverse.
@@ -14,6 +15,24 @@ public class MVVersionEvent extends Event {
versionInfoBuilder = new StringBuilder(versionInfo);
}
private static final HandlerList HANDLERS = new HandlerList();
/**
* {@inheritDoc}
*/
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
/**
* Gets the handler list. This is required by the event system.
* @return A list of HANDLERS.
*/
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* Gets the version-info currently saved in this event.
* @return The version-info.
@@ -1,45 +0,0 @@
/******************************************************************************
* 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.event;
import org.bukkit.event.Event;
/**
* Called when somebody requests version information about Multiverse.
* @deprecated Use {@link MVVersionEvent} instead.
*/
@Deprecated
public class MVVersionRequestEvent extends Event {
private String pasteBinBuffer;
public MVVersionRequestEvent(String pasteBinBuffer) {
super("MVVersion");
this.pasteBinBuffer = pasteBinBuffer;
}
/**
* Gets the pasteBinBuffer.
* @return The pasteBinBuffer.
* @deprecated Use {@link MVVersionEvent} instead.
*/
@Deprecated
public String getPasteBinBuffer() {
return this.pasteBinBuffer;
}
/**
* Sets the pasteBinBuffer.
* @param buffer The new pasteBinBuffer.
* @deprecated Use {@link MVVersionEvent} instead.
*/
@Deprecated
public void setPasteBinBuffer(String buffer) {
this.pasteBinBuffer = buffer;
}
}
@@ -4,6 +4,7 @@ import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import org.bukkit.event.HandlerList;
/**
* Called when a world is about to be deleted by Multiverse.
@@ -24,6 +25,24 @@ public class MVWorldDeleteEvent extends Event implements Cancellable {
this.removeFromConfig = removeFromConfig;
}
private static final HandlerList HANDLERS = new HandlerList();
/**
* {@inheritDoc}
*/
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
/**
* Gets the handler list. This is required by the event system.
* @return A list of HANDLERS.
*/
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* {@inheritDoc}
*/
@@ -11,6 +11,7 @@ import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import org.bukkit.command.CommandSender;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* This event is fired *before* the property is actually changed.
@@ -27,7 +28,6 @@ public class MVWorldPropertyChangeEvent extends Event implements Cancellable {
private String value;
private String name;
public MVWorldPropertyChangeEvent(MultiverseWorld world, CommandSender changer, String name, String value) {
super("MVWorldPropertyChange");
this.world = world;
@@ -36,6 +36,24 @@ public class MVWorldPropertyChangeEvent extends Event implements Cancellable {
this.value = value;
}
private static final HandlerList HANDLERS = new HandlerList();
/**
* {@inheritDoc}
*/
@Override
public HandlerList getHandlers() {
return HANDLERS;
}
/**
* Gets the handler list. This is required by the event system.
* @return A list of handlers.
*/
public static HandlerList getHandlerList() {
return HANDLERS;
}
/**
* Gets the changed world property's name.
* @return The changed world property's name.
@@ -85,8 +85,8 @@ public class MVEntityListener implements Listener {
*/
@EventHandler
public void creatureSpawn(CreatureSpawnEvent event) {
// Check to see if the Creature is spawned by a plugin, we don't want to prevent this behaviour.
// TODO: Implement MONSTER_EGG when it becomes available.
if (event.getSpawnReason() == SpawnReason.CUSTOM) {
return;
}
@@ -12,7 +12,6 @@ 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 com.onarandombox.MultiverseCore.utils.SafeTTeleporter;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
@@ -56,7 +55,7 @@ public class MVPlayerListener implements Listener {
}
// Check whether the Server is set to prefix the chat with the World name.
// If not we do nothing, if so we need to check if the World has an Alias.
if (MultiverseCore.PrefixChat) {
if (plugin.getMVConfig().getPrefixChat()) {
String world = event.getPlayer().getWorld().getName();
String prefix = "";
// If we're not a MV world, don't do anything
@@ -128,7 +127,7 @@ public class MVPlayerListener implements Listener {
Player p = event.getPlayer();
if (!p.hasPlayedBefore()) {
this.plugin.log(Level.FINE, "Player joined first!");
if (MultiverseCore.FirstSpawnOverride) {
if (plugin.getMVConfig().getFirstSpawnOverride()) {
this.plugin.log(Level.FINE, "Moving NEW player to(firstspawnoverride): " + worldManager.getFirstSpawnWorld().getSpawnLocation());
this.spawnNewPlayer(p);
}
@@ -198,7 +197,7 @@ public class MVPlayerListener implements Listener {
teleportee.getName(), event.getTo().getWorld().getName(), teleporter.getName()));
return;
}
if (MultiverseCore.EnforceAccess) {
if (plugin.getMVConfig().getEnforceAccess()) {
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, teleporter, teleportee));
if (event.isCancelled() && teleporter != null) {
this.plugin.log(Level.FINE, String.format("Player '%s' was DENIED ACCESS to '%s' because '%s' don't have: multiverse.access.%s",
@@ -225,7 +224,7 @@ public class MVPlayerListener implements Listener {
// REMEMBER! getTo MAY be NULL HERE!!!
// If the player was actually outside of the portal, adjust the from location
if (event.getFrom().getWorld().getBlockAt(event.getFrom()).getType() != Material.PORTAL) {
Location newloc = SafeTTeleporter.findPortalBlockNextTo(event.getFrom());
Location newloc = this.plugin.getSafeTTeleporter().findPortalBlockNextTo(event.getFrom());
// TODO: Fix this. Currently, we only check for PORTAL blocks. I'll have to figure out what
// TODO: we want to do here.
if (newloc != null) {
@@ -263,7 +262,7 @@ public class MVPlayerListener implements Listener {
event.getPlayer().getName(), event.getTo().getWorld().getName()));
return;
}
if (MultiverseCore.EnforceAccess) {
if (plugin.getMVConfig().getEnforceAccess()) {
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, event.getPlayer(), event.getPlayer()));
if (event.isCancelled()) {
this.plugin.log(Level.FINE, String.format("Player '%s' was DENIED ACCESS to '%s' because they don't have: multiverse.access.%s",
@@ -309,7 +308,7 @@ public class MVPlayerListener implements Listener {
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()) {
MultiverseCore.staticLog(Level.FINE, "Handeling gamemode for player: " + player.getName() + ", " + world.getGameMode().toString());
MultiverseCore.staticLog(Level.FINE, "Handling gamemode for player: " + player.getName() + ", " + world.getGameMode().toString());
MultiverseCore.staticLog(Level.FINE, "PWorld: " + player.getWorld());
MultiverseCore.staticLog(Level.FINE, "AWorld: " + world);
player.setGameMode(world.getGameMode());
@@ -36,7 +36,7 @@ public class MVPluginListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void pluginEnable(PluginEnableEvent event) {
// Let AllPay handle all econ plugin loadings, only go for econ plugins we support
if (Arrays.asList(AllPay.validEconPlugins).contains(event.getPlugin().getDescription().getName())) {
if (Arrays.asList(AllPay.getValidEconPlugins()).contains(event.getPlugin().getDescription().getName())) {
this.plugin.setBank(this.plugin.getBanker().loadEconPlugin());
}
@@ -0,0 +1,85 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2012. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.listeners;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import org.bukkit.Material;
import org.bukkit.PortalType;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityCreatePortalEvent;
import org.bukkit.event.world.PortalCreateEvent;
/**
* A custom listener for portal related events.
*/
public class MVPortalListener implements Listener {
private MultiverseCore plugin;
public MVPortalListener(MultiverseCore core) {
this.plugin = core;
}
/**
* This is called when an entity creates a portal.
*
* @param event The event where an entity created a portal.
*/
@EventHandler
public void entityPortalCreate(EntityCreatePortalEvent event) {
if (event.isCancelled() || event.getBlocks().size() == 0) {
return;
}
MultiverseWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getBlocks().get(0).getWorld());
// We have to do it like this due to a bug in 1.1-R3
if (this.cancelPortalEvent(world, event.getPortalType())) {
event.setCancelled(true);
}
}
/**
* This is called when a portal is created as the result of another world being linked.
* @param event The event where a portal was formed due to a world link
*/
@EventHandler
public void portalForm(PortalCreateEvent event) {
if (event.isCancelled() || event.getBlocks().size() == 0) {
return;
}
// There's no type attribute (as of 1.1-R1), so we have to iterate.
for (Block b : event.getBlocks()) {
if (b.getType() == Material.PORTAL) {
MultiverseWorld world = this.plugin.getMVWorldManager().getMVWorld(b.getWorld());
if (this.cancelPortalEvent(world, PortalType.NETHER)) {
event.setCancelled(true);
return;
}
}
}
// If We're here, then the Portal was an Ender type:
MultiverseWorld world = this.plugin.getMVWorldManager().getMVWorld(event.getBlocks().get(0).getWorld());
if (this.cancelPortalEvent(world, PortalType.ENDER)) {
event.setCancelled(true);
}
}
private boolean cancelPortalEvent(MultiverseWorld world, PortalType type) {
if (world.getAllowedPortals() == AllowedPortalType.NONE) {
return true;
} else if (world.getAllowedPortals() != AllowedPortalType.ALL) {
if (type != world.getAllowedPortals().getActualPortalType()) {
return true;
}
}
return false;
}
}
@@ -48,7 +48,7 @@ public class AnchorManager {
Set<String> anchorKeys = anchorsSection.getKeys(false);
for (String key : anchorKeys) {
//world:x,y,z:pitch:yaw
Location anchorLocation = LocationManipulation.stringToLocation(anchorsSection.getString(key, ""));
Location anchorLocation = plugin.getLocationManipulation().stringToLocation(anchorsSection.getString(key, ""));
if (anchorLocation != null) {
MultiverseCore.staticLog(Level.INFO, "Loading anchor: '" + key + "'...");
this.anchors.put(key, anchorLocation);
@@ -98,7 +98,7 @@ public class AnchorManager {
* @return True if the anchor was successfully saved.
*/
public boolean saveAnchorLocation(String anchor, String location) {
Location parsed = LocationManipulation.stringToLocation(location);
Location parsed = plugin.getLocationManipulation().stringToLocation(location);
return parsed != null && this.saveAnchorLocation(anchor, parsed);
}
@@ -112,7 +112,7 @@ public class AnchorManager {
if (l == null) {
return false;
}
this.anchorConfig.set("anchors." + anchor, LocationManipulation.locationToString(l));
this.anchorConfig.set("anchors." + anchor, plugin.getLocationManipulation().locationToString(l));
this.anchors.put(anchor, l);
return this.saveAnchors();
}
@@ -18,7 +18,10 @@ import java.util.logging.Level;
/**
* Used to determine block/location-related facts.
*
* @deprecated Use instead: {@link com.onarandombox.MultiverseCore.api.BlockSafety} and {@link SimpleBlockSafety}.
*/
@Deprecated
public class BlockSafety {
/**
@@ -22,7 +22,10 @@ import java.util.Map;
/**
* Utility class to manipulate locations.
*
* @deprecated Use instead: {@link com.onarandombox.MultiverseCore.api.LocationManipulation} and {@link SimpleLocationManipulation}.
*/
@Deprecated
public class LocationManipulation {
private LocationManipulation() { }
@@ -10,14 +10,16 @@ package com.onarandombox.MultiverseCore.utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.onarandombox.MultiverseCore.api.MultiverseMessaging;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* Utility-class for messaging.
* The default-implementation of {@link MultiverseMessaging}.
*/
public class MVMessaging {
public class MVMessaging implements MultiverseMessaging {
private Map<String, Long> sentList;
private int cooldown;
@@ -27,35 +29,25 @@ public class MVMessaging {
}
/**
* Sets the message-cooldown.
* @param milliseconds The new message-cooldown in milliseconds.
* {@inheritDoc}
*/
@Override
public void setCooldown(int milliseconds) {
this.cooldown = milliseconds;
}
/**
* Sends a message to the specified sender if the cooldown has passed.
*
* @param sender The person/console to send the message to.
* @param message The message to send.
* @param ignoreCooldown If true this message will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
* {@inheritDoc}
*/
@Override
public boolean sendMessage(CommandSender sender, String message, boolean ignoreCooldown) {
return this.sendMessages(sender, new String[]{ message }, ignoreCooldown);
}
/**
* Sends a group of messages to the specified sender if the cooldown has passed.
* This method is needed, since sending many messages in quick succession would violate
* the cooldown.
*
* @param sender The person/console to send the message to.
* @param messages The messages to send.
* @param ignoreCooldown If true these messages will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
* {@inheritDoc}
*/
@Override
public boolean sendMessages(CommandSender sender, String[] messages, boolean ignoreCooldown) {
if (!(sender instanceof Player) || ignoreCooldown) {
@@ -78,15 +70,9 @@ public class MVMessaging {
}
/**
* Sends a group of messages to the specified sender if the cooldown has passed.
* This method is needed, since sending many messages in quick succession would violate
* the cooldown.
*
* @param sender The person/console to send the message to.
* @param messages The messages to send.
* @param ignoreCooldown If true these messages will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
* {@inheritDoc}
*/
@Override
public boolean sendMessages(CommandSender sender, Collection<String> messages, boolean ignoreCooldown) {
return this.sendMessages(sender, messages.toArray(new String[0]), ignoreCooldown);
}
@@ -98,9 +84,9 @@ public class MVMessaging {
}
/**
* Gets the message-cooldown.
* @return The message-cooldown.
* {@inheritDoc}
*/
@Override
public int getCooldown() {
return cooldown;
}
@@ -43,10 +43,6 @@ public class MVPermissions implements PermissionsInterface {
* @return True if they should bypass restrictions.
*/
public boolean canIgnoreGameModeRestriction(Player p, MultiverseWorld w) {
if (p.hasPermission("mv.bypass.gamemode.*")) {
this.plugin.log(Level.FINER, "Player has mv.bypass.gamemode.* their gamemode is ignored!");
return true;
}
return p.hasPermission("mv.bypass.gamemode." + w.getName());
}
@@ -98,7 +94,8 @@ public class MVPermissions implements PermissionsInterface {
*/
public boolean canEnterWorld(Player p, MultiverseWorld w) {
// If we're not enforcing access, anyone can enter.
if (!MultiverseCore.EnforceAccess) {
if (!plugin.getMVConfig().getEnforceAccess()) {
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);
@@ -169,9 +166,9 @@ public class MVPermissions implements PermissionsInterface {
// plugin reloads, when MV asks the API if a player has a perm, it reports that they do NOT.
// For the moment, we're going to check all of this node's parents to see if the user has those. It stops
// when if finds a true or there are no more parents. --FF
if (!hasPermission) {
hasPermission = this.hasAnyParentPermission(sender, node);
}
// if (!hasPermission) {
// hasPermission = this.hasAnyParentPermission(sender, node);
// }
return hasPermission;
}
@@ -179,10 +176,12 @@ public class MVPermissions implements PermissionsInterface {
// TODO: Better player checks, most likely not needed, but safer.
private boolean checkActualPermission(CommandSender sender, String node) {
Player player = (Player) sender;
this.plugin.log(Level.FINEST, "Checking to see if player [" + player.getName() + "] has permission [" + node + "]");
boolean hasPermission = sender.hasPermission(node);
if (hasPermission) {
this.plugin.log(Level.FINER, "Player [" + player.getName() + "] HAS PERMISSION [" + node + "]!");
this.plugin.log(Level.FINEST, "Checking to see if player [" + player.getName() + "] has permission [" + node + "]... YES");
} else {
this.plugin.log(Level.FINEST, "Checking to see if player [" + player.getName() + "] has permission [" + node + "]... NO");
}
return hasPermission;
}
@@ -7,8 +7,7 @@
package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import org.bukkit.configuration.Configuration;
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
import org.bukkit.entity.Player;
import java.util.Date;
@@ -23,9 +22,9 @@ public class MVPlayerSession {
private long teleportLast = 0L; // Timestamp for the Players last Portal Teleportation.
private long messageLast = 0L; // Timestamp for the Players last Alert Message.
private Configuration config; // Configuration file to find out Cooldown Timers.
private MultiverseCoreConfig config; // Configuration file to find out Cooldown Timers.
public MVPlayerSession(Player player, Configuration config, MultiverseCore multiVerseCore) {
public MVPlayerSession(Player player, MultiverseCoreConfig config) {
this.player = player;
this.config = config;
// this.bedSpawn = null;
@@ -42,6 +41,6 @@ public class MVPlayerSession {
*/
public boolean getTeleportable() {
long time = (new Date()).getTime();
return ((time - this.teleportLast) > this.config.getInt("portalcooldown", 5000)); // SUPPRESS CHECKSTYLE: MagicNumberCheck
return ((time - this.teleportLast) > this.config.getTeleportCooldown());
}
}
@@ -9,6 +9,7 @@ package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.destination.CannonDestination;
import org.bukkit.Location;
import org.bukkit.TravelAgent;
@@ -106,7 +107,7 @@ public class MVTravelAgent implements TravelAgent {
if (this.destination instanceof CannonDestination) {
this.core.log(Level.FINE, "Using Stock TP method. This cannon will have 0 velocity");
}
SafeTTeleporter teleporter = new SafeTTeleporter(this.core);
SafeTTeleporter teleporter = this.core.getSafeTTeleporter();
Location newLoc = this.destination.getLocation(this.player);
if (this.destination.useSafeTeleporter()) {
newLoc = teleporter.getSafeLocation(this.player, this.destination);
@@ -100,7 +100,7 @@ public class PermissionTools {
*/
public boolean playerHasMoneyToEnter(MultiverseWorld fromWorld, MultiverseWorld toWorld, CommandSender teleporter, Player teleportee, boolean pay) {
Player teleporterPlayer;
if (MultiverseCore.TeleportIntercept) {
if (plugin.getMVConfig().getTeleportIntercept()) {
if (teleporter instanceof ConsoleCommandSender) {
return true;
}
@@ -171,7 +171,7 @@ public class PermissionTools {
this.plugin.log(Level.FINEST, "Checking '" + teleporter + "' can send '" + teleportee + "' somewhere");
Player teleporterPlayer;
if (MultiverseCore.TeleportIntercept) {
if (plugin.getMVConfig().getTeleportIntercept()) {
// The console can send anyone anywhere
if (teleporter instanceof ConsoleCommandSender) {
return true;
@@ -9,6 +9,7 @@ package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Animals;
@@ -25,7 +26,10 @@ import java.util.logging.Level;
/**
* Utility class that removes animals from worlds that don't belong there.
*
* @deprecated Use instead: {@link WorldPurger} and {@link SimpleWorldPurger}.
*/
@Deprecated
public class PurgeWorlds {
private MultiverseCore plugin;
@@ -8,9 +8,11 @@
package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
import com.onarandombox.MultiverseCore.enums.TeleportResult;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@@ -26,7 +28,10 @@ import java.util.logging.Level;
/**
* The {@link SafeTTeleporter}.
*
* @deprecated Use instead: {@link com.onarandombox.MultiverseCore.api.SafeTTeleporter} and {@link SimpleSafeTTeleporter}.
*/
@Deprecated
public class SafeTTeleporter {
private MultiverseCore plugin;
@@ -34,7 +39,7 @@ public class SafeTTeleporter {
public SafeTTeleporter(MultiverseCore plugin) {
this.plugin = plugin;
this.bs = new BlockSafety();
this.bs = plugin.getBlockSafety();
}
private static final int DEFAULT_TOLERANCE = 6;
@@ -63,7 +68,7 @@ public class SafeTTeleporter {
if (safe != null) {
safe.setX(safe.getBlockX() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
safe.setZ(safe.getBlockZ() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
this.plugin.log(Level.FINE, "Hey! I found one: " + LocationManipulation.strCoordsRaw(safe));
this.plugin.log(Level.FINE, "Hey! I found one: " + plugin.getLocationManipulation().strCoordsRaw(safe));
} else {
this.plugin.log(Level.FINE, "Uh oh! No safe place found!");
}
@@ -77,7 +82,7 @@ public class SafeTTeleporter {
}
// We want half of it, so we can go up and down
tolerance /= 2;
this.plugin.log(Level.FINER, "Given Location of: " + LocationManipulation.strCoordsRaw(l));
this.plugin.log(Level.FINER, "Given Location of: " + plugin.getLocationManipulation().strCoordsRaw(l));
this.plugin.log(Level.FINER, "Checking +-" + tolerance + " with a radius of " + radius);
// For now this will just do a straight up block.
@@ -0,0 +1,254 @@
/******************************************************************************
* 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.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.Core;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Vehicle;
import java.util.logging.Level;
/**
* The default-implementation of {@link BlockSafety}.
*/
public class SimpleBlockSafety implements BlockSafety {
private final Core plugin;
public SimpleBlockSafety(Core plugin) {
this.plugin = plugin;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isBlockAboveAir(Location l) {
Location downOne = l.clone();
downOne.setY(downOne.getY() - 1);
return (downOne.getBlock().getType() == Material.AIR);
}
/**
* {@inheritDoc}
*/
@Override
public boolean playerCanSpawnHereSafely(World world, double x, double y, double z) {
Location l = new Location(world, x, y, z);
return playerCanSpawnHereSafely(l);
}
/**
* {@inheritDoc}
*/
@Override
public boolean playerCanSpawnHereSafely(Location l) {
if (l == null) {
// Can't safely spawn at a null location!
return false;
}
World world = l.getWorld();
Location actual = l.clone();
Location upOne = l.clone();
Location downOne = l.clone();
upOne.setY(upOne.getY() + 1);
downOne.setY(downOne.getY() - 1);
if (this.isSolidBlock(world.getBlockAt(actual).getType())
|| this.isSolidBlock(upOne.getBlock().getType())) {
MultiverseCore.staticLog(Level.FINER, "Error Here (Actual)? ("
+ actual.getBlock().getType() + ")[" + this.isSolidBlock(actual.getBlock().getType()) + "]");
MultiverseCore.staticLog(Level.FINER, "Error Here (upOne)? ("
+ upOne.getBlock().getType() + ")[" + this.isSolidBlock(upOne.getBlock().getType()) + "]");
return false;
}
if (downOne.getBlock().getType() == Material.LAVA || downOne.getBlock().getType() == Material.STATIONARY_LAVA) {
MultiverseCore.staticLog(Level.FINER, "Error Here (downOne)? ("
+ downOne.getBlock().getType() + ")[" + this.isSolidBlock(downOne.getBlock().getType()) + "]");
return false;
}
if (downOne.getBlock().getType() == Material.FIRE) {
MultiverseCore.staticLog(Level.FINER, "There's fire below! ("
+ actual.getBlock().getType() + ")[" + this.isSolidBlock(actual.getBlock().getType()) + "]");
return false;
}
if (isBlockAboveAir(actual)) {
MultiverseCore.staticLog(Level.FINER, "Is block above air [" + isBlockAboveAir(actual) + "]");
MultiverseCore.staticLog(Level.FINER, "Has 2 blocks of water below [" + this.hasTwoBlocksofWaterBelow(actual) + "]");
return this.hasTwoBlocksofWaterBelow(actual);
}
return true;
}
/**
* {@inheritDoc}
*/
@Override
public Location getTopBlock(Location l) {
Location check = l.clone();
check.setY(127); // SUPPRESS CHECKSTYLE: MagicNumberCheck
while (check.getY() > 0) {
if (this.playerCanSpawnHereSafely(check)) {
return check;
}
check.setY(check.getY() - 1);
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public Location getBottomBlock(Location l) {
Location check = l.clone();
check.setY(0);
while (check.getY() < 127) { // SUPPRESS CHECKSTYLE: MagicNumberCheck
if (this.playerCanSpawnHereSafely(check)) {
return check;
}
check.setY(check.getY() + 1);
}
return null;
}
/*
* If someone has a better way of this... Please either tell us, or submit a pull request!
*/
private boolean isSolidBlock(Material type) {
switch (type) {
case AIR:
return false;
case SNOW:
return false;
case TRAP_DOOR:
return false;
case TORCH:
return false;
case YELLOW_FLOWER:
return false;
case RED_ROSE:
return false;
case RED_MUSHROOM:
return false;
case BROWN_MUSHROOM:
return false;
case REDSTONE:
return false;
case REDSTONE_WIRE:
return false;
case RAILS:
return false;
case POWERED_RAIL:
return false;
case REDSTONE_TORCH_ON:
return false;
case REDSTONE_TORCH_OFF:
return false;
case DEAD_BUSH:
return false;
case SAPLING:
return false;
case STONE_BUTTON:
return false;
case LEVER:
return false;
case LONG_GRASS:
return false;
case PORTAL:
return false;
case STONE_PLATE:
return false;
case WOOD_PLATE:
return false;
case SEEDS:
return false;
case SUGAR_CANE_BLOCK:
return false;
case WALL_SIGN:
return false;
case SIGN_POST:
return false;
case WOODEN_DOOR:
return false;
case STATIONARY_WATER:
return false;
case WATER:
return false;
default:
return true;
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isEntitiyOnTrack(Location l) {
Material currentBlock = l.getBlock().getType();
return (currentBlock == Material.POWERED_RAIL || currentBlock == Material.DETECTOR_RAIL || currentBlock == Material.RAILS);
}
/**
* Checks recursively below a {@link Location} for 2 blocks of water.
*
* @param l The {@link Location}
* @return Whether there are 2 blocks of water
*/
private boolean hasTwoBlocksofWaterBelow(Location l) {
if (l.getBlockY() < 0) {
return false;
}
Location oneBelow = l.clone();
oneBelow.subtract(0, 1, 0);
if (oneBelow.getBlock().getType() == Material.WATER || oneBelow.getBlock().getType() == Material.STATIONARY_WATER) {
Location twoBelow = oneBelow.clone();
twoBelow.subtract(0, 1, 0);
return (oneBelow.getBlock().getType() == Material.WATER || oneBelow.getBlock().getType() == Material.STATIONARY_WATER);
}
if (oneBelow.getBlock().getType() != Material.AIR) {
return false;
}
return hasTwoBlocksofWaterBelow(oneBelow);
}
/**
* {@inheritDoc}
*/
@Override
public boolean canSpawnCartSafely(Minecart cart) {
if (this.isBlockAboveAir(cart.getLocation())) {
return true;
}
if (this.isEntitiyOnTrack(plugin.getLocationManipulation().getNextBlock(cart))) {
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public boolean canSpawnVehicleSafely(Vehicle vehicle) {
if (this.isBlockAboveAir(vehicle.getLocation())) {
return true;
}
return false;
}
}
@@ -0,0 +1,251 @@
/******************************************************************************
* 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.utils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* The default-implementation of {@link LocationManipulation}.
*/
public class SimpleLocationManipulation implements LocationManipulation {
private static final Map<String, Integer> ORIENTATION_INTS;
static {
Map<String, Integer> orientationInts = new HashMap<String, Integer>();
// BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
orientationInts.put("n", 180);
orientationInts.put("ne", 225);
orientationInts.put("e", 270);
orientationInts.put("se", 315);
orientationInts.put("s", 0);
orientationInts.put("sw", 45);
orientationInts.put("w", 90);
orientationInts.put("nw", 135);
// "freeze" the map:
ORIENTATION_INTS = Collections.unmodifiableMap(orientationInts);
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
}
/**
* {@inheritDoc}
*/
@Override
public String locationToString(Location location) {
if (location == null) {
return "";
}
return String.format("%s:%.2f,%.2f,%.2f:%.2f:%.2f", location.getWorld().getName(),
location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
}
/**
* {@inheritDoc}
*/
@Override
public Location getBlockLocation(Location l) {
l.setX(l.getBlockX());
l.setY(l.getBlockY());
l.setZ(l.getBlockZ());
return l;
}
/**
* {@inheritDoc}
*/
@Override
public Location stringToLocation(String locationString) {
//format:
//world:x,y,z:pitch:yaw
if (locationString == null) {
return null;
}
// Split the whole string, format is:
// {'world', 'x,y,z'[, 'pitch', 'yaw']}
String[] split = locationString.split(":");
if (split.length < 2 || split.length > 4) { // SUPPRESS CHECKSTYLE: MagicNumberCheck
return null;
}
// Split the xyz string, format is:
// {'x', 'y', 'z'}
String[] xyzsplit = split[1].split(",");
if (xyzsplit.length != 3) {
return null;
}
// Verify the world is valid
World w = Bukkit.getWorld(split[0]);
if (w == null) {
return null;
}
try {
float pitch = 0;
float yaw = 0;
if (split.length >= 3) {
yaw = (float) Double.parseDouble(split[2]);
}
if (split.length == 4) { // SUPPRESS CHECKSTYLE: MagicNumberCheck
pitch = (float) Double.parseDouble(split[3]);
}
return new Location(w, Double.parseDouble(xyzsplit[0]), Double.parseDouble(xyzsplit[1]), Double.parseDouble(xyzsplit[2]), yaw, pitch);
} catch (NumberFormatException e) {
return null;
}
}
/**
* {@inheritDoc}
*/
@Override
public String strCoords(Location l) {
String result = "";
DecimalFormat df = new DecimalFormat();
df.setMinimumFractionDigits(0);
df.setMaximumFractionDigits(2);
result += ChatColor.WHITE + "X: " + ChatColor.AQUA + df.format(l.getX()) + " ";
result += ChatColor.WHITE + "Y: " + ChatColor.AQUA + df.format(l.getY()) + " ";
result += ChatColor.WHITE + "Z: " + ChatColor.AQUA + df.format(l.getZ()) + " ";
result += ChatColor.WHITE + "P: " + ChatColor.GOLD + df.format(l.getPitch()) + " ";
result += ChatColor.WHITE + "Y: " + ChatColor.GOLD + df.format(l.getYaw()) + " ";
return result;
}
/**
* {@inheritDoc}
*/
@Override
public String strCoordsRaw(Location l) {
if (l == null) {
return "null";
}
String result = "";
DecimalFormat df = new DecimalFormat();
df.setMinimumFractionDigits(0);
df.setMaximumFractionDigits(2);
result += "X: " + df.format(l.getX()) + " ";
result += "Y: " + df.format(l.getY()) + " ";
result += "Z: " + df.format(l.getZ()) + " ";
result += "P: " + df.format(l.getPitch()) + " ";
result += "Y: " + df.format(l.getYaw()) + " ";
return result;
}
/**
* {@inheritDoc}
*/
@Override
public String getDirection(Location location) {
// BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
double r = (location.getYaw() % 360) + 180;
// Remember, these numbers are every 45 degrees with a 22.5 offset, to detect boundaries.
String dir;
if (r < 22.5)
dir = "n";
else if (r < 67.5)
dir = "ne";
else if (r < 112.5)
dir = "e";
else if (r < 157.5)
dir = "se";
else if (r < 202.5)
dir = "s";
else if (r < 247.5)
dir = "sw";
else if (r < 292.5)
dir = "w";
else if (r < 337.5)
dir = "nw";
else
dir = "n";
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
return dir;
}
/**
* {@inheritDoc}
*/
@Override
public float getYaw(String orientation) {
if (orientation == null) {
return 0;
}
if (ORIENTATION_INTS.containsKey(orientation.toLowerCase())) {
return ORIENTATION_INTS.get(orientation.toLowerCase());
}
return 0;
}
/**
* {@inheritDoc}
*/
@Override
public float getSpeed(Vector v) {
return (float) Math.sqrt(v.getX() * v.getX() + v.getZ() * v.getZ());
}
// X, Y, Z
// -W/+E,0, -N/+S
/**
* {@inheritDoc}
*/
@Override
public Vector getTranslatedVector(Vector v, String direction) {
if (direction == null) {
return v;
}
float speed = getSpeed(v);
float halfSpeed = (float) (speed / 2.0);
// TODO: Mathmatacize this:
if (direction.equalsIgnoreCase("n")) {
return new Vector(0, 0, -1 * speed);
} else if (direction.equalsIgnoreCase("ne")) {
return new Vector(halfSpeed, 0, -1 * halfSpeed);
} else if (direction.equalsIgnoreCase("e")) {
return new Vector(speed, 0, 0);
} else if (direction.equalsIgnoreCase("se")) {
return new Vector(halfSpeed, 0, halfSpeed);
} else if (direction.equalsIgnoreCase("s")) {
return new Vector(0, 0, speed);
} else if (direction.equalsIgnoreCase("sw")) {
return new Vector(-1 * halfSpeed, 0, halfSpeed);
} else if (direction.equalsIgnoreCase("w")) {
return new Vector(-1 * speed, 0, 0);
} else if (direction.equalsIgnoreCase("nw")) {
return new Vector(-1 * halfSpeed, 0, -1 * halfSpeed);
}
return v;
}
/**
* {@inheritDoc}
*/
@Override
public Location getNextBlock(Vehicle v) {
Vector vector = v.getVelocity();
Location location = v.getLocation();
int x = vector.getX() < 0 ? vector.getX() == 0 ? 0 : -1 : 1;
int z = vector.getZ() < 0 ? vector.getZ() == 0 ? 0 : -1 : 1;
return location.add(x, 0, z);
}
}
@@ -0,0 +1,334 @@
/******************************************************************************
* 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.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
import com.onarandombox.MultiverseCore.enums.TeleportResult;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
import java.util.logging.Level;
/**
* The default-implementation of {@link SafeTTeleporter}.
*/
public class SimpleSafeTTeleporter implements SafeTTeleporter {
private MultiverseCore plugin;
public SimpleSafeTTeleporter(MultiverseCore plugin) {
this.plugin = plugin;
}
private static final int DEFAULT_TOLERANCE = 6;
private static final int DEFAULT_RADIUS = 9;
/**
* {@inheritDoc}
*/
@Override
public Location getSafeLocation(Location l) {
return this.getSafeLocation(l, DEFAULT_TOLERANCE, DEFAULT_RADIUS);
}
/**
* {@inheritDoc}
*/
@Override
public Location getSafeLocation(Location l, int tolerance, int radius) {
// Check around the player first in a configurable radius:
// TODO: Make this configurable
Location safe = checkAboveAndBelowLocation(l, tolerance, radius);
if (safe != null) {
safe.setX(safe.getBlockX() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
safe.setZ(safe.getBlockZ() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
this.plugin.log(Level.FINE, "Hey! I found one: " + plugin.getLocationManipulation().strCoordsRaw(safe));
} else {
this.plugin.log(Level.FINE, "Uh oh! No safe place found!");
}
return safe;
}
private Location checkAboveAndBelowLocation(Location l, int tolerance, int radius) {
// Tolerance must be an even number:
if (tolerance % 2 != 0) {
tolerance += 1;
}
// We want half of it, so we can go up and down
tolerance /= 2;
this.plugin.log(Level.FINER, "Given Location of: " + plugin.getLocationManipulation().strCoordsRaw(l));
this.plugin.log(Level.FINER, "Checking +-" + tolerance + " with a radius of " + radius);
// For now this will just do a straight up block.
Location locToCheck = l.clone();
// Check the main level
Location safe = this.checkAroundLocation(locToCheck, radius);
if (safe != null) {
return safe;
}
// We've already checked zero right above this.
int currentLevel = 1;
while (currentLevel <= tolerance) {
// Check above
locToCheck = l.clone();
locToCheck.add(0, currentLevel, 0);
safe = this.checkAroundLocation(locToCheck, radius);
if (safe != null) {
return safe;
}
// Check below
locToCheck = l.clone();
locToCheck.subtract(0, currentLevel, 0);
safe = this.checkAroundLocation(locToCheck, radius);
if (safe != null) {
return safe;
}
currentLevel++;
}
return null;
}
/*
* For my crappy algorithm, radius MUST be odd.
*/
private Location checkAroundLocation(Location l, int diameter) {
if (diameter % 2 == 0) {
diameter += 1;
}
Location checkLoc = l.clone();
// Start at 3, the min diameter around a block
int loopcounter = 3;
while (loopcounter <= diameter) {
boolean foundSafeArea = checkAroundSpecificDiameter(checkLoc, loopcounter);
// If a safe area was found:
if (foundSafeArea) {
// Return the checkLoc, it is the safe location.
return checkLoc;
}
// Otherwise, let's reset our location
checkLoc = l.clone();
// And increment the radius
loopcounter += 2;
}
return null;
}
private boolean checkAroundSpecificDiameter(Location checkLoc, int circle) {
// Adjust the circle to get how many blocks to step out.
// A radius of 3 makes the block step 1
// A radius of 5 makes the block step 2
// A radius of 7 makes the block step 3
// ...
int adjustedCircle = ((circle - 1) / 2);
checkLoc.add(adjustedCircle, 0, 0);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
// Now we go to the right that adjustedCircle many
for (int i = 0; i < adjustedCircle; i++) {
checkLoc.add(0, 0, 1);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
// Then down adjustedCircle *2
for (int i = 0; i < adjustedCircle * 2; i++) {
checkLoc.add(-1, 0, 0);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
// Then left adjustedCircle *2
for (int i = 0; i < adjustedCircle * 2; i++) {
checkLoc.add(0, 0, -1);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
// Then up Then left adjustedCircle *2
for (int i = 0; i < adjustedCircle * 2; i++) {
checkLoc.add(1, 0, 0);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
// Then finish up by doing adjustedCircle - 1
for (int i = 0; i < adjustedCircle - 1; i++) {
checkLoc.add(0, 0, 1);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, MVDestination d) {
if (d instanceof InvalidDestination) {
this.plugin.log(Level.FINER, "Entity tried to teleport to an invalid destination");
return TeleportResult.FAIL_INVALID;
}
Player teleporteePlayer = null;
if (teleportee instanceof Player) {
teleporteePlayer = ((Player) teleportee);
} else if (teleportee.getPassenger() instanceof Player) {
teleporteePlayer = ((Player) teleportee.getPassenger());
}
if (teleporteePlayer == null) {
return TeleportResult.FAIL_INVALID;
}
MultiverseCore.addPlayerToTeleportQueue(teleporter.getName(), teleporteePlayer.getName());
Location safeLoc = d.getLocation(teleportee);
if (d.useSafeTeleporter()) {
safeLoc = this.getSafeLocation(teleportee, d);
}
if (safeLoc != null) {
if (teleportee.teleport(safeLoc)) {
if (!d.getVelocity().equals(new Vector(0, 0, 0))) {
teleportee.setVelocity(d.getVelocity());
}
return TeleportResult.SUCCESS;
}
return TeleportResult.FAIL_OTHER;
}
return TeleportResult.FAIL_UNSAFE;
}
/**
* {@inheritDoc}
*/
@Override
public TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, Location location, boolean safely) {
if (safely) {
location = this.getSafeLocation(location);
}
if (location != null) {
if (teleportee.teleport(location)) {
return TeleportResult.SUCCESS;
}
return TeleportResult.FAIL_OTHER;
}
return TeleportResult.FAIL_UNSAFE;
}
/**
* {@inheritDoc}
*/
@Override
public Location getSafeLocation(Entity e, MVDestination d) {
Location l = d.getLocation(e);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(l)) {
plugin.log(Level.FINE, "The first location you gave me was safe.");
return l;
}
if (e instanceof Minecart) {
Minecart m = (Minecart) e;
if (!plugin.getBlockSafety().canSpawnCartSafely(m)) {
return null;
}
} else if (e instanceof Vehicle) {
Vehicle v = (Vehicle) e;
if (!plugin.getBlockSafety().canSpawnVehicleSafely(v)) {
return null;
}
}
Location safeLocation = this.getSafeLocation(l);
if (safeLocation != null) {
// Add offset to account for a vehicle on dry land!
if (e instanceof Minecart && !plugin.getBlockSafety().isEntitiyOnTrack(safeLocation)) {
safeLocation.setY(safeLocation.getBlockY() + .5);
this.plugin.log(Level.FINER, "Player was inside a minecart. Offsetting Y location.");
}
this.plugin.log(Level.FINE, "Had to look for a bit, but I found a safe place for ya!");
return safeLocation;
}
if (e instanceof Player) {
Player p = (Player) e;
this.plugin.getMessaging().sendMessage(p, "No safe locations found!", false);
this.plugin.log(Level.FINER, "No safe location found for " + p.getName());
} else if (e.getPassenger() instanceof Player) {
Player p = (Player) e.getPassenger();
this.plugin.getMessaging().sendMessage(p, "No safe locations found!", false);
this.plugin.log(Level.FINER, "No safe location found for " + p.getName());
}
this.plugin.log(Level.FINE, "Sorry champ, you're basically trying to teleport into a minefield. I should just kill you now.");
return null;
}
/**
* {@inheritDoc}
*/
@Override
public Location findPortalBlockNextTo(Location l) {
Block b = l.getWorld().getBlockAt(l);
Location foundLocation = null;
if (b.getType() == Material.PORTAL) {
return l;
}
if (b.getRelative(BlockFace.NORTH).getType() == Material.PORTAL) {
foundLocation = getCloserBlock(l, b.getRelative(BlockFace.NORTH).getLocation(), foundLocation);
}
if (b.getRelative(BlockFace.SOUTH).getType() == Material.PORTAL) {
foundLocation = getCloserBlock(l, b.getRelative(BlockFace.SOUTH).getLocation(), foundLocation);
}
if (b.getRelative(BlockFace.EAST).getType() == Material.PORTAL) {
foundLocation = getCloserBlock(l, b.getRelative(BlockFace.EAST).getLocation(), foundLocation);
}
if (b.getRelative(BlockFace.WEST).getType() == Material.PORTAL) {
foundLocation = getCloserBlock(l, b.getRelative(BlockFace.WEST).getLocation(), foundLocation);
}
return foundLocation;
}
private static Location getCloserBlock(Location source, Location blockA, Location blockB) {
// If B wasn't given, return a.
if (blockB == null) {
return blockA;
}
// Center our calculations
blockA.add(.5, 0, .5);
blockB.add(.5, 0, .5);
// Retrieve the distance to the normalized blocks
double testA = source.distance(blockA);
double testB = source.distance(blockB);
// Compare and return
if (testA <= testB) {
return blockA;
}
return blockB;
}
}
@@ -0,0 +1,153 @@
/******************************************************************************
* 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.utils;
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;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Ghast;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Squid;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
/**
* Utility class that removes animals from worlds that don't belong there.
*/
public class SimpleWorldPurger implements WorldPurger {
private MultiverseCore plugin;
public SimpleWorldPurger(MultiverseCore plugin) {
this.plugin = plugin;
}
/**
* {@inheritDoc}
*/
@Override
public void purgeWorlds(List<MultiverseWorld> worlds) {
if (worlds == null || worlds.isEmpty()) {
return;
}
for (MultiverseWorld world : worlds) {
this.purgeWorld(world);
}
}
/**
* {@inheritDoc}
*/
@Override
public void purgeWorld(MultiverseWorld world) {
if (world == null) {
return;
}
ArrayList<String> allMobs = new ArrayList<String>(world.getAnimalList());
allMobs.addAll(world.getMonsterList());
purgeWorld(world, allMobs, !world.canAnimalsSpawn(), !world.canMonstersSpawn());
}
/**
* {@inheritDoc}
*/
@Override
public void purgeWorld(MultiverseWorld mvworld, List<String> thingsToKill,
boolean negateAnimals, boolean negateMonsters, CommandSender sender) {
if (mvworld == null) {
return;
}
World world = this.plugin.getServer().getWorld(mvworld.getName());
if (world == null) {
return;
}
int entitiesKilled = 0;
for (Entity e : world.getEntities()) {
this.plugin.log(Level.FINEST, "Entity list (aval for purge) from WORLD < " + mvworld.getName() + " >: " + e.toString());
// Check against Monsters
if (killMonster(mvworld, e, thingsToKill, negateMonsters)) {
entitiesKilled++;
continue;
}
// Check against Animals
if (this.killCreature(mvworld, e, thingsToKill, negateAnimals)) {
entitiesKilled++;
}
}
if (sender != null) {
sender.sendMessage(entitiesKilled + " entities purged from the world '" + world.getName() + "'");
}
}
/**
* {@inheritDoc}
*/
@Override
public void purgeWorld(MultiverseWorld mvworld, List<String> thingsToKill, boolean negateAnimals, boolean negateMonsters) {
purgeWorld(mvworld, thingsToKill, negateAnimals, negateMonsters, null);
}
private boolean killCreature(MultiverseWorld mvworld, Entity e, List<String> creaturesToKill, boolean negate) {
String entityName = e.toString().replaceAll("Craft", "").toUpperCase();
if (e instanceof Squid || e instanceof Animals) {
if (creaturesToKill.contains(entityName) || creaturesToKill.contains("ALL") || creaturesToKill.contains("ANIMALS")) {
if (!negate) {
e.remove();
return true;
}
} else {
if (negate) {
e.remove();
return true;
}
}
}
return false;
}
/*
* Will kill the monster if it's in the list UNLESS the NEGATE boolean is set, then it will kill it if it's NOT.
*/
private boolean killMonster(MultiverseWorld mvworld, Entity e, List<String> creaturesToKill, boolean negate) {
String entityName = "";
//TODO: Fixme once either Rigby puts his awesome thing in OR Enderdragon gets a toString, OR both.
if (e instanceof EnderDragon) {
entityName = "ENDERDRAGON";
} else {
entityName = e.toString().replaceAll("Craft", "").toUpperCase();
}
if (e instanceof Slime || e instanceof Monster || e instanceof Ghast || e instanceof EnderDragon) {
this.plugin.log(Level.FINER, "Looking at a monster: " + e);
if (creaturesToKill.contains(entityName) || creaturesToKill.contains("ALL") || creaturesToKill.contains("MONSTERS")) {
if (!negate) {
this.plugin.log(Level.FINEST, "Removing a monster: " + e);
e.remove();
return true;
}
} else {
if (negate) {
this.plugin.log(Level.FINEST, "Removing a monster: " + e);
e.remove();
return true;
}
}
}
return false;
}
}
@@ -11,6 +11,8 @@ 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.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import com.onarandombox.MultiverseCore.commands.EnvironmentCommand;
import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent;
import org.bukkit.World;
@@ -41,7 +43,7 @@ import java.util.logging.Level;
*/
public class WorldManager implements MVWorldManager {
private MultiverseCore plugin;
private PurgeWorlds worldPurger;
private WorldPurger worldPurger;
private Map<String, MultiverseWorld> worlds;
private List<String> unloadedWorlds;
private FileConfiguration configWorlds = null;
@@ -52,7 +54,7 @@ public class WorldManager implements MVWorldManager {
this.plugin = core;
this.worlds = new HashMap<String, MultiverseWorld>();
this.unloadedWorlds = new ArrayList<String>();
this.worldPurger = new PurgeWorlds(this.plugin);
this.worldPurger = new SimpleWorldPurger(plugin);
}
/**
@@ -82,16 +84,17 @@ public class WorldManager implements MVWorldManager {
* {@inheritDoc}
*/
@Override
public boolean addWorld(String name, Environment env, String seedString, WorldType type, String generator) {
return this.addWorld(name, env, seedString, type, generator, true);
public boolean addWorld(String name, Environment env, String seedString, WorldType type, Boolean generateStructures,
String generator) {
return this.addWorld(name, env, seedString, type, generateStructures, generator, true);
}
/**
* {@inheritDoc}
*/
@Override
public boolean addWorld(String name, Environment env, String seedString, WorldType type, String generator, boolean useSpawnAdjust) {
plugin.log(Level.FINE, "Adding world with: " + name + ", " + env.toString() + ", " + seedString + ", " + type.toString() + ", " + generator);
public boolean addWorld(String name, Environment env, String seedString, WorldType type, Boolean generateStructures,
String generator, boolean useSpawnAdjust) {
Long seed = null;
WorldCreator c = new WorldCreator(name);
if (seedString != null && seedString.length() > 0) {
@@ -108,7 +111,12 @@ public class WorldManager implements MVWorldManager {
c.generator(generator);
}
c.environment(env);
c.type(type);
if (type != null) {
c.type(type);
}
if (generateStructures != null) {
c.generateStructures(generateStructures);
}
World world;
StringBuilder builder = new StringBuilder();
@@ -139,7 +147,7 @@ public class WorldManager implements MVWorldManager {
MultiverseWorld mvworld = new MVWorld(world, this.configWorlds, this.plugin,
this.plugin.getServer().getWorld(name).getSeed(), generator, useSpawnAdjust);
this.worldPurger.purgeWorld(null, mvworld);
this.worldPurger.purgeWorld(mvworld);
this.worlds.put(name, mvworld);
if (this.unloadedWorlds.contains(name)) {
this.unloadedWorlds.remove(name);
@@ -205,7 +213,7 @@ public class WorldManager implements MVWorldManager {
*/
@Override
public void setFirstSpawnWorld(String world) {
if (world == null) {
if ((world == null) && (this.plugin.getServer().getWorlds().size() > 0)) {
this.firstSpawn = this.plugin.getServer().getWorlds().get(0).getName();
} else {
this.firstSpawn = world;
@@ -279,9 +287,10 @@ public class WorldManager implements MVWorldManager {
String type = this.configWorlds.getString("worlds." + name + ".type", "NORMAL");
String seedString = this.configWorlds.getString("worlds." + name + ".seed", "");
String generatorString = this.configWorlds.getString("worlds." + name + ".generator");
boolean generateStructures = this.configWorlds.getBoolean("worlds." + name + ".generatestructures", true);
addWorld(name, EnvironmentCommand.getEnvFromString(environment), seedString,
EnvironmentCommand.getWorldTypeFromString(type), generatorString);
this.addWorld(name, EnvironmentCommand.getEnvFromString(environment), seedString,
EnvironmentCommand.getWorldTypeFromString(type), generateStructures, generatorString);
if (this.unloadedWorlds.contains(name)) {
this.unloadedWorlds.remove(name);
}
@@ -371,7 +380,7 @@ public class WorldManager implements MVWorldManager {
if (w != null) {
World safeWorld = this.plugin.getServer().getWorlds().get(0);
List<Player> ps = w.getPlayers();
SafeTTeleporter teleporter = this.plugin.getTeleporter();
SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
for (Player p : ps) {
// We're removing players forcefully from a world, they'd BETTER spawn safely.
teleporter.safelyTeleport(null, p, safeWorld.getSpawnLocation(), true);
@@ -467,9 +476,11 @@ public class WorldManager implements MVWorldManager {
String name = w.getName();
if (!worldStrings.contains(name)) {
if (this.defaultGens.containsKey(name)) {
this.addWorld(name, w.getEnvironment(), w.getSeed() + "", w.getWorldType(), this.defaultGens.get(name));
this.addWorld(name, w.getEnvironment(), w.getSeed() + "", w.getWorldType(),
w.canGenerateStructures(), this.defaultGens.get(name));
} else {
this.addWorld(name, w.getEnvironment(), w.getSeed() + "", w.getWorldType(), null);
this.addWorld(name, w.getEnvironment(), w.getSeed() + "", w.getWorldType(),
w.canGenerateStructures(), null);
}
}
@@ -516,7 +527,7 @@ public class WorldManager implements MVWorldManager {
this.plugin.getServer().getPluginManager().removePermission(w.getAccessPermission().getName());
this.plugin.getServer().getPluginManager().removePermission(w.getExemptPermission().getName());
// Special namespace for gamemodes
this.plugin.getServer().getPluginManager().removePermission("mv.gamemode.bypass." + w.getName());
this.plugin.getServer().getPluginManager().removePermission("mv.bypass.gamemode." + w.getName());
}
// Recalc the all permission
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(allAccess);
@@ -543,6 +554,7 @@ public class WorldManager implements MVWorldManager {
String environment = this.configWorlds.getString("worlds." + worldKey + ".environment", "NORMAL");
String type = this.configWorlds.getString("worlds." + worldKey + ".type", "NORMAL");
String seedString = this.configWorlds.getString("worlds." + worldKey + ".seed", null);
boolean generateStructures = this.configWorlds.getBoolean("worlds." + worldKey + ".generatestructures", true);
if (seedString == null) {
seedString = this.configWorlds.getLong("worlds." + worldKey + ".seed") + "";
}
@@ -552,9 +564,8 @@ public class WorldManager implements MVWorldManager {
this.plugin.log(Level.WARNING, "Found SKYLANDS world. Not importing automatically, as it won't work atm :(");
continue;
}
// TODO: UNCOMMENT BEFORE RELEASE
addWorld(worldKey, EnvironmentCommand.getEnvFromString(environment), seedString,
EnvironmentCommand.getWorldTypeFromString(type), generatorString);
EnvironmentCommand.getWorldTypeFromString(type), generateStructures, generatorString);
// Increment the world count
count++;
@@ -575,10 +586,20 @@ public class WorldManager implements MVWorldManager {
/**
* {@inheritDoc}
* @deprecated This is deprecated!
*/
@Override
@Deprecated
public PurgeWorlds getWorldPurger() {
return this.worldPurger;
return new PurgeWorlds(plugin);
}
/**
* {@inheritDoc}
*/
@Override
public WorldPurger getTheWorldPurger() {
return worldPurger;
}
/**
+16 -14
View File
@@ -1,14 +1,16 @@
# This is the MV2 Config. If you mess it up, copy the values out
# delete it, and it will be regenerated. Then use the ingame interface
# to add your values back via the "/mv conf" command.
# When in-game, simply type: "/mv conf ?" for help.
# A config with explanations can be found here:
# https://github.com/Multiverse/Multiverse-Core/wiki/config.yml
worldnameprefix: true
enforceaccess: true
displaypermerrors: true
teleportintercept: true
firstspawnoverride: true
messagecooldown: 5000
version: 2.7
# ------------------------------------------------------------------------- #
# This is the MV2 Config. If you mess it up, copy the values out #
# delete it, and it will be regenerated. Then use the ingame interface #
# to add your values back via the "/mv conf" command. #
# When in-game, simply type: "/mv conf ?" for help. #
# A config with explanations can be found here: #
# https://github.com/Multiverse/Multiverse-Core/wiki/config.yml #
# #
# #
# IMPORTANT !! IMPORTANT !! IMPORTANT !! IMPORTANT !! IMPORTANT !!IMPORTANT #
# #
# Do NOT delete this line from your config!!!! #
# ==: com.onarandombox.MultiverseCore.MultiverseCoreConfiguration #
# #
# IMPORTANT !! IMPORTANT !! IMPORTANT !! IMPORTANT !! IMPORTANT !!IMPORTANT #
# ------------------------------------------------------------------------- #
@@ -22,12 +22,14 @@ import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
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;
@RunWith(PowerMockRunner.class)
@@ -54,6 +56,7 @@ public class TestDebugMode {
public void testEnableDebugMode() {
// Pull a core instance from the server.
Plugin plugin = mockServer.getPluginManager().getPlugin("Multiverse-Core");
Core core = (Core) plugin;
// Make sure Core is not null
assertNotNull(plugin);
@@ -70,12 +73,12 @@ public class TestDebugMode {
when(mockCommand.getName()).thenReturn("mv");
// Assert debug mode is off
Assert.assertEquals(0, MultiverseCore.GlobalDebug);
Assert.assertEquals(0, core.getMVConfig().getGlobalDebug());
// Send the debug command.
String[] debugArgs = new String[] { "debug", "3" };
plugin.onCommand(mockCommandSender, mockCommand, "", debugArgs);
Assert.assertEquals(3, MultiverseCore.GlobalDebug);
Assert.assertEquals(3, core.getMVConfig().getGlobalDebug());
}
}
@@ -0,0 +1,345 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2012. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.test;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.weather.ThunderChangeEvent;
import org.bukkit.event.weather.WeatherChangeEvent;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.PluginManager;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.internal.verification.VerificationModeFactory;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.test.utils.TestInstanceCreator;
import com.onarandombox.MultiverseCore.utils.WorldManager;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ PluginManager.class, MultiverseCore.class, Permission.class, Bukkit.class,
WeatherChangeEvent.class, ThunderChangeEvent.class, PlayerChatEvent.class,
PlayerJoinEvent.class, PlayerRespawnEvent.class, EntityRegainHealthEvent.class,
FoodLevelChangeEvent.class, WorldManager.class })
public class TestWorldProperties {
private TestInstanceCreator creator;
private MultiverseCore core;
private CommandSender mockCommandSender;
// Events
private WeatherChangeEvent weatherChangeOffEvent;
private WeatherChangeEvent weatherChangeOnEvent;
private ThunderChangeEvent thunderChangeOffEvent;
private ThunderChangeEvent thunderChangeOnEvent;
private Player mockPlayer;
private PlayerChatEvent playerChatEvent;
private Player mockNewPlayer;
private PlayerJoinEvent playerNewJoinEvent;
private PlayerJoinEvent playerJoinEvent;
private PlayerRespawnEvent playerRespawnBed;
private PlayerRespawnEvent playerRespawnNormal;
private Entity mockEntity;
private EntityRegainHealthEvent entityRegainHealthEvent;
private FoodLevelChangeEvent entityFoodLevelChangeEvent;
private FoodLevelChangeEvent entityFoodLevelRiseEvent;
@Before
public void setUp() throws Exception {
creator = new TestInstanceCreator();
assertTrue(creator.setUp());
core = creator.getCore();
mockCommandSender = creator.getCommandSender();
}
@After
public void tearDown() throws Exception {
creator.tearDown();
}
@Test
public void test() {
// Initialize a fake command
Command mockCommand = mock(Command.class);
when(mockCommand.getName()).thenReturn("mv");
// Import the first world
String[] normalArgs = new String[] { "import", "world", "normal" };
core.onCommand(mockCommandSender, mockCommand, "", normalArgs);
verify(mockCommandSender).sendMessage("Starting import of world 'world'...");
verify(mockCommandSender).sendMessage(ChatColor.GREEN + "Complete!");
// Import a second world
String[] netherArgs = new String[] { "import", "world_nether", "nether" };
core.onCommand(mockCommandSender, mockCommand, "", netherArgs);
verify(mockCommandSender).sendMessage("Starting import of world 'world_nether'...");
verify(mockCommandSender, VerificationModeFactory.times(2)).sendMessage(
ChatColor.GREEN + "Complete!");
// ////////////////////////////////////////////////
// let's set some world-properties
// we can test the API with this, too :D
MVWorldManager worldManager = core.getMVWorldManager();
assertNotNull(worldManager);
MultiverseWorld mvWorld = worldManager.getMVWorld("world");
MultiverseWorld netherWorld = worldManager.getMVWorld("world_nether");
assertNotNull(mvWorld);
assertNotNull(netherWorld);
assertSame(mvWorld, worldManager.getFirstSpawnWorld());
assertSame(mvWorld, worldManager.getSpawnWorld());
/* ***************************** *
* Check defaults
* ***************************** */
assertFalse(mvWorld.isHidden());
assertEquals(mvWorld.getName(), mvWorld.getAlias());
assertEquals(ChatColor.WHITE, mvWorld.getColor());
assertTrue(mvWorld.isPVPEnabled());
assertEquals((Object) 1D, (Object) mvWorld.getScaling()); // we're casting this to objects to use
// assertEquals(Object,Object) instead of assertEquals(double,double)
assertNull(mvWorld.getRespawnToWorld());
assertTrue(mvWorld.isWeatherEnabled());
World cbWorld = mvWorld.getCBWorld();
when(cbWorld.getDifficulty()).thenReturn(Difficulty.NORMAL);
assertEquals(Difficulty.NORMAL, mvWorld.getDifficulty());
assertTrue(mvWorld.canAnimalsSpawn());
assertTrue(mvWorld.canMonstersSpawn());
assertEquals(-1, mvWorld.getCurrency());
assertEquals(0, mvWorld.getPrice(), 0);
assertTrue(mvWorld.getHunger());
assertTrue(mvWorld.getAutoHeal());
assertTrue(mvWorld.getAdjustSpawn());
assertEquals(GameMode.SURVIVAL, mvWorld.getGameMode());
assertTrue(mvWorld.isKeepingSpawnInMemory());
assertTrue(mvWorld.getBedRespawn());
assertTrue(mvWorld.getAutoLoad());
assertEquals(new Location(mvWorld.getCBWorld(), 0, 64, 0), mvWorld.getSpawnLocation());
/* ****************************************** *
* Call some events and verify behavior
* ****************************************** */
createEvents(mvWorld);
// call both weather change events
core.getWeatherListener().weatherChange(weatherChangeOffEvent);
assertFalse(weatherChangeOffEvent.isCancelled());
core.getWeatherListener().weatherChange(weatherChangeOnEvent);
assertFalse(weatherChangeOnEvent.isCancelled());
// call both thunder change events
core.getWeatherListener().thunderChange(thunderChangeOffEvent);
assertFalse(thunderChangeOffEvent.isCancelled());
core.getWeatherListener().thunderChange(thunderChangeOnEvent);
assertFalse(thunderChangeOnEvent.isCancelled());
// call player chat event
core.getMVConfig().setPrefixChat(true);
core.getPlayerListener().playerChat(playerChatEvent);
verify(playerChatEvent).setFormat("[" + mvWorld.getColoredWorldString() + "]" + "format");
core.getMVConfig().setPrefixChat(false);
core.getPlayerListener().playerChat(playerChatEvent);
verify(playerChatEvent, times(1)).setFormat(anyString()); // only ONE TIME (not the 2nd time!)
// call player join events
core.getPlayerListener().playerJoin(playerJoinEvent);
verify(mockPlayer, never()).teleport(any(Location.class));
core.getPlayerListener().playerJoin(playerNewJoinEvent);
verify(mockNewPlayer).teleport(worldManager.getFirstSpawnWorld().getSpawnLocation());
// call player respawn events
core.getPlayerListener().playerRespawn(playerRespawnBed);
// bedrespawn is on so nothing should happen
verify(playerRespawnBed, never()).setRespawnLocation(any(Location.class));
core.getPlayerListener().playerRespawn(playerRespawnNormal);
verify(playerRespawnNormal).setRespawnLocation(mvWorld.getSpawnLocation());
// call entity regain health event
core.getEntityListener().entityRegainHealth(entityRegainHealthEvent);
// autoheal is on so nothing should happen
verify(entityRegainHealthEvent, never()).setCancelled(true);
/* ************************ *
* Modify & Verify
* ************************ */
mvWorld.setHidden(true);
assertEquals(true, mvWorld.isHidden());
mvWorld.setAlias("alias");
assertEquals("alias", mvWorld.getAlias());
assertTrue(mvWorld.setColor("BLACK"));
ChatColor oldColor = mvWorld.getColor();
assertFalse(mvWorld.setColor("INVALID COLOR"));
assertEquals(oldColor, mvWorld.getColor());
assertEquals(oldColor.toString() + "alias" + ChatColor.WHITE.toString(), mvWorld.getColoredWorldString());
mvWorld.setPVPMode(false);
assertEquals(false, mvWorld.isPVPEnabled());
assertTrue(mvWorld.setScaling(2D));
assertEquals((Object) 2D, (Object) mvWorld.getScaling());
assertFalse(mvWorld.setRespawnToWorld("INVALID WORLD"));
assertTrue(mvWorld.setRespawnToWorld("world_nether"));
assertSame(worldManager.getMVWorld("world_nether").getCBWorld(),
mvWorld.getRespawnToWorld());
mvWorld.setEnableWeather(false);
assertEquals(false, mvWorld.isWeatherEnabled());
assertTrue(mvWorld.setDifficulty("PEACEFUL"));
Difficulty oldDifficulty = mvWorld.getDifficulty();
assertFalse(mvWorld.setDifficulty("INVALID DIFFICULTY"));
assertEquals(oldDifficulty, mvWorld.getDifficulty());
mvWorld.setAllowAnimalSpawn(false);
assertEquals(false, mvWorld.canAnimalsSpawn());
mvWorld.setAllowMonsterSpawn(false);
assertEquals(false, mvWorld.canMonstersSpawn());
mvWorld.setCurrency(1);
assertEquals(1, mvWorld.getCurrency());
mvWorld.setPrice(1D);
assertEquals((Object) 1D, (Object) mvWorld.getPrice());
mvWorld.setHunger(false);
assertEquals(false, mvWorld.getHunger());
mvWorld.setAutoHeal(false);
assertEquals(false, mvWorld.getAutoHeal());
mvWorld.setAdjustSpawn(false);
assertEquals(false, mvWorld.getAdjustSpawn());
assertTrue(mvWorld.setGameMode("CREATIVE"));
GameMode oldGamemode = mvWorld.getGameMode();
assertFalse(mvWorld.setGameMode("INVALID GAMEMODE"));
assertEquals(oldGamemode, mvWorld.getGameMode());
mvWorld.setKeepSpawnInMemory(false);
assertEquals(false, mvWorld.isKeepingSpawnInMemory());
mvWorld.setBedRespawn(false);
assertEquals(false, mvWorld.getBedRespawn());
mvWorld.setAutoLoad(false);
assertEquals(false, mvWorld.getAutoLoad());
mvWorld.setSpawnLocation(new Location(mvWorld.getCBWorld(), 1, 1, 1));
assertEquals(new Location(mvWorld.getCBWorld(), 1, 1, 1), mvWorld.getSpawnLocation());
/* ****************************************** *
* Call some events and verify behavior
* ****************************************** */
// We have to recreate the events and the mock-objects
createEvents(mvWorld);
// call both weather change events
core.getWeatherListener().weatherChange(weatherChangeOffEvent);
assertFalse(weatherChangeOffEvent.isCancelled());
core.getWeatherListener().weatherChange(weatherChangeOnEvent);
assertTrue(weatherChangeOnEvent.isCancelled());
// call both thunder change events
core.getWeatherListener().thunderChange(thunderChangeOffEvent);
assertFalse(thunderChangeOffEvent.isCancelled());
core.getWeatherListener().thunderChange(thunderChangeOnEvent);
assertTrue(thunderChangeOnEvent.isCancelled());
// call player chat event
core.getMVConfig().setPrefixChat(true);
core.getPlayerListener().playerChat(playerChatEvent);
// never because it's hidden!
verify(playerChatEvent, never()).setFormat(
"[" + mvWorld.getColoredWorldString() + "]" + "format");
mvWorld.setHidden(false);
core.getPlayerListener().playerChat(playerChatEvent);
verify(playerChatEvent).setFormat("[" + mvWorld.getColoredWorldString() + "]" + "format");
core.getMVConfig().setPrefixChat(false);
core.getPlayerListener().playerChat(playerChatEvent);
verify(playerChatEvent, times(1)).setFormat(anyString()); // only ONE TIME (not the 2nd time!)
// call player join events
core.getPlayerListener().playerJoin(playerJoinEvent);
verify(mockPlayer, never()).teleport(any(Location.class));
core.getPlayerListener().playerJoin(playerNewJoinEvent);
verify(mockNewPlayer).teleport(new Location(mvWorld.getCBWorld(), 1, 1, 1));
// call player respawn events
core.getPlayerListener().playerRespawn(playerRespawnBed);
// bedrespawn is off so something should happen (and we've set respawn to nether...)
verify(playerRespawnBed).setRespawnLocation(netherWorld.getSpawnLocation());
core.getPlayerListener().playerRespawn(playerRespawnNormal);
verify(playerRespawnNormal).setRespawnLocation(netherWorld.getSpawnLocation());
// call entity regain health event
core.getEntityListener().entityRegainHealth(entityRegainHealthEvent);
// autoheal is off so something should happen
verify(entityRegainHealthEvent).setCancelled(true);
}
public void createEvents(MultiverseWorld mvWorld) {
//// Weather events
// weather change
weatherChangeOffEvent = new WeatherChangeEvent(mvWorld.getCBWorld(), false);
weatherChangeOnEvent = new WeatherChangeEvent(mvWorld.getCBWorld(), true);
// thunder change
thunderChangeOffEvent = new ThunderChangeEvent(mvWorld.getCBWorld(), false);
thunderChangeOnEvent = new ThunderChangeEvent(mvWorld.getCBWorld(), true);
//// Player events
// player chat
mockPlayer = mock(Player.class);
when(mockPlayer.getWorld()).thenReturn(mvWorld.getCBWorld());
when(mockPlayer.hasPlayedBefore()).thenReturn(true);
playerChatEvent = PowerMockito.mock(PlayerChatEvent.class);
when(playerChatEvent.getPlayer()).thenReturn(mockPlayer);
when(playerChatEvent.getFormat()).thenReturn("format");
// player join
mockNewPlayer = mock(Player.class);
when(mockNewPlayer.hasPlayedBefore()).thenReturn(false);
playerJoinEvent = PowerMockito.mock(PlayerJoinEvent.class);
when(playerJoinEvent.getPlayer()).thenReturn(mockPlayer);
playerNewJoinEvent = PowerMockito.mock(PlayerJoinEvent.class);
when(playerNewJoinEvent.getPlayer()).thenReturn(mockNewPlayer);
// player respawn
playerRespawnBed = PowerMockito.mock(PlayerRespawnEvent.class);
when(playerRespawnBed.getPlayer()).thenReturn(mockPlayer);
when(playerRespawnBed.isBedSpawn()).thenReturn(true);
playerRespawnNormal = PowerMockito.mock(PlayerRespawnEvent.class);
when(playerRespawnNormal.getPlayer()).thenReturn(mockPlayer);
when(playerRespawnNormal.isBedSpawn()).thenReturn(false);
//// Entity events
mockEntity = mock(Entity.class);
// entity regain health
entityRegainHealthEvent = PowerMockito.mock(EntityRegainHealthEvent.class);
when(entityRegainHealthEvent.getRegainReason()).thenReturn(RegainReason.REGEN);
when(mockEntity.getLocation()).thenReturn(new Location(mvWorld.getCBWorld(), 0, 0, 0));
when(entityRegainHealthEvent.getEntity()).thenReturn(mockEntity);
// entity food level change event
entityFoodLevelChangeEvent = PowerMockito.mock(FoodLevelChangeEvent.class);
// this won't do anything since we're not mocking a player,
// but the plugin should be able to handle this!
when(entityFoodLevelChangeEvent.getEntity()).thenReturn(mockEntity);
entityFoodLevelRiseEvent = PowerMockito.mock(FoodLevelChangeEvent.class);
when(mockPlayer.getFoodLevel()).thenReturn(2);
when(entityFoodLevelRiseEvent.getEntity()).thenReturn(mockPlayer);
when(entityFoodLevelRiseEvent.getFoodLevel()).thenReturn(3);
}
}
@@ -168,6 +168,41 @@ public class TestWorldStuff {
}
@Test
public void testNullWorld() {
// Pull a core instance from the server.
Plugin plugin = mockServer.getPluginManager().getPlugin("Multiverse-Core");
// Make sure Core is not null
assertNotNull(plugin);
// Make sure Core is enabled
assertTrue(plugin.isEnabled());
// Initialize a fake command
Command mockCommand = mock(Command.class);
when(mockCommand.getName()).thenReturn("mv");
// Ensure that there are no worlds imported. This is a fresh setup.
assertEquals(0, creator.getCore().getMVWorldManager().getMVWorlds().size());
// Create the NULL world
// The safe check is now BALLS SLOW. Use the -n to skip checking.
String[] normalArgs = new String[]{ "create", "nullworld", "normal", "-n" };
plugin.onCommand(mockCommandSender, mockCommand, "", normalArgs);
// We should now have one world!
assertEquals(1, creator.getCore().getMVWorldManager().getMVWorlds().size());
// Verify
verify(mockCommandSender).sendMessage("Starting creation of world 'nullworld'...");
verify(mockCommandSender).sendMessage("Complete!");
WorldCreatorMatcher matcher = new WorldCreatorMatcher(new WorldCreator("nullworld"));
verify(mockServer).createWorld(Matchers.argThat(matcher));
}
@Test
// TODO Migrate this to TestWorldProperties
public void testModifyGameMode() {
// Pull a core instance from the server.
Plugin plugin = mockServer.getPluginManager().getPlugin("Multiverse-Core");
@@ -40,7 +40,50 @@ public class MockWorldFactory {
when(mockWorld.getName()).thenReturn(world);
when(mockWorld.getEnvironment()).thenReturn(env);
when(mockWorld.getWorldType()).thenReturn(type);
when(mockWorld.getSpawnLocation()).thenReturn(new Location(mockWorld, 0, 0, 0));
when(mockWorld.getSpawnLocation()).thenReturn(new Location(mockWorld, 0, 64, 0));
when(mockWorld.getWorldFolder()).thenAnswer(new Answer<File>() {
public File answer(InvocationOnMock invocation) throws Throwable {
if (!(invocation.getMock() instanceof World))
return null;
World thiss = (World) invocation.getMock();
return new File(TestInstanceCreator.serverDirectory, thiss.getName());
}
});
when(mockWorld.getBlockAt(any(Location.class))).thenAnswer(new Answer<Block>() {
public Block answer(InvocationOnMock invocation) throws Throwable {
Location loc;
try {
loc = (Location) invocation.getArguments()[0];
} catch (Exception e) {
return null;
}
Material blockType = Material.AIR;
Block mockBlock = mock(Block.class);
if (loc.getBlockY() < 64) {
blockType = Material.DIRT;
}
when(mockBlock.getType()).thenReturn(blockType);
when(mockBlock.getTypeId()).thenReturn(blockType.getId());
when(mockBlock.getWorld()).thenReturn(loc.getWorld());
when(mockBlock.getX()).thenReturn(loc.getBlockX());
when(mockBlock.getY()).thenReturn(loc.getBlockY());
when(mockBlock.getZ()).thenReturn(loc.getBlockZ());
when(mockBlock.getLocation()).thenReturn(loc);
when(mockBlock.isEmpty()).thenReturn(blockType == Material.AIR);
return mockBlock;
}
});
return mockWorld;
}
private static World nullWorld(String world, World.Environment env, WorldType type) {
World mockWorld = mock(World.class);
when(mockWorld.getName()).thenReturn(world);
when(mockWorld.getEnvironment()).thenReturn(env);
when(mockWorld.getWorldType()).thenReturn(type);
when(mockWorld.getSpawnLocation()).thenReturn(new Location(mockWorld, 0, 64, 0));
when(mockWorld.getWorldFolder()).thenAnswer(new Answer<File>() {
public File answer(InvocationOnMock invocation) throws Throwable {
if (!(invocation.getMock() instanceof World))
@@ -60,7 +103,7 @@ public class MockWorldFactory {
}
Block mockBlock = mock(Block.class);
Material blockType = Material.AIR; // TODO we might use other materials, too
Material blockType = Material.AIR;
when(mockBlock.getType()).thenReturn(blockType);
when(mockBlock.getTypeId()).thenReturn(blockType.getId());
@@ -82,6 +125,12 @@ public class MockWorldFactory {
return w;
}
public static World makeNewNullMockWorld(String world, World.Environment env, WorldType type) {
World w = nullWorld(world, env, type);
registerWorld(w);
return w;
}
public static World makeNewMockWorld(String world, World.Environment env, WorldType type, long seed,
ChunkGenerator generator) {
World mockWorld = basics(world, env, type);
@@ -96,7 +145,13 @@ public class MockWorldFactory {
}
public static List<World> getWorlds() {
return new ArrayList<World>(createdWorlds.values());
// we have to invert the order!
ArrayList<World> myList = new ArrayList<World>(createdWorlds.values());
List<World> retList = new ArrayList<World>();
for (int i = (myList.size() - 1); i >= 0; i--) {
retList.add(myList.get(i));
}
return retList;
}
public static void clearWorlds() {
@@ -26,9 +26,11 @@ import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permission;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.mockito.Matchers;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
@@ -36,6 +38,9 @@ import org.powermock.api.mockito.PowerMockito;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.listeners.MVEntityListener;
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
import com.onarandombox.MultiverseCore.listeners.MVWeatherListener;
import com.onarandombox.MultiverseCore.utils.FileUtils;
import com.onarandombox.MultiverseCore.utils.WorldManager;
@@ -122,12 +127,45 @@ public class TestInstanceCreator {
} catch (Exception e) {
return null;
}
// Add special case for creating null worlds.
// Not sure I like doing it this way, but this is a special case
if (arg.name().equalsIgnoreCase("nullworld")) {
return MockWorldFactory.makeNewNullMockWorld(arg.name(), arg.environment(), arg.type());
}
return MockWorldFactory.makeNewMockWorld(arg.name(), arg.environment(), arg.type());
}
});
when(mockServer.unloadWorld(anyString(), anyBoolean())).thenReturn(true);
// add mock scheduler
BukkitScheduler mockScheduler = mock(BukkitScheduler.class);
when(mockScheduler.scheduleSyncDelayedTask(any(Plugin.class), any(Runnable.class), anyLong())).
thenAnswer(new Answer<Integer>() {
public Integer answer(InvocationOnMock invocation) throws Throwable {
Runnable arg;
try {
arg = (Runnable) invocation.getArguments()[1];
} catch (Exception e) {
return null;
}
arg.run();
return null;
}});
when(mockScheduler.scheduleSyncDelayedTask(any(Plugin.class), any(Runnable.class))).
thenAnswer(new Answer<Integer>() {
public Integer answer(InvocationOnMock invocation) throws Throwable {
Runnable arg;
try {
arg = (Runnable) invocation.getArguments()[1];
} catch (Exception e) {
return null;
}
arg.run();
return null;
}});
when(mockServer.getScheduler()).thenReturn(mockScheduler);
// Set server
Field serverfield = JavaPlugin.class.getDeclaredField("server");
serverfield.setAccessible(true);
@@ -139,6 +177,24 @@ public class TestInstanceCreator {
worldmanagerfield.setAccessible(true);
worldmanagerfield.set(core, wm);
// Set playerListener
MVPlayerListener pl = PowerMockito.spy(new MVPlayerListener(core));
Field playerlistenerfield = MultiverseCore.class.getDeclaredField("playerListener");
playerlistenerfield.setAccessible(true);
playerlistenerfield.set(core, pl);
// Set entityListener
MVEntityListener el = PowerMockito.spy(new MVEntityListener(core));
Field entitylistenerfield = MultiverseCore.class.getDeclaredField("entityListener");
entitylistenerfield.setAccessible(true);
entitylistenerfield.set(core, el);
// Set weatherListener
MVWeatherListener wl = PowerMockito.spy(new MVWeatherListener(core));
Field weatherlistenerfield = MultiverseCore.class.getDeclaredField("weatherListener");
weatherlistenerfield.setAccessible(true);
weatherlistenerfield.set(core, wl);
// Init our command sender
final Logger commandSenderLogger = Logger.getLogger("CommandSender");
commandSenderLogger.setParent(Util.logger);