From 41bfd404ca86c2850a56bda1d46540367d29fc49 Mon Sep 17 00:00:00 2001 From: WizardlyBump17 Date: Fri, 6 Feb 2026 19:35:11 -0300 Subject: [PATCH 1/3] added the v1_21_r7 module --- settings.gradle | 4 +- versions/v1_21_r7/build.gradle.kts | 18 ++ .../adapter/v1_21_r7/AttributeAdapter.java | 76 ++++++++ .../wlib/adapter/v1_21_r7/ItemAdapter.java | 171 ++++++++++++++++++ .../v1_21_r7/player/PlayerAdapter.java | 39 ++++ 5 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 versions/v1_21_r7/build.gradle.kts create mode 100644 versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/AttributeAdapter.java create mode 100644 versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/ItemAdapter.java create mode 100644 versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/player/PlayerAdapter.java diff --git a/settings.gradle b/settings.gradle index 37c4d078..e82789f4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -27,4 +27,6 @@ findProject(':versions:v1_21_R1')?.name = 'v1_21_R1' include 'versions:v1_21_R3' findProject(':versions:v1_21_R3')?.name = 'v1_21_R3' include 'versions:v1_21_R5' -findProject(':versions:v1_21_R5')?.name = 'v1_21_R5' \ No newline at end of file +findProject(':versions:v1_21_R5')?.name = 'v1_21_R5' + +include 'versions:v1_21_r7' \ No newline at end of file diff --git a/versions/v1_21_r7/build.gradle.kts b/versions/v1_21_r7/build.gradle.kts new file mode 100644 index 00000000..f99c0ebc --- /dev/null +++ b/versions/v1_21_r7/build.gradle.kts @@ -0,0 +1,18 @@ +plugins { + id("io.papermc.paperweight.userdev") version "2.0.0-SNAPSHOT" +} + +apply(plugin = "io.papermc.paperweight.userdev") + +val paper = "1.21.11-R0.1-SNAPSHOT" +val jetbrainsAnnotations = "26.0.2" + +dependencies { + paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:${paper}") + + compileOnly("org.jetbrains:annotations:${jetbrainsAnnotations}") + + implementation(project(":versions:adapter")) + implementation(project(":utils")) + implementation(project(":bukkit-utils")) +} diff --git a/versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/AttributeAdapter.java b/versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/AttributeAdapter.java new file mode 100644 index 00000000..cab4d976 --- /dev/null +++ b/versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/AttributeAdapter.java @@ -0,0 +1,76 @@ +package com.wizardlybump17.wlib.adapter.v1_21_r7; + +import com.google.common.collect.Multimap; +import com.google.common.collect.TreeMultimap; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeModifier; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class AttributeAdapter extends com.wizardlybump17.wlib.adapter.AttributeAdapter { + + public static final @NotNull Map ATTRIBUTES; + + static { + Map attributes = new HashMap<>(); + attributes.put("GENERIC_MAX_HEALTH", Attribute.MAX_HEALTH); + attributes.put("GENERIC_FOLLOW_RANGE", Attribute.FOLLOW_RANGE); + attributes.put("GENERIC_KNOCKBACK_RESISTANCE", Attribute.KNOCKBACK_RESISTANCE); + attributes.put("GENERIC_MOVEMENT_SPEED", Attribute.MOVEMENT_SPEED); + attributes.put("GENERIC_FLYING_SPEED", Attribute.FLYING_SPEED); + attributes.put("GENERIC_ATTACK_DAMAGE", Attribute.ATTACK_DAMAGE); + attributes.put("GENERIC_ATTACK_KNOCKBACK", Attribute.ATTACK_KNOCKBACK); + attributes.put("GENERIC_ATTACK_SPEED", Attribute.ATTACK_SPEED); + attributes.put("GENERIC_ARMOR", Attribute.ARMOR); + attributes.put("GENERIC_ARMOR_TOUGHNESS", Attribute.ARMOR_TOUGHNESS); + attributes.put("GENERIC_FALL_DAMAGE_MULTIPLIER", Attribute.FALL_DAMAGE_MULTIPLIER); + attributes.put("GENERIC_LUCK", Attribute.LUCK); + attributes.put("GENERIC_MAX_ABSORPTION", Attribute.MAX_ABSORPTION); + attributes.put("GENERIC_SAFE_FALL_DISTANCE", Attribute.SAFE_FALL_DISTANCE); + attributes.put("GENERIC_SCALE", Attribute.SCALE); + attributes.put("GENERIC_STEP_HEIGHT", Attribute.STEP_HEIGHT); + attributes.put("GENERIC_GRAVITY", Attribute.GRAVITY); + attributes.put("GENERIC_JUMP_STRENGTH", Attribute.JUMP_STRENGTH); + attributes.put("PLAYER_BLOCK_INTERACTION_RANGE", Attribute.BLOCK_INTERACTION_RANGE); + attributes.put("PLAYER_ENTITY_INTERACTION_RANGE", Attribute.ENTITY_INTERACTION_RANGE); + attributes.put("PLAYER_BLOCK_BREAK_SPEED", Attribute.BLOCK_BREAK_SPEED); + attributes.put("ZOMBIE_SPAWN_REINFORCEMENTS", Attribute.SPAWN_REINFORCEMENTS); + ATTRIBUTES = Collections.unmodifiableMap(attributes); + } + + @Override + public Attribute getAttribute(@NotNull String name) { + Attribute converted = ATTRIBUTES.get(name.toUpperCase()); + if (converted != null) + return converted; + return Registry.ATTRIBUTE.get(NamespacedKey.fromString(name.toLowerCase())); + } + + @Override + public @NotNull Map serialize(@NotNull Multimap attributes) { + Map result = new TreeMap<>(); + for (Attribute attribute : attributes.keySet()) + result.put(attribute.getKey().toString(), List.copyOf(attributes.get(attribute))); + return result; + } + + @SuppressWarnings("unchecked") + @Override + public @NotNull Multimap deserialize(@NotNull Map serialized) { + Multimap result = TreeMultimap.create( + Comparator.comparing(attribute -> attribute.getKey().toString()), + Comparator.comparing(AttributeModifier::getKey) + .thenComparing(AttributeModifier::getAmount) + .thenComparing(AttributeModifier::getOperation) + ); + serialized.forEach((attribute, modifiers) -> { + if (modifiers != null) + for (AttributeModifier modifier : ((Collection) modifiers)) + result.put(getAttribute(attribute), modifier); + }); + return result; + } +} diff --git a/versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/ItemAdapter.java b/versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/ItemAdapter.java new file mode 100644 index 00000000..2b9eb1b9 --- /dev/null +++ b/versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/ItemAdapter.java @@ -0,0 +1,171 @@ +package com.wizardlybump17.wlib.adapter.v1_21_r7; + +import com.wizardlybump17.wlib.util.ReflectionUtil; +import net.minecraft.nbt.*; +import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer; +import org.bukkit.inventory.meta.Damageable; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; +import java.util.*; + +public class ItemAdapter extends com.wizardlybump17.wlib.adapter.ItemAdapter { + + public static final @NotNull Class CRAFT_META_ITEM = ReflectionUtil.getClass("org.bukkit.craftbukkit.inventory.CraftMetaItem"); + public static final @NotNull Field CUSTOM_TAG = ReflectionUtil.getField("customTag", CRAFT_META_ITEM); + + @Override + public void transferPersistentData(@NotNull PersistentDataContainer from, @NotNull PersistentDataContainer to) { + Map tags = ((CraftPersistentDataContainer) to).getRaw(); + tags.clear(); + tags.putAll(((CraftPersistentDataContainer) from).getTagsCloned()); + } + + @Override + public void copyPersistentData(@NotNull PersistentDataContainer from, @NotNull PersistentDataContainer to) { + ((CraftPersistentDataContainer) to).getRaw().putAll(((CraftPersistentDataContainer) from).getTagsCloned()); + } + + @Override + public void setDamage(@NotNull ItemMeta meta, @Nullable Integer damage) { + if (!(meta instanceof Damageable damageable)) + return; + + if (damage == null) + damageable.resetDamage(); + else + damageable.setDamage(damage); + } + + @Override + public @Nullable Integer getDamage(@NotNull ItemMeta meta) { + return meta instanceof Damageable damageable && damageable.hasDamage() ? damageable.getDamage() : null; + } + + @Override + public @NotNull Map getCustomData(@NotNull ItemMeta meta) { + Map result = new HashMap<>(); + + CompoundTag tag = ReflectionUtil.getFieldValue(CUSTOM_TAG, meta); + if (tag == null) + return result; + + for (String key : tag.keySet()) { + Tag data = tag.get(key); + if (data != null) + result.put(key, fromNBT(data)); + } + + return result; + } + + @Override + public void setCustomData(@NotNull ItemMeta meta, @NotNull Map customData) { + CompoundTag tag = new CompoundTag(); + for (Map.Entry entry : customData.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + tag.put(key, toNBT(value)); + } + + ReflectionUtil.setFieldValue(CUSTOM_TAG, meta, tag); + } + + @Override + protected @NotNull Tag toNBT(@NotNull Object java) { + return switch (java) { + case Byte b -> ByteTag.valueOf(b); + case Short s -> ShortTag.valueOf(s); + case Integer i -> IntTag.valueOf(i); + case Long l -> LongTag.valueOf(l); + case Float f -> FloatTag.valueOf(f); + case Double d -> DoubleTag.valueOf(d); + + case Boolean b -> ByteTag.valueOf(b); + + case String string -> StringTag.valueOf(string); + + case byte[] byteArray -> new ByteArrayTag(byteArray); + case Byte[] byteArray -> { + byte[] array = new byte[byteArray.length]; + for (int i = 0; i < byteArray.length; i++) + array[i] = byteArray[i]; + yield new ByteArrayTag(array); + } + case int[] intArray -> new IntArrayTag(intArray); + case Integer[] intArray -> { + int[] array = new int[intArray.length]; + for (int i = 0; i < intArray.length; i++) + array[i] = intArray[i]; + yield new IntArrayTag(array); + } + case long[] longArray -> new LongArrayTag(longArray); + case Long[] longArray -> { + long[] array = new long[longArray.length]; + for (int i = 0; i < longArray.length; i++) + array[i] = longArray[i]; + yield new LongArrayTag(array); + } + + case Collection collection -> { + List values = new ArrayList<>(collection.size()); + for (Object object : collection) { + Tag tag = toNBT(object); + values.add(tag); + } + yield new ListTag(values); + } + + case Map map -> { + Map values = new HashMap<>(map.size()); + map.forEach((key, value) -> values.put(String.valueOf(key), toNBT(value))); + + CompoundTag tag = new CompoundTag(); + values.forEach(tag::put); + yield tag; + } + + default -> throw new UnsupportedOperationException("Unsupported Java type: " + java); + }; + } + + @Override + protected @NotNull Object fromNBT(@NotNull Object nbt) { + return switch (nbt) { + case ByteTag tag -> tag.byteValue(); + case ShortTag tag -> tag.shortValue(); + case IntTag tag -> tag.intValue(); + case LongTag tag -> tag.longValue(); + case FloatTag tag -> tag.floatValue(); + case DoubleTag tag -> tag.doubleValue(); + + case StringTag tag -> tag.value(); + + case ByteArrayTag tag -> tag.getAsByteArray(); + case IntArrayTag tag -> tag.getAsIntArray(); + case LongArrayTag tag -> tag.getAsLongArray(); + + case CollectionTag tag -> { + List list = new ArrayList<>(tag.size()); + for (Tag value : tag) + list.add(fromNBT(value)); + yield list; + } + + case CompoundTag tag -> { + Map map = new HashMap<>(tag.size()); + for (String key : tag.keySet()) { + Tag value = tag.get(key); + if (value != null) + map.put(key, fromNBT(value)); + } + yield map; + } + + default -> throw new UnsupportedOperationException("Unsupported NBT type: " + nbt); + }; + } +} \ No newline at end of file diff --git a/versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/player/PlayerAdapter.java b/versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/player/PlayerAdapter.java new file mode 100644 index 00000000..d76adb40 --- /dev/null +++ b/versions/v1_21_r7/src/main/java/com/wizardlybump17/wlib/adapter/v1_21_r7/player/PlayerAdapter.java @@ -0,0 +1,39 @@ +package com.wizardlybump17.wlib.adapter.v1_21_r7.player; + +import com.wizardlybump17.wlib.util.ReflectionUtil; +import org.bukkit.conversations.Conversation; +import org.bukkit.craftbukkit.conversations.ConversationTracker; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Predicate; + +public class PlayerAdapter extends com.wizardlybump17.wlib.adapter.player.PlayerAdapter { + + public static final @NotNull Field CONVERSATION_TRACKER = ReflectionUtil.getField("conversationTracker", CraftPlayer.class); + public static final @NotNull Field CONVERSATION_QUEUE = ReflectionUtil.getField("conversationQueue", ConversationTracker.class); + + @Override + public @Nullable Conversation getConversation(@NotNull Player player) { + return getConversationQueue(player).getFirst(); + } + + @Override + public @NotNull List getConversationQueue(@NotNull Player player) { + return ReflectionUtil.getFieldValue(CONVERSATION_QUEUE, ReflectionUtil.getFieldValue(CONVERSATION_TRACKER, player)); + } + + @Override + public @NotNull List abandonConversations(@NotNull Player player, @NotNull Predicate filter) { + List queue = getConversationQueue(player); + List removed = new ArrayList<>(queue); + queue.removeIf(filter); + removed.removeAll(queue); + return removed; + } +} From b910cea32e997cbd2f77ff839cd1fa63324e5604 Mon Sep 17 00:00:00 2001 From: WizardlyBump17 Date: Fri, 6 Feb 2026 19:35:56 -0300 Subject: [PATCH 2/3] including the 1.21.11 stuff --- core/build.gradle | 1 + core/src/main/java/com/wizardlybump17/wlib/WLib.java | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/core/build.gradle b/core/build.gradle index 41d1f181..4706f9f0 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -14,6 +14,7 @@ dependencies { project(':versions:v1_21_R1'), project(':versions:v1_21_R3'), project(':versions:v1_21_R5'), + project(':versions:v1_21_r7'), project(':database'), diff --git a/core/src/main/java/com/wizardlybump17/wlib/WLib.java b/core/src/main/java/com/wizardlybump17/wlib/WLib.java index 3e1d35fd..59e49b5f 100644 --- a/core/src/main/java/com/wizardlybump17/wlib/WLib.java +++ b/core/src/main/java/com/wizardlybump17/wlib/WLib.java @@ -135,6 +135,11 @@ private void setupAdapters() { PlayerAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_R5.player.PlayerAdapter()); AttributeAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_R5.AttributeAdapter()); } + case "1.21.11" -> { + ItemAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_r7.ItemAdapter()); + PlayerAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_r7.player.PlayerAdapter()); + AttributeAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_r7.AttributeAdapter()); + } default -> getLogger().severe("The server version (" + version + ") is not supported by WLib yet."); } } From 226bb11ca05d710e015783d7964b608e1fb5be2f Mon Sep 17 00:00:00 2001 From: WizardlyBump17 Date: Fri, 6 Feb 2026 19:36:59 -0300 Subject: [PATCH 3/3] added a fallback to the last known version --- core/src/main/java/com/wizardlybump17/wlib/WLib.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/wizardlybump17/wlib/WLib.java b/core/src/main/java/com/wizardlybump17/wlib/WLib.java index 59e49b5f..2b7bbfca 100644 --- a/core/src/main/java/com/wizardlybump17/wlib/WLib.java +++ b/core/src/main/java/com/wizardlybump17/wlib/WLib.java @@ -140,7 +140,13 @@ private void setupAdapters() { PlayerAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_r7.player.PlayerAdapter()); AttributeAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_r7.AttributeAdapter()); } - default -> getLogger().severe("The server version (" + version + ") is not supported by WLib yet."); + default -> { + getLogger().severe("The server version (" + version + ") is not supported by WLib yet. Using last known version (1.21.11), but expect stuff to break."); + + ItemAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_r7.ItemAdapter()); + PlayerAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_r7.player.PlayerAdapter()); + AttributeAdapter.setInstance(new com.wizardlybump17.wlib.adapter.v1_21_r7.AttributeAdapter()); + } } }