| using System.Collections; | 
| using System.Collections.Generic; | 
| using UnityEngine; | 
| using System; | 
| using UnityEditor; | 
| using System.IO; | 
| using System.Text.RegularExpressions; | 
| using System.Text; | 
| using Beebyte.Obfuscator; | 
|   | 
| public class ClientPackage_Standalone | 
| { | 
|     static readonly string versionsFilePath = Application.dataPath + Path.DirectorySeparatorChar + "Editor/VersionConfigs/Versions.txt"; | 
|     static readonly string[] baseLevels = new string[] { "Assets/Resources/Scenes/Launch.unity", "Assets/Resources/Scenes/Empty.unity" }; | 
|     static readonly List<string> builtinConfigs = new List<string>() { | 
|         "Contact.txt","HelpInfo.txt","PriorBundle.txt","PriorLanguage.txt","ApkUpdateUrl.txt","InitialFunction.txt" | 
|     }; | 
|   | 
|     public static bool obfuscatorEnabled | 
|     { | 
|         get { return LocalSave.GetBool("obfuscatorEnabled", false); } | 
|         set { LocalSave.SetBool("obfuscatorEnabled", value); } | 
|     } | 
|   | 
|     public static int AssetPrior | 
|     { | 
|         get { return LocalSave.GetInt("Standalone_HalfAssetPrior", 1); } | 
|         set { LocalSave.SetInt("Standalone_HalfAssetPrior", value); } | 
|     } | 
|   | 
|     public struct BuildParams | 
|     { | 
|         public string publisher; | 
|         public string assetBundle; | 
|         public string output; | 
|         public int buildIndex; | 
|         public bool development; | 
|     } | 
|   | 
|     public static void Build(BuildParams buildParams) | 
|     { | 
|         var packageIds = new List<int>(); | 
|         var tempStrings = buildParams.publisher.Split(StringUtility.splitSeparator, StringSplitOptions.RemoveEmptyEntries); | 
|         foreach (var temp in tempStrings) | 
|         { | 
|             var matches = Regex.Matches(temp, "\\d+"); | 
|             switch (matches.Count) | 
|             { | 
|                 case 1: | 
|                     var id = int.Parse(matches[0].Value); | 
|                     packageIds.Add(id); | 
|                     break; | 
|                 case 2: | 
|                     var min = int.Parse(matches[0].Value); | 
|                     var max = int.Parse(matches[1].Value); | 
|                     for (int index = min; index <= max; index++) | 
|                     { | 
|                         packageIds.Add(index); | 
|                     } | 
|                     break; | 
|             } | 
|         } | 
|   | 
|         var smallPackages = new List<int>(); | 
|         var middlePackages = new List<int>(); | 
|         var bigPackages = new List<int>(); | 
|         foreach (var id in packageIds) | 
|         { | 
|             var versionName = string.Empty; | 
|             var versionConfig = GetVersionConfig(id.ToString(), out versionName); | 
|             switch (versionConfig.assetAccess) | 
|             { | 
|                 case InstalledAsset.NullAsset: | 
|                     smallPackages.Add(id); | 
|                     break; | 
|                 case InstalledAsset.HalfAsset: | 
|                     middlePackages.Add(id); | 
|                     break; | 
|                 case InstalledAsset.FullAsset: | 
|                 case InstalledAsset.IngoreDownLoad: | 
|                     bigPackages.Add(id); | 
|                     break; | 
|   | 
|             } | 
|         } | 
|   | 
|         BuildSmallPackage(smallPackages, buildParams.assetBundle, buildParams.output, buildParams.buildIndex, buildParams.development); | 
|         BuildMiddlePackage(middlePackages, buildParams.assetBundle, buildParams.output, buildParams.buildIndex, buildParams.development); | 
|         BuildBigPackage(bigPackages, buildParams.assetBundle, buildParams.output, buildParams.buildIndex, buildParams.development); | 
|     } | 
|   | 
|     static void BuildSmallPackage(List<int> packageIds, string assetPath, string output, int buildIndex, bool development) | 
|     { | 
|         if (Directory.Exists(ResourcesPath.Instance.StreamingAssetPath)) | 
|         { | 
|             Directory.Delete(ResourcesPath.Instance.StreamingAssetPath, true); | 
|         } | 
|   | 
|         if (packageIds.IsNullOrEmpty()) | 
|         { | 
|             return; | 
|         } | 
|   | 
|         var builtInFiles = new List<FileInfo>(); | 
|         var files = new List<FileInfo>(); | 
|         FileExtersion.GetAllDirectoryFileInfos(assetPath, files); | 
|         foreach (var file in files) | 
|         { | 
|             var fileName = Path.GetFileName(file.FullName); | 
|             if (file.FullName.Contains("builtin") || builtinConfigs.Contains(fileName)) | 
|             { | 
|                 builtInFiles.Add(file); | 
|             } | 
|             else | 
|             { | 
|                 File.Delete(file.FullName); | 
|             } | 
|         } | 
|   | 
|         foreach (var item in builtInFiles) | 
|         { | 
|             var directory = Path.GetDirectoryName(item.FullName); | 
|             if (!Directory.Exists(directory)) | 
|             { | 
|                 Directory.CreateDirectory(directory); | 
|             } | 
|   | 
|             var relativePath = FileExtersion.GetFileRelativePath(assetPath, item.FullName); | 
|             var to = StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, relativePath); | 
|             File.Copy(item.FullName, to, true); | 
|         } | 
|   | 
|         foreach (var id in packageIds) | 
|         { | 
|             BuildPackage(id, output, buildIndex, development); | 
|         } | 
|     } | 
|   | 
|     static void BuildMiddlePackage(List<int> packageIds, string assetPath, string output, int buildIndex, bool development) | 
|     { | 
|         if (Directory.Exists(ResourcesPath.Instance.StreamingAssetPath)) | 
|         { | 
|             Directory.Delete(ResourcesPath.Instance.StreamingAssetPath, true); | 
|         } | 
|   | 
|         if (packageIds.IsNullOrEmpty()) | 
|         { | 
|             return; | 
|         } | 
|   | 
|         PriorBundleConfig.Init(true); | 
|   | 
|         var fromFiles = new List<FileInfo>(); | 
|         FileExtersion.GetAllDirectoryFileInfos(assetPath, fromFiles); | 
|   | 
|         var excludeFileFullNames = new List<string>(); | 
|         var tempFiles = new List<FileInfo>(); | 
|         FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(assetPath, "/gmodels"), tempFiles); | 
|         foreach (var file in tempFiles) | 
|         { | 
|             var extersion = Path.GetExtension(file.FullName); | 
|             var fileName = Path.GetFileName(file.FullName); | 
|             if (!string.IsNullOrEmpty(extersion)) | 
|             { | 
|                 fileName = fileName.Replace(extersion, ""); | 
|             } | 
|   | 
|             var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Mob, fileName); | 
|             if (prior > AssetPrior) | 
|             { | 
|                 excludeFileFullNames.Add(file.FullName); | 
|             } | 
|         } | 
|   | 
|         tempFiles.Clear(); | 
|         FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(assetPath, "/maps"), tempFiles); | 
|         foreach (var file in tempFiles) | 
|         { | 
|             var extersion = Path.GetExtension(file.FullName); | 
|             var fileName = Path.GetFileName(file.FullName); | 
|             if (!string.IsNullOrEmpty(extersion)) | 
|             { | 
|                 fileName = fileName.Replace(extersion, ""); | 
|             } | 
|   | 
|             var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Scene, fileName); | 
|             if (prior > AssetPrior) | 
|             { | 
|                 excludeFileFullNames.Add(file.FullName); | 
|             } | 
|         } | 
|   | 
|         tempFiles.Clear(); | 
|         FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(assetPath, "/audio"), tempFiles); | 
|         foreach (var file in tempFiles) | 
|         { | 
|             var extersion = Path.GetExtension(file.FullName); | 
|             var fileName = Path.GetFileName(file.FullName); | 
|             if (!string.IsNullOrEmpty(extersion)) | 
|             { | 
|                 fileName = fileName.Replace(extersion, ""); | 
|             } | 
|   | 
|             var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Audio, fileName); | 
|             if (prior > AssetPrior) | 
|             { | 
|                 excludeFileFullNames.Add(file.FullName); | 
|             } | 
|         } | 
|   | 
|         tempFiles.Clear(); | 
|         FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(assetPath, "/effect"), tempFiles); | 
|         foreach (var file in tempFiles) | 
|         { | 
|             var extersion = Path.GetExtension(file.FullName); | 
|             var fileName = Path.GetFileName(file.FullName); | 
|             if (!string.IsNullOrEmpty(extersion)) | 
|             { | 
|                 fileName = fileName.Replace(extersion, ""); | 
|             } | 
|   | 
|             var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Effect, fileName); | 
|             if (prior > AssetPrior) | 
|             { | 
|                 excludeFileFullNames.Add(file.FullName); | 
|             } | 
|         } | 
|   | 
|         tempFiles.Clear(); | 
|         FileExtersion.GetAllDirectoryFileInfos(StringUtility.Contact(assetPath, "/ui/sprite"), tempFiles); | 
|         foreach (var file in tempFiles) | 
|         { | 
|             var fileName = Path.GetFileName(file.FullName); | 
|             if (fileName == "loadingbg") | 
|             { | 
|                 excludeFileFullNames.Add(file.FullName); | 
|             } | 
|         } | 
|   | 
|         for (int i = fromFiles.Count - 1; i >= 0; i--) | 
|         { | 
|             var item = fromFiles[i]; | 
|             if (excludeFileFullNames.Contains(item.FullName)) | 
|             { | 
|                 fromFiles.RemoveAt(i); | 
|             } | 
|         } | 
|   | 
|         foreach (var item in fromFiles) | 
|         { | 
|             var relativePath = FileExtersion.GetFileRelativePath(assetPath, item.FullName); | 
|             var to = StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, relativePath); | 
|             var directory = Path.GetDirectoryName(to); | 
|             if (!Directory.Exists(directory)) | 
|             { | 
|                 Directory.CreateDirectory(directory); | 
|             } | 
|             File.Copy(item.FullName, to, true); | 
|         } | 
|   | 
|         foreach (var id in packageIds) | 
|         { | 
|             BuildPackage(id, output, buildIndex, development); | 
|         } | 
|     } | 
|   | 
|     static void BuildBigPackage(List<int> packageIds, string assetPath, string output, int buildIndex, bool development) | 
|     { | 
|         if (Directory.Exists(ResourcesPath.Instance.StreamingAssetPath)) | 
|         { | 
|             Directory.Delete(ResourcesPath.Instance.StreamingAssetPath, true); | 
|         } | 
|   | 
|         if (packageIds.IsNullOrEmpty()) | 
|         { | 
|             return; | 
|         } | 
|   | 
|         var fromFiles = new List<FileInfo>(); | 
|         FileExtersion.GetAllDirectoryFileInfos(assetPath, fromFiles); | 
|         foreach (var item in fromFiles) | 
|         { | 
|             var relativePath = FileExtersion.GetFileRelativePath(assetPath, item.FullName); | 
|             var to = StringUtility.Contact(ResourcesPath.Instance.StreamingAssetPath, relativePath); | 
|             var directory = Path.GetDirectoryName(to); | 
|             if (!Directory.Exists(directory)) | 
|             { | 
|                 Directory.CreateDirectory(directory); | 
|             } | 
|   | 
|             File.Copy(item.FullName, to, true); | 
|         } | 
|   | 
|         foreach (var id in packageIds) | 
|         { | 
|             BuildPackage(id, output, buildIndex, development); | 
|         } | 
|     } | 
|   | 
|     static void BuildPackage(int packageId, string output, int buildIndex, bool development) | 
|     { | 
|         PreBuild(packageId, buildIndex, development); | 
|   | 
|         var versionName = string.Empty; | 
|         var versionConfig = GetVersionConfig(packageId.ToString(), out versionName); | 
|         var versionConfigCSpath = Application.dataPath + "/Scripts/System/ClientVersion/VersionConfig.cs"; | 
|         var text = File.ReadAllText(versionConfigCSpath); | 
|   | 
|         if (text.Contains("VERSION_ALTERNATIVE")) | 
|         { | 
|             var pattern = "VERSION_ALTERNATIVE = \".*\""; | 
|             text = Regex.Replace(text, pattern, StringUtility.Contact("VERSION_ALTERNATIVE = ", "\"", versionConfig.m_Version, "\"")); | 
|   | 
|             var encoderShouldEmitUTF8Identifier = true; | 
|             var throwOnInvalidBytes = false; | 
|             var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier, throwOnInvalidBytes); | 
|             var append = false; | 
|             var streamWriter = new StreamWriter(versionConfigCSpath, append, encoding); | 
|             streamWriter.Write(text); | 
|             streamWriter.Close(); | 
|             AssetDatabase.ImportAsset(versionConfigCSpath); | 
|         } | 
|   | 
|         var option = AssetDatabase.LoadAssetAtPath<Options>("Assets/Editor/Beebyte/Obfuscator/ObfuscatorOptions.asset"); | 
|         if (option != null) | 
|         { | 
|             option.enabled = obfuscatorEnabled; | 
|             EditorUtility.SetDirty(option); | 
|         } | 
|   | 
|         AssetDatabase.SaveAssets(); | 
|         AssetDatabase.Refresh(); | 
|   | 
|         if (development) | 
|         { | 
|             var name = StringUtility.Contact(output, "/", versionName, "_", versionConfig.clientPackageFlag, "_v", versionConfig.m_Version, "_", buildIndex, "_development.exe"); | 
|             BuildPipeline.BuildPlayer(baseLevels, name, BuildTarget.StandaloneWindows, BuildOptions.Development | BuildOptions.ConnectWithProfiler | BuildOptions.AllowDebugging); | 
|         } | 
|         else | 
|         { | 
|             var name = StringUtility.Contact(output, "/", versionName, "_", versionConfig.clientPackageFlag, "_v", versionConfig.m_Version, "_", buildIndex, ".exe"); | 
|             BuildPipeline.BuildPlayer(baseLevels, name, BuildTarget.StandaloneWindows, BuildOptions.None); | 
|         } | 
|     } | 
|   | 
|     private static void PreBuild(int packageId, int buildIndex, bool development) | 
|     { | 
|         try | 
|         { | 
|             var newVersionConfigPath = StringUtility.Contact("Assets/Resources/VersionConfig", ".asset"); | 
|             var versionName = string.Empty; | 
|             var fromVersionConfig = GetVersionConfig(packageId.ToString(), out versionName); | 
|             var newVersionConfig = ScriptableObject.CreateInstance<VersionConfig>(); | 
|             if (File.Exists(newVersionConfigPath)) | 
|             { | 
|                 AssetDatabase.DeleteAsset(newVersionConfigPath); | 
|             } | 
|   | 
|             VersionConfig.Copy(fromVersionConfig, newVersionConfig); | 
|             newVersionConfig.buildTime = DateTime.Now.ToString("yy/MM/dd--HH:mm"); | 
|             newVersionConfig.buildIndex = buildIndex; | 
|   | 
|             AssetDatabase.CreateAsset(newVersionConfig, newVersionConfigPath); | 
|             EditorUtility.SetDirty(newVersionConfig); | 
|   | 
|             SetIconAndSplashImage(versionName); | 
|             //SetCreateRoleAnimation(); | 
|   | 
|             PlayerSettings.companyName = "TheSecondWorld"; | 
|             PlayerSettings.productName = newVersionConfig.productName; | 
|             PlayerSettings.applicationIdentifier = newVersionConfig.bundleIdentifier; | 
|             PlayerSettings.bundleVersion = VersionConfig.GetVersionNumber(newVersionConfig.version).ToString(); | 
|   | 
|             PlayerSettings.usePlayerLog = development; | 
|             PlayerSettings.SetAspectRatio(AspectRatio.Aspect16by9, true); | 
|             PlayerSettings.SetAspectRatio(AspectRatio.Aspect4by3, false); | 
|             PlayerSettings.SetAspectRatio(AspectRatio.Aspect16by10, false); | 
|             PlayerSettings.SetAspectRatio(AspectRatio.Aspect5by4, false); | 
|             PlayerSettings.SetAspectRatio(AspectRatio.AspectOthers, false); | 
|   | 
|             PlayerSettings.fullScreenMode = FullScreenMode.FullScreenWindow; | 
|             PlayerSettings.enableInternalProfiler = development; | 
|         } | 
|         catch (Exception ex) | 
|         { | 
|             Debug.Log(ex); | 
|         } | 
|         finally | 
|         { | 
|             AssetDatabase.SaveAssets(); | 
|             AssetDatabase.Refresh(); | 
|         } | 
|   | 
|     } | 
|   | 
|     static VersionConfig GetVersionConfig(string packageId, out string versionName) | 
|     { | 
|         var lines = File.ReadAllLines(versionsFilePath); | 
|         for (int i = 2; i < lines.Length; i++) | 
|         { | 
|             var line = lines[i]; | 
|             var lineStrings = line.Split('\t'); | 
|             if (lineStrings[0] == packageId) | 
|             { | 
|                 var config = new VersionConfig(); | 
|                 config.Read(line); | 
|                 versionName = lineStrings[1]; | 
|                 return config; | 
|             } | 
|         } | 
|   | 
|         versionName = string.Empty; | 
|         return null; | 
|     } | 
|   | 
|     static void SetIconAndSplashImage(string _versionName) | 
|     { | 
|         var buildTarget = BuildTargetGroup.Standalone; | 
|         var texture = AssetDatabase.LoadAssetAtPath<Texture2D>(StringUtility.Contact("Assets/Editor/Logo/", _versionName, "/Icon.png")); | 
|         var iconSizes = PlayerSettings.GetIconSizesForTargetGroup(buildTarget); | 
|         var icons = new Texture2D[iconSizes.Length]; | 
|         for (int i = 0; i < iconSizes.Length; i++) | 
|         { | 
|             icons[i] = texture; | 
|         } | 
|   | 
|         PlayerSettings.SetIconsForTargetGroup(buildTarget, icons); | 
|   | 
|         PlayerSettings.SplashScreen.show = false; | 
|         PlayerSettings.SplashScreen.showUnityLogo = false; | 
|         PlayerSettings.SplashScreen.unityLogoStyle = PlayerSettings.SplashScreen.UnityLogoStyle.LightOnDark; | 
|   | 
|         var splashImage = AssetDatabase.LoadAssetAtPath<Sprite>(StringUtility.Contact("Assets/Editor/Logo/", _versionName, "/SplashImage.png")); | 
|         var splashScreenLogo = PlayerSettings.SplashScreenLogo.Create(3, splashImage); | 
|         PlayerSettings.SplashScreen.logos = new PlayerSettings.SplashScreenLogo[] { splashScreenLogo }; | 
|     } | 
|   | 
|     public static void SetCreateRoleAnimation() | 
|     { | 
|         var from = "Assets/Editor/Video/CreateRoleMovie.mp4"; | 
|         var to = "Assets/Resources/CreateRoleMovie.mp4"; | 
|   | 
|         if (!Directory.Exists(Application.dataPath + "Resources")) | 
|         { | 
|             Directory.CreateDirectory(Application.dataPath + "Resources"); | 
|         } | 
|   | 
|         if (AssetDatabase.LoadAssetAtPath<UnityEngine.Video.VideoClip>(to) == null) | 
|         { | 
|             AssetDatabase.CopyAsset(from, to); | 
|         } | 
|     } | 
|   | 
| } |