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; + } + }