Beispiel #1
0
    /// <summary>
    /// Creates an APK of the selected <paramref name="profile"/>.
    /// </summary>
    /// <param name="profile"><see cref="ProfileXML"/> to be compiled into an APK.</param>
    /// <param name="useHqMusic">Wether to create the APK with high quality music or not.</param>
    /// <param name="progress">Provides the current progress of this method.</param>
    public static void CreateAPK(ProfileXML profile, bool useHqMusic, IProgress <int> progress)
    {
        // Overall safety check just in case of bad situations
        if (!profile.SupportsAndroid)
        {
            progress.Report(100);
            return;
        }

        log.Info("Creating Android APK for profile " + profile.Name + ".");

        // Create working dir after some cleanup
        string apktoolPath = CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/android/apktool.jar",
               uberPath    = CrossPlatformOperations.CURRENTPATH + "/PatchData/utilities/android/uber-apk-signer.jar",
               tempDir     = new DirectoryInfo(CrossPlatformOperations.CURRENTPATH + "/temp").FullName,
               dataPath    = CrossPlatformOperations.CURRENTPATH + profile.DataPath;

        if (Directory.Exists(tempDir))
        {
            Directory.Delete(tempDir, true);
        }
        Directory.CreateDirectory(tempDir);

        log.Info("Cleanup, variables, and working directory created.");
        progress.Report(14);

        // Decompile AM2RWrapper.apk
        CrossPlatformOperations.RunJavaJar("\"" + apktoolPath + "\" d \"" + dataPath + "/android/AM2RWrapper.apk\"", tempDir);
        log.Info("AM2RWrapper decompiled.");
        progress.Report(28);

        // Add datafiles: 1.1, new datafiles, hq music, am2r.ini
        string workingDir = tempDir + "/AM2RWrapper/assets";

        ZipFile.ExtractToDirectory(CrossPlatformOperations.CURRENTPATH + "/AM2R_11.zip", workingDir);
        HelperMethods.DirectoryCopy(dataPath + "/files_to_copy", workingDir);

        if (useHqMusic)
        {
            HelperMethods.DirectoryCopy(CrossPlatformOperations.CURRENTPATH + "/PatchData/data/HDR_HQ_in-game_music", workingDir);
        }
        // Yes, I'm aware this is dumb. If you've got any better ideas for how to copy a seemingly randomly named .ini from this folder to the APK, please let me know.
        foreach (FileInfo file in new DirectoryInfo(dataPath).GetFiles().Where(f => f.Name.EndsWith("ini")))
        {
            File.Copy(file.FullName, workingDir + "/" + file.Name);
        }

        log.Info("AM2R_11.zip extracted and datafiles copied into AM2RWrapper.");
        progress.Report(42);

        // Patch data.win to game.droid
        CrossPlatformOperations.ApplyXdeltaPatch(workingDir + "/data.win", dataPath + "/droid.xdelta", workingDir + "/game.droid");
        log.Info("game.droid successfully patched.");
        progress.Report(56);

        // Delete unnecessary files
        File.Delete(workingDir + "/AM2R.exe");
        File.Delete(workingDir + "/D3DX9_43.dll");
        File.Delete(workingDir + "/explanations.txt");
        File.Delete(workingDir + "/modifiers.ini");
        File.Delete(workingDir + "/readme.txt");
        File.Delete(workingDir + "/data.win");
        Directory.Delete(workingDir + "/mods", true);
        Directory.Delete(workingDir + "/lang/headers", true);
        if (OS.IsLinux)
        {
            File.Delete(workingDir + "/icon.png");
        }

        // Modify apktool.yml to NOT compress ogg files
        string apktoolText = File.ReadAllText(workingDir + "/../apktool.yml");

        apktoolText = apktoolText.Replace("doNotCompress:", "doNotCompress:\n- ogg");
        File.WriteAllText(workingDir + "/../apktool.yml", apktoolText);
        log.Info("Unnecessary files removed, apktool.yml modified to prevent ogg compression.");
        progress.Report(70);

        // Rebuild APK
        CrossPlatformOperations.RunJavaJar("\"" + apktoolPath + "\" b AM2RWrapper -o \"" + profile.Name + ".apk\"", tempDir);
        log.Info("AM2RWrapper rebuilt into " + profile.Name + ".apk.");
        progress.Report(84);

        // Debug-sign APK
        CrossPlatformOperations.RunJavaJar("\"" + uberPath + "\" -a \"" + profile.Name + ".apk\"", tempDir);

        // Extra file cleanup
        File.Copy(tempDir + "/" + profile.Name + "-aligned-debugSigned.apk", CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk", true);
        log.Info(profile.Name + ".apk signed and moved to " + CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk.");
        HelperMethods.DeleteDirectory(tempDir);

        // Done
        progress.Report(100);
        log.Info("Successfully created Android APK for profile " + profile.Name + ".");
        CrossPlatformOperations.OpenFolderAndSelectFile(CrossPlatformOperations.CURRENTPATH + "/" + profile.Name + ".apk");
    }