mirror of
https://gitee.com/sui-feng-cb/AzurLaneAutoScript1
synced 2026-05-12 20:02:10 +08:00
Merge branch 'master' of https://github.com/LmeSzinc/AzurLaneAutoScript
This commit is contained in:
BIN
assets/cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png
Normal file
BIN
assets/cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
@@ -294,3 +294,4 @@ To add a new event, add a new row in here, and run `python -m module.config.conf
|
||||
| 20260417 | event 20201126 cn | Vacation Lane Rerun | 复刻假日航线 | Vacation Lane Rerun | バケーションレーン(復刻) | - |
|
||||
| 20260417 | event 20250424 cn | Toward Tulipa’s Seas Rerun | 复刻扬起郁金之旗 | Toward Tulipa’s Seas Rerun | チュリッパの海へ(復刻) | - |
|
||||
| 20260417 | event 20260417 cn | Vacation Lane – Beachside Brilliance | - | - | - | 假日航線閃耀海濱 |
|
||||
| 20260417 | event 20201126 cn | Vacation Lane Rerun | - | - | - | 復刻假日航線 |
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from module.base.button import Button
|
||||
from module.campaign.assets import EVENT_20201126_PT_ICON, EVENT_20201126_DETAIL, EVENT_20201126_DETAIL_CHECK, EVENT_20201126_DETAIL_WHITE, EVENT_20201126_ENTRANCE
|
||||
from module.campaign.assets import EVENT_20201126_DETAIL, EVENT_20201126_DETAIL_CHECK, EVENT_20201126_DETAIL_WHITE, \
|
||||
EVENT_20201126_ENTRANCE, EVENT_20201126_ENTRANCE_TEMP, EVENT_20201126_PT_ICON
|
||||
from module.campaign.campaign_base import CampaignBase as CampaignBase_
|
||||
from module.exception import CampaignNameError
|
||||
from module.logger import logger
|
||||
from module.ui.page import page_campaign_menu, page_event, page_main_white
|
||||
from module.ui_white.assets import MAIN_GOTO_CAMPAIGN_WHITE
|
||||
|
||||
EVENT_ANIMATION = Button(area=(49, 229, 119, 400), color=(118, 215, 240), button=(49, 229, 119, 400),
|
||||
name='EVENT_ANIMATION')
|
||||
@@ -24,6 +26,11 @@ class CampaignBase(CampaignBase_):
|
||||
return True
|
||||
self.ui_ensure(page_campaign_menu)
|
||||
if self.is_event_entrance_available():
|
||||
if self.config.SERVER == 'tw':
|
||||
self.ui_click(EVENT_20201126_ENTRANCE_TEMP, check_button=EVENT_20201126_PT_ICON,
|
||||
appear_button=MAIN_GOTO_CAMPAIGN_WHITE, offset=(40, 20))
|
||||
return True
|
||||
|
||||
self.ui_goto_main()
|
||||
if self.ui_page_appear(page_main_white):
|
||||
self.ui_click(EVENT_20201126_DETAIL_WHITE, check_button=EVENT_20201126_DETAIL_CHECK)
|
||||
|
||||
@@ -45,6 +45,52 @@ class LuaLoader:
|
||||
def filepath(self, path):
|
||||
return os.path.join(self.folder, self.server, path)
|
||||
|
||||
def _find_matching_brace(self, text, start_index):
|
||||
depth = 0
|
||||
in_string = None
|
||||
escape = False
|
||||
for i in range(start_index, len(text)):
|
||||
ch = text[i]
|
||||
if in_string:
|
||||
if escape:
|
||||
escape = False
|
||||
elif ch == '\\':
|
||||
escape = True
|
||||
elif ch == in_string:
|
||||
in_string = None
|
||||
else:
|
||||
if ch in ('"', "'"):
|
||||
in_string = ch
|
||||
elif ch == '{':
|
||||
depth += 1
|
||||
elif ch == '}':
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
return i
|
||||
return -1
|
||||
|
||||
def _infer_base_name(self, file, keyword):
|
||||
if keyword:
|
||||
keyword = keyword.strip()
|
||||
if keyword.startswith('pg.base.'):
|
||||
return keyword[len('pg.base.') :]
|
||||
if keyword.startswith('pg.'):
|
||||
return keyword[len('pg.') :]
|
||||
return keyword
|
||||
return os.path.splitext(os.path.basename(file))[0]
|
||||
|
||||
def _load_pg_base_entries(self, text, base_name):
|
||||
pattern = rf"pg\.base\.{re.escape(base_name)}\[(\d+)\]\s*=\s*\{{"
|
||||
result = {}
|
||||
for m in re.finditer(pattern, text):
|
||||
start = m.end() - 1
|
||||
end = self._find_matching_brace(text, start)
|
||||
if end == -1:
|
||||
continue
|
||||
table_text = text[start:end + 1]
|
||||
result[int(m.group(1))] = slpp.decode(table_text)
|
||||
return result
|
||||
|
||||
def _load_file(self, file, keyword=None):
|
||||
"""
|
||||
Args:
|
||||
@@ -56,6 +102,16 @@ class LuaLoader:
|
||||
with open(self.filepath(file), 'r', encoding='utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
if 'pg.base.' in text:
|
||||
base_name = self._infer_base_name(file, keyword)
|
||||
if not base_name:
|
||||
m = re.search(r"pg\.base\.([A-Za-z0-9_]+)\[", text)
|
||||
base_name = m.group(1) if m else None
|
||||
if base_name:
|
||||
result = self._load_pg_base_entries(text, base_name)
|
||||
if result:
|
||||
return result
|
||||
|
||||
result = {}
|
||||
if text.startswith('_G'):
|
||||
text = '{' + text + '}'
|
||||
@@ -86,7 +142,7 @@ class LuaLoader:
|
||||
if os.path.isdir(self.filepath(path)):
|
||||
result = {}
|
||||
for file in tqdm(os.listdir(self.filepath(path))):
|
||||
result.update(self._load_file(f'./{path}/{file}'))
|
||||
result.update(self._load_file(f'./{path}/{file}', keyword=keyword))
|
||||
else:
|
||||
result = self._load_file(path, keyword=keyword)
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ EVENT_20201126_DETAIL = Button(area={'cn': (617, 470, 659, 510), 'en': (617, 470
|
||||
EVENT_20201126_DETAIL_CHECK = Button(area={'cn': (1198, 20, 1244, 65), 'en': (1198, 20, 1244, 65), 'jp': (1198, 20, 1244, 65), 'tw': (1198, 20, 1244, 65)}, color={'cn': (176, 138, 121), 'en': (176, 138, 121), 'jp': (176, 138, 121), 'tw': (176, 138, 121)}, button={'cn': (1198, 20, 1244, 65), 'en': (1198, 20, 1244, 65), 'jp': (1198, 20, 1244, 65), 'tw': (1198, 20, 1244, 65)}, file={'cn': './assets/cn/campaign/EVENT_20201126_DETAIL_CHECK.png', 'en': './assets/cn/campaign/EVENT_20201126_DETAIL_CHECK.png', 'jp': './assets/cn/campaign/EVENT_20201126_DETAIL_CHECK.png', 'tw': './assets/cn/campaign/EVENT_20201126_DETAIL_CHECK.png'})
|
||||
EVENT_20201126_DETAIL_WHITE = Button(area={'cn': (969, 94, 1030, 156), 'en': (969, 94, 1030, 156), 'jp': (969, 94, 1030, 156), 'tw': (969, 94, 1030, 156)}, color={'cn': (178, 148, 165), 'en': (178, 148, 165), 'jp': (178, 148, 165), 'tw': (178, 148, 165)}, button={'cn': (969, 94, 1030, 156), 'en': (969, 94, 1030, 156), 'jp': (969, 94, 1030, 156), 'tw': (969, 94, 1030, 156)}, file={'cn': './assets/cn/campaign/EVENT_20201126_DETAIL_WHITE.png', 'en': './assets/cn/campaign/EVENT_20201126_DETAIL_WHITE.png', 'jp': './assets/cn/campaign/EVENT_20201126_DETAIL_WHITE.png', 'tw': './assets/cn/campaign/EVENT_20201126_DETAIL_WHITE.png'})
|
||||
EVENT_20201126_ENTRANCE = Button(area={'cn': (927, 599, 1054, 631), 'en': (927, 599, 1054, 631), 'jp': (927, 599, 1054, 631), 'tw': (927, 599, 1054, 631)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (927, 599, 1054, 631), 'en': (927, 599, 1054, 631), 'jp': (927, 599, 1054, 631), 'tw': (927, 599, 1054, 631)}, file={'cn': './assets/cn/campaign/EVENT_20201126_ENTRANCE.png', 'en': './assets/cn/campaign/EVENT_20201126_ENTRANCE.png', 'jp': './assets/cn/campaign/EVENT_20201126_ENTRANCE.png', 'tw': './assets/cn/campaign/EVENT_20201126_ENTRANCE.png'})
|
||||
EVENT_20201126_ENTRANCE_TEMP = Button(area={'cn': (1022, 375, 1100, 398), 'en': (1022, 375, 1100, 398), 'jp': (1022, 375, 1100, 398), 'tw': (1022, 375, 1100, 398)}, color={'cn': (143, 197, 241), 'en': (143, 197, 241), 'jp': (143, 197, 241), 'tw': (143, 197, 241)}, button={'cn': (1022, 375, 1100, 398), 'en': (1022, 375, 1100, 398), 'jp': (1022, 375, 1100, 398), 'tw': (1022, 375, 1100, 398)}, file={'cn': './assets/cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png', 'en': './assets/cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png', 'jp': './assets/cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png', 'tw': './assets/cn/campaign/EVENT_20201126_ENTRANCE_TEMP.png'})
|
||||
EVENT_20201126_PT_ICON = Button(area={'cn': (1108, 102, 1133, 127), 'en': (1108, 102, 1133, 127), 'jp': (1108, 102, 1133, 127), 'tw': (1108, 102, 1133, 127)}, color={'cn': (231, 121, 159), 'en': (231, 121, 159), 'jp': (231, 121, 159), 'tw': (231, 121, 159)}, button={'cn': (1108, 102, 1133, 127), 'en': (1108, 102, 1133, 127), 'jp': (1108, 102, 1133, 127), 'tw': (1108, 102, 1133, 127)}, file={'cn': './assets/cn/campaign/EVENT_20201126_PT_ICON.png', 'en': './assets/cn/campaign/EVENT_20201126_PT_ICON.png', 'jp': './assets/cn/campaign/EVENT_20201126_PT_ICON.png', 'tw': './assets/cn/campaign/EVENT_20201126_PT_ICON.png'})
|
||||
EVENT_20221124_ENTRANCE = Button(area={'cn': (1037, 162, 1077, 195), 'en': (1037, 162, 1077, 195), 'jp': (1037, 162, 1077, 195), 'tw': (1037, 162, 1077, 195)}, color={'cn': (207, 168, 148), 'en': (207, 168, 148), 'jp': (207, 168, 148), 'tw': (207, 168, 148)}, button={'cn': (1037, 162, 1077, 195), 'en': (1037, 162, 1077, 195), 'jp': (1037, 162, 1077, 195), 'tw': (1037, 162, 1077, 195)}, file={'cn': './assets/cn/campaign/EVENT_20221124_ENTRANCE.png', 'en': './assets/cn/campaign/EVENT_20221124_ENTRANCE.png', 'jp': './assets/cn/campaign/EVENT_20221124_ENTRANCE.png', 'tw': './assets/cn/campaign/EVENT_20221124_ENTRANCE.png'})
|
||||
EVENT_20221124_PT_ICON = Button(area={'cn': (1106, 109, 1135, 130), 'en': (1071, 109, 1101, 129), 'jp': (1106, 109, 1135, 130), 'tw': (1106, 109, 1135, 130)}, color={'cn': (151, 116, 139), 'en': (152, 115, 138), 'jp': (151, 116, 139), 'tw': (151, 116, 139)}, button={'cn': (1106, 109, 1135, 130), 'en': (1071, 109, 1101, 129), 'jp': (1106, 109, 1135, 130), 'tw': (1106, 109, 1135, 130)}, file={'cn': './assets/cn/campaign/EVENT_20221124_PT_ICON.png', 'en': './assets/en/campaign/EVENT_20221124_PT_ICON.png', 'jp': './assets/cn/campaign/EVENT_20221124_PT_ICON.png', 'tw': './assets/cn/campaign/EVENT_20221124_PT_ICON.png'})
|
||||
|
||||
@@ -12,7 +12,7 @@ from module.commission.project import COMMISSION_FILTER, Commission
|
||||
from module.config.config_generated import GeneratedConfig
|
||||
from module.config.utils import get_server_last_update, get_server_next_update, nearest_future
|
||||
from module.dorm.dorm import RewardDorm
|
||||
from module.exception import GameStuckError
|
||||
from module.exception import GameStuckError, OilMaxed, RequestHumanTakeover
|
||||
from module.handler.info_handler import InfoHandler
|
||||
from module.logger import logger
|
||||
from module.map.map_grids import SelectedGrids
|
||||
@@ -491,7 +491,7 @@ class RewardCommission(UI, InfoHandler):
|
||||
if not self.daily_choose and not self.urgent_choose:
|
||||
logger.info('No commission chose')
|
||||
|
||||
def commission_receive(self, skip_first_screenshot=True):
|
||||
def _commission_receive(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Args:
|
||||
skip_first_screenshot:
|
||||
@@ -559,11 +559,7 @@ class RewardCommission(UI, InfoHandler):
|
||||
# handle oil maxed
|
||||
if self.config.SERVER in ['cn']:
|
||||
if self.appear(OIL_MAXED, offset=(20, 20), interval=3):
|
||||
logger.info("Oil maxed, buy food to consume oil")
|
||||
RewardDorm(self.config, self.device).dorm_run(
|
||||
feed=False, collect=False, buy_furniture=False, buy_food=10)
|
||||
self.ui_ensure(page_reward)
|
||||
continue
|
||||
raise OilMaxed
|
||||
# Check GET_SHIP at last to handle random white background at page_main
|
||||
for button in [GET_SHIP]:
|
||||
if click_timer.reached() and self.appear(button, interval=1):
|
||||
@@ -581,6 +577,27 @@ class RewardCommission(UI, InfoHandler):
|
||||
|
||||
return reward
|
||||
|
||||
def commission_receive(self):
|
||||
"""
|
||||
Returns:
|
||||
bool: If rewarded.
|
||||
|
||||
Pages:
|
||||
in: page_reward
|
||||
out: page_commission
|
||||
"""
|
||||
for _ in range(3):
|
||||
try:
|
||||
reward = self._commission_receive()
|
||||
return reward
|
||||
except OilMaxed:
|
||||
logger.info("Oil maxed, buy food to consume oil")
|
||||
RewardDorm(self.config, self.device).dorm_food_run(amount=10)
|
||||
self.ui_ensure(page_reward)
|
||||
|
||||
logger.critical(f'Failed to handle oil maxed after 3 trial')
|
||||
raise RequestHumanTakeover
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Pages:
|
||||
|
||||
@@ -1995,6 +1995,7 @@
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20201126_cn",
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_bold": [
|
||||
@@ -2423,6 +2424,7 @@
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20201126_cn",
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_bold": [
|
||||
@@ -2845,6 +2847,7 @@
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20201126_cn",
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_bold": [
|
||||
@@ -4670,6 +4673,7 @@
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20201126_cn",
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_bold": [
|
||||
@@ -5110,6 +5114,7 @@
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20201126_cn",
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_bold": [
|
||||
@@ -5550,6 +5555,7 @@
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20201126_cn",
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_bold": [
|
||||
@@ -5990,6 +5996,7 @@
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20201126_cn",
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_bold": [
|
||||
@@ -6420,6 +6427,7 @@
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_tw": [
|
||||
"event_20201126_cn",
|
||||
"event_20260417_cn"
|
||||
],
|
||||
"option_bold": [
|
||||
|
||||
@@ -742,7 +742,7 @@
|
||||
"event_20201002_en": "Counterattack Within the Fjord",
|
||||
"event_20201012_cn": "復刻劃破海空之翼",
|
||||
"event_20201029_cn": "激唱的UNIVERSE",
|
||||
"event_20201126_cn": "假日航線",
|
||||
"event_20201126_cn": "復刻假日航線",
|
||||
"event_20201229_cn": "復刻-負象限作戰",
|
||||
"event_20210121_cn": "復刻神聖的悲喜劇",
|
||||
"event_20210225_cn": "復刻破曉冰華",
|
||||
|
||||
@@ -481,13 +481,35 @@ class RewardDorm(UI):
|
||||
if self.appear_then_click(DORM_BUY_FOOD_CONFIRM, offset=(20, 20), interval=5):
|
||||
continue
|
||||
|
||||
def dorm_run(self, feed=True, collect=True, buy_furniture=False, buy_food=0):
|
||||
def dorm_food_run(self, amount):
|
||||
"""
|
||||
Args:
|
||||
amount (int): amount of food to buy
|
||||
|
||||
Pages:
|
||||
in: Any page
|
||||
out: page_dorm
|
||||
"""
|
||||
if amount <= 0:
|
||||
return
|
||||
|
||||
self.ui_ensure(page_dormmenu)
|
||||
self.handle_info_bar()
|
||||
self.ui_goto(page_dorm, skip_first_screenshot=True)
|
||||
logger.hr('Dorm buy food', level=1)
|
||||
self.dorm_feed_enter()
|
||||
self.dorm_buy_food_enter()
|
||||
self.dorm_buy_food(amount=amount)
|
||||
self.dorm_buy_food_confirm()
|
||||
self.dorm_feed_quit()
|
||||
|
||||
def dorm_run(self, feed=True, collect=True, buy_furniture=False):
|
||||
"""
|
||||
Pages:
|
||||
in: Any page
|
||||
out: page_dorm
|
||||
"""
|
||||
if not feed and not collect and not buy_furniture and buy_food <= 0:
|
||||
if not feed and not collect and not buy_furniture:
|
||||
return
|
||||
|
||||
self.ui_ensure(page_dormmenu)
|
||||
@@ -516,19 +538,8 @@ class RewardDorm(UI):
|
||||
logger.hr('Dorm buy furniture', level=1)
|
||||
BuyFurniture(self.config, self.device).run()
|
||||
|
||||
if buy_food > 0:
|
||||
logger.hr('Dorm buy food', level=1)
|
||||
self.dorm_feed_enter()
|
||||
self.dorm_buy_food_enter()
|
||||
self.dorm_buy_food(amount=buy_food)
|
||||
self.dorm_buy_food_confirm()
|
||||
self.dorm_feed_quit()
|
||||
|
||||
def get_dorm_ship_amount(self):
|
||||
"""
|
||||
Args:
|
||||
skip_first_screenshot:
|
||||
|
||||
Returns:
|
||||
int: Number of ships in dorm
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ class OilExhausted(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class OilMaxed(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class MapDetectionError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
@@ -337,8 +337,8 @@ class InfoHandler(ModuleBase):
|
||||
list[Button]: List of story options, from upper to bottom. If no option found, return an empty list.
|
||||
"""
|
||||
# Area to detect the options, should include at least 3 options.
|
||||
story_option_area = (315, 130, 965, 555)
|
||||
story_detect_area = (330, 130, 355, 555)
|
||||
story_option_area = (330, 135, 980, 555)
|
||||
story_detect_area = (330, 135, 355, 555)
|
||||
story_option_color = (247, 247, 247)
|
||||
|
||||
image = color_similarity_2d(self.image_crop(story_detect_area, copy=False), color=story_option_color)
|
||||
|
||||
Reference in New Issue
Block a user