Adding a converter for block fields.

This commit is contained in:
Kristian S. Stangeland 2013-12-10 13:21:31 +01:00
parent c3ae43c75f
commit 9b0d4294cb
4 changed files with 77 additions and 9 deletions

View File

@ -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.
* <p>
* This modifier will automatically marshall between Material and the
* internal Minecraft Block.
* @return A modifier for GameProfile fields.
*/
public StructureModifier<Material> getBlocks() {
// Convert to and from the Bukkit wrapper
return structureModifier.<Material>withType(
MinecraftReflection.getBlockClass(), BukkitConverters.getBlockConverter());
}
/**
* Retrieves a read/write structure for game profiles in Minecraft 1.7.2.
* <p>
@ -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<Protocol> 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<ClientCommand> 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<ChatVisibility> 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<Difficulty> 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<EntityUseAction> 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<NativeGameMode> getGamemodes() {

View File

@ -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<Object> mobEffectModifier;
@ -586,7 +594,44 @@ public class BukkitConverters {
};
}
/**
* Retrieve a converter for block instances.
* @return A converter for block instances.
*/
public static EquivalentConverter<Material> 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<Material>() {
@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<Material> getSpecificType() {
return Material.class;
}
};
}
/**
* Retrieve the converter used to convert between a PotionEffect and the equivalent NMS Mobeffect.

View File

@ -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;

View File

@ -379,6 +379,14 @@ public class PacketContainerTest {
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
public void testPotionEffect() {