3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-11-08 17:20:24 +01:00

Make metadata (almost) fail-safe

This could mean life and death, see
`new Metadata(17, MetaType1_14.Float, event.meta()).value()`
vs.
`new Metadata(17, MetaType1_14.Float, event.meta().value())`
Dieser Commit ist enthalten in:
KennyTV 2021-05-25 16:27:46 +02:00
Ursprung a6b4b16fd3
Commit 57769c5671
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 6BE3B555EBC5982B
3 geänderte Dateien mit 45 neuen und 10 gelöschten Zeilen

Datei anzeigen

@ -22,6 +22,9 @@
*/ */
package com.viaversion.viaversion.api.minecraft.metadata; package com.viaversion.viaversion.api.minecraft.metadata;
import com.google.common.base.Preconditions;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Objects; import java.util.Objects;
public final class Metadata { public final class Metadata {
@ -29,10 +32,20 @@ public final class Metadata {
private MetaType metaType; private MetaType metaType;
private Object value; private Object value;
public Metadata(int id, MetaType metaType, Object value) { /**
* Creates a new metadata instance.
*
* @param id metadata index
* @param metaType metadata type
* @param value value if present
* @throws NullPointerException if the given metaType is null
* @throws IllegalArgumentException if the value and metaType are incompatible
*/
public Metadata(int id, MetaType metaType, @Nullable Object value) {
Preconditions.checkNotNull(metaType);
this.id = id; this.id = id;
this.metaType = metaType; this.metaType = metaType;
this.value = value; this.value = checkValue(value);
} }
public int id() { public int id() {
@ -47,7 +60,14 @@ public final class Metadata {
return metaType; return metaType;
} }
/**
* Sets the metadata type.
* Update the value with {@link #setValue(Object)} in case value and type are no longer compatible.
*
* @param metaType metadata type
*/
public void setMetaType(MetaType metaType) { public void setMetaType(MetaType metaType) {
Preconditions.checkNotNull(metaType);
this.metaType = metaType; this.metaType = metaType;
} }
@ -55,12 +75,26 @@ public final class Metadata {
return (T) value; return (T) value;
} }
public Object getValue() { public @Nullable Object getValue() {
return value; return value;
} }
public void setValue(Object value) { /**
this.value = value; * Sets the metadata value.
* Always call {@link #setMetaType(MetaType)} first if the output type changes.
*
* @param value value
* @throws IllegalArgumentException if the value and metaType are incompatible
*/
public void setValue(@Nullable Object value) {
this.value = checkValue(value);
}
private Object checkValue(Object value) {
if (value != null && !metaType.type().getOutputClass().isAssignableFrom(value.getClass())) {
throw new IllegalArgumentException("Metadata value and metaType are incompatible. Type=" + metaType + ", value=" + value);
}
return value;
} }
@Override @Override

Datei anzeigen

@ -46,7 +46,7 @@ public abstract class AbstractProtocol<C1 extends ClientboundPacketType, C2 exte
implements Protocol<C1, C2, S1, S2> { implements Protocol<C1, C2, S1, S2> {
private final Map<Packet, ProtocolPacket> serverbound = new HashMap<>(); private final Map<Packet, ProtocolPacket> serverbound = new HashMap<>();
private final Map<Packet, ProtocolPacket> clientbound = new HashMap<>(); private final Map<Packet, ProtocolPacket> clientbound = new HashMap<>();
private final Map<Class, Object> storedObjects = new HashMap<>(); // currently only used for MetadataRewriters private final Map<Class<?>, Object> storedObjects = new HashMap<>(); // currently only used for MetadataRewriters
protected final Class<C1> oldClientboundPacketEnum; protected final Class<C1> oldClientboundPacketEnum;
protected final Class<C2> newClientboundPacketEnum; protected final Class<C2> newClientboundPacketEnum;
protected final Class<S1> oldServerboundPacketEnum; protected final Class<S1> oldServerboundPacketEnum;

Datei anzeigen

@ -139,14 +139,14 @@ public class MetadataRewriter1_14To1_13_2 extends EntityRewriter<Protocol1_14To1
} else if (type.is(Entity1_14Types.VILLAGER)) { } else if (type.is(Entity1_14Types.VILLAGER)) {
if (metadata.id() == 15) { if (metadata.id() == 15) {
// plains // plains
metadata.setValue(new VillagerData(2, getNewProfessionId((int) metadata.getValue()), 0));
metadata.setMetaType(MetaType1_14.VillagerData); metadata.setMetaType(MetaType1_14.VillagerData);
metadata.setValue(new VillagerData(2, getNewProfessionId((int) metadata.getValue()), 0));
} }
} else if (type.is(Entity1_14Types.ZOMBIE_VILLAGER)) { } else if (type.is(Entity1_14Types.ZOMBIE_VILLAGER)) {
if (metadata.id() == 18) { if (metadata.id() == 18) {
// plains // plains
metadata.setValue(new VillagerData(2, getNewProfessionId((int) metadata.getValue()), 0));
metadata.setMetaType(MetaType1_14.VillagerData); metadata.setMetaType(MetaType1_14.VillagerData);
metadata.setValue(new VillagerData(2, getNewProfessionId((int) metadata.getValue()), 0));
} }
} else if (type.isOrHasParent(Entity1_14Types.ABSTRACT_ARROW)) { } else if (type.isOrHasParent(Entity1_14Types.ABSTRACT_ARROW)) {
if (metadata.id() >= 9) { // New piercing if (metadata.id() >= 9) { // New piercing
@ -154,9 +154,10 @@ public class MetadataRewriter1_14To1_13_2 extends EntityRewriter<Protocol1_14To1
} }
} else if (type.is(Entity1_14Types.FIREWORK_ROCKET)) { } else if (type.is(Entity1_14Types.FIREWORK_ROCKET)) {
if (metadata.id() == 8) { if (metadata.id() == 8) {
if (metadata.getValue().equals(0))
metadata.setValue(null); // https://bugs.mojang.com/browse/MC-111480
metadata.setMetaType(MetaType1_14.OptVarInt); metadata.setMetaType(MetaType1_14.OptVarInt);
if (metadata.getValue().equals(0)) {
metadata.setValue(null); // https://bugs.mojang.com/browse/MC-111480
}
} }
} else if (type.isOrHasParent(Entity1_14Types.ABSTRACT_SKELETON)) { } else if (type.isOrHasParent(Entity1_14Types.ABSTRACT_SKELETON)) {
if (metadata.id() == 14) { if (metadata.id() == 14) {