diff --git a/.gradle/8.8/checksums/checksums.lock b/.gradle/8.8/checksums/checksums.lock index 07ca503..5a1120c 100644 Binary files a/.gradle/8.8/checksums/checksums.lock and b/.gradle/8.8/checksums/checksums.lock differ diff --git a/.gradle/8.8/executionHistory/executionHistory.bin b/.gradle/8.8/executionHistory/executionHistory.bin index 71f9e97..a1af76c 100644 Binary files a/.gradle/8.8/executionHistory/executionHistory.bin and b/.gradle/8.8/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.8/executionHistory/executionHistory.lock b/.gradle/8.8/executionHistory/executionHistory.lock index bf8b0e4..3d7bdde 100644 Binary files a/.gradle/8.8/executionHistory/executionHistory.lock and b/.gradle/8.8/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.8/fileHashes/fileHashes.bin b/.gradle/8.8/fileHashes/fileHashes.bin index 2f68423..b92adb4 100644 Binary files a/.gradle/8.8/fileHashes/fileHashes.bin and b/.gradle/8.8/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock index 182eb95..2022636 100644 Binary files a/.gradle/8.8/fileHashes/fileHashes.lock and b/.gradle/8.8/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.8/fileHashes/resourceHashesCache.bin b/.gradle/8.8/fileHashes/resourceHashesCache.bin index da2c5a1..ce098b5 100644 Binary files a/.gradle/8.8/fileHashes/resourceHashesCache.bin and b/.gradle/8.8/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index fde4444..a0e16bd 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin index 45a82f4..32aaaa5 100644 Binary files a/build/tmp/compileJava/previous-compilation-data.bin and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/src/main/java/me/trouper/armorsmp/data/ArmorTier.java b/src/main/java/me/trouper/armorsmp/data/ArmorTier.java index e25281d..7834f25 100644 --- a/src/main/java/me/trouper/armorsmp/data/ArmorTier.java +++ b/src/main/java/me/trouper/armorsmp/data/ArmorTier.java @@ -8,8 +8,6 @@ import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import java.util.function.Consumer; - public enum ArmorTier { NONE(0, new ItemStack(Material.AIR), @@ -146,7 +144,7 @@ public enum ArmorTier { if (value.getLeggings().getType().equals(p.getInventory().getLeggings().getType())) return value; if (value.getBoots().getType().equals(p.getInventory().getBoots().getType())) return value; } - return ArmorSMP.getInstance().getManager().armor.getTier(p); + return ArmorSMP.getInstance().getManager().tiers.getTier(p); } public int getNumeric() { diff --git a/src/main/java/me/trouper/armorsmp/data/Unique.java b/src/main/java/me/trouper/armorsmp/data/Unique.java index 6673dd3..7afd006 100644 --- a/src/main/java/me/trouper/armorsmp/data/Unique.java +++ b/src/main/java/me/trouper/armorsmp/data/Unique.java @@ -7,7 +7,7 @@ import me.trouper.armorsmp.ArmorSMP; import me.trouper.armorsmp.utils.Display; import me.trouper.armorsmp.utils.Text; import me.trouper.armorsmp.utils.Verbose; -import me.trouper.armorsmp.utils.WorldUtils; +import me.trouper.armorsmp.utils.ItemUtils; import org.bukkit.*; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.*; @@ -41,7 +41,7 @@ public enum Unique { p.addPotionEffect(new PotionEffect(PotionEffectType.HEALTH_BOOST,25,2,true,false,false)); }, (p) -> { }, 50), - CHESTPLATE(ItemBuilder.create() + DRAGON_EGG(ItemBuilder.create() .material(Material.NETHERITE_CHESTPLATE) .lore(Text.legacyColor("&bAbilities:")) .lore(Text.legacyColor("&3| &7Dragon's Breath")) @@ -216,24 +216,29 @@ public enum Unique { } public static boolean isUnique(ItemStack i) { + if (i == null) return false; for (Unique value : values()) { - if (WorldUtils.isSimilar(value.getInGameItem(),i)) return true; + if (ItemUtils.isSimilar(value.getInGameItem(),i)) return true; if (i.getType().equals(Material.DRAGON_EGG)) return true; } return false; } + + public static boolean isArmor(Unique unique) { + return ItemUtils.isArmor(unique.getInGameItem()); + } public static Unique matchUnique(ItemStack i) { Verbose.send("Matching Unique, Item Type: %s",i.getType()); Unique match = null; for (Unique value : values()) { - if (WorldUtils.isSimilar(value.getInGameItem(),i)) { + if (ItemUtils.isSimilar(value.getInGameItem(),i)) { match = value; Verbose.send("Matched with, Unique: %s",match); } } if (i.getType().equals(Material.DRAGON_EGG)) { - match = Unique.CHESTPLATE; + match = Unique.DRAGON_EGG; Verbose.send("Matched with dragon egg: Unique: %s",match); } return match; diff --git a/src/main/java/me/trouper/armorsmp/server/Manager.java b/src/main/java/me/trouper/armorsmp/server/Manager.java index cf822d8..6d0f95c 100644 --- a/src/main/java/me/trouper/armorsmp/server/Manager.java +++ b/src/main/java/me/trouper/armorsmp/server/Manager.java @@ -8,20 +8,17 @@ import me.trouper.armorsmp.server.commands.TipsCommand; import me.trouper.armorsmp.server.commands.TrustCommand; import me.trouper.armorsmp.server.crafting.ArmorUpgrade; import me.trouper.armorsmp.server.events.*; -import me.trouper.armorsmp.server.systems.ArmorBackend; -import me.trouper.armorsmp.server.systems.Broadcaster; -import me.trouper.armorsmp.server.systems.TrustBackend; -import me.trouper.armorsmp.server.systems.UniquesBackend; +import me.trouper.armorsmp.server.systems.*; import org.bukkit.Bukkit; public class Manager { // My systems public IO io; - - public ArmorBackend armor; + public TrustBackend trust; - public UniquesBackend uniques; + public TierBackend tiers; public Broadcaster broadcaster; + public UniquesBackend uniques; public Manager() { io = new IO(); @@ -30,17 +27,19 @@ public class Manager { public void init() { io.loadAll(); - armor = new ArmorBackend(); + trust = new TrustBackend(); - uniques = new UniquesBackend(); + tiers = new TierBackend(); + //uniques = new UniquesBackend(); broadcaster = new Broadcaster(); + uniques = new UniquesBackend(); registerCommands(); registerEvents(); registerCrafting(); Bukkit.getScheduler().runTaskTimer(ArmorSMP.getInstance(),broadcaster::broadcastTip,0,io.config.tips.tipInterval); - Bukkit.getScheduler().runTaskTimer(ArmorSMP.getInstance(),uniques::applyPersistence,0,20); + Bukkit.getScheduler().runTaskTimer(ArmorSMP.getInstance(), uniques::applyPersistence,0,20); } diff --git a/src/main/java/me/trouper/armorsmp/server/commands/AdminCommand.java b/src/main/java/me/trouper/armorsmp/server/commands/AdminCommand.java index e0c7085..8eb6e8c 100644 --- a/src/main/java/me/trouper/armorsmp/server/commands/AdminCommand.java +++ b/src/main/java/me/trouper/armorsmp/server/commands/AdminCommand.java @@ -11,7 +11,6 @@ import me.trouper.armorsmp.data.io.Config; import me.trouper.armorsmp.data.Unique; import me.trouper.armorsmp.server.crafting.ArmorUpgrade; import me.trouper.armorsmp.utils.Text; -import me.trouper.armorsmp.utils.Verbose; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; @@ -153,7 +152,7 @@ public class AdminCommand implements CustomCommand { return; } - ArmorSMP.getInstance().getManager().armor.setTier(target, tier); + ArmorSMP.getInstance().getManager().tiers.setTier(target, tier); Text.sendMessage(false, Text.Pallet.SUCCESS, sender, "Changed armor tier to {0} for {1}", tier, target.getName()); } @@ -205,8 +204,7 @@ public class AdminCommand implements CustomCommand { } ArmorSMP.getInstance().getManager().uniques.setOwner(piece, target); - ArmorSMP.getInstance().getManager().armor.queueUpdate(target, true); - ArmorSMP.getInstance().getManager().uniques.queueUpdate(target); + ArmorSMP.getInstance().getManager().tiers.queueUpdate(target, true); Text.sendMessage(false, Text.Pallet.SUCCESS, sender, "Set the owner of unique {0} to {1}.", piece.getCanonical(), target.getName()); } @@ -287,7 +285,7 @@ public class AdminCommand implements CustomCommand { } ArmorSMP.getInstance().getManager().uniques.dropUnique(target,piece); - ArmorSMP.getInstance().getManager().armor.queueUpdate(target, true); + ArmorSMP.getInstance().getManager().tiers.queueUpdate(target, true); ArmorSMP.getInstance().getManager().uniques.queueUpdate(target); Text.sendMessage(false, Text.Pallet.SUCCESS, sender, "Removed {0} from {1}", piece.getCanonical(), target.getName()); diff --git a/src/main/java/me/trouper/armorsmp/server/events/DeathEvents.java b/src/main/java/me/trouper/armorsmp/server/events/DeathEvents.java index 21e9fe4..d5b91ec 100644 --- a/src/main/java/me/trouper/armorsmp/server/events/DeathEvents.java +++ b/src/main/java/me/trouper/armorsmp/server/events/DeathEvents.java @@ -6,7 +6,7 @@ import me.trouper.armorsmp.data.ArmorTier; import me.trouper.armorsmp.server.crafting.ArmorUpgrade; import me.trouper.armorsmp.utils.Text; import me.trouper.armorsmp.utils.Verbose; -import me.trouper.armorsmp.utils.WorldUtils; +import me.trouper.armorsmp.utils.ItemUtils; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -18,26 +18,25 @@ public class DeathEvents implements CustomListener { @EventHandler public void onDeath(PlayerDeathEvent e) { Player p = e.getEntity(); - final ArmorTier tier = ArmorSMP.getInstance().getManager().armor.getTier(p); + final ArmorTier tier = ArmorSMP.getInstance().getManager().tiers.getTier(p); Verbose.send("Handling death event for %s, their tier is %s",p.getName(),tier); - e.getDrops().removeIf(WorldUtils::notDroppable); + e.getDrops().removeIf(ItemUtils::notDroppable); if (tier.equals(ArmorTier.NONE)) { Verbose.send("Tier was none"); Text.sendMessage(true, Text.Pallet.INFO,p,"You have died! Since you were at tier {0}, you didn't drop an Armor Upgrader.",tier); return; } - if (ArmorSMP.getInstance().getManager().armor.downTier(p)) { + if (ArmorSMP.getInstance().getManager().tiers.downTier(p)) { Verbose.send("They have been down-tiered"); e.getDrops().add(ArmorUpgrade.ARMOR_UGPRADE); e.deathMessage(Text.getMessage(false, Text.Pallet.INFO,"{0} has died, and dropped an {1}!", LegacyComponentSerializer.legacyAmpersand().serialize(p.name()),"Armor Upgrader")); } - ArmorSMP.getInstance().getManager().armor.dropUniqueArmor(p); - ArmorSMP.getInstance().getManager().uniques.dropUniqueItems(p); + ArmorSMP.getInstance().getManager().uniques.dropAllUniques(p); } @EventHandler public void onRespawn(PlayerRespawnEvent e) { - ArmorSMP.getInstance().getManager().armor.queueUpdate(e.getPlayer(),false); + ArmorSMP.getInstance().getManager().tiers.queueUpdate(e.getPlayer(),false); } } diff --git a/src/main/java/me/trouper/armorsmp/server/events/DropItemEvent.java b/src/main/java/me/trouper/armorsmp/server/events/DropItemEvent.java index fd6549a..ee44717 100644 --- a/src/main/java/me/trouper/armorsmp/server/events/DropItemEvent.java +++ b/src/main/java/me/trouper/armorsmp/server/events/DropItemEvent.java @@ -3,8 +3,6 @@ package me.trouper.armorsmp.server.events; import io.github.itzispyder.pdk.events.CustomListener; import me.trouper.armorsmp.ArmorSMP; import me.trouper.armorsmp.data.Unique; -import me.trouper.armorsmp.utils.Text; -import me.trouper.armorsmp.utils.WorldUtils; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerDropItemEvent; diff --git a/src/main/java/me/trouper/armorsmp/server/events/JoinEvent.java b/src/main/java/me/trouper/armorsmp/server/events/JoinEvent.java index 76542fb..219e7af 100644 --- a/src/main/java/me/trouper/armorsmp/server/events/JoinEvent.java +++ b/src/main/java/me/trouper/armorsmp/server/events/JoinEvent.java @@ -32,9 +32,9 @@ public class JoinEvent implements CustomListener { Verbose.send("Checking for updates needed on %s",p.getName()); final Map armorCache = ArmorSMP.getInstance().getManager().io.storage.armorUpdateCache; final Set uniquesCache = ArmorSMP.getInstance().getManager().io.storage.uniqueUpdateCache; - if (!ArmorSMP.getInstance().getManager().armor.verifyArmor(p)) { + if (!ArmorSMP.getInstance().getManager().tiers.verifyArmor(p)) { Verbose.send("Updating armor"); - ArmorSMP.getInstance().getManager().armor.queueUpdate(p,armorCache.getOrDefault(p.getUniqueId().toString(),true)); + ArmorSMP.getInstance().getManager().tiers.queueUpdate(p,armorCache.getOrDefault(p.getUniqueId().toString(),true)); } if (!ArmorSMP.getInstance().getManager().uniques.verifyUniques(p)) { Verbose.send("Updating uniques"); @@ -42,7 +42,7 @@ public class JoinEvent implements CustomListener { } if (armorCache.containsKey(p.getUniqueId().toString())) { Verbose.send("Updating armor from cache"); - ArmorSMP.getInstance().getManager().armor.queueUpdate(p,armorCache.getOrDefault(p.getUniqueId().toString(),true)); + ArmorSMP.getInstance().getManager().tiers.queueUpdate(p,armorCache.getOrDefault(p.getUniqueId().toString(),true)); ArmorSMP.getInstance().getManager().io.storage.armorUpdateCache.remove(p.getUniqueId().toString()); ArmorSMP.getInstance().getManager().io.storage.save(); } diff --git a/src/main/java/me/trouper/armorsmp/server/events/PickUpEvent.java b/src/main/java/me/trouper/armorsmp/server/events/PickUpEvent.java index caca8a3..b12e112 100644 --- a/src/main/java/me/trouper/armorsmp/server/events/PickUpEvent.java +++ b/src/main/java/me/trouper/armorsmp/server/events/PickUpEvent.java @@ -4,7 +4,7 @@ import io.github.itzispyder.pdk.events.CustomListener; import me.trouper.armorsmp.ArmorSMP; import me.trouper.armorsmp.data.Unique; import me.trouper.armorsmp.utils.Text; -import me.trouper.armorsmp.utils.WorldUtils; +import me.trouper.armorsmp.utils.ItemUtils; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityPickupItemEvent; @@ -29,9 +29,9 @@ public class PickUpEvent implements CustomListener { Text.sendMessage(true, Text.Pallet.INFO,p,"Congratulations! You have picked up the unique {0}. There is only one of each in the whole server!",match.getCanonical()); ArmorSMP.getInstance().getServer().broadcast(Text.getMessage(false, Text.Pallet.INFO,"GG, {0}! They are the new owner of the unique {1}.",p.getName(),match.getCanonical())); - if (WorldUtils.isArmor(match.getInGameItem())) { + if (ItemUtils.isArmor(match.getInGameItem())) { p.getInventory().remove(i); - ArmorSMP.getInstance().getManager().armor.queueUpdate(p,true); + ArmorSMP.getInstance().getManager().tiers.queueUpdate(p,true); } } } diff --git a/src/main/java/me/trouper/armorsmp/server/events/UpgradeRedeemEvent.java b/src/main/java/me/trouper/armorsmp/server/events/UpgradeRedeemEvent.java index 9da66ff..234124e 100644 --- a/src/main/java/me/trouper/armorsmp/server/events/UpgradeRedeemEvent.java +++ b/src/main/java/me/trouper/armorsmp/server/events/UpgradeRedeemEvent.java @@ -24,11 +24,11 @@ public class UpgradeRedeemEvent implements CustomListener { if (!holding.hasItemMeta()) return; if (holding.getItemMeta().getCustomModelData() != ArmorUpgrade.ARMOR_UGPRADE.getItemMeta().getCustomModelData()) return; - final ArmorTier tier = ArmorSMP.getInstance().getManager().armor.getTier(p); + final ArmorTier tier = ArmorSMP.getInstance().getManager().tiers.getTier(p); - if (ArmorSMP.getInstance().getManager().armor.upTier(p)) { + if (ArmorSMP.getInstance().getManager().tiers.upTier(p)) { holding.setAmount(holding.getAmount() - 1); - Text.sendMessage(true, Text.Pallet.INFO,p,"Successfully redeemed armor upgrade! Tier {0} -> Tier {1}",tier,ArmorSMP.getInstance().getManager().armor.getTier(p)); + Text.sendMessage(true, Text.Pallet.INFO,p,"Successfully redeemed armor upgrade! Tier {0} -> Tier {1}",tier,ArmorSMP.getInstance().getManager().tiers.getTier(p)); } else { Text.sendMessage(true, Text.Pallet.ERROR,p,"Unable to upgrade. You are already at the maximum Armor Tier!"); } diff --git a/src/main/java/me/trouper/armorsmp/server/systems/ArmorBackend.java b/src/main/java/me/trouper/armorsmp/server/systems/TierBackend.java similarity index 60% rename from src/main/java/me/trouper/armorsmp/server/systems/ArmorBackend.java rename to src/main/java/me/trouper/armorsmp/server/systems/TierBackend.java index df019b8..f7c09b5 100644 --- a/src/main/java/me/trouper/armorsmp/server/systems/ArmorBackend.java +++ b/src/main/java/me/trouper/armorsmp/server/systems/TierBackend.java @@ -2,9 +2,8 @@ package me.trouper.armorsmp.server.systems; import me.trouper.armorsmp.ArmorSMP; import me.trouper.armorsmp.data.ArmorTier; -import me.trouper.armorsmp.data.io.IO; import me.trouper.armorsmp.data.io.Storage; -import me.trouper.armorsmp.data.Unique; +import me.trouper.armorsmp.utils.ItemUtils; import me.trouper.armorsmp.utils.Verbose; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -12,12 +11,26 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; - -public class ArmorBackend { +public class TierBackend { private final Storage storage = ArmorSMP.getInstance().getManager().io.storage; + + public synchronized void setTier(OfflinePlayer target, ArmorTier tier, boolean transferEnchants) { + Verbose.send("Setting tier of %s to %s",target.getName(),tier); + storage.userData.playerTiers.put(target.getUniqueId().toString(),tier); + storage.save(); + queueUpdate(target,transferEnchants); + } + + public synchronized void queueUpdate(OfflinePlayer target, boolean transferEnchants) { + Verbose.send("Queueing update for %s",target.getName()); + if (target.getPlayer() != null && target.isOnline()) updateArmor(target.getPlayer(), transferEnchants); + else { + storage.armorUpdateCache.put(target.getUniqueId().toString(),transferEnchants); + ArmorSMP.getInstance().getManager().io.storage.save(); + } + + } public boolean shouldTransferEnchants(OfflinePlayer target, ArmorTier request) { final ArmorTier current = getTier(target); @@ -26,14 +39,7 @@ public class ArmorBackend { public void setTier(OfflinePlayer target, ArmorTier tier) { setTier(target, tier, shouldTransferEnchants(target, tier)); - } - - public void setTier(OfflinePlayer target, ArmorTier tier, boolean transferEnchants) { - Verbose.send("Setting tier of %s to %s",target.getName(),tier); - storage.userData.playerTiers.put(target.getUniqueId().toString(),tier); - storage.save(); - queueUpdate(target,transferEnchants); - } + } public boolean downTier(OfflinePlayer target) { int numeric = storage.userData.playerTiers.get(target.getUniqueId().toString()).getNumeric(); @@ -64,7 +70,7 @@ public class ArmorBackend { Verbose.send("Got tier of %s: %s", target.getName(),tier); return tier; } - + public boolean verifyArmor(Player target) { Verbose.send("Verifying armor of %s", target.getName()); PlayerInventory e = target.getInventory(); @@ -74,78 +80,57 @@ public class ArmorBackend { final Material correctChestplate = tier.getChestplate().getType(); final Material correctLeggings = tier.getLeggings().getType(); final Material correctBoots = tier.getBoots().getType(); - Verbose.send(""" - Correct Gear: - %s - %s - %s - %s - """, correctHelmet,correctChestplate,correctLeggings,correctBoots - ); - final Material helmet = e.getHelmet() == null ? Material.AIR : e.getHelmet().getType() == Material.NETHERITE_HELMET ? correctHelmet : e.getHelmet().getType(); - final Material chestplate = e.getChestplate() == null ? Material.AIR : e.getChestplate().getType() == Material.NETHERITE_CHESTPLATE ? correctChestplate : e.getChestplate().getType(); - final Material leggings = e.getLeggings() == null ? Material.AIR : e.getLeggings().getType() == Material.NETHERITE_LEGGINGS ? correctLeggings : e.getLeggings().getType(); - final Material boots = e.getBoots() == null ? Material.AIR : e.getBoots().getType() == Material.NETHERITE_BOOTS ? correctBoots : e.getBoots().getType(); - Verbose.send(""" - Equipped Gear: - %s - %s - %s - %s - """, helmet,chestplate,leggings,boots - ); + boolean helmetValid = (e.getHelmet() != null && ItemUtils.isUniqueArmor(e.getHelmet())) || (e.getHelmet() != null ? e.getHelmet().getType() : Material.AIR) == correctHelmet; + boolean chestplateValid = (e.getChestplate() != null && ItemUtils.isUniqueArmor(e.getChestplate())) || (e.getChestplate() != null ? e.getChestplate().getType() : Material.AIR) == correctChestplate; + boolean leggingsValid = (e.getLeggings() != null && ItemUtils.isUniqueArmor(e.getLeggings())) || (e.getLeggings() != null ? e.getLeggings().getType() : Material.AIR) == correctLeggings; + boolean bootsValid = (e.getBoots() != null && ItemUtils.isUniqueArmor(e.getBoots())) || (e.getBoots() != null ? e.getBoots().getType() : Material.AIR) == correctBoots; - return helmet.equals(correctHelmet) && chestplate.equals(correctChestplate) && leggings.equals(correctLeggings) && boots.equals(correctBoots); + Verbose.send("Armor validation result: [%b, %b, %b, %b]", + helmetValid, chestplateValid, leggingsValid, bootsValid); + + return helmetValid && chestplateValid && leggingsValid && bootsValid; } - + private void updateArmor(Player target, boolean transferEnchants) { - Verbose.send("Updating the armor of %s",target.getName()); + Verbose.send("Updating the armor of %s", target.getName()); PlayerInventory e = target.getInventory(); final ArmorTier tier = getTier(target); - Verbose.send("Tier is %s",tier); - - final ItemStack helmet = e.getHelmet(); - final ItemStack chestplate = e.getChestplate(); - final ItemStack leggings = e.getLeggings(); - final ItemStack boots = e.getBoots(); - if (tier.equals(ArmorTier.NONE)) { e.setHelmet(new ItemStack(Material.AIR)); e.setChestplate(new ItemStack(Material.AIR)); e.setLeggings(new ItemStack(Material.AIR)); e.setBoots(new ItemStack(Material.AIR)); - - updateUniqueArmor(target); - Verbose.send("Returning to prevent NPE"); + ArmorSMP.getInstance().getManager().uniques.queueUpdate(target); + Verbose.send("Cleared armor slots for tier NONE."); return; } - - AtomicReference updatedHelmet = new AtomicReference<>(tier.getHelmet()); - AtomicReference updatedChestplate = new AtomicReference<>(tier.getChestplate()); - AtomicReference updatedLeggings = new AtomicReference<>(tier.getLeggings()); - AtomicReference updatedBoots = new AtomicReference<>(tier.getBoots()); - - + + ItemStack updatedHelmet = tier.getHelmet().clone(); + ItemStack updatedChestplate = tier.getChestplate().clone(); + ItemStack updatedLeggings = tier.getLeggings().clone(); + ItemStack updatedBoots = tier.getBoots().clone(); + if (transferEnchants) { - Verbose.send("Transfering enchants..."); - if (helmet != null && !helmet.getType().name().contains("NETHERITE")) updatedHelmet.get().addEnchantments(helmet.getEnchantments()); - if (chestplate != null && !chestplate.getType().name().contains("NETHERITE")) updatedChestplate.get().addEnchantments(chestplate.getEnchantments()); - if (leggings != null && !leggings.getType().name().contains("NETHERITE")) updatedLeggings.get().addEnchantments(leggings.getEnchantments()); - if (boots != null && !boots.getType().name().contains("NETHERITE")) updatedBoots.get().addEnchantments(boots.getEnchantments()); + Verbose.send("Transfering enchants (non-unique only)..."); + ItemUtils.transferEnchants(e.getHelmet(), updatedHelmet); + ItemUtils.transferEnchants(e.getChestplate(), updatedChestplate); + ItemUtils.transferEnchants(e.getLeggings(), updatedLeggings); + ItemUtils.transferEnchants(e.getBoots(), updatedBoots); } - - Verbose.send("Setting items..."); - e.setHelmet(updatedHelmet.get()); - e.setChestplate(updatedChestplate.get()); - e.setLeggings(updatedLeggings.get()); - e.setBoots(updatedBoots.get()); - - updateUniqueArmor(target); - Verbose.send("Update complete!"); + + e.setHelmet(updatedHelmet); + e.setChestplate(updatedChestplate); + e.setLeggings(updatedLeggings); + e.setBoots(updatedBoots); + + ArmorSMP.getInstance().getManager().uniques.queueUpdate(target); + Verbose.send("Armor update complete!"); } + + /* private void updateUniqueArmor(Player target) { PlayerInventory e = target.getInventory(); @@ -163,12 +148,7 @@ public class ArmorBackend { } } - public synchronized void queueUpdate(OfflinePlayer target, boolean transferEnchants) { - Verbose.send("Queueing update for %s",target.getName()); - if (target.getPlayer() != null && target.isOnline()) updateArmor(target.getPlayer(), transferEnchants); - else storage.armorUpdateCache.put(target.getUniqueId().toString(),transferEnchants); - ArmorSMP.getInstance().getManager().io.storage.save(); - } + public synchronized void dropUniqueArmor(Player target) { final Map uniques = storage.uniques.owners; @@ -191,4 +171,6 @@ public class ArmorBackend { ArmorSMP.getInstance().getManager().io.storage.save(); } + + */ } diff --git a/src/main/java/me/trouper/armorsmp/server/systems/UniquesBackend.java b/src/main/java/me/trouper/armorsmp/server/systems/UniquesBackend.java index 90b331f..d78f378 100644 --- a/src/main/java/me/trouper/armorsmp/server/systems/UniquesBackend.java +++ b/src/main/java/me/trouper/armorsmp/server/systems/UniquesBackend.java @@ -1,77 +1,99 @@ package me.trouper.armorsmp.server.systems; import me.trouper.armorsmp.ArmorSMP; -import me.trouper.armorsmp.data.io.IO; -import me.trouper.armorsmp.data.io.Storage; import me.trouper.armorsmp.data.Unique; +import me.trouper.armorsmp.data.io.Storage; +import me.trouper.armorsmp.utils.ItemUtils; import me.trouper.armorsmp.utils.Verbose; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; import java.util.ArrayList; import java.util.List; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicBoolean; public class UniquesBackend { private final Storage storage = ArmorSMP.getInstance().getManager().io.storage; - - private void updateUniques() { - ArmorSMP.getInstance().getServer().getOnlinePlayers().forEach(this::updateUniques); - } - - public void updateUniques(Player p) { - ArmorSMP.getInstance().getManager().io.storage.uniques.owners.forEach(((unique, id) -> { - if (unique.equals(Unique.HELMET) - || unique.equals(Unique.CHESTPLATE) - || unique.equals(Unique.LEGGINGS) - || unique.equals(Unique.BOOTS) - ) return; - if (id.equals(p.getUniqueId().toString())) { - Verbose.send(1, "They own the unique, checking if they have it: ", p.getInventory().contains(unique.getInGameItem())); - if (!p.getInventory().contains(unique.getInGameItem())) { - Verbose.send(1, "They don't have it, giving them the item."); - p.getInventory().removeItemAnySlot(unique.getInGameItem()); - p.getInventory().addItem(unique.getInGameItem()); - } - } else { - p.getInventory().removeItemAnySlot(unique.getInGameItem()); - } - })); - } public void queueUpdate(OfflinePlayer target) { - if (target.getPlayer() != null && target.isOnline()) updateUniques(); - else storage.uniqueUpdateCache.add(target.getUniqueId().toString()); - ArmorSMP.getInstance().getManager().io.storage.save(); - } - - public void setOwner(Unique u, OfflinePlayer p) { - storage.uniques.owners.put(u,p.getUniqueId().toString()); - ArmorSMP.getInstance().getManager().io.storage.save(); - queueUpdate(p); + if (target.getPlayer() != null && target.isOnline()) updateUniques(target.getPlayer()); + else { + storage.uniqueUpdateCache.add(target.getUniqueId().toString()); + ArmorSMP.getInstance().getManager().io.storage.save(); + } + } - public void dropUnique(Player p, Unique dropped) { - storage.uniques.owners.remove(dropped); - ArmorSMP.getInstance().getManager().io.storage.save(); + private void updateUniques(Player p) { + + removeUnowned(p); + equipOwnedArmor(p); + addMissing(p); + + storage.save(); } - public void dropUniqueItems(Player p) { - storage.uniques.owners.forEach((unique,owner)->{ - if (unique.equals(Unique.MACE) || unique.equals(Unique.SWORD) || unique.equals(Unique.AXE) && owner.equals(p.getUniqueId().toString())) { - storage.uniques.owners.remove(unique); + private void removeUnowned(Player p) { + PlayerInventory inv = p.getInventory(); + for (ItemStack item : inv.getContents()) { + if (item == null || !ItemUtils.isUnique(item)) continue; + Unique unique = Unique.matchUnique(item); + if (unique == null || !isOwner(p, unique)) { + inv.removeItemAnySlot(item); + } + } + + for (ItemStack armor : inv.getArmorContents()) { + if (armor == null || !ItemUtils.isUnique(armor)) continue; + Unique unique = Unique.matchUnique(armor); + if (unique == null || !isOwner(p, unique)) { + inv.setItem(inv.first(armor), null); + } + } + } + + private void equipOwnedArmor(Player p) { + storage.uniques.owners.forEach((unique, ownerId) -> { + if (ownerId.equals(p.getUniqueId().toString()) && Unique.isArmor(unique)) { + if (ItemUtils.isHelmet(unique.getInGameItem())) p.getInventory().setHelmet(unique.getInGameItem()); + else if (ItemUtils.isChestplate(unique.getInGameItem())) p.getInventory().setChestplate(unique.getInGameItem()); + else if (ItemUtils.isLeggings(unique.getInGameItem())) p.getInventory().setLeggings(unique.getInGameItem()); + else if (ItemUtils.isBoots(unique.getInGameItem())) p.getInventory().setBoots(unique.getInGameItem()); } }); - ArmorSMP.getInstance().getManager().io.storage.save(); } - + + private void addMissing(Player p) { + storage.uniques.owners.forEach((unique, ownerId) -> { + if (ownerId.equals(p.getUniqueId().toString())) { + if (!Unique.isArmor(unique) && !hasItem(p, unique)) { + p.getInventory().addItem(unique.getInGameItem()); + } + } + }); + } + + public boolean isOwner(Player p, Unique unique) { + return storage.uniques.owners.containsKey(unique) && storage.uniques.owners.get(unique).equals(p.getUniqueId().toString()); + } + + + private boolean hasItem(Player p, Unique unique) { + for (ItemStack item : p.getInventory().getContents()) { + if (item != null && ItemUtils.isSimilar(item, unique.getInGameItem())) { + return true; + } + } + return false; + } + public void applyPersistence() { Bukkit.getOnlinePlayers().forEach(this::applyEffects); } - + public void applyEffects(Player p) { storage.uniques.owners.forEach((unique, owner) -> { if (p != null && owner.equals(p.getUniqueId().toString()) && p.isOnline()) { @@ -80,18 +102,32 @@ public class UniquesBackend { }); } + public void dropUnique(Player p, Unique dropped) { + storage.uniques.owners.remove(dropped); + storage.save(); + } + + public void dropAllUniques(Player p) { + storage.uniques.owners.forEach((unique,owner)->{ + if (owner.equals(p.getUniqueId().toString())) { + storage.uniques.owners.remove(unique); + } + }); + storage.save(); + } + + public void setOwner(Unique u, OfflinePlayer p) { + storage.uniques.owners.put(u, p.getUniqueId().toString()); + storage.save(); + if (p.isOnline()) updateUniques(p.getPlayer()); + } + public boolean verifyUniques(Player p) { - AtomicBoolean success = new AtomicBoolean(false); List checks = new ArrayList<>(); ArmorSMP.getInstance().getManager().io.storage.uniques.owners.forEach(((unique, id) -> { - if (unique.equals(Unique.HELMET) - || unique.equals(Unique.CHESTPLATE) - || unique.equals(Unique.LEGGINGS) - || unique.equals(Unique.BOOTS) - ) return; if (id.equals(p.getUniqueId().toString())) { Verbose.send(1, "They own the unique, checking if they have it: ", p.getInventory().contains(unique.getInGameItem())); - if (p.getInventory().contains(unique.getInGameItem())) { + if (hasItem(p,unique)) { Verbose.send(1, "They have it"); checks.add(true); } else { @@ -102,4 +138,6 @@ public class UniquesBackend { })); return !checks.contains(false); } -} + + +} \ No newline at end of file diff --git a/src/main/java/me/trouper/armorsmp/utils/Display.java b/src/main/java/me/trouper/armorsmp/utils/Display.java index 205c4a8..5b6b9d6 100644 --- a/src/main/java/me/trouper/armorsmp/utils/Display.java +++ b/src/main/java/me/trouper/armorsmp/utils/Display.java @@ -36,11 +36,14 @@ public class Display implements Global { } } } + public static final Function> PARTICLE_FACTORY = particle -> l -> l.getWorld().spawnParticle(particle, l, 1, 0, 0, 0, 0); + public static final BiFunction> DUST_PARTICLE_FACTORY = (color, thickness) -> { Particle.DustOptions dust = new Particle.DustOptions(color, thickness); return l -> l.getWorld().spawnParticle(Particle.DUST, l, 1, 0, 0, 0, 0, dust); }; + public static final Function> FLAME_PARTICLE_FACTORY = soul -> { Particle flame = soul ? Particle.SOUL_FIRE_FLAME : Particle.FLAME; return l -> l.getWorld().spawnParticle(flame, l, 1, 0, 0, 0, 0); diff --git a/src/main/java/me/trouper/armorsmp/utils/ItemUtils.java b/src/main/java/me/trouper/armorsmp/utils/ItemUtils.java new file mode 100644 index 0000000..be1fb19 --- /dev/null +++ b/src/main/java/me/trouper/armorsmp/utils/ItemUtils.java @@ -0,0 +1,81 @@ +package me.trouper.armorsmp.utils; + +import me.trouper.armorsmp.data.Unique; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; + +public class ItemUtils { + + public static boolean notDroppable(ItemStack i) { + return isArmor(i) && !isUnique(i) && !isDragonEggEquivalent(i); + } + + private static boolean isDragonEggEquivalent(ItemStack i) { + Material m = i.getType(); + return m.equals(Unique.DRAGON_EGG); + } + + public static boolean isArmor(ItemStack i) { + return isHelmet(i) || isChestplate(i) || isLeggings(i) || isBoots(i); + } + + public static boolean isHelmet(ItemStack i) { + Material m = i.getType(); + String n = m.name(); + return n.contains("HELMET"); + } + + public static boolean isChestplate(ItemStack i) { + Material m = i.getType(); + String n = m.name(); + return n.contains("CHESTPLATE"); + } + + public static boolean isLeggings(ItemStack i) { + Material m = i.getType(); + String n = m.name(); + return n.contains("LEGGINGS"); + } + + public static boolean isBoots(ItemStack i) { + Material m = i.getType(); + String n = m.name(); + return n.contains("BOOTS"); + } + + public static boolean isUnique(ItemStack i) { + Material m = i.getType(); + List uniqueMets = new ArrayList<>(); + for (Unique value : Unique.values()) { + uniqueMets.add(value.getInGameItem().getType()); + } + + return uniqueMets.contains(m); + } + + public static boolean isUniqueArmor(ItemStack i) { + return isUnique(i) && isArmor(i); + } + + public static boolean isSimilar(ItemStack item1, ItemStack item2) { + if (item1 == null || item2 == null) return false; + if (item1.getType() != item2.getType()) return false; + if (item1.hasItemMeta() != item2.hasItemMeta()) return false; + + ItemMeta meta1 = item1.getItemMeta(); + ItemMeta meta2 = item2.getItemMeta(); + + return meta1 == null || meta2 == null || meta1.equals(meta2); + } + + /** @excludes unique enchants */ + public static void transferEnchants(ItemStack oldItem, ItemStack newItem) { + if (oldItem != null && !isUnique(oldItem)) { + newItem.addEnchantments(oldItem.getEnchantments()); + } + } +} diff --git a/src/main/java/me/trouper/armorsmp/utils/WorldUtils.java b/src/main/java/me/trouper/armorsmp/utils/WorldUtils.java deleted file mode 100644 index c74a7f1..0000000 --- a/src/main/java/me/trouper/armorsmp/utils/WorldUtils.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.trouper.armorsmp.utils; - -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -public class WorldUtils { - - public static boolean notDroppable(ItemStack i) { - return isArmor(i) && !isUnique(i) && !isDragonEggEquivalent(i); - } - - private static boolean isDragonEggEquivalent(ItemStack i) { - Material m = i.getType(); - return m.equals(Material.NETHERITE_CHESTPLATE); - } - - public static boolean isArmor(ItemStack i) { - Material m = i.getType(); - String n = m.name(); - return n.contains("HELMET") - || n.contains("CHESTPLATE") - || n.contains("LEGGINGS") - || n.contains("BOOTS"); - } - - public static boolean isUnique(ItemStack i) { - Material m = i.getType(); - String n = m.name(); - return (n.contains("NETHERITE") && isArmor(i)) - || n.contains("MACE") - || n.contains("NETHERITE_SWORD") - || n.contains("NETHERITE_AXE"); - } - - public static boolean isSimilar(ItemStack item1, ItemStack item2) { - if (item1 == null || item2 == null) return false; - if (item1.getType() != item2.getType()) return false; - if (item1.hasItemMeta() != item2.hasItemMeta()) return false; - - ItemMeta meta1 = item1.getItemMeta(); - ItemMeta meta2 = item2.getItemMeta(); - - return meta1 == null || meta2 == null || meta1.equals(meta2); - } -}