예제 #1
0
        private void XcodeBuild()
        {
            string workPath = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag));

            message = errorMessage = "";
            Module.DisplayProgressBar("Start Xcode Build...", 0, true);
            using (var xcodeBuildLogWriter = new StreamWriter(Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, "XcodeBuild.log"))
            {
                AutoFlush = true
            })
            {
                Process p = SVNUpdate.Runner.ExcuteCommand("/bin/bash",
                                                           EBPUtility.Quote(Path.Combine(Module.ModuleConfig.ModuleRootPath, "Shells/XcodeBuild.sh")) + " " +
                                                           EBPUtility.Quote(workPath) + " " +
                                                           EBPUtility.Quote("Project/Unity-iPhone.xcodeproj"),
                                                           (object sender, DataReceivedEventArgs e) =>
                {
                    message = e.Data;
                    xcodeBuildLogWriter.WriteLine(message);
                },
                                                           OnErrorReceived, null);
                int progress = 0;
                while (!p.HasExited)
                {
                    Module.DisplayProgressBar("Xcode Building...", message, (float)(progress++ % 1000) / 1000);
                    System.Threading.Thread.Sleep(100);
                }
                if (p.ExitCode != 0)
                {
                    throw new EBPException("XcodeBuild Shell Error: " + errorMessage);
                }
            }
            Module.DisplayProgressBar("Xcode Build", "Finish!", 1, true);
        }
예제 #2
0
        private void CreateIPAExportOptionsPlist()
        {
            var           ios   = Module.UserConfig.Json.PlayerSettings.IOS;
            var           eo    = ios.IPAExportOptions;
            PlistDocument plist = new PlistDocument();

            plist.root = new PlistElementDict();
            plist.root.SetBoolean("compileBitcode", eo.CompileBitcode);
            plist.root.SetString("destination", eo.Destination);
            plist.root.SetString("method", eo.Method);
            var provisioningProfiles = plist.root.CreateDict("provisioningProfiles");

            provisioningProfiles.SetString(ios.BundleID, ios.ProfileID);
            plist.root.SetString("signingCertificate", eo.SigningCertificate);
            plist.root.SetString("signingStyle", eo.SigningStyle);
            plist.root.SetBoolean("stripSwiftSymbols", eo.StripSwiftSymbols);
            plist.root.SetString("teamID", ios.TeamID);
            plist.root.SetString("thinning", eo.Thinning);

            string tagsPath      = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag));
            string ipaFolderPath = Path.Combine(tagsPath, "IPA");

            Directory.CreateDirectory(ipaFolderPath);
            plist.WriteToFile(Path.Combine(ipaFolderPath, "ExportOptions.plist"));
        }
예제 #3
0
 private void LoadAllModulesUserConfigList()
 {
     assetPreprocessorUserConfigNames = EBPUtility.FindFilesRelativePathWithoutExtension(G.Module.AssetPreprocessorModule.ModuleConfig.UserConfigsFolderPath);
     bundleManagerUserConfigNames     = EBPUtility.FindFilesRelativePathWithoutExtension(G.Module.BundleManagerModule.ModuleConfig.UserConfigsFolderPath);
     packageManagerUserConfigNames    = EBPUtility.FindFilesRelativePathWithoutExtension(G.Module.PackageManagerModule.ModuleConfig.UserConfigsFolderPath);
     userConfigNames = EBPUtility.FindFilesRelativePathWithoutExtension(G.Module.PlayerBuilderModule.ModuleConfig.UserConfigsFolderPath);
 }
예제 #4
0
        protected override void RunProcess()
        {
            //清理无用Bundle项
            List <AssetBundleBuild> cleanedBuilds = null;

            if (Module.ModuleStateConfig.Json.CleanUpBundles)
            {
                Module.DisplayProgressBar("开始清理无用Bundle项", 0, true);
                AssetPolice.Editor.Module policeModule = new AssetPolice.Editor.Module();
                AssetPolice.Editor.Runner policeRunner = new AssetPolice.Editor.Runner(policeModule);
                policeModule.LoadConfigs();
                policeModule.ModuleConfig.Json.OutputPath = CommonModule.CommonConfig.CurrentLogFolderPath; //Hack: 由于输出目录必须存在,所以临时这样设置
                policeRunner.Run();
                cleanedBuilds = policeRunner.GetCleanedBuilds(Module.UserConfig.Json, CommonModule.CommonConfig.CurrentLogFolderPath);
            }
            else
            {
                cleanedBuilds = Module.UserConfig.Json;
            }

            //准备参数
            BuildTarget target          = (BuildTarget)Enum.Parse(typeof(BuildTarget), Module.ModuleStateConfig.Json.CurrentTag[0], true);
            int         optionsValue    = Module.ModuleStateConfig.Json.CurrentBuildAssetBundleOptionsValue;
            int         resourceVersion = Module.ModuleStateConfig.Json.ResourceVersion;
            string      tagPath         = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag));

            //创建目录
            Module.DisplayProgressBar("正在重建目录:" + tagPath, 0.3f, true);
            if (Directory.Exists(tagPath))
            {
                Directory.Delete(tagPath, true); //清空目录
            }
            string infoPath    = Path.Combine(tagPath, "_Info");
            string bundlesPath = Path.Combine(tagPath, "Bundles");

            Directory.CreateDirectory(infoPath);
            Directory.CreateDirectory(bundlesPath);

            //创建json文件
            Module.DisplayProgressBar("Creating Info Files...", 0.45f, true);
            File.WriteAllText(Path.Combine(infoPath, "BuildMap.json"), JsonConvert.SerializeObject(cleanedBuilds, Formatting.Indented));
            File.WriteAllText(Path.Combine(infoPath, "Versions.json"), JsonConvert.SerializeObject(new Dictionary <string, int> {
                { "ResourceVersion", resourceVersion }
            }, Formatting.Indented));
            //创建Map文件
            //此处保留旧map文件的生成方式
            AssetBundleManagement.ABExtractItemBuilder.BuildMapperFile(AssetBundleManagement.ABExtractItemBuilder.BuildAssetMapper(cleanedBuilds.ToArray()), Path.Combine(infoPath, "map"));

            //创建Bundles
            Module.DisplayProgressBar("Start Build AssetBundles...", 0.5f, true);
            var manifest = BuildPipeline.BuildAssetBundles(bundlesPath, cleanedBuilds.ToArray(), (BuildAssetBundleOptions)optionsValue, target);

            if (manifest == null)
            {
                throw new EBPException("BuildAssetBundles失败!详情请查看Console面板。");
            }
            //重命名Bundles清单文件
            Module.DisplayProgressBar("Renaming assetbundlemanifest...", 1f, true);
            RenameMainBundleManifest(bundlesPath);
        }
