Embedded module mt_pickup wraps GameWindow.PickUpItem (Z / `): with batch pickup on it sends /mt_pickup 1 MASK (0.5 s gap, one in flight, presses swallowed while waiting); after 3 s without a reply it notes once in chat and falls back to the original single pickup. Settings window (on/off and 8 categories, persisted in mt_pickup.cfg) behind a "拾取" button under the switchbot entry by the minimap. Live tested against 203 (channel-5 test core, port 13040) with the macOS native client. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3.5 KiB
3.5 KiB
AVA2 批量拾取适配进度(v1)
2026-10-15。修改了 metin2-client 和 metin2-server,AVA2 代码只作参考(do_pickup_all、ENABLE_AUTOMATIC_PICK_UP_SYSTEM)。服务端规则和协议见 metin2-server/docs/FEATURE-PICKUP.md。
与 AVA2 的差异
| 项目 | AVA2 | 本实现 |
|---|---|---|
| 触发 | 新包头 HEADER_CG_ITEMS_PICKUP,以及付费状态 70002(AFFECT_AUTO_PICK_UP)下的自动拾取 |
聊天命令 /mt_pickup,不新增包头;只在按拾取键时触发,不做自动拾取和付费状态 |
| 范围 | 自己的物品 | 相同:只拾取自己的或无主的物品;队伍分配的物品不批量拾取 |
| 拾取过程 | 自己实现 | 每件物品都调用原 PickupItem,距离、堆叠、背包空间、GET 日志、任务触发都不变 |
| 分类 | CheckItemCanGet 模式掩码 | 8 个分类位:金币、武器、防具/首饰、技能书、灵石、材料、时装、其他 |
客户端
- 模块
mt_pickup(src/platform/ScriptLib/PickupScript.inc),在PythonBoot.cpp中安装。替换了GameWindow.PickUpItem(Z 键和 ` 键)。 - 开启时,按拾取键会发送
/mt_pickup 1 掩码。等待回复时,以及两次发送间隔不足 0.5 秒时,按键会被吞掉(防止按住 Z 连发)。关闭时走原来的单个拾取。 - 3 秒没有回复:在聊天框提示一次“服务器尚未启用批量拾取”,之后改用单个拾取;再收到回复会自动恢复。
- 设置窗口:入口是小地图旁“洗练”下方的“拾取”按钮。窗口内可开关批量拾取、选择 8 个分类(
【】表示已选,至少保留一个),并显示上次结果(附近 N 件、拾取 N 件、失败 N 件)。设置保存在客户端目录的mt_pickup.cfg,格式为“开关 掩码”。 - 单件物品的提示仍由服务端发送;失败提示(例如背包已满)只发一次。
证据
tests/wiki/test_pickup.py(CTest:port.pickup)共 7 项通过,覆盖:- 发送节流和等待回复;
- done/error 解析,畸形行和其他前缀;
- 超时后改用单个拾取,迟到的回复会恢复批量拾取;
- 关闭开关、分类掩码、至少保留一个分类;
- 配置文件读写和损坏的配置;
- GameWindow 钩子:入口位置、拾取键、命令拦截、窗口开关;
- 和服务端的分类位、错误码、0.5 秒间隔一致。
tests/wiki/test_switchbot.py仍然通过。- 2026-10-15 联机测试(203 测试核心 channel5/first,端口 13040,使用隔离编译的 game;macOS 原生客户端,账号 admin)。先用
/item生成并逐件丢下武器 19、铠甲 11209、材料 30003、灵石 28030、技能书 50300 和 1000 金币:- 掩码 2(武器):
done 1 1 0,只拾回武器。 - 掩码 48(灵石+材料):
done 2 2 0。 - 掩码 255:
done 3 3 0,拾回铠甲、技能书和金币(金币数恢复)。 - 地上已没有物品:
done 0 0 0;紧接着再发一次:error rate。 - log.log 有 5 行 GET,每件物品一行,和 DROP 一一对应。原路径拾取金币不写 GET 日志。
- 测试核心 syserr 没有新错误。丢金币时出现的 LOCALE_ERROR 来自原有的丢金币提示。
- 掩码 2(武器):
未完成
- Android 真机测试和触屏拾取按钮(
touch_controller.h的按钮发送 DIK 键码,需要再加布局)。 - 背包已满时的联机测试(服务端桩测试已覆盖)。
- 服务端还没有部署到 203 正式环境。
- 自动狩猎自带的客户端拾取(
PICKUP_TEXTS)没有改动。