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 builtinConfigs = new List() { "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(); 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(); var middlePackages = new List(); var bigPackages = new List(); 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 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(); var files = new List(); 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 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(); FileExtersion.GetAllDirectoryFileInfos(assetPath, fromFiles); var excludeFileFullNames = new List(); var tempFiles = new List(); 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 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(); 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("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(); 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(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(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(to) == null) { AssetDatabase.CopyAsset(from, to); } } }