Merge branch 'LmeSzinc:master' into master

This commit is contained in:
Schwarze-Katze 2024-04-01 00:27:15 +08:00 committed by GitHub
commit 792eb2157a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
89 changed files with 1608 additions and 358 deletions

8
.gitignore vendored
View File

@ -19,6 +19,14 @@ config/reloadflag
config/reloadalas
test.py
test/
resources/
locales/
*.pak
*.dll
*.dat
v8_context_snapshot.bin
snapshot_blob.bin
vk_swiftshader_icd.json
# Created by .ignore support plugin (hsz.mobi)

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -2,6 +2,7 @@
"Alas": {
"Emulator": {
"Serial": "auto",
"GameClient": "android",
"PackageName": "auto",
"GameLanguage": "auto",
"ScreenshotMethod": "scrcpy",
@ -23,6 +24,11 @@
"ScreenshotInterval": 0.2,
"CombatScreenshotInterval": 1.0,
"WhenTaskQueueEmpty": "goto_main"
},
"CloudStorage": {
"CloudRemainSeasonPass": {},
"CloudRemainPaid": {},
"CloudRemainFree": {}
}
},
"Restart": {

View File

@ -92,8 +92,9 @@ def iter_images():
for server in ASSET_SERVER:
for path, folders, files in os.walk(os.path.join(AzurLaneConfig.ASSETS_FOLDER, server)):
for file in files:
file = os.path.join(path, file).replace('\\', '/')
yield AssetsImage(file)
if not file.startswith('.'):
file = os.path.join(path, file).replace('\\', '/')
yield AssetsImage(file)
@dataclass

View File

@ -525,12 +525,14 @@ class KeywordExtract:
)
try:
from tasks.rogue.event.event import OcrRogueEventOption
except AttributeError:
except AttributeError as e:
logger.error(e)
logger.critical(
f'Importing OcrRogueEventOption fails, probably due to changes in {output_file}')
try:
from tasks.rogue.event.preset import STRATEGIES
except AttributeError:
except AttributeError as e:
logger.error(e)
logger.critical(
f'Importing preset strategies fails, probably due to changes in {output_file}')

View File

@ -62,6 +62,18 @@ class AzurLaneAutoScript:
logger.exception(e)
exit(1)
def restart(self):
raise NotImplemented
def start(self):
raise NotImplemented
def stop(self):
raise NotImplemented
def goto_main(self):
raise NotImplemented
def run(self, command):
try:
self.device.screenshot()
@ -211,7 +223,7 @@ class AzurLaneAutoScript:
method = self.config.Optimization_WhenTaskQueueEmpty
if method == 'close_game':
logger.info('Close game during wait')
self.device.app_stop()
self.run('stop')
release_resources()
self.device.release_during_wait()
if not self.wait_until(task.next_run):

View File

@ -6,6 +6,7 @@ from module.base.timer import Timer
from module.base.utils import *
from module.config.config import AzurLaneConfig
from module.device.device import Device
from module.device.method.utils import HierarchyButton
from module.logger import logger
from module.webui.setting import cached_class_property
@ -132,9 +133,56 @@ class ModuleBase:
return appear
appear = match_template
def xpath(self, xpath) -> HierarchyButton:
if isinstance(xpath, str):
return HierarchyButton(self.device.hierarchy, xpath)
else:
return xpath
def xpath_appear(self, xpath: str, interval=0):
button = self.xpath(xpath)
self.device.stuck_record_add(button)
if interval and not self.interval_is_reached(button, interval=interval):
return False
appear = bool(button)
if appear and interval:
self.interval_reset(button, interval=interval)
return appear
def appear(self, button, interval=0, similarity=0.85):
"""
Args:
button (Button, ButtonWrapper, HierarchyButton, str):
interval (int, float): interval between two active events.
Returns:
bool:
Examples:
Template match:
```
self.device.screenshot()
self.appear(POPUP_CONFIRM)
```
Hierarchy detection (detect elements with xpath):
```
self.device.dump_hierarchy()
self.appear('//*[@resource-id="..."]')
```
"""
if isinstance(button, (HierarchyButton, str)):
return self.xpath_appear(button, interval=interval)
else:
return self.match_template(button, interval=interval, similarity=similarity)
def appear_then_click(self, button, interval=5, similarity=0.85):
button = self.xpath(button)
appear = self.appear(button, interval=interval, similarity=similarity)
if appear:
self.device.click(button)

View File

