From 2917905b23200b8d60ed76eba386f1ec2b1ce12f Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 9 Jan 2022 12:12:55 +0100 Subject: [PATCH] Performs a lot of various changes Adds some new command classes Adds support for several languages Adds README Updates Java and Spigot versions Adds command info and additional permission info to plugin.yml Implements manual sign creation request cancelling --- README.md | 5 ++ pom.xml | 10 ++- .../permissionsigns/PermissionSigns.java | 71 ++++++++++++++++--- .../permissionsigns/command/AboutCommand.java | 24 +++++++ .../command/CancelCommand.java | 15 ++-- .../command/CreateCommand.java | 48 +++++++++++-- .../command/CreateTabCompleter.java | 10 ++- .../command/PermissionSignsCommand.java | 27 +++++++ .../command/PermissionSignsTabCompleter.java | 56 +++++++++++++++ .../command/ReloadCommand.java | 4 ++ .../container/PermissionSign.java | 60 ++++++++++++++-- .../container/SignCreationRequest.java | 16 ++--- .../formatting/StringFormatter.java | 40 +++++++++++ .../formatting/TranslatableMessage.java | 19 +++++ .../formatting/Translator.java | 67 +++++++++++++++++ .../listener/SignListener.java | 35 +++++++-- .../SignCreationRequestTimeoutThread.java | 12 ++-- src/main/resources/plugin.yml | 24 ++++++- src/main/resources/strings.yml | 11 +++ 19 files changed, 502 insertions(+), 52 deletions(-) create mode 100644 README.md create mode 100644 src/main/java/net/knarcraft/permissionsigns/command/AboutCommand.java create mode 100644 src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsCommand.java create mode 100644 src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsTabCompleter.java create mode 100644 src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java create mode 100644 src/main/java/net/knarcraft/permissionsigns/formatting/StringFormatter.java create mode 100644 src/main/java/net/knarcraft/permissionsigns/formatting/TranslatableMessage.java create mode 100644 src/main/java/net/knarcraft/permissionsigns/formatting/Translator.java create mode 100644 src/main/resources/strings.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..a136b73 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Permission Signs + +This is a plugin based on the permission signs plugin created by _ForgeUser7294733. As the previous plugin does not +offer source code and has a restrictive license, this plugin is written from scratch, but trying to imitate the original +plugin's behavior. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 869314e..62e094d 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ A plugin for selling permissions using signs - 16 + 17 UTF-8 git.knarcraft.net @@ -69,8 +69,14 @@ org.spigotmc spigot-api - 1.17.1-R0.1-SNAPSHOT + 1.18.1-R0.1-SNAPSHOT provided + + org.jetbrains + annotations + RELEASE + compile + diff --git a/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java b/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java index 130bae8..2acffde 100644 --- a/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java +++ b/src/main/java/net/knarcraft/permissionsigns/PermissionSigns.java @@ -1,9 +1,14 @@ package net.knarcraft.permissionsigns; +import net.knarcraft.permissionsigns.command.PermissionSignsCommand; +import net.knarcraft.permissionsigns.command.PermissionSignsTabCompleter; +import net.knarcraft.permissionsigns.container.PermissionSign; import net.knarcraft.permissionsigns.container.SignCreationRequest; import net.knarcraft.permissionsigns.thread.SignCreationRequestTimeoutThread; import org.bukkit.Bukkit; +import org.bukkit.command.PluginCommand; import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitScheduler; @@ -14,12 +19,32 @@ import java.util.UUID; import java.util.stream.Stream; public final class PermissionSigns extends JavaPlugin { - - private static Queue signCreationRequests = new PriorityQueue<>(); + + private static final Queue signCreationRequests = new PriorityQueue<>(); + private static String pluginVersion; + + /** + * Gets the version of this plugin + * + * @return

This plugin's version

