卫戍协议
This commit is contained in:
parent
7c1f2041c6
commit
21dc3d1793
25 changed files with 243 additions and 35 deletions
|
@ -8,7 +8,9 @@ res_path = Path(res_path_name)
|
|||
data = "from typing import Literal\n\nRes = Literal[\n"
|
||||
references = {}
|
||||
|
||||
for i in sorted(res_path.glob("**/*.png"), key=lambda x: x.as_posix()):
|
||||
for i in sorted(res_path.glob("**/*"), key=lambda x: x.as_posix()):
|
||||
if not i.is_file():
|
||||
continue
|
||||
res_name = i.as_posix()
|
||||
res_name = res_name.replace(res_path_name, "")
|
||||
res_name = res_name.replace(".png", "")
|
||||
|
|
|
@ -707,6 +707,38 @@
|
|||
"label": "ROGUE_REFRESH_SHOP",
|
||||
"comment": "肉鸽商店刷新确认"
|
||||
},
|
||||
"1801": {
|
||||
"label": "SP_MAIN",
|
||||
"comment": "卫戍协议首页"
|
||||
},
|
||||
"1802": {
|
||||
"label": "SP_DEFENCE",
|
||||
"comment": "卫戍协议防守方策略"
|
||||
},
|
||||
"1803": {
|
||||
"label": "SP_ACTION",
|
||||
"comment": "卫戍协议玩家行动"
|
||||
},
|
||||
"1804": {
|
||||
"label": "SP_AUTO",
|
||||
"comment": "卫戍协议玩家发呆"
|
||||
},
|
||||
"1805": {
|
||||
"label": "SP_GIVEUP_CONFIRM",
|
||||
"comment": "卫戍协议放弃模拟确认"
|
||||
},
|
||||
"1806": {
|
||||
"label": "SP_COMPLETE",
|
||||
"comment": "卫戍协议结算"
|
||||
},
|
||||
"1807": {
|
||||
"label": "SP_BACK_CONFIRM",
|
||||
"comment": "卫戍协议回到主页确认"
|
||||
},
|
||||
"1808": {
|
||||
"label": "SP_ANIMATION",
|
||||
"comment": "卫戍协议动画"
|
||||
},
|
||||
"9998": {
|
||||
"label": "LOADING",
|
||||
"comment": "场景跳转时的等待界面"
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
# Resources
|
||||
|
||||
资源文件,用于识别游戏中的元素和场景判定
|
BIN
mower/resources/double_confirm/stronghold_protocol_back.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/double_confirm/stronghold_protocol_back.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/double_confirm/stronghold_protocol_giveup.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/double_confirm/stronghold_protocol_giveup.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/stronghold_protocol/action.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/stronghold_protocol/action.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/stronghold_protocol/animation.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/stronghold_protocol/animation.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/stronghold_protocol/auto.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/stronghold_protocol/auto.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/stronghold_protocol/complete.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/stronghold_protocol/complete.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/stronghold_protocol/defence.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/stronghold_protocol/defence.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/stronghold_protocol/entry.jpg
Normal file
BIN
mower/resources/stronghold_protocol/entry.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 230 KiB |
BIN
mower/resources/stronghold_protocol/main.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/stronghold_protocol/main.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/stronghold_protocol/medic.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/stronghold_protocol/medic.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/stronghold_protocol/start.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/stronghold_protocol/start.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
mower/resources/stronghold_protocol/stop.png
(Stored with Git LFS)
Normal file
BIN
mower/resources/stronghold_protocol/stop.png
(Stored with Git LFS)
Normal file
Binary file not shown.
|
@ -5,13 +5,7 @@ import cv2
|
|||
|
||||
from mower.utils import config
|
||||
from mower.utils.graph import SceneGraphSolver
|
||||
from mower.utils.image import loadres, saveimg
|
||||
from mower.utils.log import logger
|
||||
from mower.utils.matcher import (
|
||||
GOOD_DISTANCE_LIMIT,
|
||||
flann,
|
||||
keypoints_scale_invariant,
|
||||
)
|
||||
from mower.utils.scene import Scene
|
||||
from mower.utils.vector import va, vs
|
||||
|
||||
|
@ -72,30 +66,7 @@ class ActivityNavigation(SceneGraphSolver):
|
|||
|
||||
def transition(self) -> bool:
|
||||
if (scene := self.scene()) == Scene.TERMINAL_MAIN:
|
||||
img = loadres("navigation/activity/terminal.jpg", True)
|
||||
kp1, des1 = keypoints_scale_invariant(img)
|
||||
kp2, des2 = config.recog.matcher.kp, config.recog.matcher.des
|
||||
matches = flann.knnMatch(des1, des2, k=2)
|
||||
good = []
|
||||
for pair in matches:
|
||||
if (len_pair := len(pair)) == 2:
|
||||
x, y = pair
|
||||
if x.distance < GOOD_DISTANCE_LIMIT * y.distance:
|
||||
good.append(x)
|
||||
elif len_pair == 1:
|
||||
good.append(pair[0])
|
||||
good = sorted(good, key=lambda x: x.distance)
|
||||
debug_img = cv2.drawMatches(
|
||||
img,
|
||||
kp1,
|
||||
config.recog.gray,
|
||||
kp2,
|
||||
good[:10],
|
||||
None,
|
||||
flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS,
|
||||
)
|
||||
saveimg(debug_img, "navigation")
|
||||
self.tap(kp2[good[0].trainIdx].pt, interval=4)
|
||||
self.terminal_entry("navigation/activity/terminal.jpg")
|
||||
elif scene == Scene.ACTIVITY_MAIN:
|
||||
self.tap("navigation/activity/entry")
|
||||
elif scene == Scene.ACTIVITY_CHOOSE_LEVEL:
|
||||
|
|
62
mower/solvers/stronghold_protocol.py
Normal file
62
mower/solvers/stronghold_protocol.py
Normal file
|
@ -0,0 +1,62 @@
|
|||
import cv2
|
||||
|
||||
from mower.solvers.fight.mixin import FightMixin
|
||||
from mower.utils import config
|
||||
from mower.utils.graph import SceneGraphSolver
|
||||
from mower.utils.image import cropimg, thres2
|
||||
from mower.utils.scene import Scene
|
||||
from mower.utils.vector import va
|
||||
|
||||
|
||||
class StrongholdProtocol(SceneGraphSolver, FightMixin):
|
||||
solver_name = "卫戍协议"
|
||||
|
||||
def run(self):
|
||||
self.buy = True
|
||||
self.depoly = True
|
||||
return super().run()
|
||||
|
||||
def transition(self):
|
||||
if (scene := self.scene()) == Scene.TERMINAL_MAIN:
|
||||
self.terminal_entry("stronghold_protocol/entry.jpg")
|
||||
elif scene == Scene.SP_MAIN:
|
||||
if pos := self.find("stronghold_protocol/stop"):
|
||||
self.tap(pos)
|
||||
return
|
||||
self.tap((1664, 911))
|
||||
elif scene == Scene.SP_DEFENCE:
|
||||
if pos := self.find("stronghold_protocol/start"):
|
||||
self.tap(pos)
|
||||
return
|
||||
self.buy = True
|
||||
self.deploy = True
|
||||
self.tap((383, 948))
|
||||
elif scene == Scene.SP_ACTION:
|
||||
img = cropimg(config.recog.gray, ((1045, 24), (1063, 46)))
|
||||
img = cv2.bitwise_not(thres2(img, 127))
|
||||
if config.recog.num.number_int("secret_front", img=img) >= 2:
|
||||
self.back()
|
||||
return
|
||||
if self.buy:
|
||||
for pos in [(407, 540), (804, 513), (875, 431)]:
|
||||
self.tap(pos, interval=0.5)
|
||||
if not self.find("stronghold_protocol/medic"):
|
||||
break
|
||||
self.tap((1056, 482))
|
||||
self.buy = False
|
||||
return
|
||||
if self.deploy:
|
||||
for pos in [(1475, 524), (1058, 746)]:
|
||||
self.swipe_ext([(1602, 989), pos], [500], up_wait=100, interval=0.4)
|
||||
if self.drag_success():
|
||||
self.swipe_ext(
|
||||
[pos, va(pos, (300, 0))], [200], up_wait=100, interval=0.4
|
||||
)
|
||||
self.deploy = False
|
||||
break
|
||||
return
|
||||
self.tap((1827, 93))
|
||||
elif scene == Scene.SP_AUTO:
|
||||
self.sleep()
|
||||
else:
|
||||
self.scene_graph_step(Scene.TERMINAL_MAIN)
|
|
@ -10,6 +10,7 @@ from . import (
|
|||
rogue,
|
||||
shop,
|
||||
sss,
|
||||
stronghold_protocol,
|
||||
terminal,
|
||||
)
|
||||
from .utils import DG, SceneGraphSolver, edge
|
||||
|
@ -30,4 +31,5 @@ __all__ = [
|
|||
"sss",
|
||||
"terminal",
|
||||
"rogue",
|
||||
"stronghold_protocol",
|
||||
]
|
||||
|
|
|
@ -52,6 +52,7 @@ from .utils import edge
|
|||
@edge(Scene.OPERATOR_MANAGEMENT, Scene.NAVIGATION_BAR)
|
||||
@edge(Scene.OPERATOR_DETAILS, Scene.NAVIGATION_BAR)
|
||||
@edge(Scene.ROGUE_INDEX, Scene.NAVIGATION_BAR)
|
||||
@edge(Scene.SP_MAIN, Scene.NAVIGATION_BAR)
|
||||
def index_nav(solver: BaseSolver):
|
||||
solver.tap("nav_button")
|
||||
|
||||
|
|
26
mower/utils/graph/stronghold_protocol.py
Normal file
26
mower/utils/graph/stronghold_protocol.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from mower.utils.scene import Scene
|
||||
from mower.utils.solver import BaseSolver
|
||||
|
||||
from .utils import edge
|
||||
|
||||
# 卫戍协议
|
||||
|
||||
|
||||
@edge(Scene.SP_MAIN, Scene.TERMINAL_MAIN)
|
||||
@edge(Scene.SP_DEFENCE, Scene.SP_MAIN)
|
||||
@edge(Scene.SP_ACTION, Scene.SP_MAIN)
|
||||
@edge(Scene.SP_AUTO, Scene.SP_BACK_CONFIRM)
|
||||
@edge(Scene.SP_COMPLETE, Scene.SP_BACK_CONFIRM)
|
||||
def sp_back(solver: BaseSolver):
|
||||
solver.back()
|
||||
|
||||
|
||||
@edge(Scene.SP_GIVEUP_CONFIRM, Scene.SP_MAIN)
|
||||
@edge(Scene.SP_BACK_CONFIRM, Scene.SP_MAIN)
|
||||
def dialog_confirm(solver: BaseSolver):
|
||||
solver.tap("double_confirm/main", x_rate=1)
|
||||
|
||||
|
||||
@edge(Scene.SP_ANIMATION, Scene.SP_ACTION)
|
||||
def wait(solver: BaseSolver):
|
||||
solver.sleep()
|
|
@ -256,6 +256,10 @@ class Recognizer:
|
|||
self.scene = Scene.ROGUE_REFRESH_SHOP
|
||||
elif self.find("double_confirm/headhunting"):
|
||||
self.scene = Scene.HEADHUNTING_FREE_CONFIRM
|
||||
elif self.find("double_confirm/stronghold_protocol_back"):
|
||||
self.scene = Scene.SP_BACK_CONFIRM
|
||||
elif self.find("double_confirm/stronghold_protocol_giveup"):
|
||||
self.scene = Scene.SP_GIVEUP_CONFIRM
|
||||
else:
|
||||
self.scene = Scene.DOUBLE_CONFIRM
|
||||
elif self.find("mission_trainee_on"):
|
||||
|
@ -341,6 +345,17 @@ class Recognizer:
|
|||
self.scene = Scene.SIGN_IN_ORUNDUM
|
||||
elif self.find("start_story"):
|
||||
self.scene = Scene.STORY_STAGE
|
||||
elif self.find("stronghold_protocol/main"):
|
||||
self.scene = Scene.SP_MAIN
|
||||
elif self.find("stronghold_protocol/defence"):
|
||||
self.scene = Scene.SP_DEFENCE
|
||||
elif self.find("stronghold_protocol/auto"):
|
||||
self.scene = Scene.SP_AUTO
|
||||
elif self.find("stronghold_protocol/complete"):
|
||||
self.scene = Scene.SP_COMPLETE
|
||||
elif self.find("stronghold_protocol/animation"):
|
||||
self.scene = Scene.SP_ANIMATION
|
||||
|
||||
elif self.is_black():
|
||||
self.scene = Scene.LOADING
|
||||
|
||||
|
@ -434,6 +449,8 @@ class Recognizer:
|
|||
self.scene = Scene.STORY_SKIP
|
||||
elif self.find("story_skip"):
|
||||
self.scene = Scene.STORY
|
||||
elif self.find("stronghold_protocol/action"):
|
||||
self.scene = Scene.SP_ACTION
|
||||
|
||||
# 没弄完的
|
||||
# elif self.find("ope_elimi_finished"):
|
||||
|
|
|
@ -37,6 +37,8 @@ color = {
|
|||
"double_confirm/refresh_shop": (901, 435),
|
||||
"double_confirm/sss": (901, 465),
|
||||
"double_confirm/sss_abandon_drop": (901, 463),
|
||||
"double_confirm/stronghold_protocol_back": (1056, 437),
|
||||
"double_confirm/stronghold_protocol_giveup": (921, 434),
|
||||
"double_confirm/voice": (745, 435),
|
||||
"drone": (274, 437),
|
||||
"factory_collect": (1542, 886),
|
||||
|
@ -160,6 +162,13 @@ color = {
|
|||
"sss/switch_to_ex": (1255, 942),
|
||||
"sss/switch_to_normal": (1255, 934),
|
||||
"start_story": (1392, 623),
|
||||
"stronghold_protocol/animation": (803, 391),
|
||||
"stronghold_protocol/auto": (898, 56),
|
||||
"stronghold_protocol/complete": (231, 101),
|
||||
"stronghold_protocol/defence": (29, 14),
|
||||
"stronghold_protocol/main": (1456, 472),
|
||||
"stronghold_protocol/start": (1709, 879),
|
||||
"stronghold_protocol/stop": (1272, 801),
|
||||
"terminal_main": (1658, 734),
|
||||
}
|
||||
|
||||
|
@ -307,6 +316,8 @@ template_matching = {
|
|||
"stone_fragment": None,
|
||||
"story_skip": (1718, 58),
|
||||
"story_skip_confirm_dialog": ((685, 504), (1234, 730)),
|
||||
"stronghold_protocol/action": (849, 60),
|
||||
"stronghold_protocol/medic": (37, 167),
|
||||
"switch_order/check": None,
|
||||
"switch_order/lmb": (1442, 891),
|
||||
"switch_order/oru": (1442, 891),
|
||||
|
|
|
@ -353,6 +353,22 @@ class Scene:
|
|||
"放弃本次肉鸽探索"
|
||||
ROGUE_REFRESH_SHOP = 1704
|
||||
"肉鸽商店刷新确认"
|
||||
SP_MAIN = 1801
|
||||
"卫戍协议首页"
|
||||
SP_DEFENCE = 1802
|
||||
"卫戍协议防守方策略"
|
||||
SP_ACTION = 1803
|
||||
"卫戍协议玩家行动"
|
||||
SP_AUTO = 1804
|
||||
"卫戍协议玩家发呆"
|
||||
SP_GIVEUP_CONFIRM = 1805
|
||||
"卫戍协议放弃模拟确认"
|
||||
SP_COMPLETE = 1806
|
||||
"卫戍协议结算"
|
||||
SP_BACK_CONFIRM = 1807
|
||||
"卫戍协议回到主页确认"
|
||||
SP_ANIMATION = 1808
|
||||
"卫戍协议动画"
|
||||
LOADING = 9998
|
||||
"场景跳转时的等待界面"
|
||||
CONFIRM = 9999
|
||||
|
@ -537,6 +553,14 @@ SceneComment = {
|
|||
1702: "肉鸽首页",
|
||||
1703: "放弃本次肉鸽探索",
|
||||
1704: "肉鸽商店刷新确认",
|
||||
1801: "卫戍协议首页",
|
||||
1802: "卫戍协议防守方策略",
|
||||
1803: "卫戍协议玩家行动",
|
||||
1804: "卫戍协议玩家发呆",
|
||||
1805: "卫戍协议放弃模拟确认",
|
||||
1806: "卫戍协议结算",
|
||||
1807: "卫戍协议回到主页确认",
|
||||
1808: "卫戍协议动画",
|
||||
9998: "场景跳转时的等待界面",
|
||||
9999: "确认对话框",
|
||||
}
|
||||
|
|
|
@ -14,8 +14,9 @@ from mower.utils.csleep import MowerExit, csleep
|
|||
from mower.utils.device.adb_client.const import KeyCode
|
||||
from mower.utils.device.adb_client.session import Session
|
||||
from mower.utils.device.device import Device
|
||||
from mower.utils.image import cropimg, thres2
|
||||
from mower.utils.image import cropimg, loadres, thres2
|
||||
from mower.utils.log import logger
|
||||
from mower.utils.matcher import GOOD_DISTANCE_LIMIT, flann, keypoints_scale_invariant
|
||||
from mower.utils.recognize import RecognizeError, Recognizer, Scene
|
||||
from mower.utils.simulator import restart_simulator
|
||||
from mower.utils.traceback import caller_info
|
||||
|
@ -642,3 +643,19 @@ class BaseSolver:
|
|||
csleep(3)
|
||||
self.check_current_focus()
|
||||
return False
|
||||
|
||||
def terminal_entry(self, res: tp.Res):
|
||||
img = loadres(res, True)
|
||||
kp1, des1 = keypoints_scale_invariant(img)
|
||||
kp2, des2 = config.recog.matcher.kp, config.recog.matcher.des
|
||||
matches = flann.knnMatch(des1, des2, k=2)
|
||||
good = []
|
||||
for pair in matches:
|
||||
if (len_pair := len(pair)) == 2:
|
||||
x, y = pair
|
||||
if x.distance < GOOD_DISTANCE_LIMIT * y.distance:
|
||||
good.append(x)
|
||||
elif len_pair == 1:
|
||||
good.append(pair[0])
|
||||
good = sorted(good, key=lambda x: x.distance)
|
||||
self.tap(kp2[good[0].trainIdx].pt, interval=4)
|
||||
|
|
|
@ -87,6 +87,8 @@ Res = Literal[
|
|||
"double_confirm/refresh_shop",
|
||||
"double_confirm/sss",
|
||||
"double_confirm/sss_abandon_drop",
|
||||
"double_confirm/stronghold_protocol_back",
|
||||
"double_confirm/stronghold_protocol_giveup",
|
||||
"double_confirm/voice",
|
||||
"drone",
|
||||
"episode",
|
||||
|
@ -175,6 +177,7 @@ Res = Literal[
|
|||
"navigation/act/2",
|
||||
"navigation/activity/banner",
|
||||
"navigation/activity/entry",
|
||||
"navigation/activity/terminal.jpg",
|
||||
"navigation/biography/OF_banner",
|
||||
"navigation/biography/OF_entry",
|
||||
"navigation/collection/AP-1",
|
||||
|
@ -504,6 +507,16 @@ Res = Literal[
|
|||
"story_skip",
|
||||
"story_skip_confirm_dialog",
|
||||
"story_stage",
|
||||
"stronghold_protocol/action",
|
||||
"stronghold_protocol/animation",
|
||||
"stronghold_protocol/auto",
|
||||
"stronghold_protocol/complete",
|
||||
"stronghold_protocol/defence",
|
||||
"stronghold_protocol/entry.jpg",
|
||||
"stronghold_protocol/main",
|
||||
"stronghold_protocol/medic",
|
||||
"stronghold_protocol/start",
|
||||
"stronghold_protocol/stop",
|
||||
"switch_order/check",
|
||||
"switch_order/lmb",
|
||||
"switch_order/oru",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue