{ "_说明": [ "★ 这是 AnantaUnifiedLoader 的【最小依赖副本】,只带两个模块:bowling(保龄球瓶)+ balloon(气球)。", " 其余通道(A 户外 gadget 网格 / B 场景物品网格 / D 地铁座位 / E 室内扇区 / F 显式摆放)", " **服务端已经接管**,注入器再开就是白刷负载,所以这里**一个都不放**。", " (addbtn / settingsfix 也一并去掉:addbtn 已降级为手动兜底,settingsfix 是纯手动 RPC。)", "", "⛑ 改动这里的 enabled 之后要**重启本加载器**才生效(config 只在启动时读一次)。", "⛑⛑ balloon 依赖服务端写的 %LOCALAPPDATA%\\AnantaBalloon\\balloon_push.json(GameRouter.Balloon.cs:1140-1159)。", " ★ 2026-09-29 修复:balloon_fix.js:3417 的 PUSH_PATHS 默认是作者机器的 D:\\Ananta\\gym_tools\\...,", " 原 exe 会在装载时把这一行整个改写成本机路径,**我们漏了这步** ⇒ agent 读不到文件 ⇒ pushN 恒 0。", " 现在由 loader_common.apply_balloon_paths() 在 create_script 前改写(js 本身保持与上游逐字节一致)。" ], "_attachGate说明": [ "★★ 为什么要有这道闸门(2026-09-29,响应用户『以前有注入器得先进入世界再启动』的担心):", " bowling_agent.js:5547 的 Il2Cpp.perform **没有重试** —— ", " var blob = bfClass('LX6.Item.SceneItemBlob');", " if (!blob) { sendlog('ERR: SceneItemBlob not found'); return; }", " 拿不到类就**永久放弃**,直到重新 attach 才会再试。所以『游戏刚起就挂』是有风险的。", " 解决办法:先看服务端日志确认玩家已经进世界,再 attach —— 复现你手动『进世界→再开加载器』这条已验证的路径。", "", " mode=serverLog:轮询 <服务端>/logs/ 里**最新**那份 console-*.log,只扫**本次启动之后新增的字节**,", " 命中 markers 里任意一条即放行。⛑ 只扫新增字节很重要 —— 否则会把上一局的历史内容当成『已进世界』。", " mode=process :不做闸门,Ananta.exe 一出现就 attach(老行为)。排查时用它。", " 超时(timeoutSec)到了还没命中 ⇒ 按 fallback 处理(attachAnyway = 照样挂,只是打一条 warn)。", "", " markers 选的都是『只有 world-ready 之后才会打』的行:", " [WORLD-V7] ready → ★ 最准的 world-ready,比 RESTOCK 早约 26 秒(2026-09-29 实测)", " [RESTOCK] raid=.. 进入格子 → PropRestock 按格子推进", " [GADGET-GRID] push group → 户外 gadget 网格(★ 该循环只在 world-ready 起,见硬规则 234)", " [SCENE-ITEM-GRID] push group → 场景物品网格", " 三条全关(服务端 world.content 全 false)时闸门会走超时兜底,不会把你卡死。" ], "attachGate": { "mode": "serverLog", "serverLogDir": "../../logs", "serverLogGlob": "console-*.log", "markers": [ "[WORLD-V7] ready", "[RESTOCK] raid=", "[GADGET-GRID] push group", "[SCENE-ITEM-GRID] push group" ], "timeoutSec": 900, "fallback": "attachAnyway", "pollSec": 1.0, "_delayAfterMarkerSec说明": [ "★ 2026-09-30:命中 marker 后**再等 N 秒**才 attach —— 命中瞬间正是客户端", " 「进世界黑屏加载」的爆发期,此刻 attach(V8 编译 + Il2Cpp 域遍历 + 热路径挂 hook)", " 会把客户端钉死在黑屏上,直到注入器断开才放行。等爆发期过了再挂则无感。", " 代价:进世界后头 N 秒没注入器(走到保龄球馆/气球区远不止 30 秒,无影响)。" ], "delayAfterMarkerSec": 30 }, "_armedGuard说明": [ "★★ 第二道保险:闸门只保证『时机对』,不保证 hook 真装上。", " 所以 attach 之后持续轮询各模块的 bfStatus.armed:", " armed=true → hook 已装上,正常(tpl=false 是正常的,那只是还没拿到模板,不要重挂)", " armed=false → 说明脚本里 return 掉了(多半是类没找到)⇒ 等 maxWaitSec 后**主动重挂**", " 重挂会先优雅卸载再重新 attach,最多连试 maxAttempts 次,之后退避到 backoffSec 再试,不无限刷。" ], "armedGuard": { "enabled": true, "maxWaitSec": 60, "recheckEverySec": 10, "maxAttempts": 5, "backoffSec": 120 }, "groups": { "_说明": [ "★★ 2026-10-01 新增:**分组开关** —— 每个模块用 `\"group\": \"xxx\"` 声明组别,这里整组一起开关。", " 改布尔值即可(改完**重启加载器**生效,config 只在启动时读一次)。", " 目前只有 `minigame` 一组(bowling 保龄球瓶 + balloon 气球)。", " ⛔ `traffic` 组(vehicle_go.js)已于 2026-10-01 晚**整组删除**:那条思路 hook", " `AetherVehicleViewManager:CheckShouldNotUseGo` 实机 8 探针全 0 命中、类根本没在用;", " 车流改走服务端 `trafficCruiseDrive`(SyncAssignVehicleAITask + Cruise 参数)。", "⛑ 与每个模块的 enabled、命令行 --no 是**叠加**关系(任一处关掉就不挂)。", "⛑⛑ 同一时刻**只能有一个 frida 会话**挂在 Ananta.exe 上(两个 = 游戏必崩)——", " 所以「拆分」是同一个进程内的模块取舍,不是开两个加载器,别去复制第二份目录。" ], "minigame": true }, "modules": [ { "name": "bowling", "group": "minigame", "file": "modules/bowling_agent.js", "enabled": true, "desc": "通道 C 补表类 —— 保龄球球瓶(服务端没有对应 S2C,只能注入端补)", "drive": [ { "rpc": "bfStatus", "everySec": 30.0 } ], "statusRpc": [ "bfStatus" ], "_判据": "bfStatus 里 armed=true 才算 hook 装上;tpl=true 才算拿到球瓶模板。tpl=false 时站进保龄球馆让 AOI 表加载一次。" }, { "name": "balloon", "group": "minigame", "file": "modules/balloon_fix.js", "enabled": true, "desc": "通道 C 补表类 —— 打气球的气球本体(需服务端同机写 side-channel)", "drive": [], "statusRpc": [ "bfStatus" ], "_判据": "bfStatus 里 armed=true;pushN 是服务端推送的条目数(>0 才算读到 side-channel)。" } ], "statusPollSec": 30.0 }