Compare commits

...

20 Commits

Author SHA1 Message Date
何冠峰
549ec74519 Update CHANGELOG.md 2025-09-09 20:06:53 +08:00
何冠峰
247ee31348 Update package.json 2025-09-09 20:06:31 +08:00
何冠峰
90d3a53bc3 fix #631 2025-09-09 19:06:17 +08:00
何冠峰
19f1d67a61 feat : 弱引用资源句柄 2025-09-09 18:31:02 +08:00
何冠峰
a71c46d1c4 feat : 构建过程图集依赖计算增加开关 2025-09-08 19:00:55 +08:00
何冠峰
82d7bc8fef fix #614 增加Taptap小游戏扩展类 2025-08-30 18:09:28 +08:00
何冠峰
cc85099253 update mini game
重构相关代码,使用通用逻辑
2025-08-30 17:38:26 +08:00
何冠峰
d392b02bd4 refactor : 重构了Web文件系统公共类
方便小游戏共用基础代码。
2025-08-30 17:30:29 +08:00
何冠峰
a5138b9846 feat : 在SBP构建管线里,自动建立主资源对象对图集的依赖关系 2025-08-29 19:06:55 +08:00
何冠峰
e1b6458c26 update space shooter 2025-08-29 19:04:29 +08:00
何冠峰
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
126 changed files with 2073 additions and 1354 deletions

View File

@@ -2,6 +2,104 @@
All notable changes to this package will be documented in this file.
## [2.3.15] - 2025-09-09
**重要**:升级了资源清单版本,不兼容老版本。建议重新提审安装包。
### Improvements
- 重构了UniTask扩展库的目录结构和说明文档。
- 重构了内置文件系统类的加载和拷贝逻辑,解决在一些特殊机型上遇到的偶发性拷贝失败问题。
- 增加了生成内置清单文件的窗口工具详情见扩展工程里CreateBuildinCatalog目录。
- 优化了异步操作系统的繁忙检测机制。
- (#621) 资源配置页面可以展示DependCollector和StaticCollector包含的文件列表内容。
- (#627) 优化了资源清单部分字段类型CRC字段从字符串类型调整为整形可以降低清单尺寸。
### Fixed
- 修复了构建页面扩展类缺少指定属性报错的问题。
- (#611) 修复了资源扫描器配置页面,修改备注信息后会丢失焦点的问题。
- (#622) 修复了纯鸿蒙系统读取内置加密文件失败的问题。
- (#620) 修复了LINUX系统URL地址转换失败的问题。
- (#631) 修复了NET 4.x程序集库Math.Clamp导致的编译错误。
### Added
- 新增了支持支付宝小游戏的文件系统扩展类。
- 新增了支持Taptap小游戏的文件系统扩展类。
- 新增了资源系统初始化参数UseWeakReferenceHandle
目前处于预览版可以在引擎设置页面开启宏YOOASSET_EXPERIMENTAL
```csharp
/// <summary>
/// 启用弱引用资源句柄
/// </summary>
public bool UseWeakReferenceHandle = false;
```
- 内置文件系统和缓存文件系统新增初始化参数FILE_VERIFY_MAX_CONCURRENCY
```csharp
/// <summary>
/// 自定义参数:初始化的时候缓存文件校验最大并发数
/// </summary>
public int FileVerifyMaxConcurrency { private set; get; }
```
- (#623) 内置构建管线新增构建参数StripUnityVersion
```csharp
/// <summary>
/// 从文件头里剥离Unity版本信息
/// </summary>
public bool StripUnityVersion = false;
```
- 可编程构建管线新增构建参数TrackSpriteAtlasDependencies
```csharp
/// <summary>
/// 自动建立资源对象对图集的依赖关系
/// </summary>
public bool TrackSpriteAtlasDependencies = false;
```
- (#617) 新增资源收集配置参数SupportExtensionless
在不需要模糊加载模式的前提下,开启此选项,可以降低运行时内存大小。
```csharp
public class CollectCommand
{
/// <summary>
/// 支持无后缀名的资源定位地址
/// </summary>
public bool SupportExtensionless { set; get; }
}
```
- (#625) 异步操作系统类新增监听方法。
```csharp
class OperationSystem
{
/// <summary>
/// 监听任务开始
/// </summary>
public static void RegisterStartCallback(Action<string, AsyncOperationBase> callback);
/// <summary>
/// 监听任务结束
/// </summary>
public static void RegisterFinishCallback(Action<string, AsyncOperationBase> callback);
}
```
## [2.3.14] - 2025-07-23
**重要****所有下载相关的超时参数timeout已更新判定逻辑**

View File

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

View File

@@ -13,6 +13,11 @@ namespace YooAsset.Editor
/// </summary>
private readonly Dictionary<string, BuildBundleInfo> _bundleInfoDic = new Dictionary<string, BuildBundleInfo>(10000);
/// <summary>
/// 图集资源集合
/// </summary>
public readonly List<BuildAssetInfo> SpriteAtlasAssetList = new List<BuildAssetInfo>(10000);
/// <summary>
/// 未被依赖的资源列表
/// </summary>
@@ -60,6 +65,12 @@ namespace YooAsset.Editor
newBundleInfo.PackAsset(assetInfo);
_bundleInfoDic.Add(bundleName, newBundleInfo);
}
// 统计所有的精灵图集
if (assetInfo.AssetInfo.IsSpriteAtlas())
{
SpriteAtlasAssetList.Add(assetInfo);
}
}
/// <summary>

View File

@@ -2,6 +2,7 @@
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
namespace YooAsset.Editor
{
@@ -32,6 +33,7 @@ namespace YooAsset.Editor
PackageManifest manifest = new PackageManifest();
manifest.FileVersion = ManifestDefine.FileVersion;
manifest.EnableAddressable = buildMapContext.Command.EnableAddressable;
manifest.SupportExtensionless = buildMapContext.Command.SupportExtensionless;
manifest.LocationToLower = buildMapContext.Command.LocationToLower;
manifest.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
manifest.OutputNameStyle = (int)buildParameters.FileNameStyle;
@@ -300,18 +302,40 @@ namespace YooAsset.Editor
#region YOOASSET_LEGACY_DEPENDENCY
private void ProcessBuiltinBundleDependency(BuildContext context, PackageManifest manifest)
{
// 注意:初始化资源清单建立引用关系
ManifestTools.InitManifest(manifest);
// 注意:如果是可编程构建管线,需要补充内置资源包
// 注意:该步骤依赖前面的操作!
var buildResultContext = context.TryGetContextObject<TaskBuilding_SBP.BuildResultContext>();
if (buildResultContext != null)
{
// 注意:初始化资源清单建立引用关系
ManifestTools.InitManifest(manifest);
ProcessBuiltinBundleReference(context, manifest, buildResultContext.BuiltinShadersBundleName);
ProcessBuiltinBundleReference(context, manifest, buildResultContext.MonoScriptsBundleName);
ProcessBuiltinBundleReference(manifest, buildResultContext.BuiltinShadersBundleName);
ProcessBuiltinBundleReference(manifest, buildResultContext.MonoScriptsBundleName);
var buildParametersContext = context.TryGetContextObject<BuildParametersContext>();
var buildParameters = buildParametersContext.Parameters;
if (buildParameters is ScriptableBuildParameters scriptableBuildParameters)
{
if (scriptableBuildParameters.TrackSpriteAtlasDependencies)
{
// 注意:检测是否开启图集模式
// 说明:需要记录主资源对象对图集的依赖关系!
if (EditorSettings.spritePackerMode != SpritePackerMode.Disabled)
{
var buildMapContext = context.GetContextObject<BuildMapContext>();
foreach (var spriteAtlasAsset in buildMapContext.SpriteAtlasAssetList)
{
string spriteAtlasBundleName = spriteAtlasAsset.BundleName;
ProcessBuiltinBundleReference(manifest, spriteAtlasBundleName);
}
}
}
}
}
}
private void ProcessBuiltinBundleReference(BuildContext context, PackageManifest manifest, string builtinBundleName)
private void ProcessBuiltinBundleReference(PackageManifest manifest, string builtinBundleName)
{
if (string.IsNullOrEmpty(builtinBundleName))
return;

View File

@@ -32,6 +32,7 @@ namespace YooAsset.Editor
// 收集器配置
buildReport.Summary.UniqueBundleName = buildMapContext.Command.UniqueBundleName;
buildReport.Summary.EnableAddressable = buildMapContext.Command.EnableAddressable;
buildReport.Summary.SupportExtensionless = buildMapContext.Command.SupportExtensionless;
buildReport.Summary.LocationToLower = buildMapContext.Command.LocationToLower;
buildReport.Summary.IncludeAssetGUID = buildMapContext.Command.IncludeAssetGUID;
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 uint GetUnityCRC(BuildBundleInfo bundleInfo, BuildContext context);
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);
}
}

View File

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

View File

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

View File

@@ -24,9 +24,9 @@ namespace YooAsset.Editor
string filePath = bundleInfo.PackageSourceFilePath;
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)
{

View File

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

View File

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

View File

@@ -15,7 +15,7 @@ namespace YooAsset.Editor
public ECompressOption CompressOption = ECompressOption.Uncompressed;
/// <summary>
/// 从AssetBundle文件头里剥离Unity版本信息
/// 从文件头里剥离Unity版本信息
/// </summary>
public bool StripUnityVersion = false;
@@ -25,10 +25,15 @@ namespace YooAsset.Editor
public bool DisableWriteTypeTree = false;
/// <summary>
/// 忽略类型树变化
/// 忽略类型树变化(无效参数)
/// </summary>
public bool IgnoreTypeTreeChanges = true;
/// <summary>
/// 自动建立资源对象对图集的依赖关系
/// </summary>
public bool TrackSpriteAtlasDependencies = false;
/// <summary>
/// 生成代码防裁剪配置
@@ -76,10 +81,9 @@ namespace YooAsset.Editor
throw new System.NotImplementedException(CompressOption.ToString());
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)
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.CacheServerHost = CacheServerHost;

View File

@@ -139,13 +139,6 @@ namespace YooAsset.Editor
/// </summary>
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);
// 收集打包资源路径

View File

@@ -10,7 +10,7 @@ namespace YooAsset.Editor
{
public class AssetBundleCollectorConfig
{
public const string ConfigVersion = "v2.1";
public const string ConfigVersion = "v2025.8.28";
public const string XmlVersion = "Version";
public const string XmlCommon = "Common";
@@ -23,6 +23,7 @@ namespace YooAsset.Editor
public const string XmlPackageName = "PackageName";
public const string XmlPackageDesc = "PackageDesc";
public const string XmlEnableAddressable = "AutoAddressable";
public const string XmlSupportExtensionless = "SupportExtensionless";
public const string XmlLocationToLower = "LocationToLower";
public const string XmlIncludeAssetGUID = "IncludeAssetGUID";
public const string XmlIgnoreRuleName = "IgnoreRuleName";
@@ -99,6 +100,7 @@ namespace YooAsset.Editor
package.PackageName = packageElement.GetAttribute(XmlPackageName);
package.PackageDesc = packageElement.GetAttribute(XmlPackageDesc);
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.IncludeAssetGUID = packageElement.GetAttribute(XmlIncludeAssetGUID) == "True" ? true : false;
package.IgnoreRuleName = packageElement.GetAttribute(XmlIgnoreRuleName);
@@ -211,6 +213,7 @@ namespace YooAsset.Editor
packageElement.SetAttribute(XmlPackageName, package.PackageName);
packageElement.SetAttribute(XmlPackageDesc, package.PackageDesc);
packageElement.SetAttribute(XmlEnableAddressable, package.EnableAddressable.ToString());
packageElement.SetAttribute(XmlSupportExtensionless, package.SupportExtensionless.ToString());
packageElement.SetAttribute(XmlLocationToLower, package.LocationToLower.ToString());
packageElement.SetAttribute(XmlIncludeAssetGUID, package.IncludeAssetGUID.ToString());
packageElement.SetAttribute(XmlIgnoreRuleName, package.IgnoreRuleName);
@@ -275,6 +278,23 @@ namespace YooAsset.Editor
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;
}
}

View File

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

View File

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

View File

@@ -38,6 +38,7 @@ namespace YooAsset.Editor
private VisualElement _setting2Container;
private Toggle _enableAddressableToogle;
private Toggle _supportExtensionlessToogle;
private Toggle _locationToLowerToogle;
private Toggle _includeAssetGUIDToogle;
private Toggle _autoCollectShadersToogle;
@@ -131,6 +132,17 @@ namespace YooAsset.Editor
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.RegisterValueChangedCallback(evt =>
{
@@ -487,6 +499,7 @@ namespace YooAsset.Editor
_packageSettingsButton.SetEnabled(true);
_packageSettingsButton.text = $"{packageSettingName} ({selectPackage.PackageName})";
_enableAddressableToogle.SetValueWithoutNotify(selectPackage.EnableAddressable);
_supportExtensionlessToogle.SetValueWithoutNotify(selectPackage.SupportExtensionless);
_locationToLowerToogle.SetValueWithoutNotify(selectPackage.LocationToLower);
_includeAssetGUIDToogle.SetValueWithoutNotify(selectPackage.IncludeAssetGUID);
_autoCollectShadersToogle.SetValueWithoutNotify(selectPackage.AutoCollectShaders);
@@ -831,7 +844,7 @@ namespace YooAsset.Editor
var foldout = new Foldout();
foldout.name = "Foldout1";
foldout.value = false;
foldout.text = "Main Assets";
foldout.text = "Assets";
elementFoldout.Add(foldout);
}
@@ -864,11 +877,9 @@ namespace YooAsset.Editor
var foldout = element.Q<Foldout>("Foldout1");
foldout.RegisterValueChangedCallback(evt =>
{
if (evt.newValue)
RefreshFoldout(foldout, selectGroup, collector);
else
foldout.Clear();
RefreshFoldoutContent(foldout, selectGroup, collector);
});
RefreshFoldoutName(foldout, collector.CollectorType);
// Remove Button
var removeBtn = element.Q<Button>("Button1");
@@ -885,10 +896,7 @@ namespace YooAsset.Editor
collector.CollectPath = AssetDatabase.GetAssetPath(evt.newValue);
collector.CollectorGUID = AssetDatabase.AssetPathToGUID(collector.CollectPath);
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value)
{
RefreshFoldout(foldout, selectGroup, collector);
}
RefreshFoldoutContent(foldout, selectGroup, collector);
});
UIElementsTools.RefreshObjectFieldShowPath(objectField1);
@@ -899,10 +907,7 @@ namespace YooAsset.Editor
{
collector.CollectorType = EditorTools.NameToEnum<ECollectorType>(evt.newValue);
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value)
{
RefreshFoldout(foldout, selectGroup, collector);
}
RefreshFoldoutContent(foldout, selectGroup, collector);
if (collector.CollectorType == ECollectorType.MainAssetCollector)
textTags.SetEnabled(true);
@@ -921,10 +926,7 @@ namespace YooAsset.Editor
{
collector.AddressRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value)
{
RefreshFoldout(foldout, selectGroup, collector);
}
RefreshFoldoutContent(foldout, selectGroup, collector);
});
}
@@ -937,10 +939,7 @@ namespace YooAsset.Editor
{
collector.PackRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value)
{
RefreshFoldout(foldout, selectGroup, collector);
}
RefreshFoldoutContent(foldout, selectGroup, collector);
});
// Filter Rule
@@ -952,10 +951,7 @@ namespace YooAsset.Editor
{
collector.FilterRuleName = evt.newValue.ClassName;
AssetBundleCollectorSettingData.ModifyCollector(selectGroup, collector);
if (foldout.value)
{
RefreshFoldout(foldout, selectGroup, collector);
}
RefreshFoldoutContent(foldout, selectGroup, collector);
});
// UserData
@@ -976,61 +972,101 @@ namespace YooAsset.Editor
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();
// 检测配置是否有效
if (collector.IsValid() == false)
{
collector.CheckConfigError();
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);
string packageName = _packageNameTxt.value;
var command = new CollectCommand(packageName, ignoreRule);
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;
VisualElement elementRow = new VisualElement();
elementRow.style.flexDirection = FlexDirection.Row;
foldout.Add(elementRow);
collector.CheckConfigError();
collectAssetInfos = collector.GetAllCollectAssets(command, group);
}
catch (System.Exception e)
{
Debug.LogError(e.ToString());
}
string showInfo = collectAsset.AssetInfo.AssetPath;
if (showAdress)
showInfo = $"[{collectAsset.Address}] {collectAsset.AssetInfo.AssetPath}";
if (collectAssetInfos != null)
{
foreach (var collectAsset in collectAssetInfos)
{
VisualElement elementRow = new VisualElement();
elementRow.style.flexDirection = FlexDirection.Row;
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);
}
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:VisualElement name="PublicContainer2">
<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="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;" />

