diff --git a/README.md b/README.md index 6ca5554..2e9ec56 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,11 @@ permission permanently by another cause) when they expire. ### The create command -/ps create \ \ \ \ \ - Creates a new permission sign. The name is +/ps create \ \ \ \ \ - 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 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 number of seconds the player should keep the permission for. Use 0 for permanent. diff --git a/pom.xml b/pom.xml index 1919568..04a2601 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ net.knarcraft PermissionSigns - 1.0.5-SNAPSHOT + 1.0.5 jar PermissionSigns @@ -73,7 +73,7 @@ org.spigotmc spigot-api - 1.20.1-R0.1-SNAPSHOT + 1.20.4-R0.1-SNAPSHOT provided @@ -88,5 +88,11 @@ 1.7 provided + + net.knarcraft + knarlib + 1.2.4 + compile + diff --git a/src/main/java/net/knarcraft/permissionsigns/command/AboutCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/AboutCommand.java index d418364..bab3f5e 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/AboutCommand.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/AboutCommand.java @@ -14,7 +14,8 @@ import org.jetbrains.annotations.NotNull; public class AboutCommand implements CommandExecutor { @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 + "EpicKnarvik97")); sender.sendMessage(StringFormatter.formatInfoMessage("Plugin version: " + PermissionSigns.getPluginVersion())); diff --git a/src/main/java/net/knarcraft/permissionsigns/command/CancelCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/CancelCommand.java index 22126d6..18ab990 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/CancelCommand.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/CancelCommand.java @@ -15,7 +15,8 @@ import org.jetbrains.annotations.NotNull; public class CancelCommand implements CommandExecutor { @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.hasPermission("permissionsigns.admin.create")) { PermissionSigns.cancelSignCreationRequest(player.getUniqueId()); diff --git a/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java index 60b7710..63f7c1c 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/CreateCommand.java @@ -19,10 +19,12 @@ import java.util.List; public class CreateCommand implements CommandExecutor { @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 to create a new permission-sign //Name and permission(s) required, but duration and cost optional - String usage = "/ps create [cost] [duration] - Used for creating a new permission sign"; + String usage = "/ps create [cost] [duration] - Used for creating" + + " a new permission sign"; if (!(sender instanceof Player)) { sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.COMMAND_PLAYER_ONLY)); return false; @@ -101,7 +103,7 @@ public class CreateCommand implements CommandExecutor { * @param description

The description to replace underscores in

* @return

The string with underscores replaced

*/ - private String replaceUnderscoresWithSpaces(String description) { + private @NotNull String replaceUnderscoresWithSpaces(@NotNull String description) { String temporaryString = "\\|ESCAPED-UNDERSCORE\\|"; description = description.replaceAll("\\\\_", temporaryString); description = description.replaceAll("_", " "); diff --git a/src/main/java/net/knarcraft/permissionsigns/command/CreateTabCompleter.java b/src/main/java/net/knarcraft/permissionsigns/command/CreateTabCompleter.java index 2b70378..1185c9d 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/CreateTabCompleter.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/CreateTabCompleter.java @@ -61,7 +61,7 @@ public class CreateTabCompleter implements TabCompleter { * @param typedNode

The full permission node typed by the player

* @return

All known valid auto-complete options

*/ - private List tabCompletePermission(String typedNode) { + private @NotNull List tabCompletePermission(@NotNull String typedNode) { StringBuilder permissionListString = new StringBuilder(); if (typedNode.contains(",")) { String[] permissionList = typedNode.split(","); @@ -110,7 +110,7 @@ public class CreateTabCompleter implements TabCompleter { * @param typedText

The text the player has started typing

* @return

The given string values which start with the player's typed text

*/ - private List filterMatching(List values, String typedText) { + private @NotNull List filterMatching(@NotNull List values, @NotNull String typedText) { List configValues = new ArrayList<>(); for (String value : values) { if (value.toLowerCase().startsWith(typedText.toLowerCase())) { @@ -137,7 +137,7 @@ public class CreateTabCompleter implements TabCompleter { * * @param permissionName

The permission to load

*/ - private static void loadPermission(String permissionName) { + private static void loadPermission(@NotNull String permissionName) { String[] permissionParts = permissionName.split("\\."); if (permissionParts.length == 1 && !plugins.contains(permissionParts[0])) { plugins.add(permissionParts[0]); diff --git a/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsCommand.java index 9a54fe5..d59fde3 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsCommand.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsCommand.java @@ -13,7 +13,8 @@ import java.util.Arrays; public class PermissionSignsCommand implements CommandExecutor { @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[0].equalsIgnoreCase("create")) { String[] subArgs = Arrays.copyOfRange(args, 1, args.length); diff --git a/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsTabCompleter.java b/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsTabCompleter.java index a0661aa..317c778 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsTabCompleter.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/PermissionSignsTabCompleter.java @@ -16,7 +16,8 @@ import java.util.List; public class PermissionSignsTabCompleter implements TabCompleter { @Override - public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, + @NotNull String[] args) { if (args.length == 1) { List commands = getAvailableCommands(sender); List matchingCommands = new ArrayList<>(); @@ -40,7 +41,7 @@ public class PermissionSignsTabCompleter implements TabCompleter { * @param commandSender

The command sender to get available commands for

* @return

The commands available to the command sender

*/ - private List getAvailableCommands(CommandSender commandSender) { + private List getAvailableCommands(@NotNull CommandSender commandSender) { List commands = new ArrayList<>(); commands.add("about"); if (!(commandSender instanceof Player player) || player.hasPermission("permissionsigns.admin.reload")) { diff --git a/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java b/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java index 2c197a3..796fb94 100644 --- a/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java +++ b/src/main/java/net/knarcraft/permissionsigns/command/ReloadCommand.java @@ -16,7 +16,8 @@ import org.jetbrains.annotations.NotNull; public class ReloadCommand implements CommandExecutor { @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")) { SignManager.loadSigns(); PermissionManager.loadTemporaryPermissions(); diff --git a/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java b/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java index 0e9bdd6..bc4d316 100644 --- a/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java +++ b/src/main/java/net/knarcraft/permissionsigns/container/PermissionSign.java @@ -4,6 +4,8 @@ import net.knarcraft.permissionsigns.formatting.TranslatableMessage; import net.knarcraft.permissionsigns.formatting.Translator; import net.knarcraft.permissionsigns.manager.EconomyManager; import org.bukkit.Location; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; @@ -38,8 +40,8 @@ public class PermissionSign { * @param duration

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

* @param cost

The cost of using this permission sign

*/ - public PermissionSign(Location signLocation, String name, String description, List permissionNodes, - int duration, double cost) { + public PermissionSign(@NotNull Location signLocation, @NotNull String name, @NotNull String description, + @NotNull List permissionNodes, int duration, double cost) { this.signLocation = signLocation; this.name = name; this.description = description; @@ -59,7 +61,8 @@ public class PermissionSign { * @param duration

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

* @param cost

The cost of using this permission sign

*/ - public PermissionSign(String name, String description, List permissionNodes, int duration, double cost) { + public PermissionSign(@NotNull String name, @NotNull String description, @NotNull List permissionNodes, + int duration, double cost) { this.name = name; this.description = description; this.permissionNodes = new ArrayList<>(permissionNodes); @@ -72,7 +75,7 @@ public class PermissionSign { * * @param signLocation

>The location of this permission sign's actual sign

*/ - public void setSignLocation(Location signLocation) { + public void setSignLocation(@NotNull Location signLocation) { if (this.signLocation == null) { this.signLocation = signLocation; } else { @@ -87,7 +90,7 @@ public class PermissionSign { * * @return

The location of this permission sign

*/ - public Location getSignLocation() { + public @NotNull Location getSignLocation() { return signLocation; } @@ -96,7 +99,7 @@ public class PermissionSign { * * @return

The name of this permission sign

*/ - public String getName() { + public @NotNull String getName() { return name; } @@ -105,7 +108,7 @@ public class PermissionSign { * * @return

The description of this permission sign

*/ - public String getDescription() { + public @NotNull String getDescription() { return description; } @@ -114,7 +117,7 @@ public class PermissionSign { * * @return

The permission nodes granted by this permission sign

*/ - public List getPermissionNodes() { + public @NotNull List getPermissionNodes() { return new ArrayList<>(this.permissionNodes); } @@ -143,7 +146,7 @@ public class PermissionSign { * * @return

The lines used to draw this permission sign

*/ - public String[] getSignLines() { + public @NotNull String[] getSignLines() { String[] lines = new String[4]; lines[0] = Translator.getTranslatedMessage(TranslatableMessage.SIGN_PREFIX); lines[1] = replacePlaceholder(Translator.getTranslatedMessage( @@ -154,7 +157,7 @@ public class PermissionSign { } @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { if (!(other instanceof PermissionSign)) { return false; } @@ -170,7 +173,7 @@ public class PermissionSign { * * @return

The string used for displaying this sign's duration

*/ - public String getDurationString() { + public @NotNull String getDurationString() { if (duration == 0) { return Translator.getTranslatedMessage(TranslatableMessage.SIGN_PERMANENT); } else { @@ -193,7 +196,7 @@ public class PermissionSign { * * @return

The string used for displaying this sign's cost

*/ - public String getCostString() { + public @NotNull String getCostString() { if (cost == 0) { return Translator.getTranslatedMessage(TranslatableMessage.SIGN_COST_FREE); } else { @@ -219,7 +222,8 @@ public class PermissionSign { * @param castToInt

Whether to cast the duration to an int

* @return

The formatted duration string

*/ - 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); durationFormat = replacePlaceholder(durationFormat, "{unit}", Translator.getTranslatedMessage(translatableMessage)); diff --git a/src/main/java/net/knarcraft/permissionsigns/container/SignCreationRequest.java b/src/main/java/net/knarcraft/permissionsigns/container/SignCreationRequest.java index be225ca..8fdf464 100644 --- a/src/main/java/net/knarcraft/permissionsigns/container/SignCreationRequest.java +++ b/src/main/java/net/knarcraft/permissionsigns/container/SignCreationRequest.java @@ -1,6 +1,8 @@ package net.knarcraft.permissionsigns.container; 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 @@ -18,7 +20,7 @@ public class SignCreationRequest implements Comparable { * @param player

The player starting to create the permission sign

* @param initiationTime

The time the request was initiated

*/ - public SignCreationRequest(PermissionSign permissionSign, Player player, long initiationTime) { + public SignCreationRequest(@NotNull PermissionSign permissionSign, @NotNull Player player, long initiationTime) { this.permissionSign = permissionSign; this.player = player; this.initiationTime = initiationTime; @@ -29,7 +31,7 @@ public class SignCreationRequest implements Comparable { * * @return

The involved permission sign

*/ - public PermissionSign getPermissionSign() { + public @NotNull PermissionSign getPermissionSign() { return this.permissionSign; } @@ -38,7 +40,7 @@ public class SignCreationRequest implements Comparable { * * @return

The involved player

*/ - public Player getPlayer() { + public @NotNull Player getPlayer() { return this.player; } @@ -52,7 +54,7 @@ public class SignCreationRequest implements Comparable { } @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { if (!(other instanceof SignCreationRequest otherRequest)) { return false; } @@ -64,7 +66,7 @@ public class SignCreationRequest implements Comparable { } @Override - public int compareTo(SignCreationRequest other) { + public int compareTo(@NotNull SignCreationRequest other) { return (int) (this.initiationTime - other.initiationTime); } } diff --git a/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java b/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java index 5fef274..831023b 100644 --- a/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java +++ b/src/main/java/net/knarcraft/permissionsigns/container/TemporaryPermission.java @@ -3,6 +3,7 @@ package net.knarcraft.permissionsigns.container; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * A temporary permission that needs to be removed after a given duration @@ -23,7 +24,8 @@ public class TemporaryPermission implements Comparable { * @param duration

The duration, in seconds, the temporary permission should last

* @param world

The world the permission should be added to

*/ - 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(); this.grantedPlayer = player; this.permissionNode = permissionNode; @@ -40,7 +42,8 @@ public class TemporaryPermission implements Comparable { * @param duration

The duration, in seconds, the temporary permission should last

* @param world

The world the permission should be added to

*/ - 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.permissionNode = permissionNode; this.grantedTime = grantedTime; @@ -71,7 +74,7 @@ public class TemporaryPermission implements Comparable { * * @return

The player this temporary permission was granted to

*/ - public OfflinePlayer getGrantedPlayer() { + public @NotNull OfflinePlayer getGrantedPlayer() { return grantedPlayer; } @@ -80,7 +83,7 @@ public class TemporaryPermission implements Comparable { * * @return

The permission node that was granted to this player

*/ - public String getPermissionNode() { + public @NotNull String getPermissionNode() { return permissionNode; } @@ -89,7 +92,7 @@ public class TemporaryPermission implements Comparable { * * @return

The world the permission node should be added to

*/ - public String getWorld() { + public @Nullable String getWorld() { return world; } diff --git a/src/main/java/net/knarcraft/permissionsigns/formatting/StringFormatter.java b/src/main/java/net/knarcraft/permissionsigns/formatting/StringFormatter.java index 0218324..633d7ee 100644 --- a/src/main/java/net/knarcraft/permissionsigns/formatting/StringFormatter.java +++ b/src/main/java/net/knarcraft/permissionsigns/formatting/StringFormatter.java @@ -1,6 +1,7 @@ package net.knarcraft.permissionsigns.formatting; import net.md_5.bungee.api.ChatColor; +import org.jetbrains.annotations.NotNull; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -18,7 +19,8 @@ public class StringFormatter { * @param replacement

The replacement value

* @return

The input string with the placeholder replaced

*/ - 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); } @@ -30,7 +32,8 @@ public class StringFormatter { * @param replacements

The replacement values

* @return

The input string with placeholders replaced

*/ - 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++) { input = replacePlaceholder(input, placeholders[i], replacements[i]); } @@ -43,7 +46,7 @@ public class StringFormatter { * @param translatableMessage

The translatable message to translate and format

* @return

The translated and formatted message

*/ - public static String getTranslatedInfoMessage(TranslatableMessage translatableMessage) { + public static @NotNull String getTranslatedInfoMessage(@NotNull TranslatableMessage translatableMessage) { return formatInfoMessage(Translator.getTranslatedMessage(translatableMessage)); } @@ -53,7 +56,7 @@ public class StringFormatter { * @param translatableMessage

The translatable message to translate and format

* @return

The translated and formatted message

*/ - public static String getTranslatedErrorMessage(TranslatableMessage translatableMessage) { + public static @NotNull String getTranslatedErrorMessage(@NotNull TranslatableMessage translatableMessage) { return formatErrorMessage(Translator.getTranslatedMessage(translatableMessage)); } @@ -63,7 +66,7 @@ public class StringFormatter { * @param message

The message to format

* @return

The formatted message

*/ - public static String formatInfoMessage(String message) { + public static @NotNull String formatInfoMessage(@NotNull String message) { return ChatColor.DARK_GREEN + formatMessage(message); } @@ -73,7 +76,7 @@ public class StringFormatter { * @param message

The message to format

* @return

The formatted message

*/ - public static String formatErrorMessage(String message) { + public static @NotNull String formatErrorMessage(@NotNull String message) { return ChatColor.DARK_RED + formatMessage(message); } @@ -83,7 +86,7 @@ public class StringFormatter { * @param message

The message to format

* @return

The formatted message

*/ - private static String formatMessage(String message) { + private static @NotNull String formatMessage(@NotNull String message) { return Translator.getTranslatedMessage(TranslatableMessage.PREFIX) + " " + ChatColor.RESET + message; } @@ -94,7 +97,7 @@ public class StringFormatter { * @param message

The string to search for color codes

* @return

The message with color codes translated

*/ - public static String translateAllColorCodes(String message) { + public static @NotNull String translateAllColorCodes(@NotNull String message) { message = ChatColor.translateAlternateColorCodes('&', message); Pattern pattern = Pattern.compile("(#[a-fA-F0-9]{6})"); Matcher matcher = pattern.matcher(message); diff --git a/src/main/java/net/knarcraft/permissionsigns/formatting/Translator.java b/src/main/java/net/knarcraft/permissionsigns/formatting/Translator.java index 0ae9b37..5b18fde 100644 --- a/src/main/java/net/knarcraft/permissionsigns/formatting/Translator.java +++ b/src/main/java/net/knarcraft/permissionsigns/formatting/Translator.java @@ -3,6 +3,8 @@ package net.knarcraft.permissionsigns.formatting; import net.knarcraft.permissionsigns.PermissionSigns; import net.knarcraft.permissionsigns.utility.FileHelper; import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; import java.io.File; @@ -29,7 +31,7 @@ public final class Translator { /** * Loads the languages used by this translator */ - public static void loadLanguages(String selectedLanguage) { + public static void loadLanguages(@NotNull String selectedLanguage) { backupTranslatedMessages = loadTranslatedMessages("en"); translatedMessages = loadCustomTranslatedMessages(selectedLanguage); if (translatedMessages == null) { @@ -43,7 +45,7 @@ public final class Translator { * @param translatableMessage

The message to translate

* @return

The translated message

*/ - public static String getTranslatedMessage(TranslatableMessage translatableMessage) { + public static @NotNull String getTranslatedMessage(@NotNull TranslatableMessage translatableMessage) { if (translatedMessages == null) { return "Translated strings not loaded"; } @@ -64,7 +66,7 @@ public final class Translator { * @param language

The language chosen by the user

* @return

A mapping of all strings for the given language

*/ - public static Map loadTranslatedMessages(String language) { + public static @Nullable Map loadTranslatedMessages(@NotNull String language) { try { BufferedReader reader = FileHelper.getBufferedReaderForInternalFile("/strings.yml"); return loadTranslatableMessages(language, reader); @@ -80,7 +82,7 @@ public final class Translator { * @param language

The selected language

* @return

The loaded translated strings, or null if no custom language file exists

*/ - public static Map loadCustomTranslatedMessages(String language) { + public static @Nullable Map loadCustomTranslatedMessages(@NotNull String language) { File strings = new File(PermissionSigns.getInstance().getDataFolder(), "strings.yml"); if (!strings.exists()) { PermissionSigns.getInstance().getLogger().log(Level.FINEST, "Strings file not found"); diff --git a/src/main/java/net/knarcraft/permissionsigns/listener/BlockListener.java b/src/main/java/net/knarcraft/permissionsigns/listener/BlockListener.java index f97e182..fd9ddb7 100644 --- a/src/main/java/net/knarcraft/permissionsigns/listener/BlockListener.java +++ b/src/main/java/net/knarcraft/permissionsigns/listener/BlockListener.java @@ -21,6 +21,8 @@ import org.bukkit.event.block.BlockExplodeEvent; import org.bukkit.event.block.BlockPistonExtendEvent; import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.entity.EntityExplodeEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -33,27 +35,27 @@ import static net.knarcraft.permissionsigns.PermissionSigns.extensiveSignProtect public class BlockListener implements Listener { @EventHandler(priority = EventPriority.LOWEST) - public void onPistonExtend(BlockPistonExtendEvent event) { + public void onPistonExtend(@NotNull BlockPistonExtendEvent event) { preventDestruction(event.getBlocks(), event); } @EventHandler(priority = EventPriority.LOWEST) - public void onPistonRetract(BlockPistonRetractEvent event) { + public void onPistonRetract(@NotNull BlockPistonRetractEvent event) { preventDestruction(event.getBlocks(), event); } @EventHandler(priority = EventPriority.LOWEST) - public void onBlockExplode(BlockExplodeEvent event) { + public void onBlockExplode(@NotNull BlockExplodeEvent event) { preventDestruction(event.blockList(), event); } @EventHandler(priority = EventPriority.LOWEST) - public void onEntityExplode(EntityExplodeEvent event) { + public void onEntityExplode(@NotNull EntityExplodeEvent event) { preventDestruction(event.blockList(), event); } @EventHandler(priority = EventPriority.LOWEST) - public void onBlockBreak(BlockBreakEvent event) { + public void onBlockBreak(@NotNull BlockBreakEvent event) { Block block = event.getBlock(); Player player = event.getPlayer(); @@ -81,7 +83,8 @@ public class BlockListener implements Listener { * @param player

The player breaking the block

* @param direction

The direction to check for affected blocks

*/ - 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); while ((direction == BlockFace.DOWN && directionBlock.getBlockData().getMaterial() == Material.POINTED_DRIPSTONE) || (direction == BlockFace.UP && @@ -100,7 +103,7 @@ public class BlockListener implements Listener { * @param blocks

The blocks affected by the event

* @param event

The event to cancel if a permission sign is found

*/ - private void preventDestruction(List blocks, Cancellable event) { + private void preventDestruction(@NotNull List blocks, @NotNull Cancellable event) { //Don't do anything if indirect protection is disabled if (!PermissionSigns.indirectProtectionEnabled()) { return; @@ -128,7 +131,7 @@ public class BlockListener implements Listener { * @param block

The block to check if it's a sign

* @param player

The player breaking the block

*/ - 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 Material material = block.getBlockData().getMaterial(); if (Tag.SIGNS.isTagged(material)) { @@ -148,7 +151,7 @@ public class BlockListener implements Listener { * @param block

The block to check if it's a sign

* @param player

The player breaking the block

*/ - 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); if (Tag.STANDING_SIGNS.isTagged(aboveBlock.getBlockData().getMaterial())) { checkIfBlockIsPermissionSign(aboveBlock, player, event); @@ -177,7 +180,7 @@ public class BlockListener implements Listener { * @param player

The player that caused the event

* @param event

The triggered event

*/ - 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(); boolean registered = SignManager.getSign(sign.getLocation()) != null; if (!registered) { @@ -206,7 +209,7 @@ public class BlockListener implements Listener { * * @return

The relevant block faces for checking around a block

*/ - private List getRelevantBlockFaces() { + private @NotNull List getRelevantBlockFaces() { List relevantBlockFaces = new ArrayList<>(); relevantBlockFaces.add(BlockFace.WEST); relevantBlockFaces.add(BlockFace.EAST); @@ -221,7 +224,7 @@ public class BlockListener implements Listener { * @param material

The material to check

* @return

True if the material is affected by gravity

*/ - private boolean isAffectedByGravity(Material material) { + private boolean isAffectedByGravity(@NotNull Material material) { //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 || Tag.STANDING_SIGNS.isTagged(material) || material == Material.DRAGON_EGG || material == Material.GRAVEL || diff --git a/src/main/java/net/knarcraft/permissionsigns/listener/PlayerListener.java b/src/main/java/net/knarcraft/permissionsigns/listener/PlayerListener.java index 19d177a..c6985ef 100644 --- a/src/main/java/net/knarcraft/permissionsigns/listener/PlayerListener.java +++ b/src/main/java/net/knarcraft/permissionsigns/listener/PlayerListener.java @@ -5,6 +5,7 @@ import net.knarcraft.permissionsigns.manager.PermissionManager; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; +import org.jetbrains.annotations.NotNull; import java.util.PriorityQueue; import java.util.Queue; @@ -15,7 +16,7 @@ import java.util.Queue; public class PlayerListener implements Listener { @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { + public void onPlayerJoin(@NotNull PlayerJoinEvent event) { //Give the joining player any temporary permissions containing their UUID Queue temporaryPermissions = new PriorityQueue<>(PermissionManager.getTemporaryPermissions()); temporaryPermissions.removeIf((item) -> !item.getGrantedPlayer().getUniqueId().equals(event.getPlayer().getUniqueId())); diff --git a/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java b/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java index 92c500d..7ac1057 100644 --- a/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java +++ b/src/main/java/net/knarcraft/permissionsigns/listener/SignListener.java @@ -22,6 +22,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.List; @@ -38,7 +39,7 @@ public class SignListener implements Listener { * @param event

The player interact event which was triggered

*/ @EventHandler - public void onPlayerInteract(PlayerInteractEvent event) { + public void onPlayerInteract(@NotNull PlayerInteractEvent event) { Player player = event.getPlayer(); Block block = event.getClickedBlock(); @@ -53,8 +54,6 @@ public class SignListener implements Listener { Sign sign = (Sign) block.getState(); if (event.getHand() == EquipmentSlot.HAND) { - // Cancel the interaction to avoid sign editing - event.setCancelled(true); handleSignClick(sign, player, event.getAction(), event); } } @@ -67,7 +66,8 @@ public class SignListener implements Listener { * @param action

The hand the player used to interact with the sign

* @param event

The player interact event which was triggered

*/ - 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 PermissionSign permissionSign = SignManager.getSign(sign.getLocation()); if (permissionSign != null) { @@ -79,9 +79,9 @@ public class SignListener implements Listener { player.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.INTERACT_PERMISSION_MISSING)); return; } + //Prevent placement of any blocks, and sign clicking + event.setCancelled(true); if (player.isSneaking()) { - //Prevent placement of any blocks - event.setCancelled(true); handlePermissionSignInteract(permissionSign, player); } else { player.sendMessage(getSignInfoText(permissionSign)); @@ -102,7 +102,7 @@ public class SignListener implements Listener { * @param sign

The sign to get information about

* @return

The information to display

*/ - private String getSignInfoText(PermissionSign sign) { + private String getSignInfoText(@NotNull PermissionSign sign) { String rawSignInfo = Translator.getTranslatedMessage(TranslatableMessage.SIGN_INFO); StringBuilder permissionString = new StringBuilder(); List permissionNodes = sign.getPermissionNodes(); @@ -126,7 +126,7 @@ public class SignListener implements Listener { * @param permissionSign

The permission sign that was interacted with

* @param player

The player that interacted with the permission sign

*/ - 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 boolean hasAllPermissions = true; for (String permissionNode : permissionSign.getPermissionNodes()) { @@ -157,7 +157,7 @@ public class SignListener implements Listener { * @param player

The player to give permissions to

* @param permissionSign

The permission sign the player clicked

*/ - private void performPermissionTransaction(Player player, PermissionSign permissionSign) { + private void performPermissionTransaction(@NotNull Player player, @NotNull PermissionSign permissionSign) { EconomyManager.withdraw(player, permissionSign.getCost()); StringJoiner permissionsJoiner = new StringJoiner(", "); for (String permissionNode : permissionSign.getPermissionNodes()) { @@ -197,7 +197,8 @@ public class SignListener implements Listener { * @param request

The creation request to fulfill

* @param player

The player that interacted with the sign

*/ - 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); String[] lines = frontSide.getLines(); //Don't allow non-empty signs to be overwritten diff --git a/src/main/java/net/knarcraft/permissionsigns/manager/EconomyManager.java b/src/main/java/net/knarcraft/permissionsigns/manager/EconomyManager.java index 8dae776..7942413 100644 --- a/src/main/java/net/knarcraft/permissionsigns/manager/EconomyManager.java +++ b/src/main/java/net/knarcraft/permissionsigns/manager/EconomyManager.java @@ -3,6 +3,7 @@ package net.knarcraft.permissionsigns.manager; import net.milkbowl.vault.economy.Economy; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; /** * A manager that performs all Economy tasks @@ -20,7 +21,7 @@ public final class EconomyManager { * * @param economy

The economy object to use for everything economy-related

*/ - public static void initialize(Economy economy) { + public static void initialize(@NotNull Economy economy) { EconomyManager.economy = economy; } @@ -31,7 +32,7 @@ public final class EconomyManager { * @param cost

The cost the player needs to pay

* @return

True if the player is able to afford the cost

*/ - public static boolean canAfford(OfflinePlayer player, double cost) { + public static boolean canAfford(@NotNull OfflinePlayer player, double cost) { return economy.has(player, cost); } @@ -51,7 +52,7 @@ public final class EconomyManager { * @param player

The player to withdraw money from

* @param cost

The amount of money to withdraw

*/ - public static void withdraw(Player player, double cost) { + public static void withdraw(@NotNull Player player, double cost) { economy.withdrawPlayer(player, cost); } diff --git a/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java b/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java index 5c4388e..4ec9170 100644 --- a/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java +++ b/src/main/java/net/knarcraft/permissionsigns/manager/PermissionManager.java @@ -8,6 +8,8 @@ import org.bukkit.OfflinePlayer; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -35,7 +37,7 @@ public final class PermissionManager { * * @param permission

The permission object to use for everything permission-related

*/ - public static void initialize(Permission permission) { + public static void initialize(@NotNull Permission permission) { PermissionManager.permission = permission; } @@ -44,7 +46,7 @@ public final class PermissionManager { * * @return

The registered temporary permissions

*/ - public static Queue getTemporaryPermissions() { + public static @NotNull Queue getTemporaryPermissions() { return temporaryPermissions; } @@ -54,7 +56,7 @@ public final class PermissionManager { * @param player

The player to grant the permission to

* @param permissionNode

The permission node to grant to the player

*/ - public static void addPermission(Player player, String permissionNode) { + public static void addPermission(@NotNull Player player, @NotNull String permissionNode) { //Allow world:permission syntax if (permissionNode.contains(":")) { grantWorldPermission(player, permissionNode, false); @@ -71,7 +73,8 @@ public final class PermissionManager { * @param permissionNode

The permission node to grant

* @param worldName

The world to add the permission node to

*/ - 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 if (permissionNode.contains(":")) { grantWorldPermission(player, permissionNode, true); @@ -88,7 +91,7 @@ public final class PermissionManager { * @param permissionNode

The permission node to grant

* @param temporary

Whether the permission node should be set temporarily

*/ - 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 world = permissionParts[0]; if (world.equalsIgnoreCase("all") || world.equalsIgnoreCase("any")) { @@ -108,7 +111,7 @@ public final class PermissionManager { * @param permissionNode

The temporary permission to grant

* @param duration

The duration for which the player should keep the given permission

*/ - public static void addTemporaryPermission(Player player, String permissionNode, int duration) { + public static void addTemporaryPermission(@NotNull Player player, @NotNull String permissionNode, int duration) { String world = player.getWorld().getName(); grantTemporaryPermission(player, permissionNode, world); temporaryPermissions.add(new TemporaryPermission(player, permissionNode, duration, world)); @@ -126,7 +129,7 @@ public final class PermissionManager { * @param offlinePlayer

The player to remove the permission from

* @param permissionNode

The permission node to remove from the player

*/ - public static void removeTemporaryPermission(OfflinePlayer offlinePlayer, String permissionNode) { + public static void removeTemporaryPermission(@NotNull OfflinePlayer offlinePlayer, @NotNull String permissionNode) { Player player = offlinePlayer.getPlayer(); if (player != null && player.hasPermission(permissionNode)) { permission.playerRemoveTransient(null, player, permissionNode); @@ -141,7 +144,7 @@ public final class PermissionManager { * @param world

The world to check for the permission

* @return

True if the player has the permission

*/ - 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); } @@ -182,6 +185,11 @@ public final class PermissionManager { String[] identifierParts = key.split(","); OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(identifierParts[0])); 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]); int duration = permissionSection.getInt(key + ".duration", 1); String world = permissionSection.getString(key + ".world", null); diff --git a/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java b/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java index 133af72..507dcb8 100644 --- a/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java +++ b/src/main/java/net/knarcraft/permissionsigns/manager/SignManager.java @@ -12,6 +12,8 @@ import org.bukkit.block.sign.SignSide; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -42,7 +44,7 @@ public final class SignManager { * @param signLocation

The location of the permission sign to get

* @return

The permission sign at the given location, or null if no such sign exists

*/ - public static PermissionSign getSign(Location signLocation) { + public static @Nullable PermissionSign getSign(@NotNull Location signLocation) { return managedSigns.get(signLocation); } @@ -51,7 +53,7 @@ public final class SignManager { * * @param sign

The sign to add

*/ - public static void addSign(PermissionSign sign) { + public static void addSign(@NotNull PermissionSign sign) { managedSigns.put(sign.getSignLocation(), sign); save(); } @@ -61,7 +63,7 @@ public final class SignManager { * * @param location

The location of the sign to remove

*/ - public static void removeSign(Location location) { + public static void removeSign(@NotNull Location location) { managedSigns.remove(location); save(); } @@ -163,7 +165,8 @@ public final class SignManager { * @param key

The sign key which is also the sign's location

* @throws InvalidConfigurationException

If unable to load the sign

*/ - 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(","); Location signLocation; try { @@ -198,7 +201,8 @@ public final class SignManager { int duration = signSection.getInt(key + ".duration"); 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); } diff --git a/src/main/java/net/knarcraft/permissionsigns/thread/SignCreationRequestTimeoutThread.java b/src/main/java/net/knarcraft/permissionsigns/thread/SignCreationRequestTimeoutThread.java index ce43587..cd91432 100644 --- a/src/main/java/net/knarcraft/permissionsigns/thread/SignCreationRequestTimeoutThread.java +++ b/src/main/java/net/knarcraft/permissionsigns/thread/SignCreationRequestTimeoutThread.java @@ -1,6 +1,7 @@ package net.knarcraft.permissionsigns.thread; import net.knarcraft.permissionsigns.container.SignCreationRequest; +import org.jetbrains.annotations.NotNull; import java.util.Queue; @@ -16,7 +17,7 @@ public class SignCreationRequestTimeoutThread implements Runnable { * * @param signCreationRequests

A pointer to the queue of sign creation requests

*/ - public SignCreationRequestTimeoutThread(Queue signCreationRequests) { + public SignCreationRequestTimeoutThread(@NotNull Queue signCreationRequests) { this.signCreationRequests = signCreationRequests; } diff --git a/src/main/java/net/knarcraft/permissionsigns/utility/FileHelper.java b/src/main/java/net/knarcraft/permissionsigns/utility/FileHelper.java index 54a8b99..5165415 100644 --- a/src/main/java/net/knarcraft/permissionsigns/utility/FileHelper.java +++ b/src/main/java/net/knarcraft/permissionsigns/utility/FileHelper.java @@ -1,5 +1,7 @@ package net.knarcraft.permissionsigns.utility; +import org.jetbrains.annotations.NotNull; + import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.InputStream; @@ -21,7 +23,7 @@ public final class FileHelper { * @return

A buffered read for reading the file

* @throws FileNotFoundException

If unable to get an input stream for the given file

*/ - public static BufferedReader getBufferedReaderForInternalFile(String file) throws FileNotFoundException { + public static @NotNull BufferedReader getBufferedReaderForInternalFile(@NotNull String file) throws FileNotFoundException { InputStream inputStream = FileHelper.class.getResourceAsStream(file); if (inputStream == null) { throw new FileNotFoundException("Unable to read the given file"); @@ -35,7 +37,7 @@ public final class FileHelper { * @param inputStream

The input stream to read

* @return

A buffered reader reading the input stream

*/ - public static BufferedReader getBufferedReaderFromInputStream(InputStream inputStream) { + public static @NotNull BufferedReader getBufferedReaderFromInputStream(@NotNull InputStream inputStream) { InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); return new BufferedReader(inputStreamReader); } diff --git a/src/main/java/net/knarcraft/permissionsigns/utility/UpdateChecker.java b/src/main/java/net/knarcraft/permissionsigns/utility/UpdateChecker.java index 677c85e..9deac2b 100644 --- a/src/main/java/net/knarcraft/permissionsigns/utility/UpdateChecker.java +++ b/src/main/java/net/knarcraft/permissionsigns/utility/UpdateChecker.java @@ -2,6 +2,8 @@ package net.knarcraft.permissionsigns.utility; import org.bukkit.plugin.Plugin; import org.bukkit.scheduler.BukkitScheduler; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; 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 */ - public static void checkForUpdate(Plugin plugin, String apiResourceURL, Supplier getVersionMethod, - Consumer setVersionMethod) { + public static void checkForUpdate(@NotNull Plugin plugin, @NotNull String apiResourceURL, + @NotNull Supplier getVersionMethod, + @Nullable Consumer setVersionMethod) { BukkitScheduler scheduler = plugin.getServer().getScheduler(); scheduler.runTaskAsynchronously(plugin, () -> UpdateChecker.queryAPI(plugin, apiResourceURL, getVersionMethod, setVersionMethod)); @@ -35,8 +38,9 @@ public final class UpdateChecker { /** * Queries the spigot API to check for a newer version, and informs the user */ - private static void queryAPI(Plugin plugin, String APIResourceURL, Supplier getVersionMethod, - Consumer setVersionMethod) { + private static void queryAPI(@NotNull Plugin plugin, @NotNull String APIResourceURL, + @NotNull Supplier getVersionMethod, + @Nullable Consumer setVersionMethod) { try { InputStream inputStream = new URL(APIResourceURL).openStream(); BufferedReader reader = FileHelper.getBufferedReaderFromInputStream(inputStream); @@ -64,7 +68,7 @@ public final class UpdateChecker { * @param oldVersion

The old (current) plugin version

* @return

The string to display

*/ - 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); } @@ -75,7 +79,7 @@ public final class UpdateChecker { * @param newVersion

The new version to check

* @return

True if the new version is higher than the old one

*/ - public static boolean isVersionHigher(String oldVersion, String newVersion) { + public static boolean isVersionHigher(@NotNull String oldVersion, @NotNull String newVersion) { String[] oldVersionParts = oldVersion.split("\\."); String[] newVersionParts = newVersion.split("\\."); int versionLength = Math.max(oldVersionParts.length, newVersionParts.length);