1
0
mirror of https://github.com/TheFunny/ArisuAutoSweeper synced 2025-12-16 19:55:12 +00:00

feat: shop

This commit is contained in:
RedDeadDepresso 2023-12-19 11:34:06 +00:00
parent 83da63ff8e
commit e17c0a0e44
34 changed files with 1155 additions and 140 deletions

5
aas.py
View File

@ -50,11 +50,14 @@ class ArisuAutoSweeper(AzurLaneAutoScript):
from tasks.task.task import Task
Task(config=self.config, device=self.device).run()
def shop(self):
from tasks.shop.shop import Shop
Shop(config=self.config, device=self.device).run()
def data_update(self):
from tasks.item.data_update import DataUpdate
DataUpdate(config=self.config, device=self.device).run()
if __name__ == '__main__':
aas = ArisuAutoSweeper('aas')
aas.loop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
assets/en/shop/PURCHASE.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
assets/en/shop/REFRESH.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
assets/en/shop/TC_OFF.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

BIN
assets/en/shop/TC_ON.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -33,6 +33,22 @@
"ServerUpdate": "04:00"
}
},
"DataUpdate": {
"Scheduler": {
"Enable": true,
"NextRun": "2020-01-01 00:00:00",
"Command": "DataUpdate",
"ServerUpdate": "04:00"
},
"ItemStorage": {
"AP": {},
"Credit": {},
"Pyroxene": {},
"BountyTicket": {},
"ScrimmageTicket": {},
"TacticalChallengeTicket": {}
}
},
"Cafe": {
"Scheduler": {
"Enable": true,
@ -54,20 +70,55 @@
"Substitute": false
}
},
"DataUpdate": {
"Shop": {
"Scheduler": {
"Enable": true,
"Enable": false,
"NextRun": "2020-01-01 00:00:00",
"Command": "DataUpdate",
"Command": "Shop",
"ServerUpdate": "04:00"
},
"ItemStorage": {
"AP": {},
"Credit": {},
"Pyroxene": {},
"BountyTicket": {},
"ScrimmageTicket": {},
"TacticalChallengeTicket": {}
"NormalShop": {
"Enable": false,
"Purchases": 1,
"1": false,
"2": false,
"3": false,
"4": false,
"5": false,
"6": false,
"7": false,
"8": false,
"9": false,
"10": false,
"11": false,
"12": false,
"13": false,
"14": false,
"15": false,
"16": false,
"17": false,
"18": false,
"19": false,
"20": false
},
"TacticalChallengeShop": {
"Enable": false,
"Purchases": 1,
"1": false,
"2": false,
"3": false,
"4": false,
"5": false,
"6": false,
"7": false,
"8": false,
"9": false,
"10": false,
"11": false,
"12": false,
"13": false,
"14": false,
"15": false
}
},
"Bounty": {

View File

@ -162,6 +162,85 @@
}
}
},
"DataUpdate": {
"Scheduler": {
"Enable": {
"type": "state",
"value": true,
"option": [
true
],
"option_bold": [
true
]
},
"NextRun": {
"type": "datetime",
"value": "2020-01-01 00:00:00",
"validate": "datetime"
},
"Command": {
"type": "input",
"value": "DataUpdate",
"display": "hide"
},
"ServerUpdate": {
"type": "input",
"value": "04:00",
"display": "hide"
}
},
"ItemStorage": {
"AP": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredAP",
"order": 1,
"color": "#62ea6e"
},
"Credit": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredInt",
"order": 2,
"color": "#fdec00"
},
"Pyroxene": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredInt",
"order": 3,
"color": "#21befc"
},
"BountyTicket": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredBountyTicket",
"order": 4,
"color": "#94cb44"
},
"ScrimmageTicket": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredScrimmageTicket",
"order": 5,
"color": "#f86c6a"
},
"TacticalChallengeTicket": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredTacticalChallengeTicket",
"order": 6,
"color": "#7ac8e5"
}
}
},
"Cafe": {
"Scheduler": {
"Enable": {
@ -239,16 +318,14 @@
}
}
},
"DataUpdate": {
"Shop": {
"Scheduler": {
"Enable": {
"type": "state",
"value": true,
"type": "checkbox",
"value": false,
"option": [
true
],
"option_bold": [
true
true,
false
]
},
"NextRun": {
@ -258,7 +335,7 @@
},
"Command": {
"type": "input",
"value": "DataUpdate",
"value": "Shop",
"display": "hide"
},
"ServerUpdate": {
@ -267,54 +344,176 @@
"display": "hide"
}
},
"ItemStorage": {
"AP": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredAP",
"order": 1,
"color": "#62ea6e"
"NormalShop": {
"Enable": {
"type": "checkbox",
"value": false
},
"Credit": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredInt",
"order": 2,
"color": "#fdec00"
"Purchases": {
"type": "select",
"value": 1,
"option": [
1,
2,
3,
4
]
},
"Pyroxene": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredInt",
"order": 3,
"color": "#21befc"
"1": {
"type": "checkbox",
"value": false
},
"BountyTicket": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredBountyTicket",
"order": 4,
"color": "#94cb44"
"2": {
"type": "checkbox",
"value": false
},
"ScrimmageTicket": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredScrimmageTicket",
"order": 5,
"color": "#f86c6a"
"3": {
"type": "checkbox",
"value": false
},
"TacticalChallengeTicket": {
"type": "stored",
"value": {},
"display": "hide",
"stored": "StoredTacticalChallengeTicket",
"order": 6,
"color": "#7ac8e5"
"4": {
"type": "checkbox",
"value": false
},
"5": {
"type": "checkbox",
"value": false
},
"6": {
"type": "checkbox",
"value": false
},
"7": {
"type": "checkbox",
"value": false
},
"8": {
"type": "checkbox",
"value": false
},
"9": {
"type": "checkbox",
"value": false
},
"10": {
"type": "checkbox",
"value": false
},
"11": {
"type": "checkbox",
"value": false
},
"12": {
"type": "checkbox",
"value": false
},
"13": {
"type": "checkbox",
"value": false
},
"14": {
"type": "checkbox",
"value": false
},
"15": {
"type": "checkbox",
"value": false
},
"16": {
"type": "checkbox",
"value": false
},
"17": {
"type": "checkbox",
"value": false
},
"18": {
"type": "checkbox",
"value": false
},
"19": {
"type": "checkbox",
"value": false
},
"20": {
"type": "checkbox",
"value": false
}
},
"TacticalChallengeShop": {
"Enable": {
"type": "checkbox",
"value": false
},
"Purchases": {
"type": "select",
"value": 1,
"option": [
1,
2,
3,
4
]
},
"1": {
"type": "checkbox",
"value": false
},
"2": {
"type": "checkbox",
"value": false
},
"3": {
"type": "checkbox",
"value": false
},
"4": {
"type": "checkbox",
"value": false
},
"5": {
"type": "checkbox",
"value": false
},
"6": {
"type": "checkbox",
"value": false
},
"7": {
"type": "checkbox",
"value": false
},
"8": {
"type": "checkbox",
"value": false
},
"9": {
"type": "checkbox",
"value": false
},
"10": {
"type": "checkbox",
"value": false
},
"11": {
"type": "checkbox",
"value": false
},
"12": {
"type": "checkbox",
"value": false
},
"13": {
"type": "checkbox",
"value": false
},
"14": {
"type": "checkbox",
"value": false
},
"15": {
"type": "checkbox",
"value": false
}
}
},

View File

@ -140,6 +140,53 @@ TacticalChallenge:
value: 0
option: [ 0, 1, 2, 3 ]
NormalShop:
Enable: false
Purchases:
value: 1
option: [ 1, 2, 3, 4 ]
"1": false
"2": false
"3": false
"4": false
"5": false
"6": false
"7": false
"8": false
"9": false
"10": false
"11": false
"12": false
"13": false
"14": false
"15": false
"16": false
"17": false
"18": false
"19": false
"20": false
TacticalChallengeShop:
Enable: false
Purchases:
value: 1
option: [ 1, 2, 3, 4 ]
"1": false
"2": false
"3": false
"4": false
"5": false
"6": false
"7": false
"8": false
"9": false
"10": false
"11": false
"12": false
"13": false
"14": false
"15": false
ItemStorage:
AP:
stored: StoredAP

View File

@ -4,7 +4,8 @@
"page": "setting",
"tasks": [
"Alas",
"Restart"
"Restart",
"DataUpdate"
]
},
"Daily": {
@ -12,7 +13,7 @@
"page": "setting",
"tasks": [
"Cafe",
"DataUpdate"
"Shop"
]
},
"Farm": {

View File

@ -15,6 +15,9 @@ Alas:
- Optimization
Restart:
- Scheduler
DataUpdate:
- Scheduler
- ItemStorage
# ==================== Daily ====================
@ -26,10 +29,11 @@ Daily:
- Scheduler
- Cafe
- Invitation
DataUpdate:
Shop:
- Scheduler
- ItemStorage
- NormalShop
- TacticalChallengeShop
# ==================== Farm ====================
Farm:

View File

@ -85,6 +85,49 @@ class GeneratedConfig:
# Group `TacticalChallenge`
TacticalChallenge_PlayerSelect = 0 # 0, 1, 2, 3
# Group `NormalShop`
NormalShop_Enable = False
NormalShop_Purchases = 1 # 1, 2, 3, 4
NormalShop_1 = False
NormalShop_2 = False
NormalShop_3 = False
NormalShop_4 = False
NormalShop_5 = False
NormalShop_6 = False
NormalShop_7 = False
NormalShop_8 = False
NormalShop_9 = False
NormalShop_10 = False
NormalShop_11 = False
NormalShop_12 = False
NormalShop_13 = False
NormalShop_14 = False
NormalShop_15 = False
NormalShop_16 = False
NormalShop_17 = False
NormalShop_18 = False
NormalShop_19 = False
NormalShop_20 = False
# Group `TacticalChallengeShop`
TacticalChallengeShop_Enable = False
TacticalChallengeShop_Purchases = 1 # 1, 2, 3, 4
TacticalChallengeShop_1 = False
TacticalChallengeShop_2 = False
TacticalChallengeShop_3 = False
TacticalChallengeShop_4 = False
TacticalChallengeShop_5 = False
TacticalChallengeShop_6 = False
TacticalChallengeShop_7 = False
TacticalChallengeShop_8 = False
TacticalChallengeShop_9 = False
TacticalChallengeShop_10 = False
TacticalChallengeShop_11 = False
TacticalChallengeShop_12 = False
TacticalChallengeShop_13 = False
TacticalChallengeShop_14 = False
TacticalChallengeShop_15 = False
# Group `ItemStorage`
ItemStorage_AP = {}
ItemStorage_Credit = {}

View File

@ -9,7 +9,7 @@ class ManualConfig:
SCHEDULER_PRIORITY = """
Restart
> Cafe > Circle > Mail > DataUpdate > Bounty
> Scrimmage > TacticalChallenge > Task
> Scrimmage > TacticalChallenge > Task > Shop
"""
"""

View File

@ -26,12 +26,16 @@
"name": "Error Handling",
"help": ""
},
"DataUpdate": {
"name": "Dashboard Upd",
"help": ""
},
"Cafe": {
"name": "Cafe",
"help": ""
},
"DataUpdate": {
"name": "Dashboard Upd",
"Shop": {
"name": "Shop",
"help": ""
},
"Bounty": {
@ -432,6 +436,182 @@
"3": "Third"
}
},
"NormalShop": {
"_info": {
"name": "Normal Shop Settings",
"help": ""
},
"Enable": {
"name": "Enable",
"help": ""
},
"Purchases": {
"name": "Number of Purchases",
"help": "",
"1": "1",
"2": "2",
"3": "3",
"4": "4"
},
"1": {
"name": "1",
"help": "Novice Activity Report x5"
},
"2": {
"name": "2",
"help": "x5 Normal Activity Report"
},
"3": {
"name": "3",
"help": "x3 Advanced Activity Report"
},
"4": {
"name": "4",
"help": "x1 Superior Activity Report"
},
"5": {
"name": "5",
"help": "x5 Lesser Enhancement Stone"
},
"6": {
"name": "6",
"help": "x5 Normal Enhancement Stone"
},
"7": {
"name": "7",
"help": "x3 Advanced Enhancement Stone"
},
"8": {
"name": "8",
"help": "x1 Superior Enhancement Stone"
},
"9": {
"name": "9",
"help": "x5 Lesser Enhancement Stone"
},
"10": {
"name": "10",
"help": "x5 Normal Enhancement Stone"
},
"11": {
"name": "11",
"help": "x3 Advanced Enhancement Stone"
},
"12": {
"name": "12",
"help": "x1 Superior Enhancement Stone"
},
"13": {
"name": "13",
"help": "x10 Lesser Enhancement Stone"
},
"14": {
"name": "14",
"help": "x10 Normal Enhancement Stone"
},
"15": {
"name": "15",
"help": "x6 Advanced Enhancement Stone"
},
"16": {
"name": "16",
"help": "x2 Superior Enhancement Stone"
},
"17": {
"name": "17",
"help": "x1 Mandrake Seed"
},
"18": {
"name": "18",
"help": "x1 Voynich Manuscript Page"
},
"19": {
"name": "19",
"help": "x1 Broken Nimrud Lens"
},
"20": {
"name": "20",
"help": "x1 Aether Piece"
}
},
"TacticalChallengeShop": {
"_info": {
"name": "Tactical Challenge Shop Settings",
"help": ""
},
"Enable": {
"name": "Enable",
"help": ""
},
"Purchases": {
"name": "Number of Purchases",
"help": "",
"1": "1",
"2": "2",
"3": "3",
"4": "4"
},
"1": {
"name": "1",
"help": ""
},
"2": {
"name": "2",
"help": ""
},
"3": {
"name": "3",
"help": ""
},
"4": {
"name": "4",
"help": ""
},
"5": {
"name": "5",
"help": ""
},
"6": {
"name": "6",
"help": ""
},
"7": {
"name": "7",
"help": ""
},
"8": {
"name": "8",
"help": ""
},
"9": {
"name": "9",
"help": ""
},
"10": {
"name": "10",
"help": ""
},
"11": {
"name": "11",
"help": ""
},
"12": {
"name": "12",
"help": ""
},
"13": {
"name": "13",
"help": ""
},
"14": {
"name": "14",
"help": ""
},
"15": {
"name": "15",
"help": ""
}
},
"ItemStorage": {
"_info": {
"name": "ItemStorage._info.name",

View File

@ -26,13 +26,17 @@
"name": "异常处理",
"help": ""
},
"DataUpdate": {
"name": "仪表盘更新",
"help": ""
},
"Cafe": {
"name": "咖啡厅",
"help": ""
},
"DataUpdate": {
"name": "仪表盘更新",
"help": ""
"Shop": {
"name": "Task.Shop.name",
"help": "Task.Shop.help"
},
"Bounty": {
"name": "悬赏通缉",
@ -432,6 +436,182 @@
"3": "第三位"
}
},
"NormalShop": {
"_info": {
"name": "NormalShop._info.name",
"help": "NormalShop._info.help"
},
"Enable": {
"name": "NormalShop.Enable.name",
"help": "NormalShop.Enable.help"
},
"Purchases": {
"name": "NormalShop.Purchases.name",
"help": "NormalShop.Purchases.help",
"1": "1",
"2": "2",
"3": "3",
"4": "4"
},
"1": {
"name": "1",
"help": ""
},
"2": {
"name": "2",
"help": ""
},
"3": {
"name": "3",
"help": ""
},
"4": {
"name": "4",
"help": ""
},
"5": {
"name": "5",
"help": ""
},
"6": {
"name": "6",
"help": ""
},
"7": {
"name": "7",
"help": ""
},
"8": {
"name": "8",
"help": ""
},
"9": {
"name": "9",
"help": ""
},
"10": {
"name": "10",
"help": ""
},
"11": {
"name": "11",
"help": ""
},
"12": {
"name": "12",
"help": ""
},
"13": {
"name": "13",
"help": ""
},
"14": {
"name": "14",
"help": ""
},
"15": {
"name": "15",
"help": ""
},
"16": {
"name": "16",
"help": ""
},
"17": {
"name": "NormalShop.17.name",
"help": "NormalShop.17.help"
},
"18": {
"name": "NormalShop.18.name",
"help": "NormalShop.18.help"
},
"19": {
"name": "NormalShop.19.name",
"help": "NormalShop.19.help"
},
"20": {
"name": "NormalShop.20.name",
"help": "NormalShop.20.help"
}
},
"TacticalChallengeShop": {
"_info": {
"name": "TacticalChallengeShop._info.name",
"help": "TacticalChallengeShop._info.help"
},
"Enable": {
"name": "TacticalChallengeShop.Enable.name",
"help": "TacticalChallengeShop.Enable.help"
},
"Purchases": {
"name": "TacticalChallengeShop.Purchases.name",
"help": "TacticalChallengeShop.Purchases.help",
"1": "1",
"2": "2",
"3": "3",
"4": "4"
},
"1": {
"name": "1",
"help": ""
},
"2": {
"name": "2",
"help": ""
},
"3": {
"name": "3",
"help": ""
},
"4": {
"name": "4",
"help": ""
},
"5": {
"name": "5",
"help": ""
},
"6": {
"name": "6",
"help": ""
},
"7": {
"name": "7",
"help": ""
},
"8": {
"name": "8",
"help": ""
},
"9": {
"name": "9",
"help": ""
},
"10": {
"name": "10",
"help": ""
},
"11": {
"name": "11",
"help": ""
},
"12": {
"name": "12",
"help": ""
},
"13": {
"name": "13",
"help": ""
},
"14": {
"name": "14",
"help": ""
},
"15": {
"name": "15",
"help": ""
}
},
"ItemStorage": {
"_info": {
"name": "ItemStorage._info.name",

View File

@ -0,0 +1,115 @@
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 ```
CONFIRM_PURCHASE = ButtonWrapper(
name='CONFIRM_PURCHASE',
jp=None,
en=Button(
file='./assets/en/shop/CONFIRM_PURCHASE.png',
area=(467, 231, 807, 309),
search=(447, 211, 827, 329),
color=(217, 218, 219),
button=(668, 458, 865, 514),
),
)
CONFIRM_REFRESH = ButtonWrapper(
name='CONFIRM_REFRESH',
jp=None,
en=Button(
file='./assets/en/shop/CONFIRM_REFRESH.png',
area=(474, 271, 806, 306),
search=(454, 251, 826, 326),
color=(202, 203, 204),
button=(675, 434, 863, 500),
),
)
ITEM_LIST = ButtonWrapper(
name='ITEM_LIST',
jp=None,
en=Button(
file='./assets/en/shop/ITEM_LIST.png',
area=(625, 127, 1244, 610),
search=(605, 107, 1264, 630),
color=(193, 206, 213),
button=(625, 127, 1244, 610),
),
)
NORMAL_OFF = ButtonWrapper(
name='NORMAL_OFF',
jp=None,
en=Button(
file='./assets/en/shop/NORMAL_OFF.png',
area=(4, 111, 213, 167),
search=(0, 91, 233, 187),
color=(248, 248, 245),
button=(4, 111, 213, 167),
),
)
NORMAL_ON = ButtonWrapper(
name='NORMAL_ON',
jp=None,
en=Button(
file='./assets/en/shop/NORMAL_ON.png',
area=(4, 109, 212, 170),
search=(0, 89, 232, 190),
color=(57, 78, 96),
button=(4, 109, 212, 170),
),
)
OCR_REFRESH = ButtonWrapper(
name='OCR_REFRESH',
jp=None,
en=Button(
file='./assets/en/shop/OCR_REFRESH.png',
area=(712, 302, 762, 344),
search=(692, 282, 782, 364),
color=(225, 225, 226),
button=(712, 302, 762, 344),
),
)
PURCHASE = ButtonWrapper(
name='PURCHASE',
jp=None,
en=Button(
file='./assets/en/shop/PURCHASE.png',
area=(1102, 640, 1227, 684),
search=(1082, 620, 1247, 704),
color=(226, 206, 65),
button=(1102, 640, 1227, 684),
),
)
REFRESH = ButtonWrapper(
name='REFRESH',
jp=None,
en=Button(
file='./assets/en/shop/REFRESH.png',
area=(1098, 643, 1223, 682),
search=(1078, 623, 1243, 702),
color=(231, 234, 237),
button=(1098, 643, 1223, 682),
),
)
TC_OFF = ButtonWrapper(
name='TC_OFF',
jp=None,
en=Button(
file='./assets/en/shop/TC_OFF.png',
area=(2, 503, 209, 558),
search=(0, 483, 229, 578),
color=(239, 242, 244),
button=(2, 503, 209, 558),
),
)
TC_ON = ButtonWrapper(
name='TC_ON',
jp=None,
en=Button(
file='./assets/en/shop/TC_ON.png',
area=(3, 493, 208, 548),
search=(0, 473, 228, 568),
color=(62, 84, 99),
button=(3, 493, 208, 548),
),
)

118
tasks/shop/shop.py Normal file
View File

@ -0,0 +1,118 @@
from enum import Flag
from module.base.timer import Timer
from module.exception import RequestHumanTakeover
from module.logger import logger
from module.ui.switch import Switch
from tasks.base.assets.assets_base_page import BACK
from tasks.base.page import page_main, page_shop
from tasks.shop.assets.assets_shop import *
from tasks.shop.ui import ShopUI
class ShopStatus(Flag):
SELECT_SHOP = 0
SELECT_ITEMS = 1
PURCHASE = 2
REFRESH = 3
END = 4
FINISH = -1
class Shop(ShopUI):
@property
def shop_info(self):
"""Similiar to bounty_info and scrimmage_info.
Returns a list with elements the select button, check button, how many times do make purchases and the list of items"""
info = []
if self.config.NormalShop_Enable:
normal_config = self.config.cross_get(["Shop", "NormalShop"])
normal_items = [num for num in range(1, 21) if normal_config[str(num)]]
if normal_items:
SWITCH_NORMAL = Switch('NormalShop_Switch')
SWITCH_NORMAL.add_state('on', NORMAL_ON)
SWITCH_NORMAL.add_state('off', NORMAL_OFF)
info.append([SWITCH_NORMAL, self.config.NormalShop_Purchases, normal_items])
if self.config.TacticalChallengeShop_Enable:
tc_config = self.config.cross_get(["Shop", "TacticalChallengeShop"])
tc_items = [num for num in range(1, 16) if tc_config[str(num)]]
if tc_items:
SWITCH_TC = Switch('TacticalChallengeShop_Switch')
SWITCH_TC.add_state('on', TC_ON)
SWITCH_TC.add_state('off', TC_OFF)
info.append([SWITCH_TC, self.config.TacticalChallengeShop_Purchases, tc_items])
return info
@property
def valid_task(self) -> list:
task = self.shop_info
if not task:
logger.warning('Shop enabled but no task set')
return task
@property
def current_shop(self):
return self.task[0][0]
@property
def current_purchase_count(self):
return self.task[0][1]
@property
def current_item_list(self):
return self.task[0][2]
def handle_shop(self, status):
match status:
case ShopStatus.SELECT_SHOP:
if not self.task:
return ShopStatus.FINISH
if self.select_shop(self.current_shop):
self.reset_swipe_flags()
return ShopStatus.SELECT_ITEMS
case ShopStatus.SELECT_ITEMS:
self.select_items(self.current_item_list)
return ShopStatus.PURCHASE
case ShopStatus.PURCHASE:
if self.make_purchase():
return ShopStatus.REFRESH
return ShopStatus.END
case ShopStatus.REFRESH:
if self.refresh_shop(self.current_purchase_count):
return ShopStatus.SELECT_SHOP
return ShopStatus.END
case ShopStatus.END:
if self.appear(page_shop.check_button):
self.task.pop(0)
return ShopStatus.SELECT_SHOP
self.click_with_interval(BACK, interval=2)
case ShopStatus.FINISH:
return status
case _:
logger.warning(f'Invalid status: {status}')
return status
def run(self):
"""Reset the items position by going main and then shop"""
self.ui_ensure(page_main)
self.ui_ensure(page_shop)
self.task = self.valid_task
action_timer = Timer(0.5, 1)
status = ShopStatus.SELECT_SHOP
while 1:
self.device.screenshot()
if self.ui_additional():
continue
if action_timer.reached_and_reset():
logger.attr('Status', status)
status = self.handle_shop(status)
if status == ShopStatus.FINISH:
break
self.config.task_delay(server_update=True)

125
tasks/shop/ui.py Normal file
View File

@ -0,0 +1,125 @@
import numpy as np
from module.base.timer import Timer
from module.base.base import ModuleBase
from module.base.utils import area_size
from module.logger import logger
from module.ocr.ocr import DigitCounter
from tasks.base.ui import UI
from tasks.shop.assets.assets_shop import *
ITEM_POSITIONS = {
1: (650, 200), 2: (805, 200), 3: (960, 200), 4: (1110, 200),
5: (650, 460), 6: (805, 460), 7: (960, 460), 8: (1110, 460),
9: (650, 200), 10: (805, 200), 11: (960, 200), 12: (1110, 200),
13: (650, 460), 14: (805, 460), 15: (960, 460), 16: (1110, 460),
17: (650, 200), 18: (805, 200), 19: (960, 200), 20: (1110, 200),
}
class ShopUI(UI):
def __init__(self, config, device):
super().__init__(config, device)
self.click_coords = self.device.click_methods.get(self.config.Emulator_ControlMethod, self.device.click_adb)
self.swipe_vector_range = (0.65, 0.85)
self.swipe_flags = {8:False, 16: False}
self.list = ITEM_LIST
def swipe_page(self, direction: str, main: ModuleBase, vector_range=None, reverse=False):
"""
Args:
direction: up, down
main:
vector_range (tuple[float, float]):
reverse (bool):
"""
if vector_range is None:
vector_range = self.swipe_vector_range
vector = np.random.uniform(*vector_range)
width, height = area_size(self.list.button)
if direction == 'up':
vector = (0, vector * height)
elif direction == 'down':
vector = (0, -vector * height)
else:
logger.warning(f'Unknown swipe direction: {direction}')
return
if reverse:
vector = (-vector[0], -vector[1])
main.device.swipe_vector(vector, self.list.button)
def select_then_check(self, dest_enter: ButtonWrapper, dest_check: ButtonWrapper):
timer = Timer(5, 10).start()
while 1:
self.device.screenshot()
self.appear_then_click(dest_enter, interval=1)
if self.appear(dest_check):
return True
if timer.reached():
return False
def select_shop(self, shop_switch):
"""
Set skip switch to on
Returns:
True if switch is set, False if switch not found
"""
if not shop_switch.appear(main=self):
logger.info('Shop switch not found')
return False
shop_switch.set('on', main=self)
return True
def select_items(self, item_list):
for item in item_list:
if self.should_swipe(item):
self.swipe_page('down', self)
self.wait_until_stable(
self.list.button,
timer=Timer(0, 0),
timeout=Timer(1.5, 5)
)
self.click_coords(*ITEM_POSITIONS[item])
def should_swipe(self, item):
if (8 < item < 16) and not self.swipe_flags[8]:
self.swipe_flags[8] = True
return True
elif item > 16 and not self.swipe_flags[16]:
self.swipe_flags[16] = True
return True
return False
def reset_swipe_flags(self):
self.swipe_flags[8], self.swipe_flags[16] = False, False
def make_purchase(self):
if self.select_then_check(PURCHASE, CONFIRM_PURCHASE) and self.appear_then_click(CONFIRM_PURCHASE):
return True
return False
def refresh_shop(self, need_count):
"""
Refresh the shop
"""
refresh_count = self.get_refresh_count()
if refresh_count:
purchased_count = 4 - refresh_count
if need_count > purchased_count and self.appear_then_click(CONFIRM_REFRESH):
return True
return False
def get_refresh_count(self):
if not self.select_then_check(REFRESH, CONFIRM_REFRESH):
logger.warning('OCR failed due to invalid page')
return False
count, _, total = DigitCounter(OCR_REFRESH).ocr_single_line(self.device.image)
if total == 0:
logger.warning('Invalid count')
return False
return count

View File

@ -8,42 +8,20 @@ CLAIM = ButtonWrapper(
jp=None,
en=Button(
file='./assets/en/task/CLAIM.png',
area=(941, 656, 1009, 684),
search=(921, 636, 1029, 704),
color=(213, 190, 58),
area=(935, 639, 1015, 698),
search=(915, 619, 1035, 718),
color=(234, 214, 69),
button=(935, 639, 1015, 698),
),
)
CLAIMED = ButtonWrapper(
name='CLAIMED',
jp=None,
en=Button(
file='./assets/en/task/CLAIMED.png',
area=(941, 653, 1007, 682),
search=(921, 633, 1027, 702),
color=(205, 205, 204),
button=(936, 643, 1012, 698),
),
)
CLAIMED_ALL = ButtonWrapper(
name='CLAIMED_ALL',
jp=None,
en=Button(
file='./assets/en/task/CLAIMED_ALL.png',
area=(1088, 650, 1215, 687),
search=(1068, 630, 1235, 707),
color=(181, 182, 185),
button=(1052, 644, 1250, 700),
),
)
CLAIM_ALL = ButtonWrapper(
name='CLAIM_ALL',
jp=None,
en=Button(
file='./assets/en/task/CLAIM_ALL.png',
area=(1086, 652, 1216, 685),
search=(1066, 632, 1236, 705),
color=(215, 198, 64),
area=(1054, 642, 1243, 700),
search=(1034, 622, 1263, 720),
color=(236, 219, 67),
button=(1054, 642, 1243, 700),
),
)

View File

@ -1,56 +1,27 @@
from enum import Enum
from module.base.timer import Timer
from module.logger import logger
from tasks.base.page import page_task
from tasks.base.ui import UI
from tasks.task.assets.assets_task import *
class TaskStatus(Enum):
"""
Task status
"""
CLAIM_ALL = 0
CLAIM = 1
FINISHED = -1
class Task(UI):
def _handle_task(self, status):
match status:
case TaskStatus.CLAIM_ALL:
if self.match_color(CLAIM_ALL):
self.device.click(CLAIM_ALL)
logger.info("Click Claim All")
else:
return TaskStatus.CLAIM
case TaskStatus.CLAIM:
if self.match_color(CLAIM):
self.device.click(CLAIM)
logger.info("Click Claim")
else:
return TaskStatus.FINISHED
case _:
logger.warning(f"Invalid status: {status}")
return status
def run(self):
self.ui_ensure(page_task)
status = TaskStatus.CLAIM_ALL
action_timer = Timer(0.5)
action_timer = Timer(1).start()
while 1:
self.device.screenshot()
if self.ui_additional():
continue
if action_timer.reached_and_reset():
logger.attr('Status', status)
status = self._handle_task(status)
if status is TaskStatus.FINISHED:
break
if self.match_color(CLAIM_ALL):
self.device.click(CLAIM_ALL)
logger.info("Click Claim All")
continue
if self.match_color(CLAIM):
self.device.click(CLAIM)
logger.info("Click Claim")
continue
break
self.config.task_delay(server_update=True)