From 1c2db1ec26b3a7b2c8ffda2da777c37413625a09 Mon Sep 17 00:00:00 2001 From: LmeSzinc Date: Tue, 5 May 2020 17:27:19 +0800 Subject: [PATCH] =?UTF-8?q?Add:=20=E5=A2=9E=E5=8A=A0=E6=88=98=E6=9C=AF?= =?UTF-8?q?=E5=AD=A6=E9=99=A2=E6=94=B6=E8=8E=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复委托收获时可能卡住的问题 --- assets/reward/TACTICAL_CLASS_START.png | Bin 0 -> 12787 bytes assets/ui/REWARD_GOTO_TACTICAL.png | Bin 0 -> 8566 bytes assets/ui/TACTICAL_CHECK.png | Bin 0 -> 9452 bytes config/template.ini | 6 + module/base/timer.py | 31 +++- module/config/argparser.py | 8 + module/config/config.py | 24 ++- module/config/dictionary.py | 10 +- module/reward/assets.py | 1 + module/reward/commission.py | 3 +- module/reward/reward.py | 25 +-- module/reward/tactical_class.py | 247 +++++++++++++++++++++++++ module/ui/assets.py | 2 + module/ui/page.py | 7 + 14 files changed, 340 insertions(+), 24 deletions(-) create mode 100644 assets/reward/TACTICAL_CLASS_START.png create mode 100644 assets/ui/REWARD_GOTO_TACTICAL.png create mode 100644 assets/ui/TACTICAL_CHECK.png create mode 100644 module/reward/tactical_class.py diff --git a/assets/reward/TACTICAL_CLASS_START.png b/assets/reward/TACTICAL_CLASS_START.png new file mode 100644 index 0000000000000000000000000000000000000000..0f1a0ff6f0f36cf9b1004e437866ab60aeb44c07 GIT binary patch literal 12787 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 literal 0 HcmV?d00001 diff --git a/assets/ui/REWARD_GOTO_TACTICAL.png b/assets/ui/REWARD_GOTO_TACTICAL.png new file mode 100644 index 0000000000000000000000000000000000000000..e3297a994eef7de6d6146a86f94b9ee2a3d32230 GIT binary patch literal 8566 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 literal 0 HcmV?d00001 diff --git a/assets/ui/TACTICAL_CHECK.png b/assets/ui/TACTICAL_CHECK.png new file mode 100644 index 0000000000000000000000000000000000000000..53d3e2663ecb941555be35c8d0cebf30fce72c0d GIT binary patch literal 9452 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 end: + start = start - timedelta(days=1) + return start, end + + +def time_range_active(time_range): + """ + Args: + time_range(tuple(datetime.datetime)): (time start, time end). + + Returns: + bool: + """ + return time_range[0] < datetime.now() < time_range[1] + + class Timer: def __init__(self, limit, count=0): """ @@ -43,8 +68,8 @@ class Timer: if self.appear(MAIN_CHECK): if confirm_timer.reached(): pass - else: - confirm_timer.reset() + else: + confirm_timer.reset() """ self.limit = limit self.count = count diff --git a/module/config/argparser.py b/module/config/argparser.py index aa5e9cd58..c747b38b8 100644 --- a/module/config/argparser.py +++ b/module/config/argparser.py @@ -250,6 +250,14 @@ def main(ini_name=''): priority4.add_argument('--钻石类紧急委托', default=default('--钻石类紧急委托'), help='BIW要员护卫, NYB巡视护卫') priority4.add_argument('--观舰类紧急委托', default=default('--观舰类紧急委托'), help='小型观舰仪式, 同盟观舰仪式') + reward_tactical = reward_parser.add_argument_group('战术学院', '只支持续技能书, 不支持学新技能') + reward_tactical.add_argument('--启用战术学院收获', default=default('--启用战术学院收获'), choices=['是', '否']) + reward_tactical.add_argument('--战术学院夜间时段', default=default('--战术学院夜间时段'), help='格式 23:30-06:30') + reward_tactical.add_argument('--技能书稀有度', default=default('--技能书稀有度'), choices=['3', '2', '1'], help='最多使用T几的技能书\nT3是金书, T2是紫书, T1是蓝书') + reward_tactical.add_argument('--技能书优先使用同类型', default=default('--技能书优先使用同类型'), choices=['是', '否'], help='选是, 优先使用有150%加成的\n选否, 优先使用同稀有度的技能书') + reward_tactical.add_argument('--技能书夜间稀有度', default=default('--技能书夜间稀有度'), choices=['3', '2', '1']) + reward_tactical.add_argument('--技能书夜间优先使用同类型', default=default('--技能书夜间优先使用同类型'), choices=['是', '否']) + # ==========设备设置========== emulator_parser = subs.add_parser('设备设置') emulator = emulator_parser.add_argument_group('模拟器', '需要运行一次来保存选项, 会检查游戏是否启动') diff --git a/module/config/config.py b/module/config/config.py index b03d0de3e..66c94f7e6 100644 --- a/module/config/config.py +++ b/module/config/config.py @@ -2,13 +2,12 @@ import codecs import configparser import copy import os -from datetime import datetime import cv2 import numpy as np from PIL import Image -from module.base.timer import future_time +from module.base.timer import * from module.config.dictionary import * from module.logger import logger @@ -282,6 +281,8 @@ class AzurLaneConfig: ENABLE_COIN_REWARD = True ENABLE_MISSION_REWARD = True ENABLE_COMMISSION_REWARD = True + ENABLE_TACTICAL_REWARD = True + COMMISSION_PRIORITY = { 'major_comm': 0, 'daily_comm': 100, @@ -304,6 +305,12 @@ class AzurLaneConfig: } COMMISSION_TIME_LIMIT = 0 + TACTICAL_BOOK_TIER = 2 + TACTICAL_EXP_FIRST = True + TACTICAL_BOOK_TIER_NIGHT = 3 + TACTICAL_EXP_FIRST_NIGHT = False + TACTICAL_NIGHT_RANGE = future_time_range('23:30-06:30') # (Night start, night end), datetime.datetime instance. + """ C_7_2_mystery_farming """ @@ -425,11 +432,16 @@ class AzurLaneConfig: # Reward option = config['Reward'] self.REWARD_INTERVAL = int(option['reward_interval']) - for attr in ['enable_reward', 'enable_oil_reward', 'enable_coin_reward', 'enable_mission_reward', 'enable_commission_reward']: + for attr in ['enable_reward', 'enable_oil_reward', 'enable_coin_reward', 'enable_mission_reward', 'enable_commission_reward', 'enable_tactical_reward']: self.__setattr__(attr.upper(), to_bool(option[attr])) self.COMMISSION_TIME_LIMIT = future_time(option['commission_time_limit']) for attr in self.COMMISSION_PRIORITY.keys(): self.COMMISSION_PRIORITY[attr] = int(option[attr]) + self.TACTICAL_NIGHT_RANGE = future_time_range(option['tactical_night_range']) + self.TACTICAL_BOOK_TIER = int(option['tactical_book_tier']) + self.TACTICAL_EXP_FIRST = to_bool(option['tactical_exp_first']) + self.TACTICAL_BOOK_TIER_NIGHT = int(option['tactical_book_tier_night']) + self.TACTICAL_EXP_FIRST_NIGHT = to_bool(option['tactical_exp_first_night']) option = config['Main'] self.CAMPAIGN_NAME = option['main_stage'] @@ -443,12 +455,12 @@ class AzurLaneConfig: for n in [1, 2, 4, 5]: self.DAILY_CHOOSE[n] = dic_daily[option[f'daily_mission_{n}']] self.FLEET_DAILY = int(option['daily_fleet']) - self.FLEET_DAILY_EQUIPMENT = equip(option['daily_equipment']) + self.FLEET_DAILY_EQUIPMENT = to_list(option['daily_equipment']) # Hard self.ENABLE_HARD_CAMPAIGN = to_bool(option['enable_hard_campaign']) self.HARD_CAMPAIGN = option['hard_campaign'] self.FLEET_HARD = int(option['hard_fleet']) - self.FLEET_HARD_EQUIPMENT = equip(option['hard_equipment']) + self.FLEET_HARD_EQUIPMENT = to_list(option['hard_equipment']) # Exercise self.ENABLE_EXERCISE = to_bool(option['enable_exercise']) self.EXERCISE_CHOOSE_MODE = option['exercise_choose_mode'] @@ -456,7 +468,7 @@ class AzurLaneConfig: self.OPPONENT_CHALLENGE_TRIAL = int(option['exercise_try']) self.LOW_HP_THRESHOLD = float(option['exercise_hp_threshold']) self.LOW_HP_CONFIRM_WAIT = float(option['exercise_low_hp_confirm']) - self.EXERCISE_FLEET_EQUIPMENT = equip(option['exercise_equipment']) + self.EXERCISE_FLEET_EQUIPMENT = to_list(option['exercise_equipment']) # Event option = config['Event'] diff --git a/module/config/dictionary.py b/module/config/dictionary.py index ff8f8442d..2a4e49b90 100644 --- a/module/config/dictionary.py +++ b/module/config/dictionary.py @@ -91,6 +91,7 @@ dic_chi_to_eng = { '启用物资收获': 'enable_coin_reward', '启用任务收获': 'enable_mission_reward', '启用委托收获': 'enable_commission_reward', + '启用战术学院收获': 'enable_tactical_reward', '委托时间限制': 'commission_time_limit', '委托耗时小于2h': 'duration_shorter_than_2', '委托耗时超过6h': 'duration_longer_than_6', @@ -110,6 +111,11 @@ dic_chi_to_eng = { '装备类紧急委托': 'urgent_box', '钻石类紧急委托': 'urgent_gem', '观舰类紧急委托': 'urgent_ship', + '战术学院夜间时段': 'tactical_night_range', + '技能书稀有度': 'tactical_book_tier', + '技能书优先使用同类型': 'tactical_exp_first', + '技能书夜间稀有度': 'tactical_book_tier_night', + '技能书夜间优先使用同类型': 'tactical_exp_first_night', '设备': 'serial', '包名': 'package_name', '出错时保存log和截图': 'enable_error_log_and_screenshot_save', @@ -198,10 +204,8 @@ def to_bool(string): return dic_bool.get(string, string) -def equip(string): +def to_list(string): if string.isdigit(): return None - out = [int(letter.strip()) for letter in string.split(',')] - assert len(out) == 6 return out diff --git a/module/reward/assets.py b/module/reward/assets.py index 6833544fc..ac490fc21 100644 --- a/module/reward/assets.py +++ b/module/reward/assets.py @@ -21,3 +21,4 @@ REWARD_1 = Button(area=(383, 285, 503, 297), color=(238, 168, 81), button=(383, REWARD_2 = Button(area=(383, 404, 503, 444), color=(233, 165, 67), button=(383, 404, 503, 444), file='./assets/reward/REWARD_2.png') REWARD_3 = Button(area=(383, 546, 503, 586), color=(234, 163, 69), button=(383, 546, 503, 586), file='./assets/reward/REWARD_3.png') REWARD_SAVE_CLICK = Button(area=(415, 184, 496, 214), color=(152, 150, 168), button=(415, 184, 496, 214), file='./assets/reward/REWARD_SAVE_CLICK.png') +TACTICAL_CLASS_START = Button(area=(1024, 590, 1197, 648), color=(96, 139, 194), button=(1024, 590, 1197, 648), file='./assets/reward/TACTICAL_CLASS_START.png') diff --git a/module/reward/commission.py b/module/reward/commission.py index d63fa77ba..fba635ec2 100644 --- a/module/reward/commission.py +++ b/module/reward/commission.py @@ -443,7 +443,7 @@ class RewardCommission(UI, InfoBarHandler, PopupHandler): logger.info('No commission chose') def handle_commission_start(self): - """Make sure current page is page_reward before calls. + """Remember to make sure current page is page_reward before calls. Returns: bool: If runs a commission. @@ -460,6 +460,7 @@ class RewardCommission(UI, InfoBarHandler, PopupHandler): self.commission_start() self.ui_goto(page_reward, skip_first_screenshot=True) + return True def commission_notice_show_at_campaign(self): """ diff --git a/module/reward/reward.py b/module/reward/reward.py index 818ec99e4..359336142 100644 --- a/module/reward/reward.py +++ b/module/reward/reward.py @@ -6,9 +6,10 @@ from module.logger import logger from module.reward.assets import * from module.ui.page import * from module.reward.commission import RewardCommission +from module.reward.tactical_class import RewardTacticalClass -class Reward(RewardCommission): +class Reward(RewardCommission, RewardTacticalClass): def reward(self): if not self.config.ENABLE_REWARD: return False @@ -21,6 +22,7 @@ class Reward(RewardCommission): self._reward_receive() self.handle_info_bar() self.handle_commission_start() + self.handle_tactical_class() self.ui_click( click_button=page_reward.links[page_main], @@ -47,7 +49,7 @@ class Reward(RewardCommission): Returns: bool: If rewarded. """ - logger.hr('Oil Reward') + logger.hr('Reward receive') reward = False exit_timer = Timer(1, count=3) @@ -75,15 +77,16 @@ class Reward(RewardCommission): reward = True continue - for button in btn: - if not click_timer.reached(): - continue - if self.appear_then_click(button, interval=1): - btn.remove(button) - exit_timer.reset() - click_timer.reset() - reward = True - continue + if click_timer.reached() and ( + (self.config.ENABLE_OIL_REWARD and self.appear_then_click(OIL, interval=60)) + or (self.config.ENABLE_COIN_REWARD and self.appear_then_click(COIN, interval=60)) + or (self.config.ENABLE_COMMISSION_REWARD and self.appear_then_click(REWARD_1, interval=1)) + or (self.config.ENABLE_REWARD and self.appear_then_click(REWARD_3, interval=1)) + ): + exit_timer.reset() + click_timer.reset() + reward = True + continue if not self.appear(page_reward.check_button) or self.info_bar_count(): exit_timer.reset() diff --git a/module/reward/tactical_class.py b/module/reward/tactical_class.py new file mode 100644 index 000000000..51a63b94b --- /dev/null +++ b/module/reward/tactical_class.py @@ -0,0 +1,247 @@ +import numpy as np +from scipy import signal + +from module.base.button import Button, ButtonGrid +from module.base.timer import Timer, time_range_active +from module.base.utils import area_offset, get_color, color_similar, color_similarity_2d +from module.handler.popup import PopupHandler +from module.logger import logger +from module.reward.assets import TACTICAL_CLASS_START, REWARD_2 +from module.ui.assets import TACTICAL_CHECK +from module.ui.ui import UI, page_tactical, page_reward + +GENRE_NAME_DICT = { + 1: 'Offensive', # red + 2: 'Defensive', # blue + 3: 'Support', # yellow +} +BOOKS_GRID = ButtonGrid(origin=(239, 288), delta=(140, 120), button_shape=(98, 98), grid_shape=(6, 2)) + + +class Book: + color_genre = { + 1: (214, 69, 74), # Offensive, red + 2: (115, 178, 255), # Defensive, blue + 3: (247, 190, 99), # Support, yellow + } + color_tier = { + 1: (104, 181, 238), # T1, blue + 2: (151, 129, 203), # T2, purple + 3: (235, 208, 120), # T3, gold + } + + def __init__(self, image, button): + """ + Args: + image (PIL.Image.Image): + button (Button): + """ + image = image.crop(button.area) + self.button = button + + self.genre = 0 + color = get_color(image, (65, 35, 72, 42)) + for key, value in self.color_genre.items(): + if color_similar(color1=color, color2=value, threshold=30): + self.genre = key + + self.tier = 0 + color = get_color(image, (83, 61, 92, 70)) + for key, value in self.color_tier.items(): + if color_similar(color1=color, color2=value, threshold=30): + self.tier = key + + color = color_similarity_2d(image.crop((15, 0, 97, 13)), color=(148, 251, 99)) + self.exp = bool(np.sum(color > 221) > 50) + + self.valid = bool(self.genre and self.tier) + + def __str__(self): + # Example: Defensive_T3_Exp + text = f'{GENRE_NAME_DICT.get(self.genre, "Unknown")}_T{self.tier}' + if self.exp: + text += '_Exp' + return text + + +class BookGroup: + def __init__(self, books): + """ + Args: + books (list[Book]): + """ + self.books = books + + def __iter__(self): + return iter(self.books) + + def __len__(self): + return len(self.books) + + def __bool__(self): + return len(self.books) > 0 + + def __getitem__(self, item): + return self.books[item] + + def __str__(self): + # return str([str(grid) for grid in self]) + return '[' + ', '.join([str(grid) for grid in self]) + ']' + + def select(self, **kwargs): + """ + Args: + **kwargs: Attributes of Grid. + + Returns: + SelectedGrids: + """ + result = [] + for grid in self.books: + flag = True + for k, v in kwargs.items(): + if grid.__getattribute__(k) != v: + flag = False + if flag: + result.append(grid) + + return BookGroup(result) + + def add(self, books): + """ + Args: + books(BookGroup): + + Returns: + BookGroup: + """ + return BookGroup(self.books + books.books) + + def choose(self, tier, exp=True): + """ + Args: + tier (int): Max tier to choose. + exp (bool): True to choose books with exp bonus, False to choose other books in the same tier. + + Returns: + Book: + """ + while 1: + books = self.select(tier=tier) + tier -= 1 + books_with_exp = books.select(exp=True) + if exp and not books_with_exp: + continue + if books_with_exp: + books = books_with_exp + if books: + logger.attr('Book_choose', books[0]) + return books[0] + + # End + if tier <= 0: + break + + logger.warning('No book choose, return first book.') + return self[0] + + +class RewardTacticalClass(UI, PopupHandler): + tactical_animation_timer = Timer(2, count=3) + + def _tactical_animation_running(self): + """ + Returns: + bool: If showing skill points increasing animation. + """ + color_height = np.mean(self.device.image.crop((922, 0, 1036, 720)).convert('L'), axis=1) + parameters = {'height': 200} + peaks, _ = signal.find_peaks(color_height, **parameters) + peaks = [y for y in peaks if y > 67 + 243] + + if not len(peaks): + logger.warning('No student card found.') + for y in peaks: + student_area = (447, y - 243, 1244, y) + area = area_offset((677, 172, 761, 183), student_area[0:2]) + # Normal: 160, In skill-increasing animation: 109 + if np.mean(get_color(self.device.image, area)) < 135: + return True + + return False + + def _tactical_books_choose(self): + """ + Choose tactical book according to config. + """ + books = BookGroup([Book(self.device.image, button) for button in BOOKS_GRID.buttons()]).select(valid=True) + logger.attr('Book_count', len(books)) + for index in range(1, 4): + logger.info(f'Book_T{index}: {books.select(tier=index)}') + if not books: + logger.warning('No book found.') + + if not time_range_active(self.config.TACTICAL_NIGHT_RANGE): + tier = self.config.TACTICAL_BOOK_TIER + exp = self.config.TACTICAL_EXP_FIRST + else: + tier = self.config.TACTICAL_BOOK_TIER_NIGHT + exp = self.config.TACTICAL_EXP_FIRST_NIGHT + book = books.choose(tier=tier, exp=exp) + + self.device.click(book.button) + self.device.sleep((0.3, 0.5)) + + def _tactical_class_receive(self, skip_first_screenshot=True): + """Remember to make sure current page is page_reward before calls. + + Args: + skip_first_screenshot (bool): + + Returns: + bool: If rewarded. + """ + if not self.appear(REWARD_2): + logger.info('No tactical class reward.') + return False + + logger.hr('Tactical class receive') + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + if self.appear_then_click(REWARD_2, interval=1): + continue + if self.handle_popup_confirm(): + continue + if self.appear(TACTICAL_CLASS_START, offset=(30, 30), interval=1): + self._tactical_books_choose() + self.device.click(TACTICAL_CLASS_START) + continue + + # End + if self.appear(TACTICAL_CHECK, offset=(20, 20)): + self.ui_current = page_tactical + if not self._tactical_animation_running(): + if self.tactical_animation_timer.reached(): + logger.info('Tactical reward end.') + break + else: + self.tactical_animation_timer.reset() + + self.ui_goto(page_reward, skip_first_screenshot=True) + return True + + def handle_tactical_class(self): + """ + Returns: + bool: If rewarded. + """ + if not self.config.ENABLE_TACTICAL_REWARD: + return False + + self._tactical_class_receive() + + return True diff --git a/module/ui/assets.py b/module/ui/assets.py index 4e0509e62..d6ecc5d21 100644 --- a/module/ui/assets.py +++ b/module/ui/assets.py @@ -24,4 +24,6 @@ MISSION_CHECK = Button(area=(120, 15, 173, 40), color=(141, 156, 194), button=(1 REWARD_CHECK = Button(area=(302, 119, 371, 195), color=(146, 118, 120), button=(302, 119, 371, 195), file='./assets/ui/REWARD_CHECK.png') REWARD_GOTO_COMMISSION = Button(area=(383, 262, 503, 302), color=(91, 136, 199), button=(383, 262, 503, 302), file='./assets/ui/REWARD_GOTO_COMMISSION.png') REWARD_GOTO_MAIN = Button(area=(1037, 611, 1107, 656), color=(134, 122, 127), button=(1037, 611, 1107, 656), file='./assets/ui/REWARD_GOTO_MAIN.png') +REWARD_GOTO_TACTICAL = Button(area=(383, 404, 503, 444), color=(89, 140, 198), button=(383, 404, 503, 444), file='./assets/ui/REWARD_GOTO_TACTICAL.png') SP_CHECK = Button(area=(123, 63, 206, 109), color=(95, 110, 145), button=(123, 63, 206, 109), file='./assets/ui/SP_CHECK.png') +TACTICAL_CHECK = Button(area=(122, 14, 231, 38), color=(145, 161, 200), button=(122, 14, 231, 38), file='./assets/ui/TACTICAL_CHECK.png') diff --git a/module/ui/page.py b/module/ui/page.py index 2a9d7e990..edd7bc963 100644 --- a/module/ui/page.py +++ b/module/ui/page.py @@ -78,6 +78,13 @@ page_commission.link(button=GOTO_MAIN, destination=page_main) page_commission.link(button=BACK_ARROW, destination=page_reward) page_reward.link(button=REWARD_GOTO_COMMISSION, destination=page_commission) +# Tactical class +# Please don't goto tactical class from academy. +page_tactical = Page(TACTICAL_CHECK) +page_tactical.link(button=GOTO_MAIN, destination=page_main) +page_tactical.link(button=BACK_ARROW, destination=page_reward) +page_reward.link(button=REWARD_GOTO_TACTICAL, destination=page_tactical) + # Event list page_event_list = Page(EVENT_LIST_CHECK) page_event_list.link(button=GOTO_MAIN, destination=page_main)