Skip to content

Commit a62a6c9

Browse files
authored
Merge pull request #1857 from LGG686/dev-f
修复庭院识别错误
2 parents 9ec6101 + 7738d5d commit a62a6c9

20 files changed

Lines changed: 246 additions & 138 deletions

‎tasks/DemonEncounter/assets.py‎

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,22 @@ class DemonEncounterAssets:
6060

6161

6262
# Click Rule Assets
63-
# 从下开始数第一个
64-
C_DE_1 = RuleClick(roi_front=(1211,478,61,58), roi_back=(1211,478,61,58), name="de_1")
63+
# 从下开始数第一个(点击区已收缩, 仅包住内部图形)
64+
C_DE_1 = RuleClick(roi_front=(1222,497,39,25), roi_back=(1222,497,39,25), name="de_1")
6565
# 2
66-
C_DE_2 = RuleClick(roi_front=(1196,409,55,56), roi_back=(1196,409,55,56), name="de_2")
66+
C_DE_2 = RuleClick(roi_front=(1204,424,39,31), roi_back=(1204,424,39,31), name="de_2")
6767
# 3
68-
C_DE_3 = RuleClick(roi_front=(1225,344,53,55), roi_back=(1225,344,53,55), name="de_3")
68+
C_DE_3 = RuleClick(roi_front=(1234,364,32,22), roi_back=(1234,364,32,22), name="de_3")
6969
# 第四个
70-
C_DE_4 = RuleClick(roi_front=(1200,282,56,53), roi_back=(1200,282,56,53), name="de_4")
70+
C_DE_4 = RuleClick(roi_front=(1214,297,34,27), roi_back=(1214,297,34,27), name="de_4")
71+
# 灯笼1类型识别搜索区(须容纳完整灯笼图案, 仅供check_lantern匹配, 不用于点击)
72+
C_DE_MATCH_1 = RuleClick(roi_front=(1211,478,61,58), roi_back=(1211,478,61,58), name="de_match_1")
73+
# 灯笼2类型识别搜索区
74+
C_DE_MATCH_2 = RuleClick(roi_front=(1196,409,55,56), roi_back=(1196,409,55,56), name="de_match_2")
75+
# 灯笼3类型识别搜索区
76+
C_DE_MATCH_3 = RuleClick(roi_front=(1225,344,53,55), roi_back=(1225,344,53,55), name="de_match_3")
77+
# 灯笼4类型识别搜索区
78+
C_DE_MATCH_4 = RuleClick(roi_front=(1200,282,56,53), roi_back=(1200,282,56,53), name="de_match_4")
7179

7280

7381
# Image Rule Assets
@@ -96,6 +104,8 @@ class DemonEncounterAssets:
96104
I_DE_BALLOON = RuleImage(roi_front=(1214,295,28,27), roi_back=(1198,269,81,266), threshold=0.8, method="Template matching", file="./tasks/DemonEncounter/demon/demon_de_balloon.png")
97105
# 右侧的宝箱
98106
I_DE_BOX = RuleImage(roi_front=(1210,295,34,33), roi_back=(1183,278,96,277), threshold=0.8, method="Template matching", file="./tasks/DemonEncounter/demon/demon_de_box.png")
107+
# 地图中央未购买的宝箱展示
108+
I_DE_BOX_CENTER = RuleImage(roi_front=(618,325,45,34), roi_back=(547,264,190,157), threshold=0.8, method="Template matching", file="./tasks/DemonEncounter/demon/demon_de_box_center.png")
99109
# 挑战某一个后的封印图片
100110
I_DE_DEFEAT_2 = RuleImage(roi_front=(1211,422,28,35), roi_back=(1211,422,28,35), threshold=0.7, method="Template matching", file="./tasks/DemonEncounter/demon/demon_de_defeat_2.png")
101111
# description
@@ -126,7 +136,7 @@ class DemonEncounterAssets:
126136
# 计数已经开启多少的
127137
O_DE_COUNTER = RuleOcr(roi=(1204,685,48,34), area=(1204,685,48,34), mode="DigitCounter", method="Default", keyword="", name="de_counter")
128138
# 现世逢魔顶部今日挑战次数X/1的最小识别区, 0/1表示已打过直接结束
129-
O_DE_CHALLENGE_COUNT = RuleOcr(roi=(705,68,45,36), area=(705,68,45,36), mode="Full", method="Default", keyword="", name="de_challenge_count")
139+
O_DE_CHALLENGE_COUNT = RuleOcr(roi=(705,68,45,36), area=(705,68,45,36), mode="DigitCounter", method="Default", keyword="", name="de_challenge_count")
130140

