Skip to content

Commit b738682

Browse files
committed
Remove most-times unnecessary client reconfiguration
1 parent 4aa9ee7 commit b738682

8 files changed

+227
-28
lines changed

proxy/src/main/java/com/velocitypowered/proxy/connection/MinecraftSessionHandler.java

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.velocitypowered.proxy.protocol.packet.LoginAcknowledgedPacket;
3838
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessagePacket;
3939
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponsePacket;
40+
import com.velocitypowered.proxy.protocol.packet.ObjectivePacket;
4041
import com.velocitypowered.proxy.protocol.packet.PingIdentifyPacket;
4142
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
4243
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfoPacket;
@@ -364,4 +365,8 @@ default boolean handle(ClientboundCustomReportDetailsPacket packet) {
364365
default boolean handle(ClientboundServerLinksPacket packet) {
365366
return false;
366367
}
368+
369+
default boolean handle(ObjectivePacket packet) {
370+
return false;
371+
}
367372
}

proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java

+11
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
5757
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
5858
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItemPacket;
59+
import com.velocitypowered.proxy.protocol.packet.ObjectivePacket;
5960
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
6061
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfoPacket;
6162
import com.velocitypowered.proxy.protocol.packet.RemoveResourcePackPacket;
@@ -183,6 +184,16 @@ public boolean handle(BossBarPacket packet) {
183184
return false; // forward
184185
}
185186

187+
@Override
188+
public boolean handle(ObjectivePacket packet) {
189+
if (packet.getAction() == ObjectivePacket.ADD) {
190+
playerSessionHandler.getServerObjectives().add(packet.getName());
191+
} else if (packet.getAction() == ObjectivePacket.REMOVE) {
192+
playerSessionHandler.getServerObjectives().remove(packet.getName());
193+
}
194+
return false; // forward
195+
}
196+
186197
@Override
187198
public boolean handle(final ResourcePackRequestPacket packet) {
188199
final ResourcePackInfo.Builder builder = new VelocityResourcePackInfo.BuilderImpl(

proxy/src/main/java/com/velocitypowered/proxy/connection/backend/ConfigSessionHandler.java

+45-15
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
3737
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
3838
import com.velocitypowered.proxy.protocol.MinecraftPacket;
39+
import com.velocitypowered.proxy.protocol.ProtocolUtils;
3940
import com.velocitypowered.proxy.protocol.StateRegistry;
4041
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
4142
import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
@@ -50,13 +51,16 @@
5051
import com.velocitypowered.proxy.protocol.packet.config.ClientboundCustomReportDetailsPacket;
5152
import com.velocitypowered.proxy.protocol.packet.config.ClientboundServerLinksPacket;
5253
import com.velocitypowered.proxy.protocol.packet.config.FinishedUpdatePacket;
54+
import com.velocitypowered.proxy.protocol.packet.config.KnownPacksPacket;
5355
import com.velocitypowered.proxy.protocol.packet.config.RegistrySyncPacket;
5456
import com.velocitypowered.proxy.protocol.packet.config.StartUpdatePacket;
5557
import com.velocitypowered.proxy.protocol.packet.config.TagsUpdatePacket;
5658
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
5759
import java.io.IOException;
5860
import java.net.InetSocketAddress;
5961
import java.util.concurrent.CompletableFuture;
62+
import io.netty.buffer.ByteBuf;
63+
import io.netty.buffer.Unpooled;
6064
import net.kyori.adventure.key.Key;
6165
import org.apache.logging.log4j.LogManager;
6266
import org.apache.logging.log4j.Logger;
@@ -226,24 +230,21 @@ public boolean handle(RemoveResourcePackPacket packet) {
226230
public boolean handle(FinishedUpdatePacket packet) {
227231
final MinecraftConnection smc = serverConn.ensureConnected();
228232
final ConnectedPlayer player = serverConn.getPlayer();
229-
final ClientConfigSessionHandler configHandler = (ClientConfigSessionHandler) player.getConnection().getActiveSessionHandler();
230233

231234
smc.getChannel().pipeline().get(MinecraftDecoder.class).setState(StateRegistry.PLAY);
232-
//noinspection DataFlowIssue
233-
configHandler.handleBackendFinishUpdate(serverConn).thenRunAsync(() -> {
234-
smc.write(FinishedUpdatePacket.INSTANCE);
235-
if (serverConn == player.getConnectedServer()) {
236-
smc.setActiveSessionHandler(StateRegistry.PLAY);
237-
player.sendPlayerListHeaderAndFooter(player.getPlayerListHeader(), player.getPlayerListFooter());
238-
// The client cleared the tab list. TODO: Restore changes done via TabList API
239-
player.getTabList().clearAllSilent();
240-
} else {
241-
smc.setActiveSessionHandler(StateRegistry.PLAY, new TransitionSessionHandler(server, serverConn, resultFuture));
242-
}
243-
if (player.resourcePackHandler().getFirstAppliedPack() == null && resourcePackToApply != null) {
244-
player.resourcePackHandler().queueResourcePack(resourcePackToApply);
235+
if (player.getConnection().getActiveSessionHandler() instanceof ClientConfigSessionHandler configHandler) {
236+
configHandler.handleBackendFinishUpdate(serverConn).thenRunAsync(this::finish, smc.eventLoop());
237+
} else {
238+
final String brand = serverConn.getPlayer().getClientBrand();
239+
if (brand != null) {
240+
final ByteBuf buf = Unpooled.buffer();
241+
ProtocolUtils.writeString(buf, brand);
242+
final PluginMessagePacket brandPacket = new PluginMessagePacket("minecraft:brand", buf);
243+
smc.write(brandPacket);
245244
}
246-
}, smc.eventLoop());
245+
246+
finish();
247+
}
247248
return true;
248249
}
249250

@@ -296,6 +297,17 @@ public boolean handle(TransferPacket packet) {
296297
return true;
297298
}
298299

300+
@Override
301+
public boolean handle(KnownPacksPacket packet) {
302+
// Server expects us to reply to this packet
303+
if (serverConn.getPlayer().getConnection().getState() != StateRegistry.CONFIG) {
304+
// TODO: just replay the first packet the user sent
305+
serverConn.ensureConnected().write(packet);
306+
return true;
307+
}
308+
return false; // forward
309+
}
310+
299311
@Override
300312
public boolean handle(ClientboundStoreCookiePacket packet) {
301313
server.getEventManager()
@@ -348,6 +360,24 @@ private void switchFailure(Throwable cause) {
348360
resultFuture.completeExceptionally(cause);
349361
}
350362

363+
private void finish() {
364+
final MinecraftConnection smc = serverConn.ensureConnected();
365+
final ConnectedPlayer player = serverConn.getPlayer();
366+
367+
smc.write(FinishedUpdatePacket.INSTANCE);
368+
if (serverConn == player.getConnectedServer()) {
369+
smc.setActiveSessionHandler(StateRegistry.PLAY);
370+
player.sendPlayerListHeaderAndFooter(player.getPlayerListHeader(), player.getPlayerListFooter());
371+
// The client cleared the tab list. TODO: Restore changes done via TabList API
372+
player.getTabList().clearAllSilent();
373+
} else {
374+
smc.setActiveSessionHandler(StateRegistry.PLAY, new TransitionSessionHandler(server, serverConn, resultFuture));
375+
}
376+
if (player.resourcePackHandler().getFirstAppliedPack() == null && resourcePackToApply != null) {
377+
player.resourcePackHandler().queueResourcePack(resourcePackToApply);
378+
}
379+
}
380+
351381
/**
352382
* Represents the state of the configuration stage.
353383
*/

proxy/src/main/java/com/velocitypowered/proxy/connection/backend/LoginSessionHandler.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,7 @@ public boolean handle(ServerLoginSuccessPacket packet) {
163163
if (player.getClientSettingsPacket() != null) {
164164
smc.write(player.getClientSettingsPacket());
165165
}
166-
if (player.getConnection().getActiveSessionHandler() instanceof ClientPlaySessionHandler clientPlaySessionHandler) {
167-
smc.setAutoReading(false);
168-
clientPlaySessionHandler.doSwitch().thenAcceptAsync((unused) -> smc.setAutoReading(true), smc.eventLoop());
169-
} else {
166+
if (!(player.getConnection().getActiveSessionHandler() instanceof ClientPlaySessionHandler)) {
170167
// Initial login - the player is already in configuration state.
171168
server.getEventManager().fireAndForget(new PlayerEnteredConfigurationEvent(player, serverConn));
172169
}

proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientConfigSessionHandler.java

+7-9
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,9 @@ public boolean handle(final PluginMessagePacket packet) {
125125
// but at this time the backend server may not be ready
126126
} else if (serverConn != null) {
127127
serverConn.ensureConnected().write(packet.retain());
128+
return true;
128129
}
129-
return true;
130+
return false;
130131
}
131132

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

142143
@Override
143144
public boolean handle(KnownPacksPacket packet) {
144-
callConfigurationEvent().thenRun(() -> {
145-
player.getConnectionInFlightOrConnectedServer().ensureConnected().write(packet);
146-
}).exceptionally(ex -> {
147-
logger.error("Error forwarding known packs response to backend:", ex);
148-
return null;
149-
});
150-
151-
return true;
145+
if (player.getConnectionInFlight() != null) {
146+
player.getConnectionInFlight().ensureConnected().write(packet);
147+
return true;
148+
}
149+
return false;
152150
}
153151

154152
@Override

proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java

+16
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
4848
import com.velocitypowered.proxy.protocol.packet.JoinGamePacket;
4949
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
50+
import com.velocitypowered.proxy.protocol.packet.ObjectivePacket;
5051
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
5152
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
5253
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
@@ -81,8 +82,10 @@
8182
import java.time.Instant;
8283
import java.util.ArrayList;
8384
import java.util.Collection;
85+
import java.util.HashSet;
8486
import java.util.List;
8587
import java.util.Queue;
88+
import java.util.Set;
8689
import java.util.UUID;
8790
import java.util.concurrent.CompletableFuture;
8891
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -104,6 +107,7 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
104107
private final ConnectedPlayer player;
105108
private boolean spawned = false;
106109
private final List<UUID> serverBossBars = new ArrayList<>();
110+
private final Set<String> serverObjectives = new HashSet<>();
107111
private final Queue<PluginMessagePacket> loginPluginMessages = new ConcurrentLinkedQueue<>();
108112
private final VelocityServer server;
109113
private @Nullable TabCompleteRequestPacket outstandingTabComplete;
@@ -526,6 +530,7 @@ public CompletableFuture<Void> doSwitch() {
526530
// Config state clears everything in the client. No need to clear later.
527531
spawned = false;
528532
serverBossBars.clear();
533+
serverObjectives.clear();
529534
player.clearPlayerListHeaderAndFooterSilent();
530535
player.getTabList().clearAllSilent();
531536
}
@@ -574,6 +579,13 @@ public void handleBackendJoinGame(JoinGamePacket joinGame, VelocityServerConnect
574579
player.getConnection().delayedWrite(deletePacket);
575580
}
576581
serverBossBars.clear();
582+
for (String serverObjective : serverObjectives) {
583+
ObjectivePacket deletePacket = new ObjectivePacket();
584+
deletePacket.setName(serverObjective);
585+
deletePacket.setAction(ObjectivePacket.REMOVE);
586+
player.getConnection().delayedWrite(deletePacket);
587+
}
588+
serverObjectives.clear();
577589

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

660+
public Set<String> getServerObjectives() {
661+
return serverObjectives;
662+
}
663+
648664
private boolean handleCommandTabComplete(TabCompleteRequestPacket packet) {
649665
// In 1.13+, we need to do additional work for the richer suggestions available.
650666
String command = packet.getCommand().substring(1);

proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java

+19
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
import com.velocitypowered.proxy.protocol.packet.LoginAcknowledgedPacket;
6969
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessagePacket;
7070
import com.velocitypowered.proxy.protocol.packet.LoginPluginResponsePacket;
71+
import com.velocitypowered.proxy.protocol.packet.ObjectivePacket;
7172
import com.velocitypowered.proxy.protocol.packet.PingIdentifyPacket;
7273
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
7374
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfoPacket;
@@ -706,6 +707,24 @@ public enum StateRegistry {
706707
ClientboundServerLinksPacket::new,
707708
map(0x7B, MINECRAFT_1_21, false),
708709
map(0x82, MINECRAFT_1_21_2, false));
710+
clientbound.register(
711+
ObjectivePacket.class,
712+
ObjectivePacket::new,
713+
map(0x3B, MINECRAFT_1_8, false),
714+
map(0x3F, MINECRAFT_1_9, false),
715+
map(0x41, MINECRAFT_1_12, false),
716+
map(0x42, MINECRAFT_1_12_1, false),
717+
map(0x45, MINECRAFT_1_13, false),
718+
map(0x49, MINECRAFT_1_14, false),
719+
map(0x4A, MINECRAFT_1_15, false),
720+
map(0x53, MINECRAFT_1_17, false),
721+
map(0x56, MINECRAFT_1_19_1, false),
722+
map(0x54, MINECRAFT_1_19_3, false),
723+
map(0x58, MINECRAFT_1_19_4, false),
724+
map(0x5A, MINECRAFT_1_20_2, false),
725+
map(0x5C, MINECRAFT_1_20_3, false),
726+
map(0x5E, MINECRAFT_1_20_5, false),
727+
map(0x64, MINECRAFT_1_21_2, false));
709728
}
710729
},
711730
LOGIN {

0 commit comments

Comments
 (0)