예제 #5
0
        void GetRepositoryInfoAndLocalVersion()
        {
            const string urlName     = "URL: ";
            const string versionName = "Revision: ";

            foreach (var line in SVNInfo.Split('\n'))
            {
                //获取仓库信息
                if (line.Length > urlName.Length &&
                    line.Substring(0, urlName.Length) == urlName)
                {
                    string repositoryURL = line.Substring(urlName.Length);
                    try
                    {
                        ExcuteCommand("svn", "info " + EBPUtility.Quote(repositoryURL), OnRepositoryInfoReceived, OnInfoErrorReceived, OnRepositoryInfoExited);
                    }
                    catch (Exception err)
                    {
                        InfoErrorMessage = err.Message;
                        InfoExitedAction(false);
                    }
                }
                //获取本地版本
                else if (line.Length > versionName.Length &&
                         line.Substring(0, versionName.Length) == versionName)
                {
                    LocalVersion = line.Substring(versionName.Length);
                }
            }
        }
예제 #6
0
        protected override void PreProcess()
        {
            Module.DisplayProgressBar("Clear Wrap Files...", 0, true);
            ToLuaMenu.ClearLuaWraps();
            Module.DisplayProgressBar("Clear Lua Files...", 0.2f, true);
            LuaScriptsPreProcessor.Clean();

            EBPUtility.RefreshAssets();
        }
예제 #7
0
        protected override void PreProcess()
        {
            EBPUtility.RefreshAssets();

            Module.DisplayProgressBar("-- Start Handle Lua Files --", 0f, true);
            HandleLuaFiles(0f, 1f);
            Module.DisplayProgressBar("-- End Handle Lua Files --", 1f, true);

            EBPUtility.RefreshAssets();
        }
예제 #8
0
        public void Prepare()
        {
            try
            {
                Module.StartLog();
                Module.LogHead("Start Prepare", 1);

                Module.DisplayProgressBar("Clear Lua Wraps", 0, true);
                ToLuaMenu.ClearLuaWraps();

                EBPUtility.RefreshAssets();

                Module.DisplayProgressBar("Preparing BuildOptions", 0.2f, true);
                PrepareBuildOptions();

                Module.DisplayProgressBar("Start DownloadConfigs", 0.22f, true);
                DownLoadConfigs(0.22f, 0.5f);

                Module.DisplayProgressBar("Creating Building Configs Class File", 0.5f, true);
                CreateBuildingConfigsClassFile();

                Module.DisplayProgressBar("Applying PlayerSettings", 0.55f, true);
                ApplyPlayerSettings(BuildPlayerOptions.target);

                if (CommonModule.CommonConfig.IsBatchMode)
                {
                    Module.DisplayProgressBar("Start Copy Directories", 0.6f, true);
                    CopyAllDirectories(BuildPlayerOptions.target, Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, copyFileLogName));

                    Module.DisplayProgressBar("Applying Scripting Defines", 0.95f, true);
                    ApplyScriptDefines(BuildPlayerOptions.target);
                }
                EBPUtility.RefreshAssets();
            }
            catch (Exception e)
            {
                var state = Module.ModuleStateConfig.Json;
                state.ErrorMessage         = e.Message;
                state.DetailedErrorMessage = e.ToString();
                if (!string.IsNullOrEmpty(Module.ModuleStateConfig.JsonPath))
                {
                    Module.ModuleStateConfig.Save();
                }
                Module.Log(state.DetailedErrorMessage);
                throw new EBPException(e.Message, e);
            }
            finally
            {
                Module.LogHead("End Prepare", 1);
                Module.EndLog();
                EditorUtility.ClearProgressBar();
            }
        }
예제 #9
0
        protected override void RunProcess()
        {
            CommonModule.CommonConfig.Json.CurrentAssetTag = new string[] { "Applying" }.Concat(Module.UserConfig.Json.Tags).ToArray();
            CommonModule.CommonConfig.Save();

            //初始化两个步骤的信息集
            totalCountList = new List <int> {
                -1, -1
            };
            skipCountList = new List <int>()
            {
                -1, -1
            };
            successCountList = new List <int> {
                -1, -1
            };
            LogFilePathList = new List <string> {
                null, null
            };

            //第一步
            currentStepIndex = 0;
            string copyFileArgs = Path.Combine(Module.ModuleConfig.ShellsFolderPath, "CopyFile.sh") + " "
                                  + Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, "CopyPreAssets.log") + " Assets " + Module.ModuleConfig.PreStoredAssetsFolderPath;

            copyFileArgs += " " + Module.UserConfig.Json.CopyFileTags;
            RunShell_ShowProgress_WaitForExit(copyFileArgs, "正在从PreStoredAssets里查找文件...", "第1步(共2步) 从PreStoredAssets拷贝文件至Assets目录");
            if (process.ExitCode != 0) //第一步出错
            {
                throw new EBPException("第一步CopyFile时发生错误:" + errorMessage);
            }

            EBPUtility.RefreshAssets();

            //第二步
            currentStepIndex = 1;
            string importerLogPath = Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, "ImporterSetting.log");

            LogFilePathList[currentStepIndex] = importerLogPath;
            using (var writer = new StreamWriter(importerLogPath)
            {
                AutoFlush = true
            })
            {
                ApplyImporter(writer);
            }

            CommonModule.CommonConfig.Json.CurrentAssetTag = Module.UserConfig.Json.Tags;
            CommonModule.CommonConfig.Save();
        }
예제 #10
0
        public void Awake()
        {
            InitStyles();

            userConfigNames = EBPUtility.FindFilesRelativePathWithoutExtension(G.Module.ModuleConfig.UserConfigsFolderPath);
            string currentUserConfigName = G.Module.ModuleStateConfig.Json.CurrentUserConfigName;

            if (currentUserConfigName != null)
            {
                string extension = Path.GetExtension(currentUserConfigName);
                selectedUserConfigIndex = userConfigNames.IndexOf(currentUserConfigName.Remove(
                                                                      currentUserConfigName.Length - extension.Length, extension.Length));
            }
            //G.Module.DisplayRunError();
        }
예제 #11
0
 private void CreateNewUserConfig(string name, string path)
 {
     //新建
     if (!Directory.Exists(CommonModule.CommonConfig.UserConfigsRootPath))
     {
         G.Module.DisplayDialog("创建失败!用户配置根目录不存在:");
         return;
     }
     //保存
     Directory.CreateDirectory(Path.GetDirectoryName(path));
     G.Module.UserConfig.JsonPath = path;
     SaveUserConfig();
     //更新列表
     userConfigNames = EBPUtility.FindFilesRelativePathWithoutExtension(G.Module.ModuleConfig.UserConfigsFolderPath);
     //切换
     G.Module.IsDirty = false;
     ChangeUserConfig(userConfigNames.IndexOf(name));
     //用于总控
     G.g.OnChangeConfigList();
 }
