1
0
mirror of https://gitee.com/sui-feng-cb/AzurLaneAutoScript1 synced 2026-03-09 18:39:04 +08:00

Merge pull request #5525 from LmeSzinc/dev

Bug fix
This commit is contained in:
LmeSzinc 2026-02-19 03:18:06 +08:00 committed by GitHub
commit ad623f6332
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 91 additions and 63 deletions

View File

@ -7879,7 +7879,8 @@
"option": [ "option": [
2, 2,
3, 3,
4 4,
5
] ]
}, },
"ShipIndex": { "ShipIndex": {
@ -7914,7 +7915,8 @@
2, 2,
3, 3,
4, 4,
5 5,
6
] ]
}, },
"ShipIndex": { "ShipIndex": {

View File

@ -541,7 +541,7 @@ CoreShop:
ShipyardDr: ShipyardDr:
ResearchSeries: ResearchSeries:
value: 2 value: 2
option: [ 2, 3, 4 ] option: [ 2, 3, 4, 5 ]
ShipIndex: ShipIndex:
value: 0 value: 0
option: [ 0, 1, 2, 3, 4, 5, 6 ] option: [ 0, 1, 2, 3, 4, 5, 6 ]
@ -550,7 +550,7 @@ ShipyardDr:
Shipyard: Shipyard:
ResearchSeries: ResearchSeries:
value: 1 value: 1
option: [ 1, 2, 3, 4, 5 ] option: [ 1, 2, 3, 4, 5, 6 ]
ShipIndex: ShipIndex:
value: 0 value: 0
option: [ 0, 1, 2, 3, 4, 5, 6 ] option: [ 0, 1, 2, 3, 4, 5, 6 ]

View File

@ -297,13 +297,13 @@ class GeneratedConfig:
CoreShop_Filter = 'Array' CoreShop_Filter = 'Array'
# Group `ShipyardDr` # Group `ShipyardDr`
ShipyardDr_ResearchSeries = 2 # 2, 3, 4 ShipyardDr_ResearchSeries = 2 # 2, 3, 4, 5
ShipyardDr_ShipIndex = 0 # 0, 1, 2, 3, 4, 5, 6 ShipyardDr_ShipIndex = 0 # 0, 1, 2, 3, 4, 5, 6
ShipyardDr_BuyAmount = 2 ShipyardDr_BuyAmount = 2
ShipyardDr_LastRun = datetime.datetime(2020, 1, 1, 0, 0) ShipyardDr_LastRun = datetime.datetime(2020, 1, 1, 0, 0)
# Group `Shipyard` # Group `Shipyard`
Shipyard_ResearchSeries = 1 # 1, 2, 3, 4, 5 Shipyard_ResearchSeries = 1 # 1, 2, 3, 4, 5, 6
Shipyard_ShipIndex = 0 # 0, 1, 2, 3, 4, 5, 6 Shipyard_ShipIndex = 0 # 0, 1, 2, 3, 4, 5, 6
Shipyard_BuyAmount = 2 Shipyard_BuyAmount = 2
Shipyard_LastRun = datetime.datetime(2020, 1, 1, 0, 0) Shipyard_LastRun = datetime.datetime(2020, 1, 1, 0, 0)

View File

@ -1888,7 +1888,8 @@
"help": "", "help": "",
"2": "DR2", "2": "DR2",
"3": "DR3", "3": "DR3",
"4": "DR4" "4": "DR4",
"5": "DR5"
}, },
"ShipIndex": { "ShipIndex": {
"name": "Ship Index", "name": "Ship Index",
@ -1922,7 +1923,8 @@
"2": "PR2", "2": "PR2",
"3": "PR3", "3": "PR3",
"4": "PR4", "4": "PR4",
"5": "PR5" "5": "PR5",
"6": "PR6"
}, },
"ShipIndex": { "ShipIndex": {
"name": "Ship Index", "name": "Ship Index",

View File

@ -1888,7 +1888,8 @@
"help": "ShipyardDr.ResearchSeries.help", "help": "ShipyardDr.ResearchSeries.help",
"2": "2", "2": "2",
"3": "3", "3": "3",
"4": "4" "4": "4",
"5": "5"
}, },
"ShipIndex": { "ShipIndex": {
"name": "ShipyardDr.ShipIndex.name", "name": "ShipyardDr.ShipIndex.name",
@ -1922,7 +1923,8 @@
"2": "2", "2": "2",
"3": "3", "3": "3",
"4": "4", "4": "4",
"5": "5" "5": "5",
"6": "6"
}, },
"ShipIndex": { "ShipIndex": {
"name": "Shipyard.ShipIndex.name", "name": "Shipyard.ShipIndex.name",

View File

@ -1888,7 +1888,8 @@
"help": "", "help": "",
"2": "二期科研", "2": "二期科研",
"3": "三期科研", "3": "三期科研",
"4": "四期科研" "4": "四期科研",
"5": "五期科研"
}, },
"ShipIndex": { "ShipIndex": {
"name": "舰船序号", "name": "舰船序号",
@ -1922,7 +1923,8 @@
"2": "二期科研", "2": "二期科研",
"3": "三期科研", "3": "三期科研",
"4": "四期科研", "4": "四期科研",
"5": "五期科研" "5": "五期科研",
"6": "六期科研"
}, },
"ShipIndex": { "ShipIndex": {
"name": "舰船序号", "name": "舰船序号",

View File

@ -1888,7 +1888,8 @@
"help": "", "help": "",
"2": "二期科研", "2": "二期科研",
"3": "三期科研", "3": "三期科研",
"4": "四期科研" "4": "四期科研",
"5": "五期科研"
}, },
"ShipIndex": { "ShipIndex": {
"name": "艦船序號", "name": "艦船序號",
@ -1922,7 +1923,8 @@
"2": "二期科研", "2": "二期科研",
"3": "三期科研", "3": "三期科研",
"4": "四期科研", "4": "四期科研",
"5": "五期科研" "5": "五期科研",
"6": "六期科研"
}, },
"ShipIndex": { "ShipIndex": {
"name": "艦船序號", "name": "艦船序號",

View File

@ -2,6 +2,7 @@ import numpy as np
from module.base.button import ButtonGrid from module.base.button import ButtonGrid
from module.base.decorator import Config from module.base.decorator import Config
from module.base.timer import Timer
from module.handler.assets import * from module.handler.assets import *
from module.handler.enemy_searching import EnemySearchingHandler from module.handler.enemy_searching import EnemySearchingHandler
from module.logger import logger from module.logger import logger
@ -49,21 +50,14 @@ class AutoSearchHandler(EnemySearchingHandler):
origin=(1185, 155 + offset), delta=(0, 111), origin=(1185, 155 + offset), delta=(0, 111),
button_shape=(53, 104), grid_shape=(1, 3), name='FLEET_SIDEBAR') button_shape=(53, 104), grid_shape=(1, 3), name='FLEET_SIDEBAR')
def _fleet_preparation_sidebar_click(self, index): def _fleet_preparation_get(self):
""" """
Args: Returns:
index (int): int:
1 for formation 1 for formation
2 for meowfficers 2 for meowfficers
3 for auto search setting 3 for auto search setting
Returns:
bool: If changed.
""" """
if index <= 0 or index > 3:
logger.warning(f'Sidebar index cannot be clicked, {index}, limit to 1 through 5 only')
return False
current = 0 current = 0
total = 0 total = 0
sidebar = self._fleet_sidebar() sidebar = self._fleet_sidebar()
@ -81,46 +75,38 @@ class AutoSearchHandler(EnemySearchingHandler):
if not current: if not current:
logger.warning('No fleet sidebar active.') logger.warning('No fleet sidebar active.')
logger.attr('Fleet_sidebar', f'{current}/{total}') logger.attr('Fleet_sidebar', f'{current}/{total}')
if current == index: return current
return False
self.device.click(sidebar[0, index - 1]) def fleet_preparation_sidebar_ensure(self, index):
return True
def fleet_preparation_sidebar_ensure(self, index, skip_first_screenshot=True):
""" """
Args: Args:
index (int): index (int):
1 for formation 1 for formation
2 for meowfficers 2 for meowfficers
3 for auto search setting 3 for auto search setting
skip_first_screenshot (bool):
Returns: Returns:
bool: whether sidebar could be ensured bool: whether sidebar could be ensured
at most 3 attempts are made before at most 3 attempts are made before
return False otherwise True return False otherwise True
""" """
if index <= 0 or index > 5: if index <= 0 or index > 5:
logger.warning(f'Sidebar index cannot be ensured, {index}, limit 1 through 5 only') logger.warning(f'Sidebar index cannot be ensured, {index}, limit 1 through 5 only')
return False return False
counter = 0 interval = Timer(1, count=2)
while 1: sidebar = self._fleet_sidebar()
if skip_first_screenshot: for _ in self.loop(timeout=3):
skip_first_screenshot = False current = self._fleet_preparation_get()
else: if current == index:
self.device.screenshot()
if self._fleet_preparation_sidebar_click(index):
if counter >= 2:
logger.warning('Sidebar could not be ensured')
return False
counter += 1
self.device.sleep((0.3, 0.5))
continue
else:
return True return True
if interval.reached():
self.device.click(sidebar[0, index - 1])
interval.reset()
continue
else:
logger.warning('Sidebar could not be ensured')
return False
def _auto_search_set_click(self, setting): def _auto_search_set_click(self, setting):
""" """