@ -6,6 +6,14 @@
"value": "auto",
"valuetype": "str"
},
"GameClient": {
"type": "select",
"value": "android",
"option": [
"android",
"cloud_android"
]
},
"PackageName": {
"type": "select",
"value": "auto",
@ -131,6 +139,26 @@
"close_game"
]
}
},
"CloudStorage": {
"CloudRemainSeasonPass": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredInt"
},
"CloudRemainPaid": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredInt"
},
"CloudRemainFree": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredInt"
}
}
},
"Restart": {
@ -165,11 +193,13 @@
"Dungeon": {
"Scheduler": {
"Enable": {
"type": "checkbox",
"type": "state",
"value": true,
"option": [
true,
false
true
],
"option_bold": [
true
]
},
"NextRun": {
@ -205,8 +235,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape",
"Calyx_Crimson_Preservation_Herta_SupplyZone",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden",
"Calyx_Crimson_Erudition_Jarilo_RivetTown",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape",
@ -216,6 +248,7 @@
"Stagnant_Shadow_Perdition",
"Stagnant_Shadow_Blaze",
"Stagnant_Shadow_Scorch",
"Stagnant_Shadow_Ire",
"Stagnant_Shadow_Rime",
"Stagnant_Shadow_Icicle",
"Stagnant_Shadow_Nectar",
@ -243,7 +276,6 @@
"type": "select",
"value": "Calyx_Golden_Treasures",
"option": [
"do_not_participate",
"Calyx_Golden_Memories_Jarilo_VI",
"Calyx_Golden_Memories_The_Xianzhou_Luofu",
"Calyx_Golden_Memories_Penacony",
@ -256,8 +288,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape",
"Calyx_Crimson_Preservation_Herta_SupplyZone",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden",
"Calyx_Crimson_Erudition_Jarilo_RivetTown",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape",
@ -269,7 +303,6 @@
"type": "select",
"value": "Cavern_of_Corrosion_Path_of_Providence",
"option": [
"do_not_participate",
"Cavern_of_Corrosion_Path_of_Gelid_Wind",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch",
"Cavern_of_Corrosion_Path_of_Drifting",
@ -322,8 +355,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape",
"Calyx_Crimson_Preservation_Herta_SupplyZone",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden",
"Calyx_Crimson_Erudition_Jarilo_RivetTown",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape",
@ -340,6 +375,7 @@
"Stagnant_Shadow_Perdition",
"Stagnant_Shadow_Blaze",
"Stagnant_Shadow_Scorch",
"Stagnant_Shadow_Ire",
"Stagnant_Shadow_Rime",
"Stagnant_Shadow_Icicle",
"Stagnant_Shadow_Nectar",
@ -386,6 +422,7 @@
"value": "FirstCharacter",
"option": [
"FirstCharacter",
"Acheron",
"Argenti",
"Arlan",
"Asta",
@ -398,6 +435,7 @@
"DanHengImbibitorLunae",
"DrRatio",
"FuXuan",
"Gallagher",
"Gepard",
"Guinaifen",
"Hanya",
@ -476,11 +514,13 @@
"DailyQuest": {
"Scheduler": {
"Enable": {
"type": "checkbox",
"type": "state",
"value": true,
"option": [
true,
false
true
],
"option_bold": [
true
]
},
"NextRun": {
@ -911,11 +951,13 @@
"BattlePass": {
"Scheduler": {
"Enable": {
"type": "checkbox",
"type": "state",
"value": true,
"option": [
true,
false
true
],
"option_bold": [
true
]
},
"NextRun": {
@ -996,11 +1038,13 @@
"Assignment": {
"Scheduler": {
"Enable": {
"type": "checkbox",
"type": "state",
"value": true,
"option": [
true,
false
true
],
"option_bold": [
true
]
},
"NextRun": {
@ -1292,6 +1336,7 @@
"value": "FirstCharacter",
"option": [
"FirstCharacter",
"Acheron",
"Argenti",
"Arlan",
"Asta",
@ -1304,6 +1349,7 @@
"DanHengImbibitorLunae",
"DrRatio",
"FuXuan",
"Gallagher",
"Gepard",
"Guinaifen",
"Hanya",

View File

@ -18,6 +18,9 @@ Emulator:
Serial:
value: auto
valuetype: str
GameClient:
value: android
option: [ android, cloud_android ]
PackageName:
value: auto
option: [ auto, ]
@ -72,6 +75,13 @@ Optimization:
WhenTaskQueueEmpty:
value: goto_main
option: [ stay_there, goto_main, close_game ]
CloudStorage:
CloudRemainSeasonPass:
stored: StoredInt
CloudRemainPaid:
stored: StoredInt
CloudRemainFree:
stored: StoredInt
# ==================== Daily ====================
@ -82,10 +92,10 @@ Dungeon:
option: [ ]
NameAtDoubleCalyx:
value: Calyx_Golden_Treasures
option: [ do_not_participate, ]
option: [ ]
NameAtDoubleRelic:
value: Cavern_of_Corrosion_Path_of_Providence
option: [ do_not_participate, ]
option: [ ]
Team:
value: 1
option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

View File

@ -23,6 +23,34 @@ Restart:
# ==================== Daily ====================
Dungeon:
Scheduler:
Enable:
type: state
value: true
option: [ true, ]
option_bold: [ true, ]
DailyQuest:
Scheduler:
Enable:
type: state
value: true
option: [ true, ]
option_bold: [ true, ]
BattlePass:
Scheduler:
Enable:
type: state
value: true
option: [ true, ]
option_bold: [ true, ]
Assignment:
Scheduler:
Enable:
type: state
value: true
option: [ true, ]
option_bold: [ true, ]
DataUpdate:
Scheduler:
Enable:

View File

@ -101,6 +101,42 @@
"order": 8,
"color": "#fc8f8b"
},
"CloudRemainSeasonPass": {
"name": "CloudRemainSeasonPass",
"path": "Alas.CloudStorage.CloudRemainSeasonPass",
"i18n": "CloudStorage.CloudRemainSeasonPass.name",
"stored": "StoredInt",
"attrs": {
"time": "2020-01-01 00:00:00",
"value": 0
},
"order": 0,
"color": "#777777"
},
"CloudRemainPaid": {
"name": "CloudRemainPaid",
"path": "Alas.CloudStorage.CloudRemainPaid",
"i18n": "CloudStorage.CloudRemainPaid.name",
"stored": "StoredInt",
"attrs": {
"time": "2020-01-01 00:00:00",
"value": 0
},
"order": 0,
"color": "#777777"
},
"CloudRemainFree": {
"name": "CloudRemainFree",
"path": "Alas.CloudStorage.CloudRemainFree",
"i18n": "CloudStorage.CloudRemainFree.name",
"stored": "StoredInt",
"attrs": {
"time": "2020-01-01 00:00:00",
"value": 0
},
"order": 0,
"color": "#777777"
},
"Immersifier": {
"name": "Immersifier",
"path": "Dungeon.DungeonStorage.Immersifier",

View File

@ -13,6 +13,7 @@ Alas:
- EmulatorInfo
- Error
- Optimization
- CloudStorage
Restart:
- Scheduler

View File

@ -176,6 +176,12 @@ class AzurLaneConfig(ConfigUpdater, ManualConfig, GeneratedConfig, ConfigWatcher
self.data, keys="Alas.Optimization.CloseGameDuringWait", default=False
)
@property
def is_cloud_game(self):
return deep_get(
self.data, keys="Alas.Emulator.GameClient"
) == 'cloud_android'
@cached_property
def stored(self) -> StoredGenerated:
stored = StoredGenerated()

View File

@ -17,6 +17,7 @@ class GeneratedConfig:
# Group `Emulator`
Emulator_Serial = 'auto'
Emulator_GameClient = 'android' # android, cloud_android
Emulator_PackageName = 'auto' # auto, CN-Official, CN-Bilibili, OVERSEA-America, OVERSEA-Asia, OVERSEA-Europe, OVERSEA-TWHKMO
Emulator_GameLanguage = 'auto' # auto, cn, en
Emulator_ScreenshotMethod = 'auto' # auto, ADB, ADB_nc, uiautomator2, aScreenCap, aScreenCap_nc, DroidCast, DroidCast_raw, scrcpy
@ -39,21 +40,26 @@ class GeneratedConfig:
Optimization_CombatScreenshotInterval = 1.0
Optimization_WhenTaskQueueEmpty = 'goto_main' # stay_there, goto_main, close_game
# Group `CloudStorage`
CloudStorage_CloudRemainSeasonPass = {}
CloudStorage_CloudRemainPaid = {}
CloudStorage_CloudRemainFree = {}
# Group `Dungeon`
Dungeon_Name = 'Calyx_Golden_Treasures' # Calyx_Golden_Memories_Jarilo_VI, Calyx_Golden_Memories_The_Xianzhou_Luofu, Calyx_Golden_Memories_Penacony, Calyx_Golden_Aether_Jarilo_VI, Calyx_Golden_Aether_The_Xianzhou_Luofu, Calyx_Golden_Aether_Penacony, Calyx_Golden_Treasures_Jarilo_VI, Calyx_Golden_Treasures_The_Xianzhou_Luofu, Calyx_Golden_Treasures_Penacony, Calyx_Crimson_Destruction_Herta_StorageZone, Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape, Calyx_Crimson_Preservation_Herta_SupplyZone, Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains, Calyx_Crimson_Abundance_Jarilo_BackwaterPass, Calyx_Crimson_Erudition_Jarilo_RivetTown, Calyx_Crimson_Harmony_Jarilo_RobotSettlement, Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape, Calyx_Crimson_Nihility_Jarilo_GreatMine, Calyx_Crimson_Nihility_Luofu_AlchemyCommission, Stagnant_Shadow_Spike, Stagnant_Shadow_Perdition, Stagnant_Shadow_Blaze, Stagnant_Shadow_Scorch, Stagnant_Shadow_Rime, Stagnant_Shadow_Icicle, Stagnant_Shadow_Nectar, Stagnant_Shadow_Fulmination, Stagnant_Shadow_Doom, Stagnant_Shadow_Gust, Stagnant_Shadow_Celestial, Stagnant_Shadow_Quanta, Stagnant_Shadow_Abomination, Stagnant_Shadow_Roast, Stagnant_Shadow_Mirage, Stagnant_Shadow_Puppetry, Cavern_of_Corrosion_Path_of_Gelid_Wind, Cavern_of_Corrosion_Path_of_Jabbing_Punch, Cavern_of_Corrosion_Path_of_Drifting, Cavern_of_Corrosion_Path_of_Providence, Cavern_of_Corrosion_Path_of_Holy_Hymn, Cavern_of_Corrosion_Path_of_Conflagration, Cavern_of_Corrosion_Path_of_Elixir_Seekers, Cavern_of_Corrosion_Path_of_Darkness, Cavern_of_Corrosion_Path_of_Dreamdive
Dungeon_NameAtDoubleCalyx = 'Calyx_Golden_Treasures' # do_not_participate, Calyx_Golden_Memories_Jarilo_VI, Calyx_Golden_Memories_The_Xianzhou_Luofu, Calyx_Golden_Memories_Penacony, Calyx_Golden_Aether_Jarilo_VI, Calyx_Golden_Aether_The_Xianzhou_Luofu, Calyx_Golden_Aether_Penacony, Calyx_Golden_Treasures_Jarilo_VI, Calyx_Golden_Treasures_The_Xianzhou_Luofu, Calyx_Golden_Treasures_Penacony, Calyx_Crimson_Destruction_Herta_StorageZone, Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape, Calyx_Crimson_Preservation_Herta_SupplyZone, Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains, Calyx_Crimson_Abundance_Jarilo_BackwaterPass, Calyx_Crimson_Erudition_Jarilo_RivetTown, Calyx_Crimson_Harmony_Jarilo_RobotSettlement, Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape, Calyx_Crimson_Nihility_Jarilo_GreatMine, Calyx_Crimson_Nihility_Luofu_AlchemyCommission
Dungeon_NameAtDoubleRelic = 'Cavern_of_Corrosion_Path_of_Providence' # do_not_participate, Cavern_of_Corrosion_Path_of_Gelid_Wind, Cavern_of_Corrosion_Path_of_Jabbing_Punch, Cavern_of_Corrosion_Path_of_Drifting, Cavern_of_Corrosion_Path_of_Providence, Cavern_of_Corrosion_Path_of_Holy_Hymn, Cavern_of_Corrosion_Path_of_Conflagration, Cavern_of_Corrosion_Path_of_Elixir_Seekers, Cavern_of_Corrosion_Path_of_Darkness, Cavern_of_Corrosion_Path_of_Dreamdive
Dungeon_Name = 'Calyx_Golden_Treasures' # Calyx_Golden_Memories_Jarilo_VI, Calyx_Golden_Memories_The_Xianzhou_Luofu, Calyx_Golden_Memories_Penacony, Calyx_Golden_Aether_Jarilo_VI, Calyx_Golden_Aether_The_Xianzhou_Luofu, Calyx_Golden_Aether_Penacony, Calyx_Golden_Treasures_Jarilo_VI, Calyx_Golden_Treasures_The_Xianzhou_Luofu, Calyx_Golden_Treasures_Penacony, Calyx_Crimson_Destruction_Herta_StorageZone, Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape, Calyx_Crimson_Preservation_Herta_SupplyZone, Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark, Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains, Calyx_Crimson_Abundance_Jarilo_BackwaterPass, Calyx_Crimson_Abundance_Luofu_FyxestrollGarden, Calyx_Crimson_Erudition_Jarilo_RivetTown, Calyx_Crimson_Harmony_Jarilo_RobotSettlement, Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape, Calyx_Crimson_Nihility_Jarilo_GreatMine, Calyx_Crimson_Nihility_Luofu_AlchemyCommission, Stagnant_Shadow_Spike, Stagnant_Shadow_Perdition, Stagnant_Shadow_Blaze, Stagnant_Shadow_Scorch, Stagnant_Shadow_Ire, Stagnant_Shadow_Rime, Stagnant_Shadow_Icicle, Stagnant_Shadow_Nectar, Stagnant_Shadow_Fulmination, Stagnant_Shadow_Doom, Stagnant_Shadow_Gust, Stagnant_Shadow_Celestial, Stagnant_Shadow_Quanta, Stagnant_Shadow_Abomination, Stagnant_Shadow_Roast, Stagnant_Shadow_Mirage, Stagnant_Shadow_Puppetry, Cavern_of_Corrosion_Path_of_Gelid_Wind, Cavern_of_Corrosion_Path_of_Jabbing_Punch, Cavern_of_Corrosion_Path_of_Drifting, Cavern_of_Corrosion_Path_of_Providence, Cavern_of_Corrosion_Path_of_Holy_Hymn, Cavern_of_Corrosion_Path_of_Conflagration, Cavern_of_Corrosion_Path_of_Elixir_Seekers, Cavern_of_Corrosion_Path_of_Darkness, Cavern_of_Corrosion_Path_of_Dreamdive
Dungeon_NameAtDoubleCalyx = 'Calyx_Golden_Treasures' # Calyx_Golden_Memories_Jarilo_VI, Calyx_Golden_Memories_The_Xianzhou_Luofu, Calyx_Golden_Memories_Penacony, Calyx_Golden_Aether_Jarilo_VI, Calyx_Golden_Aether_The_Xianzhou_Luofu, Calyx_Golden_Aether_Penacony, Calyx_Golden_Treasures_Jarilo_VI, Calyx_Golden_Treasures_The_Xianzhou_Luofu, Calyx_Golden_Treasures_Penacony, Calyx_Crimson_Destruction_Herta_StorageZone, Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape, Calyx_Crimson_Preservation_Herta_SupplyZone, Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark, Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains, Calyx_Crimson_Abundance_Jarilo_BackwaterPass, Calyx_Crimson_Abundance_Luofu_FyxestrollGarden, Calyx_Crimson_Erudition_Jarilo_RivetTown, Calyx_Crimson_Harmony_Jarilo_RobotSettlement, Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape, Calyx_Crimson_Nihility_Jarilo_GreatMine, Calyx_Crimson_Nihility_Luofu_AlchemyCommission
Dungeon_NameAtDoubleRelic = 'Cavern_of_Corrosion_Path_of_Providence' # Cavern_of_Corrosion_Path_of_Gelid_Wind, Cavern_of_Corrosion_Path_of_Jabbing_Punch, Cavern_of_Corrosion_Path_of_Drifting, Cavern_of_Corrosion_Path_of_Providence, Cavern_of_Corrosion_Path_of_Holy_Hymn, Cavern_of_Corrosion_Path_of_Conflagration, Cavern_of_Corrosion_Path_of_Elixir_Seekers, Cavern_of_Corrosion_Path_of_Darkness, Cavern_of_Corrosion_Path_of_Dreamdive
Dungeon_Team = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
# Group `DungeonDaily`
DungeonDaily_CalyxGolden = 'Calyx_Golden_Treasures_Jarilo_VI' # do_not_achieve, Calyx_Golden_Memories_Jarilo_VI, Calyx_Golden_Memories_The_Xianzhou_Luofu, Calyx_Golden_Memories_Penacony, Calyx_Golden_Aether_Jarilo_VI, Calyx_Golden_Aether_The_Xianzhou_Luofu, Calyx_Golden_Aether_Penacony, Calyx_Golden_Treasures_Jarilo_VI, Calyx_Golden_Treasures_The_Xianzhou_Luofu, Calyx_Golden_Treasures_Penacony
DungeonDaily_CalyxCrimson = 'Calyx_Crimson_Destruction_Herta_StorageZone' # do_not_achieve, Calyx_Crimson_Destruction_Herta_StorageZone, Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape, Calyx_Crimson_Preservation_Herta_SupplyZone, Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains, Calyx_Crimson_Abundance_Jarilo_BackwaterPass, Calyx_Crimson_Erudition_Jarilo_RivetTown, Calyx_Crimson_Harmony_Jarilo_RobotSettlement, Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape, Calyx_Crimson_Nihility_Jarilo_GreatMine, Calyx_Crimson_Nihility_Luofu_AlchemyCommission
DungeonDaily_StagnantShadow = 'Stagnant_Shadow_Quanta' # do_not_achieve, Stagnant_Shadow_Spike, Stagnant_Shadow_Perdition, Stagnant_Shadow_Blaze, Stagnant_Shadow_Scorch, Stagnant_Shadow_Rime, Stagnant_Shadow_Icicle, Stagnant_Shadow_Nectar, Stagnant_Shadow_Fulmination, Stagnant_Shadow_Doom, Stagnant_Shadow_Gust, Stagnant_Shadow_Celestial, Stagnant_Shadow_Quanta, Stagnant_Shadow_Abomination, Stagnant_Shadow_Roast, Stagnant_Shadow_Mirage, Stagnant_Shadow_Puppetry
DungeonDaily_CalyxCrimson = 'Calyx_Crimson_Destruction_Herta_StorageZone' # do_not_achieve, Calyx_Crimson_Destruction_Herta_StorageZone, Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape, Calyx_Crimson_Preservation_Herta_SupplyZone, Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark, Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains, Calyx_Crimson_Abundance_Jarilo_BackwaterPass, Calyx_Crimson_Abundance_Luofu_FyxestrollGarden, Calyx_Crimson_Erudition_Jarilo_RivetTown, Calyx_Crimson_Harmony_Jarilo_RobotSettlement, Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape, Calyx_Crimson_Nihility_Jarilo_GreatMine, Calyx_Crimson_Nihility_Luofu_AlchemyCommission
DungeonDaily_StagnantShadow = 'Stagnant_Shadow_Quanta' # do_not_achieve, Stagnant_Shadow_Spike, Stagnant_Shadow_Perdition, Stagnant_Shadow_Blaze, Stagnant_Shadow_Scorch, Stagnant_Shadow_Ire, Stagnant_Shadow_Rime, Stagnant_Shadow_Icicle, Stagnant_Shadow_Nectar, Stagnant_Shadow_Fulmination, Stagnant_Shadow_Doom, Stagnant_Shadow_Gust, Stagnant_Shadow_Celestial, Stagnant_Shadow_Quanta, Stagnant_Shadow_Abomination, Stagnant_Shadow_Roast, Stagnant_Shadow_Mirage, Stagnant_Shadow_Puppetry
DungeonDaily_CavernOfCorrosion = 'Cavern_of_Corrosion_Path_of_Providence' # do_not_achieve, Cavern_of_Corrosion_Path_of_Gelid_Wind, Cavern_of_Corrosion_Path_of_Jabbing_Punch, Cavern_of_Corrosion_Path_of_Drifting, Cavern_of_Corrosion_Path_of_Providence, Cavern_of_Corrosion_Path_of_Holy_Hymn, Cavern_of_Corrosion_Path_of_Conflagration, Cavern_of_Corrosion_Path_of_Elixir_Seekers, Cavern_of_Corrosion_Path_of_Darkness, Cavern_of_Corrosion_Path_of_Dreamdive
# Group `DungeonSupport`
DungeonSupport_Use = 'when_daily' # always_use, when_daily, do_not_use
DungeonSupport_Character = 'FirstCharacter' # FirstCharacter, Argenti, Arlan, Asta, Bailu, BlackSwan, Blade, Bronya, Clara, DanHeng, DanHengImbibitorLunae, DrRatio, FuXuan, Gepard, Guinaifen, Hanya, Herta, Himeko, Hook, Huohuo, JingYuan, Jingliu, Kafka, Luka, Luocha, Lynx, March7th, Misha, Natasha, Pela, Qingque, RuanMei, Sampo, Seele, Serval, SilverWolf, Sparkle, Sushang, Tingyun, TopazNumby, TrailblazerDestruction, TrailblazerPreservation, Welt, Xueyi, Yanqing, Yukong
DungeonSupport_Character = 'FirstCharacter' # FirstCharacter, Acheron, Argenti, Arlan, Asta, Bailu, BlackSwan, Blade, Bronya, Clara, DanHeng, DanHengImbibitorLunae, DrRatio, FuXuan, Gallagher, Gepard, Guinaifen, Hanya, Herta, Himeko, Hook, Huohuo, JingYuan, Jingliu, Kafka, Luka, Luocha, Lynx, March7th, Misha, Natasha, Pela, Qingque, RuanMei, Sampo, Seele, Serval, SilverWolf, Sparkle, Sushang, Tingyun, TopazNumby, TrailblazerDestruction, TrailblazerPreservation, Welt, Xueyi, Yanqing, Yukong
# Group `DungeonStorage`
DungeonStorage_TrailblazePower = {}

View File

@ -100,7 +100,7 @@ class ConfigGenerator:
options=[dungeon.name for dungeon in DungeonList.instances.values() if dungeon.is_Echo_of_War])
# Insert characters
from tasks.character.keywords import CharacterList
unsupported_characters = []
unsupported_characters = ['Aventurine']
characters = [character.name for character in CharacterList.instances.values()
if character.name not in unsupported_characters]
option_add(keys='DungeonSupport.Character.option', options=characters)
@ -795,6 +795,9 @@ class ConfigUpdater:
# Store immersifier in dungeon task
if deep_get(data, keys='Rogue.RogueWorld.UseImmersifier') is True:
deep_set(data, keys='Dungeon.Scheduler.Enable', value=True)
# Cloud settings
if deep_get(data, keys='Alas.Emulator.GameClient') == 'cloud_android':
deep_set(data, keys='Alas.Emulator.PackageName', value='CN-Official')
return data
@ -842,6 +845,9 @@ class ConfigUpdater:
yield 'Rogue.RogueWorld.UseImmersifier', True
elif key == 'Rogue.RogueWorld.DoubleEvent' and value is True:
yield 'Rogue.RogueWorld.UseImmersifier', True
elif key == 'Alas.Emulator.GameClient' and value == 'cloud_android':
yield 'Alas.Emulator.PackageName', 'CN-Official'
yield 'Alas.Optimization.WhenTaskQueueEmpty', 'close_game'
def iter_hidden_args(self, data) -> t.Iterator[str]:
"""

View File

@ -96,6 +96,12 @@
"name": "Serial",
"help": "Common emulator Serial can be queried in the list below\nUse \"auto\" to auto-detect emulators, but if multiple emulators are running or use emulators that do not support auto-detect, \"auto\" cannot be used and serial must be filled in manually\nDefault serial for select emulators:\n- BlueStacks 127.0.0.1:5555\n- BlueStacks4 Hyper-V use \"bluestacks4-hyperv\", \"bluestacks4-hyperv-2\" for multi instance, and so on\n- BlueStacks5 Hyper-V use \"bluestacks5-hyperv\", \"bluestacks5-hyperv-1\" for multi instance, and so on\n- NoxPlayer 127.0.0.1:62001\n- NoxPlayer64bit 127.0.0.1:59865\n- MuMuPlayer/MuMuPlayer X 127.0.0.1:7555\n- MuMuPlayer12 127.0.0.1:16384\n- MemuPlayer 127.0.0.1:21503\n- LDPlayer emulator-5554 or 127.0.0.1:5555\n- WSA use \"wsa-0\" to make the game run in the background, which needs to be controlled or closed by third-party software\nIf there are multiple emulator instances running, the default is reserved for one of them and the others will use different serials to avoid conflicts\nOpen console.bat and run `adb devices` to find them or follow the emulator's official tutorial"
},
"GameClient": {
"name": "Game Client",
"help": "When using cloud, you will be automatically queued to log in. Cloud game is available in CN only",
"android": "Android client",
"cloud_android": "Cloud game android client"
},
"PackageName": {
"name": "Game Server",
"help": "Can't distinguish different regions of oversea servers, please select the server manually.",
@ -215,6 +221,24 @@
"close_game": "Close Game"
}
},
"CloudStorage": {
"_info": {
"name": "CloudStorage._info.name",
"help": "CloudStorage._info.help"
},
"CloudRemainSeasonPass": {
"name": "CloudStorage.CloudRemainSeasonPass.name",
"help": "CloudStorage.CloudRemainSeasonPass.help"
},
"CloudRemainPaid": {
"name": "CloudStorage.CloudRemainPaid.name",
"help": "CloudStorage.CloudRemainPaid.help"
},
"CloudRemainFree": {
"name": "CloudStorage.CloudRemainFree.name",
"help": "CloudStorage.CloudRemainFree.help"
}
},
"Dungeon": {
"_info": {
"name": "Dungeon Settings",
@ -235,8 +259,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "Trace: Destruction (Storage Zone)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "Trace: Destruction (Scalegorge Waterscape)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "Trace: Preservation (Supply Zone)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "Trace: Preservation (Clock Studios Theme Park)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "Trace: The Hunt (Outlying Snow Plains)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "Trace: Abundance (Backwater Pass)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "Trace: Abundance (Fyxestroll Garden)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "Trace: Erudition (Rivet Town)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "Trace: The Harmony (Robot Settlement)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "Trace: The Harmony (The Reverie (Dreamscape))",
@ -246,18 +272,19 @@
"Stagnant_Shadow_Perdition": "Ascension: Physical (Hanya / Argenti)",
"Stagnant_Shadow_Blaze": "Ascension: Fire (Himeko / Asta / Hook)",
"Stagnant_Shadow_Scorch": "Ascension: Fire (Guinaifen / Topaz & Numby)",
"Stagnant_Shadow_Ire": "Ascension: Fire (Gallagher)",
"Stagnant_Shadow_Rime": "Ascension: Ice (March 7th / Herta / Gepard / Pela)",
"Stagnant_Shadow_Icicle": "Ascension: Ice (Yanqing / Jingliu / Ruan Mei)",
"Stagnant_Shadow_Nectar": "Ascension: Ice (Misha)",
"Stagnant_Shadow_Fulmination": "Ascension: Lightning (Arlan / Serval / Tingyun / Bailu)",
"Stagnant_Shadow_Doom": "Ascension: Lightning (Kafka / Jing Yuan)",
"Stagnant_Shadow_Doom": "Ascension: Lightning (Kafka / Jing Yuan / Acheron)",
"Stagnant_Shadow_Gust": "Ascension: Wind (Dan Heng / Bronya / Sampo)",
"Stagnant_Shadow_Celestial": "Ascension: Wind (Blade / Huohuo / Black Swan)",
"Stagnant_Shadow_Quanta": "Ascension: Quantum (Silver Wolf / Seele / Qingque)",
"Stagnant_Shadow_Abomination": "Ascension: Quantum (Lynx / Fu Xuan / Xueyi)",
"Stagnant_Shadow_Roast": "Ascension: Quantum (Sparkle)",
"Stagnant_Shadow_Mirage": "Ascension: Imaginary (Welt / Luocha / Yukong)",
"Stagnant_Shadow_Puppetry": "Ascension: Imaginary (Dan Heng • Imbibitor Lunae / Dr. Ratio)",
"Stagnant_Shadow_Puppetry": "Ascension: Imaginary (Dan Heng • Imbibitor Lunae / Aventurine / Dr. Ratio)",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "Relics: Ice Set & Wind Set (Path of Gelid Wind)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "Relics: Physical Set & Break Effect Set (Path of Jabbing Punch)",
"Cavern_of_Corrosion_Path_of_Drifting": "Relics: Healing Set & Musketeer Set (Path of Drifting)",
@ -271,7 +298,6 @@
"NameAtDoubleCalyx": {
"name": "At Double Calyx Event, choose dungeon",
"help": "Return to the default dungeon settings after double times exhausted",
"do_not_participate": "Dont participate in event",
"Calyx_Golden_Memories_Jarilo_VI": "Material: Character EXP (Bud of Memories (Jarilo-Ⅵ))",
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "Material: Character EXP (Bud of Memories (The Xianzhou Luofu))",
"Calyx_Golden_Memories_Penacony": "Material: Character EXP (Bud of Memories (Penacony))",
@ -284,8 +310,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "Trace: Destruction (Storage Zone)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "Trace: Destruction (Scalegorge Waterscape)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "Trace: Preservation (Supply Zone)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "Trace: Preservation (Clock Studios Theme Park)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "Trace: The Hunt (Outlying Snow Plains)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "Trace: Abundance (Backwater Pass)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "Trace: Abundance (Fyxestroll Garden)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "Trace: Erudition (Rivet Town)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "Trace: The Harmony (Robot Settlement)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "Trace: The Harmony (The Reverie (Dreamscape))",
@ -295,7 +323,6 @@
"NameAtDoubleRelic": {
"name": "At Double Relic Event, choose dungeon",
"help": "Return to the default dungeon settings after double times exhausted",
"do_not_participate": "Dont participate in event",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "Relics: Ice Set & Wind Set (Path of Gelid Wind)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "Relics: Physical Set & Break Effect Set (Path of Jabbing Punch)",
"Cavern_of_Corrosion_Path_of_Drifting": "Relics: Healing Set & Musketeer Set (Path of Drifting)",
@ -346,8 +373,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "Trace: Destruction (Storage Zone)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "Trace: Destruction (Scalegorge Waterscape)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "Trace: Preservation (Supply Zone)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "Trace: Preservation (Clock Studios Theme Park)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "Trace: The Hunt (Outlying Snow Plains)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "Trace: Abundance (Backwater Pass)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "Trace: Abundance (Fyxestroll Garden)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "Trace: Erudition (Rivet Town)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "Trace: The Harmony (Robot Settlement)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "Trace: The Harmony (The Reverie (Dreamscape))",
@ -362,18 +391,19 @@
"Stagnant_Shadow_Perdition": "Ascension: Physical (Hanya / Argenti)",
"Stagnant_Shadow_Blaze": "Ascension: Fire (Himeko / Asta / Hook)",
"Stagnant_Shadow_Scorch": "Ascension: Fire (Guinaifen / Topaz & Numby)",
"Stagnant_Shadow_Ire": "Ascension: Fire (Gallagher)",
"Stagnant_Shadow_Rime": "Ascension: Ice (March 7th / Herta / Gepard / Pela)",
"Stagnant_Shadow_Icicle": "Ascension: Ice (Yanqing / Jingliu / Ruan Mei)",
"Stagnant_Shadow_Nectar": "Ascension: Ice (Misha)",
"Stagnant_Shadow_Fulmination": "Ascension: Lightning (Arlan / Serval / Tingyun / Bailu)",
"Stagnant_Shadow_Doom": "Ascension: Lightning (Kafka / Jing Yuan)",
"Stagnant_Shadow_Doom": "Ascension: Lightning (Kafka / Jing Yuan / Acheron)",
"Stagnant_Shadow_Gust": "Ascension: Wind (Dan Heng / Bronya / Sampo)",
"Stagnant_Shadow_Celestial": "Ascension: Wind (Blade / Huohuo / Black Swan)",
"Stagnant_Shadow_Quanta": "Ascension: Quantum (Silver Wolf / Seele / Qingque)",
"Stagnant_Shadow_Abomination": "Ascension: Quantum (Lynx / Fu Xuan / Xueyi)",
"Stagnant_Shadow_Roast": "Ascension: Quantum (Sparkle)",
"Stagnant_Shadow_Mirage": "Ascension: Imaginary (Welt / Luocha / Yukong)",
"Stagnant_Shadow_Puppetry": "Ascension: Imaginary (Dan Heng • Imbibitor Lunae / Dr. Ratio)"
"Stagnant_Shadow_Puppetry": "Ascension: Imaginary (Dan Heng • Imbibitor Lunae / Aventurine / Dr. Ratio)"
},
"CavernOfCorrosion": {
"name": "Clear Cavern of Corrosion 1 times",
@ -406,6 +436,7 @@
"name": "Support Character",
"help": "Select a friend support character, if not found, select the default (first) role\nSupport character should not be the same as the character in the team, recommended to prioritize friends.",
"FirstCharacter": "First Character",
"Acheron": "Acheron",
"Argenti": "Argenti",
"Arlan": "Arlan",
"Asta": "Asta",
@ -418,6 +449,7 @@
"DanHengImbibitorLunae": "Dan Heng • Imbibitor Lunae",
"DrRatio": "Dr. Ratio",
"FuXuan": "Fu Xuan",
"Gallagher": "Gallagher",
"Gepard": "Gepard",
"Guinaifen": "Guinaifen",
"Hanya": "Hanya",

View File

@ -96,6 +96,12 @@
"name": "Serial",
"help": "Los serial de emuladores comunes pueden ser consultados aquí:\nUsa \"auto\" para detectar automáticamente el emulador, pero si hay varios ejecutando a la vez o no se puede detectar de forma automática, \"auto\" no podrá ser usado y tendrás que ajustarlo manualmente.\nSerial comunes de algunos emuladores:\n- BlueStacks 127.0.0.1:5555\n- BlueStacks4 Hyper-V usa \"bluestacks4-hyperv\", \"bluestacks4-hyperv-2\" para multi-instancia, etc...\n- BlueStacks5 Hyper-V usa \"bluestacks5-hyperv\", \"bluestacks5-hyperv-1\" para multi-instancia, etc...\n- NoxPlayer 127.0.0.1:62001\n- NoxPlayer64bit 127.0.0.1:59865\n- MuMuPlayer/MuMuPlayer X 127.0.0.1:7555\n- MuMuPlayer12 127.0.0.1:16384\n- MemuPlayer 127.0.0.1:21503\n- LDPlayer emulator-5554 or 127.0.0.1:5555\n- WSA usa \"wsa-0\" para ejecutar el juego en segundo plano, que será cerrado/controlado por software externo.\nSi hay varias instancias ejecutándose a la vez, se usará la predeterminada para la primera y las demás se reajustarán.\nAbre console.bat y ejecuta `adb devices` para encontrarlas o usa la guía oficial del emulador."
},
"GameClient": {
"name": "Cliente del juego",
"help": "Al usar la nube, automáticamente se pondrá en cola para iniciar sesión. El juego en la nube está disponible solo en CN",
"android": "Cliente Android",
"cloud_android": "Cliente de juego en la nube para Android"
},
"PackageName": {
"name": "Región del juego",
"help": "No es posible detectar regiones que no sean de China, por tanto, ajústalo manualmente si se da la situación.",
@ -215,6 +221,24 @@
"close_game": "Cerrar el juego"
}
},
"CloudStorage": {
"_info": {
"name": "CloudStorage._info.name",
"help": "CloudStorage._info.help"
},
"CloudRemainSeasonPass": {
"name": "CloudStorage.CloudRemainSeasonPass.name",
"help": "CloudStorage.CloudRemainSeasonPass.help"
},
"CloudRemainPaid": {
"name": "CloudStorage.CloudRemainPaid.name",
"help": "CloudStorage.CloudRemainPaid.help"
},
"CloudRemainFree": {
"name": "CloudStorage.CloudRemainFree.name",
"help": "CloudStorage.CloudRemainFree.help"
}
},
"Dungeon": {
"_info": {
"name": "Ajustes de Mazmorra",
@ -235,8 +259,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "Rastros: Destrucción (Zona de almacenamiento)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "Rastros: Destrucción (Desfiladero de Escamas)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "Rastros: Conservación (Zona de suministros)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "Rastros: Conservación (Parque temático de los Estudios Reloj)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "Rastros: Cacería (Llanuras nevadas de las afueras)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "Rastros: Abundancia (Paso del Remanso)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "Rastros: Abundancia (Jardín del Sosiego)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "Rastros: Erudición (Villarremache)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "Rastros: Armonía (Asentamiento robot)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "Rastros: Armonía (Hotel Fantasía (paisaje onírico))",
@ -246,18 +272,19 @@
"Stagnant_Shadow_Perdition": "Ascension: Físico (Hanya / Argenti)",
"Stagnant_Shadow_Blaze": "Ascension: Fuego (Himeko / Asta / Hook)",
"Stagnant_Shadow_Scorch": "Ascension: Fuego (Guinaifen / Topaz y Conti)",
"Stagnant_Shadow_Ire": "Ascension: Fuego (Gallagher)",
"Stagnant_Shadow_Rime": "Ascension: Hielo (Siete de Marzo / Herta / Gepard / Pela)",
"Stagnant_Shadow_Icicle": "Ascension: Hielo (Yanqing / Jingliu / Ruan Mei)",
"Stagnant_Shadow_Nectar": "Ascension: Hielo (Misha)",
"Stagnant_Shadow_Fulmination": "Ascension: Rayo (Arlan / Serval / Tingyun / Bailu)",
"Stagnant_Shadow_Doom": "Ascension: Rayo (Kafka / Jing Yuan)",
"Stagnant_Shadow_Doom": "Ascension: Rayo (Kafka / Jing Yuan / Acheron)",
"Stagnant_Shadow_Gust": "Ascension: Viento (Dan Heng / Bronya / Sampo)",
"Stagnant_Shadow_Celestial": "Ascension: Viento (Blade / Huohuo / Cisne Negro)",
"Stagnant_Shadow_Quanta": "Ascension: Cuántico (Silver Wolf / Seele / Qingque)",
"Stagnant_Shadow_Abomination": "Ascension: Cuántico (Lynx / Fu Xuan / Xueyi)",
"Stagnant_Shadow_Roast": "Ascension: Cuántico (Sparkle)",
"Stagnant_Shadow_Mirage": "Ascension: Imaginario (Welt / Luocha / Yukong)",
"Stagnant_Shadow_Puppetry": "Ascension: Imaginario (Dan Heng - Imbibitor Lunae / Dr. Ratio)",
"Stagnant_Shadow_Puppetry": "Ascension: Imaginario (Dan Heng - Imbibitor Lunae / Aventurino / Dr. Ratio)",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "Artefactos: Hielo y Viento (Senda del viento gélido)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "Artefactos: Físico y Efecto de Ruptura (Senda de los puños rápidos)",
"Cavern_of_Corrosion_Path_of_Drifting": "Artefactos: Curación y Pistolera de la espiga silvestre (Senda de la deriva)",
@ -271,7 +298,6 @@
"NameAtDoubleCalyx": {
"name": "En los eventos de x2 de Cáliz",
"help": "Se volverán a los ajustes predeterminados una vez se acaben los intentos del evento",
"do_not_participate": "No participar en el evento",
"Calyx_Golden_Memories_Jarilo_VI": "Material: EXP de personaje (Flor de los recuerdos (Jarilo-Ⅵ))",
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "Material: EXP de personaje (Flor de los recuerdos (El Luofu de Xianzhou))",
"Calyx_Golden_Memories_Penacony": "Material: EXP de personaje (Flor de los recuerdos (Colonipenal))",
@ -284,8 +310,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "Rastros: Destrucción (Zona de almacenamiento)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "Rastros: Destrucción (Desfiladero de Escamas)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "Rastros: Conservación (Zona de suministros)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "Rastros: Conservación (Parque temático de los Estudios Reloj)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "Rastros: Cacería (Llanuras nevadas de las afueras)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "Rastros: Abundancia (Paso del Remanso)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "Rastros: Abundancia (Jardín del Sosiego)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "Rastros: Erudición (Villarremache)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "Rastros: Armonía (Asentamiento robot)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "Rastros: Armonía (Hotel Fantasía (paisaje onírico))",
@ -295,7 +323,6 @@
"NameAtDoubleRelic": {
"name": "En los eventos de x2 de Caverna de la corrosión",
"help": "Se volverán a los ajustes predeterminados una vez se acaben los intentos del evento",
"do_not_participate": "No participar en el evento",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "Artefactos: Hielo y Viento (Senda del viento gélido)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "Artefactos: Físico y Efecto de Ruptura (Senda de los puños rápidos)",
"Cavern_of_Corrosion_Path_of_Drifting": "Artefactos: Curación y Pistolera de la espiga silvestre (Senda de la deriva)",
@ -346,8 +373,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "Rastros: Destrucción (Zona de almacenamiento)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "Rastros: Destrucción (Desfiladero de Escamas)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "Rastros: Conservación (Zona de suministros)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "Rastros: Conservación (Parque temático de los Estudios Reloj)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "Rastros: Cacería (Llanuras nevadas de las afueras)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "Rastros: Abundancia (Paso del Remanso)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "Rastros: Abundancia (Jardín del Sosiego)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "Rastros: Erudición (Villarremache)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "Rastros: Armonía (Asentamiento robot)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "Rastros: Armonía (Hotel Fantasía (paisaje onírico))",
@ -362,18 +391,19 @@
"Stagnant_Shadow_Perdition": "Ascension: Físico (Hanya / Argenti)",
"Stagnant_Shadow_Blaze": "Ascension: Fuego (Himeko / Asta / Hook)",
"Stagnant_Shadow_Scorch": "Ascension: Fuego (Guinaifen / Topaz y Conti)",
"Stagnant_Shadow_Ire": "Ascension: Fuego (Gallagher)",
"Stagnant_Shadow_Rime": "Ascension: Hielo (Siete de Marzo / Herta / Gepard / Pela)",
"Stagnant_Shadow_Icicle": "Ascension: Hielo (Yanqing / Jingliu / Ruan Mei)",
"Stagnant_Shadow_Nectar": "Ascension: Hielo (Misha)",
"Stagnant_Shadow_Fulmination": "Ascension: Rayo (Arlan / Serval / Tingyun / Bailu)",
"Stagnant_Shadow_Doom": "Ascension: Rayo (Kafka / Jing Yuan)",
"Stagnant_Shadow_Doom": "Ascension: Rayo (Kafka / Jing Yuan / Acheron)",
"Stagnant_Shadow_Gust": "Ascension: Viento (Dan Heng / Bronya / Sampo)",
"Stagnant_Shadow_Celestial": "Ascension: Viento (Blade / Huohuo / Cisne Negro)",
"Stagnant_Shadow_Quanta": "Ascension: Cuántico (Silver Wolf / Seele / Qingque)",
"Stagnant_Shadow_Abomination": "Ascension: Cuántico (Lynx / Fu Xuan / Xueyi)",
"Stagnant_Shadow_Roast": "Ascension: Cuántico (Sparkle)",
"Stagnant_Shadow_Mirage": "Ascension: Imaginario (Welt / Luocha / Yukong)",
"Stagnant_Shadow_Puppetry": "Ascension: Imaginario (Dan Heng - Imbibitor Lunae / Dr. Ratio)"
"Stagnant_Shadow_Puppetry": "Ascension: Imaginario (Dan Heng - Imbibitor Lunae / Aventurino / Dr. Ratio)"
},
"CavernOfCorrosion": {
"name": "Completar Caverna de la corrosión 1 vez",
@ -406,6 +436,7 @@
"name": "Personaje de apoyo",
"help": "Selecciona qué personaje de apoyo de un amigo se usará. Si no se encuentra, se seleccionará al predeterminado.\nEl personaje de apoyo no debe ser el mismo que el personaje del equipo, se recomienda priorizar a los amigos.",
"FirstCharacter": "Primer personaje",
"Acheron": "Acheron",
"Argenti": "Argenti",
"Arlan": "Arlan",
"Asta": "Asta",
@ -418,6 +449,7 @@
"DanHengImbibitorLunae": "Dan Heng - Imbibitor Lunae",
"DrRatio": "Dr. Ratio",
"FuXuan": "Fu Xuan",
"Gallagher": "Gallagher",
"Gepard": "Gepard",
"Guinaifen": "Guinaifen",
"Hanya": "Hanya",

View File

@ -96,6 +96,12 @@
"name": "Emulator.Serial.name",
"help": "Emulator.Serial.help"
},
"GameClient": {
"name": "Emulator.GameClient.name",
"help": "Emulator.GameClient.help",
"android": "android",
"cloud_android": "cloud_android"
},
"PackageName": {
"name": "Emulator.PackageName.name",
"help": "Emulator.PackageName.help",
@ -215,6 +221,24 @@
"close_game": "close_game"
}
},
"CloudStorage": {
"_info": {
"name": "CloudStorage._info.name",
"help": "CloudStorage._info.help"
},
"CloudRemainSeasonPass": {
"name": "CloudStorage.CloudRemainSeasonPass.name",
"help": "CloudStorage.CloudRemainSeasonPass.help"
},
"CloudRemainPaid": {
"name": "CloudStorage.CloudRemainPaid.name",
"help": "CloudStorage.CloudRemainPaid.help"
},
"CloudRemainFree": {
"name": "CloudStorage.CloudRemainFree.name",
"help": "CloudStorage.CloudRemainFree.help"
}
},
"Dungeon": {
"_info": {
"name": "Dungeon._info.name",
@ -235,8 +259,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "軌跡素材:壊滅(収容部分)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "軌跡素材:壊滅(鱗淵境)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "軌跡素材:存護(サポート部分)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "軌跡素材:存護(クラークフィルムランド)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "軌跡素材:巡狩(郊外雪原)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "軌跡素材:豊穣(外縁通路)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "軌跡素材:豊穣(綏園)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "軌跡素材:知恵(リベットタウン)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "軌跡素材:調和(機械集落)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "軌跡素材:調和(ホテル・レバリー-夢境)",
@ -246,18 +272,19 @@
"Stagnant_Shadow_Perdition": "キャラクター昇格素材:物理(寒鴉 / アルジェンティ)",
"Stagnant_Shadow_Blaze": "キャラクター昇格素材:炎(姫子 / アスター / フック)",
"Stagnant_Shadow_Scorch": "キャラクター昇格素材:炎(桂乃芬 / トパーズ&カブ)",
"Stagnant_Shadow_Ire": "キャラクター昇格素材:炎(ギャラガー)",
"Stagnant_Shadow_Rime": "キャラクター昇格素材:氷(三月なのか / ヘルタ / ジェパード / ペラ)",
"Stagnant_Shadow_Icicle": "キャラクター昇格素材:氷(彦卿 / 鏡流 / ルアン・メェイ)",
"Stagnant_Shadow_Nectar": "キャラクター昇格素材:氷(ミーシャ)",
"Stagnant_Shadow_Fulmination": "キャラクター昇格素材:雷(アーラン / セーバル / 停雲 / 白露)",
"Stagnant_Shadow_Doom": "キャラクター昇格素材:雷(カフカ / 景元",
"Stagnant_Shadow_Doom": "キャラクター昇格素材:雷(カフカ / 景元 / 黄泉",
"Stagnant_Shadow_Gust": "キャラクター昇格素材:風(丹恒 / ブローニャ / サンポ)",
"Stagnant_Shadow_Celestial": "キャラクター昇格素材:風(刃 / フォフォ / ブラックスワン)",
"Stagnant_Shadow_Quanta": "キャラクター昇格素材:量子(銀狼 / ゼーレ / 青雀)",
"Stagnant_Shadow_Abomination": "キャラクター昇格素材:量子(リンクス / 符玄 / 雪衣)",
"Stagnant_Shadow_Roast": "キャラクター昇格素材:量子(花火)",
"Stagnant_Shadow_Mirage": "キャラクター昇格素材:虚数(ヴェルト / 羅刹 / 御空)",
"Stagnant_Shadow_Puppetry": "キャラクター昇格素材:虚数(丹恒・飲月 / Dr.レイシオ)",
"Stagnant_Shadow_Puppetry": "キャラクター昇格素材:虚数(丹恒・飲月 / アベンチュリン / Dr.レイシオ)",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "侵蝕トンネル・霜風の路(侵蝕トンネル・霜風の路)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "侵蝕トンネル・迅拳の路(侵蝕トンネル・迅拳の路)",
"Cavern_of_Corrosion_Path_of_Drifting": "侵蝕トンネル・漂泊の路(侵蝕トンネル・漂泊の路)",
@ -271,7 +298,6 @@
"NameAtDoubleCalyx": {
"name": "Dungeon.NameAtDoubleCalyx.name",
"help": "Dungeon.NameAtDoubleCalyx.help",
"do_not_participate": "do_not_participate",
"Calyx_Golden_Memories_Jarilo_VI": "素材:役割経験(回憶の蕾・ヤリーロ-Ⅵ):",
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "素材:役割経験(回憶の蕾・仙舟羅浮):",
"Calyx_Golden_Memories_Penacony": "素材:役割経験(回憶の蕾・ピノコニー):",
@ -284,8 +310,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "軌跡素材:壊滅(収容部分)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "軌跡素材:壊滅(鱗淵境)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "軌跡素材:存護(サポート部分)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "軌跡素材:存護(クラークフィルムランド)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "軌跡素材:巡狩(郊外雪原)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "軌跡素材:豊穣(外縁通路)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "軌跡素材:豊穣(綏園)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "軌跡素材:知恵(リベットタウン)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "軌跡素材:調和(機械集落)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "軌跡素材:調和(ホテル・レバリー-夢境)",
@ -295,7 +323,6 @@
"NameAtDoubleRelic": {
"name": "Dungeon.NameAtDoubleRelic.name",
"help": "Dungeon.NameAtDoubleRelic.help",
"do_not_participate": "do_not_participate",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "侵蝕トンネル・霜風の路(侵蝕トンネル・霜風の路)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "侵蝕トンネル・迅拳の路(侵蝕トンネル・迅拳の路)",
"Cavern_of_Corrosion_Path_of_Drifting": "侵蝕トンネル・漂泊の路(侵蝕トンネル・漂泊の路)",
@ -346,8 +373,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "軌跡素材:壊滅(収容部分)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "軌跡素材:壊滅(鱗淵境)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "軌跡素材:存護(サポート部分)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "軌跡素材:存護(クラークフィルムランド)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "軌跡素材:巡狩(郊外雪原)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "軌跡素材:豊穣(外縁通路)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "軌跡素材:豊穣(綏園)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "軌跡素材:知恵(リベットタウン)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "軌跡素材:調和(機械集落)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "軌跡素材:調和(ホテル・レバリー-夢境)",
@ -362,18 +391,19 @@
"Stagnant_Shadow_Perdition": "キャラクター昇格素材:物理(寒鴉 / アルジェンティ)",
"Stagnant_Shadow_Blaze": "キャラクター昇格素材:炎(姫子 / アスター / フック)",
"Stagnant_Shadow_Scorch": "キャラクター昇格素材:炎(桂乃芬 / トパーズ&カブ)",
"Stagnant_Shadow_Ire": "キャラクター昇格素材:炎(ギャラガー)",
"Stagnant_Shadow_Rime": "キャラクター昇格素材:氷(三月なのか / ヘルタ / ジェパード / ペラ)",
"Stagnant_Shadow_Icicle": "キャラクター昇格素材:氷(彦卿 / 鏡流 / ルアン・メェイ)",
"Stagnant_Shadow_Nectar": "キャラクター昇格素材:氷(ミーシャ)",
"Stagnant_Shadow_Fulmination": "キャラクター昇格素材:雷(アーラン / セーバル / 停雲 / 白露)",
"Stagnant_Shadow_Doom": "キャラクター昇格素材:雷(カフカ / 景元",
"Stagnant_Shadow_Doom": "キャラクター昇格素材:雷(カフカ / 景元 / 黄泉",
"Stagnant_Shadow_Gust": "キャラクター昇格素材:風(丹恒 / ブローニャ / サンポ)",
"Stagnant_Shadow_Celestial": "キャラクター昇格素材:風(刃 / フォフォ / ブラックスワン)",
"Stagnant_Shadow_Quanta": "キャラクター昇格素材:量子(銀狼 / ゼーレ / 青雀)",
"Stagnant_Shadow_Abomination": "キャラクター昇格素材:量子(リンクス / 符玄 / 雪衣)",
"Stagnant_Shadow_Roast": "キャラクター昇格素材:量子(花火)",
"Stagnant_Shadow_Mirage": "キャラクター昇格素材:虚数(ヴェルト / 羅刹 / 御空)",
"Stagnant_Shadow_Puppetry": "キャラクター昇格素材:虚数(丹恒・飲月 / Dr.レイシオ)"
"Stagnant_Shadow_Puppetry": "キャラクター昇格素材:虚数(丹恒・飲月 / アベンチュリン / Dr.レイシオ)"
},
"CavernOfCorrosion": {
"name": "DungeonDaily.CavernOfCorrosion.name",
@ -406,6 +436,7 @@
"name": "DungeonSupport.Character.name",
"help": "DungeonSupport.Character.help",
"FirstCharacter": "FirstCharacter",
"Acheron": "黄泉",
"Argenti": "アルジェンティ",
"Arlan": "アーラン",
"Asta": "アスター",
@ -418,6 +449,7 @@
"DanHengImbibitorLunae": "丹恒・飲月",
"DrRatio": "Dr.レイシオ",
"FuXuan": "符玄",
"Gallagher": "ギャラガー",
"Gepard": "ジェパード",
"Guinaifen": "桂乃芬",
"Hanya": "寒鴉",

View File

@ -96,6 +96,12 @@
"name": "模拟器 Serial",
"help": "常见的模拟器 Serial 可以查询下方列表\n填 \"auto\" 自动检测模拟器,多个模拟器正在运行或使用不支持自动检测的模拟器时无法使用 \"auto\",必须手动填写\n\n模拟器默认 Serial\n- 蓝叠模拟器 127.0.0.1:5555\n- 蓝叠模拟器4 Hyper-v版填\"bluestacks4-hyperv\"自动连接,多开填\"bluestacks4-hyperv-2\"以此类推\n- 蓝叠模拟器5 Hyper-v版填\"bluestacks5-hyperv\"自动连接,多开填\"bluestacks5-hyperv-1\"以此类推\n- 夜神模拟器 127.0.0.1:62001\n- 夜神模拟器64位 127.0.0.1:59865\n- MuMu模拟器/MuMu模拟器X 127.0.0.1:7555\n- MuMu模拟器12 127.0.0.1:16384\n- 逍遥模拟器 127.0.0.1:21503\n- 雷电模拟器 emulator-5554 或 127.0.0.1:5555\n- WSA填\"wsa-0\"使游戏在后台运行需要使用第三方软件操控或关闭建议使用scrcpy操控\n如果你使用了模拟器的多开功能它们的 Serial 将不是默认的,可以在 console.bat 中执行 `adb devices` 查询,或根据模拟器官方的教程填写"
},
"GameClient": {
"name": "游戏客户端",
"help": "选择云游戏时,将自动排队登录,云游戏目前仅有国服",
"android": "安卓端",
"cloud_android": "云游戏安卓端"
},
"PackageName": {
"name": "游戏服务器",
"help": "无法区分国际服的不同地区,请手动选择服务器",
@ -215,6 +221,24 @@
"close_game": "关闭游戏"
}
},
"CloudStorage": {
"_info": {
"name": "",
"help": ""
},
"CloudRemainSeasonPass": {
"name": "畅玩卡剩余 X 天",
"help": ""
},
"CloudRemainPaid": {
"name": "星云币剩余 X 分钟",
"help": ""
},
"CloudRemainFree": {
"name": "免费时长剩余 X 分钟",
"help": ""
}
},
"Dungeon": {
"_info": {
"name": "每日副本设置",
@ -235,8 +259,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "行迹材料:毁灭(收容舱段)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "行迹材料:毁灭(鳞渊境)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "行迹材料:存护(支援舱段)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "行迹材料:存护(克劳克影视乐园)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "行迹材料:巡猎(城郊雪原)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "行迹材料:丰饶(边缘通路)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "行迹材料:丰饶(绥园)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "行迹材料:智识(铆钉镇)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "行迹材料:同谐(机械聚落)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "行迹材料:同谐(白日梦酒店-梦境)",
@ -246,18 +272,19 @@
"Stagnant_Shadow_Perdition": "角色晋阶材料:物理(寒鸦 / 银枝)",
"Stagnant_Shadow_Blaze": "角色晋阶材料:火(姬子 / 艾丝妲 / 虎克)",
"Stagnant_Shadow_Scorch": "角色晋阶材料:火(桂乃芬 / 托帕&账账)",
"Stagnant_Shadow_Ire": "角色晋阶材料:火(加拉赫)",
"Stagnant_Shadow_Rime": "角色晋阶材料:冰(三月七 / 黑塔 / 杰帕德 / 佩拉)",
"Stagnant_Shadow_Icicle": "角色晋阶材料:冰(彦卿 / 镜流 / 阮•梅)",
"Stagnant_Shadow_Nectar": "角色晋阶材料:冰(米沙)",
"Stagnant_Shadow_Fulmination": "角色晋阶材料:雷(阿兰 / 希露瓦 / 停云 / 白露)",
"Stagnant_Shadow_Doom": "角色晋阶材料:雷(卡芙卡 / 景元",
"Stagnant_Shadow_Doom": "角色晋阶材料:雷(卡芙卡 / 景元 / 黄泉",
"Stagnant_Shadow_Gust": "角色晋阶材料:风(丹恒 / 布洛妮娅 / 桑博)",
"Stagnant_Shadow_Celestial": "角色晋阶材料:风(刃 / 藿藿 / 黑天鹅)",
"Stagnant_Shadow_Quanta": "角色晋阶材料:量子(银狼 / 希儿 / 青雀)",
"Stagnant_Shadow_Abomination": "角色晋阶材料:量子(玲可 / 符玄 / 雪衣)",
"Stagnant_Shadow_Roast": "角色晋阶材料:量子(花火)",
"Stagnant_Shadow_Mirage": "角色晋阶材料:虚数(瓦尔特 / 罗刹 / 驭空)",
"Stagnant_Shadow_Puppetry": "角色晋阶材料:虚数(丹恒•饮月 / 真理医生)",
"Stagnant_Shadow_Puppetry": "角色晋阶材料:虚数(丹恒•饮月 / 砂金 / 真理医生)",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "遗器:冰套+风套(霜风之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "遗器:物理套+击破套(迅拳之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Drifting": "遗器:治疗套+快枪手(漂泊之径•侵蚀隧洞)",
@ -271,7 +298,6 @@
"NameAtDoubleCalyx": {
"name": "有双倍花活动时,选择副本",
"help": "次数耗尽后回退到默认打本设置",
"do_not_participate": "不参与活动",
"Calyx_Golden_Memories_Jarilo_VI": "材料:角色经验(回忆之蕾•雅利洛-Ⅵ)",
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "材料:角色经验(回忆之蕾•仙舟罗浮)",
"Calyx_Golden_Memories_Penacony": "材料:角色经验(回忆之蕾•匹诺康尼)",
@ -284,8 +310,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "行迹材料:毁灭(收容舱段)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "行迹材料:毁灭(鳞渊境)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "行迹材料:存护(支援舱段)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "行迹材料:存护(克劳克影视乐园)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "行迹材料:巡猎(城郊雪原)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "行迹材料:丰饶(边缘通路)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "行迹材料:丰饶(绥园)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "行迹材料:智识(铆钉镇)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "行迹材料:同谐(机械聚落)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "行迹材料:同谐(白日梦酒店-梦境)",
@ -295,7 +323,6 @@
"NameAtDoubleRelic": {
"name": "有遗器活动时,选择副本",
"help": "次数耗尽后回退到默认打本设置",
"do_not_participate": "不参与活动",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "遗器:冰套+风套(霜风之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "遗器:物理套+击破套(迅拳之径•侵蚀隧洞)",
"Cavern_of_Corrosion_Path_of_Drifting": "遗器:治疗套+快枪手(漂泊之径•侵蚀隧洞)",
@ -346,8 +373,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "行迹材料:毁灭(收容舱段)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "行迹材料:毁灭(鳞渊境)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "行迹材料:存护(支援舱段)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "行迹材料:存护(克劳克影视乐园)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "行迹材料:巡猎(城郊雪原)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "行迹材料:丰饶(边缘通路)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "行迹材料:丰饶(绥园)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "行迹材料:智识(铆钉镇)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "行迹材料:同谐(机械聚落)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "行迹材料:同谐(白日梦酒店-梦境)",
@ -362,18 +391,19 @@
"Stagnant_Shadow_Perdition": "角色晋阶材料:物理(寒鸦 / 银枝)",
"Stagnant_Shadow_Blaze": "角色晋阶材料:火(姬子 / 艾丝妲 / 虎克)",
"Stagnant_Shadow_Scorch": "角色晋阶材料:火(桂乃芬 / 托帕&账账)",
"Stagnant_Shadow_Ire": "角色晋阶材料:火(加拉赫)",
"Stagnant_Shadow_Rime": "角色晋阶材料:冰(三月七 / 黑塔 / 杰帕德 / 佩拉)",
"Stagnant_Shadow_Icicle": "角色晋阶材料:冰(彦卿 / 镜流 / 阮•梅)",
"Stagnant_Shadow_Nectar": "角色晋阶材料:冰(米沙)",
"Stagnant_Shadow_Fulmination": "角色晋阶材料:雷(阿兰 / 希露瓦 / 停云 / 白露)",
"Stagnant_Shadow_Doom": "角色晋阶材料:雷(卡芙卡 / 景元",
"Stagnant_Shadow_Doom": "角色晋阶材料:雷(卡芙卡 / 景元 / 黄泉",
"Stagnant_Shadow_Gust": "角色晋阶材料:风(丹恒 / 布洛妮娅 / 桑博)",
"Stagnant_Shadow_Celestial": "角色晋阶材料:风(刃 / 藿藿 / 黑天鹅)",
"Stagnant_Shadow_Quanta": "角色晋阶材料:量子(银狼 / 希儿 / 青雀)",
"Stagnant_Shadow_Abomination": "角色晋阶材料:量子(玲可 / 符玄 / 雪衣)",
"Stagnant_Shadow_Roast": "角色晋阶材料:量子(花火)",
"Stagnant_Shadow_Mirage": "角色晋阶材料:虚数(瓦尔特 / 罗刹 / 驭空)",
"Stagnant_Shadow_Puppetry": "角色晋阶材料:虚数(丹恒•饮月 / 真理医生)"
"Stagnant_Shadow_Puppetry": "角色晋阶材料:虚数(丹恒•饮月 / 砂金 / 真理医生)"
},
"CavernOfCorrosion": {
"name": "完成1次侵蚀隧洞",
@ -406,6 +436,7 @@
"name": "好友支援角色",
"help": "选择好友支援角色,未找到则选择默认(第一个)角色\n支援角色不要与队伍中的角色重复建议置顶好友角色",
"FirstCharacter": "支援列表第一个角色",
"Acheron": "黄泉",
"Argenti": "银枝",
"Arlan": "阿兰",
"Asta": "艾丝妲",
@ -418,6 +449,7 @@
"DanHengImbibitorLunae": "丹恒•饮月",
"DrRatio": "真理医生",
"FuXuan": "符玄",
"Gallagher": "加拉赫",
"Gepard": "杰帕德",
"Guinaifen": "桂乃芬",
"Hanya": "寒鸦",

View File

@ -96,6 +96,12 @@
"name": "模擬器 Serial",
"help": "常見的模擬器 Serial 可以查詢下方列表\n填 \"auto\" 自動檢測模擬器,多個模擬器正在運行或使用不支援自動檢測的模擬器時無法使用 \"auto\",必須手動填寫\n模擬器預設 Serial\n- 藍疊模擬器 127.0.0.1:5555\n- 藍疊模擬器4 Hyper-v版填\"bluestacks4-hyperv\"自動連接,多開填\"bluestacks4-hyperv-2\"以此類推\n- 藍疊模擬器5 Hyper-v版填\"bluestacks5-hyperv\"自動連接,多開填\"bluestacks5-hyperv-1\"以此類推\n- 夜神模擬器 127.0.0.1:62001\n- 夜神模擬器64位元 127.0.0.1:59865\n- MuMu模擬器/MuMu模擬器X 127.0.0.1:7555\n- MuMu模擬器12 127.0.0.1:16384\n- 逍遙模擬器 127.0.0.1:21503\n- 雷電模擬器 emulator-5554 或 127.0.0.1:5555\n- WSA填\"wsa-0\"使遊戲在後臺運行,需要使用第三方軟件操控或關閉\n如果你使用了模擬器的多開功能他們的 Serial 將不是預設的,可以在 console.bat 中執行 `adb devices` 查詢,或根據模擬器官方的教程填寫"
},
"GameClient": {
"name": "遊戲客戶端",
"help": "選擇雲端遊戲時,將自動排隊登入,雲端遊戲目前僅有國服",
"android": "安卓端",
"cloud_android": "雲端遊戲安卓端"
},
"PackageName": {
"name": "遊戲伺服器",
"help": "無法區分國際服的不同地區,請手動選擇伺服器",
@ -215,6 +221,24 @@
"close_game": "關閉遊戲"
}
},
"CloudStorage": {
"_info": {
"name": "CloudStorage._info.name",
"help": "CloudStorage._info.help"
},
"CloudRemainSeasonPass": {
"name": "CloudStorage.CloudRemainSeasonPass.name",
"help": "CloudStorage.CloudRemainSeasonPass.help"
},
"CloudRemainPaid": {
"name": "CloudStorage.CloudRemainPaid.name",
"help": "CloudStorage.CloudRemainPaid.help"
},
"CloudRemainFree": {
"name": "CloudStorage.CloudRemainFree.name",
"help": "CloudStorage.CloudRemainFree.help"
}
},
"Dungeon": {
"_info": {
"name": "每日副本設定",
@ -235,8 +259,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "行跡材料:毀滅(收容艙段)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "行跡材料:毀滅(鱗淵境)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "行跡材料:存護(支援艙段)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "行跡材料:存護(克勞克影視樂園)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "行跡材料:巡獵(城郊雪原)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "行跡材料:豐饒(邊緣通道)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "行跡材料:豐饒(綏園)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "行跡材料:智識(鉚釘鎮)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "行跡材料:同諧(機械聚落)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "行跡材料:同諧(白日夢飯店-夢境)",
@ -246,18 +272,19 @@
"Stagnant_Shadow_Perdition": "角色晉階材料:物理(寒鴉 / 銀枝)",
"Stagnant_Shadow_Blaze": "角色晉階材料:火(姬子 / 艾絲妲 / 虎克)",
"Stagnant_Shadow_Scorch": "角色晉階材料:火(桂乃芬 / 托帕&帳帳)",
"Stagnant_Shadow_Ire": "角色晉階材料:火(加拉赫)",
"Stagnant_Shadow_Rime": "角色晉階材料:冰(三月七 / 黑塔 / 傑帕德 / 佩拉)",
"Stagnant_Shadow_Icicle": "角色晉階材料:冰(彥卿 / 鏡流 / 阮•梅)",
"Stagnant_Shadow_Nectar": "角色晉階材料:冰(米沙)",
"Stagnant_Shadow_Fulmination": "角色晉階材料:雷(阿蘭 / 希露瓦 / 停雲 / 白露)",
"Stagnant_Shadow_Doom": "角色晉階材料:雷(卡芙卡 / 景元",
"Stagnant_Shadow_Doom": "角色晉階材料:雷(卡芙卡 / 景元 / 黃泉",
"Stagnant_Shadow_Gust": "角色晉階材料:風(丹恆 / 布洛妮婭 / 桑博)",
"Stagnant_Shadow_Celestial": "角色晉階材料:風(刃 / 藿藿 / 黑天鵝)",
"Stagnant_Shadow_Quanta": "角色晉階材料:量子(銀狼 / 希兒 / 青雀)",
"Stagnant_Shadow_Abomination": "角色晉階材料:量子(玲可 / 符玄 / 雪衣)",
"Stagnant_Shadow_Roast": "角色晉階材料:量子(花火)",
"Stagnant_Shadow_Mirage": "角色晉階材料:虛數(瓦爾特 / 羅剎 / 馭空)",
"Stagnant_Shadow_Puppetry": "角色晉階材料:虛數(丹恆•飲月 / 真理醫生)",
"Stagnant_Shadow_Puppetry": "角色晉階材料:虛數(丹恆•飲月 / 砂金 / 真理醫生)",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "遺器:冰套+風套(霜風之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "遺器:物理套+擊破套(迅拳之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Drifting": "遺器:治療套+快槍手(漂泊之徑•侵蝕隧洞)",
@ -271,7 +298,6 @@
"NameAtDoubleCalyx": {
"name": "有雙倍花活動時,選擇副本",
"help": "次數耗儘後回退到默認打本設定",
"do_not_participate": "不參與活動",
"Calyx_Golden_Memories_Jarilo_VI": "材料:角色經驗(回憶之蕾•雅利洛-Ⅵ)",
"Calyx_Golden_Memories_The_Xianzhou_Luofu": "材料:角色經驗(回憶之蕾•仙舟羅浮)",
"Calyx_Golden_Memories_Penacony": "材料:角色經驗(回憶之蕾•匹諾康尼)",
@ -284,8 +310,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "行跡材料:毀滅(收容艙段)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "行跡材料:毀滅(鱗淵境)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "行跡材料:存護(支援艙段)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "行跡材料:存護(克勞克影視樂園)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "行跡材料:巡獵(城郊雪原)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "行跡材料:豐饒(邊緣通道)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "行跡材料:豐饒(綏園)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "行跡材料:智識(鉚釘鎮)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "行跡材料:同諧(機械聚落)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "行跡材料:同諧(白日夢飯店-夢境)",
@ -295,7 +323,6 @@
"NameAtDoubleRelic": {
"name": "有遺器活動時,選擇副本",
"help": "次數耗儘後回退到默認打本設定",
"do_not_participate": "不參與活動",
"Cavern_of_Corrosion_Path_of_Gelid_Wind": "遺器:冰套+風套(霜風之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Jabbing_Punch": "遺器:物理套+擊破套(迅拳之徑•侵蝕隧洞)",
"Cavern_of_Corrosion_Path_of_Drifting": "遺器:治療套+快槍手(漂泊之徑•侵蝕隧洞)",
@ -346,8 +373,10 @@
"Calyx_Crimson_Destruction_Herta_StorageZone": "行跡材料:毀滅(收容艙段)",
"Calyx_Crimson_Destruction_Luofu_ScalegorgeWaterscape": "行跡材料:毀滅(鱗淵境)",
"Calyx_Crimson_Preservation_Herta_SupplyZone": "行跡材料:存護(支援艙段)",
"Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark": "行跡材料:存護(克勞克影視樂園)",
"Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains": "行跡材料:巡獵(城郊雪原)",
"Calyx_Crimson_Abundance_Jarilo_BackwaterPass": "行跡材料:豐饒(邊緣通道)",
"Calyx_Crimson_Abundance_Luofu_FyxestrollGarden": "行跡材料:豐饒(綏園)",
"Calyx_Crimson_Erudition_Jarilo_RivetTown": "行跡材料:智識(鉚釘鎮)",
"Calyx_Crimson_Harmony_Jarilo_RobotSettlement": "行跡材料:同諧(機械聚落)",
"Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape": "行跡材料:同諧(白日夢飯店-夢境)",
@ -362,18 +391,19 @@
"Stagnant_Shadow_Perdition": "角色晉階材料:物理(寒鴉 / 銀枝)",
"Stagnant_Shadow_Blaze": "角色晉階材料:火(姬子 / 艾絲妲 / 虎克)",
"Stagnant_Shadow_Scorch": "角色晉階材料:火(桂乃芬 / 托帕&帳帳)",
"Stagnant_Shadow_Ire": "角色晉階材料:火(加拉赫)",
"Stagnant_Shadow_Rime": "角色晉階材料:冰(三月七 / 黑塔 / 傑帕德 / 佩拉)",
"Stagnant_Shadow_Icicle": "角色晉階材料:冰(彥卿 / 鏡流 / 阮•梅)",
"Stagnant_Shadow_Nectar": "角色晉階材料:冰(米沙)",
"Stagnant_Shadow_Fulmination": "角色晉階材料:雷(阿蘭 / 希露瓦 / 停雲 / 白露)",
"Stagnant_Shadow_Doom": "角色晉階材料:雷(卡芙卡 / 景元",
"Stagnant_Shadow_Doom": "角色晉階材料:雷(卡芙卡 / 景元 / 黃泉",
"Stagnant_Shadow_Gust": "角色晉階材料:風(丹恆 / 布洛妮婭 / 桑博)",
"Stagnant_Shadow_Celestial": "角色晉階材料:風(刃 / 藿藿 / 黑天鵝)",
"Stagnant_Shadow_Quanta": "角色晉階材料:量子(銀狼 / 希兒 / 青雀)",
"Stagnant_Shadow_Abomination": "角色晉階材料:量子(玲可 / 符玄 / 雪衣)",
"Stagnant_Shadow_Roast": "角色晉階材料:量子(花火)",
"Stagnant_Shadow_Mirage": "角色晉階材料:虛數(瓦爾特 / 羅剎 / 馭空)",
"Stagnant_Shadow_Puppetry": "角色晉階材料:虛數(丹恆•飲月 / 真理醫生)"
"Stagnant_Shadow_Puppetry": "角色晉階材料:虛數(丹恆•飲月 / 砂金 / 真理醫生)"
},
"CavernOfCorrosion": {
"name": "完成1次侵蝕隧洞",
@ -406,6 +436,7 @@
"name": "好友支援角色",
"help": "選擇好友支援角色,未找到則選擇默認(第一個)角色\n支援角色不要與隊伍中的角色重複建議置頂好友角色",
"FirstCharacter": "支援列表第一個角色",
"Acheron": "黃泉",
"Argenti": "銀枝",
"Arlan": "阿蘭",
"Asta": "艾絲妲",
@ -418,6 +449,7 @@
"DanHengImbibitorLunae": "丹恆•飲月",
"DrRatio": "真理醫生",
"FuXuan": "符玄",
"Gallagher": "加拉赫",
"Gepard": "傑帕德",
"Guinaifen": "桂乃芬",
"Hanya": "寒鴉",

View File

@ -15,6 +15,10 @@ VALID_SERVER = {
'OVERSEA-TWHKMO': 'com.HoYoverse.hkrpgoversea',
}
VALID_PACKAGE = set(list(VALID_SERVER.values()))
VALID_CLOUD_SERVER = {
'CN-Official': 'com.miHoYo.cloudgames.hkrpg',
}
VALID_CLOUD_PACKAGE = set(list(VALID_SERVER.values()))
def set_lang(lang_: str):
@ -47,18 +51,30 @@ def to_server(package_or_server: str) -> str:
return key
if key == package_or_server:
return key
for key, value in VALID_CLOUD_SERVER.items():
if value == package_or_server:
return key
if key == package_or_server:
return key
raise ValueError(f'Package invalid: {package_or_server}')
def to_package(package_or_server: str) -> str:
def to_package(package_or_server: str, is_cloud=False) -> str:
"""
Convert package/server to package.
"""
for key, value in VALID_SERVER.items():
if value == package_or_server:
return value
if key == package_or_server:
return value
if is_cloud:
for key, value in VALID_CLOUD_SERVER.items():
if value == package_or_server:
return value
if key == package_or_server:
return value
else:
for key, value in VALID_SERVER.items():
if value == package_or_server:
return value
if key == package_or_server:
return value
raise ValueError(f'Server invalid: {package_or_server}')

View File

@ -28,6 +28,9 @@ from module.config.stored.classes import (
# ``` python -m module/config/config_updater.py ```
class StoredGenerated:
CloudRemainSeasonPass = StoredInt("Alas.CloudStorage.CloudRemainSeasonPass")
CloudRemainPaid = StoredInt("Alas.CloudStorage.CloudRemainPaid")
CloudRemainFree = StoredInt("Alas.CloudStorage.CloudRemainFree")
TrailblazePower = StoredTrailblazePower("Dungeon.DungeonStorage.TrailblazePower")
Immersifier = StoredImmersifier("Dungeon.DungeonStorage.Immersifier")
DungeonDouble = StoredDungeonDouble("Dungeon.DungeonStorage.DungeonDouble")

View File

@ -49,11 +49,14 @@ class AppControl(Adb, WSA, Uiautomator2):
Returns:
etree._Element: Select elements with `self.hierarchy.xpath('//*[@text="Hermit"]')` for example.
"""
method = self.config.Emulator_ControlMethod
if method in AppControl._app_u2_family:
self.hierarchy = self.dump_hierarchy_uiautomator2()
else:
self.hierarchy = self.dump_hierarchy_adb()
# method = self.config.Emulator_ControlMethod
# if method in AppControl._app_u2_family:
# self.hierarchy = self.dump_hierarchy_uiautomator2()
# else:
# self.hierarchy = self.dump_hierarchy_adb()
# Using uiautomator2
self.hierarchy = self.dump_hierarchy_uiautomator2()
return self.hierarchy
def xpath_to_button(self, xpath: str) -> HierarchyButton:

View File

@ -84,6 +84,11 @@ class AdbDeviceWithStatus(AdbDevice):
def __bool__(self):
return True
@cached_property
def may_mumu12_family(self):
# 127.0.0.1:16XXX
return len(self.serial) == 15 and self.serial.startswith('127.0.0.1:16')
class Connection(ConnectionAttr):
def __init__(self, config):
@ -100,7 +105,9 @@ class Connection(ConnectionAttr):
logger.attr('AdbDevice', self.adb)
# Package
if self.config.Emulator_PackageName == 'auto':
if self.config.is_cloud_game:
self.package = server_.to_package(self.config.Emulator_PackageName, is_cloud=True)
elif self.config.Emulator_PackageName == 'auto':
self.detect_package()
else:
self.package = server_.to_package(self.config.Emulator_PackageName)
@ -778,7 +785,16 @@ class Connection(ConnectionAttr):
raise RequestHumanTakeover
elif available.count == 1:
logger.info(f'Auto device detection found only one device, using it')
self.serial = devices[0].serial
self.serial = available[0].serial
del_cached_property(self, 'adb')
elif available.count == 2 \
and available.select(serial='127.0.0.1:7555') \
and available.select(may_mumu12_family=True):
logger.info(f'Auto device detection found MuMu12 device, using it')
# For MuMu12 serials like 127.0.0.1:7555 and 127.0.0.1:16384
# ignore 7555 use 16384
remain = available.select(may_mumu12_family=True).first_or_none()
self.serial = remain.serial
del_cached_property(self, 'adb')
else:
logger.critical('Multiple devices found, auto device detection cannot decide which to choose, '

View File

@ -18,9 +18,11 @@ except ImportError:
# We expect `screencap | nc 192.168.0.1 20298` instead of `screencap '|' nc 192.168.80.1 20298`
import adbutils
import subprocess
adbutils._utils.list2cmdline = subprocess.list2cmdline
adbutils._device.list2cmdline = subprocess.list2cmdline
# BaseDevice.shell() is missing a check_okay() call before reading output,
# resulting in an `OKAY` prefix in output.
def shell(self,
@ -40,6 +42,7 @@ except ImportError:
output = c.read_until_close()
return output.rstrip() if rstrip else output
adbutils._device.BaseDevice.shell = shell
from module.base.decorator import cached_property
@ -323,7 +326,7 @@ class HierarchyButton:
if res:
return res[0]
else:
return 'HierarchyButton'
return self.xpath
@cached_property
def count(self):
@ -333,15 +336,30 @@ class HierarchyButton:
def exist(self):
return self.count == 1
@cached_property
def attrib(self):
if self.exist:
return self.nodes[0].attrib
else:
return {}
@cached_property
def area(self):
if self.exist:
bounds = self.nodes[0].attrib.get("bounds")
bounds = self.attrib.get("bounds")
lx, ly, rx, ry = map(int, re.findall(r"\d+", bounds))
return lx, ly, rx, ry
else:
return None
@cached_property
def size(self):
if self.area is not None:
lx, ly, rx, ry = self.area
return rx - lx, ry - ly
else:
return None
@cached_property
def button(self):
return self.area
@ -352,9 +370,82 @@ class HierarchyButton:
def __str__(self):
return self.name
"""
Element props
"""
def _get_bool_prop(self, prop: str) -> bool:
return self.attrib.get(prop, "").lower() == 'true'
@cached_property
def focused(self):
if self.exist:
return self.nodes[0].attrib.get("focused").lower() == 'true'
else:
return False
def index(self) -> int:
try:
return int(self.attrib.get("index", 0))
except IndexError:
return 0
@cached_property
def text(self) -> str:
return self.attrib.get("text", "").strip()
@cached_property
def resourceId(self) -> str:
return self.attrib.get("resourceId", "").strip()
@cached_property
def package(self) -> str:
return self.attrib.get("resourceId", "").strip()
@cached_property
def description(self) -> str:
return self.attrib.get("resourceId", "").strip()
@cached_property
def checkable(self) -> bool:
return self._get_bool_prop('checkable')
@cached_property
def clickable(self) -> bool:
return self._get_bool_prop('clickable')
@cached_property
def enabled(self) -> bool:
return self._get_bool_prop('enabled')
@cached_property
def fucusable(self) -> bool:
return self._get_bool_prop('fucusable')
@cached_property
def focused(self) -> bool:
return self._get_bool_prop('focused')
@cached_property
def scrollable(self) -> bool:
return self._get_bool_prop('scrollable')
@cached_property
def longClickable(self) -> bool:
return self._get_bool_prop('longClickable')
@cached_property
def password(self) -> bool:
return self._get_bool_prop('password')
@cached_property
def selected(self) -> bool:
return self._get_bool_prop('selected')
class AreaButton:
def __init__(self, area, name='AREA_BUTTON'):
self.area = area
self.color = ()
self.name = name
self.button = area
def __str__(self):
return self.name
def __bool__(self):
# Cannot appear
return False

View File

@ -1,9 +1,10 @@
import numpy as np
from scipy import signal
from module.base.base import ModuleBase
from module.base.button import Button, ButtonWrapper
from module.base.timer import Timer
from module.base.utils import color_similarity_2d, random_rectangle_point
from module.base.utils import color_similarity_2d, random_rectangle_point, rgb2gray
from module.logger import logger
@ -46,7 +47,7 @@ class Scroll:
Returns:
np.ndarray: Shape (n,), dtype bool.
"""
image = main.image_crop(self.area)
image = main.image_crop(self.area, copy=False)
image = color_similarity_2d(image, color=self.color)
mask = np.max(image, axis=1 if self.is_vertical else 0) > self.color_threshold
self.length = np.sum(mask)
@ -210,3 +211,49 @@ class Scroll:
def prev_page(self, main, page=0.8, random_range=(-0.01, 0.01), skip_first_screenshot=True):
return self.drag_page(-page, main=main, random_range=random_range, skip_first_screenshot=skip_first_screenshot)
class AdaptiveScroll(Scroll):
def __init__(self, area, parameters: dict = None, background=5, is_vertical=True, name='Scroll'):
"""
Args:
area (Button, tuple): A button or area of the whole scroll.
prominence (dict): Parameters passing to scipy.find_peaks
background (int):
is_vertical (bool): True if vertical, false if horizontal.
name (str):
"""
if parameters is None:
parameters = {}
self.parameters = parameters
self.background = background
super().__init__(area, color=(255, 255, 255), is_vertical=is_vertical, name=name)
def match_color(self, main):
if self.is_vertical:
area = (self.area[0] - self.background, self.area[1], self.area[2] + self.background, self.area[3])
image = main.image_crop(area, copy=False)
image = rgb2gray(image)
image = image.flatten()
wlen = area[2] - area[0]
else:
area = (self.area[0], self.area[1] - self.background, self.area[2], self.area[3] + self.background)
image = main.image_crop(area, copy=False)
image = rgb2gray(image)
image = image.flatten('F')
wlen = area[3] - area[1]
parameters = {
'height': 128,
'prominence': 30,
'wlen': wlen,
'width': 2,
}
parameters.update(self.parameters)
peaks, _ = signal.find_peaks(image, **parameters)
peaks //= wlen
self.length = len(peaks)
mask = np.zeros((self.total,), dtype=np.bool_)
mask[peaks] = 1
return mask

View File

@ -216,6 +216,7 @@ class Route(RouteBase):
| -------- | ------------------------- | --------- | -------- |
| spawn | Waypoint((463.3, 123.5)), | 96.7 | 91 |
| item | Waypoint((476.9, 129.9)), | 116.8 | 114 |
| node1 | Waypoint((524.8, 122.6)), | 94.2 | 271 |
| enemy1 | Waypoint((544.4, 128.5)), | 129.9 | 128 |
| node2 | Waypoint((554.6, 141.6)), | 166.6 | 158 |
| enemy2 | Waypoint((556.4, 206.8)), | 190.1 | 184 |
@ -228,6 +229,7 @@ class Route(RouteBase):
Waypoint((556.4, 206.8)), end_rotation=184,
left_door=Waypoint((563.1, 211.9)), right_door=Waypoint((544.4, 211.7)))
item = Waypoint((476.9, 129.9))
node1 = Waypoint((524.8, 122.6))
enemy1 = Waypoint((544.4, 128.5))
node2 = Waypoint((554.6, 141.6))
enemy2 = Waypoint((556.4, 206.8))
@ -235,7 +237,11 @@ class Route(RouteBase):
self.rotation_set(120)
self.clear_item(item)
self.clear_enemy(enemy1)
# Avoid the ice sculpture at corner
self.clear_enemy(
node1.set_threshold(5),
enemy1,
)
self.rotation_set(180)
self.clear_enemy(
node2.set_threshold(5),

View File

@ -168,6 +168,7 @@ class Route(RouteBase):
enemy2 = Waypoint((273.9, 584.9))
# ===== End of generated waypoints =====
self.rotation_set(270)
# 1
self.clear_item(
item1.straight_run(),
@ -179,6 +180,41 @@ class Route(RouteBase):
self.clear_item(item2)
self.clear_enemy(enemy2)
def Luofu_Cloudford_F1_X433Y617(self):
"""
| Waypoint | Position | Direction | Rotation |
| -------- | ------------------------- | --------- | -------- |
| spawn | Waypoint((433.5, 616.8)), | 358.2 | 4 |
| node1 | Waypoint((431.5, 593.4)), | 2.7 | 357 |
| item1 | Waypoint((371.8, 592.8)), | 263.8 | 267 |
| enemy1 | Waypoint((341.2, 586.8)), | 274.2 | 274 |
| item2 | Waypoint((310.4, 582.2)), | 289.0 | 288 |
| enemy2 | Waypoint((273.9, 584.9)), | 274.1 | 271 |
| exit_ | Waypoint((273.9, 584.9)), | 274.1 | 271 |
"""
self.map_init(plane=Luofu_Cloudford, floor="F1", position=(433.5, 616.8))
self.register_domain_exit(Waypoint((273.9, 584.9)), end_rotation=271)
node1 = Waypoint((431.5, 593.4))
item1 = Waypoint((371.8, 592.8))
enemy1 = Waypoint((341.2, 586.8))
item2 = Waypoint((310.4, 582.2))
enemy2 = Waypoint((273.9, 584.9))
# ===== End of generated waypoints =====
# Similar to Luofu_Cloudford_F1_X431Y593, but has different spawn point
self.rotation_set(270)
# 1
self.clear_item(
node1.set_threshold(3),
item1.straight_run(),
)
self.clear_enemy(
enemy1.straight_run(),
)
# 2
self.clear_item(item2)
self.clear_enemy(enemy2)
def Luofu_Cloudford_F1_X435Y669(self):
"""
| Waypoint | Position | Direction | Rotation |

View File

@ -1,6 +1,5 @@
from tasks.map.control.waypoint import Waypoint
from tasks.map.keywords.plane import Luofu_AlchemyCommission
from tasks.map.route.base import locked_position
from tasks.rogue.route.base import RouteBase
@ -24,3 +23,30 @@ class Route(RouteBase):
self.domain_reward(reward)
self.domain_single_exit(exit_)
# ===== End of generated waypoints =====
def Luofu_AlchemyCommission_F2_X664Y545(self):
"""
| Waypoint | Position | Direction | Rotation |
| -------- | ------------------------- | --------- | -------- |
| spawn | Waypoint((623.1, 590.0)), | 282.2 | 274 |
| enemy | Waypoint((571.6, 589.5)), | 282.0 | 274 |
| reward | Waypoint((563.5, 581.4)), | 281.9 | 274 |
| exit_ | Waypoint((555.5, 597.3)), | 267.8 | 264 |
"""
self.map_init(plane=Luofu_AlchemyCommission, floor="F2", position=(664.2, 546.8))
enemy = Waypoint((571.6, 589.5))
reward = Waypoint((563.5, 581.4))
exit_ = Waypoint((555.5, 597.3))
self.clear_elite(enemy)
self.domain_reward(reward)
self.domain_single_exit(exit_)
# ===== End of generated waypoints =====
"""
Notes
Luofu_AlchemyCommission_F2_X664Y545 is the same as Luofu_AlchemyCommission_F2_X625Y590
but for wrong spawn point detected
Spawn point is too far from the correct result but should be fine in Boss room
"""

View File

@ -1,10 +1,12 @@
from tasks.map.control.waypoint import Waypoint
from tasks.map.keywords.plane import Jarilo_BackwaterPass
from tasks.map.route.base import locked_position
from tasks.rogue.route.base import RouteBase
class Route(RouteBase):
@locked_position
def Jarilo_BackwaterPass_F1_X581Y403(self):
"""
| Waypoint | Position | Direction | Rotation |

View File

@ -868,6 +868,17 @@
],
"domain": "Combat"
},
{
"name": "Combat_Luofu_Cloudford_F1_X433Y617",
"route": "route.rogue.Combat.Luofu_Cloudford_F1:Luofu_Cloudford_F1_X433Y617",
"plane": "Luofu_Cloudford",
"floor": "F1",
"position": [
433.5,
616.8
],
"domain": "Combat"
},
{
"name": "Combat_Luofu_Cloudford_F1_X435Y669",
"route": "route.rogue.Combat.Luofu_Cloudford_F1:Luofu_Cloudford_F1_X435Y669",
@ -1330,6 +1341,17 @@
],
"domain": "Elite"
},
{
"name": "Elite_Luofu_AlchemyCommission_F2_X664Y545",
"route": "route.rogue.Elite.Luofu_AlchemyCommission_F2:Luofu_AlchemyCommission_F2_X664Y545",
"plane": "Luofu_AlchemyCommission",
"floor": "F2",
"position": [
664.2,
546.8
],
"domain": "Elite"
},
{
"name": "Elite_Luofu_ArtisanshipCommission_F1_X385Y494",
"route": "route.rogue.Elite.Luofu_ArtisanshipCommission_F1:Luofu_ArtisanshipCommission_F1_X385Y494",

4
src.py
View File

@ -11,6 +11,10 @@ class StarRailCopilot(AzurLaneAutoScript):
from tasks.login.login import Login
Login(self.config, device=self.device).app_start()
def stop(self):
from tasks.login.login import Login
Login(self.config, device=self.device).app_stop()
def goto_main(self):
from tasks.login.login import Login
from tasks.base.ui import UI

View File

@ -7,17 +7,17 @@ ASSIGNMENT_START = ButtonWrapper(
name='ASSIGNMENT_START',
cn=Button(
file='./assets/cn/assignment/dispatch/ASSIGNMENT_START.png',
area=(581, 321, 699, 349),
search=(573, 299, 707, 412),
color=(93, 84, 66),
button=(581, 321, 699, 349),
area=(563, 341, 716, 376),
search=(552, 299, 725, 412),
color=(103, 92, 72),
button=(563, 341, 716, 376),
),
en=Button(
file='./assets/en/assignment/dispatch/ASSIGNMENT_START.png',
area=(679, 323, 784, 347),
search=(669, 297, 794, 416),
color=(93, 83, 65),
button=(679, 323, 784, 347),
area=(693, 343, 831, 374),
search=(669, 297, 831, 416),
color=(95, 86, 67),
button=(693, 343, 831, 374),
),
)
ASSIGNMENT_STARTED_CHECK = ButtonWrapper(
@ -34,40 +34,40 @@ CHARACTER_1 = ButtonWrapper(
name='CHARACTER_1',
share=Button(
file='./assets/share/assignment/dispatch/CHARACTER_1.png',
area=(116, 212, 206, 312),
search=(96, 192, 226, 332),
color=(149, 134, 123),
button=(116, 212, 206, 312),
area=(110, 202, 202, 309),
search=(90, 182, 222, 329),
color=(153, 141, 159),
button=(110, 202, 202, 309),
),
)
CHARACTER_1_SELECTED = ButtonWrapper(
name='CHARACTER_1_SELECTED',
share=Button(
file='./assets/share/assignment/dispatch/CHARACTER_1_SELECTED.png',
area=(114, 207, 134, 225),
search=(94, 187, 154, 245),
color=(192, 204, 193),
button=(114, 207, 134, 225),
area=(107, 199, 126, 217),
search=(87, 179, 146, 237),
color=(217, 218, 216),
button=(107, 199, 126, 217),
),
)
CHARACTER_2 = ButtonWrapper(
name='CHARACTER_2',
share=Button(
file='./assets/share/assignment/dispatch/CHARACTER_2.png',
area=(228, 211, 318, 311),
search=(208, 191, 338, 331),
color=(184, 161, 172),
button=(228, 211, 318, 311),
area=(222, 202, 314, 309),
search=(202, 182, 334, 329),
color=(120, 120, 138),
button=(222, 202, 314, 309),
),
)
CHARACTER_2_SELECTED = ButtonWrapper(
name='CHARACTER_2_SELECTED',
share=Button(
file='./assets/share/assignment/dispatch/CHARACTER_2_SELECTED.png',
area=(226, 207, 245, 225),
search=(206, 187, 265, 245),
color=(179, 194, 187),
button=(226, 207, 245, 225),
area=(219, 199, 238, 217),
search=(199, 179, 258, 237),
color=(206, 207, 204),
button=(219, 199, 238, 217),
),
)
CHARACTER_LIST = ButtonWrapper(

View File

@ -67,7 +67,12 @@ class AssignmentOcr(Ocr):
def after_process(self, result: str):
result = super().after_process(result)
# Born to ObeyCurrently Owned:7781 -> Born to Obey
for splitter in ['Currently', 'currently', '当前持有']:
try:
result = result.split(splitter)[0]
except IndexError:
pass
if self.ocr_regex is None:
return result
matched = self.ocr_regex.fullmatch(result)

View File

@ -23,6 +23,16 @@ CHAT_OPTION = ButtonWrapper(
button=(649, 496, 1129, 525),
),
)
DUNGEON_EXIT = ButtonWrapper(
name='DUNGEON_EXIT',
share=Button(
file='./assets/share/base/daemon/DUNGEON_EXIT.png',
area=(582, 598, 606, 622),
search=(562, 578, 626, 642),
color=(106, 99, 89),
button=(582, 598, 606, 622),
),
)
INTERACT_COLLECT = ButtonWrapper(
name='INTERACT_COLLECT',
share=Button(
@ -73,3 +83,33 @@ STORY_OPTION = ButtonWrapper(
button=(813, 453, 1069, 488),
),
)
TUTORIAL_CHECK = ButtonWrapper(
name='TUTORIAL_CHECK',
share=Button(
file='./assets/share/base/daemon/TUTORIAL_CHECK.png',
area=(628, 43, 653, 65),
search=(608, 23, 673, 85),
color=(90, 155, 145),
button=(628, 43, 653, 65),
),
)
TUTORIAL_CLOSE = ButtonWrapper(
name='TUTORIAL_CLOSE',
share=Button(
file='./assets/share/base/daemon/TUTORIAL_CLOSE.png',
area=(579, 634, 700, 669),
search=(559, 614, 720, 689),
color=(215, 213, 215),
button=(579, 634, 700, 669),
),
)
TUTORIAL_NEXT = ButtonWrapper(
name='TUTORIAL_NEXT',
share=Button(
file='./assets/share/base/daemon/TUTORIAL_NEXT.png',
area=(1190, 303, 1240, 365),
search=(1170, 283, 1260, 385),
color=(45, 45, 49),
button=(1190, 303, 1240, 365),
),
)

View File

@ -59,7 +59,7 @@ class Daemon(RouteBase, DaemonBase, AimDetectorMixin):
else:
logger.warning(f'Maatouch contact on {builder.contact}, may cause interruptions')
STORY_OPTION.set_search_offset((-5, -5, 32, 5))
STORY_OPTION.set_search_offset((-5, -10, 32, 5))
INTERACT_COLLECT.set_search_offset((-5, -5, 32, 5))
INTERACT_INVESTIGATE.set_search_offset((-5, -5, 32, 5))
INTERACT_TREASURE.set_search_offset((-5, -5, 32, 5))
@ -107,6 +107,16 @@ class Daemon(RouteBase, DaemonBase, AimDetectorMixin):
continue
if self.handle_ui_close(PICTURE_TAKEN, interval=1):
continue
if self.appear_then_click(DUNGEON_EXIT, interval=1.5):
continue
# Tutorial popup
if self.appear(TUTORIAL_CHECK, interval=0.2):
if self.image_color_count(TUTORIAL_CLOSE, color=(255, 255, 255), threshold=180, count=400):
self.device.click(TUTORIAL_CLOSE)
continue
if self.image_color_count(TUTORIAL_NEXT, color=(255, 255, 255), threshold=180, count=50):
self.device.click(TUTORIAL_NEXT)
continue
# Rogue
if self.handle_blessing():
continue

View File

@ -40,6 +40,8 @@ class OcrPlaneName(OcrWhiteLetterOnComplexBackground):
result = re.sub(r'区域.*战$', '区域战斗', result)
# 区域-事
result = re.sub(r'区域.*事$', '区域事件', result)
# 区域-战
result = re.sub(r'区域.*交$', '区域交易', result)
# 区域-事伴, 区域-事祥
result = re.sub(r'事[伴祥]', '事件', result)
# 医域-战斗

View File

@ -3,8 +3,17 @@ from .classes import CharacterList
# This file was auto-generated, do not modify it manually. To generate:
# ``` python -m dev_tools.keyword_extract ```
Argenti = CharacterList(
Acheron = CharacterList(
id=1,
name='Acheron',
cn='黄泉',
cht='黃泉',
en='Acheron',
jp='黄泉',
es='Acheron',
)
Argenti = CharacterList(
id=2,
name='Argenti',
cn='银枝',
cht='銀枝',
@ -13,7 +22,7 @@ Argenti = CharacterList(
es='Argenti',
)
Arlan = CharacterList(
id=2,
id=3,
name='Arlan',
cn='阿兰',
cht='阿蘭',
@ -22,7 +31,7 @@ Arlan = CharacterList(
es='Arlan',
)
Asta = CharacterList(
id=3,
id=4,
name='Asta',
cn='艾丝妲',
cht='艾絲妲',
@ -30,8 +39,17 @@ Asta = CharacterList(
jp='アスター',
es='Asta',
)
Aventurine = CharacterList(
id=5,
name='Aventurine',
cn='砂金',
cht='砂金',
en='Aventurine',
jp='アベンチュリン',
es='Aventurino',
)
Bailu = CharacterList(
id=4,
id=6,
name='Bailu',
cn='白露',
cht='白露',
@ -40,7 +58,7 @@ Bailu = CharacterList(
es='Bailu',
)
BlackSwan = CharacterList(
id=5,
id=7,
name='BlackSwan',
cn='黑天鹅',
cht='黑天鵝',
@ -49,7 +67,7 @@ BlackSwan = CharacterList(
es='Cisne Negro',
)
Blade = CharacterList(
id=6,
id=8,
name='Blade',
cn='',
cht='',
@ -58,7 +76,7 @@ Blade = CharacterList(
es='Blade',
)
Bronya = CharacterList(
id=7,
id=9,
name='Bronya',
cn='布洛妮娅',
cht='布洛妮婭',
@ -67,7 +85,7 @@ Bronya = CharacterList(
es='Bronya',
)
Clara = CharacterList(
id=8,
id=10,
name='Clara',
cn='克拉拉',
cht='克拉拉',
@ -76,7 +94,7 @@ Clara = CharacterList(
es='Clara',
)
DanHeng = CharacterList(
id=9,
id=11,
name='DanHeng',
cn='丹恒',
cht='丹恆',
@ -85,7 +103,7 @@ DanHeng = CharacterList(
es='Dan Heng',
)
DanHengImbibitorLunae = CharacterList(
id=10,
id=12,
name='DanHengImbibitorLunae',
cn='丹恒•饮月',
cht='丹恆•飲月',
@ -94,7 +112,7 @@ DanHengImbibitorLunae = CharacterList(
es='Dan Heng - Imbibitor Lunae',
)
DrRatio = CharacterList(
id=11,
id=13,
name='DrRatio',
cn='真理医生',
cht='真理醫生',
@ -103,7 +121,7 @@ DrRatio = CharacterList(
es='Dr. Ratio',
)
FuXuan = CharacterList(
id=12,
id=14,
name='FuXuan',
cn='符玄',
cht='符玄',
@ -111,8 +129,17 @@ FuXuan = CharacterList(
jp='符玄',
es='Fu Xuan',
)
Gallagher = CharacterList(
id=15,
name='Gallagher',
cn='加拉赫',
cht='加拉赫',
en='Gallagher',
jp='ギャラガー',
es='Gallagher',
)
Gepard = CharacterList(
id=13,
id=16,
name='Gepard',
cn='杰帕德',
cht='傑帕德',
@ -121,7 +148,7 @@ Gepard = CharacterList(
es='Gepard',
)
Guinaifen = CharacterList(
id=14,
id=17,
name='Guinaifen',
cn='桂乃芬',
cht='桂乃芬',
@ -130,7 +157,7 @@ Guinaifen = CharacterList(
es='Guinaifen',
)
Hanya = CharacterList(
id=15,
id=18,
name='Hanya',
cn='寒鸦',
cht='寒鴉',
@ -139,7 +166,7 @@ Hanya = CharacterList(
es='Hanya',
)
Herta = CharacterList(
id=16,
id=19,
name='Herta',
cn='黑塔',
cht='黑塔',
@ -148,7 +175,7 @@ Herta = CharacterList(
es='Herta',
)
Himeko = CharacterList(
id=17,
id=20,
name='Himeko',
cn='姬子',
cht='姬子',
@ -157,7 +184,7 @@ Himeko = CharacterList(
es='Himeko',
)
Hook = CharacterList(
id=18,
id=21,
name='Hook',
cn='虎克',
cht='虎克',
@ -166,7 +193,7 @@ Hook = CharacterList(
es='Hook',
)
Huohuo = CharacterList(
id=19,
id=22,
name='Huohuo',
cn='藿藿',
cht='藿藿',
@ -175,7 +202,7 @@ Huohuo = CharacterList(
es='Huohuo',
)
JingYuan = CharacterList(
id=20,
id=23,
name='JingYuan',
cn='景元',
cht='景元',
@ -184,7 +211,7 @@ JingYuan = CharacterList(
es='Jing Yuan',
)
Jingliu = CharacterList(
id=21,
id=24,
name='Jingliu',
cn='镜流',
cht='鏡流',
@ -193,7 +220,7 @@ Jingliu = CharacterList(
es='Jingliu',
)
Kafka = CharacterList(
id=22,
id=25,
name='Kafka',
cn='卡芙卡',
cht='卡芙卡',
@ -202,7 +229,7 @@ Kafka = CharacterList(
es='Kafka',
)
Luka = CharacterList(
id=23,
id=26,
name='Luka',
cn='卢卡',
cht='盧卡',
@ -211,7 +238,7 @@ Luka = CharacterList(
es='Luka',
)
Luocha = CharacterList(
id=24,
id=27,
name='Luocha',
cn='罗刹',
cht='羅剎',
@ -220,7 +247,7 @@ Luocha = CharacterList(
es='Luocha',
)
Lynx = CharacterList(
id=25,
id=28,
name='Lynx',
cn='玲可',
cht='玲可',
@ -229,7 +256,7 @@ Lynx = CharacterList(
es='Lynx',
)
March7th = CharacterList(
id=26,
id=29,
name='March7th',
cn='三月七',
cht='三月七',
@ -238,7 +265,7 @@ March7th = CharacterList(
es='Siete de Marzo',
)
Misha = CharacterList(
id=27,
id=30,
name='Misha',
cn='米沙',
cht='米沙',
@ -247,7 +274,7 @@ Misha = CharacterList(
es='Misha',
)
Natasha = CharacterList(
id=28,
id=31,
name='Natasha',
cn='娜塔莎',
cht='娜塔莎',
@ -256,7 +283,7 @@ Natasha = CharacterList(
es='Natasha',
)
Pela = CharacterList(
id=29,
id=32,
name='Pela',
cn='佩拉',
cht='佩拉',
@ -265,7 +292,7 @@ Pela = CharacterList(
es='Pela',
)
Qingque = CharacterList(
id=30,
id=33,
name='Qingque',
cn='青雀',
cht='青雀',
@ -274,7 +301,7 @@ Qingque = CharacterList(
es='Qingque',
)
RuanMei = CharacterList(
id=31,
id=34,
name='RuanMei',
cn='阮•梅',
cht='阮•梅',
@ -283,7 +310,7 @@ RuanMei = CharacterList(
es='Ruan Mei',
)
Sampo = CharacterList(
id=32,
id=35,
name='Sampo',
cn='桑博',
cht='桑博',
@ -292,7 +319,7 @@ Sampo = CharacterList(
es='Sampo',
)
Seele = CharacterList(
id=33,
id=36,
name='Seele',
cn='希儿',
cht='希兒',
@ -301,7 +328,7 @@ Seele = CharacterList(
es='Seele',
)
Serval = CharacterList(
id=34,
id=37,
name='Serval',
cn='希露瓦',
cht='希露瓦',
@ -310,7 +337,7 @@ Serval = CharacterList(
es='Serval',
)
SilverWolf = CharacterList(
id=35,
id=38,
name='SilverWolf',
cn='银狼',
cht='銀狼',
@ -319,7 +346,7 @@ SilverWolf = CharacterList(
es='Silver Wolf',
)
Sparkle = CharacterList(
id=36,
id=39,
name='Sparkle',
cn='花火',
cht='花火',
@ -328,7 +355,7 @@ Sparkle = CharacterList(
es='Sparkle',
)
Sushang = CharacterList(
id=37,
id=40,
name='Sushang',
cn='素裳',
cht='素裳',
@ -337,7 +364,7 @@ Sushang = CharacterList(
es='Sushang',
)
Tingyun = CharacterList(
id=38,
id=41,
name='Tingyun',
cn='停云',
cht='停雲',
@ -346,7 +373,7 @@ Tingyun = CharacterList(
es='Tingyun',
)
TopazNumby = CharacterList(
id=39,
id=42,
name='TopazNumby',
cn='托帕&账账',
cht='托帕&帳帳',
@ -355,7 +382,7 @@ TopazNumby = CharacterList(
es='Topaz y Conti',
)
TrailblazerDestruction = CharacterList(
id=40,
id=43,
name='TrailblazerDestruction',
cn='Trailblazer•毁灭',
cht='Trailblazer•毀滅',
@ -364,7 +391,7 @@ TrailblazerDestruction = CharacterList(
es='Trailblazer: Destrucción',
)
TrailblazerPreservation = CharacterList(
id=41,
id=44,
name='TrailblazerPreservation',
cn='Trailblazer•存护',
cht='Trailblazer•存護',
@ -373,7 +400,7 @@ TrailblazerPreservation = CharacterList(
es='Trailblazer: Conservación',
)
Welt = CharacterList(
id=42,
id=45,
name='Welt',
cn='瓦尔特',
cht='瓦爾特',
@ -382,7 +409,7 @@ Welt = CharacterList(
es='Welt',
)
Xueyi = CharacterList(
id=43,
id=46,
name='Xueyi',
cn='雪衣',
cht='雪衣',
@ -391,7 +418,7 @@ Xueyi = CharacterList(
es='Xueyi',
)
Yanqing = CharacterList(
id=44,
id=47,
name='Yanqing',
cn='彦卿',
cht='彥卿',
@ -400,7 +427,7 @@ Yanqing = CharacterList(
es='Yanqing',
)
Yukong = CharacterList(
id=45,
id=48,
name='Yukong',
cn='驭空',
cht='馭空',

View File

@ -81,7 +81,15 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
"""
logger.hr('Combat prepare')
skip_first_screenshot = True
pre_set_team = bool(support_character)
if support_character:
# To set team before support set
pre_set_team = True
# Block COMBAT_TEAM_PREPARE before support set
support_set = False
else:
pre_set_team = False
support_set = True
logger.info([support_character, pre_set_team, support_set])
trial = 0
while 1:
if skip_first_screenshot:
@ -99,14 +107,15 @@ class Combat(CombatInteract, CombatPrepare, CombatState, CombatTeam, CombatSuppo
raise RequestHumanTakeover
# Click
if self.appear(COMBAT_TEAM_SUPPORT) and support_character:
if support_character and self.appear(COMBAT_TEAM_SUPPORT):
if pre_set_team:
self.team_set(team)
pre_set_team = False
continue
self.support_set(support_character)
support_set = True
continue
if self.appear(COMBAT_TEAM_PREPARE, interval=2):
if support_set and self.appear(COMBAT_TEAM_PREPARE, interval=2):
self.team_set(team)
self.device.click(COMBAT_TEAM_PREPARE)
self.interval_reset(COMBAT_TEAM_PREPARE)

View File

@ -2,7 +2,7 @@ import cv2
from scipy import signal
from module.base.timer import Timer
from module.base.utils import rgb2gray
from module.base.utils import rgb2luma
from module.logger import logger
from tasks.base.ui import UI
from tasks.combat.assets.assets_combat_state import COMBAT_AUTO, COMBAT_PAUSE, COMBAT_SPEED_2X
@ -22,7 +22,7 @@ class CombatState(UI):
return False
def _is_combat_button_active(self, button):
image = rgb2gray(self.image_crop(button))
image = rgb2luma(self.image_crop(button))
lines = cv2.reduce(image, 1, cv2.REDUCE_AVG).flatten()
# [122 122 122 182 141 127 139 135 130 135 136 141 147 149 149 150 147 145
# 148 150 150 150 150 150 144 138 134 141 136 133 173 183 130 128 127 126]

View File

@ -1,12 +1,11 @@
import cv2
import numpy as np
from scipy import signal
from module.base.button import ClickButton
from module.base.timer import Timer
from module.base.utils import area_offset, area_size, crop, load_image, rgb2luma
from module.base.utils import area_offset, crop, load_image
from module.logger import logger
from module.ui.scroll import Scroll
from module.ui.scroll import AdaptiveScroll
from tasks.base.assets.assets_base_popup import POPUP_CANCEL
from tasks.base.ui import UI
from tasks.combat.assets.assets_combat_support import COMBAT_SUPPORT_ADD, COMBAT_SUPPORT_LIST, \
@ -116,41 +115,6 @@ class NextSupportCharacter:
return SUPPORT_SELECTED.match_template(image, similarity=0.75, direct_match=True)
class SupportListScroll(Scroll):
def cal_position(self, main):
"""
Args:
main (ModuleBase):
Returns:
float: 0 to 1.
"""
image = main.device.image
temp_area = list(self.area)
temp_area[0] = int(temp_area[0] * 0.98)
temp_area[2] = int(temp_area[2] * 1.02)
line = rgb2luma(crop(image, temp_area)).flatten()
width = area_size(temp_area)[0]
parameters = {
"height": 180,
"prominence": 30,
"distance": width * 0.75,
}
peaks, _ = signal.find_peaks(line, **parameters)
peaks //= width
self.length = len(peaks)
middle = np.mean(peaks)
position = (middle - self.length / 2) / (self.total - self.length)
position = position if position > 0 else 0.0
position = position if position < 1 else 1.0
logger.attr(
self.name, f"{position:.2f} ({middle}-{self.length / 2})/({self.total}-{self.length})")
return position
class CombatSupport(UI):
def support_set(self, support_character_name: str = "FirstCharacter"):
"""
@ -212,8 +176,8 @@ class CombatSupport(UI):
out: COMBAT_SUPPORT_LIST
"""
logger.hr("Combat support search")
scroll = SupportListScroll(area=COMBAT_SUPPORT_LIST_SCROLL.area, color=(194, 196, 205),
name=COMBAT_SUPPORT_LIST_SCROLL.name)
scroll = AdaptiveScroll(area=COMBAT_SUPPORT_LIST_SCROLL.area,
name=COMBAT_SUPPORT_LIST_SCROLL.name)
if scroll.appear(main=self):
if not scroll.at_bottom(main=self):
# Dropdown to load the entire support list, so large threshold is acceptable
@ -311,8 +275,8 @@ class CombatSupport(UI):
out: COMBAT_SUPPORT_LIST
"""
skip_first_screenshot = True
scroll = SupportListScroll(area=COMBAT_SUPPORT_LIST_SCROLL.area, color=(194, 196, 205),
name=COMBAT_SUPPORT_LIST_SCROLL.name)
scroll = AdaptiveScroll(area=COMBAT_SUPPORT_LIST_SCROLL.area,
name=COMBAT_SUPPORT_LIST_SCROLL.name)
interval = Timer(1)
next_support = None
if scroll.appear(main=self):

View File

@ -141,9 +141,9 @@ SYNTHESIZE_SCROLL = ButtonWrapper(
name='SYNTHESIZE_SCROLL',
share=Button(
file='./assets/share/daily/synthesize_consumable/SYNTHESIZE_SCROLL.png',
area=(458, 80, 464, 628),
search=(438, 60, 484, 648),
color=(134, 130, 144),
button=(458, 80, 464, 628),
area=(460, 90, 464, 618),
search=(440, 70, 484, 638),
color=(167, 165, 177),
button=(460, 90, 464, 618),
),
)

View File

@ -1,5 +1,5 @@
from module.ocr.ocr import *
from module.ui.scroll import Scroll
from module.ui.scroll import AdaptiveScroll, Scroll
from tasks.base.assets.assets_base_page import MENU_CHECK, MENU_SCROLL, SYNTHESIZE_CHECK
from tasks.base.assets.assets_base_popup import POPUP_CONFIRM
from tasks.base.page import Page, page_menu, page_synthesize
@ -32,7 +32,7 @@ class SynthesizeUI(UI):
scroll = Scroll(MENU_SCROLL.button, color=(191, 191, 191), name=MENU_SCROLL.name)
case page_synthesize.name:
check_image = SYNTHESIZE_CHECK
scroll = Scroll(SYNTHESIZE_SCROLL.button, color=(210, 210, 210), name=SYNTHESIZE_SCROLL.name)
scroll = AdaptiveScroll(SYNTHESIZE_SCROLL.button, name=SYNTHESIZE_SCROLL.name)
case _:
logger.info(f'No page matched, just skip')
return
@ -109,7 +109,7 @@ class SynthesizeUI(UI):
else self.__class__.default_candidate_items
# Search target button from top to bottom
scroll = Scroll(SYNTHESIZE_SCROLL.button, color=(210, 210, 210), name=SYNTHESIZE_SCROLL.name)
scroll = AdaptiveScroll(SYNTHESIZE_SCROLL.button, name=SYNTHESIZE_SCROLL.name)
if scroll.appear(main=self):
skip_first_screenshot = True
while 1:

View File

@ -37,10 +37,10 @@ OCR_DOUBLE_EVENT_REMAIN = ButtonWrapper(
name='OCR_DOUBLE_EVENT_REMAIN',
share=Button(
file='./assets/share/dungeon/event/OCR_DOUBLE_EVENT_REMAIN.png',
area=(513, 181, 1103, 203),
search=(493, 161, 1123, 223),
color=(201, 164, 88),
button=(513, 181, 1103, 203),
area=(517, 239, 1081, 261),
search=(497, 219, 1101, 281),
color=(198, 161, 90),
button=(517, 239, 1081, 261),
),
)
OCR_DOUBLE_EVENT_REMAIN_AT_COMBAT = ButtonWrapper(

View File

@ -226,8 +226,7 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
ran_calyx_crimson = False
ran_cavern_of_corrosion = False
# Double calyx
if self.config.Dungeon_NameAtDoubleCalyx != 'do_not_participate' \
and self.config.stored.DungeonDouble.calyx > 0:
if self.config.stored.DungeonDouble.calyx > 0:
logger.info('Run double calyx')
dungeon = DungeonList.find(self.config.Dungeon_NameAtDoubleCalyx)
self.running_double = True
@ -237,8 +236,7 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
if dungeon.is_Calyx_Crimson:
ran_calyx_crimson = True
# Double relic
if self.config.Dungeon_NameAtDoubleRelic != 'do_not_participate' \
and self.config.stored.DungeonDouble.relic > 0:
if self.config.stored.DungeonDouble.relic > 0:
logger.info('Run double relic')
dungeon = DungeonList.find(self.config.Dungeon_NameAtDoubleRelic)
self.running_double = True

View File

@ -123,8 +123,18 @@ Calyx_Crimson_Preservation_Herta_SupplyZone = DungeonList(
es='Flor de la Conservación',
plane_id=2000301,
)
Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains = DungeonList(
Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark = DungeonList(
id=13,
name='Calyx_Crimson_Preservation_Penacony_ClockStudiosThemePark',
cn='存护之蕾•拟造花萼(赤)',
cht='存護之蕾•擬造花萼(赤)',
en='Bud of Preservation',
jp='疑似花萼(赤)・存護の蕾',
es='Flor de la Conservación',
plane_id=2032101,
)
Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains = DungeonList(
id=14,
name='Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains',
cn='巡猎之蕾•拟造花萼(赤)',
cht='巡獵之蕾•擬造花萼(赤)',
@ -134,7 +144,7 @@ Calyx_Crimson_The_Hunt_Jarilo_OutlyingSnowPlains = DungeonList(
plane_id=2010101,
)
Calyx_Crimson_Abundance_Jarilo_BackwaterPass = DungeonList(
id=14,
id=15,
name='Calyx_Crimson_Abundance_Jarilo_BackwaterPass',
cn='丰饶之蕾•拟造花萼(赤)',
cht='豐饒之蕾•擬造花萼(赤)',
@ -143,8 +153,18 @@ Calyx_Crimson_Abundance_Jarilo_BackwaterPass = DungeonList(
es='Flor de la Abundancia',
plane_id=2011101,
)
Calyx_Crimson_Abundance_Luofu_FyxestrollGarden = DungeonList(
id=16,
name='Calyx_Crimson_Abundance_Luofu_FyxestrollGarden',
cn='丰饶之蕾•拟造花萼(赤)',
cht='豐饒之蕾•擬造花萼(赤)',
en='Bud of Abundance',
jp='疑似花萼(赤)・豊穣の蕾',
es='Flor de la Abundancia',
plane_id=2022301,
)
Calyx_Crimson_Erudition_Jarilo_RivetTown = DungeonList(
id=15,
id=17,
name='Calyx_Crimson_Erudition_Jarilo_RivetTown',
cn='智识之蕾•拟造花萼(赤)',
cht='智識之蕾•擬造花萼(赤)',
@ -154,7 +174,7 @@ Calyx_Crimson_Erudition_Jarilo_RivetTown = DungeonList(
plane_id=2012201,
)
Calyx_Crimson_Harmony_Jarilo_RobotSettlement = DungeonList(
id=16,
id=18,
name='Calyx_Crimson_Harmony_Jarilo_RobotSettlement',
cn='同谐之蕾•拟造花萼(赤)',
cht='同諧之蕾•擬造花萼(赤)',
@ -164,7 +184,7 @@ Calyx_Crimson_Harmony_Jarilo_RobotSettlement = DungeonList(
plane_id=2012301,
)
Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape = DungeonList(
id=17,
id=19,
name='Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape',
cn='同谐之蕾•拟造花萼(赤)',
cht='同諧之蕾•擬造花萼(赤)',
@ -174,7 +194,7 @@ Calyx_Crimson_Harmony_Penacony_TheReverieDreamscape = DungeonList(
plane_id=2031101,
)
Calyx_Crimson_Nihility_Jarilo_GreatMine = DungeonList(
id=18,
id=20,
name='Calyx_Crimson_Nihility_Jarilo_GreatMine',
cn='虚无之蕾•拟造花萼(赤)',
cht='虛無之蕾•擬造花萼(赤)',
@ -184,7 +204,7 @@ Calyx_Crimson_Nihility_Jarilo_GreatMine = DungeonList(
plane_id=2012101,
)
Calyx_Crimson_Nihility_Luofu_AlchemyCommission = DungeonList(
id=19,
id=21,
name='Calyx_Crimson_Nihility_Luofu_AlchemyCommission',
cn='虚无之蕾•拟造花萼(赤)',
cht='虛無之蕾•擬造花萼(赤)',
@ -194,7 +214,7 @@ Calyx_Crimson_Nihility_Luofu_AlchemyCommission = DungeonList(
plane_id=2023101,
)
Stagnant_Shadow_Quanta = DungeonList(
id=20,
id=22,
name='Stagnant_Shadow_Quanta',
cn='空海之形•凝滞虚影',
cht='空海之形•凝滯虛影',
@ -204,7 +224,7 @@ Stagnant_Shadow_Quanta = DungeonList(
plane_id=2000101,
)
Stagnant_Shadow_Gust = DungeonList(
id=21,
id=23,
name='Stagnant_Shadow_Gust',
cn='巽风之形•凝滞虚影',
cht='巽風之形•凝滯虛影',
@ -214,7 +234,7 @@ Stagnant_Shadow_Gust = DungeonList(
plane_id=2012201,
)
Stagnant_Shadow_Fulmination = DungeonList(
id=22,
id=24,
name='Stagnant_Shadow_Fulmination',
cn='鸣雷之形•凝滞虚影',
cht='鳴雷之形•凝滯虛影',
@ -224,7 +244,7 @@ Stagnant_Shadow_Fulmination = DungeonList(
plane_id=2013201,
)
Stagnant_Shadow_Blaze = DungeonList(
id=23,
id=25,
name='Stagnant_Shadow_Blaze',
cn='炎华之形•凝滞虚影',
cht='炎華之形•凝滯虛影',
@ -234,7 +254,7 @@ Stagnant_Shadow_Blaze = DungeonList(
plane_id=2013101,
)
Stagnant_Shadow_Spike = DungeonList(
id=24,
id=26,
name='Stagnant_Shadow_Spike',
cn='锋芒之形•凝滞虚影',
cht='鋒芒之形•凝滯虛影',
@ -244,7 +264,7 @@ Stagnant_Shadow_Spike = DungeonList(
plane_id=2012101,
)
Stagnant_Shadow_Rime = DungeonList(
id=25,
id=27,
name='Stagnant_Shadow_Rime',
cn='霜晶之形•凝滞虚影',
cht='霜晶之形•凝滯虛影',
@ -254,7 +274,7 @@ Stagnant_Shadow_Rime = DungeonList(
plane_id=2013201,
)
Stagnant_Shadow_Mirage = DungeonList(
id=26,
id=28,
name='Stagnant_Shadow_Mirage',
cn='幻光之形•凝滞虚影',
cht='幻光之形•凝滯虛影',
@ -264,7 +284,7 @@ Stagnant_Shadow_Mirage = DungeonList(
plane_id=2011101,
)
Stagnant_Shadow_Icicle = DungeonList(
id=27,
id=29,
name='Stagnant_Shadow_Icicle',
cn='冰棱之形•凝滞虚影',
cht='冰稜之形•凝滯虛影',
@ -274,7 +294,7 @@ Stagnant_Shadow_Icicle = DungeonList(
plane_id=2021101,
)
Stagnant_Shadow_Doom = DungeonList(
id=28,
id=30,
name='Stagnant_Shadow_Doom',
cn='震厄之形•凝滞虚影',
cht='震厄之形•凝滯虛影',
@ -284,7 +304,7 @@ Stagnant_Shadow_Doom = DungeonList(
plane_id=2021201,
)
Stagnant_Shadow_Puppetry = DungeonList(
id=29,
id=31,
name='Stagnant_Shadow_Puppetry',
cn='偃偶之形•凝滞虚影',
cht='偃偶之形•凝滯虛影',
@ -294,7 +314,7 @@ Stagnant_Shadow_Puppetry = DungeonList(
plane_id=2022201,
)
Stagnant_Shadow_Abomination = DungeonList(
id=30,
id=32,
name='Stagnant_Shadow_Abomination',
cn='孽兽之形•凝滞虚影',
cht='孽獸之形•凝滯虛影',
@ -304,7 +324,7 @@ Stagnant_Shadow_Abomination = DungeonList(
plane_id=2023201,
)
Stagnant_Shadow_Scorch = DungeonList(
id=31,
id=33,
name='Stagnant_Shadow_Scorch',
cn='燔灼之形•凝滞虚影',
cht='燔灼之形•凝滯虛影',
@ -314,7 +334,7 @@ Stagnant_Shadow_Scorch = DungeonList(
plane_id=2012101,
)
Stagnant_Shadow_Celestial = DungeonList(
id=32,
id=34,
name='Stagnant_Shadow_Celestial',
cn='天人之形•凝滞虚影',
cht='天人之形•凝滯虛影',
@ -324,7 +344,7 @@ Stagnant_Shadow_Celestial = DungeonList(
plane_id=2023101,
)
Stagnant_Shadow_Perdition = DungeonList(
id=33,
id=35,
name='Stagnant_Shadow_Perdition',
cn='幽府之形•凝滞虚影',
cht='幽府之形•凝滯虛影',
@ -334,7 +354,7 @@ Stagnant_Shadow_Perdition = DungeonList(
plane_id=2022301,
)
Stagnant_Shadow_Nectar = DungeonList(
id=34,
id=36,
name='Stagnant_Shadow_Nectar',
cn='冰酿之形•凝滞虚影',
cht='冰釀之形•凝滯虛影',
@ -344,7 +364,7 @@ Stagnant_Shadow_Nectar = DungeonList(
plane_id=2031101,
)
Stagnant_Shadow_Roast = DungeonList(
id=35,
id=37,
name='Stagnant_Shadow_Roast',
cn='焦炙之形•凝滞虚影',
cht='焦炙之形•凝滯虛影',
@ -353,8 +373,18 @@ Stagnant_Shadow_Roast = DungeonList(
es='Forma del agostamiento',
plane_id=2031301,
)
Stagnant_Shadow_Ire = DungeonList(
id=38,
name='Stagnant_Shadow_Ire',
cn='嗔怒之形•凝滞虚影',
cht='嗔怒之形•凝滯虛影',
en='Shape of Ire',
jp='凝結虚影・憤怒の形',
es='Forma de la ira',
plane_id=2032201,
)
Cavern_of_Corrosion_Path_of_Gelid_Wind = DungeonList(
id=36,
id=39,
name='Cavern_of_Corrosion_Path_of_Gelid_Wind',
cn='霜风之径•侵蚀隧洞',
cht='霜風之徑•侵蝕隧洞',
@ -364,7 +394,7 @@ Cavern_of_Corrosion_Path_of_Gelid_Wind = DungeonList(
plane_id=2000201,
)
Cavern_of_Corrosion_Path_of_Jabbing_Punch = DungeonList(
id=37,
id=40,
name='Cavern_of_Corrosion_Path_of_Jabbing_Punch',
cn='迅拳之径•侵蚀隧洞',
cht='迅拳之徑•侵蝕隧洞',
@ -374,7 +404,7 @@ Cavern_of_Corrosion_Path_of_Jabbing_Punch = DungeonList(
plane_id=2013101,
)
Cavern_of_Corrosion_Path_of_Drifting = DungeonList(
id=38,
id=41,
name='Cavern_of_Corrosion_Path_of_Drifting',
cn='漂泊之径•侵蚀隧洞',
cht='漂泊之徑•侵蝕隧洞',
@ -384,7 +414,7 @@ Cavern_of_Corrosion_Path_of_Drifting = DungeonList(
plane_id=2013201,
)
Cavern_of_Corrosion_Path_of_Providence = DungeonList(
id=39,
id=42,
name='Cavern_of_Corrosion_Path_of_Providence',
cn='睿治之径•侵蚀隧洞',
cht='睿治之徑•侵蝕隧洞',
@ -394,7 +424,7 @@ Cavern_of_Corrosion_Path_of_Providence = DungeonList(
plane_id=2013401,
)
Cavern_of_Corrosion_Path_of_Holy_Hymn = DungeonList(
id=40,
id=43,
name='Cavern_of_Corrosion_Path_of_Holy_Hymn',
cn='圣颂之径•侵蚀隧洞',
cht='聖頌之徑•侵蝕隧洞',
@ -404,7 +434,7 @@ Cavern_of_Corrosion_Path_of_Holy_Hymn = DungeonList(
plane_id=2021101,
)
Cavern_of_Corrosion_Path_of_Conflagration = DungeonList(
id=41,
id=44,
name='Cavern_of_Corrosion_Path_of_Conflagration',
cn='野焰之径•侵蚀隧洞',
cht='野焰之徑•侵蝕隧洞',
@ -414,7 +444,7 @@ Cavern_of_Corrosion_Path_of_Conflagration = DungeonList(
plane_id=2021201,
)
Cavern_of_Corrosion_Path_of_Elixir_Seekers = DungeonList(
id=42,
id=45,
name='Cavern_of_Corrosion_Path_of_Elixir_Seekers',
cn='药使之径•侵蚀隧洞',
cht='藥使之徑•侵蝕隧洞',
@ -424,7 +454,7 @@ Cavern_of_Corrosion_Path_of_Elixir_Seekers = DungeonList(
plane_id=2023101,
)
Cavern_of_Corrosion_Path_of_Darkness = DungeonList(
id=43,
id=46,
name='Cavern_of_Corrosion_Path_of_Darkness',
cn='幽冥之径•侵蚀隧洞',
cht='幽冥之徑•侵蝕隧洞',
@ -434,7 +464,7 @@ Cavern_of_Corrosion_Path_of_Darkness = DungeonList(
plane_id=2022301,
)
Cavern_of_Corrosion_Path_of_Dreamdive = DungeonList(
id=44,
id=47,
name='Cavern_of_Corrosion_Path_of_Dreamdive',
cn='梦潜之径•侵蚀隧洞',
cht='夢潛之徑•侵蝕隧洞',
@ -444,7 +474,7 @@ Cavern_of_Corrosion_Path_of_Dreamdive = DungeonList(
plane_id=2031101,
)
Echo_of_War_Destruction_Beginning = DungeonList(
id=45,
id=48,
name='Echo_of_War_Destruction_Beginning',
cn='毁灭的开端•历战余响',
cht='毀滅的開端•歷戰餘響',
@ -454,7 +484,7 @@ Echo_of_War_Destruction_Beginning = DungeonList(
plane_id=2000301,
)
Echo_of_War_End_of_the_Eternal_Freeze = DungeonList(
id=46,
id=49,
name='Echo_of_War_End_of_the_Eternal_Freeze',
cn='寒潮的落幕•历战余响',
cht='寒潮的落幕•歷戰餘響',
@ -464,7 +494,7 @@ Echo_of_War_End_of_the_Eternal_Freeze = DungeonList(
plane_id=2013401,
)
Echo_of_War_Divine_Seed = DungeonList(
id=47,
id=50,
name='Echo_of_War_Divine_Seed',
cn='不死的神实•历战余响',
cht='不死的神實•歷戰餘響',
@ -474,7 +504,7 @@ Echo_of_War_Divine_Seed = DungeonList(
plane_id=2023201,
)
Echo_of_War_Borehole_Planet_Old_Crater = DungeonList(
id=48,
id=51,
name='Echo_of_War_Borehole_Planet_Old_Crater',
cn='蛀星的旧靥•历战余响',
cht='蛀星的舊靨•歷戰餘響',
@ -484,7 +514,7 @@ Echo_of_War_Borehole_Planet_Old_Crater = DungeonList(
plane_id=2000401,
)
Simulated_Universe_World_1 = DungeonList(
id=49,
id=52,
name='Simulated_Universe_World_1',
cn='第一世界•模拟宇宙',
cht='第一世界•模擬宇宙',
@ -494,7 +524,7 @@ Simulated_Universe_World_1 = DungeonList(
plane_id=100000104,
)
Simulated_Universe_World_3 = DungeonList(
id=50,
id=53,
name='Simulated_Universe_World_3',
cn='第三世界•模拟宇宙',
cht='第三世界•模擬宇宙',
@ -504,7 +534,7 @@ Simulated_Universe_World_3 = DungeonList(
plane_id=100000104,
)
Simulated_Universe_World_4 = DungeonList(
id=51,
id=54,
name='Simulated_Universe_World_4',
cn='第四世界•模拟宇宙',
cht='第四世界•模擬宇宙',
@ -514,7 +544,7 @@ Simulated_Universe_World_4 = DungeonList(
plane_id=100000104,
)
Simulated_Universe_World_5 = DungeonList(
id=52,
id=55,
name='Simulated_Universe_World_5',
cn='第五世界•模拟宇宙',
cht='第五世界•模擬宇宙',
@ -524,7 +554,7 @@ Simulated_Universe_World_5 = DungeonList(
plane_id=100000104,
)
Simulated_Universe_World_6 = DungeonList(
id=53,
id=56,
name='Simulated_Universe_World_6',
cn='第六世界•模拟宇宙',
cht='第六世界•模擬宇宙',
@ -534,7 +564,7 @@ Simulated_Universe_World_6 = DungeonList(
plane_id=100000104,
)
Simulated_Universe_World_7 = DungeonList(
id=54,
id=57,
name='Simulated_Universe_World_7',
cn='第七世界•模拟宇宙',
cht='第七世界•模擬宇宙',
@ -544,7 +574,7 @@ Simulated_Universe_World_7 = DungeonList(
plane_id=100000104,
)
Simulated_Universe_World_8 = DungeonList(
id=55,
id=58,
name='Simulated_Universe_World_8',
cn='第八世界•模拟宇宙',
cht='第八世界•模擬宇宙',
@ -553,8 +583,18 @@ Simulated_Universe_World_8 = DungeonList(
es='Mundo 8',
plane_id=100000104,
)
Simulated_Universe_World_9 = DungeonList(
id=59,
name='Simulated_Universe_World_9',
cn='第九世界•模拟宇宙',
cht='第九世界•模擬宇宙',
en='Simulated Universe: World 9',
jp='第九世界・模擬宇宙',
es='Mundo 9',
plane_id=100000104,
)
Simulated_Universe_The_Swarm_Disaster = DungeonList(
id=56,
id=60,
name='Simulated_Universe_The_Swarm_Disaster',
cn='寰宇蝗灾',
cht='寰宇蝗災',
@ -564,7 +604,7 @@ Simulated_Universe_The_Swarm_Disaster = DungeonList(
plane_id=-1,
)
Simulated_Universe_Gold_and_Gears = DungeonList(
id=57,
id=61,
name='Simulated_Universe_Gold_and_Gears',
cn='黄金与机械',
cht='黃金與機械',
@ -574,7 +614,7 @@ Simulated_Universe_Gold_and_Gears = DungeonList(
plane_id=-1,
)
Memory_of_Chaos = DungeonList(
id=58,
id=62,
name='Memory_of_Chaos',
cn='混沌回忆',
cht='混沌回憶',
@ -584,7 +624,7 @@ Memory_of_Chaos = DungeonList(
plane_id=-1,
)
The_Voyage_of_Navis_Astriger = DungeonList(
id=59,
id=63,
name='The_Voyage_of_Navis_Astriger',
cn='天艟求仙迷航录',
cht='天艟求仙迷航錄',
@ -594,7 +634,7 @@ The_Voyage_of_Navis_Astriger = DungeonList(
plane_id=-1,
)
The_Last_Vestiges_of_Towering_Citadel = DungeonList(
id=60,
id=64,
name='The_Last_Vestiges_of_Towering_Citadel',
cn='永屹之城遗秘',
cht='永屹之城遺秘',

View File

@ -78,20 +78,20 @@ Stagnant_Shadow_Icicle = DungeonDetailed(
Stagnant_Shadow_Doom = DungeonDetailed(
id=9,
name='Stagnant_Shadow_Doom',
cn='角色晋阶材料:雷(卡芙卡 / 景元',
cht='角色晉階材料:雷(卡芙卡 / 景元',
en='Ascension: Lightning (Kafka / Jing Yuan)',
jp='キャラクター昇格素材:雷(カフカ / 景元',
es='Ascension: Rayo (Kafka / Jing Yuan)',
cn='角色晋阶材料:雷(卡芙卡 / 景元 / 黄泉',
cht='角色晉階材料:雷(卡芙卡 / 景元 / 黃泉',
en='Ascension: Lightning (Kafka / Jing Yuan / Acheron)',
jp='キャラクター昇格素材:雷(カフカ / 景元 / 黄泉',
es='Ascension: Rayo (Kafka / Jing Yuan / Acheron)',
)
Stagnant_Shadow_Puppetry = DungeonDetailed(
id=10,
name='Stagnant_Shadow_Puppetry',
cn='角色晋阶材料:虚数(丹恒•饮月 / 真理医生)',
cht='角色晉階材料:虛數(丹恆•飲月 / 真理醫生)',
en='Ascension: Imaginary (Dan Heng • Imbibitor Lunae / Dr. Ratio)',
jp='キャラクター昇格素材:虚数(丹恒・飲月 / Dr.レイシオ)',
es='Ascension: Imaginario (Dan Heng - Imbibitor Lunae / Dr. Ratio)',
cn='角色晋阶材料:虚数(丹恒•饮月 / 砂金 / 真理医生)',
cht='角色晉階材料:虛數(丹恆•飲月 / 砂金 / 真理醫生)',
en='Ascension: Imaginary (Dan Heng • Imbibitor Lunae / Aventurine / Dr. Ratio)',
jp='キャラクター昇格素材:虚数(丹恒・飲月 / アベンチュリン / Dr.レイシオ)',
es='Ascension: Imaginario (Dan Heng - Imbibitor Lunae / Aventurino / Dr. Ratio)',
)
Stagnant_Shadow_Abomination = DungeonDetailed(
id=11,
@ -147,3 +147,12 @@ Stagnant_Shadow_Roast = DungeonDetailed(
jp='キャラクター昇格素材:量子(花火)',
es='Ascension: Cuántico (Sparkle)',
)
Stagnant_Shadow_Ire = DungeonDetailed(
id=17,
name='Stagnant_Shadow_Ire',
cn='角色晋阶材料:火(加拉赫)',
cht='角色晉階材料:火(加拉赫)',
en='Ascension: Fire (Gallagher)',
jp='キャラクター昇格素材:炎(ギャラガー)',
es='Ascension: Fuego (Gallagher)',
)

View File

@ -7,10 +7,10 @@ ITEM_CONSUMABLE_SCROLL = ButtonWrapper(
name='ITEM_CONSUMABLE_SCROLL',
share=Button(
file='./assets/share/item/consumable_usage/ITEM_CONSUMABLE_SCROLL.png',
area=(837, 89, 843, 615),
search=(817, 69, 863, 635),
color=(118, 117, 121),
button=(837, 89, 843, 615),
area=(838, 90, 842, 614),
search=(818, 70, 862, 634),
color=(141, 141, 153),
button=(838, 90, 842, 614),
),
)
SIMPLE_PROTECTIVE_GEAR = ButtonWrapper(

View File

@ -1,5 +1,5 @@
from module.ocr.ocr import *
from module.ui.scroll import Scroll
from module.ui.scroll import AdaptiveScroll
from tasks.base.assets.assets_base_popup import POPUP_CONFIRM
from tasks.base.page import page_item
from tasks.daily.assets.assets_daily_synthesize_consumable import \
@ -54,7 +54,7 @@ class ConsumableUsageUI(ItemUI):
# Determine if there is a scroll bar. If there is a scroll bar,
# pull it down and check if the consumable to be used can be found
scroll = Scroll(area=ITEM_CONSUMABLE_SCROLL.button, color=(200, 200, 200), name=ITEM_CONSUMABLE_SCROLL.name)
scroll = AdaptiveScroll(area=ITEM_CONSUMABLE_SCROLL.button, name=ITEM_CONSUMABLE_SCROLL.name)
if scroll.appear(main=self):
if not scroll.at_top(main=self):
scroll.set_top(main=self)

View File

@ -5,13 +5,22 @@ from module.base.button import Button, ButtonWrapper
LOGIN_CONFIRM = ButtonWrapper(
name='LOGIN_CONFIRM',
share=Button(
file='./assets/share/login/LOGIN_CONFIRM.png',
area=(1188, 44, 1220, 74),
search=(1168, 24, 1240, 94),
color=(140, 124, 144),
button=(683, 327, 1143, 620),
),
share=[
Button(
file='./assets/share/login/LOGIN_CONFIRM.png',
area=(1188, 44, 1220, 74),
search=(1168, 24, 1240, 94),
color=(140, 124, 144),
button=(683, 327, 1143, 620),
),
Button(
file='./assets/share/login/LOGIN_CONFIRM.2.png',
area=(1109, 48, 1139, 73),
search=(1089, 28, 1159, 93),
color=(149, 145, 164),
button=(683, 327, 1143, 620),
),
],
)
LOGIN_LOADING = ButtonWrapper(
name='LOGIN_LOADING',

389
tasks/login/cloud.py Normal file
View File

@ -0,0 +1,389 @@
import re
from module.base.base import ModuleBase
from module.base.timer import Timer
from module.base.utils import area_offset, random_rectangle_vector_opted
from module.device.method.utils import AreaButton
from module.exception import GameNotRunningError, RequestHumanTakeover
from module.logger import logger
class XPath:
"""
xpath 元素元素可通过 uiautomator2 内的 weditor.exe 查找
"""
"""
登录界面元素
"""
# 帐号登录界面的进入游戏按钮,有这按钮说明帐号没登录
ACCOUNT_LOGIN = '//*[@text="进入游戏"]'
# 登录后的弹窗,获得免费时长
GET_REWARD = '//*[@text="点击空白区域关闭"]'
# 用户协议和隐私政策更新提示
# - 拒绝 - 接受
AGREEMENT_ACCEPT = '//*[@text="接受"]'
# 版本更新
# - 立即更新
UPDATE_CONFIRM = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/mUpgradeDialogOK"]'
# 新版本已下载完成
# - 开始安装
UPDATE_INSTALL = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/mBtnConfirm"]'
# 安卓系统弹窗
# 要更新此应用吗?- 取消 - 更新
# 已完成安装应用。-完成 -打开
ANDROID_UPDATE_CONFIRM = '//*[@resource-id="android:id/button1"]'
# 补丁资源已更新,重启游戏可活动更好的游玩体验
# - 下次再说 - 关闭游戏
POPUP_TITLE = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/titleTv"]'
POPUP_CONFIRM = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/confirmTv"]'
POPUP_CANCEL = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/cancelTv"]'
# 畅玩卡的剩余时间
REMAIN_SEASON_PASS = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tvCardStatus"]'
# 星云币时长0 分钟
REMAIN_PAID = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tvMiCoinDuration"]'
# 免费时长: 600 分钟
REMAIN_FREE = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tvRemainingFreeTime"]'
# 主界面的开始游戏按钮
START_GAME = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/btnLauncher"]'
# 排队剩余时间
QUEUE_REMAIN = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tvQueueInfoWaitTimeContent"]'
"""
游戏界面元素
"""
# 网络状态 简洁
FLOAT_STATE_SIMPLE = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tvSimpleNetStateMode"]'
# 网络状态 详细
FLOAT_STATE_DETAIL = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tv_ping_value"]'
"""
悬浮窗及侧边栏元素
"""
# 悬浮窗
FLOAT_WINDOW = '//*[@class="android.widget.ImageView"]'
# 弹出侧边栏的 节点信息
# 将这个区域向右偏移作为退出悬浮窗的按钮
FLOAT_DELAY = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tv_node_region"]'
# 弹出侧边栏的滚动区域
SCROLL_VIEW = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/innerScrollView"]'
# 画质选择 超高清
# 选中时selected=True
SETTING_BITRATE_UHD = '//*[@text="超高清"]'
# 网络状态 开关
SETTING_NET_STATE_TOGGLE = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/sw_net_state"]'
SETTING_NET_STATE_SIMPLE = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/mTvTitleOfSimpleMode"]'
SETTING_NET_STATE_DETAIL = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/mTvTitleOfDetailMode"]'
# 问题反馈
SETTING_PROBLEM = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tv_problem"]'
# 下载游戏
SETTING_DOWNLOAD = '//*[@resource-id="com.miHoYo.cloudgames.hkrpg:id/tv_downloadGame"]'
class LoginAndroidCloud(ModuleBase):
def _cloud_start(self, skip_first=False):
"""
Pages:
out: START_GAME
"""
logger.hr('Cloud start')
update_checker = Timer(2)
while 1:
if skip_first:
skip_first = False
else:
self.device.dump_hierarchy()
# End
if self.appear(XPath.START_GAME):
logger.info('Login to cloud main page')
break
if self.appear(XPath.ACCOUNT_LOGIN):
logger.critical('Account not login, you must have login once before running')
raise RequestHumanTakeover
if update_checker.started() and update_checker.reached():
if not self.device.app_is_running():
logger.error('Detected hot fixes from game server, game died')
raise GameNotRunningError('Game not running')
update_checker.clear()
# Click
if self.appear_then_click(XPath.GET_REWARD):
continue
if self.appear_then_click(XPath.POPUP_CONFIRM):
update_checker.start()
continue
# Update
if self.appear_then_click(XPath.AGREEMENT_ACCEPT):
continue
if self.appear_then_click(XPath.UPDATE_CONFIRM):
continue
button = self.xpath(XPath.UPDATE_INSTALL)
if button.text == '开始安装':
if self.appear_then_click(button):
continue
button = self.xpath(XPath.ANDROID_UPDATE_CONFIRM)
if button.text in ['更新', '打开']:
if self.appear_then_click(button):
continue
def _cloud_get_remain(self):
"""
Pages:
in: START_GAME
"""
regex = re.compile(r'(\d+)')
text = self.xpath(XPath.REMAIN_SEASON_PASS).text
logger.info(f'Remain season pass: {text}')
if res := regex.search(text):
season_pass = int(res.group(1))
else:
season_pass = 0
text = self.xpath(XPath.REMAIN_PAID).text
logger.info(f'Remain paid: {text}')
if res := regex.search(text):
paid = int(res.group(1))
else:
paid = 0
text = self.xpath(XPath.REMAIN_FREE).text
logger.info(f'Remain free: {text}')
if res := regex.search(text):
free = int(res.group(1))
else:
free = 0
logger.info(f'Cloud remain: season pass {season_pass} days, {paid} min paid, {free} min free')
with self.config.multi_set():
self.config.stored.CloudRemainSeasonPass = season_pass
self.config.stored.CloudRemainPaid = paid
self.config.stored.CloudRemainFree = free
def _cloud_enter(self, skip_first=False):
"""
Pages:
in: START_GAME
out: page_main
"""
logger.hr('Cloud enter')
while 1:
if skip_first:
skip_first = False
else:
self.device.dump_hierarchy()
# End
button = self.xpath(XPath.FLOAT_WINDOW)
if self.appear(button):
# Confirm float window size
width, height = button.size
if (width < 120 and height < 120) and (width / height < 0.6 or height / width < 0.6):
logger.info('Cloud game entered')
break
# Queue daemon
button = self.xpath(XPath.QUEUE_REMAIN)
if self.appear(button):
remain = button.text
logger.info(f'Queue remain: {remain}')
self.device.stuck_record_clear()
# Click
if self.appear_then_click(XPath.GET_REWARD):
continue
if self.appear_then_click(XPath.START_GAME):
continue
if self.appear(XPath.POPUP_CONFIRM, interval=5):
title = self.xpath(XPath.POPUP_TITLE).text
logger.info(f'Popup: {title}')
# 计费提示
# 本次游戏将使用畅玩卡无限畅玩
# - 进入游戏(9s) - 退出游戏
if title == '计费提示':
self.device.click(self.xpath(XPath.POPUP_CONFIRM))
continue
# 是否使用星云币时长进入游戏
# 使用后可优先排队进入游戏,本次游戏仅可使用星云币时长,无法消耗免费时长
# - 确认使用 - 暂不使用
if title == '是否使用星云币时长进入游戏':
self.device.click(self.xpath(XPath.POPUP_CONFIRM))
continue
# 连接中断
# 因为您长时间未操作游戏,已中断连接,错误码: -1022
# - 退出游戏
if title == '连接中断':
self.device.click(self.xpath(XPath.POPUP_CONFIRM))
continue
# Disable net state display
if self._cloud_net_state_appear():
self._cloud_setting_disable_net_state()
# Login to game
from tasks.login.login import Login
Login(config=self.config, device=self.device).handle_app_login()
def _cloud_setting_enter(self, skip_first=True):
while 1:
if skip_first:
skip_first = False
else:
self.device.dump_hierarchy()
if self.appear(XPath.FLOAT_DELAY):
break
if self.appear_then_click(XPath.FLOAT_WINDOW, interval=3):
continue
def _cloud_setting_exit(self, skip_first=True):
while 1:
if skip_first:
skip_first = False
else:
self.device.dump_hierarchy()
if self.appear(XPath.FLOAT_WINDOW):
break
if self.appear(XPath.FLOAT_DELAY, interval=3):
area = self.xpath(XPath.FLOAT_DELAY).area
area = area_offset(area, offset=(150, 0))
button = AreaButton(area=area, name='CLOUD_SETTING_EXIT')
self.device.click(button)
continue
def _cloud_setting_disable_net_state(self, skip_first=True):
"""
Pages:
in: page_main
out: page_main
"""
self._cloud_setting_enter(skip_first=skip_first)
skip_first = True
while 1:
if skip_first:
skip_first = False
else:
self.device.dump_hierarchy()
button = self.xpath(XPath.SETTING_BITRATE_UHD)
if self.appear(button, interval=3):
if not button.selected:
logger.info('Set bitrate to UHD')
self.device.click(button)
continue
if self.appear(XPath.SETTING_NET_STATE_TOGGLE):
if self.appear(XPath.SETTING_NET_STATE_SIMPLE) or self.appear(XPath.SETTING_NET_STATE_DETAIL):
logger.info('Set net state to disabled')
self.appear_then_click(XPath.SETTING_NET_STATE_TOGGLE, interval=3)
continue
else:
logger.info('Net state display disabled')
break
# Scroll down
if not self.appear(XPath.SETTING_PROBLEM):
area = self.xpath(XPath.SCROLL_VIEW).area
# An area safe to swipe
area = (area[0], area[1], area[0] + 25, area[3])
p1, p2 = random_rectangle_vector_opted(
(0, -450), box=area, random_range=(-10, -30, 10, 30), padding=2)
self.device.swipe(p1, p2, name='SETTING_SCROLL')
continue
self._cloud_setting_exit(skip_first=True)
def _cloud_net_state_appear(self):
"""
Returns:
bool: True if net state display is enabled
"""
if self.appear(XPath.FLOAT_STATE_SIMPLE):
logger.attr('Net state', 'FLOAT_STATE_SIMPLE')
return True
if self.appear(XPath.FLOAT_STATE_DETAIL):
logger.attr('Net state', 'FLOAT_STATE_DETAIL')
return True
logger.attr('Net state', None)
return False
def cloud_ensure_ingame(self):
"""
Pages:
in: Any
out: page_main
"""
logger.hr('Cloud ensure ingame', level=1)
with self.config.multi_set():
if self.config.Emulator_GameClient != 'cloud_android':
self.config.Emulator_GameClient = 'cloud_android'
if self.config.Emulator_PackageName != 'CN-Official':
self.config.Emulator_PackageName = 'CN-Official'
if self.config.Optimization_WhenTaskQueueEmpty != 'close_game':
self.config.Optimization_WhenTaskQueueEmpty = 'close_game'
for _ in range(3):
if self.device.app_is_running():
logger.info('Cloud game is already running')
self.device.dump_hierarchy()
if self.appear(XPath.START_GAME):
logger.info('Cloud game is in main page')
self._cloud_get_remain()
self._cloud_enter()
return True
elif self.appear(XPath.FLOAT_WINDOW):
logger.info('Cloud game is in game')
return True
elif self.appear(XPath.FLOAT_DELAY):
logger.info('Cloud game is in game with float window expanded')
self._cloud_setting_exit()
return True
elif self.appear(XPath.POPUP_CONFIRM):
logger.info('Cloud game have a popup')
self._cloud_enter()
return True
else:
try:
self._cloud_start()
except GameNotRunningError:
continue
self._cloud_get_remain()
self._cloud_enter()
return True
else:
logger.info('Cloud game is not running')
self.device.app_start()
try:
self._cloud_start()
except GameNotRunningError:
continue
self._cloud_get_remain()
self._cloud_enter()
return True
logger.error('Failed to enter cloud game after 3 trials')
return False
def cloud_keep_alive(self):
"""
Randomly do something to prevent being kicked
WARNING:
this may cause extra fee
"""
logger.hr('cloud_keep_alive', level=2)
while 1:
self.device.sleep((45, 60))
logger.info('cloud_keep_alive')
self._cloud_setting_enter(skip_first=False)
self._cloud_setting_exit(skip_first=True)
if __name__ == '__main__':
self = LoginAndroidCloud('src')
self.cloud_ensure_ingame()
self.cloud_keep_alive()

View File

@ -3,10 +3,11 @@ from module.exception import GameNotRunningError
from module.logger import logger
from tasks.base.page import page_main
from tasks.base.ui import UI
from tasks.login.assets.assets_login import LOGIN_CONFIRM, USER_AGREEMENT_ACCEPT, LOGIN_LOADING
from tasks.login.assets.assets_login import LOGIN_CONFIRM, LOGIN_LOADING, USER_AGREEMENT_ACCEPT
from tasks.login.cloud import LoginAndroidCloud
class Login(UI):
class Login(UI, LoginAndroidCloud):
def _handle_app_login(self):
"""
Pages:
@ -86,12 +87,33 @@ class Login(UI):
def app_start(self):
logger.hr('App start')
self.device.app_start()
if self.config.is_cloud_game:
self.cloud_ensure_ingame()
else:
self.device.app_start()
self.handle_app_login()
def app_restart(self):
logger.hr('App restart')
self.device.app_stop()
self.device.app_start()
if self.config.is_cloud_game:
self.cloud_ensure_ingame()
else:
self.device.app_start()
self.handle_app_login()
self.config.task_delay(server_update=True)
def cloud_start(self):
if not self.config.is_cloud_game:
return
logger.hr('Cloud start')
self.cloud_ensure_ingame()
self.handle_app_login()
def cloud_stop(self):
if not self.config.is_cloud_game:
return
logger.hr('Cloud stop')
self.app_stop()

View File

@ -53,53 +53,63 @@ RUN_BUTTON = ButtonWrapper(
button=(1147, 591, 1195, 639),
),
)
TECHNIQUE_POINT_0 = ButtonWrapper(
name='TECHNIQUE_POINT_0',
share=Button(
file='./assets/share/map/control/TECHNIQUE_POINT_0.png',
area=(884, 597, 891, 604),
search=(831, 589, 944, 612),
color=(56, 56, 56),
button=(884, 597, 891, 604),
),
)
TECHNIQUE_POINT_1 = ButtonWrapper(
name='TECHNIQUE_POINT_1',
share=Button(
file='./assets/share/map/control/TECHNIQUE_POINT_1.png',
area=(881, 594, 894, 607),
search=(861, 574, 914, 627),
color=(149, 141, 186),
button=(881, 594, 894, 607),
area=(884, 597, 891, 604),
search=(831, 589, 944, 612),
color=(222, 213, 253),
button=(884, 597, 891, 604),
),
)
TECHNIQUE_POINT_2 = ButtonWrapper(
name='TECHNIQUE_POINT_2',
share=Button(
file='./assets/share/map/control/TECHNIQUE_POINT_2.png',
area=(889, 578, 903, 592),
search=(869, 558, 923, 612),
color=(139, 132, 174),
button=(889, 578, 903, 592),
area=(892, 581, 900, 589),
search=(872, 561, 920, 609),
color=(213, 203, 249),
button=(892, 581, 900, 589),
),
)
TECHNIQUE_POINT_3 = ButtonWrapper(
name='TECHNIQUE_POINT_3',
share=Button(
file='./assets/share/map/control/TECHNIQUE_POINT_3.png',
area=(902, 566, 916, 580),
search=(882, 546, 936, 600),
color=(138, 130, 173),
button=(902, 566, 916, 580),
area=(905, 569, 913, 577),
search=(885, 549, 933, 597),
color=(207, 195, 249),
button=(905, 569, 913, 577),
),
)
TECHNIQUE_POINT_4 = ButtonWrapper(
name='TECHNIQUE_POINT_4',
share=Button(
file='./assets/share/map/control/TECHNIQUE_POINT_4.png',
area=(918, 559, 932, 573),
search=(898, 539, 952, 593),
color=(138, 130, 173),
button=(918, 559, 932, 573),
area=(921, 562, 929, 570),
search=(901, 542, 949, 590),
color=(210, 198, 248),
button=(921, 562, 929, 570),
),
)
TECHNIQUE_POINT_5 = ButtonWrapper(
name='TECHNIQUE_POINT_5',
share=Button(
file='./assets/share/map/control/TECHNIQUE_POINT_5.png',
area=(935, 559, 948, 573),
search=(915, 539, 968, 593),
color=(71, 72, 77),
button=(935, 559, 948, 573),
area=(938, 562, 945, 570),
search=(918, 542, 965, 590),
color=(215, 203, 250),
button=(938, 562, 945, 570),
),
)

View File

@ -5,6 +5,7 @@ import cv2
import numpy as np
from module.base.timer import Timer
from module.base.utils import area_offset
from module.device.method.maatouch import MaatouchBuilder
from module.device.method.minitouch import CommandBuilder, insert_swipe, random_normal_distribution
from module.exception import ScriptError
@ -195,18 +196,35 @@ class MapControlJoystick(UI):
def map_get_technique_points(self):
"""
Returns:
int: 0 to 5.
int: 0 to 5
"""
points = [
self.image_color_count(button, color=(255, 255, 255), threshold=221, count=20)
for button in [
TECHNIQUE_POINT_1,
TECHNIQUE_POINT_2,
TECHNIQUE_POINT_3,
TECHNIQUE_POINT_4,
TECHNIQUE_POINT_5,
]
]
confirm = Timer(3, count=0).start()
while 1:
matched = TECHNIQUE_POINT_1.match_template(self.device.image)
if matched:
matched_button = TECHNIQUE_POINT_1
break
matched = TECHNIQUE_POINT_0.match_template(self.device.image)
if matched:
matched_button = TECHNIQUE_POINT_0
break
if confirm.reached():
logger.warning('Can not match technique points.')
return 0
else:
self.device.screenshot()
points = []
for button in [
TECHNIQUE_POINT_1,
TECHNIQUE_POINT_2,
TECHNIQUE_POINT_3,
TECHNIQUE_POINT_4,
TECHNIQUE_POINT_5,
]:
if matched_button is not None:
button.load_offset(matched_button)
points.append(self.image_color_count(area_offset(button.area, button.button_offset), color=(255, 255, 255),
threshold=221, count=20))
count = sum(points)
logger.attr('TechniquePoints', count)
return count

View File

@ -465,3 +465,25 @@ Penacony_TheReverieDreamscape = MapPlane(
world_id=3,
plane_id=2031101,
)
Penacony_DewlightPavilion = MapPlane(
id=43,
name='Penacony_DewlightPavilion',
cn='朝露公馆',
cht='朝露公館',
en='Dewlight Pavilion',
jp='朝露の館',
es='Pabellón del Rocío Matutino',
world_id=3,
plane_id=2032201,
)
Penacony_ClockStudiosThemePark = MapPlane(
id=44,
name='Penacony_ClockStudiosThemePark',
cn='克劳克影视乐园',
cht='克勞克影視樂園',
en='Clock Studios Theme Park',
jp='クラークフィルムランド',
es='Parque temático de los Estudios Reloj',
world_id=3,
plane_id=2032101,
)

View File

@ -86,13 +86,22 @@ CURIO_OBTAINED = ButtonWrapper(
color=(125, 126, 134),
button=(643, 86, 708, 117),
),
en=Button(
file='./assets/en/rogue/ui/CURIO_OBTAINED.png',
area=(511, 88, 600, 116),
search=(491, 68, 620, 136),
color=(93, 95, 102),
button=(511, 88, 600, 116),
),
en=[
Button(
file='./assets/en/rogue/ui/CURIO_OBTAINED.png',
area=(511, 88, 600, 116),
search=(491, 68, 620, 136),
color=(93, 95, 102),
button=(511, 88, 600, 116),
),
Button(
file='./assets/en/rogue/ui/CURIO_OBTAINED.2.png',
area=(526, 46, 605, 71),
search=(506, 26, 625, 91),
color=(103, 91, 66),
button=(526, 46, 605, 71),
),
],
)
FLAG_UNRECORD = ButtonWrapper(
name='FLAG_UNRECORD',

View File

@ -92,10 +92,10 @@ class OcrRogueEventOption(OcrRogueEvent):
(KEYWORDS_ROGUE_EVENT_OPTION.Deposit_2_Cosmic_Fragments, '存入\d+.*'),
(KEYWORDS_ROGUE_EVENT_OPTION.Withdraw_2_Cosmic_Fragments, '取出\d+.*'),
(KEYWORDS_ROGUE_EVENT_OPTION.Record_of_the_Aeon_of_1, '^关于.*'),
(KEYWORDS_ROGUE_EVENT_OPTION.Wait_for_them, '^等待.*'),
(KEYWORDS_ROGUE_EVENT_OPTION.Wait_for_THEM, '^等待.*'),
(KEYWORDS_ROGUE_EVENT_OPTION.Choose_number_two_It_snores_like_Andatur_Zazzalo, '.*二号.*安达.*'),
(KEYWORDS_ROGUE_EVENT_OPTION.Choose_number_three_Its_teeth_are_rusted, '.*三号.*牙齿.*'),
(KEYWORDS_ROGUE_EVENT_OPTION.Believe_in_them_with_pure_devotion, '虔诚信仰'),
(KEYWORDS_ROGUE_EVENT_OPTION.Believe_in_THEM_with_pure_devotion, '虔诚信仰'),
],
'en': [
(KEYWORDS_ROGUE_EVENT_OPTION.Deposit_2_Cosmic_Fragments, 'Deposit \d+.*'),

View File

@ -41,7 +41,7 @@ STRATEGY_COMMON = {
]
],
KEYWORDS_ROGUE_EVENT_TITLE.Statue: [
KEYWORDS_ROGUE_EVENT_OPTION.Believe_in_them_with_pure_devotion,
KEYWORDS_ROGUE_EVENT_OPTION.Believe_in_THEM_with_pure_devotion,
KEYWORDS_ROGUE_EVENT_OPTION.Discard_the_statue_Be_decisive
],
KEYWORDS_ROGUE_EVENT_TITLE.Unending_Darkness: [
@ -82,7 +82,7 @@ STRATEGY_COMMON = {
],
KEYWORDS_ROGUE_EVENT_TITLE.The_Cremators: [
KEYWORDS_ROGUE_EVENT_OPTION.Bear_ten_carats_of_trash,
KEYWORDS_ROGUE_EVENT_OPTION.Give_everything_to_them,
KEYWORDS_ROGUE_EVENT_OPTION.Give_everything_to_THEM,
],
KEYWORDS_ROGUE_EVENT_TITLE.Pixel_World: [
KEYWORDS_ROGUE_EVENT_OPTION.Jump_onto_the_bricks_to_the_right,
@ -145,7 +145,7 @@ STRATEGY_COMBAT = {
],
KEYWORDS_ROGUE_EVENT_TITLE.Insect_Nest: [
KEYWORDS_ROGUE_EVENT_OPTION.Go_deeper_into_the_insect_nest,
KEYWORDS_ROGUE_EVENT_OPTION.Wait_for_them,
KEYWORDS_ROGUE_EVENT_OPTION.Wait_for_THEM,
KEYWORDS_ROGUE_EVENT_OPTION.Stop_at_the_entrance_of_the_nest,
KEYWORDS_ROGUE_EVENT_OPTION.Hug_it
],
@ -174,7 +174,7 @@ STRATEGY_OCCURRENCE = {
KEYWORDS_ROGUE_EVENT_TITLE.Insect_Nest: [
KEYWORDS_ROGUE_EVENT_OPTION.Go_deeper_into_the_insect_nest,
KEYWORDS_ROGUE_EVENT_OPTION.Hug_it,
KEYWORDS_ROGUE_EVENT_OPTION.Wait_for_them,
KEYWORDS_ROGUE_EVENT_OPTION.Wait_for_THEM,
KEYWORDS_ROGUE_EVENT_OPTION.Stop_at_the_entrance_of_the_nest
]
}

View File

@ -486,7 +486,7 @@ Fissured_Cuckoo_Clock = RogueCurio(
cn='分裂咕咕钟',
cht='分裂咕咕鐘',
en='Fissured Cuckoo Clock',
jp='機械式鳩時計',
jp='分裂鳩時計',
es='Reloj de cuco agrietado',
)
Typical_Genius_Society_Gossip = RogueCurio(

View File

@ -237,12 +237,12 @@ Smash_this_television = RogueEventOption(
jp='そのテレビを破壊する!',
es='¡Destruye este televisor!',
)
Give_everything_to_them = RogueEventOption(
Give_everything_to_THEM = RogueEventOption(
id=27,
name='Give_everything_to_them',
name='Give_everything_to_THEM',
cn='将一切奉献给「祂」。',
cht='將一切奉獻給「祂」。',
en='Give everything to "them."',
en='Give everything to "THEM."',
jp='すべてを「其」に捧げる',
es='Dedícalo todo a "ellos".',
)
@ -525,12 +525,12 @@ Discard_the_statue_Be_decisive = RogueEventOption(
jp='彫像を捨てよう!きっぱりと!',
es='¡Suelta la estatua! Con decisión.',
)
Believe_in_them_with_pure_devotion = RogueEventOption(
Believe_in_THEM_with_pure_devotion = RogueEventOption(
id=59,
name='Believe_in_them_with_pure_devotion',
name='Believe_in_THEM_with_pure_devotion',
cn='对「祂」虔诚信仰,身心无垢。',
cht='對「祂」虔誠信仰,身心無垢。',
en='Believe in "them" with pure devotion.',
en='Believe in "THEM" with pure devotion.',
jp='「其」に対する敬虔な信仰は、無垢である',
es='Cree en "ellos" con gran devoción.',
)
@ -570,12 +570,12 @@ Hug_it = RogueEventOption(
jp='抱擁する',
es='Abrázalo.',
)
Wait_for_them = RogueEventOption(
Wait_for_THEM = RogueEventOption(
id=64,
name='Wait_for_them',
name='Wait_for_THEM',
cn='等待「祂」。',
cht='等待「祂」。',
en='Wait for "them."',
en='Wait for "THEM."',
jp='「其」を待つ',
es='Espéralos.',
)
@ -1803,12 +1803,12 @@ Pretend_to_not_notice_that_something_was_off = RogueEventOption(
jp='違和感を覚えていないフリをする',
es='Finge que no te das cuenta de que algo anda mal.',
)
They_re_here = RogueEventOption(
THEY_re_here = RogueEventOption(
id=201,
name='They_re_here',
name='THEY_re_here',
cn='祂出现了!',
cht='祂出現了!',
en="They're here!",
en="THEY're here!",
jp='其が現れた!',
es='¡Está aquí!',
)

View File

@ -943,22 +943,22 @@ Ka_ching_IPC_Banking_Part_2 = RogueEventTitle(
es='El banco de la Corporación II',
option_ids=[142, 277, 278, 279, 280, 281],
)
Loneliness_Costic_Beauty_Bugs_Simulated_Universe_Part_1 = RogueEventTitle(
Loneliness_Cosmic_Beauty_Bugs_Simulated_Universe_Part_1 = RogueEventTitle(
id=95,
name='Loneliness_Costic_Beauty_Bugs_Simulated_Universe_Part_1',
name='Loneliness_Cosmic_Beauty_Bugs_Simulated_Universe_Part_1',
cn='孤独,太空美虫,模拟宇宙(其一)',
cht='孤獨,太空美蟲,模擬宇宙(其一)',
en='Loneliness, Costic Beauty Bugs, Simulated Universe (Part 1)',
en='Loneliness, Cosmic Beauty Bugs, Simulated Universe (Part 1)',
jp='孤独、宇宙の美虫、模擬宇宙1',
es='Soledad, gusanos espaciales y el Universo Simulado I',
option_ids=[77, 282, 283, 284, 285, 286, 287, 288, 289],
)
Loneliness_Costic_Beauty_Bugs_Simulated_Universe_Part_2 = RogueEventTitle(
Loneliness_Cosmic_Beauty_Bugs_Simulated_Universe_Part_2 = RogueEventTitle(
id=96,
name='Loneliness_Costic_Beauty_Bugs_Simulated_Universe_Part_2',
name='Loneliness_Cosmic_Beauty_Bugs_Simulated_Universe_Part_2',
cn='孤独,太空美虫,模拟宇宙(其二)',
cht='孤獨,太空美蟲,模擬宇宙(其二)',
en='Loneliness, Costic Beauty Bugs, Simulated Universe (Part 2)',
en='Loneliness, Cosmic Beauty Bugs, Simulated Universe (Part 2)',
jp='孤独、宇宙の美虫、模擬宇宙2',
es='Soledad, gusanos espaciales y el Universo Simulado II',
option_ids=[77, 283, 284, 285, 286, 287, 288, 289],
@ -1120,7 +1120,7 @@ Insights_from_the_Universal_Dancer = RogueEventTitle(
cht='寰宇舞者的啟示',
en='Insights from the Universal Dancer',
jp='世界の踊り手の啓示',
es='Reflexiones del bailarín universal',
es='Reflexiones de la bailarina universal',
option_ids=[311, 312],
)
Pixel_World_Hidden_Stage = RogueEventTitle(

View File

@ -300,6 +300,11 @@ class RouteBase(RouteBase_, RogueExit, RogueEvent, RogueReward):
"""
logger.hr('Domain single exit', level=1)
waypoints = ensure_waypoints(waypoints)
for point in waypoints:
if 'item' not in point.expected_enroute:
point.expected_enroute.append('item')
end_point = waypoints[-1]
end_point.min_speed = 'run'
end_point.interact_radius = 5

View File

@ -165,7 +165,13 @@ class RouteLoader(RogueUI, MinimapWrapper, RouteLoader_, CharacterSwitch):
# return True
# Before Combat_Luofu_Cloudford_F1_X281Y873
if route.name == [
if route.name in [
'Occurrence_Jarilo_BackwaterPass_F1_X553Y643',
'Combat_Jarilo_GreatMine_F1_X545Y513',
'Combat_Herta_SupplyZone_F2_X45Y369',
] and similarity > 0.20:
return True
if route.name in [
'Combat_Herta_StorageZone_F1_X273Y92',
'Occurrence_Herta_StorageZone_F1_X273Y93',
'Occurrence_Jarilo_RivetTown_F1_X289Y97',
@ -173,12 +179,20 @@ class RouteLoader(RogueUI, MinimapWrapper, RouteLoader_, CharacterSwitch):
'Occurrence_Luofu_ArtisanshipCommission_F1_X169Y491',
] and similarity > 0.1:
return True
# Luofu_Cloudford_F1_X283Y865 and its equivalents
# INFO 21:27:00.816 │ Best 3 nearby predictions: [
# ('Combat_Herta_SupplyZone_F2_X45Y369', 0.184, (41.0, 369.1)),
# ('Combat_Luofu_Cloudford_F1_X281Y873', 0.149, (281.8, 869.6)),
# ('Combat_Luofu_Cloudford_F1_X283Y865', 0.149, (281.8, 869.6))]
if route.name in ['Combat_Luofu_Cloudford_F1_X283Y865', 'Occurrence_Luofu_Cloudford_F1_X283Y865'] \
and similarity > 0.05:
# INFO | Best 3 predictions: [('Combat_Herta_SupplyZone_F2_X45Y369', 0.149, (43.4, 369.3)),
# ('Combat_Luofu_Cloudford_F1_X241Y947', 0.138, (198.6, 956.8)),
# ('Combat_Luofu_Cloudford_F1Rogue_X59Y405', 0.134, (81.0, 397.4))]
if route.name in [
'Combat_Luofu_Cloudford_F1_X283Y865',
'Occurrence_Luofu_Cloudford_F1_X283Y865',
'Combat_Luofu_Cloudford_F1_X281Y873',
'Occurrence_Luofu_Cloudford_F1_X281Y873',
] and similarity > 0.05:
return True
return False