════ 发包写法_开店放入物品 v2(0926 二次定案)════ 【相对 v1 的更正】v1 第15行说"唯一码 B313AD8B19EBDC00 是 0x99 包 token, CB61 样本结尾都是 AD0C5D00,格式对不上" —— **此结论作废**。 证据:本次新给的 3 条样本(物品 1000000106)唯一码一律是 B313AD8B19EBDC00, 与从 物品位置+92 读出的值 100% 吻合。唯一码读法正确,错误包拒收与它无关。 ── 一、七条样本统一解码(统一补齐到 105 字节)── 字段序:[00000000][CB00][6100][02][物品编号4][00000000][唯一码8][价格2][格子2][数量2][74×00] 样本1 物品=1000000010 唯一码=B1D31C80AD0C5D00 价格=111 格子=6 数量=111 样本2 物品=1000000010 唯一码=E383AB80AD0C5D00 价格=111 格子=7 数量=222 样本3 物品=1000000010 唯一码=CFF37A80AD0C5D00 价格=2 格子=8 数量=2 样本4 物品=1000000010 唯一码=E383AB80AD0C5D00 价格=2 格子=7 数量=3 样本5 物品=1000000106 唯一码=B313AD8B19EBDC00 价格=103 格子=4 数量=111 样本6 物品=1000000106 唯一码=B313AD8B19EBDC00 价格=11 格子=4 数量=11 样本7 物品=1000000106 唯一码=B313AD8B19EBDC00 价格=11 格子=4 数量=1 → 价格 / 格子 / 数量 三字段定案 = **2 字节小端**(v1 结论被新样本再确认一次)。 → 样本5/6/7 是同一物品分 3 次放(111 / 11 / 1),间隔 500ms 左右,别连着秒发。 → 尾零填充固定 **74** 字节,总长 **105**。 【错误包 vs 样本5】同一物品、同一唯一码,只剩两处不同: 错误包 [25:43] = 00CA9A3B00000000 00 04000000 67000000 ← 8+1+4+1+4 = 18 字节 样本5 [25:31] = 0067 0004 006F ← 2+2+2 = 6 字节 错误包长度 43 字节,头部声明 97 → 缺 62 字节。 `到字节集(长整数型)` 出 8 字节、`到字节集(整数型)` 出 4 字节 —— 这就是 8/4/4 的来源, 统一改用 `到字节(值 % 256) + 到字节(值 \ 256)` 手工拆 2 字节。 ── 二、修正后的完整子程序(整块复制)── .版本 2 .子程序 发包开店放入物品, 逻辑型, 公开, 开店后把背包物品放进摊位(1A选格+CB放物) .参数 物品格子, 整数型, , 背包格子 0-95 .参数 出售价格, 长整数型, , 单价 1~65535(字段只有 2 字节,超过会被截断,内部自动钳位) .参数 出售数量, 整数型, , 传 0 则按背包实际数量全放 .局部变量 背包基址, 整数型 .局部变量 物品位置, 整数型 .局部变量 物品编号, 字节集 .局部变量 物品数量, 整数型 .局部变量 唯一码, 字节集 .局部变量 封包内容, 字节集 背包基址 = 内存_读整数型 (全局_进程句柄, #背包基址值) 物品位置 = 内存_读整数型 (全局_进程句柄, 背包基址 + 4 × 物品格子 + #背包物品位置值) 物品编号 = 内存_读字节集 (全局_进程句柄, 物品位置 + #背包物品编号值, 4) 物品数量 = 内存_读整数型 (全局_进程句柄, 物品位置 + #背包物品数量值) .如果真 (出售数量 = 0) 出售数量 = 物品数量 .如果真结束 ' ★ 唯一码在 物品位置+92(0x5C),读 8 字节,已用 7 条样本交叉验证通过 唯一码 = 内存_读字节集 (全局_进程句柄, 物品位置 + 92, 8) ' 价格:字段只有 2 字节,钳位到 65535 以内再拆小端 .如果真 (出售价格 < 1) 出售价格 = 100 .如果真结束 .如果真 (出售价格 > 65535) 出售价格 = 65535 .如果真结束 ' 数量:同样钳到 2 字节范围内 .如果真 (出售数量 > 65535) 出售数量 = 65535 .如果真结束 程序_延时 (500) ' ① 00000000CB00610002 = 前缀4 + 功能号2 + 包体长度2(97) + 操作类型1(共 9 字节) ' ② 物品编号 4 字节小端 ' ③ 固定 4 零 ' ④ 唯一码 8 字节(来自 物品位置+92) ' ⑤ 出售价格 2 字节小端:位与(值,255) 取低8位 + 位右移(值,8) 取高8位 ' ⑥ 物品格子 2 字节小端(同上) ' ⑦ 出售数量 2 字节小端(同上) ' ⑧ 取空白字节集(74) 尾部补零 → 9+4+4+8+2+2+2+74 = 105,与头部声明的 97 包体吻合 封包内容 = 机器码到字节集 (“00000000CB00610002”) + 物品编号 + { 0, 0, 0, 0 } + 唯一码 封包内容 = 封包内容 + 到字节 (位与 (出售价格, 255)) + 到字节 (位右移 (出售价格, 8)) 封包内容 = 封包内容 + 到字节 (位与 (物品格子, 255)) + 到字节 (位右移 (物品格子, 8)) 封包内容 = 封包内容 + 到字节 (位与 (出售数量, 255)) + 到字节 (位右移 (出售数量, 8)) 封包内容 = 封包内容 + 取空白字节集 (74) 发包Call (封包内容, 取字节集长度 (封包内容)) 挂机信息.加入文本 (自定义时间 () + “发包开店放入物品:” + 到文本 (转换_字节集到十六进制 (封包内容)) + #换行符 + #换行符) 返回 (真) ── 二补、拆 2 字节的两种写法(都不用 % 和 \)── 写法A 内联位运算: 到字节(位与(值, 255)) + 到字节(位右移(值, 8)) 写法B 独立子程序(主程序里三处变成 拆16位(值)): .子程序 拆16位, 字节集型, 公开, 把 0~65535 的整数拆成 2 字节小端 .参数 数值, 整数型 返回 (到字节 (位与 (数值, 255)) + 到字节 (位右移 (数值, 8))) 对应关系(位运算就是 %256 / \256 的位操作等价物): 值 % 256 ≡ 位与 (值, 255) 取低 8 位 值 \ 256 ≡ 位右移 (值, 8) 取高 8 位 位运算是易语言核心功能(不在任何支持库里),默认可直接用。 ── 三、现成验证包(样本5 原内容 + 74 字节补零,共 105 字节)── 00000000CB006100026ACA9A3B00000000B313AD8B19EBDC00670004006F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 先发这条:内容与抓包样本5 完全一致,只是补齐了长度。 收到 → 证明 6100 是包体长度、105 是真实长度、74 字节补零位置正确 拒收 → 去掉尾部补零试 72 字节的抓包原样版 ── 四、观察要点 ── 1. 别连发。样本 5/6/7 是同一物品间隔发的(数量 111 / 11 / 1),一次只放一种数量。 2. 出售数量不能超过背包实际数量,否则服务端会拒。 3. 价格上限 65535。样本里最高只见到 103,若游戏能摆更高价,说明价格另有字段, 到时候抓一条高价样本重新定字段宽度。 4. 参数 出售价格 保留 长整数型 是为了不改动已有调用处,内部已钳位到 65535; 若你确认价格永远在 1~65535,可把参数直接改成 整数型,去掉两处钳位。 ════════════════════════════════════