feat(task): 培育中增加对“活動支給”的处理
This commit is contained in:
parent
f0a3dadd71
commit
c75bb49e4e
|
@ -1,65 +0,0 @@
|
|||
import dearpygui.dearpygui as dpg
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
|
||||
dpg.create_context()
|
||||
dpg.create_viewport(title='Custom Title', width=600, height=800)
|
||||
dpg.setup_dearpygui()
|
||||
|
||||
vid = cv.VideoCapture(0)
|
||||
ret, frame = vid.read()
|
||||
|
||||
# image size or you can get this from image shape
|
||||
frame_width = vid.get(cv.CAP_PROP_FRAME_WIDTH)
|
||||
frame_height = vid.get(cv.CAP_PROP_FRAME_HEIGHT)
|
||||
video_fps = vid.get(cv.CAP_PROP_FPS)
|
||||
print(frame_width)
|
||||
print(frame_height)
|
||||
print(video_fps)
|
||||
|
||||
print("Frame Array:")
|
||||
print("Array is of type: ", type(frame))
|
||||
print("No. of dimensions: ", frame.ndim)
|
||||
print("Shape of array: ", frame.shape)
|
||||
print("Size of array: ", frame.size)
|
||||
print("Array stores elements of type: ", frame.dtype)
|
||||
data = np.flip(frame, 2) # because the camera data comes in as BGR and we need RGB
|
||||
data = data.ravel() # flatten camera data to a 1 d stricture
|
||||
data = np.asarray(data, dtype=np.float32) # change data type to 32bit floats
|
||||
texture_data = np.true_divide(data, 255.0) # normalize image data to prepare for GPU
|
||||
|
||||
print("texture_data Array:")
|
||||
print("Array is of type: ", type(texture_data))
|
||||
print("No. of dimensions: ", texture_data.ndim)
|
||||
print("Shape of array: ", texture_data.shape)
|
||||
print("Size of array: ", texture_data.size)
|
||||
print("Array stores elements of type: ", texture_data.dtype)
|
||||
|
||||
with dpg.texture_registry(show=True):
|
||||
dpg.add_raw_texture(frame.shape[1], frame.shape[0], texture_data, tag="texture_tag", format=dpg.mvFormat_Float_rgb)
|
||||
|
||||
with dpg.window(label="Example Window"):
|
||||
dpg.add_text("Hello, world")
|
||||
dpg.add_image("texture_tag")
|
||||
|
||||
dpg.show_metrics()
|
||||
dpg.show_viewport()
|
||||
while dpg.is_dearpygui_running():
|
||||
|
||||
# updating the texture in a while loop the frame rate will be limited to the camera frame rate.
|
||||
# commenting out the "ret, frame = vid.read()" line will show the full speed that operations and updating a texture can run at
|
||||
|
||||
ret, frame = vid.read()
|
||||
data = np.flip(frame, 2)
|
||||
data = data.ravel()
|
||||
data = np.asarray(data, dtype=np.float32)
|
||||
texture_data = np.true_divide(data, 255.0)
|
||||
dpg.set_value("texture_tag", texture_data)
|
||||
|
||||
# to compare to the base example in the open cv tutorials uncomment below
|
||||
#cv.imshow('frame', frame)
|
||||
dpg.render_dearpygui_frame()
|
||||
|
||||
vid.release()
|
||||
#cv.destroyAllWindows() # when using upen cv window "imshow" call this also
|
||||
dpg.destroy_context()
|
|
@ -1,15 +1,4 @@
|
|||
from kotonebot.client.protocol import DeviceABC
|
||||
from .client.protocol import DeviceABC
|
||||
from .backend.context import ContextOcr, ContextImage, ContextDebug, device, ocr, image, debug
|
||||
from .backend.util import Rect, fuzz, regex, contains, grayscale
|
||||
|
||||
# device: DeviceProtocol
|
||||
# ocr: ContextOcr
|
||||
# image: ContextImage
|
||||
# debug: ContextDebug
|
||||
|
||||
# def __getattr__(name: str):
|
||||
# try:
|
||||
# return getattr(_c, name)
|
||||
# except AttributeError:
|
||||
# return globals()[name]
|
||||
from .backend.util import Rect, fuzz, regex, contains, grayscaled, grayscale_cached
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class ContextOcr:
|
|||
def raw(self, lang: OcrLanguage = 'jp') -> Ocr:
|
||||
"""
|
||||
返回 `kotonebot.backend.ocr` 中的 Ocr 对象。\n
|
||||
Ocr 对象与此对象的区别是,此对象会自动截图,而 Ocr 对象需要手动传入图像参数。
|
||||
Ocr 对象与此对象(ContextOcr)的区别是,此对象会自动截图,而 Ocr 对象需要手动传入图像参数。
|
||||
"""
|
||||
match lang:
|
||||
case 'jp':
|
||||
|
@ -201,7 +201,7 @@ class ContextImage:
|
|||
time.sleep(0.1)
|
||||
|
||||
|
||||
def expect(self, template: str, mask: str | None = None, threshold: float = 0.9) -> TemplateMatchResult:
|
||||
def expect(self, template: str | MatLike, mask: str | None = None, threshold: float = 0.9) -> TemplateMatchResult:
|
||||
"""
|
||||
寻找指定图像。
|
||||
|
||||
|
|
|
@ -76,12 +76,12 @@ def cropper_x(x1: float, x2: float) -> Callable[[MatLike], MatLike]:
|
|||
return lambda img: crop_x(img, x1, x2)
|
||||
|
||||
|
||||
def grayscale(img: MatLike | str) -> MatLike:
|
||||
def grayscaled(img: MatLike | str) -> MatLike:
|
||||
if isinstance(img, str):
|
||||
img = cv2.imread(img)
|
||||
return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
@lru_cache
|
||||
def grayscale_cached(img: MatLike | str) -> MatLike:
|
||||
return grayscale(img)
|
||||
return grayscaled(img)
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class AdbDevice(DeviceABC):
|
|||
|
||||
def __click_last(self) -> None:
|
||||
if self.last_find is None:
|
||||
raise ValueError("No last find result")
|
||||
raise ValueError("No last find result. Make sure you are not calling the 'raw' functions.")
|
||||
self.click(self.last_find)
|
||||
|
||||
def __click_rect(self, rect: Rect) -> None:
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
from typing import Literal
|
||||
from logging import getLogger
|
||||
from time import sleep
|
||||
|
||||
from kotonebot import (
|
||||
ocr,
|
||||
device,
|
||||
contains,
|
||||
image,
|
||||
debug,
|
||||
regex,
|
||||
grayscaled,
|
||||
grayscale_cached
|
||||
)
|
||||
from .. import R
|
||||
from .pdorinku import acquire_pdorinku
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
def acquire_skill_card():
|
||||
"""获取技能卡(スキルカード)"""
|
||||
# TODO: 识别卡片内容,而不是固定选卡
|
||||
# TODO: 不硬编码坐标
|
||||
CARD_POSITIONS = [
|
||||
(157, 820, 128, 128),
|
||||
(296, 820, 128, 128),
|
||||
(435, 820, 128, 128),
|
||||
]
|
||||
logger.info("Click first skill card")
|
||||
device.click(CARD_POSITIONS[0])
|
||||
sleep(0.5)
|
||||
# 确定
|
||||
logger.info("Click 受け取る")
|
||||
device.click(ocr.expect(contains("受け取る")).rect)
|
||||
# 跳过动画
|
||||
device.click(image.expect_wait_any([
|
||||
R.InPurodyuusu.PSkillCardIconBlue,
|
||||
R.InPurodyuusu.PSkillCardIconColorful
|
||||
]))
|
||||
|
||||
AcquisitionType = Literal[
|
||||
"PDrinkAcquire", # P饮料被动领取
|
||||
"PDrinkSelect", # P饮料主动领取
|
||||
"PDrinkMax", # P饮料到达上限
|
||||
"PSkillCardAcquire", # 技能卡领取
|
||||
"PSkillCardSelect", # 技能卡选择
|
||||
"PItem", # P物品
|
||||
"Clear", # 目标达成
|
||||
]
|
||||
def acquisitions() -> AcquisitionType | None:
|
||||
"""处理行动开始前和结束后可能需要处理的事件,直到到行动页面为止"""
|
||||
img = device.screenshot_raw()
|
||||
gray_img = grayscaled(img)
|
||||
logger.info("Acquisition stuffs...")
|
||||
|
||||
# P饮料被动领取
|
||||
logger.info("Check PDrink acquisition...")
|
||||
if image.raw().find(img, R.InPurodyuusu.PDrinkIcon):
|
||||
logger.info("Click to finish animation")
|
||||
device.click_center()
|
||||
sleep(1)
|
||||
return "PDrinkAcquire"
|
||||
# P饮料主动领取
|
||||
# if ocr.raw().find(img, contains("受け取るPドリンクを選れでください")):
|
||||
if image.raw().find(img, R.InPurodyuusu.TextPleaseSelectPDrink):
|
||||
logger.info("PDrink acquisition")
|
||||
# 不领取
|
||||
# device.click(ocr.expect(contains("受け取らない")))
|
||||
# sleep(0.5)
|
||||
# device.click(image.expect(R.InPurodyuusu.ButtonNotAcquire))
|
||||
# sleep(0.5)
|
||||
# device.click(image.expect(R.InPurodyuusu.ButtonConfirm))
|
||||
acquire_pdorinku(index=0)
|
||||
return "PDrinkSelect"
|
||||
# P饮料到达上限
|
||||
if image.raw().find(img, R.InPurodyuusu.TextPDrinkMax):
|
||||
device.click(image.expect(R.InPurodyuusu.ButtonLeave))
|
||||
sleep(0.7)
|
||||
# 可能需要点击确认
|
||||
device.click(image.expect(R.InPurodyuusu.ButtonConfirm, threshold=0.8))
|
||||
return "PDrinkMax"
|
||||
# 技能卡被动领取(支援卡效果)
|
||||
logger.info("Check skill card acquisition...")
|
||||
if image.raw().find_any(img, [
|
||||
R.InPurodyuusu.PSkillCardIconBlue,
|
||||
R.InPurodyuusu.PSkillCardIconColorful
|
||||
]):
|
||||
logger.info("Acquire skill card")
|
||||
device.click_center()
|
||||
return "PSkillCardAcquire"
|
||||
# 技能卡选择
|
||||
if ocr.raw().find(img, contains("受け取るスキルカードを選んでください")):
|
||||
logger.info("Acquire skill card")
|
||||
acquire_skill_card()
|
||||
sleep(5)
|
||||
return "PSkillCardSelect"
|
||||
# 奖励箱技能卡
|
||||
if res := image.raw().find(gray_img, grayscaled(R.InPurodyuusu.LootBoxSkillCard)):
|
||||
logger.info("Acquire skill card from loot box")
|
||||
device.click(res.rect)
|
||||
# 下面就是普通的技能卡选择
|
||||
return acquisitions()
|
||||
# 目标达成
|
||||
if image.raw().find(gray_img, grayscale_cached(R.InPurodyuusu.IconClearBlue)):
|
||||
logger.debug("達成: clicked")
|
||||
device.click_center()
|
||||
sleep(5)
|
||||
# TODO: 可能不存在 達成 NEXT
|
||||
logger.debug("達成 NEXT: clicked")
|
||||
device.click_center()
|
||||
return "Clear"
|
||||
# P物品
|
||||
if image.raw().find(img, R.InPurodyuusu.PItemIconColorful):
|
||||
logger.info("Click to finish PItem acquisition")
|
||||
device.click_center()
|
||||
sleep(1)
|
||||
return "PItem"
|
||||
# 支援卡
|
||||
# logger.info("Check support card acquisition...")
|
||||
# 记忆
|
||||
# 未跳过剧情
|
||||
return None
|
||||
|
||||
if __name__ == '__main__':
|
||||
from logging import getLogger
|
||||
import logging
|
||||
from kotonebot.backend.context import init_context
|
||||
logging.basicConfig(level=logging.INFO, format='[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s')
|
||||
getLogger('kotonebot').setLevel(logging.DEBUG)
|
||||
getLogger(__name__).setLevel(logging.DEBUG)
|
||||
init_context()
|
||||
acquisitions()
|
|
@ -1,20 +1,19 @@
|
|||
import random
|
||||
import re
|
||||
import time
|
||||
from typing import Literal
|
||||
from typing_extensions import deprecated
|
||||
import numpy as np
|
||||
import cv2
|
||||
import unicodedata
|
||||
import logging
|
||||
from time import sleep
|
||||
|
||||
from kotonebot import ocr, device, fuzz, contains, image, debug, regex
|
||||
from kotonebot import ocr, device, contains, image, debug, regex
|
||||
from kotonebot.backend.context import init_context
|
||||
from kotonebot.backend.util import crop_y, cropper_y, grayscale, grayscale_cached
|
||||
from kotonebot.backend.util import crop_y, cropper_y
|
||||
from kotonebot.tasks import R
|
||||
from kotonebot.tasks.actions import loading
|
||||
from kotonebot.tasks.actions.pdorinku import acquire_pdorinku
|
||||
from .non_lesson_actions import enter_allowance, study_available, enter_study, allowance_available
|
||||
from .common import acquisitions, AcquisitionType, acquire_skill_card
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -299,26 +298,7 @@ def remaing_turns_and_points():
|
|||
turns_ocr = ocr.ocr(turns_img)
|
||||
logger.debug("turns_ocr: %s", turns_ocr)
|
||||
|
||||
def acquire_skill_card():
|
||||
"""获取技能卡(スキルカード)"""
|
||||
# TODO: 识别卡片内容,而不是固定选卡
|
||||
# TODO: 不硬编码坐标
|
||||
CARD_POSITIONS = [
|
||||
(157, 820, 128, 128),
|
||||
(296, 820, 128, 128),
|
||||
(435, 820, 128, 128),
|
||||
]
|
||||
logger.info("Click first skill card")
|
||||
device.click(CARD_POSITIONS[0])
|
||||
sleep(0.5)
|
||||
# 确定
|
||||
logger.info("Click 受け取る")
|
||||
device.click(ocr.expect(contains("受け取る")).rect)
|
||||
# 跳过动画
|
||||
device.click(image.expect_wait_any([
|
||||
R.InPurodyuusu.PSkillCardIconBlue,
|
||||
R.InPurodyuusu.PSkillCardIconColorful
|
||||
]))
|
||||
|
||||
|
||||
def rest():
|
||||
"""执行休息"""
|
||||
|
@ -328,83 +308,7 @@ def rest():
|
|||
# 确定
|
||||
device.click(image.expect_wait(R.InPurodyuusu.RestConfirmBtn))
|
||||
|
||||
AcquisitionType = Literal[
|
||||
"PDrinkAcquire", # P饮料被动领取
|
||||
"PDrinkSelect", # P饮料主动领取
|
||||
"PDrinkMax", # P饮料到达上限
|
||||
"PSkillCardAcquire", # 技能卡被动领取
|
||||
"PSkillCardSelect", # 技能卡主动领取
|
||||
"PItem", # P物品
|
||||
"Clear", # 目标达成
|
||||
]
|
||||
def acquisitions() -> AcquisitionType | None:
|
||||
"""处理行动开始前和结束后可能需要处理的事件,直到到行动页面为止"""
|
||||
img = device.screenshot_raw()
|
||||
gray_img = grayscale(img)
|
||||
logger.info("Acquisition stuffs...")
|
||||
|
||||
# P饮料被动领取
|
||||
logger.info("Check PDrink acquisition...")
|
||||
if image.raw().find(img, R.InPurodyuusu.PDrinkIcon):
|
||||
logger.info("Click to finish animation")
|
||||
device.click_center()
|
||||
sleep(1)
|
||||
return "PDrinkAcquire"
|
||||
# P饮料主动领取
|
||||
# if ocr.raw().find(img, contains("受け取るPドリンクを選れでください")):
|
||||
if image.raw().find(img, R.InPurodyuusu.TextPleaseSelectPDrink):
|
||||
logger.info("PDrink acquisition")
|
||||
# 不领取
|
||||
# device.click(ocr.expect(contains("受け取らない")))
|
||||
# sleep(0.5)
|
||||
# device.click(image.expect(R.InPurodyuusu.ButtonNotAcquire))
|
||||
# sleep(0.5)
|
||||
# device.click(image.expect(R.InPurodyuusu.ButtonConfirm))
|
||||
acquire_pdorinku(index=0)
|
||||
return "PDrinkSelect"
|
||||
# P饮料到达上限
|
||||
if image.raw().find(img, R.InPurodyuusu.TextPDrinkMax):
|
||||
device.click(image.expect(R.InPurodyuusu.ButtonLeave))
|
||||
sleep(0.7)
|
||||
# 可能需要点击确认
|
||||
device.click(image.expect(R.InPurodyuusu.ButtonConfirm, threshold=0.8))
|
||||
return "PDrinkMax"
|
||||
# 技能卡被动领取
|
||||
logger.info("Check skill card acquisition...")
|
||||
if image.raw().find_any(img, [
|
||||
R.InPurodyuusu.PSkillCardIconBlue,
|
||||
R.InPurodyuusu.PSkillCardIconColorful
|
||||
]):
|
||||
logger.info("Acquire skill card")
|
||||
device.click_center()
|
||||
return "PSkillCardAcquire"
|
||||
# 技能卡主动领取
|
||||
if ocr.raw().find(img, contains("受け取るスキルカードを選んでください")):
|
||||
logger.info("Acquire skill card")
|
||||
acquire_skill_card()
|
||||
sleep(5)
|
||||
return "PSkillCardSelect"
|
||||
|
||||
# 目标达成
|
||||
if image.raw().find(gray_img, grayscale_cached(R.InPurodyuusu.IconClearBlue)):
|
||||
logger.debug("達成: clicked")
|
||||
device.click_center()
|
||||
sleep(5)
|
||||
# TODO: 可能不存在 達成 NEXT
|
||||
logger.debug("達成 NEXT: clicked")
|
||||
device.click_center()
|
||||
return "Clear"
|
||||
# P物品
|
||||
if image.raw().find(img, R.InPurodyuusu.PItemIconColorful):
|
||||
logger.info("Click to finish PItem acquisition")
|
||||
device.click_center()
|
||||
sleep(1)
|
||||
return "PItem"
|
||||
# 支援卡
|
||||
# logger.info("Check support card acquisition...")
|
||||
# 记忆
|
||||
# 未跳过剧情
|
||||
return None
|
||||
|
||||
def until_action_scene():
|
||||
"""等待进入行动场景"""
|
||||
|
@ -663,7 +567,7 @@ def hajime_regular(week: int = -1, start_from: int = 1):
|
|||
if not enter_recommended_action():
|
||||
rest()
|
||||
|
||||
def week_common():
|
||||
def week_lesson():
|
||||
until_action_scene()
|
||||
executed_action = enter_recommended_action()
|
||||
logger.info("Executed recommended action: %s", executed_action)
|
||||
|
@ -677,8 +581,16 @@ def hajime_regular(week: int = -1, start_from: int = 1):
|
|||
rest()
|
||||
until_action_scene()
|
||||
|
||||
def week_non_lesson():
|
||||
"""非练习周。可能可用行动包括:おでかけ、相談、活動支給、授業"""
|
||||
until_action_scene()
|
||||
if allowance_available():
|
||||
enter_allowance()
|
||||
# elif study_available():
|
||||
# enter_study()
|
||||
until_action_scene()
|
||||
|
||||
def week_final():
|
||||
def week_final_lesson():
|
||||
if enter_recommended_action(final_week=True) != 'lesson':
|
||||
raise ValueError("Failed to enter recommended action on final week.")
|
||||
sleep(5)
|
||||
|
@ -709,19 +621,19 @@ def hajime_regular(week: int = -1, start_from: int = 1):
|
|||
produce_end()
|
||||
|
||||
weeks = [
|
||||
week_common, # 1
|
||||
week_common, # 2
|
||||
week_common, # 3
|
||||
week_common, # 4
|
||||
week_final, # 5
|
||||
week_mid_exam, # 6
|
||||
week_common, # 7
|
||||
week_common, # 8
|
||||
week_common, # 9
|
||||
week_common, # 10
|
||||
week_common, # 11
|
||||
week_final, # 12
|
||||
week_final_exam, # 13
|
||||
week_lesson, # 1: Vo.レッスン、Da.レッスン、Vi.レッスン
|
||||
week_lesson, # 2: 授業
|
||||
week_lesson, # 3: Vo.レッスン、Da.レッスン、Vi.レッスン、授業
|
||||
week_non_lesson, # 4: おでかけ、相談、活動支給
|
||||
week_final_lesson, # 5: 追い込みレッスン
|
||||
week_mid_exam, # 6: 中間試験
|
||||
week_non_lesson, # 7: おでかけ、活動支給
|
||||
week_non_lesson, # 8: 授業、活動支給
|
||||
week_lesson, # 9: Vo.レッスン、Da.レッスン、Vi.レッスン
|
||||
week_lesson, # 10: Vo.レッスン、Da.レッスン、Vi.レッスン、授業
|
||||
week_non_lesson, # 11: おでかけ、相談、活動支給
|
||||
week_final_lesson, # 12: 追い込みレッスン
|
||||
week_final_exam, # 13: 最終試験
|
||||
]
|
||||
if week != -1:
|
||||
logger.info("Week %d started.", week)
|
||||
|
@ -751,13 +663,13 @@ if __name__ == '__main__':
|
|||
getLogger(__name__).setLevel(logging.DEBUG)
|
||||
init_context()
|
||||
|
||||
while not image.wait_for_any([
|
||||
R.InPurodyuusu.TextPDiary, # 普通周
|
||||
R.InPurodyuusu.ButtonFinalPracticeDance # 离考试剩余一周
|
||||
], timeout=2):
|
||||
logger.info("Action scene not detected. Retry...")
|
||||
acquisitions()
|
||||
sleep(3)
|
||||
# while not image.wait_for_any([
|
||||
# R.InPurodyuusu.TextPDiary, # 普通周
|
||||
# R.InPurodyuusu.ButtonFinalPracticeDance # 离考试剩余一周
|
||||
# ], timeout=2):
|
||||
# logger.info("Action scene not detected. Retry...")
|
||||
# acquisitions()
|
||||
# sleep(3)
|
||||
|
||||
# image.wait_for_any([
|
||||
# R.InPurodyuusu.TextPDiary, # 普通周
|
||||
|
@ -775,7 +687,7 @@ if __name__ == '__main__':
|
|||
# acquisitions()
|
||||
# acquire_pdorinku(0)
|
||||
# image.wait_for(R.InPurodyuusu.InPractice.PDorinkuIcon)
|
||||
# hajime_regular(start_from=1)
|
||||
hajime_regular(start_from=9)
|
||||
# until_practice_scene()
|
||||
# device.click(image.expect_wait_any([
|
||||
# R.InPurodyuusu.PSkillCardIconBlue,
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
"""
|
||||
此文件包含非练习周的行动。
|
||||
|
||||
具体包括:おでかけ、相談、活動支給、授業
|
||||
"""
|
||||
from time import sleep
|
||||
from logging import getLogger
|
||||
|
||||
from kotonebot import device, image, ocr, debug
|
||||
from kotonebot.tasks import R
|
||||
from .common import acquisitions, AcquisitionType
|
||||
|
||||
logger = getLogger(__name__)
|
||||
|
||||
def allowance_available():
|
||||
"""
|
||||
判断是否可以执行活動支給。
|
||||
"""
|
||||
return image.expect(R.InPurodyuusu.ButtonTextAllowance) is not None
|
||||
|
||||
def study_available():
|
||||
"""
|
||||
判断是否可以执行授業。
|
||||
"""
|
||||
return image.expect(R.InPurodyuusu.ButtonTextStudy) is not None
|
||||
|
||||
def enter_study():
|
||||
"""
|
||||
执行授業。
|
||||
"""
|
||||
raise NotImplementedError("授業功能未实现")
|
||||
|
||||
def enter_allowance():
|
||||
"""
|
||||
执行活動支給。
|
||||
|
||||
前置条件:位于行动页面,且所有行动按钮清晰可见 \n
|
||||
结束状态:无
|
||||
"""
|
||||
logger.info("Executing 活動支給.")
|
||||
# 点击活動支給 [screenshots\allowance\step_1.png]
|
||||
logger.info("Double clicking on 活動支給.")
|
||||
device.double_click(image.expect(R.InPurodyuusu.ButtonTextAllowance), interval=1)
|
||||
# 等待进入页面
|
||||
sleep(3)
|
||||
# 第一个箱子 [screenshots\allowance\step_2.png]
|
||||
logger.info("Clicking on the first lootbox.")
|
||||
device.click(image.expect_wait_any([
|
||||
R.InPurodyuusu.LootboxSliverLock
|
||||
]))
|
||||
while acquisitions() is None:
|
||||
logger.info("Waiting for acquisitions finished.")
|
||||
sleep(2)
|
||||
# 第二个箱子
|
||||
logger.info("Clicking on the second lootbox.")
|
||||
device.click(image.expect_wait_any([
|
||||
R.InPurodyuusu.LootboxSliverLock
|
||||
]))
|
||||
while acquisitions() is None:
|
||||
logger.info("Waiting for acquisitions finished.")
|
||||
sleep(2)
|
||||
logger.info("活動支給 completed.")
|
||||
# 可能会出现的新动画
|
||||
# 技能卡:[screenshots\allowance\step_4.png]
|
||||
|
||||
|
||||
def study():
|
||||
"""授業"""
|
||||
pass
|
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 947 KiB |
Binary file not shown.
After Width: | Height: | Size: 906 KiB |
Binary file not shown.
After Width: | Height: | Size: 775 KiB |
|
@ -14,7 +14,7 @@ class {{ class_name }}:
|
|||
"""
|
||||
路径:{{ attr.rel_path }}<br>
|
||||
模块:`{{ attr.class_path|join('.') }}.{{ attr.name }}`<br>
|
||||
<img src="vscode-file://vscode-app/{{ attr.abspath }}" style="max-width: 200px;">
|
||||
<img src="vscode-file://vscode-app/{{ attr.abspath }}" style="max-width: 70%; max-height: 200px;">
|
||||
"""
|
||||
{%- elif attr.type == 'next_class' -%}
|
||||
{{ attr.name }} = {{ attr.value }}
|
||||
|
|
Loading…
Reference in New Issue