feat(task): 工作奖励收取与分配
This commit is contained in:
parent
b92c0f0cc3
commit
1148f6a013
|
@ -2,6 +2,8 @@
|
|||
tests/output_images
|
||||
tests/output_images/*
|
||||
R.py
|
||||
kotonebot-ui/node_modules
|
||||
kotonebot-ui/.vite
|
||||
##########################
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
|
|
|
@ -2,7 +2,7 @@ import os
|
|||
from typing import NamedTuple, Protocol, TypeVar, Sequence, runtime_checkable
|
||||
from logging import getLogger
|
||||
|
||||
from .debug import result, debug, img
|
||||
from .debug import result as debug_result, debug, img
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
@ -302,7 +302,7 @@ def find(
|
|||
result_text += f"matches: {len(matches)} \n"
|
||||
for match in matches:
|
||||
result_text += f"score: {match.score} position: {match.position} size: {match.size} \n"
|
||||
result(f"image.find", result_image, result_text)
|
||||
debug_result(f"image.find", result_image, result_text)
|
||||
return matches[0] if len(matches) > 0 else None
|
||||
|
||||
def find_many(
|
||||
|
@ -336,7 +336,7 @@ def find_many(
|
|||
]
|
||||
if debug.enabled:
|
||||
result_image = _draw_result(image, results)
|
||||
result(
|
||||
debug_result(
|
||||
'image.find_many',
|
||||
result_image,
|
||||
f"template: {img(template)} \n"
|
||||
|
@ -389,7 +389,7 @@ def find_any(
|
|||
]) +
|
||||
"</table>\n"
|
||||
)
|
||||
result(
|
||||
debug_result(
|
||||
'image.find_any',
|
||||
_draw_result(image, ret),
|
||||
msg
|
||||
|
@ -427,7 +427,7 @@ def count(
|
|||
]
|
||||
if debug.enabled:
|
||||
result_image = _draw_result(image, results)
|
||||
result(
|
||||
debug_result(
|
||||
'image.count',
|
||||
result_image,
|
||||
(
|
||||
|
@ -461,7 +461,7 @@ def expect(
|
|||
"""
|
||||
ret = find(image, template, mask, transparent, threshold, colored=colored)
|
||||
if debug.enabled:
|
||||
result(
|
||||
debug_result(
|
||||
'image.expect',
|
||||
_draw_result(image, ret),
|
||||
(
|
||||
|
@ -481,11 +481,23 @@ def expect(
|
|||
def similar(
|
||||
image1: MatLike,
|
||||
image2: MatLike,
|
||||
threshold: float = 0.8
|
||||
threshold: float = 0.9
|
||||
) -> bool:
|
||||
"""
|
||||
判断两张图像是否相似。输入的两张图片必须为相同尺寸。
|
||||
判断两张图像是否相似(灰度)。输入的两张图片必须为相同尺寸。
|
||||
"""
|
||||
if image1.shape != image2.shape:
|
||||
raise ValueError('Expected two images with the same size.')
|
||||
return structural_similarity(image1, image2, multichannel=True) >= threshold
|
||||
image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
|
||||
image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
|
||||
result = structural_similarity(image1, image2, multichannel=True)
|
||||
# 调试输出
|
||||
if debug.enabled:
|
||||
result_image = np.hstack([image1, image2])
|
||||
debug_result(
|
||||
'image.similar',
|
||||
result_image,
|
||||
f"result: {result} >= {threshold} == {result >= threshold} \n"
|
||||
)
|
||||
return result >= threshold
|
||||
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
"""工作。お仕事"""
|
||||
import logging
|
||||
from time import sleep
|
||||
from typing import Literal
|
||||
from kotonebot import task, device, image, action, ocr, contains, cropped
|
||||
from .actions.scenes import at_home, goto_home
|
||||
from . import R
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@action
|
||||
def acquire_assignment():
|
||||
"""
|
||||
领取工作奖励
|
||||
|
||||
前置条件:点击了工作按钮,已进入领取页面 \n
|
||||
结束状态:分配工作页面
|
||||
"""
|
||||
# 领取奖励 [screenshots/assignment/acquire.png]
|
||||
while image.wait_for(R.Common.ButtonCompletion, timeout=5):
|
||||
device.click()
|
||||
sleep(5)
|
||||
|
||||
@action
|
||||
def assign_mini_live():
|
||||
"""
|
||||
分配 MiniLive
|
||||
|
||||
前置条件:分配工作页面 \n
|
||||
结束状态:工作开始动画
|
||||
"""
|
||||
# [kotonebot/tasks/assignment.py]
|
||||
device.click(image.expect_wait(R.Daily.IconAssignMiniLive, timeout=2))
|
||||
# MiniLive 页面 [screenshots/assignment/assign_mini_live.png]
|
||||
# 等待加载完成
|
||||
image.expect_wait(R.Common.ButtonSelect, timeout=5)
|
||||
results = image.find_many(R.Daily.IconAssignKouchou, threshold=0.8)
|
||||
results.sort(key=lambda r: tuple(r.position))
|
||||
results.pop(0) # 第一个是说明文字里的图标
|
||||
# 选择第一个好调
|
||||
target = results.pop()
|
||||
device.click(target)
|
||||
# 点击选择
|
||||
sleep(0.5)
|
||||
device.click(image.expect(R.Common.ButtonSelect))
|
||||
# 等待页面加载
|
||||
confirm = image.expect_wait(R.Common.ButtonConfirmNoIcon)
|
||||
# 选择时间 [screenshots/assignment/assign_mini_live2.png]
|
||||
# CONFIG: 工作时长
|
||||
if ocr.find(contains('12時間')):
|
||||
logger.info('12時間 selected.')
|
||||
device.click()
|
||||
else:
|
||||
logger.warning('12時間 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))
|
||||
|
||||
|
||||
@action
|
||||
def assign(type: Literal['mini', 'online']):
|
||||
"""
|
||||
分配工作
|
||||
|
||||
前置条件:分配工作页面 \n
|
||||
结束状态:工作开始动画
|
||||
|
||||
:param type: 工作类型。mini=ミニライブ 或 online=ライブ配信。
|
||||
"""
|
||||
# [kotonebot/tasks/assignment.py]
|
||||
if type == 'mini':
|
||||
device.click(image.expect(R.Daily.IconAssignMiniLive))
|
||||
elif type == 'online':
|
||||
device.click(image.expect(R.Daily.IconAssignOnlineLive))
|
||||
else:
|
||||
raise ValueError(f'Invalid type: {type}')
|
||||
# MiniLive/OnlineLive 页面 [screenshots/assignment/assign_mini_live.png]
|
||||
image.expect_wait(R.Common.ButtonSelect, timeout=5)
|
||||
results = image.find_many(R.Daily.IconAssignKouchou, threshold=0.8)
|
||||
results.sort(key=lambda r: tuple(r.position))
|
||||
results.pop(0) # 第一个是说明文字里的图标
|
||||
# 选择好调偶像
|
||||
for target in results:
|
||||
with cropped(device, y2=0.4):
|
||||
img1 = device.screenshot()
|
||||
target = results.pop()
|
||||
device.click(target)
|
||||
sleep(1)
|
||||
img2 = device.screenshot()
|
||||
if image.raw().similar(img1, img2):
|
||||
logger.info(f'Idol #{target} already assigned. Trying next.')
|
||||
continue
|
||||
# 点击选择
|
||||
sleep(0.5)
|
||||
device.click(image.expect(R.Common.ButtonSelect))
|
||||
# 等待页面加载
|
||||
confirm = image.expect_wait(R.Common.ButtonConfirmNoIcon)
|
||||
# 选择时间 [screenshots/assignment/assign_mini_live2.png]
|
||||
# CONFIG: 工作时长
|
||||
if ocr.find(contains('12時間')):
|
||||
logger.info('12時間 selected.')
|
||||
device.click()
|
||||
else:
|
||||
logger.warning('12時間 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))
|
||||
|
||||
|
||||
@task('工作')
|
||||
def assignment():
|
||||
if not at_home():
|
||||
goto_home()
|
||||
# 由于“完了”标签会有高光特效,所以要多试几次
|
||||
if image.wait_for(R.Daily.TextAssignmentCompleted, timeout=6, interval=0):
|
||||
logger.info('Assignment completed. Acquiring...')
|
||||
device.click()
|
||||
# 加载页面等待
|
||||
sleep(4)
|
||||
acquire_assignment()
|
||||
logger.info('Assignment acquired.')
|
||||
# 领取完后会自动进入分配页面
|
||||
image.expect_wait(R.Daily.IconAssignMiniLive, timeout=7)
|
||||
assign('mini')
|
||||
image.expect_wait(R.Daily.IconAssignOnlineLive, timeout=7)
|
||||
assign('online')
|
||||
else:
|
||||
logger.info('Assignment not completed yet. Skipped.')
|
||||
|
||||
if __name__ == '__main__':
|
||||
from kotonebot.backend.context import init_context
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO, format='[%(asctime)s] [%(levelname)s] [%(name)s] [%(funcName)s] [%(lineno)d] %(message)s')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
init_context()
|
||||
# assignment()
|
||||
# acquire_assignment()
|
||||
# logger.info('Assignment acquired.')
|
||||
# # 领取完后会自动进入分配页面
|
||||
# image.expect_wait(R.Daily.IconAssignMiniLive, timeout=7)
|
||||
# assign_mini_live()
|
||||
assign('online')
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
opencv-python==4.10.0.84
|
||||
rapidocr_onnxruntime==1.4.3
|
||||
av==14.0.1
|
||||
scikit-image==0.25.0
|
||||
thefuzz==0.22.1
|
||||
# Adb 控制
|
||||
adbutils==2.8.0
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 450 B |
Loading…
Reference in New Issue