Fix tp perms to take into account teleporter and teleportee. This may eat your server

This commit is contained in:
Eric Stokes 2011-11-26 19:38:57 -07:00
parent 156e7ce373
commit 562de0f002
6 changed files with 170 additions and 71 deletions

View File

@ -41,13 +41,32 @@ import java.util.logging.Level;
import java.util.logging.Logger;
public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
private final static int Protocol = 8;
private final static int Protocol = 9;
// Global Multiverse config variable, states whether or not
// Multiverse should stop other plugins from teleporting players
// to worlds.
public static boolean EnforceAccess;
public static boolean EnforceGameModes;
public static boolean PrefixChat;
public static Map<String, String> teleportQueue = new HashMap<String, String>();
/**
* This method is used to find out who is teleporting a player.
* @param playerName
* @return
*/
public static String getPlayerTeleporter(String playerName) {
if(teleportQueue.containsKey(playerName)) {
String teleportee = teleportQueue.get(playerName);
teleportQueue.remove(playerName);
return teleportee;
}
return null;
}
public static void addPlayerToTeleportQueue(String teleporter, String teleportee) {
teleportQueue.put(teleporter, teleportee);
}
@Override
public String toString() {

View File

@ -12,6 +12,7 @@ import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.destination.DestinationFactory;
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
import com.onarandombox.MultiverseCore.destination.WorldDestination;
import com.onarandombox.MultiverseCore.enums.TeleportResult;
import com.onarandombox.MultiverseCore.event.MVTeleportEvent;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import com.onarandombox.MultiverseCore.utils.MVMessaging;
@ -144,7 +145,8 @@ public class TeleportCommand extends MultiverseCommand {
teleporter.sendMessage("Sorry Boss, I tried everything, but just couldn't teleport ya there!");
return;
}
if (!this.playerTeleporter.safelyTeleport(teleporter, teleportee, d)) {
TeleportResult result = this.playerTeleporter.safelyTeleport(teleporter, teleportee, d);
if (result == TeleportResult.FAIL_UNSAFE) {
this.plugin.log(Level.FINE, "Could not teleport " + teleportee.getName() + " to " + LocationManipulation.strCoordsRaw(d.getLocation(teleportee)));
this.plugin.log(Level.FINE, "Queueing Command");
Class<?> paramTypes[] = {CommandSender.class, Player.class, Location.class};

View File

@ -0,0 +1,12 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2011. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.enums;
public enum TeleportResult {
FAIL_PERMISSION, FAIL_UNSAFE, FAIL_TOO_POOR, FAIL_INVALID, FAIL_OTHER, SUCCESS
}

View File

@ -7,13 +7,12 @@
package com.onarandombox.MultiverseCore.listeners;
import com.fernferret.allpay.GenericBank;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.event.MVRespawnEvent;
import com.onarandombox.MultiverseCore.utils.PermissionTools;
import com.onarandombox.MultiverseCore.utils.SafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.WorldManager;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.event.player.*;
@ -24,10 +23,13 @@ public class MVPlayerListener extends PlayerListener {
MultiverseCore plugin;
SafeTTeleporter mvteleporter;
MVWorldManager worldManager;
private PermissionTools pt;
public MVPlayerListener(MultiverseCore plugin) {
this.plugin = plugin;
worldManager = plugin.getMVWorldManager();
pt = new PermissionTools(plugin);
}
@Override
@ -127,39 +129,60 @@ public class MVPlayerListener extends PlayerListener {
if (event.isCancelled()) {
return;
}
Player teleportee = event.getPlayer();
Player teleporter = null;
String teleporterName = MultiverseCore.getPlayerTeleporter(teleportee.getName());
if (teleporterName != null) {
teleporter = this.plugin.getServer().getPlayer(teleporterName);
}
MultiverseWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld().getName());
MultiverseWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName());
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
// The player is Teleporting to the same world.
this.plugin.log(Level.FINER, "Player '" + event.getPlayer().getName() + "' is teleporting to the same world.");
this.plugin.log(Level.FINER, "Player '" + teleportee.getName() + "' is teleporting to the same world.");
return;
}
// TODO: Refactor these lines.
// Charge the teleporter
event.setCancelled(!pt.playerHasMoneyToEnter(fromWorld, toWorld, teleporter, teleportee));
if (event.isCancelled() && teleporter != null) {
this.plugin.log(Level.FINE, "Player '" + teleportee.getName() + "' was DENIED ACCESS to '" + event.getTo().getWorld().getName() +
"' because '" + teleporter.getName() + "' don't have the FUNDS required to enter it.");
return;
}
if (MultiverseCore.EnforceAccess) {
event.setCancelled(!playerCanGoFromTo(fromWorld, toWorld, event.getPlayer()));
if (event.isCancelled()) {
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName() + "' was DENIED ACCESS to '" + event.getTo().getWorld().getName() +
"' because they don't have: multiverse.access." + event.getTo().getWorld().getName());
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, teleporter, teleportee));
if (event.isCancelled() && teleporter != null) {
this.plugin.log(Level.FINE, "Player '" + teleportee.getName() + "' was DENIED ACCESS to '" + event.getTo().getWorld().getName() +
"' because '" + teleporter.getName() + "' don't have: multiverse.access." + event.getTo().getWorld().getName());
}
} else {
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName() + "' was allowed to go to '" + event.getTo().getWorld().getName() + "' because enforceaccess is off.");
this.plugin.log(Level.FINE, "Player '" + teleportee.getName() + "' was allowed to go to '" + event.getTo().getWorld().getName() + "' because enforceaccess is off.");
}
}
@Override
public void onPlayerPortal(PlayerPortalEvent event) {
if (event.isCancelled() || event.getTo() == null || event.getFrom() == null) {
if (event.isCancelled() || event.getFrom() == null) {
return;
}
// REMEMBER! getTo MAY be NULL HERE!!!
// If the player was actually outside of the portal, adjust the from location
if (event.getFrom().getWorld().getBlockAt(event.getFrom()).getType() != Material.PORTAL) {
Location newloc = SafeTTeleporter.findPortalBlockNextTo(event.getFrom());
// TODO: Fix this. Currently, we only check for PORTAL blocks. I'll have to figure out what
// TODO: we want to do here.
if (newloc != null) {
System.out.println("Found a new location!");
event.setFrom(newloc);
} else {
System.out.println("Did NOT find a new location!");
}
}
// Wait for the adjust, then return!
if (event.getTo() == null) {
return;
}
MultiverseWorld fromWorld = this.worldManager.getMVWorld(event.getFrom().getWorld().getName());
MultiverseWorld toWorld = this.worldManager.getMVWorld(event.getTo().getWorld().getName());
if (event.getFrom().getWorld().equals(event.getTo().getWorld())) {
@ -167,8 +190,14 @@ public class MVPlayerListener extends PlayerListener {
this.plugin.log(Level.FINER, "Player '" + event.getPlayer().getName() + "' is portaling to the same world.");
return;
}
event.setCancelled(!pt.playerHasMoneyToEnter(fromWorld, toWorld, event.getPlayer(), event.getPlayer()));
if (event.isCancelled()) {
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName() + "' was DENIED ACCESS to '" + event.getTo().getWorld().getName() +
"' because they don't have the FUNDS required to enter.");
return;
}
if (MultiverseCore.EnforceAccess) {
event.setCancelled(!playerCanGoFromTo(fromWorld, toWorld, event.getPlayer()));
event.setCancelled(!pt.playerCanGoFromTo(fromWorld, toWorld, event.getPlayer(), event.getPlayer()));
if (event.isCancelled()) {
this.plugin.log(Level.FINE, "Player '" + event.getPlayer().getName() + "' was DENIED ACCESS to '" + event.getTo().getWorld().getName() +
"' because they don't have: multiverse.access." + event.getTo().getWorld().getName());
@ -178,51 +207,6 @@ public class MVPlayerListener extends PlayerListener {
}
}
/**
* 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 player The player that wants to travel.
*
* @return True if they can't go to the world, False if they can.
*/
private boolean playerCanGoFromTo(MultiverseWorld fromWorld, MultiverseWorld toWorld, Player player) {
if (toWorld != null) {
if (!this.plugin.getMVPerms().canEnterWorld(player, toWorld)) {
player.sendMessage("You don't have access to go 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())) {
player.sendMessage("You don't have access to go to " + toWorld.getColoredWorldString() + " from " + fromWorld.getColoredWorldString());
return false;
}
}
// Only check payments if it's a different world:
if (!toWorld.equals(fromWorld)) {
// If the player does not have to pay, return now.
if (this.plugin.getMVPerms().hasPermission(player, toWorld.getExemptPermission().getName(), true)) {
return true;
}
GenericBank bank = plugin.getBank();
if (!bank.hasEnough(player, toWorld.getPrice(), toWorld.getCurrency(), "You need " + bank.getFormattedAmount(player, toWorld.getPrice(), toWorld.getCurrency()) + " to enter " + toWorld.getColoredWorldString())) {
return false;
} else {
bank.pay(player, toWorld.getPrice(), toWorld.getCurrency());
}
}
return true;
}
// FOLLOWING 2 Methods and Private class handle Per Player GameModes.
private void handleGameMode(Player player, World world) {
@ -239,7 +223,9 @@ public class MVPlayerListener extends PlayerListener {
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, new HandleGameMode(player, world), 1L);
}
/** The following private class is used to handle player game mode changes within a scheduler. */
/**
* The following private class is used to handle player game mode changes within a scheduler.
*/
private class HandleGameMode implements Runnable {
private Player player;

View File

@ -7,7 +7,10 @@
package com.onarandombox.MultiverseCore.utils;
import com.fernferret.allpay.GenericBank;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permission;
public class PermissionTools {
@ -63,7 +66,6 @@ public class PermissionTools {
* 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 String getParentPerm(String[] separatedPermissionString) {
@ -76,4 +78,72 @@ public class PermissionTools {
}
return returnString + "*";
}
public boolean playerHasMoneyToEnter(MultiverseWorld fromWorld, MultiverseWorld toWorld, Player teleporter, Player teleportee) {
if (teleporter == null) {
return true;
}
// Only check payments if it's a different world:
if (!toWorld.equals(fromWorld)) {
// If the player does not have to pay, return now.
if (this.plugin.getMVPerms().hasPermission(teleporter, toWorld.getExemptPermission().getName(), true)) {
return true;
}
GenericBank bank = plugin.getBank();
String errString = "You need " + bank.getFormattedAmount(teleporter, toWorld.getPrice(), toWorld.getCurrency()) + " to send " + teleportee + " to " + toWorld.getColoredWorldString();
if (teleportee.equals(teleporter)) {
errString = "You need " + bank.getFormattedAmount(teleporter, toWorld.getPrice(), toWorld.getCurrency()) + " to enter " + toWorld.getColoredWorldString();
}
if (!bank.hasEnough(teleporter, toWorld.getPrice(), toWorld.getCurrency(), errString)) {
return false;
} else {
bank.pay(teleporter, toWorld.getPrice(), toWorld.getCurrency());
}
}
return true;
}
/**
* 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 player that wants to travel.
* @return True if they can't go to the world, False if they can.
*/
public boolean playerCanGoFromTo(MultiverseWorld fromWorld, MultiverseWorld toWorld, Player teleporter, Player teleportee) {
// The console can send anyone anywhere
if (teleporter == null) {
return true;
}
if (toWorld != null) {
if (!this.plugin.getMVPerms().canEnterWorld(teleporter, 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;
}
}

View File

@ -10,6 +10,7 @@ package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
import com.onarandombox.MultiverseCore.enums.TeleportResult;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
@ -100,7 +101,6 @@ public class SafeTTeleporter {
*
* @param l
* @param diameter
*
* @return
*/
private Location checkAroundLocation(Location l, int diameter) {
@ -186,14 +186,24 @@ public class SafeTTeleporter {
* @param teleporter Person who performed the teleport command.
* @param teleportee Entity to teleport
* @param d Destination to teleport them to
*
* @return true for success, false for failure
*/
public boolean safelyTeleport(CommandSender teleporter, Entity teleportee, MVDestination d) {
public TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, MVDestination d) {
if (d instanceof InvalidDestination) {
this.plugin.log(Level.FINER, "Entity tried to teleport to an invalid destination");
return false;
return TeleportResult.FAIL_INVALID;
}
Player teleporteePlayer = null;
if (teleportee instanceof Player) {
teleporteePlayer = ((Player) teleportee);
} else if (teleportee.getPassenger() instanceof Player) {
teleporteePlayer = ((Player) teleportee.getPassenger());
}
if (teleporteePlayer == null) {
return TeleportResult.FAIL_INVALID;
}
MultiverseCore.addPlayerToTeleportQueue(teleporter.getName(), teleporteePlayer.getName());
Location safeLoc = d.getLocation(teleportee);
if (d.useSafeTeleporter()) {
@ -205,10 +215,11 @@ public class SafeTTeleporter {
if (!d.getVelocity().equals(new Vector(0, 0, 0))) {
teleportee.setVelocity(d.getVelocity());
}
return true;
return TeleportResult.SUCCESS;
}
return TeleportResult.FAIL_OTHER;
}
return false;
return TeleportResult.FAIL_UNSAFE;
}
/**
@ -220,20 +231,20 @@ public class SafeTTeleporter {
* @param teleportee Entity to teleport.
* @param location Location to teleport them to.
* @param safely Should the destination be checked for safety before teleport?
*
* @return true for success, false for failure.
*/
public boolean safelyTeleport(CommandSender teleporter, Entity teleportee, Location location, boolean safely) {
public TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, Location location, boolean safely) {
if (safely) {
location = this.getSafeLocation(location);
}
if (location != null) {
if (teleportee.teleport(location)) {
return true;
return TeleportResult.SUCCESS;
}
return TeleportResult.FAIL_OTHER;
}
return false;
return TeleportResult.FAIL_UNSAFE;
}
/**
@ -241,7 +252,6 @@ public class SafeTTeleporter {
*
* @param e The entity to spawn
* @param d The MVDestination to take the entity to.
*
* @return A new location to spawn the entity at.
*/
public Location getSafeLocation(Entity e, MVDestination d) {