Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove most-times unnecessary client reconfiguration #1477

Draft
wants to merge 1 commit into
base: dev/3.0.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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