diff --git a/libraries/packets/implementations/1_21_6/src/main/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundShowDialogPacketImpl.java b/libraries/packets/implementations/1_21_6/src/main/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundShowDialogPacketImpl.java index 0d78c796..57f57c48 100644 --- a/libraries/packets/implementations/1_21_6/src/main/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundShowDialogPacketImpl.java +++ b/libraries/packets/implementations/1_21_6/src/main/java/de/oliver/fancysitula/versions/v1_21_6/packets/ClientboundShowDialogPacketImpl.java @@ -245,7 +245,7 @@ public class ClientboundShowDialogPacketImpl extends FS_ClientboundShowDialogPac Optional additions; if (customAction.getAdditions() != null) { CompoundTag tag = new CompoundTag(); - tag.putString("additions", customAction.getAdditions()); + tag.putString("data", customAction.getAdditions()); additions = Optional.of(tag); } else { additions = Optional.empty(); diff --git a/libraries/packets/implementations/1_21_6/src/main/java/de/oliver/fancysitula/versions/v1_21_6/utils/PacketListenerImpl.java b/libraries/packets/implementations/1_21_6/src/main/java/de/oliver/fancysitula/versions/v1_21_6/utils/PacketListenerImpl.java new file mode 100644 index 00000000..b40b4b3b --- /dev/null +++ b/libraries/packets/implementations/1_21_6/src/main/java/de/oliver/fancysitula/versions/v1_21_6/utils/PacketListenerImpl.java @@ -0,0 +1,90 @@ +package de.oliver.fancysitula.versions.v1_21_6.utils; + +import de.oliver.fancysitula.api.packets.FS_ServerboundCustomClickActionPacket; +import de.oliver.fancysitula.api.packets.FS_ServerboundPacket; +import de.oliver.fancysitula.api.utils.FS_PacketListener; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; +import io.papermc.paper.adventure.PaperAdventure; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.common.ServerboundCustomClickActionPacket; +import net.minecraft.server.level.ServerPlayer; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.entity.Player; + +import java.util.List; +import java.util.Optional; + +public class PacketListenerImpl extends FS_PacketListener { + + private static final String PIPELINE_NAME = "fancysitula-packet-injector"; + + public PacketListenerImpl(FS_ServerboundPacket.Type packet) { + super(packet); + } + + @Override + public void inject(Player player) { + ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); + + Channel channel = serverPlayer.connection.connection.channel; + + if (channel.pipeline().get(PIPELINE_NAME) != null) { + return; + } + + channel.pipeline().addAfter("decoder", PIPELINE_NAME, new MessageToMessageDecoder>() { + @Override + protected void decode(ChannelHandlerContext ctx, Packet msg, List out) { + out.add(msg); + + FS_ServerboundPacket.Type packetType = getPacketType(msg); + if (packetType == null) { + return; // Unsupported packet type + } + + if (packet == FS_ServerboundPacket.Type.ALL) { + FS_ServerboundPacket fsPacket = convert(packetType, msg); + PacketReceivedEvent packetReceivedEvent = new PacketReceivedEvent(fsPacket, player); + listeners.forEach(listener -> listener.accept(packetReceivedEvent)); + return; + } + + if (packet == packetType) { + FS_ServerboundPacket fsPacket = convert(packetType, msg); + PacketReceivedEvent packetReceivedEvent = new PacketReceivedEvent(fsPacket, player); + listeners.forEach(listener -> listener.accept(packetReceivedEvent)); + } + } + }); + } + + private FS_ServerboundPacket.Type getPacketType(Packet packet) { + String className = packet.getClass().getSimpleName(); + for (FS_ServerboundPacket.Type type : FS_ServerboundPacket.Type.values()) { + if (type.getPacketClassName().equalsIgnoreCase(className)) { + return type; + } + } + + return null; + } + + private FS_ServerboundPacket convert(FS_ServerboundPacket.Type type, Packet packet) { + switch (type) { + case CUSTOM_CLICK_ACTION -> { + ServerboundCustomClickActionPacket customClickActionPacket = (ServerboundCustomClickActionPacket) packet; + return new FS_ServerboundCustomClickActionPacket( + type, + PaperAdventure.asAdventure(customClickActionPacket.id()), + customClickActionPacket.payload().isPresent() ? + customClickActionPacket.payload().get().asCompound().get().getString("data") : + Optional.empty() + ); + } + // Add more cases for other packet types as needed + default -> throw new IllegalArgumentException("Unsupported packet type: " + type); + } + } +} diff --git a/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/packets/FS_ServerboundCustomClickActionPacket.java b/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/packets/FS_ServerboundCustomClickActionPacket.java new file mode 100644 index 00000000..6b4c198d --- /dev/null +++ b/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/packets/FS_ServerboundCustomClickActionPacket.java @@ -0,0 +1,30 @@ +package de.oliver.fancysitula.api.packets; + +import net.kyori.adventure.key.Key; + +import java.util.Optional; + +public class FS_ServerboundCustomClickActionPacket extends FS_ServerboundPacket { + + private final Key id; + private final Optional payload; + + public FS_ServerboundCustomClickActionPacket(Type type, Key id, Optional payload) { + super(type); + this.id = id; + this.payload = payload; + } + + public Key getId() { + return id; + } + + public Optional getPayload() { + return payload; + } + + @Override + public Type getType() { + return super.getType(); + } +} diff --git a/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/packets/FS_ServerboundPacket.java b/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/packets/FS_ServerboundPacket.java new file mode 100644 index 00000000..f001e076 --- /dev/null +++ b/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/packets/FS_ServerboundPacket.java @@ -0,0 +1,30 @@ +package de.oliver.fancysitula.api.packets; + +public abstract class FS_ServerboundPacket { + + protected final Type type; + + public FS_ServerboundPacket(Type type) { + this.type = type; + } + + public Type getType() { + return type; + } + + public enum Type { + ALL("*"), + CUSTOM_CLICK_ACTION("ServerboundCustomClickActionPacket"), + ; + + private String packetClassName; + + Type(String packetClassName) { + this.packetClassName = packetClassName; + } + + public String getPacketClassName() { + return packetClassName; + } + } +} diff --git a/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/utils/FS_PacketListener.java b/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/utils/FS_PacketListener.java new file mode 100644 index 00000000..fad976cf --- /dev/null +++ b/libraries/packets/packets-api/src/main/java/de/oliver/fancysitula/api/utils/FS_PacketListener.java @@ -0,0 +1,35 @@ +package de.oliver.fancysitula.api.utils; + +import de.oliver.fancysitula.api.packets.FS_ServerboundPacket; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +public abstract class FS_PacketListener { + + protected final FS_ServerboundPacket.Type packet; + protected final List> listeners; + + public FS_PacketListener(FS_ServerboundPacket.Type packet) { + this.packet = packet; + this.listeners = new ArrayList<>(); + } + + public abstract void inject(Player player); + + public void addListener(Consumer listener) { + listeners.add(listener); + } + + public FS_ServerboundPacket.Type getPacket() { + return packet; + } + + public record PacketReceivedEvent( + FS_ServerboundPacket packet, + Player player + ) { + } +} diff --git a/libraries/packets/src/main/java/de/oliver/fancysitula/factories/FancySitula.java b/libraries/packets/src/main/java/de/oliver/fancysitula/factories/FancySitula.java index e16f4bd3..d0d25785 100644 --- a/libraries/packets/src/main/java/de/oliver/fancysitula/factories/FancySitula.java +++ b/libraries/packets/src/main/java/de/oliver/fancysitula/factories/FancySitula.java @@ -3,6 +3,7 @@ package de.oliver.fancysitula.factories; public class FancySitula { public static final PacketFactory PACKET_FACTORY = new PacketFactory(); + public static final PacketListenerFactory PACKET_LISTENER_FACTORY = new PacketListenerFactory(); public static final EntityFactory ENTITY_FACTORY = new EntityFactory(); public static final TeamFactory TEAM_FACTORY = new TeamFactory(); } diff --git a/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketListenerFactory.java b/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketListenerFactory.java new file mode 100644 index 00000000..1fff167f --- /dev/null +++ b/libraries/packets/src/main/java/de/oliver/fancysitula/factories/PacketListenerFactory.java @@ -0,0 +1,19 @@ +package de.oliver.fancysitula.factories; + +import de.oliver.fancysitula.api.packets.FS_ServerboundPacket; +import de.oliver.fancysitula.api.utils.FS_PacketListener; +import de.oliver.fancysitula.api.utils.ServerVersion; + +public class PacketListenerFactory { + + public FS_PacketListener createPacketListener(FS_ServerboundPacket.Type packet) { + switch (ServerVersion.getCurrentVersion()) { + case v1_21_6 -> { + return new de.oliver.fancysitula.versions.v1_21_6.utils.PacketListenerImpl(packet); + } + default -> + throw new IllegalArgumentException("Unsupported server version: " + ServerVersion.getCurrentVersion()); + } + } + +} diff --git a/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/FancySitulaPlugin.java b/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/FancySitulaPlugin.java index 413d61e8..e93489cb 100644 --- a/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/FancySitulaPlugin.java +++ b/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/FancySitulaPlugin.java @@ -2,15 +2,46 @@ package de.oliver.fancysitula; import de.oliver.fancyanalytics.logger.LogLevel; import de.oliver.fancysitula.api.IFancySitula; +import de.oliver.fancysitula.api.packets.FS_ServerboundCustomClickActionPacket; +import de.oliver.fancysitula.api.packets.FS_ServerboundPacket; +import de.oliver.fancysitula.api.utils.FS_PacketListener; import de.oliver.fancysitula.commands.FancySitulaCMD; +import de.oliver.fancysitula.factories.FancySitula; +import de.oliver.fancysitula.listener.PlayerJoinListener; import org.bukkit.plugin.java.JavaPlugin; public class FancySitulaPlugin extends JavaPlugin { + private static FancySitulaPlugin instance; + private FS_PacketListener packetListener; + + public FancySitulaPlugin() { + instance = this; + } + + public static FancySitulaPlugin getInstance() { + return instance; + } + + @Override + public void onLoad() { + packetListener = FancySitula.PACKET_LISTENER_FACTORY.createPacketListener(FS_ServerboundPacket.Type.CUSTOM_CLICK_ACTION); + packetListener.addListener((event) -> { + FS_ServerboundCustomClickActionPacket packet = (FS_ServerboundCustomClickActionPacket) event.packet(); + System.out.println("Received custom click action packet: " + packet.getId() + " with payload: " + packet.getPayload().orElse("No payload")); + }); + } + @Override public void onEnable() { IFancySitula.LOGGER.setCurrentLevel(LogLevel.DEBUG); getServer().getCommandMap().register("fancysitula", new FancySitulaCMD()); + + getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this); + } + + public FS_PacketListener getPacketListener() { + return packetListener; } } diff --git a/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/commands/FancySitulaCMD.java b/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/commands/FancySitulaCMD.java index af4170a6..7bbde0f2 100644 --- a/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/commands/FancySitulaCMD.java +++ b/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/commands/FancySitulaCMD.java @@ -4,6 +4,7 @@ import de.oliver.fancysitula.api.dialogs.FS_CommonDialogData; import de.oliver.fancysitula.api.dialogs.FS_DialogAction; import de.oliver.fancysitula.api.dialogs.actions.FS_CommonButtonData; import de.oliver.fancysitula.api.dialogs.actions.FS_DialogActionButton; +import de.oliver.fancysitula.api.dialogs.actions.FS_DialogCustomAction; import de.oliver.fancysitula.api.dialogs.body.FS_DialogTextBody; import de.oliver.fancysitula.api.dialogs.inputs.FS_DialogBooleanInput; import de.oliver.fancysitula.api.dialogs.inputs.FS_DialogInput; @@ -102,7 +103,10 @@ public class FancySitulaCMD extends Command { "tooltip1", 40 ), - null + new FS_DialogCustomAction( + "my-custom-action-1", + "someAdditionalData1" + ) ) ); diff --git a/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/listener/PlayerJoinListener.java b/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/listener/PlayerJoinListener.java new file mode 100644 index 00000000..48f53e4c --- /dev/null +++ b/libraries/packets/test-plugin/src/main/java/de/oliver/fancysitula/listener/PlayerJoinListener.java @@ -0,0 +1,14 @@ +package de.oliver.fancysitula.listener; + +import de.oliver.fancysitula.FancySitulaPlugin; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class PlayerJoinListener implements Listener { + + @EventHandler + public void onPlayerJoin(org.bukkit.event.player.PlayerJoinEvent event) { + FancySitulaPlugin.getInstance().getPacketListener().inject(event.getPlayer()); + } + +}