From b6d35fd5b358b3a63e6c491e9adbc68873ded7a6 Mon Sep 17 00:00:00 2001 From: chinosk <2248589280@qq.com> Date: Sun, 5 May 2024 10:38:41 +0800 Subject: [PATCH] Add: Unlock Idol Event and Support Event #20 --- README.md | 31 +++++++++++----------- readme_EN.md | 1 + resources/scsp-config.json | 3 ++- src/hook.cpp | 53 ++++++++++++++++++++++++++++++++++++++ src/main.cpp | 4 +++ src/scgui/scGUILoop.cpp | 4 +++ src/stdinclude.hpp | 1 + 7 files changed, 81 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index d291a55..2e91fd0 100644 --- a/README.md +++ b/README.md @@ -40,21 +40,22 @@ - 配置项位于 `scsp-config.json` 文件中 -| 配置项 | 类型 | 默认值 | 说明 | -| --------------------- | ---------------------------------------- | -------------------------------------- | ---------------------------------------------------- | -| enableConsole | Bool | `true` | 是否开启控制台 | -| enableVSync | Bool | `false` | 是否启用垂直同步 | -| maxFps | Int | `60` | 最大帧数
当启用 `enableVSync` 时,此项配置失效 | -| 3DResolutionScale | Float | `1.0` | 3D 渲染分辨率倍率 | -| localifyBasePath | String | `scsp_localify` | 本地化文件目录 | -| hotKey | String (Char) | `u` | 按下 `Ctrl` + 此项配置的热键,**打开插件 GUI** | -| dumpUntransLyrics | Bool | `false` | dump 未翻译的歌词 | -| dumpUntransLocal2 | Bool | `false` | dump 未翻译的文本 | -| autoDumpAllJson | Bool | `false` | dump 所有游戏加载的 JSON | -| extraAssetBundlePaths | String[] | `["scsp_localify/scsp-bundle"]` | 自定义数据包路径 | -| customFontPath | String | `assets/font/sbtphumminge-regular.ttf` | 自定义数据包中字体路径
用于替换游戏内置字体 | -| blockOutOfFocus | Bool | `true` | 拦截窗口失焦事件
切换到其它窗口后不会触发游戏暂停 | -| baseFreeCamera | [BaseFreeCamera](#BaseFreeCamera) Object | [BaseFreeCamera](#BaseFreeCamera) | 自由视角配置 | +| 配置项 | 类型 | 默认值 | 说明 | +| -------------------------- | ---------------------------------------- | -------------------------------------- | ---------------------------------------------------- | +| enableConsole | Bool | `true` | 是否开启控制台 | +| enableVSync | Bool | `false` | 是否启用垂直同步 | +| maxFps | Int | `60` | 最大帧数
当启用 `enableVSync` 时,此项配置失效 | +| 3DResolutionScale | Float | `1.0` | 3D 渲染分辨率倍率 | +| localifyBasePath | String | `scsp_localify` | 本地化文件目录 | +| hotKey | String (Char) | `u` | 按下 `Ctrl` + 此项配置的热键,**打开插件 GUI** | +| dumpUntransLyrics | Bool | `false` | dump 未翻译的歌词 | +| dumpUntransLocal2 | Bool | `false` | dump 未翻译的文本 | +| autoDumpAllJson | Bool | `false` | dump 所有游戏加载的 JSON | +| extraAssetBundlePaths | String[] | `["scsp_localify/scsp-bundle"]` | 自定义数据包路径 | +| customFontPath | String | `assets/font/sbtphumminge-regular.ttf` | 自定义数据包中字体路径
用于替换游戏内置字体 | +| blockOutOfFocus | Bool | `true` | 拦截窗口失焦事件
切换到其它窗口后不会触发游戏暂停 | +| baseFreeCamera | [BaseFreeCamera](#BaseFreeCamera) Object | [BaseFreeCamera](#BaseFreeCamera) | 自由视角配置 | +| unlockPIdolAndSCharaEvents | Bool | `false` | 解锁 `角色` - `一览` 中的P卡和S卡事件 | diff --git a/readme_EN.md b/readme_EN.md index d4812f8..cbaeb13 100644 --- a/readme_EN.md +++ b/readme_EN.md @@ -54,6 +54,7 @@ iM@S SCSP localify plugin. | customFontPath | String | `assets/font/sbtphumminge-regular.ttf` | Custom font path in asset bundles
Used for replacing built-in fonts in the game | | blockOutOfFocus | Bool | `true` | Intercept window out-of-focus events
Game won't pause when switching to other windows | | baseFreeCamera | [BaseFreeCamera](#BaseFreeCamera) Object | [BaseFreeCamera](#BaseFreeCamera) | Free camera configuration | +| unlockPIdolAndSCharaEvents | Bool | `false` | Unlock Idol Event (アイドルイベント) and Support Event (サポートイベント) in `Characters` - `Overview` | diff --git a/resources/scsp-config.json b/resources/scsp-config.json index 93f9711..9b2a693 100644 --- a/resources/scsp-config.json +++ b/resources/scsp-config.json @@ -18,5 +18,6 @@ "enable": false, "moveStep": 50, "mouseSpeed": 35 - } + }, + "unlockPIdolAndSCharaEvents": false } \ No newline at end of file diff --git a/src/hook.cpp b/src/hook.cpp index c7be9fd..8a774b5 100644 --- a/src/hook.cpp +++ b/src/hook.cpp @@ -593,6 +593,48 @@ namespace } + // NOT HOOK + void* PIdolDetailPopupViewModel_Create_orig; + void* PIdolDetailPopupViewModel_Create_hook(void* produceIdol, void* costumeSetInfoList, void* idolBase, void* idolParameter, bool isChangeableIdolSkill, bool isChangeableFavorite, void* produceAdvStatusList, bool isPlayableAdv, bool inLive, bool upgradingButtonActive) { + auto ret = reinterpret_cast(PIdolDetailPopupViewModel_Create_orig)( + produceIdol, costumeSetInfoList, idolBase, idolParameter, isChangeableIdolSkill, isChangeableFavorite, produceAdvStatusList, isPlayableAdv, inLive, upgradingButtonActive + ); + return ret; + /* // 功能被 EventModel_ctor_hook 替代 + static auto get_EventList = reinterpret_cast( + il2cpp_symbols::get_method_pointer("PRISM.Adapters.dll", "PRISM.Adapters", + "PIdolDetailPopupViewModel", "get_EventList", 0) + ); + static auto EventModel_klass = il2cpp_symbols::get_class("PRISM.Adapters.dll", "PRISM.Adapters", "EventModel"); + static auto Read_field = il2cpp_class_get_field_from_name(EventModel_klass, "k__BackingField"); + static auto IsAdvPlayable_field = il2cpp_class_get_field_from_name(EventModel_klass, "k__BackingField"); + + printf("PIdolDetailPopupViewModel_Create\n"); + + auto events = get_EventList(ret); + + il2cpp_symbols::iterate_IEnumerable(events, [](void* event) { + const auto read = il2cpp_symbols::read_field(event, Read_field); + const auto isAdvPlayable = il2cpp_symbols::read_field(event, IsAdvPlayable_field); + printf("read: %d, isAdvPlayable: %d\n", read, isAdvPlayable); + + il2cpp_symbols::write_field(event, Read_field, true); + }); + + return ret;*/ + } + + void* EventModel_ctor_orig; + void EventModel_ctor_hook(void* _this, void* scenarioID, Il2CppString* title, Il2CppString* summary, bool read, bool isAdvPlayable) { + if (g_unlock_PIdol_and_SChara_events) { + if (!read) { + wprintf(L"Force Unlock Event: %ls\n", title->start_char); + read = true; + } + } + return reinterpret_cast(EventModel_ctor_orig)(_this, scenarioID, title, summary, read, isAdvPlayable); + } + void* LocalizationManager_GetTextOrNull_orig; Il2CppString* LocalizationManager_GetTextOrNull_hook(void* _this, Il2CppString* category, int id) { if (g_max_fps != -1) set_fps_hook(g_max_fps); @@ -2025,6 +2067,15 @@ namespace "TextLog", "AddLog", 4 ); + auto PIdolDetailPopupViewModel_Create_addr = il2cpp_symbols::get_method_pointer( + "PRISM.Adapters.dll", "PRISM.Adapters", + "PIdolDetailPopupViewModel", "Create", 10 + ); + auto EventModel_ctor_addr = il2cpp_symbols::get_method_pointer( + "PRISM.Adapters.dll", "PRISM.Adapters", + "EventModel", ".ctor", 5 + ); + auto LocalizationManager_GetTextOrNull_addr = il2cpp_symbols::get_method_pointer( "ENTERPRISE.Localization.dll", "ENTERPRISE.Localization", "LocalizationManager", "GetTextOrNull", 2 @@ -2215,6 +2266,8 @@ namespace ); #pragma endregion + // ADD_HOOK(PIdolDetailPopupViewModel_Create, "PIdolDetailPopupViewModel_Create at %p"); + ADD_HOOK(EventModel_ctor, "EventModel_ctor at %p"); ADD_HOOK(LocalizationManager_GetTextOrNull, "LocalizationManager_GetTextOrNull at %p"); ADD_HOOK(get_NeedsLocalization, "get_NeedsLocalization at %p"); ADD_HOOK(GetResolutionSize, "GetResolutionSize at %p"); diff --git a/src/main.cpp b/src/main.cpp index c9279f7..e9358cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,6 +43,7 @@ bool g_allow_same_idol = false; bool g_unlock_all_dress = false; bool g_unlock_all_headwear = false; bool g_enable_chara_param_edit = false; +bool g_unlock_PIdol_and_SChara_events = false; std::filesystem::path g_localify_base("scsp_localify"); constexpr const char ConfigJson[] = "scsp-config.json"; @@ -180,6 +181,9 @@ namespace if (document.HasMember("unlockAllHeadwear")) { g_unlock_all_headwear = document["unlockAllHeadwear"].GetBool() && g_unlock_all_dress; } + if (document.HasMember("unlockPIdolAndSCharaEvents")) { + g_unlock_PIdol_and_SChara_events = document["unlockPIdolAndSCharaEvents"].GetBool(); + } } diff --git a/src/scgui/scGUILoop.cpp b/src/scgui/scGUILoop.cpp index 8ffa1d7..77107df 100644 --- a/src/scgui/scGUILoop.cpp +++ b/src/scgui/scGUILoop.cpp @@ -172,6 +172,10 @@ namespace SCGUILoop { ImGui::SameLine(); HELP_TOOLTIP("(?)", "启用角色身体参数编辑器") + ImGui::Checkbox("Unlock PIdol And SChara Events", &g_unlock_PIdol_and_SChara_events); + ImGui::SameLine(); + HELP_TOOLTIP("(?)", "解锁 角色 - 一览 中的P卡和S卡事件\nUnlock Idol Event (アイドルイベント) and Support Event (サポートイベント)") + if (ImGui::CollapsingHeader("Resolution Settings", ImGuiTreeNodeFlags_DefaultOpen)) { ImGui::Text("Window Resolution Settings"); diff --git a/src/stdinclude.hpp b/src/stdinclude.hpp index 3ed7566..9ebbdfb 100644 --- a/src/stdinclude.hpp +++ b/src/stdinclude.hpp @@ -175,3 +175,4 @@ extern bool g_unlock_all_headwear; extern bool g_enable_chara_param_edit; extern float g_font_size_offset; extern float g_3d_resolution_scale; +extern bool g_unlock_PIdol_and_SChara_events;