예제 #12
0
        private void PrepareBuildOptions()
        {
            //准备BuildOptions
            BuildOptions buildOptions =
                (Module.ModuleStateConfig.Json.DevelopmentBuild ? BuildOptions.Development : BuildOptions.None) |
                (Module.ModuleStateConfig.Json.ConnectWithProfiler ? BuildOptions.ConnectWithProfiler : BuildOptions.None) |
                (Module.ModuleStateConfig.Json.AllowDebugging ? BuildOptions.AllowDebugging : BuildOptions.None) |
                (Module.UserConfig.Json.BuildSettings.CompressionMethod == UserConfig.BuildSettings.CompressionMethodEnum.LZ4 ? BuildOptions.CompressWithLz4 : BuildOptions.None) |
                (Module.UserConfig.Json.BuildSettings.CompressionMethod == UserConfig.BuildSettings.CompressionMethodEnum.LZ4HC ? BuildOptions.CompressWithLz4HC : BuildOptions.None);

            //设置路径和文件名
            string tagsPath = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag));
            string locationPath;
            string versionInfo = string.Format("{0}_{1}.{2}", PlayerSettings.productName, PlayerSettings.bundleVersion, PlayerSettings.Android.bundleVersionCode);

            switch (EditorUserBuildSettings.activeBuildTarget)
            {
            case BuildTarget.Android:
                locationPath = Path.Combine(tagsPath, versionInfo + ".apk");
                break;

            case BuildTarget.iOS:
                locationPath = Path.Combine(tagsPath, "Project");
                break;

            default:
                throw new EBPException("意外的平台:" + EditorUserBuildSettings.activeBuildTarget);
            }

            //获取场景
            string[] scenes = EditorBuildSettingsScene.GetActiveSceneList(EditorBuildSettings.scenes).Take(2).ToArray(); //Hack: 只获取头两个场景

            //构成BuildPlayerOptions
            BuildPlayerOptions = new BuildPlayerOptions
            {
                scenes           = scenes,
                locationPathName = locationPath,
                target           = EditorUserBuildSettings.activeBuildTarget,
                options          = buildOptions
            };
        }
예제 #13
0
        protected override void PostProcess()
        {
            //工程需要的后处理
            switch (BuildPlayerOptions.target)
            {
            case BuildTarget.Android:
                Module.DisplayProgressBar("Renaming OBB File...", 0, true);
                RenameOBBFileForAndroid();
                break;

            case BuildTarget.iOS:
                Module.DisplayProgressBar("Postprocessing for iOS...", 0, true);
                IOSPostProcess(BuildPlayerOptions.locationPathName);
                break;

            default:
                throw new EBPException("意外的平台:" + BuildPlayerOptions.target.ToString());
            }

            EBPUtility.RefreshAssets();
        }
예제 #14
0
        protected override void PreProcess()
        {
            EBPUtility.RefreshAssets();

            Module.DisplayProgressBar("Preparing BuildOptions", 0, true);
            PrepareBuildOptions();

            Module.DisplayProgressBar("-- Start Handle Wrap Files --", 0f, true);
            HandleWrapFiles(0f, 1f);
            Module.DisplayProgressBar("-- End Handle Wrap Files --", 1f, true);

            Module.DisplayProgressBar("Applying PostProcess Settings", 1f, true);
            ApplyPostProcessSettings();

            //为了防止第二次启动Unity后部分设置自动消失(如Android的Keystore配置)
            Module.DisplayProgressBar("Applying PlayerSettings", 1f, true);
            ApplyPlayerSettings(BuildPlayerOptions.target);

            EBPUtility.RefreshAssets();

            iOSBuildPostProcessor.DisableOnce = true; //HACK: 关闭一次旧的后处理过程
        }
예제 #15
0
        protected override void RunProcess()
        {
            int progress = 0;

            message      = "";
            errorMessage = "";
            Module.DisplayProgressBar("SVN Update Starting...", 0, true);
            Process p;

            p = ExcuteCommand("/bin/bash", EBPUtility.Quote(Path.Combine(Module.ModuleConfig.ModuleRootPath, "SVNUpdate.sh")) + " "
                              + EBPUtility.Quote(Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, "SVNUpdate.log")),
                              OnReceived, OnErrorReceived, OnExited);
            while (!p.HasExited)
            {
                Module.DisplayProgressBar("SVN Updating...", message, (float)(progress++ % 1000) / 1000);
                System.Threading.Thread.Sleep(50);
            }
            if (p.ExitCode != 0)
            {
                throw new EBPException("SVN Update Error: " + errorMessage);
            }
            Module.DisplayProgressBar("SVN", "Finish!", 1, true);
        }
예제 #16
0
        protected override void Finally()
        {
            iOSBuildPostProcessor.DisableOnce = false;

            if (CommonModule.CommonConfig.IsBatchMode)
            {
                //还原宏定义
                Module.DisplayProgressBar("Revert Scripting Defines", 0f, true);
                ApplyScriptDefines(EditorUserBuildSettings.activeBuildTarget, true);

                //还原被拷贝覆盖的文件
                Module.DisplayProgressBar("Revert Copied Files", 0f, true);
                string copyFileLogPath = Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, copyFileLogName);
                if (File.Exists(copyFileLogPath))
                {
                    RevertAllCopiedFiles(File.ReadAllLines(copyFileLogPath), Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, "RevertFiles.log"));
                }

                //清除Wrap
                ToLuaMenu.ClearLuaWraps();
            }

            EBPUtility.RefreshAssets();
        }
예제 #17
0
        void OnRepositoryInfoExited(object sender, EventArgs e)
        {
            Process process = (Process)sender;

            Available = process.ExitCode == 0;
            if (Available)
            {
                //设置版本状态
                if (LocalVersion != "" && RepositoryVersion != "")
                {
                    VersionState = RepositoryVersion == LocalVersion ? VersionStateEnum.Latest : VersionStateEnum.Obsolete;
                }
                //检查本地修改
                if (Module.ModuleConfig.Json.EnableCheckDiff)
                {
                    try
                    {
                        ExcuteCommand("/bin/bash", EBPUtility.Quote(Path.Combine(Module.ModuleConfig.ModuleRootPath, "SVNDiff.sh")),
                                      OnDiffReceived, OnDiffErrorReceived, OnDiffExited);
                    }
                    catch (Exception err)
                    {
                        InfoErrorMessage = err.Message;
                        DiffExitedAction(false);
                    }
                }
            }
            else
            {
                IsPartOfPipeline = false;
            }
            if (InfoExitedAction != null)
            {
                InfoExitedAction(Available);
            }
        }
