Compare commits

...

2 Commits

Author SHA1 Message Date
guoh064
50c21d7e09 Merge branch 'island_project' into test 2026-05-12 23:30:32 +08:00
guoh064
f5445d0ee5 Add: island planner freebie receive 2026-05-12 23:30:15 +08:00
32 changed files with 284 additions and 1 deletions

View File

@ -415,6 +415,10 @@ class AzurLaneAutoScript:
GemsFarming(config=self.config, device=self.device).run(
name=self.config.Campaign_Name, folder=self.config.Campaign_Event, mode=self.config.Campaign_Mode)
def island_freebie(self):
from module.island.freebie import IslandFreebie
IslandFreebie(config=self.config, device=self.device).run()
def island_season_task(self):
from module.island.season_task import IslandSeasonTaskHandler
IslandSeasonTaskHandler(config=self.config, device=self.device).run()

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -2040,6 +2040,22 @@
"Storage": {}
}
},
"IslandFreebie": {
"Scheduler": {
"Enable": false,
"NextRun": "2020-01-01 00:00:00",
"Command": "IslandFreebie",
"SuccessInterval": 0,
"FailureInterval": 120,
"ServerUpdate": "00:00"
},
"IslandFreebie": {
"Share": true
},
"Storage": {
"Storage": {}
}
},
"IslandSeasonTask": {
"Scheduler": {
"Enable": false,

View File

@ -9963,6 +9963,57 @@
}
}
},
"IslandFreebie": {
"Scheduler": {
"Enable": {
"type": "checkbox",
"value": false,
"option": [
true,
false
]
},
"NextRun": {
"type": "datetime",
"value": "2020-01-01 00:00:00",
"validate": "datetime"
},
"Command": {
"type": "input",
"value": "IslandFreebie",
"display": "hide"
},
"SuccessInterval": {
"type": "input",
"value": 0,
"display": "hide"
},
"FailureInterval": {
"type": "input",
"value": 120,
"display": "hide"
},
"ServerUpdate": {
"type": "input",
"value": "00:00",
"display": "hide"
}
},
"IslandFreebie": {
"Share": {
"type": "checkbox",
"value": true
}
},
"Storage": {
"Storage": {
"type": "storage",
"value": {},
"valuetype": "ignore",
"display": "disabled"
}
}
},
"IslandSeasonTask": {
"Scheduler": {
"Enable": {

View File

@ -778,6 +778,8 @@ IslandTechnology:
TechnologyStatus:
type: textarea
value: |-
IslandFreebie:
Share: true
# ==================== Tools ====================

View File

@ -103,6 +103,7 @@
"page": "setting",
"tasks": [
"IslandInfo",
"IslandFreebie",
"IslandSeasonTask"
]
},

View File

@ -350,6 +350,9 @@ Island:
IslandInfo:
- IslandSeasonTask
- IslandTechnology
IslandFreebie:
- Scheduler
- IslandFreebie
IslandSeasonTask:
- Scheduler

View File

@ -462,6 +462,9 @@ class GeneratedConfig:
# Group `IslandTechnology`
IslandTechnology_TechnologyStatus = None
# Group `IslandFreebie`
IslandFreebie_Share = True
# Group `Daemon`
Daemon_EnterMap = True

View File

@ -22,7 +22,7 @@ class ManualConfig:
> OpsiAshBeacon
> OpsiDaily > OpsiShop > OpsiVoucher
> OpsiAbyssal > OpsiStronghold > OpsiObscure > OpsiArchive
> IslandSeasonTask
> IslandFreebie > IslandSeasonTask
> Daily > Hard > OpsiAshBeacon > OpsiAshAssist > OpsiMonthBoss
> Sos > EventSp > EventA > EventB > EventC > EventD
> RaidDaily > CoalitionSp > WarArchives > MaritimeEscort

View File

@ -270,6 +270,10 @@
"name": "Task.IslandInfo.name",
"help": "Task.IslandInfo.help"
},
"IslandFreebie": {
"name": "Daily Supplement",
"help": ""
},
"IslandSeasonTask": {
"name": "Task.IslandSeasonTask.name",
"help": "Task.IslandSeasonTask.help"
@ -2675,6 +2679,16 @@
"help": "IslandTechnology.TechnologyStatus.help"
}
},
"IslandFreebie": {
"_info": {
"name": "Daily Supplement",
"help": ""
},
"Share": {
"name": "Share Supplement",
"help": ""
}
},
"Daemon": {
"_info": {
"name": "Semi-auto Clicking",

View File

@ -270,6 +270,10 @@
"name": "Task.IslandInfo.name",
"help": "Task.IslandInfo.help"
},
"IslandFreebie": {
"name": "Task.IslandFreebie.name",
"help": "Task.IslandFreebie.help"
},
"IslandSeasonTask": {
"name": "Task.IslandSeasonTask.name",
"help": "Task.IslandSeasonTask.help"
@ -2675,6 +2679,16 @@
"help": "IslandTechnology.TechnologyStatus.help"
}
},
"IslandFreebie": {
"_info": {
"name": "IslandFreebie._info.name",
"help": "IslandFreebie._info.help"
},
"Share": {
"name": "IslandFreebie.Share.name",
"help": "IslandFreebie.Share.help"
}
},
"Daemon": {
"_info": {
"name": "Daemon._info.name",

View File

@ -270,6 +270,10 @@
"name": "岛屿信息",
"help": "岛屿仪表盘"
},
"IslandFreebie": {
"name": "每日补给",
"help": ""
},
"IslandSeasonTask": {
"name": "赛季任务",
"help": ""
@ -2675,6 +2679,16 @@
"help": "Alas会自动导出列表"
}
},
"IslandFreebie": {
"_info": {
"name": "每日补给",
"help": ""
},
"Share": {
"name": "分享补给",
"help": ""
}
},
"Daemon": {
"_info": {
"name": "半自动点击",

View File

@ -270,6 +270,10 @@
"name": "Task.IslandInfo.name",
"help": "Task.IslandInfo.help"
},
"IslandFreebie": {
"name": "每日補給",
"help": ""
},
"IslandSeasonTask": {
"name": "Task.IslandSeasonTask.name",
"help": "Task.IslandSeasonTask.help"
@ -2675,6 +2679,16 @@
"help": "IslandTechnology.TechnologyStatus.help"
}
},
"IslandFreebie": {
"_info": {
"name": "每日補給",
"help": ""
},
"Share": {
"name": "共享補給",
"help": ""
}
},
"Daemon": {
"_info": {
"name": "半自動點擊",

View File

@ -4,6 +4,16 @@ from module.base.template import Template
# This file was automatically generated by dev_tools/button_extract.py.
# Don't modify it manually.
ISLAND_CLICK_SAFE_AREA = Button(area={'cn': (596, 687, 680, 720), 'en': (596, 687, 680, 720), 'jp': (596, 687, 680, 720), 'tw': (596, 687, 680, 720)}, color={'cn': (255, 255, 255), 'en': (255, 255, 255), 'jp': (255, 255, 255), 'tw': (255, 255, 255)}, button={'cn': (596, 687, 680, 720), 'en': (596, 687, 680, 720), 'jp': (596, 687, 680, 720), 'tw': (596, 687, 680, 720)}, file={'cn': './assets/cn/island/ISLAND_CLICK_SAFE_AREA.png', 'en': './assets/cn/island/ISLAND_CLICK_SAFE_AREA.png', 'jp': './assets/cn/island/ISLAND_CLICK_SAFE_AREA.png', 'tw': './assets/cn/island/ISLAND_CLICK_SAFE_AREA.png'})
ISLAND_FREEBIE_AVAILABLE = Button(area={'cn': (0, 600, 120, 720), 'en': (0, 600, 120, 720), 'jp': (0, 600, 120, 720), 'tw': (0, 600, 120, 720)}, color={'cn': (83, 83, 75), 'en': (83, 83, 75), 'jp': (83, 83, 75), 'tw': (83, 83, 75)}, button={'cn': (37, 631, 87, 681), 'en': (37, 631, 87, 681), 'jp': (37, 631, 87, 681), 'tw': (37, 631, 87, 681)}, file={'cn': './assets/cn/island/ISLAND_FREEBIE_AVAILABLE.gif', 'en': './assets/cn/island/ISLAND_FREEBIE_AVAILABLE.gif', 'jp': './assets/cn/island/ISLAND_FREEBIE_AVAILABLE.gif', 'tw': './assets/cn/island/ISLAND_FREEBIE_AVAILABLE.gif'})
ISLAND_FREEBIE_CLAIM = Button(area={'cn': (890, 381, 984, 405), 'en': (890, 381, 984, 405), 'jp': (890, 381, 984, 405), 'tw': (890, 381, 984, 405)}, color={'cn': (194, 195, 196), 'en': (194, 195, 196), 'jp': (194, 195, 196), 'tw': (194, 195, 196)}, button={'cn': (890, 381, 984, 405), 'en': (890, 381, 984, 405), 'jp': (890, 381, 984, 405), 'tw': (890, 381, 984, 405)}, file={'cn': './assets/cn/island/ISLAND_FREEBIE_CLAIM.png', 'en': './assets/cn/island/ISLAND_FREEBIE_CLAIM.png', 'jp': './assets/jp/island/ISLAND_FREEBIE_CLAIM.png', 'tw': './assets/cn/island/ISLAND_FREEBIE_CLAIM.png'})
ISLAND_FREEBIE_COOLDOWN = Button(area={'cn': (870, 380, 1003, 406), 'en': (870, 380, 1003, 406), 'jp': (870, 380, 1003, 406), 'tw': (870, 380, 1003, 406)}, color={'cn': (200, 202, 201), 'en': (200, 202, 201), 'jp': (200, 202, 201), 'tw': (200, 202, 201)}, button={'cn': (870, 380, 1003, 406), 'en': (870, 380, 1003, 406), 'jp': (870, 380, 1003, 406), 'tw': (870, 380, 1003, 406)}, file={'cn': './assets/cn/island/ISLAND_FREEBIE_COOLDOWN.png', 'en': './assets/cn/island/ISLAND_FREEBIE_COOLDOWN.png', 'jp': './assets/jp/island/ISLAND_FREEBIE_COOLDOWN.png', 'tw': './assets/cn/island/ISLAND_FREEBIE_COOLDOWN.png'})
ISLAND_FREEBIE_RECEIVE = Button(area={'cn': (859, 380, 1012, 406), 'en': (859, 380, 1012, 406), 'jp': (859, 380, 1012, 406), 'tw': (859, 380, 1012, 406)}, color={'cn': (205, 207, 206), 'en': (205, 207, 206), 'jp': (205, 207, 206), 'tw': (205, 207, 206)}, button={'cn': (859, 380, 1012, 406), 'en': (859, 380, 1012, 406), 'jp': (859, 380, 1012, 406), 'tw': (859, 380, 1012, 406)}, file={'cn': './assets/cn/island/ISLAND_FREEBIE_RECEIVE.png', 'en': './assets/cn/island/ISLAND_FREEBIE_RECEIVE.png', 'jp': './assets/jp/island/ISLAND_FREEBIE_RECEIVE.png', 'tw': './assets/cn/island/ISLAND_FREEBIE_RECEIVE.png'})
ISLAND_FREEBIE_SHARE = Button(area={'cn': (849, 380, 1024, 406), 'en': (849, 380, 1024, 406), 'jp': (849, 380, 1024, 406), 'tw': (849, 380, 1024, 406)}, color={'cn': (210, 214, 214), 'en': (210, 214, 214), 'jp': (210, 214, 214), 'tw': (210, 214, 214)}, button={'cn': (849, 380, 1024, 406), 'en': (849, 380, 1024, 406), 'jp': (849, 380, 1024, 406), 'tw': (849, 380, 1024, 406)}, file={'cn': './assets/cn/island/ISLAND_FREEBIE_SHARE.png', 'en': './assets/cn/island/ISLAND_FREEBIE_SHARE.png', 'jp': './assets/jp/island/ISLAND_FREEBIE_SHARE.png', 'tw': './assets/cn/island/ISLAND_FREEBIE_SHARE.png'})
ISLAND_FREEBIE_SHARE_ALL = Button(area={'cn': (724, 587, 814, 613), 'en': (724, 587, 814, 613), 'jp': (724, 587, 814, 613), 'tw': (724, 587, 814, 613)}, color={'cn': (73, 104, 128), 'en': (73, 104, 128), 'jp': (73, 104, 128), 'tw': (73, 104, 128)}, button={'cn': (724, 587, 814, 613), 'en': (724, 587, 814, 613), 'jp': (724, 587, 814, 613), 'tw': (724, 587, 814, 613)}, file={'cn': './assets/cn/island/ISLAND_FREEBIE_SHARE_ALL.png', 'en': './assets/cn/island/ISLAND_FREEBIE_SHARE_ALL.png', 'jp': './assets/jp/island/ISLAND_FREEBIE_SHARE_ALL.png', 'tw': './assets/cn/island/ISLAND_FREEBIE_SHARE_ALL.png'})
ISLAND_FREEBIE_SHARE_BACK = Button(area={'cn': (844, 101, 878, 135), 'en': (844, 101, 878, 135), 'jp': (844, 101, 878, 135), 'tw': (844, 101, 878, 135)}, color={'cn': (170, 213, 232), 'en': (170, 213, 232), 'jp': (170, 213, 232), 'tw': (170, 213, 232)}, button={'cn': (844, 101, 878, 135), 'en': (844, 101, 878, 135), 'jp': (844, 101, 878, 135), 'tw': (844, 101, 878, 135)}, file={'cn': './assets/cn/island/ISLAND_FREEBIE_SHARE_BACK.png', 'en': './assets/cn/island/ISLAND_FREEBIE_SHARE_BACK.png', 'jp': './assets/cn/island/ISLAND_FREEBIE_SHARE_BACK.png', 'tw': './assets/cn/island/ISLAND_FREEBIE_SHARE_BACK.png'})
ISLAND_GET_ITEMS = Button(area={'cn': (559, 258, 721, 291), 'en': (559, 258, 721, 291), 'jp': (559, 258, 721, 291), 'tw': (559, 258, 721, 291)}, color={'cn': (204, 206, 206), 'en': (204, 206, 206), 'jp': (204, 206, 206), 'tw': (204, 206, 206)}, button={'cn': (559, 258, 721, 291), 'en': (559, 258, 721, 291), 'jp': (559, 258, 721, 291), 'tw': (559, 258, 721, 291)}, file={'cn': './assets/cn/island/ISLAND_GET_ITEMS.png', 'en': './assets/cn/island/ISLAND_GET_ITEMS.png', 'jp': './assets/jp/island/ISLAND_GET_ITEMS.png', 'tw': './assets/cn/island/ISLAND_GET_ITEMS.png'})
ISLAND_LEVEL_UP = Button(area={'cn': (616, 339, 662, 377), 'en': (616, 339, 662, 377), 'jp': (616, 339, 662, 377), 'tw': (616, 339, 662, 377)}, color={'cn': (186, 213, 226), 'en': (186, 213, 226), 'jp': (186, 213, 226), 'tw': (186, 213, 226)}, button={'cn': (616, 339, 662, 377), 'en': (616, 339, 662, 377), 'jp': (616, 339, 662, 377), 'tw': (616, 339, 662, 377)}, file={'cn': './assets/cn/island/ISLAND_LEVEL_UP.png', 'en': './assets/cn/island/ISLAND_LEVEL_UP.png', 'jp': './assets/cn/island/ISLAND_LEVEL_UP.png', 'tw': './assets/cn/island/ISLAND_LEVEL_UP.png'})
ISLAND_SEASON_TASK_SCROLL_AREA = Button(area={'cn': (1236, 171, 1237, 604), 'en': (1236, 171, 1237, 604), 'jp': (1236, 171, 1237, 604), 'tw': (1236, 171, 1237, 604)}, color={'cn': (186, 192, 191), 'en': (186, 192, 191), 'jp': (186, 192, 191), 'tw': (186, 192, 191)}, button={'cn': (1236, 171, 1237, 604), 'en': (1236, 171, 1237, 604), 'jp': (1236, 171, 1237, 604), 'tw': (1236, 171, 1237, 604)}, file={'cn': './assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png', 'en': './assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png', 'jp': './assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png', 'tw': './assets/cn/island/ISLAND_SEASON_TASK_SCROLL_AREA.png'})
ISLAND_TECHNOLOGY_TAB1 = Button(area={'cn': (20, 575, 109, 644), 'en': (20, 575, 109, 644), 'jp': (20, 575, 109, 644), 'tw': (20, 575, 109, 644)}, color={'cn': (76, 109, 130), 'en': (76, 109, 130), 'jp': (76, 109, 130), 'tw': (76, 109, 130)}, button={'cn': (20, 575, 109, 644), 'en': (20, 575, 109, 644), 'jp': (20, 575, 109, 644), 'tw': (20, 575, 109, 644)}, file={'cn': './assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png', 'en': './assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png', 'jp': './assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png', 'tw': './assets/cn/island/ISLAND_TECHNOLOGY_TAB1.png'})
TEMPLATE_ISLAND_SEASON_REWARD = Template(file={'cn': './assets/cn/island/TEMPLATE_ISLAND_SEASON_REWARD.png', 'en': './assets/cn/island/TEMPLATE_ISLAND_SEASON_REWARD.png', 'jp': './assets/cn/island/TEMPLATE_ISLAND_SEASON_REWARD.png', 'tw': './assets/cn/island/TEMPLATE_ISLAND_SEASON_REWARD.png'})

114
module/island/freebie.py Normal file
View File

@ -0,0 +1,114 @@
from module.base.timer import Timer
from module.exception import GameStuckError
from module.handler.assets import STORY_SKIP
from module.island.ui import IslandUI
from module.island.assets import *
from module.logger import logger
from module.ui.page import page_island, page_island_manage, page_island_phone
class IslandFreebie(IslandUI):
def island_freebie_notice_appear(self):
"""
Returns:
bool: If appear.
Page:
in: page_island_manage
"""
return self.appear(ISLAND_FREEBIE_AVAILABLE, offset=(20, 20))
def freebie_move_to(self):
"""
Page:
in: page_island_manage
out: page_island
"""
for _ in self.loop(timeout=30):
if self.appear_then_click(ISLAND_FREEBIE_AVAILABLE, offset=(20, 20), interval=3):
continue
if self.ui_page_appear(page_island_phone):
logger.info('Moved to location of freebie')
self.ui_goto(page_island)
break
else:
logger.warning('Failed to move to location of freebie after 30 seconds')
raise GameStuckError(f'Failed to move to location of freebie after 30 seconds')
def freebie_claim(self):
if not self.appear(ISLAND_FREEBIE_CLAIM, offset=(20, 20)):
logger.warning('No freebie claim button')
return False
retry_wait = Timer(3, count=5).reset()
for _ in self.loop(timeout=30):
if self.appear_then_click(ISLAND_FREEBIE_CLAIM, offset=(20, 20), interval=3):
continue
if self.appear(ISLAND_FREEBIE_COOLDOWN, offset=(20, 20)):
logger.info('Claimed freebie')
break
elif self.ui_page_appear(page_island_phone):
logger.info('Misclicked into page_island_phone, go back')
self.ui_goto(page_island)
continue
elif retry_wait.reached_and_reset():
self.device.click(STORY_SKIP)
continue
def freebie_receive(self):
p1 = (217, 507)
p2 = (217 - 8, 507 + 36)
self.device.drag(p1, p2, point_random=(0, 0, 0, 0), shake_random=(0, 0, 0, 0), hold_duration=1.05)
self.device.screenshot()
if not self.appear(ISLAND_FREEBIE_RECEIVE, offset=(20, 20)):
logger.warning('Failed to receive freebie')
return False
confirm_timer = Timer(3, count=5).reset()
for _ in self.loop(skip_first=False):
if self.appear_then_click(ISLAND_FREEBIE_RECEIVE, offset=(20, 20), interval=3):
confirm_timer.reset()
continue
if self.handle_island_additional():
confirm_timer.reset()
continue
# End
if self.appear(ISLAND_FREEBIE_SHARE, offset=(20, 20)):
if confirm_timer.reached():
logger.info('Received freebie')
return True
def freebie_share(self):
if not self.appear(ISLAND_FREEBIE_SHARE, offset=(20, 20)):
logger.warning('No freebie share button')
return False
for _ in self.loop(skip_first=False):
if self.appear_then_click(ISLAND_FREEBIE_SHARE, offset=(20, 20), interval=3):
continue
if self.appear_then_click(ISLAND_FREEBIE_SHARE_ALL, offset=(20, 20), interval=3):
break
for _ in self.loop(skip_first=False):
if self.appear_then_click(ISLAND_FREEBIE_SHARE_BACK, offset=(20, 20), interval=3):
continue
if self.ui_page_appear(page_island):
logger.info('Shared freebie')
return True
def run(self):
self.ui_ensure(page_island_manage)
if self.island_freebie_notice_appear():
self.freebie_move_to()
self.freebie_claim()
self.freebie_receive()
if self.config.IslandFreebie_Share:
self.freebie_share()
else:
logger.info('No freebie notice')
self.config.task_delay(server_update=True)

View File

@ -1,5 +1,6 @@
from module.base.button import ButtonGrid
from module.base.decorator import cached_property
from module.combat.assets import GET_ITEMS_1
from module.island.assets import *
from module.ui.navbar import Navbar
from module.ui.scroll import Scroll
@ -17,6 +18,28 @@ class IslandUI(UI):
def ui_additional(self, get_ship=True):
return super().ui_additional(get_ship=False)
def handle_island_get_items(self):
if self.appear(ISLAND_GET_ITEMS, offset=(20, 20), interval=3):
self.device.click(ISLAND_CLICK_SAFE_AREA)
return True
if self.appear(GET_ITEMS_1, offset=(20, 20), interval=3):
self.device.click(ISLAND_CLICK_SAFE_AREA)
return True
return False
def handle_island_level_up(self):
if self.appear(ISLAND_LEVEL_UP, offset=(20, 20), interval=3):
self.device.click(ISLAND_CLICK_SAFE_AREA)
return True
return False
def handle_island_additional(self):
if self.handle_island_get_items():
return True
if self.handle_island_level_up():
return True
return False
@cached_property
def _island_season_bottom_navbar(self):
"""