Makes temporary permissions expire as intended

Fixes the sign prefix used on the first line
Makes TemporaryPermission comparable
Replaces some usage of OfflinePlayer with Player
Only removes a permissions if owned by the player
Adds a new thread that looks for expired temporary permissions
This commit is contained in:
Kristian Knarvik 2022-01-14 17:53:16 +01:00
parent 252d3ed88a
commit 339aedf2e9
6 changed files with 102 additions and 17 deletions

View File

@ -9,6 +9,7 @@ import net.knarcraft.permissionsigns.listener.SignListener;
import net.knarcraft.permissionsigns.manager.EconomyManager; import net.knarcraft.permissionsigns.manager.EconomyManager;
import net.knarcraft.permissionsigns.manager.PermissionManager; import net.knarcraft.permissionsigns.manager.PermissionManager;
import net.knarcraft.permissionsigns.manager.SignManager; import net.knarcraft.permissionsigns.manager.SignManager;
import net.knarcraft.permissionsigns.thread.PermissionTimeoutThread;
import net.knarcraft.permissionsigns.thread.SignCreationRequestTimeoutThread; import net.knarcraft.permissionsigns.thread.SignCreationRequestTimeoutThread;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
@ -164,6 +165,7 @@ public final class PermissionSigns extends JavaPlugin {
registerCommands(); registerCommands();
BukkitScheduler scheduler = Bukkit.getScheduler(); BukkitScheduler scheduler = Bukkit.getScheduler();
scheduler.runTaskTimer(this, new SignCreationRequestTimeoutThread(signCreationRequests), 0L, 100L); scheduler.runTaskTimer(this, new SignCreationRequestTimeoutThread(signCreationRequests), 0L, 100L);
scheduler.runTaskTimer(this, new PermissionTimeoutThread(), 0L, 25L);
SignManager.loadSigns(); SignManager.loadSigns();
} }

View File