View File

@ -3,8 +3,8 @@ from module.combat.assets import GET_ITEMS_1
from module.logger import logger from module.logger import logger
from module.minigame.assets import * from module.minigame.assets import *
from module.ocr.ocr import Digit from module.ocr.ocr import Digit
from module.ui.assets import GAME_ROOM_CHECK from module.ui.assets import ACADEMY_GOTO_GAME_ROOM, GAME_ROOM_CHECK
from module.ui.page import page_game_room from module.ui.page import page_academy, page_game_room
from module.ui.scroll import Scroll from module.ui.scroll import Scroll
from module.ui.ui import UI from module.ui.ui import UI
@ -131,6 +131,7 @@ class Minigame(UI):
in: page_game_room main_page/choose_game_page in: page_game_room main_page/choose_game_page
out: page_game_room main_page out: page_game_room main_page
""" """
logger.info('minigame go_to_main_page')
while 1: while 1:
if skip_first_screenshot: if skip_first_screenshot:
skip_first_screenshot = False skip_first_screenshot = False
@ -183,8 +184,19 @@ class Minigame(UI):
in: Any page in: Any page
out: page_game_room out: page_game_room
""" """
# TEMP: 2026.02.18 separate self.ui_ensure(page_game_room) into 2 steps
# EN has different page_academy detection, to use ui_ensure(page_game_room),
# ui_goto must use `if self.ui_page_appear(page)` instead of `if self.appear(page.check_button)`
# But that would cause page_main/page_main_white clicking a static switch button
self.ui_ensure(page_academy)
# page_academy -> page_game_room
for _ in self.loop():
if self.ui_page_appear(page_game_room):
break
if self.ui_page_appear(page_academy, interval=5):
self.device.click(ACADEMY_GOTO_GAME_ROOM)
continue
self.ui_ensure(page_game_room)
# game room and choose game have same header, go to game room first # game room and choose game have same header, go to game room first
self.go_to_main_page() self.go_to_main_page()
coin_collected = False coin_collected = False

