From 67e967a2643a1097bfde4c35d6b0f8b20ebee5fb Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sat, 15 Jan 2022 14:49:46 +0100 Subject: [PATCH] Implements world-specific permissions Accounts for world specifiers where necessary Makes the reload command work? Stores the world as part of temporary permissions Fixes sign break protection Allows sign interaction with both right- and left-click Fixes temporary permissions sometimes colliding Cleans the main class a bit Adds a "star" permission Adds missing check for the use permission --- .../permissionsigns/PermissionSigns.java | 119 ++++++++++-------- .../command/CreateCommand.java | 13 ++ .../command/ReloadCommand.java | 5 +- .../container/TemporaryPermission.java | 19 ++- .../formatting/TranslatableMessage.java | 10 ++ .../listener/BlockListener.java | 48 +++++++ .../listener/PlayerListener.java | 2 +- .../listener/SignListener.java | 51 ++++---- .../manager/PermissionManager.java | 67 ++++++++-- src/main/resources/plugin.yml | 6 + src/main/resources/strings.yml | 2 + 11 files changed, 243 insertions(+), 99 deletions(-) create mode 100644 src/main/java/net/knarcraft/permissionsigns/listener/BlockListener.java diff --git a/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java b/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java index 637f6e4..e9d9890 100644 --- a/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java +++ b/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java @@ -5,6 +5,7 @@ import net.knarcraft.permissionsigns.command.PermissionSignsTabCompleter; import net.knarcraft.permissionsigns.container.PermissionSign; import net.knarcraft.permissionsigns.container.SignCreationRequest; import net.knarcraft.permissionsigns.formatting.Translator; +import net.knarcraft.permissionsigns.listener.BlockListener; import net.knarcraft.permissionsigns.listener.PlayerListener; import net.knarcraft.permissionsigns.listener.SignListener; import net.knarcraft.permissionsigns.manager.EconomyManager; @@ -16,8 +17,10 @@ import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.permission.Permission; import org.bukkit.Bukkit; import org.bukkit.command.PluginCommand; +import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginDescriptionFile; +import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.ServicesManager; import org.bukkit.plugin.java.JavaPlugin; @@ -35,6 +38,7 @@ public final class PermissionSigns extends JavaPlugin { private static final Queue signCreationRequests = new PriorityQueue<>(); private static String pluginVersion; private static PermissionSigns instance; + private static boolean perWorldPermissions; /** * Instantiates the permission signs class @@ -104,57 +108,74 @@ public final class PermissionSigns extends JavaPlugin { } } + /** + * Checks whether permissions should always be set for the world the sign belongs to + * + * @return

Whether permissions should be set for the current world

+ */ + public static boolean usePerWorldPermissions() { + return perWorldPermissions; + } + + @Override + public void reloadConfig() { + super.reloadConfig(); + FileConfiguration config = this.getConfig(); + String language = config.getString("language"); + perWorldPermissions = config.getBoolean("perWorldPermissions"); + Translator.loadLanguages(language); + } + @Override public void onEnable() { PluginDescriptionFile pluginDescriptionFile = this.getDescription(); pluginVersion = pluginDescriptionFile.getVersion(); - - // Plugin startup logic - - //TODO: Add commands create, add and remove - // /ps create, /ps add, and /ps remove - // create initiates the creation, and add adds properties - // On creation, write "Creating PermissionSign", first asked for the name - // Then asked for the permission. Allow several comma-separated permissions - // Then asked for duration - // Then asked for cost - // Say "Sign completed! Right-click a sign to enable it." - // Then asked to right-click a sign to create the new permission-sign - // Perhaps ignore the old ways, and just have one command for creating permission signs: - // /ps create to create a new permission-sign - // Right-click a sign to create it - // /ps cancel to cancel the sing creation - // Break the sign to remove it, check for permission first - // The name thing is probably useless, as the sign's location works as its id - - //TODO: Display and register the permission-sign - // Start with [PermSign] in red - // Next line is the permission node. Last child, upper-cased - // Third line is n seconds - // Last line is the cost, including the unit - // Need to store any temporary permissions in a list/queue and have a thread which searches for expired - // permissions to de-register them - - //Not persistent, but might work as things shouldn't persist anyway - //player.addAttachment(this, "essentials.fly", true, seconds * 20); - //Vault probably has some API to add permissions - - //TODO: Store all temporary permissions with the time they were assigned and the time they should be granted. - // Set the permissions as permanent and remove when the timer expires? Might cause problems for players that has - // the permission inherited, unless we make sure the player does not have the permission before - // Alternatively: Manage all permissions ourselves, for temporary permissions, and add permission attachments - // on startup I guess. - - //TODO: Start sign creation when the create command is used and save the data until an empty sign is right-clicked - - //TODO: Check for existence of old permission signs when clicked and register them as new permission signs. If - // it has the permissionSigns header and a name matching contents in signs.yml, add it. - - //TODO: Implement config file - //TODO: Account for per-world permissions if enabled (perhaps allow world specification as world:permission?) //TODO: Allow for custom language files. Perhaps just look for strings.yml in the folder + FileConfiguration config = this.getConfig(); + config.options().copyDefaults(true); + this.saveDefaultConfig(); + + String language = config.getString("language"); + perWorldPermissions = config.getBoolean("perWorldPermissions"); + //Check if vault is loaded + setupVault(); + + registerListeners(); + + Translator.loadLanguages(language); + registerCommands(); + + runThreads(); + + SignManager.loadSigns(); + PermissionManager.loadTemporaryPermissions(); + } + + /** + * Starts all separate threads for executing tasks + */ + private void runThreads() { + BukkitScheduler scheduler = Bukkit.getScheduler(); + scheduler.runTaskTimer(this, new SignCreationRequestTimeoutThread(signCreationRequests), 0L, 100L); + scheduler.runTaskTimer(this, new PermissionTimeoutThread(), 0L, 25L); + } + + /** + * Registers all necessary listeners + */ + private void registerListeners() { + PluginManager pluginManager = getServer().getPluginManager(); + pluginManager.registerEvents(new SignListener(), this); + pluginManager.registerEvents(new PlayerListener(), this); + pluginManager.registerEvents(new BlockListener(), this); + } + + /** + * Sets up Vault by getting plugins from their providers + */ + private void setupVault() { ServicesManager servicesManager = this.getServer().getServicesManager(); RegisteredServiceProvider permissionProvider = servicesManager.getRegistration(Permission.class); RegisteredServiceProvider economyProvider = servicesManager.getRegistration(Economy.class); @@ -164,16 +185,6 @@ public final class PermissionSigns extends JavaPlugin { } else { throw new IllegalStateException("[PermissionSigns] Error: Vault could not be loaded"); } - getServer().getPluginManager().registerEvents(new SignListener(), this); - getServer().getPluginManager().registerEvents(new PlayerListener(), this); - - Translator.loadLanguages("en"); - registerCommands(); - BukkitScheduler scheduler = Bukkit.getScheduler(); - scheduler.runTaskTimer(this, new SignCreationRequestTimeoutThread(signCreationRequests), 0L, 100L); - scheduler.runTaskTimer(this, new PermissionTimeoutThread(), 0L, 25L); - SignManager.loadSigns(); - PermissionManager.loadTemporaryPermissions(); } /** diff --git a/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java index 0adb9b2..48cf117 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java @@ -4,6 +4,7 @@ import net.knarcraft.permissionsigns.PermissionSigns; import net.knarcraft.permissionsigns.container.PermissionSign; import net.knarcraft.permissionsigns.formatting.StringFormatter; import net.knarcraft.permissionsigns.formatting.TranslatableMessage; +import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -57,6 +58,18 @@ public class CreateCommand implements CommandExecutor { private PermissionSign parseSign(@NotNull CommandSender sender, @NotNull String[] args) { String name = args[0]; String[] permissions = args[1].split(","); + for (String permission : permissions) { + if (permission.contains(":")) { + //TODO: Might need to account for world names with spaces in the name + String world = permission.split(":")[0]; + if (!world.equalsIgnoreCase("all") && Bukkit.getWorld(world) == null) { + sender.sendMessage(StringFormatter.replacePlaceholder(StringFormatter.getTranslatedErrorMessage( + TranslatableMessage.PERMISSION_WORLD_INVALID), "{world}", world)); + return null; + } + } + } + double cost = 0; int duration = 0; if (args.length > 2) { diff --git a/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java index 34c677d..baf0461 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java @@ -1,7 +1,9 @@ package net.knarcraft.permissionsigns.command; +import net.knarcraft.permissionsigns.PermissionSigns; import net.knarcraft.permissionsigns.formatting.StringFormatter; import net.knarcraft.permissionsigns.formatting.TranslatableMessage; +import net.knarcraft.permissionsigns.manager.PermissionManager; import net.knarcraft.permissionsigns.manager.SignManager; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -16,8 +18,9 @@ public class ReloadCommand implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (sender.hasPermission("permissionsigns.admin.reload")) { - //TODO: Perform a reload from disk SignManager.loadSigns(); + PermissionManager.loadTemporaryPermissions(); + PermissionSigns.getInstance().reloadConfig(); } else { sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COMMAND_PERMISSION_DENIED)); } diff --git a/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java b/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java index 2b854ac..5fef274 100644 --- a/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java +++ b/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java @@ -13,6 +13,7 @@ public class TemporaryPermission implements Comparable { private final OfflinePlayer grantedPlayer; private final String permissionNode; private final int duration; + private final String world; /** * Instantiates a new temporary permission @@ -20,14 +21,14 @@ public class TemporaryPermission implements Comparable { * @param player

The player the temporary permission was assigned to

* @param permissionNode

The permission node granted to the player

* @param duration

The duration, in seconds, the temporary permission should last

+ * @param world

The world the permission should be added to

*/ - public TemporaryPermission(Player player, String permissionNode, int duration) { + public TemporaryPermission(Player player, String permissionNode, int duration, String world) { grantedTime = System.currentTimeMillis(); this.grantedPlayer = player; this.permissionNode = permissionNode; this.duration = duration; - //TODO: Need to account for world. Perhaps have a config option to choose between setting permissions for all - // worlds, or just the world the sign and player is in + this.world = world; } /** @@ -37,12 +38,14 @@ public class TemporaryPermission implements Comparable { * @param permissionNode

The permission node granted to the player

* @param grantedTime

The time this temporary permission was granted

* @param duration

The duration, in seconds, the temporary permission should last

+ * @param world

The world the permission should be added to

*/ - public TemporaryPermission(OfflinePlayer player, String permissionNode, long grantedTime, int duration) { + public TemporaryPermission(OfflinePlayer player, String permissionNode, long grantedTime, int duration, String world) { this.grantedPlayer = player; this.permissionNode = permissionNode; this.grantedTime = grantedTime; this.duration = duration; + this.world = world; } /** @@ -81,6 +84,14 @@ public class TemporaryPermission implements Comparable { return permissionNode; } + /** + * Gets the world the permission node should be added to + * + * @return

The world the permission node should be added to

+ */ + public String getWorld() { + return world; + } @Override public int compareTo(@NotNull TemporaryPermission other) { diff --git a/src/main/java/net/knarcraft/permissionsigns/formatting/TranslatableMessage.java b/src/main/java/net/knarcraft/permissionsigns/formatting/TranslatableMessage.java index 3bbff5e..19c4228 100644 --- a/src/main/java/net/knarcraft/permissionsigns/formatting/TranslatableMessage.java +++ b/src/main/java/net/knarcraft/permissionsigns/formatting/TranslatableMessage.java @@ -90,6 +90,16 @@ public enum TranslatableMessage { */ PERMISSIONS_GRANTED, + /** + * The message to display if a player has specified an invalid world to set a permission for + */ + PERMISSION_WORLD_INVALID, + + /** + * The message to display if a player is missing the permission required for interacting with permission signs + */ + INTERACT_PERMISSION_MISSING, + /** * The message to display when a permission sign has been successfully created */ diff --git a/src/main/java/net/knarcraft/permissionsigns/listener/BlockListener.java b/src/main/java/net/knarcraft/permissionsigns/listener/BlockListener.java new file mode 100644 index 0000000..f598caa --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/listener/BlockListener.java @@ -0,0 +1,48 @@ +package net.knarcraft.permissionsigns.listener; + +import net.knarcraft.permissionsigns.formatting.StringFormatter; +import net.knarcraft.permissionsigns.formatting.TranslatableMessage; +import net.knarcraft.permissionsigns.manager.SignManager; +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.Block; +import org.bukkit.block.Sign; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; + +public class BlockListener implements Listener { + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + Block block = event.getBlock(); + Player player = event.getPlayer(); + + if (event.isCancelled()) { + return; + } + + Material material = block.getBlockData().getMaterial(); + if (!Tag.SIGNS.isTagged(material) && !Tag.WALL_SIGNS.isTagged(material)) { + return; + } + + Sign sign = (Sign) block.getState(); + boolean registered = SignManager.getSign(sign.getLocation()) != null; + if (!registered) { + return; + } + if (!player.hasPermission("permissionsigns.admin.create")) { + event.setCancelled(true); + player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.PERMISSION_SIGN_DESTROY_DENY)); + } else { + SignManager.removeSign(sign.getLocation()); + player.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.PERMISSION_SIGN_REMOVED)); + } + + //TODO: Need to protect against other things that might damage the sign, such as explosions + //TODO: Only allow the sign to be broken if shift-clicking? + } + +} diff --git a/src/main/java/net/knarcraft/permissionsigns/listener/PlayerListener.java b/src/main/java/net/knarcraft/permissionsigns/listener/PlayerListener.java index fc22c28..19d177a 100644 --- a/src/main/java/net/knarcraft/permissionsigns/listener/PlayerListener.java +++ b/src/main/java/net/knarcraft/permissionsigns/listener/PlayerListener.java @@ -20,7 +20,7 @@ public class PlayerListener implements Listener { Queue temporaryPermissions = new PriorityQueue<>(PermissionManager.getTemporaryPermissions()); temporaryPermissions.removeIf((item) -> !item.getGrantedPlayer().getUniqueId().equals(event.getPlayer().getUniqueId())); temporaryPermissions.forEach((item) -> PermissionManager.grantTemporaryPermission(event.getPlayer(), - item.getPermissionNode())); + item.getPermissionNode(), item.getWorld())); } } diff --git a/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java b/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java index 86d0f57..b555627 100644 --- a/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java +++ b/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java @@ -16,7 +16,6 @@ import org.bukkit.block.Sign; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import java.util.Arrays; @@ -46,32 +45,7 @@ public class SignListener implements Listener { } Sign sign = (Sign) block.getState(); - if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - handleSignRightClick(sign, player); - } else if (event.getAction() == Action.LEFT_CLICK_BLOCK) { - handleSignLeftClick(sign, player, event); - } - } - - /** - * Handles the left click of a sign that might be a permission sign - * - * @param sign

The clicked sign

- * @param player

The player that clicked the sign

- * @param event

The triggered interaction event

- */ - private void handleSignLeftClick(Sign sign, Player player, PlayerInteractEvent event) { - boolean registered = SignManager.getSign(sign.getLocation()) != null; - if (!registered) { - return; - } - if (!player.hasPermission("permissionsigns.admin")) { - event.setCancelled(true); - player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.PERMISSION_SIGN_DESTROY_DENY)); - } else { - SignManager.removeSign(sign.getLocation()); - player.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.PERMISSION_SIGN_REMOVED)); - } + handleSignClick(sign, player); } /** @@ -80,13 +54,18 @@ public class SignListener implements Listener { * @param sign

The clicked sign

* @param player

The player that clicked the sign

*/ - private void handleSignRightClick(Sign sign, Player player) { + private void handleSignClick(Sign sign, Player player) { //Check if the sign is a registered permission sign PermissionSign permissionSign = SignManager.getSign(sign.getLocation()); if (permissionSign != null) { + if (!player.hasPermission("permissionsigns.use")) { + player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.INTERACT_PERMISSION_MISSING)); + return; + } handlePermissionSignInteract(permissionSign, player); return; } + //TODO: Display information about granted permissions when shift-clicking? //Check if the player has a creation request that can be fulfilled SignCreationRequest request = PermissionSigns.getSignCreationRequest(player.getUniqueId()); @@ -105,7 +84,12 @@ public class SignListener implements Listener { //Don't allow players to pay for permissions they already own boolean hasAllPermissions = true; for (String permissionNode : permissionSign.getPermissionNodes()) { - if (!player.hasPermission(permissionNode)) { + if (permissionNode.contains(":")) { + String[] permissionParts = permissionNode.split(":"); + if (!PermissionManager.hasPermission(player, permissionParts[1], permissionParts[0])) { + hasAllPermissions = false; + } + } else if (!player.hasPermission(permissionNode)) { hasAllPermissions = false; } } @@ -132,7 +116,14 @@ public class SignListener implements Listener { StringBuilder permissionsBuilder = new StringBuilder(); for (String permissionNode : permissionSign.getPermissionNodes()) { //Only grant the permission if not already owned - if (!player.hasPermission(permissionNode)) { + boolean hasPermission; + if (permissionNode.contains(":")) { + String[] permissionParts = permissionNode.split(":"); + hasPermission = PermissionManager.hasPermission(player, permissionParts[1], permissionParts[0]); + } else { + hasPermission = player.hasPermission(permissionNode); + } + if (!hasPermission) { permissionsBuilder.append(permissionNode); permissionsBuilder.append(", "); if (permissionSign.getDuration() == 0) { diff --git a/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java b/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java index d980f42..3cb4429 100644 --- a/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java +++ b/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java @@ -12,6 +12,7 @@ import org.bukkit.entity.Player; import java.io.File; import java.io.IOException; import java.util.Queue; +import java.util.Random; import java.util.UUID; import java.util.concurrent.PriorityBlockingQueue; import java.util.logging.Level; @@ -50,8 +51,13 @@ public class PermissionManager { * @param permissionNode

The permission node to grant to the player

*/ public static void addPermission(Player player, String permissionNode) { - //TODO: Account for world when granting permissions, if wanted - permission.playerAdd(null, player, permissionNode); + //Allow world:permission syntax + if (permissionNode.contains(":")) { + grantWorldPermission(player, permissionNode, false); + } else { + boolean perWorldPermissions = PermissionSigns.usePerWorldPermissions(); + permission.playerAdd(perWorldPermissions ? player.getWorld().getName() : null, player, permissionNode); + } } /** @@ -59,9 +65,36 @@ public class PermissionManager { * * @param player

The player to add the temporary permission to

* @param permissionNode

The permission node to grant

+ * @param worldName

The world to add the permission node to

*/ - public static void grantTemporaryPermission(Player player, String permissionNode) { - permission.playerAddTransient(null, player, permissionNode); + public static void grantTemporaryPermission(Player player, String permissionNode, String worldName) { + //Allow world:permission syntax + if (permissionNode.contains(":")) { + grantWorldPermission(player, permissionNode, true); + } else { + boolean perWorldPermissions = PermissionSigns.usePerWorldPermissions(); + permission.playerAddTransient(perWorldPermissions ? worldName : null, player, permissionNode); + } + } + + /** + * Grants a permission for the world specified in the permission node + * + * @param player

The player to grant the permission node to

+ * @param permissionNode

The permission node to grant

+ * @param temporary

Whether the permission node should be set temporarily

+ */ + private static void grantWorldPermission(Player player, String permissionNode, boolean temporary) { + String[] permissionParts = permissionNode.split(":"); + String world = permissionParts[0]; + if (world.equalsIgnoreCase("all")) { + world = null; + } + if (temporary) { + permission.playerAddTransient(world, player, permissionParts[1]); + } else { + permission.playerAdd(world, player, permissionParts[1]); + } } /** @@ -72,8 +105,9 @@ public class PermissionManager { * @param duration

The duration for which the player should keep the given permission

*/ public static void addTemporaryPermission(Player player, String permissionNode, int duration) { - grantTemporaryPermission(player, permissionNode); - temporaryPermissions.add(new TemporaryPermission(player, permissionNode, duration)); + String world = player.getWorld().getName(); + grantTemporaryPermission(player, permissionNode, world); + temporaryPermissions.add(new TemporaryPermission(player, permissionNode, duration, world)); try { saveTemporaryPermissions(); } catch (IOException e) { @@ -95,6 +129,18 @@ public class PermissionManager { } } + /** + * Checks whether the given player has the given permission + * + * @param player

The player to check

+ * @param permissionNode

The permission node to check for

+ * @param world

The world to check for the permission

+ * @return

True if the player has the permission

+ */ + public static boolean hasPermission(Player player, String permissionNode, String world) { + return permission.playerHas(world, player, permissionNode); + } + /** * Saves all temporary permissions to a file * @@ -103,11 +149,14 @@ public class PermissionManager { public static void saveTemporaryPermissions() throws IOException { YamlConfiguration configuration = YamlConfiguration.loadConfiguration(permissionsFile); ConfigurationSection permissionSection = configuration.createSection("permissions"); + Random random = new Random(); temporaryPermissions.forEach((item) -> { - String key = item.getGrantedPlayer().getUniqueId() + "," + item.getGrantedTime(); + //A random long is added to prevent any conflicts + String key = item.getGrantedPlayer().getUniqueId() + "," + item.getGrantedTime() + "," + random.nextLong(); permissionSection.set(key + ".permissionNode", item.getPermissionNode()); permissionSection.set(key + ".duration", item.getGrantedDuration()); + permissionSection.set(key + ".world", item.getWorld()); }); configuration.save(permissionsFile); } @@ -131,13 +180,13 @@ public class PermissionManager { String permissionNode = permissionSection.getString(key + ".permissionNode"); long granted = Long.parseLong(identifierParts[1]); int duration = permissionSection.getInt(key + ".duration", 1); + String world = permissionSection.getString(key + ".world", null); //Skip any expired temporary permissions if (currentTime > granted + (1000L * duration)) { continue; } - //TODO: Need to wait for the player to join the server before allocating transient permissions - temporaryPermissions.add(new TemporaryPermission(player, permissionNode, granted, duration)); + temporaryPermissions.add(new TemporaryPermission(player, permissionNode, granted, duration, world)); } try { saveTemporaryPermissions(); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 4c5ac1a..f42d657 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -18,6 +18,12 @@ commands: description: Used for all permission sign commands usage: / - Used for all permission sign commands permissions: + permissionsigns.*: + description: Grants all PermissionSigns permissions + default: false + children: + permissionsigns.use: true + permissionsigns.admin: true permissionsigns.use: description: Allows players to use the permission signs default: true diff --git a/src/main/resources/strings.yml b/src/main/resources/strings.yml index 7e22542..732cbff 100644 --- a/src/main/resources/strings.yml +++ b/src/main/resources/strings.yml @@ -16,4 +16,6 @@ en: ALREADY_HAS_PERMISSIONS: "&7You already have all permissions given by this permission sign" PERMISSIONS_GRANTED: "&7You have been granted the following permission nodes: {permissions} for {time}" PERMISSION_SIGN_CREATED: "&7Permission sign successfully created!" + PERMISSION_WORLD_INVALID: "&7The world {world} is not a valid world name on this server!" + INTERACT_PERMISSION_MISSING: "&7You do not have the necessary permissions required to use permission signs" CREATION_REQUEST_CANCELLED: "&7Your last permission sign creation request has been cancelled" \ No newline at end of file