+ */ + public static String getPluginVersion() { + return pluginVersion; + } + + /** + * Adds a new sign creation request + * + * @param player

The player that initiated the sign creation

+ * @param sign

The sign the player is about to create

+ */ + public static void addSignCreationRequest(Player player, PermissionSign sign) { + signCreationRequests.add(new SignCreationRequest(sign, player, System.currentTimeMillis())); + } /** * Gets the sign creation request for the player with the given UUID - * + * * @param uuid

The UUID to get a sign creation request for

* @return

A sign creation request, or null if the UUID is not found

*/ @@ -34,10 +59,25 @@ public final class PermissionSigns extends JavaPlugin { } } + /** + * Cancels the sign creation request triggered by the user + * + * @param uuid

The UUID of the player to cancel the request for

+ */ + public static void cancelSignCreationRequest(UUID uuid) { + Stream matchingRequests = signCreationRequests.stream().filter( + (item) -> item.getPlayer().getUniqueId().equals(uuid)); + List requestList = matchingRequests.toList(); + signCreationRequests.remove(requestList.get(0)); + } + @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 @@ -53,7 +93,7 @@ public final class PermissionSigns extends JavaPlugin { // /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 @@ -61,23 +101,36 @@ public final class PermissionSigns extends JavaPlugin { // 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: 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 signdata.yml, add it. + registerCommands(); BukkitScheduler scheduler = Bukkit.getScheduler(); scheduler.runTaskTimer(this, new SignCreationRequestTimeoutThread(signCreationRequests), 0L, 100L); } + /** + * Registers a command for this plugin + */ + private void registerCommands() { + PluginCommand stargateCommand = this.getCommand("permissionsigns"); + if (stargateCommand != null) { + stargateCommand.setExecutor(new PermissionSignsCommand()); + stargateCommand.setTabCompleter(new PermissionSignsTabCompleter()); + } + } + @Override public void onDisable() { // Plugin shutdown logic } + } diff --git a/src/main/java/net/knarcraft/permissionsigns/command/AboutCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/AboutCommand.java new file mode 100644 index 0000000..d418364 --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/command/AboutCommand.java @@ -0,0 +1,24 @@ +package net.knarcraft.permissionsigns.command; + +import net.knarcraft.permissionsigns.PermissionSigns; +import net.knarcraft.permissionsigns.formatting.StringFormatter; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +/** + * A command for getting information about the plugin + */ +public class AboutCommand implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + sender.sendMessage(StringFormatter.formatInfoMessage("Permission Signs plugin created by " + ChatColor.GOLD + + "EpicKnarvik97")); + sender.sendMessage(StringFormatter.formatInfoMessage("Plugin version: " + PermissionSigns.getPluginVersion())); + return true; + } + +} diff --git a/src/main/java/net/knarcraft/permissionsigns/command/CancelCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/CancelCommand.java index 5c3b2ea..6a34da8 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/CancelCommand.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/CancelCommand.java @@ -1,14 +1,21 @@ package net.knarcraft.permissionsigns.command; +import net.knarcraft.permissionsigns.PermissionSigns; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +/** + * The command used to cancel a sign creation request + */ public class CancelCommand implements CommandExecutor { - + @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - return false; + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + PermissionSigns.cancelSignCreationRequest(((Player) sender).getUniqueId()); + return true; } - + } diff --git a/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java index 54bb9dc..e7988b8 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java @@ -1,17 +1,55 @@ package net.knarcraft.permissionsigns.command; +import net.knarcraft.permissionsigns.PermissionSigns; +import net.knarcraft.permissionsigns.container.PermissionSign; +import net.knarcraft.permissionsigns.formatting.TranslatableMessage; +import net.knarcraft.permissionsigns.formatting.Translator; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import java.util.List; + +/** + * The command used to create a new permission sign + */ public class CreateCommand implements CommandExecutor { - + @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { // /ps create to create a new permission-sign //Name and permission(s) required, but duration and cost optional - - return false; + if (!(sender instanceof Player)) { + sender.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.COMMAND_PLAYER_ONLY)); + return false; + } + if (args.length < 2) { + sender.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.MISSING_CREATION_INFO)); + return false; + } + + String name = args[0]; + String[] permissions = args[1].split(","); + int cost; + int duration; + try { + cost = Integer.parseInt(args[2]); + } catch (NumberFormatException exception) { + sender.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.COST_INVALID_NUMBER)); + return false; + } + try { + duration = Integer.parseInt(args[3]); + } catch (NumberFormatException exception) { + sender.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.DURATION_INVALID_NUMBER)); + return false; + } + + PermissionSign newSign = new PermissionSign(name, List.of(permissions), cost, duration); + PermissionSigns.addSignCreationRequest((Player) sender, newSign); + return true; } - + } diff --git a/src/main/java/net/knarcraft/permissionsigns/command/CreateTabCompleter.java b/src/main/java/net/knarcraft/permissionsigns/command/CreateTabCompleter.java index 705846a..e8c8081 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/CreateTabCompleter.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/CreateTabCompleter.java @@ -3,14 +3,18 @@ package net.knarcraft.permissionsigns.command; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; import java.util.List; +/** + * The tab completer for the create command + */ public class CreateTabCompleter implements TabCompleter { - + @Override - public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { return null; } - + } diff --git a/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsCommand.java new file mode 100644 index 0000000..040ad33 --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsCommand.java @@ -0,0 +1,27 @@ +package net.knarcraft.permissionsigns.command; + +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +/** + * The main command for this plugin + */ +public class PermissionSignsCommand implements CommandExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length > 0) { + if (args[0].equalsIgnoreCase("create")) { + + } else if (args[0].equalsIgnoreCase("cancel")) { + + } else if (args[0].equalsIgnoreCase("about")) { + + } + } + return false; + } + +} diff --git a/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsTabCompleter.java b/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsTabCompleter.java new file mode 100644 index 0000000..1fe7be2 --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsTabCompleter.java @@ -0,0 +1,56 @@ +package net.knarcraft.permissionsigns.command; + +import org.apache.commons.lang.ArrayUtils; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * The tab completer for this plugin's main command + */ +public class PermissionSignsTabCompleter implements TabCompleter { + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + if (args.length == 1) { + List commands = getAvailableCommands(sender); + List matchingCommands = new ArrayList<>(); + for (String availableCommand : commands) { + if (availableCommand.startsWith(args[0])) { + matchingCommands.add(availableCommand); + } + } + return matchingCommands; + } else if (args.length > 1 && args[0].equalsIgnoreCase("create")) { + String[] subArgs = (String[]) ArrayUtils.remove(args, 0); + return new CreateTabCompleter().onTabComplete(sender, command, alias, subArgs); + } else { + return new ArrayList<>(); + } + } + + /** + * Gets the available commands + * + * @param commandSender

The command sender to get available commands for

+ * @return

The commands available to the command sender

+ */ + private List getAvailableCommands(CommandSender commandSender) { + List commands = new ArrayList<>(); + commands.add("about"); + if (!(commandSender instanceof Player player) || player.hasPermission("permissionsigns.admin.reload")) { + commands.add("reload"); + } + if (commandSender instanceof Player player && player.hasPermission("permissionsigns.admin.create")) { + commands.add("create"); + commands.add("cancel"); + } + return commands; + } + +} diff --git a/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java new file mode 100644 index 0000000..adf8506 --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java @@ -0,0 +1,4 @@ +package net.knarcraft.permissionsigns.command; + +public class ReloadCommand { +} diff --git a/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java b/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java index b2f51dd..c127683 100644 --- a/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java +++ b/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java @@ -1,6 +1,8 @@ package net.knarcraft.permissionsigns.container; -import net.knarcraft.permissionsigns.PermissionSigns; +import net.knarcraft.permissionsigns.formatting.TranslatableMessage; +import net.knarcraft.permissionsigns.formatting.Translator; +import org.bukkit.ChatColor; import org.bukkit.Location; import java.util.ArrayList; @@ -30,6 +32,8 @@ public class PermissionSign { this.signLocation = signLocation; this.name = name; this.permissionNodes = new ArrayList<>(permissionNodes); + + //Automatically fix negative values this.duration = Math.max(0, duration); this.cost = Math.max(0, cost); } @@ -37,11 +41,12 @@ public class PermissionSign { /** * Instantiates a new permission sign * + * @param name

The name to display on the permission sign

* @param permissionNodes

The permissions granted when this permission sign is used

* @param duration

The duration, in seconds, until the permission should be revoked. 0 for non-temporary

* @param cost

The cost of using this permission sign

*/ - public PermissionSign(List permissionNodes, int duration, int cost) { + public PermissionSign(String name, List permissionNodes, int duration, int cost) { this.permissionNodes = new ArrayList<>(permissionNodes); this.duration = Math.max(0, duration); this.cost = Math.max(0, cost); @@ -49,7 +54,7 @@ public class PermissionSign { /** * Sets the sign location of this permission sign - * + * * @param signLocation

>The location of this permission sign's actual sign

*/ public void setSignLocation(Location signLocation) { @@ -64,7 +69,7 @@ public class PermissionSign { * Gets the location of this permission sign * *

The location might be null until a sign has been right-clicked

- * + * * @return

The location of this permission sign

*/ public Location getSignLocation() { @@ -73,7 +78,7 @@ public class PermissionSign { /** * Gets the name of this permission sign - * + * * @return

The name of this permission sign

*/ public String getName() { @@ -108,7 +113,21 @@ public class PermissionSign { public int getCost() { return this.cost; } - + + /** + * Gets the lines used to represent this permission sign on a sign + * + * @return

The lines used to draw this permission sign

+ */ + public String[] getSignLines() { + String[] lines = new String[4]; + lines[0] = ChatColor.RED + Translator.getTranslatedMessage(TranslatableMessage.PREFIX); + lines[1] = getName(); + lines[2] = getDurationString(); + lines[3] = getCostString(); + return lines; + } + @Override public boolean equals(Object other) { if (!(other instanceof PermissionSign)) { @@ -117,8 +136,35 @@ public class PermissionSign { if (this == other) { return true; } - + return this.signLocation.equals(((PermissionSign) other).signLocation); } + /** + * Gets the string used for displaying this sign's duration + * + * @return

The string used for displaying this sign's duration

+ */ + private String getDurationString() { + if (duration == 0) { + return Translator.getTranslatedMessage(TranslatableMessage.PERMANENT); + } else { + return duration + " " + Translator.getTranslatedMessage(TranslatableMessage.TIME_UNIT); + } + } + + /** + * Gets the string used for displaying this sign's cost + * + * @return

The string used for displaying this sign's cost

+ */ + private String getCostString() { + if (cost == 0) { + return Translator.getTranslatedMessage(TranslatableMessage.COST_FREE); + } else { + //TODO: Get currency unit from Vault + return cost + "$"; + } + } + } diff --git a/src/main/java/net/knarcraft/permissionsigns/container/SignCreationRequest.java b/src/main/java/net/knarcraft/permissionsigns/container/SignCreationRequest.java index e7a8951..9cb6025 100644 --- a/src/main/java/net/knarcraft/permissionsigns/container/SignCreationRequest.java +++ b/src/main/java/net/knarcraft/permissionsigns/container/SignCreationRequest.java @@ -6,16 +6,16 @@ import org.bukkit.entity.Player; * A sign creation request represents the state where a player has used the create command, but not clicked a sign */ public class SignCreationRequest implements Comparable { - + private final PermissionSign permissionSign; private final Player player; private final long initiationTime; /** * Instantiates a new sign creation request - * + * * @param permissionSign

The sign which is about to be created

- * @param player

The player starting to create the permission sign

+ * @param player

The player starting to create the permission sign

* @param initiationTime

*/ public SignCreationRequest(PermissionSign permissionSign, Player player, long initiationTime) { @@ -26,7 +26,7 @@ public class SignCreationRequest implements Comparable { /** * Gets the permission sign involved in this request - * + * * @return

The involved permission sign

*/ public PermissionSign getPermissionSign() { @@ -35,7 +35,7 @@ public class SignCreationRequest implements Comparable { /** * Gets the player involved in this request - * + * * @return

The involved player

*/ public Player getPlayer() { @@ -44,13 +44,13 @@ public class SignCreationRequest implements Comparable { /** * Gets the time this sign creation request was initiated - * + * * @return

The time this request was initiated

*/ public long initiationTime() { return this.initiationTime; } - + @Override public boolean equals(Object other) { if (!(other instanceof SignCreationRequest otherRequest)) { @@ -59,7 +59,7 @@ public class SignCreationRequest implements Comparable { if (this == other) { return true; } - + return this.getPlayer().getUniqueId() == otherRequest.getPlayer().getUniqueId(); } diff --git a/src/main/java/net/knarcraft/permissionsigns/formatting/StringFormatter.java b/src/main/java/net/knarcraft/permissionsigns/formatting/StringFormatter.java new file mode 100644 index 0000000..969a853 --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/formatting/StringFormatter.java @@ -0,0 +1,40 @@ +package net.knarcraft.permissionsigns.formatting; + +import org.bukkit.ChatColor; + +/** + * A formatter for formatting displayed messages + */ +public class StringFormatter { + + /** + * Formats an information message by adding the prefix and text color + * + * @param message

The message to format

+ * @return

The formatted message

+ */ + public static String formatInfoMessage(String message) { + return ChatColor.DARK_RED + formatMessage(message); + } + + /** + * Formats an error message by adding the prefix and text color + * + * @param message

The message to format

+ * @return

The formatted message

+ */ + public static String formatErrorMessage(String message) { + return ChatColor.DARK_GREEN + formatMessage(message); + } + + /** + * Formats a message by adding the prefix and text color + * + * @param message

The message to format

+ * @return

The formatted message

+ */ + private static String formatMessage(String message) { + return Translator.getTranslatedMessage(TranslatableMessage.PREFIX) + ChatColor.GRAY + message; + } + +} diff --git a/src/main/java/net/knarcraft/permissionsigns/formatting/TranslatableMessage.java b/src/main/java/net/knarcraft/permissionsigns/formatting/TranslatableMessage.java new file mode 100644 index 0000000..dc8487c --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/formatting/TranslatableMessage.java @@ -0,0 +1,19 @@ +package net.knarcraft.permissionsigns.formatting; + +/** + * An enum representing all translatable messages + */ +public enum TranslatableMessage { + + PREFIX, + MISSING_CREATION_INFO, + TIME_UNIT, + COST_FREE, + PERMANENT, + COST_INVALID_NUMBER, + DURATION_INVALID_NUMBER, + COMMAND_PLAYER_ONLY, + PERMISSION_SIGN_DESTROY_DENY, + PERMISSION_SIGN_REMOVED + +} diff --git a/src/main/java/net/knarcraft/permissionsigns/formatting/Translator.java b/src/main/java/net/knarcraft/permissionsigns/formatting/Translator.java new file mode 100644 index 0000000..2c1c84b --- /dev/null +++ b/src/main/java/net/knarcraft/permissionsigns/formatting/Translator.java @@ -0,0 +1,67 @@ +package net.knarcraft.permissionsigns.formatting; + +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Map; + +/** + * A tool to get strings translated to the correct language + */ +public class Translator { + + private static Map translatedMessages; + private static Map backupTranslatedMessages; + + /** + * Loads the languages used by this translator + */ + public Translator() { + backupTranslatedMessages = loadTranslatedMessages("en"); + translatedMessages = loadTranslatedMessages("en"); + } + + /** + * Gets a translated version of the given translatable message + * + * @param translatableMessage

The message to translate

+ * @return

The translated message

+ */ + public static String getTranslatedMessage(TranslatableMessage translatableMessage) { + if (translatedMessages.containsKey(translatableMessage)) { + return translatedMessages.get(translatableMessage); + } else if (backupTranslatedMessages.containsKey(translatableMessage)) { + return backupTranslatedMessages.get(translatableMessage); + } else { + return translatableMessage.toString(); + } + } + + /** + * Loads all translated messages for the given language + * + * @param language

The language chosen by the user

+ * @return

A mapping of all strings for the given language

+ */ + public static Map loadTranslatedMessages(String language) { + Map translatedMessages = new HashMap<>(); + InputStream inputStream = Translator.class.getResourceAsStream("/strings.yml"); + if (inputStream == null) { + throw new IllegalArgumentException("Unable to load strings"); + } + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + YamlConfiguration configuration = YamlConfiguration.loadConfiguration(reader); + + for (TranslatableMessage message : TranslatableMessage.values()) { + String translated = configuration.getString(language + "." + message.toString()); + if (translated != null) { + translatedMessages.put(message, translated); + } + } + return translatedMessages; + } + +} \ No newline at end of file diff --git a/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java b/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java index bd9465f..8da85c4 100644 --- a/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java +++ b/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java @@ -2,6 +2,8 @@ package net.knarcraft.permissionsigns.listener; import net.knarcraft.permissionsigns.PermissionSigns; import net.knarcraft.permissionsigns.container.SignCreationRequest; +import net.knarcraft.permissionsigns.formatting.TranslatableMessage; +import net.knarcraft.permissionsigns.formatting.Translator; import org.bukkit.Material; import org.bukkit.Tag; import org.bukkit.block.Block; @@ -14,6 +16,9 @@ import org.bukkit.event.player.PlayerInteractEvent; import java.util.Arrays; +/** + * A listener for all events related to signs + */ public class SignListener implements Listener { /** @@ -29,26 +34,46 @@ public class SignListener implements Listener { if (block == null) { return; } - + Material material = block.getBlockData().getMaterial(); if (!Tag.SIGNS.isTagged(material) && !Tag.WALL_SIGNS.isTagged(material)) { return; } + Sign sign = (Sign) block.getState(); if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { - Sign sign = (Sign) block.getState(); handleSignRightClick(sign, player); + } else if (event.getAction() == Action.LEFT_CLICK_BLOCK) { + handleSignLeftClick(sign, player, event); + } + } + + private void handleSignLeftClick(Sign sign, Player player, PlayerInteractEvent event) { + //TODO: Check if the sign is a registered permissions sign + boolean registered = true; + if (!registered) { + return; + } + if (!player.hasPermission("permissionsigns.admin")) { + event.setCancelled(true); + player.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.PERMISSION_SIGN_DESTROY_DENY)); + } else { + //TODO: Un-register the permissions sign + player.sendMessage(Translator.getTranslatedMessage(TranslatableMessage.PERMISSION_SIGN_REMOVED)); } } /** * Handles the right-clicking action - * - * @param sign

The clicked sign

+ * + * @param sign

The clicked sign

* @param player

The player that clicked the sign

*/ private void handleSignRightClick(Sign sign, Player player) { String[] lines = sign.getLines(); + + //TODO: Check if the sign is a registered permissions sign + //Don't allow non-empty signs to be overwritten if (!Arrays.stream(lines).allMatch(String::isEmpty)) { return; @@ -61,5 +86,5 @@ public class SignListener implements Listener { //TODO: Register the sign and remove the request } - + } diff --git a/src/main/java/net/knarcraft/permissionsigns/thread/SignCreationRequestTimeoutThread.java b/src/main/java/net/knarcraft/permissionsigns/thread/SignCreationRequestTimeoutThread.java index 0fd7bb2..ce43587 100644 --- a/src/main/java/net/knarcraft/permissionsigns/thread/SignCreationRequestTimeoutThread.java +++ b/src/main/java/net/knarcraft/permissionsigns/thread/SignCreationRequestTimeoutThread.java @@ -8,23 +8,23 @@ import java.util.Queue; * The sign creation request timeout thread is responsible for removing sign creation requests as they time out */ public class SignCreationRequestTimeoutThread implements Runnable { - + private final Queue signCreationRequests; /** * Instantiates a new sign creation request timeout thread - * + * * @param signCreationRequests

A pointer to the queue of sign creation requests

*/ public SignCreationRequestTimeoutThread(Queue signCreationRequests) { this.signCreationRequests = signCreationRequests; } - + @Override public void run() { long currentTime = System.currentTimeMillis(); - int requestTimeoutSeconds = 20; - + int requestTimeoutSeconds = 60; + SignCreationRequest firstElement = signCreationRequests.peek(); while (firstElement != null && currentTime > firstElement.initiationTime() + (1000 * requestTimeoutSeconds)) { //Remove any expired sign creation requests @@ -32,5 +32,5 @@ public class SignCreationRequestTimeoutThread implements Runnable { firstElement = signCreationRequests.peek(); } } - + } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6eb1c99..90c0f18 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,17 +1,35 @@ name: PermissionSigns version: '${project.version}' main: net.knarcraft.permissionsigns.Permissionsigns -api-version: 1.17 +api-version: 1.18 prefix: PermissionSigns depend: [ Vault ] authors: [ EpicKnarvik97 ] description: A plugin for selling permissions using signs website: git.knarcraft.net - -permissions: +commands: + permissionsigns: + aliases: + - ps + - permsigns + - permsign + - signperm + - signperms + description: Used for all permission sign commands + usage: / - Used for all permission sign commands +permissions: permissionsigns.use: description: Allows players to use the permission signs default: true permissionsigns.admin: + description: Allows all administrative tasks such as creating permission signs and reloading + default: op + children: + permissionsigns.admin.reload: true + permissionsigns.admin.create: true + permissionsigns.admin.reload: + description: Allows the usage of the /reload command + default: op + permissionsigns.admin.create: description: Allows players to create/destroy permissionsigns default: op \ No newline at end of file diff --git a/src/main/resources/strings.yml b/src/main/resources/strings.yml new file mode 100644 index 0000000..b40e53a --- /dev/null +++ b/src/main/resources/strings.yml @@ -0,0 +1,11 @@ +en: + PREFIX: "[PermSign]" + MISSING_CREATION_INFO: "You must specify a sign name and a comma-separated list of permissions to create a permission sign" + TIME_UNIT: "seconds" + PERMANENT: "Permanent" + COST_FREE: "Free" + COST_INVALID_NUMBER: "The given cost is not a valid number" + DURATION_INVALID_NUMBER: "The given duration is not a valid number" + COMMAND_PLAYER_ONLY: "This command is only available to players" + PERMISSION_SIGN_DESTROY_DENY: "You do not have permissions to delete a permissions sign" + PERMISSION_SIGN_REMOVED: "Permissions sign removed" \ No newline at end of file