Fixed config state tracking issues

This commit is contained in:
RaphiMC 2023-08-18 23:42:47 +02:00
parent 4b54e6703d
commit 3ac0d81484
No known key found for this signature in database
GPG Key ID: 0F6BB0657A03AC94
9 changed files with 74 additions and 43 deletions

View File

@ -85,7 +85,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
protected void channelRead0(ChannelHandlerContext ctx, IPacket packet) throws Exception {
if (this.proxyConnection.isClosed()) return;
if (this.proxyConnection.getConnectionState() == ConnectionState.HANDSHAKING) {
if (this.proxyConnection.getC2pConnectionState() == ConnectionState.HANDSHAKING) {
if (packet instanceof C2SHandshakePacket) this.handleHandshake((C2SHandshakePacket) packet);
else throw new IllegalStateException("Unexpected packet in HANDSHAKING state");
return;
@ -105,15 +105,15 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
ExceptionUtil.handleNettyException(ctx, cause, this.proxyConnection);
}
private void handleHandshake(final C2SHandshakePacket packet) throws InterruptedException {
private void handleHandshake(final C2SHandshakePacket packet) {
final VersionEnum clientVersion = VersionEnum.fromProtocolVersion(ProtocolVersion.getProtocol(packet.protocolVersion));
if (packet.intendedState != ConnectionState.STATUS && packet.intendedState != ConnectionState.LOGIN) {
if (packet.intendedState == null) {
throw CloseAndReturn.INSTANCE;
}
this.proxyConnection.setClientVersion(clientVersion);
this.proxyConnection.setConnectionState(packet.intendedState);
this.proxyConnection.setC2pConnectionState(packet.intendedState);
if (clientVersion == VersionEnum.UNKNOWN || !VersionEnum.OFFICIAL_SUPPORTED_PROTOCOLS.contains(clientVersion)) {
this.proxyConnection.kickClient("§cYour client version is not supported by ViaProxy!");
@ -213,7 +213,7 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
}
this.proxyConnection.getC2P().attr(ProxyConnection.PROXY_CONNECTION_ATTRIBUTE_KEY).set(this.proxyConnection);
this.proxyConnection.setClientVersion(clientVersion);
this.proxyConnection.setConnectionState(packet.intendedState);
this.proxyConnection.setC2pConnectionState(packet.intendedState);
this.proxyConnection.setClassicMpPass(classicMpPass);
this.proxyConnection.getPacketHandlers().add(new StatusPacketHandler(this.proxyConnection));
this.proxyConnection.getPacketHandlers().add(new CustomPayloadPacketHandler(this.proxyConnection));
@ -246,8 +246,11 @@ public class Client2ProxyHandler extends SimpleChannelInboundHandler<IPacket> {
}
handshakeParts[0] = serverAddress.getAddress();
this.proxyConnection.getChannel().writeAndFlush(new C2SHandshakePacket(clientVersion.getOriginalVersion(), String.join("\0", handshakeParts), serverAddress.getPort(), packet.intendedState)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE).await();
this.proxyConnection.setConnectionState(packet.intendedState);
this.proxyConnection.getChannel().writeAndFlush(new C2SHandshakePacket(clientVersion.getOriginalVersion(), String.join("\0", handshakeParts), serverAddress.getPort(), packet.intendedState)).addListeners(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, (ChannelFutureListener) f -> {
if (f.isSuccess()) {
this.proxyConnection.setP2sConnectionState(packet.intendedState);
}
});
}
}

View File

@ -44,31 +44,32 @@ public class ConfigurationPacketHandler extends PacketHandler {
@Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket && this.proxyConnection.getConnectionState() == ConnectionState.PLAY) {
if (packet instanceof UnknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) {
final UnknownPacket unknownPacket = (UnknownPacket) packet;
if (unknownPacket.packetId == this.configurationAcknowledgedId) {
this.proxyConnection.setC2pConnectionState(ConnectionState.CONFIGURATION);
listeners.add(f -> {
if (f.isSuccess()) {
Logger.u_info("session", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Switching to CONFIGURATION state");
this.proxyConnection.setConnectionState(ConnectionState.CONFIGURATION);
this.proxyConnection.setP2sConnectionState(ConnectionState.CONFIGURATION);
this.proxyConnection.getChannel().config().setAutoRead(true);
}
});
}
} else if (packet instanceof C2SLoginStartConfiguration1_20_2) {
this.proxyConnection.getC2P().config().setAutoRead(false);
this.proxyConnection.setC2pConnectionState(ConnectionState.CONFIGURATION);
listeners.add(f -> {
if (f.isSuccess()) {
this.proxyConnection.setConnectionState(ConnectionState.CONFIGURATION);
this.proxyConnection.setP2sConnectionState(ConnectionState.CONFIGURATION);
this.proxyConnection.getChannel().config().setAutoRead(true);
this.proxyConnection.getC2P().config().setAutoRead(true);
}
});
} else if (packet instanceof C2SConfigFinishConfiguration1_20_2) {
this.proxyConnection.setC2pConnectionState(ConnectionState.PLAY);
listeners.add(f -> {
if (f.isSuccess()) {
Logger.u_info("session", this.proxyConnection.getC2P().remoteAddress(), this.proxyConnection.getGameProfile(), "Configuration finished! Switching to PLAY state");
this.proxyConnection.setConnectionState(ConnectionState.PLAY);
this.proxyConnection.setP2sConnectionState(ConnectionState.PLAY);
this.proxyConnection.getChannel().config().setAutoRead(true);
}
});
@ -79,7 +80,7 @@ public class ConfigurationPacketHandler extends PacketHandler {
@Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket && this.proxyConnection.getConnectionState() == ConnectionState.PLAY) {
if (packet instanceof UnknownPacket && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY) {
final UnknownPacket unknownPacket = (UnknownPacket) packet;
if (unknownPacket.packetId == this.startConfigurationId) {
this.proxyConnection.getChannel().config().setAutoRead(false);

View File

@ -46,7 +46,7 @@ public class CustomPayloadPacketHandler extends PacketHandler {
@Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket && this.proxyConnection.getConnectionState() == ConnectionState.PLAY) {
if (packet instanceof UnknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) {
final UnknownPacket unknownPacket = (UnknownPacket) packet;
if (unknownPacket.packetId == this.customPayloadId) {
final ByteBuf data = Unpooled.wrappedBuffer(unknownPacket.data);

View File

@ -67,7 +67,7 @@ public class LoginPacketHandler extends PacketHandler {
@Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) throws GeneralSecurityException {
if (packet instanceof UnknownPacket && this.proxyConnection.getConnectionState() == ConnectionState.PLAY) {
if (packet instanceof UnknownPacket && this.proxyConnection.getC2pConnectionState() == ConnectionState.PLAY) {
final UnknownPacket unknownPacket = (UnknownPacket) packet;
if (unknownPacket.packetId == this.chatSessionUpdateId && this.proxyConnection.getChannel().attr(MCPipeline.ENCRYPTION_ATTRIBUTE_KEY).get() == null) {
return false;
@ -202,7 +202,8 @@ public class LoginPacketHandler extends PacketHandler {
this.proxyConnection.getChannel().config().setAutoRead(false);
listeners.add(f -> {
if (f.isSuccess() && nextState != ConnectionState.CONFIGURATION) {
this.proxyConnection.setConnectionState(nextState);
this.proxyConnection.setC2pConnectionState(nextState);
this.proxyConnection.setP2sConnectionState(nextState);
this.proxyConnection.getChannel().config().setAutoRead(true);
}
});

View File

@ -47,7 +47,7 @@ public class ResourcePackPacketHandler extends PacketHandler {
@Override
public boolean handleP2S(IPacket packet, List<ChannelFutureListener> listeners) {
if (packet instanceof UnknownPacket && this.proxyConnection.getConnectionState() == ConnectionState.PLAY) {
if (packet instanceof UnknownPacket && this.proxyConnection.getP2sConnectionState() == ConnectionState.PLAY) {
final UnknownPacket unknownPacket = (UnknownPacket) packet;
if (unknownPacket.packetId == this.joinGameId) {
listeners.add(f -> {

View File

@ -32,7 +32,7 @@ public class UnexpectedPacketHandler extends PacketHandler {
@Override
public boolean handleC2P(IPacket packet, List<ChannelFutureListener> listeners) {
final ConnectionState connectionState = this.proxyConnection.getConnectionState();
final ConnectionState connectionState = this.proxyConnection.getC2pConnectionState();
if (connectionState.equals(ConnectionState.HANDSHAKING)) {
throw new IllegalStateException("Unexpected packet in " + connectionState + " state");
}

View File

@ -74,7 +74,7 @@ public class BedrockProxyConnection extends ProxyConnection {
@Override
public void connectToServer(ServerAddress serverAddress, VersionEnum targetVersion) {
if (this.getConnectionState() == ConnectionState.STATUS) {
if (this.getC2pConnectionState() == ConnectionState.STATUS) {
RStream.of(this).withSuper().fields().by("serverAddress").set(serverAddress);
RStream.of(this).withSuper().fields().by("serverVersion").set(targetVersion);
this.ping(serverAddress);

View File

@ -97,10 +97,15 @@ public class DummyProxyConnection extends ProxyConnection {
}
@Override
public ConnectionState getConnectionState() {
public ConnectionState getC2pConnectionState() {
return ConnectionState.HANDSHAKING;
}
@Override
public ConnectionState getP2sConnectionState() {
throw new UnsupportedOperationException();
}
@Override
public CompletableFuture<ByteBuf> sendCustomPayload(String channel, ByteBuf data) {
throw new UnsupportedOperationException();

View File

@ -74,7 +74,8 @@ public class ProxyConnection extends NetClient {
private GameProfile gameProfile;
private C2SLoginHelloPacket1_7 loginHelloPacket;
private UserConnection userConnection;
private ConnectionState connectionState = ConnectionState.HANDSHAKING;
private ConnectionState c2pConnectionState = ConnectionState.HANDSHAKING;
private ConnectionState p2sConnectionState = ConnectionState.HANDSHAKING;
private Key storedSecretKey;
private String classicMpPass;
@ -167,39 +168,59 @@ public class ProxyConnection extends NetClient {
return this.userConnection;
}
public void setConnectionState(final ConnectionState connectionState) {
this.connectionState = connectionState;
switch (this.connectionState) {
public void setC2pConnectionState(final ConnectionState connectionState) {
this.c2pConnectionState = connectionState;
switch (connectionState) {
case HANDSHAKING:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getHandshakeRegistry(true));
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getHandshakeRegistry(false));
break;
case STATUS:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getStatusRegistry(true));
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getStatusRegistry(false));
break;
case LOGIN:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getLoginRegistry(true, this.clientVersion.getVersion()));
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getLoginRegistry(false, this.clientVersion.getVersion()));
break;
case CONFIGURATION:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getConfigurationRegistry(true, this.clientVersion.getVersion()));
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getConfigurationRegistry(false, this.clientVersion.getVersion()));
break;
case PLAY:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getPlayRegistry(true, this.clientVersion.getVersion()));
this.c2p.attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getPlayRegistry(false, this.clientVersion.getVersion()));
break;
}
}
public ConnectionState getConnectionState() {
return this.connectionState;
public void setP2sConnectionState(final ConnectionState connectionState) {
this.p2sConnectionState = connectionState;
switch (connectionState) {
case HANDSHAKING:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getHandshakeRegistry(true));
break;
case STATUS:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getStatusRegistry(true));
break;
case LOGIN:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getLoginRegistry(true, this.clientVersion.getVersion()));
break;
case CONFIGURATION:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getConfigurationRegistry(true, this.clientVersion.getVersion()));
break;
case PLAY:
if (this.getChannel() != null)
this.getChannel().attr(MCPipeline.PACKET_REGISTRY_ATTRIBUTE_KEY).set(PacketRegistryUtil.getPlayRegistry(true, this.clientVersion.getVersion()));
break;
}
}
public ConnectionState getC2pConnectionState() {
return this.c2pConnectionState;
}
public ConnectionState getP2sConnectionState() {
return this.p2sConnectionState;
}
public CompletableFuture<ByteBuf> sendCustomPayload(final String channel, final ByteBuf data) {
@ -207,7 +228,7 @@ public class ProxyConnection extends NetClient {
final CompletableFuture<ByteBuf> future = new CompletableFuture<>();
final int id = this.customPayloadId.getAndIncrement();
switch (this.connectionState) {
switch (this.c2pConnectionState) {
case LOGIN:
if (this.clientVersion.isNewerThanOrEqualTo(VersionEnum.r1_13)) {
this.c2p.writeAndFlush(new S2CLoginCustomPayloadPacket(id, channel, PacketTypes.readReadableBytes(data))).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
@ -228,7 +249,7 @@ public class ProxyConnection extends NetClient {
this.c2p.writeAndFlush(customPayloadPacket).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
break;
default:
throw new IllegalStateException("Can't send a custom payload packet during " + this.connectionState);
throw new IllegalStateException("Can't send a custom payload packet during " + this.c2pConnectionState);
}
this.customPayloadListener.put(id, future);
@ -255,16 +276,16 @@ public class ProxyConnection extends NetClient {
Logger.u_err("kick", this.c2p.remoteAddress(), this.getGameProfile(), message.replaceAll("§.", ""));
final ChannelFuture future;
if (this.connectionState == ConnectionState.STATUS) {
if (this.c2pConnectionState == ConnectionState.STATUS) {
future = this.c2p.writeAndFlush(new S2CStatusResponsePacket("{\"players\":{\"max\":0,\"online\":0},\"description\":" + new JsonPrimitive(message) + ",\"version\":{\"protocol\":-1,\"name\":\"ViaProxy\"}}"));
} else if (this.connectionState == ConnectionState.LOGIN) {
} else if (this.c2pConnectionState == ConnectionState.LOGIN) {
future = this.c2p.writeAndFlush(new S2CLoginDisconnectPacket(messageToJson(message)));
} else if (this.connectionState == ConnectionState.CONFIGURATION) {
} else if (this.c2pConnectionState == ConnectionState.CONFIGURATION) {
final ByteBuf disconnectPacket = Unpooled.buffer();
PacketTypes.writeVarInt(disconnectPacket, MCPackets.S2C_CONFIG_DISCONNECT.getId(this.clientVersion.getVersion()));
PacketTypes.writeString(disconnectPacket, messageToJson(message));
future = this.c2p.writeAndFlush(disconnectPacket);
} else if (this.connectionState == ConnectionState.PLAY) {
} else if (this.c2pConnectionState == ConnectionState.PLAY) {
final ByteBuf disconnectPacket = Unpooled.buffer();
PacketTypes.writeVarInt(disconnectPacket, MCPackets.S2C_DISCONNECT.getId(this.clientVersion.getVersion()));
PacketTypes.writeString(disconnectPacket, messageToJson(message));