feat(task): 优化培育与日常流程,修复一些 bug
1. 优化工作页面重新分配后的结束动画检测逻辑 2. 修复无法处理培育中,目前已有两个饮料,一次获得两个饮料时,弹出的饮料溢出弹窗 3. 调整培育中无推荐行动时执行行动的优先级 4. 支持 PRO 培育的中断继续 5. 修复培育中外出事件时,若弹出 AP 溢出提示,会卡住的问题 6. 优化加载画面的检测
This commit is contained in:
parent
62d5805b96
commit
145f97f148
Binary file not shown.
After Width: | Height: | Size: 723 KiB |
|
@ -0,0 +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}}]}
|
Before Width: | Height: | Size: 410 KiB After Width: | Height: | Size: 410 KiB |
|
@ -0,0 +1 @@
|
|||
{"definitions":{"5ebcde3b-f0fd-4e5d-b3de-ada8f0b5e03b":{"name":"Common.ButtonSelect2","displayName":"選択する","type":"template","annotationId":"5ebcde3b-f0fd-4e5d-b3de-ada8f0b5e03b","useHintRect":false}},"annotations":[{"id":"5ebcde3b-f0fd-4e5d-b3de-ada8f0b5e03b","type":"rect","data":{"x1":393,"y1":1145,"x2":577,"y2":1176}}]}
|
|
@ -9,6 +9,7 @@ from kotonebot import (
|
|||
device,
|
||||
contains,
|
||||
image,
|
||||
regex,
|
||||
action,
|
||||
sleep,
|
||||
Interval,
|
||||
|
@ -110,6 +111,7 @@ AcquisitionType = Literal[
|
|||
"PItemClaim", # P物品领取
|
||||
"PItemSelect", # P物品选择
|
||||
"Clear", # 目标达成
|
||||
"ClearNext", # 目标达成 NEXT
|
||||
"NetworkError", # 网络中断弹窗
|
||||
"SkipCommu", # 跳过交流
|
||||
"Loading", # 加载画面
|
||||
|
@ -143,6 +145,13 @@ def acquisitions() -> AcquisitionType | None:
|
|||
logger.debug("PDrink max found")
|
||||
device.screenshot()
|
||||
if image.find(R.InPurodyuusu.TextPDrinkMax):
|
||||
# 有对话框标题,但是没找到确认按钮
|
||||
# 可能是需要勾选一个饮料
|
||||
if not image.find(R.InPurodyuusu.ButtonLeave, colored=True):
|
||||
logger.info("No leave button found, click checkbox")
|
||||
device.click(image.expect(R.Common.CheckboxUnchecked, colored=True))
|
||||
sleep(0.2)
|
||||
device.screenshot()
|
||||
if leave := image.find(R.InPurodyuusu.ButtonLeave, colored=True):
|
||||
logger.info("Leave button found")
|
||||
device.click(leave)
|
||||
|
@ -171,16 +180,19 @@ def acquisitions() -> AcquisitionType | None:
|
|||
return "PSkillCardEnhanceSelect"
|
||||
|
||||
# 目标达成
|
||||
logger.debug("Check gloal clear...")
|
||||
logger.debug("Check gloal clear (達成)...")
|
||||
if image.find(R.InPurodyuusu.IconClearBlue):
|
||||
logger.info("Clear found")
|
||||
logger.debug("達成: clicked")
|
||||
device.click_center()
|
||||
sleep(5)
|
||||
# TODO: 可能不存在 達成 NEXT
|
||||
logger.debug("達成 NEXT: clicked") # TODO: 需要截图
|
||||
logger.debug("Goal clear (達成): clicked")
|
||||
device.click_center()
|
||||
sleep(1)
|
||||
return "Clear"
|
||||
# 目标达成 NEXT
|
||||
if ocr.find(regex('NEXT|next'), rect=R.InPurodyuusu.BoxGoalClearNext):
|
||||
logger.info("Goal clear (達成) next found")
|
||||
device.click_center()
|
||||
sleep(1)
|
||||
return "ClearNext"
|
||||
# P物品领取
|
||||
logger.debug("Check PItem claim...")
|
||||
if image.find(R.InPurodyuusu.PItemIconColorful):
|
||||
|
|
|
@ -733,10 +733,10 @@ def week_normal(week_first: bool = False):
|
|||
elif executed_action is None:
|
||||
if outing_available():
|
||||
enter_outing()
|
||||
elif allowance_available():
|
||||
enter_allowance()
|
||||
elif study_available():
|
||||
enter_study()
|
||||
elif allowance_available():
|
||||
enter_allowance()
|
||||
elif is_rest_available():
|
||||
rest()
|
||||
else:
|
||||
|
@ -856,7 +856,7 @@ ProduceStage = Literal[
|
|||
]
|
||||
|
||||
@action('检测当前培育场景', dispatcher=True)
|
||||
def detect_regular_produce_scene(ctx: DispatcherContext) -> ProduceStage:
|
||||
def detect_produce_scene(ctx: DispatcherContext) -> ProduceStage:
|
||||
"""
|
||||
判断当前是培育的什么阶段,并开始 Regular 培育。
|
||||
|
||||
|
@ -896,7 +896,7 @@ def detect_regular_produce_scene(ctx: DispatcherContext) -> ProduceStage:
|
|||
return 'unknown'
|
||||
|
||||
@action('开始 Regular 培育')
|
||||
def hajime_regular_from_stage(stage: ProduceStage):
|
||||
def hajime_regular_from_stage(stage: ProduceStage, type: Literal['regular', 'pro']):
|
||||
"""
|
||||
开始 Regular 培育。
|
||||
"""
|
||||
|
@ -907,12 +907,15 @@ def hajime_regular_from_stage(stage: ProduceStage):
|
|||
if not remaining_week:
|
||||
raise UnrecoverableError("Failed to detect week.")
|
||||
# 判断阶段
|
||||
MID_WEEK = 6 if type == 'regular' else 7
|
||||
FINAL_WEEK = 13 if type == 'regular' else 16
|
||||
function = hajime_regular if type == 'regular' else hajime_pro
|
||||
if texts.where(contains('中間')):
|
||||
week = 6 - remaining_week[0]
|
||||
hajime_regular(start_from=week)
|
||||
week = MID_WEEK - remaining_week[0]
|
||||
function(start_from=week)
|
||||
elif texts.where(contains('最終')):
|
||||
week = 13 - remaining_week[0]
|
||||
hajime_regular(start_from=week)
|
||||
week = FINAL_WEEK - remaining_week[0]
|
||||
function(start_from=week)
|
||||
else:
|
||||
raise UnrecoverableError("Failed to detect produce stage.")
|
||||
elif stage == 'exam-start':
|
||||
|
@ -925,7 +928,7 @@ def hajime_regular_from_stage(stage: ProduceStage):
|
|||
exam()
|
||||
result = ocr.expect_wait(contains('中間|最終'))
|
||||
if '中間' in result.text:
|
||||
return hajime_regular_from_stage(detect_regular_produce_scene())
|
||||
return hajime_regular_from_stage(detect_produce_scene(), type)
|
||||
elif '最終' in result.text:
|
||||
produce_end()
|
||||
else:
|
||||
|
@ -934,7 +937,7 @@ def hajime_regular_from_stage(stage: ProduceStage):
|
|||
# TODO: 应该直接调用 week_final_exam 而不是再写一次
|
||||
logger.info("Practice ongoing. Start practice.")
|
||||
practice()
|
||||
return hajime_regular_from_stage(detect_regular_produce_scene())
|
||||
return hajime_regular_from_stage(detect_produce_scene(), type)
|
||||
else:
|
||||
raise UnrecoverableError(f'Cannot resume produce REGULAR from stage "{stage}".')
|
||||
|
||||
|
@ -943,7 +946,14 @@ def resume_regular_produce():
|
|||
"""
|
||||
继续 Regular 培育。
|
||||
"""
|
||||
hajime_regular_from_stage(detect_regular_produce_scene())
|
||||
hajime_regular_from_stage(detect_produce_scene(), 'regular')
|
||||
|
||||
@action('继续 PRO 培育')
|
||||
def resume_pro_produce():
|
||||
"""
|
||||
继续 PRO 培育。
|
||||
"""
|
||||
hajime_regular_from_stage(detect_produce_scene(), 'pro')
|
||||
|
||||
if __name__ == '__main__':
|
||||
from logging import getLogger
|
||||
|
@ -989,8 +999,8 @@ if __name__ == '__main__':
|
|||
|
||||
# hajime_pro(start_from=16)
|
||||
# exam('mid')
|
||||
stage = (detect_regular_produce_scene())
|
||||
hajime_regular_from_stage(stage)
|
||||
stage = (detect_produce_scene())
|
||||
hajime_regular_from_stage(stage, 'pro')
|
||||
|
||||
# click_recommended_card(card_count=skill_card_count())
|
||||
# exam('mid')
|
||||
|
|
|
@ -17,8 +17,8 @@ def loading() -> bool:
|
|||
original_img = img.copy()
|
||||
# 二值化图片
|
||||
_, img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
|
||||
# 裁剪上面 20%
|
||||
img = img[:int(img.shape[0] * 0.2), :]
|
||||
# 裁剪上面 35%
|
||||
img = img[:int(img.shape[0] * 0.35), :]
|
||||
# 判断图片中颜色数量是否 <= 2
|
||||
# https://stackoverflow.com/questions/56606294/count-number-of-unique-colours-in-image
|
||||
b,g,r = cv2.split(img)
|
||||
|
|
|
@ -196,7 +196,7 @@ def enter_outing():
|
|||
elif acquisitions():
|
||||
pass
|
||||
# [screenshots\produce\outing_ap_confirm.png]
|
||||
elif image.find(R.Common.ButtonSelect):
|
||||
elif image.find(R.Common.ButtonSelect2):
|
||||
logger.info("AP max out dialog found. Click to continue.")
|
||||
device.click()
|
||||
sleep(0.1)
|
||||
|
|
|
@ -54,13 +54,13 @@ def goto_home():
|
|||
elif home := toolbar_home():
|
||||
device.click(home)
|
||||
logger.debug("Clicked toolbar home button.")
|
||||
sleep(0.2)
|
||||
sleep(1)
|
||||
# 課題CLEAR [screenshots/go_home/quest_clear.png]
|
||||
elif image.find(R.Common.ButtonIconClose):
|
||||
device.click()
|
||||
logger.debug("Clicked close button.")
|
||||
sleep(0.2)
|
||||
|
||||
logger.debug(f"Trying to go home...")
|
||||
it.wait()
|
||||
|
||||
@action('前往商店页面')
|
||||
|
|
|
@ -31,7 +31,7 @@ def assign(type: Literal['mini', 'online']) -> bool:
|
|||
分配工作
|
||||
|
||||
前置条件:分配工作页面 \n
|
||||
结束状态:工作开始动画
|
||||
结束状态:分配工作页面
|
||||
|
||||
:param type: 工作类型。mini=ミニライブ 或 online=ライブ配信。
|
||||
"""
|
||||
|
@ -103,10 +103,13 @@ def assign(type: Literal['mini', 'online']) -> bool:
|
|||
else:
|
||||
logger.warning(f'{target_duration}時間 not found. Using default duration.')
|
||||
sleep(0.5)
|
||||
# 点击 决定する
|
||||
device.click(confirm)
|
||||
# 点击 開始する [screenshots/assignment/assign_mini_live3.png]
|
||||
device.click(image.expect_wait(R.Common.ButtonStart, timeout=5))
|
||||
while not at_assignment():
|
||||
# 点击 决定する
|
||||
if image.find(R.Common.ButtonConfirmNoIcon):
|
||||
device.click()
|
||||
elif image.find(R.Common.ButtonStart):
|
||||
# 点击 開始する [screenshots/assignment/assign_mini_live3.png]
|
||||
device.click()
|
||||
return True
|
||||
|
||||
@action('获取剩余时间')
|
||||
|
|
|
@ -164,6 +164,7 @@ def do_produce(idol: PIdol, mode: Literal['regular', 'pro']) -> bool:
|
|||
break
|
||||
elif image.find(R.Produce.ButtonAutoSet):
|
||||
device.click()
|
||||
sleep(1)
|
||||
elif image.find(R.Common.ButtonConfirm, colored=True):
|
||||
device.click()
|
||||
device.screenshot()
|
||||
|
|
Loading…
Reference in New Issue