|
36 | 36 | import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
|
37 | 37 | import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
38 | 38 | import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
| 39 | +import com.velocitypowered.proxy.protocol.ProtocolUtils; |
39 | 40 | import com.velocitypowered.proxy.protocol.StateRegistry;
|
40 | 41 | import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
41 | 42 | import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
|
|
50 | 51 | import com.velocitypowered.proxy.protocol.packet.config.ClientboundCustomReportDetailsPacket;
|
51 | 52 | import com.velocitypowered.proxy.protocol.packet.config.ClientboundServerLinksPacket;
|
52 | 53 | import com.velocitypowered.proxy.protocol.packet.config.FinishedUpdatePacket;
|
| 54 | +import com.velocitypowered.proxy.protocol.packet.config.KnownPacksPacket; |
53 | 55 | import com.velocitypowered.proxy.protocol.packet.config.RegistrySyncPacket;
|
54 | 56 | import com.velocitypowered.proxy.protocol.packet.config.StartUpdatePacket;
|
55 | 57 | import com.velocitypowered.proxy.protocol.packet.config.TagsUpdatePacket;
|
56 | 58 | import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
57 | 59 | import java.io.IOException;
|
58 | 60 | import java.net.InetSocketAddress;
|
59 | 61 | import java.util.concurrent.CompletableFuture;
|
| 62 | +import io.netty.buffer.ByteBuf; |
| 63 | +import io.netty.buffer.Unpooled; |
60 | 64 | import net.kyori.adventure.key.Key;
|
61 | 65 | import org.apache.logging.log4j.LogManager;
|
62 | 66 | import org.apache.logging.log4j.Logger;
|
@@ -226,24 +230,21 @@ public boolean handle(RemoveResourcePackPacket packet) {
|
226 | 230 | public boolean handle(FinishedUpdatePacket packet) {
|
227 | 231 | final MinecraftConnection smc = serverConn.ensureConnected();
|
228 | 232 | final ConnectedPlayer player = serverConn.getPlayer();
|
229 |
| - final ClientConfigSessionHandler configHandler = (ClientConfigSessionHandler) player.getConnection().getActiveSessionHandler(); |
230 | 233 |
|
231 | 234 | 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); |
245 | 244 | }
|
246 |
| - }, smc.eventLoop()); |
| 245 | + |
| 246 | + finish(); |
| 247 | + } |
247 | 248 | return true;
|
248 | 249 | }
|
249 | 250 |
|
@@ -296,6 +297,17 @@ public boolean handle(TransferPacket packet) {
|
296 | 297 | return true;
|
297 | 298 | }
|
298 | 299 |
|
| 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 | + |
299 | 311 | @Override
|
300 | 312 | public boolean handle(ClientboundStoreCookiePacket packet) {
|
301 | 313 | server.getEventManager()
|
@@ -348,6 +360,24 @@ private void switchFailure(Throwable cause) {
|
348 | 360 | resultFuture.completeExceptionally(cause);
|
349 | 361 | }
|
350 | 362 |
|
| 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 | + |
351 | 381 | /**
|
352 | 382 | * Represents the state of the configuration stage.
|
353 | 383 | */
|
|
0 commit comments