Archiviert
13
0

Add support for getting vectors

Dieser Commit ist enthalten in:
Dan Mulloy 2014-12-05 21:41:55 -05:00
Ursprung 2c017c6dac
Commit f6e0bcf6f5
3 geänderte Dateien mit 96 neuen und 19 gelöschten Zeilen

Datei anzeigen

@ -45,6 +45,7 @@ import org.bukkit.World;
import org.bukkit.WorldType; import org.bukkit.WorldType;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Protocol; import com.comphenix.protocol.PacketType.Protocol;
@ -499,6 +500,17 @@ public class PacketContainer implements Serializable {
BukkitConverters.getNbtConverter()); BukkitConverters.getNbtConverter());
} }
/**
* Retrieves a read/write structure for Vectors.
* @return A modifier for Vectors.
*/
public StructureModifier<Vector> getVectors() {
// Automatically marshal between Vec3d and the Bukkit wrapper
return structureModifier.withType(
MinecraftReflection.getVec3dClass(),
BukkitConverters.getVectorConverter());
}
/** /**
* Retrieves a read/write structure for collections of attribute snapshots. * Retrieves a read/write structure for collections of attribute snapshots.
* <p> * <p>

Datei anzeigen

@ -1237,6 +1237,19 @@ public class MinecraftReflection {
} }
} }
/**
* Retrieves the Vec3d class.
* @return The Vec3d class.
*/
public static Class<?> getVec3dClass() {
try {
return getMinecraftClass("Vec3d");
} catch (RuntimeException e) {
// TODO: Figure out a fuzzy field contract
return null;
}
}
/** /**
* Retrieve the ChunkCoordinates class. * Retrieve the ChunkCoordinates class.
* @return The ChunkPosition class. * @return The ChunkPosition class.

Datei anzeigen

@ -35,6 +35,7 @@ import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
@ -121,6 +122,7 @@ public class BukkitConverters {
* @param <T> - type that can be converted. * @param <T> - type that can be converted.
*/ */
private static abstract class IgnoreNullConverter<TType> implements EquivalentConverter<TType> { private static abstract class IgnoreNullConverter<TType> implements EquivalentConverter<TType> {
@Override
public final Object getGeneric(Class<?> genericType, TType specific) { public final Object getGeneric(Class<?> genericType, TType specific) {
if (specific != null) if (specific != null)
return getGenericValue(genericType, specific); return getGenericValue(genericType, specific);
@ -448,6 +450,7 @@ public class BukkitConverters {
return specific.getHandle(); return specific.getHandle();
} }
@Override
protected WrappedWatchableObject getSpecificValue(Object generic) { protected WrappedWatchableObject getSpecificValue(Object generic) {
if (MinecraftReflection.isWatchableObject(generic)) if (MinecraftReflection.isWatchableObject(generic))
return new WrappedWatchableObject(generic); return new WrappedWatchableObject(generic);
@ -799,6 +802,56 @@ public class BukkitConverters {
}; };
} }
private static Constructor<?> vec3dConstructor;
private static StructureModifier<Object> vec3dModifier;
/**
* Retrieve the converter used to convert between a Vector and the equivalent NMS Vec3d.
* @return The Vector converter.
*/
public static EquivalentConverter<Vector> getVectorConverter() {
return new IgnoreNullConverter<Vector>() {
@Override
public Class<Vector> getSpecificType() {
return Vector.class;
}
@Override
protected Object getGenericValue(Class<?> genericType, Vector specific) {
if (vec3dConstructor == null) {
try {
vec3dConstructor = MinecraftReflection.getVec3dClass().getConstructor(
double.class, double.class, double.class);
} catch (Throwable ex) {
throw new RuntimeException("Could not find Vec3d constructor (double, double, double)");
}
}
try {
return vec3dConstructor.newInstance(specific.getX(), specific.getY(), specific.getZ());
} catch (Throwable ex) {
throw new RuntimeException("Could not construct Vec3d.", ex);
}
}
@Override
protected Vector getSpecificValue(Object generic) {
if (vec3dModifier == null) {
vec3dModifier = new StructureModifier<Object>(MinecraftReflection.getVec3dClass(), false);
}
StructureModifier<Double> doubles = vec3dModifier.withTarget(generic).withType(double.class);
return new Vector(
doubles.read(0), /* x */
doubles.read(1), /* y */
doubles.read(2) /* z */
);
}
};
}
/** /**
* Wraps a given equivalent converter in NULL checks, ensuring that such values are ignored. * Wraps a given equivalent converter in NULL checks, ensuring that such values are ignored.
* @param delegate - the underlying equivalent converter. * @param delegate - the underlying equivalent converter.
@ -832,7 +885,6 @@ public class BukkitConverters {
*/ */
public static Unwrapper asUnwrapper(final Class<?> nativeType, final EquivalentConverter<Object> converter) { public static Unwrapper asUnwrapper(final Class<?> nativeType, final EquivalentConverter<Object> converter) {
return new Unwrapper() { return new Unwrapper() {
@SuppressWarnings("rawtypes")
@Override @Override
public Object unwrapItem(Object wrappedObject) { public Object unwrapItem(Object wrappedObject) {
Class<?> type = PacketConstructor.getClass(wrappedObject); Class<?> type = PacketConstructor.getClass(wrappedObject);
@ -842,7 +894,7 @@ public class BukkitConverters {
if (wrappedObject instanceof Class) if (wrappedObject instanceof Class)
return nativeType; return nativeType;
else else
return converter.getGeneric((Class) nativeType, wrappedObject); return converter.getGeneric(nativeType, wrappedObject);
} }
return null; return null;
} }