131141

132142
# Click Rule Assets
Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,50 @@
11
[
22
{
33
"itemName": "de_1",
4-
"roiFront": "1211,478,61,58",
5-
"roiBack": "1211,478,61,58",
4+
"roiFront": "1222,497,39,25",
5+
"roiBack": "1222,497,39,25",
66
"description": "从下开始数第一个"
77
},
88
{
99
"itemName": "de_2",
10-
"roiFront": "1196,409,55,56",
11-
"roiBack": "1196,409,55,56",
10+
"roiFront": "1204,424,39,31",
11+
"roiBack": "1204,424,39,31",
1212
"description": "2"
1313
},
1414
{
1515
"itemName": "de_3",
16-
"roiFront": "1225,344,53,55",
17-
"roiBack": "1225,344,53,55",
16+
"roiFront": "1234,364,32,22",
17+
"roiBack": "1234,364,32,22",
1818
"description": "3"
1919
},
2020
{
2121
"itemName": "de_4",
22+
"roiFront": "1214,297,34,27",
23+
"roiBack": "1214,297,34,27",
24+
"description": "第四个"
25+
},
26+
{
27+
"itemName": "de_match_1",
28+
"roiFront": "1211,478,61,58",
29+
"roiBack": "1211,478,61,58",
30+
"description": "灯笼1类型识别搜索区(须容纳完整灯笼图案, 仅供check_lantern匹配, 不用于点击)"
31+
},
32+
{
33+
"itemName": "de_match_2",
34+
"roiFront": "1196,409,55,56",
35+
"roiBack": "1196,409,55,56",
36+
"description": "灯笼2类型识别搜索区"
37+
},
38+
{
39+
"itemName": "de_match_3",
40+
"roiFront": "1225,344,53,55",
41+
"roiBack": "1225,344,53,55",
42+
"description": "灯笼3类型识别搜索区"
43+
},
44+
{
45+
"itemName": "de_match_4",
2246
"roiFront": "1200,282,56,53",
2347
"roiBack": "1200,282,56,53",
24-
"description": "第四个"
48+
"description": "灯笼4类型识别搜索区"
2549
}
26-
]
50+
]
2.85 KB
Loading

‎tasks/DemonEncounter/demon/image.json‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,14 @@
7979
"method": "Template matching",
8080
"threshold": 0.8,
8181
"description": "50勾玉购买"
82+
},
83+
{
84+
"itemName": "de_box_center",
85+
"imageName": "demon_de_box_center.png",
86+
"roiFront": "618,325,45,34",
87+
"roiBack": "547,264,190,157",
88+
"method": "Template matching",
89+
"threshold": 0.8,
90+
"description": "地图中央未购买的宝箱展示"
8291
}
83-
]
92+
]

‎tasks/DemonEncounter/demon/ocr.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"itemName": "de_challenge_count",
1313
"roiFront": "705,68,45,36",
1414
"roiBack": "705,68,45,36",
15-
"mode": "Full",
15+
"mode": "DigitCounter",
1616
"method": "Default",
1717
"keyword": "",
1818
"description": "现世逢魔顶部今日挑战次数X/1的最小识别区, 0/1表示已打过直接结束"

‎tasks/DemonEncounter/script_task.py‎

Lines changed: 85 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
# github https://github.com/runhey
44
import time
55
from time import sleep
6-
import re
76

