The duration, in seconds, until the permission should be revoked. 0 for non-temporary
* @param costThe cost of using this permission sign
*/ - public PermissionSign(Location signLocation, String name, ListThe duration, in seconds, until the permission should be revoked. 0 for non-temporary
* @param costThe cost of using this permission sign
*/ - public PermissionSign(String name, ListThe cost of using this permission sign
*/ - public int getCost() { + public double getCost() { return this.cost; } @@ -163,8 +164,8 @@ public class PermissionSign { if (cost == 0) { return Translator.getTranslatedMessage(TranslatableMessage.SIGN_COST_FREE); } else { - //TODO: Get currency unit from Vault - return cost + "$"; + String currency = EconomyManager.getCurrency(cost != 1); + return String.format("%f%s", cost, currency); } } diff --git a/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java b/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java new file mode 100644 index 0000000..f8a8c7f --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java @@ -0,0 +1,82 @@ +package net.knarcraft.permissionsigns.container; + +import org.bukkit.OfflinePlayer; + +/** + * A temporary permission that needs to be removed after a given duration + */ +public class TemporaryPermission { + + private final long grantedTime; + private final OfflinePlayer grantedPlayer; + private final String permissionNode; + private final int duration; + + /** + * Instantiates a new temporary permission + * + * @param playerThe player the temporary permission was assigned to
+ * @param permissionNodeThe permission node granted to the player
+ * @param durationThe duration, in seconds, the temporary permission should last
+ */ + public TemporaryPermission(OfflinePlayer player, String permissionNode, int duration) { + 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 + } + + /** + * Instantiates a new temporary permission + * + * @param playerThe player the temporary permission was assigned to
+ * @param permissionNodeThe permission node granted to the player
+ * @param grantedTimeThe time this temporary permission was granted
+ * @param durationThe duration, in seconds, the temporary permission should last
+ */ + public TemporaryPermission(OfflinePlayer player, String permissionNode, long grantedTime, int duration) { + this.grantedPlayer = player; + this.permissionNode = permissionNode; + this.grantedTime = grantedTime; + this.duration = duration; + } + + /** + * Gets the time that this temporary permission was granted + * + * @returnThe time (current time millis) this permission was granted
+ */ + public long getGrantedTime() { + return this.grantedTime; + } + + /** + * Gets the duration the player should be granted this permission for + * + * @returnThe duration of the temporary permission
+ */ + public int getGrantedDuration() { + return this.duration; + } + + /** + * Gets the player this temporary permission was granted to + * + * @returnThe player this temporary permission was granted to
+ */ + public OfflinePlayer getGrantedPlayer() { + return grantedPlayer; + } + + /** + * Gets the permission node that was granted to this player + * + * @returnThe permission node that was granted to this player
+ */ + public String getPermissionNode() { + return permissionNode; + } + +} diff --git a/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java b/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java index dea9a8c..9722b97 100644 --- a/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java +++ b/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java @@ -1,11 +1,13 @@ package net.knarcraft.permissionsigns.listener; import net.knarcraft.permissionsigns.PermissionSigns; -import net.knarcraft.permissionsigns.SignManager; import net.knarcraft.permissionsigns.container.PermissionSign; import net.knarcraft.permissionsigns.container.SignCreationRequest; import net.knarcraft.permissionsigns.formatting.TranslatableMessage; import net.knarcraft.permissionsigns.formatting.Translator; +import net.knarcraft.permissionsigns.manager.EconomyManager; +import net.knarcraft.permissionsigns.manager.PermissionManager; +import net.knarcraft.permissionsigns.manager.SignManager; import org.bukkit.Material; import org.bukkit.Tag; import org.bukkit.block.Block; @@ -78,23 +80,53 @@ public class SignListener implements Listener { * @param playerThe player that clicked the sign
*/ private void handleSignRightClick(Sign sign, Player player) { - String[] lines = sign.getLines(); - - if (SignManager.getSign(sign.getLocation()) != null) { - //TODO: Perform the permission payment/granting + //Check if the sign is a registered permission sign + PermissionSign permissionSign = SignManager.getSign(sign.getLocation()); + if (permissionSign != null) { + handlePermissionSignInteract(permissionSign, player); return; } + //Check if the player has a creation request that can be fulfilled + SignCreationRequest request = PermissionSigns.getSignCreationRequest(player.getUniqueId()); + if (request != null) { + registerPermissionSign(sign, request, player); + } + } + + /** + * Handles the interaction with a permission sign + * + * @param permissionSignThe permission sign that was interacted with
+ * @param playerThe player that interacted with the permission sign
+ */ + private void handlePermissionSignInteract(PermissionSign permissionSign, Player player) { + //TODO: Check if the player has the permissions for sale. If it has, just explain that it does + if (EconomyManager.canAfford(player, permissionSign.getCost())) { + EconomyManager.withdraw(player, permissionSign.getCost()); + for (String permissionString : permissionSign.getPermissionNodes()) { + PermissionManager.addPermission(player, permissionString, permissionSign.getDuration() == 0); + } + //TODO: Tell the player that they've been granted the new permissions, possibly including the full nodes? + } else { + //TODO: Tell the player that they cannot afford the transaction + } + } + + /** + * Registers a new permission sign if the given sign is empty + * + * @param signThe sign to register as a permission sign
+ * @param requestThe creation request to fulfill
+ * @param playerThe player that interacted with the sign
+ */ + private void registerPermissionSign(Sign sign, SignCreationRequest request, Player player) { + String[] lines = sign.getLines(); //Don't allow non-empty signs to be overwritten if (!Arrays.stream(lines).allMatch(String::isEmpty)) { return; } - SignCreationRequest request = PermissionSigns.getSignCreationRequest(player.getUniqueId()); - if (request == null) { - return; - } - //Register the sign and remove the request PermissionSign permissionSign = request.getPermissionSign(); permissionSign.setSignLocation(sign.getLocation()); @@ -107,6 +139,7 @@ public class SignListener implements Listener { sign.setLine(i, signLines[i]); } sign.update(); + //TODO: Display text in the chat explaining that the permission sign has been created } } diff --git a/src/main/java/net/knarcraft/permissionsigns/manager/EconomyManager.java b/src/main/java/net/knarcraft/permissionsigns/manager/EconomyManager.java new file mode 100644 index 0000000..e5d690b --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/manager/EconomyManager.java @@ -0,0 +1,58 @@ +package net.knarcraft.permissionsigns.manager; + +import net.milkbowl.vault.economy.Economy; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +/** + * A manager that performs all Economy tasks + */ +public class EconomyManager { + + private static Economy economy; + + /** + * Initializes the economy manager + * + * @param economyThe economy object to use for everything economy-related
+ */ + public static void initialize(Economy economy) { + EconomyManager.economy = economy; + } + + /** + * Checks whether the given player can afford the given cost + * + * @param playerThe player to pay the cost
+ * @param costThe cost the player needs to pay
+ * @returnTrue if the player is able to afford the cost
+ */ + public static boolean canAfford(OfflinePlayer player, double cost) { + return economy.has(player, cost); + } + + /** + * Gets the name of the used currency + * + * @param pluralWhether to get the plural name or the singular name
+ * @returnThe name of the used currency
+ */ + public static String getCurrency(boolean plural) { + if (plural) { + return economy.currencyNamePlural(); + } else { + return economy.currencyNameSingular(); + } + } + + /** + * Withdraws the given cost from the given player's account + * + * @param playerThe player to withdraw money from
+ * @param costThe amount of money to withdraw
+ */ + public static void withdraw(Player player, double cost) { + economy.withdrawPlayer(player, cost); + } + +} diff --git a/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java b/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java new file mode 100644 index 0000000..7c1be1d --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java @@ -0,0 +1,79 @@ +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; + +/** + * A manager that performs all Permission tasks + */ +public class PermissionManager { + + private static Permission permission; + private static ListThe permission object to use for everything permission-related
+ */ + public static void initialize(Permission permission) { + PermissionManager.permission = permission; + } + + /** + * Grants a permission to the given player + * + * @param playerThe player to grant the permission to
+ * @param permissionNodeThe permission node to grant the player
+ * @param permanentWhether to permanently grant the permission node
+ */ + public static void addPermission(Player player, String permissionNode, boolean permanent) { + if (permanent) { + addPermission(player, permissionNode); + } else { + addTemporaryPermission(player, permissionNode); + } + } + + /** + * Grants a permanent permission to a player + * + * @param playerThe player to grant the permission to
+ * @param permissionNodeThe permission node to grant to the player
+ */ + private static void addPermission(Player player, String permissionNode) { + permission.playerAdd(player, permissionNode); + } + + /** + * Grants a temporary permission to a player + * + * @param playerThe player to give the permission to
+ * @param permissionNodeThe temporary permission to grant
+ */ + private static void addTemporaryPermission(OfflinePlayer player, String permissionNode) { + permission.playerAddTransient(player, permissionNode); + //TODO: Create and store a temporary permission + // Check all stored temporary permissions on startup: + // * Remove expired temporary permissions + // * Grant transient permissions + // In a separate thread, remove any expired permissions, checking at least once every seconds. Might want to + // store the granted permissions in a priority queue where the priority is the least duration left. + // How to store temporary permissions? Identifier as Player + permission granted time? + } + + /** + * Removes a temporary permission + * + * @param playerThe player to remove the permission from
+ * @param permissionNodeThe permission node to remove from the player
+ */ + public static void removeTemporaryPermission(OfflinePlayer player, String permissionNode) { + permission.playerRemoveTransient(player, permissionNode); + } + +} diff --git a/src/main/java/net/knarcraft/permissionsigns/SignManager.java b/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java similarity index 97% rename from src/main/java/net/knarcraft/permissionsigns/SignManager.java rename to src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java index 8875b1b..7d21a4c 100644 --- a/src/main/java/net/knarcraft/permissionsigns/SignManager.java +++ b/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java @@ -1,5 +1,6 @@ -package net.knarcraft.permissionsigns; +package net.knarcraft.permissionsigns.manager; +import net.knarcraft.permissionsigns.PermissionSigns; import net.knarcraft.permissionsigns.container.PermissionSign; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -142,7 +143,7 @@ public class SignManager { }); int duration = signSection.getInt(key + ".duration"); - int cost = signSection.getInt(key + ".cost"); + double cost = signSection.getDouble(key + ".cost"); PermissionSign loadedSign = new PermissionSign(signLocation, signName, permissionStrings, duration, cost); managedSigns.put(signLocation, loadedSign);