From 8dccc9a01c9727b6777ded7b7c3076d179a53a29 Mon Sep 17 00:00:00 2001 From: Danik Vitek Date: Mon, 30 Sep 2024 21:45:38 +0300 Subject: [PATCH] 2.2 (#6) * Remove dependency on Item NBT API * Separate out accessor methods for `ItemMeta` --- build.gradle.kts | 4 +- .../slimeinabukkit/SlimeInABukkitPlugin.java | 18 ++++++-- .../slimeinabukkit/SlimeListener.java | 28 ++++--------- .../command/GetSlimeCommand.java | 12 +++--- .../PersistentContainerAccessor.java | 37 +++++++++++++++++ .../persistence/datatype/UUIDTagType.java | 41 +++++++++++++++++++ 6 files changed, 109 insertions(+), 31 deletions(-) create mode 100644 src/main/java/com/danikvitek/slimeinabukkit/persistence/PersistentContainerAccessor.java create mode 100644 src/main/java/com/danikvitek/slimeinabukkit/persistence/datatype/UUIDTagType.java diff --git a/build.gradle.kts b/build.gradle.kts index 4681dc1..7bd05e2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "com.danikvitek" -version = "2.1" +version = "2.2" repositories { mavenCentral() @@ -32,7 +32,6 @@ dependencies { paperweight.paperDevBundle("1.18.2-R0.1-SNAPSHOT") compileOnly(libs.jetbrains.annotations) implementation(libs.bstats.bukkit) - implementation(libs.itemnbt.api) implementation(libs.vavr) } @@ -46,7 +45,6 @@ tasks { } shadowJar { relocate("org.bstats", "com.danikvitek.bstats") - relocate("de.tr7zw.changeme.nbtapi", "com.danikvitek.itemnbtapi") } build { dependsOn(shadowJar) diff --git a/src/main/java/com/danikvitek/slimeinabukkit/SlimeInABukkitPlugin.java b/src/main/java/com/danikvitek/slimeinabukkit/SlimeInABukkitPlugin.java index 5e5d073..7de4493 100644 --- a/src/main/java/com/danikvitek/slimeinabukkit/SlimeInABukkitPlugin.java +++ b/src/main/java/com/danikvitek/slimeinabukkit/SlimeInABukkitPlugin.java @@ -5,9 +5,11 @@ import com.danikvitek.slimeinabukkit.config.ChunkMessageResolver; import com.danikvitek.slimeinabukkit.config.ConfigAccessor; import com.danikvitek.slimeinabukkit.config.PluginConfig; +import com.danikvitek.slimeinabukkit.persistence.PersistentContainerAccessor; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; @@ -15,7 +17,6 @@ public final class SlimeInABukkitPlugin extends JavaPlugin implements ConfigAccessor { public static final Material SLIME_BUCKET_MATERIAL = Material.SLIME_BALL; - public static final String SLIME_BUCKET_UUID_KEY = "SLIME_UUID"; private static final int PLUGIN_ID = 14716; private final Scheduler scheduler = new Scheduler(this, getServer().getScheduler()); @@ -26,7 +27,10 @@ public void onEnable() { this.getConfig().options().configuration(); this.saveDefaultConfig(); - Objects.requireNonNull(getCommand("get_slime")).setExecutor(new GetSlimeCommand(pluginConfig)); + final var persistentContainerAccessor = new PersistentContainerAccessor(new NamespacedKey(this, "slime-uuid")); + + Objects.requireNonNull(getCommand("get_slime")) + .setExecutor(new GetSlimeCommand(pluginConfig, persistentContainerAccessor)); final var messageResolver = new ChunkMessageResolver( pluginConfig.getSlimeChunkMessage(), @@ -37,7 +41,15 @@ public void onEnable() { new Metrics(this, PLUGIN_ID); - Bukkit.getPluginManager().registerEvents(new SlimeListener(pluginConfig, this::debugLog, scheduler), this); + Bukkit.getPluginManager().registerEvents( + new SlimeListener( + pluginConfig, + this::debugLog, + scheduler, + persistentContainerAccessor + ), + this + ); } @Override diff --git a/src/main/java/com/danikvitek/slimeinabukkit/SlimeListener.java b/src/main/java/com/danikvitek/slimeinabukkit/SlimeListener.java index 0f4f5b4..806770e 100644 --- a/src/main/java/com/danikvitek/slimeinabukkit/SlimeListener.java +++ b/src/main/java/com/danikvitek/slimeinabukkit/SlimeListener.java @@ -1,8 +1,8 @@ package com.danikvitek.slimeinabukkit; import com.danikvitek.slimeinabukkit.config.PluginConfig; +import com.danikvitek.slimeinabukkit.persistence.PersistentContainerAccessor; import com.danikvitek.slimeinabukkit.util.ISUtil; -import de.tr7zw.changeme.nbtapi.NBT; import io.vavr.collection.Iterator; import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; @@ -35,7 +35,6 @@ import java.util.function.Consumer; import static com.danikvitek.slimeinabukkit.SlimeInABukkitPlugin.SLIME_BUCKET_MATERIAL; -import static com.danikvitek.slimeinabukkit.SlimeInABukkitPlugin.SLIME_BUCKET_UUID_KEY; public class SlimeListener implements Listener { public static final String SLIME_INTERACT_PERMISSION = "slimeinabukkit.interact"; @@ -47,13 +46,16 @@ public class SlimeListener implements Listener { private final @NotNull PluginConfig config; private final @NotNull Consumer debugLog; private final @NotNull Scheduler scheduler; + private final @NotNull PersistentContainerAccessor persistentContainerAccessor; public SlimeListener(@NotNull PluginConfig config, @NotNull Consumer debugLog, - @NotNull Scheduler scheduler) { + @NotNull Scheduler scheduler, + @NotNull PersistentContainerAccessor persistentContainerAccessor) { this.config = config; this.debugLog = debugLog; this.scheduler = scheduler; + this.persistentContainerAccessor = persistentContainerAccessor; } @EventHandler @@ -147,7 +149,7 @@ private void pickupSlime(final @NotNull Slime slime, slimeBucketStack.setItemMeta(slimeBucketMeta); slimeBucketStack.setType(SLIME_BUCKET_MATERIAL); - assignUUID(slimeBucketStack, slime.getUniqueId()); + persistentContainerAccessor.setSlimeBucketUUID(slimeBucketStack, slime.getUniqueId()); if (bucketStack.getAmount() > 1) { bucketStack.setAmount(bucketStack.getAmount() - 1); final var notFittedItems = player.getInventory().addItem(slimeBucketStack); @@ -165,13 +167,6 @@ private void pickupSlime(final @NotNull Slime slime, scheduler.runTask(() -> interactingPlayers.remove(player.getUniqueId())); } - private void assignUUID(final @NotNull ItemStack slimeBucketStack, - final @NotNull UUID uuid) { - NBT.modify(slimeBucketStack, nbt -> { - nbt.setUUID(SLIME_BUCKET_UUID_KEY, uuid); - }); - } - @EventHandler public void onClickAtBlock(final @NotNull PlayerInteractEvent event) { debugLog.accept("PlayerInteractEvent was caught"); @@ -234,6 +229,7 @@ private void placeSlime(final @NotNull PlayerInteractEvent event, player.getWorld().spawn(slimeReleaseLocation, Slime.class, slime -> { slime.setSize(1); final var serializer = PlainTextComponentSerializer.plainText(); + ISUtil.useDisplayName(itemMeta, displayName -> { if (!serializer.serialize(displayName) .equals(serializer.serialize(config.getSlimeBucketTitle()))) { @@ -244,9 +240,9 @@ private void placeSlime(final @NotNull PlayerInteractEvent event, itemMeta.setCustomModelData(null); itemMeta.displayName(null); + persistentContainerAccessor.removeSlimeBucketUUID(itemMeta); itemStack.setItemMeta(itemMeta); itemStack.setType(Material.BUCKET); - removeUUID(itemStack); if (event.getHand() == EquipmentSlot.HAND) player.swingMainHand(); else player.swingOffHand(); @@ -254,12 +250,6 @@ private void placeSlime(final @NotNull PlayerInteractEvent event, scheduler.runTask(() -> interactingPlayers.remove(player.getUniqueId())); } - private void removeUUID(final @NotNull ItemStack itemStack) { - NBT.modify(itemStack, nbt -> { - nbt.removeKey(SLIME_BUCKET_UUID_KEY); - }); - } - @EventHandler(priority = EventPriority.MONITOR) public void onCraftWithSlimeBucket(final @NotNull CraftItemEvent e) { final int matrixSize = e.getInventory().getMatrix().length; @@ -293,8 +283,8 @@ public void onCraftWithSlimeBucket(final @NotNull CraftItemEvent e) { assert clonedBucketMeta != null; clonedBucketMeta.setCustomModelData(null); clonedBucketMeta.displayName(null); + persistentContainerAccessor.removeSlimeBucketUUID(clonedBucketMeta); clonedBucket.setItemMeta(clonedBucketMeta); - removeUUID(clonedBucket); newMatrix[slot] = clonedBucket; }); diff --git a/src/main/java/com/danikvitek/slimeinabukkit/command/GetSlimeCommand.java b/src/main/java/com/danikvitek/slimeinabukkit/command/GetSlimeCommand.java index abc238a..f85a0a3 100644 --- a/src/main/java/com/danikvitek/slimeinabukkit/command/GetSlimeCommand.java +++ b/src/main/java/com/danikvitek/slimeinabukkit/command/GetSlimeCommand.java @@ -1,7 +1,7 @@ package com.danikvitek.slimeinabukkit.command; import com.danikvitek.slimeinabukkit.config.PluginConfig; -import de.tr7zw.changeme.nbtapi.NBT; +import com.danikvitek.slimeinabukkit.persistence.PersistentContainerAccessor; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Location; @@ -18,13 +18,15 @@ import java.util.UUID; import static com.danikvitek.slimeinabukkit.SlimeInABukkitPlugin.SLIME_BUCKET_MATERIAL; -import static com.danikvitek.slimeinabukkit.SlimeInABukkitPlugin.SLIME_BUCKET_UUID_KEY; public class GetSlimeCommand implements CommandExecutor { private final @NotNull PluginConfig config; + private final @NotNull PersistentContainerAccessor persistentContainerAccessor; - public GetSlimeCommand(@NotNull PluginConfig config) { + public GetSlimeCommand(@NotNull PluginConfig config, + @NotNull PersistentContainerAccessor persistentContainerAccessor) { this.config = config; + this.persistentContainerAccessor = persistentContainerAccessor; } @Override @@ -53,10 +55,8 @@ private void getSlimeImpl(@NotNull CommandSender sender) { ); slimeBucketMeta.displayName(config.getSlimeBucketTitle()); + persistentContainerAccessor.setSlimeBucketUUID(slimeBucketMeta, UUID.randomUUID()); // for it to be not stackable slimeBucket.setItemMeta(slimeBucketMeta); - NBT.modify(slimeBucket, nbt -> { - nbt.setUUID(SLIME_BUCKET_UUID_KEY, UUID.randomUUID()); // for it to be not stackable - }); final World world = player.getWorld(); world.playSound(location, Sound.ENTITY_ITEM_PICKUP, 1f, 1f); diff --git a/src/main/java/com/danikvitek/slimeinabukkit/persistence/PersistentContainerAccessor.java b/src/main/java/com/danikvitek/slimeinabukkit/persistence/PersistentContainerAccessor.java new file mode 100644 index 0000000..6e7757f --- /dev/null +++ b/src/main/java/com/danikvitek/slimeinabukkit/persistence/PersistentContainerAccessor.java @@ -0,0 +1,37 @@ +package com.danikvitek.slimeinabukkit.persistence; + +import com.danikvitek.slimeinabukkit.persistence.datatype.UUIDTagType; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public class PersistentContainerAccessor { + private final @NotNull NamespacedKey slimeBucketUuidKey; + + public PersistentContainerAccessor(@NotNull NamespacedKey slimeBucketUuidKey) { + this.slimeBucketUuidKey = slimeBucketUuidKey; + } + + public void setSlimeBucketUUID(final @NotNull ItemStack itemStack, final @NotNull UUID uuid) { + final ItemMeta itemMeta = itemStack.getItemMeta(); + setSlimeBucketUUID(itemMeta, uuid); + itemStack.setItemMeta(itemMeta); + } + + public void setSlimeBucketUUID(final @NotNull ItemMeta itemMeta, final @NotNull UUID uuid) { + itemMeta.getPersistentDataContainer().set(slimeBucketUuidKey, UUIDTagType.INSTANCE, uuid); + } + + public void removeSlimeBucketUUID(final @NotNull ItemStack itemStack) { + final ItemMeta itemMeta = itemStack.getItemMeta(); + removeSlimeBucketUUID(itemMeta); + itemStack.setItemMeta(itemMeta); + } + + public void removeSlimeBucketUUID(final @NotNull ItemMeta itemMeta) { + itemMeta.getPersistentDataContainer().remove(slimeBucketUuidKey); + } +} diff --git a/src/main/java/com/danikvitek/slimeinabukkit/persistence/datatype/UUIDTagType.java b/src/main/java/com/danikvitek/slimeinabukkit/persistence/datatype/UUIDTagType.java new file mode 100644 index 0000000..9fffa87 --- /dev/null +++ b/src/main/java/com/danikvitek/slimeinabukkit/persistence/datatype/UUIDTagType.java @@ -0,0 +1,41 @@ +package com.danikvitek.slimeinabukkit.persistence.datatype; + +import org.bukkit.persistence.PersistentDataAdapterContext; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; + +import java.nio.ByteBuffer; +import java.util.UUID; + +public final class UUIDTagType implements PersistentDataType { + public static final UUIDTagType INSTANCE = new UUIDTagType(); + + private UUIDTagType() { + } + + @Override + public @NotNull Class getPrimitiveType() { + return byte[].class; + } + + @Override + public @NotNull Class getComplexType() { + return UUID.class; + } + + @Override + public byte @NotNull [] toPrimitive(final @NotNull UUID complex, final @NotNull PersistentDataAdapterContext context) { + final ByteBuffer bb = ByteBuffer.wrap(new byte[16]); + bb.putLong(complex.getMostSignificantBits()); + bb.putLong(complex.getLeastSignificantBits()); + return bb.array(); + } + + @Override + public @NotNull UUID fromPrimitive(final byte @NotNull [] primitive, final @NotNull PersistentDataAdapterContext context) { + final ByteBuffer bb = ByteBuffer.wrap(primitive); + final long firstLong = bb.getLong(); + final long secondLong = bb.getLong(); + return new UUID(firstLong, secondLong); + } +}