View File

@ -47,7 +47,7 @@ class OSMapOperation(MapOrderHandler, MissionHandler, PortHandler, StorageHandle
name = ocr.ocr(self.device.image) name = ocr.ocr(self.device.image)
name = "".join(name.split()) name = "".join(name.split())
name = name.lower() name = name.lower()
name = name.strip('\\/-') name = name.strip('\\/-—–-')
if '-' in name: if '-' in name:
name = name.split('-')[0] name = name.split('-')[0]
if 'é' in name: # Méditerranée name maps if 'é' in name: # Méditerranée name maps
@ -80,7 +80,7 @@ class OSMapOperation(MapOrderHandler, MissionHandler, PortHandler, StorageHandle
# For JP only # For JP only
ocr = Ocr(MAP_NAME, lang='jp', letter=(157, 173, 192), threshold=127, name='OCR_OS_MAP_NAME') ocr = Ocr(MAP_NAME, lang='jp', letter=(157, 173, 192), threshold=127, name='OCR_OS_MAP_NAME')
name = ocr.ocr(self.device.image) name = ocr.ocr(self.device.image)
name = name.strip('\\/-') name = name.strip('\\/-—–-')
self.is_zone_name_hidden = '安全' in name self.is_zone_name_hidden = '安全' in name
# Remove punctuations # Remove punctuations
for char in '': for char in '':
@ -109,7 +109,7 @@ class OSMapOperation(MapOrderHandler, MissionHandler, PortHandler, StorageHandle
# For TW only # For TW only
ocr = Ocr(MAP_NAME, lang='tw', letter=(198, 215, 239), threshold=127, name='OCR_OS_MAP_NAME') ocr = Ocr(MAP_NAME, lang='tw', letter=(198, 215, 239), threshold=127, name='OCR_OS_MAP_NAME')
name = ocr.ocr(self.device.image) name = ocr.ocr(self.device.image)
name = name.strip('\\/-') name = name.strip('\\/-—–-')
self.is_zone_name_hidden = '安全' in name self.is_zone_name_hidden = '安全' in name
# Remove '塞壬要塞海域' # Remove '塞壬要塞海域'
if '' in name: if '' in name:
@ -123,7 +123,7 @@ class OSMapOperation(MapOrderHandler, MissionHandler, PortHandler, StorageHandle
# For CN only # For CN only
ocr = Ocr(MAP_NAME, lang='cnocr', letter=(214, 231, 255), threshold=127, name='OCR_OS_MAP_NAME') ocr = Ocr(MAP_NAME, lang='cnocr', letter=(214, 231, 255), threshold=127, name='OCR_OS_MAP_NAME')
name = ocr.ocr(self.device.image) name = ocr.ocr(self.device.image)
name = name.strip('\\/-') name = name.strip('\\/-—–-')
self.is_zone_name_hidden = '安全' in name self.is_zone_name_hidden = '安全' in name
if '-' in name: if '-' in name:
name = name.split('-')[0] name = name.split('-')[0]

View File

@ -15,6 +15,15 @@ from module.ui.assets import RAID_CHECK
from module.ui.page import page_rpg_stage from module.ui.page import page_rpg_stage
class RaidCounterPostMixin(DigitCounter):
def after_process(self, result):
# fix result like "915/", "1515"
result = result.strip('/')
if result.isdigit() and len(result) > 2 and result.endswith('15'):
result = f'{result[:-2]}/15'
return result
class RaidCounter(DigitCounter): class RaidCounter(DigitCounter):
def pre_process(self, image): def pre_process(self, image):
image = super().pre_process(image) image = super().pre_process(image)
@ -163,7 +172,7 @@ def raid_ocr(raid, mode):
if mode == 'ex': if mode == 'ex':
return Digit(button, letter=(255, 239, 215), threshold=128) return Digit(button, letter=(255, 239, 215), threshold=128)
else: else:
return DigitCounter(button, lang='cnocr', letter=(154, 148, 133), threshold=128) return RaidCounterPostMixin(button, lang='cnocr', letter=(154, 148, 133), threshold=128)
def pt_ocr(raid): def pt_ocr(raid):

View File

@ -95,7 +95,7 @@ class RaidRun(Raid, CampaignEvent):
# UI switches # UI switches
if not self._raid_has_oil_icon: if not self._raid_has_oil_icon:
self.ui_goto(page_campaign_menu) self.ui_ensure(page_campaign_menu)
if self.triggered_stop_condition(oil_check=True, coin_check=True): if self.triggered_stop_condition(oil_check=True, coin_check=True):
break break

View File

@ -45,8 +45,12 @@ class StorageHandler(StorageUI):
def _handle_use_box_amount(self, amount): def _handle_use_box_amount(self, amount):
""" """
Args:
amount (int): Expected amount to set
Returns: Returns:
bool: if clicked int: Actual amount set in the UI.
May be less than expected if not enough boxes available.
Pages: Pages:
in: SHOP_BUY_CONFIRM_AMOUNT in: SHOP_BUY_CONFIRM_AMOUNT
@ -84,6 +88,7 @@ class StorageHandler(StorageUI):
logger.info(f'Set box amount: {amount}') logger.info(f'Set box amount: {amount}')
skip_first = True skip_first = True
retry = Timer(1, count=2) retry = Timer(1, count=2)
click_count = 0
for _ in self.loop(): for _ in self.loop():
if skip_first: if skip_first:
skip_first = False skip_first = False
@ -92,13 +97,19 @@ class StorageHandler(StorageUI):
diff = amount - current diff = amount - current
if diff == 0: if diff == 0:
break break
if click_count >= 2:
logger.warning(f'Box amount stuck at {current}, '
f'requested {amount} but only {current} available')
break
if retry.reached(): if retry.reached():
button = AMOUNT_PLUS if diff > 0 else AMOUNT_MINUS button = AMOUNT_PLUS if diff > 0 else AMOUNT_MINUS
self.device.multi_click(button, n=abs(diff), interval=(0.1, 0.2)) self.device.multi_click(button, n=abs(diff), interval=(0.1, 0.2))
click_count += 1
retry.reset() retry.reset()
return True logger.info(f'Box amount set to {current}')
return current
def _storage_use_one_box(self, button, amount=1): def _storage_use_one_box(self, button, amount=1):
""" """
@ -155,10 +166,10 @@ class StorageHandler(StorageUI):
# use match_template_color on BOX_AMOUNT_CONFIRM # use match_template_color on BOX_AMOUNT_CONFIRM
# a long animation that opens a box, will be on the top of BOX_AMOUNT_CONFIRM # a long animation that opens a box, will be on the top of BOX_AMOUNT_CONFIRM
if self.match_template_color(BOX_AMOUNT_CONFIRM, offset=(20, 20), interval=5): if self.match_template_color(BOX_AMOUNT_CONFIRM, offset=(20, 20), interval=5):
self._handle_use_box_amount(amount) actual = self._handle_use_box_amount(amount)
self.device.click(BOX_AMOUNT_CONFIRM) self.device.click(BOX_AMOUNT_CONFIRM)
self.interval_reset(BOX_AMOUNT_CONFIRM) self.interval_reset(BOX_AMOUNT_CONFIRM)
used = amount used = actual
continue continue
if self.appear_then_click(EQUIP_CONFIRM, offset=(20, 20), interval=5): if self.appear_then_click(EQUIP_CONFIRM, offset=(20, 20), interval=5):
self.interval_reset(MATERIAL_CHECK) self.interval_reset(MATERIAL_CHECK)