Skip to content

Commit c100978

Browse files
EeeMaoYclaude
andauthored
refactor(furniture): 重构家具领取功能中选择房产的方式,并且适配了新的房产 (#279)
* refactor(furniture): 重构家具领取功能中选择房产的方式,并且适配了新的房产 * 配置天骏的option * fix(furniture): 适配"完整的木箱"家具名称变更,新增 FurnitureIntactCrate 识别节点 游戏更新后赋能总览中的"破损的木箱"已变为"完整的木箱",OCR 无法匹配。 新增 FurnitureIntactCrate 节点识别新名称,并清理 i18n 中未使用的 cannot_claim/not_found 键。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 1ac121a commit c100978

11 files changed

Lines changed: 374 additions & 150 deletions

File tree

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import json
2+
import time
3+
4+
from maa.agent.agent_server import AgentServer
5+
from maa.context import Context
6+
from maa.custom_action import CustomAction
7+
8+
from utils.logger import logger
9+
10+
_TOP_RESET_COUNT = 1
11+
_MAX_SCROLL_COUNT = 1
12+
_SWIPE_DURATION_MS = 500
13+
_SWIPE_DELAY_SEC = 0.1
14+
_TOP_SWIPE_BEGIN = (40, 170)
15+
_TOP_SWIPE_END = (160, 470)
16+
_NEXT_SWIPE_BEGIN = (40, 470)
17+
_NEXT_SWIPE_END = (160, 170)
18+
19+
20+
def _screencap(controller):
21+
job = controller.post_screencap()
22+
job.wait()
23+
return controller.cached_image
24+
25+
26+
def _box_to_rect(box):
27+
if isinstance(box, (list, tuple)):
28+
return list(box)
29+
return [box.x, box.y, box.w, box.h]
30+
31+
32+
def _click_rect(controller, rect):
33+
cx = rect[0] + rect[2] // 2
34+
cy = rect[1] + rect[3] // 2
35+
controller.post_touch_move(cx, cy).wait()
36+
controller.post_touch_down(cx, cy).wait()
37+
time.sleep(0.05)
38+
controller.post_touch_up().wait()
39+
time.sleep(0.05)
40+
41+
42+
def _swipe(controller, begin, end):
43+
controller.post_swipe(
44+
begin[0], begin[1], end[0], end[1], duration=_SWIPE_DURATION_MS
45+
).wait()
46+
time.sleep(_SWIPE_DELAY_SEC)
47+
48+
49+
def _parse_target(custom_action_param) -> str | None:
50+
if not custom_action_param:
51+
return None
52+
53+
if isinstance(custom_action_param, str):
54+
try:
55+
params = json.loads(custom_action_param)
56+
except json.JSONDecodeError:
57+
return custom_action_param.strip() or None
58+
59+
if isinstance(params, str):
60+
return params.strip() or None
61+
if isinstance(params, dict):
62+
target = params.get("target")
63+
if isinstance(target, str):
64+
return target.strip() or None
65+
return None
66+
67+
if isinstance(custom_action_param, dict):
68+
target = custom_action_param.get("target")
69+
if isinstance(target, str):
70+
return target.strip() or None
71+
72+
return None
73+
74+
75+
@AgentServer.custom_action("furniture_choose_property")
76+
class FurnitureChooseProperty(CustomAction):
77+
def run(
78+
self, context: Context, argv: CustomAction.RunArg
79+
) -> CustomAction.RunResult:
80+
target = _parse_target(getattr(argv, "custom_action_param", None))
81+
if not target:
82+
logger.warning(f"furniture_choose_property missing target:{argv}")
83+
return CustomAction.RunResult(success=False)
84+
85+
controller = context.tasker.controller
86+
87+
for _ in range(_TOP_RESET_COUNT):
88+
if context.tasker.stopping:
89+
return CustomAction.RunResult(success=False)
90+
_swipe(controller, _TOP_SWIPE_BEGIN, _TOP_SWIPE_END)
91+
92+
for scroll_index in range(_MAX_SCROLL_COUNT + 1):
93+
if context.tasker.stopping:
94+
return CustomAction.RunResult(success=False)
95+
96+
image = _screencap(controller)
97+
result = context.run_recognition(target, image)
98+
if result and result.hit and result.box is not None:
99+
rect = _box_to_rect(result.box)
100+
logger.debug(
101+
f"furniture_choose_property target found: {target} rect={rect}"
102+
)
103+
_click_rect(controller, rect)
104+
return CustomAction.RunResult(success=True)
105+
106+
if scroll_index >= _MAX_SCROLL_COUNT:
107+
break
108+
109+
logger.debug(
110+
f"furniture_choose_property target not found, scroll next: {target} step={scroll_index+1}"
111+
)
112+
_swipe(controller, _NEXT_SWIPE_BEGIN, _NEXT_SWIPE_END)
113+
114+
logger.warning(f"furniture_choose_property target not found: {target}")
115+
return CustomAction.RunResult(success=False)

agent/custom/action/furniture_claim.py renamed to agent/custom/action/Furniture/furniture_claim.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
from utils.logger import logger
66
from utils.maafocus import PrintT
77

8-
FURNITURE_LIST = [
9-
"仓鼠球",
10-
"棉棉",
11-
"破损的木箱",
8+
FURNITURE_RECOG_NODES = [
9+
("FurnitureHamsterBall", "仓鼠球", "hamster_ball"),
10+
("FurnitureFluff", "棉棉", "fluff"),
11+
("FurnitureDamagedCrate", "破损的木箱", "damaged_crate"),
12+
("FurnitureIntactCrate", "完整的木箱", "intact_crate"),
1213
]
1314

1415

@@ -18,15 +19,9 @@ def run(
1819
self, context: Context, _argv: CustomAction.RunArg
1920
) -> CustomAction.RunResult:
2021
controller = context.tasker.controller
21-
for name in FURNITURE_LIST:
22+
for node_name, name, msg_key in FURNITURE_RECOG_NODES:
2223
image = controller.post_screencap().wait().get()
23-
result = context.run_recognition(
24-
"FurnitureOcrRec",
25-
image,
26-
pipeline_override={
27-
"FurnitureOcrRec": {"recognition": {"param": {"expected": name}}}
28-
},
29-
)
24+
result = context.run_recognition(node_name, image)
3025
if result and result.box:
3126
roi = [result.box.x, result.box.y, result.box.w, result.box.h]
3227
result = context.run_recognition(
@@ -43,7 +38,7 @@ def run(
4338
"FurnitureClaim": {"recogniton": {"param": roi}}
4439
},
4540
)
46-
PrintT(context, "furniture.claimed", name)
41+
PrintT(context, f"furniture.claimed.{msg_key}")
4742
else:
4843
logger.debug(f"识别到但无法领取 {name}")
4944
else:

agent/custom/action/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
from .Movement.mouse_move import *
1919
from .Movement.character_move import *
2020
from .Common.alt_click import *
21-
from .furniture_claim import *
21+
from .Furniture.furniture_claim import *
22+
from .Furniture.furniture_choose_property import *
2223
from .auto_piano.action import *
2324
from .withdraw_money_choose_item import *
2425
from .DatasetCollection.autonomous_driving_dataset_recorder import *
@@ -43,6 +44,7 @@
4344
"AutoFScroll",
4445
"AltClick",
4546
"FurnitureClaim",
47+
"FurnitureChooseProperty",
4648
"AutoPlayPiano",
4749
"WithdrawMoneyChooseItem",
4850
"AutonomousDrivingDatasetRecorder",

assets/resource/base/pipeline/Furniture/Furniture.json

Lines changed: 39 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -46,66 +46,19 @@
4646
"FurnitureChooseEdenApartments",
4747
"FurnitureChooseSkyviewHalls",
4848
"FurnitureChooseGoldenCapital",
49-
"FurnitureApartmentsSwipe"
50-
]
51-
},
52-
"FurnitureApartmentsSwipe": {
53-
"desc": "滑动房产界面以选择其他房产",
54-
"recognition": "TemplateMatch",
55-
"roi": [
56-
4,
57-
7,
58-
71,
59-
70
60-
],
61-
"template": [
62-
"Furniture/FurnitureHousePropertyIcon.png"
63-
],
64-
"action": "Swipe",
65-
"begin": [
66-
20,
67-
520,
68-
160,
69-
1
70-
],
71-
"end": [
72-
20,
73-
380,
74-
160,
75-
1
76-
],
77-
"end_hold": 600,
78-
"next": [
79-
"FurnitureChooseApartmentsOthers"
80-
]
81-
},
82-
"FurnitureChooseApartmentsOthers": {
83-
"desc": "中间节点,后续新房产的添加也在这里",
84-
"pre_delay": 0,
85-
"post_delay": 0,
86-
"next": [
49+
"FurnitureChooseTianJun",
8750
"FurnitureChooseFenglinVilla",
8851
"FurnitureExit"
8952
]
9053
},
9154
"FurnitureChooseWienerApartments": {
9255
"desc": "选择维纳公寓",
9356
"max_hit": 1,
94-
"recognition": "OCR",
95-
"roi": [
96-
9,
97-
84,
98-
190,
99-
562
100-
],
101-
"expected": [
102-
"维纳公寓",
103-
"維納公寓",
104-
"(?i)Wiener\\s*Apartments",
105-
"メゾンVINA",
106-
"위너 아파트"
107-
],
108-
"action": "Click",
57+
"action": "Custom",
58+
"custom_action": "furniture_choose_property",
59+
"custom_action_param": {
60+
"target": "FurnitureWienerApartments"
61+
},
10962
"next": [
11063
"FurnitureGoHome",
11164
"FurnitureGotoBuy"
@@ -114,20 +67,11 @@
11467
"FurnitureChooseEdenApartments": {
11568
"desc": "选择伊登公寓",
11669
"max_hit": 1,
117-
"recognition": "OCR",
118-
"roi": [
119-
9,
120-
84,
121-
190,
122-
562
123-
],
124-
"expected": [
125-
"伊登公寓",
126-
"(?i)Eden\\s*Apartments",
127-
"レジスEDEN",
128-
"에덴 아파트"
129-
],
130-
"action": "Click",
70+
"action": "Custom",
71+
"custom_action": "furniture_choose_property",
72+
"custom_action_param": {
73+
"target": "FurnitureEdenApartments"
74+
},
13175
"next": [
13276
"FurnitureGoHome",
13377
"FurnitureGotoBuy"
@@ -136,21 +80,11 @@
13680
"FurnitureChooseSkyviewHalls": {
13781
"desc": "选择天景空馆",
13882
"max_hit": 1,
139-
"recognition": "OCR",
140-
"roi": [
141-
9,
142-
84,
143-
190,
144-
562
145-
],
146-
"expected": [
147-
"天景空馆",
148-
"天景空館",
149-
"(?i)Skyview\\s*Halls",
150-
"天景の館",
151-
"천공의 집"
152-
],
153-
"action": "Click",
83+
"action": "Custom",
84+
"custom_action": "furniture_choose_property",
85+
"custom_action_param": {
86+
"target": "FurnitureSkyviewHalls"
87+
},
15488
"next": [
15589
"FurnitureGoHome",
15690
"FurnitureGotoBuy"
@@ -159,21 +93,24 @@
15993
"FurnitureChooseGoldenCapital": {
16094
"desc": "选择金都云邸",
16195
"max_hit": 1,
162-
"recognition": "OCR",
163-
"roi": [
164-
9,
165-
84,
166-
190,
167-
562
168-
],
169-
"expected": [
170-
"金都云邸",
171-
"金都雲邸",
172-
"(?i)Golden\\s*Capital",
173-
"パレス雲都",
174-
"금빛 헤리티지"
175-
],
176-
"action": "Click",
96+
"action": "Custom",
97+
"custom_action": "furniture_choose_property",
98+
"custom_action_param": {
99+
"target": "FurnitureGoldenCapital"
100+
},
101+
"next": [
102+
"FurnitureGoHome",
103+
"FurnitureGotoBuy"
104+
]
105+
},
106+
"FurnitureChooseTianJun": {
107+
"desc": "选择天骏公阁",
108+
"max_hit": 1,
109+
"action": "Custom",
110+
"custom_action": "furniture_choose_property",
111+
"custom_action_param": {
112+
"target": "FurnitureTianJun"
113+
},
177114
"next": [
178115
"FurnitureGoHome",
179116
"FurnitureGotoBuy"
@@ -182,21 +119,11 @@
182119
"FurnitureChooseFenglinVilla": {
183120
"desc": "选择峰林别墅",
184121
"max_hit": 1,
185-
"recognition": "OCR",
186-
"roi": [
187-
9,
188-
84,
189-
190,
190-
562
191-
],
192-
"expected": [
193-
"峰林别墅",
194-
"峰林別墅",
195-
"(?i)Fenglin\\s*Villa",
196-
"シルヴァ邸苑",
197-
"봉우리 별장"
198-
],
199-
"action": "Click",
122+
"action": "Custom",
123+
"custom_action": "furniture_choose_property",
124+
"custom_action_param": {
125+
"target": "FurnitureFenglinVilla"
126+
},
200127
"next": [
201128
"FurnitureGoHome",
202129
"FurnitureGotoBuy"

0 commit comments

Comments
 (0)