forked from chinosk/gkms-local
				
			add ListEditor tool function
This commit is contained in:
		
							parent
							
								
									c27085772f
								
							
						
					
					
						commit
						6ac94178fa
					
				| 
						 | 
					@ -483,32 +483,6 @@ namespace GakumasLocal::HookMain {
 | 
				
			||||||
        return 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<void* (*)(void*, void*)>(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默认选择
 | 
					    DEFINE_HOOK(bool, UserIdolCardSkinCollection_Exists, (void* self, Il2cppString* id, void* mtd)) { // Live默认选择
 | 
				
			||||||
        auto ret = UserIdolCardSkinCollection_Exists_Orig(self, id, mtd);
 | 
					        auto ret = UserIdolCardSkinCollection_Exists_Orig(self, id, mtd);
 | 
				
			||||||
        // Log::DebugFmt("UserIdolCardSkinCollection_Exists: %s, ret: %d", id->ToString().c_str(), ret);
 | 
					        // Log::DebugFmt("UserIdolCardSkinCollection_Exists: %s, ret: %d", id->ToString().c_str(), ret);
 | 
				
			||||||
| 
						 | 
					@ -533,7 +507,13 @@ namespace GakumasLocal::HookMain {
 | 
				
			||||||
        PictureBookLiveThumbnailView_SetDataAsync_Orig(self, liveData, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd);
 | 
					        PictureBookLiveThumbnailView_SetDataAsync_Orig(self, liveData, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::vector<std::string> GetIdolMusicIdAll(const std::string& charaNameId = "") {
 | 
					    enum class GetIdolIdType {
 | 
				
			||||||
 | 
					        MusicId,
 | 
				
			||||||
 | 
					        CostumeId,
 | 
				
			||||||
 | 
					        CostumeHeadId
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::vector<std::string> GetIdolMusicIdAll(const std::string& charaNameId = "", GetIdolIdType getType = GetIdolIdType::MusicId) {
 | 
				
			||||||
        // 传入例: fktn
 | 
					        // 传入例: fktn
 | 
				
			||||||
        // System.Collections.Generic.List`1<valuetype [mscorlib]System.ValueTuple`2<class Campus.Common.Proto.Client.Master.IdolCardSkin, class Campus.Common.Proto.Client.Master.Music>>
 | 
					        // System.Collections.Generic.List`1<valuetype [mscorlib]System.ValueTuple`2<class Campus.Common.Proto.Client.Master.IdolCardSkin, class Campus.Common.Proto.Client.Master.Music>>
 | 
				
			||||||
        static auto get_IdolCardSkinMaster = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Master", "MasterManager", "get_IdolCardSkinMaster");
 | 
					        static auto get_IdolCardSkinMaster = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Master", "MasterManager", "get_IdolCardSkinMaster");
 | 
				
			||||||
| 
						 | 
					@ -542,6 +522,8 @@ namespace GakumasLocal::HookMain {
 | 
				
			||||||
        static auto IdolCardSkin_get_IdolCardId = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.Common.Proto.Client.Master", "IdolCardSkin", "get_IdolCardId");
 | 
					        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_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_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",
 | 
					        static auto GetLiveMusics = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.OutGame",
 | 
				
			||||||
                                                           "PictureBookWindowPresenter", "GetLiveMusics");
 | 
					                                                           "PictureBookWindowPresenter", "GetLiveMusics");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -561,15 +543,27 @@ namespace GakumasLocal::HookMain {
 | 
				
			||||||
        // Log::DebugFmt("checkStartCharaId: %s", checkStartCharaId.c_str());
 | 
					        // Log::DebugFmt("checkStartCharaId: %s", checkStartCharaId.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // origMusics->Clear();
 | 
					        // origMusics->Clear();
 | 
				
			||||||
 | 
					        UnityResolve::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) {
 | 
					        for (auto i : idolCardSkins) {
 | 
				
			||||||
            if (!i) continue;
 | 
					            if (!i) continue;
 | 
				
			||||||
            // auto charaId = IdolCardSkin_get_Id->Invoke<Il2cppString*>(i);
 | 
					            // auto charaId = IdolCardSkin_get_Id->Invoke<Il2cppString*>(i);
 | 
				
			||||||
            auto musicId = IdolCardSkin_get_MusicId->Invoke<Il2cppString*>(i);
 | 
					            auto targetId = idGetFunc->Invoke<Il2cppString*>(i);
 | 
				
			||||||
            auto cardId = IdolCardSkin_get_IdolCardId->Invoke<Il2cppString*>(i)->ToString();
 | 
					            auto cardId = IdolCardSkin_get_IdolCardId->Invoke<Il2cppString*>(i)->ToString();
 | 
				
			||||||
            auto music = IdolCardSkin_GetMusic->Invoke<void*>(i);
 | 
					            auto music = IdolCardSkin_GetMusic->Invoke<void*>(i);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (charaNameId.empty() || cardId.starts_with(checkStartCharaId)) {
 | 
					            if (charaNameId.empty() || cardId.starts_with(checkStartCharaId)) {
 | 
				
			||||||
                std::string musicIdStr = musicId->ToString();
 | 
					                std::string musicIdStr = targetId->ToString();
 | 
				
			||||||
                // Log::DebugFmt("Add cardId: %s, musicId: %s", cardId.c_str(), musicIdStr.c_str());
 | 
					                // Log::DebugFmt("Add cardId: %s, musicId: %s", cardId.c_str(), musicIdStr.c_str());
 | 
				
			||||||
                if (std::find(ret.begin(), ret.end(), musicIdStr) == ret.end()) {
 | 
					                if (std::find(ret.begin(), ret.end(), musicIdStr) == ret.end()) {
 | 
				
			||||||
                    ret.emplace_back(musicIdStr);
 | 
					                    ret.emplace_back(musicIdStr);
 | 
				
			||||||
| 
						 | 
					@ -579,6 +573,92 @@ namespace GakumasLocal::HookMain {
 | 
				
			||||||
        return ret;
 | 
					        return ret;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void* AddIdsToUserDataCollectionFromMaster(void* origList, std::vector<std::string>& allIds,
 | 
				
			||||||
 | 
					                                               UnityResolve::Method* get_CostumeId, UnityResolve::Method* set_CostumeId, UnityResolve::Method* Clone) {
 | 
				
			||||||
 | 
					        Il2cppUtils::Tools::CSListEditor listEditor(origList);
 | 
				
			||||||
 | 
					        if (listEditor.get_Count() <= 0) {
 | 
				
			||||||
 | 
					            return origList;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (auto i : listEditor) {
 | 
				
			||||||
 | 
					            auto currCostumeId = get_CostumeId->Invoke<Il2cppString*>(i);
 | 
				
			||||||
 | 
					            if (!currCostumeId) continue;
 | 
				
			||||||
 | 
					            std::string currCostumeIdStr = currCostumeId->ToString();
 | 
				
			||||||
 | 
					            if (std::find(allIds.begin(), allIds.end(), currCostumeIdStr) == allIds.end()) {
 | 
				
			||||||
 | 
					                allIds.emplace_back(currCostumeIdStr);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int currIndex = 0;
 | 
				
			||||||
 | 
					        int origSize = listEditor.get_Count();
 | 
				
			||||||
 | 
					        for (auto& i : allIds) {
 | 
				
			||||||
 | 
					            if (i.empty()) continue;
 | 
				
			||||||
 | 
					            // Log::DebugFmt("Try add %s", i.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (currIndex < origSize) {
 | 
				
			||||||
 | 
					                auto userCostume = listEditor.get_Item(currIndex);
 | 
				
			||||||
 | 
					                set_CostumeId->Invoke<void>(userCostume, Il2cppString::New(i));
 | 
				
			||||||
 | 
					                listEditor.set_Item(currIndex, userCostume);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                auto userCostume = Clone->Invoke<void*>(listEditor.get_Item(0));
 | 
				
			||||||
 | 
					                set_CostumeId->Invoke<void>(userCostume, Il2cppString::New(i));
 | 
				
			||||||
 | 
					                listEditor.Add(userCostume);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            currIndex++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return origList;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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<void* (*)(void*, void*)>(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") {
 | 
				
			||||||
 | 
					            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<Campus.Common.Proto.Client.Transaction.UserCostumeHead>
 | 
				
			||||||
 | 
					            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<Campus.Common.Proto.Client.Transaction.UserCostume>
 | 
				
			||||||
 | 
					            return AddIdsToUserDataCollectionFromMaster(origList, allIds, UserCostume_get_CostumeId, UserCostume_set_CostumeId, UserCostume_Clone);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void* PictureBookWindowPresenter_instance = nullptr;
 | 
					    void* PictureBookWindowPresenter_instance = nullptr;
 | 
				
			||||||
    std::string PictureBookWindowPresenter_charaId;
 | 
					    std::string PictureBookWindowPresenter_charaId;
 | 
				
			||||||
    DEFINE_HOOK(void*, PictureBookWindowPresenter_GetLiveMusics, (void* self, Il2cppString* charaId, void* mtd)) {
 | 
					    DEFINE_HOOK(void*, PictureBookWindowPresenter_GetLiveMusics, (void* self, Il2cppString* charaId, void* mtd)) {
 | 
				
			||||||
| 
						 | 
					@ -598,18 +678,16 @@ namespace GakumasLocal::HookMain {
 | 
				
			||||||
                        "System.Collections.Generic.List`1[System.String]");
 | 
					                        "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_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(List_String_klass, ".ctor", 0);
 | 
				
			||||||
                static auto List_String_ctor = reinterpret_cast<void (*)(void*, void*)>(List_String_ctor_mtd->methodPointer);
 | 
					                static auto List_String_ctor = reinterpret_cast<void (*)(void*, void*)>(List_String_ctor_mtd->methodPointer);
 | 
				
			||||||
                static auto List_String_Add_mtd = Il2cppUtils::il2cpp_class_get_method_from_name(List_String_klass, "Add", 1);
 | 
					 | 
				
			||||||
                static auto List_String_Add = reinterpret_cast<void (*)(void*, void*, void*)>(List_String_Add_mtd->methodPointer);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                auto newList = UnityResolve::Invoke<void*>("il2cpp_object_new", List_String_klass);
 | 
					                auto newList = UnityResolve::Invoke<void*>("il2cpp_object_new", List_String_klass);
 | 
				
			||||||
                List_String_ctor(newList, List_String_ctor_mtd);
 | 
					                List_String_ctor(newList, List_String_ctor_mtd);
 | 
				
			||||||
 | 
					                Il2cppUtils::Tools::CSListEditor<Il2cppString*> newListEditor(newList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                auto fullIds = GetIdolMusicIdAll();
 | 
					                auto fullIds = GetIdolMusicIdAll();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for (auto& i : fullIds) {
 | 
					                for (auto& i : fullIds) {
 | 
				
			||||||
                    // Log::DebugFmt("GetLiveMusics - Add: %s", i.c_str());
 | 
					                    // Log::DebugFmt("GetLiveMusics - Add: %s", i.c_str());
 | 
				
			||||||
                    // newList->Add(Il2cppString::New(i));
 | 
					                    newListEditor.Add(Il2cppString::New(i));
 | 
				
			||||||
                    List_String_Add(newList, Il2cppString::New(i), List_String_Add_mtd);
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                Il2cppUtils::ClassSetFieldValue(self, existsMusicIds_field, newList);
 | 
					                Il2cppUtils::ClassSetFieldValue(self, existsMusicIds_field, newList);
 | 
				
			||||||
                // Log::DebugFmt("GetLiveMusics - set end: %d", fullIds.size());
 | 
					                // Log::DebugFmt("GetLiveMusics - set end: %d", fullIds.size());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -244,4 +244,95 @@ namespace Il2cppUtils {
 | 
				
			||||||
        auto reflectionType = assemblyGetType(reflectionAssembly, Il2CppString::New(typeStr));
 | 
					        auto reflectionType = assemblyGetType(reflectionAssembly, Il2CppString::New(typeStr));
 | 
				
			||||||
        return UnityResolve::Invoke<void*>("il2cpp_class_from_system_type", reflectionType);
 | 
					        return UnityResolve::Invoke<void*>("il2cpp_class_from_system_type", reflectionType);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    namespace Tools {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        template <typename T = void*>
 | 
				
			||||||
 | 
					        class CSListEditor {
 | 
				
			||||||
 | 
					        public:
 | 
				
			||||||
 | 
					            CSListEditor(void* list) {
 | 
				
			||||||
 | 
					                list_klass = get_class_from_instance(list);
 | 
				
			||||||
 | 
					                lst = list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                lst_get_Count_method = il2cpp_class_get_method_from_name(list_klass, "get_Count", 0);
 | 
				
			||||||
 | 
					                lst_get_Item_method = il2cpp_class_get_method_from_name(list_klass, "get_Item", 1);
 | 
				
			||||||
 | 
					                lst_set_Item_method = il2cpp_class_get_method_from_name(list_klass, "set_Item", 2);
 | 
				
			||||||
 | 
					                lst_Add_method = il2cpp_class_get_method_from_name(list_klass, "Add", 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                lst_get_Count = reinterpret_cast<lst_get_Count_t>(lst_get_Count_method->methodPointer);
 | 
				
			||||||
 | 
					                lst_get_Item = reinterpret_cast<lst_get_Item_t>(lst_get_Item_method->methodPointer);
 | 
				
			||||||
 | 
					                lst_set_Item = reinterpret_cast<lst_set_Item_t>(lst_set_Item_method->methodPointer);
 | 
				
			||||||
 | 
					                lst_Add = reinterpret_cast<lst_Add_t>(lst_Add_method->methodPointer);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void Add(T value) {
 | 
				
			||||||
 | 
					                lst_Add(lst, value, lst_Add_method);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            T get_Item(int index) {
 | 
				
			||||||
 | 
					                return lst_get_Item(lst, index, lst_get_Item_method);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void set_Item(int index, T value) {
 | 
				
			||||||
 | 
					                return lst_set_Item(lst, index, value, lst_set_Item_method);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int get_Count() {
 | 
				
			||||||
 | 
					                return lst_get_Count(lst, lst_get_Count_method);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            T operator[] (int key) {
 | 
				
			||||||
 | 
					                return get_Item(key);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            class Iterator {
 | 
				
			||||||
 | 
					            public:
 | 
				
			||||||
 | 
					                Iterator(CSListEditor<T>* editor, int index) : editor(editor), index(index) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                T operator*() const {
 | 
				
			||||||
 | 
					                    return editor->get_Item(index);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Iterator& operator++() {
 | 
				
			||||||
 | 
					                    ++index;
 | 
				
			||||||
 | 
					                    return *this;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                bool operator!=(const Iterator& other) const {
 | 
				
			||||||
 | 
					                    return index != other.index;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            private:
 | 
				
			||||||
 | 
					                CSListEditor<T>* editor;
 | 
				
			||||||
 | 
					                int index;
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Iterator begin() {
 | 
				
			||||||
 | 
					                return Iterator(this, 0);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Iterator end() {
 | 
				
			||||||
 | 
					                return Iterator(this, get_Count());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void* lst;
 | 
				
			||||||
 | 
					            void* list_klass;
 | 
				
			||||||
 | 
					        private:
 | 
				
			||||||
 | 
					            typedef T(*lst_get_Item_t)(void*, int, void* mtd);
 | 
				
			||||||
 | 
					            typedef void(*lst_Add_t)(void*, T, void* mtd);
 | 
				
			||||||
 | 
					            typedef void(*lst_set_Item_t)(void*, int, T, void* mtd);
 | 
				
			||||||
 | 
					            typedef int(*lst_get_Count_t)(void*, void* mtd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            MethodInfo* lst_get_Item_method;
 | 
				
			||||||
 | 
					            MethodInfo* lst_Add_method;
 | 
				
			||||||
 | 
					            MethodInfo* lst_get_Count_method;
 | 
				
			||||||
 | 
					            MethodInfo* lst_set_Item_method;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            lst_get_Item_t lst_get_Item;
 | 
				
			||||||
 | 
					            lst_set_Item_t lst_set_Item;
 | 
				
			||||||
 | 
					            lst_Add_t lst_Add;
 | 
				
			||||||
 | 
					            lst_get_Count_t lst_get_Count;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue