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 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.id = id;
this.properties = properties;
}
public String name() {
public @Nullable String name() {
return name;
}

View File

@ -67,4 +67,28 @@ final class EmptyStructuredData<T> implements StructuredData<T> {
public int 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 io.netty.buffer.ByteBuf;
import java.util.Objects;
final class FilledStructuredData<T> implements StructuredData<T> {
@ -72,4 +73,31 @@ final class FilledStructuredData<T> implements StructuredData<T> {
public int 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.data.FullMappings;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.Unit;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -68,13 +69,17 @@ public final class StructuredDataContainer {
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);
if (id != -1) {
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) {
// Empty optional to override the Minecraft default
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.ArmorTrim;
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.BlockStateProperties;
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.Fireworks;
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.SuspiciousStewEffect;
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<Holder<Instrument>> INSTRUMENT = new StructuredDataKey<>("instrument", Instrument.TYPE);
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<Fireworks> FIREWORKS = new StructuredDataKey<>("fireworks", Fireworks.TYPE);
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<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<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);

View File

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

View File

@ -23,40 +23,39 @@
package com.viaversion.viaversion.api.minecraft.item.data;
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;
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
public BannerPattern read(final ByteBuf buffer) throws Exception {
final int pattern = Type.VAR_INT.readPrimitive(buffer);
final int color = Type.VAR_INT.readPrimitive(buffer);
return new BannerPattern(pattern, color);
public BannerPattern readDirect(final ByteBuf buffer) throws Exception {
final String assetId = Type.STRING.read(buffer);
final String tanslationKey = Type.STRING.read(buffer);
return new BannerPattern(assetId, tanslationKey);
}
@Override
public void write(final ByteBuf buffer, final BannerPattern value) throws Exception {
Type.VAR_INT.writePrimitive(buffer, value.pattern);
Type.VAR_INT.writePrimitive(buffer, value.color);
public void writeDirect(final ByteBuf buffer, final BannerPattern value) throws Exception {
Type.STRING.write(buffer, value.assetId);
Type.STRING.write(buffer, value.tanslationKey);
}
};
public static final Type<BannerPattern[]> ARRAY_TYPE = new ArrayType<>(TYPE);
private final int pattern;
private final int color;
private final String assetId;
private final String tanslationKey;
public BannerPattern(final int pattern, final int color) {
this.pattern = pattern;
this.color = color;
public BannerPattern(final String assetId, final String tanslationKey) {
this.assetId = assetId;
this.tanslationKey = tanslationKey;
}
public int pattern() {
return this.pattern;
public String assetId() {
return assetId;
}
public int color() {
return this.color;
public String tanslationKey() {
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.type.Type;
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
public LodestoneTarget read(final ByteBuf buffer) throws Exception {
final GlobalPosition position = Type.GLOBAL_POSITION.read(buffer);
public LodestoneTracker read(final ByteBuf buffer) throws Exception {
final GlobalPosition position = Type.OPTIONAL_GLOBAL_POSITION.read(buffer);
final boolean tracked = buffer.readBoolean();
return new LodestoneTarget(position, tracked);
return new LodestoneTracker(position, tracked);
}
@Override
public void write(final ByteBuf buffer, final LodestoneTarget value) throws Exception {
Type.GLOBAL_POSITION.write(buffer, value.position);
public void write(final ByteBuf buffer, final LodestoneTracker value) throws Exception {
Type.OPTIONAL_GLOBAL_POSITION.write(buffer, value.position);
buffer.writeBoolean(value.tracked);
}
};
@ -46,12 +47,12 @@ public final class LodestoneTarget {
private final GlobalPosition position;
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.tracked = tracked;
}
public GlobalPosition pos() {
public @Nullable GlobalPosition pos() {
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 poseType = add(20, Type.VAR_INT);
public final MetaType catVariantType = add(21, Type.VAR_INT);
public final MetaType frogVariantType = add(22, Type.VAR_INT);
public final MetaType optionalGlobalPosition = add(23, Type.OPTIONAL_GLOBAL_POSITION);
public final MetaType paintingVariantType = add(24, Type.VAR_INT);
public final MetaType snifferState = add(25, Type.VAR_INT);
public final MetaType armadilloState = add(26, Type.VAR_INT);
public final MetaType vectorType = add(27, Type.VECTOR3F);
public final MetaType quaternionType = add(28, Type.QUATERNION);
public final MetaType wolfVariantType = add(22, Type.VAR_INT);
public final MetaType frogVariantType = add(23, Type.VAR_INT);
public final MetaType optionalGlobalPosition = add(24, Type.OPTIONAL_GLOBAL_POSITION);
public final MetaType paintingVariantType = add(25, Type.VAR_INT);
public final MetaType snifferState = add(26, Type.VAR_INT);
public final MetaType armadilloState = add(27, Type.VAR_INT);
public final MetaType vectorType = add(28, Type.VECTOR3F);
public final MetaType quaternionType = add(29, Type.QUATERNION);
public MetaTypes1_20_5(final ParticleType particleType) {
super(29);
super(30);
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_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_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 ProtocolVersion register(int version, String name) {

View File

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

View File

@ -34,7 +34,7 @@ public final class GameProfileType extends Type<GameProfile> {
@Override
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 int propertyCount = Type.VAR_INT.readPrimitive(buffer);
final GameProfile.Property[] properties = new GameProfile.Property[propertyCount];
@ -49,7 +49,7 @@ public final class GameProfileType extends Type<GameProfile> {
@Override
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.VAR_INT.writePrimitive(buffer, value.properties().length);
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.protocols.base.ClientboundLoginPackets;
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_3to1_20_2.packet.ClientboundConfigurationPackets1_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
});
new CommandRewriter1_19_4<>(this).registerDeclareCommands1_19(ClientboundPackets1_20_3.DECLARE_COMMANDS);
cancelServerbound(State.LOGIN, ServerboundLoginPackets.COOKIE_RESPONSE.getId());
cancelServerbound(ServerboundConfigurationPackets1_20_5.COOKIE_RESPONSE);
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.INSTRUMENT)
.add(StructuredDataKey.RECIPES)
.add(StructuredDataKey.LODESTONE_TARGET)
.add(StructuredDataKey.LODESTONE_TRACKER)
.add(StructuredDataKey.FIREWORK_EXPLOSION)
.add(StructuredDataKey.FIREWORKS)
.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.StructuredItem;
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.type.Type;
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.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.UUIDUtil;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
@ -192,17 +194,22 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
return toOldItem(item);
}
// TODO Block entity changes
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();
data.setIdLookup(protocol, true);
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
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
return new DataItem(item.identifier(), (byte) item.amount(), (short) 0, tag);
return dataItem;
}
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
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");
if (damage != null && damage.asInt() != 0) {
data.add(StructuredDataKey.DAMAGE, damage.asInt());
data.set(StructuredDataKey.DAMAGE, damage.asInt());
}
final NumberTag repairCost = tag.getNumberTag("RepairCost");
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");
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");
@ -240,12 +253,13 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
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");
if (entityTag != null) {
data.add(StructuredDataKey.ENTITY_DATA, entityTag);
data.set(StructuredDataKey.ENTITY_DATA, entityTag);
}
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);
}
final NumberTag hideFlags = tag.getNumberTag("HideFlags");
final int hideFlagsValue = hideFlags != null ? hideFlags.asInt() : 0;
final NumberTag unbreakable = tag.getNumberTag("Unbreakable");
if (unbreakable != null && unbreakable.asBoolean()) {
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 {
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, "StoredEnchantments", StructuredDataKey.STORED_ENCHANTMENTS, (hideFlagsValue & 0x20) == 0);
final NumberTag map = tag.getNumberTag("map");
if (map != null) {
data.add(StructuredDataKey.MAP_ID, map.asInt());
data.set(StructuredDataKey.MAP_ID, map.asInt());
}
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"));
// TODO
// StructuredDataKey.CUSTOM_NAME
// StructuredDataKey.LORE
// StructuredDataKey.CAN_PLACE_ON
// StructuredDataKey.CAN_BREAK
// StructuredDataKey.ATTRIBUTE_MODIFIERS
// StructuredDataKey.HIDE_ADDITIONAL_TOOLTIP
// StructuredDataKey.REPAIR_COST
// StructuredDataKey.CREATIVE_SLOT_LOCK
// StructuredDataKey.INTANGIBLE_PROJECTILE
// 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
tag.putBoolean(nbtTagName(), true);
data.add(StructuredDataKey.CUSTOM_DATA, tag);
data.set(StructuredDataKey.CUSTOM_DATA, tag);
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,
final StructuredDataKey<Enchantments> newKey, final boolean show) {
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());
}
data.add(newKey, enchantments);
data.set(newKey, enchantments);
// Add glint if none of the enchantments were valid
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;
}
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) {
@ -423,18 +456,38 @@ public final class BlockItemPacketRewriter1_20_5 extends ItemRewriter<Clientboun
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) {
return;
}
final NumberTag mapColorTag = displayTag.getNumberTag("MapColor");
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) {
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
projectVersion=4.10.0-24w09a-SNAPSHOT
projectVersion=4.10.0-24w10a-SNAPSHOT
# 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