You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

发送LoginStart数据包后Minecraft服务器返回IndexOutOfBoundsException错误

排查Minecraft LoginStart数据包发送导致的IndexOutOfBoundsException错误

服务器返回的错误明确指向Netty解码时的索引越界:readerIndex(27) + length(8) exceeds writerIndex(34),说明服务器尝试从数据包的27索引位读取8字节数据,但数据包总长度仅34字节,数据量不足。结合你怀疑的OutputPacketContainer#writeUUID方法,大概率是UUID的编码逻辑不符合Minecraft协议规范。

核心问题分析

根据Minecraft登录协议规范,LoginStart数据包中的UUID字段必须按以下规则编码:

  • 无论在线/离线模式,都需要将UUID拆分为高64位整数和低64位整数,分别以**大端序(Big-Endian)**写入数据包
  • 离线模式登录时,需写入全零的UUID(即两个64位的0值)

排查与修复步骤

  1. 检查writeUUID方法的实现逻辑
    错误示例(直接转字节数组或用小端序写入):

    // 错误写法:不符合MC协议对UUID的拆分编码要求
    public void writeUUID(UUID uuid) {
        byte[] bytes = ByteBuffer.allocate(16)
            .putLong(uuid.getMostSignificantBits())
            .putLong(uuid.getLeastSignificantBits())
            .array();
        writeBytes(bytes);
    }
    

    正确实现(拆分高低位并按大端序写入):

    // 正确写法:按MC协议要求分别写入UUID的高低64位
    public void writeUUID(UUID uuid) {
        writeLong(uuid.getMostSignificantBits()); // 写入高64位
        writeLong(uuid.getLeastSignificantBits()); // 写入低64位
    }
    
  2. 验证writeLong方法的字节序
    Minecraft协议所有多字节整数均要求大端序,确保你的writeLong方法不是小端序实现:

    public void writeLong(long value) {
        byte[] bytes = ByteBuffer.allocate(8)
            .order(ByteOrder.BIG_ENDIAN)
            .putLong(value)
            .array();
        buffer.writeBytes(bytes);
    }
    
  3. 检查LoginStart数据包的整体结构
    确认数据包字段无遗漏或长度编码错误:

    • 数据包长度(VarInt编码)
    • 数据包ID(固定为0x00,VarInt编码)
    • 用户名(VarInt编码的长度 + UTF-8字节)
    • UUID(必须存在,离线模式填全零UUID)

验证

修改writeUUID方法为符合协议的实现后,重新发送LoginStart数据包,服务器应能正常解析,不会再触发索引越界错误。若问题仍存在,需排查VarInt编码逻辑(比如数据包长度、用户名长度的VarInt是否符合可变长度编码规范)。

内容的提问来源于stack exchange,提问作者Lite Mix-Ray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 16:32:43