예제 #18
0
 private void LoadConfigsList()
 {
     BundleConfigNames = EBPUtility.FindFilesRelativePathWithoutExtension(CommonModule.CommonConfig.UserConfigsFolderPath_BundleManager);
     userConfigNames   = EBPUtility.FindFilesRelativePathWithoutExtension(G.Module.ModuleConfig.UserConfigsFolderPath);
 }
예제 #19
0
        private void ClickedApply()
        {
            G.Module.UserConfig.Json.Packages = GetPackageMap(); //从配置现场覆盖当前map
            try
            {
                CommonModule.ClearLogFolderPath();
                G.Runner.Check();
            }
            catch (EBPCheckFailedException e)
            {
                G.Module.DisplayDialog(e.Message);
                return;
            }
            if (!CheckAllPackageItem())
            {
                return;
            }

            bool ensure = G.Module.DisplayDialog("确定应用当前配置?", "确定", "取消");

            if (ensure)
            {
                try
                {
                    G.Module.DisplayProgressBar("Build Packages", "Starting...", 0);
                    double startTime = EditorApplication.timeSinceStartup;

                    CommonModule.GenerateLogFolderPath();
                    G.Runner.Run();

                    TimeSpan time = TimeSpan.FromSeconds(EditorApplication.timeSinceStartup - startTime);
                    if (G.Module.DisplayDialog("打包完成!用时:" + string.Format("{0}时 {1}分 {2}秒", time.Hours, time.Minutes, time.Seconds),
                                               "显示文件", "关闭"))
                    {
                        string firstPackagePath = Path.Combine(G.Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(G.Module.ModuleStateConfig.Json.CurrentTag));
                        EditorUtility.RevealInFinder(firstPackagePath);
                    }
                }
                catch
                {
                    G.Module.DisplayRunError();
                }
            }
        }
예제 #20
0
 public string GetBundleInfoFolderPath()
 {
     return(Path.Combine(ModuleConfig.BundleWorkFolderPath, EBPUtility.GetTagStr(ModuleStateConfig.Json.CurrentTag) + "/_Info"));
 }
