Merge branch 'master' into dev
BIN
assets/cn/assignment/dispatch/ASSIGNMENT_START.2.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
assets/cn/assignment/ui/ALL_ABOUT_BOOTHILL_CHECK.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
assets/cn/assignment/ui/ALL_ABOUT_BOOTHILL_CLICK.png
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
assets/en/assignment/dispatch/ASSIGNMENT_START.2.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/en/assignment/ui/ALL_ABOUT_BOOTHILL_CHECK.png
Normal file
After Width: | Height: | Size: 9.4 KiB |
BIN
assets/en/assignment/ui/ALL_ABOUT_BOOTHILL_CLICK.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
assets/share/assignment/dispatch/ASSIGNMENT_STARTED_CHECK.2.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
@ -126,6 +126,7 @@ class GenerateAssignmentEventGroup(GenerateKeyword):
|
|||||||
|
|
||||||
def iter_keywords(self) -> Iterable[dict]:
|
def iter_keywords(self) -> Iterable[dict]:
|
||||||
yield dict(text_id=self.find_keyword('空间站特派', lang='cn')[0])
|
yield dict(text_id=self.find_keyword('空间站特派', lang='cn')[0])
|
||||||
|
yield dict(text_id=self.find_keyword('关于波提欧的一切…', lang='cn')[0])
|
||||||
|
|
||||||
|
|
||||||
class GenerateAssignmentEventEntry(GenerateKeyword):
|
class GenerateAssignmentEventEntry(GenerateKeyword):
|
||||||
|
@ -1113,7 +1113,7 @@
|
|||||||
"20": "20 Hours"
|
"20": "20 Hours"
|
||||||
},
|
},
|
||||||
"Event": {
|
"Event": {
|
||||||
"name": "Complete Event Assignments First",
|
"name": "Complete Event Assignments",
|
||||||
"help": ""
|
"help": ""
|
||||||
},
|
},
|
||||||
"Assignment": {
|
"Assignment": {
|
||||||
|
@ -1113,7 +1113,7 @@
|
|||||||
"20": "20小时"
|
"20": "20小时"
|
||||||
},
|
},
|
||||||
"Event": {
|
"Event": {
|
||||||
"name": "有活动时优先做活动委托",
|
"name": "有活动时参加活动委托",
|
||||||
"help": ""
|
"help": ""
|
||||||
},
|
},
|
||||||
"Assignment": {
|
"Assignment": {
|
||||||
|
@ -1113,7 +1113,7 @@
|
|||||||
"20": "20小時"
|
"20": "20小時"
|
||||||
},
|
},
|
||||||
"Event": {
|
"Event": {
|
||||||
"name": "有活動時優先做活動委託",
|
"name": "有活動時參加活動委託",
|
||||||
"help": ""
|
"help": ""
|
||||||
},
|
},
|
||||||
"Assignment": {
|
"Assignment": {
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
from tasks.assignment.assets.assets_assignment_ui import (
|
from tasks.assignment.assets.assets_assignment_ui import (
|
||||||
|
ALL_ABOUT_BOOTHILL_CHECK, ALL_ABOUT_BOOTHILL_CLICK,
|
||||||
CHARACTER_MATERIALS_CHECK, CHARACTER_MATERIALS_CLICK,
|
CHARACTER_MATERIALS_CHECK, CHARACTER_MATERIALS_CLICK,
|
||||||
EXP_MATERIALS_CREDITS_CHECK, EXP_MATERIALS_CREDITS_CLICK, GROUP_SEARCH,
|
EXP_MATERIALS_CREDITS_CHECK, EXP_MATERIALS_CREDITS_CLICK, GROUP_SEARCH,
|
||||||
SPACE_STATION_TASK_FORCE_CHECK, SPACE_STATION_TASK_FORCE_CLICK,
|
SYNTHESIS_MATERIALS_CHECK, SYNTHESIS_MATERIALS_CLICK)
|
||||||
SYNTHESIS_MATERIALS_CHECK, SYNTHESIS_MATERIALS_CLICK
|
|
||||||
)
|
|
||||||
|
|
||||||
for group_button_wrapper in (
|
for group_button_wrapper in (
|
||||||
SPACE_STATION_TASK_FORCE_CHECK, SPACE_STATION_TASK_FORCE_CLICK,
|
ALL_ABOUT_BOOTHILL_CHECK, ALL_ABOUT_BOOTHILL_CLICK,
|
||||||
CHARACTER_MATERIALS_CHECK, CHARACTER_MATERIALS_CLICK,
|
CHARACTER_MATERIALS_CHECK, CHARACTER_MATERIALS_CLICK,
|
||||||
EXP_MATERIALS_CREDITS_CHECK, EXP_MATERIALS_CREDITS_CLICK,
|
EXP_MATERIALS_CREDITS_CHECK, EXP_MATERIALS_CREDITS_CLICK,
|
||||||
SYNTHESIS_MATERIALS_CHECK, SYNTHESIS_MATERIALS_CLICK,
|
SYNTHESIS_MATERIALS_CHECK, SYNTHESIS_MATERIALS_CLICK,
|
||||||
|
@ -5,30 +5,57 @@ from module.base.button import Button, ButtonWrapper
|
|||||||
|
|
||||||
ASSIGNMENT_START = ButtonWrapper(
|
ASSIGNMENT_START = ButtonWrapper(
|
||||||
name='ASSIGNMENT_START',
|
name='ASSIGNMENT_START',
|
||||||
cn=Button(
|
cn=[
|
||||||
|
Button(
|
||||||
file='./assets/cn/assignment/dispatch/ASSIGNMENT_START.png',
|
file='./assets/cn/assignment/dispatch/ASSIGNMENT_START.png',
|
||||||
area=(563, 341, 716, 376),
|
area=(563, 341, 716, 376),
|
||||||
search=(552, 299, 725, 412),
|
search=(552, 299, 725, 412),
|
||||||
color=(103, 92, 72),
|
color=(103, 92, 72),
|
||||||
button=(563, 341, 716, 376),
|
button=(563, 341, 716, 376),
|
||||||
),
|
),
|
||||||
en=Button(
|
Button(
|
||||||
|
file='./assets/cn/assignment/dispatch/ASSIGNMENT_START.2.png',
|
||||||
|
area=(579, 373, 702, 405),
|
||||||
|
search=(552, 299, 725, 412),
|
||||||
|
color=(84, 75, 59),
|
||||||
|
button=(579, 373, 702, 405),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
en=[
|
||||||
|
Button(
|
||||||
file='./assets/en/assignment/dispatch/ASSIGNMENT_START.png',
|
file='./assets/en/assignment/dispatch/ASSIGNMENT_START.png',
|
||||||
area=(693, 343, 831, 374),
|
area=(693, 343, 831, 374),
|
||||||
search=(669, 297, 831, 416),
|
search=(669, 297, 831, 416),
|
||||||
color=(95, 86, 67),
|
color=(95, 86, 67),
|
||||||
button=(693, 343, 831, 374),
|
button=(693, 343, 831, 374),
|
||||||
),
|
),
|
||||||
|
Button(
|
||||||
|
file='./assets/en/assignment/dispatch/ASSIGNMENT_START.2.png',
|
||||||
|
area=(676, 376, 787, 404),
|
||||||
|
search=(669, 297, 831, 416),
|
||||||
|
color=(80, 71, 56),
|
||||||
|
button=(676, 376, 787, 404),
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
ASSIGNMENT_STARTED_CHECK = ButtonWrapper(
|
ASSIGNMENT_STARTED_CHECK = ButtonWrapper(
|
||||||
name='ASSIGNMENT_STARTED_CHECK',
|
name='ASSIGNMENT_STARTED_CHECK',
|
||||||
share=Button(
|
share=[
|
||||||
|
Button(
|
||||||
file='./assets/share/assignment/dispatch/ASSIGNMENT_STARTED_CHECK.png',
|
file='./assets/share/assignment/dispatch/ASSIGNMENT_STARTED_CHECK.png',
|
||||||
area=(542, 412, 1156, 422),
|
area=(542, 412, 1156, 422),
|
||||||
search=(522, 392, 1176, 442),
|
search=(522, 392, 1176, 442),
|
||||||
color=(232, 230, 226),
|
color=(232, 230, 226),
|
||||||
button=(542, 412, 1156, 422),
|
button=(542, 412, 1156, 422),
|
||||||
),
|
),
|
||||||
|
Button(
|
||||||
|
file='./assets/share/assignment/dispatch/ASSIGNMENT_STARTED_CHECK.2.png',
|
||||||
|
area=(542, 412, 1156, 422),
|
||||||
|
search=(522, 392, 1176, 442),
|
||||||
|
color=(254, 244, 221),
|
||||||
|
button=(542, 412, 1156, 422),
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
CHARACTER_1 = ButtonWrapper(
|
CHARACTER_1 = ButtonWrapper(
|
||||||
name='CHARACTER_1',
|
name='CHARACTER_1',
|
||||||
|
@ -3,6 +3,40 @@ from module.base.button import Button, ButtonWrapper
|
|||||||
# This file was auto-generated, do not modify it manually. To generate:
|
# This file was auto-generated, do not modify it manually. To generate:
|
||||||
# ``` python -m dev_tools.button_extract ```
|
# ``` python -m dev_tools.button_extract ```
|
||||||
|
|
||||||
|
ALL_ABOUT_BOOTHILL_CHECK = ButtonWrapper(
|
||||||
|
name='ALL_ABOUT_BOOTHILL_CHECK',
|
||||||
|
cn=Button(
|
||||||
|
file='./assets/cn/assignment/ui/ALL_ABOUT_BOOTHILL_CHECK.png',
|
||||||
|
area=(153, 98, 226, 118),
|
||||||
|
search=(133, 78, 246, 138),
|
||||||
|
color=(186, 180, 164),
|
||||||
|
button=(153, 98, 226, 118),
|
||||||
|
),
|
||||||
|
en=Button(
|
||||||
|
file='./assets/en/assignment/ui/ALL_ABOUT_BOOTHILL_CHECK.png',
|
||||||
|
area=(154, 89, 240, 129),
|
||||||
|
search=(134, 69, 260, 149),
|
||||||
|
color=(207, 201, 183),
|
||||||
|
button=(154, 89, 240, 129),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
ALL_ABOUT_BOOTHILL_CLICK = ButtonWrapper(
|
||||||
|
name='ALL_ABOUT_BOOTHILL_CLICK',
|
||||||
|
cn=Button(
|
||||||
|
file='./assets/cn/assignment/ui/ALL_ABOUT_BOOTHILL_CLICK.png',
|
||||||
|
area=(153, 98, 227, 119),
|
||||||
|
search=(133, 78, 247, 139),
|
||||||
|
color=(80, 79, 77),
|
||||||
|
button=(153, 98, 227, 119),
|
||||||
|
),
|
||||||
|
en=Button(
|
||||||
|
file='./assets/en/assignment/ui/ALL_ABOUT_BOOTHILL_CLICK.png',
|
||||||
|
area=(154, 90, 241, 128),
|
||||||
|
search=(134, 70, 261, 148),
|
||||||
|
color=(59, 57, 56),
|
||||||
|
button=(154, 90, 241, 128),
|
||||||
|
),
|
||||||
|
)
|
||||||
CHARACTER_MATERIALS_CHECK = ButtonWrapper(
|
CHARACTER_MATERIALS_CHECK = ButtonWrapper(
|
||||||
name='CHARACTER_MATERIALS_CHECK',
|
name='CHARACTER_MATERIALS_CHECK',
|
||||||
cn=Button(
|
cn=Button(
|
||||||
|
@ -2,7 +2,9 @@ from datetime import datetime
|
|||||||
|
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from tasks.assignment.claim import AssignmentClaim
|
from tasks.assignment.claim import AssignmentClaim
|
||||||
from tasks.assignment.keywords import (AssignmentEntry, AssignmentEventGroup, KEYWORDS_ASSIGNMENT_GROUP)
|
from tasks.assignment.keywords import (KEYWORDS_ASSIGNMENT_GROUP,
|
||||||
|
AssignmentEntry, AssignmentEventEntry,
|
||||||
|
AssignmentEventGroup)
|
||||||
from tasks.assignment.ui import AssignmentStatus
|
from tasks.assignment.ui import AssignmentStatus
|
||||||
from tasks.base.page import page_assignment, page_menu
|
from tasks.base.page import page_assignment, page_menu
|
||||||
from tasks.daily.keywords import KEYWORDS_DAILY_QUEST
|
from tasks.daily.keywords import KEYWORDS_DAILY_QUEST
|
||||||
@ -10,7 +12,7 @@ from tasks.daily.synthesize import SynthesizeUI
|
|||||||
|
|
||||||
|
|
||||||
class Assignment(AssignmentClaim, SynthesizeUI):
|
class Assignment(AssignmentClaim, SynthesizeUI):
|
||||||
def run(self, assignments: list[AssignmentEntry] = None, duration: int = None, event_first: bool = None):
|
def run(self, assignments: list[AssignmentEntry] = None, duration: int = None, join_event: bool = None):
|
||||||
self.config.update_battle_pass_quests()
|
self.config.update_battle_pass_quests()
|
||||||
self.config.update_daily_quests()
|
self.config.update_daily_quests()
|
||||||
|
|
||||||
@ -26,22 +28,21 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
|||||||
'There are duplicate assignments in config, check it out')
|
'There are duplicate assignments in config, check it out')
|
||||||
if duration is None:
|
if duration is None:
|
||||||
duration = self.config.Assignment_Duration
|
duration = self.config.Assignment_Duration
|
||||||
if event_first is None:
|
if join_event is None:
|
||||||
event_first = self.config.Assignment_Event
|
join_event = self.config.Assignment_Event
|
||||||
|
|
||||||
self.dispatched = dict()
|
self.dispatched = dict()
|
||||||
self.has_new_dispatch = False
|
self.has_new_dispatch = False
|
||||||
self.ensure_scroll_top(page_menu)
|
self.ensure_scroll_top(page_menu)
|
||||||
self.ui_ensure(page_assignment)
|
self.ui_ensure(page_assignment)
|
||||||
|
self._wait_until_group_loaded()
|
||||||
event_ongoing = next((
|
event_ongoing = next((
|
||||||
g for g in self._iter_groups()
|
g for g in self._iter_groups()
|
||||||
if isinstance(g, AssignmentEventGroup)
|
if isinstance(g, AssignmentEventGroup)
|
||||||
), None)
|
), None)
|
||||||
if event_first and event_ongoing is not None:
|
if join_event and event_ongoing is not None:
|
||||||
undispatched = assignments
|
if self._check_event():
|
||||||
remain = self._check_all()
|
self._check_event()
|
||||||
remain = self._dispatch_event(remain)
|
|
||||||
else:
|
|
||||||
# Iterate in user-specified order, return undispatched ones
|
# Iterate in user-specified order, return undispatched ones
|
||||||
undispatched = list(self._check_inlist(assignments, duration))
|
undispatched = list(self._check_inlist(assignments, duration))
|
||||||
remain = self._check_all()
|
remain = self._check_all()
|
||||||
@ -89,13 +90,15 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
|||||||
logger.hr('Assignment check inlist', level=1)
|
logger.hr('Assignment check inlist', level=1)
|
||||||
logger.info(
|
logger.info(
|
||||||
f'User specified assignments: {", ".join([x.name for x in assignments])}')
|
f'User specified assignments: {", ".join([x.name for x in assignments])}')
|
||||||
_, remain, _ = self._limit_status
|
remain = None
|
||||||
for assignment in assignments:
|
for assignment in assignments:
|
||||||
if assignment in self.dispatched:
|
if assignment in self.dispatched:
|
||||||
continue
|
continue
|
||||||
logger.hr('Assignment inlist', level=2)
|
logger.hr('Assignment inlist', level=2)
|
||||||
logger.info(f'Check assignment inlist: {assignment}')
|
logger.info(f'Check assignment inlist: {assignment}')
|
||||||
self.goto_entry(assignment)
|
self.goto_entry(assignment)
|
||||||
|
if remain is None:
|
||||||
|
_, remain, _ = self._limit_status
|
||||||
status = self._check_assignment_status()
|
status = self._check_assignment_status()
|
||||||
if status == AssignmentStatus.CLAIMABLE:
|
if status == AssignmentStatus.CLAIMABLE:
|
||||||
self.claim(assignment, duration, should_redispatch=True)
|
self.claim(assignment, duration, should_redispatch=True)
|
||||||
@ -121,10 +124,16 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
|||||||
"""
|
"""
|
||||||
logger.hr('Assignment check all', level=1)
|
logger.hr('Assignment check all', level=1)
|
||||||
current, remain, _ = self._limit_status
|
current, remain, _ = self._limit_status
|
||||||
|
len_dispatched = len([
|
||||||
|
x for x in self.dispatched.keys()
|
||||||
|
if not isinstance(x, AssignmentEventEntry)
|
||||||
|
])
|
||||||
# current = #Claimable + #Dispatched
|
# current = #Claimable + #Dispatched
|
||||||
if current == len(self.dispatched):
|
if current == len_dispatched:
|
||||||
return remain
|
return remain
|
||||||
for group in self._iter_groups():
|
for group in self._iter_groups():
|
||||||
|
if isinstance(group, AssignmentEventGroup):
|
||||||
|
continue
|
||||||
self.goto_group(group)
|
self.goto_group(group)
|
||||||
insight = False
|
insight = False
|
||||||
for assignment in self._iter_entries():
|
for assignment in self._iter_entries():
|
||||||
@ -139,14 +148,15 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
|||||||
current -= 1
|
current -= 1
|
||||||
remain += 1
|
remain += 1
|
||||||
insight = True # Order of entries change after claiming
|
insight = True # Order of entries change after claiming
|
||||||
if current == len(self.dispatched):
|
if current == len_dispatched:
|
||||||
return remain
|
return remain
|
||||||
continue
|
continue
|
||||||
if status == AssignmentStatus.DISPATCHED:
|
if status == AssignmentStatus.DISPATCHED:
|
||||||
self.dispatched[assignment] = datetime.now() + \
|
self.dispatched[assignment] = datetime.now() + \
|
||||||
self._get_assignment_time()
|
self._get_assignment_time()
|
||||||
|
len_dispatched += 1
|
||||||
insight = False # Order of entries does not change here
|
insight = False # Order of entries does not change here
|
||||||
if current == len(self.dispatched):
|
if current == len_dispatched:
|
||||||
return remain
|
return remain
|
||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
@ -183,10 +193,9 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
|||||||
if remain <= 0:
|
if remain <= 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
def _dispatch_event(self, remain: int):
|
def _check_event(self):
|
||||||
if remain <= 0:
|
logger.hr('Assignment check event', level=1)
|
||||||
return remain
|
claimed = False
|
||||||
logger.hr('Assignment dispatch event', level=1)
|
|
||||||
for group in self._iter_groups():
|
for group in self._iter_groups():
|
||||||
if not isinstance(group, AssignmentEventGroup):
|
if not isinstance(group, AssignmentEventGroup):
|
||||||
continue
|
continue
|
||||||
@ -199,12 +208,14 @@ class Assignment(AssignmentClaim, SynthesizeUI):
|
|||||||
# Order of entries does not change during iteration
|
# Order of entries does not change during iteration
|
||||||
self.goto_entry(assignment, insight=False)
|
self.goto_entry(assignment, insight=False)
|
||||||
status = self._check_assignment_status()
|
status = self._check_assignment_status()
|
||||||
# Should only be dispatchable or locked after _check_all
|
if status == AssignmentStatus.LOCKED:
|
||||||
|
continue
|
||||||
|
if status == AssignmentStatus.CLAIMABLE:
|
||||||
|
self.claim(assignment, None, should_redispatch=False)
|
||||||
|
claimed = True
|
||||||
if status == AssignmentStatus.DISPATCHABLE:
|
if status == AssignmentStatus.DISPATCHABLE:
|
||||||
self.dispatch(assignment, None)
|
self.dispatch(assignment, None)
|
||||||
remain -= 1
|
if status == AssignmentStatus.DISPATCHED:
|
||||||
if remain <= 0:
|
self.dispatched[assignment] = datetime.now() + \
|
||||||
return remain
|
self._get_assignment_time()
|
||||||
continue
|
return claimed
|
||||||
break
|
|
||||||
return remain
|
|
||||||
|
@ -30,7 +30,7 @@ KEYWORDS_ASSIGNMENT_GROUP.Synthesis_Materials.entries = (
|
|||||||
KEYWORDS_ASSIGNMENT_ENTRY.Fragments_of_Illusory_Dreams,
|
KEYWORDS_ASSIGNMENT_ENTRY.Fragments_of_Illusory_Dreams,
|
||||||
KEYWORDS_ASSIGNMENT_ENTRY.Scalpel_and_Screwdriver,
|
KEYWORDS_ASSIGNMENT_ENTRY.Scalpel_and_Screwdriver,
|
||||||
)
|
)
|
||||||
KEYWORDS_ASSIGNMENT_EVENT_GROUP.Space_Station_Task_Force.entries = (
|
KEYWORDS_ASSIGNMENT_EVENT_GROUP.All_About_Boothill.entries = (
|
||||||
KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Activate_Genetic_Samples,
|
KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Activate_Genetic_Samples,
|
||||||
KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Reproduce_Experimental_Data,
|
KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Reproduce_Experimental_Data,
|
||||||
KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Burned_Warehouse,
|
KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Burned_Warehouse,
|
||||||
@ -60,7 +60,7 @@ for group in (
|
|||||||
KEYWORDS_ASSIGNMENT_GROUP.Character_Materials,
|
KEYWORDS_ASSIGNMENT_GROUP.Character_Materials,
|
||||||
KEYWORDS_ASSIGNMENT_GROUP.EXP_Materials_Credits,
|
KEYWORDS_ASSIGNMENT_GROUP.EXP_Materials_Credits,
|
||||||
KEYWORDS_ASSIGNMENT_GROUP.Synthesis_Materials,
|
KEYWORDS_ASSIGNMENT_GROUP.Synthesis_Materials,
|
||||||
KEYWORDS_ASSIGNMENT_EVENT_GROUP.Space_Station_Task_Force,
|
KEYWORDS_ASSIGNMENT_EVENT_GROUP.All_About_Boothill,
|
||||||
):
|
):
|
||||||
for entry in group.entries:
|
for entry in group.entries:
|
||||||
assert entry.group is None
|
assert entry.group is None
|
||||||
|
@ -12,3 +12,12 @@ Space_Station_Task_Force = AssignmentEventGroup(
|
|||||||
jp='ステーション特派',
|
jp='ステーション特派',
|
||||||
es='Comando de la Estación Espacial',
|
es='Comando de la Estación Espacial',
|
||||||
)
|
)
|
||||||
|
All_About_Boothill = AssignmentEventGroup(
|
||||||
|
id=2,
|
||||||
|
name='All_About_Boothill',
|
||||||
|
cn='关于波提欧的一切…',
|
||||||
|
cht='關於波提歐的一切……',
|
||||||
|
en='All About Boothill...',
|
||||||
|
jp='ブートヒルに関するすべて…',
|
||||||
|
es='Todo sobre Boothill...',
|
||||||
|
)
|
||||||
|
@ -8,13 +8,14 @@ from module.base.timer import Timer
|
|||||||
from module.exception import ScriptError
|
from module.exception import ScriptError
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
from module.ocr.ocr import DigitCounter, Duration, Ocr
|
from module.ocr.ocr import DigitCounter, Duration, Ocr
|
||||||
from tasks.dungeon.ui import DungeonTabSwitch as Switch
|
|
||||||
from module.ui.draggable_list import DraggableList
|
from module.ui.draggable_list import DraggableList
|
||||||
from tasks.assignment.assets.assets_assignment_claim import CLAIM
|
from tasks.assignment.assets.assets_assignment_claim import CLAIM
|
||||||
from tasks.assignment.assets.assets_assignment_dispatch import EMPTY_SLOT
|
from tasks.assignment.assets.assets_assignment_dispatch import EMPTY_SLOT
|
||||||
from tasks.assignment.assets.assets_assignment_ui import *
|
from tasks.assignment.assets.assets_assignment_ui import *
|
||||||
from tasks.assignment.keywords import *
|
from tasks.assignment.keywords import *
|
||||||
|
from tasks.base.assets.assets_base_page import ASSIGNMENT_CHECK
|
||||||
from tasks.base.ui import UI
|
from tasks.base.ui import UI
|
||||||
|
from tasks.dungeon.ui import DungeonTabSwitch as Switch
|
||||||
|
|
||||||
|
|
||||||
class AssignmentStatus(Enum):
|
class AssignmentStatus(Enum):
|
||||||
@ -31,17 +32,20 @@ class AssignmentOcr(Ocr):
|
|||||||
|
|
||||||
OCR_REPLACE = {
|
OCR_REPLACE = {
|
||||||
'cn': [
|
'cn': [
|
||||||
(KEYWORDS_ASSIGNMENT_ENTRY.Winter_Soldiers.name, '[黑]冬的战士们'),
|
(KEYWORDS_ASSIGNMENT_ENTRY.Winter_Soldiers, '[黑]冬的战士们'),
|
||||||
(KEYWORDS_ASSIGNMENT_ENTRY.Born_to_Obey.name, '[牛]而服从'),
|
(KEYWORDS_ASSIGNMENT_ENTRY.Born_to_Obey, '[牛]而服从'),
|
||||||
(KEYWORDS_ASSIGNMENT_ENTRY.Root_Out_the_Turpitude.name,
|
(KEYWORDS_ASSIGNMENT_ENTRY.Root_Out_the_Turpitude,
|
||||||
'根除恶[擎薯尊掌鞋]?'),
|
'根除恶[擎薯尊掌鞋]?'),
|
||||||
(KEYWORDS_ASSIGNMENT_ENTRY.Akashic_Records.name, '阿[未][夏复]记录'),
|
(KEYWORDS_ASSIGNMENT_ENTRY.Akashic_Records, '阿[未][夏复]记录'),
|
||||||
(KEYWORDS_ASSIGNMENT_ENTRY.Legend_of_the_Puppet_Master.name, '^师传说'),
|
(KEYWORDS_ASSIGNMENT_ENTRY.Legend_of_the_Puppet_Master, '^师传说'),
|
||||||
(KEYWORDS_ASSIGNMENT_ENTRY.The_Wages_of_Humanity.name, '[赠]养人类'),
|
(KEYWORDS_ASSIGNMENT_ENTRY.The_Wages_of_Humanity, '[赠]养人类'),
|
||||||
|
(KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Car_Thief, '.*的偷车贼.*'),
|
||||||
|
(KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Synesthesia_Beacon_Function_Iteration, '联觉信标功能[送]代'),
|
||||||
],
|
],
|
||||||
'en': [
|
'en': [
|
||||||
# (KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Food_Improvement_Plan.name,
|
# (KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Food_Improvement_Plan.name,
|
||||||
# 'Food\s*[I]{0}mprovement Plan'),
|
# 'Food\s*[I]{0}mprovement Plan'),
|
||||||
|
(KEYWORDS_ASSIGNMENT_EVENT_ENTRY.Car_Thief, '.*Car Thief.*'),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +54,10 @@ class AssignmentOcr(Ocr):
|
|||||||
rules = AssignmentOcr.OCR_REPLACE.get(self.lang)
|
rules = AssignmentOcr.OCR_REPLACE.get(self.lang)
|
||||||
if rules is None:
|
if rules is None:
|
||||||
return None
|
return None
|
||||||
return re.compile('|'.join('(?P<%s>%s)' % pair for pair in rules))
|
return re.compile('|'.join(
|
||||||
|
f'(?P<{kw.name}>{pat})'
|
||||||
|
for kw, pat in rules
|
||||||
|
))
|
||||||
|
|
||||||
def filter_detected(self, result) -> bool:
|
def filter_detected(self, result) -> bool:
|
||||||
# Drop duration rows
|
# Drop duration rows
|
||||||
@ -78,17 +85,17 @@ class AssignmentOcr(Ocr):
|
|||||||
matched = self.ocr_regex.fullmatch(result)
|
matched = self.ocr_regex.fullmatch(result)
|
||||||
if matched is None:
|
if matched is None:
|
||||||
return result
|
return result
|
||||||
keyword_lang = self.lang
|
|
||||||
for keyword_class in (
|
for keyword_class in (
|
||||||
KEYWORDS_ASSIGNMENT_ENTRY,
|
KEYWORDS_ASSIGNMENT_ENTRY,
|
||||||
KEYWORDS_ASSIGNMENT_EVENT_ENTRY,
|
KEYWORDS_ASSIGNMENT_EVENT_ENTRY,
|
||||||
):
|
):
|
||||||
matched = getattr(keyword_class, matched.lastgroup, None)
|
kw = getattr(keyword_class, matched.lastgroup, None)
|
||||||
if matched is not None:
|
if kw is not None:
|
||||||
|
matched = kw
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise ScriptError(f'No keyword found for {matched.lastgroup}')
|
raise ScriptError(f'No keyword found for {matched.lastgroup}')
|
||||||
matched = getattr(matched, keyword_lang)
|
matched = getattr(matched, self.lang)
|
||||||
logger.attr(name=f'{self.name} after_process',
|
logger.attr(name=f'{self.name} after_process',
|
||||||
text=f'{result} -> {matched}')
|
text=f'{result} -> {matched}')
|
||||||
return matched
|
return matched
|
||||||
@ -98,10 +105,15 @@ ASSIGNMENT_GROUP_SWITCH = Switch(
|
|||||||
'AssignmentGroupSwitch',
|
'AssignmentGroupSwitch',
|
||||||
is_selector=True
|
is_selector=True
|
||||||
)
|
)
|
||||||
|
# ASSIGNMENT_GROUP_SWITCH.add_state(
|
||||||
|
# KEYWORDS_ASSIGNMENT_EVENT_GROUP.Space_Station_Task_Force,
|
||||||
|
# check_button=SPACE_STATION_TASK_FORCE_CHECK,
|
||||||
|
# click_button=SPACE_STATION_TASK_FORCE_CLICK
|
||||||
|
# )
|
||||||
ASSIGNMENT_GROUP_SWITCH.add_state(
|
ASSIGNMENT_GROUP_SWITCH.add_state(
|
||||||
KEYWORDS_ASSIGNMENT_EVENT_GROUP.Space_Station_Task_Force,
|
KEYWORDS_ASSIGNMENT_EVENT_GROUP.All_About_Boothill,
|
||||||
check_button=SPACE_STATION_TASK_FORCE_CHECK,
|
check_button=ALL_ABOUT_BOOTHILL_CHECK,
|
||||||
click_button=SPACE_STATION_TASK_FORCE_CLICK
|
click_button=ALL_ABOUT_BOOTHILL_CLICK
|
||||||
)
|
)
|
||||||
ASSIGNMENT_GROUP_SWITCH.add_state(
|
ASSIGNMENT_GROUP_SWITCH.add_state(
|
||||||
KEYWORDS_ASSIGNMENT_GROUP.Character_Materials,
|
KEYWORDS_ASSIGNMENT_GROUP.Character_Materials,
|
||||||
@ -174,7 +186,7 @@ class AssignmentUI(UI):
|
|||||||
|
|
||||||
def _wait_until_group_loaded(self):
|
def _wait_until_group_loaded(self):
|
||||||
skip_first_screenshot = True
|
skip_first_screenshot = True
|
||||||
timeout = Timer(2, count=3).start()
|
timeout = Timer(3, count=3).start()
|
||||||
while 1:
|
while 1:
|
||||||
if skip_first_screenshot:
|
if skip_first_screenshot:
|
||||||
skip_first_screenshot = False
|
skip_first_screenshot = False
|
||||||
@ -201,13 +213,17 @@ class AssignmentUI(UI):
|
|||||||
if timeout.reached():
|
if timeout.reached():
|
||||||
logger.warning('Wait entry loaded timeout')
|
logger.warning('Wait entry loaded timeout')
|
||||||
break
|
break
|
||||||
if self.image_color_count(ENTRY_LOADED, (35, 35, 35), count=800):
|
if self.appear(ASSIGNMENT_CHECK) and \
|
||||||
|
self.image_color_count(ENTRY_LOADED, (35, 35, 35), count=800):
|
||||||
logger.info('Entry loaded')
|
logger.info('Entry loaded')
|
||||||
break
|
break
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _limit_status(self) -> tuple[int, int, int]:
|
def _limit_status(self) -> tuple[int, int, int]:
|
||||||
self.device.screenshot()
|
self.device.screenshot()
|
||||||
|
if isinstance(ASSIGNMENT_GROUP_SWITCH.get(self), AssignmentEventGroup):
|
||||||
|
ASSIGNMENT_GROUP_SWITCH.set(
|
||||||
|
KEYWORDS_ASSIGNMENT_GROUP.Character_Materials, self)
|
||||||
current, remain, total = DigitCounter(
|
current, remain, total = DigitCounter(
|
||||||
OCR_ASSIGNMENT_LIMIT).ocr_single_line(self.device.image)
|
OCR_ASSIGNMENT_LIMIT).ocr_single_line(self.device.image)
|
||||||
if total and current <= total:
|
if total and current <= total:
|
||||||
|
@ -156,11 +156,6 @@ class CombatSupport(UI):
|
|||||||
self.interval_reset(POPUP_CANCEL)
|
self.interval_reset(POPUP_CANCEL)
|
||||||
continue
|
continue
|
||||||
if self.appear(COMBAT_SUPPORT_LIST, interval=2):
|
if self.appear(COMBAT_SUPPORT_LIST, interval=2):
|
||||||
scroll = AdaptiveScroll(area=COMBAT_SUPPORT_LIST_SCROLL.area,
|
|
||||||
name=COMBAT_SUPPORT_LIST_SCROLL.name)
|
|
||||||
if not scroll.appear(main=self):
|
|
||||||
self.interval_clear(COMBAT_SUPPORT_LIST)
|
|
||||||
continue
|
|
||||||
if not selected_support and support_character_name != "FirstCharacter":
|
if not selected_support and support_character_name != "FirstCharacter":
|
||||||
self._search_support(support_character_name) # Search support
|
self._search_support(support_character_name) # Search support
|
||||||
selected_support = True
|
selected_support = True
|
||||||
|
@ -591,7 +591,9 @@ class DungeonUI(DungeonState):
|
|||||||
break
|
break
|
||||||
|
|
||||||
# Additional
|
# Additional
|
||||||
pass
|
# Popup that confirm character switch
|
||||||
|
if self.handle_popup_confirm('DUNGEON_ENTER'):
|
||||||
|
continue
|
||||||
|
|
||||||
# Click teleport
|
# Click teleport
|
||||||
if self.appear(page_guide.check_button, interval=1):
|
if self.appear(page_guide.check_button, interval=1):
|
||||||
|