From 7305ad5cd70984a271eeb90e6d045ef1c4c43eb1 Mon Sep 17 00:00:00 2001 From: chinosk <2248589280@qq.com> Date: Sat, 21 Mar 2026 15:51:41 +0800 Subject: [PATCH] More stable add unlock --- GakumasLocalify/GakumasLocalify/Hook.cpp | 269 +++++++++++++++++- .../GakumasLocalify/Il2cppUtils.hpp | 45 ++- GakumasLocalify/il2cpp_dump/Il2cppJson.hpp | 8 +- GakumasLocalify/il2cpp_dump/il2cppTypes.hpp | 71 +++++ 4 files changed, 374 insertions(+), 19 deletions(-) diff --git a/GakumasLocalify/GakumasLocalify/Hook.cpp b/GakumasLocalify/GakumasLocalify/Hook.cpp index f917290..c60401f 100644 --- a/GakumasLocalify/GakumasLocalify/Hook.cpp +++ b/GakumasLocalify/GakumasLocalify/Hook.cpp @@ -420,8 +420,8 @@ namespace GakumasLocal::HookMain { // 用于本地化 MasterDB - DEFINE_HOOK(void, MessageExtensions_MergeFrom, (void* message, void* span, void* mtd)) { - MessageExtensions_MergeFrom_Orig(message, span, mtd); + DEFINE_HOOK(void, MessageExtensions_MergeFrom, (void* message, void* span, bool discardUnknownFields, void* registry, void* mtd)) { + MessageExtensions_MergeFrom_Orig(message, span, discardUnknownFields, registry, mtd); if (message) { auto ret_klass = Il2cppUtils::get_class_from_instance(message); if (ret_klass) { @@ -472,6 +472,250 @@ namespace GakumasLocal::HookMain { // return Il2cppString::New("[I18]" + ret->ToString()); } +#pragma region UnlockLive + enum class GetIdolIdType { + MusicId, + CostumeId, + CostumeHeadId + }; + + std::vector GetIdolMusicIdAll(const std::string& charaNameId = "", GetIdolIdType getType = GetIdolIdType::MusicId) { + // 传入例: fktn + // System.Collections.Generic.List`1> + static auto get_IdolCardSkinMaster = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Master", "MasterManager", "get_IdolCardSkinMaster"); + static auto Master_GetAllWithSortByKey = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Master", "IdolCardSkinMaster", "GetAllWithSortByKey"); + static auto IdolCardSkin_get_Id = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_Id"); + static auto IdolCardSkin_get_IdolCardId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_IdolCardId"); + static auto IdolCardSkin_GetMusic = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "GetMusic"); + static auto IdolCardSkin_get_MusicId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_MusicId"); + static auto IdolCardSkin_get_CostumeId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_CostumeId"); + static auto IdolCardSkin_get_CostumeHeadId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_CostumeHeadId"); + static auto GetLiveMusics = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.OutGame", + "PictureBookWindowPresenter", "GetLiveMusics"); + + auto idolCardSkinMaster = get_IdolCardSkinMaster->Invoke(nullptr); // IdolCardSkinMaster + + std::vector ret{}; + + if (!idolCardSkinMaster) { + Log::ErrorFmt("get_IdolCardSkinMaster failed: %p", idolCardSkinMaster); + return ret; + } + // List + auto idolCardSkinList = Master_GetAllWithSortByKey->Invoke*>(idolCardSkinMaster, 0x0, nullptr); + + auto idolCardSkins = idolCardSkinList->ToArray()->ToVector(); + const auto checkStartCharaId = "i_card-" + charaNameId; + // Log::DebugFmt("checkStartCharaId: %s", checkStartCharaId.c_str()); + + // origMusics->Clear(); + Il2cppJson::Method* idGetFunc = nullptr; + switch (getType) { + case GetIdolIdType::MusicId: idGetFunc = IdolCardSkin_get_MusicId; + break; + case GetIdolIdType::CostumeId: idGetFunc = IdolCardSkin_get_CostumeId; + break; + case GetIdolIdType::CostumeHeadId: idGetFunc = IdolCardSkin_get_CostumeHeadId; + break; + default: + idGetFunc = IdolCardSkin_get_MusicId; + } + + for (auto i : idolCardSkins) { + if (!i) continue; + // auto charaId = IdolCardSkin_get_Id->Invoke(i); + auto targetId = idGetFunc->Invoke(i); + auto cardId = IdolCardSkin_get_IdolCardId->Invoke(i)->ToString(); + auto music = IdolCardSkin_GetMusic->Invoke(i); + + if (charaNameId.empty() || cardId.starts_with(checkStartCharaId)) { + std::string musicIdStr = targetId->ToString(); + // Log::DebugFmt("Add cardId: %s, musicId: %s", cardId.c_str(), musicIdStr.c_str()); + if (std::find(ret.begin(), ret.end(), musicIdStr) == ret.end()) { + ret.emplace_back(musicIdStr); + } + } + } + return ret; + } + + void* AddIdsToUserDataCollectionFromMaster(void* origList, std::vector& allIds, + Il2cppJson::Method* get_CostumeId, Il2cppJson::Method* set_CostumeId, Il2cppJson::Method* Clone) { + std::unordered_set existIds{}; + Il2cppUtils::Tools::CSListEditor listEditor(origList); + if (listEditor.get_Count() <= 0) { + return origList; + } + + for (auto i : listEditor) { + auto costumeId = get_CostumeId->Invoke(i); + if (!costumeId) continue; + existIds.emplace(costumeId->ToString()); + } + + for (auto& i : allIds) { + if (i.empty()) continue; + // Log::DebugFmt("Try add %s", i.c_str()); + if (existIds.contains(i)) continue; + + auto userCostume = Clone->Invoke(listEditor.get_Item(0)); + set_CostumeId->Invoke(userCostume, Il2cppString::New(i)); + listEditor.Add(userCostume); + } + return origList; + } + + 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::dbgMode && 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, Il2cppString* characterId, 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_SetDataAsync_Orig(self, liveData, characterId, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd); + } + + DEFINE_HOOK(void*, UserCostumeCollection_FindBy, (void* self, void* predicate, void* mtd)) { + // Log::DebugFmt("UserCostumeCollection_FindBy"); + auto ret = UserCostumeCollection_FindBy_Orig(self, predicate, mtd); + if (!(Config::dbgMode && 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_mtd_pointer = Il2cppUtils::GetMethodPointerIl2cpp("Assembly-CSharp.dll", "Campus.Common.User", + "UserCostumeCollection", "GetAllList", 1); + static auto UserCostumeCollection_GetAllList = reinterpret_cast(UserCostumeCollection_GetAllList_mtd_pointer); + + std::string thisKlassName(this_klass->name); + // Campus.Common.User::UserCostumeHeadCollection || Campus.Common.User::UserCostumeCollection + // 两个 class 的 GetAllList 均使用的父类 Qua.UserDataManagement.UserDataCollectionBase`2 的方法,地址一致 + if (thisKlassName == "UserCostumeHeadCollection") { + static auto UserCostume_Clone = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostumeHead", "Clone"); + static auto UserCostume_get_CostumeHeadId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostumeHead", "get_CostumeHeadId"); + static auto UserCostume_set_CostumeHeadId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostumeHead", "set_CostumeHeadId"); + + // auto ret_klass = Il2cppUtils::get_class_from_instance(ret); // WhereEnumerableIterator + auto origList = UserCostumeCollection_GetAllList(self, nullptr); + + auto allIds = GetIdolMusicIdAll("", GetIdolIdType::CostumeHeadId); + + // List + return AddIdsToUserDataCollectionFromMaster(origList, allIds, UserCostume_get_CostumeHeadId, UserCostume_set_CostumeHeadId, UserCostume_Clone); + } + else if (thisKlassName == "UserCostumeCollection") { + // static auto UserCostume_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostume"); + static auto UserCostume_Clone = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostume", "Clone"); + static auto UserCostume_get_CostumeId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostume", "get_CostumeId"); + static auto UserCostume_set_CostumeId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Transaction", "UserCostume", "set_CostumeId"); + + // auto ret_klass = Il2cppUtils::get_class_from_instance(ret); // WhereEnumerableIterator + auto origList = UserCostumeCollection_GetAllList(self, nullptr); + + auto allIds = GetIdolMusicIdAll("", GetIdolIdType::CostumeId); + + // List + return AddIdsToUserDataCollectionFromMaster(origList, allIds, UserCostume_get_CostumeId, UserCostume_set_CostumeId, UserCostume_Clone); + } + + return ret; + } + + void* PictureBookWindowPresenter_instance = nullptr; + std::string PictureBookWindowPresenter_charaId; + DEFINE_HOOK(void*, PictureBookWindowPresenter_GetLiveMusics, (void* self, Il2cppString* charaId, void* mtd)) { + // Log::DebugFmt("GetLiveMusics: %s", charaId->ToString().c_str()); + + if (Config::dbgMode && Config::unlockAllLive) { + PictureBookWindowPresenter_instance = self; + PictureBookWindowPresenter_charaId = charaId->ToString(); + + static auto PictureBookWindowPresenter_klass = Il2cppUtils::get_class_from_instance(self); + static auto existsMusicIds_field = Il2cppJson::InvokeIl2cpp( + "il2cpp_class_get_field_from_name", + PictureBookWindowPresenter_klass, + "_existsMusicIds" + ); + /* + static auto PictureBookWindowPresenter_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.OutGame", + "PictureBookWindowPresenter"); + static auto existsMusicIds_field = PictureBookWindowPresenter_klass->Get("_existsMusicIds");*/ + // auto existsMusicIds = Il2cppUtils::ClassGetFieldValue*>(self, existsMusicIds_field); + auto existsMusicIds = Il2cppUtils::ClassGetFieldValue(self, existsMusicIds_field); + + if (!existsMusicIds) { + static auto Dict_List_String_klass = Il2cppUtils::get_system_class_from_reflection_type_str( + "System.Collections.Generic.Dictionary`2[System.String, System.Collections.Generic.List`1[System.String]]"); + static auto List_String_klass = Il2cppUtils::get_system_class_from_reflection_type_str( + "System.Collections.Generic.List`1[System.String]"); + static auto List_String_ctor_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(List_String_klass, ".ctor", 0); + static auto List_String_ctor = reinterpret_cast(List_String_ctor_mtd->methodPointer); + + auto fullIds = GetIdolMusicIdAll(); + + static auto Dict_List_String_ctor_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(Dict_List_String_klass, ".ctor", 0); + static auto Dict_List_String_ctor = reinterpret_cast(Dict_List_String_ctor_mtd->methodPointer); + + auto newDict = Il2cppJson::InvokeIl2cpp("il2cpp_object_new", Dict_List_String_klass); + Dict_List_String_ctor(newDict, Dict_List_String_ctor_mtd); + Il2cppUtils::Tools::CSDictEditor newDictEditor(newDict, Dict_List_String_klass); + + // auto fullIds = GetIdolMusicIdAll(); + + for (auto& i : fullIds) { + // Log::DebugFmt("GetLiveMusics - Add: %s", i.c_str()); // eg. music-all-amao-001, music-char-hski-001 + //newListEditor.Add(Il2cppString::New(i)); + auto newList = Il2cppJson::InvokeIl2cpp("il2cpp_object_new", List_String_klass); + List_String_ctor(newList, List_String_ctor_mtd); + newDictEditor.Add(Il2cppString::New(i), newList); + } + Il2cppUtils::ClassSetFieldValue(self, existsMusicIds_field, newDict); + existsMusicIds = reinterpret_cast(newDict); + // Log::DebugFmt("GetLiveMusics - set end: %d", fullIds.size()); + } + + } + + return PictureBookWindowPresenter_GetLiveMusics_Orig(self, charaId, mtd); + } + + DEFINE_HOOK(void, PictureBookLiveSelectScreenModel_ctor, (void* self, void* transitionParam, Il2cppTypes::List* musics, void* mtd)) { + // Log::DebugFmt("PictureBookLiveSelectScreenModel_ctor"); + + if (Config::dbgMode && Config::unlockAllLive) { + static auto GetLiveMusics = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.OutGame", + "PictureBookWindowPresenter", "GetLiveMusics"); + if (PictureBookWindowPresenter_instance && !PictureBookWindowPresenter_charaId.empty()) { + auto fullMusics = GetLiveMusics->Invoke*>(PictureBookWindowPresenter_instance, + Il2cppString::New(PictureBookWindowPresenter_charaId)); + return PictureBookLiveSelectScreenModel_ctor_Orig(self, transitionParam, fullMusics, mtd); + } + } + + return PictureBookLiveSelectScreenModel_ctor_Orig(self, transitionParam, musics, mtd); + } +#pragma endregion void StartInjectFunctions() { const auto hookInstaller = Plugin::GetInstance().GetHookInstaller(); @@ -529,7 +773,8 @@ namespace GakumasLocal::HookMain { ADD_HOOK(MessageExtensions_MergeFrom, Il2cppUtils::GetMethodPointer("Google.Protobuf.dll", "Google.Protobuf", "MessageExtensions", "MergeFrom", // {"Google.Protobuf.IMessage", "System.ReadOnlySpan"} - {"IMessage", "ReadOnlySpan`1[Byte]"} + // {"IMessage", "ReadOnlySpan`1[Byte]"} + {"IMessage", "ReadOnlySpan`1[Byte]", "Boolean", "ExtensionRegistry"} )); @@ -554,6 +799,24 @@ namespace GakumasLocal::HookMain { Il2cppUtils::GetMethodPointer("campus-submodule.Runtime.dll", "Campus.Common", "ScreenOrientationControllerBase", "InternalSetOrientationAsync", 3)); +#pragma region UnlockLive + ADD_HOOK(UserIdolCardSkinCollection_Exists, Il2cppUtils::GetMethodPointerIl2cpp("Assembly-CSharp.dll", "Campus.Common.User", + "UserIdolCardSkinCollection", "Exists", 1)); + ADD_HOOK(PictureBookLiveThumbnailView_SetDataAsync, + Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame.PictureBook", + "PictureBookLiveThumbnailView", "SetDataAsync")); + + ADD_HOOK(UserCostumeCollection_FindBy, Il2cppUtils::GetMethodPointerIl2cpp("Assembly-CSharp.dll", "Campus.Common.User", + "UserCostumeCollection", "FindBy", 1)); + ADD_HOOK(PictureBookWindowPresenter_GetLiveMusics, + Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame", + "PictureBookWindowPresenter", "GetLiveMusics")); + ADD_HOOK(PictureBookLiveSelectScreenModel_ctor, + Il2cppUtils::GetMethodPointer("Assembly-CSharp.dll", "Campus.OutGame", + "PictureBookLiveSelectScreenModel", ".ctor")); + +#pragma endregion + } // 77 2640 5000 diff --git a/GakumasLocalify/GakumasLocalify/Il2cppUtils.hpp b/GakumasLocalify/GakumasLocalify/Il2cppUtils.hpp index 1fbfef2..86cb941 100644 --- a/GakumasLocalify/GakumasLocalify/Il2cppUtils.hpp +++ b/GakumasLocalify/GakumasLocalify/Il2cppUtils.hpp @@ -120,6 +120,10 @@ namespace Il2cppUtils { uint8_t is_marshaled_from_native : 1; }; + struct Il2CppAssembly { + void* image; + }; + static Il2CppClassHead* get_class_from_instance(const void* instance) { #ifdef GKMS_IOS return static_cast(*static_cast(__builtin_assume_aligned(instance, alignof(void*)))); @@ -156,31 +160,33 @@ namespace Il2cppUtils { } inline Il2CppClassHead* GetIl2cppClassFromName(const char* assemblyName, const char* nameSpaceName, const char* className) { - Log::Info("GetMethodIl2cpp 0"); + // Log::Info("GetMethodIl2cpp 0"); static auto domain = Il2cppJson::InvokeIl2cpp("il2cpp_domain_get"); if (!domain) { Log::ErrorFmt("GetMethodIl2cpp error: failed to get domain."); return nullptr; } - auto assembly = Il2cppJson::InvokeIl2cpp("il2cpp_domain_assembly_open", domain, assemblyName); + + Il2cppJson::InvokeIl2cpp("il2cpp_thread_attach", domain); + + auto assembly = Il2cppJson::InvokeIl2cpp("il2cpp_domain_assembly_open", domain, assemblyName); if (!assembly) { Log::ErrorFmt("GetMethodIl2cpp error: failed to get assembly: %s", assemblyName); return nullptr; } - // auto assembly = Il2cppJson::InvokeIl2cpp("il2cpp_domain_assembly_open+1", assemblyName); - // UnityResolve::Invoke("il2cpp_thread_attach", domain); - Log::Info("GetMethodIl2cpp 1"); - auto image = Il2cppJson::InvokeIl2cpp("il2cpp_assembly_get_image", assembly); + // Log::Info("GetMethodIl2cpp 1"); + // auto image = Il2cppJson::InvokeIl2cpp("il2cpp_assembly_get_image", assembly); + auto image = assembly->image; if (!image) { Log::ErrorFmt("GetMethodIl2cpp error: assembly %s not found.", assemblyName); return nullptr; } - Log::InfoFmt("GetMethodIl2cpp 2, assembly: %p, image: %p, nameSpace: %s, class: %s", assembly, image, nameSpaceName, className); + // Log::InfoFmt("GetMethodIl2cpp 2, assembly: %p, image: %p, nameSpace: %s, class: %s", assembly, image, nameSpaceName, className); auto klass = Il2cppJson::InvokeIl2cpp("il2cpp_class_from_name", image, nameSpaceName, className); - Log::Info("GetMethodIl2cpp 3"); + // Log::Info("GetMethodIl2cpp 3"); if (!klass) { Log::ErrorFmt("GetMethodIl2cpp error: Class %s::%s not found.", nameSpaceName, className); return nullptr; @@ -192,11 +198,11 @@ namespace Il2cppUtils { const char* className, const char* methodName, const int argsCount) { auto klass = GetIl2cppClassFromName(assemblyName, nameSpaceName, className); if (!klass) return nullptr; - Log::Info("GetMethodIl2cpp 4"); + // Log::Info("GetMethodIl2cpp 4"); auto ret = Il2cppJson::InvokeIl2cpp("il2cpp_class_get_method_from_name", klass, methodName, argsCount); - Log::Info("GetMethodIl2cpp 5"); + // Log::Info("GetMethodIl2cpp 5"); if (!ret) { - Log::ErrorFmt("GetMethodIl2cpp error: method %s::%s.%s not found.", nameSpaceName, className, methodName); + // Log::ErrorFmt("GetMethodIl2cpp error: method %s::%s.%s not found.", nameSpaceName, className, methodName); return nullptr; } return ret; @@ -251,6 +257,17 @@ namespace Il2cppUtils { return reinterpret_cast(method->address); } + inline void* GetMethodPointerIl2cpp(const char* assemblyName, + const char* nameSpaceName, + const char* className, + const char* methodName, + const int argsCount) + { + const auto method = GetMethodIl2cpp(assemblyName, nameSpaceName, className, methodName, argsCount); + if (!method) return nullptr; + return reinterpret_cast(method->methodPointer); + } + template static auto ClassGetFieldValue(void* obj, FieldInfo* field) -> RType { return *reinterpret_cast(reinterpret_cast(obj) + field->offset); @@ -464,9 +481,9 @@ namespace Il2cppUtils { // dic_klass = dicClass; this->dict = dict; - get_Item_method = Il2cppJson::InvokeIl2cpp("il2cpp_class_get_method_from_name", "get_Item", 1); - Add_method = Il2cppJson::InvokeIl2cpp("il2cpp_class_get_method_from_name", "Add", 2); - ContainsKey_method = Il2cppJson::InvokeIl2cpp("il2cpp_class_get_method_from_name", "ContainsKey", 1); + get_Item_method = il2cpp_class_get_method_from_name(dic_klass, "get_Item", 1); + Add_method = il2cpp_class_get_method_from_name(dic_klass, "Add", 2); + ContainsKey_method = il2cpp_class_get_method_from_name(dic_klass, "ContainsKey", 1); dic_get_Item = (dic_get_Item_t)get_Item_method->methodPointer; dic_Add = (dic_Add_t)Add_method->methodPointer; diff --git a/GakumasLocalify/il2cpp_dump/Il2cppJson.hpp b/GakumasLocalify/il2cpp_dump/Il2cppJson.hpp index 59f4cf7..bbeb463 100644 --- a/GakumasLocalify/il2cpp_dump/Il2cppJson.hpp +++ b/GakumasLocalify/il2cpp_dump/Il2cppJson.hpp @@ -29,8 +29,9 @@ inline std::map& GetIl2cppAddressMap() { { "il2cpp_class_from_system_type", 0x9DCC028 }, { "il2cpp_init", 0x9D70D90 }, { "il2cpp_class_from_name", 0x9DCE4A4 }, - { "il2cpp_assembly_get_image", 0x7C11B50 }, + // { "il2cpp_assembly_get_image", 0x7C11B50 }, { "il2cpp_domain_get", 0x9DB81AC }, + { "il2cpp_thread_attach", 0x9DBB684 }, { "il2cpp_domain_assembly_open", 0x9D70EE4 }, { "il2cpp_domain_assembly_open+1", 0x9DA374C }, { "il2cpp_resolve_icall", 0x9D71304 }, @@ -42,7 +43,6 @@ inline std::map& GetIl2cppAddressMap() { // il2cpp_class_get_type // il2cpp_field_static_set_value // il2cpp_runtime_invoke - // il2cpp_thread_attach // il2cpp_domain_get_assemblies // il2cpp_image_get_filename // il2cpp_image_get_name @@ -65,6 +65,10 @@ auto InvokeIl2cpp(const std::string& name, Args... args) -> Return { // GakumasLocal::Log::InfoFmt("InvokeIl2cpp: %s", name.c_str()); return InvokeAddress(GetUnityBaseAddress() + it->second, args...); } + else + { + GakumasLocal::Log::ErrorFmt("Il2cpp Method: %s not found!", name.c_str()); + } // GakumasLocal::Log::InfoFmt("InvokeIl2cpp failed: %s", name.c_str()); // return nullptr; diff --git a/GakumasLocalify/il2cpp_dump/il2cppTypes.hpp b/GakumasLocalify/il2cpp_dump/il2cppTypes.hpp index eb179ba..6dd3905 100644 --- a/GakumasLocalify/il2cpp_dump/il2cppTypes.hpp +++ b/GakumasLocalify/il2cpp_dump/il2cppTypes.hpp @@ -161,4 +161,75 @@ namespace Il2cppTypes return UnityResolve::Invoke("mono_array_new", pDomain, kalss->address, size); }*/ }; + + + template + struct List : Il2CppObject { + Array* pList; + int size{}; + int version{}; + void* syncRoot{}; + + auto ToArray() -> Array* { return pList; } + + /* + static auto New(const Class* kalss, const std::uintptr_t size) -> List* { + auto pList = new List(); + pList->pList = Array::New(kalss, size); + pList->size = size; + }*/ + + auto operator[](const unsigned int m_uIndex) -> Type& { return pList->At(m_uIndex); } + /* + auto Add(Type pDate) -> void { + if (!this) return; + static Method* method; + if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get("Add"); + if (method) return method->Invoke(this, pDate); + } + + auto Remove(Type pDate) -> bool { + if (!this) return false; + static Method* method; + if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get("Remove"); + if (method) return method->Invoke(this, pDate); + return false; + } + + auto RemoveAt(int index) -> void { + if (!this) return; + static Method* method; + if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get("RemoveAt"); + if (method) return method->Invoke(this, index); + } + + auto ForEach(void(*action)(Type pDate)) -> void { + if (!this) return; + static Method* method; + if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get("ForEach"); + if (method) return method->Invoke(this, action); + } + + auto GetRange(int index, int count) -> List* { + if (!this) return {}; + static Method* method; + if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get("GetRange"); + if (method) return method->Invoke(this, index, count); + return nullptr; + } + + auto Clear() -> void { + if (!this) return; + static Method* method; + if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get("Clear"); + if (method) return method->Invoke(this); + } + + auto Sort(int (*comparison)(Type* pX, Type* pY)) -> void { + if (!this) return; + static Method* method; + if (!method) method = Get("mscorlib.dll")->Get("List`1")->Get("Sort", { "*" }); + if (method) return method->Invoke(this, comparison); + }*/ + }; }