24w10a, more item component work

This commit is contained in:
Nassim Jahnke 2024-03-06 16:53:37 +01:00
parent 73178b504e
commit b4ee564aa2
No known key found for this signature in database
GPG Key ID: EF6771C01F6EF02F
20 changed files with 281 additions and 83 deletions

View File

@ -31,13 +31,13 @@ public final class GameProfile {
private final UUID id; private final UUID id;
private final Property[] properties; private final Property[] properties;
public GameProfile(final String name, @Nullable final UUID id, final Property[] properties) { public GameProfile(@Nullable final String name, @Nullable final UUID id, final Property[] properties) {
this.name = name; this.name = name;
this.id = id; this.id = id;
this.properties = properties; this.properties = properties;
} }
public String name() { public @Nullable String name() {
return name; return name;
} }

View File

@ -67,4 +67,28 @@ final class EmptyStructuredData<T> implements StructuredData<T> {
public int id() { public int id() {
return this.id; return this.id;
} }
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final EmptyStructuredData<?> that = (EmptyStructuredData<?>) o;
if (id != that.id) return false;
return key.equals(that.key);
}
@Override
public int hashCode() {
int result = key.hashCode();
result = 31 * result + id;
return result;
}
@Override
public String toString() {
return "EmptyStructuredData{" +
"key=" + key +
", id=" + id +
'}';
}
} }

View File

@ -24,6 +24,7 @@ package com.viaversion.viaversion.api.minecraft.data;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import java.util.Objects;
final class FilledStructuredData<T> implements StructuredData<T> { final class FilledStructuredData<T> implements StructuredData<T> {
@ -72,4 +73,31 @@ final class FilledStructuredData<T> implements StructuredData<T> {
public int id() { public int id() {
return id; return id;
} }
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final FilledStructuredData<?> that = (FilledStructuredData<?>) o;
if (id != that.id) return false;
if (!key.equals(that.key)) return false;
return Objects.equals(value, that.value);
}
@Override
public int hashCode() {
int result = key.hashCode();
result = 31 * result + (value != null ? value.hashCode() : 0);
result = 31 * result + id;
return result;
}
@Override
public String toString() {
return "FilledStructuredData{" +
"key=" + key +
", value=" + value +
", id=" + id +
'}';
}
} }

View File

@ -25,6 +25,7 @@ package com.viaversion.viaversion.api.minecraft.data;
import com.viaversion.viaversion.api.Via; import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.FullMappings; import com.viaversion.viaversion.api.data.FullMappings;
import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.Unit;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import java.util.Map; import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -68,13 +69,17 @@ public final class StructuredDataContainer {
return data != null && data.isPresent() ? data : null; return data != null && data.isPresent() ? data : null;
} }
public <T> void add(final StructuredDataKey<T> key, final T value) { public <T> void set(final StructuredDataKey<T> key, final T value) {
final int id = serializerId(key); final int id = serializerId(key);
if (id != -1) { if (id != -1) {
this.data.put(key, StructuredData.of(key, value, id)); this.data.put(key, StructuredData.of(key, value, id));
} }
} }
public void set(final StructuredDataKey<Unit> key) {
this.set(key, Unit.INSTANCE);
}
public void addEmpty(final StructuredDataKey<?> key) { public void addEmpty(final StructuredDataKey<?> key) {
// Empty optional to override the Minecraft default // Empty optional to override the Minecraft default
this.data.put(key, StructuredData.empty(key, serializerId(key))); this.data.put(key, StructuredData.empty(key, serializerId(key)));

View File

@ -30,7 +30,7 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate; import com.viaversion.viaversion.api.minecraft.item.data.AdventureModePredicate;
import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim; import com.viaversion.viaversion.api.minecraft.item.data.ArmorTrim;
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers; import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers;
import com.viaversion.viaversion.api.minecraft.item.data.BannerPattern; import com.viaversion.viaversion.api.minecraft.item.data.BannerPatternLayer;
import com.viaversion.viaversion.api.minecraft.item.data.Bee; import com.viaversion.viaversion.api.minecraft.item.data.Bee;
import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties; import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties;
import com.viaversion.viaversion.api.minecraft.item.data.DyedColor; import com.viaversion.viaversion.api.minecraft.item.data.DyedColor;
@ -38,7 +38,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion; import com.viaversion.viaversion.api.minecraft.item.data.FireworkExplosion;
import com.viaversion.viaversion.api.minecraft.item.data.Fireworks; import com.viaversion.viaversion.api.minecraft.item.data.Fireworks;
import com.viaversion.viaversion.api.minecraft.item.data.Instrument; import com.viaversion.viaversion.api.minecraft.item.data.Instrument;
import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTarget; import com.viaversion.viaversion.api.minecraft.item.data.LodestoneTracker;
import com.viaversion.viaversion.api.minecraft.item.data.PotionContents; import com.viaversion.viaversion.api.minecraft.item.data.PotionContents;
import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect; import com.viaversion.viaversion.api.minecraft.item.data.SuspiciousStewEffect;
import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook; import com.viaversion.viaversion.api.minecraft.item.data.WrittenBook;
@ -82,12 +82,12 @@ public final class StructuredDataKey<T> {
public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Type.COMPOUND_TAG); public static final StructuredDataKey<CompoundTag> BLOCK_ENTITY_DATA = new StructuredDataKey<>("block_entity_data", Type.COMPOUND_TAG);
public static final StructuredDataKey<Holder<Instrument>> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE); public static final StructuredDataKey<Holder<Instrument>> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE);
public static final StructuredDataKey<String[]> RECIPES = new StructuredDataKey<>("recipes", Type.STRING_ARRAY); public static final StructuredDataKey<String[]> RECIPES = new StructuredDataKey<>("recipes", Type.STRING_ARRAY);
public static final StructuredDataKey<LodestoneTarget> LODESTONE_TARGET = new StructuredDataKey<>("lodestone_target", LodestoneTarget.TYPE); public static final StructuredDataKey<LodestoneTracker> LODESTONE_TRACKER = new StructuredDataKey<>("lodestone_tracker", LodestoneTracker.TYPE);
public static final StructuredDataKey<FireworkExplosion> FIREWORK_EXPLOSION = new StructuredDataKey<>("firework_explosion", FireworkExplosion.TYPE); public static final StructuredDataKey<FireworkExplosion> FIREWORK_EXPLOSION = new StructuredDataKey<>("firework_explosion", FireworkExplosion.TYPE);
public static final StructuredDataKey<Fireworks> FIREWORKS = new StructuredDataKey<>("fireworks", Fireworks.TYPE); public static final StructuredDataKey<Fireworks> FIREWORKS = new StructuredDataKey<>("fireworks", Fireworks.TYPE);
public static final StructuredDataKey<GameProfile> PROFILE = new StructuredDataKey<>("profile", Type.GAME_PROFILE); public static final StructuredDataKey<GameProfile> PROFILE = new StructuredDataKey<>("profile", Type.GAME_PROFILE);
public static final StructuredDataKey<String> NOTE_BLOCK_SOUND = new StructuredDataKey<>("note_block_sound", Type.STRING); public static final StructuredDataKey<String> NOTE_BLOCK_SOUND = new StructuredDataKey<>("note_block_sound", Type.STRING);
public static final StructuredDataKey<BannerPattern[]> BANNER_PATTERNS = new StructuredDataKey<>("banner_patterns", BannerPattern.ARRAY_TYPE); public static final StructuredDataKey<BannerPatternLayer[]> BANNER_PATTERNS = new StructuredDataKey<>("banner_patterns", BannerPatternLayer.ARRAY_TYPE);
public static final StructuredDataKey<Integer> BASE_COLOR = new StructuredDataKey<>("base_color", Type.VAR_INT); public static final StructuredDataKey<Integer> BASE_COLOR = new StructuredDataKey<>("base_color", Type.VAR_INT);
public static final StructuredDataKey<int[]> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", Type.VAR_INT_ARRAY_PRIMITIVE); public static final StructuredDataKey<int[]> POT_DECORATIONS = new StructuredDataKey<>("pot_decorations", Type.VAR_INT_ARRAY_PRIMITIVE);
public static final StructuredDataKey<Item[]> CONTAINER = new StructuredDataKey<>("container", Types1_20_5.ITEM_ARRAY); public static final StructuredDataKey<Item[]> CONTAINER = new StructuredDataKey<>("container", Types1_20_5.ITEM_ARRAY);

View File