@ -123,7 +123,8 @@ public class PermissionSign {
*/ */
public String[] getSignLines() { public String[] getSignLines() {
String[] lines = new String[4]; 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[1] = getName();
lines[2] = getDurationString(); lines[2] = getDurationString();
lines[3] = getCostString(); lines[3] = getCostString();

View File

@ -1,14 +1,15 @@
package net.knarcraft.permissionsigns.container; 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 * A temporary permission that needs to be removed after a given duration
*/ */
public class TemporaryPermission { public class TemporaryPermission implements Comparable<TemporaryPermission> {
private final long grantedTime; private final long grantedTime;
private final OfflinePlayer grantedPlayer; private final Player grantedPlayer;
private final String permissionNode; private final String permissionNode;
private final int duration; private final int duration;
@ -19,7 +20,7 @@ public class TemporaryPermission {
* @param permissionNode <p>The permission node granted to the player</p> * @param permissionNode <p>The permission node granted to the player</p>
* @param duration <p>The duration, in seconds, the temporary permission should last</p> * @param duration <p>The duration, in seconds, the temporary permission should last</p>
*/ */
public TemporaryPermission(OfflinePlayer player, String permissionNode, int duration) { public TemporaryPermission(Player player, String permissionNode, int duration) {
grantedTime = System.currentTimeMillis(); grantedTime = System.currentTimeMillis();
this.grantedPlayer = player; this.grantedPlayer = player;
this.permissionNode = permissionNode; this.permissionNode = permissionNode;
@ -36,7 +37,7 @@ public class TemporaryPermission {
* @param grantedTime <p>The time this temporary permission was granted</p> * @param grantedTime <p>The time this temporary permission was granted</p>
* @param duration <p>The duration, in seconds, the temporary permission should last</p> * @param duration <p>The duration, in seconds, the temporary permission should last</p>
*/ */
public TemporaryPermission(OfflinePlayer player, String permissionNode, long grantedTime, int duration) { public TemporaryPermission(Player player, String permissionNode, long grantedTime, int duration) {
this.grantedPlayer = player; this.grantedPlayer = player;
this.permissionNode = permissionNode; this.permissionNode = permissionNode;
this.grantedTime = grantedTime; this.grantedTime = grantedTime;
@ -66,7 +67,7 @@ public class TemporaryPermission {
* *
* @return <p>The player this temporary permission was granted to</p> * @return <p>The player this temporary permission was granted to</p>
*/ */
public OfflinePlayer getGrantedPlayer() { public Player getGrantedPlayer() {
return grantedPlayer; return grantedPlayer;
} }
@ -79,4 +80,10 @@ public class TemporaryPermission {
return permissionNode; return permissionNode;
} }
@Override
public int compareTo(@NotNull TemporaryPermission other) {
return (int) (grantedTime + (1000 * duration) - (grantedTime + (1000 * other.duration)));
}
} }

View File

@ -2,10 +2,10 @@ package net.knarcraft.permissionsigns.manager;
import net.knarcraft.permissionsigns.container.TemporaryPermission; import net.knarcraft.permissionsigns.container.TemporaryPermission;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; 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 * A manager that performs all Permission tasks
@ -13,7 +13,7 @@ import java.util.List;
public class PermissionManager { public class PermissionManager {
private static Permission permission; private static Permission permission;
private static List<TemporaryPermission> temporaryPermissions; private static final Queue<TemporaryPermission> temporaryPermissions = new PriorityBlockingQueue<>();
/** /**
* Initializes the permission manager * Initializes the permission manager
@ -24,6 +24,15 @@ public class PermissionManager {
PermissionManager.permission = permission; PermissionManager.permission = permission;
} }
/**
* Gets the registered temporary permissions
*
* @return <p>The registered temporary permissions</p>
*/
public static Queue<TemporaryPermission> getTemporaryPermissions() {
return temporaryPermissions;
}
/** /**
* Grants a permanent permission to a player * Grants a permanent permission to a player
* *
@ -31,7 +40,8 @@ public class PermissionManager {
* @param permissionNode <p>The permission node to grant to the player</p> * @param permissionNode <p>The permission node to grant to the player</p>
*/ */
public static void addPermission(Player player, String permissionNode) { 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 <p>The temporary permission to grant</p> * @param permissionNode <p>The temporary permission to grant</p>
* @param duration <p>The duration for which the player should keep the given permission</p> * @param duration <p>The duration for which the player should keep the given permission</p>
*/ */
public static void addTemporaryPermission(OfflinePlayer player, String permissionNode, int duration) { public static void addTemporaryPermission(Player player, String permissionNode, int duration) {
permission.playerAddTransient(player, permissionNode); permission.playerAddTransient(null, player, permissionNode);
temporaryPermissions.add(new TemporaryPermission(player, permissionNode, duration)); temporaryPermissions.add(new TemporaryPermission(player, permissionNode, duration));
//TODO: Create and store a temporary permission //TODO: Create and store a temporary permission
// Check all stored temporary permissions on startup: // Check all stored temporary permissions on startup:
@ -59,8 +69,10 @@ public class PermissionManager {
* @param player <p>The player to remove the permission from</p> * @param player <p>The player to remove the permission from</p>
* @param permissionNode <p>The permission node to remove from the player</p> * @param permissionNode <p>The permission node to remove from the player</p>
*/ */
public static void removeTemporaryPermission(OfflinePlayer player, String permissionNode) { public static void removeTemporaryPermission(Player player, String permissionNode) {
permission.playerRemoveTransient(player, permissionNode); if (player.hasPermission(permissionNode)) {
permission.playerRemoveTransient(null, player, permissionNode);
}
} }
} }

View File

@ -4,6 +4,9 @@ import net.knarcraft.permissionsigns.PermissionSigns;
import net.knarcraft.permissionsigns.container.PermissionSign; import net.knarcraft.permissionsigns.container.PermissionSign;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; 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.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@ -11,6 +14,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -96,8 +100,33 @@ public class SignManager {
e.getMessage()); 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();
}
});
} }
/** /**

View File

@ -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<TemporaryPermission> 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;
}
}
}
}