Add wrapped block position, fix some errors
Dieser Commit ist enthalten in:
Ursprung
1f6b873f84
Commit
38cf8f4888
@ -423,7 +423,8 @@ public class MinecraftReflection {
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isChunkPosition(Object obj) {
|
||||
return obj != null && getChunkPositionClass().isAssignableFrom(obj.getClass());
|
||||
Class<?> chunkPosition = getChunkPositionClass();
|
||||
return obj != null && chunkPosition != null && chunkPosition.isAssignableFrom(obj.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -447,10 +448,13 @@ public class MinecraftReflection {
|
||||
/**
|
||||
* Determine if a given object is a ChunkCoordinate.
|
||||
* @param obj - the object to test.
|
||||
* @deprecated ChunkCoordinate(s) does not exist.
|
||||
* @return TRUE if it can, FALSE otherwise.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isChunkCoordinates(Object obj) {
|
||||
return obj != null && getChunkCoordinatesClass().isAssignableFrom(obj.getClass());
|
||||
Class<?> chunkCoordinates = getChunkCoordinatesClass();
|
||||
return obj != null && chunkCoordinates != null && chunkCoordinates.isAssignableFrom(obj.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1188,7 +1192,7 @@ public class MinecraftReflection {
|
||||
try {
|
||||
return getMinecraftClass("ChunkPosition");
|
||||
} catch (RuntimeException e) {
|
||||
return getBlockPositionClass();
|
||||
return null;
|
||||
// Class<?> normalChunkGenerator = getCraftBukkitClass("generator.NormalChunkGenerator");
|
||||
//
|
||||
// // ChunkPosition a(net.minecraft.server.World world, String string, int i, int i1, int i2) {
|
||||
@ -1233,6 +1237,7 @@ public class MinecraftReflection {
|
||||
* Retrieve the ChunkCoordinates class.
|
||||
* @return The ChunkPosition class.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Class<?> getChunkCoordinatesClass() {
|
||||
try {
|
||||
return getMinecraftClass("ChunkCoordinates");
|
||||
|
@ -0,0 +1,230 @@
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* Copyright (C) 2012 Kristian S. Stangeland
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program;
|
||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Copies a immutable net.minecraft.server.BlockPosition, which represents a integer 3D vector.
|
||||
*
|
||||
* @author dmulloy2
|
||||
*/
|
||||
public class BlockPosition {
|
||||
|
||||
/**
|
||||
* Represents the null (0, 0, 0) origin.
|
||||
*/
|
||||
public static BlockPosition ORIGIN = new BlockPosition(0, 0, 0);
|
||||
|
||||
private static Constructor<?> blockPositionConstructor;
|
||||
|
||||
// Use protected members, like Bukkit
|
||||
protected final int x;
|
||||
protected final int y;
|
||||
protected final int z;
|
||||
|
||||
// Used to access a BlockPosition, in case it's names are changed
|
||||
private static StructureModifier<Integer> intModifier;
|
||||
|
||||
/**
|
||||
* Construct an immutable 3D vector.
|
||||
*/
|
||||
public BlockPosition(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an immutable integer 3D vector from a mutable Bukkit vector.
|
||||
* @param vector - the mutable real Bukkit vector to copy.
|
||||
*/
|
||||
public BlockPosition(Vector vector) {
|
||||
if (vector == null)
|
||||
throw new IllegalArgumentException("Vector cannot be NULL.");
|
||||
this.x = vector.getBlockX();
|
||||
this.y = vector.getBlockY();
|
||||
this.z = vector.getBlockZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this instance to an equivalent real 3D vector.
|
||||
* @return Real 3D vector.
|
||||
*/
|
||||
public Vector toVector() {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the x-coordinate.
|
||||
* @return X coordinate.
|
||||
*/
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the y-coordinate.
|
||||
* @return Y coordinate.
|
||||
*/
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the z-coordinate.
|
||||
* @return Z coordinate.
|
||||
*/
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the current position and a given position together, producing a result position.
|
||||
* @param other - the other position.
|
||||
* @return The new result position.
|
||||
*/
|
||||
public BlockPosition add(BlockPosition other) {
|
||||
if (other == null)
|
||||
throw new IllegalArgumentException("other cannot be NULL");
|
||||
return new BlockPosition(x + other.x, y + other.y, z + other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the current position and a given position together, producing a result position.
|
||||
* @param other - the other position.
|
||||
* @return The new result position.
|
||||
*/
|
||||
public BlockPosition subtract(BlockPosition other) {
|
||||
if (other == null)
|
||||
throw new IllegalArgumentException("other cannot be NULL");
|
||||
return new BlockPosition(x - other.x, y - other.y, z - other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply each dimension in the current position by the given factor.
|
||||
* @param factor - multiplier.
|
||||
* @return The new result.
|
||||
*/
|
||||
public BlockPosition multiply(int factor) {
|
||||
return new BlockPosition(x * factor, y * factor, z * factor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide each dimension in the current position by the given divisor.
|
||||
* @param divisor - the divisor.
|
||||
* @return The new result.
|
||||
*/
|
||||
public BlockPosition divide(int divisor) {
|
||||
if (divisor == 0)
|
||||
throw new IllegalArgumentException("Cannot divide by null.");
|
||||
return new BlockPosition(x / divisor, y / divisor, z / divisor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to convert between NMS ChunkPosition and the wrapper instance.
|
||||
* @return A new converter.
|
||||
*/
|
||||
public static EquivalentConverter<BlockPosition> getConverter() {
|
||||
return new EquivalentConverter<BlockPosition>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, BlockPosition specific) {
|
||||
if (blockPositionConstructor == null) {
|
||||
try {
|
||||
blockPositionConstructor = MinecraftReflection.getBlockPositionClass().
|
||||
getConstructor(int.class, int.class, int.class);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot find block position constructor.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the underlying BlockPosition
|
||||
try {
|
||||
Object result = blockPositionConstructor.newInstance(specific.x, specific.y, specific.z);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct BlockPosition.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPosition getSpecific(Object generic) {
|
||||
if (MinecraftReflection.isBlockPosition(generic)) {
|
||||
// Use a structure modifier
|
||||
intModifier = new StructureModifier<Object>(generic.getClass(), null, false).withType(int.class);
|
||||
|
||||
// Damn it all
|
||||
if (intModifier.size() < 3) {
|
||||
throw new IllegalStateException("Cannot read class " + generic.getClass() + " for its integer fields.");
|
||||
}
|
||||
|
||||
if (intModifier.size() >= 3) {
|
||||
try {
|
||||
StructureModifier<Integer> instance = intModifier.withTarget(generic);
|
||||
BlockPosition result = new BlockPosition(instance.read(0), instance.read(1), instance.read(2));
|
||||
return result;
|
||||
} catch (FieldAccessException e) {
|
||||
// This is an exeptional work-around, so we don't want to burden the caller with the messy details
|
||||
throw new RuntimeException("Field access error.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, return NULL
|
||||
return null;
|
||||
}
|
||||
|
||||
// Thanks Java Generics!
|
||||
@Override
|
||||
public Class<BlockPosition> getSpecificType() {
|
||||
return BlockPosition.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Fast checks
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
|
||||
// Only compare objects of similar type
|
||||
if (obj instanceof BlockPosition) {
|
||||
BlockPosition other = (BlockPosition) obj;
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BlockPosition [x=" + x + ", y=" + y + ", z=" + z + "]";
|
||||
}
|
||||
}
|
@ -353,6 +353,8 @@ public class WrappedWatchableObject extends AbstractWrapper {
|
||||
static Class<?> getWrappedType(Class<?> unwrapped) {
|
||||
if (unwrapped.equals(MinecraftReflection.getChunkPositionClass()))
|
||||
return ChunkPosition.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getBlockPositionClass()))
|
||||
return BlockPosition.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getChunkCoordinatesClass()))
|
||||
return WrappedChunkCoordinate.class;
|
||||
else if (unwrapped.equals(MinecraftReflection.getItemStackClass()))
|
||||
@ -369,13 +371,13 @@ public class WrappedWatchableObject extends AbstractWrapper {
|
||||
static Object getUnwrapped(Object wrapped) {
|
||||
// Convert special cases
|
||||
if (wrapped instanceof ChunkPosition)
|
||||
return ChunkPosition.getConverter().getGeneric(
|
||||
MinecraftReflection.getChunkPositionClass(), (ChunkPosition) wrapped);
|
||||
return ChunkPosition.getConverter().getGeneric(MinecraftReflection.getChunkPositionClass(), (ChunkPosition) wrapped);
|
||||
else if (wrapped instanceof BlockPosition)
|
||||
return BlockPosition.getConverter().getGeneric(MinecraftReflection.getBlockPositionClass(), (BlockPosition) wrapped);
|
||||
else if (wrapped instanceof WrappedChunkCoordinate)
|
||||
return ((WrappedChunkCoordinate) wrapped).getHandle();
|
||||
else if (wrapped instanceof ItemStack)
|
||||
return BukkitConverters.getItemStackConverter().getGeneric(
|
||||
MinecraftReflection.getItemStackClass(), (ItemStack) wrapped);
|
||||
return BukkitConverters.getItemStackConverter().getGeneric(MinecraftReflection.getItemStackClass(), (ItemStack) wrapped);
|
||||
else
|
||||
return wrapped;
|
||||
}
|
||||
@ -388,6 +390,8 @@ public class WrappedWatchableObject extends AbstractWrapper {
|
||||
static Class<?> getUnwrappedType(Class<?> wrapped) {
|
||||
if (wrapped.equals(ChunkPosition.class))
|
||||
return MinecraftReflection.getChunkPositionClass();
|
||||
else if (wrapped.equals(BlockPosition.class))
|
||||
return MinecraftReflection.getBlockPositionClass();
|
||||
else if (wrapped.equals(WrappedChunkCoordinate.class))
|
||||
return MinecraftReflection.getChunkCoordinatesClass();
|
||||
else if (ItemStack.class.isAssignableFrom(wrapped))
|
||||
@ -417,7 +421,10 @@ public class WrappedWatchableObject extends AbstractWrapper {
|
||||
Object value = getNMSValue();
|
||||
|
||||
// Only a limited set of references types are supported
|
||||
if (MinecraftReflection.isChunkPosition(value)) {
|
||||
if (MinecraftReflection.isBlockPosition(value)) {
|
||||
EquivalentConverter<BlockPosition> converter = BlockPosition.getConverter();
|
||||
return converter.getGeneric(MinecraftReflection.getBlockPositionClass(), converter.getSpecific(value));
|
||||
} else if (MinecraftReflection.isChunkPosition(value)) {
|
||||
EquivalentConverter<ChunkPosition> converter = ChunkPosition.getConverter();
|
||||
return converter.getGeneric(MinecraftReflection.getChunkPositionClass(), converter.getSpecific(value));
|
||||
} else if (MinecraftReflection.isItemStack(value)) {
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren