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

Compare commits

..

No commits in common. "71da6fd996214e6f5a9c436fab42ef1317d556fa" and "32cee3f6b5ea57042f22544aee6a5d38441c177d" have entirely different histories.

11 changed files with 42 additions and 132 deletions

View File

@ -12,7 +12,7 @@
The script is still under active development. The following features have been implemented: The script is still under active development. The following features have been implemented:
- [x] **Cafe** Claim rewards / Interact / Invitation / Second floor - [x] **Cafe** Claim rewards / Interact / Second floor
- [x] **Club** Claim AP - [x] **Club** Claim AP
- [x] **Mailbox** Claim rewards - [x] **Mailbox** Claim rewards
- [x] **Bounty** Auto sweep - [x] **Bounty** Auto sweep

View File

@ -12,7 +12,7 @@
当前脚本还在活跃开发中,已经实现的功能有: 当前脚本还在活跃开发中,已经实现的功能有:
- [x] **咖啡厅** 领取奖励 / 互动 / 邀请 / 第二咖啡厅 - [x] **咖啡厅** 领取奖励 / 互动 / 第二咖啡厅
- [x] **公会** 领取体力 - [x] **公会** 领取体力
- [x] **邮箱** 领取奖励 - [x] **邮箱** 领取奖励
- [x] **悬赏通缉** 自动扫荡 - [x] **悬赏通缉** 自动扫荡

View File

@ -81,15 +81,15 @@
"OnError": "skip" "OnError": "skip"
}, },
"Highway": { "Highway": {
"Stage": 0, "Stage": 1,
"Count": 2 "Count": 2
}, },
"DesertRailroad": { "DesertRailroad": {
"Stage": 0, "Stage": 1,
"Count": 2 "Count": 2
}, },
"Schoolhouse": { "Schoolhouse": {
"Stage": 0, "Stage": 1,
"Count": 2 "Count": 2
} }
}, },
@ -104,15 +104,15 @@
"OnError": "skip" "OnError": "skip"
}, },
"Trinity": { "Trinity": {
"Stage": 0, "Stage": 1,
"Count": 2 "Count": 2
}, },
"Gehenna": { "Gehenna": {
"Stage": 0, "Stage": 1,
"Count": 2 "Count": 2
}, },
"Millennium": { "Millennium": {
"Stage": 0, "Stage": 1,
"Count": 2 "Count": 2
} }
}, },

View File