예제 #21
0
        public void OnGUI()
        {
            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

            if (creatingNewConfig == true && GUI.GetNameOfFocusedControl() != "InputField1")
            {
                creatingNewConfig = false;
            }
            //Root
            GUILayout.FlexibleSpace();
            EBPEditorGUILayout.RootSettingLine(PlayerBuilder.G.Module, ChangeRootPath);
            GUILayout.FlexibleSpace();

            //SVN Update
            EditorGUILayout.BeginHorizontal();
            FrontIndicator(currentStep == Step.SVNUpdate, false, G.Module.SVNUpdateRunner.errorMessage);
            G.Module.SVNUpdateRunner.IsPartOfPipeline = GUILayout.Toggle(G.Module.SVNUpdateRunner.IsPartOfPipeline, "SVN Update", GUILayout.Width(200)) && G.Module.SVNUpdateRunner.Available;
            SVNInfo();
            if (GUILayout.Button(refreshIcon, miniButtonOptions))
            {
                RunSVNCheckProcess();
            }
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            GUILayout.FlexibleSpace();

            //AssetPreprocessor
            EditorGUILayout.BeginHorizontal();
            FrontIndicator(currentStep == Step.PreprocessAssets, G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.Applying,
                           G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.ErrorMessage);
            G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.IsPartOfPipeline = EditorGUILayout.BeginToggleGroup(
                assetPreprocessorContent, G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.IsPartOfPipeline);

            EditorGUILayout.BeginHorizontal();
            int index_new = EditorGUILayout.Popup(assetPreprocessorUserConfigSelectedIndex, assetPreprocessorUserConfigNames, dropdownOptions);

            if (assetPreprocessorUserConfigSelectedIndex != index_new)
            {
                assetPreprocessorUserConfigSelectedIndex = index_new;
                G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.CurrentUserConfigName = assetPreprocessorUserConfigNames[index_new] + ".json";
                G.Module.AssetPreprocessorModule.LoadUserConfig();
                return;
            }
            if (GUILayout.Button(settingGUIContent, miniButtonOptions))
            {
                AssetPreprocessor.G.OverrideCurrentUserConfigName = G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.CurrentUserConfigName;
                if (AssetPreprocessor.G.g == null)
                {
                    EditorWindow.GetWindow <AssetPreprocessor.Editor.AssetPreprocessorWindow>();
                    AssetPreprocessor.G.g.OnChangeCurrentUserConfig += Action_AssetPreprocessor_OnChangeCurrentConfig;
                    AssetPreprocessor.G.g.OnChangeConfigList        += Action_OnChangeConfigList;
                }
                else
                {
                    EditorWindow.GetWindow <AssetPreprocessor.Editor.AssetPreprocessorWindow>();
                }
                return;
            }
            GUILayout.Space(10);
            GUILayout.Label(G.Module.AssetPreprocessorModule.ModuleStateConfig.Json.IsPartOfPipeline ?
                            "<color=orange>→  " + EBPUtility.GetTagStr(G.Module.AssetPreprocessorModule.UserConfig.Json.Tags) + "</color>" :
                            "<color=cyan>" + EBPUtility.GetTagStr(CommonModule.CommonConfig.Json.CurrentAssetTag) + "</color>", richTextLabel);
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndToggleGroup();
            EditorGUILayout.EndHorizontal();

            GUILayout.FlexibleSpace();

            //BundleManager
            EditorGUILayout.BeginHorizontal();
            FrontIndicator(currentStep == Step.BuildBundles, G.Module.BundleManagerModule.ModuleStateConfig.Json.Applying,
                           G.Module.BundleManagerModule.ModuleStateConfig.Json.ErrorMessage);
            G.Module.BundleManagerModule.ModuleStateConfig.Json.IsPartOfPipeline = EditorGUILayout.BeginToggleGroup(
                bundleManagerContent, G.Module.BundleManagerModule.ModuleStateConfig.Json.IsPartOfPipeline);
            EditorGUILayout.BeginHorizontal();

            index_new = EditorGUILayout.Popup(bundleManagerUserConfigSelectedIndex, bundleManagerUserConfigNames, dropdownOptions);
            if (bundleManagerUserConfigSelectedIndex != index_new)
            {
                bundleManagerUserConfigSelectedIndex = index_new;
                G.Module.BundleManagerModule.ModuleStateConfig.Json.CurrentUserConfigName = bundleManagerUserConfigNames[index_new] + ".json";
                return;
            }
            if (GUILayout.Button(settingGUIContent, miniButtonOptions))
            {
                if (BundleManager.G.g == null)
                {
                    EditorWindow.GetWindow <BundleManager.Editor.BundleManagerWindow>();
                    BundleManager.G.g.OnChangeConfigList += Action_OnChangeConfigList;
                }
                else
                {
                    EditorWindow.GetWindow <BundleManager.Editor.BundleManagerWindow>();
                }
                return;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndToggleGroup();

            GUILayout.Space(10);
            EditorGUILayout.LabelField("Resource Version:", labelOptions);
            int n = EditorGUILayout.IntField(G.Module.BundleManagerModule.ModuleStateConfig.Json.ResourceVersion, inputOptions);

            if (G.Module.BundleManagerModule.ModuleStateConfig.Json.ResourceVersion != n)
            {
                G.Module.BundleManagerModule.ModuleStateConfig.Json.ResourceVersion = n;
            }

            int selectedCompressionIndex_new = EditorGUILayout.Popup(selectedCompressionIndex, G.Module.BundleManagerModule.CompressionEnum, dropdownOptions2);

            if (selectedCompressionIndex_new != selectedCompressionIndex)
            {
                G.Module.BundleManagerModule.ModuleStateConfig.Json.CompressionOption = G.Module.BundleManagerModule.CompressionEnumMap[G.Module.BundleManagerModule.CompressionEnum[selectedCompressionIndex_new]];
                selectedCompressionIndex = selectedCompressionIndex_new;
                return;
            }

            G.Module.BundleManagerModule.ModuleStateConfig.Json.CleanUpBundles = GUILayout.Toggle(G.Module.BundleManagerModule.ModuleStateConfig.Json.CleanUpBundles, "CleanUp");

            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            GUILayout.FlexibleSpace();

            //PackageManager
            EditorGUILayout.BeginHorizontal();
            FrontIndicator(currentStep == Step.BuildPackages, G.Module.PackageManagerModule.ModuleStateConfig.Json.Applying,
                           G.Module.PackageManagerModule.ModuleStateConfig.Json.ErrorMessage);
            G.Module.PackageManagerModule.ModuleStateConfig.Json.IsPartOfPipeline = EditorGUILayout.BeginToggleGroup(
                packageManagerContent, G.Module.PackageManagerModule.ModuleStateConfig.Json.IsPartOfPipeline);
            EditorGUILayout.BeginHorizontal();

            index_new = EditorGUILayout.Popup(packageManagerUserConfigSelectedIndex, packageManagerUserConfigNames, dropdownOptions);
            if (packageManagerUserConfigSelectedIndex != index_new)
            {
                packageManagerUserConfigSelectedIndex = index_new;
                G.Module.PackageManagerModule.ModuleStateConfig.Json.CurrentUserConfigName = packageManagerUserConfigNames[index_new] + ".json";
                return;
            }
            if (GUILayout.Button(settingGUIContent, miniButtonOptions))
            {
                PackageManager.G.OverrideCurrentUserConfigName = G.Module.PackageManagerModule.ModuleStateConfig.Json.CurrentUserConfigName;
                if (PackageManager.G.g == null)
                {
                    EditorWindow.GetWindow <PackageManager.Editor.PackageManagerWindow>();
                    PackageManager.G.g.OnChangeConfigList += Action_OnChangeConfigList;
                }
                else
                {
                    EditorWindow.GetWindow <PackageManager.Editor.PackageManagerWindow>();
                }
                return;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndToggleGroup();

            GUILayout.Space(10);
            EditorGUILayout.LabelField("Client Version:", labelOptions);
            string packageVersion_new = EditorGUILayout.TextField(G.Module.PackageManagerModule.ModuleStateConfig.Json.ClientVersion, inputOptions);

            if (G.Module.PackageManagerModule.ModuleStateConfig.Json.ClientVersion != packageVersion_new)
            {
                G.Module.PackageManagerModule.ModuleStateConfig.Json.ClientVersion = packageVersion_new;
            }
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            GUILayout.FlexibleSpace();

            //BuildPlayer
            EditorGUILayout.BeginHorizontal();
            FrontIndicator(currentStep == Step.BuildPlayer || currentStep == Step.Prepare, G.Module.PlayerBuilderModule.ModuleStateConfig.Json.Applying,
                           G.Module.PlayerBuilderModule.ModuleStateConfig.Json.ErrorMessage);
            G.Module.PlayerBuilderModule.ModuleStateConfig.Json.IsPartOfPipeline = EditorGUILayout.BeginToggleGroup(
                playerBuilderContent, G.Module.PlayerBuilderModule.ModuleStateConfig.Json.IsPartOfPipeline);
            EditorGUILayout.BeginHorizontal();
            if (creatingNewConfig)
            {
                ShowInputField();
            }
            else
            {
                if (ShowBuildSettingDropdown())
                {
                    return;
                }
            }
            if (GUILayout.Button(new GUIContent(EditorGUIUtility.FindTexture("ViewToolOrbit"), "查看该文件"), miniButtonOptions))
            {
                ClickedShowConfigFile(); return;
            }
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndToggleGroup();
            GUILayout.Space(10);
            EditorGUILayout.LabelField("Build Number:", labelOptions);
            int buildNum = EditorGUILayout.IntField(G.Module.PlayerBuilderModule.ModuleStateConfig.Json.BuildNumber, inputOptions);

            if (G.Module.PlayerBuilderModule.ModuleStateConfig.Json.BuildNumber != buildNum)
            {
                G.Module.PlayerBuilderModule.ModuleStateConfig.Json.BuildNumber = buildNum;
            }
            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();
            GUILayout.FlexibleSpace();

            EditorGUILayout.BeginHorizontal();
            GUILayout.Space(30);
            if (GUILayout.Button(new GUIContent("New", "新建配置文件"), buttonOptions))
            {
                ClickedNew(); return;
            }
            if (GUILayout.Button(new GUIContent("Save", "保存配置文件"), buttonOptions))
            {
                ClickedSave(); return;
            }
            if (GUILayout.Button(new GUIContent("Revert", "重新载入配置文件"), buttonOptions))
            {
                ClickedRevert(); return;
            }
            if (GUILayout.Button(new GUIContent("Apply", "应用下面的PlayerSettings(不包括宏定义)"), buttonOptions))
            {
                ClickedApply(); return;
            }
            if (GUILayout.Button(new GUIContent("Fetch", "获取当前的PlayerSettings"), buttonOptions))
            {
                FetchSettings(); return;
            }
            if (GUILayout.Button(new GUIContent("CopyDir", "自动拷贝目录并设置宏定义"), buttonOptions))
            {
                if (PlayerBuilder.Editor.PlayerSettingsPanel.CopyNow(EditorUserBuildSettings.activeBuildTarget))
                {
                    G.Module.PlayerBuilderRunner.ApplyScriptDefines(EditorUserBuildSettings.activeBuildTarget);
                    ToLuaMenu.ClearLuaWraps();
                }
                return;
            }
            if (GUILayout.Button(new GUIContent("RevertDir", "自动恢复拷贝目录并恢复宏定义"), buttonOptions))
            {
                if (PlayerBuilder.Editor.PlayerSettingsPanel.RevertNow())
                {
                    G.Module.PlayerBuilderRunner.ApplyScriptDefines(EditorUserBuildSettings.activeBuildTarget, true);
                    ToLuaMenu.ClearLuaWraps();
                }
                return;
            }
            GUILayout.FlexibleSpace();

            //Run Button
            Color defaultColor = GUI.contentColor;

            GUI.contentColor = Color.green;
            if (PlayerBuilder.G.Module.StateConfigAvailable)
            {
                if (GUILayout.Button(new GUIContent("Run Pipeline")))
                {
                    ClickedRunPipeline(); return;
                }
            }
            else
            {
                if (GUILayout.Button(new GUIContent("Check", "检查所有勾选的模块配置")))
                {
                    ClickedCheckAll(); return;
                }
            }
            GUI.contentColor = defaultColor;
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.EndScrollView();
        }
예제 #22
0
        private void ClickedApply()
        {
            G.Module.ModuleStateConfig.Json.CurrentUserConfigName = Path.GetFileName(AssetBundleManagement2.AssetBundleModel.BuildMapPath) + ".json"; //TODO: 覆盖当前map文件名,BundleMaster的特殊处理
            G.Module.UserConfig.Json = G.g.mainTab.GetBuildMap_extension().ToList();                                                                  //从配置现场覆盖当前map
            try
            {
                CommonModule.ClearLogFolderPath();
                G.Runner.Check();
            }
            catch (EBPCheckFailedException e)
            {
                G.Module.DisplayDialog(e.Message);
                return;
            }
            //确认信息
            BuildTarget target          = (BuildTarget)Enum.Parse(typeof(BuildTarget), G.Module.ModuleStateConfig.Json.CurrentTag[0], true);
            int         optionsValue    = G.Module.ModuleStateConfig.Json.CurrentBuildAssetBundleOptionsValue;
            int         resourceVersion = G.Module.ModuleStateConfig.Json.ResourceVersion;
            string      tagPath         = Path.Combine(G.Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(G.Module.ModuleStateConfig.Json.CurrentTag));

            bool ensure = G.Module.DisplayDialog(string.Format("确定应用当前配置?\n\n" +
                                                               "目标平台: {0}\n 输出路径: {1} \n Resources Version: {2} \n 参数: {3}",
                                                               target, tagPath, resourceVersion, optionsValue), "确定", "取消");

            //开始应用
            if (ensure)
            {
                try
                {
                    CommonModule.GenerateLogFolderPath();
                    G.Runner.Run();
                    G.Module.DisplayDialog("创建AssetBundles成功!");
                }
                catch
                {
                    G.Module.DisplayRunError();
                }
            }
        }
예제 #23
0
 protected override void PostProcess()
 {
     EBPUtility.RefreshAssets();
 }
예제 #24
0
        public void CopyAllDirectories(BuildTarget buildTarget, string logPath)
        {
            string directoryRegexStr = CommonModule.CommonConfig.Json.DirectoryRegex;
            string fileRegexStr      = CommonModule.CommonConfig.Json.FileRegex;
            List <UserConfig.PlayerSettings.CopyItem> copyList;

            switch (buildTarget)
            {
            case BuildTarget.Android:
                string directoryRegexStr_Android = Module.UserConfig.Json.PlayerSettings.Android.CopyDirectoryRegex;
                string fileRegexStr_Android      = Module.UserConfig.Json.PlayerSettings.Android.CopyFileRegex;
                if (!string.IsNullOrEmpty(directoryRegexStr_Android))
                {
                    directoryRegexStr = directoryRegexStr_Android;
                }
                if (!string.IsNullOrEmpty(fileRegexStr_Android))
                {
                    fileRegexStr = fileRegexStr_Android;
                }
                copyList = Module.UserConfig.Json.PlayerSettings.Android.CopyList;
                break;

            case BuildTarget.iOS:
                string directoryRegexStr_IOS = Module.UserConfig.Json.PlayerSettings.IOS.CopyDirectoryRegex;
                string fileRegexStr_IOS      = Module.UserConfig.Json.PlayerSettings.IOS.CopyFileRegex;
                if (!string.IsNullOrEmpty(directoryRegexStr_IOS))
                {
                    directoryRegexStr = directoryRegexStr_IOS;
                }
                if (!string.IsNullOrEmpty(fileRegexStr_IOS))
                {
                    fileRegexStr = fileRegexStr_IOS;
                }
                copyList = Module.UserConfig.Json.PlayerSettings.IOS.CopyList;
                break;

            default:
                throw new EBPException("意外的平台:" + BuildPlayerOptions.target.ToString());
            }

            Regex directoryRegex = string.IsNullOrEmpty(directoryRegexStr) ? null : new Regex(directoryRegexStr);
            Regex fileRegex      = string.IsNullOrEmpty(fileRegexStr) ? null : new Regex(fileRegexStr);

            using (var copyFileLogWriter = new StreamWriter(logPath)
            {
                AutoFlush = true
            })
            {
                for (int i = 0; i < copyList.Count; i++)
                {
                    if (!copyList[i].Active)
                    {
                        continue;
                    }
                    Module.DisplayProgressBar(string.Format("Copy Directory... ({0}/{1})", i + 1, copyList.Count), copyList[i].SourcePath + " -> " + copyList[i].TargetPath, 0.5f, true);
                    copyFileLogWriter.WriteLine((copyList[i].Revert ? "R " : "D ") + copyList[i].TargetPath);
                    EBPUtility.CopyDirectory(copyList[i].SourcePath, copyList[i].TargetPath, copyList[i].CopyMode, directoryRegex, fileRegex,
                                             (targetPath) =>
                    {
                        copyFileLogWriter.WriteLine("  " + targetPath);
                    });
                }
            }
            EBPUtility.RefreshAssets();
        }
예제 #25
0
        public void RevertAllCopiedFiles(string[] copiedFilesLogText, string revertLogPath)
        {
            //读入所有已拷贝的文件列表
            var  revertFolderList = new List <string>();
            var  revertFilesList  = new List <string>();
            bool revertThis       = false;

            foreach (var line in copiedFilesLogText)
            {
                if (line[0] == 'R' && line[1] == ' ')
                {
                    revertFolderList.Add(line.Substring(2).Trim());
                    revertThis = true;
                }
                else if (line[0] == 'D' && line[1] == ' ')
                {
                    revertThis = false;
                }
                else if (line[0] == ' ' && line[1] == ' ' && revertThis)
                {
                    revertFilesList.Add(line.Substring(2).Trim());
                }
            }
            //单独的日志文件
            errorMessage = "";
            float progress = 0;

            //删除所有已拷贝并标记为R(revert)的文件(不存在的文件不记录日志)
            using (var logWriter = new StreamWriter(revertLogPath, true))
            {
                Module.DisplayProgressBar("Start Delete Copied Files", 0, true);
                logWriter.WriteLine("Start Delete Files"); logWriter.Flush();
                foreach (string file in revertFilesList)
                {
                    if (File.Exists(file))
                    {
                        Module.DisplayProgressBar("Delete Copied Files", file, progress++ % 1000 / 1000);
                        File.Delete(file);
                        logWriter.WriteLine("Deleted: " + file); logWriter.Flush();
                    }
                }
                logWriter.WriteLine("End Delete Files"); logWriter.Flush();
                Module.DisplayProgressBar("End Delete Copied Files", 0, true);
            }

            //还原目录
            progress = 0;
            Module.DisplayProgressBar("Start Revert All Copied Files", 0, true);
            foreach (var folderPath in revertFolderList)
            {
                string title = "Revert Copied Files in " + EBPUtility.Quote(Path.GetFileName(folderPath));
                Module.DisplayProgressBar(title, "Start Revert " + EBPUtility.Quote(folderPath), 0, true);

                Process p = SVNUpdate.Runner.ExcuteCommand("/bin/bash",
                                                           EBPUtility.Quote(Path.Combine(Module.ModuleConfig.ModuleRootPath, "Shells/SVNRevert.sh")) + " " +
                                                           EBPUtility.Quote(folderPath) + " " +
                                                           EBPUtility.Quote(revertLogPath), OnReceived, OnErrorReceived, null);

                while (!p.HasExited)
                {
                    Module.DisplayProgressBar(title, message, progress++ % 1000 / 1000);
                    System.Threading.Thread.Sleep(50);
                }

                if (p.ExitCode != 0)
                {
                    throw new EBPException("还原目录(" + folderPath + ")时发生错误:" + errorMessage);
                }
                Module.DisplayProgressBar(title, "Finish!", 1, true);
            }
            Module.DisplayProgressBar("End Revert All Copied Files", 1, true);
            EBPUtility.RefreshAssets();
        }
예제 #26
0
        protected override void RunProcess()
        {
            //准备参数
            bundlesFolderPath = Module.GetBundleFolderPath();
            if (!Directory.Exists(bundlesFolderPath))
            {
                throw new EBPException("Bundles目录不存:" + bundlesFolderPath);
            }

            string packagesFolderPath = Path.Combine(Module.ModuleConfig.WorkPath, EBPUtility.GetTagStr(Module.ModuleStateConfig.Json.CurrentTag)
                                                     + "/" + Module.UserConfig.Json.PackageMode);
            int   count    = 0;
            int   total    = 0;
            float progress = 0;
            var   packages = Module.UserConfig.Json.Packages;

            //清除不存在的Bundle
            Module.DisplayProgressBar("正在从Packages清单中清除不存在的Bundle", 0, true);
            notExistLogWriter = new StreamWriter(Path.Combine(CommonModule.CommonConfig.CurrentLogFolderPath, "NotExistBundlesWhenBuildPackage.log"));
            notExistLogWriter.WriteLine("Root: " + bundlesFolderPath + "\n");
            cleanBundlesCount = 0;
            foreach (var package in packages)
            {
                package.Bundles.RemoveAll(IsNotExist);
            }
            notExistLogWriter.WriteLine("\ntotal:" + cleanBundlesCount);
            notExistLogWriter.Close();

            //统计总数
            foreach (var package in packages)
            {
                total += package.Bundles.Count;
            }
            int packagesCount = packages.Count;

            //TODO:构建map改进方法
            //if (Configs.g.bundleTree.BundleBuildMap == null)
            //{
            //    throw new EBPException("BuildMap is null");
            //}
            //string mapContent = JsonConvert.SerializeObject(BuildAsset2BundleMap(Configs.g.bundleTree.BundleBuildMap), Formatting.Indented);

            //重建目录
            Module.DisplayProgressBar("正在重建" + Module.UserConfig.Json.PackageMode + "目录", packagesFolderPath, progress, true); progress += 0.01f;
            if (Directory.Exists(packagesFolderPath))
            {
                Directory.Delete(packagesFolderPath, true);
            }
            Directory.CreateDirectory(packagesFolderPath);

            //设置路径
            string platform = Module.ModuleStateConfig.Json.CurrentTag[0].ToLower();
            string bundlesRootPathInPackage       = "AssetBundles/" + platform + "/AssetBundles/";
            string bundleVersionFilePathInPackage = "AssetBundles/" + platform + "/bundle_version";
            string mapFilePathInPackage           = "AssetBundles/" + platform + "/maps/map";
            string streamingPath = Path.Combine("Assets/StreamingAssets/AssetBundles", Module.ModuleStateConfig.Json.CurrentTag[0]);

            byte[] buffer = new byte[20971520]; //20M缓存,不够会自动扩大

            //以下为整体上Addon和Patch的不同
            switch (Module.UserConfig.Json.PackageMode)
            {
            case "Patch":
                mapFilePathInPackage += "_" + Module.ModuleStateConfig.Json.ResourceVersion;
                break;

            case "Addon":
                Module.DisplayProgressBar("正在获取需要拷贝到Streaming中的Bundles信息", progress, true); progress += 0.01f;
                //得到需要拷贝到Streaming中的Bundles
                List <string> bundlesCopyToStreaming = new List <string>();
                //List<string> bundlesCopyToStreaming_all = new List<string>();

                foreach (var package in packages)
                {
                    if (package.CopyToStreaming)
                    {
                        bundlesCopyToStreaming = bundlesCopyToStreaming.Union(package.Bundles).ToList();
                    }
                    //bundlesCopyToStreaming_all = bundlesCopyToStreaming_all.Union(package.Bundles).ToList();
                }

                //重建StreamingAssets/AssetBundles/[Platform]目录
                Module.DisplayProgressBar("正在重建StreamingAssets目录:", "Assets/StreamingAssets/AssetBundles", progress, true); progress += 0.01f;
                if (Directory.Exists("Assets/StreamingAssets/AssetBundles"))
                {
                    Directory.Delete("Assets/StreamingAssets/AssetBundles", true);
                }
                Directory.CreateDirectory(streamingPath);

                //构建PackageManifest.json
                Module.DisplayProgressBar("正在StreamingAssets中构建文件", "PackageManifest.json", progress, true); progress += 0.01f;
                List <PackageManifestStruct> packageManifest = new List <PackageManifestStruct>();
                //单独加一个核心包的配置信息
                string corePackageName = string.Join("_", new string[] {
                    platform,
                    Module.UserConfig.Json.PackageMode.ToLower(),
                    Module.ModuleStateConfig.Json.ClientVersion,
                    "Core"
                }) + Module.ModuleConfig.Json.PackageExtension;
                packageManifest.Add(new PackageManifestStruct
                {
                    name_          = corePackageName,
                    flag_          = G.NecesseryEnum.IndexOf("Immediate"),
                    location_      = G.DeploymentLocationEnum.IndexOf("Built-in"),
                    hasDownloaded_ = false
                });

                //所有package的配置信息
                foreach (var package in packages)
                {
                    packageManifest.Add(new PackageManifestStruct
                    {
                        name_          = GetPackageFileName(package.PackageName, Module.ModuleStateConfig.Json.ResourceVersion),
                        flag_          = G.NecesseryEnum.IndexOf(package.Necessery),
                        location_      = G.DeploymentLocationEnum.IndexOf(package.DeploymentLocation),
                        hasDownloaded_ = package.CopyToStreaming
                    });
                }
                string packageManifestContent = JsonConvert.SerializeObject(packageManifest, Formatting.Indented);
                File.WriteAllText(Path.Combine(streamingPath, "PackageManifest.json"), packageManifestContent);

                //构建核心包
                string corePackagePath = Path.Combine(streamingPath, corePackageName);
                Module.DisplayProgressBar("正在向StreamingAssets中构建CorePackage", corePackagePath, progress, true); progress += 0.01f;
                using (FileStream zipFileStream = new FileStream(corePackagePath, FileMode.Create))
                {
                    using (ZipOutputStream zipStream = new ZipOutputStream(zipFileStream))
                    {
                        zipStream.SetLevel(Module.UserConfig.Json.CompressionLevel);

                        //构建bundle_version
                        BuildBundleVersionInfoInZipStream(bundleVersionFilePathInPackage, Module.ModuleStateConfig.Json.ResourceVersion, bundlesCopyToStreaming, zipStream);

                        //构建map
                        BuildMapInZipStream(mapFilePathInPackage, buffer, zipStream);

                        //添加Lua
                        BuildLuaInZipStream(buffer, zipStream);
                    }
                }

                //拷贝Assetbundle
                string bundlesRootPathInStreaming  = Path.Combine(streamingPath, "AssetBundles");
                int    bundlesCopyToStreamingCount = bundlesCopyToStreaming.Count;
                for (int i = 0; i < bundlesCopyToStreamingCount; i++)
                {
                    string bundle = bundlesCopyToStreaming[i];

                    Module.DisplayProgressBar(string.Format("正在向StreamingAssets中拷贝Bundles({0}/{1})",
                                                            i + 1, bundlesCopyToStreamingCount),
                                              bundle, progress + (float)i / bundlesCopyToStreamingCount * 0.1f);//拷贝Assetbundle过程占整个过程的10%

                    string targetPath = Path.Combine(bundlesRootPathInStreaming, bundle);
                    Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
                    File.Copy(Path.Combine(bundlesFolderPath, bundle), targetPath, false);     //这里不允许覆盖,若已存在则抛出异常
                }
                progress += 0.1f;
                break;

            default:
                throw new EBPException("不能识别模式:" + Module.UserConfig.Json.PackageMode);
            }

            float restProgress = 1 - progress;

            for (int pi = 0; pi < packagesCount; pi++)
            {
                var package = packages[pi];
                if (package.CopyToStreaming) //copyToStreaming的Package不打成Addon
                {
                    continue;
                }
                using (FileStream zipFileStream = new FileStream(Path.Combine(packagesFolderPath, GetPackageFileName(package.PackageName, Module.ModuleStateConfig.Json.ResourceVersion)), FileMode.Create))
                {
                    using (ZipOutputStream zipStream = new ZipOutputStream(zipFileStream))
                    {
                        zipStream.SetLevel(Module.UserConfig.Json.CompressionLevel);

                        //构建Bundles
                        int bundlesCount = package.Bundles.Count;
                        for (int i = 0; i < bundlesCount; i++)
                        {
                            string bundleRelativePath = package.Bundles[i];
                            string bundlePath         = Path.Combine(bundlesFolderPath, bundleRelativePath);

                            Module.DisplayProgressBar(string.Format("正在打包{0}({1}/{2}) : ({3}/{4})  总计:({5}/{6})",
                                                                    package.PackageName, pi + 1, packagesCount, i + 1, bundlesCount, count + 1, total),
                                                      bundleRelativePath, progress + (float)count / total * restProgress);

                            AddFileToZipStream(zipStream, bundlePath, Path.Combine(bundlesRootPathInPackage, bundleRelativePath), buffer);
                            count++;
                        }

                        //构建空目录
                        int emptyFolderCount = package.EmptyFolders.Count;
                        Module.DisplayProgressBar(string.Format("正在打包{0}({1}/{2}) : ({3}/{4})  总计:({5}/{6})",
                                                                package.PackageName, pi + 1, packagesCount, bundlesCount, bundlesCount, count, total),
                                                  string.Format("Empty Folders (Total:{0})", emptyFolderCount), progress + (float)count / total * restProgress, true);
                        for (int i = 0; i < emptyFolderCount; i++)
                        {
                            zipStream.PutNextEntry(new ZipEntry(package.EmptyFolders[i] + "/")
                            {
                            });
                        }

                        //构建bundle_version
                        BuildBundleVersionInfoInZipStream(bundleVersionFilePathInPackage, Module.ModuleStateConfig.Json.ResourceVersion, package.Bundles, zipStream);

                        //以下为每个包中Patch和Addon独有内容
                        switch (Module.UserConfig.Json.PackageMode)
                        {
                        case "Patch":
                            //构建map
                            Module.DisplayProgressBar(string.Format("正在打包{0}({1}/{2}) : ({3}/{4})  总计:({5}/{6})",
                                                                    package.PackageName, pi + 1, packagesCount, bundlesCount, bundlesCount, count, total),
                                                      "Building Map...", progress + (float)count / total * restProgress, true);
                            BuildMapInZipStream(mapFilePathInPackage, buffer, zipStream);
                            //添加Lua
                            Module.DisplayProgressBar(string.Format("正在打包{0}({1}/{2}) : ({3}/{4})  总计:({5}/{6})",
                                                                    package.PackageName, pi + 1, packagesCount, bundlesCount, bundlesCount, count, total),
                                                      "Adding Lua...", progress + (float)count / total * restProgress, true);
                            BuildLuaInZipStream(buffer, zipStream);
                            break;

                        case "Addon":
                            break;

                        default:
                            throw new EBPException("不能识别模式:" + Module.UserConfig.Json.PackageMode);
                        }
                    }
                }
            }
        }