161 lines
5.7 KiB
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() + "]";
|
|
}
|
|
}
|