From 361c48e2c9ebf0a753030cb728c21112a824c52f Mon Sep 17 00:00:00 2001 From: chinosk <2248589280@qq.com> Date: Tue, 24 Dec 2024 00:52:11 +0000 Subject: [PATCH] fix: incomplete hooks --- app/src/main/cpp/GakumasLocalify/Hook.cpp | 105 +++++++++++++++++- .../cpp/GakumasLocalify/config/Config.cpp | 2 + .../cpp/GakumasLocalify/config/Config.hpp | 1 + .../gakumas/localify/ConfigUpdateListener.kt | 6 + .../gakumas/localify/models/GakumasConfig.kt | 1 + .../ui/pages/subPages/AdvancedSettingsPage.kt | 4 + app/src/main/res/values-ja/strings.xml | 1 + app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 9 files changed, 116 insertions(+), 6 deletions(-) diff --git a/app/src/main/cpp/GakumasLocalify/Hook.cpp b/app/src/main/cpp/GakumasLocalify/Hook.cpp index 157eee2..0da1087 100644 --- a/app/src/main/cpp/GakumasLocalify/Hook.cpp +++ b/app/src/main/cpp/GakumasLocalify/Hook.cpp @@ -466,14 +466,71 @@ namespace GakumasLocal::HookMain { // return UnityResolve::UnityType::String::New("[I18]" + ret->ToString()); } - DEFINE_HOOK(void, PictureBookLiveThumbnailView_SetData, (void* self, void* liveData, bool isReleased, bool isUnlocked, bool isNew, bool hasLiveSkin, void* ct, void* mtd)) { - // Log::DebugFmt("PictureBookLiveThumbnailView_SetData: isReleased: %d, isUnlocked: %d, isNew: %d, hasLiveSkin: %d", - // isReleased, isUnlocked, isNew, hasLiveSkin); + /* + DEFINE_HOOK(void*, UserDataManagerBase_get__userIdolCardSkinList, (void* self, void* mtd)) { // Live默认选择 + auto ret = UserDataManagerBase_get__userIdolCardSkinList_Orig(self, mtd); + Log::DebugFmt("UserDataManagerBase_get__userIdolCardSkinList: %p", ret); + return ret; + } + DEFINE_HOOK(void*, UserDataManagerBase_get__userCostumeList, (void* self, void* mtd)) { // 服装选择界面 + auto ret = UserDataManagerBase_get__userCostumeList_Orig(self, mtd); + Log::DebugFmt("UserDataManagerBase_get__userCostumeList: %p", ret); + return ret; + } + DEFINE_HOOK(void*, UserDataManagerBase_get__userCostumeHeadList, (void* self, void* mtd)) { // 服装选择界面 + auto ret = UserDataManagerBase_get__userCostumeHeadList_Orig(self, mtd); + Log::DebugFmt("UserDataManagerBase_get__userCostumeHeadList: %p", ret); + return ret; + }*/ + + DEFINE_HOOK(void*, UserCostumeCollection_FindBy, (void* self, void* predicate, void* mtd)) { + auto ret = UserCostumeCollection_FindBy_Orig(self, predicate, mtd); + if (!Config::unlockAllLiveCostume) return ret; + + auto this_klass = Il2cppUtils::get_class_from_instance(self); + // auto predicate_klass = Il2cppUtils::get_class_from_instance(predicate); // System::Predicate`1 + // Log::DebugFmt("UserCostumeCollection_FindBy this: %s::%s, predicate: %s::%s", this_klass->namespaze, this_klass->name, + // predicate_klass->namespaze, predicate_klass->name); + + static auto UserCostumeCollection_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.Common.User", + "UserCostumeCollection"); + static auto UserCostumeCollection_GetAllList_mtd = Il2cppUtils::il2cpp_class_get_method_from_name( + UserCostumeCollection_klass->address, "GetAllList", 1); + static auto UserCostumeCollection_GetAllList = reinterpret_cast(UserCostumeCollection_GetAllList_mtd->methodPointer); + + std::string thisKlassName(this_klass->name); + // Campus.Common.User::UserCostumeHeadCollection || Campus.Common.User::UserCostumeCollection + // 两个 class 的 GetAllList 均使用的父类 Qua.UserDataManagement.UserDataCollectionBase`2 的方法,地址一致 + if ((thisKlassName == "UserCostumeHeadCollection") || (thisKlassName == "UserCostumeCollection")) { + // auto ret_klass = Il2cppUtils::get_class_from_instance(ret); // WhereEnumerableIterator + return UserCostumeCollection_GetAllList(self, nullptr); + } + + return ret; + } + + DEFINE_HOOK(bool, UserIdolCardSkinCollection_Exists, (void* self, Il2cppString* id, void* mtd)) { // Live默认选择 + auto ret = UserIdolCardSkinCollection_Exists_Orig(self, id, mtd); + // Log::DebugFmt("UserIdolCardSkinCollection_Exists: %s, ret: %d", id->ToString().c_str(), ret); + if (!Config::unlockAllLive) return ret; + + if (id) { + std::string idStr = id->ToString(); + if (idStr.starts_with("music") || idStr.starts_with("i_card-skin")) { // eg. music-all-kllj-006, i_card-skin-hski-3-002 + return true; + } + } + return ret; + } + + DEFINE_HOOK(void, PictureBookLiveThumbnailView_SetDataAsync, (void* self, void* liveData, bool isReleased, bool isUnlocked, bool isNew, bool hasLiveSkin, void* ct, void* mtd)) { + // Log::DebugFmt("PictureBookLiveThumbnailView_SetDataAsync: isReleased: %d, isUnlocked: %d, isNew: %d, hasLiveSkin: %d", isReleased, isUnlocked, isNew, hasLiveSkin); if (Config::dbgMode && Config::unlockAllLive) { isUnlocked = true; isReleased = true; + hasLiveSkin = true; } - PictureBookLiveThumbnailView_SetData_Orig(self, liveData, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd); + PictureBookLiveThumbnailView_SetDataAsync_Orig(self, liveData, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd); } std::vector GetIdolMusicIdAll(const std::string& charaNameId = "") { @@ -1011,9 +1068,45 @@ namespace GakumasLocal::HookMain { Il2cppUtils::GetMethodPointer("Octo.dll", "Octo", "OnDownloadProgress", "Invoke")); - ADD_HOOK(PictureBookLiveThumbnailView_SetData, + /* + auto UserDataManager_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.Common.User", + "UserDataManager"); + if (UserDataManager_klass) { + auto UserDataManagerBase_klass = UnityResolve::Invoke("il2cpp_class_get_parent", UserDataManager_klass->address); + if (UserDataManagerBase_klass) { + auto get_userIdolCardSkinList_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(UserDataManagerBase_klass, "get__userIdolCardSkinList", 0); + if (get_userIdolCardSkinList_mtd) { + ADD_HOOK(UserDataManagerBase_get__userIdolCardSkinList, get_userIdolCardSkinList_mtd->methodPointer); + } + auto get_userCostumeList_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(UserDataManagerBase_klass, "get__userCostumeList", 0); + if (get_userCostumeList_mtd) { + ADD_HOOK(UserDataManagerBase_get__userCostumeList, get_userCostumeList_mtd->methodPointer); + } + auto get_userCostumeHeadList_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(UserDataManagerBase_klass, "get__userCostumeHeadList", 0); + if (get_userCostumeHeadList_mtd) { + ADD_HOOK(UserDataManagerBase_get__userCostumeHeadList, get_userCostumeHeadList_mtd->methodPointer); + } + } + }*/ + + auto UserIdolCardSkinCollection_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.Common.User", + "UserIdolCardSkinCollection"); + auto UserIdolCardSkinCollection_Exists_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(UserIdolCardSkinCollection_klass->address, "Exists", 1); + if (UserIdolCardSkinCollection_Exists_mtd) { + ADD_HOOK(UserIdolCardSkinCollection_Exists, UserIdolCardSkinCollection_Exists_mtd->methodPointer); + } + + auto UserCostumeCollection_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.Common.User", + "UserCostumeCollection"); + auto UserCostumeCollection_FindBy_mtd = Il2cppUtils::il2cpp_class_get_method_from_name( + UserCostumeCollection_klass->address, "FindBy", 1); + if (UserCostumeCollection_FindBy_mtd) { + ADD_HOOK(UserCostumeCollection_FindBy, UserCostumeCollection_FindBy_mtd->methodPointer); + } + + ADD_HOOK(PictureBookLiveThumbnailView_SetDataAsync, Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame.PictureBook", - "PictureBookLiveThumbnailView", "SetDataAsync", {"*", "*", "*", "*"})); + "PictureBookLiveThumbnailView", "SetDataAsync", {"*", "*", "*", "*", "*"})); ADD_HOOK(PictureBookWindowPresenter_GetLiveMusics, Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame", "PictureBookWindowPresenter", "GetLiveMusics")); diff --git a/app/src/main/cpp/GakumasLocalify/config/Config.cpp b/app/src/main/cpp/GakumasLocalify/config/Config.cpp index 83e28a4..f262581 100644 --- a/app/src/main/cpp/GakumasLocalify/config/Config.cpp +++ b/app/src/main/cpp/GakumasLocalify/config/Config.cpp @@ -16,6 +16,7 @@ namespace GakumasLocal::Config { bool enableFreeCamera = false; int targetFrameRate = 0; bool unlockAllLive = false; + bool unlockAllLiveCostume = false; bool enableLiveCustomeDress = false; std::string liveCustomeHeadId = ""; @@ -67,6 +68,7 @@ namespace GakumasLocal::Config { GetConfigItem(targetFrameRate); GetConfigItem(enableFreeCamera); GetConfigItem(unlockAllLive); + GetConfigItem(unlockAllLiveCostume); GetConfigItem(enableLiveCustomeDress); GetConfigItem(liveCustomeHeadId); GetConfigItem(liveCustomeCostumeId); diff --git a/app/src/main/cpp/GakumasLocalify/config/Config.hpp b/app/src/main/cpp/GakumasLocalify/config/Config.hpp index 3813a4a..5020e16 100644 --- a/app/src/main/cpp/GakumasLocalify/config/Config.hpp +++ b/app/src/main/cpp/GakumasLocalify/config/Config.hpp @@ -14,6 +14,7 @@ namespace GakumasLocal::Config { extern bool enableFreeCamera; extern int targetFrameRate; extern bool unlockAllLive; + extern bool unlockAllLiveCostume; extern bool enableLiveCustomeDress; extern std::string liveCustomeHeadId; diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt index 3fa7fd9..23c2b87 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/ConfigUpdateListener.kt @@ -24,6 +24,7 @@ interface ConfigListener { fun onEnableFreeCameraChanged(value: Boolean) fun onTargetFpsChanged(s: CharSequence, start: Int, before: Int, count: Int) fun onUnlockAllLiveChanged(value: Boolean) + fun onUnlockAllLiveCostumeChanged(value: Boolean) fun onLiveCustomeDressChanged(value: Boolean) fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int) fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int) @@ -152,6 +153,11 @@ interface ConfigUpdateListener: ConfigListener, IHasConfigItems { saveConfig() } + override fun onUnlockAllLiveCostumeChanged(value: Boolean) { + config.unlockAllLiveCostume = value + saveConfig() + } + override fun onTargetFpsChanged(s: CharSequence, start: Int, before: Int, count: Int) { try { val valueStr = s.toString() diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt index fca7b64..e259fd8 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/models/GakumasConfig.kt @@ -15,6 +15,7 @@ data class GakumasConfig ( var enableFreeCamera: Boolean = false, var targetFrameRate: Int = 0, var unlockAllLive: Boolean = false, + var unlockAllLiveCostume: Boolean = false, var enableLiveCustomeDress: Boolean = false, var liveCustomeHeadId: String = "", var liveCustomeCostumeId: String = "", diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/ui/pages/subPages/AdvancedSettingsPage.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/ui/pages/subPages/AdvancedSettingsPage.kt index 88dbd58..8a41691 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/ui/pages/subPages/AdvancedSettingsPage.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/ui/pages/subPages/AdvancedSettingsPage.kt @@ -357,6 +357,10 @@ fun AdvanceSettingsPage(modifier: Modifier = Modifier, checked = config.value.unlockAllLive) { v -> context?.onUnlockAllLiveChanged(v) } + GakuSwitch(modifier, stringResource(R.string.unlockAllLiveCostume), + checked = config.value.unlockAllLiveCostume) { + v -> context?.onUnlockAllLiveCostumeChanged(v) + } HorizontalDivider( thickness = 1.dp, color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.12f) diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index b95925c..2ca9d6a 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -118,6 +118,7 @@ 翻訳のリポジトリ 翻訳リソースをアップデート すべてのライブを開放 + すべてのライブ衣装を開放 カスタムグラフィック設定を使用する リモート ZIP リソースを使用する Arm コレクションを使用する diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b856d71..029927d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -8,6 +8,7 @@ 以上述配置启动游戏/重载配置 最大 FPS (0 为保持游戏原设置) 解锁所有 Live + 解锁所有 Live 服装 Live 使用自定义角色 Live 自定义头部 ID (例: costume_head_hski-cstm-0002) Live 自定义服装 ID (例: hski-cstm-0002) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ed35cef..76ace6f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,6 +8,7 @@ Start Game / Hot Reload Config Max FPS (0 is Use Original Settings) Unlock All Live + Unlock All Live Costume Live Custom Character Live Custom Head ID (eg. costume_head_hski-cstm-0002) Live Custom Dress ID (eg. hski-cstm-0002)