Compare commits

..
Author SHA1 Message Date
main() caf4f1b566 Bukkit perms are broken.
Or at least they don't work the way they (in my opinion) should. Take a
look at HierarchyPermission.java for a detailed explanation.
2013-04-13 02:26:19 +02:00
main() 4a66a2f5bb If the debug level is >= 1: stacktrace 2013-03-18 18:02:55 +01:00
main() a8040abd52 "Not MV's fault"-Message for getChunkGenerator()
If a plugin, for whatever weird reason, gets loaded and enabled correctly,
but just getDefaultWorldGenerator() throws, people might think it's MV's
fault. Not anymore.
2013-03-18 17:27:03 +01:00
Jeremy Wood 72a14719ac Now using apache commons for file operations. Hopefully we will get more success with deleting and copying stuff. May fix Inventories test failures. 2013-03-11 15:35:05 -04:00
main() 2b827a1fae Style fixes. 2013-03-02 13:13:24 +01:00
main() e45520c43b Update checkstyle. 2013-03-02 13:13:09 +01:00
main() 0fb33d12d6 Now mocking plugin.getLogger() in the tests.
Fixes the test issues with AllPay.
2013-03-02 12:31:31 +01:00
main() ebe44ed99e Fixed the GenericBank imports 2013-03-02 12:24:05 +01:00
Jeremy Wood 23ba7fe73b Updated to AllPay 13. 2013-02-26 09:49:38 -05:00
Jeremy Wood 4efa97ee0e Removing deprecated getMVConfiguration() method because I suspect it could be related to some issues. 2013-02-20 13:56:24 -05:00
Jeremy Wood 8bfe3a5473 Don't try to set search radius when portal travel agent is null. Fixes #1072. 2013-02-04 15:15:52 -05:00
Jeremy Wood 07a38e3e58 Should fix issue where gamemode/flight change on /reload of server due to permission issues. 2013-01-02 13:20:52 -05:00
Jeremy Wood 360c63fad9 Updated to AllPay 11 2013-01-02 11:44:38 -05:00
Jeremy Wood 2a5edc4f91 Added argument check to setBlockSafety. 2012-12-27 16:02:46 -05:00
main() fa9191dd8f The message now CLEARLY states that it's not Multiverse's fault. 2012-12-22 15:26:20 +01:00
main() 4043d5abcb Getting the generator is now wrapped in a try block.
The Bukkit API calls a plugin method. If that method throws exceptions, they fall through right into our face and then Bukkit blames us. Not good.
Thanks andrewkm for mentioning this.
2012-12-22 00:53:03 +01:00
Jeremy Wood eff56f74da Changed the default portal search radius back to match vanilla's 128 instead of 16. 2012-12-21 10:14:45 -05:00
Jeremy Wood d97a9bccde Now building against Vault 1.2.20 which is hosted on our own repo now. 2012-12-13 08:50:32 -05:00
Jeremy Wood 55741b524d Added bats to animals for the time being. Fixes #996 2012-12-10 23:27:55 -05:00
Jeremy Wood 186d3f15a4 Woo, Travis.ci! 2012-12-10 12:04:26 -08:00
32 changed files with 483 additions and 462 deletions

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
language: java
jdk:
- oraclejdk6
notifications:
email: false
-1
View File
@@ -104,7 +104,6 @@
</module>
<module name="LeftCurly"/>
<module name="RightCurly"/>
<module name="DoubleCheckedLocking"/>
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="HiddenField">
+33 -19
View File
@@ -26,10 +26,10 @@
<url>http://repo.mcstats.org/content/repositories/snapshots</url>
</repository>
<!-- Required for Vault -->
<repository>
<!--repository>
<id>herocraft</id>
<url>http://ci.herocraftonline.com/plugin/repository/everything/</url>
</repository>
</repository-->
</repositories>
<pluginRepositories>
@@ -134,7 +134,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.8</version>
<version>2.10</version>
<configuration>
<enableRulesSummary>true</enableRulesSummary>
<configLocation>${project.basedir}/config/mv_checks.xml</configLocation>
@@ -185,7 +185,6 @@
<include>com.dumptruckman.minecraft:buscript</include>
<include>org.mcstats:metrics</include>
<include>com.dumptruckman.minecraft:Logging</include>
<include>com.dumptruckman.minecraft:Permissions-Bukkit</include>
<include>com.fernferret.allpay:AllPay</include>
</includes>
</artifactSet>
@@ -214,10 +213,6 @@
<pattern>com.dumptruckman.minecraft.util.Logging</pattern>
<shadedPattern>com.onarandombox.MultiverseCore.utils.CoreLogging</shadedPattern>
</relocation>
<relocation>
<pattern>com.dumptruckman.minecraft.pluginbase</pattern>
<shadedPattern>com.onarandombox.MultiverseCore.pluginbase</shadedPattern>
</relocation>
<relocation>
<pattern>com.dumptruckman.minecraft.util.DebugLog</pattern>
<shadedPattern>com.onarandombox.MultiverseCore.utils.DebugFileLogger</shadedPattern>
@@ -225,12 +220,40 @@
</relocations>
</configuration>
</execution>
<execution>
<id>apache-commons-io</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>org.apache.commons:commons-io</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.apache.commons</pattern>
<shadedPattern>org.apache.commons.multiverse</shadedPattern>
</relocation>
</relocations>
<minimizeJar>true</minimizeJar>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- Bukkit Dependency -->
<dependency>
<groupId>org.bukkit</groupId>
@@ -262,14 +285,14 @@
<dependency>
<groupId>com.fernferret.allpay</groupId>
<artifactId>AllPay</artifactId>
<version>10</version>
<version>13</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>Vault</artifactId>
<version>1.2.19-SNAPSHOT</version>
<version>1.2.20</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
@@ -310,15 +333,6 @@
<scope>compile</scope>
</dependency>
<!-- End of Logging Dependency -->
<!-- Start of Permissions lib Dependency -->
<dependency>
<groupId>com.dumptruckman.minecraft</groupId>
<artifactId>Permissions-Bukkit</artifactId>
<version>1.5-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- End of Permissions lib Dependency -->
<!-- Start of Test Dependencies -->
<dependency>
<groupId>junit</groupId>
@@ -16,7 +16,6 @@ import com.onarandombox.MultiverseCore.configuration.WorldPropertyValidator;
import com.onarandombox.MultiverseCore.enums.AllowedPortalType;
import com.onarandombox.MultiverseCore.enums.EnglishChatColor;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
import com.onarandombox.MultiverseCore.utils.Permissions;
import me.main__.util.SerializationConfig.ChangeDeniedException;
import me.main__.util.SerializationConfig.NoSuchPropertyException;
import me.main__.util.SerializationConfig.VirtualProperty;
@@ -31,6 +30,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.configuration.serialization.SerializableAs;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.util.Vector;
import org.json.simple.JSONObject;
@@ -50,7 +50,7 @@ public class MVWorld implements MultiverseWorld {
private final MultiverseCore plugin; // Hold the Plugin Instance.
private final String name; // The Worlds Name, EG its folder name.
private final UUID worldUID;
final WorldProperties props;
private final WorldProperties props;
public MVWorld(MultiverseCore plugin, World world, WorldProperties properties) {
this(plugin, world, properties, true);
@@ -84,6 +84,8 @@ public class MVWorld implements MultiverseWorld {
this.props.environment = world.getEnvironment();
this.props.seed = world.getSeed();
this.initPerms();
this.props.flushChanges();
validateProperties();
@@ -320,7 +322,10 @@ public class MVWorld implements MultiverseWorld {
}
}
private Permission permission;
private Permission exempt;
private Permission ignoreperm;
private Permission limitbypassperm;
/**
* Null-location.
@@ -366,6 +371,37 @@ public class MVWorld implements MultiverseWorld {
};
}
/**
* Initializes permissions.
*/
private void initPerms() {
this.permission = new Permission("multiverse.access." + this.getName(), "Allows access to " + this.getName(), PermissionDefault.OP);
// This guy is special. He shouldn't be added to any parent perms.
this.ignoreperm = new Permission("mv.bypass.gamemode." + this.getName(),
"Allows players with this permission to ignore gamemode changes.", PermissionDefault.FALSE);
this.exempt = new Permission("multiverse.exempt." + this.getName(),
"A player who has this does not pay to enter this world, or use any MV portals in it " + this.getName(), PermissionDefault.OP);
this.limitbypassperm = new Permission("mv.bypass.playerlimit." + this.getName(),
"A player who can enter this world regardless of wether its full", PermissionDefault.OP);
try {
this.plugin.getServer().getPluginManager().addPermission(this.permission);
this.plugin.getServer().getPluginManager().addPermission(this.exempt);
this.plugin.getServer().getPluginManager().addPermission(this.ignoreperm);
this.plugin.getServer().getPluginManager().addPermission(this.limitbypassperm);
// Add the permission and exempt to parents.
this.addToUpperLists(this.permission);
// Add ignore to it's parent:
this.ignoreperm.addParent("mv.bypass.gamemode.*", true);
// Add limit bypass to it's parent
this.limitbypassperm.addParent("mv.bypass.playerlimit.*", true);
} catch (IllegalArgumentException e) {
this.plugin.log(Level.FINER, "Permissions nodes were already added for " + this.name);
}
}
private Location readSpawnFromWorld(World w) {
Location location = w.getSpawnLocation();
// Set the worldspawn to our configspawn
@@ -408,10 +444,44 @@ public class MVWorld implements MultiverseWorld {
return location;
}
private void addToUpperLists(Permission perm) {
Permission all = this.plugin.getServer().getPluginManager().getPermission("multiverse.*");
Permission allWorlds = this.plugin.getServer().getPluginManager().getPermission("multiverse.access.*");
Permission allExemption = this.plugin.getServer().getPluginManager().getPermission("multiverse.exempt.*");
if (allWorlds == null) {
allWorlds = new Permission("multiverse.access.*");
this.plugin.getServer().getPluginManager().addPermission(allWorlds);
}
allWorlds.getChildren().put(perm.getName(), true);
if (allExemption == null) {
allExemption = new Permission("multiverse.exempt.*");
this.plugin.getServer().getPluginManager().addPermission(allExemption);
}
allExemption.getChildren().put(this.exempt.getName(), true);
if (all == null) {
all = new Permission("multiverse.*");
this.plugin.getServer().getPluginManager().addPermission(all);
}
all.getChildren().put("multiverse.access.*", true);
all.getChildren().put("multiverse.exempt.*", true);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(all);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(allWorlds);
}
/**
* Copies all properties from another {@link MVWorld} object.
* @param other The other world object.
*/
public void copyValues(MVWorld other) {
props.copyValues(other.props);
}
/**
* Copies all properties from a {@link WorldProperties} object.
* @param other The world properties object.
*/
public void copyValues(WorldProperties other) {
props.copyValues(other);
}
@@ -854,7 +924,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public Permission getAccessPermission() {
return Permissions.ACCESS.getPermission(getName());
return this.permission;
}
/**
@@ -894,7 +964,7 @@ public class MVWorld implements MultiverseWorld {
*/
@Override
public Permission getExemptPermission() {
return Permissions.COST_EXEMPT.getPermission(getName());
return this.exempt;
}
/**
@@ -8,10 +8,9 @@
package com.onarandombox.MultiverseCore;
import buscript.Buscript;
import com.dumptruckman.minecraft.pluginbase.permission.BukkitPermFactory;
import com.dumptruckman.minecraft.util.Logging;
import com.fernferret.allpay.AllPay;
import com.fernferret.allpay.GenericBank;
import com.fernferret.allpay.commons.GenericBank;
import com.onarandombox.MultiverseCore.MVWorld.NullLocation;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.Core;
@@ -81,6 +80,7 @@ import com.onarandombox.MultiverseCore.utils.MVPlayerSession;
import com.onarandombox.MultiverseCore.utils.SimpleBlockSafety;
import com.onarandombox.MultiverseCore.utils.SimpleLocationManipulation;
import com.onarandombox.MultiverseCore.utils.SimpleSafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper;
import com.onarandombox.MultiverseCore.utils.VaultHandler;
import com.onarandombox.MultiverseCore.utils.WorldManager;
import com.pneumaticraft.commandhandler.CommandHandler;
@@ -219,14 +219,12 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
private BlockSafety blockSafety;
private LocationManipulation locationManipulation;
private SafeTTeleporter safeTTeleporter;
private UnsafeCallWrapper unsafeCallWrapper;
private File serverFolder = new File(System.getProperty("user.dir"));
@Override
public void onLoad() {
// Register permission handler
BukkitPermFactory.registerPermissionName(getClass(), "multiverse");
BukkitPermFactory.registerPermissionName(Core.class, "multiverse");
// Register our config
SerializationConfig.registerAll(MultiverseCoreConfiguration.class);
// Register our world
@@ -242,16 +240,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
this.locationManipulation = new SimpleLocationManipulation();
// Setup our SafeTTeleporter
this.safeTTeleporter = new SimpleSafeTTeleporter(this);
}
/**
* {@inheritDoc}
* @deprecated This is deprecated.
*/
@Override
@Deprecated
public FileConfiguration getMVConfiguration() {
return this.multiverseConfig;
this.unsafeCallWrapper = new UnsafeCallWrapper(this);
}
/**
@@ -1238,6 +1227,9 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*/
@Override
public void setBlockSafety(BlockSafety bs) {
if (bs == null) {
throw new NullPointerException("block safety may not be null.");
}
this.blockSafety = bs;
}
@@ -1296,4 +1288,8 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
public Buscript getScriptAPI() {
return buscript;
}
public UnsafeCallWrapper getUnsafeCallWrapper() {
return this.unsafeCallWrapper;
}
}
@@ -1,12 +1,10 @@
package com.onarandombox.MultiverseCore;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.api.MultiverseCoreConfig;
import me.main__.util.SerializationConfig.NoSuchPropertyException;
import me.main__.util.SerializationConfig.Property;
import me.main__.util.SerializationConfig.SerializationConfig;
import com.dumptruckman.minecraft.util.*;
import com.onarandombox.MultiverseCore.api.*;
import me.main__.util.SerializationConfig.*;
import java.util.Map;
import java.util.*;
/**
* Our configuration.
@@ -96,7 +94,7 @@ public class MultiverseCoreConfiguration extends SerializationConfig implements
this.version = 2.9;
silentstart = false;
defaultportalsearch = false;
portalsearchradius = 16;
portalsearchradius = 128;
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
}
@@ -29,6 +29,11 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* This is a property class, I think we don't need that much javadoc.
* BEGIN CHECKSTYLE-SUPPRESSION: Javadoc
*/
@SerializableAs("MVWorld")
public class WorldProperties extends SerializationConfig {
@@ -235,7 +240,7 @@ public class WorldProperties extends SerializationConfig {
@Property(serializor = EnumPropertySerializor.class, description = "Sorry, 'style' must be a valid style-name.")
private volatile EnglishChatStyle style;
@Property(description = "Sorry, 'pvp' must either be: true or false.", virtualType = Boolean.class, persistVirtual = true)
volatile VirtualProperty<Boolean> pvp;
volatile VirtualProperty<Boolean> pvp; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property(description = "Scale must be a positive double value. ex: 2.3")
private volatile double scale;
@Property(description = "You must set this to the NAME not alias of a world.")
@@ -244,7 +249,7 @@ public class WorldProperties extends SerializationConfig {
private volatile boolean allowWeather;
@Property(serializor = DifficultyPropertySerializor.class, virtualType = Difficulty.class, persistVirtual = true,
description = "Difficulty must be set as one of the following: peaceful easy normal hard")
volatile VirtualProperty<Difficulty> difficulty;
volatile VirtualProperty<Difficulty> difficulty; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property(description = "Sorry, 'animals' must either be: true or false.")
private volatile SpawnSettings spawning;
@Property
@@ -260,12 +265,12 @@ public class WorldProperties extends SerializationConfig {
@Property(serializor = GameModePropertySerializor.class, description = "GameMode must be set as one of the following: survival creative")
private volatile GameMode gameMode;
@Property(description = "Sorry, this must either be: true or false.", virtualType = Boolean.class, persistVirtual = true)
volatile VirtualProperty<Boolean> keepSpawnInMemory;
volatile VirtualProperty<Boolean> keepSpawnInMemory; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property
volatile SpawnLocation spawnLocation;
volatile SpawnLocation spawnLocation; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property(virtualType = Location.class,
description = "There is no help available for this variable. Go bug Rigby90 about it.")
volatile VirtualProperty<Location> spawn;
volatile VirtualProperty<Location> spawn; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property(description = "Set this to false ONLY if you don't want this world to load itself on server restart.")
private volatile boolean autoLoad;
@Property(description = "If a player dies in this world, shoudld they go to their bed?")
@@ -274,11 +279,11 @@ public class WorldProperties extends SerializationConfig {
private volatile List<String> worldBlacklist;
@Property(serializor = TimePropertySerializor.class, virtualType = Long.class,
description = "Set the time to whatever you want! (Will NOT freeze time)")
volatile VirtualProperty<Long> time;
volatile VirtualProperty<Long> time; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property
volatile Environment environment;
volatile Environment environment; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property
volatile long seed;
volatile long seed; // SUPPRESS CHECKSTYLE: VisibilityModifier
@Property
private volatile String generator;
@Property
@@ -547,7 +552,7 @@ public class WorldProperties extends SerializationConfig {
return this.difficulty.get();
}
@Deprecated
@Deprecated // SUPPRESS CHECKSTYLE: Deprecated
public boolean setDifficulty(String difficulty) {
return this.setPropertyUnchecked("difficulty", difficulty);
}
@@ -9,7 +9,7 @@ package com.onarandombox.MultiverseCore.api;
import buscript.Buscript;
import com.fernferret.allpay.AllPay;
import com.fernferret.allpay.GenericBank;
import com.fernferret.allpay.commons.GenericBank;
import com.onarandombox.MultiverseCore.destination.DestinationFactory;
import com.onarandombox.MultiverseCore.utils.AnchorManager;
import com.onarandombox.MultiverseCore.utils.MVPermissions;
@@ -19,7 +19,6 @@ import com.onarandombox.MultiverseCore.utils.SimpleLocationManipulation;
import com.onarandombox.MultiverseCore.utils.SimpleSafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.VaultHandler;
import com.pneumaticraft.commandhandler.CommandHandler;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
/**
@@ -29,15 +28,6 @@ import org.bukkit.entity.Player;
*/
public interface Core {
/**
* Gets the Multiverse config file.
*
* @return The Multiverse config file.
* @deprecated Don't modify the config-file manually!
*/
@Deprecated
FileConfiguration getMVConfiguration();
/**
* Gets the Banking system that Multiverse-Core has hooked into.
*
@@ -9,7 +9,6 @@ package com.onarandombox.MultiverseCore.api;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.permissions.Permissible;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
@@ -131,14 +130,6 @@ public interface MVDestination {
*/
String getRequiredPermission();
/**
* Checks whether the given permissible has the permission to go to this destination.
*
* @param permissible Whoever we need to check permissions for.
* @return True if they are allowed to go to this destination based on permissions.
*/
boolean hasRequiredPermission(Permissible permissible);
/**
* Should the Multiverse SafeTeleporter be used?
* <p>
@@ -245,18 +245,14 @@ public interface MultiverseWorld {
* Gets the permission required to enter this world.
*
* @return The permission required to be exempt from charges to/from this world.
* @deprecated Now using {@link com.onarandombox.MultiverseCore.utils.Permissions#ACCESS}.
*/
@Deprecated
Permission getAccessPermission();
/**
* Gets the permission required to be exempt when entering.
*
* @return The permission required to be exempt when entering.
* @deprecated Now using {@link com.onarandombox.MultiverseCore.utils.Permissions#COST_EXEMPT}.
*/
@Deprecated
Permission getExemptPermission();
// end of permission stuff
@@ -9,7 +9,6 @@ package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.Permissions;
import org.bukkit.ChatColor;
import org.bukkit.World.Environment;
import org.bukkit.command.CommandSender;
@@ -66,7 +65,7 @@ public class ListCommand extends PaginatedCoreCommand<String> {
}
}
for (String name : this.plugin.getMVWorldManager().getUnloadedWorlds()) {
if (p == null || Permissions.ACCESS.hasPermission(p, name)) {
if (p == null || this.plugin.getMVPerms().hasPermission(p, "multiverse.access." + name, true)) {
worldList.add(ChatColor.GRAY + name + " - UNLOADED");
}
}
@@ -9,10 +9,8 @@ package com.onarandombox.MultiverseCore.destination;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.utils.Permissions;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.permissions.Permissible;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
@@ -136,15 +134,7 @@ public class AnchorDestination implements MVDestination {
*/
@Override
public String getRequiredPermission() {
return Permissions.ACCESS.getName(this.location.getWorld().getName());
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasRequiredPermission(Permissible permissible) {
return Permissions.ACCESS.hasPermission(permissible, this.location.getWorld().getName());
return "multiverse.access." + this.location.getWorld().getName();
}
/**
@@ -9,12 +9,10 @@ package com.onarandombox.MultiverseCore.destination;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.utils.Permissions;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permissible;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
@@ -106,22 +104,11 @@ public class BedDestination implements MVDestination {
@Override
public String getRequiredPermission() {
if (knownBedLoc != null) {
return Permissions.ACCESS.getName(knownBedLoc.getWorld().getName());
return "multiverse.access." + knownBedLoc.getWorld().getName();
}
return "";
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasRequiredPermission(Permissible permissible) {
if (knownBedLoc != null) {
Permissions.ACCESS.hasPermission(permissible, knownBedLoc.getWorld().getName());
}
return true;
}
/**
* {@inheritDoc}
*/
@@ -9,10 +9,8 @@ package com.onarandombox.MultiverseCore.destination;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.utils.Permissions;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.permissions.Permissible;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
@@ -207,15 +205,7 @@ public class CannonDestination implements MVDestination {
*/
@Override
public String getRequiredPermission() {
return Permissions.ACCESS.getName(this.location.getWorld().getName());
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasRequiredPermission(Permissible permissible) {
return Permissions.ACCESS.hasPermission(permissible, this.location.getWorld().getName());
return "multiverse.access." + this.location.getWorld().getName();
}
/**
@@ -9,10 +9,8 @@ package com.onarandombox.MultiverseCore.destination;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.utils.Permissions;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.permissions.Permissible;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
@@ -210,15 +208,7 @@ public class ExactDestination implements MVDestination {
*/
@Override
public String getRequiredPermission() {
return Permissions.ACCESS.getName(this.location.getWorld().getName());
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasRequiredPermission(Permissible permissible) {
return Permissions.ACCESS.hasPermission(permissible, this.location.getWorld().getName());
return "multiverse.access." + this.location.getWorld().getName();
}
/**
@@ -11,10 +11,8 @@ 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.Permissions;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.permissions.Permissible;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
@@ -151,15 +149,9 @@ public class WorldDestination implements MVDestination {
*/
@Override
public String getRequiredPermission() {
return Permissions.ACCESS.getName(this.world.getName());
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasRequiredPermission(Permissible permissible) {
return Permissions.ACCESS.hasPermission(permissible, this.world.getName());
// TODO: Potenitally replace spaces wiht tabs for friendlier yaml.
// this.world.getName().replace(" ","_");
return "multiverse.access." + this.world.getName();
}
/**
@@ -21,6 +21,10 @@ public class MVMapListener implements Listener {
this.plugin = plugin;
}
/**
* This method is called when a map is initialized.
* @param event The event that was fired.
*/
@EventHandler
public void mapInitialize(final MapInitializeEvent event) {
for (final Player player : Bukkit.getOnlinePlayers()) {
@@ -13,7 +13,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.Permissions;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -121,7 +120,7 @@ public class MVPlayerListener implements Listener {
} else {
this.plugin.log(Level.FINER, "Player joined AGAIN!");
if (this.plugin.getMVConfig().getEnforceAccess() // check this only if we're enforcing access!
&& !Permissions.ACCESS.hasPermission(p, p.getWorld().getName())) {
&& !this.plugin.getMVPerms().hasPermission(p, "multiverse.access." + p.getWorld().getName(), false)) {
p.sendMessage("[MV] - Sorry you can't be in this world anymore!");
this.sendPlayerToDefaultWorld(p);
}
@@ -202,8 +201,8 @@ public class MVPlayerListener implements Listener {
if (event.isCancelled() && teleporter != null) {
this.plugin.log(Level.FINE, "Player '" + teleportee.getName()
+ "' was DENIED ACCESS to '" + toWorld.getAlias()
+ "' because '" + teleporter.getName() + "' don't have: "
+ Permissions.ACCESS.getName(event.getTo().getWorld().getName()));
+ "' because '" + teleporter.getName()
+ "' don't have: multiverse.access." + event.getTo().getWorld().getName());
return;
}
} else {
@@ -217,9 +216,11 @@ public class MVPlayerListener implements Listener {
if (toWorld.getCBWorld().getPlayers().size() >= toWorld.getPlayerLimit()) {
// Ouch the world is full, lets see if the player can bypass that limitation
if (!pt.playerCanBypassPlayerLimit(toWorld, teleporter, teleportee)) {
Logging.fine("Player '%s' was DENIED ACCESS to '%s' because the world is full and '%s' doesn't have: %s.%s",
teleportee.getName(), toWorld.getAlias(), teleporter.getName(),
Permissions.BYPASS_PLAYERLIMIT.getName(), event.getTo().getWorld().getName());
this.plugin.log(Level.FINE, "Player '" + teleportee.getName()
+ "' was DENIED ACCESS to '" + toWorld.getAlias()
+ "' because the world is full and '" + teleporter.getName()
+ "' doesn't have: mv.bypass.playerlimit." + event.getTo().getWorld().getName());
event.setCancelled(true);
return;
}
}
@@ -290,18 +291,16 @@ public class MVPlayerListener implements Listener {
if (plugin.getMVConfig().getEnforceAccess()) {
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, event.getPlayer(), event.getPlayer()));
if (event.isCancelled()) {
//
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName()
+ "' was DENIED ACCESS to '" + event.getTo().getWorld().getName()
+ "' because they don't have: "
+ Permissions.ACCESS.getName(event.getTo().getWorld().getName()));
+ "' because they don't have: multiverse.access." + event.getTo().getWorld().getName());
}
} else {
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName()
+ "' was allowed to go to '" + event.getTo().getWorld().getName()
+ "' because enforceaccess is off.");
}
if (!plugin.getMVConfig().isUsingDefaultPortalSearch()) {
if (!plugin.getMVConfig().isUsingDefaultPortalSearch() && event.getPortalTravelAgent() != null) {
event.getPortalTravelAgent().setSearchRadius(plugin.getMVConfig().getPortalSearchRadius());
}
}
@@ -337,38 +336,37 @@ public class MVPlayerListener implements Listener {
public void handleGameModeAndFlight(final Player player, final MultiverseWorld world) {
// We perform this task one tick later to MAKE SURE that the player actually reaches the
// destination world, otherwise we'd be changing the player mode if they havent moved anywhere.
if (!this.pt.playerCanIgnoreGameModeRestriction(world, player)) {
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin,
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin,
new Runnable() {
@Override
public void run() {
// Check that the player is in the new world and they haven't been teleported elsewhere or the event cancelled.
if (player.getWorld() == world.getCBWorld()) {
Logging.fine("Handling gamemode for player: %s, Changing to %s", player.getName(), world.getGameMode().toString());
Logging.finest("From World: %s", player.getWorld());
Logging.finest("To World: %s", world);
player.setGameMode(world.getGameMode());
if (!MVPlayerListener.this.pt.playerCanIgnoreGameModeRestriction(world, player)) {
// Check that the player is in the new world and they haven't been teleported elsewhere or the event cancelled.
if (player.getWorld() == world.getCBWorld()) {
Logging.fine("Handling gamemode for player: %s, Changing to %s", player.getName(), world.getGameMode().toString());
Logging.finest("From World: %s", player.getWorld());
Logging.finest("To World: %s", world);
player.setGameMode(world.getGameMode());
// Check if their flight mode should change
// TODO need a override permission for this
if (player.getAllowFlight() && !world.getAllowFlight() && player.getGameMode() != GameMode.CREATIVE) {
player.setAllowFlight(false);
if (player.isFlying()) {
player.setFlying(false);
}
} else if (world.getAllowFlight()) {
if (player.getGameMode() == GameMode.CREATIVE) {
player.setAllowFlight(true);
}
}
} else {
Logging.fine("The gamemode/allowfly was NOT changed for player '%s' because he is now in world '%s' instead of world '%s'",
player.getName(), player.getWorld().getName(), world.getName());
}
} else {
Logging.fine("The gamemode was NOT changed for player '%s' because he is now in world '%s' instead of world '%s'",
player.getName(), player.getWorld().getName(), world.getName());
MVPlayerListener.this.plugin.log(Level.FINE, "Player: " + player.getName() + " is IMMUNE to gamemode changes!");
}
}
}, 1L);
} else {
this.plugin.log(Level.FINE, "Player: " + player.getName() + " is IMMUNE to gamemode changes!");
}
// TODO need a override permission for this
if (player.getAllowFlight() && !world.getAllowFlight() && player.getGameMode() != GameMode.CREATIVE) {
if (!this.pt.playerCanIgnoreAllowFlightRestriction(world, player)) {
player.setAllowFlight(false);
if (player.isFlying()) {
player.setFlying(false);
}
}
} else if (world.getAllowFlight()) {
if (player.getGameMode() == GameMode.CREATIVE) {
player.setAllowFlight(true);
}
}
}
}
@@ -0,0 +1,52 @@
package com.onarandombox.MultiverseCore.permissions;
import org.bukkit.Bukkit;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.Permissible;
import org.bukkit.permissions.PermissionDefault;
/**
* Provides improved parent-child relationships for permissions. This is the standard implementation of {@link PermissionNode}.
* <p>
* Apparently parents override their children in Bukkit:
* Let {@code permissionA} be a parent permission of {@code permissionB}, setting {@code permissionB} to {@code true}.
* Now a player has {@code permissionA=true} and {@code permissionB=false}. Result: Both are {@code true}.
* Another player has {@code permissionA=false} and {@code permissionB=true}. Result: Both are {@code false}.
* <p>
* This is completely useless for things like MV's world access permissions where you could for example want to deny
* access to all worlds by default, with a few exceptions.
* <p>
* This class takes over all the permission hierarchy checks and provides a way that makes sense. In the
* above examples, the effective permissions would be equal to the permissions that were set.
*/
public class HierarchyPermission implements PermissionNode {
private final PermissionNode parent;
private final Permission permission;
public HierarchyPermission(final PermissionNode parent, final String permission, final String description) {
this.parent = parent;
Permission p = Bukkit.getServer().getPluginManager().getPermission(permission);
if (p == null)
p = new Permission(permission, description, PermissionDefault.FALSE);
else {
p.getChildren().clear();
//p.recalculatePermissibles(); // Not necessary because it's done automatically after setting the default
p.setDefault(PermissionDefault.FALSE);
}
this.permission = p;
}
/**
* Checks whether a given {@link Permissible} has this {@link HierarchyPermission}.
*
* @param permissible The {@link Permissible} that might have the permission.
* @return Whether it has the permission.
*/
public boolean has(Permissible permissible) {
if (permissible.isPermissionSet(permission))
return permissible.hasPermission(permission);
// ask the guy over there
return parent.has(permissible);
}
}
@@ -0,0 +1,38 @@
package com.onarandombox.MultiverseCore.permissions;
import org.bukkit.permissions.Permissible;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a permission node with dynamically created children.
*/
public class PermissionCollection {
private final PermissionNode root;
private final Map<String, PermissionNode> elements;
private final String prefix;
private final String description;
public PermissionCollection(PermissionNode parent, String prefix, String description) {
if (!prefix.endsWith("."))
throw new IllegalArgumentException("The prefix must end with a dot!");
this.root = new HierarchyPermission(parent, prefix + "*", description);
this.elements = new HashMap<String, PermissionNode>();
this.prefix = prefix;
this.description = description;
}
/**
* Checks whether a given {@link Permissible} has a specified element permission.
*
* @param p The {@link Permissible}.
* @param element The element.
* @return Whether the {@link Permissible} has the permission.
*/
public boolean has(Permissible p, String element) {
if (!this.elements.containsKey(element))
this.elements.put(element, new HierarchyPermission(root, prefix + element, description));
return this.elements.get(element).has(p);
}
}
@@ -0,0 +1,30 @@
package com.onarandombox.MultiverseCore.permissions;
import org.bukkit.permissions.Permissible;
/**
* A node in a permissions hierarchy.
*
* @see HierarchyPermission
*/
public interface PermissionNode {
static final class OperatorDefault implements PermissionNode {
@Override
public boolean has(final Permissible permissible) {
return permissible.isOp();
}
}
/**
* This {@link HierarchyPermission} depends on the operator state. Ops have it, non-ops don't.
*/
PermissionNode OP_DEFAULT = new OperatorDefault();
/**
* Checks whether a given {@link Permissible} has this node.
*
* @param permissible The {@link Permissible} that might have the permission.
* @return Whether it has the permission.
*/
boolean has(Permissible permissible);
}
@@ -0,0 +1,21 @@
package com.onarandombox.MultiverseCore.permissions;
/**
* Permission nodes.
*/
public class Permissions {
protected Permissions() {
throw new UnsupportedOperationException();
}
/**
* The {@code multiverse.*} permission.
*/
public static final HierarchyPermission MV_ROOT = new HierarchyPermission(PermissionNode.OP_DEFAULT,
"multiverse.*", "Provides access to all Multiverse features.");
/**
* The {@code multiverse.access.*} family of permissions.
*/
public static final PermissionCollection ACCESS = new PermissionCollection(MV_ROOT, "multiverse.access.", "World access");
}
@@ -0,0 +1,4 @@
/**
* Contains permissions utility classes.
*/
package com.onarandombox.MultiverseCore.permissions;
@@ -140,7 +140,7 @@ public class AnchorManager {
if (ancLoc == null) {
continue;
}
if (Permissions.ACCESS.hasPermission(p, ancLoc.getWorld().getName())) {
if (p.hasPermission("multiverse.access." + ancLoc.getWorld().getName())) {
myAnchors.add(anchor);
}
}
@@ -7,13 +7,10 @@
package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.util.Logging;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Logger;
/**
@@ -31,16 +28,11 @@ public class FileUtils {
* @return true if the folder was successfully deleted.
*/
public static boolean deleteFolder(File file) {
if (file.exists()) {
boolean ret = true;
// If the file exists, and it has more than one file in it.
if (file.isDirectory()) {
for (File f : file.listFiles()) {
ret = ret && deleteFolder(f);
}
}
return ret && file.delete();
} else {
try {
org.apache.commons.io.FileUtils.deleteDirectory(file);
return true;
} catch (IOException e) {
Logging.warning(e.getMessage());
return false;
}
}
@@ -52,16 +44,11 @@ public class FileUtils {
* @return true if the contents were successfully deleted
*/
public static boolean deleteFolderContents(File file) {
if (file.exists()) {
boolean ret = true;
// If the file exists, and it has more than one file in it.
if (file.isDirectory()) {
for (File f : file.listFiles()) {
ret = ret && deleteFolder(f);
}
}
return ret;
} else {
try {
org.apache.commons.io.FileUtils.cleanDirectory(file);
return true;
} catch (IOException e) {
Logging.warning(e.getMessage());
return false;
}
}
@@ -77,46 +64,12 @@ public class FileUtils {
* @return if it had success
*/
public static boolean copyFolder(File source, File target, Logger log) {
InputStream in = null;
OutputStream out = null;
try {
if (source.isDirectory()) {
if (!target.exists())
target.mkdir();
String[] children = source.list();
// for (int i=0; i<children.length; i++) {
for (String child : children) {
copyFolder(new File(source, child), new File(target, child), log);
}
} else {
in = new FileInputStream(source);
out = new FileOutputStream(target);
byte[] buf = new byte[COPY_BLOCK_SIZE];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
org.apache.commons.io.FileUtils.copyDirectory(source, target);
return true;
} catch (FileNotFoundException e) {
log.warning("Exception while copying file: " + e.getMessage());
} catch (IOException e) {
log.warning("Exception while copying file: " + e.getMessage());
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignore) { }
}
if (out != null) {
try {
out.close();
} catch (IOException ignore) { }
}
log.warning(e.getMessage());
return false;
}
return false;
}
}
@@ -11,6 +11,7 @@ import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.permissions.Permissions;
import com.pneumaticraft.commandhandler.PermissionsInterface;
import org.bukkit.ChatColor;
import org.bukkit.Location;
@@ -36,6 +37,17 @@ public class MVPermissions implements PermissionsInterface {
}
/**
* Check if a Player can ignore GameMode restrictions for world they travel to.
*
* @param p The {@link Player} to check.
* @param w The {@link MultiverseWorld} the player wants to teleport to.
* @return True if they should bypass restrictions.
*/
public boolean canIgnoreGameModeRestriction(Player p, MultiverseWorld w) {
return p.hasPermission("mv.bypass.gamemode." + w.getName());
}
/**
* Check if a Player can teleport to the Destination world from there current world.
*
@@ -92,18 +104,15 @@ public class MVPermissions implements PermissionsInterface {
this.plugin.log(Level.FINEST, "EnforceAccess is OFF. Player was allowed in " + w.getAlias());
return true;
}
return Permissions.ACCESS.hasPermission(p, w.getName());
return Permissions.ACCESS.has(p, w.getName());
}
private boolean canEnterLocation(Player p, Location l) {
if (l == null) {
if (l == null)
return false;
}
String worldName = l.getWorld().getName();
if (!this.plugin.getMVWorldManager().isMVWorld(worldName)) {
return false;
}
return Permissions.ACCESS.hasPermission(p, worldName);
return this.plugin.getMVWorldManager().isMVWorld(worldName) && Permissions.ACCESS.has(p, worldName);
}
/**
@@ -130,7 +139,7 @@ public class MVPermissions implements PermissionsInterface {
if (!canEnterLocation(p, d.getLocation(p))) {
return false;
}
return d.hasRequiredPermission(p);
return this.hasPermission(p, d.getRequiredPermission(), false);
}
/**
@@ -166,14 +175,14 @@ public class MVPermissions implements PermissionsInterface {
ChatColor.DARK_AQUA, ChatColor.WHITE));
cango = false;
}
if (!Permissions.ACCESS.hasPermission(p, worldName)) {
if (!this.hasPermission(p, "multiverse.access." + worldName, false)) {
asker.sendMessage(String.format("The player (%s%s%s) does not have the required world entry permission (%s%s%s) to go to the destination (%s%s%s).",
ChatColor.AQUA, p.getDisplayName(), ChatColor.WHITE,
ChatColor.GREEN, Permissions.ACCESS.getName(worldName), ChatColor.WHITE,
ChatColor.GREEN, "multiverse.access." + worldName, ChatColor.WHITE,
ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE));
cango = false;
}
if (d.hasRequiredPermission(p)) {
if (!this.hasPermission(p, d.getRequiredPermission(), false)) {
asker.sendMessage(String.format("The player (%s%s%s) does not have the required entry permission (%s%s%s) to go to the destination (%s%s%s).",
ChatColor.AQUA, p.getDisplayName(), ChatColor.WHITE,
ChatColor.GREEN, d.getRequiredPermission(), ChatColor.WHITE,
@@ -7,7 +7,7 @@
package com.onarandombox.MultiverseCore.utils;
import com.fernferret.allpay.GenericBank;
import com.fernferret.allpay.commons.GenericBank;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import org.bukkit.command.CommandSender;
@@ -140,7 +140,7 @@ public class PermissionTools {
return true;
}
// If the player does not have to pay, return now.
if (Permissions.COST_EXEMPT.hasPermission(teleporter, toWorld.getName())) {
if (this.plugin.getMVPerms().hasPermission(teleporter, toWorld.getExemptPermission().getName(), true)) {
return true;
}
final boolean usingVault;
@@ -275,7 +275,8 @@ public class PermissionTools {
return true;
}
if (Permissions.BYPASS_PLAYERLIMIT.hasPermission(teleportee, toWorld.getName())) {
MVPermissions perms = plugin.getMVPerms();
if (perms.hasPermission(teleportee, "mv.bypass.playerlimit." + toWorld.getName(), false)) {
return true;
} else {
teleporter.sendMessage("The world " + toWorld.getColoredWorldString() + " is full");
@@ -292,24 +293,7 @@ public class PermissionTools {
*/
public boolean playerCanIgnoreGameModeRestriction(MultiverseWorld toWorld, Player teleportee) {
if (toWorld != null) {
return Permissions.BYPASS_GAMEMODE.hasPermission(teleportee, toWorld.getName());
} else {
// TODO: Determine if this value is false because a world didn't exist
// or if it was because a world wasn't imported.
return true;
}
}
/**
* Checks to see if a player should bypass allow flight restrictions.
*
* @param toWorld world travelling to.
* @param teleportee player travelling.
* @return True if they should bypass restrictions
*/
public boolean playerCanIgnoreAllowFlightRestriction(MultiverseWorld toWorld, Player teleportee) {
if (toWorld != null) {
return Permissions.BYPASS_ALLOWFLY.hasPermission(teleportee, toWorld.getName());
return this.plugin.getMVPerms().canIgnoreGameModeRestriction(teleportee, toWorld);
} else {
// TODO: Determine if this value is false because a world didn't exist
// or if it was because a world wasn't imported.
@@ -1,182 +0,0 @@
package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.pluginbase.permission.BukkitPerm;
import com.dumptruckman.minecraft.pluginbase.permission.BukkitPermFactory;
import com.dumptruckman.minecraft.pluginbase.permission.PermDefault;
import com.onarandombox.MultiverseCore.api.Core;
public class Permissions {
// ============ Multiverse Bypass Permissions ============
private static final BukkitPerm MV = BukkitPermFactory.newBukkitPerm(Core.class, "mv.*")
.def(PermDefault.FALSE).build();
private static final BukkitPerm BYPASS_ALL = BukkitPermFactory.newBukkitPerm(Core.class, "mv.bypass.*")
.def(PermDefault.FALSE).parent(MV).build();
private static final BukkitPerm BYPASS_GAMEMODE_ALL = BukkitPermFactory.newBukkitPerm(Core.class,
"mv.bypass.gamemode.*").desc("Allows a player to ignore gamemode changes for all worlds.")
.def(PermDefault.FALSE).parent(BYPASS_ALL).build();
private static final BukkitPerm BYPASS_PLAYERLIMIT_ALL = BukkitPermFactory.newBukkitPerm(Core.class,
"mv.bypass.playerlimit.*").desc("Allows a player to ignore the player limit for all worlds.")
.def(PermDefault.FALSE).parent(BYPASS_ALL).build();
private static final BukkitPerm BYPASS_ALLOWFLY_ALL = BukkitPermFactory.newBukkitPerm(Core.class,
"mv.bypass.allowfly.*").desc("Allows a player to ignore the flight restrictions for all worlds.")
.def(PermDefault.FALSE).parent(BYPASS_ALL).build();
/** Used for bypassing the gamemode of specific worlds. */
public static final BukkitPerm BYPASS_GAMEMODE = BukkitPermFactory.newBukkitPerm(Core.class,
"mv.bypass.gamemode").desc("Allows a player to ignore gamemode changes for a specific world.")
.specificOnly().def(PermDefault.FALSE).parent(BYPASS_GAMEMODE_ALL).build();
/** Used for bypassing the player limit of specific worlds. */
public static final BukkitPerm BYPASS_PLAYERLIMIT = BukkitPermFactory.newBukkitPerm(Core.class,
"mv.bypass.playerlimit").desc("Allows a player to ignore the player limit for a specific world.")
.specificOnly().def(PermDefault.FALSE).parent(BYPASS_PLAYERLIMIT_ALL).build();
/** Used for bypassing the allow fly setting of specific worlds. */
public static final BukkitPerm BYPASS_ALLOWFLY = BukkitPermFactory.newBukkitPerm(Core.class,
"mv.bypass.allowfly").desc("Allows a player to ignore the flight restrictions for a specific world.")
.specificOnly().def(PermDefault.FALSE).parent(BYPASS_ALLOWFLY_ALL).build();
// ============ Multiverse World Permissions ============
private static final BukkitPerm ACCESS_ALL = BukkitPermFactory.newBukkitPerm(Core.class, "access.*")
.desc("Allows a player to access all worlds.")
.usePluginName().addToAll().build();
private static final BukkitPerm COST_EXEMPT_ALL = BukkitPermFactory.newBukkitPerm(Core.class, "exempt.*")
.desc("Allows a player to bypass the costs for worlds and MV portals.")
.usePluginName().addToAll().build();
public static final BukkitPerm ACCESS = BukkitPermFactory.newBukkitPerm(Core.class, "access")
.desc("Allows a player to access a specific world.")
.usePluginName().specificOnly().parent(ACCESS_ALL).build();
public static final BukkitPerm COST_EXEMPT = BukkitPermFactory.newBukkitPerm(Core.class, "exempt")
.desc("Allows a player to bypass the costs for a specific world and MV portals in that world.")
.usePluginName().specificOnly().parent(COST_EXEMPT_ALL).build();
// ============ Multiverse Teleport Permissions ============
private static final BukkitPerm TELEPORT_ALL = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.*")
.desc("Allows the player to use all forms of teleportation.")
.usePluginName().addToAll().build();
private static final BukkitPerm TELEPORT_SELF_ALL = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.*")
.desc("Allows the player to use all forms of self teleportation.")
.usePluginName().parent(TELEPORT_ALL).build();
private static final BukkitPerm TELEPORT_OTHER_ALL = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.*")
.desc("Allows the player to use all forms of teleportation on other players.")
.usePluginName().parent(TELEPORT_ALL).build();
private static final BukkitPerm TELEPORT_SELF_WORLD = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.w")
.desc("Allows the player to teleport self to any world.")
.usePluginName().parent(TELEPORT_SELF_ALL).build();
public static final BukkitPerm TP_SELF_WORLD = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.w")
.desc("Allows the player to teleport self to a specific world.")
.usePluginName().specificOnly().parent(TELEPORT_SELF_WORLD).build();
private static final BukkitPerm TELEPORT_SELF_ANCHOR = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.a")
.desc("Allows the player to teleport self to any anchor.")
.usePluginName().parent(TELEPORT_SELF_ALL).build();
public static final BukkitPerm TP_SELF_ANCHOR = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.a")
.desc("Allows the player to teleport self to a specific anchor.")
.usePluginName().specificOnly().parent(TELEPORT_SELF_ANCHOR).build();
public static final BukkitPerm TP_SELF_EXACT = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.e")
.desc("Allows the player to teleport self to an exact location.")
.usePluginName().parent(TELEPORT_SELF_ALL).build();
private static final BukkitPerm TELEPORT_SELF_PLAYER = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.pl")
.desc("Allows the player to teleport self to any player.")
.usePluginName().parent(TELEPORT_SELF_ALL).build();
public static final BukkitPerm TP_SELF_PLAYER = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.pl")
.desc("Allows the player to teleport self to a specific player.")
.usePluginName().specificOnly().parent(TELEPORT_SELF_PLAYER).build();
public static final BukkitPerm TP_SELF_CANNON = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.ca")
.desc("Allows the player to teleport self to cannon.")
.usePluginName().parent(TELEPORT_SELF_ALL).build();
public static final BukkitPerm TP_SELF_BED = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.b")
.desc("Allows the player to teleport self to their bed.")
.usePluginName().parent(TELEPORT_SELF_ALL).build();
private static final BukkitPerm TELEPORT_SELF_PORTAL = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.p")
.desc("Allows the player to teleport self to any MV portal.")
.usePluginName().parent(TELEPORT_SELF_ALL).build();
public static final BukkitPerm TP_SELF_PORTAL = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.p")
.desc("Allows the player to teleport self to a specific MV portal.")
.usePluginName().specificOnly().parent(TELEPORT_SELF_PORTAL).build();
private static final BukkitPerm TELEPORT_SELF_OPENWARP = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.ow")
.desc("Allows the player to teleport self to any OpenWarp destination.")
.usePluginName().parent(TELEPORT_SELF_ALL).build();
public static final BukkitPerm TP_SELF_OPENWARP = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.self.ow")
.desc("Allows the player to teleport self to a specific OpenWarp destination.")
.usePluginName().specificOnly().parent(TELEPORT_SELF_OPENWARP).build();
private static final BukkitPerm TELEPORT_OTHER_WORLD = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.w")
.desc("Allows the player to teleport other to any world.")
.usePluginName().parent(TELEPORT_OTHER_ALL).build();
public static final BukkitPerm TP_OTHER_WORLD = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.w")
.desc("Allows the player to teleport other to a specific world.")
.usePluginName().specificOnly().parent(TELEPORT_OTHER_WORLD).build();
private static final BukkitPerm TELEPORT_OTHER_ANCHOR = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.a")
.desc("Allows the player to teleport other to any anchor.")
.usePluginName().parent(TELEPORT_OTHER_ALL).build();
public static final BukkitPerm TP_OTHER_ANCHOR = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.a")
.desc("Allows the player to teleport other to a specific anchor.")
.usePluginName().specificOnly().parent(TELEPORT_OTHER_ANCHOR).build();
public static final BukkitPerm TP_OTHER_EXACT = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.e")
.desc("Allows the player to teleport other to an exact location.")
.usePluginName().parent(TELEPORT_OTHER_ALL).build();
private static final BukkitPerm TELEPORT_OTHER_PLAYER = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.pl")
.desc("Allows the player to teleport other to any player.")
.usePluginName().parent(TELEPORT_OTHER_ALL).build();
public static final BukkitPerm TP_OTHER_PLAYER = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.pl")
.desc("Allows the player to teleport other to a specific player.")
.usePluginName().specificOnly().parent(TELEPORT_OTHER_PLAYER).build();
public static final BukkitPerm TP_OTHER_CANNON = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.ca")
.desc("Allows the player to teleport other to cannon.")
.usePluginName().parent(TELEPORT_OTHER_ALL).build();
public static final BukkitPerm TP_OTHER_BED = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.b")
.desc("Allows the player to teleport other to their bed.")
.usePluginName().parent(TELEPORT_OTHER_ALL).build();
private static final BukkitPerm TELEPORT_OTHER_PORTAL = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.p")
.desc("Allows the player to teleport other to any MV portal.")
.usePluginName().parent(TELEPORT_OTHER_ALL).build();
public static final BukkitPerm TP_OTHER_PORTAL = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.p")
.desc("Allows the player to teleport other to a specific MV portal.")
.usePluginName().specificOnly().parent(TELEPORT_OTHER_PORTAL).build();
private static final BukkitPerm TELEPORT_OTHER_OPENWARP = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.ow")
.desc("Allows the player to teleport other to any OpenWarp destination.")
.usePluginName().parent(TELEPORT_OTHER_ALL).build();
public static final BukkitPerm TP_OTHER_OPENWARP = BukkitPermFactory.newBukkitPerm(Core.class, "teleport.other.ow")
.desc("Allows the player to teleport other to a specific OpenWarp destination.")
.usePluginName().specificOnly().parent(TELEPORT_OTHER_OPENWARP).build();
}
@@ -35,8 +35,16 @@ public class SimpleWorldPurger implements WorldPurger {
private MultiverseCore plugin;
private Class<Entity> ambientClass = null;
public SimpleWorldPurger(MultiverseCore plugin) {
this.plugin = plugin;
try {
Class entityClass = Class.forName("org.bukkit.entity.Ambient");
if (Entity.class.isAssignableFrom(entityClass)) {
ambientClass = entityClass;
}
} catch (ClassNotFoundException ignore) { }
}
/**
@@ -130,7 +138,8 @@ public class SimpleWorldPurger implements WorldPurger {
boolean negateMonsters, boolean specifiedAnimals, boolean specifiedMonsters) {
boolean negate = false;
boolean specified = false;
if (e instanceof Golem || e instanceof Squid || e instanceof Animals) {
if (e instanceof Golem || e instanceof Squid || e instanceof Animals
|| (ambientClass != null && ambientClass.isInstance(e))) {
// it's an animal
if (specifiedAnimals && !negateAnimals) {
Logging.finest("Removing an entity because I was told to remove all animals in world %s: %s", e.getWorld().getName(), e);
@@ -0,0 +1,44 @@
package com.onarandombox.MultiverseCore.utils;
import com.dumptruckman.minecraft.util.Logging;
import com.onarandombox.MultiverseCore.api.Core;
import java.util.concurrent.Callable;
/**
* Wraps calls that could result in exceptions that are not Multiverse's fault.
*/
public class UnsafeCallWrapper {
private final Core core;
public UnsafeCallWrapper(Core core) {
this.core = core;
}
/**
* Wraps calls that could result in exceptions that are not Multiverse's fault.
*
* @param callable The potentially unsafe call.
* @param plugin The plugin that's probably the culprit.
* @param action What MV was attempting to do (error message, format string).
* @param formatArgs The formatting arguments for the error message.
* The exception that was thrown will be appended to these objects.
* @param <T> The type of the return value.
* @return The return value or null if the call failed.
*/
public <T> T wrap(Callable<T> callable, String plugin, String action, Object... formatArgs) {
try {
// We're ready to catch you! JUMP!
return callable.call();
} catch (Throwable t) {
Object[] actualFormatArgs = new Object[formatArgs.length + 1];
System.arraycopy(formatArgs, 0, actualFormatArgs, 0, formatArgs.length);
actualFormatArgs[formatArgs.length] = t;
Logging.warning(action, actualFormatArgs);
Logging.warning("This is a bug in %s, NOT a bug in Multiverse!", plugin);
if (core.getMVConfig().getGlobalDebug() >= 1)
t.printStackTrace();
return null;
}
}
}
@@ -27,6 +27,8 @@ import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.Plugin;
import java.io.File;
@@ -40,6 +42,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -239,16 +242,21 @@ public class WorldManager implements MVWorldManager {
* {@inheritDoc}
*/
@Override
public ChunkGenerator getChunkGenerator(String generator, String generatorID, String worldName) {
public ChunkGenerator getChunkGenerator(String generator, final String generatorID, final String worldName) {
if (generator == null) {
return null;
}
Plugin myPlugin = this.plugin.getServer().getPluginManager().getPlugin(generator);
final Plugin myPlugin = this.plugin.getServer().getPluginManager().getPlugin(generator);
if (myPlugin == null) {
return null;
} else {
return myPlugin.getDefaultWorldGenerator(worldName, generatorID);
return plugin.getUnsafeCallWrapper().wrap(new Callable<ChunkGenerator>() {
@Override
public ChunkGenerator call() throws Exception {
return myPlugin.getDefaultWorldGenerator(worldName, generatorID);
}
}, myPlugin.getName(), "Failed to get the default chunk generator: %s");
}
}
@@ -361,17 +369,25 @@ public class WorldManager implements MVWorldManager {
if (!worldsFromTheConfig.containsKey(name))
throw new IllegalArgumentException("That world doesn't exist!");
WorldProperties world = worldsFromTheConfig.get(name);
WorldCreator creator = WorldCreator.name(name);
final WorldProperties world = worldsFromTheConfig.get(name);
final WorldCreator creator = WorldCreator.name(name);
creator.environment(world.getEnvironment()).seed(world.getSeed());
if (type != null) {
creator.type(type);
}
if ((world.getGenerator() != null) && (!world.getGenerator().equals("null")))
creator.generator(world.getGenerator());
return doLoad(creator, ignoreExists);
boolean generatorSuccess = true;
if ((world.getGenerator() != null) && (!world.getGenerator().equals("null")))
generatorSuccess = null != plugin.getUnsafeCallWrapper().wrap(new Callable<Object>() {
@Override
public Object call() throws Exception {
creator.generator(world.getGenerator());
return new Object();
}
}, "the generator plugin", "Failed to set the generator for world '%s' to '%s': %s", name, world.getGenerator());
return generatorSuccess && doLoad(creator, ignoreExists);
}
private boolean doLoad(WorldCreator creator, boolean ignoreExists) {
@@ -612,9 +628,29 @@ public class WorldManager implements MVWorldManager {
// Basic Counter to count how many Worlds we are loading.
int count = 0;
this.ensureConfigIsPrepared();
this.ensureSecondNamespaceIsPrepared();
// Force the worlds to be loaded, ie don't just load new worlds.
if (forceLoad) {
// Remove all world permissions.
Permission allAccess = this.plugin.getServer().getPluginManager().getPermission("multiverse.access.*");
Permission allExempt = this.plugin.getServer().getPluginManager().getPermission("multiverse.exempt.*");
for (MultiverseWorld w : this.worlds.values()) {
// Remove this world from the master list
if (allAccess != null) {
allAccess.getChildren().remove(w.getAccessPermission().getName());
}
if (allExempt != null) {
allExempt.getChildren().remove(w.getAccessPermission().getName());
}
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.bypass.gamemode." + w.getName());
}
// Recalc the all permission
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(allAccess);
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(allExempt);
this.worlds.clear();
}
@@ -634,6 +670,14 @@ public class WorldManager implements MVWorldManager {
this.saveWorldsConfig();
}
private void ensureSecondNamespaceIsPrepared() {
Permission special = this.plugin.getServer().getPluginManager().getPermission("mv.bypass.gamemode.*");
if (special == null) {
special = new Permission("mv.bypass.gamemode.*", PermissionDefault.FALSE);
this.plugin.getServer().getPluginManager().addPermission(special);
}
}
/**
* {@inheritDoc}
* @deprecated This is deprecated!
@@ -76,6 +76,7 @@ public class TestInstanceCreator {
when(pdf.getAuthors()).thenReturn(new ArrayList<String>());
doReturn(pdf).when(core).getDescription();
doReturn(true).when(core).isEnabled();
doReturn(Util.logger).when(core).getLogger();
core.setServerFolder(serverDirectory);
// Add Core to the list of loaded plugins