卫戍协议

This commit is contained in:
zhbaor 2024-11-19 00:52:34 +08:00
parent 7c1f2041c6
commit 21dc3d1793
25 changed files with 243 additions and 35 deletions

View file

@ -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", "")

View file

@ -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": "场景跳转时的等待界面"

View file

@ -1,3 +0,0 @@
# Resources
资源文件,用于识别游戏中的元素和场景判定

BIN
mower/resources/double_confirm/stronghold_protocol_back.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

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

Binary file not shown.

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

Binary file not shown.

BIN
mower/resources/stronghold_protocol/defence.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

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

Binary file not shown.

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

Binary file not shown.

View file

@ -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:

View 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)

View file

@ -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",
]

View file

@ -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")

View 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()

View file

@ -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"):

View file

@ -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),

View file

@ -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: "确认对话框",
}

View file

@ -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)

View file

@ -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",