1
0
mirror of https://github.com/TheFunny/ArisuAutoSweeper synced 2026-06-29 12:54:52 +00:00

2 Commits

Author SHA1 Message Date
RedDeadDepresso 5feb46040c added more images 2023-11-12 22:44:09 +00:00
RedDeadDepresso bc920f065d added en folder 2023-11-12 21:30:23 +00:00
129 changed files with 202 additions and 2782 deletions
+3 -10
View File
@@ -12,17 +12,12 @@
The script is still under active development. The following features have been implemented: The script is still under active development. The following features have been implemented:
- [x] **Cafe** Claim rewards / Interact / Second floor - [x] **Cafe** Claim rewards / Interact / Second cafe
- [x] **Club** Claim AP - [x] **Circle** Claim AP
- [x] **Mailbox** Claim rewards - [x] **Mailbox** Claim rewards
- [x] **Bounty** Auto sweep
- [x] **Scrimmage** Auto sweep
- [x] **Tactical Challenge** Claim rewards / Auto battle - [x] **Tactical Challenge** Claim rewards / Auto battle
Supported servers: _Currently only supports JP server._
- [x] JP
- [x] OVERSEA - Global
## Relative projects ## 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) Thanks to [Alas](https://github.com/LmeSzinc/AzurLaneAutoScript) and [SRC](https://github.com/LmeSzinc/StarRailCopilot)
for the development framework. for the development framework.
Thanks to [RedDeadDepresso](https://github.com/RedDeadDepresso) for EN support.
+1 -16
View File
@@ -15,22 +15,9 @@
- [x] **咖啡厅** 领取奖励 / 互动 / 第二咖啡厅 - [x] **咖啡厅** 领取奖励 / 互动 / 第二咖啡厅
- [x] **公会** 领取体力 - [x] **公会** 领取体力
- [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) 感谢 [Alas](https://github.com/LmeSzinc/AzurLaneAutoScript) 以及 [SRC](https://github.com/LmeSzinc/StarRailCopilot)
提供的开发框架。 提供的开发框架。
感谢 [RedDeadDepresso](https://github.com/RedDeadDepresso) 提供英语支持。
-8
View File
@@ -34,14 +34,6 @@ class ArisuAutoSweeper(AzurLaneAutoScript):
from tasks.mail.mail import Mail from tasks.mail.mail import Mail
Mail(config=self.config, device=self.device).run() 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): def tactical_challenge(self):
from tasks.tactical_challenge.tactical_challenge import TacticalChallenge from tasks.tactical_challenge.tactical_challenge import TacticalChallenge
TacticalChallenge(config=self.config, device=self.device).run() TacticalChallenge(config=self.config, device=self.device).run()
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

+1 -1
View File
@@ -285,7 +285,7 @@ pre.rich-traceback-code {
*[style*="--header-icon--"] { *[style*="--header-icon--"] {
margin: .25rem auto .25rem; margin: .25rem auto .25rem;
border-radius: 1.5rem; border-radius: 1.5rem;
height: 3em; height: 3.5em;
} }
*[style*="--header-text--"] { *[style*="--header-text--"] {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

+2 -2
View File
@@ -1,8 +1,8 @@
Deploy: Deploy:
Git: Git:
# URL of AzurLaneAutoScript repository # URL of AzurLaneAutoScript repository
# [CN user] Use 'cn' to get update from self-hosted git service # [CN user] Use 'cn' to get update from git-over-cdn service
# [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSweeper # [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSrcipt
Repository: cn Repository: cn
# Branch of Alas # Branch of Alas
# [Developer] Use 'dev', 'app', etc, to try new features # [Developer] Use 'dev', 'app', etc, to try new features
+2 -2
View File
@@ -1,8 +1,8 @@
Deploy: Deploy:
Git: Git:
# URL of AzurLaneAutoScript repository # URL of AzurLaneAutoScript repository
# [CN user] Use 'cn' to get update from self-hosted git service # [CN user] Use 'cn' to get update from git-over-cdn service
# [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSweeper # [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSrcipt
Repository: global Repository: global
# Branch of Alas # Branch of Alas
# [Developer] Use 'dev', 'app', etc, to try new features # [Developer] Use 'dev', 'app', etc, to try new features
+1 -50
View File
@@ -63,52 +63,6 @@
"ServerUpdate": "04:00" "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": { "TacticalChallenge": {
"Scheduler": { "Scheduler": {
"Enable": true, "Enable": true,
@@ -130,10 +84,7 @@
"ItemStorage": { "ItemStorage": {
"AP": {}, "AP": {},
"Credit": {}, "Credit": {},
"Pyroxene": {}, "Pyroxene": {}
"BountyTicket": {},
"ScrimmageTicket": {},
"TacticalChallengeTicket": {}
} }
} }
} }
+2 -2
View File
@@ -1,8 +1,8 @@
Deploy: Deploy:
Git: Git:
# URL of AzurLaneAutoScript repository # URL of AzurLaneAutoScript repository
# [CN user] Use 'cn' to get update from self-hosted git service # [CN user] Use 'cn' to get update from git-over-cdn service
# [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSweeper # [Other] Use 'global' to get update from https://github.com/TheFunny/ArisuAutoSrcipt
Repository: 'global' Repository: 'global'
# Branch of Alas # Branch of Alas
# [Developer] Use 'dev', 'app', etc, to try new features # [Developer] Use 'dev', 'app', etc, to try new features
+7 -16
View File
@@ -179,29 +179,20 @@ def iter_assets():
if image.attr != '': if image.attr != '':
row = deep_get(data, keys=[image.module, image.assets, image.server, image.frame]) row = deep_get(data, keys=[image.module, image.assets, image.server, image.frame])
row.load_image(image) row.load_image(image)
# Set `search` # Apply `search` of the first frame to all
for path, frames in deep_iter(data, depth=3): for path, frames in deep_iter(data, depth=3):
print(path, frames) print(path, frames)
# If `search` attribute is set in the first frame, apply to all
first = frames[1] first = frames[1]
if first.search: search = first.search if first.search else DataAssets.area_to_search(first.area)
for frame in frames.values(): for frame in frames.values():
frame.search = first.search frame.search = 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)
return data return data
def generate_code(): def generate_code():
all_assets = iter_assets() all = iter_assets()
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]) path = os.path.join(AzurLaneConfig.ASSETS_MODULE, module.split('/', maxsplit=1)[0])
output = os.path.join(path, 'assets.py') output = os.path.join(path, 'assets.py')
if os.path.exists(output): if os.path.exists(output):
@@ -213,7 +204,7 @@ def generate_code():
continue continue
os.remove(prev) 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]) path = os.path.join(AzurLaneConfig.ASSETS_MODULE, module.split('/', maxsplit=1)[0])
output = os.path.join(path, 'assets') output = os.path.join(path, 'assets')
gen = CodeGenerator() gen = CodeGenerator()
+21 -101
View File
@@ -74,7 +74,7 @@ class Button(Resource):
threshold=threshold 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. Detects assets by template matching.
@@ -83,45 +83,18 @@ class Button(Resource):
Args: Args:
image: Screenshot. image: Screenshot.
similarity (float): 0-1. similarity (float): 0-1.
direct_match: True to ignore `self.search`
Returns: Returns:
bool. bool.
""" """
if not direct_match: image = crop(image, self.search, copy=False)
image = crop(image, self.search, copy=False)
res = cv2.matchTemplate(self.image, image, cv2.TM_CCOEFF_NORMED) res = cv2.matchTemplate(self.image, image, cv2.TM_CCOEFF_NORMED)
_, sim, _, point = cv2.minMaxLoc(res) _, sim, _, point = cv2.minMaxLoc(res)
self._button_offset = np.array(point) + self.search[:2] - self.area[:2] self._button_offset = np.array(point) + self.search[:2] - self.area[:2]
return sim > similarity return sim > similarity
def match_multi_template(self, image, similarity=0.85, direct_match=False): def match_template_color(self, image, similarity=0.85, threshold=30) -> bool:
"""
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:
""" """
Template match first, color match then Template match first, color match then
@@ -129,12 +102,11 @@ class Button(Resource):
image: Screenshot. image: Screenshot.
similarity (float): 0-1. similarity (float): 0-1.
threshold (int): Default to 10. threshold (int): Default to 10.
direct_match: True to ignore `self.search`
Returns: Returns:
bool.
""" """
matched = self.match_template(image, similarity=similarity, direct_match=direct_match) matched = self.match_template(image, similarity=similarity)
if not matched: if not matched:
return False return False
@@ -152,10 +124,10 @@ class ButtonWrapper(Resource):
self.name = name self.name = name
self.data_buttons = kwargs self.data_buttons = kwargs
self._matched_button: t.Optional[Button] = None 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): def resource_release(self):
del_cached_property(self, 'buttons') del_cached_property(self, 'assets')
self._matched_button = None self._matched_button = None
def __str__(self): def __str__(self):
@@ -172,25 +144,16 @@ class ButtonWrapper(Resource):
def __bool__(self): def __bool__(self):
return True 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 @cached_property
def buttons(self) -> t.List[Button]: def buttons(self) -> t.List[Button]:
for trial in [server.lang, 'share', 'cn']: # for trial in [server.lang, 'share', 'cn']:
try: for trial in [server.lang, 'share', 'jp']:
assets = self.data_buttons[trial] assets = self.data_buttons.get(trial, None)
if assets is not None:
if isinstance(assets, Button): if isinstance(assets, Button):
return [assets] return [assets]
elif isinstance(assets, list): elif isinstance(assets, list):
return assets return assets
except KeyError:
pass
raise ScriptError(f'ButtonWrapper({self}) on server {server.lang} has no fallback button') raise ScriptError(f'ButtonWrapper({self}) on server {server.lang} has no fallback button')
@@ -201,45 +164,16 @@ class ButtonWrapper(Resource):
return True return True
return False 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: 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 self._matched_button = assets
return True return True
return False return False
def match_multi_template(self, image, similarity=0.85, threshold=5, direct_match=False): def match_template_color(self, image, similarity=0.85, threshold=30) -> bool:
"""
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 = []
for assets in self.buttons: for assets in self.buttons:
ps += assets.match_multi_template(image, similarity=similarity, direct_match=direct_match) if assets.match_template_color(image, similarity=similarity, threshold=threshold):
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):
self._matched_button = assets self._matched_button = assets
return True return True
return False return False
@@ -288,32 +222,18 @@ class ButtonWrapper(Resource):
""" """
if isinstance(button, ButtonWrapper): if isinstance(button, ButtonWrapper):
button = button.matched_button button = button.matched_button
for b in self.iter_buttons(): for b in self.buttons:
b.load_offset(button) b.load_offset(button)
def clear_offset(self): def clear_offset(self):
for b in self.iter_buttons(): for b in self.buttons:
b.clear_offset() 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: class ClickButton:
def __init__(self, area, button=None, name='CLICK_BUTTON'): def __init__(self, button, name='CLICK_BUTTON'):
self.area = area self.area = button
if button is None: self.button = button
self.button = area
else:
self.button = button
self.name = name self.name = name
def __str__(self): def __str__(self):
@@ -345,4 +265,4 @@ def match_template(image, template, similarity=0.85):
""" """
res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED) res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
_, sim, _, point = cv2.minMaxLoc(res) _, sim, _, point = cv2.minMaxLoc(res)
return sim > similarity return sim > similarity
+13 -18
View File
@@ -1,11 +1,11 @@
import re 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() assets = set()
regex = re.compile(r"file='(.*?)'")
with open(file, 'r', encoding='utf-8') as f: with open(file, 'r', encoding='utf-8') as f:
for row in f.readlines(): for row in f.readlines():
result = regex.search(row) result = regex.search(row)
@@ -20,9 +20,11 @@ class PreservedAssets:
assets = set() assets = set()
assets |= get_assets_from_file( assets |= get_assets_from_file(
file='./tasks/base/assets/assets_base_page.py', file='./tasks/base/assets/assets_base_page.py',
regex=re.compile(r'^([A-Za-z][A-Za-z0-9_]+) = ')
) )
assets |= get_assets_from_file( assets |= get_assets_from_file(
file='./tasks/base/assets/assets_base_popup.py', file='./tasks/base/assets/assets_base_popup.py',
regex=re.compile(r'^([A-Za-z][A-Za-z0-9_]+) = ')
) )
return assets return assets
@@ -42,13 +44,11 @@ class Resource:
@classmethod @classmethod
def is_loaded(cls, obj): def is_loaded(cls, obj):
if hasattr(obj, '_image') and obj._image is not None: if hasattr(obj, '_image') and obj._image is None:
return True return False
if hasattr(obj, 'image') and obj.image is not None: elif hasattr(obj, 'image') and obj.image is None:
return True return False
if hasattr(obj, 'buttons') and obj.buttons is not None: return True
return True
return False
@classmethod @classmethod
def resource_show(cls): def resource_show(cls):
@@ -56,16 +56,11 @@ class Resource:
logger.hr('Show resource') logger.hr('Show resource')
for key, obj in cls.instances.items(): for key, obj in cls.instances.items():
if cls.is_loaded(obj): if cls.is_loaded(obj):
logger.info(f'{obj}: {key}') continue
logger.info(f'{obj}: {key}')
def release_resources(next_task=''): 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 # Release assets cache
# module.ui has about 80 assets and takes about 3MB # module.ui has about 80 assets and takes about 3MB
# Alas has about 800 assets, but they are not all loaded. # Alas has about 800 assets, but they are not all loaded.
@@ -79,4 +74,4 @@ def release_resources(next_task=''):
obj.resource_release() obj.resource_release()
# Useless in most cases, but just call it # Useless in most cases, but just call it
# gc.collect() # gc.collect()
+2 -213
View File
@@ -11,8 +11,7 @@
"value": "auto", "value": "auto",
"option": [ "option": [
"auto", "auto",
"JP-Official", "JP-Official"
"OVERSEA-Global"
] ]
}, },
"GameLanguage": { "GameLanguage": {
@@ -20,8 +19,7 @@
"value": "auto", "value": "auto",
"option": [ "option": [
"auto", "auto",
"jp", "jp"
"en"
] ]
}, },
"ScreenshotMethod": { "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": { "TacticalChallenge": {
"Scheduler": { "Scheduler": {
"Enable": { "Enable": {
@@ -533,30 +346,6 @@
"stored": "StoredInt", "stored": "StoredInt",
"order": 3, "order": 3,
"color": "#21befc" "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"
} }
} }
} }
+1 -55
View File
@@ -23,7 +23,7 @@ Emulator:
option: [ auto, ] option: [ auto, ]
GameLanguage: GameLanguage:
value: auto value: auto
option: [ auto, jp, en ] option: [ auto, jp ]
ScreenshotMethod: ScreenshotMethod:
value: auto value: auto
option: [ auto, ADB, ADB_nc, uiautomator2, aScreenCap, aScreenCap_nc, DroidCast, DroidCast_raw, scrcpy ] option: [ auto, ADB, ADB_nc, uiautomator2, aScreenCap, aScreenCap_nc, DroidCast, DroidCast_raw, scrcpy ]
@@ -81,48 +81,6 @@ Cafe:
AutoAdjust: true AutoAdjust: true
SecondCafe: 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: TacticalChallenge:
PlayerSelect: PlayerSelect:
value: 0 value: 0
@@ -141,15 +99,3 @@ ItemStorage:
stored: StoredInt stored: StoredInt
order: 3 order: 3
color: "#21befc" color: "#21befc"
BountyTicket:
stored: StoredBountyTicket
order: 4
color: "#94cb44"
ScrimmageTicket:
stored: StoredScrimmageTicket
order: 5
color: "#f86c6a"
TacticalChallengeTicket:
stored: StoredTacticalChallengeTicket
order: 6
color: "#7ac8e5"
-6
View File
@@ -13,12 +13,6 @@ Mail:
Circle: Circle:
Scheduler: Scheduler:
Enable: true Enable: true
Bounty:
Scheduler:
Enable: true
Scrimmage:
Scheduler:
Enable: true
TacticalChallenge: TacticalChallenge:
Scheduler: Scheduler:
Enable: true Enable: true
-2
View File
@@ -14,8 +14,6 @@
"Cafe", "Cafe",
"Mail", "Mail",
"Circle", "Circle",
"Bounty",
"Scrimmage",
"TacticalChallenge", "TacticalChallenge",
"DataUpdate" "DataUpdate"
] ]
-39
View File
@@ -35,44 +35,5 @@
}, },
"order": 3, "order": 3,
"color": "#21befc" "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"
} }
} }
-12
View File
@@ -29,18 +29,6 @@ Daily:
- Scheduler - Scheduler
Circle: Circle:
- Scheduler - Scheduler
Bounty:
- Scheduler
- Bounty
- Highway
- DesertRailroad
- Schoolhouse
Scrimmage:
- Scheduler
- Scrimmage
- Trinity
- Gehenna
- Millennium
TacticalChallenge: TacticalChallenge:
- Scheduler - Scheduler
- TacticalChallenge - TacticalChallenge
+13
View File
@@ -499,6 +499,19 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher
self.task_call('DailyQuest') self.task_call('DailyQuest')
self.task_stop() 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 @property
def DEVICE_SCREENSHOT_METHOD(self): def DEVICE_SCREENSHOT_METHOD(self):
return self.Emulator_ScreenshotMethod return self.Emulator_ScreenshotMethod
+2 -35
View File
@@ -17,8 +17,8 @@ class GeneratedConfig:
# Group `Emulator` # Group `Emulator`
Emulator_Serial = 'auto' Emulator_Serial = 'auto'
Emulator_PackageName = 'auto' # auto, JP-Official, OVERSEA-Global Emulator_PackageName = 'auto' # auto, JP-Official
Emulator_GameLanguage = 'auto' # auto, jp, en Emulator_GameLanguage = 'auto' # auto, jp
Emulator_ScreenshotMethod = 'auto' # auto, ADB, ADB_nc, uiautomator2, aScreenCap, aScreenCap_nc, DroidCast, DroidCast_raw, scrcpy Emulator_ScreenshotMethod = 'auto' # auto, ADB, ADB_nc, uiautomator2, aScreenCap, aScreenCap_nc, DroidCast, DroidCast_raw, scrcpy
Emulator_ControlMethod = 'MaaTouch' # minitouch, MaaTouch Emulator_ControlMethod = 'MaaTouch' # minitouch, MaaTouch
Emulator_AdbRestart = False Emulator_AdbRestart = False
@@ -45,36 +45,6 @@ class GeneratedConfig:
Cafe_AutoAdjust = True Cafe_AutoAdjust = True
Cafe_SecondCafe = 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` # Group `TacticalChallenge`
TacticalChallenge_PlayerSelect = 0 # 0, 1, 2, 3 TacticalChallenge_PlayerSelect = 0 # 0, 1, 2, 3
@@ -82,6 +52,3 @@ class GeneratedConfig:
ItemStorage_AP = {} ItemStorage_AP = {}
ItemStorage_Credit = {} ItemStorage_Credit = {}
ItemStorage_Pyroxene = {} ItemStorage_Pyroxene = {}
ItemStorage_BountyTicket = {}
ItemStorage_ScrimmageTicket = {}
ItemStorage_TacticalChallengeTicket = {}
+1 -2
View File
@@ -8,8 +8,7 @@ class ManualConfig:
SCHEDULER_PRIORITY = """ SCHEDULER_PRIORITY = """
Restart Restart
> Cafe > Circle > Mail > DataUpdate > Bounty > Cafe > Circle > Mail > DataUpdate > TacticalChallenge
> Scrimmage > TacticalChallenge
""" """
""" """
+1 -2
View File
@@ -458,8 +458,7 @@ class ConfigUpdater:
value = deep_get(old, keys=keys, default=data['value']) value = deep_get(old, keys=keys, default=data['value'])
typ = data['type'] typ = data['type']
display = data.get('display') display = data.get('display')
if (is_template or value is None or value == '' if is_template or value is None or value == '' or typ == 'lock' or (display == 'hide' and typ != 'stored'):
or typ in ['lock', 'state'] or (display == 'hide' and typ != 'stored')):
value = data['value'] value = data['value']
value = parse_value(value, data=data) value = parse_value(value, data=data)
deep_set(new, keys=keys, value=value) deep_set(new, keys=keys, value=value)
+6 -175
View File
@@ -30,14 +30,6 @@
"name": "Club", "name": "Club",
"help": "" "help": ""
}, },
"Bounty": {
"name": "Bounty",
"help": ""
},
"Scrimmage": {
"name": "Scrimmage",
"help": ""
},
"TacticalChallenge": { "TacticalChallenge": {
"name": "Tactical Challenge", "name": "Tactical Challenge",
"help": "" "help": ""
@@ -84,21 +76,19 @@
"name": "Game Server", "name": "Game Server",
"help": "Can't distinguish different regions of oversea servers, please select the server manually.", "help": "Can't distinguish different regions of oversea servers, please select the server manually.",
"auto": "Auto-detect", "auto": "Auto-detect",
"JP-Official": "[JP]-Official", "JP-Official": "[JP]-Official"
"OVERSEA-Global": "[OVERSEA]-Global"
}, },
"GameLanguage": { "GameLanguage": {
"name": "In-game Text Language", "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", "auto": "Auto-detect",
"jp": "Japanese", "jp": "Japanese"
"en": "English"
}, },
"ScreenshotMethod": { "ScreenshotMethod": {
"name": "Screenshot Method", "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.", "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", "auto": "Auto-select the fastest",
"ADB": "ADB", "ADB": "ADB ",
"ADB_nc": "ADB_nc", "ADB_nc": "ADB_nc",
"uiautomator2": "uiautomator2", "uiautomator2": "uiautomator2",
"aScreenCap": "aScreenCap", "aScreenCap": "aScreenCap",
@@ -213,155 +203,8 @@
"help": "Auto adjust cafe interface for better student interaction" "help": "Auto adjust cafe interface for better student interaction"
}, },
"SecondCafe": { "SecondCafe": {
"name": "Second Floor", "name": "Second Cafe",
"help": "JP server only\nEnable auto switch to second floor and perform interaction" "help": "Enable auto switch to second cafe 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"
} }
}, },
"TacticalChallenge": { "TacticalChallenge": {
@@ -394,18 +237,6 @@
"Pyroxene": { "Pyroxene": {
"name": "Pyroxene", "name": "Pyroxene",
"help": "" "help": ""
},
"BountyTicket": {
"name": "Bounty",
"help": ""
},
"ScrimmageTicket": {
"name": "Scrimmage",
"help": ""
},
"TacticalChallengeTicket": {
"name": "Tactical Challenge",
"help": ""
} }
}, },
"Gui": { "Gui": {
+3 -172
View File
@@ -30,14 +30,6 @@
"name": "公会", "name": "公会",
"help": "社团 / 小组" "help": "社团 / 小组"
}, },
"Bounty": {
"name": "悬赏通缉",
"help": ""
},
"Scrimmage": {
"name": "学院交流会",
"help": ""
},
"TacticalChallenge": { "TacticalChallenge": {
"name": "战术对抗赛", "name": "战术对抗赛",
"help": "战术大赛 / 竞技场" "help": "战术大赛 / 竞技场"
@@ -84,15 +76,13 @@
"name": "游戏服务器", "name": "游戏服务器",
"help": "无法区分国际服的不同地区,请手动选择服务器", "help": "无法区分国际服的不同地区,请手动选择服务器",
"auto": "自动检测", "auto": "自动检测",
"JP-Official": "[日服]-官服", "JP-Official": "[日服]-官服"
"OVERSEA-Global": "[国际服]-全球"
}, },
"GameLanguage": { "GameLanguage": {
"name": "游戏内文本语言", "name": "游戏内文本语言",
"help": "", "help": "",
"auto": "自动检测", "auto": "自动检测",
"jp": "日语", "jp": "日语"
"en": "英语"
}, },
"ScreenshotMethod": { "ScreenshotMethod": {
"name": "模拟器截图方案", "name": "模拟器截图方案",
@@ -214,154 +204,7 @@
}, },
"SecondCafe": { "SecondCafe": {
"name": "第二咖啡厅", "name": "第二咖啡厅",
"help": "仅支持日服\n自动切换第二咖啡厅进行互动点击" "help": "自动切换第二咖啡厅进行互动点击"
}
},
"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 次"
} }
}, },
"TacticalChallenge": { "TacticalChallenge": {
@@ -394,18 +237,6 @@
"Pyroxene": { "Pyroxene": {
"name": "青辉石", "name": "青辉石",
"help": "" "help": ""
},
"BountyTicket": {
"name": "悬赏通缉",
"help": ""
},
"ScrimmageTicket": {
"name": "学院交流会",
"help": ""
},
"TacticalChallengeTicket": {
"name": "战术对抗赛",
"help": ""
} }
}, },
"Gui": { "Gui": {
+2 -3
View File
@@ -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 lang = 'jp' # Setting default to cn, will avoid errors when using dev_tools
server = 'JP-Official' server = 'JP-Official'
VALID_LANG = ['jp', 'en'] VALID_LANG = ['jp']
VALID_SERVER = { VALID_SERVER = {
'JP-Official': 'com.YostarJP.BlueArchive', 'JP-Official': 'com.YostarJP.BlueArchive'
'OVERSEA-Global': 'com.nexon.bluearchive',
} }
VALID_PACKAGE = set(list(VALID_SERVER.values())) VALID_PACKAGE = set(list(VALID_SERVER.values()))
-16
View File
@@ -3,8 +3,6 @@ from functools import cached_property as functools_cached_property
from module.base.decorator import 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.config.utils import DEFAULT_TIME, deep_get, get_server_last_monday_update, get_server_last_update
# from module.exception import ScriptError # from module.exception import ScriptError
@@ -175,20 +173,6 @@ class StoredCounter(StoredBase):
class StoredAP(StoredCounter): class StoredAP(StoredCounter):
pass 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): # class StoredDailyActivity(StoredCounter, StoredExpiredAt0400):
# FIXED_TOTAL = 500 # FIXED_TOTAL = 500
# #
+4 -6
View File
@@ -1,9 +1,10 @@
from module.config.stored.classes import ( from module.config.stored.classes import (
StoredAP, StoredAP,
StoredBountyTicket, StoredBase,
StoredCounter,
StoredExpiredAt0400,
StoredExpiredAtMonday0400,
StoredInt, StoredInt,
StoredScrimmageTicket,
StoredTacticalChallengeTicket,
) )
@@ -14,6 +15,3 @@ class StoredGenerated:
AP = StoredAP("DataUpdate.ItemStorage.AP") AP = StoredAP("DataUpdate.ItemStorage.AP")
Credit = StoredInt("DataUpdate.ItemStorage.Credit") Credit = StoredInt("DataUpdate.ItemStorage.Credit")
Pyroxene = StoredInt("DataUpdate.ItemStorage.Pyroxene") Pyroxene = StoredInt("DataUpdate.ItemStorage.Pyroxene")
BountyTicket = StoredBountyTicket("DataUpdate.ItemStorage.BountyTicket")
ScrimmageTicket = StoredScrimmageTicket("DataUpdate.ItemStorage.ScrimmageTicket")
TacticalChallengeTicket = StoredTacticalChallengeTicket("DataUpdate.ItemStorage.TacticalChallengeTicket")
-1
View File
@@ -13,7 +13,6 @@ from module.config.atomicwrites import atomic_write
LANGUAGES = ['zh-CN', 'en-US'] LANGUAGES = ['zh-CN', 'en-US']
SERVER_TO_TIMEZONE = { SERVER_TO_TIMEZONE = {
'JP-Official': timedelta(hours=9), 'JP-Official': timedelta(hours=9),
'OVERSEA-Global': timedelta(hours=0),
} }
DEFAULT_TIME = datetime(2020, 1, 1, 0, 0) DEFAULT_TIME = datetime(2020, 1, 1, 0, 0)
+3 -3
View File
@@ -863,8 +863,8 @@ class Connection(ConnectionAttr):
# Auto package detection # Auto package detection
if len(packages) == 0: if len(packages) == 0:
logger.critical(f'No Blue Archive package found, ' logger.critical(f'No Star Rail package found, '
f'please confirm Blue Archive has been installed on device "{self.serial}"') f'please confirm Star Rail has been installed on device "{self.serial}"')
raise RequestHumanTakeover raise RequestHumanTakeover
if len(packages) == 1: if len(packages) == 1:
logger.info('Auto package detection found only one package, using it') logger.info('Auto package detection found only one package, using it')
@@ -877,6 +877,6 @@ class Connection(ConnectionAttr):
# set_server(self.package) # set_server(self.package)
else: else:
logger.critical( 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') 'please copy one of the available devices listed above to Alas.Emulator.PackageName')
raise RequestHumanTakeover raise RequestHumanTakeover

Some files were not shown because too many files have changed in this diff Show More