Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5feb46040c | |||
| bc920f065d |
@@ -12,17 +12,12 @@
|
||||
|
||||
The script is still under active development. The following features have been implemented:
|
||||
|
||||
- [x] **Cafe** Claim rewards / Interact / Second floor
|
||||
- [x] **Club** Claim AP
|
||||
- [x] **Cafe** Claim rewards / Interact / Second cafe
|
||||
- [x] **Circle** Claim AP
|
||||
- [x] **Mailbox** Claim rewards
|
||||
- [x] **Bounty** Auto sweep
|
||||
- [x] **Scrimmage** Auto sweep
|
||||
- [x] **Tactical Challenge** Claim rewards / Auto battle
|
||||
|
||||
Supported servers:
|
||||
|
||||
- [x] JP
|
||||
- [x] OVERSEA - Global
|
||||
_Currently only supports JP server._
|
||||
|
||||
## Relative projects
|
||||
|
||||
@@ -43,5 +38,3 @@ Thanks to [6bir](https://github.com/6bir) for the icon design.
|
||||
|
||||
Thanks to [Alas](https://github.com/LmeSzinc/AzurLaneAutoScript) and [SRC](https://github.com/LmeSzinc/StarRailCopilot)
|
||||
for the development framework.
|
||||
|
||||
Thanks to [RedDeadDepresso](https://github.com/RedDeadDepresso) for EN support.
|
||||
|
||||
@@ -15,22 +15,9 @@
|
||||
- [x] **咖啡厅** 领取奖励 / 互动 / 第二咖啡厅
|
||||
- [x] **公会** 领取体力
|
||||
- [x] **邮箱** 领取奖励
|
||||
- [x] **悬赏通缉** 自动扫荡
|
||||
- [x] **学院交流会** 自动扫荡
|
||||
- [x] **战术对抗赛** 领取奖励 / 自动战斗
|
||||
|
||||
目前支持的服务器:
|
||||
|
||||
- [x] 日服
|
||||
- [x] 国际服 - 全球
|
||||
|
||||
## 已知问题
|
||||
|
||||
若愿意提供其他服务器支持,请开 PR 或 Issue。
|
||||
|
||||
- **大小月卡**:未实现自动领取,~~因为没买过~~,可能不影响使用。愿意提供图片的请开 Issue
|
||||
- **月卡的额外悬赏券和学院交流券**:不太清楚月卡领取额外券的机制,~~因为没买过~~,可能影响相关任务使用券和体力的计算。愿意提供相关信息的请开
|
||||
Issue
|
||||
_目前仅支持日服。_
|
||||
|
||||
## 相关项目
|
||||
|
||||
@@ -49,5 +36,3 @@
|
||||
|
||||
感谢 [Alas](https://github.com/LmeSzinc/AzurLaneAutoScript) 以及 [SRC](https://github.com/LmeSzinc/StarRailCopilot)
|
||||
提供的开发框架。
|
||||
|
||||
感谢 [RedDeadDepresso](https://github.com/RedDeadDepresso) 提供英语支持。
|
||||
|
||||
@@ -34,14 +34,6 @@ class ArisuAutoSweeper(AzurLaneAutoScript):
|
||||
from tasks.mail.mail import Mail
|
||||
Mail(config=self.config, device=self.device).run()
|
||||
|
||||
def bounty(self):
|
||||
from tasks.bounty.bounty import Bounty
|
||||
Bounty(config=self.config, device=self.device).run()
|
||||
|
||||
def scrimmage(self):
|
||||
from tasks.scrimmage.scrimmage import Scrimmage
|
||||
Scrimmage(config=self.config, device=self.device).run()
|
||||
|
||||
def tactical_challenge(self):
|
||||
from tasks.tactical_challenge.tactical_challenge import TacticalChallenge
|
||||
TacticalChallenge(config=self.config, device=self.device).run()
|
||||
|
||||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 8.3 KiB |
@@ -285,7 +285,7 @@ pre.rich-traceback-code {
|
||||
*[style*="--header-icon--"] {
|
||||
margin: .25rem auto .25rem;
|
||||
border-radius: 1.5rem;
|
||||
height: 3em;
|
||||
height: 3.5em;
|
||||
}
|
||||
|
||||
*[style*="--header-text--"] {
|
||||
|
||||
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
@@ -1,8 +1,8 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'cn' to get update from self-hosted git service
|
||||
# [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSweeper
|
||||
# [CN user] Use 'cn' to get update from git-over-cdn service
|
||||
# [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSrcipt
|
||||
Repository: cn
|
||||
# Branch of Alas
|
||||
# [Developer] Use 'dev', 'app', etc, to try new features
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'cn' to get update from self-hosted git service
|
||||
# [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSweeper
|
||||
# [CN user] Use 'cn' to get update from git-over-cdn service
|
||||
# [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSrcipt
|
||||
Repository: global
|
||||
# Branch of Alas
|
||||
# [Developer] Use 'dev', 'app', etc, to try new features
|
||||
|
||||
@@ -63,52 +63,6 @@
|
||||
"ServerUpdate": "04:00"
|
||||
}
|
||||
},
|
||||
"Bounty": {
|
||||
"Scheduler": {
|
||||
"Enable": true,
|
||||
"NextRun": "2020-01-01 00:00:00",
|
||||
"Command": "Bounty",
|
||||
"ServerUpdate": "04:00"
|
||||
},
|
||||
"Bounty": {
|
||||
"OnError": "skip"
|
||||
},
|
||||
"Highway": {
|
||||
"Stage": 1,
|
||||
"Count": 2
|
||||
},
|
||||
"DesertRailroad": {
|
||||
"Stage": 1,
|
||||
"Count": 2
|
||||
},
|
||||
"Schoolhouse": {
|
||||
"Stage": 1,
|
||||
"Count": 2
|
||||
}
|
||||
},
|
||||
"Scrimmage": {
|
||||
"Scheduler": {
|
||||
"Enable": true,
|
||||
"NextRun": "2020-01-01 00:00:00",
|
||||
"Command": "Scrimmage",
|
||||
"ServerUpdate": "04:00"
|
||||
},
|
||||
"Scrimmage": {
|
||||
"OnError": "skip"
|
||||
},
|
||||
"Trinity": {
|
||||
"Stage": 1,
|
||||
"Count": 2
|
||||
},
|
||||
"Gehenna": {
|
||||
"Stage": 1,
|
||||
"Count": 2
|
||||
},
|
||||
"Millennium": {
|
||||
"Stage": 1,
|
||||
"Count": 2
|
||||
}
|
||||
},
|
||||
"TacticalChallenge": {
|
||||
"Scheduler": {
|
||||
"Enable": true,
|
||||
@@ -130,10 +84,7 @@
|
||||
"ItemStorage": {
|
||||
"AP": {},
|
||||
"Credit": {},
|
||||
"Pyroxene": {},
|
||||
"BountyTicket": {},
|
||||
"ScrimmageTicket": {},
|
||||
"TacticalChallengeTicket": {}
|
||||
"Pyroxene": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
Deploy:
|
||||
Git:
|
||||
# URL of AzurLaneAutoScript repository
|
||||
# [CN user] Use 'cn' to get update from self-hosted git service
|
||||
# [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSweeper
|
||||
# [CN user] Use 'cn' to get update from git-over-cdn service
|
||||
# [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSrcipt
|
||||
Repository: 'global'
|
||||
# Branch of Alas
|
||||
# [Developer] Use 'dev', 'app', etc, to try new features
|
||||
|
||||
@@ -179,29 +179,20 @@ def iter_assets():
|
||||
if image.attr != '':
|
||||
row = deep_get(data, keys=[image.module, image.assets, image.server, image.frame])
|
||||
row.load_image(image)
|
||||
# Set `search`
|
||||
# Apply `search` of the first frame to all
|
||||
for path, frames in deep_iter(data, depth=3):
|
||||
print(path, frames)
|
||||
# If `search` attribute is set in the first frame, apply to all
|
||||
first = frames[1]
|
||||
if first.search:
|
||||
search = first.search if first.search else DataAssets.area_to_search(first.area)
|
||||
for frame in frames.values():
|
||||
frame.search = first.search
|
||||
else:
|
||||
for frame in frames.values():
|
||||
if frame.search:
|
||||
# Follow frame specific `search`
|
||||
pass
|
||||
else:
|
||||
# Generate `search` from `area`
|
||||
frame.search = DataAssets.area_to_search(frame.area)
|
||||
frame.search = search
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def generate_code():
|
||||
all_assets = iter_assets()
|
||||
for module, module_data in all_assets.items():
|
||||
all = iter_assets()
|
||||
for module, module_data in all.items():
|
||||
path = os.path.join(AzurLaneConfig.ASSETS_MODULE, module.split('/', maxsplit=1)[0])
|
||||
output = os.path.join(path, 'assets.py')
|
||||
if os.path.exists(output):
|
||||
@@ -213,7 +204,7 @@ def generate_code():
|
||||
continue
|
||||
os.remove(prev)
|
||||
|
||||
for module, module_data in all_assets.items():
|
||||
for module, module_data in all.items():
|
||||
path = os.path.join(AzurLaneConfig.ASSETS_MODULE, module.split('/', maxsplit=1)[0])
|
||||
output = os.path.join(path, 'assets')
|
||||
gen = CodeGenerator()
|
||||
|
||||
@@ -74,7 +74,7 @@ class Button(Resource):
|
||||
threshold=threshold
|
||||
)
|
||||
|
||||
def match_template(self, image, similarity=0.85, direct_match=False) -> bool:
|
||||
def match_template(self, image, similarity=0.85) -> bool:
|
||||
"""
|
||||
Detects assets by template matching.
|
||||
|
||||
@@ -83,12 +83,10 @@ class Button(Resource):
|
||||
Args:
|
||||
image: Screenshot.
|
||||
similarity (float): 0-1.
|
||||
direct_match: True to ignore `self.search`
|
||||
|
||||
Returns:
|
||||
bool.
|
||||
"""
|
||||
if not direct_match:
|
||||
image = crop(image, self.search, copy=False)
|
||||
res = cv2.matchTemplate(self.image, image, cv2.TM_CCOEFF_NORMED)
|
||||
_, sim, _, point = cv2.minMaxLoc(res)
|
||||
@@ -96,32 +94,7 @@ class Button(Resource):
|
||||
self._button_offset = np.array(point) + self.search[:2] - self.area[:2]
|
||||
return sim > similarity
|
||||
|
||||
def match_multi_template(self, image, similarity=0.85, direct_match=False):
|
||||
"""
|
||||
Detects assets by template matching, return multiple reults
|
||||
|
||||
Args:
|
||||
image: Screenshot.
|
||||
similarity (float): 0-1.
|
||||
direct_match: True to ignore `self.search`
|
||||
|
||||
Returns:
|
||||
list:
|
||||
"""
|
||||
if not direct_match:
|
||||
image = crop(image, self.search, copy=False)
|
||||
res = cv2.matchTemplate(self.image, image, cv2.TM_CCOEFF_NORMED)
|
||||
res = cv2.inRange(res, similarity, 1.)
|
||||
try:
|
||||
points = np.array(cv2.findNonZero(res))[:, 0, :]
|
||||
points += self.search[:2]
|
||||
return points.tolist()
|
||||
except IndexError:
|
||||
# Empty result
|
||||
# IndexError: too many indices for array: array is 0-dimensional, but 3 were indexed
|
||||
return []
|
||||
|
||||
def match_template_color(self, image, similarity=0.85, threshold=30, direct_match=False) -> bool:
|
||||
def match_template_color(self, image, similarity=0.85, threshold=30) -> bool:
|
||||
"""
|
||||
Template match first, color match then
|
||||
|
||||
@@ -129,12 +102,11 @@ class Button(Resource):
|
||||
image: Screenshot.
|
||||
similarity (float): 0-1.
|
||||
threshold (int): Default to 10.
|
||||
direct_match: True to ignore `self.search`
|
||||
|
||||
Returns:
|
||||
bool.
|
||||
|
||||
"""
|
||||
matched = self.match_template(image, similarity=similarity, direct_match=direct_match)
|
||||
matched = self.match_template(image, similarity=similarity)
|
||||
if not matched:
|
||||
return False
|
||||
|
||||
@@ -152,10 +124,10 @@ class ButtonWrapper(Resource):
|
||||
self.name = name
|
||||
self.data_buttons = kwargs
|
||||
self._matched_button: t.Optional[Button] = None
|
||||
self.resource_add(f'{name}:{next(self.iter_buttons(), None)}')
|
||||
self.resource_add(self.name)
|
||||
|
||||
def resource_release(self):
|
||||
del_cached_property(self, 'buttons')
|
||||
del_cached_property(self, 'assets')
|
||||
self._matched_button = None
|
||||
|
||||
def __str__(self):
|
||||
@@ -172,25 +144,16 @@ class ButtonWrapper(Resource):
|
||||
def __bool__(self):
|
||||
return True
|
||||
|
||||
def iter_buttons(self) -> t.Iterator[Button]:
|
||||
for _, assets in self.data_buttons.items():
|
||||
if isinstance(assets, Button):
|
||||
yield assets
|
||||
elif isinstance(assets, list):
|
||||
for asset in assets:
|
||||
yield asset
|
||||
|
||||
@cached_property
|
||||
def buttons(self) -> t.List[Button]:
|
||||
for trial in [server.lang, 'share', 'cn']:
|
||||
try:
|
||||
assets = self.data_buttons[trial]
|
||||
# for trial in [server.lang, 'share', 'cn']:
|
||||
for trial in [server.lang, 'share', 'jp']:
|
||||
assets = self.data_buttons.get(trial, None)
|
||||
if assets is not None:
|
||||
if isinstance(assets, Button):
|
||||
return [assets]
|
||||
elif isinstance(assets, list):
|
||||
return assets
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
raise ScriptError(f'ButtonWrapper({self}) on server {server.lang} has no fallback button')
|
||||
|
||||
@@ -201,45 +164,16 @@ class ButtonWrapper(Resource):
|
||||
return True
|
||||
return False
|
||||
|
||||
def match_template(self, image, similarity=0.85, direct_match=False) -> bool:
|
||||
def match_template(self, image, similarity=0.85) -> bool:
|
||||
for assets in self.buttons:
|
||||
if assets.match_template(image, similarity=similarity, direct_match=direct_match):
|
||||
if assets.match_template(image, similarity=similarity):
|
||||
self._matched_button = assets
|
||||
return True
|
||||
return False
|
||||
|
||||
def match_multi_template(self, image, similarity=0.85, threshold=5, direct_match=False):
|
||||
"""
|
||||
Detects assets by template matching, return multiple results
|
||||
|
||||
Args:
|
||||
image: Screenshot.
|
||||
similarity (float): 0-1.
|
||||
threshold:
|
||||
direct_match: True to ignore `self.search`
|
||||
|
||||
Returns:
|
||||
list[ClickButton]:
|
||||
"""
|
||||
ps = []
|
||||
def match_template_color(self, image, similarity=0.85, threshold=30) -> bool:
|
||||
for assets in self.buttons:
|
||||
ps += assets.match_multi_template(image, similarity=similarity, direct_match=direct_match)
|
||||
if not ps:
|
||||
return []
|
||||
|
||||
from module.base.utils.points import Points
|
||||
ps = Points(ps).group(threshold=threshold)
|
||||
area_list = [area_offset(self.area, p - self.area[:2]) for p in ps]
|
||||
button_list = [area_offset(self.button, p - self.area[:2]) for p in ps]
|
||||
return [
|
||||
ClickButton(area=info[0], button=info[1], name=f'{self.name}_result{i}')
|
||||
for i, info in enumerate(zip(area_list, button_list))
|
||||
]
|
||||
|
||||
def match_template_color(self, image, similarity=0.85, threshold=30, direct_match=False) -> bool:
|
||||
for assets in self.buttons:
|
||||
if assets.match_template_color(
|
||||
image, similarity=similarity, threshold=threshold, direct_match=direct_match):
|
||||
if assets.match_template_color(image, similarity=similarity, threshold=threshold):
|
||||
self._matched_button = assets
|
||||
return True
|
||||
return False
|
||||
@@ -288,31 +222,17 @@ class ButtonWrapper(Resource):
|
||||
"""
|
||||
if isinstance(button, ButtonWrapper):
|
||||
button = button.matched_button
|
||||
for b in self.iter_buttons():
|
||||
for b in self.buttons:
|
||||
b.load_offset(button)
|
||||
|
||||
def clear_offset(self):
|
||||
for b in self.iter_buttons():
|
||||
for b in self.buttons:
|
||||
b.clear_offset()
|
||||
|
||||
def load_search(self, area):
|
||||
"""
|
||||
Set `search` attribute.
|
||||
Note that this method is irreversible.
|
||||
|
||||
Args:
|
||||
area:
|
||||
"""
|
||||
for b in self.iter_buttons():
|
||||
b.search = area
|
||||
|
||||
|
||||
class ClickButton:
|
||||
def __init__(self, area, button=None, name='CLICK_BUTTON'):
|
||||
self.area = area
|
||||
if button is None:
|
||||
self.button = area
|
||||
else:
|
||||
def __init__(self, button, name='CLICK_BUTTON'):
|
||||
self.area = button
|
||||
self.button = button
|
||||
self.name = name
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import re
|
||||
|
||||
from module.base.decorator import cached_property
|
||||
import module.config.server as server
|
||||
from module.base.decorator import cached_property, del_cached_property
|
||||
|
||||
|
||||
def get_assets_from_file(file):
|
||||
def get_assets_from_file(file, regex):
|
||||
assets = set()
|
||||
regex = re.compile(r"file='(.*?)'")
|
||||
with open(file, 'r', encoding='utf-8') as f:
|
||||
for row in f.readlines():
|
||||
result = regex.search(row)
|
||||
@@ -20,9 +20,11 @@ class PreservedAssets:
|
||||
assets = set()
|
||||
assets |= get_assets_from_file(
|
||||
file='./tasks/base/assets/assets_base_page.py',
|
||||
regex=re.compile(r'^([A-Za-z][A-Za-z0-9_]+) = ')
|
||||
)
|
||||
assets |= get_assets_from_file(
|
||||
file='./tasks/base/assets/assets_base_popup.py',
|
||||
regex=re.compile(r'^([A-Za-z][A-Za-z0-9_]+) = ')
|
||||
)
|
||||
return assets
|
||||
|
||||
@@ -42,13 +44,11 @@ class Resource:
|
||||
|
||||
@classmethod
|
||||
def is_loaded(cls, obj):
|
||||
if hasattr(obj, '_image') and obj._image is not None:
|
||||
return True
|
||||
if hasattr(obj, 'image') and obj.image is not None:
|
||||
return True
|
||||
if hasattr(obj, 'buttons') and obj.buttons is not None:
|
||||
return True
|
||||
if hasattr(obj, '_image') and obj._image is None:
|
||||
return False
|
||||
elif hasattr(obj, 'image') and obj.image is None:
|
||||
return False
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def resource_show(cls):
|
||||
@@ -56,16 +56,11 @@ class Resource:
|
||||
logger.hr('Show resource')
|
||||
for key, obj in cls.instances.items():
|
||||
if cls.is_loaded(obj):
|
||||
continue
|
||||
logger.info(f'{obj}: {key}')
|
||||
|
||||
|
||||
def release_resources(next_task=''):
|
||||
# Release all OCR models
|
||||
# det models take 400MB
|
||||
if not next_task:
|
||||
from module.ocr.models import OCR_MODEL
|
||||
OCR_MODEL.resource_release()
|
||||
|
||||
# Release assets cache
|
||||
# module.ui has about 80 assets and takes about 3MB
|
||||
# Alas has about 800 assets, but they are not all loaded.
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
"value": "auto",
|
||||
"option": [
|
||||
"auto",
|
||||
"JP-Official",
|
||||
"OVERSEA-Global"
|
||||
"JP-Official"
|
||||
]
|
||||
},
|
||||
"GameLanguage": {
|
||||
@@ -20,8 +19,7 @@
|
||||
"value": "auto",
|
||||
"option": [
|
||||
"auto",
|
||||
"jp",
|
||||
"en"
|
||||
"jp"
|
||||
]
|
||||
},
|
||||
"ScreenshotMethod": {
|
||||
@@ -257,191 +255,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Bounty": {
|
||||
"Scheduler": {
|
||||
"Enable": {
|
||||
"type": "checkbox",
|
||||
"value": true,
|
||||
"option": [
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"NextRun": {
|
||||
"type": "datetime",
|
||||
"value": "2020-01-01 00:00:00",
|
||||
"validate": "datetime"
|
||||
},
|
||||
"Command": {
|
||||
"type": "input",
|
||||
"value": "Bounty",
|
||||
"display": "hide"
|
||||
},
|
||||
"ServerUpdate": {
|
||||
"type": "input",
|
||||
"value": "04:00",
|
||||
"display": "hide"
|
||||
}
|
||||
},
|
||||
"Bounty": {
|
||||
"OnError": {
|
||||
"type": "select",
|
||||
"value": "skip",
|
||||
"option": [
|
||||
"stop",
|
||||
"skip"
|
||||
]
|
||||
}
|
||||
},
|
||||
"Highway": {
|
||||
"Stage": {
|
||||
"type": "select",
|
||||
"value": 1,
|
||||
"option": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
]
|
||||
},
|
||||
"Count": {
|
||||
"type": "input",
|
||||
"value": 2
|
||||
}
|
||||
},
|
||||
"DesertRailroad": {
|
||||
"Stage": {
|
||||
"type": "select",
|
||||
"value": 1,
|
||||
"option": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
]
|
||||
},
|
||||
"Count": {
|
||||
"type": "input",
|
||||
"value": 2
|
||||
}
|
||||
},
|
||||
"Schoolhouse": {
|
||||
"Stage": {
|
||||
"type": "select",
|
||||
"value": 1,
|
||||
"option": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9
|
||||
]
|
||||
},
|
||||
"Count": {
|
||||
"type": "input",
|
||||
"value": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"Scrimmage": {
|
||||
"Scheduler": {
|
||||
"Enable": {
|
||||
"type": "checkbox",
|
||||
"value": true,
|
||||
"option": [
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"NextRun": {
|
||||
"type": "datetime",
|
||||
"value": "2020-01-01 00:00:00",
|
||||
"validate": "datetime"
|
||||
},
|
||||
"Command": {
|
||||
"type": "input",
|
||||
"value": "Scrimmage",
|
||||
"display": "hide"
|
||||
},
|
||||
"ServerUpdate": {
|
||||
"type": "input",
|
||||
"value": "04:00",
|
||||
"display": "hide"
|
||||
}
|
||||
},
|
||||
"Scrimmage": {
|
||||
"OnError": {
|
||||
"type": "select",
|
||||
"value": "skip",
|
||||
"option": [
|
||||
"stop",
|
||||
"skip"
|
||||
]
|
||||
}
|
||||
},
|
||||
"Trinity": {
|
||||
"Stage": {
|
||||
"type": "select",
|
||||
"value": 1,
|
||||
"option": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4
|
||||
]
|
||||
},
|
||||
"Count": {
|
||||
"type": "input",
|
||||
"value": 2
|
||||
}
|
||||
},
|
||||
"Gehenna": {
|
||||
"Stage": {
|
||||
"type": "select",
|
||||
"value": 1,
|
||||
"option": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4
|
||||
]
|
||||
},
|
||||
"Count": {
|
||||
"type": "input",
|
||||
"value": 2
|
||||
}
|
||||
},
|
||||
"Millennium": {
|
||||
"Stage": {
|
||||
"type": "select",
|
||||
"value": 1,
|
||||
"option": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4
|
||||
]
|
||||
},
|
||||
"Count": {
|
||||
"type": "input",
|
||||
"value": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"TacticalChallenge": {
|
||||
"Scheduler": {
|
||||
"Enable": {
|
||||
@@ -533,30 +346,6 @@
|
||||
"stored": "StoredInt",
|
||||
"order": 3,
|
||||
"color": "#21befc"
|
||||
},
|
||||
"BountyTicket": {
|
||||
"type": "stored",
|
||||
"value": {},
|
||||
"display": "hide",
|
||||
"stored": "StoredBountyTicket",
|
||||
"order": 4,
|
||||
"color": "#94cb44"
|
||||
},
|
||||
"ScrimmageTicket": {
|
||||
"type": "stored",
|
||||
"value": {},
|
||||
"display": "hide",
|
||||
"stored": "StoredScrimmageTicket",
|
||||
"order": 5,
|
||||
"color": "#f86c6a"
|
||||
},
|
||||
"TacticalChallengeTicket": {
|
||||
"type": "stored",
|
||||
"value": {},
|
||||
"display": "hide",
|
||||
"stored": "StoredTacticalChallengeTicket",
|
||||
"order": 6,
|
||||
"color": "#7ac8e5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ Emulator:
|
||||
option: [ auto, ]
|
||||
GameLanguage:
|
||||
value: auto
|
||||
option: [ auto, jp, en ]
|
||||
option: [ auto, jp ]
|
||||
ScreenshotMethod:
|
||||
value: auto
|
||||
option: [ auto, ADB, ADB_nc, uiautomator2, aScreenCap, aScreenCap_nc, DroidCast, DroidCast_raw, scrcpy ]
|
||||
@@ -81,48 +81,6 @@ Cafe:
|
||||
AutoAdjust: true
|
||||
SecondCafe: true
|
||||
|
||||
Bounty:
|
||||
OnError:
|
||||
value: skip
|
||||
option: [ stop, skip ]
|
||||
|
||||
Highway:
|
||||
Stage:
|
||||
value: 1
|
||||
option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
||||
Count: 2
|
||||
DesertRailroad:
|
||||
Stage:
|
||||
value: 1
|
||||
option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
||||
Count: 2
|
||||
Schoolhouse:
|
||||
Stage:
|
||||
value: 1
|
||||
option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
|
||||
Count: 2
|
||||
|
||||
Scrimmage:
|
||||
OnError:
|
||||
value: skip
|
||||
option: [ stop, skip ]
|
||||
|
||||
Trinity:
|
||||
Stage:
|
||||
value: 1
|
||||
option: [ 1, 2, 3, 4 ]
|
||||
Count: 2
|
||||
Gehenna:
|
||||
Stage:
|
||||
value: 1
|
||||
option: [ 1, 2, 3, 4 ]
|
||||
Count: 2
|
||||
Millennium:
|
||||
Stage:
|
||||
value: 1
|
||||
option: [ 1, 2, 3, 4 ]
|
||||
Count: 2
|
||||
|
||||
TacticalChallenge:
|
||||
PlayerSelect:
|
||||
value: 0
|
||||
@@ -141,15 +99,3 @@ ItemStorage:
|
||||
stored: StoredInt
|
||||
order: 3
|
||||
color: "#21befc"
|
||||
BountyTicket:
|
||||
stored: StoredBountyTicket
|
||||
order: 4
|
||||
color: "#94cb44"
|
||||
ScrimmageTicket:
|
||||
stored: StoredScrimmageTicket
|
||||
order: 5
|
||||
color: "#f86c6a"
|
||||
TacticalChallengeTicket:
|
||||
stored: StoredTacticalChallengeTicket
|
||||
order: 6
|
||||
color: "#7ac8e5"
|
||||
|
||||
@@ -13,12 +13,6 @@ Mail:
|
||||
Circle:
|
||||
Scheduler:
|
||||
Enable: true
|
||||
Bounty:
|
||||
Scheduler:
|
||||
Enable: true
|
||||
Scrimmage:
|
||||
Scheduler:
|
||||
Enable: true
|
||||
TacticalChallenge:
|
||||
Scheduler:
|
||||
Enable: true
|
||||
@@ -14,8 +14,6 @@
|
||||
"Cafe",
|
||||
"Mail",
|
||||
"Circle",
|
||||
"Bounty",
|
||||
"Scrimmage",
|
||||
"TacticalChallenge",
|
||||
"DataUpdate"
|
||||
]
|
||||
|
||||
@@ -35,44 +35,5 @@
|
||||
},
|
||||
"order": 3,
|
||||
"color": "#21befc"
|
||||
},
|
||||
"BountyTicket": {
|
||||
"name": "BountyTicket",
|
||||
"path": "DataUpdate.ItemStorage.BountyTicket",
|
||||
"i18n": "ItemStorage.BountyTicket.name",
|
||||
"stored": "StoredBountyTicket",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00",
|
||||
"total": 6,
|
||||
"value": 0
|
||||
},
|
||||
"order": 4,
|
||||
"color": "#94cb44"
|
||||
},
|
||||
"ScrimmageTicket": {
|
||||
"name": "ScrimmageTicket",
|
||||
"path": "DataUpdate.ItemStorage.ScrimmageTicket",
|
||||
"i18n": "ItemStorage.ScrimmageTicket.name",
|
||||
"stored": "StoredScrimmageTicket",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00",
|
||||
"total": 6,
|
||||
"value": 0
|
||||
},
|
||||
"order": 5,
|
||||
"color": "#f86c6a"
|
||||
},
|
||||
"TacticalChallengeTicket": {
|
||||
"name": "TacticalChallengeTicket",
|
||||
"path": "DataUpdate.ItemStorage.TacticalChallengeTicket",
|
||||
"i18n": "ItemStorage.TacticalChallengeTicket.name",
|
||||
"stored": "StoredTacticalChallengeTicket",
|
||||
"attrs": {
|
||||
"time": "2020-01-01 00:00:00",
|
||||
"total": 5,
|
||||
"value": 0
|
||||
},
|
||||
"order": 6,
|
||||
"color": "#7ac8e5"
|
||||
}
|
||||
}
|
||||
@@ -29,18 +29,6 @@ Daily:
|
||||
- Scheduler
|
||||
Circle:
|
||||
- Scheduler
|
||||
Bounty:
|
||||
- Scheduler
|
||||
- Bounty
|
||||
- Highway
|
||||
- DesertRailroad
|
||||
- Schoolhouse
|
||||
Scrimmage:
|
||||
- Scheduler
|
||||
- Scrimmage
|
||||
- Trinity
|
||||
- Gehenna
|
||||
- Millennium
|
||||
TacticalChallenge:
|
||||
- Scheduler
|
||||
- TacticalChallenge
|
||||
|
||||
@@ -499,6 +499,19 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher
|
||||
self.task_call('DailyQuest')
|
||||
self.task_stop()
|
||||
|
||||
def update_battle_pass_quests(self):
|
||||
"""
|
||||
Raises:
|
||||
TaskEnd: Call task `BattlePass` and stop current task
|
||||
"""
|
||||
if self.stored.BattlePassTodayQuest.is_expired():
|
||||
if self.stored.BattlePassLevel.is_full():
|
||||
logger.info('BattlePassLevel full, no updates')
|
||||
else:
|
||||
logger.info('BattlePassTodayQuest expired, call task to update')
|
||||
self.task_call('BattlePass')
|
||||
self.task_stop()
|
||||
|
||||
@property
|
||||
def DEVICE_SCREENSHOT_METHOD(self):
|
||||
return self.Emulator_ScreenshotMethod
|
||||
|
||||
@@ -17,8 +17,8 @@ class GeneratedConfig:
|
||||
|
||||
# Group `Emulator`
|
||||
Emulator_Serial = 'auto'
|
||||
Emulator_PackageName = 'auto' # auto, JP-Official, OVERSEA-Global
|
||||
Emulator_GameLanguage = 'auto' # auto, jp, en
|
||||
Emulator_PackageName = 'auto' # auto, JP-Official
|
||||
Emulator_GameLanguage = 'auto' # auto, jp
|
||||
Emulator_ScreenshotMethod = 'auto' # auto, ADB, ADB_nc, uiautomator2, aScreenCap, aScreenCap_nc, DroidCast, DroidCast_raw, scrcpy
|
||||
Emulator_ControlMethod = 'MaaTouch' # minitouch, MaaTouch
|
||||
Emulator_AdbRestart = False
|
||||
@@ -45,36 +45,6 @@ class GeneratedConfig:
|
||||
Cafe_AutoAdjust = True
|
||||
Cafe_SecondCafe = True
|
||||
|
||||
# Group `Bounty`
|
||||
Bounty_OnError = 'skip' # stop, skip
|
||||
|
||||
# Group `Highway`
|
||||
Highway_Stage = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
Highway_Count = 2
|
||||
|
||||
# Group `DesertRailroad`
|
||||
DesertRailroad_Stage = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
DesertRailroad_Count = 2
|
||||
|
||||
# Group `Schoolhouse`
|
||||
Schoolhouse_Stage = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
Schoolhouse_Count = 2
|
||||
|
||||
# Group `Scrimmage`
|
||||
Scrimmage_OnError = 'skip' # stop, skip
|
||||
|
||||
# Group `Trinity`
|
||||
Trinity_Stage = 1 # 1, 2, 3, 4
|
||||
Trinity_Count = 2
|
||||
|
||||
# Group `Gehenna`
|
||||
Gehenna_Stage = 1 # 1, 2, 3, 4
|
||||
Gehenna_Count = 2
|
||||
|
||||
# Group `Millennium`
|
||||
Millennium_Stage = 1 # 1, 2, 3, 4
|
||||
Millennium_Count = 2
|
||||
|
||||
# Group `TacticalChallenge`
|
||||
TacticalChallenge_PlayerSelect = 0 # 0, 1, 2, 3
|
||||
|
||||
@@ -82,6 +52,3 @@ class GeneratedConfig:
|
||||
ItemStorage_AP = {}
|
||||
ItemStorage_Credit = {}
|
||||
ItemStorage_Pyroxene = {}
|
||||
ItemStorage_BountyTicket = {}
|
||||
ItemStorage_ScrimmageTicket = {}
|
||||
ItemStorage_TacticalChallengeTicket = {}
|
||||
|
||||
@@ -8,8 +8,7 @@ class ManualConfig:
|
||||
|
||||
SCHEDULER_PRIORITY = """
|
||||
Restart
|
||||
> Cafe > Circle > Mail > DataUpdate > Bounty
|
||||
> Scrimmage > TacticalChallenge
|
||||
> Cafe > Circle > Mail > DataUpdate > TacticalChallenge
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
@@ -458,8 +458,7 @@ class ConfigUpdater:
|
||||
value = deep_get(old, keys=keys, default=data['value'])
|
||||
typ = data['type']
|
||||
display = data.get('display')
|
||||
if (is_template or value is None or value == ''
|
||||
or typ in ['lock', 'state'] or (display == 'hide' and typ != 'stored')):
|
||||
if is_template or value is None or value == '' or typ == 'lock' or (display == 'hide' and typ != 'stored'):
|
||||
value = data['value']
|
||||
value = parse_value(value, data=data)
|
||||
deep_set(new, keys=keys, value=value)
|
||||
|
||||
@@ -30,14 +30,6 @@
|
||||
"name": "Club",
|
||||
"help": ""
|
||||
},
|
||||
"Bounty": {
|
||||
"name": "Bounty",
|
||||
"help": ""
|
||||
},
|
||||
"Scrimmage": {
|
||||
"name": "Scrimmage",
|
||||
"help": ""
|
||||
},
|
||||
"TacticalChallenge": {
|
||||
"name": "Tactical Challenge",
|
||||
"help": ""
|
||||
@@ -84,21 +76,19 @@
|
||||
"name": "Game Server",
|
||||
"help": "Can't distinguish different regions of oversea servers, please select the server manually.",
|
||||
"auto": "Auto-detect",
|
||||
"JP-Official": "[JP]-Official",
|
||||
"OVERSEA-Global": "[OVERSEA]-Global"
|
||||
"JP-Official": "[JP]-Official"
|
||||
},
|
||||
"GameLanguage": {
|
||||
"name": "In-game Text Language",
|
||||
"help": "",
|
||||
"help": "Currently, only Simplified Chinese and English are supported. Please set the text language in game to one of them.",
|
||||
"auto": "Auto-detect",
|
||||
"jp": "Japanese",
|
||||
"en": "English"
|
||||
"jp": "Japanese"
|
||||
},
|
||||
"ScreenshotMethod": {
|
||||
"name": "Screenshot Method",
|
||||
"help": "When using auto-select, a benchmark will be performed and automatically changed to the fastest screenshot method.\nGeneral speed: DroidCast_raw >> aScreenCap_nc > ADB_nc >>> aScreenCap > uiautomator2 ~= ADB.\nRun Tools - Performance Test to find the fastest method.",
|
||||
"auto": "Auto-select the fastest",
|
||||
"ADB": "ADB",
|
||||
"ADB": "ADB ",
|
||||
"ADB_nc": "ADB_nc",
|
||||
"uiautomator2": "uiautomator2",
|
||||
"aScreenCap": "aScreenCap",
|
||||
@@ -213,155 +203,8 @@
|
||||
"help": "Auto adjust cafe interface for better student interaction"
|
||||
},
|
||||
"SecondCafe": {
|
||||
"name": "Second Floor",
|
||||
"help": "JP server only\nEnable auto switch to second floor and perform interaction"
|
||||
}
|
||||
},
|
||||
"Bounty": {
|
||||
"_info": {
|
||||
"name": "Bounty Settings",
|
||||
"help": ""
|
||||
},
|
||||
"OnError": {
|
||||
"name": "Error Handling",
|
||||
"help": "Perform the selected action when an error occurs (ticket not enough or any invalid setting)",
|
||||
"stop": "Stop script",
|
||||
"skip": "Skip current task"
|
||||
}
|
||||
},
|
||||
"Highway": {
|
||||
"_info": {
|
||||
"name": "Overpass",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "Select Stage",
|
||||
"help": "",
|
||||
"1": "01 - Overpass A",
|
||||
"2": "02 - Overpass B",
|
||||
"3": "03 - Overpass C",
|
||||
"4": "04 - Overpass D",
|
||||
"5": "05 - Overpass E",
|
||||
"6": "06 - Overpass F",
|
||||
"7": "07 - Overpass G",
|
||||
"8": "08 - Overpass H",
|
||||
"9": "09 - Overpass I"
|
||||
},
|
||||
"Count": {
|
||||
"name": "Sweep X times",
|
||||
"help": "Sweep the selected stage for X times"
|
||||
}
|
||||
},
|
||||
"DesertRailroad": {
|
||||
"_info": {
|
||||
"name": "Desert Railroad",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "Select Stage",
|
||||
"help": "",
|
||||
"1": "01 - Abandoned Train A",
|
||||
"2": "02 - Abandoned Train B",
|
||||
"3": "03 - Abandoned Train C",
|
||||
"4": "04 - Abandoned Train D",
|
||||
"5": "05 - Abandoned Train E",
|
||||
"6": "06 - Abandoned Train F",
|
||||
"7": "07 - Abandoned Train G",
|
||||
"8": "08 - Abandoned Train H",
|
||||
"9": "09 - Abandoned Train I"
|
||||
},
|
||||
"Count": {
|
||||
"name": "Sweep X times",
|
||||
"help": "Sweep the selected stage for X times"
|
||||
}
|
||||
},
|
||||
"Schoolhouse": {
|
||||
"_info": {
|
||||
"name": "Classroom",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "Select Stage",
|
||||
"help": "",
|
||||
"1": "01 - Besieged Classroom A",
|
||||
"2": "02 - Besieged Classroom B",
|
||||
"3": "03 - Besieged Classroom C",
|
||||
"4": "04 - Besieged Classroom D",
|
||||
"5": "05 - Besieged Classroom E",
|
||||
"6": "06 - Besieged Classroom F",
|
||||
"7": "07 - Besieged Classroom G",
|
||||
"8": "08 - Besieged Classroom H",
|
||||
"9": "09 - Besieged Classroom I"
|
||||
},
|
||||
"Count": {
|
||||
"name": "Sweep X times",
|
||||
"help": "Sweep the selected stage for X times"
|
||||
}
|
||||
},
|
||||
"Scrimmage": {
|
||||
"_info": {
|
||||
"name": "Scrimmage Settings",
|
||||
"help": ""
|
||||
},
|
||||
"OnError": {
|
||||
"name": "Error Handling",
|
||||
"help": "Perform the selected action when an error occurs (ticket not enough or any invalid setting)",
|
||||
"stop": "Stop script",
|
||||
"skip": "Skip current task"
|
||||
}
|
||||
},
|
||||
"Trinity": {
|
||||
"_info": {
|
||||
"name": "Trinity",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "Select Stage",
|
||||
"help": "",
|
||||
"1": "01 - Trinity A",
|
||||
"2": "02 - Trinity B",
|
||||
"3": "03 - Trinity C",
|
||||
"4": "04 - Trinity D"
|
||||
},
|
||||
"Count": {
|
||||
"name": "Sweep X times",
|
||||
"help": "Sweep the selected stage for X times"
|
||||
}
|
||||
},
|
||||
"Gehenna": {
|
||||
"_info": {
|
||||
"name": "Gehenna",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "Select Stage",
|
||||
"help": "",
|
||||
"1": "01 - Gehenna A",
|
||||
"2": "02 - Gehenna B",
|
||||
"3": "03 - Gehenna C",
|
||||
"4": "04 - Gehenna D"
|
||||
},
|
||||
"Count": {
|
||||
"name": "Sweep X times",
|
||||
"help": "Sweep the selected stage for X times"
|
||||
}
|
||||
},
|
||||
"Millennium": {
|
||||
"_info": {
|
||||
"name": "Millennium",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "Select Stage",
|
||||
"help": "",
|
||||
"1": "01 - Millennium A",
|
||||
"2": "02 - Millennium B",
|
||||
"3": "03 - Millennium C",
|
||||
"4": "04 - Millennium D"
|
||||
},
|
||||
"Count": {
|
||||
"name": "Sweep X times",
|
||||
"help": "Sweep the selected stage for X times"
|
||||
"name": "Second Cafe",
|
||||
"help": "Enable auto switch to second cafe and perform interaction"
|
||||
}
|
||||
},
|
||||
"TacticalChallenge": {
|
||||
@@ -394,18 +237,6 @@
|
||||
"Pyroxene": {
|
||||
"name": "Pyroxene",
|
||||
"help": ""
|
||||
},
|
||||
"BountyTicket": {
|
||||
"name": "Bounty",
|
||||
"help": ""
|
||||
},
|
||||
"ScrimmageTicket": {
|
||||
"name": "Scrimmage",
|
||||
"help": ""
|
||||
},
|
||||
"TacticalChallengeTicket": {
|
||||
"name": "Tactical Challenge",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Gui": {
|
||||
|
||||
@@ -30,14 +30,6 @@
|
||||
"name": "公会",
|
||||
"help": "社团 / 小组"
|
||||
},
|
||||
"Bounty": {
|
||||
"name": "悬赏通缉",
|
||||
"help": ""
|
||||
},
|
||||
"Scrimmage": {
|
||||
"name": "学院交流会",
|
||||
"help": ""
|
||||
},
|
||||
"TacticalChallenge": {
|
||||
"name": "战术对抗赛",
|
||||
"help": "战术大赛 / 竞技场"
|
||||
@@ -84,15 +76,13 @@
|
||||
"name": "游戏服务器",
|
||||
"help": "无法区分国际服的不同地区,请手动选择服务器",
|
||||
"auto": "自动检测",
|
||||
"JP-Official": "[日服]-官服",
|
||||
"OVERSEA-Global": "[国际服]-全球"
|
||||
"JP-Official": "[日服]-官服"
|
||||
},
|
||||
"GameLanguage": {
|
||||
"name": "游戏内文本语言",
|
||||
"help": "",
|
||||
"auto": "自动检测",
|
||||
"jp": "日语",
|
||||
"en": "英语"
|
||||
"jp": "日语"
|
||||
},
|
||||
"ScreenshotMethod": {
|
||||
"name": "模拟器截图方案",
|
||||
@@ -214,154 +204,7 @@
|
||||
},
|
||||
"SecondCafe": {
|
||||
"name": "第二咖啡厅",
|
||||
"help": "仅支持日服\n自动切换第二咖啡厅进行互动点击"
|
||||
}
|
||||
},
|
||||
"Bounty": {
|
||||
"_info": {
|
||||
"name": "悬赏通缉设置",
|
||||
"help": ""
|
||||
},
|
||||
"OnError": {
|
||||
"name": "错误处理",
|
||||
"help": "当出现票券不足或设置有误等错误时,执行该操作",
|
||||
"stop": "停止脚本运行",
|
||||
"skip": "跳过当前任务"
|
||||
}
|
||||
},
|
||||
"Highway": {
|
||||
"_info": {
|
||||
"name": "高架公路",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "选择关卡",
|
||||
"help": "",
|
||||
"1": "01 - 高架公路 A",
|
||||
"2": "02 - 高架公路 B",
|
||||
"3": "03 - 高架公路 C",
|
||||
"4": "04 - 高架公路 D",
|
||||
"5": "05 - 高架公路 E",
|
||||
"6": "06 - 高架公路 F",
|
||||
"7": "07 - 高架公路 G",
|
||||
"8": "08 - 高架公路 H",
|
||||
"9": "09 - 高架公路 I"
|
||||
},
|
||||
"Count": {
|
||||
"name": "扫荡次数",
|
||||
"help": "扫荡所选择关卡 X 次"
|
||||
}
|
||||
},
|
||||
"DesertRailroad": {
|
||||
"_info": {
|
||||
"name": "沙漠铁路",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "选择关卡",
|
||||
"help": "",
|
||||
"1": "01 - 被遗弃的列车 A",
|
||||
"2": "02 - 被遗弃的列车 B",
|
||||
"3": "03 - 被遗弃的列车 C",
|
||||
"4": "04 - 被遗弃的列车 D",
|
||||
"5": "05 - 被遗弃的列车 E",
|
||||
"6": "06 - 被遗弃的列车 F",
|
||||
"7": "07 - 被遗弃的列车 G",
|
||||
"8": "08 - 被遗弃的列车 H",
|
||||
"9": "09 - 被遗弃的列车 I"
|
||||
},
|
||||
"Count": {
|
||||
"name": "扫荡次数",
|
||||
"help": "扫荡所选择关卡 X 次"
|
||||
}
|
||||
},
|
||||
"Schoolhouse": {
|
||||
"_info": {
|
||||
"name": "教室",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "选择关卡",
|
||||
"help": "",
|
||||
"1": "01 - 被袭击的教室 A",
|
||||
"2": "02 - 被袭击的教室 B",
|
||||
"3": "03 - 被袭击的教室 C",
|
||||
"4": "04 - 被袭击的教室 D",
|
||||
"5": "05 - 被袭击的教室 E",
|
||||
"6": "06 - 被袭击的教室 F",
|
||||
"7": "07 - 被袭击的教室 G",
|
||||
"8": "08 - 被袭击的教室 H",
|
||||
"9": "09 - 被袭击的教室 I"
|
||||
},
|
||||
"Count": {
|
||||
"name": "扫荡次数",
|
||||
"help": "扫荡所选择关卡 X 次"
|
||||
}
|
||||
},
|
||||
"Scrimmage": {
|
||||
"_info": {
|
||||
"name": "学院交流会设置",
|
||||
"help": ""
|
||||
},
|
||||
"OnError": {
|
||||
"name": "错误处理",
|
||||
"help": "当出现票券不足或设置有误等错误时,执行该操作",
|
||||
"stop": "停止脚本运行",
|
||||
"skip": "跳过当前任务"
|
||||
}
|
||||
},
|
||||
"Trinity": {
|
||||
"_info": {
|
||||
"name": "三一",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "选择关卡",
|
||||
"help": "",
|
||||
"1": "01 - 三一 A",
|
||||
"2": "02 - 三一 B",
|
||||
"3": "03 - 三一 C",
|
||||
"4": "04 - 三一 D"
|
||||
},
|
||||
"Count": {
|
||||
"name": "扫荡次数",
|
||||
"help": "扫荡所选择关卡 X 次"
|
||||
}
|
||||
},
|
||||
"Gehenna": {
|
||||
"_info": {
|
||||
"name": "格黑娜",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "选择关卡",
|
||||
"help": "",
|
||||
"1": "01 - 格黑娜 A",
|
||||
"2": "02 - 格黑娜 B",
|
||||
"3": "03 - 格黑娜 C",
|
||||
"4": "04 - 格黑娜 D"
|
||||
},
|
||||
"Count": {
|
||||
"name": "扫荡次数",
|
||||
"help": "扫荡所选择关卡 X 次"
|
||||
}
|
||||
},
|
||||
"Millennium": {
|
||||
"_info": {
|
||||
"name": "千年",
|
||||
"help": ""
|
||||
},
|
||||
"Stage": {
|
||||
"name": "选择关卡",
|
||||
"help": "",
|
||||
"1": "01 - 千年 A",
|
||||
"2": "02 - 千年 B",
|
||||
"3": "03 - 千年 C",
|
||||
"4": "04 - 千年 D"
|
||||
},
|
||||
"Count": {
|
||||
"name": "扫荡次数",
|
||||
"help": "扫荡所选择关卡 X 次"
|
||||
"help": "自动切换第二咖啡厅进行互动点击"
|
||||
}
|
||||
},
|
||||
"TacticalChallenge": {
|
||||
@@ -394,18 +237,6 @@
|
||||
"Pyroxene": {
|
||||
"name": "青辉石",
|
||||
"help": ""
|
||||
},
|
||||
"BountyTicket": {
|
||||
"name": "悬赏通缉",
|
||||
"help": ""
|
||||
},
|
||||
"ScrimmageTicket": {
|
||||
"name": "学院交流会",
|
||||
"help": ""
|
||||
},
|
||||
"TacticalChallengeTicket": {
|
||||
"name": "战术对抗赛",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"Gui": {
|
||||
|
||||
@@ -5,10 +5,9 @@ Use 'import module.config.server as server' to import, don't use 'from xxx impor
|
||||
lang = 'jp' # Setting default to cn, will avoid errors when using dev_tools
|
||||
server = 'JP-Official'
|
||||
|
||||
VALID_LANG = ['jp', 'en']
|
||||
VALID_LANG = ['jp']
|
||||
VALID_SERVER = {
|
||||
'JP-Official': 'com.YostarJP.BlueArchive',
|
||||
'OVERSEA-Global': 'com.nexon.bluearchive',
|
||||
'JP-Official': 'com.YostarJP.BlueArchive'
|
||||
}
|
||||
VALID_PACKAGE = set(list(VALID_SERVER.values()))
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ from functools import cached_property as functools_cached_property
|
||||
|
||||
from module.base.decorator import cached_property
|
||||
from module.config.utils import DEFAULT_TIME, deep_get, get_server_last_monday_update, get_server_last_update
|
||||
|
||||
|
||||
# from module.exception import ScriptError
|
||||
|
||||
|
||||
@@ -175,20 +173,6 @@ class StoredCounter(StoredBase):
|
||||
class StoredAP(StoredCounter):
|
||||
pass
|
||||
|
||||
|
||||
class StoredBountyTicket(StoredCounter, StoredExpiredAt0400):
|
||||
FIXED_TOTAL = 6
|
||||
pass
|
||||
|
||||
|
||||
class StoredScrimmageTicket(StoredCounter, StoredExpiredAt0400):
|
||||
FIXED_TOTAL = 6
|
||||
|
||||
|
||||
class StoredTacticalChallengeTicket(StoredCounter, StoredExpiredAt0400):
|
||||
FIXED_TOTAL = 5
|
||||
|
||||
|
||||
# class StoredDailyActivity(StoredCounter, StoredExpiredAt0400):
|
||||
# FIXED_TOTAL = 500
|
||||
#
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from module.config.stored.classes import (
|
||||
StoredAP,
|
||||
StoredBountyTicket,
|
||||
StoredBase,
|
||||
StoredCounter,
|
||||
StoredExpiredAt0400,
|
||||
StoredExpiredAtMonday0400,
|
||||
StoredInt,
|
||||
StoredScrimmageTicket,
|
||||
StoredTacticalChallengeTicket,
|
||||
)
|
||||
|
||||
|
||||
@@ -14,6 +15,3 @@ class StoredGenerated:
|
||||
AP = StoredAP("DataUpdate.ItemStorage.AP")
|
||||
Credit = StoredInt("DataUpdate.ItemStorage.Credit")
|
||||
Pyroxene = StoredInt("DataUpdate.ItemStorage.Pyroxene")
|
||||
BountyTicket = StoredBountyTicket("DataUpdate.ItemStorage.BountyTicket")
|
||||
ScrimmageTicket = StoredScrimmageTicket("DataUpdate.ItemStorage.ScrimmageTicket")
|
||||
TacticalChallengeTicket = StoredTacticalChallengeTicket("DataUpdate.ItemStorage.TacticalChallengeTicket")
|
||||
|
||||
@@ -13,7 +13,6 @@ from module.config.atomicwrites import atomic_write
|
||||
LANGUAGES = ['zh-CN', 'en-US']
|
||||
SERVER_TO_TIMEZONE = {
|
||||
'JP-Official': timedelta(hours=9),
|
||||
'OVERSEA-Global': timedelta(hours=0),
|
||||
}
|
||||
DEFAULT_TIME = datetime(2020, 1, 1, 0, 0)
|
||||
|
||||
|
||||
@@ -863,8 +863,8 @@ class Connection(ConnectionAttr):
|
||||
|
||||
# Auto package detection
|
||||
if len(packages) == 0:
|
||||
logger.critical(f'No Blue Archive package found, '
|
||||
f'please confirm Blue Archive has been installed on device "{self.serial}"')
|
||||
logger.critical(f'No Star Rail package found, '
|
||||
f'please confirm Star Rail has been installed on device "{self.serial}"')
|
||||
raise RequestHumanTakeover
|
||||
if len(packages) == 1:
|
||||
logger.info('Auto package detection found only one package, using it')
|
||||
@@ -877,6 +877,6 @@ class Connection(ConnectionAttr):
|
||||
# set_server(self.package)
|
||||
else:
|
||||
logger.critical(
|
||||
f'Multiple Blue Archive packages found, auto package detection cannot decide which to choose, '
|
||||
f'Multiple Star Rail packages found, auto package detection cannot decide which to choose, '
|
||||
'please copy one of the available devices listed above to Alas.Emulator.PackageName')
|
||||
raise RequestHumanTakeover
|
||||
|
||||