Add wrapper for BlockData

Closes #34
This commit is contained in:
Dan Mulloy 2015-01-26 17:26:07 -05:00
parent 8846b28469
commit 1d711315e4
4 changed files with 151 additions and 1 deletions

View File

@ -88,6 +88,7 @@ import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction;
import com.comphenix.protocol.wrappers.EnumWrappers.WorldBorderAction; import com.comphenix.protocol.wrappers.EnumWrappers.WorldBorderAction;
import com.comphenix.protocol.wrappers.PlayerInfoData; import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedAttribute; import com.comphenix.protocol.wrappers.WrappedAttribute;
import com.comphenix.protocol.wrappers.WrappedBlockData;
import com.comphenix.protocol.wrappers.WrappedChatComponent; import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedDataWatcher; import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.comphenix.protocol.wrappers.WrappedGameProfile;
@ -612,6 +613,19 @@ public class PacketContainer implements Serializable {
GameProfile.class, BukkitConverters.getWrappedGameProfileConverter()); GameProfile.class, BukkitConverters.getWrappedGameProfileConverter());
} }
/**
* Retrieves a read/write structure for BlockData in Minecraft 1.8.
* <p>
* This modifier will automatically marshall between WrappedBlockData and the
* internal Minecraft BlockData.
* @return A modifier for BlockData fields.
*/
public StructureModifier<WrappedBlockData> getBlockData() {
// Conver to and from our wrapper
return structureModifier.<WrappedBlockData>withType(
MinecraftReflection.getIBlockDataClass(), BukkitConverters.getWrappedBlockDataConverter());
}
/** /**
* Retrieves a read/write structure for chat components in Minecraft 1.7.2. * Retrieves a read/write structure for chat components in Minecraft 1.7.2.
* <p> * <p>

View File

@ -1915,6 +1915,24 @@ public class MinecraftReflection {
return clazz != null && obj.getClass().equals(clazz); return clazz != null && obj.getClass().equals(clazz);
} }
/**
* Retrieve the IBlockData class in 1.8.
* @return The IBlockData class
*/
public static Class<?> getIBlockDataClass() {
return getMinecraftClass("IBlockData");
}
/**
* Determine if the given object is an IBlockData.
* @param obj - the given object.
* @return TRUE if it is, FALSE otherwise.
*/
public static boolean isIBlockData(Object obj) {
Class<?> clazz = getIBlockDataClass();
return clazz != null && obj.getClass().equals(clazz);
}
/** /**
* Retrieve the given class by name. * Retrieve the given class by name.
* @param className - name of the class. * @param className - name of the class.

View File

@ -395,7 +395,7 @@ public class BukkitConverters {
/** /**
* Retrieve a converter for wrapped chat components. * Retrieve a converter for wrapped chat components.
* @return Wrapped chat componetns. * @return Wrapped chat component.
*/ */
public static EquivalentConverter<WrappedChatComponent> getWrappedChatComponentConverter() { public static EquivalentConverter<WrappedChatComponent> getWrappedChatComponentConverter() {
return new IgnoreNullConverter<WrappedChatComponent>() { return new IgnoreNullConverter<WrappedChatComponent>() {
@ -416,6 +416,29 @@ public class BukkitConverters {
}; };
} }
/**
* Retrieve a converter for wrapped block data.
* @return Wrapped block data.
*/
public static EquivalentConverter<WrappedBlockData> getWrappedBlockDataConverter() {
return new IgnoreNullConverter<WrappedBlockData>() {
@Override
protected Object getGenericValue(Class<?> genericType, WrappedBlockData specific) {
return specific.getHandle();
}
@Override
protected WrappedBlockData getSpecificValue(Object generic) {
return new WrappedBlockData(generic);
}
@Override
public Class<WrappedBlockData> getSpecificType() {
return WrappedBlockData.class;
}
};
}
/** /**
* Retrieve a converter for wrapped attribute snapshots. * Retrieve a converter for wrapped attribute snapshots.
* @return Wrapped attribute snapshot converter. * @return Wrapped attribute snapshot converter.

View File

@ -0,0 +1,95 @@
/**
* (c) 2015 dmulloy2
*/
package com.comphenix.protocol.wrappers;
import org.bukkit.Material;
import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.utility.MinecraftReflection;
/**
* Represents a wrapper around IBlockData.
*
* @author dmulloy2
*/
public class WrappedBlockData extends AbstractWrapper {
private static final Class<?> MAGIC_NUMBERS = MinecraftReflection.getCraftBukkitClass("util.CraftMagicNumbers");
private static final Class<?> IBLOCK_DATA = MinecraftReflection.getIBlockDataClass();
private static final Class<?> BLOCK = MinecraftReflection.getBlockClass();
private static MethodAccessor FROM_LEGACY_DATA = null;
private static MethodAccessor GET_NMS_BLOCK = null;
private static MethodAccessor GET_BLOCK = null;
static {
FuzzyReflection fuzzy = FuzzyReflection.fromClass(BLOCK);
FROM_LEGACY_DATA = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("fromLegacyData", IBLOCK_DATA,
new Class<?>[] { int.class }));
fuzzy = FuzzyReflection.fromClass(MAGIC_NUMBERS);
GET_NMS_BLOCK = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getBlock", BLOCK,
new Class<?>[] { int.class }));
fuzzy = FuzzyReflection.fromClass(IBLOCK_DATA);
GET_BLOCK = Accessors.getMethodAccessor(fuzzy.getMethodByParameters("getBlock", BLOCK,
new Class<?>[0]));
}
public WrappedBlockData(Object handle) {
super(IBLOCK_DATA);
setHandle(handle);
}
/**
* Retrieves the type of this BlockData.
* @return The type of this BlockData.
*/
public Material getType() {
Object block = GET_BLOCK.invoke(handle);
return BukkitConverters.getBlockConverter().getSpecific(block);
}
/**
* Sets the type of this BlockData.
* @param type New type
*/
public void setType(Material type) {
setTypeAndData(type, 0);
}
/**
* Sets the type and data of this BlockData.
* @param type New type
* @param data New data
*/
public void setTypeAndData(Material type, int data) {
Object nmsBlock = GET_NMS_BLOCK.invoke(null, type.getId());
Object blockData = FROM_LEGACY_DATA.invoke(nmsBlock, data);
setHandle(blockData);
}
/**
* Creates a new BlockData instance with the given type and no data.
* @param type Block type
* @return New BlockData
*/
public static WrappedBlockData createData(Material type) {
return createData(type, 0);
}
/**
* Creates a new BlockData instance with the given type and data.
* @param type Block type
* @param data Block data
* @return New BlockData
*/
public static WrappedBlockData createData(Material type, int data) {
Object nmsBlock = GET_NMS_BLOCK.invoke(null, type.getId());
Object blockData = FROM_LEGACY_DATA.invoke(nmsBlock, data);
return new WrappedBlockData(blockData);
}
}