Skip to content

网络包参考

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

概述

逃走中MOD使用 NeoForge 的 CustomPacketPayload + PayloadRegistrar 机制(NeoForge 21.x 标准网络 API)实现客户端与服务端之间的数据同步。总计注册 53 个 Payload 类型(S→C 方向 27 个,C→S 方向 26 个),分为 Phone(27个)、RFM(25个)、Permission(1个)三大模块。

网络协议版本号硬编码为 "1",客户端与服务端版本不匹配时网络包将被拒绝。


核心概念

架构分层

ModNetwork.registerPayloads()
    |
    +-- PayloadRegistrar (version "1")
    |     +-- playToServer(...)  : 25 条 C->S 注册
    |     +-- playToClient(...)  : 31 条 S->C 注册
    |
    +-- PhonePayloadHandler(分派层,27个payload → 5个子handler)
    |     +-- PhoneRegistrationPayloadHandler    手机注册
    |     +-- PhoneCallPayloadHandler            通话管理
    |     +-- PhoneContactsPayloadHandler        通讯录管理
    |     +-- PhoneMessagePayloadHandler         短信管理
    |     +-- PhoneConfigPayloadHandler          配置管理
    |
    +-- RfmPayloadHandler(单层,28个payload)
    |
    +-- PermissionPayloadHandler(单层,1个payload)

三种交互模式

模式描述典型命名
请求-响应客户端 Request*Payload → 服务端 Sync*PayloadRequestRfmNoticesPayload → SyncRfmNoticesPayload
服务端推送服务端主动发送 Notify*Append*Play*NotifyIncomingMessagePayloadPlayRfmTitleWriterPayload
命令-执行客户端发送 Update*Payload(含 action 字段),服务端根据 action 执行UpdateRfmControlPayload(action="start")

数据方向标注

标注含义
C→S客户端发送到服务端(playToServer)
S→C服务端发送到客户端(playToClient)

架构设计

网络包处理流程

mermaid
sequenceDiagram
    participant Client as 客户端
    participant PReg as PayloadRegistrar
    participant Handler as PayloadHandler
    participant Server as 服务端

    rect rgb(40, 40, 60)
        Note over Client,Server: C→S 请求-响应模式
        Client->>PReg: playToServer(RequestPayload)
        PReg->>Handler: handle(RequestPayload, context)
        Handler->>Server: 委托给 Manager
        Server->>PReg: playToClient(SyncPayload, player)
        PReg->>Client: 发送到客户端
    end

    rect rgb(40, 60, 40)
        Note over Client,Server: S→C 推送模式
        Server->>PReg: playToClient(NotifyPayload, player)
        PReg->>Client: 发送到客户端
        Client->>Handler: handle(NotifyPayload, context)
        Handler->>Client: 写入 ClientState
    end

关键文件

文件说明
com/chenxi/chenxi_rfm/common/network/ModNetwork.java网络包注册入口
com/chenxi/chenxi_rfm/common/network/handler/PhonePayloadHandler.javaPhone 分派层 Handler
com/chenxi/chenxi_rfm/common/network/handler/RfmPayloadHandler.javaRFM 单体 Handler
com/chenxi/chenxi_rfm/common/network/handler/permission/PermissionPayloadHandler.java权限同步 Handler
com/chenxi/chenxi_rfm/common/network/handler/phone/PhoneRegistrationPayloadHandler.java手机注册子Handler
com/chenxi/chenxi_rfm/common/network/handler/phone/PhoneCallPayloadHandler.java通话管理子Handler
com/chenxi/chenxi_rfm/common/network/handler/phone/PhoneContactsPayloadHandler.java通讯录子Handler
com/chenxi/chenxi_rfm/common/network/handler/phone/PhoneMessagePayloadHandler.java短信子Handler
com/chenxi/chenxi_rfm/common/network/handler/phone/PhoneConfigPayloadHandler.java配置管理子Handler
com/chenxi/chenxi_rfm/common/network/handler/phone/PhonePayloadSupport.javaPhone 工具类(非网络Handler)

网络包清单

手机 — 注册(3个)

Payload 类方向字段用途
RegisterPhoneAppPayloadC→S(无字段)客户端请求注册当前手机
RequestPhoneRegistrationStatePayloadC→S(无字段)客户端请求查询手机注册状态
SyncPhoneRegistrationStatePayloadS→Cboolean registered, String ownerName服务端同步手机注册状态

手机 — 通话(5个)

Payload 类方向字段用途
RequestStartPhoneCallPayloadC→SString phoneNumber, String displayName客户端请求发起通话
RequestHandlePhoneCallPayloadC→SString callId, String action客户端处理通话(接听/挂断)
SyncPhoneCallStatePayloadS→CString callId, state, peerUuid, peerName, peerPhone, message, long stateStartMillis, stateEndMillis, serverNowMillis服务端同步通话状态
RequestCallHistoryPayloadC→S(无字段)客户端请求通话记录
SyncCallHistoryPayloadS→CList<PhoneCallHistoryData> records服务端同步通话记录

手机 — 通讯录(4个)

Payload 类方向字段用途
RequestContactsPayloadC→S(无字段)客户端请求联系人列表
SyncContactsPayloadS→CList<PhoneContactData> contacts服务端同步联系人列表
RequestContactDetailPayloadC→SString targetName客户端请求联系人详情
SyncContactDetailPayloadS→CString ownerUuid, ownerName, phoneNumber服务端同步联系人详情

手机 — 消息(8个)

Payload 类方向字段用途
RequestMessageThreadsPayloadC→S(无字段)客户端请求消息线程列表
SyncMessageThreadsPayloadS→CList<PhoneMessageThreadData> threads服务端同步消息线程列表
RequestMessageConversationPayloadC→SString targetName客户端请求对话内容
SyncMessageConversationPayloadS→CString targetName, List<PhoneMessageLineData> messages服务端同步完整对话
SendPhoneMessagePayloadC→SString targetName, String content客户端发送短信
NotifyIncomingMessagePayloadS→CString senderName, String threadKey服务端通知新消息
SyncSingleMessageThreadPayloadS→CPhoneMessageThreadData thread服务端同步单个消息线程
AppendMessageConversationLinePayloadS→CString targetName, PhoneMessageLineData line服务端追加消息行

手机 — 冷却/配置(7个)

Payload 类方向字段用途
UpdateMessageCooldownPayloadC→Sint cooldownSecondsOP 更新消息冷却秒数
SyncMessageCooldownPayloadS→Cint cooldownSeconds服务端同步消息冷却秒数
UpdateCallWaitSecondsPayloadC→Sint callWaitSecondsOP 更新呼叫等待秒数
SyncCallWaitSecondsPayloadS→Cint callWaitSeconds服务端同步呼叫等待秒数
UpdateMaxCallSecondsPayloadC→Sint maxCallSecondsOP 更新最大通话秒数
SyncMaxCallSecondsPayloadS→Cint maxCallSeconds服务端同步最大通话秒数
SyncConversationCooldownPayloadS→CString targetName, int remainingSeconds服务端同步对话冷却剩余秒数

RFM — 游戏控制(9个)

Payload 类方向字段用途
RequestOpenRfmManagerPanelPayloadC→Sint initialTab客户端请求打开管理面板
OpenRfmManagerPanelPayloadS→Cint initialTab, hasBlockContext, String boundNoticeId, blockDimension, int blockX, blockY, blockZ服务端响应打开管理面板
RequestRfmGameStatePayloadC→S(无字段)客户端请求游戏状态
SyncRfmGameStatePayloadS→CString state, phase, int totalSeconds, elapsedSeconds, long syncMillis, serverNowMillis, int escapersRemaining服务端同步游戏状态
UpdateRfmControlPayloadC→SString action, int valueOP 发送控制指令(start/pause/resume/stop/setTime/setRate/clearCoin)
RequestRfmManagerPlayersPayloadC→S(无字段)客户端请求管理器玩家列表
SyncRfmManagerPlayersPayloadS→CList<RfmManagerPlayerData> players服务端同步管理器玩家列表
UpdateRfmPlayerManagePayloadC→SString action, targetUuid, valueOP 管理玩家(nickname/role/eliminate/abstain/traitor/addCoin)
SyncRfmHudPayloadS→CString mode, int originX, originY, originZ, List<RfmHudPlayerData> players, List<String> aliveParticipantUuids, boolean resurrectStageActive, List<String> pendingResurrectRunnerUuids服务端同步游戏HUD数据

RFM — 通知(6个)

Payload 类方向字段用途
RequestRfmNoticesPayloadC→S(无字段)客户端请求通知列表
SyncRfmNoticesPayloadS→CList<RfmNoticeData> notices服务端同步通知列表
UpdateRfmNoticePayloadC→SString action, RfmNoticeData noticeOP 管理通知(create/save/delete/send)
BindRfmNoticeToBlockPayloadC→SString noticeId, dimension, int blockX, blockY, blockZOP 绑定通知到 notice_sender 方块
RequestRfmNoticeTargetsPayloadC→S(无字段)客户端请求通知目标列表
SyncRfmNoticeTargetsPayloadS→CList<RfmNoticeTargetData> targets服务端同步通知目标列表

RFM — 坐标(3个)

