封包协议 (Packet Protocol)

基本信息

属性 值
通道名 BQ_NET_CHAN(BetterQuesting.CHANNEL)
传输实现 SimpleNetworkWrapper,NetworkRegistry.INSTANCE.newSimpleChannel(CHANNEL)(BetterQuesting.java:83)
判别式注册 betterquesting.network.PacketQuesting,discriminator 0,双向(client + server 两侧均注册,Side.CLIENT / Side.SERVER)
处理器注册表 betterquesting.network.PacketTypeRegistry(单例 INSTANCE)
发送工具 betterquesting.network.PacketSender(单例,经 ApiReference.PACKET_SENDER 暴露)
核心封包数 16
初始化时机 preInit 中 PacketTypeRegistry.INSTANCE.init()(BetterQuesting.java:90)

功能

BetterQuesting 用两套并行机制传封包,整合包作者需要分清:

机制一:SimpleNetworkWrapper 判别式通道(仅 1 条逻辑通道)

preInit 里建立通道后只注册了一对处理器(BetterQuesting.java:92-93):

network.registerMessage(PacketQuesting.HandleClient.class, PacketQuesting.class, 0, Side.CLIENT);
network.registerMessage(PacketQuesting.HandleServer.class, PacketQuesting.class, 0, Side.SERVER);

即所有自定义封包都装在 PacketQuesting 这一个消息类里,用 NBT 内容区分,判别式恒为 0。PacketAssembly / PacketQuesting 是这层的数据载体。

机制二:按 ResourceLocation 分发(16 个处理器)

PacketTypeRegistry.init() 调用 16 次 registerHandler()(PacketTypeRegistry.java:38-59),每个处理器把自己注册到一张以 ResourceLocation 为键的表上。表分两张:

表 值类型 用途
serverHandlers Consumer<Tuple2<NBTTagCompound, EntityPlayerMP>> 客户端 → 服务端,附带发包玩家
clientHandlers Consumer<NBTTagCompound> 服务端 → 客户端

registerServerHandler / registerClientHandler 均在重名时抛 IllegalArgumentException("Cannot register dupliate packet handler: " + idName)(PacketTypeRegistry.java:62-80)—— 注意源码里 dupliate 是拼写错误,属原文。

clientHandlers 的两个方法都带 @SideOnly(Side.CLIENT),这是为了让服务端不加载客户端类。

16 个核心封包

封包类 ResourceLocation ID 归属
NetQuestSync betterquesting:quest_sync 任务进度同步
NetQuestEdit betterquesting:quest_edit 任务编辑(OP / 编辑模式)
NetQuestAction betterquesting:quest_action 任务动作(勾选、提交等)
NetChapterSync betterquesting:chapter_sync 任务线(章节)同步
NetChapterEdit betterquesting:chapter_edit 任务线编辑
NetPartySync betterquesting:party_sync 队伍同步
NetPartyAction betterquesting:party_action 队伍动作
NetInviteSync betterquesting:invite_sync 队伍邀请同步
NetLifeSync betterquesting:life_sync 生命值同步
NetNameSync betterquesting:name_sync 名称缓存同步
NetNotices betterquesting:notification 任务通知下发
NetStationEdit betterquesting:station_edit 提交站/观测站的任务绑定
NetImport betterquesting:import 任务数据导入
NetSettingSync betterquesting:setting_sync 世界设置同步
NetCacheSync betterquesting:cache_sync 缓存同步
NetBulkSync betterquesting:main_sync 主体全量同步

以上 16 行与 PacketTypeRegistry.init() 的 16 次 registerHandler() 调用、network/handlers/ 下的 16 个 Net*.java 文件、以及 16 个唯一 ResourceLocation ID 一一对应(三次独立计数互相印证)。

附属包封包(非本分类 modid)

同仓库的 bq_standard 在自己的 registerExpansion() 中额外注册 7 条,通道名 BQ_STANDARD(bq_standard/core/BQ_Standard.java:45):

封包类 ID
NetLootSync bq_standard:loot_database
NetLootClaim bq_standard:loot_claim
NetLootImport bq_standard:loot_import
NetTaskCheckbox bq_standard:task_checkbox
NetScoreSync bq_standard:score_sync
NetRewardChoice bq_standard:choice_reward
NetTaskInteract bq_standard:task_interact

drethic.questbook(questbook)与 lokko12.CB4BQ(cb4bq)在源码中未建立自己的 SimpleNetworkWrapper 通道。

数值

数值名 值
核心通道名 BQ_NET_CHAN
判别式值 0
核心封包处理器数 16
服务端处理器表大小 16
客户端处理器表大小 16
bq_standard 额外封包 7
NetNotices 的 ID 简写 notification(唯一与类名不对应的 ID)

相关条目

  • 扩展示例加载器 - ApiReference.PACKET_REG / PACKET_SENDER 的注册处,附属包通过它们收发封包
  • 提交站 (OSS) - betterquesting:station_edit 封包写入其 questID / taskID
  • 队伍系统 - party_sync / party_action / invite_sync 三条封包的消费方
  • 客户端配置 - betterquesting:setting_sync 同步的是世界级设置