New file |
| | |
| | | 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" |
| | | }; |
| | | |
| | | 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, "/mob"), 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); |
| | | |
| | | 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.defaultIsFullScreen = true; |
| | | 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 }; |
| | | } |
| | | |
| | | } |