Skip to content

Commit f44e8e1

Browse files
committed
feat: 御魂副本 & 部分用户界面
1 parent 262b092 commit f44e8e1

10 files changed

Lines changed: 190 additions & 18 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,4 @@ test.*
164164
/cache/
165165

166166
main.exe
167+
*.zip

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
### 阴阳师脚本
22

3+
暂时仅支持mumu模拟器,可以通过标准的ip+端口连结任何可以访问的安卓设备。
4+
5+
使用adb-shell,使用adb标准api通过tcp连接到安卓设备,实现截图、虚拟点击等核心功能。
6+
7+
使用opencv的模板匹配模块检测截图中的目标图像位置,在找到目标后进行虚拟点击。
8+
39
#### 目前实现:
410

511
* 基本操作
6-
* 业原火自动demo
12+
* 业原火
13+
* 组队御魂副本
714

815
#### todo
916

1017
##### 更多功能:
1118

12-
* [ ] 御魂副本
1319
* [ ] 探索副本
20+
* [ ] 活动副本
1421

1522
##### 用户友好
1623

logger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def format(self, record):
4444
console_handler.setLevel(logging.DEBUG)
4545

4646
# create formatter with datefmt and add it to the handler
47-
formatter = ColoredFormatter(datefmt='%Y-%m-%d %H:%M:%S')
47+
formatter = ColoredFormatter(datefmt='%H:%M:%S')
4848
console_handler.setFormatter(formatter)
4949

5050
# add the handler to the logger

main.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,17 @@
88

99
from logger import logger
1010

11-
from connector import ConnectorPool
12-
from player import CVPlayer
11+
from performer import scripts
12+
from performer.performer import Performer
13+
14+
from InquirerPy import inquirer
15+
from InquirerPy.base.control import Choice
16+
17+
performer:Performer = inquirer.select(
18+
message="Select a script",
19+
choices=[Choice(value=script,name=script.description) for script in scripts]
20+
).execute()(logger=logger)
21+
22+
performer.run()
1323

14-
connect_pool = ConnectorPool(logger)
15-
connect_pool.add_connector('Mumu', '127.0.0.1', 16384).connect()
16-
player = CVPlayer()
17-
while True:
18-
current_connector = connect_pool.get_current_connector()
19-
screenshot = current_connector.screen_shot()
20-
target_list = ['wanted\\refuse.jpg','wanted\\yyh_begin.jpg', 'wanted\\yys_jieshu.jpg', 'wanted\\yys_jixu.jpg']
21-
for target in target_list:
22-
location = player.locate(target, screenshot)
23-
if location:
24-
logger.info(f'Found {target} at {location}')
25-
current_connector.touch(*location)
2624

performer/YH.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from .performer import Performer
2+
3+
class MultiYHPerformer(Performer):
4+
description = '组队御魂副本(魂十、魂土、魂王等)'
5+
'''多人御魂'''
6+
def __init__(self,**kwargs):
7+
super().__init__(**kwargs)
8+
9+
def main_step(self):
10+
target_list = ['refuse.jpg','yys_begin.jpg', 'yys_jieshu.jpg', 'yys_jixu.jpg']
11+
self.find_and_touch(target_list)

performer/YYH.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from .performer import Performer
2+
3+
class YYHPerformer(Performer):
4+
description = '业原火副本'
5+
'''业原火'''
6+
def __init__(self,**kwargs):
7+
super().__init__(**kwargs)
8+
9+
def main_step(self):
10+
target_list = ['refuse.jpg','yyh_begin.jpg', 'yys_jieshu.jpg', 'yys_jixu.jpg']
11+
self.find_and_touch(target_list)

performer/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from .YYH import YYHPerformer
2+
from .YH import MultiYHPerformer
3+
4+
scripts:list = [YYHPerformer, MultiYHPerformer]