@ -29,13 +29,13 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class StructuredItem implements Item { public class StructuredItem implements Item {
private final StructuredDataContainer data; private final StructuredDataContainer data;
private int identifier; private int identifier;
private byte amount; private int amount;
public StructuredItem() { public StructuredItem() {
this(0, (byte) 0, new StructuredDataContainer()); this(0, 0, new StructuredDataContainer());
} }
public StructuredItem(final int identifier, final byte amount, final StructuredDataContainer data) { public StructuredItem(final int identifier, final int amount, final StructuredDataContainer data) {
this.identifier = identifier; this.identifier = identifier;
this.amount = amount; this.amount = amount;
this.data = data; this.data = data;
@ -58,10 +58,7 @@ public class StructuredItem implements Item {
@Override @Override
public void setAmount(final int amount) { public void setAmount(final int amount) {
if (amount > Byte.MAX_VALUE || amount < Byte.MIN_VALUE) { this.amount = amount;
throw new IllegalArgumentException("Invalid item amount: " + amount);
}
this.amount = (byte) amount;
} }
@Override @Override

View File

@ -23,40 +23,39 @@
package com.viaversion.viaversion.api.minecraft.item.data; package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType; import com.viaversion.viaversion.api.type.types.misc.HolderType;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
public final class BannerPattern { public final class BannerPattern {
public static final Type<BannerPattern> TYPE = new Type<BannerPattern>(BannerPattern.class) { public static final HolderType<BannerPattern> TYPE = new HolderType<BannerPattern>() {
@Override @Override
public BannerPattern read(final ByteBuf buffer) throws Exception { public BannerPattern readDirect(final ByteBuf buffer) throws Exception {
final int pattern = Type.VAR_INT.readPrimitive(buffer); final String assetId = Type.STRING.read(buffer);
final int color = Type.VAR_INT.readPrimitive(buffer); final String tanslationKey = Type.STRING.read(buffer);
return new BannerPattern(pattern, color); return new BannerPattern(assetId, tanslationKey);
} }
@Override @Override
public void write(final ByteBuf buffer, final BannerPattern value) throws Exception { public void writeDirect(final ByteBuf buffer, final BannerPattern value) throws Exception {
Type.VAR_INT.writePrimitive(buffer, value.pattern); Type.STRING.write(buffer, value.assetId);
Type.VAR_INT.writePrimitive(buffer, value.color); Type.STRING.write(buffer, value.tanslationKey);
} }
}; };
public static final Type<BannerPattern[]> ARRAY_TYPE = new ArrayType<>(TYPE);
private final int pattern; private final String assetId;
private final int color; private final String tanslationKey;
public BannerPattern(final int pattern, final int color) { public BannerPattern(final String assetId, final String tanslationKey) {
this.pattern = pattern; this.assetId = assetId;
this.color = color; this.tanslationKey = tanslationKey;
} }
public int pattern() { public String assetId() {
return this.pattern; return assetId;
} }
public int color() { public String tanslationKey() {
return this.color; return tanslationKey;
} }
} }

View File

@ -0,0 +1,63 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.ArrayType;
import io.netty.buffer.ByteBuf;
public final class BannerPatternLayer {
public static final Type<BannerPatternLayer> TYPE = new Type<BannerPatternLayer>(BannerPatternLayer.class) {
@Override
public BannerPatternLayer read(final ByteBuf buffer) throws Exception {
final Holder<BannerPattern> pattern = BannerPattern.TYPE.read(buffer);
final DyedColor color = DyedColor.TYPE.read(buffer);
return new BannerPatternLayer(pattern, color);
}
@Override
public void write(final ByteBuf buffer, final BannerPatternLayer value) throws Exception {
BannerPattern.TYPE.write(buffer, value.pattern);
DyedColor.TYPE.write(buffer, value.color);
}
};
public static final Type<BannerPatternLayer[]> ARRAY_TYPE = new ArrayType<>(TYPE);
private final Holder<BannerPattern> pattern;
private final DyedColor color;
public BannerPatternLayer(final Holder<BannerPattern> pattern, final DyedColor color) {
this.pattern = pattern;
this.color = color;
}
public Holder<BannerPattern> pattern() {
return pattern;
}
public DyedColor color() {
return color;
}
}

View File

@ -25,20 +25,21 @@ package com.viaversion.viaversion.api.minecraft.item.data;
import com.viaversion.viaversion.api.minecraft.GlobalPosition; import com.viaversion.viaversion.api.minecraft.GlobalPosition;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class LodestoneTarget { public final class LodestoneTracker {
public static final Type<LodestoneTarget> TYPE = new Type<LodestoneTarget>(LodestoneTarget.class) { public static final Type<LodestoneTracker> TYPE = new Type<LodestoneTracker>(LodestoneTracker.class) {
@Override @Override
public LodestoneTarget read(final ByteBuf buffer) throws Exception { public LodestoneTracker read(final ByteBuf buffer) throws Exception {
final GlobalPosition position = Type.GLOBAL_POSITION.read(buffer); final GlobalPosition position = Type.OPTIONAL_GLOBAL_POSITION.read(buffer);
final boolean tracked = buffer.readBoolean(); final boolean tracked = buffer.readBoolean();
return new LodestoneTarget(position, tracked); return new LodestoneTracker(position, tracked);
} }
@Override @Override
public void write(final ByteBuf buffer, final LodestoneTarget value) throws Exception { public void write(final ByteBuf buffer, final LodestoneTracker value) throws Exception {
Type.GLOBAL_POSITION.write(buffer, value.position); Type.OPTIONAL_GLOBAL_POSITION.write(buffer, value.position);
buffer.writeBoolean(value.tracked); buffer.writeBoolean(value.tracked);
} }
}; };
@ -46,12 +47,12 @@ public final class LodestoneTarget {
private final GlobalPosition position; private final GlobalPosition position;
private final boolean tracked; private final boolean tracked;
public LodestoneTarget(final GlobalPosition position, final boolean tracked) { public LodestoneTracker(@Nullable final GlobalPosition position, final boolean tracked) {
this.position = position; this.position = position;
this.tracked = tracked; this.tracked = tracked;
} }
public GlobalPosition pos() { public @Nullable GlobalPosition pos() {
return this.position; return this.position;
} }

View File

@ -51,16 +51,17 @@ public final class MetaTypes1_20_5 extends AbstractMetaTypes {
public final MetaType optionalVarIntType = add(19, Type.OPTIONAL_VAR_INT); public final MetaType optionalVarIntType = add(19, Type.OPTIONAL_VAR_INT);
public final MetaType poseType = add(20, Type.VAR_INT); public final MetaType poseType = add(20, Type.VAR_INT);
public final MetaType catVariantType = add(21, Type.VAR_INT); public final MetaType catVariantType = add(21, Type.VAR_INT);
public final MetaType frogVariantType = add(22, Type.VAR_INT); public final MetaType wolfVariantType = add(22, Type.VAR_INT);
public final MetaType optionalGlobalPosition = add(23, Type.OPTIONAL_GLOBAL_POSITION); public final MetaType frogVariantType = add(23, Type.VAR_INT);
public final MetaType paintingVariantType = add(24, Type.VAR_INT); public final MetaType optionalGlobalPosition = add(24, Type.OPTIONAL_GLOBAL_POSITION);
public final MetaType snifferState = add(25, Type.VAR_INT); public final MetaType paintingVariantType = add(25, Type.VAR_INT);
public final MetaType armadilloState = add(26, Type.VAR_INT); public final MetaType snifferState = add(26, Type.VAR_INT);
public final MetaType vectorType = add(27, Type.VECTOR3F); public final MetaType armadilloState = add(27, Type.VAR_INT);
public final MetaType quaternionType = add(28, Type.QUATERNION); public final MetaType vectorType = add(28, Type.VECTOR3F);
public final MetaType quaternionType = add(29, Type.QUATERNION);
public MetaTypes1_20_5(final ParticleType particleType) { public MetaTypes1_20_5(final ParticleType particleType) {
super(29); super(30);
this.particleType = add(17, particleType); this.particleType = add(17, particleType);
} }
} }

View File

@ -83,7 +83,7 @@ public class ProtocolVersion implements Comparable<ProtocolVersion> {
public static final ProtocolVersion v1_20 = register(763, "1.20/1.20.1", new SubVersionRange("1.20", 0, 1)); public static final ProtocolVersion v1_20 = register(763, "1.20/1.20.1", new SubVersionRange("1.20", 0, 1));
public static final ProtocolVersion v1_20_2 = register(764, "1.20.2"); public static final ProtocolVersion v1_20_2 = register(764, "1.20.2");
public static final ProtocolVersion v1_20_3 = register(765, "1.20.3/1.20.4", new SubVersionRange("1.20", 3, 4)); public static final ProtocolVersion v1_20_3 = register(765, "1.20.3/1.20.4", new SubVersionRange("1.20", 3, 4));
public static final ProtocolVersion v1_20_5 = register(766, 178, "1.20.5"); public static final ProtocolVersion v1_20_5 = register(766, 179, "1.20.5");
public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null); public static final ProtocolVersion unknown = new ProtocolVersion(VersionType.SPECIAL, -1, -1, "UNKNOWN", null);
public static ProtocolVersion register(int version, String name) { public static ProtocolVersion register(int version, String name) {

View File

@ -45,7 +45,7 @@ public class ItemType1_20_5 extends Type<Item> {
@Override @Override
public @Nullable Item read(final ByteBuf buffer) throws Exception { public @Nullable Item read(final ByteBuf buffer) throws Exception {
final byte amount = buffer.readByte(); final int amount = Type.VAR_INT.readPrimitive(buffer);
if (amount <= 0) { if (amount <= 0) {
return null; return null;
} }
@ -82,11 +82,11 @@ public class ItemType1_20_5 extends Type<Item> {
@Override @Override
public void write(final ByteBuf buffer, @Nullable final Item object) throws Exception { public void write(final ByteBuf buffer, @Nullable final Item object) throws Exception {
if (object == null) { if (object == null) {
buffer.writeByte(0); Type.VAR_INT.writePrimitive(buffer, 0);
return; return;
} }
buffer.writeByte(object.amount()); Type.VAR_INT.writePrimitive(buffer, object.amount());
Type.VAR_INT.writePrimitive(buffer, object.identifier()); Type.VAR_INT.writePrimitive(buffer, object.identifier());
final Map<StructuredDataKey<?>, StructuredData<?>> data = object.structuredData().data(); final Map<StructuredDataKey<?>, StructuredData<?>> data = object.structuredData().data();

View File

@ -34,7 +34,7 @@ public final class GameProfileType extends Type<GameProfile> {
@Override @Override
public GameProfile read(final ByteBuf buffer) throws Exception { public GameProfile read(final ByteBuf buffer) throws Exception {
final String name = Type.STRING.read(buffer); final String name = Type.OPTIONAL_STRING.read(buffer);
final java.util.UUID id = Type.OPTIONAL_UUID.read(buffer); final java.util.UUID id = Type.OPTIONAL_UUID.read(buffer);
final int propertyCount = Type.VAR_INT.readPrimitive(buffer); final int propertyCount = Type.VAR_INT.readPrimitive(buffer);
final GameProfile.Property[] properties = new GameProfile.Property[propertyCount]; final GameProfile.Property[] properties = new GameProfile.Property[propertyCount];
@ -49,7 +49,7 @@ public final class GameProfileType extends Type<GameProfile> {
@Override @Override
public void write(final ByteBuf buffer, final GameProfile value) throws Exception { public void write(final ByteBuf buffer, final GameProfile value) throws Exception {
Type.STRING.write(buffer, value.name()); Type.OPTIONAL_STRING.write(buffer, value.name());
Type.OPTIONAL_UUID.write(buffer, value.id()); Type.OPTIONAL_UUID.write(buffer, value.id());
Type.VAR_INT.writePrimitive(buffer, value.properties().length); Type.VAR_INT.writePrimitive(buffer, value.properties().length);
for (final GameProfile.Property property : value.properties()) { for (final GameProfile.Property property : value.properties()) {

View File

@ -33,6 +33,7 @@ import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.data.entity.EntityTrackerBase; import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets; import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets; import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.CommandRewriter1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2; import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundConfigurationPackets1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundConfigurationPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3; import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3;
@ -90,6 +91,8 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
wrapper.read(Type.BOOLEAN); // Enforces secure chat - moved to join game wrapper.read(Type.BOOLEAN); // Enforces secure chat - moved to join game
}); });
new CommandRewriter1_19_4<>(this).registerDeclareCommands1_19(ClientboundPackets1_20_3.DECLARE_COMMANDS);
cancelServerbound(State.LOGIN, ServerboundLoginPackets.COOKIE_RESPONSE.getId()); cancelServerbound(State.LOGIN, ServerboundLoginPackets.COOKIE_RESPONSE.getId());
cancelServerbound(ServerboundConfigurationPackets1_20_5.COOKIE_RESPONSE); cancelServerbound(ServerboundConfigurationPackets1_20_5.COOKIE_RESPONSE);
cancelServerbound(ServerboundConfigurationPackets1_20_5.SELECT_KNOWN_PACKS); cancelServerbound(ServerboundConfigurationPackets1_20_5.SELECT_KNOWN_PACKS);
@ -147,7 +150,7 @@ public final class Protocol1_20_5To1_20_3 extends AbstractProtocol<ClientboundPa
.add(StructuredDataKey.BLOCK_ENTITY_DATA) .add(StructuredDataKey.BLOCK_ENTITY_DATA)
.add(StructuredDataKey.INSTRUMENT) .add(StructuredDataKey.INSTRUMENT)
.add(StructuredDataKey.RECIPES) .add(StructuredDataKey.RECIPES)
.add(StructuredDataKey.LODESTONE_TARGET) .add(StructuredDataKey.LODESTONE_TRACKER)
.add(StructuredDataKey.FIREWORK_EXPLOSION) .add(StructuredDataKey.FIREWORK_EXPLOSION)
.add(StructuredDataKey.FIREWORKS) .add(StructuredDataKey.FIREWORKS)
.add(StructuredDataKey.PROFILE) .add(StructuredDataKey.PROFILE)

View File

@ -33,6 +33,7 @@ import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item; import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.StructuredItem; import com.viaversion.viaversion.api.minecraft.item.StructuredItem;
import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties; import com.viaversion.viaversion.api.minecraft.item.data.BlockStateProperties;
import com.viaversion.viaversion.api.minecraft.item.data.DyedColor;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments; import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2; import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
@ -48,6 +49,7 @@ import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.Serverb
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPackets1_20_5; import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPackets1_20_5;
import com.viaversion.viaversion.rewriter.BlockRewriter; import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ItemRewriter; import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.UUIDUtil; import com.viaversion.viaversion.util.UUIDUtil;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
@ -192,17 +194,22 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
return toOldItem(item); return toOldItem(item);
} }
// TODO Block entity changes
public Item toOldItem(final Item item) { public Item toOldItem(final Item item) {
// Start out with custom data and add the rest on top // Start out with custom data and add the rest on top, or short-curcuit with the original item
final StructuredDataContainer data = item.structuredData(); final StructuredDataContainer data = item.structuredData();
data.setIdLookup(protocol, true); data.setIdLookup(protocol, true);
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA); final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
final CompoundTag tag = customData != null ? customData.value() : new CompoundTag(); final CompoundTag tag = customData != null ? customData.value() : new CompoundTag();
final DataItem dataItem = new DataItem(item.identifier(), (byte) item.amount(), (short) 0, tag);
if (customData != null && tag.remove(tagMarker) != null) {
return dataItem;
}
// TODO // TODO
return new DataItem(item.identifier(), (byte) item.amount(), (short) 0, tag); return dataItem;
} }
public Item toStructuredItem(final Item old) { public Item toStructuredItem(final Item old) {
@ -215,21 +222,27 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
} }
// Rewrite nbt to new data structures // Rewrite nbt to new data structures
updateDisplay(data, tag.getCompoundTag("display")); final NumberTag hideFlags = tag.getNumberTag("HideFlags");
final int hideFlagsValue = hideFlags != null ? hideFlags.asInt() : 0;
if ((hideFlagsValue & 0x20) != 0) {
data.set(StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP);
}
updateDisplay(data, tag.getCompoundTag("display"), hideFlagsValue);
final NumberTag damage = tag.getNumberTag("Damage"); final NumberTag damage = tag.getNumberTag("Damage");
if (damage != null && damage.asInt() != 0) { if (damage != null && damage.asInt() != 0) {
data.add(StructuredDataKey.DAMAGE, damage.asInt()); data.set(StructuredDataKey.DAMAGE, damage.asInt());
} }
final NumberTag repairCost = tag.getNumberTag("RepairCost"); final NumberTag repairCost = tag.getNumberTag("RepairCost");
if (repairCost != null && repairCost.asInt() != 0) { if (repairCost != null && repairCost.asInt() != 0) {
data.add(StructuredDataKey.REPAIR_COST, repairCost.asInt()); data.set(StructuredDataKey.REPAIR_COST, repairCost.asInt());
} }
final NumberTag customModelData = tag.getNumberTag("CustomModelData"); final NumberTag customModelData = tag.getNumberTag("CustomModelData");
if (customModelData != null) { if (customModelData != null) {
data.add(StructuredDataKey.CUSTOM_MODEL_DATA, customModelData.asInt()); data.set(StructuredDataKey.CUSTOM_MODEL_DATA, customModelData.asInt());
} }
final CompoundTag blockState = tag.getCompoundTag("BlockStateTag"); final CompoundTag blockState = tag.getCompoundTag("BlockStateTag");
@ -240,12 +253,13 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
properties.put(entry.getKey(), ((StringTag) entry.getValue()).getValue()); properties.put(entry.getKey(), ((StringTag) entry.getValue()).getValue());
} }
} }
data.add(StructuredDataKey.BLOCK_STATE, new BlockStateProperties(properties)); // TODO block state changes
data.set(StructuredDataKey.BLOCK_STATE, new BlockStateProperties(properties));
} }
final CompoundTag entityTag = tag.getCompoundTag("EntityTag"); final CompoundTag entityTag = tag.getCompoundTag("EntityTag");
if (entityTag != null) { if (entityTag != null) {
data.add(StructuredDataKey.ENTITY_DATA, entityTag); data.set(StructuredDataKey.ENTITY_DATA, entityTag);
} }
final CompoundTag blockEntityTag = tag.getCompoundTag("BlockEntityTag"); final CompoundTag blockEntityTag = tag.getCompoundTag("BlockEntityTag");
@ -254,24 +268,40 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
// item.structuredData().add(protocol, "block_entity_data", Type.COMPOUND_TAG, blockEntityTag); // item.structuredData().add(protocol, "block_entity_data", Type.COMPOUND_TAG, blockEntityTag);
} }
final NumberTag hideFlags = tag.getNumberTag("HideFlags");
final int hideFlagsValue = hideFlags != null ? hideFlags.asInt() : 0;
final NumberTag unbreakable = tag.getNumberTag("Unbreakable"); final NumberTag unbreakable = tag.getNumberTag("Unbreakable");
if (unbreakable != null && unbreakable.asBoolean()) { if (unbreakable != null && unbreakable.asBoolean()) {
if ((hideFlagsValue & 0x04) != 0) { if ((hideFlagsValue & 0x04) != 0) {
data.add(StructuredDataKey.UNBREAKABLE, true); // TODO Value is hide, should have a wrapper data.set(StructuredDataKey.UNBREAKABLE, true); // TODO Value is hide, should have a wrapper
} else { } else {
data.addEmpty(StructuredDataKey.UNBREAKABLE); data.addEmpty(StructuredDataKey.UNBREAKABLE);
} }
} }
final CompoundTag trimTag = tag.getCompoundTag("Trim");
if (trimTag != null) {
// TODO
//final ArmorTrim armorTrim = new ArmorTrim(, , (hideFlagsValue & 0x80) == 0);
//data.set(StructuredDataKey.TRIM, armorTrim);
}
final ListTag chargedProjectiles = tag.getListTag("ChargedProjectiles");
if (chargedProjectiles != null) {
final List<Item> items = new ArrayList<>();
for (final Tag chargedProjectile : chargedProjectiles) {
if (!(chargedProjectile instanceof CompoundTag)) {
continue;
}
items.add(itemFromTag((CompoundTag) chargedProjectile));
}
data.set(StructuredDataKey.CHARGED_PROJECTILES, items.toArray(new Item[0]));
}
updateEnchantments(data, tag, "Enchantments", StructuredDataKey.ENCHANTMENTS, (hideFlagsValue & 0x01) == 0); updateEnchantments(data, tag, "Enchantments", StructuredDataKey.ENCHANTMENTS, (hideFlagsValue & 0x01) == 0);
updateEnchantments(data, tag, "StoredEnchantments", StructuredDataKey.STORED_ENCHANTMENTS, (hideFlagsValue & 0x20) == 0); updateEnchantments(data, tag, "StoredEnchantments", StructuredDataKey.STORED_ENCHANTMENTS, (hideFlagsValue & 0x20) == 0);
final NumberTag map = tag.getNumberTag("map"); final NumberTag map = tag.getNumberTag("map");
if (map != null) { if (map != null) {
data.add(StructuredDataKey.MAP_ID, map.asInt()); data.set(StructuredDataKey.MAP_ID, map.asInt());
} }
updateMapDecorations(data, tag.getListTag("Decorations", CompoundTag.class)); updateMapDecorations(data, tag.getListTag("Decorations", CompoundTag.class));
@ -281,13 +311,9 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
updateProfile(data, tag.get("SkullOwner")); updateProfile(data, tag.get("SkullOwner"));
// TODO // TODO
// StructuredDataKey.CUSTOM_NAME
// StructuredDataKey.LORE
// StructuredDataKey.CAN_PLACE_ON // StructuredDataKey.CAN_PLACE_ON
// StructuredDataKey.CAN_BREAK // StructuredDataKey.CAN_BREAK
// StructuredDataKey.ATTRIBUTE_MODIFIERS // StructuredDataKey.ATTRIBUTE_MODIFIERS
// StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP
// StructuredDataKey.REPAIR_COST
// StructuredDataKey.CREATIVE_SLOT_LOCK // StructuredDataKey.CREATIVE_SLOT_LOCK
// StructuredDataKey.INTANGIBLE_PROJECTILE // StructuredDataKey.INTANGIBLE_PROJECTILE
// StructuredDataKey.DYED_COLOR // StructuredDataKey.DYED_COLOR
@ -317,10 +343,17 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
// Add the original as custom data, to be re-used for creative clients as well // Add the original as custom data, to be re-used for creative clients as well
tag.putBoolean(nbtTagName(), true); tag.putBoolean(nbtTagName(), true);
data.add(StructuredDataKey.CUSTOM_DATA, tag); data.set(StructuredDataKey.CUSTOM_DATA, tag);
return item; return item;
} }
private Item itemFromTag(final CompoundTag item) {
final StringTag id = item.getStringTag("id");
final NumberTag count = item.getNumberTag("Count");
final CompoundTag tag = item.getCompoundTag("tag");
return handleItemToClient(new DataItem(0, count.asByte(), (short) 0, tag)); // TODO unmapped id from key
}
private void updateEnchantments(final StructuredDataContainer data, final CompoundTag tag, final String key, private void updateEnchantments(final StructuredDataContainer data, final CompoundTag tag, final String key,
final StructuredDataKey<Enchantments> newKey, final boolean show) { final StructuredDataKey<Enchantments> newKey, final boolean show) {
final ListTag<CompoundTag> enchantmentsTag = tag.getListTag(key, CompoundTag.class); final ListTag<CompoundTag> enchantmentsTag = tag.getListTag(key, CompoundTag.class);
@ -346,11 +379,11 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
enchantments.enchantments().put(intId, lvl.asInt()); enchantments.enchantments().put(intId, lvl.asInt());
} }
data.add(newKey, enchantments); data.set(newKey, enchantments);
// Add glint if none of the enchantments were valid // Add glint if none of the enchantments were valid
if (enchantments.size() == 0 && !enchantmentsTag.isEmpty()) { if (enchantments.size() == 0 && !enchantmentsTag.isEmpty()) {
data.add(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, true); data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, true);
} }
} }
@ -397,7 +430,7 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
return; return;
} }
data.add(StructuredDataKey.PROFILE, new GameProfile(name, uuid, properties.toArray(new GameProfile.Property[0]))); data.set(StructuredDataKey.PROFILE, new GameProfile(name, uuid, properties.toArray(new GameProfile.Property[0])));
} }
private void updateMapDecorations(final StructuredDataContainer data, final ListTag<CompoundTag> decorationsTag) { private void updateMapDecorations(final StructuredDataContainer data, final ListTag<CompoundTag> decorationsTag) {
@ -423,18 +456,38 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
updatedDecorationsTag.put(id, updatedDecorationTag); updatedDecorationsTag.put(id, updatedDecorationTag);
} }
data.add(StructuredDataKey.MAP_DECORATIONS, updatedDecorationsTag); data.set(StructuredDataKey.MAP_DECORATIONS, updatedDecorationsTag);
} }
private void updateDisplay(final StructuredDataContainer data, final CompoundTag displayTag) { private void updateDisplay(final StructuredDataContainer data, final CompoundTag displayTag, final int hideFlags) {
if (displayTag == null) { if (displayTag == null) {
return; return;
} }
final NumberTag mapColorTag = displayTag.getNumberTag("MapColor"); final NumberTag mapColorTag = displayTag.getNumberTag("MapColor");
if (mapColorTag != null) { if (mapColorTag != null) {
data.add(StructuredDataKey.MAP_COLOR, mapColorTag.asInt()); data.set(StructuredDataKey.MAP_COLOR, mapColorTag.asInt());
}
final StringTag nameTag = displayTag.getStringTag("Name");
if (nameTag != null) {
data.set(StructuredDataKey.CUSTOM_NAME, ComponentUtil.jsonStringToTag(nameTag.getValue()));
}
final ListTag loreTag = displayTag.getListTag("Lore");
if (loreTag != null) {
final List<Tag> updatedLore = new ArrayList<>();
for (final Tag loreEntry : loreTag) {
if (loreEntry instanceof StringTag) {
updatedLore.add(ComponentUtil.jsonStringToTag(((StringTag) loreEntry).getValue()));
}
}
data.set(StructuredDataKey.LORE, updatedLore.toArray(new Tag[0]));
}
final NumberTag colorTag = displayTag.getNumberTag("color");
if (colorTag != null) {
data.set(StructuredDataKey.DYED_COLOR, new DyedColor(colorTag.asInt(), (hideFlags & 0x40) == 0));
} }
// TODO other display values
} }
} }

