跳到主要内容

登录流程详解

EMC 高级登录采用 QQ OAuth 授权 + 轮询模式,完整的登录流程包含多个阶段。

登录状态机

插件为每个玩家维护一个 LoginSession,包含以下状态:

状态说明
PENDING_SCAN等待玩家点击链接完成 QQ 授权
PENDING_PASSWORDQQ 授权成功,等待输入 AuthMe 旧密码验证
PENDING_SET_PASSWORD需要设置离线备用密码
LOGGED_IN登录完成

阶段一:进入服务器

玩家加入服务器后,插件会:

  1. 创建新的 LoginSession
  2. 保存玩家当前状态(背包、盔甲、经验、生命值、饱食度、游戏模式)到 pending_states.yml 文件
  3. 清空玩家背包,设置冒险模式,添加隐身效果
  4. 异步请求登录 API(act=login&mode=poll),获取 QQ 授权 URL 和登录码
  5. 通过 tellraw 发送可点击的授权链接

阶段二:等待授权

插件以配置的间隔(默认 3 秒)异步轮询 API(act=check):

  • 等待中(status=0) — 继续轮询
  • 授权成功(status=1) — 获取 social_uidnicknametoken,进入下一阶段
  • 已过期(status=2) — 自动重新请求登录 API,发送新的授权链接

阶段三:封禁检查

QQ 授权成功后,插件会依次检查:

  1. 联合封禁 — 调用 API(act=ban&do=check_ban)查询中央数据库
  2. 本地封禁 — 检查本地 bans.yml 文件

如果玩家被封禁,将显示封禁原因和期限,并踢出服务器。

阶段四:AuthMe 继承(可选)

如果启用了 AuthMe 联动且玩家名在 AuthMe 数据库中已注册:

  • 首次登录 — 提示输入旧 AuthMe 密码,验证通过后标记为已继承
  • 已继承过 — 跳过密码验证,直接完成登录

如果 AuthMe 中没有该玩家名的记录,进入离线密码设置阶段。

阶段五:设置离线密码

未在 AuthMe 注册的玩家需要设置一个 4-30 位的离线密码:

  • 密码会以 AuthMe SHA256 格式($SHA$salt$hash)写入数据库
  • 用于服务器切换到离线模式时的备用登录

阶段六:登录完成

  • 将 Session 状态设为 LOGGED_IN
  • pending_states.yml 恢复玩家全部状态
  • 移除隐身效果,恢复原游戏模式
  • 发送登录成功消息

崩溃恢复

如果服务器在玩家登录过程中崩溃:

  • 玩家状态已持久化在 pending_states.yml
  • 重连时插件检测到残留数据,直接清空当前状态(数据安全保存在文件中)
  • 登录完成后从文件恢复,不会丢失任何物品

行为限制

未登录玩家的以下行为会被拦截:

  • 移动位置(允许转头)
  • 交互、物品栏点击
  • 丢弃/拾取物品
  • 破坏/放置方块
  • 受到/造成伤害
  • 饥饿值变化
  • 执行命令
  • 聊天(密码输入阶段除外)