feat(task): 工作奖励收取与分配

This commit is contained in:
XcantloadX 2025-01-11 16:28:27 +08:00
parent b92c0f0cc3
commit 1148f6a013
5 changed files with 171 additions and 9 deletions

2
.gitignore vendored
View File

@ -2,6 +2,8 @@
tests/output_images
tests/output_images/*
R.py
kotonebot-ui/node_modules
kotonebot-ui/.vite
##########################
# Byte-compiled / optimized / DLL files

View File

@ -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

View File

@ -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')

View File

@ -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