Skip to content

Commit

Permalink
Merge branch 'release/2.1.5' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
Konano committed Aug 1, 2022
2 parents b52f980 + bcc5213 commit e0d14dd
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 62 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ arknights-mower shop 招聘许可 赤金 龙门币
# 在商场使用信用点消费,购买物品的优先级从高到低分别是招聘许可、赤金和龙门币,其余物品不购买
arknights-mower base -f12 plan_2
# 自动使用菲亚梅塔恢复B102房间心情最差干员的心情,并保持原位;自动进行名为`plan_2`的的基建排班(排班功能须搭配配置文件使用)
arknights-mower base -c -d33 -f12
arknights-mower base -c -d33
# 自动收取基建中的信赖/货物/订单;自动放置线索;自动前往 B303 房间(地下 3 层从左往右数第 3 间)使用无人机加速生产或贸易订单;
```

Expand Down
2 changes: 1 addition & 1 deletion arknights_mower/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
__cli__ = not (__pyinstall__ and not sys.argv[1:])

__system__ = platform.system().lower()
__version__ = '2.1.4'
__version__ = '2.1.5'
3 changes: 3 additions & 0 deletions arknights_mower/data/agent.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
"特米米",
"天火",
"惊蛰",
"星源",
"蜜蜡",
"莱恩哈特",
"薄绿",
Expand Down Expand Up @@ -152,6 +153,7 @@
"安哲拉",
"熔泉",
"埃拉托",
"承曦格雷伊",
"崖心",
"雪雉",
"初雪",
Expand Down Expand Up @@ -209,6 +211,7 @@
"歌蕾蒂娅",
"水月",
"归溟幽灵鲨",
"多萝西",
"闪灵",
"夜莺",
"凯尔希",
Expand Down
54 changes: 54 additions & 0 deletions arknights_mower/data/level.json
Original file line number Diff line number Diff line change
Expand Up @@ -2056,5 +2056,59 @@
"ap_cost": 18,
"code": "WR-10",
"name": ""
},
"DH-1": {
"zone_id": "permanent_sidestory_9_Dossoles_Holiday",
"ap_cost": 9,
"code": "DH-1",
"name": "意外入选"
},
"DH-2": {
"zone_id": "permanent_sidestory_9_Dossoles_Holiday",
"ap_cost": 9,
"code": "DH-2",
"name": "首轮竞赛"
},
"DH-3": {
"zone_id": "permanent_sidestory_9_Dossoles_Holiday",
"ap_cost": 9,
"code": "DH-3",
"name": "拔铳相助"
},
"DH-4": {
"zone_id": "permanent_sidestory_9_Dossoles_Holiday",
"ap_cost": 12,
"code": "DH-4",
"name": "铁人三项"
},
"DH-5": {
"zone_id": "permanent_sidestory_9_Dossoles_Holiday",
"ap_cost": 12,
"code": "DH-5",
"name": "曲径求胜"
},
"DH-6": {
"zone_id": "permanent_sidestory_9_Dossoles_Holiday",
"ap_cost": 12,
"code": "DH-6",
"name": "紧追猛赶"
},
"DH-7": {
"zone_id": "permanent_sidestory_9_Dossoles_Holiday",
"ap_cost": 18,
"code": "DH-7",
"name": "沙滩阻击"
},
"DH-8": {
"zone_id": "permanent_sidestory_9_Dossoles_Holiday",
"ap_cost": 18,
"code": "DH-8",
"name": "抢滩登陆"
},
"DH-9": {
"zone_id": "permanent_sidestory_9_Dossoles_Holiday",
"ap_cost": 18,
"code": "DH-9",
"name": "鼠胆龙威"
}
}
6 changes: 6 additions & 0 deletions arknights_mower/data/zone.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,5 +190,11 @@
"name": "画中人",
"chapterIndex": null,
"zoneIndex": 8
},
"permanent_sidestory_9_Dossoles_Holiday": {
"type": "SIDESTORY",
"name": "多索雷斯假日",
"chapterIndex": null,
"zoneIndex": 9
}
}
Binary file modified arknights_mower/fonts/SourceHanSansSC-Bold.otf
Binary file not shown.
38 changes: 1 addition & 37 deletions arknights_mower/ocr/__init__.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,4 @@
from ..data import ocr_error
from ..utils import config
from ..utils.log import logger
from .model import OcrHandle
from .ocrspace import API, Language
from .rectify import ocr_rectify

ocrhandle = OcrHandle()


def ocr_rectify(img, pre, valid, text=''):
"""
调用在线 OCR 校正本地 OCR 得到的错误结果,并返回校正后的识别结果
若在线 OCR 依旧无法正确识别则返回 None
:param img: numpy.array, 图像
:param pre: (str, tuple), 本地 OCR 得到的错误结果,包括字符串和范围
:param valid: list[str], 期望得到的识别结果
:param text: str, 指定 log 信息前缀
:return res: str | None, 识别的结果
"""
logger.warning(f'{text}识别异常:正在调用在线 OCR 处理异常结果……')

global ocronline
ocronline = API(api_key=config.OCR_APIKEY,
language=Language.Chinese_Simplified)
pre_res = pre[1]
res = ocronline.predict(img, pre[2])
if res is None or res == pre_res:
logger.warning(
f'{text}识别异常:{pre_res} 为不存在的数据')
elif res not in valid:
logger.warning(
f'{text}识别异常:{pre_res}{res} 均为不存在的数据')
else:
logger.warning(
f'{text}识别异常:{pre_res} 应为 {res}')
ocr_error[pre_res] = res
pre_res = res
return pre_res
38 changes: 38 additions & 0 deletions arknights_mower/ocr/rectify.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from ..data import ocr_error
from ..utils import config
from ..utils.log import logger
from .ocrspace import API, Language


def ocr_rectify(img, pre, valid, text=''):
"""
调用在线 OCR 校正本地 OCR 得到的错误结果,并返回校正后的识别结果
若在线 OCR 依旧无法正确识别则返回 None
:param img: numpy.array, 图像
:param pre: (str, tuple), 本地 OCR 得到的错误结果,包括字符串和范围
:param valid: list[str], 期望得到的识别结果
:param text: str, 指定 log 信息前缀
:return res: str | None, 识别的结果
"""
logger.warning(f'{text}识别异常:正在调用在线 OCR 处理异常结果……')

global ocronline
print(config)
ocronline = API(api_key=config.OCR_APIKEY,
language=Language.Chinese_Simplified)
pre_res = pre[1]
res = ocronline.predict(img, pre[2])
if res is None or res == pre_res:
logger.warning(
f'{text}识别异常:{pre_res} 为不存在的数据')
elif res not in valid:
logger.warning(
f'{text}识别异常:{pre_res}{res} 均为不存在的数据')
else:
logger.warning(
f'{text}识别异常:{pre_res} 应为 {res}')
ocr_error[pre_res] = res
pre_res = res
return pre_res
File renamed without changes
54 changes: 35 additions & 19 deletions arknights_mower/solvers/base_construct.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def clue(self) -> None:
self.enter_room('meeting')

# 点击线索详情
self.tap((self.recog.w*0.05, self.recog.h*0.95), interval=3)
self.tap((self.recog.w*0.1, self.recog.h*0.9), interval=3)

# 如果是线索交流的报告则返回
self.find('clue_summary') and self.back()
Expand Down Expand Up @@ -252,8 +252,8 @@ def recog_view(self, only_y2: bool = True) -> None:
return y2
# x3: 右边黑色 mask 边缘
x3 = self.recog_view_mask_right()
# x4: 四分之三的位置,用来定位单个线索
x4 = (x1 + 3 * x2) // 4
# x4: 用来区分单个线索
x4 = (54 * x1 + 25 * x2) // 79

logger.debug(f'recog_view: y2:{y2}, x3:{x3}, x4:{x4}')

Expand Down Expand Up @@ -438,8 +438,9 @@ def choose_agent(self, agent: list[str], skip_free: int = 0, order: ArrangeOrder

if not first_time:
# 滑动到最左边
self.sleep(interval=0.5, rebuild=False)
for _ in range(9):
self.swipe((w//2, h//2), (w//2, 0), interval=0.5)
self.swipe_only((w//2, h//2), (w//2, 0), interval=0.5)
self.swipe((w//2, h//2), (w//2, 0), interval=3, rebuild=False)
else:
# 第一次进入按技能排序
Expand Down Expand Up @@ -491,8 +492,9 @@ def choose_agent(self, agent: list[str], skip_free: int = 0, order: ArrangeOrder
if len(agent) == 0:
break
# 否则滑动到最左边
self.sleep(interval=0.5, rebuild=False)
for _ in range(9):
self.swipe((w//2, h//2), (w//2, 0), interval=0.5)
self.swipe_only((w//2, h//2), (w//2, 0), interval=0.5)
self.swipe((w//2, h//2), (w//2, 0), interval=3, rebuild=False)

# reset the statuses and cancel the rightward-swiping
Expand All @@ -502,12 +504,17 @@ def choose_agent(self, agent: list[str], skip_free: int = 0, order: ArrangeOrder
continue

else:
for name in agent_name & agent:
for y in ret:
if y[0] == name:
self.tap((y[1][0]), interval=0, rebuild=False)
break
agent.remove(name)
for y in ret:
name = y[0]
if name in agent_name & agent:
self.tap((y[1][0]), interval=0, rebuild=False)
agent.remove(name)
# for name in agent_name & agent:
# for y in ret:
# if y[0] == name:
# self.tap((y[1][0]), interval=0, rebuild=False)
# break
# agent.remove(name)

# 如果已经完成选择则退出
if len(agent) == 0:
Expand All @@ -522,8 +529,9 @@ def choose_agent(self, agent: list[str], skip_free: int = 0, order: ArrangeOrder

if not first_time:
# 滑动到最左边
self.sleep(interval=0.5, rebuild=False)
for _ in range(9):
self.swipe((w//2, h//2), (w//2, 0), interval=0.5)
self.swipe_only((w//2, h//2), (w//2, 0), interval=0.5)
self.swipe((w//2, h//2), (w//2, 0), interval=3, rebuild=False)
else:
# 第一次进入按技能排序
Expand Down Expand Up @@ -628,7 +636,7 @@ def agent_arrange(self, plan: tp.BasePlan) -> None:
continue
self.recog.update()
self.tap_element(
'comfirm_blue', detected=True, judge=False, interval=3)
'confirm_blue', detected=True, judge=False, interval=3)
if self.scene() == Scene.INFRA_ARRANGE_CONFIRM:
x = self.recog.w // 3 * 2 # double confirm
y = self.recog.h - 10
Expand Down Expand Up @@ -706,8 +714,9 @@ def choose_agent_in_order(self, agent: list[str], exclude: list[str] = None, exc

if first_time and not far_left and agent[idx] != 'Free':
# 如果是寻找这位干员目前为止的第一次滑动, 且目前不是最左端,则滑动到最左端
self.sleep(interval=0.5, rebuild=False)
for _ in range(9):
self.swipe((w//2, h//2), (w//2, 0), interval=0.5)
self.swipe_only((w//2, h//2), (w//2, 0), interval=0.5)
self.swipe((w//2, h//2), (w//2, 0), interval=3, rebuild=True)
far_left = True
first_time = False
Expand Down Expand Up @@ -831,7 +840,9 @@ def fia(self, room: str):
self.tap((self.recog.w*BY_STATUS[0], self.recog.h*BY_STATUS[1]), interval=0.1)
# 安排空闲干员
_free = self.choose_agent_in_order(_temp_on_shift_agents, exclude_checked_in=True)
self.tap_element('comfirm_blue', detected=True, judge=False, interval=3)
self.tap_element('confirm_blue', detected=True, judge=False, interval=3)
while self.scene() == Scene.CONNECTING:
self.sleep(3)
self.back(interval=2)

logger.info('进入菲亚梅塔所在宿舍,为%s恢复心情', _recover)
Expand All @@ -843,13 +854,17 @@ def fia(self, room: str):

rest_agents = [_recover, '菲亚梅塔']
self.choose_agent_in_order(rest_agents, exclude_checked_in=True)
self.tap_element('comfirm_blue', detected=True, judge=False, interval=3)
self.tap_element('confirm_blue', detected=True, judge=False, interval=3)
while self.scene() == Scene.CONNECTING:
self.sleep(3)

logger.info('恢复完毕,填满宿舍')
rest_agents = '菲亚梅塔 Free Free Free Free'.split()
self.tap((self.recog.w*0.82, self.recog.h*0.25), interval=2)
self.choose_agent_in_order(rest_agents, exclude=[_recover], dormitory=True)
self.tap_element('comfirm_blue', detected=True, judge=False, interval=3)
self.tap_element('confirm_blue', detected=True, judge=False, interval=3)
while self.scene() == Scene.CONNECTING:
self.sleep(3)

logger.info('恢复原职')
self.back(interval=2)
Expand All @@ -858,8 +873,9 @@ def fia(self, room: str):
self.tap_element('arrange_check_in', interval=2, rebuild=False)
self.tap((self.recog.w*0.82, self.recog.h*0.25), interval=2)
self.choose_agent_in_order(on_shift_agents)
self.tap_element('comfirm_blue', detected=True, judge=False, interval=3)

self.tap_element('confirm_blue', detected=True, judge=False, interval=3)
while self.scene() == Scene.CONNECTING:
self.sleep(3)
self.back(interval=2)

# def clue_statis(self):
Expand Down
5 changes: 3 additions & 2 deletions arknights_mower/solvers/recruit.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ def transition(self) -> bool:
if self.scene() == Scene.INDEX:
self.tap_element('index_recruit')
elif self.scene() == Scene.RECRUIT_MAIN:
if not self.has_ticket and not self.can_refresh:
return True
segments = segment.recruit(self.recog.img)
tapped = False
for idx, seg in enumerate(segments):
Expand All @@ -65,6 +63,8 @@ def transition(self) -> bool:
if self.tap_element('recruit_finish', scope=seg, detected=True):
tapped = True
break
if not self.has_ticket and not self.can_refresh:
continue
required = self.find('job_requirements', scope=seg)
if required is None:
self.tap(seg)
Expand Down Expand Up @@ -137,6 +137,7 @@ def recruit_tags(self) -> bool:

# 如果没有招募券则只刷新标签不选人
if not self.has_ticket:
logger.debug('OK')
self.back()
return

Expand Down
13 changes: 11 additions & 2 deletions arknights_mower/utils/segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,14 +471,23 @@ def free_agent(img, draw=False):
st = ret[-2][2] # 起点
ed = ret[0][1] # 终点

# 去除空白的干员框,同时收集 y 坐标
# 收集 y 坐标并初步筛选
y_set = set()
__ret = []
for poly in ret:
__img = img[poly[0, 1]:poly[2, 1], poly[0, 0]:poly[2, 0]]
y_set.add(poly[0, 1])
y_set.add(poly[2, 1])
# 去除空白的干员框
if 80 <= np.min(__img):
ret.remove(poly)
logger.debug(f'drop(empty): {poly.tolist()}')
continue
# 去除被选中的蓝框
elif np.count_nonzero(__img[:, :, 0] >= 224) == 0 or np.count_nonzero(__img[:, :, 0] == 0) > 0:
logger.debug(f'drop(selected): {poly.tolist()}')
continue
__ret.append(poly)
ret = __ret

y1, y2, y4, y5 = sorted(list(y_set))
y0 = height - y5
Expand Down
7 changes: 7 additions & 0 deletions arknights_mower/utils/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ def swipe(self, start: tp.Coordinate, movement: tp.Coordinate, duration: int = 1
if interval > 0:
self.sleep(interval, rebuild)

def swipe_only(self, start: tp.Coordinate, movement: tp.Coordinate, duration: int = 100, interval: float = 1) -> None:
""" swipe only, no rebuild and recapture """
end = (start[0] + movement[0], start[1] + movement[1])
self.device.swipe(start, end, duration=duration)
if interval > 0:
time.sleep(interval)

# def swipe_seq(self, points: list[tp.Coordinate], duration: int = 100, interval: float = 1, rebuild: bool = True) -> None:
# """ swipe with point sequence """
# self.device.swipe(points, duration=duration)
Expand Down

0 comments on commit e0d14dd

Please sign in to comment.