1.20 Update #6
@@ -23,10 +23,11 @@ permission permanently by another cause) when they expire.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
### The create command
 | 
					### The create command
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/ps create \<name> \<description> \<permission,permission> \<cost> \<duration> - Creates a new permission sign. The name is
 | 
					/ps create \<name> \<description> \<permission,permission> \<cost> \<duration> - Creates a new permission sign. The name
 | 
				
			||||||
 | 
					is
 | 
				
			||||||
used to describe what the permission sign does, and is displayed on the sign. The description is used to describe what
 | 
					used to describe what the permission sign does, and is displayed on the sign. The description is used to describe what
 | 
				
			||||||
the permission sign does, but without any limit on the length (use "_" between words, like: This_is_a_sentence). To use
 | 
					the permission sign does, but without any limit on the length (use "_" between words, like: This_is_a_sentence). To use
 | 
				
			||||||
actual underscores, escape them like "\\_". The permission,permission is the list of comma-separated permissions the
 | 
					actual underscores, escape them like "\_". The permission,permission is the list of comma-separated permissions the
 | 
				
			||||||
permission sign will grant to the using player. The cost is the cost to use the permission sign. The duration is the
 | 
					permission sign will grant to the using player. The cost is the cost to use the permission sign. The duration is the
 | 
				
			||||||
number of seconds the player should keep the permission for. Use 0 for permanent.
 | 
					number of seconds the player should keep the permission for. Use 0 for permanent.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								pom.xml
									
									
									
									
									
								
							@@ -6,7 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <groupId>net.knarcraft</groupId>
 | 
					    <groupId>net.knarcraft</groupId>
 | 
				
			||||||
    <artifactId>PermissionSigns</artifactId>
 | 
					    <artifactId>PermissionSigns</artifactId>
 | 
				
			||||||
    <version>1.0.5-SNAPSHOT</version>
 | 
					    <version>1.0.5</version>
 | 
				
			||||||
    <packaging>jar</packaging>
 | 
					    <packaging>jar</packaging>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <name>PermissionSigns</name>
 | 
					    <name>PermissionSigns</name>
 | 
				
			||||||
@@ -73,7 +73,7 @@
 | 
				
			|||||||
        <dependency>
 | 
					        <dependency>
 | 
				
			||||||
            <groupId>org.spigotmc</groupId>
 | 
					            <groupId>org.spigotmc</groupId>
 | 
				
			||||||
            <artifactId>spigot-api</artifactId>
 | 
					            <artifactId>spigot-api</artifactId>
 | 
				
			||||||
            <version>1.20.1-R0.1-SNAPSHOT</version>
 | 
					            <version>1.20.4-R0.1-SNAPSHOT</version>
 | 
				
			||||||
            <scope>provided</scope>
 | 
					            <scope>provided</scope>
 | 
				
			||||||
        </dependency>
 | 
					        </dependency>
 | 
				
			||||||
        <dependency>
 | 
					        <dependency>
 | 
				
			||||||
@@ -88,5 +88,11 @@
 | 
				
			|||||||
            <version>1.7</version>
 | 
					            <version>1.7</version>
 | 
				
			||||||
            <scope>provided</scope>
 | 
					            <scope>provided</scope>
 | 
				
			||||||
        </dependency>
 | 
					        </dependency>
 | 
				
			||||||
 | 
					        <dependency>
 | 
				
			||||||
 | 
					            <groupId>net.knarcraft</groupId>
 | 
				
			||||||
 | 
					            <artifactId>knarlib</artifactId>
 | 
				
			||||||
 | 
					            <version>1.2.4</version>
 | 
				
			||||||
 | 
					            <scope>compile</scope>
 | 
				
			||||||
 | 
					        </dependency>
 | 
				
			||||||
    </dependencies>
 | 
					    </dependencies>
 | 
				
			||||||
</project>
 | 
					</project>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,8 @@ import org.jetbrains.annotations.NotNull;
 | 
				
			|||||||
public class AboutCommand implements CommandExecutor {
 | 
					public class AboutCommand implements CommandExecutor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
 | 
					    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 +
 | 
					        sender.sendMessage(StringFormatter.formatInfoMessage("Permission Signs plugin created by " + ChatColor.GOLD +
 | 
				
			||||||
                "EpicKnarvik97"));
 | 
					                "EpicKnarvik97"));
 | 
				
			||||||
        sender.sendMessage(StringFormatter.formatInfoMessage("Plugin version: " + PermissionSigns.getPluginVersion()));
 | 
					        sender.sendMessage(StringFormatter.formatInfoMessage("Plugin version: " + PermissionSigns.getPluginVersion()));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,8 @@ import org.jetbrains.annotations.NotNull;
 | 
				
			|||||||
public class CancelCommand implements CommandExecutor {
 | 
					public class CancelCommand implements CommandExecutor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
 | 
				
