Add: 增加了挂委托的功能

This commit is contained in:
LmeSzinc 2020-04-06 19:01:22 +08:00
parent 87ed9532c9
commit 7523847fac
21 changed files with 619 additions and 12 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -46,6 +46,26 @@ reward_interval = 20
enable_oil_reward = yes
enable_coin_reward = yes
enable_mission_reward = yes
enable_commission_reward = yes
commission_time_limit = 23:30
duration_shorter_than_2 = 11
duration_longer_than_6 = -11
expire_shorter_than_2 = 11
expire_longer_than_6 = -11
daily_comm = 100
major_comm = 0
extra_drill = 20
extra_part = 60
extra_cube = 80
extra_oil = 90
extra_book = 70
urgent_drill = 45
urgent_part = 95
urgent_cube = 165
urgent_book = 145
urgent_box = 195
urgent_gem = 205
urgent_ship = 155
[Emulator]
command = emulator

View File

@ -154,6 +154,36 @@ def main():
reward_mission = reward_parser.add_argument_group('任务奖励', '')
reward_mission.add_argument('--启用任务收获', default=default('--启用任务收获'), choices=['', ''])
reward_commission = reward_parser.add_argument_group('委托设置', '')
reward_commission.add_argument('--启用委托收获', default=default('--启用委托收获'), choices=['', ''])
reward_commission.add_argument('--委托时间限制', default=default('--委托时间限制'), help='忽略完成时间超过限制的委托, 格式: 23:30')
priority1 = reward_commission.add_argument_group('委托耗时优先级', '')
priority1.add_argument('--委托耗时小于2h', default=default('--委托耗时小于2h'), help='')
priority1.add_argument('--委托耗时超过6h', default=default('--委托耗时超过6h'), help='')
priority1.add_argument('--委托过期小于2h', default=default('--委托过期小于2h'), help='')
priority1.add_argument('--委托过期大于6h', default=default('--委托过期大于6h'), help='')
priority2 = reward_commission.add_argument_group('日常委托优先级', '')
priority2.add_argument('--日常委托', default=default('--日常委托'), help='日常资源开发, 高阶战术研发')
priority2.add_argument('--主要委托', default=default('--主要委托'), help='1200油/1000油委托')
priority3 = reward_commission.add_argument_group('额外委托优先级', '')
priority3.add_argument('--钻头类额外委托', default=default('--钻头类额外委托'), help='短距离航行训练, 近海防卫巡逻')
priority3.add_argument('--部件类额外委托', default=default('--部件类额外委托'), help='矿脉护卫委托, 林木护卫委托')
priority3.add_argument('--魔方类额外委托', default=default('--魔方类额外委托'), help='舰队高阶演习, 舰队护卫演习')
priority3.add_argument('--石油类额外委托', default=default('--石油类额外委托'), help='小型油田开发, 大型油田开发')
priority3.add_argument('--教材类额外委托', default=default('--教材类额外委托'), help='小型商船护卫, 大型商船护卫')
priority4 = reward_commission.add_argument_group('紧急委托优先级', '')
priority4.add_argument('--钻头类紧急委托', default=default('--钻头类紧急委托'), help='保卫运输部队, 歼灭敌精锐部队')
priority4.add_argument('--部件类紧急委托', default=default('--部件类紧急委托'), help='支援维拉维拉岛, 支援恐班纳')
priority4.add_argument('--魔方类紧急委托', default=default('--魔方类紧急委托'), help='解救商船, 敌袭')
priority4.add_argument('--教材类紧急委托', default=default('--教材类紧急委托'), help='支援土豪尔岛, 支援萌岛')
priority4.add_argument('--装备类紧急委托', default=default('--装备类紧急委托'), help='BIW装备运输, NYB装备研发')
priority4.add_argument('--钻石类紧急委托', default=default('--钻石类紧急委托'), help='BIW要员护卫, NYB巡视护卫')
priority4.add_argument('--观舰类紧急委托', default=default('--观舰类紧急委托'), help='小型观舰仪式, 同盟观舰仪式')
# ==========设备设置==========
emulator_parser = subs.add_parser('设备设置')
emulator = emulator_parser.add_argument_group('模拟器', '')

View File

