From b4a6ce1a77dcd92db81c18741249fb56d9be87c5 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 20 Feb 2024 12:43:01 +0100 Subject: [PATCH 1/8] Adds nullability annotations among other things Adds nullability annotations for all methods Fixes some nullability problems and inconsistencies Gets rid of RelativeBlockVector's inner class Changes RelativeBlockVector to a record Simplifies FromTheEndTeleportation's storage, and makes it into a minimal record Removes the putStringInList method Gets rid of some primitive list usage Fixes some incorrect method accessibility Removes some redundancy in PortalOption --- README.md | 4 +- .../java/net/knarcraft/stargate/Stargate.java | 52 +++++++---- .../stargate/command/CommandAbout.java | 8 +- .../stargate/command/CommandConfig.java | 52 +++++++---- .../stargate/command/ConfigTabCompleter.java | 26 +++--- .../command/StarGateTabCompleter.java | 8 +- .../stargate/config/ConfigOption.java | 17 ++-- .../knarcraft/stargate/config/ConfigTag.java | 43 ++++++---- .../stargate/config/DynmapManager.java | 19 ++-- .../stargate/config/EconomyConfig.java | 16 ++-- .../stargate/config/LanguageLoader.java | 30 ++++--- .../stargate/config/MessageSender.java | 9 +- .../stargate/config/StargateConfig.java | 31 +++++-- .../stargate/config/StargateGateConfig.java | 13 +-- .../config/StargateYamlConfiguration.java | 33 ++++--- .../container/BlockChangeRequest.java | 7 +- .../stargate/container/BlockLocation.java | 26 ++++-- .../container/ChunkUnloadRequest.java | 5 +- .../container/FromTheEndTeleportation.java | 54 ++---------- .../container/RelativeBlockVector.java | 86 +++++++++---------- .../stargate/container/SignData.java | 6 +- .../stargate/event/StargateAccessEvent.java | 3 +- .../stargate/event/StargateActivateEvent.java | 10 ++- .../stargate/event/StargateCloseEvent.java | 3 +- .../stargate/event/StargateCreateEvent.java | 8 +- .../event/StargateDeactivateEvent.java | 3 +- .../stargate/event/StargateDestroyEvent.java | 7 +- .../event/StargateEntityPortalEvent.java | 9 +- .../stargate/event/StargateEvent.java | 4 +- .../stargate/event/StargateOpenEvent.java | 4 +- .../stargate/event/StargatePlayerEvent.java | 5 +- .../event/StargatePlayerPortalEvent.java | 8 +- .../stargate/event/StargateTeleportEvent.java | 2 + .../stargate/listener/BlockEventListener.java | 23 ++--- .../listener/EntityEventListener.java | 5 +- .../listener/EntitySpawnListener.java | 12 +-- .../listener/PlayerEventListener.java | 47 ++++++---- .../listener/PluginEventListener.java | 16 ++-- .../listener/PortalEventListener.java | 67 ++++++++------- .../listener/TeleportEventListener.java | 3 +- .../listener/VehicleEventListener.java | 11 ++- .../stargate/listener/WorldEventListener.java | 5 +- .../net/knarcraft/stargate/portal/Portal.java | 34 ++++++-- .../stargate/portal/PortalActivator.java | 23 +++-- .../stargate/portal/PortalCreator.java | 23 +++-- .../stargate/portal/PortalHandler.java | 66 +++++++++----- .../stargate/portal/PortalOpener.java | 11 ++- .../stargate/portal/PortalRegistry.java | 25 ++++-- .../stargate/portal/PortalSignDrawer.java | 57 +++++++----- .../portal/property/PortalLocation.java | 22 ++++- .../portal/property/PortalOption.java | 29 ++++--- .../portal/property/PortalOptions.java | 3 +- .../stargate/portal/property/PortalOwner.java | 15 ++-- .../portal/property/PortalStructure.java | 13 ++- .../stargate/portal/property/gate/Gate.java | 53 ++++++++---- .../portal/property/gate/GateHandler.java | 42 ++++++--- .../portal/property/gate/GateLayout.java | 26 ++++-- .../portal/teleporter/EntityTeleporter.java | 5 +- .../portal/teleporter/PlayerTeleporter.java | 6 +- .../portal/teleporter/Teleporter.java | 50 ++++++----- .../portal/teleporter/VehicleTeleporter.java | 16 ++-- .../stargate/thread/BlockChangeThread.java | 5 +- .../stargate/utility/BStatsHelper.java | 3 +- .../stargate/utility/BungeeHelper.java | 25 ++++-- .../stargate/utility/DirectionHelper.java | 19 ++-- .../stargate/utility/EconomyHelper.java | 35 ++++---- .../stargate/utility/EntityHelper.java | 5 +- .../stargate/utility/FileHelper.java | 11 ++- .../stargate/utility/GateReader.java | 41 ++++----- .../stargate/utility/MaterialHelper.java | 7 +- .../stargate/utility/PermissionHelper.java | 58 ++++++++----- .../stargate/utility/PortalFileHelper.java | 74 ++++++++++------ .../stargate/utility/SignHelper.java | 7 +- .../stargate/utility/TeleportHelper.java | 27 +++--- .../stargate/utility/UUIDMigrationHelper.java | 8 +- .../stargate/RelativeBlockVectorTest.java | 6 +- .../container/RelativeBlockVectorTest.java | 6 +- .../stargate/portal/GateLayoutTest.java | 8 +- 78 files changed, 1025 insertions(+), 639 deletions(-) diff --git a/README.md b/README.md index 83139b0..8692f37 100644 --- a/README.md +++ b/README.md @@ -541,7 +541,7 @@ portalInfoServer=Server: %server% #### \[Version 0.11.5.3] Unified Legacy Fork -- Hotfix for an issue wherein the gate folder failed to populate on fresh installs. +- Hotfix for an issue wherein the gate folder failed to populate on fresh installations. #### \[Version 0.11.5.2] Unified Legacy Fork @@ -757,7 +757,7 @@ found [here](https://github.com/stargate-rewritten/Stargate-ESR#version-01081-lc - Improves the stability of Stargate's load-time portal handling. - Highlights destination selector brackets on signs ("-") as to improve readability. - Uses dark red to mark portals which are inactive (missing destination or invalid gate type) -- Adds provisions to re-draw incorrect signs. +- Adds provision to re-draw incorrect signs. - Fixed a load of other miscellaneous bugs. #### \[Version 0.8.0.3] PseudoKnight fork diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 3293978..2cebbb3 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -35,6 +35,8 @@ import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; import org.bukkit.scheduler.BukkitScheduler; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -112,7 +114,7 @@ public class Stargate extends JavaPlugin { * * @param version

The version of the new update available

*/ - public static void setUpdateAvailable(String version) { + public static void setUpdateAvailable(@NotNull String version) { updateAvailable = version; } @@ -121,6 +123,7 @@ public class Stargate extends JavaPlugin { * * @return

The version number if an update is available. Null otherwise

*/ + @Nullable public static String getUpdateAvailable() { return updateAvailable; } @@ -130,6 +133,7 @@ public class Stargate extends JavaPlugin { * * @return

An instance of this plugin, or null if not instantiated

*/ + @NotNull public static Stargate getInstance() { return stargate; } @@ -139,7 +143,7 @@ public class Stargate extends JavaPlugin { * * @param request

The request to add

*/ - public static void addBlockChangeRequest(BlockChangeRequest request) { + public static void addBlockChangeRequest(@Nullable BlockChangeRequest request) { if (request != null) { blockChangeRequestQueue.add(request); } @@ -150,6 +154,7 @@ public class Stargate extends JavaPlugin { * * @return

A block change request queue

*/ + @NotNull public static Queue getBlockChangeRequestQueue() { return blockChangeRequestQueue; } @@ -159,6 +164,7 @@ public class Stargate extends JavaPlugin { * * @return

The sender for sending messages to players

*/ + @NotNull public static MessageSender getMessageSender() { return stargateConfig.getMessageSender(); } @@ -168,6 +174,7 @@ public class Stargate extends JavaPlugin { * * @return

The object containing gate configuration values

*/ + @NotNull public static StargateGateConfig getGateConfig() { return stargateConfig.getStargateGateConfig(); } @@ -177,6 +184,7 @@ public class Stargate extends JavaPlugin { * * @return

This plugin's version

*/ + @NotNull public static String getPluginVersion() { return pluginVersion; } @@ -186,6 +194,7 @@ public class Stargate extends JavaPlugin { * * @return

The logger

*/ + @NotNull public static Logger getConsoleLogger() { return logger; } @@ -206,7 +215,7 @@ public class Stargate extends JavaPlugin { * @param route

The class name/route where something happened

* @param message

A message describing what happened

*/ - public static void debug(String route, String message) { + public static void debug(@NotNull String route, @NotNull String message) { if (stargateConfig == null || stargateConfig.isNotLoaded() || stargateConfig.isDebuggingEnabled()) { logger.info("[Stargate::" + route + "] " + message); } else { @@ -219,7 +228,7 @@ public class Stargate extends JavaPlugin { * * @param message

The message to log

*/ - public static void logInfo(String message) { + public static void logInfo(@NotNull String message) { log(Level.INFO, message); } @@ -228,7 +237,7 @@ public class Stargate extends JavaPlugin { * * @param message

The message to log

*/ - public static void logSevere(String message) { + public static void logSevere(@NotNull String message) { log(Level.SEVERE, message); } @@ -237,7 +246,7 @@ public class Stargate extends JavaPlugin { * * @param message

The message to log

*/ - public static void logWarning(String message) { + public static void logWarning(@NotNull String message) { log(Level.WARNING, message); } @@ -247,7 +256,7 @@ public class Stargate extends JavaPlugin { * @param severity

The severity of the event triggering the message

* @param message

The message to log

*/ - private static void log(Level severity, String message) { + private static void log(@NotNull Level severity, @NotNull String message) { if (logger == null) { logger = Bukkit.getLogger(); } @@ -261,6 +270,7 @@ public class Stargate extends JavaPlugin { * * @return

The folder for storing the portal database

*/ + @NotNull public static String getPortalFolder() { return stargateConfig.getPortalFolder(); } @@ -272,6 +282,7 @@ public class Stargate extends JavaPlugin { * * @return

The folder storing gate files

*/ + @NotNull public static String getGateFolder() { return stargateConfig.getGateFolder(); } @@ -281,6 +292,7 @@ public class Stargate extends JavaPlugin { * * @return

The default network

*/ + @NotNull public static String getDefaultNetwork() { return stargateConfig.getStargateGateConfig().getDefaultPortalNetwork(); } @@ -293,7 +305,7 @@ public class Stargate extends JavaPlugin { * @param name

The name/key of the string to get

* @return

The full translated string

*/ - public static String getString(String name) { + public static @NotNull String getString(@NotNull String name) { return stargateConfig.getLanguageLoader().getString(name); } @@ -305,7 +317,7 @@ public class Stargate extends JavaPlugin { * @param name

The name/key of the string to get

* @return

The full string in the backup language (English)

*/ - public static String getBackupString(String name) { + public static @NotNull String getBackupString(@NotNull String name) { return stargateConfig.getLanguageLoader().getBackupString(name); } @@ -317,7 +329,8 @@ public class Stargate extends JavaPlugin { * @param value

The replacement value

* @return

The input string with the search replaced with value

*/ - public static String replaceVars(String input, String search, String value) { + @NotNull + public static String replacePlaceholders(@NotNull String input, @NotNull String search, @NotNull String value) { return input.replace(search, value); } @@ -326,6 +339,7 @@ public class Stargate extends JavaPlugin { * * @return

A plugin manager

*/ + @NotNull public static PluginManager getPluginManager() { return pluginManager; } @@ -335,6 +349,7 @@ public class Stargate extends JavaPlugin { * * @return

The object containing economy config values

*/ + @NotNull public static EconomyConfig getEconomyConfig() { return stargateConfig.getEconomyConfig(); } @@ -344,6 +359,7 @@ public class Stargate extends JavaPlugin { * * @return

The raw configuration

*/ + @NotNull public FileConfiguration getConfiguration() { return this.configuration; } @@ -354,8 +370,8 @@ public class Stargate extends JavaPlugin { this.configuration = new StargateYamlConfiguration(); try { this.configuration.load(new File(getDataFolder(), CONFIG_FILE_NAME)); - } catch (IOException | InvalidConfigurationException e) { - logSevere("Unable to load the configuration! Message: " + e.getMessage()); + } catch (IOException | InvalidConfigurationException exception) { + logSevere("Unable to load the configuration! Message: " + exception.getMessage()); } } @@ -364,8 +380,8 @@ public class Stargate extends JavaPlugin { super.saveConfig(); try { this.configuration.save(new File(getDataFolder(), CONFIG_FILE_NAME)); - } catch (IOException e) { - logSevere("Unable to save the configuration! Message: " + e.getMessage()); + } catch (IOException exception) { + logSevere("Unable to save the configuration! Message: " + exception.getMessage()); } } @@ -390,8 +406,8 @@ public class Stargate extends JavaPlugin { this.configuration = new StargateYamlConfiguration(); try { this.configuration.load(new File(getDataFolder(), CONFIG_FILE_NAME)); - } catch (IOException | InvalidConfigurationException e) { - getLogger().log(Level.SEVERE, e.getMessage()); + } catch (IOException | InvalidConfigurationException exception) { + getLogger().log(Level.SEVERE, exception.getMessage()); } this.configuration.options().copyDefaults(true); @@ -470,6 +486,7 @@ public class Stargate extends JavaPlugin { * * @return

The chunk unload queue

*/ + @NotNull public static Queue getChunkUnloadQueue() { return chunkUnloadQueue; } @@ -479,7 +496,7 @@ public class Stargate extends JavaPlugin { * * @param request

The new chunk unload request to add

*/ - public static void addChunkUnloadRequest(ChunkUnloadRequest request) { + public static void addChunkUnloadRequest(@NotNull ChunkUnloadRequest request) { chunkUnloadQueue.removeIf((item) -> item.getChunkToUnload().equals(request.getChunkToUnload())); chunkUnloadQueue.add(request); } @@ -489,6 +506,7 @@ public class Stargate extends JavaPlugin { * * @return

The stargate configuration

*/ + @NotNull public static StargateConfig getStargateConfig() { return stargateConfig; } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java index 51a6725..2ceb5d8 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java @@ -26,9 +26,11 @@ public class CommandAbout implements CommandExecutor { ChatColor highlightColor = ChatColor.GREEN; try (InputStream inputStream = Stargate.class.getResourceAsStream("/messages/about.md")) { - String aboutMessageString = FileHelper.readStreamToString(inputStream); - BaseComponent[] component = MineDown.parse(aboutMessageString); - commandSender.spigot().sendMessage(component); + if (inputStream != null) { + String aboutMessageString = FileHelper.readStreamToString(inputStream); + BaseComponent[] component = MineDown.parse(aboutMessageString); + commandSender.spigot().sendMessage(component); + } } catch (IOException ioException) { commandSender.sendMessage("Internal error"); } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 2ae0691..2e61ad8 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -16,6 +16,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -65,7 +66,8 @@ public class CommandConfig implements CommandExecutor { * @param commandSender

The command sender that changed the value

* @param value

The new value of the config option

*/ - private void updateConfigValue(ConfigOption selectedOption, CommandSender commandSender, String value) { + private void updateConfigValue(@NotNull ConfigOption selectedOption, @NotNull CommandSender commandSender, + @NotNull String value) { FileConfiguration configuration = Stargate.getInstance().getConfiguration(); //Validate any sign colors @@ -119,7 +121,8 @@ public class CommandConfig implements CommandExecutor { * @param value

The new value of the config option

* @param configuration

The configuration file to save to

*/ - private void updateBooleanConfigValue(ConfigOption selectedOption, String value, FileConfiguration configuration) { + private void updateBooleanConfigValue(@NotNull ConfigOption selectedOption, @NotNull String value, + @NotNull FileConfiguration configuration) { boolean newValue = Boolean.parseBoolean(value); if (selectedOption == ConfigOption.ENABLE_BUNGEE && newValue != Stargate.getGateConfig().enableBungee()) { Stargate.getStargateConfig().startStopBungeeListener(newValue); @@ -135,7 +138,8 @@ public class CommandConfig implements CommandExecutor { * @param commandSender

The command sender that changed the value

* @param value

The new value of the config option

*/ - private void updateStringConfigValue(ConfigOption selectedOption, CommandSender commandSender, String value) { + private void updateStringConfigValue(@NotNull ConfigOption selectedOption, @NotNull CommandSender commandSender, + @NotNull String value) { if (selectedOption == ConfigOption.GATE_FOLDER || selectedOption == ConfigOption.PORTAL_FOLDER || selectedOption == ConfigOption.DEFAULT_GATE_NETWORK) { if (value.contains("../") || value.contains("..\\")) { @@ -161,7 +165,8 @@ public class CommandConfig implements CommandExecutor { * @param commandSender

The command sender that changed the value

* @param arguments

The arguments for the new config option

*/ - private void updateListConfigValue(ConfigOption selectedOption, CommandSender commandSender, String[] arguments) { + private void updateListConfigValue(@NotNull ConfigOption selectedOption, @NotNull CommandSender commandSender, + @NotNull String[] arguments) { FileConfiguration configuration = Stargate.getInstance().getConfiguration(); if (selectedOption == ConfigOption.PER_SIGN_COLORS) { @@ -190,7 +195,8 @@ public class CommandConfig implements CommandExecutor { * @param arguments

The arguments given by the user

* @return

The per-sign color string to update with, or null if the input was invalid

*/ - private String parsePerSignColorInput(CommandSender commandSender, String[] arguments) { + @Nullable + private String parsePerSignColorInput(@NotNull CommandSender commandSender, @NotNull String[] arguments) { //Make sure the sign type is an actual sign if (Material.matchMaterial(arguments[1] + "_SIGN") == null) { Stargate.getMessageSender().sendErrorMessage(commandSender, "The given sign type is invalid"); @@ -199,7 +205,8 @@ public class CommandConfig implements CommandExecutor { String colorString = arguments[1] + ":"; //Validate the colors given by the user - String[] errorMessage = new String[]{"The given main sign color is invalid!", "The given highlight sign color is invalid!"}; + String[] errorMessage = new String[]{"The given main sign color is invalid!", "The given highlight sign color " + + "is invalid!"}; String[] newColors = new String[2]; for (int i = 0; i < 2; i++) { if (validatePerSignColor(arguments[i + 2])) { @@ -220,9 +227,11 @@ public class CommandConfig implements CommandExecutor { * @param colorString

The new color string to replace any previous value with

* @param configuration

The file configuration to update with the new per-sign colors

*/ - private void updatePerSignColors(String signType, String colorString, FileConfiguration configuration) { + private void updatePerSignColors(@NotNull String signType, @NotNull String colorString, + @NotNull FileConfiguration configuration) { List newColorStrings = new ArrayList<>(); - List oldColors = (List) Stargate.getStargateConfig().getConfigOptionsReference().get(ConfigOption.PER_SIGN_COLORS); + List oldColors = (List) Stargate.getStargateConfig().getConfigOptionsReference().get( + ConfigOption.PER_SIGN_COLORS); for (Object object : oldColors) { newColorStrings.add(String.valueOf(object)); } @@ -239,7 +248,7 @@ public class CommandConfig implements CommandExecutor { * @param color

The color chosen by the user

* @return

True if the given color is valid

*/ - private boolean validatePerSignColor(String color) { + private boolean validatePerSignColor(@NotNull String color) { ChatColor newHighlightColor = parseColor(color); return newHighlightColor != null || color.equalsIgnoreCase("default") || color.equalsIgnoreCase("inverted"); @@ -251,7 +260,7 @@ public class CommandConfig implements CommandExecutor { * @param selectedOption

The config option that was changed

* @param commandSender

The command sender that executed the config command

*/ - private void saveAndReload(ConfigOption selectedOption, CommandSender commandSender) { + private void saveAndReload(@NotNull ConfigOption selectedOption, @NotNull CommandSender commandSender) { //Save the config file and reload if necessary Stargate.getInstance().saveConfig(); @@ -268,7 +277,8 @@ public class CommandConfig implements CommandExecutor { * @param commandSender

The command sender to alert if the color is invalid

* @param value

The new option value

*/ - private boolean registerColor(ConfigOption selectedOption, String value, CommandSender commandSender) { + private boolean registerColor(@NotNull ConfigOption selectedOption, @NotNull String value, + @NotNull CommandSender commandSender) { ChatColor parsedColor = parseColor(value); if (parsedColor == null) { commandSender.sendMessage(ChatColor.RED + "Invalid color given"); @@ -291,7 +301,8 @@ public class CommandConfig implements CommandExecutor { * @param value

The value to parse

* @return

The parsed color or null

*/ - private ChatColor parseColor(String value) { + @Nullable + private ChatColor parseColor(@NotNull String value) { try { return ChatColor.of(value.toUpperCase()); } catch (IllegalArgumentException | NullPointerException ignored) { @@ -307,7 +318,9 @@ public class CommandConfig implements CommandExecutor { * @param value

The value given

* @return

An integer, or null if it was invalid

*/ - private Integer getInteger(CommandSender commandSender, ConfigOption selectedOption, String value) { + @Nullable + private Integer getInteger(@NotNull CommandSender commandSender, @NotNull ConfigOption selectedOption, + @NotNull String value) { try { int intValue = Integer.parseInt(value); @@ -331,7 +344,9 @@ public class CommandConfig implements CommandExecutor { * @param value

The value given

* @return

A double, or null if it was invalid

*/ - private Double getDouble(CommandSender commandSender, ConfigOption selectedOption, String value) { + @Nullable + private Double getDouble(@NotNull CommandSender commandSender, @NotNull ConfigOption selectedOption, + @NotNull String value) { try { double doubleValue = Double.parseDouble(value); @@ -353,7 +368,7 @@ public class CommandConfig implements CommandExecutor { * @param commandSender

The command sender initiating the reload

* @param configOption

The changed config option

*/ - private void reloadIfNecessary(CommandSender commandSender, ConfigOption configOption) { + private void reloadIfNecessary(@NotNull CommandSender commandSender, @NotNull ConfigOption configOption) { if (ConfigTag.requiresFullReload(configOption)) { //Reload everything Stargate.getStargateConfig().reload(commandSender); @@ -391,7 +406,7 @@ public class CommandConfig implements CommandExecutor { * @param sender

The command sender that sent the command

* @param option

The config option to print information about

*/ - private void printConfigOptionValue(CommandSender sender, ConfigOption option) { + private void printConfigOptionValue(@NotNull CommandSender sender, @NotNull ConfigOption option) { Object value = Stargate.getStargateConfig().getConfigOptions().get(option); sender.sendMessage(getOptionDescription(option)); sender.sendMessage(ChatColor.GREEN + "Current value: " + ChatColor.GOLD + value); @@ -402,7 +417,7 @@ public class CommandConfig implements CommandExecutor { * * @param sender

The command sender to display the config list to

*/ - private void displayConfigValues(CommandSender sender) { + private void displayConfigValues(@NotNull CommandSender sender) { sender.sendMessage(ChatColor.GREEN + Stargate.getBackupString("prefix") + ChatColor.GOLD + "Config values:"); for (ConfigOption option : ConfigOption.values()) { @@ -416,7 +431,8 @@ public class CommandConfig implements CommandExecutor { * @param option

The option to describe

* @return

A string describing the config option

*/ - private String getOptionDescription(ConfigOption option) { + @NotNull + private String getOptionDescription(@NotNull ConfigOption option) { Object defaultValue = option.getDefaultValue(); String stringValue = String.valueOf(defaultValue); if (option.getDataType() == OptionDataType.STRING_LIST) { diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index ff09aa9..2ba5613 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -61,7 +61,9 @@ public class ConfigTabCompleter implements TabCompleter { * @param typedText

The beginning of the typed text, for filtering matching results

* @return

Some or all of the valid values for the option

*/ - private List getPossibleOptionValues(ConfigOption selectedOption, String typedText) { + @Nullable + private List getPossibleOptionValues(@NotNull ConfigOption selectedOption, + @NotNull String typedText) { switch (selectedOption) { case LANGUAGE: //Return available languages @@ -71,7 +73,7 @@ public class ConfigTabCompleter implements TabCompleter { case DEFAULT_GATE_NETWORK: //Just return the default value as most values should be possible if (typedText.trim().isEmpty()) { - return putStringInList((String) selectedOption.getDefaultValue()); + return List.of((String) selectedOption.getDefaultValue()); } else { return new ArrayList<>(); } @@ -114,7 +116,9 @@ public class ConfigTabCompleter implements TabCompleter { * @param args

The arguments given by the user

* @return

Some or all of the valid values for the option

*/ - private List getPossibleStringListOptionValues(ConfigOption selectedOption, String[] args) { + @Nullable + private List getPossibleStringListOptionValues(@NotNull ConfigOption selectedOption, + @NotNull String[] args) { if (selectedOption == ConfigOption.PER_SIGN_COLORS) { return getPerSignColorCompletion(args); } else { @@ -128,7 +132,8 @@ public class ConfigTabCompleter implements TabCompleter { * @param args

The arguments given by the user

* @return

The options to give the user

*/ - private List getPerSignColorCompletion(String[] args) { + @NotNull + private List getPerSignColorCompletion(@NotNull String[] args) { if (args.length < 3) { return filterMatchingStartsWith(signTypes, args[1]); } else if (args.length < 4) { @@ -139,18 +144,6 @@ public class ConfigTabCompleter implements TabCompleter { return new ArrayList<>(); } - /** - * Puts a single string value into a string list - * - * @param value

The string to make into a list

- * @return

A list containing the string value

- */ - private List putStringInList(String value) { - List list = new ArrayList<>(); - list.add(value); - return list; - } - /** * Initializes all lists of auto-completable values */ @@ -200,6 +193,7 @@ public class ConfigTabCompleter implements TabCompleter { * * @return

The available chat colors

*/ + @NotNull private List getChatColors() { List chatColors = new ArrayList<>(); char[] colors = new char[]{'a', 'b', 'c', 'd', 'e', 'f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; diff --git a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java index 96ecd3d..25c1d1d 100644 --- a/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/StarGateTabCompleter.java @@ -17,8 +17,9 @@ import java.util.List; public class StarGateTabCompleter implements TabCompleter { @Override - public @Nullable List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, - @NotNull String s, @NotNull String[] args) { + @Nullable + public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] args) { if (args.length == 1) { List commands = getAvailableCommands(commandSender); List matchingCommands = new ArrayList<>(); @@ -42,7 +43,8 @@ public class StarGateTabCompleter 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) { + @NotNull + private List getAvailableCommands(@NotNull CommandSender commandSender) { List commands = new ArrayList<>(); commands.add("about"); if (!(commandSender instanceof Player player) || player.hasPermission("stargate.admin.reload")) { diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java index e6879e5..5c41c71 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigOption.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigOption.java @@ -1,5 +1,8 @@ package net.knarcraft.stargate.config; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + /** * A ConfigOption represents one of the available config options */ @@ -209,7 +212,7 @@ public enum ConfigOption { * @param description

The description of what this config option does

* @param defaultValue

The default value of this config option

*/ - ConfigOption(String configNode, String description, Object defaultValue) { + ConfigOption(@NotNull String configNode, @NotNull String description, @NotNull Object defaultValue) { this.configNode = configNode; this.description = description; this.defaultValue = defaultValue; @@ -235,7 +238,7 @@ public enum ConfigOption { * @param name

The name of the config option to get

* @return

The corresponding config option, or null if the name is invalid

*/ - public static ConfigOption getByName(String name) { + public static @Nullable ConfigOption getByName(@NotNull String name) { for (ConfigOption option : ConfigOption.values()) { if (option.getName().equalsIgnoreCase(name)) { return option; @@ -249,7 +252,7 @@ public enum ConfigOption { * * @return

The name of this config option

*/ - public String getName() { + public @NotNull String getName() { if (!this.configNode.contains(".")) { return this.configNode; } @@ -262,7 +265,7 @@ public enum ConfigOption { * * @return

The data type used

*/ - public OptionDataType getDataType() { + public @NotNull OptionDataType getDataType() { return this.dataType; } @@ -271,7 +274,7 @@ public enum ConfigOption { * * @return

This config option's config node

*/ - public String getConfigNode() { + public @NotNull String getConfigNode() { return this.configNode; } @@ -280,7 +283,7 @@ public enum ConfigOption { * * @return

The description of this config option

*/ - public String getDescription() { + public @NotNull String getDescription() { return this.description; } @@ -289,7 +292,7 @@ public enum ConfigOption { * * @return

This config option's default value

*/ - public Object getDefaultValue() { + public @NotNull Object getDefaultValue() { return this.defaultValue; } diff --git a/src/main/java/net/knarcraft/stargate/config/ConfigTag.java b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java index 024b205..a992d46 100644 --- a/src/main/java/net/knarcraft/stargate/config/ConfigTag.java +++ b/src/main/java/net/knarcraft/stargate/config/ConfigTag.java @@ -1,25 +1,38 @@ package net.knarcraft.stargate.config; -import java.util.Arrays; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; /** * A config tag groups config values by a property */ public enum ConfigTag { - COLOR(new ConfigOption[]{ConfigOption.FREE_GATES_COLOR, ConfigOption.MAIN_SIGN_COLOR, - ConfigOption.HIGHLIGHT_SIGN_COLOR, ConfigOption.PER_SIGN_COLORS}), - FOLDER(new ConfigOption[]{ConfigOption.GATE_FOLDER, ConfigOption.PORTAL_FOLDER}), - DYNMAP(new ConfigOption[]{ConfigOption.ENABLE_DYNMAP, ConfigOption.DYNMAP_ICONS_DEFAULT_HIDDEN}); + /** + * Color-related configuration options + */ + COLOR(Set.of(ConfigOption.FREE_GATES_COLOR, ConfigOption.MAIN_SIGN_COLOR, ConfigOption.HIGHLIGHT_SIGN_COLOR, + ConfigOption.PER_SIGN_COLORS)), - private final ConfigOption[] taggedOptions; + /** + * Folder-altering configuration options + */ + FOLDER(Set.of(ConfigOption.GATE_FOLDER, ConfigOption.PORTAL_FOLDER)), + + /** + * Dynmap-related configuration options + */ + DYNMAP(Set.of(ConfigOption.ENABLE_DYNMAP, ConfigOption.DYNMAP_ICONS_DEFAULT_HIDDEN)); + + private final Set taggedOptions; /** * Instantiates a new config tag * * @param taggedOptions

The config options included in this tag

*/ - ConfigTag(ConfigOption[] taggedOptions) { + ConfigTag(@NotNull Set taggedOptions) { this.taggedOptions = taggedOptions; } @@ -29,8 +42,8 @@ public enum ConfigTag { * @param option

The config option to check

* @return

True of the config option is tagged

*/ - public boolean isTagged(ConfigOption option) { - return Arrays.stream(taggedOptions).anyMatch((item) -> item == option); + public boolean isTagged(@NotNull ConfigOption option) { + return taggedOptions.contains(option); } /** @@ -39,7 +52,7 @@ public enum ConfigTag { * @param configOption

The config option to check

* @return

True if changing the config option requires a "reload of colors" to take effect

*/ - public static boolean requiresColorReload(ConfigOption configOption) { + public static boolean requiresColorReload(@NotNull ConfigOption configOption) { return (COLOR.isTagged(configOption) && configOption != ConfigOption.FREE_GATES_COLOR); } @@ -49,7 +62,7 @@ public enum ConfigTag { * @param option

The config option to check

* @return

True if changing the config option requires a full reload to take effect

*/ - public static boolean requiresFullReload(ConfigOption option) { + public static boolean requiresFullReload(@NotNull ConfigOption option) { return FOLDER.isTagged(option); } @@ -59,7 +72,7 @@ public enum ConfigTag { * @param configOption

The config option to check

* @return

True if changing the config option requires a reload of all dynmap markers

*/ - public static boolean requiresDynmapReload(ConfigOption configOption) { + public static boolean requiresDynmapReload(@NotNull ConfigOption configOption) { return DYNMAP.isTagged(configOption); } @@ -69,7 +82,7 @@ public enum ConfigTag { * @param option

The config option to check

* @return

True if changing the config option requires a portal reload to take effect

*/ - public static boolean requiresPortalReload(ConfigOption option) { + public static boolean requiresPortalReload(@NotNull ConfigOption option) { return COLOR.isTagged(option) || FOLDER.isTagged(option) || option == ConfigOption.VERIFY_PORTALS; } @@ -79,7 +92,7 @@ public enum ConfigTag { * @param option

The config option to check

* @return

True if the language loader requires a reload

*/ - public static boolean requiresLanguageReload(ConfigOption option) { + public static boolean requiresLanguageReload(@NotNull ConfigOption option) { return option == ConfigOption.LANGUAGE; } @@ -89,7 +102,7 @@ public enum ConfigTag { * @param option

The config option to check

* @return

True if economy requires a reload

*/ - public static boolean requiresEconomyReload(ConfigOption option) { + public static boolean requiresEconomyReload(@NotNull ConfigOption option) { return option == ConfigOption.USE_ECONOMY; } diff --git a/src/main/java/net/knarcraft/stargate/config/DynmapManager.java b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java index 497ea84..67b015f 100644 --- a/src/main/java/net/knarcraft/stargate/config/DynmapManager.java +++ b/src/main/java/net/knarcraft/stargate/config/DynmapManager.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.config; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalRegistry; import org.bukkit.Location; @@ -10,6 +11,8 @@ import org.dynmap.markers.GenericMarker; import org.dynmap.markers.Marker; import org.dynmap.markers.MarkerIcon; import org.dynmap.markers.MarkerSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * A manager for dealing with everything Dynmap @@ -29,7 +32,7 @@ public final class DynmapManager { * @param dynmapAPI

A reference

* @throws NullPointerException

If dynmap has an invalid state

*/ - public static void initialize(DynmapAPI dynmapAPI) throws NullPointerException { + public static void initialize(@Nullable DynmapAPI dynmapAPI) throws NullPointerException { if (dynmapAPI == null || !dynmapAPI.markerAPIInitialized() || dynmapAPI.getMarkerAPI() == null) { markerSet = null; portalIcon = null; @@ -67,7 +70,7 @@ public final class DynmapManager { * * @param portal

The portal to add a marker for

*/ - public static void addPortalMarker(Portal portal) { + public static void addPortalMarker(@NotNull Portal portal) { if (markerSet == null || Stargate.getStargateConfig().isDynmapDisabled()) { return; } @@ -76,7 +79,13 @@ public final class DynmapManager { return; } - Location location = portal.getBlockAt(portal.getGate().getLayout().getExit()); + Location location; + @Nullable RelativeBlockVector exit = portal.getGate().getLayout().getExit(); + if (exit == null) { + location = portal.getTopLeft(); + } else { + location = portal.getBlockAt(exit); + } Marker marker = markerSet.createMarker(getPortalMarkerId(portal), portal.getName(), world.getName(), location.getX(), location.getY(), location.getZ(), portalIcon, false); if (marker == null) { @@ -112,7 +121,7 @@ public final class DynmapManager { * * @param portal

The portal to remove the marker for

*/ - public static void removePortalMarker(Portal portal) { + public static void removePortalMarker(@NotNull Portal portal) { if (markerSet == null || Stargate.getStargateConfig().isDynmapDisabled()) { return; } @@ -128,7 +137,7 @@ public final class DynmapManager { * @param portal

The portal to get a marker id for

* @return

*/ - private static String getPortalMarkerId(Portal portal) { + private static String getPortalMarkerId(@NotNull Portal portal) { return portal.getNetwork() + "-:-" + portal.getName(); } diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index b3b5d34..5058246 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -11,6 +11,8 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.ServicesManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Map; @@ -29,7 +31,7 @@ public final class EconomyConfig { * * @param configOptions

The loaded config options to read

*/ - public EconomyConfig(Map configOptions) { + public EconomyConfig(@NotNull Map configOptions) { this.configOptions = configOptions; try { String freeColor = (String) configOptions.get(ConfigOption.FREE_GATES_COLOR); @@ -62,6 +64,7 @@ public final class EconomyConfig { * * @return

An economy object, or null if economy is disabled or not initialized

*/ + @Nullable public Economy getEconomy() { return economy; } @@ -71,6 +74,7 @@ public final class EconomyConfig { * * @return

An instance of the Vault plugin, or null if Vault is not loaded

*/ + @Nullable public Plugin getVault() { return vault; } @@ -137,6 +141,7 @@ public final class EconomyConfig { * * @return

The account all taxes are paid to

*/ + @Nullable public String getTaxAccount() { return (String) configOptions.get(ConfigOption.TAX_ACCOUNT); } @@ -158,6 +163,7 @@ public final class EconomyConfig { * @param amount

The amount to display

* @return

A formatted text string describing the amount

*/ + @NotNull public String format(int amount) { if (isEconomyEnabled()) { return economy.format(amount); @@ -172,7 +178,7 @@ public final class EconomyConfig { * @param pluginManager

The plugin manager to get plugins from

* @return

True if economy was enabled

*/ - public boolean setupEconomy(PluginManager pluginManager) { + public boolean setupEconomy(@NotNull PluginManager pluginManager) { if (!isEconomyEnabled()) { return false; } @@ -211,7 +217,7 @@ public final class EconomyConfig { * @param gate

The gate type used

* @return

The cost of creating the gate

*/ - public int getCreateCost(Player player, Gate gate) { + public int getCreateCost(@NotNull Player player, @NotNull Gate gate) { if (isFree(player, "create")) { return 0; } else { @@ -226,7 +232,7 @@ public final class EconomyConfig { * @param gate

The gate type used

* @return

The cost of destroying the gate

*/ - public int getDestroyCost(Player player, Gate gate) { + public int getDestroyCost(@NotNull Player player, @NotNull Gate gate) { if (isFree(player, "destroy")) { return 0; } else { @@ -241,7 +247,7 @@ public final class EconomyConfig { * @param permissionNode

The free.permissionNode necessary to allow free gate {action}

* @return

*/ - private boolean isFree(Player player, String permissionNode) { + private boolean isFree(@NotNull Player player, @NotNull String permissionNode) { return !useEconomy() || PermissionHelper.hasPermission(player, "stargate.free." + permissionNode); } diff --git a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java index bd8a335..77b3ee3 100644 --- a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java @@ -3,6 +3,8 @@ package net.knarcraft.stargate.config; import net.knarcraft.knarlib.property.ColorConversion; import net.knarcraft.knarlib.util.FileHelper; import net.knarcraft.stargate.Stargate; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -30,7 +32,7 @@ public final class LanguageLoader { * * @param languageFolder

The folder containing the language files

*/ - public LanguageLoader(String languageFolder) { + public LanguageLoader(@NotNull String languageFolder) { this.languageFolder = languageFolder; File testFile = new File(languageFolder, "en.txt"); if (!testFile.exists()) { @@ -65,7 +67,8 @@ public final class LanguageLoader { * @param name

The name/key of the string to display

* @return

The string in the user's preferred language

*/ - public String getString(String name) { + @NotNull + public String getString(@NotNull String name) { String value = null; if (loadedStringTranslations != null) { value = loadedStringTranslations.get(name); @@ -82,7 +85,8 @@ public final class LanguageLoader { * @param name

The name/key of the string to display

* @return

The string in the backup language (English)

*/ - public String getBackupString(String name) { + @NotNull + public String getBackupString(@NotNull String name) { String value = null; if (loadedBackupStrings != null) { value = loadedBackupStrings.get(name); @@ -98,7 +102,7 @@ public final class LanguageLoader { * * @param chosenLanguage

The new plugin language

*/ - public void setChosenLanguage(String chosenLanguage) { + public void setChosenLanguage(@NotNull String chosenLanguage) { this.chosenLanguage = chosenLanguage; } @@ -107,7 +111,7 @@ public final class LanguageLoader { * * @param language

The language to update

*/ - private void updateLanguage(String language) { + private void updateLanguage(@NotNull String language) { Map currentLanguageValues = load(language); InputStream inputStream = getClass().getResourceAsStream("/lang/" + language + ".txt"); @@ -133,8 +137,8 @@ public final class LanguageLoader { * @param currentLanguageValues

The current values of the loaded/processed language

* @throws IOException

if unable to read a language file

*/ - private void readChangedLanguageStrings(InputStream inputStream, String language, Map currentLanguageValues) throws IOException { + private void readChangedLanguageStrings(@NotNull InputStream inputStream, @NotNull String language, + @Nullable Map currentLanguageValues) throws IOException { //Get language values BufferedReader bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream); Map internalLanguageValues = FileHelper.readKeyValuePairs(bufferedReader, "=", @@ -177,8 +181,8 @@ public final class LanguageLoader { * @param customLanguageStrings

Any custom language strings not recognized

* @throws IOException

If unable to write to the language file

*/ - private void updateLanguageFile(String language, Map languageStrings, - Map customLanguageStrings) throws IOException { + private void updateLanguageFile(@NotNull String language, @NotNull Map languageStrings, + @Nullable Map customLanguageStrings) throws IOException { BufferedWriter bufferedWriter = FileHelper.getBufferedWriterFromString(languageFolder + language + ".txt"); //Output normal Language data @@ -203,7 +207,8 @@ public final class LanguageLoader { * @param lang

The language to load

* @return

A mapping between loaded string indexes and the strings to display

*/ - private Map load(String lang) { + @Nullable + private Map load(@NotNull String lang) { return load(lang, null); } @@ -214,7 +219,8 @@ public final class LanguageLoader { * @param inputStream

An optional input stream to use. Defaults to using a file input stream

* @return

A mapping between loaded string indexes and the strings to display

*/ - private Map load(String lang, InputStream inputStream) { + @Nullable + private Map load(@NotNull String lang, @Nullable InputStream inputStream) { Map strings; BufferedReader bufferedReader; try { @@ -224,7 +230,7 @@ public final class LanguageLoader { bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream); } strings = FileHelper.readKeyValuePairs(bufferedReader, "=", ColorConversion.NORMAL); - } catch (Exception e) { + } catch (Exception exception) { if (Stargate.getStargateConfig().isDebuggingEnabled()) { Stargate.logInfo("Unable to load language " + lang); } diff --git a/src/main/java/net/knarcraft/stargate/config/MessageSender.java b/src/main/java/net/knarcraft/stargate/config/MessageSender.java index bfc706a..a021de4 100644 --- a/src/main/java/net/knarcraft/stargate/config/MessageSender.java +++ b/src/main/java/net/knarcraft/stargate/config/MessageSender.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.config; import net.md_5.bungee.api.ChatColor; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; /** * The message sender is responsible sending messages to players with correct coloring and formatting @@ -15,7 +16,7 @@ public final class MessageSender { * * @param languageLoader

The language loader to get translated strings from

*/ - public MessageSender(LanguageLoader languageLoader) { + public MessageSender(@NotNull LanguageLoader languageLoader) { this.languageLoader = languageLoader; } @@ -25,7 +26,7 @@ public final class MessageSender { * @param player

The player to send the message to

* @param message

The message to send

*/ - public void sendErrorMessage(CommandSender player, String message) { + public void sendErrorMessage(@NotNull CommandSender player, @NotNull String message) { sendMessage(player, message, true); } @@ -35,7 +36,7 @@ public final class MessageSender { * @param player

The player to send the message to

* @param message

The message to send

*/ - public void sendSuccessMessage(CommandSender player, String message) { + public void sendSuccessMessage(@NotNull CommandSender player, @NotNull String message) { sendMessage(player, message, false); } @@ -46,7 +47,7 @@ public final class MessageSender { * @param message

The message to send

* @param error

Whether the message sent is an error

*/ - private void sendMessage(CommandSender sender, String message, boolean error) { + private void sendMessage(@NotNull CommandSender sender, @NotNull String message, boolean error) { if (message.isEmpty()) { return; } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 768277e..1b9316c 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -19,6 +19,7 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.messaging.Messenger; import org.dynmap.DynmapAPI; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; @@ -58,7 +59,7 @@ public final class StargateConfig { * * @param logger

The logger to use for logging errors

*/ - public StargateConfig(Logger logger) { + public StargateConfig(@NotNull Logger logger) { this.logger = logger; configOptions = new HashMap<>(); @@ -76,6 +77,7 @@ public final class StargateConfig { * * @return

A reference to the config options map

*/ + @NotNull public Map getConfigOptionsReference() { return configOptions; } @@ -136,6 +138,7 @@ public final class StargateConfig { * * @return

The loaded config options

*/ + @NotNull public Map getConfigOptions() { return new HashMap<>(configOptions); } @@ -147,6 +150,7 @@ public final class StargateConfig { * * @return

The open portals queue

*/ + @NotNull public Queue getOpenPortalsQueue() { return openPortalsQueue; } @@ -158,6 +162,7 @@ public final class StargateConfig { * * @return

The active portals queue

*/ + @NotNull public Queue getActivePortalsQueue() { return activePortalsQueue; } @@ -203,6 +208,7 @@ public final class StargateConfig { * * @return

The object containing economy config values

*/ + @NotNull public EconomyConfig getEconomyConfig() { return this.economyConfig; } @@ -212,7 +218,7 @@ public final class StargateConfig { * * @param sender

The sender of the reload request

*/ - public void reload(CommandSender sender) { + public void reload(@NotNull CommandSender sender) { //Unload all saved data unload(); @@ -285,6 +291,7 @@ public final class StargateConfig { * * @return

The managed worlds

*/ + @NotNull public Set getManagedWorlds() { return new HashSet<>(managedWorlds); } @@ -294,7 +301,7 @@ public final class StargateConfig { * * @param worldName

The name of the world to manage

*/ - public void addManagedWorld(String worldName) { + public void addManagedWorld(@NotNull String worldName) { managedWorlds.add(worldName); } @@ -303,7 +310,7 @@ public final class StargateConfig { * * @param worldName

The name of the world to stop managing

*/ - public void removeManagedWorld(String worldName) { + public void removeManagedWorld(@NotNull String worldName) { managedWorlds.remove(worldName); } @@ -448,6 +455,7 @@ public final class StargateConfig { * * @return

Gets the gate config

*/ + @NotNull public StargateGateConfig getStargateGateConfig() { return stargateGateConfig; } @@ -465,13 +473,13 @@ public final class StargateConfig { * * @param currentConfiguration

The current config to back up

*/ - private void migrateConfig(FileConfiguration currentConfiguration) { + private void migrateConfig(@NotNull FileConfiguration currentConfiguration) { String debugPath = "StargateConfig::migrateConfig"; //Save the old config just in case something goes wrong try { currentConfiguration.save(new File(dataFolderPath, "config.yml.old")); - } catch (IOException e) { + } catch (IOException exception) { Stargate.debug(debugPath, "Unable to save old backup and do migration"); return; } @@ -489,7 +497,7 @@ public final class StargateConfig { migrationFields = FileHelper.readKeyValuePairs(FileHelper.getBufferedReaderFromInputStream( FileHelper.getInputStreamForInternalFile("/config-migrations.txt")), "=", ColorConversion.NORMAL); - } catch (IOException e) { + } catch (IOException exception) { Stargate.debug(debugPath, "Unable to load config migration file"); return; } @@ -530,9 +538,10 @@ public final class StargateConfig { */ private void setupVaultEconomy() { EconomyConfig economyConfig = getEconomyConfig(); - if (economyConfig.setupEconomy(Stargate.getPluginManager()) && economyConfig.getEconomy() != null) { + if (economyConfig.setupEconomy(Stargate.getPluginManager()) && economyConfig.getEconomy() != null && + economyConfig.getVault() != null) { String vaultVersion = economyConfig.getVault().getDescription().getVersion(); - Stargate.logInfo(Stargate.replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + Stargate.logInfo(Stargate.replacePlaceholders(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); } } @@ -578,6 +587,7 @@ public final class StargateConfig { * * @return

The portal folder

*/ + @NotNull public String getPortalFolder() { return portalFolder; } @@ -589,6 +599,7 @@ public final class StargateConfig { * * @return

The folder storing gate files

*/ + @NotNull public String getGateFolder() { return gateFolder; } @@ -598,6 +609,7 @@ public final class StargateConfig { * * @return

The sender for sending messages to players

*/ + @NotNull public MessageSender getMessageSender() { return messageSender; } @@ -607,6 +619,7 @@ public final class StargateConfig { * * @return

The language loader

*/ + @NotNull public LanguageLoader getLanguageLoader() { return languageLoader; } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index f97cd16..f3dc071 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -6,6 +6,7 @@ import net.knarcraft.stargate.portal.PortalSignDrawer; import net.md_5.bungee.api.ChatColor; import org.bukkit.Color; import org.bukkit.Material; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.HashMap; @@ -26,7 +27,7 @@ public final class StargateGateConfig { * * @param configOptions

The loaded config options to use

*/ - public StargateGateConfig(Map configOptions) { + public StargateGateConfig(@NotNull Map configOptions) { this.configOptions = configOptions; loadGateConfig(); } @@ -248,8 +249,8 @@ public final class StargateGateConfig { * @param defaultColors

The specified default colors

* @param colorMaps

The list of color maps to save the resulting colors to

*/ - private void parsePerSignColors(Object signColorSpecification, ChatColor[] defaultColors, - List> colorMaps) { + private void parsePerSignColors(@NotNull Object signColorSpecification, @NotNull ChatColor[] defaultColors, + @NotNull List> colorMaps) { String[] specificationData = String.valueOf(signColorSpecification).split(":"); Material[] signMaterials = new Material[]{Material.matchMaterial(specificationData[0] + "_SIGN"), Material.matchMaterial(specificationData[0] + "_WALL_SIGN")}; @@ -280,8 +281,8 @@ public final class StargateGateConfig { * @param signMaterials

The materials to load this color for

* @param colorMaps

The list of color maps to save the resulting color to

*/ - private void loadPerSignColor(String[] colors, int colorIndex, ChatColor[] defaultColors, Material[] signMaterials, - List> colorMaps) { + private void loadPerSignColor(@NotNull String[] colors, int colorIndex, @NotNull ChatColor[] defaultColors, + @NotNull Material[] signMaterials, @NotNull List> colorMaps) { ChatColor parsedColor; if (colors[colorIndex].equalsIgnoreCase("inverted")) { //Convert from ChatColor to awt.Color to Bukkit.Color then invert and convert to ChatColor @@ -309,7 +310,7 @@ public final class StargateGateConfig { * * @param mainSignColor

A string representing the main sign color

*/ - private void loadPerSignColor(String mainSignColor, String highlightSignColor) { + private void loadPerSignColor(@NotNull String mainSignColor, @NotNull String highlightSignColor) { try { PortalSignDrawer.setMainColor(ChatColor.of(mainSignColor.toUpperCase())); } catch (IllegalArgumentException | NullPointerException exception) { diff --git a/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java b/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java index 84b73b7..688e388 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java @@ -21,18 +21,20 @@ import java.util.List; */ public class StargateYamlConfiguration extends YamlConfiguration { - public static final String START_OF_COMMENT_LINE = "[HASHTAG]"; - static public final String END_OF_COMMENT = "_endOfComment_"; - static public final String START_OF_COMMENT = "comment_"; + private static final String START_OF_COMMENT_LINE = "[HASHTAG]"; + private static final String END_OF_COMMENT = "_endOfComment_"; + private static final String START_OF_COMMENT = "comment_"; @Override + @NotNull @SuppressWarnings("deprecation") - protected @NotNull String buildHeader() { + protected String buildHeader() { return ""; } @Override - public @NotNull String saveToString() { + @NotNull + public String saveToString() { // Convert YAML comments to normal comments return this.convertYAMLMappingsToComments(super.saveToString()); } @@ -51,7 +53,8 @@ public class StargateYamlConfiguration extends YamlConfiguration { * the {@link FileConfiguration#save(File)} method. The config * needs to be saved if a config value has changed.

*/ - private String convertCommentsToYAMLMappings(String configString) { + @NotNull + private String convertCommentsToYAMLMappings(@NotNull String configString) { StringBuilder yamlBuilder = new StringBuilder(); List currentComment = new ArrayList<>(); int commentId = 0; @@ -84,8 +87,8 @@ public class StargateYamlConfiguration extends YamlConfiguration { * @param previousIndentation

The indentation of the current block comment

* @param commentId

The id of the comment

*/ - private void addYamlString(StringBuilder yamlBuilder, List currentComment, String line, - int previousIndentation, int commentId) { + private void addYamlString(@NotNull StringBuilder yamlBuilder, @NotNull List currentComment, + @NotNull String line, int previousIndentation, int commentId) { String trimmed = line.trim(); //Write the full formatted comment to the StringBuilder if (!currentComment.isEmpty()) { @@ -105,7 +108,7 @@ public class StargateYamlConfiguration extends YamlConfiguration { * @param commentParts

The list to add to

* @param comment

The comment to add

*/ - private void addComment(List commentParts, String comment) { + private void addComment(@NotNull List commentParts, @NotNull String comment) { if (comment.startsWith("# ")) { commentParts.add(comment.replaceFirst("# ", START_OF_COMMENT_LINE)); } else { @@ -121,7 +124,8 @@ public class StargateYamlConfiguration extends YamlConfiguration { * @param commentId

The unique id of the comment

* @param indentation

The indentation to add to every line

*/ - private void generateCommentYAML(StringBuilder yamlBuilder, List commentLines, int commentId, int indentation) { + private void generateCommentYAML(@NotNull StringBuilder yamlBuilder, @NotNull List commentLines, + int commentId, int indentation) { String subIndentation = this.addIndentation(indentation + 2); //Add the comment start marker yamlBuilder.append(this.addIndentation(indentation)).append(START_OF_COMMENT).append(commentId).append(": |\n"); @@ -143,7 +147,8 @@ public class StargateYamlConfiguration extends YamlConfiguration { * @param yamlString

A string using the YAML format

* @return

The corresponding comment string

*/ - private String convertYAMLMappingsToComments(String yamlString) { + @NotNull + private String convertYAMLMappingsToComments(@NotNull String yamlString) { StringBuilder finalText = new StringBuilder(); String[] lines = yamlString.split("\n"); @@ -173,7 +178,8 @@ public class StargateYamlConfiguration extends YamlConfiguration { * @param commentIndentation

The indentation of the read comment

* @return

The index containing the next non-comment line

*/ - private int readComment(StringBuilder builder, String[] lines, int startIndex, int commentIndentation) { + private int readComment(@NotNull StringBuilder builder, @NotNull String[] lines, int startIndex, + int commentIndentation) { for (int currentIndex = startIndex; currentIndex < lines.length; currentIndex++) { String line = lines[currentIndex]; String possibleComment = line.trim(); @@ -194,6 +200,7 @@ public class StargateYamlConfiguration extends YamlConfiguration { * @param indentationSpaces

The number spaces to use for indentation

* @return

A string containing the number of spaces specified

*/ + @NotNull private String addIndentation(int indentationSpaces) { return " ".repeat(Math.max(0, indentationSpaces)); } @@ -205,7 +212,7 @@ public class StargateYamlConfiguration extends YamlConfiguration { * @param line

The line to get indentation of

* @return

The number of spaces in the line's indentation

*/ - private int getIndentation(String line) { + private int getIndentation(@NotNull String line) { int spacesFound = 0; for (char aCharacter : line.toCharArray()) { if (aCharacter == ' ') { diff --git a/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java b/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java index 55e5269..3603503 100644 --- a/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockChangeRequest.java @@ -2,6 +2,8 @@ package net.knarcraft.stargate.container; import org.bukkit.Axis; import org.bukkit.Material; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Represents a request for changing a block into another material @@ -19,7 +21,7 @@ public class BlockChangeRequest { * @param material

The new material to change the block to

* @param axis

The new axis to orient the block along

*/ - public BlockChangeRequest(BlockLocation blockLocation, Material material, Axis axis) { + public BlockChangeRequest(@NotNull BlockLocation blockLocation, @NotNull Material material, @Nullable Axis axis) { this.blockLocation = blockLocation; newMaterial = material; newAxis = axis; @@ -30,6 +32,7 @@ public class BlockChangeRequest { * * @return

The location of the block

*/ + @NotNull public BlockLocation getBlockLocation() { return blockLocation; } @@ -39,6 +42,7 @@ public class BlockChangeRequest { * * @return

The material to change the block into

*/ + @NotNull public Material getMaterial() { return newMaterial; } @@ -48,6 +52,7 @@ public class BlockChangeRequest { * * @return

The axis to orient the block along

*/ + @Nullable public Axis getAxis() { return newAxis; } diff --git a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java index bb8b533..bf84940 100644 --- a/src/main/java/net/knarcraft/stargate/container/BlockLocation.java +++ b/src/main/java/net/knarcraft/stargate/container/BlockLocation.java @@ -10,6 +10,8 @@ import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; import org.bukkit.block.data.type.Sign; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * This class represents a block location @@ -30,7 +32,7 @@ public class BlockLocation extends Location { * @param y

The y coordinate of the block

* @param z

The z coordinate of the block

*/ - public BlockLocation(World world, int x, int y, int z) { + public BlockLocation(@NotNull World world, int x, int y, int z) { super(world, x, y, z); } @@ -39,7 +41,7 @@ public class BlockLocation extends Location { * * @param block

The block to get the location of

*/ - public BlockLocation(Block block) { + public BlockLocation(@NotNull Block block) { super(block.getWorld(), block.getX(), block.getY(), block.getZ()); } @@ -49,7 +51,7 @@ public class BlockLocation extends Location { * @param world

The world the block exists in

* @param string

A comma separated list of x, y and z coordinates as integers

*/ - public BlockLocation(World world, String string) { + public BlockLocation(@NotNull World world, @NotNull String string) { super(world, Integer.parseInt(string.split(",")[0]), Integer.parseInt(string.split(",")[1]), Integer.parseInt(string.split(",")[2])); } @@ -62,6 +64,7 @@ public class BlockLocation extends Location { * @param z

The number of blocks to move in the z-direction

* @return

A new block location

*/ + @NotNull public BlockLocation makeRelativeBlockLocation(int x, int y, int z) { return (BlockLocation) this.clone().add(x, y, z); } @@ -75,6 +78,7 @@ public class BlockLocation extends Location { * @param yaw

The number of blocks to move in the z-direction

* @return

A new location

*/ + @NotNull public Location makeRelativeLocation(double x, double y, double z, float yaw) { Location newLocation = this.clone(); newLocation.setYaw(yaw); @@ -89,9 +93,10 @@ public class BlockLocation extends Location { * @param yaw

The yaw pointing outwards from a portal (in the relative vector's out direction)

* @return

A location relative to this location

*/ - public BlockLocation getRelativeLocation(RelativeBlockVector relativeVector, double yaw) { - Vector realVector = DirectionHelper.getCoordinateVectorFromRelativeVector(relativeVector.getRight(), - relativeVector.getDown(), relativeVector.getOut(), yaw); + @NotNull + public BlockLocation getRelativeLocation(@NotNull RelativeBlockVector relativeVector, double yaw) { + Vector realVector = DirectionHelper.getCoordinateVectorFromRelativeVector(relativeVector.right(), + relativeVector.down(), relativeVector.out(), yaw); return makeRelativeBlockLocation(realVector.getBlockX(), realVector.getBlockY(), realVector.getBlockZ()); } @@ -107,6 +112,7 @@ public class BlockLocation extends Location { * @param portalYaw

The yaw when looking out from the portal

* @return A new location relative to this block location */ + @NotNull public Location getRelativeLocation(double right, double down, double out, float portalYaw) { Vector realVector = DirectionHelper.getCoordinateVectorFromRelativeVector(right, down, out, portalYaw); return makeRelativeLocation(0.5 + realVector.getBlockX(), realVector.getBlockY(), @@ -118,6 +124,7 @@ public class BlockLocation extends Location { * * @return

The block's material type

*/ + @NotNull public Material getType() { return this.getBlock().getType(); } @@ -127,7 +134,7 @@ public class BlockLocation extends Location { * * @param type

The block's new material type

*/ - public void setType(Material type) { + public void setType(@NotNull Material type) { this.getBlock().setType(type); } @@ -136,6 +143,7 @@ public class BlockLocation extends Location { * * @return

The location representing this block location

*/ + @NotNull public Location getLocation() { return this.clone(); } @@ -148,6 +156,7 @@ public class BlockLocation extends Location { * * @return

This block location's parent block

*/ + @Nullable public Block getParent() { if (parent == null) { findParent(); @@ -184,6 +193,7 @@ public class BlockLocation extends Location { } @Override + @NotNull public String toString() { return String.valueOf(this.getBlockX()) + ',' + this.getBlockY() + ',' + this.getBlockZ(); } @@ -203,7 +213,7 @@ public class BlockLocation extends Location { } @Override - public boolean equals(Object object) { + public boolean equals(@Nullable Object object) { if (this == object) { return true; } diff --git a/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java b/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java index 4c47d15..de62651 100644 --- a/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java +++ b/src/main/java/net/knarcraft/stargate/container/ChunkUnloadRequest.java @@ -17,7 +17,7 @@ public class ChunkUnloadRequest implements Comparable { * @param chunkToUnload

The chunk to request the unloading of

* @param timeUntilUnload

The time in milliseconds to wait before unloading the chunk

*/ - public ChunkUnloadRequest(Chunk chunkToUnload, Long timeUntilUnload) { + public ChunkUnloadRequest(@NotNull Chunk chunkToUnload, @NotNull Long timeUntilUnload) { this.chunkToUnload = chunkToUnload; long systemNanoTime = System.nanoTime(); this.unloadNanoTime = systemNanoTime + (timeUntilUnload * 1000000); @@ -28,6 +28,7 @@ public class ChunkUnloadRequest implements Comparable { * * @return

The chunk to unload

*/ + @NotNull public Chunk getChunkToUnload() { return this.chunkToUnload; } @@ -37,11 +38,13 @@ public class ChunkUnloadRequest implements Comparable { * * @return

The system nano time denoting when the chunk is to be unloaded

*/ + @NotNull public Long getUnloadNanoTime() { return this.unloadNanoTime; } @Override + @NotNull public String toString() { return "{" + chunkToUnload + ", " + unloadNanoTime + "}"; } diff --git a/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java b/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java index 54c7171..736f847 100644 --- a/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java +++ b/src/main/java/net/knarcraft/stargate/container/FromTheEndTeleportation.java @@ -1,60 +1,16 @@ package net.knarcraft.stargate.container; import net.knarcraft.stargate.portal.Portal; -import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; /** - * This class represents a player teleporting from the end to the over-world using an artificial end portal + * This class represents a teleportation from the end to the over-world using an artificial end portal * *

This is necessary because a player entering an end portal in the end is a special case. Instead of being * teleported, the player is respawned. Because of this, the teleportation needs to be saved and later used to hijack * the position of where the player is to respawn.

+ * + * @param exitPortal

The portal the player should exit from when arriving in the over-world

*/ -public class FromTheEndTeleportation { - - private final Player teleportingPlayer; - private final Portal exitPortal; - - /** - * Instantiates a new teleportation from the end - * - * @param teleportingPlayer

The teleporting player

- * @param exitPortal

The portal to exit from

- */ - public FromTheEndTeleportation(Player teleportingPlayer, Portal exitPortal) { - this.teleportingPlayer = teleportingPlayer; - this.exitPortal = exitPortal; - } - - /** - * Gets the teleporting player - * - * @return

The teleporting player

- */ - public Player getPlayer() { - return this.teleportingPlayer; - } - - /** - * Gets the portal to exit from - * - * @return

The portal to exit from

- */ - public Portal getExit() { - return this.exitPortal; - } - - @Override - public int hashCode() { - return teleportingPlayer.hashCode(); - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof FromTheEndTeleportation otherTeleportation)) { - return false; - } - return teleportingPlayer.equals(otherTeleportation.teleportingPlayer); - } - +public record FromTheEndTeleportation(@NotNull Portal exitPortal) { } diff --git a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java index 847c7ff..e06d08e 100644 --- a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java @@ -1,5 +1,8 @@ package net.knarcraft.stargate.container; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + /** * This stores a block location as a vector relative to a position * @@ -7,62 +10,48 @@ package net.knarcraft.stargate.container; * top-left block of a gate (top-left when looking at the side with the sign). The right is therefore the distance * from the top-left corner towards the top-right corner. Down is the distance from the top-left corner towards the * bottom-left corner. Out is the distance outward from the gate.

+ * + *

Relative block vectors start from a top-left corner. A yaw is used to orient a relative block vector in the + * "real world". In terms of a gate layout, the origin is 0,0. Right is towards the end of the line. Down is to the + * next line. Out is towards the observer.

+ * + * @param right

The distance rightward relative to the origin

+ * @param down

The distance downward relative to the origin

+ * @param out

The distance outward relative to the origin

*/ -public class RelativeBlockVector { - - private final int right; - private final int down; - private final int out; +public record RelativeBlockVector(int right, int down, int out) { /** - * A specifier for one of the relative block vector's three properties + * Adds the given value to this relative block vector's "right" property + * + * @param valueToAdd

The value to add

+ * @return

The new resulting vector

*/ - public enum Property { - /** - * Specifies the relative block vector's right property - */ - RIGHT, - /** - * Specifies the relative block vector's down property - */ - DOWN, - /** - * Specifies the relative block vector's out property - */ - OUT + @NotNull + public RelativeBlockVector addRight(int valueToAdd) { + return new RelativeBlockVector(this.right + valueToAdd, this.down, this.out); } /** - * Instantiates a new relative block vector + * Adds the given value to this relative block vector's "down" property * - *

Relative block vectors start from a top-left corner. A yaw is used to orient a relative block vector in the - * "real world". - * In terms of a gate layout, the origin is 0,0. Right is towards the end of the line. Down is to the - * next line. Out is towards the observer.

- * - * @param right

The distance rightward relative to the origin

- * @param down

The distance downward relative to the origin

- * @param out

The distance outward relative to the origin

+ * @param valueToAdd

The value to add

+ * @return

The new resulting vector

*/ - public RelativeBlockVector(int right, int down, int out) { - this.right = right; - this.down = down; - this.out = out; + @NotNull + public RelativeBlockVector addDown(int valueToAdd) { + return new RelativeBlockVector(this.right, this.down + valueToAdd, this.out); } /** - * Adds a value to one of the properties of this relative block vector + * Adds the given value to this relative block vector's "out" property * - * @param propertyToAddTo

The property to add to

- * @param valueToAdd

The value to add to the property (negative to move in the opposite direction)

- * @return

A new relative block vector with the property altered

+ * @param valueToAdd

The value to add

+ * @return

The new resulting vector

*/ - public RelativeBlockVector addToVector(Property propertyToAddTo, int valueToAdd) { - return switch (propertyToAddTo) { - case RIGHT -> new RelativeBlockVector(this.right + valueToAdd, this.down, this.out); - case DOWN -> new RelativeBlockVector(this.right, this.down + valueToAdd, this.out); - case OUT -> new RelativeBlockVector(this.right, this.down, this.out + valueToAdd); - }; + @NotNull + public RelativeBlockVector addOut(int valueToAdd) { + return new RelativeBlockVector(this.right, this.down, this.out + valueToAdd); } /** @@ -70,6 +59,7 @@ public class RelativeBlockVector { * * @return

This vector, but inverted

*/ + @NotNull public RelativeBlockVector invert() { return new RelativeBlockVector(-this.right, -this.down, -this.out); } @@ -79,7 +69,8 @@ public class RelativeBlockVector { * * @return

The distance to the right relative to the origin

*/ - public int getRight() { + @Override + public int right() { return right; } @@ -88,7 +79,8 @@ public class RelativeBlockVector { * * @return

The distance downward relative to the origin

*/ - public int getDown() { + @Override + public int down() { return down; } @@ -97,17 +89,19 @@ public class RelativeBlockVector { * * @return

The distance outward relative to the origin

*/ - public int getOut() { + @Override + public int out() { return out; } @Override + @NotNull public String toString() { return String.format("(right = %d, down = %d, out = %d)", right, down, out); } @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { if (other == this) { return true; } diff --git a/src/main/java/net/knarcraft/stargate/container/SignData.java b/src/main/java/net/knarcraft/stargate/container/SignData.java index ccb25fb..8d65caa 100644 --- a/src/main/java/net/knarcraft/stargate/container/SignData.java +++ b/src/main/java/net/knarcraft/stargate/container/SignData.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.utility.SignHelper; import net.md_5.bungee.api.ChatColor; import org.bukkit.DyeColor; import org.bukkit.block.Sign; +import org.jetbrains.annotations.NotNull; /** * A class that keeps track of the sign colors for a given sign @@ -23,7 +24,7 @@ public class SignData { * @param mainSignColor

The main color to use for the sign

* @param highlightSignColor

The highlighting color to use for the sign

*/ - public SignData(Sign sign, ChatColor mainSignColor, ChatColor highlightSignColor) { + public SignData(@NotNull Sign sign, @NotNull ChatColor mainSignColor, @NotNull ChatColor highlightSignColor) { this.sign = sign; this.mainSignColor = mainSignColor; this.highlightSignColor = highlightSignColor; @@ -35,6 +36,7 @@ public class SignData { * * @return

The sign of this sign colors object

*/ + @NotNull public Sign getSign() { return sign; } @@ -44,6 +46,7 @@ public class SignData { * * @return

The main color of the sign

*/ + @NotNull public ChatColor getMainSignColor() { if (dyedColor != DyeColor.BLACK) { return ColorHelper.fromColor(dyedColor.getColor()); @@ -57,6 +60,7 @@ public class SignData { * * @return

The highlighting color of the sign

*/ + @NotNull public ChatColor getHighlightSignColor() { if (dyedColor != DyeColor.BLACK) { return ColorHelper.fromColor(ColorHelper.invert(dyedColor.getColor())); diff --git a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java index 5b64a14..83328ac 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateAccessEvent.java @@ -24,7 +24,7 @@ public class StargateAccessEvent extends StargatePlayerEvent { * @param portal

The portal involved in the event

* @param deny

Whether the stargate access should be denied

*/ - public StargateAccessEvent(Player player, Portal portal, boolean deny) { + public StargateAccessEvent(@NotNull Player player, @NotNull Portal portal, boolean deny) { super(portal, player); this.deny = deny; @@ -53,6 +53,7 @@ public class StargateAccessEvent extends StargatePlayerEvent { * * @return

A handler-list with all event handlers

*/ + @NotNull public static HandlerList getHandlerList() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java index 3d09661..6509d90 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateActivateEvent.java @@ -28,7 +28,8 @@ public class StargateActivateEvent extends StargatePlayerEvent { * @param destinations

The destinations available to the player using the portal

* @param destination

The currently selected destination

*/ - public StargateActivateEvent(Portal portal, Player player, List destinations, String destination) { + public StargateActivateEvent(@NotNull Portal portal, @NotNull Player player, @NotNull List destinations, + @NotNull String destination) { super(portal, player); this.destinations = destinations; @@ -40,6 +41,7 @@ public class StargateActivateEvent extends StargatePlayerEvent { * * @return

The destinations available for the portal

*/ + @NotNull public List getDestinations() { return destinations; } @@ -49,7 +51,7 @@ public class StargateActivateEvent extends StargatePlayerEvent { * * @param destinations

The new list of available destinations

*/ - public void setDestinations(List destinations) { + public void setDestinations(@NotNull List destinations) { this.destinations = destinations; } @@ -58,6 +60,7 @@ public class StargateActivateEvent extends StargatePlayerEvent { * * @return

The selected destination

*/ + @NotNull public String getDestination() { return destination; } @@ -67,7 +70,7 @@ public class StargateActivateEvent extends StargatePlayerEvent { * * @param destination

The new selected destination

*/ - public void setDestination(String destination) { + public void setDestination(@NotNull String destination) { this.destination = destination; } @@ -76,6 +79,7 @@ public class StargateActivateEvent extends StargatePlayerEvent { * * @return

A handler-list with all event handlers

*/ + @NotNull public static HandlerList getHandlerList() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java index 3f2ff07..2a00e52 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCloseEvent.java @@ -22,7 +22,7 @@ public class StargateCloseEvent extends StargateEvent { * @param portal

The portal to close

* @param force

Whether to force the gate to close, even if set as always-on

*/ - public StargateCloseEvent(Portal portal, boolean force) { + public StargateCloseEvent(@NotNull Portal portal, boolean force) { super(portal); this.force = force; @@ -51,6 +51,7 @@ public class StargateCloseEvent extends StargateEvent { * * @return

A handler-list with all event handlers

*/ + @NotNull public static HandlerList getHandlerList() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java index 1f66e60..20b58c1 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateCreateEvent.java @@ -29,7 +29,8 @@ public class StargateCreateEvent extends StargatePlayerEvent { * @param denyReason

The reason stargate creation was denied

* @param cost

The cost of creating the new star gate

*/ - public StargateCreateEvent(Player player, Portal portal, String[] lines, boolean deny, String denyReason, int cost) { + public StargateCreateEvent(@NotNull Player player, @NotNull Portal portal, @NotNull String[] lines, boolean deny, + @NotNull String denyReason, int cost) { super(portal, player); this.lines = lines; this.deny = deny; @@ -44,6 +45,7 @@ public class StargateCreateEvent extends StargatePlayerEvent { * @return

The text on the given line

* @throws IndexOutOfBoundsException

If given a line index less than zero or above three

*/ + @NotNull public String getLine(int index) throws IndexOutOfBoundsException { return lines[index]; } @@ -71,6 +73,7 @@ public class StargateCreateEvent extends StargatePlayerEvent { * * @return

The reason the stargate creation was denied

*/ + @NotNull public String getDenyReason() { return denyReason; } @@ -80,7 +83,7 @@ public class StargateCreateEvent extends StargatePlayerEvent { * * @param denyReason

The new reason why the stargate creation was denied

*/ - public void setDenyReason(String denyReason) { + public void setDenyReason(@NotNull String denyReason) { this.denyReason = denyReason; } @@ -107,6 +110,7 @@ public class StargateCreateEvent extends StargatePlayerEvent { * * @return

A handler-list with all event handlers

*/ + @NotNull public static HandlerList getHandlerList() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java index 3314ac1..c81e901 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDeactivateEvent.java @@ -20,7 +20,7 @@ public class StargateDeactivateEvent extends StargateEvent { * * @param portal

The portal which was deactivated

*/ - public StargateDeactivateEvent(Portal portal) { + public StargateDeactivateEvent(@NotNull Portal portal) { super(portal); } @@ -29,6 +29,7 @@ public class StargateDeactivateEvent extends StargateEvent { * * @return

A handler-list with all event handlers

*/ + @NotNull public static HandlerList getHandlerList() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java index bfcc606..3e9a6f5 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateDestroyEvent.java @@ -27,7 +27,8 @@ public class StargateDestroyEvent extends StargatePlayerEvent { * @param denyMsg

The message to display if the event is denied

* @param cost

The cost of destroying the portal

*/ - public StargateDestroyEvent(Portal portal, Player player, boolean deny, String denyMsg, int cost) { + public StargateDestroyEvent(@NotNull Portal portal, @NotNull Player player, boolean deny, @NotNull String denyMsg, + int cost) { super(portal, player); this.deny = deny; this.denyReason = denyMsg; @@ -57,6 +58,7 @@ public class StargateDestroyEvent extends StargatePlayerEvent { * * @return

The reason the event was denied

*/ + @NotNull public String getDenyReason() { return denyReason; } @@ -66,7 +68,7 @@ public class StargateDestroyEvent extends StargatePlayerEvent { * * @param denyReason

The reason the event was denied

*/ - public void setDenyReason(String denyReason) { + public void setDenyReason(@NotNull String denyReason) { this.denyReason = denyReason; } @@ -93,6 +95,7 @@ public class StargateDestroyEvent extends StargatePlayerEvent { * * @return

A handler-list with all event handlers

*/ + @NotNull public static HandlerList getHandlerList() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java index cd34504..5f4a4a1 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEntityPortalEvent.java @@ -27,7 +27,8 @@ public class StargateEntityPortalEvent extends StargateEvent implements Stargate * @param destination

The destination the entity should exit from

* @param exit

The exit location of the destination portal the entity will be teleported to

*/ - public StargateEntityPortalEvent(Entity travellingEntity, Portal portal, Portal destination, Location exit) { + public StargateEntityPortalEvent(@NotNull Entity travellingEntity, @NotNull Portal portal, + @NotNull Portal destination, @NotNull Location exit) { super(portal); this.travellingEntity = travellingEntity; @@ -40,6 +41,7 @@ public class StargateEntityPortalEvent extends StargateEvent implements Stargate * * @return

The non-player teleporting

*/ + @NotNull public Entity getEntity() { return travellingEntity; } @@ -49,6 +51,7 @@ public class StargateEntityPortalEvent extends StargateEvent implements Stargate * * @return

The destination portal

*/ + @NotNull public Portal getDestination() { return destination; } @@ -59,6 +62,7 @@ public class StargateEntityPortalEvent extends StargateEvent implements Stargate * @return

Location of the exit point

*/ @Override + @NotNull public Location getExit() { return exit; } @@ -68,7 +72,7 @@ public class StargateEntityPortalEvent extends StargateEvent implements Stargate * * @param location

The new location of the entity's exit point

*/ - public void setExit(Location location) { + public void setExit(@NotNull Location location) { this.exit = location; } @@ -77,6 +81,7 @@ public class StargateEntityPortalEvent extends StargateEvent implements Stargate * * @return

A handler-list with all event handlers

*/ + @NotNull public static HandlerList getHandlerList() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java index f67a388..911937f 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateEvent.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.event; import net.knarcraft.stargate.portal.Portal; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; +import org.jetbrains.annotations.NotNull; /** * An abstract event describing any stargate event @@ -18,7 +19,7 @@ public abstract class StargateEvent extends Event implements Cancellable { * * @param portal

The portal involved in this stargate event

*/ - StargateEvent(Portal portal) { + StargateEvent(@NotNull Portal portal) { this.portal = portal; this.cancelled = false; } @@ -28,6 +29,7 @@ public abstract class StargateEvent extends Event implements Cancellable { * * @return

The portal involved in this stargate event

*/ + @NotNull public Portal getPortal() { return portal; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java index ce10534..0767f05 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateOpenEvent.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * This event should be called whenever a player opens a stargate @@ -23,7 +24,7 @@ public class StargateOpenEvent extends StargatePlayerEvent { * @param portal

The opened portal

* @param force

Whether to force the portal open

*/ - public StargateOpenEvent(Player player, Portal portal, boolean force) { + public StargateOpenEvent(@Nullable Player player, @NotNull Portal portal, boolean force) { super(portal, player); this.force = force; @@ -52,6 +53,7 @@ public class StargateOpenEvent extends StargatePlayerEvent { * * @return

A handler-list with all event handlers

*/ + @NotNull public static HandlerList getHandlerList() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java index 14514f6..ff701e4 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePlayerEvent.java @@ -2,6 +2,8 @@ package net.knarcraft.stargate.event; import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * An abstract event describing any stargate event where a player is involved @@ -16,7 +18,7 @@ public abstract class StargatePlayerEvent extends StargateEvent { * * @param portal

The portal involved in this stargate event

*/ - StargatePlayerEvent(Portal portal, Player player) { + StargatePlayerEvent(@NotNull Portal portal, @Nullable Player player) { super(portal); this.player = player; } @@ -26,6 +28,7 @@ public abstract class StargatePlayerEvent extends StargateEvent { * * @return

The player creating the star gate

*/ + @Nullable public Player getPlayer() { return player; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java b/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java index 3d2526a..6bb4f88 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargatePlayerPortalEvent.java @@ -26,7 +26,8 @@ public class StargatePlayerPortalEvent extends StargatePlayerEvent implements St * @param destination

The destination the player should exit from

* @param exit

The exit location of the destination portal the user will be teleported to

*/ - public StargatePlayerPortalEvent(Player player, Portal portal, Portal destination, Location exit) { + public StargatePlayerPortalEvent(@NotNull Player player, @NotNull Portal portal, @NotNull Portal destination, + @NotNull Location exit) { super(portal, player); this.destination = destination; @@ -38,6 +39,7 @@ public class StargatePlayerPortalEvent extends StargatePlayerEvent implements St * * @return

The destination portal

*/ + @NotNull public Portal getDestination() { return destination; } @@ -48,6 +50,7 @@ public class StargatePlayerPortalEvent extends StargatePlayerEvent implements St * @return

Location of the exit point

*/ @Override + @NotNull public Location getExit() { return exit; } @@ -57,7 +60,7 @@ public class StargatePlayerPortalEvent extends StargatePlayerEvent implements St * * @param location

The new location of the player's exit point

*/ - public void setExit(Location location) { + public void setExit(@NotNull Location location) { this.exit = location; } @@ -66,6 +69,7 @@ public class StargatePlayerPortalEvent extends StargatePlayerEvent implements St * * @return

A handler-list with all event handlers

*/ + @NotNull public static HandlerList getHandlerList() { return handlers; } diff --git a/src/main/java/net/knarcraft/stargate/event/StargateTeleportEvent.java b/src/main/java/net/knarcraft/stargate/event/StargateTeleportEvent.java index e440828..35bef4e 100644 --- a/src/main/java/net/knarcraft/stargate/event/StargateTeleportEvent.java +++ b/src/main/java/net/knarcraft/stargate/event/StargateTeleportEvent.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.event; import org.bukkit.Location; import org.bukkit.event.Cancellable; +import org.jetbrains.annotations.NotNull; /** * A generic teleportation event @@ -13,6 +14,7 @@ public interface StargateTeleportEvent extends Cancellable { * * @return

Location of the exit point

*/ + @NotNull Location getExit(); } diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index f443569..25230f8 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -28,6 +28,7 @@ import org.bukkit.event.block.BlockPistonRetractEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.EntityBlockFormEvent; import org.bukkit.event.block.SignChangeEvent; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -46,7 +47,7 @@ public class BlockEventListener implements Listener { * @param event

The triggered event

*/ @EventHandler - public void onBlockFormedByEntity(EntityBlockFormEvent event) { + public void onBlockFormedByEntity(@NotNull EntityBlockFormEvent event) { if (event.isCancelled() || (!Stargate.getGateConfig().protectEntrance() && !Stargate.getGateConfig().verifyPortals())) { return; @@ -67,7 +68,7 @@ public class BlockEventListener implements Listener { * @param event

The triggered event

*/ @EventHandler - public void onSignChange(SignChangeEvent event) { + public void onSignChange(@NotNull SignChangeEvent event) { if (event.isCancelled()) { return; } @@ -98,7 +99,7 @@ public class BlockEventListener implements Listener { } @EventHandler(priority = EventPriority.HIGHEST) - public void onBlockPlace(BlockPlaceEvent event) { + public void onBlockPlace(@NotNull BlockPlaceEvent event) { if (event.isCancelled() || !Stargate.getGateConfig().protectEntrance()) { return; } @@ -119,7 +120,7 @@ public class BlockEventListener implements Listener { * @param event

The triggered event

*/ @EventHandler(priority = EventPriority.HIGHEST) - public void onBlockBreak(BlockBreakEvent event) { + public void onBlockBreak(@NotNull BlockBreakEvent event) { if (event.isCancelled()) { return; } @@ -182,8 +183,8 @@ public class BlockEventListener implements Listener { * @param event

The break event

* @return

True if the payment was successful. False if the event was cancelled

*/ - private boolean handleEconomyPayment(StargateDestroyEvent destroyEvent, Player player, Portal portal, - BlockBreakEvent event) { + private boolean handleEconomyPayment(@NotNull StargateDestroyEvent destroyEvent, @NotNull Player player, + @NotNull Portal portal, @NotNull BlockBreakEvent event) { int cost = destroyEvent.getCost(); if (cost != 0) { String portalName = portal.getName(); @@ -210,7 +211,7 @@ public class BlockEventListener implements Listener { * @param event

The event to check and possibly cancel

*/ @EventHandler - public void onBlockPhysics(BlockPhysicsEvent event) { + public void onBlockPhysics(@NotNull BlockPhysicsEvent event) { Block block = event.getBlock(); Portal portal = null; @@ -230,7 +231,7 @@ public class BlockEventListener implements Listener { * @param event

The event to check and possibly cancel

*/ @EventHandler - public void onBlockFromTo(BlockFromToEvent event) { + public void onBlockFromTo(@NotNull BlockFromToEvent event) { Portal portal = PortalHandler.getByEntrance(event.getBlock()); if (portal != null) { @@ -244,7 +245,7 @@ public class BlockEventListener implements Listener { * @param event

The event to check and possibly cancel

*/ @EventHandler - public void onPistonExtend(BlockPistonExtendEvent event) { + public void onPistonExtend(@NotNull BlockPistonExtendEvent event) { cancelPistonEvent(event, event.getBlocks()); } @@ -254,7 +255,7 @@ public class BlockEventListener implements Listener { * @param event

The event to check and possibly cancel

*/ @EventHandler - public void onPistonRetract(BlockPistonRetractEvent event) { + public void onPistonRetract(@NotNull BlockPistonRetractEvent event) { if (!event.isSticky()) { return; } @@ -267,7 +268,7 @@ public class BlockEventListener implements Listener { * @param event

The event to cancel

* @param blocks

The blocks included in the event

*/ - private void cancelPistonEvent(BlockPistonEvent event, List blocks) { + private void cancelPistonEvent(@NotNull BlockPistonEvent event, @NotNull List blocks) { for (Block block : blocks) { Portal portal = PortalHandler.getByBlock(block); if (portal != null) { diff --git a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java index cc181c2..adb6d06 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntityEventListener.java @@ -12,6 +12,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityPortalEvent; +import org.jetbrains.annotations.NotNull; /** * This listener listens for any relevant events on portal entities @@ -25,7 +26,7 @@ public class EntityEventListener implements Listener { * @param event

The event to check and possibly cancel

*/ @EventHandler(priority = EventPriority.LOWEST) - public void onPortalEvent(EntityPortalEvent event) { + public void onPortalEvent(@NotNull EntityPortalEvent event) { if (event.isCancelled()) { return; } @@ -46,7 +47,7 @@ public class EntityEventListener implements Listener { * @param event

The triggered explosion event

*/ @EventHandler - public void onEntityExplode(EntityExplodeEvent event) { + public void onEntityExplode(@NotNull EntityExplodeEvent event) { if (event.isCancelled()) { return; } diff --git a/src/main/java/net/knarcraft/stargate/listener/EntitySpawnListener.java b/src/main/java/net/knarcraft/stargate/listener/EntitySpawnListener.java index b4c0b2c..f806e6c 100644 --- a/src/main/java/net/knarcraft/stargate/listener/EntitySpawnListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/EntitySpawnListener.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.portal.PortalHandler; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.jetbrains.annotations.NotNull; /** * A listener that listens for any relevant events causing entities to spawn @@ -12,13 +13,12 @@ import org.bukkit.event.entity.CreatureSpawnEvent; public class EntitySpawnListener implements Listener { @EventHandler - public void onCreatureSpawn(CreatureSpawnEvent event) { + public void onCreatureSpawn(@NotNull CreatureSpawnEvent event) { //Prevent Zombified Piglins and other creatures form spawning at stargates - if (event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.NETHER_PORTAL) { - if (PortalHandler.getByEntrance(event.getLocation()) != null) { - event.setCancelled(true); - Stargate.debug("EntitySpawnListener", "Prevented creature from spawning at Stargate"); - } + if (event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.NETHER_PORTAL && + PortalHandler.getByEntrance(event.getLocation()) != null) { + event.setCancelled(true); + Stargate.debug("EntitySpawnListener", "Prevented creature from spawning at Stargate"); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 6fd69b0..4720def 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -35,6 +35,8 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; @@ -53,7 +55,7 @@ public class PlayerEventListener implements Listener { * @param event

The event to check for a teleporting player

*/ @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { + public void onPlayerJoin(@NotNull PlayerJoinEvent event) { Player player = event.getPlayer(); //Migrate player name to UUID if necessary UUIDMigrationHelper.migrateUUID(player); @@ -91,7 +93,7 @@ public class PlayerEventListener implements Listener { * @param event

The player move event which was triggered

*/ @EventHandler - public void onPlayerMove(PlayerMoveEvent event) { + public void onPlayerMove(@NotNull PlayerMoveEvent event) { if (event.isCancelled() || event.getTo() == null) { return; } @@ -108,9 +110,16 @@ public class PlayerEventListener implements Listener { //Check an additional block away in case the portal is a bungee portal using END_PORTAL if (entrancePortal == null) { entrancePortal = PortalHandler.getByAdjacentEntrance(toLocation); + // This should never realistically be null + if (entrancePortal == null) { + return; + } } Portal destination = entrancePortal.getPortalActivator().getDestination(player); + if (destination == null) { + return; + } Entity playerVehicle = player.getVehicle(); //If the player is in a vehicle, but vehicle handling is disabled, just ignore the player @@ -129,8 +138,8 @@ public class PlayerEventListener implements Listener { * @param destination

The destination of the entrance portal

* @param event

The move event causing the teleportation to trigger

*/ - private void teleportPlayer(Entity playerVehicle, Player player, Portal entrancePortal, Portal destination, - PlayerMoveEvent event) { + private void teleportPlayer(@Nullable Entity playerVehicle, @NotNull Player player, @NotNull Portal entrancePortal, + @NotNull Portal destination, @NotNull PlayerMoveEvent event) { if (playerVehicle instanceof LivingEntity) { //Make sure any horses are properly tamed if (playerVehicle instanceof AbstractHorse horse && !horse.isTamed()) { @@ -159,8 +168,8 @@ public class PlayerEventListener implements Listener { * @param toLocation

The location the player is moving to

* @return

True if the event is relevant

*/ - private boolean isRelevantMoveEvent(PlayerMoveEvent event, Player player, BlockLocation fromLocation, - BlockLocation toLocation) { + private boolean isRelevantMoveEvent(@NotNull PlayerMoveEvent event, Player player, + @NotNull BlockLocation fromLocation, @NotNull BlockLocation toLocation) { //Check to see if the player moved to another block if (fromLocation.equals(toLocation)) { return false; @@ -207,7 +216,7 @@ public class PlayerEventListener 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(); @@ -216,6 +225,10 @@ public class PlayerEventListener implements Listener { } if (event.getAction() == Action.RIGHT_CLICK_BLOCK) { + if (event.getHand() == null) { + return; + } + // Handle right-click of a sign, button or other handleRightClickBlock(event, player, block, event.getHand()); } else if (event.getAction() == Action.LEFT_CLICK_BLOCK && block.getBlockData() instanceof WallSign) { //Handle left click of a wall sign @@ -231,7 +244,8 @@ public class PlayerEventListener implements Listener { * @param block

The block that was clicked

* @param leftClick

Whether the player performed a left click as opposed to a right click

*/ - private void handleSignClick(PlayerInteractEvent event, Player player, Block block, boolean leftClick) { + private void handleSignClick(@NotNull PlayerInteractEvent event, @NotNull Player player, @NotNull Block block, + boolean leftClick) { Portal portal = PortalHandler.getByBlock(block); if (portal == null) { return; @@ -286,7 +300,7 @@ public class PlayerEventListener implements Listener { * @param portal

The portal the player is trying to use

* @return

True if the player should be denied

*/ - private boolean cannotAccessPortal(Player player, Portal portal) { + private boolean cannotAccessPortal(@NotNull Player player, @NotNull Portal portal) { boolean deny = PermissionHelper.cannotAccessNetwork(player, portal.getCleanNetwork()); if (PermissionHelper.portalAccessDenied(player, portal, deny)) { @@ -306,7 +320,8 @@ public class PlayerEventListener implements Listener { * @param block

The block the player clicked

* @param hand

The hand the player used to interact with the stargate

*/ - private void handleRightClickBlock(PlayerInteractEvent event, Player player, Block block, EquipmentSlot hand) { + private void handleRightClickBlock(@NotNull PlayerInteractEvent event, @NotNull Player player, @NotNull Block block, + @NotNull EquipmentSlot hand) { if (block.getBlockData() instanceof WallSign) { handleSignClick(event, player, block, false); return; @@ -353,7 +368,7 @@ public class PlayerEventListener implements Listener { * @param block

The clicked block

* @param player

The player that clicked the block

*/ - private void displayPortalInfo(Block block, Player player) { + private void displayPortalInfo(@NotNull Block block, @NotNull Player player) { Portal portal = PortalHandler.getByBlock(block); if (portal == null) { return; @@ -363,15 +378,15 @@ public class PlayerEventListener implements Listener { if (portal.getOptions().hasNoSign() && (!portal.getOptions().isSilent() || player.isSneaking())) { MessageSender sender = Stargate.getMessageSender(); sender.sendSuccessMessage(player, ChatColor.GOLD + Stargate.getString("portalInfoTitle")); - sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoName"), + sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString("portalInfoName"), "%name%", portal.getName())); - sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoDestination"), + sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString("portalInfoDestination"), "%destination%", portal.getDestinationName())); if (portal.getOptions().isBungee()) { - sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoServer"), + sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString("portalInfoServer"), "%server%", portal.getNetwork())); } else { - sender.sendSuccessMessage(player, Stargate.replaceVars(Stargate.getString("portalInfoNetwork"), + sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString("portalInfoNetwork"), "%network%", portal.getNetwork())); } } @@ -388,7 +403,7 @@ public class PlayerEventListener implements Listener { * @param block

The block to check

* @return

True if the click is a bug and should be cancelled

*/ - private boolean clickIsBug(Player player, Block block) { + private boolean clickIsBug(@NotNull Player player, @NotNull Block block) { Long previousEventTime = previousEventTimes.get(player); if (previousEventTime != null && previousEventTime + 50 > System.currentTimeMillis()) { previousEventTimes.put(player, null); diff --git a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java index 2f70de3..d675335 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java @@ -5,6 +5,8 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginEnableEvent; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; /** * This listener listens for any plugins being enabled or disabled to catch the loading of vault @@ -19,7 +21,7 @@ public class PluginEventListener implements Listener { * * @param stargate

A reference to the stargate plugin to

*/ - public PluginEventListener(Stargate stargate) { + public PluginEventListener(@NotNull Stargate stargate) { this.stargate = stargate; } @@ -31,10 +33,14 @@ public class PluginEventListener implements Listener { * @param ignored

The actual event called. This is currently not used

*/ @EventHandler - public void onPluginEnable(PluginEnableEvent ignored) { + public void onPluginEnable(@NotNull PluginEnableEvent ignored) { if (Stargate.getEconomyConfig().setupEconomy(stargate.getServer().getPluginManager())) { - String vaultVersion = Stargate.getEconomyConfig().getVault().getDescription().getVersion(); - Stargate.logInfo(Stargate.replaceVars(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + Plugin vault = Stargate.getEconomyConfig().getVault(); + if (vault != null) { + String vaultVersion = vault.getDescription().getVersion(); + Stargate.logInfo(Stargate.replacePlaceholders(Stargate.getString("vaultLoaded"), "%version%", + vaultVersion)); + } } } @@ -44,7 +50,7 @@ public class PluginEventListener implements Listener { * @param event

The event caused by disabling a plugin

*/ @EventHandler - public void onPluginDisable(PluginDisableEvent event) { + public void onPluginDisable(@NotNull PluginDisableEvent event) { if (event.getPlugin().equals(Stargate.getEconomyConfig().getVault())) { Stargate.logInfo("Vault plugin lost."); } diff --git a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java index c81640f..41d2d9b 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PortalEventListener.java @@ -17,16 +17,17 @@ import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityPortalEnterEvent; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.world.PortalCreateEvent; +import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.Map; /** * Listens for and cancels relevant portal events */ public class PortalEventListener implements Listener { - private static final List playersFromTheEnd = new ArrayList<>(); + private static final Map playersFromTheEnd = new HashMap<>(); /** * Listens for and aborts vanilla portal creation caused by stargate creation @@ -34,7 +35,7 @@ public class PortalEventListener implements Listener { * @param event

The triggered event

*/ @EventHandler - public void onPortalCreation(PortalCreateEvent event) { + public void onPortalCreation(@NotNull PortalCreateEvent event) { if (event.isCancelled()) { return; } @@ -56,32 +57,37 @@ public class PortalEventListener implements Listener { * @param event

The triggered event

*/ @EventHandler - public void onEntityPortalEnter(EntityPortalEnterEvent event) { + public void onEntityPortalEnter(@NotNull EntityPortalEnterEvent event) { Location location = event.getLocation(); World world = location.getWorld(); Entity entity = event.getEntity(); - //Hijack normal portal teleportation if teleporting from a stargate - if (entity instanceof Player player && location.getBlock().getType() == Material.END_PORTAL && world != null && - world.getEnvironment() == World.Environment.THE_END) { - Portal portal = PortalHandler.getByAdjacentEntrance(location); - if (portal == null) { - return; - } + //Hijack normal portal teleportation if teleporting from a stargate, and teleporting from an end portal in the + // end + if (!(entity instanceof Player player) || location.getBlock().getType() != Material.END_PORTAL || + world == null || world.getEnvironment() != World.Environment.THE_END) { + return; + } + + Portal portal = PortalHandler.getByAdjacentEntrance(location); + if (portal == null) { + return; + } + + Stargate.debug("PortalEventListener::onEntityPortalEnter", + "Found player " + player + " entering END_PORTAL " + portal); + + //Decide if the anything stops the player from teleporting + if (PermissionHelper.playerCannotTeleport(portal, portal.getPortalActivator().getDestination(), + player, null) || portal.getOptions().isBungee()) { + //Teleport the player back to the portal they came in, just in case + playersFromTheEnd.put(player, new FromTheEndTeleportation(portal)); Stargate.debug("PortalEventListener::onEntityPortalEnter", - "Found player " + player + " entering END_PORTAL " + portal); - - //Remove any old player teleportations in case weird things happen - playersFromTheEnd.removeIf((teleportation -> teleportation.getPlayer() == player)); - //Decide if the anything stops the player from teleporting - if (PermissionHelper.playerCannotTeleport(portal, portal.getPortalActivator().getDestination(), player, null) || - portal.getOptions().isBungee()) { - //Teleport the player back to the portal they came in, just in case - playersFromTheEnd.add(new FromTheEndTeleportation(player, portal)); - Stargate.debug("PortalEventListener::onEntityPortalEnter", - "Sending player back to the entrance"); - } else { - playersFromTheEnd.add(new FromTheEndTeleportation(player, portal.getPortalActivator().getDestination())); + "Sending player back to the entrance"); + } else { + Portal destination = portal.getPortalActivator().getDestination(); + if (destination != null) { + playersFromTheEnd.put(player, new FromTheEndTeleportation(destination)); Stargate.debug("PortalEventListener::onEntityPortalEnter", "Sending player to destination"); } @@ -94,16 +100,11 @@ public class PortalEventListener implements Listener { * @param event

The triggered event

*/ @EventHandler - public void onRespawn(PlayerRespawnEvent event) { + public void onRespawn(@NotNull PlayerRespawnEvent event) { Player respawningPlayer = event.getPlayer(); - int playerIndex = playersFromTheEnd.indexOf(new FromTheEndTeleportation(respawningPlayer, null)); - if (playerIndex == -1) { - return; - } - FromTheEndTeleportation teleportation = playersFromTheEnd.get(playerIndex); - playersFromTheEnd.remove(playerIndex); + FromTheEndTeleportation teleportation = playersFromTheEnd.remove(respawningPlayer); + Portal exitPortal = teleportation.exitPortal(); - Portal exitPortal = teleportation.getExit(); //Overwrite respawn location to respawn in front of the portal PlayerTeleporter teleporter = new PlayerTeleporter(exitPortal, respawningPlayer); Location respawnLocation = teleporter.getExit(); diff --git a/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java b/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java index 21a0118..34ab7a6 100644 --- a/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/TeleportEventListener.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.portal.PortalHandler; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerTeleportEvent; +import org.jetbrains.annotations.NotNull; /** * This listener listens to teleportation-related events @@ -21,7 +22,7 @@ public class TeleportEventListener implements Listener { * @param event

The event to check and possibly cancel

*/ @EventHandler - public void onPlayerTeleport(PlayerTeleportEvent event) { + public void onPlayerTeleport(@NotNull PlayerTeleportEvent event) { PlayerTeleportEvent.TeleportCause cause = event.getCause(); //Block normal portal teleportation if teleporting from a stargate diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index 42c1102..f2ecb6a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -13,6 +13,7 @@ import org.bukkit.entity.Vehicle; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.vehicle.VehicleMoveEvent; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -28,7 +29,7 @@ public class VehicleEventListener implements Listener { * @param event

The triggered move event

*/ @EventHandler - public void onVehicleMove(VehicleMoveEvent event) { + public void onVehicleMove(@NotNull VehicleMoveEvent event) { if (!Stargate.getGateConfig().handleVehicles()) { return; } @@ -58,7 +59,8 @@ public class VehicleEventListener implements Listener { * @param entrancePortal

The portal the vehicle is entering

* @param vehicle

The vehicle passing through

*/ - private static void teleportVehicle(List passengers, Portal entrancePortal, Vehicle vehicle) { + private static void teleportVehicle(@NotNull List passengers, @NotNull Portal entrancePortal, + @NotNull Vehicle vehicle) { String route = "VehicleEventListener::teleportVehicle"; if (!passengers.isEmpty() && TeleportHelper.containsPlayer(passengers)) { @@ -83,7 +85,7 @@ public class VehicleEventListener implements Listener { * @param entrancePortal

The portal the minecart entered

* @param vehicle

The vehicle to teleport

*/ - private static void teleportPlayerAndVehicle(Portal entrancePortal, Vehicle vehicle) { + private static void teleportPlayerAndVehicle(@NotNull Portal entrancePortal, @NotNull Vehicle vehicle) { Entity rootEntity = vehicle; while (rootEntity.getVehicle() != null) { rootEntity = rootEntity.getVehicle(); @@ -101,6 +103,7 @@ public class VehicleEventListener implements Listener { Portal possibleDestinationPortal = entrancePortal.getPortalActivator().getDestination(player); if (possibleDestinationPortal != null) { destinationPortal = possibleDestinationPortal; + break; } } @@ -116,7 +119,7 @@ public class VehicleEventListener implements Listener { cancelTeleport = true; } } - if (cancelTeleport) { + if (cancelTeleport || destinationPortal == null) { return; } diff --git a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java index 6329d6d..5606e80 100644 --- a/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/WorldEventListener.java @@ -9,6 +9,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldUnloadEvent; +import org.jetbrains.annotations.NotNull; /** * This listener listens for the loading and unloading of worlds to load and unload stargates @@ -22,7 +23,7 @@ public class WorldEventListener implements Listener { * @param event

The triggered world load event

*/ @EventHandler - public void onWorldLoad(WorldLoadEvent event) { + public void onWorldLoad(@NotNull WorldLoadEvent event) { StargateConfig config = Stargate.getStargateConfig(); if (!config.getManagedWorlds().contains(event.getWorld().getName()) && PortalFileHelper.loadAllPortals(event.getWorld())) { @@ -36,7 +37,7 @@ public class WorldEventListener implements Listener { * @param event

The triggered world unload event

*/ @EventHandler - public void onWorldUnload(WorldUnloadEvent event) { + public void onWorldUnload(@NotNull WorldUnloadEvent event) { Stargate.debug("onWorldUnload", "Reloading all Stargates"); World world = event.getWorld(); String worldName = world.getName(); diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index f42ddb2..304136e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -11,6 +11,8 @@ import net.knarcraft.stargate.portal.property.gate.Gate; import net.md_5.bungee.api.ChatColor; import org.bukkit.World; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Map; @@ -46,8 +48,9 @@ public class Portal { * @param portalOwner

The portal's owner

* @param options

A map containing all possible portal options, with true for the ones enabled

*/ - public Portal(PortalLocation portalLocation, BlockLocation button, String destination, String name, String network, - Gate gate, PortalOwner portalOwner, Map options) { + public Portal(@NotNull PortalLocation portalLocation, @Nullable BlockLocation button, @NotNull String destination, + @NotNull String name, @NotNull String network, @NotNull Gate gate, @NotNull PortalOwner portalOwner, + @NotNull Map options) { this.location = portalLocation; this.network = network; this.name = name; @@ -84,6 +87,7 @@ public class Portal { * * @return

This portal's location data

*/ + @NotNull public PortalLocation getLocation() { return this.location; } @@ -96,6 +100,7 @@ public class Portal { * * @return

This portal's structure

*/ + @NotNull public PortalStructure getStructure() { return this.structure; } @@ -108,6 +113,7 @@ public class Portal { * * @return

This portal's activator

*/ + @NotNull public PortalActivator getPortalActivator() { return this.portalActivator; } @@ -124,6 +130,7 @@ public class Portal { * * @return

This portal's portal options

*/ + @NotNull public PortalOptions getOptions() { return this.options; } @@ -142,6 +149,7 @@ public class Portal { * * @return

The player currently using this portal

*/ + @Nullable public Player getActivePlayer() { return portalActivator.getActivePlayer(); } @@ -151,6 +159,7 @@ public class Portal { * * @return

The network this portal belongs to

*/ + @NotNull public String getNetwork() { return network; } @@ -160,6 +169,7 @@ public class Portal { * * @return

The clean network name

*/ + @NotNull public String getCleanNetwork() { return cleanNetwork; } @@ -181,6 +191,7 @@ public class Portal { * * @return

The name of this portal

*/ + @NotNull public String getName() { return name; } @@ -190,6 +201,7 @@ public class Portal { * * @return

The clean name of this portal

*/ + @NotNull public String getCleanName() { return cleanName; } @@ -201,6 +213,7 @@ public class Portal { * * @return

This portal's portal opener

*/ + @NotNull public PortalOpener getPortalOpener() { return portalOpener; } @@ -210,6 +223,7 @@ public class Portal { * * @return

The name of this portal's destination portal

*/ + @NotNull public String getDestinationName() { return portalOpener.getPortalActivator().getDestinationName(); } @@ -219,6 +233,7 @@ public class Portal { * * @return

The gate type used by this portal

*/ + @NotNull public Gate getGate() { return structure.getGate(); } @@ -230,6 +245,7 @@ public class Portal { * * @return

This portal's owner

*/ + @NotNull public PortalOwner getOwner() { return portalOwner; } @@ -240,7 +256,7 @@ public class Portal { * @param player

The player to check

* @return

True if the player is the owner of this portal

*/ - public boolean isOwner(Player player) { + public boolean isOwner(@NotNull Player player) { if (this.portalOwner.getUUID() != null) { return player.getUniqueId().compareTo(this.portalOwner.getUUID()) == 0; } else { @@ -253,6 +269,7 @@ public class Portal { * * @return

The world this portal belongs to

*/ + @Nullable public World getWorld() { return location.getWorld(); } @@ -262,6 +279,7 @@ public class Portal { * * @return

The location of this portal's sign

*/ + @NotNull public BlockLocation getSignLocation() { return this.location.getSignLocation(); } @@ -283,6 +301,7 @@ public class Portal { * * @return

The location of the top-left portal block

*/ + @NotNull public BlockLocation getTopLeft() { return this.location.getTopLeft(); } @@ -293,7 +312,8 @@ public class Portal { * @param vector

The relative block vector explaining the position of the block

* @return

The block at the given relative position

*/ - public BlockLocation getBlockAt(RelativeBlockVector vector) { + @NotNull + public BlockLocation getBlockAt(@NotNull RelativeBlockVector vector) { return getTopLeft().getRelativeLocation(vector, getYaw()); } @@ -303,11 +323,13 @@ public class Portal { * @param string

The string to clean

* @return

The clean string

*/ - public static String cleanString(String string) { + @NotNull + public static String cleanString(@NotNull String string) { return ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', string)).toLowerCase(); } @Override + @NotNull public String toString() { return String.format("Portal [id=%s, network=%s name=%s, type=%s]", getSignLocation(), network, name, structure.getGate().getFilename()); @@ -323,7 +345,7 @@ public class Portal { } @Override - public boolean equals(Object object) { + public boolean equals(@Nullable Object object) { if (this == object) { return true; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index c0fd01e..55878f8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -4,6 +4,8 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Comparator; @@ -33,7 +35,7 @@ public class PortalActivator { * @param portalOpener

The portal opener to trigger when the activation causes the portal to open

* @param destination

The fixed destination specified on the portal's sign

*/ - public PortalActivator(Portal portal, PortalOpener portalOpener, String destination) { + public PortalActivator(@NotNull Portal portal, @NotNull PortalOpener portalOpener, @NotNull String destination) { this.portal = portal; this.opener = portalOpener; this.destination = destination; @@ -44,6 +46,7 @@ public class PortalActivator { * * @return

The player this activator's portal is currently activated for

*/ + @NotNull public Player getActivePlayer() { return activePlayer; } @@ -53,6 +56,7 @@ public class PortalActivator { * * @return

The available portal destinations

*/ + @NotNull public List getDestinations() { return new ArrayList<>(this.destinations); } @@ -63,7 +67,8 @@ public class PortalActivator { * @param player

Used for random gates to determine which destinations are available

* @return

The destination portal the player should teleport to

*/ - public Portal getDestination(Player player) { + @Nullable + public Portal getDestination(@Nullable Player player) { String portalNetwork = portal.getCleanNetwork(); if (portal.getOptions().isRandom()) { //Find possible destinations @@ -88,6 +93,7 @@ public class PortalActivator { * * @return

The portal destination

*/ + @Nullable public Portal getDestination() { return getDestination(null); } @@ -97,7 +103,7 @@ public class PortalActivator { * * @param destination

The new destination of this portal activator's portal

*/ - public void setDestination(Portal destination) { + public void setDestination(@NotNull Portal destination) { setDestination(destination.getName()); } @@ -106,7 +112,7 @@ public class PortalActivator { * * @param destination

The new destination of this portal activator's portal

*/ - public void setDestination(String destination) { + public void setDestination(@NotNull String destination) { this.destination = destination; } @@ -115,6 +121,7 @@ public class PortalActivator { * * @return

The name of the selected destination

*/ + @NotNull public String getDestinationName() { return destination; } @@ -125,7 +132,7 @@ public class PortalActivator { * @param player

The player to activate the portal for

* @return

True if the portal was activated

*/ - boolean activate(Player player) { + public boolean activate(@NotNull Player player) { //Clear previous destination data this.destination = ""; this.destinations.clear(); @@ -162,7 +169,7 @@ public class PortalActivator { * @param player

The player trying to activate this activator's portal

* @return

True if the portal was activated. False otherwise

*/ - private boolean triggerStargateActivationEvent(Player player) { + private boolean triggerStargateActivationEvent(@NotNull Player player) { StargateActivateEvent event = new StargateActivateEvent(portal, player, destinations, destination); Stargate.getInstance().getServer().getPluginManager().callEvent(event); if (event.isCancelled()) { @@ -217,7 +224,7 @@ public class PortalActivator { * * @param player

The player to cycle the gate for

*/ - public void cycleDestination(Player player) { + public void cycleDestination(@NotNull Player player) { cycleDestination(player, 1); } @@ -227,7 +234,7 @@ public class PortalActivator { * @param player

The player cycling destinations

* @param direction

The direction of the cycle (+1 for next, -1 for previous)

*/ - public void cycleDestination(Player player, int direction) { + public void cycleDestination(@NotNull Player player, int direction) { //Only allow going exactly one step in either direction if (direction != 1 && direction != -1) { throw new IllegalArgumentException("The destination direction must be 1 or -1."); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 4ec865c..b84489e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -18,6 +18,8 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.event.block.SignChangeEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; @@ -39,7 +41,7 @@ public class PortalCreator { * @param event

The sign change event which initialized the creation

* @param player

The player creating the portal

*/ - public PortalCreator(SignChangeEvent event, Player player) { + public PortalCreator(@NotNull SignChangeEvent event, @NotNull Player player) { this.event = event; this.player = player; } @@ -49,12 +51,13 @@ public class PortalCreator { * * @return

The created portal

*/ + @Nullable public Portal createPortal() { BlockLocation signLocation = new BlockLocation(event.getBlock()); Block signControlBlock = signLocation.getParent(); //Return early if the sign is not placed on a block, or the block is not a control block - if (signControlBlock == null || GateHandler.getGatesByControlBlock(signControlBlock).length == 0) { + if (signControlBlock == null || GateHandler.getGatesByControlBlock(signControlBlock).isEmpty()) { Stargate.debug("createPortal", "Control block not registered"); return null; } @@ -144,7 +147,7 @@ public class PortalCreator { //Check if the user can create portals to this world. if (!portalOptions.get(PortalOption.BUNGEE) && !deny && destinationName.length() > 0) { Portal portal = PortalHandler.getByName(destinationName, network); - if (portal != null) { + if (portal != null && portal.getWorld() != null) { String world = portal.getWorld().getName(); if (PermissionHelper.cannotAccessWorld(player, world)) { Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); @@ -173,7 +176,8 @@ public class PortalCreator { * @param deny

Whether the portal creation has already been denied

* @return

The portal or null if its creation was denied

*/ - public Portal validatePortal(String denyMessage, String[] lines, boolean deny) { + @Nullable + public Portal validatePortal(@NotNull String denyMessage, String[] lines, boolean deny) { PortalLocation portalLocation = portal.getLocation(); Gate gate = portal.getStructure().getGate(); PortalOptions portalOptions = portal.getOptions(); @@ -219,7 +223,9 @@ public class PortalCreator { PortalHandler.updatePortalsPointingAtNewPortal(portal); } - PortalFileHelper.saveAllPortals(portal.getWorld()); + if (portal.getWorld() != null) { + PortalFileHelper.saveAllPortals(portal.getWorld()); + } return portal; } @@ -231,7 +237,7 @@ public class PortalCreator { * @param portalName

The name of the newly created portal

* @return

True if the portal is completely valid

*/ - private boolean checkIfNewPortalIsValid(int cost, String portalName) { + private boolean checkIfNewPortalIsValid(int cost, @NotNull String portalName) { //Check if the portal name can fit on the sign with padding (>name<) if (portal.getCleanName().length() < 1 || portal.getCleanName().length() > getMaxNameNetworkLength()) { Stargate.debug("createPortal", String.format("Name length error. %s is too long.", @@ -282,7 +288,7 @@ public class PortalCreator { * * @param destinationName

The name of the destination portal. Only used if set as always on

*/ - private void updateNewPortalOpenState(String destinationName) { + private void updateNewPortalOpenState(@NotNull String destinationName) { portal.drawSign(); if (portal.getOptions().isRandom() || portal.getOptions().isBungee()) { //Open the implicitly always on portal @@ -312,7 +318,8 @@ public class PortalCreator { * @param player

The player creating the new portal

* @return

True if a conflict was found. False otherwise

*/ - private static boolean conflictsWithExistingPortal(Gate gate, BlockLocation topLeft, double yaw, Player player) { + private static boolean conflictsWithExistingPortal(@NotNull Gate gate, @NotNull BlockLocation topLeft, double yaw, + @NotNull Player player) { for (RelativeBlockVector borderVector : gate.getLayout().getBorder()) { BlockLocation borderBlockLocation = topLeft.getRelativeLocation(borderVector, yaw); if (PortalHandler.getByBlock(borderBlockLocation.getBlock()) != null) { diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 3ce9b56..caba7e3 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -13,6 +13,8 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.HashMap; @@ -33,6 +35,7 @@ public class PortalHandler { * * @return

A copy of all portal networks

*/ + @NotNull public static Map> getAllPortalNetworks() { return PortalRegistry.getAllPortalNetworks(); } @@ -42,6 +45,7 @@ public class PortalHandler { * * @return

A copy of all bungee portals

*/ + @NotNull public static Map getBungeePortals() { return PortalRegistry.getBungeePortals(); } @@ -52,6 +56,7 @@ public class PortalHandler { * @param network

The network to get portals from

* @return

A list of portal names

*/ + @NotNull public static List getNetwork(String network) { return PortalRegistry.getNetwork(network); } @@ -64,7 +69,9 @@ public class PortalHandler { * @param network

The network to get destinations from

* @return

All destinations the player can go to

*/ - public static List getDestinations(Portal entrancePortal, Player player, String network) { + @NotNull + public static List getDestinations(@NotNull Portal entrancePortal, @Nullable Player player, + @NotNull String network) { List destinations = new ArrayList<>(); for (String destination : PortalRegistry.getAllPortalNetworks().get(network)) { Portal portal = getByName(destination, network); @@ -94,7 +101,7 @@ public class PortalHandler { continue; } //Check if this player can access the destination world - if (PermissionHelper.cannotAccessWorld(player, portal.getWorld().getName())) { + if (portal.getWorld() != null && PermissionHelper.cannotAccessWorld(player, portal.getWorld().getName())) { continue; } //The portal is visible to the player @@ -110,7 +117,7 @@ public class PortalHandler { * * @param portal

The portal to register

*/ - public static void registerPortal(Portal portal) { + public static void registerPortal(@NotNull Portal portal) { PortalRegistry.registerPortal(portal); } @@ -123,8 +130,8 @@ public class PortalHandler { * @param network

The name of the portal's network

* @return

False if the portal is an invalid bungee portal. True otherwise

*/ - static boolean isValidBungeePortal(Map portalOptions, Player player, - String destinationName, String network) { + public static boolean isValidBungeePortal(@NotNull Map portalOptions, @NotNull Player player, + @NotNull String destinationName, String network) { if (portalOptions.get(PortalOption.BUNGEE)) { if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDeny")); @@ -147,13 +154,17 @@ public class PortalHandler { * @param world

The world the player is located in

* @return

The matching gate type, or null if no such gate could be found

*/ - static Gate findMatchingGate(PortalLocation portalLocation, World world) { + @Nullable + public static Gate findMatchingGate(@NotNull PortalLocation portalLocation, @NotNull World world) { Block signParent = portalLocation.getSignLocation().getParent(); + if (signParent == null) { + return null; + } BlockLocation parent = new BlockLocation(world, signParent.getX(), signParent.getY(), signParent.getZ()); //Get all gates with the used type of control blocks - Gate[] possibleGates = GateHandler.getGatesByControlBlock(signParent); + List possibleGates = GateHandler.getGatesByControlBlock(signParent); double yaw = portalLocation.getYaw(); Gate gate = null; @@ -187,7 +198,7 @@ public class PortalHandler { * * @param portal

The newly created portal

*/ - static void updatePortalsPointingAtNewPortal(Portal portal) { + public static void updatePortalsPointingAtNewPortal(@NotNull Portal portal) { for (String originName : PortalRegistry.getAllPortalNetworks().get(portal.getCleanNetwork())) { Portal origin = getByName(originName, portal.getCleanNetwork()); if (origin == null || @@ -214,7 +225,9 @@ public class PortalHandler { * @param options

The string on the option line of the sign

* @return

A map containing all portal options and their values

*/ - static Map getPortalOptions(Player player, String destinationName, String options) { + @NotNull + public static Map getPortalOptions(@NotNull Player player, @NotNull String destinationName, + @NotNull String options) { Map portalOptions = new HashMap<>(); for (PortalOption option : PortalOption.values()) { portalOptions.put(option, options.indexOf(option.getCharacterRepresentation()) != -1 && @@ -252,7 +265,8 @@ public class PortalHandler { * @param network

The network the portal is connected to

* @return

The portal with the given name or null

*/ - public static Portal getByName(String name, String network) { + @Nullable + public static Portal getByName(@NotNull String name, @NotNull String network) { Map> lookupMap = PortalRegistry.getPortalLookupByNetwork(); if (!lookupMap.containsKey(network.toLowerCase())) { return null; @@ -267,7 +281,11 @@ public class PortalHandler { * @param location

The location of the portal's entrance

* @return

The portal at the given location

*/ - public static Portal getByEntrance(Location location) { + @Nullable + public static Portal getByEntrance(@NotNull Location location) { + if (location.getWorld() == null) { + return null; + } return PortalRegistry.getLookupEntrances().get(new BlockLocation(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ())); } @@ -278,7 +296,8 @@ public class PortalHandler { * @param block

The block at the portal's entrance

* @return

The portal at the given block's location

*/ - public static Portal getByEntrance(Block block) { + @Nullable + public static Portal getByEntrance(@NotNull Block block) { return PortalRegistry.getLookupEntrances().get(new BlockLocation(block)); } @@ -288,7 +307,8 @@ public class PortalHandler { * @param location

A location adjacent to the portal's entrance

* @return

The portal adjacent to the given location

*/ - public static Portal getByAdjacentEntrance(Location location) { + @Nullable + public static Portal getByAdjacentEntrance(@NotNull Location location) { return getByAdjacentEntrance(location, 1); } @@ -299,7 +319,8 @@ public class PortalHandler { * @param range

The range to scan for portals

* @return

The portal adjacent to the given location

*/ - public static Portal getByAdjacentEntrance(Location location, int range) { + @Nullable + public static Portal getByAdjacentEntrance(@NotNull Location location, int range) { List adjacentPositions = new ArrayList<>(); BlockLocation centerLocation = new BlockLocation(location.getBlock()); adjacentPositions.add(centerLocation); @@ -332,7 +353,8 @@ public class PortalHandler { * @param block

The portal's control block

* @return

The portal with the given control block

*/ - public static Portal getByControl(Block block) { + @Nullable + public static Portal getByControl(@NotNull Block block) { return PortalRegistry.getLookupControls().get(new BlockLocation(block)); } @@ -342,7 +364,8 @@ public class PortalHandler { * @param block

One of the loaded lookup blocks

* @return

The portal corresponding to the block

*/ - public static Portal getByBlock(Block block) { + @Nullable + public static Portal getByBlock(@NotNull Block block) { return PortalRegistry.getLookupBlocks().get(new BlockLocation(block)); } @@ -352,7 +375,8 @@ public class PortalHandler { * @param name

The name of the bungee portal to get

* @return

A bungee portal

*/ - public static Portal getBungeePortal(String name) { + @Nullable + public static Portal getBungeePortal(@NotNull String name) { return PortalRegistry.getBungeePortals().get(name.toLowerCase()); } @@ -362,7 +386,8 @@ public class PortalHandler { * @param portalData

The string list containing all information about a portal

* @return

A map between portal options and booleans

*/ - public static Map getPortalOptions(String[] portalData) { + @NotNull + public static Map getPortalOptions(@NotNull String[] portalData) { Map portalOptions = new HashMap<>(); for (PortalOption option : PortalOption.values()) { int saveIndex = option.getSaveIndex(); @@ -415,7 +440,7 @@ public class PortalHandler { * * @param portal

The portal of the star portal

*/ - private static void unregisterInvalidPortal(Portal portal) { + private static void unregisterInvalidPortal(@NotNull Portal portal) { //Show debug information for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) { Block block = portal.getBlockAt(control).getBlock(); @@ -447,7 +472,8 @@ public class PortalHandler { * @param input

The name to filter

* @return

The filtered name

*/ - public static String filterName(String input) { + @NotNull + public static String filterName(@Nullable String input) { if (input == null) { return ""; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index 8390c05..77d5dcb 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -10,6 +10,8 @@ import org.bukkit.Axis; import org.bukkit.Material; import org.bukkit.block.data.Orientable; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * The portal opener is responsible for opening and closing a portal @@ -28,7 +30,7 @@ public class PortalOpener { * @param portal

The portal this portal opener should open

* @param destination

The fixed destination defined on the portal's sign

*/ - public PortalOpener(Portal portal, String destination) { + public PortalOpener(@NotNull Portal portal, @NotNull String destination) { this.portal = portal; this.portalActivator = new PortalActivator(portal, this, destination); } @@ -56,6 +58,7 @@ public class PortalOpener { * * @return

The portal activator belonging to this portal opener

*/ + @NotNull public PortalActivator getPortalActivator() { return this.portalActivator; } @@ -75,7 +78,7 @@ public class PortalOpener { * @param openFor

The player to open the portal for

* @param force

Whether to force the portal open, even if it's already open for some player

*/ - public void openPortal(Player openFor, boolean force) { + public void openPortal(@Nullable Player openFor, boolean force) { //Call the StargateOpenEvent to allow the opening to be cancelled StargateOpenEvent event = new StargateOpenEvent(openFor, portal, force); Stargate.getInstance().getServer().getPluginManager().callEvent(event); @@ -102,7 +105,7 @@ public class PortalOpener { * * @param openFor

The player to open this portal opener's portal for

*/ - private void updatePortalOpenState(Player openFor) { + private void updatePortalOpenState(@Nullable Player openFor) { //Update the open state of this portal isOpen = true; triggeredTime = System.currentTimeMillis() / 1000; @@ -207,7 +210,7 @@ public class PortalOpener { * @param player

The player to check portal state for

* @return

True if this portal opener's portal is open to the given player

*/ - public boolean isOpenFor(Player player) { + public boolean isOpenFor(@Nullable Player player) { //If closed, it's closed for everyone if (!isOpen) { return false; diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index fe07562..ac0d016 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -5,6 +5,7 @@ import net.knarcraft.stargate.config.DynmapManager; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.World; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.HashMap; @@ -44,11 +45,11 @@ public class PortalRegistry { * * @param world

The world containing the portals to clear

*/ - public static void clearPortals(World world) { + public static void clearPortals(@NotNull World world) { //Storing the portals to clear is necessary to avoid a concurrent modification exception List portalsToRemove = new ArrayList<>(); allPortals.forEach((portal) -> { - if (portal.getWorld().equals(world)) { + if (portal.getWorld() != null && portal.getWorld().equals(world)) { portalsToRemove.add(portal); } }); @@ -61,7 +62,7 @@ public class PortalRegistry { * * @param portalsToRemove

A list of portals to remove

*/ - private static void clearPortals(List portalsToRemove) { + private static void clearPortals(@NotNull List portalsToRemove) { //Store the names of the portals to remove as some maps require the name, not the object List portalNames = new ArrayList<>(); portalsToRemove.forEach((portal) -> portalNames.add(portal.getCleanName())); @@ -87,6 +88,7 @@ public class PortalRegistry { * * @return

A copy of the list of all portals

*/ + @NotNull public static List getAllPortals() { return new ArrayList<>(allPortals); } @@ -96,6 +98,7 @@ public class PortalRegistry { * * @return

A copy of the frame block lookup map

*/ + @NotNull public static Map getLookupBlocks() { return new HashMap<>(lookupBlocks); } @@ -105,6 +108,7 @@ public class PortalRegistry { * * @return

A copy of the control block lookup map

*/ + @NotNull public static Map getLookupControls() { return new HashMap<>(lookupControls); } @@ -114,6 +118,7 @@ public class PortalRegistry { * * @return

A copy of the network portal lookup map

*/ + @NotNull public static Map> getPortalLookupByNetwork() { return new HashMap<>(portalLookupByNetwork); } @@ -123,6 +128,7 @@ public class PortalRegistry { * * @return

A copy of all entrances to portal mappings

*/ + @NotNull public static Map getLookupEntrances() { return new HashMap<>(lookupEntrances); } @@ -132,6 +138,7 @@ public class PortalRegistry { * * @return

A copy of all portal networks

*/ + @NotNull public static Map> getAllPortalNetworks() { return new HashMap<>(allPortalNetworks); } @@ -141,6 +148,7 @@ public class PortalRegistry { * * @return

A copy of all bungee portals

*/ + @NotNull public static Map getBungeePortals() { return new HashMap<>(bungeePortals); } @@ -151,7 +159,8 @@ public class PortalRegistry { * @param network

The network to get portals from

* @return

A list of portal names

*/ - public static List getNetwork(String network) { + @NotNull + public static List getNetwork(@NotNull String network) { return allPortalNetworks.get(network.toLowerCase()); } @@ -161,7 +170,7 @@ public class PortalRegistry { * @param portal

The portal to un-register

* @param removeAll

Whether to remove the portal from the list of all portals

*/ - public static void unregisterPortal(Portal portal, boolean removeAll) { + public static void unregisterPortal(@NotNull Portal portal, boolean removeAll) { Stargate.debug("Unregister", "Unregistering gate " + portal.getName()); portal.getPortalActivator().deactivate(); portal.getPortalOpener().closePortal(true); @@ -223,7 +232,9 @@ public class PortalRegistry { //Mark the portal's sign as unregistered new PortalSignDrawer(portal).drawUnregisteredSign(); - PortalFileHelper.saveAllPortals(portal.getWorld()); + if (portal.getWorld() != null) { + PortalFileHelper.saveAllPortals(portal.getWorld()); + } portal.setRegistered(false); DynmapManager.removePortalMarker(portal); } @@ -233,7 +244,7 @@ public class PortalRegistry { * * @param portal

The portal to register

*/ - static void registerPortal(Portal portal) { + public static void registerPortal(@NotNull Portal portal) { portal.getOptions().setFixed(portal.getDestinationName().length() > 0 || portal.getOptions().isRandom() || portal.getOptions().isBungee()); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 00f8c25..506b702 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -12,8 +12,11 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Map; +import java.util.Objects; /** * The portal sign drawer draws the sing of a given portal @@ -33,7 +36,7 @@ public class PortalSignDrawer { * * @param portal

The portal whose sign this portal sign drawer is responsible for drawing

*/ - public PortalSignDrawer(Portal portal) { + public PortalSignDrawer(@NotNull Portal portal) { this.portal = portal; } @@ -44,7 +47,7 @@ public class PortalSignDrawer { * * @param newHighlightColor

The new highlight color

*/ - public static void setHighlightColor(ChatColor newHighlightColor) { + public static void setHighlightColor(@NotNull ChatColor newHighlightColor) { highlightColor = newHighlightColor; } @@ -55,7 +58,7 @@ public class PortalSignDrawer { * * @param newMainColor

The new main sign color

*/ - public static void setMainColor(ChatColor newMainColor) { + public static void setMainColor(@NotNull ChatColor newMainColor) { mainColor = newMainColor; } @@ -64,7 +67,7 @@ public class PortalSignDrawer { * * @param freeColor

The new color to use for marking free stargates

*/ - public static void setFreeColor(ChatColor freeColor) { + public static void setFreeColor(@NotNull ChatColor freeColor) { PortalSignDrawer.freeColor = freeColor; } @@ -73,7 +76,7 @@ public class PortalSignDrawer { * * @param signMainColors

The per-sign main colors

*/ - public static void setPerSignMainColors(Map signMainColors) { + public static void setPerSignMainColors(@NotNull Map signMainColors) { PortalSignDrawer.perSignMainColors = signMainColors; } @@ -82,7 +85,7 @@ public class PortalSignDrawer { * * @param signHighlightColors

The per-sign highlight colors

*/ - public static void setPerSignHighlightColors(Map signHighlightColors) { + public static void setPerSignHighlightColors(@NotNull Map signHighlightColors) { PortalSignDrawer.perSignHighlightColors = signHighlightColors; } @@ -91,6 +94,7 @@ public class PortalSignDrawer { * * @return

The currently used main sign color

*/ + @NotNull public static ChatColor getMainColor() { return mainColor; } @@ -100,6 +104,7 @@ public class PortalSignDrawer { * * @return

The currently used highlighting sign color

*/ + @NotNull public static ChatColor getHighlightColor() { return highlightColor; } @@ -122,6 +127,7 @@ public class PortalSignDrawer { * * @return

The sign of this sign drawer's portal

*/ + @Nullable private Sign getSign() { Block signBlock = portal.getSignLocation().getBlock(); BlockState state = signBlock.getState(); @@ -141,7 +147,7 @@ public class PortalSignDrawer { * * @param signData

All necessary sign information

*/ - private void drawSign(SignData signData) { + private void drawSign(@NotNull SignData signData) { Sign sign = signData.getSign(); ChatColor highlightColor = signData.getHighlightSignColor(); ChatColor mainColor = signData.getMainSignColor(); @@ -174,7 +180,7 @@ public class PortalSignDrawer { * * @param sign

The sign to clear

*/ - private void clearSign(Sign sign) { + private void clearSign(@NotNull Sign sign) { for (int index = 0; index <= 3; index++) { SignHelper.setSignLine(sign, index, ""); } @@ -198,7 +204,7 @@ public class PortalSignDrawer { * * @param signData

All necessary sign information

*/ - private void drawNetworkSign(SignData signData) { + private void drawNetworkSign(@NotNull SignData signData) { PortalActivator destinations = portal.getPortalActivator(); int maxIndex = destinations.getDestinations().size() - 1; int signLineIndex = 0; @@ -233,12 +239,12 @@ public class PortalSignDrawer { * @param freeGatesColored

Whether to display free gates in a different color

* @param signLineIndex

The line to draw on

*/ - private void drawNetworkSignChosenLine(SignData signData, boolean freeGatesColored, int signLineIndex) { + private void drawNetworkSignChosenLine(@NotNull SignData signData, boolean freeGatesColored, int signLineIndex) { ChatColor highlightColor = signData.getHighlightSignColor(); ChatColor mainColor = signData.getMainSignColor(); if (freeGatesColored) { Portal destination = PortalHandler.getByName(portal.getDestinationName(), portal.getNetwork()); - boolean free = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); + boolean free = PermissionHelper.isFree(Objects.requireNonNull(portal.getActivePlayer()), portal, destination); ChatColor nameColor = (free ? freeColor : highlightColor); setLine(signData, signLineIndex, nameColor + ">" + (free ? freeColor : mainColor) + translateAllColorCodes(portal.getDestinationName()) + nameColor + "<"); @@ -255,7 +261,7 @@ public class PortalSignDrawer { * @param index

The index of the sign line to change

* @param text

The new text on the sign

*/ - public void setLine(SignData signData, int index, String text) { + public void setLine(@NotNull SignData signData, int index, @NotNull String text) { ChatColor mainColor = signData.getMainSignColor(); SignHelper.setSignLine(signData.getSign(), index, mainColor + text); } @@ -268,13 +274,14 @@ public class PortalSignDrawer { * @param signLineIndex

The line to draw on

* @param destinationIndex

The index of the destination to draw

*/ - private void drawNetworkSignLine(SignData signData, boolean freeGatesColored, int signLineIndex, int destinationIndex) { + private void drawNetworkSignLine(@NotNull SignData signData, boolean freeGatesColored, int signLineIndex, + int destinationIndex) { ChatColor mainColor = signData.getMainSignColor(); PortalActivator destinations = portal.getPortalActivator(); String destinationName = destinations.getDestinations().get(destinationIndex); if (freeGatesColored) { Portal destination = PortalHandler.getByName(destinationName, portal.getNetwork()); - boolean free = PermissionHelper.isFree(portal.getActivePlayer(), portal, destination); + boolean free = PermissionHelper.isFree(Objects.requireNonNull(portal.getActivePlayer()), portal, destination); setLine(signData, signLineIndex, (free ? freeColor : mainColor) + translateAllColorCodes(destinationName)); } else { setLine(signData, signLineIndex, mainColor + translateAllColorCodes(destinationName)); @@ -286,12 +293,12 @@ public class PortalSignDrawer { * * @param signData

All necessary sign information

*/ - private void drawBungeeSign(SignData signData) { + private void drawBungeeSign(@NotNull SignData signData) { ChatColor highlightColor = signData.getHighlightSignColor(); ChatColor mainColor = signData.getMainSignColor(); setLine(signData, 1, Stargate.getString("bungeeSign")); - setLine(signData, 2, highlightColor + ">" + mainColor + translateAllColorCodes(portal.getDestinationName()) + - highlightColor + "<"); + setLine(signData, 2, highlightColor + ">" + mainColor + + translateAllColorCodes(portal.getDestinationName()) + highlightColor + "<"); setLine(signData, 3, highlightColor + "[" + mainColor + translateAllColorCodes(portal.getNetwork()) + highlightColor + "]"); } @@ -303,7 +310,7 @@ public class PortalSignDrawer { * * @param signData

All necessary sign information

*/ - private void drawInactiveSign(SignData signData) { + private void drawInactiveSign(@NotNull SignData signData) { ChatColor highlightColor = signData.getHighlightSignColor(); ChatColor mainColor = signData.getMainSignColor(); setLine(signData, 1, Stargate.getString("signRightClick")); @@ -321,7 +328,7 @@ public class PortalSignDrawer { * * @param signData

All necessary sign information

*/ - private void drawFixedSign(SignData signData) { + private void drawFixedSign(@NotNull SignData signData) { ChatColor highlightColor = signData.getHighlightSignColor(); ChatColor mainColor = signData.getMainSignColor(); Portal destinationPortal = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), @@ -353,7 +360,8 @@ public class PortalSignDrawer { * @param gateName

The name of the invalid gate type

* @param lineIndex

The index of the line the invalid portal was found at

*/ - public static void markPortalWithInvalidGate(PortalLocation portalLocation, String gateName, int lineIndex) { + public static void markPortalWithInvalidGate(@NotNull PortalLocation portalLocation, @NotNull String gateName, + int lineIndex) { BlockState blockState = portalLocation.getSignLocation().getBlock().getState(); if (!(blockState instanceof Sign sign)) { return; @@ -370,7 +378,8 @@ public class PortalSignDrawer { * @param signType

The sign type to get the main color for

* @return

The main color for the given sign type

*/ - private ChatColor getMainColor(Material signType) { + @NotNull + private ChatColor getMainColor(@NotNull Material signType) { ChatColor signColor = perSignMainColors.get(signType); if (signColor == null) { return mainColor; @@ -385,7 +394,8 @@ public class PortalSignDrawer { * @param signType

The sign type to get the highlight color for

* @return

The highlight color for the given sign type

*/ - private ChatColor getHighlightColor(Material signType) { + @NotNull + private ChatColor getHighlightColor(@NotNull Material signType) { ChatColor signColor = perSignHighlightColors.get(signType); if (signColor == null) { return highlightColor; @@ -400,7 +410,8 @@ public class PortalSignDrawer { * @param input

The input to translate color codes for

* @return

The input with color codes converted translated from & to §

*/ - private String translateAllColorCodes(String input) { + @NotNull + private String translateAllColorCodes(@NotNull String input) { return ColorHelper.translateColorCodes(input, ColorConversion.RGB); } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalLocation.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalLocation.java index 49c09ff..10fa189 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalLocation.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalLocation.java @@ -5,6 +5,8 @@ import net.knarcraft.stargate.container.RelativeBlockVector; import org.bukkit.Axis; import org.bukkit.World; import org.bukkit.block.BlockFace; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Keeps track of location related data for a portal @@ -23,6 +25,7 @@ public class PortalLocation { * * @return

The top-left block of the portal

*/ + @NotNull public BlockLocation getTopLeft() { return topLeft; } @@ -41,6 +44,7 @@ public class PortalLocation { * * @return

The location of the portal's sign

*/ + @NotNull public BlockLocation getSignLocation() { return signLocation; } @@ -50,6 +54,7 @@ public class PortalLocation { * * @return

The relative location of the portal's button

*/ + @Nullable public RelativeBlockVector getButtonVector() { return buttonVector; } @@ -59,16 +64,19 @@ public class PortalLocation { * * @return

The button's block face

*/ + @NotNull public BlockFace getButtonFacing() { return buttonFacing; } /** * Gets the rotation axis, which is the axis along which the gate is placed + * *

The portal's rotation axis is the cross axis of the button's axis

* * @return

The portal's rotation axis

*/ + @NotNull public Axis getRotationAxis() { return getYaw() == 0.0F || getYaw() == 180.0F ? Axis.X : Axis.Z; } @@ -78,6 +86,7 @@ public class PortalLocation { * * @return

The world this portal resides in

*/ + @Nullable public World getWorld() { return topLeft.getWorld(); } @@ -91,7 +100,8 @@ public class PortalLocation { * @param topLeft

The new top-left block of the portal's square structure

* @return

The portal location Object

*/ - public PortalLocation setTopLeft(BlockLocation topLeft) { + @NotNull + public PortalLocation setTopLeft(@NotNull BlockLocation topLeft) { this.topLeft = topLeft; return this; } @@ -104,6 +114,7 @@ public class PortalLocation { * @param yaw

The portal's new yaw

* @return

The portal location Object

*/ + @NotNull public PortalLocation setYaw(float yaw) { this.yaw = yaw; return this; @@ -115,7 +126,8 @@ public class PortalLocation { * @param signLocation

The new sign location

* @return

The portal location Object

*/ - public PortalLocation setSignLocation(BlockLocation signLocation) { + @NotNull + public PortalLocation setSignLocation(@NotNull BlockLocation signLocation) { this.signLocation = signLocation; return this; } @@ -126,7 +138,8 @@ public class PortalLocation { * @param buttonVector

The new relative button location

* @return

The portal location Object

*/ - public PortalLocation setButtonVector(RelativeBlockVector buttonVector) { + @NotNull + public PortalLocation setButtonVector(@Nullable RelativeBlockVector buttonVector) { this.buttonVector = buttonVector; return this; } @@ -137,7 +150,8 @@ public class PortalLocation { * @param buttonFacing

The new block face of the portal's button

* @return

The portal location Object

*/ - public PortalLocation setButtonFacing(BlockFace buttonFacing) { + @NotNull + public PortalLocation setButtonFacing(@NotNull BlockFace buttonFacing) { this.buttonFacing = buttonFacing; return this; } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java index f7ba015..46c1649 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOption.java @@ -1,5 +1,7 @@ package net.knarcraft.stargate.portal.property; +import org.jetbrains.annotations.NotNull; + /** * Each enum value represents one option a portal can have/use */ @@ -8,57 +10,57 @@ public enum PortalOption { /** * This option allows a portal to be hidden from others */ - HIDDEN('h', "stargate.option.hidden", 11), + HIDDEN('h', "hidden", 11), /** * This option allows a portal that's always on and does not need to be activated or opened each time */ - ALWAYS_ON('a', "stargate.option.alwayson", 12), + ALWAYS_ON('a', "alwayson", 12), /** * This option allows a portal that's private to the stargate's owner */ - PRIVATE('p', "stargate.option.private", 13), + PRIVATE('p', "private", 13), /** * This option allows a portal that's free even if stargates usually are not */ - FREE('f', "stargate.option.free", 15), + FREE('f', "free", 15), /** * This option allows a portal where players exit through the back of the portal */ - BACKWARDS('b', "stargate.option.backwards", 16), + BACKWARDS('b', "backwards", 16), /** * This option shows the gate in the network list even if it's always on */ - SHOW('s', "stargate.option.show", 17), + SHOW('s', "show", 17), /** * This option hides the network name on the sign */ - NO_NETWORK('n', "stargate.option.nonetwork", 18), + NO_NETWORK('n', "nonetwork", 18), /** * This option allows a portal where players teleport to a random exit portal in the network */ - RANDOM('r', "stargate.option.random", 19), + RANDOM('r', "random", 19), /** * This option allows a portal to teleport to another server connected through BungeeCord */ - BUNGEE('u', "stargate.admin.bungee", 20), + BUNGEE('u', "bungee", 20), /** * This option allows a portal which does not display a teleportation message, for better immersion */ - SILENT('q', "stargate.option.silent", 21), + SILENT('q', "silent", 21), /** * This option causes a fixed portal's sign to be removed after creation */ - NO_SIGN('v', "stargate.option.nosign", 22); + NO_SIGN('v', "nosign", 22); private final char characterRepresentation; private final String permissionString; @@ -70,9 +72,9 @@ public enum PortalOption { * @param characterRepresentation

The character representation used on the sign to allow this option

* @param permissionString

The permission necessary to use this option

*/ - PortalOption(final char characterRepresentation, String permissionString, int saveIndex) { + PortalOption(final char characterRepresentation, @NotNull String permissionString, int saveIndex) { this.characterRepresentation = characterRepresentation; - this.permissionString = permissionString; + this.permissionString = "stargate.option." + permissionString; this.saveIndex = saveIndex; } @@ -90,6 +92,7 @@ public enum PortalOption { * * @return

The permission necessary for this option

*/ + @NotNull public String getPermissionString() { return this.permissionString; } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java index 03cf40f..776d588 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOptions.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.portal.property; import net.knarcraft.stargate.Stargate; +import org.jetbrains.annotations.NotNull; import java.util.Map; @@ -18,7 +19,7 @@ public class PortalOptions { * @param options

All options to keep track of

* @param hasDestination

Whether the portal has a fixed destination

*/ - public PortalOptions(Map options, boolean hasDestination) { + public PortalOptions(@NotNull Map options, boolean hasDestination) { this.options = options; isFixed = hasDestination || this.isRandom() || this.isBungee(); diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalOwner.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalOwner.java index 307621e..212fba4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalOwner.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalOwner.java @@ -4,6 +4,8 @@ import net.knarcraft.stargate.Stargate; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.UUID; @@ -20,7 +22,7 @@ public class PortalOwner { * * @param ownerIdentifier

A UUID, or a username for legacy support

*/ - public PortalOwner(String ownerIdentifier) { + public PortalOwner(@NotNull String ownerIdentifier) { parseIdentifier(ownerIdentifier); } @@ -29,7 +31,7 @@ public class PortalOwner { * * @param player

The player which is the owner of the portal

*/ - public PortalOwner(Player player) { + public PortalOwner(@NotNull Player player) { this.ownerUUID = player.getUniqueId(); this.ownerName = player.getName(); } @@ -39,6 +41,7 @@ public class PortalOwner { * * @return

The UUID of this owner, or null if a UUID is not available

*/ + @Nullable public UUID getUUID() { return ownerUUID; } @@ -51,7 +54,7 @@ public class PortalOwner { * * @param uniqueId

The new unique id for the portal owner

*/ - public void setUUID(UUID uniqueId) { + public void setUUID(@NotNull UUID uniqueId) { if (ownerUUID == null) { ownerUUID = uniqueId; } else { @@ -64,6 +67,7 @@ public class PortalOwner { * * @return

The name of this owner

*/ + @NotNull public String getName() { return ownerName; } @@ -76,6 +80,7 @@ public class PortalOwner { * * @return

The owner's identifier

*/ + @NotNull public String getIdentifier() { if (ownerUUID != null) { return ownerUUID.toString(); @@ -93,7 +98,7 @@ public class PortalOwner { * * @param ownerIdentifier

The identifier for a portal's owner

*/ - private void parseIdentifier(String ownerIdentifier) { + private void parseIdentifier(@NotNull String ownerIdentifier) { UUID ownerUUID = null; String ownerName; if (ownerIdentifier.length() > 16) { @@ -102,7 +107,7 @@ public class PortalOwner { ownerUUID = UUID.fromString(ownerIdentifier); OfflinePlayer offlineOwner = Bukkit.getServer().getOfflinePlayer(ownerUUID); ownerName = offlineOwner.getName(); - } catch (IllegalArgumentException ex) { + } catch (IllegalArgumentException exception) { //Invalid as UUID and username, so just keep it as owner name and hope the server owner fixes it ownerName = ownerIdentifier; Stargate.debug("loadAllPortals", "Invalid stargate owner string: " + ownerIdentifier); diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalStructure.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalStructure.java index 2f324d0..ebf97f1 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/PortalStructure.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalStructure.java @@ -5,6 +5,8 @@ import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.property.gate.Gate; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * The portal structure is responsible for the physical properties of a portal @@ -28,7 +30,7 @@ public class PortalStructure { * @param gate

The gate type used by this portal structure

* @param button

The real location of the portal's button

*/ - public PortalStructure(Portal portal, Gate gate, BlockLocation button) { + public PortalStructure(@NotNull Portal portal, @NotNull Gate gate, @Nullable BlockLocation button) { this.portal = portal; this.gate = gate; this.verified = false; @@ -40,6 +42,7 @@ public class PortalStructure { * * @return

The gate used by this portal structure

*/ + @NotNull public Gate getGate() { return gate; } @@ -49,6 +52,7 @@ public class PortalStructure { * * @return

The location of this portal's button

*/ + @Nullable public BlockLocation getButton() { return button; } @@ -58,7 +62,7 @@ public class PortalStructure { * * @param button

The location of this portal's button

*/ - public void setButton(BlockLocation button) { + public void setButton(@NotNull BlockLocation button) { this.button = button; } @@ -113,7 +117,8 @@ public class PortalStructure { * @param vectors

The relative block vectors to convert

* @return

A list of block locations

*/ - private BlockLocation[] relativeBlockVectorsToBlockLocations(RelativeBlockVector[] vectors) { + @NotNull + private BlockLocation[] relativeBlockVectorsToBlockLocations(@NotNull RelativeBlockVector[] vectors) { BlockLocation[] locations = new BlockLocation[vectors.length]; for (int i = 0; i < vectors.length; i++) { locations[i] = portal.getBlockAt(vectors[i]); @@ -126,6 +131,7 @@ public class PortalStructure { * * @return

The locations of this portal's entrances

*/ + @NotNull public BlockLocation[] getEntrances() { if (entrances == null) { //Get the locations of the entrances once, and only if necessary as it's an expensive operation @@ -139,6 +145,7 @@ public class PortalStructure { * * @return

The locations of this portal's frame

*/ + @NotNull public BlockLocation[] getFrame() { if (frame == null) { //Get the locations of the frame blocks once, and only if necessary as it's an expensive operation diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java index d488ca2..57c6dd2 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java @@ -5,6 +5,8 @@ import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; import org.bukkit.Material; import org.bukkit.Tag; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.BufferedWriter; import java.io.File; @@ -24,10 +26,12 @@ public class Gate { private final GateLayout layout; private final Map characterMaterialMap; private final Map> characterTagMap; + //Gate materials private final Material portalOpenBlock; private final Material portalClosedBlock; private final Material portalButton; + //Economy information private final int useCost; private final int createCost; @@ -49,10 +53,11 @@ public class Gate { * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

* @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

*/ - public Gate(String filename, GateLayout layout, Map characterMaterialMap, - Map> characterTagMap, Material portalOpenBlock, - Material portalClosedBlock, Material portalButton, int useCost, int createCost, int destroyCost, - boolean toOwner) { + public Gate(@NotNull String filename, @NotNull GateLayout layout, + @NotNull Map characterMaterialMap, + @NotNull Map> characterTagMap, @NotNull Material portalOpenBlock, + @NotNull Material portalClosedBlock, @NotNull Material portalButton, int useCost, int createCost, + int destroyCost, boolean toOwner) { this.filename = filename; this.layout = layout; this.characterMaterialMap = characterMaterialMap; @@ -71,6 +76,7 @@ public class Gate { * * @return

This gate's layout

*/ + @NotNull public GateLayout getLayout() { return layout; } @@ -80,6 +86,7 @@ public class Gate { * * @return

The character to material map

*/ + @NotNull public Map getCharacterMaterialMap() { return new HashMap<>(characterMaterialMap); } @@ -90,8 +97,9 @@ public class Gate { * @param material

The material to check

* @return

True if the material is valid for control blocks

*/ - public boolean isValidControlBlock(Material material) { - return (getControlBlock() != null) ? getControlBlock().equals(material) : getControlBlockTag().isTagged(material); + public boolean isValidControlBlock(@NotNull Material material) { + return (getControlBlock() != null) ? getControlBlock().equals(material) : + getControlBlockTag().isTagged(material); } /** @@ -99,6 +107,7 @@ public class Gate { * * @return

The material tag type used for control blocks

*/ + @NotNull public Tag getControlBlockTag() { return characterTagMap.get(GateHandler.getControlBlockCharacter()); } @@ -108,6 +117,7 @@ public class Gate { * * @return

The material type used for control blocks

*/ + @Nullable public Material getControlBlock() { return characterMaterialMap.get(GateHandler.getControlBlockCharacter()); } @@ -117,6 +127,7 @@ public class Gate { * * @return

The filename of this gate's file

*/ + @NotNull public String getFilename() { return filename; } @@ -126,6 +137,7 @@ public class Gate { * * @return

The block type to use for the opening when open

*/ + @NotNull public Material getPortalOpenBlock() { return portalOpenBlock; } @@ -135,6 +147,7 @@ public class Gate { * * @return

The block type to use for the opening when closed

*/ + @NotNull public Material getPortalClosedBlock() { return portalClosedBlock; } @@ -144,6 +157,7 @@ public class Gate { * * @return

The material to use for a portal's button if using this gate type

*/ + @NotNull public Material getPortalButton() { return portalButton; } @@ -162,6 +176,7 @@ public class Gate { * * @return

The cost of creating a portal with this gate

*/ + @NotNull public Integer getCreateCost() { return createCost < 0 ? Stargate.getEconomyConfig().getDefaultCreateCost() : createCost; } @@ -171,6 +186,7 @@ public class Gate { * * @return

The cost of destroying a portal with this gate

*/ + @NotNull public Integer getDestroyCost() { return destroyCost < 0 ? Stargate.getEconomyConfig().getDefaultDestroyCost() : destroyCost; } @@ -180,6 +196,7 @@ public class Gate { * * @return

Whether portal payments go to the owner

*/ + @NotNull public Boolean getToOwner() { return toOwner; } @@ -191,7 +208,7 @@ public class Gate { * @param yaw

The yaw when looking directly outwards

* @return

True if this gate matches the portal

*/ - public boolean matches(BlockLocation topLeft, double yaw) { + public boolean matches(@NotNull BlockLocation topLeft, double yaw) { return matches(topLeft, yaw, false); } @@ -207,7 +224,7 @@ public class Gate { * @param onCreate

Whether this is used in the context of creating a new gate

* @return

True if this gate matches the portal

*/ - public boolean matches(BlockLocation topLeft, double yaw, boolean onCreate) { + public boolean matches(@NotNull BlockLocation topLeft, double yaw, boolean onCreate) { return verifyGateEntrancesMatch(topLeft, yaw, onCreate) && verifyGateBorderMatches(topLeft, yaw); } @@ -218,12 +235,12 @@ public class Gate { * @param yaw

The yaw when looking directly outwards from the portal

* @return

True if all border blocks of the gate match the layout

*/ - private boolean verifyGateBorderMatches(BlockLocation topLeft, double yaw) { + private boolean verifyGateBorderMatches(@NotNull BlockLocation topLeft, double yaw) { Map characterMaterialMap = new HashMap<>(this.characterMaterialMap); Map> characterTagMap = new HashMap<>(this.characterTagMap); for (RelativeBlockVector borderVector : layout.getBorder()) { - int rowIndex = borderVector.getRight(); - int lineIndex = borderVector.getDown(); + int rowIndex = borderVector.right(); + int lineIndex = borderVector.down(); Character key = layout.getLayout()[lineIndex][rowIndex]; Material materialInLayout = characterMaterialMap.get(key); @@ -263,7 +280,7 @@ public class Gate { * @param onCreate

Whether this is used in the context of creating a new gate

* @return

Whether this is used in the context of creating a new gate

*/ - private boolean verifyGateEntrancesMatch(BlockLocation topLeft, double yaw, boolean onCreate) { + private boolean verifyGateEntrancesMatch(@NotNull BlockLocation topLeft, double yaw, boolean onCreate) { Stargate.debug("verifyGateEntrancesMatch", String.valueOf(topLeft)); for (RelativeBlockVector entranceVector : layout.getEntrances()) { Stargate.debug("verifyGateEntrancesMatch", String.valueOf(entranceVector)); @@ -289,7 +306,7 @@ public class Gate { * * @param gateFolder

The folder to save the gate file in

*/ - public void save(String gateFolder) { + public void save(@NotNull String gateFolder) { try { BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File(gateFolder, filename))); @@ -321,7 +338,7 @@ public class Gate { * @param bufferedWriter

The buffered writer to write to

* @throws IOException

If unable to write to the buffered writer

*/ - private void saveEconomyValues(BufferedWriter bufferedWriter) throws IOException { + private void saveEconomyValues(@NotNull BufferedWriter bufferedWriter) throws IOException { //Write use cost if not disabled if (useCost != -1) { writeConfig(bufferedWriter, "usecost", useCost); @@ -343,7 +360,7 @@ public class Gate { * @param bufferedWriter

The buffered writer to write to

* @throws IOException

If unable to write to the buffered writer

*/ - private void saveFrameBlockType(BufferedWriter bufferedWriter) throws IOException { + private void saveFrameBlockType(@NotNull BufferedWriter bufferedWriter) throws IOException { for (Map.Entry entry : this.characterMaterialMap.entrySet()) { Character key = entry.getKey(); //Skip characters not part of the frame @@ -368,7 +385,8 @@ public class Gate { * @param bufferedWriter

The buffered writer to write to

* @throws IOException

If unable to write to the buffered writer

*/ - private void saveFrameBlockType(Character key, String value, BufferedWriter bufferedWriter) throws IOException { + private void saveFrameBlockType(@NotNull Character key, @Nullable String value, + @NotNull BufferedWriter bufferedWriter) throws IOException { bufferedWriter.append(key.toString()); bufferedWriter.append('='); if (value != null) { @@ -385,7 +403,8 @@ public class Gate { * @param value

The config value to save

* @throws IOException

If unable to write to the buffered writer

*/ - private void writeConfig(BufferedWriter bufferedWriter, String key, Object value) throws IOException { + private void writeConfig(@NotNull BufferedWriter bufferedWriter, @NotNull String key, + @NotNull Object value) throws IOException { //Figure out the correct formatting to use String format = "%s="; if (value instanceof Boolean) { diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java index 197fe6b..ebdce4e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java @@ -8,6 +8,8 @@ import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.Tag; import org.bukkit.block.Block; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.InputStream; @@ -48,6 +50,7 @@ public class GateHandler { * * @return

The character used for blocks that are not part of the gate

*/ + @NotNull public static Character getAnythingCharacter() { return ANYTHING; } @@ -57,6 +60,7 @@ public class GateHandler { * * @return

The character used for defining the entrance

*/ + @NotNull public static Character getEntranceCharacter() { return ENTRANCE; } @@ -66,6 +70,7 @@ public class GateHandler { * * @return

The character used for defining the exit

*/ + @NotNull public static Character getExitCharacter() { return EXIT; } @@ -76,6 +81,7 @@ public class GateHandler { * * @return

The character used for defining control blocks

*/ + @NotNull public static Character getControlBlockCharacter() { return CONTROL_BLOCK; } @@ -85,7 +91,7 @@ public class GateHandler { * * @param gate

The gate to register

*/ - private static void registerGate(Gate gate) { + private static void registerGate(@NotNull Gate gate) { gates.put(gate.getFilename(), gate); Material blockId = gate.getControlBlock(); @@ -110,7 +116,8 @@ public class GateHandler { * @param file

The file containing the gate data

* @return

The loaded gate, or null if unable to load the gate

*/ - private static Gate loadGate(File file) { + @Nullable + private static Gate loadGate(@NotNull File file) { try (Scanner scanner = new Scanner(file)) { return loadGate(file.getName(), file.getParent(), scanner); } catch (Exception exception) { @@ -127,7 +134,9 @@ public class GateHandler { * @param scanner

The scanner to use for reading the gate data

* @return

The loaded gate or null if unable to load the gate

*/ - private static Gate loadGate(String fileName, String parentFolder, Scanner scanner) { + @Nullable + private static Gate loadGate(@NotNull String fileName, @NotNull String parentFolder, + @NotNull Scanner scanner) { List> design = new ArrayList<>(); Map characterMaterialMap = new HashMap<>(); Map> characterTagMap = new HashMap<>(); @@ -166,9 +175,11 @@ public class GateHandler { * @param materialTagMap

A map between layout characters and the material tags to use

* @return

A new gate, or null if the config is invalid

*/ - private static Gate createGate(Map config, String fileName, Character[][] layout, - Map characterMaterialMap, - Map> materialTagMap) { + @Nullable + private static Gate createGate(@NotNull Map config, @NotNull String fileName, + @NotNull Character[][] layout, + @NotNull Map characterMaterialMap, + @NotNull Map> materialTagMap) { //Read relevant material types Material portalOpenBlock = readGateConfig(config, fileName, "portal-open", defaultPortalBlockOpen); Material portalClosedBlock = readGateConfig(config, fileName, "portal-closed", defaultPortalBlockClosed); @@ -198,7 +209,7 @@ public class GateHandler { * @param fileName

The filename of the loaded gate file

* @return

True if the gate is valid. False otherwise

*/ - private static boolean validateGate(Gate gate, String fileName) { + private static boolean validateGate(@NotNull Gate gate, @NotNull String fileName) { String failString = String.format("Could not load Gate %s", fileName) + " - %s"; if (gate.getLayout().getControls().length != 2) { @@ -236,7 +247,7 @@ public class GateHandler { * * @param gateFolder

The folder containing the gates

*/ - public static void loadGates(String gateFolder) { + public static void loadGates(@NotNull String gateFolder) { File directory = new File(gateFolder); File[] files; @@ -269,7 +280,7 @@ public class GateHandler { * * @param gateFolder

The folder containing gate config files

*/ - public static void writeDefaultGatesToFolder(String gateFolder) { + public static void writeDefaultGatesToFolder(@NotNull String gateFolder) { loadGateFromJar("nethergate.gate", gateFolder); loadGateFromJar("watergate.gate", gateFolder); loadGateFromJar("endgate.gate", gateFolder); @@ -283,7 +294,7 @@ public class GateHandler { * @param gateFile

The name of the gate file

* @param gateFolder

The folder containing gates

*/ - private static void loadGateFromJar(String gateFile, String gateFolder) { + private static void loadGateFromJar(@NotNull String gateFile, @NotNull String gateFolder) { //Get an input stream for the internal file InputStream gateFileStream = Gate.class.getResourceAsStream("/gates/" + gateFile); if (gateFileStream != null) { @@ -305,7 +316,8 @@ public class GateHandler { * @param block

The control block to check

* @return

A list of gates using the given control block

*/ - public static Gate[] getGatesByControlBlock(Block block) { + @NotNull + public static List getGatesByControlBlock(@NotNull Block block) { return getGatesByControlBlock(block.getType()); } @@ -318,7 +330,8 @@ public class GateHandler { * @param type

The type of the control block to check

* @return

A list of gates using the given material for control block

*/ - public static Gate[] getGatesByControlBlock(Material type) { + @NotNull + public static List getGatesByControlBlock(@NotNull Material type) { List result = new ArrayList<>(); List fromId = controlBlocks.get(type); List fromTag = null; @@ -337,7 +350,7 @@ public class GateHandler { result.addAll(fromTag); } - return result.toArray(new Gate[0]); + return result; } /** @@ -346,7 +359,8 @@ public class GateHandler { * @param fileName

The filename of the gate to get

* @return

The gate with the given filename

*/ - public static Gate getGateByName(String fileName) { + @Nullable + public static Gate getGateByName(@NotNull String fileName) { return gates.get(fileName); } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateLayout.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateLayout.java index 540983e..1940471 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateLayout.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateLayout.java @@ -1,6 +1,8 @@ package net.knarcraft.stargate.portal.property.gate; import net.knarcraft.stargate.container.RelativeBlockVector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.BufferedWriter; import java.io.IOException; @@ -28,7 +30,7 @@ public class GateLayout { * * @param layout

A character matrix describing the layout

*/ - public GateLayout(Character[][] layout) { + public GateLayout(@NotNull Character[][] layout) { this.layout = layout; readLayout(); } @@ -38,6 +40,7 @@ public class GateLayout { * * @return

The character array describing this layout

*/ + @NotNull public Character[][] getLayout() { return this.layout; } @@ -49,6 +52,7 @@ public class GateLayout { * * @return

The locations of entrances for this gate

*/ + @NotNull public RelativeBlockVector[] getEntrances() { return entrances; } @@ -61,6 +65,7 @@ public class GateLayout { * * @return

The locations of border blocks for this gate

*/ + @NotNull public RelativeBlockVector[] getBorder() { return border; } @@ -70,6 +75,7 @@ public class GateLayout { * * @return

The exit block defined in the layout

*/ + @Nullable public RelativeBlockVector getExit() { return exitBlock; } @@ -82,6 +88,7 @@ public class GateLayout { * * @return

All possible exits

*/ + @NotNull public List getExits() { return exits; } @@ -94,6 +101,7 @@ public class GateLayout { * * @return

The locations of the control blocks for this gate

*/ + @NotNull public RelativeBlockVector[] getControls() { return controls; } @@ -104,7 +112,7 @@ public class GateLayout { * @param bufferedWriter

The buffered writer to write to

* @throws IOException

If unable to write to the buffered writer

*/ - public void saveLayout(BufferedWriter bufferedWriter) throws IOException { + public void saveLayout(@NotNull BufferedWriter bufferedWriter) throws IOException { for (Character[] line : this.layout) { for (Character character : line) { bufferedWriter.append(character); @@ -137,8 +145,9 @@ public class GateLayout { * @param entranceList

The list of entrances to save to

* @param borderList

The list of border blocks to save to

*/ - private void readLayout(List controlList, List entranceList, - List borderList) { + private void readLayout(@NotNull List controlList, + @NotNull List entranceList, + @NotNull List borderList) { //Store the lowest opening for each column int[] exitDepths = new int[layout[0].length]; @@ -173,9 +182,10 @@ public class GateLayout { * @param entranceList

The list of entrances to save to

* @param borderList

The list of border blocks to save to

*/ - private void parseLayoutCharacter(Character key, int columnIndex, int rowIndex, int[] exitDepths, - List controlList, List entranceList, - List borderList) { + private void parseLayoutCharacter(@NotNull Character key, int columnIndex, int rowIndex, int[] exitDepths, + @NotNull List controlList, + @NotNull List entranceList, + @NotNull List borderList) { //Add control blocks to the control block list if (key.equals(GateHandler.getControlBlockCharacter())) { controlList.add(new RelativeBlockVector(columnIndex, rowIndex, 0)); @@ -202,7 +212,7 @@ public class GateLayout { * @param character

The character to check

* @return

True if the character represents an opening

*/ - private boolean isOpening(Character character) { + private boolean isOpening(@NotNull Character character) { return character.equals(GateHandler.getEntranceCharacter()) || character.equals(GateHandler.getExitCharacter()); } diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java index e963c92..8b18d11 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/EntityTeleporter.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.portal.teleporter; import net.knarcraft.stargate.event.StargateEntityPortalEvent; import net.knarcraft.stargate.portal.Portal; import org.bukkit.entity.Entity; +import org.jetbrains.annotations.NotNull; /** * The portal teleporter takes care of the actual portal teleportation for any entities @@ -16,7 +17,7 @@ public class EntityTeleporter extends Teleporter { * * @param targetPortal

The portal which is the target of the teleportation

*/ - public EntityTeleporter(Portal targetPortal, Entity teleportingEntity) { + public EntityTeleporter(@NotNull Portal targetPortal, @NotNull Entity teleportingEntity) { super(targetPortal, teleportingEntity); this.teleportingEntity = teleportingEntity; } @@ -27,7 +28,7 @@ public class EntityTeleporter extends Teleporter { * @param origin

The portal the entity is teleporting from

* @return

True if the entity was teleported. False otherwise

*/ - public boolean teleportEntity(Portal origin) { + public boolean teleportEntity(@NotNull Portal origin) { return teleport(origin, new StargateEntityPortalEvent(teleportingEntity, origin, portal, exit)); } diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java index 3460340..e34a68c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/PlayerTeleporter.java @@ -10,6 +10,8 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -26,7 +28,7 @@ public class PlayerTeleporter extends Teleporter { * @param targetPortal

The portal which is the target of the teleportation

* @param player

The teleporting player

*/ - public PlayerTeleporter(Portal targetPortal, Player player) { + public PlayerTeleporter(@NotNull Portal targetPortal, @NotNull Player player) { super(targetPortal, player); this.player = player; } @@ -37,7 +39,7 @@ public class PlayerTeleporter extends Teleporter { * @param origin

The portal the player teleports from

* @param event

The player move event triggering the event

*/ - public void teleportPlayer(Portal origin, PlayerMoveEvent event) { + public void teleportPlayer(@NotNull Portal origin, @Nullable PlayerMoveEvent event) { double velocity = player.getVelocity().length(); List passengers = player.getPassengers(); diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 7e1f7ee..3322b4d 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -20,6 +20,8 @@ import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -55,7 +57,7 @@ public abstract class Teleporter { * @param portal

The portal which is the target of the teleportation

* @param teleportedEntity

The entity teleported by this teleporter

*/ - public Teleporter(Portal portal, Entity teleportedEntity) { + public Teleporter(@NotNull Portal portal, @NotNull Entity teleportedEntity) { this.portal = portal; this.scheduler = Stargate.getInstance().getServer().getScheduler(); this.teleportedEntity = teleportedEntity; @@ -69,11 +71,11 @@ public abstract class Teleporter { * @param stargateTeleportEvent

The event to call to make sure the teleportation is valid

* @return

True if the teleportation was successfully performed

*/ - public boolean teleport(Portal origin, StargateTeleportEvent stargateTeleportEvent) { + public boolean teleport(@NotNull Portal origin, @Nullable StargateTeleportEvent stargateTeleportEvent) { List passengers = teleportedEntity.getPassengers(); //Call the StargateEntityPortalEvent to allow plugins to change destination - if (!origin.equals(portal)) { + if (!origin.equals(portal) && stargateTeleportEvent != null) { exit = triggerPortalEvent(origin, stargateTeleportEvent); if (exit == null) { return false; @@ -96,6 +98,7 @@ public abstract class Teleporter { * * @return

The exit location of this teleporter

*/ + @NotNull public Location getExit() { return exit.clone(); } @@ -107,7 +110,9 @@ public abstract class Teleporter { * @param stargateTeleportEvent

The exit location to teleport the entity to

* @return

The location the entity should be teleported to, or null if the event was cancelled

*/ - protected Location triggerPortalEvent(Portal origin, StargateTeleportEvent stargateTeleportEvent) { + @Nullable + protected Location triggerPortalEvent(@NotNull Portal origin, + @NotNull StargateTeleportEvent stargateTeleportEvent) { Stargate.getInstance().getServer().getPluginManager().callEvent((Event) stargateTeleportEvent); //Teleport is cancelled. Teleport the entity back to where it came from just for sanity's sake if (stargateTeleportEvent.isCancelled()) { @@ -122,7 +127,7 @@ public abstract class Teleporter { * * @param exit

The location the entity will exit from

*/ - protected void adjustExitLocationRotation(Location exit) { + protected void adjustExitLocationRotation(@NotNull Location exit) { int adjust = 0; if (portal.getOptions().isBackwards()) { adjust = 180; @@ -151,7 +156,9 @@ public abstract class Teleporter { * @param entity

The travelling entity

* @return

A location which won't suffocate the entity inside the portal

*/ - private Location preventExitSuffocation(RelativeBlockVector relativeExit, Location exitLocation, Entity entity) { + @NotNull + private Location preventExitSuffocation(@NotNull RelativeBlockVector relativeExit, + @NotNull Location exitLocation, @NotNull Entity entity) { //Go left to find start of opening RelativeBlockVector openingLeft = getPortalExitEdge(relativeExit, -1); @@ -159,8 +166,8 @@ public abstract class Teleporter { RelativeBlockVector openingRight = getPortalExitEdge(relativeExit, 1); //Get the width to check if the entity fits - int openingWidth = openingRight.getRight() - openingLeft.getRight() + 1; - int existingOffset = relativeExit.getRight() - openingLeft.getRight(); + int openingWidth = openingRight.right() - openingLeft.right() + 1; + int existingOffset = relativeExit.right() - openingLeft.right(); double newOffset = (openingWidth - existingOffset) / 2D; //Remove the half offset for better centering @@ -180,7 +187,8 @@ public abstract class Teleporter { * @param entity

The entity to adjust the exit location for

* @return

The adjusted exit location

*/ - private Location moveExitLocationOutwards(Location exitLocation, Entity entity) { + @NotNull + private Location moveExitLocationOutwards(@NotNull Location exitLocation, @NotNull Entity entity) { double entitySize = EntityHelper.getEntityMaxSize(entity); int entityBoxSize = EntityHelper.getEntityMaxSizeInt(entity); if (entitySize > 1) { @@ -207,12 +215,13 @@ public abstract class Teleporter { * @param direction

The direction to move (+1 for right, -1 for left)

* @return

The right or left edge of the opening

*/ - private RelativeBlockVector getPortalExitEdge(RelativeBlockVector relativeExit, int direction) { + @NotNull + private RelativeBlockVector getPortalExitEdge(@NotNull RelativeBlockVector relativeExit, int direction) { RelativeBlockVector openingEdge = relativeExit; do { - RelativeBlockVector possibleOpening = new RelativeBlockVector(openingEdge.getRight() + direction, - openingEdge.getDown(), openingEdge.getOut()); + RelativeBlockVector possibleOpening = new RelativeBlockVector(openingEdge.right() + direction, + openingEdge.down(), openingEdge.out()); if (portal.getGate().getLayout().getExits().contains(possibleOpening)) { openingEdge = possibleOpening; } else { @@ -234,7 +243,8 @@ public abstract class Teleporter { * @param exitLocation

The exit location generated

* @return

The location the travelling entity should be teleported to

*/ - private Location adjustExitLocationHeight(Entity entity, Location exitLocation) { + @NotNull + private Location adjustExitLocationHeight(@NotNull Entity entity, @Nullable Location exitLocation) { if (exitLocation != null) { BlockData blockData = exitLocation.getBlock().getBlockData(); if ((blockData instanceof Bisected bisected && bisected.getHalf() == Bisected.Half.BOTTOM) || @@ -257,7 +267,8 @@ public abstract class Teleporter { * @param entity

The entity to teleport (used to determine distance from portal to avoid suffocation)

* @return

The location the entity should be teleported to.

*/ - private Location getExit(Entity entity) { + @NotNull + private Location getExit(@NotNull Entity entity) { Location exitLocation = null; RelativeBlockVector relativeExit = portal.getGate().getLayout().getExit(); if (relativeExit != null) { @@ -270,12 +281,10 @@ public abstract class Teleporter { } exitLocation = exit.getRelativeLocation(0D, 0D, 1, portalYaw); - if (entity != null) { - double entitySize = EntityHelper.getEntityMaxSize(entity); - //Prevent exit suffocation for players riding horses or similar - if (entitySize > 1) { - exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); - } + double entitySize = EntityHelper.getEntityMaxSize(entity); + //Prevent exit suffocation for players riding horses or similar + if (entitySize > 1) { + exitLocation = preventExitSuffocation(relativeExit, exitLocation, entity); } } else { Stargate.logWarning(String.format("Missing destination point in .gate file %s", @@ -293,6 +302,7 @@ public abstract class Teleporter { * * @return

A list of chunks to load

*/ + @NotNull private List getChunksToLoad() { List chunksToLoad = new ArrayList<>(); for (RelativeBlockVector vector : portal.getGate().getLayout().getEntrances()) { diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java index 4f3e42c..ac2fd17 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/VehicleTeleporter.java @@ -14,6 +14,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Vehicle; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; import java.util.List; @@ -30,7 +31,7 @@ public class VehicleTeleporter extends EntityTeleporter { * @param targetPortal

The targetPortal which is the target of the teleportation

* @param teleportingVehicle

The teleporting vehicle

*/ - public VehicleTeleporter(Portal targetPortal, Vehicle teleportingVehicle) { + public VehicleTeleporter(@NotNull Portal targetPortal, @NotNull Vehicle teleportingVehicle) { super(targetPortal, teleportingVehicle); this.teleportingVehicle = teleportingVehicle; } @@ -45,7 +46,7 @@ public class VehicleTeleporter extends EntityTeleporter { * @return

True if the vehicle was teleported. False otherwise

*/ @Override - public boolean teleportEntity(Portal origin) { + public boolean teleportEntity(@NotNull Portal origin) { Stargate.debug("VehicleTeleporter::teleport", "Preparing to teleport: " + teleportingVehicle); double velocity = teleportingVehicle.getVelocity().length(); @@ -75,7 +76,7 @@ public class VehicleTeleporter extends EntityTeleporter { * @param origin

The portal the vehicle teleported from

* @return

True if the vehicle was teleported. False otherwise

*/ - private boolean teleportVehicle(Location exit, Vector newVelocity, Portal origin) { + private boolean teleportVehicle(@NotNull Location exit, @NotNull Vector newVelocity, @NotNull Portal origin) { //Load chunks to make sure not to teleport to the void loadChunks(); @@ -113,7 +114,7 @@ public class VehicleTeleporter extends EntityTeleporter { * @param passengers

The passengers to teleport

* @return

True if the passengers are allowed to teleport

*/ - private boolean vehiclePassengersAllowed(List passengers) { + private boolean vehiclePassengersAllowed(@NotNull List passengers) { StargateGateConfig config = Stargate.getGateConfig(); //Don't teleport if the vehicle contains a creature and creature transportation is disabled if (TeleportHelper.containsNonPlayer(passengers) && !config.handleCreatureTransportation()) { @@ -131,7 +132,8 @@ public class VehicleTeleporter extends EntityTeleporter { * @param newVelocity

The new velocity of the teleported vehicle

* @param origin

The portal the vehicle teleported from

*/ - private void teleportVehicle(List passengers, Location exit, Vector newVelocity, Portal origin) { + private void teleportVehicle(@NotNull List passengers, @NotNull Location exit, @NotNull Vector newVelocity, + @NotNull Portal origin) { if (teleportingVehicle.eject()) { TeleportHelper.handleEntityPassengers(passengers, teleportingVehicle, origin, portal, exit.getDirection(), newVelocity); @@ -159,8 +161,8 @@ public class VehicleTeleporter extends EntityTeleporter { * @param newVelocity

The new velocity of the new vehicle

* @param origin

The portal the vehicle teleported from

*/ - private void putPassengersInNewVehicle(List passengers, Location exit, - Vector newVelocity, Portal origin) { + private void putPassengersInNewVehicle(@NotNull List passengers, @NotNull Location exit, + @NotNull Vector newVelocity, Portal origin) { World vehicleWorld = exit.getWorld(); if (vehicleWorld == null) { Stargate.logWarning("Unable to get the world to teleport the vehicle to"); diff --git a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java index faa14fc..8dd703c 100644 --- a/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java +++ b/src/main/java/net/knarcraft/stargate/thread/BlockChangeThread.java @@ -8,6 +8,7 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.EndGateway; import org.bukkit.block.data.Orientable; +import org.jetbrains.annotations.NotNull; /** * This thread changes gate blocks to display a gate as open or closed @@ -58,7 +59,7 @@ public class BlockChangeThread implements Runnable { * * @param block

The block to fix

*/ - private static void fixEndGatewayGate(Block block) { + private static void fixEndGatewayGate(@NotNull Block block) { EndGateway gateway = (EndGateway) block.getState(); gateway.setAge(Long.MIN_VALUE); if (block.getWorld().getEnvironment() == World.Environment.THE_END) { @@ -74,7 +75,7 @@ public class BlockChangeThread implements Runnable { * @param block

The block to orient

* @param axis

The axis to use for orienting the block

*/ - private static void orientBlock(Block block, Axis axis) { + private static void orientBlock(@NotNull Block block, @NotNull Axis axis) { Orientable orientable = (Orientable) block.getBlockData(); orientable.setAxis(axis); block.setBlockData(orientable); diff --git a/src/main/java/net/knarcraft/stargate/utility/BStatsHelper.java b/src/main/java/net/knarcraft/stargate/utility/BStatsHelper.java index 1372507..134419b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BStatsHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BStatsHelper.java @@ -8,6 +8,7 @@ import org.bstats.bukkit.Metrics; import org.bstats.charts.SimplePie; import org.bstats.charts.SingleLineChart; import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.Map; @@ -28,7 +29,7 @@ public final class BStatsHelper { * * @param plugin

The plugin to initialize BStats for

*/ - public static void initialize(JavaPlugin plugin) { + public static void initialize(@NotNull JavaPlugin plugin) { if (hasBeenInitialized) { throw new IllegalArgumentException("BStats initialized twice"); } else { diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index b59bde2..1145d73 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -7,6 +7,8 @@ import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; import net.md_5.bungee.api.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -36,6 +38,7 @@ public final class BungeeHelper { * * @return

The bungee plugin channel

*/ + @NotNull public static String getBungeeChannel() { return bungeeChannel; } @@ -48,9 +51,10 @@ public final class BungeeHelper { * queue and teleported to the destination.

* * @param playerUUID

The UUID of the player to remove

- * @return

The name of the destination portal the player should be teleported to

+ * @return

The name of the destination portal the player should be teleported to, or null if not queued

*/ - public static String removeFromQueue(UUID playerUUID) { + @Nullable + public static String removeFromQueue(@NotNull UUID playerUUID) { return bungeeQueue.remove(playerUUID); } @@ -61,7 +65,7 @@ public final class BungeeHelper { * @param entrancePortal

The portal the player is teleporting from

* @return

True if the message was successfully sent

*/ - public static boolean sendTeleportationMessage(Player player, Portal entrancePortal) { + public static boolean sendTeleportationMessage(@NotNull Player player, @NotNull Portal entrancePortal) { try { //Build the teleportation message, format is delimiter String message = player.getUniqueId() + teleportMessageDelimiter + entrancePortal.getDestinationName(); @@ -81,8 +85,8 @@ public final class BungeeHelper { dataOutputStream.writeBytes(message); //Send the plugin message player.sendPluginMessage(Stargate.getInstance(), bungeeChannel, byteArrayOutputStream.toByteArray()); - } catch (IOException ex) { - Stargate.logSevere("Error sending BungeeCord teleport packet! Message: " + ex.getMessage()); + } catch (IOException exception) { + Stargate.logSevere("Error sending BungeeCord teleport packet! Message: " + exception.getMessage()); return false; } return true; @@ -95,7 +99,7 @@ public final class BungeeHelper { * @param entrancePortal

The bungee portal the player is teleporting from

* @return

True if the plugin message was sent successfully

*/ - public static boolean changeServer(Player player, Portal entrancePortal) { + public static boolean changeServer(@NotNull Player player, @NotNull Portal entrancePortal) { try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream); @@ -119,6 +123,7 @@ public final class BungeeHelper { * @param message

The byte array to read

* @return

The message contained in the byte array, or null on failure

*/ + @Nullable public static String readPluginMessage(byte[] message) { byte[] data; try { @@ -147,7 +152,7 @@ public final class BungeeHelper { * * @param receivedMessage

The received teleport message

*/ - public static void handleTeleportMessage(String receivedMessage) { + public static void handleTeleportMessage(@NotNull String receivedMessage) { //Get the player id and destination from the message String[] messageParts = receivedMessage.split(teleportMessageDelimiter); UUID playerUUID = UUID.fromString(messageParts[0]); @@ -176,7 +181,8 @@ public final class BungeeHelper { * @param event

The event causing the teleportation

* @return

True if the teleportation was successful

*/ - public static boolean bungeeTeleport(Player player, Portal entrancePortal, PlayerMoveEvent event) { + public static boolean bungeeTeleport(@NotNull Player player, @NotNull Portal entrancePortal, + @NotNull PlayerMoveEvent event) { //Check if bungee is actually enabled if (!Stargate.getGateConfig().enableBungee()) { if (!entrancePortal.getOptions().isSilent()) { @@ -211,7 +217,8 @@ public final class BungeeHelper { * @param string

The string to strip color from

* @return

The string without color codes

*/ - private static String stripColor(String string) { + @NotNull + private static String stripColor(@NotNull String string) { return ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', string)); } diff --git a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java index 82adf9f..0300cc4 100644 --- a/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/DirectionHelper.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.utility; import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; /** * This class helps with direction-related calculations @@ -24,7 +25,7 @@ public final class DirectionHelper { * @param location2

The second location, which the yaw will point towards

* @return

The yaw pointing from the first location to the second location

*/ - public static float getYawFromLocationDifference(Location location1, Location location2) { + public static float getYawFromLocationDifference(@NotNull Location location1, @NotNull Location location2) { Location difference = location1.clone().subtract(location2.clone()); if (difference.getX() > 0) { return 90; @@ -45,8 +46,10 @@ public final class DirectionHelper { * * @param yaw

The yaw value to convert

* @return

The block face the yaw corresponds to

+ * @throws IllegalArgumentException

If a yaw not divisible by 90 us given

*/ - public static BlockFace getBlockFaceFromYaw(double yaw) { + @NotNull + public static BlockFace getBlockFaceFromYaw(double yaw) throws IllegalArgumentException { //Make sure the yaw is between 0 and 360 yaw = normalizeYaw(yaw); @@ -68,8 +71,10 @@ public final class DirectionHelper { * * @param yaw

The yaw to convert to a direction vector

* @return

The direction vector pointing in the same direction as the yaw

+ * @throws IllegalArgumentException

If a yaw not divisible by 90 is given

*/ - public static Vector getDirectionVectorFromYaw(double yaw) { + @NotNull + public static Vector getDirectionVectorFromYaw(double yaw) throws IllegalArgumentException { //Make sure the yaw is between 0 and 360 yaw = normalizeYaw(yaw); @@ -99,7 +104,8 @@ public final class DirectionHelper { * @param yaw

The yaw when looking directly outwards from a portal

* @return

A location relative to the given location

*/ - public static Location moveLocation(Location location, double right, double down, double out, double yaw) { + @NotNull + public static Location moveLocation(@NotNull Location location, double right, double down, double out, double yaw) { return location.add(getCoordinateVectorFromRelativeVector(right, down, out, yaw)); } @@ -111,8 +117,11 @@ public final class DirectionHelper { * @param out

The distance outward from the top-left origin

* @param yaw

The yaw when looking directly outwards from a portal

* @return

A normal vector

+ * @throws IllegalArgumentException

If a yaw not divisible by 90 is given

*/ - public static Vector getCoordinateVectorFromRelativeVector(double right, double down, double out, double yaw) { + @NotNull + public static Vector getCoordinateVectorFromRelativeVector(double right, double down, double out, + double yaw) throws IllegalArgumentException { //Make sure the yaw is between 0 and 360 yaw = normalizeYaw(yaw); diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index 3bdccb1..aa462f3 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -9,6 +9,8 @@ import net.milkbowl.vault.economy.Economy; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.UUID; @@ -29,7 +31,7 @@ public final class EconomyHelper { * @param cost

The cost of teleportation

* @return

False if payment was successful. True if the payment was unsuccessful

*/ - public static boolean cannotPayTeleportFee(Portal entrancePortal, Player player, int cost) { + public static boolean cannotPayTeleportFee(@NotNull Portal entrancePortal, @NotNull Player player, int cost) { boolean success; //Try to charge the player. Paying the portal owner is only possible if a UUID is available @@ -78,7 +80,7 @@ public final class EconomyHelper { * @param portalOwner

The owner of the portal

* @param earnings

The amount the owner earned

*/ - public static void sendObtainMessage(String portalName, Player portalOwner, int earnings) { + public static void sendObtainMessage(@NotNull String portalName, @NotNull Player portalOwner, int earnings) { String obtainedMsg = Stargate.getString("ecoObtain"); obtainedMsg = replacePlaceholders(obtainedMsg, portalName, earnings); Stargate.getMessageSender().sendSuccessMessage(portalOwner, obtainedMsg); @@ -91,7 +93,7 @@ public final class EconomyHelper { * @param player

The interacting player

* @param cost

The cost of the interaction

*/ - public static void sendDeductMessage(String portalName, Player player, int cost) { + public static void sendDeductMessage(@NotNull String portalName, @NotNull Player player, int cost) { String deductMsg = Stargate.getString("ecoDeduct"); deductMsg = replacePlaceholders(deductMsg, portalName, cost); Stargate.getMessageSender().sendSuccessMessage(player, deductMsg); @@ -104,7 +106,7 @@ public final class EconomyHelper { * @param player

The interacting player

* @param cost

The cost of the interaction

*/ - public static void sendInsufficientFundsMessage(String portalName, Player player, int cost) { + public static void sendInsufficientFundsMessage(@NotNull String portalName, @NotNull Player player, int cost) { String inFundMsg = Stargate.getString("ecoInFunds"); inFundMsg = replacePlaceholders(inFundMsg, portalName, cost); Stargate.getMessageSender().sendErrorMessage(player, inFundMsg); @@ -117,7 +119,7 @@ public final class EconomyHelper { * @param player

The player breaking the portal

* @param cost

The amount the user has to pay for destroying the portal. (expects a negative value)

*/ - public static void sendRefundMessage(String portalName, Player player, int cost) { + public static void sendRefundMessage(@NotNull String portalName, @NotNull Player player, int cost) { String refundMsg = Stargate.getString("ecoRefund"); refundMsg = replacePlaceholders(refundMsg, portalName, -cost); Stargate.getMessageSender().sendSuccessMessage(player, refundMsg); @@ -131,7 +133,7 @@ public final class EconomyHelper { * @param destination

The destination portal

* @return

The cost of using the portal

*/ - public static int getUseCost(Player player, Portal source, Portal destination) { + public static int getUseCost(@NotNull Player player, @NotNull Portal source, @Nullable Portal destination) { EconomyConfig config = Stargate.getEconomyConfig(); //No payment required if (!config.useEconomy() || source.getOptions().isFree()) { @@ -161,7 +163,7 @@ public final class EconomyHelper { * @param cost

The cost of the transaction

* @return

True if the player was charged successfully

*/ - public static boolean chargePlayerIfNecessary(Player player, UUID target, int cost) { + public static boolean chargePlayerIfNecessary(@NotNull Player player, @NotNull UUID target, int cost) { if (skipPayment(cost)) { return true; } @@ -176,7 +178,7 @@ public final class EconomyHelper { * @param amount

The amount to charge

* @return

True if the payment succeeded, or if no payment was necessary

*/ - private static boolean chargePlayer(Player player, double amount) { + private static boolean chargePlayer(@NotNull Player player, double amount) { Economy economy = Stargate.getEconomyConfig().getEconomy(); if (Stargate.getEconomyConfig().isEconomyEnabled() && economy != null) { if (!economy.has(player, amount)) { @@ -198,7 +200,7 @@ public final class EconomyHelper { * @param cost

The cost to transfer

*/ @SuppressWarnings("deprecation") - private static void transferFees(Economy economy, int cost) { + private static void transferFees(@NotNull Economy economy, int cost) { String accountName = Stargate.getEconomyConfig().getTaxAccount(); if (accountName == null || accountName.isEmpty()) { return; @@ -220,7 +222,7 @@ public final class EconomyHelper { * @param cost

The cost of the transaction

* @return

True if the player was charged successfully

*/ - public static boolean chargePlayerIfNecessary(Player player, int cost) { + public static boolean chargePlayerIfNecessary(@NotNull Player player, int cost) { if (skipPayment(cost)) { return true; } @@ -228,8 +230,9 @@ public final class EconomyHelper { boolean charged = chargePlayer(player, cost); // Transfer the charged amount to the tax account - if (charged) { - transferFees(Stargate.getEconomyConfig().getEconomy(), cost); + Economy economy = Stargate.getEconomyConfig().getEconomy(); + if (charged && economy != null) { + transferFees(economy, cost); } return charged; @@ -253,9 +256,10 @@ public final class EconomyHelper { * @param amount

The amount to charge

* @return

True if the payment succeeded, or if no payment was necessary

*/ - private static boolean chargePlayer(Player player, UUID target, double amount) { + private static boolean chargePlayer(@NotNull Player player, @NotNull UUID target, double amount) { Economy economy = Stargate.getEconomyConfig().getEconomy(); - if (Stargate.getEconomyConfig().isEconomyEnabled() && player.getUniqueId().compareTo(target) != 0 && economy != null) { + if (Stargate.getEconomyConfig().isEconomyEnabled() && player.getUniqueId().compareTo(target) != 0 && + economy != null) { if (!economy.has(player, amount)) { return false; } @@ -274,7 +278,8 @@ public final class EconomyHelper { * @param cost

The cost for a given interaction

* @return

The same string with cost and portal variables replaced

*/ - private static String replacePlaceholders(String message, String portalName, int cost) { + @NotNull + private static String replacePlaceholders(@NotNull String message, @NotNull String portalName, int cost) { return StringFormatter.replacePlaceholders(message, new String[]{"%cost%", "%portal%"}, new String[]{Stargate.getEconomyConfig().format(cost), portalName}); } diff --git a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java index 04ed19f..72adf56 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EntityHelper.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.utility; import org.bukkit.entity.Entity; +import org.jetbrains.annotations.NotNull; /** * This helper class helps with entity properties not immediately available @@ -21,7 +22,7 @@ public final class EntityHelper { * @param entity

The entity to get max size for

* @return

The max size of the entity

*/ - public static int getEntityMaxSizeInt(Entity entity) { + public static int getEntityMaxSizeInt(@NotNull Entity entity) { return (int) Math.ceil((float) getEntityMaxSize(entity)); } @@ -31,7 +32,7 @@ public final class EntityHelper { * @param entity

The entity to get max size for

* @return

The max size of the entity

*/ - public static double getEntityMaxSize(Entity entity) { + public static double getEntityMaxSize(@NotNull Entity entity) { return Math.max(entity.getBoundingBox().getWidthX(), entity.getBoundingBox().getWidthZ()); } diff --git a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java index be88ef3..77385c6 100644 --- a/src/main/java/net/knarcraft/stargate/utility/FileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/FileHelper.java @@ -1,12 +1,18 @@ package net.knarcraft.stargate.utility; +import org.jetbrains.annotations.NotNull; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -public class FileHelper { +public final class FileHelper { + + private FileHelper() { + + } /** * Converts the stream directly into a string, includes the newline character @@ -15,7 +21,8 @@ public class FileHelper { * @return

A String of the file read

* @throws IOException

If unable to read the stream

*/ - public static String readStreamToString(InputStream stream) throws IOException { + @NotNull + public static String readStreamToString(@NotNull InputStream stream) throws IOException { InputStreamReader inputStreamReader = new InputStreamReader(stream, StandardCharsets.UTF_8); BufferedReader reader = new BufferedReader(inputStreamReader); String line = reader.readLine(); diff --git a/src/main/java/net/knarcraft/stargate/utility/GateReader.java b/src/main/java/net/knarcraft/stargate/utility/GateReader.java index 4903fd0..d8804fb 100644 --- a/src/main/java/net/knarcraft/stargate/utility/GateReader.java +++ b/src/main/java/net/knarcraft/stargate/utility/GateReader.java @@ -5,6 +5,7 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.Tag; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -31,12 +32,12 @@ public final class GateReader { * @param config

The map of config values to store to

* @return

The column count/width of the loaded gate

*/ - public static int readGateFile(Scanner scanner, Map characterMaterialMap, - Map> materialTagMap, String fileName, - List> design, Map config) { + public static int readGateFile(@NotNull Scanner scanner, @NotNull Map characterMaterialMap, + @NotNull Map> materialTagMap, @NotNull String fileName, + @NotNull List> design, Map config) { boolean designing = false; int columns = 0; - try { + try (scanner) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); @@ -59,10 +60,6 @@ public final class GateReader { } catch (Exception exception) { Stargate.logSevere(String.format("Could not load Gate %s - %s", fileName, exception.getMessage())); return -1; - } finally { - if (scanner != null) { - scanner.close(); - } } return columns; } @@ -81,9 +78,10 @@ public final class GateReader { * @param design

The two-dimensional list to store the loaded design to

* @return

The new max columns value of the design

*/ - private static int readGateDesignLine(String line, int maxColumns, Map characterMaterialMap, - Map> materialTagMap, - String fileName, List> design) { + private static int readGateDesignLine(@NotNull String line, int maxColumns, + @NotNull Map characterMaterialMap, + @NotNull Map> materialTagMap, + @NotNull String fileName, @NotNull List> design) { List row = new ArrayList<>(); //Update the max columns number if this line has more columns @@ -116,9 +114,9 @@ public final class GateReader { * @param config

The config value map to store to

* @throws Exception

If an invalid material is encountered

*/ - private static void readGateConfigValue(String line, Map characterMaterialMap, - Map> materialTagMap, - Map config) throws Exception { + private static void readGateConfigValue(@NotNull String line, @NotNull Map characterMaterialMap, + @NotNull Map> materialTagMap, + @NotNull Map config) throws Exception { String[] split = line.split("="); String key = split[0].trim(); String value = split[1].trim(); @@ -158,12 +156,13 @@ public final class GateReader { * @param key

The config key to read

* @return

The read value, or -1 if it could not be read

*/ - public static int readGateConfig(Map config, String fileName, String key) { + public static int readGateConfig(@NotNull Map config, @NotNull String fileName, + @NotNull String key) { if (config.containsKey(key)) { try { return Integer.parseInt(config.get(key)); - } catch (NumberFormatException ex) { - Stargate.logWarning(String.format("%s reading %s: %s is not numeric", ex.getClass().getName(), + } catch (NumberFormatException exception) { + Stargate.logWarning(String.format("%s reading %s: %s is not numeric", exception.getClass().getName(), fileName, key)); } } @@ -180,8 +179,9 @@ public final class GateReader { * @param defaultMaterial

The default material to use, in case the config is invalid

* @return

The material specified in the config, or the default material if it could not be read

*/ - public static Material readGateConfig(Map config, String fileName, String key, - Material defaultMaterial) { + @NotNull + public static Material readGateConfig(@NotNull Map config, @NotNull String fileName, + @NotNull String key, @NotNull Material defaultMaterial) { if (config.containsKey(key)) { Material material = Material.matchMaterial(config.get(key)); if (material != null) { @@ -203,7 +203,8 @@ public final class GateReader { * @param columns

The largest amount of columns in the design

* @return

A matrix containing the gate's layout

*/ - public static Character[][] generateLayoutMatrix(List> design, int columns) { + @NotNull + public static Character[][] generateLayoutMatrix(@NotNull List> design, int columns) { Character[][] layout = new Character[design.size()][columns]; for (int lineIndex = 0; lineIndex < design.size(); lineIndex++) { List row = design.get(lineIndex); diff --git a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java index 1d00239..466e844 100644 --- a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.utility; import org.bukkit.Material; import org.bukkit.Tag; +import org.jetbrains.annotations.NotNull; /** * This class helps decide properties of materials not already present in the Spigot API @@ -18,7 +19,7 @@ public final class MaterialHelper { * @param material

The material to check

* @return

True if the material is a wall coral

*/ - public static boolean isWallCoral(Material material) { + public static boolean isWallCoral(@NotNull Material material) { //Unfortunately, there is no tag for dead wall corals, so they need to be checked manually return Tag.WALL_CORALS.isTagged(material) || material.equals(Material.DEAD_BRAIN_CORAL_WALL_FAN) || @@ -34,7 +35,7 @@ public final class MaterialHelper { * @param material

The material to check

* @return

True if the material is a container

*/ - public static boolean isContainer(Material material) { + public static boolean isContainer(@NotNull Material material) { return Tag.SHULKER_BOXES.isTagged(material) || material == Material.CHEST || material == Material.TRAPPED_CHEST || material == Material.ENDER_CHEST; } @@ -45,7 +46,7 @@ public final class MaterialHelper { * @param material

The material to check

* @return

True if the material can be used as a button

*/ - public static boolean isButtonCompatible(Material material) { + public static boolean isButtonCompatible(@NotNull Material material) { return Tag.BUTTONS.isTagged(material) || isWallCoral(material) || isContainer(material); } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index f87dc41..2416e98 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -7,6 +7,8 @@ import net.knarcraft.stargate.portal.property.PortalOption; import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import static net.knarcraft.stargate.Stargate.getMaxNameNetworkLength; @@ -25,7 +27,7 @@ public final class PermissionHelper { * @param player

The player opening the portal

* @param portal

The portal to open

*/ - public static void openPortal(Player player, Portal portal) { + public static void openPortal(@NotNull Player player, @NotNull Portal portal) { Portal destination = portal.getPortalActivator().getDestination(); //For an always open portal, no action is necessary @@ -89,7 +91,7 @@ public final class PermissionHelper { * @param deny

Whether the player's access has already been denied by a previous check

* @return

False if the player should be allowed through the portal

*/ - public static boolean portalAccessDenied(Player player, Portal portal, boolean deny) { + public static boolean portalAccessDenied(@NotNull Player player, @NotNull Portal portal, boolean deny) { StargateAccessEvent event = new StargateAccessEvent(player, portal, deny); Stargate.getInstance().getServer().getPluginManager().callEvent(event); return event.getDeny(); @@ -103,7 +105,8 @@ public final class PermissionHelper { * @param destination

The portal the user wants to exit from

* @return

False if the user is allowed to access the portal

*/ - public static boolean cannotAccessPortal(Player player, Portal entrancePortal, Portal destination) { + public static boolean cannotAccessPortal(@NotNull Player player, @NotNull Portal entrancePortal, + @Nullable Portal destination) { boolean deny = false; if (entrancePortal.getOptions().isBungee()) { @@ -116,10 +119,17 @@ public final class PermissionHelper { //If the player does not have access to the network, deny Stargate.debug("cannotAccessPortal", "Cannot access network"); deny = true; - } else if (PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { - //If the player does not have access to the portal's world, deny - Stargate.debug("cannotAccessPortal", "Cannot access world"); - deny = true; + } else { + if (destination == null) { + //If there is no destination, deny + Stargate.debug("cannotAccessPortal", "Portal has no destination"); + deny = true; + } else if (destination.getWorld() != null && + PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { + //If the player does not have access to the portal's world, deny + Stargate.debug("cannotAccessPortal", "Cannot access world"); + deny = true; + } } //Allow other plugins to override whether the player can access the portal return portalAccessDenied(player, entrancePortal, deny); @@ -134,7 +144,7 @@ public final class PermissionHelper { * @param permission

The permission to check

* @return

True if the player has the permission

*/ - public static boolean hasPermission(Player player, String permission) { + public static boolean hasPermission(@NotNull Player player, @NotNull String permission) { if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { Stargate.debug("hasPerm::Permission(" + player.getName() + ")", permission + " => " + player.hasPermission(permission)); @@ -152,7 +162,7 @@ public final class PermissionHelper { * @param permission

The permission to check

* @return

True if the player has the permission implicitly or explicitly

*/ - public static boolean hasPermissionImplicit(Player player, String permission) { + public static boolean hasPermissionImplicit(@NotNull Player player, @NotNull String permission) { if (!player.isPermissionSet(permission)) { if (Stargate.getStargateConfig().isPermissionDebuggingEnabled()) { Stargate.debug("hasPermissionImplicit::Permission", permission + " => implicitly true"); @@ -173,7 +183,7 @@ public final class PermissionHelper { * @param world

The world the player is trying to access

* @return

False if the player should be allowed to access the world

*/ - public static boolean cannotAccessWorld(Player player, String world) { + public static boolean cannotAccessWorld(@NotNull Player player, @NotNull String world) { //The player can access all worlds if (hasPermission(player, "stargate.world")) { //Check if the world permission has been explicitly denied @@ -190,7 +200,7 @@ public final class PermissionHelper { * @param network

The network to check

* @return

True if the player is denied from accessing the network

*/ - public static boolean cannotAccessNetwork(Player player, String network) { + public static boolean cannotAccessNetwork(@NotNull Player player, @NotNull String network) { //The player can access all networks if (hasPermission(player, "stargate.network")) { //Check if the world permission has been explicitly denied @@ -215,7 +225,7 @@ public final class PermissionHelper { * @param server

The server the player is trying to connect to

* @return

True if the player is allowed to access the given server

*/ - public static boolean canAccessServer(Player player, String server) { + public static boolean canAccessServer(@NotNull Player player, @NotNull String server) { //The player can access all servers if (hasPermission(player, "stargate.server")) { //Check if the server permission has been explicitly denied @@ -233,7 +243,7 @@ public final class PermissionHelper { * @param dest

The portal the player wants to teleport to

* @return

True if the player can travel for free

*/ - public static boolean isFree(Player player, Portal src, Portal dest) { + public static boolean isFree(@NotNull Player player, @NotNull Portal src, @Nullable Portal dest) { //This portal is free if (src.getOptions().isFree()) { return true; @@ -255,7 +265,7 @@ public final class PermissionHelper { * @param portal

The portal to check

* @return

True if the given player can see the given portal

*/ - public static boolean canSeePortal(Player player, Portal portal) { + public static boolean canSeePortal(@NotNull Player player, @NotNull Portal portal) { //The portal is not hidden if (!portal.getOptions().isHidden()) { return true; @@ -275,7 +285,7 @@ public final class PermissionHelper { * @param portal

The private portal used

* @return

True if the player is allowed to use the portal

*/ - public static boolean canUsePrivatePortal(Player player, Portal portal) { + public static boolean canUsePrivatePortal(@NotNull Player player, @NotNull Portal portal) { //Check if the player is the owner of the gate if (portal.isOwner(player)) { return true; @@ -291,7 +301,7 @@ public final class PermissionHelper { * @param option

The option the player is trying to use

* @return

True if the player is allowed to create a portal with the given option

*/ - public static boolean canUseOption(Player player, PortalOption option) { + public static boolean canUseOption(@NotNull Player player, @NotNull PortalOption option) { return hasPermission(player, option.getPermissionString()); } @@ -302,7 +312,7 @@ public final class PermissionHelper { * @param network

The network the player is trying to create a gate on

* @return

True if the player is allowed to create the new gate

*/ - public static boolean canCreateNetworkGate(Player player, String network) { + public static boolean canCreateNetworkGate(@NotNull Player player, @NotNull String network) { //Check if the player is allowed to create a portal on any network if (hasPermission(player, "stargate.create.network")) { //Check if the network has been explicitly denied @@ -318,7 +328,7 @@ public final class PermissionHelper { * @param player

The player trying to create the new gate

* @return

True if the player is allowed

*/ - public static boolean canCreatePersonalPortal(Player player) { + public static boolean canCreatePersonalPortal(@NotNull Player player) { return hasPermission(player, "stargate.create.personal"); } @@ -329,7 +339,7 @@ public final class PermissionHelper { * @param gate

The gate type of the new portal

* @return

True if the player is allowed to create a portal with the given gate layout

*/ - public static boolean canCreatePortal(Player player, String gate) { + public static boolean canCreatePortal(@NotNull Player player, @NotNull String gate) { //Check if the player is allowed to create all gates if (hasPermission(player, "stargate.create.gate")) { //Check if the gate type has been explicitly denied @@ -346,7 +356,7 @@ public final class PermissionHelper { * @param portal

The portal to destroy

* @return

True if the player is allowed to destroy the portal

*/ - public static boolean canDestroyPortal(Player player, Portal portal) { + public static boolean canDestroyPortal(@NotNull Player player, @NotNull Portal portal) { String network = portal.getCleanNetwork(); //Use a special check for bungee portals @@ -376,7 +386,8 @@ public final class PermissionHelper { * @param event

The move event causing the teleportation

* @return

True if the player cannot teleport. False otherwise

*/ - public static boolean playerCannotTeleport(Portal entrancePortal, Portal destination, Player player, PlayerMoveEvent event) { + public static boolean playerCannotTeleport(@Nullable Portal entrancePortal, @Nullable Portal destination, + @NotNull Player player, @Nullable PlayerMoveEvent event) { //No portal or not open if (entrancePortal == null || !entrancePortal.isOpen()) { return true; @@ -392,12 +403,13 @@ public final class PermissionHelper { } //No destination - if (!entrancePortal.getOptions().isBungee() && destination == null) { + boolean isBungee = entrancePortal.getOptions().isBungee(); + if (!isBungee && destination == null) { return true; } //Player cannot access portal - if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { + if (!PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { if (!entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); } diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 6ba84e7..33ca2d5 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -20,6 +20,8 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; import org.bukkit.block.data.Waterlogged; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.BufferedWriter; import java.io.File; @@ -43,7 +45,7 @@ public final class PortalFileHelper { * * @param world

The world to save portals for

*/ - public static void saveAllPortals(World world) { + public static void saveAllPortals(@NotNull World world) { Stargate.getStargateConfig().addManagedWorld(world.getName()); String saveFileLocation = Stargate.getPortalFolder() + "/" + world.getName() + ".db"; @@ -52,6 +54,11 @@ public final class PortalFileHelper { for (Portal portal : PortalRegistry.getAllPortals()) { //Skip portals in other worlds + if (portal.getWorld() == null) { + Stargate.logSevere(String.format("Could not save portal %s because its world is null", + portal.getName())); + continue; + } String worldName = portal.getWorld().getName(); if (!worldName.equalsIgnoreCase(world.getName())) { continue; @@ -61,8 +68,8 @@ public final class PortalFileHelper { } bufferedWriter.close(); - } catch (Exception e) { - Stargate.logSevere(String.format("Exception while writing stargates to %s: %s", saveFileLocation, e)); + } catch (Exception exception) { + Stargate.logSevere(String.format("Exception while writing stargates to %s: %s", saveFileLocation, exception)); } } @@ -73,13 +80,13 @@ public final class PortalFileHelper { * @param portal

The portal to save

* @throws IOException

If unable to write to the buffered writer

*/ - private static void savePortal(BufferedWriter bufferedWriter, Portal portal) throws IOException { + private static void savePortal(@NotNull BufferedWriter bufferedWriter, @NotNull Portal portal) throws IOException { StringBuilder builder = new StringBuilder(); BlockLocation button = portal.getStructure().getButton(); //WARNING: Because of the primitive save format, any change in order will break everything! builder.append(portal.getName()).append(':'); - builder.append(portal.getSignLocation().toString()).append(':'); + builder.append(portal.getSignLocation()).append(':'); builder.append((button != null) ? button.toString() : "").append(':'); //Add removes config values to keep indices consistent @@ -87,7 +94,7 @@ public final class PortalFileHelper { builder.append(0).append(':'); builder.append(portal.getYaw()).append(':'); - builder.append(portal.getTopLeft().toString()).append(':'); + builder.append(portal.getTopLeft()).append(':'); builder.append(portal.getGate().getFilename()).append(':'); //Only save the destination name if the gate is fixed as it doesn't matter otherwise @@ -111,13 +118,17 @@ public final class PortalFileHelper { * @param portal

The portal to save

* @param builder

The string builder to append to

*/ - private static void savePortalOptions(Portal portal, StringBuilder builder) { + private static void savePortalOptions(@NotNull Portal portal, @NotNull StringBuilder builder) { PortalOptions options = portal.getOptions(); builder.append(':'); builder.append(options.isHidden()).append(':'); builder.append(options.isAlwaysOn()).append(':'); builder.append(options.isPrivate()).append(':'); - builder.append(portal.getWorld().getName()).append(':'); + if (portal.getWorld() != null) { + builder.append(portal.getWorld().getName()).append(':'); + } else { + builder.append(':'); + } builder.append(options.isFree()).append(':'); builder.append(options.isBackwards()).append(':'); builder.append(options.isShown()).append(':'); @@ -134,7 +145,7 @@ public final class PortalFileHelper { * @param world

The world to load portals for

* @return

True if portals could be loaded

*/ - public static boolean loadAllPortals(World world) { + public static boolean loadAllPortals(@NotNull World world) { String location = Stargate.getPortalFolder(); File database = new File(location, world.getName() + ".db"); @@ -154,7 +165,7 @@ public final class PortalFileHelper { * @param database

The database file containing the portals

* @return

True if the portals were loaded successfully

*/ - private static boolean loadPortals(World world, File database) { + private static boolean loadPortals(@NotNull World world, @NotNull File database) { int lineIndex = 0; try { Scanner scanner = new Scanner(database); @@ -185,7 +196,7 @@ public final class PortalFileHelper { * @param world

The world for which portals are currently being read

* @return

True if the read portal has changed and the world's database needs to be saved

*/ - private static boolean readPortalLine(Scanner scanner, int lineIndex, World world) { + private static boolean readPortalLine(@NotNull Scanner scanner, int lineIndex, @NotNull World world) { String line = scanner.nextLine().trim(); //Ignore empty and comment lines @@ -213,7 +224,7 @@ public final class PortalFileHelper { * @param world

The world portals have been loaded for

* @param needsToSaveDatabase

Whether the portal database's file needs to be updated

*/ - private static void doPostLoadTasks(World world, boolean needsToSaveDatabase) { + private static void doPostLoadTasks(@NotNull World world, boolean needsToSaveDatabase) { //Open any always-on portals. Do this here as it should be more efficient than in the loop. PortalHandler.verifyAllPortals(); int portalCount = PortalRegistry.getAllPortals().size(); @@ -245,7 +256,7 @@ public final class PortalFileHelper { * @param lineIndex

The line index to report in case the user needs to fix an error

* @return

True if the portal's data has changed and its database needs to be updated

*/ - private static boolean loadPortal(String[] portalData, World world, int lineIndex) { + private static boolean loadPortal(@NotNull String[] portalData, @NotNull World world, int lineIndex) { //Load min. required portal data String name = portalData[0]; BlockLocation button = (portalData[2].length() > 0) ? new BlockLocation(world, portalData[2]) : null; @@ -289,17 +300,21 @@ public final class PortalFileHelper { * * @param portal

The portal update the button of

*/ - private static void updatePortalButton(Portal portal) { + private static void updatePortalButton(@NotNull Portal portal) { BlockLocation buttonLocation = getButtonLocation(portal); + if (buttonLocation == null) { + return; + } + if (portal.getOptions().isAlwaysOn()) { - //Clear button if not already air or water + //Clear button if it exists if (MaterialHelper.isButtonCompatible(buttonLocation.getType())) { Material newMaterial = decideRemovalMaterial(buttonLocation, portal); Stargate.addBlockChangeRequest(new BlockChangeRequest(buttonLocation, newMaterial, null)); } } else { - //Replace button if the material does not match - if (buttonLocation.getType() != portal.getGate().getPortalButton()) { + //Replace button if the material is not a button + if (!MaterialHelper.isButtonCompatible(buttonLocation.getType())) { generatePortalButton(portal, DirectionHelper.getBlockFaceFromYaw(portal.getYaw())); } } @@ -312,7 +327,8 @@ public final class PortalFileHelper { * @param portal

The portal the button/sign belongs to

* @return

The material to use for removing the button/sign

*/ - public static Material decideRemovalMaterial(BlockLocation location, Portal portal) { + @NotNull + public static Material decideRemovalMaterial(@NotNull BlockLocation location, @NotNull Portal portal) { //Get the blocks to each side of the location Location leftLocation = location.getRelativeLocation(-1, 0, 0, portal.getYaw()); Location rightLocation = location.getRelativeLocation(1, 0, 0, portal.getYaw()); @@ -333,7 +349,7 @@ public final class PortalFileHelper { * @param location

The location to check

* @return

True if the location is underwater

*/ - private static boolean isUnderwater(Location location) { + private static boolean isUnderwater(@NotNull Location location) { BlockData blockData = location.getBlock().getBlockData(); return blockData.getMaterial() == Material.WATER || (blockData instanceof Waterlogged waterlogged && waterlogged.isWaterlogged()); @@ -348,7 +364,7 @@ public final class PortalFileHelper { * @param portal

The portal to update the button vector for

* @return

True if the calculated button location is not the same as the one in the portal file

*/ - private static boolean updateButtonVector(Portal portal) { + private static boolean updateButtonVector(@NotNull Portal portal) { for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) { BlockLocation controlLocation = portal.getLocation().getTopLeft().getRelativeLocation(control, portal.getYaw()); @@ -374,10 +390,15 @@ public final class PortalFileHelper { * @param portal

The portal to generate button for

* @param buttonFacing

The direction the button should be facing

*/ - public static void generatePortalButton(Portal portal, BlockFace buttonFacing) { + public static void generatePortalButton(@NotNull Portal portal, @NotNull BlockFace buttonFacing) { //Go one block outwards to find the button's location rather than the control block's location BlockLocation button = getButtonLocation(portal); + // If the button location is null here, it is assumed that the button generation wasn't necessary + if (button == null) { + return; + } + Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); buttonData.setFacing(buttonFacing); button.getBlock().setBlockData(buttonData); @@ -390,11 +411,16 @@ public final class PortalFileHelper { * @param portal

The portal to find the button for

* @return

The location of the portal's button

*/ - private static BlockLocation getButtonLocation(Portal portal) { + @Nullable + private static BlockLocation getButtonLocation(@NotNull Portal portal) { BlockLocation topLeft = portal.getTopLeft(); RelativeBlockVector buttonVector = portal.getLocation().getButtonVector(); - return topLeft.getRelativeLocation(buttonVector.addToVector(RelativeBlockVector.Property.OUT, 1), - portal.getYaw()); + + if (buttonVector == null) { + return null; + } + + return topLeft.getRelativeLocation(buttonVector.addOut(1), portal.getYaw()); } } diff --git a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java index af6f790..566cc46 100644 --- a/src/main/java/net/knarcraft/stargate/utility/SignHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/SignHelper.java @@ -3,6 +3,8 @@ package net.knarcraft.stargate.utility; import org.bukkit.DyeColor; import org.bukkit.block.Sign; import org.bukkit.block.sign.Side; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * A helper class for dealing with signs @@ -21,7 +23,8 @@ public final class SignHelper { * @param sign

The sign to check

* @return

The dye currently applied to the sign

*/ - public static DyeColor getDye(Sign sign) { + @Nullable + public static DyeColor getDye(@NotNull Sign sign) { if (HAS_SIGN_SIDES) { return sign.getSide(Side.FRONT).getColor(); } else { @@ -38,7 +41,7 @@ public final class SignHelper { * @param line

The line to set

* @param text

The text to set

*/ - public static void setSignLine(Sign sign, int line, String text) { + public static void setSignLine(@NotNull Sign sign, int line, @NotNull String text) { if (HAS_SIGN_SIDES) { sign.getSide(Side.FRONT).setLine(line, text); } else { diff --git a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java index e3d7747..e748119 100644 --- a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java @@ -10,6 +10,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -31,7 +32,7 @@ public final class TeleportHelper { * @param player

The player trying to teleport

* @return

False if the player has leashed any creatures that cannot go through the portal

*/ - public static boolean noLeashedCreaturesPreventTeleportation(Player player) { + public static boolean noLeashedCreaturesPreventTeleportation(@NotNull Player player) { //Find any nearby leashed entities to teleport with the player List nearbyCreatures = getLeashedCreatures(player); @@ -56,7 +57,8 @@ public final class TeleportHelper { * @param player

The player to check

* @return

A list of all creatures the player is holding in a leash (lead)

*/ - public static List getLeashedCreatures(Player player) { + @NotNull + public static List getLeashedCreatures(@NotNull Player player) { List leashedCreatures = new ArrayList<>(); //Find any nearby leashed entities to teleport with the player List nearbyEntities = player.getNearbyEntities(15, 15, 15); @@ -80,8 +82,8 @@ public final class TeleportHelper { * @param exitDirection

The direction of any passengers exiting the stargate

* @param newVelocity

The new velocity of the teleported passenger

*/ - public static void teleportAndAddPassenger(Entity targetVehicle, Entity passenger, Vector exitDirection, - Vector newVelocity) { + public static void teleportAndAddPassenger(@NotNull Entity targetVehicle, @NotNull Entity passenger, + @NotNull Vector exitDirection, @NotNull Vector newVelocity) { Location passengerExit = targetVehicle.getLocation().clone().setDirection(exitDirection); if (!passenger.teleport(passengerExit)) { Stargate.debug("TeleportHelper::handleVehiclePassengers", "Failed to teleport passenger" + @@ -112,8 +114,9 @@ public final class TeleportHelper { * @param exitRotation

The rotation of any passengers exiting the stargate

* @param newVelocity

The new velocity of the teleported passengers

*/ - public static void handleEntityPassengers(List passengers, Entity entity, Portal origin, Portal target, - Vector exitRotation, Vector newVelocity) { + public static void handleEntityPassengers(@NotNull List passengers, @NotNull Entity entity, + @NotNull Portal origin, @NotNull Portal target, + @NotNull Vector exitRotation, @NotNull Vector newVelocity) { for (Entity passenger : passengers) { List passengerPassengers = passenger.getPassengers(); if (!passengerPassengers.isEmpty()) { @@ -144,7 +147,7 @@ public final class TeleportHelper { * @param origin

The portal the player is teleporting from

* @param target

The portal the player is teleporting to

*/ - public static void teleportLeashedCreatures(Player player, Portal origin, Portal target) { + public static void teleportLeashedCreatures(@NotNull Player player, @NotNull Portal origin, @NotNull Portal target) { //If this feature is disabled, just return if (!Stargate.getGateConfig().handleLeashedCreatures()) { return; @@ -171,7 +174,7 @@ public final class TeleportHelper { * @param entities

The list of entities to check

* @return

True if at least one entity is not a player

*/ - public static boolean containsNonPlayer(List entities) { + public static boolean containsNonPlayer(@NotNull List entities) { for (Entity entity : entities) { if (!(entity instanceof Player) || containsNonPlayer(entity.getPassengers())) { return true; @@ -186,7 +189,7 @@ public final class TeleportHelper { * @param entities

The list of entities to check

* @return

True if at least one player is present among the passengers

*/ - public static boolean containsPlayer(List entities) { + public static boolean containsPlayer(@NotNull List entities) { for (Entity entity : entities) { if (entity instanceof Player || containsPlayer(entity.getPassengers())) { return true; @@ -201,7 +204,8 @@ public final class TeleportHelper { * @param entities

The entities to check for players

* @return

The found players

*/ - public static List getPlayers(List entities) { + @NotNull + public static List getPlayers(@NotNull List entities) { List players = new ArrayList<>(5); for (Entity entity : entities) { if (entity instanceof Player) { @@ -220,7 +224,8 @@ public final class TeleportHelper { * @param destinationPortal

The portal the player is to exit from

* @return

True if the player is allowed to teleport and is able to pay necessary fees

*/ - public static boolean playerCanTeleport(Player player, Portal entrancePortal, Portal destinationPortal) { + public static boolean playerCanTeleport(@NotNull Player player, @NotNull Portal entrancePortal, + @NotNull Portal destinationPortal) { //Make sure the user can access the portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { if (!entrancePortal.getOptions().isSilent()) { diff --git a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java index 4cb4472..0e93892 100644 --- a/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/UUIDMigrationHelper.java @@ -7,6 +7,7 @@ import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.portal.property.PortalOwner; import org.bukkit.OfflinePlayer; import org.bukkit.World; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.HashMap; @@ -35,7 +36,7 @@ public final class UUIDMigrationHelper { * * @param player

The player to migrate

*/ - public static void migrateUUID(OfflinePlayer player) { + public static void migrateUUID(@NotNull OfflinePlayer player) { Map> playersToMigrate = getPlayersToMigrate(); String playerName = player.getName(); @@ -53,7 +54,7 @@ public final class UUIDMigrationHelper { migratePortalsToUUID(portalsOwned, player.getUniqueId()); - //Remove the player to prevent the migration to happen every time the player joins + //Remove the player to prevent the migration from happening every time the player joins playersToMigrate.remove(playerName); } @@ -63,7 +64,7 @@ public final class UUIDMigrationHelper { * @param portals

The portals to migrate

* @param uniqueId

The unique ID of the portals' owner

*/ - private static void migratePortalsToUUID(List portals, UUID uniqueId) { + private static void migratePortalsToUUID(@NotNull List portals, @NotNull UUID uniqueId) { Set worldsToSave = new HashSet<>(); //Get the real portal from the copy and set UUID @@ -86,6 +87,7 @@ public final class UUIDMigrationHelper { * * @return

The player names to migrate

*/ + @NotNull private static Map> getPlayersToMigrate() { //Make sure to only go through portals once if (playerNamesToMigrate != null) { diff --git a/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java index f75aefe..2af9dcb 100644 --- a/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java +++ b/src/test/java/net/knarcraft/stargate/RelativeBlockVectorTest.java @@ -11,9 +11,9 @@ public class RelativeBlockVectorTest { @Test public void getTest() { RelativeBlockVector relativeBlockVector = new RelativeBlockVector(56, 44, 23); - assertEquals(56, relativeBlockVector.getRight()); - assertEquals(44, relativeBlockVector.getDown()); - assertEquals(23, relativeBlockVector.getOut()); + assertEquals(56, relativeBlockVector.right()); + assertEquals(44, relativeBlockVector.down()); + assertEquals(23, relativeBlockVector.out()); } @Test diff --git a/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java b/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java index 8259b37..076f55b 100644 --- a/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java +++ b/src/test/java/net/knarcraft/stargate/container/RelativeBlockVectorTest.java @@ -15,13 +15,13 @@ public class RelativeBlockVectorTest { for (int i = 0; i < 1000; i++) { int randomValue = getRandomNumber(); - RelativeBlockVector newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.RIGHT, randomValue); + RelativeBlockVector newVector = relativeBlockVector.addRight(randomValue); Assertions.assertEquals(new RelativeBlockVector(right + randomValue, down, out), newVector); - newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.OUT, randomValue); + newVector = relativeBlockVector.addOut(randomValue); Assertions.assertEquals(new RelativeBlockVector(right, down, out + randomValue), newVector); - newVector = relativeBlockVector.addToVector(RelativeBlockVector.Property.DOWN, randomValue); + newVector = relativeBlockVector.addDown(randomValue); Assertions.assertEquals(new RelativeBlockVector(right, down + randomValue, out), newVector); } } diff --git a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java index 58bb24a..e966521 100644 --- a/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java +++ b/src/test/java/net/knarcraft/stargate/portal/GateLayoutTest.java @@ -5,6 +5,7 @@ import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.WorldMock; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.portal.property.gate.GateLayout; import org.bukkit.Material; @@ -28,7 +29,12 @@ public class GateLayoutTest { server.addWorld(new WorldMock(Material.DIRT, 5)); System.setProperty("bstats.relocatecheck", "false"); MockBukkit.load(Stargate.class); - layout = GateHandler.getGateByName("nethergate.gate").getLayout(); + Gate gate = GateHandler.getGateByName("nethergate.gate"); + if (gate != null) { + layout = gate.getLayout(); + } else { + throw new IllegalStateException("Could not set up tests, because nethergate.gate is unavailable"); + } } @AfterAll From a9e5855194f73fe4cb4387d343d3c9216babdbae Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 20 Feb 2024 15:15:52 +0100 Subject: [PATCH 2/8] Improves button and material customization Allows specifying a comma-separated list of materials and tags for a portal's button, open-material, closed-material and border blocks. A random value is used if more than one material is available.0 Uses the supplied button if any, instead of enforcing the specified button material. Always protects the button against block breaking. Fixes an incorrect permission result in the previous commit, which caused players stargate access to be inverted. --- .../material/BukkitMaterialSpecifier.java | 36 ++++++ .../config/material/BukkitTagSpecifier.java | 35 ++++++ .../config/material/MaterialSpecifier.java | 29 +++++ .../stargate/listener/BlockEventListener.java | 8 ++ .../listener/PlayerEventListener.java | 3 +- .../stargate/portal/PortalActivator.java | 4 +- .../stargate/portal/PortalCreator.java | 9 +- .../stargate/portal/PortalHandler.java | 6 +- .../stargate/portal/PortalOpener.java | 19 ++- .../stargate/portal/property/gate/Gate.java | 117 +++++++----------- .../portal/property/gate/GateHandler.java | 82 ++++++------ .../stargate/utility/GateReader.java | 59 ++++----- .../stargate/utility/ListHelper.java | 28 +++++ .../stargate/utility/MaterialHelper.java | 87 +++++++++++++ .../stargate/utility/PermissionHelper.java | 4 +- .../stargate/utility/PortalFileHelper.java | 13 +- 16 files changed, 385 insertions(+), 154 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/config/material/BukkitMaterialSpecifier.java create mode 100644 src/main/java/net/knarcraft/stargate/config/material/BukkitTagSpecifier.java create mode 100644 src/main/java/net/knarcraft/stargate/config/material/MaterialSpecifier.java create mode 100644 src/main/java/net/knarcraft/stargate/utility/ListHelper.java diff --git a/src/main/java/net/knarcraft/stargate/config/material/BukkitMaterialSpecifier.java b/src/main/java/net/knarcraft/stargate/config/material/BukkitMaterialSpecifier.java new file mode 100644 index 0000000..a761d5c --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/material/BukkitMaterialSpecifier.java @@ -0,0 +1,36 @@ +package net.knarcraft.stargate.config.material; + +import org.bukkit.Material; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * A specifier for a Bukkit material + */ +public class BukkitMaterialSpecifier implements MaterialSpecifier { + + private final Material material; + + /** + * Instantiates a new material specifier + * + * @param material

The material to specify

+ */ + public BukkitMaterialSpecifier(@NotNull Material material) { + this.material = material; + } + + @Override + @NotNull + public String asString() { + return this.material.name(); + } + + @Override + @NotNull + public Set asMaterials() { + return Set.of(this.material); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/config/material/BukkitTagSpecifier.java b/src/main/java/net/knarcraft/stargate/config/material/BukkitTagSpecifier.java new file mode 100644 index 0000000..8e4f6f4 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/material/BukkitTagSpecifier.java @@ -0,0 +1,35 @@ +package net.knarcraft.stargate.config.material; + +import org.bukkit.Material; +import org.bukkit.Tag; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * A specifier for a Bukkit material tag + */ +public class BukkitTagSpecifier implements MaterialSpecifier { + + private final Tag tag; + + /** + * Instantiates a new tag specifier + * + * @param tag

The tag to specify

+ */ + public BukkitTagSpecifier(@NotNull Tag tag) { + this.tag = tag; + } + + @Override + public @NotNull String asString() { + return "#" + this.tag.getKey().toString().replaceFirst("minecraft:", ""); + } + + @Override + public @NotNull Set asMaterials() { + return this.tag.getValues(); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/config/material/MaterialSpecifier.java b/src/main/java/net/knarcraft/stargate/config/material/MaterialSpecifier.java new file mode 100644 index 0000000..9665c05 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/material/MaterialSpecifier.java @@ -0,0 +1,29 @@ +package net.knarcraft.stargate.config.material; + +import org.bukkit.Material; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; + +/** + * An interface describing a specifier for one or more Bukkit materials + */ +public interface MaterialSpecifier { + + /** + * Gets the string representation of the material specifier + * + *

This is used when saving the value to a gate file

+ */ + @NotNull + String asString(); + + /** + * Gets all the materials the specifier specifies + * + *

This is used when registering gate materials

+ */ + @NotNull + Set asMaterials(); + +} diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 25230f8..78e0e37 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.container.BlockChangeRequest; +import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.event.StargateDestroyEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalCreator; @@ -139,6 +140,13 @@ public class BlockEventListener implements Listener { boolean deny = false; String denyMessage = ""; + // Block breaking the button from breaking the entire Stargate + if (portal.getStructure().getButton() != null && portal.getStructure().getButton().equals( + new BlockLocation(event.getBlock()))) { + event.setCancelled(true); + return; + } + //Decide if the user can destroy the portal if (!PermissionHelper.canDestroyPortal(player, portal)) { denyMessage = Stargate.getString("denyMsg"); diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 4720def..f75fc36 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -181,7 +181,8 @@ public class PlayerEventListener implements Listener { //Check an additional block away for BungeeCord portals using END_PORTAL as its material entrancePortal = PortalHandler.getByAdjacentEntrance(toLocation); if (entrancePortal == null || !entrancePortal.getOptions().isBungee() || - entrancePortal.getGate().getPortalOpenBlock() != Material.END_PORTAL) { + !MaterialHelper.specifiersToMaterials( + entrancePortal.getGate().getPortalOpenMaterials()).contains(Material.END_PORTAL)) { return false; } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 55878f8..53f0ea0 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; +import net.knarcraft.stargate.utility.ListHelper; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -10,7 +11,6 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.Random; /** * The portal activator activates/de-activates portals and keeps track of a portal's destinations @@ -77,7 +77,7 @@ public class PortalActivator { return null; } //Get one random destination - String destination = destinations.get((new Random()).nextInt(destinations.size())); + String destination = ListHelper.getRandom(destinations); return PortalHandler.getByName(Portal.cleanString(destination), portalNetwork); } else { //Just return the normal fixed destination diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index b84489e..9668ba8 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -12,8 +12,11 @@ import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.utility.DirectionHelper; import net.knarcraft.stargate.utility.EconomyHelper; +import net.knarcraft.stargate.utility.ListHelper; +import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; import net.knarcraft.stargate.utility.PortalFileHelper; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; @@ -303,8 +306,12 @@ public class PortalCreator { } else { //Update the block type for the portal's opening to the closed block as the closed block can be anything, // not just air or water + @NotNull List possibleMaterials = MaterialHelper.specifiersToMaterials( + portal.getGate().getPortalClosedMaterials()).stream().toList(); + Material closedType = ListHelper.getRandom(possibleMaterials); + for (BlockLocation entrance : portal.getStructure().getEntrances()) { - entrance.setType(portal.getGate().getPortalClosedBlock()); + entrance.setType(closedType); } } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index caba7e3..cb0c029 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -8,6 +8,7 @@ import net.knarcraft.stargate.portal.property.PortalOption; import net.knarcraft.stargate.portal.property.PortalStructure; import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.portal.property.gate.GateHandler; +import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.PermissionHelper; import org.bukkit.Location; import org.bukkit.World; @@ -445,8 +446,9 @@ public class PortalHandler { for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) { Block block = portal.getBlockAt(control).getBlock(); //Log control blocks not matching the gate layout - if (!block.getType().equals(portal.getGate().getControlBlock())) { - Stargate.debug("PortalHandler::destroyInvalidPortal", "Control Block Type == " + + if (!MaterialHelper.specifiersToMaterials(portal.getGate().getControlBlockMaterials()).contains( + block.getType())) { + Stargate.debug("PortalHandler::unregisterInvalidPortal", "Control Block Type == " + block.getType().name()); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java index 77d5dcb..ac41741 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalOpener.java @@ -6,6 +6,8 @@ import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateOpenEvent; import net.knarcraft.stargate.portal.property.PortalOptions; +import net.knarcraft.stargate.utility.ListHelper; +import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Axis; import org.bukkit.Material; import org.bukkit.block.data.Orientable; @@ -13,6 +15,8 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + /** * The portal opener is responsible for opening and closing a portal */ @@ -87,7 +91,10 @@ public class PortalOpener { } //Get the material to change the opening to - Material openType = portal.getGate().getPortalOpenBlock(); + @NotNull List possibleMaterials = MaterialHelper.specifiersToMaterials( + portal.getGate().getPortalOpenMaterials()).stream().toList(); + Material openType = ListHelper.getRandom(possibleMaterials); + //Adjust orientation if applicable Axis axis = (openType.createBlockData() instanceof Orientable) ? portal.getLocation().getRotationAxis() : null; @@ -168,9 +175,15 @@ public class PortalOpener { } //Close the portal by requesting the opening blocks to change - Material closedType = portal.getGate().getPortalClosedBlock(); + @NotNull List possibleMaterials = MaterialHelper.specifiersToMaterials( + portal.getGate().getPortalClosedMaterials()).stream().toList(); + Material closedType = ListHelper.getRandom(possibleMaterials); + + //Adjust orientation if applicable + Axis axis = (closedType.createBlockData() instanceof Orientable) ? portal.getLocation().getRotationAxis() : null; + for (BlockLocation entrance : portal.getStructure().getEntrances()) { - Stargate.addBlockChangeRequest(new BlockChangeRequest(entrance, closedType, null)); + Stargate.addBlockChangeRequest(new BlockChangeRequest(entrance, closedType, axis)); } //Update the portal state to make it actually closed diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java index 57c6dd2..efcfc30 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java @@ -1,10 +1,12 @@ package net.knarcraft.stargate.portal.property.gate; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.material.BukkitMaterialSpecifier; +import net.knarcraft.stargate.config.material.MaterialSpecifier; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; +import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Material; -import org.bukkit.Tag; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -13,6 +15,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -24,13 +27,12 @@ public class Gate { private final String filename; private final GateLayout layout; - private final Map characterMaterialMap; - private final Map> characterTagMap; + private final Map> characterMaterialMap; //Gate materials - private final Material portalOpenBlock; - private final Material portalClosedBlock; - private final Material portalButton; + private final List portalOpenMaterials; + private final List portalClosedMaterials; + private final List portalButtonMaterials; //Economy information private final int useCost; @@ -41,34 +43,33 @@ public class Gate { /** * Instantiates a new gate * - * @param filename

The name of the gate file, including extension

- * @param layout

The gate layout defined in the gate file

- * @param characterMaterialMap

The material types the different layout characters represent

- * @param characterTagMap

The material tag types the different layout characters represent

- * @param portalOpenBlock

The material to set the opening to when the portal is open

- * @param portalClosedBlock

The material to set the opening to when the portal is closed

- * @param portalButton

The material to use for the portal button

- * @param useCost

The cost of using a portal with this gate layout (-1 to disable)

- * @param createCost

The cost of creating a portal with this gate layout (-1 to disable)

- * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

- * @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

+ * @param filename

The name of the gate file, including extension

+ * @param layout

The gate layout defined in the gate file

+ * @param characterMaterialsMap

The material types the different layout characters represent

+ * @param portalOpenMaterials

The material to set the opening to when the portal is open

+ * @param portalClosedMaterials

The material to set the opening to when the portal is closed

+ * @param portalButtonMaterials

The material to use for the portal button

+ * @param useCost

The cost of using a portal with this gate layout (-1 to disable)

+ * @param createCost

The cost of creating a portal with this gate layout (-1 to disable)

+ * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

+ * @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

*/ public Gate(@NotNull String filename, @NotNull GateLayout layout, - @NotNull Map characterMaterialMap, - @NotNull Map> characterTagMap, @NotNull Material portalOpenBlock, - @NotNull Material portalClosedBlock, @NotNull Material portalButton, int useCost, int createCost, - int destroyCost, boolean toOwner) { + @NotNull Map> characterMaterialsMap, + @NotNull List portalOpenMaterials, + @NotNull List portalClosedMaterials, + @NotNull List portalButtonMaterials, int useCost, int createCost, int destroyCost, + boolean toOwner) { this.filename = filename; this.layout = layout; - this.characterMaterialMap = characterMaterialMap; - this.portalOpenBlock = portalOpenBlock; - this.portalClosedBlock = portalClosedBlock; - this.portalButton = portalButton; + this.characterMaterialMap = characterMaterialsMap; + this.portalOpenMaterials = portalOpenMaterials; + this.portalClosedMaterials = portalClosedMaterials; + this.portalButtonMaterials = portalButtonMaterials; this.useCost = useCost; this.createCost = createCost; this.destroyCost = destroyCost; this.toOwner = toOwner; - this.characterTagMap = characterTagMap; } /** @@ -87,7 +88,7 @@ public class Gate { * @return

The character to material map

*/ @NotNull - public Map getCharacterMaterialMap() { + public Map> getCharacterMaterialMap() { return new HashMap<>(characterMaterialMap); } @@ -98,18 +99,7 @@ public class Gate { * @return

True if the material is valid for control blocks

*/ public boolean isValidControlBlock(@NotNull Material material) { - return (getControlBlock() != null) ? getControlBlock().equals(material) : - getControlBlockTag().isTagged(material); - } - - /** - * Gets the material tag used for this gate's control blocks - * - * @return

The material tag type used for control blocks

- */ - @NotNull - public Tag getControlBlockTag() { - return characterTagMap.get(GateHandler.getControlBlockCharacter()); + return getControlBlockMaterials().contains(new BukkitMaterialSpecifier(material)); } /** @@ -117,8 +107,8 @@ public class Gate { * * @return

The material type used for control blocks

*/ - @Nullable - public Material getControlBlock() { + @NotNull + public List getControlBlockMaterials() { return characterMaterialMap.get(GateHandler.getControlBlockCharacter()); } @@ -138,8 +128,8 @@ public class Gate { * @return

The block type to use for the opening when open

*/ @NotNull - public Material getPortalOpenBlock() { - return portalOpenBlock; + public List getPortalOpenMaterials() { + return portalOpenMaterials; } /** @@ -148,8 +138,8 @@ public class Gate { * @return

The block type to use for the opening when closed

*/ @NotNull - public Material getPortalClosedBlock() { - return portalClosedBlock; + public List getPortalClosedMaterials() { + return portalClosedMaterials; } /** @@ -158,8 +148,8 @@ public class Gate { * @return

The material to use for a portal's button if using this gate type

*/ @NotNull - public Material getPortalButton() { - return portalButton; + public List getPortalButtonMaterials() { + return portalButtonMaterials; } /** @@ -236,35 +226,27 @@ public class Gate { * @return

True if all border blocks of the gate match the layout

*/ private boolean verifyGateBorderMatches(@NotNull BlockLocation topLeft, double yaw) { - Map characterMaterialMap = new HashMap<>(this.characterMaterialMap); - Map> characterTagMap = new HashMap<>(this.characterTagMap); + Map> characterMaterialMap = new HashMap<>(this.characterMaterialMap); for (RelativeBlockVector borderVector : layout.getBorder()) { int rowIndex = borderVector.right(); int lineIndex = borderVector.down(); Character key = layout.getLayout()[lineIndex][rowIndex]; - Material materialInLayout = characterMaterialMap.get(key); - Tag tagInLayout = characterTagMap.get(key); + List materialInLayout = characterMaterialMap.get(key); Material materialAtLocation = topLeft.getRelativeLocation(borderVector, yaw).getType(); if (materialInLayout != null) { - if (materialAtLocation != materialInLayout) { + if (!MaterialHelper.specifiersToMaterials(materialInLayout).contains(materialAtLocation)) { Stargate.debug("Gate::Matches", String.format("Block Type Mismatch: %s != %s", materialAtLocation, materialInLayout)); return false; } - } else if (tagInLayout != null) { - if (!tagInLayout.isTagged(materialAtLocation)) { - Stargate.debug("Gate::Matches", String.format("Block Type Mismatch: %s != %s", - materialAtLocation, tagInLayout)); - return false; - } } else { /* This generally should not happen with proper checking, but just in case a material character is not * recognized, but still allowed in previous checks, verify the gate as long as all such instances of * the character correspond to the same material in the physical gate. All subsequent gates will also * need to match the first verified gate. */ - characterMaterialMap.put(key, materialAtLocation); + characterMaterialMap.put(key, List.of(new BukkitMaterialSpecifier(materialAtLocation))); Stargate.debug("Gate::Matches", String.format("Missing layout material in %s. Using %s from the" + " physical portal.", getFilename(), materialAtLocation)); } @@ -291,7 +273,8 @@ public class Gate { continue; } - if (type != portalClosedBlock && type != portalOpenBlock) { + if (!MaterialHelper.specifiersToMaterials(portalClosedMaterials).contains(type) && + !MaterialHelper.specifiersToMaterials(portalOpenMaterials).contains(type)) { Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type); return false; } @@ -311,9 +294,9 @@ public class Gate { BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File(gateFolder, filename))); //Save main material names - writeConfig(bufferedWriter, "portal-open", portalOpenBlock.name()); - writeConfig(bufferedWriter, "portal-closed", portalClosedBlock.name()); - writeConfig(bufferedWriter, "button", portalButton.name()); + writeConfig(bufferedWriter, "portal-open", MaterialHelper.specifiersToString(portalOpenMaterials)); + writeConfig(bufferedWriter, "portal-closed", MaterialHelper.specifiersToString(portalClosedMaterials)); + writeConfig(bufferedWriter, "button", MaterialHelper.specifiersToString(portalButtonMaterials)); //Save the values necessary for economy saveEconomyValues(bufferedWriter); @@ -361,7 +344,7 @@ public class Gate { * @throws IOException

If unable to write to the buffered writer

*/ private void saveFrameBlockType(@NotNull BufferedWriter bufferedWriter) throws IOException { - for (Map.Entry entry : this.characterMaterialMap.entrySet()) { + for (Map.Entry> entry : this.characterMaterialMap.entrySet()) { Character key = entry.getKey(); //Skip characters not part of the frame if (key.equals(GateHandler.getAnythingCharacter()) || @@ -369,11 +352,7 @@ public class Gate { key.equals(GateHandler.getExitCharacter())) { continue; } - saveFrameBlockType(key, entry.getValue().toString(), bufferedWriter); - } - for (Map.Entry> entry : this.characterTagMap.entrySet()) { - saveFrameBlockType(entry.getKey(), "#" + entry.getValue().getKey().toString().replaceFirst( - "minecraft:", ""), bufferedWriter); + saveFrameBlockType(key, MaterialHelper.specifiersToString(entry.getValue()), bufferedWriter); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java index ebdce4e..7a26ef4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java @@ -1,7 +1,8 @@ package net.knarcraft.stargate.portal.property.gate; import net.knarcraft.stargate.Stargate; -import net.knarcraft.stargate.utility.GateReader; +import net.knarcraft.stargate.config.material.BukkitMaterialSpecifier; +import net.knarcraft.stargate.config.material.MaterialSpecifier; import net.knarcraft.stargate.utility.MaterialHelper; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -18,6 +19,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; +import java.util.Set; +import java.util.function.Predicate; import static net.knarcraft.stargate.utility.GateReader.generateLayoutMatrix; import static net.knarcraft.stargate.utility.GateReader.readGateConfig; @@ -94,20 +97,13 @@ public class GateHandler { private static void registerGate(@NotNull Gate gate) { gates.put(gate.getFilename(), gate); - Material blockId = gate.getControlBlock(); - if (blockId != null) { - if (!controlBlocks.containsKey(blockId)) { - controlBlocks.put(blockId, new ArrayList<>()); + Set blockTypes = MaterialHelper.specifiersToMaterials(gate.getControlBlockMaterials()); + for (Material material : blockTypes) { + if (!controlBlocks.containsKey(material)) { + controlBlocks.put(material, new ArrayList<>()); } - controlBlocks.get(blockId).add(gate); - return; + controlBlocks.get(material).add(gate); } - - Tag materialTag = gate.getControlBlockTag(); - if (!controlBlockTags.containsKey(materialTag.getKey().toString())) { - controlBlockTags.put(materialTag.getKey().toString(), new ArrayList<>()); - } - controlBlockTags.get(materialTag.getKey().toString()).add(gate); } /** @@ -138,24 +134,23 @@ public class GateHandler { private static Gate loadGate(@NotNull String fileName, @NotNull String parentFolder, @NotNull Scanner scanner) { List> design = new ArrayList<>(); - Map characterMaterialMap = new HashMap<>(); - Map> characterTagMap = new HashMap<>(); + Map> characterMaterialMap = new HashMap<>(); Map config = new HashMap<>(); //Initialize character to material map - characterMaterialMap.put(ENTRANCE, Material.AIR); - characterMaterialMap.put(EXIT, Material.AIR); - characterMaterialMap.put(ANYTHING, Material.AIR); + characterMaterialMap.put(ENTRANCE, List.of(new BukkitMaterialSpecifier(Material.AIR))); + characterMaterialMap.put(EXIT, List.of(new BukkitMaterialSpecifier(Material.AIR))); + characterMaterialMap.put(ANYTHING, List.of(new BukkitMaterialSpecifier(Material.AIR))); //Read the file into appropriate lists and maps - int columns = readGateFile(scanner, characterMaterialMap, characterTagMap, fileName, design, config); + int columns = readGateFile(scanner, characterMaterialMap, fileName, design, config); if (columns < 0) { return null; } Character[][] layout = generateLayoutMatrix(design, columns); //Create and validate the new gate - Gate gate = createGate(config, fileName, layout, characterMaterialMap, characterTagMap); + Gate gate = createGate(config, fileName, layout, characterMaterialMap); if (gate == null) { return null; } @@ -172,28 +167,26 @@ public class GateHandler { * @param fileName

The name of the saved gate config file

* @param layout

The layout matrix of the new gate

* @param characterMaterialMap

A map between layout characters and the material to use

- * @param materialTagMap

A map between layout characters and the material tags to use

* @return

A new gate, or null if the config is invalid

*/ @Nullable private static Gate createGate(@NotNull Map config, @NotNull String fileName, @NotNull Character[][] layout, - @NotNull Map characterMaterialMap, - @NotNull Map> materialTagMap) { + @NotNull Map> characterMaterialMap) { //Read relevant material types - Material portalOpenBlock = readGateConfig(config, fileName, "portal-open", defaultPortalBlockOpen); - Material portalClosedBlock = readGateConfig(config, fileName, "portal-closed", defaultPortalBlockClosed); - Material portalButton = readGateConfig(config, fileName, "button", defaultButton); + List portalOpenBlock = readGateConfig(config, fileName, "portal-open", defaultPortalBlockOpen); + List portalClosedBlock = readGateConfig(config, fileName, "portal-closed", defaultPortalBlockClosed); + List portalButton = readGateConfig(config, fileName, "button", defaultButton); //Read economy values - int useCost = GateReader.readGateConfig(config, fileName, "usecost"); - int createCost = GateReader.readGateConfig(config, fileName, "createcost"); - int destroyCost = GateReader.readGateConfig(config, fileName, "destroycost"); + int useCost = readGateConfig(config, fileName, "usecost"); + int createCost = readGateConfig(config, fileName, "createcost"); + int destroyCost = readGateConfig(config, fileName, "destroycost"); boolean toOwner = (config.containsKey("toowner") ? Boolean.parseBoolean(config.get("toowner")) : Stargate.getEconomyConfig().sendPaymentToOwner()); //Create the new gate - Gate gate = new Gate(fileName, new GateLayout(layout), characterMaterialMap, materialTagMap, portalOpenBlock, + Gate gate = new Gate(fileName, new GateLayout(layout), characterMaterialMap, portalOpenBlock, portalClosedBlock, portalButton, useCost, createCost, destroyCost, toOwner); if (!validateGate(gate, fileName)) { @@ -217,23 +210,23 @@ public class GateHandler { return false; } - if (!MaterialHelper.isButtonCompatible(gate.getPortalButton())) { + if (checkMaterialPredicateFail(gate.getPortalButtonMaterials(), MaterialHelper::isButtonCompatible)) { Stargate.logSevere(String.format(failString, "Gate button must be a type of button.")); return false; } - if (!gate.getPortalOpenBlock().isBlock()) { + if (checkMaterialPredicateFail(gate.getPortalOpenMaterials(), Material::isBlock)) { Stargate.logSevere(String.format(failString, "Gate open block must be a type of block.")); return false; } - if (!gate.getPortalClosedBlock().isBlock()) { + if (checkMaterialPredicateFail(gate.getPortalClosedMaterials(), Material::isBlock)) { Stargate.logSevere(String.format(failString, "Gate closed block must be a type of block.")); return false; } - for (Material material : gate.getCharacterMaterialMap().values()) { - if (!material.isBlock()) { + for (List materialSpecifiers : gate.getCharacterMaterialMap().values()) { + if (checkMaterialPredicateFail(materialSpecifiers, Material::isBlock)) { Stargate.logSevere(String.format(failString, "Every gate border block must be a type of block.")); return false; } @@ -242,6 +235,25 @@ public class GateHandler { return true; } + /** + * Checks whether a predicate is true for a list of material specifiers + * + * @param materialSpecifiers

The material specifiers to test

+ * @param predicate

The predicate to test

+ * @return

True if the predicate failed for any specified materials

+ */ + private static boolean checkMaterialPredicateFail(@NotNull List materialSpecifiers, + @NotNull Predicate predicate) { + Set closedMaterials = MaterialHelper.specifiersToMaterials(materialSpecifiers); + for (Material material : closedMaterials) { + if (!predicate.test(material)) { + return true; + } + } + + return false; + } + /** * Loads all gates inside the given folder * diff --git a/src/main/java/net/knarcraft/stargate/utility/GateReader.java b/src/main/java/net/knarcraft/stargate/utility/GateReader.java index d8804fb..f57c6c0 100644 --- a/src/main/java/net/knarcraft/stargate/utility/GateReader.java +++ b/src/main/java/net/knarcraft/stargate/utility/GateReader.java @@ -1,10 +1,9 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; -import org.bukkit.Bukkit; +import net.knarcraft.stargate.config.material.BukkitMaterialSpecifier; +import net.knarcraft.stargate.config.material.MaterialSpecifier; import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.Tag; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -26,15 +25,15 @@ public final class GateReader { * * @param scanner

The scanner to read from

* @param characterMaterialMap

The map of characters to store valid symbols in

- * @param materialTagMap

The map of characters to store valid tag symbols in

* @param fileName

The filename of the loaded gate config file

* @param design

The list to store the loaded design/layout to

* @param config

The map of config values to store to

* @return

The column count/width of the loaded gate

*/ - public static int readGateFile(@NotNull Scanner scanner, @NotNull Map characterMaterialMap, - @NotNull Map> materialTagMap, @NotNull String fileName, - @NotNull List> design, Map config) { + public static int readGateFile(@NotNull Scanner scanner, + @NotNull Map> characterMaterialMap, + @NotNull String fileName, @NotNull List> design, + @NotNull Map config) { boolean designing = false; int columns = 0; try (scanner) { @@ -43,14 +42,14 @@ public final class GateReader { if (designing) { //If we have reached the gate's layout/design, read it - columns = readGateDesignLine(line, columns, characterMaterialMap, materialTagMap, fileName, design); + columns = readGateDesignLine(line, columns, characterMaterialMap, fileName, design); if (columns < 0) { return -1; } } else { if (!line.isEmpty() && !line.startsWith("#")) { //Read a normal config value - readGateConfigValue(line, characterMaterialMap, materialTagMap, config); + readGateConfigValue(line, characterMaterialMap, config); } else if ((line.isEmpty()) || (!line.contains("=") && !line.startsWith("#"))) { //An empty line marks the start of the gate's layout/design designing = true; @@ -73,14 +72,12 @@ public final class GateReader { * @param line

The line to read

* @param maxColumns

The current max columns value of the design

* @param characterMaterialMap

The map between characters and the corresponding materials to use

- * @param materialTagMap

The map between characters and the corresponding material tags to use

* @param fileName

The filename of the loaded gate config file

* @param design

The two-dimensional list to store the loaded design to

* @return

The new max columns value of the design

*/ private static int readGateDesignLine(@NotNull String line, int maxColumns, - @NotNull Map characterMaterialMap, - @NotNull Map> materialTagMap, + @NotNull Map> characterMaterialMap, @NotNull String fileName, @NotNull List> design) { List row = new ArrayList<>(); @@ -91,7 +88,7 @@ public final class GateReader { for (Character symbol : line.toCharArray()) { //Refuse read gate designs with unknown characters - if (symbol.equals('?') || (!characterMaterialMap.containsKey(symbol) && !materialTagMap.containsKey(symbol))) { + if (symbol.equals('?') || !characterMaterialMap.containsKey(symbol)) { Stargate.logSevere(String.format("Could not load Gate %s - Unknown symbol '%s' in diagram", fileName, symbol)); return -1; @@ -110,12 +107,11 @@ public final class GateReader { * * @param line

The line to read

* @param characterMaterialMap

The character to material map to store to

- * @param materialTagMap

The character to material tag map to store to

* @param config

The config value map to store to

* @throws Exception

If an invalid material is encountered

*/ - private static void readGateConfigValue(@NotNull String line, @NotNull Map characterMaterialMap, - @NotNull Map> materialTagMap, + private static void readGateConfigValue(@NotNull String line, + @NotNull Map> characterMaterialMap, @NotNull Map config) throws Exception { String[] split = line.split("="); String key = split[0].trim(); @@ -125,23 +121,12 @@ public final class GateReader { //Read a gate frame material Character symbol = key.charAt(0); - if (value.startsWith("#")) { - String tagString = value.replaceFirst("#", ""); - Tag tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, NamespacedKey.minecraft(tagString.toLowerCase()), - Material.class); - if (tag != null) { - materialTagMap.put(symbol, tag); - return; - } + List materials = MaterialHelper.parseTagsAndMaterials(value); + if (!materials.isEmpty()) { + characterMaterialMap.put(symbol, materials); } else { - Material material = Material.matchMaterial(value); - if (material != null) { - //Register the map between the read symbol and the corresponding material - characterMaterialMap.put(symbol, material); - return; - } + throw new Exception("Invalid material in line: " + line); } - throw new Exception("Invalid material in line: " + line); } else { //Read a normal config value config.put(key, value); @@ -180,17 +165,17 @@ public final class GateReader { * @return

The material specified in the config, or the default material if it could not be read

*/ @NotNull - public static Material readGateConfig(@NotNull Map config, @NotNull String fileName, - @NotNull String key, @NotNull Material defaultMaterial) { + public static List readGateConfig(@NotNull Map config, @NotNull String fileName, + @NotNull String key, @NotNull Material defaultMaterial) { if (config.containsKey(key)) { - Material material = Material.matchMaterial(config.get(key)); - if (material != null) { - return material; + List materialSpecifiers = MaterialHelper.parseTagsAndMaterials(config.get(key)); + if (!materialSpecifiers.isEmpty()) { + return materialSpecifiers; } else { Stargate.logWarning(String.format("Error reading %s: %s is not a material", fileName, key)); } } - return defaultMaterial; + return List.of(new BukkitMaterialSpecifier(defaultMaterial)); } /** diff --git a/src/main/java/net/knarcraft/stargate/utility/ListHelper.java b/src/main/java/net/knarcraft/stargate/utility/ListHelper.java new file mode 100644 index 0000000..fa82656 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/utility/ListHelper.java @@ -0,0 +1,28 @@ +package net.knarcraft.stargate.utility; + +import java.util.List; +import java.util.Random; + +/** + * A helper class for dealing with lists + */ +public final class ListHelper { + + private static final Random random = new Random(); + + private ListHelper() { + + } + + /** + * Gets a random item from a list + * + * @param list

The list to get an item from

+ * @param

The type of item the list contains

+ * @return

A random item

+ */ + public static T getRandom(List list) { + return list.get(random.nextInt(list.size())); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java index 466e844..2e310bc 100644 --- a/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/MaterialHelper.java @@ -1,8 +1,19 @@ package net.knarcraft.stargate.utility; +import net.knarcraft.stargate.config.material.BukkitMaterialSpecifier; +import net.knarcraft.stargate.config.material.BukkitTagSpecifier; +import net.knarcraft.stargate.config.material.MaterialSpecifier; +import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.Tag; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * This class helps decide properties of materials not already present in the Spigot API @@ -50,4 +61,80 @@ public final class MaterialHelper { return Tag.BUTTONS.isTagged(material) || isWallCoral(material) || isContainer(material); } + @NotNull + public static String specifiersToString(@NotNull List specifiers) { + List names = new ArrayList<>(); + for (MaterialSpecifier specifier : specifiers) { + names.add(specifier.asString()); + } + return String.join(",", names); + } + + /** + * Converts a list of material specifiers to a set of materials + * + * @param specifiers

The material specifiers to convert

+ * @return

The materials the specifiers represent

+ */ + @NotNull + public static Set specifiersToMaterials(@NotNull List specifiers) { + Set output = new HashSet<>(); + + for (MaterialSpecifier specifier : specifiers) { + output.addAll(specifier.asMaterials()); + } + + return output; + } + + /** + * Parses all materials and material tags found in the input string + * + * @param input

The input string to parse

+ * @return

All material specifiers found

+ */ + @NotNull + public static List parseTagsAndMaterials(@NotNull String input) { + List specifiers = new ArrayList<>(); + + // Nothing to parse + if (input.isBlank()) { + return specifiers; + } + + String[] parts; + if (input.contains(",")) { + parts = input.split(","); + } else { + parts = new String[]{input}; + } + + for (String part : parts) { + MaterialSpecifier materialSpecifier = parseTagOrMaterial(part.trim()); + if (materialSpecifier != null) { + specifiers.add(materialSpecifier); + } + } + + return specifiers; + } + + @Nullable + private static MaterialSpecifier parseTagOrMaterial(@NotNull String input) { + if (input.startsWith("#")) { + String tagString = input.replaceFirst("#", "").toLowerCase(); + Tag tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, NamespacedKey.minecraft(tagString), Material.class); + if (tag != null) { + return new BukkitTagSpecifier(tag); + } + } else { + Material material = Material.matchMaterial(input); + if (material != null) { + return new BukkitMaterialSpecifier(material); + } + } + + return null; + } + } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index 2416e98..dcef0e0 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -409,11 +409,13 @@ public final class PermissionHelper { } //Player cannot access portal - if (!PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { + if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { if (!entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); } new PlayerTeleporter(entrancePortal, player).teleportPlayer(entrancePortal, event); + Stargate.debug("PermissionHelper::playerCannotTeleport", "Closed portal because player is " + + "missing necessary permissions"); entrancePortal.getPortalOpener().closePortal(false); return true; } diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 33ca2d5..98ff915 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -27,6 +27,7 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.List; import java.util.Scanner; import static net.knarcraft.stargate.portal.PortalSignDrawer.markPortalWithInvalidGate; @@ -399,9 +400,15 @@ public final class PortalFileHelper { return; } - Directional buttonData = (Directional) Bukkit.createBlockData(portal.getGate().getPortalButton()); - buttonData.setFacing(buttonFacing); - button.getBlock().setBlockData(buttonData); + if (!MaterialHelper.isButtonCompatible(button.getType())) { + @NotNull List possibleMaterials = MaterialHelper.specifiersToMaterials( + portal.getGate().getPortalButtonMaterials()).stream().toList(); + Material buttonType = ListHelper.getRandom(possibleMaterials); + + Directional buttonData = (Directional) Bukkit.createBlockData(buttonType); + buttonData.setFacing(buttonFacing); + button.getBlock().setBlockData(buttonData); + } portal.getStructure().setButton(button); } From e57aa4097ceb4d87a201be8f48a34a410c5d7782 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 20 Feb 2024 16:18:38 +0100 Subject: [PATCH 3/8] Adds a Message enum to avoid string keys --- .../java/net/knarcraft/stargate/Stargate.java | 13 +- .../stargate/command/CommandAbout.java | 3 +- .../stargate/command/CommandConfig.java | 3 +- .../stargate/config/EconomyConfig.java | 4 +- .../stargate/config/LanguageLoader.java | 78 +++--- .../knarcraft/stargate/config/Message.java | 251 ++++++++++++++++++ .../stargate/config/MessageSender.java | 4 +- .../stargate/config/StargateConfig.java | 4 +- .../stargate/listener/BlockEventListener.java | 7 +- .../listener/PlayerEventListener.java | 17 +- .../listener/PluginEventListener.java | 3 +- .../listener/VehicleEventListener.java | 5 +- .../stargate/portal/PortalActivator.java | 3 +- .../stargate/portal/PortalCreator.java | 19 +- .../stargate/portal/PortalHandler.java | 7 +- .../stargate/portal/PortalSignDrawer.java | 13 +- .../stargate/utility/BungeeHelper.java | 3 +- .../stargate/utility/EconomyHelper.java | 9 +- .../stargate/utility/PermissionHelper.java | 13 +- .../stargate/utility/TeleportHelper.java | 5 +- 20 files changed, 369 insertions(+), 95 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/config/Message.java diff --git a/src/main/java/net/knarcraft/stargate/Stargate.java b/src/main/java/net/knarcraft/stargate/Stargate.java index 2cebbb3..86be6df 100644 --- a/src/main/java/net/knarcraft/stargate/Stargate.java +++ b/src/main/java/net/knarcraft/stargate/Stargate.java @@ -4,6 +4,7 @@ import net.knarcraft.knarlib.util.UpdateChecker; import net.knarcraft.stargate.command.CommandStarGate; import net.knarcraft.stargate.command.StarGateTabCompleter; import net.knarcraft.stargate.config.EconomyConfig; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.config.MessageSender; import net.knarcraft.stargate.config.StargateConfig; import net.knarcraft.stargate.config.StargateGateConfig; @@ -298,26 +299,22 @@ public class Stargate extends JavaPlugin { } /** - * Gets a translated string given its string key - * - *

The name/key is the string before the equals sign in the language files

+ * Gets a translated string given its message key * * @param name

The name/key of the string to get

* @return

The full translated string

*/ - public static @NotNull String getString(@NotNull String name) { + public static @NotNull String getString(@NotNull Message name) { return stargateConfig.getLanguageLoader().getString(name); } /** - * Gets a backup string given its string key - * - *

The name/key is the string before the equals sign in the language files

+ * Gets a backup string given its message key * * @param name

The name/key of the string to get

* @return

The full string in the backup language (English)

*/ - public static @NotNull String getBackupString(@NotNull String name) { + public static @NotNull String getBackupString(@NotNull Message name) { return stargateConfig.getLanguageLoader().getBackupString(name); } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java index 2ceb5d8..e0e7217 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandAbout.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandAbout.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.command; import de.themoep.minedown.MineDown; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.utility.FileHelper; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.BaseComponent; @@ -34,7 +35,7 @@ public class CommandAbout implements CommandExecutor { } catch (IOException ioException) { commandSender.sendMessage("Internal error"); } - String author = Stargate.getStargateConfig().getLanguageLoader().getString("author"); + String author = Stargate.getStargateConfig().getLanguageLoader().getString(Message.AUTHOR); if (!author.isEmpty()) { commandSender.sendMessage(textColor + "Language created by " + highlightColor + author); } diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 2e61ad8..684393b 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.ConfigOption; import net.knarcraft.stargate.config.ConfigTag; import net.knarcraft.stargate.config.DynmapManager; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.config.OptionDataType; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalRegistry; @@ -418,7 +419,7 @@ public class CommandConfig implements CommandExecutor { * @param sender

The command sender to display the config list to

*/ private void displayConfigValues(@NotNull CommandSender sender) { - sender.sendMessage(ChatColor.GREEN + Stargate.getBackupString("prefix") + ChatColor.GOLD + + sender.sendMessage(ChatColor.GREEN + Stargate.getBackupString(Message.PREFIX) + ChatColor.GOLD + "Config values:"); for (ConfigOption option : ConfigOption.values()) { sender.sendMessage(getOptionDescription(option)); diff --git a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java index 5058246..d421ba8 100644 --- a/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/EconomyConfig.java @@ -192,10 +192,10 @@ public final class EconomyConfig { this.vault = vault; return true; } else { - Stargate.logInfo(Stargate.getString("ecoLoadError")); + Stargate.logInfo(Stargate.getString(Message.ECONOMY_LOAD_ERROR)); } } else { - Stargate.logInfo(Stargate.getString("vaultLoadError")); + Stargate.logInfo(Stargate.getString(Message.VAULT_LOAD_ERROR)); } configOptions.put(ConfigOption.USE_ECONOMY, false); return false; diff --git a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java index 77b3ee3..2c612e0 100644 --- a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java @@ -21,9 +21,9 @@ import java.util.Set; public final class LanguageLoader { private final String languageFolder; - private final Map loadedBackupStrings; + private final Map loadedBackupStrings; private String chosenLanguage; - private Map loadedStringTranslations; + private Map loadedStringTranslations; /** * Instantiates a new language loader @@ -62,34 +62,34 @@ public final class LanguageLoader { } /** - * Gets the string to display given its name/key + * Gets the string to display given its message key * - * @param name

The name/key of the string to display

- * @return

The string in the user's preferred language

+ * @param message

The message to display

+ * @return

The message in the user's preferred language

*/ @NotNull - public String getString(@NotNull String name) { + public String getString(@NotNull Message message) { String value = null; if (loadedStringTranslations != null) { - value = loadedStringTranslations.get(name); + value = loadedStringTranslations.get(message); } if (value == null) { - value = getBackupString(name); + value = getBackupString(message); } return value; } /** - * Gets the string to display given its name/key + * Gets the string to display given its message key * - * @param name

The name/key of the string to display

+ * @param message

The message to display

* @return

The string in the backup language (English)

*/ @NotNull - public String getBackupString(@NotNull String name) { + public String getBackupString(@NotNull Message message) { String value = null; if (loadedBackupStrings != null) { - value = loadedBackupStrings.get(name); + value = loadedBackupStrings.get(message); } if (value == null) { return ""; @@ -112,7 +112,7 @@ public final class LanguageLoader { * @param language

The language to update

*/ private void updateLanguage(@NotNull String language) { - Map currentLanguageValues = load(language); + Map currentLanguageValues = load(language); InputStream inputStream = getClass().getResourceAsStream("/lang/" + language + ".txt"); if (inputStream == null) { @@ -138,11 +138,11 @@ public final class LanguageLoader { * @throws IOException

if unable to read a language file

*/ private void readChangedLanguageStrings(@NotNull InputStream inputStream, @NotNull String language, - @Nullable Map currentLanguageValues) throws IOException { + @Nullable Map currentLanguageValues) throws IOException { //Get language values BufferedReader bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream); - Map internalLanguageValues = FileHelper.readKeyValuePairs(bufferedReader, "=", - ColorConversion.NORMAL); + Map internalLanguageValues = fromStringMap(FileHelper.readKeyValuePairs(bufferedReader, + "=", ColorConversion.NORMAL)); //If currentLanguageValues is null; the chosen language has not been used before if (currentLanguageValues == null) { @@ -153,9 +153,9 @@ public final class LanguageLoader { //If a key is not found in the language file, add the one in the internal file. Must update the external file if (!internalLanguageValues.keySet().equals(currentLanguageValues.keySet())) { - Map newLanguageValues = new HashMap<>(); + Map newLanguageValues = new HashMap<>(); boolean updateNecessary = false; - for (String key : internalLanguageValues.keySet()) { + for (Message key : internalLanguageValues.keySet()) { if (currentLanguageValues.get(key) == null) { newLanguageValues.put(key, internalLanguageValues.get(key)); //Found at least one value in the internal file not in the external file. Need to update @@ -181,19 +181,19 @@ public final class LanguageLoader { * @param customLanguageStrings

Any custom language strings not recognized

* @throws IOException

If unable to write to the language file

*/ - private void updateLanguageFile(@NotNull String language, @NotNull Map languageStrings, - @Nullable Map customLanguageStrings) throws IOException { + private void updateLanguageFile(@NotNull String language, @NotNull Map languageStrings, + @Nullable Map customLanguageStrings) throws IOException { BufferedWriter bufferedWriter = FileHelper.getBufferedWriterFromString(languageFolder + language + ".txt"); //Output normal Language data - for (String key : languageStrings.keySet()) { + for (Message key : languageStrings.keySet()) { bufferedWriter.write(key + "=" + languageStrings.get(key)); bufferedWriter.newLine(); } bufferedWriter.newLine(); //Output any custom language strings the user had if (customLanguageStrings != null) { - for (String key : customLanguageStrings.keySet()) { + for (Message key : customLanguageStrings.keySet()) { bufferedWriter.write(key + "=" + customLanguageStrings.get(key)); bufferedWriter.newLine(); } @@ -207,8 +207,7 @@ public final class LanguageLoader { * @param lang

The language to load

* @return

A mapping between loaded string indexes and the strings to display

*/ - @Nullable - private Map load(@NotNull String lang) { + private Map load(@NotNull String lang) { return load(lang, null); } @@ -219,9 +218,7 @@ public final class LanguageLoader { * @param inputStream

An optional input stream to use. Defaults to using a file input stream

* @return

A mapping between loaded string indexes and the strings to display

*/ - @Nullable - private Map load(@NotNull String lang, @Nullable InputStream inputStream) { - Map strings; + private Map load(@NotNull String lang, @Nullable InputStream inputStream) { BufferedReader bufferedReader; try { if (inputStream == null) { @@ -229,14 +226,13 @@ public final class LanguageLoader { } else { bufferedReader = FileHelper.getBufferedReaderFromInputStream(inputStream); } - strings = FileHelper.readKeyValuePairs(bufferedReader, "=", ColorConversion.NORMAL); + return fromStringMap(FileHelper.readKeyValuePairs(bufferedReader, "=", ColorConversion.NORMAL)); } catch (Exception exception) { if (Stargate.getStargateConfig().isDebuggingEnabled()) { Stargate.logInfo("Unable to load language " + lang); } return null; } - return strings; } /** @@ -244,8 +240,8 @@ public final class LanguageLoader { */ public void debug() { if (loadedStringTranslations != null) { - Set keys = loadedStringTranslations.keySet(); - for (String key : keys) { + Set keys = loadedStringTranslations.keySet(); + for (Message key : keys) { Stargate.debug("LanguageLoader::Debug::loadedStringTranslations", key + " => " + loadedStringTranslations.get(key)); } @@ -253,11 +249,27 @@ public final class LanguageLoader { if (loadedBackupStrings == null) { return; } - Set keys = loadedBackupStrings.keySet(); - for (String key : keys) { + Set keys = loadedBackupStrings.keySet(); + for (Message key : keys) { Stargate.debug("LanguageLoader::Debug::loadedBackupStrings", key + " => " + loadedBackupStrings.get(key)); } } + @NotNull + private Map fromStringMap(@NotNull Map configurationStrings) { + Map output = new HashMap<>(); + for (Map.Entry entry : configurationStrings.entrySet()) { + Message message = Message.getFromKey(entry.getKey()); + if (message == null) { + Stargate.logWarning("Found unrecognized language key " + entry.getKey()); + continue; + } + + output.put(message, entry.getValue()); + } + + return output; + } + } diff --git a/src/main/java/net/knarcraft/stargate/config/Message.java b/src/main/java/net/knarcraft/stargate/config/Message.java new file mode 100644 index 0000000..312f5ad --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/Message.java @@ -0,0 +1,251 @@ +package net.knarcraft.stargate.config; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * Translated messages displayed to players + */ +public enum Message { + + /** + * The prefix displayed in front of all messages shown in the chat + */ + PREFIX("prefix"), + + /** + * The message displayed when a player is teleported + */ + TELEPORTED("teleportMsg"), + + /** + * The message displayed when a player destroys a Stargate + */ + DESTROYED("destroyMsg"), + + /** + * The message displayed when the currently selected Stargate destination is invalid + */ + INVALID_DESTINATION("invalidMsg"), + + /** + * The message displayed when the destination portal is busy with another player + */ + DESTINATION_BLOCKED("blockMsg"), + + /** + * The message displayed when the Stargate has no destinations available to the player + */ + NO_DESTINATION("destEmpty"), + + /** + * The message displayed when a player is denied access to any action + */ + ACCESS_DENIED("denyMsg"), + + /** + * The message displayed when the plugin is reloaded + */ + RELOADED("reloaded"), + + /** + * The message displayed when a player has some currency deducted from their account + */ + ECONOMY_DEDUCTED("ecoDeduct"), + + /** + * The message displayed when a player has some currency refunded to their account + */ + ECONOMY_REFUNDED("ecoRefund"), + + /** + * The message displayed when a player obtains some currency to their account (from portal usage) + */ + ECONOMY_OBTAINED("ecoObtain"), + + /** + * The message displayed when the player has an insufficient amount of currency to perform an action + */ + ECONOMY_INSUFFICIENT("ecoInFunds"), + + /** + * The message displayed when economy fails to load + */ + ECONOMY_LOAD_ERROR("ecoLoadError"), + + /** + * The message displayed when Vault fails to load + */ + VAULT_LOAD_ERROR("vaultLoadError"), + + /** + * The message displayed when Vault successfully loads + */ + VAULT_LOADED("vaultLoaded"), + + /** + * The message displayed when a Stargate is successfully created + */ + CREATED("createMsg"), + + /** + * The message displayed when a player is denied from creating a Stargate on the selected network + */ + CREATION_NETWORK_DENIED("createNetDeny"), + + /** + * The message displayed when a player is denied from creating a Stargate of the given gate type + */ + CREATION_GATE_DENIED("createGateDeny"), + + /** + * The message displayed when a Stargate is created on the player's personal network + */ + CREATION_PERSONAL("createPersonal"), + + /** + * The message displayed when the name of a Stargate is too short or too long + */ + CREATION_NAME_LENGTH("createNameLength"), + + /** + * The message displayed when another Stargate on the network has the same name as the new Stargate + */ + CREATION_NAME_COLLISION("createExists"), + + /** + * The message displayed when the specified network is full + */ + CREATION_NETWORK_FULL("createFull"), + + /** + * The message displayed when a player is denied from creating a Stargate in the current world + */ + CREATION_WORLD_DENIED("createWorldDeny"), + + /** + * The message displayed when a gate is physically conflicting with another + */ + CREATION_CONFLICT("createConflict"), + + /** + * The right-click prompt displayed on Stargate signs + */ + SIGN_RIGHT_CLICK("signRightClick"), + + /** + * The to use prompt displayed on Stargate signs + */ + SIGN_TO_USE("signToUse"), + + /** + * The random string displayed on Stargate signs + */ + SIGN_RANDOM("signRandom"), + + /** + * The disconnected string displayed on Stargate signs + */ + SIGN_DISCONNECTED("signDisconnected"), + + /** + * The invalid gate string displayed on Stargate signs + */ + SIGN_INVALID("signInvalidGate"), + + /** + * The message displayed if trying to create a bungee gate when bungee is disabled + */ + BUNGEE_DISABLED("bungeeDisabled"), + + /** + * The message displayed when a player is denied from creating a bungee Stargate + */ + BUNGEE_CREATION_DENIED("bungeeDeny"), + + /** + * The message displayed if a Stargate is missing the destination, the network or both + */ + BUNGEE_MISSING_INFO("bungeeEmpty"), + + /** + * The teleportation prompt shown on bungee signs + */ + BUNGEE_SIGN("bungeeSign"), + + /** + * The format of the title of the portal info shown in chat + */ + PORTAL_INFO_TITLE("portalInfoTitle"), + + /** + * The format of the name of the portal info shown in chat + */ + PORTAL_INFO_NAME("portalInfoName"), + + /** + * The format of the destination of the portal info shown in chat + */ + PORTAL_INFO_DESTINATION("portalInfoDestination"), + + /** + * The format of the network of the portal info shown in chat + */ + PORTAL_INFO_NETWORK("portalInfoNetwork"), + + /** + * The format of the server of the portal info shown in chat + */ + PORTAL_INFO_SERVER("portalInfoServer"), + + /** + * The author that created the loaded translation + */ + AUTHOR("author"), + ; + + private final String key; + + /** + * Instantiates a new message + * + * @param key

The key of the message in the language files

+ */ + Message(@NotNull String key) { + this.key = key; + } + + /** + * Gets the language file key for this message + * + * @return

This message's key

+ */ + @NotNull + public String getKey() { + return this.key; + } + + /** + * Gets the message corresponding to the given key + * + * @param key

The key to get a message from

+ * @return

The message, or null if not found

+ */ + @Nullable + public static Message getFromKey(@NotNull String key) { + for (Message message : Message.values()) { + if (message.getKey().equalsIgnoreCase(key)) { + return message; + } + } + + return null; + } + + @Override + @NotNull + public String toString() { + return this.getKey(); + } + +} diff --git a/src/main/java/net/knarcraft/stargate/config/MessageSender.java b/src/main/java/net/knarcraft/stargate/config/MessageSender.java index a021de4..80ac7f2 100644 --- a/src/main/java/net/knarcraft/stargate/config/MessageSender.java +++ b/src/main/java/net/knarcraft/stargate/config/MessageSender.java @@ -53,9 +53,9 @@ public final class MessageSender { } message = ChatColor.translateAlternateColorCodes('&', message); if (error) { - sender.sendMessage(ChatColor.RED + languageLoader.getString("prefix") + ChatColor.WHITE + message); + sender.sendMessage(ChatColor.RED + languageLoader.getString(Message.PREFIX) + ChatColor.WHITE + message); } else { - sender.sendMessage(ChatColor.GREEN + languageLoader.getString("prefix") + ChatColor.WHITE + message); + sender.sendMessage(ChatColor.GREEN + languageLoader.getString(Message.PREFIX) + ChatColor.WHITE + message); } } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 1b9316c..bf5f663 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -244,7 +244,7 @@ public final class StargateConfig { //Reload portal markers DynmapManager.addAllPortalMarkers(); - messageSender.sendErrorMessage(sender, languageLoader.getString("reloaded")); + messageSender.sendErrorMessage(sender, languageLoader.getString(Message.RELOADED)); } /** @@ -541,7 +541,7 @@ public final class StargateConfig { if (economyConfig.setupEconomy(Stargate.getPluginManager()) && economyConfig.getEconomy() != null && economyConfig.getVault() != null) { String vaultVersion = economyConfig.getVault().getDescription().getVersion(); - Stargate.logInfo(Stargate.replacePlaceholders(Stargate.getString("vaultLoaded"), "%version%", vaultVersion)); + Stargate.logInfo(Stargate.replacePlaceholders(Stargate.getString(Message.VAULT_LOADED), "%version%", vaultVersion)); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java index 78e0e37..66b87d5 100644 --- a/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/BlockEventListener.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.container.BlockChangeRequest; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.event.StargateDestroyEvent; @@ -93,7 +94,7 @@ public class BlockEventListener implements Listener { Stargate.addBlockChangeRequest(request); } - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("createMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString(Message.CREATED)); Stargate.debug("onSignChange", "Initialized stargate: " + portal.getName()); Stargate.getInstance().getServer().getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), portal::drawSign, 1); @@ -149,7 +150,7 @@ public class BlockEventListener implements Listener { //Decide if the user can destroy the portal if (!PermissionHelper.canDestroyPortal(player, portal)) { - denyMessage = Stargate.getString("denyMsg"); + denyMessage = Stargate.getString(Message.ACCESS_DENIED); deny = true; Stargate.logInfo(String.format("%s tried to destroy gate", player.getName())); } @@ -179,7 +180,7 @@ public class BlockEventListener implements Listener { } PortalRegistry.unregisterPortal(portal, true); - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("destroyMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString(Message.DESTROYED)); } /** diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index f75fc36..35b53ed 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -2,6 +2,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.knarlib.util.UpdateChecker; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.config.MessageSender; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.portal.Portal; @@ -154,7 +155,7 @@ public class PlayerEventListener implements Listener { new PlayerTeleporter(destination, player).teleportPlayer(entrancePortal, event); } if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString(Message.TELEPORTED)); } entrancePortal.getPortalOpener().closePortal(false); } @@ -202,7 +203,7 @@ public class PlayerEventListener implements Listener { //Decide if the user should be teleported to another bungee server if (entrancePortal.getOptions().isBungee()) { if (BungeeHelper.bungeeTeleport(player, entrancePortal, event) && !entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString(Message.TELEPORTED)); } return false; } @@ -306,7 +307,7 @@ public class PlayerEventListener implements Listener { if (PermissionHelper.portalAccessDenied(player, portal, deny)) { if (!portal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.ACCESS_DENIED)); } return true; } @@ -378,16 +379,16 @@ public class PlayerEventListener implements Listener { //Display portal information as a portal without a sign does not display any if (portal.getOptions().hasNoSign() && (!portal.getOptions().isSilent() || player.isSneaking())) { MessageSender sender = Stargate.getMessageSender(); - sender.sendSuccessMessage(player, ChatColor.GOLD + Stargate.getString("portalInfoTitle")); - sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString("portalInfoName"), + sender.sendSuccessMessage(player, ChatColor.GOLD + Stargate.getString(Message.PORTAL_INFO_TITLE)); + sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString(Message.PORTAL_INFO_NAME), "%name%", portal.getName())); - sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString("portalInfoDestination"), + sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString(Message.PORTAL_INFO_DESTINATION), "%destination%", portal.getDestinationName())); if (portal.getOptions().isBungee()) { - sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString("portalInfoServer"), + sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString(Message.PORTAL_INFO_SERVER), "%server%", portal.getNetwork())); } else { - sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString("portalInfoNetwork"), + sender.sendSuccessMessage(player, Stargate.replacePlaceholders(Stargate.getString(Message.PORTAL_INFO_NETWORK), "%network%", portal.getNetwork())); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java index d675335..4628640 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PluginEventListener.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.server.PluginDisableEvent; @@ -38,7 +39,7 @@ public class PluginEventListener implements Listener { Plugin vault = Stargate.getEconomyConfig().getVault(); if (vault != null) { String vaultVersion = vault.getDescription().getVersion(); - Stargate.logInfo(Stargate.replacePlaceholders(Stargate.getString("vaultLoaded"), "%version%", + Stargate.logInfo(Stargate.replacePlaceholders(Stargate.getString(Message.VAULT_LOADED), "%version%", vaultVersion)); } } diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index f2ecb6a..b7c1e26 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.listener; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.teleporter.VehicleTeleporter; @@ -113,7 +114,7 @@ public class VehicleEventListener implements Listener { if (destinationPortal == null) { cancelTeleport = true; if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.INVALID_DESTINATION)); } } else if (!TeleportHelper.playerCanTeleport(player, entrancePortal, destinationPortal)) { cancelTeleport = true; @@ -140,7 +141,7 @@ public class VehicleEventListener implements Listener { if (teleported) { if (!entrancePortal.getOptions().isSilent()) { for (Player player : players) { - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString("teleportMsg")); + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString(Message.TELEPORTED)); } } entrancePortal.getPortalOpener().closePortal(false); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 53f0ea0..0833f87 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent; import net.knarcraft.stargate.utility.ListHelper; @@ -256,7 +257,7 @@ public class PortalActivator { //If no destinations are available, just tell the player and quit if (destinations.size() == 0) { if (!portal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("destEmpty")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.NO_DESTINATION)); } return; } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 9668ba8..c09d17c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.event.StargateCreateEvent; @@ -130,11 +131,11 @@ public class PortalCreator { network = network.substring(0, getMaxNameNetworkLength()); } Stargate.debug("createPortal", "Creating personal portal"); - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createPersonal")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_PERSONAL)); } else { Stargate.debug("createPortal", "Player does not have access to network"); deny = true; - denyMessage = Stargate.getString("createNetDeny"); + denyMessage = Stargate.getString(Message.CREATION_NETWORK_DENIED); } } @@ -144,7 +145,7 @@ public class PortalCreator { if (!deny && !PermissionHelper.canCreatePortal(player, gateName)) { Stargate.debug("createPortal", "Player does not have access to gate layout"); deny = true; - denyMessage = Stargate.getString("createGateDeny"); + denyMessage = Stargate.getString(Message.CREATION_GATE_DENIED); } //Check if the user can create portals to this world. @@ -155,7 +156,7 @@ public class PortalCreator { if (PermissionHelper.cannotAccessWorld(player, world)) { Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); deny = true; - denyMessage = Stargate.getString("createWorldDeny"); + denyMessage = Stargate.getString(Message.CREATION_WORLD_DENIED); } } } @@ -245,7 +246,7 @@ public class PortalCreator { if (portal.getCleanName().length() < 1 || portal.getCleanName().length() > getMaxNameNetworkLength()) { Stargate.debug("createPortal", String.format("Name length error. %s is too long.", portal.getCleanName())); - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createNameLength")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_NAME_LENGTH)); return false; } @@ -253,14 +254,14 @@ public class PortalCreator { //Check if the bungee portal's name has been duplicated if (PortalHandler.getBungeePortals().get(portal.getCleanName()) != null) { Stargate.debug("createPortal::Bungee", "Gate name duplicate"); - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_NAME_COLLISION)); return false; } } else { //Check if the portal name has been duplicated on the network if (PortalHandler.getByName(portal.getCleanName(), portal.getCleanNetwork()) != null) { Stargate.debug("createPortal", "Gate name duplicate"); - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createExists")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_NAME_COLLISION)); return false; } @@ -268,7 +269,7 @@ public class PortalCreator { List networkList = PortalHandler.getAllPortalNetworks().get(portal.getCleanNetwork()); int maxGates = Stargate.getGateConfig().maxGatesEachNetwork(); if (maxGates > 0 && networkList != null && networkList.size() >= maxGates) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createFull")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_NETWORK_FULL)); return false; } } @@ -331,7 +332,7 @@ public class PortalCreator { BlockLocation borderBlockLocation = topLeft.getRelativeLocation(borderVector, yaw); if (PortalHandler.getByBlock(borderBlockLocation.getBlock()) != null) { Stargate.debug("createPortal", "Gate conflicts with existing gate"); - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("createConflict")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_CONFLICT)); return true; } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index cb0c029..9f57fc7 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.container.BlockLocation; import net.knarcraft.stargate.container.RelativeBlockVector; import net.knarcraft.stargate.portal.property.PortalLocation; @@ -135,13 +136,13 @@ public class PortalHandler { @NotNull String destinationName, String network) { if (portalOptions.get(PortalOption.BUNGEE)) { if (!PermissionHelper.hasPermission(player, "stargate.admin.bungee")) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDeny")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.BUNGEE_CREATION_DENIED)); return false; } else if (!Stargate.getGateConfig().enableBungee()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.BUNGEE_DISABLED)); return false; } else if (destinationName.isEmpty() || network.isEmpty()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeEmpty")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.BUNGEE_MISSING_INFO)); return false; } } diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java index 506b702..3432c2e 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalSignDrawer.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.portal; import net.knarcraft.knarlib.property.ColorConversion; import net.knarcraft.knarlib.util.ColorHelper; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.container.SignData; import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.utility.PermissionHelper; @@ -296,7 +297,7 @@ public class PortalSignDrawer { private void drawBungeeSign(@NotNull SignData signData) { ChatColor highlightColor = signData.getHighlightSignColor(); ChatColor mainColor = signData.getMainSignColor(); - setLine(signData, 1, Stargate.getString("bungeeSign")); + setLine(signData, 1, Stargate.getString(Message.BUNGEE_SIGN)); setLine(signData, 2, highlightColor + ">" + mainColor + translateAllColorCodes(portal.getDestinationName()) + highlightColor + "<"); setLine(signData, 3, highlightColor + "[" + mainColor + translateAllColorCodes(portal.getNetwork()) + @@ -313,8 +314,8 @@ public class PortalSignDrawer { private void drawInactiveSign(@NotNull SignData signData) { ChatColor highlightColor = signData.getHighlightSignColor(); ChatColor mainColor = signData.getMainSignColor(); - setLine(signData, 1, Stargate.getString("signRightClick")); - setLine(signData, 2, Stargate.getString("signToUse")); + setLine(signData, 1, Stargate.getString(Message.SIGN_RIGHT_CLICK)); + setLine(signData, 2, Stargate.getString(Message.SIGN_TO_USE)); if (!portal.getOptions().isNoNetwork()) { setLine(signData, 3, highlightColor + "(" + mainColor + translateAllColorCodes(portal.getNetwork()) + highlightColor + ")"); @@ -333,7 +334,7 @@ public class PortalSignDrawer { ChatColor mainColor = signData.getMainSignColor(); Portal destinationPortal = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), portal.getCleanNetwork()); - String destinationName = portal.getOptions().isRandom() ? Stargate.getString("signRandom") : + String destinationName = portal.getOptions().isRandom() ? Stargate.getString(Message.SIGN_RANDOM) : (destinationPortal != null ? destinationPortal.getName() : portal.getDestinationName()); setLine(signData, 1, highlightColor + ">" + mainColor + translateAllColorCodes(destinationName) + highlightColor + "<"); @@ -347,7 +348,7 @@ public class PortalSignDrawer { Portal destination = PortalHandler.getByName(Portal.cleanString(portal.getDestinationName()), portal.getNetwork()); if (destination == null && !portal.getOptions().isRandom()) { - setLine(signData, 3, errorColor + Stargate.getString("signDisconnected")); + setLine(signData, 3, errorColor + Stargate.getString(Message.SIGN_DISCONNECTED)); } else { setLine(signData, 3, ""); } @@ -366,7 +367,7 @@ public class PortalSignDrawer { if (!(blockState instanceof Sign sign)) { return; } - SignHelper.setSignLine(sign, 3, errorColor + Stargate.getString("signInvalidGate")); + SignHelper.setSignLine(sign, 3, errorColor + Stargate.getString(Message.SIGN_INVALID)); sign.update(); Stargate.logInfo(String.format("Gate layout on line %d does not exist [%s]", lineIndex, gateName)); diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 1145d73..d586b2c 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.PortalHandler; import net.knarcraft.stargate.portal.teleporter.PlayerTeleporter; @@ -186,7 +187,7 @@ public final class BungeeHelper { //Check if bungee is actually enabled if (!Stargate.getGateConfig().enableBungee()) { if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("bungeeDisabled")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.BUNGEE_DISABLED)); } entrancePortal.getPortalOpener().closePortal(false); return false; diff --git a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java index aa462f3..8e4cbe2 100644 --- a/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/EconomyHelper.java @@ -3,6 +3,7 @@ package net.knarcraft.stargate.utility; import net.knarcraft.knarlib.formatting.StringFormatter; import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.EconomyConfig; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.property.PortalOwner; import net.milkbowl.vault.economy.Economy; @@ -81,7 +82,7 @@ public final class EconomyHelper { * @param earnings

The amount the owner earned

*/ public static void sendObtainMessage(@NotNull String portalName, @NotNull Player portalOwner, int earnings) { - String obtainedMsg = Stargate.getString("ecoObtain"); + String obtainedMsg = Stargate.getString(Message.ECONOMY_OBTAINED); obtainedMsg = replacePlaceholders(obtainedMsg, portalName, earnings); Stargate.getMessageSender().sendSuccessMessage(portalOwner, obtainedMsg); } @@ -94,7 +95,7 @@ public final class EconomyHelper { * @param cost

The cost of the interaction

*/ public static void sendDeductMessage(@NotNull String portalName, @NotNull Player player, int cost) { - String deductMsg = Stargate.getString("ecoDeduct"); + String deductMsg = Stargate.getString(Message.ECONOMY_DEDUCTED); deductMsg = replacePlaceholders(deductMsg, portalName, cost); Stargate.getMessageSender().sendSuccessMessage(player, deductMsg); } @@ -107,7 +108,7 @@ public final class EconomyHelper { * @param cost

The cost of the interaction

*/ public static void sendInsufficientFundsMessage(@NotNull String portalName, @NotNull Player player, int cost) { - String inFundMsg = Stargate.getString("ecoInFunds"); + String inFundMsg = Stargate.getString(Message.ECONOMY_INSUFFICIENT); inFundMsg = replacePlaceholders(inFundMsg, portalName, cost); Stargate.getMessageSender().sendErrorMessage(player, inFundMsg); } @@ -120,7 +121,7 @@ public final class EconomyHelper { * @param cost

The amount the user has to pay for destroying the portal. (expects a negative value)

*/ public static void sendRefundMessage(@NotNull String portalName, @NotNull Player player, int cost) { - String refundMsg = Stargate.getString("ecoRefund"); + String refundMsg = Stargate.getString(Message.ECONOMY_REFUNDED); refundMsg = replacePlaceholders(refundMsg, portalName, -cost); Stargate.getMessageSender().sendSuccessMessage(player, refundMsg); } diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index dcef0e0..ea36003 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.event.StargateAccessEvent; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.property.PortalOption; @@ -38,7 +39,7 @@ public final class PermissionHelper { //Destination is invalid or the same portal. Send an error message if (destination == null || destination == portal) { if (!portal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("invalidMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.INVALID_DESTINATION)); } return; } @@ -56,7 +57,7 @@ public final class PermissionHelper { if (!portal.getOptions().isFixed() && portal.getPortalActivator().isActive() && portal.getActivePlayer() != player) { if (!portal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.ACCESS_DENIED)); } return; } @@ -64,7 +65,7 @@ public final class PermissionHelper { //Check if the player can use the private gate if (portal.getOptions().isPrivate() && !PermissionHelper.canUsePrivatePortal(player, portal)) { if (!portal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.ACCESS_DENIED)); } return; } @@ -72,7 +73,7 @@ public final class PermissionHelper { //Destination is currently in use by another player, blocking teleportation if (destination.isOpen() && !destination.getOptions().isAlwaysOn()) { if (!portal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("blockMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.DESTINATION_BLOCKED)); } return; } @@ -396,7 +397,7 @@ public final class PermissionHelper { //Not open for this player if (!entrancePortal.getPortalOpener().isOpenFor(player)) { if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.ACCESS_DENIED)); } new PlayerTeleporter(entrancePortal, player).teleportPlayer(entrancePortal, event); return true; @@ -411,7 +412,7 @@ public final class PermissionHelper { //Player cannot access portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destination)) { if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.ACCESS_DENIED)); } new PlayerTeleporter(entrancePortal, player).teleportPlayer(entrancePortal, event); Stargate.debug("PermissionHelper::playerCannotTeleport", "Closed portal because player is " + diff --git a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java index e748119..9c7b34b 100644 --- a/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/TeleportHelper.java @@ -1,6 +1,7 @@ package net.knarcraft.stargate.utility; import net.knarcraft.stargate.Stargate; +import net.knarcraft.stargate.config.Message; import net.knarcraft.stargate.portal.Portal; import net.knarcraft.stargate.portal.teleporter.EntityTeleporter; import org.bukkit.Bukkit; @@ -229,7 +230,7 @@ public final class TeleportHelper { //Make sure the user can access the portal if (PermissionHelper.cannotAccessPortal(player, entrancePortal, destinationPortal)) { if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("denyMsg")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.ACCESS_DENIED)); } entrancePortal.getPortalOpener().closePortal(false); return false; @@ -240,7 +241,7 @@ public final class TeleportHelper { boolean canAffordFee = cost <= 0 || Stargate.getEconomyConfig().canAffordFee(player, cost); if (!canAffordFee) { if (!entrancePortal.getOptions().isSilent()) { - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString("ecoInFunds")); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.ECONOMY_INSUFFICIENT)); } return false; } From ee9bc2109979d9382c0659de0a522e4615fedc58 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 20 Feb 2024 18:54:04 +0100 Subject: [PATCH 4/8] Fixes some code style issues, and attempts to fix test failures --- .../stargate/command/ConfigTabCompleter.java | 4 +- .../stargate/config/LanguageLoader.java | 37 ++++---- .../stargate/config/StargateConfig.java | 23 +++++ .../listener/PlayerEventListener.java | 47 +++++++--- .../listener/VehicleEventListener.java | 86 +++++++++++++------ 5 files changed, 137 insertions(+), 60 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java index 2ba5613..c2319d2 100644 --- a/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java +++ b/src/main/java/net/knarcraft/stargate/command/ConfigTabCompleter.java @@ -116,13 +116,13 @@ public class ConfigTabCompleter implements TabCompleter { * @param args

The arguments given by the user

* @return

Some or all of the valid values for the option

*/ - @Nullable + @NotNull private List getPossibleStringListOptionValues(@NotNull ConfigOption selectedOption, @NotNull String[] args) { if (selectedOption == ConfigOption.PER_SIGN_COLORS) { return getPerSignColorCompletion(args); } else { - return null; + return new ArrayList<>(); } } diff --git a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java index 2c612e0..cbfcfe6 100644 --- a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java @@ -11,9 +11,8 @@ import java.io.BufferedWriter; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; +import java.util.EnumMap; import java.util.Map; -import java.util.Set; /** * This class is responsible for loading all strings which are translated into several languages @@ -153,11 +152,14 @@ public final class LanguageLoader { //If a key is not found in the language file, add the one in the internal file. Must update the external file if (!internalLanguageValues.keySet().equals(currentLanguageValues.keySet())) { - Map newLanguageValues = new HashMap<>(); + Map newLanguageValues = new EnumMap<>(Message.class); boolean updateNecessary = false; - for (Message key : internalLanguageValues.keySet()) { + for (Map.Entry entry : internalLanguageValues.entrySet()) { + Message key = entry.getKey(); + String value = entry.getValue(); + if (currentLanguageValues.get(key) == null) { - newLanguageValues.put(key, internalLanguageValues.get(key)); + newLanguageValues.put(key, value); //Found at least one value in the internal file not in the external file. Need to update updateNecessary = true; } else { @@ -186,15 +188,15 @@ public final class LanguageLoader { BufferedWriter bufferedWriter = FileHelper.getBufferedWriterFromString(languageFolder + language + ".txt"); //Output normal Language data - for (Message key : languageStrings.keySet()) { - bufferedWriter.write(key + "=" + languageStrings.get(key)); + for (Map.Entry entry : languageStrings.entrySet()) { + bufferedWriter.write(entry.getKey() + "=" + entry.getValue()); bufferedWriter.newLine(); } bufferedWriter.newLine(); //Output any custom language strings the user had if (customLanguageStrings != null) { - for (Message key : customLanguageStrings.keySet()) { - bufferedWriter.write(key + "=" + customLanguageStrings.get(key)); + for (Map.Entry entry : customLanguageStrings.entrySet()) { + bufferedWriter.write(entry.getKey() + "=" + entry.getValue()); bufferedWriter.newLine(); } } @@ -240,25 +242,24 @@ public final class LanguageLoader { */ public void debug() { if (loadedStringTranslations != null) { - Set keys = loadedStringTranslations.keySet(); - for (Message key : keys) { - Stargate.debug("LanguageLoader::Debug::loadedStringTranslations", key + " => " + - loadedStringTranslations.get(key)); + for (Map.Entry entry : loadedStringTranslations.entrySet()) { + Stargate.debug("LanguageLoader::Debug::loadedStringTranslations", entry.getKey() + + " => " + entry.getValue()); } } if (loadedBackupStrings == null) { return; } - Set keys = loadedBackupStrings.keySet(); - for (Message key : keys) { - Stargate.debug("LanguageLoader::Debug::loadedBackupStrings", key + " => " + - loadedBackupStrings.get(key)); + + for (Map.Entry entry : loadedBackupStrings.entrySet()) { + Stargate.debug("LanguageLoader::Debug::loadedBackupStrings", entry.getKey() + " => " + + entry.getValue()); } } @NotNull private Map fromStringMap(@NotNull Map configurationStrings) { - Map output = new HashMap<>(); + Map output = new EnumMap<>(Message.class); for (Map.Entry entry : configurationStrings.entrySet()) { Message message = Message.getFromKey(entry.getKey()); if (message == null) { diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index bf5f663..189b2c7 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -30,6 +30,8 @@ import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * The stargate config is responsible for keeping track of all configuration values @@ -429,10 +431,14 @@ public final class StargateConfig { portalFolder = (String) configOptions.get(ConfigOption.PORTAL_FOLDER); if (portalFolder.isEmpty()) { portalFolder = dataFolderPath + "/portals/"; + } else { + portalFolder = replacePluginFolderPath(portalFolder); } gateFolder = (String) configOptions.get(ConfigOption.GATE_FOLDER); if (gateFolder.isEmpty()) { gateFolder = dataFolderPath + "/gates/"; + } else { + gateFolder = replacePluginFolderPath(gateFolder); } //If users have an outdated config, assume they also need to update their default gates @@ -450,6 +456,23 @@ public final class StargateConfig { Stargate.getInstance().saveConfig(); } + /** + * Replaces "plugins/Stargate" in a folder path, and replaces it with the full path relative to the data folder + * + * @param input

The input string to replace in

+ * @return

The replaced path, or the input if not applicable

+ */ + @NotNull + private String replacePluginFolderPath(@NotNull String input) { + Pattern pattern = Pattern.compile("(?i)^plugins/Stargate"); + Matcher matcher = pattern.matcher(input); + if (matcher.matches()) { + return dataFolderPath + matcher.replaceAll(""); + } else { + return input; + } + } + /** * Gets the object containing configuration values regarding gates * diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 35b53ed..7f8b418 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -254,18 +254,8 @@ public class PlayerEventListener implements Listener { } //Allow players with permissions to apply dye to signs - EquipmentSlot hand = event.getHand(); - if (hand != null && (PermissionHelper.hasPermission(player, "stargate.admin.dye") || - portal.isOwner(player))) { - ItemStack item = player.getInventory().getItem(hand); - if (item != null) { - String itemName = item.getType().toString(); - if (itemName.endsWith("DYE") || itemName.endsWith("INK_SAC")) { - event.setUseInteractedBlock(Event.Result.ALLOW); - Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), portal::drawSign, 1); - return; - } - } + if (dyeSign(event, player, portal)) { + return; } event.setUseInteractedBlock(Event.Result.DENY); @@ -295,6 +285,39 @@ public class PlayerEventListener implements Listener { } } + /** + * Tries to take care of a sign dye interaction + * + * @param event

The triggered player interaction event

+ * @param player

The involved player

+ * @param portal

The involved portal

+ * @return

True if a sign was dyed

+ */ + private boolean dyeSign(@NotNull PlayerInteractEvent event, @NotNull Player player, @NotNull Portal portal) { + EquipmentSlot hand = event.getHand(); + // Check if the player is allowed to dye the sign + if (hand == null || (!PermissionHelper.hasPermission(player, "stargate.admin.dye") && + !portal.isOwner(player))) { + return false; + } + + // Check if the player is holding an item + ItemStack item = player.getInventory().getItem(hand); + if (item == null) { + return false; + } + + String itemName = item.getType().toString(); + // Check if the player's item can be used to dye the sign + if (itemName.endsWith("DYE") || itemName.endsWith("INK_SAC")) { + event.setUseInteractedBlock(Event.Result.ALLOW); + Bukkit.getScheduler().scheduleSyncDelayedTask(Stargate.getInstance(), portal::drawSign, 1); + return true; + } else { + return false; + } + } + /** * Check if a player should be denied from accessing (using) a portal * diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index b7c1e26..b35b978 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -15,6 +15,7 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.vehicle.VehicleMoveEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -92,48 +93,27 @@ public class VehicleEventListener implements Listener { rootEntity = rootEntity.getVehicle(); } List players = TeleportHelper.getPlayers(rootEntity.getPassengers()); - Portal destinationPortal = null; - - for (Player player : players) { - //The entrance portal must be open for one player for the teleportation to happen - if (!entrancePortal.getPortalOpener().isOpenFor(player)) { - continue; - } - - //Check if any of the players has selected the destination - Portal possibleDestinationPortal = entrancePortal.getPortalActivator().getDestination(player); - if (possibleDestinationPortal != null) { - destinationPortal = possibleDestinationPortal; - break; - } - } + Portal destinationPortal = getDestinationPortal(players, entrancePortal); //Cancel the teleport if no players activated the portal, or if any players are denied access - boolean cancelTeleport = false; + boolean cancelTeleportation = false; for (Player player : players) { if (destinationPortal == null) { - cancelTeleport = true; + cancelTeleportation = true; if (!entrancePortal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.INVALID_DESTINATION)); } } else if (!TeleportHelper.playerCanTeleport(player, entrancePortal, destinationPortal)) { - cancelTeleport = true; + cancelTeleportation = true; } } - if (cancelTeleport || destinationPortal == null) { + if (cancelTeleportation || destinationPortal == null) { return; } //Take payment from all players - for (Player player : players) { - //To prevent the case where the first passenger pays and then the second passenger is denied, this has to be - // run after it has been confirmed that all passengers are able to pay - int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal); - if (cost > 0) { - if (EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost)) { - return; - } - } + if (!takePayment(players, entrancePortal, destinationPortal)) { + return; } //Teleport the vehicle and inform the user if the vehicle was teleported @@ -148,4 +128,54 @@ public class VehicleEventListener implements Listener { } } + /** + * Tries to get the destination portal selected by one of the players included in the teleportation + * + * @param players

The players to be teleported

+ * @param entrancePortal

The portal the players are entering

+ * @return

The destination portal, or null if not found

+ */ + @Nullable + private static Portal getDestinationPortal(@NotNull List players, @NotNull Portal entrancePortal) { + for (Player player : players) { + //The entrance portal must be open for one player for the teleportation to happen + if (!entrancePortal.getPortalOpener().isOpenFor(player)) { + continue; + } + + //Check if any of the players has selected the destination + Portal possibleDestinationPortal = entrancePortal.getPortalActivator().getDestination(player); + if (possibleDestinationPortal != null) { + return possibleDestinationPortal; + } + } + + return null; + } + + /** + * Takes payment for the given players + * + * @param players

The players to take payment from

+ * @param entrancePortal

The portal the players are travelling from

+ * @param destinationPortal

The portal the players are travelling to

+ * @return

True if payment was successfully taken, false otherwise

+ */ + private static boolean takePayment(@NotNull List players, @NotNull Portal entrancePortal, + @NotNull Portal destinationPortal) { + for (Player player : players) { + //To prevent the case where the first passenger pays and then the second passenger is denied, this has to be + // run after it has been confirmed that all passengers are able to pay. Also note that some players might + // not have to pay, and thus the cost check has to be in the loop, + int cost = EconomyHelper.getUseCost(player, entrancePortal, destinationPortal); + if (cost > 0) { + if (EconomyHelper.cannotPayTeleportFee(entrancePortal, player, cost)) { + return false; + } + } + } + + return true; + } + } From 9abf6db27a2eacd4a6970edab2ac9cd5538af7d7 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 20 Feb 2024 19:29:27 +0100 Subject: [PATCH 5/8] Alters the RegEx for replacing the plugin folder path --- .../stargate/config/StargateConfig.java | 2 +- .../container/RelativeBlockVector.java | 30 ------------------- .../listener/PlayerEventListener.java | 5 ++-- .../listener/VehicleEventListener.java | 30 ++++++++++++++----- .../net/knarcraft/stargate/portal/Portal.java | 17 +++++------ .../stargate/portal/PortalActivator.java | 4 +-- .../stargate/portal/PortalCreator.java | 5 ++-- .../portal/property/PortalStrings.java | 13 ++++++++ .../stargate/utility/PortalFileHelper.java | 4 ++- 9 files changed, 55 insertions(+), 55 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/portal/property/PortalStrings.java diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 189b2c7..23cb4b7 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -464,7 +464,7 @@ public final class StargateConfig { */ @NotNull private String replacePluginFolderPath(@NotNull String input) { - Pattern pattern = Pattern.compile("(?i)^plugins/Stargate"); + Pattern pattern = Pattern.compile("(?i)^plugins[\\\\\\/]Stargate"); Matcher matcher = pattern.matcher(input); if (matcher.matches()) { return dataFolderPath + matcher.replaceAll(""); diff --git a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java index e06d08e..5f904a5 100644 --- a/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java +++ b/src/main/java/net/knarcraft/stargate/container/RelativeBlockVector.java @@ -64,36 +64,6 @@ public record RelativeBlockVector(int right, int down, int out) { return new RelativeBlockVector(-this.right, -this.down, -this.out); } - /** - * Gets the distance to the right relative to the origin - * - * @return

The distance to the right relative to the origin

- */ - @Override - public int right() { - return right; - } - - /** - * Gets the distance downward relative to the origin - * - * @return

The distance downward relative to the origin

- */ - @Override - public int down() { - return down; - } - - /** - * Gets the distance outward relative to the origin - * - * @return

The distance outward relative to the origin

- */ - @Override - public int out() { - return out; - } - @Override @NotNull public String toString() { diff --git a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java index 7f8b418..04323e3 100644 --- a/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/PlayerEventListener.java @@ -353,7 +353,7 @@ public class PlayerEventListener implements Listener { } //Prevent a double click caused by a Spigot bug - if (clickIsBug(event.getPlayer(), block)) { + if (clickIsBug(event.getPlayer())) { return; } @@ -425,10 +425,9 @@ public class PlayerEventListener implements Listener { * clicking once the bug is fixed.

* * @param player

The player performing the right-click

- * @param block

The block to check

* @return

True if the click is a bug and should be cancelled

*/ - private boolean clickIsBug(@NotNull Player player, @NotNull Block block) { + private boolean clickIsBug(@NotNull Player player) { Long previousEventTime = previousEventTimes.get(player); if (previousEventTime != null && previousEventTime + 50 > System.currentTimeMillis()) { previousEventTimes.put(player, null); diff --git a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java index b35b978..5de125a 100644 --- a/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java +++ b/src/main/java/net/knarcraft/stargate/listener/VehicleEventListener.java @@ -116,16 +116,32 @@ public class VehicleEventListener implements Listener { return; } + // Perform the teleportation + teleportPlayerAndVehicle(players, vehicle, entrancePortal, destinationPortal); + } + + /** + * Performs the teleportation of one or more players in a vehicle + * + * @param players

The players to be teleported

+ * @param vehicle

The vehicle that triggered the teleportation

+ * @param entrancePortal

The portal the player(s) and vehicle entered from

+ * @param destinationPortal

The portal the player(s) and vehicle are teleporting to

+ */ + private static void teleportPlayerAndVehicle(@NotNull List players, @NotNull Vehicle vehicle, + @NotNull Portal entrancePortal, @NotNull Portal destinationPortal) { //Teleport the vehicle and inform the user if the vehicle was teleported boolean teleported = new VehicleTeleporter(destinationPortal, vehicle).teleportEntity(entrancePortal); - if (teleported) { - if (!entrancePortal.getOptions().isSilent()) { - for (Player player : players) { - Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString(Message.TELEPORTED)); - } - } - entrancePortal.getPortalOpener().closePortal(false); + if (!teleported) { + return; } + + if (!entrancePortal.getOptions().isSilent()) { + for (Player player : players) { + Stargate.getMessageSender().sendSuccessMessage(player, Stargate.getString(Message.TELEPORTED)); + } + } + entrancePortal.getPortalOpener().closePortal(false); } /** diff --git a/src/main/java/net/knarcraft/stargate/portal/Portal.java b/src/main/java/net/knarcraft/stargate/portal/Portal.java index 304136e..660106a 100644 --- a/src/main/java/net/knarcraft/stargate/portal/Portal.java +++ b/src/main/java/net/knarcraft/stargate/portal/Portal.java @@ -6,6 +6,7 @@ import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.portal.property.PortalOption; import net.knarcraft.stargate.portal.property.PortalOptions; import net.knarcraft.stargate.portal.property.PortalOwner; +import net.knarcraft.stargate.portal.property.PortalStrings; import net.knarcraft.stargate.portal.property.PortalStructure; import net.knarcraft.stargate.portal.property.gate.Gate; import net.md_5.bungee.api.ChatColor; @@ -41,23 +42,21 @@ public class Portal { * * @param portalLocation

Object containing locations of all relevant blocks

* @param button

The location of the portal's open button

- * @param destination

The destination defined on the sign's destination line. "" for non-fixed gates

- * @param name

The name of the portal defined on the sign's first line

- * @param network

The network the portal belongs to, defined on the sign's third

+ * @param portalStrings

The portal's string values, such as name, network and destination

* @param gate

The gate type to use for this portal

* @param portalOwner

The portal's owner

* @param options

A map containing all possible portal options, with true for the ones enabled

*/ - public Portal(@NotNull PortalLocation portalLocation, @Nullable BlockLocation button, @NotNull String destination, - @NotNull String name, @NotNull String network, @NotNull Gate gate, @NotNull PortalOwner portalOwner, + public Portal(@NotNull PortalLocation portalLocation, @Nullable BlockLocation button, + @NotNull PortalStrings portalStrings, @NotNull Gate gate, @NotNull PortalOwner portalOwner, @NotNull Map options) { this.location = portalLocation; - this.network = network; - this.name = name; + this.network = portalStrings.network(); + this.name = portalStrings.name(); this.portalOwner = portalOwner; - this.options = new PortalOptions(options, destination.length() > 0); + this.options = new PortalOptions(options, portalStrings.destination().length() > 0); this.signDrawer = new PortalSignDrawer(this); - this.portalOpener = new PortalOpener(this, destination); + this.portalOpener = new PortalOpener(this, portalStrings.destination()); this.structure = new PortalStructure(this, gate, button); this.portalActivator = portalOpener.getPortalActivator(); this.cleanName = cleanString(name); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java index 0833f87..4c3e253 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalActivator.java @@ -78,8 +78,8 @@ public class PortalActivator { return null; } //Get one random destination - String destination = ListHelper.getRandom(destinations); - return PortalHandler.getByName(Portal.cleanString(destination), portalNetwork); + String randomDestination = ListHelper.getRandom(destinations); + return PortalHandler.getByName(Portal.cleanString(randomDestination), portalNetwork); } else { //Just return the normal fixed destination return PortalHandler.getByName(Portal.cleanString(destination), portalNetwork); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index c09d17c..942931f 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -9,6 +9,7 @@ import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.portal.property.PortalOption; import net.knarcraft.stargate.portal.property.PortalOptions; import net.knarcraft.stargate.portal.property.PortalOwner; +import net.knarcraft.stargate.portal.property.PortalStrings; import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.portal.property.gate.GateHandler; import net.knarcraft.stargate.utility.DirectionHelper; @@ -167,8 +168,8 @@ public class PortalCreator { } PortalOwner owner = new PortalOwner(player); - this.portal = new Portal(portalLocation, null, destinationName, portalName, network, gate, owner, - portalOptions); + PortalStrings portalStrings = new PortalStrings(portalName, network, destinationName); + this.portal = new Portal(portalLocation, null, portalStrings, gate, owner, portalOptions); return validatePortal(denyMessage, event.getLines(), deny); } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/PortalStrings.java b/src/main/java/net/knarcraft/stargate/portal/property/PortalStrings.java new file mode 100644 index 0000000..839a6e9 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/property/PortalStrings.java @@ -0,0 +1,13 @@ +package net.knarcraft.stargate.portal.property; + +import org.jetbrains.annotations.NotNull; + +/** + * A record of a portal's string values + * + * @param name

The name of the portal

+ * @param network

The name of the network the portal belongs to

+ * @param destination

The name of the portal's destination

+ */ +public record PortalStrings(@NotNull String name, @NotNull String network, @NotNull String destination) { +} diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 98ff915..bfc8d8f 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -10,6 +10,7 @@ import net.knarcraft.stargate.portal.PortalRegistry; import net.knarcraft.stargate.portal.property.PortalLocation; import net.knarcraft.stargate.portal.property.PortalOptions; import net.knarcraft.stargate.portal.property.PortalOwner; +import net.knarcraft.stargate.portal.property.PortalStrings; import net.knarcraft.stargate.portal.property.gate.Gate; import net.knarcraft.stargate.portal.property.gate.GateHandler; import org.bukkit.Bukkit; @@ -286,7 +287,8 @@ public final class PortalFileHelper { PortalOwner owner = new PortalOwner(ownerString); //Create the new portal - Portal portal = new Portal(portalLocation, button, destination, name, network, gate, owner, + PortalStrings portalStrings = new PortalStrings(name, network, destination); + Portal portal = new Portal(portalLocation, button, portalStrings, gate, owner, PortalHandler.getPortalOptions(portalData)); //Register the portal, and close it in case it wasn't properly closed when the server stopped From cde20e35d5d0bf2f8c6cd6b436ba79b538777c9c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 20 Feb 2024 19:45:41 +0100 Subject: [PATCH 6/8] Uses matcher.find instead of matcher.matches Also removes some code smells --- .../stargate/config/StargateConfig.java | 5 ++- .../stargate/utility/GateReader.java | 7 ++-- .../stargate/utility/PermissionHelper.java | 36 ++++++++++++++----- .../stargate/utility/PortalFileHelper.java | 14 ++++---- 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 23cb4b7..de57922 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -434,12 +434,15 @@ public final class StargateConfig { } else { portalFolder = replacePluginFolderPath(portalFolder); } + Stargate.debug("StargateConfig::loadConfig", "Portal folder is " + portalFolder); + gateFolder = (String) configOptions.get(ConfigOption.GATE_FOLDER); if (gateFolder.isEmpty()) { gateFolder = dataFolderPath + "/gates/"; } else { gateFolder = replacePluginFolderPath(gateFolder); } + Stargate.debug("StargateConfig::loadConfig", "Gate folder is " + gateFolder); //If users have an outdated config, assume they also need to update their default gates if (isMigrating) { @@ -466,7 +469,7 @@ public final class StargateConfig { private String replacePluginFolderPath(@NotNull String input) { Pattern pattern = Pattern.compile("(?i)^plugins[\\\\\\/]Stargate"); Matcher matcher = pattern.matcher(input); - if (matcher.matches()) { + if (matcher.find()) { return dataFolderPath + matcher.replaceAll(""); } else { return input; diff --git a/src/main/java/net/knarcraft/stargate/utility/GateReader.java b/src/main/java/net/knarcraft/stargate/utility/GateReader.java index f57c6c0..fc1803a 100644 --- a/src/main/java/net/knarcraft/stargate/utility/GateReader.java +++ b/src/main/java/net/knarcraft/stargate/utility/GateReader.java @@ -4,6 +4,7 @@ import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.config.material.BukkitMaterialSpecifier; import net.knarcraft.stargate.config.material.MaterialSpecifier; import org.bukkit.Material; +import org.bukkit.configuration.InvalidConfigurationException; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -108,11 +109,11 @@ public final class GateReader { * @param line

The line to read

* @param characterMaterialMap

The character to material map to store to

* @param config

The config value map to store to

- * @throws Exception

If an invalid material is encountered

+ * @throws InvalidConfigurationException

If an invalid material is encountered

*/ private static void readGateConfigValue(@NotNull String line, @NotNull Map> characterMaterialMap, - @NotNull Map config) throws Exception { + @NotNull Map config) throws InvalidConfigurationException { String[] split = line.split("="); String key = split[0].trim(); String value = split[1].trim(); @@ -125,7 +126,7 @@ public final class GateReader { if (!materials.isEmpty()) { characterMaterialMap.put(symbol, materials); } else { - throw new Exception("Invalid material in line: " + line); + throw new InvalidConfigurationException("Invalid material in line: " + line); } } else { //Read a normal config value diff --git a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java index ea36003..93c0862 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PermissionHelper.java @@ -53,13 +53,31 @@ public final class PermissionHelper { return; } + // Check if the player is able to open the portal + if (canNotOpen(player, portal, destination)) { + return; + } + + //Open the portal + portal.getPortalOpener().openPortal(player, false); + } + + /** + * Checks whether something prevents the player from opening the given portal to the given destination + * + * @param player

The player trying to open the portal

+ * @param portal

The portal to open

+ * @param destination

The destination the player is attempting to open

+ * @return

True if the player cannot open the portal

+ */ + private static boolean canNotOpen(Player player, Portal portal, Portal destination) { //Deny access if another player has activated the portal, and it's still in use if (!portal.getOptions().isFixed() && portal.getPortalActivator().isActive() && portal.getActivePlayer() != player) { if (!portal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.ACCESS_DENIED)); } - return; + return true; } //Check if the player can use the private gate @@ -67,7 +85,7 @@ public final class PermissionHelper { if (!portal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.ACCESS_DENIED)); } - return; + return true; } //Destination is currently in use by another player, blocking teleportation @@ -75,11 +93,10 @@ public final class PermissionHelper { if (!portal.getOptions().isSilent()) { Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.DESTINATION_BLOCKED)); } - return; + return true; } - //Open the portal - portal.getPortalOpener().openPortal(player, false); + return false; } /** @@ -109,26 +126,27 @@ public final class PermissionHelper { public static boolean cannotAccessPortal(@NotNull Player player, @NotNull Portal entrancePortal, @Nullable Portal destination) { boolean deny = false; + String route = "PermissionHelper::cannotAccessPortal"; if (entrancePortal.getOptions().isBungee()) { if (!PermissionHelper.canAccessServer(player, entrancePortal.getCleanNetwork())) { //If the portal is a bungee portal, and the player cannot access the server, deny - Stargate.debug("cannotAccessPortal", "Cannot access server"); + Stargate.debug(route, "Cannot access server"); deny = true; } } else if (PermissionHelper.cannotAccessNetwork(player, entrancePortal.getCleanNetwork())) { //If the player does not have access to the network, deny - Stargate.debug("cannotAccessPortal", "Cannot access network"); + Stargate.debug(route, "Cannot access network"); deny = true; } else { if (destination == null) { //If there is no destination, deny - Stargate.debug("cannotAccessPortal", "Portal has no destination"); + Stargate.debug(route, "Portal has no destination"); deny = true; } else if (destination.getWorld() != null && PermissionHelper.cannotAccessWorld(player, destination.getWorld().getName())) { //If the player does not have access to the portal's world, deny - Stargate.debug("cannotAccessPortal", "Cannot access world"); + Stargate.debug(route, "Cannot access world"); deny = true; } } diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index bfc8d8f..0fd620d 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -59,14 +59,14 @@ public final class PortalFileHelper { if (portal.getWorld() == null) { Stargate.logSevere(String.format("Could not save portal %s because its world is null", portal.getName())); - continue; + } else { + String worldName = portal.getWorld().getName(); + if (!worldName.equalsIgnoreCase(world.getName())) { + continue; + } + //Save the portal + savePortal(bufferedWriter, portal); } - String worldName = portal.getWorld().getName(); - if (!worldName.equalsIgnoreCase(world.getName())) { - continue; - } - //Save the portal - savePortal(bufferedWriter, portal); } bufferedWriter.close(); From 9abf60bb31d7081121d4eecda62b40e15bd1567e Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 20 Feb 2024 20:48:29 +0100 Subject: [PATCH 7/8] Reduces some code complexity --- .../stargate/config/StargateConfig.java | 2 +- .../stargate/portal/PortalCreator.java | 123 ++++++++++++------ .../stargate/portal/PortalHandler.java | 70 ++++++---- .../stargate/portal/PortalRegistry.java | 58 +++++---- .../stargate/portal/property/gate/Gate.java | 19 +-- .../portal/property/gate/GateCosts.java | 12 ++ .../portal/property/gate/GateHandler.java | 13 +- .../portal/teleporter/Teleporter.java | 2 +- 8 files changed, 190 insertions(+), 109 deletions(-) create mode 100644 src/main/java/net/knarcraft/stargate/portal/property/gate/GateCosts.java diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index de57922..7a0004d 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -467,7 +467,7 @@ public final class StargateConfig { */ @NotNull private String replacePluginFolderPath(@NotNull String input) { - Pattern pattern = Pattern.compile("(?i)^plugins[\\\\\\/]Stargate"); + Pattern pattern = Pattern.compile("(?i)^plugins[\\\\/]Stargate"); Matcher matcher = pattern.matcher(input); if (matcher.find()) { return dataFolderPath + matcher.replaceAll(""); diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index 942931f..fb1cc65 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -79,6 +79,8 @@ public class PortalCreator { String network = PortalHandler.filterName(event.getLine(2)); String options = PortalHandler.filterName(event.getLine(3)).toLowerCase(); + PortalStrings portalStrings = new PortalStrings(portalName, network, destinationName); + //Get portal options available to the player creating the portal Map portalOptions = PortalHandler.getPortalOptions(player, destinationName, options); @@ -94,6 +96,12 @@ public class PortalCreator { Stargate.debug("createPortal", "Finished getting all portal info"); + return createPortal(portalStrings, portalOptions, yaw, portalLocation); + } + + @Nullable + private Portal createPortal(@NotNull PortalStrings portalStrings, @NotNull Map portalOptions, + float yaw, @NotNull PortalLocation portalLocation) { //Try and find a gate matching the new portal Gate gate = PortalHandler.findMatchingGate(portalLocation, player.getWorld()); if ((gate == null) || (portalLocation.getButtonVector() == null)) { @@ -102,7 +110,8 @@ public class PortalCreator { } //If the portal is a bungee portal and invalid, abort here - if (!PortalHandler.isValidBungeePortal(portalOptions, player, destinationName, network)) { + if (!PortalHandler.isValidBungeePortal(portalOptions, player, portalStrings.destination(), + portalStrings.network())) { Stargate.debug("createPortal", "Portal is an invalid bungee portal"); return null; } @@ -114,51 +123,27 @@ public class PortalCreator { } Stargate.debug("createPortal", builder.toString()); - //Use default network if a proper alternative is not set - if (!portalOptions.get(PortalOption.BUNGEE) && (network.length() < 1 || network.length() > - getMaxNameNetworkLength())) { - network = Stargate.getDefaultNetwork(); - } - boolean deny = false; String denyMessage = ""; - //Check if the player can create portals on this network. If not, create a personal portal - if (!portalOptions.get(PortalOption.BUNGEE) && !PermissionHelper.canCreateNetworkGate(player, network)) { - Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); - if (PermissionHelper.canCreatePersonalPortal(player)) { - network = player.getName(); - if (network.length() > getMaxNameNetworkLength()) { - network = network.substring(0, getMaxNameNetworkLength()); - } - Stargate.debug("createPortal", "Creating personal portal"); - Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_PERSONAL)); - } else { - Stargate.debug("createPortal", "Player does not have access to network"); + if (!portalOptions.get(PortalOption.BUNGEE)) { + String networkName = getNetworkName(portalStrings); + if (networkName == null) { deny = true; denyMessage = Stargate.getString(Message.CREATION_NETWORK_DENIED); + } else { + portalStrings = new PortalStrings(portalStrings.name(), networkName, portalStrings.destination()); } } - //Check if the player can create this gate layout - String gateName = gate.getFilename(); - gateName = gateName.substring(0, gateName.indexOf('.')); - if (!deny && !PermissionHelper.canCreatePortal(player, gateName)) { - Stargate.debug("createPortal", "Player does not have access to gate layout"); - deny = true; - denyMessage = Stargate.getString(Message.CREATION_GATE_DENIED); - } - - //Check if the user can create portals to this world. - if (!portalOptions.get(PortalOption.BUNGEE) && !deny && destinationName.length() > 0) { - Portal portal = PortalHandler.getByName(destinationName, network); - if (portal != null && portal.getWorld() != null) { - String world = portal.getWorld().getName(); - if (PermissionHelper.cannotAccessWorld(player, world)) { - Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); - deny = true; - denyMessage = Stargate.getString(Message.CREATION_WORLD_DENIED); - } + // Check whether the player can create a portal with the specified gate in the specified world + if (!deny) { + denyMessage = canCreatePortal(portalOptions.get(PortalOption.BUNGEE), portalStrings.network(), gate, + portalStrings.destination()); + if (denyMessage != null) { + deny = true; + } else { + denyMessage = ""; } } @@ -168,11 +153,71 @@ public class PortalCreator { } PortalOwner owner = new PortalOwner(player); - PortalStrings portalStrings = new PortalStrings(portalName, network, destinationName); this.portal = new Portal(portalLocation, null, portalStrings, gate, owner, portalOptions); return validatePortal(denyMessage, event.getLines(), deny); } + /** + * Gets the network name to use for the new portal + * + * @param portalStrings

The string values for the new portal

+ * @return

The new network name, or null if the player does not have the necessary permission for any networks

+ */ + @Nullable + private String getNetworkName(@NotNull PortalStrings portalStrings) { + String network = portalStrings.network(); + + //Use default network if a proper alternative is not set + if (portalStrings.network().length() < 1 || portalStrings.network().length() > getMaxNameNetworkLength()) { + network = Stargate.getDefaultNetwork(); + } + + //Check if the player can create portals on this network. If not, create a personal portal + if (!PermissionHelper.canCreateNetworkGate(player, network)) { + Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); + if (PermissionHelper.canCreatePersonalPortal(player)) { + network = player.getName(); + if (network.length() > getMaxNameNetworkLength()) { + network = network.substring(0, getMaxNameNetworkLength()); + } + Stargate.debug("createPortal", "Creating personal portal"); + Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_PERSONAL)); + return network; + } else { + Stargate.debug("createPortal", "Player does not have access to network"); + return null; + } + } + + return network; + } + + @Nullable + private String canCreatePortal(boolean bungee, @NotNull String network, + @NotNull Gate gate, @NotNull String destinationName) { + //Check if the player can create this gate layout + String gateName = gate.getFilename(); + gateName = gateName.substring(0, gateName.indexOf('.')); + if (!PermissionHelper.canCreatePortal(player, gateName)) { + Stargate.debug("createPortal", "Player does not have access to gate layout"); + return Stargate.getString(Message.CREATION_GATE_DENIED); + } + + //Check if the user can create portals to this world. + if (!bungee && destinationName.length() > 0) { + Portal portal = PortalHandler.getByName(destinationName, network); + if (portal != null && portal.getWorld() != null) { + String world = portal.getWorld().getName(); + if (PermissionHelper.cannotAccessWorld(player, world)) { + Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); + return Stargate.getString(Message.CREATION_WORLD_DENIED); + } + } + } + + return null; + } + /** * Validates the newly created portal assigned to this portal validator * diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java index 9f57fc7..e0cfdd0 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalHandler.java @@ -80,40 +80,54 @@ public class PortalHandler { if (portal == null) { continue; } - //Check if destination is a random portal - if (portal.getOptions().isRandom()) { - continue; - } - //Check if destination is always open (Don't show if so) - if (portal.getOptions().isAlwaysOn() && !portal.getOptions().isShown()) { - continue; - } - //Check if destination is this portal - if (destination.equals(entrancePortal.getCleanName())) { - continue; - } - //Check if destination is a fixed portal not pointing to this portal - if (portal.getOptions().isFixed() && - !Portal.cleanString(portal.getDestinationName()).equals(entrancePortal.getCleanName())) { - continue; - } - //Allow random use by non-players (Minecarts) - if (player == null) { - destinations.add(portal.getName()); - continue; - } - //Check if this player can access the destination world - if (portal.getWorld() != null && PermissionHelper.cannotAccessWorld(player, portal.getWorld().getName())) { - continue; - } - //The portal is visible to the player - if (PermissionHelper.canSeePortal(player, portal)) { + + if (isDestinationAvailable(entrancePortal, portal, player)) { destinations.add(portal.getName()); } } return destinations; } + /** + * Checks whether the given destination is available to the given player + * + * @param entrancePortal

The portal the player has activated

+ * @param destinationPortal

The destination portal to check if is valid

+ * @param player

The player trying to attempt the destination

+ * @return

True if the destination is available

+ */ + private static boolean isDestinationAvailable(@NotNull Portal entrancePortal, @NotNull Portal destinationPortal, + @Nullable Player player) { + //Check if destination is a random portal + if (destinationPortal.getOptions().isRandom()) { + return false; + } + //Check if destination is always open (Don't show if so) + if (destinationPortal.getOptions().isAlwaysOn() && !destinationPortal.getOptions().isShown()) { + return false; + } + //Check if destination is this portal + if (destinationPortal.equals(entrancePortal)) { + return false; + } + //Check if destination is a fixed portal not pointing to this portal + if (destinationPortal.getOptions().isFixed() && + !Portal.cleanString(destinationPortal.getDestinationName()).equals(entrancePortal.getCleanName())) { + return false; + } + //Allow random use by non-players (Minecarts) + if (player == null) { + return true; + } + //Check if this player can access the destination world + if (destinationPortal.getWorld() != null && PermissionHelper.cannotAccessWorld(player, + destinationPortal.getWorld().getName())) { + return false; + } + //The portal is visible to the player + return PermissionHelper.canSeePortal(player, destinationPortal); + } + /** * Registers a portal * diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java index ac0d016..f2def13 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalRegistry.java @@ -178,30 +178,7 @@ public class PortalRegistry { String portalName = portal.getCleanName(); String networkName = portal.getCleanNetwork(); - //Remove portal from lookup blocks - for (BlockLocation block : portal.getStructure().getFrame()) { - lookupBlocks.remove(block); - } - - //Remove registered info about the lookup controls and blocks - lookupBlocks.remove(portal.getSignLocation()); - lookupControls.remove(portal.getSignLocation()); - - BlockLocation button = portal.getStructure().getButton(); - if (button != null) { - lookupBlocks.remove(button); - lookupControls.remove(button); - } - - //Remove entrances - for (BlockLocation entrance : portal.getStructure().getEntrances()) { - lookupEntrances.remove(entrance); - } - - //Remove the portal from the list of all portals - if (removeAll) { - allPortals.remove(portal); - } + clearLookupMaps(portal, removeAll); if (portal.getOptions().isBungee()) { //Remove the bungee listing @@ -239,6 +216,39 @@ public class PortalRegistry { DynmapManager.removePortalMarker(portal); } + /** + * Clears the given portal's presence from lookup maps + * + * @param portal

The portal to clear

+ * @param removeAll

Whether to remove the portal from the list of all portals

+ */ + private static void clearLookupMaps(@NotNull Portal portal, boolean removeAll) { + //Remove portal from lookup blocks + for (BlockLocation block : portal.getStructure().getFrame()) { + lookupBlocks.remove(block); + } + + //Remove registered info about the lookup controls and blocks + lookupBlocks.remove(portal.getSignLocation()); + lookupControls.remove(portal.getSignLocation()); + + BlockLocation button = portal.getStructure().getButton(); + if (button != null) { + lookupBlocks.remove(button); + lookupControls.remove(button); + } + + //Remove entrances + for (BlockLocation entrance : portal.getStructure().getEntrances()) { + lookupEntrances.remove(entrance); + } + + //Remove the portal from the list of all portals + if (removeAll) { + allPortals.remove(portal); + } + } + /** * Registers a portal * diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java index efcfc30..f405f11 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java @@ -49,27 +49,23 @@ public class Gate { * @param portalOpenMaterials

The material to set the opening to when the portal is open

* @param portalClosedMaterials

The material to set the opening to when the portal is closed

* @param portalButtonMaterials

The material to use for the portal button

- * @param useCost

The cost of using a portal with this gate layout (-1 to disable)

- * @param createCost

The cost of creating a portal with this gate layout (-1 to disable)

- * @param destroyCost

The cost of destroying a portal with this gate layout (-1 to disable)

- * @param toOwner

Whether any payment should go to the owner of the gate, as opposed to just disappearing

+ * @param gateCosts

The costs and other economy information for the gate

*/ public Gate(@NotNull String filename, @NotNull GateLayout layout, @NotNull Map> characterMaterialsMap, @NotNull List portalOpenMaterials, @NotNull List portalClosedMaterials, - @NotNull List portalButtonMaterials, int useCost, int createCost, int destroyCost, - boolean toOwner) { + @NotNull List portalButtonMaterials, @NotNull GateCosts gateCosts) { this.filename = filename; this.layout = layout; this.characterMaterialMap = characterMaterialsMap; this.portalOpenMaterials = portalOpenMaterials; this.portalClosedMaterials = portalClosedMaterials; this.portalButtonMaterials = portalButtonMaterials; - this.useCost = useCost; - this.createCost = createCost; - this.destroyCost = destroyCost; - this.toOwner = toOwner; + this.useCost = gateCosts.useCost(); + this.createCost = gateCosts.createCost(); + this.destroyCost = gateCosts.destroyCost(); + this.toOwner = gateCosts.toOwner(); } /** @@ -226,7 +222,6 @@ public class Gate { * @return

True if all border blocks of the gate match the layout

*/ private boolean verifyGateBorderMatches(@NotNull BlockLocation topLeft, double yaw) { - Map> characterMaterialMap = new HashMap<>(this.characterMaterialMap); for (RelativeBlockVector borderVector : layout.getBorder()) { int rowIndex = borderVector.right(); int lineIndex = borderVector.down(); @@ -246,7 +241,7 @@ public class Gate { * recognized, but still allowed in previous checks, verify the gate as long as all such instances of * the character correspond to the same material in the physical gate. All subsequent gates will also * need to match the first verified gate. */ - characterMaterialMap.put(key, List.of(new BukkitMaterialSpecifier(materialAtLocation))); + this.characterMaterialMap.put(key, List.of(new BukkitMaterialSpecifier(materialAtLocation))); Stargate.debug("Gate::Matches", String.format("Missing layout material in %s. Using %s from the" + " physical portal.", getFilename(), materialAtLocation)); } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateCosts.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateCosts.java new file mode 100644 index 0000000..93a224d --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateCosts.java @@ -0,0 +1,12 @@ +package net.knarcraft.stargate.portal.property.gate; + +/** + * The costs assigned to a gate + * + * @param useCost

The cost for using (entering) the gate

+ * @param createCost

The cost for creating a portal with the gate type

+ * @param destroyCost

The cost for destroying a portal with the gate type

+ * @param toOwner

Whether the use cost is paid to the gate's owner

+ */ +public record GateCosts(int useCost, int createCost, int destroyCost, boolean toOwner) { +} diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java index 7a26ef4..87e491c 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java @@ -115,11 +115,15 @@ public class GateHandler { @Nullable private static Gate loadGate(@NotNull File file) { try (Scanner scanner = new Scanner(file)) { - return loadGate(file.getName(), file.getParent(), scanner); + Gate gate = loadGate(file.getName(), file.getParent(), scanner); + if (gate != null) { + return gate; + } } catch (Exception exception) { Stargate.logSevere(String.format("Could not load Gate %s - %s", file.getName(), exception.getMessage())); - return null; } + + return null; } /** @@ -184,10 +188,11 @@ public class GateHandler { int destroyCost = readGateConfig(config, fileName, "destroycost"); boolean toOwner = (config.containsKey("toowner") ? Boolean.parseBoolean(config.get("toowner")) : Stargate.getEconomyConfig().sendPaymentToOwner()); + GateCosts gateCosts = new GateCosts(useCost, createCost, destroyCost, toOwner); //Create the new gate - Gate gate = new Gate(fileName, new GateLayout(layout), characterMaterialMap, portalOpenBlock, - portalClosedBlock, portalButton, useCost, createCost, destroyCost, toOwner); + Gate gate = new Gate(fileName, new GateLayout(layout), characterMaterialMap, portalOpenBlock, portalClosedBlock, + portalButton, gateCosts); if (!validateGate(gate, fileName)) { return null; diff --git a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java index 3322b4d..9894d6b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java +++ b/src/main/java/net/knarcraft/stargate/portal/teleporter/Teleporter.java @@ -57,7 +57,7 @@ public abstract class Teleporter { * @param portal

The portal which is the target of the teleportation

* @param teleportedEntity

The entity teleported by this teleporter

*/ - public Teleporter(@NotNull Portal portal, @NotNull Entity teleportedEntity) { + protected Teleporter(@NotNull Portal portal, @NotNull Entity teleportedEntity) { this.portal = portal; this.scheduler = Stargate.getInstance().getServer().getScheduler(); this.teleportedEntity = teleportedEntity; From c03b3fc6b003486da5210ae3a0a050c2e214b6e4 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 20 Feb 2024 22:48:36 +0100 Subject: [PATCH 8/8] Removes some redundancy in createPortal --- .../stargate/portal/PortalCreator.java | 46 +++++++++++-------- .../portal/property/gate/GateHandler.java | 8 +--- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java index fb1cc65..cdfffd4 100644 --- a/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java +++ b/src/main/java/net/knarcraft/stargate/portal/PortalCreator.java @@ -58,18 +58,19 @@ public class PortalCreator { */ @Nullable public Portal createPortal() { + String route = "PortalCreator::createPortal"; BlockLocation signLocation = new BlockLocation(event.getBlock()); Block signControlBlock = signLocation.getParent(); //Return early if the sign is not placed on a block, or the block is not a control block if (signControlBlock == null || GateHandler.getGatesByControlBlock(signControlBlock).isEmpty()) { - Stargate.debug("createPortal", "Control block not registered"); + Stargate.debug(route, "Control block not registered"); return null; } //The control block is already part of another portal if (PortalHandler.getByBlock(signControlBlock) != null) { - Stargate.debug("createPortal", "idParent belongs to existing stargate"); + Stargate.debug(route, "idParent belongs to existing stargate"); return null; } @@ -94,7 +95,7 @@ public class PortalCreator { PortalLocation portalLocation = new PortalLocation(); portalLocation.setButtonFacing(buttonFacing).setYaw(yaw).setSignLocation(signLocation); - Stargate.debug("createPortal", "Finished getting all portal info"); + Stargate.debug(route, "Finished getting all portal info"); return createPortal(portalStrings, portalOptions, yaw, portalLocation); } @@ -102,17 +103,18 @@ public class PortalCreator { @Nullable private Portal createPortal(@NotNull PortalStrings portalStrings, @NotNull Map portalOptions, float yaw, @NotNull PortalLocation portalLocation) { + String route = "PortalCreator::createPortal"; //Try and find a gate matching the new portal Gate gate = PortalHandler.findMatchingGate(portalLocation, player.getWorld()); if ((gate == null) || (portalLocation.getButtonVector() == null)) { - Stargate.debug("createPortal", "Could not find matching gate layout"); + Stargate.debug(route, "Could not find matching gate layout"); return null; } //If the portal is a bungee portal and invalid, abort here if (!PortalHandler.isValidBungeePortal(portalOptions, player, portalStrings.destination(), portalStrings.network())) { - Stargate.debug("createPortal", "Portal is an invalid bungee portal"); + Stargate.debug(route, "Portal is an invalid bungee portal"); return null; } @@ -121,12 +123,12 @@ public class PortalCreator { for (PortalOption option : portalOptions.keySet()) { builder.append(option.getCharacterRepresentation()).append(" = ").append(portalOptions.get(option)).append(" "); } - Stargate.debug("createPortal", builder.toString()); + Stargate.debug(route, builder.toString()); boolean deny = false; String denyMessage = ""; - if (!portalOptions.get(PortalOption.BUNGEE)) { + if (!(boolean) portalOptions.get(PortalOption.BUNGEE)) { String networkName = getNetworkName(portalStrings); if (networkName == null) { deny = true; @@ -166,6 +168,7 @@ public class PortalCreator { @Nullable private String getNetworkName(@NotNull PortalStrings portalStrings) { String network = portalStrings.network(); + String route = "PortalCreator::getNetworkName"; //Use default network if a proper alternative is not set if (portalStrings.network().length() < 1 || portalStrings.network().length() > getMaxNameNetworkLength()) { @@ -174,17 +177,17 @@ public class PortalCreator { //Check if the player can create portals on this network. If not, create a personal portal if (!PermissionHelper.canCreateNetworkGate(player, network)) { - Stargate.debug("createPortal", "Player doesn't have create permissions on network. Trying personal"); + Stargate.debug(route, "Player doesn't have create permissions on network. Trying personal"); if (PermissionHelper.canCreatePersonalPortal(player)) { network = player.getName(); if (network.length() > getMaxNameNetworkLength()) { network = network.substring(0, getMaxNameNetworkLength()); } - Stargate.debug("createPortal", "Creating personal portal"); + Stargate.debug(route, "Creating personal portal"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_PERSONAL)); return network; } else { - Stargate.debug("createPortal", "Player does not have access to network"); + Stargate.debug(route, "Player does not have access to network"); return null; } } @@ -199,17 +202,17 @@ public class PortalCreator { String gateName = gate.getFilename(); gateName = gateName.substring(0, gateName.indexOf('.')); if (!PermissionHelper.canCreatePortal(player, gateName)) { - Stargate.debug("createPortal", "Player does not have access to gate layout"); + Stargate.debug("PortalCreator::canCreatePortal", "Player does not have access to gate layout"); return Stargate.getString(Message.CREATION_GATE_DENIED); } //Check if the user can create portals to this world. if (!bungee && destinationName.length() > 0) { - Portal portal = PortalHandler.getByName(destinationName, network); - if (portal != null && portal.getWorld() != null) { - String world = portal.getWorld().getName(); + Portal destinationPortal = PortalHandler.getByName(destinationName, network); + if (destinationPortal != null && destinationPortal.getWorld() != null) { + String world = destinationPortal.getWorld().getName(); if (PermissionHelper.cannotAccessWorld(player, world)) { - Stargate.debug("canCreateNetworkGate", "Player does not have access to destination world"); + Stargate.debug("PortalCreator::canCreatePortal", "Player does not have access to destination world"); return Stargate.getString(Message.CREATION_WORLD_DENIED); } } @@ -288,9 +291,11 @@ public class PortalCreator { * @return

True if the portal is completely valid

*/ private boolean checkIfNewPortalIsValid(int cost, @NotNull String portalName) { + String route = "PortalCreator::checkIfNewPortalIsValid"; + //Check if the portal name can fit on the sign with padding (>name<) if (portal.getCleanName().length() < 1 || portal.getCleanName().length() > getMaxNameNetworkLength()) { - Stargate.debug("createPortal", String.format("Name length error. %s is too long.", + Stargate.debug(route, String.format("Name length error. %s is too long.", portal.getCleanName())); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_NAME_LENGTH)); return false; @@ -299,14 +304,14 @@ public class PortalCreator { if (portal.getOptions().isBungee()) { //Check if the bungee portal's name has been duplicated if (PortalHandler.getBungeePortals().get(portal.getCleanName()) != null) { - Stargate.debug("createPortal::Bungee", "Gate name duplicate"); + Stargate.debug(route, "Gate name duplicate"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_NAME_COLLISION)); return false; } } else { //Check if the portal name has been duplicated on the network if (PortalHandler.getByName(portal.getCleanName(), portal.getCleanNetwork()) != null) { - Stargate.debug("createPortal", "Gate name duplicate"); + Stargate.debug(route, "Gate name duplicate"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_NAME_COLLISION)); return false; } @@ -324,7 +329,7 @@ public class PortalCreator { //Deduct the required fee from the player if (!EconomyHelper.chargePlayerIfNecessary(player, cost)) { EconomyHelper.sendInsufficientFundsMessage(portalName, player, cost); - Stargate.debug("createPortal", "Insufficient Funds"); + Stargate.debug(route, "Insufficient Funds"); return false; } else { EconomyHelper.sendDeductMessage(portalName, player, cost); @@ -377,7 +382,8 @@ public class PortalCreator { for (RelativeBlockVector borderVector : gate.getLayout().getBorder()) { BlockLocation borderBlockLocation = topLeft.getRelativeLocation(borderVector, yaw); if (PortalHandler.getByBlock(borderBlockLocation.getBlock()) != null) { - Stargate.debug("createPortal", "Gate conflicts with existing gate"); + Stargate.debug("PortalCreator::conflictsWithExistingPortal", + "Gate conflicts with existing gate"); Stargate.getMessageSender().sendErrorMessage(player, Stargate.getString(Message.CREATION_CONFLICT)); return true; } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java index 87e491c..6218b75 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java @@ -115,15 +115,11 @@ public class GateHandler { @Nullable private static Gate loadGate(@NotNull File file) { try (Scanner scanner = new Scanner(file)) { - Gate gate = loadGate(file.getName(), file.getParent(), scanner); - if (gate != null) { - return gate; - } + return loadGate(file.getName(), file.getParent(), scanner); } catch (Exception exception) { Stargate.logSevere(String.format("Could not load Gate %s - %s", file.getName(), exception.getMessage())); + return null; } - - return null; } /**