1
0
mirror of https://github.com/TheFunny/ArisuAutoSweeper synced 2026-06-29 21:35:02 +00:00

31 Commits

Author SHA1 Message Date
YoursFunny 15bf77da3d fix(cafe): expand search box 2023-11-23 16:21:58 +08:00
YoursFunny 4ce8073096 perf(sweep): simplify sweep num ocr 2023-11-23 16:08:51 +08:00
YoursFunny aa872c890d doc: update readme 2023-11-23 14:45:31 +08:00
YoursFunny 25e0559171 feat: add oversea servers 2023-11-23 14:23:52 +08:00
YoursFunny df6da1f77a fix(cafe): adjust property of second cafe setting 2023-11-23 14:06:38 +08:00
YoursFunny fc49adc859 doc: update readme 2023-11-22 22:23:09 +08:00
YoursFunny 4582406ef2 perf(tc): improve status check stability 2023-11-22 22:04:50 +08:00
YoursFunny 256dc96598 fix(tc): restrict count frequency of claim reward 2023-11-22 22:01:07 +08:00
YoursFunny 04744d6f8c fix(scrimmage): add missing multiply of ap count 2023-11-22 22:01:06 +08:00
YoursFunny 8fe578615d fix: change webui port 2023-11-22 21:02:00 +08:00
YoursFunny 5e9615542c fix: set repo when update 2023-11-22 20:47:18 +08:00
YoursFunny 36c5f60eb3 fix(cafe): adjust property of second cafe setting 2023-11-22 19:05:36 +08:00
YoursFunny 91650cc584 feat: add en assets for bounty scrimmage and sweep 2023-11-22 19:04:50 +08:00
YoursFunny 67881568dd perf(button): combine shared assets 2023-11-22 13:13:39 +08:00
YoursFunny f8404edd9e fix: set repo of build-in update 2023-11-21 23:15:06 +08:00
YoursFunny ff3ec041d2 refactor(cafe): separate ui operation and simplify template extraction 2023-11-21 22:18:28 +08:00
YoursFunny 99074a1575 feat(cafe): add template search area 2023-11-21 21:31:01 +08:00
YoursFunny 7862fa6cb8 fix(scrimmage): fix typo 2023-11-21 20:56:39 +08:00
YoursFunny baac90ecf0 fix(resource): remove non-existing assets loading 2023-11-21 20:42:24 +08:00
YoursFunny 53ec298fed fix(alas): validate datetime instead of using regex 2023-11-21 20:29:26 +08:00
YoursFunny b4f18f78ff perf: use more friendly record time on dashboard 2023-11-21 20:27:19 +08:00
YoursFunny eb9af42f38 fix: ignore value in state type args 2023-11-21 20:16:40 +08:00
YoursFunny c29d972c6c feat: support direct_match and match_multi_template 2023-11-21 20:07:45 +08:00
YoursFunny 92b34d4760 perf: release resource when free 2023-11-21 19:59:32 +08:00
YoursFunny 04853b6c31 feat: support load search for buttons 2023-11-21 19:53:02 +08:00
YoursFunny 9604e8962a fix: accept area attr in ClickButton 2023-11-21 19:20:04 +08:00
YoursFunny 03380b2d71 fix: use distinctive search attr for each button frame 2023-11-21 19:17:06 +08:00
YoursFunny c27bd74050 fix: adjust icon css 2023-11-21 19:00:14 +08:00
YoursFunny c3e9945b15 lang: use shorter description for items 2023-11-21 18:43:04 +08:00
YoursFunny 1dd100ac04 lang: fix typo 2023-11-21 15:28:08 +08:00
YoursFunny 77dca70af1 doc: update readme 2023-11-21 15:25:41 +08:00
113 changed files with 617 additions and 437 deletions
+7 -1
View File
@@ -16,12 +16,18 @@ The script is still under active development. The following features have been i
- [x] **Club** Claim AP - [x] **Club** Claim AP
- [x] **Mailbox** Claim rewards - [x] **Mailbox** Claim rewards
- [x] **Bounty** Auto sweep - [x] **Bounty** Auto sweep
- [x] **Scrimmage** Auto sweep
- [x] **Tactical Challenge** Claim rewards / Auto battle - [x] **Tactical Challenge** Claim rewards / Auto battle
Supported servers: Supported servers:
- [x] JP - [x] JP
- [x] OVERSEA - Global - [x] OVERSEA
Supported in-game languages:
- [x] Japanese
- [x] English
## Relative projects ## Relative projects
+9 -2
View File
@@ -16,17 +16,24 @@
- [x] **公会** 领取体力 - [x] **公会** 领取体力
- [x] **邮箱** 领取奖励 - [x] **邮箱** 领取奖励
- [x] **悬赏通缉** 自动扫荡 - [x] **悬赏通缉** 自动扫荡
- [x] **学院交流会** 自动扫荡
- [x] **战术对抗赛** 领取奖励 / 自动战斗 - [x] **战术对抗赛** 领取奖励 / 自动战斗
目前支持的服务器: 目前支持的服务器:
- [x] 日服 - [x] 日服
- [x] 国际服 - 全球 - [x] 国际服
目前支持的游戏内语言:
- [x] 日语
- [x] 英语
## 已知问题 ## 已知问题
若愿意提供其他服务器支持,请开 PR 或 Issue。 若愿意提供其他语言或国服支持,请开 PR 或 Issue。
- **国际服登录的全屏通知**:未实现自动关闭,正在研究中
- **大小月卡**:未实现自动领取,~~因为没买过~~,可能不影响使用。愿意提供图片的请开 Issue - **大小月卡**:未实现自动领取,~~因为没买过~~,可能不影响使用。愿意提供图片的请开 Issue
- **月卡的额外悬赏券和学院交流券**:不太清楚月卡领取额外券的机制,~~因为没买过~~,可能影响相关任务使用券和体力的计算。愿意提供相关信息的请开 - **月卡的额外悬赏券和学院交流券**:不太清楚月卡领取额外券的机制,~~因为没买过~~,可能影响相关任务使用券和体力的计算。愿意提供相关信息的请开
Issue Issue
Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 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: 3.5em; height: 3em;
} }
*[style*="--header-text--"] { *[style*="--header-text--"] {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 905 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

Before

Width:  |  Height:  |  Size: 7.8 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Before

Width:  |  Height:  |  Size: 905 KiB

After

Width:  |  Height:  |  Size: 905 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1016 KiB

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

+2 -2
View File
@@ -128,8 +128,8 @@ Deploy:
WebuiHost: 0.0.0.0 WebuiHost: 0.0.0.0
# --port. Port to listen # --port. Port to listen
# You will be able to access webui via `http://{host}:{port}` # You will be able to access webui via `http://{host}:{port}`
# [In most cases] Default to 22367 # [In most cases] Default to 23467
WebuiPort: 22367 WebuiPort: 23467
# Language to use on web ui # Language to use on web ui
# 'zh-CN' for Chinese simplified # 'zh-CN' for Chinese simplified
# 'en-US' for English # 'en-US' for English
+2 -2
View File
@@ -128,8 +128,8 @@ Deploy:
WebuiHost: 0.0.0.0 WebuiHost: 0.0.0.0
# --port. Port to listen # --port. Port to listen
# You will be able to access webui via `http://{host}:{port}` # You will be able to access webui via `http://{host}:{port}`
# [In most cases] Default to 22367 # [In most cases] Default to 23467
WebuiPort: 22367 WebuiPort: 23467
# Language to use on web ui # Language to use on web ui
# 'zh-CN' for Chinese simplified # 'zh-CN' for Chinese simplified
# 'en-US' for English # 'en-US' for English
+7 -4
View File
@@ -55,7 +55,7 @@ class ConfigModel:
# Webui # Webui
WebuiHost: str = "0.0.0.0" WebuiHost: str = "0.0.0.0"
WebuiPort: int = 22367 WebuiPort: int = 23467
Language: str = "en-US" Language: str = "en-US"
Theme: str = "default" Theme: str = "default"
DpiScaling: bool = True DpiScaling: bool = True
@@ -77,6 +77,12 @@ class DeployConfig(ConfigModel):
self.config_template = {} self.config_template = {}
self.read() self.read()
self.set_repo()
self.write()
self.show_config()
def set_repo(self):
# Bypass webui.config.DeployConfig.__setattr__() # Bypass webui.config.DeployConfig.__setattr__()
# Don't write these into deploy.yaml # Don't write these into deploy.yaml
if self.Repository == 'cn': if self.Repository == 'cn':
@@ -84,9 +90,6 @@ class DeployConfig(ConfigModel):
if self.Repository == 'global': if self.Repository == 'global':
super().__setattr__('Repository', 'https://github.com/TheFunny/ArisuAutoSweeper') super().__setattr__('Repository', 'https://github.com/TheFunny/ArisuAutoSweeper')
self.write()
self.show_config()
def show_config(self): def show_config(self):
logger.hr("Show deploy config", 1) logger.hr("Show deploy config", 1)
for k, v in self.config.items(): for k, v in self.config.items():
+2 -2
View File
@@ -128,8 +128,8 @@ Deploy:
WebuiHost: 0.0.0.0 WebuiHost: 0.0.0.0
# --port. Port to listen # --port. Port to listen
# You will be able to access webui via `http://{host}:{port}` # You will be able to access webui via `http://{host}:{port}`
# [In most cases] Default to 22367 # [In most cases] Default to 23467
WebuiPort: 22367 WebuiPort: 23467
# Language to use on web ui # Language to use on web ui
# 'zh-CN' for Chinese simplified # 'zh-CN' for Chinese simplified
# 'en-US' for English # 'en-US' for English
+16 -7
View File
@@ -179,20 +179,29 @@ 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)
# Apply `search` of the first frame to all # Set `search`
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]
search = first.search if first.search else DataAssets.area_to_search(first.area) if first.search:
for frame in frames.values(): for frame in frames.values():
frame.search = search frame.search = first.search
else:
for frame in frames.values():
if frame.search:
# Follow frame specific `search`
pass
else:
# Generate `search` from `area`
frame.search = DataAssets.area_to_search(frame.area)
return data return data
def generate_code(): def generate_code():
all = iter_assets() all_assets = iter_assets()
for module, module_data in all.items(): for module, module_data in all_assets.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):
@@ -204,7 +213,7 @@ def generate_code():
continue continue
os.remove(prev) os.remove(prev)
for module, module_data in all.items(): for module, module_data in all_assets.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()
+1 -1
View File
@@ -49,7 +49,7 @@ def func(ev: threading.Event):
args, _ = parser.parse_known_args() args, _ = parser.parse_known_args()
host = args.host or State.deploy_config.WebuiHost or "0.0.0.0" host = args.host or State.deploy_config.WebuiHost or "0.0.0.0"
port = args.port or int(State.deploy_config.WebuiPort) or 22367 port = args.port or int(State.deploy_config.WebuiPort) or 23467
State.electron = args.electron State.electron = args.electron
logger.hr("Launcher config") logger.hr("Launcher config")
+101 -21
View File
@@ -74,7 +74,7 @@ class Button(Resource):
threshold=threshold threshold=threshold
) )
def match_template(self, image, similarity=0.85) -> bool: def match_template(self, image, similarity=0.85, direct_match=False) -> bool:
""" """
Detects assets by template matching. Detects assets by template matching.
@@ -83,18 +83,45 @@ 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.
""" """
image = crop(image, self.search, copy=False) if not direct_match:
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_template_color(self, image, similarity=0.85, threshold=30) -> bool: def match_multi_template(self, image, similarity=0.85, direct_match=False):
"""
Detects assets by template matching, return multiple reults
Args:
image: Screenshot.
similarity (float): 0-1.
direct_match: True to ignore `self.search`
Returns:
list:
"""
if not direct_match:
image = crop(image, self.search, copy=False)
res = cv2.matchTemplate(self.image, image, cv2.TM_CCOEFF_NORMED)
res = cv2.inRange(res, similarity, 1.)
try:
points = np.array(cv2.findNonZero(res))[:, 0, :]
points += self.search[:2]
return points.tolist()
except IndexError:
# Empty result
# IndexError: too many indices for array: array is 0-dimensional, but 3 were indexed
return []
def match_template_color(self, image, similarity=0.85, threshold=30, direct_match=False) -> bool:
""" """
Template match first, color match then Template match first, color match then
@@ -102,11 +129,12 @@ 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) matched = self.match_template(image, similarity=similarity, direct_match=direct_match)
if not matched: if not matched:
return False return False
@@ -124,10 +152,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(self.name) self.resource_add(f'{name}:{next(self.iter_buttons(), None)}')
def resource_release(self): def resource_release(self):
del_cached_property(self, 'assets') del_cached_property(self, 'buttons')
self._matched_button = None self._matched_button = None
def __str__(self): def __str__(self):
@@ -144,16 +172,25 @@ 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']:
for trial in [server.lang, 'share', 'jp']: try:
assets = self.data_buttons.get(trial, None) assets = self.data_buttons[trial]
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')
@@ -164,16 +201,45 @@ class ButtonWrapper(Resource):
return True return True
return False return False
def match_template(self, image, similarity=0.85) -> bool: def match_template(self, image, similarity=0.85, direct_match=False) -> bool:
for assets in self.buttons: for assets in self.buttons:
if assets.match_template(image, similarity=similarity): if assets.match_template(image, similarity=similarity, direct_match=direct_match):
self._matched_button = assets self._matched_button = assets
return True return True
return False return False
def match_template_color(self, image, similarity=0.85, threshold=30) -> bool: def match_multi_template(self, image, similarity=0.85, threshold=5, direct_match=False):
"""
Detects assets by template matching, return multiple results
Args:
image: Screenshot.
similarity (float): 0-1.
threshold:
direct_match: True to ignore `self.search`
Returns:
list[ClickButton]:
"""
ps = []
for assets in self.buttons: for assets in self.buttons:
if assets.match_template_color(image, similarity=similarity, threshold=threshold): ps += assets.match_multi_template(image, similarity=similarity, direct_match=direct_match)
if not ps:
return []
from module.base.utils.points import Points
ps = Points(ps).group(threshold=threshold)
area_list = [area_offset(self.area, p - self.area[:2]) for p in ps]
button_list = [area_offset(self.button, p - self.area[:2]) for p in ps]
return [
ClickButton(area=info[0], button=info[1], name=f'{self.name}_result{i}')
for i, info in enumerate(zip(area_list, button_list))
]
def match_template_color(self, image, similarity=0.85, threshold=30, direct_match=False) -> bool:
for assets in self.buttons:
if assets.match_template_color(
image, similarity=similarity, threshold=threshold, direct_match=direct_match):
self._matched_button = assets self._matched_button = assets
return True return True
return False return False
@@ -222,18 +288,32 @@ class ButtonWrapper(Resource):
""" """
if isinstance(button, ButtonWrapper): if isinstance(button, ButtonWrapper):
button = button.matched_button button = button.matched_button
for b in self.buttons: for b in self.iter_buttons():
b.load_offset(button) b.load_offset(button)
def clear_offset(self): def clear_offset(self):
for b in self.buttons: for b in self.iter_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, button, name='CLICK_BUTTON'): def __init__(self, area, button=None, name='CLICK_BUTTON'):
self.area = button self.area = area
self.button = button if button is None:
self.button = area
else:
self.button = button
self.name = name self.name = name
def __str__(self): def __str__(self):
@@ -265,4 +345,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
+18 -13
View File
@@ -1,11 +1,11 @@
import re import re
import module.config.server as server from module.base.decorator import cached_property
from module.base.decorator import cached_property, del_cached_property
def get_assets_from_file(file, regex): def get_assets_from_file(file):
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,11 +20,9 @@ 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
@@ -44,11 +42,13 @@ class Resource:
@classmethod @classmethod
def is_loaded(cls, obj): def is_loaded(cls, obj):
if hasattr(obj, '_image') and obj._image is None: if hasattr(obj, '_image') and obj._image is not None:
return False return True
elif hasattr(obj, 'image') and obj.image is None: if hasattr(obj, 'image') and obj.image is not None:
return False return True
return True if hasattr(obj, 'buttons') and obj.buttons is not None:
return True
return False
@classmethod @classmethod
def resource_show(cls): def resource_show(cls):
@@ -56,11 +56,16 @@ 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.
@@ -74,4 +79,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()
+4
View File
@@ -12,6 +12,10 @@
"option": [ "option": [
"auto", "auto",
"JP-Official", "JP-Official",
"OVERSEA-TWHKMO",
"OVERSEA-Korea",
"OVERSEA-Asia",
"OVERSEA-America",
"OVERSEA-Global" "OVERSEA-Global"
] ]
}, },
+1 -1
View File
@@ -17,7 +17,7 @@ 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, OVERSEA-TWHKMO, OVERSEA-Korea, OVERSEA-Asia, OVERSEA-America, OVERSEA-Global
Emulator_GameLanguage = 'auto' # auto, jp, en Emulator_GameLanguage = 'auto' # auto, jp, en
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
+2 -1
View File
@@ -458,7 +458,8 @@ 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 == '' or typ == 'lock' or (display == 'hide' and typ != 'stored'): if (is_template or value is None or value == ''
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)
+8 -4
View File
@@ -85,11 +85,15 @@
"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-TWHKMO": "[OVERSEA]-TW/HK/MO",
"OVERSEA-Korea": "[OVERSEA]-Korea",
"OVERSEA-Asia": "[OVERSEA]-Asia",
"OVERSEA-America": "[OVERSEA]-North America",
"OVERSEA-Global": "[OVERSEA]-Global" "OVERSEA-Global": "[OVERSEA]-Global"
}, },
"GameLanguage": { "GameLanguage": {
"name": "In-game Text Language", "name": "In-game Text Language",
"help": "", "help": "Can't detect language automatically, please select the language manually.",
"auto": "Auto-detect", "auto": "Auto-detect",
"jp": "Japanese", "jp": "Japanese",
"en": "English" "en": "English"
@@ -396,15 +400,15 @@
"help": "" "help": ""
}, },
"BountyTicket": { "BountyTicket": {
"name": "Bounty Ticket", "name": "Bounty",
"help": "" "help": ""
}, },
"ScrimmageTicket": { "ScrimmageTicket": {
"name": "Scrimmage Ticket", "name": "Scrimmage",
"help": "" "help": ""
}, },
"TacticalChallengeTicket": { "TacticalChallengeTicket": {
"name": "Tactical Challenge Ticket", "name": "Tactical Challenge",
"help": "" "help": ""
} }
}, },
+9 -5
View File
@@ -31,7 +31,7 @@
"help": "社团 / 小组" "help": "社团 / 小组"
}, },
"Bounty": { "Bounty": {
"name": "通缉悬赏", "name": "悬赏通缉",
"help": "" "help": ""
}, },
"Scrimmage": { "Scrimmage": {
@@ -85,11 +85,15 @@
"help": "无法区分国际服的不同地区,请手动选择服务器", "help": "无法区分国际服的不同地区,请手动选择服务器",
"auto": "自动检测", "auto": "自动检测",
"JP-Official": "[日服]-官服", "JP-Official": "[日服]-官服",
"OVERSEA-TWHKMO": "[国际服]-港澳台",
"OVERSEA-Korea": "[国际服]-韩国",
"OVERSEA-Asia": "[国际服]-亚洲",
"OVERSEA-America": "[国际服]-北美",
"OVERSEA-Global": "[国际服]-全球" "OVERSEA-Global": "[国际服]-全球"
}, },
"GameLanguage": { "GameLanguage": {
"name": "游戏内文本语言", "name": "游戏内文本语言",
"help": "", "help": "无法自动检测语言,请手动选择语言",
"auto": "自动检测", "auto": "自动检测",
"jp": "日语", "jp": "日语",
"en": "英语" "en": "英语"
@@ -396,15 +400,15 @@
"help": "" "help": ""
}, },
"BountyTicket": { "BountyTicket": {
"name": "悬赏通缉票券", "name": "悬赏通缉",
"help": "" "help": ""
}, },
"ScrimmageTicket": { "ScrimmageTicket": {
"name": "学院交流会票券", "name": "学院交流会",
"help": "" "help": ""
}, },
"TacticalChallengeTicket": { "TacticalChallengeTicket": {
"name": "战术对抗赛票券", "name": "战术对抗赛",
"help": "" "help": ""
} }
}, },
+4
View File
@@ -8,6 +8,10 @@ server = 'JP-Official'
VALID_LANG = ['jp', 'en'] VALID_LANG = ['jp', 'en']
VALID_SERVER = { VALID_SERVER = {
'JP-Official': 'com.YostarJP.BlueArchive', 'JP-Official': 'com.YostarJP.BlueArchive',
'OVERSEA-TWHKMO': 'com.nexon.bluearchive',
'OVERSEA-Korea': 'com.nexon.bluearchive',
'OVERSEA-Asia': 'com.nexon.bluearchive',
'OVERSEA-America': 'com.nexon.bluearchive',
'OVERSEA-Global': 'com.nexon.bluearchive', 'OVERSEA-Global': 'com.nexon.bluearchive',
} }
VALID_PACKAGE = set(list(VALID_SERVER.values())) VALID_PACKAGE = set(list(VALID_SERVER.values()))
+5 -1
View File
@@ -13,7 +13,11 @@ 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), 'OVERSEA-TWHKMO': timedelta(hours=9),
'OVERSEA-Korea': timedelta(hours=9),
'OVERSEA-Asia': timedelta(hours=9),
'OVERSEA-America': timedelta(hours=9),
'OVERSEA-Global': timedelta(hours=9),
} }
DEFAULT_TIME = datetime(2020, 1, 1, 0, 0) DEFAULT_TIME = datetime(2020, 1, 1, 0, 0)
+7 -1
View File
@@ -1,6 +1,6 @@
from pponnxcr import TextSystem as TextSystem_ from pponnxcr import TextSystem as TextSystem_
from module.base.decorator import cached_property from module.base.decorator import cached_property, del_cached_property
from module.exception import ScriptError from module.exception import ScriptError
DIC_LANG_TO_MODEL = { DIC_LANG_TO_MODEL = {
@@ -56,6 +56,12 @@ class OcrModel:
except AttributeError: except AttributeError:
raise ScriptError(f'OCR model under lang "{lang}" does not exists') raise ScriptError(f'OCR model under lang "{lang}" does not exists')
def resource_release(self):
del_cached_property(self, 'zhs')
del_cached_property(self, 'en')
del_cached_property(self, 'ja')
del_cached_property(self, 'zht')
@cached_property @cached_property
def zhs(self): def zhs(self):
return TextSystem('zhs') return TextSystem('zhs')
+6 -3
View File
@@ -89,12 +89,15 @@ def readable_time(before: str) -> str:
elif diff < 60: elif diff < 60:
# < 1 min # < 1 min
return t("Gui.Dashboard.JustNow") return t("Gui.Dashboard.JustNow")
elif diff < 3600: elif diff < 5400:
# < 90 min
return t("Gui.Dashboard.MinutesAgo", time=int(diff // 60)) return t("Gui.Dashboard.MinutesAgo", time=int(diff // 60))
elif diff < 86400: elif diff < 129600:
# < 36 hours
return t("Gui.Dashboard.HoursAgo", time=int(diff // 3600)) return t("Gui.Dashboard.HoursAgo", time=int(diff // 3600))
elif diff < 1296000: elif diff < 1296000:
# < 15 days
return t("Gui.Dashboard.DaysAgo", time=int(diff // 86400)) return t("Gui.Dashboard.DaysAgo", time=int(diff // 86400))
else: else:
# > 15 days # >= 15 days
return t("Gui.Dashboard.LongTimeAgo") return t("Gui.Dashboard.LongTimeAgo")
+2 -2
View File
@@ -16,8 +16,8 @@ import time
from subprocess import PIPE, Popen from subprocess import PIPE, Popen
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from module.logger import logger
from module.config.utils import random_id from module.config.utils import random_id
from module.logger import logger
from module.webui.setting import State from module.webui.setting import State
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -41,7 +41,7 @@ def am_i_the_only_thread() -> bool:
def remote_access_service( def remote_access_service(
local_host="127.0.0.1", local_host="127.0.0.1",
local_port=22367, local_port=23467,
server="app.pywebio.online", server="app.pywebio.online",
server_port=1022, server_port=1022,
remote_port="/", remote_port="/",
+3
View File
@@ -5,6 +5,7 @@ import time
from typing import Generator, List, Tuple from typing import Generator, List, Tuple
import requests import requests
from deploy.Windows.config import ExecutionError from deploy.Windows.config import ExecutionError
from deploy.Windows.git import GitManager from deploy.Windows.git import GitManager
from deploy.Windows.pip import PipManager from deploy.Windows.pip import PipManager
@@ -20,6 +21,7 @@ from module.webui.utils import TaskHandler, get_next_time
class Updater(DeployConfig, GitManager, PipManager): class Updater(DeployConfig, GitManager, PipManager):
def __init__(self, file=DEPLOY_CONFIG): def __init__(self, file=DEPLOY_CONFIG):
super().__init__(file=file) super().__init__(file=file)
self.set_repo()
self.state = 0 self.state = 0
self.event: threading.Event = None self.event: threading.Event = None
@@ -194,6 +196,7 @@ class Updater(DeployConfig, GitManager, PipManager):
def update(self): def update(self):
logger.hr("Run update") logger.hr("Run update")
self.set_repo()
try: try:
self.git_install() self.git_install()
self.pip_install() self.pip_install()
+9 -5
View File
@@ -9,17 +9,17 @@ from queue import Queue
from typing import Callable, Generator, List from typing import Callable, Generator, List
import pywebio import pywebio
from module.config.utils import deep_iter
from module.logger import logger
from module.webui.setting import State
from pywebio.input import PASSWORD, input from pywebio.input import PASSWORD, input
from pywebio.output import PopupSize, popup, put_html, toast from pywebio.output import PopupSize, popup, put_html, toast
from pywebio.session import eval_js from pywebio.session import eval_js
from pywebio.session import info as session_info from pywebio.session import info as session_info
from pywebio.session import register_thread, run_js from pywebio.session import register_thread, run_js
from rich.console import Console, ConsoleOptions from rich.console import Console
from rich.terminal_theme import TerminalTheme from rich.terminal_theme import TerminalTheme
from module.config.utils import deep_iter
from module.logger import logger
from module.webui.setting import State
RE_DATETIME = ( RE_DATETIME = (
r"\d{4}\-(0\d|1[0-2])\-([0-2]\d|[3][0-1]) " r"\d{4}\-(0\d|1[0-2])\-([0-2]\d|[3][0-1]) "
@@ -455,7 +455,11 @@ def get_localstorage(key):
def re_fullmatch(pattern, string): def re_fullmatch(pattern, string):
if pattern == "datetime": if pattern == "datetime":
pattern = RE_DATETIME try:
datetime.datetime.fromisoformat(string)
return True
except ValueError:
return False
# elif: # elif:
return re.fullmatch(pattern=pattern, string=string) return re.fullmatch(pattern=pattern, string=string)
+30 -135
View File
@@ -22,15 +22,8 @@ ACCOUNT_INFO_CHECK = ButtonWrapper(
) )
BACK = ButtonWrapper( BACK = ButtonWrapper(
name='BACK', name='BACK',
jp=Button( share=Button(
file='./assets/jp/base/page/BACK.png', file='./assets/share/base/page/BACK.png',
area=(34, 19, 81, 56),
search=(14, 0, 101, 76),
color=(93, 118, 164),
button=(34, 19, 81, 56),
),
en=Button(
file='./assets/en/base/page/BACK.png',
area=(34, 19, 81, 56), area=(34, 19, 81, 56),
search=(14, 0, 101, 76), search=(14, 0, 101, 76),
color=(93, 118, 164), color=(93, 118, 164),
@@ -141,15 +134,8 @@ GACHA_CHECK = ButtonWrapper(
) )
HOME = ButtonWrapper( HOME = ButtonWrapper(
name='HOME', name='HOME',
jp=Button( share=Button(
file='./assets/jp/base/page/HOME.png', file='./assets/share/base/page/HOME.png',
area=(1218, 8, 1253, 41),
search=(1198, 0, 1273, 61),
color=(168, 182, 205),
button=(1218, 8, 1253, 41),
),
en=Button(
file='./assets/en/base/page/HOME.png',
area=(1218, 8, 1253, 41), area=(1218, 8, 1253, 41),
search=(1198, 0, 1273, 61), search=(1198, 0, 1273, 61),
color=(168, 182, 205), color=(168, 182, 205),
@@ -158,15 +144,8 @@ HOME = ButtonWrapper(
) )
LOADING_CHECK = ButtonWrapper( LOADING_CHECK = ButtonWrapper(
name='LOADING_CHECK', name='LOADING_CHECK',
jp=Button( share=Button(
file='./assets/jp/base/page/LOADING_CHECK.png', file='./assets/share/base/page/LOADING_CHECK.png',
area=(1084, 659, 1120, 674),
search=(1064, 639, 1140, 694),
color=(173, 196, 219),
button=(1084, 659, 1120, 674),
),
en=Button(
file='./assets/en/base/page/LOADING_CHECK.png',
area=(1084, 659, 1120, 674), area=(1084, 659, 1120, 674),
search=(1064, 639, 1140, 694), search=(1064, 639, 1140, 694),
color=(173, 196, 219), color=(173, 196, 219),
@@ -192,15 +171,8 @@ MAIL_CHECK = ButtonWrapper(
) )
MAIN_GO_TO_CAFE = ButtonWrapper( MAIN_GO_TO_CAFE = ButtonWrapper(
name='MAIN_GO_TO_CAFE', name='MAIN_GO_TO_CAFE',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_CAFE.png', file='./assets/share/base/page/MAIN_GO_TO_CAFE.png',
area=(81, 638, 102, 668),
search=(61, 618, 122, 688),
color=(156, 209, 233),
button=(81, 638, 102, 668),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_CAFE.png',
area=(81, 638, 102, 668), area=(81, 638, 102, 668),
search=(61, 618, 122, 688), search=(61, 618, 122, 688),
color=(156, 209, 233), color=(156, 209, 233),
@@ -209,15 +181,8 @@ MAIN_GO_TO_CAFE = ButtonWrapper(
) )
MAIN_GO_TO_CIRCLE = ButtonWrapper( MAIN_GO_TO_CIRCLE = ButtonWrapper(
name='MAIN_GO_TO_CIRCLE', name='MAIN_GO_TO_CIRCLE',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_CIRCLE.png', file='./assets/share/base/page/MAIN_GO_TO_CIRCLE.png',
area=(540, 631, 583, 660),
search=(520, 611, 603, 680),
color=(131, 204, 234),
button=(540, 631, 583, 660),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_CIRCLE.png',
area=(540, 631, 583, 660), area=(540, 631, 583, 660),
search=(520, 611, 603, 680), search=(520, 611, 603, 680),
color=(131, 204, 234), color=(131, 204, 234),
@@ -226,15 +191,8 @@ MAIN_GO_TO_CIRCLE = ButtonWrapper(
) )
MAIN_GO_TO_CRAFTING = ButtonWrapper( MAIN_GO_TO_CRAFTING = ButtonWrapper(
name='MAIN_GO_TO_CRAFTING', name='MAIN_GO_TO_CRAFTING',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_CRAFTING.png', file='./assets/share/base/page/MAIN_GO_TO_CRAFTING.png',
area=(665, 622, 693, 664),
search=(645, 602, 713, 684),
color=(192, 229, 241),
button=(665, 622, 693, 664),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_CRAFTING.png',
area=(665, 622, 693, 664), area=(665, 622, 693, 664),
search=(645, 602, 713, 684), search=(645, 602, 713, 684),
color=(192, 229, 241), color=(192, 229, 241),
@@ -243,15 +201,8 @@ MAIN_GO_TO_CRAFTING = ButtonWrapper(
) )
MAIN_GO_TO_GACHA = ButtonWrapper( MAIN_GO_TO_GACHA = ButtonWrapper(
name='MAIN_GO_TO_GACHA', name='MAIN_GO_TO_GACHA',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_GACHA.png', file='./assets/share/base/page/MAIN_GO_TO_GACHA.png',
area=(900, 623, 924, 670),
search=(880, 603, 944, 690),
color=(157, 219, 241),
button=(900, 623, 924, 670),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_GACHA.png',
area=(900, 623, 924, 670), area=(900, 623, 924, 670),
search=(880, 603, 944, 690), search=(880, 603, 944, 690),
color=(157, 219, 241), color=(157, 219, 241),
@@ -260,15 +211,8 @@ MAIN_GO_TO_GACHA = ButtonWrapper(
) )
MAIN_GO_TO_MAIL = ButtonWrapper( MAIN_GO_TO_MAIL = ButtonWrapper(
name='MAIN_GO_TO_MAIL', name='MAIN_GO_TO_MAIL',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_MAIL.png', file='./assets/share/base/page/MAIN_GO_TO_MAIL.png',
area=(1130, 29, 1156, 49),
search=(1110, 9, 1176, 69),
color=(94, 121, 166),
button=(1130, 29, 1156, 49),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_MAIL.png',
area=(1130, 29, 1156, 49), area=(1130, 29, 1156, 49),
search=(1110, 9, 1176, 69), search=(1110, 9, 1176, 69),
color=(94, 121, 166), color=(94, 121, 166),
@@ -277,15 +221,8 @@ MAIN_GO_TO_MAIL = ButtonWrapper(
) )
MAIN_GO_TO_MOMOTALK = ButtonWrapper( MAIN_GO_TO_MOMOTALK = ButtonWrapper(
name='MAIN_GO_TO_MOMOTALK', name='MAIN_GO_TO_MOMOTALK',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_MOMOTALK.png', file='./assets/share/base/page/MAIN_GO_TO_MOMOTALK.png',
area=(154, 134, 177, 158),
search=(134, 114, 197, 178),
color=(255, 219, 227),
button=(154, 134, 177, 158),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_MOMOTALK.png',
area=(154, 134, 177, 158), area=(154, 134, 177, 158),
search=(134, 114, 197, 178), search=(134, 114, 197, 178),
color=(255, 219, 227), color=(255, 219, 227),
@@ -294,15 +231,8 @@ MAIN_GO_TO_MOMOTALK = ButtonWrapper(
) )
MAIN_GO_TO_PURCHASE = ButtonWrapper( MAIN_GO_TO_PURCHASE = ButtonWrapper(
name='MAIN_GO_TO_PURCHASE', name='MAIN_GO_TO_PURCHASE',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_PURCHASE.png', file='./assets/share/base/page/MAIN_GO_TO_PURCHASE.png',
area=(148, 204, 183, 253),
search=(128, 184, 203, 273),
color=(172, 214, 239),
button=(148, 204, 183, 253),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_PURCHASE.png',
area=(148, 204, 183, 253), area=(148, 204, 183, 253),
search=(128, 184, 203, 273), search=(128, 184, 203, 273),
color=(172, 214, 239), color=(172, 214, 239),
@@ -311,15 +241,8 @@ MAIN_GO_TO_PURCHASE = ButtonWrapper(
) )
MAIN_GO_TO_SCHEDULE = ButtonWrapper( MAIN_GO_TO_SCHEDULE = ButtonWrapper(
name='MAIN_GO_TO_SCHEDULE', name='MAIN_GO_TO_SCHEDULE',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_SCHEDULE.png', file='./assets/share/base/page/MAIN_GO_TO_SCHEDULE.png',
area=(194, 638, 216, 672),
search=(174, 618, 236, 692),
color=(149, 194, 222),
button=(194, 638, 216, 672),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_SCHEDULE.png',
area=(194, 638, 216, 672), area=(194, 638, 216, 672),
search=(174, 618, 236, 692), search=(174, 618, 236, 692),
color=(149, 194, 222), color=(149, 194, 222),
@@ -328,15 +251,8 @@ MAIN_GO_TO_SCHEDULE = ButtonWrapper(
) )
MAIN_GO_TO_SHOP = ButtonWrapper( MAIN_GO_TO_SHOP = ButtonWrapper(
name='MAIN_GO_TO_SHOP', name='MAIN_GO_TO_SHOP',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_SHOP.png', file='./assets/share/base/page/MAIN_GO_TO_SHOP.png',
area=(773, 630, 816, 667),
search=(753, 610, 836, 687),
color=(146, 208, 235),
button=(773, 630, 816, 667),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_SHOP.png',
area=(773, 630, 816, 667), area=(773, 630, 816, 667),
search=(753, 610, 836, 687), search=(753, 610, 836, 687),
color=(146, 208, 235), color=(146, 208, 235),
@@ -345,15 +261,8 @@ MAIN_GO_TO_SHOP = ButtonWrapper(
) )
MAIN_GO_TO_TASK = ButtonWrapper( MAIN_GO_TO_TASK = ButtonWrapper(
name='MAIN_GO_TO_TASK', name='MAIN_GO_TO_TASK',
jp=Button( share=Button(
file='./assets/jp/base/page/MAIN_GO_TO_TASK.png', file='./assets/share/base/page/MAIN_GO_TO_TASK.png',
area=(52, 220, 78, 248),
search=(32, 200, 98, 268),
color=(226, 207, 203),
button=(52, 220, 78, 248),
),
en=Button(
file='./assets/en/base/page/MAIN_GO_TO_TASK.png',
area=(52, 220, 78, 248), area=(52, 220, 78, 248),
search=(32, 200, 98, 268), search=(32, 200, 98, 268),
color=(226, 207, 203), color=(226, 207, 203),
@@ -396,15 +305,8 @@ MISSION_CHECK = ButtonWrapper(
) )
MOMOTALK_CHECK = ButtonWrapper( MOMOTALK_CHECK = ButtonWrapper(
name='MOMOTALK_CHECK', name='MOMOTALK_CHECK',
jp=Button( share=Button(
file='./assets/jp/base/page/MOMOTALK_CHECK.png', file='./assets/share/base/page/MOMOTALK_CHECK.png',
area=(144, 107, 169, 130),
search=(124, 87, 189, 150),
color=(253, 211, 219),
button=(144, 107, 169, 130),
),
en=Button(
file='./assets/en/base/page/MOMOTALK_CHECK.png',
area=(144, 107, 169, 130), area=(144, 107, 169, 130),
search=(124, 87, 189, 150), search=(124, 87, 189, 150),
color=(253, 211, 219), color=(253, 211, 219),
@@ -413,15 +315,8 @@ MOMOTALK_CHECK = ButtonWrapper(
) )
MOMOTALK_GO_TO_MAIN = ButtonWrapper( MOMOTALK_GO_TO_MAIN = ButtonWrapper(
name='MOMOTALK_GO_TO_MAIN', name='MOMOTALK_GO_TO_MAIN',
jp=Button( share=Button(
file='./assets/jp/base/page/MOMOTALK_GO_TO_MAIN.png', file='./assets/share/base/page/MOMOTALK_GO_TO_MAIN.png',
area=(1108, 105, 1134, 131),
search=(1088, 85, 1154, 151),
color=(252, 182, 194),
button=(1108, 105, 1134, 131),
),
en=Button(
file='./assets/en/base/page/MOMOTALK_GO_TO_MAIN.png',
area=(1108, 105, 1134, 131), area=(1108, 105, 1134, 131),
search=(1088, 85, 1154, 151), search=(1088, 85, 1154, 151),
color=(252, 182, 194), color=(252, 182, 194),
+6 -27
View File
@@ -39,15 +39,8 @@ AP_EXCEED = ButtonWrapper(
) )
DAILY_NEWS = ButtonWrapper( DAILY_NEWS = ButtonWrapper(
name='DAILY_NEWS', name='DAILY_NEWS',
jp=Button( share=Button(
file='./assets/jp/base/popup/DAILY_NEWS.png', file='./assets/share/base/popup/DAILY_NEWS.png',
area=(120, 89, 326, 113),
search=(100, 69, 346, 133),
color=(150, 204, 253),
button=(1128, 89, 1156, 117),
),
en=Button(
file='./assets/en/base/popup/DAILY_NEWS.png',
area=(120, 89, 326, 113), area=(120, 89, 326, 113),
search=(100, 69, 346, 133), search=(100, 69, 346, 133),
color=(150, 204, 253), color=(150, 204, 253),
@@ -56,15 +49,8 @@ DAILY_NEWS = ButtonWrapper(
) )
DAILY_REWARD = ButtonWrapper( DAILY_REWARD = ButtonWrapper(
name='DAILY_REWARD', name='DAILY_REWARD',
jp=Button( share=Button(
file='./assets/jp/base/popup/DAILY_REWARD.png', file='./assets/share/base/popup/DAILY_REWARD.png',
area=(416, 165, 434, 216),
search=(396, 145, 454, 236),
color=(203, 227, 237),
button=(920, 632, 1140, 712),
),
en=Button(
file='./assets/en/base/popup/DAILY_REWARD.png',
area=(416, 165, 434, 216), area=(416, 165, 434, 216),
search=(396, 145, 454, 236), search=(396, 145, 454, 236),
color=(203, 227, 237), color=(203, 227, 237),
@@ -73,15 +59,8 @@ DAILY_REWARD = ButtonWrapper(
) )
GET_NEW_STUDENT = ButtonWrapper( GET_NEW_STUDENT = ButtonWrapper(
name='GET_NEW_STUDENT', name='GET_NEW_STUDENT',
jp=Button( share=Button(
file='./assets/jp/base/popup/GET_NEW_STUDENT.png', file='./assets/share/base/popup/GET_NEW_STUDENT.png',
area=(32, 93, 158, 114),
search=(12, 73, 178, 134),
color=(125, 132, 92),
button=(934, 643, 1263, 714),
),
en=Button(
file='./assets/en/base/popup/GET_NEW_STUDENT.png',
area=(32, 93, 158, 114), area=(32, 93, 158, 114),
search=(12, 73, 178, 134), search=(12, 73, 178, 134),
color=(125, 132, 92), color=(125, 132, 92),

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