ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedSignedProperty.java

161 lines
5.7 KiB
Java

package com.comphenix.protocol.wrappers;
import java.security.PublicKey;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.google.common.base.Objects;
/**
* Represents a wrapper over a signed property.
* @author Kristian
*/
public class WrappedSignedProperty extends AbstractWrapper {
private static final String CLASS_NAME = "com.mojang.authlib.properties.Property";
private static final String UTIL_PACKAGE = "net.minecraft.util.";
private static Class<?> PROPERTY;
private static ConstructorAccessor CONSTRUCTOR;
private static MethodAccessor GET_NAME;
private static MethodAccessor GET_SIGNATURE;
private static MethodAccessor GET_VALUE;
private static MethodAccessor HAS_SIGNATURE;
private static MethodAccessor IS_SIGNATURE_VALID;
static {
try {
PROPERTY = Class.forName(CLASS_NAME);
} catch (ClassNotFoundException ex) {
try {
PROPERTY = Class.forName(UTIL_PACKAGE + CLASS_NAME);
} catch (ClassNotFoundException ex1) {
throw new RuntimeException("Failed to obtain Property class.", ex1);
}
}
try {
CONSTRUCTOR = Accessors.getConstructorAccessor(PROPERTY, String.class, String.class, String.class);
HAS_SIGNATURE = Accessors.getMethodAccessor(PROPERTY, "hasSignature");
IS_SIGNATURE_VALID = Accessors.getMethodAccessor(PROPERTY, "isSignatureValid", PublicKey.class);
if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) {
GET_NAME = Accessors.getMethodAccessorOrNull(PROPERTY, "name");
GET_SIGNATURE = Accessors.getMethodAccessor(PROPERTY, "signature");
GET_VALUE = Accessors.getMethodAccessor(PROPERTY, "value");
} else {
GET_NAME = Accessors.getMethodAccessorOrNull(PROPERTY, "getName");
GET_SIGNATURE = Accessors.getMethodAccessor(PROPERTY, "getSignature");
GET_VALUE = Accessors.getMethodAccessor(PROPERTY, "getValue");
}
} catch (Throwable ex) {
throw new RuntimeException("Failed to obtain methods for Property.", ex);
}
}
/**
* Construct a new wrapped signed property from the given values.
* @param name - the name of the property.
* @param value - the value of the property.
* @param signature - the BASE64-encoded signature of the value.
*/
public WrappedSignedProperty(String name, String value, String signature) {
this(CONSTRUCTOR.invoke(name, value, signature));
}
/**
* Construct a new wrapped signed property from a given handle.
* @param handle - the handle.
*/
private WrappedSignedProperty(Object handle) {
super(PROPERTY);
setHandle(handle);
}
/**
* Construct a new signed property from a given NMS property.
* @param handle - the property.
* @return The wrapped signed property.
*/
public static WrappedSignedProperty fromHandle(Object handle) {
return new WrappedSignedProperty(handle);
}
/**
* Construct a new wrapped signed property from the given values.
* @param name - the name of the property.
* @param value - the value of the property.
* @param signature - the BASE64-encoded signature of the value.
* @return The signed property.
*/
public static WrappedSignedProperty fromValues(String name, String value, String signature) {
return new WrappedSignedProperty(name, value, signature);
}
/**
* Retrieve the name of the underlying property, such as "textures".
* @return Name of the property.
*/
public String getName() {
return (String) GET_NAME.invoke(handle);
}
/**
* Retrieve the signature of the property (base64) as returned by the session server's /hasJoined.
* @return The signature of the property.
*/
public String getSignature() {
return (String) GET_SIGNATURE.invoke(handle);
}
/**
* Retrieve the value of the property (base64) as return by the session server's /hasJoined
* @return The value of the property.
*/
public String getValue() {
return (String) GET_VALUE.invoke(handle);
}
/**
* Determine if this property has a signature.
* @return TRUE if it does, FALSE otherwise.
*/
public boolean hasSignature() {
return (Boolean) HAS_SIGNATURE.invoke(handle);
}
/**
* Determine if the signature of this property is valid and signed by the corresponding private key.
* @param key - the public key.
* @return TRUE if it is, FALSE otherwise.
*/
public boolean isSignatureValid(PublicKey key) {
return (Boolean) IS_SIGNATURE_VALID.invoke(handle, key);
}
@Override
public int hashCode() {
return Objects.hashCode(getName(), getValue(), getSignature());
}
@Override
public boolean equals(Object object) {
if (object == this) return true;
if (object instanceof WrappedSignedProperty) {
WrappedSignedProperty that = (WrappedSignedProperty) object;
return Objects.equal(this.getName(), that.getName())
&& Objects.equal(this.getValue(), that.getValue())
&& Objects.equal(this.getSignature(), that.getSignature());
}
return false;
}
@Override
public String toString() {
return "WrappedSignedProperty[name=" + getName() + ", value=" + getValue() + ", signature=" + getSignature() + "]";
}
}