Compare commits

..

10 Commits

Author SHA1 Message Date
何冠峰
0f73dc3047 update sample 2025-08-28 22:08:02 +08:00
何冠峰
a85e49c22a fix #625 2025-08-28 22:07:00 +08:00
何冠峰
6b291de922 fix #617 2025-08-28 19:02:08 +08:00
何冠峰
a4b1300195 fix #623 2025-08-28 10:40:13 +08:00
何冠峰
6f34951a74 refactor #627 2025-08-28 10:27:37 +08:00
何冠峰
c798250258 feat : CRC工具类增加获取整形值的方法 2025-08-27 19:19:00 +08:00
何冠峰
6fc82bb55a feat : 新增配置参数控制缓存文件验证最大并发数 2025-08-27 18:03:53 +08:00
何冠峰
c22cf5ffeb fix #620 2025-08-27 16:04:18 +08:00
何冠峰
36bc24f9fd fix #622 2025-08-27 10:29:13 +08:00
何冠峰
addb0ecdfe build #621 2025-08-27 10:27:12 +08:00
41 changed files with 366 additions and 131 deletions

View File

@@ -27,7 +27,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 文件哈希值 /// 文件哈希值
/// </summary> /// </summary>
public string PackageFileCRC { set; get; } public uint PackageFileCRC { set; get; }
/// <summary> /// <summary>
/// 文件哈希值 /// 文件哈希值

View File

@@ -32,6 +32,7 @@ namespace YooAsset.Editor
PackageManifest manifest = new PackageManifest(); PackageManifest manifest = new PackageManifest();
manifest.FileVersion = ManifestDefine.FileVersion; manifest.FileVersion = ManifestDefine.FileVersion;
manifest.EnableAddressable = buildMapContext.Command.EnableAddressable; manifest.EnableAddressable = buildMapContext.Command.EnableAddressable;
manifest.SupportExtensionless = buildMapContext.Command.SupportExtensionless;
manifest.LocationToLower = buildMapContext.Command.LocationToLower; manifest.LocationToLower = buildMapContext.Command.LocationToLower;
manifest.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID; manifest.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
manifest.OutputNameStyle = (int)buildParameters.FileNameStyle; manifest.OutputNameStyle = (int)buildParameters.FileNameStyle;

View File

@@ -32,6 +32,7 @@ namespace YooAsset.Editor
// 收集器配置 // 收集器配置
buildReport.Summary.UniqueBundleName = buildMapContext.Command.UniqueBundleName; buildReport.Summary.UniqueBundleName = buildMapContext.Command.UniqueBundleName;
buildReport.Summary.EnableAddressable = buildMapContext.Command.EnableAddressable; buildReport.Summary.EnableAddressable = buildMapContext.Command.EnableAddressable;
buildReport.Summary.SupportExtensionless = buildMapContext.Command.SupportExtensionless;
buildReport.Summary.LocationToLower = buildMapContext.Command.LocationToLower; buildReport.Summary.LocationToLower = buildMapContext.Command.LocationToLower;
buildReport.Summary.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID; buildReport.Summary.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
buildReport.Summary.AutoCollectShaders = buildMapContext.Command.AutoCollectShaders; buildReport.Summary.AutoCollectShaders = buildMapContext.Command.AutoCollectShaders;

View File

@@ -63,7 +63,7 @@ namespace YooAsset.Editor
protected abstract string GetUnityHash(BuildBundleInfo bundleInfo, BuildContext context); protected abstract string GetUnityHash(BuildBundleInfo bundleInfo, BuildContext context);
protected abstract uint GetUnityCRC(BuildBundleInfo bundleInfo, BuildContext context); protected abstract uint GetUnityCRC(BuildBundleInfo bundleInfo, BuildContext context);
protected abstract string GetBundleFileHash(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext); protected abstract string GetBundleFileHash(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext);
protected abstract string GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext); protected abstract uint GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext);
protected abstract long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext); protected abstract long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext);
} }
} }

View File

@@ -45,10 +45,10 @@ namespace YooAsset.Editor
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
return HashUtility.FileMD5(filePath); return HashUtility.FileMD5(filePath);
} }
protected override string GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext) protected override uint GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{ {
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
return HashUtility.FileCRC32(filePath); return HashUtility.FileCRC32Value(filePath);
} }
protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext) protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{ {

View File

@@ -12,6 +12,11 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public ECompressOption CompressOption = ECompressOption.Uncompressed; public ECompressOption CompressOption = ECompressOption.Uncompressed;
/// <summary>
/// 从文件头里剥离Unity版本信息
/// </summary>
public bool StripUnityVersion = false;
/// <summary> /// <summary>
/// 禁止写入类型树结构(可以降低包体和内存并提高加载效率) /// 禁止写入类型树结构(可以降低包体和内存并提高加载效率)
/// </summary> /// </summary>
@@ -41,6 +46,8 @@ namespace YooAsset.Editor
if (ClearBuildCacheFiles) if (ClearBuildCacheFiles)
opt |= BuildAssetBundleOptions.ForceRebuildAssetBundle; //Force rebuild the asset bundles opt |= BuildAssetBundleOptions.ForceRebuildAssetBundle; //Force rebuild the asset bundles
if (StripUnityVersion)
opt |= BuildAssetBundleOptions.AssetBundleStripUnityVersion; //Removes the Unity Version number in the Archive File & Serialized File headers
if (DisableWriteTypeTree) if (DisableWriteTypeTree)
opt |= BuildAssetBundleOptions.DisableWriteTypeTree; //Do not include type information within the asset bundle (don't write type tree). opt |= BuildAssetBundleOptions.DisableWriteTypeTree; //Do not include type information within the asset bundle (don't write type tree).
if (IgnoreTypeTreeChanges) if (IgnoreTypeTreeChanges)

View File

@@ -24,9 +24,9 @@ namespace YooAsset.Editor
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
return GetFilePathTempHash(filePath); return GetFilePathTempHash(filePath);
} }
protected override string GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext) protected override uint GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{ {
return "00000000"; //8位 return 0;
} }
protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext) protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{ {

View File

@@ -27,10 +27,10 @@ namespace YooAsset.Editor
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
return HashUtility.FileMD5(filePath); return HashUtility.FileMD5(filePath);
} }
protected override string GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext) protected override uint GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{ {
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
return HashUtility.FileCRC32(filePath); return HashUtility.FileCRC32Value(filePath);
} }
protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext) protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{ {

View File

@@ -45,10 +45,10 @@ namespace YooAsset.Editor
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
return HashUtility.FileMD5(filePath); return HashUtility.FileMD5(filePath);
} }
protected override string GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext) protected override uint GetBundleFileCRC(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{ {
string filePath = bundleInfo.PackageSourceFilePath; string filePath = bundleInfo.PackageSourceFilePath;
return HashUtility.FileCRC32(filePath); return HashUtility.FileCRC32Value(filePath);
} }
protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext) protected override long GetBundleFileSize(BuildBundleInfo bundleInfo, BuildParametersContext buildParametersContext)
{ {

View File

@@ -15,7 +15,7 @@ namespace YooAsset.Editor
public ECompressOption CompressOption = ECompressOption.Uncompressed; public ECompressOption CompressOption = ECompressOption.Uncompressed;
/// <summary> /// <summary>
/// 从AssetBundle文件头里剥离Unity版本信息 /// 从文件头里剥离Unity版本信息
/// </summary> /// </summary>
public bool StripUnityVersion = false; public bool StripUnityVersion = false;
@@ -25,7 +25,7 @@ namespace YooAsset.Editor
public bool DisableWriteTypeTree = false; public bool DisableWriteTypeTree = false;
/// <summary> /// <summary>
/// 忽略类型树变化 /// 忽略类型树变化(无效参数)
/// </summary> /// </summary>
public bool IgnoreTypeTreeChanges = true; public bool IgnoreTypeTreeChanges = true;
@@ -76,10 +76,9 @@ namespace YooAsset.Editor
throw new System.NotImplementedException(CompressOption.ToString()); throw new System.NotImplementedException(CompressOption.ToString());
if (StripUnityVersion) if (StripUnityVersion)
buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.StripUnityVersion; buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.StripUnityVersion; // Build Flag to indicate the Unity Version should not be written to the serialized file.
if (DisableWriteTypeTree) if (DisableWriteTypeTree)
buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.DisableWriteTypeTree; buildParams.ContentBuildFlags |= UnityEditor.Build.Content.ContentBuildFlags.DisableWriteTypeTree; //Do not include type information within the built content.
buildParams.UseCache = true; buildParams.UseCache = true;
buildParams.CacheServerHost = CacheServerHost; buildParams.CacheServerHost = CacheServerHost;

View File

@@ -139,13 +139,6 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public List<CollectAssetInfo> GetAllCollectAssets(CollectCommand command, AssetBundleCollectorGroup group) public List<CollectAssetInfo> GetAllCollectAssets(CollectCommand command, AssetBundleCollectorGroup group)
{ {
// 注意:模拟构建模式下只收集主资源
if (command.SimulateBuild)
{
if (CollectorType != ECollectorType.MainAssetCollector)
return new List<CollectAssetInfo>();
}
Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(1000); Dictionary<string, CollectAssetInfo> result = new Dictionary<string, CollectAssetInfo>(1000);
// 收集打包资源路径 // 收集打包资源路径

View File

@@ -10,7 +10,7 @@ namespace YooAsset.Editor
{ {
public class AssetBundleCollectorConfig public class AssetBundleCollectorConfig
{ {
public const string ConfigVersion = "v2.1"; public const string ConfigVersion = "v2025.8.28";
public const string XmlVersion = "Version"; public const string XmlVersion = "Version";
public const string XmlCommon = "Common"; public const string XmlCommon = "Common";
@@ -23,6 +23,7 @@ namespace YooAsset.Editor
public const string XmlPackageName = "PackageName"; public const string XmlPackageName = "PackageName";
public const string XmlPackageDesc = "PackageDesc"; public const string XmlPackageDesc = "PackageDesc";
public const string XmlEnableAddressable = "AutoAddressable"; public const string XmlEnableAddressable = "AutoAddressable";
public const string XmlSupportExtensionless = "SupportExtensionless";
public const string XmlLocationToLower = "LocationToLower"; public const string XmlLocationToLower = "LocationToLower";
public const string XmlIncludeAssetGUID = "IncludeAssetGUID"; public const string XmlIncludeAssetGUID = "IncludeAssetGUID";
public const string XmlIgnoreRuleName = "IgnoreRuleName"; public const string XmlIgnoreRuleName = "IgnoreRuleName";
@@ -99,6 +100,7 @@ namespace YooAsset.Editor
package.PackageName = packageElement.GetAttribute(XmlPackageName); package.PackageName = packageElement.GetAttribute(XmlPackageName);
package.PackageDesc = packageElement.GetAttribute(XmlPackageDesc); package.PackageDesc = packageElement.GetAttribute(XmlPackageDesc);
package.EnableAddressable = packageElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false; package.EnableAddressable = packageElement.GetAttribute(XmlEnableAddressable) == "True" ? true : false;
package.SupportExtensionless = packageElement.GetAttribute(XmlSupportExtensionless) == "True" ? true : false;
package.LocationToLower = packageElement.GetAttribute(XmlLocationToLower) == "True" ? true : false; package.LocationToLower = packageElement.GetAttribute(XmlLocationToLower) == "True" ? true : false;
package.IncludeAssetGUID = packageElement.GetAttribute(XmlIncludeAssetGUID) == "True" ? true : false; package.IncludeAssetGUID = packageElement.GetAttribute(XmlIncludeAssetGUID) == "True" ? true : false;
package.IgnoreRuleName = packageElement.GetAttribute(XmlIgnoreRuleName); package.IgnoreRuleName = packageElement.GetAttribute(XmlIgnoreRuleName);
@@ -211,6 +213,7 @@ namespace YooAsset.Editor
packageElement.SetAttribute(XmlPackageName, package.PackageName); packageElement.SetAttribute(XmlPackageName, package.PackageName);
packageElement.SetAttribute(XmlPackageDesc, package.PackageDesc); packageElement.SetAttribute(XmlPackageDesc, package.PackageDesc);
packageElement.SetAttribute(XmlEnableAddressable, package.EnableAddressable.ToString()); packageElement.SetAttribute(XmlEnableAddressable, package.EnableAddressable.ToString());
packageElement.SetAttribute(XmlSupportExtensionless, package.SupportExtensionless.ToString());
packageElement.SetAttribute(XmlLocationToLower, package.LocationToLower.ToString()); packageElement.SetAttribute(XmlLocationToLower, package.LocationToLower.ToString());
packageElement.SetAttribute(XmlIncludeAssetGUID, package.IncludeAssetGUID.ToString()); packageElement.SetAttribute(XmlIncludeAssetGUID, package.IncludeAssetGUID.ToString());
packageElement.SetAttribute(XmlIgnoreRuleName, package.IgnoreRuleName); packageElement.SetAttribute(XmlIgnoreRuleName, package.IgnoreRuleName);
@@ -275,6 +278,23 @@ namespace YooAsset.Editor
return UpdateXmlConfig(xmlDoc); return UpdateXmlConfig(xmlDoc);
} }
// v2.1 -> v2025.8.28
if (configVersion == "v2.1")
{
// 读取包裹配置
var packageNodeList = root.GetElementsByTagName(XmlPackage);
foreach (var packageNode in packageNodeList)
{
XmlElement packageElement = packageNode as XmlElement;
if (packageElement.HasAttribute(XmlSupportExtensionless) == false)
packageElement.SetAttribute(XmlSupportExtensionless, "True");
}
// 更新版本
root.SetAttribute(XmlVersion, "v2025.8.28");
return UpdateXmlConfig(xmlDoc);
}
return false; return false;
} }
} }

View File

@@ -25,6 +25,11 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool EnableAddressable = false; public bool EnableAddressable = false;
/// <summary>
/// 支持无后缀名的资源定位地址
/// </summary>
public bool SupportExtensionless = true;
/// <summary> /// <summary>
/// 资源定位地址大小写不敏感 /// 资源定位地址大小写不敏感
/// </summary> /// </summary>

View File

@@ -111,6 +111,7 @@ namespace YooAsset.Editor
command.UniqueBundleName = UniqueBundleName; command.UniqueBundleName = UniqueBundleName;
command.UseAssetDependencyDB = useAssetDependencyDB; command.UseAssetDependencyDB = useAssetDependencyDB;
command.EnableAddressable = package.EnableAddressable; command.EnableAddressable = package.EnableAddressable;
command.SupportExtensionless = package.SupportExtensionless;
command.LocationToLower = package.LocationToLower; command.LocationToLower = package.LocationToLower;
command.IncludeAssetGUID = package.IncludeAssetGUID; command.IncludeAssetGUID = package.IncludeAssetGUID;
command.AutoCollectShaders = package.AutoCollectShaders; command.AutoCollectShaders = package.AutoCollectShaders;

View File

@@ -38,6 +38,7 @@ namespace YooAsset.Editor
private VisualElement _setting2Container; private VisualElement _setting2Container;
private Toggle _enableAddressableToogle; private Toggle _enableAddressableToogle;
private Toggle _supportExtensionlessToogle;
private Toggle _locationToLowerToogle; private Toggle _locationToLowerToogle;
private Toggle _includeAssetGUIDToogle; private Toggle _includeAssetGUIDToogle;
private Toggle _autoCollectShadersToogle; private Toggle _autoCollectShadersToogle;
@@ -131,6 +132,17 @@ namespace YooAsset.Editor
RefreshWindow(); RefreshWindow();
} }
}); });
_supportExtensionlessToogle = root.Q<Toggle>("SupportExtensionless");
_supportExtensionlessToogle.RegisterValueChangedCallback(evt =>
{
var selectPackage = _packageListView.selectedItem as AssetBundleCollectorPackage;
if (selectPackage != null)
{
selectPackage.SupportExtensionless = evt.newValue;
AssetBundleCollectorSettingData.ModifyPackage(selectPackage);
RefreshWindow();
}
});
_locationToLowerToogle = root.Q<Toggle>("LocationToLower"); _locationToLowerToogle = root.Q<Toggle>("LocationToLower");
_locationToLowerToogle.RegisterValueChangedCallback(evt => _locationToLowerToogle.RegisterValueChangedCallback(evt =>
{ {
@@ -487,6 +499,7 @@ namespace YooAsset.Editor
_packageSettingsButton.SetEnabled(true); _packageSettingsButton.SetEnabled(true);
_packageSettingsButton.text = $"{packageSettingName} ({selectPackage.PackageName})"; _packageSettingsButton.text = $"{packageSettingName} ({selectPackage.PackageName})";
_enableAddressableToogle.SetValueWithoutNotify(selectPackage.EnableAddressable); _enableAddressableToogle.SetValueWithoutNotify(selectPackage.EnableAddressable);
_supportExtensionlessToogle.SetValueWithoutNotify(selectPackage.SupportExtensionless);
_locationToLowerToogle.SetValueWithoutNotify(selectPackage.LocationToLower); _locationToLowerToogle.SetValueWithoutNotify(selectPackage.LocationToLower);
_includeAssetGUIDToogle.SetValueWithoutNotify(selectPackage.IncludeAssetGUID); _includeAssetGUIDToogle.SetValueWithoutNotify(selectPackage.IncludeAssetGUID);
_autoCollectShadersToogle.SetValueWithoutNotify(selectPackage.AutoCollectShaders); _autoCollectShadersToogle.SetValueWithoutNotify(selectPackage.AutoCollectShaders);
@@ -831,7 +844,7 @@ namespace YooAsset.Editor
var foldout = new Foldout(); var foldout = new Foldout();
foldout.name = "Foldout1"; foldout.name = "Foldout1";
foldout.value = false; foldout.value = false;
foldout.text = "Main Assets"; foldout.text = "Assets";
elementFoldout.Add(foldout); elementFoldout.Add(foldout);
} }
@@ -864,11 +877,9 @@ namespace YooAsset.Editor
var foldout = element.Q<Foldout>("Foldout1"); var foldout = element.Q<Foldout>("Foldout1");
foldout.RegisterValueChangedCallback(evt => foldout.RegisterValueChangedCallback(evt =>
{ {
if (evt.newValue) RefreshFoldoutContent(foldout, selectGroup, collector);
RefreshFoldout(foldout, selectGroup, collector);
else
foldout.Clear();
}); });
RefreshFoldoutName(foldout, collector.CollectorType);
// Remove Button // Remove Button
var removeBtn = element.Q<Button>("Button1"); var removeBtn = element.Q<Button>("Button1");
@@ -885,10 +896,7 @@ namespace YooAsset.Editor
collector.CollectPath = AssetDatabase.GetAssetPath(evt.newValue); collector.CollectPath = AssetDatabase.GetAssetPath(evt.newValue);
collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath); collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) RefreshFoldoutContent(foldout, selectGroup, collector);
{
RefreshFoldout(foldout, selectGroup, collector);
}
}); });
UIElementsTools.RefreshObjectFieldShowPath(objectField1); UIElementsTools.RefreshObjectFieldShowPath(objectField1);
@@ -899,10 +907,7 @@ namespace YooAsset.Editor
{ {
collector.CollectorType = EditorTools.NameToEnum<ECollectorType>(evt.newValue); collector.CollectorType = EditorTools.NameToEnum<ECollectorType>(evt.newValue);
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) RefreshFoldoutContent(foldout, selectGroup, collector);
{
RefreshFoldout(foldout, selectGroup, collector);
}
if (collector.CollectorType == ECollectorType.MainAssetCollector) if (collector.CollectorType == ECollectorType.MainAssetCollector)
textTags.SetEnabled(true); textTags.SetEnabled(true);
@@ -921,10 +926,7 @@ namespace YooAsset.Editor
{ {
collector.AddressRuleName = evt.newValue.ClassName; collector.AddressRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) RefreshFoldoutContent(foldout, selectGroup, collector);
{
RefreshFoldout(foldout, selectGroup, collector);
}
}); });
} }
@@ -937,10 +939,7 @@ namespace YooAsset.Editor
{ {
collector.PackRuleName = evt.newValue.ClassName; collector.PackRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) RefreshFoldoutContent(foldout, selectGroup, collector);
{
RefreshFoldout(foldout, selectGroup, collector);
}
}); });
// Filter Rule // Filter Rule
@@ -952,10 +951,7 @@ namespace YooAsset.Editor
{ {
collector.FilterRuleName = evt.newValue.ClassName; collector.FilterRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value) RefreshFoldoutContent(foldout, selectGroup, collector);
{
RefreshFoldout(foldout, selectGroup, collector);
}
}); });
// UserData // UserData
@@ -976,61 +972,101 @@ namespace YooAsset.Editor
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector); AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
}); });
} }
private void RefreshFoldout(Foldout foldout, AssetBundleCollectorGroup group, AssetBundleCollector collector) private void RefreshFoldoutName(Foldout foldout, ECollectorType collectorType, int elementNumber = -1)
{ {
if (collectorType == ECollectorType.MainAssetCollector)
{
if (elementNumber >= 0)
foldout.text = $"Main Assets ({elementNumber})";
else
foldout.text = $"Main Assets";
}
else if (collectorType == ECollectorType.StaticAssetCollector)
{
if (elementNumber >= 0)
foldout.text = $"Static Assets ({elementNumber})";
else
foldout.text = $"Static Assets";
}
else if (collectorType == ECollectorType.DependAssetCollector)
{
if (elementNumber >= 0)
foldout.text = $"Depend Assets ({elementNumber})";
else
foldout.text = $"Depend Assets";
}
else
{
throw new System.NotImplementedException(collectorType.ToString());
}
}
private void RefreshFoldoutContent(Foldout foldout, AssetBundleCollectorGroup group, AssetBundleCollector collector)
{
RefreshFoldoutName(foldout, collector.CollectorType);
// 折叠栏不可见
if (foldout.value == false)
{
foldout.Clear();
return;
}
// 清空旧元素 // 清空旧元素
foldout.Clear(); foldout.Clear();
// 检测配置是否有效
if (collector.IsValid() == false) if (collector.IsValid() == false)
{ {
collector.CheckConfigError(); collector.CheckConfigError();
return; return;
} }
if (collector.CollectorType == ECollectorType.MainAssetCollector || collector.CollectorType == ECollectorType.StaticAssetCollector) List<CollectAssetInfo> collectAssetInfos = null;
try
{ {
List<CollectAssetInfo> collectAssetInfos = null; IIgnoreRule ignoreRule = AssetBundleCollectorSettingData.GetIgnoreRuleInstance(_ignoreRulePopupField.value.ClassName);
string packageName = _packageNameTxt.value;
var command = new CollectCommand(packageName, ignoreRule);
command.SimulateBuild = true;
command.UniqueBundleName = _uniqueBundleNameToogle.value;
command.EnableAddressable = _enableAddressableToogle.value;
command.SupportExtensionless = _supportExtensionlessToogle.value;
command.LocationToLower = _locationToLowerToogle.value;
command.IncludeAssetGUID = _includeAssetGUIDToogle.value;
command.AutoCollectShaders = _autoCollectShadersToogle.value;
try collector.CheckConfigError();
collectAssetInfos = collector.GetAllCollectAssets(command, group);
}
catch (System.Exception e)
{
Debug.LogError(e.ToString());
}
if (collectAssetInfos != null)
{
bool showAdress = false;
if (_enableAddressableToogle.value && collector.CollectorType == ECollectorType.MainAssetCollector)
showAdress = true;
RefreshFoldoutName(foldout, collector.CollectorType, collectAssetInfos.Count);
foreach (var collectAsset in collectAssetInfos)
{ {
IIgnoreRule ignoreRule = AssetBundleCollectorSettingData.GetIgnoreRuleInstance(_ignoreRulePopupField.value.ClassName); VisualElement elementRow = new VisualElement();
string packageName = _packageNameTxt.value; elementRow.style.flexDirection = FlexDirection.Row;
var command = new CollectCommand(packageName, ignoreRule); foldout.Add(elementRow);
command.SimulateBuild = true;
command.UniqueBundleName = _uniqueBundleNameToogle.value;
command.UseAssetDependencyDB = true;
command.EnableAddressable = _enableAddressableToogle.value;
command.LocationToLower = _locationToLowerToogle.value;
command.IncludeAssetGUID = _includeAssetGUIDToogle.value;
command.AutoCollectShaders = _autoCollectShadersToogle.value;
collector.CheckConfigError(); string showInfo = collectAsset.AssetInfo.AssetPath;
collectAssetInfos = collector.GetAllCollectAssets(command, group); if (showAdress)
} showInfo = $"[{collectAsset.Address}] {collectAsset.AssetInfo.AssetPath}";
catch (System.Exception e)
{
Debug.LogError(e.ToString());
}
if (collectAssetInfos != null) var label = new Label();
{ label.text = showInfo;
foreach (var collectAsset in collectAssetInfos) label.style.width = 300;
{ label.style.marginLeft = 0;
VisualElement elementRow = new VisualElement(); label.style.flexGrow = 1;
elementRow.style.flexDirection = FlexDirection.Row; elementRow.Add(label);
foldout.Add(elementRow);
string showInfo = collectAsset.AssetInfo.AssetPath;
if (_enableAddressableToogle.value)
showInfo = $"[{collectAsset.Address}] {collectAsset.AssetInfo.AssetPath}";
var label = new Label();
label.text = showInfo;
label.style.width = 300;
label.style.marginLeft = 0;
label.style.flexGrow = 1;
elementRow.Add(label);
}
} }
} }
} }

View File

@@ -19,6 +19,7 @@
<ui:Button text="Package Settings" display-tooltip-when-elided="true" name="PackageSettingsButton" /> <ui:Button text="Package Settings" display-tooltip-when-elided="true" name="PackageSettingsButton" />
<ui:VisualElement name="PublicContainer2"> <ui:VisualElement name="PublicContainer2">
<ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" /> <ui:Toggle label="Enable Addressable" name="EnableAddressable" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Support Extensionless" name="SupportExtensionless" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Location To Lower" name="LocationToLower" style="width: 196px; -unity-text-align: middle-left;" /> <ui:Toggle label="Location To Lower" name="LocationToLower" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Include Asset GUID" name="IncludeAssetGUID" style="width: 196px; -unity-text-align: middle-left;" /> <ui:Toggle label="Include Asset GUID" name="IncludeAssetGUID" style="width: 196px; -unity-text-align: middle-left;" />
<ui:Toggle label="Auto Collect Shaders" name="AutoCollectShaders" value="true" style="width: 196px; -unity-text-align: middle-left;" /> <ui:Toggle label="Auto Collect Shaders" name="AutoCollectShaders" value="true" style="width: 196px; -unity-text-align: middle-left;" />

View File

@@ -34,6 +34,11 @@ namespace YooAsset.Editor
/// </summary> /// </summary>
public bool EnableAddressable { set; get; } public bool EnableAddressable { set; get; }
/// <summary>
/// 支持无后缀名的资源定位地址
/// </summary>
public bool SupportExtensionless { set; get; }
/// <summary> /// <summary>
/// 资源定位地址大小写不敏感 /// 资源定位地址大小写不敏感
/// </summary> /// </summary>

View File

@@ -26,7 +26,7 @@ namespace YooAsset.Editor
/// <summary> /// <summary>
/// 文件校验码 /// 文件校验码
/// </summary> /// </summary>
public string FileCRC; public uint FileCRC;
/// <summary> /// <summary>
/// 文件大小(字节数) /// 文件大小(字节数)

View File

@@ -61,6 +61,7 @@ namespace YooAsset.Editor
// 收集器配置 // 收集器配置
public bool UniqueBundleName; public bool UniqueBundleName;
public bool EnableAddressable; public bool EnableAddressable;
public bool SupportExtensionless;
public bool LocationToLower; public bool LocationToLower;
public bool IncludeAssetGUID; public bool IncludeAssetGUID;
public bool AutoCollectShaders; public bool AutoCollectShaders;

View File

@@ -55,6 +55,7 @@ namespace YooAsset.Editor
BindListViewHeader("Collect Settings"); BindListViewHeader("Collect Settings");
BindListViewItem("Unique Bundle Name", $"{buildReport.Summary.UniqueBundleName}"); BindListViewItem("Unique Bundle Name", $"{buildReport.Summary.UniqueBundleName}");
BindListViewItem("Enable Addressable", $"{buildReport.Summary.EnableAddressable}"); BindListViewItem("Enable Addressable", $"{buildReport.Summary.EnableAddressable}");
BindListViewItem("Support Extensionless", $"{buildReport.Summary.SupportExtensionless}");
BindListViewItem("Location To Lower", $"{buildReport.Summary.LocationToLower}"); BindListViewItem("Location To Lower", $"{buildReport.Summary.LocationToLower}");
BindListViewItem("Include Asset GUID", $"{buildReport.Summary.IncludeAssetGUID}"); BindListViewItem("Include Asset GUID", $"{buildReport.Summary.IncludeAssetGUID}");
BindListViewItem("Auto Collect Shaders", $"{buildReport.Summary.AutoCollectShaders}"); BindListViewItem("Auto Collect Shaders", $"{buildReport.Summary.AutoCollectShaders}");

