一个面向 Arclight 混合端(Forge + Bukkit)的轻量补丁插件:在死亡时把死亡坐标补写进 CMI,
让玩家继续用原生的 /back 就能回到死亡点。
它不新增任何命令,不接管
/back,不做任何传送逻辑 —— 只把 CMI 该拿到的死亡点交给 CMI。
在 Arclight 混合端上,CMI 的 /back 在死亡场景下会失效,玩家死后提示「没有保存的死亡地点」,
但普通的 tp / home / warp 之后的 /back 却完全正常。
CMI 的 UserEvents.onPlayerDeath(PlayerDeathEvent) 逻辑如下:
user.setDeathLoc(new CMILocation(player.getLocation())); // 无条件写 → /dback 用
if (player.hasPermission("cmi.command.back.ondeath")) { // ← 权限门槛!
user.setLastTeleportLocation(player.getLocation(), false); // → /back 用
user.setBungeeBackLocation(null);
}
user.addForDelayedSave();注意两点:
/back读的是LastTeleportLocation,而它在死亡路径下只在玩家拥有cmi.command.back.ondeath权限时才会被写入。服务器default组通常只给了cmi.command.back,缺这一条 → 死亡后/back永远无效。- 普通传送(tp/home/warp)走的是另一条链路
UserEvents.teleportBack(PlayerTeleportEvent), 那条没有权限门槛,所以一直是好的 —— 这正是「唯独死亡不行」的原因。
此外,在 Arclight 上,深度介入死亡流程的 Forge 模组(如
Corpse 尸体模组)还可能干扰
Bukkit PlayerDeathEvent 的桥接,导致 CMI 根本收不到死亡事件。
| 方案 | 做法 | 说明 |
|---|---|---|
| 正统(推荐先做) | lp group default permission set cmi.command.back.ondeath true |
给玩家补上权限,CMI 原生逻辑即恢复正常 |
| 兜底(本插件) | 装上 DeathBack |
绕过权限门槛直接补写,并能兜住「死亡事件被吞」的极端情况 |
两者可以同时使用:权限是正统解法,插件是保险层。
- 不注册任何命令,纯被动监听:死亡时把坐标写进 CMI 的
CMIUser - 写入两步,与 CMI 原生
onPlayerDeath完全一致:setDeathLoc(new CMILocation(loc))→ 供/dback使用setLastTeleportLocation(loc, false)→ 供/back使用
- 三重数据源,确保拿得到死亡坐标:
PlayerDeathEventEntityDeathEventcorpse:corpse尸体实体生成(EntitySpawnEvent)—— 兜底,即使前两个事件被吞也能读到
- 同一玩家 3 秒内只写一次,避免重复事件把坐标覆盖成重生点
- 全部通过反射调用 CMI,不依赖 CMI 的编译期 API
| 项目 | 版本 |
|---|---|
| 服务端 | Arclight(Forge + Bukkit)1.20.1,Forge 47.4.20 |
| CMI | 9.7.12.3 与 9.8.10.3 均已逐一反汇编核对,反射接口完全一致 |
| CMILib | 1.5.5.0 / 1.6.0.1 |
| JDK | 17 |
包含的 Arclight 适配:mod 实体在 Bukkit 侧被包装为
io.izzel.arclight.common.mod.server.entity.ArclightModEntity,
需先调 getHandle() 取出 NMS 原始实体,才能反射到
CorpseEntity.getCorpseUUID()。
不需要插件操心 —— /back 走的是 CMI 的统一传送通道
TeleportHandler.teleportPlayer(player, loc, CMITeleportType.Back),
该通道内置:
getSafeLocation/getSafeTeleportationLocation—— 自动寻找安全落脚点isEmptySpaceForPlayer—— 检测落脚位置是否被占据needToFly—— 需要时自动开启飞行setTeleportInvulnerability—— 传送后短暂无敌dangerousTp—— 危险传送点记录
所以即使死亡点在岩浆里,是否安全、要不要挪位,全部由 CMI 自己判断。 本插件只负责「把坐标交给 CMI」,职责边界清晰。
- 前往 Releases 下载
DeathBack-1.1.0.jar(或自行用 Maven 构建) - 放入服务端
plugins/目录 - 重启服务器
无需任何配置,无需给玩家加权限。
玩家死亡后,控制台应出现:
[DeathBack] 已补写 CMI 死亡点 <玩家名> @ <世界> x,y,z(来源:PlayerDeathEvent)
之后玩家输入 /back 即可回到死亡点。
需要 JDK 17 + Maven:
mvn clean package产物在 target/DeathBack-1.1.0.jar。
在 Arclight 1.20.1 + CMI 9.8.10.3 的完整副本服务端上验证,全部通过:
| 项目 | 结果 |
|---|---|
| 直调写入 | DeathLoc 与 /back 目标均写入,回读坐标精确一致 |
| 3 秒防重 | 连续写入不同坐标,旧值未被覆盖 |
| 非玩家死亡事件 | 监听器正确忽略,不产生误写入 |
| 尸体兜底链路 | summon corpse:corpse 时实时读出主人 UUID |