提交前确认
HyperZoneLogin 主插件版本
26.7.3-SNAPSHOT-bd98b152
(源码基线:upstream master @ bd98b152;本地为适配 Java 21 / Velocity 3.5 的构建产物)
说明:官方 26.7.3-RC 源码中 jvmToolchain(25) 且 velocity = "4.1.0-SNAPSHOT"。
我们线上代理仍为 Java 21 + Velocity 3.5.x,因此在 bd98b152 基础上将 toolchain/依赖改回 21 + 3.5 后构建上线。
希望作者确认:该组合是否在支持范围内,还是仅保证 Vel 4.1 + Java 25。
已安装模块及版本
单体 all-in-one:HyperZoneLogin-26.7.3-SNAPSHOT-bd98b152-...-all.jar
启用:auth-yggd、safe
禁用:auth-offline、auth-floodgate、profile-skin、data-merge
Velocity 版本
Velocity 3.5.x(与 HZL compileOnly velocity-api/proxy 3.5.0-SNAPSHOT 对齐)
代理 JVM:Java 21
后端服务端版本
Mohist 1.20.1(Forge 模组端,主城/游戏服)
认证等待:outpre 直连 127.0.0.1:25581(auth-label=verify)
代理转发模式
当前数据库类型
已安装模块
部署结构
- 1× Velocity 代理(Java 21)
- HZL v-server.mode=outpre
- auth-label=verify,auth-host=127.0.0.1,auth-port=25581
- post-auth-default-server=corath
- struck-online-mode=true
- Forge/Mohist 游戏服:corath
- Mojang + 第三方 Yggdrasil Entry;auth-offline/floodgate/profile-skin 关
- 共存 Ambassador(Forge)+ TAB 等
- 数据库:MYSQL
问题类型
- 跳服 / 认证等待区相关
- (叠加)与第三方 Forge 代理插件 Ambassador 共存
复现步骤
- 启动 Velocity(HZL + Ambassador)与 Mohist/Forge 后端、认证等待服 verify。
- 使用 Forge 模组客户端 连接代理。
- 完成 Yggdrasil 认证(日志:认证成功 / 通过 Yggdrasil 验证)。
- 离开等待区后进入 Forge 服 corath。
- 失败时:corath has connected → 恰好约 30s → disconnected → unable to connect;Amb 向 LOGIN 客户端转发 Registry/ConfigData 失败刷屏。
预期结果
- 认证成功后进入 Forge 后端应在合理时间内完成 FML 握手并进入游戏区。
- 若失败,应有 明确、可操作 的失败原因(超时原因、握手阶段),而不是泛化
unable to connect。
实际结果
- 主路径可用:大量玩家 Yggdrasil 认证成功并可游玩。
- 失败模式(可在日志中对齐时间戳):
- HZL:
认证成功(Yggdrasil / Entry)
- 约 30s 后 Velocity:
unable to connect to server corath
- 同时 Ambassador 侧大量:
failed forwarding backend forge packet (RegistryPacket/ConfigDataPacket/...) to client,clientState=LOGIN + StacklessClosedChannelException
- 表现像:后端已向代理推 Forge 登录握手包,客户端停留 LOGIN、无有效应答,直到原版/后端登录超时。
- 源码层面 HZL 已对 Ambassador 做 soft-fail(
registerConnection 失败仅 debug:maybe using Ambassador),说明作者已知共存,但 缺少正式协作契约。
相关日志(生产代理日志摘录;玩家名 / 公网 IP 已脱敏;本机回环地址保留)
启动与模块:
[06:23:49] [main/INFO] [com.velocitypowered.proxy.plugin.VelocityPluginManager]: Loaded plugin ambassador 1.5.3-beta by adde0109
[06:23:49] [main/INFO] [com.velocitypowered.proxy.plugin.VelocityPluginManager]: Loaded plugin hyperzonelogin 26.7.3-SNAPSHOT-bd98b152 by ksqeib
[06:23:50] [CMIV - Task Executor #0/INFO] [hyperzonelogin]: Using outpre waiting-area adapter on direct auth endpoint 'verify' (127.0.0.1/<unresolved>:25581)
[06:23:50] [CMIV - Task Executor #0/INFO] [hyperzonelogin]: 内置模块已禁用: Auth Offline (modules.conf -> authOffline=false)
[06:23:50] [CMIV - Task Executor #0/INFO] [hyperzonelogin]: 凭证渠道已注册: yggdrasil (模块: YggdrasilSubModule) [canRegister=true]
[06:23:50] [HyperZoneLogin - Task Executor #0/INFO] [hyperzonelogin]: 接收到 Entry 注册事件: Dream-WingSkin (ID: Dream-WingSkin)
[06:23:50] [HyperZoneLogin - Task Executor #0/INFO] [hyperzonelogin]: 接收到 Entry 注册事件: mojang (ID: mojang)
[06:23:50] [CMIV - Task Executor #0/INFO] [hyperzonelogin]: 成功加载 2 个 Entry 配置文件
[06:23:50] [CMIV - Task Executor #0/INFO] [hyperzonelogin]: 模块加载成功: icu.h2l.login.auth.online.main.YggdrasilSubModule
[06:23:51] [CMIV - Task Executor #0/WARN] [com.velocitypowered.proxy.network.ConnectionManager]: The server channel initializer has been replaced by org.adde0109.ambassador.Ambassador.inject(Ambassador.java:156)
[06:23:51] [CMIV - Task Executor #0/WARN] [com.velocitypowered.proxy.network.ConnectionManager]: The backend channel initializer has been replaced by org.adde0109.ambassador.Ambassador.inject(Ambassador.java:159)
案例 A(可精确复现的 30s 后端登录超时):玩家 PlayerA,Mojang Entry
[10:08:27] [Netty NIO Worker #3/INFO] [com.velocitypowered.proxy.connection.client.AuthSessionHandler]: [connected player] PlayerA (/x.x.x.x:xxxxx) entered outpre pre-registration flow
[10:08:29] [DefaultDispatcher-worker-3/INFO] [hyperzonelogin]: 条目 mojang: 玩家 PlayerA 认证成功
[10:08:29] [DefaultDispatcher-worker-1/INFO] [hyperzonelogin]: 玩家 PlayerA 通过 Yggdrasil 验证,Entry: mojang
[10:08:29] [Netty NIO Worker #3/INFO] [com.velocitypowered.proxy.connection.MinecraftConnection]: [server connection] PlayerA -> corath has connected
[10:08:59] [Netty NIO Worker #3/INFO] [com.velocitypowered.proxy.connection.MinecraftConnection]: [server connection] PlayerA -> corath has disconnected
[10:08:59] [Netty NIO Worker #3/ERROR] [com.velocitypowered.proxy.connection.client.ConnectedPlayer]: [connected player] PlayerA (/x.x.x.x:xxxxx): unable to connect to server corath
[10:08:59] [Netty NIO Worker #3/INFO] [com.velocitypowered.proxy.connection.client.ConnectedPlayer]: [connected player] PlayerA (/x.x.x.x:xxxxx) has disconnected: 无法将您连接到 corath,请稍后再试。
同一玩家同日多次重复同一模式(均为 connected → 恰好 30s → disconnected / unable to connect):
10:08:29 → 10:08:59 corath (Δ30s)
10:10:36 → 10:11:06 corath (Δ30s)
10:13:13 → 10:13:43 corath (Δ30s)
10:23:25 → 10:23:55 corath (Δ30s)
10:29:03 → 10:29:33 corath (Δ30s)
案例 B(认证成功 + 30s 失败 + 随后 Amb 转发 Forge 包刷屏):玩家 PlayerB
[13:59:20] [Netty NIO Worker #7/INFO] [com.velocitypowered.proxy.connection.client.AuthSessionHandler]: [connected player] PlayerB (/x.x.x.x:xxxxx) entered outpre pre-registration flow
[13:59:21] [DefaultDispatcher-worker-3/INFO] [hyperzonelogin]: 条目 mojang: 玩家 PlayerB 认证成功
[13:59:21] [DefaultDispatcher-worker-1/INFO] [hyperzonelogin]: 玩家 PlayerB 通过 Yggdrasil 验证,Entry: mojang
[13:59:21] [Netty NIO Worker #7/INFO] [com.velocitypowered.proxy.connection.MinecraftConnection]: [server connection] PlayerB -> corath has connected
[13:59:51] [Netty NIO Worker #7/INFO] [com.velocitypowered.proxy.connection.MinecraftConnection]: [server connection] PlayerB -> corath has disconnected
[13:59:51] [Netty NIO Worker #7/ERROR] [com.velocitypowered.proxy.connection.client.ConnectedPlayer]: [connected player] PlayerB (/x.x.x.x:xxxxx): unable to connect to server corath
com.velocitypowered.proxy.util.except.QuietRuntimeException: The connection to the remote server was unexpectedly closed.
[13:59:51] [Netty NIO Worker #7/INFO] [com.velocitypowered.proxy.connection.client.ConnectedPlayer]: [connected player] PlayerB (/x.x.x.x:xxxxx) has disconnected: 无法将您连接到 corath,请稍后再试。
[14:01:20] [Netty NIO Worker #7/ERROR] [com.velocitypowered.proxy.connection.MinecraftConnection]: [connected player] PlayerB (/x.x.x.x:xxxxx): read timed out
[14:01:20] [Netty NIO Worker #7/WARN] [ambassador]: [HZL-OUTPRE] failed forwarding backend forge packet RegistryPacket to client player=PlayerB clientState=LOGIN
io.netty.channel.StacklessClosedChannelException
at io.netty.channel.AbstractChannel.close(ChannelPromise)(Unknown Source)
[14:01:20] [Netty NIO Worker #7/WARN] [ambassador]: [HZL-OUTPRE] failed forwarding backend forge packet ConfigDataPacket to client player=PlayerB clientState=LOGIN
io.netty.channel.StacklessClosedChannelException
at io.netty.channel.AbstractChannel.close(ChannelPromise)(Unknown Source)
# 同一秒内 RegistryPacket/ConfigDataPacket 同类 WARN 合计约 120+ 次(closed channel 后仍积压写)
同日统计:
unable to connect to server corath : 9 次
[HZL-OUTPRE] failed forwarding backend forge packet ... : 121 次
说明:
- HZL 认证阶段成功,问题集中在 outpre 释放后连 Forge 后端
corath 的登录握手窗口(稳定约 30s)。
- Ambassador 日志显示向客户端转发后端 Forge 登录包时
clientState=LOGIN,通道已关仍刷屏(当前线上 Amb 尚未换看门狗/去重版)。
- 部分玩家后续可成功进其它后端服,说明并非全局无法连后端。
相关配置片段(已脱敏)
start.conf
format=hocon
language="zh_cn"
ready=true
core.conf(关键段)
database {
type=MYSQL
table-prefix="hz_"
# mysql host/port/user/password 已脱敏省略
}
modules {
auth-floodgate=false
auth-offline=false
auth-yggd=true
safe=true
profile-skin=false
data-merge=false
}
misc {
kill-chat-session=true
}
debug {
log {
general=false
out-pre-trace=false
yggdrasil-auth=false
network-rewrite=false
backend-compat=false
profile-skin=false
floodgate=false
}
}
v-server {
mode=outpre
post-auth-default-server=corath
remember-requested-server-during-auth=true
backend {
fallback-auth-server=verify
enable-player-info-compensation=true
enable-profile-compensation=true
enable-name-hot-change=true
enable-uuid-hot-change=false
}
outpre {
auth-label=verify
auth-host="127.0.0.1"
auth-port=25581
presented-host=""
presented-port=-1
presented-player-ip=""
# 在线模式玩家直通:认证通过后跳过等待区直接进游戏
struck-online-mode=true
}
}
auth {
disable-registration=["<channel-id>"]
}
auth-yggd Entry
# mojang.conf
id=mojang
name="Mojang Official"
yggdrasil {
pass-yggdrasil-uuid-to-profile-resolve=true
retry=5
retry-delay=5000
timeout=10000
url="https://sessionserver.mojang.com/session/minecraft/hasJoined?username={username}&serverId={serverId}{ip}"
proxy { type=DIRECT }
}
# 第三方 Entry
id=Dream-WingSkin
name="<third-party-entry>"
yggdrasil {
pass-yggdrasil-uuid-to-profile-resolve=true
retry=5
retry-delay=5000
timeout=10000
url="<third-party-hasJoined-url>"
proxy { type=DIRECT }
}
与日志对齐的要点
mode=outpre + auth-host=127.0.0.1 + auth-port=25581 + auth-label=verify → 与日志 outpre adapter 一致
post-auth-default-server=corath → 与失败目标服一致
struck-online-mode=true → 在线玩家可能跳过等待区直进,与 Forge/Ambassador 握手时序可能相关
已尝试的排查
其他补充信息 / 希望作者协助的点
A. 本 Issue 主问题(outpre + Forge/Ambassador)
我们不是要求 Amb 成为 HZL 官方依赖,但希望在文档或 API 层明确 outpre 与会提前 registerConnection / 修改 LOGIN 状态机的第三方插件 如何共存:
-
outpre × Forge 握手所有权
- 认证成功后切 Forge 服时,FML LOGIN 握手由谁主导?
- 客户端长时间停在
LOGIN 时,HZL 是否应有超时与可观测日志(而不是只暴露 Velocity 的 unable to connect)?
-
registerConnection soft-fail 策略
- 当前“失败就当 Ambassador、继续流程”在真·双连接撞名时可能误放行。
- 是否考虑可配置 / 可观测区分「预期 Amb 已注册」vs「异常重复连接」。
-
struck-online-mode=true 与 Forge 切服时序
- 在线玩家直通是否更容易踩中「认证成功 → 立刻连 corath → 30s 登录超时」?
B. 本地侧其它改动(仅供参考,与本 Bug 无关)
为在 Java 21 + Velocity 3.5 上跑 26.7.3 线,以及服内安全加固,我们在 bd98b152 上有过本地修改。不作为对本 Issue 的诉求,也不默认会提 PR,仅供作者知晓:
| 类别 |
摘要 |
| 构建 |
toolchain 21 + velocity 3.5(官方 RC 为 25 + 4.1) |
| 离线密码 |
PBKDF2+salt;拒绝 plain;旧格式登录后 rehash |
| logout |
detach Profile + 清 session |
| 邮箱找回 |
默认关;LOG 模式不打印验证码 |
| 绑定码 |
先销毁 code 再 bind |
| 其它 |
名称大小写、pending 注册 TTL 等 |
- 上表 与 corath 30s 超时无直接关系。
- Amb 侧另有修改,看门狗版未上生产;本 Issue 仍以当前线上 Amb 为准。
C. 支持矩阵(可选)
- 26.7.x 是否仅保证 Velocity 4.1 + Java 25?
- 是否仍考虑 Vel 3.5 + Java 21?
如需可再补脱敏日志时间线。
我尊重你对于高版本的兼容,但是我个人觉得盲目的追新会导致某些插件组合无法使用,徒增维护成本,这是我降版本的初衷。
提交前确认
HyperZoneLogin 主插件版本
已安装模块及版本
Velocity 版本
后端服务端版本
代理转发模式
当前数据库类型
已安装模块
部署结构
问题类型
复现步骤
预期结果
unable to connect。实际结果
认证成功(Yggdrasil / Entry)unable to connect to server corathfailed forwarding backend forge packet (RegistryPacket/ConfigDataPacket/...) to client,clientState=LOGIN+StacklessClosedChannelExceptionregisterConnection失败仅 debug:maybe using Ambassador),说明作者已知共存,但 缺少正式协作契约。相关日志(生产代理日志摘录;玩家名 / 公网 IP 已脱敏;本机回环地址保留)
启动与模块:
案例 A(可精确复现的 30s 后端登录超时):玩家
PlayerA,Mojang Entry同一玩家同日多次重复同一模式(均为 connected → 恰好 30s → disconnected / unable to connect):
案例 B(认证成功 + 30s 失败 + 随后 Amb 转发 Forge 包刷屏):玩家
PlayerB同日统计:
说明:
corath的登录握手窗口(稳定约 30s)。clientState=LOGIN,通道已关仍刷屏(当前线上 Amb 尚未换看门狗/去重版)。相关配置片段(已脱敏)
start.confcore.conf(关键段)auth-yggdEntry与日志对齐的要点
mode=outpre+auth-host=127.0.0.1+auth-port=25581+auth-label=verify→ 与日志 outpre adapter 一致post-auth-default-server=corath→ 与失败目标服一致struck-online-mode=true→ 在线玩家可能跳过等待区直进,与 Forge/Ambassador 握手时序可能相关已尝试的排查
OutPreAuthSessionHandler对registerConnection==falsesoft-fail(注释提及 Ambassador)OutPreBackendBridge组合包装真实VelocityServerConnection写入connectionInFlight其他补充信息 / 希望作者协助的点
A. 本 Issue 主问题(outpre + Forge/Ambassador)
我们不是要求 Amb 成为 HZL 官方依赖,但希望在文档或 API 层明确 outpre 与会提前
registerConnection/ 修改 LOGIN 状态机的第三方插件 如何共存:outpre × Forge 握手所有权
LOGIN时,HZL 是否应有超时与可观测日志(而不是只暴露 Velocity 的unable to connect)?registerConnectionsoft-fail 策略struck-online-mode=true与 Forge 切服时序B. 本地侧其它改动(仅供参考,与本 Bug 无关)
为在 Java 21 + Velocity 3.5 上跑 26.7.3 线,以及服内安全加固,我们在
bd98b152上有过本地修改。不作为对本 Issue 的诉求,也不默认会提 PR,仅供作者知晓:C. 支持矩阵(可选)
如需可再补脱敏日志时间线。
我尊重你对于高版本的兼容,但是我个人觉得盲目的追新会导致某些插件组合无法使用,徒增维护成本,这是我降版本的初衷。