Payload 类方向字段用途
RequestRfmCoordinatesPayloadC→S(无字段)客户端请求坐标点列表
SyncRfmCoordinatesPayloadS→CList<RfmCoordinateData> coordinates服务端同步坐标点列表
UpdateRfmCoordinatePayloadC→SString action, RfmCoordinateData coordinate, boolean useCurrentPositionOP 管理坐标点(add/delete/teleport)

RFM — 触发器(3个)

Payload 类方向字段用途
RequestRfmTriggersPayloadC→S(无字段)客户端请求触发器列表
SyncRfmTriggersPayloadS→CList<RfmTriggerData> triggers服务端同步触发器列表
UpdateRfmTriggerPayloadC→SString action, RfmTriggerData triggerOP 管理触发器(save/trigger/reset/teleport/clear)

RFM — 手机通知(2个)

Payload 类方向字段用途
SyncPhoneRfmNoticesPayloadS→CList<RfmPhoneNoticeData> notices服务端同步手机端通知列表
AppendPhoneRfmNoticePayloadS→CRfmPhoneNoticeData notice服务端追加一条手机通知

RFM — 标题动画(2个)

Payload 类方向字段用途
PlayRfmTitleWriterPayloadS→CString fileId, int startGroup, List<RfmTitleWriterGroupData> groups服务端播放字幕动画
StopRfmTitleWriterPayloadS→C(无字段)服务端停止字幕动画

权限(1个)

Payload 类方向字段用途
SyncPermissionLevelPayloadS→CNfaPermissionLevel level(枚举序列化为 String id)服务端同步玩家的权限等级

内嵌数据结构

以下 13 个类为内嵌数据结构(record),不实现 CustomPacketPayload,仅作为列表元素嵌入在 Sync 类中:

类名所属模块包含字段
PhoneCallHistoryDataphone.callpeerUuid, peerName, peerPhone, directionText, statusText, missed, timeMillis
PhoneContactDataphone.contactsownerUuid, ownerName
PhoneMessageThreadDataphone.messagesthreadKey, ownerUuid, ownerName, lastMessage, lastMessageTimeMillis, unread
PhoneMessageLineDataphone.messagessenderOwnerName, receiverOwnerName, content, timestampMillis
RfmManagerPlayerDatarfmuuid, displayName, nickname, role, state, permissionLevel
RfmHudPlayerDatarfmuuid, displayName, role, runnerEliminated, runnerAbstained, traitor
RfmNoticeDatarfmnoticeId, name, content, receiverType, extraReceivers
RfmNoticeVariableDatarfmkey, type, value(未被网络直接使用)
RfmNoticeTargetDatarfmuuid, displayName, originalName, runnerEliminated, runnerAbstained, online
RfmCoordinateDatarfmcoordinateId, name, dimension, x, y, z
RfmTriggerDatarfmdimension, name, mode, blockX, blockY, blockZ, targetRemainingSeconds, powered
RfmPhoneNoticeDatarfmtitle, content, titleColorRgb, titleBold
RfmTitleWriterGroupDatarfmindex, next, preBlinkTicks, charIntervalTicks, cursorBlinkTicks, stayTicks, blankAfterTicks, line1Text, line2Text, line1Style, line2Style

关键流程

Payload 序列化方式

所有 Payload 均为 Java record,使用 StreamCodec 进行序列化:

编码方式适用场景
StreamCodec.composite()有字段的 Payload,组合多个 ByteBufCodecs.*
StreamCodec.of()手动读写 ByteBuf,用于自定义编解码
StreamCodec.unit()无字段的空 Payload(纯请求类)

注意事项 / 限制

  1. 协议版本硬编码ModNetwork 使用 version "1",升级网络协议时必须手动增加版本号,否则新旧客户端无法通信。
  2. Payload 不可变性:所有 Payload 使用 Java record 定义,是不可变的。修改数据必须构造新实例。
  3. 内嵌数据类不独立传输:13 个 Data 类(如 PhoneContactDataRfmTriggerData)只能作为列表元素嵌入在 Sync 类中传输,不能独立作为网络包发送。
  4. 代码风格不一致:部分类使用了 ByteBufCodecs.list() 的流式风格(如 SyncRfmNoticesPayload),部分使用了手动列表读写循环(如 SyncRfmHudPayload)。后者可能是为了更好的 null 安全性。
  5. PhonePayloadHandler 非严格分派SyncMessageCooldownPayload 等三个 sync 包在 PhonePayloadHandler 中被路由到了 PhoneRegistrationPayloadHandler 而非 PhoneConfigPayloadHandler,这是实现层面的设计选择。
  6. 权限检查在 Handler 层RfmPayloadHandlerPhonePayloadHandler 中的服务端 handler 方法在执行业务逻辑前会调用 NfaPermissionService 进行权限检查。

相关文档

最后更新: