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