Clientbound 一侧
序号锚点 · 打开 1 tick 窗口 · 返回总条目
Clientbound 一侧在复合包里承担两件事:给出 Sequence 的真实取值,并打开那个 1 tick 的发送窗口。它不是一个新的包类型——官方映射里没有对应的类,这一侧的内容全部来自 S32(ClientboundPingPacket)与 S08(ClientboundPlayerPositionPacket)。
本页字段表按握手说 / 融合说整理。C08 复合载荷说不承认存在独立的 Clientbound 一侧,认为这一侧只是序号往返,与拉弓包本身无关。
| Packet ID | State | Bound To | Field Name | Field Type | Notes |
|---|---|---|---|---|---|
| 独立 ID 无 由组成包 各自的 ID 承载 |
Play | Client | X | Double | 服务端记录的玩家绝对坐标;来源 C04/C03 族。 |
| Y | Double | ||||
| Z | Double | ||||
| Yaw | Float | 水平视角,单位为度。 | |||
| Pitch | Float | 垂直视角,单位为度。 | |||
| On Ground | Boolean | 玩家是否在地面,直接取自 C03 的 onGround 位。 | |||
| Charge Ticks | VarInt | 服务端侧该玩家 getTicksUsingItem() 的值,不是包字段。下发时恒 ≥ 20。 | |||
| Sequence | VarInt | 来自 S32 的 id;客户端必须用 C0F 原样带回。 |
为什么这一侧没有“半个”
“半个”指一个包只带一部分参数,另一部分沿用上一个包、由接收方自己补上。这是发送方省略重复信息的做法:客户端的朝向、手持物在这一刻通常和上一个包一样,没必要重发。服务端下发的位置校正和序号则每次都是新值,没有可沿用的东西,所以这一侧总是完整下发。
为什么 Sequence 只能来自 S32
这个字段要满足两个条件:客户端能读到它,且服务端手里有一份同样的值可以比对。
自增值不行——客户端和服务端各数各的,第一次重连就错位。Uuid 或时间戳不行——它们没有“服务端刚发过一个、客户端刚回过一个”的配对语义。
S32 / C0F 这一对恰好就是为这个语义存在的:服务端发一个 int,客户端原样送回,服务端立刻知道“我发出去的那个号回来了”。这就是拉弓包 Sequence 的唯一合理来源。
八个字段的规模对照
同类交互包通常只有一到两个字段(C09 只有一个 short 槽位,C0F 只有一个 int)。这一侧有八个,是因为它同时承担了位置(3)、朝向(2)、状态(1)、计时(1)与配对号(1)五类语义。
字段多本身不是证据,但它是“这一侧由多个来源拼成”的直接后果——见构成。
这一侧不是什么
- 不是新注册的包类型。官方映射里没有
ClientboundPullBowPacket这个类;ClientboundPullBowPacket是社区俗称。 - 没有独立 ID。线上看到的是组成它的几个原版包各自带着自己的 ID 连续发出;play 状态下的包 ID 逐版本重排。
- 不是能单独构造的包。没有独立类型就没有独立的序列化入口,它的内容来自组成包。
与这一侧对应的另一半见 Serverbound 一侧;两边的先后顺序见握手序列。