玩家在任意子服完成一个成就后,成就消息会在整个服务器群组中只播放一次,解决了即使安装了huskhomme或invsync等插件成就仍然不会跨服同步播报的问题;之后无论玩家切换到哪台子服,进度同步造成的回放都不会重复刷屏。
- 监听 Paper 的
PlayerAdvancementDoneEvent,捕获原版成就消息。 - 使用 InvSync Addon API 将每名玩家的“已播放成就 ID”保存到同步数据中。
- 首次完成的成就保留 Paper 原生 Adventure 消息(翻译键、颜色与悬停文本),并通过 Redis 发布至全部子服。
- 玩家切服后,InvSync 回放的旧成就已存在于记录中,因此会被静默跳过。
首次部署时,插件会为没有历史记录的玩家建立基线,将其已有成就标记为历史成就,避免一次性播放大量旧消息。基线窗口仅影响该玩家首次进入时的已有进度,时长可在 config.yml 调整。
- 原生支持: InvSync(通过其 Addon API 保存玩家的已播放状态)。
- 服务器核心: Paper 与 Folia,目标版本为 1.21.11、Java 21;同一 1.21 系列通常也可使用。
- 同步插件适配: 设计上可适配 HuskSync 及其他提供成就同步、共享 Redis 或可扩展玩家数据接口的同类插件。当前发行版内置的是 InvSync 适配器;使用 HuskSync 等方案前,需要增加对应适配器,不能将其当作现成的直接支持。
- 已安装并配置 InvSync,且启用
sync.advancement: true。 - 所有子服连接到同一 Redis,并使用同一套 InvSync Redis 前缀。
- 每台需要接收跨服成就消息的子服都安装本插件。
- 从 GitHub Actions 的大版本构建产物下载 JAR,或在本地构建。
- 将
InvSyncAdvancementBroadcast-<版本>.jar放入每台子服的plugins目录。 - 保持
redis.auto-detect-invsync: true,插件会读取plugins/InvSync/config.yml中的 Redis 地址、密码、数据库与前缀。 - 重启全部子服;不建议使用 PlugMan 等热加载工具。
- 在游戏中执行
/isab,确认 Redis 订阅状态和已记录的成就数量。
默认配置已适用于使用 InvSync 的标准 Redis 部署。常用配置项如下:
| 配置项 | 作用 |
|---|---|
redis.auto-detect-invsync |
自动读取 InvSync 的 Redis 连接配置,默认 true。 |
redis.channel |
跨服广播频道;留空时使用 <InvSync Redis 前缀>:advancement-broadcast:v1。 |
invsync.data-key |
InvSync 玩家数据中保存已播放成就的键;部署后不要随意修改。 |
invsync.bootstrap-delay-ticks |
新玩家首次建立历史基线前的等待 tick 数,默认 100。 |
invsync.bootstrap-scan-batch-size |
首次基线每 tick 扫描的最大成就数,避免卡顿。 |
本地构建:
.\gradlew.bat clean test shadowJar成品位于 build/libs/InvSyncAdvancementBroadcast-<版本>.jar。
仓库包含 GitHub Actions 工作流。推送格式为 vX.0.0 的大版本标签(例如 v2.0.0)时,工作流会执行测试、构建 Shadow JAR,并自动创建同名 GitHub Release;生成的 JAR 会作为 Release 附件上传,同时保留为 Actions artifact。普通提交、分支推送,以及 v1.1.0 这类非大版本标签都不会执行构建任务。
git tag v2.0.0
git push origin v2.0.0- InvSync 的重复自动保存复用缓存字节,只有获得新成就后才重新编码。
- 首次历史基线按 tick 分批扫描,并短时复用全服成就注册表快照。
- Paper 使用单次原生广播;Folia 按玩家区域线程安全调度。
- Redis 发布使用有界队列、5 秒超时与指数重连退避,故障时不会无限积压。
- 可复现的 JMH A/B 数据见 BENCHMARKS.md。
运行性能 A/B:
.\gradlew.bat jmh