Error handler

This commit is contained in:
Adrian Bergqvist 2023-03-27 00:07:45 +02:00
parent dbf0777d29
commit 71d5114d4a
No known key found for this signature in database
GPG Key ID: FAE7D8EDE225E686
4 changed files with 69 additions and 2 deletions

View File

@ -10,6 +10,7 @@ public class ForgeConstants {
public static final String FORGE_HANDSHAKE_HOLDER = "ambassador-forge-handshake-holder";
public static final String FORGE_HANDSHAKE_DECODER = "ambassador-forge-decoder";
public static final String FORGE_HANDSHAKE_HANDLER = "ambassador-forge-handler";
public static final String COMMAND_ERROR_CATCHER = "ambassador-command-catcher";
public static final String FML2Marker = "\0FML2\0";
public static final String FML3Marker = "\0FML3\0";

View File

@ -4,11 +4,12 @@ import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.backend.BackendConnectionPhase;
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.network.Connections;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.packet.AvailableCommands;
import com.velocitypowered.proxy.protocol.packet.LoginPluginMessage;
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import org.adde0109.ambassador.forge.pipeline.CommandDecoderErrorCatcher;
import org.adde0109.ambassador.forge.pipeline.ForgeLoginWrapperDecoder;
public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhase {
@ -22,6 +23,10 @@ public enum VelocityForgeBackendConnectionPhase implements BackendConnectionPhas
@Override
public void onLoginSuccess(VelocityServerConnection serverCon, ConnectedPlayer player) {
serverCon.setConnectionPhase(VelocityForgeBackendConnectionPhase.COMPLETE);
serverCon.getConnection().getChannel().pipeline().addBefore(Connections.MINECRAFT_DECODER,
ForgeConstants.COMMAND_ERROR_CATCHER,
new CommandDecoderErrorCatcher(serverCon.getConnection().getProtocolVersion(),player));
}
@Override

View File

@ -0,0 +1,61 @@
package org.adde0109.ambassador.forge.pipeline;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.network.Connections;
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.AvailableCommands;
import com.velocitypowered.proxy.protocol.packet.Disconnect;
import com.velocitypowered.proxy.util.except.QuietRuntimeException;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.CorruptedFrameException;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
public class CommandDecoderErrorCatcher extends ChannelInboundHandlerAdapter {
private final StateRegistry.PacketRegistry.ProtocolRegistry registry;
private final ConnectedPlayer player;
public CommandDecoderErrorCatcher(ProtocolVersion protocolVersion, ConnectedPlayer player) {
this.registry = StateRegistry.PLAY.getProtocolRegistry(ProtocolUtils.Direction.CLIENTBOUND, protocolVersion);
this.player = player;
}
@Override
public void channelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) throws Exception {
if (msg instanceof ByteBuf buf) {
if (!ctx.channel().isActive() || !buf.isReadable()) {
buf.release();
return;
}
int originalReaderIndex = buf.readerIndex();
int packetId = ProtocolUtils.readVarInt(buf);
MinecraftPacket packet = registry.createPacket(packetId);
buf.readerIndex(originalReaderIndex);
if (packet instanceof AvailableCommands) {
try {
((MinecraftDecoder) ctx.pipeline().get(Connections.MINECRAFT_DECODER)).channelRead(ctx, msg);
} catch (QuietRuntimeException | CorruptedFrameException e) {
RegisteredServer server = player.getConnectedServer().getServer();
player.handleConnectionException(server,
Disconnect.create(Component.text("Ambassador: Unsupported command argument type detected! " +
"Please install Proxy-Compatible-Forge mod on this backend server."),
player.getProtocolVersion()),true);
}
} else {
ctx.fireChannelRead(msg);
}
}
}
}

View File

@ -80,7 +80,7 @@ public class ForgeLoginSessionHandler implements MinecraftSessionHandler {
public void disconnected() {
if (!serverConnection.getPhase().consideredComplete()) {
serverConnection.getPlayer().handleConnectionException(serverConnection.getServer(),
Disconnect.create(Component.text("Backend server disconnected during handshake could be: " +
Disconnect.create(Component.text("Ambassador: Backend server disconnected during handshake could be: " +
"mismatched mods OR bad player-forwarding config"),
serverConnection.getPlayer().getProtocolVersion()),false);
return;