			||||||
 | 
					                             @NotNull String[] args) {
 | 
				
			||||||
        if (sender instanceof Player player) {
 | 
					        if (sender instanceof Player player) {
 | 
				
			||||||
            if (sender.hasPermission("permissionsigns.admin.create")) {
 | 
					            if (sender.hasPermission("permissionsigns.admin.create")) {
 | 
				
			||||||
                PermissionSigns.cancelSignCreationRequest(player.getUniqueId());
 | 
					                PermissionSigns.cancelSignCreationRequest(player.getUniqueId());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,10 +19,12 @@ import java.util.List;
 | 
				
			|||||||
public class CreateCommand implements CommandExecutor {
 | 
					public class CreateCommand implements CommandExecutor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
 | 
				
			||||||
 | 
					                             @NotNull String[] args) {
 | 
				
			||||||
        // /ps create <name> <permission,permission> <cost> <duration> to create a new permission-sign
 | 
					        // /ps create <name> <permission,permission> <cost> <duration> to create a new permission-sign
 | 
				
			||||||
        //Name and permission(s) required, but duration and cost optional
 | 
					        //Name and permission(s) required, but duration and cost optional
 | 
				
			||||||
        String usage = "/ps create <name> <description> <permission,permission> [cost] [duration] - Used for creating a new permission sign";
 | 
					        String usage = "/ps create <name> <description> <permission,permission> [cost] [duration] - Used for creating" +
 | 
				
			||||||
 | 
					                " a new permission sign";
 | 
				
			||||||
        if (!(sender instanceof Player)) {
 | 
					        if (!(sender instanceof Player)) {
 | 
				
			||||||
            sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COMMAND_PLAYER_ONLY));
 | 
					            sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COMMAND_PLAYER_ONLY));
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
@@ -101,7 +103,7 @@ public class CreateCommand implements CommandExecutor {
 | 
				
			|||||||
     * @param description <p>The description to replace underscores in</p>
 | 
					     * @param description <p>The description to replace underscores in</p>
 | 
				
			||||||
     * @return <p>The string with underscores replaced</p>
 | 
					     * @return <p>The string with underscores replaced</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private String replaceUnderscoresWithSpaces(String description) {
 | 
					    private @NotNull String replaceUnderscoresWithSpaces(@NotNull String description) {
 | 
				
			||||||
        String temporaryString = "\\|ESCAPED-UNDERSCORE\\|";
 | 
					        String temporaryString = "\\|ESCAPED-UNDERSCORE\\|";
 | 
				
			||||||
        description = description.replaceAll("\\\\_", temporaryString);
 | 
					        description = description.replaceAll("\\\\_", temporaryString);
 | 
				
			||||||
        description = description.replaceAll("_", " ");
 | 
					        description = description.replaceAll("_", " ");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,7 @@ public class CreateTabCompleter implements TabCompleter {
 | 
				
			|||||||
     * @param typedNode <p>The full permission node typed by the player</p>
 | 
					     * @param typedNode <p>The full permission node typed by the player</p>
 | 
				
			||||||
     * @return <p>All known valid auto-complete options</p>
 | 
					     * @return <p>All known valid auto-complete options</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private List<String> tabCompletePermission(String typedNode) {
 | 
					    private @NotNull List<String> tabCompletePermission(@NotNull String typedNode) {
 | 
				
			||||||
        StringBuilder permissionListString = new StringBuilder();
 | 
					        StringBuilder permissionListString = new StringBuilder();
 | 
				
			||||||
        if (typedNode.contains(",")) {
 | 
					        if (typedNode.contains(",")) {
 | 
				
			||||||
            String[] permissionList = typedNode.split(",");
 | 
					            String[] permissionList = typedNode.split(",");
 | 
				
			||||||
@@ -110,7 +110,7 @@ public class CreateTabCompleter implements TabCompleter {
 | 
				
			|||||||
     * @param typedText <p>The text the player has started typing</p>
 | 
					     * @param typedText <p>The text the player has started typing</p>
 | 
				
			||||||
     * @return <p>The given string values which start with the player's typed text</p>
 | 
					     * @return <p>The given string values which start with the player's typed text</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private List<String> filterMatching(List<String> values, String typedText) {
 | 
					    private @NotNull List<String> filterMatching(@NotNull List<String> values, @NotNull String typedText) {
 | 
				
			||||||
        List<String> configValues = new ArrayList<>();
 | 
					        List<String> configValues = new ArrayList<>();
 | 
				
			||||||
        for (String value : values) {
 | 
					        for (String value : values) {
 | 
				
			||||||
            if (value.toLowerCase().startsWith(typedText.toLowerCase())) {
 | 
					            if (value.toLowerCase().startsWith(typedText.toLowerCase())) {
 | 
				
			||||||
@@ -137,7 +137,7 @@ public class CreateTabCompleter implements TabCompleter {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param permissionName <p>The permission to load</p>
 | 
					     * @param permissionName <p>The permission to load</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static void loadPermission(String permissionName) {
 | 
					    private static void loadPermission(@NotNull String permissionName) {
 | 
				
			||||||
        String[] permissionParts = permissionName.split("\\.");
 | 
					        String[] permissionParts = permissionName.split("\\.");
 | 
				
			||||||
        if (permissionParts.length == 1 && !plugins.contains(permissionParts[0])) {
 | 
					        if (permissionParts.length == 1 && !plugins.contains(permissionParts[0])) {
 | 
				
			||||||
            plugins.add(permissionParts[0]);
 | 
					            plugins.add(permissionParts[0]);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,8 @@ import java.util.Arrays;
 | 
				
			|||||||
public class PermissionSignsCommand implements CommandExecutor {
 | 
					public class PermissionSignsCommand implements CommandExecutor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
 | 
				
			||||||
 | 
					                             @NotNull String[] args) {
 | 
				
			||||||
        if (args.length > 0) {
 | 
					        if (args.length > 0) {
 | 
				
			||||||
            if (args[0].equalsIgnoreCase("create")) {
 | 
					            if (args[0].equalsIgnoreCase("create")) {
 | 
				
			||||||
                String[] subArgs = Arrays.copyOfRange(args, 1, args.length);
 | 
					                String[] subArgs = Arrays.copyOfRange(args, 1, args.length);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,8 @@ import java.util.List;
 | 
				
			|||||||
public class PermissionSignsTabCompleter implements TabCompleter {
 | 
					public class PermissionSignsTabCompleter implements TabCompleter {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
 | 
					    public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias,
 | 
				
			||||||
 | 
					                                      @NotNull String[] args) {
 | 
				
			||||||
        if (args.length == 1) {
 | 
					        if (args.length == 1) {
 | 
				
			||||||
            List<String> commands = getAvailableCommands(sender);
 | 
					            List<String> commands = getAvailableCommands(sender);
 | 
				
			||||||
            List<String> matchingCommands = new ArrayList<>();
 | 
					            List<String> matchingCommands = new ArrayList<>();
 | 
				
			||||||
@@ -40,7 +41,7 @@ public class PermissionSignsTabCompleter implements TabCompleter {
 | 
				
			|||||||
     * @param commandSender <p>The command sender to get available commands for</p>
 | 
					     * @param commandSender <p>The command sender to get available commands for</p>
 | 
				
			||||||
     * @return <p>The commands available to the command sender</p>
 | 
					     * @return <p>The commands available to the command sender</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private List<String> getAvailableCommands(CommandSender commandSender) {
 | 
					    private List<String> getAvailableCommands(@NotNull CommandSender commandSender) {
 | 
				
			||||||
        List<String> commands = new ArrayList<>();
 | 
					        List<String> commands = new ArrayList<>();
 | 
				
			||||||
        commands.add("about");
 | 
					        commands.add("about");
 | 
				
			||||||
        if (!(commandSender instanceof Player player) || player.hasPermission("permissionsigns.admin.reload")) {
 | 
					        if (!(commandSender instanceof Player player) || player.hasPermission("permissionsigns.admin.reload")) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,8 @@ import org.jetbrains.annotations.NotNull;
 | 
				
			|||||||
public class ReloadCommand implements CommandExecutor {
 | 
					public class ReloadCommand implements CommandExecutor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
 | 
					    public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
 | 
				
			||||||
 | 
					                             @NotNull String[] args) {
 | 
				
			||||||
        if (sender.hasPermission("permissionsigns.admin.reload")) {
 | 
					        if (sender.hasPermission("permissionsigns.admin.reload")) {
 | 
				
			||||||
            SignManager.loadSigns();
 | 
					            SignManager.loadSigns();
 | 
				
			||||||
            PermissionManager.loadTemporaryPermissions();
 | 
					            PermissionManager.loadTemporaryPermissions();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,8 @@ import net.knarcraft.permissionsigns.formatting.TranslatableMessage;
 | 
				
			|||||||
import net.knarcraft.permissionsigns.formatting.Translator;
 | 
					import net.knarcraft.permissionsigns.formatting.Translator;
 | 
				
			||||||
import net.knarcraft.permissionsigns.manager.EconomyManager;
 | 
					import net.knarcraft.permissionsigns.manager.EconomyManager;
 | 
				
			||||||
import org.bukkit.Location;
 | 
					import org.bukkit.Location;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.Collections;
 | 
					import java.util.Collections;
 | 
				
			||||||
@@ -38,8 +40,8 @@ public class PermissionSign {
 | 
				
			|||||||
     * @param duration        <p>The duration, in seconds, until the permission should be revoked. 0 for non-temporary</p>
 | 
					     * @param duration        <p>The duration, in seconds, until the permission should be revoked. 0 for non-temporary</p>
 | 
				
			||||||
     * @param cost            <p>The cost of using this permission sign</p>
 | 
					     * @param cost            <p>The cost of using this permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public PermissionSign(Location signLocation, String name, String description, List<String> permissionNodes,
 | 
					    public PermissionSign(@NotNull Location signLocation, @NotNull String name, @NotNull String description,
 | 
				
			||||||
                          int duration, double cost) {
 | 
					                          @NotNull List<String> permissionNodes, int duration, double cost) {
 | 
				
			||||||
        this.signLocation = signLocation;
 | 
					        this.signLocation = signLocation;
 | 
				
			||||||
        this.name = name;
 | 
					        this.name = name;
 | 
				
			||||||
        this.description = description;
 | 
					        this.description = description;
 | 
				
			||||||
@@ -59,7 +61,8 @@ public class PermissionSign {
 | 
				
			|||||||
     * @param duration        <p>The duration, in seconds, until the permission should be revoked. 0 for non-temporary</p>
 | 
					     * @param duration        <p>The duration, in seconds, until the permission should be revoked. 0 for non-temporary</p>
 | 
				
			||||||
     * @param cost            <p>The cost of using this permission sign</p>
 | 
					     * @param cost            <p>The cost of using this permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public PermissionSign(String name, String description, List<String> permissionNodes, int duration, double cost) {
 | 
					    public PermissionSign(@NotNull String name, @NotNull String description, @NotNull List<String> permissionNodes,
 | 
				
			||||||
 | 
					                          int duration, double cost) {
 | 
				
			||||||
        this.name = name;
 | 
					        this.name = name;
 | 
				
			||||||
        this.description = description;
 | 
					        this.description = description;
 | 
				
			||||||
        this.permissionNodes = new ArrayList<>(permissionNodes);
 | 
					        this.permissionNodes = new ArrayList<>(permissionNodes);
 | 
				
			||||||
@@ -72,7 +75,7 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param signLocation <p>>The location of this permission sign's actual sign</p>
 | 
					     * @param signLocation <p>>The location of this permission sign's actual sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public void setSignLocation(Location signLocation) {
 | 
					    public void setSignLocation(@NotNull Location signLocation) {
 | 
				
			||||||
        if (this.signLocation == null) {
 | 
					        if (this.signLocation == null) {
 | 
				
			||||||
            this.signLocation = signLocation;
 | 
					            this.signLocation = signLocation;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -87,7 +90,7 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The location of this permission sign</p>
 | 
					     * @return <p>The location of this permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public Location getSignLocation() {
 | 
					    public @NotNull Location getSignLocation() {
 | 
				
			||||||
        return signLocation;
 | 
					        return signLocation;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -96,7 +99,7 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The name of this permission sign</p>
 | 
					     * @return <p>The name of this permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String getName() {
 | 
					    public @NotNull String getName() {
 | 
				
			||||||
        return name;
 | 
					        return name;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -105,7 +108,7 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The description of this permission sign</p>
 | 
					     * @return <p>The description of this permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String getDescription() {
 | 
					    public @NotNull String getDescription() {
 | 
				
			||||||
        return description;
 | 
					        return description;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -114,7 +117,7 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The permission nodes granted by this permission sign</p>
 | 
					     * @return <p>The permission nodes granted by this permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public List<String> getPermissionNodes() {
 | 
					    public @NotNull List<String> getPermissionNodes() {
 | 
				
			||||||
        return new ArrayList<>(this.permissionNodes);
 | 
					        return new ArrayList<>(this.permissionNodes);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -143,7 +146,7 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The lines used to draw this permission sign</p>
 | 
					     * @return <p>The lines used to draw this permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String[] getSignLines() {
 | 
					    public @NotNull String[] getSignLines() {
 | 
				
			||||||
        String[] lines = new String[4];
 | 
					        String[] lines = new String[4];
 | 
				
			||||||
        lines[0] = Translator.getTranslatedMessage(TranslatableMessage.SIGN_PREFIX);
 | 
					        lines[0] = Translator.getTranslatedMessage(TranslatableMessage.SIGN_PREFIX);
 | 
				
			||||||
        lines[1] = replacePlaceholder(Translator.getTranslatedMessage(
 | 
					        lines[1] = replacePlaceholder(Translator.getTranslatedMessage(
 | 
				
			||||||
@@ -154,7 +157,7 @@ public class PermissionSign {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean equals(Object other) {
 | 
					    public boolean equals(@Nullable Object other) {
 | 
				
			||||||
        if (!(other instanceof PermissionSign)) {
 | 
					        if (!(other instanceof PermissionSign)) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -170,7 +173,7 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The string used for displaying this sign's duration</p>
 | 
					     * @return <p>The string used for displaying this sign's duration</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String getDurationString() {
 | 
					    public @NotNull String getDurationString() {
 | 
				
			||||||
        if (duration == 0) {
 | 
					        if (duration == 0) {
 | 
				
			||||||
            return Translator.getTranslatedMessage(TranslatableMessage.SIGN_PERMANENT);
 | 
					            return Translator.getTranslatedMessage(TranslatableMessage.SIGN_PERMANENT);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -193,7 +196,7 @@ public class PermissionSign {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The string used for displaying this sign's cost</p>
 | 
					     * @return <p>The string used for displaying this sign's cost</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String getCostString() {
 | 
					    public @NotNull String getCostString() {
 | 
				
			||||||
        if (cost == 0) {
 | 
					        if (cost == 0) {
 | 
				
			||||||
            return Translator.getTranslatedMessage(TranslatableMessage.SIGN_COST_FREE);
 | 
					            return Translator.getTranslatedMessage(TranslatableMessage.SIGN_COST_FREE);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@@ -219,7 +222,8 @@ public class PermissionSign {
 | 
				
			|||||||
     * @param castToInt           <p>Whether to cast the duration to an int</p>
 | 
					     * @param castToInt           <p>Whether to cast the duration to an int</p>
 | 
				
			||||||
     * @return <p>The formatted duration string</p>
 | 
					     * @return <p>The formatted duration string</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private String formatDurationString(double duration, TranslatableMessage translatableMessage, boolean castToInt) {
 | 
					    private @NotNull String formatDurationString(double duration, @NotNull TranslatableMessage translatableMessage,
 | 
				
			||||||
 | 
					                                                 boolean castToInt) {
 | 
				
			||||||
        String durationFormat = Translator.getTranslatedMessage(TranslatableMessage.SIGN_DURATION_FORMAT);
 | 
					        String durationFormat = Translator.getTranslatedMessage(TranslatableMessage.SIGN_DURATION_FORMAT);
 | 
				
			||||||
        durationFormat = replacePlaceholder(durationFormat, "{unit}",
 | 
					        durationFormat = replacePlaceholder(durationFormat, "{unit}",
 | 
				
			||||||
                Translator.getTranslatedMessage(translatableMessage));
 | 
					                Translator.getTranslatedMessage(translatableMessage));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,8 @@
 | 
				
			|||||||
package net.knarcraft.permissionsigns.container;
 | 
					package net.knarcraft.permissionsigns.container;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A sign creation request represents the state where a player has used the create command, but not clicked a sign
 | 
					 * A sign creation request represents the state where a player has used the create command, but not clicked a sign
 | 
				
			||||||
@@ -18,7 +20,7 @@ public class SignCreationRequest implements Comparable<SignCreationRequest> {
 | 
				
			|||||||
     * @param player         <p>The player starting to create the permission sign</p>
 | 
					     * @param player         <p>The player starting to create the permission sign</p>
 | 
				
			||||||
     * @param initiationTime <p>The time the request was initiated</p>
 | 
					     * @param initiationTime <p>The time the request was initiated</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public SignCreationRequest(PermissionSign permissionSign, Player player, long initiationTime) {
 | 
					    public SignCreationRequest(@NotNull PermissionSign permissionSign, @NotNull Player player, long initiationTime) {
 | 
				
			||||||
        this.permissionSign = permissionSign;
 | 
					        this.permissionSign = permissionSign;
 | 
				
			||||||
        this.player = player;
 | 
					        this.player = player;
 | 
				
			||||||
        this.initiationTime = initiationTime;
 | 
					        this.initiationTime = initiationTime;
 | 
				
			||||||
@@ -29,7 +31,7 @@ public class SignCreationRequest implements Comparable<SignCreationRequest> {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The involved permission sign</p>
 | 
					     * @return <p>The involved permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public PermissionSign getPermissionSign() {
 | 
					    public @NotNull PermissionSign getPermissionSign() {
 | 
				
			||||||
        return this.permissionSign;
 | 
					        return this.permissionSign;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,7 +40,7 @@ public class SignCreationRequest implements Comparable<SignCreationRequest> {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The involved player</p>
 | 
					     * @return <p>The involved player</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public Player getPlayer() {
 | 
					    public @NotNull Player getPlayer() {
 | 
				
			||||||
        return this.player;
 | 
					        return this.player;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,7 +54,7 @@ public class SignCreationRequest implements Comparable<SignCreationRequest> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public boolean equals(Object other) {
 | 
					    public boolean equals(@Nullable Object other) {
 | 
				
			||||||
        if (!(other instanceof SignCreationRequest otherRequest)) {
 | 
					        if (!(other instanceof SignCreationRequest otherRequest)) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -64,7 +66,7 @@ public class SignCreationRequest implements Comparable<SignCreationRequest> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public int compareTo(SignCreationRequest other) {
 | 
					    public int compareTo(@NotNull SignCreationRequest other) {
 | 
				
			||||||
        return (int) (this.initiationTime - other.initiationTime);
 | 
					        return (int) (this.initiationTime - other.initiationTime);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ package net.knarcraft.permissionsigns.container;
 | 
				
			|||||||
import org.bukkit.OfflinePlayer;
 | 
					import org.bukkit.OfflinePlayer;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.jetbrains.annotations.NotNull;
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A temporary permission that needs to be removed after a given duration
 | 
					 * A temporary permission that needs to be removed after a given duration
 | 
				
			||||||
@@ -23,7 +24,8 @@ public class TemporaryPermission implements Comparable<TemporaryPermission> {
 | 
				
			|||||||
     * @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>
 | 
				
			||||||
     * @param world          <p>The world the permission should be added to</p>
 | 
					     * @param world          <p>The world the permission should be added to</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public TemporaryPermission(Player player, String permissionNode, int duration, String world) {
 | 
					    public TemporaryPermission(@NotNull Player player, @NotNull String permissionNode, int duration,
 | 
				
			||||||
 | 
					                               @Nullable String world) {
 | 
				
			||||||
        grantedTime = System.currentTimeMillis();
 | 
					        grantedTime = System.currentTimeMillis();
 | 
				
			||||||
        this.grantedPlayer = player;
 | 
					        this.grantedPlayer = player;
 | 
				
			||||||
        this.permissionNode = permissionNode;
 | 
					        this.permissionNode = permissionNode;
 | 
				
			||||||
@@ -40,7 +42,8 @@ public class TemporaryPermission implements Comparable<TemporaryPermission> {
 | 
				
			|||||||
     * @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>
 | 
				
			||||||
     * @param world          <p>The world the permission should be added to</p>
 | 
					     * @param world          <p>The world the permission should be added to</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public TemporaryPermission(OfflinePlayer player, String permissionNode, long grantedTime, int duration, String world) {
 | 
					    public TemporaryPermission(@NotNull OfflinePlayer player, @NotNull String permissionNode, long grantedTime,
 | 
				
			||||||
 | 
					                               int duration, @Nullable String world) {
 | 
				
			||||||
        this.grantedPlayer = player;
 | 
					        this.grantedPlayer = player;
 | 
				
			||||||
        this.permissionNode = permissionNode;
 | 
					        this.permissionNode = permissionNode;
 | 
				
			||||||
        this.grantedTime = grantedTime;
 | 
					        this.grantedTime = grantedTime;
 | 
				
			||||||
@@ -71,7 +74,7 @@ public class TemporaryPermission implements Comparable<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 @NotNull OfflinePlayer getGrantedPlayer() {
 | 
				
			||||||
        return grantedPlayer;
 | 
					        return grantedPlayer;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,7 +83,7 @@ public class TemporaryPermission implements Comparable<TemporaryPermission> {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The permission node that was granted to this player</p>
 | 
					     * @return <p>The permission node that was granted to this player</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String getPermissionNode() {
 | 
					    public @NotNull String getPermissionNode() {
 | 
				
			||||||
        return permissionNode;
 | 
					        return permissionNode;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -89,7 +92,7 @@ public class TemporaryPermission implements Comparable<TemporaryPermission> {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The world the permission node should be added to</p>
 | 
					     * @return <p>The world the permission node should be added to</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public String getWorld() {
 | 
					    public @Nullable String getWorld() {
 | 
				
			||||||
        return world;
 | 
					        return world;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package net.knarcraft.permissionsigns.formatting;
 | 
					package net.knarcraft.permissionsigns.formatting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.md_5.bungee.api.ChatColor;
 | 
					import net.md_5.bungee.api.ChatColor;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.regex.Matcher;
 | 
					import java.util.regex.Matcher;
 | 
				
			||||||
import java.util.regex.Pattern;
 | 
					import java.util.regex.Pattern;
 | 
				
			||||||
@@ -18,7 +19,8 @@ public class StringFormatter {
 | 
				
			|||||||
     * @param replacement <p>The replacement value</p>
 | 
					     * @param replacement <p>The replacement value</p>
 | 
				
			||||||
     * @return <p>The input string with the placeholder replaced</p>
 | 
					     * @return <p>The input string with the placeholder replaced</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String replacePlaceholder(String input, String placeholder, String replacement) {
 | 
					    public static @NotNull String replacePlaceholder(@NotNull String input, @NotNull String placeholder,
 | 
				
			||||||
 | 
					                                                     @NotNull String replacement) {
 | 
				
			||||||
        return input.replace(placeholder, replacement);
 | 
					        return input.replace(placeholder, replacement);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,7 +32,8 @@ public class StringFormatter {
 | 
				
			|||||||
     * @param replacements <p>The replacement values</p>
 | 
					     * @param replacements <p>The replacement values</p>
 | 
				
			||||||
     * @return <p>The input string with placeholders replaced</p>
 | 
					     * @return <p>The input string with placeholders replaced</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String replacePlaceholders(String input, String[] placeholders, String[] replacements) {
 | 
					    public static @NotNull String replacePlaceholders(@NotNull String input, @NotNull String[] placeholders,
 | 
				
			||||||
 | 
					                                                      @NotNull String[] replacements) {
 | 
				
			||||||
        for (int i = 0; i < Math.min(placeholders.length, replacements.length); i++) {
 | 
					        for (int i = 0; i < Math.min(placeholders.length, replacements.length); i++) {
 | 
				
			||||||
            input = replacePlaceholder(input, placeholders[i], replacements[i]);
 | 
					            input = replacePlaceholder(input, placeholders[i], replacements[i]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -43,7 +46,7 @@ public class StringFormatter {
 | 
				
			|||||||
     * @param translatableMessage <p>The translatable message to translate and format</p>
 | 
					     * @param translatableMessage <p>The translatable message to translate and format</p>
 | 
				
			||||||
     * @return <p>The translated and formatted message</p>
 | 
					     * @return <p>The translated and formatted message</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String getTranslatedInfoMessage(TranslatableMessage translatableMessage) {
 | 
					    public static @NotNull String getTranslatedInfoMessage(@NotNull TranslatableMessage translatableMessage) {
 | 
				
			||||||
        return formatInfoMessage(Translator.getTranslatedMessage(translatableMessage));
 | 
					        return formatInfoMessage(Translator.getTranslatedMessage(translatableMessage));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,7 +56,7 @@ public class StringFormatter {
 | 
				
			|||||||
     * @param translatableMessage <p>The translatable message to translate and format</p>
 | 
					     * @param translatableMessage <p>The translatable message to translate and format</p>
 | 
				
			||||||
     * @return <p>The translated and formatted message</p>
 | 
					     * @return <p>The translated and formatted message</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String getTranslatedErrorMessage(TranslatableMessage translatableMessage) {
 | 
					    public static @NotNull String getTranslatedErrorMessage(@NotNull TranslatableMessage translatableMessage) {
 | 
				
			||||||
        return formatErrorMessage(Translator.getTranslatedMessage(translatableMessage));
 | 
					        return formatErrorMessage(Translator.getTranslatedMessage(translatableMessage));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,7 +66,7 @@ public class StringFormatter {
 | 
				
			|||||||
     * @param message <p>The message to format</p>
 | 
					     * @param message <p>The message to format</p>
 | 
				
			||||||
     * @return <p>The formatted message</p>
 | 
					     * @return <p>The formatted message</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String formatInfoMessage(String message) {
 | 
					    public static @NotNull String formatInfoMessage(@NotNull String message) {
 | 
				
			||||||
        return ChatColor.DARK_GREEN + formatMessage(message);
 | 
					        return ChatColor.DARK_GREEN + formatMessage(message);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -73,7 +76,7 @@ public class StringFormatter {
 | 
				
			|||||||
     * @param message <p>The message to format</p>
 | 
					     * @param message <p>The message to format</p>
 | 
				
			||||||
     * @return <p>The formatted message</p>
 | 
					     * @return <p>The formatted message</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String formatErrorMessage(String message) {
 | 
					    public static @NotNull String formatErrorMessage(@NotNull String message) {
 | 
				
			||||||
        return ChatColor.DARK_RED + formatMessage(message);
 | 
					        return ChatColor.DARK_RED + formatMessage(message);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -83,7 +86,7 @@ public class StringFormatter {
 | 
				
			|||||||
     * @param message <p>The message to format</p>
 | 
					     * @param message <p>The message to format</p>
 | 
				
			||||||
     * @return <p>The formatted message</p>
 | 
					     * @return <p>The formatted message</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static String formatMessage(String message) {
 | 
					    private static @NotNull String formatMessage(@NotNull String message) {
 | 
				
			||||||
        return Translator.getTranslatedMessage(TranslatableMessage.PREFIX) + " " +
 | 
					        return Translator.getTranslatedMessage(TranslatableMessage.PREFIX) + " " +
 | 
				
			||||||
                ChatColor.RESET + message;
 | 
					                ChatColor.RESET + message;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -94,7 +97,7 @@ public class StringFormatter {
 | 
				
			|||||||
     * @param message <p>The string to search for color codes</p>
 | 
					     * @param message <p>The string to search for color codes</p>
 | 
				
			||||||
     * @return <p>The message with color codes translated</p>
 | 
					     * @return <p>The message with color codes translated</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String translateAllColorCodes(String message) {
 | 
					    public static @NotNull String translateAllColorCodes(@NotNull String message) {
 | 
				
			||||||
        message = ChatColor.translateAlternateColorCodes('&', message);
 | 
					        message = ChatColor.translateAlternateColorCodes('&', message);
 | 
				
			||||||
        Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})");
 | 
					        Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})");
 | 
				
			||||||
        Matcher matcher = pattern.matcher(message);
 | 
					        Matcher matcher = pattern.matcher(message);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,8 @@ package net.knarcraft.permissionsigns.formatting;
 | 
				
			|||||||
import net.knarcraft.permissionsigns.PermissionSigns;
 | 
					import net.knarcraft.permissionsigns.PermissionSigns;
 | 
				
			||||||
import net.knarcraft.permissionsigns.utility.FileHelper;
 | 
					import net.knarcraft.permissionsigns.utility.FileHelper;
 | 
				
			||||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
					import org.bukkit.configuration.file.YamlConfiguration;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.BufferedReader;
 | 
					import java.io.BufferedReader;
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
@@ -29,7 +31,7 @@ public final class Translator {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Loads the languages used by this translator
 | 
					     * Loads the languages used by this translator
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void loadLanguages(String selectedLanguage) {
 | 
					    public static void loadLanguages(@NotNull String selectedLanguage) {
 | 
				
			||||||
        backupTranslatedMessages = loadTranslatedMessages("en");
 | 
					        backupTranslatedMessages = loadTranslatedMessages("en");
 | 
				
			||||||
        translatedMessages = loadCustomTranslatedMessages(selectedLanguage);
 | 
					        translatedMessages = loadCustomTranslatedMessages(selectedLanguage);
 | 
				
			||||||
        if (translatedMessages == null) {
 | 
					        if (translatedMessages == null) {
 | 
				
			||||||
@@ -43,7 +45,7 @@ public final class Translator {
 | 
				
			|||||||
     * @param translatableMessage <p>The message to translate</p>
 | 
					     * @param translatableMessage <p>The message to translate</p>
 | 
				
			||||||
     * @return <p>The translated message</p>
 | 
					     * @return <p>The translated message</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String getTranslatedMessage(TranslatableMessage translatableMessage) {
 | 
					    public static @NotNull String getTranslatedMessage(@NotNull TranslatableMessage translatableMessage) {
 | 
				
			||||||
        if (translatedMessages == null) {
 | 
					        if (translatedMessages == null) {
 | 
				
			||||||
            return "Translated strings not loaded";
 | 
					            return "Translated strings not loaded";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -64,7 +66,7 @@ public final class Translator {
 | 
				
			|||||||
     * @param language <p>The language chosen by the user</p>
 | 
					     * @param language <p>The language chosen by the user</p>
 | 
				
			||||||
     * @return <p>A mapping of all strings for the given language</p>
 | 
					     * @return <p>A mapping of all strings for the given language</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static Map<TranslatableMessage, String> loadTranslatedMessages(String language) {
 | 
					    public static @Nullable Map<TranslatableMessage, String> loadTranslatedMessages(@NotNull String language) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            BufferedReader reader = FileHelper.getBufferedReaderForInternalFile("/strings.yml");
 | 
					            BufferedReader reader = FileHelper.getBufferedReaderForInternalFile("/strings.yml");
 | 
				
			||||||
            return loadTranslatableMessages(language, reader);
 | 
					            return loadTranslatableMessages(language, reader);
 | 
				
			||||||
@@ -80,7 +82,7 @@ public final class Translator {
 | 
				
			|||||||
     * @param language <p>The selected language</p>
 | 
					     * @param language <p>The selected language</p>
 | 
				
			||||||
     * @return <p>The loaded translated strings, or null if no custom language file exists</p>
 | 
					     * @return <p>The loaded translated strings, or null if no custom language file exists</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static Map<TranslatableMessage, String> loadCustomTranslatedMessages(String language) {
 | 
					    public static @Nullable Map<TranslatableMessage, String> loadCustomTranslatedMessages(@NotNull String language) {
 | 
				
			||||||
        File strings = new File(PermissionSigns.getInstance().getDataFolder(), "strings.yml");
 | 
					        File strings = new File(PermissionSigns.getInstance().getDataFolder(), "strings.yml");
 | 
				
			||||||
        if (!strings.exists()) {
 | 
					        if (!strings.exists()) {
 | 
				
			||||||
            PermissionSigns.getInstance().getLogger().log(Level.FINEST, "Strings file not found");
 | 
					            PermissionSigns.getInstance().getLogger().log(Level.FINEST, "Strings file not found");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,8 @@ import org.bukkit.event.block.BlockExplodeEvent;
 | 
				
			|||||||
import org.bukkit.event.block.BlockPistonExtendEvent;
 | 
					import org.bukkit.event.block.BlockPistonExtendEvent;
 | 
				
			||||||
import org.bukkit.event.block.BlockPistonRetractEvent;
 | 
					import org.bukkit.event.block.BlockPistonRetractEvent;
 | 
				
			||||||
import org.bukkit.event.entity.EntityExplodeEvent;
 | 
					import org.bukkit.event.entity.EntityExplodeEvent;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
@@ -33,27 +35,27 @@ import static net.knarcraft.permissionsigns.PermissionSigns.extensiveSignProtect
 | 
				
			|||||||
public class BlockListener implements Listener {
 | 
					public class BlockListener implements Listener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.LOWEST)
 | 
					    @EventHandler(priority = EventPriority.LOWEST)
 | 
				
			||||||
    public void onPistonExtend(BlockPistonExtendEvent event) {
 | 
					    public void onPistonExtend(@NotNull BlockPistonExtendEvent event) {
 | 
				
			||||||
        preventDestruction(event.getBlocks(), event);
 | 
					        preventDestruction(event.getBlocks(), event);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.LOWEST)
 | 
					    @EventHandler(priority = EventPriority.LOWEST)
 | 
				
			||||||
    public void onPistonRetract(BlockPistonRetractEvent event) {
 | 
					    public void onPistonRetract(@NotNull BlockPistonRetractEvent event) {
 | 
				
			||||||
        preventDestruction(event.getBlocks(), event);
 | 
					        preventDestruction(event.getBlocks(), event);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.LOWEST)
 | 
					    @EventHandler(priority = EventPriority.LOWEST)
 | 
				
			||||||
    public void onBlockExplode(BlockExplodeEvent event) {
 | 
					    public void onBlockExplode(@NotNull BlockExplodeEvent event) {
 | 
				
			||||||
        preventDestruction(event.blockList(), event);
 | 
					        preventDestruction(event.blockList(), event);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.LOWEST)
 | 
					    @EventHandler(priority = EventPriority.LOWEST)
 | 
				
			||||||
    public void onEntityExplode(EntityExplodeEvent event) {
 | 
					    public void onEntityExplode(@NotNull EntityExplodeEvent event) {
 | 
				
			||||||
        preventDestruction(event.blockList(), event);
 | 
					        preventDestruction(event.blockList(), event);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler(priority = EventPriority.LOWEST)
 | 
					    @EventHandler(priority = EventPriority.LOWEST)
 | 
				
			||||||
    public void onBlockBreak(BlockBreakEvent event) {
 | 
					    public void onBlockBreak(@NotNull BlockBreakEvent event) {
 | 
				
			||||||
        Block block = event.getBlock();
 | 
					        Block block = event.getBlock();
 | 
				
			||||||
        Player player = event.getPlayer();
 | 
					        Player player = event.getPlayer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,7 +83,8 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
     * @param player    <p>The player breaking the block</p>
 | 
					     * @param player    <p>The player breaking the block</p>
 | 
				
			||||||
     * @param direction <p>The direction to check for affected blocks</p>
 | 
					     * @param direction <p>The direction to check for affected blocks</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void protectSignsInDirection(Cancellable event, Block block, Player player, BlockFace direction) {
 | 
					    private void protectSignsInDirection(@NotNull Cancellable event, @NotNull Block block, @Nullable Player player,
 | 
				
			||||||
 | 
					                                         @NotNull BlockFace direction) {
 | 
				
			||||||
        Block directionBlock = block.getRelative(direction);
 | 
					        Block directionBlock = block.getRelative(direction);
 | 
				
			||||||
        while ((direction == BlockFace.DOWN && directionBlock.getBlockData().getMaterial() ==
 | 
					        while ((direction == BlockFace.DOWN && directionBlock.getBlockData().getMaterial() ==
 | 
				
			||||||
                Material.POINTED_DRIPSTONE) || (direction == BlockFace.UP &&
 | 
					                Material.POINTED_DRIPSTONE) || (direction == BlockFace.UP &&
 | 
				
			||||||
@@ -100,7 +103,7 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
     * @param blocks <p>The blocks affected by the event</p>
 | 
					     * @param blocks <p>The blocks affected by the event</p>
 | 
				
			||||||
     * @param event  <p>The event to cancel if a permission sign is found</p>
 | 
					     * @param event  <p>The event to cancel if a permission sign is found</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void preventDestruction(List<Block> blocks, Cancellable event) {
 | 
					    private void preventDestruction(@NotNull List<Block> blocks, @NotNull Cancellable event) {
 | 
				
			||||||
        //Don't do anything if indirect protection is disabled
 | 
					        //Don't do anything if indirect protection is disabled
 | 
				
			||||||
        if (!PermissionSigns.indirectProtectionEnabled()) {
 | 
					        if (!PermissionSigns.indirectProtectionEnabled()) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
@@ -128,7 +131,7 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
     * @param block  <p>The block to check if it's a sign</p>
 | 
					     * @param block  <p>The block to check if it's a sign</p>
 | 
				
			||||||
     * @param player <p>The player breaking the block</p>
 | 
					     * @param player <p>The player breaking the block</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void protectBlockIfPermissionSign(Cancellable event, Block block, Player player) {
 | 
					    private void protectBlockIfPermissionSign(@NotNull Cancellable event, @NotNull Block block, @Nullable Player player) {
 | 
				
			||||||
        //Protect the permission sign itself
 | 
					        //Protect the permission sign itself
 | 
				
			||||||
        Material material = block.getBlockData().getMaterial();
 | 
					        Material material = block.getBlockData().getMaterial();
 | 
				
			||||||
        if (Tag.SIGNS.isTagged(material)) {
 | 
					        if (Tag.SIGNS.isTagged(material)) {
 | 
				
			||||||
@@ -148,7 +151,7 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
     * @param block  <p>The block to check if it's a sign</p>
 | 
					     * @param block  <p>The block to check if it's a sign</p>
 | 
				
			||||||
     * @param player <p>The player breaking the block</p>
 | 
					     * @param player <p>The player breaking the block</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void lookForAdjacentPermissionSigns(Cancellable event, Block block, Player player) {
 | 
					    private void lookForAdjacentPermissionSigns(@NotNull Cancellable event, @NotNull Block block, @Nullable Player player) {
 | 
				
			||||||
        Block aboveBlock = block.getRelative(BlockFace.UP);
 | 
					        Block aboveBlock = block.getRelative(BlockFace.UP);
 | 
				
			||||||
        if (Tag.STANDING_SIGNS.isTagged(aboveBlock.getBlockData().getMaterial())) {
 | 
					        if (Tag.STANDING_SIGNS.isTagged(aboveBlock.getBlockData().getMaterial())) {
 | 
				
			||||||
            checkIfBlockIsPermissionSign(aboveBlock, player, event);
 | 
					            checkIfBlockIsPermissionSign(aboveBlock, player, event);
 | 
				
			||||||
@@ -177,7 +180,7 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
     * @param player <p>The player that caused the event</p>
 | 
					     * @param player <p>The player that caused the event</p>
 | 
				
			||||||
     * @param event  <p>The triggered event</p>
 | 
					     * @param event  <p>The triggered event</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void checkIfBlockIsPermissionSign(Block block, Player player, Cancellable event) {
 | 
					    private void checkIfBlockIsPermissionSign(@NotNull Block block, @Nullable Player player, @NotNull Cancellable event) {
 | 
				
			||||||
        Sign sign = (Sign) block.getState();
 | 
					        Sign sign = (Sign) block.getState();
 | 
				
			||||||
        boolean registered = SignManager.getSign(sign.getLocation()) != null;
 | 
					        boolean registered = SignManager.getSign(sign.getLocation()) != null;
 | 
				
			||||||
        if (!registered) {
 | 
					        if (!registered) {
 | 
				
			||||||
@@ -206,7 +209,7 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The relevant block faces for checking around a block</p>
 | 
					     * @return <p>The relevant block faces for checking around a block</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private List<BlockFace> getRelevantBlockFaces() {
 | 
					    private @NotNull List<BlockFace> getRelevantBlockFaces() {
 | 
				
			||||||
        List<BlockFace> relevantBlockFaces = new ArrayList<>();
 | 
					        List<BlockFace> relevantBlockFaces = new ArrayList<>();
 | 
				
			||||||
        relevantBlockFaces.add(BlockFace.WEST);
 | 
					        relevantBlockFaces.add(BlockFace.WEST);
 | 
				
			||||||
        relevantBlockFaces.add(BlockFace.EAST);
 | 
					        relevantBlockFaces.add(BlockFace.EAST);
 | 
				
			||||||
@@ -221,7 +224,7 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
     * @param material <p>The material to check</p>
 | 
					     * @param material <p>The material to check</p>
 | 
				
			||||||
     * @return <p>True if the material is affected by gravity</p>
 | 
					     * @return <p>True if the material is affected by gravity</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private boolean isAffectedByGravity(Material material) {
 | 
					    private boolean isAffectedByGravity(@NotNull Material material) {
 | 
				
			||||||
        //TODO: Find a better way of deciding which blocks are affected by gravity
 | 
					        //TODO: Find a better way of deciding which blocks are affected by gravity
 | 
				
			||||||
        return Tag.SAND.isTagged(material) || Tag.ANVIL.isTagged(material) || material == Material.POINTED_DRIPSTONE ||
 | 
					        return Tag.SAND.isTagged(material) || Tag.ANVIL.isTagged(material) || material == Material.POINTED_DRIPSTONE ||
 | 
				
			||||||
                Tag.STANDING_SIGNS.isTagged(material) || material == Material.DRAGON_EGG || material == Material.GRAVEL ||
 | 
					                Tag.STANDING_SIGNS.isTagged(material) || material == Material.DRAGON_EGG || material == Material.GRAVEL ||
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ import net.knarcraft.permissionsigns.manager.PermissionManager;
 | 
				
			|||||||
import org.bukkit.event.EventHandler;
 | 
					import org.bukkit.event.EventHandler;
 | 
				
			||||||
import org.bukkit.event.Listener;
 | 
					import org.bukkit.event.Listener;
 | 
				
			||||||
import org.bukkit.event.player.PlayerJoinEvent;
 | 
					import org.bukkit.event.player.PlayerJoinEvent;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.PriorityQueue;
 | 
					import java.util.PriorityQueue;
 | 
				
			||||||
import java.util.Queue;
 | 
					import java.util.Queue;
 | 
				
			||||||
@@ -15,7 +16,7 @@ import java.util.Queue;
 | 
				
			|||||||
public class PlayerListener implements Listener {
 | 
					public class PlayerListener implements Listener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
    public void onPlayerJoin(PlayerJoinEvent event) {
 | 
					    public void onPlayerJoin(@NotNull PlayerJoinEvent event) {
 | 
				
			||||||
        //Give the joining player any temporary permissions containing their UUID
 | 
					        //Give the joining player any temporary permissions containing their UUID
 | 
				
			||||||
        Queue<TemporaryPermission> temporaryPermissions = new PriorityQueue<>(PermissionManager.getTemporaryPermissions());
 | 
					        Queue<TemporaryPermission> temporaryPermissions = new PriorityQueue<>(PermissionManager.getTemporaryPermissions());
 | 
				
			||||||
        temporaryPermissions.removeIf((item) -> !item.getGrantedPlayer().getUniqueId().equals(event.getPlayer().getUniqueId()));
 | 
					        temporaryPermissions.removeIf((item) -> !item.getGrantedPlayer().getUniqueId().equals(event.getPlayer().getUniqueId()));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@ import org.bukkit.event.Listener;
 | 
				
			|||||||
import org.bukkit.event.block.Action;
 | 
					import org.bukkit.event.block.Action;
 | 
				
			||||||
import org.bukkit.event.player.PlayerInteractEvent;
 | 
					import org.bukkit.event.player.PlayerInteractEvent;
 | 
				
			||||||
import org.bukkit.inventory.EquipmentSlot;
 | 
					import org.bukkit.inventory.EquipmentSlot;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
@@ -38,7 +39,7 @@ public class SignListener implements Listener {
 | 
				
			|||||||
     * @param event <p>The player interact event which was triggered</p>
 | 
					     * @param event <p>The player interact event which was triggered</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    @EventHandler
 | 
					    @EventHandler
 | 
				
			||||||
    public void onPlayerInteract(PlayerInteractEvent event) {
 | 
					    public void onPlayerInteract(@NotNull PlayerInteractEvent event) {
 | 
				
			||||||
        Player player = event.getPlayer();
 | 
					        Player player = event.getPlayer();
 | 
				
			||||||
        Block block = event.getClickedBlock();
 | 
					        Block block = event.getClickedBlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,8 +54,6 @@ public class SignListener implements Listener {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Sign sign = (Sign) block.getState();
 | 
					        Sign sign = (Sign) block.getState();
 | 
				
			||||||
        if (event.getHand() == EquipmentSlot.HAND) {
 | 
					        if (event.getHand() == EquipmentSlot.HAND) {
 | 
				
			||||||
            // Cancel the interaction to avoid sign editing
 | 
					 | 
				
			||||||
            event.setCancelled(true);
 | 
					 | 
				
			||||||
            handleSignClick(sign, player, event.getAction(), event);
 | 
					            handleSignClick(sign, player, event.getAction(), event);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -67,7 +66,8 @@ public class SignListener implements Listener {
 | 
				
			|||||||
     * @param action <p>The hand the player used to interact with the sign</p>
 | 
					     * @param action <p>The hand the player used to interact with the sign</p>
 | 
				
			||||||
     * @param event  <p>The player interact event which was triggered</p>
 | 
					     * @param event  <p>The player interact event which was triggered</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void handleSignClick(Sign sign, Player player, Action action, PlayerInteractEvent event) {
 | 
					    private void handleSignClick(@NotNull Sign sign, @NotNull Player player, @NotNull Action action,
 | 
				
			||||||
 | 
					                                 @NotNull PlayerInteractEvent event) {
 | 
				
			||||||
        //Check if the sign is a registered permission sign
 | 
					        //Check if the sign is a registered permission sign
 | 
				
			||||||
        PermissionSign permissionSign = SignManager.getSign(sign.getLocation());
 | 
					        PermissionSign permissionSign = SignManager.getSign(sign.getLocation());
 | 
				
			||||||
        if (permissionSign != null) {
 | 
					        if (permissionSign != null) {
 | 
				
			||||||
@@ -79,9 +79,9 @@ public class SignListener implements Listener {
 | 
				
			|||||||
                player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.INTERACT_PERMISSION_MISSING));
 | 
					                player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.INTERACT_PERMISSION_MISSING));
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            //Prevent placement of any blocks, and sign clicking
 | 
				
			||||||
 | 
					            event.setCancelled(true);
 | 
				
			||||||
            if (player.isSneaking()) {
 | 
					            if (player.isSneaking()) {
 | 
				
			||||||
                //Prevent placement of any blocks
 | 
					 | 
				
			||||||
                event.setCancelled(true);
 | 
					 | 
				
			||||||
                handlePermissionSignInteract(permissionSign, player);
 | 
					                handlePermissionSignInteract(permissionSign, player);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                player.sendMessage(getSignInfoText(permissionSign));
 | 
					                player.sendMessage(getSignInfoText(permissionSign));
 | 
				
			||||||
@@ -102,7 +102,7 @@ public class SignListener implements Listener {
 | 
				
			|||||||
     * @param sign <p>The sign to get information about</p>
 | 
					     * @param sign <p>The sign to get information about</p>
 | 
				
			||||||
     * @return <p>The information to display</p>
 | 
					     * @return <p>The information to display</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private String getSignInfoText(PermissionSign sign) {
 | 
					    private String getSignInfoText(@NotNull PermissionSign sign) {
 | 
				
			||||||
        String rawSignInfo = Translator.getTranslatedMessage(TranslatableMessage.SIGN_INFO);
 | 
					        String rawSignInfo = Translator.getTranslatedMessage(TranslatableMessage.SIGN_INFO);
 | 
				
			||||||
        StringBuilder permissionString = new StringBuilder();
 | 
					        StringBuilder permissionString = new StringBuilder();
 | 
				
			||||||
        List<String> permissionNodes = sign.getPermissionNodes();
 | 
					        List<String> permissionNodes = sign.getPermissionNodes();
 | 
				
			||||||
@@ -126,7 +126,7 @@ public class SignListener implements Listener {
 | 
				
			|||||||
     * @param permissionSign <p>The permission sign that was interacted with</p>
 | 
					     * @param permissionSign <p>The permission sign that was interacted with</p>
 | 
				
			||||||
     * @param player         <p>The player that interacted with the permission sign</p>
 | 
					     * @param player         <p>The player that interacted with the permission sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void handlePermissionSignInteract(PermissionSign permissionSign, Player player) {
 | 
					    private void handlePermissionSignInteract(@NotNull PermissionSign permissionSign, @NotNull Player player) {
 | 
				
			||||||
        //Don't allow players to pay for permissions they already own
 | 
					        //Don't allow players to pay for permissions they already own
 | 
				
			||||||
        boolean hasAllPermissions = true;
 | 
					        boolean hasAllPermissions = true;
 | 
				
			||||||
        for (String permissionNode : permissionSign.getPermissionNodes()) {
 | 
					        for (String permissionNode : permissionSign.getPermissionNodes()) {
 | 
				
			||||||
@@ -157,7 +157,7 @@ public class SignListener implements Listener {
 | 
				
			|||||||
     * @param player         <p>The player to give permissions to</p>
 | 
					     * @param player         <p>The player to give permissions to</p>
 | 
				
			||||||
     * @param permissionSign <p>The permission sign the player clicked</p>
 | 
					     * @param permissionSign <p>The permission sign the player clicked</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void performPermissionTransaction(Player player, PermissionSign permissionSign) {
 | 
					    private void performPermissionTransaction(@NotNull Player player, @NotNull PermissionSign permissionSign) {
 | 
				
			||||||
        EconomyManager.withdraw(player, permissionSign.getCost());
 | 
					        EconomyManager.withdraw(player, permissionSign.getCost());
 | 
				
			||||||
        StringJoiner permissionsJoiner = new StringJoiner(", ");
 | 
					        StringJoiner permissionsJoiner = new StringJoiner(", ");
 | 
				
			||||||
        for (String permissionNode : permissionSign.getPermissionNodes()) {
 | 
					        for (String permissionNode : permissionSign.getPermissionNodes()) {
 | 
				
			||||||
@@ -197,7 +197,8 @@ public class SignListener implements Listener {
 | 
				
			|||||||
     * @param request <p>The creation request to fulfill</p>
 | 
					     * @param request <p>The creation request to fulfill</p>
 | 
				
			||||||
     * @param player  <p>The player that interacted with the sign</p>
 | 
					     * @param player  <p>The player that interacted with the sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private void registerPermissionSign(Sign sign, SignCreationRequest request, Player player) {
 | 
					    private void registerPermissionSign(@NotNull Sign sign, @NotNull SignCreationRequest request,
 | 
				
			||||||
 | 
					                                        @NotNull Player player) {
 | 
				
			||||||
        SignSide frontSide = sign.getSide(Side.FRONT);
 | 
					        SignSide frontSide = sign.getSide(Side.FRONT);
 | 
				
			||||||
        String[] lines = frontSide.getLines();
 | 
					        String[] lines = frontSide.getLines();
 | 
				
			||||||
        //Don't allow non-empty signs to be overwritten
 | 
					        //Don't allow non-empty signs to be overwritten
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ package net.knarcraft.permissionsigns.manager;
 | 
				
			|||||||
import net.milkbowl.vault.economy.Economy;
 | 
					import net.milkbowl.vault.economy.Economy;
 | 
				
			||||||
import org.bukkit.OfflinePlayer;
 | 
					import org.bukkit.OfflinePlayer;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A manager that performs all Economy tasks
 | 
					 * A manager that performs all Economy tasks
 | 
				
			||||||
@@ -20,7 +21,7 @@ public final class EconomyManager {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param economy <p>The economy object to use for everything economy-related</p>
 | 
					     * @param economy <p>The economy object to use for everything economy-related</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void initialize(Economy economy) {
 | 
					    public static void initialize(@NotNull Economy economy) {
 | 
				
			||||||
        EconomyManager.economy = economy;
 | 
					        EconomyManager.economy = economy;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -31,7 +32,7 @@ public final class EconomyManager {
 | 
				
			|||||||
     * @param cost   <p>The cost the player needs to pay</p>
 | 
					     * @param cost   <p>The cost the player needs to pay</p>
 | 
				
			||||||
     * @return <p>True if the player is able to afford the cost</p>
 | 
					     * @return <p>True if the player is able to afford the cost</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean canAfford(OfflinePlayer player, double cost) {
 | 
					    public static boolean canAfford(@NotNull OfflinePlayer player, double cost) {
 | 
				
			||||||
        return economy.has(player, cost);
 | 
					        return economy.has(player, cost);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -51,7 +52,7 @@ public final class EconomyManager {
 | 
				
			|||||||
     * @param player <p>The player to withdraw money from</p>
 | 
					     * @param player <p>The player to withdraw money from</p>
 | 
				
			||||||
     * @param cost   <p>The amount of money to withdraw</p>
 | 
					     * @param cost   <p>The amount of money to withdraw</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void withdraw(Player player, double cost) {
 | 
					    public static void withdraw(@NotNull Player player, double cost) {
 | 
				
			||||||
        economy.withdrawPlayer(player, cost);
 | 
					        economy.withdrawPlayer(player, cost);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,8 @@ import org.bukkit.OfflinePlayer;
 | 
				
			|||||||
import org.bukkit.configuration.ConfigurationSection;
 | 
					import org.bukkit.configuration.ConfigurationSection;
 | 
				
			||||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
					import org.bukkit.configuration.file.YamlConfiguration;
 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
@@ -35,7 +37,7 @@ public final class PermissionManager {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param permission <p>The permission object to use for everything permission-related</p>
 | 
					     * @param permission <p>The permission object to use for everything permission-related</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void initialize(Permission permission) {
 | 
					    public static void initialize(@NotNull Permission permission) {
 | 
				
			||||||
        PermissionManager.permission = permission;
 | 
					        PermissionManager.permission = permission;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,7 +46,7 @@ public final class PermissionManager {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @return <p>The registered temporary permissions</p>
 | 
					     * @return <p>The registered temporary permissions</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static Queue<TemporaryPermission> getTemporaryPermissions() {
 | 
					    public static @NotNull Queue<TemporaryPermission> getTemporaryPermissions() {
 | 
				
			||||||
        return temporaryPermissions;
 | 
					        return temporaryPermissions;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -54,7 +56,7 @@ public final class PermissionManager {
 | 
				
			|||||||
     * @param player         <p>The player to grant the permission to</p>
 | 
					     * @param player         <p>The player to grant the permission to</p>
 | 
				
			||||||
     * @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(@NotNull Player player, @NotNull String permissionNode) {
 | 
				
			||||||
        //Allow world:permission syntax
 | 
					        //Allow world:permission syntax
 | 
				
			||||||
        if (permissionNode.contains(":")) {
 | 
					        if (permissionNode.contains(":")) {
 | 
				
			||||||
            grantWorldPermission(player, permissionNode, false);
 | 
					            grantWorldPermission(player, permissionNode, false);
 | 
				
			||||||
@@ -71,7 +73,8 @@ public final class PermissionManager {
 | 
				
			|||||||
     * @param permissionNode <p>The permission node to grant</p>
 | 
					     * @param permissionNode <p>The permission node to grant</p>
 | 
				
			||||||
     * @param worldName      <p>The world to add the permission node to</p>
 | 
					     * @param worldName      <p>The world to add the permission node to</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void grantTemporaryPermission(Player player, String permissionNode, String worldName) {
 | 
					    public static void grantTemporaryPermission(@NotNull Player player, @NotNull String permissionNode,
 | 
				
			||||||
 | 
					                                                @Nullable String worldName) {
 | 
				
			||||||
        //Allow world:permission syntax
 | 
					        //Allow world:permission syntax
 | 
				
			||||||
        if (permissionNode.contains(":")) {
 | 
					        if (permissionNode.contains(":")) {
 | 
				
			||||||
            grantWorldPermission(player, permissionNode, true);
 | 
					            grantWorldPermission(player, permissionNode, true);
 | 
				
			||||||
@@ -88,7 +91,7 @@ public final class PermissionManager {
 | 
				
			|||||||
     * @param permissionNode <p>The permission node to grant</p>
 | 
					     * @param permissionNode <p>The permission node to grant</p>
 | 
				
			||||||
     * @param temporary      <p>Whether the permission node should be set temporarily</p>
 | 
					     * @param temporary      <p>Whether the permission node should be set temporarily</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static void grantWorldPermission(Player player, String permissionNode, boolean temporary) {
 | 
					    private static void grantWorldPermission(@NotNull Player player, @NotNull String permissionNode, boolean temporary) {
 | 
				
			||||||
        String[] permissionParts = permissionNode.split(":");
 | 
					        String[] permissionParts = permissionNode.split(":");
 | 
				
			||||||
        String world = permissionParts[0];
 | 
					        String world = permissionParts[0];
 | 
				
			||||||
        if (world.equalsIgnoreCase("all") || world.equalsIgnoreCase("any")) {
 | 
					        if (world.equalsIgnoreCase("all") || world.equalsIgnoreCase("any")) {
 | 
				
			||||||
@@ -108,7 +111,7 @@ public final 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(Player player, String permissionNode, int duration) {
 | 
					    public static void addTemporaryPermission(@NotNull Player player, @NotNull String permissionNode, int duration) {
 | 
				
			||||||
        String world = player.getWorld().getName();
 | 
					        String world = player.getWorld().getName();
 | 
				
			||||||
        grantTemporaryPermission(player, permissionNode, world);
 | 
					        grantTemporaryPermission(player, permissionNode, world);
 | 
				
			||||||
        temporaryPermissions.add(new TemporaryPermission(player, permissionNode, duration, world));
 | 
					        temporaryPermissions.add(new TemporaryPermission(player, permissionNode, duration, world));
 | 
				
			||||||
@@ -126,7 +129,7 @@ public final class PermissionManager {
 | 
				
			|||||||
     * @param offlinePlayer  <p>The player to remove the permission from</p>
 | 
					     * @param offlinePlayer  <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 offlinePlayer, String permissionNode) {
 | 
					    public static void removeTemporaryPermission(@NotNull OfflinePlayer offlinePlayer, @NotNull String permissionNode) {
 | 
				
			||||||
        Player player = offlinePlayer.getPlayer();
 | 
					        Player player = offlinePlayer.getPlayer();
 | 
				
			||||||
        if (player != null && player.hasPermission(permissionNode)) {
 | 
					        if (player != null && player.hasPermission(permissionNode)) {
 | 
				
			||||||
            permission.playerRemoveTransient(null, player, permissionNode);
 | 
					            permission.playerRemoveTransient(null, player, permissionNode);
 | 
				
			||||||
@@ -141,7 +144,7 @@ public final class PermissionManager {
 | 
				
			|||||||
     * @param world          <p>The world to check for the permission</p>
 | 
					     * @param world          <p>The world to check for the permission</p>
 | 
				
			||||||
     * @return <p>True if the player has the permission</p>
 | 
					     * @return <p>True if the player has the permission</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean hasPermission(Player player, String permissionNode, String world) {
 | 
					    public static boolean hasPermission(@NotNull Player player, @NotNull String permissionNode, @NotNull String world) {
 | 
				
			||||||
        return permission.playerHas(world, player, permissionNode);
 | 
					        return permission.playerHas(world, player, permissionNode);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -182,6 +185,11 @@ public final class PermissionManager {
 | 
				
			|||||||
            String[] identifierParts = key.split(",");
 | 
					            String[] identifierParts = key.split(",");
 | 
				
			||||||
            OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(identifierParts[0]));
 | 
					            OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(identifierParts[0]));
 | 
				
			||||||
            String permissionNode = permissionSection.getString(key + ".permissionNode");
 | 
					            String permissionNode = permissionSection.getString(key + ".permissionNode");
 | 
				
			||||||
 | 
					            if (permissionNode == null) {
 | 
				
			||||||
 | 
					                PermissionSigns.getInstance().getLogger().log(Level.WARNING, "Temporary permission " + key +
 | 
				
			||||||
 | 
					                        " has a missing permission node.");
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            long granted = Long.parseLong(identifierParts[1]);
 | 
					            long granted = Long.parseLong(identifierParts[1]);
 | 
				
			||||||
            int duration = permissionSection.getInt(key + ".duration", 1);
 | 
					            int duration = permissionSection.getInt(key + ".duration", 1);
 | 
				
			||||||
            String world = permissionSection.getString(key + ".world", null);
 | 
					            String world = permissionSection.getString(key + ".world", null);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,8 @@ import org.bukkit.block.sign.SignSide;
 | 
				
			|||||||
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;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.File;
 | 
					import java.io.File;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
@@ -42,7 +44,7 @@ public final class SignManager {
 | 
				
			|||||||
     * @param signLocation <p>The location of the permission sign to get</p>
 | 
					     * @param signLocation <p>The location of the permission sign to get</p>
 | 
				
			||||||
     * @return <p>The permission sign at the given location, or null if no such sign exists</p>
 | 
					     * @return <p>The permission sign at the given location, or null if no such sign exists</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static PermissionSign getSign(Location signLocation) {
 | 
					    public static @Nullable PermissionSign getSign(@NotNull Location signLocation) {
 | 
				
			||||||
        return managedSigns.get(signLocation);
 | 
					        return managedSigns.get(signLocation);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -51,7 +53,7 @@ public final class SignManager {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param sign <p>The sign to add</p>
 | 
					     * @param sign <p>The sign to add</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void addSign(PermissionSign sign) {
 | 
					    public static void addSign(@NotNull PermissionSign sign) {
 | 
				
			||||||
        managedSigns.put(sign.getSignLocation(), sign);
 | 
					        managedSigns.put(sign.getSignLocation(), sign);
 | 
				
			||||||
        save();
 | 
					        save();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -61,7 +63,7 @@ public final class SignManager {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param location <p>The location of the sign to remove</p>
 | 
					     * @param location <p>The location of the sign to remove</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void removeSign(Location location) {
 | 
					    public static void removeSign(@NotNull Location location) {
 | 
				
			||||||
        managedSigns.remove(location);
 | 
					        managedSigns.remove(location);
 | 
				
			||||||
        save();
 | 
					        save();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -163,7 +165,8 @@ public final class SignManager {
 | 
				
			|||||||
     * @param key         <p>The sign key which is also the sign's location</p>
 | 
					     * @param key         <p>The sign key which is also the sign's location</p>
 | 
				
			||||||
     * @throws InvalidConfigurationException <p>If unable to load the sign</p>
 | 
					     * @throws InvalidConfigurationException <p>If unable to load the sign</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static void loadSign(ConfigurationSection signSection, String key) throws InvalidConfigurationException {
 | 
					    private static void loadSign(@NotNull ConfigurationSection signSection,
 | 
				
			||||||
 | 
					                                 @NotNull String key) throws InvalidConfigurationException {
 | 
				
			||||||
        String[] locationParts = key.split(",");
 | 
					        String[] locationParts = key.split(",");
 | 
				
			||||||
        Location signLocation;
 | 
					        Location signLocation;
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
@@ -198,7 +201,8 @@ public final class SignManager {
 | 
				
			|||||||
        int duration = signSection.getInt(key + ".duration");
 | 
					        int duration = signSection.getInt(key + ".duration");
 | 
				
			||||||
        double cost = signSection.getDouble(key + ".cost");
 | 
					        double cost = signSection.getDouble(key + ".cost");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        PermissionSign loadedSign = new PermissionSign(signLocation, signName, signDescription, permissionStrings, duration, cost);
 | 
					        PermissionSign loadedSign = new PermissionSign(signLocation, signName, signDescription, permissionStrings,
 | 
				
			||||||
 | 
					                duration, cost);
 | 
				
			||||||
        managedSigns.put(signLocation, loadedSign);
 | 
					        managedSigns.put(signLocation, loadedSign);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package net.knarcraft.permissionsigns.thread;
 | 
					package net.knarcraft.permissionsigns.thread;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import net.knarcraft.permissionsigns.container.SignCreationRequest;
 | 
					import net.knarcraft.permissionsigns.container.SignCreationRequest;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.Queue;
 | 
					import java.util.Queue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,7 +17,7 @@ public class SignCreationRequestTimeoutThread implements Runnable {
 | 
				
			|||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param signCreationRequests <p>A pointer to the queue of sign creation requests</p>
 | 
					     * @param signCreationRequests <p>A pointer to the queue of sign creation requests</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public SignCreationRequestTimeoutThread(Queue<SignCreationRequest> signCreationRequests) {
 | 
					    public SignCreationRequestTimeoutThread(@NotNull Queue<SignCreationRequest> signCreationRequests) {
 | 
				
			||||||
        this.signCreationRequests = signCreationRequests;
 | 
					        this.signCreationRequests = signCreationRequests;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
package net.knarcraft.permissionsigns.utility;
 | 
					package net.knarcraft.permissionsigns.utility;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.BufferedReader;
 | 
					import java.io.BufferedReader;
 | 
				
			||||||
import java.io.FileNotFoundException;
 | 
					import java.io.FileNotFoundException;
 | 
				
			||||||
import java.io.InputStream;
 | 
					import java.io.InputStream;
 | 
				
			||||||
@@ -21,7 +23,7 @@ public final class FileHelper {
 | 
				
			|||||||
     * @return <p>A buffered read for reading the file</p>
 | 
					     * @return <p>A buffered read for reading the file</p>
 | 
				
			||||||
     * @throws FileNotFoundException <p>If unable to get an input stream for the given file</p>
 | 
					     * @throws FileNotFoundException <p>If unable to get an input stream for the given file</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static BufferedReader getBufferedReaderForInternalFile(String file) throws FileNotFoundException {
 | 
					    public static @NotNull BufferedReader getBufferedReaderForInternalFile(@NotNull String file) throws FileNotFoundException {
 | 
				
			||||||
        InputStream inputStream = FileHelper.class.getResourceAsStream(file);
 | 
					        InputStream inputStream = FileHelper.class.getResourceAsStream(file);
 | 
				
			||||||
        if (inputStream == null) {
 | 
					        if (inputStream == null) {
 | 
				
			||||||
            throw new FileNotFoundException("Unable to read the given file");
 | 
					            throw new FileNotFoundException("Unable to read the given file");
 | 
				
			||||||
@@ -35,7 +37,7 @@ public final class FileHelper {
 | 
				
			|||||||
     * @param inputStream <p>The input stream to read</p>
 | 
					     * @param inputStream <p>The input stream to read</p>
 | 
				
			||||||
     * @return <p>A buffered reader reading the input stream</p>
 | 
					     * @return <p>A buffered reader reading the input stream</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static BufferedReader getBufferedReaderFromInputStream(InputStream inputStream) {
 | 
					    public static @NotNull BufferedReader getBufferedReaderFromInputStream(@NotNull InputStream inputStream) {
 | 
				
			||||||
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
 | 
					        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
 | 
				
			||||||
        return new BufferedReader(inputStreamReader);
 | 
					        return new BufferedReader(inputStreamReader);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,8 @@ package net.knarcraft.permissionsigns.utility;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import org.bukkit.plugin.Plugin;
 | 
					import org.bukkit.plugin.Plugin;
 | 
				
			||||||
import org.bukkit.scheduler.BukkitScheduler;
 | 
					import org.bukkit.scheduler.BukkitScheduler;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.NotNull;
 | 
				
			||||||
 | 
					import org.jetbrains.annotations.Nullable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.BufferedReader;
 | 
					import java.io.BufferedReader;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
@@ -25,8 +27,9 @@ public final class UpdateChecker {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Checks if there's a new update available, and alerts the user if necessary
 | 
					     * Checks if there's a new update available, and alerts the user if necessary
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void checkForUpdate(Plugin plugin, String apiResourceURL, Supplier<String> getVersionMethod,
 | 
					    public static void checkForUpdate(@NotNull Plugin plugin, @NotNull String apiResourceURL,
 | 
				
			||||||
                                      Consumer<String> setVersionMethod) {
 | 
					                                      @NotNull Supplier<String> getVersionMethod,
 | 
				
			||||||
 | 
					                                      @Nullable Consumer<String> setVersionMethod) {
 | 
				
			||||||
        BukkitScheduler scheduler = plugin.getServer().getScheduler();
 | 
					        BukkitScheduler scheduler = plugin.getServer().getScheduler();
 | 
				
			||||||
        scheduler.runTaskAsynchronously(plugin, () -> UpdateChecker.queryAPI(plugin, apiResourceURL, getVersionMethod,
 | 
					        scheduler.runTaskAsynchronously(plugin, () -> UpdateChecker.queryAPI(plugin, apiResourceURL, getVersionMethod,
 | 
				
			||||||
                setVersionMethod));
 | 
					                setVersionMethod));
 | 
				
			||||||
@@ -35,8 +38,9 @@ public final class UpdateChecker {
 | 
				
			|||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Queries the spigot API to check for a newer version, and informs the user
 | 
					     * Queries the spigot API to check for a newer version, and informs the user
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static void queryAPI(Plugin plugin, String APIResourceURL, Supplier<String> getVersionMethod,
 | 
					    private static void queryAPI(@NotNull Plugin plugin, @NotNull String APIResourceURL,
 | 
				
			||||||
                                 Consumer<String> setVersionMethod) {
 | 
					                                 @NotNull Supplier<String> getVersionMethod,
 | 
				
			||||||
 | 
					                                 @Nullable Consumer<String> setVersionMethod) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            InputStream inputStream = new URL(APIResourceURL).openStream();
 | 
					            InputStream inputStream = new URL(APIResourceURL).openStream();
 | 
				
			||||||
            BufferedReader reader = FileHelper.getBufferedReaderFromInputStream(inputStream);
 | 
					            BufferedReader reader = FileHelper.getBufferedReaderFromInputStream(inputStream);
 | 
				
			||||||
@@ -64,7 +68,7 @@ public final class UpdateChecker {
 | 
				
			|||||||
     * @param oldVersion <p>The old (current) plugin version</p>
 | 
					     * @param oldVersion <p>The old (current) plugin version</p>
 | 
				
			||||||
     * @return <p>The string to display</p>
 | 
					     * @return <p>The string to display</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static String getUpdateAvailableString(String newVersion, String oldVersion) {
 | 
					    public static @NotNull String getUpdateAvailableString(@NotNull String newVersion, @NotNull String oldVersion) {
 | 
				
			||||||
        return String.format(updateNotice, newVersion, oldVersion);
 | 
					        return String.format(updateNotice, newVersion, oldVersion);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,7 +79,7 @@ public final class UpdateChecker {
 | 
				
			|||||||
     * @param newVersion <p>The new version to check</p>
 | 
					     * @param newVersion <p>The new version to check</p>
 | 
				
			||||||
     * @return <p>True if the new version is higher than the old one</p>
 | 
					     * @return <p>True if the new version is higher than the old one</p>
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static boolean isVersionHigher(String oldVersion, String newVersion) {
 | 
					    public static boolean isVersionHigher(@NotNull String oldVersion, @NotNull String newVersion) {
 | 
				
			||||||
        String[] oldVersionParts = oldVersion.split("\\.");
 | 
					        String[] oldVersionParts = oldVersion.split("\\.");
 | 
				
			||||||
        String[] newVersionParts = newVersion.split("\\.");
 | 
					        String[] newVersionParts = newVersion.split("\\.");
 | 
				
			||||||
        int versionLength = Math.max(oldVersionParts.length, newVersionParts.length);
 | 
					        int versionLength = Math.max(oldVersionParts.length, newVersionParts.length);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user