diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java index c41ba265..2a93d9e0 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java @@ -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 teleportQueue = new HashMap(); + + /** + * 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() { diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/TeleportCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/TeleportCommand.java index f2ff6a44..fb0b888d 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/TeleportCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/TeleportCommand.java @@ -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}; diff --git a/src/main/java/com/onarandombox/MultiverseCore/enums/TeleportResult.java b/src/main/java/com/onarandombox/MultiverseCore/enums/TeleportResult.java new file mode 100644 index 00000000..4359c1cd --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/enums/TeleportResult.java @@ -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 +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java index 6fa47bfc..ab20d813 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java +++ b/src/main/java/com/onarandombox/MultiverseCore/listeners/MVPlayerListener.java @@ -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. - *

- * 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; diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java b/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java index 5434e163..2adbb08d 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/PermissionTools.java @@ -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. + *

+ * 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; + } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/SafeTTeleporter.java b/src/main/java/com/onarandombox/MultiverseCore/utils/SafeTTeleporter.java index a622b00c..5fa5696e 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/SafeTTeleporter.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/SafeTTeleporter.java @@ -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) {