forked from chinosk/gkms-local
				
			fix crash when using remote files
This commit is contained in:
		
							parent
							
								
									06b552a097
								
							
						
					
					
						commit
						e03736bd7d
					
				| 
						 | 
				
			
			@ -466,12 +466,60 @@ namespace GakumasLocal::HookMain {
 | 
			
		|||
        // return UnityResolve::UnityType::String::New("[I18]" + ret->ToString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DEFINE_HOOK(void, PictureBookLiveThumbnailView_SetData, (void* self, void* liveData, bool isUnlocked, bool isNew, void* ct, void* mtd)) {
 | 
			
		||||
        // Log::DebugFmt("PictureBookLiveThumbnailView_SetData: isUnlocked: %d, isNew: %d", isUnlocked, isNew);
 | 
			
		||||
    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);
 | 
			
		||||
        if (Config::dbgMode && Config::unlockAllLive) {
 | 
			
		||||
            isUnlocked = true;
 | 
			
		||||
            isReleased = true;
 | 
			
		||||
        }
 | 
			
		||||
        PictureBookLiveThumbnailView_SetData_Orig(self, liveData, isUnlocked, isNew, ct, mtd);
 | 
			
		||||
        PictureBookLiveThumbnailView_SetData_Orig(self, liveData, isReleased, isUnlocked, isNew, hasLiveSkin, ct, mtd);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::vector<std::string> GetIdolMusicIdAll(const std::string& charaNameId = "") {
 | 
			
		||||
        // 传入例: 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>>
 | 
			
		||||
        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 GetLiveMusics = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.OutGame",
 | 
			
		||||
                                                           "PictureBookWindowPresenter", "GetLiveMusics");
 | 
			
		||||
 | 
			
		||||
        auto idolCardSkinMaster = get_IdolCardSkinMaster->Invoke<void*>(nullptr);  // IdolCardSkinMaster
 | 
			
		||||
 | 
			
		||||
        std::vector<std::string> ret{};
 | 
			
		||||
 | 
			
		||||
        if (!idolCardSkinMaster) {
 | 
			
		||||
            Log::ErrorFmt("get_IdolCardSkinMaster failed: %p", idolCardSkinMaster);
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
        // List<IdolCardSkin>
 | 
			
		||||
        auto idolCardSkinList = Master_GetAllWithSortByKey->Invoke<UnityResolve::UnityType::List<void*>*>(idolCardSkinMaster, 0x0, nullptr);
 | 
			
		||||
 | 
			
		||||
        auto idolCardSkins = idolCardSkinList->ToArray()->ToVector();
 | 
			
		||||
        const auto checkStartCharaId = "i_card-" + charaNameId;
 | 
			
		||||
        // Log::DebugFmt("checkStartCharaId: %s", checkStartCharaId.c_str());
 | 
			
		||||
 | 
			
		||||
        // origMusics->Clear();
 | 
			
		||||
        for (auto i : idolCardSkins) {
 | 
			
		||||
            if (!i) continue;
 | 
			
		||||
            // auto charaId = IdolCardSkin_get_Id->Invoke<Il2cppString*>(i);
 | 
			
		||||
            auto musicId = IdolCardSkin_get_MusicId->Invoke<Il2cppString*>(i);
 | 
			
		||||
            auto cardId = IdolCardSkin_get_IdolCardId->Invoke<Il2cppString*>(i)->ToString();
 | 
			
		||||
            auto music = IdolCardSkin_GetMusic->Invoke<void*>(i);
 | 
			
		||||
 | 
			
		||||
            if (charaNameId.empty() || cardId.starts_with(checkStartCharaId)) {
 | 
			
		||||
                std::string musicIdStr = musicId->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* PictureBookWindowPresenter_instance = nullptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -482,19 +530,46 @@ namespace GakumasLocal::HookMain {
 | 
			
		|||
        if (Config::unlockAllLive) {
 | 
			
		||||
            PictureBookWindowPresenter_instance = self;
 | 
			
		||||
            PictureBookWindowPresenter_charaId = charaId->ToString();
 | 
			
		||||
 | 
			
		||||
            static auto PictureBookWindowPresenter_klass = Il2cppUtils::GetClass("Assembly-CSharp.dll", "Campus.OutGame",
 | 
			
		||||
                                                                                 "PictureBookWindowPresenter");
 | 
			
		||||
            static auto existsMusicIds_field = PictureBookWindowPresenter_klass->Get<UnityResolve::Field>("_existsMusicIds");
 | 
			
		||||
            auto existsMusicIds = Il2cppUtils::ClassGetFieldValue<UnityResolve::UnityType::List<Il2cppString*>*>(self, existsMusicIds_field);
 | 
			
		||||
 | 
			
		||||
            if (!existsMusicIds) {
 | 
			
		||||
                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<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);
 | 
			
		||||
                List_String_ctor(newList, List_String_ctor_mtd);
 | 
			
		||||
 | 
			
		||||
                auto fullIds = GetIdolMusicIdAll();
 | 
			
		||||
 | 
			
		||||
                for (auto& i : fullIds) {
 | 
			
		||||
                    // Log::DebugFmt("GetLiveMusics - Add: %s", i.c_str());
 | 
			
		||||
                    // newList->Add(Il2cppString::New(i));
 | 
			
		||||
                    List_String_Add(newList, Il2cppString::New(i), List_String_Add_mtd);
 | 
			
		||||
                }
 | 
			
		||||
                Il2cppUtils::ClassSetFieldValue(self, existsMusicIds_field, newList);
 | 
			
		||||
                // Log::DebugFmt("GetLiveMusics - set end: %d", fullIds.size());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return PictureBookWindowPresenter_GetLiveMusics_Orig(self, charaId, mtd);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DEFINE_HOOK(void, PictureBookLiveSelectScreenModel_ctor, (void* self, void* transitionParam, void* musics, void* mtd)) {
 | 
			
		||||
    DEFINE_HOOK(void, PictureBookLiveSelectScreenModel_ctor, (void* self, void* transitionParam, UnityResolve::UnityType::List<void*>* musics, void* mtd)) {
 | 
			
		||||
        // Log::DebugFmt("PictureBookLiveSelectScreenModel_ctor");
 | 
			
		||||
 | 
			
		||||
        if (Config::unlockAllLive) {
 | 
			
		||||
            static auto GetLiveMusics = Il2cppUtils::GetMethod("Assembly-CSharp.dll", "Campus.OutGame",
 | 
			
		||||
                                                               "PictureBookWindowPresenter", "GetLiveMusics");
 | 
			
		||||
            if (PictureBookWindowPresenter_instance && !PictureBookWindowPresenter_charaId.empty()) {
 | 
			
		||||
                auto fullMusics = GetLiveMusics->Invoke<void*>(PictureBookWindowPresenter_instance,
 | 
			
		||||
                auto fullMusics = GetLiveMusics->Invoke<UnityResolve::UnityType::List<void*>*>(PictureBookWindowPresenter_instance,
 | 
			
		||||
                                                               Il2cppString::New(PictureBookWindowPresenter_charaId));
 | 
			
		||||
                return PictureBookLiveSelectScreenModel_ctor_Orig(self, transitionParam, fullMusics, mtd);
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,74 @@ namespace Il2cppUtils {
 | 
			
		|||
        uint8_t is_marshaled_from_native : 1;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct Il2CppObject
 | 
			
		||||
    {
 | 
			
		||||
        union
 | 
			
		||||
        {
 | 
			
		||||
            void* klass;
 | 
			
		||||
            void* vtable;
 | 
			
		||||
        };
 | 
			
		||||
        void* monitor;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum Il2CppTypeEnum
 | 
			
		||||
    {
 | 
			
		||||
        IL2CPP_TYPE_END = 0x00,       /* End of List */
 | 
			
		||||
        IL2CPP_TYPE_VOID = 0x01,
 | 
			
		||||
        IL2CPP_TYPE_BOOLEAN = 0x02,
 | 
			
		||||
        IL2CPP_TYPE_CHAR = 0x03,
 | 
			
		||||
        IL2CPP_TYPE_I1 = 0x04,
 | 
			
		||||
        IL2CPP_TYPE_U1 = 0x05,
 | 
			
		||||
        IL2CPP_TYPE_I2 = 0x06,
 | 
			
		||||
        IL2CPP_TYPE_U2 = 0x07,
 | 
			
		||||
        IL2CPP_TYPE_I4 = 0x08,
 | 
			
		||||
        IL2CPP_TYPE_U4 = 0x09,
 | 
			
		||||
        IL2CPP_TYPE_I8 = 0x0a,
 | 
			
		||||
        IL2CPP_TYPE_U8 = 0x0b,
 | 
			
		||||
        IL2CPP_TYPE_R4 = 0x0c,
 | 
			
		||||
        IL2CPP_TYPE_R8 = 0x0d,
 | 
			
		||||
        IL2CPP_TYPE_STRING = 0x0e,
 | 
			
		||||
        IL2CPP_TYPE_PTR = 0x0f,
 | 
			
		||||
        IL2CPP_TYPE_BYREF = 0x10,
 | 
			
		||||
        IL2CPP_TYPE_VALUETYPE = 0x11,
 | 
			
		||||
        IL2CPP_TYPE_CLASS = 0x12,
 | 
			
		||||
        IL2CPP_TYPE_VAR = 0x13,
 | 
			
		||||
        IL2CPP_TYPE_ARRAY = 0x14,
 | 
			
		||||
        IL2CPP_TYPE_GENERICINST = 0x15,
 | 
			
		||||
        IL2CPP_TYPE_TYPEDBYREF = 0x16,
 | 
			
		||||
        IL2CPP_TYPE_I = 0x18,
 | 
			
		||||
        IL2CPP_TYPE_U = 0x19,
 | 
			
		||||
        IL2CPP_TYPE_FNPTR = 0x1b,
 | 
			
		||||
        IL2CPP_TYPE_OBJECT = 0x1c,
 | 
			
		||||
        IL2CPP_TYPE_SZARRAY = 0x1d,
 | 
			
		||||
        IL2CPP_TYPE_MVAR = 0x1e,
 | 
			
		||||
        IL2CPP_TYPE_CMOD_REQD = 0x1f,
 | 
			
		||||
        IL2CPP_TYPE_CMOD_OPT = 0x20,
 | 
			
		||||
        IL2CPP_TYPE_INTERNAL = 0x21,
 | 
			
		||||
 | 
			
		||||
        IL2CPP_TYPE_MODIFIER = 0x40,
 | 
			
		||||
        IL2CPP_TYPE_SENTINEL = 0x41,
 | 
			
		||||
        IL2CPP_TYPE_PINNED = 0x45,
 | 
			
		||||
 | 
			
		||||
        IL2CPP_TYPE_ENUM = 0x55
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef struct Il2CppType
 | 
			
		||||
    {
 | 
			
		||||
        void* dummy;
 | 
			
		||||
        unsigned int attrs : 16;
 | 
			
		||||
        Il2CppTypeEnum type : 8;
 | 
			
		||||
        unsigned int num_mods : 6;
 | 
			
		||||
        unsigned int byref : 1;
 | 
			
		||||
        unsigned int pinned : 1;
 | 
			
		||||
    } Il2CppType;
 | 
			
		||||
 | 
			
		||||
    struct Il2CppReflectionType
 | 
			
		||||
    {
 | 
			
		||||
        Il2CppObject object;
 | 
			
		||||
        const Il2CppType* type;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct Resolution_t {
 | 
			
		||||
        int width;
 | 
			
		||||
        int height;
 | 
			
		||||
| 
						 | 
				
			
			@ -160,5 +228,20 @@ namespace Il2cppUtils {
 | 
			
		|||
        *reinterpret_cast<RType*>(reinterpret_cast<uintptr_t>(obj) + field->offset) = value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void* get_system_class_from_reflection_type_str(const char* typeStr, const char* assemblyName = "mscorlib") {
 | 
			
		||||
        using Il2CppString = UnityResolve::UnityType::String;
 | 
			
		||||
 | 
			
		||||
        static auto assemblyLoad = reinterpret_cast<void* (*)(Il2CppString*)>(
 | 
			
		||||
                GetMethodPointer("mscorlib.dll", "System.Reflection",
 | 
			
		||||
                                 "Assembly", "Load", {"*"})
 | 
			
		||||
        );
 | 
			
		||||
        static auto assemblyGetType = reinterpret_cast<Il2CppReflectionType * (*)(void*, Il2CppString*)>(
 | 
			
		||||
                GetMethodPointer("mscorlib.dll", "System.Reflection",
 | 
			
		||||
                                 "Assembly", "GetType", {"*"})
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        static auto reflectionAssembly = assemblyLoad(Il2CppString::New(assemblyName));
 | 
			
		||||
        auto reflectionType = assemblyGetType(reflectionAssembly, Il2CppString::New(typeStr));
 | 
			
		||||
        return UnityResolve::Invoke<void*>("il2cpp_class_from_system_type", reflectionType);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,7 +128,15 @@ fun <T> T.onClickStartGame() where T : Activity, T : IHasConfigItems {
 | 
			
		|||
            "io.github.chinosk.gakumas.localify.fileprovider",
 | 
			
		||||
            File(targetFile.absolutePath)
 | 
			
		||||
        )
 | 
			
		||||
        intent.setDataAndType(dirUri, "resource/file")
 | 
			
		||||
        // intent.setDataAndType(dirUri, "resource/file")
 | 
			
		||||
 | 
			
		||||
        grantUriPermission(
 | 
			
		||||
            "com.bandainamcoent.idolmaster_gakuen",
 | 
			
		||||
            dirUri,
 | 
			
		||||
            Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
 | 
			
		||||
        )
 | 
			
		||||
        intent.putExtra("resource_file", dirUri)
 | 
			
		||||
        // intent.clipData = ClipData.newRawUri("resource_file", dirUri)
 | 
			
		||||
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import android.content.Context
 | 
			
		|||
import android.content.Intent
 | 
			
		||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import android.os.Handler
 | 
			
		||||
import android.os.Looper
 | 
			
		||||
import android.util.Log
 | 
			
		||||
| 
						 | 
				
			
			@ -282,7 +283,14 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
 | 
			
		|||
 | 
			
		||||
            // 使用热更新文件
 | 
			
		||||
            if ((programConfig?.useRemoteAssets == true) || (programConfig?.useAPIAssets == true)) {
 | 
			
		||||
                val dataUri = intent.data
 | 
			
		||||
                // val dataUri = intent.data
 | 
			
		||||
                val dataUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
 | 
			
		||||
                    intent.getParcelableExtra("resource_file", Uri::class.java)
 | 
			
		||||
                } else {
 | 
			
		||||
                    @Suppress("DEPRECATION")
 | 
			
		||||
                    intent.getParcelableExtra<Uri>("resource_file")
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (dataUri != null) {
 | 
			
		||||
                    if (!externalFilesChecked) {
 | 
			
		||||
                        externalFilesChecked = true
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -645,7 +645,7 @@ class PatchActivity : ComponentActivity() {
 | 
			
		|||
                    val copyFilesCmd: MutableList<String> = mutableListOf()
 | 
			
		||||
                    val movedFiles: MutableList<String> = mutableListOf()
 | 
			
		||||
                    savedFileNames.forEach { file ->
 | 
			
		||||
                        val movedFileName = "$installDS/${file}"
 | 
			
		||||
                        val movedFileName = "\"$installDS/${file}\""
 | 
			
		||||
                        movedFiles.add(movedFileName)
 | 
			
		||||
                        val dlSaveFileName = File(targetDirectory, file)
 | 
			
		||||
                        copyFilesCmd.add("$action ${dlSaveFileName.absolutePath} $movedFileName")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue