示例#1
0
 private void AddModLoaderToApk(string apkFilename)
 {
     UpdateStatus("Adding the libmodloader.so file to the APK...");
     try
     {
         using (var apk = new ZipFileProvider(apkFilename, FileCacheMode.None, false, QuestomAssets.Utils.FileUtils.GetTempDirectory()))
         {
             using (var resStream = _context.Resources.OpenRawResource(Resource.Raw.libmodloader))
             {
                 using (var resStream64 = _context.Resources.OpenRawResource(Resource.Raw.libmodloader64))
                 {
                     if (apk.DirectoryExists(LIBMODLOADER_TARGET_FILE.GetDirectoryFwdSlash()))
                     {
                         if (apk.FileExists(LIBMODLOADER_TARGET_FILE))
                         {
                             apk.Delete(LIBMODLOADER_TARGET_FILE);
                             apk.Save();
                         }
                         apk.QueueWriteStream(LIBMODLOADER_TARGET_FILE, resStream, true, true);
                     }
                     if (apk.DirectoryExists(LIBMODLOADER64_TARGET_FILE.GetDirectoryFwdSlash()))
                     {
                         if (apk.FileExists(LIBMODLOADER64_TARGET_FILE))
                         {
                             apk.Delete(LIBMODLOADER64_TARGET_FILE);
                             apk.Save();
                         }
                         apk.QueueWriteStream(LIBMODLOADER64_TARGET_FILE, resStream64, true, true);
                     }
                     try
                     {
                         apk.Save();
                     } catch (IOException)
                     {
                         GC.Collect();
                         System.Threading.Thread.Sleep(1000);
                         apk.Save();
                     }
                 }
             }
         }
     }
     catch (Exception ex)
     {
         Log.LogErr("Error adding libmodloader.so to APK", ex);
         UpdateStatus("Error adding modloader to the APK!");
         throw new ModException("Error adding libmodloader.so to APK", ex);
     }
 }
示例#2
0
        private void AddAndroidPermissions(string apkFilename, List <string> permissions)
        {
            if (permissions == null || permissions.Count < 1)
            {
                throw new ArgumentException("At least one permission must be specified to add.");
            }
            try
            {
                using (var apk = new ZipFileProvider(apkFilename, FileCacheMode.None, false, QuestomAssets.Utils.FileUtils.GetTempDirectory()))
                {
                    byte[]     manifest = apk.Read("AndroidManifest.xml");
                    AxmlWriter writer   = new WritePermissionAxmlWriter(permissions);
                    AxmlReader reader   = new AxmlReader(manifest);

                    reader.Accept(writer);
                    var outData = writer.ToByteArray();
                    apk.Write("AndroidManifest.xml", outData, true);
                    apk.Save();
                }
            }
            catch (Exception ex)
            {
                Log.LogErr("Exception trying to add permissions to AndroidManifest.xml", ex);
                throw;
            }
        }
示例#3
0
 private void SaveFileToApk(string apkFileName, string toFileName, string sourceFile)
 {
     using (var apk = new ZipFileProvider(apkFileName, FileCacheMode.None, false, QuestomAssets.Utils.FileUtils.GetTempDirectory()))
     {
         using (var fs = File.OpenRead(sourceFile))
         {
             apk.QueueWriteStream(toFileName, fs, true, true);
             apk.Save();
         }
     }
 }
示例#4
0
 private void AddTagFileToApk(string apkFilename)
 {
     using (var apk = new ZipFileProvider(apkFilename, FileCacheMode.None, false, QuestomAssets.Utils.FileUtils.GetTempDirectory()))
     {
         if (apk.FileExists(MOD_TAG_FILE))
         {
             Log.LogMsg("APK file already had the mod's tag file.");
             return;
         }
         apk.Write(MOD_TAG_FILE, new byte[1], true, false);
         apk.Save();
     }
 }
示例#5
0
 private void AddModLoaderToApk(string apkFilename)
 {
     UpdateStatus("Adding the libmodloader.so file to the APK...");
     try
     {
         using (var apk = new ZipFileProvider(apkFilename, FileCacheMode.None, false, QuestomAssets.Utils.FileUtils.GetTempDirectory()))
         {
             using (var resStream = _context.Resources.OpenRawResource(Resource.Raw.libmodloader))
             {
                 apk.QueueWriteStream(LIBMODLOADER_TARGET_FILE, resStream, true, true);
                 apk.Save();
             }
         }
     }
     catch (Exception ex)
     {
         Log.LogErr("Error adding libmodloader.so to APK", ex);
         UpdateStatus("Error adding modloader to the APK!");
         throw new ModException("Error adding libmodloader.so to APK", ex);
     }
 }
示例#6
0
 private void AddManifestModToApk(string apkFilename)
 {
     UpdateStatus("Modding the manifest in the APK...");
     try
     {
         using (var apk = new ZipFileProvider(apkFilename, FileCacheMode.None, false, QuestomAssets.Utils.FileUtils.GetTempDirectory()))
         {
             using (var resStream = _context.Resources.OpenRawResource(Resource.Raw.manifestmod))
             {
                 apk.QueueWriteStream("AndroidManifest.xml", resStream, true, true);
                 apk.Save();
             }
         }
     }
     catch (Exception ex)
     {
         Log.LogErr("Error modding the manifest in the APK", ex);
         UpdateStatus("Error modding the manifest in the APK!");
         throw new ModException("Error modding the manifest in the APK", ex);
     }
 }
示例#7
0
        private void ExtractAssetsFromApkToExternalStorage(string apkFilename, List <string> excludePaths = null, bool fromBakFiles = false)
        {
            UpdateStatus("Extracting assets files from the APK to external storage...");
            using (var apk = new ZipFileProvider(apkFilename, FileCacheMode.None, false, QuestomAssets.Utils.FileUtils.GetTempDirectory()))
            {
                foreach (var assetFilename in apk.FindFiles(APK_ASSETS_PATH + "*"))
                {
                    string relativeFilename = assetFilename.Substring(APK_ASSETS_PATH.Length);
                    if (excludePaths != null)
                    {
                        if (excludePaths.Any(x => relativeFilename.StartsWith(x)))
                        {
                            Log.LogMsg($"The asset file {assetFilename} ({relativeFilename}) is not included in assets that should be extracted, skipping.");
                            continue;
                        }
                    }
                    Log.LogMsg($"Extracting {assetFilename}...");
                    string targetFile = Path.Combine(Constants.ASSETS_RELOC_PATH, relativeFilename);
                    string dirName    = Path.GetDirectoryName(targetFile);
                    try
                    {
                        if (!Directory.Exists(dirName))
                        {
                            Log.LogMsg($"Assets target directory doesn't exist, creating {dirName}");
                            Directory.CreateDirectory(dirName);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.LogErr($"Unable to create directory {dirName}!", ex);
                        UpdateStatus("Failed to create assets directory in external storage!");
                        throw new ModException($"Unable to create directory {dirName}!", ex);
                    }
                    try
                    {
                        using (var readStream = apk.GetReadStream(assetFilename, true))
                        {
                            if (targetFile.EndsWith(".bobak"))
                            {
                                targetFile = targetFile.Substring(0, targetFile.Length - 6);
                            }

                            using (var fs = File.Open(targetFile, FileMode.Create, FileAccess.Write))
                            {
                                readStream.CopyTo(fs);
                            }
                        }
                        if (!assetFilename.EndsWith(".bobak"))
                        {
                            apk.Rename(assetFilename, assetFilename + ".bobak");
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.LogErr($"Failed to extract {assetFilename} to {targetFile}", ex);
                        UpdateStatus("Failed extracting an asset from the APK to external storage!");
                        throw new ModException($"Failed to extract {assetFilename} to {targetFile}", ex);
                    }
                }
                apk.Save();
            }
        }
示例#8
0
        /// <summary>
        /// Checks if the backup exists, or creates a very unideal backup of the modded APK for the sake of uninstalling mods
        /// </summary>
        public void CheckCreateModdedBackup()
        {
            try
            {
                if (File.Exists(Constants.BEATSABER_APK_BACKUP_FILE))
                {
                    return;
                }
                Log.LogErr("WARNING: backup of original Beat Saber APK does not exist.  Will attempt to fall back to a post-mod backup.");
                if (File.Exists(Constants.BEATSABER_APK_MODDED_BACKUP_FILE))
                {
                    return;
                }
                Log.LogErr("Post-modded backup of Beat Saber APK does not exist, will attempt to create one.");

                if (!IsBeatSaberInstalled)
                {
                    Log.LogErr("Beat saber isn't even installed.  Can't make any sort of backup.");
                    return;
                }
                var apkPath = FindBeatSaberApk();
                if (apkPath == null)
                {
                    Log.LogErr("Unable to find the installed Beat Saber APK path.  Cannot make a post-mod backup.");
                    return;
                }
                Log.LogErr("Copying APK for unideal backup...");
                try
                {
                    File.Copy(apkPath, Constants.BEATSABER_APK_MODDED_BACKUP_FILE, true);
                }
                catch (Exception ex)
                {
                    Log.LogErr("Exception trying to copy APK for half assed backup.", ex);
                    return;
                }
                try
                {
                    Log.LogErr("Restoring names of modded APK asset files so they can serve as a backup...");
                    using (var apk = new ZipFileProvider(Constants.BEATSABER_APK_MODDED_BACKUP_FILE, FileCacheMode.None, false, QuestomAssets.Utils.FileUtils.GetTempDirectory()))
                    {
                        foreach (var assetFilename in apk.FindFiles(APK_ASSETS_PATH + "*"))
                        {
                            if (assetFilename.EndsWith(".bobak"))
                            {
                                apk.Rename(assetFilename, assetFilename.Substring(0, assetFilename.Length - 6));
                            }
                        }
                        apk.Save();
                    }
                }
                catch (Exception ex)
                {
                    Log.LogErr("Exception trying to make a half assed, post-mod backup while renaming files within the APK", ex);
                }
            }
            catch (Exception ex)
            {
                Log.LogErr($"Exception trying to check/create backups", ex);
            }
        }