From 30c00628f8c8ca597c648c181a2df61aeb0b1cd1 Mon Sep 17 00:00:00 2001 From: 0O0o0oOoO00 <11174151+0O0o0oOoO00@users.noreply.github.com> Date: Sun, 16 Nov 2025 19:38:48 +0800 Subject: [PATCH] add: chapter auto next battle --- blcrack/cracker/cracker.cpp | 40 ++++++++++++++++++++++++++ blcrack/cracker/cracker.hpp | 7 +++++ blcrack/cracker/server.cpp | 22 ++++++++++++++ blcrack/cracker/ui/ui.cpp | 1 + blcrack/http/cracker.http | 6 ++++ config/template.json | 3 +- module/config/argument/args.json | 4 +++ module/config/argument/argument.yaml | 1 + module/config/config_generated.py | 1 + module/config/full_config_generated.py | 1 + module/config/i18n/en-US.json | 4 +++ module/config/i18n/ja-JP.json | 4 +++ module/config/i18n/zh-CN.json | 4 +++ module/config/i18n/zh-TW.json | 4 +++ module/luahook/api.py | 6 ++++ module/luahook/crack.py | 7 +++++ module/luahook/op.py | 6 ++++ 17 files changed, 120 insertions(+), 1 deletion(-) diff --git a/blcrack/cracker/cracker.cpp b/blcrack/cracker/cracker.cpp index d77efa80a..5821a9a60 100644 --- a/blcrack/cracker/cracker.cpp +++ b/blcrack/cracker/cracker.cpp @@ -248,6 +248,7 @@ void Cracker::disable_all() { disable_skip_ship_gain_show(); disable_chapter_force_enable_auto_fight(); disable_chapter_skip_precombat(); + disable_chapter_auto_next_battle(); } void Cracker::enable_hooked_lua_function_trace() { @@ -266,6 +267,14 @@ void Cracker::disable_chapter_skip_precombat() { DISABLE(CHAPTER_SKIP_PRECOMBAT); } +void Cracker::enable_chapter_auto_next_battle() { + ENABLE(CHAPTER_AUTO_NEXT_BATTLE); +} + +void Cracker::disable_chapter_auto_next_battle() { + DISABLE(CHAPTER_AUTO_NEXT_BATTLE); +} + void Cracker::enable_chapter_force_enable_auto_fight() { ENABLE(CHAPTER_FORCE_ENABLE_AUTO_FIGHT); } @@ -554,6 +563,7 @@ void Cracker::load_lua_resources() { m_lua_res.getProxy = m_state["getProxy"]; m_lua_res.ChapterProxy = m_state["ChapterProxy"]; m_lua_res.ChapterProxy_GetChapterAutoFlag = m_state["ChapterProxy"]["GetChapterAutoFlag"]; + m_lua_res.ChapterProxy_SetChapterAutoFlag = m_state["ChapterProxy"]["SetChapterAutoFlag"]; SPDLOG_INFO("Load lua functions"); m_original.GetBattleCheckResult = m_state["GetBattleCheckResult"]; @@ -588,11 +598,34 @@ void Cracker::load_lua_resources() { m_original.Chapter_CanActivateAutoFight = m_state["Chapter"]["CanActivateAutoFight"]; m_original.Chapter_IsAutoFight = m_state["Chapter"]["IsAutoFight"]; m_original.Chapter_IsSkipPrecombat = m_state["Chapter"]["IsSkipPrecombat"]; + m_original.Chapter_writeBack = m_state["Chapter"]["writeBack"]; } void Cracker::hook_all_lua_functions() { SPDLOG_INFO("Hook lua functions"); + // chapter_auto_next_battle + m_state["Chapter"]["writeBack"] = [this](sol::this_state L, Lua::VariadicArgs args) { + CALLED(Chapter.writeBack); + + if (!IS_ENABLED(CHAPTER_AUTO_NEXT_BATTLE)) { + m_original.Chapter_writeBack(L, args); + return; + } + + m_original.Chapter_writeBack(L, args); + + bool is_win = args[1]; + if (!is_win) { + return; + } + + Lua::Table self = args[0]; + Lua::Object chapter_proxy = m_lua_res.getProxy(L, m_lua_res.ChapterProxy); + int id = self["id"]; + m_lua_res.ChapterProxy_SetChapterAutoFlag(L, chapter_proxy, id, true); + }; + // chapter_skip_precombat m_state["Chapter"]["IsSkipPrecombat"] = [this](sol::this_state L, Lua::VariadicArgs args) -> Lua::Object { CALLED(Chapter.IsSkipPrecombat); @@ -1255,6 +1288,7 @@ Cracker::Config Cracker::get_config() { SET_CONFIG_FLAG(SKIP_SHIP_GAIN_SHOW), SET_CONFIG_FLAG(CHAPTER_FORCE_ENABLE_AUTO_FIGHT), SET_CONFIG_FLAG(CHAPTER_SKIP_PRECOMBAT), + SET_CONFIG_FLAG(CHAPTER_AUTO_NEXT_BATTLE), }, .globle_ship_properties = m_globle_ship_properties, .global_speedup_rate = static_cast(m_global_speedup_rate), @@ -1286,6 +1320,12 @@ void Cracker::apply_config(Config& config) { disable_chapter_force_enable_auto_fight(); } + if(IS_CONFIG_ENABLED(CHAPTER_AUTO_NEXT_BATTLE)) { + enable_chapter_auto_next_battle(); + } else { + disable_chapter_auto_next_battle(); + } + if(IS_CONFIG_ENABLED(SKIP_SHIP_GAIN_SHOW)) { enable_skip_ship_gain_show(); } else { diff --git a/blcrack/cracker/cracker.hpp b/blcrack/cracker/cracker.hpp index 1143396ea..2451814b5 100644 --- a/blcrack/cracker/cracker.hpp +++ b/blcrack/cracker/cracker.hpp @@ -93,6 +93,7 @@ public: bool SKIP_SHIP_GAIN_SHOW = false; bool CHAPTER_FORCE_ENABLE_AUTO_FIGHT = false; bool CHAPTER_SKIP_PRECOMBAT = false; + bool CHAPTER_AUTO_NEXT_BATTLE = false; } flag; ShipProperties globle_ship_properties; int global_speedup_rate = 1; @@ -134,6 +135,9 @@ public: void enable_chapter_skip_precombat(); void disable_chapter_skip_precombat(); + void enable_chapter_auto_next_battle(); + void disable_chapter_auto_next_battle(); + void enable_chapter_force_enable_auto_fight(); void disable_chapter_force_enable_auto_fight(); @@ -246,6 +250,7 @@ private: std::atomic SKIP_SHIP_GAIN_SHOW = false; std::atomic CHAPTER_FORCE_ENABLE_AUTO_FIGHT = false; std::atomic CHAPTER_SKIP_PRECOMBAT = false; + std::atomic CHAPTER_AUTO_NEXT_BATTLE = false; } m_flag; struct { @@ -289,6 +294,7 @@ private: Lua::Function Chapter_CanActivateAutoFight; Lua::Function Chapter_IsAutoFight; Lua::Function Chapter_IsSkipPrecombat; + Lua::Function Chapter_writeBack; } m_original; struct { Lua::Function Clone; @@ -310,6 +316,7 @@ private: Lua::Function getProxy; Lua::Table ChapterProxy; Lua::Function ChapterProxy_GetChapterAutoFlag; + Lua::Function ChapterProxy_SetChapterAutoFlag; } m_lua_res; std::atomic m_exercise_more_power_rate = 0.03; FakePlayerInfo m_fake_player_info; diff --git a/blcrack/cracker/server.cpp b/blcrack/cracker/server.cpp index 4e0fd237d..f303f7baa 100644 --- a/blcrack/cracker/server.cpp +++ b/blcrack/cracker/server.cpp @@ -960,6 +960,28 @@ CrackerServer::CrackerServer() { CRACK_OK(); }); + Post("/enable_chapter_auto_next_battle", [](const httplib::Request& req, httplib::Response& res) { + try { + Cracker::Instance().enable_chapter_auto_next_battle(); + } catch (std::exception& e) { + SPDLOG_ERROR("Enable chapter auto next battle failed: {}", e.what()); + res.status = 500; + return; + } + CRACK_OK(); + }); + + Post("/disable_chapter_auto_next_battle", [](const httplib::Request& req, httplib::Response& res) { + try { + Cracker::Instance().disable_chapter_auto_next_battle(); + } catch (std::exception& e) { + SPDLOG_ERROR("Disable chapter auto next battle 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 b3e0c599e..58a4bdb21 100644 --- a/blcrack/cracker/ui/ui.cpp +++ b/blcrack/cracker/ui/ui.cpp @@ -115,6 +115,7 @@ void CrackerUI::draw_menu() { ImGui::Checkbox("无伤害无击杀", &CONFIG_FLAG(NO_DAMAGE)); ImGui::Checkbox("全皮肤", &CONFIG_FLAG(ALL_SKIN)); ImGui::Checkbox("跳过舰船获取展示", &CONFIG_FLAG(SKIP_SHIP_GAIN_SHOW)); + ImGui::Checkbox("章节图自动下一战", &CONFIG_FLAG(CHAPTER_AUTO_NEXT_BATTLE)); ImGui::EndTable(); } diff --git a/blcrack/http/cracker.http b/blcrack/http/cracker.http index 35d7959e0..4918dbf73 100644 --- a/blcrack/http/cracker.http +++ b/blcrack/http/cracker.http @@ -197,6 +197,12 @@ POST http://{{Host}}:{{Port}}/enable_chapter_skip_precombat ### POST http://{{Host}}:{{Port}}/disable_chapter_skip_precombat +### +POST http://{{Host}}:{{Port}}/enable_chapter_auto_next_battle + +### +POST http://{{Host}}:{{Port}}/disable_chapter_auto_next_battle + ### POST http://{{Host}}:{{Port}}/is_alive diff --git a/config/template.json b/config/template.json index 7dc0c15ec..16cd0b57e 100644 --- a/config/template.json +++ b/config/template.json @@ -224,7 +224,8 @@ "OpsiNoMapFog": false, "SkipShipGainShow": false, "ChapterForceEnableAutoFight": false, - "ChapterSkipPrecombat": false + "ChapterSkipPrecombat": false, + "ChapterAutoNextBattle": false }, "ShipProperty": { "Method": "disable", diff --git a/module/config/argument/args.json b/module/config/argument/args.json index ab91a0530..17cc0aed5 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -893,6 +893,10 @@ "ChapterSkipPrecombat": { "type": "checkbox", "value": false + }, + "ChapterAutoNextBattle": { + "type": "checkbox", + "value": false } }, "ShipProperty": { diff --git a/module/config/argument/argument.yaml b/module/config/argument/argument.yaml index fc19155e6..83612f229 100644 --- a/module/config/argument/argument.yaml +++ b/module/config/argument/argument.yaml @@ -889,6 +889,7 @@ Misc: SkipShipGainShow: false ChapterForceEnableAutoFight: false ChapterSkipPrecombat: false + ChapterAutoNextBattle: false # ==================== Cheat ==================== PowerLimit: diff --git a/module/config/config_generated.py b/module/config/config_generated.py index c5ba9813f..9105e89b6 100644 --- a/module/config/config_generated.py +++ b/module/config/config_generated.py @@ -544,6 +544,7 @@ class GeneratedConfig: Misc_SkipShipGainShow = False Misc_ChapterForceEnableAutoFight = False Misc_ChapterSkipPrecombat = False + Misc_ChapterAutoNextBattle = False # Group `PowerLimit` PowerLimit_Enable = True diff --git a/module/config/full_config_generated.py b/module/config/full_config_generated.py index e6032c7d6..c109f20c8 100644 --- a/module/config/full_config_generated.py +++ b/module/config/full_config_generated.py @@ -158,6 +158,7 @@ class FullGeneratedConfig: Hook_Misc_SkipShipGainShow = None Hook_Misc_ChapterForceEnableAutoFight = None Hook_Misc_ChapterSkipPrecombat = None + Hook_Misc_ChapterAutoNextBattle = 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 73f988352..4ce8fd454 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -3136,6 +3136,10 @@ "ChapterSkipPrecombat": { "name": "Misc.ChapterSkipPrecombat.name", "help": "Misc.ChapterSkipPrecombat.help" + }, + "ChapterAutoNextBattle": { + "name": "Misc.ChapterAutoNextBattle.name", + "help": "Misc.ChapterAutoNextBattle.help" } }, "PowerLimit": { diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index 9f55ee3d4..092e70d3f 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -3136,6 +3136,10 @@ "ChapterSkipPrecombat": { "name": "Misc.ChapterSkipPrecombat.name", "help": "Misc.ChapterSkipPrecombat.help" + }, + "ChapterAutoNextBattle": { + "name": "Misc.ChapterAutoNextBattle.name", + "help": "Misc.ChapterAutoNextBattle.help" } }, "PowerLimit": { diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index b153598ad..c10129fac 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -3136,6 +3136,10 @@ "ChapterSkipPrecombat": { "name": "章节图跳过战前准备", "help": "" + }, + "ChapterAutoNextBattle": { + "name": "章节图自动下一战", + "help": "" } }, "PowerLimit": { diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index d15ae34dc..63d2f7cc9 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -3136,6 +3136,10 @@ "ChapterSkipPrecombat": { "name": "Misc.ChapterSkipPrecombat.name", "help": "Misc.ChapterSkipPrecombat.help" + }, + "ChapterAutoNextBattle": { + "name": "Misc.ChapterAutoNextBattle.name", + "help": "Misc.ChapterAutoNextBattle.help" } }, "PowerLimit": { diff --git a/module/luahook/api.py b/module/luahook/api.py index 22d69208e..70bba6071 100644 --- a/module/luahook/api.py +++ b/module/luahook/api.py @@ -343,3 +343,9 @@ class CrackApi: def disable_chapter_skip_precombat(self): self.post("disable_chapter_skip_precombat") + + def enable_chapter_auto_next_battle(self): + self.post("enable_chapter_auto_next_battle") + + def disable_chapter_auto_next_battle(self): + self.post("disable_chapter_auto_next_battle") diff --git a/module/luahook/crack.py b/module/luahook/crack.py index bfd4bab8d..2179cc0b0 100644 --- a/module/luahook/crack.py +++ b/module/luahook/crack.py @@ -41,6 +41,7 @@ ALL_ENABLE_OPS = [ CrackOp.EnableSkipShipGainShow, CrackOp.EnableChapterForceEnableAutoFight, CrackOp.EnableChapterSkipPrecombat, + CrackOp.EnableChapterAutoNextBattle, ] REMOTE_PORT = 23897 @@ -270,6 +271,11 @@ def do_crack_op(config: AzurLaneConfig, device: Device, ops: Union[Type[CrackOp. api.enable_chapter_skip_precombat() elif op == CrackOp.DisableChapterSkipPrecombat: api.disable_chapter_skip_precombat() + elif op == CrackOp.EnableChapterAutoNextBattle: + if full_config.Hook_Misc_ChapterForceEnableAutoFight: + api.enable_chapter_auto_next_battle() + elif op == CrackOp.DisableChapterAutoNextBattle: + api.disable_chapter_auto_next_battle() else: logger.error(f"Unsupported op: {op}") @@ -324,6 +330,7 @@ CHAPTER_CRACK_OPS = [ CrackOp.EnableSkipShipGainShow, CrackOp.EnableChapterForceEnableAutoFight, CrackOp.EnableChapterSkipPrecombat, + CrackOp.EnableChapterAutoNextBattle, ] diff --git a/module/luahook/op.py b/module/luahook/op.py index d644fcd3f..92605e58d 100644 --- a/module/luahook/op.py +++ b/module/luahook/op.py @@ -154,3 +154,9 @@ class CrackOp: class DisableChapterSkipPrecombat(Op): ... + + class EnableChapterAutoNextBattle(Op): + ... + + class DisableChapterAutoNextBattle(Op): + ...