From 9b0d4294cb904ca9e11135eb29fb8f8246963719 Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Tue, 10 Dec 2013 13:21:31 +0100 Subject: [PATCH] Adding a converter for block fields. --- .../protocol/events/PacketContainer.java | 28 ++++++++--- .../protocol/wrappers/BukkitConverters.java | 49 ++++++++++++++++++- .../protocol/wrappers/WrappedServerPing.java | 1 - .../protocol/events/PacketContainerTest.java | 8 +++ 4 files changed, 77 insertions(+), 9 deletions(-) diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketContainer.java b/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketContainer.java index 5522f6e1..7977749c 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketContainer.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/events/PacketContainer.java @@ -39,6 +39,8 @@ import javax.annotation.Nullable; import net.minecraft.util.com.mojang.authlib.GameProfile; import net.minecraft.util.io.netty.buffer.ByteBuf; import net.minecraft.util.io.netty.buffer.UnpooledByteBufAllocator; + +import org.bukkit.Material; import org.bukkit.World; import org.bukkit.WorldType; import org.bukkit.entity.Entity; @@ -486,6 +488,20 @@ public class PacketContainer implements Serializable { ); } + + /** + * Retrieves a read/write structure for block fields. + *

+ * This modifier will automatically marshall between Material and the + * internal Minecraft Block. + * @return A modifier for GameProfile fields. + */ + public StructureModifier getBlocks() { + // Convert to and from the Bukkit wrapper + return structureModifier.withType( + MinecraftReflection.getBlockClass(), BukkitConverters.getBlockConverter()); + } + /** * Retrieves a read/write structure for game profiles in Minecraft 1.7.2. *

@@ -526,7 +542,7 @@ public class PacketContainer implements Serializable { } /** - * Retrieve a read/write structure for the Protocol enum. + * Retrieve a read/write structure for the Protocol enum in 1.7.2. * @return A modifier for Protocol enum fields. */ public StructureModifier getProtocols() { @@ -536,7 +552,7 @@ public class PacketContainer implements Serializable { } /** - * Retrieve a read/write structure for the ClientCommand enum. + * Retrieve a read/write structure for the ClientCommand enum in 1.7.2. * @return A modifier for ClientCommand enum fields. */ public StructureModifier getClientCommands() { @@ -546,7 +562,7 @@ public class PacketContainer implements Serializable { } /** - * Retrieve a read/write structure for the ChatVisibility enum. + * Retrieve a read/write structure for the ChatVisibility enum in 1.7.2. * @return A modifier for ChatVisibility enum fields. */ public StructureModifier getChatVisibilities() { @@ -556,7 +572,7 @@ public class PacketContainer implements Serializable { } /** - * Retrieve a read/write structure for the Difficulty enum. + * Retrieve a read/write structure for the Difficulty enum in 1.7.2. * @return A modifier for Difficulty enum fields. */ public StructureModifier getDifficulties() { @@ -566,7 +582,7 @@ public class PacketContainer implements Serializable { } /** - * Retrieve a read/write structure for the EntityUse enum. + * Retrieve a read/write structure for the EntityUse enum in 1.7.2. * @return A modifier for EntityUse enum fields. */ public StructureModifier getEntityUseActions() { @@ -576,7 +592,7 @@ public class PacketContainer implements Serializable { } /** - * Retrieve a read/write structure for the NativeGameMode enum. + * Retrieve a read/write structure for the NativeGameMode enum in 1.7.2. * @return A modifier for NativeGameMode enum fields. */ public StructureModifier getGamemodes() { diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java index ffb26d27..9b6fbee1 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java @@ -21,12 +21,14 @@ import java.lang.ref.WeakReference; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import org.bukkit.Material; import org.bukkit.World; import org.bukkit.WorldType; import org.bukkit.entity.Entity; @@ -35,7 +37,6 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.PacketType.Protocol; import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.injector.PacketConstructor; @@ -44,6 +45,9 @@ import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.StructureModifier; +import com.comphenix.protocol.reflect.accessors.Accessors; +import com.comphenix.protocol.reflect.accessors.MethodAccessor; +import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.reflect.instances.DefaultInstances; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.wrappers.nbt.NbtBase; @@ -73,6 +77,10 @@ public class BukkitConverters { private static Method worldTypeName; private static Method worldTypeGetType; + // Used to get block instances + private static MethodAccessor GET_BLOCK; + private static MethodAccessor GET_BLOCK_ID; + // Used for potion effect conversion private static volatile Constructor mobEffectConstructor; private static volatile StructureModifier mobEffectModifier; @@ -586,7 +594,44 @@ public class BukkitConverters { }; } - + /** + * Retrieve a converter for block instances. + * @return A converter for block instances. + */ + public static EquivalentConverter getBlockConverter() { + // Initialize if we have't already + if (GET_BLOCK == null || GET_BLOCK_ID == null) { + Class block = MinecraftReflection.getBlockClass(); + + FuzzyMethodContract getIdContract = FuzzyMethodContract.newBuilder(). + parameterExactArray(block). + requireModifier(Modifier.STATIC). + build(); + FuzzyMethodContract getBlockContract = FuzzyMethodContract.newBuilder(). + parameterExactArray(int.class). + requireModifier(Modifier.STATIC). + build(); + GET_BLOCK = Accessors.getMethodAccessor(FuzzyReflection.fromClass(block).getMethod(getBlockContract)); + GET_BLOCK_ID = Accessors.getMethodAccessor(FuzzyReflection.fromClass(block).getMethod(getIdContract)); + } + + return new IgnoreNullConverter() { + @Override + protected Object getGenericValue(Class genericType, Material specific) { + return GET_BLOCK.invoke(null, specific.getId()); + } + + @Override + protected Material getSpecificValue(Object generic) { + return Material.getMaterial((Integer) GET_BLOCK_ID.invoke(null, generic)); + } + + @Override + public Class getSpecificType() { + return Material.class; + } + }; + } /** * Retrieve the converter used to convert between a PotionEffect and the equivalent NMS Mobeffect. diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedServerPing.java b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedServerPing.java index 7927c2cc..d4ccb06c 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedServerPing.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedServerPing.java @@ -6,7 +6,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.nio.ByteBuffer; import java.util.List; import javax.imageio.ImageIO; diff --git a/ProtocolLib/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java b/ProtocolLib/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java index 2f67d4c7..00554cae 100644 --- a/ProtocolLib/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java +++ b/ProtocolLib/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java @@ -378,6 +378,14 @@ public class PacketContainerTest { ToStringBuilder.reflectionToString(snapshot, ToStringStyle.SHORT_PREFIX_STYLE), ToStringBuilder.reflectionToString(clonedSnapshot, ToStringStyle.SHORT_PREFIX_STYLE)); } + + @Test + public void testBlocks() { + PacketContainer blockAction = new PacketContainer(PacketType.Play.Server.BLOCK_ACTION); + blockAction.getBlocks().write(0, Material.STONE); + + assertEquals(Material.STONE, blockAction.getBlocks().read(0)); + } @SuppressWarnings("deprecation") @Test