@ -332,9 +332,8 @@
"Highway": { "Highway": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 0, "value": 1,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@ -354,9 +353,8 @@
"DesertRailroad": { "DesertRailroad": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 0, "value": 1,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@ -376,9 +374,8 @@
"Schoolhouse": { "Schoolhouse": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 0, "value": 1,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@ -435,9 +432,8 @@
"Trinity": { "Trinity": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 0, "value": 1,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@ -452,9 +448,8 @@
"Gehenna": { "Gehenna": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 0, "value": 1,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,
@ -469,9 +464,8 @@
"Millennium": { "Millennium": {
"Stage": { "Stage": {
"type": "select", "type": "select",
"value": 0, "value": 1,
"option": [ "option": [
0,
1, 1,
2, 2,
3, 3,

View File

@ -100,18 +100,18 @@ Bounty:
Highway: Highway:
Stage: Stage:
value: 0 value: 1
option: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Count: 2 Count: 2
DesertRailroad: DesertRailroad:
Stage: Stage:
value: 0 value: 1
option: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Count: 2 Count: 2
Schoolhouse: Schoolhouse:
Stage: Stage:
value: 0 value: 1
option: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ] option: [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Count: 2 Count: 2
Scrimmage: Scrimmage:
@ -121,18 +121,18 @@ Scrimmage:
Trinity: Trinity:
Stage: Stage:
value: 0 value: 1
option: [ 0, 1, 2, 3, 4 ] option: [ 1, 2, 3, 4 ]
Count: 2 Count: 2
Gehenna: Gehenna:
Stage: Stage:
value: 0 value: 1
option: [ 0, 1, 2, 3, 4 ] option: [ 1, 2, 3, 4 ]
Count: 2 Count: 2
Millennium: Millennium:
Stage: Stage:
value: 0 value: 1
option: [ 0, 1, 2, 3, 4 ] option: [ 1, 2, 3, 4 ]
Count: 2 Count: 2
TacticalChallenge: TacticalChallenge:

View File

@ -56,30 +56,30 @@ class GeneratedConfig:
Bounty_OnError = 'skip' # stop, skip Bounty_OnError = 'skip' # stop, skip
# Group `Highway` # Group `Highway`
Highway_Stage = 0 # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Highway_Stage = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
Highway_Count = 2 Highway_Count = 2
# Group `DesertRailroad` # Group `DesertRailroad`
DesertRailroad_Stage = 0 # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 DesertRailroad_Stage = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
DesertRailroad_Count = 2 DesertRailroad_Count = 2
# Group `Schoolhouse` # Group `Schoolhouse`
Schoolhouse_Stage = 0 # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 Schoolhouse_Stage = 1 # 1, 2, 3, 4, 5, 6, 7, 8, 9
Schoolhouse_Count = 2 Schoolhouse_Count = 2
# Group `Scrimmage` # Group `Scrimmage`
Scrimmage_OnError = 'skip' # stop, skip Scrimmage_OnError = 'skip' # stop, skip
# Group `Trinity` # Group `Trinity`
Trinity_Stage = 0 # 0, 1, 2, 3, 4 Trinity_Stage = 1 # 1, 2, 3, 4
Trinity_Count = 2 Trinity_Count = 2
# Group `Gehenna` # Group `Gehenna`
Gehenna_Stage = 0 # 0, 1, 2, 3, 4 Gehenna_Stage = 1 # 1, 2, 3, 4
Gehenna_Count = 2 Gehenna_Count = 2
# Group `Millennium` # Group `Millennium`
Millennium_Stage = 0 # 0, 1, 2, 3, 4 Millennium_Stage = 1 # 1, 2, 3, 4
Millennium_Count = 2 Millennium_Count = 2
# Group `TacticalChallenge` # Group `TacticalChallenge`

View File

@ -273,7 +273,6 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Overpass A", "1": "01 - Overpass A",
"2": "02 - Overpass B", "2": "02 - Overpass B",
"3": "03 - Overpass C", "3": "03 - Overpass C",
@ -297,7 +296,6 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Abandoned Train A", "1": "01 - Abandoned Train A",
"2": "02 - Abandoned Train B", "2": "02 - Abandoned Train B",
"3": "03 - Abandoned Train C", "3": "03 - Abandoned Train C",
@ -321,7 +319,6 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Besieged Classroom A", "1": "01 - Besieged Classroom A",
"2": "02 - Besieged Classroom B", "2": "02 - Besieged Classroom B",
"3": "03 - Besieged Classroom C", "3": "03 - Besieged Classroom C",
@ -357,7 +354,6 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Trinity A", "1": "01 - Trinity A",
"2": "02 - Trinity B", "2": "02 - Trinity B",
"3": "03 - Trinity C", "3": "03 - Trinity C",
@ -376,7 +372,6 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Gehenna A", "1": "01 - Gehenna A",
"2": "02 - Gehenna B", "2": "02 - Gehenna B",
"3": "03 - Gehenna C", "3": "03 - Gehenna C",
@ -395,7 +390,6 @@
"Stage": { "Stage": {
"name": "Select Stage", "name": "Select Stage",
"help": "", "help": "",
"0": "Auto select",
"1": "01 - Millennium A", "1": "01 - Millennium A",
"2": "02 - Millennium B", "2": "02 - Millennium B",
"3": "03 - Millennium C", "3": "03 - Millennium C",

View File

@ -273,7 +273,6 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 高架公路 A", "1": "01 - 高架公路 A",
"2": "02 - 高架公路 B", "2": "02 - 高架公路 B",
"3": "03 - 高架公路 C", "3": "03 - 高架公路 C",
@ -297,7 +296,6 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 被遗弃的列车 A", "1": "01 - 被遗弃的列车 A",
"2": "02 - 被遗弃的列车 B", "2": "02 - 被遗弃的列车 B",
"3": "03 - 被遗弃的列车 C", "3": "03 - 被遗弃的列车 C",
@ -321,7 +319,6 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 被袭击的教室 A", "1": "01 - 被袭击的教室 A",
"2": "02 - 被袭击的教室 B", "2": "02 - 被袭击的教室 B",
"3": "03 - 被袭击的教室 C", "3": "03 - 被袭击的教室 C",
@ -357,7 +354,6 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 三一 A", "1": "01 - 三一 A",
"2": "02 - 三一 B", "2": "02 - 三一 B",
"3": "03 - 三一 C", "3": "03 - 三一 C",
@ -376,7 +372,6 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 格黑娜 A", "1": "01 - 格黑娜 A",
"2": "02 - 格黑娜 B", "2": "02 - 格黑娜 B",
"3": "03 - 格黑娜 C", "3": "03 - 格黑娜 C",
@ -395,7 +390,6 @@
"Stage": { "Stage": {
"name": "选择关卡", "name": "选择关卡",
"help": "", "help": "",
"0": "自动选择",
"1": "01 - 千年 A", "1": "01 - 千年 A",
"2": "02 - 千年 B", "2": "02 - 千年 B",
"3": "03 - 千年 C", "3": "03 - 千年 C",

View File

@ -22,8 +22,6 @@ class BountyUI(UI):
return False return False
def enter_stage(self, index: int) -> bool: def enter_stage(self, index: int) -> bool:
if not index:
index = BOUNTY_LIST.insight_max_sweepable_index(self)
if BOUNTY_LIST.select_index_enter(self, index): if BOUNTY_LIST.select_index_enter(self, index):
return True return True
return False return False

View File

@ -22,8 +22,6 @@ class ScrimmageUI(UI):
return False return False
def enter_stage(self, index: int) -> bool: def enter_stage(self, index: int) -> bool:
if not index:
index = SCRIMMAGE_LIST.insight_max_sweepable_index(self)
if SCRIMMAGE_LIST.select_index_enter(self, index, insight=False): if SCRIMMAGE_LIST.select_index_enter(self, index, insight=False):
return True return True
return False return False

View File

@ -1,5 +1,3 @@
import re
import numpy as np import numpy as np
from module.base.base import ModuleBase from module.base.base import ModuleBase
@ -33,7 +31,7 @@ class StageList:
self.current_index_min = 1 self.current_index_min = 1
self.current_index_max = 1 self.current_index_max = 1
self.current_indexes: list[tuple[str, tuple]] = [] self.current_indexes = []
def __str__(self): def __str__(self):
return f'StageList({self.name})' return f'StageList({self.name})'
@ -48,14 +46,11 @@ class StageList:
@property @property
def _indexes(self) -> list[int]: def _indexes(self) -> list[int]:
return [int(x[0]) for x in self.current_indexes] return list(map(lambda x: int(x.ocr_text), self.current_indexes))
def load_stage_indexes(self, main: ModuleBase): def load_stage_indexes(self, main: ModuleBase):
self.current_indexes = list( self.current_indexes = list(
filter( filter(lambda x: x.ocr_text.isdigit(), self.index_ocr.detect_and_ocr(main.device.image))
lambda x: re.match(r'^\d{1,2}-?\d?$', x[0]),
map(lambda x: (x.ocr_text, x.box), self.index_ocr.detect_and_ocr(main.device.image))
)
) )
if not self.current_indexes: if not self.current_indexes:
logger.warning(f'No valid index in {self.index_ocr.name}') logger.warning(f'No valid index in {self.index_ocr.name}')
@ -131,79 +126,13 @@ class StageList:
timeout=Timer(1.5, 5) timeout=Timer(1.5, 5)
) )
def insight_max_sweepable_index(self, main: ModuleBase, skip_first_screenshot=True) -> int:
"""
Args:
main:
skip_first_screenshot:
Returns:
Index of max sweepable stage
"""
logger.info('Insight sweepable index')
max_sweepable_index = 0
last_max_sweepable_index = 0
while 1:
if skip_first_screenshot:
skip_first_screenshot = False
else:
main.device.screenshot()
self.load_stage_indexes(main=main)
sweepable_index = next(
filter(
lambda x: not self.is_sweepable(main, self.search_box(x[-1][:2])),
self.current_indexes
), None
)
# all sweepable
if sweepable_index is None:
logger.info('All sweepable')
max_sweepable_index = self.current_index_max
self.swipe_page(self.swipe_direction, main)
if max_sweepable_index == last_max_sweepable_index:
logger.info(f'Max sweepable index: {max_sweepable_index}')
return max_sweepable_index
last_max_sweepable_index = max_sweepable_index
# all not sweepable
elif int(sweepable_index[0]) == self.current_index_min:
logger.info('All not sweepable')
if int(sweepable_index[0]) == 1:
logger.warning('No sweepable index')
return 0
self.swipe_page(self.swipe_direction, main, reverse=True)
else:
logger.info(f'Sweepable index: {int(sweepable_index[0]) - 1}')
return int(sweepable_index[0]) - 1
main.wait_until_stable(
self.stage.button,
timer=Timer(0, 0),
timeout=Timer(1.5, 5)
)
def is_sweepable(self, main: ModuleBase, search_box) -> bool:
self.sweepable.load_search(search_box)
return main.appear(self.sweepable, similarity=0.8)
def search_box(
self,
index_cord: tuple[int, int],
padding: tuple[int, int] = (-20, -15)
) -> tuple[int, int, int, int]:
stage_item_box = area_pad((*padding, *area_size(self.stage_item)))
return area_offset(stage_item_box, index_cord)
def select_index_enter( def select_index_enter(
self, self,
main: ModuleBase, main: ModuleBase,
index: int, index: int,
insight: bool = True, insight: bool = True,
sweepable: bool = True, sweepable: bool = True,
padding: tuple[int, int] = (-20, -15), offset: tuple[int, int] = (-20, -15),
skip_first_screenshot: bool = True, skip_first_screenshot: bool = True,
interval: int = 1.5 interval: int = 1.5
) -> bool: ) -> bool:
@ -225,14 +154,17 @@ class StageList:
self.load_stage_indexes(main=main) self.load_stage_indexes(main=main)
# find box of index # find box of index
index_box = next(filter(lambda x: int(x[0]) == index, self.current_indexes), None) index_box = next(filter(lambda x: int(x.ocr_text) == index, self.current_indexes), None)
if index_box is None: if index_box is None:
logger.warning(f'No index {index} in {self.index_ocr.name}') logger.warning(f'No index {index} in {self.index_ocr.name}')
continue continue
search_box = self.search_box(index_box[-1][:2], padding) stage_item_box = area_pad((*offset, *area_size(self.stage_item)))
if sweepable and not self.is_sweepable(main, search_box): search_box = area_offset(stage_item_box, index_box.box[:2])
self.sweepable.load_search(search_box)
if sweepable and not main.appear(self.sweepable):
logger.warning(f'Index {index} is not sweepable') logger.warning(f'Index {index} is not sweepable')
return False return False