Appearance
消息系统
文档版本:基于 2026-06-01 代码分析
概述
消息系统为逃走中MOD提供玩家间的短信通信功能。支持私信发送、对话线程管理、冷却机制和未读标记。消息通过客户端手机的消息 APP 页面展示,发送和接收均有铃声通知。
核心概念
消息线程
两个玩家之间的所有消息构成一个对话线程(thread)。线程 key 为对方名称(小写),每个玩家的线程列表独立维护。
冷却机制
发送方向冷却:A 发给 B 后进入冷却,冷却期间 A 不能再次发消息给 B。冷却不阻止 B 发给 A,也不阻止 A 发给 C。
架构设计
消息发送时序
mermaid
sequenceDiagram
participant Sender as 发送方
participant Handler as PhoneMessagePayloadHandler
participant MsgData as PersistentPhoneMessagesSavedData
participant CoolData as PersistentPhoneConversationCooldownSavedData
participant Receiver as 接收方
Sender->>Handler: SendPhoneMessagePayload(target, content)
Handler->>Handler: 解析发送者+接收者
Handler->>Handler: 合法性校验(字节权重值<=50)
Handler->>CoolData: getRemainingSeconds(sender, receiver)
alt 冷却中
Handler->>Sender: SyncConversationCooldownPayload
else 冷却已过
Handler->>MsgData: appendMessage(...)
Handler->>CoolData: startCooldown(sender, receiver, cooldownSeconds)
Handler->>Sender: SyncConversationCooldownPayload + SyncSingleMessageThreadPayload
Handler->>Sender: AppendMessageConversationLinePayload
Handler->>Receiver: NotifyIncomingMessagePayload + SyncSingleMessageThreadPayload
Handler->>Receiver: AppendMessageConversationLinePayload
Handler->>Receiver: scheduleRingBurst(uuid, 3)
end关键文件
| 文件 | 说明 |
|---|---|
com/chenxi/chenxi_rfm/server/config/phone/PersistentPhoneMessagesSavedData.java | 消息持久化存储 |
com/chenxi/chenxi_rfm/server/config/phone/PersistentPhoneConversationCooldownSavedData.java | 对话冷却持久化 |
com/chenxi/chenxi_rfm/common/network/handler/phone/PhoneMessagePayloadHandler.java | 消息处理核心 |
com/chenxi/chenxi_rfm/server/config/phone/PersistentPhoneServerConfigSavedData.java | 冷却秒数配置 |
关键流程
发送流程
- 解析发送者:通过当前手机查找 ownerName
- 解析接收者:通过显示名反查 originalName
- 合法性校验:接收者和内容非空,内容字节权重值 ≤ 50(ASCII 字符计 1,中文等非 ASCII 字符计 2,约等于 25 个汉字)
- 接收者注册检查:目标必须在注册表中
- 冷却检查:
getRemainingSeconds(sender, receiver) > 0则拒绝 - 存储消息:
appendMessage(sender, receiver, content, timestamp) - 启动冷却:
startCooldown(sender, receiver, cooldownSeconds) - 推送:发送方收到线程更新+追加行,接收方收到通知+追加行+3 次铃声
未读标记
- 收到新消息时自动标记接收方线程为未读
- 打开对话时调用
clearUnreadThread清除标记 - 服务端
unreadThreadKeysByOwner使用LinkedHashSet保持顺序
线程列表获取
- 遍历所有消息,提取与当前玩家的对话
- 每条线程仅保留最新一条消息作为摘要
- 按时间倒序排列
数据持久化
PersistentPhoneMessagesSavedData
文件:<world>/data/nfa_rfm/phone/messages.dat
Records: List<(senderOwnerName, receiverOwnerName, content, timestampMillis)>
UnreadThreads: Map<ownerName, Set<threadKey>>PersistentPhoneConversationCooldownSavedData
文件:<world>/data/nfa_rfm/phone/conversation_cooldown.dat
Records: List<(senderOwnerLower, targetOwnerLower, cooldownEndMillis)>自动从旧版 nfa_phone_message_cooldown 迁移。
注意事项
- 冷却单向:仅阻止发送方再次向同一接收方发送消息
- 消息长度限制:通过
PhonePayloadSupport.computeMessageLength()计算字节权重值(≤50),ASCII 字符计 1,非 ASCII 计 2 - 过期冷却自动清理:每次查询时自动删除已过期记录
- 铃声通知 3 次:接收方收到消息后播放 3 次铃声(间隔 2 秒)