Handle keep all player attributes boolean in LOGIN in 1.16->1.15.2 (#822)

This commit is contained in:
EnZaXD 2024-07-17 19:02:34 +02:00 committed by GitHub
parent b10b161fe7
commit bb2f26a5eb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 110 additions and 17 deletions

View File

@ -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.rewriter.TranslatableRewriter1_16;
import com.viaversion.viabackwards.protocol.v1_16to1_15_2.data.BackwardsMappingData1_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.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.storage.WorldNameTracker;
import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.BlockItemPacketRewriter1_16; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.BlockItemPacketRewriter1_16;
import com.viaversion.viabackwards.protocol.v1_16to1_15_2.rewriter.EntityPacketRewriter1_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<ClientboundPackets1_
user.put(new PlayerSneakStorage()); user.put(new PlayerSneakStorage());
user.put(new WorldNameTracker()); user.put(new WorldNameTracker());
user.put(new PlayerAttributesStorage());
user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, EntityTypes1_16.PLAYER)); user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, EntityTypes1_16.PLAYER));
} }

View File

@ -21,6 +21,7 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viabackwards.api.data.BackwardsMappingData; import com.viaversion.viabackwards.api.data.BackwardsMappingData;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.Protocol1_15_2To1_16; import com.viaversion.viaversion.protocols.v1_15_2to1_16.Protocol1_15_2To1_16;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.data.AttributeMappings1_16; import com.viaversion.viaversion.protocols.v1_15_2to1_16.data.AttributeMappings1_16;
import com.viaversion.viaversion.util.Key;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -35,11 +36,11 @@ public class BackwardsMappingData1_16 extends BackwardsMappingData {
protected void loadExtras(final CompoundTag data) { protected void loadExtras(final CompoundTag data) {
super.loadExtras(data); super.loadExtras(data);
for (Map.Entry<String, String> entry : AttributeMappings1_16.attributeIdentifierMappings().entrySet()) { for (Map.Entry<String, String> entry : AttributeMappings1_16.attributeIdentifierMappings().entrySet()) {
attributeMappings.put(entry.getValue(), entry.getKey()); attributeMappings.put(Key.stripMinecraftNamespace(entry.getValue()), entry.getKey());
} }
} }
public Map<String, String> attributeIdentifierMappings() { public String mappedAttributeIdentifier(final String identifier) {
return attributeMappings; return attributeMappings.getOrDefault(identifier, identifier);
} }
} }

View File

@ -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.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.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.WorldNameTracker;
import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.WolfDataMaskStorage; import com.viaversion.viabackwards.protocol.v1_16to1_15_2.storage.WolfDataMaskStorage;
import com.viaversion.viaversion.api.Via; 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_14_4to1_15.packet.ClientboundPackets1_15;
import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ClientboundPackets1_16; import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ClientboundPackets1_16;
import com.viaversion.viaversion.util.Key; import com.viaversion.viaversion.util.Key;
import java.util.UUID;
public class EntityPacketRewriter1_16 extends EntityRewriter<ClientboundPackets1_16, Protocol1_16To1_15_2> { public class EntityPacketRewriter1_16 extends EntityRewriter<ClientboundPackets1_16, Protocol1_16To1_15_2> {
@ -132,7 +134,17 @@ public class EntityPacketRewriter1_16 extends EntityRewriter<ClientboundPackets1
if (wrapper.read(Types.BOOLEAN)) { if (wrapper.read(Types.BOOLEAN)) {
wrapper.set(Types.STRING, 0, "flat"); wrapper.set(Types.STRING, 0, "flat");
} }
wrapper.read(Types.BOOLEAN); // Keep all playerdata
final PlayerAttributesStorage attributes = wrapper.user().get(PlayerAttributesStorage.class);
final boolean keepPlayerAttributes = wrapper.read(Types.BOOLEAN);
if (keepPlayerAttributes) {
// Ensure packet order
wrapper.send(Protocol1_16To1_15_2.class);
wrapper.cancel();
attributes.sendAttributes(wrapper.user(), tracker(wrapper.user()).clientEntityId());
} else {
attributes.clearAttributes();
}
// Finally update the world name // Finally update the world name
worldNameTracker.setWorldName(nextWorldName); worldNameTracker.setWorldName(nextWorldName);
@ -171,6 +183,7 @@ public class EntityPacketRewriter1_16 extends EntityRewriter<ClientboundPackets1
wrapper.set(Types.STRING, 0, "flat"); wrapper.set(Types.STRING, 0, "flat");
} }
}); });
handler(playerTrackerHandler());
} }
}); });
@ -182,19 +195,29 @@ public class EntityPacketRewriter1_16 extends EntityRewriter<ClientboundPackets1
registerSetEntityData(ClientboundPackets1_16.SET_ENTITY_DATA, Types1_16.ENTITY_DATA_LIST, Types1_14.ENTITY_DATA_LIST); registerSetEntityData(ClientboundPackets1_16.SET_ENTITY_DATA, Types1_16.ENTITY_DATA_LIST, Types1_14.ENTITY_DATA_LIST);
protocol.registerClientbound(ClientboundPackets1_16.UPDATE_ATTRIBUTES, wrapper -> { protocol.registerClientbound(ClientboundPackets1_16.UPDATE_ATTRIBUTES, wrapper -> {
wrapper.passthrough(Types.VAR_INT); final PlayerAttributesStorage attributes = wrapper.user().get(PlayerAttributesStorage.class);
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));
wrapper.passthrough(Types.DOUBLE); final int entityId = wrapper.passthrough(Types.VAR_INT);
int modifierSize = wrapper.passthrough(Types.VAR_INT);
for (int j = 0; j < modifierSize; j++) { final int size = wrapper.passthrough(Types.INT);
wrapper.passthrough(Types.UUID); for (int i = 0; i < size; i++) {
wrapper.passthrough(Types.DOUBLE); final String identifier = Key.stripMinecraftNamespace(wrapper.read(Types.STRING));
wrapper.passthrough(Types.BYTE);
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));
} }
} }
}); });

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<String, Attribute> 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<String, Attribute> 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) {
}
}

View File

@ -202,7 +202,7 @@ public final class EntityPacketRewriter1_19 extends EntityRewriter<ClientboundPa
map(Types.BYTE); // Previous gamemode map(Types.BYTE); // Previous gamemode
map(Types.BOOLEAN); // Debug map(Types.BOOLEAN); // Debug
map(Types.BOOLEAN); // Flat map(Types.BOOLEAN); // Flat
map(Types.BOOLEAN); // Keep player data map(Types.BOOLEAN); // Keep player attributes
handler(wrapper -> { handler(wrapper -> {
final GlobalBlockPosition lastDeathPosition = wrapper.read(Types.OPTIONAL_GLOBAL_POSITION); final GlobalBlockPosition lastDeathPosition = wrapper.read(Types.OPTIONAL_GLOBAL_POSITION);
if (lastDeathPosition != null) { if (lastDeathPosition != null) {