From cf76ab6818a9754e2217ef6edd1e1210a86a395c Mon Sep 17 00:00:00 2001 From: RoccoDev Date: Wed, 21 Oct 2026 19:38:49 +0200 Subject: [PATCH] Rewrite interactions as invisible slimes --- .../entities/storage/WrappedEntityData.java | 4 ++ .../rewriter/EntityPacketRewriter1_19_4.java | 39 +++++++++++++-- .../storage/InteractionData.java | 50 +++++++++++++++++++ 3 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/storage/InteractionData.java diff --git a/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/WrappedEntityData.java b/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/WrappedEntityData.java index a261718ed..1cdbea847 100644 --- a/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/WrappedEntityData.java +++ b/common/src/main/java/com/viaversion/viabackwards/api/entities/storage/WrappedEntityData.java @@ -28,6 +28,10 @@ public boolean has(EntityData data) { return this.entityDataList.contains(data); } + public boolean has(int index) { + return entityDataList.stream().anyMatch(data -> data.id() == index); + } + public void remove(EntityData data) { this.entityDataList.remove(data); } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/rewriter/EntityPacketRewriter1_19_4.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/rewriter/EntityPacketRewriter1_19_4.java index ce9beef0d..b70659de7 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/rewriter/EntityPacketRewriter1_19_4.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/rewriter/EntityPacketRewriter1_19_4.java @@ -26,6 +26,7 @@ import com.viaversion.viabackwards.api.rewriters.EntityRewriter; import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.Protocol1_19_4To1_19_3; import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.storage.EntityTracker1_19_4; +import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.storage.InteractionData; import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.storage.LinkedEntityStorage; import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.data.entity.TrackedEntity; @@ -494,9 +495,33 @@ public void registerRewrites() { } }); - filter().type(EntityTypes1_19_4.INTERACTION).cancel(8); // Width - filter().type(EntityTypes1_19_4.INTERACTION).cancel(9); // Height - filter().type(EntityTypes1_19_4.INTERACTION).cancel(10); // Response + filter().type(EntityTypes1_19_4.INTERACTION).handler(((event, data) -> { + if (event.index() == 8 || event.index() == 9) { + // Width/Height, use slime of appropriate size + InteractionData interactionData = event.trackedEntity().get(InteractionData.class); + if (interactionData == null) { + interactionData = new InteractionData(); + event.trackedEntity().put(interactionData); + } + final int slimeSize = interactionData.update(data.value(), event.index() == 8); + // let's only send one size data even if we get both width and height + final EntityData otherDimData = event.dataAtIndex(16); + if (otherDimData != null) { + otherDimData.setTypeAndValue(Types1_19_3.ENTITY_DATA_TYPES.varIntType, slimeSize); + event.cancel(); + return; + } + event.setIndex(16); + data.setTypeAndValue(Types1_19_3.ENTITY_DATA_TYPES.varIntType, slimeSize); + } else if (event.index() == 10) { + // Response + event.cancel(); + } else if (event.index() == 0) { + // Keep invisibility + final byte flags = data.value(); + data.setValue((byte) (flags | 0x20)); + } + })); filter().type(EntityTypes1_19_4.SNIFFER).cancel(17); // State filter().type(EntityTypes1_19_4.SNIFFER).cancel(18); // Drop seed at tick @@ -644,7 +669,13 @@ public void onMappingDataLoaded() { mapEntityTypeWithData(EntityTypes1_19_4.ITEM_DISPLAY, EntityTypes1_19_4.ARMOR_STAND).spawnEntityData(displayDataCreator); mapEntityTypeWithData(EntityTypes1_19_4.BLOCK_DISPLAY, EntityTypes1_19_4.ARMOR_STAND).spawnEntityData(displayDataCreator); - mapEntityTypeWithData(EntityTypes1_19_4.INTERACTION, EntityTypes1_19_4.ARMOR_STAND).spawnEntityData(displayDataCreator); // Not much we can do about this one + mapEntityTypeWithData(EntityTypes1_19_4.INTERACTION, EntityTypes1_19_4.SLIME).spawnEntityData(storage -> { + storage.add(new EntityData(0, Types1_19_3.ENTITY_DATA_TYPES.byteType, (byte) 0x20)); // Invisible + storage.add(new EntityData(4, Types1_19_3.ENTITY_DATA_TYPES.booleanType, true)); // Silent + if (!storage.has(16)) { + storage.add(new EntityData(16, Types1_19_3.ENTITY_DATA_TYPES.varIntType, 2)); // Size + } + }); mapEntityTypeWithData(EntityTypes1_19_4.SNIFFER, EntityTypes1_19_4.RAVAGER).jsonName(); } diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/storage/InteractionData.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/storage/InteractionData.java new file mode 100644 index 000000000..d43bfdb60 --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19_4to1_19_3/storage/InteractionData.java @@ -0,0 +1,50 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * Copyright (C) 2016-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.storage; + +import com.viaversion.viaversion.api.connection.StorableObject; +import com.viaversion.viaversion.util.MathUtil; + +public class InteractionData implements StorableObject { + private static final double SLIME_DIMENSIONS = 0.52; + + private float width; + private float height; + + private int slimeSize; + + public InteractionData() { + this.width = 1.0F; + this.height = 1.0F; + calculateSize(); + } + + public int update(final float dimension, final boolean isWidth) { + if (isWidth) { + this.width = dimension; + } else { + this.height = dimension; + } + calculateSize(); + return slimeSize; + } + + private void calculateSize() { + slimeSize = MathUtil.clamp((int) Math.round(Math.min(width, height) / SLIME_DIMENSIONS), 1, 127); + } +}