2022-12-07 19:52:09 +01:00
|
|
|
package com.comphenix.protocol.wrappers;
|
|
|
|
|
|
|
|
import com.comphenix.protocol.BukkitInitialization;
|
Packet filtering for bundled packets in 1.19.4 (#2258)
Since Minecraft 1.19.4, the protocol supports bundling consecutive packets to ensure the client processes them in one tick. However, Packet Events are not called for the individual packets in such a bundle in the current dev build of ProtocolLib. For example, no packet events are currently sent for the ENTITY_METADATA packet when an entity is first spawned as the packet is bundled with the ENTITY_SPAWN packet. However, if the entity metadata is changed later on, the event will be called.
This PR proposes to fix this by unpacking the bundled packets and invoking the packet filtering for each packet.
I also want to briefly explain how the bundling works. A bundle starts with a PACKET_DELIMITER (0x00, net.minecraft.network.protocol.BundleDelimiterPacket) packet followed by all packets that should be bundled and finished with another PACKET_DELIMITER (0x00). Within the Netty pipeline, this sequence is transformed into one synthesized packet found in net.minecraft.network.protocol.game.ClientboundBundlePacket, which is essentially just a list of packets. At the stage at which ProtocolLib injects into the clientbound netty pipeline, this packet has not been unpacked yet. Thus, we need to handle the ClientboundBundlePacket, which unfortunately is not registered in ProtocolLib. The fact that two different classes map to the same packet currently requires a dirty remapping in the packet structure modifier.
2023-03-26 04:08:31 +02:00
|
|
|
import com.comphenix.protocol.PacketType;
|
|
|
|
import com.comphenix.protocol.events.PacketContainer;
|
2022-12-07 19:52:09 +01:00
|
|
|
import com.comphenix.protocol.reflect.EquivalentConverter;
|
2023-04-29 21:49:51 +02:00
|
|
|
import com.comphenix.protocol.utility.TestUtils;
|
2022-12-07 19:52:09 +01:00
|
|
|
import com.comphenix.protocol.wrappers.Either.Left;
|
Packet filtering for bundled packets in 1.19.4 (#2258)
Since Minecraft 1.19.4, the protocol supports bundling consecutive packets to ensure the client processes them in one tick. However, Packet Events are not called for the individual packets in such a bundle in the current dev build of ProtocolLib. For example, no packet events are currently sent for the ENTITY_METADATA packet when an entity is first spawned as the packet is bundled with the ENTITY_SPAWN packet. However, if the entity metadata is changed later on, the event will be called.
This PR proposes to fix this by unpacking the bundled packets and invoking the packet filtering for each packet.
I also want to briefly explain how the bundling works. A bundle starts with a PACKET_DELIMITER (0x00, net.minecraft.network.protocol.BundleDelimiterPacket) packet followed by all packets that should be bundled and finished with another PACKET_DELIMITER (0x00). Within the Netty pipeline, this sequence is transformed into one synthesized packet found in net.minecraft.network.protocol.game.ClientboundBundlePacket, which is essentially just a list of packets. At the stage at which ProtocolLib injects into the clientbound netty pipeline, this packet has not been unpacked yet. Thus, we need to handle the ClientboundBundlePacket, which unfortunately is not registered in ProtocolLib. The fact that two different classes map to the same packet currently requires a dirty remapping in the packet structure modifier.
2023-03-26 04:08:31 +02:00
|
|
|
import org.apache.commons.lang.builder.EqualsBuilder;
|
2022-12-07 19:52:09 +01:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.ChatColor;
|
|
|
|
import org.bukkit.Material;
|
|
|
|
import org.bukkit.enchantments.Enchantment;
|
|
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import org.bukkit.inventory.meta.ItemMeta;
|
|
|
|
import org.junit.jupiter.api.BeforeAll;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
2023-04-29 21:49:51 +02:00
|
|
|
import java.util.Random;
|
|
|
|
|
2023-05-01 05:28:19 +02:00
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
2023-04-29 21:49:51 +02:00
|
|
|
|
2022-12-07 19:52:09 +01:00
|
|
|
public class BukkitConvertersTest {
|
|
|
|
|
2023-04-29 21:49:51 +02:00
|
|
|
@BeforeAll
|
|
|
|
public static void beforeClass() {
|
|
|
|
BukkitInitialization.initializeAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
public void testItemStacks() {
|
|
|
|
ItemStack item = new ItemStack(Material.DIAMOND_SWORD, 16);
|
|
|
|
item.addEnchantment(Enchantment.DAMAGE_ALL, 4);
|
|
|
|
ItemMeta meta = item.getItemMeta();
|
|
|
|
meta.setDisplayName(ChatColor.GREEN + "Diamond Sword");
|
|
|
|
item.setItemMeta(meta);
|
|
|
|
|
|
|
|
EquivalentConverter<ItemStack> converter = BukkitConverters.getItemStackConverter();
|
|
|
|
Object nmsStack = converter.getGeneric(item);
|
|
|
|
ItemStack back = converter.getSpecific(nmsStack);
|
|
|
|
|
|
|
|
assertEquals(item.getType(), back.getType());
|
|
|
|
assertEquals(item.getDurability(), back.getDurability());
|
|
|
|
assertEquals(item.hasItemMeta(), back.hasItemMeta());
|
|
|
|
assertTrue(Bukkit.getItemFactory().equals(item.getItemMeta(), back.getItemMeta()));
|
|
|
|
}
|
2022-12-07 19:52:09 +01:00
|
|
|
|
|
|
|
@Test
|
|
|
|
public void testEither() {
|
|
|
|
Either<String, String> test = new Left<>("bla");
|
|
|
|
|
|
|
|
EquivalentConverter<Either<String, String>> converter = BukkitConverters.getEitherConverter(
|
2023-04-29 21:49:51 +02:00
|
|
|
Converters.passthrough(String.class), Converters.passthrough(String.class)
|
2022-12-07 19:52:09 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
com.mojang.datafixers.util.Either<String, String> nmsEither = (com.mojang.datafixers.util.Either<String, String>) converter.getGeneric(test);
|
|
|
|
Either<String, String> wrapped = converter.getSpecific(nmsEither);
|
|
|
|
|
|
|
|
assertEquals(wrapped.left(), nmsEither.left());
|
|
|
|
assertEquals(wrapped.right(), nmsEither.right());
|
|
|
|
}
|
Packet filtering for bundled packets in 1.19.4 (#2258)
Since Minecraft 1.19.4, the protocol supports bundling consecutive packets to ensure the client processes them in one tick. However, Packet Events are not called for the individual packets in such a bundle in the current dev build of ProtocolLib. For example, no packet events are currently sent for the ENTITY_METADATA packet when an entity is first spawned as the packet is bundled with the ENTITY_SPAWN packet. However, if the entity metadata is changed later on, the event will be called.
This PR proposes to fix this by unpacking the bundled packets and invoking the packet filtering for each packet.
I also want to briefly explain how the bundling works. A bundle starts with a PACKET_DELIMITER (0x00, net.minecraft.network.protocol.BundleDelimiterPacket) packet followed by all packets that should be bundled and finished with another PACKET_DELIMITER (0x00). Within the Netty pipeline, this sequence is transformed into one synthesized packet found in net.minecraft.network.protocol.game.ClientboundBundlePacket, which is essentially just a list of packets. At the stage at which ProtocolLib injects into the clientbound netty pipeline, this packet has not been unpacked yet. Thus, we need to handle the ClientboundBundlePacket, which unfortunately is not registered in ProtocolLib. The fact that two different classes map to the same packet currently requires a dirty remapping in the packet structure modifier.
2023-03-26 04:08:31 +02:00
|
|
|
|
2023-05-01 05:28:19 +02:00
|
|
|
@Test
|
|
|
|
public void testPacketContainerConverter() {
|
|
|
|
for (PacketType type : PacketType.values()) {
|
|
|
|
if(!type.isSupported()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
PacketContainer container = new PacketContainer(type);
|
|
|
|
Object generic = BukkitConverters.getPacketContainerConverter().getGeneric(container);
|
|
|
|
Object specific = BukkitConverters.getPacketContainerConverter().getSpecific(generic);
|
|
|
|
assertTrue(EqualsBuilder.reflectionEquals(container, specific)); // PacketContainer does not properly implement equals(.)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
void getWrappedMessageSignatureConverter() {
|
|
|
|
byte[] data = new byte[256];
|
|
|
|
new Random().nextBytes(data);
|
|
|
|
WrappedMessageSignature messageSignature = new WrappedMessageSignature(data);
|
|
|
|
|
|
|
|
assertArrayEquals(data, BukkitConverters.getWrappedMessageSignatureConverter().getSpecific(BukkitConverters.getWrappedMessageSignatureConverter().getGeneric(messageSignature)).getBytes());
|
|
|
|
}
|
2023-04-29 21:49:51 +02:00
|
|
|
|
|
|
|
@Test
|
|
|
|
public void testRemoteChatSessionDataConverter() throws Exception {
|
|
|
|
WrappedRemoteChatSessionData wrappedRemoteChatSessionData = TestUtils.creteDummyRemoteChatSessionData();
|
|
|
|
Object generic = BukkitConverters.getWrappedRemoteChatSessionDataConverter().getGeneric(wrappedRemoteChatSessionData);
|
|
|
|
|
|
|
|
WrappedRemoteChatSessionData specific = BukkitConverters.getWrappedRemoteChatSessionDataConverter().getSpecific(generic);
|
|
|
|
assertEquals(wrappedRemoteChatSessionData, specific);
|
|
|
|
|
|
|
|
}
|
2022-12-07 19:52:09 +01:00
|
|
|
}
|