- 版权类型
- 原创
- 插件中文名称
- MikuAuth | 新时代菜单登录插件
- 插件英文名称
- MikuAuth | 新时代菜单登录插件
- 原帖地址
- #
- 支持的核心(代理端)
- Velocity
- 语言支持
- 中文(简体)
- 前置组件
- 任意Limbo环境
PacketEvents
- 适配版本(Java)
- 最新版本
[MD]
# MikuAuth
> **Velocity 登录验证插件** —— 正版与基岩版玩家免密进入,离线玩家用密码登录,
> 并附带原版对话框菜单、账号生命周期管理与完整的风控能力。




---
## 目录
- [它解决什么问题](#它解决什么问题)
- [功能一览](#功能一览)
- [环境要求](#环境要求)
- [安装](#安装)
- [快速开始](#快速开始)
- [玩家会看到什么](#玩家会看到什么)
- [命令](#命令)
- [权限](#权限)
- [配置说明](#配置说明)
- [工作原理](#工作原理)
- [文件说明](#文件说明)
- [常见问题](#常见问题)
- [已知限制](#已知限制)
---
## 它解决什么问题
Velocity 代理本身不做玩家身份验证:离线模式下**任何人都能用任意昵称进入服务器**,
盗号、冒充、刷小号几乎零成本。
MikuAuth 在代理层补上这一环:
- **正版玩家**:自动识别并走 Mojang 会话校验,通过后**免密进入**,体验无感;
- **基岩版玩家**:通过 Floodgate 识别,同样**免密进入**;
- **离线玩家**:进服后停在专用认证服,用密码完成注册/登录,认证通过才放行到正式服。
同时它把"离线账号"当成真正的账号体系来管理:密码可改可重置、账号绑定设备身份、
改名不会丢数据、按 IP 限制刷小号、暴力破解会被临时封禁。
---
## 功能一览
### 登录验证
| 能力 | 说明 |
| --- | --- |
| **正版多源查询** | 并发查询 Mojang 官方 API 与 Ashcon / WPME 镜像,任一确认即按正版处理;权威源与镜像结果矛盾时保守拒绝,避免昵称被抢注 |
| **正版免密** | 正版玩家直接连目标服,不经过认证服,无感知进入 |
| **防昵称抢注** | PreLogin 阶段记录该昵称的正版 UUID,连接建立时核对实际 UUID,不一致直接拒绝 |
| **基岩版免密** | 通过 Floodgate 识别基岩版玩家并直接放行(同时规避 limbo 与 Geyser 的注册表兼容问题) |
| **同 IP 会话免密** | 离线玩家密码登录成功后,在有效期内从同一 IP 再次进入免密 |
| **原版对话框菜单** | 客户端 1.21.6+ 时弹出原版 Dialog 表单直接输入密码;更低版本自动降级为聊天栏 + Title + BossBar |
### 账号安全
| 能力 | 说明 |
| --- | --- |
| **BCrypt 密码哈希** | 成本因子可配,密码永不明文落库 |
| **跨会话失败封禁** | 同一 IP 与同一账号两个维度累计失败次数,超阈值临时封禁(单次连接的限制可被"断线重连"绕过,本机制不能) |
| **同 IP 账号上限** | 限制单个 IP 可注册的账号数,正版账号不计入配额 |
| **密码策略** | 长度与字符集统一校验;注册、玩家改密、管理员重置三处共用同一套规则 |
| **提交频率限制** | 同 IP 短时间重复提交被拒绝,同一账号的并发提交只放行一次,防止 BCrypt 洪泛 |
| **会话即时失效** | 改密 / 重置密码会清除该账号的会话免密记录,旧凭证立即作废 |
### 账号生命周期
| 能力 | 说明 |
| --- | --- |
| **玩家自助改密** | `/changepassword`,不必再找管理员删密码重注册 |
| **管理员重置密码** | `/mikuauth setpassword`,**保留账号**(对比删除密码会丢账号所有权) |
| **账号身份 UUID 化** | 账号以 UUID 为身份键:正版玩家在 Mojang 改名后,数据自动跟随玩家 |
| **改名自动迁移** | 改名后旧昵称自动释放、账号数据(密码/注册信息/登录统计)完整保留 |
| **死昵称自动清理** | 旧昵称的残留正版记录会被自动识别并清理,不再出现"谁都进不来"的昵称 |
| **手工兜底** | `/mikuauth unbind` 清除正版绑定:自动清理刻意跳过的场景(记录带密码、需立即释放昵称)用它处理 |
### 管理与运维
| 能力 | 说明 |
| --- | --- |
| **一键诊断** | `/mikuauth diagnose <玩家>` 回放该昵称的完整进服判定链路,直接告诉你"他为什么进不来" |
| **名下账号查询** | `/mikuauth accounts <玩家>` 列出同 IP 下的所有账号 |
| **文案全可自定义** | `messages.yml` 覆盖所有游戏内文本,支持 MiniMessage 与 `{占位符}` |
| **配置自动补充** | 升级后新增的配置段/文案会自动补进你的文件(只增不改,留 `.bak` 备份) |
| **数据库自动升级** | 启动时自动补建表/索引;账号表结构升级在事务中完成并带行数校验 |
### 存储
- **SQLite**:单文件、零外部依赖,适合单代理实例(默认);
- **MariaDB**:连接池(HikariCP),适合多代理实例共享同一套账号库。
---
## 环境要求
| 项目 | 要求 |
| --- | --- |
| 代理 | **Velocity 3.x**(编译目标 Java 17) |
| 必需插件 | **packetevents-velocity**(必须使用官方完整版,对话框与登录流程基于它实现) |
| 可选插件 | **floodgate**(未安装时基岩版按常规离线账号处理,不影响其它功能) |
| 客户端 | 对话框需 **1.21.6+**;更低版本自动降级为聊天栏提示,功能不受影响 |
| 数据库 | 内置 SQLite,或自备 MariaDB 10.5+ |
---
## 安装
1. 把 `MikuAuth-<版本>.jar` 放入 `plugins/` 目录;
2. 确保 `packetevents-velocity` 也已安装;
3. 启动代理,插件会自动生成 `plugins/MikuAuth/config.yml` 与 `messages.yml`;
4. 按需修改配置后重启代理(或执行 `/mikuauth reload`)。
> **升级提示**:升级时请先删除 `plugins/` 下的旧版 jar —— 插件 id 相同,新旧 jar 共存会重复加载。
---
## 快速开始
最少只需要确认两件事:
```yaml
server:
# 认证服:离线玩家在这里完成注册/登录(通常是一个 limbo 空服)
auth-server: "auth"
# 认证通过后要去的正式服;留空则使用玩家原本要去的服务器
fallback-server: "lobby"
```
然后在 Velocity 的 `velocity.toml` 中确保 `auth` 服务器存在(通常是一个 limbo 服,
如 `pico_limbo` / `LimboAPI` 提供的空服)。玩家连接流程即可正常工作。
**首次验证建议**:用正版账号连一次(应无感进入),再用离线客户端连一次
(应进入认证服并弹出登录/注册提示)。
---
## 玩家会看到什么
```
玩家连接
│
├─ 正版玩家 ──────────────→ 直接进入目标服(无感)
├─ 基岩版玩家 ────────────→ 直接进入目标服(无感)
└─ 离线玩家 ──→ 认证服(limbo)
│
├─ 同 IP 会话有效 ──→ 免密放行(无感)
├─ 已注册 ─────────→ 弹对话框 / 提示 /login <密码>
└─ 未注册 ─────────→ 弹对话框 / 提示 /register <密码> <确认密码>
│
└─ 认证成功 → 自动转服到正式服
```
未认证的玩家只能使用认证相关命令,尝试其它命令会得到提示;认证超时会显示
BossBar 倒计时,超时自动踢出。
---
## 命令
### 玩家命令
| 命令 | 别名 | 说明 |
| --- | --- | --- |
| `/login <密码>` | `/l`、`/log` | 登录 |
| `/register <密码> <确认密码>` | `/reg` | 注册 |
| `/changepassword <当前密码> <新密码> <确认新密码>` | `/cp`、`/changepw` | 修改密码(需已认证) |
> 别名可在 `config.yml` 的 `commands` 段自定义,**修改后需重启代理**(别名在启动时注册)。
> 出于安全考虑,这些命令**不提供参数补全**。
### 管理员命令
需要权限 `mikuauth.admin`(控制台默认拥有)。
| 命令 | 说明 |
| --- | --- |
| `/mikuauth accounts <玩家>` | 查询该玩家 IP 名下的所有账号 |
| `/mikuauth diagnose <玩家>` | 诊断该昵称为什么进不来(回放完整判定链路) |
| `/mikuauth setpassword <玩家> <新密码>` | 重置密码,**保留账号**(推荐) |
| `/mikuauth deletepassword <玩家>` | 删除密码,账号回到"未注册"(会丢失账号所有权,谨慎使用) |
| `/mikuauth unbind <玩家>` | 清除正版绑定,把账号降级为普通离线账号 |
| `/mikuauth unlock <玩家\|IP>` | 解除登录失败导致的临时封禁 |
| `/mikuauth limit [数量]` | 查看 / 临时设置每 IP 账号上限 |
| `/mikuauth reload` | 重载配置与语言文件 |
---
## 权限
| 权限 | 默认 | 说明 |
| --- | --- | --- |
| `mikuauth.admin` | 仅控制台 | 使用 `/mikuauth` 管理命令 |
> 未认证玩家的命令白名单由插件内部控制,无需额外配置权限节点。
---
## 配置说明
`config.yml` 分 11 个段落,全部带中文注释:
| 段落 | 作用 | 关键项 |
| --- | --- | --- |
| `server` | 认证服与目标服 | `auth-server`、`fallback-server` |
| `premium` | 正版验证 | `enabled`、`mojang`/`ashcon`/`wpme`、`fail-closed`、`auto-migrate-renamed` |
| `bedrock` | 基岩版 | `auto-login`、`username-prefix` |
| `session` | 同 IP 会话免密 | `enabled`、`duration-minutes` |
| `registration` | 注册限制 | `min-password-length`、`max-password-length`、`max-accounts-per-ip` |
| `login` | 登录流程 | `max-tries`、`timeout-seconds`、`bcrypt-cost` |
| `dialog` | 对话框菜单 | `show-delay-millis` |
| `display` | 提示样式 | `title`、`bossbar`、`bossbar-color`、`bossbar-overlay` |
| `database` | 存储后端 | `type`(sqlite/mariadb)、`file`、`mariadb.*` |
| `security` | 风控 | `max-failures`、`failure-window-minutes`、`lockout-minutes` |
| `commands` | 命令别名 | `login-aliases`、`register-aliases`、`changepassword-aliases` |
### 几个值得注意的配置
**`premium.fail-closed`**(默认 `true`)
三个验证源全部失败时(例如网络问题),是拒绝未注册玩家进入,还是按离线处理。
`true` 更安全(防止正版昵称被抢注),`false` 可用性更好。
**`premium.auto-migrate-renamed`**(默认 `true`)
正版玩家改名后自动迁移账号数据并释放旧昵称。**建议保持开启** ——
关闭后旧昵称会被旧记录永久占住,只能手工用 `/mikuauth unbind` 处理。
**`security`** 段解决的是"断线重连即清零"的问题:
`login.max-tries` 只限制单次连接内的尝试次数,而 `security.max-failures`
按 IP 与账号两个维度累计失败,超过阈值临时封禁。
**`session.duration-minutes`**
同 IP 会话免密是离线账号唯一的跨会话免密机制。若你对共享 IP
(NAT、网吧、合租)有顾虑,可把时长调小(如 15 分钟),或直接关闭。
### 语言文件
`messages.yml` 覆盖所有游戏内文本,支持 MiniMessage 格式与占位符:
```yaml
login:
title: "<gradient:#ffd700:#ff8800>请 登 录</gradient>"
chat-usage: "<gray>请输入</gray> <yellow>/login <密码></yellow> <gray>完成登录"
```
---
## 工作原理
### 登录模式决策链
在 PreLogin 阶段(异步)决定这条连接按什么模式处理:
```
基岩版昵称 ─────────────────────────────→ 强制离线模式(连接后由 Floodgate 免密放行)
已注册正版账号 ─────────────────────────→ 强制正版会话校验(连接后免密)
已注册离线账号(有密码)────────────────→ 强制离线模式(连接后密码登录)
无记录 → 并发查询三个验证源:
任一源确认正版 → 强制正版会话校验
明确离线 → 强制离线模式
全部失败 → 按 fail-closed 配置决定拒绝或离线
```
### 账号身份模型
账号记录以 **UUID** 为身份键,昵称只是唯一索引:
| 账号类型 | 身份键 | 改名后 |
| --- | --- | --- |
| 正版账号 | Mojang UUID | UUID 不变 → 账号数据自动跟随玩家,旧昵称自动释放 |
| 离线账号 | 离线 UUID(由昵称推导) | 离线模式下"账号即昵称",改名等于换号 |
这样正版玩家改名不会丢账号,也不会留下"谁都进不来的旧昵称"。
### 数据库
```
miku_players 账号表(uuid 主键 + 昵称唯一索引)
miku_sessions 同 IP 会话免密记录
```
升级时账号表结构会自动迁移(事务内重建 + 行数校验 + 方言化的换表方式),
历史遗留的重复记录会在迁移时清理并打印被释放的昵称。
---
## 文件说明
```
plugins/MikuAuth/
├── config.yml 主配置(自动生成,带完整中文注释)
├── messages.yml 语言文件(所有游戏内文本)
├── config.yml.bak 配置自动补充前的备份(仅在发生过补充时存在)
└── database.db SQLite 数据库(使用 MariaDB 时不生成)
```
---
## 常见问题
**Q:玩家一直卡在"正在连接"?**
先用 `/mikuauth diagnose <玩家>` 查看判定链路。最常见的原因是认证服未配置或未启动,
以及正版验证源全部失败时的 fail-closed 拒绝。
**Q:正版玩家进不来,提示验证失败?**
检查代理的 `velocity.toml` 是否开启了 `online-mode`(本插件需要正版校验能力)。
若该玩家刚在 Mojang 改过名,2.3.0 起会自动迁移账号,旧昵称也会被自动释放。
**Q:离线玩家换网络后就要重新输密码?**
这是同 IP 会话免密的预期行为(会话按 IP 判定)。这是原版客户端能力下的唯一选择 ——
Minecraft 客户端的 Cookie 只在内存中、断开即丢失,无法用于"记住设备"。
**Q:想限制一个人注册大量小号?**
配置 `registration.max-accounts-per-ip`(正版账号不计入配额),
也可用 `/mikuauth limit <数量>` 临时调整。
**Q:怎么让玩家改密码?**
告诉玩家用 `/changepassword`。若玩家忘了密码,管理员用
`/mikuauth setpassword <玩家> <新密码>` 重置(保留账号,不要用 `deletepassword`)。
**Q:对话框没弹出来?**
对话框需要客户端 **1.21.6+**,且需要 `packetevents-velocity` 正常加载。
不满足时会自动降级为聊天栏 + Title + BossBar 提示,功能不受影响。
---
## 已知限制
- **离线账号的身份由昵称决定**:离线 UUID 由昵称推导,离线玩家改名等于换号。
这是离线模式的固有属性,插件无法改变。
- **对话框提交密码走原版命令通道**(`/login <密码>`),密码在代理侧是明文命令。
请勿在代理上安装会记录命令内容的插件,也不要开启 Velocity 的命令日志。
- **同 IP 会话免密无法区分共享同一 IP 的不同玩家**(NAT、网吧、合租)。
有顾虑请缩短会话时长或关闭该功能。
- **自动清理只针对没有密码的正版记录**:带密码的记录(管理员 `setpassword` 产生)
不会被自动删除,避免误删仍可登录的凭据,需用 `/mikuauth unbind` 手工处理。
- **SQLite 与 MariaDB 之间切换不会自动迁移数据**,需自行导出/导入。
[/MD]