WBDAddon —— WarZBombDefuse 第三方附加(击杀报告 / 单独伤害统计 / 比赛状态 / 饥饿锁定 / JourneyMap / 自定义)

原创 衍生资源 WBDAddon —— WarZBombDefuse 第三方附加(击杀报告 / 单独伤害统计 / 比赛状态 / 饥饿锁定 / JourneyMap / 自定义) 1.2.1

请登录后获取
[MD] # 【1.2.1 更新】开放对外 API:让第三方游戏模式复用本插件 > WarZBombDefuse 的第三方附加组件合集 > 每个功能都是独立模块,`config.yml` 单独开关,互不影响,无需改动 WBD 本体 --- ## ⚠️ 重要变更:移除「防第三人称」,不再需要 ProtocolLib 上个版本(1.0.1)新增的 `antithirdcam`(防第三人称)模块,**本次已连同代码一起删除**。 原因是实测下来它在 Arclight 这类 Forge + Bukkit 混合端上**做不到两全**: - 遮挡面摆在能挡住第三人称的位置时,第一人称一低头就会扫到它,糊一脸黑块 - 把面挪开避开第一人称,第三人称又挡不住了 根因是这套方案要求在**相机坐标系**里精确摆放一块巨大平面,而这块面能遮住哪里取决于客户端的 FOV、视角距离设置、实体渲染距离 —— **这些服务端全都拿不到**,只能靠一次次试。更根本的一点:面被摆在「相机下方」时,它主要盖住的是视野的**下方**,而隔掩体偷看看的是**正前方**,所以它的实际防护效果本来就有限。 与其留着一个「看起来在跑、其实未必挡得住」的功能,不如直接去掉。 **连带影响:** | 项目 | 变化 | | --- | --- | | **ProtocolLib** | **不再需要**。它当初只是为了让遮挡面「只对本人可见」而引入,现在已无任何模块依赖它,`plugin.yml` 的软依赖与 `pom.xml` 的依赖均已删除 | | `NOTICE.md` | 已删除(那份「防第三人称现在需要 ProtocolLib」的告知随之作废) | | `/wbdaddon diag` | **命令已移除**。它就是为诊断该模块的 API 可用性而加的 | | 旧配置 | `config.yml` 里的 `modules.antithirdcam` 整段可以直接删掉,留着不会有任何效果 | > 如果你当初是为了这个模块才装的 ProtocolLib,现在可以把它一起移除了。 --- ## 🌟 头号新功能:对外 API —— 让第三方游戏模式复用本插件 ### 改造前的问题 在此之前,每个模块都用同一句话判断「这个玩家在不在竞技场」: ```java wbd.getArenaManager().getSession(player) != null ``` 这句话把「在竞技场里」和「在 WBD 的爆破模式里」划了等号。于是一个独立实现的模式(比如团队死斗)的玩家不在 WBD 的 `ArenaSession` 里,**所有模块都看不见他们** —— 饥饿不锁、JourneyMap 上队友敌军分不清,而且**不会报任何错**。 ### 现在 WBDAddon 把「一个游戏模式」抽象成 `AddonMode` 接口,并发布 `WbdAddonApi` 服务。任何第三方模式都可以注册进来,让上面那些附加功能**自动**对新模式的玩家生效 —— 不必每个模式各写一遍。爆破模式本身也变成了这个接口的一个实现(内置注册,永远排在第一位)。 ### 用法 模式侧只需要实现 `AddonMode`: ```java public final class MyMode implements AddonMode { @Override public String getModeId() { return "my-mode"; } // 稳定标识 @Override public String getDisplayName() { return "我的模式"; } @Override public boolean isParticipating(Player p) { return match(p) != null; } @Override public boolean isPlaying(Player p) { return match(p) != null; } @Override public boolean isAlive(Player p) { return match(p) != null && match(p).isAlive(p); } @Override public String getTeamId(Player p) { return match(p).teamId(p); } // "T" / "CT" / null @Override public String getArenaId(Player p) { return match(p).arenaId(); } @Override public String getArenaName(Player p) { return match(p).arenaName(); } } ``` 然后在自己的 `onEnable` 里注册: ```java RegisteredServiceProvider<WbdAddonApi> rsp = Bukkit.getServicesManager().getRegistration(WbdAddonApi.class); if (rsp == null) return; // WBDAddon 没装,降级即可 rsp.getProvider().registerMode(new MyMode()); ``` > 在 `plugin.yml` 里写 `softdepend: [WBDAddon]`,就能保证自己的 `onEnable` 一定在服务发布之后执行,不必延迟到下一 tick。 > 记得在自己的 `onDisable` 里 `unregisterMode("my-mode")`,否则 WBDAddon 的定时任务会一直踩到一个已经卸载的模式对象。 ### `WbdAddonApi` 提供了什么 | 方法 | 作用 | | --- | --- | | `getApiVersion()` | API 版本号(当前 `1.2`),可据此判断有没有自己要用的能力 | | `registerMode(mode)` / `unregisterMode(id)` | 注册 / 注销模式。同一 id 重复注册会覆盖,重载时不必先注销 | | `getModes()` / `getMode(id)` / `getModeFor(player)` | 查询已接入的模式与玩家归属 | | `isInAnyMode(player)` | 玩家是否属于任一已注册模式 | | `resolveWeaponName(player)` | 解析玩家手中武器的人类可读名(TacZ 枪械 `tacz:p320 → P320`) | | `getCombatStats()` | 取伤害账本,做击杀归属校正或自建伤害统计;模块被禁用时返回 `null` | | `isHudRelayAvailable()` | 本插件此刻是否真的会代你渲染顶部状态行 | ### 注册后自动获得什么 | 能力 | 由哪个模块提供 | 触发条件 | | --- | --- | --- | | 饥饿锁定(跑速恒定、不回血) | `arena-food` | `isParticipating` 为 true | | JourneyMap 队友可见 / 敌军隐藏 | `journeymap-bridge` | `isAlive` 且有 `getTeamId` | | 顶部状态行代渲染 | `match-status` | 实现了 `hudLine`,且该模块启用 | | 伤害账本(击杀归属校正) | `kill-reports` | 通过 `api.getCombatStats()` 取用 | | 枪械名解析 | 内置 | 通过 `api.resolveWeaponName(player)` 取用 | ### 两个容易踩的坑 1. **`hudLine` 只是「申请」,不保证有人发。** 代渲染取决于 `match-status` 模块是否启用、它的顶栏开关有没有被服主关掉。注册后请调用一次 `api.isHudRelayAvailable()`,返回 `false` 时自己把 HUD 发出去 —— 否则玩家屏幕上会什么都没有,且不报错。 2. **JourneyMap 桥接受「玩家当前使用哪块计分板」影响。** 原版队伍数据跟着玩家当前所用的计分板下发,所以模式如果给玩家 `setScoreboard(自己的独立计分板)`,就会顺带把 `wbd_*` 队伍数据从该玩家那里屏蔽掉,JourneyMap 于是读不到队友关系。想同时要自定义侧边栏和 JourneyMap 桥接,就把侧边栏注册在**主计分板**上。 --- ## 🧩 API 1.2 新增:队友名牌前缀 + 隐藏敌人名牌 模式现在可以额外实现两个方法,让队友头顶带前缀、敌人名牌完全隐藏: | 方法 | 作用 | | --- | --- | | `nameTagPrefix(player)` | 队友头顶的名牌前缀,返回 `null` 表示不改动名牌 | | `hideEnemyNameTags()` | 是否隐藏敌人的头顶名牌 | 实现走的是**原版队伍的 `NAME_TAG_VISIBILITY`**,不需要任何发包插件。两项设计成配对使用:只加前缀而不管可见性的话,敌人头上也会顶着一个 `[队友]`,比不做还糟。 **多模式共存的隔离**:生成的队伍名形如 `wbd_<模式id>_<阵营id>`(例:`wbd_bomb_def_T`)。带上模式 id 是必要的 —— 爆破与死斗都有 T/CT,若只按阵营拼名,两个模式的玩家会挤进同一个原版队伍,在 JourneyMap 上互相看得见,那等于把敌军位置显示给了对手。名字会被裁剪到原版 16 字符上限以内。 > **对爆破玩法没有任何影响**:内置的爆破模式这两个方法都用默认值(不改名牌、不隐藏),因为爆破模式的名牌显示由 WarZBombDefuse 本体自己负责,附加组件擅自设前缀会和主插件抢同一个队伍的 prefix。 --- ## ⌨️ 命令变动 | 命令 | 状态 | 作用 | | --- | --- | --- | | `/wbdaddon modes` | **新增** | 查看已接入的游戏模式与各自的在线人数 | | `/wbdaddon diag` | **已移除** | (原为诊断防第三人称的 API 可用性而加) | | `/wbdaddon reload` | 不变 | 重载配置并重新启停模块 | | `/wbdaddon modules` | 不变 | 查看各模块启用状态 | | `/wbdaddon sound <音效名> [音调]` | 不变 | 试听拆弹提示音 | > 排查「第三方模式接进来了但附加功能没生效」时先看 `/wbdaddon modes`: > 模式没出现说明注册没成功(多半是加载顺序);模式在、人数为 0 说明它的 `isParticipating` 判定写错了。 --- ## 🔧 内部重构 - **伤害账本对外**:`kill-reports` 的伤害累计表抽成 `CombatStats` 接口(`recordDamage` / `getDamageSources` / `reset`),第三方模式可以拿它做击杀归属校正,也可以 `reset()` 在每场比赛开始时清账 - **枪械名解析提到工具类**:原本埋在淘汰消息监听器的私有方法里,现在提取为 `WeaponNames` 并经由 `api.resolveWeaponName(player)` 对外复用。自己实现一遍枪械改名不难,但要把 TacZ 桥接、自定义显示名、lore 回退、颜色码剥离这些边界都处理对就没那么轻松了 - **所有模块改为面向 `AddonMode` 判定玩家**,不再直接认识 WarZBombDefuse 的 `ArenaSession`。这就是第三方模式能被自动覆盖到的前提 --- ## 📦 升级步骤 1. 删掉 `plugins/` 里旧的 `WBDAddon-*.jar`(**文件名不认,Bukkit 只认插件名,留着多个会冲突**) 2. 放入新的 `WBDAddon-1.2.1-xxxxxxx-xxxxxxxx-xxxx.jar` 3. **不需要 ProtocolLib** —— 如果你当初是为了本插件装的,可以一并移除 4. 重启服务器,或执行 `/wbdaddon reload` > 旧版配置文件不会自动补上新配置项,建议对照新版 `config.yml` 手动合并,或删掉重新生成。 > 旧配置里的 `modules.antithirdcam` 整段已无对应模块,删掉即可。 --- ## 📋 模块一览 | 模块 | id | 说明 | | --- | --- | --- | | 击杀报告 | `kill-reports` | 淘汰提示显示击杀者与武器;回合结束给每人单独发送自己的伤害统计 | | 比赛状态 | `match-status` | 顶部显示 T/CT 存活人数;炸弹安放后 Bossbar 倒计时 | | 拆弹声音提示 | `bomb-defuse-sound` | CT 拆弹时向全图播放可定位的提示音与滴答声 | | 竞技场饥饿锁定 | `arena-food` | 饥饿恒定到安全值:跑速恒定、不自然回血 | | JourneyMap 桥接 | `journeymap-bridge` | 同步队伍到原版 Team,配合 JourneyMap Teams 队友可见、敌军隐藏 | | 模式接入 API | — | **新增** — 通过 `WbdAddonApi` 让第三方模式复用上面这些能力 | | 防第三人称(已移除) | ~~antithirdcam~~ | **本次删除** —— 实测在混合端上做不到两全,连同 ProtocolLib 依赖一并删除 | --- ## 🔗 配合使用:WBDTeamDeathmatch 本 API 的第一个使用方是同一作者的 **WBDTeamDeathmatch**(团队死斗模式,无限复活 / 限时击杀赛)。 它通过注册 `AddonMode` 直接复用本插件的饥饿锁定、JourneyMap 桥接、伤害账本与枪械名解析, 并覆盖了自己的名牌策略(死斗的近身缠斗节奏下,隐藏敌人名牌比显示它更合理)。 --- 有问题欢迎回帖或提 Issue,反馈 QQ:2387629002 [/MD]
[MD] # 【1.0.1 更新】新增防第三人称与拆弹声音提示 > WarZBombDefuse 的第三方附加组件合集 > 每个功能都是独立模块,`config.yml` 单独开关,互不影响,无需改动 WBD 本体 --- ## ⚠️ 先说重点:本次新增一个依赖 **「防第三人称」模块需要 [ProtocolLib](https://hangar.papermc.io/dmulloy2/ProtocolLib/versions)。** 如果你在 **Arclight / Spigot** 上开服,请务必装上,否则这个模块会**自动禁用**。 为什么非得要它?防第三人称的原理是给玩家挂一块「只对本人可见」的遮挡面,而「只对本人可见」这件事,Arclight 上**用 Bukkit 自带的方法做不到**——那些方法签名都在、调用也不报错,就是一点效果都没有,结果遮挡面会挂在**所有人**身上(玩起来就是「黑块糊在对手脸上还跟着跑」)。 所以改成在数据包层拦截:你装了 ProtocolLib,插件就能把遮挡面的实体包**只发给本人**,别人客户端根本收不到这个实体。 **不装会怎样?** 不会报错、不会崩、也不会有黑块——插件会主动检测并**直接禁用这个模块**,其它模块照常工作。 > 如果你用 **Paper / Folia**,那边的隐藏 API 是真有效的,可以不装 ProtocolLib,只需把配置里的 `require-protocol-lib` 设为 `false`。 --- ## 新增模块 ### 1. 防第三人称偷看(`antithirdcam`) 有些玩家会切第三人称隔着掩体偷看。第三人称是**纯客户端按键**,服务端既禁不掉也侦测不到,所以这里换个思路——**遮挡**: - 给参赛玩家挂一块巨大的黑色遮挡面,**只对该玩家本人可见** - 切到第三人称时视野被糊住,隔墙偷看就失去意义了 - 只在竞技场内对**参赛且仍存活**的玩家生效;观战者、大厅玩家、本回合已阵亡的人都不受影响 - 遮挡面每 tick 主动跟随玩家,不改变玩家自身的任何状态 > 实现思路参考开源插件 [AntiF5](https://github.com/ladakx/AntiF5) ### 2. 拆弹声音提示(`bomb-defuse-sound`) **WBD 本体在「开始拆弹」和整个拆弹过程中是完全静音的**——它只在拆除成功(`bomb-defused`)和进度被中断(`cancel`)时才有音效。结果就是 CT 蹲下去拆弹,T 阵营一点动静都听不到,等于没有博弈信息。 本模块补上这一段: - CT 开始拆弹时,在 **C4 所在位置**播放一声提示音,随后按固定间隔持续播放滴答声 - 声音以 C4 为音源,**带方位与距离衰减**——T 能听出「有人在拆」以及「大概在哪个方向」,而不是只收到一句广播 - 默认可听范围约 **32 格**(音量可调,17 音量约等于 256 格) - 音效可以换,默认用 `BLOCK_NOTE_BLOCK_BIT`(8-bit 芯片音色)做电子「嘀嘀嘀」 - 中断音与成功音默认**留空**,因为 WBD 本体已经有了,避免重复出声 --- ## 其他改进 **比赛状态新增「方块串」存活样式** 除了原来的数字样式(`T 存活 3/5`),现在可以切换成方块串,每人一个方块、用亮色/暗色区分存活与淘汰,一眼看清还剩几个人: ```yaml modules: match-status: alive-display-style: block ``` **新增两个命令** | 命令 | 作用 | | --- | --- | | `/wbdaddon sound <音效名> [音调]` | 试听拆弹提示音(连播三次),不带参数会列出推荐音效清单 | | `/wbdaddon diag` | 环境诊断:列出你服务端有哪些 API 可用、ProtocolLib 是否就位 | 挑音效原来只能真去拆一次弹才听得到,现在直接试听就行。 --- ## 修复 - **防第三人称的黑块泄漏**:此前遮挡面对所有人可见(就是上面说的「黑块糊脸」),已改为 ProtocolLib 数据包层拦截 - **缺少依赖时不再留下副作用**:检测不到 ProtocolLib 时直接禁用该模块,而不是半死不活地跑着 - **比赛状态**:清理离场玩家残留的 BossBar 与过期的炸弹计时记录,避免长时间运行后内存缓慢增长 - **构建产物**:文件名带上版本号 + git 短哈希 + 构建时间戳,多次构建不会互相覆盖 --- ## 升级步骤 1. 删掉 `plugins/` 里旧的 `WBDAddon-*.jar`(**文件名不认,Bukkit 只认插件名,留着多个会冲突**) 2. 放入新的 `WBDAddon-1.0.1-xxxxxxx-xxxxxxxx-xxxx.jar` 3. 需要防第三人称的话,把 **ProtocolLib 5.4.0** 也放进 `plugins/` 4. 重启服务器,或执行 `/wbdaddon reload` 装好后启动日志里应该能看到这两行: ``` 遮挡面已改用 ProtocolLib 在数据包层隐藏,只对本人可见。 [WBDAddon] 防第三人称已启动,检查间隔 20 tick,跟随方式 teleport。 ``` > 旧版配置文件不会自动补上新配置项,建议对照新版 `config.yml` 手动合并,或删掉重新生成。 --- ## 模块一览 | 模块 | id | 说明 | | --- | --- | --- | | 击杀报告 | `kill-reports` | 淘汰提示显示击杀者与武器;回合结束给每人单独发送自己的伤害统计 | | 比赛状态 | `match-status` | 顶部显示 T/CT 存活人数;炸弹安放后 Bossbar 倒计时 | | 拆弹声音提示 | `bomb-defuse-sound` | **新增** — CT 拆弹时向全图播放可定位的提示音与滴答声 | | 竞技场饥饿锁定 | `arena-food` | 饥饿恒定到安全值:跑速恒定、不自然回血 | | 防第三人称 | `antithirdcam` | **新增** — 只对本人可见的遮挡面,让第三人称失去偷看价值 | | JourneyMap 桥接 | `journeymap-bridge` | 同步队伍到原版 Team,配合 JourneyMap Teams 队友可见、敌军隐藏 | --- [/MD]

有问题欢迎回帖或提 Issue,反馈 QQ:2387629002
后退
顶部 底部