View File

@@ -43,11 +43,11 @@ namespace YooAsset
// 说明AppleTV对应的是tvOS系统。 // 说明AppleTV对应的是tvOS系统。
#if UNITY_EDITOR_OSX #if UNITY_EDITOR_OSX
url = StringUtility.Format("file://{0}", path); url = StringUtility.Format("file://{0}", path);
#elif UNITY_EDITOR #elif UNITY_EDITOR_WIN
url = StringUtility.Format("file:///{0}", path); url = StringUtility.Format("file:///{0}", path);
#elif UNITY_WEBGL #elif UNITY_WEBGL
url = path; url = path;
#elif UNITY_IPHONE #elif UNITY_IOS || UNITY_IPHONE
url = StringUtility.Format("file://{0}", path); url = StringUtility.Format("file://{0}", path);
#elif UNITY_ANDROID #elif UNITY_ANDROID
if (path.StartsWith("jar:file://")) if (path.StartsWith("jar:file://"))
@@ -69,12 +69,17 @@ namespace YooAsset
else else
url = StringUtility.Format("file://{0}", path); url = StringUtility.Format("file://{0}", path);
} }
#elif UNITY_STANDALONE_OSX
url = new System.Uri(path).ToString(); #elif UNITY_WSA
#elif UNITY_STANDALONE || UNITY_WSA
url = StringUtility.Format("file:///{0}", path); url = StringUtility.Format("file:///{0}", path);
#elif UNITY_TVOS #elif UNITY_TVOS
url = StringUtility.Format("file:///{0}", path); url = StringUtility.Format("file:///{0}", path);
#elif UNITY_STANDALONE_OSX
url = new System.Uri(path).ToString();
#elif UNITY_STANDALONE_WIN
url = StringUtility.Format("file:///{0}", path);
#elif UNITY_STANDALONE_LINUX
url = StringUtility.Format("file:///root/{0}", path);
#else #else
throw new System.NotImplementedException(); throw new System.NotImplementedException();
#endif #endif

View File

@@ -53,15 +53,20 @@ namespace YooAsset
} }
#region #region
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
/// <summary> /// <summary>
/// 自定义参数:初始化的时候缓存文件校验级别 /// 自定义参数:初始化的时候缓存文件校验级别
/// </summary> /// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle; public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
/// <summary> /// <summary>
/// 自定义参数:覆盖安装缓存清理模式 /// 自定义参数:初始化的时候缓存文件校验最大并发数
/// </summary> /// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles; public int FileVerifyMaxConcurrency { private set; get; } = int.MaxValue;
/// <summary> /// <summary>
/// 自定义参数:数据文件追加文件格式 /// 自定义参数:数据文件追加文件格式
@@ -156,13 +161,18 @@ namespace YooAsset
public virtual void SetParameter(string name, object value) public virtual void SetParameter(string name, object value)
{ {
if (name == FileSystemParametersDefine.FILE_VERIFY_LEVEL) if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EOverwriteInstallClearMode)value;
}
else if (name == FileSystemParametersDefine.FILE_VERIFY_LEVEL)
{ {
FileVerifyLevel = (EFileVerifyLevel)value; FileVerifyLevel = (EFileVerifyLevel)value;
} }
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE) else if (name == FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY)
{ {
InstallClearMode = (EOverwriteInstallClearMode)value; int convertValue = Convert.ToInt32(value);
FileVerifyMaxConcurrency = Math.Clamp(convertValue, 1, int.MaxValue);
} }
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION) else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
{ {
@@ -210,8 +220,9 @@ namespace YooAsset
var remoteServices = new DefaultUnpackRemoteServices(_packageRoot); var remoteServices = new DefaultUnpackRemoteServices(_packageRoot);
_unpackFileSystem = new DefaultUnpackFileSystem(); _unpackFileSystem = new DefaultUnpackFileSystem();
_unpackFileSystem.SetParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices); _unpackFileSystem.SetParameter(FileSystemParametersDefine.REMOTE_SERVICES, remoteServices);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, InstallClearMode); _unpackFileSystem.SetParameter(FileSystemParametersDefine.INSTALL_CLEAR_MODE, InstallClearMode);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_LEVEL, FileVerifyLevel);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY, FileVerifyMaxConcurrency);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension); _unpackFileSystem.SetParameter(FileSystemParametersDefine.APPEND_FILE_EXTENSION, AppendFileExtension);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, DecryptionServices); _unpackFileSystem.SetParameter(FileSystemParametersDefine.DECRYPTION_SERVICES, DecryptionServices);
_unpackFileSystem.SetParameter(FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices); _unpackFileSystem.SetParameter(FileSystemParametersDefine.COPY_LOCAL_FILE_SERVICES, CopyLocalFileServices);
@@ -343,7 +354,7 @@ namespace YooAsset
if (Belong(bundle) == false) if (Belong(bundle) == false)
return false; return false;
#if UNITY_ANDROID #if UNITY_ANDROID || UNITY_OPENHARMONY
if (bundle.Encrypted) if (bundle.Encrypted)
return true; return true;

View File

