From 843f437d0eec78290e332c44866537651287adbf Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Wed, 20 Oct 2021 22:24:10 +0200 Subject: [PATCH 01/28] Initial custom townblock types draft --- .../bukkit/config/ConfigNodes.java | 14 +- .../bukkit/towny/ChunkNotification.java | 10 +- src/com/palmergames/bukkit/towny/Towny.java | 4 + .../bukkit/towny/TownyAsciiMap.java | 2 +- .../bukkit/towny/TownyFormatter.java | 2 +- .../bukkit/towny/TownySettings.java | 189 +++++++++++++++--- .../bukkit/towny/command/PlotCommand.java | 53 ++--- .../bukkit/towny/command/TownyCommand.java | 4 +- .../bukkit/towny/db/TownyFlatFileSource.java | 8 +- .../bukkit/towny/db/TownySQLSource.java | 8 +- .../event/TownBlockTypeRegisterEvent.java | 37 ++++ .../palmergames/bukkit/towny/huds/MapHUD.java | 2 +- .../towny/listeners/TownyEntityListener.java | 6 +- .../towny/listeners/TownyPlayerListener.java | 14 +- .../towny/listeners/TownyVehicleListener.java | 2 +- .../bukkit/towny/object/TownBlock.java | 131 ++++++------ .../bukkit/towny/object/TownBlockData.java | 91 +++++++++ .../bukkit/towny/object/TownBlockType.java | 86 ++++---- .../towny/object/TownBlockTypeHandler.java | 120 ++++++++++- .../bukkit/towny/tasks/DailyTimerTask.java | 62 +++--- .../bukkit/towny/utils/PlayerCacheUtil.java | 46 ++--- .../palmergames/bukkit/util/ItemLists.java | 2 +- 22 files changed, 647 insertions(+), 246 deletions(-) create mode 100644 src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java create mode 100644 src/com/palmergames/bukkit/towny/object/TownBlockData.java diff --git a/src/com/palmergames/bukkit/config/ConfigNodes.java b/src/com/palmergames/bukkit/config/ConfigNodes.java index 72f36f8f7a..23ac076d8a 100644 --- a/src/com/palmergames/bukkit/config/ConfigNodes.java +++ b/src/com/palmergames/bukkit/config/ConfigNodes.java @@ -1405,6 +1405,18 @@ public enum ConfigNodes { "false", "", "# When set to true, players with the Frost Walker enchant will need to be able to build where they are attempting to freeze."), + TOWNBLOCKTYPES( + "townblocktypes", + "", + "", + "", + "############################################################", + "# +------------------------------------------------------+ #", + "# | Town Block Types | #", + "# +------------------------------------------------------+ #", + "############################################################", + ""), + TOWNBLOCKTYPES_TYPES("townblocktypes.types", ""), UNCLAIMED_ZONE( "unclaimed", "", @@ -1448,7 +1460,7 @@ public enum ConfigNodes { UNCLAIMED_ZONE_SWITCH("unclaimed.unclaimed_zone_switch", "false", "", - "# Can players interact with switch blocks listed in the above protectection.switch_ids in the wilderness without restriction?"), + "# Can players interact with switch blocks listed in the above protection.switch_ids in the wilderness without restriction?"), UNCLAIMED_ZONE_IGNORE( "unclaimed.unclaimed_zone_ignore", "SAPLING,GOLD_ORE,IRON_ORE,COAL_ORE,LOG,LEAVES,LAPIS_ORE,LONG_GRASS,YELLOW_FLOWER,RED_ROSE,BROWN_MUSHROOM,RED_MUSHROOM,TORCH,DIAMOND_ORE,LADDER,RAILS,REDSTONE_ORE,GLOWING_REDSTONE_ORE,CACTUS,CLAY,SUGAR_CANE_BLOCK,PUMPKIN,GLOWSTONE,LOG_2,VINE,NETHER_WARTS,COCOA", diff --git a/src/com/palmergames/bukkit/towny/ChunkNotification.java b/src/com/palmergames/bukkit/towny/ChunkNotification.java index 85010ca9c6..2164f4e375 100644 --- a/src/com/palmergames/bukkit/towny/ChunkNotification.java +++ b/src/com/palmergames/bukkit/towny/ChunkNotification.java @@ -72,7 +72,7 @@ public static void loadFormatStrings() { TownBlock fromTownBlock, toTownBlock = null; Town fromTown = null, toTown = null; Resident fromResident = null, toResident = null; - TownBlockType fromPlotType = null, toPlotType = null; + String fromPlotType = null, toPlotType = null; PlotGroup fromPlotGroup = null, toPlotGroup = null; public ChunkNotification(WorldCoord from, WorldCoord to) { @@ -82,7 +82,7 @@ public ChunkNotification(WorldCoord from, WorldCoord to) { if (from.hasTownBlock()) { fromTownBlock = from.getTownBlockOrNull(); - fromPlotType = fromTownBlock.getType(); + fromPlotType = StringMgmt.capitalize(fromTownBlock.getData().getType()); fromForSale = fromTownBlock.getPlotPrice() != -1; if (fromTownBlock.hasPlotObjectGroup()) { fromPlotGroup = fromTownBlock.getPlotObjectGroup(); @@ -98,7 +98,7 @@ public ChunkNotification(WorldCoord from, WorldCoord to) { if (to.hasTownBlock()) { toTownBlock = to.getTownBlockOrNull(); - toPlotType = toTownBlock.getType(); + toPlotType = StringMgmt.capitalize(toTownBlock.getData().getType()); toTown = toTownBlock.getTownOrNull(); toResident = toTownBlock.getResidentOrNull(); toForSale = toTownBlock.getPlotPrice() != -1; @@ -313,8 +313,8 @@ public String getGroupNotification() { public String getPlotTypeNotification() { - if (fromPlotType != toPlotType && toPlotType != null && toPlotType != TownBlockType.RESIDENTIAL) - return String.format(plotTypeNotificationFormat, toPlotType.toString()); + if (toPlotType != null && !toPlotType.equals(fromPlotType) && !TownBlockType.RESIDENTIAL.equals(toPlotType)) + return String.format(plotTypeNotificationFormat, toPlotType); return null; } } diff --git a/src/com/palmergames/bukkit/towny/Towny.java b/src/com/palmergames/bukkit/towny/Towny.java index 1c9fb3e12f..3605f63813 100644 --- a/src/com/palmergames/bukkit/towny/Towny.java +++ b/src/com/palmergames/bukkit/towny/Towny.java @@ -37,6 +37,7 @@ import com.palmergames.bukkit.towny.object.Coord; import com.palmergames.bukkit.towny.object.PlayerCache; import com.palmergames.bukkit.towny.object.Resident; +import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import com.palmergames.bukkit.towny.object.Translatable; import com.palmergames.bukkit.towny.object.Translation; import com.palmergames.bukkit.towny.object.WorldCoord; @@ -240,6 +241,9 @@ public void loadFoundation(boolean reload) { // Then load permissions loadPermissions(reload); + // Initialize the type handler after the config is loaded and before the database is. + TownBlockTypeHandler.initialize(); + // Initialize the special log4j hook logger. TownyLogger.getInstance(); diff --git a/src/com/palmergames/bukkit/towny/TownyAsciiMap.java b/src/com/palmergames/bukkit/towny/TownyAsciiMap.java index 644c995d5a..002543607f 100644 --- a/src/com/palmergames/bukkit/towny/TownyAsciiMap.java +++ b/src/com/palmergames/bukkit/towny/TownyAsciiMap.java @@ -131,7 +131,7 @@ else if (nation.hasEnemy(town.getNation())) } else if (townblock.isHomeBlock()) townyMap[y][x] = townyMap[y][x].content("H"); else - townyMap[y][x] = townyMap[y][x].content(townblock.getType().getAsciiMapKey()); + townyMap[y][x] = townyMap[y][x].content(townblock.getData().getMapKey()); TextComponent forSaleComponent = Component.empty(); TextComponent claimedAtComponent = Component.empty(); diff --git a/src/com/palmergames/bukkit/towny/TownyFormatter.java b/src/com/palmergames/bukkit/towny/TownyFormatter.java index f97d3688b1..6437996963 100644 --- a/src/com/palmergames/bukkit/towny/TownyFormatter.java +++ b/src/com/palmergames/bukkit/towny/TownyFormatter.java @@ -1049,7 +1049,7 @@ public static List getTaxStatus(Resident resident, Locale locale) { if (town != null) { if (taxExempt && town.hasResident(resident)) // Resident will not pay any tax for plots owned by their towns. continue; - plotTax += townBlock.getType().getTax(town); + plotTax += townBlock.getData().getTax(town); } } diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index b27078a099..4a25dcc37e 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -13,6 +13,7 @@ import com.palmergames.bukkit.towny.object.NationSpawnLevel.NSpawnLevel; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; +import com.palmergames.bukkit.towny.object.TownBlock; import com.palmergames.bukkit.towny.object.TownBlockOwner; import com.palmergames.bukkit.towny.object.TownSpawnLevel.SpawnLevel; import com.palmergames.bukkit.towny.object.TownyPermission.ActionType; @@ -28,14 +29,20 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; + import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; @@ -59,8 +66,8 @@ public enum NationLevel { private static final SortedMap> configTownLevel = Collections.synchronizedSortedMap(new TreeMap<>(Collections.reverseOrder())); private static final SortedMap> configNationLevel = Collections.synchronizedSortedMap(new TreeMap<>(Collections.reverseOrder())); - private static final List ItemUseMaterials = new ArrayList<>(); - private static final List SwitchUseMaterials = new ArrayList<>(); + private static final Set itemUseMaterials = new HashSet<>(); + private static final Set switchUseMaterials = new HashSet<>(); private static final List> protectedMobs = new ArrayList<>(); public static void newTownLevel(int numResidents, String namePrefix, String namePostfix, String mayorPrefix, String mayorPostfix, int townBlockLimit, double townUpkeepMultiplier, int townOutpostLimit, int townBlockBuyBonusLimit, double debtCapModifier) { @@ -302,8 +309,8 @@ private static void loadProtectedMobsList() { private static void loadSwitchAndItemUseMaterialsLists() { - SwitchUseMaterials.clear(); - ItemUseMaterials.clear(); + switchUseMaterials.clear(); + itemUseMaterials.clear(); /* * Load switches from config value. @@ -313,10 +320,11 @@ private static void loadSwitchAndItemUseMaterialsLists() { List switches = getStrArr(ConfigNodes.PROT_SWITCH_MAT); for (String matName : switches) { if (ItemLists.GROUPS.contains(matName)) { - List group = ItemLists.getGrouping(matName); - SwitchUseMaterials.addAll(group); + switchUseMaterials.addAll(toMaterialSet(ItemLists.getGrouping(matName))); } else { - SwitchUseMaterials.add(matName); + Material material = Material.matchMaterial(matName); + if (material != null) + itemUseMaterials.add(material); } } @@ -328,13 +336,25 @@ private static void loadSwitchAndItemUseMaterialsLists() { List items = getStrArr(ConfigNodes.PROT_ITEM_USE_MAT); for (String matName : items) { if (ItemLists.GROUPS.contains(matName)) { - List group = ItemLists.getGrouping(matName); - ItemUseMaterials.addAll(group); + itemUseMaterials.addAll(toMaterialSet(ItemLists.getGrouping(matName))); } else { - ItemUseMaterials.add(matName); + Material material = Material.matchMaterial(matName); + if (material != null) + itemUseMaterials.add(material); } } } + + private static Set toMaterialSet(List materialList) { + Set materials = new HashSet<>(); + for (String materialName : materialList) { + Material material = Material.matchMaterial(materialName); + if (material != null) + materials.add(material); + } + + return materials; + } public static void sendError(String msg) { Towny.getPlugin().getLogger().warning(() -> String.format("Error could not read %s",msg)); @@ -480,17 +500,13 @@ private static void setDefaults(String version, Path configPath) { setDefaultLevels(); - } else if ( (root.getRoot().equals(ConfigNodes.LEVELS_TOWN_LEVEL.getRoot())) - || (root.getRoot().equals(ConfigNodes.LEVELS_NATION_LEVEL.getRoot())) ){ - - // Do nothing here as setDefaultLevels configured town and - // nation levels. - } else if (root.getRoot().equals(ConfigNodes.VERSION.getRoot())) { setNewProperty(root.getRoot(), version); } else if (root.getRoot().equals(ConfigNodes.LAST_RUN_VERSION.getRoot())) { setNewProperty(root.getRoot(), getLastRunVersion(version)); - } else + } else if (root.getRoot().equals(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot())) + setTownBlockTypes(); + else setNewProperty(root.getRoot(), (config.get(root.getRoot().toLowerCase()) != null) ? config.get(root.getRoot().toLowerCase()) : root.getDefault()); } @@ -711,6 +727,102 @@ private static void setDefaultLevels() { } else newConfig.set(ConfigNodes.LEVELS_NATION_LEVEL.getRoot(), config.get(ConfigNodes.LEVELS_NATION_LEVEL.getRoot())); } + + private static void setTownBlockTypes() { + addComment(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot(), + "# Townblock types config", + "# If empty, itemUseIds & switchIds will use values defined in protection.item_use_ids and protection.switch_ids.", + "# Allowed blocks are blocks that will always be allowed to be placed and broken in a plot.", + "# If tax is set to 0, the towns' plot tax will be used instead." + ); + + if (!config.contains(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot())) { + List> types = new ArrayList<>(); + Map type = new LinkedHashMap<>(); + + type.put("name", "default"); + type.put("cost", 0.0); + type.put("tax", 0.0); + type.put("mapKey", "+"); + type.put("itemUseIds", ""); + type.put("switchIds", ""); + type.put("allowedBlocks", ""); + types.add(new LinkedHashMap<>(type)); + type.clear(); + + type.put("name", "shop"); + type.put("cost", 0.0); + type.put("tax", 0.0); + type.put("mapKey", "C"); + type.put("itemUseIds", ""); + type.put("switchIds", ""); + type.put("allowedBlocks", ""); + types.add(new LinkedHashMap<>(type)); + type.clear(); + + type.put("name", "arena"); + type.put("cost", 0.0); + type.put("tax", 0.0); + type.put("mapKey", "A"); + type.put("itemUseIds", ""); + type.put("switchIds", ""); + type.put("allowedBlocks", ""); + types.add(new LinkedHashMap<>(type)); + type.clear(); + + type.put("name", "wilds"); + type.put("cost", 0.0); + type.put("tax", 0.0); + type.put("mapKey", "W"); + type.put("itemUseIds", ""); + type.put("switchIds", ""); + type.put("allowedBlocks", ""); + types.add(new LinkedHashMap<>(type)); + type.clear(); + + type.put("name", "inn"); + type.put("cost", 0.0); + type.put("tax", 0.0); + type.put("mapKey", "I"); + type.put("itemUseIds", ""); + type.put("switchIds", ""); + type.put("allowedBlocks", ""); + types.add(new LinkedHashMap<>(type)); + type.clear(); + + type.put("name", "jail"); + type.put("cost", 0.0); + type.put("tax", 0.0); + type.put("mapKey", "J"); + type.put("itemUseIds", ""); + type.put("switchIds", ""); + type.put("allowedBlocks", ""); + types.add(new LinkedHashMap<>(type)); + type.clear(); + + type.put("name", "farm"); + type.put("cost", 0.0); + type.put("tax", 0.0); + type.put("mapKey", "F"); + type.put("itemUseIds", ""); + type.put("switchIds", ""); + type.put("allowedBlocks", "BAMBOO,BAMBOO_SAPLING,JUNGLE_LOG,JUNGLE_SAPLING,JUNGLE_LEAVES,OAK_LOG,OAK_SAPLING,OAK_LEAVES,BIRCH_LOG,BIRCH_SAPLING,BIRCH_LEAVES,ACACIA_LOG,ACACIA_SAPLING,ACACIA_LEAVES,DARK_OAK_LOG,DARK_OAK_SAPLING,DARK_OAK_LEAVES,SPRUCE_LOG,SPRUCE_SAPLING,SPRUCE_LEAVES,BEETROOTS,COCOA,CHORUS_PLANT,CHORUS_FLOWER,SWEET_BERRY_BUSH,KELP,SEAGRASS,TALL_SEAGRASS,GRASS,TALL_GRASS,FERN,LARGE_FERN,CARROTS,WHEAT,POTATOES,PUMPKIN,PUMPKIN_STEM,ATTACHED_PUMPKIN_STEM,NETHER_WART,COCOA,VINE,MELON,MELON_STEM,ATTACHED_MELON_STEM,SUGAR_CANE,CACTUS,ALLIUM,AZURE_BLUET,BLUE_ORCHID,CORNFLOWER,DANDELION,LILAC,LILY_OF_THE_VALLEY,ORANGE_TULIP,OXEYE_DAISY,PEONY,PINK_TULIP,POPPY,RED_TULIP,ROSE_BUSH,SUNFLOWER,WHITE_TULIP,WITHER_ROSE,CRIMSON_FUNGUS,CRIMSON_STEM,CRIMSON_HYPHAE,CRIMSON_ROOTS,MUSHROOM_STEM,NETHER_WART_BLOCK,BROWN_MUSHROOM,BROWN_MUSHROOM_BLOCK,RED_MUSHROOM,RED_MUSHROOM_BLOCK,SHROOMLIGHT,WARPED_FUNGUS,WARPED_HYPHAE,WARPED_ROOTS,WARPED_STEM,WARPED_WART_BLOCK,WEEPING_VINES_PLANT,WEEPING_VINES,NETHER_SPROUTS,SHEARS"); + types.add(new LinkedHashMap<>(type)); + type.clear(); + + type.put("name", "bank"); + type.put("cost", 0.0); + type.put("tax", 0.0); + type.put("mapKey", "B"); + type.put("itemUseIds", ""); + type.put("switchIds", ""); + type.put("allowedBlocks", ""); + types.add(new LinkedHashMap<>(type)); + type.clear(); + newConfig.set(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot(), types); + } else + newConfig.set(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot(), config.get(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot())); + } public static String getKingPrefix(Resident resident) { @@ -1316,24 +1428,52 @@ public static double getOutpostCost() { return getDouble(ConfigNodes.ECO_PRICE_OUTPOST); } - public static List getSwitchMaterials() { + public static Set getSwitchMaterials() { - return SwitchUseMaterials; + return switchUseMaterials; } - public static List getItemUseMaterials() { + public static Set getItemUseMaterials() { - return ItemUseMaterials; + return itemUseMaterials; } + /** + * For compatibility with custom plot types, this has been deprecated. Please use {@link #isSwitchMaterial(Material, Location)} instead. + * @param mat The name of the material. + * @return Whether this is a switch material or not. + */ + @Deprecated public static boolean isSwitchMaterial(String mat) { + return switchUseMaterials.contains(Material.matchMaterial(mat)); + } + + public static boolean isSwitchMaterial(Material material, Location location) { + if (!TownyAPI.getInstance().isWilderness(location)) { - return SwitchUseMaterials.contains(mat); + TownBlock townBlock = TownyAPI.getInstance().getTownBlock(location); + return townBlock.getData().getSwitchIds().contains(material); + } else + return switchUseMaterials.contains(material); } + /** + * For compatibility with custom plot types, this has been deprecated. Please use {@link #isItemUseMaterial(Material, Location)} instead. + * @param mat The name of the material. + * @return Whether this is an item use material or not. + */ + @Deprecated public static boolean isItemUseMaterial(String mat) { + return itemUseMaterials.contains(Material.matchMaterial(mat)); + } + + public static boolean isItemUseMaterial(Material material, Location location) { + if (!TownyAPI.getInstance().isWilderness(location)) { - return ItemUseMaterials.contains(mat); + TownBlock townBlock = TownyAPI.getInstance().getTownBlock(location); + return townBlock.getData().getItemUseIds().contains(material); + } else + return itemUseMaterials.contains(material); } public static List getFireSpreadBypassMaterials() { @@ -2515,8 +2655,9 @@ public static double getNationRequiresProximity() { return getDouble(ConfigNodes.GTOWN_SETTINGS_NATION_REQUIRES_PROXIMITY); } + @Deprecated public static List getFarmPlotBlocks() { - return getStrArr(ConfigNodes.GTOWN_FARM_PLOT_ALLOW_BLOCKS); + return Collections.emptyList(); } public static List getFarmAnimals() { diff --git a/src/com/palmergames/bukkit/towny/command/PlotCommand.java b/src/com/palmergames/bukkit/towny/command/PlotCommand.java index 4a96bfcb6d..5c9be2cbfd 100644 --- a/src/com/palmergames/bukkit/towny/command/PlotCommand.java +++ b/src/com/palmergames/bukkit/towny/command/PlotCommand.java @@ -32,8 +32,10 @@ import com.palmergames.bukkit.towny.object.SpawnPointLocation; import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.TownBlock; +import com.palmergames.bukkit.towny.object.TownBlockData; import com.palmergames.bukkit.towny.object.TownBlockOwner; import com.palmergames.bukkit.towny.object.TownBlockType; +import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import com.palmergames.bukkit.towny.object.TownyPermission; import com.palmergames.bukkit.towny.object.TownyPermissionChange; import com.palmergames.bukkit.towny.object.TownyWorld; @@ -683,10 +685,8 @@ public boolean parsePlotCommand(Player player, String[] split) { // Handle type being reset if (plotTypeName.equalsIgnoreCase("reset")) plotTypeName = "default"; - - TownBlockType townBlockType = TownBlockType.lookup(plotTypeName); - if (townBlockType == null) + if (!TownBlockTypeHandler.exists(plotTypeName)) throw new TownyException(Translatable.of("msg_err_not_block_type")); try { @@ -706,46 +706,48 @@ public boolean parsePlotCommand(Player player, String[] split) { } } - PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(townBlockType, townBlock, resident); + PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(TownBlockType.lookup(plotTypeName), townBlock, resident); BukkitTools.getPluginManager().callEvent(preEvent); if (preEvent.isCancelled()) { TownyMessaging.sendErrorMsg(player, preEvent.getCancelMessage()); return false; } - - double cost = townBlockType.getCost(); + + TownBlockData data = TownBlockTypeHandler.getData(plotTypeName); + double cost = data.getCost(); + final String finalName = plotTypeName; // Test if we can pay first to throw an exception. if (cost > 0 && TownyEconomyHandler.isActive() && !resident.getAccount().canPayFromHoldings(cost)) - throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", townBlockType, TownyEconomyHandler.getFormattedBalance(cost))); + throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", plotTypeName, TownyEconomyHandler.getFormattedBalance(cost))); // Handle payment via a confirmation to avoid suprise costs. if (cost > 0 && TownyEconomyHandler.isActive()) { Confirmation.runOnAccept(() -> { - if (!resident.getAccount().withdraw(cost, String.format("Plot set to %s", townBlockType))) { - TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", townBlockType, TownyEconomyHandler.getFormattedBalance(cost))); + if (!resident.getAccount().withdraw(cost, String.format("Plot set to %s", finalName))) { + TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", finalName, TownyEconomyHandler.getFormattedBalance(cost))); return; } - TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), townBlockType)); + TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), finalName)); try { - townBlock.setType(townBlockType, resident); + townBlock.setType(finalName, resident); } catch (TownyException e) { TownyMessaging.sendErrorMsg(resident, e.getMessage(player)); return; } - TownyMessaging.sendMsg(player, Translatable.of("msg_plot_set_type", townBlockType)); + TownyMessaging.sendMsg(player, Translatable.of("msg_plot_set_type", finalName)); }) .setTitle(Translatable.of("msg_confirm_purchase", TownyEconomyHandler.getFormattedBalance(cost))) .sendTo(BukkitTools.getPlayerExact(resident.getName())); // No cost or economy so no confirmation. } else { - townBlock.setType(townBlockType, resident); + townBlock.setType(plotTypeName, resident); TownyMessaging.sendMsg(player, Translatable.of("msg_plot_set_type", plotTypeName)); } } catch (TownyException te){ @@ -1725,9 +1727,7 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow if (plotTypeName.equalsIgnoreCase("reset")) plotTypeName = "default"; - TownBlockType type = TownBlockType.lookup(plotTypeName); - - if (type == null) + if (!TownBlockTypeHandler.exists(plotTypeName)) throw new TownyException(Translatable.of("msg_err_not_block_type")); for (TownBlock tb : townBlock.getPlotObjectGroup().getTownBlocks()) { @@ -1750,7 +1750,7 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow } // Allow for PlotPreChangeTypeEvent to trigger - PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(type, tb, resident); + PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(TownBlockType.lookup(plotTypeName), tb, resident); BukkitTools.getPluginManager().callEvent(preEvent); // If any one of the townblocks is not allowed to be set, cancel setting all of them. @@ -1760,33 +1760,34 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow } } - int amount = townBlock.getPlotObjectGroup().getTownBlocks().size(); - double cost = type.getCost() * amount; + TownBlockData data = TownBlockTypeHandler.getData(plotTypeName); + int amount = townBlock.getPlotObjectGroup().getTownBlocks().size(); + double cost = data.getCost() * amount; try { // Test if we can pay first to throw an exception. if (cost > 0 && TownyEconomyHandler.isActive() && !resident.getAccount().canPayFromHoldings(cost)) - throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", type, TownyEconomyHandler.getFormattedBalance(cost))); + throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", data.getType(), TownyEconomyHandler.getFormattedBalance(cost))); // Handle payment via a confirmation to avoid suprise costs. if (cost > 0 && TownyEconomyHandler.isActive()) { Confirmation.runOnAccept(() -> { - if (!resident.getAccount().withdraw(cost, String.format("Plot (" + amount + ") set to %s", type))) { - TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", type, TownyEconomyHandler.getFormattedBalance(cost))); + if (!resident.getAccount().withdraw(cost, String.format("Plot (" + amount + ") set to %s", data.getType()))) { + TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", data.getType(), TownyEconomyHandler.getFormattedBalance(cost))); return; } - TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), type)); + TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), data.getType())); for (TownBlock tb : townBlock.getPlotObjectGroup().getTownBlocks()) { try { - tb.setType(type, resident); + tb.setType(data.getType(), resident); } catch (TownyException ignored) { // Cannot be set to jail type as a group. } } - TownyMessaging.sendMsg(player, Translatable.of("msg_set_group_type_to_x", type)); + TownyMessaging.sendMsg(player, Translatable.of("msg_set_group_type_to_x", data.getType())); }) .setTitle(Translatable.of("msg_confirm_purchase", TownyEconomyHandler.getFormattedBalance(cost))) @@ -1796,7 +1797,7 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow } else { for (TownBlock tb : townBlock.getPlotObjectGroup().getTownBlocks()) - tb.setType(type, resident); + tb.setType(data.getType(), resident); TownyMessaging.sendMsg(player, Translatable.of("msg_set_group_type_to_x", plotTypeName)); } diff --git a/src/com/palmergames/bukkit/towny/command/TownyCommand.java b/src/com/palmergames/bukkit/towny/command/TownyCommand.java index 51ed187bfa..a1e8793534 100644 --- a/src/com/palmergames/bukkit/towny/command/TownyCommand.java +++ b/src/com/palmergames/bukkit/towny/command/TownyCommand.java @@ -232,7 +232,7 @@ else if (split.length > 1 && split[1].equalsIgnoreCase("hud")) for (String line : getTownyPrices(town, Translation.getLocale(player))) TownyMessaging.sendMessage(player, line); - } else if (split[0].equalsIgnoreCase("switches")) { + /*} else if (split[0].equalsIgnoreCase("switches")) { Resident resident = getResidentOrThrow(player.getUniqueId()); ResidentUtil.openGUIInventory(resident, TownySettings.getSwitchMaterials(), Translatable.of("gui_title_towny_switch").forLocale(player)); } else if (split[0].equalsIgnoreCase("itemuse")) { @@ -244,7 +244,7 @@ else if (split.length > 1 && split[1].equalsIgnoreCase("hud")) } else if (split[0].equalsIgnoreCase("wildsblocks")) { Resident resident = getResidentOrThrow(player.getUniqueId()); ResidentUtil.openGUIInventory(resident, world.getUnclaimedZoneIgnoreMaterials(), Translatable.of("gui_title_towny_wildsblocks").forLocale(player)); - } else if (split[0].equalsIgnoreCase("plotclearblocks")) { + */} else if (split[0].equalsIgnoreCase("plotclearblocks")) { Resident resident = getResidentOrThrow(player.getUniqueId()); ResidentUtil.openGUIInventory(resident, world.getPlotManagementMayorDelete(), Translatable.of("gui_title_towny_plotclear").forLocale(player)); } else if (split[0].equalsIgnoreCase("top")) { diff --git a/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java b/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java index c2e9fd7dfc..b8f6363343 100644 --- a/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java +++ b/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java @@ -1625,7 +1625,11 @@ else if (universe.getReplacementNameMap().containsKey(line.trim())) line = keys.get("type"); if (line != null) - townBlock.setType(TownBlockTypeHandler.getTypeInternal(line)); + try { + townBlock.setType(Integer.parseInt(line)); + } catch (Exception e) { + townBlock.setType(line); + } line = keys.get("outpost"); if (line != null) @@ -2258,7 +2262,7 @@ public boolean saveTownBlock(TownBlock townBlock) { list.add("resident=" + townBlock.getResidentOrNull().getName()); // type - list.add("type=" + townBlock.getType().getId()); + list.add("type=" + townBlock.getTypeName()); // outpost list.add("outpost=" + townBlock.isOutpost()); diff --git a/src/com/palmergames/bukkit/towny/db/TownySQLSource.java b/src/com/palmergames/bukkit/towny/db/TownySQLSource.java index 6b01ff9774..88ea24c2bf 100644 --- a/src/com/palmergames/bukkit/towny/db/TownySQLSource.java +++ b/src/com/palmergames/bukkit/towny/db/TownySQLSource.java @@ -1791,7 +1791,11 @@ public boolean loadTownBlocks() { line = rs.getString("type"); if (line != null) - townBlock.setType(TownBlockTypeHandler.getTypeInternal(line)); + try { + townBlock.setType(Integer.parseInt(line)); + } catch (Exception e) { + townBlock.setType(line); + } boolean outpost = rs.getBoolean("outpost"); if (line != null && !line.isEmpty()) @@ -2413,7 +2417,7 @@ public synchronized boolean saveTownBlock(TownBlock townBlock) { tb_hm.put("price", townBlock.getPlotPrice()); tb_hm.put("town", townBlock.getTown().getName()); tb_hm.put("resident", (townBlock.hasResident()) ? townBlock.getResidentOrNull().getName() : ""); - tb_hm.put("type", townBlock.getType().getId()); + tb_hm.put("type", townBlock.getTypeName()); tb_hm.put("outpost", townBlock.isOutpost()); tb_hm.put("permissions", (townBlock.isChanged()) ? townBlock.getPermissions().toString().replaceAll(",", "#") : ""); diff --git a/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java b/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java new file mode 100644 index 0000000000..56453a8f33 --- /dev/null +++ b/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java @@ -0,0 +1,37 @@ +package com.palmergames.bukkit.towny.event; + +import com.palmergames.bukkit.towny.exceptions.TownyException; +import com.palmergames.bukkit.towny.object.TownBlockData; +import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class TownBlockTypeRegisterEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + public TownBlockTypeRegisterEvent() { + super(!Bukkit.isPrimaryThread()); + } + + /** + * Registers a new type. + * @param name - The name for this type. + * @param data - The data for this type. + * @throws TownyException - If a type with this name is already registered. + */ + public static void registerType(@NotNull String name, @Nullable TownBlockData data) throws TownyException { + TownBlockTypeHandler.registerType(name, data); + } + + @Override + public @NotNull HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/palmergames/bukkit/towny/huds/MapHUD.java b/src/com/palmergames/bukkit/towny/huds/MapHUD.java index c4f91b9e39..c3e9e9e8bc 100644 --- a/src/com/palmergames/bukkit/towny/huds/MapHUD.java +++ b/src/com/palmergames/bukkit/towny/huds/MapHUD.java @@ -133,7 +133,7 @@ else if (nation.hasEnemy(townblock.getTown().getNation())) } else if (townblock.isHomeBlock()) map[y][x] += "H"; else - map[y][x] += townblock.getType().getAsciiMapKey(); + map[y][x] += townblock.getData().getMapKey(); } catch (TownyException e) { // Unregistered town block diff --git a/src/com/palmergames/bukkit/towny/listeners/TownyEntityListener.java b/src/com/palmergames/bukkit/towny/listeners/TownyEntityListener.java index cef143627f..dfb63948d1 100644 --- a/src/com/palmergames/bukkit/towny/listeners/TownyEntityListener.java +++ b/src/com/palmergames/bukkit/towny/listeners/TownyEntityListener.java @@ -470,7 +470,7 @@ public void onEntityInteract(EntityInteractEvent event) { for (Entity passenger : passengers) { if (!passenger.getType().equals(EntityType.PLAYER)) return; - if (TownySettings.isSwitchMaterial(block.getType().name())) { + if (TownySettings.isSwitchMaterial(block.getType(), block.getLocation())) { //Make decision on whether this is allowed using the PlayerCache and then a cancellable event. event.setCancelled(!TownyActionEventExecutor.canSwitch((Player) passenger, block.getLocation(), block.getType())); return; @@ -832,7 +832,7 @@ public void onProjectileHitEventButtonOrPlate(ProjectileHitEvent event) { Block block = event.getHitBlock().getRelative(event.getHitBlockFace()); Material material = block.getType(); - if (ItemLists.PROJECTILE_TRIGGERED_REDSTONE.contains(material.name()) && TownySettings.isSwitchMaterial(material.name())) { + if (ItemLists.PROJECTILE_TRIGGERED_REDSTONE.contains(material.name()) && TownySettings.isSwitchMaterial(material, block.getLocation())) { //Make decision on whether this is allowed using the PlayerCache and then a cancellable event. if (!TownyActionEventExecutor.canSwitch((Player) event.getEntity().getShooter(), block.getLocation(), material)) { /* @@ -860,7 +860,7 @@ public void onProjectileHitEventTarget(ProjectileHitEvent event) { if (plugin.isError() || !Towny.is116Plus() || !TownyAPI.getInstance().isTownyWorld(event.getEntity().getWorld()) || event.getHitBlock() == null || !(event.getEntity().getShooter() instanceof Player)) return; - if (event.getHitBlock().getType() == Material.TARGET && TownySettings.isSwitchMaterial(Material.TARGET.name())) { + if (event.getHitBlock().getType() == Material.TARGET && TownySettings.isSwitchMaterial(Material.TARGET, event.getHitBlock().getLocation())) { //Make decision on whether this is allowed using the PlayerCache and then a cancellable event. if (!TownyActionEventExecutor.canSwitch((Player) event.getEntity().getShooter(), event.getHitBlock().getLocation(), Material.TARGET)) { diff --git a/src/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java b/src/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java index 4311546898..15c82d5b37 100644 --- a/src/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java +++ b/src/com/palmergames/bukkit/towny/listeners/TownyPlayerListener.java @@ -281,7 +281,7 @@ public void onPlayerInteract(PlayerInteractEvent event) { /* * Test item_use. */ - if (TownySettings.isItemUseMaterial(item.name())) + if (TownySettings.isItemUseMaterial(item, loc)) event.setCancelled(!TownyActionEventExecutor.canItemuse(player, loc, item)); /* @@ -345,7 +345,7 @@ public void onPlayerInteract(PlayerInteractEvent event) { /* * Test switch use. */ - if (TownySettings.isSwitchMaterial(clickedMat.name())) { + if (TownySettings.isSwitchMaterial(clickedMat, clickedBlock.getLocation())) { //Make decision on whether this is allowed using the PlayerCache and then a cancellable event. event.setCancelled(!TownyActionEventExecutor.canSwitch(player, clickedBlock.getLocation(), clickedMat)); return; @@ -554,7 +554,7 @@ public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { return; } // Material has been supplied in place of an entity, run Switch Tests. - if (TownySettings.isSwitchMaterial(mat.name()) && actionType == ActionType.SWITCH) { + if (TownySettings.isSwitchMaterial(mat, event.getRightClicked().getLocation()) && actionType == ActionType.SWITCH) { //Make decision on whether this is allowed using the PlayerCache and then a cancellable event. event.setCancelled(!TownyActionEventExecutor.canSwitch(player, event.getRightClicked().getLocation(), mat)); return; @@ -587,7 +587,7 @@ public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { /* * Item_use protection. */ - if (TownySettings.isItemUseMaterial(item.name())) { + if (TownySettings.isItemUseMaterial(item, event.getRightClicked().getLocation())) { //Make decision on whether this is allowed using the PlayerCache and then a cancellable event. event.setCancelled(!TownyActionEventExecutor.canItemuse(player, event.getRightClicked().getLocation(), item)); return; @@ -715,7 +715,7 @@ public void onPlayerTeleport(PlayerTeleportEvent event) { /* * Test to see if CHORUS_FRUIT is in the item_use list. */ - if (event.getCause() == TeleportCause.CHORUS_FRUIT && TownySettings.isItemUseMaterial(Material.CHORUS_FRUIT.name())) { + if (event.getCause() == TeleportCause.CHORUS_FRUIT && TownySettings.isItemUseMaterial(Material.CHORUS_FRUIT, event.getTo())) { //Make decision on whether this is allowed using the PlayerCache and then a cancellable event. if (!TownyActionEventExecutor.canItemuse(event.getPlayer(), event.getTo(), Material.CHORUS_FRUIT)) { event.setCancelled(true); @@ -726,7 +726,7 @@ public void onPlayerTeleport(PlayerTeleportEvent event) { /* * Test to see if Ender pearls are disabled. */ - if (event.getCause() == TeleportCause.ENDER_PEARL && TownySettings.isItemUseMaterial(Material.ENDER_PEARL.name())) { + if (event.getCause() == TeleportCause.ENDER_PEARL && TownySettings.isItemUseMaterial(Material.ENDER_PEARL, event.getTo())) { //Make decision on whether this is allowed using the PlayerCache and then a cancellable event. if (!TownyActionEventExecutor.canItemuse(event.getPlayer(), event.getTo(), Material.ENDER_PEARL)) { event.setCancelled(true); @@ -1285,7 +1285,7 @@ public void onAdminToolUseOnEntities(PlayerInteractEntityEvent event) { @EventHandler(priority = EventPriority.NORMAL) public void onEggLand(PlayerEggThrowEvent event) { - if (TownySettings.isItemUseMaterial(Material.EGG.name()) && !TownyActionEventExecutor.canItemuse(event.getPlayer(), event.getEgg().getLocation(), Material.EGG)) + if (TownySettings.isItemUseMaterial(Material.EGG, event.getEgg().getLocation()) && !TownyActionEventExecutor.canItemuse(event.getPlayer(), event.getEgg().getLocation(), Material.EGG)) event.setHatching(false); } } diff --git a/src/com/palmergames/bukkit/towny/listeners/TownyVehicleListener.java b/src/com/palmergames/bukkit/towny/listeners/TownyVehicleListener.java index a328770f3a..95f8bb74f8 100644 --- a/src/com/palmergames/bukkit/towny/listeners/TownyVehicleListener.java +++ b/src/com/palmergames/bukkit/towny/listeners/TownyVehicleListener.java @@ -157,7 +157,7 @@ public void onVehicleEnter(VehicleEnterEvent event) { if (vehicle != null) { //Make decision on whether this is allowed using the PlayerCache and then a cancellable event. - if (TownySettings.isSwitchMaterial(vehicle.name())) + if (TownySettings.isSwitchMaterial(vehicle, event.getVehicle().getLocation())) event.setCancelled(!TownyActionEventExecutor.canSwitch(player, event.getVehicle().getLocation(), vehicle)); } } diff --git a/src/com/palmergames/bukkit/towny/object/TownBlock.java b/src/com/palmergames/bukkit/towny/object/TownBlock.java index 5a8befa8d5..3370d02fc0 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlock.java @@ -34,7 +34,6 @@ public class TownBlock extends TownyObject { private TownyWorld world; private Town town = null; private Resident resident = null; - private TownBlockType type = TownBlockType.RESIDENTIAL; private int x, z; private double plotPrice = -1; private boolean locked = false; @@ -44,6 +43,7 @@ public class TownBlock extends TownyObject { private Jail jail; private Map permissionOverrides = new HashMap<>(); private Set trustedResidents = new HashSet<>(); + private String type = "default"; //Plot level permissions protected TownyPermission permissions = new TownyPermission(); @@ -260,90 +260,93 @@ public void setOutpost(boolean outpost) { } public TownBlockType getType() { - + return getTypeInternal(); + } + + public String getTypeName() { return type; } - public void setType(TownBlockType type) { - if (type != this.type) - this.permissions.reset(); - - if (type != null){ - Bukkit.getPluginManager().callEvent(new PlotChangeTypeEvent(this.type, type, this)); - } - this.type = type; - - // Custom plot settings here - switch (type) { + public void setType(@NotNull String type) { + if (!TownBlockTypeHandler.exists(type)) + type = "default"; - case RESIDENTIAL: - - case COMMERCIAL: - - case EMBASSY: - - case BANK: - - case INN: + if (!type.equalsIgnoreCase(this.type)) + this.permissions.reset(); - if (this.hasResident()) { - setPermissions(this.resident.getPermissions().toString()); - } else { - setPermissions(this.town.getPermissions().toString()); - } - - break; - - case ARENA: - - setPermissions("pvp"); - break; - - case SPLEEF: - - case JAIL: - - setPermissions("denyAll"); - break; - - case FARM: - - case WILDS: - - setPermissions("residentBuild,residentDestroy"); - break; - default: + this.type = type.toLowerCase(); + TownBlockType townBlockType = TownBlockType.lookup(type); + + if (townBlockType != null) { + Bukkit.getPluginManager().callEvent(new PlotChangeTypeEvent(getTypeInternal(), townBlockType, this)); + + switch (townBlockType) { + case RESIDENTIAL: + case COMMERCIAL: + case EMBASSY: + case BANK: + case INN: + if (this.hasResident()) { + setPermissions(this.resident.getPermissions().toString()); + } else { + setPermissions(this.town.getPermissions().toString()); + } + + break; + case ARENA: + setPermissions("pvp"); + break; + case JAIL: + setPermissions("denyAll"); + break; + case FARM: + case WILDS: + setPermissions("residentBuild,residentDestroy"); + break; + } } - // Set the changed status. this.setChanged(false); - } + /** + * Sets the type of this townblock to the specified ID. + * @param typeId The id of the type + * @deprecated For compatibility with custom types, this is deprecated. + * @see #setType(String) + */ + @Deprecated public void setType(int typeId) { - - setType(TownBlockType.lookup(typeId)); + setType(TownBlockType.lookup(typeId).getName()); } + public void setType(TownBlockType type) { + setType(type.getName()); + } + + @Deprecated public void setType(TownBlockType type, Resident resident) throws TownyException { - + setType(type.getName(), resident); + } + + public void setType(String type, Resident resident) throws TownyException { + // Delete a jail if this is no longer going to be a jail. - if (this.isJail() && !type.equals(TownBlockType.JAIL)) { + if (this.isJail() && !TownBlockType.JAIL.equals(type)) { TownyUniverse.getInstance().getDataSource().removeJail(getJail()); setJail(null); } - if ((getType().equals(TownBlockType.ARENA) || type.equals(TownBlockType.ARENA)) - && TownySettings.getPVPCoolDownTime() > 0 + if (TownBlockType.ARENA.equals(this.type) || TownBlockType.ARENA.equals(type) + && TownySettings.getPVPCoolDownTime() > 0 && !TownyUniverse.getInstance().getPermissionSource().testPermission(resident.getPlayer(), PermissionNodes.TOWNY_ADMIN.getNode())) { // Test to see if the pvp cooldown timer is active for this plot. if (CooldownTimerTask.hasCooldown(getWorldCoord().toString(), CooldownType.PVP)) throw new TownyException(Translation.of("msg_err_cannot_toggle_pvp_x_seconds_remaining", CooldownTimerTask.getCooldownRemaining(getWorldCoord().toString(), CooldownType.PVP))); - + setType(type); CooldownTimerTask.addCooldownTimer(getWorldCoord().toString(), CooldownType.PVP); - } else setType(type); @@ -553,4 +556,14 @@ public TownBlockOwner getTownBlockOwner() { else return getTownOrNull(); } + + public TownBlockData getData() { + return TownBlockTypeHandler.getData(this.type); + } + + private TownBlockType getTypeInternal() { + TownBlockType type = TownBlockType.lookup(this.type); + + return type == null ? TownBlockType.CUSTOM : type; + } } \ No newline at end of file diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockData.java b/src/com/palmergames/bukkit/towny/object/TownBlockData.java new file mode 100644 index 0000000000..ed6fa559f7 --- /dev/null +++ b/src/com/palmergames/bukkit/towny/object/TownBlockData.java @@ -0,0 +1,91 @@ +package com.palmergames.bukkit.towny.object; + + import com.palmergames.bukkit.towny.TownySettings; + import org.bukkit.Material; + +import java.util.HashSet; +import java.util.Set; + +public class TownBlockData { + private String type = "default"; + private String mapKey = ""; + private double cost = 0.0; + private double tax = 0.0; + private Set itemUseIds = new HashSet<>(); // List of item names that will trigger an item use test. + private Set switchIds = new HashSet<>(); // List of item names that will trigger a switch test. + private Set allowedBlocks = new HashSet<>(); // List of item names that will always be allowed. + + public TownBlockData(String typeName) { + this.type = typeName.toLowerCase(); + + TownBlockType type = TownBlockType.lookup(this.type); + if (type != null) { + mapKey = type.getAsciiMapKey(); + } + } + + public String getMapKey() { + return mapKey; + } + + public void setMapKey(String mapKey) { + this.mapKey = mapKey; + } + + public double getCost() { + return cost; + } + + /** + * Sets how much it costs for a player to set to plot to this type. + * @param cost The cost + */ + public void setCost(double cost) { + this.cost = cost; + } + + public Set getItemUseIds() { + if (itemUseIds.isEmpty()) + return TownySettings.getItemUseMaterials(); + else + return itemUseIds; + } + + public Set getSwitchIds() { + if (switchIds.isEmpty()) + return TownySettings.getSwitchMaterials(); + else + return switchIds; + } + + public Set getAllowedBlocks() { + return allowedBlocks; + } + + public void setItemUseIds(Set itemUseIds) { + this.itemUseIds = new HashSet<>(itemUseIds); + } + + public void setSwitchIds(Set switchIds) { + this.switchIds = new HashSet<>(switchIds); + } + + public void setAllowedBlocks(Set allowedBlocks) { + this.allowedBlocks = new HashSet<>(allowedBlocks); + } + + public void setTax(double tax) { + this.tax = tax; + } + + public double getTax(Town town) { + if (tax == 0) + return town.getPlotTax(); + else + return tax; + } + + public String getType() { + return type; + } +} diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index 25952d375c..21e6381d8f 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -5,15 +5,15 @@ import java.util.Map; import com.palmergames.bukkit.towny.TownySettings; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author dumptruckman */ public enum TownBlockType { - RESIDENTIAL(0, "Default", "+", 0.0) { // The default Block Type. - }, - - COMMERCIAL(1, "Shop", "C", TownySettings.getPlotSetCommercialCost()) { // Just like residential but has additional tax + RESIDENTIAL(0, "Default", "+"), // The default Block Type. + COMMERCIAL(1, "Shop", "C") { // Just like residential but has additional tax @Override public double getTax(Town town) { @@ -21,11 +21,8 @@ public double getTax(Town town) { return town.getCommercialPlotTax() + town.getPlotTax(); } }, - - ARENA(2, "Arena", "A", TownySettings.getPlotSetArenaCost()) { //Always PVP enabled. - }, - - EMBASSY(3, "Embassy", "E", TownySettings.getPlotSetEmbassyCost()) { // For other towns to own a plot in your town. + ARENA(2, "Arena", "A"), //Always PVP enabled. + EMBASSY(3, "Embassy", "E") { // For other towns to own a plot in your town. @Override public double getTax(Town town) { @@ -33,44 +30,23 @@ public double getTax(Town town) { return town.getEmbassyPlotTax() + town.getPlotTax(); } }, - WILDS(4, "Wilds", "W", TownySettings.getPlotSetWildsCost()) { //Follows wilderness protection settings, but town owned. - }, - SPLEEF(5, "Spleef", "+", 0.0) { //Follows wilderness protection settings, but town owned. - }, - INN(6, "Inn", "I", TownySettings.getPlotSetInnCost()) { //Allows use of beds outside your own plot. - }, - JAIL(7, "Jail", "J", TownySettings.getPlotSetInnCost()) { //Enables setting the jail spawn. - }, - FARM(8, "Farm", "F", TownySettings.getPlotSetInnCost()) { //Follows wilderness protection settings, but town owned. - }, - BANK(9, "Bank", "B", TownySettings.getPlotSetBankCost()) { // Enables depositing into town and nation banks, if that has been enabled in the config. - } + WILDS(4, "Wilds", "W"), //Follows wilderness protection settings, but town owned. + INN(6, "Inn", "I"), //Allows use of beds outside your own plot. + JAIL(7, "Jail", "J"), //Enables setting the jail spawn. + FARM(8, "Farm", "F"), //Follows wilderness protection settings, but town owned. + BANK(9, "Bank", "B"), // Enables depositing into town and nation banks, if that has been enabled in the config. + CUSTOM(10, "Custom", "C"); - // These are subject to change, and may not necessarily be added: -/* - * PUBLIC(10, "") { // Will have it's own permission set - * }, - * - * MINE(11, "") { // Will have it's own permission set within a y range - * }, - * - * HOTEL(12, "") { // Will stack multiple y-ranges and function like a micro town - * }, - */ - ; - - private int id; - private String name, asciiMapKey; - private double cost; - private static final Map idLookup = new HashMap(); - private static final Map nameLookup = new HashMap(); + private final int id; + private final String name, asciiMapKey; + private static final Map idLookup = new HashMap<>(); + private static final Map nameLookup = new HashMap<>(); - TownBlockType(int id, String name, String asciiMapKey, double cost) { + TownBlockType(int id, String name, String asciiMapKey) { this.id = id; this.name = name; this.asciiMapKey = asciiMapKey; - this.cost = cost; } static { @@ -86,37 +62,51 @@ public String toString() { return name; } + @Deprecated public double getTax(Town town) { return town.getPlotTax(); } + @Deprecated public int getId() { return id; } public String getAsciiMapKey() { - - return asciiMapKey; + TownBlockData data = TownBlockTypeHandler.getData(this.name); + + return data == null ? asciiMapKey : data.getMapKey(); } public double getCost() { - - return cost; + TownBlockData data = TownBlockTypeHandler.getData(this.name); + + return data == null ? 0.0 : data.getCost(); } public String getName() { return name; } + @Nullable + @Deprecated public static TownBlockType lookup(int id) { - return idLookup.get(id); } - public static TownBlockType lookup(String name) { + @Nullable + public static TownBlockType lookup(@NotNull String name) { + TownBlockType type = nameLookup.get(name.toLowerCase()); + + if (type == null && TownBlockTypeHandler.exists(name)) // Type exists but it's not one of ours. + type = TownBlockType.CUSTOM; - return nameLookup.get(name.toLowerCase()); + return type; + } + + public boolean equals(String type) { + return type != null && this == lookup(type); } } \ No newline at end of file diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index 9e04d64404..27bae07a93 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -1,17 +1,121 @@ package com.palmergames.bukkit.towny.object; +import com.palmergames.bukkit.towny.Towny; +import com.palmergames.bukkit.towny.TownySettings; +import com.palmergames.bukkit.towny.event.TownBlockTypeRegisterEvent; +import com.palmergames.bukkit.towny.exceptions.TownyException; +import org.bukkit.Bukkit; +import org.bukkit.Material; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; public final class TownBlockTypeHandler { + private static Map townBlockDataMap = new ConcurrentHashMap<>(); + + public static void initialize() { + Map newData = new ConcurrentHashMap<>(); + for (TownBlockType type : TownBlockType.values()) { + String typeName = type.getName().toLowerCase(Locale.ROOT); + newData.put(typeName, new TownBlockData(typeName)); + } + + applyConfigSettings(newData); + + Bukkit.getPluginManager().callEvent(new TownBlockTypeRegisterEvent()); + + townBlockDataMap = newData; + } + + /** + * Registers a new type. Should not be used at all outside of the TownBlockTypeRegisterEvent. + * @param name - The name for this type. + * @param data - The data for this type. + * @throws TownyException - If a type with this name is already registered. + */ + public static void registerType(@NotNull String name, @Nullable TownBlockData data) throws TownyException { + if (exists(name)) + throw new TownyException(String.format("A type named '%s' is already registered!", name)); + + if (data == null) + data = new TownBlockData(name); + + townBlockDataMap.put(name.toLowerCase(), data); + } + + /** + * Gets the data for a townblock type. + * @param townBlockType The name of the town block type. + */ + @Nullable + public static TownBlockData getData(@NotNull String townBlockType) { + return townBlockDataMap.get(townBlockType.toLowerCase(Locale.ROOT)); + } + + /** + * @param typeName The name of the type to test for. + * @return Whether a type with the specified name exists. + */ + public static boolean exists(@NotNull String typeName) { + return getData(typeName) != null; + } + + private static void applyConfigSettings(Map newData) { - public static TownBlockType getTypeInternal(@NotNull String input) { - try { - int id = Integer.parseInt(input); - return TownBlockType.lookup(id); - } catch (NumberFormatException e) { - // We're dealing with someone who was on a version using the modern TownBlockTypes. - TownBlockType type = TownBlockType.lookup(input); - return type != null ? type : TownBlockType.RESIDENTIAL; + List> types = TownySettings.getConfig().getMapList("townblocktypes.types"); + for (Map type : types) { + String name = "unknown type"; + + try { + name = String.valueOf(type.get("name")); + double cost = Double.parseDouble(type.get("cost").toString()); + double tax = Double.parseDouble(type.get("tax").toString()); + String mapKey = String.valueOf(type.get("mapKey")); + + Set itemUseIds = loadMaterialList(String.valueOf(type.get("itemUseIds")), name); + Set switchIds = loadMaterialList(String.valueOf(type.get("switchIds")), name); + Set allowedBlocks = loadMaterialList(String.valueOf(type.get("allowedBlocks")), name); + + TownBlockData data = new TownBlockData(name); + data.setCost(cost); + data.setTax(tax); + data.setMapKey(mapKey); + data.setItemUseIds(itemUseIds); + data.setSwitchIds(switchIds); + data.setAllowedBlocks(allowedBlocks); + + newData.put(name.toLowerCase(), data); + Towny.getPlugin().getLogger().info(String.format("Loaded a townblock type: %s", name)); + + } catch (Exception e) { + Towny.getPlugin().getLogger().warning(String.format("Error while loading townblock type '%s', skipping...", name)); + e.printStackTrace(); + } } } + + private static Set loadMaterialList(String materialList, String typeName) { + if (!materialList.isEmpty()) { + Set set = new HashSet<>(); + for (String materialName : materialList.split(",")) { + Material material = Material.matchMaterial(materialName); + + if (material == null) + Towny.getPlugin().getLogger().warning(String.format("Could not find a material named '%s' while loading the item use list for the %s type.", materialName, typeName)); + else + set.add(material); + } + + return set; + } else + return new HashSet<>(); + } + + private TownBlockTypeHandler() {} } diff --git a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java index 8a00e106bd..70de6c8f0e 100644 --- a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java +++ b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java @@ -375,40 +375,44 @@ protected void collectTownTaxes(Town town) { Resident resident = townBlock.getResidentOrNull(); - /* - * Only collect plot tax from this resident if it really - * still exists. We are running in an Async thread so MUST - * verify all objects. - */ - if (universe.hasResident(resident.getName())) { - if (resident.hasTown() && resident.getTownOrNull() == town) - if (TownyPerms.getResidentPerms(resident).containsKey("towny.tax_exempt") || resident.isNPC()) + /* + * Only collect plot tax from this resident if it really + * still exists. We are running in an Async thread so MUST + * verify all objects. + */ + if (universe.hasResident(resident.getName())) { + if (resident.hasTown() && resident.getTownOrNull() == town) + if (TownyPerms.getResidentPerms(resident).containsKey("towny.tax_exempt") || resident.isNPC()) + continue; + + double tax = townBlock.getData().getTax(town); + if (tax < 1) continue; - // If the tax would put the town over the bank cap we reduce what will be - // paid by the plot owner to what will be allowed. - if (TownySettings.getTownBankCap() != 0 && tax + town.getAccount().getHoldingBalance() > TownySettings.getTownBankCap()) - tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); - - if (!resident.getAccount().payTo(tax, town, String.format("Plot Tax (%s)", townBlock.getType()))) { - if (!lostPlots.contains(resident.getName())) - lostPlots.add(resident.getName()); - - townBlock.setResident(null); - - // Set the plot price. - if (TownySettings.doesPlotTaxNonPaymentSetPlotForSale()) - townBlock.setPlotPrice(town.getPlotTypePrice(townBlock.getType())); - else - townBlock.setPlotPrice(-1); - - // Set the plot permissions to mirror the towns. - townBlock.setType(townBlock.getType()); + // If the tax would put the town over the bank cap we reduce what will be + // paid by the plot owner to what will be allowed. + if (TownySettings.getTownBankCap() != 0 && tax + town.getAccount().getHoldingBalance() > TownySettings.getTownBankCap()) + tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); + + if (!resident.getAccount().payTo(tax, town, String.format("Plot Tax (%s)", townBlock.getTypeName()))) { + if (!lostPlots.contains(resident.getName())) + lostPlots.add(resident.getName()); - townBlock.save(); + townBlock.setResident(null); + + // Set the plot price. + if (TownySettings.doesPlotTaxNonPaymentSetPlotForSale()) + townBlock.setPlotPrice(townBlock.getData().getCost()); + else + townBlock.setPlotPrice(-1); + + // Set the plot permissions to mirror the towns. + townBlock.setType(townBlock.getTypeName()); + + townBlock.save(); + } } } - } if (lostPlots != null && !lostPlots.isEmpty()) { if (lostPlots.size() == 1) diff --git a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java index ce86087a76..4fe42ea256 100644 --- a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java @@ -490,13 +490,16 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.PLOT_TRUSTED || status == TownBlockStatus.TOWN_TRUSTED) return true; + if (isAllowedMaterial(townBlock, material, action)) + return true; + /* * Handle personally-owned plots' friend and town permissions. */ if (status == TownBlockStatus.PLOT_FRIEND) { // Plot allows Friends perms and we aren't stopped by Wilds or Farm Plot overrides. - if (townBlock.getPermissions().getResidentPerm(action) && testSpecialPlots(pos.getTownyWorldOrNull(), townBlock.getType(), material, action)) + if (townBlock.getPermissions().getResidentPerm(action)) return true; cacheBlockErrMsg(player, Translatable.of("msg_cache_block_error_plot", Translatable.of("msg_cache_block_error_plot_friends"), Translatable.of(action.toString())).forLocale(player)); @@ -506,7 +509,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.PLOT_TOWN) { // Plot allows Town perms and we aren't stopped by Wilds or Farm Plot overrides. - if (townBlock.getPermissions().getNationPerm(action) && testSpecialPlots(pos.getTownyWorldOrNull(), townBlock.getType(), material, action)) + if (townBlock.getPermissions().getNationPerm(action)) return true; cacheBlockErrMsg(player, Translatable.of("msg_cache_block_error_plot", Translatable.of("msg_cache_block_error_plot_town_members"), Translatable.of(action.toString())).forLocale(player)); @@ -518,8 +521,8 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl */ if (status == TownBlockStatus.TOWN_RESIDENT) { - // Plot allows Resident perms and we aren't stopped by Wilds or Farm Plot overrides. - if (townBlock.getPermissions().getResidentPerm(action) && testSpecialPlots(pos.getTownyWorldOrNull(), townBlock.getType(), material, action)) + // Plot allows Resident perms + if (townBlock.getPermissions().getResidentPerm(action)) return true; cacheBlockErrMsg(player, Translatable.of("msg_cache_block_error_town_resident", Translatable.of(action.toString())).forLocale(player)); @@ -528,8 +531,8 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.TOWN_NATION) { - // Plot allows Nation perms and we aren't stopped by Wilds or Farm Plot overrides. - if (townBlock.getPermissions().getNationPerm(action) && testSpecialPlots(pos.getTownyWorldOrNull(), townBlock.getType(), material, action)) + // Plot allows Nation perms + if (townBlock.getPermissions().getNationPerm(action)) return true; cacheBlockErrMsg(player, Translatable.of("msg_cache_block_error_town_nation", Translatable.of(action.toString())).forLocale(player)); @@ -541,8 +544,8 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl */ if (status == TownBlockStatus.PLOT_ALLY || status == TownBlockStatus.TOWN_ALLY) { - // Plot allows Ally perms and we aren't stopped by Wilds or Farm Plot overrides. - if (townBlock.getPermissions().getAllyPerm(action) && testSpecialPlots(pos.getTownyWorldOrNull(), townBlock.getType(), material, action)) + // Plot allows Ally perms + if (townBlock.getPermissions().getAllyPerm(action)) return true; // Choose which error message will be shown. @@ -558,8 +561,8 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl */ if (status == TownBlockStatus.OUTSIDER || status == TownBlockStatus.ENEMY) { - // Plot allows Outsider perms and we aren't stopped by Wilds or Farm Plot overrides. - if (townBlock.getPermissions().getOutsiderPerm(action) && testSpecialPlots(pos.getTownyWorldOrNull(), townBlock.getType(), material, action)) + // Plot allows Outsider perms + if (townBlock.getPermissions().getOutsiderPerm(action)) return true; // Choose which error message will be shown. @@ -574,24 +577,17 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl return false; } - /** - * Wilds and Farm plots have special overrides over the normal plot permissions, - * limiting interaction to only specific blocks. - * - * @param world TownyWorld where the action is occuring. - * @param type TownBlockType of the TownBlock. + /** + * @param townBlock The townblock. * @param material Material being actioned upon. * @param action ActionType being done on the material. - * @return False if the player is in a Wilds or Farm plot and trying to interact outside the allowed materials & actions. + * @return True if this material is allowed in this townblock. */ - private static boolean testSpecialPlots(TownyWorld world, TownBlockType type, Material material, ActionType action) { - if (type == TownBlockType.WILDS) - return TownyUniverse.getInstance().getPermissionSource().unclaimedZoneAction(world, material, action); - - if (type == TownBlockType.FARM && (action.equals(ActionType.BUILD) || action.equals(ActionType.DESTROY))) - return TownySettings.getFarmPlotBlocks().contains(material.toString()); + private static boolean isAllowedMaterial(TownBlock townBlock, Material material, ActionType action) { + if (action.equals(ActionType.BUILD) || action.equals(ActionType.DESTROY)) { + return townBlock.getData().getAllowedBlocks().contains(material); + } - // This isn't a Wilds or Farm plot with special overrides, the Plot has permissions on, return true. - return true; + return false; } } \ No newline at end of file diff --git a/src/com/palmergames/bukkit/util/ItemLists.java b/src/com/palmergames/bukkit/util/ItemLists.java index ec60d86e6f..fb7964f2ff 100644 --- a/src/com/palmergames/bukkit/util/ItemLists.java +++ b/src/com/palmergames/bukkit/util/ItemLists.java @@ -83,7 +83,7 @@ public class ItemLists { /** * Config-useable material groups. */ - public static List GROUPS = new ArrayList<>(Arrays.asList("BOATS","MINECARTS","WOOD_DOORS","PRESSURE_PLATES","FENCE_GATES","TRAPDOORS","SHULKER_BOXES","BUTTONS")); + public static List GROUPS = new ArrayList<>(Arrays.asList("BOATS","MINECARTS","WOOD_DOORS","PRESSURE_PLATES","FENCE_GATES","TRAPDOORS","SHULKER_BOXES","BUTTONS","CANDLES")); /** * List of Buckets. From f8f411f6acdf673086f1755a90d2462ed8abe210 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Wed, 20 Oct 2021 23:42:56 +0200 Subject: [PATCH 02/28] Other fixes & javadocs --- .../bukkit/towny/TownySettings.java | 2 ++ .../bukkit/towny/command/PlotCommand.java | 2 +- .../towny/command/TownyAdminCommand.java | 2 ++ .../palmergames/bukkit/towny/object/Town.java | 25 ++++++------------- .../bukkit/towny/object/TownBlock.java | 18 ++++++++++--- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index 4a25dcc37e..d506b38635 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -1442,6 +1442,7 @@ public static Set getItemUseMaterials() { * For compatibility with custom plot types, this has been deprecated. Please use {@link #isSwitchMaterial(Material, Location)} instead. * @param mat The name of the material. * @return Whether this is a switch material or not. + * @deprecated as of 0.97.3.0. */ @Deprecated public static boolean isSwitchMaterial(String mat) { @@ -1461,6 +1462,7 @@ public static boolean isSwitchMaterial(Material material, Location location) { * For compatibility with custom plot types, this has been deprecated. Please use {@link #isItemUseMaterial(Material, Location)} instead. * @param mat The name of the material. * @return Whether this is an item use material or not. + * @deprecated as of 0.97.3.0. */ @Deprecated public static boolean isItemUseMaterial(String mat) { diff --git a/src/com/palmergames/bukkit/towny/command/PlotCommand.java b/src/com/palmergames/bukkit/towny/command/PlotCommand.java index 5c9be2cbfd..c56eb2453a 100644 --- a/src/com/palmergames/bukkit/towny/command/PlotCommand.java +++ b/src/com/palmergames/bukkit/towny/command/PlotCommand.java @@ -473,7 +473,7 @@ public boolean parsePlotCommand(Player player, String[] split) { Town town = townBlock.getTownOrNull(); if (town == null) throw new TownyException(Translatable.of("msg_err_empty_area_selection")); - double plotPrice = town.getPlotTypePrice(pos.getTownBlock().getType()); + double plotPrice = town.getPlotTypePrice(townBlock.getType()); if (split.length > 1) { /* diff --git a/src/com/palmergames/bukkit/towny/command/TownyAdminCommand.java b/src/com/palmergames/bukkit/towny/command/TownyAdminCommand.java index 79e6b2aa3b..ea8541fcb2 100644 --- a/src/com/palmergames/bukkit/towny/command/TownyAdminCommand.java +++ b/src/com/palmergames/bukkit/towny/command/TownyAdminCommand.java @@ -32,6 +32,7 @@ import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.TownBlock; import com.palmergames.bukkit.towny.object.TownBlockType; +import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import com.palmergames.bukkit.towny.object.TownyWorld; import com.palmergames.bukkit.towny.object.Translatable; import com.palmergames.bukkit.towny.object.Translation; @@ -2055,6 +2056,7 @@ public void reloadConfig(boolean reset) { TownySettings.loadTownLevelConfig(); // TownLevel and NationLevels are not loaded in the config, TownySettings.loadNationLevelConfig(); // but later so the config-migrator can do it's work on them if needed. Translation.loadTranslationRegistry(); + TownBlockTypeHandler.initialize(); } catch (IOException e) { TownyMessaging.sendErrorMsg(sender, Translatable.of("msg_reload_error")); e.printStackTrace(); diff --git a/src/com/palmergames/bukkit/towny/object/Town.java b/src/com/palmergames/bukkit/towny/object/Town.java index b10774b011..5a0a61338f 100644 --- a/src/com/palmergames/bukkit/towny/object/Town.java +++ b/src/com/palmergames/bukkit/towny/object/Town.java @@ -964,24 +964,13 @@ public double getPlotPrice() { } public double getPlotTypePrice(TownBlockType type) { - - double plotPrice; - switch (type.ordinal()) { - case 1: - plotPrice = getCommercialPlotPrice(); - break; - case 3: - plotPrice = getEmbassyPlotPrice(); - break; - default: - plotPrice = getPlotPrice(); - - } - // check price isn't negative - if (plotPrice < 0) - plotPrice = 0; - - return plotPrice; + double plotPrice = switch (type) { + case COMMERCIAL -> getCommercialPlotPrice(); + case EMBASSY -> getEmbassyPlotPrice(); + default -> getPlotPrice(); + }; + + return Math.max(plotPrice, 0); } public void setCommercialPlotPrice(double commercialPlotPrice) { diff --git a/src/com/palmergames/bukkit/towny/object/TownBlock.java b/src/com/palmergames/bukkit/towny/object/TownBlock.java index 3370d02fc0..e39c86fb8c 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlock.java @@ -313,7 +313,7 @@ public void setType(@NotNull String type) { /** * Sets the type of this townblock to the specified ID. * @param typeId The id of the type - * @deprecated For compatibility with custom types, this is deprecated. + * @deprecated As of 0.97.3.0, this is deprecated for compatibility with custom types. * @see #setType(String) */ @Deprecated @@ -324,12 +324,24 @@ public void setType(int typeId) { public void setType(TownBlockType type) { setType(type.getName()); } - + + /** + * + * @param type The {@link TownBlockType} type set this plot to. + * @param resident The resident who is trying to set the type. + * @throws TownyException If this townblock has a pvp toggle cooldown. + * @deprecated As of 0.97.3.0, this is deprecated for compatibility with custom types. + */ @Deprecated public void setType(TownBlockType type, Resident resident) throws TownyException { setType(type.getName(), resident); } - + + /** + * @param type The name of the type set this plot to. + * @param resident The resident who is trying to set the type. + * @throws TownyException If this townblock has a pvp toggle cooldown. + */ public void setType(String type, Resident resident) throws TownyException { // Delete a jail if this is no longer going to be a jail. From 2bd69a4882b23597a82cdcf57d3a10a6df7641a6 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Wed, 20 Oct 2021 23:45:28 +0200 Subject: [PATCH 03/28] Fix up PlayerCacheUtil --- .../bukkit/towny/utils/PlayerCacheUtil.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java index 4fe42ea256..05558d2c0a 100644 --- a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java @@ -490,9 +490,6 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.PLOT_TRUSTED || status == TownBlockStatus.TOWN_TRUSTED) return true; - if (isAllowedMaterial(townBlock, material, action)) - return true; - /* * Handle personally-owned plots' friend and town permissions. */ @@ -508,8 +505,8 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.PLOT_TOWN) { - // Plot allows Town perms and we aren't stopped by Wilds or Farm Plot overrides. - if (townBlock.getPermissions().getNationPerm(action)) + // Plot allows Town perms + if (townBlock.getPermissions().getNationPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; cacheBlockErrMsg(player, Translatable.of("msg_cache_block_error_plot", Translatable.of("msg_cache_block_error_plot_town_members"), Translatable.of(action.toString())).forLocale(player)); @@ -522,7 +519,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.TOWN_RESIDENT) { // Plot allows Resident perms - if (townBlock.getPermissions().getResidentPerm(action)) + if (townBlock.getPermissions().getResidentPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; cacheBlockErrMsg(player, Translatable.of("msg_cache_block_error_town_resident", Translatable.of(action.toString())).forLocale(player)); @@ -532,7 +529,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.TOWN_NATION) { // Plot allows Nation perms - if (townBlock.getPermissions().getNationPerm(action)) + if (townBlock.getPermissions().getNationPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; cacheBlockErrMsg(player, Translatable.of("msg_cache_block_error_town_nation", Translatable.of(action.toString())).forLocale(player)); @@ -545,7 +542,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.PLOT_ALLY || status == TownBlockStatus.TOWN_ALLY) { // Plot allows Ally perms - if (townBlock.getPermissions().getAllyPerm(action)) + if (townBlock.getPermissions().getAllyPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; // Choose which error message will be shown. @@ -562,7 +559,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.OUTSIDER || status == TownBlockStatus.ENEMY) { // Plot allows Outsider perms - if (townBlock.getPermissions().getOutsiderPerm(action)) + if (townBlock.getPermissions().getOutsiderPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; // Choose which error message will be shown. @@ -584,10 +581,9 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl * @return True if this material is allowed in this townblock. */ private static boolean isAllowedMaterial(TownBlock townBlock, Material material, ActionType action) { - if (action.equals(ActionType.BUILD) || action.equals(ActionType.DESTROY)) { + if ((action == ActionType.BUILD || action == ActionType.DESTROY) && !townBlock.getData().getAllowedBlocks().isEmpty()) return townBlock.getData().getAllowedBlocks().contains(material); - } - return false; + return true; } } \ No newline at end of file From d499fc6928543596d643173e96650e16a9acc0a9 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 21 Oct 2021 02:13:59 +0200 Subject: [PATCH 04/28] Nuke the TownBlockType enum --- .../bukkit/towny/ChunkNotification.java | 4 +- .../bukkit/towny/command/PlotCommand.java | 43 ++++---- .../event/TownBlockTypeRegisterEvent.java | 7 +- .../bukkit/towny/huds/PermHUD.java | 2 +- .../palmergames/bukkit/towny/object/Town.java | 6 +- .../bukkit/towny/object/TownBlock.java | 99 ++++++++----------- .../bukkit/towny/object/TownBlockData.java | 16 +-- .../bukkit/towny/object/TownBlockType.java | 85 ++++++---------- .../towny/object/TownBlockTypeHandler.java | 54 ++++++---- .../bukkit/towny/tasks/DailyTimerTask.java | 2 +- 10 files changed, 139 insertions(+), 179 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/ChunkNotification.java b/src/com/palmergames/bukkit/towny/ChunkNotification.java index 2164f4e375..cae4482aab 100644 --- a/src/com/palmergames/bukkit/towny/ChunkNotification.java +++ b/src/com/palmergames/bukkit/towny/ChunkNotification.java @@ -82,7 +82,7 @@ public ChunkNotification(WorldCoord from, WorldCoord to) { if (from.hasTownBlock()) { fromTownBlock = from.getTownBlockOrNull(); - fromPlotType = StringMgmt.capitalize(fromTownBlock.getData().getType()); + fromPlotType = StringMgmt.capitalize(fromTownBlock.getTypeName()); fromForSale = fromTownBlock.getPlotPrice() != -1; if (fromTownBlock.hasPlotObjectGroup()) { fromPlotGroup = fromTownBlock.getPlotObjectGroup(); @@ -98,7 +98,7 @@ public ChunkNotification(WorldCoord from, WorldCoord to) { if (to.hasTownBlock()) { toTownBlock = to.getTownBlockOrNull(); - toPlotType = StringMgmt.capitalize(toTownBlock.getData().getType()); + toPlotType = StringMgmt.capitalize(toTownBlock.getTypeName()); toTown = toTownBlock.getTownOrNull(); toResident = toTownBlock.getResidentOrNull(); toForSale = toTownBlock.getPlotPrice() != -1; diff --git a/src/com/palmergames/bukkit/towny/command/PlotCommand.java b/src/com/palmergames/bukkit/towny/command/PlotCommand.java index c56eb2453a..f201640417 100644 --- a/src/com/palmergames/bukkit/towny/command/PlotCommand.java +++ b/src/com/palmergames/bukkit/towny/command/PlotCommand.java @@ -686,7 +686,9 @@ public boolean parsePlotCommand(Player player, String[] split) { if (plotTypeName.equalsIgnoreCase("reset")) plotTypeName = "default"; - if (!TownBlockTypeHandler.exists(plotTypeName)) + TownBlockType type = TownBlockTypeHandler.getType(plotTypeName); + + if (type == null) throw new TownyException(Translatable.of("msg_err_not_block_type")); try { @@ -714,40 +716,38 @@ public boolean parsePlotCommand(Player player, String[] split) { return false; } - TownBlockData data = TownBlockTypeHandler.getData(plotTypeName); - double cost = data.getCost(); - final String finalName = plotTypeName; + double cost = type.getData().getCost(); // Test if we can pay first to throw an exception. if (cost > 0 && TownyEconomyHandler.isActive() && !resident.getAccount().canPayFromHoldings(cost)) - throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", plotTypeName, TownyEconomyHandler.getFormattedBalance(cost))); + throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", type, TownyEconomyHandler.getFormattedBalance(cost))); // Handle payment via a confirmation to avoid suprise costs. if (cost > 0 && TownyEconomyHandler.isActive()) { Confirmation.runOnAccept(() -> { - if (!resident.getAccount().withdraw(cost, String.format("Plot set to %s", finalName))) { - TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", finalName, TownyEconomyHandler.getFormattedBalance(cost))); + if (!resident.getAccount().withdraw(cost, String.format("Plot set to %s", type))) { + TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", type, TownyEconomyHandler.getFormattedBalance(cost))); return; } - TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), finalName)); + TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), type)); try { - townBlock.setType(finalName, resident); + townBlock.setType(type, resident); } catch (TownyException e) { TownyMessaging.sendErrorMsg(resident, e.getMessage(player)); return; } - TownyMessaging.sendMsg(player, Translatable.of("msg_plot_set_type", finalName)); + TownyMessaging.sendMsg(player, Translatable.of("msg_plot_set_type", type)); }) .setTitle(Translatable.of("msg_confirm_purchase", TownyEconomyHandler.getFormattedBalance(cost))) .sendTo(BukkitTools.getPlayerExact(resident.getName())); // No cost or economy so no confirmation. } else { - townBlock.setType(plotTypeName, resident); + townBlock.setType(type, resident); TownyMessaging.sendMsg(player, Translatable.of("msg_plot_set_type", plotTypeName)); } } catch (TownyException te){ @@ -1726,8 +1726,10 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow // Handle type being reset if (plotTypeName.equalsIgnoreCase("reset")) plotTypeName = "default"; + + TownBlockType type = TownBlockTypeHandler.getType(plotTypeName); - if (!TownBlockTypeHandler.exists(plotTypeName)) + if (type == null) throw new TownyException(Translatable.of("msg_err_not_block_type")); for (TownBlock tb : townBlock.getPlotObjectGroup().getTownBlocks()) { @@ -1760,34 +1762,33 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow } } - TownBlockData data = TownBlockTypeHandler.getData(plotTypeName); int amount = townBlock.getPlotObjectGroup().getTownBlocks().size(); - double cost = data.getCost() * amount; + double cost = type.getData().getCost() * amount; try { // Test if we can pay first to throw an exception. if (cost > 0 && TownyEconomyHandler.isActive() && !resident.getAccount().canPayFromHoldings(cost)) - throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", data.getType(), TownyEconomyHandler.getFormattedBalance(cost))); + throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", type, TownyEconomyHandler.getFormattedBalance(cost))); // Handle payment via a confirmation to avoid suprise costs. if (cost > 0 && TownyEconomyHandler.isActive()) { Confirmation.runOnAccept(() -> { - if (!resident.getAccount().withdraw(cost, String.format("Plot (" + amount + ") set to %s", data.getType()))) { - TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", data.getType(), TownyEconomyHandler.getFormattedBalance(cost))); + if (!resident.getAccount().withdraw(cost, String.format("Plot (" + amount + ") set to %s", type))) { + TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", type, TownyEconomyHandler.getFormattedBalance(cost))); return; } - TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), data.getType())); + TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), type)); for (TownBlock tb : townBlock.getPlotObjectGroup().getTownBlocks()) { try { - tb.setType(data.getType(), resident); + tb.setType(type, resident); } catch (TownyException ignored) { // Cannot be set to jail type as a group. } } - TownyMessaging.sendMsg(player, Translatable.of("msg_set_group_type_to_x", data.getType())); + TownyMessaging.sendMsg(player, Translatable.of("msg_set_group_type_to_x", type)); }) .setTitle(Translatable.of("msg_confirm_purchase", TownyEconomyHandler.getFormattedBalance(cost))) @@ -1797,7 +1798,7 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow } else { for (TownBlock tb : townBlock.getPlotObjectGroup().getTownBlocks()) - tb.setType(data.getType(), resident); + tb.setType(type, resident); TownyMessaging.sendMsg(player, Translatable.of("msg_set_group_type_to_x", plotTypeName)); } diff --git a/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java b/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java index 56453a8f33..e8001aa6c9 100644 --- a/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java +++ b/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java @@ -2,6 +2,7 @@ import com.palmergames.bukkit.towny.exceptions.TownyException; import com.palmergames.bukkit.towny.object.TownBlockData; +import com.palmergames.bukkit.towny.object.TownBlockType; import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import org.bukkit.Bukkit; import org.bukkit.event.Event; @@ -19,11 +20,11 @@ public TownBlockTypeRegisterEvent() { /** * Registers a new type. * @param name - The name for this type. - * @param data - The data for this type. + * @param type - The type * @throws TownyException - If a type with this name is already registered. */ - public static void registerType(@NotNull String name, @Nullable TownBlockData data) throws TownyException { - TownBlockTypeHandler.registerType(name, data); + public static void registerType(@NotNull String name, @NotNull TownBlockType type) throws TownyException { + TownBlockTypeHandler.registerType(name, type); } @Override diff --git a/src/com/palmergames/bukkit/towny/huds/PermHUD.java b/src/com/palmergames/bukkit/towny/huds/PermHUD.java index 8dd0d05a0e..247c6af3e1 100644 --- a/src/com/palmergames/bukkit/towny/huds/PermHUD.java +++ b/src/com/palmergames/bukkit/towny/huds/PermHUD.java @@ -61,7 +61,7 @@ public static void updatePerms(Player p, WorldCoord worldCoord) { destroy = (tp.getResidentPerm(ActionType.DESTROY) ? v : "-") + (tp.getNationPerm(ActionType.DESTROY) ? u : "-") + (tp.getAllyPerm(ActionType.DESTROY) ? "a" : "-") + (tp.getOutsiderPerm(ActionType.DESTROY) ? "o" : "-"); switching = (tp.getResidentPerm(ActionType.SWITCH) ? v : "-") + (tp.getNationPerm(ActionType.SWITCH) ? u : "-") + (tp.getAllyPerm(ActionType.SWITCH) ? "a" : "-") + (tp.getOutsiderPerm(ActionType.SWITCH) ? "o" : "-"); item = (tp.getResidentPerm(ActionType.ITEM_USE) ? v : "-") + (tp.getNationPerm(ActionType.ITEM_USE) ? u : "-") + (tp.getAllyPerm(ActionType.ITEM_USE) ? "a" : "-") + (tp.getOutsiderPerm(ActionType.ITEM_USE) ? "o" : "-"); - type = (townBlock.getType().equals(TownBlockType.RESIDENTIAL) ? " " : townBlock.getType().name()); + type = (townBlock.getType().equals(TownBlockType.RESIDENTIAL) ? " " : townBlock.getType().getName()); pvp = (!CombatUtil.preventPvP(worldCoord.getTownyWorld(), townBlock)) ? ChatColor.DARK_RED + "ON" : ChatColor.GREEN + "OFF"; explosions = (world.isForceExpl() || townBlock.getPermissions().explosion) ? ChatColor.DARK_RED + "ON" : ChatColor.GREEN + "OFF"; firespread = (town.isFire() || world.isForceFire() || townBlock.getPermissions().fire) ? ChatColor.DARK_RED + "ON" : ChatColor.GREEN + "OFF"; diff --git a/src/com/palmergames/bukkit/towny/object/Town.java b/src/com/palmergames/bukkit/towny/object/Town.java index 5a0a61338f..f908f6eedc 100644 --- a/src/com/palmergames/bukkit/towny/object/Town.java +++ b/src/com/palmergames/bukkit/towny/object/Town.java @@ -964,9 +964,9 @@ public double getPlotPrice() { } public double getPlotTypePrice(TownBlockType type) { - double plotPrice = switch (type) { - case COMMERCIAL -> getCommercialPlotPrice(); - case EMBASSY -> getEmbassyPlotPrice(); + double plotPrice = switch (type.getName().toLowerCase()) { + case "shop" -> getCommercialPlotPrice(); + case "embassy" -> getEmbassyPlotPrice(); default -> getPlotPrice(); }; diff --git a/src/com/palmergames/bukkit/towny/object/TownBlock.java b/src/com/palmergames/bukkit/towny/object/TownBlock.java index e39c86fb8c..5b9094eadc 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlock.java @@ -43,7 +43,7 @@ public class TownBlock extends TownyObject { private Jail jail; private Map permissionOverrides = new HashMap<>(); private Set trustedResidents = new HashSet<>(); - private String type = "default"; + private TownBlockType type = TownBlockType.RESIDENTIAL; //Plot level permissions protected TownyPermission permissions = new TownyPermission(); @@ -260,50 +260,51 @@ public void setOutpost(boolean outpost) { } public TownBlockType getType() { - return getTypeInternal(); + return type; } public String getTypeName() { - return type; + return type.getName(); } public void setType(@NotNull String type) { - if (!TownBlockTypeHandler.exists(type)) - type = "default"; + setType(TownBlockTypeHandler.getType(type)); + } + + public void setType(@NotNull TownBlockType type) { + if (!TownBlockTypeHandler.exists(type.getName())) + type = TownBlockType.RESIDENTIAL; - if (!type.equalsIgnoreCase(this.type)) + if (!type.equals(this.type)) this.permissions.reset(); - this.type = type.toLowerCase(); - TownBlockType townBlockType = TownBlockType.lookup(type); + this.type = type; - if (townBlockType != null) { - Bukkit.getPluginManager().callEvent(new PlotChangeTypeEvent(getTypeInternal(), townBlockType, this)); - - switch (townBlockType) { - case RESIDENTIAL: - case COMMERCIAL: - case EMBASSY: - case BANK: - case INN: - if (this.hasResident()) { - setPermissions(this.resident.getPermissions().toString()); - } else { - setPermissions(this.town.getPermissions().toString()); - } - - break; - case ARENA: - setPermissions("pvp"); - break; - case JAIL: - setPermissions("denyAll"); - break; - case FARM: - case WILDS: - setPermissions("residentBuild,residentDestroy"); - break; - } + Bukkit.getPluginManager().callEvent(new PlotChangeTypeEvent(this.type, type, this)); + + switch (type.getName().toLowerCase()) { + case "default": + case "shop": + case "embassy": + case "bank": + case "inn": + if (this.hasResident()) { + setPermissions(this.resident.getPermissions().toString()); + } else { + setPermissions(this.town.getPermissions().toString()); + } + + break; + case "arena": + setPermissions("pvp"); + break; + case "jail": + setPermissions("denyAll"); + break; + case "farm": + case "wilds": + setPermissions("residentBuild,residentDestroy"); + break; } // Set the changed status. @@ -318,23 +319,7 @@ public void setType(@NotNull String type) { */ @Deprecated public void setType(int typeId) { - setType(TownBlockType.lookup(typeId).getName()); - } - - public void setType(TownBlockType type) { - setType(type.getName()); - } - - /** - * - * @param type The {@link TownBlockType} type set this plot to. - * @param resident The resident who is trying to set the type. - * @throws TownyException If this townblock has a pvp toggle cooldown. - * @deprecated As of 0.97.3.0, this is deprecated for compatibility with custom types. - */ - @Deprecated - public void setType(TownBlockType type, Resident resident) throws TownyException { - setType(type.getName(), resident); + } /** @@ -342,7 +327,7 @@ public void setType(TownBlockType type, Resident resident) throws TownyException * @param resident The resident who is trying to set the type. * @throws TownyException If this townblock has a pvp toggle cooldown. */ - public void setType(String type, Resident resident) throws TownyException { + public void setType(TownBlockType type, Resident resident) throws TownyException { // Delete a jail if this is no longer going to be a jail. if (this.isJail() && !TownBlockType.JAIL.equals(type)) { @@ -570,12 +555,6 @@ public TownBlockOwner getTownBlockOwner() { } public TownBlockData getData() { - return TownBlockTypeHandler.getData(this.type); - } - - private TownBlockType getTypeInternal() { - TownBlockType type = TownBlockType.lookup(this.type); - - return type == null ? TownBlockType.CUSTOM : type; + return type.getData(); } } \ No newline at end of file diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockData.java b/src/com/palmergames/bukkit/towny/object/TownBlockData.java index ed6fa559f7..6aa6dca16f 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockData.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockData.java @@ -7,23 +7,13 @@ import java.util.Set; public class TownBlockData { - private String type = "default"; - private String mapKey = ""; + private String mapKey = "+"; private double cost = 0.0; private double tax = 0.0; private Set itemUseIds = new HashSet<>(); // List of item names that will trigger an item use test. private Set switchIds = new HashSet<>(); // List of item names that will trigger a switch test. private Set allowedBlocks = new HashSet<>(); // List of item names that will always be allowed. - public TownBlockData(String typeName) { - this.type = typeName.toLowerCase(); - - TownBlockType type = TownBlockType.lookup(this.type); - if (type != null) { - mapKey = type.getAsciiMapKey(); - } - } - public String getMapKey() { return mapKey; } @@ -84,8 +74,4 @@ public double getTax(Town town) { else return tax; } - - public String getType() { - return type; - } } diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index 21e6381d8f..eb083682b8 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -1,59 +1,38 @@ package com.palmergames.bukkit.towny.object; -import java.util.EnumSet; import java.util.HashMap; import java.util.Map; -import com.palmergames.bukkit.towny.TownySettings; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author dumptruckman */ -public enum TownBlockType { - RESIDENTIAL(0, "Default", "+"), // The default Block Type. - COMMERCIAL(1, "Shop", "C") { // Just like residential but has additional tax - - @Override - public double getTax(Town town) { - - return town.getCommercialPlotTax() + town.getPlotTax(); - } - }, - ARENA(2, "Arena", "A"), //Always PVP enabled. - EMBASSY(3, "Embassy", "E") { // For other towns to own a plot in your town. - - @Override - public double getTax(Town town) { - - return town.getEmbassyPlotTax() + town.getPlotTax(); - } - }, - WILDS(4, "Wilds", "W"), //Follows wilderness protection settings, but town owned. - INN(6, "Inn", "I"), //Allows use of beds outside your own plot. - JAIL(7, "Jail", "J"), //Enables setting the jail spawn. - FARM(8, "Farm", "F"), //Follows wilderness protection settings, but town owned. - BANK(9, "Bank", "B"), // Enables depositing into town and nation banks, if that has been enabled in the config. - CUSTOM(10, "Custom", "C"); - - private final int id; - private final String name, asciiMapKey; +public class TownBlockType { + public static final TownBlockType RESIDENTIAL = new TownBlockType("Default"); // The default Block Type. + public static final TownBlockType COMMERCIAL = new TownBlockType("Shop"); // Just like residential but has additional tax + public static final TownBlockType ARENA = new TownBlockType("Arena"); //Always PVP enabled. + public static final TownBlockType EMBASSY = new TownBlockType("Embassy"); // For other towns to own a plot in your town. + public static final TownBlockType WILDS = new TownBlockType("Wilds"); //Follows wilderness protection settings, but town owned. + public static final TownBlockType INN = new TownBlockType("Inn"); //Allows use of beds outside your own plot. + public static final TownBlockType JAIL = new TownBlockType("Jail"); //Enables setting the jail spawn. + public static final TownBlockType FARM = new TownBlockType("Farm"); //Follows wilderness protection settings, but town owned. + public static final TownBlockType BANK = new TownBlockType("Bank"); // Enables depositing into town and nation banks, if that has been enabled in the config. + + private final String name; + private final TownBlockData data; private static final Map idLookup = new HashMap<>(); private static final Map nameLookup = new HashMap<>(); - TownBlockType(int id, String name, String asciiMapKey) { - - this.id = id; + public TownBlockType(String name, TownBlockData data) { this.name = name; - this.asciiMapKey = asciiMapKey; + this.data = data; } - - static { - for (TownBlockType s : EnumSet.allOf(TownBlockType.class)) { - idLookup.put(s.getId(), s); - nameLookup.put(s.toString().toLowerCase(), s); - } + + public TownBlockType(String name) { + this.name = name; + this.data = new TownBlockData(); } @Override @@ -70,20 +49,15 @@ public double getTax(Town town) { @Deprecated public int getId() { - - return id; + return 0; } public String getAsciiMapKey() { - TownBlockData data = TownBlockTypeHandler.getData(this.name); - - return data == null ? asciiMapKey : data.getMapKey(); + return data.getMapKey(); } public double getCost() { - TownBlockData data = TownBlockTypeHandler.getData(this.name); - - return data == null ? 0.0 : data.getCost(); + return data.getCost(); } public String getName() { @@ -99,14 +73,19 @@ public static TownBlockType lookup(int id) { @Nullable public static TownBlockType lookup(@NotNull String name) { TownBlockType type = nameLookup.get(name.toLowerCase()); - - if (type == null && TownBlockTypeHandler.exists(name)) // Type exists but it's not one of ours. - type = TownBlockType.CUSTOM; return type; } - public boolean equals(String type) { - return type != null && this == lookup(type); + public TownBlockData getData() { + return data; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof TownBlockType townBlockType)) + return false; + + return townBlockType.getName().equalsIgnoreCase(this.name); } } \ No newline at end of file diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index 27bae07a93..e17b63f4fb 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -9,6 +9,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Field; +import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -17,45 +19,50 @@ import java.util.concurrent.ConcurrentHashMap; public final class TownBlockTypeHandler { - private static Map townBlockDataMap = new ConcurrentHashMap<>(); + private static Map townBlockTypeMap = new ConcurrentHashMap<>(); public static void initialize() { - Map newData = new ConcurrentHashMap<>(); - for (TownBlockType type : TownBlockType.values()) { - String typeName = type.getName().toLowerCase(Locale.ROOT); - newData.put(typeName, new TownBlockData(typeName)); + Map newData = new ConcurrentHashMap<>(); + + for (Field field : TownBlockType.class.getFields()) { + String typeName = field.getName().toLowerCase(); + + try { + TownBlockType type = (TownBlockType) field.get(null); + newData.put(typeName, type); + } catch (Exception ignored) {} } applyConfigSettings(newData); Bukkit.getPluginManager().callEvent(new TownBlockTypeRegisterEvent()); - townBlockDataMap = newData; + Towny.getPlugin().getLogger().info(String.format("Loaded %d townblock types: %s", newData.size(), Arrays.toString(newData.keySet().toArray()))); + + townBlockTypeMap = newData; } /** * Registers a new type. Should not be used at all outside of the TownBlockTypeRegisterEvent. * @param name - The name for this type. - * @param data - The data for this type. + * @param type - The type * @throws TownyException - If a type with this name is already registered. */ - public static void registerType(@NotNull String name, @Nullable TownBlockData data) throws TownyException { + public static void registerType(@NotNull String name, @NotNull TownBlockType type) throws TownyException { if (exists(name)) throw new TownyException(String.format("A type named '%s' is already registered!", name)); - if (data == null) - data = new TownBlockData(name); - - townBlockDataMap.put(name.toLowerCase(), data); + townBlockTypeMap.put(name.toLowerCase(), type); } /** - * Gets the data for a townblock type. + * Gets the townblock instance for the name. * @param townBlockType The name of the town block type. + * @return The townblocktype instance, or {@code null} if none is registered. */ @Nullable - public static TownBlockData getData(@NotNull String townBlockType) { - return townBlockDataMap.get(townBlockType.toLowerCase(Locale.ROOT)); + public static TownBlockType getType(@NotNull String townBlockType) { + return townBlockTypeMap.get(townBlockType.toLowerCase()); } /** @@ -63,10 +70,10 @@ public static TownBlockData getData(@NotNull String townBlockType) { * @return Whether a type with the specified name exists. */ public static boolean exists(@NotNull String typeName) { - return getData(typeName) != null; + return getType(typeName) != null; } - private static void applyConfigSettings(Map newData) { + private static void applyConfigSettings(Map newData) { List> types = TownySettings.getConfig().getMapList("townblocktypes.types"); for (Map type : types) { @@ -82,7 +89,15 @@ private static void applyConfigSettings(Map newData) { Set switchIds = loadMaterialList(String.valueOf(type.get("switchIds")), name); Set allowedBlocks = loadMaterialList(String.valueOf(type.get("allowedBlocks")), name); - TownBlockData data = new TownBlockData(name); + TownBlockType townBlockType = newData.get(name.toLowerCase()); + TownBlockData data; + + if (townBlockType == null) { + data = new TownBlockData(); + townBlockType = new TownBlockType(name, data); + } else + data = townBlockType.getData(); + data.setCost(cost); data.setTax(tax); data.setMapKey(mapKey); @@ -90,8 +105,7 @@ private static void applyConfigSettings(Map newData) { data.setSwitchIds(switchIds); data.setAllowedBlocks(allowedBlocks); - newData.put(name.toLowerCase(), data); - Towny.getPlugin().getLogger().info(String.format("Loaded a townblock type: %s", name)); + newData.put(name.toLowerCase(), townBlockType); } catch (Exception e) { Towny.getPlugin().getLogger().warning(String.format("Error while loading townblock type '%s', skipping...", name)); diff --git a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java index 70de6c8f0e..1ccd05cfe2 100644 --- a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java +++ b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java @@ -407,7 +407,7 @@ protected void collectTownTaxes(Town town) { townBlock.setPlotPrice(-1); // Set the plot permissions to mirror the towns. - townBlock.setType(townBlock.getTypeName()); + townBlock.setType(townBlock.getType()); townBlock.save(); } From f11ebed0feb4e24673fd00045b0263d8580b734d Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 21 Oct 2021 02:33:21 +0200 Subject: [PATCH 05/28] Reduce diff & fixes --- .../bukkit/towny/ChunkNotification.java | 8 ++++---- .../palmergames/bukkit/towny/TownyAsciiMap.java | 2 +- .../bukkit/towny/TownyFormatter.java | 2 +- .../bukkit/towny/command/PlotCommand.java | 10 +++++----- .../towny/event/TownBlockTypeRegisterEvent.java | 7 ++----- .../palmergames/bukkit/towny/huds/MapHUD.java | 2 +- .../bukkit/towny/object/TownBlock.java | 2 +- .../bukkit/towny/object/TownBlockType.java | 17 ++++++++++------- .../towny/object/TownBlockTypeHandler.java | 9 ++++----- .../bukkit/towny/tasks/DailyTimerTask.java | 6 +++--- .../bukkit/towny/utils/PlayerCacheUtil.java | 2 +- 11 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/ChunkNotification.java b/src/com/palmergames/bukkit/towny/ChunkNotification.java index cae4482aab..8554045eea 100644 --- a/src/com/palmergames/bukkit/towny/ChunkNotification.java +++ b/src/com/palmergames/bukkit/towny/ChunkNotification.java @@ -72,7 +72,7 @@ public static void loadFormatStrings() { TownBlock fromTownBlock, toTownBlock = null; Town fromTown = null, toTown = null; Resident fromResident = null, toResident = null; - String fromPlotType = null, toPlotType = null; + TownBlockType fromPlotType = null, toPlotType = null; PlotGroup fromPlotGroup = null, toPlotGroup = null; public ChunkNotification(WorldCoord from, WorldCoord to) { @@ -82,7 +82,7 @@ public ChunkNotification(WorldCoord from, WorldCoord to) { if (from.hasTownBlock()) { fromTownBlock = from.getTownBlockOrNull(); - fromPlotType = StringMgmt.capitalize(fromTownBlock.getTypeName()); + fromPlotType = fromTownBlock.getType(); fromForSale = fromTownBlock.getPlotPrice() != -1; if (fromTownBlock.hasPlotObjectGroup()) { fromPlotGroup = fromTownBlock.getPlotObjectGroup(); @@ -98,7 +98,7 @@ public ChunkNotification(WorldCoord from, WorldCoord to) { if (to.hasTownBlock()) { toTownBlock = to.getTownBlockOrNull(); - toPlotType = StringMgmt.capitalize(toTownBlock.getTypeName()); + toPlotType = toTownBlock.getType(); toTown = toTownBlock.getTownOrNull(); toResident = toTownBlock.getResidentOrNull(); toForSale = toTownBlock.getPlotPrice() != -1; @@ -314,7 +314,7 @@ public String getGroupNotification() { public String getPlotTypeNotification() { if (toPlotType != null && !toPlotType.equals(fromPlotType) && !TownBlockType.RESIDENTIAL.equals(toPlotType)) - return String.format(plotTypeNotificationFormat, toPlotType); + return String.format(plotTypeNotificationFormat, StringMgmt.capitalize(toPlotType.getName())); return null; } } diff --git a/src/com/palmergames/bukkit/towny/TownyAsciiMap.java b/src/com/palmergames/bukkit/towny/TownyAsciiMap.java index 002543607f..644c995d5a 100644 --- a/src/com/palmergames/bukkit/towny/TownyAsciiMap.java +++ b/src/com/palmergames/bukkit/towny/TownyAsciiMap.java @@ -131,7 +131,7 @@ else if (nation.hasEnemy(town.getNation())) } else if (townblock.isHomeBlock()) townyMap[y][x] = townyMap[y][x].content("H"); else - townyMap[y][x] = townyMap[y][x].content(townblock.getData().getMapKey()); + townyMap[y][x] = townyMap[y][x].content(townblock.getType().getAsciiMapKey()); TextComponent forSaleComponent = Component.empty(); TextComponent claimedAtComponent = Component.empty(); diff --git a/src/com/palmergames/bukkit/towny/TownyFormatter.java b/src/com/palmergames/bukkit/towny/TownyFormatter.java index 6437996963..f97d3688b1 100644 --- a/src/com/palmergames/bukkit/towny/TownyFormatter.java +++ b/src/com/palmergames/bukkit/towny/TownyFormatter.java @@ -1049,7 +1049,7 @@ public static List getTaxStatus(Resident resident, Locale locale) { if (town != null) { if (taxExempt && town.hasResident(resident)) // Resident will not pay any tax for plots owned by their towns. continue; - plotTax += townBlock.getData().getTax(town); + plotTax += townBlock.getType().getTax(town); } } diff --git a/src/com/palmergames/bukkit/towny/command/PlotCommand.java b/src/com/palmergames/bukkit/towny/command/PlotCommand.java index f201640417..14580ff6cb 100644 --- a/src/com/palmergames/bukkit/towny/command/PlotCommand.java +++ b/src/com/palmergames/bukkit/towny/command/PlotCommand.java @@ -708,7 +708,7 @@ public boolean parsePlotCommand(Player player, String[] split) { } } - PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(TownBlockType.lookup(plotTypeName), townBlock, resident); + PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(type, townBlock, resident); BukkitTools.getPluginManager().callEvent(preEvent); if (preEvent.isCancelled()) { @@ -1726,7 +1726,7 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow // Handle type being reset if (plotTypeName.equalsIgnoreCase("reset")) plotTypeName = "default"; - + TownBlockType type = TownBlockTypeHandler.getType(plotTypeName); if (type == null) @@ -1752,7 +1752,7 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow } // Allow for PlotPreChangeTypeEvent to trigger - PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(TownBlockType.lookup(plotTypeName), tb, resident); + PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(type, tb, resident); BukkitTools.getPluginManager().callEvent(preEvent); // If any one of the townblocks is not allowed to be set, cancel setting all of them. @@ -1762,8 +1762,8 @@ private boolean handlePlotGroupCommand(String[] split, Player player) throws Tow } } - int amount = townBlock.getPlotObjectGroup().getTownBlocks().size(); - double cost = type.getData().getCost() * amount; + int amount = townBlock.getPlotObjectGroup().getTownBlocks().size(); + double cost = type.getCost() * amount; try { // Test if we can pay first to throw an exception. diff --git a/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java b/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java index e8001aa6c9..bb6ee2a32f 100644 --- a/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java +++ b/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java @@ -1,14 +1,12 @@ package com.palmergames.bukkit.towny.event; import com.palmergames.bukkit.towny.exceptions.TownyException; -import com.palmergames.bukkit.towny.object.TownBlockData; import com.palmergames.bukkit.towny.object.TownBlockType; import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; public class TownBlockTypeRegisterEvent extends Event { private static final HandlerList handlers = new HandlerList(); @@ -19,12 +17,11 @@ public TownBlockTypeRegisterEvent() { /** * Registers a new type. - * @param name - The name for this type. * @param type - The type * @throws TownyException - If a type with this name is already registered. */ - public static void registerType(@NotNull String name, @NotNull TownBlockType type) throws TownyException { - TownBlockTypeHandler.registerType(name, type); + public static void registerType(@NotNull TownBlockType type) throws TownyException { + TownBlockTypeHandler.registerType(type); } @Override diff --git a/src/com/palmergames/bukkit/towny/huds/MapHUD.java b/src/com/palmergames/bukkit/towny/huds/MapHUD.java index c3e9e9e8bc..c4f91b9e39 100644 --- a/src/com/palmergames/bukkit/towny/huds/MapHUD.java +++ b/src/com/palmergames/bukkit/towny/huds/MapHUD.java @@ -133,7 +133,7 @@ else if (nation.hasEnemy(townblock.getTown().getNation())) } else if (townblock.isHomeBlock()) map[y][x] += "H"; else - map[y][x] += townblock.getData().getMapKey(); + map[y][x] += townblock.getType().getAsciiMapKey(); } catch (TownyException e) { // Unregistered town block diff --git a/src/com/palmergames/bukkit/towny/object/TownBlock.java b/src/com/palmergames/bukkit/towny/object/TownBlock.java index 5b9094eadc..41619f7c84 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlock.java @@ -34,6 +34,7 @@ public class TownBlock extends TownyObject { private TownyWorld world; private Town town = null; private Resident resident = null; + private TownBlockType type = TownBlockType.RESIDENTIAL; private int x, z; private double plotPrice = -1; private boolean locked = false; @@ -43,7 +44,6 @@ public class TownBlock extends TownyObject { private Jail jail; private Map permissionOverrides = new HashMap<>(); private Set trustedResidents = new HashSet<>(); - private TownBlockType type = TownBlockType.RESIDENTIAL; //Plot level permissions protected TownyPermission permissions = new TownyPermission(); diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index eb083682b8..8036e9f1ba 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -41,10 +41,8 @@ public String toString() { return name; } - @Deprecated public double getTax(Town town) { - - return town.getPlotTax(); + return data.getTax(town); } @Deprecated @@ -64,17 +62,22 @@ public String getName() { return name; } + /** + * @deprecated As of 0.97.3.0 + */ @Nullable @Deprecated public static TownBlockType lookup(int id) { - return idLookup.get(id); + return null; } + /** + * @deprecated As of 0.97.3.0, please use {@link TownBlockTypeHandler#getType(String)} instead. + */ @Nullable + @Deprecated public static TownBlockType lookup(@NotNull String name) { - TownBlockType type = nameLookup.get(name.toLowerCase()); - - return type; + return TownBlockTypeHandler.getType(name); } public TownBlockData getData() { diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index e17b63f4fb..884313e64b 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -44,15 +44,14 @@ public static void initialize() { /** * Registers a new type. Should not be used at all outside of the TownBlockTypeRegisterEvent. - * @param name - The name for this type. * @param type - The type * @throws TownyException - If a type with this name is already registered. */ - public static void registerType(@NotNull String name, @NotNull TownBlockType type) throws TownyException { - if (exists(name)) - throw new TownyException(String.format("A type named '%s' is already registered!", name)); + public static void registerType(@NotNull TownBlockType type) throws TownyException { + if (exists(type.getName())) + throw new TownyException(String.format("A type named '%s' is already registered!", type.getName())); - townBlockTypeMap.put(name.toLowerCase(), type); + townBlockTypeMap.put(type.getName().toLowerCase(), type); } /** diff --git a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java index 1ccd05cfe2..3a7ff4cc72 100644 --- a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java +++ b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java @@ -385,7 +385,7 @@ protected void collectTownTaxes(Town town) { if (TownyPerms.getResidentPerms(resident).containsKey("towny.tax_exempt") || resident.isNPC()) continue; - double tax = townBlock.getData().getTax(town); + double tax = townBlock.getType().getTax(town); if (tax < 1) continue; @@ -394,7 +394,7 @@ protected void collectTownTaxes(Town town) { if (TownySettings.getTownBankCap() != 0 && tax + town.getAccount().getHoldingBalance() > TownySettings.getTownBankCap()) tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); - if (!resident.getAccount().payTo(tax, town, String.format("Plot Tax (%s)", townBlock.getTypeName()))) { + if (!resident.getAccount().payTo(tax, town, String.format("Plot Tax (%s)", townBlock.getType()))) { if (!lostPlots.contains(resident.getName())) lostPlots.add(resident.getName()); @@ -402,7 +402,7 @@ protected void collectTownTaxes(Town town) { // Set the plot price. if (TownySettings.doesPlotTaxNonPaymentSetPlotForSale()) - townBlock.setPlotPrice(townBlock.getData().getCost()); + townBlock.setPlotPrice(town.getPlotTypePrice(townBlock.getType())); else townBlock.setPlotPrice(-1); diff --git a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java index 05558d2c0a..e475c52901 100644 --- a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java @@ -496,7 +496,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.PLOT_FRIEND) { // Plot allows Friends perms and we aren't stopped by Wilds or Farm Plot overrides. - if (townBlock.getPermissions().getResidentPerm(action)) + if (townBlock.getPermissions().getResidentPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; cacheBlockErrMsg(player, Translatable.of("msg_cache_block_error_plot", Translatable.of("msg_cache_block_error_plot_friends"), Translatable.of(action.toString())).forLocale(player)); From 37dbbfdd2d8a033d3dfffc8162a19604b938a596 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 21 Oct 2021 17:08:49 +0200 Subject: [PATCH 06/28] Migration start & fixes --- .../config/migration/ConfigMigrator.java | 38 ++++++++++++++----- .../config/migration/MigrationType.java | 3 +- .../bukkit/towny/TownySettings.java | 6 +++ .../bukkit/towny/object/TownBlockType.java | 3 -- .../towny/object/TownBlockTypeHandler.java | 7 +--- 5 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/com/palmergames/bukkit/config/migration/ConfigMigrator.java b/src/com/palmergames/bukkit/config/migration/ConfigMigrator.java index 70fa3ce962..652962bf5e 100644 --- a/src/com/palmergames/bukkit/config/migration/ConfigMigrator.java +++ b/src/com/palmergames/bukkit/config/migration/ConfigMigrator.java @@ -11,7 +11,8 @@ import com.palmergames.bukkit.towny.object.TownyWorld; import com.palmergames.bukkit.towny.permissions.TownyPerms; import com.palmergames.bukkit.util.Version; -import java.io.InputStream; + +import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.util.List; @@ -19,7 +20,7 @@ import java.util.Objects; /** - * An object which manages the procces of migrating towny config versions to + * An object which manages the process of migrating towny config versions to * up-to-date ones. */ public class ConfigMigrator { @@ -84,6 +85,9 @@ private void performChange(Change change) { addPermissions(change.path, change.value); TownyMessaging.sendDebugMsg("Updating townyperms.yml, adding " + change.value + " to " + change.path + " group."); break; + case TOWNBLOCKTYPE_ADD: + addTownBlockTypeProperty(change.path, change.key, change.value); + break; default: throw new UnsupportedOperationException("Unsupported Change type: " + change); } @@ -107,15 +111,12 @@ private void addPermissions(String key, String value) { } private List readMigrator() { - InputStream file = Towny.getPlugin().getResource(migrationFilename); - - if (file == null) { - throw new UnsupportedOperationException(migrationFilename + " was not found cannot upgrade config"); + try (Reader reader = new InputStreamReader(Towny.getPlugin().getResource(migrationFilename))) { + + return GSON.fromJson(reader, new TypeToken>(){}.getType()); + } catch (IOException ignored) { + return null; } - - Reader reader = new InputStreamReader(file); - - return GSON.fromJson(reader, new TypeToken>(){}.getType()); } public void addTownLevelProperty(String key, String value) { @@ -139,6 +140,23 @@ public void addNationLevelProperty(String key, String value) { config.set("levels.nation_level", mapList); } + + public void addTownBlockTypeProperty(String path, String key, String value) { + List> mapList = config.getMapList("townblocktypes.types"); + + Object object = value; + + if (config.contains(value)) + object = config.get(value); + + for (Map map : mapList) { + if (map.get("name").toString().equalsIgnoreCase(path)) { + ((Map) map).put(key, object); + } + } + + config.set("townblocktypes.types", mapList); + } /** * Represents a collection of changes. diff --git a/src/com/palmergames/bukkit/config/migration/MigrationType.java b/src/com/palmergames/bukkit/config/migration/MigrationType.java index 0be7238fee..77833f7076 100644 --- a/src/com/palmergames/bukkit/config/migration/MigrationType.java +++ b/src/com/palmergames/bukkit/config/migration/MigrationType.java @@ -5,5 +5,6 @@ public enum MigrationType { APPEND, NATION_LEVEL_ADD, TOWN_LEVEL_ADD, - TOWNYPERMS_ADD + TOWNYPERMS_ADD, + TOWNBLOCKTYPE_ADD } diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index d506b38635..e5d184e675 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -500,6 +500,12 @@ private static void setDefaults(String version, Path configPath) { setDefaultLevels(); + } else if ( (root.getRoot().equals(ConfigNodes.LEVELS_TOWN_LEVEL.getRoot())) + || (root.getRoot().equals(ConfigNodes.LEVELS_NATION_LEVEL.getRoot()))){ + + // Do nothing here as setDefaultLevels configured town and + // nation levels. + } else if (root.getRoot().equals(ConfigNodes.VERSION.getRoot())) { setNewProperty(root.getRoot(), version); } else if (root.getRoot().equals(ConfigNodes.LAST_RUN_VERSION.getRoot())) { diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index 8036e9f1ba..7e5b36b449 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -22,8 +22,6 @@ public class TownBlockType { private final String name; private final TownBlockData data; - private static final Map idLookup = new HashMap<>(); - private static final Map nameLookup = new HashMap<>(); public TownBlockType(String name, TownBlockData data) { this.name = name; @@ -37,7 +35,6 @@ public TownBlockType(String name) { @Override public String toString() { - return name; } diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index 884313e64b..02a21bb355 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -13,7 +13,6 @@ import java.util.Arrays; import java.util.HashSet; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -24,12 +23,10 @@ public final class TownBlockTypeHandler { public static void initialize() { Map newData = new ConcurrentHashMap<>(); - for (Field field : TownBlockType.class.getFields()) { - String typeName = field.getName().toLowerCase(); - + for (Field field : TownBlockType.class.getFields()) { try { TownBlockType type = (TownBlockType) field.get(null); - newData.put(typeName, type); + newData.put(type.getName().toLowerCase(), type); } catch (Exception ignored) {} } From ca04651f67326727ffbd1bb5c2a919636a499e9e Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 21 Oct 2021 20:57:39 +0200 Subject: [PATCH 07/28] Finish migration code --- .../bukkit/config/ConfigNodes.java | 44 ------------ .../config/migration/ConfigMigrator.java | 20 ------ .../config/migration/MigrationType.java | 3 +- src/com/palmergames/bukkit/towny/Towny.java | 2 + .../bukkit/towny/TownySettings.java | 40 ++--------- .../bukkit/towny/command/TownyCommand.java | 5 -- .../towny/object/TownBlockTypeHandler.java | 71 +++++++++++++++++++ 7 files changed, 81 insertions(+), 104 deletions(-) diff --git a/src/com/palmergames/bukkit/config/ConfigNodes.java b/src/com/palmergames/bukkit/config/ConfigNodes.java index 23ac076d8a..c5cdc6e489 100644 --- a/src/com/palmergames/bukkit/config/ConfigNodes.java +++ b/src/com/palmergames/bukkit/config/ConfigNodes.java @@ -720,13 +720,6 @@ public enum ConfigNodes { "# Automatically precludes towns from one world joining a nation in another world.", "# If the number is 0, towns will not a proximity to a nation." ), - GTOWN_FARM_PLOT_ALLOW_BLOCKS( - "global_town_settings.farm_plot_allow_blocks", - "BAMBOO,BAMBOO_SAPLING,JUNGLE_LOG,JUNGLE_SAPLING,JUNGLE_LEAVES,OAK_LOG,OAK_SAPLING,OAK_LEAVES,BIRCH_LOG,BIRCH_SAPLING,BIRCH_LEAVES,ACACIA_LOG,ACACIA_SAPLING,ACACIA_LEAVES,DARK_OAK_LOG,DARK_OAK_SAPLING,DARK_OAK_LEAVES,SPRUCE_LOG,SPRUCE_SAPLING,SPRUCE_LEAVES,BEETROOTS,COCOA,CHORUS_PLANT,CHORUS_FLOWER,SWEET_BERRY_BUSH,KELP,SEAGRASS,TALL_SEAGRASS,GRASS,TALL_GRASS,FERN,LARGE_FERN,CARROTS,WHEAT,POTATOES,PUMPKIN,PUMPKIN_STEM,ATTACHED_PUMPKIN_STEM,NETHER_WART,COCOA,VINE,MELON,MELON_STEM,ATTACHED_MELON_STEM,SUGAR_CANE,CACTUS,ALLIUM,AZURE_BLUET,BLUE_ORCHID,CORNFLOWER,DANDELION,LILAC,LILY_OF_THE_VALLEY,ORANGE_TULIP,OXEYE_DAISY,PEONY,PINK_TULIP,POPPY,RED_TULIP,ROSE_BUSH,SUNFLOWER,WHITE_TULIP,WITHER_ROSE,CRIMSON_FUNGUS,CRIMSON_STEM,CRIMSON_HYPHAE,CRIMSON_ROOTS,MUSHROOM_STEM,NETHER_WART_BLOCK,BROWN_MUSHROOM,BROWN_MUSHROOM_BLOCK,RED_MUSHROOM,RED_MUSHROOM_BLOCK,SHROOMLIGHT,WARPED_FUNGUS,WARPED_HYPHAE,WARPED_ROOTS,WARPED_STEM,WARPED_WART_BLOCK,WEEPING_VINES_PLANT,WEEPING_VINES,NETHER_SPROUTS,SHEARS", - "", - "# List of blocks which can be modified on farm plots, as long as player is also allowed in the plot's '/plot perm' line.", - "# Not included by default but some servers add GRASS_BLOCK,FARMLAND,DIRT,NETHERRACK,CRIMSON_NYLIUM,WARPED_NYLIUM to their list." - ), GTOWN_FARM_ANIMALS( "global_town_settings.farm_animals", "PIG,COW,CHICKEN,SHEEP,MOOSHROOM", @@ -2233,43 +2226,6 @@ public enum ConfigNodes { "false", "", "# Does a conquered town which cannot pay the nation tax get deleted?"), - - ECO_PLOT_TYPE_COSTS("economy.plot_type_costs","",""), - ECO_PLOT_TYPE_COSTS_COMMERCIAL("economy.plot_type_costs.set_commercial", - "0.0", - "", - "# Cost to use /plot set shop to change a normal plot to a shop plot."), - ECO_PLOT_TYPE_COSTS_ARENA("economy.plot_type_costs.set_arena", - "0.0", - "", - "# Cost to use /plot set arena to change a normal plot to a arena plot."), - ECO_PLOT_TYPE_COSTS_EMBASSY("economy.plot_type_costs.set_embassy", - "0.0", - "", - "# Cost to use /plot set embassy to change a normal plot to a embassy plot."), - ECO_PLOT_TYPE_COSTS_WILDS("economy.plot_type_costs.set_wilds", - "0.0", - "", - "# Cost to use /plot set wilds to change a normal plot to a wilds plot."), - ECO_PLOT_TYPE_COSTS_INN("economy.plot_type_costs.set_inn", - "0.0", - "", - "# Cost to use /plot set inn to change a normal plot to a inn plot."), - ECO_PLOT_TYPE_COSTS_JAIL("economy.plot_type_costs.set_jail", - "0.0", - "", - "# Cost to use /plot set jail to change a normal plot to a jail plot."), - ECO_PLOT_TYPE_COSTS_FARM("economy.plot_type_costs.set_farm", - "0.0", - "", - "# Cost to use /plot set farm to change a normal plot to a farm plot."), - ECO_PLOT_TYPE_COSTS_BANK("economy.plot_type_costs.set_bank", - "0.0", - "", - "# Cost to use /plot set bank to change a normal plot to a bank plot."), -// ECO_PLOT_TYPE_COSTS_OUTPOST("economy.plot_type_costs.set_outpost", -// "0.0", -// "# Cost to use /plot set outpost to change a normal plot to a outpost plot."), BANKHISTORY( "bank_history", diff --git a/src/com/palmergames/bukkit/config/migration/ConfigMigrator.java b/src/com/palmergames/bukkit/config/migration/ConfigMigrator.java index 652962bf5e..f743d27abb 100644 --- a/src/com/palmergames/bukkit/config/migration/ConfigMigrator.java +++ b/src/com/palmergames/bukkit/config/migration/ConfigMigrator.java @@ -85,9 +85,6 @@ private void performChange(Change change) { addPermissions(change.path, change.value); TownyMessaging.sendDebugMsg("Updating townyperms.yml, adding " + change.value + " to " + change.path + " group."); break; - case TOWNBLOCKTYPE_ADD: - addTownBlockTypeProperty(change.path, change.key, change.value); - break; default: throw new UnsupportedOperationException("Unsupported Change type: " + change); } @@ -140,23 +137,6 @@ public void addNationLevelProperty(String key, String value) { config.set("levels.nation_level", mapList); } - - public void addTownBlockTypeProperty(String path, String key, String value) { - List> mapList = config.getMapList("townblocktypes.types"); - - Object object = value; - - if (config.contains(value)) - object = config.get(value); - - for (Map map : mapList) { - if (map.get("name").toString().equalsIgnoreCase(path)) { - ((Map) map).put(key, object); - } - } - - config.set("townblocktypes.types", mapList); - } /** * Represents a collection of changes. diff --git a/src/com/palmergames/bukkit/config/migration/MigrationType.java b/src/com/palmergames/bukkit/config/migration/MigrationType.java index 77833f7076..0be7238fee 100644 --- a/src/com/palmergames/bukkit/config/migration/MigrationType.java +++ b/src/com/palmergames/bukkit/config/migration/MigrationType.java @@ -5,6 +5,5 @@ public enum MigrationType { APPEND, NATION_LEVEL_ADD, TOWN_LEVEL_ADD, - TOWNYPERMS_ADD, - TOWNBLOCKTYPE_ADD + TOWNYPERMS_ADD } diff --git a/src/com/palmergames/bukkit/towny/Towny.java b/src/com/palmergames/bukkit/towny/Towny.java index 3605f63813..a55bdeb03f 100644 --- a/src/com/palmergames/bukkit/towny/Towny.java +++ b/src/com/palmergames/bukkit/towny/Towny.java @@ -231,6 +231,8 @@ public void onEnable() { public void loadFoundation(boolean reload) { // Before anything can continue we must load the databaseconfig, config // file, language and permissions, setting the foundation for Towny. + + TownBlockTypeHandler.Migrator.checkForLegacyOptions(); // Load the database config first, so any conversion happens before the config is loaded. loadDatabaseConfig(reload); diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index e5d184e675..af234c0b13 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -15,6 +15,7 @@ import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.TownBlock; import com.palmergames.bukkit.towny.object.TownBlockOwner; +import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import com.palmergames.bukkit.towny.object.TownSpawnLevel.SpawnLevel; import com.palmergames.bukkit.towny.object.TownyPermission.ActionType; import com.palmergames.bukkit.towny.object.TownyPermission.PermLevel; @@ -300,6 +301,7 @@ public static void loadConfig(Path configPath, String version) { loadSwitchAndItemUseMaterialsLists(); loadProtectedMobsList(); ChunkNotification.loadFormatStrings(); + TownBlockTypeHandler.Migrator.migrate(); } private static void loadProtectedMobsList() { @@ -812,7 +814,7 @@ private static void setTownBlockTypes() { type.put("mapKey", "F"); type.put("itemUseIds", ""); type.put("switchIds", ""); - type.put("allowedBlocks", "BAMBOO,BAMBOO_SAPLING,JUNGLE_LOG,JUNGLE_SAPLING,JUNGLE_LEAVES,OAK_LOG,OAK_SAPLING,OAK_LEAVES,BIRCH_LOG,BIRCH_SAPLING,BIRCH_LEAVES,ACACIA_LOG,ACACIA_SAPLING,ACACIA_LEAVES,DARK_OAK_LOG,DARK_OAK_SAPLING,DARK_OAK_LEAVES,SPRUCE_LOG,SPRUCE_SAPLING,SPRUCE_LEAVES,BEETROOTS,COCOA,CHORUS_PLANT,CHORUS_FLOWER,SWEET_BERRY_BUSH,KELP,SEAGRASS,TALL_SEAGRASS,GRASS,TALL_GRASS,FERN,LARGE_FERN,CARROTS,WHEAT,POTATOES,PUMPKIN,PUMPKIN_STEM,ATTACHED_PUMPKIN_STEM,NETHER_WART,COCOA,VINE,MELON,MELON_STEM,ATTACHED_MELON_STEM,SUGAR_CANE,CACTUS,ALLIUM,AZURE_BLUET,BLUE_ORCHID,CORNFLOWER,DANDELION,LILAC,LILY_OF_THE_VALLEY,ORANGE_TULIP,OXEYE_DAISY,PEONY,PINK_TULIP,POPPY,RED_TULIP,ROSE_BUSH,SUNFLOWER,WHITE_TULIP,WITHER_ROSE,CRIMSON_FUNGUS,CRIMSON_STEM,CRIMSON_HYPHAE,CRIMSON_ROOTS,MUSHROOM_STEM,NETHER_WART_BLOCK,BROWN_MUSHROOM,BROWN_MUSHROOM_BLOCK,RED_MUSHROOM,RED_MUSHROOM_BLOCK,SHROOMLIGHT,WARPED_FUNGUS,WARPED_HYPHAE,WARPED_ROOTS,WARPED_STEM,WARPED_WART_BLOCK,WEEPING_VINES_PLANT,WEEPING_VINES,NETHER_SPROUTS,SHEARS"); + type.put("allowedBlocks", getDefaultFarmblocks()); types.add(new LinkedHashMap<>(type)); type.clear(); @@ -829,6 +831,10 @@ private static void setTownBlockTypes() { } else newConfig.set(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot(), config.get(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot())); } + + public static String getDefaultFarmblocks() { + return "BAMBOO,BAMBOO_SAPLING,JUNGLE_LOG,JUNGLE_SAPLING,JUNGLE_LEAVES,OAK_LOG,OAK_SAPLING,OAK_LEAVES,BIRCH_LOG,BIRCH_SAPLING,BIRCH_LEAVES,ACACIA_LOG,ACACIA_SAPLING,ACACIA_LEAVES,DARK_OAK_LOG,DARK_OAK_SAPLING,DARK_OAK_LEAVES,SPRUCE_LOG,SPRUCE_SAPLING,SPRUCE_LEAVES,BEETROOTS,COCOA,CHORUS_PLANT,CHORUS_FLOWER,SWEET_BERRY_BUSH,KELP,SEAGRASS,TALL_SEAGRASS,GRASS,TALL_GRASS,FERN,LARGE_FERN,CARROTS,WHEAT,POTATOES,PUMPKIN,PUMPKIN_STEM,ATTACHED_PUMPKIN_STEM,NETHER_WART,COCOA,VINE,MELON,MELON_STEM,ATTACHED_MELON_STEM,SUGAR_CANE,CACTUS,ALLIUM,AZURE_BLUET,BLUE_ORCHID,CORNFLOWER,DANDELION,LILAC,LILY_OF_THE_VALLEY,ORANGE_TULIP,OXEYE_DAISY,PEONY,PINK_TULIP,POPPY,RED_TULIP,ROSE_BUSH,SUNFLOWER,WHITE_TULIP,WITHER_ROSE,CRIMSON_FUNGUS,CRIMSON_STEM,CRIMSON_HYPHAE,CRIMSON_ROOTS,MUSHROOM_STEM,NETHER_WART_BLOCK,BROWN_MUSHROOM,BROWN_MUSHROOM_BLOCK,RED_MUSHROOM,RED_MUSHROOM_BLOCK,SHROOMLIGHT,WARPED_FUNGUS,WARPED_HYPHAE,WARPED_ROOTS,WARPED_STEM,WARPED_WART_BLOCK,WEEPING_VINES_PLANT,WEEPING_VINES,NETHER_SPROUTS,SHEARS"; + } public static String getKingPrefix(Resident resident) { @@ -2846,38 +2852,6 @@ public static String getPAPIRelationAlly() { public static String getPAPIRelationEnemy() { return getString(ConfigNodes.FILTERS_PAPI_REL_FORMATTING_ENEMY); } - - public static double getPlotSetCommercialCost() { - return getDouble(ConfigNodes.ECO_PLOT_TYPE_COSTS_COMMERCIAL); - } - - public static double getPlotSetArenaCost() { - return getDouble(ConfigNodes.ECO_PLOT_TYPE_COSTS_ARENA); - } - - public static double getPlotSetEmbassyCost() { - return getDouble(ConfigNodes.ECO_PLOT_TYPE_COSTS_EMBASSY); - } - - public static double getPlotSetWildsCost() { - return getDouble(ConfigNodes.ECO_PLOT_TYPE_COSTS_WILDS); - } - - public static double getPlotSetInnCost() { - return getDouble(ConfigNodes.ECO_PLOT_TYPE_COSTS_INN); - } - - public static double getPlotSetJailCost() { - return getDouble(ConfigNodes.ECO_PLOT_TYPE_COSTS_JAIL); - } - - public static double getPlotSetFarmCost() { - return getDouble(ConfigNodes.ECO_PLOT_TYPE_COSTS_FARM); - } - - public static double getPlotSetBankCost() { - return getDouble(ConfigNodes.ECO_PLOT_TYPE_COSTS_BANK); - } public static int getMaxDistanceFromTownSpawnForInvite() { return getInt(ConfigNodes.INVITE_SYSTEM_MAX_DISTANCE_FROM_TOWN_SPAWN); diff --git a/src/com/palmergames/bukkit/towny/command/TownyCommand.java b/src/com/palmergames/bukkit/towny/command/TownyCommand.java index a1e8793534..5810d9a799 100644 --- a/src/com/palmergames/bukkit/towny/command/TownyCommand.java +++ b/src/com/palmergames/bukkit/towny/command/TownyCommand.java @@ -489,11 +489,6 @@ else if (TownySettings.isNationUpkeepPerTown()) output.add(translator.of("towny_prices_taxes_shop", getMoney(town.getCommercialPlotTax()), getMoney(town.getEmbassyPlotTax()))); output.add(translator.of("towny_prices_town_neutral_tax", getMoney(TownySettings.getTownNeutralityCost()))); - output.add(translator.of("towny_prices_plots_shop", getMoney(TownySettings.getPlotSetCommercialCost()), getMoney(TownySettings.getPlotSetEmbassyCost()))); - output.add(translator.of("towny_prices_plots_wilds", getMoney(TownySettings.getPlotSetWildsCost()), getMoney(TownySettings.getPlotSetInnCost()))); - output.add(translator.of("towny_prices_plots_jail", getMoney(TownySettings.getPlotSetJailCost()), getMoney(TownySettings.getPlotSetFarmCost()))); - output.add(translator.of("towny_prices_plots_bank", getMoney(TownySettings.getPlotSetBankCost()))); - if (nation != null) { output.add(translator.of("towny_prices_nationname", nation.getFormattedName())); output.add(translator.of("towny_prices_nation_tax", nation.getTaxes(), getMoney(TownySettings.getNationNeutralityCost()))); diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index 02a21bb355..def10e7bba 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -1,5 +1,9 @@ package com.palmergames.bukkit.towny.object; +import com.github.bsideup.jabel.Desugar; +import com.google.common.primitives.Doubles; +import com.palmergames.bukkit.config.CommentedConfiguration; +import com.palmergames.bukkit.config.ConfigNodes; import com.palmergames.bukkit.towny.Towny; import com.palmergames.bukkit.towny.TownySettings; import com.palmergames.bukkit.towny.event.TownBlockTypeRegisterEvent; @@ -10,6 +14,8 @@ import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Arrays; import java.util.HashSet; import java.util.List; @@ -128,4 +134,69 @@ private static Set loadMaterialList(String materialList, String typeNa } private TownBlockTypeHandler() {} + + public static class Migrator { + private static final Set migrations = new HashSet<>(); + + public static void checkForLegacyOptions() { + Path configPath = Towny.getPlugin().getDataFolder().toPath().resolve("settings").resolve("config.yml"); + if (!Files.exists(configPath)) + return; + + CommentedConfiguration config = new CommentedConfiguration(configPath); + if (!config.load() || config.contains(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot())) + return; + + double shopCost = parseDouble(config.getString("economy.plot_type_costs.set_commercial")); + double arenaCost = parseDouble(config.getString("economy.plot_type_costs.set_arena")); + double embassyCost = parseDouble(config.getString("economy.plot_type_costs.set_embassy")); + double wildsCost = parseDouble(config.getString("economy.plot_type_costs.set_wilds")); + double innCost = parseDouble(config.getString("economy.plot_type_costs.set_inn")); + double jailCost = parseDouble(config.getString("economy.plot_type_costs.set_jail")); + double farmCost = parseDouble(config.getString("economy.plot_type_costs.set_farm")); + double bankCost = parseDouble(config.getString("economy.plot_type_costs.set_bank")); + + String farmPlotBlocks = config.getString("global_town_settings.farm_plot_allow_blocks", TownySettings.getDefaultFarmblocks()); + + migrations.add(new Migration("shop", "cost", shopCost)); + migrations.add(new Migration("arena", "cost", arenaCost)); + migrations.add(new Migration("embassy", "cost", embassyCost)); + migrations.add(new Migration("wilds", "cost", wildsCost)); + migrations.add(new Migration("inn", "cost", innCost)); + migrations.add(new Migration("jail", "cost", jailCost)); + migrations.add(new Migration("farm", "cost", farmCost)); + migrations.add(new Migration("farm", "allowedBlocks", farmPlotBlocks)); + migrations.add(new Migration("bank", "cost", bankCost)); + } + + private static double parseDouble(String string) { + try { + return Double.parseDouble(string); + } catch (NumberFormatException e) { + return 0.0D; + } + } + + public static void migrate() { + if (migrations.isEmpty()) + return; + + List> mapList = TownySettings.getConfig().getMapList("townblocktypes.types"); + + for (Migration migration : migrations) { + for (Map map : mapList) { + if (map.get("name").toString().equalsIgnoreCase(migration.type())) { + ((Map) map).put(migration.key(), migration.value()); + } + } + } + + TownySettings.getConfig().set("townblocktypes.types", mapList); + TownySettings.getConfig().save(); + migrations.clear(); + } + + @Desugar + private record Migration(String type, String key, Object value) {} + } } From 4aaefb3865cff262f956dd554f188e9dfbbce3d3 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 21 Oct 2021 23:50:07 +0200 Subject: [PATCH 08/28] Re-add inventory support --- resources/lang/en-US.yml | 2 +- .../bukkit/towny/command/TownyCommand.java | 15 ++-- .../listeners/TownyInventoryListener.java | 82 +++++++------------ .../bukkit/towny/object/TownBlock.java | 4 +- .../bukkit/towny/object/TownBlockData.java | 16 ++-- .../bukkit/towny/object/TownBlockType.java | 25 ++++-- .../towny/object/TownBlockTypeHandler.java | 35 +++++--- .../bukkit/towny/object/TownyInventory.java | 44 +++++++++- .../towny/object/gui/PermissionGUI.java | 30 +++++++ .../bukkit/towny/object/gui/SelectionGUI.java | 25 ++++++ .../bukkit/towny/utils/ResidentUtil.java | 45 +++++++++- src/com/palmergames/util/StringMgmt.java | 4 +- 12 files changed, 233 insertions(+), 94 deletions(-) create mode 100644 src/com/palmergames/bukkit/towny/object/gui/SelectionGUI.java diff --git a/resources/lang/en-US.yml b/resources/lang/en-US.yml index aeee29f9f7..e360a86922 100644 --- a/resources/lang/en-US.yml +++ b/resources/lang/en-US.yml @@ -1132,7 +1132,7 @@ msg_bankrupt: '&c(Bankrupt)' #Added in 0.98 msg_del_town2: '&bThe town of %s has been deleted!' msg_ruin_town: '&bThe town of %s fell into ruin!' -gui_title_towny_farmblocks: 'Towny FarmBlocks List' +gui_title_towny_allowedblocks: 'Towny AllowedBlocks List' gui_title_towny_wildsblocks: 'Towny WildsBlocks List' gui_title_towny_itemuse: 'Towny ItemUse List' gui_title_towny_switch: 'Towny Switch List' diff --git a/src/com/palmergames/bukkit/towny/command/TownyCommand.java b/src/com/palmergames/bukkit/towny/command/TownyCommand.java index 5810d9a799..d600495d4e 100644 --- a/src/com/palmergames/bukkit/towny/command/TownyCommand.java +++ b/src/com/palmergames/bukkit/towny/command/TownyCommand.java @@ -26,6 +26,7 @@ import com.palmergames.bukkit.towny.object.TownyObject; import com.palmergames.bukkit.towny.object.TownyWorld; import com.palmergames.bukkit.towny.object.Translation; +import com.palmergames.bukkit.towny.object.gui.SelectionGUI; import com.palmergames.bukkit.towny.permissions.PermissionNodes; import com.palmergames.bukkit.towny.permissions.TownyPermissionSource; import com.palmergames.bukkit.towny.utils.NameUtil; @@ -67,7 +68,7 @@ public class TownyCommand extends BaseCommand implements CommandExecutor { "v", "switches", "itemuse", - "farmblocks", + "allowedblocks", "wildsblocks", "plotclearblocks" ); @@ -232,19 +233,19 @@ else if (split.length > 1 && split[1].equalsIgnoreCase("hud")) for (String line : getTownyPrices(town, Translation.getLocale(player))) TownyMessaging.sendMessage(player, line); - /*} else if (split[0].equalsIgnoreCase("switches")) { + } else if (split[0].equalsIgnoreCase("switches")) { Resident resident = getResidentOrThrow(player.getUniqueId()); - ResidentUtil.openGUIInventory(resident, TownySettings.getSwitchMaterials(), Translatable.of("gui_title_towny_switch").forLocale(player)); + ResidentUtil.openSelectionGUI(resident, SelectionGUI.SelectionType.SWITCHES); } else if (split[0].equalsIgnoreCase("itemuse")) { Resident resident = getResidentOrThrow(player.getUniqueId()); - ResidentUtil.openGUIInventory(resident, TownySettings.getItemUseMaterials(), Translatable.of("gui_title_towny_itemuse").forLocale(player)); - } else if (split[0].equalsIgnoreCase("farmblocks")) { + ResidentUtil.openSelectionGUI(resident, SelectionGUI.SelectionType.ITEMUSE); + } else if (split[0].equalsIgnoreCase("allowedblocks")) { Resident resident = getResidentOrThrow(player.getUniqueId()); - ResidentUtil.openGUIInventory(resident, TownySettings.getFarmPlotBlocks(), Translatable.of("gui_title_towny_farmblocks").forLocale(player)); + ResidentUtil.openSelectionGUI(resident, SelectionGUI.SelectionType.ALLOWEDBLOCKS); } else if (split[0].equalsIgnoreCase("wildsblocks")) { Resident resident = getResidentOrThrow(player.getUniqueId()); ResidentUtil.openGUIInventory(resident, world.getUnclaimedZoneIgnoreMaterials(), Translatable.of("gui_title_towny_wildsblocks").forLocale(player)); - */} else if (split[0].equalsIgnoreCase("plotclearblocks")) { + } else if (split[0].equalsIgnoreCase("plotclearblocks")) { Resident resident = getResidentOrThrow(player.getUniqueId()); ResidentUtil.openGUIInventory(resident, world.getPlotManagementMayorDelete(), Translatable.of("gui_title_towny_plotclear").forLocale(player)); } else if (split[0].equalsIgnoreCase("top")) { diff --git a/src/com/palmergames/bukkit/towny/listeners/TownyInventoryListener.java b/src/com/palmergames/bukkit/towny/listeners/TownyInventoryListener.java index f8748fd0f2..daea9d1118 100644 --- a/src/com/palmergames/bukkit/towny/listeners/TownyInventoryListener.java +++ b/src/com/palmergames/bukkit/towny/listeners/TownyInventoryListener.java @@ -1,9 +1,13 @@ package com.palmergames.bukkit.towny.listeners; import com.palmergames.bukkit.towny.Towny; +import com.palmergames.bukkit.towny.object.TownBlockType; +import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import com.palmergames.bukkit.towny.object.gui.EditGUI; import com.palmergames.bukkit.towny.object.gui.PermissionGUI; +import com.palmergames.bukkit.towny.object.gui.SelectionGUI; import com.palmergames.bukkit.towny.utils.PermissionGUIUtil; +import com.palmergames.bukkit.towny.utils.ResidentUtil; import net.kyori.adventure.key.Key; import net.kyori.adventure.sound.Sound; import org.bukkit.ChatColor; @@ -18,6 +22,8 @@ import com.palmergames.bukkit.util.Colors; import org.bukkit.inventory.meta.ItemMeta; +import java.util.Set; + public class TownyInventoryListener implements Listener { Sound clickSound = Sound.sound(Key.key(Key.MINECRAFT_NAMESPACE, "block.stone_button.click_on"), Sound.Source.PLAYER, 1.0f, 1.0f); @@ -28,7 +34,7 @@ public TownyInventoryListener() { @EventHandler(ignoreCancelled = true) public void onClick(InventoryClickEvent event) { - if (!(event.getInventory().getHolder() instanceof TownyInventory) || event.getCurrentItem() == null) + if (!(event.getInventory().getHolder() instanceof TownyInventory townyInventory) || event.getCurrentItem() == null) return; event.setCancelled(true); @@ -39,13 +45,13 @@ public void onClick(InventoryClickEvent event) { if (resident == null || (event.getClickedInventory() != null && !(event.getClickedInventory().getHolder() instanceof TownyInventory))) return; - if (event.getInventory().getHolder() instanceof EditGUI) { + if (event.getInventory().getHolder() instanceof EditGUI editGUI) { ItemMeta meta = event.getCurrentItem().getItemMeta(); switch (event.getCurrentItem().getType()) { case LIME_WOOL: if (meta.getDisplayName().equals(Colors.LightGreen + ChatColor.BOLD + "Save")) { - ((EditGUI) event.getInventory().getHolder()).saveChanges(); + editGUI.saveChanges(); } else { meta.setDisplayName(Colors.Red + ChatColor.BOLD + Colors.strip(meta.getDisplayName())); event.getCurrentItem().setType(Material.RED_WOOL); @@ -53,9 +59,9 @@ public void onClick(InventoryClickEvent event) { break; case RED_WOOL: if (meta.getDisplayName().equals(Colors.Red + ChatColor.BOLD + "Back")) { - ((EditGUI) event.getInventory().getHolder()).exitScreen(); + editGUI.exitScreen(); } else if (meta.getDisplayName().equals(Colors.Red + ChatColor.BOLD + "Delete")) { - ((EditGUI) event.getInventory().getHolder()).deleteResident(); + editGUI.deleteResident(); } else { meta.setDisplayName(Colors.Gray + ChatColor.BOLD + Colors.strip(meta.getDisplayName())); event.getCurrentItem().setType(Material.GRAY_WOOL); @@ -70,7 +76,7 @@ public void onClick(InventoryClickEvent event) { } event.getCurrentItem().setItemMeta(meta); - Towny.getAdventure().player(player).playSound(clickSound); + editGUI.playClickSound(player); } else if (event.getInventory().getHolder() instanceof PermissionGUI permissionGUI) { if (event.getCurrentItem().getType() == Material.PLAYER_HEAD && permissionGUI.canEdit()) { @@ -82,58 +88,26 @@ public void onClick(InventoryClickEvent event) { PermissionGUIUtil.handleConversation(player); event.getWhoClicked().closeInventory(); } else { - int currentPage = resident.getGUIPageNum(); - - try { - // If the pressed item was a nextpage button - if (event.getCurrentItem().getItemMeta().getDisplayName().equals(Colors.Gold + "Next")) { - if (resident.getGUIPageNum() <= resident.getGUIPages().size() - 1) { - // Next page exists, flip the page - resident.setGUIPageNum(++currentPage); - new PermissionGUI(resident, resident.getGUIPage(), event.getView().getTitle(), permissionGUI.getTownBlock(), permissionGUI.canEdit()); - Towny.getAdventure().player(player).playSound(clickSound); - } - // if the pressed item was a previous page button - } else if (event.getCurrentItem().getItemMeta().getDisplayName().equals(Colors.Gold + "Back")) { - // If the page number is more than 0 (So a previous page exists) - if (resident.getGUIPageNum() > 0) { - // Flip to previous page - resident.setGUIPageNum(--currentPage); - new PermissionGUI(resident, resident.getGUIPage(), event.getView().getTitle(), permissionGUI.getTownBlock(), permissionGUI.canEdit()); - Towny.getAdventure().player(player).playSound(clickSound); - } - } - } catch (Exception ignored) {} + permissionGUI.tryPaginate(event.getCurrentItem(), player, resident, event.getView()); } + } else if (event.getInventory().getHolder() instanceof SelectionGUI selectionGUI) { + TownBlockType type = TownBlockTypeHandler.getType(Colors.strip(event.getCurrentItem().getItemMeta().getDisplayName())); + if (type == null) + player.closeInventory(); + + Set materialSet = switch (selectionGUI.getType()) { + case ITEMUSE -> type.getData().getItemUseIds(); + case ALLOWEDBLOCKS -> type.getData().getAllowedBlocks(); + case SWITCHES -> type.getData().getSwitchIds(); + }; + + selectionGUI.playClickSound(player); + ResidentUtil.openGUIInventory(resident, materialSet, event.getView().getTitle()); } else { /* - * Not a PermissionGUI or EditGUI, use normal pagination + * Not a PermissionGUI, EditGUI or SelectionGUI. Use normal pagination. */ - int currentPage = resident.getGUIPageNum(); - - try { - // If the pressed item was a nextpage button - if (event.getCurrentItem().getItemMeta().getDisplayName().equals(Colors.Gold + "Next")) { - // If there is no next page, don't do anything - if (resident.getGUIPageNum() >= resident.getGUIPages().size() - 1) { - return; - } else { - // Next page exists, flip the page - resident.setGUIPageNum(++currentPage); - new TownyInventory(resident, resident.getGUIPage(), event.getView().getTitle()); - Towny.getAdventure().player(player).playSound(clickSound); - } - // if the pressed item was a previous page button - } else if (event.getCurrentItem().getItemMeta().getDisplayName().equals(Colors.Gold + "Back")) { - // If the page number is more than 0 (So a previous page exists) - if (resident.getGUIPageNum() > 0) { - // Flip to previous page - resident.setGUIPageNum(--currentPage); - new TownyInventory(resident, resident.getGUIPage(), event.getView().getTitle()); - Towny.getAdventure().player(player).playSound(clickSound); - } - } - } catch (Exception ignored) {} + townyInventory.tryPaginate(event.getCurrentItem(), player, resident, event.getView()); } } } \ No newline at end of file diff --git a/src/com/palmergames/bukkit/towny/object/TownBlock.java b/src/com/palmergames/bukkit/towny/object/TownBlock.java index 41619f7c84..e06220116d 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlock.java @@ -271,8 +271,8 @@ public void setType(@NotNull String type) { setType(TownBlockTypeHandler.getType(type)); } - public void setType(@NotNull TownBlockType type) { - if (!TownBlockTypeHandler.exists(type.getName())) + public void setType(@Nullable TownBlockType type) { + if (type == null || !TownBlockTypeHandler.exists(type.getName())) type = TownBlockType.RESIDENTIAL; if (!type.equals(this.type)) diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockData.java b/src/com/palmergames/bukkit/towny/object/TownBlockData.java index 6aa6dca16f..70118a84e4 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockData.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockData.java @@ -3,16 +3,16 @@ import com.palmergames.bukkit.towny.TownySettings; import org.bukkit.Material; -import java.util.HashSet; -import java.util.Set; + import java.util.LinkedHashSet; + import java.util.Set; public class TownBlockData { private String mapKey = "+"; private double cost = 0.0; private double tax = 0.0; - private Set itemUseIds = new HashSet<>(); // List of item names that will trigger an item use test. - private Set switchIds = new HashSet<>(); // List of item names that will trigger a switch test. - private Set allowedBlocks = new HashSet<>(); // List of item names that will always be allowed. + private Set itemUseIds = new LinkedHashSet<>(); // List of item names that will trigger an item use test. + private Set switchIds = new LinkedHashSet<>(); // List of item names that will trigger a switch test. + private Set allowedBlocks = new LinkedHashSet<>(); // List of item names that will always be allowed. public String getMapKey() { return mapKey; @@ -53,15 +53,15 @@ public Set getAllowedBlocks() { } public void setItemUseIds(Set itemUseIds) { - this.itemUseIds = new HashSet<>(itemUseIds); + this.itemUseIds = new LinkedHashSet<>(itemUseIds); } public void setSwitchIds(Set switchIds) { - this.switchIds = new HashSet<>(switchIds); + this.switchIds = new LinkedHashSet<>(switchIds); } public void setAllowedBlocks(Set allowedBlocks) { - this.allowedBlocks = new HashSet<>(allowedBlocks); + this.allowedBlocks = new LinkedHashSet<>(allowedBlocks); } public void setTax(double tax) { diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index 7e5b36b449..490ebd334e 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -1,8 +1,6 @@ package com.palmergames.bukkit.towny.object; -import java.util.HashMap; -import java.util.Map; - +import com.palmergames.util.StringMgmt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -11,9 +9,19 @@ */ public class TownBlockType { public static final TownBlockType RESIDENTIAL = new TownBlockType("Default"); // The default Block Type. - public static final TownBlockType COMMERCIAL = new TownBlockType("Shop"); // Just like residential but has additional tax + public static final TownBlockType COMMERCIAL = new TownBlockType("Shop", new TownBlockData() { + @Override + public double getTax(Town town) { + return town.getCommercialPlotTax() + town.getPlotTax(); + } + }); // Just like residential but has additional tax public static final TownBlockType ARENA = new TownBlockType("Arena"); //Always PVP enabled. - public static final TownBlockType EMBASSY = new TownBlockType("Embassy"); // For other towns to own a plot in your town. + public static final TownBlockType EMBASSY = new TownBlockType("Embassy", new TownBlockData() { + @Override + public double getTax(Town town) { + return town.getEmbassyPlotTax() + town.getPlotTax(); + } + }); // For other towns to own a plot in your town. public static final TownBlockType WILDS = new TownBlockType("Wilds"); //Follows wilderness protection settings, but town owned. public static final TownBlockType INN = new TownBlockType("Inn"); //Allows use of beds outside your own plot. public static final TownBlockType JAIL = new TownBlockType("Jail"); //Enables setting the jail spawn. @@ -58,6 +66,10 @@ public double getCost() { public String getName() { return name; } + + public String getFormattedName() { + return StringMgmt.capitalize(this.name); + } /** * @deprecated As of 0.97.3.0 @@ -83,6 +95,9 @@ public TownBlockData getData() { @Override public boolean equals(Object other) { + if (this == other) + return true; + if (!(other instanceof TownBlockType townBlockType)) return false; diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index def10e7bba..dc87809e88 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -1,7 +1,6 @@ package com.palmergames.bukkit.towny.object; import com.github.bsideup.jabel.Desugar; -import com.google.common.primitives.Doubles; import com.palmergames.bukkit.config.CommentedConfiguration; import com.palmergames.bukkit.config.ConfigNodes; import com.palmergames.bukkit.towny.Towny; @@ -17,7 +16,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -57,6 +58,14 @@ public static void registerType(@NotNull TownBlockType type) throws TownyExcepti townBlockTypeMap.put(type.getName().toLowerCase(), type); } + /** + * Gets the currently registered townblock types. + * @return An unmodifiable map containing the types. + */ + public static Map getTypes() { + return Collections.unmodifiableMap(townBlockTypeMap); + } + /** * Gets the townblock instance for the name. * @param townBlockType The name of the town block type. @@ -83,8 +92,8 @@ private static void applyConfigSettings(Map newData) { try { name = String.valueOf(type.get("name")); - double cost = Double.parseDouble(type.get("cost").toString()); - double tax = Double.parseDouble(type.get("tax").toString()); + double cost = parseDouble(type.get("cost").toString()); + double tax = parseDouble(type.get("tax").toString()); String mapKey = String.valueOf(type.get("mapKey")); Set itemUseIds = loadMaterialList(String.valueOf(type.get("itemUseIds")), name); @@ -118,7 +127,7 @@ private static void applyConfigSettings(Map newData) { private static Set loadMaterialList(String materialList, String typeName) { if (!materialList.isEmpty()) { - Set set = new HashSet<>(); + Set set = new LinkedHashSet<>(); for (String materialName : materialList.split(",")) { Material material = Material.matchMaterial(materialName); @@ -130,7 +139,15 @@ private static Set loadMaterialList(String materialList, String typeNa return set; } else - return new HashSet<>(); + return new LinkedHashSet<>(); + } + + private static double parseDouble(String string) { + try { + return Double.parseDouble(string); + } catch (NumberFormatException e) { + return 0.0D; + } } private TownBlockTypeHandler() {} @@ -169,14 +186,6 @@ public static void checkForLegacyOptions() { migrations.add(new Migration("bank", "cost", bankCost)); } - private static double parseDouble(String string) { - try { - return Double.parseDouble(string); - } catch (NumberFormatException e) { - return 0.0D; - } - } - public static void migrate() { if (migrations.isEmpty()) return; diff --git a/src/com/palmergames/bukkit/towny/object/TownyInventory.java b/src/com/palmergames/bukkit/towny/object/TownyInventory.java index 7f75a1326a..702c28361f 100644 --- a/src/com/palmergames/bukkit/towny/object/TownyInventory.java +++ b/src/com/palmergames/bukkit/towny/object/TownyInventory.java @@ -1,10 +1,20 @@ package com.palmergames.bukkit.towny.object; +import com.palmergames.bukkit.towny.Towny; +import com.palmergames.bukkit.util.Colors; +import net.kyori.adventure.key.Key; +import net.kyori.adventure.sound.Sound; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; public class TownyInventory implements InventoryHolder { + + private static final Sound clickSound = Sound.sound(Key.key(Key.MINECRAFT_NAMESPACE, "block.stone_button.click_on"), Sound.Source.MASTER, 1.0f, 1.0f); private final Inventory inv; @@ -15,7 +25,39 @@ public TownyInventory(Resident res, Inventory inv, String name) { } @Override - public Inventory getInventory() { + public @NotNull Inventory getInventory() { return inv; } + + public void playClickSound(Player player) { + Towny.getAdventure().player(player).playSound(clickSound); + } + + public void tryPaginate(ItemStack clickedItem, Player player, Resident resident, InventoryView inventoryView) { + int currentPage = resident.getGUIPageNum(); + + try { + // If the pressed item was a nextpage button + if (clickedItem.getItemMeta().getDisplayName().equals(Colors.Gold + "Next")) { + // If there is no next page, don't do anything + if (resident.getGUIPageNum() >= resident.getGUIPages().size() - 1) { + return; + } else { + // Next page exists, flip the page + resident.setGUIPageNum(++currentPage); + new TownyInventory(resident, resident.getGUIPage(), inventoryView.getTitle()); + playClickSound(player); + } + // if the pressed item was a previous page button + } else if (clickedItem.getItemMeta().getDisplayName().equals(Colors.Gold + "Back")) { + // If the page number is more than 0 (So a previous page exists) + if (resident.getGUIPageNum() > 0) { + // Flip to previous page + resident.setGUIPageNum(--currentPage); + new TownyInventory(resident, resident.getGUIPage(), inventoryView.getTitle()); + playClickSound(player); + } + } + } catch (Exception ignored) {} + } } diff --git a/src/com/palmergames/bukkit/towny/object/gui/PermissionGUI.java b/src/com/palmergames/bukkit/towny/object/gui/PermissionGUI.java index 0722edaffd..81f43310a5 100644 --- a/src/com/palmergames/bukkit/towny/object/gui/PermissionGUI.java +++ b/src/com/palmergames/bukkit/towny/object/gui/PermissionGUI.java @@ -3,7 +3,11 @@ import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.TownBlock; import com.palmergames.bukkit.towny.object.TownyInventory; +import com.palmergames.bukkit.util.Colors; +import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.ItemStack; public class PermissionGUI extends TownyInventory { private final TownBlock townBlock; @@ -22,4 +26,30 @@ public TownBlock getTownBlock() { public boolean canEdit() { return canEdit; } + + @Override + public void tryPaginate(ItemStack clickedItem, Player player, Resident resident, InventoryView inventoryView) { + int currentPage = resident.getGUIPageNum(); + + try { + // If the pressed item was a nextpage button + if (clickedItem.getItemMeta().getDisplayName().equals(Colors.Gold + "Next")) { + if (resident.getGUIPageNum() <= resident.getGUIPages().size() - 1) { + // Next page exists, flip the page + resident.setGUIPageNum(++currentPage); + new PermissionGUI(resident, resident.getGUIPage(), inventoryView.getTitle(), townBlock, canEdit); + playClickSound(player); + } + // if the pressed item was a previous page button + } else if (clickedItem.getItemMeta().getDisplayName().equals(Colors.Gold + "Back")) { + // If the page number is more than 0 (So a previous page exists) + if (resident.getGUIPageNum() > 0) { + // Flip to previous page + resident.setGUIPageNum(--currentPage); + new PermissionGUI(resident, resident.getGUIPage(), inventoryView.getTitle(), townBlock, canEdit); + playClickSound(player); + } + } + } catch (Exception ignored) {} + } } diff --git a/src/com/palmergames/bukkit/towny/object/gui/SelectionGUI.java b/src/com/palmergames/bukkit/towny/object/gui/SelectionGUI.java new file mode 100644 index 0000000000..21282508c1 --- /dev/null +++ b/src/com/palmergames/bukkit/towny/object/gui/SelectionGUI.java @@ -0,0 +1,25 @@ +package com.palmergames.bukkit.towny.object.gui; + +import com.palmergames.bukkit.towny.object.Resident; +import com.palmergames.bukkit.towny.object.TownyInventory; +import org.bukkit.inventory.Inventory; + +/** + * A GUI used for selecting + */ +public class SelectionGUI extends TownyInventory { + private final SelectionType type; + + public SelectionGUI(Resident res, Inventory inv, String name, SelectionType type) { + super(res, inv, name); + this.type = type; + } + + public SelectionType getType() { + return type; + } + + public enum SelectionType { + SWITCHES, ALLOWEDBLOCKS, ITEMUSE + } +} diff --git a/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java b/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java index 7c4422f627..eecdae0c6a 100644 --- a/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java @@ -2,10 +2,14 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.UUID; +import com.palmergames.bukkit.towny.object.TownBlockType; +import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import com.palmergames.bukkit.towny.object.Translatable; +import com.palmergames.bukkit.towny.object.gui.SelectionGUI; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.command.CommandSender; @@ -110,6 +114,46 @@ public static void openGUIInventory(Resident resident, List list, String createTownyGUI(resident, items, name); } + public static void openGUIInventory(Resident resident, Set set, String name) { + ArrayList items = new ArrayList<>(); + for (Material material : set) + items.add(new ItemStack(material)); + + createTownyGUI(resident, items, name); + } + + public static void openSelectionGUI(Resident resident, SelectionGUI.SelectionType selectionType) { + String inventoryName = switch (selectionType) { + case ITEMUSE -> Translatable.of("gui_title_towny_itemuse").forLocale(resident); + case SWITCHES -> Translatable.of("gui_title_towny_switch").forLocale(resident); + case ALLOWEDBLOCKS -> Translatable.of("gui_title_towny_allowedblocks").forLocale(resident); + }; + + Inventory page = getBlankPage(inventoryName); + ArrayList pages = new ArrayList<>(); + + for (TownBlockType townBlockType : TownBlockTypeHandler.getTypes().values()) { + ItemStack item = new ItemStack(Material.GRASS_BLOCK); + + ItemMeta meta = item.getItemMeta(); + meta.setDisplayName(Colors.Gold + townBlockType.getFormattedName()); + item.setItemMeta(meta); + + if (page.firstEmpty() == 46) { + pages.add(page); + page = getBlankPage(inventoryName); + } + + page.addItem(item); + } + + pages.add(page); + resident.setGUIPageNum(0); + resident.setGUIPages(pages); + + new SelectionGUI(resident, pages.get(0), inventoryName, selectionType); + } + /* * Big credit goes to Hex_27 for the guidance following his ScrollerInventory * https://www.spigotmc.org/threads/infinite-inventory-with-pages.178964/ @@ -125,7 +169,6 @@ private static void createTownyGUI(Resident resident, ArrayList items if (page.firstEmpty() == 46) { pages.add(page); page = getBlankPage(name); - page.addItem(items.get(i)); } else { //Add the item to the current page as per normal page.addItem(items.get(i)); diff --git a/src/com/palmergames/util/StringMgmt.java b/src/com/palmergames/util/StringMgmt.java index 004b801eed..924e83c8af 100644 --- a/src/com/palmergames/util/StringMgmt.java +++ b/src/com/palmergames/util/StringMgmt.java @@ -188,11 +188,11 @@ public static String remUnderscore (String str) { return str.replaceAll("_", " "); } - public static String capitalize (String str) { + public static String capitalize(String str) { if (str == null || str.isEmpty()) return str; - return str.substring(0, 1).toUpperCase() + str.substring(1); + return str.substring(0, 1).toUpperCase() + str.substring(1); } /** From 0a0f6834ceeddf4d60f13377e519ed018b013fcd Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Fri, 22 Oct 2021 00:33:21 +0200 Subject: [PATCH 09/28] Add custom types to /plot set completions --- src/com/palmergames/bukkit/towny/TownySettings.java | 2 +- .../bukkit/towny/command/PlotCommand.java | 13 +++++++++++-- .../bukkit/towny/object/TownBlockTypeHandler.java | 5 +++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index af234c0b13..acec802308 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -740,7 +740,7 @@ private static void setTownBlockTypes() { addComment(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot(), "# Townblock types config", "# If empty, itemUseIds & switchIds will use values defined in protection.item_use_ids and protection.switch_ids.", - "# Allowed blocks are blocks that will always be allowed to be placed and broken in a plot.", + "# Defining allowedBlocks will make it so players with build or destroy permissions are only able to affect those blocks, see the farm type for an example.", "# If tax is set to 0, the towns' plot tax will be used instead." ); diff --git a/src/com/palmergames/bukkit/towny/command/PlotCommand.java b/src/com/palmergames/bukkit/towny/command/PlotCommand.java index 14580ff6cb..572748aeed 100644 --- a/src/com/palmergames/bukkit/towny/command/PlotCommand.java +++ b/src/com/palmergames/bukkit/towny/command/PlotCommand.java @@ -32,7 +32,6 @@ import com.palmergames.bukkit.towny.object.SpawnPointLocation; import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.TownBlock; -import com.palmergames.bukkit.towny.object.TownBlockData; import com.palmergames.bukkit.towny.object.TownBlockOwner; import com.palmergames.bukkit.towny.object.TownBlockType; import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; @@ -181,7 +180,7 @@ public List onTabComplete(CommandSender sender, Command command, String switch (args[0].toLowerCase()) { case "set": if (args.length == 2) { - return NameUtil.filterByStart(TownyCommandAddonAPI.getTabCompletes(CommandType.PLOT_SET, plotSetTabCompletes), args[1]); + return NameUtil.filterByStart(TownyCommandAddonAPI.getTabCompletes(CommandType.PLOT_SET, getPlotSetCompletions()), args[1]); } if (args.length > 2 && args[1].equalsIgnoreCase("perm")) { return permTabComplete(StringMgmt.remArgs(args, 2)); @@ -2247,4 +2246,14 @@ public void sendPlotInfo(Player player, String[] args) { else TownyMessaging.sendStatusScreen(player, TownyFormatter.getStatus(coord.getTownBlockOrNull(), player)); } + + private List getPlotSetCompletions() { + List completions = new ArrayList<>(plotSetTabCompletes); + + for (String townBlockType : TownBlockTypeHandler.getTypeNames()) + if (!completions.contains(townBlockType)) + completions.add(townBlockType); + + return completions; + } } diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index dc87809e88..3b3eed20a3 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -15,6 +15,7 @@ import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -65,6 +66,10 @@ public static void registerType(@NotNull TownBlockType type) throws TownyExcepti public static Map getTypes() { return Collections.unmodifiableMap(townBlockTypeMap); } + + public static List getTypeNames() { + return new ArrayList<>(townBlockTypeMap.keySet()); + } /** * Gets the townblock instance for the name. From 66bcf7b4a4855291ad16f24a9fda31c5510287c0 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Fri, 22 Oct 2021 12:50:56 +0200 Subject: [PATCH 10/28] Fix up registration event --- .../bukkit/towny/event/TownBlockTypeRegisterEvent.java | 2 +- .../bukkit/towny/object/TownBlockTypeHandler.java | 7 ++++--- .../palmergames/bukkit/towny/utils/PlayerCacheUtil.java | 2 -- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java b/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java index bb6ee2a32f..b5b35fc827 100644 --- a/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java +++ b/src/com/palmergames/bukkit/towny/event/TownBlockTypeRegisterEvent.java @@ -20,7 +20,7 @@ public TownBlockTypeRegisterEvent() { * @param type - The type * @throws TownyException - If a type with this name is already registered. */ - public static void registerType(@NotNull TownBlockType type) throws TownyException { + public void registerType(@NotNull TownBlockType type) throws TownyException { TownBlockTypeHandler.registerType(type); } diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index 3b3eed20a3..3b398c7fc9 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -40,11 +40,11 @@ public static void initialize() { applyConfigSettings(newData); - Bukkit.getPluginManager().callEvent(new TownBlockTypeRegisterEvent()); + townBlockTypeMap = newData; - Towny.getPlugin().getLogger().info(String.format("Loaded %d townblock types: %s", newData.size(), Arrays.toString(newData.keySet().toArray()))); + Bukkit.getPluginManager().callEvent(new TownBlockTypeRegisterEvent()); - townBlockTypeMap = newData; + Towny.getPlugin().getLogger().info(String.format("Loaded %d townblock types: %s", townBlockTypeMap.size(), Arrays.toString(townBlockTypeMap.keySet().toArray()))); } /** @@ -57,6 +57,7 @@ public static void registerType(@NotNull TownBlockType type) throws TownyExcepti throw new TownyException(String.format("A type named '%s' is already registered!", type.getName())); townBlockTypeMap.put(type.getName().toLowerCase(), type); + Towny.getPlugin().getLogger().info(String.format("A new townblock type was registered: %s", type.getName())); } /** diff --git a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java index e475c52901..f028e0a575 100644 --- a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java @@ -14,10 +14,8 @@ import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.TownBlock; -import com.palmergames.bukkit.towny.object.TownBlockType; import com.palmergames.bukkit.towny.object.TownyPermission; import com.palmergames.bukkit.towny.object.TownyPermission.ActionType; -import com.palmergames.bukkit.towny.object.TownyWorld; import com.palmergames.bukkit.towny.object.Translatable; import com.palmergames.bukkit.towny.object.WorldCoord; import com.palmergames.bukkit.towny.permissions.PermissionNodes; From 26929e712d9391009e795feb92c640bdccb1c925 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Fri, 22 Oct 2021 15:40:23 +0200 Subject: [PATCH 11/28] Fix item orders in GUIs --- src/com/palmergames/bukkit/towny/TownySettings.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index acec802308..70b0554390 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -40,6 +40,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; @@ -67,8 +68,8 @@ public enum NationLevel { private static final SortedMap> configTownLevel = Collections.synchronizedSortedMap(new TreeMap<>(Collections.reverseOrder())); private static final SortedMap> configNationLevel = Collections.synchronizedSortedMap(new TreeMap<>(Collections.reverseOrder())); - private static final Set itemUseMaterials = new HashSet<>(); - private static final Set switchUseMaterials = new HashSet<>(); + private static final Set itemUseMaterials = new LinkedHashSet<>(); + private static final Set switchUseMaterials = new LinkedHashSet<>(); private static final List> protectedMobs = new ArrayList<>(); public static void newTownLevel(int numResidents, String namePrefix, String namePostfix, String mayorPrefix, String mayorPostfix, int townBlockLimit, double townUpkeepMultiplier, int townOutpostLimit, int townBlockBuyBonusLimit, double debtCapModifier) { From 230e68a18b51c0391f21a7b8af481c528ad3a40d Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 28 Oct 2021 21:31:10 +0200 Subject: [PATCH 12/28] Fix up converting from old dbs --- .../bukkit/towny/db/TownyFlatFileSource.java | 1 + .../bukkit/towny/db/TownySQLSource.java | 1 + .../bukkit/towny/object/TownBlock.java | 2 +- .../bukkit/towny/object/TownBlockData.java | 2 +- .../bukkit/towny/object/TownBlockType.java | 21 +++++++++++++++++-- .../towny/object/TownBlockTypeHandler.java | 2 +- 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java b/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java index b8f6363343..3ce77ec92c 100644 --- a/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java +++ b/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java @@ -1626,6 +1626,7 @@ else if (universe.getReplacementNameMap().containsKey(line.trim())) line = keys.get("type"); if (line != null) try { + //noinspection deprecation townBlock.setType(Integer.parseInt(line)); } catch (Exception e) { townBlock.setType(line); diff --git a/src/com/palmergames/bukkit/towny/db/TownySQLSource.java b/src/com/palmergames/bukkit/towny/db/TownySQLSource.java index 88ea24c2bf..3b0abc77f2 100644 --- a/src/com/palmergames/bukkit/towny/db/TownySQLSource.java +++ b/src/com/palmergames/bukkit/towny/db/TownySQLSource.java @@ -1792,6 +1792,7 @@ public boolean loadTownBlocks() { line = rs.getString("type"); if (line != null) try { + //noinspection deprecation townBlock.setType(Integer.parseInt(line)); } catch (Exception e) { townBlock.setType(line); diff --git a/src/com/palmergames/bukkit/towny/object/TownBlock.java b/src/com/palmergames/bukkit/towny/object/TownBlock.java index e06220116d..c9cc8fe115 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlock.java @@ -319,7 +319,7 @@ public void setType(@Nullable TownBlockType type) { */ @Deprecated public void setType(int typeId) { - + setType(TownBlockType.lookup(typeId)); } /** diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockData.java b/src/com/palmergames/bukkit/towny/object/TownBlockData.java index 70118a84e4..40fe85cf7d 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockData.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockData.java @@ -19,7 +19,7 @@ public String getMapKey() { } public void setMapKey(String mapKey) { - this.mapKey = mapKey; + this.mapKey = mapKey.substring(0, 1); } public double getCost() { diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index 490ebd334e..eed7adf486 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -4,6 +4,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; +import java.util.Map; + /** * @author dumptruckman */ @@ -70,14 +73,28 @@ public String getName() { public String getFormattedName() { return StringMgmt.capitalize(this.name); } + + private static final Map legacyLookupMap = new HashMap<>(); + + static { + legacyLookupMap.put(0, "default"); + legacyLookupMap.put(1, "shop"); + legacyLookupMap.put(2, "arena"); + legacyLookupMap.put(3, "embassy"); + legacyLookupMap.put(4, "wilds"); + legacyLookupMap.put(6, "inn"); + legacyLookupMap.put(7, "jail"); + legacyLookupMap.put(8, "farm"); + legacyLookupMap.put(9, "bank"); + } /** - * @deprecated As of 0.97.3.0 + * @deprecated As of 0.97.3.0, please use {@link TownBlockTypeHandler#getType(String)} instead. */ @Nullable @Deprecated public static TownBlockType lookup(int id) { - return null; + return TownBlockTypeHandler.getType(legacyLookupMap.getOrDefault(id, "default")); } /** diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index 3b398c7fc9..05b68b0ade 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -31,7 +31,7 @@ public final class TownBlockTypeHandler { public static void initialize() { Map newData = new ConcurrentHashMap<>(); - for (Field field : TownBlockType.class.getFields()) { + for (Field field : TownBlockType.class.getFields()) { try { TownBlockType type = (TownBlockType) field.get(null); newData.put(type.getName().toLowerCase(), type); From db1e5d1e9546b9a4fe2aa10d8ec2176319c0cc67 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 2 Dec 2021 17:16:37 +0100 Subject: [PATCH 13/28] Fix compile --- src/com/palmergames/bukkit/towny/command/PlotCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/palmergames/bukkit/towny/command/PlotCommand.java b/src/com/palmergames/bukkit/towny/command/PlotCommand.java index 572748aeed..fdf1c8709c 100644 --- a/src/com/palmergames/bukkit/towny/command/PlotCommand.java +++ b/src/com/palmergames/bukkit/towny/command/PlotCommand.java @@ -700,7 +700,7 @@ public boolean parsePlotCommand(Player player, String[] split) { return false; } - if (TownBlockType.ARENA.equals(townBlockType) && TownySettings.getOutsidersPreventPVPToggle()) { + if (TownBlockType.ARENA.equals(type) && TownySettings.getOutsidersPreventPVPToggle()) { for (Player target : Bukkit.getOnlinePlayers()) { if (!townBlock.getTownOrNull().hasResident(target) && !player.getName().equals(target.getName()) && townBlock.getWorldCoord().equals(WorldCoord.parseWorldCoord(target))) throw new TownyException(Translatable.of("msg_cant_toggle_pvp_outsider_in_plot")); From 10423de2fe99e23a3315bd72ba83b30e9a642dcb Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 2 Dec 2021 18:11:34 +0100 Subject: [PATCH 14/28] Fix towny gui regression Fixes items not being added to the page if one was newly created. --- .../palmergames/bukkit/towny/utils/ResidentUtil.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java b/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java index eecdae0c6a..0e72022d02 100644 --- a/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java @@ -163,17 +163,17 @@ public static void openSelectionGUI(Resident resident, SelectionGUI.SelectionTyp private static void createTownyGUI(Resident resident, ArrayList items, String name) { Inventory page = getBlankPage(name); - ArrayList pages = new ArrayList(); + ArrayList pages = new ArrayList<>(); - for (int i = 0; i < items.size(); i++) { + for (ItemStack item : items) { if (page.firstEmpty() == 46) { pages.add(page); page = getBlankPage(name); - } else { - //Add the item to the current page as per normal - page.addItem(items.get(i)); } + + page.addItem(item); } + pages.add(page); resident.setGUIPages(pages); resident.setGUIPageNum(0); From eb3f85ba58c9c712da7389b0e76b53dc348c0713 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Thu, 2 Dec 2021 22:47:38 +0100 Subject: [PATCH 15/28] Fix wilds plots not working as intended --- src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java index f028e0a575..1c2c49bbcc 100644 --- a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java @@ -14,6 +14,7 @@ import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.TownBlock; +import com.palmergames.bukkit.towny.object.TownBlockType; import com.palmergames.bukkit.towny.object.TownyPermission; import com.palmergames.bukkit.towny.object.TownyPermission.ActionType; import com.palmergames.bukkit.towny.object.Translatable; @@ -579,6 +580,9 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl * @return True if this material is allowed in this townblock. */ private static boolean isAllowedMaterial(TownBlock townBlock, Material material, ActionType action) { + if (townBlock.getType() == TownBlockType.WILDS) + return TownyUniverse.getInstance().getPermissionSource().unclaimedZoneAction(townBlock.getWorld(), material, action); + if ((action == ActionType.BUILD || action == ActionType.DESTROY) && !townBlock.getData().getAllowedBlocks().isEmpty()) return townBlock.getData().getAllowedBlocks().contains(material); From 24596a1716fb4280f4a3f27ecb1eb1182729b0a0 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Fri, 3 Dec 2021 22:01:24 +0100 Subject: [PATCH 16/28] Fix migrator NPE --- src/com/palmergames/bukkit/towny/object/TownBlockType.java | 4 ++-- .../palmergames/bukkit/towny/object/TownBlockTypeHandler.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index eed7adf486..47ae164d20 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -89,7 +89,7 @@ public String getFormattedName() { } /** - * @deprecated As of 0.97.3.0, please use {@link TownBlockTypeHandler#getType(String)} instead. + * @deprecated As of 0.97.5.0, please use {@link TownBlockTypeHandler#getType(String)} instead. */ @Nullable @Deprecated @@ -98,7 +98,7 @@ public static TownBlockType lookup(int id) { } /** - * @deprecated As of 0.97.3.0, please use {@link TownBlockTypeHandler#getType(String)} instead. + * @deprecated As of 0.97.5.0, please use {@link TownBlockTypeHandler#getType(String)} instead. */ @Nullable @Deprecated diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index 05b68b0ade..cccc717bb8 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -151,7 +151,7 @@ private static Set loadMaterialList(String materialList, String typeNa private static double parseDouble(String string) { try { return Double.parseDouble(string); - } catch (NumberFormatException e) { + } catch (NumberFormatException | NullPointerException e) { return 0.0D; } } From db3f02723b5f41fff5c40fd42ee53205f5a93667 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sat, 4 Dec 2021 22:39:54 +0100 Subject: [PATCH 17/28] Add embassy to config --- src/com/palmergames/bukkit/towny/TownySettings.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index 70b0554390..97f53c85da 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -778,6 +778,16 @@ private static void setTownBlockTypes() { type.put("allowedBlocks", ""); types.add(new LinkedHashMap<>(type)); type.clear(); + + type.put("name", "embassy"); + type.put("cost", 0.0); + type.put("tax", 0.0); + type.put("mapKey", "E"); + type.put("itemUseIds", ""); + type.put("switchIds", ""); + type.put("allowedBlocks", ""); + types.add(new LinkedHashMap<>(type)); + type.clear(); type.put("name", "wilds"); type.put("cost", 0.0); From 00e48e96fdbda63a347759fd69a5117af3e01861 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sun, 5 Dec 2021 23:20:16 +0100 Subject: [PATCH 18/28] Fix tax collection in the DailyTimerTask --- .../bukkit/towny/tasks/DailyTimerTask.java | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java index 3a7ff4cc72..8a00e106bd 100644 --- a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java +++ b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java @@ -375,44 +375,40 @@ protected void collectTownTaxes(Town town) { Resident resident = townBlock.getResidentOrNull(); - /* - * Only collect plot tax from this resident if it really - * still exists. We are running in an Async thread so MUST - * verify all objects. - */ - if (universe.hasResident(resident.getName())) { - if (resident.hasTown() && resident.getTownOrNull() == town) - if (TownyPerms.getResidentPerms(resident).containsKey("towny.tax_exempt") || resident.isNPC()) - continue; - - double tax = townBlock.getType().getTax(town); - if (tax < 1) + /* + * Only collect plot tax from this resident if it really + * still exists. We are running in an Async thread so MUST + * verify all objects. + */ + if (universe.hasResident(resident.getName())) { + if (resident.hasTown() && resident.getTownOrNull() == town) + if (TownyPerms.getResidentPerms(resident).containsKey("towny.tax_exempt") || resident.isNPC()) continue; - // If the tax would put the town over the bank cap we reduce what will be - // paid by the plot owner to what will be allowed. - if (TownySettings.getTownBankCap() != 0 && tax + town.getAccount().getHoldingBalance() > TownySettings.getTownBankCap()) - tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); - - if (!resident.getAccount().payTo(tax, town, String.format("Plot Tax (%s)", townBlock.getType()))) { - if (!lostPlots.contains(resident.getName())) - lostPlots.add(resident.getName()); + // If the tax would put the town over the bank cap we reduce what will be + // paid by the plot owner to what will be allowed. + if (TownySettings.getTownBankCap() != 0 && tax + town.getAccount().getHoldingBalance() > TownySettings.getTownBankCap()) + tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); - townBlock.setResident(null); - - // Set the plot price. - if (TownySettings.doesPlotTaxNonPaymentSetPlotForSale()) - townBlock.setPlotPrice(town.getPlotTypePrice(townBlock.getType())); - else - townBlock.setPlotPrice(-1); - - // Set the plot permissions to mirror the towns. - townBlock.setType(townBlock.getType()); - - townBlock.save(); - } + if (!resident.getAccount().payTo(tax, town, String.format("Plot Tax (%s)", townBlock.getType()))) { + if (!lostPlots.contains(resident.getName())) + lostPlots.add(resident.getName()); + + townBlock.setResident(null); + + // Set the plot price. + if (TownySettings.doesPlotTaxNonPaymentSetPlotForSale()) + townBlock.setPlotPrice(town.getPlotTypePrice(townBlock.getType())); + else + townBlock.setPlotPrice(-1); + + // Set the plot permissions to mirror the towns. + townBlock.setType(townBlock.getType()); + + townBlock.save(); } } + } if (lostPlots != null && !lostPlots.isEmpty()) { if (lostPlots.size() == 1) From 2896b5a2855f4240b0023a259dd20bf0921ca4f6 Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Sat, 18 Dec 2021 12:17:25 -0600 Subject: [PATCH 19/28] Replaces Towny's own usages of the deprecated getType() methods. --- .../palmergames/bukkit/towny/db/TownyFlatFileSource.java | 7 +------ src/com/palmergames/bukkit/towny/db/TownySQLSource.java | 7 +------ src/com/palmergames/bukkit/towny/object/TownBlock.java | 2 ++ .../palmergames/bukkit/towny/object/TownBlockType.java | 7 +++++++ .../bukkit/towny/object/TownBlockTypeHandler.java | 9 +++++++++ src/com/palmergames/bukkit/towny/utils/TownRuinUtil.java | 2 +- 6 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java b/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java index 3ce77ec92c..248f93f705 100644 --- a/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java +++ b/src/com/palmergames/bukkit/towny/db/TownyFlatFileSource.java @@ -1625,12 +1625,7 @@ else if (universe.getReplacementNameMap().containsKey(line.trim())) line = keys.get("type"); if (line != null) - try { - //noinspection deprecation - townBlock.setType(Integer.parseInt(line)); - } catch (Exception e) { - townBlock.setType(line); - } + townBlock.setType(TownBlockTypeHandler.getTypeInternal(line)); line = keys.get("outpost"); if (line != null) diff --git a/src/com/palmergames/bukkit/towny/db/TownySQLSource.java b/src/com/palmergames/bukkit/towny/db/TownySQLSource.java index 3b0abc77f2..ebb8941efb 100644 --- a/src/com/palmergames/bukkit/towny/db/TownySQLSource.java +++ b/src/com/palmergames/bukkit/towny/db/TownySQLSource.java @@ -1791,12 +1791,7 @@ public boolean loadTownBlocks() { line = rs.getString("type"); if (line != null) - try { - //noinspection deprecation - townBlock.setType(Integer.parseInt(line)); - } catch (Exception e) { - townBlock.setType(line); - } + townBlock.setType(TownBlockTypeHandler.getTypeInternal(line)); boolean outpost = rs.getBoolean("outpost"); if (line != null && !line.isEmpty()) diff --git a/src/com/palmergames/bukkit/towny/object/TownBlock.java b/src/com/palmergames/bukkit/towny/object/TownBlock.java index c9cc8fe115..0a3fb8b549 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlock.java @@ -305,6 +305,8 @@ public void setType(@Nullable TownBlockType type) { case "wilds": setPermissions("residentBuild,residentDestroy"); break; + default: + break; } // Set the changed status. diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index 47ae164d20..4388f23ba8 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -76,6 +76,13 @@ public String getFormattedName() { private static final Map legacyLookupMap = new HashMap<>(); + /** + * @return the legacylookupmap + */ + public static Map getLegacylookupmap() { + return legacyLookupMap; + } + static { legacyLookupMap.put(0, "default"); legacyLookupMap.put(1, "shop"); diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index cccc717bb8..91d1ce7865 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -82,6 +82,15 @@ public static TownBlockType getType(@NotNull String townBlockType) { return townBlockTypeMap.get(townBlockType.toLowerCase()); } + public static TownBlockType getTypeInternal(@NotNull String input) { + try { + int id = Integer.parseInt(input); + return getType(TownBlockType.getLegacylookupmap().getOrDefault(id, "default")); + } catch (NumberFormatException e) { + return getType(input); + } + } + /** * @param typeName The name of the type to test for. * @return Whether a type with the specified name exists. diff --git a/src/com/palmergames/bukkit/towny/utils/TownRuinUtil.java b/src/com/palmergames/bukkit/towny/utils/TownRuinUtil.java index c551ca7207..cfc9c2db28 100644 --- a/src/com/palmergames/bukkit/towny/utils/TownRuinUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/TownRuinUtil.java @@ -102,7 +102,7 @@ public static void putTownIntoRuinedState(Town town, Towny plugin) { for(TownBlock townBlock: town.getTownBlocks()) { if (townBlock.hasResident()) townBlock.setResident(null); // Removes any personal ownership. - townBlock.setType(0); // Sets the townblock's perm line to the Town's perm line set above. + townBlock.setType("default"); // Sets the townblock's perm line to the Town's perm line set above. townBlock.setPlotPrice(-1); // Makes the plot not for sale. townBlock.removePlotObjectGroup(); // Removes plotgroup if it were present. townBlock.getPermissionOverrides().clear(); // Removes all permission overrides from the plot. From fe13680aaffe76a5a42877612c6cd638ffc83a86 Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Sat, 18 Dec 2021 15:10:40 -0600 Subject: [PATCH 20/28] Fix Config section creating in wrong place. Moves it to just above the jail plot section. Moves comments into the config section header, add more explanations. --- .../bukkit/config/ConfigNodes.java | 50 ++++++++++++++----- .../bukkit/towny/TownySettings.java | 14 ++---- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/com/palmergames/bukkit/config/ConfigNodes.java b/src/com/palmergames/bukkit/config/ConfigNodes.java index c5cdc6e489..4b3c548271 100644 --- a/src/com/palmergames/bukkit/config/ConfigNodes.java +++ b/src/com/palmergames/bukkit/config/ConfigNodes.java @@ -1398,18 +1398,6 @@ public enum ConfigNodes { "false", "", "# When set to true, players with the Frost Walker enchant will need to be able to build where they are attempting to freeze."), - TOWNBLOCKTYPES( - "townblocktypes", - "", - "", - "", - "############################################################", - "# +------------------------------------------------------+ #", - "# | Town Block Types | #", - "# +------------------------------------------------------+ #", - "############################################################", - ""), - TOWNBLOCKTYPES_TYPES("townblocktypes.types", ""), UNCLAIMED_ZONE( "unclaimed", "", @@ -2245,7 +2233,43 @@ public enum ConfigNodes { "", "# This allows you to modify the style displayed via bankhistory commands." ), - + TOWNBLOCKTYPES( + "townblocktypes", + "", + "", + "", + "############################################################", + "# +------------------------------------------------------+ #", + "# | Town Block Types | #", + "# | | #", + "# | You may add your own custom townblocks to this | #", + "# | section of the config. Removing the townblocks | #", + "# | supplied by Towny from this configuration is not | #", + "# | recommended. | #", + "# | | #", + "# | name: The name used for this townblock, in-game and | #", + "# | in the database. | #", + "# | cost: Cost a player pays to set a townblock to the | #", + "# | type. If tax is set to 0, the towns' plot tax will| #", + "# | be used instead. | #", + "# | tax: The amount a player has to pay city each day to | #", + "# | continue owning the plot. | #", + "# | mapKey: The character that shows on the //towny map | #", + "# | commands. | #", + "# | itemUseIds: If empty, will use values defined in | #", + "# | protection.item_use_ids. If not empty this defines| #", + "# | what items are considered item_use. | #", + "# | switchIds: If empty, will use values defined in | #", + "# | protection.switch_ids. If not empty this defines | #", + "# | what blocks are considered switches in the type. | #", + "# | allowedBlocks: will make it so players with build or | #", + "# | destroy permissions are only able to affect those | #", + "# | blocks, see the farm type for an example. | #", + "# | | #", + "# +------------------------------------------------------+ #", + "############################################################", + ""), + TOWNBLOCKTYPES_TYPES("townblocktypes.types", ""), JAIL( "jail", "", diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index 97f53c85da..01c67393ea 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -513,9 +513,10 @@ private static void setDefaults(String version, Path configPath) { setNewProperty(root.getRoot(), version); } else if (root.getRoot().equals(ConfigNodes.LAST_RUN_VERSION.getRoot())) { setNewProperty(root.getRoot(), getLastRunVersion(version)); - } else if (root.getRoot().equals(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot())) + } else if (root.getRoot().equals(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot())) { + setNewProperty(root.getRoot(), root.getDefault()); setTownBlockTypes(); - else + } else setNewProperty(root.getRoot(), (config.get(root.getRoot().toLowerCase()) != null) ? config.get(root.getRoot().toLowerCase()) : root.getDefault()); } @@ -738,14 +739,8 @@ private static void setDefaultLevels() { } private static void setTownBlockTypes() { - addComment(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot(), - "# Townblock types config", - "# If empty, itemUseIds & switchIds will use values defined in protection.item_use_ids and protection.switch_ids.", - "# Defining allowedBlocks will make it so players with build or destroy permissions are only able to affect those blocks, see the farm type for an example.", - "# If tax is set to 0, the towns' plot tax will be used instead." - ); - if (!config.contains(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot())) { + // The TownBlockTypes section does not exist yet. List> types = new ArrayList<>(); Map type = new LinkedHashMap<>(); @@ -840,6 +835,7 @@ private static void setTownBlockTypes() { type.clear(); newConfig.set(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot(), types); } else + // The TownBlockTypes section exists, use the existing config's values. newConfig.set(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot(), config.get(ConfigNodes.TOWNBLOCKTYPES_TYPES.getRoot())); } From 0e6ac7d9f7ad2a3048d0edb5ec5c0ce02e9790ab Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Sat, 18 Dec 2021 18:48:16 -0600 Subject: [PATCH 21/28] Cleanup on custom_types branch. Mainly comments and javadocs, but also undoing a variable change in PlotCommand. --- src/com/palmergames/bukkit/towny/Towny.java | 12 +++++++++- .../bukkit/towny/TownySettings.java | 4 ++++ .../bukkit/towny/command/PlotCommand.java | 24 +++++++++---------- .../bukkit/towny/object/TownBlock.java | 6 ++--- .../bukkit/towny/object/TownBlockType.java | 14 +++++++---- .../bukkit/towny/utils/PlayerCacheUtil.java | 12 +++++----- 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/Towny.java b/src/com/palmergames/bukkit/towny/Towny.java index a55bdeb03f..60be52d0b9 100644 --- a/src/com/palmergames/bukkit/towny/Towny.java +++ b/src/com/palmergames/bukkit/towny/Towny.java @@ -232,7 +232,8 @@ public void loadFoundation(boolean reload) { // Before anything can continue we must load the databaseconfig, config // file, language and permissions, setting the foundation for Towny. - TownBlockTypeHandler.Migrator.checkForLegacyOptions(); + // Handle any legacy config settings. + handleLegacyConfigs(); // Load the database config first, so any conversion happens before the config is loaded. loadDatabaseConfig(reload); @@ -338,6 +339,15 @@ private void loadTownAndNationLevels() { } } + /** + * Handle any legacy config settings before we load the config and database. + */ + private void handleLegacyConfigs() { + // Old configs stored various TownBlock settings throughout the config. + // This will migrate the old settings into the TownBlockType config section. + TownBlockTypeHandler.Migrator.checkForLegacyOptions(); + } + /** * Converts the older config.yml's database settings into the database.yml file. * @return true if successful diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index 01c67393ea..e0b02a90d8 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -2676,6 +2676,10 @@ public static double getNationRequiresProximity() { return getDouble(ConfigNodes.GTOWN_SETTINGS_NATION_REQUIRES_PROXIMITY); } + /** + * @deprecated since 0.97.5.3 + * @return Collections.emptyList() + */ @Deprecated public static List getFarmPlotBlocks() { return Collections.emptyList(); diff --git a/src/com/palmergames/bukkit/towny/command/PlotCommand.java b/src/com/palmergames/bukkit/towny/command/PlotCommand.java index fdf1c8709c..f2eb8acdec 100644 --- a/src/com/palmergames/bukkit/towny/command/PlotCommand.java +++ b/src/com/palmergames/bukkit/towny/command/PlotCommand.java @@ -685,9 +685,9 @@ public boolean parsePlotCommand(Player player, String[] split) { if (plotTypeName.equalsIgnoreCase("reset")) plotTypeName = "default"; - TownBlockType type = TownBlockTypeHandler.getType(plotTypeName); + TownBlockType townBlockType = TownBlockTypeHandler.getType(plotTypeName); - if (type == null) + if (townBlockType == null) throw new TownyException(Translatable.of("msg_err_not_block_type")); try { @@ -700,14 +700,14 @@ public boolean parsePlotCommand(Player player, String[] split) { return false; } - if (TownBlockType.ARENA.equals(type) && TownySettings.getOutsidersPreventPVPToggle()) { + if (TownBlockType.ARENA.equals(townBlockType) && TownySettings.getOutsidersPreventPVPToggle()) { for (Player target : Bukkit.getOnlinePlayers()) { if (!townBlock.getTownOrNull().hasResident(target) && !player.getName().equals(target.getName()) && townBlock.getWorldCoord().equals(WorldCoord.parseWorldCoord(target))) throw new TownyException(Translatable.of("msg_cant_toggle_pvp_outsider_in_plot")); } } - PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(type, townBlock, resident); + PlotPreChangeTypeEvent preEvent = new PlotPreChangeTypeEvent(townBlockType, townBlock, resident); BukkitTools.getPluginManager().callEvent(preEvent); if (preEvent.isCancelled()) { @@ -715,38 +715,38 @@ public boolean parsePlotCommand(Player player, String[] split) { return false; } - double cost = type.getData().getCost(); + double cost = townBlockType.getData().getCost(); // Test if we can pay first to throw an exception. if (cost > 0 && TownyEconomyHandler.isActive() && !resident.getAccount().canPayFromHoldings(cost)) - throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", type, TownyEconomyHandler.getFormattedBalance(cost))); + throw new TownyException(Translatable.of("msg_err_cannot_afford_plot_set_type_cost", townBlockType, TownyEconomyHandler.getFormattedBalance(cost))); // Handle payment via a confirmation to avoid suprise costs. if (cost > 0 && TownyEconomyHandler.isActive()) { Confirmation.runOnAccept(() -> { - if (!resident.getAccount().withdraw(cost, String.format("Plot set to %s", type))) { - TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", type, TownyEconomyHandler.getFormattedBalance(cost))); + if (!resident.getAccount().withdraw(cost, String.format("Plot set to %s", townBlockType))) { + TownyMessaging.sendErrorMsg(player, Translatable.of("msg_err_cannot_afford_plot_set_type_cost", townBlockType, TownyEconomyHandler.getFormattedBalance(cost))); return; } - TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), type)); + TownyMessaging.sendMsg(resident, Translatable.of("msg_plot_set_cost", TownyEconomyHandler.getFormattedBalance(cost), townBlockType)); try { - townBlock.setType(type, resident); + townBlock.setType(townBlockType, resident); } catch (TownyException e) { TownyMessaging.sendErrorMsg(resident, e.getMessage(player)); return; } - TownyMessaging.sendMsg(player, Translatable.of("msg_plot_set_type", type)); + TownyMessaging.sendMsg(player, Translatable.of("msg_plot_set_type", townBlockType)); }) .setTitle(Translatable.of("msg_confirm_purchase", TownyEconomyHandler.getFormattedBalance(cost))) .sendTo(BukkitTools.getPlayerExact(resident.getName())); // No cost or economy so no confirmation. } else { - townBlock.setType(type, resident); + townBlock.setType(townBlockType, resident); TownyMessaging.sendMsg(player, Translatable.of("msg_plot_set_type", plotTypeName)); } } catch (TownyException te){ diff --git a/src/com/palmergames/bukkit/towny/object/TownBlock.java b/src/com/palmergames/bukkit/towny/object/TownBlock.java index 0a3fb8b549..1b70c4bacf 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlock.java @@ -316,7 +316,7 @@ public void setType(@Nullable TownBlockType type) { /** * Sets the type of this townblock to the specified ID. * @param typeId The id of the type - * @deprecated As of 0.97.3.0, this is deprecated for compatibility with custom types. + * @deprecated As of 0.97.5.3, this is deprecated for compatibility with custom types. * @see #setType(String) */ @Deprecated @@ -325,8 +325,8 @@ public void setType(int typeId) { } /** - * @param type The name of the type set this plot to. - * @param resident The resident who is trying to set the type. + * @param type The TownBlockType to set this plot to. + * @param resident The Resident who is trying to set the type. * @throws TownyException If this townblock has a pvp toggle cooldown. */ public void setType(TownBlockType type, Resident resident) throws TownyException { diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index 4388f23ba8..a000ebdbb0 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -25,10 +25,10 @@ public double getTax(Town town) { return town.getEmbassyPlotTax() + town.getPlotTax(); } }); // For other towns to own a plot in your town. - public static final TownBlockType WILDS = new TownBlockType("Wilds"); //Follows wilderness protection settings, but town owned. - public static final TownBlockType INN = new TownBlockType("Inn"); //Allows use of beds outside your own plot. + public static final TownBlockType WILDS = new TownBlockType("Wilds"); //Limits build/destroy-able blocks to the world's unclaimedZoneIgnoreIDs. + public static final TownBlockType INN = new TownBlockType("Inn"); //Allows use of beds outside your own plot, when deny_bed_use is true. public static final TownBlockType JAIL = new TownBlockType("Jail"); //Enables setting the jail spawn. - public static final TownBlockType FARM = new TownBlockType("Farm"); //Follows wilderness protection settings, but town owned. + public static final TownBlockType FARM = new TownBlockType("Farm"); //Limits build/destroy-able blocks to the farm plot block list. public static final TownBlockType BANK = new TownBlockType("Bank"); // Enables depositing into town and nation banks, if that has been enabled in the config. private final String name; @@ -53,6 +53,10 @@ public double getTax(Town town) { return data.getTax(town); } + /** + * @deprecated since 0.97.5.3. + * @return 0. + */ @Deprecated public int getId() { return 0; @@ -96,7 +100,7 @@ public static Map getLegacylookupmap() { } /** - * @deprecated As of 0.97.5.0, please use {@link TownBlockTypeHandler#getType(String)} instead. + * @deprecated As of 0.97.5.3, please use {@link TownBlockTypeHandler#getType(String)} instead. */ @Nullable @Deprecated @@ -105,7 +109,7 @@ public static TownBlockType lookup(int id) { } /** - * @deprecated As of 0.97.5.0, please use {@link TownBlockTypeHandler#getType(String)} instead. + * @deprecated As of 0.97.5.3, please use {@link TownBlockTypeHandler#getType(String)} instead. */ @Nullable @Deprecated diff --git a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java index 1c2c49bbcc..f030c55163 100644 --- a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java @@ -494,7 +494,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl */ if (status == TownBlockStatus.PLOT_FRIEND) { - // Plot allows Friends perms and we aren't stopped by Wilds or Farm Plot overrides. + // Plot allows Friends perms and we aren't stopped by a TownBlockType overriding the allowed material and action. if (townBlock.getPermissions().getResidentPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; @@ -504,7 +504,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.PLOT_TOWN) { - // Plot allows Town perms + // Plot allows Town perms and we aren't stopped by a TownBlockType overriding the allowed material and action. if (townBlock.getPermissions().getNationPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; @@ -517,7 +517,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl */ if (status == TownBlockStatus.TOWN_RESIDENT) { - // Plot allows Resident perms + // Plot allows Resident perms and we aren't stopped by a TownBlockType overriding the allowed material and action. if (townBlock.getPermissions().getResidentPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; @@ -527,7 +527,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl if (status == TownBlockStatus.TOWN_NATION) { - // Plot allows Nation perms + // Plot allows Nation perms and we aren't stopped by a TownBlockType overriding the allowed material and action. if (townBlock.getPermissions().getNationPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; @@ -540,7 +540,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl */ if (status == TownBlockStatus.PLOT_ALLY || status == TownBlockStatus.TOWN_ALLY) { - // Plot allows Ally perms + // Plot allows Ally perms and we aren't stopped by a TownBlockType overriding things. if (townBlock.getPermissions().getAllyPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; @@ -557,7 +557,7 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl */ if (status == TownBlockStatus.OUTSIDER || status == TownBlockStatus.ENEMY) { - // Plot allows Outsider perms + // Plot allows Outsider perms and we aren't stopped by a TownBlockType overriding the allowed material and action. if (townBlock.getPermissions().getOutsiderPerm(action) && isAllowedMaterial(townBlock, material, action)) return true; From 39e6b93f39001a048d0e59690eb12e0272113bfd Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Sun, 19 Dec 2021 13:16:38 -0600 Subject: [PATCH 22/28] Separate UnclaimedZoneIgnoreIDs from Wilds plots. Wilds plots get their own list, so that the /towny allowedblocks command returns a proper list. Updates the vastly out-of-date unclaimedZoneIgnoreIds list in the config. Removes wilds plot special case in PlayerCacheUtil. --- src/com/palmergames/bukkit/config/ConfigNodes.java | 2 +- src/com/palmergames/bukkit/towny/TownySettings.java | 6 +++++- .../bukkit/towny/object/TownBlockTypeHandler.java | 11 ++++++----- .../bukkit/towny/utils/PlayerCacheUtil.java | 4 ---- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/com/palmergames/bukkit/config/ConfigNodes.java b/src/com/palmergames/bukkit/config/ConfigNodes.java index 4b3c548271..734c84c655 100644 --- a/src/com/palmergames/bukkit/config/ConfigNodes.java +++ b/src/com/palmergames/bukkit/config/ConfigNodes.java @@ -1444,7 +1444,7 @@ public enum ConfigNodes { "# Can players interact with switch blocks listed in the above protection.switch_ids in the wilderness without restriction?"), UNCLAIMED_ZONE_IGNORE( "unclaimed.unclaimed_zone_ignore", - "SAPLING,GOLD_ORE,IRON_ORE,COAL_ORE,LOG,LEAVES,LAPIS_ORE,LONG_GRASS,YELLOW_FLOWER,RED_ROSE,BROWN_MUSHROOM,RED_MUSHROOM,TORCH,DIAMOND_ORE,LADDER,RAILS,REDSTONE_ORE,GLOWING_REDSTONE_ORE,CACTUS,CLAY,SUGAR_CANE_BLOCK,PUMPKIN,GLOWSTONE,LOG_2,VINE,NETHER_WARTS,COCOA", + "GOLD_ORE,IRON_ORE,COAL_ORE,COPPER_ORE,REDSTONE_ORE,EMERALD_ORE,LAPIS_ORE,DIAMOND_ORE,DEEPSLATE_COAL_ORE,DEEPSLATE_IRON_ORE,DEEPSLATE_COPPER_ORE,DEEPSLATE_GOLD_ORE,DEEPSLATE_EMERALD_ORE,DEEPSLATE_REDSTONE_ORE,DEEPSLATE_LAPIS_ORE,DEEPSLATE_DIAMOND_ORE,NETHER_GOLD_ORE,NETHER_QUARTZ_ORE,ANCIENT_DEBRIS,OAK_LOG,SPRUCE_LOG,BIRCH_LOG,JUNGLE_LOG,ACACIA_LOG,DARK_OAK_LOG,CRIMSON_STEM,WARPED_STEM,ACACIA_LEAVES,OAK_LEAVES,DARK_OAK_LEAVES,JUNGLE_LEAVES,BIRCH_LEAVES,SPRUCE_LEAVES,CRIMSON_HYPHAE,WARPED_HYPHAE,ACACIA_SAPLING,BAMBOO_SAPLING,BIRCH_SAPLING,DARK_OAK_SAPLING,JUNGLE_SAPLING,OAK_SAPLING,SPRUCE_SAPLING,TALL_GRASS,BROWN_MUSHROOM,RED_MUSHROOM,CACTUS,ALLIUM,AZURE_BLUET,BLUE_ORCHID,CORNFLOWER,DANDELION,LILAC,LILY_OF_THE_VALLEY,ORANGE_TULIP,OXEYE_DAISY,PEONY,PINK_TULIP,POPPY,RED_TULIP,ROSE_BUSH,SUNFLOWER,WHITE_TULIP,WITHER_ROSE,CRIMSON_FUNGUS,LARGE_FERN,TORCH,LADDER,CLAY,PUMPKIN,GLOWSTONE,VINE,NETHER_WART_BLOCK,COCOA", "", "# A list of blocks that will bypass the above settings and do not require the towny.wild.* permission node.", "# These blocks are also used in determining which blocks can be interacted with in Towny Wilds plots in towns."), diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index e0b02a90d8..217bf94e82 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -790,7 +790,7 @@ private static void setTownBlockTypes() { type.put("mapKey", "W"); type.put("itemUseIds", ""); type.put("switchIds", ""); - type.put("allowedBlocks", ""); + type.put("allowedBlocks", getDefaultWildsblocks()); types.add(new LinkedHashMap<>(type)); type.clear(); @@ -842,6 +842,10 @@ private static void setTownBlockTypes() { public static String getDefaultFarmblocks() { return "BAMBOO,BAMBOO_SAPLING,JUNGLE_LOG,JUNGLE_SAPLING,JUNGLE_LEAVES,OAK_LOG,OAK_SAPLING,OAK_LEAVES,BIRCH_LOG,BIRCH_SAPLING,BIRCH_LEAVES,ACACIA_LOG,ACACIA_SAPLING,ACACIA_LEAVES,DARK_OAK_LOG,DARK_OAK_SAPLING,DARK_OAK_LEAVES,SPRUCE_LOG,SPRUCE_SAPLING,SPRUCE_LEAVES,BEETROOTS,COCOA,CHORUS_PLANT,CHORUS_FLOWER,SWEET_BERRY_BUSH,KELP,SEAGRASS,TALL_SEAGRASS,GRASS,TALL_GRASS,FERN,LARGE_FERN,CARROTS,WHEAT,POTATOES,PUMPKIN,PUMPKIN_STEM,ATTACHED_PUMPKIN_STEM,NETHER_WART,COCOA,VINE,MELON,MELON_STEM,ATTACHED_MELON_STEM,SUGAR_CANE,CACTUS,ALLIUM,AZURE_BLUET,BLUE_ORCHID,CORNFLOWER,DANDELION,LILAC,LILY_OF_THE_VALLEY,ORANGE_TULIP,OXEYE_DAISY,PEONY,PINK_TULIP,POPPY,RED_TULIP,ROSE_BUSH,SUNFLOWER,WHITE_TULIP,WITHER_ROSE,CRIMSON_FUNGUS,CRIMSON_STEM,CRIMSON_HYPHAE,CRIMSON_ROOTS,MUSHROOM_STEM,NETHER_WART_BLOCK,BROWN_MUSHROOM,BROWN_MUSHROOM_BLOCK,RED_MUSHROOM,RED_MUSHROOM_BLOCK,SHROOMLIGHT,WARPED_FUNGUS,WARPED_HYPHAE,WARPED_ROOTS,WARPED_STEM,WARPED_WART_BLOCK,WEEPING_VINES_PLANT,WEEPING_VINES,NETHER_SPROUTS,SHEARS"; } + + public static String getDefaultWildsblocks() { + return "GOLD_ORE,IRON_ORE,COAL_ORE,COPPER_ORE,REDSTONE_ORE,EMERALD_ORE,LAPIS_ORE,DIAMOND_ORE,DEEPSLATE_COAL_ORE,DEEPSLATE_IRON_ORE,DEEPSLATE_COPPER_ORE,DEEPSLATE_GOLD_ORE,DEEPSLATE_EMERALD_ORE,DEEPSLATE_REDSTONE_ORE,DEEPSLATE_LAPIS_ORE,DEEPSLATE_DIAMOND_ORE,NETHER_GOLD_ORE,NETHER_QUARTZ_ORE,ANCIENT_DEBRIS,OAK_LOG,SPRUCE_LOG,BIRCH_LOG,JUNGLE_LOG,ACACIA_LOG,DARK_OAK_LOG,CRIMSON_STEM,WARPED_STEM,ACACIA_LEAVES,OAK_LEAVES,DARK_OAK_LEAVES,JUNGLE_LEAVES,BIRCH_LEAVES,SPRUCE_LEAVES,CRIMSON_HYPHAE,WARPED_HYPHAE,ACACIA_SAPLING,BAMBOO_SAPLING,BIRCH_SAPLING,DARK_OAK_SAPLING,JUNGLE_SAPLING,OAK_SAPLING,SPRUCE_SAPLING,TALL_GRASS,BROWN_MUSHROOM,RED_MUSHROOM,CACTUS,ALLIUM,AZURE_BLUET,BLUE_ORCHID,CORNFLOWER,DANDELION,LILAC,LILY_OF_THE_VALLEY,ORANGE_TULIP,OXEYE_DAISY,PEONY,PINK_TULIP,POPPY,RED_TULIP,ROSE_BUSH,SUNFLOWER,WHITE_TULIP,WITHER_ROSE,CRIMSON_FUNGUS,LARGE_FERN,TORCH,LADDER,CLAY,PUMPKIN,GLOWSTONE,VINE,NETHER_WART_BLOCK,COCOA"; + } public static String getKingPrefix(Resident resident) { diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index 91d1ce7865..6f2597d896 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -4,6 +4,7 @@ import com.palmergames.bukkit.config.CommentedConfiguration; import com.palmergames.bukkit.config.ConfigNodes; import com.palmergames.bukkit.towny.Towny; +import com.palmergames.bukkit.towny.TownyMessaging; import com.palmergames.bukkit.towny.TownySettings; import com.palmergames.bukkit.towny.event.TownBlockTypeRegisterEvent; import com.palmergames.bukkit.towny.exceptions.TownyException; @@ -111,9 +112,9 @@ private static void applyConfigSettings(Map newData) { double tax = parseDouble(type.get("tax").toString()); String mapKey = String.valueOf(type.get("mapKey")); - Set itemUseIds = loadMaterialList(String.valueOf(type.get("itemUseIds")), name); - Set switchIds = loadMaterialList(String.valueOf(type.get("switchIds")), name); - Set allowedBlocks = loadMaterialList(String.valueOf(type.get("allowedBlocks")), name); + Set itemUseIds = loadMaterialList("itemUseIds", String.valueOf(type.get("itemUseIds")), name); + Set switchIds = loadMaterialList("switchIds", String.valueOf(type.get("switchIds")), name); + Set allowedBlocks = loadMaterialList("allowedBlocks", String.valueOf(type.get("allowedBlocks")), name); TownBlockType townBlockType = newData.get(name.toLowerCase()); TownBlockData data; @@ -140,14 +141,14 @@ private static void applyConfigSettings(Map newData) { } } - private static Set loadMaterialList(String materialList, String typeName) { + private static Set loadMaterialList(String listName, String materialList, String typeName) { if (!materialList.isEmpty()) { Set set = new LinkedHashSet<>(); for (String materialName : materialList.split(",")) { Material material = Material.matchMaterial(materialName); if (material == null) - Towny.getPlugin().getLogger().warning(String.format("Could not find a material named '%s' while loading the item use list for the %s type.", materialName, typeName)); + TownyMessaging.sendDebugMsg(String.format("Could not find a material named '%s' while loading the " + listName + " list for the %s type.", materialName, typeName)); else set.add(material); } diff --git a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java index f030c55163..23714a571b 100644 --- a/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/PlayerCacheUtil.java @@ -14,7 +14,6 @@ import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; import com.palmergames.bukkit.towny.object.TownBlock; -import com.palmergames.bukkit.towny.object.TownBlockType; import com.palmergames.bukkit.towny.object.TownyPermission; import com.palmergames.bukkit.towny.object.TownyPermission.ActionType; import com.palmergames.bukkit.towny.object.Translatable; @@ -580,9 +579,6 @@ private static boolean getPermission(Player player, TownBlockStatus status, Worl * @return True if this material is allowed in this townblock. */ private static boolean isAllowedMaterial(TownBlock townBlock, Material material, ActionType action) { - if (townBlock.getType() == TownBlockType.WILDS) - return TownyUniverse.getInstance().getPermissionSource().unclaimedZoneAction(townBlock.getWorld(), material, action); - if ((action == ActionType.BUILD || action == ActionType.DESTROY) && !townBlock.getData().getAllowedBlocks().isEmpty()) return townBlock.getData().getAllowedBlocks().contains(material); From 8ad06f76ae0c56387de4493ad392fd088c5982d8 Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sun, 19 Dec 2021 23:15:54 +0100 Subject: [PATCH 23/28] Add back plot set prices to /towny prices --- resources/lang/en-US.yml | 7 +++---- .../bukkit/towny/command/TownyCommand.java | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/resources/lang/en-US.yml b/resources/lang/en-US.yml index e360a86922..85cda54789 100644 --- a/resources/lang/en-US.yml +++ b/resources/lang/en-US.yml @@ -1110,10 +1110,9 @@ towny_prices_price_shop: '&c &2Shop: &a%s &8| &2Embassy: &a%s' towny_prices_taxes_plot: '&c [Taxes] &2Resident: &a%s &8| &2Plot: &a%s' towny_prices_taxes_shop: '&c &2Shop: &a%s &8| &2Embassy: &a%s' towny_prices_town_neutral_tax: '&c &2Peace: &a%s' -towny_prices_plots_shop: '&c [Setting Plots] &2Shop: &a%s &8| &2Embassy: &a%s' -towny_prices_plots_wilds: '&c &2Wilds: &a%s &8| &2Inn: &a%s' -towny_prices_plots_jail: '&c &2Jail: &a%s &8| &2Farm: &a%s' -towny_prices_plots_bank: '&c &2Bank: &a%s' +towny_prices_plots: '&c [Setting Plots]' +towny_prices_type_single: ' &2%s: &a%s' +towny_prices_type_double: ' &2%s: &a%s &8| &2%s: &a%s' towny_prices_nationname: '&cNation: &6%s' towny_prices_nation_tax: '&c [Taxes] &2Town: &a%s &8| &2Peace: &a%s' diff --git a/src/com/palmergames/bukkit/towny/command/TownyCommand.java b/src/com/palmergames/bukkit/towny/command/TownyCommand.java index d600495d4e..1ceeae3219 100644 --- a/src/com/palmergames/bukkit/towny/command/TownyCommand.java +++ b/src/com/palmergames/bukkit/towny/command/TownyCommand.java @@ -15,6 +15,8 @@ import com.palmergames.bukkit.towny.exceptions.TownyException; import com.palmergames.bukkit.towny.huds.HUDManager; import com.palmergames.bukkit.towny.object.Government; +import com.palmergames.bukkit.towny.object.TownBlockType; +import com.palmergames.bukkit.towny.object.TownBlockTypeHandler; import com.palmergames.bukkit.towny.object.Translatable; import com.palmergames.bukkit.towny.object.Translator; import com.palmergames.bukkit.towny.object.comparators.GovernmentComparators; @@ -489,6 +491,21 @@ else if (TownySettings.isNationUpkeepPerTown()) output.add(translator.of("towny_prices_taxes_plot", (town.isTaxPercentage()? town.getTaxes() + "%" : getMoney(town.getTaxes())), getMoney(town.getPlotTax()))); output.add(translator.of("towny_prices_taxes_shop", getMoney(town.getCommercialPlotTax()), getMoney(town.getEmbassyPlotTax()))); output.add(translator.of("towny_prices_town_neutral_tax", getMoney(TownySettings.getTownNeutralityCost()))); + + output.add(translator.of("towny_prices_plots")); + List townBlockTypes = new ArrayList<>(TownBlockTypeHandler.getTypes().values()); + for (int i = 0; i < townBlockTypes.size(); i++) { + if (i == townBlockTypes.size() - 1) + output.add(translator.of("towny_prices_type_single", townBlockTypes.get(i).getFormattedName(), getMoney(townBlockTypes.get(i).getCost()))); + else { + output.add(translator.of("towny_prices_type_double", + townBlockTypes.get(i).getFormattedName(), getMoney(townBlockTypes.get(i).getCost()), + townBlockTypes.get(i+1).getFormattedName(), getMoney(townBlockTypes.get(i+1).getCost()) + )); + + i++; + } + } if (nation != null) { output.add(translator.of("towny_prices_nationname", nation.getFormattedName())); From 7a6fc83a5fa685ed7deec5eecd6fea56bd76e09b Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sun, 19 Dec 2021 23:30:52 +0100 Subject: [PATCH 24/28] Add default values to the loading process --- .../towny/object/TownBlockTypeHandler.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java index 6f2597d896..408d02efb8 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockTypeHandler.java @@ -100,21 +100,24 @@ public static boolean exists(@NotNull String typeName) { return getType(typeName) != null; } + @SuppressWarnings("unchecked") private static void applyConfigSettings(Map newData) { List> types = TownySettings.getConfig().getMapList("townblocktypes.types"); - for (Map type : types) { + for (Map genericType : types) { String name = "unknown type"; try { + Map type = (Map) genericType; + name = String.valueOf(type.get("name")); - double cost = parseDouble(type.get("cost").toString()); - double tax = parseDouble(type.get("tax").toString()); - String mapKey = String.valueOf(type.get("mapKey")); + double cost = parseDouble(type.getOrDefault("cost", 0.0).toString()); + double tax = parseDouble(type.getOrDefault("tax", 0.0).toString()); + String mapKey = String.valueOf(type.getOrDefault("mapKey", "+")); - Set itemUseIds = loadMaterialList("itemUseIds", String.valueOf(type.get("itemUseIds")), name); - Set switchIds = loadMaterialList("switchIds", String.valueOf(type.get("switchIds")), name); - Set allowedBlocks = loadMaterialList("allowedBlocks", String.valueOf(type.get("allowedBlocks")), name); + Set itemUseIds = loadMaterialList("itemUseIds", String.valueOf(type.getOrDefault("itemUseIds", "")), name); + Set switchIds = loadMaterialList("switchIds", String.valueOf(type.getOrDefault("switchIds", "")), name); + Set allowedBlocks = loadMaterialList("allowedBlocks", String.valueOf(type.getOrDefault("allowedBlocks", "")), name); TownBlockType townBlockType = newData.get(name.toLowerCase()); TownBlockData data; @@ -202,6 +205,7 @@ public static void checkForLegacyOptions() { migrations.add(new Migration("bank", "cost", bankCost)); } + @SuppressWarnings("unchecked") public static void migrate() { if (migrations.isEmpty()) return; From e066eaf90e3fc6bf325fd145cb8c75806d98e53c Mon Sep 17 00:00:00 2001 From: Warrior <50800980+Warriorrrr@users.noreply.github.com> Date: Sun, 19 Dec 2021 23:40:23 +0100 Subject: [PATCH 25/28] Adjust version in deprecation notice --- src/com/palmergames/bukkit/towny/TownySettings.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index 217bf94e82..1713e4f62b 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -1465,7 +1465,7 @@ public static Set getItemUseMaterials() { * For compatibility with custom plot types, this has been deprecated. Please use {@link #isSwitchMaterial(Material, Location)} instead. * @param mat The name of the material. * @return Whether this is a switch material or not. - * @deprecated as of 0.97.3.0. + * @deprecated as of 0.97.5.3. */ @Deprecated public static boolean isSwitchMaterial(String mat) { @@ -1485,7 +1485,7 @@ public static boolean isSwitchMaterial(Material material, Location location) { * For compatibility with custom plot types, this has been deprecated. Please use {@link #isItemUseMaterial(Material, Location)} instead. * @param mat The name of the material. * @return Whether this is an item use material or not. - * @deprecated as of 0.97.3.0. + * @deprecated as of 0.97.5.3. */ @Deprecated public static boolean isItemUseMaterial(String mat) { From 761a4011a1fd81f2ddebecf277821f4297513f08 Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Mon, 20 Dec 2021 10:21:02 -0600 Subject: [PATCH 26/28] Fix spacing, colouring and missing claimedat values in ascii map hovering. --- .../bukkit/towny/TownyAsciiMap.java | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/TownyAsciiMap.java b/src/com/palmergames/bukkit/towny/TownyAsciiMap.java index 644c995d5a..63c9a6ba0c 100644 --- a/src/com/palmergames/bukkit/towny/TownyAsciiMap.java +++ b/src/com/palmergames/bukkit/towny/TownyAsciiMap.java @@ -133,44 +133,56 @@ else if (nation.hasEnemy(town.getNation())) else townyMap[y][x] = townyMap[y][x].content(townblock.getType().getAsciiMapKey()); + TextComponent residentComponent = Component.empty(); TextComponent forSaleComponent = Component.empty(); TextComponent claimedAtComponent = Component.empty(); TextComponent groupComponent = Component.empty(); if (TownyEconomyHandler.isActive()) { - double cost; - if (townblock.hasPlotObjectGroup()) - cost = townblock.getPlotObjectGroup().getPrice(); - else - cost = townblock.getPlotPrice(); - + double cost = townblock.hasPlotObjectGroup() + ? townblock.getPlotObjectGroup().getPrice() + : townblock.getPlotPrice(); if (cost > -1) forSaleComponent = Component.text(String.format(ChunkNotification.forSaleNotificationFormat, TownyEconomyHandler.getFormattedBalance(cost)).replaceAll("[\\[\\]]", "") + " " + Translatable.of("msg_click_purchase").forLocale(player)).color(NamedTextColor.YELLOW).append(Component.newline()); } if (townblock.getClaimedAt() > 0) - claimedAtComponent = Component.text(Translatable.of("msg_plot_perm_claimed_at", TownyFormatter.registeredFormat.format(townblock.getClaimedAt())).forLocale(player)).append(Component.newline()); - - if (townblock.hasPlotObjectGroup()) { + claimedAtComponent = Component.text(Translatable.of("msg_plot_perm_claimed_at").forLocale(player)).color(NamedTextColor.DARK_GREEN) + .append(Component.space()) + .append(Component.text(TownyFormatter.registeredFormat.format(townblock.getClaimedAt())).color(NamedTextColor.GREEN)) + .append(Component.newline()); + + if (townblock.hasPlotObjectGroup()) groupComponent = Component.text(Translatable.of("map_hover_plot_group").forLocale(player)).color(NamedTextColor.DARK_GREEN) .append(Component.text(townblock.getPlotObjectGroup().getFormattedName()).color(NamedTextColor.GREEN) .append(Component.text(Translatable.of("map_hover_plot_group_size").forLocale(player)).color(NamedTextColor.DARK_GREEN) .append(Component.text(Translatable.of("map_hover_plots", townblock.getPlotObjectGroup().getTownBlocks().size()).forLocale(player)).color(NamedTextColor.GREEN) .append(Component.newline())))); - } - - TextComponent hoverComponent = Component.text(Translatable.of("status_town").forLocale(player) + town.getName() + (townblock.hasResident() ? " (" + townblock.getResidentOrNull().getName() + ")" : "")).color(NamedTextColor.GREEN).append(Component.text(" (" + tby + ", " + tbx + ")").color(NamedTextColor.WHITE)).append(Component.newline()) - .append(Component.text(Translatable.of("status_plot_type").forLocale(player)).color(NamedTextColor.DARK_GREEN).append(Component.text(townblock.getType().getName()).color(NamedTextColor.GREEN).append(Component.newline()) + if (townblock.hasResident()) + residentComponent = Component.text(" (" + townblock.getResidentOrNull().getName() + ")"); + + TextComponent townComponent = Component.text(Translatable.of("status_town").forLocale(player)).color(NamedTextColor.DARK_GREEN) + .append(Component.space()) + .append(Component.text(town.getName()).color(NamedTextColor.GREEN)) + .append(residentComponent.color(NamedTextColor.GREEN)) + .append(Component.text(" (" + tby + ", " + tbx + ")").color(NamedTextColor.WHITE)).append(Component.newline()); + + TextComponent plotTypeComponent = Component.text(Translatable.of("status_plot_type").forLocale(player)).color(NamedTextColor.DARK_GREEN) + .append(Component.space()) + .append(Component.text(townblock.getType().getName()).color(NamedTextColor.GREEN).append(Component.newline())); + + TextComponent hoverComponent = townComponent + .append(plotTypeComponent) .append(groupComponent) .append(forSaleComponent) .append(claimedAtComponent) - .append(Component.text(Translatable.of("towny_map_detailed_information").forLocale(player)).color(NamedTextColor.DARK_GREEN)))); + .append(Component.text(Translatable.of("towny_map_detailed_information").forLocale(player)).color(NamedTextColor.DARK_GREEN)); + + ClickEvent clickEvent = forSaleComponent.equals(Component.empty()) + ? ClickEvent.runCommand("/towny:plot info " + tby + " " + tbx) + : ClickEvent.runCommand("/towny:plot claim " + world.getName() + " x" + tby + " z" + tbx); - ClickEvent clickEvent = ClickEvent.runCommand("/towny:plot info " + tby + " " + tbx); - if (!forSaleComponent.equals(Component.empty())) - clickEvent = ClickEvent.runCommand("/towny:plot claim " + world.getName() + " x" + tby + " z" + tbx); - townyMap[y][x] = townyMap[y][x].hoverEvent(HoverEvent.showText(hoverComponent)).clickEvent(clickEvent); } catch (TownyException e) { // Unregistered town block (Wilderness) From 48aec6dcb91ed03c5c1c65e070dd07ffcb36ae6a Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Mon, 20 Dec 2021 10:54:04 -0600 Subject: [PATCH 27/28] Alter the GUI titles to more accurately reflect what is being asked and represented. --- resources/lang/en-US.yml | 4 +++- .../towny/listeners/TownyInventoryListener.java | 11 ++++++++++- .../palmergames/bukkit/towny/utils/ResidentUtil.java | 7 +------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/resources/lang/en-US.yml b/resources/lang/en-US.yml index 85cda54789..6845fe14af 100644 --- a/resources/lang/en-US.yml +++ b/resources/lang/en-US.yml @@ -1131,7 +1131,9 @@ msg_bankrupt: '&c(Bankrupt)' #Added in 0.98 msg_del_town2: '&bThe town of %s has been deleted!' msg_ruin_town: '&bThe town of %s fell into ruin!' -gui_title_towny_allowedblocks: 'Towny AllowedBlocks List' +gui_title_select_plot_type: 'Select PlotType' +gui_title_no_restrictions: 'No restrictions for this plottype.' +gui_title_towny_allowedblocks: '%s AllowedBlocks List' gui_title_towny_wildsblocks: 'Towny WildsBlocks List' gui_title_towny_itemuse: 'Towny ItemUse List' gui_title_towny_switch: 'Towny Switch List' diff --git a/src/com/palmergames/bukkit/towny/listeners/TownyInventoryListener.java b/src/com/palmergames/bukkit/towny/listeners/TownyInventoryListener.java index daea9d1118..c55ed99b50 100644 --- a/src/com/palmergames/bukkit/towny/listeners/TownyInventoryListener.java +++ b/src/com/palmergames/bukkit/towny/listeners/TownyInventoryListener.java @@ -19,6 +19,7 @@ import com.palmergames.bukkit.towny.TownyUniverse; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.TownyInventory; +import com.palmergames.bukkit.towny.object.Translatable; import com.palmergames.bukkit.util.Colors; import org.bukkit.inventory.meta.ItemMeta; @@ -100,9 +101,17 @@ public void onClick(InventoryClickEvent event) { case ALLOWEDBLOCKS -> type.getData().getAllowedBlocks(); case SWITCHES -> type.getData().getSwitchIds(); }; + + String title = materialSet.isEmpty() + ? Translatable.of("gui_title_no_restrictions").forLocale(resident) + : switch (selectionGUI.getType()) { + case ALLOWEDBLOCKS -> Translatable.of("gui_title_towny_allowedblocks", type.getName()).forLocale(resident); + case SWITCHES -> Translatable.of("gui_title_towny_switch").forLocale(resident); + case ITEMUSE -> Translatable.of("gui_title_towny_itemuse").forLocale(resident); + }; selectionGUI.playClickSound(player); - ResidentUtil.openGUIInventory(resident, materialSet, event.getView().getTitle()); + ResidentUtil.openGUIInventory(resident, materialSet, title); } else { /* * Not a PermissionGUI, EditGUI or SelectionGUI. Use normal pagination. diff --git a/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java b/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java index 0e72022d02..a5309cce31 100644 --- a/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java +++ b/src/com/palmergames/bukkit/towny/utils/ResidentUtil.java @@ -123,12 +123,7 @@ public static void openGUIInventory(Resident resident, Set set, String } public static void openSelectionGUI(Resident resident, SelectionGUI.SelectionType selectionType) { - String inventoryName = switch (selectionType) { - case ITEMUSE -> Translatable.of("gui_title_towny_itemuse").forLocale(resident); - case SWITCHES -> Translatable.of("gui_title_towny_switch").forLocale(resident); - case ALLOWEDBLOCKS -> Translatable.of("gui_title_towny_allowedblocks").forLocale(resident); - }; - + String inventoryName = Translatable.of("gui_title_select_plot_type").forLocale(resident); Inventory page = getBlankPage(inventoryName); ArrayList pages = new ArrayList<>(); From ccfc1202145fec1288e3beabcbb91f010cfb158f Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Tue, 21 Dec 2021 11:59:31 -0600 Subject: [PATCH 28/28] Adjust version reference from 0.97.5.3 to 0.97.5.4. --- src/com/palmergames/bukkit/towny/Towny.java | 1 + src/com/palmergames/bukkit/towny/TownySettings.java | 6 +++--- src/com/palmergames/bukkit/towny/object/TownBlock.java | 2 +- src/com/palmergames/bukkit/towny/object/TownBlockType.java | 6 +++--- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/Towny.java b/src/com/palmergames/bukkit/towny/Towny.java index 60be52d0b9..c674d2dedd 100644 --- a/src/com/palmergames/bukkit/towny/Towny.java +++ b/src/com/palmergames/bukkit/towny/Towny.java @@ -345,6 +345,7 @@ private void loadTownAndNationLevels() { private void handleLegacyConfigs() { // Old configs stored various TownBlock settings throughout the config. // This will migrate the old settings into the TownBlockType config section. + // Since 0.97.5.4. TownBlockTypeHandler.Migrator.checkForLegacyOptions(); } diff --git a/src/com/palmergames/bukkit/towny/TownySettings.java b/src/com/palmergames/bukkit/towny/TownySettings.java index 1713e4f62b..20d948058d 100644 --- a/src/com/palmergames/bukkit/towny/TownySettings.java +++ b/src/com/palmergames/bukkit/towny/TownySettings.java @@ -1465,7 +1465,7 @@ public static Set getItemUseMaterials() { * For compatibility with custom plot types, this has been deprecated. Please use {@link #isSwitchMaterial(Material, Location)} instead. * @param mat The name of the material. * @return Whether this is a switch material or not. - * @deprecated as of 0.97.5.3. + * @deprecated as of 0.97.5.4. */ @Deprecated public static boolean isSwitchMaterial(String mat) { @@ -1485,7 +1485,7 @@ public static boolean isSwitchMaterial(Material material, Location location) { * For compatibility with custom plot types, this has been deprecated. Please use {@link #isItemUseMaterial(Material, Location)} instead. * @param mat The name of the material. * @return Whether this is an item use material or not. - * @deprecated as of 0.97.5.3. + * @deprecated as of 0.97.5.4. */ @Deprecated public static boolean isItemUseMaterial(String mat) { @@ -2681,7 +2681,7 @@ public static double getNationRequiresProximity() { } /** - * @deprecated since 0.97.5.3 + * @deprecated since 0.97.5.4 * @return Collections.emptyList() */ @Deprecated diff --git a/src/com/palmergames/bukkit/towny/object/TownBlock.java b/src/com/palmergames/bukkit/towny/object/TownBlock.java index 1b70c4bacf..ddc8d33848 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlock.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlock.java @@ -316,7 +316,7 @@ public void setType(@Nullable TownBlockType type) { /** * Sets the type of this townblock to the specified ID. * @param typeId The id of the type - * @deprecated As of 0.97.5.3, this is deprecated for compatibility with custom types. + * @deprecated As of 0.97.5.4, this is deprecated for compatibility with custom types. * @see #setType(String) */ @Deprecated diff --git a/src/com/palmergames/bukkit/towny/object/TownBlockType.java b/src/com/palmergames/bukkit/towny/object/TownBlockType.java index a000ebdbb0..4504752ae6 100644 --- a/src/com/palmergames/bukkit/towny/object/TownBlockType.java +++ b/src/com/palmergames/bukkit/towny/object/TownBlockType.java @@ -54,7 +54,7 @@ public double getTax(Town town) { } /** - * @deprecated since 0.97.5.3. + * @deprecated since 0.97.5.4. * @return 0. */ @Deprecated @@ -100,7 +100,7 @@ public static Map getLegacylookupmap() { } /** - * @deprecated As of 0.97.5.3, please use {@link TownBlockTypeHandler#getType(String)} instead. + * @deprecated As of 0.97.5.4, please use {@link TownBlockTypeHandler#getType(String)} instead. */ @Nullable @Deprecated @@ -109,7 +109,7 @@ public static TownBlockType lookup(int id) { } /** - * @deprecated As of 0.97.5.3, please use {@link TownBlockTypeHandler#getType(String)} instead. + * @deprecated As of 0.97.5.4, please use {@link TownBlockTypeHandler#getType(String)} instead. */ @Nullable @Deprecated