View File

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

View File

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

View File

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

View File

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

View File

@@ -62,6 +62,17 @@ namespace YooAsset.Editor
return false;
}
/// <summary>
/// 是否为图集资源
/// </summary>
public bool IsSpriteAtlas()
{
if (AssetType == typeof(UnityEngine.U2D.SpriteAtlas))
return true;
else
return false;
}
public int CompareTo(AssetInfo other)
{
return this.AssetPath.CompareTo(other.AssetPath);

View File

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

View File

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

View File

@@ -2,6 +2,7 @@
using System.IO;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace YooAsset
{
@@ -60,15 +61,20 @@ namespace YooAsset
/// </summary>
public IRemoteServices RemoteServices { private set; get; }
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
/// <summary>
/// 自定义参数:初始化的时候缓存文件校验级别
/// </summary>
public EFileVerifyLevel FileVerifyLevel { private set; get; } = EFileVerifyLevel.Middle;
/// <summary>
/// 自定义参数:覆盖安装缓存清理模式
/// 自定义参数:初始化的时候缓存文件校验最大并发数
/// </summary>
public EOverwriteInstallClearMode InstallClearMode { private set; get; } = EOverwriteInstallClearMode.ClearAllManifestFiles;
public int FileVerifyMaxConcurrency { private set; get; } = int.MaxValue;
/// <summary>
/// 自定义参数:数据文件追加文件格式
@@ -215,13 +221,18 @@ namespace YooAsset
{
RemoteServices = (IRemoteServices)value;
}
else if (name == FileSystemParametersDefine.INSTALL_CLEAR_MODE)
{
InstallClearMode = (EOverwriteInstallClearMode)value;
}
else if (name == FileSystemParametersDefine.FILE_VERIFY_LEVEL)
{
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 = Mathf.Clamp(convertValue, 1, int.MaxValue);
}
else if (name == FileSystemParametersDefine.APPEND_FILE_EXTENSION)
{
@@ -233,11 +244,13 @@ namespace YooAsset
}
else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_CONCURRENCY)
{
DownloadMaxConcurrency = Convert.ToInt32(value);
int convertValue = Convert.ToInt32(value);
DownloadMaxConcurrency = Mathf.Clamp(convertValue, 1, int.MaxValue);
}
else if (name == FileSystemParametersDefine.DOWNLOAD_MAX_REQUEST_PER_FRAME)
{
DownloadMaxRequestPerFrame = Convert.ToInt32(value);
int convertValue = Convert.ToInt32(value);
DownloadMaxRequestPerFrame = Mathf.Clamp(convertValue, 1, int.MaxValue);
}
else if (name == FileSystemParametersDefine.RESUME_DOWNLOAD_MINMUM_SIZE)
{
@@ -493,22 +506,22 @@ namespace YooAsset
}
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))
{
_sharedBuffer.Clear();
_sharedBuffer.WriteUTF8(dataFileCRC);
_sharedBuffer.WriteUInt32(dataFileCRC);
_sharedBuffer.WriteInt64(dataFileSize);
_sharedBuffer.WriteToStream(fs);
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);
BufferReader buffer = new BufferReader(binaryData);
dataFileCRC = buffer.ReadUTF8();
dataFileCRC = buffer.ReadUInt32();
dataFileSize = buffer.ReadInt64();
}
#endregion

View File

@@ -7,10 +7,10 @@ namespace YooAsset
{
public string InfoFilePath { 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 RecordFileElement(string infoFilePath, string dataFilePath, string dataFileCRC, long dataFileSize)
public RecordFileElement(string infoFilePath, string dataFilePath, uint dataFileCRC, long dataFileSize)
{
InfoFilePath = infoFilePath;
DataFilePath = dataFilePath;

View File

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

View File

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

View File

@@ -54,11 +54,13 @@ namespace YooAsset
// 设置同时验证的最大数
ThreadPool.GetMaxThreads(out int workerThreads, out int 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;
if (_verifyMaxNum < 1)
_verifyMaxNum = 1;
YooLogger.Log($"Verify max concurrency : {_verifyMaxNum}");
_verifyingList = new List<VerifyFileElement>(_verifyMaxNum);
_steps = ESteps.UpdateVerify;
}

View File

@@ -14,8 +14,8 @@ namespace YooAsset
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private RequestWebRemotePackageHashOperation _requestWebPackageHashOp;
private LoadWebRemotePackageManifestOperation _loadWebPackageManifestOp;
private RequestWebPackageHashOperation _requestWebPackageHashOp;
private LoadWebPackageManifestOperation _loadWebPackageManifestOp;
private ESteps _steps = ESteps.None;
@@ -38,7 +38,7 @@ namespace YooAsset
{
if (_requestWebPackageHashOp == null)
{
_requestWebPackageHashOp = new RequestWebRemotePackageHashOperation(_fileSystem, _packageVersion, _timeout);
_requestWebPackageHashOp = new RequestWebPackageHashOperation(_fileSystem.RemoteServices, _fileSystem.PackageName, _packageVersion, _timeout);
_requestWebPackageHashOp.StartOperation();
AddChildOperation(_requestWebPackageHashOp);
}
@@ -64,7 +64,10 @@ namespace YooAsset
if (_loadWebPackageManifestOp == null)
{
string packageHash = _requestWebPackageHashOp.PackageHash;
_loadWebPackageManifestOp = new LoadWebRemotePackageManifestOperation(_fileSystem, _packageVersion, packageHash, _timeout);
string packageName = _fileSystem.PackageName;
var manifestServices = _fileSystem.ManifestServices;
var remoteServices = _fileSystem.RemoteServices;
_loadWebPackageManifestOp = new LoadWebPackageManifestOperation(manifestServices, remoteServices, packageName, _packageVersion, packageHash, _timeout);
_loadWebPackageManifestOp.StartOperation();
AddChildOperation(_loadWebPackageManifestOp);
}

View File

@@ -13,7 +13,7 @@ namespace YooAsset
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private RequestWebRemotePackageVersionOperation _requestWebPackageVersionOp;
private RequestWebPackageVersionOperation _requestWebPackageVersionOp;
private ESteps _steps = ESteps.None;
@@ -36,7 +36,7 @@ namespace YooAsset
{
if (_requestWebPackageVersionOp == null)
{
_requestWebPackageVersionOp = new RequestWebRemotePackageVersionOperation(_fileSystem, _appendTimeTicks, _timeout);
_requestWebPackageVersionOp = new RequestWebPackageVersionOperation(_fileSystem.RemoteServices, _fileSystem.PackageName, _appendTimeTicks, _timeout);
_requestWebPackageVersionOp.StartOperation();
AddChildOperation(_requestWebPackageVersionOp);
}

View File

@@ -1,131 +0,0 @@

namespace YooAsset
{
internal class LoadWebRemotePackageManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestFileData,
VerifyFileData,
LoadManifest,
Done,
}
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly string _packageHash;
private readonly int _timeout;
private UnityWebDataRequestOperation _webDataRequestOp;
private DeserializeManifestOperation _deserializer;
private int _requestCount = 0;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹清单
/// </summary>
public PackageManifest Manifest { private set; get; }
internal LoadWebRemotePackageManifestOperation(DefaultWebRemoteFileSystem fileSystem, string packageVersion, string packageHash, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_packageHash = packageHash;
_timeout = timeout;
}
internal override void InternalStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(LoadWebRemotePackageManifestOperation));
_steps = ESteps.RequestFileData;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestFileData)
{
if (_webDataRequestOp == null)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion);
string url = GetWebRequestURL(fileName);
_webDataRequestOp = new UnityWebDataRequestOperation(url, _timeout);
_webDataRequestOp.StartOperation();
AddChildOperation(_webDataRequestOp);
}
_webDataRequestOp.UpdateOperation();
if (_webDataRequestOp.IsDone == false)
return;
if (_webDataRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.VerifyFileData;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webDataRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(LoadWebRemotePackageManifestOperation));
}
}
if (_steps == ESteps.VerifyFileData)
{
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{
_steps = ESteps.LoadManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify web remote package manifest file!";
}
}
if (_steps == ESteps.LoadManifest)
{
if (_deserializer == null)
{
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result);
_deserializer.StartOperation();
AddChildOperation(_deserializer);
}
_deserializer.UpdateOperation();
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_deserializer.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Manifest = _deserializer.Manifest;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
internal override string InternalGetDesc()
{
return $"PackageVersion : {_packageVersion} PackageHash : {_packageHash}";
}
private string GetWebRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
}
}
}

View File

@@ -1,92 +0,0 @@

namespace YooAsset
{
internal class RequestWebRemotePackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestPackageHash,
Done,
}
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private int _requestCount = 0;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹哈希值
/// </summary>
public string PackageHash { private set; get; }
public RequestWebRemotePackageHashOperation(DefaultWebRemoteFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestWebRemotePackageHashOperation));
_steps = ESteps.RequestPackageHash;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestPackageHash)
{
if (_webTextRequestOp == null)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion);
string url = GetWebRequestURL(fileName);
_webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
_webTextRequestOp.StartOperation();
AddChildOperation(_webTextRequestOp);
}
_webTextRequestOp.UpdateOperation();
Progress = _webTextRequestOp.Progress;
if (_webTextRequestOp.IsDone == false)
return;
if (_webTextRequestOp.Status == EOperationStatus.Succeed)
{
PackageHash = _webTextRequestOp.Result;
if (string.IsNullOrEmpty(PackageHash))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Web remote package hash file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webTextRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestWebRemotePackageHashOperation));
}
}
}
private string GetWebRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
}
}
}

View File

@@ -1,100 +0,0 @@

namespace YooAsset
{
internal class RequestWebRemotePackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestPackageVersion,
Done,
}
private readonly DefaultWebRemoteFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private int _requestCount = 0;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹版本
/// </summary>
public string PackageVersion { private set; get; }
internal RequestWebRemotePackageVersionOperation(DefaultWebRemoteFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestWebRemotePackageVersionOperation));
_steps = ESteps.RequestPackageVersion;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestPackageVersion)
{
if (_webTextRequestOp == null)
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_fileSystem.PackageName);
string url = GetWebRequestURL(fileName);
_webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
_webTextRequestOp.StartOperation();
AddChildOperation(_webTextRequestOp);
}
_webTextRequestOp.UpdateOperation();
Progress = _webTextRequestOp.Progress;
if (_webTextRequestOp.IsDone == false)
return;
if (_webTextRequestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _webTextRequestOp.Result;
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Web remote package version file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webTextRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestWebRemotePackageVersionOperation));
}
}
}
private string GetWebRequestURL(string fileName)
{
string url;
// 轮流返回请求地址
if (_requestCount % 2 == 0)
url = _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
url = _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
// 在URL末尾添加时间戳
if (_appendTimeTicks)
return $"{url}?{System.DateTime.UtcNow.Ticks}";
else
return url;
}
}
}

View File

@@ -4,6 +4,7 @@ namespace YooAsset
public class FileSystemParametersDefine
{
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 REMOTE_SERVICES = "REMOTE_SERVICES";
public const string DECRYPTION_SERVICES = "DECRYPTION_SERVICES";

View File

@@ -8,7 +8,7 @@ namespace YooAsset
/// <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
{
@@ -25,7 +25,7 @@ namespace YooAsset
// 再验证文件CRC
if (verifyLevel == EFileVerifyLevel.High)
{
string crc = HashUtility.FileCRC32(filePath);
uint crc = HashUtility.FileCRC32Value(filePath);
if (crc == fileCRC)
return EFileVerifyResult.Succeed;
else

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 97923f5987c469a4898718033af09e99
guid: 1ca8ffceab2965e4c8892f62efa86e90
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

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

View File

@@ -1,7 +1,6 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using YooAsset;
using YooAsset;
internal class LoadTiktokPackageManifestOperation : AsyncOperationBase
internal class LoadWebPackageManifestOperation : AsyncOperationBase
{
private enum ESteps
{
@@ -12,7 +11,9 @@ internal class LoadTiktokPackageManifestOperation : AsyncOperationBase
Done,
}
private readonly TiktokFileSystem _fileSystem;
private readonly IManifestRestoreServices _manifestServices;
private readonly IRemoteServices _remoteServices;
private readonly string _packageName;
private readonly string _packageVersion;
private readonly string _packageHash;
private readonly int _timeout;
@@ -27,16 +28,19 @@ internal class LoadTiktokPackageManifestOperation : AsyncOperationBase
public PackageManifest Manifest { private set; get; }
internal LoadTiktokPackageManifestOperation(TiktokFileSystem fileSystem, string packageVersion, string packageHash, int timeout)
internal LoadWebPackageManifestOperation(IManifestRestoreServices manifestServices, IRemoteServices remoteServices,
string packageName, string packageVersion, string packageHash, int timeout)
{
_fileSystem = fileSystem;
_manifestServices = manifestServices;
_remoteServices = remoteServices;
_packageName = packageName;
_packageVersion = packageVersion;
_packageHash = packageHash;
_timeout = timeout;
}
internal override void InternalStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(LoadTiktokPackageManifestOperation));
_requestCount = WebRequestCounter.GetRequestFailedCount(_packageName, nameof(LoadWebPackageManifestOperation));
_steps = ESteps.RequestFileData;
}
internal override void InternalUpdate()
@@ -48,7 +52,7 @@ internal class LoadTiktokPackageManifestOperation : AsyncOperationBase
{
if (_webDataRequestOp == null)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion);
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_packageName, _packageVersion);
string url = GetRequestURL(fileName);
_webDataRequestOp = new UnityWebDataRequestOperation(url, _timeout);
_webDataRequestOp.StartOperation();
@@ -69,14 +73,13 @@ internal class LoadTiktokPackageManifestOperation : AsyncOperationBase
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webDataRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(LoadTiktokPackageManifestOperation));
WebRequestCounter.RecordRequestFailed(_packageName, nameof(LoadWebPackageManifestOperation));
}
}
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
if (ManifestTools.VerifyManifestData(_webDataRequestOp.Result, _packageHash))
{
_steps = ESteps.LoadManifest;
}
@@ -84,7 +87,7 @@ internal class LoadTiktokPackageManifestOperation : AsyncOperationBase
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify package manifest file!";
Error = "Failed to verify web package manifest file!";
}
}
@@ -92,7 +95,7 @@ internal class LoadTiktokPackageManifestOperation : AsyncOperationBase
{
if (_deserializer == null)
{
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result);
_deserializer = new DeserializeManifestOperation(_manifestServices, _webDataRequestOp.Result);
_deserializer.StartOperation();
AddChildOperation(_deserializer);
}
@@ -116,14 +119,17 @@ internal class LoadTiktokPackageManifestOperation : AsyncOperationBase
}
}
}
internal override string InternalGetDesc()
{
return $"PackageVersion : {_packageVersion} PackageHash : {_packageHash}";
}
private string GetRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
return _remoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
return _remoteServices.GetRemoteFallbackURL(fileName);
}
}
#endif
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9a38597f546a46a429b24abd595c76e4
guid: eb2ed9a86dbe88c42a3715b90df0e266
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,7 +1,6 @@
#if UNITY_WEBGL && UNITY_ALIMINIGAME
using YooAsset;
using YooAsset;
internal class RequestAlipayPackageHashOperation : AsyncOperationBase
internal class RequestWebPackageHashOperation : AsyncOperationBase
{
private enum ESteps
{
@@ -10,7 +9,8 @@ internal class RequestAlipayPackageHashOperation : AsyncOperationBase
Done,
}
private readonly AlipayFileSystem _fileSystem;
private readonly IRemoteServices _remoteServices;
private readonly string _packageName;
private readonly string _packageVersion;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
@@ -23,15 +23,16 @@ internal class RequestAlipayPackageHashOperation : AsyncOperationBase
public string PackageHash { private set; get; }
public RequestAlipayPackageHashOperation(AlipayFileSystem fileSystem, string packageVersion, int timeout)
public RequestWebPackageHashOperation(IRemoteServices remoteServices, string packageName, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_remoteServices = remoteServices;
_packageName = packageName;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestAlipayPackageHashOperation));
_requestCount = WebRequestCounter.GetRequestFailedCount(_packageName, nameof(RequestWebPackageHashOperation));
_steps = ESteps.RequestPackageHash;
}
internal override void InternalUpdate()
@@ -43,7 +44,7 @@ internal class RequestAlipayPackageHashOperation : AsyncOperationBase
{
if (_webTextRequestOp == null)
{
string fileName = YooAssetSettingsData.GetPackageHashFileName(_fileSystem.PackageName, _packageVersion);
string fileName = YooAssetSettingsData.GetPackageHashFileName(_packageName, _packageVersion);
string url = GetRequestURL(fileName);
_webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
_webTextRequestOp.StartOperation();
@@ -75,7 +76,7 @@ internal class RequestAlipayPackageHashOperation : AsyncOperationBase
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webTextRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestAlipayPackageHashOperation));
WebRequestCounter.RecordRequestFailed(_packageName, nameof(RequestWebPackageHashOperation));
}
}
}
@@ -84,9 +85,8 @@ internal class RequestAlipayPackageHashOperation : AsyncOperationBase
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
return _remoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
return _remoteServices.GetRemoteFallbackURL(fileName);
}
}
#endif
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 8ac57bde14f2e1a4e9323751a7157ed7
guid: 9c7603967834be04e9307b6d4eec2666
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,7 +1,6 @@
#if UNITY_WEBGL && DOUYINMINIGAME
using YooAsset;
using YooAsset;
internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
internal class RequestWebPackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
@@ -10,7 +9,8 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
Done,
}
private readonly TiktokFileSystem _fileSystem;
private readonly IRemoteServices _remoteServices;
private readonly string _packageName;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
@@ -23,15 +23,16 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
public string PackageVersion { private set; get; }
public RequestTiktokPackageVersionOperation(TiktokFileSystem fileSystem, bool appendTimeTicks, int timeout)
public RequestWebPackageVersionOperation(IRemoteServices remoteServices, string packageName, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_remoteServices = remoteServices;
_packageName = packageName;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestTiktokPackageVersionOperation));
_requestCount = WebRequestCounter.GetRequestFailedCount(_packageName, nameof(RequestWebPackageVersionOperation));
_steps = ESteps.RequestPackageVersion;
}
internal override void InternalUpdate()
@@ -43,7 +44,7 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
{
if (_webTextRequestOp == null)
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_fileSystem.PackageName);
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_packageName);
string url = GetRequestURL(fileName);
_webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
_webTextRequestOp.StartOperation();
@@ -75,7 +76,7 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webTextRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestTiktokPackageVersionOperation));
WebRequestCounter.RecordRequestFailed(_packageName, nameof(RequestWebPackageVersionOperation));
}
}
}
@@ -86,9 +87,9 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
// 轮流返回请求地址
if (_requestCount % 2 == 0)
url = _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
url = _remoteServices.GetRemoteMainURL(fileName);
else
url = _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
url = _remoteServices.GetRemoteFallbackURL(fileName);
// 在URL末尾添加时间戳
if (_appendTimeTicks)
@@ -96,5 +97,4 @@ internal class RequestTiktokPackageVersionOperation : AsyncOperationBase
else
return url;
}
}
#endif
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: c802e6ad51754e144bb4e08942da9592
guid: ae045c2050b3e8a4d91fb0585bdfb2c0
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -47,6 +47,15 @@ namespace YooAsset
/// WebGL平台强制同步加载资源对象
/// </summary>
public bool WebGLForceSyncLoadAsset = false;
#if YOOASSET_EXPERIMENTAL
/// <summary>
/// 启用弱引用资源句柄
/// </summary>
public bool UseWeakReferenceHandle = false;
#else
internal bool UseWeakReferenceHandle = false;
#endif
}
/// <summary>

View File

@@ -1,4 +1,5 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
@@ -16,6 +17,8 @@ namespace YooAsset
private static readonly List<AsyncOperationBase> _operations = 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;
@@ -58,7 +61,12 @@ namespace YooAsset
{
var operation = _operations[i];
if (operation.IsFinish)
{
_operations.RemoveAt(i);
if (_finishCallback != null)
_finishCallback.Invoke(operation.PackageName, operation);
}
}
// 添加新增的异步操作
@@ -105,6 +113,8 @@ namespace YooAsset
{
_operations.Clear();
_newList.Clear();
_startCallback = null;
_finishCallback = null;
_watch = null;
_frameTime = 0;
MaxTimeSlice = long.MaxValue;
@@ -142,6 +152,25 @@ namespace YooAsset
_newList.Add(operation);
operation.SetPackageName(packageName);
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

View File

@@ -17,7 +17,7 @@ namespace YooAsset
AddChildOperation(_loadAllAssetsOp);
#if UNITY_WEBGL
if (_resManager.WebGLForceSyncLoadAsset())
if (_resManager.WebGLForceSyncLoadAsset)
_loadAllAssetsOp.WaitForAsyncComplete();
#endif
}

View File

