Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-28 09:00:09 +01:00
Re-send last resource pack on server switch
Dieser Commit ist enthalten in:
Ursprung
53aca791dd
Commit
fe5646a68c
@ -18,6 +18,7 @@
|
|||||||
package com.viaversion.viaversion.protocols.protocol1_20_2to1_20;
|
package com.viaversion.viaversion.protocols.protocol1_20_2to1_20;
|
||||||
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
import com.viaversion.viaversion.api.Via;
|
import com.viaversion.viaversion.api.Via;
|
||||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||||
import com.viaversion.viaversion.api.data.MappingData;
|
import com.viaversion.viaversion.api.data.MappingData;
|
||||||
@ -45,6 +46,7 @@ import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter.BlockIt
|
|||||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter.EntityPacketRewriter1_20_2;
|
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.rewriter.EntityPacketRewriter1_20_2;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.ConfigurationState;
|
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.ConfigurationState;
|
||||||
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.ConfigurationState.BridgePhase;
|
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.ConfigurationState.BridgePhase;
|
||||||
|
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.storage.LastResourcePack;
|
||||||
import com.viaversion.viaversion.rewriter.SoundRewriter;
|
import com.viaversion.viaversion.rewriter.SoundRewriter;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
@ -68,6 +70,14 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
|
|||||||
soundRewriter.register1_19_3Sound(ClientboundPackets1_19_4.SOUND);
|
soundRewriter.register1_19_3Sound(ClientboundPackets1_19_4.SOUND);
|
||||||
soundRewriter.registerEntitySound(ClientboundPackets1_19_4.ENTITY_SOUND);
|
soundRewriter.registerEntitySound(ClientboundPackets1_19_4.ENTITY_SOUND);
|
||||||
|
|
||||||
|
registerClientbound(ClientboundPackets1_19_4.RESOURCE_PACK, wrapper -> {
|
||||||
|
final String url = wrapper.passthrough(Type.STRING);
|
||||||
|
final String hash = wrapper.passthrough(Type.STRING);
|
||||||
|
final boolean required = wrapper.passthrough(Type.BOOLEAN);
|
||||||
|
final JsonElement prompt = wrapper.passthrough(Type.OPTIONAL_COMPONENT);
|
||||||
|
wrapper.user().put(new LastResourcePack(url, hash, required, prompt));
|
||||||
|
});
|
||||||
|
|
||||||
registerClientbound(ClientboundPackets1_19_4.DISPLAY_SCOREBOARD, wrapper -> {
|
registerClientbound(ClientboundPackets1_19_4.DISPLAY_SCOREBOARD, wrapper -> {
|
||||||
final byte slot = wrapper.read(Type.BYTE);
|
final byte slot = wrapper.read(Type.BYTE);
|
||||||
wrapper.write(Type.VAR_INT, (int) slot);
|
wrapper.write(Type.VAR_INT, (int) slot);
|
||||||
@ -115,7 +125,8 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
|
|||||||
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.PLUGIN_MESSAGE));
|
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.PLUGIN_MESSAGE));
|
||||||
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.KEEP_ALIVE.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.KEEP_ALIVE));
|
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.KEEP_ALIVE.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.KEEP_ALIVE));
|
||||||
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.PONG.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.PONG));
|
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.PONG.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.PONG));
|
||||||
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.RESOURCE_PACK.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.RESOURCE_PACK_STATUS));
|
// Cancel this, as it will always just be the response to a re-sent pack from us
|
||||||
|
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.RESOURCE_PACK.getId(), -1, PacketWrapper::cancel);
|
||||||
|
|
||||||
cancelClientbound(ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES); // TODO Sad emoji
|
cancelClientbound(ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES); // TODO Sad emoji
|
||||||
registerServerbound(ServerboundPackets1_20_2.CONFIGURATION_ACKNOWLEDGED, null, wrapper -> {
|
registerServerbound(ServerboundPackets1_20_2.CONFIGURATION_ACKNOWLEDGED, null, wrapper -> {
|
||||||
@ -128,7 +139,9 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
|
|||||||
|
|
||||||
// Reenter the configuration state
|
// Reenter the configuration state
|
||||||
configurationState.setBridgePhase(BridgePhase.CONFIGURATION);
|
configurationState.setBridgePhase(BridgePhase.CONFIGURATION);
|
||||||
sendConfigurationPackets(wrapper.user(), configurationState.getReenterInfo().dimensionRegistry());
|
|
||||||
|
final LastResourcePack lastResourcePack = wrapper.user().get(LastResourcePack.class);
|
||||||
|
sendConfigurationPackets(wrapper.user(), configurationState.getReenterInfo().dimensionRegistry(), lastResourcePack);
|
||||||
configurationState.setReenterInfo(null);
|
configurationState.setReenterInfo(null);
|
||||||
});
|
});
|
||||||
cancelServerbound(ServerboundPackets1_20_2.CHUNK_BATCH_RECEIVED);
|
cancelServerbound(ServerboundPackets1_20_2.CHUNK_BATCH_RECEIVED);
|
||||||
@ -165,14 +178,14 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean reentering = configurationBridge.getReenterInfo() != null;
|
|
||||||
if (direction == Direction.SERVERBOUND) {
|
if (direction == Direction.SERVERBOUND) {
|
||||||
// Client and server will be on different protocol states, pick the right client protocol state
|
// Client and server will be on different protocol states, pick the right client protocol state
|
||||||
super.transform(direction, phase == BridgePhase.PROFILE_SENT ? State.LOGIN : reentering ? State.PLAY : State.CONFIGURATION, packetWrapper);
|
super.transform(direction, phase == BridgePhase.PROFILE_SENT ? State.LOGIN
|
||||||
|
: phase == BridgePhase.REENTERING_CONFIGURATION ? State.PLAY : State.CONFIGURATION, packetWrapper);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phase == BridgePhase.PROFILE_SENT || reentering) {
|
if (phase == BridgePhase.PROFILE_SENT || phase == BridgePhase.REENTERING_CONFIGURATION) {
|
||||||
// Queue packets sent by the server while we wait for the client to transition to the configuration state
|
// Queue packets sent by the server while we wait for the client to transition to the configuration state
|
||||||
configurationBridge.addPacketToQueue(packetWrapper, true);
|
configurationBridge.addPacketToQueue(packetWrapper, true);
|
||||||
throw CancelException.generate();
|
throw CancelException.generate();
|
||||||
@ -207,14 +220,13 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
|
|||||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.KEEP_ALIVE);
|
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.KEEP_ALIVE);
|
||||||
} else if (unmappedId == ClientboundPackets1_19_4.PING.getId()) {
|
} else if (unmappedId == ClientboundPackets1_19_4.PING.getId()) {
|
||||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.PING);
|
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.PING);
|
||||||
} else if (unmappedId == ClientboundPackets1_19_4.RESOURCE_PACK.getId()) {
|
|
||||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.RESOURCE_PACK);
|
|
||||||
} else if (unmappedId == ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES.getId()) {
|
} else if (unmappedId == ClientboundPackets1_19_4.UPDATE_ENABLED_FEATURES.getId()) {
|
||||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES);
|
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES);
|
||||||
} else if (unmappedId == ClientboundPackets1_19_4.TAGS.getId()) {
|
} else if (unmappedId == ClientboundPackets1_19_4.TAGS.getId()) {
|
||||||
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_TAGS);
|
packetWrapper.setPacketType(ClientboundConfigurationPackets1_20_2.UPDATE_TAGS);
|
||||||
} else {
|
} else {
|
||||||
// Not a packet that can be mapped to the configuration protocol
|
// Not a packet that can be mapped to the configuration protocol
|
||||||
|
// Includes resource pack packets to make sure it is not applied sooner than the server expects
|
||||||
configurationBridge.addPacketToQueue(packetWrapper, true);
|
configurationBridge.addPacketToQueue(packetWrapper, true);
|
||||||
throw CancelException.generate();
|
throw CancelException.generate();
|
||||||
}
|
}
|
||||||
@ -226,7 +238,7 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
|
|||||||
super.transform(direction, State.CONFIGURATION, packetWrapper);
|
super.transform(direction, State.CONFIGURATION, packetWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendConfigurationPackets(final UserConnection connection, final CompoundTag dimensionRegistry) throws Exception {
|
public static void sendConfigurationPackets(final UserConnection connection, final CompoundTag dimensionRegistry, @Nullable final LastResourcePack lastResourcePack) throws Exception {
|
||||||
final PacketWrapper registryDataPacket = PacketWrapper.create(ClientboundConfigurationPackets1_20_2.REGISTRY_DATA, connection);
|
final PacketWrapper registryDataPacket = PacketWrapper.create(ClientboundConfigurationPackets1_20_2.REGISTRY_DATA, connection);
|
||||||
registryDataPacket.write(Type.NAMELESS_NBT, dimensionRegistry);
|
registryDataPacket.write(Type.NAMELESS_NBT, dimensionRegistry);
|
||||||
registryDataPacket.send(Protocol1_20_2To1_20.class);
|
registryDataPacket.send(Protocol1_20_2To1_20.class);
|
||||||
@ -238,6 +250,16 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
|
|||||||
enableFeaturesPacket.write(Type.STRING, "minecraft:vanilla");
|
enableFeaturesPacket.write(Type.STRING, "minecraft:vanilla");
|
||||||
enableFeaturesPacket.send(Protocol1_20_2To1_20.class);
|
enableFeaturesPacket.send(Protocol1_20_2To1_20.class);
|
||||||
|
|
||||||
|
if (lastResourcePack != null) {
|
||||||
|
// The client for some reason drops the resource pack when reentering the configuration state
|
||||||
|
final PacketWrapper resourcePackPacket = PacketWrapper.create(ClientboundConfigurationPackets1_20_2.RESOURCE_PACK, connection);
|
||||||
|
resourcePackPacket.write(Type.STRING, lastResourcePack.url());
|
||||||
|
resourcePackPacket.write(Type.STRING, lastResourcePack.hash());
|
||||||
|
resourcePackPacket.write(Type.BOOLEAN, lastResourcePack.required());
|
||||||
|
resourcePackPacket.write(Type.OPTIONAL_COMPONENT, lastResourcePack.prompt());
|
||||||
|
resourcePackPacket.send(Protocol1_20_2To1_20.class);
|
||||||
|
}
|
||||||
|
|
||||||
final PacketWrapper finishConfigurationPacket = PacketWrapper.create(ClientboundConfigurationPackets1_20_2.FINISH_CONFIGURATION, connection);
|
final PacketWrapper finishConfigurationPacket = PacketWrapper.create(ClientboundConfigurationPackets1_20_2.FINISH_CONFIGURATION, connection);
|
||||||
finishConfigurationPacket.send(Protocol1_20_2To1_20.class);
|
finishConfigurationPacket.send(Protocol1_20_2To1_20.class);
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ public final class EntityPacketRewriter1_20_2 extends EntityRewriter<Clientbound
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol1_20_2To1_20.sendConfigurationPackets(wrapper.user(), dimensionRegistry);
|
Protocol1_20_2To1_20.sendConfigurationPackets(wrapper.user(), dimensionRegistry, null);
|
||||||
|
|
||||||
// Manually send it at the end and hope nothing breaks
|
// Manually send it at the end and hope nothing breaks
|
||||||
configurationBridge.setJoinGamePacket(wrapper);
|
configurationBridge.setJoinGamePacket(wrapper);
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
||||||
|
* Copyright (C) 2023 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.viaversion.protocols.protocol1_20_2to1_20.storage;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
public final class LastResourcePack implements StorableObject {
|
||||||
|
|
||||||
|
private final String url;
|
||||||
|
private final String hash;
|
||||||
|
private final boolean required;
|
||||||
|
private final JsonElement prompt;
|
||||||
|
|
||||||
|
public LastResourcePack(final String url, final String hash, final boolean required, @Nullable final JsonElement prompt) {
|
||||||
|
this.url = url;
|
||||||
|
this.hash = hash;
|
||||||
|
this.required = required;
|
||||||
|
this.prompt = prompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String url() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String hash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean required() {
|
||||||
|
return required;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable JsonElement prompt() {
|
||||||
|
return prompt;
|
||||||
|
}
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren