From 7edb43844cc60ade566b57f95111defda78bac03 Mon Sep 17 00:00:00 2001 From: Nassim Jahnke Date: Sun, 2 Jul 2023 11:01:12 +0200 Subject: [PATCH] Properly handle item display rotation change Fixes #3354 --- .../viaversion/api/minecraft/Quaternion.java | 10 ++ .../packets/EntityPackets.java | 116 ++++-------------- .../viaversion/rewriter/EntityRewriter.java | 10 +- .../rewriter/meta/MetaHandlerEvent.java | 24 +++- .../rewriter/meta/MetaHandlerEventImpl.java | 15 +-- 5 files changed, 69 insertions(+), 106 deletions(-) diff --git a/api/src/main/java/com/viaversion/viaversion/api/minecraft/Quaternion.java b/api/src/main/java/com/viaversion/viaversion/api/minecraft/Quaternion.java index 80236a26a..2d0fddd9e 100644 --- a/api/src/main/java/com/viaversion/viaversion/api/minecraft/Quaternion.java +++ b/api/src/main/java/com/viaversion/viaversion/api/minecraft/Quaternion.java @@ -50,4 +50,14 @@ public final class Quaternion { public float w() { return w; } + + @Override + public String toString() { + return "Quaternion{" + + "x=" + x + + ", y=" + y + + ", z=" + z + + ", w=" + w + + '}'; + } } diff --git a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20to1_19_4/packets/EntityPackets.java b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20to1_19_4/packets/EntityPackets.java index dce22e5f2..2361ef1a4 100644 --- a/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20to1_19_4/packets/EntityPackets.java +++ b/common/src/main/java/com/viaversion/viaversion/protocols/protocol1_20to1_19_4/packets/EntityPackets.java @@ -23,10 +23,10 @@ import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; -import com.viaversion.viaversion.api.data.entity.TrackedEntity; +import com.viaversion.viaversion.api.minecraft.Quaternion; import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types; import com.viaversion.viaversion.api.minecraft.entities.EntityType; -import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; +import com.viaversion.viaversion.api.minecraft.metadata.Metadata; import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers; import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.types.version.Types1_19_4; @@ -37,105 +37,18 @@ import com.viaversion.viaversion.rewriter.EntityRewriter; public final class EntityPackets extends EntityRewriter { + private static final Quaternion Y_FLIPPED_ROTATION = new Quaternion(0, 1, 0, 0); + public EntityPackets(final Protocol1_20To1_19_4 protocol) { super(protocol); } @Override public void registerPackets() { + registerTrackerWithData1_19(ClientboundPackets1_19_4.SPAWN_ENTITY, Entity1_19_4Types.FALLING_BLOCK); registerMetadataRewriter(ClientboundPackets1_19_4.ENTITY_METADATA, Types1_19_4.METADATA_LIST, Types1_20.METADATA_LIST); registerRemoveEntities(ClientboundPackets1_19_4.REMOVE_ENTITIES); - protocol.registerClientbound(ClientboundPackets1_19_4.SPAWN_ENTITY, new PacketHandlers() { - @Override - public void register() { - map(Type.VAR_INT); // Entity id - map(Type.UUID); // Entity UUID - map(Type.VAR_INT); // Entity type - map(Type.DOUBLE); // X - map(Type.DOUBLE); // Y - map(Type.DOUBLE); // Z - map(Type.BYTE); // Pitch - map(Type.BYTE); // Yaw - map(Type.BYTE); // Head yaw - map(Type.VAR_INT); // Data - handler(trackerHandler()); - handler(wrapper -> { - int entityId = wrapper.get(Type.VAR_INT, 0); - EntityType entityType = tracker(wrapper.user()).entityType(entityId); - if (entityType == Entity1_19_4Types.FALLING_BLOCK) { - wrapper.set(Type.VAR_INT, 2, protocol.getMappingData().getNewBlockStateId(wrapper.get(Type.VAR_INT, 2))); - } else if (entityType == Entity1_19_4Types.ITEM_DISPLAY) { - // Turn it upside down - wrapper.set(Type.BYTE, 0, (byte) -wrapper.get(Type.BYTE, 0)); - wrapper.set(Type.BYTE, 1, (byte) (wrapper.get(Type.BYTE, 1) - 128)); - } - }); - } - }); - - final PacketHandler displayYawPitchHandler = wrapper -> { - final TrackedEntity trackedEntity = tracker(wrapper.user()).entity(wrapper.get(Type.VAR_INT, 0)); - if (trackedEntity == null || trackedEntity.entityType() != Entity1_19_4Types.ITEM_DISPLAY) { - return; - } - - // Turn it upside down - wrapper.set(Type.BYTE, 0, (byte) (wrapper.get(Type.BYTE, 0) - 128)); - wrapper.set(Type.BYTE, 1, (byte) -wrapper.get(Type.BYTE, 1)); - }; - protocol.registerClientbound(ClientboundPackets1_19_4.ENTITY_POSITION_AND_ROTATION, new PacketHandlers() { - @Override - protected void register() { - map(Type.VAR_INT); // Entity id - map(Type.SHORT); // Delta X - map(Type.SHORT); // Delta Y - map(Type.SHORT); // Delta Z - map(Type.BYTE); // Yaw - map(Type.BYTE); // Pitch - handler(displayYawPitchHandler); - } - }); - protocol.registerClientbound(ClientboundPackets1_19_4.ENTITY_ROTATION, new PacketHandlers() { - @Override - protected void register() { - map(Type.VAR_INT); // Entity id - map(Type.BYTE); // Yaw - map(Type.BYTE); // Pitch - handler(displayYawPitchHandler); - } - }); - - protocol.registerClientbound(ClientboundPackets1_19_4.ENTITY_HEAD_LOOK, wrapper -> { - final TrackedEntity trackedEntity = tracker(wrapper.user()).entity(wrapper.passthrough(Type.VAR_INT)); - if (trackedEntity == null || trackedEntity.entityType() != Entity1_19_4Types.ITEM_DISPLAY) { - return; - } - - wrapper.write(Type.BYTE, (byte) (wrapper.read(Type.BYTE) - 128)); - }); - - protocol.registerClientbound(ClientboundPackets1_19_4.ENTITY_TELEPORT, new PacketHandlers() { - @Override - protected void register() { - map(Type.VAR_INT); // Entity id - map(Type.DOUBLE); // X - map(Type.DOUBLE); // Y - map(Type.DOUBLE); // Z - map(Type.BYTE); // Yaw - map(Type.BYTE); // Pitch - handler(wrapper -> { - TrackedEntity trackedEntity = tracker(wrapper.user()).entity(wrapper.get(Type.VAR_INT, 0)); - if (trackedEntity == null || trackedEntity.entityType() != Entity1_19_4Types.ITEM_DISPLAY) { - return; - } - - wrapper.set(Type.BYTE, 0, (byte) (wrapper.get(Type.BYTE, 0) - 128)); - wrapper.set(Type.BYTE, 1, (byte) -wrapper.get(Type.BYTE, 1)); - }); - } - }); - protocol.registerClientbound(ClientboundPackets1_19_4.JOIN_GAME, new PacketHandlers() { @Override public void register() { @@ -218,6 +131,21 @@ public final class EntityPackets extends EntityRewriter meta.setMetaType(Types1_20.META_TYPES.byId(meta.metaType().typeId()))); registerMetaTypeHandler(Types1_20.META_TYPES.itemType, Types1_20.META_TYPES.blockStateType, Types1_20.META_TYPES.optionalBlockStateType, Types1_20.META_TYPES.particleType); + // Rotate item display by 180 degrees around the Y axis + filter().filterFamily(Entity1_19_4Types.DISPLAY).handler((event, meta) -> { + if (event.trackedEntity().hasSentMetadata() || event.hasExtraMeta()) { + return; + } + + if (event.metaAtIndex(12) == null) { + event.createExtraMeta(new Metadata(12, Types1_20.META_TYPES.quaternionType, Y_FLIPPED_ROTATION)); + } + }); + filter().filterFamily(Entity1_19_4Types.DISPLAY).index(12).handler((event, meta) -> { + final Quaternion quaternion = meta.value(); + meta.setValue(rotateY180(quaternion)); + }); + filter().filterFamily(Entity1_19_4Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> { final int blockState = meta.value(); meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState)); @@ -228,4 +156,8 @@ public final class EntityPackets extends EntityRewriter metadataList, UserConnection connection) { + public void handleMetadata(final int entityId, final List metadataList, final UserConnection connection) { final TrackedEntity entity = tracker(connection).entity(entityId); final EntityType type = entity != null ? entity.entityType() : null; int i = 0; // Count index for fast removal - for (Metadata metadata : metadataList.toArray(EMPTY_ARRAY)) { // Copy the list to allow mutation + for (final Metadata metadata : metadataList.toArray(EMPTY_ARRAY)) { // Copy the list to allow mutation // Call handlers implementing the old handleMetadata if (!callOldMetaHandler(entityId, type, metadata, metadataList, connection)) { metadataList.remove(i--); @@ -113,18 +113,18 @@ public abstract class EntityRewriter extraMeta(); + /** + * Returns whether additionally created metadata will be added. + * + * @return true if additionally created metadata is present + */ + default boolean hasExtraMeta() { + return extraMeta() != null; + } + /** * Adds the given metadata to the metadata list. * This metadata will not be passed through handlers of the current loop. diff --git a/common/src/main/java/com/viaversion/viaversion/rewriter/meta/MetaHandlerEventImpl.java b/common/src/main/java/com/viaversion/viaversion/rewriter/meta/MetaHandlerEventImpl.java index 313ec2988..98523a57e 100644 --- a/common/src/main/java/com/viaversion/viaversion/rewriter/meta/MetaHandlerEventImpl.java +++ b/common/src/main/java/com/viaversion/viaversion/rewriter/meta/MetaHandlerEventImpl.java @@ -19,25 +19,26 @@ package com.viaversion.viaversion.rewriter.meta; import com.viaversion.viaversion.api.connection.UserConnection; -import com.viaversion.viaversion.api.minecraft.entities.EntityType; +import com.viaversion.viaversion.api.data.entity.TrackedEntity; import com.viaversion.viaversion.api.minecraft.metadata.Metadata; +import org.checkerframework.checker.nullness.qual.Nullable; + import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.checkerframework.checker.nullness.qual.Nullable; public class MetaHandlerEventImpl implements MetaHandlerEvent { private final UserConnection connection; - private final EntityType entityType; + private final TrackedEntity trackedEntity; private final int entityId; private final List metadataList; private final Metadata meta; private List extraData; private boolean cancel; - public MetaHandlerEventImpl(UserConnection connection, @Nullable EntityType entityType, int entityId, Metadata meta, List metadataList) { + public MetaHandlerEventImpl(UserConnection connection, @Nullable TrackedEntity trackedEntity, int entityId, Metadata meta, List metadataList) { this.connection = connection; - this.entityType = entityType; + this.trackedEntity = trackedEntity; this.entityId = entityId; this.meta = meta; this.metadataList = metadataList; @@ -54,8 +55,8 @@ public class MetaHandlerEventImpl implements MetaHandlerEvent { } @Override - public @Nullable EntityType entityType() { - return entityType; + public @Nullable TrackedEntity trackedEntity() { + return trackedEntity; } @Override