diff --git a/pom.xml b/pom.xml index 3c7a417c..b8e871ba 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 dev.espi protectionstones - 2.10.6 + 2.10.7 ProtectionStones A grief prevention plugin for Spigot Minecraft servers. https://github.com/espidev/ProtectionStones @@ -14,25 +14,25 @@ - - GPLv3 - https://www.gnu.org/licenses/gpl-3.0.en.html - + + GPLv3 + https://www.gnu.org/licenses/gpl-3.0.en.html + - - Devin Lin - espidev@gmail.com - EstiNet - https://estinet.net - + + Devin Lin + espidev@gmail.com + EstiNet + https://estinet.net + - scm:git:git://github.com/espidev/ProtectionStones.git - scm:git:ssh://github.com:espidev/ProtectionStones.git - https://github.com/espidev/ProtectionStones/tree/master + scm:git:git://github.com/espidev/ProtectionStones.git + scm:git:ssh://github.com:espidev/ProtectionStones.git + https://github.com/espidev/ProtectionStones/tree/master @@ -89,8 +89,8 @@ 3.1 - 16 - 16 + 21 + 21 ${project.build.sourceEncoding} @@ -107,13 +107,18 @@ org.apache.maven.plugins maven-shade-plugin - 3.3.0 + 3.5.0 - true + false + false org.bstats - dev.espi.protectionstones + dev.espi.protectionstones.bstats + + + net.kyori + dev.espi.protectionstones.lib.kyori @@ -201,7 +206,7 @@ org.bstats bstats-bukkit - 3.0.2 + 3.1.0 compile @@ -272,5 +277,15 @@ json-simple 1.1.1 + + net.kyori + adventure-text-minimessage + 4.17.0 + + + net.kyori + adventure-platform-bukkit + 4.3.3 + diff --git a/src/main/java/dev/espi/protectionstones/FlagHandler.java b/src/main/java/dev/espi/protectionstones/FlagHandler.java index 28e46b20..3f6d6e3c 100644 --- a/src/main/java/dev/espi/protectionstones/FlagHandler.java +++ b/src/main/java/dev/espi/protectionstones/FlagHandler.java @@ -41,15 +41,20 @@ public class FlagHandler { // Custom WorldGuard Flags public static final Flag GREET_ACTION = new StringFlag("greeting-action"); public static final Flag FAREWELL_ACTION = new StringFlag("farewell-action"); + public static final Flag PS_GREETING = new StringFlag("ps-greeting"); + public static final Flag PS_FAREWELL = new StringFlag("ps-farewell"); // Custom WorldGuard Flags used by ProtectionStones // Added to blocks on BlockPlaceEvent Listener - // When adding flags, you may want to add them to the hidden_flags_from_info config option list + // When adding flags, you may want to add them to the hidden_flags_from_info + // config option list public static final Flag PS_HOME = new StringFlag("ps-home"); public static final Flag PS_BLOCK_MATERIAL = new StringFlag("ps-block-material"); public static final Flag PS_NAME = new StringFlag("ps-name"); - public static final Flag> PS_MERGED_REGIONS = new SetFlag<>("ps-merged-regions", new StringFlag("ps-merged-region")); - public static final Flag> PS_MERGED_REGIONS_TYPES = new SetFlag<>("ps-merged-regions-types", new StringFlag("ps-merged-region-type")); // each entry: "[psID] [type]" + public static final Flag> PS_MERGED_REGIONS = new SetFlag<>("ps-merged-regions", + new StringFlag("ps-merged-region")); + public static final Flag> PS_MERGED_REGIONS_TYPES = new SetFlag<>("ps-merged-regions-types", + new StringFlag("ps-merged-region-type")); // each entry: "[psID] [type]" public static final Flag PS_LANDLORD = new StringFlag("ps-landlord"); public static final Flag PS_TENANT = new StringFlag("ps-tenant"); @@ -57,9 +62,12 @@ public class FlagHandler { public static final Flag PS_PRICE = new DoubleFlag("ps-price"); public static final Flag PS_RENT_LAST_PAID = new DoubleFlag("ps-rent-last-paid"); public static final Flag PS_FOR_SALE = new BooleanFlag("ps-for-sale"); - public static final Flag> PS_RENT_SETTINGS = new SetFlag<>("ps-rent-settings", new StringFlag("ps-rent-setting")); // TODO - public static final Flag> PS_TAX_PAYMENTS_DUE = new SetFlag<>("ps-tax-payments-due", new StringFlag("ps-tax-payment")); - public static final Flag> PS_TAX_LAST_PAYMENT_ADDED = new SetFlag<>("ps-tax-last-payment-added", new StringFlag("ps-tax-last-payment-entry")); + public static final Flag> PS_RENT_SETTINGS = new SetFlag<>("ps-rent-settings", + new StringFlag("ps-rent-setting")); // TODO + public static final Flag> PS_TAX_PAYMENTS_DUE = new SetFlag<>("ps-tax-payments-due", + new StringFlag("ps-tax-payment")); + public static final Flag> PS_TAX_LAST_PAYMENT_ADDED = new SetFlag<>("ps-tax-last-payment-added", + new StringFlag("ps-tax-last-payment-entry")); public static final Flag PS_TAX_AUTOPAYER = new StringFlag("ps-tax-autopayer"); // called on initial start @@ -83,7 +91,8 @@ static void registerFlags() { registry.register(PS_TAX_LAST_PAYMENT_ADDED); registry.register(PS_TAX_AUTOPAYER); } catch (FlagConflictException e) { - Bukkit.getLogger().severe("Flag conflict found! The plugin will not work properly! Please contact the developers of the plugin."); + Bukkit.getLogger().severe( + "Flag conflict found! The plugin will not work properly! Please contact the developers of the plugin."); e.printStackTrace(); } @@ -91,6 +100,8 @@ static void registerFlags() { try { registry.register(GREET_ACTION); registry.register(FAREWELL_ACTION); + registry.register(PS_GREETING); + registry.register(PS_FAREWELL); } catch (FlagConflictException ignored) { // ignore if flag conflict } @@ -98,8 +109,15 @@ static void registerFlags() { static void registerHandlers() { SessionManager sessionManager = WorldGuard.getInstance().getPlatform().getSessionManager(); - sessionManager.registerHandler(GreetingFlagHandler.FACTORY, ExitFlag.FACTORY); - sessionManager.registerHandler(FarewellFlagHandler.FACTORY, ExitFlag.FACTORY); + sessionManager.registerHandler( + new dev.espi.protectionstones.flags.PSMessageFlagHandler.Factory(GREET_ACTION, true), ExitFlag.FACTORY); + sessionManager.registerHandler( + new dev.espi.protectionstones.flags.PSMessageFlagHandler.Factory(FAREWELL_ACTION, true), + ExitFlag.FACTORY); + sessionManager.registerHandler( + new dev.espi.protectionstones.flags.PSMessageFlagHandler.Factory(PS_GREETING, false), ExitFlag.FACTORY); + sessionManager.registerHandler( + new dev.espi.protectionstones.flags.PSMessageFlagHandler.Factory(PS_FAREWELL, false), ExitFlag.FACTORY); } // adds flag permissions for ALL registered WorldGuard flags @@ -123,12 +141,14 @@ static void initCustomFlagsForPS(ProtectedRegion region, Location l, PSProtectBl } public static List getPlayerPlaceholderFlags() { - return Arrays.asList("greeting", "greeting-title", "greeting-action", "farewell", "farewell-title", "farewell-action"); + return Arrays.asList("greeting", "greeting-title", "greeting-action", "farewell", "farewell-title", + "farewell-action", "ps-greeting", "ps-farewell"); } // Edit flags that require placeholders (variables) public static void initDefaultFlagPlaceholders(HashMap, Object> flags, Player p) { - for (Flag f : getPlayerPlaceholderFlags().stream().map(WGUtils.getFlagRegistry()::get).collect(Collectors.toList())) { + for (Flag f : getPlayerPlaceholderFlags().stream().map(WGUtils.getFlagRegistry()::get) + .collect(Collectors.toList())) { if (flags.get(f) != null) { String s = (String) flags.get(f); @@ -153,7 +173,8 @@ static void initDefaultFlagsForBlock(PSProtectBlock b) { String[] splGroups = spl[1].split(","); List groups = new ArrayList<>(); for (String g : splGroups) { - if (FLAG_GROUPS.contains(g)) groups.add(g); + if (FLAG_GROUPS.contains(g)) + groups.add(g); } b.allowedFlags.put(spl[2], groups); @@ -161,7 +182,8 @@ static void initDefaultFlagsForBlock(PSProtectBlock b) { b.allowedFlags.put(f, FLAG_GROUPS); } } catch (Exception e) { - ProtectionStones.getInstance().getLogger().warning("Skipping flag " + f + ". Did you configure the allowed_flags section correctly?"); + ProtectionStones.getInstance().getLogger() + .warning("Skipping flag " + f + ". Did you configure the allowed_flags section correctly?"); e.printStackTrace(); } } @@ -190,7 +212,8 @@ static void initDefaultFlagsForBlock(PSProtectBlock b) { } // get settings (after flag name) - for (int i = startInd; i < split.length; i++) settings += split[i] + " "; + for (int i = startInd; i < split.length; i++) + settings += split[i] + " "; settings = settings.trim(); // if the setting is set to -e, change to empty flag @@ -204,7 +227,9 @@ static void initDefaultFlagsForBlock(PSProtectBlock b) { // warn if flag setting has already been set if (b.regionFlags.containsKey(flag)) { - ProtectionStones.getPluginLogger().warning(String.format("Duplicate default flags found (only one flag setting can be applied for each flag)! Overwriting the previous value set for %s with \"%s\" ...", flagName, flagraw)); + ProtectionStones.getPluginLogger().warning(String.format( + "Duplicate default flags found (only one flag setting can be applied for each flag)! Overwriting the previous value set for %s with \"%s\" ...", + flagName, flagraw)); } // apply flag @@ -214,7 +239,8 @@ static void initDefaultFlagsForBlock(PSProtectBlock b) { RegionGroup rGroup = flag.getRegionGroupFlag().detectValue(group); if (rGroup == null) { - ProtectionStones.getPluginLogger().severe(String.format("Error parsing flag \"%s\", the group value is invalid!", flagraw)); + ProtectionStones.getPluginLogger().severe( + String.format("Error parsing flag \"%s\", the group value is invalid!", flagraw)); continue; } diff --git a/src/main/java/dev/espi/protectionstones/PSL.java b/src/main/java/dev/espi/protectionstones/PSL.java index b64c3248..7da8d529 100644 --- a/src/main/java/dev/espi/protectionstones/PSL.java +++ b/src/main/java/dev/espi/protectionstones/PSL.java @@ -22,6 +22,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import net.kyori.adventure.text.minimessage.MiniMessage; + import java.io.File; import java.io.IOException; import java.util.Arrays; @@ -32,11 +34,13 @@ public enum PSL { // messages.yml - COOLDOWN("cooldown", ChatColor.GOLD + "Warning: " + ChatColor.GRAY + "Please wait for %time% seconds before placing again!"), + COOLDOWN("cooldown", + ChatColor.GOLD + "Warning: " + ChatColor.GRAY + "Please wait for %time% seconds before placing again!"), NO_SUCH_COMMAND("no_such_command", ChatColor.RED + "No such command. please type /ps help for more info"), NO_ACCESS("no_access", ChatColor.RED + "You are not allowed to do that here."), NO_ROOM_IN_INVENTORY("no_room_in_inventory", ChatColor.RED + "You don't have enough room in your inventory."), - NO_ROOM_DROPPING_ON_FLOOR("no_room_dropping_on_floor", ChatColor.RED + "You don't have enough room in your inventory. Dropping item on floor."), + NO_ROOM_DROPPING_ON_FLOOR("no_room_dropping_on_floor", + ChatColor.RED + "You don't have enough room in your inventory. Dropping item on floor."), INVALID_BLOCK("invalid_block", ChatColor.RED + "Invalid protection block."), NOT_ENOUGH_MONEY("not_enough_money", ChatColor.RED + "You don't have enough money! The price is %price%."), PAID_MONEY("paid_money", ChatColor.AQUA + "You've paid $%price%."), @@ -46,78 +50,122 @@ public enum PSL { GO_NEXT_PAGE("go_next_page", "Go to next page."), PAGE_DOES_NOT_EXIST("page_does_not_exist", ChatColor.RED + "Page does not exist."), - HELP("help", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " PS Help " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "=====\n" + ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps help"), + HELP("help", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " PS Help " + + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "=====\n" + ChatColor.AQUA + "> " + ChatColor.GRAY + + "/ps help"), HELP_NEXT("help_next", ChatColor.GRAY + "Do /ps help %page% to go to the next page!"), - COMMAND_REQUIRES_PLAYER_NAME("command_requires_player_name", ChatColor.RED + "This command requires a player name."), - - NO_PERMISSION_TOGGLE("no_permission_toggle", ChatColor.RED + "You don't have permission to use the toggle command."), - NO_PERMISSION_CREATE("no_permission_create", ChatColor.RED + "You don't have permission to place a protection block."), - NO_PERMISSION_CREATE_SPECIFIC("no_permission_create_specific", ChatColor.RED + "You don't have permission to place this protection block type."), - NO_PERMISSION_DESTROY("no_permission_destroy", ChatColor.RED + "You don't have permission to destroy a protection block."), + COMMAND_REQUIRES_PLAYER_NAME("command_requires_player_name", + ChatColor.RED + "This command requires a player name."), + + NO_PERMISSION_TOGGLE("no_permission_toggle", + ChatColor.RED + "You don't have permission to use the toggle command."), + NO_PERMISSION_CREATE("no_permission_create", + ChatColor.RED + "You don't have permission to place a protection block."), + NO_PERMISSION_CREATE_SPECIFIC("no_permission_create_specific", + ChatColor.RED + "You don't have permission to place this protection block type."), + NO_PERMISSION_DESTROY("no_permission_destroy", + ChatColor.RED + "You don't have permission to destroy a protection block."), NO_PERMISSION_MEMBERS("no_permission_members", "&cYou don't have permission to use member commands."), NO_PERMISSION_OWNERS("no_permission_owners", "&cYou don't have permission to use owner commands."), NO_PERMISSION_ADMIN("no_permission_admin", ChatColor.RED + "You do not have permission to use that command."), NO_PERMISSION_COUNT("no_permission_count", ChatColor.RED + "You do not have permission to use that command."), - NO_PERMISSION_COUNT_OTHERS("no_permission_count_others", ChatColor.RED + "You do not have permission to use that command."), + NO_PERMISSION_COUNT_OTHERS("no_permission_count_others", + ChatColor.RED + "You do not have permission to use that command."), NO_PERMISSION_FLAGS("no_permission_flags", "&cYou do not have permission to use flag commands."), NO_PERMISSION_PER_FLAG("no_permission_per_flag", ChatColor.RED + "You do not have permission to use that flag."), NO_PERMISSION_RENT("no_permission_rent", ChatColor.RED + "You do not have permission for renting."), NO_PERMISSION_TAX("no_permission_tax", ChatColor.RED + "You do not have permission to use the tax command."), - NO_PERMISSION_BUYSELL("no_permission_buysell", ChatColor.RED + "You do not have permission to buy and sell regions."), - NO_PERMISSION_UNHIDE("no_permission_unhide", ChatColor.RED + "You do not have permission to unhide protection blocks."), + NO_PERMISSION_BUYSELL("no_permission_buysell", + ChatColor.RED + "You do not have permission to buy and sell regions."), + NO_PERMISSION_UNHIDE("no_permission_unhide", + ChatColor.RED + "You do not have permission to unhide protection blocks."), NO_PERMISSION_HIDE("no_permission_hide", ChatColor.RED + "You do not have permission to hide protection blocks."), - NO_PERMISSION_INFO("no_permission_info", ChatColor.RED + "You do not have permission to use the region info command."), - NO_PERMISSION_PRIORITY("no_permission_priority", ChatColor.RED + "You do not have permission to use the priority command."), + NO_PERMISSION_INFO("no_permission_info", + ChatColor.RED + "You do not have permission to use the region info command."), + NO_PERMISSION_PRIORITY("no_permission_priority", + ChatColor.RED + "You do not have permission to use the priority command."), NO_PERMISSION_REGION("no_permission_region", ChatColor.RED + "You do not have permission to use region commands."), - NO_PERMISSION_TP("no_permission_tp", ChatColor.RED + "You do not have permission to teleport to other players' protection blocks."), - NO_PERMISSION_HOME("no_permission_home", ChatColor.RED + "You do not have permission to teleport to your protection blocks."), - NO_PERMISSION_UNCLAIM("no_permission_unclaim", ChatColor.RED + "You do not have permission to use the unclaim command."), - NO_PERMISSION_UNCLAIM_REMOTE("no_permission_unclaim_remote", ChatColor.RED + "You do not have permission to use the unclaim remote command."), + NO_PERMISSION_TP("no_permission_tp", + ChatColor.RED + "You do not have permission to teleport to other players' protection blocks."), + NO_PERMISSION_HOME("no_permission_home", + ChatColor.RED + "You do not have permission to teleport to your protection blocks."), + NO_PERMISSION_UNCLAIM("no_permission_unclaim", + ChatColor.RED + "You do not have permission to use the unclaim command."), + NO_PERMISSION_UNCLAIM_REMOTE("no_permission_unclaim_remote", + ChatColor.RED + "You do not have permission to use the unclaim remote command."), NO_PERMISSION_VIEW("no_permission_view", ChatColor.RED + "You do not have permission to use the view command."), NO_PERMISSION_GIVE("no_permission_give", ChatColor.RED + "You do not have permission to use the give command."), NO_PERMISSION_GET("no_permission_get", ChatColor.RED + "You do not have permission to use the get command."), - NO_PERMISSION_SETHOME("no_permission_sethome", ChatColor.RED + "You do not have permission to use the sethome command."), + NO_PERMISSION_SETHOME("no_permission_sethome", + ChatColor.RED + "You do not have permission to use the sethome command."), NO_PERMISSION_LIST("no_permission_list", ChatColor.RED + "You do not have permission to use the list command."), - NO_PERMISSION_LIST_OTHERS("no_permission_list_others", ChatColor.RED + "You do not have permission to use the list command for others."), + NO_PERMISSION_LIST_OTHERS("no_permission_list_others", + ChatColor.RED + "You do not have permission to use the list command for others."), NO_PERMISSION_NAME("no_permission_name", ChatColor.RED + "You do not have permission to use the name command."), - NO_PERMISSION_SETPARENT("no_permission_setparent", ChatColor.RED + "You do not have permission to use the setparent command."), - NO_PERMISSION_SETPARENT_OTHERS("no_permission_setparent_others", ChatColor.RED + "You do not have permission to inherit from regions you don't own."), + NO_PERMISSION_SETPARENT("no_permission_setparent", + ChatColor.RED + "You do not have permission to use the setparent command."), + NO_PERMISSION_SETPARENT_OTHERS("no_permission_setparent_others", + ChatColor.RED + "You do not have permission to inherit from regions you don't own."), NO_PERMISSION_MERGE("no_permission_merge", ChatColor.RED + "You do not have permission to use /ps merge."), - ADDED_TO_REGION("psregion.added_to_region", ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has been added to this region."), - ADDED_TO_REGION_SPECIFIC("psregion.added_to_region_specific", ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has been added to region %region%."), - REMOVED_FROM_REGION("psregion.removed_from_region", ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has been removed from region."), - REMOVED_FROM_REGION_SPECIFIC("psregion.removed_from_region_specific", ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has been removed from region %region%."), + ADDED_TO_REGION("psregion.added_to_region", + ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has been added to this region."), + ADDED_TO_REGION_SPECIFIC("psregion.added_to_region_specific", + ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has been added to region %region%."), + REMOVED_FROM_REGION("psregion.removed_from_region", + ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has been removed from region."), + REMOVED_FROM_REGION_SPECIFIC("psregion.removed_from_region_specific", + ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has been removed from region %region%."), NOT_IN_REGION("psregion.not_in_region", ChatColor.RED + "You are not in a protection stones region!"), PLAYER_NOT_FOUND("psregion.player_not_found", ChatColor.RED + "Player not found."), NOT_PS_REGION("psregion.not_ps_region", ChatColor.RED + "Not a protection stones region."), REGION_DOES_NOT_EXIST("psregion.region_does_not_exist", ChatColor.RED + "Region does not exist."), NO_REGIONS_OWNED("psregion.no_regions_owned", ChatColor.RED + "You don't own any protected regions in this world!"), - NO_REGION_PERMISSION("psregion.no_region_permission", ChatColor.RED + "You do not have permission to do this in this region."), + NO_REGION_PERMISSION("psregion.no_region_permission", + ChatColor.RED + "You do not have permission to do this in this region."), PROTECTED("psregion.protected", ChatColor.AQUA + "This area is now protected."), NO_LONGER_PROTECTED("psregion.no_longer_protected", ChatColor.YELLOW + "This area is no longer protected."), CANT_PROTECT_THAT("psregion.cant_protect_that", ChatColor.RED + "You can't protect that area."), - REACHED_REGION_LIMIT("psregion.reached_region_limit", ChatColor.RED + "You can not have any more protected regions (%limit%)."), - REACHED_PER_BLOCK_REGION_LIMIT("psregion.reached_per_block_region_limit", ChatColor.RED + "You can not have any more regions of this type (%limit%)."), - WORLD_DENIED_CREATE("psregion.world_denied_create", ChatColor.RED + "You can not create protections in this world."), - REGION_OVERLAP("psregion.region_overlap", ChatColor.RED + "You can not place a protection block here as it overlaps another region."), - REGION_TOO_CLOSE("psregion.region_too_close", ChatColor.RED + "Your protection block must be a minimum of %num% blocks from the edge of other regions!"), - REGION_CANT_TELEPORT("psregion.cant_teleport", ChatColor.RED + "Your teleportation was blocked by a protection region!"), - SPECIFY_ID_INSTEAD_OF_ALIAS("psregion.specify_id_instead_of_alias", ChatColor.GRAY + "There were multiple regions found with this name! Please use an ID instead.\n Regions with this name: " + ChatColor.AQUA + "%regions%"), - REGION_NOT_ADJACENT("psregion.region_not_adjacent", ChatColor.RED + "You've passed the limit of non-adjacent regions! Try putting your protection block closer to other regions you already own."), + REACHED_REGION_LIMIT("psregion.reached_region_limit", + ChatColor.RED + "You can not have any more protected regions (%limit%)."), + REACHED_PER_BLOCK_REGION_LIMIT("psregion.reached_per_block_region_limit", + ChatColor.RED + "You can not have any more regions of this type (%limit%)."), + WORLD_DENIED_CREATE("psregion.world_denied_create", + ChatColor.RED + "You can not create protections in this world."), + REGION_OVERLAP("psregion.region_overlap", + ChatColor.RED + "You can not place a protection block here as it overlaps another region."), + REGION_TOO_CLOSE("psregion.region_too_close", + ChatColor.RED + "Your protection block must be a minimum of %num% blocks from the edge of other regions!"), + REGION_CANT_TELEPORT("psregion.cant_teleport", + ChatColor.RED + "Your teleportation was blocked by a protection region!"), + SPECIFY_ID_INSTEAD_OF_ALIAS("psregion.specify_id_instead_of_alias", ChatColor.GRAY + + "There were multiple regions found with this name! Please use an ID instead.\n Regions with this name: " + + ChatColor.AQUA + "%regions%"), + REGION_NOT_ADJACENT("psregion.region_not_adjacent", ChatColor.RED + + "You've passed the limit of non-adjacent regions! Try putting your protection block closer to other regions you already own."), REGION_NOT_OVERLAPPING("psregion.not_overlapping", ChatColor.RED + "These regions don't overlap each other!"), MULTI_REGION_DOES_NOT_EXIST("psregion.multi_region_does_not_exist", "One of these regions don't exist!"), - NO_REGION_HOLES("psregion.no_region_holes", ChatColor.RED + "Unprotected area detected inside region! This is not allowed!"), - DELETE_REGION_PREVENTED_NO_HOLES("psregion.delete_region_prevented", ChatColor.GRAY + "The region could not be removed, possibly because it creates a hole in the existing region."), + NO_REGION_HOLES("psregion.no_region_holes", + ChatColor.RED + "Unprotected area detected inside region! This is not allowed!"), + DELETE_REGION_PREVENTED_NO_HOLES("psregion.delete_region_prevented", + ChatColor.GRAY + + "The region could not be removed, possibly because it creates a hole in the existing region."), NOT_OWNER("psregion.not_owner", ChatColor.RED + "You are not an owner of this region!"), - CANNOT_MERGE_RENTED_REGION("psregion.cannot_merge_rented_region", ChatColor.RED + "Cannot merge regions because region %region% is in the process of being rented out!"), - NO_PERMISSION_REGION_TYPE("psregion.no_permission_region_type", ChatColor.RED + "You do not have permission to have this region type."), + CANNOT_MERGE_RENTED_REGION("psregion.cannot_merge_rented_region", + ChatColor.RED + "Cannot merge regions because region %region% is in the process of being rented out!"), + NO_PERMISSION_REGION_TYPE("psregion.no_permission_region_type", + ChatColor.RED + "You do not have permission to have this region type."), REGION_HIDDEN("psregion.hidden", ChatColor.GRAY + "The protection block is now hidden."), - MUST_BE_PLACED_IN_EXISTING_REGION("psregion.must_be_placed_in_existing_region", ChatColor.RED + "This must be placed inside of an existing region!"), - REGION_ALREADY_IN_LOCATION_IS_HIDDEN("psregion.already_in_location_is_hidden", ChatColor.RED + "A region already exists in this location (is the protection block hidden?)"), - CANNOT_REMOVE_YOURSELF_LAST_OWNER("psregion.cannot_remove_yourself_last_owner", ChatColor.RED + "You cannot remove yourself as you are the last owner."), - CANNOT_REMOVE_YOURSELF_FROM_ALL_REGIONS("psregion.cannot_remove_yourself_all_regions", ChatColor.RED + "You cannot remove yourself from all of your regions at once, for safety reasons."), + MUST_BE_PLACED_IN_EXISTING_REGION("psregion.must_be_placed_in_existing_region", + ChatColor.RED + "This must be placed inside of an existing region!"), + REGION_ALREADY_IN_LOCATION_IS_HIDDEN("psregion.already_in_location_is_hidden", + ChatColor.RED + "A region already exists in this location (is the protection block hidden?)"), + CANNOT_REMOVE_YOURSELF_LAST_OWNER("psregion.cannot_remove_yourself_last_owner", + ChatColor.RED + "You cannot remove yourself as you are the last owner."), + CANNOT_REMOVE_YOURSELF_FROM_ALL_REGIONS("psregion.cannot_remove_yourself_all_regions", + ChatColor.RED + "You cannot remove yourself from all of your regions at once, for safety reasons."), // ps toggle TOGGLE_HELP("toggle.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps toggle|on|off"), @@ -128,72 +176,131 @@ public enum PSL { // ps count COUNT_HELP("count.count_help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps count [player (optional)]"), COUNT_HELP_DESC("count.count_help_desc", "Count the number of regions you own or another player."), - PERSONAL_REGION_COUNT("count.personal_region_count", ChatColor.GRAY + "Your region count in this world: " + ChatColor.AQUA + "%num%"), - PERSONAL_REGION_COUNT_MERGED("count.personal_region_count_merged", ChatColor.GRAY + "- Including each merged region: " + ChatColor.AQUA + "%num%"), - OTHER_REGION_COUNT("count.other_region_count", ChatColor.GRAY + "%player%'s region count in this world: " + ChatColor.AQUA + "%num%"), - OTHER_REGION_COUNT_MERGED("count.other_region_count_merged", ChatColor.GRAY + "- Including each merged region: " + ChatColor.AQUA + "%num%"), + PERSONAL_REGION_COUNT("count.personal_region_count", + ChatColor.GRAY + "Your region count in this world: " + ChatColor.AQUA + "%num%"), + PERSONAL_REGION_COUNT_MERGED("count.personal_region_count_merged", + ChatColor.GRAY + "- Including each merged region: " + ChatColor.AQUA + "%num%"), + OTHER_REGION_COUNT("count.other_region_count", + ChatColor.GRAY + "%player%'s region count in this world: " + ChatColor.AQUA + "%num%"), + OTHER_REGION_COUNT_MERGED("count.other_region_count_merged", + ChatColor.GRAY + "- Including each merged region: " + ChatColor.AQUA + "%num%"), // ps flag FLAG_HELP("flag.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps flag [flagname] [value|null|default]"), FLAG_HELP_DESC("flag.help_desc", "Use this command to set a flag in your protected region."), FLAG_SET("flag.flag_set", ChatColor.AQUA + "%flag%" + ChatColor.GRAY + " flag has been set."), - FLAG_NOT_SET("flag.flag_not_set", ChatColor.AQUA + "%flag%" + ChatColor.GRAY + " flag has " + ChatColor.RED + "not" + ChatColor.GRAY + " been set. Check your values again."), + FLAG_NOT_SET("flag.flag_not_set", + ChatColor.AQUA + "%flag%" + ChatColor.GRAY + " flag has " + ChatColor.RED + "not" + ChatColor.GRAY + + " been set. Check your values again."), FLAG_PREVENT_EXPLOIT("flag.flag_prevent_exploit", ChatColor.RED + "This has been disabled to prevent exploits."), FLAG_PREVENT_EXPLOIT_HOVER("flag.flag_prevent_exploit_hover", ChatColor.RED + "Disabled for security reasons."), - FLAG_GUI_HEADER("flag.gui_header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Flags (click to change) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + FLAG_GUI_HEADER("flag.gui_header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Flags (click to change) " + + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), FLAG_GUI_HOVER_SET("flag.gui_hover_set", ChatColor.AQUA + "Click to set."), - FLAG_GUI_HOVER_SET_TEXT("flag.gui_hover_set_text", ChatColor.AQUA + "Click to change." + ChatColor.WHITE + "\nCurrent value:\n%value%"), + FLAG_GUI_HOVER_SET_TEXT("flag.gui_hover_set_text", + ChatColor.AQUA + "Click to change." + ChatColor.WHITE + "\nCurrent value:\n%value%"), FLAG_GUI_HOVER_CHANGE_GROUP("flag.hover_change_group", "Click to set this flag to apply to only %group%."), - FLAG_GUI_HOVER_CHANGE_GROUP_NULL("flag.hover_change_group_null", ChatColor.RED + "You must set this flag to a value before changing the group."), + FLAG_GUI_HOVER_CHANGE_GROUP_NULL("flag.hover_change_group_null", + ChatColor.RED + "You must set this flag to a value before changing the group."), // ps rent RENT_HELP("rent.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps rent"), RENT_HELP_DESC("rent.help_desc", "Use this command to manage rents (buying and selling)."), - RENT_HELP_HEADER("rent.help_header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Rent Help " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), - RENT_ALREADY_RENTING("rent.already_renting", ChatColor.RED + "The region is already being rented out! You must stop leasing the region first."), + RENT_HELP_HEADER("rent.help_header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Rent Help " + + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + RENT_ALREADY_RENTING("rent.already_renting", + ChatColor.RED + "The region is already being rented out! You must stop leasing the region first."), RENT_NOT_RENTED("rent.not_rented", ChatColor.RED + "This region is not being rented."), - RENT_LEASE_SUCCESS("rent.lease_success", ChatColor.AQUA + "Region leasing terms set:\n" + ChatColor.AQUA + "Price: " + ChatColor.GRAY + "%price%\n" + ChatColor.AQUA + "Payment Term: " + ChatColor.GRAY + "%period%"), + RENT_LEASE_SUCCESS("rent.lease_success", + ChatColor.AQUA + "Region leasing terms set:\n" + ChatColor.AQUA + "Price: " + ChatColor.GRAY + "%price%\n" + + ChatColor.AQUA + "Payment Term: " + ChatColor.GRAY + "%period%"), RENT_STOPPED("rent.stopped", ChatColor.AQUA + "Leasing stopped."), RENT_EVICTED("rent.evicted", ChatColor.GRAY + "Evicted tenant %tenant%."), RENT_NOT_RENTING("rent.not_renting", ChatColor.RED + "This region is not being rented out to tenants."), - RENT_PAID_LANDLORD("rent.paid_landlord", ChatColor.AQUA + "%tenant%" + ChatColor.GRAY + " has paid " + ChatColor.AQUA + "$%price%" + ChatColor.GRAY + " for renting out " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + "."), - RENT_PAID_TENANT("rent.paid_tenant", ChatColor.GRAY + "Paid " + ChatColor.AQUA + "$%price%" + ChatColor.GRAY + " to " + ChatColor.AQUA + "%landlord%" + ChatColor.GRAY + " for region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + "."), - RENT_RENTING_LANDLORD("rent.renting_landlord", ChatColor.AQUA + "%player%" + ChatColor.GRAY + " is now renting out region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + "."), - RENT_RENTING_TENANT("rent.renting_tenant", ChatColor.GRAY + "You are now renting out region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " for " + ChatColor.AQUA + "%price%" + ChatColor.GRAY + " per " + ChatColor.AQUA + "%period%" + ChatColor.GRAY + "."), + RENT_PAID_LANDLORD("rent.paid_landlord", + ChatColor.AQUA + "%tenant%" + ChatColor.GRAY + " has paid " + ChatColor.AQUA + "$%price%" + ChatColor.GRAY + + " for renting out " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + "."), + RENT_PAID_TENANT("rent.paid_tenant", + ChatColor.GRAY + "Paid " + ChatColor.AQUA + "$%price%" + ChatColor.GRAY + " to " + ChatColor.AQUA + + "%landlord%" + ChatColor.GRAY + " for region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + + "."), + RENT_RENTING_LANDLORD("rent.renting_landlord", + ChatColor.AQUA + "%player%" + ChatColor.GRAY + " is now renting out region " + ChatColor.AQUA + "%region%" + + ChatColor.GRAY + "."), + RENT_RENTING_TENANT("rent.renting_tenant", + ChatColor.GRAY + "You are now renting out region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " for " + + ChatColor.AQUA + "%price%" + ChatColor.GRAY + " per " + ChatColor.AQUA + "%period%" + + ChatColor.GRAY + "."), RENT_NOT_TENANT("rent.not_tenant", ChatColor.RED + "You are not the tenant of this region!"), - RENT_TENANT_STOPPED_LANDLORD("rent.tenant_stopped_landlord", ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has stopped renting out region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + ". It is now available for others to rent."), - RENT_TENANT_STOPPED_TENANT("rent.tenant_stopped_tenant", ChatColor.AQUA + "You have stopped renting out region %region%."), + RENT_TENANT_STOPPED_LANDLORD("rent.tenant_stopped_landlord", + ChatColor.AQUA + "%player%" + ChatColor.GRAY + " has stopped renting out region " + ChatColor.AQUA + + "%region%" + ChatColor.GRAY + ". It is now available for others to rent."), + RENT_TENANT_STOPPED_TENANT("rent.tenant_stopped_tenant", + ChatColor.AQUA + "You have stopped renting out region %region%."), RENT_BEING_SOLD("rent.being_sold", ChatColor.RED + "The region is being sold! Do /ps sell stop first."), - RENT_EVICT_NO_MONEY_TENANT("rent.evict_no_money_tenant", ChatColor.GRAY + "You have been " + ChatColor.RED + "evicted" + ChatColor.GRAY + " from region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " because you do not have enough money (%price%) to pay for rent."), - RENT_EVICT_NO_MONEY_LANDLORD("rent.evict_no_money_landlord", ChatColor.AQUA + "%tenant%" + ChatColor.GRAY + " has been " + ChatColor.RED + "evicted" + ChatColor.GRAY + " from region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " because they are unable to afford rent."), + RENT_EVICT_NO_MONEY_TENANT("rent.evict_no_money_tenant", + ChatColor.GRAY + "You have been " + ChatColor.RED + "evicted" + ChatColor.GRAY + " from region " + + ChatColor.AQUA + "%region%" + ChatColor.GRAY + + " because you do not have enough money (%price%) to pay for rent."), + RENT_EVICT_NO_MONEY_LANDLORD("rent.evict_no_money_landlord", + ChatColor.AQUA + "%tenant%" + ChatColor.GRAY + " has been " + ChatColor.RED + "evicted" + ChatColor.GRAY + + " from region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + + " because they are unable to afford rent."), RENT_CANNOT_RENT_OWN_REGION("rent.cannot_rent_own_region", ChatColor.RED + "You cannot rent your own region!"), - RENT_REACHED_LIMIT("rent.reached_limit", ChatColor.RED + "You've reached the limit of regions you are allowed to rent!"), - RENT_PRICE_TOO_LOW("rent.price_too_low", ChatColor.RED + "The rent price is too low (must be larger than %price%)."), - RENT_PRICE_TOO_HIGH("rent.price_too_high", ChatColor.RED + "The rent price is too high (must be lower than %price%)."), - RENT_PERIOD_TOO_SHORT("rent.period_too_short", ChatColor.RED + "The rent period is too short (must be longer than %period% seconds)."), - RENT_PERIOD_TOO_LONG("rent.period_too_long", ChatColor.RED + "The rent period is too long (must be shorter than %period% seconds)."), + RENT_REACHED_LIMIT("rent.reached_limit", + ChatColor.RED + "You've reached the limit of regions you are allowed to rent!"), + RENT_PRICE_TOO_LOW("rent.price_too_low", + ChatColor.RED + "The rent price is too low (must be larger than %price%)."), + RENT_PRICE_TOO_HIGH("rent.price_too_high", + ChatColor.RED + "The rent price is too high (must be lower than %price%)."), + RENT_PERIOD_TOO_SHORT("rent.period_too_short", + ChatColor.RED + "The rent period is too short (must be longer than %period% seconds)."), + RENT_PERIOD_TOO_LONG("rent.period_too_long", + ChatColor.RED + "The rent period is too long (must be shorter than %period% seconds)."), RENT_PERIOD_INVALID("rent.period_invalid", ChatColor.RED + "Invalid period format! Example: 24h for once a day."), - RENT_CANNOT_BREAK_WHILE_RENTING("rent.cannot_break_while_renting", ChatColor.RED + "You cannot break the region when it is being rented out."), + RENT_CANNOT_BREAK_WHILE_RENTING("rent.cannot_break_while_renting", + ChatColor.RED + "You cannot break the region when it is being rented out."), // ps tax TAX_HELP("tax.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps tax"), TAX_HELP_DESC("tax.help_desc", "Use this command to manage and pay taxes."), - TAX_HELP_HEADER("tax.help_header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Taxes Help " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + TAX_HELP_HEADER("tax.help_header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Taxes Help " + + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), TAX_DISABLED_REGION("tax.disabled_region", ChatColor.RED + "Taxes are disabled for this region."), - TAX_SET_AS_AUTOPAYER("tax.set_as_autopayer", ChatColor.GRAY + "Taxes for region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " will now be automatically paid by you."), - TAX_SET_NO_AUTOPAYER("tax.set_no_autopayer", ChatColor.GRAY + "Taxes for region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " now have to be manually paid for."), - TAX_PAID("tax.paid", ChatColor.GRAY + "Paid " + ChatColor.AQUA + "$%amount%" + ChatColor.GRAY + " in taxes for region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + "."), - TAX_INFO_HEADER("tax.info_header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Tax Info (click for more info) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), - TAX_JOIN_MSG_PENDING_PAYMENTS("tax.join_msg_pending_payments", ChatColor.GRAY + "You have " + ChatColor.AQUA + "$%money%" + ChatColor.GRAY + " in tax payments due on your regions!\nView them with /ps tax info."), - TAX_PLAYER_REGION_INFO("tax.player_region_info", ChatColor.GRAY + "> " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " - " + ChatColor.DARK_AQUA + "$%money% due"), - TAX_PLAYER_REGION_INFO_AUTOPAYER("tax.player_region_info_autopayer", ChatColor.GRAY + "> " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " - " + ChatColor.DARK_AQUA + "$%money% due" + ChatColor.GRAY + " (you autopay)"), + TAX_SET_AS_AUTOPAYER("tax.set_as_autopayer", + ChatColor.GRAY + "Taxes for region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + + " will now be automatically paid by you."), + TAX_SET_NO_AUTOPAYER("tax.set_no_autopayer", + ChatColor.GRAY + "Taxes for region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + + " now have to be manually paid for."), + TAX_PAID("tax.paid", + ChatColor.GRAY + "Paid " + ChatColor.AQUA + "$%amount%" + ChatColor.GRAY + " in taxes for region " + + ChatColor.AQUA + "%region%" + ChatColor.GRAY + "."), + TAX_INFO_HEADER("tax.info_header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + + " Tax Info (click for more info) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + TAX_JOIN_MSG_PENDING_PAYMENTS("tax.join_msg_pending_payments", + ChatColor.GRAY + "You have " + ChatColor.AQUA + "$%money%" + ChatColor.GRAY + + " in tax payments due on your regions!\nView them with /ps tax info."), + TAX_PLAYER_REGION_INFO("tax.player_region_info", + ChatColor.GRAY + "> " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " - " + ChatColor.DARK_AQUA + + "$%money% due"), + TAX_PLAYER_REGION_INFO_AUTOPAYER("tax.player_region_info_autopayer", + ChatColor.GRAY + "> " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " - " + ChatColor.DARK_AQUA + + "$%money% due" + ChatColor.GRAY + " (you autopay)"), TAX_CLICK_TO_SHOW_MORE_INFO("tax.click_to_show_more_info", "Click to show more information."), - TAX_REGION_INFO_HEADER("tax.region_info_header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " %region% Tax Info " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), - TAX_REGION_INFO("tax.region_info", ChatColor.BLUE + "Tax Rate: " + ChatColor.GRAY + "$%taxrate% (sum of all merged regions)" + "\n" - + ChatColor.BLUE + "Time between tax cycles: " + ChatColor.GRAY + "%taxperiod%" + "\n" - + ChatColor.BLUE + "Time to pay taxes after cycle: " + ChatColor.GRAY + "%taxpaymentperiod%" + "\n" - + ChatColor.BLUE + "Tax Autopayer: " + ChatColor.GRAY + "%taxautopayer%" + "\n" - + ChatColor.BLUE + "Taxes Owed: " + ChatColor.GRAY + "$%taxowed%"), + TAX_REGION_INFO_HEADER("tax.region_info_header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " %region% Tax Info " + + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + TAX_REGION_INFO("tax.region_info", + ChatColor.BLUE + "Tax Rate: " + ChatColor.GRAY + "$%taxrate% (sum of all merged regions)" + "\n" + + ChatColor.BLUE + "Time between tax cycles: " + ChatColor.GRAY + "%taxperiod%" + "\n" + + ChatColor.BLUE + "Time to pay taxes after cycle: " + ChatColor.GRAY + "%taxpaymentperiod%" + "\n" + + ChatColor.BLUE + "Tax Autopayer: " + ChatColor.GRAY + "%taxautopayer%" + "\n" + + ChatColor.BLUE + "Taxes Owed: " + ChatColor.GRAY + "$%taxowed%"), TAX_NEXT("tax.next_page", ChatColor.GRAY + "Do /ps tax info -p %page% to go to the next page!"), // ps buy @@ -201,27 +308,38 @@ public enum PSL { BUY_HELP_DESC("buy.help_desc", "Buy the region you are currently in."), BUY_NOT_FOR_SALE("buy.not_for_sale", ChatColor.RED + "This region is not for sale."), BUY_STOP_SELL("buy.stop_sell", ChatColor.GRAY + "The region is now not for sale."), - BUY_SOLD_BUYER("buy.sold_buyer", ChatColor.GRAY + "Bought region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " for " + ChatColor.AQUA + "$%price%" + ChatColor.GRAY + " from " + ChatColor.AQUA + "%player%" + ChatColor.GRAY + "."), - BUY_SOLD_SELLER("buy.sold_seller", ChatColor.GRAY + "Sold region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " for " + ChatColor.AQUA + "$%price%" + ChatColor.GRAY + " to " + ChatColor.AQUA + "%player%" + ChatColor.GRAY + "."), + BUY_SOLD_BUYER("buy.sold_buyer", + ChatColor.GRAY + "Bought region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " for " + ChatColor.AQUA + + "$%price%" + ChatColor.GRAY + " from " + ChatColor.AQUA + "%player%" + ChatColor.GRAY + "."), + BUY_SOLD_SELLER("buy.sold_seller", + ChatColor.GRAY + "Sold region " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + " for " + ChatColor.AQUA + + "$%price%" + ChatColor.GRAY + " to " + ChatColor.AQUA + "%player%" + ChatColor.GRAY + "."), // ps sell SELL_HELP("sell.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps sell [price|stop]"), SELL_HELP_DESC("sell.help_desc", "Sell the region you are currently in."), - SELL_RENTED_OUT("sell.rented_out", ChatColor.RED + "The region is being rented out! You must stop renting it out to sell."), - SELL_FOR_SALE("sell.for_sale", ChatColor.GRAY + "The region is now for sale for " + ChatColor.AQUA + "$%price%" + ChatColor.GRAY + "."), + SELL_RENTED_OUT("sell.rented_out", + ChatColor.RED + "The region is being rented out! You must stop renting it out to sell."), + SELL_FOR_SALE("sell.for_sale", + ChatColor.GRAY + "The region is now for sale for " + ChatColor.AQUA + "$%price%" + ChatColor.GRAY + "."), // ps hide/unhide VISIBILITY_HIDE_HELP("visibility.hide_help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps hide"), VISIBILITY_HIDE_HELP_DESC("visibility.hide_help_desc", "Use this command to hide or unhide your protection block."), VISIBILITY_UNHIDE_HELP("visibility.unhide_help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps unhide"), - VISIBILITY_UNHIDE_HELP_DESC("visibility.unhide_help_desc", "Use this command to hide or unhide your protection block."), - ALREADY_NOT_HIDDEN("visibility.already_not_hidden", ChatColor.GRAY + "The protection stone doesn't appear hidden..."), - ALREADY_HIDDEN("visibility.already_hidden", ChatColor.GRAY + "The protection stone appears to already be hidden..."), + VISIBILITY_UNHIDE_HELP_DESC("visibility.unhide_help_desc", + "Use this command to hide or unhide your protection block."), + ALREADY_NOT_HIDDEN("visibility.already_not_hidden", + ChatColor.GRAY + "The protection stone doesn't appear hidden..."), + ALREADY_HIDDEN("visibility.already_hidden", + ChatColor.GRAY + "The protection stone appears to already be hidden..."), // ps info INFO_HELP("info.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps info members|owners|flags"), INFO_HELP_DESC("info.help_desc", "Use this command inside a ps region to see more information about it."), - INFO_HEADER("info.header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " PS Info " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + INFO_HEADER("info.header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " PS Info " + + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), INFO_TYPE2("info.type2", "&9Type: &7%type%", "%type%"), INFO_MAY_BE_MERGED("info.may_be_merged", "(may be merged with other types)"), INFO_MERGED2("info.merged2", ChatColor.BLUE + "Merged regions: " + ChatColor.GRAY + "%merged%", "%merged%"), @@ -235,11 +353,9 @@ public enum PSL { INFO_PRIORITY2("info.priority2", "&9Priority: &b%priority%", "%priority%"), INFO_PARENT2("info.parent2", "&9Parent: &b%parentregion%", "%parentregion%"), INFO_BOUNDS_XYZ("info.bounds_xyz", "&9Bounds: &b(%minx%,%miny%,%minz%) -> (%maxx%,%maxy%,%maxz%)", - "%minx%", "%miny%", "%minz%", "%maxx%", "%maxy%", "%maxz%" - ), + "%minx%", "%miny%", "%minz%", "%maxx%", "%maxy%", "%maxz%"), INFO_BOUNDS_XZ("info.bounds_xz", "&9Bounds: &b(%minx%, %minz%) -> (%maxx%, %maxz%)", - "%minx%", "%minz%", "%maxx%", "%maxz%" - ), + "%minx%", "%minz%", "%maxx%", "%maxz%"), INFO_SELLER2("info.seller2", "&9Seller: &7%seller%", "%seller%"), INFO_PRICE2("info.price2", "&9Price: &7%price%", "%price%"), INFO_TENANT2("info.tenant2", "&9Tenant: &7%tenant%", "%tenant%"), @@ -257,12 +373,17 @@ public enum PSL { // ps region REGION_HELP("region.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps region [list|remove|disown] [playername]"), - REGION_HELP_DESC("region.help_desc", "Use this command to find information or edit other players' (or your own) protected regions."), - REGION_NOT_FOUND_FOR_PLAYER("region.not_found_for_player", ChatColor.GRAY + "No regions found for %player% in this world."), + REGION_HELP_DESC("region.help_desc", + "Use this command to find information or edit other players' (or your own) protected regions."), + REGION_NOT_FOUND_FOR_PLAYER("region.not_found_for_player", + ChatColor.GRAY + "No regions found for %player% in this world."), REGION_LIST("region.list", ChatColor.GRAY + "%player%'s regions in this world: " + ChatColor.AQUA + "%regions%"), - REGION_REMOVE("region.remove", ChatColor.YELLOW + "%player%'s regions have been removed in this world, and they have been removed from regions they co-owned."), - REGION_DISOWN("region.disown", ChatColor.YELLOW + "%player% has been removed as owner from all regions on this world."), - REGION_ERROR_SEARCH("region.error_search", ChatColor.RED + "Error while searching for %player%'s regions. Please make sure you have entered the correct name."), + REGION_REMOVE("region.remove", ChatColor.YELLOW + + "%player%'s regions have been removed in this world, and they have been removed from regions they co-owned."), + REGION_DISOWN("region.disown", + ChatColor.YELLOW + "%player% has been removed as owner from all regions on this world."), + REGION_ERROR_SEARCH("region.error_search", ChatColor.RED + + "Error while searching for %player%'s regions. Please make sure you have entered the correct name."), // ps tp TP_HELP("tp.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps tp [id/player] [num (optional)]"), @@ -271,22 +392,29 @@ public enum PSL { TP_VALID_NUMBER("tp.valid_number", ChatColor.RED + "Please enter a valid number."), ONLY_HAS_REGIONS("tp.only_has_regions", ChatColor.RED + "%player% only has %num% protected regions in this world!"), TPING("tp.tping", ChatColor.GREEN + "Teleporting..."), - TP_ERROR_NAME("tp.error_name", ChatColor.RED + "Error in teleporting to protected region! (parsing WG region name error)"), + TP_ERROR_NAME("tp.error_name", + ChatColor.RED + "Error in teleporting to protected region! (parsing WG region name error)"), TP_ERROR_TP("tp.error_tp", ChatColor.RED + "Error in finding the region to teleport to!"), - TP_IN_SECONDS("tp.in_seconds", ChatColor.GRAY + "Teleporting in " + ChatColor.AQUA + "%seconds%" + ChatColor.GRAY + " seconds."), + TP_IN_SECONDS("tp.in_seconds", + ChatColor.GRAY + "Teleporting in " + ChatColor.AQUA + "%seconds%" + ChatColor.GRAY + " seconds."), TP_CANCELLED_MOVED("tp.cancelled_moved", ChatColor.RED + "Teleport cancelled. You moved!"), // ps home HOME_HELP("home.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps home [name/id]"), HOME_HELP_DESC("home.help_desc", "Teleports you to one of your protected regions."), - HOME_HEADER("home.header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Homes (click to teleport) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + HOME_HEADER("home.header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + + " Homes (click to teleport) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), HOME_CLICK_TO_TP("home.click_to_tp", "Click to teleport!"), HOME_NEXT("home.next_page", ChatColor.GRAY + "Do /ps home -p %page% to go to the next page!"), // ps unclaim UNCLAIM_HELP("unclaim.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps unclaim"), - UNCLAIM_HELP_DESC("unclaim.help_desc", "Use this command to pickup a placed protection stone and remove the region."), - UNCLAIM_HEADER("unclaim.header",ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Unclaim (click to unclaim) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + UNCLAIM_HELP_DESC("unclaim.help_desc", + "Use this command to pickup a placed protection stone and remove the region."), + UNCLAIM_HEADER("unclaim.header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + + " Unclaim (click to unclaim) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), // ps view VIEW_HELP("view.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps view"), @@ -294,21 +422,24 @@ public enum PSL { VIEW_COOLDOWN("view.cooldown", ChatColor.RED + "Please wait a while before using /ps view again."), VIEW_GENERATING("view.generating", ChatColor.GRAY + "Generating border..."), VIEW_GENERATE_DONE("view.generate_done", ChatColor.GREEN + "Done! The border will disappear after 30 seconds!"), - VIEW_REMOVING("view.removing", ChatColor.AQUA + "Removing border...\n" + ChatColor.GREEN + "If you still see ghost blocks, relog!"), + VIEW_REMOVING("view.removing", + ChatColor.AQUA + "Removing border...\n" + ChatColor.GREEN + "If you still see ghost blocks, relog!"), // ps admin ADMIN_HELP("admin.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps admin"), ADMIN_HELP_DESC("admin.help_desc", "Do /ps admin help for more information."), ADMIN_CLEANUP_HEADER("admin.cleanup_header", ChatColor.YELLOW + "Cleanup %arg% %days% days\n================"), ADMIN_CLEANUP_FOOTER("admin.cleanup_footer", ChatColor.YELLOW + "================\nCompleted %arg% cleanup."), - ADMIN_HIDE_TOGGLED("admin.hide_toggled", ChatColor.YELLOW + "All protection stones have been %message% in this world."), + ADMIN_HIDE_TOGGLED("admin.hide_toggled", + ChatColor.YELLOW + "All protection stones have been %message% in this world."), ADMIN_LAST_LOGON("admin.last_logon", ChatColor.YELLOW + "%player% last played %days% days ago."), ADMIN_IS_BANNED("admin.is_banned", ChatColor.YELLOW + "%player% is banned."), ADMIN_ERROR_PARSING("admin.error_parsing", ChatColor.RED + "Error parsing days, are you sure it is a number?"), ADMIN_CONSOLE_WORLD("admin.console_world", ChatColor.RED + "Please specify the world as the last parameter."), ADMIN_LASTLOGONS_HEADER("admin.lastlogons_header", ChatColor.YELLOW + "%days% Days Plus:\n================"), ADMIN_LASTLOGONS_LINE("admin.lastlogons_line", ChatColor.YELLOW + "%player% %time% days"), - ADMIN_LASTLOGONS_FOOTER("admin.lastlogons_footer", ChatColor.YELLOW + "================\n%count% Total Players Shown\n%checked% Total Players Checked"), + ADMIN_LASTLOGONS_FOOTER("admin.lastlogons_footer", + ChatColor.YELLOW + "================\n%count% Total Players Shown\n%checked% Total Players Checked"), // ps reload RELOAD_HELP("reload.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps reload"), @@ -319,66 +450,97 @@ public enum PSL { // ps add/remove ADDREMOVE_HELP("addremove.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps add|remove [playername]"), ADDREMOVE_HELP_DESC("addremove.help_desc", "Use this command to add or remove a member of your protected region."), - ADDREMOVE_OWNER_HELP("addremove.owner_help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps addowner|removeowner [playername]"), - ADDREMOVE_OWNER_HELP_DESC("addremove.owner_help_desc", "Use this command to add or remove an owner of your protected region."), - ADDREMOVE_PLAYER_REACHED_LIMIT("addremove.player_reached_limit", ChatColor.RED + "This player has reached their region limit."), - ADDREMOVE_PLAYER_NEEDS_TO_BE_ONLINE("addremove.player_needs_to_be_online", ChatColor.RED + "The player needs to be online to add them."), + ADDREMOVE_OWNER_HELP("addremove.owner_help", + ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps addowner|removeowner [playername]"), + ADDREMOVE_OWNER_HELP_DESC("addremove.owner_help_desc", + "Use this command to add or remove an owner of your protected region."), + ADDREMOVE_PLAYER_REACHED_LIMIT("addremove.player_reached_limit", + ChatColor.RED + "This player has reached their region limit."), + ADDREMOVE_PLAYER_NEEDS_TO_BE_ONLINE("addremove.player_needs_to_be_online", + ChatColor.RED + "The player needs to be online to add them."), // ps get GET_HELP("get.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps get [block]"), GET_HELP_DESC("get.help_desc", "Use this command to get or purchase a protection block."), GET_GOTTEN("get.gotten", ChatColor.AQUA + "Added protection block to inventory!"), GET_NO_PERMISSION_BLOCK("get.no_permission_block", ChatColor.RED + "You don't have permission to get this block."), - GET_HEADER("get.header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Protect Blocks (click to get) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), - GET_GUI_BLOCK("get.gui_block", ChatColor.GRAY + "> " + ChatColor.AQUA + "%alias% " + ChatColor.GRAY + "- %description% (" + ChatColor.WHITE + "$%price%" + ChatColor.GRAY + ")"), + GET_HEADER("get.header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + + " Protect Blocks (click to get) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + GET_GUI_BLOCK("get.gui_block", + ChatColor.GRAY + "> " + ChatColor.AQUA + "%alias% " + ChatColor.GRAY + "- %description% (" + ChatColor.WHITE + + "$%price%" + ChatColor.GRAY + ")"), GET_GUI_HOVER("get.gui_hover", "Click to buy a %alias%!"), // ps give GIVE_HELP("give.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps give [block] [player] [amount (optional)]"), GIVE_HELP_DESC("give.help_desc", "Use this command to give a player a protection block."), - GIVE_GIVEN("give.given", ChatColor.GRAY + "Gave " + ChatColor.AQUA + "%block%" + ChatColor.GRAY + " to " + ChatColor.AQUA + "%player%" + ChatColor.GRAY + "."), + GIVE_GIVEN("give.given", + ChatColor.GRAY + "Gave " + ChatColor.AQUA + "%block%" + ChatColor.GRAY + " to " + ChatColor.AQUA + + "%player%" + ChatColor.GRAY + "."), GIVE_NO_INVENTORY_ROOM("give.no_inventory_room", ChatColor.RED + "The player does not have enough inventory room."), // ps sethome SETHOME_HELP("sethome.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps sethome"), SETHOME_HELP_DESC("sethome.help_desc", "Use this command to set the home of a region to where you are right now."), - SETHOME_SET("sethome.set", ChatColor.GRAY + "The home for " + ChatColor.AQUA + "%psid%" + ChatColor.GRAY + " has been set to your location."), + SETHOME_SET("sethome.set", + ChatColor.GRAY + "The home for " + ChatColor.AQUA + "%psid%" + ChatColor.GRAY + + " has been set to your location."), // ps list LIST_HELP("list.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps list [player (optional)]"), LIST_HELP_DESC("list.help_desc", "Use this command to list the regions you, or another player owns."), - LIST_HEADER("list.header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " %player%'s Regions " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + LIST_HEADER("list.header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " %player%'s Regions " + + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), LIST_OWNER("list.owner", ChatColor.GRAY + "Owner of:"), LIST_MEMBER("list.member", ChatColor.GRAY + "Member of:"), - LIST_NO_REGIONS("list.no_regions", ChatColor.GRAY + "You currently do not own and are not a member of any regions."), - LIST_NO_REGIONS_PLAYER("list.no_regions_player", ChatColor.AQUA + "%player% " + ChatColor.GRAY + "does not own and is not a member of any regions."), + LIST_NO_REGIONS("list.no_regions", + ChatColor.GRAY + "You currently do not own and are not a member of any regions."), + LIST_NO_REGIONS_PLAYER("list.no_regions_player", + ChatColor.AQUA + "%player% " + ChatColor.GRAY + "does not own and is not a member of any regions."), // ps name NAME_HELP("name.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps name [name|none]"), - NAME_HELP_DESC("name.help_desc", "Use this command to give a nickname to your region, to make identifying your region easier."), + NAME_HELP_DESC("name.help_desc", + "Use this command to give a nickname to your region, to make identifying your region easier."), NAME_REMOVED("name.removed", ChatColor.GRAY + "Removed the name for %id%."), - NAME_SET_NAME("name.set_name", ChatColor.GRAY + "Set the name of %id% to " + ChatColor.AQUA + "%name%" + ChatColor.GRAY + "."), - NAME_TAKEN("name.taken", ChatColor.GRAY + "The region name " + ChatColor.AQUA + "%name%" + ChatColor.GRAY + " has already been taken! Try another one."), + NAME_SET_NAME("name.set_name", + ChatColor.GRAY + "Set the name of %id% to " + ChatColor.AQUA + "%name%" + ChatColor.GRAY + "."), + NAME_TAKEN("name.taken", + ChatColor.GRAY + "The region name " + ChatColor.AQUA + "%name%" + ChatColor.GRAY + + " has already been taken! Try another one."), // ps setparent SETPARENT_HELP("setparent.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps setparent [region|none]"), - SETPARENT_HELP_DESC("setparent.help_desc", "Use this command to allow this region to inherit properties from another region (owners, members, flags, etc.)."), - SETPARENT_SUCCESS("setparent.success", ChatColor.GRAY + "Successfully set the parent of " + ChatColor.AQUA + "%id%" + ChatColor.GRAY + " to " + ChatColor.AQUA + "%parent%" + ChatColor.GRAY + "."), - SETPARENT_SUCCESS_REMOVE("setparent.success_remove", ChatColor.GRAY + "Successfully removed the parent of " + ChatColor.AQUA + "%id%" + ChatColor.GRAY + "."), - SETPARENT_CIRCULAR_INHERITANCE("setparent.circular_inheritance", ChatColor.RED + "Detected circular inheritance (the parent already inherits from this region?). Parent not set."), + SETPARENT_HELP_DESC("setparent.help_desc", + "Use this command to allow this region to inherit properties from another region (owners, members, flags, etc.)."), + SETPARENT_SUCCESS("setparent.success", + ChatColor.GRAY + "Successfully set the parent of " + ChatColor.AQUA + "%id%" + ChatColor.GRAY + " to " + + ChatColor.AQUA + "%parent%" + ChatColor.GRAY + "."), + SETPARENT_SUCCESS_REMOVE("setparent.success_remove", + ChatColor.GRAY + "Successfully removed the parent of " + ChatColor.AQUA + "%id%" + ChatColor.GRAY + "."), + SETPARENT_CIRCULAR_INHERITANCE("setparent.circular_inheritance", + ChatColor.RED + + "Detected circular inheritance (the parent already inherits from this region?). Parent not set."), // ps merge MERGE_HELP("merge.help", ChatColor.AQUA + "> " + ChatColor.GRAY + "/ps merge"), - MERGE_HELP_DESC("merge.help_desc", "Use this command to merge the region you are in with other overlapping regions."), + MERGE_HELP_DESC("merge.help_desc", + "Use this command to merge the region you are in with other overlapping regions."), MERGE_DISABLED("merge.disabled", "Merging regions is disabled in the config!"), MERGE_MERGED("merge.merged", ChatColor.AQUA + "Regions were successfully merged!"), - MERGE_HEADER("merge.header", ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + " Merge %region% (click to merge) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), - MERGE_WARNING("merge.warning", ChatColor.GRAY + "Note: This will delete all of the settings for the current region!"), + MERGE_HEADER("merge.header", + ChatColor.DARK_GRAY + "" + ChatColor.STRIKETHROUGH + "=====" + ChatColor.RESET + + " Merge %region% (click to merge) " + ChatColor.DARK_GRAY + ChatColor.STRIKETHROUGH + "====="), + MERGE_WARNING("merge.warning", + ChatColor.GRAY + "Note: This will delete all of the settings for the current region!"), MERGE_NOT_ALLOWED("merge.not_allowed", ChatColor.RED + "You are not allowed to merge this protection region type."), MERGE_INTO("merge.into", ChatColor.AQUA + "This region overlaps other regions you can merge into!"), MERGE_NO_REGIONS("merge.no_region", ChatColor.GRAY + "There are no overlapping regions to merge into."), MERGE_CLICK_TO_MERGE("merge.click_to_merge", "Click to merge with %region%!"), - MERGE_AUTO_MERGED("merge.auto_merged", ChatColor.GRAY + "Region automatically merged with " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + "."), + MERGE_AUTO_MERGED("merge.auto_merged", + ChatColor.GRAY + "Region automatically merged with " + ChatColor.AQUA + "%region%" + ChatColor.GRAY + "."), ; @@ -421,14 +583,14 @@ public String format(final Object... args) { } if (this.placeholdersCount != args.length) { - throw new IllegalArgumentException("Expected " + this.placeholdersCount + " arguments but got " + args.length); + throw new IllegalArgumentException( + "Expected " + this.placeholdersCount + " arguments but got " + args.length); } return StringUtils.replaceEach( this.message, this.placeholders, - Arrays.stream(args).filter(Objects::nonNull).map(Object::toString).toArray(String[]::new) - ); + Arrays.stream(args).filter(Objects::nonNull).map(Object::toString).toArray(String[]::new)); } public boolean send(@NotNull final CommandSender receiver, @NotNull final Object... args) { @@ -453,11 +615,45 @@ public void append(@NotNull final StringBuilder builder, @NotNull final Object.. public static boolean msg(CommandSender p, String str) { if (str != null && !str.isEmpty() && p != null) { - p.sendMessage(str); + String mm = legacyToMiniMessage(str); + ProtectionStones.getAdventure().sender(p).sendMessage(MiniMessage.miniMessage().deserialize(mm)); } return true; } + public static String legacyToMiniMessage(String str) { + if (str == null) + return ""; + + // Convert &#RRGGBB to <#RRGGBB> + str = str.replaceAll("(?i)[&§]#([a-f0-9]{6})", "<#$1>"); + + // Replace legacy characters + return str + .replace("&0", "").replace("§0", "") + .replace("&1", "").replace("§1", "") + .replace("&2", "").replace("§2", "") + .replace("&3", "").replace("§3", "") + .replace("&4", "").replace("§4", "") + .replace("&5", "").replace("§5", "") + .replace("&6", "").replace("§6", "") + .replace("&7", "").replace("§7", "") + .replace("&8", "").replace("§8", "") + .replace("&9", "").replace("§9", "") + .replace("&a", "").replace("§a", "") + .replace("&b", "").replace("§b", "") + .replace("&c", "").replace("§c", "") + .replace("&d", "").replace("§d", "") + .replace("&e", "").replace("§e", "") + .replace("&f", "").replace("§f", "") + .replace("&k", "").replace("§k", "") + .replace("&l", "").replace("§l", "") + .replace("&m", "").replace("§m", "") + .replace("&n", "").replace("§n", "") + .replace("&o", "").replace("§o", "") + .replace("&r", "").replace("§r", ""); + } + public static boolean msg(PSPlayer p, String str) { return msg(p.getPlayer(), str); } @@ -504,12 +700,13 @@ public static void loadConfig() { // message upgrades over time private static void messageUpgrades(PSL psl, YamlConfiguration yml) { String value = yml.getString(psl.path); - assert(value != null); + assert (value != null); // psl upgrade conversions if (psl == PSL.REACHED_REGION_LIMIT && value.equals("&cYou can not create any more protected regions.")) { yml.set(psl.path, psl.defaultMessage); - } else if (psl == PSL.REACHED_PER_BLOCK_REGION_LIMIT && value.equals("&cYou can not create any more regions of this type.")) { + } else if (psl == PSL.REACHED_PER_BLOCK_REGION_LIMIT + && value.equals("&cYou can not create any more regions of this type.")) { yml.set(psl.path, psl.defaultMessage); } else if (value.contains("§")) { yml.set(psl.path, applyConfigColours(value)); @@ -524,7 +721,8 @@ private static String applyInGameColours(String msg) { Matcher matcher = hexPattern.matcher(msg); while (matcher.find()) { String color = msg.substring(matcher.start() + 1, matcher.end()); - msg = msg.replace(msg.substring(matcher.start(), matcher.end()), "" + net.md_5.bungee.api.ChatColor.of(color)); + msg = msg.replace(msg.substring(matcher.start(), matcher.end()), + "" + net.md_5.bungee.api.ChatColor.of(color)); } return msg.replace('&', '§'); diff --git a/src/main/java/dev/espi/protectionstones/ProtectionStones.java b/src/main/java/dev/espi/protectionstones/ProtectionStones.java index bd1775f9..2b58ced8 100644 --- a/src/main/java/dev/espi/protectionstones/ProtectionStones.java +++ b/src/main/java/dev/espi/protectionstones/ProtectionStones.java @@ -52,9 +52,9 @@ import static com.google.common.base.Preconditions.checkNotNull; - /** - * The base class for the plugin. Some utilities are static, and others are instance methods, so they need to + * The base class for the plugin. Some utilities are static, and others are + * instance methods, so they need to * be accessed through getInstance(). */ @@ -76,7 +76,6 @@ public class ProtectionStones extends JavaPlugin { private PSConfig configOptions; static HashMap protectionStonesOptions = new HashMap<>(); - // ps alias to id cache // > static HashMap>> regionNameToID = new HashMap<>(); @@ -94,6 +93,15 @@ public class ProtectionStones extends JavaPlugin { // ps toggle/on/off list public static Set toggleList = new HashSet<>(); + private static net.kyori.adventure.platform.bukkit.BukkitAudiences adventure; + + public static net.kyori.adventure.platform.bukkit.BukkitAudiences getAdventure() { + if (adventure == null) { + throw new IllegalStateException("Tried to access Adventure when the plugin was disabled!"); + } + return adventure; + } + /* ~~~~~~~~~~ Instance methods ~~~~~~~~~~~~ */ /** @@ -164,6 +172,7 @@ public boolean isDebug() { /** * Print a debug message (only prints if the plugin is in debug mode). + * * @param msg the message to print */ public void debug(String msg) { @@ -194,12 +203,12 @@ public void setConfigOptions(PSConfig conf) { public List getConfiguredBlocks() { List l = new ArrayList<>(); for (PSProtectBlock b : protectionStonesOptions.values()) { - if (!l.contains(b)) l.add(b); + if (!l.contains(b)) + l.add(b); } return l; } - /* ~~~~~~~~~~ Static methods ~~~~~~~~~~~~~~ */ /** @@ -227,18 +236,21 @@ public static PSEconomy getEconomy() { * Get the protection block config options for the block specified. * * @param block the block to get the block options of - * @return the config options for the protect block specified (null if not found) + * @return the config options for the protect block specified (null if not + * found) */ public static PSProtectBlock getBlockOptions(Block block) { - if (block == null) return null; + if (block == null) + return null; return getBlockOptions(BlockUtil.getProtectBlockType(block)); } /** * Get the protection block config options for the item specified. * - * If the options has restrict-obtaining enabled, and the item does not contain the required NBT tag, null will + * If the options has restrict-obtaining enabled, and the item does not contain + * the required NBT tag, null will * be returned. * * @param item the item to get the block options of @@ -246,16 +258,20 @@ public static PSProtectBlock getBlockOptions(Block block) { */ public static PSProtectBlock getBlockOptions(ItemStack item) { - if (!isProtectBlockItem(item)) return null; + if (!isProtectBlockItem(item)) + return null; return getBlockOptions(BlockUtil.getProtectBlockType(item)); } /** - * Gets the config options for the protection block type specified. It is recommended to use the block parameter overloaded + * Gets the config options for the protection block type specified. It is + * recommended to use the block parameter overloaded * method instead if possible, since it deals better with heads. * - * @param blockType the material type name (Bukkit) of the protect block to get the options for, or "PLAYER_HEAD name" for heads - * @return the config options for the protect block specified (null if not found) + * @param blockType the material type name (Bukkit) of the protect block to get + * the options for, or "PLAYER_HEAD name" for heads + * @return the config options for the protect block specified (null if not + * found) */ public static PSProtectBlock getBlockOptions(String blockType) { return protectionStonesOptions.get(blockType); @@ -266,10 +282,13 @@ public static boolean isProtectBlockType(Block b) { } /** - * Get whether or not a material is used as a protection block. It is recommended to use the block - * parameter overloaded method if possible since player heads have a different format. + * Get whether or not a material is used as a protection block. It is + * recommended to use the block + * parameter overloaded method if possible since player heads have a different + * format. * - * @param material material type to check (Bukkit material name), or "PLAYER_HEAD name" for heads + * @param material material type to check (Bukkit material name), or + * "PLAYER_HEAD name" for heads * @return whether or not that material is being used for a protection block */ public static boolean isProtectBlockType(String material) { @@ -277,41 +296,52 @@ public static boolean isProtectBlockType(String material) { } /** - * Check whether or not a given block is a protection block, and actually protects a region. + * Check whether or not a given block is a protection block, and actually + * protects a region. + * * @param b the block to look at - * @return whether or not the block is a protection block responsible for a region. + * @return whether or not the block is a protection block responsible for a + * region. */ public static boolean isProtectBlock(Block b) { - if (!isProtectBlockType(b)) return false; + if (!isProtectBlockType(b)) + return false; RegionManager rgm = WGUtils.getRegionManagerWithWorld(b.getWorld()); - if (rgm == null) return false; - return rgm.getRegion(WGUtils.createPSID(b.getLocation())) != null || PSMergedRegion.getMergedRegion(b.getLocation()) != null; + if (rgm == null) + return false; + return rgm.getRegion(WGUtils.createPSID(b.getLocation())) != null + || PSMergedRegion.getMergedRegion(b.getLocation()) != null; } /** - * Check if a WorldGuard {@link ProtectedRegion} is a ProtectionStones region, and is configured in the config. + * Check if a WorldGuard {@link ProtectedRegion} is a ProtectionStones region, + * and is configured in the config. * * @param r the region to check - * @return true if the WorldGuard region is a ProtectionStones region, and false if it isn't + * @return true if the WorldGuard region is a ProtectionStones region, and false + * if it isn't */ public static boolean isPSRegion(ProtectedRegion r) { return isPSRegionFormat(r) && getBlockOptions(r.getFlag(FlagHandler.PS_BLOCK_MATERIAL)) != null; } /** - * Check if a WorldGuard {@link ProtectedRegion} has the format of a ProtectionStones region, but is not necessarily configured + * Check if a WorldGuard {@link ProtectedRegion} has the format of a + * ProtectionStones region, but is not necessarily configured * in the config. * * @param r the region to check - * @return true if the WorldGuard region is a ProtectionStones region, and false if it isn't + * @return true if the WorldGuard region is a ProtectionStones region, and false + * if it isn't */ public static boolean isPSRegionFormat(ProtectedRegion r) { return r != null && r.getId().startsWith("ps") && r.getFlag(FlagHandler.PS_BLOCK_MATERIAL) != null; } /** - * Check if a ProtectionStones name is already used by a region globally (from /ps name) + * Check if a ProtectionStones name is already used by a region globally (from + * /ps name) * * @param name the name to search for * @return whether or not there is a region with this name @@ -322,14 +352,16 @@ public static boolean isPSNameAlreadyUsed(String name) { RegionManager rgm = WGUtils.getRegionManagerWithWorld(Bukkit.getWorld(worldUid)); List l = regionNameToID.get(worldUid).get(name); - if (l == null) continue; + if (l == null) + continue; for (int i = 0; i < l.size(); i++) { // remove outdated cache if (rgm.getRegion(l.get(i)) == null) { l.remove(i); i--; } } - if (!l.isEmpty()) return true; + if (!l.isEmpty()) + return true; } return false; } @@ -337,14 +369,17 @@ public static boolean isPSNameAlreadyUsed(String name) { /** * Get protection stone regions using an ID or alias. * - * @param w the world to search in (only if it is an id; aliases/names are global) + * @param w the world to search in (only if it is an id; aliases/names + * are global) * @param identifier id or alias of the region - * @return a list of psregions that match the id or alias; will be empty if no regions were found + * @return a list of psregions that match the id or alias; will be empty if no + * regions were found */ public static List getPSRegions(World w, String identifier) { RegionManager rgm = WGUtils.getRegionManagerWithWorld(w); - if (rgm == null) return new ArrayList<>(); + if (rgm == null) + return new ArrayList<>(); PSRegion r = PSRegion.fromWGRegion(w, rgm.getRegion(identifier)); if (r != null) { // return id based query @@ -357,7 +392,8 @@ public static List getPSRegions(World w, String identifier) { } /** - * Removes a protection stone region given its ID, and the region manager it is stored in + * Removes a protection stone region given its ID, and the region manager it is + * stored in * Note: Does not remove the PS block. * * @param w the world that the region is in @@ -366,13 +402,16 @@ public static List getPSRegions(World w, String identifier) { */ public static boolean removePSRegion(World w, String psID) { - PSRegion r = PSRegion.fromWGRegion(checkNotNull(w), checkNotNull(WGUtils.getRegionManagerWithWorld(w).getRegion(psID))); + PSRegion r = PSRegion.fromWGRegion(checkNotNull(w), + checkNotNull(WGUtils.getRegionManagerWithWorld(w).getRegion(psID))); return r != null && r.deleteRegion(false); } /** - * Removes a protection stone region given its ID, and the region manager it is stored in, with a player as its cause - * Note: Does not remove the PS block, and does not check if the player (cause) has permission to do this. + * Removes a protection stone region given its ID, and the region manager it is + * stored in, with a player as its cause + * Note: Does not remove the PS block, and does not check if the player (cause) + * has permission to do this. * * @param w the world that the region is in * @param psID the worldguard region ID of the region @@ -381,7 +420,8 @@ public static boolean removePSRegion(World w, String psID) { */ public static boolean removePSRegion(World w, String psID, Player cause) { - PSRegion r = PSRegion.fromWGRegion(checkNotNull(w), checkNotNull(WGUtils.getRegionManagerWithWorld(w).getRegion(psID))); + PSRegion r = PSRegion.fromWGRegion(checkNotNull(w), + checkNotNull(WGUtils.getRegionManagerWithWorld(w).getRegion(psID))); return r != null && r.deleteRegion(false, cause); } @@ -393,41 +433,54 @@ public static boolean removePSRegion(World w, String psID, Player cause) { */ public static PSProtectBlock getProtectBlockFromAlias(String name) { - if (name == null) return null; + if (name == null) + return null; for (PSProtectBlock cpb : ProtectionStones.protectionStonesOptions.values()) { - if (cpb.alias.equalsIgnoreCase(name) || cpb.type.equalsIgnoreCase(name)) return cpb; + if (cpb.alias.equalsIgnoreCase(name) || cpb.type.equalsIgnoreCase(name)) + return cpb; } return null; } /** - * Check if an item is a valid protection block, and if checkNBT is true, check if it was created by - * ProtectionStones. Be aware that blocks may have restrict-obtaining off, meaning that it is ignored whether or not + * Check if an item is a valid protection block, and if checkNBT is true, check + * if it was created by + * ProtectionStones. Be aware that blocks may have restrict-obtaining off, + * meaning that it is ignored whether or not * the item is created by ProtectionStones (in this case have checkNBT false). * * @param item the item to check - * @param checkNBT whether or not to check if the plugin signed off on the item (restrict-obtaining) - * @return whether or not the item is a valid protection block item, and was created by protection stones + * @param checkNBT whether or not to check if the plugin signed off on the item + * (restrict-obtaining) + * @return whether or not the item is a valid protection block item, and was + * created by protection stones */ public static boolean isProtectBlockItem(ItemStack item, boolean checkNBT) { - if (item == null) return false; + if (item == null) + return false; // check basic item - if (!ProtectionStones.isProtectBlockType(BlockUtil.getProtectBlockType(item))) return false; + if (!ProtectionStones.isProtectBlockType(BlockUtil.getProtectBlockType(item))) + return false; // check for player heads - if (!checkNBT) return true; // if not checking nbt, you only need to check type + if (!checkNBT) + return true; // if not checking nbt, you only need to check type boolean tag = false; - // otherwise, check if the item was created by protection stones (stored in custom tag) + // otherwise, check if the item was created by protection stones (stored in + // custom tag) if (item.getItemMeta() != null) { CustomItemTagContainer tagContainer = item.getItemMeta().getCustomTagContainer(); try { // check if tag byte is 1 - Byte isPSBlock = tagContainer.getCustomTag(new NamespacedKey(ProtectionStones.getInstance(), "isPSBlock"), ItemTagType.BYTE); + Byte isPSBlock = tagContainer + .getCustomTag(new NamespacedKey(ProtectionStones.getInstance(), "isPSBlock"), ItemTagType.BYTE); tag = isPSBlock != null && isPSBlock == 1; } catch (IllegalArgumentException es) { - try { // some nbt data may be using a string (legacy nbt from ps version 2.0.0 -> 2.0.6) - String isPSBlock = tagContainer.getCustomTag(new NamespacedKey(ProtectionStones.getInstance(), "isPSBlock"), ItemTagType.STRING); + try { // some nbt data may be using a string (legacy nbt from ps version 2.0.0 -> + // 2.0.6) + String isPSBlock = tagContainer.getCustomTag( + new NamespacedKey(ProtectionStones.getInstance(), "isPSBlock"), ItemTagType.STRING); tag = isPSBlock != null && isPSBlock.equals("true"); } catch (IllegalArgumentException ignored) { } @@ -438,18 +491,24 @@ public static boolean isProtectBlockItem(ItemStack item, boolean checkNBT) { } /** - * Check if an item is a valid protection block, and if the block type has restrict-obtaining on, check if it was - * created by ProtectionStones (custom NBT tag). Be aware that blocks may have restrict-obtaining - * off, meaning that it ignores whether or not the item is created by ProtectionStones. + * Check if an item is a valid protection block, and if the block type has + * restrict-obtaining on, check if it was + * created by ProtectionStones (custom NBT tag). Be aware that blocks may have + * restrict-obtaining + * off, meaning that it ignores whether or not the item is created by + * ProtectionStones. * - * @param item the item to check - * @return whether or not the item is a valid protection block item, and was created by protection stones + * @param item the item to check + * @return whether or not the item is a valid protection block item, and was + * created by protection stones */ public static boolean isProtectBlockItem(ItemStack item) { - if (item == null) return false; + if (item == null) + return false; PSProtectBlock b = ProtectionStones.getBlockOptions(BlockUtil.getProtectBlockType(item)); - if (b == null) return false; + if (b == null) + return false; return isProtectBlockItem(item, b.restrictObtaining); } @@ -457,7 +516,8 @@ public static boolean isProtectBlockItem(ItemStack item) { * Get a protection block item from a protect block config object. * * @param b the config options for the protection block - * @return the item with NBT and other metadata to signify that it was created by protection stones + * @return the item with NBT and other metadata to signify that it was created + * by protection stones */ public static ItemStack createProtectBlockItem(PSProtectBlock b) { @@ -482,11 +542,17 @@ public static ItemStack createProtectBlockItem(PSProtectBlock b) { } // add display name and lore + net.kyori.adventure.text.minimessage.MiniMessage mm = net.kyori.adventure.text.minimessage.MiniMessage + .miniMessage(); + net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer lcs = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer + .builder().hexColors().useUnusualXRepeatedCharacterHexFormat().build(); + if (!b.displayName.equals("")) { - im.setDisplayName(ChatColor.translateAlternateColorCodes('&', b.displayName)); + im.setDisplayName(lcs.serialize(mm.deserialize(PSL.legacyToMiniMessage(b.displayName)))); } List lore = new ArrayList<>(); - for (String s : b.lore) lore.add(ChatColor.translateAlternateColorCodes('&', s)); + for (String s : b.lore) + lore.add(lcs.serialize(mm.deserialize(PSL.legacyToMiniMessage(s)))); im.setLore(lore); // hide enchant name (cannot call addUnsafeEnchantment here) @@ -517,7 +583,8 @@ public static void loadConfig(boolean isReload) { ArgHelp.initHelpMenu(); // load economy - if (ProtectionStones.getInstance().economy != null) ProtectionStones.getInstance().economy.stop(); + if (ProtectionStones.getInstance().economy != null) + ProtectionStones.getInstance().economy.stop(); ProtectionStones.getInstance().economy = new PSEconomy(); // add command to Bukkit (using reflection) @@ -549,6 +616,7 @@ public void onLoad() { @Override public void onEnable() { + adventure = net.kyori.adventure.platform.bukkit.BukkitAudiences.create(this); FlagHandler.registerHandlers(); // register custom WG flag handlers TomlFormat.instance(); @@ -568,15 +636,19 @@ public void onEnable() { // register event listeners getServer().getPluginManager().registerEvents(new ListenerClass(), this); - // check that WorldGuard and WorldEdit are enabled (WorldGuard will only be enabled if there's WorldEdit) - if (getServer().getPluginManager().getPlugin("WorldGuard") == null || !getServer().getPluginManager().getPlugin("WorldGuard").isEnabled()) { + // check that WorldGuard and WorldEdit are enabled (WorldGuard will only be + // enabled if there's WorldEdit) + if (getServer().getPluginManager().getPlugin("WorldGuard") == null + || !getServer().getPluginManager().getPlugin("WorldGuard").isEnabled()) { getLogger().severe("WorldGuard or WorldEdit not enabled! Disabling ProtectionStones..."); getServer().getPluginManager().disablePlugin(this); } // check if Vault is enabled (for economy support) - if (getServer().getPluginManager().getPlugin("Vault") != null && getServer().getPluginManager().getPlugin("Vault").isEnabled()) { - RegisteredServiceProvider econ = getServer().getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class); + if (getServer().getPluginManager().getPlugin("Vault") != null + && getServer().getPluginManager().getPlugin("Vault").isEnabled()) { + RegisteredServiceProvider econ = getServer().getServicesManager() + .getRegistration(net.milkbowl.vault.economy.Economy.class); if (econ == null) { getLogger().warning("No economy plugin found by Vault! There will be no economy support!"); vaultSupportEnabled = false; @@ -589,7 +661,8 @@ public void onEnable() { } // check for PlaceholderAPI - if (getServer().getPluginManager().getPlugin("PlaceholderAPI") != null && getServer().getPluginManager().getPlugin("PlaceholderAPI").isEnabled()) { + if (getServer().getPluginManager().getPlugin("PlaceholderAPI") != null + && getServer().getPluginManager().getPlugin("PlaceholderAPI").isEnabled()) { getLogger().info("PlaceholderAPI support enabled!"); placeholderAPISupportEnabled = true; new PSPlaceholderExpansion().register(); @@ -598,7 +671,8 @@ public void onEnable() { } // check for LuckPerms - if (getServer().getPluginManager().getPlugin("LuckPerms") != null && getServer().getPluginManager().getPlugin("LuckPerms").isEnabled()) { + if (getServer().getPluginManager().getPlugin("LuckPerms") != null + && getServer().getPluginManager().getPlugin("LuckPerms").isEnabled()) { try { luckPermsSupportEnabled = true; luckPerms = getServer().getServicesManager().load(LuckPerms.class); @@ -661,4 +735,12 @@ public void onEnable() { getLogger().info(ChatColor.WHITE + "ProtectionStones has successfully started!"); } + @Override + public void onDisable() { + if (adventure != null) { + adventure.close(); + adventure = null; + } + } + } \ No newline at end of file diff --git a/src/main/java/dev/espi/protectionstones/flags/PSMessageFlagHandler.java b/src/main/java/dev/espi/protectionstones/flags/PSMessageFlagHandler.java new file mode 100644 index 00000000..4f3396ff --- /dev/null +++ b/src/main/java/dev/espi/protectionstones/flags/PSMessageFlagHandler.java @@ -0,0 +1,76 @@ +package dev.espi.protectionstones.flags; + +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.flags.Flag; +import com.sk89q.worldguard.session.MoveType; +import com.sk89q.worldguard.session.Session; +import com.sk89q.worldguard.session.handler.FlagValueChangeHandler; +import com.sk89q.worldguard.session.handler.Handler; +import dev.espi.protectionstones.PSL; +import dev.espi.protectionstones.ProtectionStones; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +public class PSMessageFlagHandler extends FlagValueChangeHandler { + + private final boolean isActionBar; + + public static class Factory extends Handler.Factory { + private final Flag flag; + private final boolean isActionBar; + + public Factory(Flag flag, boolean isActionBar) { + this.flag = flag; + this.isActionBar = isActionBar; + } + + @Override + public PSMessageFlagHandler create(Session session) { + return new PSMessageFlagHandler(session, flag, isActionBar); + } + } + + public PSMessageFlagHandler(Session session, Flag flag, boolean isActionBar) { + super(session, flag); + this.isActionBar = isActionBar; + } + + private void sendMessage(LocalPlayer localPlayer, String message) { + if (message == null || message.isEmpty()) + return; + Player p = Bukkit.getPlayer(localPlayer.getUniqueId()); + if (p == null) + return; + + var component = MiniMessage.miniMessage().deserialize(PSL.legacyToMiniMessage(message)); + var audience = ProtectionStones.getAdventure().player(p); + + if (isActionBar) { + audience.sendActionBar(component); + } else { + audience.sendMessage(component); + } + } + + @Override + protected void onInitialValue(LocalPlayer localPlayer, ApplicableRegionSet applicableRegionSet, String s) { + } + + @Override + protected boolean onSetValue(LocalPlayer localPlayer, Location location, Location location1, + ApplicableRegionSet applicableRegionSet, String currentValue, String lastValue, MoveType moveType) { + if (currentValue != null && !currentValue.equals(lastValue)) { + sendMessage(localPlayer, currentValue); + } + return true; + } + + @Override + protected boolean onAbsentValue(LocalPlayer localPlayer, Location location, Location location1, + ApplicableRegionSet applicableRegionSet, String lastValue, MoveType moveType) { + return true; + } +}