From 195fe0ce2ef62facaa5bf836ebdf8866984e84a1 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期一, 11 五月 2026 16:21:23 +0800
Subject: [PATCH] Merge branch 'master' into h5version

---
 Assets/Editor/Tool/ClientPackage.cs |  282 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 281 insertions(+), 1 deletions(-)

diff --git a/Assets/Editor/Tool/ClientPackage.cs b/Assets/Editor/Tool/ClientPackage.cs
index 53b3c99..b7741a9 100644
--- a/Assets/Editor/Tool/ClientPackage.cs
+++ b/Assets/Editor/Tool/ClientPackage.cs
@@ -1,4 +1,4 @@
-锘縰sing System.Collections;
+using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using System;
@@ -386,6 +386,286 @@
     }
 
     public static VersionConfig versionConfig1 = null;
+
+    /// <summary>
+    /// 瀵煎嚭Android宸ョ▼缁橝S鎵撳寘
+    /// Unity鍙礋璐e鍑簎nityLibrary锛孲DK/Gradle/绛惧悕绛夊潎鐢盇S宸ョ▼澶勭悊
+    /// </summary>
+    public static void ExportAndroidProject(string _publisher, int _buildIndex, bool _development, string _outputPath, string _assetBundlePath)
+    {
+        if (string.IsNullOrEmpty(_outputPath) || !Directory.Exists(_outputPath))
+        {
+            Debug.LogError("瀵煎嚭璺緞鏃犳晥锛岃璁剧疆鏈夋晥鐨� Android Export Path: " + _outputPath);
+            return;
+        }
+
+        PreBuild(_publisher, _buildIndex);
+
+        var versionName = string.Empty;
+        var versionConfig = GetVersionConfig(_publisher, out versionName);
+
+        PlayerSettings.Android.bundleVersionCode = VersionConfig.GetVersionNumber(versionConfig.version);
+        PlayerSettings.enableInternalProfiler = _development;
+
+        // 鍏堟竻鐞哠treamingAssets锛屽啀鏍规嵁assetAccess閰嶇疆鎷疯礉璧勬簮鍒癝treamingAssets
+        var streamingPath = ResourcesPath.Instance.StreamingAssetPath;
+        if (Directory.Exists(streamingPath))
+            Directory.Delete(streamingPath, true);
+
+        if (!string.IsNullOrEmpty(_assetBundlePath) && Directory.Exists(_assetBundlePath))
+        {
+            switch (versionConfig.assetAccess)
+            {
+                case InstalledAsset.NullAsset:
+                    CopyNullAssetResources(_assetBundlePath, streamingPath);
+                    break;
+                case InstalledAsset.HalfAsset:
+                    CopyHalfAssetResources(_assetBundlePath, streamingPath);
+                    break;
+                case InstalledAsset.FullAsset:
+                case InstalledAsset.IngoreDownLoad:
+                    CopyFullAssetResources(_assetBundlePath, streamingPath);
+                    break;
+            }
+            Debug.LogFormat("璧勬簮鎷疯礉瀹屾垚({0})锛屼粠 {1} 鍒� {2}", versionConfig.assetAccess, _assetBundlePath, streamingPath);
+        }
+        else
+        {
+            Debug.LogWarningFormat("AssetBundle璺緞涓虹┖鎴栦笉瀛樺湪: {0}锛屽鍑哄伐绋嬪皢涓嶅寘鍚父鎴忚祫婧�", _assetBundlePath);
+        }
+
+        // 鍏抽敭璁剧疆锛氬鍑轰负Gradle宸ョ▼鑰岄潪鐩存帴鎵揂PK
+        EditorUserBuildSettings.exportAsGoogleAndroidProject = true;
+        EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle;
+        EditorUserBuildSettings.development = _development;
+
+        // 瀵煎嚭璺緞
+        _outputPath = Path.GetFullPath(_outputPath);
+        string outputDir = Path.Combine(_outputPath, versionName + "_" + versionConfig.clientPackageFlag);
+
+        if (Directory.Exists(outputDir))
+        {
+            Directory.Delete(outputDir, true);
+        }
+
+        Debug.LogFormat("寮�濮嬪鍑篈ndroid宸ョ▼锛岃緭鍑鸿矾寰�: {0}", outputDir);
+
+        BuildPipeline.BuildPlayer(baseLevels, outputDir, BuildTarget.Android,
+            _development ? BuildOptions.AcceptExternalModificationsToPlayer | BuildOptions.Development | BuildOptions.AllowDebugging
+                         : BuildOptions.AcceptExternalModificationsToPlayer);
+
+        Debug.LogFormat("瀵煎嚭Android宸ョ▼瀹屾垚锛佽緭鍑鸿矾寰�: {0}", outputDir);
+
+        // 瀵煎嚭瀹屾垚鍚庢仮澶嶈缃�
+        EditorUserBuildSettings.exportAsGoogleAndroidProject = false;
+        EditorUserBuildSettings.development = false;
+    }
+
+    /// <summary>
+    /// 灏忓寘鎷疯礉锛氫粎鎷疯礉builtin璧勬簮
+    /// </summary>
+    static void CopyNullAssetResources(string _assetBundlePath, string _streamingPath)
+    {
+        var files = new List<FileInfo>();
+        var builtInFiles = new List<FileInfo>();
+
+        FileExtersion.GetAllDirectoryFileInfos(_assetBundlePath, files);
+        foreach (var file in files)
+        {
+            if (file.FullName.Contains("builtin"))
+            {
+                builtInFiles.Add(file);
+            }
+        }
+
+        foreach (var item in builtInFiles)
+        {
+            var extension = Path.GetExtension(item.FullName);
+            if (extension == ".meta")
+                continue;
+
+            var relativePath = FileExtersion.GetFileRelativePath(_assetBundlePath, item.FullName);
+            var to = StringUtility.Concat(_streamingPath, relativePath);
+            var directory = Path.GetDirectoryName(to);
+            if (!Directory.Exists(directory))
+                Directory.CreateDirectory(directory);
+
+            File.Copy(item.FullName, to, true);
+        }
+    }
+
+    /// <summary>
+    /// 鍗婂寘鎷疯礉锛氭牴鎹甈riorBundleConfig鍓旈櫎浼樺厛绾т綆鐨刪ero/maps/audio/uieffect/video璧勬簮锛�
+    /// 浠ュ強config鍜寀i璧勬簮锛堝彇鍐充簬includeConfig/includeUI寮�鍏筹級
+    /// </summary>
+    static void CopyHalfAssetResources(string _assetBundlePath, string _streamingPath)
+    {
+        PriorBundleConfig.LazyInit();
+
+        var fromFiles = new List<FileInfo>();
+        FileExtersion.GetAllDirectoryFileInfos(_assetBundlePath, fromFiles);
+
+        var excludeFileFullNames = new List<string>();
+
+        // 鍓旈櫎浼樺厛绾т綆鐨刪ero璧勬簮
+        var tempFiles = new List<FileInfo>();
+        FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/hero"), tempFiles);
+        foreach (var file in tempFiles)
+        {
+            var fileName = Path.GetFileNameWithoutExtension(file.FullName);
+            var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Mob, AssetVersionUtility.DecodeFileName(fileName));
+            if (prior > AssetPrior)
+            {
+                excludeFileFullNames.Add(file.FullName);
+            }
+        }
+
+        // 鍓旈櫎浼樺厛绾т綆鐨刴aps璧勬簮
+        tempFiles.Clear();
+        FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/maps"), tempFiles);
+        foreach (var file in tempFiles)
+        {
+            var fileName = Path.GetFileNameWithoutExtension(file.FullName);
+            var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Scene, AssetVersionUtility.DecodeFileName(fileName));
+            if (prior > AssetPrior)
+            {
+                excludeFileFullNames.Add(file.FullName);
+            }
+        }
+
+        // 鍓旈櫎浼樺厛绾т綆鐨刟udio璧勬簮
+        tempFiles.Clear();
+        FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/audio"), tempFiles);
+        foreach (var file in tempFiles)
+        {
+            var fileName = Path.GetFileNameWithoutExtension(file.FullName);
+            var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Audio, AssetVersionUtility.DecodeFileName(fileName));
+            if (prior > AssetPrior)
+            {
+                excludeFileFullNames.Add(file.FullName);
+            }
+        }
+
+        // 鍓旈櫎浼樺厛绾т綆鐨剈ieffect璧勬簮
+        tempFiles.Clear();
+        FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/uieffect"), tempFiles);
+        foreach (var file in tempFiles)
+        {
+            var fileName = Path.GetFileNameWithoutExtension(file.FullName);
+            var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Effect, AssetVersionUtility.DecodeFileName(fileName));
+            if (prior > AssetPrior)
+            {
+                excludeFileFullNames.Add(file.FullName);
+            }
+        }
+
+        // 鍓旈櫎瑙嗛璧勬簮
+        tempFiles.Clear();
+        var videoPath = StringUtility.Concat(_assetBundlePath, "/video");
+        if (Directory.Exists(videoPath))
+        {
+            FileExtersion.GetAllDirectoryFileInfos(videoPath, tempFiles);
+            foreach (var file in tempFiles)
+            {
+                var fileName = Path.GetFileNameWithoutExtension(file.FullName);
+                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.Video, AssetVersionUtility.DecodeFileName(fileName));
+                if (prior > AssetPrior)
+                {
+                    excludeFileFullNames.Add(file.FullName);
+                }
+            }
+        }
+
+        // 鍓旈櫎琛ㄨ祫婧�
+        if (!includeConfig)
+        {
+            tempFiles.Clear();
+            FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/config"), tempFiles);
+            foreach (var file in tempFiles)
+            {
+                excludeFileFullNames.Add(file.FullName);
+            }
+        }
+
+        // 鍓旈櫎UI璧勬簮
+        if (!includeUI)
+        {
+            tempFiles.Clear();
+            FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/ui"), tempFiles);
+            foreach (var file in tempFiles)
+            {
+                excludeFileFullNames.Add(file.FullName);
+            }
+        }
+        else
+        {
+            tempFiles.Clear();
+            FileExtersion.GetAllDirectoryFileInfos(StringUtility.Concat(_assetBundlePath, "/ui"), tempFiles);
+            foreach (var file in tempFiles)
+            {
+                var fileName = Path.GetFileNameWithoutExtension(file.FullName);
+                var prior = PriorBundleConfig.GetAssetPrior(AssetVersion.AssetCategory.UI, fileName);
+                if (prior > AssetPrior)
+                {
+                    excludeFileFullNames.Add(file.FullName);
+                }
+            }
+        }
+
+        // 浠庢枃浠跺垪琛ㄤ腑绉婚櫎闇�瑕佹帓闄ょ殑鏂囦欢
+        for (int i = fromFiles.Count - 1; i >= 0; i--)
+        {
+            if (excludeFileFullNames.Contains(fromFiles[i].FullName))
+            {
+                fromFiles.RemoveAt(i);
+            }
+        }
+
+        foreach (var item in fromFiles)
+        {
+            var extension = Path.GetExtension(item.FullName);
+            if (extension == ".meta")
+                continue;
+
+            var relativePath = FileExtersion.GetFileRelativePath(_assetBundlePath, item.FullName);
+            if (relativePath.StartsWith("patch"))
+                continue;
+
+            var to = StringUtility.Concat(_streamingPath, relativePath);
+            var directory = Path.GetDirectoryName(to);
+            if (!Directory.Exists(directory))
+                Directory.CreateDirectory(directory);
+
+            File.Copy(item.FullName, to, true);
+        }
+    }
+
+    /// <summary>
+    /// 鍏ㄥ寘鎷疯礉锛氭嫹璐濇墍鏈夎祫婧愶紙鎺掗櫎patch鍜�.meta锛�
+    /// </summary>
+    static void CopyFullAssetResources(string _assetBundlePath, string _streamingPath)
+    {
+        var files = new List<FileInfo>();
+        FileExtersion.GetAllDirectoryFileInfos(_assetBundlePath, files);
+        foreach (var file in files)
+        {
+            var extension = Path.GetExtension(file.FullName);
+            if (extension == ".meta")
+                continue;
+
+            var relativePath = FileExtersion.GetFileRelativePath(_assetBundlePath, file.FullName);
+            if (relativePath.StartsWith("patch"))
+                continue;
+
+            var to = StringUtility.Concat(_streamingPath, relativePath);
+            var directory = Path.GetDirectoryName(to);
+            if (!Directory.Exists(directory))
+                Directory.CreateDirectory(directory);
+
+            File.Copy(file.FullName, to, true);
+        }
+    }
+
     public static void BuildIpa(string _sdkPath, string _publisher, int _buildIndex, bool _replace)
     {
         PreBuild(_publisher, _buildIndex);

--
Gitblit v1.8.0