mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2024-11-24 03:25:12 +01:00
feat!: Revamp permission handling and its relevant checks
This commit is contained in:
parent
e58de8d74d
commit
05c5cd8d66
@ -62,7 +62,8 @@ import com.onarandombox.MultiverseCore.listeners.MVWorldListener;
|
||||
import com.onarandombox.MultiverseCore.teleportation.SimpleBlockSafety;
|
||||
import com.onarandombox.MultiverseCore.teleportation.SimpleLocationManipulation;
|
||||
import com.onarandombox.MultiverseCore.teleportation.SimpleSafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.utils.MVPermissions;
|
||||
import com.onarandombox.MultiverseCore.utils.PermissionsTool;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerActionChecker;
|
||||
import com.onarandombox.MultiverseCore.utils.TestingMode;
|
||||
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper;
|
||||
import com.onarandombox.MultiverseCore.utils.metrics.MetricsConfigurator;
|
||||
@ -90,7 +91,8 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
private DestinationsProvider destinationsProvider;
|
||||
private MVEconomist economist;
|
||||
private LocationManipulation locationManipulation = new SimpleLocationManipulation();
|
||||
private final MVPermissions mvPermissions = new MVPermissions(this);
|
||||
private final PermissionsTool permissionsTool = new PermissionsTool(this);
|
||||
private PlayerActionChecker playerActionChecker;
|
||||
private SafeTTeleporter safeTTeleporter = new SimpleSafeTTeleporter(this);
|
||||
private final UnsafeCallWrapper unsafeCallWrapper = new UnsafeCallWrapper(this);
|
||||
private final MVWorldManager worldManager = new SimpleMVWorldManager(this);
|
||||
@ -102,7 +104,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
// Listeners
|
||||
private MVChatListener chatListener;
|
||||
private final MVEntityListener entityListener = new MVEntityListener(this);
|
||||
private final MVPlayerListener playerListener = new MVPlayerListener(this);
|
||||
private MVPlayerListener playerListener;
|
||||
private final MVPortalListener portalListener = new MVPortalListener(this);
|
||||
private final MVWeatherListener weatherListener = new MVWeatherListener(this);
|
||||
private final MVWorldListener worldListener = new MVWorldListener(this);
|
||||
@ -137,6 +139,9 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
*/
|
||||
@Override
|
||||
public void onEnable() {
|
||||
this.permissionsTool.setUpPermissions();
|
||||
this.playerActionChecker = new PlayerActionChecker(this);
|
||||
|
||||
// Load our configs first as we need them for everything else.
|
||||
this.loadConfigs();
|
||||
if (this.multiverseConfig == null) {
|
||||
@ -186,6 +191,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
*/
|
||||
private void registerEvents() {
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
this.playerListener = new MVPlayerListener(this);
|
||||
this.chatListener = new MVChatListener(this, this.playerListener);
|
||||
pluginManager.registerEvents(this.chatListener, this);
|
||||
pluginManager.registerEvents(this.entityListener, this);
|
||||
@ -274,12 +280,14 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
|
||||
return economist;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public MVPermissions getMVPerms() {
|
||||
return this.mvPermissions;
|
||||
public PermissionsTool getPermissionsTool() {
|
||||
return permissionsTool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerActionChecker getPlayerActionChecker() {
|
||||
return playerActionChecker;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,8 @@ import com.onarandombox.MultiverseCore.economy.MVEconomist;
|
||||
import com.onarandombox.MultiverseCore.teleportation.SimpleBlockSafety;
|
||||
import com.onarandombox.MultiverseCore.teleportation.SimpleLocationManipulation;
|
||||
import com.onarandombox.MultiverseCore.teleportation.SimpleSafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.utils.MVPermissions;
|
||||
import com.onarandombox.MultiverseCore.utils.PermissionsTool;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerActionChecker;
|
||||
import com.onarandombox.MultiverseCore.utils.UnsafeCallWrapper;
|
||||
|
||||
/**
|
||||
@ -44,14 +45,6 @@ public interface MVCore extends MVPlugin {
|
||||
*/
|
||||
UnsafeCallWrapper getUnsafeCallWrapper();
|
||||
|
||||
/**
|
||||
* Multiverse uses an advanced permissions setup, this object
|
||||
* simplifies getting/setting permissions.
|
||||
*
|
||||
* @return A non-null {@link MVPermissions}.
|
||||
*/
|
||||
MVPermissions getMVPerms();
|
||||
|
||||
/**
|
||||
* Multiverse uses {@link MVCommandManager} to make adding and using commands
|
||||
* a piece of cake.
|
||||
@ -113,6 +106,10 @@ public interface MVCore extends MVPlugin {
|
||||
*/
|
||||
int getPluginCount();
|
||||
|
||||
PermissionsTool getPermissionsTool();
|
||||
|
||||
PlayerActionChecker getPlayerActionChecker();
|
||||
|
||||
/**
|
||||
* Gets the {@link BlockSafety} this {@link MVCore} is using.
|
||||
* @return The {@link BlockSafety} this {@link MVCore} is using.
|
||||
|
@ -1,142 +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.api;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* A destination API for Multiverse
|
||||
* Any plugin can add these to MV and when they are, any action that uses them (portals, MVTP, etc.) can use them!
|
||||
*/
|
||||
@Deprecated
|
||||
public interface MVDestination {
|
||||
/**
|
||||
* Returns the identifier or prefix that is required for this destination.
|
||||
* <p>
|
||||
* Portals have a prefix of "p" for example and OpenWarp (third party plugin) uses "ow". This is derived from a
|
||||
* hash and cannot have duplicate values. Read that as your plugin cannot use 'p' because it's already used.
|
||||
* Please check the wiki when adding a custom destination!
|
||||
*
|
||||
* @return The identifier or prefix that is required for this destination.
|
||||
*/
|
||||
String getIdentifier();
|
||||
|
||||
/**
|
||||
* Allows you to determine if a Destination is valid for the type it thinks it is.
|
||||
* <p>
|
||||
* An example of this would be the exact destination. A valid string would be: e:0,0,0 where an invalid one would
|
||||
* be e:1:2:3. The first string would return true the second would return false. This is simply a convenience
|
||||
* method
|
||||
* and does not even NEED to be called, but it's highly recommended if you're teleporting, but it's mainly for
|
||||
* Multiverse Internal use.
|
||||
*
|
||||
* @param plugin The plugin who the type belongs to.
|
||||
* @param destination The destination string. ex: p:MyPortal:nw
|
||||
*
|
||||
* @return True if the destination is valid, false if not.
|
||||
*/
|
||||
boolean isThisType(JavaPlugin plugin, String destination);
|
||||
|
||||
/**
|
||||
* Returns the location a specific entity will spawn at when being teleported to this Destination.
|
||||
* <p>
|
||||
* To just retrieve the location as it is stored you can just pass null, but be warned some destinations may return
|
||||
* null back to you if you do this. It is always safer to pass an actual entity. This is used so things like
|
||||
* minecarts can be teleported.
|
||||
* <p>
|
||||
* Do not forget to use {@link #getVelocity()} as destinations can use this too!
|
||||
*
|
||||
* @param entity The entity to be teleported.
|
||||
*
|
||||
* @return The location of the entity.
|
||||
*/
|
||||
Location getLocation(Entity entity);
|
||||
|
||||
/**
|
||||
* Returns the velocity vector for this destination.
|
||||
* <p>
|
||||
* Plugins wishing to fully support MVDestinations MUST implement this.
|
||||
*
|
||||
* @return A vector representing the speed/direction the player should travel when arriving
|
||||
*/
|
||||
Vector getVelocity();
|
||||
|
||||
/**
|
||||
* Sets the destination string.
|
||||
* <p>
|
||||
* This should be used when you want to tell this destination object about a change in where it should take people.
|
||||
* The destination param should be match the result from {@link #getIdentifier()}. A valid example would be that if
|
||||
* {@link #getIdentifier()} returned "ow" our destination string could be "ow:TownCenter" but could not be
|
||||
* "p:HomePortal"
|
||||
*
|
||||
* @param plugin The plugin who the type belongs to.
|
||||
* @param destination The destination string. ex: p:MyPortal:nw
|
||||
*/
|
||||
void setDestination(JavaPlugin plugin, String destination);
|
||||
|
||||
/**
|
||||
* Returns true if the destination is valid and players will be taken to it.
|
||||
* <p>
|
||||
* Even if destinations are in the correct format (p:MyPortal) MyPortal may not exist, and therefore this would
|
||||
* return false.
|
||||
*
|
||||
* @return True if the destination is valid; false if not.
|
||||
*/
|
||||
boolean isValid();
|
||||
|
||||
/**
|
||||
* Gives you a general friendly description of the type of destination.
|
||||
* <p>
|
||||
* For example, the PlayerDestination sets this to "Player". You can use this to show where a player will be taken.
|
||||
*
|
||||
* @return A friendly string description of the type of destination.
|
||||
*/
|
||||
String getType();
|
||||
|
||||
/**
|
||||
* Gives you a specific name of the destination.
|
||||
* <p>
|
||||
* For example, the PlayerDestination sets this to The Player's Name.
|
||||
*
|
||||
* @return A friendly string stating the name of the destination.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns a string that can easily be saved in the config that contains all the details needed to rebuild this
|
||||
* destination.
|
||||
* <p>
|
||||
* ex: e:0,0,0:50:50
|
||||
*
|
||||
* @return The savable config string.
|
||||
*/
|
||||
String toString();
|
||||
|
||||
/**
|
||||
* Returns the permissions string required to go here.
|
||||
* <p>
|
||||
* ex: multiverse.access.world
|
||||
* <p>
|
||||
* NOTE: This is NOT the permission to use the teleport command.
|
||||
*
|
||||
* @return the permissions string required to go here.
|
||||
*/
|
||||
String getRequiredPermission();
|
||||
|
||||
/**
|
||||
* Should the Multiverse SafeTeleporter be used?
|
||||
* <p>
|
||||
* If not, MV will blindly take people to the location specified.
|
||||
*
|
||||
* @return True if the SafeTeleporter will be used, false if not.
|
||||
*/
|
||||
boolean useSafeTeleporter();
|
||||
}
|
@ -20,7 +20,6 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@ -200,34 +199,6 @@ public interface MVWorld {
|
||||
boolean clearList(String property);
|
||||
// end of old config stuff
|
||||
|
||||
// permission stuff
|
||||
/**
|
||||
* Gets the lowercased name of the world. This method is required, since the permissables
|
||||
* lowercase all permissions when recalculating.
|
||||
* <p>
|
||||
* Note: This also means if a user has worlds named: world and WORLD, that they can both
|
||||
* exist, and both be teleported to independently, but their permissions **cannot** be
|
||||
* uniqueified at this time. See bug report #.
|
||||
*
|
||||
* @return The lowercased name of the world.
|
||||
*/
|
||||
String getPermissibleName();
|
||||
|
||||
/**
|
||||
* Gets the permission required to enter this world.
|
||||
*
|
||||
* @return The permission required to be exempt from charges to/from this world.
|
||||
*/
|
||||
Permission getAccessPermission();
|
||||
|
||||
/**
|
||||
* Gets the permission required to be exempt when entering.
|
||||
*
|
||||
* @return The permission required to be exempt when entering.
|
||||
*/
|
||||
Permission getExemptPermission();
|
||||
// end of permission stuff
|
||||
|
||||
/**
|
||||
* Gets the alias of this world.
|
||||
* <p>
|
||||
|
@ -35,6 +35,11 @@ public class CheckCommand extends MultiverseCoreCommand {
|
||||
) {
|
||||
issuer.sendMessage("Checking " + player + " to " + destination + "...");
|
||||
//TODO More detailed output on permissions required.
|
||||
this.plugin.getDestinationsProvider().checkTeleportPermissions(issuer, player, destination);
|
||||
if (!this.plugin.getPlayerActionChecker().canUseDestinationToTeleport(issuer.getIssuer(), player, destination).isSuccessful()) {
|
||||
issuer.sendMessage("You don't have permission to use this destination.");
|
||||
}
|
||||
if (!this.plugin.getPlayerActionChecker().canGoToDestination(issuer.getIssuer(), player, destination).isSuccessful()) {
|
||||
issuer.sendMessage("You don't have permission to teleport to this destination.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ public class TeleportCommand extends MultiverseCoreCommand {
|
||||
) {
|
||||
// TODO Add warning if teleporting too many players at once.
|
||||
for (Player player : players) {
|
||||
if (!this.plugin.getPlayerActionChecker().canUseDestinationToTeleport(issuer.getIssuer(), player, destination).isSuccessful()) {
|
||||
issuer.sendMessage("You don't have permission to use this destination.");
|
||||
continue;
|
||||
}
|
||||
issuer.sendMessage("Teleporting "
|
||||
+ (issuer.getPlayer() == player ? "you" : player.getName())
|
||||
+ " to " + destination + "...");
|
||||
@ -44,6 +48,6 @@ public class TeleportCommand extends MultiverseCoreCommand {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(CommandIssuer issuer) {
|
||||
return this.plugin.getDestinationsProvider().hasAnyTeleportPermission(issuer);
|
||||
return this.plugin.getPermissionsTool().hasAnyDestinationTeleportPermissions(issuer.getIssuer());
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,12 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import co.aikar.commands.BukkitCommandIssuer;
|
||||
import co.aikar.commands.CommandIssuer;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.Destination;
|
||||
import com.onarandombox.MultiverseCore.api.DestinationInstance;
|
||||
import com.onarandombox.MultiverseCore.api.Teleporter;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -23,7 +20,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public class DestinationsProvider {
|
||||
private static final String SEPARATOR = ":";
|
||||
private static final String PERMISSION_PREFIX = "multiverse.teleport.";
|
||||
|
||||
private final MultiverseCore plugin;
|
||||
private final Map<String, Destination<?>> destinationMap;
|
||||
@ -45,13 +41,7 @@ public class DestinationsProvider {
|
||||
*/
|
||||
public void registerDestination(@NotNull Destination<?> destination) {
|
||||
this.destinationMap.put(destination.getIdentifier(), destination);
|
||||
this.registerDestinationPerms(destination);
|
||||
}
|
||||
|
||||
private void registerDestinationPerms(@NotNull Destination<?> destination) {
|
||||
PluginManager pluginManager = this.plugin.getServer().getPluginManager();
|
||||
pluginManager.addPermission(new Permission(PERMISSION_PREFIX + "self." + destination.getIdentifier()));
|
||||
pluginManager.addPermission(new Permission(PERMISSION_PREFIX + "other." + destination.getIdentifier()));
|
||||
this.plugin.getPermissionsTool().registerDestinationTeleportPermissions(destination);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,8 +55,8 @@ public class DestinationsProvider {
|
||||
@Nullable String deststring
|
||||
) {
|
||||
return destinationMap.values().stream()
|
||||
.filter(destination -> issuer.hasPermission(PERMISSION_PREFIX + "self." + destination.getIdentifier())
|
||||
|| issuer.hasPermission(PERMISSION_PREFIX + "other." + destination.getIdentifier()))
|
||||
.filter(destination -> this.plugin.getPermissionsTool().hasDestinationTeleportPermission(null, issuer.getIssuer(), destination)
|
||||
|| this.plugin.getPermissionsTool().hasDestinationTeleportPermission(issuer.getIssuer(), this.plugin.getServer().getConsoleSender(), destination))
|
||||
.map(destination -> destination.suggestDestinations(issuer, deststring).stream()
|
||||
.map(s -> destination.getIdentifier() + SEPARATOR + s)
|
||||
.collect(Collectors.toList()))
|
||||
@ -118,6 +108,10 @@ public class DestinationsProvider {
|
||||
return this.destinationMap.get(identifier);
|
||||
}
|
||||
|
||||
public @NotNull Collection<Destination<?>> getRegisteredDestinations() {
|
||||
return this.destinationMap.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleports the teleportee to the destination.
|
||||
*
|
||||
@ -129,9 +123,6 @@ public class DestinationsProvider {
|
||||
@NotNull Player teleportee,
|
||||
@NotNull ParsedDestination<?> destination
|
||||
) {
|
||||
if (!checkTeleportPermissions(teleporter, teleportee, destination)) {
|
||||
return;
|
||||
}
|
||||
teleport(teleporter, teleportee, destination);
|
||||
}
|
||||
|
||||
@ -152,57 +143,4 @@ public class DestinationsProvider {
|
||||
}
|
||||
teleportHandler.teleport(teleporter, teleportee, destination);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the teleporter has permission to teleport the teleportee to the destination.
|
||||
*
|
||||
* @param teleporter The teleporter.
|
||||
* @param teleportee The teleportee.
|
||||
* @param destination The destination.
|
||||
* @return True if the teleporter has permission, false otherwise.
|
||||
*/
|
||||
public boolean checkTeleportPermissions(CommandIssuer teleporter, Entity teleportee, ParsedDestination<?> destination) {
|
||||
//TODO Move permission checking to a separate class
|
||||
String permission = PERMISSION_PREFIX
|
||||
+ (teleportee.equals(teleporter.getIssuer()) ? "self" : "other") + "."
|
||||
+ destination.getDestination().getIdentifier();
|
||||
if (!teleporter.hasPermission(permission)) {
|
||||
teleporter.sendMessage("You don't have permission to teleport to this destination.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//TODO Config whether to use finer permission
|
||||
String finerPermissionSuffix = destination.getDestinationInstance().getFinerPermissionSuffix();
|
||||
if (finerPermissionSuffix == null || finerPermissionSuffix.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String finerPermission = permission + "." + finerPermissionSuffix;
|
||||
if (!teleporter.hasPermission(finerPermission)) {
|
||||
teleporter.sendMessage("You don't have permission to teleport to this destination.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the issuer has permission to teleport to at least one destination.
|
||||
*
|
||||
* @param issuer The issuer.
|
||||
* @return True if the issuer has permission, false otherwise.
|
||||
*/
|
||||
public boolean hasAnyTeleportPermission(CommandIssuer issuer) {
|
||||
for (Destination<?> destination : this.destinationMap.values()) {
|
||||
String permission = PERMISSION_PREFIX + "self." + destination.getIdentifier();
|
||||
if (issuer.hasPermission(permission)) {
|
||||
return true;
|
||||
}
|
||||
permission = PERMISSION_PREFIX + "other." + destination.getIdentifier();
|
||||
if (issuer.hasPermission(permission)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.onarandombox.MultiverseCore.economy;
|
||||
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -30,6 +31,10 @@ public class MVEconomist {
|
||||
return getVaultHandler().hasEconomy();
|
||||
}
|
||||
|
||||
public String formatPrice(MVWorld world) {
|
||||
return formatPrice(world.getPrice(), world.getCurrency());
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the amount to a human readable currency string.
|
||||
*
|
||||
@ -76,6 +81,29 @@ public class MVEconomist {
|
||||
}
|
||||
}
|
||||
|
||||
public void payEntryFee(Player player, MVWorld world) {
|
||||
payEntryFee(player, world.getPrice(), world.getCurrency());
|
||||
}
|
||||
|
||||
/**
|
||||
* Pays for a given amount of currency either from the player's economy account or inventory if the currency
|
||||
*
|
||||
* @param player the player to take currency from.
|
||||
* @param price the amount to take.
|
||||
* @param currency the type of currency.
|
||||
*/
|
||||
public void payEntryFee(Player player, double price, Material currency) {
|
||||
if (price == 0D) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (price < 0) {
|
||||
this.deposit(player, -price, currency);
|
||||
} else {
|
||||
this.withdraw(player, price, currency);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a message for a player indicating they don't have enough currency.
|
||||
*
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
package com.onarandombox.MultiverseCore.event;
|
||||
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
|
||||
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -20,13 +20,13 @@ import org.bukkit.event.HandlerList;
|
||||
* Event that gets called when a player use the /mvtp command.
|
||||
*/
|
||||
public class MVTeleportEvent extends Event implements Cancellable {
|
||||
private Player teleportee;
|
||||
private CommandSender teleporter;
|
||||
private MVDestination dest;
|
||||
private boolean useSafeTeleport;
|
||||
private final Player teleportee;
|
||||
private final CommandSender teleporter;
|
||||
private final ParsedDestination<?> dest;
|
||||
private final boolean useSafeTeleport;
|
||||
private boolean isCancelled;
|
||||
|
||||
public MVTeleportEvent(MVDestination dest, Player teleportee, CommandSender teleporter, boolean safeTeleport) {
|
||||
public MVTeleportEvent(ParsedDestination<?> dest, Player teleportee, CommandSender teleporter, boolean safeTeleport) {
|
||||
this.teleportee = teleportee;
|
||||
this.teleporter = teleporter;
|
||||
this.dest = dest;
|
||||
@ -83,7 +83,7 @@ public class MVTeleportEvent extends Event implements Cancellable {
|
||||
*
|
||||
* @return The destination the player will spawn at.
|
||||
*/
|
||||
public MVDestination getDestination() {
|
||||
public ParsedDestination<?> getDestination() {
|
||||
return this.dest;
|
||||
}
|
||||
|
||||
|
@ -8,14 +8,19 @@
|
||||
package com.onarandombox.MultiverseCore.listeners;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import co.aikar.commands.BukkitCommandIssuer;
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.event.MVRespawnEvent;
|
||||
import com.onarandombox.MultiverseCore.utils.PermissionTools;
|
||||
import com.onarandombox.MultiverseCore.utils.action.ActionResponse;
|
||||
import com.onarandombox.MultiverseCore.utils.ActionCheckResult;
|
||||
import com.onarandombox.MultiverseCore.utils.PlayerActionChecker;
|
||||
import com.onarandombox.MultiverseCore.utils.action.ActionResult;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -30,6 +35,8 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerPortalEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Multiverse's {@link Listener} for players.
|
||||
@ -37,19 +44,20 @@ import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
public class MVPlayerListener implements Listener {
|
||||
private final MultiverseCore plugin;
|
||||
private final MVWorldManager worldManager;
|
||||
private final PermissionTools pt;
|
||||
private final PlayerActionChecker actionChecker;
|
||||
|
||||
private final Map<String, String> playerWorld = new ConcurrentHashMap<String, String>();
|
||||
private final Map<String, String> playerWorld = new ConcurrentHashMap<>();
|
||||
|
||||
public MVPlayerListener(MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
worldManager = plugin.getMVWorldManager();
|
||||
pt = new PermissionTools(plugin);
|
||||
actionChecker = plugin.getPlayerActionChecker();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the playerWorld-map
|
||||
*/
|
||||
@Deprecated
|
||||
public Map<String, String> getPlayerWorld() {
|
||||
return playerWorld;
|
||||
}
|
||||
@ -105,26 +113,32 @@ public class MVPlayerListener implements Listener {
|
||||
*/
|
||||
@EventHandler
|
||||
public void playerJoin(PlayerJoinEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
if (!p.hasPlayedBefore()) {
|
||||
Player player = event.getPlayer();
|
||||
if (!player.hasPlayedBefore()) {
|
||||
Logging.finer("Player joined for the FIRST time!");
|
||||
if (plugin.getMVConfig().getFirstSpawnOverride()) {
|
||||
Logging.fine("Moving NEW player to(firstspawnoverride): "
|
||||
+ worldManager.getFirstSpawnWorld().getSpawnLocation());
|
||||
this.sendPlayerToDefaultWorld(p);
|
||||
if (!plugin.getMVConfig().getFirstSpawnOverride()) {
|
||||
return;
|
||||
}
|
||||
Logging.fine("Moving NEW player to(firstspawnoverride): " + worldManager.getFirstSpawnWorld().getSpawnLocation());
|
||||
this.sendPlayerToDefaultWorld(player);
|
||||
return;
|
||||
} else {
|
||||
Logging.finer("Player joined AGAIN!");
|
||||
if (this.plugin.getMVConfig().getEnforceAccess() // check this only if we're enforcing access!
|
||||
&& !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);
|
||||
}
|
||||
}
|
||||
|
||||
Logging.finer("Player joined AGAIN!");
|
||||
MVWorld world = worldManager.getMVWorld(player.getWorld());
|
||||
if (world == null) {
|
||||
Logging.fine("Player is in a world that is not managed by Multiverse. Ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.plugin.getPlayerActionChecker().hasAccessToWorld(player, world).isSuccessful()) {
|
||||
player.sendMessage("[MV] - Sorry you can't be in this world anymore!");
|
||||
this.sendPlayerToDefaultWorld(player);
|
||||
}
|
||||
|
||||
// Handle the Players GameMode setting for the new world.
|
||||
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
|
||||
playerWorld.put(p.getName(), p.getWorld().getName());
|
||||
this.handleGameModeAndFlight(event.getPlayer(), world);
|
||||
playerWorld.put(player.getName(), player.getWorld().getName()); //TODO REMOVE
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,9 +147,14 @@ public class MVPlayerListener implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void playerChangedWorld(PlayerChangedWorldEvent event) {
|
||||
// Permissions now determine whether or not to handle a gamemode.
|
||||
this.handleGameModeAndFlight(event.getPlayer(), event.getPlayer().getWorld());
|
||||
playerWorld.put(event.getPlayer().getName(), event.getPlayer().getWorld().getName());
|
||||
MVWorld world = worldManager.getMVWorld(event.getPlayer().getWorld());
|
||||
if (world == null) {
|
||||
Logging.fine("Player is in a world that is not managed by Multiverse. Ignoring.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.handleGameModeAndFlight(event.getPlayer(), world);
|
||||
playerWorld.put(event.getPlayer().getName(), event.getPlayer().getWorld().getName()); //TODO REMOVE
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,87 +163,54 @@ public class MVPlayerListener implements Listener {
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void playerTeleport(PlayerTeleportEvent event) {
|
||||
Logging.finer("Got teleport event for player '"
|
||||
+ event.getPlayer().getName() + "' with cause '" + event.getCause() + "'");
|
||||
if (event.isCancelled()) {
|
||||
if (event.isCancelled() || event.getTo() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Logging.fine("Got teleport event for player '"
|
||||
+ event.getPlayer().getName() + "' with cause '" + event.getCause() + "'");
|
||||
|
||||
Player teleportee = event.getPlayer();
|
||||
CommandSender teleporter = null;
|
||||
|
||||
//TODO - Redo teleporter queue handling
|
||||
String teleporterName = MultiverseCore.getPlayerTeleporter(teleportee.getName());
|
||||
if (teleporterName != null) {
|
||||
if (teleporterName.equals("CONSOLE")) {
|
||||
Logging.finer("We know the teleporter is the console! Magical!");
|
||||
teleporter = this.plugin.getServer().getConsoleSender();
|
||||
} else {
|
||||
teleporter = this.plugin.getServer().getPlayerExact(teleporterName);
|
||||
}
|
||||
}
|
||||
Logging.finer("Inferred sender '" + teleporter + "' from name '"
|
||||
+ teleporterName + "', fetched from name '" + teleportee.getName() + "'");
|
||||
MVWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld().getName());
|
||||
MVWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName());
|
||||
if (toWorld == null) {
|
||||
Logging.fine("Player '" + teleportee.getName() + "' is teleporting to world '"
|
||||
+ event.getTo().getWorld().getName() + "' which is not managed by Multiverse-Core. No further "
|
||||
+ "actions will be taken by Multiverse-Core.");
|
||||
return;
|
||||
}
|
||||
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
|
||||
// The player is Teleporting to the same world.
|
||||
Logging.finer("Player '" + teleportee.getName() + "' is teleporting to the same world.");
|
||||
this.stateSuccess(teleportee.getName(), toWorld.getAlias());
|
||||
return;
|
||||
}
|
||||
// TODO: Refactor these lines.
|
||||
// Charge the teleporter
|
||||
event.setCancelled(!pt.playerHasMoneyToEnter(fromWorld, toWorld, teleporter, teleportee, true));
|
||||
if (event.isCancelled() && teleporter != null) {
|
||||
Logging.fine("Player '" + teleportee.getName()
|
||||
+ "' was DENIED ACCESS to '" + toWorld.getAlias()
|
||||
+ "' because '" + teleporter.getName()
|
||||
+ "' don't have the FUNDS required to enter it.");
|
||||
if (teleporterName == null && !this.plugin.getMVConfig().getTeleportIntercept()) {
|
||||
Logging.finer("Teleporting without intercepting.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if player is allowed to enter the world if we're enforcing permissions
|
||||
if (plugin.getMVConfig().getEnforceAccess()) {
|
||||
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, teleporter, teleportee));
|
||||
if (event.isCancelled() && teleporter != null) {
|
||||
Logging.fine("Player '" + teleportee.getName()
|
||||
+ "' was DENIED ACCESS to '" + toWorld.getAlias()
|
||||
+ "' because '" + teleporter.getName()
|
||||
+ "' don't have: multiverse.access." + event.getTo().getWorld().getName());
|
||||
return;
|
||||
}
|
||||
if (Objects.equals(teleporterName, "CONSOLE")) {
|
||||
Logging.finer("We know the teleporter is the console! Magical!");
|
||||
teleporter = this.plugin.getServer().getConsoleSender();
|
||||
} else {
|
||||
Logging.fine("Player '" + teleportee.getName()
|
||||
+ "' was allowed to go to '" + toWorld.getAlias() + "' because enforceaccess is off.");
|
||||
teleporter = this.plugin.getServer().getPlayerExact(teleporterName);
|
||||
}
|
||||
Logging.fine("Inferred sender '" + teleporter + "' from name '"
|
||||
+ teleporterName + "', fetched from name '" + teleportee.getName() + "'");
|
||||
|
||||
if (teleporter == null) {
|
||||
Logging.finer("We don't know who the teleporter is, so we'll assume it's the player.");
|
||||
teleporter = teleportee;
|
||||
}
|
||||
|
||||
// Does a limit actually exist?
|
||||
if (toWorld.getPlayerLimit() > -1) {
|
||||
// Are there equal or more people on the world than the limit?
|
||||
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 '" + 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;
|
||||
}
|
||||
}
|
||||
MVWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld());
|
||||
MVWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld());
|
||||
ActionResponse actionCheckResponse = this.actionChecker.canGoFromToWorld(teleporter, teleportee, fromWorld, toWorld);
|
||||
Logging.fine(actionCheckResponse.toString());
|
||||
if (!actionCheckResponse.isSuccessful()) {
|
||||
tellReason(teleporter, teleportee, fromWorld, toWorld, actionCheckResponse);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// By this point anything cancelling the event has returned on the method, meaning the teleport is a success \o/
|
||||
this.stateSuccess(teleportee.getName(), toWorld.getAlias());
|
||||
}
|
||||
if (actionCheckResponse.hasResult(ActionCheckResult.ENOUGH_MONEY)) {
|
||||
double price = toWorld.getPrice();
|
||||
Material currency = toWorld.getCurrency();
|
||||
this.plugin.getEconomist().payEntryFee((Player) teleporter, price, currency);
|
||||
}
|
||||
|
||||
private void stateSuccess(String playerName, String worldName) {
|
||||
Logging.fine("MV-Core is allowing Player '" + playerName
|
||||
+ "' to go to '" + worldName + "'.");
|
||||
Logging.fine("MV-Core is allowing Player '" + teleportee.getName() + "' to go to '" + toWorld.getName() + "'.");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,71 +239,37 @@ public class MVPlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when a player actually portals via a vanilla style portal.
|
||||
* @param event The Event that was fired.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
public void playerPortal(PlayerPortalEvent event) {
|
||||
if (event.isCancelled() || (event.getFrom() == null)) {
|
||||
if (event.isCancelled() || event.getFrom() == null || event.getTo() == null) {
|
||||
return;
|
||||
}
|
||||
// The adjust should have happened much earlier.
|
||||
if (event.getTo() == null) {
|
||||
|
||||
MVWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld());
|
||||
MVWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld());
|
||||
ActionResponse actionCheckResponse = this.actionChecker.canGoFromToWorld(event.getPlayer(), fromWorld, toWorld);
|
||||
Logging.fine(actionCheckResponse.toString());
|
||||
if (!actionCheckResponse.isSuccessful()) {
|
||||
tellReason(event.getPlayer(), event.getPlayer(), fromWorld, toWorld, actionCheckResponse);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
MVWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld().getName());
|
||||
MVWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName());
|
||||
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
|
||||
// The player is Portaling to the same world.
|
||||
Logging.finer("Player '" + event.getPlayer().getName() + "' is portaling to the same world.");
|
||||
return;
|
||||
}
|
||||
event.setCancelled(!pt.playerHasMoneyToEnter(fromWorld, toWorld, event.getPlayer(), event.getPlayer(), true));
|
||||
if (event.isCancelled()) {
|
||||
Logging.fine("Player '" + event.getPlayer().getName()
|
||||
+ "' was DENIED ACCESS to '" + event.getTo().getWorld().getName()
|
||||
+ "' because they don't have the FUNDS required to enter.");
|
||||
return;
|
||||
}
|
||||
if (plugin.getMVConfig().getEnforceAccess()) {
|
||||
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, event.getPlayer(), event.getPlayer()));
|
||||
if (event.isCancelled()) {
|
||||
Logging.fine("Player '" + event.getPlayer().getName()
|
||||
+ "' was DENIED ACCESS to '" + event.getTo().getWorld().getName()
|
||||
+ "' because they don't have: multiverse.access." + event.getTo().getWorld().getName());
|
||||
}
|
||||
} else {
|
||||
Logging.fine("Player '" + event.getPlayer().getName()
|
||||
+ "' was allowed to go to '" + event.getTo().getWorld().getName()
|
||||
+ "' because enforceaccess is off.");
|
||||
}
|
||||
|
||||
if (!this.plugin.getMVConfig().isUsingDefaultPortalSearch()) {
|
||||
event.setSearchRadius(this.plugin.getMVConfig().getPortalSearchRadius());
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPlayerToDefaultWorld(final Player player) {
|
||||
private void sendPlayerToDefaultWorld(@NotNull Player player) {
|
||||
// Remove the player 1 tick after the login. I'm sure there's GOT to be a better way to do this...
|
||||
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin,
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.teleport(plugin.getMVWorldManager().getFirstSpawnWorld().getSpawnLocation());
|
||||
}
|
||||
}, 1L);
|
||||
}
|
||||
|
||||
// FOLLOWING 2 Methods and Private class handle Per Player GameModes.
|
||||
private void handleGameModeAndFlight(Player player, World world) {
|
||||
|
||||
MVWorld mvWorld = this.worldManager.getMVWorld(world.getName());
|
||||
if (mvWorld != null) {
|
||||
this.handleGameModeAndFlight(player, mvWorld);
|
||||
} else {
|
||||
Logging.finer("Not handling gamemode and flight for world '" + world.getName()
|
||||
+ "' not managed by Multiverse.");
|
||||
}
|
||||
() -> player.teleport(plugin.getMVWorldManager().getFirstSpawnWorld().getSpawnLocation()),
|
||||
1L);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -325,40 +277,87 @@ public class MVPlayerListener implements Listener {
|
||||
* @param player The {@link Player}.
|
||||
* @param world The world the player is in.
|
||||
*/
|
||||
public void handleGameModeAndFlight(final Player player, final MVWorld world) {
|
||||
public void handleGameModeAndFlight(@NotNull Player player, @NotNull MVWorld 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.
|
||||
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin,
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
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("Player: " + player.getName() + " is IMMUNE to gamemode changes!");
|
||||
}
|
||||
}
|
||||
}, 1L);
|
||||
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(
|
||||
this.plugin,
|
||||
()-> applyGameModeAndFlight(player, world),
|
||||
1L);
|
||||
}
|
||||
|
||||
private void applyGameModeAndFlight(@NotNull Player player, @NotNull MVWorld world) {
|
||||
if (MVPlayerListener.this.actionChecker.canKeepGameMode(player, world).isSuccessful()) {
|
||||
Logging.fine("Player: " + player.getName() + " is IMMUNE to gamemode changes!");
|
||||
return;
|
||||
}
|
||||
|
||||
// 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("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());
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void tellReason(@NotNull CommandSender sender,
|
||||
@NotNull Player teleportee,
|
||||
@Nullable MVWorld fromWorld,
|
||||
@Nullable MVWorld toWorld,
|
||||
@NotNull ActionResult result
|
||||
) {
|
||||
BukkitCommandIssuer issuer = this.plugin.getMVCommandManager().getCommandIssuer(sender);
|
||||
String targetName = issuer.getIssuer() == teleportee ? "You" : teleportee.getName();
|
||||
|
||||
if (result.hasResult(ActionCheckResult.NULL_DESTINATION)) {
|
||||
issuer.sendMessage(targetName + " cannot be teleported to because the destination is null.");
|
||||
return;
|
||||
}
|
||||
if (result.hasResult(ActionCheckResult.NULL_LOCATION)) {
|
||||
issuer.sendMessage(targetName + " cannot be teleported to because the location is null.");
|
||||
return;
|
||||
}
|
||||
if (result.hasResult(ActionCheckResult.NULL_WORLD)) {
|
||||
issuer.sendMessage(targetName + " cannot be teleported because the world is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.hasResult(ActionCheckResult.NO_WORLD_ACCESS)) {
|
||||
issuer.sendMessage(targetName + " cannot be teleported to because you does not have access to " + toWorld.getName());
|
||||
}
|
||||
if (result.hasResult(ActionCheckResult.EXCEED_PLAYERLIMIT)) {
|
||||
issuer.sendMessage(targetName + " cannot cannot enter " + toWorld.getName() + " because it is full.");
|
||||
}
|
||||
if (result.hasResult(ActionCheckResult.NOT_ENOUGH_MONEY)) {
|
||||
issuer.sendMessage("You do not have enough money to pay for " + targetName + " to enter " + toWorld.getName());
|
||||
issuer.sendMessage("The entry fee required is " + this.plugin.getEconomist().formatPrice(toWorld));
|
||||
}
|
||||
if (result.hasResult(ActionCheckResult.CANNOT_PAY_ENTRY_FEE)) {
|
||||
issuer.sendMessage("You do not have the ability to pay the entry fee for " + targetName + " to enter " + toWorld.getName());
|
||||
}
|
||||
if (result.hasResult(ActionCheckResult.BLACKLISTED)) {
|
||||
if (toWorld.equals(fromWorld)) {
|
||||
issuer.sendMessage(targetName + " cannot teleport within " + toWorld.getName() + " because it is blacklisted.");
|
||||
} else {
|
||||
issuer.sendMessage(fromWorld.getName() + " is blacklisted from teleporting to " + toWorld.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,56 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.onarandombox.MultiverseCore.utils.action.ActionResult;
|
||||
|
||||
public enum ActionCheckResult implements ActionResult {
|
||||
NULL_WORLD(false),
|
||||
NULL_LOCATION(false),
|
||||
NULL_DESTINATION(false),
|
||||
|
||||
CAN_USE_DESTINATION(true),
|
||||
NO_DESTINATION_PERMISSION(false),
|
||||
|
||||
NOT_MV_WORLD(true),
|
||||
SAME_WORLD(true),
|
||||
|
||||
HAS_WORLD_ACCESS(true),
|
||||
NO_WORLD_ACCESS(false),
|
||||
NO_ENFORCE_WORLD_ACCESS(true),
|
||||
|
||||
ENOUGH_MONEY(true),
|
||||
NOT_ENOUGH_MONEY(false),
|
||||
EXEMPTED_FROM_ENTRY_FEE(true),
|
||||
CANNOT_PAY_ENTRY_FEE(false),
|
||||
FREE_ENTRY(true),
|
||||
|
||||
WITHIN_PLAYERLIMIT(true),
|
||||
EXCEED_PLAYERLIMIT(false),
|
||||
BYPASS_PLAYERLIMIT(true),
|
||||
|
||||
NOT_BLACKLISTED(true),
|
||||
BLACKLISTED(false),
|
||||
|
||||
KEEP_GAME_MODE(true),
|
||||
ENFORCE_GAME_MODE(false),
|
||||
;
|
||||
|
||||
private final boolean isSuccessful;
|
||||
|
||||
ActionCheckResult(boolean isSuccessful) {
|
||||
this.isSuccessful = isSuccessful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name();
|
||||
}
|
||||
|
||||
public boolean isSuccessful() {
|
||||
return isSuccessful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasResult(ActionResult result) {
|
||||
return result == this;
|
||||
}
|
||||
}
|
@ -1,405 +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.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVDestination;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
|
||||
/**
|
||||
* Multiverse's permission checker
|
||||
*/
|
||||
public class MVPermissions {
|
||||
|
||||
private MultiverseCore plugin;
|
||||
private MVWorldManager worldMgr;
|
||||
|
||||
public MVPermissions(MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
this.worldMgr = plugin.getMVWorldManager();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Player can ignore GameMode restrictions for world they travel to.
|
||||
*
|
||||
* @param p The {@link Player} to check.
|
||||
* @param w The {@link MVWorld} the player wants to teleport to.
|
||||
* @return True if they should bypass restrictions.
|
||||
*/
|
||||
public boolean canIgnoreGameModeRestriction(Player p, MVWorld w) {
|
||||
return p.hasPermission("mv.bypass.gamemode." + w.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Player can teleport to the Destination world from there current world.
|
||||
*
|
||||
* @param p The {@link Player} to check.
|
||||
* @param w The {@link MVWorld} the player wants to teleport to.
|
||||
* @return Whether the player can teleport to the given {@link MVWorld}.
|
||||
*/
|
||||
public boolean canTravelFromWorld(Player p, MVWorld w) {
|
||||
List<String> blackList = w.getWorldBlacklist();
|
||||
|
||||
boolean returnValue = true;
|
||||
|
||||
for (String s : blackList) {
|
||||
if (s.equalsIgnoreCase(p.getWorld().getName())) {
|
||||
returnValue = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the specified {@link CommandSender} can travel to the specified {@link Location}.
|
||||
* @param sender The {@link CommandSender}.
|
||||
* @param location The {@link Location}.
|
||||
* @return Whether the {@link CommandSender} can travel to the specified {@link Location}.
|
||||
*/
|
||||
public boolean canTravelFromLocation(CommandSender sender, Location location) {
|
||||
// Now The Bed destination can return null now.
|
||||
if (location == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
Player teleporter = (Player) sender;
|
||||
if (!this.worldMgr.isMVWorld(location.getWorld().getName())) {
|
||||
return false;
|
||||
}
|
||||
return canTravelFromWorld(teleporter, this.worldMgr.getMVWorld(location.getWorld().getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Player has the permissions to enter this world.
|
||||
*
|
||||
* @param p The {@link Player} player that wants to enter
|
||||
* @param w The {@link MVWorld} he wants to enter
|
||||
* @return Whether he has the permission to enter the world
|
||||
*/
|
||||
public boolean canEnterWorld(Player p, MVWorld w) {
|
||||
// If we're not enforcing access, anyone can enter.
|
||||
if (!plugin.getMVConfig().getEnforceAccess()) {
|
||||
Logging.finest("EnforceAccess is OFF. Player was allowed in " + w.getAlias());
|
||||
return true;
|
||||
}
|
||||
return this.hasPermission(p, "multiverse.access." + w.getName(), false);
|
||||
}
|
||||
|
||||
private boolean canEnterLocation(Player p, Location l) {
|
||||
if (l == null) {
|
||||
return false;
|
||||
}
|
||||
String worldName = l.getWorld().getName();
|
||||
if (!this.plugin.getMVWorldManager().isMVWorld(worldName)) {
|
||||
return false;
|
||||
}
|
||||
return this.hasPermission(p, "multiverse.access." + worldName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a sender can enter a destination.
|
||||
* The reason this is not a player, is it can be used to simply check permissions
|
||||
* The console should, for exmaple, always see all worlds
|
||||
*
|
||||
* @param sender The CommandSender to check.
|
||||
* @param d The destination they are requesting.
|
||||
* @return True if that sender can go to that destination
|
||||
*/
|
||||
public boolean canEnterDestination(CommandSender sender, MVDestination d) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
Player p = (Player) sender;
|
||||
if (d == null || d.getLocation(p) == null) {
|
||||
return false;
|
||||
}
|
||||
String worldName = d.getLocation(p).getWorld().getName();
|
||||
if (!this.worldMgr.isMVWorld(worldName)) {
|
||||
return false;
|
||||
}
|
||||
if (!canEnterLocation(p, d.getLocation(p))) {
|
||||
return false;
|
||||
}
|
||||
return this.hasPermission(p, d.getRequiredPermission(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells a {@link CommandSender} why another {@link CommandSender} can or can not access a certain {@link MVDestination}.
|
||||
* @param asker The {@link CommandSender} that's asking.
|
||||
* @param playerInQuestion The {@link CommandSender} whose permissions we want to know.
|
||||
* @param d The {@link MVDestination}.
|
||||
*/
|
||||
public void tellMeWhyICantDoThis(CommandSender asker, CommandSender playerInQuestion, MVDestination d) {
|
||||
boolean cango = true;
|
||||
if (!(playerInQuestion instanceof Player)) {
|
||||
asker.sendMessage(String.format("The console can do %severything%s.", ChatColor.RED, ChatColor.WHITE));
|
||||
return;
|
||||
}
|
||||
Player p = (Player) playerInQuestion;
|
||||
if (d == null) {
|
||||
asker.sendMessage(String.format("The provided Destination is %sNULL%s, and therefore %sINVALID%s.",
|
||||
ChatColor.RED, ChatColor.WHITE, ChatColor.RED, ChatColor.WHITE));
|
||||
cango = false;
|
||||
}
|
||||
// We know it'll be a player here due to the first line of this method.
|
||||
if (d.getLocation(p) == null) {
|
||||
asker.sendMessage(String.format(
|
||||
"The player will spawn at an %sindeterminate location%s. Talk to the MV Devs if you see this",
|
||||
ChatColor.RED, ChatColor.WHITE));
|
||||
cango = false;
|
||||
}
|
||||
String worldName = d.getLocation(p).getWorld().getName();
|
||||
if (!this.worldMgr.isMVWorld(worldName)) {
|
||||
asker.sendMessage(String.format("The destination resides in a world(%s%s%s) that is not managed by Multiverse.",
|
||||
ChatColor.AQUA, worldName, ChatColor.WHITE));
|
||||
asker.sendMessage(String.format("Type %s/mv import ?%s to see the import command's help page.",
|
||||
ChatColor.DARK_AQUA, ChatColor.WHITE));
|
||||
cango = false;
|
||||
}
|
||||
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, "multiverse.access." + worldName, ChatColor.WHITE,
|
||||
ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE));
|
||||
cango = false;
|
||||
}
|
||||
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,
|
||||
ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE));
|
||||
cango = false;
|
||||
}
|
||||
if (cango) {
|
||||
asker.sendMessage(String.format("The player (%s%s%s) CAN go to the destination (%s%s%s).",
|
||||
ChatColor.AQUA, p.getDisplayName(), ChatColor.WHITE,
|
||||
ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE));
|
||||
} else {
|
||||
asker.sendMessage(String.format("The player (%s%s%s) cannot access the destination %s%s%s. Therefore they can't use mvtp at all for this.",
|
||||
ChatColor.AQUA, p.getDisplayName(), ChatColor.WHITE,
|
||||
ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE));
|
||||
return;
|
||||
}
|
||||
if (!this.hasPermission(p, "multiverse.teleport.self." + d.getIdentifier(), false)) {
|
||||
asker.sendMessage(String.format("The player (%s%s%s) does not have the required teleport permission (%s%s%s) to use %s/mvtp %s%s.",
|
||||
ChatColor.AQUA, p.getDisplayName(), ChatColor.WHITE,
|
||||
ChatColor.GREEN, "multiverse.teleport.self." + d.getIdentifier(), ChatColor.WHITE,
|
||||
ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE));
|
||||
} else {
|
||||
asker.sendMessage(String.format("The player (%s%s%s) has the required teleport permission (%s%s%s) to use %s/mvtp %s%s.",
|
||||
ChatColor.AQUA, p.getDisplayName(), ChatColor.WHITE,
|
||||
ChatColor.GREEN, "multiverse.teleport.self." + d.getIdentifier(), ChatColor.WHITE,
|
||||
ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE));
|
||||
}
|
||||
if (!this.hasPermission(p, "multiverse.teleport.other." + d.getIdentifier(), false)) {
|
||||
asker.sendMessage(String.format("The player (%s%s%s) does not have the required teleport permission (%s%s%s) to send others to %s%s%s via mvtp.",
|
||||
ChatColor.AQUA, p.getDisplayName(), ChatColor.WHITE,
|
||||
ChatColor.GREEN, "multiverse.teleport.other." + d.getIdentifier(), ChatColor.WHITE,
|
||||
ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE));
|
||||
} else {
|
||||
asker.sendMessage(String.format("The player (%s%s%s) has required teleport permission (%s%s%s) to send others to %s%s%s via mvtp.",
|
||||
ChatColor.AQUA, p.getDisplayName(), ChatColor.WHITE,
|
||||
ChatColor.GREEN, "multiverse.teleport.other." + d.getIdentifier(), ChatColor.WHITE,
|
||||
ChatColor.DARK_AQUA, d.getName(), ChatColor.WHITE));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a player has a permission.
|
||||
*
|
||||
* @param sender Who is requesting the permission.
|
||||
* @param node The permission node in string format; multiverse.core.list.worlds for example.
|
||||
* @param isOpRequired deprecated This is not used for anything anymore.
|
||||
* @return True if they have that permission or any parent.
|
||||
*/
|
||||
public boolean hasPermission(CommandSender sender, String node, boolean isOpRequired) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
// NO one can access a null permission (mainly used for destinations):w
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
// Everyone can access an empty permission
|
||||
// Currently used for the PlayerDestination
|
||||
if (node.equals("")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return checkActualPermission(sender, node);
|
||||
}
|
||||
|
||||
// TODO: Better player checks, most likely not needed, but safer.
|
||||
private boolean checkActualPermission(CommandSender sender, String node) {
|
||||
Player player = (Player) sender;
|
||||
|
||||
boolean hasPermission = sender.hasPermission(node);
|
||||
if (!sender.isPermissionSet(node)) {
|
||||
Logging.finer(String.format("The node [%s%s%s] was %sNOT%s set for [%s%s%s].",
|
||||
ChatColor.RED, node, ChatColor.WHITE, ChatColor.RED, ChatColor.WHITE, ChatColor.AQUA,
|
||||
player.getDisplayName(), ChatColor.WHITE));
|
||||
}
|
||||
if (hasPermission) {
|
||||
Logging.finer("Checking to see if player [" + player.getName() + "] has permission [" + node + "]... YES");
|
||||
} else {
|
||||
Logging.finer("Checking to see if player [" + player.getName() + "] has permission [" + node + "]... NO");
|
||||
}
|
||||
return hasPermission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if the sender has any parent perms.
|
||||
* Stops when it finds one or when there are no more parents.
|
||||
* This method is recursive.
|
||||
*
|
||||
* @param sender Who is asking for the permission.
|
||||
* @param node The permission node to check (possibly already a parent).
|
||||
* @return True if they have any parent perm, false if none.
|
||||
*/
|
||||
// TODO remove this...?
|
||||
private boolean hasAnyParentPermission(CommandSender sender, String node) {
|
||||
String parentPerm = this.pullOneLevelOff(node);
|
||||
// Base case
|
||||
if (parentPerm == null) {
|
||||
return false;
|
||||
}
|
||||
// If they have a parent, they're good
|
||||
if (this.checkActualPermission(sender, parentPerm + ".*")) {
|
||||
return true;
|
||||
}
|
||||
return hasAnyParentPermission(sender, parentPerm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pulls one level off of a yaml style node.
|
||||
* Given multiverse.core.list.worlds will return multiverse.core.list
|
||||
*
|
||||
* @param node The root node to check.
|
||||
* @return The parent of the node
|
||||
*/
|
||||
private static String pullOneLevelOff(String node) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
int index = node.lastIndexOf(".");
|
||||
if (index > 0) {
|
||||
return node.substring(0, index);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean hasAnyPermission(CommandSender sender, List<String> nodes, boolean isOpRequired) {
|
||||
for (String node : nodes) {
|
||||
if (this.hasPermission(sender, node, isOpRequired)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public boolean hasAllPermission(CommandSender sender, List<String> nodes, boolean isOpRequired) {
|
||||
for (String node : nodes) {
|
||||
if (!this.hasPermission(sender, node, isOpRequired)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a permission.
|
||||
* @param string The permission as {@link String}.
|
||||
* @param defaultValue The default-value.
|
||||
* @return The permission as {@link Permission}.
|
||||
*/
|
||||
public Permission addPermission(String string, PermissionDefault defaultValue) {
|
||||
if (this.plugin.getServer().getPluginManager().getPermission(string) == null) {
|
||||
Permission permission = new Permission(string, defaultValue);
|
||||
this.plugin.getServer().getPluginManager().addPermission(permission);
|
||||
this.addToParentPerms(string);
|
||||
}
|
||||
return this.plugin.getServer().getPluginManager().getPermission(string);
|
||||
}
|
||||
|
||||
private void addToParentPerms(String permString) {
|
||||
String permStringChopped = permString.replace(".*", "");
|
||||
|
||||
String[] seperated = permStringChopped.split("\\.");
|
||||
String parentPermString = getParentPerm(seperated);
|
||||
if (parentPermString == null) {
|
||||
addToRootPermission("*", permStringChopped);
|
||||
addToRootPermission("*.*", permStringChopped);
|
||||
return;
|
||||
}
|
||||
Permission parentPermission = this.plugin.getServer().getPluginManager().getPermission(parentPermString);
|
||||
// Creat parent and grandparents
|
||||
if (parentPermission == null) {
|
||||
parentPermission = new Permission(parentPermString);
|
||||
this.plugin.getServer().getPluginManager().addPermission(parentPermission);
|
||||
|
||||
this.addToParentPerms(parentPermString);
|
||||
}
|
||||
// Create actual perm.
|
||||
Permission actualPermission = this.plugin.getServer().getPluginManager().getPermission(permString);
|
||||
// Extra check just to make sure the actual one is added
|
||||
if (actualPermission == null) {
|
||||
|
||||
actualPermission = new Permission(permString);
|
||||
this.plugin.getServer().getPluginManager().addPermission(actualPermission);
|
||||
}
|
||||
if (!parentPermission.getChildren().containsKey(permString)) {
|
||||
parentPermission.getChildren().put(actualPermission.getName(), true);
|
||||
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(parentPermission);
|
||||
}
|
||||
}
|
||||
|
||||
private void addToRootPermission(String rootPerm, String permStringChopped) {
|
||||
Permission rootPermission = this.plugin.getServer().getPluginManager().getPermission(rootPerm);
|
||||
if (rootPermission == null) {
|
||||
rootPermission = new Permission(rootPerm);
|
||||
this.plugin.getServer().getPluginManager().addPermission(rootPermission);
|
||||
}
|
||||
rootPermission.getChildren().put(permStringChopped + ".*", true);
|
||||
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(rootPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the given permission was 'multiverse.core.tp.self', this would return 'multiverse.core.tp.*'.
|
||||
*/
|
||||
private static String getParentPerm(String[] seperated) {
|
||||
if (seperated.length == 1) {
|
||||
return null;
|
||||
}
|
||||
String returnString = "";
|
||||
for (int i = 0; i < seperated.length - 1; i++) {
|
||||
returnString += seperated[i] + ".";
|
||||
}
|
||||
return returnString + "*";
|
||||
}
|
||||
}
|
@ -1,302 +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.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.economy.MVEconomist;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.Permission;
|
||||
|
||||
/**
|
||||
* Utility-class for permissions.
|
||||
*/
|
||||
public class PermissionTools {
|
||||
private MultiverseCore plugin;
|
||||
|
||||
public PermissionTools(MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a permission to the parent-permissions.
|
||||
* @param permString The new permission as {@link String}.
|
||||
*/
|
||||
public void addToParentPerms(String permString) {
|
||||
String permStringChopped = permString.replace(".*", "");
|
||||
|
||||
String[] seperated = permStringChopped.split("\\.");
|
||||
String parentPermString = getParentPerm(seperated);
|
||||
if (parentPermString == null) {
|
||||
addToRootPermission("*", permStringChopped);
|
||||
addToRootPermission("*.*", permStringChopped);
|
||||
return;
|
||||
}
|
||||
Permission parentPermission = this.plugin.getServer().getPluginManager().getPermission(parentPermString);
|
||||
// Creat parent and grandparents
|
||||
if (parentPermission == null) {
|
||||
parentPermission = new Permission(parentPermString);
|
||||
this.plugin.getServer().getPluginManager().addPermission(parentPermission);
|
||||
|
||||
this.addToParentPerms(parentPermString);
|
||||
}
|
||||
// Create actual perm.
|
||||
Permission actualPermission = this.plugin.getServer().getPluginManager().getPermission(permString);
|
||||
// Extra check just to make sure the actual one is added
|
||||
if (actualPermission == null) {
|
||||
|
||||
actualPermission = new Permission(permString);
|
||||
this.plugin.getServer().getPluginManager().addPermission(actualPermission);
|
||||
}
|
||||
if (!parentPermission.getChildren().containsKey(permString)) {
|
||||
parentPermission.getChildren().put(actualPermission.getName(), true);
|
||||
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(parentPermission);
|
||||
}
|
||||
}
|
||||
|
||||
private void addToRootPermission(String rootPerm, String permStringChopped) {
|
||||
Permission rootPermission = this.plugin.getServer().getPluginManager().getPermission(rootPerm);
|
||||
if (rootPermission == null) {
|
||||
rootPermission = new Permission(rootPerm);
|
||||
this.plugin.getServer().getPluginManager().addPermission(rootPermission);
|
||||
}
|
||||
rootPermission.getChildren().put(permStringChopped + ".*", true);
|
||||
this.plugin.getServer().getPluginManager().recalculatePermissionDefaults(rootPermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the given permission was 'multiverse.core.tp.self', this would return 'multiverse.core.tp.*'.
|
||||
*
|
||||
* @param separatedPermissionString The array of a dot separated perm string.
|
||||
* @return The dot separated parent permission string.
|
||||
*/
|
||||
private static String getParentPerm(String[] separatedPermissionString) {
|
||||
if (separatedPermissionString.length == 1) {
|
||||
return null;
|
||||
}
|
||||
String returnString = "";
|
||||
for (int i = 0; i < separatedPermissionString.length - 1; i++) {
|
||||
returnString += separatedPermissionString[i] + ".";
|
||||
}
|
||||
return returnString + "*";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given {@link Player} has enough money to enter the specified {@link MVWorld}.
|
||||
* @param fromWorld The {@link MVWorld} the player is coming from.
|
||||
* @param toWorld The {@link MVWorld} the player is going to.
|
||||
* @param teleporter The teleporter.
|
||||
* @param teleportee The teleportee.
|
||||
* @param pay If the player has to pay the money.
|
||||
* @return True if the player can enter the world.
|
||||
*/
|
||||
public boolean playerHasMoneyToEnter(MVWorld fromWorld, MVWorld toWorld, CommandSender teleporter, Player teleportee, boolean pay) {
|
||||
Player teleporterPlayer;
|
||||
if (plugin.getMVConfig().getTeleportIntercept()) {
|
||||
if (teleporter instanceof ConsoleCommandSender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (teleporter == null) {
|
||||
teleporter = teleportee;
|
||||
}
|
||||
|
||||
if (!(teleporter instanceof Player)) {
|
||||
return false;
|
||||
}
|
||||
teleporterPlayer = (Player) teleporter;
|
||||
} else {
|
||||
if (teleporter instanceof Player) {
|
||||
teleporterPlayer = (Player) teleporter;
|
||||
} else {
|
||||
teleporterPlayer = null;
|
||||
}
|
||||
|
||||
// Old-style!
|
||||
if (teleporterPlayer == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the toWorld isn't controlled by MV,
|
||||
// We don't care.
|
||||
if (toWorld == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Only check payments if it's a different world:
|
||||
if (!toWorld.equals(fromWorld)) {
|
||||
final double price = toWorld.getPrice();
|
||||
// Don't bother checking economy stuff if it doesn't even cost to enter.
|
||||
if (price == 0D) {
|
||||
return true;
|
||||
}
|
||||
// If the player does not have to pay, return now.
|
||||
if (this.plugin.getMVPerms().hasPermission(teleporter, toWorld.getExemptPermission().getName(), true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final MVEconomist economist = plugin.getEconomist();
|
||||
final Material currency = toWorld.getCurrency();
|
||||
final String formattedAmount = economist.formatPrice(price, currency);
|
||||
|
||||
if (economist.isPlayerWealthyEnough(teleporterPlayer, price, currency)) {
|
||||
if (pay) {
|
||||
if (price < 0D) {
|
||||
economist.deposit(teleporterPlayer, -price, currency);
|
||||
} else {
|
||||
economist.withdraw(teleporterPlayer, price, currency);
|
||||
}
|
||||
sendTeleportPaymentMessage(economist, teleporterPlayer, teleportee, toWorld.getColoredWorldString(), price, currency);
|
||||
}
|
||||
} else {
|
||||
if (teleportee.equals(teleporter)) {
|
||||
teleporterPlayer.sendMessage(economist.getNSFMessage(currency,
|
||||
"You need " + formattedAmount + " to enter " + toWorld.getColoredWorldString()));
|
||||
} else {
|
||||
teleporterPlayer.sendMessage(economist.getNSFMessage(currency,
|
||||
"You need " + formattedAmount + " to send " + teleportee.getName() + " to " + toWorld.getColoredWorldString()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sendTeleportPaymentMessage (MVEconomist economist, Player teleporterPlayer, Player teleportee, String toWorld, double price, Material currency) {
|
||||
price = Math.abs(price);
|
||||
if (teleporterPlayer.equals(teleportee)) {
|
||||
teleporterPlayer.sendMessage("You were " + (price > 0D ? "charged " : "given ") + economist.formatPrice(price, currency) + " for teleporting to " + toWorld);
|
||||
} else {
|
||||
teleporterPlayer.sendMessage("You were " + (price > 0D ? "charged " : "given ") + economist.formatPrice(price, currency) + " for teleporting " + teleportee.getName() + " to " + toWorld);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks to see if player can go to a world given their current status.
|
||||
* <p>
|
||||
* The return is a little backwards, and will return a value safe for event.setCancelled.
|
||||
*
|
||||
* @param fromWorld The MultiverseWorld they are in.
|
||||
* @param toWorld The MultiverseWorld they want to go to.
|
||||
* @param teleporter The CommandSender that wants to send someone somewhere. If null,
|
||||
* will be given the same value as teleportee.
|
||||
* @param teleportee The player going somewhere.
|
||||
* @return True if they can't go to the world, False if they can.
|
||||
*/
|
||||
public boolean playerCanGoFromTo(MVWorld fromWorld, MVWorld toWorld, CommandSender teleporter, Player teleportee) {
|
||||
Logging.finest("Checking '" + teleporter + "' can send '" + teleportee + "' somewhere");
|
||||
|
||||
Player teleporterPlayer;
|
||||
if (plugin.getMVConfig().getTeleportIntercept()) {
|
||||
// The console can send anyone anywhere
|
||||
if (teleporter instanceof ConsoleCommandSender) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make sure we have a teleporter of some kind, even if it's inferred to be the teleportee
|
||||
if (teleporter == null) {
|
||||
teleporter = teleportee;
|
||||
}
|
||||
|
||||
// Now make sure we can cast the teleporter to a player, 'cause I'm tired of console things now
|
||||
if (!(teleporter instanceof Player)) {
|
||||
return false;
|
||||
}
|
||||
teleporterPlayer = (Player) teleporter;
|
||||
} else {
|
||||
if (teleporter instanceof Player) {
|
||||
teleporterPlayer = (Player) teleporter;
|
||||
} else {
|
||||
teleporterPlayer = null;
|
||||
}
|
||||
|
||||
// Old-style!
|
||||
if (teleporterPlayer == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Actual checks
|
||||
if (toWorld != null) {
|
||||
if (!this.plugin.getMVPerms().canEnterWorld(teleporterPlayer, toWorld)) {
|
||||
if (teleportee.equals(teleporter)) {
|
||||
teleporter.sendMessage("You don't have access to go here...");
|
||||
} else {
|
||||
teleporter.sendMessage("You can't send " + teleportee.getName() + " here...");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
if (fromWorld != null) {
|
||||
if (fromWorld.getWorldBlacklist().contains(toWorld.getName())) {
|
||||
if (teleportee.equals(teleporter)) {
|
||||
teleporter.sendMessage("You don't have access to go to " + toWorld.getColoredWorldString() + " from " + fromWorld.getColoredWorldString());
|
||||
} else {
|
||||
teleporter.sendMessage("You don't have access to send " + teleportee.getName() + " from "
|
||||
+ fromWorld.getColoredWorldString() + " to " + toWorld.getColoredWorldString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a player can bypass the player limit.
|
||||
*
|
||||
* @param toWorld The world travelling to.
|
||||
* @param teleporter The player that initiated the teleport.
|
||||
* @param teleportee The player travelling.
|
||||
* @return True if they can bypass the player limit.
|
||||
*/
|
||||
public boolean playerCanBypassPlayerLimit(MVWorld toWorld, CommandSender teleporter, Player teleportee) {
|
||||
if (teleporter == null) {
|
||||
teleporter = teleportee;
|
||||
}
|
||||
|
||||
if (!(teleporter instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a player should bypass game mode restrictions.
|
||||
*
|
||||
* @param toWorld world travelling to.
|
||||
* @param teleportee player travelling.
|
||||
* @return True if they should bypass restrictions
|
||||
*/
|
||||
public boolean playerCanIgnoreGameModeRestriction(MVWorld toWorld, Player teleportee) {
|
||||
if (toWorld != null) {
|
||||
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.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.Destination;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PermissionsTool {
|
||||
private static final String TELEPORT_PERM_PREFIX = "multiverse.teleport.";
|
||||
|
||||
private final MultiverseCore plugin;
|
||||
private PluginManager pluginManager;
|
||||
private Permission worldAccessPermission;
|
||||
private Permission bypassGameModePermission;
|
||||
private Permission bypassEntryFeePermission;
|
||||
private Permission bypassPlayerLimitPermission;
|
||||
|
||||
public PermissionsTool(MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void setUpPermissions() {
|
||||
this.pluginManager = this.plugin.getServer().getPluginManager();
|
||||
setUpWorldPermissionWildcards();
|
||||
}
|
||||
|
||||
private void setUpWorldPermissionWildcards() {
|
||||
this.worldAccessPermission = new Permission("multiverse.access.*",
|
||||
"Allows access to all worlds",
|
||||
PermissionDefault.OP);
|
||||
this.bypassGameModePermission = new Permission("mv.bypass.gamemode.*",
|
||||
"Allows players with this permission to ignore gamemode changes.",
|
||||
PermissionDefault.FALSE);
|
||||
this.bypassEntryFeePermission = new Permission("multiverse.exempt.*",
|
||||
"A player who has this does not pay to enter this world, or use any MV portals in it",
|
||||
PermissionDefault.OP);
|
||||
this.bypassPlayerLimitPermission = new Permission("mv.bypass.playerlimit.*",
|
||||
"A player who can enter this world regardless of whether its full",
|
||||
PermissionDefault.OP);
|
||||
|
||||
try {
|
||||
pluginManager.addPermission(this.worldAccessPermission);
|
||||
pluginManager.addPermission(this.bypassGameModePermission);
|
||||
pluginManager.addPermission(this.bypassEntryFeePermission);
|
||||
pluginManager.addPermission(this.bypassPlayerLimitPermission);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logging.finer("World permissions wildcard already registered.");
|
||||
}
|
||||
|
||||
Logging.finer("Registered world permissions wildcard.");
|
||||
}
|
||||
|
||||
public void registerMVWorldPermissions(MVWorld world) {
|
||||
Permission accessPermission = new Permission("multiverse.access." + world.getName(),
|
||||
"Allows access to " + world.getName(),
|
||||
PermissionDefault.OP);
|
||||
Permission ignorePermission = new Permission("mv.bypass.gamemode." + world.getName(),
|
||||
"Allows players with this permission to ignore gamemode changes.",
|
||||
PermissionDefault.FALSE);
|
||||
Permission exemptPermission = new Permission("multiverse.exempt." + world.getName(),
|
||||
"A player who has this does not pay to enter this world, or use any MV portals in it " + world.getName(),
|
||||
PermissionDefault.OP);
|
||||
Permission playerLimitPermissions = new Permission("mv.bypass.playerlimit." + world.getName(),
|
||||
"A player who can enter this world regardless of whether its full",
|
||||
PermissionDefault.OP);
|
||||
|
||||
try {
|
||||
pluginManager.addPermission(accessPermission);
|
||||
pluginManager.addPermission(ignorePermission);
|
||||
pluginManager.addPermission(exemptPermission);
|
||||
pluginManager.addPermission(playerLimitPermissions);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logging.finer("World permissions already registered for '" + world.getName() + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
accessPermission.addParent(this.worldAccessPermission, true);
|
||||
ignorePermission.addParent(this.bypassGameModePermission, true);
|
||||
exemptPermission.addParent(this.bypassEntryFeePermission, true);
|
||||
playerLimitPermissions.addParent(this.bypassPlayerLimitPermission, true);
|
||||
|
||||
Logging.finer("Registered permissions for '" + world.getName() + "'");
|
||||
}
|
||||
|
||||
public void removeMVWorldPermissions(MVWorld world) {
|
||||
Permission accessPermission = pluginManager.getPermission("multiverse.access." + world.getName());
|
||||
if (accessPermission != null) {
|
||||
this.worldAccessPermission.getChildren().remove(accessPermission.getName());
|
||||
pluginManager.removePermission(accessPermission);
|
||||
}
|
||||
Permission ignorePermission = pluginManager.getPermission("mv.bypass.gamemode." + world.getName());
|
||||
if (ignorePermission != null) {
|
||||
this.bypassGameModePermission.getChildren().remove(ignorePermission.getName());
|
||||
pluginManager.removePermission(ignorePermission);
|
||||
}
|
||||
Permission exemptPermission = pluginManager.getPermission("multiverse.exempt." + world.getName());
|
||||
if (exemptPermission != null) {
|
||||
this.bypassEntryFeePermission.getChildren().remove(exemptPermission.getName());
|
||||
pluginManager.removePermission(exemptPermission);
|
||||
}
|
||||
Permission playerLimitPermissions = pluginManager.getPermission("mv.bypass.playerlimit." + world.getName());
|
||||
if (playerLimitPermissions != null) {
|
||||
this.bypassPlayerLimitPermission.getChildren().remove(playerLimitPermissions.getName());
|
||||
pluginManager.removePermission(playerLimitPermissions);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllMVWorldPermissions() {
|
||||
this.worldAccessPermission.getChildren().keySet().forEach(pluginManager::removePermission);
|
||||
this.bypassGameModePermission.getChildren().keySet().forEach(pluginManager::removePermission);
|
||||
this.bypassEntryFeePermission.getChildren().keySet().forEach(pluginManager::removePermission);
|
||||
this.bypassPlayerLimitPermission.getChildren().keySet().forEach(pluginManager::removePermission);
|
||||
|
||||
pluginManager.removePermission(this.worldAccessPermission);
|
||||
pluginManager.removePermission(this.bypassGameModePermission);
|
||||
pluginManager.removePermission(this.bypassEntryFeePermission);
|
||||
pluginManager.removePermission(this.bypassPlayerLimitPermission);
|
||||
|
||||
setUpWorldPermissionWildcards();
|
||||
}
|
||||
|
||||
public void registerDestinationTeleportPermissions(Destination<?> destination) {
|
||||
try {
|
||||
pluginManager.addPermission(new Permission(TELEPORT_PERM_PREFIX + "self." + destination.getIdentifier(), PermissionDefault.OP));
|
||||
pluginManager.addPermission(new Permission(TELEPORT_PERM_PREFIX + "other." + destination.getIdentifier(), PermissionDefault.OP));
|
||||
pluginManager.addPermission(new Permission(TELEPORT_PERM_PREFIX + "self." + destination.getIdentifier() + ".*", PermissionDefault.OP));
|
||||
pluginManager.addPermission(new Permission(TELEPORT_PERM_PREFIX + "other." + destination.getIdentifier() + ".*", PermissionDefault.OP));
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logging.finer("Destination permissions already registered for '" + destination.getIdentifier() + "'");
|
||||
}
|
||||
Logging.finer("Registered permissions for '" + destination.getIdentifier() + "'");
|
||||
}
|
||||
|
||||
public void registerFinerDestinationTeleportPermissions(Destination<?> destination, String finerSuffix) {
|
||||
String finerPermissionName = TELEPORT_PERM_PREFIX + "self." + destination.getIdentifier() + "." + finerSuffix;
|
||||
if (pluginManager.getPermission(finerPermissionName) != null) {
|
||||
return;
|
||||
}
|
||||
Permission permission = pluginManager.getPermission(TELEPORT_PERM_PREFIX + "self." + destination.getIdentifier() + ".*");
|
||||
if (permission == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Permission finerPermission = new Permission(finerPermissionName, PermissionDefault.OP);
|
||||
try {
|
||||
pluginManager.addPermission(finerPermission);
|
||||
return;
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logging.finer("Finer destination permissions already registered for '" + destination.getIdentifier() + "'");
|
||||
}
|
||||
|
||||
finerPermission.addParent(permission, true);
|
||||
Logging.finer("Registered finer permissions '" + finerPermissionName + "' for '" + destination.getIdentifier() + "'");
|
||||
}
|
||||
|
||||
public boolean hasBypassPlayerLimit(@NotNull CommandSender sender, @NotNull MVWorld toWorld) {
|
||||
return hasPermission(sender, "mv.bypass.playerlimit." + toWorld.getName());
|
||||
}
|
||||
|
||||
public boolean hasBypassEntryFee(@NotNull CommandSender sender, @NotNull MVWorld toWorld) {
|
||||
return hasPermission(sender, "multiverse.exempt." + toWorld.getName());
|
||||
}
|
||||
|
||||
public boolean hasBypassGameModeEnforcement(@NotNull CommandSender sender, @NotNull MVWorld toWorld) {
|
||||
return hasPermission(sender, "mv.bypass.gamemode." + toWorld.getName());
|
||||
}
|
||||
|
||||
public boolean hasWorldAccess(@NotNull CommandSender sender, @NotNull MVWorld toWorld) {
|
||||
return hasPermission(sender, "multiverse.access." + toWorld.getName());
|
||||
}
|
||||
|
||||
public boolean hasDestinationTeleportPermission(@NotNull CommandSender teleportee, @NotNull Destination<?> destination) {
|
||||
return hasDestinationTeleportPermission(null, teleportee, destination);
|
||||
}
|
||||
|
||||
public boolean hasDestinationTeleportPermission(@Nullable CommandSender teleporter,
|
||||
@NotNull CommandSender teleportee,
|
||||
@NotNull Destination<?> destination
|
||||
) {
|
||||
if (teleporter == null || teleportee.equals(teleporter)) {
|
||||
return hasPermission(teleportee, TELEPORT_PERM_PREFIX + "self." + destination.getIdentifier());
|
||||
}
|
||||
return hasPermission(teleporter, TELEPORT_PERM_PREFIX + "other." + destination.getIdentifier());
|
||||
}
|
||||
|
||||
public boolean hasFinerDestinationTeleportPermission(@NotNull CommandSender teleportee, @NotNull ParsedDestination<?> destination) {
|
||||
return hasFinerDestinationTeleportPermission(null, teleportee, destination);
|
||||
}
|
||||
|
||||
public boolean hasFinerDestinationTeleportPermission(@Nullable CommandSender teleporter,
|
||||
@NotNull CommandSender teleportee,
|
||||
@NotNull ParsedDestination<?> destination
|
||||
) {
|
||||
if (teleporter == null || teleportee.equals(teleporter)) {
|
||||
return hasPermission(teleportee, TELEPORT_PERM_PREFIX + "self."
|
||||
+ destination.getDestination().getIdentifier() + "."
|
||||
+ destination.getDestinationInstance().getFinerPermissionSuffix());
|
||||
}
|
||||
return hasPermission(teleporter, TELEPORT_PERM_PREFIX + "other."
|
||||
+ destination.getDestination().getIdentifier() + "."
|
||||
+ destination.getDestinationInstance().getFinerPermissionSuffix());
|
||||
}
|
||||
|
||||
public boolean hasAnyDestinationTeleportPermissions(@NotNull CommandSender sender) {
|
||||
return this.plugin.getDestinationsProvider().getRegisteredDestinations().stream()
|
||||
.anyMatch(destination -> hasDestinationTeleportPermission(sender, this.plugin.getServer().getConsoleSender(), destination)
|
||||
|| hasDestinationTeleportPermission(sender, destination));
|
||||
}
|
||||
|
||||
private boolean hasPermission(@NotNull CommandSender sender, @NotNull String permission) {
|
||||
if (sender.hasPermission(permission)) {
|
||||
Logging.finer("Checking to see if sender [" + sender.getName() + "] has permission [" + permission + "]... YES");
|
||||
return true;
|
||||
}
|
||||
Logging.finer("Checking to see if sender [" + sender.getName() + "] has permission [" + permission + "]... NO");
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,181 @@
|
||||
package com.onarandombox.MultiverseCore.utils;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorld;
|
||||
import com.onarandombox.MultiverseCore.api.MVWorldManager;
|
||||
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
|
||||
import com.onarandombox.MultiverseCore.utils.action.ActionResponse;
|
||||
import com.onarandombox.MultiverseCore.world.configuration.EntryFee;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PlayerActionChecker {
|
||||
private final MultiverseCore plugin;
|
||||
private final MVWorldManager worldManager;
|
||||
private final PermissionsTool permissionsTool;
|
||||
|
||||
public PlayerActionChecker(MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
this.worldManager = plugin.getMVWorldManager();
|
||||
this.permissionsTool = plugin.getPermissionsTool();
|
||||
}
|
||||
|
||||
public ActionCheckResult canUseDestinationToTeleport(@NotNull Player teleportee, @Nullable ParsedDestination<?> destination){
|
||||
return canUseDestinationToTeleport(null, teleportee, destination);
|
||||
}
|
||||
|
||||
public ActionCheckResult canUseDestinationToTeleport(@Nullable CommandSender teleporter,
|
||||
@NotNull CommandSender teleportee,
|
||||
@Nullable ParsedDestination<?> destination
|
||||
) {
|
||||
if (destination == null) {
|
||||
return ActionCheckResult.NULL_DESTINATION;
|
||||
}
|
||||
if (!permissionsTool.hasDestinationTeleportPermission(
|
||||
teleporter == null ? teleportee : teleporter,
|
||||
teleportee,
|
||||
destination.getDestination())
|
||||
) {
|
||||
return ActionCheckResult.NO_DESTINATION_PERMISSION;
|
||||
}
|
||||
//TODO Config whether to use finer permission
|
||||
return permissionsTool.hasFinerDestinationTeleportPermission(teleporter, teleportee, destination)
|
||||
? ActionCheckResult.CAN_USE_DESTINATION : ActionCheckResult.NO_DESTINATION_PERMISSION;
|
||||
}
|
||||
|
||||
public ActionResponse canGoToDestination(@NotNull Player teleportee, @Nullable ParsedDestination<?> destination){
|
||||
return canGoToDestination(null, teleportee, destination);
|
||||
}
|
||||
|
||||
public ActionResponse canGoToDestination(@Nullable CommandSender teleporter,
|
||||
@NotNull Player teleportee,
|
||||
@Nullable ParsedDestination<?> destination
|
||||
) {
|
||||
if (destination == null) {
|
||||
return new ActionResponse().addResult(ActionCheckResult.NULL_DESTINATION);
|
||||
}
|
||||
Location location = destination.getDestinationInstance().getLocation(teleportee);
|
||||
if (location == null) {
|
||||
return new ActionResponse().addResult(ActionCheckResult.NULL_LOCATION);
|
||||
}
|
||||
return canGoToLocation(teleporter, teleportee, location);
|
||||
}
|
||||
|
||||
public ActionResponse canGoToLocation(@NotNull Player teleportee, @Nullable Location location){
|
||||
return canGoToLocation(null, teleportee, location);
|
||||
}
|
||||
|
||||
public ActionResponse canGoToLocation(@Nullable CommandSender teleporter,
|
||||
@NotNull Player teleportee,
|
||||
@Nullable Location location
|
||||
) {
|
||||
if (location == null) {
|
||||
return new ActionResponse().addResult(ActionCheckResult.NULL_LOCATION);
|
||||
}
|
||||
MVWorld toWorld = this.worldManager.getMVWorld(location.getWorld());
|
||||
return canEnterWorld(teleporter, teleportee, toWorld);
|
||||
}
|
||||
|
||||
public ActionResponse canEnterWorld(@NotNull Player player, @NotNull MVWorld toWorld) {
|
||||
return canEnterWorld(null, player, toWorld);
|
||||
}
|
||||
|
||||
public ActionResponse canEnterWorld(@Nullable CommandSender teleporter,
|
||||
@NotNull Player player,
|
||||
@NotNull MVWorld toWorld
|
||||
) {
|
||||
MVWorld fromWorld = this.worldManager.getMVWorld(player.getWorld());
|
||||
return canGoFromToWorld(teleporter, player, fromWorld, toWorld);
|
||||
}
|
||||
|
||||
public ActionResponse canGoFromToWorld(@NotNull CommandSender teleportee, @Nullable MVWorld fromWorld, @NotNull MVWorld toWorld) {
|
||||
return canGoFromToWorld(null, teleportee, fromWorld, toWorld);
|
||||
}
|
||||
|
||||
public ActionResponse canGoFromToWorld(@Nullable CommandSender teleporter,
|
||||
@NotNull CommandSender teleportee,
|
||||
@Nullable MVWorld fromWorld,
|
||||
@Nullable MVWorld toWorld
|
||||
) {
|
||||
ActionResponse response = new ActionResponse();
|
||||
if (toWorld == null) {
|
||||
return new ActionResponse().addResult(ActionCheckResult.NOT_MV_WORLD);
|
||||
}
|
||||
if (toWorld.equals(fromWorld)) {
|
||||
return response.addResult(ActionCheckResult.SAME_WORLD)
|
||||
.then(() -> isNotBlacklisted(fromWorld, toWorld));
|
||||
}
|
||||
|
||||
CommandSender targetSender = (teleporter == null) ? teleportee : teleporter;
|
||||
|
||||
return response.then(() -> hasAccessToWorld(targetSender, toWorld))
|
||||
.then(() -> isWithinPlayerLimit(targetSender, toWorld))
|
||||
.then(() -> isNotBlacklisted(fromWorld, toWorld))
|
||||
.then(() -> hasMoneyToEnterWorld(targetSender, toWorld));
|
||||
}
|
||||
|
||||
public ActionCheckResult hasAccessToWorld(@NotNull CommandSender sender, @NotNull MVWorld toWorld) {
|
||||
if (!this.plugin.getMVConfig().getEnforceAccess()) {
|
||||
return ActionCheckResult.NO_ENFORCE_WORLD_ACCESS;
|
||||
}
|
||||
return permissionsTool.hasWorldAccess(sender, toWorld)
|
||||
? ActionCheckResult.HAS_WORLD_ACCESS : ActionCheckResult.NO_WORLD_ACCESS;
|
||||
}
|
||||
|
||||
public ActionCheckResult hasMoneyToEnterWorld(@NotNull CommandSender sender, @NotNull MVWorld toWorld) {
|
||||
if (sender instanceof ConsoleCommandSender || sender instanceof BlockCommandSender) {
|
||||
return ActionCheckResult.EXEMPTED_FROM_ENTRY_FEE;
|
||||
}
|
||||
if (!(sender instanceof Player)) {
|
||||
return ActionCheckResult.CANNOT_PAY_ENTRY_FEE;
|
||||
}
|
||||
|
||||
double price = toWorld.getPrice();
|
||||
Material currency = toWorld.getCurrency();
|
||||
if (price == 0D && (currency == null || currency == EntryFee.DISABLED_MATERIAL)) {
|
||||
return ActionCheckResult.FREE_ENTRY;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
if (permissionsTool.hasBypassEntryFee(player, toWorld)) {
|
||||
return ActionCheckResult.EXEMPTED_FROM_ENTRY_FEE;
|
||||
}
|
||||
|
||||
return this.plugin.getEconomist().isPlayerWealthyEnough(player, price, currency)
|
||||
? ActionCheckResult.ENOUGH_MONEY : ActionCheckResult.NOT_ENOUGH_MONEY;
|
||||
}
|
||||
|
||||
public ActionCheckResult isWithinPlayerLimit(@NotNull CommandSender sender, @NotNull MVWorld toWorld) {
|
||||
if (toWorld.getPlayerLimit() < 0 || toWorld.getCBWorld().getPlayers().size() <= toWorld.getPlayerLimit()) {
|
||||
return ActionCheckResult.WITHIN_PLAYERLIMIT;
|
||||
}
|
||||
return permissionsTool.hasBypassPlayerLimit(sender, toWorld)
|
||||
? ActionCheckResult.BYPASS_PLAYERLIMIT : ActionCheckResult.EXCEED_PLAYERLIMIT;
|
||||
}
|
||||
|
||||
public ActionCheckResult isNotBlacklisted(@NotNull Player player, @NotNull MVWorld toWorld) {
|
||||
MVWorld fromWorld = this.worldManager.getMVWorld(player.getWorld());
|
||||
return isNotBlacklisted(fromWorld, toWorld);
|
||||
}
|
||||
|
||||
public ActionCheckResult isNotBlacklisted(@Nullable MVWorld fromWorld, @NotNull MVWorld toWorld) {
|
||||
if (fromWorld == null) {
|
||||
// No blacklisting if the player is not in a MV world
|
||||
return ActionCheckResult.NOT_BLACKLISTED;
|
||||
}
|
||||
return toWorld.getWorldBlacklist().contains(fromWorld.getName())
|
||||
? ActionCheckResult.BLACKLISTED : ActionCheckResult.NOT_BLACKLISTED;
|
||||
}
|
||||
|
||||
public ActionCheckResult canKeepGameMode(@NotNull CommandSender sender, @NotNull MVWorld toWorld) {
|
||||
//TODO: Add config option disable game mode enforcement
|
||||
return permissionsTool.hasBypassGameModeEnforcement(sender, toWorld)
|
||||
? ActionCheckResult.KEEP_GAME_MODE : ActionCheckResult.ENFORCE_GAME_MODE;
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.onarandombox.MultiverseCore.utils.action;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ActionResponse implements ActionResult {
|
||||
private final Set<ActionResult> results;
|
||||
private final boolean continueIfFail;
|
||||
|
||||
private boolean isSuccessful = true;
|
||||
|
||||
public ActionResponse() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public ActionResponse(boolean continueIfFail) {
|
||||
this.results = new HashSet<>();
|
||||
this.continueIfFail = continueIfFail;
|
||||
}
|
||||
|
||||
public ActionResponse then(Supplier<ActionResult> resultSupplier) {
|
||||
if (!continueIfFail && !isSuccessful) {
|
||||
return this;
|
||||
}
|
||||
return addResult(resultSupplier.get());
|
||||
}
|
||||
|
||||
public ActionResponse addResult(ActionResult result) {
|
||||
if (!continueIfFail && !isSuccessful) {
|
||||
return this;
|
||||
}
|
||||
|
||||
results.add(result);
|
||||
if (!result.isSuccessful()) {
|
||||
isSuccessful = false;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return results.stream().map(ActionResult::getName).collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
public boolean isSuccessful() {
|
||||
return isSuccessful;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasResult(ActionResult result) {
|
||||
return results.contains(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ActionResponse{" +
|
||||
"results=" + getName() +
|
||||
"; continueIfFail=" + continueIfFail +
|
||||
"; isSuccessful=" + isSuccessful +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.onarandombox.MultiverseCore.utils.action;
|
||||
|
||||
public interface ActionResult {
|
||||
String getName();
|
||||
|
||||
boolean isSuccessful();
|
||||
|
||||
boolean hasResult(ActionResult result);
|
||||
}
|
@ -38,8 +38,6 @@ import org.bukkit.World.Environment;
|
||||
import org.bukkit.WorldType;
|
||||
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.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -87,7 +85,7 @@ public class SimpleMVWorld implements MVWorld {
|
||||
this.props.environment = world.getEnvironment();
|
||||
this.props.seed = world.getSeed();
|
||||
|
||||
this.initPerms();
|
||||
this.plugin.getPermissionsTool().registerMVWorldPermissions(this);
|
||||
|
||||
this.props.flushChanges();
|
||||
|
||||
@ -335,11 +333,6 @@ public class SimpleMVWorld implements MVWorld {
|
||||
}
|
||||
}
|
||||
|
||||
private Permission permission;
|
||||
private Permission exempt;
|
||||
private Permission ignoreperm;
|
||||
private Permission limitbypassperm;
|
||||
|
||||
/**
|
||||
* Null-location.
|
||||
*/
|
||||
@ -384,37 +377,6 @@ public class SimpleMVWorld implements MVWorld {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
Logging.finer("Permissions nodes were already added for " + this.name);
|
||||
}
|
||||
}
|
||||
|
||||
private Location readSpawnFromWorld(World w) {
|
||||
Location location = w.getSpawnLocation();
|
||||
// Set the worldspawn to our configspawn
|
||||
@ -457,32 +419,6 @@ public class SimpleMVWorld implements MVWorld {
|
||||
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 SimpleMVWorld} object.
|
||||
* @param other The other world object.
|
||||
@ -724,14 +660,6 @@ public class SimpleMVWorld implements MVWorld {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String getPermissibleName() {
|
||||
return this.name.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@ -912,14 +840,6 @@ public class SimpleMVWorld implements MVWorld {
|
||||
return this.props.setRespawnToWorld(respawnToWorld);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Permission getAccessPermission() {
|
||||
return this.permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@ -952,14 +872,6 @@ public class SimpleMVWorld implements MVWorld {
|
||||
this.props.setPrice(price);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Permission getExemptPermission() {
|
||||
return this.exempt;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -726,25 +726,7 @@ public class SimpleMVWorldManager implements MVWorldManager {
|
||||
|
||||
// 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 (MVWorld 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.plugin.getPermissionsTool().removeAllMVWorldPermissions();
|
||||
this.worlds.clear();
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ public class EntryFee extends SerializationConfig {
|
||||
@Nullable
|
||||
private Material currency;
|
||||
|
||||
private final Material DISABLED_MATERIAL = Material.AIR;
|
||||
public static final Material DISABLED_MATERIAL = Material.AIR;
|
||||
|
||||
public EntryFee() {
|
||||
super();
|
||||
|
Loading…
Reference in New Issue
Block a user