网络协议 (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检查玩家有活跃状态。