网络协议 (ModNetwork)

BetterP2P 在客户端/服务端之间通过 SimpleNetworkWrapper (betterp2p) 传输的所有自定义包。 注册入口:ModNetwork.registerNetwork() 与 ModNetwork.start()。 节流:网络请求默认 250 ms 内合并一次(NETWORK_CD = 250L)。

包清单

C2S(客户端 → 服务端)

包类 触发动作 字段 服务端处理
C2SCloseGui GUI 关闭 无 playerState.remove(uuid)
C2SUpdateMemoryInfo GUI 中模式/选中项/频率/GUI 缩放变化 info: MemoryInfo 写回持有卡片的 NBT (ItemAdvancedMemoryCard.writeInfo)
C2SLinkP2P OUTPUT/INPUT/COPY 模式下绑定 input: P2PLocation, output: P2PLocation gridCache.linkP2P(input, output),成功则触发 requestP2PUpdate
C2SUnlinkP2P UNBIND 模式 p2p: P2PLocation, type: Int gridCache.unlinkP2P(p2p),触发更新
C2STypeChange GUI 中改 P2P 类型 newType: Int, p2p: P2PLocation gridCache.changeAllP2Ps(p2p, type),成功后 requestP2PList(type.index)
C2SRenameP2P GUI 中重命名 p2p: P2PLocation, name: String 跨维度查找 TE,验证 IGridHost,设置 part.customName,标注该条目(以及其所有输出)为脏
C2SRefreshP2PList 切换类型过滤时 type: Int requestP2PList(player, type) 推送全量 S2COpenGui

S2C(服务端 → 客户端)

包类 触发动作 字段 客户端处理
S2COpenGui 右键方块或 requestP2PList infos: List<P2PInfo>, memoryInfo: MemoryInfo 若 GUI 已开则 refreshInfo,否则 displayGuiScreen(GuiAdvancedMemoryCard(msg))
S2CUpdateP2P 增量 P2P 状态变化 infos: List<P2PInfo>, clear: Boolean clear=true → refreshInfo,false → updateInfo

数据结构

类 用途 关键字段
P2PInfo 完整 P2P 描述(包传输用) frequency, posX/Y/Z, dim, facing, name, output, hasChannel, channels, type
P2PLocation 简化位置(双向校验) x, y, z, facing, dim
MemoryInfo 高级存储卡状态序列化 selectedEntry, frequency, mode, guiScale, type

关键状态

// ModNetwork.kt
val playerState: MutableMap<UUID, PlayerRequest> = Collections.synchronizedMap(WeakHashMap())

每个打开过 GUI 的玩家持有一个 PlayerRequest,包含 gridCache: GridServerCache(服务端缓存该玩家的 P2P 列表)。关闭 GUI 即 removeConnection。

节流逻辑

  • requestP2PUpdate(player):若 250 ms 内已有挂起请求,则合并;否则调度一次延迟 250 ms 的全量刷新。
  • 增量更新通过 GridServerCache.markDirty 累积到 dirtyP2P,下一次 getP2PUpdates() 取出后清空。

安全检查

  • C2SRenameP2P 跨维度访问 TE,必须确认 IGridHost 且对应方向有 GridNode。
  • 所有写操作包都先在 playerState[uuid] ?: return null 检查玩家有活跃状态。

相关条目