Browse Source

Furnace ownership tweaks

nossr50 5 years ago
parent
commit
38122d8f17
17 changed files with 236 additions and 110 deletions
  1. 2 1
      Changelog.txt
  2. 20 0
      src/main/java/com/gmail/nossr50/datatypes/meta/UUIDMeta.java
  3. 1 4
      src/main/java/com/gmail/nossr50/listeners/BlockListener.java
  4. 2 5
      src/main/java/com/gmail/nossr50/listeners/InventoryListener.java
  5. 0 23
      src/main/java/com/gmail/nossr50/runnables/skills/FurnaceCleanupTask.java
  6. 0 16
      src/main/java/com/gmail/nossr50/skills/smelting/Smelting.java
  7. 23 17
      src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java
  8. 2 1
      src/main/java/com/gmail/nossr50/util/compat/CompatibilityType.java
  9. 0 7
      src/main/java/com/gmail/nossr50/util/compat/layers/AbstractCompatibilityLayer.java
  10. 30 0
      src/main/java/com/gmail/nossr50/util/compat/layers/AbstractNMSCompatibilityLayer.java
  11. 1 1
      src/main/java/com/gmail/nossr50/util/compat/layers/attackcooldown/DummyPlayerAttackCooldownExploitPreventionLayer.java
  12. 3 2
      src/main/java/com/gmail/nossr50/util/compat/layers/attackcooldown/PlayerAttackCooldownExploitPreventionLayer.java
  13. 1 1
      src/main/java/com/gmail/nossr50/util/compat/layers/attackcooldown/PlayerAttackCooldownMethods.java
  14. 19 0
      src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/AbstractPersistentDataLayer.java
  15. 60 0
      src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotPersistentDataLayer.java
  16. 44 0
      src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotTemporaryDataLayer.java
  17. 28 32
      src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java

+ 2 - 1
Changelog.txt

@@ -1,5 +1,6 @@
 Version 2.1.136
 Version 2.1.136
-    Furnace ownership was made more reliable
+    Furnace ownership is no longer lost when the furnace stops doing a job
+    Furnaces remember owners between restarts (requires MC 1.14 or higher)
 
 
 Version 2.1.135
 Version 2.1.135
     Furnaces no longer simulate block break checks when assigning ownership as it caused some unwanted plugin conflicts
     Furnaces no longer simulate block break checks when assigning ownership as it caused some unwanted plugin conflicts

+ 20 - 0
src/main/java/com/gmail/nossr50/datatypes/meta/UUIDMeta.java

@@ -0,0 +1,20 @@
+package com.gmail.nossr50.datatypes.meta;
+
+import org.bukkit.metadata.FixedMetadataValue;
+import org.bukkit.plugin.Plugin;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+public class UUIDMeta extends FixedMetadataValue {
+    /**
+     * Initializes a FixedMetadataValue with an Object
+     *
+     * @param owningPlugin the {@link Plugin} that created this metadata value
+     * @param value        the value assigned to this metadata value
+     */
+    public UUIDMeta(@NotNull Plugin owningPlugin, @Nullable UUID value) {
+        super(owningPlugin, value);
+    }
+}

+ 1 - 4
src/main/java/com/gmail/nossr50/listeners/BlockListener.java

@@ -18,7 +18,6 @@ import com.gmail.nossr50.skills.herbalism.HerbalismManager;
 import com.gmail.nossr50.skills.mining.MiningManager;
 import com.gmail.nossr50.skills.mining.MiningManager;
 import com.gmail.nossr50.skills.repair.Repair;
 import com.gmail.nossr50.skills.repair.Repair;
 import com.gmail.nossr50.skills.salvage.Salvage;
 import com.gmail.nossr50.skills.salvage.Salvage;
-import com.gmail.nossr50.skills.smelting.Smelting;
 import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
 import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
 import com.gmail.nossr50.util.BlockUtils;
 import com.gmail.nossr50.util.BlockUtils;
 import com.gmail.nossr50.util.EventUtils;
 import com.gmail.nossr50.util.EventUtils;
@@ -39,10 +38,8 @@ import org.bukkit.event.EventPriority;
 import org.bukkit.event.Listener;
 import org.bukkit.event.Listener;
 import org.bukkit.event.block.*;
 import org.bukkit.event.block.*;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
