From 272129041b5208eefc712df06bb3adc6f7de81f3 Mon Sep 17 00:00:00 2001
From: Ash <ash@lumine.io>
Date: Fri, 17 Jan 2025 19:50:46 -0700
Subject: [PATCH] Rewrote spray handler, changed sprays to be loaded from the
 assets/textures folder like everything else

---
 plugin/pom.xml                                |  2 +
 .../cosmetics/commands/SprayCommand.java      |  8 ++-
 .../nms/cosmetic/VolatileSprayHelper.java     |  3 +-
 .../io/lumine/cosmetics/players/Profile.java  |  9 +--
 .../lumine/cosmetics/types/sprays/Spray.java  | 19 ++----
 .../cosmetics/types/sprays/SprayImage.java    | 16 +++--
 .../cosmetics/types/sprays/SprayManager.java  | 51 ++++----------
 .../cosmetics/types/sprays/SprayMap.java      | 13 ----
 .../types/sprays/types/MapSpray.java          | 67 +++++++++++++++++++
 .../v1_21_R2/cosmetic/VolatileSprayImpl.java  |  4 +-
 .../v1_21_R3/cosmetic/VolatileSprayImpl.java  |  3 +-
 11 files changed, 113 insertions(+), 82 deletions(-)
 delete mode 100644 plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayMap.java
 create mode 100644 plugin/src/main/java/io/lumine/cosmetics/types/sprays/types/MapSpray.java

diff --git a/plugin/pom.xml b/plugin/pom.xml
index 019b8c8..53b78e4 100644
--- a/plugin/pom.xml
+++ b/plugin/pom.xml
@@ -159,12 +159,14 @@
             <version>${mythic.version}</version>
             <scope>provided</scope>
         </dependency>
+        <!--
         <dependency>
             <groupId>io.lumine</groupId>
             <artifactId>LumineUtils</artifactId>
             <version>${lumineutils.version}</version>
             <scope>provided</scope>
         </dependency>
+        -->
         <dependency> 
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
diff --git a/plugin/src/main/java/io/lumine/cosmetics/commands/SprayCommand.java b/plugin/src/main/java/io/lumine/cosmetics/commands/SprayCommand.java
index 63996e0..1e0c0ca 100644
--- a/plugin/src/main/java/io/lumine/cosmetics/commands/SprayCommand.java
+++ b/plugin/src/main/java/io/lumine/cosmetics/commands/SprayCommand.java
@@ -3,6 +3,7 @@ package io.lumine.cosmetics.commands;
 import java.util.Collections;
 import java.util.List;
 
