From fa6e65d7183e13ea94da40cc9da69a8be0282c75 Mon Sep 17 00:00:00 2001 From: lexiccn <13711345+lexiccn@users.noreply.github.com> Date: Sat, 30 Mar 2024 18:40:09 +0000 Subject: [PATCH 1/8] Add coin.png to resources --- src/main/resources/coin.png | Bin 0 -> 24793 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/resources/coin.png diff --git a/src/main/resources/coin.png b/src/main/resources/coin.png new file mode 100644 index 0000000000000000000000000000000000000000..217ec5f3ae2e2832a1eb41dd9a5070cb7c48704d GIT binary patch literal 24793 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

XGk+rM1w=9n47P&!foqWR^~7-`Nu{ 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 literal 0 HcmV?d00001 From d14b4164fe1992a039b1c76a3eb450d44ac33e95 Mon Sep 17 00:00:00 2001 From: lexiccn <13711345+lexiccn@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:10:37 +0000 Subject: [PATCH 2/8] Add filepath support and fallback functionality for icon --- .../townyprovinces/settings/ConfigNodes.java | 4 +- .../settings/TownyProvincesSettings.java | 47 +++++++++++++++---- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java b/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java index 70af687..6d5ab3b 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java @@ -206,8 +206,8 @@ public enum ConfigNodes { ""), MAP_TOWN_COSTS_ICON_URL( "map_integration.town_costs_icon.url", - "https://cdn-icons-png.flaticon.com/512/9729/9729309.png", "", - "# Icon for the town costs. This must be a valid image URL.", + "coin.png", "", + "# Icon for the town costs. This must be a valid URL or filepath.", "# Default coin icon created by Md Tanvirul Haque - Flaticon", "# https://www.flaticon.com/free-icon/dollar_9729309" ), diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java b/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java index 7437237..7966ce6 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java @@ -15,8 +15,11 @@ import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.InvalidPathException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -256,20 +259,48 @@ public static boolean isBiomeCostAdjustmentsEnabled() { public static double getBiomeCostAdjustmentsHotLand() { return Settings.getDouble(ConfigNodes.BIOME_COST_ADJUSTMENTS_HOT_LAND); } public static double getBiomeCostAdjustmentsColdLand() { return Settings.getDouble(ConfigNodes.BIOME_COST_ADJUSTMENTS_COLD_LAND); } - public static @Nullable BufferedImage getTownCostsIcon() { - URL imageURL; + private static BufferedImage getFallbackTownCostsIcon() { try { - imageURL = new URL(Settings.getString(ConfigNodes.MAP_TOWN_COSTS_ICON_URL)); - return ImageIO.read(imageURL); - } catch (MalformedURLException e) { - TownyProvinces.severe("Error: Invalid Town Costs Icon URL in configuration file."); - return null; + InputStream imageStream = TownyProvinces.getPlugin().getResource("coin.png"); + if (imageStream == null) { + TownyProvinces.severe("Error: Fallback Town Costs Icon is missing from plugin jar file."); + return null; + } + return ImageIO.read(imageStream); } catch (IOException e) { - TownyProvinces.severe("Error: Failed to load Town Costs Icon from URL provided in configuration file."); + TownyProvinces.severe("Error: Failed to load fallback Town Costs Icon from plugin jar file."); return null; } } + public static @Nullable BufferedImage getTownCostsIcon() { + String imageString = Settings.getString(ConfigNodes.MAP_TOWN_COSTS_ICON_URL); + if (imageString.startsWith("https://") || imageString.startsWith("http://")) { + URL imageURL; + try { + imageURL = new URL(Settings.getString(ConfigNodes.MAP_TOWN_COSTS_ICON_URL)); + return ImageIO.read(imageURL); + } catch (MalformedURLException e) { + TownyProvinces.severe("Error: Invalid Town Costs Icon URL in configuration file."); + return getFallbackTownCostsIcon(); + } catch (IOException e) { + TownyProvinces.severe("Error: Failed to load Town Costs Icon from URL provided in configuration file."); + return getFallbackTownCostsIcon(); + } + } else { + try { + Path imagePath = TownyProvinces.getPlugin().getDataFolder().toPath().resolve(imageString); + return ImageIO.read(imagePath.toFile()); + } catch (InvalidPathException e) { + TownyProvinces.severe("Error: Invalid Town Costs Icon filepath in configuration file."); + return getFallbackTownCostsIcon(); + } catch (IOException e) { + TownyProvinces.severe("Error: Failed to load Town Costs Icon from filepath provided in configuration file."); + return getFallbackTownCostsIcon(); + } + } + } + public static int getTownCostsIconWidth() { return Settings.getInt(ConfigNodes.MAP_TOWN_COSTS_ICON_WIDTH); } public static int getTownCostsIconHeight() { return Settings.getInt(ConfigNodes.MAP_TOWN_COSTS_ICON_HEIGHT); } From ca833407d5392184546650d306a3df5f7753e59d Mon Sep 17 00:00:00 2001 From: lexiccn <13711345+lexiccn@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:25:04 +0000 Subject: [PATCH 3/8] Default to empty and load coin.png only from resources --- .../townyadvanced/townyprovinces/settings/ConfigNodes.java | 2 +- .../townyprovinces/settings/TownyProvincesSettings.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java b/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java index 6d5ab3b..9cd1e2d 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java @@ -206,7 +206,7 @@ public enum ConfigNodes { ""), MAP_TOWN_COSTS_ICON_URL( "map_integration.town_costs_icon.url", - "coin.png", "", + "", "", "# Icon for the town costs. This must be a valid URL or filepath.", "# Default coin icon created by Md Tanvirul Haque - Flaticon", "# https://www.flaticon.com/free-icon/dollar_9729309" diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java b/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java index 7966ce6..e0f47be 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java @@ -275,6 +275,7 @@ private static BufferedImage getFallbackTownCostsIcon() { public static @Nullable BufferedImage getTownCostsIcon() { String imageString = Settings.getString(ConfigNodes.MAP_TOWN_COSTS_ICON_URL); + if (imageString.isEmpty()) return getFallbackTownCostsIcon(); if (imageString.startsWith("https://") || imageString.startsWith("http://")) { URL imageURL; try { From ed144f0b2e4af4d43f80481b472e57622fc45eae Mon Sep 17 00:00:00 2001 From: lexiccn <13711345+lexiccn@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:26:14 +0000 Subject: [PATCH 4/8] Update comments on config node --- .../townyadvanced/townyprovinces/settings/ConfigNodes.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java b/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java index 9cd1e2d..6910b96 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java @@ -207,7 +207,8 @@ public enum ConfigNodes { MAP_TOWN_COSTS_ICON_URL( "map_integration.town_costs_icon.url", "", "", - "# Icon for the town costs. This must be a valid URL or filepath.", + "# Custom icon for the town costs. This must be a valid URL, or a filepath in TownyProvinces folder.", + "# Leave this empty to use the default coin icon.", "# Default coin icon created by Md Tanvirul Haque - Flaticon", "# https://www.flaticon.com/free-icon/dollar_9729309" ), From a4112618787a0a9ff8b216fa7ae504aca867736f Mon Sep 17 00:00:00 2001 From: lexiccn <13711345+lexiccn@users.noreply.github.com> Date: Sat, 30 Mar 2024 21:51:01 +0000 Subject: [PATCH 5/8] Use string variable instead of getting string again --- .../townyprovinces/settings/TownyProvincesSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java b/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java index e0f47be..d3086cd 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java @@ -279,7 +279,7 @@ private static BufferedImage getFallbackTownCostsIcon() { if (imageString.startsWith("https://") || imageString.startsWith("http://")) { URL imageURL; try { - imageURL = new URL(Settings.getString(ConfigNodes.MAP_TOWN_COSTS_ICON_URL)); + imageURL = new URL(imageString); return ImageIO.read(imageURL); } catch (MalformedURLException e) { TownyProvinces.severe("Error: Invalid Town Costs Icon URL in configuration file."); From 1d329afc6083367ac3ca82bc47895199c444e19b Mon Sep 17 00:00:00 2001 From: lexiccn <13711345+lexiccn@users.noreply.github.com> Date: Sat, 30 Mar 2024 22:23:49 +0000 Subject: [PATCH 6/8] Change config node to force change --- .../townyprovinces/settings/ConfigNodes.java | 8 ++++---- .../townyprovinces/settings/TownyProvincesSettings.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java b/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java index 6910b96..ea7f7c3 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/settings/ConfigNodes.java @@ -204,14 +204,14 @@ public enum ConfigNodes { "# | TOWN COSTS ICON | #", "# +------------------------------------------------------+ #", ""), - MAP_TOWN_COSTS_ICON_URL( - "map_integration.town_costs_icon.url", + MAP_TOWN_COSTS_ICON_PATH( + "map_integration.town_costs_icon.path", "", "", "# Custom icon for the town costs. This must be a valid URL, or a filepath in TownyProvinces folder.", - "# Leave this empty to use the default coin icon.", + "# Leave this empty to use the included default coin icon.", "# Default coin icon created by Md Tanvirul Haque - Flaticon", "# https://www.flaticon.com/free-icon/dollar_9729309" - ), + ), MAP_TOWN_COSTS_ICON_HEIGHT( "map_integration.town_costs_icon.height", "35", diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java b/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java index d3086cd..ba25afc 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/settings/TownyProvincesSettings.java @@ -274,7 +274,7 @@ private static BufferedImage getFallbackTownCostsIcon() { } public static @Nullable BufferedImage getTownCostsIcon() { - String imageString = Settings.getString(ConfigNodes.MAP_TOWN_COSTS_ICON_URL); + String imageString = Settings.getString(ConfigNodes.MAP_TOWN_COSTS_ICON_PATH); if (imageString.isEmpty()) return getFallbackTownCostsIcon(); if (imageString.startsWith("https://") || imageString.startsWith("http://")) { URL imageURL; From 4fd3dbd419f48d39ff6b86bb7c0c714ed8babd2a Mon Sep 17 00:00:00 2001 From: lexiccn <13711345+lexiccn@users.noreply.github.com> Date: Sat, 30 Mar 2024 22:35:03 +0000 Subject: [PATCH 7/8] Update errors to not say URL explicitly --- .../jobs/map_display/DisplayProvincesOnBlueMapAction.java | 2 +- .../jobs/map_display/DisplayProvincesOnDynmapAction.java | 2 +- .../jobs/map_display/DisplayProvincesOnPl3xMapV3Action.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnBlueMapAction.java b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnBlueMapAction.java index 348d382..06a2d6c 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnBlueMapAction.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnBlueMapAction.java @@ -50,7 +50,7 @@ public DisplayProvincesOnBlueMapAction() { void reloadAction() { if (TownyProvincesSettings.getTownCostsIcon() == null) { - throw new RuntimeException("Town Costs Icon URL is not a valid image link"); + throw new RuntimeException("Town Costs Icon is not a valid image"); } BlueMapAPI.getInstance().ifPresent(e -> { diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnDynmapAction.java b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnDynmapAction.java index ccf1423..f404397 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnDynmapAction.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnDynmapAction.java @@ -46,7 +46,7 @@ public DisplayProvincesOnDynmapAction() { @Override void reloadAction() { if (TownyProvincesSettings.getTownCostsIcon() == null) { - throw new RuntimeException("Town Costs Icon URL is not a valid image link"); + throw new RuntimeException("Town Costs Icon is not a valid image"); } final MarkerIcon oldMarkerIcon = markerapi.getMarkerIcon("provinces_costs_icon"); diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnPl3xMapV3Action.java b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnPl3xMapV3Action.java index f933704..1216d76 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnPl3xMapV3Action.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnPl3xMapV3Action.java @@ -128,7 +128,7 @@ private SimpleLayer createLayer(String layerKey, String layerName, boolean hideB @Override void reloadAction() { if (TownyProvincesSettings.getTownCostsIcon() == null) { - throw new RuntimeException("Town Costs Icon URL is not a valid image link"); + throw new RuntimeException("Town Costs Icon is not a valid image"); } Pl3xMap.api().getIconRegistry().register(new IconImage( From e39ab384ab37a753c0a95b334055fde3054c21cc Mon Sep 17 00:00:00 2001 From: lexiccn <13711345+lexiccn@users.noreply.github.com> Date: Sat, 30 Mar 2024 22:38:03 +0000 Subject: [PATCH 8/8] Get image once per mapper --- .../jobs/map_display/DisplayProvincesOnBlueMapAction.java | 4 ++-- .../jobs/map_display/DisplayProvincesOnDynmapAction.java | 7 +++++-- .../map_display/DisplayProvincesOnPl3xMapV3Action.java | 7 +++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnBlueMapAction.java b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnBlueMapAction.java index 06a2d6c..0855702 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnBlueMapAction.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnBlueMapAction.java @@ -48,15 +48,15 @@ public DisplayProvincesOnBlueMapAction() { @Override void reloadAction() { + BufferedImage configIcon = TownyProvincesSettings.getTownCostsIcon(); - if (TownyProvincesSettings.getTownCostsIcon() == null) { + if (configIcon == null) { throw new RuntimeException("Town Costs Icon is not a valid image"); } BlueMapAPI.getInstance().ifPresent(e -> { Path assetsFolder = e.getWebApp().getWebRoot().resolve("assets"); try (OutputStream out = Files.newOutputStream(assetsFolder.resolve("province.png"), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) { - BufferedImage configIcon = TownyProvincesSettings.getTownCostsIcon(); BufferedImage resizedIcon = new BufferedImage( TownyProvincesSettings.getTownCostsIconWidth(), TownyProvincesSettings.getTownCostsIconHeight(), diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnDynmapAction.java b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnDynmapAction.java index f404397..6d7b146 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnDynmapAction.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnDynmapAction.java @@ -16,6 +16,7 @@ import org.dynmap.markers.MarkerSet; import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -45,7 +46,9 @@ public DisplayProvincesOnDynmapAction() { @Override void reloadAction() { - if (TownyProvincesSettings.getTownCostsIcon() == null) { + BufferedImage configIcon = TownyProvincesSettings.getTownCostsIcon(); + + if (configIcon == null) { throw new RuntimeException("Town Costs Icon is not a valid image"); } @@ -56,7 +59,7 @@ void reloadAction() { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { - ImageIO.write(TownyProvincesSettings.getTownCostsIcon(), "png", outputStream); + ImageIO.write(configIcon, "png", outputStream); } catch (IOException ex) { TownyProvinces.severe("Failed to write BlueMap Marker Icon as png file!"); throw new RuntimeException(ex); diff --git a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnPl3xMapV3Action.java b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnPl3xMapV3Action.java index 1216d76..3e6d42a 100644 --- a/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnPl3xMapV3Action.java +++ b/src/main/java/io/github/townyadvanced/townyprovinces/jobs/map_display/DisplayProvincesOnPl3xMapV3Action.java @@ -26,6 +26,7 @@ import net.pl3x.map.core.markers.option.Stroke; import net.pl3x.map.core.world.World; +import java.awt.image.BufferedImage; import java.util.*; import java.util.List; @@ -127,12 +128,14 @@ private SimpleLayer createLayer(String layerKey, String layerName, boolean hideB @Override void reloadAction() { - if (TownyProvincesSettings.getTownCostsIcon() == null) { + BufferedImage configIcon = TownyProvincesSettings.getTownCostsIcon(); + + if (configIcon == null) { throw new RuntimeException("Town Costs Icon is not a valid image"); } Pl3xMap.api().getIconRegistry().register(new IconImage( - "provinces_costs_icon", TownyProvincesSettings.getTownCostsIcon(), "png")); + "provinces_costs_icon", configIcon, "png")); } @Override