From 0f6f5a5bef740bd63da8325697e7701878d1a180 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 13 Jun 2025 03:12:53 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=89=A9=E5=93=81?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=EF=BC=8C=E9=81=BF=E5=85=8D=E4=BD=BF=E7=94=A8?= =?UTF-8?q?Bukkit=20ItemStack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/BukkitCustomItem.java | 53 ++++++++++++------- .../bukkit/item/BukkitItemManager.java | 16 ++++-- .../craftengine/core/item/CustomItem.java | 2 + 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java index 80b45ab79..7586e1919 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitCustomItem.java @@ -1,7 +1,7 @@ package net.momirealms.craftengine.bukkit.item; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; -import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.core.item.*; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.modifier.ItemDataModifier; @@ -10,7 +10,6 @@ import net.momirealms.craftengine.core.plugin.context.event.EventTrigger; import net.momirealms.craftengine.core.plugin.context.function.Function; import net.momirealms.craftengine.core.registry.Holder; import net.momirealms.craftengine.core.util.Key; -import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import java.util.ArrayList; @@ -19,22 +18,23 @@ import java.util.List; import java.util.Map; public class BukkitCustomItem extends AbstractCustomItem { - private final Material material; + private final Object item; + private final Object clientItem; - public BukkitCustomItem(Holder id, Material material, Key materialKey, Key clientBoundMaterialKey, + public BukkitCustomItem(Holder id, Object item, Object clientItem, Key materialKey, Key clientBoundMaterialKey, List behaviors, List> modifiers, List> clientBoundModifiers, ItemSettings settings, Map>> events) { super(id, materialKey, clientBoundMaterialKey, behaviors, modifiers, clientBoundModifiers, settings, events); - this.material = material; + this.item = item; + this.clientItem = clientItem; } @Override public ItemStack buildItemStack(ItemBuildContext context, int count) { - ItemStack item = new ItemStack(this.material); + ItemStack item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.constructor$ItemStack(this.item, count)); Item wrapped = BukkitCraftEngine.instance().itemManager().wrap(item); - wrapped.count(count); for (ItemDataModifier modifier : this.modifiers) { modifier.apply(wrapped, context); } @@ -43,7 +43,7 @@ public class BukkitCustomItem extends AbstractCustomItem { @Override public Item buildItem(ItemBuildContext context) { - ItemStack item = new ItemStack(this.material); + ItemStack item = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.constructor$ItemStack(this.item, 1)); Item wrapped = BukkitCraftEngine.instance().itemManager().wrap(item); for (ItemDataModifier modifier : dataModifiers()) { modifier.apply(wrapped, context); @@ -51,24 +51,33 @@ public class BukkitCustomItem extends AbstractCustomItem { return BukkitCraftEngine.instance().itemManager().wrap(wrapped.load()); } - public static Builder builder(Material material) { - return new BuilderImpl(material); + public Object clientItem() { + return clientItem; + } + + public Object item() { + return item; + } + + public static Builder builder(Object item, Object clientBoundItem) { + return new BuilderImpl(item, clientBoundItem); } public static class BuilderImpl implements Builder { private Holder id; - private final Key materialKey; - private final Material material; - private Key clientBoundMaterialKey; + private Key itemKey; + private final Object item; + private Key clientBoundItemKey; + private final Object clientBoundItem; private final Map>> events = new EnumMap<>(EventTrigger.class); private final List behaviors = new ArrayList<>(4); private final List> modifiers = new ArrayList<>(4); private final List> clientBoundModifiers = new ArrayList<>(4); private ItemSettings settings; - public BuilderImpl(Material material) { - this.material = material; - this.materialKey = KeyUtils.namespacedKey2Key(material.getKey()); + public BuilderImpl(Object item, Object clientBoundItem) { + this.item = item; + this.clientBoundItem = clientBoundItem; } @Override @@ -78,8 +87,14 @@ public class BukkitCustomItem extends AbstractCustomItem { } @Override - public Builder clientBoundMaterial(Key clientBoundMaterialKey) { - this.clientBoundMaterialKey = clientBoundMaterialKey; + public Builder clientBoundMaterial(Key clientBoundMaterial) { + this.clientBoundItemKey = clientBoundMaterial; + return this; + } + + @Override + public Builder material(Key material) { + this.itemKey = material; return this; } @@ -134,7 +149,7 @@ public class BukkitCustomItem extends AbstractCustomItem { @Override public CustomItem build() { this.modifiers.addAll(this.settings.modifiers()); - return new BukkitCustomItem(this.id, this.material, this.materialKey, this.clientBoundMaterialKey, List.copyOf(this.behaviors), + return new BukkitCustomItem(this.id, this.item, this.clientBoundItem, this.itemKey, this.clientBoundItemKey, List.copyOf(this.behaviors), List.copyOf(this.modifiers), List.copyOf(this.clientBoundModifiers), this.settings, this.events); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index 450cf2d45..a74547ea7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -13,6 +13,7 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MBuiltInRegistries; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistries; +import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.MRegistryOps; import net.momirealms.craftengine.bukkit.util.ItemUtils; import net.momirealms.craftengine.bukkit.util.KeyUtils; import net.momirealms.craftengine.core.entity.player.Player; @@ -201,11 +202,18 @@ public class BukkitItemManager extends AbstractItemManager { @Override protected CustomItem.Builder createPlatformItemBuilder(Holder id, Key materialId, Key clientBoundMaterialId) { - Material material = ResourceConfigUtils.requireNonNullOrThrow(Registry.MATERIAL.get(KeyUtils.toNamespacedKey(materialId)), () -> new LocalizedResourceConfigException("warning.config.item.invalid_material", materialId.toString())); - if (!clientBoundMaterialId.equals(materialId)) { - ResourceConfigUtils.requireNonNullOrThrow(Registry.MATERIAL.get(KeyUtils.toNamespacedKey(clientBoundMaterialId)), () -> new LocalizedResourceConfigException("warning.config.item.invalid_material", clientBoundMaterialId.toString())); + Object item = FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, KeyUtils.toResourceLocation(materialId)); + Object clientBoundItem = materialId == clientBoundMaterialId ? item : FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, KeyUtils.toResourceLocation(clientBoundMaterialId)); + if (item == null) { + throw new LocalizedResourceConfigException("warning.config.item.invalid_material", materialId.toString()); } - return BukkitCustomItem.builder(material).id(id).clientBoundMaterial(clientBoundMaterialId); + if (clientBoundItem == null) { + throw new LocalizedResourceConfigException("warning.config.item.invalid_material", clientBoundMaterialId.toString()); + } + return BukkitCustomItem.builder(item, clientBoundItem) + .id(id) + .material(materialId) + .clientBoundMaterial(clientBoundMaterialId); } @SuppressWarnings("unchecked") diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java index 217b7066f..01512fa5a 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/CustomItem.java @@ -56,6 +56,8 @@ public interface CustomItem extends BuildableItem { Builder clientBoundMaterial(Key clientBoundMaterialKey); + Builder material(Key material); + Builder dataModifier(ItemDataModifier modifier); Builder dataModifiers(List> modifiers); From fed23ef21404caeaf36a4a9ed4e94fa7060c2afa Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 13 Jun 2025 03:50:32 +0800 Subject: [PATCH 02/13] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AE=A2=E6=88=B7?= =?UTF-8?q?=E7=AB=AF=E6=9D=90=E8=B4=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/LegacyNetworkItemHandler.java | 14 ++++++++------ .../bukkit/item/ModernNetworkItemHandler.java | 13 +++++++------ .../item/factory/ComponentItemFactory1_20_5.java | 13 ++++++++++--- .../bukkit/item/factory/UniversalItemFactory.java | 13 ++++++++++--- .../craftengine/core/item/AbstractItem.java | 5 +++++ .../net/momirealms/craftengine/core/item/Item.java | 2 ++ .../craftengine/core/item/ItemFactory.java | 2 ++ .../craftengine/core/pack/AbstractPackManager.java | 1 + gradle.properties | 2 +- 9 files changed, 46 insertions(+), 19 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java index 85a1a4ce8..204680ad5 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.bukkit.item; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.Item; @@ -25,6 +26,7 @@ import java.util.Map; import java.util.Optional; import java.util.function.BiConsumer; +@SuppressWarnings("DuplicatedCode") public class LegacyNetworkItemHandler implements NetworkItemHandler { @Override @@ -32,9 +34,9 @@ public class LegacyNetworkItemHandler implements NetworkItemHandler { Optional> optionalCustomItem = wrapped.getCustomItem(); boolean hasDifferentMaterial = false; if (optionalCustomItem.isPresent()) { - CustomItem customItem = optionalCustomItem.get(); - if (!customItem.material().equals(wrapped.vanillaId())) { - wrapped = wrapped.transmuteCopy(customItem.material()); + BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get(); + if (customItem.item() != FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject())) { + wrapped = wrapped.unsafeTransmuteCopy(customItem.item(), wrapped.count()); hasDifferentMaterial = true; } } @@ -61,10 +63,10 @@ public class LegacyNetworkItemHandler implements NetworkItemHandler { if (!Config.interceptItem()) return Optional.empty(); return new OtherItem(wrapped, false).process(); } else { - CustomItem customItem = optionalCustomItem.get(); - boolean hasDifferentMaterial = !wrapped.vanillaId().equals(customItem.clientBoundMaterial()); + BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get(); + boolean hasDifferentMaterial = FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getItem()) != customItem.clientItem(); if (hasDifferentMaterial) { - wrapped = wrapped.transmuteCopy(customItem.clientBoundMaterial()); + wrapped = wrapped.unsafeTransmuteCopy(customItem.clientItem(), wrapped.count()); } if (!customItem.hasClientBoundDataModifier()) { if (!Config.interceptItem() && !hasDifferentMaterial) return Optional.empty(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java index 460deddcd..f9aecf921 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.bukkit.item; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.*; import net.momirealms.craftengine.core.item.modifier.ArgumentModifier; @@ -33,9 +34,9 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler> optionalCustomItem = wrapped.getCustomItem(); boolean hasDifferentMaterial = false; if (optionalCustomItem.isPresent()) { - CustomItem customItem = optionalCustomItem.get(); - if (!customItem.material().equals(wrapped.vanillaId())) { - wrapped = wrapped.transmuteCopy(customItem.material()); + BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get(); + if (customItem.item() != FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject())) { + wrapped = wrapped.unsafeTransmuteCopy(customItem.item(), wrapped.count()); hasDifferentMaterial = true; } } @@ -64,10 +65,10 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler customItem = optionalCustomItem.get(); - boolean hasDifferentMaterial = !wrapped.vanillaId().equals(customItem.clientBoundMaterial()); + BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get(); + boolean hasDifferentMaterial = FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getItem()) != customItem.clientItem(); if (hasDifferentMaterial) { - wrapped = wrapped.transmuteCopy(customItem.clientBoundMaterial()); + wrapped = wrapped.unsafeTransmuteCopy(customItem.clientItem(), wrapped.count()); } if (!customItem.hasClientBoundDataModifier()) { if (!Config.interceptItem() && !hasDifferentMaterial) return Optional.empty(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java index c7ad75a33..1a3c19dc9 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_20_5.java @@ -526,9 +526,16 @@ public class ComponentItemFactory1_20_5 extends BukkitItemFactory { @Override protected LegacyItemWrapper mergeCopy(LegacyItemWrapper item1, LegacyItemWrapper item2) { Object itemStack = ItemObject.copy(item2.getLiteralObject()); - ItemObject.setCustomDataTag(itemStack, TagCompound.clone(FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(item1.getLiteralObject()))); + FastNMS.INSTANCE.method$ItemStack$setTag(itemStack, TagCompound.clone(FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(item1.getLiteralObject()))); // one more step than vanilla TagCompound.merge(FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(itemStack), FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(item2.getLiteralObject()), true, true); return new LegacyItemWrapper(new RtagItem(FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(itemStack))); @@ -318,7 +318,7 @@ public class UniversalItemFactory extends BukkitItemFactory { protected void merge(LegacyItemWrapper item1, LegacyItemWrapper item2) { // load previous changes on nms items item1.load(); - TagCompound.merge(ItemObject.getCustomDataTag(item1.getLiteralObject()), ItemObject.getCustomDataTag(item2.getLiteralObject()), true, true); + TagCompound.merge(FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(item1.getLiteralObject()), FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(item2.getLiteralObject()), true, true); // update wrapped item item1.update(); } @@ -326,7 +326,14 @@ public class UniversalItemFactory extends BukkitItemFactory { @Override protected LegacyItemWrapper transmuteCopy(LegacyItemWrapper item, Key newItem, int amount) { Object newItemStack = FastNMS.INSTANCE.constructor$ItemStack(FastNMS.INSTANCE.method$Registry$getValue(MBuiltInRegistries.ITEM, KeyUtils.toResourceLocation(newItem)), amount); - ItemObject.setCustomDataTag(newItemStack, TagCompound.clone(FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(item.getLiteralObject()))); + FastNMS.INSTANCE.method$ItemStack$setTag(newItemStack, TagCompound.clone(FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(item.getLiteralObject()))); + return new LegacyItemWrapper(new RtagItem(ItemObject.asCraftMirror(newItemStack))); + } + + @Override + protected LegacyItemWrapper unsafeTransmuteCopy(LegacyItemWrapper item, Object newItem, int amount) { + Object newItemStack = FastNMS.INSTANCE.constructor$ItemStack(newItem, amount); + FastNMS.INSTANCE.method$ItemStack$setTag(newItemStack, TagCompound.clone(FastNMS.INSTANCE.field$ItemStack$getOrCreateTag(item.getLiteralObject()))); return new LegacyItemWrapper(new RtagItem(ItemObject.asCraftMirror(newItemStack))); } } \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java index be0e995d5..219dd5e3f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItem.java @@ -429,6 +429,11 @@ public class AbstractItem, I> implements Item { return new AbstractItem<>(this.factory, this.factory.transmuteCopy(this.item, another, count)); } + @Override + public Item unsafeTransmuteCopy(Object another, int count) { + return new AbstractItem<>(this.factory, this.factory.unsafeTransmuteCopy(this.item, another, count)); + } + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public void merge(Item another) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java index adbc45d3e..8b2954c31 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/Item.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/Item.java @@ -181,6 +181,8 @@ public interface Item { Item transmuteCopy(Key another, int count); + Item unsafeTransmuteCopy(Object another, int count); + void shrink(int amount); default Item transmuteCopy(Key another) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java index 4c19ce8ef..783bf3365 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemFactory.java @@ -196,4 +196,6 @@ public abstract class ItemFactory, I> { protected abstract void setNBTComponent(W item, Object type, Tag value); protected abstract W transmuteCopy(W item, Key newItem, int amount); + + protected abstract W unsafeTransmuteCopy(W item, Object newItem, int count); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 55c1244a8..cf807696c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -116,6 +116,7 @@ public abstract class AbstractPackManager implements PackManager { loadInternalList("models", "block/", VANILLA_MODELS::add); loadInternalList("models", "item/", VANILLA_MODELS::add); + VANILLA_MODELS.add(Key.of("minecraft", "builtin/entity")); } private void loadInternalData(String path, BiConsumer callback) { diff --git a/gradle.properties b/gradle.properties index 5ead891b5..a3f1ff254 100644 --- a/gradle.properties +++ b/gradle.properties @@ -51,7 +51,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.17 -nms_helper_version=0.67.10 +nms_helper_version=0.67.11 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23 From a41a38236bd56b2ef6a7009fee09339a46a497b5 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 13 Jun 2025 04:02:25 +0800 Subject: [PATCH 03/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=94=B9=E5=8C=85?= =?UTF-8?q?=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/item/LegacyNetworkItemHandler.java | 2 +- .../craftengine/bukkit/item/ModernNetworkItemHandler.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java index 204680ad5..9a2050efe 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java @@ -64,7 +64,7 @@ public class LegacyNetworkItemHandler implements NetworkItemHandler { return new OtherItem(wrapped, false).process(); } else { BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get(); - boolean hasDifferentMaterial = FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getItem()) != customItem.clientItem(); + boolean hasDifferentMaterial = FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject()) != customItem.clientItem(); if (hasDifferentMaterial) { wrapped = wrapped.unsafeTransmuteCopy(customItem.clientItem(), wrapped.count()); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java index f9aecf921..c584d3de4 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java @@ -66,7 +66,7 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler Date: Fri, 13 Jun 2025 04:05:25 +0800 Subject: [PATCH 04/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=97=A7=E7=89=88?= =?UTF-8?q?=E6=9C=ACunicode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../momirealms/craftengine/core/pack/AbstractPackManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index cf807696c..5b8093283 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -117,6 +117,9 @@ public abstract class AbstractPackManager implements PackManager { loadInternalList("models", "block/", VANILLA_MODELS::add); loadInternalList("models", "item/", VANILLA_MODELS::add); VANILLA_MODELS.add(Key.of("minecraft", "builtin/entity")); + for (int i = 0; i < 256; i++) { + VANILLA_TEXTURES.add(Key.of("minecraft", "font/unicode_page_" + String.format("%02x", i))); + } } private void loadInternalData(String path, BiConsumer callback) { From ade7a75631813009a6671e9377da2fe59d893049 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 13 Jun 2025 04:07:37 +0800 Subject: [PATCH 05/13] 0.0.57 release --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a3f1ff254..7be6991a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.56.7 +project_version=0.0.57 config_version=37 lang_version=16 project_group=net.momirealms From 65f2ab7ab8553a1fdbc8061ce7075f70f195e028 Mon Sep 17 00:00:00 2001 From: Catnies Date: Fri, 13 Jun 2025 08:55:29 +0800 Subject: [PATCH 06/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Linux=20=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E4=B8=8B=E4=B8=8D=E4=BC=9A=E6=AD=A5=E8=BF=9B=E7=AC=A6?= =?UTF-8?q?=E5=8F=B7=E9=93=BE=E6=8E=A5=E8=AF=BB=E5=8F=96=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/core/pack/AbstractPackManager.java | 12 ++++++------ .../core/plugin/locale/TranslationManagerImpl.java | 7 ++----- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java index 5b8093283..a5fecf689 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/pack/AbstractPackManager.java @@ -465,7 +465,7 @@ public abstract class AbstractPackManager implements PackManager { Path configurationFolderPath = pack.configurationFolder(); if (!Files.isDirectory(configurationFolderPath)) continue; try { - Files.walkFileTree(configurationFolderPath, new SimpleFileVisitor<>() { + Files.walkFileTree(configurationFolderPath, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<>() { @Override public @NotNull FileVisitResult visitFile(@NotNull Path path, @NotNull BasicFileAttributes attrs) { if (Files.isRegularFile(path) && path.getFileName().toString().endsWith(".yml")) { @@ -632,7 +632,7 @@ public abstract class AbstractPackManager implements PackManager { for (Path namespacePath : FileUtils.collectNamespaces(assetsPath)) { Path fontPath = namespacePath.resolve("font"); if (Files.isDirectory(fontPath)) { - Files.walkFileTree(fontPath, new SimpleFileVisitor<>() { + Files.walkFileTree(fontPath, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<>() { @Override public @NotNull FileVisitResult visitFile(@NotNull Path file, @NotNull BasicFileAttributes attrs) throws IOException { if (!isJsonFile(file)) return FileVisitResult.CONTINUE; @@ -658,7 +658,7 @@ public abstract class AbstractPackManager implements PackManager { Path itemsPath = namespacePath.resolve("items"); if (Files.isDirectory(itemsPath)) { - Files.walkFileTree(itemsPath, new SimpleFileVisitor<>() { + Files.walkFileTree(itemsPath, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<>() { @Override public @NotNull FileVisitResult visitFile(@NotNull Path file, @NotNull BasicFileAttributes attrs) throws IOException { if (!isJsonFile(file)) return FileVisitResult.CONTINUE; @@ -672,7 +672,7 @@ public abstract class AbstractPackManager implements PackManager { Path blockStatesPath = namespacePath.resolve("blockstates"); if (Files.isDirectory(blockStatesPath)) { - Files.walkFileTree(blockStatesPath, new SimpleFileVisitor<>() { + Files.walkFileTree(blockStatesPath, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<>() { @Override public @NotNull FileVisitResult visitFile(@NotNull Path file, @NotNull BasicFileAttributes attrs) throws IOException { if (!isJsonFile(file)) return FileVisitResult.CONTINUE; @@ -1451,7 +1451,7 @@ public abstract class AbstractPackManager implements PackManager { .toList()); for (Path sourceFolder : folders) { if (Files.exists(sourceFolder)) { - Files.walkFileTree(sourceFolder, new SimpleFileVisitor<>() { + Files.walkFileTree(sourceFolder, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<>() { @Override public @NotNull FileVisitResult visitFile(@NotNull Path file, @NotNull BasicFileAttributes attrs) throws IOException { processRegularFile(file, attrs, sourceFolder, fs, conflictChecker, previousFiles); @@ -1504,7 +1504,7 @@ public abstract class AbstractPackManager implements PackManager { long zipLastModified = Files.getLastModifiedTime(zipFile).toMillis(); long zipSize = Files.size(zipFile); Path zipRoot = zipFs.getPath("/"); - Files.walkFileTree(zipRoot, new SimpleFileVisitor<>() { + Files.walkFileTree(zipRoot, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<>() { @Override public @NotNull FileVisitResult visitFile(@NotNull Path entry, @NotNull BasicFileAttributes entryAttrs) throws IOException { if (entryAttrs.isDirectory()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManagerImpl.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManagerImpl.java index 6a494b950..041436ec6 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManagerImpl.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/locale/TranslationManagerImpl.java @@ -23,10 +23,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; +import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -163,7 +160,7 @@ public class TranslationManagerImpl implements TranslationManager { Map previousTranslations = this.cachedTranslations; this.cachedTranslations = new HashMap<>(); try { - Files.walkFileTree(directory, new SimpleFileVisitor<>() { + Files.walkFileTree(directory, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor<>() { @Override public @NotNull FileVisitResult visitFile(@NotNull Path path, @NotNull BasicFileAttributes attrs) { String fileName = path.getFileName().toString(); From 0d10b28d84f67b561ffc49f46be15deb7bb44caf Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 13 Jun 2025 15:11:59 +0800 Subject: [PATCH 07/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BD=8E=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/item/listener/ItemEventListener.java | 2 +- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java index 7be490882..be955e898 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java @@ -404,7 +404,7 @@ public class ItemEventListener implements Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onEntityDamage(EntityDamageEvent event) { - if (event.getEntityType() == EntityType.ITEM && event.getEntity() instanceof org.bukkit.entity.Item item) { + if (event.getEntity() instanceof org.bukkit.entity.Item item) { Optional.ofNullable(this.plugin.itemManager().wrap(item.getItemStack())) .flatMap(Item::getCustomItem) .ifPresent(it -> { diff --git a/gradle.properties b/gradle.properties index 7be6991a5..2d8b56c48 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.57 +project_version=0.0.57.1 config_version=37 lang_version=16 project_group=net.momirealms From f2ad6f2ba196664cd7fdac675694f1424ba53df2 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 13 Jun 2025 16:47:25 +0800 Subject: [PATCH 08/13] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E6=94=B9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../craftengine/bukkit/item/LegacyNetworkItemHandler.java | 3 ++- .../craftengine/bukkit/item/ModernNetworkItemHandler.java | 3 ++- .../java/net/momirealms/craftengine/core/util/FileUtils.java | 5 +++-- gradle.properties | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java index 9a2050efe..871bbcb32 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/LegacyNetworkItemHandler.java @@ -64,7 +64,8 @@ public class LegacyNetworkItemHandler implements NetworkItemHandler { return new OtherItem(wrapped, false).process(); } else { BukkitCustomItem customItem = (BukkitCustomItem) optionalCustomItem.get(); - boolean hasDifferentMaterial = FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject()) != customItem.clientItem(); + Object serverItem = FastNMS.INSTANCE.method$ItemStack$getItem(wrapped.getLiteralObject()); + boolean hasDifferentMaterial = serverItem == customItem.item() && serverItem != customItem.clientItem(); if (hasDifferentMaterial) { wrapped = wrapped.unsafeTransmuteCopy(customItem.clientItem(), wrapped.count()); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java index c584d3de4..f58ccad29 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/ModernNetworkItemHandler.java @@ -66,7 +66,8 @@ public final class ModernNetworkItemHandler implements NetworkItemHandler walk = Files.walk(folder)) { + try (Stream walk = Files.walk(folder, FileVisitOption.FOLLOW_LINKS)) { walk.sorted(Comparator.reverseOrder()) .forEach(path -> { try { @@ -51,7 +52,7 @@ public class FileUtils { if (!Files.exists(configFolder)) { return List.of(); } - try (Stream stream = Files.walk(configFolder)) { + try (Stream stream = Files.walk(configFolder, FileVisitOption.FOLLOW_LINKS)) { return stream.parallel() .filter(Files::isRegularFile) .filter(path -> path.toString().endsWith(".yml")) diff --git a/gradle.properties b/gradle.properties index 2d8b56c48..ef3e8ef9d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -41,7 +41,7 @@ commons_io_version=2.18.0 commons_imaging_version=1.0.0-alpha6 commons_lang3_version=3.17.0 sparrow_nbt_version=0.9.1 -sparrow_util_version=0.49.1 +sparrow_util_version=0.49.2 fastutil_version=8.5.15 netty_version=4.1.121.Final joml_version=1.10.8 From 069be96fd3d546c4c9ec8dbb8991c690efe18a54 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 13 Jun 2025 17:21:12 +0800 Subject: [PATCH 09/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=B0=9D=E8=AF=95?= =?UTF-8?q?=E7=A0=B4=E5=9D=8F=E5=AE=B6=E5=85=B7=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/event/FurnitureAttemptBreakEvent.java | 56 +++++++++++++++++++ .../bukkit/block/BlockEventListener.java | 2 +- .../plugin/network/PacketConsumers.java | 12 +++- 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptBreakEvent.java diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptBreakEvent.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptBreakEvent.java new file mode 100644 index 000000000..6a26aab44 --- /dev/null +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/api/event/FurnitureAttemptBreakEvent.java @@ -0,0 +1,56 @@ +package net.momirealms.craftengine.bukkit.api.event; + +import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.jetbrains.annotations.NotNull; + +public class FurnitureAttemptBreakEvent extends PlayerEvent implements Cancellable { + private static final HandlerList HANDLER_LIST = new HandlerList(); + private boolean cancelled; + private final BukkitFurniture furniture; + + public FurnitureAttemptBreakEvent(@NotNull Player player, + @NotNull BukkitFurniture furniture) { + super(player); + this.furniture = furniture; + } + + @NotNull + public Player player() { + return getPlayer(); + } + + @NotNull + public BukkitFurniture furniture() { + return this.furniture; + } + + @NotNull + public Location location() { + return this.furniture.location(); + } + + @NotNull + public static HandlerList getHandlerList() { + return HANDLER_LIST; + } + + @NotNull + public HandlerList getHandlers() { + return getHandlerList(); + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } +} diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index 3cefc336a..7bb781fd2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -347,7 +347,7 @@ public class BlockEventListener implements Listener { Block block = blocks.get(i); Location location = block.getLocation(); BlockPos blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()); - ImmutableBlockState state = manager.getImmutableBlockState(BlockStateUtils.blockDataToId(block.getBlockData())); + ImmutableBlockState state = this.manager.getImmutableBlockState(BlockStateUtils.blockDataToId(block.getBlockData())); if (state != null && !state.isEmpty()) { WorldPosition position = new WorldPosition(world, Vec3d.atCenterOf(blockPos)); ContextHolder.Builder builder = ContextHolder.builder() diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index df11ad10b..d58934ded 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -12,6 +12,7 @@ import net.kyori.adventure.text.TranslationArgument; import net.momirealms.craftengine.bukkit.api.CraftEngineFurniture; import net.momirealms.craftengine.bukkit.api.event.FurnitureBreakEvent; import net.momirealms.craftengine.bukkit.api.event.FurnitureInteractEvent; +import net.momirealms.craftengine.bukkit.api.event.FurnitureAttemptBreakEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurniture; import net.momirealms.craftengine.bukkit.entity.furniture.BukkitFurnitureManager; @@ -1539,9 +1540,14 @@ public class PacketConsumers { mainThreadTask = () -> { // todo 冒险模式破坏工具白名单 if (serverPlayer.isAdventureMode() || - !furniture.isValid() || - !BukkitCraftEngine.instance().antiGrief().canBreak(platformPlayer, location) - ) return; + !furniture.isValid()) return; + + FurnitureAttemptBreakEvent preBreakEvent = new FurnitureAttemptBreakEvent(serverPlayer.platformPlayer(), furniture); + if (EventUtils.fireAndCheckCancel(preBreakEvent)) + return; + + if (!BukkitCraftEngine.instance().antiGrief().canBreak(platformPlayer, location)) + return; FurnitureBreakEvent breakEvent = new FurnitureBreakEvent(serverPlayer.platformPlayer(), furniture); if (EventUtils.fireAndCheckCancel(breakEvent)) From ff4e1754c578471d37f6368dd417bfb3296b1977 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Fri, 13 Jun 2025 17:59:23 +0800 Subject: [PATCH 10/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=B0=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../default/configuration/templates.yml | 18 +++++++++++++ .../core/item/AbstractItemManager.java | 26 ++++++++++++------- .../craftengine/core/item/ItemSettings.java | 15 +++++++++++ gradle.properties | 2 +- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/common-files/src/main/resources/resources/default/configuration/templates.yml b/common-files/src/main/resources/resources/default/configuration/templates.yml index 73324b0ed..a17ac404a 100644 --- a/common-files/src/main/resources/resources/default/configuration/templates.yml +++ b/common-files/src/main/resources/resources/default/configuration/templates.yml @@ -1,5 +1,23 @@ # This file contains some useful template data. If you have good ideas, you are welcome to contribute your template! +# These templates let you ditch the real custom_model_data on the server side. +# Instead, we use client side components sent via packets to control how items look. +templates#client_bound_model: + default:item/client_bound_custom_model_data: + custom-model-data: "${custom_model_data}" + data: + remove-components: + - minecraft:custom_model_data + client-bound-data: + custom-model-data: "${custom_model_data}" + default:item/client_bound_item_model: + item-model: "${item_model}" + data: + remove-components: + - minecraft:item_model + client-bound-data: + item-model: "${item_model}" + # blocks templates#models#block: # template: default:model/cube_all diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java index 39d2189ef..babf72df8 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/AbstractItemManager.java @@ -478,6 +478,10 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl boolean value = TypeUtils.checkType(obj, Boolean.class); return new UnbreakableModifier<>(value); }, "unbreakable"); + registerDataType((obj) -> { + int customModelData = ResourceConfigUtils.getAsInt(obj, "custom-model-data"); + return new CustomModelDataModifier<>(customModelData); + }, "custom-model-data"); registerDataType((obj) -> { Map data = MiscUtils.castToMap(obj, false); List enchantments = new ArrayList<>(); @@ -494,6 +498,14 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl String pattern = data.get("pattern").toString().toLowerCase(Locale.ENGLISH); return new TrimModifier<>(material, pattern); }, "trim"); + registerDataType((obj) -> { + Map data = MiscUtils.castToMap(obj, false); + Map arguments = new HashMap<>(); + for (Map.Entry entry : data.entrySet()) { + arguments.put(entry.getKey(), TextProviders.fromString(entry.getValue().toString())); + } + return new ArgumentModifier<>(arguments); + }, "args", "argument", "arguments"); if (VersionHelper.isOrAbove1_20_5()) { registerDataType((obj) -> { Map data = MiscUtils.castToMap(obj, false); @@ -521,21 +533,15 @@ public abstract class AbstractItemManager extends AbstractModelGenerator impl String id = obj.toString(); return new TooltipStyleModifier<>(Key.of(id)); }, "tooltip-style"); - } - if (VersionHelper.isOrAbove1_21_2()) { registerDataType((obj) -> { Map data = MiscUtils.castToMap(obj, false); return new EquippableModifier<>(EquipmentData.fromMap(data)); }, "equippable"); + registerDataType((obj) -> { + String id = obj.toString(); + return new ItemModelModifier<>(Key.of(id)); + }, "item-model"); } - registerDataType((obj) -> { - Map data = MiscUtils.castToMap(obj, false); - Map arguments = new HashMap<>(); - for (Map.Entry entry : data.entrySet()) { - arguments.put(entry.getKey(), TextProviders.fromString(entry.getValue().toString())); - } - return new ArgumentModifier<>(arguments); - }, "args", "argument", "arguments"); } protected void processModelRecursively( diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java index 7136f8b50..ea6e079d4 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java @@ -36,6 +36,7 @@ public class ItemSettings { Key consumeReplacement = null; Key craftRemainder = null; List invulnerable = List.of(); + boolean canEnchant = true; private ItemSettings() {} @@ -75,6 +76,7 @@ public class ItemSettings { newSettings.consumeReplacement = settings.consumeReplacement; newSettings.craftRemainder = settings.craftRemainder; newSettings.invulnerable = settings.invulnerable; + newSettings.canEnchant = settings.canEnchant; return newSettings; } @@ -118,6 +120,10 @@ public class ItemSettings { return dyeable; } + public boolean canEnchant() { + return canEnchant; + } + public List repairItems() { return anvilRepairItems; } @@ -171,6 +177,11 @@ public class ItemSettings { return this; } + public ItemSettings canEnchant(boolean canEnchant) { + this.canEnchant = canEnchant; + return this; + } + public ItemSettings renameable(boolean renameable) { this.renameable = renameable; return this; @@ -241,6 +252,10 @@ public class ItemSettings { boolean bool = (boolean) value; return settings -> settings.canRepair(bool); })); + registerFactory("enchantable", (value -> { + boolean bool = (boolean) value; + return settings -> settings.canEnchant(bool); + })); registerFactory("renameable", (value -> { boolean bool = (boolean) value; return settings -> settings.renameable(bool); diff --git a/gradle.properties b/gradle.properties index ef3e8ef9d..5dec2ecae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.57.1 +project_version=0.0.57.2 config_version=37 lang_version=16 project_group=net.momirealms From 52f9a7c9e72f84a4082a3b9041ef2978d5417dd2 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sat, 14 Jun 2025 04:34:24 +0800 Subject: [PATCH 11/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E9=99=84=E9=AD=94=E5=8F=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/listener/ItemEventListener.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java index be955e898..b827d63e2 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java @@ -35,6 +35,8 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.enchantment.EnchantItemEvent; +import org.bukkit.event.enchantment.PrepareItemEnchantEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; @@ -414,4 +416,16 @@ public class ItemEventListener implements Listener { }); } } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) + public void onEnchant(PrepareItemEnchantEvent event) { + ItemStack itemToEnchant = event.getItem(); + Item wrapped = this.plugin.itemManager().wrap(itemToEnchant); + Optional> optionalCustomItem = wrapped.getCustomItem(); + if (optionalCustomItem.isEmpty()) return; + CustomItem customItem = optionalCustomItem.get(); + if (!customItem.settings().canEnchant()) { + event.setCancelled(true); + } + } } From 9199a1cd2c3801f89c9a0b81c796b385dc447588 Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sat, 14 Jun 2025 04:44:01 +0800 Subject: [PATCH 12/13] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=A0=86=E8=82=A5?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/listener/ItemEventListener.java | 10 ++++++++++ .../craftengine/core/item/ItemSettings.java | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java index b827d63e2..4a86e42cc 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.bukkit.item.listener; +import io.papermc.paper.event.block.CompostItemEvent; import net.momirealms.craftengine.bukkit.api.event.CustomBlockInteractEvent; import net.momirealms.craftengine.bukkit.block.BukkitBlockManager; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; @@ -428,4 +429,13 @@ public class ItemEventListener implements Listener { event.setCancelled(true); } } + + @EventHandler(ignoreCancelled = true) + public void onCompost(CompostItemEvent event) { + ItemStack itemToCompost = event.getItem(); + Item wrapped = this.plugin.itemManager().wrap(itemToCompost); + Optional> optionalCustomItem = wrapped.getCustomItem(); + if (optionalCustomItem.isEmpty()) return; + event.setWillRaiseLevel(RandomUtils.generateRandomFloat(0, 1) < optionalCustomItem.get().settings().compostProbability()); + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java index ea6e079d4..b908dbcd1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemSettings.java @@ -37,6 +37,7 @@ public class ItemSettings { Key craftRemainder = null; List invulnerable = List.of(); boolean canEnchant = true; + float compostProbability= 0.5f; private ItemSettings() {} @@ -77,6 +78,7 @@ public class ItemSettings { newSettings.craftRemainder = settings.craftRemainder; newSettings.invulnerable = settings.invulnerable; newSettings.canEnchant = settings.canEnchant; + newSettings.compostProbability = settings.compostProbability; return newSettings; } @@ -157,6 +159,10 @@ public class ItemSettings { return invulnerable; } + public float compostProbability() { + return compostProbability; + } + public ItemSettings repairItems(List items) { this.anvilRepairItems = items; return this; @@ -172,6 +178,11 @@ public class ItemSettings { return this; } + public ItemSettings compostProbability(float chance) { + this.compostProbability = chance; + return this; + } + public ItemSettings canRepair(boolean canRepair) { this.canRepair = canRepair; return this; @@ -323,6 +334,10 @@ public class ItemSettings { Map args = MiscUtils.castToMap(value, false); return settings -> settings.helmet(new Helmet(SoundData.create(args.getOrDefault("equip-sound", "minecraft:intentionally_empty"), 1f, 1f))); })); + registerFactory("compost-probability", (value -> { + float chance = ResourceConfigUtils.getAsFloat(value, "compost-probability"); + return settings -> settings.compostProbability(chance); + })); registerFactory("dyeable", (value -> { boolean bool = (boolean) value; return settings -> settings.dyeable(bool); From fe56ce873d2ac5f6a22f0bbe63ce1a45175070ab Mon Sep 17 00:00:00 2001 From: XiaoMoMi Date: Sat, 14 Jun 2025 05:56:26 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=B1HashedStack?= =?UTF-8?q?=E5=BC=95=E8=B5=B7=E7=9A=84=E6=89=8B=E6=84=9F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/item/listener/ItemEventListener.java | 13 +++++++++++++ .../bukkit/plugin/gui/BukkitGuiManager.java | 3 ++- .../bukkit/plugin/network/PacketConsumers.java | 17 +++++++++++++++++ gradle.properties | 4 ++-- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java index 4a86e42cc..3ab37010b 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/listener/ItemEventListener.java @@ -27,6 +27,7 @@ import net.momirealms.craftengine.core.world.BlockPos; import net.momirealms.craftengine.core.world.Vec3d; import org.bukkit.GameMode; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.entity.EntityType; @@ -40,11 +41,14 @@ import org.bukkit.event.enchantment.EnchantItemEvent; import org.bukkit.event.enchantment.PrepareItemEnchantEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemConsumeEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; import java.util.List; import java.util.Objects; @@ -438,4 +442,13 @@ public class ItemEventListener implements Listener { if (optionalCustomItem.isEmpty()) return; event.setWillRaiseLevel(RandomUtils.generateRandomFloat(0, 1) < optionalCustomItem.get().settings().compostProbability()); } + + @EventHandler(ignoreCancelled = true) + public void onDragItem(InventoryClickEvent event) { +// Player player = (Player) event.getWhoClicked(); +// plugin.scheduler().sync().runLater(() -> { +// System.out.println(1); +// player.updateInventory(); +// }, 1); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java index c26361beb..75e295ae6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/gui/BukkitGuiManager.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.bukkit.plugin.gui; import net.kyori.adventure.text.Component; +import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections; import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections; @@ -69,7 +70,7 @@ public class BukkitGuiManager implements GuiManager, Listener { public void updateInventoryTitle(net.momirealms.craftengine.core.entity.player.Player player, Component component) { Object nmsPlayer = player.serverPlayer(); try { - Object containerMenu = CoreReflections.field$Player$containerMenu.get(nmsPlayer); + Object containerMenu = FastNMS.INSTANCE.field$Player$containerMenu(nmsPlayer); int containerId = CoreReflections.field$AbstractContainerMenu$containerId.getInt(containerMenu); Object menuType = CoreReflections.field$AbstractContainerMenu$menuType.get(containerMenu); Object packet = NetworkReflections.constructor$ClientboundOpenScreenPacket.newInstance(containerId, menuType, ComponentUtils.adventureToMinecraft(component)); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index d58934ded..4ec65e03f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -2108,6 +2108,23 @@ public class PacketConsumers { FriendlyByteBuf buf = event.getBuffer(); Object friendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); ItemStack itemStack = FastNMS.INSTANCE.method$FriendlyByteBuf$readItem(friendlyBuf); + if (VersionHelper.isOrAbove1_21_5()) { + Item wrapped = BukkitItemManager.instance().wrap(itemStack); + if (wrapped != null && wrapped.isCustomItem()) { + Object containerMenu = FastNMS.INSTANCE.field$Player$containerMenu(serverPlayer.serverPlayer()); + if (containerMenu != null) { + ItemStack carried = FastNMS.INSTANCE.method$CraftItemStack$asCraftMirror(FastNMS.INSTANCE.method$AbstractContainerMenu$getCarried(containerMenu)); + if (ItemUtils.isEmpty(carried)) { + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + Object newFriendlyBuf = FastNMS.INSTANCE.constructor$FriendlyByteBuf(buf); + FastNMS.INSTANCE.method$FriendlyByteBuf$writeItem(newFriendlyBuf, carried); + return; + } + } + } + } BukkitItemManager.instance().s2c(itemStack, serverPlayer).ifPresent((newItemStack) -> { event.setChanged(true); buf.clear(); diff --git a/gradle.properties b/gradle.properties index 5dec2ecae..a17dc894c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.57.2 +project_version=0.0.57.3 config_version=37 lang_version=16 project_group=net.momirealms @@ -51,7 +51,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.4 anti_grief_version=0.17 -nms_helper_version=0.67.11 +nms_helper_version=0.67.12 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.31.23