LegacyQueryHandler.java

net.minecraft.server.network.LegacyQueryHandler

信息

  • 全限定名:net.minecraft.server.network.LegacyQueryHandler
  • 类型:public class
  • 包:net.minecraft.server.network
  • 源码路径:src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
  • 起始行号:L14
  • 继承:ChannelInboundHandlerAdapter
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L15
    • 说明:

      TODO

  • server

    • 类型: ServerInfo
    • 修饰符: private final
    • 源码定位: L16
    • 说明:

      TODO

内部类/嵌套类型

构造器

public LegacyQueryHandler(ServerInfo server) @ L18

  • 构造器名:LegacyQueryHandler
  • 源码定位:L18
  • 修饰符:public

参数:

  • server: ServerInfo

说明:

TODO

方法

下面的方法块按源码顺序生成。

public void channelRead(ChannelHandlerContext ctx, Object msg) @ L22

  • 方法名:channelRead
  • 源码定位:L22
  • 返回类型:void
  • 修饰符:public

参数:

  • ctx: ChannelHandlerContext
  • msg: Object

说明:

TODO

private static boolean readCustomPayloadPacket(ByteBuf in) @ L72

  • 方法名:readCustomPayloadPacket
  • 源码定位:L72
  • 返回类型:boolean
  • 修饰符:private static

参数:

  • in: ByteBuf

说明:

TODO

private static String createVersion0Response(ServerInfo server) @ L98

  • 方法名:createVersion0Response
  • 源码定位:L98
  • 返回类型:String
  • 修饰符:private static

参数:

  • server: ServerInfo

说明:

TODO

private static String createVersion1Response(ServerInfo server) @ L102

  • 方法名:createVersion1Response
  • 源码定位:L102
  • 返回类型:String
  • 修饰符:private static

参数:

  • server: ServerInfo

说明:

TODO

private static void sendFlushAndClose(ChannelHandlerContext ctx, ByteBuf out) @ L114

  • 方法名:sendFlushAndClose
  • 源码定位:L114
  • 返回类型:void
  • 修饰符:private static

参数:

  • ctx: ChannelHandlerContext
  • out: ByteBuf

说明:

TODO

private static ByteBuf createLegacyDisconnectPacket(ByteBufAllocator alloc, String reason) @ L118

  • 方法名:createLegacyDisconnectPacket
  • 源码定位:L118
  • 返回类型:ByteBuf
  • 修饰符:private static

参数:

  • alloc: ByteBufAllocator
  • reason: String

说明:

TODO

代码

public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
    private static final Logger LOGGER = LogUtils.getLogger();
    private final ServerInfo server;
 
    public LegacyQueryHandler(ServerInfo server) {
        this.server = server;
    }
 
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf)msg;
        in.markReaderIndex();
        boolean connectNormally = true;
 
        try {
            try {
                if (in.readUnsignedByte() != 254) {
                    return;
                }
 
                SocketAddress socket = ctx.channel().remoteAddress();
                int length = in.readableBytes();
                if (length == 0) {
                    LOGGER.debug("Ping: (<1.3.x) from {}", socket);
                    String body = createVersion0Response(this.server);
                    sendFlushAndClose(ctx, createLegacyDisconnectPacket(ctx.alloc(), body));
                } else {
                    if (in.readUnsignedByte() != 1) {
                        return;
                    }
 
                    if (in.isReadable()) {
                        if (!readCustomPayloadPacket(in)) {
                            return;
                        }
 
                        LOGGER.debug("Ping: (1.6) from {}", socket);
                    } else {
                        LOGGER.debug("Ping: (1.4-1.5.x) from {}", socket);
                    }
 
                    String body = createVersion1Response(this.server);
                    sendFlushAndClose(ctx, createLegacyDisconnectPacket(ctx.alloc(), body));
                }
 
                in.release();
                connectNormally = false;
            } catch (RuntimeException var11) {
            }
        } finally {
            if (connectNormally) {
                in.resetReaderIndex();
                ctx.channel().pipeline().remove(this);
                ctx.fireChannelRead(msg);
            }
        }
    }
 
    private static boolean readCustomPayloadPacket(ByteBuf in) {
        short packetId = in.readUnsignedByte();
        if (packetId != 250) {
            return false;
        } else {
            String channelId = LegacyProtocolUtils.readLegacyString(in);
            if (!"MC|PingHost".equals(channelId)) {
                return false;
            } else {
                int payloadSize = in.readUnsignedShort();
                if (in.readableBytes() != payloadSize) {
                    return false;
                } else {
                    short protocolVersion = in.readUnsignedByte();
                    if (protocolVersion < 73) {
                        return false;
                    } else {
                        String host = LegacyProtocolUtils.readLegacyString(in);
                        int port = in.readInt();
                        return port <= 65535;
                    }
                }
            }
        }
    }
 
    private static String createVersion0Response(ServerInfo server) {
        return String.format(Locale.ROOT, "%s\u00a7%d\u00a7%d", server.getMotd(), server.getPlayerCount(), server.getMaxPlayers());
    }
 
    private static String createVersion1Response(ServerInfo server) {
        return String.format(
            Locale.ROOT,
            "\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d",
            127,
            server.getServerVersion(),
            server.getMotd(),
            server.getPlayerCount(),
            server.getMaxPlayers()
        );
    }
 
    private static void sendFlushAndClose(ChannelHandlerContext ctx, ByteBuf out) {
        ctx.pipeline().firstContext().writeAndFlush(out).addListener(ChannelFutureListener.CLOSE);
    }
 
    private static ByteBuf createLegacyDisconnectPacket(ByteBufAllocator alloc, String reason) {
        ByteBuf out = alloc.buffer();
        out.writeByte(255);
        LegacyProtocolUtils.writeLegacyString(out, reason);
        return out;
    }
}

引用的其他类

  • ServerInfo

    • 引用位置: 参数/字段
  • LegacyProtocolUtils

    • 引用位置: 方法调用
    • 关联成员: LegacyProtocolUtils.readLegacyString(), LegacyProtocolUtils.writeLegacyString()