Skip to content

Commit

Permalink
Remove most-times unnecessary client reconfiguration
Browse files Browse the repository at this point in the history
  • Loading branch information
valaphee committed Dec 17, 2024
1 parent 4aa9ee7 commit b738682
Show file tree
Hide file tree
Showing 8 changed files with 227 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.velocitypowered.proxy.protocol.packet.LoginAcknowledgedPacket;
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessagePacket;
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponsePacket;
import com.velocitypowered.proxy.protocol.packet.ObjectivePacket;
import com.velocitypowered.proxy.protocol.packet.PingIdentifyPacket;
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfoPacket;
Expand Down Expand Up @@ -364,4 +365,8 @@ default boolean handle(ClientboundCustomReportDetailsPacket packet) {
default boolean handle(ClientboundServerLinksPacket packet) {
return false;
}

default boolean handle(ObjectivePacket packet) {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItemPacket;
import com.velocitypowered.proxy.protocol.packet.ObjectivePacket;
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfoPacket;
import com.velocitypowered.proxy.protocol.packet.RemoveResourcePackPacket;
Expand Down Expand Up @@ -183,6 +184,16 @@ public boolean handle(BossBarPacket packet) {
return false; // forward
}

@Override
public boolean handle(ObjectivePacket packet) {
if (packet.getAction() == ObjectivePacket.ADD) {
playerSessionHandler.getServerObjectives().add(packet.getName());
} else if (packet.getAction() == ObjectivePacket.REMOVE) {
playerSessionHandler.getServerObjectives().remove(packet.getName());
}
return false; // forward
}

@Override
public boolean handle(final ResourcePackRequestPacket packet) {
final ResourcePackInfo.Builder builder = new VelocityResourcePackInfo.BuilderImpl(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.StateRegistry;
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
Expand All @@ -50,13 +51,16 @@
import com.velocitypowered.proxy.protocol.packet.config.ClientboundCustomReportDetailsPacket;
import com.velocitypowered.proxy.protocol.packet.config.ClientboundServerLinksPacket;
import com.velocitypowered.proxy.protocol.packet.config.FinishedUpdatePacket;
import com.velocitypowered.proxy.protocol.packet.config.KnownPacksPacket;
import com.velocitypowered.proxy.protocol.packet.config.RegistrySyncPacket;
import com.velocitypowered.proxy.protocol.packet.config.StartUpdatePacket;
import com.velocitypowered.proxy.protocol.packet.config.TagsUpdatePacket;
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.CompletableFuture;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.kyori.adventure.key.Key;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -226,24 +230,21 @@ public boolean handle(RemoveResourcePackPacket packet) {
public boolean handle(FinishedUpdatePacket packet) {
final MinecraftConnection smc = serverConn.ensureConnected();
final ConnectedPlayer player = serverConn.getPlayer();
final ClientConfigSessionHandler configHandler = (ClientConfigSessionHandler) player.getConnection().getActiveSessionHandler();

smc.getChannel().pipeline().get(MinecraftDecoder.class).setState(StateRegistry.PLAY);
//noinspection DataFlowIssue
configHandler.handleBackendFinishUpdate(serverConn).thenRunAsync(() -> {
smc.write(FinishedUpdatePacket.INSTANCE);
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 (player.resourcePackHandler().getFirstAppliedPack() == null && resourcePackToApply != null) {
player.resourcePackHandler().queueResourcePack(resourcePackToApply);
if (player.getConnection().getActiveSessionHandler() instanceof ClientConfigSessionHandler configHandler) {
configHandler.handleBackendFinishUpdate(serverConn).thenRunAsync(this::finish, smc.eventLoop());
} else {
final String brand = serverConn.getPlayer().getClientBrand();
if (brand != null) {
final ByteBuf buf = Unpooled.buffer();
ProtocolUtils.writeString(buf, brand);
final PluginMessagePacket brandPacket = new PluginMessagePacket("minecraft:brand", buf);
smc.write(brandPacket);
}
}, smc.eventLoop());

finish();
}
return true;
}

Expand Down Expand Up @@ -296,6 +297,17 @@ public boolean handle(TransferPacket packet) {
return true;
}

@Override
public boolean handle(KnownPacksPacket packet) {
// Server expects us to reply to this packet
if (serverConn.getPlayer().getConnection().getState() != StateRegistry.CONFIG) {
// TODO: just replay the first packet the user sent
serverConn.ensureConnected().write(packet);
return true;
}
return false; // forward
}

@Override
public boolean handle(ClientboundStoreCookiePacket packet) {
server.getEventManager()
Expand Down Expand Up @@ -348,6 +360,24 @@ private void switchFailure(Throwable cause) {
resultFuture.completeExceptionally(cause);
}

private void finish() {
final MinecraftConnection smc = serverConn.ensureConnected();
final ConnectedPlayer player = serverConn.getPlayer();

smc.write(FinishedUpdatePacket.INSTANCE);
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 (player.resourcePackHandler().getFirstAppliedPack() == null && resourcePackToApply != null) {
player.resourcePackHandler().queueResourcePack(resourcePackToApply);
}
}

/**
* Represents the state of the configuration stage.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,7 @@ public boolean handle(ServerLoginSuccessPacket packet) {
if (player.getClientSettingsPacket() != null) {
smc.write(player.getClientSettingsPacket());
}
if (player.getConnection().getActiveSessionHandler() instanceof ClientPlaySessionHandler clientPlaySessionHandler) {
smc.setAutoReading(false);
clientPlaySessionHandler.doSwitch().thenAcceptAsync((unused) -> smc.setAutoReading(true), smc.eventLoop());
} else {
if (!(player.getConnection().getActiveSessionHandler() instanceof ClientPlaySessionHandler)) {
// Initial login - the player is already in configuration state.
server.getEventManager().fireAndForget(new PlayerEnteredConfigurationEvent(player, serverConn));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,9 @@ public boolean handle(final PluginMessagePacket packet) {
// but at this time the backend server may not be ready
} else if (serverConn != null) {
serverConn.ensureConnected().write(packet.retain());
return true;
}
return true;
return false;
}

@Override
Expand All @@ -141,14 +142,11 @@ public boolean handle(PingIdentifyPacket packet) {

@Override
public boolean handle(KnownPacksPacket packet) {
callConfigurationEvent().thenRun(() -> {
player.getConnectionInFlightOrConnectedServer().ensureConnected().write(packet);
}).exceptionally(ex -> {
logger.error("Error forwarding known packs response to backend:", ex);
return null;
});

return true;
if (player.getConnectionInFlight() != null) {
player.getConnectionInFlight().ensureConnected().write(packet);
return true;
}
return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
import com.velocitypowered.proxy.protocol.packet.ObjectivePacket;
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
Expand Down Expand Up @@ -81,8 +82,10 @@
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
Expand All @@ -104,6 +107,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
private final ConnectedPlayer player;
private boolean spawned = false;
private final List<UUID> serverBossBars = new ArrayList<>();
private final Set<String> serverObjectives = new HashSet<>();
private final Queue<PluginMessagePacket> loginPluginMessages = new ConcurrentLinkedQueue<>();
private final VelocityServer server;
private @Nullable TabCompleteRequestPacket outstandingTabComplete;
Expand Down Expand Up @@ -526,6 +530,7 @@ public CompletableFuture<Void> doSwitch() {
// Config state clears everything in the client. No need to clear later.
spawned = false;
serverBossBars.clear();
serverObjectives.clear();
player.clearPlayerListHeaderAndFooterSilent();
player.getTabList().clearAllSilent();
}
Expand Down Expand Up @@ -574,6 +579,13 @@ public void handleBackendJoinGame(JoinGamePacket joinGame, VelocityServerConnect
player.getConnection().delayedWrite(deletePacket);
}
serverBossBars.clear();
for (String serverObjective : serverObjectives) {
ObjectivePacket deletePacket = new ObjectivePacket();
deletePacket.setName(serverObjective);
deletePacket.setAction(ObjectivePacket.REMOVE);
player.getConnection().delayedWrite(deletePacket);
}
serverObjectives.clear();

// Tell the server about the proxy's plugin message channels.
ProtocolVersion serverVersion = serverMc.getProtocolVersion();
Expand Down Expand Up @@ -645,6 +657,10 @@ public List<UUID> getServerBossBars() {
return serverBossBars;
}

public Set<String> getServerObjectives() {
return serverObjectives;
}

private boolean handleCommandTabComplete(TabCompleteRequestPacket packet) {
// In 1.13+, we need to do additional work for the richer suggestions available.
String command = packet.getCommand().substring(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import com.velocitypowered.proxy.protocol.packet.LoginAcknowledgedPacket;
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessagePacket;
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponsePacket;
import com.velocitypowered.proxy.protocol.packet.ObjectivePacket;
import com.velocitypowered.proxy.protocol.packet.PingIdentifyPacket;
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfoPacket;
Expand Down Expand Up @@ -706,6 +707,24 @@ public enum StateRegistry {
ClientboundServerLinksPacket::new,
map(0x7B, MINECRAFT_1_21, false),
map(0x82, MINECRAFT_1_21_2, false));
clientbound.register(
ObjectivePacket.class,
ObjectivePacket::new,
map(0x3B, MINECRAFT_1_8, false),
map(0x3F, MINECRAFT_1_9, false),
map(0x41, MINECRAFT_1_12, false),
map(0x42, MINECRAFT_1_12_1, false),
map(0x45, MINECRAFT_1_13, false),
map(0x49, MINECRAFT_1_14, false),
map(0x4A, MINECRAFT_1_15, false),
map(0x53, MINECRAFT_1_17, false),
map(0x56, MINECRAFT_1_19_1, false),
map(0x54, MINECRAFT_1_19_3, false),
map(0x58, MINECRAFT_1_19_4, false),
map(0x5A, MINECRAFT_1_20_2, false),
map(0x5C, MINECRAFT_1_20_3, false),
map(0x5E, MINECRAFT_1_20_5, false),
map(0x64, MINECRAFT_1_21_2, false));
}
},
LOGIN {
Expand Down
Loading

0 comments on commit b738682

Please sign in to comment.