From 3c04aeda6eb90dda2b91fbcbc4c8f2ea0546f5d1 Mon Sep 17 00:00:00 2001 From: GliczDev <67753196+GliczDev@users.noreply.github.com> Date: Sat, 28 Sep 2024 14:28:45 +0200 Subject: [PATCH] Add ItemStack decode and encode events --- .../event/packet/ItemStackDecodeEvent.java | 23 +++++ .../event/packet/ItemStackEncodeEvent.java | 23 +++++ .../patches/0012-Packet-Events.patch | 90 +++++++++++++++++++ .../airflow/event/bus/AirServerEventBus.java | 11 +++ .../java/me/glicz/testplugin/TestPlugin.java | 3 + .../listener/EmeraldEncodeListener.java | 25 ++++++ 6 files changed, 175 insertions(+) create mode 100644 Airflow-API/src/main/java/me/glicz/airflow/api/event/packet/ItemStackDecodeEvent.java create mode 100644 Airflow-API/src/main/java/me/glicz/airflow/api/event/packet/ItemStackEncodeEvent.java create mode 100644 Airflow-Server/patches/0012-Packet-Events.patch create mode 100644 test-plugin/src/main/java/me/glicz/testplugin/listener/EmeraldEncodeListener.java diff --git a/Airflow-API/src/main/java/me/glicz/airflow/api/event/packet/ItemStackDecodeEvent.java b/Airflow-API/src/main/java/me/glicz/airflow/api/event/packet/ItemStackDecodeEvent.java new file mode 100644 index 0000000..93a8e9d --- /dev/null +++ b/Airflow-API/src/main/java/me/glicz/airflow/api/event/packet/ItemStackDecodeEvent.java @@ -0,0 +1,23 @@ +package me.glicz.airflow.api.event.packet; + +import me.glicz.airflow.api.event.Event; +import me.glicz.airflow.api.item.stack.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +public class ItemStackDecodeEvent extends Event { + private ItemStack itemStack; + + @ApiStatus.Internal + public ItemStackDecodeEvent(ItemStack itemStack) { + this.itemStack = itemStack; + } + + public @NotNull ItemStack getItemStack() { + return itemStack; + } + + public void setItemStack(@NotNull ItemStack itemStack) { + this.itemStack = itemStack; + } +} \ No newline at end of file diff --git a/Airflow-API/src/main/java/me/glicz/airflow/api/event/packet/ItemStackEncodeEvent.java b/Airflow-API/src/main/java/me/glicz/airflow/api/event/packet/ItemStackEncodeEvent.java new file mode 100644 index 0000000..f083cf3 --- /dev/null +++ b/Airflow-API/src/main/java/me/glicz/airflow/api/event/packet/ItemStackEncodeEvent.java @@ -0,0 +1,23 @@ +package me.glicz.airflow.api.event.packet; + +import me.glicz.airflow.api.event.Event; +import me.glicz.airflow.api.item.stack.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +public class ItemStackEncodeEvent extends Event { + private ItemStack itemStack; + + @ApiStatus.Internal + public ItemStackEncodeEvent(ItemStack itemStack) { + this.itemStack = itemStack; + } + + public @NotNull ItemStack getItemStack() { + return itemStack; + } + + public void setItemStack(@NotNull ItemStack itemStack) { + this.itemStack = itemStack; + } +} diff --git a/Airflow-Server/patches/0012-Packet-Events.patch b/Airflow-Server/patches/0012-Packet-Events.patch new file mode 100644 index 0000000..df33fe3 --- /dev/null +++ b/Airflow-Server/patches/0012-Packet-Events.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: GliczDev <67753196+GliczDev@users.noreply.github.com> +Date: Sat, 28 Sep 2024 14:24:52 +0200 +Subject: [PATCH] Packet Events + + +diff --git a/net/minecraft/network/RegistryFriendlyByteBuf.java b/net/minecraft/network/RegistryFriendlyByteBuf.java +index e1651db791e55a6621157116359aa9aca6919475..432aad956ae1b3d91da077652d6e096eaf34b832 100644 +--- a/net/minecraft/network/RegistryFriendlyByteBuf.java ++++ b/net/minecraft/network/RegistryFriendlyByteBuf.java +@@ -6,17 +6,21 @@ import net.minecraft.core.RegistryAccess; + + public class RegistryFriendlyByteBuf extends FriendlyByteBuf { + private final RegistryAccess registryAccess; ++ public final net.minecraft.server.dedicated.DedicatedServer server; // Airflow - Packet Events + +- public RegistryFriendlyByteBuf(ByteBuf source, RegistryAccess registryAccess) { ++ public RegistryFriendlyByteBuf(ByteBuf source, RegistryAccess registryAccess, net.minecraft.server.dedicated.DedicatedServer server) { // Airflow - Packet Events + super(source); + this.registryAccess = registryAccess; ++ this.server = server; // Airflow - Packet Events + } + + public RegistryAccess registryAccess() { + return this.registryAccess; + } + +- public static Function decorator(RegistryAccess registry) { +- return byteBuf -> new RegistryFriendlyByteBuf(byteBuf, registry); ++ // Airflow start - Packet Events ++ public static Function decorator(RegistryAccess registry, net.minecraft.server.dedicated.DedicatedServer server) { ++ return byteBuf -> new RegistryFriendlyByteBuf(byteBuf, registry, server); ++ // Airflow end - Packet Events + } + } +diff --git a/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java b/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java +index 8e39d689fc5eb405d76dee0a071b45960f74a25b..6b1b289ac3f46b2e726dc72b6d30e168cdb750c7 100644 +--- a/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java ++++ b/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java +@@ -130,7 +130,7 @@ public class ServerConfigurationPacketListenerImpl extends ServerCommonPacketLis + public void handleConfigurationFinished(ServerboundFinishConfigurationPacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.server); + this.finishCurrentTask(JoinWorldTask.TYPE); +- this.connection.setupOutboundProtocol(GameProtocols.CLIENTBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess()))); ++ this.connection.setupOutboundProtocol(GameProtocols.CLIENTBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess(), this.server.getDedicatedServer()))); // Airflow - Packet Events + + try { + PlayerList playerList = this.server.getPlayerList(); +diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java +index 2f271f97353d2bbc16004a865d657e08b73fbf8c..bbb215826685ab3608879119a4772a7bb1c3cf06 100644 +--- a/net/minecraft/server/players/PlayerList.java ++++ b/net/minecraft/server/players/PlayerList.java +@@ -177,7 +177,7 @@ public abstract class PlayerList { + player.loadGameTypes(optional.orElse(null)); + ServerGamePacketListenerImpl serverGamePacketListenerImpl = new ServerGamePacketListenerImpl(this.server, connection, player, cookie); + connection.setupInboundProtocol( +- GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess())), serverGamePacketListenerImpl ++ GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess(), this.server.getDedicatedServer())), serverGamePacketListenerImpl // Airflow - Packet Events + ); + GameRules gameRules = serverLevel.getGameRules(); + boolean _boolean = gameRules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN); +diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java +index 014099568e69e8af1466645ac0fedd74de9778c9..5a10f68cec304947216aeadc1b53c41e71475c62 100644 +--- a/net/minecraft/world/item/ItemStack.java ++++ b/net/minecraft/world/item/ItemStack.java +@@ -129,12 +129,23 @@ public final class ItemStack implements DataComponentHolder { + } else { + Holder holder = ITEM_STREAM_CODEC.decode(buffer); + DataComponentPatch dataComponentPatch = DataComponentPatch.STREAM_CODEC.decode(buffer); +- return new ItemStack(holder, varInt, dataComponentPatch); ++ // Airflow start - Packet Events ++ me.glicz.airflow.api.event.packet.ItemStackDecodeEvent event = buffer.server.airflow.serverEventBus.dispatchItemStackDecode( ++ new ItemStack(holder, varInt, dataComponentPatch) ++ ); ++ return ((me.glicz.airflow.item.stack.AirItemStack) event.getItemStack()).handle; ++ // Airflow end - Packet Events + } + } + + @Override + public void encode(RegistryFriendlyByteBuf buffer, ItemStack value) { ++ // Airflow start - Packet Events ++ if (!value.isEmpty()) { ++ me.glicz.airflow.api.event.packet.ItemStackEncodeEvent event = buffer.server.airflow.serverEventBus.dispatchItemStackEncode(value); ++ value = ((me.glicz.airflow.item.stack.AirItemStack) event.getItemStack()).handle; ++ } ++ // Airflow end - Packet Events + if (value.isEmpty()) { + buffer.writeVarInt(0); + } else { diff --git a/Airflow-Server/src/main/java/me/glicz/airflow/event/bus/AirServerEventBus.java b/Airflow-Server/src/main/java/me/glicz/airflow/event/bus/AirServerEventBus.java index 4231c3c..dccfd66 100644 --- a/Airflow-Server/src/main/java/me/glicz/airflow/event/bus/AirServerEventBus.java +++ b/Airflow-Server/src/main/java/me/glicz/airflow/event/bus/AirServerEventBus.java @@ -6,11 +6,14 @@ import me.glicz.airflow.api.event.EventPriority; import me.glicz.airflow.api.event.bus.ServerEventBus; import me.glicz.airflow.api.event.command.CommandsRegisterEvent; +import me.glicz.airflow.api.event.packet.ItemStackDecodeEvent; +import me.glicz.airflow.api.event.packet.ItemStackEncodeEvent; import me.glicz.airflow.api.event.player.PlayerJoinEvent; import me.glicz.airflow.api.event.player.PlayerQuitEvent; import me.glicz.airflow.util.MinecraftComponentSerializer; import net.minecraft.network.chat.MutableComponent; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -42,6 +45,14 @@ public void dispatchCommandsRegister(Commands commands) { dispatch(new CommandsRegisterEvent(commands)); } + public ItemStackDecodeEvent dispatchItemStackDecode(ItemStack itemStack) { + return dispatch(new ItemStackDecodeEvent(itemStack.airItemStack)); + } + + public ItemStackEncodeEvent dispatchItemStackEncode(ItemStack itemStack) { + return dispatch(new ItemStackEncodeEvent(itemStack.copy().airItemStack)); + } + public PlayerJoinEvent dispatchPlayerJoin(ServerPlayer player, MutableComponent message) { return dispatch(new PlayerJoinEvent(player.getAirEntity(), MinecraftComponentSerializer.INSTANCE.deserialize(message))); } diff --git a/test-plugin/src/main/java/me/glicz/testplugin/TestPlugin.java b/test-plugin/src/main/java/me/glicz/testplugin/TestPlugin.java index a81f754..fbfe228 100644 --- a/test-plugin/src/main/java/me/glicz/testplugin/TestPlugin.java +++ b/test-plugin/src/main/java/me/glicz/testplugin/TestPlugin.java @@ -5,6 +5,7 @@ import me.glicz.airflow.api.block.BlockTypes; import me.glicz.airflow.api.command.Commands; import me.glicz.airflow.api.event.command.CommandsRegisterEvent; +import me.glicz.airflow.api.event.packet.ItemStackEncodeEvent; import me.glicz.airflow.api.event.player.PlayerJoinEvent; import me.glicz.airflow.api.event.player.PlayerQuitEvent; import me.glicz.airflow.api.permission.DummyPermissionsSource; @@ -15,6 +16,7 @@ import me.glicz.airflow.api.service.ServicePriority; import me.glicz.airflow.api.service.ServiceProvider; import me.glicz.testplugin.event.TestEvent; +import me.glicz.testplugin.listener.EmeraldEncodeListener; import me.glicz.testplugin.listener.JoinListener; import me.glicz.testplugin.listener.QuitListener; import me.glicz.testplugin.listener.TestListener; @@ -98,6 +100,7 @@ public void onLoad() { @Override public void onEnable() { + getEventBus().subscribe(ItemStackEncodeEvent.class, new EmeraldEncodeListener()); getEventBus().subscribe(PlayerJoinEvent.class, new JoinListener(this)); getEventBus().subscribe(PlayerQuitEvent.class, new QuitListener()); diff --git a/test-plugin/src/main/java/me/glicz/testplugin/listener/EmeraldEncodeListener.java b/test-plugin/src/main/java/me/glicz/testplugin/listener/EmeraldEncodeListener.java new file mode 100644 index 0000000..810aa45 --- /dev/null +++ b/test-plugin/src/main/java/me/glicz/testplugin/listener/EmeraldEncodeListener.java @@ -0,0 +1,25 @@ +package me.glicz.testplugin.listener; + +import me.glicz.airflow.api.event.bus.EventHandler; +import me.glicz.airflow.api.event.packet.ItemStackEncodeEvent; +import me.glicz.airflow.api.item.ItemTypes; +import me.glicz.airflow.api.item.component.ItemComponentTypes; +import me.glicz.airflow.api.item.lore.ItemLore; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import org.jetbrains.annotations.NotNull; + +public class EmeraldEncodeListener implements EventHandler { + @Override + public void handle(@NotNull ItemStackEncodeEvent e) { + if (e.getItemStack().getType() != ItemTypes.EMERALD) return; + + e.getItemStack().getItemComponentMap().set(ItemComponentTypes.LORE, ItemLore.itemLore( + Component.text("This is ItemStackEncodeEvent showcase!", NamedTextColor.AQUA) + .decoration(TextDecoration.ITALIC, false), + Component.text("All Emeralds come with this lore, however it's only visible client-side!", NamedTextColor.GREEN) + .decoration(TextDecoration.ITALIC, false) + )); + } +}