View File

@ -92,6 +92,30 @@ public final class ComponentUtil {
}); });
} }
public static @Nullable String tagToJsonString(@Nullable final Tag tag) {
try {
final ATextComponent component = TextComponentCodec.V1_20_3.deserializeNbtTree(tag);
return component != null ? SerializerVersion.V1_20_3.jsonSerializer.serialize(component) : null;
} catch (final Exception e) {
Via.getPlatform().getLogger().log(Level.SEVERE, "Error converting tag: " + tag, e);
return plainToJson("<error>").toString();
}
}
public static @Nullable Tag jsonStringToTag(@Nullable final String json) {
if (json == null) {
return null;
}
try {
final ATextComponent component = TextComponentSerializer.V1_20_3.deserialize(json);
return TextComponentCodec.V1_20_3.serializeNbt(component);
} catch (final Exception e) {
Via.getPlatform().getLogger().log(Level.SEVERE, "Error converting component: " + json, e);
return new StringTag("<error>");
}
}
public static @Nullable JsonElement convertJson(@Nullable final JsonElement element, final SerializerVersion from, final SerializerVersion to) { public static @Nullable JsonElement convertJson(@Nullable final JsonElement element, final SerializerVersion from, final SerializerVersion to) {
return element != null ? convert(from, to, from.jsonSerializer.deserialize(element)) : null; return element != null ? convert(from, to, from.jsonSerializer.deserialize(element)) : null;
} }

View File

@ -1,5 +1,5 @@
# Project properties - we put these here so they can be modified without causing a recompile of the build scripts # Project properties - we put these here so they can be modified without causing a recompile of the build scripts
projectVersion=4.10.0-24w09a-SNAPSHOT projectVersion=4.10.0-24w10a-SNAPSHOT
# Smile emoji # Smile emoji
mcVersions=1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9 mcVersions=1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9