-import org.bukkit.metadata.MetadataValue;
 
 
 import java.util.HashSet;
 import java.util.HashSet;
-import java.util.List;
 
 
 public class BlockListener implements Listener {
 public class BlockListener implements Listener {
     private final mcMMO plugin;
     private final mcMMO plugin;
@@ -666,7 +663,7 @@ public class BlockListener implements Listener {
                 if(mcMMO.getSmeltingTracker().isFurnaceOwned(furnace))
                 if(mcMMO.getSmeltingTracker().isFurnaceOwned(furnace))
                 {
                 {
                     player.sendMessage("[mcMMO DEBUG] This furnace has a registered owner");
                     player.sendMessage("[mcMMO DEBUG] This furnace has a registered owner");
-                    OfflinePlayer furnacePlayer = mcMMO.getSmeltingTracker().getPlayerFromFurnace(furnace);
+                    OfflinePlayer furnacePlayer = mcMMO.getSmeltingTracker().getFurnaceOwner(furnace);
                     if(furnacePlayer != null)
                     if(furnacePlayer != null)
                     {
                     {
                         player.sendMessage("[mcMMO DEBUG] This furnace is owned by player "+furnacePlayer.getName());
                         player.sendMessage("[mcMMO DEBUG] This furnace is owned by player "+furnacePlayer.getName());

+ 2 - 5
src/main/java/com/gmail/nossr50/listeners/InventoryListener.java

@@ -8,7 +8,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.events.fake.FakeBrewEvent;
 import com.gmail.nossr50.events.fake.FakeBrewEvent;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask;
 import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask;
-import com.gmail.nossr50.runnables.skills.FurnaceCleanupTask;
 import com.gmail.nossr50.skills.alchemy.Alchemy;
 import com.gmail.nossr50.skills.alchemy.Alchemy;
 import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
 import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
 import com.gmail.nossr50.util.ItemUtils;
 import com.gmail.nossr50.util.ItemUtils;
@@ -56,7 +55,7 @@ public class InventoryListener implements Listener {
 
 
         Furnace furnace = (Furnace) furnaceState;
         Furnace furnace = (Furnace) furnaceState;
 
 
-        OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getPlayerFromFurnace(furnace);
+        OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getFurnaceOwner(furnace);
 
 
         if(offlinePlayer != null && offlinePlayer.isOnline()) {
         if(offlinePlayer != null && offlinePlayer.isOnline()) {
 
 
@@ -94,7 +93,7 @@ public class InventoryListener implements Listener {
 
 
         if(blockState instanceof Furnace) {
         if(blockState instanceof Furnace) {
             Furnace furnace = (Furnace) blockState;
             Furnace furnace = (Furnace) blockState;
-            OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getPlayerFromFurnace(furnace);
+            OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getFurnaceOwner(furnace);
 
 
             if(offlinePlayer != null) {
             if(offlinePlayer != null) {
 
 
@@ -105,8 +104,6 @@ public class InventoryListener implements Listener {
                     event.setResult(offlineProfile.getSmeltingManager().smeltProcessing(smelting, event.getResult()));
                     event.setResult(offlineProfile.getSmeltingManager().smeltProcessing(smelting, event.getResult()));
                 }
                 }
             }
             }
-
-            new FurnaceCleanupTask(furnace).runTaskLater(mcMMO.p, 1);
         }
         }
     }
     }
 
 

+ 0 - 23
src/main/java/com/gmail/nossr50/runnables/skills/FurnaceCleanupTask.java

@@ -1,23 +0,0 @@
-package com.gmail.nossr50.runnables.skills;
-
-import com.gmail.nossr50.mcMMO;
-import org.bukkit.block.Furnace;
-import org.bukkit.scheduler.BukkitRunnable;
-
-public class FurnaceCleanupTask extends BukkitRunnable {
-
-    private final Furnace furnace;
-
-    public FurnaceCleanupTask(Furnace furnace) {
-        this.furnace = furnace;
-    }
-
-    @Override
-    public void run() {
-        if(furnace != null
-                && furnace.getInventory().getSmelting() == null) {
-            //Furnace is empty so stop tracking it
-            mcMMO.getSmeltingTracker().untrackFurnace(furnace);
-        }
-    }
-}

+ 0 - 16
src/main/java/com/gmail/nossr50/skills/smelting/Smelting.java

@@ -2,24 +2,8 @@ package com.gmail.nossr50.skills.smelting;
 
 
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
-import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.util.EventUtils;
-import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.player.UserManager;
-import com.gmail.nossr50.util.skills.RankUtils;
-import org.bukkit.Bukkit;
-import org.bukkit.OfflinePlayer;
-import org.bukkit.block.Furnace;
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.FurnaceInventory;
-import org.bukkit.inventory.Inventory;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
-import org.bukkit.metadata.MetadataValue;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.HashMap;
-import java.util.List;
 
 
 public class Smelting {
 public class Smelting {
 
 

+ 23 - 17
src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java

@@ -3,7 +3,10 @@ package com.gmail.nossr50.util.compat;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
-import com.gmail.nossr50.util.compat.layers.PlayerAttackCooldownExploitPreventionLayer;
+import com.gmail.nossr50.util.compat.layers.attackcooldown.PlayerAttackCooldownExploitPreventionLayer;
+import com.gmail.nossr50.util.compat.layers.persistentdata.AbstractPersistentDataLayer;
+import com.gmail.nossr50.util.compat.layers.persistentdata.SpigotPersistentDataLayer;
+import com.gmail.nossr50.util.compat.layers.persistentdata.SpigotTemporaryDataLayer;
 import com.gmail.nossr50.util.nms.NMSVersion;
 import com.gmail.nossr50.util.nms.NMSVersion;
 import com.gmail.nossr50.util.platform.MinecraftGameVersion;
 import com.gmail.nossr50.util.platform.MinecraftGameVersion;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
@@ -24,6 +27,7 @@ public class CompatibilityManager {
 
 
     /* Compatibility Layers */
     /* Compatibility Layers */
     private PlayerAttackCooldownExploitPreventionLayer playerAttackCooldownExploitPreventionLayer;
     private PlayerAttackCooldownExploitPreventionLayer playerAttackCooldownExploitPreventionLayer;
+    private AbstractPersistentDataLayer persistentDataLayer;
 
 
     public CompatibilityManager(MinecraftGameVersion minecraftGameVersion) {
     public CompatibilityManager(MinecraftGameVersion minecraftGameVersion) {
         mcMMO.p.getLogger().info("Loading compatibility layers...");
         mcMMO.p.getLogger().info("Loading compatibility layers...");
@@ -42,6 +46,10 @@ public class CompatibilityManager {
         supportedLayers = new HashMap<>(); //Init map
         supportedLayers = new HashMap<>(); //Init map
 
 
         for(CompatibilityType compatibilityType : CompatibilityType.values()) {
         for(CompatibilityType compatibilityType : CompatibilityType.values()) {
+            //TODO: Remove later
+            if(compatibilityType == CompatibilityType.PLAYER_ATTACK_COOLDOWN_EXPLOIT_PREVENTION)
+                continue;
+
             supportedLayers.put(compatibilityType, false); //All layers are set to false when initialized
             supportedLayers.put(compatibilityType, false); //All layers are set to false when initialized
         }
         }
     }
     }
@@ -51,26 +59,21 @@ public class CompatibilityManager {
      * For any unsupported layers, load a dummy layer
      * For any unsupported layers, load a dummy layer
      */
      */
     private void initCompatibilityLayers() {
     private void initCompatibilityLayers() {
-        isFullyCompatibleServerSoftware = true;
+        initPersistentDataLayer();
 
 
-//        if(nmsVersion == NMSVersion.UNSUPPORTED) {
-//            mcMMO.p.getLogger().info("NMS not supported for this version of Minecraft, possible solutions include updating mcMMO or updating your server software. NMS Support is not available on every version of Minecraft.");
-//            mcMMO.p.getLogger().info("Certain features of mcMMO that require NMS will be disabled, you can check what is disabled by running the /mmocompat command!");
-//            //Load dummy compatibility layers
-//            isFullyCompatibleServerSoftware = false;
-//            loadDummyCompatibilityLayers();
-//        } else {
-//            playerAttackCooldownExploitPreventionLayer = new PlayerAttackCooldownExploitPreventionLayer(nmsVersion);
-//
-//            //Mark as operational
-//            if(playerAttackCooldownExploitPreventionLayer.noErrorsOnInitialize()) {
-//                supportedLayers.put(CompatibilityType.PLAYER_ATTACK_COOLDOWN_EXPLOIT_PREVENTION, true);
-//            }
-//        }
+        isFullyCompatibleServerSoftware = true;
     }
     }
 
 
-    private void loadDummyCompatibilityLayers() {
+    private void initPersistentDataLayer() {
+        if(minecraftGameVersion.getMinorVersion().asInt() >= 14 || minecraftGameVersion.getMajorVersion().asInt() >= 2) {
+
+            persistentDataLayer = new SpigotPersistentDataLayer();
+        } else {
+
+            persistentDataLayer = new SpigotTemporaryDataLayer();
+        }
 
 
+        supportedLayers.put(CompatibilityType.PERSISTENT_DATA, true);
     }
     }
 
 
     //TODO: move to text manager
     //TODO: move to text manager
@@ -128,4 +131,7 @@ public class CompatibilityManager {
         return playerAttackCooldownExploitPreventionLayer;
         return playerAttackCooldownExploitPreventionLayer;
     }
     }
 
 
+    public AbstractPersistentDataLayer getPersistentDataLayer() {
+        return persistentDataLayer;
+    }
 }
 }

+ 2 - 1
src/main/java/com/gmail/nossr50/util/compat/CompatibilityType.java

@@ -1,5 +1,6 @@
 package com.gmail.nossr50.util.compat;
 package com.gmail.nossr50.util.compat;
 
 
 public enum CompatibilityType {
 public enum CompatibilityType {
-    PLAYER_ATTACK_COOLDOWN_EXPLOIT_PREVENTION
+    PLAYER_ATTACK_COOLDOWN_EXPLOIT_PREVENTION,
+    PERSISTENT_DATA
 }
 }

+ 0 - 7
src/main/java/com/gmail/nossr50/util/compat/layers/AbstractCompatibilityLayer.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.util.compat.layers;
 package com.gmail.nossr50.util.compat.layers;
 
 
 import com.gmail.nossr50.util.compat.CompatibilityLayer;
 import com.gmail.nossr50.util.compat.CompatibilityLayer;
-import com.gmail.nossr50.util.nms.NMSVersion;
-import org.jetbrains.annotations.NotNull;
 
 
 /**
 /**
  *
  *
@@ -13,11 +11,6 @@ import org.jetbrains.annotations.NotNull;
 public abstract class AbstractCompatibilityLayer implements CompatibilityLayer {
 public abstract class AbstractCompatibilityLayer implements CompatibilityLayer {
 
 
     protected boolean noErrorsOnInitialize = true;
     protected boolean noErrorsOnInitialize = true;
-    protected final @NotNull NMSVersion nmsVersion;
-
-    public AbstractCompatibilityLayer(@NotNull NMSVersion nmsVersion) {
-        this.nmsVersion = nmsVersion;
-    }
 
 
     /**
     /**
      * Initialize the CompatibilityLayer
      * Initialize the CompatibilityLayer

+ 30 - 0
src/main/java/com/gmail/nossr50/util/compat/layers/AbstractNMSCompatibilityLayer.java

@@ -0,0 +1,30 @@
+package com.gmail.nossr50.util.compat.layers;
+
+import com.gmail.nossr50.util.nms.NMSVersion;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ *
+ * These classes are a band-aid solution for adding NMS support into 2.1.XXX
+ * In 2.2 we are switching to modules and that will clean things up significantly
+ *
+ */
+public abstract class AbstractNMSCompatibilityLayer extends AbstractCompatibilityLayer {
+
+    protected final @NotNull NMSVersion nmsVersion;
+
+    public AbstractNMSCompatibilityLayer(@NotNull NMSVersion nmsVersion) {
+        this.nmsVersion = nmsVersion;
+    }
+
+    /**
+     * Initialize the CompatibilityLayer
+     * @return true if the CompatibilityLayer initialized and should be functional
+     */
+    public abstract boolean initializeLayer();
+
+    @Override
+    public boolean noErrorsOnInitialize() {
+        return noErrorsOnInitialize;
+    }
+}

+ 1 - 1
src/main/java/com/gmail/nossr50/util/compat/layers/DummyPlayerAttackCooldownExploitPreventionLayer.java → src/main/java/com/gmail/nossr50/util/compat/layers/attackcooldown/DummyPlayerAttackCooldownExploitPreventionLayer.java

@@ -1,4 +1,4 @@
-package com.gmail.nossr50.util.compat.layers;
+package com.gmail.nossr50.util.compat.layers.attackcooldown;
 
 
 import com.gmail.nossr50.util.nms.NMSVersion;
 import com.gmail.nossr50.util.nms.NMSVersion;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;

+ 3 - 2
src/main/java/com/gmail/nossr50/util/compat/layers/PlayerAttackCooldownExploitPreventionLayer.java → src/main/java/com/gmail/nossr50/util/compat/layers/attackcooldown/PlayerAttackCooldownExploitPreventionLayer.java

@@ -1,6 +1,7 @@
-package com.gmail.nossr50.util.compat.layers;
+package com.gmail.nossr50.util.compat.layers.attackcooldown;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.util.compat.layers.AbstractNMSCompatibilityLayer;
 import com.gmail.nossr50.util.nms.NMSConstants;
 import com.gmail.nossr50.util.nms.NMSConstants;
 import com.gmail.nossr50.util.nms.NMSVersion;
 import com.gmail.nossr50.util.nms.NMSVersion;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
@@ -16,7 +17,7 @@ import java.lang.reflect.Method;
  * In 2.2 we are switching to modules and that will clean things up significantly
  * In 2.2 we are switching to modules and that will clean things up significantly
  *
  *
  */
  */
-public class PlayerAttackCooldownExploitPreventionLayer extends AbstractCompatibilityLayer implements PlayerAttackCooldownMethods{
+public class PlayerAttackCooldownExploitPreventionLayer extends AbstractNMSCompatibilityLayer implements PlayerAttackCooldownMethods{
 
 
     private final String cbNMSVersionPath;
     private final String cbNMSVersionPath;
 
 

+ 1 - 1
src/main/java/com/gmail/nossr50/util/compat/layers/PlayerAttackCooldownMethods.java → src/main/java/com/gmail/nossr50/util/compat/layers/attackcooldown/PlayerAttackCooldownMethods.java

@@ -1,4 +1,4 @@
-package com.gmail.nossr50.util.compat.layers;
+package com.gmail.nossr50.util.compat.layers.attackcooldown;
 
 
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 
 

+ 19 - 0
src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/AbstractPersistentDataLayer.java

@@ -0,0 +1,19 @@
+package com.gmail.nossr50.util.compat.layers.persistentdata;
+
+import com.gmail.nossr50.util.compat.layers.AbstractCompatibilityLayer;
+import org.bukkit.block.Furnace;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+public abstract class AbstractPersistentDataLayer extends AbstractCompatibilityLayer {
+
+    public AbstractPersistentDataLayer() {
+        initializeLayer();
+    }
+
+    public abstract @Nullable UUID getFurnaceOwner(Furnace furnace);
+
+    public abstract void setFurnaceOwner(Furnace furnace, UUID uuid);
+
+}

+ 60 - 0
src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotPersistentDataLayer.java

@@ -0,0 +1,60 @@
+package com.gmail.nossr50.util.compat.layers.persistentdata;
+
+import com.gmail.nossr50.mcMMO;
+import org.bukkit.Bukkit;
+import org.bukkit.NamespacedKey;
+import org.bukkit.block.Furnace;
+import org.bukkit.persistence.PersistentDataContainer;
+import org.bukkit.persistence.PersistentDataHolder;
+import org.bukkit.persistence.PersistentDataType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+public class SpigotPersistentDataLayer extends AbstractPersistentDataLayer {
+
+    private NamespacedKey furnaceOwner_MostSig_Key;
+    private NamespacedKey furnaceOwner_LeastSig_Key;
+
+    @Override
+    public boolean initializeLayer() {
+        initNamespacedKeys();
+        return true;
+    }
+
+    private void initNamespacedKeys() {
+        furnaceOwner_MostSig_Key = getNamespacedKey("furnace_uuid_most_sig");
+        furnaceOwner_LeastSig_Key = getNamespacedKey("furnace_uuid_least_sig");
+    }
+
+    @NotNull
+    public NamespacedKey getNamespacedKey(String key) {
+        return new NamespacedKey(mcMMO.p, key);
+    }
+
+    @Override
+    public @Nullable UUID getFurnaceOwner(Furnace furnace) {
+        //Get container from entity
+        PersistentDataContainer dataContainer = ((PersistentDataHolder) furnace).getPersistentDataContainer();
+
+        Long mostSigBits = dataContainer.get(furnaceOwner_MostSig_Key, PersistentDataType.LONG);
+        Long leastSigBits = dataContainer.get(furnaceOwner_LeastSig_Key, PersistentDataType.LONG);
+
+        if(mostSigBits != null && leastSigBits != null) {
+            return new UUID(mostSigBits, leastSigBits);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void setFurnaceOwner(Furnace furnace, UUID uuid) {
+        PersistentDataContainer dataContainer = ((PersistentDataHolder) furnace).getPersistentDataContainer();
+
+        dataContainer.set(furnaceOwner_MostSig_Key, PersistentDataType.LONG, uuid.getMostSignificantBits());
+        dataContainer.set(furnaceOwner_LeastSig_Key, PersistentDataType.LONG, uuid.getLeastSignificantBits());
+
+        furnace.update();
+    }
+}

+ 44 - 0
src/main/java/com/gmail/nossr50/util/compat/layers/persistentdata/SpigotTemporaryDataLayer.java

@@ -0,0 +1,44 @@
+package com.gmail.nossr50.util.compat.layers.persistentdata;
+
+import com.gmail.nossr50.datatypes.meta.UUIDMeta;
+import com.gmail.nossr50.mcMMO;
+import org.bukkit.block.Furnace;
+import org.bukkit.metadata.Metadatable;
+
+import java.util.UUID;
+
+/**
+ * Persistent Data API is unavailable
+ */
+public class SpigotTemporaryDataLayer extends AbstractPersistentDataLayer {
+
+    private final String FURNACE_OWNER_METADATA_KEY = "mcMMO_furnace_owner";
+
+    @Override
+    public boolean initializeLayer() {
+        return true;
+    }
+
+    @Override
+    public UUID getFurnaceOwner(Furnace furnace) {
+        Metadatable metadatable = (Metadatable) furnace;
+
+        if(metadatable.getMetadata(FURNACE_OWNER_METADATA_KEY).size() > 0) {
+            UUIDMeta uuidMeta = (UUIDMeta) metadatable.getMetadata(FURNACE_OWNER_METADATA_KEY).get(0);
+            return (UUID) uuidMeta.value();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void setFurnaceOwner(Furnace furnace, UUID uuid) {
+        Metadatable metadatable = (Metadatable) furnace;
+
+        if(metadatable.getMetadata(FURNACE_OWNER_METADATA_KEY).size() > 0) {
+            metadatable.removeMetadata(FURNACE_OWNER_METADATA_KEY, mcMMO.p);
+        }
+
+        metadatable.setMetadata(FURNACE_OWNER_METADATA_KEY, new UUIDMeta(mcMMO.p, uuid));
+    }
+}

+ 28 - 32
src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java

@@ -3,8 +3,6 @@ package com.gmail.nossr50.util.skills;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.skills.smelting.Smelting;
-import com.gmail.nossr50.util.EventUtils;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 import org.bukkit.Bukkit;
 import org.bukkit.Bukkit;
@@ -16,15 +14,11 @@ import org.bukkit.inventory.FurnaceInventory;
 import org.bukkit.inventory.Inventory;
 import org.bukkit.inventory.Inventory;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.Nullable;
 
 
-import java.util.HashMap;
+import java.util.UUID;
 
 
 public class SmeltingTracker {
 public class SmeltingTracker {
 
 
-    private final HashMap<Furnace, OfflinePlayer> furnaceOwners;
-
-    public SmeltingTracker() {
-        furnaceOwners = new HashMap<>();
-    }
+//    private final HashMap<Furnace, OfflinePlayer> furnaceOwners;
 
 
     private void changeFurnaceOwnership(Furnace furnace, Player player) {
     private void changeFurnaceOwnership(Furnace furnace, Player player) {
 
 
@@ -37,7 +31,11 @@ public class SmeltingTracker {
 
 
         printOwnershipLossDebug(furnace);
         printOwnershipLossDebug(furnace);
 
 
-        furnaceOwners.put(furnace, player);
+        setFurnaceOwner(furnace, player);
+    }
+
+    private void setFurnaceOwner(Furnace furnace, Player player) {
+        mcMMO.getCompatibilityManager().getPersistentDataLayer().setFurnaceOwner(furnace, player.getUniqueId());
     }
     }
 
 
     private void printOwnershipGainDebug(Furnace furnace, McMMOPlayer mcMMOPlayer) {
     private void printOwnershipGainDebug(Furnace furnace, McMMOPlayer mcMMOPlayer) {
@@ -52,23 +50,31 @@ public class SmeltingTracker {
     }
     }
 
 
     private void printOwnershipLossDebug(Furnace furnace) {
     private void printOwnershipLossDebug(Furnace furnace) {
-        if(furnaceOwners.get(furnace) != null) {
-            OfflinePlayer furnaceOwner = furnaceOwners.get(furnace);
-
-            if(furnaceOwner.isOnline()) {
-                McMMOPlayer furnaceOwnerProfile = UserManager.getPlayer(furnaceOwner.getPlayer());
-
-                if(furnaceOwnerProfile != null) {
-                    if(furnaceOwnerProfile.isDebugMode()) {
-                        furnaceOwnerProfile.getPlayer().sendMessage("Furnace ownership " +
-                                ChatColor.RED + "lost " + ChatColor.RESET +
-                                "at location: " + furnace.getLocation().toString());
-                    }
+        OfflinePlayer furnaceOwner = getFurnaceOwner(furnace);
+
+        if(furnaceOwner != null && furnaceOwner.isOnline()) {
+            McMMOPlayer furnaceOwnerProfile = UserManager.getPlayer(furnaceOwner.getPlayer());
+
+            if(furnaceOwnerProfile != null) {
+                if(furnaceOwnerProfile.isDebugMode()) {
+                    furnaceOwnerProfile.getPlayer().sendMessage("Furnace ownership " +
+                            ChatColor.RED + "lost " + ChatColor.RESET +
+                            "at location: " + furnace.getLocation().toString());
                 }
                 }
             }
             }
         }
         }
     }
     }
 
 
+    public @Nullable OfflinePlayer getFurnaceOwner(Furnace furnace) {
+        UUID uuid = mcMMO.getCompatibilityManager().getPersistentDataLayer().getFurnaceOwner(furnace);
+
+        if(uuid != null) {
+            return Bukkit.getOfflinePlayer(uuid);
+        } else {
+            return null;
+        }
+    }
+
     @Nullable
     @Nullable
     public Furnace getFurnaceFromInventory(Inventory inventory) {
     public Furnace getFurnaceFromInventory(Inventory inventory) {
         if (!(inventory instanceof FurnaceInventory)) {
         if (!(inventory instanceof FurnaceInventory)) {
@@ -78,13 +84,8 @@ public class SmeltingTracker {
         return (Furnace) inventory.getHolder();
         return (Furnace) inventory.getHolder();
     }
     }
 
 
-    @Nullable
-    public OfflinePlayer getPlayerFromFurnace(Furnace furnace) {
-        return furnaceOwners.get(furnace);
-    }
-
     public boolean isFurnaceOwned(Furnace furnace) {
     public boolean isFurnaceOwned(Furnace furnace) {
-        return furnaceOwners.get(furnace) != null;
+        return getFurnaceOwner(furnace) != null;
     }
     }
 
 
     public void processFurnaceOwnership(Furnace furnace, Player player) {
     public void processFurnaceOwnership(Furnace furnace, Player player) {
@@ -93,9 +94,4 @@ public class SmeltingTracker {
 
 
         changeFurnaceOwnership(furnace, player);
         changeFurnaceOwnership(furnace, player);
     }
     }
-
-    public void untrackFurnace(Furnace furnace) {
-        printOwnershipLossDebug(furnace);
-        furnaceOwners.remove(furnace);
-    }
 }
 }