Added factory method for initializing WrappedDataValue (#2523)

This commit is contained in:
Lukas Alt 2023-08-26 22:49:11 +02:00 committed by GitHub
parent 9e9b39a37d
commit 8fc5e509ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 13 deletions

View File

@ -1,10 +1,5 @@
package com.comphenix.protocol.events; package com.comphenix.protocol.events;
import javax.annotation.Nonnull;
import java.lang.reflect.Array;
import java.time.Instant;
import java.util.*;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
@ -17,7 +12,6 @@ import com.comphenix.protocol.wrappers.nbt.NbtBase;
import com.comphenix.protocol.wrappers.nbt.NbtCompound; import com.comphenix.protocol.wrappers.nbt.NbtCompound;
import com.comphenix.protocol.wrappers.nbt.NbtFactory; import com.comphenix.protocol.wrappers.nbt.NbtFactory;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -31,6 +25,11 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.lang.reflect.Array;
import java.time.Instant;
import java.util.*;
public abstract class AbstractStructure { public abstract class AbstractStructure {
protected transient Object handle; protected transient Object handle;
protected transient StructureModifier<Object> structureModifier; protected transient StructureModifier<Object> structureModifier;
@ -410,7 +409,7 @@ public abstract class AbstractStructure {
} }
/** /**
* Retrieves a read/write structure for collections of watchable objects. * Retrieves a read/write structure for collections of watchable objects before Minecraft 1.19.3.
* <p> * <p>
* This modifier will automatically marshal between the visible WrappedWatchableObject and the * This modifier will automatically marshal between the visible WrappedWatchableObject and the
* internal Minecraft WatchableObject. * internal Minecraft WatchableObject.
@ -424,7 +423,7 @@ public abstract class AbstractStructure {
} }
/** /**
* Retrieves a read/write structure for collections of data values. * Retrieves a read/write structure for collections of data values for Minecraft 1.19.3 or later.
* @return A modifier for data values. * @return A modifier for data values.
*/ */
public StructureModifier<List<WrappedDataValue>> getDataValueCollectionModifier() { public StructureModifier<List<WrappedDataValue>> getDataValueCollectionModifier() {

View File

@ -9,6 +9,7 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
/** /**
* Represents a DataValue in 1.19.3+. * Represents a DataValue in 1.19.3+.
* Use {@link WrappedWatchableObject} before 1.19.3.
*/ */
public class WrappedDataValue extends AbstractWrapper { public class WrappedDataValue extends AbstractWrapper {
@ -29,10 +30,28 @@ public class WrappedDataValue extends AbstractWrapper {
this.modifier = new StructureModifier<>(this.handleType).withTarget(handle); this.modifier = new StructureModifier<>(this.handleType).withTarget(handle);
} }
/**
* Creates a new WrappedDataValue from a NMS value.
* ProtocolLib wrappers are not supported as arguments.
* If implicit unwrapping of wrappers is required, use {@link WrappedDataValue#fromWrappedValue(int, Serializer, Object)}.
* @param index the index of the metadata value
* @param serializer the serializer corresponding for serializing. Can be null.
* @param value The raw value for the DataValue. Can be null.
*/
public WrappedDataValue(int index, Serializer serializer, Object value) { public WrappedDataValue(int index, Serializer serializer, Object value) {
this(newHandle(index, serializer, value)); this(newHandle(index, serializer, value));
} }
/**
* Creates a new WrappedDataValue from a possibly wrapped value and implicitly unwrap value if possible.
* @param index the index of the metadata value
* @param serializer the serializer corresponding for serializing. Can be null.
* @param value The value for the DataValue. Can be null.
*/
public static WrappedDataValue fromWrappedValue(int index, Serializer serializer, Object value) {
return new WrappedDataValue(index, serializer, value == null ? null : WrappedWatchableObject.getUnwrapped(value));
}
private static Object newHandle(int index, Serializer serializer, Object value) { private static Object newHandle(int index, Serializer serializer, Object value) {
if (constructor == null) { if (constructor == null) {
constructor = Accessors.getConstructorAccessor(HANDLE_TYPE.getConstructors()[0]); constructor = Accessors.getConstructorAccessor(HANDLE_TYPE.getConstructors()[0]);
@ -41,14 +60,26 @@ public class WrappedDataValue extends AbstractWrapper {
return constructor.invoke(index, serializer.getHandle(), value); return constructor.invoke(index, serializer.getHandle(), value);
} }
/**
* Returns the entity-type specific index of this DataValue
* @return index of the DataValue
*/
public int getIndex() { public int getIndex() {
return this.modifier.<Integer>withType(int.class).read(0); return this.modifier.<Integer>withType(int.class).read(0);
} }
/**
* Sets the entity-type specific index of this DataValue
* @param index New index of the DataValue
*/
public void setIndex(int index) { public void setIndex(int index) {
this.modifier.withType(int.class).write(0, index); this.modifier.withType(int.class).write(0, index);
} }
/**
* Returns the current serializer for this DataValue.
* @return serializer
*/
public Serializer getSerializer() { public Serializer getSerializer() {
Object serializer = this.modifier.readSafely(1); Object serializer = this.modifier.readSafely(1);
if (serializer != null) { if (serializer != null) {
@ -63,22 +94,42 @@ public class WrappedDataValue extends AbstractWrapper {
} }
} }
/**
* Changes the serializer for this DataValue
* @param serializer serializer
*/
public void setSerializer(Serializer serializer) { public void setSerializer(Serializer serializer) {
this.modifier.writeSafely(1, serializer == null ? null : serializer.getHandle()); this.modifier.writeSafely(1, serializer == null ? null : serializer.getHandle());
} }
/**
* Returns the current value associated and implicitly wraps it to corresponding ProtocolLib wrappers if possible.
* @return Current value
*/
public Object getValue() { public Object getValue() {
return WrappedWatchableObject.getWrapped(getRawValue()); return WrappedWatchableObject.getWrapped(getRawValue());
} }
/**
* Sets the current value associated and implicitly unwraps it to NMS types if a ProtocolLib wrapper is provided.
* @param value New value for this DataValue
*/
public void setValue(Object value) { public void setValue(Object value) {
setRawValue(WrappedWatchableObject.getUnwrapped(value)); setRawValue(WrappedWatchableObject.getUnwrapped(value));
} }
/**
* Returns the current, raw value.
* @return Raw value (not wrapped)
*/
public Object getRawValue() { public Object getRawValue() {
return this.modifier.readSafely(2); return this.modifier.readSafely(2);
} }
/**
* Updates the raw value for this DataValue. No unwrapping will be applied.
* @param value NMS value
*/
public void setRawValue(Object value) { public void setRawValue(Object value) {
this.modifier.writeSafely(2, value); this.modifier.writeSafely(2, value);
} }

View File

@ -14,8 +14,6 @@
*/ */
package com.comphenix.protocol.wrappers; package com.comphenix.protocol.wrappers;
import static com.comphenix.protocol.utility.MinecraftReflection.is;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor; import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
@ -25,12 +23,15 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject; import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
import com.comphenix.protocol.wrappers.nbt.NbtCompound; import com.comphenix.protocol.wrappers.nbt.NbtCompound;
import com.comphenix.protocol.wrappers.nbt.NbtFactory; import com.comphenix.protocol.wrappers.nbt.NbtFactory;
import java.util.Optional;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.Optional;
import static com.comphenix.protocol.utility.MinecraftReflection.is;
/** /**
* Represents a DataWatcher Item in 1.8 to 1.10. * Represents a DataWatcher Item in 1.8 to 1.19.2.
* * Use {@link WrappedDataValue} for 1.19.3 or later.
* @author dmulloy2 * @author dmulloy2
*/ */
public class WrappedWatchableObject extends AbstractWrapper { public class WrappedWatchableObject extends AbstractWrapper {
@ -97,6 +98,9 @@ public class WrappedWatchableObject extends AbstractWrapper {
* @return The wrapped object. * @return The wrapped object.
*/ */
static Object getWrapped(Object value) { static Object getWrapped(Object value) {
if(value == null) {
return null;
}
// Handle watcher items first // Handle watcher items first
if (is(MinecraftReflection.getDataWatcherItemClass(), value)) { if (is(MinecraftReflection.getDataWatcherItemClass(), value)) {
return getWrapped(new WrappedWatchableObject(value).getRawValue()); return getWrapped(new WrappedWatchableObject(value).getRawValue());
@ -135,6 +139,9 @@ public class WrappedWatchableObject extends AbstractWrapper {
*/ */
// Must be kept in sync with getWrapped! // Must be kept in sync with getWrapped!
static Object getUnwrapped(Object wrapped) { static Object getUnwrapped(Object wrapped) {
if(wrapped == null) {
return null;
}
if (wrapped instanceof Optional<?>) { if (wrapped instanceof Optional<?>) {
return ((Optional<?>) wrapped).map(WrappedWatchableObject::getUnwrapped); return ((Optional<?>) wrapped).map(WrappedWatchableObject::getUnwrapped);
} }