This commit is contained in:
parent
dd300fd7af
commit
554d54f7b3
13 changed files with 300 additions and 230 deletions
|
@ -640,46 +640,42 @@
|
|||
"comment": "保全扫荡确认"
|
||||
},
|
||||
"1101": {
|
||||
"label": "SF_ENTRANCE",
|
||||
"comment": "隐秘战线入口"
|
||||
},
|
||||
"1102": {
|
||||
"label": "SF_EXIT",
|
||||
"comment": "暂离行动"
|
||||
},
|
||||
"1103": {
|
||||
"1102": {
|
||||
"label": "SF_SELECT_TEAM",
|
||||
"comment": "选择小队"
|
||||
},
|
||||
"1104": {
|
||||
"1103": {
|
||||
"label": "SF_CONTINUE",
|
||||
"comment": "继续前进"
|
||||
},
|
||||
"1105": {
|
||||
"1104": {
|
||||
"label": "SF_SELECT",
|
||||
"comment": "选择路线"
|
||||
},
|
||||
"1106": {
|
||||
"1105": {
|
||||
"label": "SF_ACTIONS",
|
||||
"comment": "行动选项"
|
||||
},
|
||||
"1107": {
|
||||
"1106": {
|
||||
"label": "SF_RESULT",
|
||||
"comment": "行动结果"
|
||||
},
|
||||
"1108": {
|
||||
"1107": {
|
||||
"label": "SF_EVENT",
|
||||
"comment": "应对危机事件"
|
||||
},
|
||||
"1109": {
|
||||
"1108": {
|
||||
"label": "SF_TEAM_PASS",
|
||||
"comment": "小队通过危机事件"
|
||||
},
|
||||
"1110": {
|
||||
"1109": {
|
||||
"label": "SF_CLICK_ANYWHERE",
|
||||
"comment": "点击任意处继续"
|
||||
},
|
||||
"1111": {
|
||||
"1110": {
|
||||
"label": "SF_END",
|
||||
"comment": "抵达终点"
|
||||
},
|
||||
|
|
BIN
mower/resources/sf/card_confirm.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/sf/card_confirm.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/sf/continue_result.png
(Stored with Git LFS)
BIN
mower/resources/sf/continue_result.png
(Stored with Git LFS)
Binary file not shown.
BIN
mower/resources/sf/event_confirm.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/sf/event_confirm.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/sf/return.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/sf/return.png
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -1,26 +1,37 @@
|
|||
from datetime import datetime, timedelta
|
||||
from difflib import SequenceMatcher
|
||||
|
||||
import cv2
|
||||
|
||||
from mower.static import secret_front
|
||||
from mower.utils import config
|
||||
from mower.utils import typealias as tp
|
||||
from mower.utils.csleep import MowerExit
|
||||
from mower.utils.email import send_message
|
||||
from mower.utils.email import notify
|
||||
from mower.utils.graph import SceneGraphSolver
|
||||
from mower.utils.image import cropimg
|
||||
from mower.utils.log import logger
|
||||
from mower.utils.rapidocr import ocr_rec
|
||||
from mower.utils.scene import Scene
|
||||
from mower.utils.solver import BaseSolver
|
||||
from mower.utils.vector import sa, va
|
||||
|
||||
CardInfo = tuple[int, int, int, float]
|
||||
|
||||
def exp(card):
|
||||
data = card[:3]
|
||||
p = card[3]
|
||||
return [i * p for i in data]
|
||||
|
||||
def exp(card: CardInfo) -> list[float]:
|
||||
"""计算卡片的期望
|
||||
|
||||
Args:
|
||||
card (CardInfo): 卡片的值
|
||||
|
||||
Returns:
|
||||
list[float]: 三项属性的期望
|
||||
"""
|
||||
return [i * card[3] for i in card[:3]]
|
||||
|
||||
|
||||
class SecretFront(BaseSolver):
|
||||
solver_name = "隐秘战线"
|
||||
|
||||
target = {
|
||||
"1A": [20, 20, 20],
|
||||
"2A": [60, 55, 45],
|
||||
|
@ -49,50 +60,77 @@ class SecretFront(BaseSolver):
|
|||
"结局E": "medicine",
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.properties: list[int] | None = None
|
||||
"三项属性值"
|
||||
self.event: bool = False
|
||||
"应对危机事件"
|
||||
self.route_names: list[str] = []
|
||||
"匹配路线"
|
||||
self.series: int | None = None
|
||||
"支援作战平台、游侠、诡影迷踪"
|
||||
self.actions: dict[int, dict[int, float]] = {}
|
||||
"记录页面中卡片的期望"
|
||||
self.send_email: bool = False
|
||||
"发送邮件提醒"
|
||||
|
||||
super().__init__()
|
||||
|
||||
@property
|
||||
def route(self):
|
||||
"路线"
|
||||
return self.routes[config.conf.secret_front.target]
|
||||
|
||||
@property
|
||||
def team(self):
|
||||
"小队"
|
||||
return self.teams[config.conf.secret_front.target]
|
||||
|
||||
def run(self):
|
||||
self.timeout = timedelta(seconds=config.conf.reclamation_algorithm.timeout)
|
||||
if self.scheduler_stop_time:
|
||||
self.deadline = self.scheduler_stop_time - timedelta(minutes=1)
|
||||
else:
|
||||
self.deadline = None
|
||||
self.unknown_time = None
|
||||
|
||||
self.properties = None
|
||||
self.route_matcher = None
|
||||
self.route_names = []
|
||||
|
||||
self.event = False
|
||||
self.series = None # 支援作战平台、游侠、诡影迷踪
|
||||
self.series = None
|
||||
|
||||
self.send_email = False
|
||||
|
||||
self.reset_actions()
|
||||
|
||||
super().run()
|
||||
return False
|
||||
return super().run()
|
||||
|
||||
def reset_actions(self):
|
||||
self.actions = {}
|
||||
for page in range(3):
|
||||
self.actions[page] = {}
|
||||
"清空缓存的卡片数据"
|
||||
self.actions = {0: {}, 1: {}, 2: {}}
|
||||
|
||||
def number(self, scope: tp.Scope, height: int | None = None):
|
||||
def number(self, scope: tp.Scope, height: int = 25):
|
||||
return config.recog.num.number_int("secret_front", scope, height)
|
||||
|
||||
def card_pos(self, total, idx):
|
||||
if total == 3:
|
||||
return [(301, 466), (830, 466), (1360, 466)][idx]
|
||||
elif total == 2:
|
||||
return [(565, 466), (1095, 466)][idx]
|
||||
else:
|
||||
return (830, 466)
|
||||
def card_pos(self, total: int, idx: int) -> tp.Coordinate:
|
||||
"""总共有total张卡片时下标为idx(从0开始)卡片的左上角坐标
|
||||
|
||||
def stage_card(self, total, idx):
|
||||
Args:
|
||||
total (int): 卡片总数
|
||||
idx (int): 下标(从0开始)
|
||||
|
||||
Returns:
|
||||
tp.Coordinate: 卡片左上角坐标
|
||||
"""
|
||||
return {
|
||||
1: [(830, 466)],
|
||||
2: [(565, 466), (1095, 466)],
|
||||
3: [(301, 466), (830, 466), (1360, 466)],
|
||||
}[total][idx]
|
||||
|
||||
def event_card(self, total: int, idx: int) -> tuple[str, bool]:
|
||||
"""应对危机事件卡片识别
|
||||
|
||||
Args:
|
||||
total (int): 卡片总数
|
||||
idx (int): 卡片下标(从0开始)
|
||||
|
||||
Returns:
|
||||
tuple[str, bool]: 危机事件选项名称及是否可选
|
||||
"""
|
||||
pos = self.card_pos(total, idx)
|
||||
|
||||
scope = sa(((10, 380), (140, 430)), pos)
|
||||
|
@ -111,7 +149,16 @@ class SecretFront(BaseSolver):
|
|||
logger.debug(f"{name=} {hue=}")
|
||||
return name, hue > 18
|
||||
|
||||
def card(self, total, idx):
|
||||
def card(self, total: int, idx: int) -> CardInfo:
|
||||
"""卡片识别
|
||||
|
||||
Args:
|
||||
total (int): 总数
|
||||
idx (int): 下标(从0开始)
|
||||
|
||||
Returns:
|
||||
CardInfo: 卡片信息
|
||||
"""
|
||||
pos = self.card_pos(total, idx)
|
||||
|
||||
materiel = sa(((84, 70), (180, 102)), pos)
|
||||
|
@ -133,24 +180,32 @@ class SecretFront(BaseSolver):
|
|||
|
||||
return materiel, intelligence, medicine, percentage
|
||||
|
||||
def page_number(self):
|
||||
title = cropimg(config.recog.gray, ((1020, 230), (1210, 285)))
|
||||
if self.route_matcher is None:
|
||||
def page_number(self) -> int | None:
|
||||
"""识别当前页数
|
||||
|
||||
Returns:
|
||||
int | None: 页数(从0开始)
|
||||
"""
|
||||
if not self.route_names:
|
||||
self.tap((125, 840))
|
||||
return None
|
||||
score, scope = self.route_matcher.match2d(title)
|
||||
if scope is None:
|
||||
return None
|
||||
pos_x = scope[0][0]
|
||||
if pos_x < 800:
|
||||
page_number = 0
|
||||
elif pos_x < 1330:
|
||||
page_number = 1
|
||||
else:
|
||||
page_number = 2
|
||||
img = cropimg(config.recog.gray, ((915, 230), (1320, 290)))
|
||||
name = ocr_rec(img)
|
||||
max_ratio = 0
|
||||
page_number = 0
|
||||
for i, n in enumerate(self.route_names):
|
||||
if (ratio := SequenceMatcher(None, name, n).ratio()) > max_ratio:
|
||||
page_number = i
|
||||
max_ratio = ratio
|
||||
logger.debug(f"{page_number=}")
|
||||
return page_number
|
||||
|
||||
def card_total(self):
|
||||
def card_total(self) -> int:
|
||||
"""识别当前有几张卡片
|
||||
|
||||
Returns:
|
||||
int: 卡片数量
|
||||
"""
|
||||
p3 = self.card_pos(3, 0)
|
||||
p2 = self.card_pos(2, 0)
|
||||
up_scope = ((0, 0), (473, 120))
|
||||
|
@ -159,11 +214,11 @@ class SecretFront(BaseSolver):
|
|||
s3d = sa(down_scope, p3)
|
||||
s2u = sa(up_scope, p2)
|
||||
s2d = sa(down_scope, p2)
|
||||
if (pos := self.find("sf/card", scope=s3u)) and pos[0][0] < 350:
|
||||
if self.find("sf/card", scope=s3u):
|
||||
total = 3
|
||||
elif self.find("sf/available", scope=s3d):
|
||||
total = 3
|
||||
elif (pos := self.find("sf/card", scope=s2u)) and pos[0][0] < 610:
|
||||
elif self.find("sf/card", scope=s2u):
|
||||
total = 2
|
||||
elif self.find("sf/available", scope=s2d):
|
||||
total = 2
|
||||
|
@ -172,14 +227,18 @@ class SecretFront(BaseSolver):
|
|||
logger.debug(f"{total=}")
|
||||
return total
|
||||
|
||||
def max_card(self):
|
||||
def max_card(self) -> tuple[int, int]:
|
||||
"""计算最优选项
|
||||
|
||||
Returns:
|
||||
tuple[int, int]: 返回最优页码及卡片下标
|
||||
"""
|
||||
max_page = -1
|
||||
max_card = -1
|
||||
max_score = -1
|
||||
|
||||
logger.debug(f"{self.properties=}")
|
||||
|
||||
# 根据目标计算
|
||||
for page, page_action in self.actions.items():
|
||||
for card, action in page_action.items():
|
||||
for stage in self.route:
|
||||
|
@ -201,42 +260,40 @@ class SecretFront(BaseSolver):
|
|||
logger.debug(f"{max_page=} {max_card=}")
|
||||
return max_page, max_card
|
||||
|
||||
def choose_card(self, total, idx):
|
||||
self.route_matcher = None
|
||||
self.properties = None
|
||||
self.reset_actions()
|
||||
def choose_card(self, total: int, idx: int):
|
||||
"""点击卡片
|
||||
|
||||
if total == 3:
|
||||
start = 545
|
||||
elif total == 2:
|
||||
start = 805
|
||||
else:
|
||||
start = 1075
|
||||
self.tap((start + idx * 530, 900), interval=0.5)
|
||||
self.tap((start + idx * 530, 900), interval=2)
|
||||
Args:
|
||||
total (int): 卡片总数
|
||||
idx (int): 卡片下标(从0开始)
|
||||
"""
|
||||
start = {3: 545, 2: 805, 1: 1075}[total]
|
||||
pos = (start + idx * 530, 900)
|
||||
self.tap(pos)
|
||||
|
||||
def move_forward(self, scene):
|
||||
# 从首页进入隐秘战线
|
||||
if scene == Scene.INDEX:
|
||||
self.tap_index_element("terminal")
|
||||
elif scene == Scene.TERMINAL_MAIN:
|
||||
self.tap_terminal_button("main_theme")
|
||||
elif scene == Scene.TERMINAL_MAIN_THEME:
|
||||
self.tap("navigation/main/14")
|
||||
elif scene == Scene.SF_ENTRANCE:
|
||||
self.tap("sf/entrance")
|
||||
|
||||
# 选择小队
|
||||
def transition(self):
|
||||
if (scene := self.scene()) == Scene.TERMINAL_MAIN_THEME:
|
||||
self.main_theme(2, 14)
|
||||
elif scene == Scene.OPERATOR_CHOOSE_LEVEL:
|
||||
if pos := self.find("sf/entrance"):
|
||||
self.tap(pos)
|
||||
return
|
||||
if self.animation():
|
||||
return
|
||||
SceneGraphSolver().step(Scene.TERMINAL_MAIN_THEME)
|
||||
elif scene == Scene.SF_SELECT_TEAM:
|
||||
self.tap(f"sf/team_{self.team}")
|
||||
if self.animation():
|
||||
return
|
||||
if pos := self.find(f"sf/team_{self.team}"):
|
||||
self.tap(pos)
|
||||
return
|
||||
self.tap("sf/select_team_ok")
|
||||
|
||||
# 继续前进
|
||||
elif scene == Scene.SF_CONTINUE:
|
||||
self.tap("sf/continue")
|
||||
|
||||
# 选择路线时识别已有属性值
|
||||
elif scene == Scene.SF_SELECT:
|
||||
if self.animation(((0, 0), (1920, 1030))):
|
||||
return
|
||||
self.send_email = True
|
||||
self.event = False
|
||||
|
||||
if self.properties is None:
|
||||
|
@ -247,8 +304,12 @@ class SecretFront(BaseSolver):
|
|||
]
|
||||
logger.debug(f"{self.properties=}")
|
||||
|
||||
if self.route_matcher is None:
|
||||
self.route_matcher = config.recog.matcher
|
||||
if not self.route_names:
|
||||
for i in range(3):
|
||||
pos = self.card_pos(3, i)
|
||||
scope = sa(((120, 145), (460, 205)), pos)
|
||||
img = cropimg(config.recog.gray, scope)
|
||||
self.route_names.append(ocr_rec(img))
|
||||
|
||||
self.series = None
|
||||
if (
|
||||
|
@ -267,39 +328,42 @@ class SecretFront(BaseSolver):
|
|||
self.series = 2
|
||||
logger.debug(f"{self.series=}")
|
||||
|
||||
self.tap((545 + 530 * self.series, 640), interval=1.5)
|
||||
self.tap((545 + 530 * self.series, 640))
|
||||
return
|
||||
|
||||
self.tap((545, 640), interval=1.5)
|
||||
|
||||
# 行动列表
|
||||
self.tap((545, 640))
|
||||
elif scene == Scene.SF_ACTIONS:
|
||||
if self.event and (pos := self.find("sf/event_confirm")):
|
||||
self.tap(pos)
|
||||
return
|
||||
elif pos := self.find("sf/card_confirm"):
|
||||
self.tap(pos)
|
||||
return
|
||||
|
||||
if self.animation(((0, 0), (1920, 1030))):
|
||||
return
|
||||
|
||||
total = self.card_total()
|
||||
|
||||
if self.event:
|
||||
name_list = [self.stage_card(total, i) for i in range(total)]
|
||||
for idx, data in enumerate(name_list):
|
||||
name, available = data
|
||||
if name in self.route:
|
||||
if available:
|
||||
self.choose_card(total, idx)
|
||||
else:
|
||||
self.exit = "restart"
|
||||
self.tap("sf/exit_button")
|
||||
name_list = [self.event_card(total, i) for i in range(total)]
|
||||
for idx, (name, available) in enumerate(name_list):
|
||||
if name not in self.route:
|
||||
continue
|
||||
if available:
|
||||
self.choose_card(total, idx)
|
||||
return
|
||||
self.exit = "restart"
|
||||
break
|
||||
self.tap("sf/exit_button")
|
||||
return
|
||||
|
||||
if (page_number := self.page_number()) is None:
|
||||
self.sleep()
|
||||
return
|
||||
|
||||
target = self.target[self.route[-1]]
|
||||
distance = [max(t - p, 0) for p, t in zip(self.properties, target)]
|
||||
if sum(distance) == 0:
|
||||
self.choose_card(total, 0)
|
||||
self.sleep(3)
|
||||
return
|
||||
|
||||
if self.series is not None:
|
||||
|
@ -309,6 +373,7 @@ class SecretFront(BaseSolver):
|
|||
if all(card[3] < 0.8 for card in card_data):
|
||||
logger.debug("成功概率太低")
|
||||
self.series = None
|
||||
self.solver_update_before_transition = False
|
||||
return
|
||||
|
||||
elif not all(self.actions.values()):
|
||||
|
@ -319,6 +384,7 @@ class SecretFront(BaseSolver):
|
|||
for idx in range(total):
|
||||
self.actions[page_number][idx] = exp(self.card(total, idx))
|
||||
logger.debug(f"{self.actions=}")
|
||||
self.solver_update_before_transition = False
|
||||
elif (page_number + 1) % 3 == target_number:
|
||||
self.tap((1785, 225)) # 下一页
|
||||
else:
|
||||
|
@ -329,87 +395,25 @@ class SecretFront(BaseSolver):
|
|||
|
||||
if max_page == page_number:
|
||||
self.choose_card(len(self.actions[max_page]), max_card)
|
||||
self.sleep(3)
|
||||
elif (page_number + 1) % 3 == max_page:
|
||||
self.tap((1785, 225)) # 下一页
|
||||
else:
|
||||
self.tap((350, 225)) # 上一页
|
||||
|
||||
# 行动结果
|
||||
elif scene == Scene.SF_RESULT:
|
||||
if pos := self.find("sf/continue_result"):
|
||||
self.tap(pos)
|
||||
else:
|
||||
self.sleep()
|
||||
|
||||
self.route_names = []
|
||||
self.properties = None
|
||||
self.reset_actions()
|
||||
self.tap((1640, 945))
|
||||
elif scene == Scene.SF_EVENT:
|
||||
self.event = True
|
||||
self.tap("sf/continue_event", interval=1.5)
|
||||
|
||||
self.tap("sf/continue_event")
|
||||
elif scene in [Scene.SF_TEAM_PASS, Scene.SF_CLICK_ANYWHERE, Scene.SF_END]:
|
||||
self.tap((960, 980), interval=2)
|
||||
|
||||
if scene == Scene.SF_END:
|
||||
send_message(
|
||||
f"隐秘战线成功完成{config.conf.secret_front.target}", level="INFO"
|
||||
)
|
||||
|
||||
# 关闭说明
|
||||
elif scene == Scene.NOTICE:
|
||||
self.tap("notice")
|
||||
self.tap((960, 980))
|
||||
|
||||
if scene == Scene.SF_END and self.send_email:
|
||||
self.send_email = False
|
||||
notify(f"隐秘战线通关{config.conf.secret_front.target}", level="INFO")
|
||||
elif scene == Scene.SF_EXIT:
|
||||
if self.exit == "restart":
|
||||
self.properties = None
|
||||
self.route_matcher = None
|
||||
self.event = False
|
||||
|
||||
self.tap("sf/restart")
|
||||
self.tap("sf/confirm")
|
||||
elif self.exit == "exit":
|
||||
self.tap("sf/confirm")
|
||||
else:
|
||||
self.tap((480, 590))
|
||||
|
||||
self.tap("sf/restart")
|
||||
else:
|
||||
self.sleep()
|
||||
|
||||
def back_to_index(self, scene):
|
||||
if scene in [Scene.TERMINAL_MAIN, Scene.TERMINAL_MAIN_THEME, Scene.SF_ENTRANCE]:
|
||||
self.back()
|
||||
elif scene == Scene.SF_EXIT:
|
||||
self.move_forward(scene)
|
||||
else:
|
||||
self.exit = "exit"
|
||||
self.tap("sf/exit_button")
|
||||
|
||||
def transition(self):
|
||||
now = datetime.now()
|
||||
|
||||
if (scene := self.sf_scene()) == Scene.UNKNOWN:
|
||||
if not self.unknown_time:
|
||||
self.unknown_time = now
|
||||
elif now - self.unknown_time > self.timeout:
|
||||
logger.warning("连续识别到未知场景")
|
||||
try:
|
||||
self.properties = None
|
||||
self.route_matcher = None
|
||||
self.event = False
|
||||
self.reset_actions()
|
||||
super().back_to_index()
|
||||
except MowerExit:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
config.device.exit()
|
||||
self.check_current_focus()
|
||||
else:
|
||||
self.unknown_time = None
|
||||
|
||||
if self.deadline and self.deadline < datetime.now():
|
||||
if scene == Scene.INDEX:
|
||||
return True
|
||||
else:
|
||||
self.back_to_index(scene)
|
||||
else:
|
||||
self.move_forward(scene)
|
||||
SceneGraphSolver().step(Scene.TERMINAL_MAIN_THEME)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# ruff: noqa: F401
|
||||
|
||||
from . import (
|
||||
extra,
|
||||
friend,
|
||||
|
@ -8,26 +10,9 @@ from . import (
|
|||
recruit,
|
||||
riic,
|
||||
rogue,
|
||||
secret_front,
|
||||
shop,
|
||||
sss,
|
||||
terminal,
|
||||
)
|
||||
from .utils import DG, SceneGraphSolver, edge
|
||||
|
||||
__all__ = [
|
||||
"SceneGraphSolver",
|
||||
"DG",
|
||||
"edge",
|
||||
"extra",
|
||||
"friend",
|
||||
"index",
|
||||
"mission",
|
||||
"navbar",
|
||||
"operation",
|
||||
"recruit",
|
||||
"riic",
|
||||
"shop",
|
||||
"sss",
|
||||
"terminal",
|
||||
"rogue",
|
||||
]
|
||||
from .utils import SceneGraphSolver
|
||||
|
|
24
mower/utils/graph/secret_front.py
Normal file
24
mower/utils/graph/secret_front.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
from mower.utils.scene import Scene
|
||||
from mower.utils.solver import BaseSolver
|
||||
|
||||
from .utils import edge
|
||||
|
||||
# 隐秘战线
|
||||
|
||||
|
||||
@edge(Scene.SF_EXIT, Scene.OPERATOR_CHOOSE_LEVEL)
|
||||
def exit_dialog(solver: BaseSolver):
|
||||
solver.tap("sf/exit_confirm")
|
||||
|
||||
|
||||
@edge(Scene.SF_SELECT_TEAM, Scene.SF_EXIT)
|
||||
@edge(Scene.SF_CONTINUE, Scene.SF_EXIT)
|
||||
@edge(Scene.SF_SELECT, Scene.SF_EXIT)
|
||||
@edge(Scene.SF_ACTIONS, Scene.SF_EXIT)
|
||||
@edge(Scene.SF_RESULT, Scene.SF_EXIT)
|
||||
@edge(Scene.SF_EVENT, Scene.SF_EXIT)
|
||||
@edge(Scene.SF_TEAM_PASS, Scene.SF_EXIT)
|
||||
@edge(Scene.SF_CLICK_ANYWHERE, Scene.SF_EXIT)
|
||||
@edge(Scene.SF_END, Scene.SF_EXIT)
|
||||
def exit_button(solver: BaseSolver):
|
||||
solver.tap("sf/exit_button")
|
|
@ -430,6 +430,34 @@ class Recognizer:
|
|||
self.scene = Scene.SIGN_IN_ORUNDUM
|
||||
elif self.find("start_story"):
|
||||
self.scene = Scene.STORY_STAGE
|
||||
elif self.find("sf/exit_button"):
|
||||
if self.find("sf/continue"):
|
||||
self.scene = Scene.SF_CONTINUE
|
||||
elif self.find("sf/properties"):
|
||||
if self.find("sf/select"):
|
||||
self.scene = Scene.SF_SELECT
|
||||
elif self.find("sf/return"):
|
||||
self.scene = Scene.SF_ACTIONS
|
||||
elif self.find("sf/success"):
|
||||
self.scene = Scene.SF_RESULT
|
||||
elif self.find("sf/failure"):
|
||||
self.scene = Scene.SF_RESULT
|
||||
else:
|
||||
self.scene = Scene.UNKNOWN
|
||||
elif self.find("sf/inheritance"):
|
||||
self.scene = Scene.SF_SELECT_TEAM
|
||||
elif self.find("sf/continue_event"):
|
||||
self.scene = Scene.SF_EVENT
|
||||
elif self.find("sf/click_anywhere"):
|
||||
self.scene = Scene.SF_CLICK_ANYWHERE
|
||||
elif self.find("sf/team_pass"):
|
||||
self.scene = Scene.SF_TEAM_PASS
|
||||
elif self.find("sf/end"):
|
||||
self.scene = Scene.SF_END
|
||||
else:
|
||||
self.scene = Scene.UNKNOWN
|
||||
elif self.find("sf/exit"):
|
||||
self.scene = Scene.SF_EXIT
|
||||
|
||||
# 模板匹配
|
||||
elif self.detect_index_scene():
|
||||
|
|
|
@ -163,6 +163,20 @@ color = {
|
|||
"room_detail": (1291, 33),
|
||||
"sanity_charge": (1111, 382),
|
||||
"sanity_charge_dialog": (570, 529),
|
||||
"sf/continue": (409, 818),
|
||||
"sf/continue_event": (346, 815),
|
||||
"sf/entrance": (32, 139),
|
||||
"sf/exit": (856, 339),
|
||||
"sf/exit_button": (30, 28),
|
||||
"sf/exit_confirm": ((1393, 658), (1153, 658)),
|
||||
"sf/inheritance": (1501, 26),
|
||||
"sf/properties": (34, 470),
|
||||
"sf/restart": (869, 657),
|
||||
"sf/return": (57, 822),
|
||||
"sf/select_team_ok": (1706, 917),
|
||||
"sf/team_intelligence": (66, 530),
|
||||
"sf/team_management": (55, 288),
|
||||
"sf/team_medicine": (56, 766),
|
||||
"shop/assist.jpg": (816, 222),
|
||||
"shop/cart": (1252, 842),
|
||||
"shop/collect": (1467, 43),
|
||||
|
@ -389,6 +403,19 @@ template_matching = {
|
|||
"rogue/refresh": ((1205, 200), (1256, 350)),
|
||||
"rogue/team_check_to_do": ((0, 800), (1920, 960)),
|
||||
"rogue/view_data_back": (147, 46),
|
||||
"sf/available": None,
|
||||
"sf/card": None,
|
||||
"sf/card_confirm": ((720, 830), (1860, 890)),
|
||||
"sf/click_anywhere": ((750, 940), (1030, 1000)),
|
||||
"sf/end": ((1060, 825), (1340, 900)),
|
||||
"sf/event_confirm": ((260, 845), (1920, 890)),
|
||||
"sf/failure": ((365, 330), (610, 850)),
|
||||
"sf/lost_in_the_trick": ((300, 600), (1830, 690)),
|
||||
"sf/ranger": ((300, 600), (1830, 690)),
|
||||
"sf/select": (274, 181),
|
||||
"sf/success": ((365, 330), (610, 850)),
|
||||
"sf/support_battle_platform": ((300, 600), (1830, 690)),
|
||||
"sf/team_pass": ((960, 825), (1200, 900)),
|
||||
"sign_in/headhunting/available": (1177, 857),
|
||||
"sign_in/moon_festival/banner": (704, 92),
|
||||
"sign_in/shop/0": (1341, 618),
|
||||
|
@ -458,6 +485,7 @@ template_matching_score = {
|
|||
"recruit/stone": 0.7,
|
||||
"recruit/time": 0.8,
|
||||
"rogue/node_be_choosed": 0.7,
|
||||
"sf/card": 0.8,
|
||||
"sign_in/moon_festival/banner": 0.5,
|
||||
"sss/add_agent": 0.8,
|
||||
"sss/drop_EC": 0.8,
|
||||
|
|
|
@ -319,27 +319,25 @@ class Scene:
|
|||
"选择定向元件"
|
||||
SSS_ELIMI_AGENCY = 1019
|
||||
"保全扫荡确认"
|
||||
SF_ENTRANCE = 1101
|
||||
"隐秘战线入口"
|
||||
SF_EXIT = 1102
|
||||
SF_EXIT = 1101
|
||||
"暂离行动"
|
||||
SF_SELECT_TEAM = 1103
|
||||
SF_SELECT_TEAM = 1102
|
||||
"选择小队"
|
||||
SF_CONTINUE = 1104
|
||||
SF_CONTINUE = 1103
|
||||
"继续前进"
|
||||
SF_SELECT = 1105
|
||||
SF_SELECT = 1104
|
||||
"选择路线"
|
||||
SF_ACTIONS = 1106
|
||||
SF_ACTIONS = 1105
|
||||
"行动选项"
|
||||
SF_RESULT = 1107
|
||||
SF_RESULT = 1106
|
||||
"行动结果"
|
||||
SF_EVENT = 1108
|
||||
SF_EVENT = 1107
|
||||
"应对危机事件"
|
||||
SF_TEAM_PASS = 1109
|
||||
SF_TEAM_PASS = 1108
|
||||
"小队通过危机事件"
|
||||
SF_CLICK_ANYWHERE = 1110
|
||||
SF_CLICK_ANYWHERE = 1109
|
||||
"点击任意处继续"
|
||||
SF_END = 1111
|
||||
SF_END = 1110
|
||||
"抵达终点"
|
||||
HEADHUNTING = 1201
|
||||
"干员寻访"
|
||||
|
@ -606,17 +604,16 @@ SceneComment = {
|
|||
1017: "应急模式额外元件",
|
||||
1018: "选择定向元件",
|
||||
1019: "保全扫荡确认",
|
||||
1101: "隐秘战线入口",
|
||||
1102: "暂离行动",
|
||||
1103: "选择小队",
|
||||
1104: "继续前进",
|
||||
1105: "选择路线",
|
||||
1106: "行动选项",
|
||||
1107: "行动结果",
|
||||
1108: "应对危机事件",
|
||||
1109: "小队通过危机事件",
|
||||
1110: "点击任意处继续",
|
||||
1111: "抵达终点",
|
||||
1101: "暂离行动",
|
||||
1102: "选择小队",
|
||||
1103: "继续前进",
|
||||
1104: "选择路线",
|
||||
1105: "行动选项",
|
||||
1106: "行动结果",
|
||||
1107: "应对危机事件",
|
||||
1108: "小队通过危机事件",
|
||||
1109: "点击任意处继续",
|
||||
1110: "抵达终点",
|
||||
1201: "干员寻访",
|
||||
1202: "使用赠送寻访机会确认对话框",
|
||||
1203: "限定池单抽结果",
|
||||
|
|
|
@ -522,15 +522,16 @@ Res = Literal[
|
|||
"sanity_charge_dialog",
|
||||
"sf/available",
|
||||
"sf/card",
|
||||
"sf/card_confirm",
|
||||
"sf/click_anywhere",
|
||||
"sf/confirm",
|
||||
"sf/continue",
|
||||
"sf/continue_event",
|
||||
"sf/continue_result",
|
||||
"sf/end",
|
||||
"sf/entrance",
|
||||
"sf/event_confirm",
|
||||
"sf/exit",
|
||||
"sf/exit_button",
|
||||
"sf/exit_confirm",
|
||||
"sf/failure",
|
||||
"sf/inheritance",
|
||||
"sf/lost_in_the_trick",
|
||||
|
@ -538,6 +539,7 @@ Res = Literal[
|
|||
"sf/properties",
|
||||
"sf/ranger",
|
||||
"sf/restart",
|
||||
"sf/return",
|
||||
"sf/select",
|
||||
"sf/select_team_ok",
|
||||
"sf/success",
|
||||
|
|
Loading…
Add table
Reference in a new issue