Refactor the wrapper classes so they inherit from a common class.
Dieser Commit ist enthalten in:
Ursprung
143ed2ff02
Commit
e8759d0b72
@ -43,6 +43,10 @@ public class PacketType implements Serializable {
|
|||||||
public static class Handshake {
|
public static class Handshake {
|
||||||
private static final Protocol PROTOCOL = Protocol.HANDSHAKING;
|
private static final Protocol PROTOCOL = Protocol.HANDSHAKING;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incoming packets.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
public static class Client extends ObjectEnum<PacketType> {
|
public static class Client extends ObjectEnum<PacketType> {
|
||||||
private final static Sender SENDER = Sender.CLIENT;
|
private final static Sender SENDER = Sender.CLIENT;
|
||||||
/**
|
/**
|
||||||
@ -92,6 +96,10 @@ public class PacketType implements Serializable {
|
|||||||
public static class Play {
|
public static class Play {
|
||||||
private static final Protocol PROTOCOL = Protocol.GAME;
|
private static final Protocol PROTOCOL = Protocol.GAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outgoing packets.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
public static class Server extends ObjectEnum<PacketType> {
|
public static class Server extends ObjectEnum<PacketType> {
|
||||||
private final static Sender SENDER = Sender.SERVER;
|
private final static Sender SENDER = Sender.SERVER;
|
||||||
|
|
||||||
@ -183,6 +191,10 @@ public class PacketType implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incoming packets.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
public static class Client extends ObjectEnum<PacketType> {
|
public static class Client extends ObjectEnum<PacketType> {
|
||||||
private final static Sender SENDER = Sender.CLIENT;
|
private final static Sender SENDER = Sender.CLIENT;
|
||||||
|
|
||||||
@ -236,6 +248,10 @@ public class PacketType implements Serializable {
|
|||||||
public static class Status {
|
public static class Status {
|
||||||
private static final Protocol PROTOCOL = Protocol.STATUS;
|
private static final Protocol PROTOCOL = Protocol.STATUS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outgoing packets.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
public static class Server extends ObjectEnum<PacketType> {
|
public static class Server extends ObjectEnum<PacketType> {
|
||||||
private final static Sender SENDER = Sender.SERVER;
|
private final static Sender SENDER = Sender.SERVER;
|
||||||
|
|
||||||
@ -256,6 +272,10 @@ public class PacketType implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incoming packets.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
public static class Client extends ObjectEnum<PacketType> {
|
public static class Client extends ObjectEnum<PacketType> {
|
||||||
private final static Sender SENDER = Sender.CLIENT;
|
private final static Sender SENDER = Sender.CLIENT;
|
||||||
|
|
||||||
@ -288,6 +308,10 @@ public class PacketType implements Serializable {
|
|||||||
public static class Login {
|
public static class Login {
|
||||||
private static final Protocol PROTOCOL = Protocol.LOGIN;
|
private static final Protocol PROTOCOL = Protocol.LOGIN;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outgoing packets.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
public static class Server extends ObjectEnum<PacketType> {
|
public static class Server extends ObjectEnum<PacketType> {
|
||||||
private final static Sender SENDER = Sender.SERVER;
|
private final static Sender SENDER = Sender.SERVER;
|
||||||
|
|
||||||
@ -309,6 +333,10 @@ public class PacketType implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incoming packets.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
public static class Client extends ObjectEnum<PacketType> {
|
public static class Client extends ObjectEnum<PacketType> {
|
||||||
private final static Sender SENDER = Sender.CLIENT;
|
private final static Sender SENDER = Sender.CLIENT;
|
||||||
|
|
||||||
@ -341,6 +369,10 @@ public class PacketType implements Serializable {
|
|||||||
public static class Legacy {
|
public static class Legacy {
|
||||||
private static final Protocol PROTOCOL = Protocol.LEGACY;
|
private static final Protocol PROTOCOL = Protocol.LEGACY;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outgoing packets.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
// Missing server packets: [10, 11, 12, 21, 107, 252]
|
// Missing server packets: [10, 11, 12, 21, 107, 252]
|
||||||
public static class Server extends ObjectEnum<PacketType> {
|
public static class Server extends ObjectEnum<PacketType> {
|
||||||
private final static Sender SENDER = Sender.SERVER;
|
private final static Sender SENDER = Sender.SERVER;
|
||||||
@ -377,6 +409,10 @@ public class PacketType implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Incoming packets.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
// Missing client packets: [1, 9, 255]
|
// Missing client packets: [1, 9, 255]
|
||||||
public static class Client extends ObjectEnum<PacketType> {
|
public static class Client extends ObjectEnum<PacketType> {
|
||||||
private final static Sender SENDER = Sender.CLIENT;
|
private final static Sender SENDER = Sender.CLIENT;
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
package com.comphenix.protocol.wrappers;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a wrapper for an NMS object.
|
||||||
|
* @author Kristian
|
||||||
|
*/
|
||||||
|
public abstract class AbstractWrapper {
|
||||||
|
protected Object handle;
|
||||||
|
protected Class<?> handleType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new NMS wrapper.
|
||||||
|
* @param handle - the wrapped NMS object.
|
||||||
|
*/
|
||||||
|
public AbstractWrapper(Class<?> handleType) {
|
||||||
|
this.handleType = Preconditions.checkNotNull(handleType, "handleType cannot be NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the underlying NMS object.
|
||||||
|
* @param handle - the NMS object.
|
||||||
|
* @throws IllegalArgumentException If the handle is NULL.
|
||||||
|
* @throws IllegalArgumentException If the handle is not assignable to {@link #getHandleType()}.
|
||||||
|
*/
|
||||||
|
protected void setHandle(Object handle) {
|
||||||
|
if (handle == null)
|
||||||
|
throw new IllegalArgumentException("handle cannot be NULL.");
|
||||||
|
if (!handleType.isAssignableFrom(handle.getClass()))
|
||||||
|
throw new IllegalArgumentException("handle (" + handle + ") is not a " + handleType);
|
||||||
|
this.handle = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the underlying NMS object.
|
||||||
|
* @return The underlying NMS object.
|
||||||
|
*/
|
||||||
|
public Object getHandle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the type of the handle.
|
||||||
|
* @return The type of the handle.
|
||||||
|
*/
|
||||||
|
public Class<?> getHandleType() {
|
||||||
|
return handleType;
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ import com.google.common.collect.Sets;
|
|||||||
* Represents a single attribute sent in packet 44.
|
* Represents a single attribute sent in packet 44.
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class WrappedAttribute {
|
public class WrappedAttribute extends AbstractWrapper {
|
||||||
// Shared structure modifier
|
// Shared structure modifier
|
||||||
private static StructureModifier<Object> ATTRIBUTE_MODIFIER;
|
private static StructureModifier<Object> ATTRIBUTE_MODIFIER;
|
||||||
|
|
||||||
@ -43,6 +43,22 @@ public class WrappedAttribute {
|
|||||||
// Cached modifiers list
|
// Cached modifiers list
|
||||||
private Set<WrappedAttributeModifier> attributeModifiers;
|
private Set<WrappedAttributeModifier> attributeModifiers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a wrapper around a specific NMS instance.
|
||||||
|
* @param handle - the NMS instance.
|
||||||
|
*/
|
||||||
|
private WrappedAttribute(@Nonnull Object handle) {
|
||||||
|
super(MinecraftReflection.getAttributeSnapshotClass());
|
||||||
|
setHandle(handle);
|
||||||
|
|
||||||
|
// Initialize modifier
|
||||||
|
if (ATTRIBUTE_MODIFIER == null) {
|
||||||
|
ATTRIBUTE_MODIFIER = new StructureModifier<Object>(MinecraftReflection.getAttributeSnapshotClass());
|
||||||
|
}
|
||||||
|
this.modifier = ATTRIBUTE_MODIFIER.withTarget(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new wrapped attribute around a specific NMS instance.
|
* Construct a new wrapped attribute around a specific NMS instance.
|
||||||
* @param handle - handle to a NMS AttributeSnapshot.
|
* @param handle - handle to a NMS AttributeSnapshot.
|
||||||
@ -70,33 +86,6 @@ public class WrappedAttribute {
|
|||||||
return new Builder(Preconditions.checkNotNull(template, "template cannot be NULL."));
|
return new Builder(Preconditions.checkNotNull(template, "template cannot be NULL."));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a wrapper around a specific NMS instance.
|
|
||||||
* @param handle - the NMS instance.
|
|
||||||
*/
|
|
||||||
private WrappedAttribute(@Nonnull Object handle) {
|
|
||||||
this.handle = Preconditions.checkNotNull(handle, "handle cannot be NULL.");
|
|
||||||
|
|
||||||
// Check handle type
|
|
||||||
if (!MinecraftReflection.getAttributeSnapshotClass().isAssignableFrom(handle.getClass())) {
|
|
||||||
throw new IllegalArgumentException("handle (" + handle + ") must be a AttributeSnapshot.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize modifier
|
|
||||||
if (ATTRIBUTE_MODIFIER == null) {
|
|
||||||
ATTRIBUTE_MODIFIER = new StructureModifier<Object>(MinecraftReflection.getAttributeSnapshotClass());
|
|
||||||
}
|
|
||||||
this.modifier = ATTRIBUTE_MODIFIER.withTarget(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the underlying NMS attribute snapshot.
|
|
||||||
* @return The underlying attribute snapshot.
|
|
||||||
*/
|
|
||||||
public Object getHandle() {
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the unique attribute key that identifies its function.
|
* Retrieve the unique attribute key that identifies its function.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -19,7 +19,7 @@ import com.google.common.base.Preconditions;
|
|||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class WrappedAttributeModifier {
|
public class WrappedAttributeModifier extends AbstractWrapper {
|
||||||
/**
|
/**
|
||||||
* Represents the different modifier operations.
|
* Represents the different modifier operations.
|
||||||
* <p>
|
* <p>
|
||||||
@ -86,10 +86,7 @@ public class WrappedAttributeModifier {
|
|||||||
// The constructor we are interested in
|
// The constructor we are interested in
|
||||||
private static Constructor<?> ATTRIBUTE_MODIFIER_CONSTRUCTOR;
|
private static Constructor<?> ATTRIBUTE_MODIFIER_CONSTRUCTOR;
|
||||||
|
|
||||||
/**
|
// A modifier for the wrapped handler
|
||||||
* Handle to the underlying AttributeModifier.
|
|
||||||
*/
|
|
||||||
protected Object handle;
|
|
||||||
protected StructureModifier<Object> modifier;
|
protected StructureModifier<Object> modifier;
|
||||||
|
|
||||||
// Cached values
|
// Cached values
|
||||||
@ -98,6 +95,58 @@ public class WrappedAttributeModifier {
|
|||||||
private final Operation operation;
|
private final Operation operation;
|
||||||
private final double amount;
|
private final double amount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new wrapped attribute modifier with no associated handle.
|
||||||
|
* <p>
|
||||||
|
* Note that the handle object is not initialized after this constructor.
|
||||||
|
* @param uuid - the UUID.
|
||||||
|
* @param name - the human readable name.
|
||||||
|
* @param amount - the amount.
|
||||||
|
* @param operation - the operation.
|
||||||
|
*/
|
||||||
|
protected WrappedAttributeModifier(UUID uuid, String name, double amount, Operation operation) {
|
||||||
|
super(MinecraftReflection.getAttributeModifierClass());
|
||||||
|
|
||||||
|
// Use the supplied values instead of reading from the NMS instance
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.name = name;
|
||||||
|
this.amount = amount;
|
||||||
|
this.operation = operation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an attribute modifier wrapper around a given NMS instance.
|
||||||
|
* @param handle - the NMS instance.
|
||||||
|
*/
|
||||||
|
protected WrappedAttributeModifier(@Nonnull Object handle) {
|
||||||
|
// Update handle and modifier
|
||||||
|
super(MinecraftReflection.getAttributeModifierClass());
|
||||||
|
setHandle(handle);
|
||||||
|
initializeModifier(handle);
|
||||||
|
|
||||||
|
// Load final values, caching them
|
||||||
|
this.uuid = (UUID) modifier.withType(UUID.class).read(0);
|
||||||
|
this.name = (String) modifier.withType(String.class).read(0);
|
||||||
|
this.amount = (Double) modifier.withType(double.class).read(0);
|
||||||
|
this.operation = Operation.fromId((Integer) modifier.withType(int.class).read(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an attribute modifier wrapper around a NMS instance.
|
||||||
|
* @param handle - the NMS instance.
|
||||||
|
* @param uuid - the UUID.
|
||||||
|
* @param name - the human readable name.
|
||||||
|
* @param amount - the amount.
|
||||||
|
* @param operation - the operation.
|
||||||
|
*/
|
||||||
|
protected WrappedAttributeModifier(@Nonnull Object handle, UUID uuid, String name, double amount, Operation operation) {
|
||||||
|
this(uuid, name, amount, operation);
|
||||||
|
|
||||||
|
// Initialize handle and modifier
|
||||||
|
setHandle(handle);
|
||||||
|
initializeModifier(handle);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new attribute modifier builder.
|
* Construct a new attribute modifier builder.
|
||||||
* <p>
|
* <p>
|
||||||
@ -136,53 +185,6 @@ public class WrappedAttributeModifier {
|
|||||||
return new WrappedAttributeModifier(handle);
|
return new WrappedAttributeModifier(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a new wrapped attribute modifier with no associated handle.
|
|
||||||
* @param uuid - the UUID.
|
|
||||||
* @param name - the human readable name.
|
|
||||||
* @param amount - the amount.
|
|
||||||
* @param operation - the operation.
|
|
||||||
*/
|
|
||||||
protected WrappedAttributeModifier(UUID uuid, String name, double amount, Operation operation) {
|
|
||||||
// Use the supplied values instead of reading from the NMS instance
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.name = name;
|
|
||||||
this.amount = amount;
|
|
||||||
this.operation = operation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct an attribute modifier wrapper around a given NMS instance.
|
|
||||||
* @param handle - the NMS instance.
|
|
||||||
*/
|
|
||||||
protected WrappedAttributeModifier(@Nonnull Object handle) {
|
|
||||||
// Update handle and modifier
|
|
||||||
setHandle(handle);
|
|
||||||
initializeModifier(handle);
|
|
||||||
|
|
||||||
// Load final values, caching them
|
|
||||||
this.uuid = (UUID) modifier.withType(UUID.class).read(0);
|
|
||||||
this.name = (String) modifier.withType(String.class).read(0);
|
|
||||||
this.amount = (Double) modifier.withType(double.class).read(0);
|
|
||||||
this.operation = Operation.fromId((Integer) modifier.withType(int.class).read(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct an attribute modifier wrapper around a NMS instance.
|
|
||||||
* @param handle - the NMS instance.
|
|
||||||
* @param uuid - the UUID.
|
|
||||||
* @param name - the human readable name.
|
|
||||||
* @param amount - the amount.
|
|
||||||
* @param operation - the operation.
|
|
||||||
*/
|
|
||||||
protected WrappedAttributeModifier(@Nonnull Object handle, UUID uuid, String name, double amount, Operation operation) {
|
|
||||||
this(uuid, name, amount, operation);
|
|
||||||
|
|
||||||
// Initialize handle and modifier
|
|
||||||
setHandle(handle);
|
|
||||||
initializeModifier(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize modifier from a given handle.
|
* Initialize modifier from a given handle.
|
||||||
* @param handle - the handle.
|
* @param handle - the handle.
|
||||||
@ -196,17 +198,6 @@ public class WrappedAttributeModifier {
|
|||||||
this.modifier = BASE_MODIFIER.withTarget(handle);
|
this.modifier = BASE_MODIFIER.withTarget(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the handle of a modifier.
|
|
||||||
* @param handle - the underlying handle.
|
|
||||||
*/
|
|
||||||
private void setHandle(Object handle) {
|
|
||||||
// Check handle type
|
|
||||||
if (!MinecraftReflection.getAttributeModifierClass().isAssignableFrom(handle.getClass()))
|
|
||||||
throw new IllegalArgumentException("handle (" + handle + ") must be a AttributeModifier.");
|
|
||||||
this.handle = handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the unique UUID that identifies the origin of this modifier.
|
* Retrieve the unique UUID that identifies the origin of this modifier.
|
||||||
* @return The unique UUID.
|
* @return The unique UUID.
|
||||||
@ -241,16 +232,6 @@ public class WrappedAttributeModifier {
|
|||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoked when we need to construct a handle object.
|
|
||||||
*/
|
|
||||||
protected void checkHandle() {
|
|
||||||
if (handle == null) {
|
|
||||||
handle = newBuilder(this).build().getHandle();
|
|
||||||
initializeModifier(handle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the underlying attribute modifier.
|
* Retrieve the underlying attribute modifier.
|
||||||
* @return The underlying modifier.
|
* @return The underlying modifier.
|
||||||
|
@ -11,7 +11,7 @@ import com.comphenix.protocol.utility.MinecraftReflection;
|
|||||||
* Represents a chat component added in Minecraft 1.7.2
|
* Represents a chat component added in Minecraft 1.7.2
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class WrappedChatComponent {
|
public class WrappedChatComponent extends AbstractWrapper {
|
||||||
private static final Class<?> SERIALIZER = MinecraftReflection.getChatSerializer();
|
private static final Class<?> SERIALIZER = MinecraftReflection.getChatSerializer();
|
||||||
private static final Class<?> COMPONENT = MinecraftReflection.getIChatBaseComponent();
|
private static final Class<?> COMPONENT = MinecraftReflection.getIChatBaseComponent();
|
||||||
private static MethodAccessor SERIALIZE_COMPONENT = null;
|
private static MethodAccessor SERIALIZE_COMPONENT = null;
|
||||||
@ -32,11 +32,11 @@ public class WrappedChatComponent {
|
|||||||
MinecraftReflection.getCraftChatMessage(), "fromString", String.class);
|
MinecraftReflection.getCraftChatMessage(), "fromString", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object handle;
|
|
||||||
private transient String cache;
|
private transient String cache;
|
||||||
|
|
||||||
private WrappedChatComponent(Object handle, String cache) {
|
private WrappedChatComponent(Object handle, String cache) {
|
||||||
this.handle = handle;
|
super(MinecraftReflection.getIChatBaseComponent());
|
||||||
|
setHandle(handle);
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,10 +46,6 @@ public class WrappedChatComponent {
|
|||||||
* @return The wrapper.
|
* @return The wrapper.
|
||||||
*/
|
*/
|
||||||
public static WrappedChatComponent fromHandle(Object handle) {
|
public static WrappedChatComponent fromHandle(Object handle) {
|
||||||
if (handle == null)
|
|
||||||
throw new IllegalArgumentException("handle cannot be NULL.");
|
|
||||||
if (!COMPONENT.isAssignableFrom(handle.getClass()))
|
|
||||||
throw new IllegalArgumentException("handle (" + handle + ") is not a " + COMPONENT);
|
|
||||||
return new WrappedChatComponent(handle, null);
|
return new WrappedChatComponent(handle, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,14 +97,6 @@ public class WrappedChatComponent {
|
|||||||
this.cache = obj;
|
this.cache = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the underlying IChatBaseComponent instance.
|
|
||||||
* @return The underlying instance.
|
|
||||||
*/
|
|
||||||
public Object getHandle() {
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj == this)
|
if (obj == this)
|
||||||
|
@ -26,27 +26,26 @@ import com.google.common.base.Objects;
|
|||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class WrappedChunkCoordinate implements Comparable<WrappedChunkCoordinate> {
|
public class WrappedChunkCoordinate extends AbstractWrapper implements Comparable<WrappedChunkCoordinate> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If TRUE, NULLs should be put before non-null instances of this class.
|
* If TRUE, NULLs should be put before non-null instances of this class.
|
||||||
*/
|
*/
|
||||||
private static final boolean LARGER_THAN_NULL = true;
|
private static final boolean LARGER_THAN_NULL = true;
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
protected Comparable handle;
|
|
||||||
|
|
||||||
// Used to access a ChunkCoordinate
|
// Used to access a ChunkCoordinate
|
||||||
private static StructureModifier<Integer> intModifier;
|
private static StructureModifier<Integer> SHARED_MODIFIER;
|
||||||
|
|
||||||
|
// The current modifier
|
||||||
|
private StructureModifier<Integer> handleModifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new empty wrapper.
|
* Create a new empty wrapper.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
public WrappedChunkCoordinate() {
|
public WrappedChunkCoordinate() {
|
||||||
|
super(MinecraftReflection.getChunkCoordinatesClass());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.handle = (Comparable) MinecraftReflection.getChunkCoordinatesClass().newInstance();
|
setHandle(getHandleType().newInstance());
|
||||||
initializeModifier();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Cannot construct chunk coordinate.");
|
throw new RuntimeException("Cannot construct chunk coordinate.");
|
||||||
}
|
}
|
||||||
@ -58,17 +57,17 @@ public class WrappedChunkCoordinate implements Comparable<WrappedChunkCoordinate
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
public WrappedChunkCoordinate(Comparable handle) {
|
public WrappedChunkCoordinate(Comparable handle) {
|
||||||
if (handle == null)
|
super(MinecraftReflection.getChunkCoordinatesClass());
|
||||||
throw new IllegalArgumentException("handle cannot be NULL");
|
setHandle(handle);
|
||||||
this.handle = handle;
|
|
||||||
initializeModifier();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the structure modifier is initialized
|
// Ensure that the structure modifier is initialized
|
||||||
private void initializeModifier() {
|
private StructureModifier<Integer> getModifier() {
|
||||||
if (intModifier == null) {
|
if (SHARED_MODIFIER == null)
|
||||||
intModifier = new StructureModifier<Object>(handle.getClass(), null, false).withType(int.class);
|
SHARED_MODIFIER = new StructureModifier<Object>(handle.getClass(), null, false).withType(int.class);
|
||||||
}
|
if (handleModifier == null)
|
||||||
|
handleModifier = SHARED_MODIFIER.withTarget(handle);
|
||||||
|
return handleModifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,7 +100,7 @@ public class WrappedChunkCoordinate implements Comparable<WrappedChunkCoordinate
|
|||||||
* @return The x coordinate.
|
* @return The x coordinate.
|
||||||
*/
|
*/
|
||||||
public int getX() {
|
public int getX() {
|
||||||
return intModifier.read(0);
|
return getModifier().read(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,7 +108,7 @@ public class WrappedChunkCoordinate implements Comparable<WrappedChunkCoordinate
|
|||||||
* @param newX - the new x coordinate.
|
* @param newX - the new x coordinate.
|
||||||
*/
|
*/
|
||||||
public void setX(int newX) {
|
public void setX(int newX) {
|
||||||
intModifier.write(0, newX);
|
getModifier().write(0, newX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,7 +116,7 @@ public class WrappedChunkCoordinate implements Comparable<WrappedChunkCoordinate
|
|||||||
* @return The y coordinate.
|
* @return The y coordinate.
|
||||||
*/
|
*/
|
||||||
public int getY() {
|
public int getY() {
|
||||||
return intModifier.read(1);
|
return getModifier().read(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,7 +124,7 @@ public class WrappedChunkCoordinate implements Comparable<WrappedChunkCoordinate
|
|||||||
* @param newY - the new y coordinate.
|
* @param newY - the new y coordinate.
|
||||||
*/
|
*/
|
||||||
public void setY(int newY) {
|
public void setY(int newY) {
|
||||||
intModifier.write(1, newY);
|
getModifier().write(1, newY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,7 +132,7 @@ public class WrappedChunkCoordinate implements Comparable<WrappedChunkCoordinate
|
|||||||
* @return The z coordinate.
|
* @return The z coordinate.
|
||||||
*/
|
*/
|
||||||
public int getZ() {
|
public int getZ() {
|
||||||
return intModifier.read(2);
|
return getModifier().read(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,7 +140,7 @@ public class WrappedChunkCoordinate implements Comparable<WrappedChunkCoordinate
|
|||||||
* @param newZ - the new z coordinate.
|
* @param newZ - the new z coordinate.
|
||||||
*/
|
*/
|
||||||
public void setZ(int newZ) {
|
public void setZ(int newZ) {
|
||||||
intModifier.write(2, newZ);
|
getModifier().write(2, newZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,7 +158,7 @@ public class WrappedChunkCoordinate implements Comparable<WrappedChunkCoordinate
|
|||||||
if (other.handle == null)
|
if (other.handle == null)
|
||||||
return LARGER_THAN_NULL ? -1 : 1;
|
return LARGER_THAN_NULL ? -1 : 1;
|
||||||
else
|
else
|
||||||
return handle.compareTo(other.handle);
|
return ((Comparable<Object>) handle).compareTo(other.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,35 +52,32 @@ import com.google.common.collect.Iterators;
|
|||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
public class WrappedDataWatcher extends AbstractWrapper implements Iterable<WrappedWatchableObject> {
|
||||||
/**
|
/**
|
||||||
* Used to assign integer IDs to given types.
|
* Used to assign integer IDs to given types.
|
||||||
*/
|
*/
|
||||||
private static Map<Class<?>, Integer> typeMap;
|
private static Map<Class<?>, Integer> TYPE_MAP;
|
||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
private static Field valueMapField;
|
private static Field VALUE_MAP_FIELD;
|
||||||
private static Field readWriteLockField;
|
private static Field READ_WRITE_LOCK_FIELD;
|
||||||
private static Field entityField;
|
private static Field ENTITY_FIELD;
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
private static Method createKeyValueMethod;
|
private static Method CREATE_KEY_VALUE_METHOD;
|
||||||
private static Method updateKeyValueMethod;
|
private static Method UPDATE_KEY_VALUE_METHOD;
|
||||||
private static Method getKeyValueMethod;
|
private static Method GET_KEY_VALUE_METHOD;
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
private static Constructor<?> createDataWatcherConstructor;
|
private static Constructor<?> CREATE_DATA_WATCHER_CONSTRUCTOR;
|
||||||
|
|
||||||
// Entity methods
|
// Entity methods
|
||||||
private volatile static Field entityDataField;
|
private volatile static Field ENTITY_DATA_FIELD;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not this class has already been initialized.
|
* Whether or not this class has already been initialized.
|
||||||
*/
|
*/
|
||||||
private static boolean hasInitialized;
|
private static boolean HAS_INITIALIZED;
|
||||||
|
|
||||||
// The underlying DataWatcher we're modifying
|
|
||||||
protected Object handle;
|
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
private ReadWriteLock readWriteLock;
|
private ReadWriteLock readWriteLock;
|
||||||
@ -96,12 +93,14 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
* @throws FieldAccessException If we're unable to wrap a DataWatcher.
|
* @throws FieldAccessException If we're unable to wrap a DataWatcher.
|
||||||
*/
|
*/
|
||||||
public WrappedDataWatcher() {
|
public WrappedDataWatcher() {
|
||||||
|
super(MinecraftReflection.getDataWatcherClass());
|
||||||
|
|
||||||
// Just create a new watcher
|
// Just create a new watcher
|
||||||
try {
|
try {
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
this.handle = newEntityHandle(null);
|
setHandle(newEntityHandle(null));
|
||||||
} else {
|
} else {
|
||||||
this.handle = MinecraftReflection.getDataWatcherClass().newInstance();
|
setHandle(getHandleType().newInstance());
|
||||||
}
|
}
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
@ -116,12 +115,8 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
* @throws FieldAccessException If we're unable to wrap a DataWatcher.
|
* @throws FieldAccessException If we're unable to wrap a DataWatcher.
|
||||||
*/
|
*/
|
||||||
public WrappedDataWatcher(Object handle) {
|
public WrappedDataWatcher(Object handle) {
|
||||||
if (handle == null)
|
super(MinecraftReflection.getDataWatcherClass());
|
||||||
throw new IllegalArgumentException("Handle cannot be NULL.");
|
setHandle(handle);
|
||||||
if (!MinecraftReflection.isDataWatcher(handle))
|
|
||||||
throw new IllegalArgumentException("The value " + handle + " is not a DataWatcher.");
|
|
||||||
|
|
||||||
this.handle = handle;
|
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,10 +145,10 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
Class<?> dataWatcher = MinecraftReflection.getDataWatcherClass();
|
Class<?> dataWatcher = MinecraftReflection.getDataWatcherClass();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (createDataWatcherConstructor == null)
|
if (CREATE_DATA_WATCHER_CONSTRUCTOR == null)
|
||||||
createDataWatcherConstructor = dataWatcher.getConstructor(MinecraftReflection.getEntityClass());
|
CREATE_DATA_WATCHER_CONSTRUCTOR = dataWatcher.getConstructor(MinecraftReflection.getEntityClass());
|
||||||
|
|
||||||
return createDataWatcherConstructor.newInstance(
|
return CREATE_DATA_WATCHER_CONSTRUCTOR.newInstance(
|
||||||
BukkitUnwrapper.getInstance().unwrapItem(entity)
|
BukkitUnwrapper.getInstance().unwrapItem(entity)
|
||||||
);
|
);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -190,14 +185,6 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the underlying data watcher.
|
|
||||||
* @return The underlying data watcher.
|
|
||||||
*/
|
|
||||||
public Object getHandle() {
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the ID of a given type, if it's allowed to be watched.
|
* Retrieve the ID of a given type, if it's allowed to be watched.
|
||||||
* @return The ID, or NULL if it cannot be watched.
|
* @return The ID, or NULL if it cannot be watched.
|
||||||
@ -205,7 +192,7 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
*/
|
*/
|
||||||
public static Integer getTypeID(Class<?> clazz) throws FieldAccessException {
|
public static Integer getTypeID(Class<?> clazz) throws FieldAccessException {
|
||||||
initialize();
|
initialize();
|
||||||
return typeMap.get(WrappedWatchableObject.getUnwrappedType(clazz));
|
return TYPE_MAP.get(WrappedWatchableObject.getUnwrappedType(clazz));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -216,7 +203,7 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
public static Class<?> getTypeClass(int id) throws FieldAccessException {
|
public static Class<?> getTypeClass(int id) throws FieldAccessException {
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
for (Map.Entry<Class<?>, Integer> entry : typeMap.entrySet()) {
|
for (Map.Entry<Class<?>, Integer> entry : TYPE_MAP.entrySet()) {
|
||||||
if (Objects.equal(entry.getValue(), id)) {
|
if (Objects.equal(entry.getValue(), id)) {
|
||||||
return entry.getKey();
|
return entry.getKey();
|
||||||
}
|
}
|
||||||
@ -462,7 +449,7 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
if (watchable != null) {
|
if (watchable != null) {
|
||||||
new WrappedWatchableObject(watchable).setValue(newValue, update);
|
new WrappedWatchableObject(watchable).setValue(newValue, update);
|
||||||
} else {
|
} else {
|
||||||
createKeyValueMethod.invoke(handle, index, WrappedWatchableObject.getUnwrapped(newValue));
|
CREATE_KEY_VALUE_METHOD.invoke(handle, index, WrappedWatchableObject.getUnwrapped(newValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle invoking the method
|
// Handle invoking the method
|
||||||
@ -479,9 +466,9 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
|
|
||||||
private Object getWatchedObject(int index) throws FieldAccessException {
|
private Object getWatchedObject(int index) throws FieldAccessException {
|
||||||
// We use the get-method first and foremost
|
// We use the get-method first and foremost
|
||||||
if (getKeyValueMethod != null) {
|
if (GET_KEY_VALUE_METHOD != null) {
|
||||||
try {
|
try {
|
||||||
return getKeyValueMethod.invoke(handle, index);
|
return GET_KEY_VALUE_METHOD.invoke(handle, index);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new FieldAccessException("Cannot invoke get key method for index " + index, e);
|
throw new FieldAccessException("Cannot invoke get key method for index " + index, e);
|
||||||
}
|
}
|
||||||
@ -506,8 +493,8 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
// Cache the read write lock
|
// Cache the read write lock
|
||||||
if (readWriteLock != null)
|
if (readWriteLock != null)
|
||||||
return readWriteLock;
|
return readWriteLock;
|
||||||
else if (readWriteLockField != null)
|
else if (READ_WRITE_LOCK_FIELD != null)
|
||||||
return readWriteLock = (ReadWriteLock) FieldUtils.readField(readWriteLockField, handle, true);
|
return readWriteLock = (ReadWriteLock) FieldUtils.readField(READ_WRITE_LOCK_FIELD, handle, true);
|
||||||
else
|
else
|
||||||
return readWriteLock = new ReentrantReadWriteLock();
|
return readWriteLock = new ReentrantReadWriteLock();
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
@ -524,7 +511,7 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
protected Map<Integer, Object> getWatchableObjectMap() throws FieldAccessException {
|
protected Map<Integer, Object> getWatchableObjectMap() throws FieldAccessException {
|
||||||
if (watchableObjects == null) {
|
if (watchableObjects == null) {
|
||||||
try {
|
try {
|
||||||
watchableObjects = (Map<Integer, Object>) FieldUtils.readField(valueMapField, handle, true);
|
watchableObjects = (Map<Integer, Object>) FieldUtils.readField(VALUE_MAP_FIELD, handle, true);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new FieldAccessException("Cannot read watchable object field.", e);
|
throw new FieldAccessException("Cannot read watchable object field.", e);
|
||||||
}
|
}
|
||||||
@ -539,14 +526,14 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
* @throws FieldAccessException Reflection failed.
|
* @throws FieldAccessException Reflection failed.
|
||||||
*/
|
*/
|
||||||
public static WrappedDataWatcher getEntityWatcher(Entity entity) throws FieldAccessException {
|
public static WrappedDataWatcher getEntityWatcher(Entity entity) throws FieldAccessException {
|
||||||
if (entityDataField == null)
|
if (ENTITY_DATA_FIELD == null)
|
||||||
entityDataField = FuzzyReflection.fromClass(MinecraftReflection.getEntityClass(), true).
|
ENTITY_DATA_FIELD = FuzzyReflection.fromClass(MinecraftReflection.getEntityClass(), true).
|
||||||
getFieldByType("datawatcher", MinecraftReflection.getDataWatcherClass());
|
getFieldByType("datawatcher", MinecraftReflection.getDataWatcherClass());
|
||||||
|
|
||||||
BukkitUnwrapper unwrapper = new BukkitUnwrapper();
|
BukkitUnwrapper unwrapper = new BukkitUnwrapper();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Object nsmWatcher = FieldUtils.readField(entityDataField, unwrapper.unwrapItem(entity), true);
|
Object nsmWatcher = FieldUtils.readField(ENTITY_DATA_FIELD, unwrapper.unwrapItem(entity), true);
|
||||||
|
|
||||||
if (nsmWatcher != null)
|
if (nsmWatcher != null)
|
||||||
return new WrappedDataWatcher(nsmWatcher);
|
return new WrappedDataWatcher(nsmWatcher);
|
||||||
@ -564,8 +551,8 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private static void initialize() throws FieldAccessException {
|
private static void initialize() throws FieldAccessException {
|
||||||
// This method should only be run once, even if an exception is thrown
|
// This method should only be run once, even if an exception is thrown
|
||||||
if (!hasInitialized)
|
if (!HAS_INITIALIZED)
|
||||||
hasInitialized = true;
|
HAS_INITIALIZED = true;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -575,27 +562,27 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
if (Modifier.isStatic(lookup.getModifiers())) {
|
if (Modifier.isStatic(lookup.getModifiers())) {
|
||||||
// This must be the type map
|
// This must be the type map
|
||||||
try {
|
try {
|
||||||
typeMap = (Map<Class<?>, Integer>) FieldUtils.readStaticField(lookup, true);
|
TYPE_MAP = (Map<Class<?>, Integer>) FieldUtils.readStaticField(lookup, true);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
throw new FieldAccessException("Cannot access type map field.", e);
|
throw new FieldAccessException("Cannot access type map field.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// If not, then we're probably dealing with the value map
|
// If not, then we're probably dealing with the value map
|
||||||
valueMapField = lookup;
|
VALUE_MAP_FIELD = lookup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
readWriteLockField = fuzzy.getFieldByType("readWriteLock", ReadWriteLock.class);
|
READ_WRITE_LOCK_FIELD = fuzzy.getFieldByType("readWriteLock", ReadWriteLock.class);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// It's not a big deal
|
// It's not a big deal
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for the entity field as well
|
// Check for the entity field as well
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
entityField = fuzzy.getFieldByType("entity", MinecraftReflection.getEntityClass());
|
ENTITY_FIELD = fuzzy.getFieldByType("entity", MinecraftReflection.getEntityClass());
|
||||||
entityField.setAccessible(true);
|
ENTITY_FIELD.setAccessible(true);
|
||||||
}
|
}
|
||||||
initializeMethods(fuzzy);
|
initializeMethods(fuzzy);
|
||||||
}
|
}
|
||||||
@ -606,9 +593,9 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
|
|
||||||
// Load the get-method
|
// Load the get-method
|
||||||
try {
|
try {
|
||||||
getKeyValueMethod = fuzzy.getMethodByParameters(
|
GET_KEY_VALUE_METHOD = fuzzy.getMethodByParameters(
|
||||||
"getWatchableObject", MinecraftReflection.getWatchableObjectClass(), new Class[] { int.class });
|
"getWatchableObject", MinecraftReflection.getWatchableObjectClass(), new Class[] { int.class });
|
||||||
getKeyValueMethod.setAccessible(true);
|
GET_KEY_VALUE_METHOD.setAccessible(true);
|
||||||
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
// Use the fallback method
|
// Use the fallback method
|
||||||
@ -616,18 +603,18 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
|
|
||||||
for (Method method : candidates) {
|
for (Method method : candidates) {
|
||||||
if (!method.getName().startsWith("watch")) {
|
if (!method.getName().startsWith("watch")) {
|
||||||
createKeyValueMethod = method;
|
CREATE_KEY_VALUE_METHOD = method;
|
||||||
} else {
|
} else {
|
||||||
updateKeyValueMethod = method;
|
UPDATE_KEY_VALUE_METHOD = method;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Did we succeed?
|
// Did we succeed?
|
||||||
if (updateKeyValueMethod == null || createKeyValueMethod == null) {
|
if (UPDATE_KEY_VALUE_METHOD == null || CREATE_KEY_VALUE_METHOD == null) {
|
||||||
// Go by index instead
|
// Go by index instead
|
||||||
if (candidates.size() > 1) {
|
if (candidates.size() > 1) {
|
||||||
createKeyValueMethod = candidates.get(0);
|
CREATE_KEY_VALUE_METHOD = candidates.get(0);
|
||||||
updateKeyValueMethod = candidates.get(1);
|
UPDATE_KEY_VALUE_METHOD = candidates.get(1);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Unable to find create and update watchable object. Update ProtocolLib.");
|
throw new IllegalStateException("Unable to find create and update watchable object. Update ProtocolLib.");
|
||||||
}
|
}
|
||||||
@ -643,8 +630,8 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Nope
|
// Nope
|
||||||
updateKeyValueMethod = candidates.get(0);
|
UPDATE_KEY_VALUE_METHOD = candidates.get(0);
|
||||||
createKeyValueMethod = candidates.get(1);
|
CREATE_KEY_VALUE_METHOD = candidates.get(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -709,7 +696,7 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
throw new IllegalStateException("This method is only supported on 1.7.2 and above.");
|
throw new IllegalStateException("This method is only supported on 1.7.2 and above.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return (Entity) MinecraftReflection.getBukkitEntity(entityField.get(handle));
|
return (Entity) MinecraftReflection.getBukkitEntity(ENTITY_FIELD.get(handle));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Unable to retrieve entity.", e);
|
throw new RuntimeException("Unable to retrieve entity.", e);
|
||||||
}
|
}
|
||||||
@ -726,7 +713,7 @@ public class WrappedDataWatcher implements Iterable<WrappedWatchableObject> {
|
|||||||
throw new IllegalStateException("This method is only supported on 1.7.2 and above.");
|
throw new IllegalStateException("This method is only supported on 1.7.2 and above.");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
entityField.set(handle, BukkitUnwrapper.getInstance().unwrapItem(entity));
|
ENTITY_FIELD.set(handle, BukkitUnwrapper.getInstance().unwrapItem(entity));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Unable to set entity.", e);
|
throw new RuntimeException("Unable to set entity.", e);
|
||||||
}
|
}
|
||||||
|
@ -6,16 +6,11 @@ import net.minecraft.util.com.mojang.authlib.GameProfile;
|
|||||||
* Represents a wrapper for a game profile.
|
* Represents a wrapper for a game profile.
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class WrappedGameProfile {
|
public class WrappedGameProfile extends AbstractWrapper {
|
||||||
private GameProfile profile;
|
|
||||||
|
|
||||||
// Profile from a handle
|
// Profile from a handle
|
||||||
private WrappedGameProfile(Object profile) {
|
private WrappedGameProfile(Object profile) {
|
||||||
if (profile == null)
|
super(GameProfile.class);
|
||||||
throw new IllegalArgumentException("Profile cannot be NULL.");
|
setHandle(profile);
|
||||||
if (!(profile instanceof GameProfile))
|
|
||||||
throw new IllegalArgumentException(profile + " is not a GameProfile");
|
|
||||||
this.profile = (GameProfile) profile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,20 +30,12 @@ public class WrappedGameProfile {
|
|||||||
return new WrappedGameProfile(handle);
|
return new WrappedGameProfile(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the underlying game profile.
|
|
||||||
* @return The profile.
|
|
||||||
*/
|
|
||||||
public Object getHandle() {
|
|
||||||
return profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the UUID of the player.
|
* Retrieve the UUID of the player.
|
||||||
* @return The UUID of the player, or NULL if not computed.
|
* @return The UUID of the player, or NULL if not computed.
|
||||||
*/
|
*/
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return profile.getId();
|
return getProfile().getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,7 +43,11 @@ public class WrappedGameProfile {
|
|||||||
* @return The player name.
|
* @return The player name.
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return profile.getName();
|
return getProfile().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
private GameProfile getProfile() {
|
||||||
|
return (GameProfile) handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,12 +73,12 @@ public class WrappedGameProfile {
|
|||||||
* @return TRUE if it does, FALSE otherwise.
|
* @return TRUE if it does, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isComplete() {
|
public boolean isComplete() {
|
||||||
return profile.isComplete();
|
return getProfile().isComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return profile.hashCode();
|
return getProfile().hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -97,7 +88,7 @@ public class WrappedGameProfile {
|
|||||||
|
|
||||||
if (obj instanceof WrappedGameProfile) {
|
if (obj instanceof WrappedGameProfile) {
|
||||||
WrappedGameProfile other = (WrappedGameProfile) obj;
|
WrappedGameProfile other = (WrappedGameProfile) obj;
|
||||||
return profile.equals(other.profile);
|
return getProfile().equals(other.getProfile());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -15,21 +15,18 @@ import com.google.common.base.Preconditions;
|
|||||||
* Represents a wrapper for the internal IntHashMap in Minecraft.
|
* Represents a wrapper for the internal IntHashMap in Minecraft.
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class WrappedIntHashMap {
|
public class WrappedIntHashMap extends AbstractWrapper {
|
||||||
private static final Class<?> INT_HASH_MAP = MinecraftReflection.getIntHashMapClass();
|
|
||||||
|
|
||||||
private static Method PUT_METHOD;
|
private static Method PUT_METHOD;
|
||||||
private static Method GET_METHOD;
|
private static Method GET_METHOD;
|
||||||
private static Method REMOVE_METHOD;
|
private static Method REMOVE_METHOD;
|
||||||
|
|
||||||
private Object handle;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct an IntHashMap wrapper around an instance.
|
* Construct an IntHashMap wrapper around an instance.
|
||||||
* @param handle - the NMS instance.
|
* @param handle - the NMS instance.
|
||||||
*/
|
*/
|
||||||
private WrappedIntHashMap(Object handle) {
|
private WrappedIntHashMap(Object handle) {
|
||||||
this.handle = handle;
|
super(MinecraftReflection.getIntHashMapClass());
|
||||||
|
setHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,7 +35,7 @@ public class WrappedIntHashMap {
|
|||||||
*/
|
*/
|
||||||
public static WrappedIntHashMap newMap() {
|
public static WrappedIntHashMap newMap() {
|
||||||
try {
|
try {
|
||||||
return new WrappedIntHashMap(INT_HASH_MAP.newInstance());
|
return new WrappedIntHashMap(MinecraftReflection.getIntHashMapClass().newInstance());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Unable to construct IntHashMap.", e);
|
throw new RuntimeException("Unable to construct IntHashMap.", e);
|
||||||
}
|
}
|
||||||
@ -51,10 +48,6 @@ public class WrappedIntHashMap {
|
|||||||
* @throws IllegalArgumentException If the handle is not an IntHasMap.
|
* @throws IllegalArgumentException If the handle is not an IntHasMap.
|
||||||
*/
|
*/
|
||||||
public static WrappedIntHashMap fromHandle(@Nonnull Object handle) {
|
public static WrappedIntHashMap fromHandle(@Nonnull Object handle) {
|
||||||
Preconditions.checkNotNull(handle, "handle cannot be NULL");
|
|
||||||
Preconditions.checkState(MinecraftReflection.isIntHashMap(handle),
|
|
||||||
"handle is a " + handle.getClass() + ", not an IntHashMap.");
|
|
||||||
|
|
||||||
return new WrappedIntHashMap(handle);
|
return new WrappedIntHashMap(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +131,7 @@ public class WrappedIntHashMap {
|
|||||||
private void initializePutMethod() {
|
private void initializePutMethod() {
|
||||||
if (PUT_METHOD == null) {
|
if (PUT_METHOD == null) {
|
||||||
// Fairly straight forward
|
// Fairly straight forward
|
||||||
PUT_METHOD = FuzzyReflection.fromClass(INT_HASH_MAP).getMethod(
|
PUT_METHOD = FuzzyReflection.fromClass(MinecraftReflection.getIntHashMapClass()).getMethod(
|
||||||
FuzzyMethodContract.newBuilder().
|
FuzzyMethodContract.newBuilder().
|
||||||
banModifier(Modifier.STATIC).
|
banModifier(Modifier.STATIC).
|
||||||
parameterCount(2).
|
parameterCount(2).
|
||||||
@ -154,7 +147,7 @@ public class WrappedIntHashMap {
|
|||||||
String expected = "hello";
|
String expected = "hello";
|
||||||
|
|
||||||
// Determine which method to trust
|
// Determine which method to trust
|
||||||
for (Method method : FuzzyReflection.fromClass(INT_HASH_MAP).
|
for (Method method : FuzzyReflection.fromClass(MinecraftReflection.getIntHashMapClass()).
|
||||||
getMethodListByParameters(Object.class, new Class<?>[] { int.class })) {
|
getMethodListByParameters(Object.class, new Class<?>[] { int.class })) {
|
||||||
|
|
||||||
// Initialize a value
|
// Initialize a value
|
||||||
@ -183,12 +176,4 @@ public class WrappedIntHashMap {
|
|||||||
throw new IllegalStateException("Unable to find appropriate GET_METHOD for IntHashMap.");
|
throw new IllegalStateException("Unable to find appropriate GET_METHOD for IntHashMap.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the underlying IntHashMap object.
|
|
||||||
* @return The underlying object.
|
|
||||||
*/
|
|
||||||
public Object getHandle() {
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,7 @@ import com.google.common.base.Objects;
|
|||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class WrappedWatchableObject {
|
public class WrappedWatchableObject extends AbstractWrapper {
|
||||||
|
|
||||||
// Whether or not the reflection machinery has been initialized
|
// Whether or not the reflection machinery has been initialized
|
||||||
private static boolean hasInitialized;
|
private static boolean hasInitialized;
|
||||||
|
|
||||||
@ -47,7 +46,6 @@ public class WrappedWatchableObject {
|
|||||||
// The watchable object class type
|
// The watchable object class type
|
||||||
private static Class<?> watchableObjectClass;
|
private static Class<?> watchableObjectClass;
|
||||||
|
|
||||||
protected Object handle;
|
|
||||||
protected StructureModifier<Object> modifier;
|
protected StructureModifier<Object> modifier;
|
||||||
|
|
||||||
// Type of the stored value
|
// Type of the stored value
|
||||||
@ -58,6 +56,7 @@ public class WrappedWatchableObject {
|
|||||||
* @param handle - the raw watchable object to wrap.
|
* @param handle - the raw watchable object to wrap.
|
||||||
*/
|
*/
|
||||||
public WrappedWatchableObject(Object handle) {
|
public WrappedWatchableObject(Object handle) {
|
||||||
|
super(MinecraftReflection.getWatchableObjectClass());
|
||||||
load(handle);
|
load(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +66,8 @@ public class WrappedWatchableObject {
|
|||||||
* @param value - non-null value of specific types.
|
* @param value - non-null value of specific types.
|
||||||
*/
|
*/
|
||||||
public WrappedWatchableObject(int index, Object value) {
|
public WrappedWatchableObject(int index, Object value) {
|
||||||
|
super(MinecraftReflection.getWatchableObjectClass());
|
||||||
|
|
||||||
if (value == null)
|
if (value == null)
|
||||||
throw new IllegalArgumentException("Value cannot be NULL.");
|
throw new IllegalArgumentException("Value cannot be NULL.");
|
||||||
|
|
||||||
@ -107,14 +108,6 @@ public class WrappedWatchableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the underlying watchable object.
|
|
||||||
* @return The underlying watchable object.
|
|
||||||
*/
|
|
||||||
public Object getHandle() {
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize reflection machinery.
|
* Initialize reflection machinery.
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.comphenix.protocol.wrappers;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.BukkitInitialization;
|
||||||
|
|
||||||
|
public class WrappedChunkCoordinateTest {
|
||||||
|
@BeforeClass
|
||||||
|
public static void initializeBukkit() throws IllegalAccessException {
|
||||||
|
BukkitInitialization.initializePackage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
WrappedChunkCoordinate coordinate = new WrappedChunkCoordinate(1, 2, 3);
|
||||||
|
|
||||||
|
assertEquals(1, coordinate.getX());
|
||||||
|
assertEquals(2, coordinate.getY());
|
||||||
|
assertEquals(3, coordinate.getZ());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.comphenix.protocol.wrappers;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.BukkitInitialization;
|
||||||
|
|
||||||
|
public class WrappedIntHashMapTest {
|
||||||
|
@BeforeClass
|
||||||
|
public static void initializeBukkit() throws IllegalAccessException {
|
||||||
|
BukkitInitialization.initializePackage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIntMap() {
|
||||||
|
WrappedIntHashMap test = WrappedIntHashMap.newMap();
|
||||||
|
test.put(1, "hello");
|
||||||
|
|
||||||
|
assertNull(test.get(0));
|
||||||
|
assertEquals(test.get(1), "hello");
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren