diff --git a/README.md b/README.md index 9951499..3472bcf 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,15 @@ - 模拟器分辨率设置为 平板版-1280x720(DPI240),帧率设置60帧 - 游戏设置为 画质档位:省电模式,帧率:60,UI布局:触屏,镜头灵敏度:5,镜头自动跟随转动:关闭,棋盘镜头移动速度:1,游戏语言:简体中文 -# 饼 +## 请严格遵照上述游戏设置 ### v0.1 -- [ ] 能跑 -- [ ] 搞定多点触控(战斗模块刚需) -- [ ] 拿命验收自动化 +- [x] 能跑 +- [x] 搞定多点触控(战斗模块刚需) +- [x] 拿命验收自动化(1号位手动上一个妮可或比利) + +# 饼 ### v0.2 - [ ] 零号空洞自动化 +- [ ] 降低CPU利用率,再跑下去赚的丁尼就真不够交电费了 \ No newline at end of file diff --git a/assets/config/maa_pi_config.json b/assets/config/maa_pi_config.json new file mode 100644 index 0000000..fb53575 --- /dev/null +++ b/assets/config/maa_pi_config.json @@ -0,0 +1,26 @@ +{ + "controller": { + "name": "安卓端", + "type": "Adb" + }, + "adb": { + "adb_path": "C:/1software/MuMu Player 12/shell/adb.exe", + "address": "127.0.0.1:16384", + "config": { + "extras": { + "mumu": { + "enable": true, + "index": 0, + "path": "C:/1software/MuMu Player 12" + } + } + } + }, + "resource": "官服", + "task": [ + { + "name": "刷丁尼", + "option": [] + } + ] +} \ No newline at end of file diff --git a/assets/interface.json b/assets/interface.json index bd481ae..169831e 100644 --- a/assets/interface.json +++ b/assets/interface.json @@ -3,15 +3,6 @@ { "name": "安卓端", "type": "Adb" - }, - { - "name": "桌面端", - "type": "Win32", - "win32": { - "method": "Search", - "class_name": ".*", - "window_name": "Visual Studio" - } } ], "resource": [ @@ -20,56 +11,12 @@ "path": [ "{PROJECT_DIR}/resource/base" ] - }, - { - "name": "B 服", - "path": [ - "{PROJECT_DIR}/resource/base", - "{PROJECT_DIR}/resource/bilibili" - ] } ], "task": [ { - "name": "普通任务", - "entry": "MyTask1" - }, - { - "name": "选项任务", - "entry": "MyTask2", - "option": [ - "任务选项1" - ] - }, - { - "name": "参数任务", - "entry": "MyTask3", - "option": [ - "任务选项1" - ], - "param": {} - } - ], - "option": { - "任务选项1": { - "cases": [ - { - "name": "文本1", - "param": { - "OcrTask": { - "text": "文本1" - } - } - }, - { - "name": "文本2", - "param": { - "OcrTask": { - "text": "文本2" - } - } - } - ] + "name": "刷丁尼", + "entry": "界面检测" } - } -} + ] +} \ No newline at end of file diff --git a/assets/resource/base/image/BAT_bili__113_48_78_32__63_0_178_130.png b/assets/resource/base/image/BAT_bili__113_48_78_32__63_0_178_130.png new file mode 100644 index 0000000..fe253cd Binary files /dev/null and b/assets/resource/base/image/BAT_bili__113_48_78_32__63_0_178_130.png differ diff --git a/assets/resource/base/image/BAT_chat__884_428_23_25__834_378_123_125.png b/assets/resource/base/image/BAT_chat__884_428_23_25__834_378_123_125.png new file mode 100644 index 0000000..2ffc027 Binary files /dev/null and b/assets/resource/base/image/BAT_chat__884_428_23_25__834_378_123_125.png differ diff --git a/assets/resource/base/image/BAT_chat_bg__547_461_181_73__497_411_281_173.png b/assets/resource/base/image/BAT_chat_bg__547_461_181_73__497_411_281_173.png new file mode 100644 index 0000000..bc31b51 Binary files /dev/null and b/assets/resource/base/image/BAT_chat_bg__547_461_181_73__497_411_281_173.png differ diff --git a/assets/resource/base/image/BAT_logo1__57_62_33_25__7_12_133_125.png b/assets/resource/base/image/BAT_logo1__57_62_33_25__7_12_133_125.png new file mode 100644 index 0000000..f39f4fb Binary files /dev/null and b/assets/resource/base/image/BAT_logo1__57_62_33_25__7_12_133_125.png differ diff --git a/assets/resource/base/image/BAT_niko__111_43_82_39__61_0_182_132.png b/assets/resource/base/image/BAT_niko__111_43_82_39__61_0_182_132.png new file mode 100644 index 0000000..ecb2f78 Binary files /dev/null and b/assets/resource/base/image/BAT_niko__111_43_82_39__61_0_182_132.png differ diff --git a/assets/resource/base/image/BAT_restart_btn__719_664_26_26__669_614_126_106.png b/assets/resource/base/image/BAT_restart_btn__719_664_26_26__669_614_126_106.png new file mode 100644 index 0000000..3ddf432 Binary files /dev/null and b/assets/resource/base/image/BAT_restart_btn__719_664_26_26__669_614_126_106.png differ diff --git a/assets/resource/base/image/BW_menu__78_41_63_43__28_0_163_134.png b/assets/resource/base/image/BW_menu__78_41_63_43__28_0_163_134.png new file mode 100644 index 0000000..b2a21e6 Binary files /dev/null and b/assets/resource/base/image/BW_menu__78_41_63_43__28_0_163_134.png differ diff --git a/assets/resource/base/image/HDD_logo1__816_26_35_34__766_0_135_110.png b/assets/resource/base/image/HDD_logo1__816_26_35_34__766_0_135_110.png new file mode 100644 index 0000000..f969cb9 Binary files /dev/null and b/assets/resource/base/image/HDD_logo1__816_26_35_34__766_0_135_110.png differ diff --git a/assets/resource/base/image/MAP_staff__168_593_201_62__118_543_301_162.png b/assets/resource/base/image/MAP_staff__168_593_201_62__118_543_301_162.png new file mode 100644 index 0000000..37a5716 Binary files /dev/null and b/assets/resource/base/image/MAP_staff__168_593_201_62__118_543_301_162.png differ diff --git a/assets/resource/base/image/empty.png b/assets/resource/base/image/empty.png deleted file mode 100644 index 8b13789..0000000 --- a/assets/resource/base/image/empty.png +++ /dev/null @@ -1 +0,0 @@ - diff --git a/assets/resource/base/pipeline/my_task.json b/assets/resource/base/pipeline/my_task.json index 581eaa8..339c006 100644 --- a/assets/resource/base/pipeline/my_task.json +++ b/assets/resource/base/pipeline/my_task.json @@ -1,5 +1,585 @@ { - "MyTask1": {}, - "MyTask2": {}, - "MyTask3": {} + "界面检测": { + "next": [ + "HDD菜单逻辑", + "在大世界", + "休息了一下1", + "休息了一下2", + "界面检测间隔" + ] + }, + "界面检测间隔": { + "next": "界面检测", + "post_delay": 1000 + }, + "休息了一下1": { + "recognition": "OCR", + "roi": [ + 408, + 577.5, + 444, + 38 + ], + "expected": "[总觉得有些累了还是先舒服地休息了一下吧]{4,}", + "action": "Click", + "next": [ + "休息了一下1", + "休息了一下2", + "界面检测" + ], + "post_delay": 2000 + }, + "休息了一下2": { + "recognition": "OCR", + "roi": [ + 392, + 350.5, + 484, + 39 + ], + "expected": "[总觉得有些累了还是先舒服地休息了一下吧]{4,}", + "action": "Click", + "next": [ + "休息了一下2", + "界面检测" + ], + "post_delay": 2000 + }, + "在大世界": { + "recognition": "TemplateMatch", + "roi": [ + 28, + 0, + 163, + 134 + ], + "template": "BW_menu__78_41_63_43__28_0_163_134.png", + "action": "Click", + "target": [ + 1105, + 401, + 43, + 39 + ], + "next": [ + "进入档案架", + "在地图" + ] + }, + "在地图": { + "recognition": "OCR", + "roi": [ + 1062, + 22, + 130, + 45 + ], + "expected": "[街区]", + "next": [ + "进入档案架", + "在地图" + ], + "action": "Swipe", + "begin": [ + 943, + 239, + 16, + 83 + ], + "end": [ + 624, + 242.5, + 30, + 86 + ] + }, + "进入档案架": { + "recognition": "TemplateMatch", + "roi": [ + 118, + 543, + 301, + 162 + ], + "template": "MAP_staff__168_593_201_62__118_543_301_162.png", + "action": "Click", + "target": true, + "next": [ + "传送确认" + ] + }, + "传送确认": { + "recognition": "OCR", + "roi": [ + 515, + 316.5, + 242, + 60 + ], + "expected": "[传送至该地点]{2,}", + "action": "Click", + "target": [ + 718, + 419.5, + 132, + 29 + ], + "next": "走到HDD", + "post_delay": 3000 + }, + "走到HDD": { + "recognition": "OCR", + "roi": [ + 627, + 110.5, + 189, + 75 + ], + "expected": "[影像档案架]{2,}", + "action": "Swipe", + "begin": [ + 232, + 579.5, + 13, + 34 + ], + "end": [ + 300, + 688.5, + 19, + 23 + ], + "duration": 850, + "next": "走到HDD2" + }, + "走到HDD2": { + "action": "Swipe", + "begin": [ + 244, + 570.5, + 34, + 14 + ], + "end": [ + 462, + 569.5, + 34, + 14 + ], + "duration": 1800, + "next": "拖拽视角朝向HDD" + }, + "拖拽视角朝向HDD": { + "action": "Swipe", + "begin": [ + 640, + 333.5, + 34, + 32 + ], + "end": [ + 789, + 244.5, + 38, + 36 + ], + "duration": 1500, + "next": [ + "进入HDD系统", + "界面检测" + ] + }, + "进入HDD系统": { + "recognition": "OCR", + "roi": [ + 425, + 8.5, + 406, + 277 + ], + "expected": "[空洞深潜系统]{2,}", + "action": "Click", + "target": [ + 999, + 561.5, + 62, + 52 + ], + "post_delay": 1500, + "next": [ + "HDD菜单逻辑" + ] + }, + "HDD菜单逻辑": { + "recognition": "TemplateMatch", + "roi": [ + 766, + 0, + 135, + 110 + ], + "template": "HDD_logo1__816_26_35_34__766_0_135_110.png", + "next": [ + "在第二章间章", + "选择章节1" + ] + }, + "选择章节1": { + "action": "Click", + "target": [ + 983, + 36.5, + 117, + 16 + ], + "next": "选择章节2" + }, + "选择章节2": { + "action": "Click", + "target": [ + 960, + 208.5, + 142, + 22 + ], + "next": [ + "HDD菜单逻辑", + "界面检测" + ], + "post_delay": 5000 + }, + "在第二章间章": { + "recognition": "OCR", + "roi": [ + 999, + 15, + 69, + 52 + ], + "expected": "[间]", + "action": "Click", + "target": [ + 556, + 443, + 97, + 67 + ], + "next": [ + "列表下滑" + ], + "timeout": 5000 + }, + "列表下滑": { + "recognition": "OCR", + "roi": [ + 814, + 657, + 104, + 46 + ], + "expected": "[委托]", + "pre_delay": 1500, + "action": "Swipe", + "begin": [ + 874, + 526, + 149, + 37 + ], + "end": [ + 857, + 153, + 153, + 31 + ], + "duration": 400, + "next": [ + "选择拿命验收" + ], + "timeout": 5000 + }, + "选择拿命验收": { + "recognition": "OCR", + "roi": [ + 627, + 92, + 611, + 517 + ], + "order_by": "Vertical", + "index": 0, + "expected": "收", + "action": "Click", + "target": true, + "next": [ + "点击下一步" + ], + "timeout": 5000 + }, + "点击下一步": { + "action": "Click", + "target": [ + 1039, + 669, + 142, + 21 + ], + "next": [ + "点击出战" + ], + "timeout": 5000 + }, + "点击出战": { + "recognition": "OCR", + "roi": [ + 1050, + 642, + 144, + 66 + ], + "expected": "[出战]", + "action": "Click", + "target": true, + "next": [ + "战斗逻辑" + ], + "post_delay": 8000, + "timeout": 60000 + }, + "战斗逻辑": { + "recognition": "TemplateMatch", + "roi": [ + 7, + 12, + 133, + 125 + ], + "template": "BAT_logo1__57_62_33_25__7_12_133_125.png", + "threshold": 0.95, + "next": [ + "战斗结束", + "妮可操作", + "比利操作", + "其他人操作" + ] + }, + "比利操作": { + "recognition": "TemplateMatch", + "roi": [ + 57, + 14, + 168, + 102 + ], + "template": "BAT_bili__113_48_78_32__63_0_178_130.png", + "action": "Custom", + "custom_action": "NikoAttack", + "next": "战斗逻辑", + "post_delay": 500 + }, + "妮可操作": { + "recognition": "TemplateMatch", + "roi": [ + 57, + 14, + 168, + 102 + ], + "template": "BAT_niko__111_43_82_39__61_0_182_132.png", + "action": "Custom", + "custom_action": "NikoAttack", + "next": "战斗逻辑", + "post_delay": 500 + }, + "其他人操作": { + "action": "Click", + "target": [ + 1102, + 507.5, + 48, + 43 + ], + "next": "战斗逻辑", + "post_delay": 500 + }, + "战斗结束": { + "recognition": "OCR", + "roi": [ + 925, + 116, + 232, + 138 + ], + "expected": "80/", + "action": "Swipe", + "begin": [ + 231, + 569.5, + 16, + 19 + ], + "end": [ + 346, + 387.5, + 23, + 27 + ], + "duration": 4900, + "post_delay": 0, + "next": "战斗结束2" + }, + "战斗结束2": { + "action": "Swipe", + "begin": [ + 231, + 569.5, + 16, + 19 + ], + "end": [ + 425, + 619.5, + 26, + 18 + ], + "duration": 1100, + "next": [ + "对话高坂" + ], + "timeout": 3000, + "pre_delay": 0, + "timeout_next": "重开战斗" + }, + "对话高坂": { + "recognition": "OCR", + "roi": [ + 669, + 75, + 234, + 321 + ], + "expected": "[高坂建设]", + "action": "Click", + "target": [ + 1003, + 566.5, + 56, + 44 + ], + "next": "对话高坂2" + }, + "对话高坂2": { + "recognition": "TemplateMatch", + "roi": [ + 497, + 411, + 281, + 173 + ], + "template": "BAT_chat_bg__547_461_181_73__497_411_281_173.png", + "threshold": 0.9, + "green_mask": true, + "action": "Click", + "target": [ + 1043, + 603.5, + 57, + 69 + ], + "next": [ + "战斗结算", + "对话高坂3", + "对话高坂2" + ] + }, + "对话高坂3": { + "recognition": "TemplateMatch", + "roi": [ + 842, + 316.5, + 93, + 171 + ], + "template": "BAT_chat__884_428_23_25__834_378_123_125.png", + "action": "Click", + "next": [ + "对话高坂2" + ] + }, + "战斗结算": { + "recognition": "OCR", + "roi": [ + 1061, + 662.5, + 76, + 31 + ], + "expected": "[完成]", + "action": "Click", + "post_delay": 1000, + "next": [ + "战斗结算", + "界面检测" + ], + "timeout": 30000 + }, + "重开战斗": { + "recognition": "TemplateMatch", + "roi": [ + 7, + 12, + 133, + 125 + ], + "template": "BAT_logo1__57_62_33_25__7_12_133_125.png", + "threshold": 0.95, + "action": "Click", + "target": [ + 70, + 56.5, + 14, + 15 + ], + "next": [ + "重开战斗2", + "重开战斗3" + ] + }, + "重开战斗2": { + "recognition": "TemplateMatch", + "roi": [ + 669, + 614, + 126, + 106 + ], + "template": "BAT_restart_btn__719_664_26_26__669_614_126_106.png", + "action": "Click", + "next": [ + "重开战斗2", + "重开战斗3" + ] + }, + "重开战斗3": { + "recognition": "OCR", + "roi": [ + 511, + 322, + 246, + 54 + ], + "expected": "[重新开始战斗]{3,}", + "action": "Click", + "target": [ + 675, + 418.5, + 171, + 29 + ], + "next": [ + "战斗逻辑" + ], + "post_delay": 8000, + "timeout": 60000 + } } \ No newline at end of file diff --git a/config/maa_option.json b/config/maa_option.json new file mode 100644 index 0000000..20ea9f8 --- /dev/null +++ b/config/maa_option.json @@ -0,0 +1,7 @@ +{ + "logging": true, + "recording": false, + "save_draw": false, + "show_hit_draw": false, + "stdout_level": 2 +} \ No newline at end of file diff --git a/src/config/maa_option.json b/src/config/maa_option.json new file mode 100644 index 0000000..20ea9f8 --- /dev/null +++ b/src/config/maa_option.json @@ -0,0 +1,7 @@ +{ + "logging": true, + "recording": false, + "save_draw": false, + "show_hit_draw": false, + "stdout_level": 2 +} \ No newline at end of file diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..aa327bc --- /dev/null +++ b/src/main.py @@ -0,0 +1,96 @@ +# -*- coding: UTF-8 -*- +from typing import Tuple + +# python -m pip install maafw +from maa.define import RectType +from maa.resource import Resource +from maa.controller import AdbController +from maa.instance import Instance +from maa.toolkit import Toolkit + +from maa.custom_recognizer import CustomRecognizer +from maa.custom_action import CustomAction + +import asyncio +import time + +import sys + +async def main(): + user_path = "./" + Toolkit.init_option(user_path) + + resource = Resource() + await resource.load("./assets/resource/base") + + device_list = await Toolkit.adb_devices() + if not device_list: + print("No ADB device found.") + exit() + + # for demo, we just use the first device + device = device_list[0] + controller = AdbController( + adb_path=device.adb_path, + address=device.address, + ) + await controller.connect() + + maa_inst = Instance() + maa_inst.bind(resource, controller) + + if not maa_inst.inited: + print("Failed to init MAA.") + exit() + + # maa_inst.register_recognizer("MyRec", my_rec) + maa_inst.register_action("NikoAttack", NikoAttack) + + print("ZZZ!启动!") + print("队伍1号位建议上妮可,用比利步子迈大了可能定位会歪,2号位上一个跑得快的") + + await maa_inst.run_task("界面检测") + + +# class MyRecognizer(CustomRecognizer): +# def analyze( +# self, context, image, task_name, custom_param +# ) -> Tuple[bool, RectType, str]: +# return True, (0, 0, 100, 100), "Hello World!" + + +class NikoAttack(CustomAction): + def run(self, context, task_name, custom_param, box, rec_detail) -> bool: + # 前进 + context.touch_down(0,233,576,50) + for i in range(576,440,-1): + context.touch_move(0,233,i,50) + time.sleep(0.001) + # 闪避 + context.touch_down(1,1119,636,50) + time.sleep(0.05) + context.touch_up(1) + time.sleep(0.05) + # 攻击 + context.touch_down(1,1024,576,50) + time.sleep(0.05) + context.touch_up(1) + time.sleep(0.05) + # 切人 + context.touch_down(1,1118,527,50) + time.sleep(0.05) + context.touch_up(1) + time.sleep(0.05) + context.touch_up(0) + return True + + def stop(self) -> None: + pass + + +# my_rec = MyRecognizer() +NikoAttack = NikoAttack() + + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/start.bat b/start.bat new file mode 100644 index 0000000..31ee59c --- /dev/null +++ b/start.bat @@ -0,0 +1,5 @@ +@echo off +echo 好像有问题? +cd src +python main.py +pause \ No newline at end of file