performer/performer.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
'''
2+
Author: tbjuechen
3+
Date: 2024-08-13
4+
Version: 1.0
5+
Description: performer class
6+
License: MIT
7+
'''
8+
import os
9+
import time
10+
from logging import Logger
11+
from abc import abstractmethod
12+
from typing import Type, List
13+
14+
from connector import ConnectorPool
15+
from connector.connector.base import BaseConnector
16+
from player.base import BasePlayer
17+
from player import CVPlayer
18+
from .utils import is_valid_ip
19+
20+
from InquirerPy import inquirer
21+
22+
class Performer:
23+
'''Performer class
24+
25+
Attributes
26+
----------
27+
connect_pool : ConnectorPool
28+
The connector pool
29+
30+
player : BasePlayer
31+
The player
32+
'''
33+
def __init__(self,
34+
logger:Logger,
35+
connCls:Type[ConnectorPool]=ConnectorPool,
36+
playerCls:Type[BasePlayer]=CVPlayer) -> None:
37+
self.logger = logger
38+
self.connect_pool = connCls()
39+
self.player = playerCls()
40+
self.init_env()
41+
self.time_dleta = inquirer.text(
42+
message="Enter the time delta (seconds):",
43+
default='1',
44+
validate=lambda x: x.isdecimal() and float(x) > 0,
45+
invalid_message='Invalid time delta!!!'
46+
).execute()
47+
48+
def init_env(self):
49+
# set the path
50+
wanted_path = os.path.join(os.getcwd(), 'wanted')
51+
os.environ['PATH'] += os.pathsep + wanted_path
52+
self.logger.debug(f'Add wanted path: {wanted_path}')
53+
54+
def add_connector(self) -> None:
55+
'''interact add connector to the pool
56+
'''
57+
flag:bool = True # flag to control the loop
58+
while flag:
59+
ConnectorType:str = inquirer.select(
60+
message="Select a connector type (mumu only for now)",
61+
choices=['Mumu', 'Nox', 'BlueStacks', 'Others'],
62+
).execute()
63+
ConnectorHost:str = inquirer.text(
64+
message="Enter the connector host:",
65+
default='127.0.0.1',
66+
validate=is_valid_ip,
67+
invalid_message='Invalid ip address!!!'
68+
).execute()
69+
ConnectorPort:int = inquirer.text(
70+
message="Enter the connector port:",
71+
default='16384' if ConnectorType == 'Mumu' else '7777',
72+
validate=lambda x: x.isdigit() and int(x) in range(65536),
73+
invalid_message='Invalid port number!!!'
74+
).execute()
75+
self.connect_pool.add_connector(ConnectorType, ConnectorHost, ConnectorPort).connect()
76+
flag = inquirer.confirm(
77+
message='Add another connector?',
78+
default=False
79+
).execute()
80+
81+
def find_and_touch(self, target_list:List[str], connector:BaseConnector=None) -> None:
82+
'''Find and touch the target in the screenshot
83+
84+
Parameters
85+
----------
86+
target_list : List[str]
87+
The list of target image files
88+
89+
connector : BaseConnector
90+
The connector to use, if None, use the current connector
91+
'''
92+
# use the current connector from pool
93+
connector = connector if connector else self.connect_pool.get_current_connector()
94+
screenshot:str = connector.screen_shot()
95+
for target in target_list:
96+
location = self.player.locate(target, screenshot)
97+
if location:
98+
self.logger.info(f'Found {target} at {location}')
99+
connector.touch(*location)
100+
101+
@abstractmethod
102+
def main_step(self):
103+
'''Main steps for the performer
104+
'''
105+
pass
106+
107+
def run(self) -> None:
108+
'''Run the script with preset steps
109+
'''
110+
self.add_connector()
111+
while True:
112+
self.main_step()
113+
self.logger.debug(f'Sleep for {self.time_dleta} seconds')
114+
time.sleep(self.time_dleta)

performer/utils.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'''
2+
Author: tbjuechen
3+
Date: 2024-08-13
4+
Version: 1.0
5+
Description: utility functions
6+
'''
7+
8+
import re
9+
10+
# is ip address
11+
IP_ADRESS_PATTERN = r'\b(?:(?:2[0-4][0-9]|25[0-5]|1[0-9]{2}|[1-9]?[0-9])\.){3}(?:2[0-4][0-9]|25[0-5]|1[0-9]{2}|[1-9]?[0-9])\b'
12+
13+
def is_valid_ip(ip:str)->bool:
14+
'''Check if the ip address is valid
15+
16+
Parameters
17+
----------
18+
ip : str
19+
The ip address
20+
21+
Returns
22+
-------
23+
bool
24+
Whether the ip address is valid
25+
'''
26+
return bool(re.match(IP_ADRESS_PATTERN, ip))

player/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class BasePlayer(ABC):
1616
acc : float
1717
The accuracy of the player model
1818
'''
19-
def __init__(self, acc:float, **kwargs):
19+
def __init__(self, acc:float=0.8, **kwargs):
2020
self.acc = acc
2121

2222
@abstractmethod

0 commit comments

Comments
 (0)