static BuilderPackagesState() { // ensure auto recovery var dummy = new BuilderPackagesState(); dummy.LoadRecoverData(); dummy.Recover(null); }
private void DoBuild(Dictionary <string, string> options) { if (BuildPipeline.isBuildingPlayer) { Debug.LogWarning("Build is already running"); return; } EditorApplication.LockReloadAssemblies(); AssetDatabase.SaveAssets(); bool hasErrors = false; using (var config = new State(this, options)) { config.Log("Build started"); config.buildPath = this.buildPath; config.buildTarget = this.buildTarget; config.buildOptions = (BuildOptions)this.buildOptions; if (config.buildTarget == BuildTarget.iPhone && (config.buildOptions & BuildOptions.AcceptExternalModificationsToPlayer) != 0) { if (!File.Exists(Path.Combine(config.buildPath, "Unity-iPhone.xcodeproj/project.pbxproj"))) { config.buildOptions &= ~BuildOptions.AcceptExternalModificationsToPlayer; } } if (this.packages.Count > 0) { config.includedPackages.AddRange(this.packages); } string oldBundleIdentifier = null; if (!string.IsNullOrEmpty(this.bundleIdentifier)) { oldBundleIdentifier = PlayerSettings.bundleIdentifier; PlayerSettings.bundleIdentifier = this.bundleIdentifier; } string oldVersion = null; int oldBundleVersion = 0; if (!string.IsNullOrEmpty(this.version)) { oldVersion = PlayerSettings.bundleVersion; PlayerSettings.bundleVersion = this.version; if (config.buildTarget == BuildTarget.Android) { try { var version = new Version(this.version); if (version.Revision > 0) { PlayerSettings.bundleVersion = (version.Build == 0) ? version.ToString(2) : version.ToString(3); oldBundleVersion = PlayerSettings.Android.bundleVersionCode; PlayerSettings.Android.bundleVersionCode = version.Revision; } } catch { } } } string oldProductName = null; if (!string.IsNullOrEmpty(this.productName)) { oldProductName = PlayerSettings.productName; PlayerSettings.productName = this.productName; } config.bundleIdentifier = PlayerSettings.bundleIdentifier; config.version = PlayerSettings.bundleVersion; config.productName = PlayerSettings.productName; var buildTargetGroup = BuilderWindow.GetBuildTargetGroup(config.buildTarget); string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, ""); foreach (var m in config.modules) { m.OnBeforeBuild(config); } foreach (var m in config.modules) { m.OnBuild(config); } if (!string.IsNullOrEmpty(config.bundleIdentifier) && config.bundleIdentifier != PlayerSettings.bundleIdentifier) { if (oldBundleIdentifier == null) { oldBundleIdentifier = PlayerSettings.bundleIdentifier; } PlayerSettings.bundleIdentifier = config.bundleIdentifier; } // complex android version patch if (config.buildTarget == BuildTarget.Android) { bool updateVersion = !string.IsNullOrEmpty(config.version); Version newVersion = null; if (updateVersion) { try { newVersion = new Version(config.version); } catch { updateVersion = false; } } if (updateVersion) { try { if (!string.IsNullOrEmpty(PlayerSettings.bundleVersion)) { var oldV = new Version(PlayerSettings.bundleVersion); oldV = new Version(oldV.Major, oldV.Minor, oldV.Build, PlayerSettings.Android.bundleVersionCode); if (newVersion == oldV) { updateVersion = false; } } } catch { } } if (updateVersion) { if (oldVersion == null) { oldVersion = PlayerSettings.bundleVersion; } if (newVersion.Revision > 0) { PlayerSettings.bundleVersion = (newVersion.Build == 0) ? newVersion.ToString(2) : newVersion.ToString(3); if (oldBundleVersion == 0) { oldBundleVersion = PlayerSettings.Android.bundleVersionCode; } PlayerSettings.Android.bundleVersionCode = newVersion.Revision; } else { PlayerSettings.bundleVersion = newVersion.ToString(); } } } else { if (!string.IsNullOrEmpty(config.version) && config.version != PlayerSettings.bundleVersion) { if (oldVersion == null) { oldVersion = PlayerSettings.bundleVersion; } PlayerSettings.bundleVersion = config.version; } } if (!string.IsNullOrEmpty(config.productName) && config.productName != PlayerSettings.productName) { if (oldProductName == null) { oldProductName = PlayerSettings.productName; } PlayerSettings.productName = config.productName; } var dir = Path.GetDirectoryName(config.buildPath); if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } AssetDatabase.SaveAssets(); string obbDir = null; string newObbName = null; string oldDigest = null; try { if (config.buildTarget == BuildTarget.Android && (config.buildOptions & BuildOptions.AcceptExternalModificationsToPlayer) != 0) { var assetsDir = Path.Combine(config.buildPath, PlayerSettings.productName + "/assets"); if (Directory.Exists(assetsDir)) { Directory.Delete(assetsDir, true); } } var packagesState = new BuilderPackagesState(); try { packagesState.Configure(config.includedPackages); int errors = packagesState.Apply(config); AssetDatabase.SaveAssets(); if (errors > 0) { config.error = "Package exclusion completed with errors. See build log for details"; config.Log(config.error); Debug.LogError(config.error); hasErrors = true; } if (!hasErrors) { string error = BuildPipeline.BuildPlayer(config.scenes.ToArray(), config.buildPath, config.buildTarget, config.buildOptions); if (!string.IsNullOrEmpty(error)) { config.error = error; config.Log(error); hasErrors = true; } } } finally { try { packagesState.Recover(config); } catch { } AssetDatabase.SaveAssets(); } if (!hasErrors && config.buildTarget == BuildTarget.Android && (config.buildOptions & BuildOptions.AcceptExternalModificationsToPlayer) != 0 && PlayerSettings.Android.useAPKExpansionFiles) { try { EditorUtility.DisplayProgressBar("Extracting OBB", "", 0.0f); var expFile = Path.Combine(config.buildPath, config.productName + ".main.obb"); if (File.Exists(expFile)) { obbDir = Path.Combine(config.buildPath, config.productName + ".main"); newObbName = Path.Combine(config.buildPath, "main." + PlayerSettings.Android.bundleVersionCode + "." + PlayerSettings.bundleIdentifier + ".obb"); if (Directory.Exists(obbDir)) { Directory.Delete(obbDir, true); } int count; using (var zipFileStream = File.OpenRead(expFile)) using (var zipStream = new ZipInputStream(zipFileStream)) { count = this.CountZipEntries(zipStream); } using (var zipFileStream = File.OpenRead(expFile)) using (var zipStream = new ZipInputStream(zipFileStream)) { this.UncompressFolder(obbDir, zipStream, count); } oldDigest = BuilderUtilities.CalculateObbDigest(expFile); } } finally { EditorUtility.ClearProgressBar(); } } } catch (Exception ex) { config.error = ex.Message; config.LogException(ex); hasErrors = true; Debug.LogException(ex); } if (!hasErrors) { try { foreach (var m in config.modules) { m.OnAfterBuild(config); } } catch (Exception ex) { config.error = ex.Message; config.LogException(ex); hasErrors = true; Debug.LogException(ex); } } if (obbDir != null) { try { EditorUtility.DisplayProgressBar("Compressing OBB", "", 0.0f); var fileName = obbDir + ".zip"; if (File.Exists(fileName)) { File.Delete(fileName); } using (var zipFile = File.Create(fileName)) using (var zip = new ZipOutputStream(zipFile)) { zip.IsStreamOwner = true; zip.SetLevel(6); int counter = 0; this.CompressFolder(obbDir, zip, obbDir.Length + 1, Directory.GetFiles(obbDir, "*.*", SearchOption.AllDirectories).Length, ref counter); } Directory.Delete(obbDir, true); var obbName = obbDir + ".obb"; if (File.Exists(obbName)) { File.Delete(obbName); } if (File.Exists(newObbName)) { File.Delete(newObbName); } File.Move(fileName, newObbName); var settingsPath = Path.Combine(config.buildPath, config.productName + "/assets/bin/Data/settings.xml"); if (File.Exists(settingsPath)) { string digest = BuilderUtilities.CalculateObbDigest(newObbName); var doc = XDocument.Load(settingsPath); doc.Root.Elements("bool").Where(x => x.Attribute("name").Value == oldDigest).Remove(); doc.Root.Add(new XElement("bool", "True", new XAttribute("name", digest))); doc.Save(settingsPath); } } catch (Exception ex) { config.error = ex.Message; config.LogException(ex); hasErrors = true; Debug.LogException(ex); } finally { EditorUtility.ClearProgressBar(); } } if (!hasErrors) { try { foreach (var m in config.modules) { m.OnFinishBuild(config); } } catch (Exception ex) { config.error = ex.Message; config.LogException(ex); hasErrors = true; Debug.LogException(ex); } } for (int i = config.modules.Count - 1; i >= 0; i--) { try { config.modules[i].OnCleanupBuild(config); } catch (Exception ex) { hasErrors = true; config.LogException(ex); Debug.LogException(ex); } } PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines); if (oldProductName != null) { PlayerSettings.productName = oldProductName; } if (oldVersion != null) { PlayerSettings.bundleVersion = oldVersion; } if (oldBundleVersion != 0) { PlayerSettings.Android.bundleVersionCode = oldBundleVersion; } if (oldBundleIdentifier != null) { PlayerSettings.bundleIdentifier = oldBundleIdentifier; } config.Log("Build is finished"); } AssetDatabase.SaveAssets(); if (!hasErrors) { Debug.Log(string.Format("Building '{0}' is successfuly completed!", this.name)); } else { Debug.LogWarning(string.Format("Building '{0}' is completed with errors!!!", this.name)); } EditorApplication.UnlockReloadAssemblies(); }