From f0899910d25de90ee03047ebc591286fab9a8b2d Mon Sep 17 00:00:00 2001 From: LoJoSho Date: Mon, 14 Jul 2025 10:41:35 -0500 Subject: [PATCH] feat: backport packet listener to 1.20.6 --- .../nms/v1_20_R4/NMSPacketChannel.java | 278 ++++++++++++++++++ .../nms/v1_20_R4/NMSPackets.java | 36 ++- .../nms/v1_20_R4/NMSUtils.java | 22 +- .../nms/v1_21_R1/NMSPacketChannel.java | 278 ++++++++++++++++++ .../nms/v1_21_R1/NMSPackets.java | 39 ++- .../nms/v1_21_R1/NMSUtils.java | 23 +- .../nms/v1_21_R2/NMSPacketChannel.java | 278 ++++++++++++++++++ .../nms/v1_21_R2/NMSPackets.java | 26 +- .../nms/v1_21_R2/NMSUtils.java | 23 +- .../nms/v1_21_R3/NMSPacketChannel.java | 278 ++++++++++++++++++ .../nms/v1_21_R3/NMSPackets.java | 33 ++- .../nms/v1_21_R3/NMSUtils.java | 22 +- 12 files changed, 1279 insertions(+), 57 deletions(-) create mode 100644 v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSPacketChannel.java create mode 100644 v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSPacketChannel.java create mode 100644 v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSPacketChannel.java create mode 100644 v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSPacketChannel.java diff --git a/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSPacketChannel.java b/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSPacketChannel.java new file mode 100644 index 0000000..d7212cd --- /dev/null +++ b/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSPacketChannel.java @@ -0,0 +1,278 @@ +package me.lojosho.hibiscuscommons.nms.v1_20_R4; + +import com.mojang.datafixers.util.Pair; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPromise; +import lombok.Getter; +import me.lojosho.hibiscuscommons.nms.NMSHandlers; +import me.lojosho.hibiscuscommons.packets.PacketAction; +import me.lojosho.hibiscuscommons.packets.wrapper.*; +import me.lojosho.hibiscuscommons.plugins.SubPlugins; +import me.lojosho.hibiscuscommons.util.MessagesUtil; +import net.minecraft.core.NonNullList; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.*; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.CraftEquipmentSlot; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +public class NMSPacketChannel extends ChannelDuplexHandler { + + @Getter + private final Player player; + + public NMSPacketChannel(Player player) { + this.player = player; + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + if (!(msg instanceof Packet packet)) { + super.write(ctx, msg, promise); + return; + } + + switch (packet) { + case ClientboundContainerSetContentPacket setContentPacket -> msg = handleMenuChange(setContentPacket); + case ClientboundContainerSetSlotPacket setSlotPacket -> msg = handleSlotChange(setSlotPacket); + case ClientboundSetEquipmentPacket equipmentPacket -> msg = handlePlayerEquipment(equipmentPacket); + case ClientboundSetPassengersPacket passengerPacket -> msg = handlePassengerSet(passengerPacket); + case ClientboundUpdateAttributesPacket attributesPacket -> msg = handleScaleChange(attributesPacket); + default -> {} + } + + if (msg == null) return; + else super.write(ctx, msg, promise); + } + + private Packet handleMenuChange(@NotNull ClientboundContainerSetContentPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundContainerSetContentPacket"); + MessagesUtil.sendDebugMessages("Menu Initial "); + + Integer windowId = packet.getContainerId(); + List slotData = packet.getItems(); + + List bukkitItems = new ArrayList<>(); + for (ItemStack nmsItem : slotData) { + if (nmsItem == null) { + slotData.add(null); + continue; + } + bukkitItems.add(CraftItemStack.asBukkitCopy(nmsItem)); + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + ContainerContentWrapper wrapper = new ContainerContentWrapper(windowId, bukkitItems); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().writeContainerContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + NonNullList nmsItems = NonNullList.create(); + for (org.bukkit.inventory.ItemStack bukkitItem : bukkitItems) { + if (bukkitItem == null) { + slotData.add(null); + continue; + } + nmsItems.add(CraftItemStack.asNMSCopy(bukkitItem)); + } + + return new ClientboundContainerSetContentPacket(wrapper.getWindowId(), packet.getStateId(), nmsItems, packet.getCarriedItem()); + } + + private Packet handleSlotChange(@NotNull ClientboundContainerSetSlotPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundContainerSetSlotPacket"); + + final int windowId = packet.getContainerId(); + final int slot = packet.getSlot(); + final ItemStack item = packet.getItem(); + + org.bukkit.inventory.ItemStack bukkitItem = CraftItemStack.asBukkitCopy(item); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SlotContentWrapper wrapper = new SlotContentWrapper(windowId, slot, bukkitItem); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writeSlotContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + final ItemStack nmsItem = CraftItemStack.asNMSCopy(wrapper.getItemStack()); + + return new ClientboundContainerSetSlotPacket(packet.getContainerId(), packet.getStateId(), wrapper.getSlot(), nmsItem); + } + + private Packet handlePlayerEquipment(@NotNull ClientboundSetEquipmentPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundSetEquipmentPacket"); + final List> nmsArmor = packet.getSlots(); + final int entity = packet.getEntity(); + HashMap bukkitArmor = new HashMap<>(); + for (Pair piece : nmsArmor) { + EquipmentSlot slot = CraftEquipmentSlot.getSlot(piece.getFirst()); + org.bukkit.inventory.ItemStack itemStack = CraftItemStack.asBukkitCopy(piece.getSecond()); + bukkitArmor.put(slot, itemStack); + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + EntityEquipmentWrapper wrapper = new EntityEquipmentWrapper(entity, bukkitArmor); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writeEquipmentContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + List> newArmor = new ArrayList<>(); + for (Map.Entry entry : wrapper.getArmor().entrySet()) { + net.minecraft.world.entity.EquipmentSlot slot = CraftEquipmentSlot.getNMS(entry.getKey()); + ItemStack itemStack = CraftItemStack.asNMSCopy(entry.getValue()); + newArmor.add(new Pair<>(slot, itemStack)); + } + + return new ClientboundSetEquipmentPacket(packet.getEntity(), newArmor); + } + + private Packet handlePassengerSet(@NotNull ClientboundSetPassengersPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundSetPassengersPacket"); + int ownerId = packet.getVehicle(); + List passengers = Arrays.stream(packet.getPassengers()).boxed().collect(Collectors.toList()); + MessagesUtil.sendDebugMessages("Mount Packet Sent - Read - EntityID: " + ownerId); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + PassengerWrapper wrapper = new PassengerWrapper(ownerId, passengers); + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writePassengerContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) { + action.set(pluginAction); + } + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + return (Packet) NMSHandlers.getHandler().getPacketHandler().createMountPacket(ownerId, passengers.stream().mapToInt(Integer::intValue).toArray()); + } + + private Packet handleScaleChange(@NotNull ClientboundUpdateAttributesPacket packet) { + final List nmsAttributes = packet.getValues(); + final ClientboundUpdateAttributesPacket.AttributeSnapshot nmsScaleAttribute = nmsAttributes.stream() + .filter(attribute -> attribute.attribute().equals(Attributes.SCALE)) + .findFirst() + .orElse(null); + + if (nmsScaleAttribute == null) { + return packet; + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + PlayerScaleWrapper wrapper = new PlayerScaleWrapper(packet.getEntityId(), nmsScaleAttribute.base()); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().readPlayerScale(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + return packet; + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (!(msg instanceof Packet packet)) { + super.channelRead(ctx, msg); + return; + } + + switch (packet) { + case ServerboundContainerClickPacket clickPacket -> msg = handleInventoryClick(clickPacket); + case ServerboundPlayerActionPacket playerActionPacket -> msg = handlePlayerAction(playerActionPacket); + case ServerboundSwingPacket swingPacket -> msg = handlePlayerArm(swingPacket); + case ServerboundInteractPacket interactPacket -> msg = handleInteract(interactPacket); + default -> {} + } + + if (msg == null) return; + else super.channelRead(ctx, msg); + } + + private Packet handleInventoryClick(@NotNull ServerboundContainerClickPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundContainerClickPacket"); + ClickType clickType = packet.getClickType(); + int slotClicked = packet.getSlotNum(); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readInventoryClick(player, new InventoryClickWrapper(clickType.ordinal(), slotClicked)); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handlePlayerAction(ServerboundPlayerActionPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundPlayerActionPacket"); + ServerboundPlayerActionPacket.Action playerAction = packet.getAction(); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readPlayerAction(player, new PlayerActionWrapper(playerAction.name())); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handlePlayerArm(@NotNull ServerboundSwingPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundSwingPacket"); + PlayerSwingWrapper wrapper = new PlayerSwingWrapper(packet.getHand().name()); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readPlayerArm(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handleInteract(@NotNull ServerboundInteractPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundInteractPacket"); + + PlayerInteractWrapper wrapper = new PlayerInteractWrapper(packet.getEntityId()); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readEntityHandle(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } +} \ No newline at end of file diff --git a/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSPackets.java b/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSPackets.java index 4761a6e..a0044fe 100644 --- a/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSPackets.java +++ b/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSPackets.java @@ -10,14 +10,15 @@ import io.papermc.paper.adventure.PaperAdventure; import it.unimi.dsi.fastutil.ints.IntList; import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin; import me.lojosho.hibiscuscommons.util.AdventureUtils; +import me.lojosho.hibiscuscommons.util.MessagesUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; +import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.network.chat.RemoteChatSession; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.EntityDataSerializer; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.resources.ResourceLocation; @@ -34,9 +35,7 @@ import net.minecraft.world.level.GameType; import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.PlayerTeam; import net.minecraft.world.scores.Team; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.Location; +import org.bukkit.*; import org.bukkit.craftbukkit.CraftEquipmentSlot; import org.bukkit.craftbukkit.entity.CraftEntityType; import org.bukkit.craftbukkit.entity.CraftPlayer; @@ -138,6 +137,14 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. sendPacket(player, packet); } + @Override + public void sendLookAtPacket(int entityId, Location location, List sendTo) { + fakeNmsEntity.setId(entityId); + fakeNmsEntity.getBukkitEntity().teleport(location); + ClientboundPlayerLookAtPacket packet = new ClientboundPlayerLookAtPacket(EntityAnchorArgument.Anchor.EYES, fakeNmsEntity, EntityAnchorArgument.Anchor.EYES); + for (Player p : sendTo) sendPacket(p, packet); + } + @Override public void sendRotateHeadPacket(int entityId, Location location, List sendTo) { fakeNmsEntity.setId(entityId); @@ -148,10 +155,11 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. } @Override - public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List sendTo) { + public void sendRotationPacket(int entityId, float originalYaw, float pitch, boolean onGround, List sendTo) { float ROTATION_FACTOR = 256.0F / 360.0F; - yaw = (byte) (yaw * ROTATION_FACTOR); + byte yaw = (byte) (originalYaw * ROTATION_FACTOR); pitch = (byte) (pitch * ROTATION_FACTOR); + MessagesUtil.sendDebugMessages("sendRotationPacket. Original: " + originalYaw + " modified: " + yaw); ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround); for (Player p : sendTo) sendPacket(p, packet); } @@ -251,10 +259,12 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. //Adding players to the team (You have to use the NPC's name, and add it to a list) ClientboundSetPlayerTeamPacket createPlayerTeamPacket = ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, new ArrayList() {{ add(name); + add(player.getName()); }}, ClientboundSetPlayerTeamPacket.Action.ADD); sendPacket(player, createPlayerTeamPacket); } + @Override public void sendMountPacket(int mountId, int[] passengerIds, List sendTo) { List passengers = Arrays.stream(passengerIds).mapToObj(id -> { @@ -262,6 +272,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. passenger.setId(id); return passenger; }).toList(); + fakeNmsEntity.setId(mountId); fakeNmsEntity.passengers = ImmutableList.copyOf(passengers); ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity); fakeNmsEntity.passengers = ImmutableList.of(); @@ -292,12 +303,15 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. boolean onGround, List sendTo ) { - fakeNmsEntity.setId(entityId); - fakeNmsEntity.setRot((yaw * 256.0F / 360.0F), (pitch * 256.0F / 360.0F)); - fakeNmsEntity.setOnGround(onGround); + try { + fakeNmsEntity.setId(entityId); + fakeNmsEntity.teleportTo(x, y, z); - ClientboundTeleportEntityPacket packet = new ClientboundTeleportEntityPacket(fakeNmsEntity); - for (Player p : sendTo) sendPacket(p, packet); + ClientboundTeleportEntityPacket packet = new ClientboundTeleportEntityPacket(fakeNmsEntity); + for (Player p : sendTo) sendPacket(p, packet); + } catch (Exception e) { + e.printStackTrace(); + } } @Override diff --git a/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSUtils.java b/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSUtils.java index 38d4981..41a5b6d 100644 --- a/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSUtils.java +++ b/v1_20_R4/src/main/java/me/lojosho/hibiscuscommons/nms/v1_20_R4/NMSUtils.java @@ -1,15 +1,18 @@ package me.lojosho.hibiscuscommons.nms.v1_20_R4; +import io.netty.channel.Channel; +import io.netty.channel.ChannelPipeline; import net.minecraft.core.component.DataComponents; +import net.minecraft.network.Connection; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.component.DyedItemColor; import org.bukkit.Bukkit; import org.bukkit.Color; -import org.bukkit.FireworkEffect; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,8 +44,7 @@ public class NMSUtils extends NMSCommon implements me.lojosho.hibiscuscommons.nm @Override public ItemStack setColor(@NotNull ItemStack itemStack, Color color) { net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - boolean tooltip = !nmsStack.has(DataComponents.DYED_COLOR) || nmsStack.get(DataComponents.DYED_COLOR).showInTooltip(); - nmsStack.set(DataComponents.DYED_COLOR, new DyedItemColor(color.asRGB(), tooltip)); + nmsStack.set(DataComponents.DYED_COLOR, new DyedItemColor(color.asRGB(), false)); return CraftItemStack.asBukkitCopy(nmsStack); } @@ -54,4 +56,16 @@ public class NMSUtils extends NMSCommon implements me.lojosho.hibiscuscommons.nm } return null; } + + @Override + public void handleChannelOpen(@NotNull Player player) { + Channel channel = ((CraftPlayer) player).getHandle().connection.connection.channel; + ChannelPipeline pipeline = channel.pipeline(); + + NMSPacketChannel channelHandler = new NMSPacketChannel(player); + for (String key : pipeline.toMap().keySet()) { + if (!(pipeline.get(key) instanceof Connection)) continue; + pipeline.addBefore(key, "hibiscus_channel_handler", channelHandler); + } + } } diff --git a/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSPacketChannel.java b/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSPacketChannel.java new file mode 100644 index 0000000..a9ef1d6 --- /dev/null +++ b/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSPacketChannel.java @@ -0,0 +1,278 @@ +package me.lojosho.hibiscuscommons.nms.v1_21_R1; + +import com.mojang.datafixers.util.Pair; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPromise; +import lombok.Getter; +import me.lojosho.hibiscuscommons.nms.NMSHandlers; +import me.lojosho.hibiscuscommons.packets.PacketAction; +import me.lojosho.hibiscuscommons.packets.wrapper.*; +import me.lojosho.hibiscuscommons.plugins.SubPlugins; +import me.lojosho.hibiscuscommons.util.MessagesUtil; +import net.minecraft.core.NonNullList; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.*; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.CraftEquipmentSlot; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +public class NMSPacketChannel extends ChannelDuplexHandler { + + @Getter + private final Player player; + + public NMSPacketChannel(Player player) { + this.player = player; + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + if (!(msg instanceof Packet packet)) { + super.write(ctx, msg, promise); + return; + } + + switch (packet) { + case ClientboundContainerSetContentPacket setContentPacket -> msg = handleMenuChange(setContentPacket); + case ClientboundContainerSetSlotPacket setSlotPacket -> msg = handleSlotChange(setSlotPacket); + case ClientboundSetEquipmentPacket equipmentPacket -> msg = handlePlayerEquipment(equipmentPacket); + case ClientboundSetPassengersPacket passengerPacket -> msg = handlePassengerSet(passengerPacket); + case ClientboundUpdateAttributesPacket attributesPacket -> msg = handleScaleChange(attributesPacket); + default -> {} + } + + if (msg == null) return; + else super.write(ctx, msg, promise); + } + + private Packet handleMenuChange(@NotNull ClientboundContainerSetContentPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundContainerSetContentPacket"); + MessagesUtil.sendDebugMessages("Menu Initial "); + + Integer windowId = packet.getContainerId(); + List slotData = packet.getItems(); + + List bukkitItems = new ArrayList<>(); + for (ItemStack nmsItem : slotData) { + if (nmsItem == null) { + slotData.add(null); + continue; + } + bukkitItems.add(CraftItemStack.asBukkitCopy(nmsItem)); + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + ContainerContentWrapper wrapper = new ContainerContentWrapper(windowId, bukkitItems); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().writeContainerContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + NonNullList nmsItems = NonNullList.create(); + for (org.bukkit.inventory.ItemStack bukkitItem : bukkitItems) { + if (bukkitItem == null) { + slotData.add(null); + continue; + } + nmsItems.add(CraftItemStack.asNMSCopy(bukkitItem)); + } + + return new ClientboundContainerSetContentPacket(wrapper.getWindowId(), packet.getStateId(), nmsItems, packet.getCarriedItem()); + } + + private Packet handleSlotChange(@NotNull ClientboundContainerSetSlotPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundContainerSetSlotPacket"); + + final int windowId = packet.getContainerId(); + final int slot = packet.getSlot(); + final ItemStack item = packet.getItem(); + + org.bukkit.inventory.ItemStack bukkitItem = CraftItemStack.asBukkitCopy(item); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SlotContentWrapper wrapper = new SlotContentWrapper(windowId, slot, bukkitItem); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writeSlotContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + final ItemStack nmsItem = CraftItemStack.asNMSCopy(wrapper.getItemStack()); + + return new ClientboundContainerSetSlotPacket(packet.getContainerId(), packet.getStateId(), wrapper.getSlot(), nmsItem); + } + + private Packet handlePlayerEquipment(@NotNull ClientboundSetEquipmentPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundSetEquipmentPacket"); + final List> nmsArmor = packet.getSlots(); + final int entity = packet.getEntity(); + HashMap bukkitArmor = new HashMap<>(); + for (Pair piece : nmsArmor) { + EquipmentSlot slot = CraftEquipmentSlot.getSlot(piece.getFirst()); + org.bukkit.inventory.ItemStack itemStack = CraftItemStack.asBukkitCopy(piece.getSecond()); + bukkitArmor.put(slot, itemStack); + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + EntityEquipmentWrapper wrapper = new EntityEquipmentWrapper(entity, bukkitArmor); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writeEquipmentContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + List> newArmor = new ArrayList<>(); + for (Map.Entry entry : wrapper.getArmor().entrySet()) { + net.minecraft.world.entity.EquipmentSlot slot = CraftEquipmentSlot.getNMS(entry.getKey()); + ItemStack itemStack = CraftItemStack.asNMSCopy(entry.getValue()); + newArmor.add(new Pair<>(slot, itemStack)); + } + + return new ClientboundSetEquipmentPacket(packet.getEntity(), newArmor); + } + + private Packet handlePassengerSet(@NotNull ClientboundSetPassengersPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundSetPassengersPacket"); + int ownerId = packet.getVehicle(); + List passengers = Arrays.stream(packet.getPassengers()).boxed().collect(Collectors.toList()); + MessagesUtil.sendDebugMessages("Mount Packet Sent - Read - EntityID: " + ownerId); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + PassengerWrapper wrapper = new PassengerWrapper(ownerId, passengers); + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writePassengerContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) { + action.set(pluginAction); + } + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + return (Packet) NMSHandlers.getHandler().getPacketHandler().createMountPacket(ownerId, passengers.stream().mapToInt(Integer::intValue).toArray()); + } + + private Packet handleScaleChange(@NotNull ClientboundUpdateAttributesPacket packet) { + final List nmsAttributes = packet.getValues(); + final ClientboundUpdateAttributesPacket.AttributeSnapshot nmsScaleAttribute = nmsAttributes.stream() + .filter(attribute -> attribute.attribute().equals(Attributes.SCALE)) + .findFirst() + .orElse(null); + + if (nmsScaleAttribute == null) { + return packet; + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + PlayerScaleWrapper wrapper = new PlayerScaleWrapper(packet.getEntityId(), nmsScaleAttribute.base()); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().readPlayerScale(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + return packet; + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (!(msg instanceof Packet packet)) { + super.channelRead(ctx, msg); + return; + } + + switch (packet) { + case ServerboundContainerClickPacket clickPacket -> msg = handleInventoryClick(clickPacket); + case ServerboundPlayerActionPacket playerActionPacket -> msg = handlePlayerAction(playerActionPacket); + case ServerboundSwingPacket swingPacket -> msg = handlePlayerArm(swingPacket); + case ServerboundInteractPacket interactPacket -> msg = handleInteract(interactPacket); + default -> {} + } + + if (msg == null) return; + else super.channelRead(ctx, msg); + } + + private Packet handleInventoryClick(@NotNull ServerboundContainerClickPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundContainerClickPacket"); + ClickType clickType = packet.getClickType(); + int slotClicked = packet.getSlotNum(); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readInventoryClick(player, new InventoryClickWrapper(clickType.ordinal(), slotClicked)); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handlePlayerAction(ServerboundPlayerActionPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundPlayerActionPacket"); + ServerboundPlayerActionPacket.Action playerAction = packet.getAction(); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readPlayerAction(player, new PlayerActionWrapper(playerAction.name())); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handlePlayerArm(@NotNull ServerboundSwingPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundSwingPacket"); + PlayerSwingWrapper wrapper = new PlayerSwingWrapper(packet.getHand().name()); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readPlayerArm(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handleInteract(@NotNull ServerboundInteractPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundInteractPacket"); + + PlayerInteractWrapper wrapper = new PlayerInteractWrapper(packet.getEntityId()); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readEntityHandle(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } +} \ No newline at end of file diff --git a/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSPackets.java b/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSPackets.java index 15771e5..9760226 100644 --- a/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSPackets.java +++ b/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSPackets.java @@ -1,6 +1,7 @@ package me.lojosho.hibiscuscommons.nms.v1_21_R1; import com.google.common.collect.ImmutableList; +import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; @@ -9,15 +10,17 @@ import com.mojang.serialization.JsonOps; import io.papermc.paper.adventure.PaperAdventure; import it.unimi.dsi.fastutil.ints.IntList; import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin; +import me.lojosho.hibiscuscommons.nms.v1_21_R1.NMSCommon; import me.lojosho.hibiscuscommons.util.AdventureUtils; +import me.lojosho.hibiscuscommons.util.MessagesUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; +import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.network.chat.RemoteChatSession; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.EntityDataSerializer; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.resources.ResourceLocation; @@ -34,9 +37,7 @@ import net.minecraft.world.level.GameType; import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.PlayerTeam; import net.minecraft.world.scores.Team; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.Location; +import org.bukkit.*; import org.bukkit.craftbukkit.CraftEquipmentSlot; import org.bukkit.craftbukkit.entity.CraftEntityType; import org.bukkit.craftbukkit.entity.CraftPlayer; @@ -138,6 +139,14 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. sendPacket(player, packet); } + @Override + public void sendLookAtPacket(int entityId, Location location, List sendTo) { + fakeNmsEntity.setId(entityId); + fakeNmsEntity.getBukkitEntity().teleport(location); + ClientboundPlayerLookAtPacket packet = new ClientboundPlayerLookAtPacket(EntityAnchorArgument.Anchor.EYES, fakeNmsEntity, EntityAnchorArgument.Anchor.EYES); + for (Player p : sendTo) sendPacket(p, packet); + } + @Override public void sendRotateHeadPacket(int entityId, Location location, List sendTo) { fakeNmsEntity.setId(entityId); @@ -148,10 +157,11 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. } @Override - public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List sendTo) { + public void sendRotationPacket(int entityId, float originalYaw, float pitch, boolean onGround, List sendTo) { float ROTATION_FACTOR = 256.0F / 360.0F; - yaw = (byte) (yaw * ROTATION_FACTOR); + byte yaw = (byte) (originalYaw * ROTATION_FACTOR); pitch = (byte) (pitch * ROTATION_FACTOR); + MessagesUtil.sendDebugMessages("sendRotationPacket. Original: " + originalYaw + " modified: " + yaw); ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround); for (Player p : sendTo) sendPacket(p, packet); } @@ -251,10 +261,12 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. //Adding players to the team (You have to use the NPC's name, and add it to a list) ClientboundSetPlayerTeamPacket createPlayerTeamPacket = ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, new ArrayList() {{ add(name); + add(player.getName()); }}, ClientboundSetPlayerTeamPacket.Action.ADD); sendPacket(player, createPlayerTeamPacket); } + @Override public void sendMountPacket(int mountId, int[] passengerIds, List sendTo) { List passengers = Arrays.stream(passengerIds).mapToObj(id -> { @@ -262,6 +274,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. passenger.setId(id); return passenger; }).toList(); + fakeNmsEntity.setId(mountId); fakeNmsEntity.passengers = ImmutableList.copyOf(passengers); ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity); fakeNmsEntity.passengers = ImmutableList.of(); @@ -292,12 +305,15 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. boolean onGround, List sendTo ) { - fakeNmsEntity.setId(entityId); - fakeNmsEntity.setRot((yaw * 256.0F / 360.0F), (pitch * 256.0F / 360.0F)); - fakeNmsEntity.setOnGround(onGround); + try { + fakeNmsEntity.setId(entityId); + fakeNmsEntity.teleportTo(x, y, z); - ClientboundTeleportEntityPacket packet = new ClientboundTeleportEntityPacket(fakeNmsEntity); - for (Player p : sendTo) sendPacket(p, packet); + ClientboundTeleportEntityPacket packet = new ClientboundTeleportEntityPacket(fakeNmsEntity); + for (Player p : sendTo) sendPacket(p, packet); + } catch (Exception e) { + e.printStackTrace(); + } } @Override @@ -308,6 +324,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. for (Player p : sendTo) sendPacket(p, packet); } + @Override public void sendSpawnEntityPacket(int entityId, UUID uuid, EntityType entityType, Location location, List sendTo) { net.minecraft.world.entity.EntityType nmsEntityType = CraftEntityType.bukkitToMinecraft(entityType); diff --git a/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSUtils.java b/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSUtils.java index 925fb09..a7d016e 100644 --- a/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSUtils.java +++ b/v1_21_R1/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R1/NMSUtils.java @@ -1,15 +1,19 @@ package me.lojosho.hibiscuscommons.nms.v1_21_R1; +import io.netty.channel.Channel; +import io.netty.channel.ChannelPipeline; +import me.lojosho.hibiscuscommons.nms.v1_21_R1.NMSPacketChannel; import net.minecraft.core.component.DataComponents; +import net.minecraft.network.Connection; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.component.DyedItemColor; import org.bukkit.Bukkit; import org.bukkit.Color; -import org.bukkit.FireworkEffect; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,8 +45,7 @@ public class NMSUtils extends NMSCommon implements me.lojosho.hibiscuscommons.nm @Override public ItemStack setColor(@NotNull ItemStack itemStack, Color color) { net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - boolean tooltip = !nmsStack.has(DataComponents.DYED_COLOR) || nmsStack.get(DataComponents.DYED_COLOR).showInTooltip(); - nmsStack.set(DataComponents.DYED_COLOR, new DyedItemColor(color.asRGB(), tooltip)); + nmsStack.set(DataComponents.DYED_COLOR, new DyedItemColor(color.asRGB(), false)); return CraftItemStack.asBukkitCopy(nmsStack); } @@ -54,4 +57,16 @@ public class NMSUtils extends NMSCommon implements me.lojosho.hibiscuscommons.nm } return null; } + + @Override + public void handleChannelOpen(@NotNull Player player) { + Channel channel = ((CraftPlayer) player).getHandle().connection.connection.channel; + ChannelPipeline pipeline = channel.pipeline(); + + NMSPacketChannel channelHandler = new NMSPacketChannel(player); + for (String key : pipeline.toMap().keySet()) { + if (!(pipeline.get(key) instanceof Connection)) continue; + pipeline.addBefore(key, "hibiscus_channel_handler", channelHandler); + } + } } diff --git a/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSPacketChannel.java b/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSPacketChannel.java new file mode 100644 index 0000000..c16efab --- /dev/null +++ b/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSPacketChannel.java @@ -0,0 +1,278 @@ +package me.lojosho.hibiscuscommons.nms.v1_21_R2; + +import com.mojang.datafixers.util.Pair; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPromise; +import lombok.Getter; +import me.lojosho.hibiscuscommons.nms.NMSHandlers; +import me.lojosho.hibiscuscommons.packets.PacketAction; +import me.lojosho.hibiscuscommons.packets.wrapper.*; +import me.lojosho.hibiscuscommons.plugins.SubPlugins; +import me.lojosho.hibiscuscommons.util.MessagesUtil; +import net.minecraft.core.NonNullList; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.*; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.CraftEquipmentSlot; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +public class NMSPacketChannel extends ChannelDuplexHandler { + + @Getter + private final Player player; + + public NMSPacketChannel(Player player) { + this.player = player; + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + if (!(msg instanceof Packet packet)) { + super.write(ctx, msg, promise); + return; + } + + switch (packet) { + case ClientboundContainerSetContentPacket setContentPacket -> msg = handleMenuChange(setContentPacket); + case ClientboundContainerSetSlotPacket setSlotPacket -> msg = handleSlotChange(setSlotPacket); + case ClientboundSetEquipmentPacket equipmentPacket -> msg = handlePlayerEquipment(equipmentPacket); + case ClientboundSetPassengersPacket passengerPacket -> msg = handlePassengerSet(passengerPacket); + case ClientboundUpdateAttributesPacket attributesPacket -> msg = handleScaleChange(attributesPacket); + default -> {} + } + + if (msg == null) return; + else super.write(ctx, msg, promise); + } + + private Packet handleMenuChange(@NotNull ClientboundContainerSetContentPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundContainerSetContentPacket"); + MessagesUtil.sendDebugMessages("Menu Initial "); + + Integer windowId = packet.getContainerId(); + List slotData = packet.getItems(); + + List bukkitItems = new ArrayList<>(); + for (ItemStack nmsItem : slotData) { + if (nmsItem == null) { + slotData.add(null); + continue; + } + bukkitItems.add(CraftItemStack.asBukkitCopy(nmsItem)); + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + ContainerContentWrapper wrapper = new ContainerContentWrapper(windowId, bukkitItems); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().writeContainerContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + NonNullList nmsItems = NonNullList.create(); + for (org.bukkit.inventory.ItemStack bukkitItem : bukkitItems) { + if (bukkitItem == null) { + slotData.add(null); + continue; + } + nmsItems.add(CraftItemStack.asNMSCopy(bukkitItem)); + } + + return new ClientboundContainerSetContentPacket(wrapper.getWindowId(), packet.getStateId(), nmsItems, packet.getCarriedItem()); + } + + private Packet handleSlotChange(@NotNull ClientboundContainerSetSlotPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundContainerSetSlotPacket"); + + final int windowId = packet.getContainerId(); + final int slot = packet.getSlot(); + final ItemStack item = packet.getItem(); + + org.bukkit.inventory.ItemStack bukkitItem = CraftItemStack.asBukkitCopy(item); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SlotContentWrapper wrapper = new SlotContentWrapper(windowId, slot, bukkitItem); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writeSlotContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + final ItemStack nmsItem = CraftItemStack.asNMSCopy(wrapper.getItemStack()); + + return new ClientboundContainerSetSlotPacket(packet.getContainerId(), packet.getStateId(), wrapper.getSlot(), nmsItem); + } + + private Packet handlePlayerEquipment(@NotNull ClientboundSetEquipmentPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundSetEquipmentPacket"); + final List> nmsArmor = packet.getSlots(); + final int entity = packet.getEntity(); + HashMap bukkitArmor = new HashMap<>(); + for (Pair piece : nmsArmor) { + EquipmentSlot slot = CraftEquipmentSlot.getSlot(piece.getFirst()); + org.bukkit.inventory.ItemStack itemStack = CraftItemStack.asBukkitCopy(piece.getSecond()); + bukkitArmor.put(slot, itemStack); + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + EntityEquipmentWrapper wrapper = new EntityEquipmentWrapper(entity, bukkitArmor); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writeEquipmentContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + List> newArmor = new ArrayList<>(); + for (Map.Entry entry : wrapper.getArmor().entrySet()) { + net.minecraft.world.entity.EquipmentSlot slot = CraftEquipmentSlot.getNMS(entry.getKey()); + ItemStack itemStack = CraftItemStack.asNMSCopy(entry.getValue()); + newArmor.add(new Pair<>(slot, itemStack)); + } + + return new ClientboundSetEquipmentPacket(packet.getEntity(), newArmor); + } + + private Packet handlePassengerSet(@NotNull ClientboundSetPassengersPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundSetPassengersPacket"); + int ownerId = packet.getVehicle(); + List passengers = Arrays.stream(packet.getPassengers()).boxed().collect(Collectors.toList()); + MessagesUtil.sendDebugMessages("Mount Packet Sent - Read - EntityID: " + ownerId); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + PassengerWrapper wrapper = new PassengerWrapper(ownerId, passengers); + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writePassengerContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) { + action.set(pluginAction); + } + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + return (Packet) NMSHandlers.getHandler().getPacketHandler().createMountPacket(ownerId, passengers.stream().mapToInt(Integer::intValue).toArray()); + } + + private Packet handleScaleChange(@NotNull ClientboundUpdateAttributesPacket packet) { + final List nmsAttributes = packet.getValues(); + final ClientboundUpdateAttributesPacket.AttributeSnapshot nmsScaleAttribute = nmsAttributes.stream() + .filter(attribute -> attribute.attribute().equals(Attributes.SCALE)) + .findFirst() + .orElse(null); + + if (nmsScaleAttribute == null) { + return packet; + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + PlayerScaleWrapper wrapper = new PlayerScaleWrapper(packet.getEntityId(), nmsScaleAttribute.base()); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().readPlayerScale(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + return packet; + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (!(msg instanceof Packet packet)) { + super.channelRead(ctx, msg); + return; + } + + switch (packet) { + case ServerboundContainerClickPacket clickPacket -> msg = handleInventoryClick(clickPacket); + case ServerboundPlayerActionPacket playerActionPacket -> msg = handlePlayerAction(playerActionPacket); + case ServerboundSwingPacket swingPacket -> msg = handlePlayerArm(swingPacket); + case ServerboundInteractPacket interactPacket -> msg = handleInteract(interactPacket); + default -> {} + } + + if (msg == null) return; + else super.channelRead(ctx, msg); + } + + private Packet handleInventoryClick(@NotNull ServerboundContainerClickPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundContainerClickPacket"); + ClickType clickType = packet.getClickType(); + int slotClicked = packet.getSlotNum(); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readInventoryClick(player, new InventoryClickWrapper(clickType.ordinal(), slotClicked)); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handlePlayerAction(ServerboundPlayerActionPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundPlayerActionPacket"); + ServerboundPlayerActionPacket.Action playerAction = packet.getAction(); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readPlayerAction(player, new PlayerActionWrapper(playerAction.name())); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handlePlayerArm(@NotNull ServerboundSwingPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundSwingPacket"); + PlayerSwingWrapper wrapper = new PlayerSwingWrapper(packet.getHand().name()); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readPlayerArm(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handleInteract(@NotNull ServerboundInteractPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundInteractPacket"); + + PlayerInteractWrapper wrapper = new PlayerInteractWrapper(packet.getEntityId()); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readEntityHandle(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } +} \ No newline at end of file diff --git a/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSPackets.java b/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSPackets.java index cf7b403..41a652e 100644 --- a/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSPackets.java +++ b/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSPackets.java @@ -1,6 +1,7 @@ package me.lojosho.hibiscuscommons.nms.v1_21_R2; import com.google.common.collect.ImmutableList; +import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; @@ -9,15 +10,17 @@ import com.mojang.serialization.JsonOps; import io.papermc.paper.adventure.PaperAdventure; import it.unimi.dsi.fastutil.ints.IntList; import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin; +import me.lojosho.hibiscuscommons.nms.v1_21_R2.NMSCommon; import me.lojosho.hibiscuscommons.util.AdventureUtils; +import me.lojosho.hibiscuscommons.util.MessagesUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; +import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.network.chat.RemoteChatSession; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.EntityDataSerializer; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.resources.ResourceLocation; @@ -35,9 +38,7 @@ import net.minecraft.world.level.GameType; import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.PlayerTeam; import net.minecraft.world.scores.Team; -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.Location; +import org.bukkit.*; import org.bukkit.craftbukkit.CraftEquipmentSlot; import org.bukkit.craftbukkit.entity.CraftEntityType; import org.bukkit.craftbukkit.entity.CraftPlayer; @@ -139,6 +140,14 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. sendPacket(player, packet); } + @Override + public void sendLookAtPacket(int entityId, Location location, List sendTo) { + fakeNmsEntity.setId(entityId); + fakeNmsEntity.getBukkitEntity().teleport(location); + ClientboundPlayerLookAtPacket packet = new ClientboundPlayerLookAtPacket(EntityAnchorArgument.Anchor.EYES, fakeNmsEntity, EntityAnchorArgument.Anchor.EYES); + for (Player p : sendTo) sendPacket(p, packet); + } + @Override public void sendRotateHeadPacket(int entityId, Location location, List sendTo) { fakeNmsEntity.setId(entityId); @@ -149,10 +158,11 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. } @Override - public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List sendTo) { + public void sendRotationPacket(int entityId, float originalYaw, float pitch, boolean onGround, List sendTo) { float ROTATION_FACTOR = 256.0F / 360.0F; - yaw = (byte) (yaw * ROTATION_FACTOR); + byte yaw = (byte) (originalYaw * ROTATION_FACTOR); pitch = (byte) (pitch * ROTATION_FACTOR); + MessagesUtil.sendDebugMessages("sendRotationPacket. Original: " + originalYaw + " modified: " + yaw); ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround); for (Player p : sendTo) sendPacket(p, packet); } @@ -252,6 +262,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. //Adding players to the team (You have to use the NPC's name, and add it to a list) ClientboundSetPlayerTeamPacket createPlayerTeamPacket = ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, new ArrayList() {{ add(name); + add(player.getName()); }}, ClientboundSetPlayerTeamPacket.Action.ADD); sendPacket(player, createPlayerTeamPacket); } @@ -264,6 +275,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. passenger.setId(id); return passenger; }).toList(); + fakeNmsEntity.setId(mountId); fakeNmsEntity.passengers = ImmutableList.copyOf(passengers); ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(fakeNmsEntity); fakeNmsEntity.passengers = ImmutableList.of(); @@ -295,7 +307,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. List sendTo ) { try { - ClientboundTeleportEntityPacket packet = ClientboundTeleportEntityPacket.teleport(entityId, new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), java.util.Set.of(), onGround); + ClientboundTeleportEntityPacket packet = ClientboundTeleportEntityPacket.teleport(entityId, new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), Set.of(), onGround); for (Player p : sendTo) sendPacket(p, packet); } catch (Exception e) { e.printStackTrace(); diff --git a/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSUtils.java b/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSUtils.java index cef93ce..fac0db6 100644 --- a/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSUtils.java +++ b/v1_21_R2/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R2/NMSUtils.java @@ -1,15 +1,19 @@ package me.lojosho.hibiscuscommons.nms.v1_21_R2; +import io.netty.channel.Channel; +import io.netty.channel.ChannelPipeline; +import me.lojosho.hibiscuscommons.nms.v1_21_R2.NMSPacketChannel; import net.minecraft.core.component.DataComponents; +import net.minecraft.network.Connection; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.component.DyedItemColor; import org.bukkit.Bukkit; import org.bukkit.Color; -import org.bukkit.FireworkEffect; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,8 +45,7 @@ public class NMSUtils extends NMSCommon implements me.lojosho.hibiscuscommons.nm @Override public ItemStack setColor(@NotNull ItemStack itemStack, Color color) { net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - boolean tooltip = !nmsStack.has(DataComponents.DYED_COLOR) || nmsStack.get(DataComponents.DYED_COLOR).showInTooltip(); - nmsStack.set(DataComponents.DYED_COLOR, new DyedItemColor(color.asRGB(), tooltip)); + nmsStack.set(DataComponents.DYED_COLOR, new DyedItemColor(color.asRGB(), false)); return CraftItemStack.asBukkitCopy(nmsStack); } @@ -54,4 +57,16 @@ public class NMSUtils extends NMSCommon implements me.lojosho.hibiscuscommons.nm } return null; } + + @Override + public void handleChannelOpen(@NotNull Player player) { + Channel channel = ((CraftPlayer) player).getHandle().connection.connection.channel; + ChannelPipeline pipeline = channel.pipeline(); + + NMSPacketChannel channelHandler = new NMSPacketChannel(player); + for (String key : pipeline.toMap().keySet()) { + if (!(pipeline.get(key) instanceof Connection)) continue; + pipeline.addBefore(key, "hibiscus_channel_handler", channelHandler); + } + } } diff --git a/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSPacketChannel.java b/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSPacketChannel.java new file mode 100644 index 0000000..6c65023 --- /dev/null +++ b/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSPacketChannel.java @@ -0,0 +1,278 @@ +package me.lojosho.hibiscuscommons.nms.v1_21_R3; + +import com.mojang.datafixers.util.Pair; +import io.netty.channel.ChannelDuplexHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPromise; +import lombok.Getter; +import me.lojosho.hibiscuscommons.nms.NMSHandlers; +import me.lojosho.hibiscuscommons.packets.PacketAction; +import me.lojosho.hibiscuscommons.packets.wrapper.*; +import me.lojosho.hibiscuscommons.plugins.SubPlugins; +import me.lojosho.hibiscuscommons.util.MessagesUtil; +import net.minecraft.core.NonNullList; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.*; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.item.ItemStack; +import org.bukkit.craftbukkit.CraftEquipmentSlot; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Player; +import org.bukkit.inventory.EquipmentSlot; +import org.jetbrains.annotations.NotNull; + +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +public class NMSPacketChannel extends ChannelDuplexHandler { + + @Getter + private final Player player; + + public NMSPacketChannel(Player player) { + this.player = player; + } + + @Override + public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { + if (!(msg instanceof Packet packet)) { + super.write(ctx, msg, promise); + return; + } + + switch (packet) { + case ClientboundContainerSetContentPacket setContentPacket -> msg = handleMenuChange(setContentPacket); + case ClientboundContainerSetSlotPacket setSlotPacket -> msg = handleSlotChange(setSlotPacket); + case ClientboundSetEquipmentPacket equipmentPacket -> msg = handlePlayerEquipment(equipmentPacket); + case ClientboundSetPassengersPacket passengerPacket -> msg = handlePassengerSet(passengerPacket); + case ClientboundUpdateAttributesPacket attributesPacket -> msg = handleScaleChange(attributesPacket); + default -> {} + } + + if (msg == null) return; + else super.write(ctx, msg, promise); + } + + private Packet handleMenuChange(@NotNull ClientboundContainerSetContentPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundContainerSetContentPacket"); + MessagesUtil.sendDebugMessages("Menu Initial "); + + Integer windowId = packet.getContainerId(); + List slotData = packet.getItems(); + + List bukkitItems = new ArrayList<>(); + for (ItemStack nmsItem : slotData) { + if (nmsItem == null) { + slotData.add(null); + continue; + } + bukkitItems.add(CraftItemStack.asBukkitCopy(nmsItem)); + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + ContainerContentWrapper wrapper = new ContainerContentWrapper(windowId, bukkitItems); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().writeContainerContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + NonNullList nmsItems = NonNullList.create(); + for (org.bukkit.inventory.ItemStack bukkitItem : bukkitItems) { + if (bukkitItem == null) { + slotData.add(null); + continue; + } + nmsItems.add(CraftItemStack.asNMSCopy(bukkitItem)); + } + + return new ClientboundContainerSetContentPacket(wrapper.getWindowId(), packet.getStateId(), nmsItems, packet.getCarriedItem()); + } + + private Packet handleSlotChange(@NotNull ClientboundContainerSetSlotPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundContainerSetSlotPacket"); + + final int windowId = packet.getContainerId(); + final int slot = packet.getSlot(); + final ItemStack item = packet.getItem(); + + org.bukkit.inventory.ItemStack bukkitItem = CraftItemStack.asBukkitCopy(item); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SlotContentWrapper wrapper = new SlotContentWrapper(windowId, slot, bukkitItem); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writeSlotContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + final ItemStack nmsItem = CraftItemStack.asNMSCopy(wrapper.getItemStack()); + + return new ClientboundContainerSetSlotPacket(packet.getContainerId(), packet.getStateId(), wrapper.getSlot(), nmsItem); + } + + private Packet handlePlayerEquipment(@NotNull ClientboundSetEquipmentPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundSetEquipmentPacket"); + final List> nmsArmor = packet.getSlots(); + final int entity = packet.getEntity(); + HashMap bukkitArmor = new HashMap<>(); + for (Pair piece : nmsArmor) { + EquipmentSlot slot = CraftEquipmentSlot.getSlot(piece.getFirst()); + org.bukkit.inventory.ItemStack itemStack = CraftItemStack.asBukkitCopy(piece.getSecond()); + bukkitArmor.put(slot, itemStack); + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + EntityEquipmentWrapper wrapper = new EntityEquipmentWrapper(entity, bukkitArmor); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writeEquipmentContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + + List> newArmor = new ArrayList<>(); + for (Map.Entry entry : wrapper.getArmor().entrySet()) { + net.minecraft.world.entity.EquipmentSlot slot = CraftEquipmentSlot.getNMS(entry.getKey()); + ItemStack itemStack = CraftItemStack.asNMSCopy(entry.getValue()); + newArmor.add(new Pair<>(slot, itemStack)); + } + + return new ClientboundSetEquipmentPacket(packet.getEntity(), newArmor); + } + + private Packet handlePassengerSet(@NotNull ClientboundSetPassengersPacket packet) { + MessagesUtil.sendDebugMessages("ClientboundSetPassengersPacket"); + int ownerId = packet.getVehicle(); + List passengers = Arrays.stream(packet.getPassengers()).boxed().collect(Collectors.toList()); + MessagesUtil.sendDebugMessages("Mount Packet Sent - Read - EntityID: " + ownerId); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + PassengerWrapper wrapper = new PassengerWrapper(ownerId, passengers); + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().writePassengerContent(player, wrapper); + if (pluginAction != PacketAction.NOTHING) { + action.set(pluginAction); + } + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + return (Packet) NMSHandlers.getHandler().getPacketHandler().createMountPacket(ownerId, passengers.stream().mapToInt(Integer::intValue).toArray()); + } + + private Packet handleScaleChange(@NotNull ClientboundUpdateAttributesPacket packet) { + final List nmsAttributes = packet.getValues(); + final ClientboundUpdateAttributesPacket.AttributeSnapshot nmsScaleAttribute = nmsAttributes.stream() + .filter(attribute -> attribute.attribute().equals(Attributes.SCALE)) + .findFirst() + .orElse(null); + + if (nmsScaleAttribute == null) { + return packet; + } + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + PlayerScaleWrapper wrapper = new PlayerScaleWrapper(packet.getEntityId(), nmsScaleAttribute.base()); + + SubPlugins.getSubPlugins().forEach(plugin -> { + PacketAction pluginAction = plugin.getPacketInterface().readPlayerScale(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + }); + + if (action.get() == PacketAction.CANCELLED) return null; + if (action.get() == PacketAction.NOTHING) return packet; + return packet; + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + if (!(msg instanceof Packet packet)) { + super.channelRead(ctx, msg); + return; + } + + switch (packet) { + case ServerboundContainerClickPacket clickPacket -> msg = handleInventoryClick(clickPacket); + case ServerboundPlayerActionPacket playerActionPacket -> msg = handlePlayerAction(playerActionPacket); + case ServerboundSwingPacket swingPacket -> msg = handlePlayerArm(swingPacket); + case ServerboundInteractPacket interactPacket -> msg = handleInteract(interactPacket); + default -> {} + } + + if (msg == null) return; + else super.channelRead(ctx, msg); + } + + private Packet handleInventoryClick(@NotNull ServerboundContainerClickPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundContainerClickPacket"); + ClickType clickType = packet.getClickType(); + int slotClicked = packet.getSlotNum(); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readInventoryClick(player, new InventoryClickWrapper(clickType.ordinal(), slotClicked)); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handlePlayerAction(ServerboundPlayerActionPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundPlayerActionPacket"); + ServerboundPlayerActionPacket.Action playerAction = packet.getAction(); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readPlayerAction(player, new PlayerActionWrapper(playerAction.name())); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handlePlayerArm(@NotNull ServerboundSwingPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundSwingPacket"); + PlayerSwingWrapper wrapper = new PlayerSwingWrapper(packet.getHand().name()); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readPlayerArm(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } + + private Packet handleInteract(@NotNull ServerboundInteractPacket packet) { + MessagesUtil.sendDebugMessages("ServerboundInteractPacket"); + + PlayerInteractWrapper wrapper = new PlayerInteractWrapper(packet.getEntityId()); + + AtomicReference action = new AtomicReference<>(PacketAction.NOTHING); + SubPlugins.getSubPlugins().forEach(plugin -> { + + PacketAction pluginAction = plugin.getPacketInterface().readEntityHandle(player, wrapper); + if (pluginAction != PacketAction.NOTHING) action.set(pluginAction); + + }); + if (action.get() == PacketAction.CANCELLED) return null; + return packet; + } +} \ No newline at end of file diff --git a/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSPackets.java b/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSPackets.java index 2af9940..b42e422 100644 --- a/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSPackets.java +++ b/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSPackets.java @@ -11,14 +11,15 @@ import io.papermc.paper.adventure.PaperAdventure; import it.unimi.dsi.fastutil.ints.IntList; import me.lojosho.hibiscuscommons.HibiscusCommonsPlugin; import me.lojosho.hibiscuscommons.util.AdventureUtils; +import me.lojosho.hibiscuscommons.util.MessagesUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minecraft.advancements.Advancement; import net.minecraft.advancements.AdvancementHolder; +import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.network.chat.RemoteChatSession; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.*; -import net.minecraft.network.syncher.EntityDataSerializer; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.resources.ResourceLocation; @@ -36,10 +37,7 @@ import net.minecraft.world.level.GameType; import net.minecraft.world.phys.Vec3; import net.minecraft.world.scores.PlayerTeam; import net.minecraft.world.scores.Team; -import org.bukkit.Bukkit; -import org.bukkit.Color; -import org.bukkit.GameMode; -import org.bukkit.Location; +import org.bukkit.*; import org.bukkit.craftbukkit.CraftEquipmentSlot; import org.bukkit.craftbukkit.entity.CraftEntityType; import org.bukkit.craftbukkit.entity.CraftPlayer; @@ -142,6 +140,14 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. sendPacket(player, packet); } + @Override + public void sendLookAtPacket(int entityId, Location location, List sendTo) { + fakeNmsEntity.setId(entityId); + fakeNmsEntity.getBukkitEntity().teleport(location); + ClientboundPlayerLookAtPacket packet = new ClientboundPlayerLookAtPacket(EntityAnchorArgument.Anchor.EYES, fakeNmsEntity, EntityAnchorArgument.Anchor.EYES); + for (Player p : sendTo) sendPacket(p, packet); + } + @Override public void sendRotateHeadPacket(int entityId, Location location, List sendTo) { fakeNmsEntity.setId(entityId); @@ -152,10 +158,11 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. } @Override - public void sendRotationPacket(int entityId, float yaw, float pitch, boolean onGround, List sendTo) { + public void sendRotationPacket(int entityId, float originalYaw, float pitch, boolean onGround, List sendTo) { float ROTATION_FACTOR = 256.0F / 360.0F; - yaw = (byte) (yaw * ROTATION_FACTOR); + byte yaw = (byte) (originalYaw * ROTATION_FACTOR); pitch = (byte) (pitch * ROTATION_FACTOR); + MessagesUtil.sendDebugMessages("sendRotationPacket. Original: " + originalYaw + " modified: " + yaw); ClientboundMoveEntityPacket.Rot packet = new ClientboundMoveEntityPacket.Rot(entityId, (byte) yaw, (byte) pitch, onGround); for (Player p : sendTo) sendPacket(p, packet); } @@ -255,6 +262,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. //Adding players to the team (You have to use the NPC's name, and add it to a list) ClientboundSetPlayerTeamPacket createPlayerTeamPacket = ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, new ArrayList() {{ add(name); + add(player.getName()); }}, ClientboundSetPlayerTeamPacket.Action.ADD); sendPacket(player, createPlayerTeamPacket); } @@ -299,7 +307,7 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. List sendTo ) { try { - ClientboundTeleportEntityPacket packet = ClientboundTeleportEntityPacket.teleport(entityId, new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), java.util.Set.of(), onGround); + ClientboundTeleportEntityPacket packet = ClientboundTeleportEntityPacket.teleport(entityId, new PositionMoveRotation(new Vec3(x, y, z), Vec3.ZERO, yaw, pitch), Set.of(), onGround); for (Player p : sendTo) sendPacket(p, packet); } catch (Exception e) { e.printStackTrace(); @@ -402,10 +410,6 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. components.addProperty("minecraft:enchantment_glint_override", true); } - if (meta.hasItemModel()) { - components.addProperty("minecraft:item_model", meta.getItemModel().toString()); - } - if (meta.hasCustomModelData()) { CustomModelDataComponent customModelDataComponent = meta.getCustomModelDataComponent(); JsonObject customModelDataComponentJson = new JsonObject(); @@ -441,6 +445,11 @@ public class NMSPackets extends NMSCommon implements me.lojosho.hibiscuscommons. components.add("minecraft:custom_model_data", customModelDataComponentJson); } + NamespacedKey itemModel = meta.getItemModel(); + if (itemModel != null) { + components.addProperty("minecraft:item_model", itemModel.toString()); + } + iconObj.add("components", components); } diff --git a/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSUtils.java b/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSUtils.java index fb6f66c..8b018eb 100644 --- a/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSUtils.java +++ b/v1_21_R3/src/main/java/me/lojosho/hibiscuscommons/nms/v1_21_R3/NMSUtils.java @@ -1,15 +1,18 @@ package me.lojosho.hibiscuscommons.nms.v1_21_R3; +import io.netty.channel.Channel; +import io.netty.channel.ChannelPipeline; import net.minecraft.core.component.DataComponents; +import net.minecraft.network.Connection; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.component.DyedItemColor; import org.bukkit.Bukkit; import org.bukkit.Color; -import org.bukkit.FireworkEffect; import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.entity.CraftPlayer; import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,8 +44,7 @@ public class NMSUtils extends NMSCommon implements me.lojosho.hibiscuscommons.nm @Override public ItemStack setColor(@NotNull ItemStack itemStack, Color color) { net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - boolean tooltip = !nmsStack.has(DataComponents.DYED_COLOR) || nmsStack.get(DataComponents.DYED_COLOR).showInTooltip(); - nmsStack.set(DataComponents.DYED_COLOR, new DyedItemColor(color.asRGB(), tooltip)); + nmsStack.set(DataComponents.DYED_COLOR, new DyedItemColor(color.asRGB(), false)); return CraftItemStack.asBukkitCopy(nmsStack); } @@ -54,4 +56,16 @@ public class NMSUtils extends NMSCommon implements me.lojosho.hibiscuscommons.nm } return null; } + + @Override + public void handleChannelOpen(@NotNull Player player) { + Channel channel = ((CraftPlayer) player).getHandle().connection.connection.channel; + ChannelPipeline pipeline = channel.pipeline(); + + NMSPacketChannel channelHandler = new NMSPacketChannel(player); + for (String key : pipeline.toMap().keySet()) { + if (!(pipeline.get(key) instanceof Connection)) continue; + pipeline.addBefore(key, "hibiscus_channel_handler", channelHandler); + } + } }