@@ -60,15 +60,20 @@ namespace YooAsset
/// </summary> /// </summary>
public IRemoteServices RemoteServices { private set; get; } public IRemoteServices RemoteServices { private set; get; }
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
/// <summary> /// <summary>
/// 自定义参数:初始化的时候缓存文件校验级别 /// 自定义参数:初始化的时候缓存文件校验级别
/// </summary> /// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle; public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
/// <summary> /// <summary>
/// 自定义参数:覆盖安装缓存清理模式 /// 自定义参数:初始化的时候缓存文件校验最大并发数
/// </summary> /// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles; public int FileVerifyMaxConcurrency { private set; get; } = int.MaxValue;
/// <summary> /// <summary>
/// 自定义参数:数据文件追加文件格式 /// 自定义参数:数据文件追加文件格式
@@ -215,13 +220,18 @@ namespace YooAsset
{ {
RemoteServices = (IRemoteServices)value; RemoteServices = (IRemoteServices)value;
} }
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EOverwriteInstallClearMode)value;
}
else if (name == FileSystemParametersDefine.FILE_VERIFY_LEVEL) else if (name == FileSystemParametersDefine.FILE_VERIFY_LEVEL)
{ {
FileVerifyLevel = (EFileVerifyLevel)value; FileVerifyLevel = (EFileVerifyLevel)value;
} }
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE) else if (name == FileSystemParametersDefine.FILE_VERIFY_MAX_CONCURRENCY)
{ {
InstallClearMode = (EOverwriteInstallClearMode)value; int convertValue = Convert.ToInt32(value);
FileVerifyMaxConcurrency = Math.Clamp(convertValue, 1, int.MaxValue);
} }
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION) else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
{ {
@@ -233,11 +243,13 @@ namespace YooAsset
} }
else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY) else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY)
{ {
DownloadMaxConcurrency = Convert.ToInt32(value); int convertValue = Convert.ToInt32(value);
DownloadMaxConcurrency = Math.Clamp(convertValue, 1, int.MaxValue);
} }
else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME) else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME)
{ {
DownloadMaxRequestPerFrame = Convert.ToInt32(value); int convertValue = Convert.ToInt32(value);
DownloadMaxRequestPerFrame = Math.Clamp(convertValue, 1, int.MaxValue);
} }
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE) else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE)
{ {
@@ -493,22 +505,22 @@ namespace YooAsset
} }
private readonly BufferWriter _sharedBuffer = new BufferWriter(1024); private readonly BufferWriter _sharedBuffer = new BufferWriter(1024);
public void WriteBundleInfoFile(string filePath, string dataFileCRC, long dataFileSize) public void WriteBundleInfoFile(string filePath, uint dataFileCRC, long dataFileSize)
{ {
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read)) using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{ {
_sharedBuffer.Clear(); _sharedBuffer.Clear();
_sharedBuffer.WriteUTF8(dataFileCRC); _sharedBuffer.WriteUInt32(dataFileCRC);
_sharedBuffer.WriteInt64(dataFileSize); _sharedBuffer.WriteInt64(dataFileSize);
_sharedBuffer.WriteToStream(fs); _sharedBuffer.WriteToStream(fs);
fs.Flush(); fs.Flush();
} }
} }
public void ReadBundleInfoFile(string filePath, out string dataFileCRC, out long dataFileSize) public void ReadBundleInfoFile(string filePath, out uint dataFileCRC, out long dataFileSize)
{ {
byte[] binaryData = FileUtility.ReadAllBytes(filePath); byte[] binaryData = FileUtility.ReadAllBytes(filePath);
BufferReader buffer = new BufferReader(binaryData); BufferReader buffer = new BufferReader(binaryData);
dataFileCRC = buffer.ReadUTF8(); dataFileCRC = buffer.ReadUInt32();
dataFileSize = buffer.ReadInt64(); dataFileSize = buffer.ReadInt64();
} }
#endregion #endregion

View File

