Merge branch 'dev' into mail_reward
1
.github/workflows/gitee-mirror.yml
vendored
@ -21,5 +21,6 @@ jobs:
|
||||
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
|
||||
dst_token: ${{ secrets.GITEE_TOKEN }}
|
||||
static_list: 'AzurLaneAutoScript'
|
||||
mappings: "AzurLaneAutoScript=>azur-lane-auto-script-mirror"
|
||||
force_update: true
|
||||
timeout: '30m'
|
||||
|
@ -21,7 +21,8 @@ GUI development, thanks **[@18870](https://github.com/18870)** , say HURRAY.
|
||||
|
||||
![](https://img.shields.io/github/commit-activity/m/LmeSzinc/AzurLaneAutoScript?color=4e4c97) ![](https://img.shields.io/tokei/lines/github/LmeSzinc/AzurLaneAutoScript?color=4e4c97) ![](https://img.shields.io/github/repo-size/LmeSzinc/AzurLaneAutoScript?color=4e4c97) ![](https://img.shields.io/github/issues-closed/LmeSzinc/AzurLaneAutoScript?color=4e4c97) ![](https://img.shields.io/github/issues-pr-closed/LmeSzinc/AzurLaneAutoScript?color=4e4c97)
|
||||
|
||||
![gui](doc/README.assets/gui.png)
|
||||
这里是一张GUI预览图:
|
||||
![gui](https://raw.githubusercontent.com/LmeSzinc/AzurLaneAutoScript/master/doc/README.assets/gui.png)
|
||||
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ GUI development, thanks **[@18870](https://github.com/18870)** , say HURRAY.
|
||||
|
||||
![](https://img.shields.io/github/commit-activity/m/LmeSzinc/AzurLaneAutoScript?color=4e4c97) ![](https://img.shields.io/tokei/lines/github/LmeSzinc/AzurLaneAutoScript?color=4e4c97) ![](https://img.shields.io/github/repo-size/LmeSzinc/AzurLaneAutoScript?color=4e4c97) ![](https://img.shields.io/github/issues-closed/LmeSzinc/AzurLaneAutoScript?color=4e4c97) ![](https://img.shields.io/github/issues-pr-closed/LmeSzinc/AzurLaneAutoScript?color=4e4c97)
|
||||
|
||||
![gui](doc/README.assets/gui_en.png)
|
||||
![gui](https://raw.githubusercontent.com/LmeSzinc/AzurLaneAutoScript/master/doc/README.assets/gui_en.png)
|
||||
|
||||
|
||||
|
||||
|
5
alas.py
@ -224,10 +224,7 @@ class AzurLaneAutoScript:
|
||||
Freebies(config=self.config, device=self.device).run()
|
||||
|
||||
def daily(self):
|
||||
if self.config.SERVER == 'tw':
|
||||
from module.daily.daily_tw import Daily
|
||||
else:
|
||||
from module.daily.daily import Daily
|
||||
from module.daily.daily import Daily
|
||||
Daily(config=self.config, device=self.device).run()
|
||||
|
||||
def hard(self):
|
||||
|
BIN
assets/cn/template/TEMPLATE_SIREN_SheffieldIdol.png
Normal file
After Width: | Height: | Size: 645 B |
BIN
assets/cn/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
assets/cn/war_archives/TEMPLATE_UNIVERSE_IN_UNISON.png
Normal file
After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 8.7 KiB |
BIN
assets/jp/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
assets/jp/war_archives/TEMPLATE_UNIVERSE_IN_UNISON.png
Normal file
After Width: | Height: | Size: 31 KiB |
@ -23,10 +23,12 @@ To add a new event, add a new row in here, and run `python -m dev_tools.event_ex
|
||||
| 20180726 | war archives 20180726 cn | Iris of Light and Dark | 光与影的鸢尾之华 | Iris of Light and Dark | 光と影のアイリス | 光與影的鳶尾之華 |
|
||||
| 20210121 | war archives 20181227 cn | Crimson Echoes | 苍红的回响 | Crimson Echoes | 縹映る深緋の残響 | 蒼紅的迴響 |
|
||||
| 20210513 | war archives 20200820 cn | Scherzo of Iron and Blood | 铁血音符誓言 | Scherzo of Iron and Blood | 黒鉄の楽章 誓いの海 | - |
|
||||
| 20211014 | war archives 20211014 cn | Crescendo of Polaris | 激奏的Polaris | Crescendo of Polaris | 激奏のポラリス | - |
|
||||
| 20220113 | war archives 20190911 cn | Empyreal Tragicomedy | 神圣的悲喜剧 | Empyreal Tragicomedy | 悲歎せし焔海の詩 | - |
|
||||
| 20220407 | war archives 20210325 cn | Ashen Simulacrum | 箱庭疗法 | Ashen Simulacrum | 開かれし紺碧の砂箱 | - |
|
||||
| 20220721 | war archives 20210624 cn | Swirling Cherry Blossoms | 浮樱影华 | Swirling Cherry Blossoms | 翳りし満ちる影の華 | - |
|
||||
| 20220721 | war archives 20200806 cn | The Enigma and the Shark | 最重要的宝物 | The Enigma and the Shark | 鉄血鮫とエニグマ | - |
|
||||
| 20220901 | war archives 20200806 cn | The Enigma and the Shark | 最重要的宝物 | The Enigma and the Shark | 鉄血鮫とエニグマ | - |
|
||||
| 20221013 | war archives 20201029 cn | Universe in Unison | 激唱的UNIVERSE | Universe in Unison | 激唱のユニバース | - |
|
||||
| 20200227 | event 20200227 cn | Northern Overture | 北境序曲 | Northern Overture | 凍絶の北海 | - |
|
||||
| 20200312 | event 20200312 cn | The Solomon Ranger | 复刻斯图尔特的硝烟 | The Solomon Ranger Rerun | 南洋に靡く硝煙(復刻) | - |
|
||||
| 20200326 | event 20200326 cn | Microlayer Medley | 微层混合 | Microlayer Medley | 闇靄払う銀翼 | - |
|
||||
@ -110,4 +112,5 @@ To add a new event, add a new row in here, and run `python -m dev_tools.event_ex
|
||||
| 20220818 | event 20220818 cn | Operation Convergence | 远汇点作战 | Operation Convergence | 結像点作戦 | - |
|
||||
| 20220901 | event 20200903 en | Stars of the Shimmering Fjord | - | - | - | 復刻峽灣間的星辰 |
|
||||
| 20220915 | event 20210916 cn | Upon the Shimmering Blue | - | - | - | 碧海光粼 |
|
||||
| 20220915 | event 20220915 cn | Violet Tempest Blooming Lycoris | 紫绛槿岚 | Violet Tempest Blooming Lycoris | 赫の涙月 菫の暁風 | - |
|
||||
| 20220915 | event 20220915 cn | Violet Tempest Blooming Lycoris | 紫绛槿岚 | Violet Tempest Blooming Lycoris | 赫の涙月 菫の暁風 | - |
|
||||
| 20221021 | event 20210121 cn | Empyreal Tragicomedy | - | - | - | 復刻神聖的悲喜劇 |
|
10
campaign/war_archives_20201029_cn/campaign_base.py
Normal file
@ -0,0 +1,10 @@
|
||||
from ..campaign_war_archives.campaign_base import CampaignBase as CampaignBase_
|
||||
from module.exception import CampaignNameError
|
||||
from module.logger import logger
|
||||
|
||||
|
||||
class CampaignBase(CampaignBase_):
|
||||
|
||||
STAGE_INCREASE = [
|
||||
'SP1 > SP2 > SP3 > SP4 > SP5',
|
||||
]
|
89
campaign/war_archives_20201029_cn/sp1.py
Normal file
@ -0,0 +1,89 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
|
||||
MAP = CampaignMap('SP1')
|
||||
MAP.shape = 'G7'
|
||||
MAP.camera_data = ['C2', 'C5']
|
||||
MAP.camera_data_spawn_point = ['C5']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_data = """
|
||||
++ ++ -- ME -- ++ ++
|
||||
++ ++ ME __ ME -- ++
|
||||
ME -- MS -- MS -- ME
|
||||
-- Me -- ++ -- -- Me
|
||||
ME -- -- -- -- -- ++
|
||||
++ -- SP MB SP -- ++
|
||||
++ ME -- -- -- ME --
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 2, 'siren': 1},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config:
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['LeMalinIdol', 'DidoIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = True
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
DETECTION_BACKEND = 'perspective'
|
||||
INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40
|
||||
EDGE_LINES_HOUGHLINES_THRESHOLD = 40
|
||||
INTERNAL_LINES_FIND_PEAKS_PARAMETERS = {
|
||||
'height': (150, 255 - 12),
|
||||
'width': (0.9, 10),
|
||||
'prominence': 10,
|
||||
'distance': 35,
|
||||
}
|
||||
EDGE_LINES_FIND_PEAKS_PARAMETERS = {
|
||||
'height': (255 - 9, 255),
|
||||
'prominence': 10,
|
||||
'distance': 50,
|
||||
# 'width': (0, 7),
|
||||
'wlen': 1000
|
||||
}
|
||||
HOMO_EDGE_COLOR_RANGE = (0, 9)
|
||||
HOMO_EDGE_HOUGHLINES_THRESHOLD = 180
|
||||
MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom'
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_4(self):
|
||||
return self.clear_boss()
|
74
campaign/war_archives_20201029_cn/sp2.py
Normal file
@ -0,0 +1,74 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
from .sp1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('SP2')
|
||||
MAP.shape = 'I7'
|
||||
MAP.camera_data = ['C2', 'C5', 'F2', 'F5']
|
||||
MAP.camera_data_spawn_point = ['C2']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_covered = ['E3']
|
||||
MAP.map_data = """
|
||||
-- SP -- SP ++ ++ ++ ME --
|
||||
-- -- __ -- -- MS ME -- MB
|
||||
Me -- -- ME -- -- -- -- --
|
||||
-- ++ -- -- ++ -- ++ ++ ME
|
||||
ME -- MS -- -- -- ++ ++ --
|
||||
-- ME -- -- Me -- -- -- ME
|
||||
++ ++ ++ ME -- ME ME -- --
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'siren': 1},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config(ConfigBase):
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['LeMalinIdol', 'DidoIdol', 'AlbacoreIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = True
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
MAP_SWIPE_MULTIPLY = 1.847
|
||||
MAP_SWIPE_MULTIPLY_MINITOUCH = 1.786
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_4(self):
|
||||
return self.clear_boss()
|
75
campaign/war_archives_20201029_cn/sp3.py
Normal file
@ -0,0 +1,75 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
from .sp1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('SP3')
|
||||
MAP.shape = 'I7'
|
||||
MAP.camera_data = ['C2', 'C5', 'F2', 'F5']
|
||||
MAP.camera_data_spawn_point = ['D2', 'D5']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_covered = ['E3']
|
||||
MAP.map_data = """
|
||||
++ ++ ++ -- -- -- ME ++ ++
|
||||
SP -- -- -- Me -- -- ME ++
|
||||
-- -- -- MS -- MS -- -- ME
|
||||
SP -- Me -- ++ -- Me __ MB
|
||||
-- -- -- MS -- MS -- -- ME
|
||||
ME ME ++ -- ME -- -- ME ++
|
||||
-- -- ++ -- MB -- ME ++ ++
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'siren': 2},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4},
|
||||
{'battle': 5, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config(ConfigBase):
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['DidoIdol', 'BaltimoreIdol', 'AlbacoreIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = True
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
MAP_SWIPE_MULTIPLY = 1.847
|
||||
MAP_SWIPE_MULTIPLY_MINITOUCH = 1.786
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_5(self):
|
||||
return self.fleet_boss.clear_boss()
|
75
campaign/war_archives_20201029_cn/sp4.py
Normal file
@ -0,0 +1,75 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
from .sp1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('SP4')
|
||||
MAP.shape = 'I7'
|
||||
MAP.camera_data = ['C2', 'C5', 'F2', 'F5']
|
||||
MAP.camera_data_spawn_point = ['D2']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_covered = ['E3']
|
||||
MAP.map_data = """
|
||||
++ -- SP -- ++ MS ++ ++ --
|
||||
++ SP -- ME -- -- Me ++ --
|
||||
-- -- -- __ MS -- -- ME ME
|
||||
-- ME -- MS ++ MB ME -- --
|
||||
MS ++ -- -- MB -- -- -- Me
|
||||
++ ME -- Me ME Me -- ++ --
|
||||
-- -- ME ++ ++ ++ ME ++ --
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'siren': 2},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'enemy': 1},
|
||||
{'battle': 5, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config(ConfigBase):
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['ClevelandIdol', 'HipperIdol', 'SpeeIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = True
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
MAP_SWIPE_MULTIPLY = 1.847
|
||||
MAP_SWIPE_MULTIPLY_MINITOUCH = 1.786
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_5(self):
|
||||
return self.fleet_boss.clear_boss()
|
102
campaign/war_archives_20201029_cn/sp5.py
Normal file
@ -0,0 +1,102 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
from .sp1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('SP5')
|
||||
MAP.shape = 'I10'
|
||||
MAP.camera_data = ['D3', 'D6', 'E6']
|
||||
MAP.camera_data_spawn_point = ['D7']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_data = """
|
||||
-- ++ ME -- -- -- ME ++ --
|
||||
-- ++ ME -- MB -- ME ++ --
|
||||
++ Me -- -- -- -- -- Me ++
|
||||
++ ++ ++ Me __ Me ++ ++ ++
|
||||
-- -- MS -- -- -- MS -- --
|
||||
-- ++ -- -- Me -- -- ++ --
|
||||
-- -- MS -- Me -- MS -- --
|
||||
++ ME -- -- -- -- -- ME ++
|
||||
-- ++ ++ SP -- SP ++ ++ --
|
||||
-- -- ++ -- -- -- ++ -- --
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'siren': 2},
|
||||
{'battle': 1, 'enemy': 2, 'siren': 1},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'enemy': 1},
|
||||
{'battle': 5},
|
||||
{'battle': 6, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
|
||||
A8, B8, C8, D8, E8, F8, G8, H8, I8, \
|
||||
A9, B9, C9, D9, E9, F9, G9, H9, I9, \
|
||||
A10, B10, C10, D10, E10, F10, G10, H10, I10, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config(ConfigBase):
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['BaltimoreIdol', 'RoonIdol', 'IllustriousIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = True
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
MAP_SWIPE_MULTIPLY = 1.445
|
||||
MAP_SWIPE_MULTIPLY_MINITOUCH = 1.397
|
||||
INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40
|
||||
EDGE_LINES_HOUGHLINES_THRESHOLD = 75
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
if self.clear_enemy(scale=(2,), genre=['light', 'main', 'enemy', 'carrier']):
|
||||
return True
|
||||
if self.clear_enemy(scale=(1,)):
|
||||
return True
|
||||
if self.clear_enemy(genre=['light', 'main', 'enemy']):
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_5(self):
|
||||
if self.clear_enemy(scale=(1,)):
|
||||
return True
|
||||
if self.clear_enemy(scale=(2,), genre=['light', 'main', 'enemy', 'carrier']):
|
||||
return True
|
||||
if self.clear_enemy(genre=['light', 'main', 'enemy']):
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_6(self):
|
||||
return self.fleet_boss.clear_boss()
|
10
campaign/war_archives_20211014_cn/campaign_base.py
Normal file
@ -0,0 +1,10 @@
|
||||
from ..campaign_war_archives.campaign_base import CampaignBase as CampaignBase_
|
||||
from module.exception import CampaignNameError
|
||||
from module.logger import logger
|
||||
|
||||
|
||||
class CampaignBase(CampaignBase_):
|
||||
|
||||
STAGE_INCREASE = [
|
||||
'SP1 > SP2 > SP3 > SP4 > SP5',
|
||||
]
|
89
campaign/war_archives_20211014_cn/sp1.py
Normal file
@ -0,0 +1,89 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
|
||||
MAP = CampaignMap('SP1')
|
||||
MAP.shape = 'G7'
|
||||
MAP.camera_data = ['A3', 'A5']
|
||||
MAP.camera_data_spawn_point = ['A3']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_data = """
|
||||
++ ++ ++ -- MS ME --
|
||||
-- ME -- ME -- ME --
|
||||
SP -- ME -- __ ME ++
|
||||
-- ME -- ++ -- -- MB
|
||||
SP -- -- -- -- ME --
|
||||
++ ++ -- -- ME -- ME
|
||||
++ ++ ME -- -- -- --
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 2, 'siren': 1},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config:
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['SheffieldIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = False
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
DETECTION_BACKEND = 'perspective'
|
||||
INTERNAL_LINES_HOUGHLINES_THRESHOLD = 40
|
||||
EDGE_LINES_HOUGHLINES_THRESHOLD = 40
|
||||
INTERNAL_LINES_FIND_PEAKS_PARAMETERS = {
|
||||
'height': (150, 255 - 12),
|
||||
'width': (0.9, 10),
|
||||
'prominence': 10,
|
||||
'distance': 35,
|
||||
}
|
||||
EDGE_LINES_FIND_PEAKS_PARAMETERS = {
|
||||
'height': (255 - 9, 255),
|
||||
'prominence': 10,
|
||||
'distance': 50,
|
||||
# 'width': (0, 7),
|
||||
'wlen': 1000
|
||||
}
|
||||
HOMO_EDGE_COLOR_RANGE = (0, 9)
|
||||
HOMO_EDGE_HOUGHLINES_THRESHOLD = 180
|
||||
MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom'
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_4(self):
|
||||
return self.clear_boss()
|
74
campaign/war_archives_20211014_cn/sp2.py
Normal file
@ -0,0 +1,74 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
from .sp1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('SP2')
|
||||
MAP.shape = 'I7'
|
||||
MAP.camera_data = ['C2', 'C5', 'F2', 'F5']
|
||||
MAP.camera_data_spawn_point = ['A5']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_covered = ['E3']
|
||||
MAP.map_data = """
|
||||
-- -- -- -- -- -- ME -- --
|
||||
-- ME -- ME -- ME -- ME --
|
||||
-- -- ME -- -- -- ++ ++ --
|
||||
SP -- -- -- ++ __ -- -- MB
|
||||
SP -- ME -- -- ME ME -- --
|
||||
-- ++ -- ME ++ ME -- ++ ++
|
||||
-- ME ME -- ME -- ME ++ ++
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'siren': 1},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config(ConfigBase):
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['HipperIdol', 'ClevelandIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = False
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
MAP_SWIPE_MULTIPLY = 1.847
|
||||
MAP_SWIPE_MULTIPLY_MINITOUCH = 1.786
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_4(self):
|
||||
return self.clear_boss()
|
75
campaign/war_archives_20211014_cn/sp3.py
Normal file
@ -0,0 +1,75 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
from .sp1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('SP3')
|
||||
MAP.shape = 'I7'
|
||||
MAP.camera_data = ['C2', 'C5', 'F2', 'F5']
|
||||
MAP.camera_data_spawn_point = ['I4']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_covered = ['E3']
|
||||
MAP.map_data = """
|
||||
-- ME ++ ++ ++ ME -- -- --
|
||||
-- MS -- MB MS -- -- ME ++
|
||||
++ -- ME -- -- ME ME -- --
|
||||
-- ME -- -- ++ __ -- ++ ++
|
||||
ME ME ME -- -- ME -- ME ME
|
||||
-- ME ++ ++ ME -- ME ME --
|
||||
ME -- ++ ++ SP SP -- -- --
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'siren': 2},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4},
|
||||
{'battle': 5, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config(ConfigBase):
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['HipperIdol', 'ClevelandIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = False
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
MAP_SWIPE_MULTIPLY = 1.847
|
||||
MAP_SWIPE_MULTIPLY_MINITOUCH = 1.786
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_5(self):
|
||||
return self.fleet_boss.clear_boss()
|
75
campaign/war_archives_20211014_cn/sp4.py
Normal file
@ -0,0 +1,75 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
from .sp1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('SP4')
|
||||
MAP.shape = 'I7'
|
||||
MAP.camera_data = ['C2', 'C5', 'F2', 'F5']
|
||||
MAP.camera_data_spawn_point = ['C5']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_covered = ['E3']
|
||||
MAP.map_data = """
|
||||
-- ++ ++ -- -- -- ME -- ++
|
||||
ME ME -- MS -- -- -- MS ++
|
||||
-- -- ME -- -- -- -- ME --
|
||||
SP -- -- -- ++ -- -- -- MB
|
||||
SP -- ME -- __ ME ME -- --
|
||||
-- ++ -- ME -- -- -- ++ ++
|
||||
-- ME ME -- ME -- ME ++ ++
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'siren': 2},
|
||||
{'battle': 1, 'enemy': 2},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'enemy': 1},
|
||||
{'battle': 5, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config(ConfigBase):
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['ClevelandIdol', 'HipperIdol', 'SpeeIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = False
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
MAP_SWIPE_MULTIPLY = 1.847
|
||||
MAP_SWIPE_MULTIPLY_MINITOUCH = 1.786
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_5(self):
|
||||
return self.fleet_boss.clear_boss()
|
76
campaign/war_archives_20211014_cn/sp5.py
Normal file
@ -0,0 +1,76 @@
|
||||
from module.logger import logger
|
||||
from module.map.map_base import CampaignMap
|
||||
from module.map.map_grids import RoadGrids, SelectedGrids
|
||||
|
||||
from .campaign_base import CampaignBase
|
||||
from .sp1 import Config as ConfigBase
|
||||
|
||||
MAP = CampaignMap('SP5')
|
||||
MAP.shape = 'I7'
|
||||
MAP.camera_data = ['C2', 'C5', 'F2', 'F5']
|
||||
MAP.camera_data_spawn_point = ['C4']
|
||||
MAP.camera_sight = (-2, -1, 3, 2)
|
||||
MAP.map_covered = ['E3']
|
||||
MAP.map_data = """
|
||||
-- -- -- ++ ++ ++ ME -- --
|
||||
-- ME -- MB ME -- -- ++ ++
|
||||
ME ME ME -- -- ME ME ME --
|
||||
ME -- -- -- ++ __ -- -- --
|
||||
ME ME -- ME -- ME -- ++ ++
|
||||
-- ME -- ME -- -- -- ++ ++
|
||||
ME -- -- SP SP -- ME ME --
|
||||
"""
|
||||
MAP.weight_data = """
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
50 50 50 50 50 50 50 50 50
|
||||
"""
|
||||
MAP.spawn_data = [
|
||||
{'battle': 0, 'enemy': 3, 'siren': 2},
|
||||
{'battle': 1, 'enemy': 2, 'siren': 1},
|
||||
{'battle': 2, 'enemy': 1},
|
||||
{'battle': 3, 'enemy': 1},
|
||||
{'battle': 4, 'enemy': 1},
|
||||
{'battle': 5},
|
||||
{'battle': 6, 'boss': 1},
|
||||
]
|
||||
A1, B1, C1, D1, E1, F1, G1, H1, I1, \
|
||||
A2, B2, C2, D2, E2, F2, G2, H2, I2, \
|
||||
A3, B3, C3, D3, E3, F3, G3, H3, I3, \
|
||||
A4, B4, C4, D4, E4, F4, G4, H4, I4, \
|
||||
A5, B5, C5, D5, E5, F5, G5, H5, I5, \
|
||||
A6, B6, C6, D6, E6, F6, G6, H6, I6, \
|
||||
A7, B7, C7, D7, E7, F7, G7, H7, I7, \
|
||||
= MAP.flatten()
|
||||
|
||||
|
||||
class Config(ConfigBase):
|
||||
# ===== Start of generated config =====
|
||||
MAP_SIREN_TEMPLATE = ['ClevelandIdol', 'HipperIdol', 'SpeeIdol']
|
||||
MOVABLE_ENEMY_TURN = (2,)
|
||||
MAP_HAS_SIREN = True
|
||||
MAP_HAS_MOVABLE_ENEMY = True
|
||||
MAP_HAS_MAP_STORY = False
|
||||
MAP_HAS_FLEET_STEP = True
|
||||
MAP_HAS_AMBUSH = False
|
||||
# ===== End of generated config =====
|
||||
|
||||
MAP_SWIPE_MULTIPLY = 1.847
|
||||
MAP_SWIPE_MULTIPLY_MINITOUCH = 1.786
|
||||
|
||||
|
||||
class Campaign(CampaignBase):
|
||||
MAP = MAP
|
||||
|
||||
def battle_0(self):
|
||||
if self.clear_siren():
|
||||
return True
|
||||
|
||||
return self.battle_default()
|
||||
|
||||
def battle_6(self):
|
||||
return self.fleet_boss.clear_boss()
|
@ -1,9 +1,9 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'https://gitee.com/LmeSzinc/AzurLaneAutoScript' for faster and more stable download
|
||||
# [CN user] Use 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror' for faster and more stable download
|
||||
# [Other] Use 'https://github.com/LmeSzinc/AzurLaneAutoScript'
|
||||
Repository: https://gitee.com/LmeSzinc/AzurLaneAutoScript
|
||||
Repository: https://gitee.com/lmeszinc/azur-lane-auto-script-mirror
|
||||
# Branch of Alas
|
||||
# [Developer] Use 'dev', 'app', etc, to try new features
|
||||
# [Other] Use 'master', the stable branch
|
||||
|
@ -1,7 +1,7 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'https://gitee.com/LmeSzinc/AzurLaneAutoScript' for faster and more stable download
|
||||
# [CN user] Use 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror' for faster and more stable download
|
||||
# [Other] Use 'https://github.com/LmeSzinc/AzurLaneAutoScript'
|
||||
Repository: https://github.com/LmeSzinc/AzurLaneAutoScript
|
||||
# Branch of Alas
|
||||
|
@ -1,9 +1,9 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'https://gitee.com/LmeSzinc/AzurLaneAutoScript' for faster and more stable download
|
||||
# [CN user] Use 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror' for faster and more stable download
|
||||
# [Other] Use 'https://github.com/LmeSzinc/AzurLaneAutoScript'
|
||||
Repository: https://gitee.com/LmeSzinc/AzurLaneAutoScript
|
||||
Repository: https://gitee.com/lmeszinc/azur-lane-auto-script-mirror
|
||||
# Branch of Alas
|
||||
# [Developer] Use 'dev', 'app', etc, to try new features
|
||||
# [Other] Use 'master', the stable branch
|
||||
|
@ -1,9 +1,9 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'https://gitee.com/LmeSzinc/AzurLaneAutoScript' for faster and more stable download
|
||||
# [CN user] Use 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror' for faster and more stable download
|
||||
# [Other] Use 'https://github.com/LmeSzinc/AzurLaneAutoScript'
|
||||
Repository: https://gitee.com/LmeSzinc/AzurLaneAutoScript
|
||||
Repository: https://gitee.com/lmeszinc/azur-lane-auto-script-mirror
|
||||
# Branch of Alas
|
||||
# [Developer] Use 'dev', 'app', etc, to try new features
|
||||
# [Other] Use 'master', the stable branch
|
||||
|
@ -1,7 +1,7 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'https://gitee.com/LmeSzinc/AzurLaneAutoScript' for faster and more stable download
|
||||
# [CN user] Use 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror' for faster and more stable download
|
||||
# [Other] Use 'https://github.com/LmeSzinc/AzurLaneAutoScript'
|
||||
Repository: https://github.com/LmeSzinc/AzurLaneAutoScript
|
||||
# Branch of Alas
|
||||
|
@ -1,7 +1,7 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'https://gitee.com/LmeSzinc/AzurLaneAutoScript' for faster and more stable download
|
||||
# [CN user] Use 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror' for faster and more stable download
|
||||
# [Other] Use 'https://github.com/LmeSzinc/AzurLaneAutoScript'
|
||||
Repository: https://github.com/LmeSzinc/AzurLaneAutoScript
|
||||
# Branch of Alas
|
||||
|
@ -1373,7 +1373,7 @@
|
||||
},
|
||||
"Campaign": {
|
||||
"Name": "12-4",
|
||||
"Event": "war_archives_20200806_cn",
|
||||
"Event": "war_archives_20201029_cn",
|
||||
"Mode": "normal",
|
||||
"UseClearMode": true,
|
||||
"UseFleetLock": true,
|
||||
@ -1437,7 +1437,7 @@
|
||||
"OpsiGeneral": {
|
||||
"OpsiGeneral": {
|
||||
"UseLogger": true,
|
||||
"BuyActionPoint": false,
|
||||
"BuyActionPointLimit": 0,
|
||||
"OilLimit": 1000,
|
||||
"RepairThreshold": 0.4,
|
||||
"DoRandomMapEvent": true,
|
||||
|
@ -70,6 +70,8 @@ class DeployConfig(ConfigModel):
|
||||
self.file = file
|
||||
self.config = {}
|
||||
self.read()
|
||||
if self.Repository == 'https://gitee.com/LmeSzinc/AzurLaneAutoScript':
|
||||
self.Repository = 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror'
|
||||
self.write()
|
||||
self.show_config()
|
||||
|
||||
|
@ -118,7 +118,7 @@ class VirtualBoxEmulator:
|
||||
|
||||
serial = []
|
||||
for file in vbox:
|
||||
with open(file, 'r') as f:
|
||||
with open(file, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
for line in f.readlines():
|
||||
# <Forwarding name="port2" proto="1" hostip="127.0.0.1" hostport="62026" guestport="5555"/>
|
||||
res = re.search('<*?hostport="(.*?)".*?guestport="5555"/>', line)
|
||||
|
@ -10,12 +10,20 @@ class GitManager(DeployConfig):
|
||||
def git(self):
|
||||
return self.filepath('GitExecutable')
|
||||
|
||||
@staticmethod
|
||||
def remove(file):
|
||||
try:
|
||||
os.remove(file)
|
||||
logger.info(f'Removed file: {file}')
|
||||
except FileNotFoundError:
|
||||
logger.info(f'File not found: {file}')
|
||||
|
||||
def git_repository_init(self, repo, source='origin', branch='master', proxy='', keep_changes=False):
|
||||
logger.hr('Git Init', 1)
|
||||
if not self.execute(f'"{self.git}" init', allow_failure=True):
|
||||
os.remove('./.git/config')
|
||||
os.remove('./.git/index')
|
||||
os.remove('./.git/HEAD')
|
||||
self.remove('./.git/config')
|
||||
self.remove('./.git/index')
|
||||
self.remove('./.git/HEAD')
|
||||
self.execute(f'"{self.git}" init')
|
||||
|
||||
logger.hr('Set Git Proxy', 1)
|
||||
|
@ -169,7 +169,7 @@ class Emulator:
|
||||
str: serial such as `127.0.0.1:5555`
|
||||
"""
|
||||
regex = re.compile('<*?hostport="(.*?)".*?guestport="5555"/>')
|
||||
with open(file, 'r') as f:
|
||||
with open(file, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
for line in f.readlines():
|
||||
# <Forwarding name="port2" proto="1" hostip="127.0.0.1" hostport="62026" guestport="5555"/>
|
||||
res = regex.search(line)
|
||||
|
@ -1,7 +1,7 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'https://gitee.com/LmeSzinc/AzurLaneAutoScript' for faster and more stable download
|
||||
# [CN user] Use 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror' for faster and more stable download
|
||||
# [Other] Use 'https://github.com/LmeSzinc/AzurLaneAutoScript'
|
||||
Repository: 'https://github.com/LmeSzinc/AzurLaneAutoScript'
|
||||
# Branch of Alas
|
||||
|
@ -7,10 +7,12 @@ from module.equipment.fleet_equipment import OCR_FLEET_INDEX
|
||||
from module.exception import CampaignEnd
|
||||
from module.logger import logger
|
||||
from module.map.assets import FLEET_PREPARATION, MAP_PREPARATION
|
||||
from module.combat.assets import BATTLE_PREPARATION
|
||||
from module.ocr.ocr import Digit
|
||||
from module.retire.assets import DOCK_CHECK, TEMPLATE_BOGUE, TEMPLATE_HERMES, TEMPLATE_LANGLEY, TEMPLATE_RANGER
|
||||
from module.retire.dock import Dock, CARD_GRIDS, CARD_EMOTION_GRIDS, CARD_LEVEL_GRIDS
|
||||
from module.ui.page import page_fleet
|
||||
from module.ui.ui import BACK_ARROW
|
||||
|
||||
SIM_VALUE = 0.95
|
||||
|
||||
@ -34,6 +36,9 @@ class GemsCampaignOverride(CampaignBase):
|
||||
|
||||
if self.handle_popup_cancel('IGNORE_LOW_EMOTION'):
|
||||
continue
|
||||
|
||||
if self.appear(BATTLE_PREPARATION, offset=(20, 20), interval=2):
|
||||
self.device.click(BACK_ARROW)
|
||||
|
||||
if self.is_in_map():
|
||||
self.withdraw()
|
||||
@ -340,7 +345,7 @@ class GemsFarming(CampaignRun, Dock, EquipmentChange):
|
||||
if self._trigger_lv32 or self._trigger_emotion:
|
||||
self.flagship_change()
|
||||
|
||||
if self.config.GemsFarming_LowEmotionRetreat:
|
||||
if self.config.GemsFarming_LowEmotionRetreat and self.config.GemsFarming_VanguardChange:
|
||||
self.vanguard_change()
|
||||
|
||||
if is_limit and self.config.StopCondition_RunCount <= 0:
|
||||
|
@ -1516,6 +1516,7 @@
|
||||
"value": "campaign_main",
|
||||
"option": [
|
||||
"campaign_main",
|
||||
"event_20210121_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20210916_cn",
|
||||
"event_20200903_en",
|
||||
@ -1555,7 +1556,6 @@
|
||||
"event_20210415_tw",
|
||||
"event_20210325_cn",
|
||||
"event_20210225_tw",
|
||||
"event_20210121_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20200312_cn",
|
||||
"event_20201002_en",
|
||||
@ -1569,10 +1569,10 @@
|
||||
"event_20200326_cn",
|
||||
"event_20200227_cn"
|
||||
],
|
||||
"tw": "event_20210121_cn",
|
||||
"cn": "event_20220915_cn",
|
||||
"en": "event_20220915_cn",
|
||||
"jp": "event_20220915_cn",
|
||||
"tw": "event_20210916_cn"
|
||||
"jp": "event_20220915_cn"
|
||||
},
|
||||
"Mode": {
|
||||
"type": "select",
|
||||
@ -1936,6 +1936,7 @@
|
||||
"type": "select",
|
||||
"value": "campaign_main",
|
||||
"option": [
|
||||
"event_20210121_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20210916_cn",
|
||||
"event_20200903_en",
|
||||
@ -1975,7 +1976,6 @@
|
||||
"event_20210415_tw",
|
||||
"event_20210325_cn",
|
||||
"event_20210225_tw",
|
||||
"event_20210121_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20200312_cn",
|
||||
"event_20201002_en",
|
||||
@ -1990,10 +1990,10 @@
|
||||
"event_20200227_cn"
|
||||
],
|
||||
"display": "disabled",
|
||||
"tw": "event_20210121_cn",
|
||||
"cn": "event_20220915_cn",
|
||||
"en": "event_20220915_cn",
|
||||
"jp": "event_20220915_cn",
|
||||
"tw": "event_20210916_cn"
|
||||
"jp": "event_20220915_cn"
|
||||
},
|
||||
"Mode": {
|
||||
"type": "select",
|
||||
@ -2356,6 +2356,7 @@
|
||||
"type": "select",
|
||||
"value": "campaign_main",
|
||||
"option": [
|
||||
"event_20210121_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20210916_cn",
|
||||
"event_20200903_en",
|
||||
@ -2395,7 +2396,6 @@
|
||||
"event_20210415_tw",
|
||||
"event_20210325_cn",
|
||||
"event_20210225_tw",
|
||||
"event_20210121_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20200312_cn",
|
||||
"event_20201002_en",
|
||||
@ -2410,10 +2410,10 @@
|
||||
"event_20200227_cn"
|
||||
],
|
||||
"display": "disabled",
|
||||
"tw": "event_20210121_cn",
|
||||
"cn": "event_20220915_cn",
|
||||
"en": "event_20220915_cn",
|
||||
"jp": "event_20220915_cn",
|
||||
"tw": "event_20210916_cn"
|
||||
"jp": "event_20220915_cn"
|
||||
},
|
||||
"Mode": {
|
||||
"type": "select",
|
||||
@ -2787,6 +2787,7 @@
|
||||
"type": "select",
|
||||
"value": "campaign_main",
|
||||
"option": [
|
||||
"event_20210121_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20210916_cn",
|
||||
"event_20200903_en",
|
||||
@ -2826,7 +2827,6 @@
|
||||
"event_20210415_tw",
|
||||
"event_20210325_cn",
|
||||
"event_20210225_tw",
|
||||
"event_20210121_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20200312_cn",
|
||||
"event_20201002_en",
|
||||
@ -2841,10 +2841,10 @@
|
||||
"event_20200227_cn"
|
||||
],
|
||||
"display": "disabled",
|
||||
"tw": "event_20210121_cn",
|
||||
"cn": "event_20220915_cn",
|
||||
"en": "event_20220915_cn",
|
||||
"jp": "event_20220915_cn",
|
||||
"tw": "event_20210916_cn"
|
||||
"jp": "event_20220915_cn"
|
||||
},
|
||||
"Mode": {
|
||||
"type": "select",
|
||||
@ -3224,6 +3224,7 @@
|
||||
"type": "select",
|
||||
"value": "campaign_main",
|
||||
"option": [
|
||||
"event_20210121_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20210916_cn",
|
||||
"event_20200903_en",
|
||||
@ -3263,7 +3264,6 @@
|
||||
"event_20210415_tw",
|
||||
"event_20210325_cn",
|
||||
"event_20210225_tw",
|
||||
"event_20210121_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20200312_cn",
|
||||
"event_20201002_en",
|
||||
@ -3278,10 +3278,10 @@
|
||||
"event_20200227_cn"
|
||||
],
|
||||
"display": "disabled",
|
||||
"tw": "event_20210121_cn",
|
||||
"cn": "event_20220915_cn",
|
||||
"en": "event_20220915_cn",
|
||||
"jp": "event_20220915_cn",
|
||||
"tw": "event_20210916_cn"
|
||||
"jp": "event_20220915_cn"
|
||||
},
|
||||
"Mode": {
|
||||
"type": "select",
|
||||
@ -3661,6 +3661,7 @@
|
||||
"type": "select",
|
||||
"value": "campaign_main",
|
||||
"option": [
|
||||
"event_20210121_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20210916_cn",
|
||||
"event_20200903_en",
|
||||
@ -3700,7 +3701,6 @@
|
||||
"event_20210415_tw",
|
||||
"event_20210325_cn",
|
||||
"event_20210225_tw",
|
||||
"event_20210121_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20200312_cn",
|
||||
"event_20201002_en",
|
||||
@ -3715,10 +3715,10 @@
|
||||
"event_20200227_cn"
|
||||
],
|
||||
"display": "disabled",
|
||||
"tw": "event_20210121_cn",
|
||||
"cn": "event_20220915_cn",
|
||||
"en": "event_20220915_cn",
|
||||
"jp": "event_20220915_cn",
|
||||
"tw": "event_20210916_cn"
|
||||
"jp": "event_20220915_cn"
|
||||
},
|
||||
"Mode": {
|
||||
"type": "select",
|
||||
@ -4098,6 +4098,7 @@
|
||||
"type": "select",
|
||||
"value": "campaign_main",
|
||||
"option": [
|
||||
"event_20210121_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20210916_cn",
|
||||
"event_20200903_en",
|
||||
@ -4137,7 +4138,6 @@
|
||||
"event_20210415_tw",
|
||||
"event_20210325_cn",
|
||||
"event_20210225_tw",
|
||||
"event_20210121_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20200312_cn",
|
||||
"event_20201002_en",
|
||||
@ -4152,10 +4152,10 @@
|
||||
"event_20200227_cn"
|
||||
],
|
||||
"display": "disabled",
|
||||
"tw": "event_20210121_cn",
|
||||
"cn": "event_20220915_cn",
|
||||
"en": "event_20220915_cn",
|
||||
"jp": "event_20220915_cn",
|
||||
"tw": "event_20210916_cn"
|
||||
"jp": "event_20220915_cn"
|
||||
},
|
||||
"Mode": {
|
||||
"type": "select",
|
||||
@ -4525,6 +4525,7 @@
|
||||
"type": "select",
|
||||
"value": "campaign_main",
|
||||
"option": [
|
||||
"event_20210121_cn",
|
||||
"event_20220915_cn",
|
||||
"event_20210916_cn",
|
||||
"event_20200903_en",
|
||||
@ -4564,7 +4565,6 @@
|
||||
"event_20210415_tw",
|
||||
"event_20210325_cn",
|
||||
"event_20210225_tw",
|
||||
"event_20210121_cn",
|
||||
"event_20201126_cn",
|
||||
"event_20200312_cn",
|
||||
"event_20201002_en",
|
||||
@ -4579,10 +4579,10 @@
|
||||
"event_20200227_cn"
|
||||
],
|
||||
"display": "disabled",
|
||||
"tw": "event_20210121_cn",
|
||||
"cn": "event_20220915_cn",
|
||||
"en": "event_20220915_cn",
|
||||
"jp": "event_20220915_cn",
|
||||
"tw": "event_20210916_cn"
|
||||
"jp": "event_20220915_cn"
|
||||
},
|
||||
"Mode": {
|
||||
"type": "select",
|
||||
@ -7045,10 +7045,12 @@
|
||||
"type": "select",
|
||||
"value": "campaign_main",
|
||||
"option": [
|
||||
"war_archives_20201029_cn",
|
||||
"war_archives_20200806_cn",
|
||||
"war_archives_20210624_cn",
|
||||
"war_archives_20210325_cn",
|
||||
"war_archives_20190911_cn",
|
||||
"war_archives_20211014_cn",
|
||||
"war_archives_20200820_cn",
|
||||
"war_archives_20181227_cn",
|
||||
"war_archives_20180726_cn",
|
||||
@ -7061,9 +7063,9 @@
|
||||
"war_archives_20191031_en",
|
||||
"war_archives_20181020_en"
|
||||
],
|
||||
"cn": "war_archives_20200806_cn",
|
||||
"en": "war_archives_20200806_cn",
|
||||
"jp": "war_archives_20200806_cn",
|
||||
"cn": "war_archives_20201029_cn",
|
||||
"en": "war_archives_20201029_cn",
|
||||
"jp": "war_archives_20201029_cn",
|
||||
"tw": "war_archives_20181227_cn"
|
||||
},
|
||||
"Mode": {
|
||||
@ -7392,9 +7394,17 @@
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
},
|
||||
"BuyActionPoint": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
"BuyActionPointLimit": {
|
||||
"type": "select",
|
||||
"value": 0,
|
||||
"option": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5
|
||||
]
|
||||
},
|
||||
"OilLimit": {
|
||||
"type": "input",
|
||||
|
@ -530,7 +530,9 @@ OpsiAshAssist:
|
||||
Tier: 15
|
||||
OpsiGeneral:
|
||||
UseLogger: true
|
||||
BuyActionPoint: false
|
||||
BuyActionPointLimit:
|
||||
value: 0
|
||||
option: [0, 1, 2, 3, 4, 5]
|
||||
OilLimit: 1000
|
||||
RepairThreshold: 0.4
|
||||
DoRandomMapEvent: true
|
||||
|
@ -335,7 +335,7 @@ class GeneratedConfig:
|
||||
|
||||
# Group `OpsiGeneral`
|
||||
OpsiGeneral_UseLogger = True
|
||||
OpsiGeneral_BuyActionPoint = False
|
||||
OpsiGeneral_BuyActionPointLimit = 0 # 0, 1, 2, 3, 4, 5
|
||||
OpsiGeneral_OilLimit = 1000
|
||||
OpsiGeneral_RepairThreshold = 0.4
|
||||
OpsiGeneral_DoRandomMapEvent = True
|
||||
|
@ -7,6 +7,7 @@ from deploy.utils import DEPLOY_TEMPLATE, poor_yaml_read, poor_yaml_write
|
||||
from module.base.timer import timer
|
||||
from module.config.redirect_utils.shop_filter import bp_redirect
|
||||
from module.config.redirect_utils.utils import upload_redirect, api_redirect
|
||||
from module.config.redirect_utils.os_handler import action_point_redirect
|
||||
from module.config.server import to_server, to_package, VALID_PACKAGE, VALID_CHANNEL_PACKAGE, VALID_SERVER_LIST
|
||||
from module.config.utils import *
|
||||
|
||||
@ -390,7 +391,7 @@ class ConfigGenerator:
|
||||
def generate_deploy_template():
|
||||
template = poor_yaml_read(DEPLOY_TEMPLATE)
|
||||
cn = {
|
||||
'Repository': 'https://gitee.com/LmeSzinc/AzurLaneAutoScript',
|
||||
'Repository': 'https://gitee.com/lmeszinc/azur-lane-auto-script-mirror',
|
||||
'PypiMirror': 'https://pypi.tuna.tsinghua.edu.cn/simple',
|
||||
}
|
||||
aidlux = {
|
||||
@ -473,6 +474,7 @@ class ConfigUpdater:
|
||||
('Alas.DropRecord.SaveCombat', 'Alas.DropRecord.CombatRecord', upload_redirect),
|
||||
('Alas.DropRecord.SaveMeowfficer', 'Alas.DropRecord.MeowfficerBuy', upload_redirect),
|
||||
('Alas.Emulator.PackageName', 'Alas.DropRecord.API', api_redirect),
|
||||
('OpsiGeneral.OpsiGeneral.BuyActionPoint', 'OpsiGeneral.OpsiGeneral.BuyActionPointLimit', action_point_redirect),
|
||||
('BattlePass.BattlePass.BattlePassReward', 'Freebies.BattlePass.Collect'),
|
||||
('DataKey.Scheduler.Enable', 'Freebies.DataKey.Collect'),
|
||||
('DataKey.DataKey.ForceGet', 'Freebies.DataKey.ForceCollect'),
|
||||
|
@ -641,10 +641,12 @@
|
||||
"event_20200423_cn": "Crimson Echoes Rerun",
|
||||
"event_20200326_cn": "Microlayer Medley",
|
||||
"event_20200227_cn": "Northern Overture",
|
||||
"war_archives_20201029_cn": "archives Universe in Unison",
|
||||
"war_archives_20200806_cn": "archives The Enigma and the Shark",
|
||||
"war_archives_20210624_cn": "archives Swirling Cherry Blossoms",
|
||||
"war_archives_20210325_cn": "archives Ashen Simulacrum",
|
||||
"war_archives_20190911_cn": "archives Empyreal Tragicomedy",
|
||||
"war_archives_20211014_cn": "archives Crescendo of Polaris",
|
||||
"war_archives_20200820_cn": "archives Scherzo of Iron and Blood",
|
||||
"war_archives_20181227_cn": "archives Crimson Echoes",
|
||||
"war_archives_20180726_cn": "archives Iris of Light and Dark",
|
||||
@ -1929,9 +1931,15 @@
|
||||
"name": "Use Logger(s)",
|
||||
"help": "Use all coordinate loggers when entering the storage"
|
||||
},
|
||||
"BuyActionPoint": {
|
||||
"name": "Buy AP",
|
||||
"help": "Restore AP through oil first then AP boxes"
|
||||
"BuyActionPointLimit": {
|
||||
"name": "Buy AP X time(s)",
|
||||
"help": "Maximum number of buying AP.",
|
||||
"0": "Don't buy",
|
||||
"1": "1 (1000oil, 100AP)",
|
||||
"2": "2 (2000oil, 200AP)",
|
||||
"3": "3 (4000oil, 400AP)",
|
||||
"4": "4 (6000oil, 600AP)",
|
||||
"5": "5 (10000oil, 1000AP)"
|
||||
},
|
||||
"OilLimit": {
|
||||
"name": "Keep Oil Above X",
|
||||
|
@ -641,10 +641,12 @@
|
||||
"event_20200423_cn": "縹映る深緋の残響(復刻)",
|
||||
"event_20200326_cn": "闇靄払う銀翼",
|
||||
"event_20200227_cn": "凍絶の北海",
|
||||
"war_archives_20201029_cn": "檔案 激唱のユニバース",
|
||||
"war_archives_20200806_cn": "檔案 鉄血鮫とエニグマ",
|
||||
"war_archives_20210624_cn": "檔案 翳りし満ちる影の華",
|
||||
"war_archives_20210325_cn": "檔案 開かれし紺碧の砂箱",
|
||||
"war_archives_20190911_cn": "檔案 悲歎せし焔海の詩",
|
||||
"war_archives_20211014_cn": "檔案 激奏のポラリス",
|
||||
"war_archives_20200820_cn": "檔案 黒鉄の楽章 誓いの海",
|
||||
"war_archives_20181227_cn": "檔案 縹映る深緋の残響",
|
||||
"war_archives_20180726_cn": "檔案 光と影のアイリス",
|
||||
@ -1929,9 +1931,15 @@
|
||||
"name": "OpsiGeneral.UseLogger.name",
|
||||
"help": "OpsiGeneral.UseLogger.help"
|
||||
},
|
||||
"BuyActionPoint": {
|
||||
"name": "OpsiGeneral.BuyActionPoint.name",
|
||||
"help": "OpsiGeneral.BuyActionPoint.help"
|
||||
"BuyActionPointLimit": {
|
||||
"name": "Buy AP X time(s)",
|
||||
"help": "Maximum number of buying AP.",
|
||||
"0": "Don't buy",
|
||||
"1": "1 (1000oil, 100AP)",
|
||||
"2": "2 (2000oil, 200AP)",
|
||||
"3": "3 (4000oil, 400AP)",
|
||||
"4": "4 (6000oil, 600AP)",
|
||||
"5": "5 (10000oil, 1000AP)"
|
||||
},
|
||||
"OilLimit": {
|
||||
"name": "OpsiGeneral.OilLimit.name",
|
||||
|
@ -641,10 +641,12 @@
|
||||
"event_20200423_cn": "复刻苍红的回响",
|
||||
"event_20200326_cn": "微层混合",
|
||||
"event_20200227_cn": "北境序曲",
|
||||
"war_archives_20201029_cn": "档案 激唱的UNIVERSE",
|
||||
"war_archives_20200806_cn": "档案 最重要的宝物",
|
||||
"war_archives_20210624_cn": "档案 浮樱影华",
|
||||
"war_archives_20210325_cn": "档案 箱庭疗法",
|
||||
"war_archives_20190911_cn": "档案 神圣的悲喜剧",
|
||||
"war_archives_20211014_cn": "档案 激奏的Polaris",
|
||||
"war_archives_20200820_cn": "档案 铁血音符誓言",
|
||||
"war_archives_20181227_cn": "档案 苍红的回响",
|
||||
"war_archives_20180726_cn": "档案 光与影的鸢尾之华",
|
||||
@ -1929,9 +1931,15 @@
|
||||
"name": "使用坐标记录仪",
|
||||
"help": "每次进入仓库的时候,使用所有的使用坐标记录仪"
|
||||
},
|
||||
"BuyActionPoint": {
|
||||
"name": "买行动力",
|
||||
"help": "用石油买行动力,行动力不足时,优先买行动力,再开箱子"
|
||||
"BuyActionPointLimit": {
|
||||
"name": "买行动力X次",
|
||||
"help": "买行动力的最大次数",
|
||||
"0": "不买",
|
||||
"1": "1次 (1000油, 100行动力)",
|
||||
"2": "2次 (2000油, 200行动力)",
|
||||
"3": "3次 (4000油, 400行动力)",
|
||||
"4": "4次 (6000油, 600行动力)",
|
||||
"5": "5次 (10000油, 1000行动力)"
|
||||
},
|
||||
"OilLimit": {
|
||||
"name": "买行动力时,保留 X 点石油",
|
||||
|
@ -585,6 +585,7 @@
|
||||
"name": "活動名稱",
|
||||
"help": "自動選擇至最新的活動圖",
|
||||
"campaign_main": "主線圖",
|
||||
"event_20210121_cn": "復刻神聖的悲喜劇",
|
||||
"event_20220915_cn": "Violet Tempest Blooming Lycoris",
|
||||
"event_20210916_cn": "碧海光粼",
|
||||
"event_20200903_en": "復刻峽灣間的星辰",
|
||||
@ -628,7 +629,6 @@
|
||||
"event_20210415_tw": "復刻圍剿施佩伯爵",
|
||||
"event_20210325_cn": "Ashen Simulacrum Rerun",
|
||||
"event_20210225_tw": "北境序曲",
|
||||
"event_20210121_cn": "Empyreal Tragicomedy Rerun",
|
||||
"event_20201126_cn": "Vacation Lane",
|
||||
"event_20200312_cn": "斯圖爾特的硝煙",
|
||||
"event_20201002_en": "Counterattack Within the Fjord",
|
||||
@ -641,10 +641,12 @@
|
||||
"event_20200423_cn": "Crimson Echoes Rerun",
|
||||
"event_20200326_cn": "Microlayer Medley",
|
||||
"event_20200227_cn": "Northern Overture",
|
||||
"war_archives_20201029_cn": "archives Universe in Unison",
|
||||
"war_archives_20200806_cn": "archives The Enigma and the Shark",
|
||||
"war_archives_20210624_cn": "archives Swirling Cherry Blossoms",
|
||||
"war_archives_20210325_cn": "archives Ashen Simulacrum",
|
||||
"war_archives_20190911_cn": "archives Empyreal Tragicomedy",
|
||||
"war_archives_20211014_cn": "archives Crescendo of Polaris",
|
||||
"war_archives_20200820_cn": "archives Scherzo of Iron and Blood",
|
||||
"war_archives_20181227_cn": "檔案 蒼紅的迴響",
|
||||
"war_archives_20180726_cn": "檔案 光與影的鳶尾之華",
|
||||
@ -1929,9 +1931,15 @@
|
||||
"name": "使用坐標記錄儀",
|
||||
"help": "每次進入倉庫的時候,使用所有的使用坐標記錄儀"
|
||||
},
|
||||
"BuyActionPoint": {
|
||||
"name": "買行動力",
|
||||
"help": "用石油買行動力,行動力不足時,優先買行動力,再開箱子"
|
||||
"BuyActionPointLimit": {
|
||||
"name": "買行動力X次",
|
||||
"help": "買行動力的最大次數",
|
||||
"0": "不買",
|
||||
"1": "1次 (1000油, 100行動力)",
|
||||
"2": "2次 (2000油, 200行動力)",
|
||||
"3": "3次 (4000油, 400行動力)",
|
||||
"4": "4次 (6000油, 400行動力)",
|
||||
"5": "5次 (10000油, 1000行動力)"
|
||||
},
|
||||
"OilLimit": {
|
||||
"name": "買行動力時,保留 X 點石油",
|
||||
|
13
module/config/redirect_utils/os_handler.py
Normal file
@ -0,0 +1,13 @@
|
||||
def action_point_redirect(value):
|
||||
"""
|
||||
redirect attr about action point
|
||||
|
||||
Args:
|
||||
value (bool):
|
||||
If Enable, return 5.
|
||||
If Disable, return 0.
|
||||
"""
|
||||
if value is True:
|
||||
return 5
|
||||
else:
|
||||
return 0
|
@ -1,279 +0,0 @@
|
||||
import numpy as np
|
||||
|
||||
from module.base.utils import get_color
|
||||
from module.combat.assets import BATTLE_PREPARATION
|
||||
from module.combat.combat import Combat
|
||||
from module.daily.assets import *
|
||||
from module.equipment.fleet_equipment import DailyEquipment
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import Digit
|
||||
from module.ui.assets import DAILY_CHECK
|
||||
from module.ui.ui import (BACK_ARROW, page_campaign_menu,
|
||||
page_daily)
|
||||
|
||||
DAILY_MISSION_LIST = [DAILY_MISSION_1, DAILY_MISSION_2, DAILY_MISSION_3]
|
||||
OCR_REMAIN = Digit(OCR_REMAIN, threshold=128, alphabet='0123')
|
||||
OCR_DAILY_FLEET_INDEX = Digit(OCR_DAILY_FLEET_INDEX, letter=(90, 154, 255), threshold=128, alphabet='123456')
|
||||
|
||||
|
||||
class Daily(Combat, DailyEquipment):
|
||||
daily_current: int
|
||||
daily_checked: list
|
||||
|
||||
def is_active(self):
|
||||
color = get_color(image=self.device.image, area=DAILY_ACTIVE.area)
|
||||
color = np.array(color).astype(float)
|
||||
color = (np.max(color) + np.min(color)) / 2
|
||||
active = color > 30
|
||||
if active:
|
||||
logger.attr(f'Daily_{self.daily_current}', 'active')
|
||||
else:
|
||||
logger.attr(f'Daily_{self.daily_current}', 'inactive')
|
||||
return active
|
||||
|
||||
def _wait_daily_switch(self):
|
||||
self.device.sleep((1, 1.2))
|
||||
|
||||
def next(self):
|
||||
self.daily_current += 1
|
||||
logger.info('Switch to %s' % str(self.daily_current))
|
||||
self.device.click(DAILY_NEXT)
|
||||
self._wait_daily_switch()
|
||||
self.device.screenshot()
|
||||
|
||||
def prev(self):
|
||||
self.daily_current -= 1
|
||||
logger.info('Switch to %s' % str(self.daily_current))
|
||||
self.device.click(DAILY_PREV)
|
||||
self._wait_daily_switch()
|
||||
self.device.screenshot()
|
||||
|
||||
def handle_daily_additional(self):
|
||||
if self.handle_guild_popup_cancel():
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_daily_stage_and_fleet(self):
|
||||
"""
|
||||
Returns:
|
||||
int: Stage index, 0 to 3
|
||||
int: Fleet index, 1 to 6
|
||||
"""
|
||||
# Meaning of daily_current
|
||||
# 1 Tactical Training, 2 Fierce Assault, 3 Supply Line Disruption, 4 Escort Mission, 5 Advance Mission
|
||||
# 1 战术研修, 2 斩首行动, 3 破交作战, 4 商船护送, 5 海域突进
|
||||
fleets = [
|
||||
0,
|
||||
self.config.Daily_TacticalTrainingFleet,
|
||||
self.config.Daily_FierceAssaultFleet,
|
||||
0, # Supply Line Disruption, which needs to be done manually or to be done by daily skip
|
||||
self.config.Daily_EscortMissionFleet,
|
||||
self.config.Daily_AdvanceMissionFleet,
|
||||
0
|
||||
]
|
||||
stages = [
|
||||
0,
|
||||
self.config.Daily_TacticalTraining,
|
||||
self.config.Daily_FierceAssault,
|
||||
self.config.Daily_SupplyLineDisruption,
|
||||
self.config.Daily_EscortMission,
|
||||
self.config.Daily_AdvanceMission,
|
||||
0
|
||||
]
|
||||
dic = {
|
||||
'skip': 0,
|
||||
'first': 1,
|
||||
'second': 2,
|
||||
'third': 3,
|
||||
}
|
||||
fleet = fleets[self.daily_current]
|
||||
stage = stages[self.daily_current]
|
||||
|
||||
if stage not in dic:
|
||||
logger.warning(f'Unknown daily stage `{stage}` from fleet_current_index={self.daily_current}')
|
||||
stage = dic.get(stage, 0)
|
||||
return int(stage), int(fleet)
|
||||
|
||||
def daily_execute(self, remain=3, stage=1, fleet=1):
|
||||
"""
|
||||
Args:
|
||||
remain (int): Remain daily challenge count.
|
||||
stage (int): Index of stage counted from top, 1 to 3.
|
||||
fleet (int): Index of fleet to use.
|
||||
|
||||
Returns:
|
||||
bool: True if success, False if daily locked.
|
||||
|
||||
Pages:
|
||||
in: page_daily
|
||||
out: page_daily
|
||||
"""
|
||||
logger.hr(f'Daily {self.daily_current}')
|
||||
logger.info(f'remain={remain}, stage={stage}, fleet={fleet}')
|
||||
|
||||
def daily_enter_check():
|
||||
return self.appear(DAILY_ENTER_CHECK, threshold=30)
|
||||
|
||||
def daily_end():
|
||||
if self.appear(BATTLE_PREPARATION, interval=2):
|
||||
self.device.click(BACK_ARROW)
|
||||
return self.appear(DAILY_ENTER_CHECK, threshold=30) or self.appear(BACK_ARROW)
|
||||
|
||||
self.ui_click(click_button=DAILY_ENTER, check_button=daily_enter_check, appear_button=DAILY_CHECK,
|
||||
skip_first_screenshot=True)
|
||||
if self.appear(DAILY_LOCKED):
|
||||
logger.info('Daily locked')
|
||||
self.ui_click(click_button=BACK_ARROW, check_button=DAILY_CHECK)
|
||||
self.device.sleep((1, 1.2))
|
||||
return False
|
||||
|
||||
button = DAILY_MISSION_LIST[stage - 1]
|
||||
for n in range(remain):
|
||||
logger.hr(f'Count {n + 1}')
|
||||
result = self.daily_enter(button)
|
||||
if not result:
|
||||
break
|
||||
if self.daily_current == 3:
|
||||
logger.info('Submarine daily skip not unlocked, skip')
|
||||
self.ui_click(click_button=BACK_ARROW, check_button=daily_enter_check, skip_first_screenshot=True)
|
||||
break
|
||||
# Execute classic daily run
|
||||
self.ui_ensure_index(fleet, letter=OCR_DAILY_FLEET_INDEX, prev_button=DAILY_FLEET_PREV,
|
||||
next_button=DAILY_FLEET_NEXT, fast=False, skip_first_screenshot=True)
|
||||
self.combat(emotion_reduce=False, save_get_items=False, expected_end=daily_end, balance_hp=False)
|
||||
|
||||
self.ui_click(click_button=BACK_ARROW, check_button=DAILY_CHECK, additional=self.handle_daily_additional,
|
||||
skip_first_screenshot=True)
|
||||
self.device.sleep((1, 1.2))
|
||||
return True
|
||||
|
||||
def daily_enter(self, button, skip_first_screenshot=True):
|
||||
"""
|
||||
Args:
|
||||
button (Button): Daily entrance
|
||||
skip_first_screenshot (bool):
|
||||
|
||||
Returns:
|
||||
bool: True if combat appear. False if daily skip unlocked, skipped daily, received rewards.
|
||||
|
||||
Pages:
|
||||
in: DAILY_ENTER_CHECK
|
||||
out: DAILY_ENTER_CHECK or combat_appear
|
||||
"""
|
||||
reward_received = False
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear(DAILY_ENTER_CHECK, threshold=30, interval=5):
|
||||
self.device.click(button)
|
||||
continue
|
||||
if self.handle_get_items():
|
||||
reward_received = True
|
||||
continue
|
||||
if self.config.Daily_UseDailySkip:
|
||||
if self.appear_then_click(DAILY_SKIP, offset=(20, 20), interval=5):
|
||||
continue
|
||||
else:
|
||||
if self.appear_then_click(DAILY_NORMAL_RUN, offset=(20, 20), interval=5):
|
||||
continue
|
||||
if self.handle_combat_automation_confirm():
|
||||
continue
|
||||
if self.handle_daily_additional():
|
||||
continue
|
||||
if self.handle_popup_confirm('DAILY_SKIP'):
|
||||
continue
|
||||
|
||||
# End
|
||||
if self.appear(DAILY_SKIP, offset=(20, 20)):
|
||||
if reward_received:
|
||||
return False
|
||||
if self.info_bar_count():
|
||||
return False
|
||||
if self.appear(DAILY_ENTER_CHECK, threshold=30):
|
||||
if self.info_bar_count():
|
||||
return False
|
||||
if self.combat_appear():
|
||||
return True
|
||||
|
||||
def daily_check(self, n=None):
|
||||
if not n:
|
||||
n = self.daily_current
|
||||
self.daily_checked.append(n)
|
||||
logger.info(f'Checked daily {n}')
|
||||
logger.info(f'Checked_list: {self.daily_checked}')
|
||||
|
||||
def daily_run_one(self):
|
||||
logger.hr('Daily run one', level=1)
|
||||
self.ui_ensure(page_daily)
|
||||
self.device.sleep(0.2)
|
||||
self.device.screenshot()
|
||||
self.daily_current = 1
|
||||
|
||||
logger.info(f'Checked_list: {self.daily_checked}')
|
||||
for _ in range(max(self.daily_checked)):
|
||||
self.next()
|
||||
|
||||
while 1:
|
||||
# Meaning of daily_current
|
||||
# 1 Tactical Training, 2 Fierce Assault, 3 Supply Line Disruption, 4 Escort Mission, 5 Advance Mission
|
||||
# 1 战术研修, 2 斩首行动, 3 破交作战, 4 商船护送, 5 海域突进
|
||||
if self.daily_current > 5:
|
||||
break
|
||||
stage, fleet = self.get_daily_stage_and_fleet()
|
||||
if self.daily_current == 3 and not self.config.Daily_UseDailySkip:
|
||||
logger.info('Skip supply line disruption if UseDailySkip disabled')
|
||||
self.daily_check()
|
||||
self.next()
|
||||
continue
|
||||
if not stage:
|
||||
logger.info(f'No stage set on daily_current: {self.daily_current}, skip')
|
||||
self.daily_check()
|
||||
self.next()
|
||||
continue
|
||||
if self.daily_current != 3 and not fleet:
|
||||
logger.info(f'No fleet set on daily_current: {self.daily_current}, skip')
|
||||
self.daily_check()
|
||||
self.next()
|
||||
continue
|
||||
if not self.is_active():
|
||||
self.daily_check()
|
||||
self.next()
|
||||
continue
|
||||
remain = OCR_REMAIN.ocr(self.device.image)
|
||||
if remain == 0:
|
||||
self.daily_check()
|
||||
self.next()
|
||||
continue
|
||||
else:
|
||||
self.daily_execute(remain=remain, stage=stage, fleet=fleet)
|
||||
self.daily_check()
|
||||
# The order of daily tasks will be disordered after execute a daily, exit and re-enter to reset.
|
||||
# 打完一次之后每日任务的顺序会乱掉, 退出再进入来重置顺序.
|
||||
self.ui_goto(page_campaign_menu)
|
||||
break
|
||||
|
||||
def daily_run(self):
|
||||
self.daily_checked = [0]
|
||||
|
||||
while 1:
|
||||
self.daily_run_one()
|
||||
|
||||
if max(self.daily_checked) >= 5:
|
||||
logger.info('Daily clear complete.')
|
||||
break
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
Pages:
|
||||
in: Any page
|
||||
out: page_daily
|
||||
"""
|
||||
# self.equipment_take_on()
|
||||
self.daily_run()
|
||||
# self.equipment_take_off()
|
||||
|
||||
# Cannot stay in page_daily, because order is disordered.
|
||||
self.config.task_delay(server_update=True)
|
@ -54,7 +54,7 @@ class EmulatorInstance(VirtualBoxEmulator):
|
||||
|
||||
serial = []
|
||||
for file in vbox:
|
||||
with open(file, 'r') as f:
|
||||
with open(file, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
for line in f.readlines():
|
||||
# <Forwarding name="port2" proto="1" hostip="127.0.0.1" hostport="62026" guestport="5555"/>
|
||||
res = re.search('<*?hostport="(.*?)".*?guestport="5555"/>', line)
|
||||
|
@ -78,6 +78,6 @@ SUBMARINE_MOVE_ENTER = Button(area={'cn': (1109, 511, 1169, 571), 'en': (1109, 5
|
||||
SUBMARINE_VIEW_OFF = Button(area={'cn': (1140, 435, 1170, 468), 'en': (1140, 435, 1170, 468), 'jp': (1140, 435, 1170, 468), 'tw': (1140, 435, 1170, 468)}, color={'cn': (156, 156, 158), 'en': (156, 156, 158), 'jp': (156, 156, 158), 'tw': (156, 156, 158)}, button={'cn': (1140, 435, 1170, 468), 'en': (1140, 435, 1170, 468), 'jp': (1140, 435, 1170, 468), 'tw': (1140, 435, 1170, 468)}, file={'cn': './assets/cn/handler/SUBMARINE_VIEW_OFF.png', 'en': './assets/en/handler/SUBMARINE_VIEW_OFF.png', 'jp': './assets/jp/handler/SUBMARINE_VIEW_OFF.png', 'tw': './assets/tw/handler/SUBMARINE_VIEW_OFF.png'})
|
||||
SUBMARINE_VIEW_ON = Button(area={'cn': (1140, 435, 1170, 468), 'en': (1140, 435, 1170, 468), 'jp': (1140, 435, 1170, 468), 'tw': (1140, 435, 1170, 468)}, color={'cn': (177, 178, 179), 'en': (177, 178, 179), 'jp': (177, 178, 179), 'tw': (177, 178, 179)}, button={'cn': (1140, 435, 1170, 468), 'en': (1140, 435, 1170, 468), 'jp': (1140, 435, 1170, 468), 'tw': (1140, 435, 1170, 468)}, file={'cn': './assets/cn/handler/SUBMARINE_VIEW_ON.png', 'en': './assets/en/handler/SUBMARINE_VIEW_ON.png', 'jp': './assets/jp/handler/SUBMARINE_VIEW_ON.png', 'tw': './assets/tw/handler/SUBMARINE_VIEW_ON.png'})
|
||||
USER_AGREEMENT_CONFIRM = Button(area={'cn': (709, 526, 742, 542), 'en': (709, 526, 742, 542), 'jp': (709, 526, 742, 542), 'tw': (709, 526, 742, 542)}, color={'cn': (151, 216, 243), 'en': (151, 216, 243), 'jp': (151, 216, 243), 'tw': (151, 216, 243)}, button={'cn': (709, 526, 742, 542), 'en': (709, 526, 742, 542), 'jp': (709, 526, 742, 542), 'tw': (709, 526, 742, 542)}, file={'cn': './assets/cn/handler/USER_AGREEMENT_CONFIRM.png', 'en': './assets/en/handler/USER_AGREEMENT_CONFIRM.png', 'jp': './assets/jp/handler/USER_AGREEMENT_CONFIRM.png', 'tw': './assets/tw/handler/USER_AGREEMENT_CONFIRM.png'})
|
||||
USE_DATA_KEY = Button(area={'cn': (688, 316, 781, 338), 'en': (754, 324, 883, 342), 'jp': (625, 318, 742, 344), 'tw': (688, 316, 782, 338)}, color={'cn': (165, 154, 99), 'en': (162, 154, 90), 'jp': (122, 130, 121), 'tw': (159, 150, 97)}, button={'cn': (688, 316, 781, 338), 'en': (754, 324, 883, 342), 'jp': (625, 318, 742, 344), 'tw': (688, 316, 782, 338)}, file={'cn': './assets/cn/handler/USE_DATA_KEY.png', 'en': './assets/en/handler/USE_DATA_KEY.png', 'jp': './assets/jp/handler/USE_DATA_KEY.png', 'tw': './assets/tw/handler/USE_DATA_KEY.png'})
|
||||
USE_DATA_KEY = Button(area={'cn': (688, 316, 781, 338), 'en': (759, 323, 889, 342), 'jp': (625, 318, 742, 344), 'tw': (688, 316, 782, 338)}, color={'cn': (165, 154, 99), 'en': (170, 160, 94), 'jp': (122, 130, 121), 'tw': (159, 150, 97)}, button={'cn': (688, 316, 781, 338), 'en': (759, 323, 889, 342), 'jp': (625, 318, 742, 344), 'tw': (688, 316, 782, 338)}, file={'cn': './assets/cn/handler/USE_DATA_KEY.png', 'en': './assets/en/handler/USE_DATA_KEY.png', 'jp': './assets/jp/handler/USE_DATA_KEY.png', 'tw': './assets/tw/handler/USE_DATA_KEY.png'})
|
||||
USE_DATA_KEY_NOTIFIED = Button(area={'cn': (770, 434, 793, 456), 'en': (820, 440, 837, 456), 'jp': (686, 430, 709, 456), 'tw': (782, 440, 799, 456)}, color={'cn': (41, 44, 49), 'en': (33, 40, 41), 'jp': (33, 44, 49), 'tw': (34, 40, 48)}, button={'cn': (770, 434, 793, 456), 'en': (820, 440, 837, 456), 'jp': (686, 430, 709, 456), 'tw': (782, 440, 799, 456)}, file={'cn': './assets/cn/handler/USE_DATA_KEY_NOTIFIED.png', 'en': './assets/en/handler/USE_DATA_KEY_NOTIFIED.png', 'jp': './assets/jp/handler/USE_DATA_KEY_NOTIFIED.png', 'tw': './assets/tw/handler/USE_DATA_KEY_NOTIFIED.png'})
|
||||
VOTE_CANCEL = Button(area={'cn': (404, 483, 576, 539), 'en': (413, 489, 566, 532), 'jp': (407, 483, 577, 538), 'tw': (404, 483, 576, 539)}, color={'cn': (167, 169, 171), 'en': (169, 170, 172), 'jp': (163, 164, 166), 'tw': (167, 169, 171)}, button={'cn': (404, 483, 576, 539), 'en': (413, 489, 566, 532), 'jp': (407, 483, 577, 538), 'tw': (404, 483, 576, 539)}, file={'cn': './assets/cn/handler/VOTE_CANCEL.png', 'en': './assets/en/handler/VOTE_CANCEL.png', 'jp': './assets/jp/handler/VOTE_CANCEL.png', 'tw': './assets/cn/handler/VOTE_CANCEL.png'})
|
||||
|
@ -99,6 +99,30 @@ class SelectedGrids:
|
||||
def indexed_select(self, *values):
|
||||
return self.indexes.get(values, SelectedGrids([]))
|
||||
|
||||
def left_join(self, right, on_attr, set_attr, default=None):
|
||||
"""
|
||||
Args:
|
||||
right (SelectedGrids): Right table to join
|
||||
on_attr:
|
||||
set_attr:
|
||||
default:
|
||||
|
||||
Returns:
|
||||
SelectedGrids:
|
||||
"""
|
||||
right.create_index(*on_attr)
|
||||
for grid in self:
|
||||
attr_value = tuple([grid.__getattribute__(attr) for attr in on_attr])
|
||||
right_grid = right.indexed_select(*attr_value).first_or_none()
|
||||
if right_grid is not None:
|
||||
for attr in set_attr:
|
||||
grid.__setattr__(attr, right_grid.__getattribute__(attr))
|
||||
else:
|
||||
for attr in set_attr:
|
||||
grid.__setattr__(attr, default)
|
||||
|
||||
return self
|
||||
|
||||
def filter(self, func):
|
||||
"""
|
||||
Filter grids by a function.
|
||||
|
@ -218,7 +218,8 @@ class OpsiAshBeacon(Meta):
|
||||
# Page beacon or dossier
|
||||
if self.appear(BEACON_LIST, offset=(20, 20)):
|
||||
if self.config.OpsiAshBeacon_OneHitMode or self.config.OpsiAshBeacon_RequestAssist:
|
||||
self._ask_for_help()
|
||||
if not self._ask_for_help():
|
||||
return False
|
||||
return True
|
||||
if self.appear(DOSSIER_LIST, offset=(20, 20)):
|
||||
return True
|
||||
@ -228,6 +229,10 @@ class OpsiAshBeacon(Meta):
|
||||
"""
|
||||
Request help from friends, guild and world.
|
||||
|
||||
Returns:
|
||||
bool: Whether success to call assist.
|
||||
False if META finished just after calling assist.
|
||||
|
||||
Pages:
|
||||
in: is_in_meta
|
||||
out: is_in_meta
|
||||
@ -257,7 +262,23 @@ class OpsiAshBeacon(Meta):
|
||||
self.device.click(HELP_2)
|
||||
self.device.sleep((0.1, 0.3))
|
||||
self.device.click(HELP_3)
|
||||
self.ui_click(click_button=HELP_CONFIRM, check_button=HELP_ENTER)
|
||||
|
||||
skip_first_screenshot = True
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
# End
|
||||
if self.appear(HELP_ENTER, offset=(30, 30)):
|
||||
return True
|
||||
if self.appear(BEACON_REWARD, offset=(30, 30)):
|
||||
logger.info('META finished just after calling assist, ignore meta assist')
|
||||
return False
|
||||
# Click
|
||||
if self.appear_then_click(HELP_CONFIRM, offset=(30, 30), interval=3):
|
||||
continue
|
||||
|
||||
def _begin_meta(self):
|
||||
"""
|
||||
|
@ -184,7 +184,10 @@ class ActionPointHandler(UI):
|
||||
"""
|
||||
self.action_point_set_button(0)
|
||||
current, _, _ = OCR_ACTION_POINT_BUY_REMAIN.ocr(self.device.image)
|
||||
if current == 0:
|
||||
buy_max = 5 # In current version of AL, players can buy 5 times of AP in a week.
|
||||
buy_count = buy_max - current
|
||||
buy_limit = self.config.OpsiGeneral_BuyActionPointLimit
|
||||
if buy_count >= buy_limit:
|
||||
logger.info('Reach the limit to buy action points this week')
|
||||
return False
|
||||
cost = ACTION_POINTS_BUY[current]
|
||||
@ -237,7 +240,7 @@ class ActionPointHandler(UI):
|
||||
return True
|
||||
|
||||
# Buy action points
|
||||
if self.config.OpsiGeneral_BuyActionPoint and not buy_checked:
|
||||
if self.config.OpsiGeneral_BuyActionPointLimit > 0 and not buy_checked:
|
||||
if self.action_point_buy(preserve=self.config.OpsiGeneral_OilLimit):
|
||||
continue
|
||||
else:
|
||||
|
@ -8,7 +8,7 @@ ACTION_POINT_BUY_REMAIN = Button(area={'cn': (803, 458, 833, 482), 'en': (907, 4
|
||||
ACTION_POINT_CANCEL = Button(area={'cn': (370, 528, 542, 585), 'en': (375, 531, 537, 584), 'jp': (369, 527, 544, 587), 'tw': (371, 528, 541, 586)}, color={'cn': (167, 168, 171), 'en': (170, 172, 175), 'jp': (161, 163, 165), 'tw': (168, 169, 172)}, button={'cn': (370, 528, 542, 585), 'en': (375, 531, 537, 584), 'jp': (369, 527, 544, 587), 'tw': (371, 528, 541, 586)}, file={'cn': './assets/cn/os_handler/ACTION_POINT_CANCEL.png', 'en': './assets/en/os_handler/ACTION_POINT_CANCEL.png', 'jp': './assets/jp/os_handler/ACTION_POINT_CANCEL.png', 'tw': './assets/tw/os_handler/ACTION_POINT_CANCEL.png'})
|
||||
ACTION_POINT_REMAIN = Button(area={'cn': (892, 220, 952, 241), 'en': (892, 220, 952, 241), 'jp': (908, 220, 979, 240), 'tw': (892, 220, 952, 241)}, color={'cn': (124, 127, 113), 'en': (124, 127, 113), 'jp': (119, 121, 113), 'tw': (124, 127, 113)}, button={'cn': (892, 220, 952, 241), 'en': (892, 220, 952, 241), 'jp': (908, 220, 979, 240), 'tw': (892, 220, 952, 241)}, file={'cn': './assets/cn/os_handler/ACTION_POINT_REMAIN.png', 'en': './assets/en/os_handler/ACTION_POINT_REMAIN.png', 'jp': './assets/jp/os_handler/ACTION_POINT_REMAIN.png', 'tw': './assets/tw/os_handler/ACTION_POINT_REMAIN.png'})
|
||||
ACTION_POINT_USE = Button(area={'cn': (738, 528, 910, 585), 'en': (742, 531, 909, 584), 'jp': (737, 528, 911, 586), 'tw': (739, 528, 909, 585)}, color={'cn': (93, 142, 203), 'en': (107, 152, 208), 'jp': (92, 141, 203), 'tw': (95, 144, 205)}, button={'cn': (738, 528, 910, 585), 'en': (742, 531, 909, 584), 'jp': (737, 528, 911, 586), 'tw': (739, 528, 909, 585)}, file={'cn': './assets/cn/os_handler/ACTION_POINT_USE.png', 'en': './assets/en/os_handler/ACTION_POINT_USE.png', 'jp': './assets/jp/os_handler/ACTION_POINT_USE.png', 'tw': './assets/tw/os_handler/ACTION_POINT_USE.png'})
|
||||
ASH_POPUP_CHECK = Button(area={'cn': (665, 318, 759, 340), 'en': (356, 324, 575, 342), 'jp': (438, 311, 534, 346), 'tw': (665, 298, 759, 320)}, color={'cn': (154, 163, 172), 'en': (172, 178, 186), 'jp': (146, 154, 161), 'tw': (157, 166, 176)}, button={'cn': (665, 318, 759, 340), 'en': (356, 324, 575, 342), 'jp': (438, 311, 534, 346), 'tw': (665, 298, 759, 320)}, file={'cn': './assets/cn/os_handler/ASH_POPUP_CHECK.png', 'en': './assets/en/os_handler/ASH_POPUP_CHECK.png', 'jp': './assets/jp/os_handler/ASH_POPUP_CHECK.png', 'tw': './assets/tw/os_handler/ASH_POPUP_CHECK.png'})
|
||||
ASH_POPUP_CHECK = Button(area={'cn': (665, 318, 759, 340), 'en': (372, 324, 601, 342), 'jp': (438, 311, 534, 346), 'tw': (665, 298, 759, 320)}, color={'cn': (154, 163, 172), 'en': (174, 179, 184), 'jp': (146, 154, 161), 'tw': (157, 166, 176)}, button={'cn': (665, 318, 759, 340), 'en': (372, 324, 601, 342), 'jp': (438, 311, 534, 346), 'tw': (665, 298, 759, 320)}, file={'cn': './assets/cn/os_handler/ASH_POPUP_CHECK.png', 'en': './assets/en/os_handler/ASH_POPUP_CHECK.png', 'jp': './assets/jp/os_handler/ASH_POPUP_CHECK.png', 'tw': './assets/tw/os_handler/ASH_POPUP_CHECK.png'})
|
||||
AUTO_SEARCH_OS_MAP_OPTION_OFF = Button(area={'cn': (1205, 549, 1275, 566), 'en': (1201, 524, 1274, 534), 'jp': (1204, 572, 1276, 593), 'tw': (1206, 573, 1275, 591)}, color={'cn': (196, 169, 169), 'en': (167, 140, 142), 'jp': (180, 154, 157), 'tw': (167, 143, 147)}, button={'cn': (1205, 549, 1275, 566), 'en': (1201, 524, 1274, 534), 'jp': (1204, 572, 1276, 593), 'tw': (1206, 573, 1275, 591)}, file={'cn': './assets/cn/os_handler/AUTO_SEARCH_OS_MAP_OPTION_OFF.png', 'en': './assets/en/os_handler/AUTO_SEARCH_OS_MAP_OPTION_OFF.png', 'jp': './assets/jp/os_handler/AUTO_SEARCH_OS_MAP_OPTION_OFF.png', 'tw': './assets/tw/os_handler/AUTO_SEARCH_OS_MAP_OPTION_OFF.png'})
|
||||
AUTO_SEARCH_OS_MAP_OPTION_ON = Button(area={'cn': (1205, 549, 1275, 566), 'en': (1201, 526, 1274, 536), 'jp': (1205, 573, 1275, 592), 'tw': (1206, 573, 1275, 591)}, color={'cn': (149, 176, 193), 'en': (108, 129, 150), 'jp': (145, 172, 190), 'tw': (123, 148, 169)}, button={'cn': (1205, 549, 1275, 566), 'en': (1201, 526, 1274, 536), 'jp': (1205, 573, 1275, 592), 'tw': (1206, 573, 1275, 591)}, file={'cn': './assets/cn/os_handler/AUTO_SEARCH_OS_MAP_OPTION_ON.png', 'en': './assets/en/os_handler/AUTO_SEARCH_OS_MAP_OPTION_ON.png', 'jp': './assets/jp/os_handler/AUTO_SEARCH_OS_MAP_OPTION_ON.png', 'tw': './assets/tw/os_handler/AUTO_SEARCH_OS_MAP_OPTION_ON.png'})
|
||||
AUTO_SEARCH_REWARD = Button(area={'cn': (575, 598, 721, 646), 'en': (574, 597, 722, 648), 'jp': (577, 597, 722, 645), 'tw': (576, 598, 720, 647)}, color={'cn': (169, 168, 170), 'en': (168, 171, 174), 'jp': (165, 170, 175), 'tw': (171, 174, 179)}, button={'cn': (575, 598, 721, 646), 'en': (574, 597, 722, 648), 'jp': (577, 597, 722, 645), 'tw': (576, 598, 720, 647)}, file={'cn': './assets/cn/os_handler/AUTO_SEARCH_REWARD.png', 'en': './assets/en/os_handler/AUTO_SEARCH_REWARD.png', 'jp': './assets/jp/os_handler/AUTO_SEARCH_REWARD.png', 'tw': './assets/tw/os_handler/AUTO_SEARCH_REWARD.png'})
|
||||
|
@ -141,8 +141,14 @@ class ResearchSelector(ResearchUI):
|
||||
self.config.Research_UsePart))
|
||||
logger.attr('Allow delay', self.config.Research_AllowDelay)
|
||||
|
||||
# Case insensitive
|
||||
string = string.lower()
|
||||
# Filter uses `hakuryu`, but allows both `hakuryu` and `hakuryuu`
|
||||
string = string.lower().replace('hakuryuu', 'hakuryu')
|
||||
string = string.replace('hakuryuu', 'hakuryu')
|
||||
# Allow both `fastest` and `shortest`
|
||||
string = string.replace('fastest', 'shortest')
|
||||
# Allow both `PR` and `PRY`
|
||||
string = re.sub(r'pr([\d\- >])', r'pry\1', string)
|
||||
|
||||
FILTER.load(string)
|
||||
priority = FILTER.apply(self.projects, func=partial(self._research_check, enforce=enforce))
|
||||
|
@ -220,7 +220,10 @@ class ItemGrid:
|
||||
str: Template name.
|
||||
"""
|
||||
color = cv2.mean(crop(image, self.template_area))[:3]
|
||||
# Match frequently hit templates first
|
||||
names = np.array(list(self.templates.keys()))[np.argsort(list(self.templates_hit.values()))][::-1]
|
||||
# Match known templates first
|
||||
names = [name for name in names if not name.isdigit()] + [name for name in names if name.isdigit()]
|
||||
for name in names:
|
||||
if color_similar(color1=color, color2=self.colors[name], threshold=30):
|
||||
res = cv2.matchTemplate(image, self.templates[name], cv2.TM_CCOEFF_NORMED)
|
||||
|
@ -15,8 +15,9 @@ from module.ocr.ocr import DigitCounter, Duration, Ocr
|
||||
from module.retire.assets import DOCK_EMPTY, DOCK_CHECK, SHIP_CONFIRM
|
||||
from module.retire.dock import CARD_GRIDS, Dock, CARD_LEVEL_GRIDS
|
||||
from module.tactical.assets import *
|
||||
from module.ui.assets import (BACK_ARROW, REWARD_GOTO_TACTICAL,
|
||||
TACTICAL_CHECK, REWARD_CHECK)
|
||||
from module.ui.assets import (BACK_ARROW, MAIN_GOTO_REWARD,
|
||||
REWARD_GOTO_TACTICAL, REWARD_CHECK,
|
||||
TACTICAL_CHECK)
|
||||
from module.ui.ui import page_reward
|
||||
|
||||
SKILL_GRIDS = ButtonGrid(origin=(315, 140), delta=(621, 132), button_shape=(621, 119), grid_shape=(1, 3), name='SKILL')
|
||||
@ -221,9 +222,6 @@ class RewardTacticalClass(Dock):
|
||||
books from self.books based on current
|
||||
progress of the tactical skill.
|
||||
"""
|
||||
# Shorthand referencing
|
||||
first, last = self.books[0], self.books[-1]
|
||||
|
||||
# Read 'current' and 'remain' will be inaccurate
|
||||
# since first exp_value is factored into it
|
||||
current, remain, total = SKILL_EXP.ocr(self.device.image)
|
||||
@ -409,6 +407,8 @@ class RewardTacticalClass(Dock):
|
||||
continue
|
||||
if self.appear_then_click(REWARD_GOTO_TACTICAL, offset=(20, 20), interval=3):
|
||||
continue
|
||||
if self.appear_then_click(MAIN_GOTO_REWARD, offset=(20, 20), interval=3):
|
||||
continue
|
||||
if self.handle_popup_confirm('TACTICAL'):
|
||||
continue
|
||||
if self.handle_urgent_commission():
|
||||
@ -458,7 +458,7 @@ class RewardTacticalClass(Dock):
|
||||
study_finished = True
|
||||
self.device.click(BACK_ARROW)
|
||||
continue
|
||||
if self.appear(TACTICAL_META, offset=(200, 20)):
|
||||
if self.appear(TACTICAL_META, offset=(200, 20), interval=3):
|
||||
# If meta's skill page, it's inappropriate
|
||||
logger.info('META skill found, exit')
|
||||
self.device.click(BACK_ARROW)
|
||||
@ -492,7 +492,8 @@ class RewardTacticalClass(Dock):
|
||||
else:
|
||||
break
|
||||
|
||||
def check_skill_selected(self, button, image):
|
||||
@staticmethod
|
||||
def check_skill_selected(button, image):
|
||||
area = button.area
|
||||
check_area = tuple([area[0], area[3] + 2, area[2], area[3] + 4])
|
||||
im = rgb2gray(crop(image, check_area))
|
||||
@ -534,14 +535,26 @@ class RewardTacticalClass(Dock):
|
||||
logger.info('Dock is empty or favorite ships is empty')
|
||||
return False
|
||||
|
||||
level_grids = CARD_LEVEL_GRIDS
|
||||
card_grids = CARD_GRIDS
|
||||
# Ship cards may slow to show, like:
|
||||
# [0, 0, 120, 120, 120, 120, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
# [12, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
# Wait until they turn into
|
||||
# [120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120]
|
||||
level_ocr = LevelOcr(CARD_LEVEL_GRIDS.buttons, name='DOCK_LEVEL_OCR', threshold=64)
|
||||
timeout = Timer(1, count=1).start()
|
||||
while 1:
|
||||
list_level = level_ocr.ocr(self.device.image)
|
||||
first_ship = next((i for i, x in enumerate(list_level) if x > 0), len(list_level))
|
||||
first_empty = next((i for i, x in enumerate(list_level) if x == 0), len(list_level))
|
||||
if timeout.reached():
|
||||
logger.warning('Wait ship cards timeout')
|
||||
break
|
||||
if first_empty >= first_ship:
|
||||
break
|
||||
self.device.screenshot()
|
||||
|
||||
level_ocr = LevelOcr(level_grids.buttons,
|
||||
name='DOCK_LEVEL_OCR', threshold=64)
|
||||
list_level = level_ocr.ocr(self.device.image)
|
||||
should_select_button = None
|
||||
for button, level in list(zip(card_grids.buttons, list_level))[self.dock_select_index:]:
|
||||
for button, level in list(zip(CARD_GRIDS.buttons, list_level))[self.dock_select_index:]:
|
||||
# Select ship LV > 1 only
|
||||
if level > 1:
|
||||
should_select_button = button
|
||||
@ -581,8 +594,12 @@ class RewardTacticalClass(Dock):
|
||||
skill_level_list = skill_level_ocr.ocr(self.device.image)
|
||||
for skill_button, skill_level in list(zip(SKILL_GRIDS.buttons, skill_level_list)):
|
||||
level = skill_level.upper().replace(' ', '')
|
||||
logger.attr('LEVEL', 'EMPTY' if len(level) == 0 else level)
|
||||
if 'NEXT' in level and 'MAX' not in level:
|
||||
# Use 'MA' as a part of `MAX`.
|
||||
# SKILL_LEVEL_GRIDS may move a little lower for unknown reason, OCR results are like:
|
||||
# ['NEXT:MA', 'NEXT:/1D]', 'NEXT:MA'] (Actually: `NEXT:MAX, NEXT:0/100, NEXT:MAX`)
|
||||
# ['NEXT:MA', 'NEX T:/ 14[]]', 'NEXT:MA'] (Actually: `NEXT:MAX, NEXT:150/1400, NEXT:MAX`)
|
||||
if 'NEXT' in level and 'MA' not in level:
|
||||
logger.attr('LEVEL', 'EMPTY' if len(level) == 0 else level)
|
||||
return skill_button
|
||||
|
||||
return None
|
||||
|
@ -152,6 +152,7 @@ TEMPLATE_SIREN_Sakawa = Template(file={'cn': './assets/cn/template/TEMPLATE_SIRE
|
||||
TEMPLATE_SIREN_SanDiego = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_SanDiego.gif', 'en': './assets/en/template/TEMPLATE_SIREN_SanDiego.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_SanDiego.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_SanDiego.gif'})
|
||||
TEMPLATE_SIREN_Scharnhorst = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Scharnhorst.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Scharnhorst.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Scharnhorst.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Scharnhorst.gif'})
|
||||
TEMPLATE_SIREN_Sheffield = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Sheffield.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Sheffield.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Sheffield.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Sheffield.gif'})
|
||||
TEMPLATE_SIREN_SheffieldIdol = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_SheffieldIdol.png', 'en': './assets/cn/template/TEMPLATE_SIREN_SheffieldIdol.png', 'jp': './assets/cn/template/TEMPLATE_SIREN_SheffieldIdol.png', 'tw': './assets/cn/template/TEMPLATE_SIREN_SheffieldIdol.png'})
|
||||
TEMPLATE_SIREN_Shokaku = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Shokaku.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Shokaku.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Shokaku.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Shokaku.gif'})
|
||||
TEMPLATE_SIREN_Soobrazitelny = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Soobrazitelny.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Soobrazitelny.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Soobrazitelny.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Soobrazitelny.gif'})
|
||||
TEMPLATE_SIREN_Spee = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Spee.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Spee.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Spee.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Spee.gif'})
|
||||
|
@ -1,7 +1,7 @@
|
||||
from module.base.base import ModuleBase
|
||||
from module.base.button import ButtonGrid
|
||||
from module.base.timer import Timer
|
||||
from module.combat.assets import GET_ITEMS_1, GET_SHIP
|
||||
from module.combat.assets import GET_ITEMS_1, GET_ITEMS_2, GET_SHIP
|
||||
from module.logger import logger
|
||||
from module.shop.assets import SHOP_CLICK_SAFE_AREA
|
||||
|
||||
@ -100,20 +100,22 @@ class Navbar:
|
||||
"""
|
||||
# Check name, identifies if NavBar
|
||||
# instance belongs to shop module
|
||||
if self.name != 'SHOP_BOTTOM_NAVBAR':
|
||||
if self.name not in ['SHOP_BOTTOM_NAVBAR', 'GUILD_SIDE_NAVBAR']:
|
||||
return False
|
||||
|
||||
# Handle shop obstructions
|
||||
if main.appear(GET_SHIP, interval=1):
|
||||
main.device.click(SHOP_CLICK_SAFE_AREA)
|
||||
return True
|
||||
if main.appear(GET_ITEMS_1, interval=1):
|
||||
if main.appear(GET_ITEMS_1, offset=(30, 30), interval=1):
|
||||
main.device.click(SHOP_CLICK_SAFE_AREA)
|
||||
return True
|
||||
if main.appear(GET_ITEMS_2, offset=(30, 30), interval=1):
|
||||
main.device.click(SHOP_CLICK_SAFE_AREA)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def set(self, main, left=None, right=None, upper=None, bottom=None, skip_first_screenshot=True):
|
||||
"""
|
||||
Set nav bar from 1 direction.
|
||||
|
@ -6,6 +6,7 @@ from module.base.template import Template
|
||||
|
||||
OCR_DATA_KEY_CAMPAIGN = Button(area={'cn': (1188, 107, 1272, 131), 'en': (1188, 107, 1272, 131), 'jp': (1188, 107, 1272, 131), 'tw': (1188, 107, 1272, 131)}, color={'cn': (104, 101, 107), 'en': (104, 101, 107), 'jp': (104, 101, 107), 'tw': (104, 101, 107)}, button={'cn': (1188, 107, 1272, 131), 'en': (1188, 107, 1272, 131), 'jp': (1188, 107, 1272, 131), 'tw': (1188, 107, 1272, 131)}, file={'cn': './assets/cn/war_archives/OCR_DATA_KEY_CAMPAIGN.png', 'en': './assets/en/war_archives/OCR_DATA_KEY_CAMPAIGN.png', 'jp': './assets/jp/war_archives/OCR_DATA_KEY_CAMPAIGN.png', 'tw': './assets/tw/war_archives/OCR_DATA_KEY_CAMPAIGN.png'})
|
||||
TEMPLATE_ASHEN_SIMULACRUM = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_ASHEN_SIMULACRUM.png', 'en': './assets/en/war_archives/TEMPLATE_ASHEN_SIMULACRUM.png', 'jp': './assets/cn/war_archives/TEMPLATE_ASHEN_SIMULACRUM.png', 'tw': './assets/cn/war_archives/TEMPLATE_ASHEN_SIMULACRUM.png'})
|
||||
TEMPLATE_CRESCENDO_OF_POLARIS = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png', 'en': './assets/cn/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png', 'jp': './assets/jp/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png', 'tw': './assets/cn/war_archives/TEMPLATE_CRESCENDO_OF_POLARIS.png'})
|
||||
TEMPLATE_CRIMSON_ECHOES = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_CRIMSON_ECHOES.png', 'en': './assets/en/war_archives/TEMPLATE_CRIMSON_ECHOES.png', 'jp': './assets/jp/war_archives/TEMPLATE_CRIMSON_ECHOES.png', 'tw': './assets/cn/war_archives/TEMPLATE_CRIMSON_ECHOES.png'})
|
||||
TEMPLATE_DIVERGENT_CHESSBOARD = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_DIVERGENT_CHESSBOARD.png', 'en': './assets/en/war_archives/TEMPLATE_DIVERGENT_CHESSBOARD.png', 'jp': './assets/jp/war_archives/TEMPLATE_DIVERGENT_CHESSBOARD.png', 'tw': './assets/tw/war_archives/TEMPLATE_DIVERGENT_CHESSBOARD.png'})
|
||||
TEMPLATE_EMPYREAL_TRAGICOMEDY = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_EMPYREAL_TRAGICOMEDY.png', 'en': './assets/en/war_archives/TEMPLATE_EMPYREAL_TRAGICOMEDY.png', 'jp': './assets/cn/war_archives/TEMPLATE_EMPYREAL_TRAGICOMEDY.png', 'tw': './assets/cn/war_archives/TEMPLATE_EMPYREAL_TRAGICOMEDY.png'})
|
||||
@ -18,6 +19,7 @@ TEMPLATE_SCHERZO_OF_IRON_AND_BLOOD = Template(file={'cn': './assets/cn/war_archi
|
||||
TEMPLATE_STRIVE_WISH_AND_STRATEGIZE = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_STRIVE_WISH_AND_STRATEGIZE.png', 'en': './assets/en/war_archives/TEMPLATE_STRIVE_WISH_AND_STRATEGIZE.png', 'jp': './assets/jp/war_archives/TEMPLATE_STRIVE_WISH_AND_STRATEGIZE.png', 'tw': './assets/tw/war_archives/TEMPLATE_STRIVE_WISH_AND_STRATEGIZE.png'})
|
||||
TEMPLATE_SWIRLING_CHERRY_BLOSSOMS = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_SWIRLING_CHERRY_BLOSSOMS.png', 'en': './assets/cn/war_archives/TEMPLATE_SWIRLING_CHERRY_BLOSSOMS.png', 'jp': './assets/cn/war_archives/TEMPLATE_SWIRLING_CHERRY_BLOSSOMS.png', 'tw': './assets/cn/war_archives/TEMPLATE_SWIRLING_CHERRY_BLOSSOMS.png'})
|
||||
TEMPLATE_THE_ENIGMA_AND_THE_SHARK = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_THE_ENIGMA_AND_THE_SHARK.png', 'en': './assets/cn/war_archives/TEMPLATE_THE_ENIGMA_AND_THE_SHARK.png', 'jp': './assets/cn/war_archives/TEMPLATE_THE_ENIGMA_AND_THE_SHARK.png', 'tw': './assets/cn/war_archives/TEMPLATE_THE_ENIGMA_AND_THE_SHARK.png'})
|
||||
TEMPLATE_UNIVERSE_IN_UNISON = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_UNIVERSE_IN_UNISON.png', 'en': './assets/cn/war_archives/TEMPLATE_UNIVERSE_IN_UNISON.png', 'jp': './assets/jp/war_archives/TEMPLATE_UNIVERSE_IN_UNISON.png', 'tw': './assets/cn/war_archives/TEMPLATE_UNIVERSE_IN_UNISON.png'})
|
||||
TEMPLATE_VISITORS_DYED_IN_RED = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_VISITORS_DYED_IN_RED.png', 'en': './assets/en/war_archives/TEMPLATE_VISITORS_DYED_IN_RED.png', 'jp': './assets/jp/war_archives/TEMPLATE_VISITORS_DYED_IN_RED.png', 'tw': './assets/tw/war_archives/TEMPLATE_VISITORS_DYED_IN_RED.png'})
|
||||
TEMPLATE_WINTERS_CROWN = Template(file={'cn': './assets/cn/war_archives/TEMPLATE_WINTERS_CROWN.png', 'en': './assets/en/war_archives/TEMPLATE_WINTERS_CROWN.png', 'jp': './assets/jp/war_archives/TEMPLATE_WINTERS_CROWN.png', 'tw': './assets/tw/war_archives/TEMPLATE_WINTERS_CROWN.png'})
|
||||
WAR_ARCHIVES_CAMPAIGN_CHECK = Button(area={'cn': (1150, 101, 1166, 130), 'en': (1150, 101, 1166, 130), 'jp': (1150, 101, 1166, 130), 'tw': (1150, 101, 1166, 130)}, color={'cn': (134, 175, 207), 'en': (134, 175, 207), 'jp': (134, 175, 207), 'tw': (134, 175, 207)}, button={'cn': (1150, 101, 1166, 130), 'en': (1150, 101, 1166, 130), 'jp': (1150, 101, 1166, 130), 'tw': (1150, 101, 1166, 130)}, file={'cn': './assets/cn/war_archives/WAR_ARCHIVES_CAMPAIGN_CHECK.png', 'en': './assets/en/war_archives/WAR_ARCHIVES_CAMPAIGN_CHECK.png', 'jp': './assets/jp/war_archives/WAR_ARCHIVES_CAMPAIGN_CHECK.png', 'tw': './assets/tw/war_archives/WAR_ARCHIVES_CAMPAIGN_CHECK.png'})
|
||||
|
@ -12,8 +12,10 @@ dic_archives_template = {
|
||||
'war_archives_20180726_cn': TEMPLATE_IRIS_OF_LIGHT_AND_DARK,
|
||||
'war_archives_20181227_cn': TEMPLATE_CRIMSON_ECHOES,
|
||||
'war_archives_20200820_cn': TEMPLATE_SCHERZO_OF_IRON_AND_BLOOD,
|
||||
'war_archives_20211014_cn': TEMPLATE_CRESCENDO_OF_POLARIS,
|
||||
'war_archives_20190911_cn': TEMPLATE_EMPYREAL_TRAGICOMEDY,
|
||||
'war_archives_20210325_cn': TEMPLATE_ASHEN_SIMULACRUM,
|
||||
'war_archives_20210624_cn': TEMPLATE_SWIRLING_CHERRY_BLOSSOMS,
|
||||
'war_archives_20200806_cn': TEMPLATE_THE_ENIGMA_AND_THE_SHARK,
|
||||
'war_archives_20201029_cn': TEMPLATE_UNIVERSE_IN_UNISON,
|
||||
}
|
||||
|
@ -156,6 +156,9 @@ class ProcessManager:
|
||||
GameManager(config=config_name, task="GameManager").run()
|
||||
elif func == 'maa':
|
||||
mod = load_mod('maa')
|
||||
|
||||
if e is not None:
|
||||
mod.set_stop_event(e)
|
||||
mod.loop(config_name)
|
||||
elif func == "MaaCopilot":
|
||||
mod = load_mod('maa')
|
||||
|
@ -110,6 +110,10 @@ def loop(config_name):
|
||||
ArknightsAutoScript(config_name).loop()
|
||||
|
||||
|
||||
def set_stop_event(e):
|
||||
ArknightsAutoScript.stop_event = e
|
||||
|
||||
|
||||
def maa_copilot(config_name):
|
||||
script = ArknightsAutoScript(config_name)
|
||||
script.config.bind('MaaCopilot')
|
||||
|