+import io.lumine.mythic.bukkit.utils.logging.Log;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
@@ -24,7 +25,7 @@ public class SprayCommand extends Command<MCCosmeticsPlugin> {
         var profile = getPlugin().getProfiles().getProfile(player);
 
         if(args.length > 0) {
-            var sprayName = args[1];
+            var sprayName = args[0];
             var maybeSpray = getPlugin().getSprayManager().getCosmetic(sprayName);
             
             if(maybeSpray.isEmpty()) {
@@ -40,12 +41,15 @@ public class SprayCommand extends Command<MCCosmeticsPlugin> {
             var maybeSpray = profile.getEquipped(Spray.class);
             
             if(maybeSpray.isEmpty()) {
+                Log.info("no spray");
                 return true;
             }
             
             var spray = (Spray) maybeSpray.get().getCosmetic();
-            
+
+            Log.info("spray");
             if(profile.has(spray)) {
+                Log.info("has spray");
                 getPlugin().getSprayManager().useSpray(player, spray);
             }
         }
diff --git a/plugin/src/main/java/io/lumine/cosmetics/nms/cosmetic/VolatileSprayHelper.java b/plugin/src/main/java/io/lumine/cosmetics/nms/cosmetic/VolatileSprayHelper.java
index 7622b84..fc282c7 100644
--- a/plugin/src/main/java/io/lumine/cosmetics/nms/cosmetic/VolatileSprayHelper.java
+++ b/plugin/src/main/java/io/lumine/cosmetics/nms/cosmetic/VolatileSprayHelper.java
@@ -1,11 +1,12 @@
 package io.lumine.cosmetics.nms.cosmetic;
 
 import io.lumine.cosmetics.types.sprays.Spray;
+import io.lumine.cosmetics.types.sprays.types.MapSpray;
 import org.bukkit.Location;
 import org.bukkit.block.BlockFace;
 
 public interface VolatileSprayHelper extends VolatileCosmeticHelper {
 
-    int drawSpray(Spray spray, Location location, BlockFace face, int rotation);
+    int drawMapSpray(MapSpray spray, Location location, BlockFace face, int rotation);
 
 }
diff --git a/plugin/src/main/java/io/lumine/cosmetics/players/Profile.java b/plugin/src/main/java/io/lumine/cosmetics/players/Profile.java
index 877d8b2..d6eeecd 100644
--- a/plugin/src/main/java/io/lumine/cosmetics/players/Profile.java
+++ b/plugin/src/main/java/io/lumine/cosmetics/players/Profile.java
@@ -10,6 +10,7 @@ import io.lumine.cosmetics.storage.sql.SqlStorage;
 import io.lumine.cosmetics.storage.sql.mappings.Keys;
 import io.lumine.cosmetics.storage.sql.mappings.tables.records.ProfileRecord;
 import io.lumine.mythic.bukkit.utils.Schedulers;
+import io.lumine.mythic.bukkit.utils.logging.Log;
 import io.lumine.mythic.bukkit.utils.serialize.Chroma;
 import lombok.Getter;
 import org.bukkit.entity.Player;
@@ -72,7 +73,7 @@ public class Profile implements CosmeticProfile,io.lumine.mythic.bukkit.utils.st
         final var cosmeticData = new ProfileCosmeticData(cosmetic);
         
         equippedCosmetics.put(cosmetic.getType(), cosmeticData);
-        equipped.put(cosmetic.getClass(), new EquippedCosmetic(cosmetic));
+        equipped.put(CosmeticType.get(cosmetic.getType()), new EquippedCosmetic(cosmetic));
         cosmetic.getManager().equip(this);
         
         if(manager.getAdapter() instanceof SqlStorage sqlStorage) {
@@ -90,7 +91,7 @@ public class Profile implements CosmeticProfile,io.lumine.mythic.bukkit.utils.st
         final var cosmeticData = new ProfileCosmeticData(cosmetic);
         
         equippedCosmetics.put(cosmetic.getType(), cosmeticData);
-        equipped.put(cosmetic.getClass(), new EquippedCosmetic(variant));
+        equipped.put(CosmeticType.get(cosmetic.getType()), new EquippedCosmetic(variant));
         cosmetic.getManager().equip(this);
         
         if(manager.getAdapter() instanceof SqlStorage sqlStorage) {
@@ -107,7 +108,7 @@ public class Profile implements CosmeticProfile,io.lumine.mythic.bukkit.utils.st
         final var cosmeticData = new ProfileCosmeticData(cosmetic, color);
         
         equippedCosmetics.put(cosmetic.getType(), cosmeticData);
-        equipped.put(cosmetic.getClass(), new EquippedCosmetic(cosmetic, color));
+        equipped.put(CosmeticType.get(cosmetic.getType()), new EquippedCosmetic(cosmetic, color));
         cosmetic.getManager().equip(this);
         
         if(manager.getAdapter() instanceof SqlStorage sqlStorage) {
@@ -117,7 +118,7 @@ public class Profile implements CosmeticProfile,io.lumine.mythic.bukkit.utils.st
 
     @Override
     public void unequip(Cosmetic cosmetic) {
-        unequip(cosmetic.getClass());
+        unequip(CosmeticType.get(cosmetic.getType()));
     }
     
     @Override
diff --git a/plugin/src/main/java/io/lumine/cosmetics/types/sprays/Spray.java b/plugin/src/main/java/io/lumine/cosmetics/types/sprays/Spray.java
index 6733747..5524a72 100644
--- a/plugin/src/main/java/io/lumine/cosmetics/types/sprays/Spray.java
+++ b/plugin/src/main/java/io/lumine/cosmetics/types/sprays/Spray.java
@@ -3,21 +3,14 @@ package io.lumine.cosmetics.types.sprays;
 import io.lumine.cosmetics.api.players.CosmeticProfile;
 import io.lumine.cosmetics.constants.CosmeticType;
 import io.lumine.cosmetics.types.AbstractCosmetic;
+import io.lumine.mythic.api.packs.Pack;
 import io.lumine.mythic.bukkit.utils.menu.Icon;
 import java.io.File;
 
-import org.bukkit.entity.Player;
+public abstract class Spray extends AbstractCosmetic {
 
-import lombok.Getter;
-
-public class Spray extends AbstractCosmetic {
-
-    @Getter private final SprayImage image;
-    
-	public Spray(SprayManager manager, File file, String key) {
-	    super(manager, file, CosmeticType.type(Spray.class), key);
-
-	    this.image = manager.getSprayImage(key);
+	public Spray(SprayManager manager, Pack pack, File file, String key) {
+	    super(manager, pack, file, CosmeticType.type(Spray.class), key);
 	}
 
 	@Override
@@ -29,9 +22,5 @@ public class Spray extends AbstractCosmetic {
     public Icon<CosmeticProfile> getIcon() {
         return buildIcon("spray");
     }
-    
-    public void use(Player player) {
-        ((SprayManager) getManager()).useSpray(player, this);
-    }
 
 }
diff --git a/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayImage.java b/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayImage.java
index e624846..21f24c3 100644
--- a/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayImage.java
+++ b/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayImage.java
@@ -2,6 +2,7 @@ package io.lumine.cosmetics.types.sprays;
 
 import java.io.File;
 
+import io.lumine.mythic.bukkit.utils.Schedulers;
 import io.lumine.mythic.bukkit.utils.logging.Log;
 import io.lumine.mythic.bukkit.utils.maps.MapImage;
 import lombok.Data;
@@ -16,17 +17,22 @@ public class SprayImage {
     private final File file;
     private final String name;
     private final int mapNumber;
-    private byte[] pixels;
+    private byte[] pixels = null;
     
     public SprayImage(SprayManager sprayManager, File file, int mapNumber) {
         this.manager = sprayManager;
         this.file = file;
         this.name = file.getName().split("\\.")[0];
         this.mapNumber = mapNumber;
-        Log.info("Loaded image {0}", name);
-        MapImage.imageToMapPixels(file, 128).ifPresent(pixels -> {
-            this.pixels = pixels;
-        });
+    }
+
+    public byte[] getPixels() {
+        if(pixels == null) {
+            MapImage.imageToMapPixels(file, MAP_SIZE).ifPresent(pixels -> {
+                this.pixels = pixels;
+            });
+        }
+        return pixels;
     }
 
 }
diff --git a/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayManager.java b/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayManager.java
index a784876..09cd3f5 100644
--- a/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayManager.java
+++ b/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayManager.java
@@ -1,5 +1,6 @@
 package io.lumine.cosmetics.types.sprays;
 
+import io.lumine.cosmetics.types.sprays.types.MapSpray;
 import io.lumine.mythic.api.packs.Pack;
 import io.lumine.mythic.bukkit.utils.Events;
 import io.lumine.mythic.bukkit.utils.Schedulers;
@@ -51,9 +52,6 @@ public class SprayManager extends MCCosmeticsManager<Spray> {
     private final static CooldownMap<UUID> keytapTimer = CooldownMap.create(Cooldown.of(500, TimeUnit.MILLISECONDS));
     
     private final AtomicInteger currentMapId = new AtomicInteger(Integer.MIN_VALUE);
-    
-    private final Map<String,SprayImage> images = Maps.newConcurrentMap();
-
     private final Map<UUID,Integer> activeByPlayer = new ConcurrentHashMap<>(); 
 
     public SprayManager(MCCosmeticsPlugin plugin) {
@@ -64,8 +62,6 @@ public class SprayManager extends MCCosmeticsManager<Spray> {
 
     @Override
     public void load(MCCosmeticsPlugin plugin) {
-        loadSprayImages();
-        
         super.load(plugin);
         
         Events.subscribe(PlayerChangedWorldEvent.class)
@@ -90,7 +86,7 @@ public class SprayManager extends MCCosmeticsManager<Spray> {
 
     @Override
     public Spray build(Pack pack, File file, String node) {
-        return new Spray(this, file, node);
+        return new MapSpray(this, pack, file, node);
     }
 
     @Override
@@ -101,38 +97,10 @@ public class SprayManager extends MCCosmeticsManager<Spray> {
         removeSpray(profile.getPlayer());
     }
 
-    private void loadSprayImages() {
-        images.clear();
-        
-        final Collection<File> files = Lists.newArrayList();
-        final String type = CosmeticType.folder(cosmeticClass);
-        for(var packFolder : plugin.getConfiguration().getPackFolders()) {
-            final File confFolder = new File(packFolder.getAbsolutePath() + System.getProperty("file.separator") + type);
-            if(confFolder.exists() && confFolder.isDirectory()) {
-                files.addAll(Files.getAll(confFolder.getAbsolutePath(), Lists.newArrayList("png", "jpg")));
-            }
-        }
-        
-        for(var file : files) {
-            var img = createSprayImage(file);
-            images.put(img.getName(), img);
-        }
-
-        Log.info("Loaded " + images.size() + " spray images");
-    }
-    
-    private SprayImage createSprayImage(File file) {
-        return new SprayImage(this, file, getNextMapId());
-    }
-
-    private int getNextMapId() {
+    public int getNextMapId() {
         return currentMapId.updateAndGet(id -> (id + 1));
     }
-    
-    public SprayImage getSprayImage(String name) {
-        return images.getOrDefault(name, null);
-    }
-    
+
     public boolean useSpray(Player player) {
         var profile = getPlugin().getProfiles().getProfile(player);
         var maybeSpray = profile.getEquipped(Spray.class);
@@ -144,7 +112,6 @@ public class SprayManager extends MCCosmeticsManager<Spray> {
         }
     }
 
-    
     public boolean useSpray(Player player, Spray spray) {
         final Location location = player.getEyeLocation();
         if(plugin.getWorldGuardSupport() != null) {
@@ -181,8 +148,14 @@ public class SprayManager extends MCCosmeticsManager<Spray> {
         if(REPLACE_SPRAY.get()) {
             removeSpray(player);
         }
-        
-        int eid = ((VolatileSprayHelper) getNMSHelper()).drawSpray(spray, location, face, rotation);
+
+        int eid;
+
+        if(spray instanceof MapSpray mapSpray) {
+            eid = ((VolatileSprayHelper) getNMSHelper()).drawMapSpray(mapSpray, location, face, rotation);
+        } else {
+            return;
+        }
                 
         if(REPLACE_SPRAY.get()) {
             activeByPlayer.put(player.getUniqueId(), eid);
diff --git a/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayMap.java b/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayMap.java
deleted file mode 100644
index 744237a..0000000
--- a/plugin/src/main/java/io/lumine/cosmetics/types/sprays/SprayMap.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package io.lumine.cosmetics.types.sprays;
-
-import java.io.File;
-
-public class SprayMap {
-
-    public SprayMap(SprayManager sprayManager, File file, int nextMapId) {
-
-    }
-
-
-    
-}
diff --git a/plugin/src/main/java/io/lumine/cosmetics/types/sprays/types/MapSpray.java b/plugin/src/main/java/io/lumine/cosmetics/types/sprays/types/MapSpray.java
new file mode 100644
index 0000000..cc5d036
--- /dev/null
+++ b/plugin/src/main/java/io/lumine/cosmetics/types/sprays/types/MapSpray.java
@@ -0,0 +1,67 @@
+package io.lumine.cosmetics.types.sprays.types;
+
+import io.lumine.cosmetics.config.MCCLang;
+import io.lumine.cosmetics.config.Scope;
+import io.lumine.cosmetics.logging.MCLogger;
+import io.lumine.cosmetics.types.sprays.Spray;
+import io.lumine.cosmetics.types.sprays.SprayImage;
+import io.lumine.cosmetics.types.sprays.SprayManager;
+import io.lumine.mythic.api.packs.Pack;
+import io.lumine.mythic.bukkit.utils.config.properties.Property;
+import io.lumine.mythic.bukkit.utils.config.properties.types.StringProp;
+import lombok.Getter;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+
+public class MapSpray extends Spray {
+
+    private static final StringProp IMAGE = Property.String(Scope.NONE, "Texture");
+
+    @Getter private final String imagePath;
+    @Getter private final SprayImage image;
+
+    public MapSpray(SprayManager manager, Pack pack, File file, String key) {
+        super(manager, pack, file, key);
+
+        this.imagePath = MODEL.fget(file, this);
+        this.image = getSprayImage(imagePath);
+
+        if(this.imagePath == null) {
+            MCLogger.error(MCCLang.get("cosmetic.spray.error.no-image-specified", "No image specified for spray {0}", key));
+            return;
+        }
+        if(this.image == null) {
+            MCLogger.error(MCCLang.get("cosmetic.spray.error.image-not-found", "Image {0} for spray {1} was not found", imagePath, key));
+        }
+    }
+
+    public void use(Player player) {
+        if(this.image == null) {
+            MCLogger.error(MCCLang.get("cosmetic.spray.error.image-not-found", "Image {0} for spray {1} was not found", imagePath, key));
+            return;
+        }
+        ((SprayManager) getManager()).useSpray(player, this);
+    }
+
+    protected SprayImage getSprayImage(String key) {
+        final var assetsFolder = mythicPack.getPackFolder("assets");
+        final var texturesFolder = new File(assetsFolder, "textures");
+
+        final var sprayFilePng = new File(texturesFolder, key + ".png");
+        final var sprayFileJpg = new File(texturesFolder, key + ".jpg");
+
+        if (sprayFilePng.exists()) {
+            return createSprayImage(sprayFilePng);
+        } else if (sprayFileJpg.exists()) {
+            return createSprayImage(sprayFileJpg);
+        }
+        return null;
+    }
+
+    private SprayImage createSprayImage(File file) {
+        final var manager = ((SprayManager) getManager());
+        return new SprayImage(manager, file, manager.getNextMapId());
+    }
+
+}
diff --git a/v1_21_R2/src/main/java/io/lumine/cosmetics/nms/v1_21_R2/cosmetic/VolatileSprayImpl.java b/v1_21_R2/src/main/java/io/lumine/cosmetics/nms/v1_21_R2/cosmetic/VolatileSprayImpl.java
index 75e4582..c8df69f 100644
--- a/v1_21_R2/src/main/java/io/lumine/cosmetics/nms/v1_21_R2/cosmetic/VolatileSprayImpl.java
+++ b/v1_21_R2/src/main/java/io/lumine/cosmetics/nms/v1_21_R2/cosmetic/VolatileSprayImpl.java
@@ -1,9 +1,9 @@
 package io.lumine.cosmetics.nms.v1_21_R2.cosmetic;
 
 import io.lumine.cosmetics.MCCosmeticsPlugin;
-import io.lumine.cosmetics.types.sprays.Spray;
 import io.lumine.cosmetics.nms.VolatileCodeEnabled_v1_21_R2;
 import io.lumine.cosmetics.nms.cosmetic.VolatileSprayHelper;
+import io.lumine.cosmetics.types.sprays.types.MapSpray;
 import lombok.Getter;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
@@ -35,7 +35,7 @@ public class VolatileSprayImpl implements VolatileSprayHelper {
     private static final MapMeta mapMeta = (MapMeta) map.getItemMeta();
     
     @Override
-    public int drawSpray(Spray spray, Location location, BlockFace face, int rotation) {
+    public int drawMapSpray(MapSpray spray, Location location, BlockFace face, int rotation) {
         var world = ((CraftWorld) location.getWorld()).getHandle();
         var pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
 
diff --git a/v1_21_R3/src/main/java/io/lumine/cosmetics/nms/v1_21_R3/cosmetic/VolatileSprayImpl.java b/v1_21_R3/src/main/java/io/lumine/cosmetics/nms/v1_21_R3/cosmetic/VolatileSprayImpl.java
index c3fa7ee..19f11e0 100644
--- a/v1_21_R3/src/main/java/io/lumine/cosmetics/nms/v1_21_R3/cosmetic/VolatileSprayImpl.java
+++ b/v1_21_R3/src/main/java/io/lumine/cosmetics/nms/v1_21_R3/cosmetic/VolatileSprayImpl.java
@@ -4,6 +4,7 @@ import io.lumine.cosmetics.MCCosmeticsPlugin;
 import io.lumine.cosmetics.types.sprays.Spray;
 import io.lumine.cosmetics.nms.VolatileCodeEnabled_v1_21_R3;
 import io.lumine.cosmetics.nms.cosmetic.VolatileSprayHelper;
+import io.lumine.cosmetics.types.sprays.types.MapSpray;
 import lombok.Getter;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
@@ -35,7 +36,7 @@ public class VolatileSprayImpl implements VolatileSprayHelper {
     private static final MapMeta mapMeta = (MapMeta) map.getItemMeta();
     
     @Override
-    public int drawSpray(Spray spray, Location location, BlockFace face, int rotation) {
+    public int drawMapSpray(MapSpray spray, Location location, BlockFace face, int rotation) {
         var world = ((CraftWorld) location.getWorld()).getHandle();
         var pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
 
-- 
GitLab