Merge pull request #166 from LmeSzinc/bug_fix

Bug fix
This commit is contained in:
LmeSzinc 2023-10-17 16:52:53 +08:00 committed by GitHub
commit db3e78498e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 374 additions and 26 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -155,6 +155,17 @@
"StallerJade": {} "StallerJade": {}
} }
}, },
"Freebies": {
"Scheduler": {
"Enable": true,
"NextRun": "2020-01-01 00:00:00",
"Command": "Freebies",
"ServerUpdate": "04:00"
},
"SupportReward": {
"Collect": true
}
},
"Rogue": { "Rogue": {
"Scheduler": { "Scheduler": {
"Enable": false, "Enable": false,

View File

@ -421,7 +421,7 @@ class KeywordExtract:
self.keywords_id = hash_list self.keywords_id = hash_list
self.write_keywords(keyword_class='RogueResonance', output_file='./tasks/rogue/keywords/resonance.py', self.write_keywords(keyword_class='RogueResonance', output_file='./tasks/rogue/keywords/resonance.py',
text_convert=blessing_name, extra_attrs=extra_attrs) text_convert=blessing_name, extra_attrs=extra_attrs)
def iter_without_duplication(self, file: dict, keys): def iter_without_duplication(self, file: dict, keys):
visited = set() visited = set()
for data in file.values(): for data in file.values():

View File

@ -124,10 +124,10 @@ class ButtonWrapper(Resource):
self.name = name self.name = name
self.data_buttons = kwargs self.data_buttons = kwargs
self._matched_button: t.Optional[Button] = None self._matched_button: t.Optional[Button] = None
self.resource_add(self.name) self.resource_add(f'{name}:{next(self.iter_buttons(), None)}')
def resource_release(self): def resource_release(self):
del_cached_property(self, 'assets') del_cached_property(self, 'buttons')
self._matched_button = None self._matched_button = None
def __str__(self): def __str__(self):

View File

@ -1,11 +1,11 @@
import re import re
import module.config.server as server from module.base.decorator import cached_property
from module.base.decorator import cached_property, del_cached_property
def get_assets_from_file(file, regex): def get_assets_from_file(file):
assets = set() assets = set()
regex = re.compile(r"file='(.*?)'")
with open(file, 'r', encoding='utf-8') as f: with open(file, 'r', encoding='utf-8') as f:
for row in f.readlines(): for row in f.readlines():
result = regex.search(row) result = regex.search(row)
@ -20,11 +20,12 @@ class PreservedAssets:
assets = set() assets = set()
assets |= get_assets_from_file( assets |= get_assets_from_file(
file='./tasks/base/assets/assets_base_page.py', file='./tasks/base/assets/assets_base_page.py',
regex=re.compile(r'^([A-Za-z][A-Za-z0-9_]+) = ')
) )
assets |= get_assets_from_file( assets |= get_assets_from_file(
file='./tasks/base/assets/assets_base_popup.py', file='./tasks/base/assets/assets_base_popup.py',
regex=re.compile(r'^([A-Za-z][A-Za-z0-9_]+) = ') )
assets |= get_assets_from_file(
file='./tasks/base/assets/assets_base_main_page.py',
) )
return assets return assets
@ -44,11 +45,13 @@ class Resource:
@classmethod @classmethod
def is_loaded(cls, obj): def is_loaded(cls, obj):
if hasattr(obj, '_image') and obj._image is None: if hasattr(obj, '_image') and obj._image is not None:
return False return True
elif hasattr(obj, 'image') and obj.image is None: if hasattr(obj, 'image') and obj.image is not None:
return False return True
return True if hasattr(obj, 'buttons') and obj.buttons is not None:
return True
return False
@classmethod @classmethod
def resource_show(cls): def resource_show(cls):
@ -56,11 +59,16 @@ class Resource:
logger.hr('Show resource') logger.hr('Show resource')
for key, obj in cls.instances.items(): for key, obj in cls.instances.items():
if cls.is_loaded(obj): if cls.is_loaded(obj):
continue logger.info(f'{obj}: {key}')
logger.info(f'{obj}: {key}')
def release_resources(next_task=''): def release_resources(next_task=''):
# Release all OCR models
# det models take 400MB
if not next_task:
from module.ocr.models import OCR_MODEL
OCR_MODEL.resource_release()
# Release assets cache # Release assets cache
# module.ui has about 80 assets and takes about 3MB # module.ui has about 80 assets and takes about 3MB
# Alas has about 800 assets, but they are not all loaded. # Alas has about 800 assets, but they are not all loaded.

View File

@ -1110,6 +1110,39 @@
} }
} }
}, },
"Freebies": {
"Scheduler": {
"Enable": {
"type": "checkbox",
"value": true,
"option": [
true,
false
]
},
"NextRun": {
"type": "datetime",
"value": "2020-01-01 00:00:00",
"validate": "datetime"
},
"Command": {
"type": "input",
"value": "Freebies",
"display": "hide"
},
"ServerUpdate": {
"type": "input",
"value": "04:00",
"display": "hide"
}
},
"SupportReward": {
"Collect": {
"type": "checkbox",
"value": true
}
}
},
"Rogue": { "Rogue": {
"Scheduler": { "Scheduler": {
"Enable": { "Enable": {

View File

@ -126,6 +126,8 @@ DungeonStorage:
stored: StoredSimulatedUniverse stored: StoredSimulatedUniverse
order: 6 order: 6
color: "#8fb5fe" color: "#8fb5fe"
SupportReward:
Collect: true
Weekly: Weekly:
Name: Name:

View File

@ -22,3 +22,6 @@ BattlePass:
Assignment: Assignment:
Scheduler: Scheduler:
Enable: true Enable: true
Freebies:
Scheduler:
Enable: true

View File

@ -16,7 +16,8 @@
"DailyQuest", "DailyQuest",
"BattlePass", "BattlePass",
"Assignment", "Assignment",
"DataUpdate" "DataUpdate",
"Freebies"
] ]
} }
} }

View File

@ -44,7 +44,9 @@ Daily:
DataUpdate: DataUpdate:
- Scheduler - Scheduler
- ItemStorage - ItemStorage
Freebies:
- Scheduler
- SupportReward
# ==================== Rogue ==================== # ==================== Rogue ====================
Rogue: Rogue:

View File

@ -61,6 +61,9 @@ class GeneratedConfig:
DungeonStorage_EchoOfWar = {} DungeonStorage_EchoOfWar = {}
DungeonStorage_SimulatedUniverse = {} DungeonStorage_SimulatedUniverse = {}
# Group `SupportReward`
SupportReward_Collect = True
# Group `Weekly` # Group `Weekly`
Weekly_Name = 'Echo_of_War_Divine_Seed' # Echo_of_War_Destruction_Beginning, Echo_of_War_End_of_the_Eternal_Freeze, Echo_of_War_Divine_Seed Weekly_Name = 'Echo_of_War_Divine_Seed' # Echo_of_War_Destruction_Beginning, Echo_of_War_End_of_the_Eternal_Freeze, Echo_of_War_Divine_Seed
Weekly_Team = 1 # 1, 2, 3, 4, 5, 6 Weekly_Team = 1 # 1, 2, 3, 4, 5, 6

View File

@ -10,7 +10,8 @@ class ManualConfig:
SCHEDULER_PRIORITY = """ SCHEDULER_PRIORITY = """
Restart Restart
> BattlePass > DailyQuest > Assignment > DataUpdate > BattlePass > DailyQuest > Assignment
> Freebies > DataUpdate
> Weekly > Dungeon > Weekly > Dungeon
""" """

View File

