diff --git a/pom.xml b/pom.xml
index 29dffe54e..a346f7662 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,13 @@
RC-37
provided
+
+
+ xyz.jpenilla
+ squaremap-api
+ 1.3.14
+ provided
+
maven.modrinth
diff --git a/src/main/java/com/bekvon/bukkit/residence/webmap/SquareWebMap.java b/src/main/java/com/bekvon/bukkit/residence/webmap/SquareWebMap.java
new file mode 100644
index 000000000..1b9cf9732
--- /dev/null
+++ b/src/main/java/com/bekvon/bukkit/residence/webmap/SquareWebMap.java
@@ -0,0 +1,224 @@
+package com.bekvon.bukkit.residence.webmap;
+
+import java.awt.Color;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World;
+
+import com.bekvon.bukkit.residence.containers.Flags;
+import com.bekvon.bukkit.residence.containers.lm;
+import com.bekvon.bukkit.residence.protection.ClaimedResidence;
+import com.bekvon.bukkit.residence.protection.CuboidArea;
+
+import net.Zrips.CMILib.Colors.CMIChatColor;
+import xyz.jpenilla.squaremap.api.BukkitAdapter;
+import xyz.jpenilla.squaremap.api.Key;
+import xyz.jpenilla.squaremap.api.LayerProvider;
+import xyz.jpenilla.squaremap.api.MapWorld;
+import xyz.jpenilla.squaremap.api.Point;
+import xyz.jpenilla.squaremap.api.Registry;
+import xyz.jpenilla.squaremap.api.SimpleLayerProvider;
+import xyz.jpenilla.squaremap.api.Squaremap;
+import xyz.jpenilla.squaremap.api.SquaremapProvider;
+import xyz.jpenilla.squaremap.api.WorldIdentifier;
+import xyz.jpenilla.squaremap.api.marker.Marker;
+import xyz.jpenilla.squaremap.api.marker.MarkerOptions;
+import xyz.jpenilla.squaremap.api.marker.Rectangle;
+
+public class SquareWebMap extends WebMap {
+
+ private static final Key LAYER_KEY = Key.of("residence.residences");
+ private static final String LAYER_LABEL = "Residence";
+
+ private final Map providers = new HashMap();
+ private Squaremap api;
+
+ @Override
+ protected void handleResidenceAdd(ClaimedResidence res, int depth) {
+ if (res == null || api == null)
+ return;
+
+ String owner = res.getOwner();
+ if ((owner != null && getSettings().getHiddenPlayerResidences().contains(owner.toLowerCase()))
+ || (res.getPermissions().has(Flags.hidden, false) && getSettings().isHideHidden())
+ || !isVisible(res.getName(), res.getPermissions().getWorldName())) {
+ handleResidenceRemove(res.getName(), res, depth);
+ return;
+ }
+
+ World world = Bukkit.getWorld(res.getPermissions().getWorldName());
+ if (world == null)
+ return;
+
+ SimpleLayerProvider provider = getProvider(world);
+ if (provider == null)
+ return;
+
+ for (Entry oneArea : res.getAreaMap().entrySet()) {
+ String resName = res.getName();
+ if (res.getAreaMap().size() > 1)
+ resName = res.getName() + " (" + oneArea.getKey() + ")";
+
+ Location low = oneArea.getValue().getLowLocation();
+ Location high = oneArea.getValue().getHighLocation();
+
+ Rectangle marker = Marker.rectangle(
+ Point.of(low.getBlockX(), low.getBlockZ()),
+ Point.of(high.getBlockX() + 1D, high.getBlockZ() + 1D)
+ );
+
+ CMIChatColor border = getSettings().getBorderColor();
+ CMIChatColor fill = fillColor(res);
+
+ MarkerOptions.Builder options = MarkerOptions.builder()
+ .strokeColor(toColor(border))
+ .strokeWeight(getSettings().getBorderWeight())
+ .strokeOpacity(toOpacity(border))
+ .fillColor(toColor(fill))
+ .fillOpacity(toOpacity(fill))
+ .clickTooltip(formatInfoWindow(res, resName));
+
+ marker.markerOptions(options);
+ provider.addMarker(markerKey(oneArea.getKey(), res.getName()), marker);
+ }
+
+ if (depth <= getSettings().getLayerSubZoneDepth()) {
+ List subzones = res.getSubzones();
+ for (ClaimedResidence subzone : subzones) {
+ try {
+ handleResidenceAdd(subzone, depth + 1);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void handleResidenceRemove(String resid, ClaimedResidence res, int depth) {
+ if (resid == null || res == null || api == null)
+ return;
+
+ World world = Bukkit.getWorld(res.getPermissions().getWorldName());
+ if (world == null)
+ return;
+
+ SimpleLayerProvider provider = getProvider(world);
+ if (provider == null)
+ return;
+
+ for (Entry oneArea : res.getAreaMap().entrySet()) {
+ provider.removeMarker(markerKey(oneArea.getKey(), resid));
+ }
+
+ if (depth <= getSettings().getLayerSubZoneDepth() + 1) {
+ List subzones = res.getSubzones();
+ for (ClaimedResidence subzone : subzones)
+ handleResidenceRemove(subzone.getName(), subzone, depth + 1);
+ }
+ }
+
+ private SimpleLayerProvider getProvider(World world) {
+ MapWorld mapWorld = getMapWorld(world);
+ if (mapWorld == null)
+ return null;
+
+ WorldIdentifier identifier = mapWorld.identifier();
+ Registry registry = mapWorld.layerRegistry();
+ ProviderRegistration registration = providers.get(identifier);
+
+ if (registration != null) {
+ if (registration.registry == registry
+ && registry.hasEntry(LAYER_KEY)
+ && registry.get(LAYER_KEY) == registration.provider)
+ return registration.provider;
+
+ if (registration.registry.hasEntry(LAYER_KEY)
+ && registration.registry.get(LAYER_KEY) == registration.provider)
+ registration.registry.unregister(LAYER_KEY);
+
+ providers.remove(identifier);
+ }
+
+ if (registry.hasEntry(LAYER_KEY))
+ registry.unregister(LAYER_KEY);
+
+ SimpleLayerProvider provider = SimpleLayerProvider.builder(LAYER_LABEL)
+ .defaultHidden(getSettings().isHideByDefault())
+ .build();
+ registry.register(LAYER_KEY, provider);
+
+ providers.put(identifier, new ProviderRegistration(registry, provider));
+ return provider;
+ }
+
+ private MapWorld getMapWorld(World world) {
+ for (MapWorld mapWorld : api.mapWorlds()) {
+ try {
+ if (world.equals(BukkitAdapter.bukkitWorld(mapWorld)))
+ return mapWorld;
+ } catch (Throwable ignored) {
+ }
+ }
+ return null;
+ }
+
+ private static Key markerKey(String areaName, String residenceName) {
+ String key = "residence." + areaName + "." + residenceName;
+ try {
+ return Key.of(key);
+ } catch (IllegalArgumentException ignored) {
+ String encoded = Base64.getUrlEncoder().withoutPadding().encodeToString(
+ (areaName + "\0" + residenceName).getBytes(StandardCharsets.UTF_8)
+ );
+ return Key.of("residence." + encoded);
+ }
+ }
+
+ private static Color toColor(CMIChatColor color) {
+ int argb = color.getARGB();
+ return new Color((argb >> 16) & 0xFF, (argb >> 8) & 0xFF, argb & 0xFF);
+ }
+
+ private static double toOpacity(CMIChatColor color) {
+ return ((color.getARGB() >>> 24) & 0xFF) / 255D;
+ }
+
+ @Override
+ public void activate() {
+ api = SquaremapProvider.get();
+ lm.consoleMessage("squaremap residence activated!");
+ postActivated();
+ }
+
+ @Override
+ public void onDisable() {
+ if (api == null)
+ return;
+
+ for (ProviderRegistration registration : providers.values()) {
+ if (registration.registry.hasEntry(LAYER_KEY)
+ && registration.registry.get(LAYER_KEY) == registration.provider)
+ registration.registry.unregister(LAYER_KEY);
+ }
+ providers.clear();
+ api = null;
+ }
+
+ private static final class ProviderRegistration {
+ private final Registry registry;
+ private final SimpleLayerProvider provider;
+
+ private ProviderRegistration(Registry registry, SimpleLayerProvider provider) {
+ this.registry = registry;
+ this.provider = provider;
+ }
+ }
+}
diff --git a/src/main/java/com/bekvon/bukkit/residence/webmap/WebMapListeners.java b/src/main/java/com/bekvon/bukkit/residence/webmap/WebMapListeners.java
index 77aae5ddb..3954d0b36 100644
--- a/src/main/java/com/bekvon/bukkit/residence/webmap/WebMapListeners.java
+++ b/src/main/java/com/bekvon/bukkit/residence/webmap/WebMapListeners.java
@@ -31,6 +31,7 @@ public void onResidenceAreaAdd(ResidenceAreaAddEvent event) {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onResidenceAreaDelete(ResidenceAreaDeleteEvent event) {
plugin.getWebMapManager().fireUpdateRemove(event.getResidence());
+ plugin.getWebMapManager().fireUpdateAdd(event.getResidence());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
diff --git a/src/main/java/com/bekvon/bukkit/residence/webmap/WebMapManager.java b/src/main/java/com/bekvon/bukkit/residence/webmap/WebMapManager.java
index 5ce072c6f..4d170879e 100644
--- a/src/main/java/com/bekvon/bukkit/residence/webmap/WebMapManager.java
+++ b/src/main/java/com/bekvon/bukkit/residence/webmap/WebMapManager.java
@@ -28,7 +28,7 @@ public void loadConfig(ConfigReader c) {
settings = webmap != null ? webmap.getSettings() : new MapSettings();
- c.addComment("WebMap.Use", "Enables or disable DynMap, Pl3exMap or BlueMap support");
+ c.addComment("WebMap.Use", "Enables or disables DynMap, Pl3xMap, squaremap, or BlueMap support");
use = c.get("WebMap.Use", true);
c.addComment("WebMap.HideByDefault", "When set to true we will hide residence areas by default on WebMap window",
"Residences can still be enabled throw provided WebMap option on left top side");
@@ -63,7 +63,7 @@ public void loadConfig(ConfigReader c) {
c.addComment("WebMap.HiddenRegions", "Hides region on map even if its not hidden in game");
settings.setHiddenRegions(c.get("WebMap.HiddenRegions", new ArrayList()));
- c.addComment("WebMap.HiddenPlayerResidences", "List of player names whose residences should be hidden in DynMap, Pl3exMap or BlueMap independent of their settings");
+ c.addComment("WebMap.HiddenPlayerResidences", "List of player names whose residences should be hidden in DynMap, Pl3xMap, squaremap, or BlueMap independent of their settings");
settings.setHiddenPlayerResidences(c.get("WebMap.HiddenPlayerResidences", new ArrayList()));
}
@@ -97,6 +97,19 @@ public void activate() {
}
}
+// Try squaremap
+ Plugin squaremap = Bukkit.getPluginManager().getPlugin("squaremap");
+ if (squaremap != null) {
+ try {
+ SquareWebMap s = new SquareWebMap();
+ s.settings = settings;
+ s.activate();
+ webmaps.add(s);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
// Try BlueMap
Plugin bluemap = Bukkit.getPluginManager().getPlugin("BlueMap");
if (bluemap != null) {
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 10eb40ad9..e8c767d18 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -7,7 +7,7 @@ api-version: 1.13
folia-supported: true
authors: [Zrips,bekvon]
depend: [CMILib]
-softdepend: [Pl3xMap,BlueMap,Vault,Essentials,RealPlugin,iConomy,bPermissions,WorldEdit,WorldGuard,CrackShot,Multiverse-Core,MultiWorld,My_Worlds,TheWorld,dynmap,LWC,Kingdoms,PlaceholderAPI,CMI,ServerControlReloaded,Slimefun,CS-CoreLib]
+softdepend: [Pl3xMap,squaremap,BlueMap,Vault,Essentials,RealPlugin,iConomy,bPermissions,WorldEdit,WorldGuard,CrackShot,Multiverse-Core,MultiWorld,My_Worlds,TheWorld,dynmap,LWC,Kingdoms,PlaceholderAPI,CMI,ServerControlReloaded,Slimefun,CS-CoreLib]
contributors: [lemon42,smbarbour,inorixu,Shayana_fr,Zrips]
commands:
res: