From bb2f26a5ebe6cfe56d628b20f8c34586097c45c8 Mon Sep 17 00:00:00 2001 From: EnZaXD Date: Wed, 17 Jul 2024 19:02:34 +0200 Subject: [PATCH] Handle keep all player attributes boolean in LOGIN in 1.16->1.15.2 (#822) --- .../v1_16to1_15_2/Protocol1_16To1_15_2.java | 2 + .../data/BackwardsMappingData1_16.java | 7 +- .../rewriter/EntityPacketRewriter1_16.java | 49 ++++++++++---- .../storage/PlayerAttributesStorage.java | 67 +++++++++++++++++++ .../rewriter/EntityPacketRewriter1_19.java | 2 +- 5 files changed, 110 insertions(+), 17 deletions(-) create mode 100644 common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/storage/PlayerAttributesStorage.java diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/Protocol1_16To1_15_2.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/Protocol1_16To1_15_2.java index 7db56ae5..348c60c3 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/Protocol1_16To1_15_2.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/Protocol1_16To1_15_2.java @@ -22,6 +22,7 @@ import com.viaversion.viabackwards.api.rewriters.SoundRewriter; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.TranslatableRewriter1_16; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.data.BackwardsMappingData1_16; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.CommandRewriter1_16; +import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.PlayerAttributesStorage; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.WorldNameTracker; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.BlockItemPacketRewriter1_16; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.EntityPacketRewriter1_16; @@ -173,6 +174,7 @@ public class Protocol1_16To1_15_2 extends BackwardsProtocol entry : AttributeMappings1_16.attributeIdentifierMappings().entrySet()) { - attributeMappings.put(entry.getValue(), entry.getKey()); + attributeMappings.put(Key.stripMinecraftNamespace(entry.getValue()), entry.getKey()); } } - public Map attributeIdentifierMappings() { - return attributeMappings; + public String mappedAttributeIdentifier(final String identifier) { + return attributeMappings.getOrDefault(identifier, identifier); } } \ No newline at end of file diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/rewriter/EntityPacketRewriter1_16.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/rewriter/EntityPacketRewriter1_16.java index 66c828b1..cba86133 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/rewriter/EntityPacketRewriter1_16.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/rewriter/EntityPacketRewriter1_16.java @@ -19,6 +19,7 @@ package com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter; import com.viaversion.viabackwards.api.rewriters.EntityRewriter; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.Protocol1_16To1_15_2; +import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.PlayerAttributesStorage; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.WorldNameTracker; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.WolfDataMaskStorage; import com.viaversion.viaversion.api.Via; @@ -41,6 +42,7 @@ import com.viaversion.viaversion.libs.gson.JsonElement; import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPackets1_15; import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ClientboundPackets1_16; import com.viaversion.viaversion.util.Key; +import java.util.UUID; public class EntityPacketRewriter1_16 extends EntityRewriter { @@ -132,7 +134,17 @@ public class EntityPacketRewriter1_16 extends EntityRewriter { - wrapper.passthrough(Types.VAR_INT); - int size = wrapper.passthrough(Types.INT); - for (int i = 0; i < size; i++) { - String attributeIdentifier = wrapper.read(Types.STRING); - String oldKey = protocol.getMappingData().attributeIdentifierMappings().get(attributeIdentifier); - wrapper.write(Types.STRING, oldKey != null ? oldKey : Key.stripMinecraftNamespace(attributeIdentifier)); + final PlayerAttributesStorage attributes = wrapper.user().get(PlayerAttributesStorage.class); - wrapper.passthrough(Types.DOUBLE); - int modifierSize = wrapper.passthrough(Types.VAR_INT); - for (int j = 0; j < modifierSize; j++) { - wrapper.passthrough(Types.UUID); - wrapper.passthrough(Types.DOUBLE); - wrapper.passthrough(Types.BYTE); + final int entityId = wrapper.passthrough(Types.VAR_INT); + + final int size = wrapper.passthrough(Types.INT); + for (int i = 0; i < size; i++) { + final String identifier = Key.stripMinecraftNamespace(wrapper.read(Types.STRING)); + + final String mappedIdentifier = protocol.getMappingData().mappedAttributeIdentifier(identifier); + wrapper.write(Types.STRING, mappedIdentifier); + final double value = wrapper.passthrough(Types.DOUBLE); + + final int count = wrapper.passthrough(Types.VAR_INT); + final var modifiers = new PlayerAttributesStorage.AttributeModifier[count]; + for (int j = 0; j < count; j++) { + final UUID uuid = wrapper.passthrough(Types.UUID); + final double amount = wrapper.passthrough(Types.DOUBLE); + final byte operation = wrapper.passthrough(Types.BYTE); + + modifiers[j] = new PlayerAttributesStorage.AttributeModifier(uuid, amount, operation); + } + if (entityId == tracker(wrapper.user()).clientEntityId()) { + attributes.addAttribute(mappedIdentifier, new PlayerAttributesStorage.Attribute(value, modifiers)); } } }); diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/storage/PlayerAttributesStorage.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/storage/PlayerAttributesStorage.java new file mode 100644 index 00000000..ef475511 --- /dev/null +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_16to1_15_2/storage/PlayerAttributesStorage.java @@ -0,0 +1,67 @@ +/* + * This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards + * Copyright (C) 2016-2024 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_16to1_15_2.storage; + +import com.viaversion.viabackwards.protocol.v1_16to1_15_2.Protocol1_16To1_15_2; +import com.viaversion.viaversion.api.connection.StorableObject; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; +import com.viaversion.viaversion.api.type.Types; +import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPackets1_15; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public final class PlayerAttributesStorage implements StorableObject { + + private final Map attributes = new HashMap<>(); + + public void sendAttributes(final UserConnection connection, final int entityId) { + final PacketWrapper updateAttributes = PacketWrapper.create(ClientboundPackets1_15.UPDATE_ATTRIBUTES, connection); + + updateAttributes.write(Types.VAR_INT, entityId); + updateAttributes.write(Types.INT, attributes.size()); + for (final Map.Entry attributeEntry : attributes.entrySet()) { + final Attribute attribute = attributeEntry.getValue(); + updateAttributes.write(Types.STRING, attributeEntry.getKey()); + updateAttributes.write(Types.DOUBLE, attribute.value()); + updateAttributes.write(Types.VAR_INT, attribute.modifiers().length); + + for (final AttributeModifier modifier : attribute.modifiers()) { + updateAttributes.write(Types.UUID, modifier.uuid()); + updateAttributes.write(Types.DOUBLE, modifier.amount()); + updateAttributes.write(Types.BYTE, modifier.operation()); + } + } + updateAttributes.send(Protocol1_16To1_15_2.class); + } + + public void clearAttributes() { + attributes.clear(); + } + + public void addAttribute(final String key, final Attribute attribute) { + attributes.put(key, attribute); + } + + public record Attribute(double value, AttributeModifier[] modifiers) { + } + + public record AttributeModifier(UUID uuid, double amount, byte operation) { + } +} diff --git a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/rewriter/EntityPacketRewriter1_19.java b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/rewriter/EntityPacketRewriter1_19.java index 76d08a2d..6cfa2097 100644 --- a/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/rewriter/EntityPacketRewriter1_19.java +++ b/common/src/main/java/com/viaversion/viabackwards/protocol/v1_19to1_18_2/rewriter/EntityPacketRewriter1_19.java @@ -202,7 +202,7 @@ public final class EntityPacketRewriter1_19 extends EntityRewriter { final GlobalBlockPosition lastDeathPosition = wrapper.read(Types.OPTIONAL_GLOBAL_POSITION); if (lastDeathPosition != null) {