├── .github └── workflows │ ├── check.yml │ ├── install.yml │ ├── mirrorchyan.yml │ └── mirrorchyan_release_note.yml ├── .gitignore ├── .gitmodules ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── assets ├── __init__.py ├── custom │ ├── __init__.py │ ├── action │ │ ├── .gitignore │ │ ├── __init__.py │ │ ├── basics │ │ │ ├── CenterCamera.py │ │ │ ├── ChainLoopCircuit.py │ │ │ ├── CombatActions.py │ │ │ ├── Count.py │ │ │ ├── Identify.py │ │ │ ├── IdentifyRoles.py │ │ │ ├── MultiplayerAutoBattle.py │ │ │ ├── PPOverride.py │ │ │ ├── ResetIdentify.py │ │ │ ├── ScreenShot.py │ │ │ ├── SetTower.py │ │ │ └── __init__.py │ │ ├── exclusives │ │ │ ├── CrimsonWeave.py │ │ │ ├── LostLullaby.py │ │ │ ├── Oblivion.py │ │ │ ├── Pyroath.py │ │ │ ├── Shukra.py │ │ │ └── Stigmata.py │ │ ├── setting.json │ │ └── tool │ │ │ ├── Enum.py │ │ │ ├── JobExecutor.py │ │ │ ├── LoadSetting.py │ │ │ ├── Logger.py │ │ │ └── __init__.py │ ├── action_log │ │ └── .gitignore │ ├── agent_file.py │ ├── custom.json │ ├── main.py │ └── recognition │ │ └── exclusives │ │ ├── CalculateScore.py │ │ ├── IDFMasteryLevel.py │ │ ├── IDFMembers.py │ │ ├── IDFscore.py │ │ └── LogicalOperators.py ├── interface.json └── resource │ ├── 4399 │ └── pipeline │ │ └── 4399.json │ ├── base │ ├── default_pipeline.json │ ├── image │ │ ├── 任务 │ │ │ └── 每日_32_293_208_40__0_243_308_140.png │ │ ├── 信号球 │ │ │ ├── 启明_红.png │ │ │ ├── 启明_蓝.png │ │ │ └── 启明_黄.png │ │ ├── 厄愿潮声 │ │ │ ├── BOSS战.png │ │ │ ├── 困难战斗.png │ │ │ ├── 战斗.png │ │ │ ├── 文字事件.png │ │ │ ├── 特殊事件.png │ │ │ └── 结束.png │ │ ├── 启动 │ │ │ ├── 切换主界面状态_家园.png │ │ │ ├── 切换主界面状态_恋屿干年歌.png │ │ │ ├── 切换主界面状态_溺梦游歌.png │ │ │ ├── 切换主界面状态_白梦游弋.png │ │ │ ├── 切换主界面状态_离诗遗城.png │ │ │ ├── 切换主界面状态_耀阳映画.png │ │ │ ├── 切换主界面状态_花溪憩乡.png │ │ │ ├── 切换主界面状态_银光教堂.png │ │ │ ├── 切换主界面状态_闲庭疏影.png │ │ │ ├── 切换主界面状态_鸣神叹妙.png │ │ │ └── 切换主界面状态_默认.png │ │ ├── 宿舍委托 │ │ │ ├── 休息中_1154_383_126_61__1054_333_226_161.png │ │ │ ├── 委托存在_242_594_31_31__192_544_131_131.png │ │ │ ├── 宿舍任务_1181_82_55_55__1125_32_155_155.png │ │ │ ├── 宿舍商店内部.png │ │ │ ├── 开始制造.png │ │ │ ├── 打开执勤_1189_392_64_52__1116_342_164_152.png │ │ │ ├── 打开遣测商店.png │ │ │ ├── 进入宿舍币商店.png │ │ │ ├── 选择C级_1011_154_69_28__961_104_169_128.png │ │ │ └── 遣测商店内部.png │ │ ├── 寒境曙光 │ │ │ ├── 分数区域.png │ │ │ ├── 启程.png │ │ │ ├── 旧国遗产_决定.png │ │ │ ├── 目标分数区域.png │ │ │ ├── 确认放塔.png │ │ │ ├── 继续.png │ │ │ ├── 翻开区域_1.png │ │ │ ├── 翻开区域_2.png │ │ │ ├── 翻开区域_3.png │ │ │ └── 翻开区域_4.png │ │ ├── 幻痛囚笼 │ │ │ ├── 关闭奖励.png │ │ │ ├── 等级地狱.png │ │ │ ├── 队伍净空_红.png │ │ │ └── 队伍净空_蓝黄.png │ │ ├── 战斗 │ │ │ ├── 使用体力界面_416_207_91_95__366_157_191_195.png │ │ │ ├── 吃体力药_993_21_30_30__943_0_130_130.png │ │ │ └── 闪避.png │ │ ├── 指挥局 │ │ │ ├── 拟真围剿入口.png │ │ │ └── 返回.png │ │ ├── 矩阵循生 │ │ │ ├── BOSS.png │ │ │ ├── 对话事件.png │ │ │ ├── 对话事件1.png │ │ │ ├── 战斗地块.png │ │ │ └── 转换层级.png │ │ ├── 纷争战区 │ │ │ ├── 作战开始_未选人.png │ │ │ ├── 关闭队长选择界面.png │ │ │ └── 选择首发.png │ │ ├── 肉鸽通用 │ │ │ ├── 作战开始.png │ │ │ ├── 启明.png │ │ │ ├── 启明_矩阵.png │ │ │ ├── 启明终解.png │ │ │ ├── 启明终解_矩阵.png │ │ │ ├── 深痕.png │ │ │ ├── 深痕_矩阵.png │ │ │ ├── 深痕终解.png │ │ │ ├── 深痕终解_矩阵.png │ │ │ ├── 深红囚影.png │ │ │ ├── 深红囚影_矩阵.png │ │ │ ├── 深红囚影终解.png │ │ │ ├── 深红囚影终解_矩阵.png │ │ │ ├── 深谣.png │ │ │ ├── 深谣_矩阵.png │ │ │ ├── 深谣终解.png │ │ │ ├── 深谣终解_矩阵.png │ │ │ ├── 终焉.png │ │ │ ├── 终焉_矩阵.png │ │ │ ├── 终焉终解.png │ │ │ ├── 终焉终解_矩阵.png │ │ │ ├── 誓焰.png │ │ │ ├── 誓焰_矩阵.png │ │ │ ├── 誓焰终解.png │ │ │ ├── 誓焰终解_矩阵.png │ │ │ └── 誓焰花嫁_矩阵.png │ │ ├── 自定义战斗 │ │ │ ├── 启明.png │ │ │ ├── 深痕.png │ │ │ ├── 深痕_u1.png │ │ │ ├── 深痕_u2.png │ │ │ ├── 深痕a2.png │ │ │ ├── 深红囚影.png │ │ │ ├── 深红囚影_u1.png │ │ │ ├── 深红囚影_u2.png │ │ │ ├── 深红囚影_红球.png │ │ │ ├── 深红囚影_蓝球.png │ │ │ ├── 深红囚影_黄球.png │ │ │ ├── 深谣_p1.png │ │ │ ├── 深谣_p2.png │ │ │ ├── 深谣_u1.png │ │ │ ├── 深谣_u2.png │ │ │ ├── 深谣_核心被动1.png │ │ │ ├── 深谣_核心被动2.png │ │ │ ├── 终焉.png │ │ │ ├── 终焉_满.png │ │ │ ├── 终焉_满2.png │ │ │ ├── 誓焰.png │ │ │ ├── 誓焰_u1.png │ │ │ ├── 誓焰_u2.png │ │ │ ├── 誓焰_u2max.png │ │ │ └── 誓焰_u3.png │ │ ├── 购买碎片 │ │ │ └── 关闭_1195_30_61_61__1119_0_161_161.png │ │ ├── 通用任务 │ │ │ └── 105157_624_220_86_57__574_170_186_157.png │ │ ├── 通行证 │ │ │ ├── 通行证_家园.png │ │ │ ├── 通行证_恋屿干年歌.png │ │ │ ├── 通行证_溺梦游歌.png │ │ │ ├── 通行证_白梦游弋.png │ │ │ ├── 通行证_离诗遗城.png │ │ │ ├── 通行证_耀阳映画.png │ │ │ ├── 通行证_花溪憩乡.png │ │ │ ├── 通行证_银光教堂.png │ │ │ ├── 通行证_闲庭疏影.png │ │ │ ├── 通行证_鸣神叹妙.png │ │ │ └── 通行证_默认.png │ │ ├── 链合回路 │ │ │ ├── 技能_快枪.png │ │ │ ├── 技能_爆破.png │ │ │ ├── 技能_纵斩.png │ │ │ └── 技能_闪星.png │ │ └── 领取体力 │ │ │ ├── 点击日常补给包_21_248_127_45__0_198_227_145.png │ │ │ └── 点击补给包_488_87_117_35__438_37_217_135.png │ ├── model │ │ └── .gitignore │ └── pipeline │ │ ├── Auto_Battle │ │ ├── Auto_Battle.json │ │ ├── Auto_Battle_Quests.json │ │ ├── Auto_Battle_Shared_Quests.json │ │ ├── Check_Characters.json │ │ └── Check_Characters_Skill.json │ │ ├── Battle_Pass.json │ │ ├── Buy_Item.json │ │ ├── Chain_Loop_Circuit.json │ │ ├── Collect_Quest.json │ │ ├── Daily_Battle.json │ │ ├── Dorm │ │ ├── Dorm_Shop.json │ │ └── Dorm_Task.json │ │ ├── General.json │ │ ├── Get_Class_A.json │ │ ├── Guardian.json │ │ ├── Guild.json │ │ ├── Mail.json │ │ ├── Phantom_Pain_Cage.json │ │ ├── Receive_Stamina.json │ │ ├── Renaissance_War.json │ │ ├── Roguelike_2 │ │ ├── Roguelike_2.json │ │ └── Roguelike_2_Event.json │ │ ├── Roguelike_3 │ │ ├── RogueLike_3_Event.json │ │ └── Roguelike_3.json │ │ ├── Roguelike_4 │ │ ├── Roguelike_4.json │ │ └── Rouguelike_4_Event.json │ │ ├── Simulated_Siege.json │ │ ├── Start_up.json │ │ ├── Stop_App.json │ │ └── War_Zone.json │ ├── bilibili │ └── pipeline │ │ └── bilibili.json │ ├── bytedance │ └── pipeline │ │ └── bytedance.json │ ├── huawei │ └── pipeline │ │ └── huawei.json │ ├── mi │ └── pipeline │ │ └── mi.json │ ├── oppo │ └── pipeline │ │ └── oppo.json │ ├── tencent │ └── pipeline │ │ └── Tencent.json │ ├── vivo │ └── pipeline │ │ └── vivo.json │ └── waydroid_base │ └── pipeline │ └── waydroid.json ├── changelog-template.hbs ├── check_resource.py ├── cliff.toml ├── config └── maa_option.json ├── configure.py ├── deps └── .gitkeep ├── docs └── 自动战斗框架开发指南.md ├── install.py ├── logo.png ├── requirements.txt └── run_cli.py /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | name: check 2 | 3 | on: 4 | push: 5 | branches: 6 | - "**" 7 | paths: 8 | - ".github/workflows/check.yml" 9 | - "assets/**" 10 | - "**.py" 11 | pull_request: 12 | branches: 13 | - "**" 14 | paths: 15 | - ".github/workflows/check.yml" 16 | - "assets/**" 17 | - "**.py" 18 | workflow_dispatch: 19 | 20 | jobs: 21 | resource: 22 | runs-on: windows-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | with: 26 | fetch-depth: 0 27 | 28 | # pip install maafw 29 | - name: Install maafw 30 | run: | 31 | python -m pip install --upgrade pip 32 | python -m pip install --upgrade maafw --pre 33 | 34 | - name: Check Resource 35 | run: | 36 | python ./check_resource.py ./assets/resource/base/ ./assets/resource/bilibili/ ./assets/resource/tencent/ -------------------------------------------------------------------------------- /.github/workflows/mirrorchyan.yml: -------------------------------------------------------------------------------- 1 | name: mirrorchyan 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | mirrorchyan: 8 | runs-on: macos-latest 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | os: [win] 13 | arch: [x86_64] 14 | steps: 15 | - id: uploading 16 | uses: MirrorChyan/uploading-action@v1 17 | with: 18 | filetype: latest-release 19 | filename: "MPA-${{ matrix.os }}-${{ matrix.arch }}-*.zip" 20 | mirrorchyan_rid: MAA_Punish 21 | 22 | owner: overflow65537 23 | repo: MAA_Punish 24 | github_token: ${{ secrets.GITHUB_TOKEN }} 25 | upload_token: ${{ secrets.MirrorChyanUploadToken }} 26 | os: ${{ matrix.os }} 27 | arch: ${{ matrix.arch }} 28 | 29 | mirrorchyan_res: 30 | runs-on: macos-latest 31 | steps: 32 | - id: uploading 33 | uses: MirrorChyan/uploading-action@v1 34 | with: 35 | filetype: latest-release 36 | filename: "MPA-win-x86_64-v*.zip" 37 | pick_files: '["resource", "interface.json", "custom"]' 38 | exclude_files: '["*model/ocr/**"]' 39 | mirrorchyan_rid: MAA_Punish 40 | 41 | owner: overflow65537 42 | repo: MAA_Punish 43 | github_token: ${{ secrets.GITHUB_TOKEN }} 44 | upload_token: ${{ secrets.MirrorChyanUploadToken }} 45 | -------------------------------------------------------------------------------- /.github/workflows/mirrorchyan_release_note.yml: -------------------------------------------------------------------------------- 1 | name: mirrorchyan_release_note 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [edited] 7 | 8 | jobs: 9 | mirrorchyan: 10 | runs-on: macos-latest 11 | 12 | steps: 13 | - id: uploading 14 | uses: MirrorChyan/release-note-action@v1 15 | with: 16 | mirrorchyan_rid : MAA_Punish 17 | 18 | upload_token: ${{ secrets.MirrorChyanUploadToken }} 19 | github_token: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "assets/MaaCommonAssets"] 2 | path = assets/MaaCommonAssets 3 | url = https://github.com/MaaXYZ/MaaCommonAssets 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "json.schemas": [ 3 | { 4 | "fileMatch": [ 5 | "/assets/resource/**/*.json", 6 | "/install/resource/**/*.json" 7 | ], 8 | "url": "/deps/tools/pipeline.schema.json" 9 | } 10 | ], 11 | "[json]": { 12 | "editor.formatOnSave": true, 13 | "editor.insertSpaces": true, 14 | "editor.tabSize": 4, 15 | "editor.indentSize": "tabSize" 16 | }, 17 | "[python]": { 18 | "editor.defaultFormatter": "ms-python.black-formatter" 19 | }, 20 | "python.analysis.autoImportCompletions": true 21 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 overflow65537 4 | Copyright (c) 2025 HCX0426 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | LOGO 4 |

5 | 6 |
7 | 8 | # MAA_Punish 9 | 10 | 基于全新架构的 战双帕弥什 小助手。图像技术 + 模拟控制,解放双手! 11 | 由 [MaaFramework](https://github.com/MaaXYZ/MaaFramework) 强力驱动! 12 | 13 |
14 | 15 |

16 | license 17 | Python 18 | platform 19 | commit 20 | mirrorchyan_rid 21 |

22 | 23 | ## 主要功能 24 | 25 | - 启动/关闭游戏 26 | - 指挥局抽签 27 | - 宿舍委托 28 | - 宿舍任务 29 | - 指挥局签到 30 | - 拟真围剿 31 | - 刷A级碎片 32 | - 纷争战区自动首通 33 | - 诺曼矿区自动首通 34 | - 幻痛囚笼自动首通 35 | - 维系者行动 36 | - 领取邮件 37 | - 商店自动购买逆元碎片 38 | - 领取体力 39 | - 自动刷拟战场域 40 | - 领取凭证和任务奖励 41 | - 自动肉鸽-厄愿潮声 42 | - 自动肉鸽-矩阵循生 43 | - 自动肉鸽-寒境曙光 44 | 45 | ## 注意事项 46 | 47 | - 打开无法运行首先尝试安装运行库 48 | - 如有其他问题可以提交issue或者加群反馈 **965061066**,反馈问题请附上日志文件 `debug/maa.log`,谢谢! 49 | 50 | ## 开发相关 51 | 52 | MPA目前支持[深红囚影](assets/custom/action/exclusives/CrimsonWeave.py),[深谣](assets/custom/action/exclusives/LostLullaby.py),[终焉](assets/custom/action/exclusives/Oblivion.py),[誓焰](assets/custom/action/exclusives/Pyroath.py),[启明](assets/custom/action/exclusives/Shukra.py)以及[深痕](assets/custom/action/exclusives/Stigmata.py)的自动战斗逻辑,其余部分人物由于开发者精力有限,无法同时添加,如果希望自行添加,具体参考[如何编写战斗逻辑](docs/自动战斗框架开发指南.md),开发途中有问题可以进群反馈 **965061066** 53 | 54 | ### 开发文档 55 | 56 | - [MaaFramework 快速开始](https://github.com/MaaAssistantArknights/MaaFramework/blob/main/docs/zh_cn/1.1-%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.md) 57 | - [如何编写战斗逻辑](docs/自动战斗框架开发指南.md) 58 | 59 | ### How to build 60 | 61 | **如果你要编译源码才看这节,否则直接 [下载](https://github.com/overflow65537/MAA_Punish/releases) 即可** 62 | 63 | 0. 完整克隆本项目及子项目 64 | 65 | ```bash 66 | git clone --recursive https://github.com/overflow65537/MAA_Punish.git 67 | ``` 68 | 69 | 1. 下载 MaaFramework 的 [Release 包](https://github.com/MaaXYZ/MaaFramework/releases),解压到 `deps` 文件夹中 70 | 2. 安装 71 | 72 | ```python 73 | python ./install.py 74 | ``` 75 | 76 | 生成的二进制及相关资源文件在 `install` 目录下 77 | 78 | ## 鸣谢 79 | 80 | ### 开源库 81 | 82 | - [MaaFramework](https://github.com/MaaXYZ/MaaFramework) 83 | 84 | 基于图像识别的自动化黑盒测试框架 | An automation black-box testing framework based on image recognition 85 | 86 | - [MFW-PyQt6](https://github.com/overflow65537/MFW-PyQt6) 87 | 基于 PyQt6 的 MaaFramework 前端 | A frontend based on PyQt6 for MaaFramework 88 | 89 | ### 开发者 90 | 91 | 感谢以下开发者对 MAA_Punish 作出的贡献: 92 | 93 | 94 | Contributors to MAA_Punish 95 | 96 | -------------------------------------------------------------------------------- /assets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/__init__.py -------------------------------------------------------------------------------- /assets/custom/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/custom/__init__.py -------------------------------------------------------------------------------- /assets/custom/action/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # UV 98 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | #uv.lock 102 | 103 | # poetry 104 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 105 | # This is especially recommended for binary packages to ensure reproducibility, and is more 106 | # commonly ignored for libraries. 107 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 108 | #poetry.lock 109 | 110 | # pdm 111 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 112 | #pdm.lock 113 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 114 | # in version control. 115 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control 116 | .pdm.toml 117 | .pdm-python 118 | .pdm-build/ 119 | 120 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 121 | __pypackages__/ 122 | 123 | # Celery stuff 124 | celerybeat-schedule 125 | celerybeat.pid 126 | 127 | # SageMath parsed files 128 | *.sage.py 129 | 130 | # Environments 131 | .env 132 | .venv 133 | env/ 134 | venv/ 135 | ENV/ 136 | env.bak/ 137 | venv.bak/ 138 | 139 | # Spyder project settings 140 | .spyderproject 141 | .spyproject 142 | 143 | # Rope project settings 144 | .ropeproject 145 | 146 | # mkdocs documentation 147 | /site 148 | 149 | # mypy 150 | .mypy_cache/ 151 | .dmypy.json 152 | dmypy.json 153 | 154 | # Pyre type checker 155 | .pyre/ 156 | 157 | # pytype static type analyzer 158 | .pytype/ 159 | 160 | # Cython debug symbols 161 | cython_debug/ 162 | 163 | # PyCharm 164 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 165 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 166 | # and can be added to the global gitignore or merged into this file. For a more nuclear 167 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 168 | #.idea/ 169 | 170 | # PyPI configuration file 171 | .pypirc 172 | -------------------------------------------------------------------------------- /assets/custom/action/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/custom/action/__init__.py -------------------------------------------------------------------------------- /assets/custom/action/basics/CenterCamera.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 肉鸽4重置镜头 24 | 作者:overflow65537 25 | """ 26 | 27 | 28 | from maa.context import Context 29 | from maa.custom_action import CustomAction 30 | import time 31 | 32 | 33 | class CenterCamera(CustomAction): 34 | def run( 35 | self, context: Context, argv: CustomAction.RunArg 36 | ) -> CustomAction.RunResult: 37 | image = context.tasker.controller.post_screencap().wait().get() 38 | if argv.custom_action_param == '{"tower":true}': 39 | origin_pos = context.run_recognition("战斗地块_寒境曙光", image) 40 | if not origin_pos or not origin_pos.best_result: 41 | return CustomAction.RunResult(success=True) 42 | x, y = ( 43 | origin_pos.best_result.box[0], 44 | origin_pos.best_result.box[1], 45 | ) 46 | context.tasker.controller.post_swipe(x, y, 764, 334, 2000).wait() 47 | time.sleep(1) 48 | context.tasker.controller.post_click(100, 100).wait() 49 | time.sleep(1) 50 | return CustomAction.RunResult(success=True) 51 | else: 52 | origin_pos = context.run_recognition("重置镜头", image) 53 | if not origin_pos or not origin_pos.best_result: 54 | return CustomAction.RunResult(success=True) 55 | x, y = ( 56 | origin_pos.best_result.box[0], 57 | origin_pos.best_result.box[1], 58 | ) 59 | context.tasker.controller.post_swipe(x, y, 1052, 342, 2000).wait() 60 | time.sleep(1) 61 | context.tasker.controller.post_click(100, 100).wait() 62 | time.sleep(1) 63 | return CustomAction.RunResult(success=True) 64 | -------------------------------------------------------------------------------- /assets/custom/action/basics/Count.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 计数程序 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_action import CustomAction 29 | import json 30 | 31 | 32 | class Count(CustomAction): 33 | def run( 34 | self, context: Context, argv: CustomAction.RunArg 35 | ) -> CustomAction.RunResult: 36 | """ 37 | 自定义动作: 38 | custom_action_param: 39 | { 40 | "count": 0, 41 | "target_count": 10, 42 | "next_node": ["node1", "node2"], 43 | "else_node": ["node3"], 44 | "next_node_msg": "已达到目标次数,执行下一节点 {next_node}", 45 | "else_node_msg": "未达到目标次数,执行备用节点 {else_node}", 46 | "count_msg": "当前次数: {count}, 目标次数: {target_count}" 47 | } 48 | count: 当前次数 49 | target_count: 目标次数 50 | next_node: 达到目标次数后执行的节点. 支持多个节点,按顺序执行,可以出现重复节点,可以为空 51 | else_node: 未达到目标次数时执行的节点. 支持多个节点,按顺序执行,可以出现重复节点,可以为空 52 | next_node_msg: 达到目标次数后执行的节点时的提示消息,可以为空 可以使用 {next_node} 来引用 next_node 中的节点名称 53 | else_node_msg: 未达到目标次数时执行的节点时的提示消息 可以为空 可以使用 {else_node} 来引用 else_node 中的节点名称 54 | count_msg: 每次执行时的提示消息 可以为空 可以使用 {count} 来引用 count 中的当前次数 可以使用 {target_count} 来引用 target_count 中的目标次数 55 | """ 56 | 57 | argv_dict: dict = json.loads(argv.custom_action_param) 58 | if not argv_dict: 59 | return CustomAction.RunResult(success=True) 60 | 61 | # 提取参数 62 | current_count: int = argv_dict.get("count", 0) 63 | target_count: int = argv_dict.get("target_count", 0) 64 | next_node_msg: str = argv_dict.get("next_node_msg", "") 65 | else_node_msg: str = argv_dict.get("else_node_msg", "") 66 | count_msg: str = argv_dict.get("count_msg", "") 67 | 68 | if current_count <= target_count: 69 | # 计数未达标时:递增计数并执行备用节点 70 | new_count = current_count + 1 71 | argv_dict["count"] = new_count 72 | 73 | # 输出计数提示(使用更新后的计数) 74 | if count_msg: 75 | self.custom_notify( 76 | context, 77 | count_msg.format(count=new_count - 1, target_count=target_count), 78 | ) 79 | 80 | # 保存更新后的参数 81 | context.override_pipeline( 82 | {argv.node_name: {"custom_action_param": argv_dict}} 83 | ) 84 | 85 | # 输出备用节点提示 86 | else_nodes = argv_dict.get("else_node") 87 | if else_node_msg and else_nodes: 88 | node_str = ( 89 | else_nodes if isinstance(else_nodes, str) else ", ".join(else_nodes) 90 | ) 91 | self.custom_notify(context, else_node_msg.format(else_node=node_str)) 92 | self._run_nodes(context, else_nodes) 93 | else: 94 | # 计数达标时:重置计数并执行下一节点 95 | reset_params = { 96 | "count": 0, 97 | "target_count": target_count, 98 | "else_node": argv_dict.get("else_node"), 99 | "next_node": argv_dict.get("next_node"), 100 | # 保留消息参数避免丢失 101 | "next_node_msg": next_node_msg, 102 | "else_node_msg": else_node_msg, 103 | "count_msg": count_msg, 104 | } 105 | 106 | # 保存重置后的参数 107 | context.override_pipeline( 108 | {argv.node_name: {"custom_action_param": reset_params}} 109 | ) 110 | 111 | # 输出下一节点提示 112 | next_nodes = argv_dict.get("next_node") 113 | if next_node_msg and next_nodes: 114 | node_str = ( 115 | next_nodes if isinstance(next_nodes, str) else ", ".join(next_nodes) 116 | ) 117 | self.custom_notify(context, next_node_msg.format(next_node=node_str)) 118 | self._run_nodes(context, next_nodes) 119 | 120 | return CustomAction.RunResult(success=True) 121 | 122 | def _run_nodes(self, context: Context, nodes: str | list[str] | None): 123 | """统一处理节点执行逻辑""" 124 | if not nodes: 125 | return 126 | # 确保节点列表为列表类型 127 | if isinstance(nodes, str): 128 | nodes = [nodes] 129 | for node in nodes: 130 | context.run_task(node) 131 | 132 | def custom_notify(self, context: Context, msg): 133 | context.override_pipeline({"custom通知": {"focus": {"succeeded": msg}}}) 134 | context.run_task("custom通知") 135 | -------------------------------------------------------------------------------- /assets/custom/action/basics/Identify.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 特殊战斗识别 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_action import CustomAction 29 | 30 | 31 | class Identify(CustomAction): 32 | def run( 33 | self, context: Context, argv: CustomAction.RunArg 34 | ) -> CustomAction.RunResult: 35 | image = context.tasker.controller.post_screencap().wait().get() 36 | if context.run_recognition("检查露娜·终焉", image): 37 | context.override_pipeline( 38 | { 39 | "识别人物": {"enabled": False}, 40 | "战斗中": {"action": "Custom", "custom_action": "Oblivion"}, 41 | } 42 | ) 43 | print("终焉战斗") 44 | elif context.run_recognition("检查比安卡·深痕", image): 45 | context.override_pipeline( 46 | { 47 | "识别人物": {"enabled": False}, 48 | "战斗中": {"action": "Custom", "custom_action": "Stigmata"}, 49 | } 50 | ) 51 | print("深痕战斗") 52 | elif context.run_recognition("检查拉弥亚·深谣", image): 53 | context.override_pipeline( 54 | { 55 | "识别人物": {"enabled": False}, 56 | "战斗中": {"action": "Custom", "custom_action": "LostLullaby"}, 57 | } 58 | ) 59 | print("深谣战斗") 60 | elif context.run_recognition("检查露西亚·深红囚影", image): 61 | context.override_pipeline( 62 | { 63 | "识别人物": {"enabled": False}, 64 | "战斗中": {"action": "Custom", "custom_action": "CrimsonWeave"}, 65 | } 66 | ) 67 | print("深红囚影") 68 | elif context.run_recognition("检查露西亚·誓焰", image): 69 | context.override_pipeline( 70 | { 71 | "识别人物": {"enabled": False}, 72 | "战斗中": {"action": "Custom", "custom_action": "Pyroath"}, 73 | } 74 | ) 75 | print("誓焰战斗") 76 | elif context.run_recognition("检查曲·启明", image): 77 | context.override_pipeline( 78 | { 79 | "识别人物": {"enabled": False}, 80 | "战斗中": {"action": "Custom", "custom_action": "Shukra"}, 81 | } 82 | ) 83 | print("启明战斗") 84 | else: 85 | context.override_pipeline( 86 | { 87 | "识别人物": {"enabled": False}, 88 | "战斗中": {"action": "Custom", "custom_action": "CombatActions"}, 89 | } 90 | ) 91 | print("未知战斗") 92 | 93 | return CustomAction.RunResult(success=True) 94 | -------------------------------------------------------------------------------- /assets/custom/action/basics/IdentifyRoles.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 识别角色 24 | 作者:HCX0426 25 | """ 26 | 27 | import sys 28 | import time 29 | from pathlib import Path 30 | from typing import Dict, Optional 31 | 32 | from maa.context import Context 33 | from maa.custom_action import CustomAction 34 | 35 | # 获取当前文件的绝对路径 36 | current_file = Path(__file__).resolve() 37 | 38 | # 定义可能的项目根目录相对路径 39 | root_paths = [ 40 | current_file.parent.parent.parent.parent.joinpath("MFW_resource"), 41 | current_file.parent.parent.parent.parent.parent.parent.joinpath("Bundles").joinpath( 42 | "MAA_Punish" 43 | ), 44 | current_file.parent.parent.parent.parent.parent.joinpath("assets"), 45 | ] 46 | 47 | # 确定项目根目录 48 | project_root = next((path for path in root_paths if path.exists()), None) 49 | if project_root: 50 | if project_root == current_file.parent.parent.parent.parent.joinpath( 51 | "MFW_resource" 52 | ): 53 | project_root = current_file.parent.parent.parent.parent 54 | print(f"项目根目录: {project_root}") 55 | # 添加项目根目录到sys.path 56 | sys.path.append(str(project_root)) 57 | 58 | from custom.action.tool.LoadSetting import ROLE_ACTIONS 59 | else: 60 | from assets.custom.action.tool.LoadSetting import ROLE_ACTIONS 61 | 62 | 63 | class IdentifyRoles(CustomAction): 64 | def run(self, context: Context, _: CustomAction.RunArg) -> CustomAction.RunResult: 65 | 66 | # ROI区域配置(x, y, w, h) 67 | ROLE_NAME_ROIS = [ 68 | ("pos1", (209, 303, 259, 46)), 69 | ("pos2", (514, 308, 252, 43)), 70 | ("pos3", (821, 302, 243, 51)), 71 | ] 72 | 73 | LEADER_FLAG_ROIS = [ 74 | ("pos1", (236, 509, 210, 59)), 75 | ("pos2", (535, 512, 212, 53)), 76 | ("pos3", (850, 509, 183, 61)), 77 | ] 78 | 79 | # 进入角色选择界面 80 | context.run_task("点击更换") 81 | time.sleep(1) 82 | 83 | # 获取屏幕截图 84 | image = context.tasker.controller.post_screencap().wait().get() 85 | 86 | # 识别角色名称 87 | role_names: Dict[str, Optional[str]] = {} 88 | for pos, roi in ROLE_NAME_ROIS: 89 | result = context.run_recognition( 90 | "识别角色名", image, {"识别角色名": {"roi": roi}} 91 | ) 92 | role_names[pos] = result.best_result.text if result else None 93 | 94 | # 识别队长标志 95 | leader_flags: Dict[str, bool] = {} 96 | for pos, roi in LEADER_FLAG_ROIS: 97 | result = context.run_recognition( 98 | "识别队长位置", image, {"识别队长位置": {"roi": roi}} 99 | ) 100 | leader_flags[pos] = bool(result.best_result.text) if result else False 101 | 102 | print("识别结果:", role_names) 103 | print("队长标记:", leader_flags) 104 | if ( 105 | not leader_flags.get("pos1") 106 | and not leader_flags.get("pos2") 107 | and not leader_flags.get("pos3") 108 | ): # 未找到队长,通常是只有一个角色在1号位,但队长标记在2号位 109 | context.run_task("选择队长") # 随便选择一个队长 110 | # 退出角色选择界面 111 | context.run_task("出队长界面") 112 | 113 | # 匹配角色并获取对应动作 114 | matched_roles = { 115 | pos: ROLE_ACTIONS[name] 116 | for pos, name in role_names.items() 117 | if name in ROLE_ACTIONS 118 | } 119 | 120 | # 处理匹配结果 121 | match len(matched_roles): 122 | case 1: # 单个角色匹配 123 | pos, action = next(iter(matched_roles.items())) 124 | 125 | # 设置队长位置(单个角色特用) 126 | if leader_flags.get(pos): 127 | color_map = {"pos1": "蓝色", "pos2": "红色", "pos3": "黄色"} 128 | context.run_task( 129 | "点击首选位置", {"点击首选位置": {"expected": color_map[pos]}} 130 | ) 131 | 132 | # 覆写战斗流程 133 | context.override_pipeline( 134 | { 135 | "角色特有战斗": {"action": "Custom", "custom_action": action}, 136 | "自动战斗开始": {"next": ["单人自动战斗循环"]}, 137 | } 138 | ) 139 | case n if n > 1: # 多个角色匹配 140 | context.override_pipeline( 141 | { 142 | "自动战斗开始": {"next": ["多人轮切自动战斗循环"]}, 143 | } 144 | ) 145 | case _: # 无匹配角色 146 | if len(role_names) == 1: 147 | # 设置队长位置(单个角色特用) 148 | if leader_flags.get(pos): 149 | color_map = {"pos1": "蓝色", "pos2": "红色", "pos3": "黄色"} 150 | context.run_task( 151 | "点击首选位置", 152 | {"点击首选位置": {"expected": color_map[pos]}}, 153 | ) 154 | 155 | context.override_pipeline( 156 | { 157 | "自动战斗开始": {"next": ["通用自动战斗循环"]}, 158 | } 159 | ) 160 | 161 | context.run_task("点击作战开始") 162 | return CustomAction.RunResult(success=True) 163 | -------------------------------------------------------------------------------- /assets/custom/action/basics/MultiplayerAutoBattle.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 多人自动战斗 24 | 作者:HCX0426 25 | """ 26 | 27 | import sys 28 | import time 29 | from pathlib import Path 30 | 31 | from maa.context import Context 32 | from maa.custom_action import CustomAction 33 | 34 | # 获取当前文件的绝对路径 35 | current_file = Path(__file__).resolve() 36 | 37 | # 定义可能的项目根目录相对路径 38 | root_paths = [ 39 | current_file.parent.parent.parent.parent.joinpath("MFW_resource"), 40 | current_file.parent.parent.parent.parent.parent.parent.joinpath("Bundles").joinpath( 41 | "MAA_Punish" 42 | ), 43 | current_file.parent.parent.parent.parent.parent.joinpath("assets"), 44 | ] 45 | 46 | # 确定项目根目录 47 | project_root = next((path for path in root_paths if path.exists()), None) 48 | if project_root: 49 | if project_root == current_file.parent.parent.parent.parent.joinpath( 50 | "MFW_resource" 51 | ): 52 | project_root = current_file.parent.parent.parent.parent 53 | print(f"项目根目录: {project_root}") 54 | # 添加项目根目录到sys.path 55 | sys.path.append(str(project_root)) 56 | 57 | from custom.action.tool.LoadSetting import ROLE_ACTIONS 58 | else: 59 | from assets.custom.action.tool.LoadSetting import ROLE_ACTIONS 60 | 61 | 62 | class MultiplayerAutoBattle(CustomAction): 63 | def run( 64 | self, context: Context, argv: CustomAction.RunArg 65 | ) -> CustomAction.RunResult: 66 | try: 67 | image = context.tasker.controller.post_screencap().wait().get() 68 | 69 | # 检查当前角色 70 | recognized_role = None 71 | for role_name, action in ROLE_ACTIONS.items(): 72 | result = context.run_recognition(f"检查{role_name}", image) 73 | if result is not None: 74 | recognized_role = {"action": "Custom", "custom_action": action} 75 | break 76 | 77 | if recognized_role: 78 | context.override_pipeline({"角色特有战斗": recognized_role}) 79 | max_battles = 8 80 | else: 81 | context.override_pipeline({"通用战斗模式": {}}) 82 | max_battles = 3 83 | 84 | n = 0 85 | while n < max_battles: 86 | context.run_task("角色特有战斗" if recognized_role else "通用战斗模式") 87 | n += 1 88 | 89 | return CustomAction.RunResult(success=True) 90 | except Exception as e: 91 | # 捕获异常并记录错误信息 92 | print(f"执行MultiplayerAutoBattle时发生错误: {e}") 93 | return CustomAction.RunResult(success=False) 94 | -------------------------------------------------------------------------------- /assets/custom/action/basics/PPOverride.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish pipeline 覆盖 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_action import CustomAction 29 | import json 30 | 31 | 32 | class PPOverride(CustomAction): 33 | def run( 34 | self, context: Context, argv: CustomAction.RunArg 35 | ) -> CustomAction.RunResult: 36 | argv = json.loads(argv.custom_action_param) 37 | if not argv: 38 | return CustomAction.RunResult(success=True) 39 | context.override_pipeline(argv) 40 | return CustomAction.RunResult(success=True) 41 | -------------------------------------------------------------------------------- /assets/custom/action/basics/ResetIdentify.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 重置特殊识别 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_action import CustomAction 29 | import json 30 | 31 | 32 | class ResetIdentify(CustomAction): 33 | def run( 34 | self, context: Context, argv: CustomAction.RunArg 35 | ) -> CustomAction.RunResult: 36 | argv: dict = json.loads(argv.custom_action_param) 37 | print(f"argv: {argv}") 38 | if not argv: 39 | context.override_pipeline({"识别人物": {"enabled": True}}) 40 | 41 | elif argv.get("mode") == "矩阵循生": 42 | 43 | context.override_pipeline( 44 | { 45 | "选择首发_矩阵循生": {"enabled": False}, 46 | "异度投影_矩阵循生": {"enabled": False}, 47 | "进入物归新主_矩阵循生": {"enabled": True}, 48 | "选择首发2_矩阵循生": {"enabled": True}, 49 | "矩阵循生": { 50 | "action": "custom", 51 | "custom_action": "ResetIdentify", 52 | "custom_action_param": {"mode": "矩阵循生"}, 53 | }, 54 | } 55 | ) 56 | 57 | return CustomAction.RunResult(success=True) 58 | -------------------------------------------------------------------------------- /assets/custom/action/basics/ScreenShot.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 截图 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_action import CustomAction 29 | import os 30 | import time 31 | import struct 32 | import zlib 33 | import numpy 34 | import json 35 | 36 | 37 | class ScreenShot(CustomAction): 38 | def run( 39 | self, context: Context, argv: CustomAction.RunArg 40 | ) -> CustomAction.RunResult: 41 | custom_action_param: dict = json.loads(argv.custom_action_param) 42 | image: numpy.ndarray = context.tasker.controller.post_screencap().wait().get() 43 | 44 | debug_dir = os.path.abspath("debug") 45 | three_days_ago = time.time() - 3 * 24 * 3600 46 | if os.path.exists(debug_dir): 47 | for entry in os.scandir(debug_dir): 48 | if ( 49 | entry.is_file() 50 | and entry.name.lower().endswith(".png") 51 | and entry.stat(follow_symlinks=False).st_mtime < three_days_ago 52 | ): 53 | try: 54 | os.remove(entry.path) 55 | except: 56 | pass 57 | 58 | height, width, _ = image.shape 59 | current_time = ( 60 | custom_action_param.get("type", "") 61 | + "_" 62 | + time.strftime("%Y-%m-%d_%H-%M-%S") 63 | + ".png" 64 | ) 65 | debug_path = os.path.join("debug", current_time) 66 | 67 | def png_chunk(chunk_type, data): 68 | chunk = chunk_type + data 69 | return ( 70 | struct.pack("!I", len(data)) 71 | + chunk 72 | + struct.pack("!I", zlib.crc32(chunk)) 73 | ) 74 | 75 | # Convert BGR to RGB 76 | image = image[:, :, [2, 1, 0]] 77 | 78 | raw_data = b"".join(b"\x00" + image[i, :, :].tobytes() for i in range(height)) 79 | ihdr = struct.pack("!2I5B", width, height, 8, 2, 0, 0, 0) 80 | idat = zlib.compress(raw_data, level=9) 81 | 82 | with open(debug_path, "wb") as f: 83 | f.write(b"\x89PNG\r\n\x1a\n") 84 | f.write(png_chunk(b"IHDR", ihdr)) 85 | f.write(png_chunk(b"IDAT", idat)) 86 | f.write(png_chunk(b"IEND", b"")) 87 | 88 | return CustomAction.RunResult(success=True) 89 | -------------------------------------------------------------------------------- /assets/custom/action/basics/SetTower.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 放置计算器 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_action import CustomAction 29 | 30 | 31 | class SetTower(CustomAction): 32 | def run( 33 | self, context: Context, argv: CustomAction.RunArg 34 | ) -> CustomAction.RunResult: 35 | image = context.tasker.controller.post_screencap().wait().get() 36 | target_pos = context.run_recognition("战斗地块_寒境曙光", image) 37 | if target_pos: 38 | image = context.tasker.controller.post_screencap().wait().get() 39 | empty_pos = context.run_recognition( 40 | "识别周围空地", 41 | image, 42 | { 43 | "识别周围空地": { 44 | "roi": "战斗地块_寒境曙光", 45 | "roi_offset": [-240, -180, 380, 320], 46 | } 47 | }, 48 | ) 49 | if empty_pos: 50 | context.tasker.controller.post_click( 51 | empty_pos.best_result.box[0], empty_pos.best_result.box[1] 52 | ).wait() 53 | return CustomAction.RunResult(success=True) 54 | -------------------------------------------------------------------------------- /assets/custom/action/basics/__init__.py: -------------------------------------------------------------------------------- 1 | from .CombatActions import CombatActions 2 | 3 | __all__ = ['CombatActions'] # 可选,明确导出的内容 -------------------------------------------------------------------------------- /assets/custom/action/exclusives/CrimsonWeave.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 囚影战斗程序 24 | 作者:overflow65537,HCX0426 25 | """ 26 | 27 | import logging 28 | import time 29 | 30 | from custom.action.basics import CombatActions 31 | from custom.action.tool import JobExecutor 32 | from custom.action.tool.Enum import GameActionEnum 33 | from custom.action.tool.LoadSetting import ROLE_ACTIONS 34 | 35 | from maa.context import Context 36 | from maa.custom_action import CustomAction 37 | 38 | 39 | class CrimsonWeave(CustomAction): 40 | def __init__(self): 41 | super().__init__() 42 | for name, action in ROLE_ACTIONS.items(): 43 | if action in self.__class__.__name__: 44 | self._role_name = name 45 | 46 | def run( 47 | self, context: Context, argv: CustomAction.RunArg 48 | ) -> CustomAction.RunResult: 49 | try: 50 | lens_lock = JobExecutor( 51 | CombatActions.lens_lock(context), 52 | GameActionEnum.LENS_LOCK, 53 | role_name=self._role_name, 54 | ) 55 | attack = JobExecutor( 56 | CombatActions.attack(context), 57 | GameActionEnum.ATTACK, 58 | role_name=self._role_name, 59 | ) 60 | dodge = JobExecutor( 61 | CombatActions.dodge(context), 62 | GameActionEnum.DODGE, 63 | role_name=self._role_name, 64 | ) 65 | 66 | use_skill = JobExecutor( 67 | CombatActions.use_skill(context), 68 | GameActionEnum.USE_SKILL, 69 | role_name=self._role_name, 70 | ) 71 | long_press_dodge = JobExecutor( 72 | CombatActions.long_press_dodge(context, 1500), 73 | GameActionEnum.LONG_PRESS_DODGE, 74 | role_name=self._role_name, 75 | ) 76 | long_press_attack = JobExecutor( 77 | CombatActions.long_press_attack(context, 2500), 78 | GameActionEnum.LONG_PRESS_ATTACK, 79 | role_name=self._role_name, 80 | ) 81 | ball_elimination = JobExecutor( 82 | CombatActions.ball_elimination(context), 83 | GameActionEnum.BALL_ELIMINATION, 84 | role_name=self._role_name, 85 | ) 86 | trigger_qte_first = JobExecutor( 87 | CombatActions.trigger_qte_first(context), 88 | GameActionEnum.TRIGGER_QTE_FIRST, 89 | role_name=self._role_name, 90 | ) 91 | trigger_qte_second = JobExecutor( 92 | CombatActions.trigger_qte_second(context), 93 | GameActionEnum.TRIGGER_QTE_SECOND, 94 | role_name=self._role_name, 95 | ) 96 | auxiliary_machine = JobExecutor( 97 | CombatActions.auxiliary_machine(context), 98 | GameActionEnum.AUXILIARY_MACHINE, 99 | role_name=self._role_name, 100 | ) 101 | lens_lock.execute() 102 | 103 | if CombatActions.check_Skill_energy_bar(context, self._role_name): 104 | if CombatActions.check_status( 105 | context, "检查u1_囚影", self._role_name 106 | ): # 一阶段 107 | use_skill.execute() # 崩落的束缚化为利刃 108 | time.sleep(0.3) 109 | long_press_attack.execute() # 登龙 110 | 111 | if CombatActions.check_status( 112 | context, "检查u2_囚影", self._role_name 113 | ): # 二阶段 114 | if CombatActions.check_status( 115 | context, "检查无光值_囚影", self._role_name 116 | ): # 检查无光值大于474 117 | long_press_attack.execute() # 登龙 118 | ball_elimination.execute() # 消球 119 | time.sleep(0.4) 120 | ball_elimination.execute() # 消球 121 | 122 | else: 123 | use_skill.execute() # 宿命的囚笼由我斩断 124 | for _ in range(2): 125 | time.sleep(0.2) 126 | trigger_qte_first.execute() 127 | trigger_qte_second.execute() 128 | auxiliary_machine.execute() 129 | else: 130 | ball_elimination.execute() # 消球 131 | time.sleep(1) 132 | ball_elimination.execute() # 消球 133 | dodge.execute() # 闪避 134 | start_time = time.time() 135 | while time.time() - start_time < 1.5: 136 | time.sleep(0.1) 137 | attack.execute() # 攻击 138 | ball_elimination.execute() # 消球 139 | long_press_dodge.execute() # 长按闪避 140 | if CombatActions.check_status(context, "检查u2_囚影", self._role_name): 141 | long_press_attack.execute() # 登龙 142 | 143 | return CustomAction.RunResult(success=True) 144 | except Exception as e: 145 | logging.getLogger(f"{self._role_name}_Job").exception(str(e)) 146 | return CustomAction.RunResult(success=False) 147 | -------------------------------------------------------------------------------- /assets/custom/action/exclusives/Oblivion.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 终焉战斗程序 24 | 作者:overflow65537,HCX0426 25 | """ 26 | 27 | 28 | import logging 29 | import time 30 | 31 | from custom.action.basics import CombatActions 32 | from custom.action.tool import JobExecutor 33 | from custom.action.tool.Enum import GameActionEnum 34 | from custom.action.tool.LoadSetting import ROLE_ACTIONS 35 | 36 | from maa.context import Context 37 | from maa.custom_action import CustomAction 38 | 39 | 40 | class Oblivion(CustomAction): 41 | def __init__(self): 42 | super().__init__() 43 | for name, action in ROLE_ACTIONS.items(): 44 | if action in self.__class__.__name__: 45 | self._role_name = name 46 | 47 | def run( 48 | self, context: Context, argv: CustomAction.RunArg 49 | ) -> CustomAction.RunResult: 50 | try: 51 | lens_lock = JobExecutor( 52 | CombatActions.lens_lock(context), 53 | GameActionEnum.LENS_LOCK, 54 | role_name=self._role_name, 55 | ) 56 | 57 | use_skill = JobExecutor( 58 | CombatActions.use_skill(context), 59 | GameActionEnum.USE_SKILL, 60 | role_name=self._role_name, 61 | ) 62 | long_press_attack = JobExecutor( 63 | CombatActions.long_press_attack(context, 2100), 64 | GameActionEnum.LONG_PRESS_ATTACK, 65 | role_name=self._role_name, 66 | ) 67 | ball_elimination = JobExecutor( 68 | CombatActions.ball_elimination(context), 69 | GameActionEnum.BALL_ELIMINATION, 70 | role_name=self._role_name, 71 | ) 72 | 73 | trigger_qte_first = JobExecutor( 74 | CombatActions.trigger_qte_first(context), 75 | GameActionEnum.TRIGGER_QTE_FIRST, 76 | role_name=self._role_name, 77 | ) 78 | trigger_qte_second = JobExecutor( 79 | CombatActions.trigger_qte_second(context), 80 | GameActionEnum.TRIGGER_QTE_SECOND, 81 | role_name=self._role_name, 82 | ) 83 | auxiliary_machine = JobExecutor( 84 | CombatActions.auxiliary_machine(context), 85 | GameActionEnum.AUXILIARY_MACHINE, 86 | role_name=self._role_name, 87 | ) 88 | # 等待时间为技能动画时间 89 | lens_lock.execute() 90 | if CombatActions.check_status(context, "检查残月值_终焉", self._role_name): 91 | long_press_attack.execute() 92 | if CombatActions.check_Skill_energy_bar(context, self._role_name): 93 | use_skill.execute() 94 | for _ in range(2): # 防止未触发QTE和辅助机 95 | time.sleep(0.3) 96 | trigger_qte_first.execute() 97 | trigger_qte_second.execute() 98 | auxiliary_machine.execute() 99 | else: 100 | ball_elimination.execute() 101 | time.sleep(0.1) 102 | ball_elimination.execute() 103 | long_press_attack.execute() 104 | if CombatActions.check_Skill_energy_bar(context, self._role_name): 105 | use_skill.execute() 106 | for _ in range(2): 107 | time.sleep(0.3) 108 | trigger_qte_first.execute() 109 | trigger_qte_second.execute() 110 | auxiliary_machine.execute() 111 | else: 112 | ball_elimination.execute() 113 | time.sleep(0.1) 114 | ball_elimination.execute() 115 | if not CombatActions.check_status( 116 | context, "检查残月值_终焉", self._role_name 117 | ): 118 | long_press_attack.execute() 119 | if CombatActions.check_Skill_energy_bar(context, self._role_name): 120 | use_skill.execute() 121 | for _ in range(2): 122 | time.sleep(0.3) 123 | trigger_qte_first.execute() 124 | trigger_qte_second.execute() 125 | auxiliary_machine.execute() 126 | 127 | return CustomAction.RunResult(success=True) 128 | except Exception as e: 129 | logging.getLogger(f"{self._role_name}_Job").exception(str(e)) 130 | return CustomAction.RunResult(success=False) 131 | -------------------------------------------------------------------------------- /assets/custom/action/exclusives/Shukra.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 启明战斗程序 24 | 作者:overflow65537 25 | """ 26 | 27 | import logging 28 | import time 29 | 30 | from custom.action.basics import CombatActions 31 | from custom.action.tool import JobExecutor 32 | from custom.action.tool.Enum import GameActionEnum 33 | from custom.action.tool.LoadSetting import ROLE_ACTIONS 34 | 35 | from maa.context import Context 36 | from maa.custom_action import CustomAction 37 | 38 | 39 | class Shukra(CustomAction): 40 | """ 41 | 启明战斗逻辑 42 | 检查是否存在大招 43 | 释放大招 44 | 检查信号球数量信号球数量大于9 45 | 7秒内循环 46 | 识别信号球 47 | 消球 48 | 如果刚才的球是三消 49 | 再消球触发核心技能 50 | 如果没有球了 51 | 结束 52 | 结束后长按攻击尝试触发冰山 53 | 检查信号球数量信号球数量小于9 54 | 攻击攒球 55 | """ 56 | 57 | tempelate = { 58 | "red": {"识别信号球": {"template": ["信号球/启明_红.png"]}}, 59 | "blue": {"识别信号球": {"template": ["信号球/启明_蓝.png"]}}, 60 | "yellow": {"识别信号球": {"template": ["信号球/启明_黄.png"]}}, 61 | } 62 | 63 | def __init__(self): 64 | super().__init__() 65 | for name, action in ROLE_ACTIONS.items(): 66 | if action in self.__class__.__name__: 67 | self._role_name = name 68 | 69 | def run( 70 | self, context: Context, argv: CustomAction.RunArg 71 | ) -> CustomAction.RunResult: 72 | 73 | def get_ball_target(): 74 | return CombatActions.Arrange_Signal_Balls( 75 | context, 76 | "any", 77 | self.tempelate, 78 | ) 79 | 80 | try: 81 | lens_lock = JobExecutor( 82 | CombatActions.lens_lock(context), 83 | GameActionEnum.LENS_LOCK, 84 | role_name=self._role_name, 85 | ) 86 | attack = JobExecutor( 87 | CombatActions.attack(context), 88 | GameActionEnum.ATTACK, 89 | role_name=self._role_name, 90 | ) 91 | 92 | use_skill = JobExecutor( 93 | CombatActions.use_skill(context), 94 | GameActionEnum.USE_SKILL, 95 | role_name=self._role_name, 96 | ) 97 | long_press_attack = JobExecutor( 98 | CombatActions.long_press_attack(context, 3000), 99 | GameActionEnum.LONG_PRESS_ATTACK, 100 | role_name=self._role_name, 101 | ) 102 | lens_lock.execute() 103 | 104 | if CombatActions.check_Skill_energy_bar(context, self._role_name): 105 | use_skill.execute() # 万世生死,淬于寒冰 106 | start_time = time.time() 107 | while time.time() - start_time < 3: # 生死喧嚣,归于寂静 108 | time.sleep(0.1) 109 | CombatActions.ball_elimination_target(context, 1)() 110 | 111 | elif CombatActions.check_status( 112 | context, "检查信号球数量_启明", self._role_name 113 | ): # 信号球数量大于9 114 | start_time = time.time() 115 | while time.time() - start_time < 7: 116 | time.sleep(0.3) 117 | target = get_ball_target() 118 | CombatActions.ball_elimination_target(context, target)() 119 | print(f"初次消球") 120 | if target > 0: 121 | time.sleep(0.1) 122 | print(f"三连目标,开始二次消球") 123 | CombatActions.ball_elimination_target(context, 1)() # 单独消球 124 | elif target == 0: 125 | print(f"信号球空,结束") 126 | break 127 | print(f"长按攻击") 128 | long_press_attack.execute() 129 | else: 130 | print(f"普攻") 131 | start_time = time.time() 132 | while time.time() - start_time < 2: 133 | attack.execute() # 攻击 134 | time.sleep(0.1) 135 | return CustomAction.RunResult(success=True) 136 | except Exception as e: 137 | logging.getLogger(f"{self._role_name}_Job").exception(str(e)) 138 | return CustomAction.RunResult(success=False) 139 | -------------------------------------------------------------------------------- /assets/custom/action/exclusives/Stigmata.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 深痕战斗程序 24 | 作者:overflow65537,HCX0426 25 | """ 26 | 27 | 28 | import logging 29 | import sys 30 | import time 31 | from pathlib import Path 32 | 33 | from custom.action.basics import CombatActions 34 | from custom.action.tool import JobExecutor 35 | from custom.action.tool.Enum import GameActionEnum 36 | from custom.action.tool.LoadSetting import ROLE_ACTIONS 37 | 38 | from maa.context import Context 39 | from maa.custom_action import CustomAction 40 | 41 | 42 | class Stigmata(CustomAction): 43 | def __init__(self): 44 | super().__init__() 45 | for name, action in ROLE_ACTIONS.items(): 46 | if action in self.__class__.__name__: 47 | self._role_name = name 48 | 49 | def run( 50 | self, context: Context, argv: CustomAction.RunArg 51 | ) -> CustomAction.RunResult: 52 | try: 53 | lens_lock = JobExecutor( 54 | CombatActions.lens_lock(context), 55 | GameActionEnum.LENS_LOCK, 56 | role_name=self._role_name, 57 | ) 58 | attack = JobExecutor( 59 | CombatActions.attack(context), 60 | GameActionEnum.ATTACK, 61 | role_name=self._role_name, 62 | ) 63 | 64 | use_skill = JobExecutor( 65 | CombatActions.use_skill(context), 66 | GameActionEnum.USE_SKILL, 67 | role_name=self._role_name, 68 | ) 69 | long_press_attack = JobExecutor( 70 | CombatActions.long_press_attack(context, 3000), 71 | GameActionEnum.LONG_PRESS_ATTACK, 72 | role_name=self._role_name, 73 | ) 74 | long_press_dodge = JobExecutor( 75 | CombatActions.long_press_dodge(context), 76 | GameActionEnum.LONG_PRESS_DODGE, 77 | role_name=self._role_name, 78 | ) 79 | ball_elimination = JobExecutor( 80 | CombatActions.ball_elimination(context), 81 | GameActionEnum.BALL_ELIMINATION, 82 | role_name=self._role_name, 83 | ) 84 | 85 | trigger_qte_first = JobExecutor( 86 | CombatActions.trigger_qte_first(context), 87 | GameActionEnum.TRIGGER_QTE_FIRST, 88 | role_name=self._role_name, 89 | ) 90 | trigger_qte_second = JobExecutor( 91 | CombatActions.trigger_qte_second(context), 92 | GameActionEnum.TRIGGER_QTE_SECOND, 93 | role_name=self._role_name, 94 | ) 95 | auxiliary_machine = JobExecutor( 96 | CombatActions.auxiliary_machine(context), 97 | GameActionEnum.AUXILIARY_MACHINE, 98 | role_name=self._role_name, 99 | ) 100 | 101 | lens_lock.execute() 102 | if CombatActions.check_status( 103 | context, "检查比安卡·深痕一阶段", self._role_name 104 | ): 105 | if not CombatActions.check_status( 106 | context, "检查u1_深痕", self._role_name 107 | ): 108 | if CombatActions.check_status( 109 | context, "检查核心被动_深痕", self._role_name 110 | ): 111 | long_press_dodge.execute() # 开启照域 112 | start_time = time.time() 113 | while time.time() - start_time < 4: 114 | ball_elimination.execute() # 消球 115 | time.sleep(0.5) 116 | attack.execute() 117 | time.sleep(0.1) 118 | if CombatActions.check_Skill_energy_bar(context, self._role_name): 119 | if CombatActions.check_status(context, "检查u1_深痕", self._role_name): 120 | use_skill.execute() # 此刻,见证终焉之光 121 | time.sleep(1) 122 | if CombatActions.check_status(context, "检查u2_深痕", self._role_name): 123 | use_skill.execute() # 以此宣告,噩梦的崩解 124 | for _ in range(2): 125 | time.sleep(1.5) 126 | trigger_qte_first.execute() 127 | trigger_qte_second.execute() 128 | auxiliary_machine.execute() 129 | time.sleep(1.8) 130 | else: 131 | if not CombatActions.check_status( 132 | context, "检查u2数值_深痕", self._role_name 133 | ): # 残光值大于90 134 | start_time = time.time() 135 | while time.time() - start_time < 2: 136 | attack.execute() # 攻击 137 | time.sleep(0.1) 138 | long_press_attack.execute() # 长按攻击 139 | else: 140 | start_time = time.time() 141 | while time.time() - start_time < 2: 142 | attack.execute() # 攻击 143 | time.sleep(0.1) 144 | long_press_attack.execute() # 长按攻击 145 | 146 | return CustomAction.RunResult(success=True) 147 | except Exception as e: 148 | logging.getLogger(f"{self._role_name}_Job").exception(str(e)) 149 | return CustomAction.RunResult(success=False) 150 | -------------------------------------------------------------------------------- /assets/custom/action/setting.json: -------------------------------------------------------------------------------- 1 | { 2 | "ROLE_ACTIONS": { 3 | "露娜·终焉": "Oblivion", 4 | "比安卡·深痕": "Stigmata", 5 | "拉弥亚·深谣": "LostLullaby", 6 | "露西亚·深红囚影": "CrimsonWeave", 7 | "露西亚·誓焰": "Pyroath", 8 | "曲·启明": "Shukra" 9 | } 10 | } -------------------------------------------------------------------------------- /assets/custom/action/tool/Enum.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 战斗人物枚举对象 24 | 作者:HCX0426 25 | """ 26 | 27 | from enum import Enum 28 | 29 | 30 | class ActionStatusEnum(Enum): 31 | INVALID = "无效" 32 | PENDING = "待处理" 33 | RUNNING = "运行中" 34 | SUCCEEDED = "成功" 35 | FAILED = "失败" 36 | DONE = "完成" 37 | 38 | 39 | class GameActionEnum(Enum): 40 | ATTACK = "攻击" 41 | DODGE = "闪避" 42 | USE_SKILL = "技能" 43 | BALL_ELIMINATION = "消球" 44 | BALL_ELIMINATION_SECOND = "消球2" 45 | BALL_ELIMINATION_THREE = "消球3" 46 | TRIGGER_QTE_FIRST = "1-触发QTE/换人" 47 | TRIGGER_QTE_SECOND = "2-触发QTE/换人" 48 | LONG_PRESS_ATTACK = "长按攻击" 49 | LONG_PRESS_DODGE = "长按闪避" 50 | LONG_PRESS_SKILL = "长按技能" 51 | LENS_LOCK = "镜头锁定" 52 | AUXILIARY_MACHINE = "辅助机" 53 | -------------------------------------------------------------------------------- /assets/custom/action/tool/LoadSetting.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 角色配置载入 24 | 作者:HCX0426 25 | """ 26 | 27 | import json 28 | import os 29 | import sys 30 | from pathlib import Path 31 | 32 | # 获取当前文件的绝对路径 33 | current_file = Path(__file__).resolve() 34 | 35 | # 定义可能的项目根目录相对路径 36 | root_paths = [ 37 | current_file.parent.parent.parent.parent.joinpath("MFW_resource"), 38 | current_file.parent.parent.parent.parent.parent.parent.joinpath("Bundles").joinpath( 39 | "MAA_Punish" 40 | ), 41 | current_file.parent.parent.parent.parent.parent.joinpath("assets"), 42 | ] 43 | 44 | # 确定项目根目录 45 | project_root = next((path for path in root_paths if path.exists()), None) 46 | if project_root: 47 | if project_root == current_file.parent.parent.parent.parent.joinpath( 48 | "MFW_resource" 49 | ): 50 | project_root = current_file.parent.parent.parent.parent 51 | print(f"项目根目录: {project_root}") 52 | 53 | # 添加项目根目录到sys.path 54 | sys.path.append(str(project_root)) 55 | 56 | 57 | class LoadSetting: 58 | def __init__(self): 59 | self._role_actions = self.load_role_setting() 60 | 61 | @property 62 | def role_actions(self): 63 | return self._role_actions 64 | 65 | @staticmethod 66 | def load_role_setting(): 67 | try: 68 | with open( 69 | os.path.join(os.path.dirname(__file__), "..", "setting.json"), 70 | "r", 71 | encoding="utf-8", 72 | ) as file: 73 | return json.load(file).get("ROLE_ACTIONS", {}) 74 | except FileNotFoundError: 75 | with open("setting.json", "r", encoding="utf-8") as file: 76 | return json.load(file).get("ROLE_ACTIONS", {}) 77 | except json.JSONDecodeError: 78 | print("setting.json 文件格式错误。") 79 | return {} 80 | 81 | 82 | # 角色名称到动作的映射表 83 | ROLE_ACTIONS = LoadSetting.load_role_setting() 84 | -------------------------------------------------------------------------------- /assets/custom/action/tool/Logger.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 日志记录工具 24 | 作者:HCX0426 25 | """ 26 | 27 | import logging 28 | import os 29 | from logging.handlers import TimedRotatingFileHandler 30 | from typing import Any, Dict, Optional, Union 31 | 32 | 33 | class Logger: 34 | """ 35 | 通用日志记录类,支持日志轮转和保留指定天数内的日志 36 | 37 | Args: 38 | name: 日志记录器名称(默认"root") 39 | level: 全局日志级别(默认DEBUG) 40 | log_file: 日志文件路径(可选) 41 | log_format: 日志格式字符串(可选) 42 | console: 是否启用控制台输出(默认True) 43 | console_level: 控制台日志级别(可选,继承全局级别) 44 | file_level: 文件日志级别(可选,继承全局级别) 45 | backup_days: 保留日志文件的天数(默认3天) 46 | 47 | Example: 48 | >>> logger = Logger() 49 | >>> logger.info("Application started") 50 | """ 51 | 52 | # DEFAULT_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" 53 | DEFAULT_FORMAT = "%(asctime)s - %(levelname)s - %(message)s" 54 | 55 | def __init__( 56 | self, 57 | name: str = "root", 58 | level: Union[int, str] = logging.DEBUG, 59 | log_file: Optional[str] = None, 60 | log_format: Optional[str] = None, 61 | console: bool = True, 62 | console_level: Optional[Union[int, str]] = None, 63 | file_level: Optional[Union[int, str]] = None, 64 | backup_days: int = 3, 65 | ) -> None: 66 | self.logger = logging.getLogger(name) 67 | self.logger.setLevel(level) 68 | 69 | if self.logger.handlers: 70 | return 71 | 72 | formatter = logging.Formatter(log_format or self.DEFAULT_FORMAT) 73 | 74 | if console: 75 | self._add_stream_handler(formatter, console_level or level) 76 | 77 | if log_file: 78 | self._add_timed_rotating_file_handler( 79 | log_file, formatter, file_level or level, backup_days 80 | ) 81 | 82 | def _add_stream_handler( 83 | self, formatter: logging.Formatter, level: Union[int, str] 84 | ) -> None: 85 | """添加控制台日志处理器""" 86 | handler = logging.StreamHandler() 87 | handler.setLevel(level) 88 | handler.setFormatter(formatter) 89 | self.logger.addHandler(handler) 90 | 91 | def _add_timed_rotating_file_handler( 92 | self, 93 | file_path: str, 94 | formatter: logging.Formatter, 95 | level: Union[int, str], 96 | backup_days: int, 97 | ) -> None: 98 | """添加按时间轮转的文件日志处理器""" 99 | log_dir = os.path.dirname(file_path) 100 | if log_dir: 101 | os.makedirs(log_dir, exist_ok=True) 102 | 103 | handler = TimedRotatingFileHandler( 104 | filename=file_path, 105 | when="midnight", 106 | interval=1, 107 | backupCount=backup_days, 108 | encoding="utf-8", 109 | ) 110 | handler.setLevel(level) 111 | handler.setFormatter(formatter) 112 | self.logger.addHandler(handler) 113 | 114 | def debug(self, msg: str, **kwargs: Dict[str, Any]) -> None: 115 | """记录DEBUG级别日志""" 116 | self.logger.debug(msg, **kwargs) 117 | 118 | def info(self, msg: str, **kwargs: Dict[str, Any]) -> None: 119 | """记录INFO级别日志""" 120 | self.logger.info(msg, **kwargs) 121 | 122 | def warning(self, msg: str, **kwargs: Dict[str, Any]) -> None: 123 | """记录WARNING级别日志""" 124 | self.logger.warning(msg, **kwargs) 125 | 126 | def error(self, msg: str, **kwargs: Dict[str, Any]) -> None: 127 | """记录ERROR级别日志""" 128 | self.logger.error(msg, **kwargs) 129 | 130 | def exception(self, msg: str, **kwargs: Dict[str, Any]) -> None: 131 | """ 132 | 记录EXCEPTION级别日志 133 | 自动添加异常信息,应在except块中使用 134 | """ 135 | self.logger.exception(msg, **kwargs) 136 | 137 | def critical(self, msg: str, **kwargs: Dict[str, Any]) -> None: 138 | """记录CRITICAL级别日志""" 139 | self.logger.critical(msg, **kwargs) 140 | 141 | @property 142 | def handlers(self) -> list[logging.Handler]: 143 | """获取所有日志处理器""" 144 | return self.logger.handlers 145 | 146 | def add_handler(self, handler: logging.Handler) -> None: 147 | """添加自定义日志处理器""" 148 | self.logger.addHandler(handler) 149 | 150 | def set_level(self, level: Union[int, str]) -> None: 151 | """设置全局日志级别""" 152 | self.logger.setLevel(level) 153 | -------------------------------------------------------------------------------- /assets/custom/action/tool/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .LoadSetting import LoadSetting 3 | from .Enum import ActionStatusEnum,GameActionEnum 4 | from .JobExecutor import JobExecutor 5 | from .Logger import Logger 6 | 7 | __all__ = ['LoadSetting','ActionStatusEnum','GameActionEnum','JobExecutor','Logger'] # 可选,明确导出的内容 -------------------------------------------------------------------------------- /assets/custom/action_log/.gitignore: -------------------------------------------------------------------------------- 1 | * -------------------------------------------------------------------------------- /assets/custom/agent_file.py: -------------------------------------------------------------------------------- 1 | from maa.agent.agent_server import AgentServer 2 | from action.basics.CenterCamera import CenterCamera 3 | from action.basics.CombatActions import CombatActions 4 | from action.basics.Identify import Identify 5 | from action.basics.IdentifyRoles import IdentifyRoles 6 | from action.basics.MultiplayerAutoBattle import MultiplayerAutoBattle 7 | from action.basics.ResetIdentify import ResetIdentify 8 | from action.basics.ScreenShot import ScreenShot 9 | from action.basics.SetTower import SetTower 10 | from action.basics.Count import Count 11 | from action.basics.PPOverride import PPOverride 12 | from action.basics.ChainLoopCircuit import ChainLoopCircuit 13 | 14 | 15 | from action.exclusives.CrimsonWeave import CrimsonWeave 16 | from action.exclusives.LostLullaby import LostLullaby 17 | from action.exclusives.Oblivion import Oblivion 18 | from action.exclusives.Pyroath import Pyroath 19 | from action.exclusives.Stigmata import Stigmata 20 | from action.exclusives.Shukra import Shukra 21 | 22 | 23 | from recognition.exclusives.CalculateScore import CalculateScore 24 | from recognition.exclusives.IDFMembers import IDFMembers 25 | from recognition.exclusives.IDFscore import IDFscore 26 | from recognition.exclusives.IDFMasteryLevel import IDFMasteryLevel 27 | from recognition.exclusives.LogicalOperators import LOp 28 | 29 | 30 | @AgentServer.custom_recognition("LOp") 31 | class Agent_LOp(LOp): 32 | pass 33 | 34 | 35 | @AgentServer.custom_action("ChainLoopCircuit") 36 | class Agent_ChainLoopCircuit(ChainLoopCircuit): 37 | pass 38 | 39 | 40 | @AgentServer.custom_action("Shukra") 41 | class Agent_Shukra(Shukra): 42 | pass 43 | 44 | 45 | @AgentServer.custom_action("PPOverride") 46 | class Agent_PPOverride(PPOverride): 47 | pass 48 | 49 | 50 | @AgentServer.custom_action("Count") 51 | class Agent_Count(Count): 52 | pass 53 | 54 | 55 | @AgentServer.custom_recognition("IDFMasteryLevel") 56 | class Agent_IDFMasteryLevel(IDFMasteryLevel): 57 | pass 58 | 59 | 60 | @AgentServer.custom_action("SetTower") 61 | class Agent_SetTower(SetTower): 62 | pass 63 | 64 | 65 | @AgentServer.custom_action("CenterCamera") 66 | class Agent_CenterCamera(CenterCamera): 67 | pass 68 | 69 | 70 | @AgentServer.custom_action("CombatActions") 71 | class Agent_CombatActions(CombatActions): 72 | pass 73 | 74 | 75 | @AgentServer.custom_action("Identify") 76 | class Agent_Identify(Identify): 77 | pass 78 | 79 | 80 | @AgentServer.custom_action("IdentifyRoles") 81 | class Agent_IdentifyRoles(IdentifyRoles): 82 | pass 83 | 84 | 85 | @AgentServer.custom_action("MultiplayerAutoBattle") 86 | class Agent_MultiplayerAutoBattle(MultiplayerAutoBattle): 87 | pass 88 | 89 | 90 | @AgentServer.custom_action("ResetIdentify") 91 | class Agent_ResetIdentify(ResetIdentify): 92 | pass 93 | 94 | 95 | @AgentServer.custom_action("ScreenShot") 96 | class Agent_ScreenShot(ScreenShot): 97 | pass 98 | 99 | 100 | @AgentServer.custom_recognition("CalculateScore") 101 | class Agent_CalculateScore(CalculateScore): 102 | pass 103 | 104 | 105 | @AgentServer.custom_recognition("IDFMembers") 106 | class Agent_IDFMembers(IDFMembers): 107 | pass 108 | 109 | 110 | @AgentServer.custom_recognition("IDFscore") 111 | class Agent_IDFscore(IDFscore): 112 | pass 113 | 114 | 115 | @AgentServer.custom_action("CrimsonWeave") 116 | class Agent_CrimsonWeave(CrimsonWeave): 117 | pass 118 | 119 | 120 | @AgentServer.custom_action("LostLullaby") 121 | class Agent_LostLullaby(LostLullaby): 122 | pass 123 | 124 | 125 | @AgentServer.custom_action("Oblivion") 126 | class Agent_Oblivion(Oblivion): 127 | pass 128 | 129 | 130 | @AgentServer.custom_action("Pyroath") 131 | class Agent_Pyroath(Pyroath): 132 | pass 133 | 134 | 135 | @AgentServer.custom_action("Stigmata") 136 | class Agent_Stigmata(Stigmata): 137 | pass 138 | -------------------------------------------------------------------------------- /assets/custom/custom.json: -------------------------------------------------------------------------------- 1 | { 2 | "CenterCamera": { 3 | "type": "action", 4 | "class": "CenterCamera", 5 | "file_path": "{custom_path}/action/basics/CenterCamera.py" 6 | }, 7 | "Identify": { 8 | "type": "action", 9 | "class": "Identify", 10 | "file_path": "{custom_path}/action/basics/Identify.py" 11 | }, 12 | "ResetIdentify": { 13 | "type": "action", 14 | "class": "ResetIdentify", 15 | "file_path": "{custom_path}/action/basics/ResetIdentify.py" 16 | }, 17 | "ScreenShot": { 18 | "type": "action", 19 | "class": "ScreenShot", 20 | "file_path": "{custom_path}/action/basics/ScreenShot.py" 21 | }, 22 | "CalculateScore": { 23 | "type": "recognition", 24 | "class": "CalculateScore", 25 | "file_path": "{custom_path}/recognition/exclusives/CalculateScore.py" 26 | }, 27 | "IDFMembers": { 28 | "type": "recognition", 29 | "class": "IDFMembers", 30 | "file_path": "{custom_path}/recognition/exclusives/IDFMembers.py" 31 | }, 32 | "IDFscore": { 33 | "type": "recognition", 34 | "class": "IDFscore", 35 | "file_path": "{custom_path}/recognition/exclusives/IDFscore.py" 36 | }, 37 | "LOp": { 38 | "type": "recognition", 39 | "class": "LOp", 40 | "file_path": "{custom_path}/recognition/exclusives/LogicalOperators.py" 41 | }, 42 | "IdentifyRoles": { 43 | "type": "action", 44 | "class": "IdentifyRoles", 45 | "file_path": "{custom_path}/action/basics/IdentifyRoles.py" 46 | }, 47 | "CombatActions": { 48 | "type": "action", 49 | "class": "CombatActions", 50 | "file_path": "{custom_path}/action/basics/CombatActions.py" 51 | }, 52 | "IDFMasteryLevel": { 53 | "type": "recognition", 54 | "class": "IDFMasteryLevel", 55 | "file_path": "{custom_path}/recognition/exclusives/IDFMasteryLevel.py" 56 | }, 57 | "MultiplayerAutoBattle": { 58 | "type": "action", 59 | "class": "MultiplayerAutoBattle", 60 | "file_path": "{custom_path}/action/basics/MultiplayerAutoBattle.py" 61 | }, 62 | "Count": { 63 | "type": "action", 64 | "class": "Count", 65 | "file_path": "{custom_path}/action/basics/Count.py" 66 | }, 67 | "PPOverride": { 68 | "type": "action", 69 | "class": "PPOverride", 70 | "file_path": "{custom_path}/action/basics/PPOverride.py" 71 | }, 72 | "ChainLoopCircuit": { 73 | "type": "action", 74 | "class": "ChainLoopCircuit", 75 | "file_path": "{custom_path}/action/basics/ChainLoopCircuit.py" 76 | }, 77 | "Stigmata": { 78 | "type": "action", 79 | "class": "Stigmata", 80 | "file_path": "{custom_path}/action/exclusives/Stigmata.py" 81 | }, 82 | "CrimsonWeave": { 83 | "type": "action", 84 | "class": "CrimsonWeave", 85 | "file_path": "{custom_path}/action/exclusives/CrimsonWeave.py" 86 | }, 87 | "LostLullaby": { 88 | "type": "action", 89 | "class": "LostLullaby", 90 | "file_path": "{custom_path}/action/exclusives/LostLullaby.py" 91 | }, 92 | "Oblivion": { 93 | "type": "action", 94 | "class": "Oblivion", 95 | "file_path": "{custom_path}/action/exclusives/Oblivion.py" 96 | }, 97 | "Pyroath": { 98 | "type": "action", 99 | "class": "Pyroath", 100 | "file_path": "{custom_path}/action/exclusives/Pyroath.py" 101 | }, 102 | "Shukra": { 103 | "type": "action", 104 | "class": "Shukra", 105 | "file_path": "{custom_path}/action/exclusives/Shukra.py" 106 | } 107 | } -------------------------------------------------------------------------------- /assets/custom/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from maa.agent.agent_server import AgentServer 3 | from maa.toolkit import Toolkit 4 | 5 | from agent_file import * 6 | 7 | 8 | def main(): 9 | Toolkit.init_option("./") 10 | if len(sys.argv) > 1: 11 | print("使用自定义socket_id: " + sys.argv[-1]) 12 | socket_id = sys.argv[-1] 13 | else: 14 | print("使用默认socket_id" \ 15 | ": MAA_AGENT_SOCKET") 16 | socket_id = "MAA_AGENT_SOCKET" 17 | AgentServer.start_up(socket_id) 18 | AgentServer.join() 19 | AgentServer.shut_down() 20 | 21 | 22 | if __name__ == "__main__": 23 | main() 24 | -------------------------------------------------------------------------------- /assets/custom/recognition/exclusives/CalculateScore.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 肉鸽4分数计算 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_recognition import CustomRecognition 29 | 30 | 31 | class CalculateScore(CustomRecognition): 32 | 33 | def analyze( 34 | self, 35 | context, 36 | argv: CustomRecognition.AnalyzeArg, 37 | ) -> CustomRecognition.AnalyzeResult: 38 | image = context.tasker.controller.post_screencap().wait().get() 39 | # 检查目标分数 40 | target_score = context.run_recognition("检查目标分数", image) 41 | # 检查当前分数 42 | current_score = context.run_recognition("检查当前分数", image) 43 | 44 | # 检查军事分数及倍率 45 | military_score = context.run_recognition( 46 | "检查分数", image, {"检查分数": {"roi": [90, 238, 105, 44]}} 47 | ) 48 | military_multiplier = context.run_recognition( 49 | "检查分数", image, {"检查分数": {"roi": [197, 239, 54, 48], "expected": ""}} 50 | ) 51 | 52 | # 检查经济分数及倍率 53 | economic_score = context.run_recognition( 54 | "检查分数", image, {"检查分数": {"roi": [90, 327, 105, 44]}} 55 | ) 56 | economic_multiplier = context.run_recognition( 57 | "检查分数", image, {"检查分数": {"roi": [193, 323, 61, 52], "expected": ""}} 58 | ) 59 | 60 | # 检查科研分数及倍率 61 | research_score = context.run_recognition( 62 | "检查分数", image, {"检查分数": {"roi": [90, 412, 107, 46]}} 63 | ) 64 | research_multiplier = context.run_recognition( 65 | "检查分数", image, {"检查分数": {"roi": [196, 416, 61, 43], "expected": ""}} 66 | ) 67 | 68 | if None in [ 69 | current_score, 70 | target_score, 71 | military_score, 72 | military_multiplier, 73 | economic_score, 74 | economic_multiplier, 75 | research_score, 76 | research_multiplier, 77 | ]: 78 | return 79 | 80 | if ( 81 | current_score.best_result.text.isdigit() 82 | and target_score.best_result.text.isdigit() 83 | and military_score.best_result.text.isdigit() 84 | and military_multiplier.best_result.text[1:].isdigit() 85 | and economic_score.best_result.text.isdigit() 86 | and economic_multiplier.best_result.text[1:].isdigit() 87 | and research_score.best_result.text.isdigit() 88 | and research_multiplier.best_result.text[1:].isdigit() 89 | ): 90 | final_score = ( 91 | int(military_score.best_result.text) 92 | * int(military_multiplier.best_result.text[1:]) 93 | + int(economic_score.best_result.text) 94 | * int(economic_multiplier.best_result.text[1:]) 95 | + int(research_score.best_result.text) 96 | * int(research_multiplier.best_result.text[1:]) 97 | + int(current_score.best_result.text) 98 | ) 99 | print(final_score) 100 | if final_score >= int(target_score.best_result.text): 101 | return CustomRecognition.AnalyzeResult( 102 | box=(0, 0, 100, 100), detail="success" 103 | ) 104 | else: 105 | return 106 | -------------------------------------------------------------------------------- /assets/custom/recognition/exclusives/IDFMasteryLevel.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 特殊识别器,识别精通等级 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_recognition import CustomRecognition 29 | 30 | 31 | class IDFMasteryLevel(CustomRecognition): 32 | 33 | def analyze( 34 | self, 35 | context, 36 | argv: CustomRecognition.AnalyzeArg, 37 | ) -> CustomRecognition.AnalyzeResult: 38 | result = context.run_recognition( 39 | "选择自动作战人物_矩阵循生", 40 | argv.image, 41 | { 42 | "选择自动作战人物_矩阵循生": { 43 | "template": [ 44 | "肉鸽通用/誓焰终解_矩阵.png", 45 | "肉鸽通用/誓焰_矩阵.png", 46 | "肉鸽通用/誓焰花嫁_矩阵.png", 47 | "肉鸽通用/深红囚影终解_矩阵.png", 48 | "肉鸽通用/深红囚影_矩阵.png", 49 | "肉鸽通用/深谣终解_矩阵.png", 50 | "肉鸽通用/深谣_矩阵.png", 51 | "肉鸽通用/终焉终解_矩阵.png", 52 | "肉鸽通用/终焉_矩阵.png", 53 | "肉鸽通用/深痕终解_矩阵.png", 54 | "肉鸽通用/深痕_矩阵.png", 55 | ], 56 | "threshold": [ 57 | 0.9, 58 | 0.9, 59 | 0.9, 60 | 0.9, 61 | 0.9, 62 | 0.9, 63 | 0.9, 64 | 0.9, 65 | 0.9, 66 | 0.9, 67 | 0.9, 68 | ], 69 | } 70 | }, 71 | ) 72 | if result: 73 | for i in result.filterd_results: 74 | if context.run_recognition( 75 | "识别精通等级", 76 | argv.image, 77 | { 78 | "识别精通等级": { 79 | "roi": i.box, 80 | "roi_offset": [189, 25, -51, -45], 81 | } 82 | }, 83 | ): 84 | context.override_pipeline( 85 | { 86 | "战斗事件_矩阵循生": { 87 | "interrupt": [ 88 | "识别人物", 89 | "重启_寒境曙光", 90 | "战斗中", 91 | "出击_矩阵循生", 92 | "跳过战斗对话", 93 | "进入战斗_矩阵循生", 94 | "载入中", 95 | ] 96 | }, 97 | "识别人物": {"enabled": True}, 98 | } 99 | ) 100 | print("IDFMasteryLevel success") 101 | return CustomRecognition.AnalyzeResult(box=i.box, detail="success") 102 | print("IDFMasteryLevel failed") 103 | return 104 | -------------------------------------------------------------------------------- /assets/custom/recognition/exclusives/IDFMembers.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 识别宿舍角色数量 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_recognition import CustomRecognition 29 | 30 | 31 | class IDFMembers(CustomRecognition): 32 | 33 | def analyze( 34 | self, 35 | context, 36 | argv: CustomRecognition.AnalyzeArg, 37 | ) -> CustomRecognition.AnalyzeResult: 38 | image = context.tasker.controller.post_screencap().wait().get() 39 | # 检查目标数量 40 | target_score = context.run_recognition("检查目标数量", image) 41 | # 检查当前数量 42 | current_score = context.run_recognition("检查当前数量", image) 43 | if current_score is None or target_score is None: 44 | return 45 | if ( 46 | current_score.best_result.text.isdigit() 47 | and target_score.best_result.text.isdigit() 48 | ): 49 | 50 | if int(current_score.best_result.text) == int( 51 | target_score.best_result.text 52 | ): 53 | return CustomRecognition.AnalyzeResult( 54 | box=(0, 0, 100, 100), detail="success" 55 | ) 56 | else: 57 | return 58 | -------------------------------------------------------------------------------- /assets/custom/recognition/exclusives/IDFscore.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 肉鸽4分数识别 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_recognition import CustomRecognition 29 | 30 | 31 | class IDFscore(CustomRecognition): 32 | 33 | def analyze( 34 | self, 35 | context, 36 | argv: CustomRecognition.AnalyzeArg, 37 | ) -> CustomRecognition.AnalyzeResult: 38 | image = context.tasker.controller.post_screencap().wait().get() 39 | # 检查目标分数 40 | context.run_recognition("检查目标分数区域", image) 41 | target_score = context.run_recognition("检查目标分数", image) 42 | # 检查当前分数 43 | context.run_recognition("检查当前分数区域", image) 44 | current_score = context.run_recognition("检查当前分数", image) 45 | if current_score is None or target_score is None: 46 | return 47 | if ( 48 | current_score.best_result.text.isdigit() 49 | and target_score.best_result.text.isdigit() 50 | ): 51 | 52 | if int(current_score.best_result.text) >= int( 53 | target_score.best_result.text 54 | ): 55 | return CustomRecognition.AnalyzeResult( 56 | box=(0, 0, 100, 100), 57 | detail=f"{current_score.best_result.text}>={target_score.best_result.text}", 58 | ) 59 | else: 60 | return 61 | -------------------------------------------------------------------------------- /assets/custom/recognition/exclusives/LogicalOperators.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024-2025 MAA_Punish 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the "Software"), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | """ 22 | MAA_Punish 23 | MAA_Punish 逻辑识别器 24 | 作者:overflow65537 25 | """ 26 | 27 | from maa.context import Context 28 | from maa.custom_recognition import CustomRecognition 29 | import json 30 | 31 | 32 | class LOp(CustomRecognition): 33 | def analyze( 34 | self, 35 | context: Context, 36 | argv: CustomRecognition.AnalyzeArg, 37 | ) -> CustomRecognition.AnalyzeResult|None: 38 | """ 39 | 逻辑识别器: 40 | custom_recognition_param: 41 | {"prestep": ["node1", "node2"], 42 | "mode": and, 43 | "nodes": ["node3", ["node4"]], 44 | } 45 | prestep: 前置识别节点,如果识别中需要前置识别进行坐标或者识别区偏移等操作,可以使用该参数 46 | mode: 模式 and 或者 or,默认为and 47 | nodes: 需要识别的节点,使用列表括起来为反转识别结果 48 | """ 49 | image = argv.image 50 | param: dict = json.loads(argv.custom_recognition_param) 51 | mode: str = param.get("mode", "and") 52 | nodes: list = param.get("nodes", []) 53 | 54 | for prestep in param.get("prestep", []): 55 | result = context.run_recognition(prestep, image) 56 | 57 | if mode.lower() == "and": 58 | for item in nodes: 59 | result = self._eval_node(item, context, image) 60 | if not result: 61 | return 62 | return CustomRecognition.AnalyzeResult( 63 | box=(0, 0, 100, 100), detail=f"{nodes} used in {mode} success" 64 | ) 65 | 66 | elif mode.lower() == "or": 67 | for item in nodes: 68 | result = self._eval_node(item, context, image) 69 | if result: 70 | return CustomRecognition.AnalyzeResult( 71 | box=(0, 0, 100, 100), detail=f"{nodes} used in {mode} success" 72 | ) 73 | return 74 | 75 | else: 76 | return 77 | 78 | def _eval_node(self, node, context: Context, image) -> bool|None: 79 | 80 | if isinstance(node, str): 81 | return bool(context.run_recognition(node, image)) 82 | 83 | elif isinstance(node, list) and len(node) == 1: 84 | inner_node = node[0] 85 | return not bool(context.run_recognition(inner_node, image)) 86 | -------------------------------------------------------------------------------- /assets/resource/4399/pipeline/4399.json: -------------------------------------------------------------------------------- 1 | { 2 | "打开应用": { 3 | "action": "StartApp", 4 | "package": "com.kurogame.haru.m4399" 5 | }, 6 | "停止": { 7 | "action": "StopApp", 8 | "package": "com.kurogame.haru.m4399" 9 | }, 10 | "重启游戏": { 11 | "action": "StopApp", 12 | "package": "com.kurogame.haru.m4399", 13 | "next": [ 14 | "启动" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /assets/resource/base/default_pipeline.json: -------------------------------------------------------------------------------- 1 | { 2 | "Default": { 3 | "on_error": [ 4 | "返回主菜单_err" 5 | ] 6 | } 7 | } -------------------------------------------------------------------------------- /assets/resource/base/image/任务/每日_32_293_208_40__0_243_308_140.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/任务/每日_32_293_208_40__0_243_308_140.png -------------------------------------------------------------------------------- /assets/resource/base/image/信号球/启明_红.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/信号球/启明_红.png -------------------------------------------------------------------------------- /assets/resource/base/image/信号球/启明_蓝.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/信号球/启明_蓝.png -------------------------------------------------------------------------------- /assets/resource/base/image/信号球/启明_黄.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/信号球/启明_黄.png -------------------------------------------------------------------------------- /assets/resource/base/image/厄愿潮声/BOSS战.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/厄愿潮声/BOSS战.png -------------------------------------------------------------------------------- /assets/resource/base/image/厄愿潮声/困难战斗.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/厄愿潮声/困难战斗.png -------------------------------------------------------------------------------- /assets/resource/base/image/厄愿潮声/战斗.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/厄愿潮声/战斗.png -------------------------------------------------------------------------------- /assets/resource/base/image/厄愿潮声/文字事件.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/厄愿潮声/文字事件.png -------------------------------------------------------------------------------- /assets/resource/base/image/厄愿潮声/特殊事件.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/厄愿潮声/特殊事件.png -------------------------------------------------------------------------------- /assets/resource/base/image/厄愿潮声/结束.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/厄愿潮声/结束.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_家园.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_家园.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_恋屿干年歌.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_恋屿干年歌.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_溺梦游歌.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_溺梦游歌.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_白梦游弋.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_白梦游弋.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_离诗遗城.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_离诗遗城.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_耀阳映画.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_耀阳映画.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_花溪憩乡.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_花溪憩乡.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_银光教堂.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_银光教堂.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_闲庭疏影.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_闲庭疏影.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_鸣神叹妙.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_鸣神叹妙.png -------------------------------------------------------------------------------- /assets/resource/base/image/启动/切换主界面状态_默认.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/启动/切换主界面状态_默认.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/休息中_1154_383_126_61__1054_333_226_161.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/休息中_1154_383_126_61__1054_333_226_161.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/委托存在_242_594_31_31__192_544_131_131.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/委托存在_242_594_31_31__192_544_131_131.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/宿舍任务_1181_82_55_55__1125_32_155_155.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/宿舍任务_1181_82_55_55__1125_32_155_155.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/宿舍商店内部.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/宿舍商店内部.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/开始制造.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/开始制造.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/打开执勤_1189_392_64_52__1116_342_164_152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/打开执勤_1189_392_64_52__1116_342_164_152.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/打开遣测商店.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/打开遣测商店.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/进入宿舍币商店.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/进入宿舍币商店.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/选择C级_1011_154_69_28__961_104_169_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/选择C级_1011_154_69_28__961_104_169_128.png -------------------------------------------------------------------------------- /assets/resource/base/image/宿舍委托/遣测商店内部.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/宿舍委托/遣测商店内部.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/分数区域.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/分数区域.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/启程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/启程.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/旧国遗产_决定.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/旧国遗产_决定.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/目标分数区域.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/目标分数区域.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/确认放塔.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/确认放塔.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/继续.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/继续.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/翻开区域_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/翻开区域_1.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/翻开区域_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/翻开区域_2.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/翻开区域_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/翻开区域_3.png -------------------------------------------------------------------------------- /assets/resource/base/image/寒境曙光/翻开区域_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/寒境曙光/翻开区域_4.png -------------------------------------------------------------------------------- /assets/resource/base/image/幻痛囚笼/关闭奖励.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/幻痛囚笼/关闭奖励.png -------------------------------------------------------------------------------- /assets/resource/base/image/幻痛囚笼/等级地狱.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/幻痛囚笼/等级地狱.png -------------------------------------------------------------------------------- /assets/resource/base/image/幻痛囚笼/队伍净空_红.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/幻痛囚笼/队伍净空_红.png -------------------------------------------------------------------------------- /assets/resource/base/image/幻痛囚笼/队伍净空_蓝黄.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/幻痛囚笼/队伍净空_蓝黄.png -------------------------------------------------------------------------------- /assets/resource/base/image/战斗/使用体力界面_416_207_91_95__366_157_191_195.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/战斗/使用体力界面_416_207_91_95__366_157_191_195.png -------------------------------------------------------------------------------- /assets/resource/base/image/战斗/吃体力药_993_21_30_30__943_0_130_130.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/战斗/吃体力药_993_21_30_30__943_0_130_130.png -------------------------------------------------------------------------------- /assets/resource/base/image/战斗/闪避.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/战斗/闪避.png -------------------------------------------------------------------------------- /assets/resource/base/image/指挥局/拟真围剿入口.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/指挥局/拟真围剿入口.png -------------------------------------------------------------------------------- /assets/resource/base/image/指挥局/返回.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/指挥局/返回.png -------------------------------------------------------------------------------- /assets/resource/base/image/矩阵循生/BOSS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/矩阵循生/BOSS.png -------------------------------------------------------------------------------- /assets/resource/base/image/矩阵循生/对话事件.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/矩阵循生/对话事件.png -------------------------------------------------------------------------------- /assets/resource/base/image/矩阵循生/对话事件1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/矩阵循生/对话事件1.png -------------------------------------------------------------------------------- /assets/resource/base/image/矩阵循生/战斗地块.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/矩阵循生/战斗地块.png -------------------------------------------------------------------------------- /assets/resource/base/image/矩阵循生/转换层级.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/矩阵循生/转换层级.png -------------------------------------------------------------------------------- /assets/resource/base/image/纷争战区/作战开始_未选人.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/纷争战区/作战开始_未选人.png -------------------------------------------------------------------------------- /assets/resource/base/image/纷争战区/关闭队长选择界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/纷争战区/关闭队长选择界面.png -------------------------------------------------------------------------------- /assets/resource/base/image/纷争战区/选择首发.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/纷争战区/选择首发.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/作战开始.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/作战开始.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/启明.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/启明.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/启明_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/启明_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/启明终解.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/启明终解.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/启明终解_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/启明终解_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深痕.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深痕.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深痕_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深痕_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深痕终解.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深痕终解.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深痕终解_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深痕终解_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深红囚影.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深红囚影.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深红囚影_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深红囚影_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深红囚影终解.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深红囚影终解.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深红囚影终解_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深红囚影终解_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深谣.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深谣.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深谣_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深谣_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深谣终解.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深谣终解.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/深谣终解_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/深谣终解_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/终焉.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/终焉.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/终焉_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/终焉_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/终焉终解.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/终焉终解.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/终焉终解_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/终焉终解_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/誓焰.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/誓焰.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/誓焰_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/誓焰_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/誓焰终解.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/誓焰终解.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/誓焰终解_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/誓焰终解_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/肉鸽通用/誓焰花嫁_矩阵.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/肉鸽通用/誓焰花嫁_矩阵.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/启明.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/启明.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深痕.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深痕.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深痕_u1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深痕_u1.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深痕_u2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深痕_u2.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深痕a2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深痕a2.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深红囚影.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深红囚影.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深红囚影_u1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深红囚影_u1.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深红囚影_u2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深红囚影_u2.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深红囚影_红球.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深红囚影_红球.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深红囚影_蓝球.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深红囚影_蓝球.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深红囚影_黄球.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深红囚影_黄球.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深谣_p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深谣_p1.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深谣_p2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深谣_p2.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深谣_u1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深谣_u1.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深谣_u2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深谣_u2.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深谣_核心被动1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深谣_核心被动1.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/深谣_核心被动2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/深谣_核心被动2.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/终焉.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/终焉.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/终焉_满.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/终焉_满.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/终焉_满2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/终焉_满2.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/誓焰.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/誓焰.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/誓焰_u1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/誓焰_u1.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/誓焰_u2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/誓焰_u2.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/誓焰_u2max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/誓焰_u2max.png -------------------------------------------------------------------------------- /assets/resource/base/image/自定义战斗/誓焰_u3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/自定义战斗/誓焰_u3.png -------------------------------------------------------------------------------- /assets/resource/base/image/购买碎片/关闭_1195_30_61_61__1119_0_161_161.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/购买碎片/关闭_1195_30_61_61__1119_0_161_161.png -------------------------------------------------------------------------------- /assets/resource/base/image/通用任务/105157_624_220_86_57__574_170_186_157.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通用任务/105157_624_220_86_57__574_170_186_157.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_家园.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_家园.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_恋屿干年歌.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_恋屿干年歌.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_溺梦游歌.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_溺梦游歌.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_白梦游弋.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_白梦游弋.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_离诗遗城.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_离诗遗城.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_耀阳映画.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_耀阳映画.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_花溪憩乡.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_花溪憩乡.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_银光教堂.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_银光教堂.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_闲庭疏影.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_闲庭疏影.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_鸣神叹妙.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_鸣神叹妙.png -------------------------------------------------------------------------------- /assets/resource/base/image/通行证/通行证_默认.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/通行证/通行证_默认.png -------------------------------------------------------------------------------- /assets/resource/base/image/链合回路/技能_快枪.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/链合回路/技能_快枪.png -------------------------------------------------------------------------------- /assets/resource/base/image/链合回路/技能_爆破.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/链合回路/技能_爆破.png -------------------------------------------------------------------------------- /assets/resource/base/image/链合回路/技能_纵斩.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/链合回路/技能_纵斩.png -------------------------------------------------------------------------------- /assets/resource/base/image/链合回路/技能_闪星.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/链合回路/技能_闪星.png -------------------------------------------------------------------------------- /assets/resource/base/image/领取体力/点击日常补给包_21_248_127_45__0_198_227_145.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/领取体力/点击日常补给包_21_248_127_45__0_198_227_145.png -------------------------------------------------------------------------------- /assets/resource/base/image/领取体力/点击补给包_488_87_117_35__438_37_217_135.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/assets/resource/base/image/领取体力/点击补给包_488_87_117_35__438_37_217_135.png -------------------------------------------------------------------------------- /assets/resource/base/model/.gitignore: -------------------------------------------------------------------------------- 1 | ocr -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Auto_Battle/Auto_Battle.json: -------------------------------------------------------------------------------- 1 | { 2 | "主线自动战斗": { 3 | "timeout": 3000000, 4 | "next": [ 5 | "循环执行器" 6 | ], 7 | "interrupt": [ 8 | "进入战斗", 9 | "进入战斗_条件2", 10 | "跳过战斗对话", 11 | "战斗重启1", 12 | "跳过剧情", 13 | "载入中", 14 | "主线跳过", 15 | "重置识别" 16 | ] 17 | }, 18 | "战斗重启1": { 19 | "recognition": "OCR", 20 | "roi": [ 21 | 820, 22 | 266, 23 | 73, 24 | 53 25 | ], 26 | "expected": [ 27 | "重启" 28 | ], 29 | "action": "Click" 30 | }, 31 | "对话跳过": { 32 | "only_rec": true, 33 | "recognition": "OCR", 34 | "roi": [ 35 | 787, 36 | 595, 37 | 50, 38 | 32 39 | ], 40 | "expected": [ 41 | "跳过" 42 | ], 43 | "action": "Click" 44 | }, 45 | "进入战斗_条件2": { 46 | "post_delay": 0, 47 | "pre_delay": 0, 48 | "recognition": "OCR", 49 | "roi": [ 50 | 14, 51 | 82, 52 | 214, 53 | 67 54 | ], 55 | "expected": [ 56 | "^击败.*", 57 | "^消灭.*", 58 | "^清理.*" 59 | ], 60 | "next": [ 61 | "识别人物", 62 | "战斗中", 63 | "空任务" 64 | ] 65 | }, 66 | "进入战斗": { 67 | "post_delay": 0, 68 | "pre_delay": 0, 69 | "recognition": "ColorMatch", 70 | "roi": [ 71 | 403, 72 | 51, 73 | 472, 74 | 7 75 | ], 76 | "upper": [ 77 | 255, 78 | 255, 79 | 255 80 | ], 81 | "lower": [ 82 | 255, 83 | 255, 84 | 255 85 | ], 86 | "connected": true, 87 | "next": [ 88 | "识别人物", 89 | "战斗中", 90 | "空任务" 91 | ] 92 | }, 93 | "重置识别": { 94 | "post_delay": 1000, 95 | "action": "Custom", 96 | "custom_action": "ResetIdentify" 97 | }, 98 | "主线跳过": { 99 | "recognition": "OCR", 100 | "roi": [ 101 | 1197, 102 | 124, 103 | 47, 104 | 25 105 | ], 106 | "expected": [ 107 | "SKIP" 108 | ], 109 | "action": "Click" 110 | }, 111 | "循环执行器": { 112 | "inverse": true 113 | }, 114 | "识别人物": { 115 | "green_mask": true, 116 | "recognition": "TemplateMatch", 117 | "roi": [ 118 | 990, 119 | 567, 120 | 131, 121 | 131 122 | ], 123 | "template": "战斗/闪避.png", 124 | "action": "Custom", 125 | "custom_action": "Identify" 126 | }, 127 | "战斗测试": { 128 | "green_mask": true, 129 | "recognition": "TemplateMatch", 130 | "roi": [ 131 | 990, 132 | 567, 133 | 131, 134 | 131 135 | ], 136 | "template": "战斗/闪避.png", 137 | "next": [ 138 | "检查比安卡·深痕", 139 | "检查露西亚·誓焰", 140 | "检查露娜·终焉", 141 | "检查露西亚·深红囚影", 142 | "检查拉弥亚·深谣" 143 | ] 144 | }, 145 | "深痕战斗": { 146 | "post_delay": 0, 147 | "pre_delay": 0, 148 | "action": "Custom", 149 | "custom_action": "Stigmata" 150 | }, 151 | "深谣战斗": { 152 | "post_delay": 0, 153 | "pre_delay": 0, 154 | "action": "Custom", 155 | "custom_action": "LostLullaby" 156 | }, 157 | "深红囚影战斗": { 158 | "post_delay": 0, 159 | "pre_delay": 0, 160 | "action": "Custom", 161 | "custom_action": "CrimsonWeave" 162 | }, 163 | "誓焰战斗": { 164 | "post_delay": 0, 165 | "pre_delay": 0, 166 | "action": "Custom", 167 | "custom_action": "Pyroath" 168 | }, 169 | "终焉战斗": { 170 | "post_delay": 0, 171 | "pre_delay": 0, 172 | "action": "Custom", 173 | "custom_action": "Oblivion" 174 | }, 175 | "启明战斗": { 176 | "post_delay": 0, 177 | "pre_delay": 0, 178 | "action": "Custom", 179 | "custom_action": "Shukra" 180 | } 181 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Auto_Battle/Auto_Battle_Quests.json: -------------------------------------------------------------------------------- 1 | { 2 | "自动战斗任务": { 3 | "recognition": "OCR", 4 | "roi": [ 5 | 1039, 6 | 642, 7 | 111, 8 | 50 9 | ], 10 | "expected": "作战开始", 11 | "next": [ 12 | "调用识别方法" 13 | ] 14 | }, 15 | "单人自动战斗循环": { 16 | "next": [ 17 | "自动战斗结束" 18 | ], 19 | "interrupt": [ 20 | "角色特有战斗" 21 | ] 22 | }, 23 | "多人轮切自动战斗循环": { 24 | "next": [ 25 | "自动战斗结束" 26 | ], 27 | "interrupt": [ 28 | "多人轮切自动战斗-1" 29 | ] 30 | }, 31 | "多人轮切自动战斗-1": { 32 | "action": "Click", 33 | "target": [ 34 | 1208, 35 | 154, 36 | 1, 37 | 1 38 | ], 39 | "next": [ 40 | "多人轮切自动战斗-2" 41 | ] 42 | }, 43 | "多人轮切自动战斗-2": { 44 | "action": "Custom", 45 | "custom_action": "MultiplayerAutoBattle", 46 | "next": [ 47 | "多人轮切自动战斗-3" 48 | ] 49 | }, 50 | "多人轮切自动战斗-3": { 51 | "action": "Click", 52 | "target": [ 53 | 1208, 54 | 265, 55 | 1, 56 | 1 57 | ], 58 | "next": [ 59 | "多人轮切自动战斗-4" 60 | ] 61 | }, 62 | "多人轮切自动战斗-4": { 63 | "action": "Custom", 64 | "custom_action": "MultiplayerAutoBattle" 65 | }, 66 | "通用自动战斗循环": { 67 | "next": [ 68 | "自动战斗结束" 69 | ], 70 | "interrupt": [ 71 | "通用战斗模式" 72 | ] 73 | }, 74 | "自动战斗(角色已选好)": { 75 | "next": [ 76 | "自动战斗任务" 77 | ] 78 | } 79 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Auto_Battle/Auto_Battle_Shared_Quests.json: -------------------------------------------------------------------------------- 1 | { 2 | "点击更换": { 3 | "recognition": "OCR", 4 | "roi": [ 5 | 314, 6 | 633, 7 | 49, 8 | 23 9 | ], 10 | "expected": "更换", 11 | "action": "Click" 12 | }, 13 | "点击作战开始": { 14 | "recognition": "OCR", 15 | "roi": [ 16 | 1022, 17 | 641, 18 | 235, 19 | 72 20 | ], 21 | "expected": "作战开始", 22 | "action": "Click", 23 | "next": [ 24 | "自动战斗开始" 25 | ], 26 | "interrupt": [ 27 | "等待加载" 28 | ] 29 | }, 30 | "自动战斗开始": { 31 | "green_mask": true, 32 | "recognition": "TemplateMatch", 33 | "roi": [ 34 | 990, 35 | 567, 36 | 131, 37 | 131 38 | ], 39 | "template": "战斗/闪避.png" 40 | }, 41 | "识别角色名": { 42 | "recognition": "OCR", 43 | "expected": "[\\u4e00-\\u9fa5]+[\\.\\·][\\u4e00-\\u9fa5]+" 44 | }, 45 | "识别队长位置": { 46 | "recognition": "OCR", 47 | "expected": "当前选择" 48 | }, 49 | "点击首选位置": { 50 | "recognition": "OCR", 51 | "roi": [ 52 | 1177, 53 | 327, 54 | 91, 55 | 153 56 | ], 57 | "expected": "", 58 | "action": "Click" 59 | }, 60 | "出队长界面": { 61 | "action": "Click", 62 | "target": [ 63 | 39, 64 | 103, 65 | 1, 66 | 1 67 | ] 68 | }, 69 | "调用识别方法": { 70 | "action": "Custom", 71 | "custom_action": "IdentifyRoles" 72 | }, 73 | "等待加载": { 74 | "recognition": "OCR", 75 | "roi": [ 76 | 1177, 77 | 625, 78 | 78, 79 | 71 80 | ], 81 | "post_delay": 3000, 82 | "expected": "Loading|oadin|adi" 83 | }, 84 | "角色特有战斗": { 85 | "post_delay": 0, 86 | "pre_delay": 0, 87 | "action": "Custom", 88 | "custom_action": "1" 89 | }, 90 | "通用战斗模式": { 91 | "post_delay": 0, 92 | "pre_delay": 0, 93 | "action": "Custom", 94 | "custom_action": "CombatActions" 95 | }, 96 | "自动战斗结束": { 97 | "post_delay": 0, 98 | "pre_delay": 0, 99 | "recognition": "OCR", 100 | "roi": [ 101 | 0, 102 | 0, 103 | 0, 104 | 0 105 | ], 106 | "expected": "结束战斗" 107 | }, 108 | "技能_能量条": { 109 | "post_delay": 0, 110 | "pre_delay": 0, 111 | "recognition": "ColorMatch", 112 | "roi": [ 113 | 28, 114 | 59, 115 | 216, 116 | 6 117 | ], 118 | "upper": [ 119 | 194, 120 | 255, 121 | 255 122 | ], 123 | "lower": [ 124 | 100, 125 | 230, 126 | 255 127 | ], 128 | "connected": true 129 | } 130 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Auto_Battle/Check_Characters.json: -------------------------------------------------------------------------------- 1 | { 2 | "检查比安卡·深痕": { 3 | "recognition": "TemplateMatch", 4 | "roi": [ 5 | 1113, 6 | 556, 7 | 138, 8 | 142 9 | ], 10 | "template": [ 11 | "自定义战斗/深痕.png", 12 | "自定义战斗/深痕a2.png" 13 | ], 14 | "green_mask": true 15 | }, 16 | "检查露西亚·誓焰": { 17 | "recognition": "TemplateMatch", 18 | "roi": [ 19 | 1113, 20 | 556, 21 | 138, 22 | 142 23 | ], 24 | "template": [ 25 | "自定义战斗/誓焰.png" 26 | ], 27 | "green_mask": true 28 | }, 29 | "检查露娜·终焉": { 30 | "recognition": "TemplateMatch", 31 | "roi": [ 32 | 1113, 33 | 556, 34 | 138, 35 | 142 36 | ], 37 | "template": [ 38 | "自定义战斗/终焉.png" 39 | ], 40 | "green_mask": true 41 | }, 42 | "检查露西亚·深红囚影": { 43 | "recognition": "TemplateMatch", 44 | "roi": [ 45 | 1113, 46 | 556, 47 | 138, 48 | 142 49 | ], 50 | "template": [ 51 | "自定义战斗/深红囚影.png" 52 | ], 53 | "green_mask": true 54 | }, 55 | "检查拉弥亚·深谣": { 56 | "recognition": "TemplateMatch", 57 | "roi": [ 58 | 1113, 59 | 556, 60 | 138, 61 | 142 62 | ], 63 | "template": [ 64 | "自定义战斗/深谣_p1.png", 65 | "自定义战斗/深谣_p2.png" 66 | ], 67 | "green_mask": true 68 | }, 69 | "检查曲·启明": { 70 | "recognition": "TemplateMatch", 71 | "roi": [ 72 | 1113, 73 | 556, 74 | 138, 75 | 142 76 | ], 77 | "template": [ 78 | "自定义战斗/启明.png" 79 | ], 80 | "green_mask": true 81 | } 82 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Battle_Pass.json: -------------------------------------------------------------------------------- 1 | { 2 | "通行证": { 3 | "next": [ 4 | "系统自动领取", 5 | "评定任务" 6 | ], 7 | "interrupt": [ 8 | "关闭奖励", 9 | "打开通行证", 10 | "打开通行证_图片", 11 | "意外点击_主界面" 12 | ] 13 | }, 14 | "打开通行证_图片": { 15 | "post_delay": 1000, 16 | "recognition": "TemplateMatch", 17 | "roi": [ 18 | 281, 19 | 54, 20 | 113, 21 | 90 22 | ], 23 | "template": [ 24 | "通行证/通行证_家园.png", 25 | "通行证/通行证_恋屿干年歌.png", 26 | "通行证/通行证_溺梦游歌.png", 27 | "通行证/通行证_白梦游弋.png", 28 | "通行证/通行证_离诗遗城.png", 29 | "通行证/通行证_耀阳映画.png", 30 | "通行证/通行证_花溪憩乡.png", 31 | "通行证/通行证_银光教堂.png", 32 | "通行证/通行证_闲庭疏影.png", 33 | "通行证/通行证_鸣神叹妙.png", 34 | "通行证/通行证_默认.png" 35 | ], 36 | "action": "Click" 37 | }, 38 | "系统自动领取": { 39 | "recognition": "OCR", 40 | "roi": [ 41 | 734, 42 | 479, 43 | 80, 44 | 44 45 | ], 46 | "expected": "确定", 47 | "action": "Click", 48 | "next": [ 49 | "通行证" 50 | ] 51 | }, 52 | "评定任务": { 53 | "recognition": "OCR", 54 | "roi": [ 55 | 8, 56 | 224, 57 | 275, 58 | 396 59 | ], 60 | "expected": "评定任务", 61 | "action": "Click", 62 | "next": [ 63 | "一键领取_评定任务", 64 | "系统自动领取" 65 | ] 66 | }, 67 | "一键领取_评定任务": { 68 | "post_delay": 1000, 69 | "recognition": "OCR", 70 | "roi": [ 71 | 974, 72 | 611, 73 | 258, 74 | 100 75 | ], 76 | "expected": [ 77 | "一键领取", 78 | "键领取" 79 | ], 80 | "action": "Click", 81 | "next": [ 82 | "战略补给", 83 | "系统自动领取" 84 | ], 85 | "interrupt": [ 86 | "关闭奖励" 87 | ] 88 | }, 89 | "战略补给": { 90 | "recognition": "OCR", 91 | "roi": [ 92 | 8, 93 | 224, 94 | 275, 95 | 396 96 | ], 97 | "expected": "战略补给", 98 | "action": "Click", 99 | "next": [ 100 | "一键领取_战略补给", 101 | "系统自动领取" 102 | ] 103 | }, 104 | "一键领取_战略补给": { 105 | "post_delay": 1000, 106 | "recognition": "OCR", 107 | "roi": [ 108 | 974, 109 | 611, 110 | 258, 111 | 100 112 | ], 113 | "expected": [ 114 | "一键领取", 115 | "键领取" 116 | ], 117 | "action": "Click", 118 | "next": [ 119 | "返回主菜单", 120 | "系统自动领取" 121 | ], 122 | "interrupt": [ 123 | "关闭奖励" 124 | ] 125 | }, 126 | "打开通行证": { 127 | "post_delay": 4000, 128 | "recognition": "OCR", 129 | "roi": [ 130 | 257, 131 | 26, 132 | 164, 133 | 151 134 | ], 135 | "expected": "BP", 136 | "action": "Click" 137 | } 138 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Buy_Item.json: -------------------------------------------------------------------------------- 1 | { 2 | "购买物品": { 3 | "next": [ 4 | "购买" 5 | ], 6 | "interrupt": [ 7 | "检查碎片", 8 | "滑动", 9 | "打开商店", 10 | "错误点击_商品", 11 | "意外点击_主界面" 12 | ] 13 | }, 14 | "错误点击_商品": { 15 | "post_wait_freezes": 500, 16 | "recognition": "TemplateMatch", 17 | "roi": [ 18 | 1195, 19 | 30, 20 | 61, 21 | 61 22 | ], 23 | "template": "购买碎片/关闭_1195_30_61_61__1119_0_161_161.png", 24 | "action": "Click" 25 | }, 26 | "检查碎片": { 27 | "post_delay": 1000, 28 | "recognition": "OCR", 29 | "roi": [ 30 | 333, 31 | 338, 32 | 930, 33 | 37 34 | ], 35 | "expected": "逆元碎片", 36 | "action": "Click", 37 | "target_offset": [ 38 | 0, 39 | 140, 40 | 0, 41 | 0 42 | ] 43 | }, 44 | "滑动": { 45 | "post_delay": 1000, 46 | "recognition": "OCR", 47 | "roi": [ 48 | 0, 49 | 0, 50 | 0, 51 | 0 52 | ], 53 | "expected": "补给商店", 54 | "action": "Swipe", 55 | "begin": [ 56 | 1200, 57 | 350, 58 | 0, 59 | 0 60 | ], 61 | "end": [ 62 | 1150, 63 | 350, 64 | 0, 65 | 0 66 | ] 67 | }, 68 | "打开商店": { 69 | "recognition": "OCR", 70 | "roi": [ 71 | 876, 72 | 485, 73 | 50, 74 | 30 75 | ], 76 | "expected": "商店", 77 | "action": "Click" 78 | }, 79 | "购买": { 80 | "recognition": "OCR", 81 | "roi": [ 82 | 536, 83 | 205, 84 | 217, 85 | 41 86 | ], 87 | "expected": "逆元碎片", 88 | "target": [ 89 | 768, 90 | 666, 91 | 0, 92 | 0 93 | ], 94 | "action": "Click", 95 | "next": [ 96 | "关闭界面", 97 | "返回主菜单_图标" 98 | ] 99 | }, 100 | "购买碎片成功": { 101 | "recognition": "OCR", 102 | "roi": [ 103 | 521, 104 | 338, 105 | 240, 106 | 37 107 | ], 108 | "expected": "购买成功", 109 | "action": "Click", 110 | "target": [ 111 | 1, 112 | 0, 113 | 0, 114 | 0 115 | ], 116 | "next": [ 117 | "返回主菜单" 118 | ] 119 | }, 120 | "购买碎片失败": { 121 | "post_delay": 1000, 122 | "recognition": "OCR", 123 | "roi": [ 124 | 521, 125 | 338, 126 | 240, 127 | 37 128 | ], 129 | "expected": [ 130 | "超过商店可购买的数量", 131 | "购买所需材料不足" 132 | ], 133 | "replace": [ 134 | [ 135 | "招", 136 | "超" 137 | ], 138 | [ 139 | "绍", 140 | "超" 141 | ], 142 | [ 143 | "可可", 144 | "可" 145 | ] 146 | ], 147 | "action": "Click", 148 | "target": [ 149 | 646, 150 | 115, 151 | 0, 152 | 0 153 | ], 154 | "next": [ 155 | "关闭界面" 156 | ] 157 | }, 158 | "关闭界面": { 159 | "post_wait_freezes": 500, 160 | "recognition": "TemplateMatch", 161 | "roi": [ 162 | 1195, 163 | 30, 164 | 61, 165 | 61 166 | ], 167 | "template": "购买碎片/关闭_1195_30_61_61__1119_0_161_161.png", 168 | "action": "Click", 169 | "next": [ 170 | "关闭界面", 171 | "返回主菜单" 172 | ] 173 | } 174 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Chain_Loop_Circuit.json: -------------------------------------------------------------------------------- 1 | { 2 | "链合回路": { 3 | "next": [ 4 | "继续_链合回路" 5 | ], 6 | "interrupt": [ 7 | "任务过程" 8 | ] 9 | }, 10 | "使用技能_链合回路": { 11 | "recognition": "OCR", 12 | "roi": [ 13 | 1114, 14 | 537, 15 | 41, 16 | 32 17 | ], 18 | "expected": [ 19 | "\\b(2[1-9]|[3-9]\\d|\\d{3,})\\b" 20 | ], 21 | "next": [] 22 | }, 23 | "继续_链合回路": { 24 | "recognition": "OCR", 25 | "roi": [ 26 | 416, 27 | 487, 28 | 129, 29 | 38 30 | ], 31 | "expected": [ 32 | "重新挑战" 33 | ], 34 | "action": "Click", 35 | "next": [ 36 | "链合回路" 37 | ] 38 | }, 39 | "任务过程": { 40 | "post_wait_freezes": 200, 41 | "recognition": "OCR", 42 | "only_rec": true, 43 | "roi": [ 44 | 1114, 45 | 635, 46 | 78, 47 | 26 48 | ], 49 | "expected": [ 50 | "道具说明" 51 | ], 52 | "replace": [ 53 | "真", 54 | "具" 55 | ], 56 | "action": "Custom", 57 | "custom_action": "ChainLoopCircuit", 58 | "next": [] 59 | }, 60 | "识别蓝球_链合回路": { 61 | "recognition": "ColorMatch", 62 | "roi": [ 63 | 430, 64 | 61, 65 | 627, 66 | 632 67 | ], 68 | "upper": [ 69 | 50, 70 | 170, 71 | 230 72 | ], 73 | "lower": [ 74 | 0, 75 | 120, 76 | 180 77 | ], 78 | "connected": true, 79 | "count": 100 80 | }, 81 | "识别黄球_链合回路": { 82 | "recognition": "ColorMatch", 83 | "roi": [ 84 | 430, 85 | 61, 86 | 627, 87 | 632 88 | ], 89 | "upper": [ 90 | 230, 91 | 170, 92 | 40 93 | ], 94 | "lower": [ 95 | 130, 96 | 95, 97 | 20 98 | ], 99 | "connected": true, 100 | "count": 100 101 | }, 102 | "识别红球_链合回路": { 103 | "recognition": "ColorMatch", 104 | "roi": [ 105 | 430, 106 | 61, 107 | 627, 108 | 632 109 | ], 110 | "upper": [ 111 | 180, 112 | 40, 113 | 40 114 | ], 115 | "lower": [ 116 | 90, 117 | 15, 118 | 15 119 | ], 120 | "connected": true, 121 | "count": 100 122 | }, 123 | "识别灰球_链合回路": { 124 | "recognition": "ColorMatch", 125 | "roi": [ 126 | 430, 127 | 61, 128 | 627, 129 | 632 130 | ], 131 | "upper": [ 132 | 230, 133 | 230, 134 | 230 135 | ], 136 | "lower": [ 137 | 200, 138 | 200, 139 | 200 140 | ], 141 | "connected": true, 142 | "count": 200 143 | }, 144 | "识别爆破_链合回路": { 145 | "recognition": "TemplateMatch", 146 | "roi": [ 147 | 430, 148 | 61, 149 | 627, 150 | 632 151 | ], 152 | "template": "链合回路/技能_爆破.png", 153 | "green_mask": true 154 | }, 155 | "识别闪星_链合回路": { 156 | "recognition": "TemplateMatch", 157 | "roi": [ 158 | 430, 159 | 61, 160 | 627, 161 | 632 162 | ], 163 | "template": "链合回路/技能_闪星.png", 164 | "green_mask": true 165 | }, 166 | "识别纵斩_链合回路": { 167 | "recognition": "TemplateMatch", 168 | "roi": [ 169 | 430, 170 | 61, 171 | 627, 172 | 632 173 | ], 174 | "template": "链合回路/技能_纵斩.png", 175 | "green_mask": true 176 | }, 177 | "识别快枪_链合回路": { 178 | "recognition": "TemplateMatch", 179 | "roi": [ 180 | 430, 181 | 61, 182 | 627, 183 | 632 184 | ], 185 | "template": "链合回路/技能_快枪.png", 186 | "green_mask": true 187 | } 188 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Collect_Quest.json: -------------------------------------------------------------------------------- 1 | { 2 | "任务": { 3 | "next": [ 4 | "每周任务" 5 | ], 6 | "interrupt": [ 7 | "打开任务", 8 | "意外点击_主界面" 9 | ] 10 | }, 11 | "每日任务": { 12 | "post_delay": 1000, 13 | "recognition": "OCR", 14 | "roi": [ 15 | 9, 16 | 184, 17 | 237, 18 | 355 19 | ], 20 | "expected": "每日", 21 | "action": "Click", 22 | "next": [ 23 | "一键领取_任务", 24 | "领取活跃0-19", 25 | "领取活跃20-39", 26 | "领取活跃40-59", 27 | "领取活跃60-79", 28 | "领取活跃80-99", 29 | "领取活跃100" 30 | ], 31 | "interrupt": [ 32 | "关闭奖励" 33 | ] 34 | }, 35 | "领取活跃0-19": { 36 | "post_delay": 1000, 37 | "recognition": "OCR", 38 | "roi": [ 39 | 284, 40 | 655, 41 | 101, 42 | 49 43 | ], 44 | "expected": "^(0?[0-9]|1[0-9])$", 45 | "next": [ 46 | "返回主菜单" 47 | ], 48 | "interrupt": [ 49 | "关闭奖励" 50 | ] 51 | }, 52 | "领取活跃20-39": { 53 | "post_delay": 1000, 54 | "recognition": "OCR", 55 | "roi": [ 56 | 284, 57 | 655, 58 | 101, 59 | 49 60 | ], 61 | "expected": "^(2[0-9]|3[0-9])$", 62 | "action": "Click", 63 | "target": [ 64 | 598, 65 | 629, 66 | 1, 67 | 1 68 | ], 69 | "next": [ 70 | "返回主菜单" 71 | ], 72 | "interrupt": [ 73 | "关闭奖励" 74 | ] 75 | }, 76 | "领取活跃40-59": { 77 | "post_delay": 1000, 78 | "recognition": "OCR", 79 | "roi": [ 80 | 284, 81 | 655, 82 | 101, 83 | 49 84 | ], 85 | "expected": "^(4[0-9]|5[0-9])$", 86 | "action": "Click", 87 | "target": [ 88 | 746, 89 | 639, 90 | 1, 91 | 1 92 | ], 93 | "next": [ 94 | "返回主菜单" 95 | ], 96 | "interrupt": [ 97 | "关闭奖励" 98 | ] 99 | }, 100 | "领取活跃60-79": { 101 | "post_delay": 1000, 102 | "recognition": "OCR", 103 | "roi": [ 104 | 284, 105 | 655, 106 | 101, 107 | 49 108 | ], 109 | "expected": "^(6[0-9]|7[0-9])$", 110 | "action": "Click", 111 | "target": [ 112 | 893, 113 | 640, 114 | 1, 115 | 1 116 | ], 117 | "next": [ 118 | "返回主菜单" 119 | ], 120 | "interrupt": [ 121 | "关闭奖励" 122 | ] 123 | }, 124 | "领取活跃80-99": { 125 | "post_delay": 1000, 126 | "recognition": "OCR", 127 | "roi": [ 128 | 284, 129 | 655, 130 | 101, 131 | 49 132 | ], 133 | "expected": "^(8[0-9]|9[0-9])$", 134 | "action": "Click", 135 | "target": [ 136 | 1053, 137 | 642, 138 | 1, 139 | 1 140 | ], 141 | "next": [ 142 | "返回主菜单" 143 | ], 144 | "interrupt": [ 145 | "关闭奖励" 146 | ] 147 | }, 148 | "领取活跃100": { 149 | "post_delay": 1000, 150 | "recognition": "OCR", 151 | "roi": [ 152 | 284, 153 | 655, 154 | 101, 155 | 49 156 | ], 157 | "expected": "^(1([0-9]{2})|200)$", 158 | "action": "Click", 159 | "target": [ 160 | 1200, 161 | 638, 162 | 1, 163 | 1 164 | ], 165 | "next": [ 166 | "返回主菜单" 167 | ], 168 | "interrupt": [ 169 | "关闭奖励" 170 | ] 171 | }, 172 | "每周任务": { 173 | "post_delay": 1000, 174 | "recognition": "OCR", 175 | "roi": [ 176 | 9, 177 | 184, 178 | 237, 179 | 355 180 | ], 181 | "expected": "每周", 182 | "action": "Click", 183 | "next": [ 184 | "一键领取_定期", 185 | "每日任务" 186 | ], 187 | "interrupt": [] 188 | }, 189 | "打开任务": { 190 | "post_delay": 2000, 191 | "recognition": "OCR", 192 | "roi": [ 193 | 900, 194 | 250, 195 | 50, 196 | 30 197 | ], 198 | "expected": [ 199 | "任务", 200 | "任笋" 201 | ], 202 | "action": "Click" 203 | }, 204 | "一键领取_定期": { 205 | "post_delay": 1000, 206 | "recognition": "OCR", 207 | "roi": [ 208 | 1072, 209 | 128, 210 | 112, 211 | 40 212 | ], 213 | "expected": [ 214 | "一键领取", 215 | "键领取" 216 | ], 217 | "action": "Click", 218 | "next": [ 219 | "关闭奖励_每周" 220 | ] 221 | }, 222 | "一键领取_任务": { 223 | "post_delay": 1000, 224 | "recognition": "OCR", 225 | "roi": [ 226 | 1072, 227 | 128, 228 | 112, 229 | 40 230 | ], 231 | "expected": [ 232 | "一键领取", 233 | "键领取" 234 | ], 235 | "action": "Click", 236 | "next": [ 237 | "关闭奖励_任务" 238 | ] 239 | }, 240 | "关闭奖励_每周": { 241 | "post_delay": 1000, 242 | "recognition": "TemplateMatch", 243 | "roi": [ 244 | 409, 245 | 176, 246 | 491, 247 | 150 248 | ], 249 | "template": "通用任务/105157_624_220_86_57__574_170_186_157.png", 250 | "action": "Click", 251 | "target": [ 252 | 446, 253 | 30, 254 | 0, 255 | 0 256 | ], 257 | "next": [ 258 | "每日任务" 259 | ] 260 | }, 261 | "关闭奖励_任务": { 262 | "post_delay": 1000, 263 | "recognition": "TemplateMatch", 264 | "roi": [ 265 | 409, 266 | 176, 267 | 491, 268 | 150 269 | ], 270 | "template": "通用任务/105157_624_220_86_57__574_170_186_157.png", 271 | "action": "Click", 272 | "target": [ 273 | 446, 274 | 30, 275 | 0, 276 | 0 277 | ], 278 | "next": [ 279 | "每日任务" 280 | ] 281 | } 282 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/General.json: -------------------------------------------------------------------------------- 1 | { 2 | "关闭奖励": { 3 | "post_delay": 1000, 4 | "recognition": "TemplateMatch", 5 | "roi": [ 6 | 409, 7 | 176, 8 | 491, 9 | 150 10 | ], 11 | "template": "通用任务/105157_624_220_86_57__574_170_186_157.png", 12 | "action": "Click", 13 | "target": [ 14 | 446, 15 | 30, 16 | 0, 17 | 0 18 | ] 19 | }, 20 | "返回主菜单": { 21 | "post_delay": 1000, 22 | "recognition": "OCR", 23 | "roi": [ 24 | 238, 25 | 27, 26 | 78, 27 | 38 28 | ], 29 | "expected": "主界面", 30 | "action": "Click", 31 | "next": [ 32 | "检查主界面2", 33 | "关闭奖励", 34 | "返回主菜单" 35 | ], 36 | "interrupt": [ 37 | "确定_厄愿潮声" 38 | ] 39 | }, 40 | "返回主菜单_图标": { 41 | "post_delay": 1000, 42 | "recognition": "OCR", 43 | "roi": [ 44 | 186, 45 | 14, 46 | 45, 47 | 42 48 | ], 49 | "expected": [ 50 | "O", 51 | "o", 52 | "0" 53 | ], 54 | "action": "Click", 55 | "next": [ 56 | "检查主界面2", 57 | "返回主菜单", 58 | "返回主菜单_图标" 59 | ] 60 | }, 61 | "意外点击_主界面": { 62 | "post_delay": 1000, 63 | "recognition": "OCR", 64 | "roi": [ 65 | 758, 66 | 199, 67 | 361, 68 | 368 69 | ], 70 | "expected": "库街区", 71 | "action": "Click", 72 | "target": [ 73 | 10, 74 | 10, 75 | 0, 76 | 0 77 | ] 78 | }, 79 | "返回": { 80 | "post_delay": 1500, 81 | "recognition": "OCR", 82 | "roi": [ 83 | 76, 84 | 18, 85 | 62, 86 | 34 87 | ], 88 | "expected": "返回", 89 | "action": "Click" 90 | }, 91 | "返回_图标": { 92 | "post_delay": 1000, 93 | "recognition": "TemplateMatch", 94 | "roi": [ 95 | 27, 96 | 10, 97 | 51, 98 | 53 99 | ], 100 | "template": "指挥局/返回.png", 101 | "action": "Click" 102 | }, 103 | "返回主菜单_err": { 104 | "focus": { 105 | "succeeded": "[color:Tomato]识别错误,返回主菜单[/color]" 106 | }, 107 | "action": "Custom", 108 | "custom_action": "ScreenShot", 109 | "custom_action_param": { 110 | "type": "ERR" 111 | }, 112 | "next": [ 113 | "检查主界面", 114 | "返回主菜单", 115 | "返回主菜单_图标" 116 | ], 117 | "interrupt": [ 118 | "确定_厄愿潮声", 119 | "领取藏品_厄愿潮声", 120 | "关闭奖励", 121 | "返回", 122 | "返回_图标" 123 | ], 124 | "on_error": [ 125 | "重启游戏" 126 | ] 127 | }, 128 | "重启游戏": { 129 | "focus": { 130 | "succeeded": "[color:Tomato]未知错误,重启游戏[/color]" 131 | }, 132 | "action": "StopApp", 133 | "package": "com.kurogame.haru.hero", 134 | "next": [ 135 | "启动" 136 | ] 137 | }, 138 | "意外点击_物品": { 139 | "recognition": "TemplateMatch", 140 | "roi": [ 141 | 1130, 142 | 24, 143 | 124, 144 | 96 145 | ], 146 | "template": "幻痛囚笼/关闭奖励.png", 147 | "action": "Click" 148 | }, 149 | "跳过剧情": { 150 | "post_delay": 1000, 151 | "recognition": "OCR", 152 | "roi": [ 153 | 1118, 154 | 22, 155 | 149, 156 | 33 157 | ], 158 | "expected": [ 159 | "跳", 160 | "过" 161 | ], 162 | "action": "Click", 163 | "next": [ 164 | "确认跳过", 165 | "跳过剧情" 166 | ] 167 | }, 168 | "确认跳过": { 169 | "recognition": "OCR", 170 | "roi": [ 171 | 973, 172 | 581, 173 | 106, 174 | 45 175 | ], 176 | "expected": "跳过", 177 | "action": "Click" 178 | } 179 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Get_Class_A.json: -------------------------------------------------------------------------------- 1 | { 2 | "刷A级碎片": { 3 | "next": [ 4 | "检查是否是资源副本界面", 5 | "检查主界面" 6 | ] 7 | }, 8 | "检查是否是资源副本界面": { 9 | "post_delay": 1000, 10 | "recognition": "OCR", 11 | "roi": [ 12 | 887, 13 | 651, 14 | 150, 15 | 66 16 | ], 17 | "expected": "资源", 18 | "next": [ 19 | "A级角色" 20 | ], 21 | "interrupt": [ 22 | "进入资源副本" 23 | ] 24 | }, 25 | "进入资源副本": { 26 | "post_delay": 1000, 27 | "recognition": "OCR", 28 | "roi": [ 29 | 887, 30 | 651, 31 | 150, 32 | 66 33 | ], 34 | "expected": "资源", 35 | "action": "Click", 36 | "next": [ 37 | "A级角色" 38 | ], 39 | "interrupt": [ 40 | "滑动角色碎片界面" 41 | ] 42 | }, 43 | "滑动角色碎片界面": { 44 | "post_delay": 0, 45 | "recognition": "OCR", 46 | "roi": [ 47 | 247, 48 | 107, 49 | 107, 50 | 41 51 | ], 52 | "expected": "角色碎片", 53 | "action": "Swipe", 54 | "begin": [ 55 | 556, 56 | 506, 57 | 1, 58 | 1 59 | ], 60 | "end": [ 61 | 358, 62 | 506, 63 | 1, 64 | 1 65 | ], 66 | "next": [ 67 | "A_滑动后点击" 68 | ] 69 | }, 70 | "A_滑动后点击": { 71 | "action": "Click", 72 | "target": [ 73 | 637, 74 | 172, 75 | 0, 76 | 0 77 | ], 78 | "next": [ 79 | "A_滑动计数" 80 | ] 81 | }, 82 | "A_滑动计数": { 83 | "action": "Custom", 84 | "custom_action": "Count", 85 | "custom_action_param": { 86 | "self": "A_滑动计数", 87 | "count": 0, 88 | "target_count": 25, 89 | "next_node": [ 90 | "返回主菜单_err", 91 | "停止任务" 92 | ] 93 | } 94 | }, 95 | "A级角色": { 96 | "post_delay": 1000, 97 | "recognition": "OCR", 98 | "roi": [ 99 | 253, 100 | 467, 101 | 1004, 102 | 62 103 | ], 104 | "expected": "", 105 | "action": "Click", 106 | "next": [ 107 | "使用体力刷碎片", 108 | "未解锁自动作战" 109 | ] 110 | }, 111 | "未解锁自动作战": { 112 | "focus": { 113 | "succeeded": "[color:Tomato]未解锁自动作战[/color]" 114 | }, 115 | "post_delay": 1000, 116 | "recognition": "OCR", 117 | "roi": [ 118 | 939, 119 | 621, 120 | 123, 121 | 69 122 | ], 123 | "expected": "^战斗$", 124 | "next": [ 125 | "返回主菜单" 126 | ] 127 | }, 128 | "使用体力刷碎片": { 129 | "post_delay": 1000, 130 | "recognition": "OCR", 131 | "roi": [ 132 | 939, 133 | 621, 134 | 123, 135 | 69 136 | ], 137 | "expected": "自动作战", 138 | "action": "Click", 139 | "next": [ 140 | "A_MAX", 141 | "A_挑战次数不足" 142 | ] 143 | }, 144 | "A_挑战次数不足": { 145 | "recognition": "OCR", 146 | "roi": [ 147 | 551, 148 | 330, 149 | 174, 150 | 46 151 | ], 152 | "expected": "挑战次数不足", 153 | "next": [ 154 | "返回主菜单" 155 | ] 156 | }, 157 | "A_MAX": { 158 | "post_delay": 1000, 159 | "recognition": "OCR", 160 | "roi": [ 161 | 286, 162 | 497, 163 | 83, 164 | 48 165 | ], 166 | "expected": "MAX", 167 | "action": "Click", 168 | "next": [ 169 | "A_确认出战" 170 | ] 171 | }, 172 | "A_确认出战": { 173 | "post_delay": 3000, 174 | "recognition": "OCR", 175 | "roi": [ 176 | 1012, 177 | 486, 178 | 251, 179 | 63 180 | ], 181 | "expected": "确认", 182 | "action": "Click", 183 | "next": [ 184 | "A_出战结束_确认", 185 | "A_血清组", 186 | "补给包不足" 187 | ] 188 | }, 189 | "A_血清组": { 190 | "post_delay": 1000, 191 | "recognition": "OCR", 192 | "roi": [ 193 | 845, 194 | 268, 195 | 195, 196 | 64 197 | ], 198 | "expected": "注射血清", 199 | "next": [ 200 | "A_使用体力", 201 | "A_不使用体力" 202 | ] 203 | }, 204 | "A_使用体力": { 205 | "post_delay": 2000, 206 | "recognition": "OCR", 207 | "roi": [ 208 | 859, 209 | 586, 210 | 67, 211 | 38 212 | ], 213 | "expected": "确定", 214 | "action": "Click", 215 | "next": [ 216 | "A_体力取消" 217 | ], 218 | "interrupt": [ 219 | "关闭奖励" 220 | ] 221 | }, 222 | "A_体力取消": { 223 | "recognition": "OCR", 224 | "roi": [ 225 | 664, 226 | 588, 227 | 57, 228 | 44 229 | ], 230 | "expected": "取消", 231 | "action": "Click", 232 | "next": [ 233 | "A_确认出战" 234 | ] 235 | }, 236 | "A_不使用体力": { 237 | "recognition": "OCR", 238 | "roi": [ 239 | 664, 240 | 588, 241 | 57, 242 | 44 243 | ], 244 | "expected": "取消", 245 | "action": "Click", 246 | "next": [ 247 | "返回主菜单" 248 | ] 249 | }, 250 | "A_出战结束_确认": { 251 | "post_delay": 1000, 252 | "recognition": "OCR", 253 | "roi": [ 254 | 1077, 255 | 623, 256 | 176, 257 | 88 258 | ], 259 | "expected": "确定", 260 | "action": "Click", 261 | "next": [ 262 | "返回主菜单" 263 | ] 264 | } 265 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Guardian.json: -------------------------------------------------------------------------------- 1 | { 2 | "维系者行动": { 3 | "next": [ 4 | "行动上限", 5 | "无需任务" 6 | ], 7 | "interrupt": [ 8 | "开始行动", 9 | "打开维系者行动", 10 | "打开任务", 11 | "意外点击_主界面" 12 | ] 13 | }, 14 | "无需任务": { 15 | "recognition": "Custom", 16 | "custom_recognition": "LOp", 17 | "custom_recognition_param": { 18 | "prestep": [ 19 | "战斗任务", 20 | "废弃仓库", 21 | "支援箱" 22 | ], 23 | "mode": "and", 24 | "nodes": [ 25 | "识别战斗任务完成情况", 26 | "识别废弃仓库完成情况", 27 | "识别支援箱完成情况" 28 | ] 29 | }, 30 | "next": [ 31 | "返回主菜单" 32 | ] 33 | }, 34 | "战斗任务": { 35 | "recognition": "OCR", 36 | "roi": [ 37 | 88, 38 | 592, 39 | 352, 40 | 102 41 | ], 42 | "expected": "战斗任务", 43 | "next": [ 44 | "识别战斗任务完成情况" 45 | ] 46 | }, 47 | "废弃仓库": { 48 | "recognition": "OCR", 49 | "roi": [ 50 | 88, 51 | 592, 52 | 352, 53 | 102 54 | ], 55 | "expected": "废弃仓库", 56 | "next": [ 57 | "识别废弃仓库完成情况" 58 | ] 59 | }, 60 | "支援箱": { 61 | "recognition": "OCR", 62 | "roi": [ 63 | 88, 64 | 592, 65 | 352, 66 | 102 67 | ], 68 | "expected": "支援箱", 69 | "next": [ 70 | "识别支援箱完成情况" 71 | ] 72 | }, 73 | "识别战斗任务完成情况": { 74 | "only_rec": true, 75 | "recognition": "OCR", 76 | "roi": "战斗任务", 77 | "roi_offset": [ 78 | 85, 79 | 0, 80 | 0, 81 | 0 82 | ], 83 | "expected": "已完成" 84 | }, 85 | "识别废弃仓库完成情况": { 86 | "only_rec": true, 87 | "recognition": "OCR", 88 | "roi": "废弃仓库", 89 | "roi_offset": [ 90 | 85, 91 | 0, 92 | 0, 93 | 0 94 | ], 95 | "expected": "已完成" 96 | }, 97 | "识别支援箱完成情况": { 98 | "only_rec": true, 99 | "recognition": "OCR", 100 | "roi": "支援箱", 101 | "roi_offset": [ 102 | 85, 103 | 0, 104 | 0, 105 | 0 106 | ], 107 | "expected": "已完成" 108 | }, 109 | "行动上限": { 110 | "recognition": "OCR", 111 | "roi": [ 112 | 510, 113 | 340, 114 | 250, 115 | 40 116 | ], 117 | "expected": "每日行动次数已达上限", 118 | "action": "Click", 119 | "target": [ 120 | 420, 121 | 20, 122 | 0, 123 | 0 124 | ], 125 | "next": [ 126 | "返回主菜单" 127 | ] 128 | }, 129 | "开始行动": { 130 | "post_delay": 1000, 131 | "recognition": "OCR", 132 | "roi": [ 133 | 85, 134 | 600, 135 | 90, 136 | 40 137 | ], 138 | "expected": "战斗任务", 139 | "action": "Click", 140 | "target": [ 141 | 960, 142 | 640, 143 | 0, 144 | 0 145 | ] 146 | }, 147 | "打开维系者行动": { 148 | "recognition": "OCR", 149 | "roi": [ 150 | 40, 151 | 660, 152 | 120, 153 | 30 154 | ], 155 | "expected": "维系者行动", 156 | "action": "Click" 157 | } 158 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Guild.json: -------------------------------------------------------------------------------- 1 | { 2 | "指挥局": { 3 | "next": [ 4 | "检查是否在指挥局内部" 5 | ], 6 | "interrupt": [ 7 | "打开指挥局", 8 | "意外点击_主界面" 9 | ] 10 | }, 11 | "检查是否在指挥局内部": { 12 | "recognition": "OCR", 13 | "roi": [ 14 | 301, 15 | 14, 16 | 123, 17 | 34 18 | ], 19 | "expected": "新版指挥局", 20 | "next": [ 21 | "检查指定按钮" 22 | ], 23 | "interrupt": [ 24 | "移动_蔚蓝之夏", 25 | "移动_岁雪新宵", 26 | "移动_庭梨栖雪", 27 | "移动_漫花清夏", 28 | "移动_鲸律星屿", 29 | "移动_云海空岛", 30 | "移动_经典舱室" 31 | ] 32 | }, 33 | "检查指定按钮": { 34 | "recognition": "OCR", 35 | "roi": [ 36 | 927, 37 | 326, 38 | 113, 39 | 49 40 | ], 41 | "expected": [ 42 | "算一签", 43 | "查看签文" 44 | ], 45 | "action": "Click", 46 | "next": [ 47 | "关闭奖励_指挥局" 48 | ] 49 | }, 50 | "移动_鲸律星屿": { 51 | "recognition": "OCR", 52 | "expected": "鲸律星屿", 53 | "roi": [ 54 | 1023, 55 | 8, 56 | 184, 57 | 51 58 | ], 59 | "action": "Swipe", 60 | "begin": [ 61 | 281, 62 | 451, 63 | 1, 64 | 1 65 | ], 66 | "end": [ 67 | 281, 68 | 451, 69 | 1, 70 | 1 71 | ] 72 | }, 73 | "移动_经典舱室": { 74 | "recognition": "OCR", 75 | "expected": "经典舱室", 76 | "roi": [ 77 | 1023, 78 | 8, 79 | 184, 80 | 51 81 | ], 82 | "action": "Swipe", 83 | "begin": [ 84 | 300, 85 | 540, 86 | 0, 87 | 0 88 | ], 89 | "end": [ 90 | 300, 91 | 540, 92 | 0, 93 | 0 94 | ] 95 | }, 96 | "移动_庭梨栖雪": { 97 | "recognition": "OCR", 98 | "expected": "庭梨栖雪", 99 | "roi": [ 100 | 1023, 101 | 8, 102 | 184, 103 | 51 104 | ], 105 | "action": "Swipe", 106 | "begin": [ 107 | 265, 108 | 470, 109 | 0, 110 | 0 111 | ], 112 | "end": [ 113 | 265, 114 | 470, 115 | 0, 116 | 0 117 | ] 118 | }, 119 | "移动_岁雪新宵": { 120 | "recognition": "OCR", 121 | "expected": "岁雪新宵", 122 | "roi": [ 123 | 1023, 124 | 8, 125 | 184, 126 | 51 127 | ], 128 | "action": "Swipe", 129 | "begin": [ 130 | 300, 131 | 540, 132 | 0, 133 | 0 134 | ], 135 | "end": [ 136 | 300, 137 | 540, 138 | 0, 139 | 0 140 | ] 141 | }, 142 | "移动_蔚蓝之夏": { 143 | "recognition": "OCR", 144 | "expected": "蔚蓝之夏", 145 | "roi": [ 146 | 1023, 147 | 8, 148 | 184, 149 | 51 150 | ], 151 | "action": "Swipe", 152 | "begin": [ 153 | 98, 154 | 476, 155 | 1, 156 | 1 157 | ], 158 | "end": [ 159 | 98, 160 | 476, 161 | 1, 162 | 1 163 | ] 164 | }, 165 | "移动_云海空岛": { 166 | "recognition": "OCR", 167 | "expected": "云海空岛", 168 | "roi": [ 169 | 1023, 170 | 8, 171 | 184, 172 | 51 173 | ], 174 | "action": "Swipe", 175 | "begin": [ 176 | 300, 177 | 540, 178 | 0, 179 | 0 180 | ], 181 | "end": [ 182 | 300, 183 | 540, 184 | 0, 185 | 0 186 | ] 187 | }, 188 | "移动_漫花清夏": { 189 | "recognition": "OCR", 190 | "expected": "漫花清夏", 191 | "roi": [ 192 | 1023, 193 | 8, 194 | 184, 195 | 51 196 | ], 197 | "action": "Swipe", 198 | "begin": [ 199 | 300, 200 | 540, 201 | 0, 202 | 0 203 | ], 204 | "end": [ 205 | 300, 206 | 540, 207 | 0, 208 | 0 209 | ] 210 | }, 211 | "关闭奖励_指挥局": { 212 | "recognition": "OCR", 213 | "roi": [ 214 | 600, 215 | 570, 216 | 76, 217 | 70 218 | ], 219 | "expected": "已领取", 220 | "action": "Click", 221 | "target": [ 222 | 833, 223 | 100, 224 | 0, 225 | 0 226 | ], 227 | "pre_delay": 1000, 228 | "next": [ 229 | "返回", 230 | "返回_图标" 231 | ] 232 | } 233 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Mail.json: -------------------------------------------------------------------------------- 1 | { 2 | "邮件": { 3 | "next": [ 4 | "领取全部" 5 | ], 6 | "interrupt": [ 7 | "打开邮件", 8 | "意外点击_主界面" 9 | ] 10 | }, 11 | "领取全部": { 12 | "recognition": "OCR", 13 | "roi": [ 14 | 212, 15 | 612, 16 | 207, 17 | 55 18 | ], 19 | "expected": "领取全部", 20 | "action": "Click", 21 | "next": [ 22 | "返回主菜单" 23 | ] 24 | }, 25 | "打开邮件": { 26 | "post_delay": 1000, 27 | "recognition": "OCR", 28 | "only_rec": true, 29 | "expected": "邮件", 30 | "roi": [ 31 | 131, 32 | 447, 33 | 39, 34 | 19 35 | ], 36 | "action": "Click" 37 | } 38 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Receive_Stamina.json: -------------------------------------------------------------------------------- 1 | { 2 | "领取体力": { 3 | "next": [ 4 | "补给包售罄" 5 | ], 6 | "interrupt": [ 7 | "领取补给包成功", 8 | "领取", 9 | "检查限购", 10 | "点击日常补给包", 11 | "点击补给包", 12 | "进入采购", 13 | "意外点击_主界面", 14 | "意外点击_皮肤卡池", 15 | "意外点击_涂装界面" 16 | ] 17 | }, 18 | "意外点击_涂装界面": { 19 | "post_delay": 2000, 20 | "recognition": "OCR", 21 | "roi": [ 22 | 847, 23 | 84, 24 | 110, 25 | 65 26 | ], 27 | "expected": "涂装", 28 | "next": [ 29 | "返回" 30 | ] 31 | }, 32 | "意外点击_皮肤卡池": { 33 | "post_delay": 2000, 34 | "recognition": "OCR", 35 | "roi": [ 36 | 93, 37 | 630, 38 | 158, 39 | 77 40 | ], 41 | "expected": "音量设置", 42 | "next": [ 43 | "返回" 44 | ] 45 | }, 46 | "补给包售罄": { 47 | "recognition": "OCR", 48 | "roi": [ 49 | 549, 50 | 247, 51 | 126, 52 | 83 53 | ], 54 | "expected": [ 55 | "已售罄", 56 | "已售馨" 57 | ], 58 | "next": [ 59 | "返回主菜单" 60 | ] 61 | }, 62 | "进入采购": { 63 | "post_delay": 1000, 64 | "recognition": "OCR", 65 | "roi": [ 66 | 975, 67 | 306, 68 | 75, 69 | 60 70 | ], 71 | "expected": "采购", 72 | "action": "Click" 73 | }, 74 | "点击补给包": { 75 | "recognition": "TemplateMatch", 76 | "roi": [ 77 | 441, 78 | 35, 79 | 217, 80 | 142 81 | ], 82 | "template": "领取体力/点击补给包_488_87_117_35__438_37_217_135.png", 83 | "action": "Click" 84 | }, 85 | "点击日常补给包": { 86 | "recognition": "TemplateMatch", 87 | "roi": [ 88 | 0, 89 | 198, 90 | 240, 91 | 149 92 | ], 93 | "template": "领取体力/点击日常补给包_21_248_127_45__0_198_227_145.png", 94 | "action": "Click" 95 | }, 96 | "检查限购": { 97 | "post_wait_freezes": 500, 98 | "recognition": "OCR", 99 | "roi": [ 100 | 349, 101 | 353, 102 | 129, 103 | 288 104 | ], 105 | "expected": [ 106 | "每周限购补给包", 107 | "每日血清补给包" 108 | ], 109 | "action": "Click" 110 | }, 111 | "领取": { 112 | "post_wait_freezes": 500, 113 | "recognition": "OCR", 114 | "roi": [ 115 | 1073, 116 | 632, 117 | 162, 118 | 60 119 | ], 120 | "expected": [ 121 | "免费", 122 | "购买", 123 | "免费购买" 124 | ], 125 | "action": "Click" 126 | }, 127 | "领取补给包成功": { 128 | "recognition": "OCR", 129 | "roi": [ 130 | 624, 131 | 220, 132 | 86, 133 | 57 134 | ], 135 | "expected": "奖励", 136 | "action": "Click", 137 | "target": [ 138 | 1, 139 | 0, 140 | 0, 141 | 0 142 | ] 143 | } 144 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Start_up.json: -------------------------------------------------------------------------------- 1 | { 2 | "启动": { 3 | "next": [ 4 | "关闭纷争战区通知", 5 | "关闭拟真围剿通知", 6 | "检查主界面" 7 | ], 8 | "interrupt": [ 9 | "关闭公告", 10 | "关闭奖励", 11 | "进入游戏", 12 | "更新", 13 | "关闭低内存提示", 14 | "打开应用", 15 | "意外点击_主界面" 16 | ] 17 | }, 18 | "关闭低内存提示": { 19 | "recognition": "OCR", 20 | "roi": [ 21 | 352, 22 | 277, 23 | 382, 24 | 42 25 | ], 26 | "expected": [ 27 | "设备", 28 | "当前", 29 | "内存", 30 | "低于" 31 | ], 32 | "action": "Click", 33 | "target": [ 34 | 779, 35 | 514, 36 | 1, 37 | 1 38 | ] 39 | }, 40 | "关闭拟真围剿通知": { 41 | "recognition": "OCR", 42 | "roi": [ 43 | 597, 44 | 275, 45 | 426, 46 | 60 47 | ], 48 | "expected": [ 49 | "拟真围剿", 50 | "行动", 51 | "完美达成" 52 | ], 53 | "action": "Click", 54 | "target": [ 55 | 10, 56 | 10, 57 | 0, 58 | 0 59 | ], 60 | "next": [ 61 | "启动" 62 | ] 63 | }, 64 | "关闭纷争战区通知": { 65 | "recognition": "OCR", 66 | "roi": [ 67 | 337, 68 | 370, 69 | 435, 70 | 60 71 | ], 72 | "expected": [ 73 | "纷争战区", 74 | "降级保护" 75 | ], 76 | "action": "Click", 77 | "target": [ 78 | 1194, 79 | 183, 80 | 11, 81 | 12 82 | ], 83 | "next": [ 84 | "启动" 85 | ] 86 | }, 87 | "更新": { 88 | "recognition": "OCR", 89 | "roi": [ 90 | 352, 91 | 248, 92 | 241, 93 | 42 94 | ], 95 | "expected": "检测到存在更新", 96 | "action": "Click", 97 | "target": [ 98 | 763, 99 | 517, 100 | 0, 101 | 0 102 | ] 103 | }, 104 | "进入游戏": { 105 | "recognition": "OCR", 106 | "roi": [ 107 | 24, 108 | 96, 109 | 71, 110 | 25 111 | ], 112 | "expected": [ 113 | "适龄", 114 | "提示" 115 | ], 116 | "target": [ 117 | 637, 118 | 645, 119 | 1, 120 | 1 121 | ], 122 | "action": "Click" 123 | }, 124 | "检查主界面": { 125 | "post_delay": 3000, 126 | "recognition": "OCR", 127 | "roi": [ 128 | 1074, 129 | 309, 130 | 95, 131 | 52 132 | ], 133 | "expected": "^战斗$", 134 | "next": [ 135 | "关闭纷争战区通知", 136 | "关闭拟真围剿通知", 137 | "检查主界面2", 138 | "启动" 139 | ] 140 | }, 141 | "关闭公告": { 142 | "recognition": "OCR", 143 | "expected": "点击空白处关闭", 144 | "action": "Click", 145 | "target": [ 146 | 10, 147 | 10, 148 | 0, 149 | 0 150 | ] 151 | }, 152 | "检查主界面2": { 153 | "recognition": "OCR", 154 | "roi": [ 155 | 1074, 156 | 309, 157 | 95, 158 | 52 159 | ], 160 | "expected": "^战斗$", 161 | "next": [ 162 | "切换主界面状态", 163 | "空任务" 164 | ] 165 | }, 166 | "打开应用": { 167 | "post_delay": 5000, 168 | "action": "StartApp", 169 | "package": "com.kurogame.haru.hero", 170 | "next": [ 171 | "黑屏计数", 172 | "空任务" 173 | ] 174 | }, 175 | "黑屏计数": { 176 | "recognition": "ColorMatch", 177 | "upper": [ 178 | 0, 179 | 0, 180 | 0 181 | ], 182 | "lower": [ 183 | 0, 184 | 0, 185 | 0 186 | ], 187 | "connected": true, 188 | "count": 90000, 189 | "action": "Custom", 190 | "custom_action": "Count", 191 | "custom_action_param": { 192 | "self": "黑屏计数", 193 | "count": 0, 194 | "target_count": 12, 195 | "next_node": [ 196 | "重启游戏" 197 | ] 198 | } 199 | }, 200 | "切换主界面状态": { 201 | "recognition": "TemplateMatch", 202 | "roi": [ 203 | 1165, 204 | 476, 205 | 77, 206 | 62 207 | ], 208 | "template": [ 209 | "启动/切换主界面状态_默认.png", 210 | "启动/切换主界面状态_家园.png", 211 | "启动/切换主界面状态_白梦游弋.png", 212 | "启动/切换主界面状态_离诗遗城.png", 213 | "启动/切换主界面状态_耀阳映画.png", 214 | "启动/切换主界面状态_花溪憩乡.png", 215 | "启动/切换主界面状态_银光教堂.png", 216 | "启动/切换主界面状态_闲庭疏影.png", 217 | "启动/切换主界面状态_鸣神叹妙.png", 218 | "启动/切换主界面状态_溺梦游歌.png" 219 | ], 220 | "action": "Click" 221 | }, 222 | "空任务": {}, 223 | "OCR": { 224 | "recognition": "OCR", 225 | "expected": "" 226 | } 227 | } -------------------------------------------------------------------------------- /assets/resource/base/pipeline/Stop_App.json: -------------------------------------------------------------------------------- 1 | { 2 | "停止": { 3 | "action": "StopApp", 4 | "package": "com.kurogame.haru.hero" 5 | } 6 | } -------------------------------------------------------------------------------- /assets/resource/bilibili/pipeline/bilibili.json: -------------------------------------------------------------------------------- 1 | { 2 | "打开应用": { 3 | "action": "StartApp", 4 | "package": "com.kurogame.haru.bilibili" 5 | }, 6 | "停止": { 7 | "action": "StopApp", 8 | "package": "com.kurogame.haru.bilibili" 9 | }, 10 | "重启游戏": { 11 | "action": "StopApp", 12 | "package": "com.kurogame.haru.bilibili", 13 | "next": [ 14 | "启动" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /assets/resource/bytedance/pipeline/bytedance.json: -------------------------------------------------------------------------------- 1 | { 2 | "打开应用": { 3 | "action": "StartApp", 4 | "package": "com.kurogame.haru.hero.bytedance.gamecenter" 5 | }, 6 | "停止": { 7 | "action": "StopApp", 8 | "package": "com.kurogame.haru.hero.bytedance.gamecenter" 9 | }, 10 | "重启游戏": { 11 | "action": "StopApp", 12 | "package": "com.kurogame.haru.hero.bytedance.gamecenter", 13 | "next": [ 14 | "启动" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /assets/resource/huawei/pipeline/huawei.json: -------------------------------------------------------------------------------- 1 | { 2 | "打开应用": { 3 | "action": "StartApp", 4 | "package": "com.kurogame.haru.huawei" 5 | }, 6 | "停止": { 7 | "action": "StopApp", 8 | "package": "com.kurogame.haru.huawei" 9 | }, 10 | "重启游戏": { 11 | "action": "StopApp", 12 | "package": "com.kurogame.haru.huawei", 13 | "next": [ 14 | "启动" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /assets/resource/mi/pipeline/mi.json: -------------------------------------------------------------------------------- 1 | { 2 | "打开应用": { 3 | "action": "StartApp", 4 | "package": "com.kurogame.haru.mi" 5 | }, 6 | "停止": { 7 | "action": "StopApp", 8 | "package": "com.kurogame.haru.mi" 9 | }, 10 | "重启游戏": { 11 | "action": "StopApp", 12 | "package": "com.kurogame.haru.mi", 13 | "next": [ 14 | "启动" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /assets/resource/oppo/pipeline/oppo.json: -------------------------------------------------------------------------------- 1 | { 2 | "打开应用": { 3 | "action": "StartApp", 4 | "package": "com.kurogame.haru.nearme.gamecenter" 5 | }, 6 | "停止": { 7 | "action": "StopApp", 8 | "package": "com.kurogame.haru.nearme.gamecenter" 9 | }, 10 | "重启游戏": { 11 | "action": "StopApp", 12 | "package": "com.kurogame.haru.nearme.gamecenter", 13 | "next": [ 14 | "启动" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /assets/resource/tencent/pipeline/Tencent.json: -------------------------------------------------------------------------------- 1 | { 2 | "打开应用": { 3 | "action": "StartApp", 4 | "package": "com.tencent.tmgp.kurogame.haru" 5 | }, 6 | "停止": { 7 | "action": "StopApp", 8 | "package": "com.tencent.tmgp.kurogame.haru" 9 | }, 10 | "重启游戏": { 11 | "action": "StopApp", 12 | "package": "com.tencent.tmgp.kurogame.haru", 13 | "next": [ 14 | "启动" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /assets/resource/vivo/pipeline/vivo.json: -------------------------------------------------------------------------------- 1 | { 2 | "打开应用": { 3 | "action": "StartApp", 4 | "package": "com.kurogame.haru.vivo" 5 | }, 6 | "停止": { 7 | "action": "StopApp", 8 | "package": "com.kurogame.haru.vivo" 9 | }, 10 | "重启游戏": { 11 | "action": "StopApp", 12 | "package": "com.kurogame.haru.vivo", 13 | "next": [ 14 | "启动" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /assets/resource/waydroid_base/pipeline/waydroid.json: -------------------------------------------------------------------------------- 1 | { 2 | "打开应用": { 3 | "action": "StartApp", 4 | "package": "com.kurogame.haru.hero --pct-syskeys 0" 5 | } 6 | } -------------------------------------------------------------------------------- /changelog-template.hbs: -------------------------------------------------------------------------------- 1 | {{#each releases}} 2 | # {{version}} 3 | 4 | {{#each groups}} 5 | ## {{title}} 6 | {{#each commits}} 7 | - {{message}} 8 | {{/each}} 9 | {{/each}} 10 | 11 | {{#if footer}} 12 | {{footer.replace '{tag}' version}} 13 | {{/if}} 14 | {{/each}} 15 | -------------------------------------------------------------------------------- /check_resource.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from typing import List 4 | from pathlib import Path 5 | 6 | from maa.resource import Resource 7 | from maa.tasker import Tasker, LoggingLevelEnum 8 | 9 | 10 | def check(dirs: List[Path]) -> bool: 11 | resource = Resource() 12 | 13 | print(f"Checking {len(dirs)} directories...") 14 | 15 | for dir in dirs: 16 | print(f"Checking {dir}...") 17 | status = resource.post_bundle(dir).wait().status 18 | if not status.succeeded: 19 | print(f"Failed to check {dir}.") 20 | return False 21 | 22 | print("All directories checked.") 23 | return True 24 | 25 | 26 | def main(): 27 | if len(sys.argv) < 2: 28 | print("Usage: python configure.py ") 29 | sys.exit(1) 30 | 31 | Tasker.set_stdout_level(LoggingLevelEnum.All) 32 | 33 | dirs = [Path(arg) for arg in sys.argv[1:]] 34 | if not check(dirs): 35 | sys.exit(1) 36 | 37 | 38 | if __name__ == "__main__": 39 | main() -------------------------------------------------------------------------------- /cliff.toml: -------------------------------------------------------------------------------- 1 | [remote.github] 2 | owner = "overflow65537" 3 | repo = "MAA_Punish" 4 | [changelog] 5 | # 尾部 6 | footer = """ 7 | 8 | 如果不知道该下载哪一个,[点击这里下载 Windows x86_64 版本](https://github.com/overflow65537/MAA_Punish/releases/download/{tag}/MPA-win-x86_64-{tag}.zip) 9 | [已有 Mirror酱 CDK?点击前往高速下载](https://mirrorchyan.com/zh/projects?rid=MAA_Punish) 10 | 11 | """ 12 | 13 | [git] 14 | # parse the commits based on https://www.conventionalcommits.org 15 | conventional_commits = true 16 | # filter out the commits that are not conventional 17 | filter_unconventional = true 18 | # process each line of a commit as an individual commit 19 | split_commits = false 20 | # regex for preprocessing the commit messages 21 | 22 | # regex for parsing and grouping commits 23 | commit_parsers = [ 24 | { message = "^feat", group = "新增 | Feat" }, 25 | { message = "^fix", group = "修复 | Fix" }, 26 | { message = "^docs", group = "文档 | Docs" }, 27 | { message = "^perf", group = "优化 | Perf" }, 28 | { message = "^refactor\\(clippy\\)", skip = true }, 29 | { message = "^refactor", group = "重构 | Refactor" }, 30 | { message = "^style", group = "样式 | Style" }, 31 | { message = "^test", group = "测试 | Test" }, 32 | { message = "^chore\\(release\\): prepare for", skip = true }, 33 | { message = "^chore\\(deps.*\\)", skip = true }, 34 | { message = "^chore\\(pr\\)", skip = true }, 35 | { message = "^chore\\(pull\\)", skip = true }, 36 | { message = "^chore\\(npm\\).*yarn\\.lock", skip = true }, 37 | { message = "^chore", group = "杂项 | Chore" }, 38 | { message = "^other", group = "其它 | Other" }, 39 | { message = "^ci", group = "集成 | CI" }, 40 | ] 41 | # protect breaking changes from being skipped due to matching a skipping commit_parser 42 | protect_breaking_commits = false 43 | # filter out the commits that are not matched by commit parsers 44 | filter_commits = false 45 | # regex for matching git tags 46 | tag_pattern = "v[0-9].*" 47 | # regex for skipping tags 48 | skip_tags = "beta|alpha" 49 | # regex for ignoring tags 50 | ignore_tags = "rc" 51 | # sort the tags topologically 52 | topo_order = false 53 | # sort the commits inside sections by oldest/newest order 54 | sort_commits = "newest" 55 | 56 | 57 | [template] 58 | file = "changelog-template.hbs" -------------------------------------------------------------------------------- /config/maa_option.json: -------------------------------------------------------------------------------- 1 | { 2 | "logging": true, 3 | "recording": false, 4 | "save_draw": false, 5 | "show_hit_draw": false, 6 | "stdout_level": 2 7 | } -------------------------------------------------------------------------------- /configure.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | import shutil 4 | 5 | assets_dir = Path(__file__).parent / "assets" 6 | 7 | 8 | def configure_ocr_model(): 9 | shutil.copytree( 10 | assets_dir / "MaaCommonAssets" / "OCR" / "ppocr_v4" / "zh_cn", 11 | assets_dir / "resource" / "base" / "model" / "ocr", 12 | dirs_exist_ok=True, 13 | ) 14 | 15 | 16 | if __name__ == "__main__": 17 | configure_ocr_model() 18 | -------------------------------------------------------------------------------- /deps/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /install.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import PyInstaller.__main__ 3 | import site 4 | import os 5 | 6 | import shutil 7 | import sys 8 | import json 9 | 10 | from configure import configure_ocr_model 11 | 12 | 13 | working_dir = Path(__file__).parent 14 | install_path = working_dir / Path("install") 15 | version = len(sys.argv) > 1 and sys.argv[1] or "v0.0.1" 16 | 17 | 18 | def bulid(): 19 | # 获取 site-packages 目录列表 20 | site_packages_paths = site.getsitepackages() 21 | 22 | # 查找包含 MaaAgentBinary 的路径 23 | maa_bin_path2 = None 24 | for path in site_packages_paths: 25 | potential_path = os.path.join(path, "MaaAgentBinary") 26 | if os.path.exists(potential_path): 27 | maa_bin_path2 = potential_path 28 | break 29 | 30 | if maa_bin_path2 is None: 31 | raise FileNotFoundError("not found MaaAgentBinary") 32 | 33 | # 构建 --add-data 参数 34 | add_data_param2 = f"{maa_bin_path2}{os.pathsep}MaaAgentBinary" 35 | 36 | command = [ 37 | "run_cli.py", 38 | "--name=install", 39 | f"--add-data={add_data_param2}", 40 | f"--distpath={working_dir}", 41 | "--clean", 42 | ] 43 | PyInstaller.__main__.run(command) 44 | 45 | if sys.platform == "win32": 46 | old_name = install_path / "install.exe" 47 | new_name = install_path / "maapicli.exe" 48 | old_name.rename(new_name) 49 | elif sys.platform == "darwin" or sys.platform == "linux": 50 | old_name = install_path / "install" 51 | new_name = install_path / "maapicli" 52 | old_name.rename(new_name) 53 | else: 54 | raise NotImplementedError("not supported platform") 55 | maa_bin_path = None 56 | for path in site_packages_paths: 57 | potential_path = os.path.join(path, "maa", "bin") 58 | if os.path.exists(potential_path): 59 | maa_bin_path = potential_path 60 | break 61 | 62 | if maa_bin_path is None: 63 | raise FileNotFoundError("not found maa/bin") 64 | shutil.copytree( 65 | maa_bin_path, 66 | install_path, 67 | dirs_exist_ok=True, 68 | ) 69 | 70 | 71 | def install_resource(): 72 | 73 | configure_ocr_model() 74 | 75 | shutil.copytree( 76 | working_dir / "assets" , 77 | install_path , 78 | dirs_exist_ok=True, 79 | ) 80 | shutil.rmtree(install_path / "MaaCommonAssets") 81 | 82 | with open(install_path / "interface.json", "r", encoding="utf-8") as f: 83 | interface = json.load(f) 84 | 85 | interface["version"] = version 86 | 87 | with open(install_path / "interface.json", "w", encoding="utf-8") as f: 88 | json.dump(interface, f, ensure_ascii=False, indent=4) 89 | 90 | 91 | def install_chores(): 92 | shutil.copy2( 93 | working_dir / "README.md", 94 | install_path, 95 | ) 96 | shutil.copy2( 97 | working_dir / "LICENSE", 98 | install_path, 99 | ) 100 | shutil.copy2( 101 | working_dir / "assets" / "custom" / "action" / "setting.json", 102 | install_path, 103 | ) 104 | 105 | 106 | if __name__ == "__main__": 107 | bulid() 108 | install_resource() 109 | install_chores() 110 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/overflow65537/MAA_Punish/13d914902eac754bf02ae3e9a00b3eb71e9bc7c9/logo.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | maafw >=2.4.0 2 | -------------------------------------------------------------------------------- /run_cli.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | if not os.path.exists("run_cli.py"): 5 | os.environ["MAAFW_BINARY_PATH"] = os.getcwd() 6 | 7 | from maa.toolkit import Toolkit 8 | 9 | from assets.custom.action.basics.CenterCamera import CenterCamera 10 | from assets.custom.action.basics.CombatActions import CombatActions 11 | from assets.custom.action.basics.Identify import Identify 12 | from assets.custom.action.basics.IdentifyRoles import IdentifyRoles 13 | from assets.custom.action.basics.MultiplayerAutoBattle import MultiplayerAutoBattle 14 | from assets.custom.action.basics.ResetIdentify import ResetIdentify 15 | from assets.custom.action.basics.ScreenShot import ScreenShot 16 | from assets.custom.action.basics.SetTower import SetTower 17 | from assets.custom.action.basics.Count import Count 18 | from assets.custom.action.basics.PPOverride import PPOverride 19 | from assets.custom.action.basics.ChainLoopCircuit import ChainLoopCircuit 20 | 21 | from assets.custom.action.exclusives.CrimsonWeave import CrimsonWeave 22 | from assets.custom.action.exclusives.LostLullaby import LostLullaby 23 | from assets.custom.action.exclusives.Oblivion import Oblivion 24 | from assets.custom.action.exclusives.Pyroath import Pyroath 25 | from assets.custom.action.exclusives.Stigmata import Stigmata 26 | from assets.custom.action.exclusives.Shukra import Shukra 27 | 28 | from assets.custom.recognition.exclusives.CalculateScore import CalculateScore 29 | from assets.custom.recognition.exclusives.IDFMembers import IDFMembers 30 | from assets.custom.recognition.exclusives.IDFscore import IDFscore 31 | from assets.custom.recognition.exclusives.IDFMasteryLevel import IDFMasteryLevel 32 | from assets.custom.recognition.exclusives.LogicalOperators import LOp 33 | 34 | print("如无必要,请使用MFW.exe运行") 35 | print("if not necessary, please use MFW.exe to run") 36 | 37 | 38 | def main(): 39 | print("开始注册自定义内容") 40 | # 注册自定义动作-角色战斗逻辑 41 | Toolkit.pi_register_custom_action("CrimsonWeave", CrimsonWeave()) # 深红囚影 42 | Toolkit.pi_register_custom_action("LostLullaby", LostLullaby()) # 深谣 43 | Toolkit.pi_register_custom_action("Oblivion", Oblivion()) # 终焉 44 | Toolkit.pi_register_custom_action("Pyroath", Pyroath()) # 誓焰 45 | Toolkit.pi_register_custom_action("Stigmata", Stigmata()) # 深痕 46 | Toolkit.pi_register_custom_action("Shukra", Shukra()) # 启明 47 | # 注册自定义动作-通用逻辑 48 | Toolkit.pi_register_custom_action("ScreenShot", ScreenShot()) # 错误截图 49 | Toolkit.pi_register_custom_action("Identify", Identify()) # 识别人物 50 | Toolkit.pi_register_custom_action("ResetIdentify", ResetIdentify()) # 重置识别 51 | Toolkit.pi_register_custom_action("CenterCamera", CenterCamera()) # 重置镜头 52 | Toolkit.pi_register_custom_action("IdentifyRoles", IdentifyRoles()) # 角色识别 53 | Toolkit.pi_register_custom_action( 54 | "MultiplayerAutoBattle", MultiplayerAutoBattle() 55 | ) # 多人战斗 56 | Toolkit.pi_register_custom_action("CombatActions", CombatActions()) # 通用角色战斗 57 | Toolkit.pi_register_custom_action("SetTower", SetTower()) # 设置塔 58 | Toolkit.pi_register_custom_action("Count", Count()) # 计数 59 | Toolkit.pi_register_custom_action("PPOverride", PPOverride()) # 覆写 60 | Toolkit.pi_register_custom_action( 61 | "ChainLoopCircuit", ChainLoopCircuit() 62 | ) # 链合回路 63 | # 注册自定义识别 64 | Toolkit.pi_register_custom_recognition( 65 | "CalculateScore", CalculateScore() 66 | ) # 计算分数 67 | Toolkit.pi_register_custom_recognition("IDFMembers", IDFMembers()) # 识别宿舍成员 68 | Toolkit.pi_register_custom_recognition("IDFscore", IDFscore()) # 识别分数 69 | Toolkit.pi_register_custom_recognition( 70 | "IDFMasteryLevel", IDFMasteryLevel() 71 | ) # 识别精通等级 72 | Toolkit.pi_register_custom_recognition("LOp", LOp()) # 逻辑识别器 73 | 74 | directly = "-d" in sys.argv 75 | Toolkit.pi_run_cli("./", "./", directly) 76 | 77 | 78 | if __name__ == "__main__": 79 | main() 80 | --------------------------------------------------------------------------------