网络封包

基本信息

属性 值
注册类 com.github.lunatrius.schematica.network.PacketHandler
封包总数 6(discriminator 0–5)
通道名 Reference.MODID.toLowerCase() = schematica(network/PacketHandler.java:18)
注册时机 CommonProxy.init → PacketHandler.init()(proxy/CommonProxy.java:54)
网络 API Forge SimpleNetworkWrapper(1.7.10 FML)

通道名由 modid 转小写得到,与 modid 本身的大小写不一致——modid 是 Schematica(大写 S,见 reference/Reference.java:8),通道是 schematica。

数值

ID 类 方向 载荷
0 MessageCapabilities Side.CLIENT boolean isPrinterEnabled / isSaveEnabled / isLoadEnabled
1 MessageDownloadBegin Side.CLIENT ItemStack icon / int width / height / length
2 MessageDownloadBeginAck Side.SERVER 空(无字段)
3 MessageDownloadChunk Side.CLIENT int baseX/baseY/baseZ、short[][][] blocks、byte[][][] metadata、List<TileEntity> tileEntities、List<Entity> entities
4 MessageDownloadChunkAck Side.SERVER 三个 int 坐标
5 MessageDownloadEnd Side.CLIENT String name

字段定义来源:network/message/MessageCapabilities.java:15-17、MessageDownloadBegin.java:17-20、MessageDownloadChunk.java:28-35、MessageDownloadChunkAck.java:21、MessageDownloadEnd.java:21。

MessageDownloadChunk 静态持有方块注册表引用 BLOCK_REGISTRY = GameData.getBlockRegistry()(network/message/MessageDownloadChunk.java:26),用于把网络传来的方块 ID 还原成 Block 对象。

功能

分块传输协议

下载走五状态握手协议,状态机定义在 network/transfer/SchematicTransfer.State(network/transfer/SchematicTransfer.java:8-28):

BEGIN_WAIT → BEGIN → CHUNK_WAIT → CHUNK → … → END_WAIT → END

标记 waiting = true 的是 BEGIN_WAIT、CHUNK_WAIT、END_WAIT(:10、:12、:14),即服务端等客户端 Ack 的状态。

DownloadHandler.onServerTick(handler/DownloadHandler.java:30-37)在每个服务端 tick 的 END 阶段调 processQueue()(:36)。processQueue(:39-76)每次只处理一名玩家(取 transferMap 的首个 key,:44-47),把该玩家从 map 取出再放回(:47、:75),实现玩家间的轮转。

当前状态 动作 来源
非 waiting 且超时 重发当前区块,超出重试上限则丢弃 :53-65
BEGIN_WAIT 发 MessageDownloadBegin :66-67、:78-83
CHUNK_WAIT 发 MessageDownloadChunk :68-69、:85-95
END_WAIT 发 MessageDownloadEnd 并结束该传输(先 return,:72) :70-72、:97-100

setState 每次转移都会把 timeout 与 retries 清零(network/transfer/SchematicTransfer.java:78-82)。

区块推进

SchematicTransfer.confirmChunk(network/transfer/SchematicTransfer.java:54-76)在收到 Ack 且坐标匹配时把 base 坐标推进一格(:57),并在 X/Y/Z 越界时逐层回绕:X 满则 baseX=0 且 baseY += HEIGHT(:59-61);Y 满则 baseY=0 且 baseZ += LENGTH(:63-65);Z 满则转 END_WAIT 并返回 false(:67-69)。

能力同步

MessageCapabilities 把服务端的 printerEnabled / saveEnabled / loadEnabled 三个配置项下发给客户端,字段与三个 ConfigurationHandler 配置项一一对应(network/message/MessageCapabilities.java:15-17 vs handler/ConfigurationHandler.java:83-85)。

⚠️ playerQuotaKilobytes 与 serversideSchematicsEnabled 不在该封包中——它们只在服务端生效,不同步到客户端。

交互

传输超时与重试常量定义在 reference/Constants.java:32-36:

常量 值 含义
Constants.Network.TIMEOUT 15 * 20 = 300 tick(15 秒) 单个状态的等待上限
Constants.Network.RETRIES 5 重试次数上限,超过则打 "{}'s download was dropped!" 并放弃(handler/DownloadHandler.java:54-58)

单个传输区块尺寸(reference/Constants.java:38-43):

常量 值
Constants.SchematicChunk.WIDTH 16
Constants.SchematicChunk.HEIGHT 16
Constants.SchematicChunk.LENGTH 16

⚠️ 区块尺寸是硬编码的 16³,与 SchematicTransfer.confirmChunk 的推进逻辑(network/transfer/SchematicTransfer.java:57-65)共用同一组常量,因此改尺寸会同时影响发包切片与 Ack 推进。

相关条目

  • 指令 - /schematicaDownload 是本协议的唯一起始入口
  • API 与兼容 - ISchematic 是传输载荷的数据模型