@ -16,6 +16,8 @@ OCR_MODELS = {
# Font: Impact
# Charset: 0123456789ABCDEFSP-:/
'stage': CnOcr(root='./cnocr_models/stage', model_epoch=56),
'cnocr': CnOcr(root='./cnocr_models/cnocr', model_epoch=20)
}
image_shape = (280, 32)
width_range = (0.6, 1.4)
@ -26,7 +28,7 @@ y_range = (-2, 2)
class Ocr:
def __init__(self, buttons, lang, letter=(255, 255, 255), back=(0, 0, 0), mid_process_height=70, threshold=127,
additional_preprocess=None, length=None, white_list=None, name='OCR'):
additional_preprocess=None, use_binary=True, length=None, white_list=None, name='OCR'):
"""
Args:
lang (str): OCR model. in ['digit', 'cnocr'].
@ -34,6 +36,7 @@ class Ocr:
back (tuple(int)): Background RGB.
mid_process_height (int): 70
additional_preprocess (callable):
use_binary (bool):
length (int, tuple(int)): Expected length.
white_list (str): Expected str.
buttons (Button, List[Button]): Button or list of Button instance.
@ -45,6 +48,7 @@ class Ocr:
self.mid_process_height = mid_process_height
self.threshold = threshold
self.additional_preprocess = additional_preprocess
self.use_binary=use_binary
self.length = (length, length) if isinstance(length, int) else length
self.white_list = white_list
self.buttons = buttons if isinstance(buttons, list) else [buttons]
@ -80,7 +84,8 @@ class Ocr:
image = self.additional_preprocess(image)
# Binarization.
_, image = cv2.threshold(image, self.threshold, 255, cv2.THRESH_BINARY)
if self.use_binary:
_, image = cv2.threshold(image, self.threshold, 255, cv2.THRESH_BINARY)
# Resize to input size.
size = (int(image.shape[1] / image.shape[0] * image_shape[1]), image_shape[1])

View File

@ -1,4 +1,5 @@
import time
from datetime import datetime, timedelta
from functools import wraps
from module.logger import logger
@ -16,6 +17,20 @@ def timer(function):
return function_timer
def future_time(string):
"""
Args:
string (str): Such as 14:59.
Returns:
datetime: Time with given hour, minute, second in the future.
"""
hour, minute = [int(x) for x in string.split(':')]
future = datetime.now().replace(hour=hour, minute=minute, second=0, microsecond=0)
future = future + timedelta(days=1) if future < datetime.now() else future
return future
class Timer:
def __init__(self, limit):
self.limit = limit

View File

@ -2,12 +2,13 @@ import codecs
import configparser
import copy
import os
from datetime import datetime, timedelta
import cv2
from datetime import datetime
import cv2
import numpy as np
from PIL import Image
from module.base.timer import future_time
from module.config.dictionary import *
from module.logger import logger
@ -240,6 +241,28 @@ class AzurLaneConfig:
ENABLE_OIL_REWARD = True
ENABLE_COIN_REWARD = True
ENABLE_MISSION_REWARD = True
ENABLE_COMMISSION_REWARD = True
COMMISSION_PRIORITY = {
'major_comm': 0,
'daily_comm': 100,
'extra_drill': 20,
'extra_part': 60,
'extra_cube': 80,
'extra_oil': 90,
'extra_book': 70,
'urgent_drill': 45,
'urgent_part': 95,
'urgent_book': 145,
'urgent_box': 195,
'urgent_cube': 165,
'urgent_gem': 205,
'urgent_ship': 155,
'expire_shorter_than_2': 11,
'expire_longer_than_6': -11,
'duration_shorter_than_2': 11,
'duration_longer_than_6': -11,
}
COMMISSION_TIME_LIMIT = 0
"""
C_7_2_mystery_farming
@ -302,10 +325,7 @@ class AzurLaneConfig:
self.ENABLE_STOP_CONDITION = to_bool(option['enable_stop_condition'])
self.STOP_IF_COUNT_GREATER_THAN = int(option['if_count_greater_than'])
if not option['if_time_reach'].isdigit():
hour, minute = [int(x) for x in option['if_time_reach'].split(':')]
limit = datetime.now().replace(hour=hour, minute=minute, second=0, microsecond=0)
limit = limit + timedelta(1) if limit < datetime.now() else limit
self.STOP_IF_TIME_REACH = limit
self.STOP_IF_TIME_REACH = future_time(option['if_time_reach'])
else:
self.STOP_IF_TIME_REACH = 0
self.STOP_IF_OIL_LOWER_THAN = int(option['if_oil_lower_than'])
@ -340,8 +360,11 @@ 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']:
for attr in ['enable_reward', 'enable_oil_reward', 'enable_coin_reward', 'enable_mission_reward', 'enable_commission_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])
option = config['Main']
self.CAMPAIGN_NAME = option['main_stage']

View File

@ -76,6 +76,26 @@ dic_chi_to_eng = {
'启用石油收获': 'enable_oil_reward',
'启用物资收获': 'enable_coin_reward',
'启用任务收获': 'enable_mission_reward',
'启用委托收获': 'enable_commission_reward',
'委托时间限制': 'commission_time_limit',
'委托耗时小于2h': 'duration_shorter_than_2',
'委托耗时超过6h': 'duration_longer_than_6',
'委托过期小于2h': 'expire_shorter_than_2',
'委托过期大于6h': 'expire_longer_than_6',
'日常委托': 'daily_comm',
'主要委托': 'major_comm',
'钻头类额外委托': 'extra_drill',
'部件类额外委托': 'extra_part',
'魔方类额外委托': 'extra_cube',
'石油类额外委托': 'extra_oil',
'教材类额外委托': 'extra_book',
'钻头类紧急委托': 'urgent_drill',
'部件类紧急委托': 'urgent_part',
'魔方类紧急委托': 'urgent_cube',
'教材类紧急委托': 'urgent_book',
'装备类紧急委托': 'urgent_box',
'钻石类紧急委托': 'urgent_gem',
'观舰类紧急委托': 'urgent_ship',
'设备': 'serial',
'打每日': 'enable_daily_mission',
'打困难': 'enable_hard_campaign',

View File

@ -5,6 +5,14 @@ from module.base.template import Template
# Don't modified it manually.
COIN = Button(area=(403, 64, 436, 88), color=(226, 173, 72), button=(403, 64, 436, 88), file='./assets/reward/COIN.png')
COMMISSION_ADVICE = Button(area=(871, 322, 999, 383), color=(230, 177, 116), button=(871, 322, 999, 383), file='./assets/reward/COMMISSION_ADVICE.png')
COMMISSION_DAILY = Button(area=(35, 132, 67, 186), color=(208, 172, 118), button=(35, 132, 67, 186), file='./assets/reward/COMMISSION_DAILY.png')
COMMISSION_HAS_PENDING = Button(area=(357, 300, 359, 330), color=(86, 201, 173), button=(357, 300, 359, 330), file='./assets/reward/COMMISSION_HAS_PENDING.png')
COMMISSION_NOTICE_AT_CAMPAIGN = Button(area=(1054, 647, 1061, 654), color=(197, 89, 64), button=(1054, 647, 1061, 654), file='./assets/reward/COMMISSION_NOTICE_AT_CAMPAIGN.png')
COMMISSION_OIL_CONFIRM = Button(area=(704, 493, 876, 550), color=(96, 145, 204), button=(704, 493, 876, 550), file='./assets/reward/COMMISSION_OIL_CONFIRM.png')
COMMISSION_START = Button(area=(1028, 322, 1156, 383), color=(229, 175, 113), button=(1028, 322, 1156, 383), file='./assets/reward/COMMISSION_START.png')
COMMISSION_STOP_SCROLLING = Button(area=(115, 236, 179, 487), color=(50, 55, 74), button=(115, 236, 179, 487), file='./assets/reward/COMMISSION_STOP_SCROLLING.png')
COMMISSION_URGENT = Button(area=(35, 231, 68, 281), color=(215, 188, 124), button=(35, 231, 68, 281), file='./assets/reward/COMMISSION_URGENT.png')
EXP_INFO_S_REWARD = Button(area=(498, 140, 557, 154), color=(233, 241, 127), button=(498, 140, 557, 154), file='./assets/reward/EXP_INFO_S_REWARD.png')
MISSION_MULTI = Button(area=(1041, 8, 1101, 39), color=(226, 192, 142), button=(1041, 8, 1101, 39), file='./assets/reward/MISSION_MULTI.png')
MISSION_NOTICE = Button(area=(940, 670, 945, 681), color=(183, 83, 66), button=(940, 670, 945, 681), file='./assets/reward/MISSION_NOTICE.png')

465
module/reward/commission.py Normal file
View File

@ -0,0 +1,465 @@
import re
from datetime import datetime, timedelta
import cv2
import numpy as np
from scipy import signal
from module.base.ocr import Ocr
from module.base.timer import Timer
from module.base.utils import area_offset, get_color
from module.handler.info_bar import InfoBarHandler
from module.logger import logger
from module.reward.assets import *
from module.ui.page import page_reward, page_commission
from module.ui.ui import UI
dictionary = {
'major_comm': ['自主训练', '对抗演习', '科研任务', '工具整备', '战术课程', '货物运输'],
'daily_comm': ['日常资源开发', '高阶战术研发'],
'extra_drill': ['航行训练', '防卫巡逻', '海域浮标检查作业'],
'extra_part': ['委托'],
'extra_cube': ['演习'],
'extra_oil': ['油田'],
'extra_book': ['商船护卫'],
'urgent_drill': ['运输部队', '侦查部队', '主力部队', '精锐部队'],
'urgent_part': ['维拉', '', '多伦瓦', '恐班纳'],
'urgent_book': ['土豪尔', '姆波罗', '马拉基', '卡波罗', '马内', '玛丽', '', '特林'],
'urgent_box': ['装备', '物资'],
'urgent_cube': ['解救', '敌袭'],
'urgent_gem': ['要员', '度假', '巡视'],
'urgent_ship': ['观舰']
}
class Commission:
def __init__(self, image, y):
self.y = y
self.stack_y = y
self.area = (188, y - 119, 1199, y)
self.image = image
self.valid = True
# Name
area = area_offset((211, 26, 415, 49), self.area[0:2])
button = Button(area=area, color=(), button=area, name='COMMISSION')
ocr = Ocr(button, lang='cnocr', back=(74, 97, 148), use_binary=False)
self.button = button
self.name = ocr.ocr(image)
self.genre = self.parse_name(self.name)
# Duration time
area = area_offset((290, 74, 390, 92), self.area[0:2])
button = Button(area=area, color=(), button=area, name='DURATION')
ocr = Ocr(button, lang='stage', back=(57, 85, 132))
self.duration = self.parse_time(ocr.ocr(image))
# Expire time
area = area_offset((-49, 68, -45, 84), self.area[0:2])
button = Button(area=area, color=(189, 65, 66), button=area, name='IS_URGENT')
if button.appear_on(image):
area = area_offset((-49, 73, 45, 91), self.area[0:2])
button = Button(area=area, color=(), button=area, name='EXPIRE')
ocr = Ocr(button, lang='stage', back=(189, 65, 66))
self.expire = self.parse_time(ocr.ocr(image))
else:
self.expire = None
# Status
area = area_offset((179, 71, 187, 93), self.area[0:2])
dic = {
0: 'finished',
1: 'running',
2: 'pending'
}
self.status = dic[int(np.argmax(get_color(image, area)))]
def __str__(self):
if self.valid:
if self.expire:
return f'{self.name} (Genre: {self.genre}, Status: {self.status}, Duration: {self.duration}, Expire: {self.expire})'
else:
return f'{self.name} (Genre: {self.genre}, Status: {self.status}, Duration: {self.duration})'
else:
return f'{self.name} (Invalid)'
def __eq__(self, other):
"""
Args:
other (Commission):
Returns:
bool:
"""
threshold = timedelta(seconds=30)
if not self.valid or not other.valid:
return False
if self.genre != other.genre or self.status != other.status:
return False
if (other.duration < self.duration - threshold) or (other.duration > self.duration + threshold):
return False
if (not self.expire and other.expire) or (self.expire and not other.expire):
return False
if self.expire and other.expire:
if (other.expire < self.expire - threshold) or (other.expire > self.expire + threshold):
return False
return True
def parse_time(self, string):
"""
Args:
string (str): Such as 01:00:00, 05:47:10, 17:50:51.
Returns:
timedelta: datetime.timedelta instance.
"""
string = string.replace('D', '0') # Poor OCR
result = re.search('(\d+):(\d+):(\d+)', string)
if not result:
logger.warning(f'Invalid time string: {string}')
self.valid = False
return None
else:
result = [int(s) for s in result.groups()]
return timedelta(hours=result[0], minutes=result[1], seconds=result[2])
def parse_name(self, string):
"""
Args:
string (str): Commission name, such as 'NYB要员护卫'.
Returns:
str: Commission genre, such as 'urgent_gem'.
"""
for key, value in dictionary.items():
for keyword in value:
if keyword in string:
return key
logger.warning(f'Name with unknown genre: {string}')
self.valid = False
return ''
class CommissionGroup:
show = (188, 67, 1199, 692)
height = 210 # About 1.5 commission height
lower = int((show[3] - show[1]) / 2 - height / 2)
template_area = (620, lower, 1154, lower + height)
def __init__(self):
self.template = None
self.swipe = 0
self.commission = []
def __contains__(self, item):
for commission in self.commission:
if commission == item:
return True
return False
def __iter__(self):
return iter(self.commission)
def __bool__(self):
return len(self.commission) > 0
@property
def count(self):
return len(self.commission)
def merge(self, image):
"""Load commissions from image.
If you want to load commissions from multiple image,
make sure that the next one and previous one have something same.
Which means, you merge a image, then swipe a little bit, then merge another image.
Args:
image (PIl.Image.Image):
"""
# Find swipe distance
if self.template is None:
self.template = np.array(image.crop(self.template_area))
self.swipe = 0
res = cv2.matchTemplate(self.template, np.array(image), cv2.TM_CCOEFF_NORMED)
_, similarity, _, position = cv2.minMaxLoc(res)
if similarity < 0.85:
logger.warning(f'Low similarity when finding swipe. Similarity: {similarity}, Position: {position}')
self.swipe -= position[1] - self.template_area[1]
self.template = np.array(image.crop(self.template_area))
# Find commission position
color_height = np.mean(image.crop((597, 0, 619, 720)).convert('L'), axis=1)
parameters = {'height': 200}
peaks, _ = signal.find_peaks(color_height, **parameters)
peaks = [y for y in peaks if y > 67 + 117]
# Add commission to list
for y in peaks:
stack_y = y + self.swipe
diff = np.array([c.stack_y - stack_y for c in self.commission])
if np.any(np.abs(diff) < 3):
continue
commission = Commission(image, y=y)
commission.stack_y = stack_y
logger.info(f'Add commission: {commission}')
self.commission.append(commission)
def commission_choose(daily, urgent, priority, time_limit=None):
"""
Args:
daily (CommissionGroup):
urgent (CommissionGroup):
priority (dict):
time_limit (datetime):
Returns:
CommissionGroup, CommissionGroup: Chosen daily commission, Chosen urgent commission
"""
# Count Commission
commission = daily.commission + urgent.commission
running_count = np.sum([1 for c in commission if c.status == 'running'])
logger.attr('Running', running_count)
if running_count >= 4:
return [], []
# Calculate priority
commission = [c for c in commission if c.valid and c.status == 'pending']
comm_priority = []
for comm in commission:
pri = priority[comm.genre]
if comm.duration <= timedelta(hours=2):
pri += priority['duration_shorter_than_2']
if comm.duration >= timedelta(hours=6):
pri += priority['duration_longer_than_6']
if comm.expire:
if comm.expire <= timedelta(hours=2):
pri += priority['expire_shorter_than_2']
if comm.expire >= timedelta(hours=6):
pri += priority['expire_longer_than_6']
comm_priority.append(pri)
# Sort
commission = list(np.array(commission)[np.argsort(comm_priority)])[::-1]
if time_limit:
commission = [comm for comm in commission if datetime.now() + comm.duration <= time_limit]
commission = commission[:4 - running_count]
daily_choose, urgent_choose = CommissionGroup(), CommissionGroup()
for comm in commission:
if comm in daily:
daily_choose.commission.append(comm)
if comm in urgent:
urgent_choose.commission.append(comm)
if daily_choose:
logger.info('Choose daily commission')
for comm in daily_choose:
logger.info(comm)
if urgent_choose:
logger.info('Choose urgent commission')
for comm in urgent_choose:
logger.info(comm)
return daily_choose, urgent_choose
class RewardCommission(UI, InfoBarHandler):
daily: CommissionGroup
urgent: CommissionGroup
daily_choose: CommissionGroup
urgent_choose: CommissionGroup
def _commission_ensure_mode(self, mode):
if self.appear(COMMISSION_DAILY):
current = 'daily'
elif self.appear(COMMISSION_URGENT):
current = 'urgent'
else:
logger.warning('Unknown Commission mode')
return False
if current == mode:
return False
if mode == 'daily':
self.device.click(COMMISSION_DAILY)
if mode == 'urgent':
self.device.click(COMMISSION_URGENT)
self.device.sleep(0.3)
self.device.screenshot()
return True
def _commission_mode_reset(self):
if self.appear(COMMISSION_DAILY):
current, another = COMMISSION_DAILY, COMMISSION_URGENT
elif self.appear(COMMISSION_URGENT):
current, another = COMMISSION_URGENT, COMMISSION_DAILY
else:
logger.warning('Unknown Commission mode')
return False
self.device.click(another)
self.device.screenshot()
self.device.click(current)
self.device.sleep(0.3)
self.device.screenshot()
return True
def _commission_swipe(self, distance=180):
# Distance of two commission is 146px
self.device.swipe((0, -distance), box=(620, 67, 1154, 692), random_range=(-20, -5, 20, 5))
self.device.click(COMMISSION_STOP_SCROLLING)
self.device.sleep(0.3)
self.device.screenshot()
def _commission_scan_list(self):
commission = CommissionGroup()
commission.merge(self.device.image)
if commission.count <= 3:
return commission
prev = commission.count
for _ in range(15):
self._commission_swipe()
commission.merge(self.device.image)
if commission.count - prev <= 0:
break
prev = commission.count
return commission
def _commission_scan_all(self):
logger.hr('Scan daily')
self._commission_ensure_mode('daily')
daily = self._commission_scan_list()
logger.hr('Scan urgent')
self._commission_ensure_mode('urgent')
urgent = self._commission_scan_list()
logger.hr('Showing commission')
logger.info('Daily commission')
for comm in daily:
logger.info(comm)
if urgent.count:
logger.info('Urgent commission')
for comm in urgent:
logger.info(comm)
self.daily = daily
self.urgent = urgent
self.daily_choose, self.urgent_choose = commission_choose(
self.daily,
self.urgent,
priority=self.config.COMMISSION_PRIORITY,
time_limit=self.config.COMMISSION_TIME_LIMIT)
return daily, urgent
def _commission_start_click(self, comm):
"""
Args:
comm (Commission):
"""
logger.info(f'Start commission {comm}')
comm_timer = Timer(3)
while 1:
if comm_timer.reached():
self.device.click(comm.button)
comm_timer.reset()
if self.appear_then_click(COMMISSION_OIL_CONFIRM, offset=True, interval=3):
pass
if self.appear_then_click(COMMISSION_START, interval=3):
pass
if self.appear_then_click(COMMISSION_ADVICE, interval=3):
pass
if self.handle_info_bar():
break
self.device.screenshot()
return True
def _commission_find_and_start(self, comm):
"""
Args:
comm (Commission):
"""
logger.hr(f'Finding commission')
logger.info(f'Finding commission {comm}')
commission = CommissionGroup()
prev = 0
for _ in range(15):
commission.merge(self.device.image)
if commission.count - prev <= 0:
return True
prev = commission.count
if comm in commission:
# Update commission position.
# Because once you start a commission, the commission list changes.
for new_comm in commission:
if comm == new_comm:
comm = new_comm
self._commission_start_click(comm)
self._commission_mode_reset()
return True
self._commission_swipe()
logger.warning(f'Commission not found: {comm}')
return False
def commission_start(self):
"""
Method to scan and run commissions.
Make sure current page is page_commission before calls.
"""
logger.hr('Commission scan', level=2)
self._commission_scan_all()
logger.hr('Commission run', level=2)
if self.daily_choose:
for comm in self.daily_choose:
self._commission_ensure_mode('daily')
self._commission_find_and_start(comm)
if self.urgent_choose:
for comm in self.urgent_choose:
self._commission_ensure_mode('urgent')
self._commission_find_and_start(comm)
if not self.daily_choose and not self.urgent_choose:
logger.info('No commission chose')
def handle_commission_start(self):
"""Make sure current page is page_reward before calls.
Returns:
bool: If runs a commission.
"""
if not self.config.ENABLE_COMMISSION_REWARD:
return False
self.device.screenshot()
if not self.appear(COMMISSION_HAS_PENDING):
logger.info('No commission pending')
return False
self.ui_goto(page_commission)
self.commission_start()
self.ui_goto(page_reward, skip_first_screenshot=True)
def commission_notice_show_at_campaign(self):
"""Make sure current page is page_campaign before calls.
Returns:
bool: If any commission finished.
"""
return self.appear(COMMISSION_NOTICE_AT_CAMPAIGN)

View File

@ -5,10 +5,10 @@ from module.combat.assets import *
from module.logger import logger
from module.reward.assets import *
from module.ui.page import *
from module.ui.ui import UI
from module.reward.commission import RewardCommission
class Reward(UI):
class Reward(RewardCommission):
def reward(self):
logger.hr('Reward start')
self.ui_goto_main()
@ -17,6 +17,8 @@ class Reward(UI):
self.ui_goto(page_reward, skip_first_screenshot=True)
self._reward_receive()
self.handle_info_bar()
self.handle_commission_start()
self.ui_click(
click_button=page_reward.links[page_main],
@ -47,6 +49,16 @@ class Reward(UI):
exit_timer = Timer(1)
click_timer = Timer(1)
exit_timer.start()
btn = []
if self.config.ENABLE_REWARD:
btn.append(REWARD_3)
if self.config.ENABLE_COMMISSION_REWARD:
btn.append(REWARD_1)
if self.config.ENABLE_OIL_REWARD:
btn.append(OIL)
if self.config.ENABLE_COIN_REWARD:
btn.append(COIN)
while 1:
self.device.screenshot()
@ -57,7 +69,7 @@ class Reward(UI):
reward = True
continue
for button in [REWARD_1, REWARD_3, OIL, COIN]:
for button in btn:
if not click_timer.reached():
continue
if self.appear_then_click(button, interval=1):

View File

@ -8,6 +8,7 @@ BACK_ARROW = Button(area=(36, 53, 82, 55), color=(251, 251, 255), button=(33, 31
CAMPAIGN_GOTO_DAILY = Button(area=(804, 648, 892, 703), color=(189, 145, 78), button=(804, 648, 892, 703), file='./assets/ui/CAMPAIGN_GOTO_DAILY.png')
CAMPAIGN_GOTO_EVENT = Button(area=(804, 648, 892, 703), color=(189, 145, 78), button=(1178, 171, 1230, 223), file='./assets/ui/CAMPAIGN_GOTO_EVENT.png')
CAMPAIGN_GOTO_EXERCISE = Button(area=(1166, 648, 1248, 703), color=(177, 136, 69), button=(1166, 648, 1248, 703), file='./assets/ui/CAMPAIGN_GOTO_EXERCISE.png')
COMMISSION_CHECK = Button(area=(122, 16, 175, 39), color=(157, 173, 210), button=(122, 16, 175, 39), file='./assets/ui/COMMISSION_CHECK.png')
DAILY_CHECK = Button(area=(23, 656, 67, 698), color=(84, 139, 210), button=(23, 656, 67, 698), file='./assets/ui/DAILY_CHECK.png')
EVENT_CHECK = Button(area=(123, 63, 206, 109), color=(88, 104, 138), button=(123, 63, 206, 109), file='./assets/ui/EVENT_CHECK.png')
EXERCISE_CHECK = Button(area=(1065, 340, 1204, 382), color=(129, 166, 220), button=(1065, 340, 1204, 382), file='./assets/ui/EXERCISE_CHECK.png')
@ -20,5 +21,6 @@ MAIN_GOTO_REWARD = Button(area=(11, 139, 30, 189), color=(69, 81, 115), button=(
MISSION_CHECK = Button(area=(120, 15, 173, 40), color=(141, 156, 194), button=(120, 15, 173, 40), file='./assets/ui/MISSION_CHECK.png')
OCR_OIL_CV = Button(area=(634, 27, 714, 48), color=(93, 95, 109), button=(634, 27, 714, 48), file='./assets/ui/OCR_OIL_CV.png')
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')
SP_CHECK = Button(area=(123, 63, 206, 109), color=(95, 110, 145), button=(123, 63, 206, 109), file='./assets/ui/SP_CHECK.png')

View File

@ -70,3 +70,10 @@ page_main.link(button=MAIN_GOTO_REWARD, destination=page_reward)
page_mission = Page(MISSION_CHECK)
page_mission.link(button=GOTO_MAIN, destination=page_main)
page_main.link(button=MAIN_GOTO_MISSION, destination=page_mission)
# Commission
# Please don't goto commission from campaign.
page_commission = Page(COMMISSION_CHECK)
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)