@@ -17,7 +17,7 @@ namespace YooAsset
AddChildOperation(_loadAssetOp);
#if UNITY_WEBGL
if (_resManager.WebGLForceSyncLoadAsset())
if (_resManager.WebGLForceSyncLoadAsset)
_loadAssetOp.WaitForAsyncComplete();
#endif
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System;
namespace YooAsset
{
@@ -72,6 +73,7 @@ namespace YooAsset
private readonly LoadBundleFileOperation _mainBundleLoader;
private readonly List<LoadBundleFileOperation> _bundleLoaders = new List<LoadBundleFileOperation>(10);
private readonly HashSet<HandleBase> _handles = new HashSet<HandleBase>();
private readonly LinkedList<WeakReference<HandleBase>> _weakReferences = new LinkedList<WeakReference<HandleBase>>();
public ProviderOperation(ResourceManager manager, string providerGUID, AssetInfo assetInfo)
{
@@ -210,6 +212,11 @@ namespace YooAsset
if (_steps == ESteps.ProcessBundleResult)
return false;
if (_resManager.UseWeakReferenceHandle)
{
TryCleanupWeakReference();
}
return RefCount <= 0;
}
@@ -222,7 +229,15 @@ namespace YooAsset
RefCount++;
HandleBase handle = HandleFactory.CreateHandle(this, typeof(T));
_handles.Add(handle);
if (_resManager.UseWeakReferenceHandle)
{
var weakRef = new WeakReference<HandleBase>(handle);
_weakReferences.AddLast(weakRef);
}
else
{
_handles.Add(handle);
}
return handle as T;
}
@@ -234,8 +249,16 @@ namespace YooAsset
if (RefCount <= 0)
throw new System.Exception("Should never get here !");
if (_handles.Remove(handle) == false)
throw new System.Exception("Should never get here !");
if (_resManager.UseWeakReferenceHandle)
{
if (RemoveWeakReference(handle) == false)
throw new System.Exception("Should never get here !");
}
else
{
if (_handles.Remove(handle) == false)
throw new System.Exception("Should never get here !");
}
// 引用计数减少
RefCount--;
@@ -246,10 +269,24 @@ namespace YooAsset
/// </summary>
public void ReleaseAllHandles()
{
List<HandleBase> tempers = _handles.ToList();
foreach (var handle in tempers)
if (_resManager.UseWeakReferenceHandle)
{
handle.Release();
List<WeakReference<HandleBase>> tempers = _weakReferences.ToList();
foreach (var weakRef in tempers)
{
if (weakRef.TryGetTarget(out HandleBase target))
{
target.Release();
}
}
}
else
{
List<HandleBase> tempers = _handles.ToList();
foreach (var handle in tempers)
{
handle.Release();
}
}
}
@@ -264,12 +301,29 @@ namespace YooAsset
// 注意:创建临时列表是为了防止外部逻辑在回调函数内创建或者释放资源句柄。
// 注意:回调方法如果发生异常,会阻断列表里的后续回调方法!
List<HandleBase> tempers = _handles.ToList();
foreach (var hande in tempers)
if (_resManager.UseWeakReferenceHandle)
{
if (hande.IsValid)
List<WeakReference<HandleBase>> tempers = _weakReferences.ToList();
foreach (var weakRef in tempers)
{
hande.InvokeCallback();
if (weakRef.TryGetTarget(out HandleBase target))
{
if (target.IsValid)
{
target.InvokeCallback();
}
}
}
}
else
{
List<HandleBase> tempers = _handles.ToList();
foreach (var handle in tempers)
{
if (handle.IsValid)
{
handle.InvokeCallback();
}
}
}
}
@@ -294,6 +348,50 @@ namespace YooAsset
return status;
}
/// <summary>
/// 移除指定句柄的弱引用对象
/// </summary>
private bool RemoveWeakReference(HandleBase handle)
{
bool removed = false;
var currentNode = _weakReferences.First;
while (currentNode != null)
{
var nextNode = currentNode.Next;
if (currentNode.Value.TryGetTarget(out HandleBase target))
{
if (ReferenceEquals(target, handle))
{
_weakReferences.Remove(currentNode);
removed = true;
break;
}
}
currentNode = nextNode;
}
return removed;
}
/// <summary>
/// 清理所有失效的弱引用
/// </summary>
private void TryCleanupWeakReference()
{
var currentNode = _weakReferences.First;
while (currentNode != null)
{
var nextNode = currentNode.Next;
if (currentNode.Value.TryGetTarget(out HandleBase target) == false)
{
_weakReferences.Remove(currentNode);
// 引用计数减少
RefCount--;
}
currentNode = nextNode;
}
}
#region
/// <summary>
/// 出生的场景

View File

@@ -17,7 +17,7 @@ namespace YooAsset
AddChildOperation(_loadSubAssetsOp);
#if UNITY_WEBGL
if (_resManager.WebGLForceSyncLoadAsset())
if (_resManager.WebGLForceSyncLoadAsset)
_loadSubAssetsOp.WaitForAsyncComplete();
#endif
}

View File

@@ -15,7 +15,10 @@ namespace YooAsset
private long _sceneCreateIndex = 0;
private IBundleQuery _bundleQuery;
private int _bundleLoadingMaxConcurrency;
private bool _webGLForceSyncLoadAsset;
// 开发者配置选项
public bool WebGLForceSyncLoadAsset { private set; get; }
public bool UseWeakReferenceHandle { private set; get; }
/// <summary>
/// 所属包裹
@@ -44,7 +47,8 @@ namespace YooAsset
public void Initialize(InitializeParameters parameters, IBundleQuery bundleServices)
{
_bundleLoadingMaxConcurrency = parameters.BundleLoadingMaxConcurrency;
_webGLForceSyncLoadAsset = parameters.WebGLForceSyncLoadAsset;
WebGLForceSyncLoadAsset = parameters.WebGLForceSyncLoadAsset;
UseWeakReferenceHandle = parameters.UseWeakReferenceHandle;
_bundleQuery = bundleServices;
SceneManager.sceneUnloaded += OnSceneUnloaded;
}
@@ -331,10 +335,6 @@ namespace YooAsset
{
return BundleLoadingCounter >= _bundleLoadingMaxConcurrency;
}
internal bool WebGLForceSyncLoadAsset()
{
return _webGLForceSyncLoadAsset;
}
private LoadBundleFileOperation CreateBundleFileLoaderInternal(BundleInfo bundleInfo)
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f2a5bb0106a45e540a43a05b72a75bcd
guid: fecc774089972ae4eaecb16bdaf9d319
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -182,10 +182,10 @@ internal class AlipayFileSystem : IFileSystem
if (string.IsNullOrEmpty(_aliCacheRoot))
{
throw new System.Exception("请配置支付宝小游戏的缓存根目录!");
throw new System.Exception("请配置小游戏的缓存根目录!");
}
// 注意CDN服务未启用的情况下使用支付宝WEB服务器
// 注意CDN服务未启用的情况下使用WEB服务器
if (RemoteServices == null)
{
string webRoot = PathUtility.Combine(Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName, packageName);

View File

@@ -14,8 +14,8 @@ internal class APFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
private readonly AlipayFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private RequestAlipayPackageHashOperation _requestPackageHashOp;
private LoadAlipayPackageManifestOperation _loadPackageManifestOp;
private RequestWebPackageHashOperation _requestPackageHashOp;
private LoadWebPackageManifestOperation _loadPackageManifestOp;
private ESteps _steps = ESteps.None;
@@ -38,7 +38,7 @@ internal class APFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
{
if (_requestPackageHashOp == null)
{
_requestPackageHashOp = new RequestAlipayPackageHashOperation(_fileSystem, _packageVersion, _timeout);
_requestPackageHashOp = new RequestWebPackageHashOperation(_fileSystem.RemoteServices, _fileSystem.PackageName, _packageVersion, _timeout);
_requestPackageHashOp.StartOperation();
AddChildOperation(_requestPackageHashOp);
}
@@ -64,7 +64,10 @@ internal class APFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
if (_loadPackageManifestOp == null)
{
string packageHash = _requestPackageHashOp.PackageHash;
_loadPackageManifestOp = new LoadAlipayPackageManifestOperation(_fileSystem, _packageVersion, packageHash, _timeout);
string packageName = _fileSystem.PackageName;
var manifestServices = _fileSystem.ManifestServices;
var remoteServices = _fileSystem.RemoteServices;
_loadPackageManifestOp = new LoadWebPackageManifestOperation(manifestServices, remoteServices, packageName, _packageVersion, packageHash, _timeout);
_loadPackageManifestOp.StartOperation();
AddChildOperation(_loadPackageManifestOp);
}

View File

@@ -13,7 +13,7 @@ internal class APFSRequestPackageVersionOperation : FSRequestPackageVersionOpera
private readonly AlipayFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private RequestAlipayPackageVersionOperation _requestWebPackageVersionOp;
private RequestWebPackageVersionOperation _requestWebPackageVersionOp;
private ESteps _steps = ESteps.None;
@@ -36,7 +36,7 @@ internal class APFSRequestPackageVersionOperation : FSRequestPackageVersionOpera
{
if (_requestWebPackageVersionOp == null)
{
_requestWebPackageVersionOp = new RequestAlipayPackageVersionOperation(_fileSystem, _appendTimeTicks, _timeout);
_requestWebPackageVersionOp = new RequestWebPackageVersionOperation(_fileSystem.RemoteServices, _fileSystem.PackageName, _appendTimeTicks, _timeout);
_requestWebPackageVersionOp.StartOperation();
AddChildOperation(_requestWebPackageVersionOp);
}

View File

@@ -1,129 +0,0 @@
#if UNITY_WEBGL && UNITY_ALIMINIGAME
using YooAsset;
internal class LoadAlipayPackageManifestOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestFileData,
VerifyFileData,
LoadManifest,
Done,
}
private readonly AlipayFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly string _packageHash;
private readonly int _timeout;
private UnityWebDataRequestOperation _webDataRequestOp;
private DeserializeManifestOperation _deserializer;
private int _requestCount = 0;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹清单
/// </summary>
public PackageManifest Manifest { private set; get; }
internal LoadAlipayPackageManifestOperation(AlipayFileSystem fileSystem, string packageVersion, string packageHash, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_packageHash = packageHash;
_timeout = timeout;
}
internal override void InternalStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(LoadAlipayPackageManifestOperation));
_steps = ESteps.RequestFileData;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestFileData)
{
if (_webDataRequestOp == null)
{
string fileName = YooAssetSettingsData.GetManifestBinaryFileName(_fileSystem.PackageName, _packageVersion);
string url = GetRequestURL(fileName);
_webDataRequestOp = new UnityWebDataRequestOperation(url, _timeout);
_webDataRequestOp.StartOperation();
AddChildOperation(_webDataRequestOp);
}
_webDataRequestOp.UpdateOperation();
Progress = _webDataRequestOp.Progress;
if (_webDataRequestOp.IsDone == false)
return;
if (_webDataRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.VerifyFileData;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webDataRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(LoadAlipayPackageManifestOperation));
}
}
if (_steps == ESteps.VerifyFileData)
{
string fileHash = HashUtility.BytesCRC32(_webDataRequestOp.Result);
if (fileHash == _packageHash)
{
_steps = ESteps.LoadManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "Failed to verify package manifest file!";
}
}
if (_steps == ESteps.LoadManifest)
{
if (_deserializer == null)
{
_deserializer = new DeserializeManifestOperation(_fileSystem.ManifestServices, _webDataRequestOp.Result);
_deserializer.StartOperation();
AddChildOperation(_deserializer);
}
_deserializer.UpdateOperation();
Progress = _deserializer.Progress;
if (_deserializer.IsDone == false)
return;
if (_deserializer.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Manifest = _deserializer.Manifest;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _deserializer.Error;
}
}
}
private string GetRequestURL(string fileName)
{
// 轮流返回请求地址
if (_requestCount % 2 == 0)
return _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
return _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
}
}
#endif

