Skip to content

Commit 3a2e3bb

Browse files
authored
Synchronize transition from PLAY to CONFIG state (#126)
1 parent 5b31c09 commit 3a2e3bb

File tree

6 files changed

+121
-43
lines changed

6 files changed

+121
-43
lines changed

plugin/src/main/java/net/elytrium/limboapi/injection/login/LoginListener.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
import net.elytrium.limboapi.injection.dummy.ClosedChannel;
7777
import net.elytrium.limboapi.injection.dummy.ClosedMinecraftConnection;
7878
import net.elytrium.limboapi.injection.dummy.DummyEventPool;
79+
import net.elytrium.limboapi.injection.login.confirmation.ConfirmHandler;
80+
import net.elytrium.limboapi.injection.login.confirmation.LoginConfirmHandler;
7981
import net.elytrium.limboapi.injection.packet.ServerLoginSuccessHook;
8082
import net.kyori.adventure.text.Component;
8183
import net.kyori.adventure.text.format.NamedTextColor;
@@ -134,7 +136,7 @@ public void hookLoginSession(GameProfileRequestEvent event) throws Throwable {
134136
MC_CONNECTION_FIELD.set(handler, CLOSED_MINECRAFT_CONNECTION);
135137

136138
if (connection.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_20_2) >= 0) {
137-
connection.setActiveSessionHandler(StateRegistry.LOGIN, new LoginTrackHandler(connection));
139+
connection.setActiveSessionHandler(StateRegistry.LOGIN, new LoginConfirmHandler(connection));
138140
}
139141

140142
// From Velocity.
@@ -151,7 +153,7 @@ public void hookLoginSession(GameProfileRequestEvent event) throws Throwable {
151153
inboundConnection.getIdentifiedKey()
152154
);
153155
if (connection.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_20_2) >= 0) {
154-
((LoginTrackHandler) connection.getActiveSessionHandler()).setPlayer(player);
156+
((ConfirmHandler) connection.getActiveSessionHandler()).setPlayer(player);
155157
}
156158
if (this.server.canRegisterConnection(player)) {
157159
if (!connection.isClosed()) {

plugin/src/main/java/net/elytrium/limboapi/injection/login/LoginTasksQueue.java

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
import net.elytrium.limboapi.LimboAPI;
7575
import net.elytrium.limboapi.api.event.SafeGameProfileRequestEvent;
7676
import net.elytrium.limboapi.injection.event.EventManagerHook;
77+
import net.elytrium.limboapi.injection.login.confirmation.ConfirmHandler;
78+
import net.elytrium.limboapi.injection.login.confirmation.TransitionConfirmHandler;
7779
import net.kyori.adventure.text.Component;
7880
import org.slf4j.Logger;
7981

@@ -241,21 +243,13 @@ private void initialize(MinecraftConnection connection) throws Throwable {
241243
this.player.disconnect0(reason.get(), true);
242244
} else {
243245
if (this.server.registerConnection(this.player)) {
244-
if (connection.getActiveSessionHandler() instanceof LoginTrackHandler) {
245-
LoginTrackHandler track = (LoginTrackHandler) connection.getActiveSessionHandler();
246-
track.waitForConfirmation(() -> {
247-
try {
248-
this.connectToServer(logger, connection);
249-
} catch (Throwable e) {
250-
throw new ReflectionException(e);
251-
}
246+
if (connection.getActiveSessionHandler() instanceof ConfirmHandler) {
247+
ConfirmHandler confirm = (ConfirmHandler) connection.getActiveSessionHandler();
248+
confirm.waitForConfirmation(() -> {
249+
this.connectToServer(logger, this.player, connection);
252250
});
253251
} else {
254-
try {
255-
this.connectToServer(logger, connection);
256-
} catch (Throwable e) {
257-
throw new ReflectionException(e);
258-
}
252+
this.connectToServer(logger, this.player, connection);
259253
}
260254
} else {
261255
this.player.disconnect0(Component.translatable("velocity.error.already-connected-proxy"), true);
@@ -268,13 +262,27 @@ private void initialize(MinecraftConnection connection) throws Throwable {
268262
});
269263
}
270264

271-
private void connectToServer(Logger logger, MinecraftConnection connection) throws Throwable {
265+
private void connectToServer(Logger logger, ConnectedPlayer player, MinecraftConnection connection) {
272266
if (connection.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_20_2) < 0) {
273-
connection.setActiveSessionHandler(connection.getState(),
274-
(InitialConnectSessionHandler) INITIAL_CONNECT_SESSION_HANDLER_CONSTRUCTOR.invokeExact(this.player, this.server));
267+
try {
268+
connection.setActiveSessionHandler(connection.getState(),
269+
(InitialConnectSessionHandler) INITIAL_CONNECT_SESSION_HANDLER_CONSTRUCTOR.invokeExact(this.player, this.server));
270+
} catch (Throwable e) {
271+
throw new ReflectionException(e);
272+
}
275273
} else {
276274
if (connection.getState() == StateRegistry.PLAY) {
277275
connection.write(new StartUpdate());
276+
277+
TransitionConfirmHandler confirm = new TransitionConfirmHandler(connection);
278+
confirm.setPlayer(player);
279+
280+
connection.setActiveSessionHandler(StateRegistry.PLAY, confirm);
281+
confirm.waitForConfirmation(() -> {
282+
this.connectToServer(logger, player, connection);
283+
});
284+
285+
return;
278286
}
279287

280288
connection.setActiveSessionHandler(StateRegistry.CONFIG,

plugin/src/main/java/net/elytrium/limboapi/injection/login/LoginTrackHandler.java renamed to plugin/src/main/java/net/elytrium/limboapi/injection/login/confirmation/ConfirmHandler.java

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,13 @@
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18-
package net.elytrium.limboapi.injection.login;
18+
package net.elytrium.limboapi.injection.login.confirmation;
1919

2020
import com.velocitypowered.proxy.connection.MinecraftConnection;
2121
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
2222
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
2323
import com.velocitypowered.proxy.protocol.MinecraftPacket;
2424
import com.velocitypowered.proxy.protocol.StateRegistry;
25-
import com.velocitypowered.proxy.protocol.packet.LoginAcknowledged;
26-
import io.netty.buffer.ByteBuf;
2725
import io.netty.channel.ChannelHandlerContext;
2826
import io.netty.util.ReferenceCountUtil;
2927
import io.netty.util.internal.PlatformDependent;
@@ -35,16 +33,16 @@
3533
import net.elytrium.commons.utils.reflection.ReflectionException;
3634
import net.elytrium.limboapi.LimboAPI;
3735

38-
public class LoginTrackHandler implements MinecraftSessionHandler {
36+
public abstract class ConfirmHandler implements MinecraftSessionHandler {
3937

4038
private static final MethodHandle TEARDOWN_METHOD;
4139

42-
private final CompletableFuture<Object> confirmation = new CompletableFuture<>();
43-
private final Queue<MinecraftPacket> queuedPackets = PlatformDependent.newMpscQueue();
44-
private final MinecraftConnection connection;
45-
private ConnectedPlayer player;
40+
protected final CompletableFuture<Object> confirmation = new CompletableFuture<>();
41+
protected final Queue<MinecraftPacket> queuedPackets = PlatformDependent.newMpscQueue();
42+
protected final MinecraftConnection connection;
43+
protected ConnectedPlayer player;
4644

47-
public LoginTrackHandler(MinecraftConnection connection) {
45+
public ConfirmHandler(MinecraftConnection connection) {
4846
this.connection = connection;
4947
}
5048

@@ -63,18 +61,6 @@ public void handleGeneric(MinecraftPacket packet) {
6361
}
6462
}
6563

66-
@Override
67-
public boolean handle(LoginAcknowledged packet) {
68-
this.connection.setState(StateRegistry.CONFIG);
69-
this.confirmation.complete(this);
70-
return true;
71-
}
72-
73-
@Override
74-
public void handleUnknown(ByteBuf buf) {
75-
this.connection.close(true);
76-
}
77-
7864
@Override
7965
public void disconnected() {
8066
try {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (C) 2021 - 2023 Elytrium
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package net.elytrium.limboapi.injection.login.confirmation;
19+
20+
import com.velocitypowered.proxy.connection.MinecraftConnection;
21+
import com.velocitypowered.proxy.protocol.StateRegistry;
22+
import com.velocitypowered.proxy.protocol.packet.LoginAcknowledged;
23+
import io.netty.buffer.ByteBuf;
24+
25+
public class LoginConfirmHandler extends ConfirmHandler {
26+
27+
public LoginConfirmHandler(MinecraftConnection connection) {
28+
super(connection);
29+
}
30+
31+
@Override
32+
public boolean handle(LoginAcknowledged packet) {
33+
this.connection.setState(StateRegistry.CONFIG);
34+
this.confirmation.complete(this);
35+
return true;
36+
}
37+
38+
@Override
39+
public void handleUnknown(ByteBuf buf) {
40+
this.connection.close(true);
41+
}
42+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (C) 2021 - 2023 Elytrium
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Affero General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Affero General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package net.elytrium.limboapi.injection.login.confirmation;
19+
20+
import com.velocitypowered.proxy.connection.MinecraftConnection;
21+
import com.velocitypowered.proxy.protocol.StateRegistry;
22+
import com.velocitypowered.proxy.protocol.packet.config.FinishedUpdate;
23+
24+
public class TransitionConfirmHandler extends ConfirmHandler {
25+
26+
public TransitionConfirmHandler(MinecraftConnection connection) {
27+
super(connection);
28+
}
29+
30+
@Override
31+
public boolean handle(FinishedUpdate packet) {
32+
if (this.connection.getState() == StateRegistry.PLAY) {
33+
this.connection.setState(StateRegistry.CONFIG);
34+
this.confirmation.complete(this);
35+
return true;
36+
}
37+
38+
return false;
39+
}
40+
}

plugin/src/main/java/net/elytrium/limboapi/server/LimboImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@
9090
import net.elytrium.limboapi.api.protocol.PacketDirection;
9191
import net.elytrium.limboapi.api.protocol.PreparedPacket;
9292
import net.elytrium.limboapi.api.protocol.packets.PacketMapping;
93-
import net.elytrium.limboapi.injection.login.LoginTrackHandler;
93+
import net.elytrium.limboapi.injection.login.confirmation.ConfirmHandler;
9494
import net.elytrium.limboapi.injection.packet.MinecraftLimitedCompressDecoder;
9595
import net.elytrium.limboapi.material.Biome;
9696
import net.elytrium.limboapi.protocol.LimboProtocol;
@@ -414,9 +414,9 @@ private void spawnPlayerLocal(ConnectedPlayer player, LimboSessionHandler handle
414414
() -> this.limboName
415415
);
416416

417-
if (connection.getActiveSessionHandler() instanceof LoginTrackHandler) {
418-
LoginTrackHandler track = (LoginTrackHandler) connection.getActiveSessionHandler();
419-
track.waitForConfirmation(() -> {
417+
if (connection.getActiveSessionHandler() instanceof ConfirmHandler) {
418+
ConfirmHandler confirm = (ConfirmHandler) connection.getActiveSessionHandler();
419+
confirm.waitForConfirmation(() -> {
420420
this.spawnPlayerLocal(handlerClass, sessionHandler, player, connection);
421421
});
422422
} else {

0 commit comments

Comments
 (0)