Skip to content

通知系统

文档版本:基于 2026-06-01 代码分析

概述

通知系统负责在逃走中游戏中向特定玩家群体推送消息。通知模板由管理员在中控面板创建,支持按接收者类型(全部/存活逃走者/已淘汰/猎人/工作人员/额外指定)过滤目标,通过 notice_sender 方块或中控面板手动触发发送。通知以红色标题卡片形式出现在玩家手机的"逃走中APP"页面,同时播放三次响铃音效。


核心概念

两层通知模型

概念用途
通知模板NoticeRecordRfmNoticeData管理员创建的模板,定义"谁该收到什么"
手机通知RfmPhoneNoticeData实际推送到玩家手机的消息实例

转换链路:一个 RfmNoticeData 模板 → 按接收者类型解析目标 → 为每个目标生成一个 RfmPhoneNoticeData → 推送。

接收者类型

枚举值含义过滤规则
ALL全部玩家所有在线的玩家身份记录
RUNNER_ALIVE存活逃走者role=="runner" && !eliminated && !abstained
RUNNER_OUT已淘汰逃走者role=="runner" && eliminated
HUNTER猎人role=="hunter"
NPC工作人员role=="npc"
EXTRA额外指定仅从 extraReceivers 列表按UUID/名称解析

额外接收者叠加:不论主接收者类型是什么,extraReceivers 列表中的目标总是被追加。


架构设计

通知发送时序

mermaid
sequenceDiagram
    participant Trigger as 触发源
    participant NM as RfmNoticeManager
    participant Data as PersistentRfmNoticeSavedData
    participant AS as RfmAppNotificationService
    participant Phone as PersistentRfmPhoneNoticesSavedData
    participant Client as 玩家手机

    Trigger->>NM: sendNoticeWithResult(server, noticeId)
    Note over Trigger: 三种触发方式:<br/>A.中控面板GUI点击发送<br/>B.notice_sender红石上升沿<br/>C.notice_sender右键→中控面板

    NM->>Data: findById(noticeId)
    Data-->>NM: NoticeRecord(name, content, receiverType, extraReceivers)

    NM->>NM: resolveTargets(server, record)
    Note over NM: 1.获取所有在线玩家身份记录<br/>2.按receiverType过滤<br/>3.叠加extraReceivers<br/>4.仅保留在线玩家

    NM->>AS: notifyPlayers(server, targets, name, content)

    loop 为每个targetUuid
        AS->>Phone: append(ownerUuid, title, content)
        AS->>Client: AppendPhoneRfmNoticePayload
        AS->>AS: scheduleRingBurst(targetUuid, 3)
        Note over AS: 安排3次铃声播放(间隔2秒)
    end

    Client->>Client: 渲染卡片式通知

中控面板同步流程

mermaid
sequenceDiagram
    participant GUI as RfmManagerNoticePage
    participant Client as 客户端
    participant Server as 服务端
    participant NM as RfmNoticeManager
    participant Data as PersistentRfmNoticeSavedData

    GUI->>Client: onOpen()
    Client->>Server: RequestRfmNoticesPayload
    Client->>Server: RequestRfmNoticeTargetsPayload

    Server->>NM: syncToPlayer(player)
    NM->>Data: list() 获取全部模板
    Server->>Client: SyncRfmNoticesPayload

    Server->>NM: syncNoticeTargetsToPlayer(player)
    NM->>NM: 构建所有在线runner目标列表
    Server->>Client: SyncRfmNoticeTargetsPayload

    Client->>GUI: 渲染通知列表+目标列表

关键文件

文件说明
com/chenxi/chenxi_rfm/server/rfm/RfmNoticeManager.java通知管理核心
com/chenxi/chenxi_rfm/server/rfm/RfmAppNotificationService.java手机通知推送服务
com/chenxi/chenxi_rfm/server/config/rfm/PersistentRfmNoticeSavedData.java通知模板持久化
com/chenxi/chenxi_rfm/server/config/rfm/PersistentRfmPhoneNoticesSavedData.java手机通知持久化
com/chenxi/chenxi_rfm/common/rfm/notice/RfmNoticeReceiverType.java接收者类型枚举
com/chenxi/chenxi_rfm/common/block/NoticeSenderBlock.java通知发送器方块
com/chenxi/chenxi_rfm/common/block/NoticeSenderBlockEntity.java方块实体(绑定+红石触发)
com/chenxi/chenxi_rfm/common/rfm/notice/RfmNoticeVariableType.java变量类型枚举(预留设施)
com/chenxi/chenxi_rfm/server/command/rfm/RfmNoticeCommand.java/nfa rfm notice clear

关键流程

三种触发方式

方式触发条件入口
中控面板管理员在通知标签页点击"发送"RfmPayloadHandler.handleUpdateRfmNotice(ACTION_SEND)
红石信号notice_sender 方块收到红石上升沿NoticeSenderBlockEntity.serverTick()
右键+发送管理员右键 notice_sender → 中控面板 → 手动发送同上路径A

NoticeSender 方块特性

  • 方块属性:POWERED(BooleanProperty),由红石信号控制
  • 右键交互:需 GAME_ADMIN 权限,打开发送面板并自动选中已绑定的通知
  • 红石触发:POWERED=truetriggered=false 时发送,设 triggered=true 防重复
  • POWERED=false 时重置 triggered=false,允许下一次触发
  • 绑定信息持久化在 BlockEntity 的 NBT 中

变量替换机制

当前状态:变量替换尚未实际实现。虽然 RfmNoticeVariableType(TEXT/PLAYER)和 RfmNoticeVariableData 已定义,但整个发送链路中没有字符串替换引擎。如果在通知内容中使用 {player_name} 占位符,它将作为字面文本发送到客户端。


数据持久化

PersistentRfmNoticeSavedData

文件:<world>/data/nfa_rfm/rfm_notice.dat

json
{
  "Notices": [
    {
      "Id": "uuid-string",
      "Name": "任务通知",
      "Content": "请前往坐标点A集合",
      "ReceiverType": "runner_alive",
      "ExtraReceivers": ["uuid1", "uuid2"]
    }
  ]
}

PersistentRfmPhoneNoticesSavedData

文件:<world>/data/nfa_rfm/rfm_phone_notices.dat

json
{
  "Notices": [
    {
      "Owner": "player-uuid",
      "Title": "任务通知",
      "Content": "请前往坐标点A集合",
      "TitleColor": 16777215,
      "TitleBold": 1,
      "Timestamp": 1748700000000
    }
  ]
}

注意事项 / 限制

  1. 变量替换未实现:通知内容中的 {player_name} 等变量不会被自动替换,目前按原样发送。
  2. 不支持删除单条手机通知PersistentRfmPhoneNoticesSavedData 仅支持 append()clearAll()
  3. 铃声仅播放3次scheduleRingBurst(targetUuid, 3) 安排3次铃声,间隔由 PhoneServerSoundScheduler 管理。
  4. notice_sender 需红石复位:触发后将 triggered=true,需要红石信号先变为 false 才能再次触发。
  5. EXTRA 类型的额外性EXTRA 作为主接收者类型时不会自动匹配任何玩家,完全依赖 extraReceivers

相关文档