using System; using System.Collections.Generic; using System.Linq; using HybridCLR.Editor.Commands; using HybridCLR.Editor.Installer; using PhxhSDK.AOT.VersionUpdate; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.Windows; using BuildTarget = UnityEditor.BuildTarget; using Debug = UnityEngine.Debug; class BuildLauncher { private const string HybirdCLRGenerateDir = "/HybridCLRGenerate"; private const string HybirdCLRGenerateLinkPath = "Assets/HybridCLRGenerate/link.xml"; private const string GameLauncherSceneName = "Assets/Scenes/GameLauncher.unity"; private const string RemoteUser = "root"; private const string RemoteHost = "132.232.113.98"; private const string RemotePath = "/var/www/html/nld/{0}/{1}/{2}"; public static void BuildHotUpdateDlls() { var controller = new InstallerController(); if(!controller.HasInstalledHybridCLR()) controller.InstallDefaultHybridCLR(); // VersionControlSystem.Checkout(HybirdCLRGenerateDir); BuildLauncherBase.SetFileReadable(Application.dataPath + HybirdCLRGenerateDir); PrebuildCommand.GenerateAll(); HotUpadeEditorHelper.CopyHotUpdateDll(); HotUpadeEditorHelper.CopyMetaDataDll(); } public static void SetEnableHotUpdate(bool isEnable) { Debug.Log($"是否开启热更新:{isEnable}"); var gameLauncherScene = EditorSceneManager.OpenScene(GameLauncherSceneName, OpenSceneMode.Additive); if (!gameLauncherScene.IsValid()) { Debug.LogError($"无法加载场景{GameLauncherSceneName}"); return; } var gameLauncher = UnityEngine.Object.FindObjectOfType(); if (gameLauncher == null) { Debug.LogError("找不到GameLauncher"); return; } gameLauncher.enableHotUpdate = isEnable; EditorSceneManager.MarkSceneDirty(gameLauncherScene); EditorSceneManager.SaveScene(gameLauncherScene); EditorSceneManager.CloseScene(gameLauncherScene, false); HybridCLR.Editor.SettingsUtil.Enable = isEnable; if (!isEnable) { //删除HybirdCLR生成的link文件 AssetDatabase.DeleteAsset(HybirdCLRGenerateLinkPath); } } #if USE_ADDRESSABLES public static bool BuildAddressables(BuildTarget buildTarget, string profileName, string version, string workSpace, bool ignoreHotUpdate, bool needClearCached = false, List groups = null) { EditorUserBuildSettings.SwitchActiveBuildTarget(BuildPipeline.GetBuildTargetGroup(buildTarget), buildTarget); SetEnableHotUpdate(!ignoreHotUpdate); if (!ignoreHotUpdate) { BuildHotUpdateDlls(); } #if USE_YOO return BuildLauncherBase.BuildYooAsset(buildTarget, profileName, version, workSpace, RemoteUser, RemoteHost, RemotePath); #else return BuildLauncherBase.BuildAddressables(buildTarget, profileName, version, workSpace, needClearCached, groups, RemoteUser, RemoteHost, RemotePath); #endif } #endif public static void UpdatePreviousBuild(string profileName, bool ignoreHotUpdate, BuildTarget buildTarget, string workSpace) { EditorUserBuildSettings.SwitchActiveBuildTarget(BuildPipeline.GetBuildTargetGroup(buildTarget), buildTarget); if (!ignoreHotUpdate) { BuildHotUpdateDlls(); } #if USE_ADDRESSABLES BuildLauncherBase.UpdatePreviousBuild(profileName, buildTarget, workSpace, RemoteUser, RemoteHost, RemotePath); #endif } public static void BuildAddressablesAndPlayer(BuildTarget buildTarget, string profileName, string version, string workSpace, bool ignoreHotUpdate, bool needClearCached = false, bool isDev = false) { #if USE_ADDRESSABLES if (BuildAddressables(buildTarget, profileName, version, workSpace, ignoreHotUpdate, needClearCached)) { BuildLauncherBase.BuildPlayer(buildTarget,isDev); } #endif } public static void BuildPlayer(BuildTarget buildTarget,bool isDev = false) { BuildLauncherBase.BuildPlayer(buildTarget,isDev); } } internal class BatchBuild { /// /// 批处理构建Addressables /// public static void BuildAddressables() { var enableHotUpdate = BatchBuildBase.Init(); if (enableHotUpdate) BuildLauncher.BuildHotUpdateDlls(); BatchBuildBase.BuildAddressables(); } private static string _oldDefines; private static bool _hasYooAsset; private static void _InitScriptDefines() { var hasYooAsset = false; // 判断本地是否有define_list.txt文件 var defineListPath = Application.dataPath + "/../define_list.txt"; var appendDefineList = new List(); if (File.Exists(defineListPath)) { var defineList = System.IO.File.ReadAllLines(defineListPath); foreach (var define in defineList) { if (string.IsNullOrEmpty(define)) continue; appendDefineList.Add(define); Debug.Log("追加宏定义:" + define); if (define == "USE_YOO") { hasYooAsset = true; } } } var currentTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); var oldDefines = PlayerSettings.GetScriptingDefineSymbolsForGroup(currentTargetGroup); _oldDefines = oldDefines; // 判断是否有需要追加的宏 if (appendDefineList.Count > 0) { var newDefineList = new List(); newDefineList.AddRange(oldDefines.Split(';')); for (var i = 0; i < newDefineList.Count; i++) { var define = newDefineList[i]; if (string.IsNullOrEmpty(define)) continue; if (define == "USE_YOO") { hasYooAsset = true; } if (appendDefineList.Contains(define)) appendDefineList.Remove(define); } newDefineList.AddRange(appendDefineList); PlayerSettings.SetScriptingDefineSymbolsForGroup(currentTargetGroup, string.Join(";", newDefineList)); } // 现已修改为使用YooAsset _hasYooAsset = hasYooAsset; _hasYooAsset = true; } private static void _RevertScriptDefines() { var currentTargetGroup = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); PlayerSettings.SetScriptingDefineSymbolsForGroup(currentTargetGroup, _oldDefines); } /// /// 批处理构建Addressables和Player /// jenkins打包新包时使用该方法 /// public static void BuildContentAndPlayer() { try { _InitScriptDefines(); var enableHotUpdate = BatchBuildBase.Init(); if (_hasYooAsset) { // 写入版本信息到Resources/LocalInfo.json var info = new UpdateLocalInfo(); info.workSpace = BatchBuildBase.workSpace; info.version = BatchBuildBase.appVersion; info.buildCount = 1; info.serverUrl = "http://132.232.113.98"; PackDataInst.CreateResourceJson(info); // 写入打包次数 PackDataInst.CreateBuildCount(info.workSpace, info.version, info.buildCount); } BuildLauncher.SetEnableHotUpdate(enableHotUpdate); if (enableHotUpdate) { BuildLauncher.BuildHotUpdateDlls(); } BatchBuildBase.BuildContentAndPlayer(); // 还原宏 _RevertScriptDefines(); } catch (Exception e) { //Build Exception用于在日志文件中定位此次打包的异常 Debug.LogError($"[Build Exception]:{e.Message} \r\n {e.StackTrace}"); throw; } } /// /// 批处理增量更新资源 /// jenkins打包增量更新时使用该方法 /// public static void UpdatePreviousBuild() { try { _InitScriptDefines(); var enableHotUpdate = BatchBuildBase.Init(); if (enableHotUpdate) BuildLauncher.BuildHotUpdateDlls(); BatchBuildBase.BuildOnlyResUpdate(); _RevertScriptDefines(); } catch (Exception e) { //Build Exception用于在日志文件中定位此次打包的异常 Debug.LogError($"[Build Exception]:{e.Message} \r\n {e.StackTrace}"); throw; } } }