@ -46,6 +46,10 @@
"name": "Dashboard Upd", "name": "Dashboard Upd",
"help": "" "help": ""
}, },
"Freebies": {
"name": "Freebies",
"help": ""
},
"Rogue": { "Rogue": {
"name": "Simulated Universe", "name": "Simulated Universe",
"help": "Simulated Universe is in development, task will not be run" "help": "Simulated Universe is in development, task will not be run"
@ -410,6 +414,16 @@
"help": "" "help": ""
} }
}, },
"SupportReward": {
"_info": {
"name": "Support Reward",
"help": ""
},
"Collect": {
"name": "Receive support reward",
"help": ""
}
},
"Weekly": { "Weekly": {
"_info": { "_info": {
"name": "Echo of War Settings", "name": "Echo of War Settings",

View File

@ -46,6 +46,10 @@
"name": "Actualizar panel", "name": "Actualizar panel",
"help": "" "help": ""
}, },
"Freebies": {
"name": "Freebies",
"help": ""
},
"Rogue": { "Rogue": {
"name": "Universo Simulado", "name": "Universo Simulado",
"help": "El Universo Simulado está en desarrollo, y no se ejecutará" "help": "El Universo Simulado está en desarrollo, y no se ejecutará"
@ -410,6 +414,16 @@
"help": "" "help": ""
} }
}, },
"SupportReward": {
"_info": {
"name": "Support Reward",
"help": ""
},
"Collect": {
"name": "Receive support reward",
"help": ""
}
},
"Weekly": { "Weekly": {
"_info": { "_info": {
"name": "Ajustes de Ecos de la guerra", "name": "Ajustes de Ecos de la guerra",

View File

@ -46,6 +46,10 @@
"name": "Task.DataUpdate.name", "name": "Task.DataUpdate.name",
"help": "Task.DataUpdate.help" "help": "Task.DataUpdate.help"
}, },
"Freebies": {
"name": "他ギフト",
"help": ""
},
"Rogue": { "Rogue": {
"name": "Task.Rogue.name", "name": "Task.Rogue.name",
"help": "Task.Rogue.help" "help": "Task.Rogue.help"
@ -410,6 +414,16 @@
"help": "DungeonStorage.SimulatedUniverse.help" "help": "DungeonStorage.SimulatedUniverse.help"
} }
}, },
"SupportReward": {
"_info": {
"name": "サポートボーナス",
"help": ""
},
"Collect": {
"name": "收取サポートボーナス",
"help": ""
}
},
"Weekly": { "Weekly": {
"_info": { "_info": {
"name": "Weekly._info.name", "name": "Weekly._info.name",

View File

@ -46,6 +46,10 @@
"name": "仪表盘更新", "name": "仪表盘更新",
"help": "" "help": ""
}, },
"Freebies": {
"name": "白嫖奖励",
"help": ""
},
"Rogue": { "Rogue": {
"name": "模拟宇宙", "name": "模拟宇宙",
"help": "模拟宇宙还在开发中,任务不会被运行" "help": "模拟宇宙还在开发中,任务不会被运行"
@ -410,6 +414,16 @@
"help": "" "help": ""
} }
}, },
"SupportReward": {
"_info": {
"name": "支援奖励",
"help": ""
},
"Collect": {
"name": "领取支援奖励",
"help": ""
}
},
"Weekly": { "Weekly": {
"_info": { "_info": {
"name": "历战余响设置", "name": "历战余响设置",

View File

@ -46,6 +46,10 @@
"name": "儀表板更新", "name": "儀表板更新",
"help": "" "help": ""
}, },
"Freebies": {
"name": "免費獎勵",
"help": ""
},
"Rogue": { "Rogue": {
"name": "模擬宇宙", "name": "模擬宇宙",
"help": "模擬宇宙還在開發中,任務不會被運行" "help": "模擬宇宙還在開發中,任務不會被運行"
@ -410,6 +414,16 @@
"help": "" "help": ""
} }
}, },
"SupportReward": {
"_info": {
"name": "支援獎勵",
"help": ""
},
"Collect": {
"name": "收取支援獎勵",
"help": ""
}
},
"Weekly": { "Weekly": {
"_info": { "_info": {
"name": "歷戰餘響設定", "name": "歷戰餘響設定",

View File

@ -1,6 +1,6 @@
from pponnxcr import TextSystem as TextSystem_ from pponnxcr import TextSystem as TextSystem_
from module.base.decorator import cached_property from module.base.decorator import cached_property, del_cached_property
from module.exception import ScriptError from module.exception import ScriptError
DIC_LANG_TO_MODEL = { DIC_LANG_TO_MODEL = {
@ -56,6 +56,12 @@ class OcrModel:
except AttributeError: except AttributeError:
raise ScriptError(f'OCR model under lang "{lang}" does not exists') raise ScriptError(f'OCR model under lang "{lang}" does not exists')
def resource_release(self):
del_cached_property(self, 'zhs')
del_cached_property(self, 'en')
del_cached_property(self, 'ja')
del_cached_property(self, 'zht')
@cached_property @cached_property
def zhs(self): def zhs(self):
return TextSystem('zhs') return TextSystem('zhs')
@ -66,7 +72,7 @@ class OcrModel:
@cached_property @cached_property
def ja(self): def ja(self):
return TextSystem('zht') return TextSystem('ja')
@cached_property @cached_property
def zht(self): def zht(self):

3
src.py
View File

@ -46,6 +46,9 @@ class StarRailCopilot(AzurLaneAutoScript):
from tasks.item.data_update import DataUpdate from tasks.item.data_update import DataUpdate
DataUpdate(config=self.config, device=self.device).run() DataUpdate(config=self.config, device=self.device).run()
def freebies(self):
from tasks.freebies.freebies import Freebies
Freebies(config=self.config, device=self.device).run()
if __name__ == '__main__': if __name__ == '__main__':
src = StarRailCopilot('src') src = StarRailCopilot('src')

View File

@ -1,18 +1,26 @@
from module.base.base import ModuleBase from module.base.base import ModuleBase
from module.logger import logger
from tasks.base.assets.assets_base_popup import * from tasks.base.assets.assets_base_popup import *
class PopupHandler(ModuleBase): class PopupHandler(ModuleBase):
def handle_reward(self, interval=5) -> bool: def handle_reward(self, interval=5, click_button=None) -> bool:
""" """
Args: Args:
interval: interval:
click_button: Set a button to click
Returns: Returns:
If handled. If handled.
""" """
if self.appear_then_click(GET_REWARD, interval=interval): if click_button is None:
return True if self.appear_then_click(GET_REWARD, interval=interval):
return True
else:
if self.appear(GET_REWARD, interval=interval):
logger.info(f'{GET_REWARD} -> {click_button}')
self.device.click(click_button)
return True
return False return False

View File

@ -1,3 +1,5 @@
import re
import numpy as np import numpy as np
from module.base.base import ModuleBase from module.base.base import ModuleBase
@ -70,6 +72,9 @@ class OcrDungeonList(Ocr):
if self.lang == 'cn': if self.lang == 'cn':
result = result.replace('', '') # 巽风之形 result = result.replace('', '') # 巽风之形
result = result.replace('皖A0', '50').replace('', '') result = result.replace('皖A0', '50').replace('', '')
# 燔灼之形•凝滞虚影
result = result.replace('', '')
result = re.sub('^灼之形', '燔灼之形', result)
return result return result
@ -411,7 +416,7 @@ class DungeonUI(UI):
Examples: Examples:
from tasks.dungeon.keywords import KEYWORDS_DUNGEON_LIST from tasks.dungeon.keywords import KEYWORDS_DUNGEON_LIST
self = DungeonUI('alas') self = DungeonUI('src')
self.device.screenshot() self.device.screenshot()
self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index) self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index)
self.dungeon_goto(KEYWORDS_DUNGEON_LIST.Calyx_Crimson_Harmony) self.dungeon_goto(KEYWORDS_DUNGEON_LIST.Calyx_Crimson_Harmony)

View File

@ -13,7 +13,7 @@ from tasks.base.assets.assets_base_page import FORGOTTEN_HALL_CHECK, MAP_EXIT
from tasks.dungeon.keywords import DungeonList, KEYWORDS_DUNGEON_LIST, KEYWORDS_DUNGEON_TAB from tasks.dungeon.keywords import DungeonList, KEYWORDS_DUNGEON_LIST, KEYWORDS_DUNGEON_TAB
from tasks.dungeon.ui import DungeonUI from tasks.dungeon.ui import DungeonUI
from tasks.forgotten_hall.assets.assets_forgotten_hall_ui import * from tasks.forgotten_hall.assets.assets_forgotten_hall_ui import *
from tasks.forgotten_hall.keywords import ForgottenHallStage from tasks.forgotten_hall.keywords import ForgottenHallStage, KEYWORDS_FORGOTTEN_HALL_STAGE
from tasks.forgotten_hall.team import ForgottenHallTeam from tasks.forgotten_hall.team import ForgottenHallTeam
from tasks.map.control.joystick import MapControlJoystick from tasks.map.control.joystick import MapControlJoystick
@ -70,7 +70,11 @@ class DraggableStageList(DraggableList):
while 1: while 1:
result = super().insight_row(row, main=main, skip_first_screenshot=skip_first_screenshot) result = super().insight_row(row, main=main, skip_first_screenshot=skip_first_screenshot)
if not result: if not result:
return False if row == KEYWORDS_FORGOTTEN_HALL_STAGE.Stage_1:
# Must have stage 1, retry if not found
continue
else:
return False
if skip_first_screenshot: if skip_first_screenshot:
skip_first_screenshot = False skip_first_screenshot = False

View File

@ -0,0 +1,62 @@
from module.base.button import Button, ButtonWrapper
# This file was auto-generated, do not modify it manually. To generate:
# ``` python -m dev_tools.button_extract ```
CAN_GET_REWARD = ButtonWrapper(
name='CAN_GET_REWARD',
share=Button(
file='./assets/share/freebies/support_reward/CAN_GET_REWARD.png',
area=(1055, 266, 1106, 310),
search=(1035, 246, 1126, 330),
color=(229, 186, 123),
button=(1055, 266, 1106, 310),
),
)
CLICKING_REWARD = ButtonWrapper(
name='CLICKING_REWARD',
share=Button(
file='./assets/share/freebies/support_reward/CLICKING_REWARD.png',
area=(1066, 268, 1105, 307),
search=(1046, 248, 1125, 327),
color=(197, 161, 111),
button=(1066, 268, 1105, 307),
),
)
IN_PROFILE = ButtonWrapper(
name='IN_PROFILE',
share=Button(
file='./assets/share/freebies/support_reward/IN_PROFILE.png',
area=(643, 106, 673, 131),
search=(623, 86, 693, 151),
color=(74, 67, 58),
button=(643, 106, 673, 131),
),
)
MENU_TO_PROFILE = ButtonWrapper(
name='MENU_TO_PROFILE',
share=Button(
file='./assets/share/freebies/support_reward/MENU_TO_PROFILE.png',
area=(1123, 82, 1149, 97),
search=(1103, 62, 1169, 117),
color=(226, 226, 225),
button=(1123, 82, 1149, 97),
),
)
PROFILE = ButtonWrapper(
name='PROFILE',
cn=Button(
file='./assets/cn/freebies/support_reward/PROFILE.png',
area=(890, 99, 1111, 131),
search=(870, 79, 1131, 151),
color=(205, 206, 206),
button=(890, 99, 1111, 131),
),
en=Button(
file='./assets/en/freebies/support_reward/PROFILE.png',
area=(907, 102, 1092, 132),
search=(887, 82, 1112, 152),
color=(190, 189, 189),
button=(907, 102, 1092, 132),
),
)

View File

@ -0,0 +1,14 @@
from module.logger import logger
from module.base.base import ModuleBase
from tasks.freebies.support_reward import SupportReward
class Freebies(ModuleBase):
def run(self):
"""
Run all freebie tasks
"""
if self.config.SupportReward_Collect:
logger.hr('Support Reward')
SupportReward(config=self.config, device=self.device).run()
self.config.task_delay(server_update=True)

View File

@ -0,0 +1,112 @@
from module.base.timer import Timer
from module.logger import logger
from tasks.base.assets.assets_base_page import CLOSE, MENU_CHECK
from tasks.base.assets.assets_base_popup import GET_REWARD
from tasks.base.page import page_menu
from tasks.base.ui import UI
from tasks.freebies.assets.assets_freebies_support_reward import (
CAN_GET_REWARD,
IN_PROFILE,
MENU_TO_PROFILE,
PROFILE
)
class SupportReward(UI):
def run(self):
"""
Run get support reward task
"""
logger.hr('Support reward', level=1)
self.ui_ensure(page_menu)
self._goto_profile()
self._get_reward()
self._goto_menu()
def _goto_profile(self):
"""
Pages:
in: MENU
out: PROFILE
"""
skip_first_screenshot = False
logger.info('Going to profile')
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(IN_PROFILE):
logger.info('Successfully in profile')
return True
if self.appear_then_click(MENU_TO_PROFILE):
continue
if self.appear_then_click(PROFILE):
continue
def _get_reward(self, skip_first_screenshot=True):
"""
Pages:
in: PROFILE
out: GET_REWARD
"""
logger.info('Getting reward')
claimed = False
empty = Timer(0.3, count=1).start()
timeout = Timer(5).start()
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if not claimed and empty.reached():
logger.info('No reward')
break
if self.appear(GET_REWARD):
logger.info('Got reward')
break
if timeout.reached():
logger.warning('Get support reward timeout')
break
if self.appear_then_click(CAN_GET_REWARD, similarity=0.70, interval=2):
claimed = True
timeout.reset()
continue
def _goto_menu(self):
"""
Pages:
in: PROFILE or GET_REWARD
out: MENU
"""
skip_first_screenshot = False
logger.info('Going to menu')
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
self.device.screenshot()
if self.appear(MENU_CHECK):
return True
if self.appear(IN_PROFILE, interval=2):
logger.info(f'{IN_PROFILE} -> {CLOSE}')
self.device.click(CLOSE)
continue
if self.handle_reward(click_button=CAN_GET_REWARD):
# # Avoid clicking on some other buttons
continue
if __name__ == '__main__':
self = SupportReward('src')
self.device.screenshot()
self.run()