87
from enum import Enum
98
from cached_property import cached_property
@@ -61,16 +60,16 @@ def run(self):
6160

6261
def check_challenge_done(self) -> bool:
6362
"""
64-
OCR识别现世逢魔顶部"今日挑战次数:X/1"
65-
:return: True表示0/1今日已打过
63+
OCR识别现世逢魔顶部"今日挑战次数:剩余/总", 支持老号X/1与新号X/2
64+
DigitCounter 返回 (current, remain, total), current 即剩余次数
65+
:return: True表示剩余=0, 今日已打过
6666
"""
67-
results = self.O_DE_CHALLENGE_COUNT.detect_and_ocr(self.device.image)
68-
text = ''.join(r.ocr_text for r in results)
69-
m = re.search(r'([01])\s*/\s*1', text)
70-
if not m:
71-
logger.warning(f'Challenge count not recognized: [{text}], continue by default')
72-
return False
73-
return m.group(1) == '0'
67+
current, _remain, total = self.O_DE_CHALLENGE_COUNT.ocr(self.device.image)
68+
if total > 0:
69+
logger.info(f'Demon encounter challenge count: {current}/{total}')
70+
return current == 0
71+
logger.warning('Challenge count not recognized, assume attempts remain')
72+
return False
7473

7574
def checkout_soul(self):
7675
"""
@@ -94,40 +93,77 @@ def execute_boss(self):
9493
logger.hr('Start boss battle', 1)
9594

9695
def find_boss():
97-
find_btn_clicked = False
98-
timer_find_boss = Timer(10 * 60)
99-
timer_find_boss.start()
100-
while 1:
96+
search_button = self.I_DE_BOSS_BEST if self.best_demon_enable else self.I_DE_BOSS
97+
boss_name = 'best boss' if self.best_demon_enable else 'normal boss'
98+
99+
# 每轮搜索前若中央有未购买的宝箱展示, 先点左下角定位(小指针)把它挪开;
100+
# 一整轮(2次搜索)都没找到则重进逢魔之时清状态, 最多3轮。
101+
for reenter_round in range(1, 4):
101102
self.screenshot()
102-
if self.appear(self.I_BOSS_FIRE) or self.appear(self.I_BEST_BOSS_FIRE):
103-
break
104-
if timer_find_boss.reached():
105-
logger.warning('find boss timeout')
106-
self.set_next_run(task='DemonEncounter', success=False, finish=True, server=False)
107-
raise TaskEnd('DemonEncounter')
108-
if self.appear(self.I_JADE_50):
109-
# 没找到boss但地图中央出现宝箱,导致点击宝箱出现50勾玉购买界面
110-
self.ui_click_until_smt_disappear(self.I_DE_FIND, self.I_JADE_50, interval=1)
111-
continue
112-
if find_btn_clicked and self.click(self.C_DM_BOSS_CLICK, interval=5):
113-
find_btn_clicked = False
114-
continue
115-
if self.best_demon_enable:
103+
if self.appear(self.I_DE_BOX_CENTER):
104+
logger.info(
105+
f'Box display at map center, click location to reset view '
106+
f'(round {reenter_round}/3)'
107+
)
108+
self.appear_then_click(self.I_DE_LOCATION, interval=2)
109+
time.sleep(1)
110+
111+
# 最多重新执行两轮“逢魔/极逢魔 -> 地图中央首领”的完整流程。
112+
for search_attempt in range(1, 3):
116113
self.device.click_record_clear()
117-
if self.appear(self.I_DE_BOSS_BEST) and (not find_btn_clicked):
118-
self.device.click_record_remove(self.I_DE_BOSS_BEST)
119-
if self.click(self.I_DE_BOSS_BEST, interval=4):
120-
logger.info("Finding best boss...")
121-
find_btn_clicked = True
122-
continue
123-
else:
124-
if self.appear(self.I_DE_BOSS) and (not find_btn_clicked):
125-
self.device.click_record_remove(self.I_DE_BOSS)
126-
if self.click(self.I_DE_BOSS, interval=4):
127-
logger.info("Finding normal boss...")
128-
find_btn_clicked = True
114+
self.screenshot()
115+
if self.appear(self.I_BOSS_FIRE) or self.appear(self.I_BEST_BOSS_FIRE):
116+
return True
117+
# 没找到boss但地图中央出现宝箱, 导致点击宝箱出现50勾玉购买界面(事后补救)
118+
if self.appear(self.I_JADE_50):
119+
self.ui_click_until_smt_disappear(self.I_DE_FIND, self.I_JADE_50, interval=1)
129120
continue
130-
return True
121+
if not self.appear_then_click(search_button, interval=2):
122+
raise GameStuckError(f'Cannot find {boss_name} search button')
123+
logger.info(
124+
f'Finding {boss_name}, attempt {search_attempt}/2 '
125+
f'(re-enter round {reenter_round}/3)...'
126+
)
127+
time.sleep(1)
128+
129+
# 每轮点击地图中央框选的红色“集结”区域至多两次,
130+
# 每次等待集结挑战标志5秒。
131+
for center_attempt in range(1, 3):
132+
self.click(self.C_DM_BOSS_CLICK, interval=2)
133+
deadline = time.monotonic() + 5
134+
while time.monotonic() < deadline:
135+
self.screenshot()
136+
if self.appear(self.I_BOSS_FIRE) or self.appear(self.I_BEST_BOSS_FIRE):
137+
logger.info(
138+
f'{boss_name} gather appeared after center click '
139+
f'{center_attempt}/2'
140+
)
141+
return True
142+
time.sleep(0.2)
143+
logger.warning(
144+
f'{boss_name} gather did not appear after center click '
145+
f'{center_attempt}/2'
146+
)
147+
148+
# 本轮失败,返回逢魔地图,重新点击逢魔/极逢魔进行下一轮搜寻。
149+
self.screenshot()
150+
if self.appear(self.I_UI_BACK_RED):
151+
self.appear_then_click(self.I_UI_BACK_RED, interval=2)
152+
deadline = time.monotonic() + 5
153+
while time.monotonic() < deadline:
154+
self.screenshot()
155+
if self.appear(search_button):
156+
break
157+
time.sleep(0.2)
158+
159+
# 2次搜索都没找到: 重进地图清状态, 最多3轮
160+
logger.info(f'Boss not found, re-enter demon encounter map (round {reenter_round}/3)')
161+
self.goto_page(page_demon_encounter)
162+
self.goto_page(page_demon_encounter_realworld)
163+
164+
raise GameStuckError(
165+
f'Cannot enter {boss_name} after 3 re-enter rounds'
166+
)
131167

132168
def enter_boss():
133169
logger.info('trying to enter boss...')
@@ -293,11 +329,13 @@ def check_lantern(self, index: int = 1):
293329
:param index: 四个灯笼,从1开始
294330
:return:
295331
"""
332+
# 分类模板的搜索区(须容纳完整灯笼图案), 与点击区 C_DE_* 分离:
333+
# 点击区只包住内部图形, 模板放不进搜索区会全部误判成 battle
296334
match_roi = {
297-
1: self.C_DE_1.roi_front,
298-
2: self.C_DE_2.roi_front,
299-
3: self.C_DE_3.roi_front,
300-
4: self.C_DE_4.roi_front,
335+
1: self.C_DE_MATCH_1.roi_front,
336+
2: self.C_DE_MATCH_2.roi_front,
337+
3: self.C_DE_MATCH_3.roi_front,
338+
4: self.C_DE_MATCH_4.roi_front,
301339
}
302340
match_empty = {
303341
1: self.I_DE_DEFEAT_1,
@@ -422,9 +460,10 @@ def answer():
422460
break
423461
# 如果没有出现红色关闭按钮,说明答题结束
424462
if not self.appear(self.I_LETTER_CLOSE):
425-
time.sleep(1.8)
463+
time.sleep(2.5)
426464
self.screenshot()
427465
if not self.appear(self.I_LETTER_CLOSE):
466+
self.ui_reward_appear_click()
428467
logger.warning('Answer finish')
429468
return
430469

‎tasks/Dokan/script_task.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,8 @@ def goto_main(self):
511511
if self.appear(self.I_RYOU_DOKAN_DOKAN_QUIT):
512512
self.click(self.I_RYOU_DOKAN_DOKAN_QUIT, interval=3)
513513
continue
514-
if self.appear(self.I_BACK_BL):
515-
self.click(self.I_BACK_BL, interval=3)
514+
if self.appear(self.I_UI_BACK_BLUE):
515+
self.click(self.I_UI_BACK_BLUE, interval=3)
516516
continue
517517
if self.appear(self.I_BACK_Y):
518518
self.click(self.I_BACK_Y, interval=3)

‎tasks/EternitySea/script_task.py‎

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from module.base.timer import Timer
88
from module.logger import logger
99

10-
from tasks.GameUi.game_ui import GameUi, Page
10+
from tasks.GameUi.game_ui import GameUi
1111
from tasks.GameUi.page import page_soul_zones, page_shikigami_records
1212
from tasks.Component.GeneralBattle.general_battle import GeneralBattle
1313
from tasks.Component.GeneralRoom.general_room import GeneralRoom
@@ -44,7 +44,7 @@ def run(self) -> None:
4444
case UserStatus.MEMBER: success = self.run_member()
4545
case UserStatus.ALONE: success = self.run_alone()
4646
case _: logger.error('Unknown user status')
47-
47+
self.goto_page(page_main)
4848
if success:
4949
self.set_next_run(self.task_name, finish=True, success=True)
5050
else:
@@ -55,7 +55,7 @@ def run(self) -> None:
5555

5656
def run_leader(self):
5757
logger.info('Start run leader')
58-
self._navigate_to_soul_zones()
58+
self.goto_page(page_soul_zones)
5959
self._enter_eternity_sea()
6060
layer = self._task_config.eternity_sea_config.layer
6161
self.check_layer(layer)
@@ -224,7 +224,7 @@ def run_member(self):
224224

225225
def run_alone(self) -> bool:
226226
logger.info("Start run alone")
227-
self._navigate_to_soul_zones()
227+
self.goto_page(page_soul_zones)
228228
self._enter_eternity_sea()
229229

230230
if self._task_config.general_battle_config.lock_team_enable == False:
@@ -266,16 +266,6 @@ def is_room_dead(self) -> bool:
266266
return True
267267
return False
268268

269-
def eternitysea_enter(self) -> bool:
270-
logger.info('Enter EternitySea')
271-
while True:
272-
self.screenshot()
273-
if self.appear(self.I_FORM_TEAM):
274-
return True
275-
if self.appear_then_click(self.I_ETERNITY_SEA, interval=1):
276-
continue
277-
278-
279269
def _is_in_eternity_sea(self) -> bool:
280270
self.screenshot()
281271
return self.appear(self.I_ETERNITY_SEA_FIRE)
@@ -299,12 +289,6 @@ def _enter_eternity_sea(self) -> None:
299289
if self.appear_then_click(self.I_BACK_BOTTOM, interval=1):
300290
continue
301291

302-
def _navigate_to_soul_zones(self) -> None:
303-
self.goto_page(page_soul_zones)
304-
305-
def _navigate_to_game_page(self, destination: Page) -> None:
306-
self.goto_page(destination)
307-
308292
@property
309293
def _task_config(self) -> EternitySea:
310294
return self.config.model.eternity_sea

‎tasks/FallenSun/script_task.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ def is_in_fallen_sun(screenshot=False) -> bool:
284284
self.screenshot()
285285
if not self.appear(self.I_FORM_TEAM):
286286
break
287-
if self.appear_then_click(self.I_BACK_BL, interval=2):
287+
if self.appear_then_click(self.I_UI_BACK_BLUE, interval=2):
288288
continue
289289
if self.appear_then_click(self.I_UI_BACK_YELLOW, interval=2):
290290
continue

0 commit comments

Comments
 (0)