View File

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

View File

@@ -1,100 +0,0 @@
#if UNITY_WEBGL && UNITY_ALIMINIGAME
using YooAsset;
internal class RequestAlipayPackageVersionOperation : AsyncOperationBase
{
private enum ESteps
{
None,
RequestPackageVersion,
Done,
}
private readonly AlipayFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private UnityWebTextRequestOperation _webTextRequestOp;
private int _requestCount = 0;
private ESteps _steps = ESteps.None;
/// <summary>
/// 包裹版本
/// </summary>
public string PackageVersion { private set; get; }
public RequestAlipayPackageVersionOperation(AlipayFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalStart()
{
_requestCount = WebRequestCounter.GetRequestFailedCount(_fileSystem.PackageName, nameof(RequestAlipayPackageVersionOperation));
_steps = ESteps.RequestPackageVersion;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestPackageVersion)
{
if (_webTextRequestOp == null)
{
string fileName = YooAssetSettingsData.GetPackageVersionFileName(_fileSystem.PackageName);
string url = GetRequestURL(fileName);
_webTextRequestOp = new UnityWebTextRequestOperation(url, _timeout);
_webTextRequestOp.StartOperation();
AddChildOperation(_webTextRequestOp);
}
_webTextRequestOp.UpdateOperation();
Progress = _webTextRequestOp.Progress;
if (_webTextRequestOp.IsDone == false)
return;
if (_webTextRequestOp.Status == EOperationStatus.Succeed)
{
PackageVersion = _webTextRequestOp.Result;
if (string.IsNullOrEmpty(PackageVersion))
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"Web package version file content is empty !";
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webTextRequestOp.Error;
WebRequestCounter.RecordRequestFailed(_fileSystem.PackageName, nameof(RequestAlipayPackageVersionOperation));
}
}
}
private string GetRequestURL(string fileName)
{
string url;
// 轮流返回请求地址
if (_requestCount % 2 == 0)
url = _fileSystem.RemoteServices.GetRemoteMainURL(fileName);
else
url = _fileSystem.RemoteServices.GetRemoteFallbackURL(fileName);
// 在URL末尾添加时间戳
if (_appendTimeTicks)
return $"{url}?{System.DateTime.UtcNow.Ticks}";
else
return url;
}
}
#endif

View File

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

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 2e26d6ba3f3c6cd48bc22d40f1857f89
guid: 3a09145cd500f3f42b2a17524f0dd3f2
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

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

View File

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

View File

@@ -0,0 +1,67 @@
#if UNITY_WEBGL && TAPMINIGAME
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
using TapTapMiniGame;
namespace YooAsset
{
internal class TPAssetBundleResult : BundleResult
{
private readonly IFileSystem _fileSystem;
private readonly PackageBundle _packageBundle;
private readonly AssetBundle _assetBundle;
public TPAssetBundleResult(IFileSystem fileSystem, PackageBundle packageBundle, AssetBundle assetBundle)
{
_fileSystem = fileSystem;
_packageBundle = packageBundle;
_assetBundle = assetBundle;
}
public override void UnloadBundleFile()
{
if (_assetBundle != null)
{
if (_packageBundle.Encrypted)
_assetBundle.Unload(true);
else
_assetBundle.TapUnload(true);
}
}
public override string GetBundleFilePath()
{
return _fileSystem.GetBundleFilePath(_packageBundle);
}
public override byte[] ReadBundleFileData()
{
return _fileSystem.ReadBundleFileData(_packageBundle);
}
public override string ReadBundleFileText()
{
return _fileSystem.ReadBundleFileText(_packageBundle);
}
public override FSLoadAssetOperation LoadAssetAsync(AssetInfo assetInfo)
{
var operation = new AssetBundleLoadAssetOperation(_packageBundle, _assetBundle, assetInfo);
return operation;
}
public override FSLoadAllAssetsOperation LoadAllAssetsAsync(AssetInfo assetInfo)
{
var operation = new AssetBundleLoadAllAssetsOperation(_packageBundle, _assetBundle, assetInfo);
return operation;
}
public override FSLoadSubAssetsOperation LoadSubAssetsAsync(AssetInfo assetInfo)
{
var operation = new AssetBundleLoadSubAssetsOperation(_packageBundle, _assetBundle, assetInfo);
return operation;
}
public override FSLoadSceneOperation LoadSceneOperation(AssetInfo assetInfo, LoadSceneParameters loadParams, bool suspendLoad)
{
var operation = new AssetBundleLoadSceneOperation(assetInfo, loadParams, suspendLoad);
return operation;
}
}
}
#endif

View File

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

View File

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

View File

@@ -0,0 +1,111 @@
#if UNITY_WEBGL && TAPMINIGAME
using UnityEngine;
using YooAsset;
internal class TPFSDownloadFileOperation : FSDownloadFileOperation
{
protected enum ESteps
{
None,
CreateRequest,
CheckRequest,
TryAgain,
Done,
}
private readonly TaptapFileSystem _fileSystem;
private readonly DownloadFileOptions _options;
private UnityWebCacheRequestOperation _webCacheRequestOp;
private int _requestCount = 0;
private float _tryAgainTimer;
private int _failedTryAgain;
private ESteps _steps = ESteps.None;
internal TPFSDownloadFileOperation(TaptapFileSystem fileSystem, PackageBundle bundle, DownloadFileOptions options) : base(bundle)
{
_fileSystem = fileSystem;
_options = options;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
string url = GetRequestURL();
_webCacheRequestOp = new UnityWebCacheRequestOperation(url);
_webCacheRequestOp.StartOperation();
AddChildOperation(_webCacheRequestOp);
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
_webCacheRequestOp.UpdateOperation();
Progress = _webCacheRequestOp.Progress;
DownloadProgress = _webCacheRequestOp.DownloadProgress;
DownloadedBytes = _webCacheRequestOp.DownloadedBytes;
if (_webCacheRequestOp.IsDone == false)
return;
if (_webCacheRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
//TODO 需要验证插件请求器的下载进度
DownloadProgress = 1f;
DownloadedBytes = Bundle.FileSize;
Progress = 1f;
}
else
{
if (_failedTryAgain > 0)
{
_steps = ESteps.TryAgain;
YooLogger.Warning($"Failed download : {_webCacheRequestOp.URL} Try again !");
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _webCacheRequestOp.Error;
YooLogger.Error(Error);
}
}
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
DownloadProgress = 0f;
DownloadedBytes = 0;
_steps = ESteps.CreateRequest;
}
}
}
/// <summary>
/// 获取网络请求地址
/// </summary>
private string GetRequestURL()
{
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return _options.FallbackURL;
else
return _options.MainURL;
}
}
#endif

View File

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

View File

