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

基于Node.js搭建Minecraft代理服务器连接Hypixel失败求助

Minecraft代理服务器连接Hypixel失败的问题排查与解决思路

问题概述

自己搭建Node.js TCP代理服务器,可正常连接部分破解版Minecraft服务器,但连接Hypixel时仅传输少量数据就断开;尝试node-minecraft-proxy库无报错但连接超时;推测是客户端握手包携带localhost地址触发Hypixel安全验证;改用mineflayer bot实现代理后客户端仍超时,本地收到以0f 00 2f开头的数据包,但bot未收到,需确认该包类型并寻求解决方案。

核心原因分析

  • Hypixel的服务器地址校验机制:握手包中的服务器地址字段必须匹配实际连接的mc.hypixel.net,如果是localhost会被判定为异常请求直接断开连接。
  • 关于0f 00 2f开头的数据包:这是Minecraft协议中的状态查询包,属于客户端在状态阶段(比如刷新服务器列表)发送的请求,mineflayer bot默认跳过状态阶段直接进入登录流程,未处理这类数据包导致转发中断。

解决方法

1. 修改TCP代理的握手包内容

必须在TCP代理层拦截并修改客户端发送的握手包,将其中的服务器地址从localhost替换为mc.hypixel.net,再转发给Hypixel。核心逻辑示例:

// 实现VarInt编解码函数(Minecraft协议专用)
function readVarInt(buffer, offset) {
  let value = 0;
  let position = 0;
  let byte;
  do {
    byte = buffer.readUInt8(offset + position);
    value |= (byte & 0x7F) << (position * 7);
    position++;
    if (position > 5) throw new Error('VarInt too long');
  } while ((byte & 0x80) !== 0);
  return { value, length: position };
}

function writeVarInt(value) {
  const buffer = [];
  do {
    let byte = value & 0x7F;
    value >>>= 7;
    if (value !== 0) byte |= 0x80;
    buffer.push(byte);
  } while (value !== 0);
  return Buffer.from(buffer);
}

// 拦截并修改握手包
clientSocket.on('data', (data) => {
  let offset = 0;
  const { value: packetLength, length: lenLength } = readVarInt(data, offset);
  offset += lenLength;
  const { value: packetId } = readVarInt(data, offset);
  
  // 仅处理握手包(包ID=0)
  if (packetId === 0) {
    offset += lenLength;
    // 解析协议版本
    const { value: protocolVersion, length: protoLen } = readVarInt(data, offset);
    offset += protoLen;
    // 解析原服务器地址
    const { value: addrLen, length: addrLenLength } = readVarInt(data, offset);
    offset += addrLenLength;
    const originalAddr = data.toString('utf8', offset, offset + addrLen);
    offset += addrLen;
    // 解析端口和后续状态
    const port = data.readUInt16BE(offset);
    offset += 2;
    const { value: nextState } = readVarInt(data, offset);

    // 构造新的服务器地址数据
    const newAddr = 'mc.hypixel.net';
    const newAddrBuffer = Buffer.from(newAddr);
    const newAddrLen = writeVarInt(newAddrBuffer.length);

    // 重新组装握手包
    const newPacketParts = [
      writeVarInt(1 + protoLen + newAddrLen.length + newAddrBuffer.length + 2 + 1), // 新包长度
      writeVarInt(0), // 握手包ID
      writeVarInt(protocolVersion),
      newAddrLen,
      newAddrBuffer,
      Buffer.from([(port >> 8) & 0xff, port & 0xff]),
      writeVarInt(nextState)
    ];
    const modifiedPacket = Buffer.concat(newPacketParts);
    
    // 转发修改后的包,后续数据直接透传
    serverSocket.write(modifiedPacket);
    clientSocket.on('data', d => serverSocket.write(d));
    serverSocket.on('data', d => clientSocket.write(d));
  } else {
    serverSocket.write(data);
  }
});

2. 修复mineflayer bot代理的数据包转发

mineflayer默认跳过状态阶段,需手动处理状态与登录阶段的数据包转发:

  • 监听客户端的data事件,先解析握手包,根据后续状态(1=状态,2=登录)分阶段处理:
    • 状态阶段:将客户端的状态请求包转发给Hypixel,再把Hypixel返回的状态响应包转发给客户端;
    • 登录阶段:初始化mineflayer bot连接Hypixel,将客户端的登录包转发给bot,同时监听bot的packet事件,把服务器发来的游戏数据包转发给客户端。
  • 确保bot的协议版本与客户端完全匹配,避免因版本不兼容导致数据包解析失败。

3. 适配Hypixel的额外验证

Hypixel可能有额外的反代理机制,需注意:

  • 确保代理的IP与客户端IP一致,避免IP mismatch;
  • 不要修改握手包外的其他协议字段,保持数据包结构的完整性;
  • 若使用mineflayer,需禁用bot的自动重连、自动聊天等行为,仅做纯数据包转发。

关于0f 00 2f数据包的确认

这个数据包是客户端在状态阶段发送的服务器信息请求包:

  • 0f是VarInt编码的包总长度(15字节);
  • 00是状态阶段的包ID(对应0x00状态请求);
  • 00 2f是后续的字符串数据(长度为0的字符串+"/",属于状态请求的附加路径)。
    mineflayer bot未收到是因为它默认直接进入登录流程,未监听状态阶段的数据包,需在代理逻辑中单独处理该阶段的转发。

内容的提问来源于stack exchange,提问作者Nuro007

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:01:17