diff --git a/blcrack/cracker/cracker.cpp b/blcrack/cracker/cracker.cpp index 88f01e840..30be63e8b 100644 --- a/blcrack/cracker/cracker.cpp +++ b/blcrack/cracker/cracker.cpp @@ -322,6 +322,15 @@ void Cracker::disable_all() { disable_chapter_auto_ambush(); disable_chapter_auto_clear(); disable_skip_story(); + disable_infinite_battle(); +} + +void Cracker::enable_infinite_battle() { + ENABLE(INFINITE_BATTLE); +} + +void Cracker::disable_infinite_battle() { + DISABLE(INFINITE_BATTLE); } void Cracker::enable_hooked_lua_function_trace() { @@ -749,11 +758,30 @@ void Cracker::load_lua_resources() { m_original.LevelStageView_TryAutoFight = m_state["LevelStageView"]["TryAutoFight"]; m_original.Story_Ctor = m_state["Story"]["Ctor"]; m_original.Fleet_EnergyCheck = m_state["Fleet"]["EnergyCheck"]; + m_original.ContinuousOperationRuntimeData_ConsumeBattleTime = m_state["ContinuousOperationRuntimeData"]["ConsumeBattleTime"]; + m_original.ActivityProxy_UseContinuousTime = m_state["ActivityProxy"]["UseContinuousTime"]; } void Cracker::hook_all_lua_functions() { SPDLOG_INFO("Hook lua functions"); + // infinite_battle + m_state["ContinuousOperationRuntimeData"]["ConsumeBattleTime"] = [this](sol::this_state L, Lua::VariadicArgs args) { + CALLED(ContinuousOperationRuntimeData.ConsumeBattleTime); + if (IS_ENABLED(INFINITE_BATTLE)) { + return; + } + m_original.ContinuousOperationRuntimeData_ConsumeBattleTime(L, args); + }; + + m_state["ActivityProxy"]["UseContinuousTime"] = [this](sol::this_state L, Lua::VariadicArgs args) { + CALLED(ActivityProxy.UseContinuousTime); + if (IS_ENABLED(INFINITE_BATTLE)) { + return; + } + m_original.ActivityProxy_UseContinuousTime(L, args); + }; + // skip_story m_state["Story"]["Ctor"] = [this](sol::this_state L, Lua::VariadicArgs args) { CALLED(Story.Ctor); @@ -1534,6 +1562,7 @@ Cracker::Config Cracker::get_config() { SET_CONFIG_FLAG(CHAPTER_AUTO_AMBUSH), SET_CONFIG_FLAG(CHAPTER_AUTO_CLEAR), SET_CONFIG_FLAG(SKIP_STORY), + SET_CONFIG_FLAG(INFINITE_BATTLE), }, .globle_ship_properties = m_globle_ship_properties, .global_speedup_rate = static_cast(m_global_speedup_rate), @@ -1547,6 +1576,12 @@ Cracker::Config Cracker::get_config() { #define IS_CONFIG_ENABLED(n) config.flag.n void Cracker::apply_config(Config& config) { + if(IS_CONFIG_ENABLED(INFINITE_BATTLE)) { + enable_infinite_battle(); + } else { + disable_infinite_battle(); + } + if(IS_CONFIG_ENABLED(HOOKED_LUA_FUNCTION_TRACE)) { enable_hooked_lua_function_trace(); } else { diff --git a/blcrack/cracker/cracker.hpp b/blcrack/cracker/cracker.hpp index 77f0bed26..a85771a61 100644 --- a/blcrack/cracker/cracker.hpp +++ b/blcrack/cracker/cracker.hpp @@ -116,6 +116,7 @@ public: bool CHAPTER_AUTO_AMBUSH = false; bool CHAPTER_AUTO_CLEAR = false; bool SKIP_STORY = false; + bool INFINITE_BATTLE = false; } flag; ShipProperties globle_ship_properties; int global_speedup_rate = 1; @@ -151,6 +152,9 @@ public: void disable_all(); + void enable_infinite_battle(); + void disable_infinite_battle(); + void enable_hooked_lua_function_trace(); void disable_hooked_lua_function_trace(); @@ -324,6 +328,7 @@ private: std::atomic CHAPTER_AUTO_AMBUSH = false; std::atomic CHAPTER_AUTO_CLEAR = false; std::atomic SKIP_STORY = false; + std::atomic INFINITE_BATTLE = false; } m_flag; struct { @@ -373,6 +378,8 @@ private: Lua::Function LevelStageView_TryAutoFight; Lua::Function Story_Ctor; Lua::Function Fleet_EnergyCheck; + Lua::Function ContinuousOperationRuntimeData_ConsumeBattleTime; + Lua::Function ActivityProxy_UseContinuousTime; } m_original; struct { Lua::Function Clone; diff --git a/blcrack/cracker/server.cpp b/blcrack/cracker/server.cpp index a558c68cb..c96e7778a 100644 --- a/blcrack/cracker/server.cpp +++ b/blcrack/cracker/server.cpp @@ -1175,6 +1175,28 @@ CrackerServer::CrackerServer() { CRACK_OK(); }); + Post("/enable_infinite_battle", [](const httplib::Request& req, httplib::Response& res) { + try { + Cracker::Instance().enable_infinite_battle(); + } catch (std::exception& e) { + SPDLOG_ERROR("Enable infinite battle failed: {}", e.what()); + res.status = 500; + return; + } + CRACK_OK(); + }); + + Post("/disable_infinite_battle", [](const httplib::Request& req, httplib::Response& res) { + try { + Cracker::Instance().disable_infinite_battle(); + } catch (std::exception& e) { + SPDLOG_ERROR("Disable infinite 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 7c2632017..d7e2ead27 100644 --- a/blcrack/cracker/ui/ui.cpp +++ b/blcrack/cracker/ui/ui.cpp @@ -123,6 +123,7 @@ void CrackerUI::draw_menu() { ImGui::Checkbox("跳过舰船获取展示", &CONFIG_FLAG(SKIP_SHIP_GAIN_SHOW)); ImGui::Checkbox("章节图自动下一战", &CONFIG_FLAG(CHAPTER_AUTO_NEXT_BATTLE)); ImGui::Checkbox("章节图自动开荒", &CONFIG_FLAG(CHAPTER_AUTO_CLEAR)); + ImGui::Checkbox("无限连战", &CONFIG_FLAG(INFINITE_BATTLE)); ImGui::EndTable(); } diff --git a/blcrack/http/cracker.http b/blcrack/http/cracker.http index 149466650..3ebe11986 100644 --- a/blcrack/http/cracker.http +++ b/blcrack/http/cracker.http @@ -249,6 +249,12 @@ POST http://{{Host}}:{{Port}}/enable_skip_story ### POST http://{{Host}}:{{Port}}/disable_skip_story +### +POST http://{{Host}}:{{Port}}/enable_infinite_battle + +### +POST http://{{Host}}:{{Port}}/disable_infinite_battle + ### POST http://{{Host}}:{{Port}}/is_alive diff --git a/config/template.json b/config/template.json index 8bedf2efa..3008b3939 100644 --- a/config/template.json +++ b/config/template.json @@ -229,7 +229,8 @@ "ChapterAutoNextBattle": false, "ChapterAutoAmbush": false, "ChapterAutoClear": false, - "SkipStory": false + "SkipStory": false, + "InfiniteBattle": false }, "ShipProperty": { "Method": "disable", diff --git a/module/config/argument/args.json b/module/config/argument/args.json index 8e309d1aa..41f9c0941 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -913,6 +913,10 @@ "SkipStory": { "type": "checkbox", "value": false + }, + "InfiniteBattle": { + "type": "checkbox", + "value": false } }, "ShipProperty": { diff --git a/module/config/argument/argument.yaml b/module/config/argument/argument.yaml index 57a84af4b..03c591864 100644 --- a/module/config/argument/argument.yaml +++ b/module/config/argument/argument.yaml @@ -895,6 +895,7 @@ Misc: ChapterAutoAmbush: false ChapterAutoClear: false SkipStory: false + InfiniteBattle: false # ==================== Cheat ==================== PowerLimit: diff --git a/module/config/config_generated.py b/module/config/config_generated.py index 18d3141c1..b66dc00d3 100644 --- a/module/config/config_generated.py +++ b/module/config/config_generated.py @@ -550,6 +550,7 @@ class GeneratedConfig: Misc_ChapterAutoAmbush = False Misc_ChapterAutoClear = False Misc_SkipStory = False + Misc_InfiniteBattle = False # Group `PowerLimit` PowerLimit_Enable = True diff --git a/module/config/full_config_generated.py b/module/config/full_config_generated.py index 9b9f5fc8c..bff6228c6 100644 --- a/module/config/full_config_generated.py +++ b/module/config/full_config_generated.py @@ -163,6 +163,7 @@ class FullGeneratedConfig: Hook_Misc_ChapterAutoAmbush = None Hook_Misc_ChapterAutoClear = None Hook_Misc_SkipStory = None + Hook_Misc_InfiniteBattle = 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 c97378261..c55e4e356 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -3160,6 +3160,10 @@ "SkipStory": { "name": "Misc.SkipStory.name", "help": "Misc.SkipStory.help" + }, + "InfiniteBattle": { + "name": "Misc.InfiniteBattle.name", + "help": "Misc.InfiniteBattle.help" } }, "PowerLimit": { diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index 9b6ebb543..9fcaffbcc 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -3160,6 +3160,10 @@ "SkipStory": { "name": "Misc.SkipStory.name", "help": "Misc.SkipStory.help" + }, + "InfiniteBattle": { + "name": "Misc.InfiniteBattle.name", + "help": "Misc.InfiniteBattle.help" } }, "PowerLimit": { diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index 58794fbf5..5b49c1acd 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -3160,6 +3160,10 @@ "SkipStory": { "name": "跳过剧情", "help": "" + }, + "InfiniteBattle": { + "name": "无限连战", + "help": "" } }, "PowerLimit": { diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index 73aa057fe..bfdcbeeaf 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -3160,6 +3160,10 @@ "SkipStory": { "name": "Misc.SkipStory.name", "help": "Misc.SkipStory.help" + }, + "InfiniteBattle": { + "name": "Misc.InfiniteBattle.name", + "help": "Misc.InfiniteBattle.help" } }, "PowerLimit": { diff --git a/module/luahook/api.py b/module/luahook/api.py index 0c8ce965f..e129d1853 100644 --- a/module/luahook/api.py +++ b/module/luahook/api.py @@ -392,6 +392,12 @@ class CrackApi: def disable_skip_story(self): self.post("disable_skip_story") + def enable_infinite_battle(self): + self.post("enable_infinite_battle") + + def disable_infinite_battle(self): + self.post("disable_infinite_battle") + def init(self): self.post("init") diff --git a/module/luahook/crack.py b/module/luahook/crack.py index 1231c4055..7b1a6d836 100644 --- a/module/luahook/crack.py +++ b/module/luahook/crack.py @@ -45,6 +45,7 @@ ALL_ENABLE_OPS = [ CrackOp.EnableChapterAutoAmbush, CrackOp.EnableChapterAutoClear, CrackOp.EnableSkipStory, + CrackOp.EnableInfiniteBattle, ] REMOTE_PORT = 23897 @@ -330,6 +331,11 @@ def do_crack_op(config: AzurLaneConfig, device: Device, ops: Union[Type[CrackOp. api.enable_skip_story() elif op == CrackOp.DisableSkipStory: api.disable_skip_story() + elif op == CrackOp.EnableInfiniteBattle: + if full_config.Hook_Misc_InfiniteBattle: + api.enable_infinite_battle() + elif op == CrackOp.DisableInfiniteBattle: + api.disable_infinite_battle() else: logger.error(f"Unsupported op: {op}") @@ -388,6 +394,7 @@ CHAPTER_CRACK_OPS = [ CrackOp.EnableChapterAutoAmbush, CrackOp.EnableChapterAutoClear, CrackOp.EnableSkipStory, + CrackOp.EnableInfiniteBattle, ] diff --git a/module/luahook/op.py b/module/luahook/op.py index f22fe1c00..01f5bcf69 100644 --- a/module/luahook/op.py +++ b/module/luahook/op.py @@ -178,3 +178,9 @@ class CrackOp: class DisableSkipStory(Op): ... + + class EnableInfiniteBattle(Op): + ... + + class DisableInfiniteBattle(Op): + ...