@@ -0,0 +1,20 @@
#if UNITY_WEBGL && TAPMINIGAME
using YooAsset;
internal partial class TPFSInitializeOperation : FSInitializeFileSystemOperation
{
private readonly TaptapFileSystem _fileSystem;
public TPFSInitializeOperation(TaptapFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
internal override void InternalStart()
{
Status = EOperationStatus.Succeed;
}
internal override void InternalUpdate()
{
}
}
#endif

View File

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

View File

@@ -0,0 +1,88 @@
#if UNITY_WEBGL && TAPMINIGAME
using YooAsset;
internal class TPFSLoadBundleOperation : FSLoadBundleOperation
{
private enum ESteps
{
None,
LoadAssetBundle,
Done,
}
private readonly TaptapFileSystem _fileSystem;
private readonly PackageBundle _bundle;
private LoadWebAssetBundleOperation _loadWebAssetBundleOp;
private ESteps _steps = ESteps.None;
internal TPFSLoadBundleOperation(TaptapFileSystem fileSystem, PackageBundle bundle)
{
_fileSystem = fileSystem;
_bundle = bundle;
}
internal override void InternalStart()
{
_steps = ESteps.LoadAssetBundle;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.LoadAssetBundle)
{
if (_loadWebAssetBundleOp == null)
{
string mainURL = _fileSystem.RemoteServices.GetRemoteMainURL(_bundle.FileName);
string fallbackURL = _fileSystem.RemoteServices.GetRemoteFallbackURL(_bundle.FileName);
DownloadFileOptions options = new DownloadFileOptions(int.MaxValue);
options.SetURL(mainURL, fallbackURL);
if (_bundle.Encrypted)
{
_loadWebAssetBundleOp = new LoadWebEncryptAssetBundleOperation(_bundle, options, _fileSystem.DecryptionServices);
_loadWebAssetBundleOp.StartOperation();
AddChildOperation(_loadWebAssetBundleOp);
}
else
{
_loadWebAssetBundleOp = new LoadTaptapAssetBundleOperation(_bundle, options);
_loadWebAssetBundleOp.StartOperation();
AddChildOperation(_loadWebAssetBundleOp);
}
}
_loadWebAssetBundleOp.UpdateOperation();
Progress = _loadWebAssetBundleOp.Progress;
DownloadProgress = _loadWebAssetBundleOp.DownloadProgress;
DownloadedBytes = _loadWebAssetBundleOp.DownloadedBytes;
if (_loadWebAssetBundleOp.IsDone == false)
return;
if (_loadWebAssetBundleOp.Status == EOperationStatus.Succeed)
{
var assetBundle = _loadWebAssetBundleOp.Result;
_steps = ESteps.Done;
Result = new TPAssetBundleResult(_fileSystem, _bundle, assetBundle);
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadWebAssetBundleOp.Error;
}
}
}
internal override void InternalWaitForAsyncComplete()
{
if (_steps != ESteps.Done)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = "WebGL platform not support sync load method !";
UnityEngine.Debug.LogError(Error);
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,95 @@
#if UNITY_WEBGL && TAPMINIGAME
using YooAsset;
internal class TPFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
{
private enum ESteps
{
None,
RequestPackageHash,
LoadPackageManifest,
Done,
}
private readonly TaptapFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private RequestWebPackageHashOperation _requestPackageHashOp;
private LoadWebPackageManifestOperation _loadPackageManifestOp;
private ESteps _steps = ESteps.None;
public TPFSLoadPackageManifestOperation(TaptapFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
_packageVersion = packageVersion;
_timeout = timeout;
}
internal override void InternalStart()
{
_steps = ESteps.RequestPackageHash;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestPackageHash)
{
if (_requestPackageHashOp == null)
{
_requestPackageHashOp = new RequestWebPackageHashOperation(_fileSystem.RemoteServices, _fileSystem.PackageName, _packageVersion, _timeout);
_requestPackageHashOp.StartOperation();
AddChildOperation(_requestPackageHashOp);
}
_requestPackageHashOp.UpdateOperation();
if (_requestPackageHashOp.IsDone == false)
return;
if (_requestPackageHashOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.LoadPackageManifest;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _requestPackageHashOp.Error;
}
}
if (_steps == ESteps.LoadPackageManifest)
{
if (_loadPackageManifestOp == null)
{
string packageHash = _requestPackageHashOp.PackageHash;
string packageName = _fileSystem.PackageName;
var manifestServices = _fileSystem.ManifestServices;
var remoteServices = _fileSystem.RemoteServices;
_loadPackageManifestOp = new LoadWebPackageManifestOperation(manifestServices, remoteServices, packageName, _packageVersion, packageHash, _timeout);
_loadPackageManifestOp.StartOperation();
AddChildOperation(_loadPackageManifestOp);
}
_loadPackageManifestOp.UpdateOperation();
Progress = _loadPackageManifestOp.Progress;
if (_loadPackageManifestOp.IsDone == false)
return;
if (_loadPackageManifestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Manifest = _loadPackageManifestOp.Manifest;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _loadPackageManifestOp.Error;
}
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,64 @@
#if UNITY_WEBGL && TAPMINIGAME
using YooAsset;
internal class TPFSRequestPackageVersionOperation : FSRequestPackageVersionOperation
{
private enum ESteps
{
None,
RequestPackageVersion,
Done,
}
private readonly TaptapFileSystem _fileSystem;
private readonly bool _appendTimeTicks;
private readonly int _timeout;
private RequestWebPackageVersionOperation _requestWebPackageVersionOp;
private ESteps _steps = ESteps.None;
internal TPFSRequestPackageVersionOperation(TaptapFileSystem fileSystem, bool appendTimeTicks, int timeout)
{
_fileSystem = fileSystem;
_appendTimeTicks = appendTimeTicks;
_timeout = timeout;
}
internal override void InternalStart()
{
_steps = ESteps.RequestPackageVersion;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.RequestPackageVersion)
{
if (_requestWebPackageVersionOp == null)
{
_requestWebPackageVersionOp = new RequestWebPackageVersionOperation(_fileSystem.RemoteServices, _fileSystem.PackageName, _appendTimeTicks, _timeout);
_requestWebPackageVersionOp.StartOperation();
AddChildOperation(_requestWebPackageVersionOp);
}
_requestWebPackageVersionOp.UpdateOperation();
Progress = _requestWebPackageVersionOp.Progress;
if (_requestWebPackageVersionOp.IsDone == false)
return;
if (_requestWebPackageVersionOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
PackageVersion = _requestWebPackageVersionOp.PackageVersion;
Status = EOperationStatus.Succeed;
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _requestWebPackageVersionOp.Error;
}
}
}
}
#endif

View File

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

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 9be3163f53935514d9e64e09686db957
guid: e4ea0eed64f86c54c82153463d3773bf
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -0,0 +1,114 @@
#if UNITY_WEBGL && TAPMINIGAME
using UnityEngine;
namespace YooAsset
{
internal class LoadTaptapAssetBundleOperation : LoadWebAssetBundleOperation
{
protected enum ESteps
{
None,
CreateRequest,
CheckRequest,
TryAgain,
Done,
}
private readonly PackageBundle _bundle;
private readonly DownloadFileOptions _options;
private UnityTaptapAssetBundleRequestOperation _unityAssetBundleRequestOp;
private int _requestCount = 0;
private float _tryAgainTimer;
private int _failedTryAgain;
private ESteps _steps = ESteps.None;
internal LoadTaptapAssetBundleOperation(PackageBundle bundle, DownloadFileOptions options)
{
_bundle = bundle;
_options = options;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
// 创建下载器
if (_steps == ESteps.CreateRequest)
{
string url = GetRequestURL();
_unityAssetBundleRequestOp = new UnityTaptapAssetBundleRequestOperation(_bundle, url);
_unityAssetBundleRequestOp.StartOperation();
AddChildOperation(_unityAssetBundleRequestOp);
_steps = ESteps.CheckRequest;
}
// 检测下载结果
if (_steps == ESteps.CheckRequest)
{
_unityAssetBundleRequestOp.UpdateOperation();
Progress = _unityAssetBundleRequestOp.Progress;
DownloadProgress = _unityAssetBundleRequestOp.DownloadProgress;
DownloadedBytes = _unityAssetBundleRequestOp.DownloadedBytes;
if (_unityAssetBundleRequestOp.IsDone == false)
return;
if (_unityAssetBundleRequestOp.Status == EOperationStatus.Succeed)
{
_steps = ESteps.Done;
Status = EOperationStatus.Succeed;
Result = _unityAssetBundleRequestOp.Result;
}
else
{
if (_failedTryAgain > 0)
{
_steps = ESteps.TryAgain;
YooLogger.Warning($"Failed download : {_unityAssetBundleRequestOp.URL} Try again !");
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = _unityAssetBundleRequestOp.Error;
YooLogger.Error(Error);
}
}
}
// 重新尝试下载
if (_steps == ESteps.TryAgain)
{
_tryAgainTimer += Time.unscaledDeltaTime;
if (_tryAgainTimer > 1f)
{
_tryAgainTimer = 0f;
_failedTryAgain--;
Progress = 0f;
DownloadProgress = 0f;
DownloadedBytes = 0;
_steps = ESteps.CreateRequest;
}
}
}
/// <summary>
/// 获取网络请求地址
/// </summary>
private string GetRequestURL()
{
// 轮流返回请求地址
_requestCount++;
if (_requestCount % 2 == 0)
return _options.FallbackURL;
else
return _options.MainURL;
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,95 @@
#if UNITY_WEBGL && TAPMINIGAME
using UnityEngine.Networking;
using UnityEngine;
using TapTapMiniGame;
namespace YooAsset
{
internal class UnityTaptapAssetBundleRequestOperation : UnityWebRequestOperation
{
protected enum ESteps
{
None,
CreateRequest,
Download,
Done,
}
private readonly PackageBundle _packageBundle;
private UnityWebRequestAsyncOperation _requestOperation;
private ESteps _steps = ESteps.None;
/// <summary>
/// 请求结果
/// </summary>
public AssetBundle Result { private set; get; }
internal UnityTaptapAssetBundleRequestOperation(PackageBundle bundle, string url) : base(url)
{
_packageBundle = bundle;
}
internal override void InternalStart()
{
_steps = ESteps.CreateRequest;
}
internal override void InternalUpdate()
{
if (_steps == ESteps.None || _steps == ESteps.Done)
return;
if (_steps == ESteps.CreateRequest)
{
CreateWebRequest();
_steps = ESteps.Download;
}
if (_steps == ESteps.Download)
{
DownloadProgress = _webRequest.downloadProgress;
DownloadedBytes = (long)_webRequest.downloadedBytes;
Progress = _requestOperation.progress;
if (_requestOperation.isDone == false)
return;
if (CheckRequestResult())
{
var downloadHanlder = (DownloadHandlerTapAssetBundle)_webRequest.downloadHandler;
AssetBundle assetBundle = downloadHanlder.assetBundle;
if (assetBundle == null)
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
Error = $"URL : {_requestURL} Download handler asset bundle object is null !";
}
else
{
_steps = ESteps.Done;
Result = assetBundle;
Status = EOperationStatus.Succeed;
//TODO 需要验证插件请求器的下载进度
DownloadProgress = 1f;
DownloadedBytes = _packageBundle.FileSize;
Progress = 1f;
}
}
else
{
_steps = ESteps.Done;
Status = EOperationStatus.Failed;
}
// 注意:最终释放请求器
DisposeRequest();
}
}
private void CreateWebRequest()
{
_webRequest = TapAssetBundle.GetAssetBundle(_requestURL);
_webRequest.disposeDownloadHandlerOnDispose = true;
_requestOperation = _webRequest.SendWebRequest();
}
}
}
#endif

View File

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

View File

@@ -0,0 +1,271 @@
#if UNITY_WEBGL && TAPMINIGAME
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using YooAsset;
using TapTapMiniGame;
public static class TaptapFileSystemCreater
{
public static FileSystemParameters CreateFileSystemParameters(string packageRoot)
{
string fileSystemClass = $"{nameof(TaptapFileSystem)},YooAsset.MiniGame";
var fileSystemParams = new FileSystemParameters(fileSystemClass, packageRoot);
return fileSystemParams;
}
}
/// <summary>
/// TapTap小游戏
/// 参考https://developer.taptap.cn/minigameapidoc/dev/engine/unity-adaptation/guide/
/// </summary>
internal class TaptapFileSystem : IFileSystem
{
private class WebRemoteServices : IRemoteServices
{
private readonly string _webPackageRoot;
protected readonly Dictionary<string, string> _mapping = new Dictionary<string, string>(10000);
public WebRemoteServices(string buildinPackRoot)
{
_webPackageRoot = buildinPackRoot;
}
string IRemoteServices.GetRemoteMainURL(string fileName)
{
return GetFileLoadURL(fileName);
}
string IRemoteServices.GetRemoteFallbackURL(string fileName)
{
return GetFileLoadURL(fileName);
}
private string GetFileLoadURL(string fileName)
{
if (_mapping.TryGetValue(fileName, out string url) == false)
{
string filePath = PathUtility.Combine(_webPackageRoot, fileName);
url = DownloadSystemHelper.ConvertToWWWPath(filePath);
_mapping.Add(fileName, url);
}
return url;
}
}
private readonly Dictionary<string, string> _cacheFilePathMapping = new Dictionary<string, string>(10000);
private TapFileSystemManager _fileSystemMgr;
private string _tapCacheRoot = string.Empty;
/// <summary>
/// 包裹名称
/// </summary>
public string PackageName { private set; get; }
/// <summary>
/// 文件根目录
/// </summary>
public string FileRoot
{
get
{
return _tapCacheRoot;
}
}
/// <summary>
/// 文件数量
/// </summary>
public int FileCount
{
get
{
return 0;
}
}
#region
/// <summary>
/// 自定义参数:远程服务接口
/// </summary>
public IRemoteServices RemoteServices { private set; get; } = null;
/// <summary>
/// 自定义参数:解密方法类
/// </summary>
public IWebDecryptionServices DecryptionServices { private set; get; }
/// <summary>
/// 自定义参数:资源清单服务类
/// </summary>
public IManifestRestoreServices ManifestServices { private set; get; }
#endregion
public TaptapFileSystem()
{
}
public virtual FSInitializeFileSystemOperation InitializeFileSystemAsync()
{
var operation = new TPFSInitializeOperation(this);
return operation;
}
public virtual FSLoadPackageManifestOperation LoadPackageManifestAsync(string packageVersion, int timeout)
{
var operation = new TPFSLoadPackageManifestOperation(this, packageVersion, timeout);
return operation;
}
public virtual FSRequestPackageVersionOperation RequestPackageVersionAsync(bool appendTimeTicks, int timeout)
{
var operation = new TPFSRequestPackageVersionOperation(this, appendTimeTicks, timeout);
return operation;
}
public virtual FSClearCacheFilesOperation ClearCacheFilesAsync(PackageManifest manifest, ClearCacheFilesOptions options)
{
var operation = new FSClearCacheFilesCompleteOperation();
return operation;
}
public virtual FSDownloadFileOperation DownloadFileAsync(PackageBundle bundle, DownloadFileOptions options)
{
string mainURL = RemoteServices.GetRemoteMainURL(bundle.FileName);
string fallbackURL = RemoteServices.GetRemoteFallbackURL(bundle.FileName);
options.SetURL(mainURL, fallbackURL);
var operation = new TPFSDownloadFileOperation(this, bundle, options);
return operation;
}
public virtual FSLoadBundleOperation LoadBundleFile(PackageBundle bundle)
{
if (bundle.BundleType == (int)EBuildBundleType.AssetBundle)
{
var operation = new TPFSLoadBundleOperation(this, bundle);
return operation;
}
else
{
string error = $"{nameof(TaptapFileSystem)} not support load bundle type : {bundle.BundleType}";
var operation = new FSLoadBundleCompleteOperation(error);
return operation;
}
}
public virtual void SetParameter(string name, object value)
{
if (name == FileSystemParametersDefine.REMOTE_SERVICES)
{
RemoteServices = (IRemoteServices)value;
}
else if (name == FileSystemParametersDefine.DECRYPTION_SERVICES)
{
DecryptionServices = (IWebDecryptionServices)value;
}
else if (name == FileSystemParametersDefine.MANIFEST_SERVICES)
{
ManifestServices = (IManifestRestoreServices)value;
}
else
{
YooLogger.Warning($"Invalid parameter : {name}");
}
}
public virtual void OnCreate(string packageName, string rootDirectory)
{
PackageName = packageName;
_tapCacheRoot = rootDirectory;
if (string.IsNullOrEmpty(_tapCacheRoot))
{
throw new System.Exception("请配置小游戏的缓存根目录!");
}
// 注意CDN服务未启用的情况下使用WEB服务器
if (RemoteServices == null)
{
string webRoot = PathUtility.Combine(Application.streamingAssetsPath, YooAssetSettingsData.Setting.DefaultYooFolderName, packageName);
RemoteServices = new WebRemoteServices(webRoot);
}
_fileSystemMgr = Tap.GetFileSystemManager();
}
public virtual void OnDestroy()
{
}
public virtual bool Belong(PackageBundle bundle)
{
return true;
}
public virtual bool Exists(PackageBundle bundle)
{
return CheckCacheFileExist(bundle);
}
public virtual bool NeedDownload(PackageBundle bundle)
{
if (Belong(bundle) == false)
return false;
return Exists(bundle) == false;
}
public virtual bool NeedUnpack(PackageBundle bundle)
{
return false;
}
public virtual bool NeedImport(PackageBundle bundle)
{
return false;
}
public virtual string GetBundleFilePath(PackageBundle bundle)
{
return GetCacheFileLoadPath(bundle);
}
public virtual byte[] ReadBundleFileData(PackageBundle bundle)
{
if (CheckCacheFileExist(bundle))
{
string filePath = GetCacheFileLoadPath(bundle);
return _fileSystemMgr.ReadFileSync(filePath);
}
else
{
return Array.Empty<byte>();
}
}
public virtual string ReadBundleFileText(PackageBundle bundle)
{
if (CheckCacheFileExist(bundle))
{
string filePath = GetCacheFileLoadPath(bundle);
return _fileSystemMgr.ReadFileSync(filePath, "utf8");
}
else
{
return string.Empty;
}
}
#region
public TapFileSystemManager GetFileSystemMgr()
{
return _fileSystemMgr;
}
public bool CheckCacheFileExist(PackageBundle bundle)
{
//TODO : 效率极低
/*
string filePath = GetCacheFileLoadPath(bundle);
string result = _fileSystemMgr.AccessSync(filePath);
return result.Equals("access:ok", StringComparison.Ordinal);
*/
return false;
}
private string GetCacheFileLoadPath(PackageBundle bundle)
{
if (_cacheFilePathMapping.TryGetValue(bundle.BundleGUID, out string filePath) == false)
{
filePath = PathUtility.Combine(_tapCacheRoot, bundle.FileName);
_cacheFilePathMapping.Add(bundle.BundleGUID, filePath);
}
return filePath;
}
#endregion
}
#endif

View File

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

View File

@@ -14,11 +14,11 @@ internal class TTFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
private readonly TiktokFileSystem _fileSystem;
private readonly string _packageVersion;
private readonly int _timeout;
private RequestTiktokPackageHashOperation _requestPackageHashOp;
private LoadTiktokPackageManifestOperation _loadPackageManifestOp;
private RequestWebPackageHashOperation _requestPackageHashOp;
private LoadWebPackageManifestOperation _loadPackageManifestOp;
private ESteps _steps = ESteps.None;
public TTFSLoadPackageManifestOperation(TiktokFileSystem fileSystem, string packageVersion, int timeout)
{
_fileSystem = fileSystem;
@@ -38,7 +38,7 @@ internal class TTFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
{
if (_requestPackageHashOp == null)
{
_requestPackageHashOp = new RequestTiktokPackageHashOperation(_fileSystem, _packageVersion, _timeout);
_requestPackageHashOp = new RequestWebPackageHashOperation(_fileSystem.RemoteServices, _fileSystem.PackageName, _packageVersion, _timeout);
_requestPackageHashOp.StartOperation();
AddChildOperation(_requestPackageHashOp);
}
@@ -64,7 +64,10 @@ internal class TTFSLoadPackageManifestOperation : FSLoadPackageManifestOperation
if (_loadPackageManifestOp == null)
{
string packageHash = _requestPackageHashOp.PackageHash;
_loadPackageManifestOp = new LoadTiktokPackageManifestOperation(_fileSystem, _packageVersion, packageHash, _timeout);
string packageName = _fileSystem.PackageName;
var manifestServices = _fileSystem.ManifestServices;
var remoteServices = _fileSystem.RemoteServices;
_loadPackageManifestOp = new LoadWebPackageManifestOperation(manifestServices, remoteServices, packageName, _packageVersion, packageHash, _timeout);
_loadPackageManifestOp.StartOperation();
AddChildOperation(_loadPackageManifestOp);
}

Some files were not shown because too many files have changed in this diff Show More