diff --git a/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java b/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java index a8d33f4..e74ad06 100644 --- a/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java +++ b/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java @@ -9,6 +9,7 @@ import net.knarcraft.permissionsigns.listener.SignListener; import net.knarcraft.permissionsigns.manager.EconomyManager; import net.knarcraft.permissionsigns.manager.PermissionManager; import net.knarcraft.permissionsigns.manager.SignManager; +import net.knarcraft.permissionsigns.thread.PermissionTimeoutThread; import net.knarcraft.permissionsigns.thread.SignCreationRequestTimeoutThread; import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.permission.Permission; @@ -164,6 +165,7 @@ public final class PermissionSigns extends JavaPlugin { registerCommands(); BukkitScheduler scheduler = Bukkit.getScheduler(); scheduler.runTaskTimer(this, new SignCreationRequestTimeoutThread(signCreationRequests), 0L, 100L); + scheduler.runTaskTimer(this, new PermissionTimeoutThread(), 0L, 25L); SignManager.loadSigns(); } diff --git a/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java b/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java index d123654..a24621f 100644 --- a/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java +++ b/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java @@ -123,7 +123,8 @@ public class PermissionSign { */ public String[] getSignLines() { String[] lines = new String[4]; - lines[0] = ChatColor.DARK_RED + Translator.getTranslatedMessage(TranslatableMessage.PREFIX); + lines[0] = ChatColor.translateAlternateColorCodes('&', Translator.getTranslatedMessage( + TranslatableMessage.SIGN_PREFIX)); lines[1] = getName(); lines[2] = getDurationString(); lines[3] = getCostString(); diff --git a/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java b/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java index f8a8c7f..b1ecb22 100644 --- a/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java +++ b/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java @@ -1,14 +1,15 @@ package net.knarcraft.permissionsigns.container; -import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; /** * A temporary permission that needs to be removed after a given duration */ -public class TemporaryPermission { +public class TemporaryPermission implements Comparable { private final long grantedTime; - private final OfflinePlayer grantedPlayer; + private final Player grantedPlayer; private final String permissionNode; private final int duration; @@ -19,7 +20,7 @@ public class TemporaryPermission { * @param permissionNode

The permission node granted to the player

* @param duration

The duration, in seconds, the temporary permission should last

*/ - public TemporaryPermission(OfflinePlayer player, String permissionNode, int duration) { + public TemporaryPermission(Player player, String permissionNode, int duration) { grantedTime = System.currentTimeMillis(); this.grantedPlayer = player; this.permissionNode = permissionNode; @@ -36,7 +37,7 @@ public class TemporaryPermission { * @param grantedTime

The time this temporary permission was granted

* @param duration

The duration, in seconds, the temporary permission should last

*/ - public TemporaryPermission(OfflinePlayer player, String permissionNode, long grantedTime, int duration) { + public TemporaryPermission(Player player, String permissionNode, long grantedTime, int duration) { this.grantedPlayer = player; this.permissionNode = permissionNode; this.grantedTime = grantedTime; @@ -66,7 +67,7 @@ public class TemporaryPermission { * * @return

The player this temporary permission was granted to

*/ - public OfflinePlayer getGrantedPlayer() { + public Player getGrantedPlayer() { return grantedPlayer; } @@ -79,4 +80,10 @@ public class TemporaryPermission { return permissionNode; } + + @Override + public int compareTo(@NotNull TemporaryPermission other) { + return (int) (grantedTime + (1000 * duration) - (grantedTime + (1000 * other.duration))); + } + } diff --git a/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java b/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java index 3158a85..50abac3 100644 --- a/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java +++ b/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java @@ -2,10 +2,10 @@ package net.knarcraft.permissionsigns.manager; import net.knarcraft.permissionsigns.container.TemporaryPermission; import net.milkbowl.vault.permission.Permission; -import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; -import java.util.List; +import java.util.Queue; +import java.util.concurrent.PriorityBlockingQueue; /** * A manager that performs all Permission tasks @@ -13,7 +13,7 @@ import java.util.List; public class PermissionManager { private static Permission permission; - private static List temporaryPermissions; + private static final Queue temporaryPermissions = new PriorityBlockingQueue<>(); /** * Initializes the permission manager @@ -24,6 +24,15 @@ public class PermissionManager { PermissionManager.permission = permission; } + /** + * Gets the registered temporary permissions + * + * @return

The registered temporary permissions

+ */ + public static Queue getTemporaryPermissions() { + return temporaryPermissions; + } + /** * Grants a permanent permission to a player * @@ -31,7 +40,8 @@ public class PermissionManager { * @param permissionNode

The permission node to grant to the player

*/ public static void addPermission(Player player, String permissionNode) { - permission.playerAdd(player, permissionNode); + //TODO: Account for world when granting permissions, if wanted + permission.playerAdd(null, player, permissionNode); } /** @@ -41,8 +51,8 @@ public class PermissionManager { * @param permissionNode

The temporary permission to grant

* @param duration

The duration for which the player should keep the given permission

*/ - public static void addTemporaryPermission(OfflinePlayer player, String permissionNode, int duration) { - permission.playerAddTransient(player, permissionNode); + public static void addTemporaryPermission(Player player, String permissionNode, int duration) { + permission.playerAddTransient(null, player, permissionNode); temporaryPermissions.add(new TemporaryPermission(player, permissionNode, duration)); //TODO: Create and store a temporary permission // Check all stored temporary permissions on startup: @@ -59,8 +69,10 @@ public class PermissionManager { * @param player

The player to remove the permission from

* @param permissionNode

The permission node to remove from the player

*/ - public static void removeTemporaryPermission(OfflinePlayer player, String permissionNode) { - permission.playerRemoveTransient(player, permissionNode); + public static void removeTemporaryPermission(Player player, String permissionNode) { + if (player.hasPermission(permissionNode)) { + permission.playerRemoveTransient(null, player, permissionNode); + } } } diff --git a/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java b/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java index 89356b9..fd13c45 100644 --- a/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java +++ b/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java @@ -4,6 +4,9 @@ import net.knarcraft.permissionsigns.PermissionSigns; import net.knarcraft.permissionsigns.container.PermissionSign; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.Sign; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; @@ -11,6 +14,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -96,8 +100,33 @@ public class SignManager { e.getMessage()); } } - PermissionSigns.getInstance().getLogger().log(Level.INFO, "Permission signs finished loading"); - //TODO: Might want to re-draw signs here in case any signs have changed + + //Re-draw all signs in a separate thread + redrawSigns(); + } + + /** + * Re-draws all loaded signs in case something changed + */ + private static void redrawSigns() { + Bukkit.getScheduler().scheduleSyncDelayedTask(PermissionSigns.getInstance(), () -> { + for (Location key : managedSigns.keySet()) { + PermissionSign permissionSign = managedSigns.get(key); + Block signBlock = key.getBlock(); + BlockState state = signBlock.getState(); + if (!(state instanceof Sign sign)) { + continue; + } + String[] newLines = permissionSign.getSignLines(); + if (Arrays.equals(sign.getLines(), newLines)) { + continue; + } + for (int i = 0; i < 4; i++) { + sign.setLine(i, newLines[i]); + } + sign.update(); + } + }); } /** diff --git a/src/main/java/net/knarcraft/permissionsigns/thread/PermissionTimeoutThread.java b/src/main/java/net/knarcraft/permissionsigns/thread/PermissionTimeoutThread.java new file mode 100644 index 0000000..a36721c --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/thread/PermissionTimeoutThread.java @@ -0,0 +1,34 @@ +package net.knarcraft.permissionsigns.thread; + +import net.knarcraft.permissionsigns.container.TemporaryPermission; +import net.knarcraft.permissionsigns.manager.PermissionManager; + +import java.util.Queue; + +/** + * The permission timeout thread is responsible for removing temporary permissions as they expire + */ +public class PermissionTimeoutThread implements Runnable { + + @Override + public void run() { + long currentTime = System.currentTimeMillis(); + Queue temporaryPermissions = PermissionManager.getTemporaryPermissions(); + TemporaryPermission topPermission = temporaryPermissions.peek(); + + if (topPermission == null) { + return; + } + + while (currentTime > topPermission.getGrantedTime() + (1000L * topPermission.getGrantedDuration())) { + temporaryPermissions.poll(); + PermissionManager.removeTemporaryPermission(topPermission.getGrantedPlayer(), topPermission.getPermissionNode()); + + topPermission = temporaryPermissions.peek(); + if (topPermission == null) { + return; + } + } + } + +}