mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-15 22:19:18 +00:00
commit
ca7202d075
BIN
assets/share/item/synthesize/SYNTHESIZE_INSUFFICIENT.png
Normal file
BIN
assets/share/item/synthesize/SYNTHESIZE_INSUFFICIENT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
@ -123,6 +123,18 @@ def has_cached_property(obj, name):
|
|||||||
return name in obj.__dict__
|
return name in obj.__dict__
|
||||||
|
|
||||||
|
|
||||||
|
def set_cached_property(obj, name, value):
|
||||||
|
"""
|
||||||
|
Set a cached property.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
obj:
|
||||||
|
name (str):
|
||||||
|
value:
|
||||||
|
"""
|
||||||
|
obj.__dict__[name] = value
|
||||||
|
|
||||||
|
|
||||||
def function_drop(rate=0.5, default=None):
|
def function_drop(rate=0.5, default=None):
|
||||||
"""
|
"""
|
||||||
Drop function calls to simulate random emulator stuck, for testing purpose.
|
Drop function calls to simulate random emulator stuck, for testing purpose.
|
||||||
|
@ -1016,7 +1016,24 @@ class Connection(ConnectionAttr):
|
|||||||
# Set server
|
# Set server
|
||||||
# logger.info('Server changed, release resources')
|
# logger.info('Server changed, release resources')
|
||||||
# set_server(self.package)
|
# set_server(self.package)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
|
if self.config.is_cloud_game:
|
||||||
|
packages = [p for p in packages if p in server_.VALID_CLOUD_PACKAGE]
|
||||||
|
if len(packages) == 1:
|
||||||
|
logger.info('Auto package detection found only one package, using it')
|
||||||
|
self.package = packages[0]
|
||||||
|
if set_config:
|
||||||
|
self.config.Emulator_PackageName = server_.to_server(self.package)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
packages = [p for p in packages if p in server_.VALID_PACKAGE]
|
||||||
|
if len(packages) == 1:
|
||||||
|
logger.info('Auto package detection found only one package, using it')
|
||||||
|
self.package = packages[0]
|
||||||
|
if set_config:
|
||||||
|
self.config.Emulator_PackageName = server_.to_server(self.package)
|
||||||
|
return
|
||||||
logger.critical(
|
logger.critical(
|
||||||
f'Multiple Star Rail packages found, auto package detection cannot decide which to choose, '
|
f'Multiple Star Rail packages found, auto package detection cannot decide which to choose, '
|
||||||
'please copy one of the available devices listed above to Alas.Emulator.PackageName')
|
'please copy one of the available devices listed above to Alas.Emulator.PackageName')
|
||||||
|
@ -413,10 +413,16 @@ def put_arg_planner(kwargs: T_Output_Kwargs) -> Output | None:
|
|||||||
if isinstance(total, dict):
|
if isinstance(total, dict):
|
||||||
total = tuple(total.values())
|
total = tuple(total.values())
|
||||||
|
|
||||||
|
if eta:
|
||||||
row = put_scope(f"arg_stored-stored-value-{name}", [
|
row = put_scope(f"arg_stored-stored-value-{name}", [
|
||||||
put_text(f"{progress:.2f}%{eta}").style("--dashboard-bold--"),
|
put_text(f"{progress:.2f}%{eta}").style("--dashboard-bold--"),
|
||||||
put_text(f"{value} / {total}").style("--dashboard-time--"),
|
put_text(f"{value} / {total}").style("--dashboard-time--"),
|
||||||
])
|
])
|
||||||
|
else:
|
||||||
|
row = put_scope(f"arg_stored-stored-value-{name}", [
|
||||||
|
put_text(f"{progress:.2f}%").style("--dashboard-value--"),
|
||||||
|
put_text(f"{value} / {total}").style("--dashboard-time--"),
|
||||||
|
])
|
||||||
|
|
||||||
return put_scope(
|
return put_scope(
|
||||||
f"arg_container-planner-{name}",
|
f"arg_container-planner-{name}",
|
||||||
|
@ -74,6 +74,11 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
|||||||
delay = min(self.dispatched.values())
|
delay = min(self.dispatched.values())
|
||||||
logger.info(f'Delay assignment check to {str(delay)}')
|
logger.info(f'Delay assignment check to {str(delay)}')
|
||||||
self.config.task_delay(target=delay)
|
self.config.task_delay(target=delay)
|
||||||
|
# Align server update
|
||||||
|
update = get_server_next_update(self.config.Scheduler_ServerUpdate)
|
||||||
|
if update - delay < timedelta(hours=4):
|
||||||
|
logger.info('Approaching next day, delay to server update instead')
|
||||||
|
self.config.task_delay(target=update)
|
||||||
else:
|
else:
|
||||||
# ValueError: min() arg is an empty sequence
|
# ValueError: min() arg is an empty sequence
|
||||||
logger.error('Empty dispatched list, delay 2 hours instead')
|
logger.error('Empty dispatched list, delay 2 hours instead')
|
||||||
|
@ -253,7 +253,13 @@ class CombatObtain(PlannerMixin):
|
|||||||
ItemAmount: Arrow_of_the_Beast_Hunter, 85
|
ItemAmount: Arrow_of_the_Beast_Hunter, 85
|
||||||
"""
|
"""
|
||||||
self.planner.load_obtained_amount(items)
|
self.planner.load_obtained_amount(items)
|
||||||
|
with self.config.multi_set():
|
||||||
self.planner_write()
|
self.planner_write()
|
||||||
|
# Sync to dashboard
|
||||||
|
for item in items:
|
||||||
|
if item.item.name == 'Credit':
|
||||||
|
self.config.stored.Credit.value = item.value
|
||||||
|
|
||||||
return items
|
return items
|
||||||
|
|
||||||
def obtained_is_full(self, dungeon: DungeonList | None, wave_done=0, obtain_get=True) -> bool:
|
def obtained_is_full(self, dungeon: DungeonList | None, wave_done=0, obtain_get=True) -> bool:
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from module.base.decorator import set_cached_property
|
||||||
from module.base.utils import area_offset
|
from module.base.utils import area_offset
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from tasks.battle_pass.keywords import KEYWORDS_BATTLE_PASS_QUEST
|
from tasks.battle_pass.keywords import KEYWORDS_BATTLE_PASS_QUEST
|
||||||
@ -191,6 +192,7 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
|||||||
def run(self):
|
def run(self):
|
||||||
self.config.update_battle_pass_quests()
|
self.config.update_battle_pass_quests()
|
||||||
self.config.update_daily_quests()
|
self.config.update_daily_quests()
|
||||||
|
self.check_synthesize()
|
||||||
self.called_daily_support = False
|
self.called_daily_support = False
|
||||||
self.achieved_daily_quest = False
|
self.achieved_daily_quest = False
|
||||||
self.achieved_weekly_quest = False
|
self.achieved_weekly_quest = False
|
||||||
@ -309,6 +311,7 @@ class Dungeon(DungeonStamina, DungeonEvent, Combat):
|
|||||||
def check_synthesize(self):
|
def check_synthesize(self):
|
||||||
logger.info('Check synthesize')
|
logger.info('Check synthesize')
|
||||||
synthesize = Synthesize(config=self.config, device=self.device, task=self.config.task.command)
|
synthesize = Synthesize(config=self.config, device=self.device, task=self.config.task.command)
|
||||||
|
set_cached_property(synthesize, 'planner', self.planner)
|
||||||
if synthesize.synthesize_needed():
|
if synthesize.synthesize_needed():
|
||||||
synthesize.synthesize_planner()
|
synthesize.synthesize_planner()
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ class WeeklyDungeon(Dungeon):
|
|||||||
planner = self.planner.get_weekly()
|
planner = self.planner.get_weekly()
|
||||||
if planner is not None:
|
if planner is not None:
|
||||||
dungeon = planner
|
dungeon = planner
|
||||||
|
self.is_doing_planner = True
|
||||||
logger.attr('DungeonWeekly', dungeon)
|
logger.attr('DungeonWeekly', dungeon)
|
||||||
|
|
||||||
# UI switches
|
# UI switches
|
||||||
@ -81,6 +82,7 @@ class WeeklyDungeon(Dungeon):
|
|||||||
|
|
||||||
# Combat
|
# Combat
|
||||||
count = self.dungeon_run(dungeon, wave_limit=min(remain, 3))
|
count = self.dungeon_run(dungeon, wave_limit=min(remain, 3))
|
||||||
|
self.is_doing_planner = False
|
||||||
|
|
||||||
logger.attr('achieved_daily_quest', self.achieved_daily_quest)
|
logger.attr('achieved_daily_quest', self.achieved_daily_quest)
|
||||||
logger.attr('achieved_weekly_quest', self.achieved_weekly_quest)
|
logger.attr('achieved_weekly_quest', self.achieved_weekly_quest)
|
||||||
|
@ -63,6 +63,16 @@ SYNTHESIZE_CONFIRM = ButtonWrapper(
|
|||||||
button=(730, 641, 998, 675),
|
button=(730, 641, 998, 675),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
SYNTHESIZE_INSUFFICIENT = ButtonWrapper(
|
||||||
|
name='SYNTHESIZE_INSUFFICIENT',
|
||||||
|
share=Button(
|
||||||
|
file='./assets/share/item/synthesize/SYNTHESIZE_INSUFFICIENT.png',
|
||||||
|
area=(510, 564, 1220, 594),
|
||||||
|
search=(490, 544, 1240, 614),
|
||||||
|
color=(177, 102, 95),
|
||||||
|
button=(510, 564, 1220, 594),
|
||||||
|
),
|
||||||
|
)
|
||||||
SYNTHESIZE_INVENTORY = ButtonWrapper(
|
SYNTHESIZE_INVENTORY = ButtonWrapper(
|
||||||
name='SYNTHESIZE_INVENTORY',
|
name='SYNTHESIZE_INVENTORY',
|
||||||
share=Button(
|
share=Button(
|
||||||
|
@ -7,6 +7,7 @@ from tasks.base.page import page_item
|
|||||||
from tasks.item.assets.assets_item_data import OCR_DATA
|
from tasks.item.assets.assets_item_data import OCR_DATA
|
||||||
from tasks.item.keywords import KEYWORDS_ITEM_TAB
|
from tasks.item.keywords import KEYWORDS_ITEM_TAB
|
||||||
from tasks.item.ui import ItemUI
|
from tasks.item.ui import ItemUI
|
||||||
|
from tasks.planner.model import PlannerMixin
|
||||||
|
|
||||||
|
|
||||||
class DataDigit(Digit):
|
class DataDigit(Digit):
|
||||||
@ -16,7 +17,7 @@ class DataDigit(Digit):
|
|||||||
return super().after_process(result)
|
return super().after_process(result)
|
||||||
|
|
||||||
|
|
||||||
class DataUpdate(ItemUI):
|
class DataUpdate(ItemUI, PlannerMixin):
|
||||||
def _get_data(self):
|
def _get_data(self):
|
||||||
"""
|
"""
|
||||||
Page:
|
Page:
|
||||||
@ -53,3 +54,9 @@ class DataUpdate(ItemUI):
|
|||||||
self.config.stored.Credit.value = credit
|
self.config.stored.Credit.value = credit
|
||||||
self.config.stored.StallerJade.value = jade
|
self.config.stored.StallerJade.value = jade
|
||||||
self.config.task_delay(server_update=True)
|
self.config.task_delay(server_update=True)
|
||||||
|
# Sync to planner
|
||||||
|
require = self.config.cross_get('Dungeon.Planner.Item_Credit.total', default=0)
|
||||||
|
if require:
|
||||||
|
self.config.cross_set('Dungeon.Planner.Item_Credit.value', credit)
|
||||||
|
self.config.cross_set('Dungeon.Planner.Item_Credit.time', self.config.stored.Credit.time)
|
||||||
|
self.planner_write()
|
||||||
|
@ -94,6 +94,12 @@ class InventoryManager:
|
|||||||
if count == 1:
|
if count == 1:
|
||||||
return mids
|
return mids
|
||||||
elif count == 2:
|
elif count == 2:
|
||||||
|
# Only one row, [173.5 175. ]
|
||||||
|
mid_diff_mean = np.mean(mid_diff_range)
|
||||||
|
diff = max(mids) - min(mids)
|
||||||
|
if diff < mid_diff_mean * 0.3:
|
||||||
|
return np.mean(mids).reshape((1,))
|
||||||
|
# Double rows
|
||||||
return mids
|
return mids
|
||||||
# print(mids)
|
# print(mids)
|
||||||
encourage = self.COINCIDENT_POINT_ENCOURAGE_DISTANCE ** 2
|
encourage = self.COINCIDENT_POINT_ENCOURAGE_DISTANCE ** 2
|
||||||
@ -179,6 +185,8 @@ class InventoryManager:
|
|||||||
area = self.inventory.area
|
area = self.inventory.area
|
||||||
x_list = np.unique(np.sort(points[:, 0]))
|
x_list = np.unique(np.sort(points[:, 0]))
|
||||||
y_list = np.unique(np.sort(points[:, 1]))
|
y_list = np.unique(np.sort(points[:, 1]))
|
||||||
|
# print(x_list)
|
||||||
|
# print(y_list)
|
||||||
x_list = self.mid_cleanse(
|
x_list = self.mid_cleanse(
|
||||||
x_list,
|
x_list,
|
||||||
mid_diff_range=(self.GRID_DELTA[0] - 3, self.GRID_DELTA[0] + 3),
|
mid_diff_range=(self.GRID_DELTA[0] - 3, self.GRID_DELTA[0] + 3),
|
||||||
@ -189,6 +197,8 @@ class InventoryManager:
|
|||||||
mid_diff_range=(self.GRID_DELTA[1] - 3, self.GRID_DELTA[1] + 3),
|
mid_diff_range=(self.GRID_DELTA[1] - 3, self.GRID_DELTA[1] + 3),
|
||||||
edge_range=(area[1], area[3])
|
edge_range=(area[1], area[3])
|
||||||
)
|
)
|
||||||
|
# print(x_list)
|
||||||
|
# print(y_list)
|
||||||
|
|
||||||
def is_near_existing(p):
|
def is_near_existing(p):
|
||||||
diff = np.linalg.norm(points - p, axis=1)
|
diff = np.linalg.norm(points - p, axis=1)
|
||||||
|
@ -387,10 +387,14 @@ class Synthesize(CombatObtain, ItemUI):
|
|||||||
out: page_synthesize, SYNTHESIZE_CONFIRM
|
out: page_synthesize, SYNTHESIZE_CONFIRM
|
||||||
"""
|
"""
|
||||||
logger.hr('Synthesize confirm')
|
logger.hr('Synthesize confirm')
|
||||||
|
self.interval_clear([SYNTHESIZE_CONFIRM, page_synthesize.check_button])
|
||||||
|
|
||||||
def appear_confirm():
|
def appear_confirm():
|
||||||
return self.image_color_count(SYNTHESIZE_CONFIRM, color=(226, 229, 232), threshold=221, count=1000)
|
return self.image_color_count(SYNTHESIZE_CONFIRM, color=(226, 229, 232), threshold=221, count=1000)
|
||||||
|
|
||||||
|
def appear_insufficient():
|
||||||
|
return self.image_color_count(SYNTHESIZE_INSUFFICIENT, color=(172, 95, 87), threshold=221, count=5000)
|
||||||
|
|
||||||
# SYNTHESIZE_CONFIRM -> reward_appear
|
# SYNTHESIZE_CONFIRM -> reward_appear
|
||||||
while 1:
|
while 1:
|
||||||
if skip_first_screenshot:
|
if skip_first_screenshot:
|
||||||
@ -404,6 +408,7 @@ class Synthesize(CombatObtain, ItemUI):
|
|||||||
break
|
break
|
||||||
# Click
|
# Click
|
||||||
if self.handle_popup_confirm():
|
if self.handle_popup_confirm():
|
||||||
|
self.interval_reset(page_synthesize.check_button)
|
||||||
continue
|
continue
|
||||||
if appear_confirm() and self.ui_page_appear(page_synthesize, interval=2):
|
if appear_confirm() and self.ui_page_appear(page_synthesize, interval=2):
|
||||||
self.device.click(SYNTHESIZE_CONFIRM)
|
self.device.click(SYNTHESIZE_CONFIRM)
|
||||||
@ -421,10 +426,15 @@ class Synthesize(CombatObtain, ItemUI):
|
|||||||
if appear_confirm():
|
if appear_confirm():
|
||||||
logger.info('Synthesize end')
|
logger.info('Synthesize end')
|
||||||
break
|
break
|
||||||
|
if appear_insufficient():
|
||||||
|
logger.info('Synthesize end, item insufficient')
|
||||||
|
break
|
||||||
# Click
|
# Click
|
||||||
if self.handle_reward(click_button=SYNTHESIZE_MINUS):
|
if self.handle_reward(click_button=SYNTHESIZE_MINUS):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
self.interval_clear([SYNTHESIZE_CONFIRM, page_synthesize.check_button])
|
||||||
|
|
||||||
def synthesize_exit(self, skip_first_screenshot=True):
|
def synthesize_exit(self, skip_first_screenshot=True):
|
||||||
"""
|
"""
|
||||||
Pages:
|
Pages:
|
||||||
|
@ -652,6 +652,15 @@ class PlannerMixin(UI):
|
|||||||
if add:
|
if add:
|
||||||
planner.add_planner_result(self.planner)
|
planner.add_planner_result(self.planner)
|
||||||
|
|
||||||
|
# Load from dashboard
|
||||||
|
try:
|
||||||
|
row = planner.rows['Credit']
|
||||||
|
value = self.config.stored.Credit.value
|
||||||
|
if value:
|
||||||
|
row.value = value
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
self.planner_write(planner)
|
self.planner_write(planner)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
|
Loading…
Reference in New Issue
Block a user