拓冰建站拓冰建站
首页 / 资讯中心 / 正文

碧蓝航线脚本ALAS如何把明日方舟MAA塞进同一个模拟器?

碧蓝航线脚本ALAS如何把明日方舟MAA塞进同一个模拟器【免费下载链接】AzurLaneAutoScriptAzur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研全自动大世界项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScriptAzurLaneAutoScript以下简称ALAS作为一款开源碧蓝航线脚本其最大的意外之喜藏在submodule/AlasMaaBridge里它让同一个模拟器、同一个 ADB 通道同时跑起明日方舟的 MAA 自动化。这篇文章不打算堆概念而是从一个双坑玩家会遇到的真实困境出发一步步拆解这套跨游戏桥接方案里的关键取舍、三个硬骨头和五条排障经验读完你既能明白为什么这么设计也知道该从哪里下手贡献代码。两个自动化程序抢一个屏幕怎么破如果你同时玩碧蓝航线和明日方舟大概率经历过这种局面晚上十点碧蓝的委托马上到期明日方舟的理智还满着两个游戏都想在模拟器里挂机可模拟器只有一个。表面上是排队用电脑的问题本质上是屏幕这个唯一资源被两个程序争抢。ALAS 面对这个问题时给出了一条很多人想不到的路径不去做多开分配器而是让明日方舟的自动化直接寄生在 ALAS 进程里。做法是把 MAA 作为一个 submodule 挂进项目在submodule/AlasMaaBridge/下搭起一座桥——maa.py负责入口module/asst/asst.py负责与 MaaCore.dll 对话module/handler/handler.py负责把 MAA 的回调翻译成 ALAS 能听懂的任务信号。结论先行与其让两个程序互相竞争不如让一个程序包含另一个。这既是架构选择也是用户体验选择——用户只需要维护一份 ADB 配置、一套日志体系。为什么要借壳而不是另起炉灶面对集成 MAA这个需求常规思路是移植把 MAA 的核心逻辑抄进 ALAS复用它的截图、点击、OCR 能力。但 ALAS 的开发者选了一条更省力的路——继承。看submodule/AlasMaaBridge/maa.py里的这段代码思路一目了然class ArknightsAutoScript(AzurLaneAutoScript): cached_property def device(self): return FakeDevice() cached_property def config(self): config ArknightsConfig(config_nameself.config_name) return config关键在FakeDeviceALAS 自身的device要管截图、点击、ADB但 MAA 有自己的一套设备交互minitouch / maatouch / adb所以这里用一个吞掉所有方法调用的替身对象把 ALAS 的设备层架空同时完整继承了任务调度、异常体系、日志与通知系统。这样做的收益很明显ALAS 积累多年的调度器Scheduler_Command驱动的任务队列、错误重试、一键推送全部免费继承MAA 只需要专注做它擅长的事。这是组合优于重写的典型示范——集成方不必理解被集成方的全部内部实现只要定义好边界。先回答最难的问题MaaCore.dll 怎么跨语言调用桥接方案的第一道坎是 ALAS 是 Python而 MAA 核心是 C 编译的MaaCore.dll。跨语言没有魔法只能用ctypes手工描述 C 接口。但真正棘手的不是声明函数签名而是DLL 依赖冲突。看submodule/AlasMaaBridge/module/asst/asst.py的加载逻辑platform_values { windows: {libpath: MaaCore.dll, environ_var: PATH}, darwin: {libpath: libMaaCore.dylib, environ_var: DYLD_LIBRARY_PATH}, linux: {libpath: libMaaCore.so, environ_var: LD_LIBRARY_PATH}, } Asst.__lib lib_import_func(str(Asst.__libpath))而maa.py在 import 阶段就先做了件反直觉的事在加载 PIL 之前优先用ctypes.WinDLL手动加载系统目录里的vcruntime140_1.dll、msvcp140.dll。原因是 MAA 依赖的 VC 运行库版本可能与 ALAS 已加载的镜像冲突提前锁定系统版本可以避免同名 DLL 版本混用导致的诡异崩溃。配合incremental_path把 YoStarEN、YoStarJP 等外服资源目录追加进AsstLoadResource一个load()就完成了核心库 增量资源的完整装载。这是典型的环境工程问题功能没写错是运行时环境在捣乱。解决的唯一办法是把依赖关系彻底摸清并保证加载顺序可控。任务跑飞了怎么办回调驱动的心跳机制DLL 加载成功只是开始。MAA 是异步的你append_task之后结果会通过回调源源不断送回来。问题来了——怎么判断任务真的结束了而不是卡死了ALAS 的做法是给回调装一个看门狗。看submodule/AlasMaaBridge/module/handler/handler.py里的maa_startself.callback_timer Timer(600) ... self.asst.start() while 1: if self.callback_timer.reached(): logger.critical(MAA no respond, probably stuck) raise RequestHumanTakeover if self.signal is not None: if self.signal self.Message.TaskChainError: raise RequestHumanTakeover self.maa_stop() return time.sleep(0.5)设计逻辑很清晰每个回调进来都会reset()这个 600 秒计时器主循环只要发现计时器超时就判定MAA 无响应抛出RequestHumanTakeover交还人工接管。同时回调里维护一个callback_listtask_end_callback负责在AllTasksCompleted等消息到达时置位signal主循环据此正常收尾。这套回调注册表 心跳计时器的模式比简单join线程高明在可组合比如fight_stop_count_callback会在每次StageDrops消息里递减MaaFight_Times计数实现刷够次数就停而它只是临时挂进callback_list任务结束自动清空互不污染。三步看懂配置生成管线从 YAML 到 Python 类MAA 模块继承了 ALAS 最引以为傲的配置体系配置不是手写死在代码里的而是从声明式文件生成出来的。整条管线在submodule/AlasMaaBridge/module/config/下清晰可见argument/argument.yaml声明每个参数的默认值、类型、可选值运行config_updater.py把它编译成argument/args.json同一份 JSON 再分叉产出config_generated.pyPython 属性和i18n/zh-CN.json等四份翻译以argument.yaml为例一个参数的声明长这样MaaEmulator: Serial: value: 127.0.0.1:5555 valuetype: str PackageName: value: Official option: [ Official, Bilibili, YoStarEN, YoStarJP, YoStarKR, txwy ] TouchMethod: value: minitouch option: [ minitouch, maatouch, adb ]生成后的config_generated.py里就对应出现MaaEmulator_Serial 127.0.0.1:5555这样的类属性。好处是显而易见的改参数只需要改 YAML不用在 Python 和前端之间手工同步GUI、校验、默认值、翻译四者永远同源。这也是为什么config_generated.py文件头特意写着 Dont modify it manually。本地化为什么需要键名回退兜底ALAS 支持 zh-CN、zh-TW、en-US、ja-JP 四种语言MAA 桥接模块把翻译文件独立放在自己的module/config/i18n/下。多语言本身不稀奇稀奇的是它的合并策略。看config_updater.py里的generate_i18n翻译生成不是从零开始而是旧翻译 新参数的深度合并def deep_load(keys, defaultTrue, words(name, help)): for word in words: d ..join(k) if default else str(word) v deep_get(old, keysk, defaultd) deep_set(new, keysk, valuev)注意defaultd当某个键在旧翻译里缺失时直接拿键名当默认值。这意味着新增的配置项即便没有翻译界面上也会显示可读的层级路径如MaaFight.Stage而不是空白或报错。这套键名回退机制让开发者和翻译贡献者可以并行工作——代码先行翻译后补谁也不会阻塞谁。另一个值得玩味的细节generate_i18n里有一段把MaaFight.Stage的关卡翻译批量复制到MaaFightWeekly各星期配置的逻辑避免同一关卡的名称被翻译两次。实战排障五个最常见的翻车现场结合社区反馈和源码里的防御逻辑MAA 桥接模块的翻车点高度集中在五个地方MaaPath 填成了 exe 而非目录。maa.py里专门有一段修正逻辑如果检测到路径是MAA.exe文件就自动退到os.path.dirname取父目录并打日志提示已修正。[WinError 126] 找不到指定的模块。这是 DLL 加载失败的典型报错多半是 VC 运行库缺失或 MAA 未正确安装。源码里对这个 OSError 做了单独捕获给出明确的中文提示而非裸异常。翻译改了不生效。翻译文件在启动时被读入内存缓存改完必须点界面上的重启后端这个行为不是 bug 而是缓存策略使然。暂停功能与触控方案不匹配。DeploymentWithPause只支持maatouch选了minitouch会直接logger.critical拒绝执行。外服资源没加载。用 YoStarEN 等包名时必须走incremental_path追加resource/global/目录漏了这一步外服截图识别会全部失灵。排障的通用入口是日志运行期问题基本都能在config/*.txt或config/*_gui.txt里找到对应关键词。从使用者到贡献者一条清晰的上手路径如果你读完上面这些想动手路径其实很平坦。先把仓库克隆下来git clone https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript然后按官方deploy/下的脚本完成环境搭建。贡献前建议先关掉自动更新避免 Git 拉取干扰本地调试——这一步通常只需把更新开关关掉再在开发模式下开启翻译监控改完 i18n 文件即可热验证。对新人最友好的切入点是翻译资源把submodule/AlasMaaBridge/module/config/i18n/下缺失的 en-US 条目补全尤其是策略说明和MaaFightWeekly的关卡名。其次是配置项帮助文本——当前MaaFight的部分选项解释分散统一的help字段补齐本身就是合规的 PR。想深入的话config_updater.py的生成逻辑、handler.py的回调注册表都是值得写单测的模块。结语桥接的终点是生态回看这条把另一个游戏塞进自己进程的技术路线最打动人的不是某个炫技的 API而是它背后反复出现的同一个决策原则能不重写的就不重写能继承的就继承能用声明式生成的就别手写。ALAS 用FakeDevice架空了设备层用ctypes驯服了 DLL用回调心跳兜住了异步的不确定性用YAML 生成一切让配置和翻译永远同源——每一步都在降低维护成本和新人门槛。对双坑玩家来说这是一个一份配置管两个游戏的省心方案对开发者来说它是一份教科书级的跨项目桥接案例。未来无论是动态热加载翻译、还是把同样的桥接模式复制到更多游戏这套骨架都已经铺好了路。真正有价值的开源项目从来不是代码堆得多而是把为什么这么做讲得足够清楚——ALAS 的源码恰好就是那个最好的讲解者。【免费下载链接】AzurLaneAutoScriptAzur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研全自动大世界项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门