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 54088f41d..4c6f37d7c 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 @@ -70,6 +70,11 @@ public class BukkitItemManager extends AbstractItemManager { Bukkit.getPluginManager().registerEvents(this.armorEventListener, this.plugin.bootstrap()); } + @Override + public NetworkItemHandler networkItemHandler() { + return this.networkItemHandler; + } + public static BukkitItemManager instance() { return instance; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java index 1e249d52e..1fa414681 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/factory/ComponentItemFactory1_21_5.java @@ -30,7 +30,7 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { if (json == null) { item.resetComponent(ComponentTypes.CUSTOM_NAME); } else { - item.setSparrowNBTComponent(ComponentTypes.CUSTOM_NAME, NBTComponentSerializer.nbt().serialize(AdventureHelper.jsonToComponent(json))); + item.setSparrowNBTComponent(ComponentTypes.CUSTOM_NAME, AdventureHelper.componentToNbt(AdventureHelper.jsonToComponent(json))); } } @@ -44,7 +44,7 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { if (component == null) { item.resetComponent(ComponentTypes.CUSTOM_NAME); } else { - item.setSparrowNBTComponent(ComponentTypes.CUSTOM_NAME, NBTComponentSerializer.nbt().serialize(component)); + item.setSparrowNBTComponent(ComponentTypes.CUSTOM_NAME, AdventureHelper.componentToNbt(component)); } } @@ -58,7 +58,7 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { if (json == null) { item.resetComponent(ComponentTypes.ITEM_NAME); } else { - item.setSparrowNBTComponent(ComponentTypes.ITEM_NAME, NBTComponentSerializer.nbt().serialize(AdventureHelper.jsonToComponent(json))); + item.setSparrowNBTComponent(ComponentTypes.ITEM_NAME, AdventureHelper.componentToNbt(AdventureHelper.jsonToComponent(json))); } } @@ -67,7 +67,7 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { if (component == null) { item.resetComponent(ComponentTypes.ITEM_NAME); } else { - item.setSparrowNBTComponent(ComponentTypes.ITEM_NAME, NBTComponentSerializer.nbt().serialize(component)); + item.setSparrowNBTComponent(ComponentTypes.ITEM_NAME, AdventureHelper.componentToNbt(component)); } } @@ -95,7 +95,7 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { } else { List loreTags = new ArrayList<>(); for (Component component : lore) { - loreTags.add(NBTComponentSerializer.nbt().serialize(component)); + loreTags.add(AdventureHelper.componentToTag(component)); } item.setSparrowNBTComponent(ComponentTypes.LORE, new ListTag(loreTags)); } @@ -108,7 +108,7 @@ public class ComponentItemFactory1_21_5 extends ComponentItemFactory1_21_4 { } else { List loreTags = new ArrayList<>(); for (String json : lore) { - loreTags.add(NBTComponentSerializer.nbt().serialize(AdventureHelper.jsonToComponent(json))); + loreTags.add(AdventureHelper.componentToTag(AdventureHelper.jsonToComponent(json))); } item.setSparrowNBTComponent(ComponentTypes.LORE, new ListTag(loreTags)); } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java index 232ac9476..5935a4330 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java @@ -3,6 +3,7 @@ package net.momirealms.craftengine.bukkit.plugin.network; import com.google.gson.JsonObject; import io.netty.buffer.ByteBuf; import io.netty.channel.*; +import io.netty.handler.codec.MessageToMessageCodec; import io.netty.handler.codec.MessageToMessageDecoder; import io.netty.handler.codec.MessageToMessageEncoder; import io.netty.util.internal.logging.InternalLogger; @@ -590,11 +591,16 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes int preProcessIndex = buf.readerIndex(); int packetId = buf.readVarInt(); int preIndex = buf.readerIndex(); - ByteBufPacketEvent event = new ByteBufPacketEvent(packetId, buf, preIndex); - BukkitNetworkManager.this.handleS2CByteBufPacket(this.player, event); - if (event.isCancelled()) { - buf.clear(); - } else if (!event.changed()) { + try { + ByteBufPacketEvent event = new ByteBufPacketEvent(packetId, buf, preIndex); + BukkitNetworkManager.this.handleS2CByteBufPacket(this.player, event); + if (event.isCancelled()) { + buf.clear(); + } else if (!event.changed()) { + buf.readerIndex(preProcessIndex); + } + } catch (Throwable e) { + CraftEngine.instance().logger().warn("An error occurred when writing packet " + packetId, e); buf.readerIndex(preProcessIndex); } } @@ -603,19 +609,46 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes public class PluginChannelDecoder extends MessageToMessageDecoder { private final NetWorkUser player; + private boolean handledCompression = false; public PluginChannelDecoder(NetWorkUser player) { this.player = player; } + public PluginChannelDecoder(PluginChannelDecoder decoder) { + this.player = decoder.player; + this.handledCompression = decoder.handledCompression; + } + @Override - protected void decode(ChannelHandlerContext context, ByteBuf byteBuf, List list) { + protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list) { + boolean needCompression = !handledCompression && handleCompression(channelHandlerContext, byteBuf); this.onByteBufReceive(byteBuf); + if (needCompression) { + compress(channelHandlerContext, byteBuf); + } if (byteBuf.isReadable()) { list.add(byteBuf.retain()); } } + private boolean handleCompression(ChannelHandlerContext ctx, ByteBuf buffer) { + if (handledCompression) return false; + int compressIndex = ctx.pipeline().names().indexOf("compress"); + if (compressIndex == -1) return false; + handledCompression = true; + int decoderIndex = ctx.pipeline().names().indexOf(PACKET_DECODER); + if (decoderIndex == -1) return false; + if (compressIndex > decoderIndex) { + decompress(ctx, buffer, buffer); + PluginChannelDecoder encoder = (PluginChannelDecoder) ctx.pipeline().remove(PACKET_DECODER); + String decoderName = ctx.pipeline().names().contains("inbound_config") ? "inbound_config" : "decoder"; + ctx.pipeline().addBefore(decoderName, PACKET_DECODER, new PluginChannelDecoder(encoder)); + return true; + } + return false; + } + private void onByteBufReceive(ByteBuf buffer) { // I don't care packets before PLAY for the moment if (player.decoderState() != ConnectionState.PLAY) return; @@ -625,11 +658,16 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes int preProcessIndex = buf.readerIndex(); int packetId = buf.readVarInt(); int preIndex = buf.readerIndex(); - ByteBufPacketEvent event = new ByteBufPacketEvent(packetId, buf, preIndex); - BukkitNetworkManager.this.handleC2SByteBufPacket(this.player, event); - if (event.isCancelled()) { - buf.clear(); - } else if (!event.changed()) { + try { + ByteBufPacketEvent event = new ByteBufPacketEvent(packetId, buf, preIndex); + BukkitNetworkManager.this.handleC2SByteBufPacket(this.player, event); + if (event.isCancelled()) { + buf.clear(); + } else if (!event.changed()) { + buf.readerIndex(preProcessIndex); + } + } catch (Throwable e) { + CraftEngine.instance().logger().warn("An error occurred when reading packet " + packetId, e); buf.readerIndex(preProcessIndex); } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index e5e844181..c103fe711 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -6936,9 +6936,8 @@ public class Reflections { ) ); - public static final Class clazz$JavaOps = requireNonNull( - ReflectionUtils.getClazz("com.mojang.serialization.JavaOps") - ); + // 1.20.5+ + public static final Class clazz$JavaOps = ReflectionUtils.getClazz("com.mojang.serialization.JavaOps"); public static final Class clazz$NbtOps = requireNonNull( BukkitReflectionUtils.findReobfOrMojmapClass( @@ -6962,8 +6961,13 @@ public class Reflections { try { Object nbtOps = ReflectionUtils.getDeclaredField(clazz$NbtOps, clazz$NbtOps, 0).get(null); instance$NBT_OPS = (DynamicOps) method$RegistryOps$create.invoke(null, nbtOps, instance$MinecraftRegistry); - Object javaOps = ReflectionUtils.getDeclaredField(clazz$JavaOps, clazz$JavaOps, 0).get(null); - instance$JAVA_OPS = (DynamicOps) method$RegistryOps$create.invoke(null, javaOps, instance$MinecraftRegistry); + if (clazz$JavaOps != null) { + Object javaOps = ReflectionUtils.getDeclaredField(clazz$JavaOps, clazz$JavaOps, 0).get(null); + instance$JAVA_OPS = (DynamicOps) method$RegistryOps$create.invoke(null, javaOps, instance$MinecraftRegistry); + } else { + // TODO Create a JavaOps + instance$JAVA_OPS = null; + } instance$JSON_OPS = (DynamicOps) method$RegistryOps$create.invoke(null, JsonOps.INSTANCE, instance$MinecraftRegistry); instance$SPARROW_NBT_OPS = (DynamicOps) method$RegistryOps$create.invoke(null, NBTOps.INSTANCE, instance$MinecraftRegistry); } catch (ReflectiveOperationException e) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java index 8a100cc33..0ab35daea 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java @@ -59,6 +59,8 @@ public interface ItemManager extends Manageable, ModelGenerator { Optional> getVanillaItem(Key key); + NetworkItemHandler networkItemHandler(); + default Optional> getBuildableItem(Key key) { Optional> item = getCustomItem(key); if (item.isPresent()) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java index 7e604313c..f26585b0c 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java +++ b/core/src/main/java/net/momirealms/craftengine/core/plugin/text/minimessage/GlobalVariableTag.java @@ -31,14 +31,18 @@ public class GlobalVariableTag implements TagResolver { if (value == null) { throw ctx.newException("Unknown variable: ", arguments); } - List args = new ArrayList<>(); - while (arguments.hasNext()) { - args.add(AdventureHelper.miniMessage().deserialize(arguments.popOr("No index argument variable id provided").toString(), this.context.tagResolvers())); + if (!arguments.hasNext()) { + return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(value, this.context.tagResolvers())); + } else { + List args = new ArrayList<>(); + while (arguments.hasNext()) { + args.add(AdventureHelper.miniMessage().deserialize(arguments.popOr("No index argument variable id provided").toString(), this.context.tagResolvers())); + } + return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(value, TagResolver.builder() + .resolvers(this.context.tagResolvers()) + .resolver(new IndexedArgumentTag(args)) + .build())); } - return Tag.selfClosingInserting(AdventureHelper.miniMessage().deserialize(value, TagResolver.builder() - .resolvers(this.context.tagResolvers()) - .resolver(new IndexedArgumentTag(args)) - .build())); } @Override diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java b/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java index 9760a00e4..a5d21f27d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/AdventureHelper.java @@ -11,6 +11,10 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.json.JSONOptions; import net.kyori.adventure.text.serializer.json.legacyimpl.NBTLegacyHoverEventSerializer; +import net.momirealms.craftengine.core.item.Item; +import net.momirealms.craftengine.core.item.ItemBuildContext; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.sparrow.nbt.CompoundTag; import net.momirealms.sparrow.nbt.Tag; import net.momirealms.sparrow.nbt.serializer.NBTComponentSerializer; import net.momirealms.sparrow.nbt.serializer.NBTSerializerOptions; @@ -48,6 +52,10 @@ public class AdventureHelper { } this.gsonComponentSerializer = builder.build(); this.nbtComponentSerializer = NBTComponentSerializer.builder() + .editItem(item -> { + if (VersionHelper.isOrAbove1_20_5()) { + } + }) .editOptions((b) -> { if (!VersionHelper.isOrAbove1_21_5()) { b.value(NBTSerializerOptions.EMIT_CLICK_EVENT_TYPE, false); diff --git a/gradle.properties b/gradle.properties index 601a89f27..7f2609357 100644 --- a/gradle.properties +++ b/gradle.properties @@ -39,7 +39,7 @@ geantyref_version=1.3.16 zstd_version=1.5.7-2 commons_io_version=2.18.0 commons_imaging_version=1.0.0-alpha6 -sparrow_nbt_version=0.8.2 +sparrow_nbt_version=0.8.3 sparrow_util_version=0.47 fastutil_version=8.5.15 netty_version=4.1.121.Final