diff --git a/locales/bsb_en_US.yml b/locales/bsb_en_US.yml index 5eadf24ab..d07c35a5e 100755 --- a/locales/bsb_en_US.yml +++ b/locales/bsb_en_US.yml @@ -71,6 +71,12 @@ help: settings: "display island settings" language: "select language" +sethome: + error: + NumHomes: "Homes can be 1 to [max]" + NotOnIsland: "You must be within your island boundaries to set home!" + homeSet: "Your island home has been set to your current location." + # TODO: These are legacy strings and should be converted to a better format but will do for now acidBottle: "Acid Bottle" acidBucket: "Acid Bucket" @@ -404,6 +410,7 @@ island: subtitle: "by tastybento" subtitlecolor: "blue" teleport: "Teleporting you to your island. (/[label] help for more info)" + teleported: "Teleported to home #[number]" title: "BSkyBlock" titlecolor: "gold" unlimited: "Unlimited" @@ -570,11 +577,7 @@ resetchallenge: errorChallengeDoesNotExist: "Challenge doesn't exist or isn't yet completed" schematics: title: "Select island..." -sethome: - errorNoIsland: "You are not part of an island. Returning you the spawn area!" - errorNotOnIsland: "You must be within your island boundaries to set home!" - errorNumHomes: "Homes can be 1 to [max]" - homeSet: "Your island home has been set to your current location." + settingsReset: done: "Done." inprogress: "Protection settings being reset, please wait..." diff --git a/plugin.yml b/plugin.yml index 302a74609..d7346017a 100755 --- a/plugin.yml +++ b/plugin.yml @@ -31,11 +31,17 @@ permissions: children: bskyblock.island.*: children: + bskyblock.island.create: + description: Allow island command usage + default: true bskyblock.island.home: description: Allow teleporting to player island default: true - bskyblock.island.create: - description: Let the player use the /island command + bskyblock.island.reset: + description: Player can use the island reset or restart command + default: true + bskyblock.island.sethome: + description: Let the player use the sethome command default: true bskyblock.island.info: description: Let the player check their island level diff --git a/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java b/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java index a791fe7d0..8a8d8dabb 100755 --- a/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java @@ -153,7 +153,17 @@ public class IslandCommand extends AbstractCommand { @Override public void execute(CommandSender sender, String[] args) { - getIslands().homeTeleport(player); + if (isPlayer) { + if (args.length == 1 && NumberUtils.isDigits(args[0])) { + int homeValue = Integer.valueOf(args[0]); + int maxHomes = Util.getPermValue(player, Settings.PERMPREFIX + "island.maxhomes", Settings.maxHomes); + if (homeValue > 1 && homeValue <= maxHomes) { + getIslands().homeTeleport(player, homeValue); + return; + } + } + getIslands().homeTeleport(player); + } } @Override @@ -163,9 +173,10 @@ public class IslandCommand extends AbstractCommand { @Override public String[] usage(CommandSender sender) { - // TODO check if multiple homes - if (VaultHelper.hasPerm((Player) sender, "todo")) - return new String[]{"[1-x]", getLocale(sender).get("help.island.go-homes")}; + int maxHomes = Util.getPermValue((Player)sender, Settings.PERMPREFIX + "island.maxhomes", Settings.maxHomes); + if (isPlayer && maxHomes > 1) { + return new String[]{"[1 - " + maxHomes + "]", getLocale(player).get("help.island.go-homes")}; + } return new String[]{null, getLocale(sender).get("help.island.go")}; } }.alias("go").alias("home").alias("h")); @@ -340,12 +351,46 @@ public class IslandCommand extends AbstractCommand { if (!VaultHelper.hasPerm(player, Settings.PERMPREFIX + "island.sethome")) { return new CanUseResp(getLocale(sender).get("general.errors.no-permission")); } - return new CanUseResp(false); + return new CanUseResp(true); } @Override public void execute(CommandSender sender, String[] args) { - + // Check island + if (plugin.getIslands().getIsland(player.getUniqueId()) == null) { + Util.sendMessage(player, ChatColor.RED + plugin.getLocale(playerUUID).get("general.errors.no-island")); + return; + } + if (!plugin.getIslands().playerIsOnIsland(player)) { + Util.sendMessage(player, ChatColor.RED + plugin.getLocale(playerUUID).get("sethome.error.NotOnIsland")); + return; + } + if (args.length == 0) { + // island sethome + plugin.getPlayers().setHomeLocation(playerUUID, player.getLocation()); + Util.sendMessage(player, ChatColor.GREEN + plugin.getLocale(playerUUID).get("sethome.homeSet")); + return; + } else if (args.length == 1) { + // Dynamic home sizes with permissions + int maxHomes = Util.getPermValue(player, Settings.PERMPREFIX + "island.maxhomes", Settings.maxHomes); + if (maxHomes > 1) { + // Check the number given is a number + int number = 0; + try { + number = Integer.valueOf(args[0]); + if (number < 1 || number > maxHomes) { + Util.sendMessage(player, ChatColor.RED + plugin.getLocale(playerUUID).get("sethome.error.NumHomes").replace("[max]",String.valueOf(maxHomes))); + } else { + plugin.getPlayers().setHomeLocation(playerUUID, player.getLocation(), number); + Util.sendMessage(player, ChatColor.GREEN + plugin.getLocale(playerUUID).get("sethome.homeSet")); + } + } catch (Exception e) { + Util.sendMessage(player, ChatColor.RED + plugin.getLocale(playerUUID).get("sethome.error.NumHomes").replace("[max]",String.valueOf(maxHomes))); + } + } else { + Util.sendMessage(player, ChatColor.RED + plugin.getLocale(playerUUID).get("general.errors.no-permission")); + } + } } @Override @@ -355,6 +400,10 @@ public class IslandCommand extends AbstractCommand { @Override public String[] usage(CommandSender sender) { + int maxHomes = Util.getPermValue((Player)sender, Settings.PERMPREFIX + "island.maxhomes", Settings.maxHomes); + if (isPlayer && maxHomes > 1) { + return new String[]{"[1 - " + maxHomes + "]", getLocale(sender).get("help.island.sethome")}; + } return new String[]{null, getLocale(sender).get("help.island.sethome")}; } }.alias("sethome")); @@ -972,7 +1021,7 @@ public class IslandCommand extends AbstractCommand { TeamEvent event = TeamEvent.builder().island(getIslands().getIsland(inviteList.get(playerUUID))).reason(TeamReason.REJECT).involvedPlayer(playerUUID).build(); plugin.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) return; - + // Remove this player from the global invite list inviteList.remove(player.getUniqueId()); Util.sendMessage(player, ChatColor.GREEN + getLocale(playerUUID).get("reject.youHaveRejectedInvitation")); @@ -982,7 +1031,7 @@ public class IslandCommand extends AbstractCommand { Util.sendMessage(Bukkit.getPlayer(inviteList.get(playerUUID)), ChatColor.RED + getLocale(playerUUID).get("reject.nameHasRejectedInvite").replace("[name]", player.getName())); } - + } else { // Someone typed /island reject and had not been invited Util.sendMessage(player, ChatColor.RED + getLocale(playerUUID).get("reject.youHaveNotBeenInvited")); @@ -1040,7 +1089,7 @@ public class IslandCommand extends AbstractCommand { TeamEvent event = TeamEvent.builder().island(getIslands().getIsland(playerUUID)).reason(TeamReason.MAKELEADER).involvedPlayer(targetUUID).build(); plugin.getServer().getPluginManager().callEvent(event); if (event.isCancelled()) return; - + // target is the new leader getIslands().getIsland(playerUUID).setOwner(targetUUID); Util.sendMessage(player, ChatColor.GREEN @@ -1467,5 +1516,5 @@ public class IslandCommand extends AbstractCommand { Schematic schematic = plugin.getSchematics().getSchematic("default"); getIslands().newIsland(player, schematic); } - + } diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/IslandsManager.java b/src/main/java/us/tastybento/bskyblock/database/managers/IslandsManager.java index f417511f6..8f0e5cc6f 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/IslandsManager.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/IslandsManager.java @@ -529,7 +529,7 @@ public class IslandsManager { if (number ==1 ) { Util.sendMessage(player, ChatColor.GREEN + plugin.getLocale(player.getUniqueId()).get("island.teleport").replace("[label]", Settings.ISLANDCOMMAND)); } else { - Util.sendMessage(player, ChatColor.GREEN + "teleported to #" + number); + Util.sendMessage(player, ChatColor.GREEN + plugin.getLocale(player.getUniqueId()).get("island.teleported").replace("[number]", String.valueOf(number))); } // Exit spectator mode if in it if (player.getGameMode().equals(GameMode.SPECTATOR)) { @@ -558,9 +558,8 @@ public class IslandsManager { if (DEBUG) plugin.getLogger().info("DEBUG: Home location " + l); if (l != null) { - // Homes are stored as integers and need correcting to be more central if (isSafeLocation(l)) { - return l.clone().add(new Vector(0.5D,0,0.5D)); + return l; } // To cover slabs, stairs and other half blocks, try one block above Location lPlusOne = l.clone(); @@ -569,7 +568,7 @@ public class IslandsManager { if (isSafeLocation(lPlusOne)) { // Adjust the home location accordingly plugin.getPlayers().setHomeLocation(playerUUID, lPlusOne, number); - return lPlusOne.clone().add(new Vector(0.5D,0,0.5D)); + return lPlusOne; } } } @@ -585,7 +584,7 @@ public class IslandsManager { if (DEBUG) plugin.getLogger().info("DEBUG:island loc is safe"); plugin.getPlayers().setHomeLocation(playerUUID, l, number); - return l.clone().add(new Vector(0.5D,0,0.5D)); + return l; } else { // try team leader's home if (DEBUG) @@ -598,7 +597,7 @@ public class IslandsManager { if (DEBUG) plugin.getLogger().info("DEBUG: team leader's home is safe"); plugin.getPlayers().setHomeLocation(playerUUID, tlh, number); - return tlh.clone().add(new Vector(0.5D,0,0.5D)); + return tlh; } } } diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java b/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java index 2f0a87d78..fc8e7aa6b 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java @@ -252,6 +252,7 @@ public class PlayersManager{ public void setHomeLocation(UUID playerUUID, Location location, int number) { addPlayer(playerUUID); playerCache.get(playerUUID).setHomeLocation(location,number); + this.save(true); } /** @@ -262,6 +263,7 @@ public class PlayersManager{ public void setHomeLocation(UUID playerUUID, Location location) { addPlayer(playerUUID); playerCache.get(playerUUID).setHomeLocation(location,1); + this.save(true); } /** diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/Players.java b/src/main/java/us/tastybento/bskyblock/database/objects/Players.java index e3e5cd2f7..4b61dcf2f 100755 --- a/src/main/java/us/tastybento/bskyblock/database/objects/Players.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/Players.java @@ -62,7 +62,7 @@ public class Players extends DataObject { */ public Location getHomeLocation(int number) { /* - * Bukkit.getLogger().info("DEBUG: getting home location " + number); + Bukkit.getLogger().info("DEBUG: getting home location " + number); Bukkit.getLogger().info("DEBUG: " + homeLocations.toString()); for (Entry en : homeLocations.entrySet()) { @@ -169,8 +169,7 @@ public class Players extends DataObject { if (location == null) { homeLocations.clear(); } else { - // Make the location x,y,z integer, but keep the yaw and pitch - homeLocations.put(number, new Location(location.getWorld(),location.getBlockX(),location.getBlockY(),location.getBlockZ(),location.getYaw(), location.getPitch())); + homeLocations.put(number, location); } } diff --git a/src/main/java/us/tastybento/bskyblock/util/Util.java b/src/main/java/us/tastybento/bskyblock/util/Util.java index 52b7b0334..d97204f6c 100755 --- a/src/main/java/us/tastybento/bskyblock/util/Util.java +++ b/src/main/java/us/tastybento/bskyblock/util/Util.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.apache.commons.lang.math.NumberUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; @@ -24,6 +25,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.material.MaterialData; import org.bukkit.material.SimpleAttachableMaterialData; import org.bukkit.material.TrapDoor; +import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; import us.tastybento.bskyblock.BSkyBlock; @@ -463,4 +465,37 @@ public class Util { return true; } + /** + * Get the maximum value of a numerical perm setting + * @param player - the player to check + * @param perm - the start of the perm, e.g., bskyblock.maxhomes + * @param permValue - the default value - the result may be higher or lower than this + * @return + */ + public static int getPermValue(Player player, String perm, int permValue) { + for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) { + if (perms.getPermission().startsWith(perm + ".")) { + // Get the max value should there be more than one + if (perms.getPermission().contains(perm + ".*")) { + return permValue; + } else { + String[] spl = perms.getPermission().split(perm + "."); + if (spl.length > 1) { + if (!NumberUtils.isDigits(spl[1])) { + plugin.getLogger().severe("Player " + player.getName() + " has permission: " + perms.getPermission() + " <-- the last part MUST be a number! Ignoring..."); + + } else { + permValue = Math.max(permValue, Integer.valueOf(spl[1])); + } + } + } + } + // Do some sanity checking + if (permValue < 1) { + permValue = 1; + } + } + return permValue; + } + }