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:
|
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.
|
|
||||||
|
|||||||
@@ -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) 提供英语支持。
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
|
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--"] {
|
*[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--"] {
|
||||||
|
|||||||
|
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:
|
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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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": {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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,12 +83,10 @@ 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)
|
||||||
@@ -96,32 +94,7 @@ class Button(Resource):
|
|||||||
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,31 +222,17 @@ 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 = area
|
|
||||||
else:
|
|
||||||
self.button = button
|
self.button = button
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
if hasattr(obj, 'image') and obj.image is not None:
|
|
||||||
return True
|
|
||||||
if hasattr(obj, 'buttons') and obj.buttons is not None:
|
|
||||||
return True
|
|
||||||
return False
|
return False
|
||||||
|
elif hasattr(obj, 'image') and obj.image is None:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
@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):
|
||||||
|
continue
|
||||||
logger.info(f'{obj}: {key}')
|
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.
|
||||||
|
|||||||
@@ -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"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -14,8 +14,6 @@
|
|||||||
"Cafe",
|
"Cafe",
|
||||||
"Mail",
|
"Mail",
|
||||||
"Circle",
|
"Circle",
|
||||||
"Bounty",
|
|
||||||
"Scrimmage",
|
|
||||||
"TacticalChallenge",
|
"TacticalChallenge",
|
||||||
"DataUpdate"
|
"DataUpdate"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 = {}
|
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ class ManualConfig:
|
|||||||
|
|
||||||
SCHEDULER_PRIORITY = """
|
SCHEDULER_PRIORITY = """
|
||||||
Restart
|
Restart
|
||||||
> Cafe > Circle > Mail > DataUpdate > Bounty
|
> Cafe > Circle > Mail > DataUpdate > TacticalChallenge
|
||||||
> Scrimmage > TacticalChallenge
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
@@ -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()))
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -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")
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||