mirror of
https://github.com/LmeSzinc/AzurLaneAutoScript.git
synced 2025-01-08 12:07:36 +08:00
Add: Event PT and time limit
- Fix: Auto update events in GemsFarming
This commit is contained in:
parent
afa9bf1686
commit
e47e613638
BIN
assets/cn/campaign/OCR_EVENT_PT.png
Normal file
BIN
assets/cn/campaign/OCR_EVENT_PT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
BIN
assets/en/campaign/OCR_EVENT_PT.png
Normal file
BIN
assets/en/campaign/OCR_EVENT_PT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/jp/campaign/OCR_EVENT_PT.png
Normal file
BIN
assets/jp/campaign/OCR_EVENT_PT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
BIN
assets/tw/campaign/OCR_EVENT_PT.png
Normal file
BIN
assets/tw/campaign/OCR_EVENT_PT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.4 KiB |
@ -7,6 +7,7 @@ from module.base.template import Template
|
||||
CHAPTER_NEXT = Button(area={'cn': (1216, 362, 1232, 388), 'en': (1216, 362, 1232, 388), 'jp': (1216, 362, 1232, 388), 'tw': (1216, 362, 1232, 388)}, color={'cn': (121, 150, 198), 'en': (121, 150, 198), 'jp': (121, 150, 198), 'tw': (121, 150, 198)}, button={'cn': (1216, 362, 1232, 388), 'en': (1216, 362, 1232, 388), 'jp': (1216, 362, 1232, 388), 'tw': (1216, 362, 1232, 388)}, file={'cn': './assets/cn/campaign/CHAPTER_NEXT.png', 'en': './assets/en/campaign/CHAPTER_NEXT.png', 'jp': './assets/jp/campaign/CHAPTER_NEXT.png', 'tw': './assets/tw/campaign/CHAPTER_NEXT.png'})
|
||||
CHAPTER_PREV = Button(area={'cn': (42, 360, 58, 387), 'en': (42, 360, 58, 387), 'jp': (42, 360, 58, 387), 'tw': (42, 360, 58, 387)}, color={'cn': (105, 133, 169), 'en': (105, 133, 169), 'jp': (105, 133, 169), 'tw': (105, 133, 169)}, button={'cn': (42, 360, 58, 387), 'en': (42, 360, 58, 387), 'jp': (42, 360, 58, 387), 'tw': (42, 360, 58, 387)}, file={'cn': './assets/cn/campaign/CHAPTER_PREV.png', 'en': './assets/en/campaign/CHAPTER_PREV.png', 'jp': './assets/jp/campaign/CHAPTER_PREV.png', 'tw': './assets/tw/campaign/CHAPTER_PREV.png'})
|
||||
COMMISSION_NOTICE_AT_CAMPAIGN = Button(area={'cn': (1077, 637, 1083, 643), 'en': (1077, 637, 1083, 643), 'jp': (1077, 637, 1083, 643), 'tw': (1077, 637, 1083, 643)}, color={'cn': (172, 72, 49), 'en': (172, 72, 49), 'jp': (172, 72, 49), 'tw': (172, 72, 49)}, button={'cn': (1077, 637, 1083, 643), 'en': (1077, 637, 1083, 643), 'jp': (1077, 637, 1083, 643), 'tw': (1077, 637, 1083, 643)}, file={'cn': './assets/cn/campaign/COMMISSION_NOTICE_AT_CAMPAIGN.png', 'en': './assets/en/campaign/COMMISSION_NOTICE_AT_CAMPAIGN.png', 'jp': './assets/jp/campaign/COMMISSION_NOTICE_AT_CAMPAIGN.png', 'tw': './assets/tw/campaign/COMMISSION_NOTICE_AT_CAMPAIGN.png'})
|
||||
OCR_EVENT_PT = Button(area={'cn': (1196, 109, 1280, 131), 'en': (1190, 109, 1280, 129), 'jp': (1196, 109, 1280, 131), 'tw': (1196, 109, 1280, 131)}, color={'cn': (121, 110, 59), 'en': (88, 78, 51), 'jp': (121, 110, 59), 'tw': (121, 110, 59)}, button={'cn': (1196, 109, 1280, 131), 'en': (1190, 109, 1280, 129), 'jp': (1196, 109, 1280, 131), 'tw': (1196, 109, 1280, 131)}, file={'cn': './assets/cn/campaign/OCR_EVENT_PT.png', 'en': './assets/en/campaign/OCR_EVENT_PT.png', 'jp': './assets/jp/campaign/OCR_EVENT_PT.png', 'tw': './assets/tw/campaign/OCR_EVENT_PT.png'})
|
||||
OCR_OIL = Button(area={'cn': (614, 23, 714, 51), 'en': (614, 23, 714, 51), 'jp': (614, 23, 714, 51), 'tw': (614, 23, 714, 51)}, color={'cn': (64, 65, 79), 'en': (64, 65, 79), 'jp': (64, 65, 79), 'tw': (64, 65, 79)}, button={'cn': (614, 23, 714, 51), 'en': (614, 23, 714, 51), 'jp': (614, 23, 714, 51), 'tw': (614, 23, 714, 51)}, file={'cn': './assets/cn/campaign/OCR_OIL.png', 'en': './assets/en/campaign/OCR_OIL.png', 'jp': './assets/jp/campaign/OCR_OIL.png', 'tw': './assets/tw/campaign/OCR_OIL.png'})
|
||||
SWITCH_1_HARD = Button(area={'cn': (82, 641, 148, 675), 'en': (87, 642, 148, 676), 'jp': (24, 645, 150, 697), 'tw': (82, 641, 148, 675)}, color={'cn': (233, 141, 128), 'en': (234, 139, 124), 'jp': (219, 116, 106), 'tw': (236, 159, 148)}, button={'cn': (82, 641, 148, 675), 'en': (87, 642, 148, 676), 'jp': (24, 645, 150, 697), 'tw': (82, 641, 148, 675)}, file={'cn': './assets/cn/campaign/SWITCH_1_HARD.png', 'en': './assets/en/campaign/SWITCH_1_HARD.png', 'jp': './assets/jp/campaign/SWITCH_1_HARD.png', 'tw': './assets/tw/campaign/SWITCH_1_HARD.png'})
|
||||
SWITCH_1_NORMAL = Button(area={'cn': (80, 641, 148, 675), 'en': (73, 639, 149, 671), 'jp': (24, 644, 150, 697), 'tw': (79, 641, 148, 675)}, color={'cn': (157, 180, 227), 'en': (153, 177, 226), 'jp': (143, 169, 222), 'tw': (156, 179, 227)}, button={'cn': (80, 641, 148, 675), 'en': (73, 639, 149, 671), 'jp': (24, 644, 150, 697), 'tw': (79, 641, 148, 675)}, file={'cn': './assets/cn/campaign/SWITCH_1_NORMAL.png', 'en': './assets/en/campaign/SWITCH_1_NORMAL.png', 'jp': './assets/jp/campaign/SWITCH_1_NORMAL.png', 'tw': './assets/tw/campaign/SWITCH_1_NORMAL.png'})
|
||||
|
140
module/campaign/campaign_event.py
Normal file
140
module/campaign/campaign_event.py
Normal file
@ -0,0 +1,140 @@
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from module.base.decorator import cached_property
|
||||
from module.campaign.assets import OCR_EVENT_PT
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import Ocr
|
||||
from module.ui.ui import UI
|
||||
from module.config.utils import deep_get
|
||||
|
||||
|
||||
class PtOcr(Ocr):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, lang='azur_lane', alphabet='X0123456789', **kwargs)
|
||||
|
||||
def pre_process(self, image):
|
||||
"""
|
||||
Args:
|
||||
image (np.ndarray): Shape (height, width, channel)
|
||||
|
||||
Returns:
|
||||
np.ndarray: Shape (width, height)
|
||||
"""
|
||||
# Use MAX(r, g, b)
|
||||
r, g, b = cv2.split(cv2.subtract((255, 255, 255, 0), image))
|
||||
image = cv2.min(cv2.min(r, g), b)
|
||||
# Remove background, 0-192 => 0-255
|
||||
image = cv2.multiply(image, 255 / 192)
|
||||
|
||||
return image.astype(np.uint8)
|
||||
|
||||
|
||||
class CampaignEvent(UI):
|
||||
@cached_property
|
||||
def campaign_pt_ocr(self):
|
||||
return PtOcr(OCR_EVENT_PT)
|
||||
|
||||
def get_event_pt(self):
|
||||
"""
|
||||
Returns:
|
||||
int: PT amount, or 0 if unable to parse
|
||||
"""
|
||||
pt = self.campaign_pt_ocr.ocr(self.device.image)
|
||||
|
||||
res = re.search('X(\d+)', pt)
|
||||
if res:
|
||||
pt = int(res.group(1))
|
||||
logger.attr('Event_PT', pt)
|
||||
return pt
|
||||
else:
|
||||
logger.warning(f'Invalid pt result: {pt}')
|
||||
return 0
|
||||
|
||||
def _disable_tasks(self, tasks):
|
||||
"""
|
||||
Args:
|
||||
tasks (list[str]): Task name
|
||||
"""
|
||||
for task in tasks:
|
||||
keys = f'{task}.Scheduler.Enable'
|
||||
logger.info(f'Disable task `{task}`')
|
||||
self.config.modified[keys] = False
|
||||
|
||||
for task in ['GemsFarming']:
|
||||
if deep_get(self.config.data, keys=f'{task}.Campaign.Event', default='campaign_main') != 'campaign_main':
|
||||
logger.info(f'Reset GemsFarming to 2-4')
|
||||
self.config.modified[f'{task}.Campaign.Name'] = '2-4'
|
||||
self.config.modified[f'{task}.Campaign.Event'] = 'campaign_main'
|
||||
|
||||
logger.info(f'Reset event time limit')
|
||||
self.config.modified['EventGeneral.EventGeneral.TimeLimit'] = datetime(2020, 1, 1, 0, 0)
|
||||
|
||||
self.config.update()
|
||||
|
||||
def event_pt_limit_triggered(self):
|
||||
"""
|
||||
Returns:
|
||||
bool:
|
||||
|
||||
Pages:
|
||||
in: page_event or page_sp
|
||||
"""
|
||||
limit = int(self.config.EventGeneral_PtLimit)
|
||||
tasks = [
|
||||
'Event',
|
||||
'EventAb',
|
||||
'EventCd',
|
||||
'EventSp',
|
||||
'GemsFarming',
|
||||
]
|
||||
command = self.config.Scheduler_Command
|
||||
if limit <= 0 or command not in tasks:
|
||||
return False
|
||||
if command == 'GemsFarming' and self.config.Campaign_Event == 'campaign_main':
|
||||
return False
|
||||
|
||||
pt = self.get_event_pt()
|
||||
if pt >= limit:
|
||||
logger.hr(f'Reach event PT limit: {limit}')
|
||||
self._disable_tasks(tasks)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def event_time_limit_triggered(self):
|
||||
"""
|
||||
Returns:
|
||||
bool:
|
||||
|
||||
Pages:
|
||||
in: page_event or page_sp
|
||||
"""
|
||||
limit = self.config.EventGeneral_TimeLimit
|
||||
tasks = [
|
||||
'Event',
|
||||
'EventAb',
|
||||
'EventCd',
|
||||
'EventSp',
|
||||
'GemsFarming',
|
||||
'Raid',
|
||||
'RaidDaily',
|
||||
'MaritimeEscort',
|
||||
]
|
||||
command = self.config.Scheduler_Command
|
||||
default = datetime(2020, 1, 1, 0, 0)
|
||||
if command not in tasks or limit == default:
|
||||
return False
|
||||
if command == 'GemsFarming' and self.config.Campaign_Event == 'campaign_main':
|
||||
return False
|
||||
|
||||
now = datetime.now()
|
||||
if now > limit:
|
||||
logger.hr(f'Reach event time limit: {limit}')
|
||||
self._disable_tasks(tasks)
|
||||
return True
|
||||
else:
|
||||
return False
|
@ -1,10 +1,10 @@
|
||||
from module.campaign.assets import *
|
||||
from module.campaign.campaign_event import CampaignEvent
|
||||
from module.campaign.campaign_ocr import CampaignOcr
|
||||
from module.exception import CampaignNameError, ScriptEnd
|
||||
from module.logger import logger
|
||||
from module.ui.assets import CAMPAIGN_CHECK
|
||||
from module.ui.switch import Switch
|
||||
from module.ui.ui import UI
|
||||
|
||||
MODE_SWITCH_1 = Switch('Mode_switch_1', offset=(30, 10))
|
||||
MODE_SWITCH_1.add_status('normal', SWITCH_1_NORMAL)
|
||||
@ -14,7 +14,7 @@ MODE_SWITCH_2.add_status('hard', SWITCH_2_HARD)
|
||||
MODE_SWITCH_2.add_status('ex', SWITCH_2_EX)
|
||||
|
||||
|
||||
class CampaignUI(UI, CampaignOcr):
|
||||
class CampaignUI(CampaignEvent, CampaignOcr):
|
||||
ENTRANCE = Button(area=(), color=(), button=(), name='default_button')
|
||||
|
||||
def campaign_ensure_chapter(self, index):
|
||||
|
@ -98,6 +98,11 @@ class CampaignRun(UI):
|
||||
logger.hr('Triggered stop condition: Get new ship')
|
||||
self.config.Scheduler_Enable = False
|
||||
return True
|
||||
# Event limit
|
||||
if oil_check and self.campaign.event_pt_limit_triggered():
|
||||
logger.hr('Triggered stop condition: Event PT limit')
|
||||
self.config.Scheduler_Enable = False
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@ -177,6 +182,8 @@ class CampaignRun(UI):
|
||||
# End
|
||||
if total and self.run_count >= total:
|
||||
break
|
||||
if self.campaign.event_time_limit_triggered():
|
||||
self.config.task_stop()
|
||||
|
||||
# Log
|
||||
logger.hr(name, level=1)
|
||||
|
@ -126,8 +126,10 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig):
|
||||
if isinstance(func, Function):
|
||||
func = func.command
|
||||
func_set = {func, 'General', 'Alas'}
|
||||
if 'opsi' in func.lower():
|
||||
if func.startswith('Opsi'):
|
||||
func_set.add('OpsiGeneral')
|
||||
if func.startswith('Event') or func.startswith('Raid') or func in ['MaritimeEscort', 'GemsFarming']:
|
||||
func_set.add('EventGeneral')
|
||||
logger.info(f'Bind task {func_set}')
|
||||
|
||||
# Bind arguments
|
||||
|
@ -424,6 +424,11 @@ class ConfigUpdater:
|
||||
deep_set(new,
|
||||
keys=f'{task}.Campaign.Event',
|
||||
value=deep_get(self.args, f'{task}.Campaign.Event.{server_}'))
|
||||
for task in ['GemsFarming']:
|
||||
if deep_get(new, keys=f'{task}.Campaign.Event', default='campaign_main') != 'campaign_main':
|
||||
deep_set(new,
|
||||
keys=f'{task}.Campaign.Event',
|
||||
value=deep_get(self.args, f'{task}.Campaign.Event.{server_}'))
|
||||
# War archive does not allow campaign_main
|
||||
for task in ['WarArchives']:
|
||||
if deep_get(new, keys=f'{task}.Campaign.Event', default='campaign_main') == 'campaign_main':
|
||||
|
@ -1,3 +1,4 @@
|
||||
from module.campaign.campaign_event import CampaignEvent
|
||||
from module.event.assets import *
|
||||
from module.exception import CampaignEnd
|
||||
from module.logger import logger
|
||||
@ -7,7 +8,7 @@ from module.ocr.ocr import DigitCounter
|
||||
OCR_REMAIN = DigitCounter(ESCORT_REMAIN, letter=(148, 255, 99), threshold=64)
|
||||
|
||||
|
||||
class MaritimeEscort(MapOperation):
|
||||
class MaritimeEscort(MapOperation, CampaignEvent):
|
||||
def is_in_escort(self):
|
||||
return self.appear(ESCORT_CHECK, offset=(20, 20))
|
||||
|
||||
@ -39,6 +40,9 @@ class MaritimeEscort(MapOperation):
|
||||
logger.info('Maritime escort finished')
|
||||
|
||||
def run(self):
|
||||
if self.event_time_limit_triggered():
|
||||
self.config.task_stop()
|
||||
|
||||
self.ui_goto_main()
|
||||
self.ui_click(MAIN_GOTO_ESCORT, check_button=ESCORT_CHECK, offset=(20, 150), skip_first_screenshot=True)
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
from module.campaign.campaign_event import CampaignEvent
|
||||
from module.exception import ScriptEnd, ScriptError
|
||||
from module.logger import logger
|
||||
from module.raid.raid import Raid, OilExhausted
|
||||
from module.ui.page import page_raid
|
||||
|
||||
|
||||
class RaidRun(Raid):
|
||||
class RaidRun(Raid, CampaignEvent):
|
||||
run_count: int
|
||||
run_limit: int
|
||||
|
||||
@ -40,6 +41,8 @@ class RaidRun(Raid):
|
||||
# End
|
||||
if total and self.run_count == total:
|
||||
break
|
||||
if self.event_time_limit_triggered():
|
||||
self.config.task_stop()
|
||||
|
||||
# Log
|
||||
logger.hr(f'{name}_{mode}', level=2)
|
||||
|
Loading…
Reference in New Issue
Block a user