Add: [CN]Dossier Beacon Attack Add: [CN]Ash Beacon OneHitMode
18
alas.py
@ -103,16 +103,16 @@ class AzurLaneAutoScript:
|
||||
logger.critical(e)
|
||||
logger.critical('This is likely to be a mistake of developers, but sometimes just random issues')
|
||||
handle_notify(
|
||||
self.config.Error_OnePushConfig,
|
||||
title=f"Alas <{self.config_name}> crashed",
|
||||
self.config.Error_OnePushConfig,
|
||||
title=f"Alas <{self.config_name}> crashed",
|
||||
content=f"<{self.config_name}> ScriptError",
|
||||
)
|
||||
exit(1)
|
||||
except RequestHumanTakeover:
|
||||
logger.critical('Request human takeover')
|
||||
handle_notify(
|
||||
self.config.Error_OnePushConfig,
|
||||
title=f"Alas <{self.config_name}> crashed",
|
||||
self.config.Error_OnePushConfig,
|
||||
title=f"Alas <{self.config_name}> crashed",
|
||||
content=f"<{self.config_name}> RequestHumanTakeover",
|
||||
)
|
||||
exit(1)
|
||||
@ -120,8 +120,8 @@ class AzurLaneAutoScript:
|
||||
logger.exception(e)
|
||||
self.save_error_log()
|
||||
handle_notify(
|
||||
self.config.Error_OnePushConfig,
|
||||
title=f"Alas <{self.config_name}> crashed",
|
||||
self.config.Error_OnePushConfig,
|
||||
title=f"Alas <{self.config_name}> crashed",
|
||||
content=f"<{self.config_name}> Exception occured",
|
||||
)
|
||||
exit(1)
|
||||
@ -288,9 +288,13 @@ class AzurLaneAutoScript:
|
||||
MaritimeEscort(config=self.config, device=self.device).run()
|
||||
|
||||
def opsi_ash_assist(self):
|
||||
from module.os_ash.ash import AshBeaconAssist
|
||||
from module.os_ash.meta import AshBeaconAssist
|
||||
AshBeaconAssist(config=self.config, device=self.device).run()
|
||||
|
||||
def opsi_ash_beacon(self):
|
||||
from module.os_ash.meta import OpsiAshBeacon
|
||||
OpsiAshBeacon(config=self.config, device=self.device).run()
|
||||
|
||||
def opsi_explore(self):
|
||||
from module.campaign.os_run import OSCampaignRun
|
||||
OSCampaignRun(config=self.config, device=self.device).opsi_explore()
|
||||
|
Before Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 10 KiB |
BIN
assets/cn/os_ash/DOSSIER_LIST.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
assets/cn/os_ash/META_AUTO_ATTACKING.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
assets/cn/os_ash/META_AUTO_CONFIRM.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
assets/cn/os_ash/META_BEACON_DATA.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
assets/cn/os_ash/META_BEACON_FLAG.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/cn/os_ash/META_BEGIN_ENTRANCE.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
assets/cn/os_ash/META_DAMAGE.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 6.9 KiB |
BIN
assets/cn/os_ash/META_ENTRANCE.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/cn/os_ash/META_INNER_PAGE_DAMAGE.png
Normal file
After Width: | Height: | Size: 9.0 KiB |
BIN
assets/cn/os_ash/META_INNER_PAGE_NOT_DAMAGE.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
assets/cn/os_ash/META_MAIN_BEACON_ENTRANCE.png
Normal file
After Width: | Height: | Size: 165 KiB |
BIN
assets/cn/os_ash/META_MAIN_DOSSIER_ENTRANCE.png
Normal file
After Width: | Height: | Size: 154 KiB |
Before Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 11 KiB |
BIN
assets/en/os_ash/META_AUTO_ATTACKING.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
assets/en/os_ash/META_BEACON_DATA.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
assets/en/os_ash/META_BEACON_FLAG.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/en/os_ash/META_BEGIN_ENTRANCE.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
assets/en/os_ash/META_DAMAGE.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
assets/en/os_ash/META_DOSSIER_DATA.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 6.9 KiB |
BIN
assets/en/os_ash/META_ENTRANCE.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/en/os_ash/META_MAIN_BEACON_ENTRANCE.png
Normal file
After Width: | Height: | Size: 165 KiB |
BIN
assets/en/os_ash/META_MAIN_DOSSIER_ENTRANCE.png
Normal file
After Width: | Height: | Size: 154 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 98 KiB |
Before Width: | Height: | Size: 11 KiB |
BIN
assets/jp/os_ash/META_AUTO_ATTACKING.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
assets/jp/os_ash/META_BEACON_DATA.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
assets/jp/os_ash/META_BEACON_FLAG.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/jp/os_ash/META_BEGIN_ENTRANCE.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
assets/jp/os_ash/META_DAMAGE.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
assets/jp/os_ash/META_DOSSIER_DATA.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 6.9 KiB |
BIN
assets/jp/os_ash/META_ENTRANCE.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/jp/os_ash/META_MAIN_BEACON_ENTRANCE.png
Normal file
After Width: | Height: | Size: 165 KiB |
BIN
assets/jp/os_ash/META_MAIN_DOSSIER_ENTRANCE.png
Normal file
After Width: | Height: | Size: 154 KiB |
Before Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 7.9 KiB |
BIN
assets/tw/os_ash/META_AUTO_ATTACKING.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
assets/tw/os_ash/META_BEACON_DATA.png
Normal file
After Width: | Height: | Size: 7.0 KiB |
BIN
assets/tw/os_ash/META_BEACON_FLAG.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
assets/tw/os_ash/META_BEGIN_ENTRANCE.png
Normal file
After Width: | Height: | Size: 80 KiB |
BIN
assets/tw/os_ash/META_DAMAGE.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
assets/tw/os_ash/META_DOSSIER_DATA.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 6.9 KiB |
BIN
assets/tw/os_ash/META_ENTRANCE.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
assets/tw/os_ash/META_MAIN_BEACON_ENTRANCE.png
Normal file
After Width: | Height: | Size: 165 KiB |
BIN
assets/tw/os_ash/META_MAIN_DOSSIER_ENTRANCE.png
Normal file
After Width: | Height: | Size: 154 KiB |
@ -1467,11 +1467,25 @@
|
||||
"RepairThreshold": 0.4,
|
||||
"DoRandomMapEvent": true,
|
||||
"AkashiShopFilter": "ActionPoint > PurpleCoins"
|
||||
}
|
||||
},
|
||||
"OpsiAshBeacon": {
|
||||
"Scheduler": {
|
||||
"Enable": false,
|
||||
"NextRun": "2020-01-01 00:00:00",
|
||||
"Command": "OpsiAshBeacon",
|
||||
"SuccessInterval": 30,
|
||||
"FailureInterval": 30,
|
||||
"ServerUpdate": "00:00"
|
||||
},
|
||||
"OpsiAshBeacon": {
|
||||
"AshAttack": true,
|
||||
"EnsureFullyCollected": true,
|
||||
"RequestAssist": true
|
||||
"OneHitMode": true,
|
||||
"RequestAssist": true,
|
||||
"EnsureFullyCollected": true
|
||||
},
|
||||
"OpsiDossierBeacon": {
|
||||
"Enable": true
|
||||
}
|
||||
},
|
||||
"OpsiAshAssist": {
|
||||
|
@ -7457,19 +7457,62 @@
|
||||
"type": "textarea",
|
||||
"value": "ActionPoint > PurpleCoins"
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpsiAshBeacon": {
|
||||
"Scheduler": {
|
||||
"Enable": {
|
||||
"type": "checkbox",
|
||||
"value": false
|
||||
},
|
||||
"NextRun": {
|
||||
"type": "datetime",
|
||||
"value": "2020-01-01 00:00:00",
|
||||
"validate": "datetime"
|
||||
},
|
||||
"Command": {
|
||||
"type": "input",
|
||||
"value": "OpsiAshBeacon",
|
||||
"display": "hide"
|
||||
},
|
||||
"SuccessInterval": {
|
||||
"type": "input",
|
||||
"value": 30,
|
||||
"display": "hide"
|
||||
},
|
||||
"FailureInterval": {
|
||||
"type": "input",
|
||||
"value": 30,
|
||||
"display": "hide"
|
||||
},
|
||||
"ServerUpdate": {
|
||||
"type": "input",
|
||||
"value": "00:00",
|
||||
"display": "hide"
|
||||
}
|
||||
},
|
||||
"OpsiAshBeacon": {
|
||||
"AshAttack": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"OneHitMode": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
},
|
||||
"RequestAssist": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
},
|
||||
"OpsiDossierBeacon": {
|
||||
"Enable": {
|
||||
"type": "checkbox",
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -530,8 +530,11 @@ OpsiGeneral:
|
||||
ActionPoint > PurpleCoins
|
||||
OpsiAshBeacon:
|
||||
AshAttack: true
|
||||
EnsureFullyCollected: true
|
||||
OneHitMode: true
|
||||
RequestAssist: true
|
||||
EnsureFullyCollected: true
|
||||
OpsiDossierBeacon:
|
||||
Enable: true
|
||||
OpsiFleetFilter:
|
||||
Filter: |-
|
||||
Fleet-4 > CallSubmarine > Fleet-2 > Fleet-3 > Fleet-1
|
||||
|
@ -52,6 +52,7 @@
|
||||
],
|
||||
"Opsi": [
|
||||
"OpsiGeneral",
|
||||
"OpsiAshBeacon",
|
||||
"OpsiAshAssist",
|
||||
"OpsiExplore",
|
||||
"OpsiShop",
|
||||
|
@ -336,6 +336,11 @@ OpsiAshAssist:
|
||||
SuccessInterval: 30
|
||||
FailureInterval: 30
|
||||
ServerUpdate: 00:00
|
||||
OpsiAshBeacon:
|
||||
Scheduler:
|
||||
SuccessInterval: 30
|
||||
FailureInterval: 30
|
||||
ServerUpdate: 00:00
|
||||
OpsiExplore:
|
||||
Scheduler:
|
||||
SuccessInterval: 0
|
||||
|
@ -235,7 +235,10 @@ WarArchives:
|
||||
|
||||
OpsiGeneral:
|
||||
- OpsiGeneral
|
||||
OpsiAshBeacon:
|
||||
- Scheduler
|
||||
- OpsiAshBeacon
|
||||
- OpsiDossierBeacon
|
||||
OpsiAshAssist:
|
||||
- Scheduler
|
||||
- OpsiAshAssist
|
||||
|
@ -338,8 +338,12 @@ class GeneratedConfig:
|
||||
|
||||
# Group `OpsiAshBeacon`
|
||||
OpsiAshBeacon_AshAttack = True
|
||||
OpsiAshBeacon_EnsureFullyCollected = True
|
||||
OpsiAshBeacon_OneHitMode = True
|
||||
OpsiAshBeacon_RequestAssist = True
|
||||
OpsiAshBeacon_EnsureFullyCollected = True
|
||||
|
||||
# Group `OpsiDossierBeacon`
|
||||
OpsiDossierBeacon_Enable = True
|
||||
|
||||
# Group `OpsiFleetFilter`
|
||||
OpsiFleetFilter_Filter = 'Fleet-4 > CallSubmarine > Fleet-2 > Fleet-3 > Fleet-1'
|
||||
|
@ -16,9 +16,10 @@ class ManualConfig:
|
||||
> Reward > MetaReward > BattlePass
|
||||
> ShopFrequent > ShopOnce > Shipyard > DataKey
|
||||
> OpsiExplore
|
||||
> OpsiAshBeacon
|
||||
> OpsiDaily > OpsiShop
|
||||
> OpsiAbyssal > OpsiStronghold > OpsiObscure
|
||||
> Daily > Hard > OpsiAshAssist
|
||||
> Daily > Hard > OpsiAshBeacon > OpsiAshAssist
|
||||
> Sos > EventSp > EventA > EventB > EventC > EventD > RaidDaily > WarArchives > MaritimeEscort
|
||||
> Event > Event2 > Raid > Main > Main2 > Main3
|
||||
> OpsiMeowfficerFarming
|
||||
|
@ -194,6 +194,10 @@
|
||||
"name": "OpSi General",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiAshBeacon": {
|
||||
"name": "Ash Beacon",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiAshAssist": {
|
||||
"name": "OpSi Ash Assist",
|
||||
"help": ""
|
||||
@ -1922,13 +1926,27 @@
|
||||
"name": "Enable Ash Attack",
|
||||
"help": "When data beacon is full; attack until ash has been completed"
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"name": "Ensure 200 Beacon Data Fully Collected",
|
||||
"help": "Ignore AP limit setting temporarily before ash beacon fully collected. \"Meowfficer Farming\" must be enabled"
|
||||
"OneHitMode": {
|
||||
"name": "One Hit Mode",
|
||||
"help": "Strike each beacon only once, then call for support every half hour thereafter"
|
||||
},
|
||||
"RequestAssist": {
|
||||
"name": "Request Assists",
|
||||
"help": "Before the attack, request assists from friends, guild and world"
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"name": "Ensure 200 Beacon Data Fully Collected",
|
||||
"help": "Ignore AP limit setting temporarily before ash beacon fully collected. \"Meowfficer Farming\" must be enabled"
|
||||
}
|
||||
},
|
||||
"OpsiDossierBeacon": {
|
||||
"_info": {
|
||||
"name": "Dossier Beacon",
|
||||
"help": ""
|
||||
},
|
||||
"Enable": {
|
||||
"name": "Enable Dossier Beacon Attack",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"OpsiFleetFilter": {
|
||||
|
@ -194,6 +194,10 @@
|
||||
"name": "Task.OpsiGeneral.name",
|
||||
"help": "Task.OpsiGeneral.help"
|
||||
},
|
||||
"OpsiAshBeacon": {
|
||||
"name": "Task.OpsiAshBeacon.name",
|
||||
"help": "Task.OpsiAshBeacon.help"
|
||||
},
|
||||
"OpsiAshAssist": {
|
||||
"name": "Task.OpsiAshAssist.name",
|
||||
"help": "Task.OpsiAshAssist.help"
|
||||
@ -1922,13 +1926,27 @@
|
||||
"name": "OpsiAshBeacon.AshAttack.name",
|
||||
"help": "OpsiAshBeacon.AshAttack.help"
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"name": "OpsiAshBeacon.EnsureFullyCollected.name",
|
||||
"help": "OpsiAshBeacon.EnsureFullyCollected.help"
|
||||
"OneHitMode": {
|
||||
"name": "OpsiAshBeacon.OneHitMode.name",
|
||||
"help": "OpsiAshBeacon.OneHitMode.help"
|
||||
},
|
||||
"RequestAssist": {
|
||||
"name": "OpsiAshBeacon.RequestAssist.name",
|
||||
"help": "OpsiAshBeacon.RequestAssist.help"
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"name": "OpsiAshBeacon.EnsureFullyCollected.name",
|
||||
"help": "OpsiAshBeacon.EnsureFullyCollected.help"
|
||||
}
|
||||
},
|
||||
"OpsiDossierBeacon": {
|
||||
"_info": {
|
||||
"name": "OpsiDossierBeacon._info.name",
|
||||
"help": "OpsiDossierBeacon._info.help"
|
||||
},
|
||||
"Enable": {
|
||||
"name": "OpsiDossierBeacon.Enable.name",
|
||||
"help": "OpsiDossierBeacon.Enable.help"
|
||||
}
|
||||
},
|
||||
"OpsiFleetFilter": {
|
||||
|
@ -194,10 +194,14 @@
|
||||
"name": "通用设置",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiAshAssist": {
|
||||
"OpsiAshBeacon": {
|
||||
"name": "余烬信标",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiAshAssist": {
|
||||
"name": "信标支援",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiExplore": {
|
||||
"name": "每月开荒",
|
||||
"help": ""
|
||||
@ -1875,7 +1879,7 @@
|
||||
},
|
||||
"OpsiAshAssist": {
|
||||
"_info": {
|
||||
"name": "余烬信标支援",
|
||||
"name": "信标支援",
|
||||
"help": "打每天三次的信标支援"
|
||||
},
|
||||
"Tier": {
|
||||
@ -1922,13 +1926,27 @@
|
||||
"name": "打余烬信标",
|
||||
"help": "信标数据满了之后打余烬信标,一直打直到打完"
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"name": "保证收集满每日200信标数据",
|
||||
"help": "在收集满为前,暂时无视保留行动力设置,需要同时开启 \"短猫相接\""
|
||||
"OneHitMode": {
|
||||
"name": "一击即走",
|
||||
"help": "对每个信标只出击一次,之后每半个小时呼叫支援"
|
||||
},
|
||||
"RequestAssist": {
|
||||
"name": "呼叫支援",
|
||||
"help": "打信标之前,从好友、舰队、世界呼叫支援"
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"name": "保证收集满每日200信标数据",
|
||||
"help": "在收集满为前,暂时无视保留行动力设置,需要同时开启 \"短猫相接\""
|
||||
}
|
||||
},
|
||||
"OpsiDossierBeacon": {
|
||||
"_info": {
|
||||
"name": "档案信标",
|
||||
"help": ""
|
||||
},
|
||||
"Enable": {
|
||||
"name": "打档案信标",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"OpsiFleetFilter": {
|
||||
|
@ -194,10 +194,14 @@
|
||||
"name": "通用設定",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiAshAssist": {
|
||||
"OpsiAshBeacon": {
|
||||
"name": "餘燼信標",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiAshAssist": {
|
||||
"name": "信標支援",
|
||||
"help": ""
|
||||
},
|
||||
"OpsiExplore": {
|
||||
"name": "每月開荒",
|
||||
"help": ""
|
||||
@ -1875,7 +1879,7 @@
|
||||
},
|
||||
"OpsiAshAssist": {
|
||||
"_info": {
|
||||
"name": "餘燼信標支援",
|
||||
"name": "信標支援",
|
||||
"help": "打每日三次的信標支援"
|
||||
},
|
||||
"Tier": {
|
||||
@ -1922,13 +1926,27 @@
|
||||
"name": "打餘燼信標",
|
||||
"help": "信標數據滿了之後打餘燼信標,一直打直到打完"
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"name": "保證收集滿每日200信標數據",
|
||||
"help": "在收集滿為前,暫時無視保留行動力設置,需要同時開啟 \"短貓相接\""
|
||||
"OneHitMode": {
|
||||
"name": "一擊即走",
|
||||
"help": "對每個信標只出擊一次,之後每半個小時呼叫支援"
|
||||
},
|
||||
"RequestAssist": {
|
||||
"name": "呼叫支援",
|
||||
"help": "打信標之前,從好友、艦隊、世界呼叫支援"
|
||||
},
|
||||
"EnsureFullyCollected": {
|
||||
"name": "保證收集滿每日200信標數據",
|
||||
"help": "在收集滿為前,暫時無視保留行動力設置,需要同時開啟 \"短貓相接\""
|
||||
}
|
||||
},
|
||||
"OpsiDossierBeacon": {
|
||||
"_info": {
|
||||
"name": "檔案信標",
|
||||
"help": ""
|
||||
},
|
||||
"Enable": {
|
||||
"name": "打檔案信標",
|
||||
"help": ""
|
||||
}
|
||||
},
|
||||
"OpsiFleetFilter": {
|
||||
|
@ -1,15 +1,11 @@
|
||||
from module.base.timer import Timer
|
||||
from module.base.utils import color_bar_percentage, image_left_strip
|
||||
from module.combat.combat import BATTLE_PREPARATION, GET_ITEMS_1, Combat
|
||||
from module.base.utils import image_left_strip
|
||||
from module.combat.combat import BATTLE_PREPARATION, Combat
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import Digit, DigitCounter
|
||||
from module.os.assets import MAP_GOTO_GLOBE, GLOBE_GOTO_MAP
|
||||
from module.ocr.ocr import DigitCounter
|
||||
from module.os_ash.assets import *
|
||||
from module.os_handler.assets import IN_MAP
|
||||
from module.os_handler.map_event import MapEventHandler
|
||||
from module.ui.assets import BACK_ARROW
|
||||
from module.ui.page import page_os
|
||||
from module.ui.switch import Switch
|
||||
from module.ui.ui import UI
|
||||
|
||||
|
||||
@ -20,14 +16,6 @@ class DailyDigitCounter(DigitCounter):
|
||||
return image
|
||||
|
||||
|
||||
OCR_BEACON_REMAIN = DigitCounter(BEACON_REMAIN, threshold=256, name='OCR_ASH_REMAIN')
|
||||
OCR_BEACON_TIER = Digit(BEACON_TIER, name='OCR_ASH_TIER')
|
||||
|
||||
SWITCH_BEACON = Switch(name='Beacon', offset=(20, 20))
|
||||
SWITCH_BEACON.add_status('mine', BEACON_LIST)
|
||||
SWITCH_BEACON.add_status('list', BEACON_MY)
|
||||
|
||||
|
||||
class AshBeaconFinished(Exception):
|
||||
pass
|
||||
|
||||
@ -83,125 +71,10 @@ class AshCombat(Combat):
|
||||
|
||||
|
||||
class OSAsh(UI, MapEventHandler):
|
||||
ash_entrance_offset = (200, 5)
|
||||
beacon_entrance_offset = (100, 100)
|
||||
|
||||
def is_in_ash(self):
|
||||
return self.appear(ASH_CHECK, offset=(100, 20)) or \
|
||||
self.appear(ASH_SHOWDOWN, offset=(30, 30))
|
||||
|
||||
def is_in_map(self):
|
||||
return self.appear(IN_MAP, offset=(200, 5))
|
||||
|
||||
def _ash_assist_enter_from_map(self, offset=(200, 5), skip_first_screenshot=True):
|
||||
"""
|
||||
Args:
|
||||
offset:
|
||||
skip_first_screenshot:
|
||||
|
||||
Pages:
|
||||
in: IN_MAP
|
||||
out: is_in_ash
|
||||
"""
|
||||
confirm_timer = Timer(1, count=2).start()
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear_then_click(MAP_GOTO_GLOBE, offset=offset, interval=5):
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self.appear_then_click(ASH_SHOWDOWN, offset=(30, 30), interval=5):
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self.appear_then_click(ASH_ENTRANCE, offset=offset, interval=5):
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self._handle_ash_beacon_reward():
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self.handle_popup_confirm('GOTO_GLOBE'):
|
||||
# Popup: Leaving current zone will terminate meowfficer searching
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
if self.handle_map_event():
|
||||
confirm_timer.reset()
|
||||
continue
|
||||
|
||||
# End
|
||||
if self.is_in_ash():
|
||||
if confirm_timer.reached():
|
||||
break
|
||||
else:
|
||||
confirm_timer.reset()
|
||||
|
||||
def _ash_beacon_select(self, tier=15, trial=5):
|
||||
"""
|
||||
Args:
|
||||
tier (int): Try to find a beacon with tier greater or equal argument tier.
|
||||
trial (int): If not found after several trial, attack current one.
|
||||
|
||||
Returns:
|
||||
bool: If selected beacon satisfies input tier.
|
||||
|
||||
Page:
|
||||
in: ASH_CHECK, beacon list
|
||||
"""
|
||||
# Ensure BEACON_TIER shown up
|
||||
# When entering beacon list, tier number wasn't shown immediately.
|
||||
for n in range(10):
|
||||
if self.image_color_count(BEACON_TIER, color=(0, 0, 0), threshold=221, count=50):
|
||||
break
|
||||
|
||||
self.device.screenshot()
|
||||
if n >= 9:
|
||||
logger.warning('Waiting for beacon tier timeout')
|
||||
|
||||
# Select beacon
|
||||
for _ in range(trial):
|
||||
current = OCR_BEACON_TIER.ocr(self.device.image)
|
||||
if current >= tier:
|
||||
return True
|
||||
else:
|
||||
self.device.click(BEACON_NEXT)
|
||||
self.device.sleep((0.3, 0.5))
|
||||
self.device.screenshot()
|
||||
|
||||
logger.info(f'Tier {tier} beacon not found after {trial} trial, use current beacon')
|
||||
return False
|
||||
|
||||
def ash_beacon_assist(self):
|
||||
"""
|
||||
Run beacon ash assist.
|
||||
|
||||
Pages:
|
||||
in: Any page
|
||||
out: page_os
|
||||
"""
|
||||
# If the main story in OS is not cleared, ASH_ENTRANCE is the first button counted from bottom right.
|
||||
# When main story is cleared, ASH_ENTRANCE move to the second one.
|
||||
# Here use an offset to handle that.
|
||||
ash_combat = AshCombat(self.config, self.device)
|
||||
self.ui_ensure(page_os)
|
||||
self._ash_assist_enter_from_map(offset=self.ash_entrance_offset, skip_first_screenshot=True)
|
||||
|
||||
for _ in range(10):
|
||||
SWITCH_BEACON.set('list', main=self)
|
||||
remain, _, _ = OCR_BEACON_REMAIN.ocr(self.device.image)
|
||||
if remain <= 0:
|
||||
logger.info('Ash beacon exhausted')
|
||||
break
|
||||
|
||||
self._ash_beacon_select(tier=self.config.OpsiAshAssist_Tier)
|
||||
ash_combat.combat(expected_end=self.is_in_ash, save_get_items=False, emotion_reduce=False)
|
||||
|
||||
self.device.sleep((0.5, 0.8))
|
||||
self.device.screenshot()
|
||||
self._ash_exit_to_globe()
|
||||
return True
|
||||
|
||||
_ash_fully_collected = False
|
||||
|
||||
def ash_collect_status(self):
|
||||
@ -239,179 +112,6 @@ class OSAsh(UI, MapEventHandler):
|
||||
status = 0
|
||||
return status
|
||||
|
||||
def _ash_mine_enter_from_map(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Pages:
|
||||
in: is_in_map
|
||||
out: is_in_ash
|
||||
"""
|
||||
in_map_timeout = Timer(2, count=3)
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if in_map_timeout.reached() and self.is_in_map():
|
||||
self.device.click(ASH_COLLECT_STATUS)
|
||||
in_map_timeout.reset()
|
||||
continue
|
||||
if self.appear_then_click(ASH_ENTER_CONFIRM, offset=(30, 50), interval=2):
|
||||
continue
|
||||
if self.appear_then_click(ASH_SHOWDOWN, offset=(30, 30), interval=3):
|
||||
continue
|
||||
if self.appear_then_click(BEACON_ENTER, offset=self.beacon_entrance_offset, interval=2):
|
||||
continue
|
||||
if self._handle_ash_beacon_reward():
|
||||
continue
|
||||
if self.handle_map_event():
|
||||
# Random map events, may slow to show.
|
||||
continue
|
||||
|
||||
# End:
|
||||
if self.appear(ASH_START, offset=(30, 30)):
|
||||
break
|
||||
|
||||
def _ash_exit_to_map(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Pages:
|
||||
in: is_in_ash
|
||||
out: is_in_map
|
||||
"""
|
||||
click_timer = Timer(3)
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
# End
|
||||
if self.is_in_map():
|
||||
break
|
||||
|
||||
if click_timer.reached() and self.is_in_ash():
|
||||
self.device.click(ASH_QUIT)
|
||||
click_timer.reset()
|
||||
continue
|
||||
if self.appear(ASH_SHOWDOWN, offset=(30, 30), interval=3):
|
||||
self.device.click(ASH_QUIT)
|
||||
continue
|
||||
if self.appear_then_click(GLOBE_GOTO_MAP, offset=(20, 20), interval=3):
|
||||
continue
|
||||
if self.handle_map_event():
|
||||
continue
|
||||
|
||||
def _ash_exit_to_globe(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Pages:
|
||||
in: is_in_ash
|
||||
out: is_in_map
|
||||
"""
|
||||
click_timer = Timer(3)
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
# End
|
||||
if self.appear(ASH_ENTRANCE, offset=self.ash_entrance_offset):
|
||||
break
|
||||
|
||||
if click_timer.reached() and self.is_in_ash():
|
||||
self.device.click(ASH_QUIT)
|
||||
click_timer.reset()
|
||||
continue
|
||||
if self.appear(ASH_SHOWDOWN, offset=(30, 30), interval=3):
|
||||
self.device.click(ASH_QUIT)
|
||||
continue
|
||||
if self.appear_then_click(MAP_GOTO_GLOBE, offset=(20, 20), interval=3):
|
||||
continue
|
||||
if self.handle_map_event():
|
||||
continue
|
||||
|
||||
def _ash_help(self):
|
||||
"""
|
||||
Request help from friends, guild and world.
|
||||
|
||||
Pages:
|
||||
in: is_in_ash
|
||||
out: is_in_ash
|
||||
"""
|
||||
self.ui_click(click_button=HELP_ENTER, check_button=HELP_CONFIRM)
|
||||
# Here use simple clicks. Dropping some clicks is acceptable, no need to confirm they are selected.
|
||||
self.device.click(HELP_1)
|
||||
self.device.sleep((0.1, 0.3))
|
||||
self.device.click(HELP_2)
|
||||
self.device.sleep((0.1, 0.3))
|
||||
self.device.click(HELP_3)
|
||||
self.ui_click(click_button=HELP_CONFIRM, check_button=HELP_ENTER)
|
||||
|
||||
def _handle_ash_beacon_reward(self):
|
||||
"""
|
||||
Returns:
|
||||
bool: If clicked
|
||||
"""
|
||||
if self.appear_then_click(BEACON_REWARD, interval=2):
|
||||
return True
|
||||
if self.appear(GET_ITEMS_1, interval=2):
|
||||
self.device.click(BEACON_REWARD)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _ash_beacon_attack(self):
|
||||
"""
|
||||
Attack ash beacon until it's killed.
|
||||
|
||||
Returns:
|
||||
bool: If all beacon finished
|
||||
|
||||
Pages:
|
||||
in: is_in_ash
|
||||
out: is_in_ash
|
||||
"""
|
||||
logger.info('Ash beacon attack')
|
||||
confirm_timer = Timer(1, count=2).start()
|
||||
ash_combat = AshCombat(self.config, self.device)
|
||||
|
||||
while 1:
|
||||
self.device.screenshot()
|
||||
percent = color_bar_percentage(
|
||||
self.device.image, BEACON_HP_PERCENTAGE.area, prev_color=(181, 56, 57), threshold=15)
|
||||
logger.attr('Ash_beacon_hp', f'{int(percent * 100)}%')
|
||||
|
||||
# End
|
||||
if self.appear(BEACON_EMPTY, offset=(20, 20)):
|
||||
if confirm_timer.reached():
|
||||
logger.info('Ash beacon attack finished')
|
||||
return True
|
||||
elif self.appear(BEACON_ENTER, offset=self.beacon_entrance_offset):
|
||||
# If previous beacon is not completed, the previous beacon is attacked in this round.
|
||||
# Then found a new beacon, after attack.
|
||||
if confirm_timer.reached():
|
||||
logger.info('Ash beacon attack finished, but found another beacon')
|
||||
return False
|
||||
else:
|
||||
confirm_timer.reset()
|
||||
|
||||
# Accident clicks
|
||||
if self.appear(BATTLE_PREPARATION, offset=(30, 30), interval=2):
|
||||
self.device.click(BACK_ARROW)
|
||||
continue
|
||||
if self.appear(HELP_CONFIRM, offset=(30, 30), interval=2):
|
||||
self.device.click(BACK_ARROW)
|
||||
continue
|
||||
# Redirected by game
|
||||
if self.appear_then_click(ASH_SHOWDOWN, offset=(30, 30), interval=2):
|
||||
continue
|
||||
# Combat and rewards
|
||||
if self._handle_ash_beacon_reward():
|
||||
continue
|
||||
if self.appear(ASH_START, offset=(30, 30)):
|
||||
ash_combat.combat(expected_end=self.is_in_ash, save_get_items=False, emotion_reduce=False)
|
||||
continue
|
||||
|
||||
def handle_ash_beacon_attack(self):
|
||||
"""
|
||||
Returns:
|
||||
@ -421,31 +121,12 @@ class OSAsh(UI, MapEventHandler):
|
||||
in: is_in_map
|
||||
out: is_in_map
|
||||
"""
|
||||
if not self.config.OpsiAshBeacon_AshAttack:
|
||||
if not self.config.OpsiAshBeacon_AshAttack \
|
||||
and not self.config.OpsiDossierBeacon_Enable:
|
||||
return False
|
||||
|
||||
if self.ash_collect_status() < 100:
|
||||
return False
|
||||
|
||||
for _ in range(3):
|
||||
self._ash_mine_enter_from_map()
|
||||
if self.config.OpsiAshBeacon_RequestAssist:
|
||||
self._ash_help()
|
||||
finish = self._ash_beacon_attack()
|
||||
if finish:
|
||||
break
|
||||
|
||||
self._ash_exit_to_map()
|
||||
self.config.task_call(task='OpsiAshBeacon')
|
||||
return True
|
||||
|
||||
|
||||
class AshBeaconAssist(OSAsh):
|
||||
def run(self):
|
||||
"""
|
||||
Run daily ash beacon assist.
|
||||
|
||||
Pages:
|
||||
in: Any page
|
||||
out: page_os
|
||||
"""
|
||||
self.ash_beacon_assist()
|
||||
self.config.task_delay(server_update=True)
|
||||
|
@ -4,26 +4,35 @@ from module.base.template import Template
|
||||
# This file was automatically generated by dev_tools/button_extract.py.
|
||||
# Don't modify it manually.
|
||||
|
||||
ASH_CHECK = Button(area={'cn': (921, 20, 1028, 53), 'en': (922, 21, 1028, 54), 'jp': (940, 24, 1013, 45), 'tw': (921, 20, 1028, 54)}, color={'cn': (116, 87, 87), 'en': (125, 84, 83), 'jp': (166, 132, 132), 'tw': (120, 84, 84)}, button={'cn': (921, 20, 1028, 53), 'en': (922, 21, 1028, 54), 'jp': (940, 24, 1013, 45), 'tw': (921, 20, 1028, 54)}, file={'cn': './assets/cn/os_ash/ASH_CHECK.png', 'en': './assets/en/os_ash/ASH_CHECK.png', 'jp': './assets/jp/os_ash/ASH_CHECK.png', 'tw': './assets/tw/os_ash/ASH_CHECK.png'})
|
||||
ASH_COLLECT_STATUS = Button(area={'cn': (640, 27, 720, 49), 'en': (640, 27, 720, 49), 'jp': (640, 27, 720, 49), 'tw': (640, 27, 720, 49)}, color={'cn': (82, 92, 99), 'en': (82, 92, 99), 'jp': (82, 92, 99), 'tw': (82, 92, 99)}, button={'cn': (640, 27, 720, 49), 'en': (640, 27, 720, 49), 'jp': (640, 27, 720, 49), 'tw': (640, 27, 720, 49)}, file={'cn': './assets/cn/os_ash/ASH_COLLECT_STATUS.png', 'en': './assets/en/os_ash/ASH_COLLECT_STATUS.png', 'jp': './assets/jp/os_ash/ASH_COLLECT_STATUS.png', 'tw': './assets/tw/os_ash/ASH_COLLECT_STATUS.png'})
|
||||
ASH_DAILY_STATUS = Button(area={'cn': (637, 0, 741, 19), 'en': (637, 0, 741, 19), 'jp': (637, 0, 741, 19), 'tw': (637, 0, 741, 19)}, color={'cn': (104, 112, 121), 'en': (104, 112, 121), 'jp': (104, 112, 121), 'tw': (104, 112, 121)}, button={'cn': (637, 0, 741, 19), 'en': (637, 0, 741, 19), 'jp': (637, 0, 741, 19), 'tw': (637, 0, 741, 19)}, file={'cn': './assets/cn/os_ash/ASH_DAILY_STATUS.png', 'en': './assets/en/os_ash/ASH_DAILY_STATUS.png', 'jp': './assets/jp/os_ash/ASH_DAILY_STATUS.png', 'tw': './assets/tw/os_ash/ASH_DAILY_STATUS.png'})
|
||||
ASH_ENTER_CONFIRM = Button(area={'cn': (554, 482, 726, 539), 'en': (560, 487, 720, 534), 'jp': (553, 482, 727, 539), 'tw': (554, 482, 726, 539)}, color={'cn': (109, 153, 209), 'en': (106, 151, 207), 'jp': (111, 154, 207), 'tw': (109, 153, 209)}, button={'cn': (554, 482, 726, 539), 'en': (560, 487, 720, 534), 'jp': (553, 482, 727, 539), 'tw': (554, 482, 726, 539)}, file={'cn': './assets/cn/os_ash/ASH_ENTER_CONFIRM.png', 'en': './assets/en/os_ash/ASH_ENTER_CONFIRM.png', 'jp': './assets/jp/os_ash/ASH_ENTER_CONFIRM.png', 'tw': './assets/tw/os_ash/ASH_ENTER_CONFIRM.png'})
|
||||
ASH_ENTRANCE = Button(area={'cn': (935, 671, 1002, 689), 'en': (938, 676, 995, 690), 'jp': (934, 658, 1026, 689), 'tw': (934, 670, 1000, 689)}, color={'cn': (53, 57, 58), 'en': (73, 74, 75), 'jp': (50, 58, 62), 'tw': (60, 63, 65)}, button={'cn': (932, 631, 1078, 692), 'en': (932, 631, 1078, 692), 'jp': (934, 629, 1079, 693), 'tw': (930, 629, 1080, 693)}, file={'cn': './assets/cn/os_ash/ASH_ENTRANCE.png', 'en': './assets/en/os_ash/ASH_ENTRANCE.png', 'jp': './assets/jp/os_ash/ASH_ENTRANCE.png', 'tw': './assets/tw/os_ash/ASH_ENTRANCE.png'})
|
||||
ASH_QUIT = Button(area={'cn': (29, 25, 59, 49), 'en': (29, 25, 59, 49), 'jp': (22, 25, 54, 48), 'tw': (29, 25, 59, 49)}, color={'cn': (115, 63, 68), 'en': (115, 63, 68), 'jp': (114, 61, 67), 'tw': (115, 63, 68)}, button={'cn': (29, 25, 59, 49), 'en': (29, 25, 59, 49), 'jp': (22, 25, 54, 48), 'tw': (29, 25, 59, 49)}, file={'cn': './assets/cn/os_ash/ASH_QUIT.png', 'en': './assets/en/os_ash/ASH_QUIT.png', 'jp': './assets/jp/os_ash/ASH_QUIT.png', 'tw': './assets/tw/os_ash/ASH_QUIT.png'})
|
||||
ASH_SHOWDOWN = Button(area={'cn': (120, 14, 262, 38), 'en': (120, 16, 319, 35), 'jp': (122, 15, 246, 39), 'tw': (120, 14, 262, 38)}, color={'cn': (153, 131, 131), 'en': (130, 106, 106), 'jp': (164, 144, 145), 'tw': (153, 131, 131)}, button={'cn': (278, 167, 559, 551), 'en': (278, 167, 559, 551), 'jp': (278, 167, 559, 551), 'tw': (278, 167, 559, 551)}, file={'cn': './assets/cn/os_ash/ASH_SHOWDOWN.png', 'en': './assets/en/os_ash/ASH_SHOWDOWN.png', 'jp': './assets/jp/os_ash/ASH_SHOWDOWN.png', 'tw': './assets/cn/os_ash/ASH_SHOWDOWN.png'})
|
||||
ASH_SHOWDOWN = Button(area={'cn': (120, 14, 262, 38), 'en': (120, 16, 319, 35), 'jp': (122, 15, 246, 39), 'tw': (120, 14, 262, 38)}, color={'cn': (153, 131, 131), 'en': (130, 106, 106), 'jp': (164, 144, 145), 'tw': (153, 131, 131)}, button={'cn': (120, 14, 262, 38), 'en': (120, 16, 319, 35), 'jp': (122, 15, 246, 39), 'tw': (120, 14, 262, 38)}, file={'cn': './assets/cn/os_ash/ASH_SHOWDOWN.png', 'en': './assets/en/os_ash/ASH_SHOWDOWN.png', 'jp': './assets/jp/os_ash/ASH_SHOWDOWN.png', 'tw': './assets/cn/os_ash/ASH_SHOWDOWN.png'})
|
||||
ASH_START = Button(area={'cn': (1061, 635, 1259, 695), 'en': (1063, 637, 1255, 693), 'jp': (1058, 634, 1260, 697), 'tw': (1043, 637, 1242, 698)}, color={'cn': (236, 187, 115), 'en': (223, 184, 124), 'jp': (222, 185, 126), 'tw': (223, 186, 131)}, button={'cn': (1061, 635, 1259, 695), 'en': (1063, 637, 1255, 693), 'jp': (1058, 634, 1260, 697), 'tw': (1043, 637, 1242, 698)}, file={'cn': './assets/cn/os_ash/ASH_START.png', 'en': './assets/en/os_ash/ASH_START.png', 'jp': './assets/jp/os_ash/ASH_START.png', 'tw': './assets/tw/os_ash/ASH_START.png'})
|
||||
BATTLE_STATUS = Button(area={'cn': (1051, 644, 1123, 675), 'en': (1022, 657, 1150, 671), 'jp': (1087, 642, 1127, 679), 'tw': (1050, 644, 1123, 675)}, color={'cn': (247, 199, 137), 'en': (243, 207, 160), 'jp': (229, 171, 91), 'tw': (243, 193, 128)}, button={'cn': (1051, 644, 1123, 675), 'en': (1022, 657, 1150, 671), 'jp': (1087, 642, 1127, 679), 'tw': (1050, 644, 1123, 675)}, file={'cn': './assets/cn/os_ash/BATTLE_STATUS.png', 'en': './assets/en/os_ash/BATTLE_STATUS.png', 'jp': './assets/jp/os_ash/BATTLE_STATUS.png', 'tw': './assets/tw/os_ash/BATTLE_STATUS.png'})
|
||||
BEACON_EMPTY = Button(area={'cn': (535, 288, 647, 316), 'en': (522, 290, 775, 313), 'jp': (465, 286, 664, 318), 'tw': (534, 287, 648, 316)}, color={'cn': (126, 129, 134), 'en': (148, 150, 154), 'jp': (119, 122, 128), 'tw': (128, 130, 135)}, button={'cn': (535, 288, 647, 316), 'en': (522, 290, 775, 313), 'jp': (465, 286, 664, 318), 'tw': (534, 287, 648, 316)}, file={'cn': './assets/cn/os_ash/BEACON_EMPTY.png', 'en': './assets/en/os_ash/BEACON_EMPTY.png', 'jp': './assets/jp/os_ash/BEACON_EMPTY.png', 'tw': './assets/tw/os_ash/BEACON_EMPTY.png'})
|
||||
BEACON_ENTER = Button(area={'cn': (553, 308, 669, 332), 'en': (590, 359, 705, 372), 'jp': (589, 348, 706, 371), 'tw': (650, 348, 706, 372)}, color={'cn': (90, 92, 92), 'en': (104, 105, 104), 'jp': (101, 102, 101), 'tw': (95, 97, 99)}, button={'cn': (509, 78, 713, 470), 'en': (509, 78, 713, 470), 'jp': (548, 115, 747, 502), 'tw': (509, 78, 714, 470)}, file={'cn': './assets/cn/os_ash/BEACON_ENTER.png', 'en': './assets/en/os_ash/BEACON_ENTER.png', 'jp': './assets/jp/os_ash/BEACON_ENTER.png', 'tw': './assets/tw/os_ash/BEACON_ENTER.png'})
|
||||
BEACON_HP_PERCENTAGE = Button(area={'cn': (278, 609, 1239, 623), 'en': (278, 609, 1239, 623), 'jp': (278, 609, 1239, 623), 'tw': (278, 609, 1239, 623)}, color={'cn': (224, 31, 22), 'en': (224, 31, 22), 'jp': (224, 31, 22), 'tw': (224, 31, 22)}, button={'cn': (278, 609, 1239, 623), 'en': (278, 609, 1239, 623), 'jp': (278, 609, 1239, 623), 'tw': (278, 609, 1239, 623)}, file={'cn': './assets/cn/os_ash/BEACON_HP_PERCENTAGE.png', 'en': './assets/en/os_ash/BEACON_HP_PERCENTAGE.png', 'jp': './assets/jp/os_ash/BEACON_HP_PERCENTAGE.png', 'tw': './assets/tw/os_ash/BEACON_HP_PERCENTAGE.png'})
|
||||
BEACON_LIST = Button(area={'cn': (26, 649, 218, 703), 'en': (25, 648, 218, 703), 'jp': (22, 645, 221, 706), 'tw': (23, 646, 221, 705)}, color={'cn': (135, 105, 122), 'en': (141, 104, 121), 'jp': (141, 107, 129), 'tw': (135, 101, 119)}, button={'cn': (26, 649, 218, 703), 'en': (25, 648, 218, 703), 'jp': (22, 645, 221, 706), 'tw': (23, 646, 221, 705)}, file={'cn': './assets/cn/os_ash/BEACON_LIST.png', 'en': './assets/en/os_ash/BEACON_LIST.png', 'jp': './assets/jp/os_ash/BEACON_LIST.png', 'tw': './assets/tw/os_ash/BEACON_LIST.png'})
|
||||
BEACON_MY = Button(area={'cn': (25, 647, 218, 702), 'en': (25, 647, 218, 704), 'jp': (22, 645, 221, 706), 'tw': (22, 644, 221, 707)}, color={'cn': (106, 84, 86), 'en': (110, 85, 86), 'jp': (102, 77, 78), 'tw': (108, 82, 84)}, button={'cn': (25, 647, 218, 702), 'en': (25, 647, 218, 704), 'jp': (22, 645, 221, 706), 'tw': (22, 644, 221, 707)}, file={'cn': './assets/cn/os_ash/BEACON_MY.png', 'en': './assets/en/os_ash/BEACON_MY.png', 'jp': './assets/jp/os_ash/BEACON_MY.png', 'tw': './assets/tw/os_ash/BEACON_MY.png'})
|
||||
BEACON_NEXT = Button(area={'cn': (129, 369, 440, 439), 'en': (129, 369, 440, 439), 'jp': (180, 368, 449, 440), 'tw': (129, 369, 440, 439)}, color={'cn': (51, 52, 48), 'en': (51, 52, 48), 'jp': (53, 54, 50), 'tw': (51, 52, 48)}, button={'cn': (129, 369, 440, 439), 'en': (129, 369, 440, 439), 'jp': (180, 368, 449, 440), 'tw': (129, 369, 440, 439)}, file={'cn': './assets/cn/os_ash/BEACON_NEXT.png', 'en': './assets/en/os_ash/BEACON_NEXT.png', 'jp': './assets/jp/os_ash/BEACON_NEXT.png', 'tw': './assets/tw/os_ash/BEACON_NEXT.png'})
|
||||
BEACON_REMAIN = Button(area={'cn': (1014, 25, 1073, 48), 'en': (1014, 25, 1073, 48), 'jp': (1014, 25, 1073, 48), 'tw': (1014, 25, 1073, 48)}, color={'cn': (48, 51, 48), 'en': (48, 51, 48), 'jp': (48, 51, 48), 'tw': (48, 51, 48)}, button={'cn': (1014, 25, 1073, 48), 'en': (1014, 25, 1073, 48), 'jp': (1014, 25, 1073, 48), 'tw': (1014, 25, 1073, 48)}, file={'cn': './assets/cn/os_ash/BEACON_REMAIN.png', 'en': './assets/en/os_ash/BEACON_REMAIN.png', 'jp': './assets/jp/os_ash/BEACON_REMAIN.png', 'tw': './assets/tw/os_ash/BEACON_REMAIN.png'})
|
||||
BEACON_REWARD = Button(area={'cn': (1049, 640, 1239, 695), 'en': (1072, 640, 1242, 695), 'jp': (1043, 637, 1242, 698), 'tw': (1049, 640, 1239, 695)}, color={'cn': (117, 164, 236), 'en': (112, 160, 237), 'jp': (108, 156, 232), 'tw': (119, 163, 228)}, button={'cn': (1049, 640, 1239, 695), 'en': (1072, 640, 1242, 695), 'jp': (1043, 637, 1242, 698), 'tw': (1049, 640, 1239, 695)}, file={'cn': './assets/cn/os_ash/BEACON_REWARD.png', 'en': './assets/en/os_ash/BEACON_REWARD.png', 'jp': './assets/jp/os_ash/BEACON_REWARD.png', 'tw': './assets/tw/os_ash/BEACON_REWARD.png'})
|
||||
BEACON_TIER = Button(area={'cn': (100, 562, 200, 637), 'en': (100, 562, 200, 637), 'jp': (100, 562, 200, 637), 'tw': (100, 562, 200, 637)}, color={'cn': (82, 83, 79), 'en': (82, 83, 79), 'jp': (82, 83, 79), 'tw': (82, 83, 79)}, button={'cn': (100, 562, 200, 637), 'en': (100, 562, 200, 637), 'jp': (100, 562, 200, 637), 'tw': (100, 562, 200, 637)}, file={'cn': './assets/cn/os_ash/BEACON_TIER.png', 'en': './assets/en/os_ash/BEACON_TIER.png', 'jp': './assets/jp/os_ash/BEACON_TIER.png', 'tw': './assets/tw/os_ash/BEACON_TIER.png'})
|
||||
DOSSIER_LIST = Button(area={'cn': (22, 646, 221, 706), 'en': (22, 646, 221, 706), 'jp': (22, 646, 221, 706), 'tw': (22, 646, 221, 706)}, color={'cn': (116, 89, 77), 'en': (116, 89, 77), 'jp': (116, 89, 77), 'tw': (116, 89, 77)}, button={'cn': (22, 646, 221, 706), 'en': (22, 646, 221, 706), 'jp': (22, 646, 221, 706), 'tw': (22, 646, 221, 706)}, file={'cn': './assets/cn/os_ash/DOSSIER_LIST.png', 'en': './assets/cn/os_ash/DOSSIER_LIST.png', 'jp': './assets/cn/os_ash/DOSSIER_LIST.png', 'tw': './assets/cn/os_ash/DOSSIER_LIST.png'})
|
||||
HELP_1 = Button(area={'cn': (391, 270, 557, 439), 'en': (391, 270, 557, 439), 'jp': (391, 270, 557, 439), 'tw': (391, 270, 557, 439)}, color={'cn': (83, 95, 118), 'en': (83, 95, 118), 'jp': (83, 95, 118), 'tw': (83, 95, 118)}, button={'cn': (391, 270, 557, 439), 'en': (391, 270, 557, 439), 'jp': (391, 270, 557, 439), 'tw': (391, 270, 557, 439)}, file={'cn': './assets/cn/os_ash/HELP_1.png', 'en': './assets/en/os_ash/HELP_1.png', 'jp': './assets/jp/os_ash/HELP_1.png', 'tw': './assets/tw/os_ash/HELP_1.png'})
|
||||
HELP_2 = Button(area={'cn': (584, 270, 750, 439), 'en': (584, 270, 750, 439), 'jp': (584, 270, 750, 439), 'tw': (584, 270, 750, 439)}, color={'cn': (82, 95, 119), 'en': (82, 95, 119), 'jp': (82, 95, 119), 'tw': (82, 95, 119)}, button={'cn': (584, 270, 750, 439), 'en': (584, 270, 750, 439), 'jp': (584, 270, 750, 439), 'tw': (584, 270, 750, 439)}, file={'cn': './assets/cn/os_ash/HELP_2.png', 'en': './assets/en/os_ash/HELP_2.png', 'jp': './assets/jp/os_ash/HELP_2.png', 'tw': './assets/tw/os_ash/HELP_2.png'})
|
||||
HELP_3 = Button(area={'cn': (778, 271, 941, 438), 'en': (778, 271, 941, 438), 'jp': (778, 271, 941, 438), 'tw': (778, 271, 941, 438)}, color={'cn': (83, 96, 118), 'en': (83, 96, 118), 'jp': (83, 96, 118), 'tw': (83, 96, 118)}, button={'cn': (778, 271, 941, 438), 'en': (778, 271, 941, 438), 'jp': (778, 271, 941, 438), 'tw': (778, 271, 941, 438)}, file={'cn': './assets/cn/os_ash/HELP_3.png', 'en': './assets/en/os_ash/HELP_3.png', 'jp': './assets/jp/os_ash/HELP_3.png', 'tw': './assets/tw/os_ash/HELP_3.png'})
|
||||
HELP_CONFIRM = Button(area={'cn': (742, 500, 914, 557), 'en': (748, 505, 908, 552), 'jp': (741, 500, 915, 557), 'tw': (742, 500, 914, 557)}, color={'cn': (94, 143, 203), 'en': (114, 156, 209), 'jp': (91, 139, 198), 'tw': (94, 143, 203)}, button={'cn': (742, 500, 914, 557), 'en': (748, 505, 908, 552), 'jp': (741, 500, 915, 557), 'tw': (742, 500, 914, 557)}, file={'cn': './assets/cn/os_ash/HELP_CONFIRM.png', 'en': './assets/en/os_ash/HELP_CONFIRM.png', 'jp': './assets/jp/os_ash/HELP_CONFIRM.png', 'tw': './assets/tw/os_ash/HELP_CONFIRM.png'})
|
||||
HELP_ENTER = Button(area={'cn': (894, 635, 1013, 699), 'en': (875, 639, 1011, 695), 'jp': (866, 636, 1010, 697), 'tw': (894, 636, 1011, 698)}, color={'cn': (210, 130, 130), 'en': (220, 160, 160), 'jp': (207, 131, 131), 'tw': (208, 127, 127)}, button={'cn': (894, 635, 1013, 699), 'en': (875, 639, 1011, 695), 'jp': (866, 636, 1010, 697), 'tw': (894, 636, 1011, 698)}, file={'cn': './assets/cn/os_ash/HELP_ENTER.png', 'en': './assets/en/os_ash/HELP_ENTER.png', 'jp': './assets/jp/os_ash/HELP_ENTER.png', 'tw': './assets/tw/os_ash/HELP_ENTER.png'})
|
||||
META_AUTO_ATTACKING = Button(area={'cn': (746, 649, 778, 680), 'en': (746, 649, 778, 680), 'jp': (746, 649, 778, 680), 'tw': (746, 649, 778, 680)}, color={'cn': (111, 95, 93), 'en': (111, 95, 93), 'jp': (111, 95, 93), 'tw': (111, 95, 93)}, button={'cn': (746, 649, 778, 680), 'en': (746, 649, 778, 680), 'jp': (746, 649, 778, 680), 'tw': (746, 649, 778, 680)}, file={'cn': './assets/cn/os_ash/META_AUTO_ATTACKING.png', 'en': './assets/en/os_ash/META_AUTO_ATTACKING.png', 'jp': './assets/jp/os_ash/META_AUTO_ATTACKING.png', 'tw': './assets/tw/os_ash/META_AUTO_ATTACKING.png'})
|
||||
META_AUTO_CONFIRM = Button(area={'cn': (608, 506, 674, 535), 'en': (608, 506, 674, 535), 'jp': (608, 506, 674, 535), 'tw': (608, 506, 674, 535)}, color={'cn': (208, 148, 141), 'en': (208, 148, 141), 'jp': (208, 148, 141), 'tw': (208, 148, 141)}, button={'cn': (608, 506, 674, 535), 'en': (608, 506, 674, 535), 'jp': (608, 506, 674, 535), 'tw': (608, 506, 674, 535)}, file={'cn': './assets/cn/os_ash/META_AUTO_CONFIRM.png', 'en': './assets/cn/os_ash/META_AUTO_CONFIRM.png', 'jp': './assets/cn/os_ash/META_AUTO_CONFIRM.png', 'tw': './assets/cn/os_ash/META_AUTO_CONFIRM.png'})
|
||||
META_BEACON_DATA = Button(area={'cn': (840, 22, 951, 45), 'en': (840, 22, 951, 45), 'jp': (840, 22, 951, 45), 'tw': (840, 22, 951, 45)}, color={'cn': (49, 53, 52), 'en': (49, 53, 52), 'jp': (49, 53, 52), 'tw': (49, 53, 52)}, button={'cn': (840, 22, 951, 45), 'en': (840, 22, 951, 45), 'jp': (840, 22, 951, 45), 'tw': (840, 22, 951, 45)}, file={'cn': './assets/cn/os_ash/META_BEACON_DATA.png', 'en': './assets/en/os_ash/META_BEACON_DATA.png', 'jp': './assets/jp/os_ash/META_BEACON_DATA.png', 'tw': './assets/tw/os_ash/META_BEACON_DATA.png'})
|
||||
META_BEACON_FLAG = Button(area={'cn': (788, 22, 811, 45), 'en': (788, 22, 811, 45), 'jp': (788, 22, 811, 45), 'tw': (788, 22, 811, 45)}, color={'cn': (48, 111, 134), 'en': (48, 111, 134), 'jp': (48, 111, 134), 'tw': (48, 111, 134)}, button={'cn': (788, 22, 811, 45), 'en': (788, 22, 811, 45), 'jp': (788, 22, 811, 45), 'tw': (788, 22, 811, 45)}, file={'cn': './assets/cn/os_ash/META_BEACON_FLAG.png', 'en': './assets/en/os_ash/META_BEACON_FLAG.png', 'jp': './assets/jp/os_ash/META_BEACON_FLAG.png', 'tw': './assets/tw/os_ash/META_BEACON_FLAG.png'})
|
||||
META_BEGIN_ENTRANCE = Button(area={'cn': (546, 115, 748, 503), 'en': (546, 115, 748, 503), 'jp': (546, 115, 748, 503), 'tw': (546, 115, 748, 503)}, color={'cn': (36, 35, 34), 'en': (36, 35, 34), 'jp': (36, 35, 34), 'tw': (36, 35, 34)}, button={'cn': (546, 115, 748, 503), 'en': (546, 115, 748, 503), 'jp': (546, 115, 748, 503), 'tw': (546, 115, 748, 503)}, file={'cn': './assets/cn/os_ash/META_BEGIN_ENTRANCE.png', 'en': './assets/en/os_ash/META_BEGIN_ENTRANCE.png', 'jp': './assets/jp/os_ash/META_BEGIN_ENTRANCE.png', 'tw': './assets/tw/os_ash/META_BEGIN_ENTRANCE.png'})
|
||||
META_DAMAGE = Button(area={'cn': (1196, 380, 1276, 416), 'en': (1196, 380, 1276, 416), 'jp': (1196, 380, 1276, 416), 'tw': (1196, 380, 1276, 416)}, color={'cn': (58, 59, 58), 'en': (58, 59, 58), 'jp': (58, 59, 58), 'tw': (58, 59, 58)}, button={'cn': (1196, 380, 1276, 416), 'en': (1196, 380, 1276, 416), 'jp': (1196, 380, 1276, 416), 'tw': (1196, 380, 1276, 416)}, file={'cn': './assets/cn/os_ash/META_DAMAGE.png', 'en': './assets/en/os_ash/META_DAMAGE.png', 'jp': './assets/jp/os_ash/META_DAMAGE.png', 'tw': './assets/tw/os_ash/META_DAMAGE.png'})
|
||||
META_DOSSIER_DATA = Button(area={'cn': (1050, 22, 1161, 46), 'en': (1050, 22, 1161, 46), 'jp': (1050, 22, 1161, 46), 'tw': (1050, 22, 1161, 46)}, color={'cn': (53, 56, 56), 'en': (53, 56, 56), 'jp': (53, 56, 56), 'tw': (53, 56, 56)}, button={'cn': (1050, 22, 1161, 46), 'en': (1050, 22, 1161, 46), 'jp': (1050, 22, 1161, 46), 'tw': (1050, 22, 1161, 46)}, file={'cn': './assets/cn/os_ash/META_DOSSIER_DATA.png', 'en': './assets/en/os_ash/META_DOSSIER_DATA.png', 'jp': './assets/jp/os_ash/META_DOSSIER_DATA.png', 'tw': './assets/tw/os_ash/META_DOSSIER_DATA.png'})
|
||||
META_DOSSIER_FLAG = Button(area={'cn': (999, 22, 1022, 45), 'en': (999, 22, 1022, 45), 'jp': (999, 22, 1022, 45), 'tw': (999, 22, 1022, 45)}, color={'cn': (123, 70, 44), 'en': (123, 70, 44), 'jp': (123, 70, 44), 'tw': (123, 70, 44)}, button={'cn': (999, 22, 1022, 45), 'en': (999, 22, 1022, 45), 'jp': (999, 22, 1022, 45), 'tw': (999, 22, 1022, 45)}, file={'cn': './assets/cn/os_ash/META_DOSSIER_FLAG.png', 'en': './assets/en/os_ash/META_DOSSIER_FLAG.png', 'jp': './assets/jp/os_ash/META_DOSSIER_FLAG.png', 'tw': './assets/tw/os_ash/META_DOSSIER_FLAG.png'})
|
||||
META_ENTRANCE = Button(area={'cn': (578, 463, 623, 493), 'en': (578, 463, 623, 493), 'jp': (578, 463, 623, 493), 'tw': (578, 463, 623, 493)}, color={'cn': (106, 134, 169), 'en': (106, 134, 169), 'jp': (106, 134, 169), 'tw': (106, 134, 169)}, button={'cn': (578, 463, 623, 493), 'en': (578, 463, 623, 493), 'jp': (578, 463, 623, 493), 'tw': (578, 463, 623, 493)}, file={'cn': './assets/cn/os_ash/META_ENTRANCE.png', 'en': './assets/en/os_ash/META_ENTRANCE.png', 'jp': './assets/jp/os_ash/META_ENTRANCE.png', 'tw': './assets/tw/os_ash/META_ENTRANCE.png'})
|
||||
META_INNER_PAGE_DAMAGE = Button(area={'cn': (936, 105, 1029, 128), 'en': (936, 105, 1029, 128), 'jp': (936, 105, 1029, 128), 'tw': (936, 105, 1029, 128)}, color={'cn': (148, 105, 105), 'en': (148, 105, 105), 'jp': (148, 105, 105), 'tw': (148, 105, 105)}, button={'cn': (936, 105, 1029, 128), 'en': (936, 105, 1029, 128), 'jp': (936, 105, 1029, 128), 'tw': (936, 105, 1029, 128)}, file={'cn': './assets/cn/os_ash/META_INNER_PAGE_DAMAGE.png', 'en': './assets/cn/os_ash/META_INNER_PAGE_DAMAGE.png', 'jp': './assets/cn/os_ash/META_INNER_PAGE_DAMAGE.png', 'tw': './assets/cn/os_ash/META_INNER_PAGE_DAMAGE.png'})
|
||||
META_INNER_PAGE_NOT_DAMAGE = Button(area={'cn': (936, 105, 1029, 128), 'en': (936, 105, 1029, 128), 'jp': (936, 105, 1029, 128), 'tw': (936, 105, 1029, 128)}, color={'cn': (68, 71, 72), 'en': (68, 71, 72), 'jp': (68, 71, 72), 'tw': (68, 71, 72)}, button={'cn': (936, 105, 1029, 128), 'en': (936, 105, 1029, 128), 'jp': (936, 105, 1029, 128), 'tw': (936, 105, 1029, 128)}, file={'cn': './assets/cn/os_ash/META_INNER_PAGE_NOT_DAMAGE.png', 'en': './assets/cn/os_ash/META_INNER_PAGE_NOT_DAMAGE.png', 'jp': './assets/cn/os_ash/META_INNER_PAGE_NOT_DAMAGE.png', 'tw': './assets/cn/os_ash/META_INNER_PAGE_NOT_DAMAGE.png'})
|
||||
META_MAIN_BEACON_ENTRANCE = Button(area={'cn': (275, 162, 567, 557), 'en': (275, 162, 567, 557), 'jp': (275, 162, 567, 557), 'tw': (275, 162, 567, 557)}, color={'cn': (68, 56, 52), 'en': (68, 56, 52), 'jp': (68, 56, 52), 'tw': (68, 56, 52)}, button={'cn': (275, 162, 567, 557), 'en': (275, 162, 567, 557), 'jp': (275, 162, 567, 557), 'tw': (275, 162, 567, 557)}, file={'cn': './assets/cn/os_ash/META_MAIN_BEACON_ENTRANCE.png', 'en': './assets/en/os_ash/META_MAIN_BEACON_ENTRANCE.png', 'jp': './assets/jp/os_ash/META_MAIN_BEACON_ENTRANCE.png', 'tw': './assets/tw/os_ash/META_MAIN_BEACON_ENTRANCE.png'})
|
||||
META_MAIN_DOSSIER_ENTRANCE = Button(area={'cn': (706, 163, 998, 557), 'en': (706, 163, 998, 557), 'jp': (706, 163, 998, 557), 'tw': (706, 163, 998, 557)}, color={'cn': (91, 82, 79), 'en': (91, 82, 79), 'jp': (91, 82, 79), 'tw': (91, 82, 79)}, button={'cn': (706, 163, 998, 557), 'en': (706, 163, 998, 557), 'jp': (706, 163, 998, 557), 'tw': (706, 163, 998, 557)}, file={'cn': './assets/cn/os_ash/META_MAIN_DOSSIER_ENTRANCE.png', 'en': './assets/en/os_ash/META_MAIN_DOSSIER_ENTRANCE.png', 'jp': './assets/jp/os_ash/META_MAIN_DOSSIER_ENTRANCE.png', 'tw': './assets/tw/os_ash/META_MAIN_DOSSIER_ENTRANCE.png'})
|
||||
|
444
module/os_ash/meta.py
Normal file
@ -0,0 +1,444 @@
|
||||
from enum import Enum
|
||||
|
||||
import module.config.server as server
|
||||
from module.base.timer import Timer
|
||||
from module.combat.assets import BATTLE_PREPARATION
|
||||
from module.logger import logger
|
||||
from module.ocr.ocr import DigitCounter, Digit
|
||||
from module.os_ash.ash import AshCombat
|
||||
from module.os_ash.assets import *
|
||||
from module.os_handler.map_event import MapEventHandler
|
||||
from module.ui.assets import BACK_ARROW
|
||||
from module.ui.page import page_reward
|
||||
from module.ui.ui import UI
|
||||
|
||||
|
||||
class MetaState(Enum):
|
||||
INIT = 'no meta begin'
|
||||
ATTACKING = 'a meta under attack'
|
||||
COMPLETE = 'reward to be collected'
|
||||
UNDEFINED = 'a undefined page'
|
||||
|
||||
|
||||
OCR_BEACON_TIER = Digit(BEACON_TIER, name='OCR_ASH_TIER')
|
||||
OCR_META_DAMAGE = Digit(META_DAMAGE, name='OCR_META_DAMAGE')
|
||||
|
||||
|
||||
class Meta(UI, MapEventHandler):
|
||||
|
||||
def digit_ocr_point_and_check(self, button: Button, check_number: int):
|
||||
point_ocr = DigitCounter(button, letter=(235, 235, 235), threshold=160, name='POINT_OCR')
|
||||
point, _, _ = point_ocr.ocr(self.device.image)
|
||||
if point >= check_number:
|
||||
return True
|
||||
return False
|
||||
|
||||
def handle_map_event(self, drop=None):
|
||||
if super().handle_map_event(drop):
|
||||
return True
|
||||
if self.appear_then_click(META_AUTO_CONFIRM, offset=(20, 20), interval=2):
|
||||
logger.info('Find auto attack complete')
|
||||
return True
|
||||
if self.appear(HELP_CONFIRM, offset=(30, 30), interval=2):
|
||||
logger.info('Accidentally click HELP_ENTER')
|
||||
self.device.click(BACK_ARROW)
|
||||
return True
|
||||
if self.appear(BATTLE_PREPARATION, offset=(30, 30), interval=2):
|
||||
logger.info('Game auto into battle preparation page')
|
||||
self.device.click(BACK_ARROW)
|
||||
return True
|
||||
if self.handle_popup_cancel():
|
||||
return True
|
||||
|
||||
|
||||
def _server_support():
|
||||
return server.server == 'cn'
|
||||
|
||||
|
||||
class OpsiAshBeacon(Meta):
|
||||
|
||||
def _attack_meta(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Handle all META attack events.
|
||||
|
||||
Pages:
|
||||
in: in_meta
|
||||
out: in_meta
|
||||
"""
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.handle_map_event():
|
||||
continue
|
||||
state = self._get_state()
|
||||
logger.info('Meta state:' + state.name)
|
||||
if MetaState.UNDEFINED == state:
|
||||
continue
|
||||
if MetaState.INIT == state:
|
||||
if self._begin_meta():
|
||||
continue
|
||||
else:
|
||||
# Normal finish
|
||||
break
|
||||
if MetaState.ATTACKING == state:
|
||||
if not self._pre_attack():
|
||||
continue
|
||||
if self._satisfy_attack_condition():
|
||||
self._make_an_attack()
|
||||
continue
|
||||
if MetaState.COMPLETE == state:
|
||||
self._handle_ash_beacon_reward()
|
||||
# Check other tasks after kill a meta
|
||||
self.config.check_task_switch()
|
||||
continue
|
||||
|
||||
def _make_an_attack(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Handle a meta combat.
|
||||
|
||||
Pages:
|
||||
in: in_meta, ASH_START
|
||||
out: in_meta, ASH_START or BEACON_REWARD
|
||||
"""
|
||||
logger.hr('Begin meta combat', level=2)
|
||||
# Attack
|
||||
combat = AshCombat(config=self.config, device=self.device)
|
||||
combat.combat(expected_end=self._in_meta_page, save_get_items=False, emotion_reduce=False)
|
||||
timer = Timer(1, count=2).start()
|
||||
# Finish random events
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self._in_meta_page():
|
||||
if timer.reached():
|
||||
logger.info('Meta combat finished and in meta page')
|
||||
break
|
||||
else:
|
||||
timer.reset()
|
||||
if self.handle_map_event():
|
||||
continue
|
||||
|
||||
def _handle_ash_beacon_reward(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Reward meta.
|
||||
|
||||
Pages:
|
||||
in: in_meta, BEACON_REWARD
|
||||
out: in_meta
|
||||
"""
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear_then_click(BEACON_REWARD, offset=(30, 30), interval=2):
|
||||
logger.info('Reap meta rewards')
|
||||
continue
|
||||
if self._in_meta_page():
|
||||
break
|
||||
# Finish random events
|
||||
if self.handle_map_event():
|
||||
continue
|
||||
|
||||
def _satisfy_attack_condition(self):
|
||||
"""
|
||||
Check whether this meta can be attacked.
|
||||
In beacon:
|
||||
when enable OneHitMode and has attacked, not allow attack.
|
||||
In Dossier:
|
||||
when enable autoAttack, not allow attack
|
||||
"""
|
||||
if self.appear(BEACON_LIST, offset=(20, 20)):
|
||||
# Enable OneHitMode and had attack this meta
|
||||
if _server_support() and self.config.OpsiAshBeacon_OneHitMode:
|
||||
damage = self._get_meta_damage()
|
||||
if damage > 0:
|
||||
logger.info('Enable OneHitMode and meta damage is ' + str(damage) + ', check after 30 minutes')
|
||||
self.config.task_delay(minute=30)
|
||||
self.config.task_stop()
|
||||
if self.appear(DOSSIER_LIST, offset=(20, 20)):
|
||||
# Meta is Auto Attacking
|
||||
if self.appear(META_AUTO_ATTACKING, offset=(20, 20)):
|
||||
logger.info('This meta is auto attacking, check after 15 minutes')
|
||||
self.config.task_delay(minute=15)
|
||||
self.config.task_stop()
|
||||
return True
|
||||
|
||||
def _get_meta_damage(self):
|
||||
"""
|
||||
Get the damage the from current meta
|
||||
"""
|
||||
self._ensure_meta_inner_page_damage()
|
||||
return OCR_META_DAMAGE.ocr(self.device.image)
|
||||
|
||||
def _ensure_meta_inner_page_damage(self, skip_first_screenshot=True):
|
||||
"""
|
||||
Switch inner page ensure in damage, not information.
|
||||
|
||||
Pages:
|
||||
in: in_meta, ASH_START
|
||||
out: in_meta, META_INNER_PAGE_DAMAGE, ASH_START
|
||||
"""
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.appear(META_INNER_PAGE_DAMAGE, offset=(20, 20)) \
|
||||
and META_INNER_PAGE_DAMAGE.match_appear_on(self.device.image):
|
||||
logger.info('Already in meta damage page')
|
||||
break
|
||||
if self.appear(META_INNER_PAGE_NOT_DAMAGE, offset=(20, 20)) \
|
||||
and META_INNER_PAGE_NOT_DAMAGE.match_appear_on(self.device.image):
|
||||
logger.info('In meta details page, should switch to damage page')
|
||||
self.appear_then_click(META_INNER_PAGE_NOT_DAMAGE, offset=(20, 20), interval=2)
|
||||
continue
|
||||
|
||||
def _pre_attack(self):
|
||||
"""
|
||||
Some pre_attack preparations.
|
||||
In beacon:
|
||||
ask for help if needed
|
||||
In dossier:
|
||||
do nothing this version
|
||||
"""
|
||||
# Page beacon or dossier
|
||||
if self.appear(BEACON_LIST, offset=(20, 20)):
|
||||
if self.config.OpsiAshBeacon_OneHitMode or self.config.OpsiAshBeacon_RequestAssist:
|
||||
self._ask_for_help()
|
||||
return True
|
||||
if self.appear(DOSSIER_LIST, offset=(20, 20)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _ask_for_help(self):
|
||||
"""
|
||||
Request help from friends, guild and world.
|
||||
|
||||
Pages:
|
||||
in: is_in_meta
|
||||
out: is_in_meta
|
||||
"""
|
||||
self.ui_click(click_button=HELP_ENTER, check_button=HELP_CONFIRM)
|
||||
# Here use simple clicks. Dropping some clicks is acceptable, no need to confirm they are selected.
|
||||
self.device.click(HELP_1)
|
||||
self.device.sleep((0.1, 0.3))
|
||||
self.device.click(HELP_2)
|
||||
self.device.sleep((0.1, 0.3))
|
||||
self.device.click(HELP_3)
|
||||
self.ui_click(click_button=HELP_CONFIRM, check_button=HELP_ENTER)
|
||||
|
||||
def _begin_meta(self):
|
||||
"""
|
||||
No matter which meta page you are in, start or select a meta.
|
||||
In meta main:
|
||||
select beacon or dossier entrance into if needed, or end task
|
||||
In beacon or dossier:
|
||||
begin a new meta if needed, or back to meta main page
|
||||
"""
|
||||
# Page meta main
|
||||
if self.appear(ASH_SHOWDOWN, offset=(30, 30), interval=2):
|
||||
if self.config.OpsiAshBeacon_AshAttack \
|
||||
and self._check_beacon_point():
|
||||
self.device.click(META_MAIN_BEACON_ENTRANCE)
|
||||
logger.info('Select beacon entrance into')
|
||||
return True
|
||||
if _server_support() \
|
||||
and self.config.OpsiDossierBeacon_Enable \
|
||||
and self._check_dossier_point():
|
||||
self.device.click(META_MAIN_DOSSIER_ENTRANCE)
|
||||
logger.info('Select dossier entrance into')
|
||||
return True
|
||||
return False
|
||||
# Page beacon
|
||||
elif self.appear(BEACON_LIST, offset=(20, 20), interval=2):
|
||||
if self.config.OpsiAshBeacon_AshAttack \
|
||||
and self._check_beacon_point():
|
||||
self.device.click(META_BEGIN_ENTRANCE)
|
||||
logger.info('Begin a beacon')
|
||||
else:
|
||||
self.appear_then_click(ASH_QUIT, offset=(10, 10), interval=2)
|
||||
return True
|
||||
# Page dossier
|
||||
elif _server_support() \
|
||||
and self.appear(DOSSIER_LIST, offset=(20, 20), interval=2):
|
||||
if self.config.OpsiDossierBeacon_Enable \
|
||||
and self._check_dossier_point():
|
||||
self.device.click(META_BEGIN_ENTRANCE)
|
||||
logger.info('Begin a dossier')
|
||||
else:
|
||||
self.appear_then_click(ASH_QUIT, offset=(10, 10), interval=2)
|
||||
return True
|
||||
# UnKnown Page
|
||||
else:
|
||||
return True
|
||||
|
||||
def _check_beacon_point(self) -> bool:
|
||||
if self.appear(META_BEACON_FLAG, offset=(180, 20)):
|
||||
META_BEACON_DATA.load_offset(META_BEACON_FLAG)
|
||||
return self.digit_ocr_point_and_check(META_BEACON_DATA.button, 100)
|
||||
return False
|
||||
|
||||
def _check_dossier_point(self) -> bool:
|
||||
if self.appear(META_DOSSIER_FLAG, offset=(180, 20)):
|
||||
META_DOSSIER_DATA.load_offset(META_DOSSIER_FLAG)
|
||||
return self.digit_ocr_point_and_check(META_DOSSIER_DATA.button, 100)
|
||||
return False
|
||||
|
||||
def _get_state(self):
|
||||
# Page UnKnown
|
||||
if not self._in_meta_page():
|
||||
return MetaState.UNDEFINED
|
||||
# Page beacon or dossier
|
||||
elif self.appear(BEACON_LIST, offset=(20, 20)) \
|
||||
or self.appear(DOSSIER_LIST, offset=(20, 20)):
|
||||
if self.appear(HELP_ENTER, offset=(30, 30)):
|
||||
return MetaState.ATTACKING
|
||||
elif self.appear(BEACON_REWARD, offset=(20, 20)):
|
||||
return MetaState.COMPLETE
|
||||
return MetaState.INIT
|
||||
elif self.appear(ASH_SHOWDOWN, offset=(30, 30)):
|
||||
return MetaState.INIT
|
||||
return MetaState.UNDEFINED
|
||||
|
||||
def _in_meta_page(self):
|
||||
return self.appear(ASH_SHOWDOWN, offset=(30, 30)) \
|
||||
or self.appear(BEACON_LIST, offset=(20, 20)) \
|
||||
or self.appear(DOSSIER_LIST, offset=(20, 20))
|
||||
|
||||
def _ensure_meta_page(self, skip_first_screenshot=True):
|
||||
logger.info('Ensure beacon attack page')
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self._in_meta_page():
|
||||
logger.info('In meta page')
|
||||
return True
|
||||
if self.handle_map_event():
|
||||
continue
|
||||
if self.appear_then_click(META_ENTRANCE, offset=(10, 10), interval=2):
|
||||
continue
|
||||
|
||||
def _begin_beacon(self):
|
||||
logger.hr('Meta Beacon Attack')
|
||||
if not _server_support():
|
||||
logger.info("Server not support dossier beacon and OneHitMode, please contact the developer.")
|
||||
self._ensure_meta_page()
|
||||
self._attack_meta()
|
||||
|
||||
def run(self):
|
||||
self.ui_ensure(page_reward)
|
||||
self._begin_beacon()
|
||||
self.config.task_delay(server_update=True)
|
||||
|
||||
|
||||
class AshBeaconAssist(Meta):
|
||||
finished = False
|
||||
|
||||
def _attack_meta(self, skip_first_screenshot=True):
|
||||
combat = AshCombat(config=self.config, device=self.device)
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self.handle_map_event():
|
||||
continue
|
||||
if self._satisfy_attack_condition():
|
||||
self._ensure_meta_level()
|
||||
combat.combat(expected_end=self._in_meta_assist_page, save_get_items=False, emotion_reduce=False)
|
||||
continue
|
||||
else:
|
||||
break
|
||||
|
||||
def _satisfy_attack_condition(self):
|
||||
remain_times = self.digit_ocr_point_and_check(BEACON_REMAIN, 1)
|
||||
if not remain_times:
|
||||
logger.info('No enough assist times, complete')
|
||||
self.finished = True
|
||||
return False
|
||||
if self.appear(ASH_START, offset=(20, 20)):
|
||||
return True
|
||||
else:
|
||||
logger.info('Can not find a meta to attack, check after 30 minutes')
|
||||
self.config.task_delay(minute=30)
|
||||
self.config.task_stop()
|
||||
|
||||
def _ensure_meta_level(self):
|
||||
"""
|
||||
Select an meta whose level satisfies
|
||||
"""
|
||||
# Ensure BEACON_TIER shown up
|
||||
# When entering beacon list, tier number wasn't shown immediately.
|
||||
tier = self.config.OpsiAshAssist_Tier
|
||||
logger.info('Begin find a level ' + str(tier) + ' meta')
|
||||
for n in range(10):
|
||||
if self.image_color_count(BEACON_TIER, color=(0, 0, 0), threshold=221, count=50):
|
||||
break
|
||||
|
||||
self.device.screenshot()
|
||||
if n >= 9:
|
||||
logger.warning('Waiting for beacon tier timeout')
|
||||
# Select beacon
|
||||
current = -1
|
||||
for _ in range(5):
|
||||
current = OCR_BEACON_TIER.ocr(self.device.image)
|
||||
if current >= tier:
|
||||
break
|
||||
else:
|
||||
self.device.click(BEACON_NEXT)
|
||||
self.device.sleep((0.3, 0.5))
|
||||
self.device.screenshot()
|
||||
if current < tier:
|
||||
logger.info(f'Tier {tier} beacon not found after 5 trial, use current beacon')
|
||||
logger.info('Find a beacon in level:' + str(current))
|
||||
|
||||
def _in_meta_assist_page(self):
|
||||
return self.appear(BEACON_MY, offset=(20, 20))
|
||||
|
||||
def _ensure_meta_assist_page(self, skip_first_screenshot=True):
|
||||
logger.info('Ensure beacon assist page')
|
||||
while 1:
|
||||
if skip_first_screenshot:
|
||||
skip_first_screenshot = False
|
||||
else:
|
||||
self.device.screenshot()
|
||||
|
||||
if self._in_meta_assist_page():
|
||||
logger.info('In beacon assist page')
|
||||
return True
|
||||
if self.handle_map_event():
|
||||
continue
|
||||
if self.appear_then_click(META_ENTRANCE, offset=(10, 10), interval=2):
|
||||
continue
|
||||
if self.appear(ASH_SHOWDOWN, offset=(20, 20)):
|
||||
self.device.click(META_MAIN_BEACON_ENTRANCE)
|
||||
logger.info('In meta page main')
|
||||
continue
|
||||
if self.appear_then_click(BEACON_LIST, offset=(300, 20), interval=2):
|
||||
continue
|
||||
if self.appear_then_click(DOSSIER_LIST, offset=(20, 20), interval=2):
|
||||
logger.info('In meta page dossier')
|
||||
continue
|
||||
|
||||
def _begin_meta_assist(self):
|
||||
logger.hr('Meta Beacon Assist')
|
||||
self._ensure_meta_assist_page()
|
||||
return self._attack_meta(skip_first_screenshot=False)
|
||||
|
||||
def run(self):
|
||||
self.ui_ensure(page_reward)
|
||||
self._begin_meta_assist()
|
||||
self.config.task_delay(server_update=True)
|