13
0
geforkt von Mirrors/Velocity

Several improvements and fixes for 1.20.2 (#1097)

* Send LoginAcknowledged immediately

* Resend player list header/footer after backend server switched to config state

* Fix clearHeaderAndFooter not clearing fields in ConnectedPlayer

* Clear boss bars, header/footer, tab list when switching client to config state

* Send client settings in config state
Dieser Commit ist enthalten in:
Gero 2023-10-12 11:11:47 +02:00 committet von GitHub
Ursprung 9be0bca3c4
Commit 1cc3f120ee
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
10 geänderte Dateien mit 72 neuen und 36 gelöschten Zeilen

Datei anzeigen

@ -31,7 +31,6 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.event.HoverEventSource;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.NotNull;
/**
@ -148,10 +147,17 @@ public interface Player extends
/**
* Clears the tab list header and footer for the player.
*
* @deprecated Use {@link TabList#clearHeaderAndFooter()}.
* @deprecated Use {@link Player#clearPlayerListHeaderAndFooter()}.
*/
@Deprecated
void clearHeaderAndFooter();
default void clearHeaderAndFooter() {
clearPlayerListHeaderAndFooter();
}
/**
* Clears the player list header and footer.
*/
void clearPlayerListHeaderAndFooter();
/**
* Returns the player's player list header.

Datei anzeigen

@ -24,6 +24,7 @@ import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.connection.client.ClientConfigSessionHandler;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.connection.player.VelocityResourcePackInfo;
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
@ -152,22 +153,26 @@ public class ConfigSessionHandler implements MinecraftSessionHandler {
@Override
public boolean handle(FinishedUpdate packet) {
MinecraftConnection smc = serverConn.ensureConnected();
ConnectedPlayer player = serverConn.getPlayer();
ClientConfigSessionHandler configHandler =
(ClientConfigSessionHandler) serverConn.getPlayer().getConnection()
.getActiveSessionHandler();
(ClientConfigSessionHandler) player.getConnection().getActiveSessionHandler();
smc.setAutoReading(false);
// Even when not auto reading messages are still decoded. Decode them with the correct state
smc.getChannel().pipeline().get(MinecraftDecoder.class).setState(StateRegistry.PLAY);
configHandler.handleBackendFinishUpdate(serverConn).thenAcceptAsync((unused) -> {
if (serverConn == serverConn.getPlayer().getConnectedServer()) {
if (serverConn == player.getConnectedServer()) {
smc.setActiveSessionHandler(StateRegistry.PLAY);
player.sendPlayerListHeaderAndFooter(
player.getPlayerListHeader(), player.getPlayerListFooter());
// The client cleared the tab list. TODO: Restore changes done via TabList API
player.getTabList().clearAllSilent();
} else {
smc.setActiveSessionHandler(StateRegistry.PLAY,
new TransitionSessionHandler(server, serverConn, resultFuture));
}
if (serverConn.getPlayer().getAppliedResourcePack() == null && resourcePackToApply != null) {
serverConn.getPlayer().queueResourcePack(resourcePackToApply);
if (player.getAppliedResourcePack() == null && resourcePackToApply != null) {
player.queueResourcePack(resourcePackToApply);
}
smc.setAutoReading(true);
}, smc.eventLoop());

Datei anzeigen

@ -156,22 +156,20 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
smc.setActiveSessionHandler(StateRegistry.PLAY,
new TransitionSessionHandler(server, serverConn, resultFuture));
} else {
smc.setAutoReading(false);
CompletableFuture<Void> switchFuture;
if (serverConn.getPlayer().getConnection()
.getActiveSessionHandler() instanceof ClientPlaySessionHandler) {
switchFuture = ((ClientPlaySessionHandler) serverConn.getPlayer().getConnection()
.getActiveSessionHandler()).doSwitch();
} else {
switchFuture = CompletableFuture.completedFuture(null);
smc.write(new LoginAcknowledged());
smc.setActiveSessionHandler(StateRegistry.CONFIG,
new ConfigSessionHandler(server, serverConn, resultFuture));
ConnectedPlayer player = serverConn.getPlayer();
if (player.getClientSettingsPacket() != null) {
smc.write(player.getClientSettingsPacket());
}
if (player.getConnection().getActiveSessionHandler() instanceof ClientPlaySessionHandler) {
smc.setAutoReading(false);
((ClientPlaySessionHandler) player.getConnection()
.getActiveSessionHandler()).doSwitch().thenAcceptAsync((unused) -> {
smc.setAutoReading(true);
}, smc.eventLoop());
}
switchFuture.thenAcceptAsync((unused) -> {
smc.write(new LoginAcknowledged());
// Sync backend
smc.setActiveSessionHandler(StateRegistry.CONFIG,
new ConfigSessionHandler(server, serverConn, resultFuture));
smc.setAutoReading(true);
}, smc.eventLoop());
}
return true;

Datei anzeigen

@ -22,6 +22,7 @@ import static com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeHands
import com.velocitypowered.api.event.player.ServerConnectedEvent;
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.ConnectionTypes;
@ -104,7 +105,7 @@ public class TransitionSessionHandler implements MinecraftSessionHandler {
player.sendKeepAlive();
// Reset Tablist header and footer to prevent desync
player.clearHeaderAndFooter();
player.clearPlayerListHeaderAndFooter();
}
// The goods are in hand! We got JoinGame. Let's transition completely to the new state.
@ -143,7 +144,9 @@ public class TransitionSessionHandler implements MinecraftSessionHandler {
// Now set the connected server.
serverConn.getPlayer().setConnectedServer(serverConn);
if (player.getClientSettingsPacket() != null) {
// Send client settings. In 1.20.2+ this is done in the config state.
if (smc.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_20_2) < 0
&& player.getClientSettingsPacket() != null) {
serverConn.ensureConnected().write(player.getClientSettingsPacket());
}

Datei anzeigen

@ -482,12 +482,13 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
// Send keep alive to try to avoid timeouts
player.sendKeepAlive();
// Reset Tablist header and footer to prevent desync
player.clearHeaderAndFooter();
// Config state clears everything in the client. No need to clear later.
spawned = false;
serverBossBars.clear();
player.clearPlayerListHeaderAndFooterSilent();
player.getTabList().clearAllSilent();
}
spawned = false;
player.switchToConfigState();
return configSwitchFuture;

Datei anzeigen

@ -544,8 +544,16 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player,
}
@Override
public void clearHeaderAndFooter() {
tabList.clearHeaderAndFooter();
public void clearPlayerListHeaderAndFooter() {
clearPlayerListHeaderAndFooterSilent();
if (this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
this.connection.write(HeaderAndFooter.reset());
}
}
public void clearPlayerListHeaderAndFooterSilent() {
this.playerListHeader = Component.empty();
this.playerListFooter = Component.empty();
}
@Override

Datei anzeigen

@ -35,4 +35,6 @@ public interface InternalTabList extends TabList {
default void processRemove(RemovePlayerInfo infoPacket) {
}
void clearAllSilent();
}

Datei anzeigen

@ -26,7 +26,6 @@ import com.velocitypowered.api.proxy.player.TabListEntry;
import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.packet.HeaderAndFooter;
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItem;
import com.velocitypowered.proxy.protocol.packet.chat.RemoteChatSession;
import java.util.ArrayList;
@ -70,7 +69,7 @@ public class KeyedVelocityTabList implements InternalTabList {
@Override
public void clearHeaderAndFooter() {
connection.write(HeaderAndFooter.reset());
this.player.clearPlayerListHeaderAndFooter();
}
@Override
@ -131,10 +130,15 @@ public class KeyedVelocityTabList implements InternalTabList {
for (TabListEntry value : listEntries) {
items.add(LegacyPlayerListItem.Item.from(value));
}
entries.clear();
clearAllSilent();
connection.delayedWrite(new LegacyPlayerListItem(LegacyPlayerListItem.REMOVE_PLAYER, items));
}
@Override
public void clearAllSilent() {
entries.clear();
}
@Override
public Collection<TabListEntry> getEntries() {
return Collections.unmodifiableCollection(this.entries.values());

Datei anzeigen

@ -25,7 +25,6 @@ import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.console.VelocityConsole;
import com.velocitypowered.proxy.protocol.packet.HeaderAndFooter;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo;
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo;
import com.velocitypowered.proxy.protocol.packet.chat.RemoteChatSession;
@ -74,7 +73,7 @@ public class VelocityTabList implements InternalTabList {
@Override
public void clearHeaderAndFooter() {
connection.write(HeaderAndFooter.reset());
this.player.clearPlayerListHeaderAndFooter();
}
@Override
@ -175,6 +174,11 @@ public class VelocityTabList implements InternalTabList {
@Override
public void clearAll() {
this.connection.delayedWrite(new RemovePlayerInfo(new ArrayList<>(this.entries.keySet())));
clearAllSilent();
}
@Override
public void clearAllSilent() {
this.entries.clear();
}

Datei anzeigen

@ -71,6 +71,11 @@ public class VelocityTabListLegacy extends KeyedVelocityTabList {
connection.delayedWrite(new LegacyPlayerListItem(LegacyPlayerListItem.REMOVE_PLAYER,
Collections.singletonList(LegacyPlayerListItem.Item.from(value))));
}
clearAllSilent();
}
@Override
public void clearAllSilent() {
entries.clear();
nameMapping.clear();
}