refactor(task): 将培育中 acquisitions 函数所有 OCR 改为模板匹配

This commit is contained in:
XcantloadX 2025-03-16 20:24:20 +08:00
parent 425e998adb
commit 6e336d94f1
10 changed files with 39 additions and 40 deletions

View File

@ -1 +1 @@
{"definitions":{"05890a1b-8764-4e9f-9d21-65d292c22e13":{"name":"InPurodyuusu.BoxGoalClearNext","displayName":"培育目标达成 NEXT 文字区域","type":"hint-box","annotationId":"05890a1b-8764-4e9f-9d21-65d292c22e13","useHintRect":false}},"annotations":[{"id":"05890a1b-8764-4e9f-9d21-65d292c22e13","type":"rect","data":{"x1":79,"y1":503,"x2":157,"y2":532}}]}
{"definitions":{"05890a1b-8764-4e9f-9d21-65d292c22e13":{"name":"InPurodyuusu.TextGoalClearNext","displayName":"培育目标达成 NEXT 文字","type":"template","annotationId":"05890a1b-8764-4e9f-9d21-65d292c22e13","useHintRect":false}},"annotations":[{"id":"05890a1b-8764-4e9f-9d21-65d292c22e13","type":"rect","data":{"x1":79,"y1":503,"x2":157,"y2":532}}]}

View File

@ -1 +1 @@
{"definitions":{"582d36c0-0916-4706-9833-4fbc026701f5":{"name":"InPurodyuusu.BoxPDrinkMaxConfirmTitle","displayName":"P饮料溢出 不领取弹窗标题","type":"hint-box","annotationId":"582d36c0-0916-4706-9833-4fbc026701f5","useHintRect":false}},"annotations":[{"id":"582d36c0-0916-4706-9833-4fbc026701f5","type":"rect","data":{"x1":46,"y1":829,"x2":270,"y2":876}}]}
{"definitions":{"582d36c0-0916-4706-9833-4fbc026701f5":{"name":"InPurodyuusu.TextPDrinkMaxConfirmTitle","displayName":"P饮料溢出 不领取弹窗标题","type":"template","annotationId":"582d36c0-0916-4706-9833-4fbc026701f5","useHintRect":false}},"annotations":[{"id":"582d36c0-0916-4706-9833-4fbc026701f5","type":"rect","data":{"x1":46,"y1":829,"x2":270,"y2":876}}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 465 KiB

View File

@ -0,0 +1 @@
{"definitions":{"8c179a21-be6f-4db8-a9b0-9afeb5c36b1c":{"name":"InPurodyuusu.TextPDrink","displayName":"文本「Pドリンク」","type":"template","annotationId":"8c179a21-be6f-4db8-a9b0-9afeb5c36b1c","useHintRect":false,"description":"用于 P 饮料选择对话框"}},"annotations":[{"id":"8c179a21-be6f-4db8-a9b0-9afeb5c36b1c","type":"rect","data":{"x1":244,"y1":615,"x2":357,"y2":641}}]}

View File

@ -1 +1 @@
{"definitions":{"6b58d90d-2e5e-4b7f-bc01-941f2633de89":{"name":"InPurodyuusu.BoxSelectPStuff","displayName":"选择奖励对话框提示语","type":"hint-box","annotationId":"6b58d90d-2e5e-4b7f-bc01-941f2633de89","useHintRect":false},"b3c9e526-de47-44c2-9bda-e9a8a79fdb5a":{"name":"InPurodyuusu.BoxSelectPStuffComfirm","displayName":"选择奖励对话框 领取按钮","type":"hint-box","annotationId":"b3c9e526-de47-44c2-9bda-e9a8a79fdb5a","useHintRect":false}},"annotations":[{"id":"6b58d90d-2e5e-4b7f-bc01-941f2633de89","type":"rect","data":{"x1":62,"y1":558,"x2":655,"y2":716}},{"id":"b3c9e526-de47-44c2-9bda-e9a8a79fdb5a","type":"rect","data":{"x1":256,"y1":1064,"x2":478,"y2":1128}}]}
{"definitions":{"b3c9e526-de47-44c2-9bda-e9a8a79fdb5a":{"name":"InPurodyuusu.BoxSelectPStuffComfirm","displayName":"选择奖励对话框 领取按钮","type":"hint-box","annotationId":"b3c9e526-de47-44c2-9bda-e9a8a79fdb5a","useHintRect":false},"c948f136-416f-447e-8152-54a1cd1d1329":{"name":"InPurodyuusu.TextClaim","displayName":"文字「受け取る」","type":"template","annotationId":"c948f136-416f-447e-8152-54a1cd1d1329","useHintRect":false,"description":"用于 P 物品、P 饮料、技能卡选择对话框"},"0c0627be-4a09-4450-a078-1858d3ace532":{"name":"InPurodyuusu.TextPItem","displayName":"文字「Pアイテム」","type":"template","annotationId":"0c0627be-4a09-4450-a078-1858d3ace532","useHintRect":false,"description":"用于 P 物品选择对话框"}},"annotations":[{"id":"b3c9e526-de47-44c2-9bda-e9a8a79fdb5a","type":"rect","data":{"x1":256,"y1":1064,"x2":478,"y2":1128}},{"id":"c948f136-416f-447e-8152-54a1cd1d1329","type":"rect","data":{"x1":144,"y1":608,"x2":245,"y2":647}},{"id":"0c0627be-4a09-4450-a078-1858d3ace532","type":"rect","data":{"x1":247,"y1":613,"x2":354,"y2":645}}]}

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 KiB

View File

@ -0,0 +1 @@
{"definitions":{"d271a24f-efe8-424d-8fd5-f6b3756ba4ca":{"name":"InPurodyuusu.TextSkillCard","displayName":"文字「スキルカード」","type":"template","annotationId":"d271a24f-efe8-424d-8fd5-f6b3756ba4ca","useHintRect":false,"description":"用于技能卡选择对话框"}},"annotations":[{"id":"d271a24f-efe8-424d-8fd5-f6b3756ba4ca","type":"rect","data":{"x1":229,"y1":614,"x2":372,"y2":645}}]}

View File

@ -1 +1 @@
{"definitions":{"6b58d90d-2e5e-4b7f-bc01-941f2633de89":{"name":"InPurodyuusu.BoxSkillCardEnhaced","displayName":"技能卡强化文本提示","type":"hint-box","annotationId":"6b58d90d-2e5e-4b7f-bc01-941f2633de89","useHintRect":false}},"annotations":[{"id":"6b58d90d-2e5e-4b7f-bc01-941f2633de89","type":"rect","data":{"x1":49,"y1":948,"x2":676,"y2":1106}}]}
{"definitions":{"6b58d90d-2e5e-4b7f-bc01-941f2633de89":{"name":"InPurodyuusu.IconSkillCardEventBubble","displayName":"技能卡事件气泡框图标","type":"template","annotationId":"6b58d90d-2e5e-4b7f-bc01-941f2633de89","useHintRect":false,"description":"背景上左右两边的星星"}},"annotations":[{"id":"6b58d90d-2e5e-4b7f-bc01-941f2633de89","type":"rect","data":{"x1":46,"y1":1007,"x2":79,"y2":1047}}]}

View File

@ -1,6 +1,7 @@
from typing import Literal
from logging import getLogger
from kotonebot.backend.preprocessor import HsvColorFilter
from kotonebot.tasks.actions.loading import loading
from .. import R
@ -14,7 +15,7 @@ from kotonebot import (
sleep,
Interval,
)
from ..game_ui import CommuEventButtonUI
from ..game_ui import CommuEventButtonUI, WhiteFilter
from .pdorinku import acquire_pdorinku
from kotonebot.backend.dispatch import SimpleDispatcher
from kotonebot.tasks.actions.commu import handle_unread_commu
@ -55,7 +56,7 @@ def acquire_skill_card():
def select_p_item():
"""
前置条件P物品选择对话框受け取るPアイテムを選んでください;\n
结束条件P物品获取动画
结束状态P物品获取动画
"""
# 前置条件 [screenshots/produce/in_produce/select_p_item.png]
# 前置条件 [screenshots/produce/in_produce/claim_p_item.png]
@ -73,12 +74,12 @@ def select_p_item():
def hanlde_skill_card_enhance():
"""
前置条件技能卡强化对话框\n
结束条件技能卡强化动画结束后瞬间
结束状态技能卡强化动画结束后瞬间
:return: 是否成功处理对话框
"""
# 前置条件 [kotonebot-resource\sprites\jp\in_purodyuusu\screenshot_skill_card_enhane.png]
# 结束条件 [screenshots/produce/in_produce/skill_card_enhance.png]
# 结束状态 [screenshots/produce/in_produce/skill_card_enhance.png]
cards = image.find_multi([
R.InPurodyuusu.A,
R.InPurodyuusu.M
@ -93,7 +94,7 @@ def hanlde_skill_card_enhance():
device.screenshot()
if image.find(R.InPurodyuusu.ButtonEnhance, colored=True):
device.click()
elif '強化' in ocr.ocr(rect=R.InPurodyuusu.BoxSkillCardEnhaced).squash().text:
elif image.find(R.InPurodyuusu.IconSkillCardEventBubble):
device.click_center()
break
it.wait()
@ -104,11 +105,10 @@ AcquisitionType = Literal[
"PDrinkSelect", # P饮料主动领取
"PDrinkMax", # P饮料到达上限
"PSkillCardAcquire", # 技能卡领取
"PSkillCardChange", # 技能卡更换
"PSkillCardSelect", # 技能卡选择
"PSkillCardEnhanced", # 技能卡强化
"PSkillCardEnhanceSelect", # 技能卡强化选择
"PSkillCardRemove", # 技能卡移除
"PSkillCardEvent", # 技能卡事件(随机强化、删除、更换)
"PItemClaim", # P物品领取
"PItemSelect", # P物品选择
"Clear", # 目标达成
@ -118,7 +118,7 @@ AcquisitionType = Literal[
"Loading", # 加载画面
]
@measure_time(file_path='logs/acquisition.time.log')
@measure_time()
@action('处理培育事件', screenshot_mode='manual')
def acquisitions() -> AcquisitionType | None:
"""处理行动开始前和结束后可能需要处理的事件,直到到行动页面为止"""
@ -158,10 +158,10 @@ def acquisitions() -> AcquisitionType | None:
logger.info("Leave button found")
device.click(leave)
return "PDrinkMax"
if ocr.find(contains('報酬'), rect=R.InPurodyuusu.BoxPDrinkMaxConfirmTitle):
if image.find(R.InPurodyuusu.TextPDrinkMaxConfirmTitle):
logger.debug("PDrink max confirm found")
device.screenshot()
if ocr.find(contains('報酬'), rect=R.InPurodyuusu.BoxPDrinkMaxConfirmTitle):
if image.find(R.InPurodyuusu.TextPDrinkMaxConfirmTitle):
if confirm := image.find(R.Common.ButtonConfirm):
logger.info("Confirm button found")
device.click(confirm)
@ -190,7 +190,7 @@ def acquisitions() -> AcquisitionType | None:
sleep(1)
return "Clear"
# 目标达成 NEXT
if ocr.find(regex('NEXT|next'), rect=R.InPurodyuusu.BoxGoalClearNext):
if image.find(R.InPurodyuusu.TextGoalClearNext, preprocessors=[WhiteFilter()]):
logger.info("Goal clear (達成) next found")
device.click_center()
sleep(1)
@ -218,53 +218,44 @@ def acquisitions() -> AcquisitionType | None:
# 物品选择对话框
logger.debug("Check award select dialog...")
if result := ocr.find(contains("受け取る"), rect=R.InPurodyuusu.BoxSelectPStuff):
if image.find(R.InPurodyuusu.TextClaim):
logger.info("Award select dialog found.")
logger.debug(f"Dialog text: {result.text}")
# P饮料选择
logger.debug("Check PDrink select...")
if "Pドリンク" in result.text:
if image.find(R.InPurodyuusu.TextPDrink):
logger.info("PDrink select found")
acquire_pdorinku(index=0)
return "PDrinkSelect"
# 技能卡选择
logger.debug("Check skill card select...")
if "スキルカード" in result.text:
if image.find(R.InPurodyuusu.TextSkillCard):
logger.info("Acquire skill card found")
acquire_skill_card()
return "PSkillCardSelect"
# P物品选择
logger.debug("Check PItem select...")
if "Pアイテム" in result.text:
if image.find(R.InPurodyuusu.TextPItem):
logger.info("Acquire PItem found")
select_p_item()
return "PItemSelect"
# 技能卡变更事件
# 包括下面这些:
# 1. 技能卡更换
# [screenshots/produce/in_produce/support_card_change.png]
# 2. 技能卡强化
# [screenshots/produce/in_produce/skill_card_enhance.png]
# 3. 技能卡移除
# [screenshots/produce/in_produce/skill_card_removal.png]
logger.debug("Check skill card events...")
if result := ocr.ocr(rect=R.InPurodyuusu.BoxSkillCardEnhaced).squash():
# 技能卡更换(支援卡效果)
# [screenshots/produce/in_produce/support_card_change.png]
if "チェンジ" in result.text:
logger.info("Change skill card found")
device.click(*bottom_pos)
return "PSkillCardChange"
# 技能卡强化
# [screenshots/produce/in_produce/skill_card_enhance.png]
if "強化" in result.text:
logger.info("Enhance skill card found")
device.click(*bottom_pos)
return "PSkillCardEnhanced"
# 技能卡移除
# [screenshots\produce\in_produce\skill_card_removal.png]
if "削除" in result.text:
logger.info("Remove skill card found")
device.click(*bottom_pos)
return "PSkillCardRemove"
if image.find(R.InPurodyuusu.IconSkillCardEventBubble):
device.click() # 不能 click_center因为中间是技能卡
return "PSkillCardEvent"
# 技能卡获取
# [res/sprites/jp/in_purodyuusu/screenshot_skill_card_acquired.png]
# [kotonebot-resource\sprites\jp\in_purodyuusu\screenshot_skill_card_acquired.png]
# 因为这个文本有缩放动画,因此暂时没法用模板匹配代替
if ocr.find("スキルカード獲得", rect=R.InPurodyuusu.BoxSkillCardAcquired):
logger.info("Acquire skill card from loot box")
device.click_center()

View File

@ -193,6 +193,12 @@ class CommuEventButtonUI:
return ocr_result.squash().text
class WhiteFilter(HsvColorFilter):
"""
匹配时只匹配图像和模板中的白色部分
此类用于识别空心/透明背景的白色图标或文字
"""
def __init__(self):
super().__init__(WHITE_LOW, WHITE_HIGH)