using System; using System.IO; using System.Xml; using System.Text; using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace YooAsset.Editor { public class AssetBundleCollectorConfig { public const string ConfigVersion = "v2.1"; public const string XmlVersion = "Version"; public const string XmlCommon = "Common"; public const string XmlShowPackageView = "ShowPackageView"; public const string XmlShowEditorAlias = "ShowEditorAlias"; public const string XmlUniqueBundleName = "UniqueBundleName"; public const string XmlPackage = "Package"; public const string XmlPackageName = "PackageName"; public const string XmlPackageDesc = "PackageDesc"; public const string XmlEnableAddressable = "AutoAddressable"; public const string XmlLocationToLower = "LocationToLower"; public const string XmlIncludeAssetGUID = "IncludeAssetGUID"; public const string XmlIgnoreRuleName = "IgnoreRuleName"; public const string XmlGroup = "Group"; public const string XmlGroupActiveRule = "GroupActiveRule"; public const string XmlGroupName = "GroupName"; public const string XmlGroupDesc = "GroupDesc"; public const string XmlCollector = "Collector"; public const string XmlCollectPath = "CollectPath"; public const string XmlCollectorGUID = "CollectGUID"; public const string XmlCollectorType = "CollectType"; public const string XmlAddressRule = "AddressRule"; public const string XmlPackRule = "PackRule"; public const string XmlFilterRule = "FilterRule"; public const string XmlUserData = "UserData"; public const string XmlAssetTags = "AssetTags"; /// /// 导入XML配置表 /// public static void ImportXmlConfig(string filePath) { if (File.Exists(filePath) == false) throw new FileNotFoundException(filePath); if (Path.GetExtension(filePath) != ".xml") throw new Exception($"Only support xml : {filePath}"); // 加载配置文件 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(filePath); XmlElement root = xmlDoc.DocumentElement; // 读取配置版本 string configVersion = root.GetAttribute(XmlVersion); if (configVersion != ConfigVersion) { if (UpdateXmlConfig(xmlDoc) == false) throw new Exception($"The config version update failed : {configVersion} -> {ConfigVersion}"); else Debug.Log($"The config version update succeed : {configVersion} -> {ConfigVersion}"); } // 读取公共配置 bool uniqueBundleName = false; bool showPackageView = false; bool showEditorAlias = false; var commonNodeList = root.GetElementsByTagName(XmlCommon); if (commonNodeList.Count > 0) { XmlElement commonElement = commonNodeList[0] as XmlElement; if (commonElement.HasAttribute(XmlShowPackageView)) showPackageView = commonElement.GetAttribute(XmlShowPackageView) == "True" ? true : false; if (commonElement.HasAttribute(XmlShowEditorAlias)) showEditorAlias = commonElement.GetAttribute(XmlShowEditorAlias) == "True" ? true : false; if (commonElement.HasAttribute(XmlUniqueBundleName)) uniqueBundleName = commonElement.GetAttribute(XmlUniqueBundleName) == "True" ? true : false; } // 读取包裹配置 List packages = new List(); var packageNodeList = root.GetElementsByTagName(XmlPackage); foreach (var packageNode in packageNodeList) { XmlElement packageElement = packageNode as XmlElement; if (packageElement.HasAttribute(XmlPackageName) == false) throw new Exception($"Not found attribute {XmlPackageName} in {XmlPackage}"); if (packageElement.HasAttribute(XmlPackageDesc) == false) throw new Exception($"Not found attribute {XmlPackageDesc} in {XmlPackage}"); AssetBundleCollectorPackage package = new AssetBundleCollectorPackage(); package.PackageName = packageElement.GetAttribute(XmlPackageName); package.PackageDesc = packageElement.GetAttribute(XmlPackageDesc); package.EnableAddressable = packageElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false; package.LocationToLower = packageElement.GetAttribute(XmlLocationToLower) == "True" ? true : false; package.IncludeAssetGUID = packageElement.GetAttribute(XmlIncludeAssetGUID) == "True" ? true : false; package.IgnoreRuleName = packageElement.GetAttribute(XmlIgnoreRuleName); packages.Add(package); // 读取分组配置 var groupNodeList = packageElement.GetElementsByTagName(XmlGroup); foreach (var groupNode in groupNodeList) { XmlElement groupElement = groupNode as XmlElement; if (groupElement.HasAttribute(XmlGroupActiveRule) == false) throw new Exception($"Not found attribute {XmlGroupActiveRule} in {XmlGroup}"); if (groupElement.HasAttribute(XmlGroupName) == false) throw new Exception($"Not found attribute {XmlGroupName} in {XmlGroup}"); if (groupElement.HasAttribute(XmlGroupDesc) == false) throw new Exception($"Not found attribute {XmlGroupDesc} in {XmlGroup}"); if (groupElement.HasAttribute(XmlAssetTags) == false) throw new Exception($"Not found attribute {XmlAssetTags} in {XmlGroup}"); AssetBundleCollectorGroup group = new AssetBundleCollectorGroup(); group.ActiveRuleName = groupElement.GetAttribute(XmlGroupActiveRule); group.GroupName = groupElement.GetAttribute(XmlGroupName); group.GroupDesc = groupElement.GetAttribute(XmlGroupDesc); group.AssetTags = groupElement.GetAttribute(XmlAssetTags); package.Groups.Add(group); // 读取收集器配置 var collectorNodeList = groupElement.GetElementsByTagName(XmlCollector); foreach (var collectorNode in collectorNodeList) { XmlElement collectorElement = collectorNode as XmlElement; if (collectorElement.HasAttribute(XmlCollectPath) == false) throw new Exception($"Not found attribute {XmlCollectPath} in {XmlCollector}"); if (collectorElement.HasAttribute(XmlCollectorGUID) == false) throw new Exception($"Not found attribute {XmlCollectorGUID} in {XmlCollector}"); if (collectorElement.HasAttribute(XmlCollectorType) == false) throw new Exception($"Not found attribute {XmlCollectorType} in {XmlCollector}"); if (collectorElement.HasAttribute(XmlAddressRule) == false) throw new Exception($"Not found attribute {XmlAddressRule} in {XmlCollector}"); if (collectorElement.HasAttribute(XmlPackRule) == false) throw new Exception($"Not found attribute {XmlPackRule} in {XmlCollector}"); if (collectorElement.HasAttribute(XmlFilterRule) == false) throw new Exception($"Not found attribute {XmlFilterRule} in {XmlCollector}"); if (collectorElement.HasAttribute(XmlUserData) == false) throw new Exception($"Not found attribute {XmlUserData} in {XmlCollector}"); if (collectorElement.HasAttribute(XmlAssetTags) == false) throw new Exception($"Not found attribute {XmlAssetTags} in {XmlCollector}"); AssetBundleCollector collector = new AssetBundleCollector(); collector.CollectPath = collectorElement.GetAttribute(XmlCollectPath); collector.CollectorGUID = collectorElement.GetAttribute(XmlCollectorGUID); collector.CollectorType = EditorTools.NameToEnum(collectorElement.GetAttribute(XmlCollectorType)); collector.AddressRuleName = collectorElement.GetAttribute(XmlAddressRule); collector.PackRuleName = collectorElement.GetAttribute(XmlPackRule); collector.FilterRuleName = collectorElement.GetAttribute(XmlFilterRule); collector.UserData = collectorElement.GetAttribute(XmlUserData); collector.AssetTags = collectorElement.GetAttribute(XmlAssetTags); group.Collectors.Add(collector); } } } // 检测配置错误 foreach (var package in packages) { package.CheckConfigError(); } // 保存配置数据 AssetBundleCollectorSettingData.ClearAll(); AssetBundleCollectorSettingData.Setting.ShowPackageView = showPackageView; AssetBundleCollectorSettingData.Setting.ShowEditorAlias = showEditorAlias; AssetBundleCollectorSettingData.Setting.UniqueBundleName = uniqueBundleName; AssetBundleCollectorSettingData.Setting.Packages.AddRange(packages); AssetBundleCollectorSettingData.SaveFile(); Debug.Log($"Asset bundle collector config import complete!"); } /// /// 导出XML配置表 /// public static void ExportXmlConfig(string savePath) { if (File.Exists(savePath)) File.Delete(savePath); StringBuilder sb = new StringBuilder(); sb.AppendLine(""); sb.AppendLine(""); sb.AppendLine(""); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(sb.ToString()); XmlElement root = xmlDoc.DocumentElement; // 设置配置版本 root.SetAttribute(XmlVersion, ConfigVersion); // 设置公共配置 var commonElement = xmlDoc.CreateElement(XmlCommon); commonElement.SetAttribute(XmlShowPackageView, AssetBundleCollectorSettingData.Setting.ShowPackageView.ToString()); commonElement.SetAttribute(XmlShowEditorAlias, AssetBundleCollectorSettingData.Setting.ShowEditorAlias.ToString()); commonElement.SetAttribute(XmlUniqueBundleName, AssetBundleCollectorSettingData.Setting.UniqueBundleName.ToString()); root.AppendChild(commonElement); // 设置Package配置 foreach (var package in AssetBundleCollectorSettingData.Setting.Packages) { var packageElement = xmlDoc.CreateElement(XmlPackage); packageElement.SetAttribute(XmlPackageName, package.PackageName); packageElement.SetAttribute(XmlPackageDesc, package.PackageDesc); packageElement.SetAttribute(XmlEnableAddressable, package.EnableAddressable.ToString()); packageElement.SetAttribute(XmlLocationToLower, package.LocationToLower.ToString()); packageElement.SetAttribute(XmlIncludeAssetGUID, package.IncludeAssetGUID.ToString()); packageElement.SetAttribute(XmlIgnoreRuleName, package.IgnoreRuleName); root.AppendChild(packageElement); // 设置分组配置 foreach (var group in package.Groups) { var groupElement = xmlDoc.CreateElement(XmlGroup); groupElement.SetAttribute(XmlGroupActiveRule, group.ActiveRuleName); groupElement.SetAttribute(XmlGroupName, group.GroupName); groupElement.SetAttribute(XmlGroupDesc, group.GroupDesc); groupElement.SetAttribute(XmlAssetTags, group.AssetTags); packageElement.AppendChild(groupElement); // 设置收集器配置 foreach (var collector in group.Collectors) { var collectorElement = xmlDoc.CreateElement(XmlCollector); collectorElement.SetAttribute(XmlCollectPath, collector.CollectPath); collectorElement.SetAttribute(XmlCollectorGUID, collector.CollectorGUID); collectorElement.SetAttribute(XmlCollectorType, collector.CollectorType.ToString()); collectorElement.SetAttribute(XmlAddressRule, collector.AddressRuleName); collectorElement.SetAttribute(XmlPackRule, collector.PackRuleName); collectorElement.SetAttribute(XmlFilterRule, collector.FilterRuleName); collectorElement.SetAttribute(XmlUserData, collector.UserData); collectorElement.SetAttribute(XmlAssetTags, collector.AssetTags); groupElement.AppendChild(collectorElement); } } } // 生成配置文件 xmlDoc.Save(savePath); Debug.Log($"Asset bundle collector config export complete!"); } /// /// 升级XML配置表 /// private static bool UpdateXmlConfig(XmlDocument xmlDoc) { XmlElement root = xmlDoc.DocumentElement; string configVersion = root.GetAttribute(XmlVersion); if (configVersion == ConfigVersion) return true; // v2.0.0 -> v2.1 if (configVersion == "v2.0.0") { // 读取包裹配置 var packageNodeList = root.GetElementsByTagName(XmlPackage); foreach (var packageNode in packageNodeList) { XmlElement packageElement = packageNode as XmlElement; if (packageElement.HasAttribute(XmlIgnoreRuleName) == false) packageElement.SetAttribute(XmlIgnoreRuleName, nameof(NormalIgnoreRule)); } // 更新版本 root.SetAttribute(XmlVersion, "v2.1"); return UpdateXmlConfig(xmlDoc); } return false; } } }