@@ -7,10 +7,10 @@ namespace YooAsset
{ {
public string InfoFilePath { private set; get; } public string InfoFilePath { private set; get; }
public string DataFilePath { private set; get; } public string DataFilePath { private set; get; }
public string DataFileCRC { private set; get; } public uint DataFileCRC { private set; get; }
public long DataFileSize { private set; get; } public long DataFileSize { private set; get; }
public RecordFileElement(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize) public RecordFileElement(string infoFilePath, string dataFilePath, uint dataFileCRC, long dataFileSize)
{ {
InfoFilePath = infoFilePath; InfoFilePath = infoFilePath;
DataFilePath = dataFilePath; DataFilePath = dataFilePath;

View File

@@ -4,7 +4,7 @@ namespace YooAsset
internal class TempFileElement internal class TempFileElement
{ {
public string TempFilePath { private set; get; } public string TempFilePath { private set; get; }
public string TempFileCRC { private set; get; } public uint TempFileCRC { private set; get; }
public long TempFileSize { private set; get; } public long TempFileSize { private set; get; }
/// <summary> /// <summary>
@@ -12,7 +12,7 @@ namespace YooAsset
/// </summary> /// </summary>
public volatile int Result = 0; public volatile int Result = 0;
public TempFileElement(string filePath, string fileCRC, long fileSize) public TempFileElement(string filePath, uint fileCRC, long fileSize)
{ {
TempFilePath = filePath; TempFilePath = filePath;
TempFileCRC = fileCRC; TempFileCRC = fileCRC;

View File

@@ -10,7 +10,7 @@ namespace YooAsset
public string DataFilePath { private set; get; } public string DataFilePath { private set; get; }
public string InfoFilePath { private set; get; } public string InfoFilePath { private set; get; }
public string DataFileCRC; public uint DataFileCRC;
public long DataFileSize; public long DataFileSize;
/// <summary> /// <summary>

View File

@@ -54,11 +54,13 @@ namespace YooAsset
// 设置同时验证的最大数 // 设置同时验证的最大数
ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads); ThreadPool.GetMaxThreads(out int workerThreads, out int ioThreads);
YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}"); YooLogger.Log($"Work threads : {workerThreads}, IO threads : {ioThreads}");
_verifyMaxNum = Math.Min(workerThreads, ioThreads); int threads = Math.Min(workerThreads, ioThreads);
_verifyMaxNum = Math.Min(threads, _fileSystem.FileVerifyMaxConcurrency);
_verifyTotalCount = fileCount; _verifyTotalCount = fileCount;
if (_verifyMaxNum < 1) if (_verifyMaxNum < 1)
_verifyMaxNum = 1; _verifyMaxNum = 1;
YooLogger.Log($"Verify max concurrency : {_verifyMaxNum}");
_verifyingList = new List<VerifyFileElement>(_verifyMaxNum); _verifyingList = new List<VerifyFileElement>(_verifyMaxNum);
_steps = ESteps.UpdateVerify; _steps = ESteps.UpdateVerify;
} }

View File

@@ -4,6 +4,7 @@ namespace YooAsset
public class FileSystemParametersDefine public class FileSystemParametersDefine
{ {
public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL"; public const string FILE_VERIFY_LEVEL = "FILE_VERIFY_LEVEL";
public const string FILE_VERIFY_MAX_CONCURRENCY = "FILE_VERIFY_MAX_CONCURRENCY";
public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE"; public const string INSTALL_CLEAR_MODE = "INSTALL_CLEAR_MODE";
public const string REMOTE_SERVICES = "REMOTE_SERVICES"; public const string REMOTE_SERVICES = "REMOTE_SERVICES";
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES"; public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES";

View File

@@ -8,7 +8,7 @@ namespace YooAsset
/// <summary> /// <summary>
/// 文件校验 /// 文件校验
/// </summary> /// </summary>
public static EFileVerifyResult FileVerify(string filePath, long fileSize, string fileCRC, EFileVerifyLevel verifyLevel) public static EFileVerifyResult FileVerify(string filePath, long fileSize, uint fileCRC, EFileVerifyLevel verifyLevel)
{ {
try try
{ {
@@ -25,7 +25,7 @@ namespace YooAsset
// 再验证文件CRC // 再验证文件CRC
if (verifyLevel == EFileVerifyLevel.High) if (verifyLevel == EFileVerifyLevel.High)
{ {
string crc = HashUtility.FileCRC32(filePath); uint crc = HashUtility.FileCRC32Value(filePath);
if (crc == fileCRC) if (crc == fileCRC)
return EFileVerifyResult.Succeed; return EFileVerifyResult.Succeed;
else else

View File

@@ -1,4 +1,5 @@
using System.Collections; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@@ -16,6 +17,8 @@ namespace YooAsset
private static readonly List<AsyncOperationBase> _operations = new List<AsyncOperationBase>(1000); private static readonly List<AsyncOperationBase> _operations = new List<AsyncOperationBase>(1000);
private static readonly List<AsyncOperationBase> _newList = new List<AsyncOperationBase>(1000); private static readonly List<AsyncOperationBase> _newList = new List<AsyncOperationBase>(1000);
private static Action<string, AsyncOperationBase> _startCallback = null;
private static Action<string, AsyncOperationBase> _finishCallback = null;
// 计时器相关 // 计时器相关
private static Stopwatch _watch; private static Stopwatch _watch;
@@ -58,7 +61,12 @@ namespace YooAsset
{ {
var operation = _operations[i]; var operation = _operations[i];
if (operation.IsFinish) if (operation.IsFinish)
{
_operations.RemoveAt(i); _operations.RemoveAt(i);
if (_finishCallback != null)
_finishCallback.Invoke(operation.PackageName, operation);
}
} }
// 添加新增的异步操作 // 添加新增的异步操作
@@ -105,6 +113,8 @@ namespace YooAsset
{ {
_operations.Clear(); _operations.Clear();
_newList.Clear(); _newList.Clear();
_startCallback = null;
_finishCallback = null;
_watch = null; _watch = null;
_frameTime = 0; _frameTime = 0;
MaxTimeSlice = long.MaxValue; MaxTimeSlice = long.MaxValue;
@@ -142,6 +152,25 @@ namespace YooAsset
_newList.Add(operation); _newList.Add(operation);
operation.SetPackageName(packageName); operation.SetPackageName(packageName);
operation.StartOperation(); operation.StartOperation();
if (_startCallback != null)
_startCallback.Invoke(packageName, operation);
}
/// <summary>
/// 监听任务开始
/// </summary>
public static void RegisterStartCallback(Action<string, AsyncOperationBase> callback)
{
_startCallback = callback;
}
/// <summary>
/// 监听任务结束
/// </summary>
public static void RegisterFinishCallback(Action<string, AsyncOperationBase> callback)
{
_finishCallback = callback;
} }
#region #region

View File

@@ -16,6 +16,6 @@ namespace YooAsset
/// <summary> /// <summary>
/// 文件格式版本 /// 文件格式版本
/// </summary> /// </summary>
public const string FileVersion = "2.3.1"; public const string FileVersion = "2025.8.28";
} }
} }

View File

@@ -59,6 +59,7 @@ namespace YooAsset
// 写入文件头信息 // 写入文件头信息
buffer.WriteBool(manifest.EnableAddressable); buffer.WriteBool(manifest.EnableAddressable);
buffer.WriteBool(manifest.SupportExtensionless);
buffer.WriteBool(manifest.LocationToLower); buffer.WriteBool(manifest.LocationToLower);
buffer.WriteBool(manifest.IncludeAssetGUID); buffer.WriteBool(manifest.IncludeAssetGUID);
buffer.WriteInt32(manifest.OutputNameStyle); buffer.WriteInt32(manifest.OutputNameStyle);
@@ -89,7 +90,7 @@ namespace YooAsset
buffer.WriteUTF8(packageBundle.BundleName); buffer.WriteUTF8(packageBundle.BundleName);
buffer.WriteUInt32(packageBundle.UnityCRC); buffer.WriteUInt32(packageBundle.UnityCRC);
buffer.WriteUTF8(packageBundle.FileHash); buffer.WriteUTF8(packageBundle.FileHash);
buffer.WriteUTF8(packageBundle.FileCRC); buffer.WriteUInt32(packageBundle.FileCRC);
buffer.WriteInt64(packageBundle.FileSize); buffer.WriteInt64(packageBundle.FileSize);
buffer.WriteBool(packageBundle.Encrypted); buffer.WriteBool(packageBundle.Encrypted);
buffer.WriteUTF8Array(packageBundle.Tags); buffer.WriteUTF8Array(packageBundle.Tags);
@@ -153,6 +154,7 @@ namespace YooAsset
// 读取文件头信息 // 读取文件头信息
manifest.FileVersion = fileVersion; manifest.FileVersion = fileVersion;
manifest.EnableAddressable = buffer.ReadBool(); manifest.EnableAddressable = buffer.ReadBool();
manifest.SupportExtensionless = buffer.ReadBool();
manifest.LocationToLower = buffer.ReadBool(); manifest.LocationToLower = buffer.ReadBool();
manifest.IncludeAssetGUID = buffer.ReadBool(); manifest.IncludeAssetGUID = buffer.ReadBool();
manifest.OutputNameStyle = buffer.ReadInt32(); manifest.OutputNameStyle = buffer.ReadInt32();
@@ -190,7 +192,7 @@ namespace YooAsset
packageBundle.BundleName = buffer.ReadUTF8(); packageBundle.BundleName = buffer.ReadUTF8();
packageBundle.UnityCRC = buffer.ReadUInt32(); packageBundle.UnityCRC = buffer.ReadUInt32();
packageBundle.FileHash = buffer.ReadUTF8(); packageBundle.FileHash = buffer.ReadUTF8();
packageBundle.FileCRC = buffer.ReadUTF8(); packageBundle.FileCRC = buffer.ReadUInt32();
packageBundle.FileSize = buffer.ReadInt64(); packageBundle.FileSize = buffer.ReadInt64();
packageBundle.Encrypted = buffer.ReadBool(); packageBundle.Encrypted = buffer.ReadBool();
packageBundle.Tags = buffer.ReadUTF8Array(); packageBundle.Tags = buffer.ReadUTF8Array();
@@ -280,13 +282,16 @@ namespace YooAsset
manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath); manifest.AssetPathMapping1.Add(location, packageAsset.AssetPath);
// 添加无后缀名路径的映射 // 添加无后缀名路径的映射
string locationWithoutExtension = Path.ChangeExtension(location, null); if (manifest.SupportExtensionless)
if (ReferenceEquals(location, locationWithoutExtension) == false)
{ {
if (manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension)) string locationWithoutExtension = Path.ChangeExtension(location, null);
YooLogger.Warning($"Location have existed : {locationWithoutExtension}"); if (ReferenceEquals(location, locationWithoutExtension) == false)
else {
manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath); if (manifest.AssetPathMapping1.ContainsKey(locationWithoutExtension))
YooLogger.Warning($"Location have existed : {locationWithoutExtension}");
else
manifest.AssetPathMapping1.Add(locationWithoutExtension, packageAsset.AssetPath);
}
} }
} }

View File

@@ -96,6 +96,7 @@ namespace YooAsset
Manifest = new PackageManifest(); Manifest = new PackageManifest();
Manifest.FileVersion = fileVersion; Manifest.FileVersion = fileVersion;
Manifest.EnableAddressable = _buffer.ReadBool(); Manifest.EnableAddressable = _buffer.ReadBool();
Manifest.SupportExtensionless = _buffer.ReadBool();
Manifest.LocationToLower = _buffer.ReadBool(); Manifest.LocationToLower = _buffer.ReadBool();
Manifest.IncludeAssetGUID = _buffer.ReadBool(); Manifest.IncludeAssetGUID = _buffer.ReadBool();
Manifest.OutputNameStyle = _buffer.ReadInt32(); Manifest.OutputNameStyle = _buffer.ReadInt32();
@@ -159,7 +160,7 @@ namespace YooAsset
packageBundle.BundleName = _buffer.ReadUTF8(); packageBundle.BundleName = _buffer.ReadUTF8();
packageBundle.UnityCRC = _buffer.ReadUInt32(); packageBundle.UnityCRC = _buffer.ReadUInt32();
packageBundle.FileHash = _buffer.ReadUTF8(); packageBundle.FileHash = _buffer.ReadUTF8();
packageBundle.FileCRC = _buffer.ReadUTF8(); packageBundle.FileCRC = _buffer.ReadUInt32();
packageBundle.FileSize = _buffer.ReadInt64(); packageBundle.FileSize = _buffer.ReadInt64();
packageBundle.Encrypted = _buffer.ReadBool(); packageBundle.Encrypted = _buffer.ReadBool();
packageBundle.Tags = _buffer.ReadUTF8Array(); packageBundle.Tags = _buffer.ReadUTF8Array();

View File

@@ -25,7 +25,7 @@ namespace YooAsset
/// <summary> /// <summary>
/// 文件校验码 /// 文件校验码
/// </summary> /// </summary>
public string FileCRC; public uint FileCRC;
/// <summary> /// <summary>
/// 文件大小(字节数) /// 文件大小(字节数)

View File

@@ -13,6 +13,11 @@ namespace YooAsset
/// </summary> /// </summary>
public bool EnableAddressable; public bool EnableAddressable;
/// <summary>
/// 支持无后缀名的资源定位地址
/// </summary>
public bool SupportExtensionless;
/// <summary> /// <summary>
/// 资源定位地址大小写不敏感 /// 资源定位地址大小写不敏感
/// </summary> /// </summary>

View File

@@ -21,6 +21,11 @@ namespace YooAsset
/// </summary> /// </summary>
public bool EnableAddressable; public bool EnableAddressable;
/// <summary>
/// 支持无后缀名的资源定位地址
/// </summary>
public bool SupportExtensionless;
/// <summary> /// <summary>
/// 资源定位地址大小写不敏感 /// 资源定位地址大小写不敏感
/// </summary> /// </summary>
@@ -116,6 +121,7 @@ namespace YooAsset
PackageDetails details = new PackageDetails(); PackageDetails details = new PackageDetails();
details.FileVersion = FileVersion; details.FileVersion = FileVersion;
details.EnableAddressable = EnableAddressable; details.EnableAddressable = EnableAddressable;
details.SupportExtensionless = SupportExtensionless;
details.LocationToLower = LocationToLower; details.LocationToLower = LocationToLower;
details.IncludeAssetGUID = IncludeAssetGUID; details.IncludeAssetGUID = IncludeAssetGUID;
details.OutputNameStyle = OutputNameStyle; details.OutputNameStyle = OutputNameStyle;

View File

@@ -73,6 +73,17 @@ namespace YooAsset
{ {
private uint _currentCrc; private uint _currentCrc;
/// <summary>
/// Gets the computed hash value.
/// </summary>
public uint CRCValue
{
get
{
return _currentCrc;
}
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="CRC32Algorithm"/> class. /// Initializes a new instance of the <see cref="CRC32Algorithm"/> class.
/// </summary> /// </summary>

View File

@@ -339,6 +339,11 @@ namespace YooAsset
byte[] buffer = Encoding.UTF8.GetBytes(str); byte[] buffer = Encoding.UTF8.GetBytes(str);
return BytesCRC32(buffer); return BytesCRC32(buffer);
} }
public static uint StringCRC32Value(string str)
{
byte[] buffer = Encoding.UTF8.GetBytes(str);
return BytesCRC32Value(buffer);
}
/// <summary> /// <summary>
/// 获取文件的CRC32 /// 获取文件的CRC32
@@ -350,6 +355,13 @@ namespace YooAsset
return StreamCRC32(fs); return StreamCRC32(fs);
} }
} }
public static uint FileCRC32Value(string filePath)
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
return StreamCRC32Value(fs);
}
}
/// <summary> /// <summary>
/// 获取文件的CRC32 /// 获取文件的CRC32
@@ -366,6 +378,18 @@ namespace YooAsset
return string.Empty; return string.Empty;
} }
} }
public static uint FileCRC32ValueSafely(string filePath)
{
try
{
return FileCRC32Value(filePath);
}
catch (Exception e)
{
YooLogger.Exception(e);
return 0;
}
}
/// <summary> /// <summary>
/// 获取数据流的CRC32 /// 获取数据流的CRC32
@@ -376,6 +400,12 @@ namespace YooAsset
byte[] hashBytes = hash.ComputeHash(stream); byte[] hashBytes = hash.ComputeHash(stream);
return ToString(hashBytes); return ToString(hashBytes);
} }
public static uint StreamCRC32Value(Stream stream)
{
CRC32Algorithm hash = new CRC32Algorithm();
hash.ComputeHash(stream);
return hash.CRCValue;
}
/// <summary> /// <summary>
/// 获取字节数组的CRC32 /// 获取字节数组的CRC32
@@ -386,6 +416,12 @@ namespace YooAsset
byte[] hashBytes = hash.ComputeHash(buffer); byte[] hashBytes = hash.ComputeHash(buffer);
return ToString(hashBytes); return ToString(hashBytes);
} }
public static uint BytesCRC32Value(byte[] buffer)
{
CRC32Algorithm hash = new CRC32Algorithm();
hash.ComputeHash(buffer);
return hash.CRCValue;
}
#endregion #endregion
} }
} }

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c0c72b92f8bf3db4b9920e968e43b2df
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
using System;
using UnityEngine;
using YooAsset;
public static class OperationMonitor
{
public static void RegisterOperationCallback()
{
OperationSystem.RegisterStartCallback(OperationStartCallback);
OperationSystem.RegisterFinishCallback(OperationFinishCallback);
}
private static void OperationStartCallback(string packageName, AsyncOperationBase operation)
{
Debug.Log($"Operation start : {operation.GetType().Name}");
}
private static void OperationFinishCallback(string packageName, AsyncOperationBase operation)
{
Debug.Log($"Operation finish : {operation.GetType().Name}");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fecc774089972ae4eaecb16bdaf9d319
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: