diff --git a/blcrack/cracker/cracker.cpp b/blcrack/cracker/cracker.cpp index e23258a83..86ef1d399 100644 --- a/blcrack/cracker/cracker.cpp +++ b/blcrack/cracker/cracker.cpp @@ -322,6 +322,15 @@ void Cracker::disable_all() { disable_skip_story(); disable_infinite_battle(); disable_skip_air_strike_animation(); + disable_auto_once_again(); +} + +void Cracker::enable_auto_once_again() { + ENABLE(AUTO_ONCE_AGAIN); +} + +void Cracker::disable_auto_once_again() { + DISABLE(AUTO_ONCE_AGAIN); } void Cracker::enable_skip_air_strike_animation() { @@ -730,6 +739,8 @@ void Cracker::load_lua_resources() { m_lua_res.Chapter_findPath = m_state["Chapter"]["findPath"]; m_lua_res.ChapterConst_SubjectPlayer = m_state["ChapterConst"]["SubjectPlayer"]; m_lua_res.Ship_ENERGY_LOW = m_state["Ship"]["ENERGY_LOW"]; + m_lua_res.BaseUI_closeView = m_state["BaseUI"]["closeView"]; + m_lua_res.LevelMediator2_ON_RETRACKING = m_state["LevelMediator2"]["ON_RETRACKING"]; SPDLOG_INFO("Load lua functions"); m_original.GetBattleCheckResult = m_state["GetBattleCheckResult"]; @@ -772,11 +783,29 @@ void Cracker::load_lua_resources() { m_original.ContinuousOperationRuntimeData_ConsumeBattleTime = m_state["ContinuousOperationRuntimeData"]["ConsumeBattleTime"]; m_original.ActivityProxy_UseContinuousTime = m_state["ActivityProxy"]["UseContinuousTime"]; m_original.LevelScene_doPlayAirStrike = m_state["LevelScene"]["doPlayAirStrike"]; + m_original.LevelStageTotalRewardPanel_UpdateView = m_state["LevelStageTotalRewardPanel"]["UpdateView"]; } void Cracker::hook_all_lua_functions() { SPDLOG_INFO("Hook lua functions"); + // auto_once_again + m_state["LevelStageTotalRewardPanel"]["UpdateView"] = [this](sol::this_state L, Lua::VariadicArgs args) { + CALLED(LevelStageTotalRewardPanel.UpdateView) + + m_original.LevelStageTotalRewardPanel_UpdateView(L, args); + + if (IS_ENABLED(AUTO_ONCE_AGAIN)) { + Lua::Table self = args[0]; + Lua::Object chap = self["contextData"]["chapter"]; + Lua::Object auto_fight_timer = m_lua_res.Timer_New(L, [this, self, chap](sol::this_state l, Lua::VariadicArgs) { + m_original.BaseUI_emit(l, self, m_lua_res.LevelMediator2_ON_RETRACKING, chap, true); + m_lua_res.BaseUI_closeView(l, self); + }, 1, 1); + m_lua_res.Timer_Start(L, auto_fight_timer); + } + }; + // skip_air_strike_animation m_state["LevelScene"]["doPlayAirStrike"] = [this](sol::this_state L, Lua::VariadicArgs args) { CALLED(LevelScene.doPlayAirStrike) @@ -1592,6 +1621,7 @@ Cracker::Config Cracker::get_config() { SET_CONFIG_FLAG(SKIP_STORY), SET_CONFIG_FLAG(INFINITE_BATTLE), SET_CONFIG_FLAG(SKIP_AIR_STRIKE_ANIMATION), + SET_CONFIG_FLAG(AUTO_ONCE_AGAIN), }, .globle_ship_properties = m_globle_ship_properties, .global_speedup_rate = static_cast(m_global_speedup_rate), @@ -1606,6 +1636,12 @@ Cracker::Config Cracker::get_config() { #define IS_CONFIG_ENABLED(n) config.flag.n void Cracker::apply_config(Config& config) { + if(IS_CONFIG_ENABLED(AUTO_ONCE_AGAIN)) { + enable_auto_once_again(); + } else { + disable_auto_once_again(); + } + if(IS_CONFIG_ENABLED(SKIP_AIR_STRIKE_ANIMATION)) { enable_skip_air_strike_animation(); } else { diff --git a/blcrack/cracker/cracker.hpp b/blcrack/cracker/cracker.hpp index 77f93de52..a49fbd453 100644 --- a/blcrack/cracker/cracker.hpp +++ b/blcrack/cracker/cracker.hpp @@ -118,6 +118,7 @@ public: bool SKIP_STORY = false; bool INFINITE_BATTLE = false; bool SKIP_AIR_STRIKE_ANIMATION = false; + bool AUTO_ONCE_AGAIN = false; } flag; ShipProperties globle_ship_properties; int global_speedup_rate = 1; @@ -154,6 +155,9 @@ public: void disable_all(); + void enable_auto_once_again(); + void disable_auto_once_again(); + void enable_skip_air_strike_animation(); void disable_skip_air_strike_animation(); @@ -336,6 +340,7 @@ private: std::atomic SKIP_STORY = false; std::atomic INFINITE_BATTLE = false; std::atomic SKIP_AIR_STRIKE_ANIMATION = false; + std::atomic AUTO_ONCE_AGAIN = false; } m_flag; struct { @@ -388,6 +393,7 @@ private: Lua::Function ContinuousOperationRuntimeData_ConsumeBattleTime; Lua::Function ActivityProxy_UseContinuousTime; Lua::Function LevelScene_doPlayAirStrike; + Lua::Function LevelStageTotalRewardPanel_UpdateView; } m_original; struct { Lua::Function Clone; @@ -426,6 +432,8 @@ private: Lua::Function Chapter_findPath; int ChapterConst_SubjectPlayer; int Ship_ENERGY_LOW; + Lua::Function BaseUI_closeView; + std::string LevelMediator2_ON_RETRACKING; } m_lua_res; struct { diff --git a/blcrack/cracker/server.cpp b/blcrack/cracker/server.cpp index 916cda85c..447791faa 100644 --- a/blcrack/cracker/server.cpp +++ b/blcrack/cracker/server.cpp @@ -1234,6 +1234,28 @@ CrackerServer::CrackerServer() { CRACK_OK(); }); + Post("/enable_auto_once_again", [](const httplib::Request& req, httplib::Response& res) { + try { + Cracker::Instance().enable_auto_once_again(); + } catch (std::exception& e) { + SPDLOG_ERROR("Enable auto once again failed: {}", e.what()); + res.status = 500; + return; + } + CRACK_OK(); + }); + + Post("/disable_auto_once_again", [](const httplib::Request& req, httplib::Response& res) { + try { + Cracker::Instance().disable_auto_once_again(); + } catch (std::exception& e) { + SPDLOG_ERROR("Disable auto once again failed: {}", e.what()); + res.status = 500; + return; + } + CRACK_OK(); + }); + Post("/init", [](const httplib::Request& req, httplib::Response& res) { try { Cracker::Instance(); diff --git a/blcrack/cracker/ui/ui.cpp b/blcrack/cracker/ui/ui.cpp index 06778aaf7..1a8e9fef9 100644 --- a/blcrack/cracker/ui/ui.cpp +++ b/blcrack/cracker/ui/ui.cpp @@ -153,6 +153,7 @@ void CrackerUI::draw_menu() { ImGui::Checkbox("章节图自动下一战", &CONFIG_FLAG(CHAPTER_AUTO_NEXT_BATTLE)); ImGui::Checkbox("章节图自动开荒", &CONFIG_FLAG(CHAPTER_AUTO_CLEAR)); ImGui::Checkbox("无限连战", &CONFIG_FLAG(INFINITE_BATTLE)); + ImGui::Checkbox("自动再次前往", &CONFIG_FLAG(AUTO_ONCE_AGAIN)); ImGui::EndTable(); } diff --git a/config/template.json b/config/template.json index d4647476a..b1a9f4751 100644 --- a/config/template.json +++ b/config/template.json @@ -232,7 +232,8 @@ "ChapterAutoClearStepInterval": 0.5, "SkipStory": false, "InfiniteBattle": false, - "SkipAirStrikeAnimation": false + "SkipAirStrikeAnimation": false, + "AutoOnceAgain": false }, "ShipProperty": { "Method": "disable", diff --git a/module/config/argument/args.json b/module/config/argument/args.json index d7bc1622a..c0851b8d0 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -925,6 +925,10 @@ "SkipAirStrikeAnimation": { "type": "checkbox", "value": false + }, + "AutoOnceAgain": { + "type": "checkbox", + "value": false } }, "ShipProperty": { diff --git a/module/config/argument/argument.yaml b/module/config/argument/argument.yaml index 12bd79ec2..e731a551f 100644 --- a/module/config/argument/argument.yaml +++ b/module/config/argument/argument.yaml @@ -898,6 +898,7 @@ Misc: SkipStory: false InfiniteBattle: false SkipAirStrikeAnimation: false + AutoOnceAgain: false # ==================== Cheat ==================== PowerLimit: diff --git a/module/config/config_generated.py b/module/config/config_generated.py index ea9c5a988..3095e5702 100644 --- a/module/config/config_generated.py +++ b/module/config/config_generated.py @@ -553,6 +553,7 @@ class GeneratedConfig: Misc_SkipStory = False Misc_InfiniteBattle = False Misc_SkipAirStrikeAnimation = False + Misc_AutoOnceAgain = False # Group `PowerLimit` PowerLimit_Enable = True diff --git a/module/config/full_config_generated.py b/module/config/full_config_generated.py index fd6827b76..df6ac7d70 100644 --- a/module/config/full_config_generated.py +++ b/module/config/full_config_generated.py @@ -166,6 +166,7 @@ class FullGeneratedConfig: Hook_Misc_SkipStory = None Hook_Misc_InfiniteBattle = None Hook_Misc_SkipAirStrikeAnimation = None + Hook_Misc_AutoOnceAgain = None Hook_ShipProperty_Method = None Hook_ShipProperty_Factor = None Hook_ShipProperty_Armor = None diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index 5adb1ef16..7b096bbd0 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -3180,6 +3180,10 @@ "SkipAirStrikeAnimation": { "name": "Misc.SkipAirStrikeAnimation.name", "help": "Misc.SkipAirStrikeAnimation.help" + }, + "AutoOnceAgain": { + "name": "Misc.AutoOnceAgain.name", + "help": "Misc.AutoOnceAgain.help" } }, "PowerLimit": { diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index 6a7be3f1a..64dcb358c 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -3180,6 +3180,10 @@ "SkipAirStrikeAnimation": { "name": "Misc.SkipAirStrikeAnimation.name", "help": "Misc.SkipAirStrikeAnimation.help" + }, + "AutoOnceAgain": { + "name": "Misc.AutoOnceAgain.name", + "help": "Misc.AutoOnceAgain.help" } }, "PowerLimit": { diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index cbad57a10..d010816e1 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -3180,6 +3180,10 @@ "SkipAirStrikeAnimation": { "name": "跳过空袭动画", "help": "" + }, + "AutoOnceAgain": { + "name": "自动再次前往", + "help": "" } }, "PowerLimit": { diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index 8aeb661a7..da2f06a93 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -3180,6 +3180,10 @@ "SkipAirStrikeAnimation": { "name": "Misc.SkipAirStrikeAnimation.name", "help": "Misc.SkipAirStrikeAnimation.help" + }, + "AutoOnceAgain": { + "name": "Misc.AutoOnceAgain.name", + "help": "Misc.AutoOnceAgain.help" } }, "PowerLimit": { diff --git a/module/luahook/api.py b/module/luahook/api.py index 9a1985f76..2f3c9ed05 100644 --- a/module/luahook/api.py +++ b/module/luahook/api.py @@ -410,6 +410,12 @@ class CrackApi: def disable_skip_air_strike_animation(self): self.post("disable_skip_air_strike_animation") + def enable_auto_once_again(self): + self.post("enable_auto_once_again") + + def disable_auto_once_again(self): + self.post("disable_auto_once_again") + def init(self): self.post("init") diff --git a/module/luahook/crack.py b/module/luahook/crack.py index 701d92b1f..3b0723e87 100644 --- a/module/luahook/crack.py +++ b/module/luahook/crack.py @@ -47,6 +47,7 @@ ALL_ENABLE_OPS = [ CrackOp.EnableSkipStory, CrackOp.EnableInfiniteBattle, CrackOp.EnableSkipAirStrikeAnimation, + CrackOp.EnableAutoOnceAgain, ] REMOTE_PORT = 23897 @@ -343,6 +344,11 @@ def do_crack_op(config: AzurLaneConfig, device: Device, ops: Union[Type[CrackOp. api.enable_skip_air_strike_animation() elif op == CrackOp.DisableSkipAirStrikeAnimation: api.disable_skip_air_strike_animation() + elif op == CrackOp.EnableAutoOnceAgain: + if full_config.Hook_Misc_AutoOnceAgain: + api.enable_auto_once_again() + elif op == CrackOp.DisableAutoOnceAgain: + api.disable_auto_once_again() else: logger.error(f"Unsupported op: {op}") @@ -403,6 +409,7 @@ CHAPTER_CRACK_OPS = [ CrackOp.EnableSkipStory, CrackOp.EnableInfiniteBattle, CrackOp.EnableSkipAirStrikeAnimation, + CrackOp.EnableAutoOnceAgain, ] diff --git a/module/luahook/op.py b/module/luahook/op.py index 2aa19826d..1ff24b00d 100644 --- a/module/luahook/op.py +++ b/module/luahook/op.py @@ -190,3 +190,9 @@ class CrackOp: class DisableSkipAirStrikeAnimation(Op): ... + + class EnableAutoOnceAgain(Op): + ... + + class DisableAutoOnceAgain(Op): + ...