3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-12-27 16:40:10 +01:00

Properly handle item display rotation change

Fixes #3354
Dieser Commit ist enthalten in:
Nassim Jahnke 2023-07-02 11:01:12 +02:00
Ursprung f28aac5eb3
Commit 7edb43844c
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 6BE3B555EBC5982B
5 geänderte Dateien mit 69 neuen und 106 gelöschten Zeilen

Datei anzeigen

@ -50,4 +50,14 @@ public final class Quaternion {
public float w() { public float w() {
return w; return w;
} }
@Override
public String toString() {
return "Quaternion{" +
"x=" + x +
", y=" + y +
", z=" + z +
", w=" + w +
'}';
}
} }

Datei anzeigen

@ -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.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag; 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.Entity1_19_4Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType; 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.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_19_4; 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<ClientboundPackets1_19_4, Protocol1_20To1_19_4> { public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_4, Protocol1_20To1_19_4> {
private static final Quaternion Y_FLIPPED_ROTATION = new Quaternion(0, 1, 0, 0);
public EntityPackets(final Protocol1_20To1_19_4 protocol) { public EntityPackets(final Protocol1_20To1_19_4 protocol) {
super(protocol); super(protocol);
} }
@Override @Override
public void registerPackets() { 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); registerMetadataRewriter(ClientboundPackets1_19_4.ENTITY_METADATA, Types1_19_4.METADATA_LIST, Types1_20.METADATA_LIST);
registerRemoveEntities(ClientboundPackets1_19_4.REMOVE_ENTITIES); 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() { protocol.registerClientbound(ClientboundPackets1_19_4.JOIN_GAME, new PacketHandlers() {
@Override @Override
public void register() { public void register() {
@ -218,6 +131,21 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_4
filter().handler((event, meta) -> meta.setMetaType(Types1_20.META_TYPES.byId(meta.metaType().typeId()))); filter().handler((event, meta) -> 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); 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) -> { filter().filterFamily(Entity1_19_4Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
final int blockState = meta.value(); final int blockState = meta.value();
meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState)); meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState));
@ -228,4 +156,8 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_4
public EntityType typeFromId(final int type) { public EntityType typeFromId(final int type) {
return Entity1_19_4Types.getTypeFromId(type); return Entity1_19_4Types.getTypeFromId(type);
} }
private Quaternion rotateY180(final Quaternion quaternion) {
return new Quaternion(-quaternion.z(), quaternion.w(), quaternion.x(), -quaternion.y());
}
} }

Datei anzeigen

@ -101,11 +101,11 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
} }
@Override @Override
public void handleMetadata(int entityId, List<Metadata> metadataList, UserConnection connection) { public void handleMetadata(final int entityId, final List<Metadata> metadataList, final UserConnection connection) {
final TrackedEntity entity = tracker(connection).entity(entityId); final TrackedEntity entity = tracker(connection).entity(entityId);
final EntityType type = entity != null ? entity.entityType() : null; final EntityType type = entity != null ? entity.entityType() : null;
int i = 0; // Count index for fast removal 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 // Call handlers implementing the old handleMetadata
if (!callOldMetaHandler(entityId, type, metadata, metadataList, connection)) { if (!callOldMetaHandler(entityId, type, metadata, metadataList, connection)) {
metadataList.remove(i--); metadataList.remove(i--);
@ -113,18 +113,18 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
} }
MetaHandlerEvent event = null; MetaHandlerEvent event = null;
for (MetaFilter filter : metadataFilters) { for (final MetaFilter filter : metadataFilters) {
if (!filter.isFiltered(type, metadata)) { if (!filter.isFiltered(type, metadata)) {
continue; continue;
} }
if (event == null) { if (event == null) {
// Only initialize when needed and share event instance // Only initialize when needed and share event instance
event = new MetaHandlerEventImpl(connection, type, entityId, metadata, metadataList); event = new MetaHandlerEventImpl(connection, entity, entityId, metadata, metadataList);
} }
try { try {
filter.handler().handle(event, metadata); filter.handler().handle(event, metadata);
} catch (Exception e) { } catch (final Exception e) {
logException(e, type, metadataList, metadata); logException(e, type, metadataList, metadata);
metadataList.remove(i--); metadataList.remove(i--);
break; break;

Datei anzeigen

@ -18,11 +18,13 @@
package com.viaversion.viaversion.rewriter.meta; package com.viaversion.viaversion.rewriter.meta;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.TrackedEntity;
import com.viaversion.viaversion.api.minecraft.entities.EntityType; import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata; import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.List;
public interface MetaHandlerEvent { public interface MetaHandlerEvent {
/** /**
@ -39,12 +41,21 @@ public interface MetaHandlerEvent {
*/ */
int entityId(); int entityId();
/**
* Returns the tracked entity if present.
*
* @return tracked entity if present, else null
*/
@Nullable TrackedEntity trackedEntity();
/** /**
* Returns the entity type of the entity the metadata belongs to if tracked. * Returns the entity type of the entity the metadata belongs to if tracked.
* *
* @return entity type of the entity if tracked, else null * @return entity type of the entity if tracked, else null
*/ */
@Nullable EntityType entityType(); default @Nullable EntityType entityType() {
return trackedEntity() != null ? trackedEntity().entityType() : null;
}
/** /**
* Returns the metadata index. * Returns the metadata index.
@ -110,6 +121,15 @@ public interface MetaHandlerEvent {
*/ */
@Nullable List<Metadata> extraMeta(); @Nullable List<Metadata> 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. * Adds the given metadata to the metadata list.
* This metadata will not be passed through handlers of the current loop. * This metadata will not be passed through handlers of the current loop.

Datei anzeigen

@ -19,25 +19,26 @@
package com.viaversion.viaversion.rewriter.meta; package com.viaversion.viaversion.rewriter.meta;
import com.viaversion.viaversion.api.connection.UserConnection; 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 com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
public class MetaHandlerEventImpl implements MetaHandlerEvent { public class MetaHandlerEventImpl implements MetaHandlerEvent {
private final UserConnection connection; private final UserConnection connection;
private final EntityType entityType; private final TrackedEntity trackedEntity;
private final int entityId; private final int entityId;
private final List<Metadata> metadataList; private final List<Metadata> metadataList;
private final Metadata meta; private final Metadata meta;
private List<Metadata> extraData; private List<Metadata> extraData;
private boolean cancel; private boolean cancel;
public MetaHandlerEventImpl(UserConnection connection, @Nullable EntityType entityType, int entityId, Metadata meta, List<Metadata> metadataList) { public MetaHandlerEventImpl(UserConnection connection, @Nullable TrackedEntity trackedEntity, int entityId, Metadata meta, List<Metadata> metadataList) {
this.connection = connection; this.connection = connection;
this.entityType = entityType; this.trackedEntity = trackedEntity;
this.entityId = entityId; this.entityId = entityId;
this.meta = meta; this.meta = meta;
this.metadataList = metadataList; this.metadataList = metadataList;
@ -54,8 +55,8 @@ public class MetaHandlerEventImpl implements MetaHandlerEvent {
} }
@Override @Override
public @Nullable EntityType entityType() { public @Nullable TrackedEntity trackedEntity() {
return entityType; return trackedEntity;
} }
@Override @Override